> On Apr 11, 2022, at 6:02 AM, Liu Jian <liujian56@xxxxxxxxxx> wrote: > > Use bpf_prog_test_run_opts to test the skb_load_bytes function. > Tests behavior when offset is greater than INT_MAX or a normal value. > > Signed-off-by: Liu Jian <liujian56@xxxxxxxxxx> > --- > .../selftests/bpf/prog_tests/skb_load_bytes.c | 65 +++++++++++++++++++ > .../selftests/bpf/progs/skb_load_bytes.c | 37 +++++++++++ > 2 files changed, 102 insertions(+) > create mode 100644 tools/testing/selftests/bpf/prog_tests/skb_load_bytes.c > create mode 100644 tools/testing/selftests/bpf/progs/skb_load_bytes.c > > diff --git a/tools/testing/selftests/bpf/prog_tests/skb_load_bytes.c b/tools/testing/selftests/bpf/prog_tests/skb_load_bytes.c > new file mode 100644 > index 000000000000..2e86f81d85f1 > --- /dev/null > +++ b/tools/testing/selftests/bpf/prog_tests/skb_load_bytes.c > @@ -0,0 +1,65 @@ > +// SPDX-License-Identifier: GPL-2.0 > +#include <test_progs.h> > +#include <network_helpers.h> > + > +void test_skb_load_bytes(void) > +{ > + struct bpf_map *test_result; > + > + __u32 map_key = 0; > + __u32 map_value = 0; > + > + struct bpf_object *obj; > + int err, map_fd, prog_fd; > + > + struct __sk_buff skb = { 0 }; > + > + LIBBPF_OPTS(bpf_test_run_opts, tattr, > + .data_in = &pkt_v4, > + .data_size_in = sizeof(pkt_v4), > + .ctx_in = &skb, > + .ctx_size_in = sizeof(skb), > + ); > + > + err = bpf_prog_test_load("./skb_load_bytes.o", BPF_PROG_TYPE_SCHED_CLS, &obj, > + &prog_fd); Why don't we use bpf skeleton? > + if (CHECK_ATTR(err, "load", "err %d errno %d\n", err, errno)) > + return; > + > + test_result = bpf_object__find_map_by_name(obj, "test_result"); > + if (CHECK_FAIL(!test_result)) > + goto close_bpf_object; > + > + map_fd = bpf_map__fd(test_result); > + if (map_fd < 0) > + goto close_bpf_object; > + > + map_key = 0; > + map_value = -1; > + err = bpf_map_update_elem(map_fd, &map_key, &map_value, BPF_ANY); > + if (CHECK_FAIL(err)) > + goto close_bpf_object; > + tattr.data_out = NULL; > + tattr.data_size_out = 0; > + err = bpf_prog_test_run_opts(prog_fd, &tattr); > + CHECK_ATTR(err != 0, "offset -1", "err %d errno %d\n", err, errno); > + map_key = 1; > + bpf_map_lookup_elem(map_fd, &map_key, &map_value); > + CHECK_ATTR(map_value != -14, "offset -1", "get result error\n"); > + > + map_key = 0; > + map_value = 10; > + err = bpf_map_update_elem(map_fd, &map_key, &map_value, BPF_ANY); > + if (CHECK_FAIL(err)) > + goto close_bpf_object; > + tattr.data_out = NULL; > + tattr.data_size_out = 0; > + err = bpf_prog_test_run_opts(prog_fd, &tattr); > + CHECK_ATTR(err != 0, "offset 10", "err %d errno %d\n", err, errno); > + map_key = 1; > + bpf_map_lookup_elem(map_fd, &map_key, &map_value); > + CHECK_ATTR(map_value != 0, "offset 10", "get result error\n"); > + > +close_bpf_object: > + bpf_object__close(obj); > +} > diff --git a/tools/testing/selftests/bpf/progs/skb_load_bytes.c b/tools/testing/selftests/bpf/progs/skb_load_bytes.c > new file mode 100644 > index 000000000000..1652540aa45d > --- /dev/null > +++ b/tools/testing/selftests/bpf/progs/skb_load_bytes.c > @@ -0,0 +1,37 @@ > +// SPDX-License-Identifier: GPL-2.0 > + > +#include <linux/bpf.h> > +#include <bpf/bpf_helpers.h> > + > +char _license[] SEC("license") = "GPL"; > + > +struct { > + __uint(type, BPF_MAP_TYPE_ARRAY); > + __uint(max_entries, 2); > + __type(key, __u32); > + __type(value, __u32); > +} test_result SEC(".maps"); We can simplify the code with BPF global variable for these. It is technical equivalent to a map, but much easier to use. > + > +SEC("tc") > +int skb_process(struct __sk_buff *skb) > +{ > + char buf[16]; > + int ret = 0; > + __u32 map_key = 0; > + __u32 *offset = NULL; > + > + offset = bpf_map_lookup_elem(&test_result, &map_key); > + if (offset == NULL) { > + bpf_printk("get offset failed\n"); bpf_printk doesn't add much value in selftests. > + map_key = 1; > + ret = -1; > + bpf_map_update_elem(&test_result, &map_key, &ret, BPF_ANY); > + return ret; > + } > + > + ret = bpf_skb_load_bytes(skb, *offset, buf, 10); > + map_key = 1; > + bpf_map_update_elem(&test_result, &map_key, &ret, BPF_ANY); > + > + return 0; > +} > -- > 2.17.1 >