Add sample usage for BPF_PROG_TYPE_NETFILTER#98
Add sample usage for BPF_PROG_TYPE_NETFILTER#98zq-david-wang wants to merge 2 commits intoxdp-project:mainfrom
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 <00107082@163.com>
Signed-off-by: David Wang <00107082@163.com>
28c42fe to
40bbc1d
Compare
|
nat64-bpf has build error, but it failed the same way before this commit And second |
tohojo
left a comment
There was a problem hiding this comment.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.