selftests/bpf: Add bpf_testmod kernel module for testing
[linux-2.6-microblaze.git] / tools / testing / selftests / bpf / test_progs.c
index 22943b5..1758775 100644 (file)
@@ -360,6 +360,58 @@ err:
        return -1;
 }
 
+static int finit_module(int fd, const char *param_values, int flags)
+{
+       return syscall(__NR_finit_module, fd, param_values, flags);
+}
+
+static int delete_module(const char *name, int flags)
+{
+       return syscall(__NR_delete_module, name, flags);
+}
+
+static void unload_bpf_testmod(void)
+{
+       if (delete_module("bpf_testmod", 0)) {
+               if (errno == ENOENT) {
+                       if (env.verbosity > VERBOSE_NONE)
+                               fprintf(stdout, "bpf_testmod.ko is already unloaded.\n");
+                       return;
+               }
+               fprintf(env.stderr, "Failed to unload bpf_testmod.ko from kernel: %d\n", -errno);
+               exit(1);
+       }
+       if (env.verbosity > VERBOSE_NONE)
+               fprintf(stdout, "Successfully unloaded bpf_testmod.ko.\n");
+}
+
+static int load_bpf_testmod(void)
+{
+       int fd;
+
+       /* ensure previous instance of the module is unloaded */
+       unload_bpf_testmod();
+
+       if (env.verbosity > VERBOSE_NONE)
+               fprintf(stdout, "Loading bpf_testmod.ko...\n");
+
+       fd = open("bpf_testmod.ko", O_RDONLY);
+       if (fd < 0) {
+               fprintf(env.stderr, "Can't find bpf_testmod.ko kernel module: %d\n", -errno);
+               return -ENOENT;
+       }
+       if (finit_module(fd, "", 0)) {
+               fprintf(env.stderr, "Failed to load bpf_testmod.ko into the kernel: %d\n", -errno);
+               close(fd);
+               return -EINVAL;
+       }
+       close(fd);
+
+       if (env.verbosity > VERBOSE_NONE)
+               fprintf(stdout, "Successfully loaded bpf_testmod.ko.\n");
+       return 0;
+}
+
 /* extern declarations for test funcs */
 #define DEFINE_TEST(name) extern void test_##name(void);
 #include <prog_tests/tests.h>
@@ -678,6 +730,11 @@ int main(int argc, char **argv)
 
        save_netns();
        stdio_hijack();
+       env.has_testmod = true;
+       if (load_bpf_testmod()) {
+               fprintf(env.stderr, "WARNING! Selftests relying on bpf_testmod.ko will be skipped.\n");
+               env.has_testmod = false;
+       }
        for (i = 0; i < prog_test_cnt; i++) {
                struct prog_test_def *test = &prog_test_defs[i];
 
@@ -722,6 +779,8 @@ int main(int argc, char **argv)
                if (test->need_cgroup_cleanup)
                        cleanup_cgroup_environment();
        }
+       if (env.has_testmod)
+               unload_bpf_testmod();
        stdio_restore();
 
        if (env.get_test_cnt) {