Add a selftest for the newly added bpf_skb_rx_checksum() kfunc. The test consists of a TC BPF program that calls the kfunc and records which checksum type each packet has in a per-type counter map, and a userspace test runner that exercises two scenarios:
- csum_none: runs with bpf_prog_test_run_opts (no special flags), verifies all packets are reported as CHECKSUM_NONE. - csum_complete: runs with BPF_F_TEST_SKB_CHECKSUM_COMPLETE flag, verifies all packets are reported as CHECKSUM_COMPLETE. Signed-off-by: Lorenzo Bianconi <[email protected]> --- tools/testing/selftests/bpf/bpf_kfuncs.h | 8 ++++ .../selftests/bpf/prog_tests/skb_rx_checksum.c | 50 ++++++++++++++++++++++ .../testing/selftests/bpf/progs/skb_rx_checksum.c | 33 ++++++++++++++ tools/testing/selftests/bpf/skb_rx_checksum.h | 8 ++++ 4 files changed, 99 insertions(+) diff --git a/tools/testing/selftests/bpf/bpf_kfuncs.h b/tools/testing/selftests/bpf/bpf_kfuncs.h index ae71e9b69051..d03572e26df2 100644 --- a/tools/testing/selftests/bpf/bpf_kfuncs.h +++ b/tools/testing/selftests/bpf/bpf_kfuncs.h @@ -64,6 +64,14 @@ struct bpf_tcp_req_attrs; extern int bpf_sk_assign_tcp_reqsk(struct __sk_buff *skb, struct sock *sk, struct bpf_tcp_req_attrs *attrs, int attrs__sz) __ksym; +/* Description + * Read skb RX checksum info (ip_summed and csum_meta). + * Returns + * 0 on success + */ +extern int bpf_skb_rx_checksum(struct __sk_buff *skb, __u32 *ip_summed, + __u32 *csum_meta) __ksym; + void *bpf_cast_to_kern_ctx(void *) __ksym; extern void *bpf_rdonly_cast(const void *obj, __u32 btf_id) __ksym __weak; diff --git a/tools/testing/selftests/bpf/prog_tests/skb_rx_checksum.c b/tools/testing/selftests/bpf/prog_tests/skb_rx_checksum.c new file mode 100644 index 000000000000..d71ab7c70b68 --- /dev/null +++ b/tools/testing/selftests/bpf/prog_tests/skb_rx_checksum.c @@ -0,0 +1,50 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <test_progs.h> +#include <network_helpers.h> +#include "skb_rx_checksum.skel.h" +#include "skb_rx_checksum.h" + +#define TX_PACKETS 3 + +static int run_test(__u32 flags, enum skb_csum expected_csum) +{ + LIBBPF_OPTS(bpf_test_run_opts, topts, + .data_in = &pkt_v4, + .data_size_in = sizeof(pkt_v4), + .repeat = TX_PACKETS, + .flags = flags, + ); + int prog_fd, err, key = expected_csum; + struct skb_rx_checksum *skel; + __u64 cnt; + + skel = skb_rx_checksum__open_and_load(); + if (!ASSERT_OK_PTR(skel, "skel_open_and_load")) + return -1; + + prog_fd = bpf_program__fd(skel->progs.tc_rx_csum); + err = bpf_prog_test_run_opts(prog_fd, &topts); + if (!ASSERT_OK(err, "test_run")) + goto cleanup; + + if (!ASSERT_EQ(topts.retval, 0, "retval")) + goto cleanup; + + err = bpf_map_lookup_elem(bpf_map__fd(skel->maps.csum_cnt), &key, &cnt); + if (!ASSERT_OK(err, "map_lookup")) + goto cleanup; + + ASSERT_EQ(cnt, TX_PACKETS, "csum_cnt"); +cleanup: + skb_rx_checksum__destroy(skel); + return 0; +} + +void test_skb_rx_checksum(void) +{ + if (test__start_subtest("csum_none")) + run_test(0, SKB_CSUM_NONE); + + if (test__start_subtest("csum_complete")) + run_test(BPF_F_TEST_SKB_CHECKSUM_COMPLETE, SKB_CSUM_COMPLETE); +} diff --git a/tools/testing/selftests/bpf/progs/skb_rx_checksum.c b/tools/testing/selftests/bpf/progs/skb_rx_checksum.c new file mode 100644 index 000000000000..dc4e192905d5 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/skb_rx_checksum.c @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include <linux/bpf.h> +#include <linux/pkt_cls.h> +#include <bpf/bpf_helpers.h> +#include "bpf_kfuncs.h" +#include "skb_rx_checksum.h" + +struct { + __uint(type, BPF_MAP_TYPE_ARRAY); + __uint(max_entries, SKB_CSUM_PARTIAL); + __type(key, __u32); + __type(value, __u64); +} csum_cnt SEC(".maps"); + +SEC("tc") +int tc_rx_csum(struct __sk_buff *skb) +{ + enum skb_csum ip_summed; + __u32 csum_meta; + __u64 *cnt; + + bpf_skb_rx_checksum(skb, &ip_summed, &csum_meta); + if (ip_summed < SKB_CSUM_PARTIAL) { + cnt = bpf_map_lookup_elem(&csum_cnt, &ip_summed); + if (cnt) + __sync_fetch_and_add(cnt, 1); + } + + return TC_ACT_OK; +} + +char _license[] SEC("license") = "GPL"; diff --git a/tools/testing/selftests/bpf/skb_rx_checksum.h b/tools/testing/selftests/bpf/skb_rx_checksum.h new file mode 100644 index 000000000000..60aad3561843 --- /dev/null +++ b/tools/testing/selftests/bpf/skb_rx_checksum.h @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +enum skb_csum { + SKB_CSUM_NONE = 0, + SKB_CSUM_UNNECESSARY = 1, + SKB_CSUM_COMPLETE = 2, + SKB_CSUM_PARTIAL = 3, +}; -- 2.55.0
