A simple test case is added for the newly introduced bpf namespcae. Signed-off-by: Yafang Shao <laoar.shao@xxxxxxxxx> --- tools/testing/selftests/bpf/Makefile | 3 +- tools/testing/selftests/bpf/test_bpfns.c | 76 ++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/bpf/test_bpfns.c diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile index 4a8ef11..55f0aeb 100644 --- a/tools/testing/selftests/bpf/Makefile +++ b/tools/testing/selftests/bpf/Makefile @@ -40,7 +40,7 @@ TEST_GEN_PROGS = test_verifier test_tag test_maps test_lru_map test_lpm_map test test_sock test_sockmap get_cgroup_id_user \ test_cgroup_storage \ test_tcpnotify_user test_sysctl \ - test_progs-no_alu32 + test_progs-no_alu32 test_bpfns # Also test bpf-gcc, if present ifneq ($(BPF_GCC),) @@ -255,6 +255,7 @@ $(OUTPUT)/flow_dissector_load: $(TESTING_HELPERS) $(OUTPUT)/test_maps: $(TESTING_HELPERS) $(OUTPUT)/test_verifier: $(TESTING_HELPERS) $(CAP_HELPERS) $(UNPRIV_HELPERS) $(OUTPUT)/xsk.o: $(BPFOBJ) +$(OUTPUT)/test_bpfns: $(TESTING_HELPERS) BPFTOOL ?= $(DEFAULT_BPFTOOL) $(DEFAULT_BPFTOOL): $(wildcard $(BPFTOOLDIR)/*.[ch] $(BPFTOOLDIR)/Makefile) \ diff --git a/tools/testing/selftests/bpf/test_bpfns.c b/tools/testing/selftests/bpf/test_bpfns.c new file mode 100644 index 0000000..7baebe2 --- /dev/null +++ b/tools/testing/selftests/bpf/test_bpfns.c @@ -0,0 +1,76 @@ +// SPDX-License-Identifier: GPL-2.0 +#ifndef _GNU_SOURCE +#define _GNU_SOURCE 1 +#endif +#include <unistd.h> +#include <errno.h> +#include <sched.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> +#include <sys/syscall.h> +#include <sys/wait.h> +#include <linux/sched.h> + +#include <bpf/bpf.h> +#include <bpf/libbpf.h> + +static int create_bpf_map(const char *name) +{ + static struct bpf_map_create_opts map_opts = { + .sz = sizeof(map_opts), + }; + unsigned int value; + unsigned int key; + int map_fd; + + map_fd = bpf_map_create(BPF_MAP_TYPE_ARRAY, name, sizeof(key), + sizeof(value), 1, &map_opts); + if (map_fd < 0) + fprintf(stderr, "%s - Failed to create map\n", strerror(errno)); + return map_fd; +} + + +int main(int argc, char *argv[]) +{ + struct bpf_map_info info = {}; + __u32 info_len = sizeof(info); + struct clone_args args = { + .flags = 0x400000000ULL, /* CLONE_NEWBPF */ + .exit_signal = SIGCHLD, + }; + int map_fd, child_map_fd; + pid_t pid; + + /* Create a map in init bpf namespace. */ + map_fd = create_bpf_map("map_in_init"); + if (map_fd < 0) + exit(EXIT_FAILURE); + pid = syscall(__NR_clone3, &args, sizeof(struct clone_args)); + if (pid < 0) { + fprintf(stderr, "%s - Failed to create new process\n", strerror(errno)); + exit(EXIT_FAILURE); + } + + if (pid == 0) { + struct bpf_map_info info = {}; + + /* In a new bpf namespace, it is the first map. */ + child_map_fd = create_bpf_map("map_in_bpfns"); + if (child_map_fd < 0) + exit(EXIT_FAILURE); + bpf_obj_get_info_by_fd(child_map_fd, &info, &info_len); + assert(info.id == 1); + exit(EXIT_SUCCESS); + } + + if (waitpid(pid, NULL, 0) != pid) { + fprintf(stderr, "Failed to wait on child process\n"); + exit(EXIT_FAILURE); + } + + return 0; +} -- 1.8.3.1