From 05ee658c654bacda03f7fecef367e62aaf8e1cfe Mon Sep 17 00:00:00 2001 From: Gerhard Engleder Date: Thu, 13 Oct 2022 22:09:22 +0200 Subject: samples/bpf: Fix map iteration in xdp1_user BPF map iteration in xdp1_user results in endless loop without any output, because the return value of bpf_map_get_next_key() is checked against the wrong value. Other call locations of bpf_map_get_next_key() check for equal 0 for continuing the iteration. xdp1_user checks against unequal -1. This is wrong for a function which can return arbitrary negative errno values, because a return value of e.g. -2 results in an endless loop. With this fix xdp1_user is printing statistics again: proto 0: 1 pkt/s proto 0: 1 pkt/s proto 17: 107383 pkt/s proto 17: 881655 pkt/s proto 17: 882083 pkt/s proto 17: 881758 pkt/s Fixes: bd054102a8c7 ("libbpf: enforce strict libbpf 1.0 behaviors") Signed-off-by: Gerhard Engleder Acked-by: Song Liu Link: https://lore.kernel.org/r/20221013200922.17167-1-gerhard@engleder-embedded.com Signed-off-by: Martin KaFai Lau --- samples/bpf/xdp1_user.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'samples') diff --git a/samples/bpf/xdp1_user.c b/samples/bpf/xdp1_user.c index ac370e638fa3d..281dc964de8da 100644 --- a/samples/bpf/xdp1_user.c +++ b/samples/bpf/xdp1_user.c @@ -51,7 +51,7 @@ static void poll_stats(int map_fd, int interval) sleep(interval); - while (bpf_map_get_next_key(map_fd, &key, &key) != -1) { + while (bpf_map_get_next_key(map_fd, &key, &key) == 0) { __u64 sum = 0; assert(bpf_map_lookup_elem(map_fd, &key, values) == 0); -- cgit 1.2.3-korg From 7a698edf954cb3f8b6e8dacdb77615355170420c Mon Sep 17 00:00:00 2001 From: Gerhard Engleder Date: Sat, 15 Oct 2022 23:30:50 +0200 Subject: samples/bpf: Fix MAC address swapping in xdp2_kern xdp2_kern rewrites and forwards packets out on the same interface. Forwarding still works but rewrite got broken when xdp multibuffer support has been added. With xdp multibuffer a local copy of the packet has been introduced. The MAC address is now swapped in the local copy, but the local copy in not written back. Fix MAC address swapping be adding write back of modified packet. Fixes: 772251742262 ("samples/bpf: fixup some tools to be able to support xdp multibuffer") Signed-off-by: Gerhard Engleder Reviewed-by: Andy Gospodarek Link: https://lore.kernel.org/r/20221015213050.65222-1-gerhard@engleder-embedded.com Signed-off-by: Martin KaFai Lau --- samples/bpf/xdp2_kern.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'samples') diff --git a/samples/bpf/xdp2_kern.c b/samples/bpf/xdp2_kern.c index 3332ba6bb95fb..67804ecf7ce37 100644 --- a/samples/bpf/xdp2_kern.c +++ b/samples/bpf/xdp2_kern.c @@ -112,6 +112,10 @@ int xdp_prog1(struct xdp_md *ctx) if (ipproto == IPPROTO_UDP) { swap_src_dst_mac(data); + + if (bpf_xdp_store_bytes(ctx, 0, pkt, sizeof(pkt))) + return rc; + rc = XDP_TX; } -- cgit 1.2.3-korg From 01dea9548f6c88dc23dc5916eecd3555b82c8fec Mon Sep 17 00:00:00 2001 From: Shaomin Deng Date: Mon, 17 Oct 2022 10:23:03 -0400 Subject: samples/bpf: Fix double word in comments Remove the repeated word "by" in comments. Signed-off-by: Shaomin Deng Link: https://lore.kernel.org/r/20221017142303.8299-1-dengshaomin@cdjrlc.com Signed-off-by: Martin KaFai Lau --- samples/bpf/hbm_edt_kern.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'samples') diff --git a/samples/bpf/hbm_edt_kern.c b/samples/bpf/hbm_edt_kern.c index a65b677acdb0c..6294f1d716c02 100644 --- a/samples/bpf/hbm_edt_kern.c +++ b/samples/bpf/hbm_edt_kern.c @@ -35,7 +35,7 @@ * * If the credit is below the drop threshold, the packet is dropped. If it * is a TCP packet, then it also calls tcp_cwr since packets dropped by - * by a cgroup skb BPF program do not automatically trigger a call to + * a cgroup skb BPF program do not automatically trigger a call to * tcp_cwr in the current kernel code. * * This BPF program actually uses 2 drop thresholds, one threshold -- cgit 1.2.3-korg From 2c4d72d66b548f1404ff43c01b7b81f4c4c6fafd Mon Sep 17 00:00:00 2001 From: Daniel Müller Date: Tue, 18 Oct 2022 16:32:31 +0000 Subject: samples/bpf: Fix typos in README MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This change fixes some typos found in the BPF samples README file. Signed-off-by: Daniel Müller Acked-by: David Vernet Link: https://lore.kernel.org/r/20221018163231.1926462-1-deso@posteo.net Signed-off-by: Martin KaFai Lau --- samples/bpf/README.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'samples') diff --git a/samples/bpf/README.rst b/samples/bpf/README.rst index 60c6494adb1b0..6cfb74fb5ee68 100644 --- a/samples/bpf/README.rst +++ b/samples/bpf/README.rst @@ -37,8 +37,8 @@ user, simply call:: make headers_install -This will creates a local "usr/include" directory in the git/build top -level directory, that the make system automatically pickup first. +This will create a local "usr/include" directory in the git/build top +level directory, that the make system will automatically pick up first. Compiling ========= -- cgit 1.2.3-korg From 3a07dcf8f57b9a90b1c07df3e9091fd04baa3036 Mon Sep 17 00:00:00 2001 From: Kang Minchul Date: Mon, 31 Oct 2022 03:02:54 +0900 Subject: samples/bpf: Fix typo in README Fix 'cofiguration' typo in BPF samples README. Signed-off-by: Kang Minchul Signed-off-by: Daniel Borkmann Link: https://lore.kernel.org/bpf/20221030180254.34138-1-tegongkang@gmail.com --- samples/bpf/README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'samples') diff --git a/samples/bpf/README.rst b/samples/bpf/README.rst index 6cfb74fb5ee68..57f93edd1957d 100644 --- a/samples/bpf/README.rst +++ b/samples/bpf/README.rst @@ -87,7 +87,7 @@ Cross compiling samples ----------------------- In order to cross-compile, say for arm64 targets, export CROSS_COMPILE and ARCH environment variables before calling make. But do this before clean, -cofiguration and header install steps described above. This will direct make to +configuration and header install steps described above. This will direct make to build samples for the cross target:: export ARCH=arm64 -- cgit 1.2.3-korg From 1baa7e38002111aee62b489ac343960ae75ce2e9 Mon Sep 17 00:00:00 2001 From: Rong Tao Date: Sat, 29 Oct 2022 17:11:13 +0800 Subject: samples/bpf: Fix tracex2 error: No such file or directory since commit c504e5c2f964("net: skb: introduce kfree_skb_reason()") kfree_skb() is replaced by kfree_skb_reason() and kfree_skb() is set to the inline function. So, we replace kprobe/kfree_skb with kprobe/kfree_skb_reason to solve the tracex2 error. $ cd samples/bpf $ sudo ./tracex2 libbpf: prog 'bpf_prog2': failed to create kprobe 'kfree_skb+0x0' perf event: No such file or directory ERROR: bpf_program__attach failed Signed-off-by: Rong Tao Signed-off-by: Andrii Nakryiko Link: https://lore.kernel.org/bpf/tencent_0F0DAE84C0B3C42E0B550E5E9F47A9114D09@qq.com --- samples/bpf/tracex2_kern.c | 4 ++-- samples/bpf/tracex2_user.c | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'samples') diff --git a/samples/bpf/tracex2_kern.c b/samples/bpf/tracex2_kern.c index 5bc696bac27d7..93e0b7680b4f0 100644 --- a/samples/bpf/tracex2_kern.c +++ b/samples/bpf/tracex2_kern.c @@ -22,14 +22,14 @@ struct { /* kprobe is NOT a stable ABI. If kernel internals change this bpf+kprobe * example will no longer be meaningful */ -SEC("kprobe/kfree_skb") +SEC("kprobe/kfree_skb_reason") int bpf_prog2(struct pt_regs *ctx) { long loc = 0; long init_val = 1; long *value; - /* read ip of kfree_skb caller. + /* read ip of kfree_skb_reason caller. * non-portable version of __builtin_return_address(0) */ BPF_KPROBE_READ_RET_IP(loc, ctx); diff --git a/samples/bpf/tracex2_user.c b/samples/bpf/tracex2_user.c index dd6205c6b6a74..089e408abd7ad 100644 --- a/samples/bpf/tracex2_user.c +++ b/samples/bpf/tracex2_user.c @@ -146,7 +146,8 @@ int main(int ac, char **argv) signal(SIGINT, int_exit); signal(SIGTERM, int_exit); - /* start 'ping' in the background to have some kfree_skb events */ + /* start 'ping' in the background to have some kfree_skb_reason + * events */ f = popen("ping -4 -c5 localhost", "r"); (void) f; -- cgit 1.2.3-korg From e5659e4e19e49f1eac58bb07ce8bc2d78a89fe65 Mon Sep 17 00:00:00 2001 From: Rong Tao Date: Sat, 5 Nov 2022 14:48:00 +0800 Subject: samples/bpf: Fix sockex3 error: Missing BPF prog type since commit 450b167fb9be("libbpf: clean up SEC() handling"), sec_def_matches() does not recognize "socket/xxx" as "socket", therefore, the BPF program type is not recognized. Instead of sockex3_user.c parsing section names to get the BPF program fd. We use the program array map to assign a static index to each BPF program (get inspired by selftests/bpf progs/test_prog_array_init.c). Therefore, use SEC("socket") as section name instead of SEC("socket/xxx"), so that the BPF program is parsed to SOCKET_FILTER type. The "missing BPF prog type" problem is solved. How to reproduce this error: $ cd samples/bpf $ sudo ./sockex3 libbpf: prog 'bpf_func_PARSE_IP': missing BPF prog type, check ELF section name 'socket/3' libbpf: prog 'bpf_func_PARSE_IP': failed to load: -22 libbpf: failed to load object './sockex3_kern.o' ERROR: loading BPF object file failed Signed-off-by: Rong Tao Signed-off-by: Andrii Nakryiko Link: https://lore.kernel.org/bpf/tencent_EBA3C18864069E42175946973C2ACBAF5408@qq.com --- samples/bpf/sockex3_kern.c | 95 ++++++++++++++++++++++++++-------------------- samples/bpf/sockex3_user.c | 23 +++++------ 2 files changed, 63 insertions(+), 55 deletions(-) (limited to 'samples') diff --git a/samples/bpf/sockex3_kern.c b/samples/bpf/sockex3_kern.c index b363503357e5d..822c13242251c 100644 --- a/samples/bpf/sockex3_kern.c +++ b/samples/bpf/sockex3_kern.c @@ -17,48 +17,11 @@ #define IP_MF 0x2000 #define IP_OFFSET 0x1FFF -#define PROG(F) SEC("socket/"__stringify(F)) int bpf_func_##F - -struct { - __uint(type, BPF_MAP_TYPE_PROG_ARRAY); - __uint(key_size, sizeof(u32)); - __uint(value_size, sizeof(u32)); - __uint(max_entries, 8); -} jmp_table SEC(".maps"); - #define PARSE_VLAN 1 #define PARSE_MPLS 2 #define PARSE_IP 3 #define PARSE_IPV6 4 -/* Protocol dispatch routine. It tail-calls next BPF program depending - * on eth proto. Note, we could have used ... - * - * bpf_tail_call(skb, &jmp_table, proto); - * - * ... but it would need large prog_array and cannot be optimised given - * the map key is not static. - */ -static inline void parse_eth_proto(struct __sk_buff *skb, u32 proto) -{ - switch (proto) { - case ETH_P_8021Q: - case ETH_P_8021AD: - bpf_tail_call(skb, &jmp_table, PARSE_VLAN); - break; - case ETH_P_MPLS_UC: - case ETH_P_MPLS_MC: - bpf_tail_call(skb, &jmp_table, PARSE_MPLS); - break; - case ETH_P_IP: - bpf_tail_call(skb, &jmp_table, PARSE_IP); - break; - case ETH_P_IPV6: - bpf_tail_call(skb, &jmp_table, PARSE_IPV6); - break; - } -} - struct vlan_hdr { __be16 h_vlan_TCI; __be16 h_vlan_encapsulated_proto; @@ -74,6 +37,8 @@ struct flow_key_record { __u32 ip_proto; }; +static inline void parse_eth_proto(struct __sk_buff *skb, u32 proto); + static inline int ip_is_fragment(struct __sk_buff *ctx, __u64 nhoff) { return load_half(ctx, nhoff + offsetof(struct iphdr, frag_off)) @@ -189,7 +154,8 @@ static __always_inline void parse_ip_proto(struct __sk_buff *skb, } } -PROG(PARSE_IP)(struct __sk_buff *skb) +SEC("socket") +int bpf_func_ip(struct __sk_buff *skb) { struct globals *g = this_cpu_globals(); __u32 nhoff, verlen, ip_proto; @@ -217,7 +183,8 @@ PROG(PARSE_IP)(struct __sk_buff *skb) return 0; } -PROG(PARSE_IPV6)(struct __sk_buff *skb) +SEC("socket") +int bpf_func_ipv6(struct __sk_buff *skb) { struct globals *g = this_cpu_globals(); __u32 nhoff, ip_proto; @@ -240,7 +207,8 @@ PROG(PARSE_IPV6)(struct __sk_buff *skb) return 0; } -PROG(PARSE_VLAN)(struct __sk_buff *skb) +SEC("socket") +int bpf_func_vlan(struct __sk_buff *skb) { __u32 nhoff, proto; @@ -256,7 +224,8 @@ PROG(PARSE_VLAN)(struct __sk_buff *skb) return 0; } -PROG(PARSE_MPLS)(struct __sk_buff *skb) +SEC("socket") +int bpf_func_mpls(struct __sk_buff *skb) { __u32 nhoff, label; @@ -279,7 +248,49 @@ PROG(PARSE_MPLS)(struct __sk_buff *skb) return 0; } -SEC("socket/0") +struct { + __uint(type, BPF_MAP_TYPE_PROG_ARRAY); + __uint(key_size, sizeof(u32)); + __uint(max_entries, 8); + __array(values, u32 (void *)); +} prog_array_init SEC(".maps") = { + .values = { + [PARSE_VLAN] = (void *)&bpf_func_vlan, + [PARSE_IP] = (void *)&bpf_func_ip, + [PARSE_IPV6] = (void *)&bpf_func_ipv6, + [PARSE_MPLS] = (void *)&bpf_func_mpls, + }, +}; + +/* Protocol dispatch routine. It tail-calls next BPF program depending + * on eth proto. Note, we could have used ... + * + * bpf_tail_call(skb, &prog_array_init, proto); + * + * ... but it would need large prog_array and cannot be optimised given + * the map key is not static. + */ +static inline void parse_eth_proto(struct __sk_buff *skb, u32 proto) +{ + switch (proto) { + case ETH_P_8021Q: + case ETH_P_8021AD: + bpf_tail_call(skb, &prog_array_init, PARSE_VLAN); + break; + case ETH_P_MPLS_UC: + case ETH_P_MPLS_MC: + bpf_tail_call(skb, &prog_array_init, PARSE_MPLS); + break; + case ETH_P_IP: + bpf_tail_call(skb, &prog_array_init, PARSE_IP); + break; + case ETH_P_IPV6: + bpf_tail_call(skb, &prog_array_init, PARSE_IPV6); + break; + } +} + +SEC("socket") int main_prog(struct __sk_buff *skb) { __u32 nhoff = ETH_HLEN; diff --git a/samples/bpf/sockex3_user.c b/samples/bpf/sockex3_user.c index cd6fa79df9007..56044acbd25da 100644 --- a/samples/bpf/sockex3_user.c +++ b/samples/bpf/sockex3_user.c @@ -24,10 +24,9 @@ struct pair { int main(int argc, char **argv) { - int i, sock, key, fd, main_prog_fd, jmp_table_fd, hash_map_fd; + int i, sock, fd, main_prog_fd, hash_map_fd; struct bpf_program *prog; struct bpf_object *obj; - const char *section; char filename[256]; FILE *f; @@ -45,26 +44,24 @@ int main(int argc, char **argv) goto cleanup; } - jmp_table_fd = bpf_object__find_map_fd_by_name(obj, "jmp_table"); hash_map_fd = bpf_object__find_map_fd_by_name(obj, "hash_map"); - if (jmp_table_fd < 0 || hash_map_fd < 0) { + if (hash_map_fd < 0) { fprintf(stderr, "ERROR: finding a map in obj file failed\n"); goto cleanup; } + /* find BPF main program */ + main_prog_fd = 0; bpf_object__for_each_program(prog, obj) { fd = bpf_program__fd(prog); - section = bpf_program__section_name(prog); - if (sscanf(section, "socket/%d", &key) != 1) { - fprintf(stderr, "ERROR: finding prog failed\n"); - goto cleanup; - } - - if (key == 0) + if (!strcmp(bpf_program__name(prog), "main_prog")) main_prog_fd = fd; - else - bpf_map_update_elem(jmp_table_fd, &key, &fd, BPF_ANY); + } + + if (main_prog_fd == 0) { + fprintf(stderr, "ERROR: can't find main_prog\n"); + goto cleanup; } sock = open_raw_sock("lo"); -- cgit 1.2.3-korg From ee748cd95e3adf4acdb05194b2ea68e4073e09b6 Mon Sep 17 00:00:00 2001 From: Tiezhu Yang Date: Fri, 18 Nov 2022 17:50:01 +0800 Subject: bpf, samples: Use "grep -E" instead of "egrep" The latest version of grep (3.8+) claims the egrep is now obsolete so the build now contains warnings that look like: egrep: warning: egrep is obsolescent; using grep -E Fix this up by moving the related file to use "grep -E" instead. Signed-off-by: Tiezhu Yang Signed-off-by: Daniel Borkmann Acked-by: Jiri Olsa Link: https://lore.kernel.org/bpf/1668765001-12477-1-git-send-email-yangtiezhu@loongson.cn --- samples/bpf/test_cgrp2_tc.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'samples') diff --git a/samples/bpf/test_cgrp2_tc.sh b/samples/bpf/test_cgrp2_tc.sh index 12faf5847e22c..395573be6ae8b 100755 --- a/samples/bpf/test_cgrp2_tc.sh +++ b/samples/bpf/test_cgrp2_tc.sh @@ -115,7 +115,7 @@ do_exit() { if [ "$DEBUG" == "yes" ] && [ "$MODE" != 'cleanuponly' ] then echo "------ DEBUG ------" - echo "mount: "; mount | egrep '(cgroup2|bpf)'; echo + echo "mount: "; mount | grep -E '(cgroup2|bpf)'; echo echo "$CGRP2_TC_LEAF: "; ls -l $CGRP2_TC_LEAF; echo if [ -d "$BPF_FS_TC_SHARE" ] then -- cgit 1.2.3-korg From 6dcd6d0152200794a26b52ff762a110268551ba6 Mon Sep 17 00:00:00 2001 From: Tiezhu Yang Date: Sat, 19 Nov 2022 10:55:04 +0800 Subject: samples: pktgen: Use "grep -E" instead of "egrep" The latest version of grep claims the egrep is now obsolete so the build now contains warnings that look like: egrep: warning: egrep is obsolescent; using grep -E fix this up by moving the related file to use "grep -E" instead. sed -i "s/egrep/grep -E/g" `grep egrep -rwl samples/pktgen` Here are the steps to install the latest grep: wget http://ftp.gnu.org/gnu/grep/grep-3.8.tar.gz tar xf grep-3.8.tar.gz cd grep-3.8 && ./configure && make sudo make install export PATH=/usr/local/bin:$PATH Signed-off-by: Tiezhu Yang Link: https://lore.kernel.org/r/1668826504-32162-1-git-send-email-yangtiezhu@loongson.cn Signed-off-by: Paolo Abeni --- samples/pktgen/functions.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'samples') diff --git a/samples/pktgen/functions.sh b/samples/pktgen/functions.sh index 933194257a24f..dd4e53ae9b734 100644 --- a/samples/pktgen/functions.sh +++ b/samples/pktgen/functions.sh @@ -191,7 +191,7 @@ function extend_addr6() fi # if shrink '::' occurs multiple, it's malformed. - shrink=( $(egrep -o "$sep{2,}" <<< $addr) ) + shrink=( $(grep -E -o "$sep{2,}" <<< $addr) ) if [[ ${#shrink[@]} -ne 0 ]]; then if [[ ${#shrink[@]} -gt 1 || ( ${shrink[0]} != $sep2 ) ]]; then err 5 "Invalid IP6 address: $1" -- cgit 1.2.3-korg From 19a2bdbaaddc71405494bd35fa034d9cf582b05e Mon Sep 17 00:00:00 2001 From: Rong Tao Date: Tue, 22 Nov 2022 10:32:56 +0800 Subject: samples/bpf: Fix wrong allocation size in xdp_router_ipv4_user prefix_key->data allocates three bytes using alloca(), but four bytes are actually accessed in the program. Signed-off-by: Rong Tao Signed-off-by: Daniel Borkmann Link: https://lore.kernel.org/bpf/tencent_F9E2E81922B0C181D05B96DAE5AB0ACE6B06@qq.com --- samples/bpf/xdp_router_ipv4_user.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'samples') diff --git a/samples/bpf/xdp_router_ipv4_user.c b/samples/bpf/xdp_router_ipv4_user.c index 683913bbf2797..9d41db09c4800 100644 --- a/samples/bpf/xdp_router_ipv4_user.c +++ b/samples/bpf/xdp_router_ipv4_user.c @@ -162,7 +162,7 @@ static void read_route(struct nlmsghdr *nh, int nll) __be32 gw; } *prefix_value; - prefix_key = alloca(sizeof(*prefix_key) + 3); + prefix_key = alloca(sizeof(*prefix_key) + 4); prefix_value = alloca(sizeof(*prefix_value)); prefix_key->prefixlen = 32; -- cgit 1.2.3-korg