-
Notifications
You must be signed in to change notification settings - Fork 84
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add sample usage for BPF_PROG_TYPE_NETFILTER #98
base: master
Are you sure you want to change the base?
Conversation
Instead of directing people to copy the files to the kernel tree, could you please add a Makefile to build the sample as part of this repo? You can copy the Makefile from one of the other directories and adjust appropriately :) |
The problem is with those new enum defined in kernel headers and the "new" vmlinux.h file. |
Sure. Have a look at the existing header files in |
New types can be easily dealt with, but the "changed" type bpf_attr in libbpf is hard to make a workaround....
|
I turns out that lastet https://github.com/xdp-project/libbpf has netfilter added to link_create, any chance to make a update to the libbpf submodule? |
David Wang ***@***.***> writes:
I turns out that lastet https://github.com/xdp-project/libbpf has
netfilter added to link_create, any chance to make a update to the
libbpf submodule?
Sure, feel free to include a libbpf version bump as part of the PR (just
make it a separate commit) :)
|
Sad story.... Even I
The bpf program works when I replace lib/install/lib/libbpf.a with 6.5.0 in-tree version..... |
Could |
David Wang ***@***.***> writes:
Could `https://github.com/xdp-project/libbpf.git` resync with in-tree
version?....
Sure, fast-forwarded it to the latest upstream :)
|
Signed-off-by: David Wang <[email protected]>
Signed-off-by: David Wang <[email protected]>
28c42fe
to
40bbc1d
Compare
nat64-bpf has build error, but it failed the same way before this commit
And second
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A bunch of minor-ish things, mostly on the userspace code.
Also, please add the netfilter-bpf directory to the toplevel Makefile.
struct bpf_dynptr ptr; | ||
struct iphdr *p, iph = {}; | ||
struct ipv4_lpm_key key; | ||
__u32 *pvalue; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please follow the kernel networking style of declaring variables in reverse x-mas tree order
__u32 *pvalue; | ||
|
||
if (skb->len <= 20 || bpf_dynptr_from_skb(skb, 0, &ptr)) | ||
return NF_ACCEPT; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For consistency, let's have an empty line after this early return as well as the other ones.
int err; | ||
struct bpf_object *obj; | ||
struct bpf_program *prog; | ||
union bpf_attr attr = { }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reverse x-mas tree here as well, please.
{ | ||
struct ipv4_lpm_key key; | ||
__u32 value = 0; | ||
__u8 *p = (__u8 *) &key.data; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of this casting to an array of u8, just do a htonl(0xc0a80b6b) with a comment explaining what it means.
Also, drop the block and just move the variables to the top of the function definition.
} | ||
/* attach to netfilter output handler */ | ||
attr.link_create.netfilter.hooknum = NF_INET_LOCAL_OUT; | ||
err = sys_bpf(BPF_LINK_CREATE, &attr, sizeof(attr)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't the map be populated before attaching the program?
if (libbpf_get_error(obj)) { | ||
printf("fail to open bpf file\n"); | ||
return 1; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From here on down, there should be proper error handling on the error paths. I.e., close the bpf object on exit, close the link fd, etc
printf("fail to find bpf program\n"); | ||
return 1; | ||
} | ||
bpf_program__set_type(prog, BPF_PROG_TYPE_NETFILTER); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this needed, the bpf code already has a SEC("netfilter")
declaration?
printf("loading BPF object file failed\n"); | ||
return 1; | ||
} | ||
map_fd = bpf_object__find_map_fd_by_name(obj, "ipv4_lpm_map"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should use the high-level libbpf API; i.e. bpf_object__find_map_by_name()
and bpf_map__update_elem()
.
return 1; | ||
} | ||
/* attach to netfilter forward handler */ | ||
prog_fd = bpf_program__fd(prog); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here, this should use bpf_program__attach_netfilter()
static inline int sys_bpf(enum bpf_cmd cmd, union bpf_attr *attr, unsigned int size) | ||
{ | ||
return syscall(__NR_bpf, cmd, attr, size); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not needed when using the highlevel libbpf APIs, see below.
BPF_PROG_TYPE_NETFILTER was introduced in 6.4, now with a new kernel, a bpf program could attach to netfilter hooks and handles package in a similiar way as iptables/nftables. By now, 6.5.0, there is no bpf kfunc implemented yet for DNAT/SNAT, and the only thing a bpf program can do is to decide whether to DROP the package or not.
This sample code implements a simple ipv4 blacklist.
The bpf program drops package if destination ip address hits a match in the map of type BPF_MAP_TYPE_LPM_TRIE,
The userspace code would load the bpf program, attach it to netfilter's FORWARD/OUTPUT hook, and then write ip patterns into the bpf map.