1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright (c) 2021 Facebook */ 3 #include <test_progs.h> 4 #include <network_helpers.h> 5 #include "kfunc_call_test.lskel.h" 6 #include "kfunc_call_test_subprog.skel.h" 7 #include "kfunc_call_test_subprog.lskel.h" 8 #include "kfunc_call_destructive.skel.h" 9 10 #include "cap_helpers.h" 11 12 static void test_main(void) 13 { 14 struct kfunc_call_test_lskel *skel; 15 int prog_fd, err; 16 LIBBPF_OPTS(bpf_test_run_opts, topts, 17 .data_in = &pkt_v4, 18 .data_size_in = sizeof(pkt_v4), 19 .repeat = 1, 20 ); 21 22 skel = kfunc_call_test_lskel__open_and_load(); 23 if (!ASSERT_OK_PTR(skel, "skel")) 24 return; 25 26 prog_fd = skel->progs.kfunc_call_test1.prog_fd; 27 err = bpf_prog_test_run_opts(prog_fd, &topts); 28 ASSERT_OK(err, "bpf_prog_test_run(test1)"); 29 ASSERT_EQ(topts.retval, 12, "test1-retval"); 30 31 prog_fd = skel->progs.kfunc_call_test2.prog_fd; 32 err = bpf_prog_test_run_opts(prog_fd, &topts); 33 ASSERT_OK(err, "bpf_prog_test_run(test2)"); 34 ASSERT_EQ(topts.retval, 3, "test2-retval"); 35 36 prog_fd = skel->progs.kfunc_call_test_ref_btf_id.prog_fd; 37 err = bpf_prog_test_run_opts(prog_fd, &topts); 38 ASSERT_OK(err, "bpf_prog_test_run(test_ref_btf_id)"); 39 ASSERT_EQ(topts.retval, 0, "test_ref_btf_id-retval"); 40 41 kfunc_call_test_lskel__destroy(skel); 42 } 43 44 static void test_subprog(void) 45 { 46 struct kfunc_call_test_subprog *skel; 47 int prog_fd, err; 48 LIBBPF_OPTS(bpf_test_run_opts, topts, 49 .data_in = &pkt_v4, 50 .data_size_in = sizeof(pkt_v4), 51 .repeat = 1, 52 ); 53 54 skel = kfunc_call_test_subprog__open_and_load(); 55 if (!ASSERT_OK_PTR(skel, "skel")) 56 return; 57 58 prog_fd = bpf_program__fd(skel->progs.kfunc_call_test1); 59 err = bpf_prog_test_run_opts(prog_fd, &topts); 60 ASSERT_OK(err, "bpf_prog_test_run(test1)"); 61 ASSERT_EQ(topts.retval, 10, "test1-retval"); 62 ASSERT_NEQ(skel->data->active_res, -1, "active_res"); 63 ASSERT_EQ(skel->data->sk_state_res, BPF_TCP_CLOSE, "sk_state_res"); 64 65 kfunc_call_test_subprog__destroy(skel); 66 } 67 68 static void test_subprog_lskel(void) 69 { 70 struct kfunc_call_test_subprog_lskel *skel; 71 int prog_fd, err; 72 LIBBPF_OPTS(bpf_test_run_opts, topts, 73 .data_in = &pkt_v4, 74 .data_size_in = sizeof(pkt_v4), 75 .repeat = 1, 76 ); 77 78 skel = kfunc_call_test_subprog_lskel__open_and_load(); 79 if (!ASSERT_OK_PTR(skel, "skel")) 80 return; 81 82 prog_fd = skel->progs.kfunc_call_test1.prog_fd; 83 err = bpf_prog_test_run_opts(prog_fd, &topts); 84 ASSERT_OK(err, "bpf_prog_test_run(test1)"); 85 ASSERT_EQ(topts.retval, 10, "test1-retval"); 86 ASSERT_NEQ(skel->data->active_res, -1, "active_res"); 87 ASSERT_EQ(skel->data->sk_state_res, BPF_TCP_CLOSE, "sk_state_res"); 88 89 kfunc_call_test_subprog_lskel__destroy(skel); 90 } 91 92 static int test_destructive_open_and_load(void) 93 { 94 struct kfunc_call_destructive *skel; 95 int err; 96 97 skel = kfunc_call_destructive__open(); 98 if (!ASSERT_OK_PTR(skel, "prog_open")) 99 return -1; 100 101 err = kfunc_call_destructive__load(skel); 102 103 kfunc_call_destructive__destroy(skel); 104 105 return err; 106 } 107 108 static void test_destructive(void) 109 { 110 __u64 save_caps = 0; 111 112 ASSERT_OK(test_destructive_open_and_load(), "successful_load"); 113 114 if (!ASSERT_OK(cap_disable_effective(1ULL << CAP_SYS_BOOT, &save_caps), "drop_caps")) 115 return; 116 117 ASSERT_EQ(test_destructive_open_and_load(), -13, "no_caps_failure"); 118 119 cap_enable_effective(save_caps, NULL); 120 } 121 122 void test_kfunc_call(void) 123 { 124 if (test__start_subtest("main")) 125 test_main(); 126 127 if (test__start_subtest("subprog")) 128 test_subprog(); 129 130 if (test__start_subtest("subprog_lskel")) 131 test_subprog_lskel(); 132 133 if (test__start_subtest("destructive")) 134 test_destructive(); 135 } 136