eBPF implicit declaration of BPF Helper The Next CEO of Stack OverflowWhat is your favorite C programming trick?What is the difference between a definition and a declaration?type checking across source fileshow to move packet from NF_INET_PRE_ROUTING to NF_INET_POST_ROUTING?fail to attach eBPF blobSimple eBPF action not taking effect with tceBPF: default bpf programs/maps?ebpf: do ternary lookups exist?eBPF program to forward HTTP requests to different portimplicit declaration of function ‘bpf’
How to write a definition with variants?
How to invert MapIndexed on a ragged structure? How to construct a tree from rules?
How do I align (1) and (2)?
How to avoid supervisors with prejudiced views?
Is it ever safe to open a suspicious HTML file (e.g. email attachment)?
Why is the US ranked as #45 in Press Freedom ratings, despite its extremely permissive free speech laws?
Proper way to express "He disappeared them"
Running a General Election and the European Elections together
Flying from Cape Town to England and return to another province
Why do airplanes bank sharply to the right after air-to-air refueling?
Reference request: Grassmannian and Plucker coordinates in type B, C, D
Find non-case sensitive string in a mixed list of elements?
The exact meaning of 'Mom made me a sandwich'
Would a grinding machine be a simple and workable propulsion system for an interplanetary spacecraft?
Is there a difference between "Fahrstuhl" and "Aufzug"
Prepend last line of stdin to entire stdin
Won the lottery - how do I keep the money?
Easy to read palindrome checker
How is this set of matrices closed under multiplication?
What steps are necessary to read a Modern SSD in Medieval Europe?
How to get from Geneva Airport to Metabief, Doubs, France by public transport?
Where do students learn to solve polynomial equations these days?
I believe this to be a fraud - hired, then asked to cash check and send cash as Bitcoin
Does Germany produce more waste than the US?
eBPF implicit declaration of BPF Helper
The Next CEO of Stack OverflowWhat is your favorite C programming trick?What is the difference between a definition and a declaration?type checking across source fileshow to move packet from NF_INET_PRE_ROUTING to NF_INET_POST_ROUTING?fail to attach eBPF blobSimple eBPF action not taking effect with tceBPF: default bpf programs/maps?ebpf: do ternary lookups exist?eBPF program to forward HTTP requests to different portimplicit declaration of function ‘bpf’
I'm having an issue with compiling an eBPF program that I'm installing with TC. At the moment, it is only performing some basic mangling, which requires recalculating the IP checksum.
I noticed in the BPF helpers, there is a function bpf_l3_csum_replace which seems to be what I want. However, when I try to use any of the built-in functions that are mapped using the BPF_FUNC macro, I get an implicit declaration error:
... warning: implicit declaration of 'bpf_l3_csum_replace' is invalid in
C99.
This is subsequently followed by an error from the verifier:
... A call to global function 'bpf_l3_csum_replace' is not supported. Only
calls to predefined BPF helpers are allowed.
My compile line:
clang -target bpf -nostdinc -I/usr/include -I/usr/lib64/clang/5.0.2/include -O2 -emit-llvm -c <file> -o - | llc -march=bpf -filetype=obj -o <output>
I should note that I am able to compile and install a BPF object (using TC), as long as I don't use any of the "predefined" bpf helpers. The issue arises once I do.
I'm doing this outside of the kernel tree, FWIW. Not sure if that is an issue. I'm including the bpf header (linux/bpf.h), and I'm using the bpf_api.h header from the iproute2 package (didn't have much luck with the bpf_helpers.h header).
I'm still relatively new to eBPF, so I would not be surprised if I'm missing something. Any help would be appreciated.
Edit: Code
#define KBUILD_NAME "testbpf"
#include <linux/bpf.h>
#include <linux/if_ether.h>
#include <linux/if_packet.h>
#include <linux/ip.h>
#include <linux/in.h>
#include <linux/tcp.h>
#include <linux/filter.h>
#include <linux/pkt_cls.h>
#include "bpf_api.h"
#define _htonl __builtin_bswap32
struct eth_hdr
unsigned char h_dest[ETH_ALEN];
unsigned char h_source[ETH_ALEN];
unsigned short h_proto;
;
#define IP_CSUM_OFFSET (ETH_HLEN + offsetof(struct iphdr, check))
#define TOS_OFF (ETH_HLEN + offsetof(struct iphdr, tos))
#define PROTO_OFF (ETH_HLEN + offsetof(struct iphdr, protocol))
__section("ingress") int bpf_prog(struct __sk_buff *skb)
void *data = (void *) (long)skb->data;
struct eth_hdr *eth = data;
void *data_end = (void*) (long) skb->data_end;
if (data+sizeof(*eth) > data_end)
return BPF_H_DEFAULT;
if (eth->h_proto == htons(ETH_P_ARP))
return BPF_H_DEFAULT;
// ipv4
if (eth->h_proto == htons(ETH_P_IP))
struct iphdr *ip = data+sizeof(*eth);
if (data+sizeof(*ip)+sizeof(*eth) > data_end)
return BPF_H_DEFAULT;
__u8 proto = ip->protocol;
__u8 old_tos = ip->tos;
// mangle our tos; not meant to achieve anything
ip->tos = 0x04;
if (proto == IPPROTO_ICMP)
ip->tos = 0x00;
if (proto == IPPROTO_TCP)
ip->tos = 0x04;
if (proto == IPPROTO_UDP)
ip->tos = 0x08;
// update our csum and return
bpf_l3_csum_replace(skb, IP_CSUM_OFFSET, old_tos, ip->tos, 2); // ISSUE here
return BPF_H_DEFAULT;
return BPF_H_DEFAULT;
char __license[] __section("license") = "GPL";
c linux-kernel clang bpf ebpf
add a comment |
I'm having an issue with compiling an eBPF program that I'm installing with TC. At the moment, it is only performing some basic mangling, which requires recalculating the IP checksum.
I noticed in the BPF helpers, there is a function bpf_l3_csum_replace which seems to be what I want. However, when I try to use any of the built-in functions that are mapped using the BPF_FUNC macro, I get an implicit declaration error:
... warning: implicit declaration of 'bpf_l3_csum_replace' is invalid in
C99.
This is subsequently followed by an error from the verifier:
... A call to global function 'bpf_l3_csum_replace' is not supported. Only
calls to predefined BPF helpers are allowed.
My compile line:
clang -target bpf -nostdinc -I/usr/include -I/usr/lib64/clang/5.0.2/include -O2 -emit-llvm -c <file> -o - | llc -march=bpf -filetype=obj -o <output>
I should note that I am able to compile and install a BPF object (using TC), as long as I don't use any of the "predefined" bpf helpers. The issue arises once I do.
I'm doing this outside of the kernel tree, FWIW. Not sure if that is an issue. I'm including the bpf header (linux/bpf.h), and I'm using the bpf_api.h header from the iproute2 package (didn't have much luck with the bpf_helpers.h header).
I'm still relatively new to eBPF, so I would not be surprised if I'm missing something. Any help would be appreciated.
Edit: Code
#define KBUILD_NAME "testbpf"
#include <linux/bpf.h>
#include <linux/if_ether.h>
#include <linux/if_packet.h>
#include <linux/ip.h>
#include <linux/in.h>
#include <linux/tcp.h>
#include <linux/filter.h>
#include <linux/pkt_cls.h>
#include "bpf_api.h"
#define _htonl __builtin_bswap32
struct eth_hdr
unsigned char h_dest[ETH_ALEN];
unsigned char h_source[ETH_ALEN];
unsigned short h_proto;
;
#define IP_CSUM_OFFSET (ETH_HLEN + offsetof(struct iphdr, check))
#define TOS_OFF (ETH_HLEN + offsetof(struct iphdr, tos))
#define PROTO_OFF (ETH_HLEN + offsetof(struct iphdr, protocol))
__section("ingress") int bpf_prog(struct __sk_buff *skb)
void *data = (void *) (long)skb->data;
struct eth_hdr *eth = data;
void *data_end = (void*) (long) skb->data_end;
if (data+sizeof(*eth) > data_end)
return BPF_H_DEFAULT;
if (eth->h_proto == htons(ETH_P_ARP))
return BPF_H_DEFAULT;
// ipv4
if (eth->h_proto == htons(ETH_P_IP))
struct iphdr *ip = data+sizeof(*eth);
if (data+sizeof(*ip)+sizeof(*eth) > data_end)
return BPF_H_DEFAULT;
__u8 proto = ip->protocol;
__u8 old_tos = ip->tos;
// mangle our tos; not meant to achieve anything
ip->tos = 0x04;
if (proto == IPPROTO_ICMP)
ip->tos = 0x00;
if (proto == IPPROTO_TCP)
ip->tos = 0x04;
if (proto == IPPROTO_UDP)
ip->tos = 0x08;
// update our csum and return
bpf_l3_csum_replace(skb, IP_CSUM_OFFSET, old_tos, ip->tos, 2); // ISSUE here
return BPF_H_DEFAULT;
return BPF_H_DEFAULT;
char __license[] __section("license") = "GPL";
c linux-kernel clang bpf ebpf
bpf_api.h
should be enough. Could you post the program or an MCVE?
– pchaigno
Sep 3 '18 at 9:11
@pchaigno So I got it to compile by manually adding a function prototype to the bpf_api.h header, though I'm not sure why it is required
– gsm
Sep 3 '18 at 23:53
Let's try to figure it out. I'm guessing you copiedbpf_api.h
in the same directory as your source file? Where exactly is it from? Which version of iproute2?
– pchaigno
Sep 4 '18 at 7:46
Yep, that is correct. It is from the latest version of iproute2 (pulled from git.kernel.org)
– gsm
Sep 4 '18 at 8:15
add a comment |
I'm having an issue with compiling an eBPF program that I'm installing with TC. At the moment, it is only performing some basic mangling, which requires recalculating the IP checksum.
I noticed in the BPF helpers, there is a function bpf_l3_csum_replace which seems to be what I want. However, when I try to use any of the built-in functions that are mapped using the BPF_FUNC macro, I get an implicit declaration error:
... warning: implicit declaration of 'bpf_l3_csum_replace' is invalid in
C99.
This is subsequently followed by an error from the verifier:
... A call to global function 'bpf_l3_csum_replace' is not supported. Only
calls to predefined BPF helpers are allowed.
My compile line:
clang -target bpf -nostdinc -I/usr/include -I/usr/lib64/clang/5.0.2/include -O2 -emit-llvm -c <file> -o - | llc -march=bpf -filetype=obj -o <output>
I should note that I am able to compile and install a BPF object (using TC), as long as I don't use any of the "predefined" bpf helpers. The issue arises once I do.
I'm doing this outside of the kernel tree, FWIW. Not sure if that is an issue. I'm including the bpf header (linux/bpf.h), and I'm using the bpf_api.h header from the iproute2 package (didn't have much luck with the bpf_helpers.h header).
I'm still relatively new to eBPF, so I would not be surprised if I'm missing something. Any help would be appreciated.
Edit: Code
#define KBUILD_NAME "testbpf"
#include <linux/bpf.h>
#include <linux/if_ether.h>
#include <linux/if_packet.h>
#include <linux/ip.h>
#include <linux/in.h>
#include <linux/tcp.h>
#include <linux/filter.h>
#include <linux/pkt_cls.h>
#include "bpf_api.h"
#define _htonl __builtin_bswap32
struct eth_hdr
unsigned char h_dest[ETH_ALEN];
unsigned char h_source[ETH_ALEN];
unsigned short h_proto;
;
#define IP_CSUM_OFFSET (ETH_HLEN + offsetof(struct iphdr, check))
#define TOS_OFF (ETH_HLEN + offsetof(struct iphdr, tos))
#define PROTO_OFF (ETH_HLEN + offsetof(struct iphdr, protocol))
__section("ingress") int bpf_prog(struct __sk_buff *skb)
void *data = (void *) (long)skb->data;
struct eth_hdr *eth = data;
void *data_end = (void*) (long) skb->data_end;
if (data+sizeof(*eth) > data_end)
return BPF_H_DEFAULT;
if (eth->h_proto == htons(ETH_P_ARP))
return BPF_H_DEFAULT;
// ipv4
if (eth->h_proto == htons(ETH_P_IP))
struct iphdr *ip = data+sizeof(*eth);
if (data+sizeof(*ip)+sizeof(*eth) > data_end)
return BPF_H_DEFAULT;
__u8 proto = ip->protocol;
__u8 old_tos = ip->tos;
// mangle our tos; not meant to achieve anything
ip->tos = 0x04;
if (proto == IPPROTO_ICMP)
ip->tos = 0x00;
if (proto == IPPROTO_TCP)
ip->tos = 0x04;
if (proto == IPPROTO_UDP)
ip->tos = 0x08;
// update our csum and return
bpf_l3_csum_replace(skb, IP_CSUM_OFFSET, old_tos, ip->tos, 2); // ISSUE here
return BPF_H_DEFAULT;
return BPF_H_DEFAULT;
char __license[] __section("license") = "GPL";
c linux-kernel clang bpf ebpf
I'm having an issue with compiling an eBPF program that I'm installing with TC. At the moment, it is only performing some basic mangling, which requires recalculating the IP checksum.
I noticed in the BPF helpers, there is a function bpf_l3_csum_replace which seems to be what I want. However, when I try to use any of the built-in functions that are mapped using the BPF_FUNC macro, I get an implicit declaration error:
... warning: implicit declaration of 'bpf_l3_csum_replace' is invalid in
C99.
This is subsequently followed by an error from the verifier:
... A call to global function 'bpf_l3_csum_replace' is not supported. Only
calls to predefined BPF helpers are allowed.
My compile line:
clang -target bpf -nostdinc -I/usr/include -I/usr/lib64/clang/5.0.2/include -O2 -emit-llvm -c <file> -o - | llc -march=bpf -filetype=obj -o <output>
I should note that I am able to compile and install a BPF object (using TC), as long as I don't use any of the "predefined" bpf helpers. The issue arises once I do.
I'm doing this outside of the kernel tree, FWIW. Not sure if that is an issue. I'm including the bpf header (linux/bpf.h), and I'm using the bpf_api.h header from the iproute2 package (didn't have much luck with the bpf_helpers.h header).
I'm still relatively new to eBPF, so I would not be surprised if I'm missing something. Any help would be appreciated.
Edit: Code
#define KBUILD_NAME "testbpf"
#include <linux/bpf.h>
#include <linux/if_ether.h>
#include <linux/if_packet.h>
#include <linux/ip.h>
#include <linux/in.h>
#include <linux/tcp.h>
#include <linux/filter.h>
#include <linux/pkt_cls.h>
#include "bpf_api.h"
#define _htonl __builtin_bswap32
struct eth_hdr
unsigned char h_dest[ETH_ALEN];
unsigned char h_source[ETH_ALEN];
unsigned short h_proto;
;
#define IP_CSUM_OFFSET (ETH_HLEN + offsetof(struct iphdr, check))
#define TOS_OFF (ETH_HLEN + offsetof(struct iphdr, tos))
#define PROTO_OFF (ETH_HLEN + offsetof(struct iphdr, protocol))
__section("ingress") int bpf_prog(struct __sk_buff *skb)
void *data = (void *) (long)skb->data;
struct eth_hdr *eth = data;
void *data_end = (void*) (long) skb->data_end;
if (data+sizeof(*eth) > data_end)
return BPF_H_DEFAULT;
if (eth->h_proto == htons(ETH_P_ARP))
return BPF_H_DEFAULT;
// ipv4
if (eth->h_proto == htons(ETH_P_IP))
struct iphdr *ip = data+sizeof(*eth);
if (data+sizeof(*ip)+sizeof(*eth) > data_end)
return BPF_H_DEFAULT;
__u8 proto = ip->protocol;
__u8 old_tos = ip->tos;
// mangle our tos; not meant to achieve anything
ip->tos = 0x04;
if (proto == IPPROTO_ICMP)
ip->tos = 0x00;
if (proto == IPPROTO_TCP)
ip->tos = 0x04;
if (proto == IPPROTO_UDP)
ip->tos = 0x08;
// update our csum and return
bpf_l3_csum_replace(skb, IP_CSUM_OFFSET, old_tos, ip->tos, 2); // ISSUE here
return BPF_H_DEFAULT;
return BPF_H_DEFAULT;
char __license[] __section("license") = "GPL";
c linux-kernel clang bpf ebpf
c linux-kernel clang bpf ebpf
edited Mar 7 at 17:00
pchaigno
4,00811228
4,00811228
asked Sep 3 '18 at 8:28
gsmgsm
35229
35229
bpf_api.h
should be enough. Could you post the program or an MCVE?
– pchaigno
Sep 3 '18 at 9:11
@pchaigno So I got it to compile by manually adding a function prototype to the bpf_api.h header, though I'm not sure why it is required
– gsm
Sep 3 '18 at 23:53
Let's try to figure it out. I'm guessing you copiedbpf_api.h
in the same directory as your source file? Where exactly is it from? Which version of iproute2?
– pchaigno
Sep 4 '18 at 7:46
Yep, that is correct. It is from the latest version of iproute2 (pulled from git.kernel.org)
– gsm
Sep 4 '18 at 8:15
add a comment |
bpf_api.h
should be enough. Could you post the program or an MCVE?
– pchaigno
Sep 3 '18 at 9:11
@pchaigno So I got it to compile by manually adding a function prototype to the bpf_api.h header, though I'm not sure why it is required
– gsm
Sep 3 '18 at 23:53
Let's try to figure it out. I'm guessing you copiedbpf_api.h
in the same directory as your source file? Where exactly is it from? Which version of iproute2?
– pchaigno
Sep 4 '18 at 7:46
Yep, that is correct. It is from the latest version of iproute2 (pulled from git.kernel.org)
– gsm
Sep 4 '18 at 8:15
bpf_api.h
should be enough. Could you post the program or an MCVE?– pchaigno
Sep 3 '18 at 9:11
bpf_api.h
should be enough. Could you post the program or an MCVE?– pchaigno
Sep 3 '18 at 9:11
@pchaigno So I got it to compile by manually adding a function prototype to the bpf_api.h header, though I'm not sure why it is required
– gsm
Sep 3 '18 at 23:53
@pchaigno So I got it to compile by manually adding a function prototype to the bpf_api.h header, though I'm not sure why it is required
– gsm
Sep 3 '18 at 23:53
Let's try to figure it out. I'm guessing you copied
bpf_api.h
in the same directory as your source file? Where exactly is it from? Which version of iproute2?– pchaigno
Sep 4 '18 at 7:46
Let's try to figure it out. I'm guessing you copied
bpf_api.h
in the same directory as your source file? Where exactly is it from? Which version of iproute2?– pchaigno
Sep 4 '18 at 7:46
Yep, that is correct. It is from the latest version of iproute2 (pulled from git.kernel.org)
– gsm
Sep 4 '18 at 8:15
Yep, that is correct. It is from the latest version of iproute2 (pulled from git.kernel.org)
– gsm
Sep 4 '18 at 8:15
add a comment |
1 Answer
1
active
oldest
votes
The compiler is throwing that error because bpf_api.h
defines this helper as:
static int l3_csum_replace(struct __sk_buff *skb, uint32_t off, uint32_t from, uint32_t to, uint32_t flags);
instead of bpf_l3_csum_replace
. If you remove the bpf_
prefix from the helper's name in your code it compiles as expected without manually adding a prototype.
Detail & Debugging
If you follow the prototype definition in bpf_api.h
, you'll see that it uses BPF_FUNC
which itself uses __BPF_FUNC
:
#ifndef __BPF_FUNC
# define __BPF_FUNC(NAME, ...)
(* NAME)(__VA_ARGS__) __maybe_unused
#endif
#ifndef BPF_FUNC
# define BPF_FUNC(NAME, ...)
__BPF_FUNC(NAME, __VA_ARGS__) = (void *) BPF_FUNC_##NAME
#else
#endif
According to this snippet of code, any helper definition of the form:
static return_type BPF_FUNC(name, ... args ...);
will be expanded into:
static return_type name(... args ...);
So no bpf_
prefix is ever appended.
I did follow those macros through, but wasn't sure if the verifier (?) would complain about a 'global function' that is not part of the API. I'm not near my computer at the moment to test, but will do so in the morning! Cheers for the assistance thus far
– gsm
Sep 4 '18 at 12:20
Oh, that's the compiler throwing an error, not the kernel's verifier (cf. the LLVM commit that added that).
– pchaigno
Sep 4 '18 at 12:33
That worked; Thanks for the help! Yeah I didn't think it was the verifier, but wasn't sure what it was
– gsm
Sep 4 '18 at 22:10
Glad I could help!
– pchaigno
Sep 5 '18 at 9:12
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52145915%2febpf-implicit-declaration-of-bpf-helper%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
The compiler is throwing that error because bpf_api.h
defines this helper as:
static int l3_csum_replace(struct __sk_buff *skb, uint32_t off, uint32_t from, uint32_t to, uint32_t flags);
instead of bpf_l3_csum_replace
. If you remove the bpf_
prefix from the helper's name in your code it compiles as expected without manually adding a prototype.
Detail & Debugging
If you follow the prototype definition in bpf_api.h
, you'll see that it uses BPF_FUNC
which itself uses __BPF_FUNC
:
#ifndef __BPF_FUNC
# define __BPF_FUNC(NAME, ...)
(* NAME)(__VA_ARGS__) __maybe_unused
#endif
#ifndef BPF_FUNC
# define BPF_FUNC(NAME, ...)
__BPF_FUNC(NAME, __VA_ARGS__) = (void *) BPF_FUNC_##NAME
#else
#endif
According to this snippet of code, any helper definition of the form:
static return_type BPF_FUNC(name, ... args ...);
will be expanded into:
static return_type name(... args ...);
So no bpf_
prefix is ever appended.
I did follow those macros through, but wasn't sure if the verifier (?) would complain about a 'global function' that is not part of the API. I'm not near my computer at the moment to test, but will do so in the morning! Cheers for the assistance thus far
– gsm
Sep 4 '18 at 12:20
Oh, that's the compiler throwing an error, not the kernel's verifier (cf. the LLVM commit that added that).
– pchaigno
Sep 4 '18 at 12:33
That worked; Thanks for the help! Yeah I didn't think it was the verifier, but wasn't sure what it was
– gsm
Sep 4 '18 at 22:10
Glad I could help!
– pchaigno
Sep 5 '18 at 9:12
add a comment |
The compiler is throwing that error because bpf_api.h
defines this helper as:
static int l3_csum_replace(struct __sk_buff *skb, uint32_t off, uint32_t from, uint32_t to, uint32_t flags);
instead of bpf_l3_csum_replace
. If you remove the bpf_
prefix from the helper's name in your code it compiles as expected without manually adding a prototype.
Detail & Debugging
If you follow the prototype definition in bpf_api.h
, you'll see that it uses BPF_FUNC
which itself uses __BPF_FUNC
:
#ifndef __BPF_FUNC
# define __BPF_FUNC(NAME, ...)
(* NAME)(__VA_ARGS__) __maybe_unused
#endif
#ifndef BPF_FUNC
# define BPF_FUNC(NAME, ...)
__BPF_FUNC(NAME, __VA_ARGS__) = (void *) BPF_FUNC_##NAME
#else
#endif
According to this snippet of code, any helper definition of the form:
static return_type BPF_FUNC(name, ... args ...);
will be expanded into:
static return_type name(... args ...);
So no bpf_
prefix is ever appended.
I did follow those macros through, but wasn't sure if the verifier (?) would complain about a 'global function' that is not part of the API. I'm not near my computer at the moment to test, but will do so in the morning! Cheers for the assistance thus far
– gsm
Sep 4 '18 at 12:20
Oh, that's the compiler throwing an error, not the kernel's verifier (cf. the LLVM commit that added that).
– pchaigno
Sep 4 '18 at 12:33
That worked; Thanks for the help! Yeah I didn't think it was the verifier, but wasn't sure what it was
– gsm
Sep 4 '18 at 22:10
Glad I could help!
– pchaigno
Sep 5 '18 at 9:12
add a comment |
The compiler is throwing that error because bpf_api.h
defines this helper as:
static int l3_csum_replace(struct __sk_buff *skb, uint32_t off, uint32_t from, uint32_t to, uint32_t flags);
instead of bpf_l3_csum_replace
. If you remove the bpf_
prefix from the helper's name in your code it compiles as expected without manually adding a prototype.
Detail & Debugging
If you follow the prototype definition in bpf_api.h
, you'll see that it uses BPF_FUNC
which itself uses __BPF_FUNC
:
#ifndef __BPF_FUNC
# define __BPF_FUNC(NAME, ...)
(* NAME)(__VA_ARGS__) __maybe_unused
#endif
#ifndef BPF_FUNC
# define BPF_FUNC(NAME, ...)
__BPF_FUNC(NAME, __VA_ARGS__) = (void *) BPF_FUNC_##NAME
#else
#endif
According to this snippet of code, any helper definition of the form:
static return_type BPF_FUNC(name, ... args ...);
will be expanded into:
static return_type name(... args ...);
So no bpf_
prefix is ever appended.
The compiler is throwing that error because bpf_api.h
defines this helper as:
static int l3_csum_replace(struct __sk_buff *skb, uint32_t off, uint32_t from, uint32_t to, uint32_t flags);
instead of bpf_l3_csum_replace
. If you remove the bpf_
prefix from the helper's name in your code it compiles as expected without manually adding a prototype.
Detail & Debugging
If you follow the prototype definition in bpf_api.h
, you'll see that it uses BPF_FUNC
which itself uses __BPF_FUNC
:
#ifndef __BPF_FUNC
# define __BPF_FUNC(NAME, ...)
(* NAME)(__VA_ARGS__) __maybe_unused
#endif
#ifndef BPF_FUNC
# define BPF_FUNC(NAME, ...)
__BPF_FUNC(NAME, __VA_ARGS__) = (void *) BPF_FUNC_##NAME
#else
#endif
According to this snippet of code, any helper definition of the form:
static return_type BPF_FUNC(name, ... args ...);
will be expanded into:
static return_type name(... args ...);
So no bpf_
prefix is ever appended.
answered Sep 4 '18 at 12:05
pchaignopchaigno
4,00811228
4,00811228
I did follow those macros through, but wasn't sure if the verifier (?) would complain about a 'global function' that is not part of the API. I'm not near my computer at the moment to test, but will do so in the morning! Cheers for the assistance thus far
– gsm
Sep 4 '18 at 12:20
Oh, that's the compiler throwing an error, not the kernel's verifier (cf. the LLVM commit that added that).
– pchaigno
Sep 4 '18 at 12:33
That worked; Thanks for the help! Yeah I didn't think it was the verifier, but wasn't sure what it was
– gsm
Sep 4 '18 at 22:10
Glad I could help!
– pchaigno
Sep 5 '18 at 9:12
add a comment |
I did follow those macros through, but wasn't sure if the verifier (?) would complain about a 'global function' that is not part of the API. I'm not near my computer at the moment to test, but will do so in the morning! Cheers for the assistance thus far
– gsm
Sep 4 '18 at 12:20
Oh, that's the compiler throwing an error, not the kernel's verifier (cf. the LLVM commit that added that).
– pchaigno
Sep 4 '18 at 12:33
That worked; Thanks for the help! Yeah I didn't think it was the verifier, but wasn't sure what it was
– gsm
Sep 4 '18 at 22:10
Glad I could help!
– pchaigno
Sep 5 '18 at 9:12
I did follow those macros through, but wasn't sure if the verifier (?) would complain about a 'global function' that is not part of the API. I'm not near my computer at the moment to test, but will do so in the morning! Cheers for the assistance thus far
– gsm
Sep 4 '18 at 12:20
I did follow those macros through, but wasn't sure if the verifier (?) would complain about a 'global function' that is not part of the API. I'm not near my computer at the moment to test, but will do so in the morning! Cheers for the assistance thus far
– gsm
Sep 4 '18 at 12:20
Oh, that's the compiler throwing an error, not the kernel's verifier (cf. the LLVM commit that added that).
– pchaigno
Sep 4 '18 at 12:33
Oh, that's the compiler throwing an error, not the kernel's verifier (cf. the LLVM commit that added that).
– pchaigno
Sep 4 '18 at 12:33
That worked; Thanks for the help! Yeah I didn't think it was the verifier, but wasn't sure what it was
– gsm
Sep 4 '18 at 22:10
That worked; Thanks for the help! Yeah I didn't think it was the verifier, but wasn't sure what it was
– gsm
Sep 4 '18 at 22:10
Glad I could help!
– pchaigno
Sep 5 '18 at 9:12
Glad I could help!
– pchaigno
Sep 5 '18 at 9:12
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52145915%2febpf-implicit-declaration-of-bpf-helper%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
bpf_api.h
should be enough. Could you post the program or an MCVE?– pchaigno
Sep 3 '18 at 9:11
@pchaigno So I got it to compile by manually adding a function prototype to the bpf_api.h header, though I'm not sure why it is required
– gsm
Sep 3 '18 at 23:53
Let's try to figure it out. I'm guessing you copied
bpf_api.h
in the same directory as your source file? Where exactly is it from? Which version of iproute2?– pchaigno
Sep 4 '18 at 7:46
Yep, that is correct. It is from the latest version of iproute2 (pulled from git.kernel.org)
– gsm
Sep 4 '18 at 8:15