Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

bpf: selftests: update xdp_adjust_tail selftest to include xdp frags

This change adds test cases for the xdp frags scenarios when shrinking
and growing.

Acked-by: Toke Hoiland-Jorgensen <toke@redhat.com>
Acked-by: John Fastabend <john.fastabend@gmail.com>
Co-developed-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Eelco Chaudron <echaudro@redhat.com>
Link: https://lore.kernel.org/r/d2e6a0ebc52db6f89e62b9befe045032e5e0a5fe.1642758637.git.lorenzo@kernel.org
Signed-off-by: Alexei Starovoitov <ast@kernel.org>

authored by

Eelco Chaudron and committed by
Alexei Starovoitov
11022108 7855e0db

+160 -7
+125
tools/testing/selftests/bpf/prog_tests/xdp_adjust_tail.c
··· 118 118 bpf_object__close(obj); 119 119 } 120 120 121 + void test_xdp_adjust_frags_tail_shrink(void) 122 + { 123 + const char *file = "./test_xdp_adjust_tail_shrink.o"; 124 + __u32 duration, retval, size, exp_size; 125 + struct bpf_program *prog; 126 + struct bpf_object *obj; 127 + int err, prog_fd; 128 + __u8 *buf; 129 + 130 + /* For the individual test cases, the first byte in the packet 131 + * indicates which test will be run. 132 + */ 133 + obj = bpf_object__open(file); 134 + if (libbpf_get_error(obj)) 135 + return; 136 + 137 + prog = bpf_object__next_program(obj, NULL); 138 + if (bpf_object__load(obj)) 139 + return; 140 + 141 + prog_fd = bpf_program__fd(prog); 142 + 143 + buf = malloc(9000); 144 + if (!ASSERT_OK_PTR(buf, "alloc buf 9Kb")) 145 + goto out; 146 + 147 + memset(buf, 0, 9000); 148 + 149 + /* Test case removing 10 bytes from last frag, NOT freeing it */ 150 + exp_size = 8990; /* 9000 - 10 */ 151 + err = bpf_prog_test_run(prog_fd, 1, buf, 9000, 152 + buf, &size, &retval, &duration); 153 + 154 + ASSERT_OK(err, "9Kb-10b"); 155 + ASSERT_EQ(retval, XDP_TX, "9Kb-10b retval"); 156 + ASSERT_EQ(size, exp_size, "9Kb-10b size"); 157 + 158 + /* Test case removing one of two pages, assuming 4K pages */ 159 + buf[0] = 1; 160 + exp_size = 4900; /* 9000 - 4100 */ 161 + err = bpf_prog_test_run(prog_fd, 1, buf, 9000, 162 + buf, &size, &retval, &duration); 163 + 164 + ASSERT_OK(err, "9Kb-4Kb"); 165 + ASSERT_EQ(retval, XDP_TX, "9Kb-4Kb retval"); 166 + ASSERT_EQ(size, exp_size, "9Kb-4Kb size"); 167 + 168 + /* Test case removing two pages resulting in a linear xdp_buff */ 169 + buf[0] = 2; 170 + exp_size = 800; /* 9000 - 8200 */ 171 + err = bpf_prog_test_run(prog_fd, 1, buf, 9000, 172 + buf, &size, &retval, &duration); 173 + 174 + ASSERT_OK(err, "9Kb-9Kb"); 175 + ASSERT_EQ(retval, XDP_TX, "9Kb-9Kb retval"); 176 + ASSERT_EQ(size, exp_size, "9Kb-9Kb size"); 177 + 178 + free(buf); 179 + out: 180 + bpf_object__close(obj); 181 + } 182 + 183 + void test_xdp_adjust_frags_tail_grow(void) 184 + { 185 + const char *file = "./test_xdp_adjust_tail_grow.o"; 186 + __u32 duration, retval, size, exp_size; 187 + struct bpf_program *prog; 188 + struct bpf_object *obj; 189 + int err, i, prog_fd; 190 + __u8 *buf; 191 + 192 + obj = bpf_object__open(file); 193 + if (libbpf_get_error(obj)) 194 + return; 195 + 196 + prog = bpf_object__next_program(obj, NULL); 197 + if (bpf_object__load(obj)) 198 + return; 199 + 200 + prog_fd = bpf_program__fd(prog); 201 + 202 + buf = malloc(16384); 203 + if (!ASSERT_OK_PTR(buf, "alloc buf 16Kb")) 204 + goto out; 205 + 206 + /* Test case add 10 bytes to last frag */ 207 + memset(buf, 1, 16384); 208 + size = 9000; 209 + exp_size = size + 10; 210 + err = bpf_prog_test_run(prog_fd, 1, buf, size, 211 + buf, &size, &retval, &duration); 212 + 213 + ASSERT_OK(err, "9Kb+10b"); 214 + ASSERT_EQ(retval, XDP_TX, "9Kb+10b retval"); 215 + ASSERT_EQ(size, exp_size, "9Kb+10b size"); 216 + 217 + for (i = 0; i < 9000; i++) 218 + ASSERT_EQ(buf[i], 1, "9Kb+10b-old"); 219 + 220 + for (i = 9000; i < 9010; i++) 221 + ASSERT_EQ(buf[i], 0, "9Kb+10b-new"); 222 + 223 + for (i = 9010; i < 16384; i++) 224 + ASSERT_EQ(buf[i], 1, "9Kb+10b-untouched"); 225 + 226 + /* Test a too large grow */ 227 + memset(buf, 1, 16384); 228 + size = 9001; 229 + exp_size = size; 230 + err = bpf_prog_test_run(prog_fd, 1, buf, size, 231 + buf, &size, &retval, &duration); 232 + 233 + ASSERT_OK(err, "9Kb+10b"); 234 + ASSERT_EQ(retval, XDP_DROP, "9Kb+10b retval"); 235 + ASSERT_EQ(size, exp_size, "9Kb+10b size"); 236 + 237 + free(buf); 238 + out: 239 + bpf_object__close(obj); 240 + } 241 + 121 242 void test_xdp_adjust_tail(void) 122 243 { 123 244 if (test__start_subtest("xdp_adjust_tail_shrink")) ··· 247 126 test_xdp_adjust_tail_grow(); 248 127 if (test__start_subtest("xdp_adjust_tail_grow2")) 249 128 test_xdp_adjust_tail_grow2(); 129 + if (test__start_subtest("xdp_adjust_frags_tail_shrink")) 130 + test_xdp_adjust_frags_tail_shrink(); 131 + if (test__start_subtest("xdp_adjust_frags_tail_grow")) 132 + test_xdp_adjust_frags_tail_grow(); 250 133 }
+7 -3
tools/testing/selftests/bpf/progs/test_xdp_adjust_tail_grow.c
··· 7 7 { 8 8 void *data_end = (void *)(long)xdp->data_end; 9 9 void *data = (void *)(long)xdp->data; 10 - unsigned int data_len; 10 + int data_len = bpf_xdp_get_buff_len(xdp); 11 11 int offset = 0; 12 12 13 13 /* Data length determine test case */ 14 - data_len = data_end - data; 15 14 16 15 if (data_len == 54) { /* sizeof(pkt_v4) */ 17 16 offset = 4096; /* test too large offset */ ··· 19 20 } else if (data_len == 64) { 20 21 offset = 128; 21 22 } else if (data_len == 128) { 22 - offset = 4096 - 256 - 320 - data_len; /* Max tail grow 3520 */ 23 + /* Max tail grow 3520 */ 24 + offset = 4096 - 256 - 320 - data_len; 25 + } else if (data_len == 9000) { 26 + offset = 10; 27 + } else if (data_len == 9001) { 28 + offset = 4096; 23 29 } else { 24 30 return XDP_ABORTED; /* No matching test */ 25 31 }
+28 -4
tools/testing/selftests/bpf/progs/test_xdp_adjust_tail_shrink.c
··· 12 12 SEC("xdp") 13 13 int _xdp_adjust_tail_shrink(struct xdp_md *xdp) 14 14 { 15 - void *data_end = (void *)(long)xdp->data_end; 16 - void *data = (void *)(long)xdp->data; 15 + __u8 *data_end = (void *)(long)xdp->data_end; 16 + __u8 *data = (void *)(long)xdp->data; 17 17 int offset = 0; 18 18 19 - if (data_end - data == 54) /* sizeof(pkt_v4) */ 19 + switch (bpf_xdp_get_buff_len(xdp)) { 20 + case 54: 21 + /* sizeof(pkt_v4) */ 20 22 offset = 256; /* shrink too much */ 21 - else 23 + break; 24 + case 9000: 25 + /* non-linear buff test cases */ 26 + if (data + 1 > data_end) 27 + return XDP_DROP; 28 + 29 + switch (data[0]) { 30 + case 0: 31 + offset = 10; 32 + break; 33 + case 1: 34 + offset = 4100; 35 + break; 36 + case 2: 37 + offset = 8200; 38 + break; 39 + default: 40 + return XDP_DROP; 41 + } 42 + break; 43 + default: 22 44 offset = 20; 45 + break; 46 + } 23 47 if (bpf_xdp_adjust_tail(xdp, 0 - offset)) 24 48 return XDP_DROP; 25 49 return XDP_TX;