1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright (c) 2022 Facebook */ 3 4 #include <test_progs.h> 5 #include <network_helpers.h> 6 #include "dynptr_fail.skel.h" 7 #include "dynptr_success.skel.h" 8 9 enum test_setup_type { 10 SETUP_SYSCALL_SLEEP, 11 SETUP_SKB_PROG, 12 SETUP_SKB_PROG_TP, 13 SETUP_XDP_PROG, 14 }; 15 16 static struct { 17 const char *prog_name; 18 enum test_setup_type type; 19 } success_tests[] = { 20 {"test_read_write", SETUP_SYSCALL_SLEEP}, 21 {"test_dynptr_data", SETUP_SYSCALL_SLEEP}, 22 {"test_dynptr_copy", SETUP_SYSCALL_SLEEP}, 23 {"test_dynptr_copy_xdp", SETUP_XDP_PROG}, 24 {"test_ringbuf", SETUP_SYSCALL_SLEEP}, 25 {"test_skb_readonly", SETUP_SKB_PROG}, 26 {"test_dynptr_skb_data", SETUP_SKB_PROG}, 27 {"test_adjust", SETUP_SYSCALL_SLEEP}, 28 {"test_adjust_err", SETUP_SYSCALL_SLEEP}, 29 {"test_zero_size_dynptr", SETUP_SYSCALL_SLEEP}, 30 {"test_dynptr_is_null", SETUP_SYSCALL_SLEEP}, 31 {"test_dynptr_is_rdonly", SETUP_SKB_PROG}, 32 {"test_dynptr_clone", SETUP_SKB_PROG}, 33 {"test_dynptr_skb_no_buff", SETUP_SKB_PROG}, 34 {"test_dynptr_skb_strcmp", SETUP_SKB_PROG}, 35 {"test_dynptr_skb_tp_btf", SETUP_SKB_PROG_TP}, 36 }; 37 38 static void verify_success(const char *prog_name, enum test_setup_type setup_type) 39 { 40 struct dynptr_success *skel; 41 struct bpf_program *prog; 42 struct bpf_link *link; 43 int err; 44 45 skel = dynptr_success__open(); 46 if (!ASSERT_OK_PTR(skel, "dynptr_success__open")) 47 return; 48 49 skel->bss->pid = getpid(); 50 51 prog = bpf_object__find_program_by_name(skel->obj, prog_name); 52 if (!ASSERT_OK_PTR(prog, "bpf_object__find_program_by_name")) 53 goto cleanup; 54 55 bpf_program__set_autoload(prog, true); 56 57 err = dynptr_success__load(skel); 58 if (!ASSERT_OK(err, "dynptr_success__load")) 59 goto cleanup; 60 61 switch (setup_type) { 62 case SETUP_SYSCALL_SLEEP: 63 link = bpf_program__attach(prog); 64 if (!ASSERT_OK_PTR(link, "bpf_program__attach")) 65 goto cleanup; 66 67 usleep(1); 68 69 bpf_link__destroy(link); 70 break; 71 case SETUP_SKB_PROG: 72 { 73 int prog_fd; 74 char buf[64]; 75 76 LIBBPF_OPTS(bpf_test_run_opts, topts, 77 .data_in = &pkt_v4, 78 .data_size_in = sizeof(pkt_v4), 79 .data_out = buf, 80 .data_size_out = sizeof(buf), 81 .repeat = 1, 82 ); 83 84 prog_fd = bpf_program__fd(prog); 85 if (!ASSERT_GE(prog_fd, 0, "prog_fd")) 86 goto cleanup; 87 88 err = bpf_prog_test_run_opts(prog_fd, &topts); 89 90 if (!ASSERT_OK(err, "test_run")) 91 goto cleanup; 92 93 break; 94 } 95 case SETUP_SKB_PROG_TP: 96 { 97 struct __sk_buff skb = {}; 98 struct bpf_object *obj; 99 int aux_prog_fd; 100 101 /* Just use its test_run to trigger kfree_skb tracepoint */ 102 err = bpf_prog_test_load("./test_pkt_access.bpf.o", BPF_PROG_TYPE_SCHED_CLS, 103 &obj, &aux_prog_fd); 104 if (!ASSERT_OK(err, "prog_load sched cls")) 105 goto cleanup; 106 107 LIBBPF_OPTS(bpf_test_run_opts, topts, 108 .data_in = &pkt_v4, 109 .data_size_in = sizeof(pkt_v4), 110 .ctx_in = &skb, 111 .ctx_size_in = sizeof(skb), 112 ); 113 114 link = bpf_program__attach(prog); 115 if (!ASSERT_OK_PTR(link, "bpf_program__attach")) 116 goto cleanup; 117 118 err = bpf_prog_test_run_opts(aux_prog_fd, &topts); 119 bpf_link__destroy(link); 120 121 if (!ASSERT_OK(err, "test_run")) 122 goto cleanup; 123 124 break; 125 } 126 case SETUP_XDP_PROG: 127 { 128 char data[5000]; 129 int err, prog_fd; 130 LIBBPF_OPTS(bpf_test_run_opts, opts, 131 .data_in = &data, 132 .data_size_in = sizeof(data), 133 .repeat = 1, 134 ); 135 136 prog_fd = bpf_program__fd(prog); 137 err = bpf_prog_test_run_opts(prog_fd, &opts); 138 139 if (!ASSERT_OK(err, "test_run")) 140 goto cleanup; 141 142 break; 143 } 144 } 145 146 ASSERT_EQ(skel->bss->err, 0, "err"); 147 148 cleanup: 149 dynptr_success__destroy(skel); 150 } 151 152 void test_dynptr(void) 153 { 154 int i; 155 156 for (i = 0; i < ARRAY_SIZE(success_tests); i++) { 157 if (!test__start_subtest(success_tests[i].prog_name)) 158 continue; 159 160 verify_success(success_tests[i].prog_name, success_tests[i].type); 161 } 162 163 RUN_TESTS(dynptr_fail); 164 } 165