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’










2















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";









share|improve this question
























  • 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















2















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";









share|improve this question
























  • 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













2












2








2








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";









share|improve this question
















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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








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 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

















  • 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
















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












1 Answer
1






active

oldest

votes


















1














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.






share|improve this answer























  • 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











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
);



);













draft saved

draft discarded


















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









1














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.






share|improve this answer























  • 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















1














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.






share|improve this answer























  • 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













1












1








1







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.






share|improve this answer













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.







share|improve this answer












share|improve this answer



share|improve this answer










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

















  • 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



















draft saved

draft discarded
















































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.




draft saved


draft discarded














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





















































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







Popular posts from this blog

1928 у кіно

Захаров Федір Захарович

Ель Греко