[RFC,bpf-next,13/13] selftests/bpf: Add selftest for bpf namespace

Message ID 20230326092208.13613-14-laoar.shao@gmail.com
State New
Headers
Series bpf: Introduce BPF namespace |

Commit Message

Yafang Shao March 26, 2023, 9:22 a.m. UTC
  A simple test case is added for the newly introduced bpf namespcae.

Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
---
 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
  

Patch

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;
+}