diff options
Diffstat (limited to 'tools/testing/selftests/bpf/prog_tests/trampoline_count.c')
-rw-r--r-- | tools/testing/selftests/bpf/prog_tests/trampoline_count.c | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/tools/testing/selftests/bpf/prog_tests/trampoline_count.c b/tools/testing/selftests/bpf/prog_tests/trampoline_count.c new file mode 100644 index 0000000000..6cd7349d4a --- /dev/null +++ b/tools/testing/selftests/bpf/prog_tests/trampoline_count.c @@ -0,0 +1,100 @@ +// SPDX-License-Identifier: GPL-2.0-only +#define _GNU_SOURCE +#include <test_progs.h> + +struct inst { + struct bpf_object *obj; + struct bpf_link *link; +}; + +static struct bpf_program *load_prog(char *file, char *name, struct inst *inst) +{ + struct bpf_object *obj; + struct bpf_program *prog; + int err; + + obj = bpf_object__open_file(file, NULL); + if (!ASSERT_OK_PTR(obj, "obj_open_file")) + return NULL; + + inst->obj = obj; + + err = bpf_object__load(obj); + if (!ASSERT_OK(err, "obj_load")) + return NULL; + + prog = bpf_object__find_program_by_name(obj, name); + if (!ASSERT_OK_PTR(prog, "obj_find_prog")) + return NULL; + + return prog; +} + +/* TODO: use different target function to run in concurrent mode */ +void serial_test_trampoline_count(void) +{ + char *file = "test_trampoline_count.bpf.o"; + char *const progs[] = { "fentry_test", "fmod_ret_test", "fexit_test" }; + int bpf_max_tramp_links, err, i, prog_fd; + struct bpf_program *prog; + struct bpf_link *link; + struct inst *inst; + LIBBPF_OPTS(bpf_test_run_opts, opts); + + bpf_max_tramp_links = get_bpf_max_tramp_links(); + if (!ASSERT_GE(bpf_max_tramp_links, 1, "bpf_max_tramp_links")) + return; + inst = calloc(bpf_max_tramp_links + 1, sizeof(*inst)); + if (!ASSERT_OK_PTR(inst, "inst")) + return; + + /* attach 'allowed' trampoline programs */ + for (i = 0; i < bpf_max_tramp_links; i++) { + prog = load_prog(file, progs[i % ARRAY_SIZE(progs)], &inst[i]); + if (!prog) + goto cleanup; + + link = bpf_program__attach(prog); + if (!ASSERT_OK_PTR(link, "attach_prog")) + goto cleanup; + + inst[i].link = link; + } + + /* and try 1 extra.. */ + prog = load_prog(file, "fmod_ret_test", &inst[i]); + if (!prog) + goto cleanup; + + /* ..that needs to fail */ + link = bpf_program__attach(prog); + if (!ASSERT_ERR_PTR(link, "attach_prog")) { + inst[i].link = link; + goto cleanup; + } + + /* with E2BIG error */ + if (!ASSERT_EQ(libbpf_get_error(link), -E2BIG, "E2BIG")) + goto cleanup; + if (!ASSERT_EQ(link, NULL, "ptr_is_null")) + goto cleanup; + + /* and finally execute the probe */ + prog_fd = bpf_program__fd(prog); + if (!ASSERT_GE(prog_fd, 0, "bpf_program__fd")) + goto cleanup; + + err = bpf_prog_test_run_opts(prog_fd, &opts); + if (!ASSERT_OK(err, "bpf_prog_test_run_opts")) + goto cleanup; + + ASSERT_EQ(opts.retval & 0xffff, 33, "bpf_modify_return_test.result"); + ASSERT_EQ(opts.retval >> 16, 2, "bpf_modify_return_test.side_effect"); + +cleanup: + for (; i >= 0; i--) { + bpf_link__destroy(inst[i].link); + bpf_object__close(inst[i].obj); + } + free(inst); +} |