Add two test cases for BPF STRUCT_OPS: one to check the return value of BPF_PROG_TYPE_STRUCT_OPS is returned, another to check the returned value through output parameter is expected. Signed-off-by: Hou Tao <houtao1@xxxxxxxxxx> --- .../selftests/bpf/prog_tests/bpf_dummy_ops.c | 95 +++++++++++++++++++ .../selftests/bpf/progs/bpf_dummy_ops.c | 34 +++++++ 2 files changed, 129 insertions(+) create mode 100644 tools/testing/selftests/bpf/prog_tests/bpf_dummy_ops.c create mode 100644 tools/testing/selftests/bpf/progs/bpf_dummy_ops.c diff --git a/tools/testing/selftests/bpf/prog_tests/bpf_dummy_ops.c b/tools/testing/selftests/bpf/prog_tests/bpf_dummy_ops.c new file mode 100644 index 000000000000..d9a45579c716 --- /dev/null +++ b/tools/testing/selftests/bpf/prog_tests/bpf_dummy_ops.c @@ -0,0 +1,95 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (C) 2021. Huawei Technologies Co., Ltd */ +#include <linux/err.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <stdlib.h> +#include <assert.h> +#include <string.h> +#include <errno.h> +#include <test_progs.h> + +#include "bpf_dummy_ops.skel.h" + +#define OPS_CTL_CMD_SIZE 64 + +static void do_ctl(const char *cmd) +{ + int duration = 0; + int fd; + size_t len; + ssize_t wr; + + fd = open("/sys/kernel/bpf_test/dummy_ops_ctl", O_WRONLY); + if (CHECK(fd < 0, "open", "open errno %d", errno)) + goto out; + + len = strlen(cmd); + wr = write(fd, cmd, len); + if (CHECK(wr != len, "write", "write cmd %s errno %d", cmd, errno)) + goto out; +out: + if (fd >= 0) + close(fd); +} + +static void test_ret_value(void) +{ + int duration = 0; + struct bpf_dummy_ops *skel; + struct bpf_link *link; + char cmd[OPS_CTL_CMD_SIZE]; + + skel = bpf_dummy_ops__open_and_load(); + if (CHECK(!skel, "bpf_dummy_ops__open_and_load", "failed\n")) + return; + + skel->bss->init_ret = 1024; + link = bpf_map__attach_struct_ops(skel->maps.dummy); + if (!ASSERT_OK_PTR(link, "bpf_map__attach_struct_ops")) + goto out; + + snprintf(cmd, sizeof(cmd), "init_1 %d", skel->bss->init_ret); + do_ctl(cmd); +out: + bpf_link__destroy(link); + bpf_dummy_ops__destroy(skel); +} + +static void test_ret_by_ptr(void) +{ + int duration = 0; + struct bpf_dummy_ops *skel; + struct bpf_link *link; + char cmd[OPS_CTL_CMD_SIZE]; + + skel = bpf_dummy_ops__open_and_load(); + if (CHECK(!skel, "bpf_dummy_ops__open_and_load", "failed\n")) + return; + + skel->bss->state_val = 0x5a; + link = bpf_map__attach_struct_ops(skel->maps.dummy); + if (!ASSERT_OK_PTR(link, "bpf_map__attach_struct_ops")) + goto out; + + snprintf(cmd, sizeof(cmd), "init_2 %d", skel->bss->state_val); + do_ctl(cmd); +out: + bpf_link__destroy(link); + bpf_dummy_ops__destroy(skel); +} + +void test_bpf_dummy_ops(void) +{ + if (!env.has_testmod) { + test__skip(); + return; + } + + if (test__start_subtest("ret_value")) + test_ret_value(); + if (test__start_subtest("ret_by_ptr")) + test_ret_by_ptr(); +} diff --git a/tools/testing/selftests/bpf/progs/bpf_dummy_ops.c b/tools/testing/selftests/bpf/progs/bpf_dummy_ops.c new file mode 100644 index 000000000000..e414532b3fc0 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/bpf_dummy_ops.c @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (C) 2021. Huawei Technologies Co., Ltd */ +#include <stddef.h> +#include <linux/bpf.h> +#include <linux/types.h> +#include <linux/stddef.h> +#include <bpf/bpf_helpers.h> +#include <bpf/bpf_tracing.h> + +struct bpf_dummy_ops_state { + int val; +}; + +struct bpf_dummy_ops { + int (*init)(void); +}; + +int state_val = 0; +int init_ret = 0; + +SEC("struct_ops/dummy_ops_init") +int BPF_PROG(dummy_ops_init, struct bpf_dummy_ops_state *state) +{ + if (state) + state->val = state_val; + return init_ret; +} + +SEC(".struct_ops") +struct bpf_dummy_ops dummy = { + .init = (void *)dummy_ops_init, +}; + +char _license[] SEC("license") = "GPL"; -- 2.29.2