]>
Commit | Line | Data |
---|---|---|
eaf90740 SF |
1 | // SPDX-License-Identifier: GPL-2.0 |
2 | #include <test_progs.h> | |
488a23b8 | 3 | #include <network_helpers.h> |
eaf90740 | 4 | |
6972dc3b | 5 | static void test_xdp_adjust_tail_shrink(void) |
eaf90740 | 6 | { |
afef88e6 | 7 | const char *file = "./test_xdp_adjust_tail_shrink.bpf.o"; |
04fcb5f9 | 8 | __u32 expect_sz; |
eaf90740 | 9 | struct bpf_object *obj; |
eaf90740 | 10 | int err, prog_fd; |
7ae2e00e | 11 | char buf[128]; |
04fcb5f9 DK |
12 | LIBBPF_OPTS(bpf_test_run_opts, topts, |
13 | .data_in = &pkt_v4, | |
14 | .data_size_in = sizeof(pkt_v4), | |
15 | .data_out = buf, | |
16 | .data_size_out = sizeof(buf), | |
17 | .repeat = 1, | |
18 | ); | |
eaf90740 | 19 | |
cbdb1461 | 20 | err = bpf_prog_test_load(file, BPF_PROG_TYPE_XDP, &obj, &prog_fd); |
791cad02 | 21 | if (ASSERT_OK(err, "test_xdp_adjust_tail_shrink")) |
eaf90740 | 22 | return; |
eaf90740 | 23 | |
04fcb5f9 | 24 | err = bpf_prog_test_run_opts(prog_fd, &topts); |
791cad02 | 25 | ASSERT_OK(err, "ipv4"); |
04fcb5f9 | 26 | ASSERT_EQ(topts.retval, XDP_DROP, "ipv4 retval"); |
eaf90740 | 27 | |
7ae2e00e | 28 | expect_sz = sizeof(pkt_v6) - 20; /* Test shrink with 20 bytes */ |
04fcb5f9 DK |
29 | topts.data_in = &pkt_v6; |
30 | topts.data_size_in = sizeof(pkt_v6); | |
31 | topts.data_size_out = sizeof(buf); | |
32 | err = bpf_prog_test_run_opts(prog_fd, &topts); | |
791cad02 | 33 | ASSERT_OK(err, "ipv6"); |
04fcb5f9 DK |
34 | ASSERT_EQ(topts.retval, XDP_TX, "ipv6 retval"); |
35 | ASSERT_EQ(topts.data_size_out, expect_sz, "ipv6 size"); | |
791cad02 | 36 | |
7ae2e00e JDB |
37 | bpf_object__close(obj); |
38 | } | |
39 | ||
6972dc3b | 40 | static void test_xdp_adjust_tail_grow(void) |
7ae2e00e | 41 | { |
afef88e6 | 42 | const char *file = "./test_xdp_adjust_tail_grow.bpf.o"; |
7ae2e00e JDB |
43 | struct bpf_object *obj; |
44 | char buf[4096]; /* avoid segfault: large buf to hold grow results */ | |
04fcb5f9 | 45 | __u32 expect_sz; |
7ae2e00e | 46 | int err, prog_fd; |
04fcb5f9 DK |
47 | LIBBPF_OPTS(bpf_test_run_opts, topts, |
48 | .data_in = &pkt_v4, | |
49 | .data_size_in = sizeof(pkt_v4), | |
50 | .data_out = buf, | |
51 | .data_size_out = sizeof(buf), | |
52 | .repeat = 1, | |
53 | ); | |
7ae2e00e | 54 | |
cbdb1461 | 55 | err = bpf_prog_test_load(file, BPF_PROG_TYPE_XDP, &obj, &prog_fd); |
791cad02 | 56 | if (ASSERT_OK(err, "test_xdp_adjust_tail_grow")) |
7ae2e00e JDB |
57 | return; |
58 | ||
04fcb5f9 | 59 | err = bpf_prog_test_run_opts(prog_fd, &topts); |
791cad02 | 60 | ASSERT_OK(err, "ipv4"); |
04fcb5f9 | 61 | ASSERT_EQ(topts.retval, XDP_DROP, "ipv4 retval"); |
7ae2e00e JDB |
62 | |
63 | expect_sz = sizeof(pkt_v6) + 40; /* Test grow with 40 bytes */ | |
04fcb5f9 DK |
64 | topts.data_in = &pkt_v6; |
65 | topts.data_size_in = sizeof(pkt_v6); | |
66 | err = bpf_prog_test_run_opts(prog_fd, &topts); | |
791cad02 | 67 | ASSERT_OK(err, "ipv6"); |
04fcb5f9 DK |
68 | ASSERT_EQ(topts.retval, XDP_TX, "ipv6 retval"); |
69 | ASSERT_EQ(topts.data_size_out, expect_sz, "ipv6 size"); | |
7ae2e00e JDB |
70 | |
71 | bpf_object__close(obj); | |
72 | } | |
73 | ||
6972dc3b | 74 | static void test_xdp_adjust_tail_grow2(void) |
7ae2e00e | 75 | { |
afef88e6 | 76 | const char *file = "./test_xdp_adjust_tail_grow.bpf.o"; |
7ae2e00e JDB |
77 | char buf[4096]; /* avoid segfault: large buf to hold grow results */ |
78 | int tailroom = 320; /* SKB_DATA_ALIGN(sizeof(struct skb_shared_info))*/; | |
79 | struct bpf_object *obj; | |
80 | int err, cnt, i; | |
39316183 | 81 | int max_grow, prog_fd; |
7ae2e00e | 82 | |
39316183 | 83 | LIBBPF_OPTS(bpf_test_run_opts, tattr, |
7ae2e00e JDB |
84 | .repeat = 1, |
85 | .data_in = &buf, | |
86 | .data_out = &buf, | |
87 | .data_size_in = 0, /* Per test */ | |
88 | .data_size_out = 0, /* Per test */ | |
39316183 | 89 | ); |
7ae2e00e | 90 | |
39316183 | 91 | err = bpf_prog_test_load(file, BPF_PROG_TYPE_XDP, &obj, &prog_fd); |
791cad02 | 92 | if (ASSERT_OK(err, "test_xdp_adjust_tail_grow")) |
7ae2e00e JDB |
93 | return; |
94 | ||
95 | /* Test case-64 */ | |
96 | memset(buf, 1, sizeof(buf)); | |
97 | tattr.data_size_in = 64; /* Determine test case via pkt size */ | |
98 | tattr.data_size_out = 128; /* Limit copy_size */ | |
99 | /* Kernel side alloc packet memory area that is zero init */ | |
39316183 | 100 | err = bpf_prog_test_run_opts(prog_fd, &tattr); |
7ae2e00e | 101 | |
791cad02 LB |
102 | ASSERT_EQ(errno, ENOSPC, "case-64 errno"); /* Due limit copy_size in bpf_test_finish */ |
103 | ASSERT_EQ(tattr.retval, XDP_TX, "case-64 retval"); | |
104 | ASSERT_EQ(tattr.data_size_out, 192, "case-64 data_size_out"); /* Expected grow size */ | |
7ae2e00e JDB |
105 | |
106 | /* Extra checks for data contents */ | |
791cad02 LB |
107 | ASSERT_EQ(buf[0], 1, "case-64-data buf[0]"); /* 0-63 memset to 1 */ |
108 | ASSERT_EQ(buf[63], 1, "case-64-data buf[63]"); | |
109 | ASSERT_EQ(buf[64], 0, "case-64-data buf[64]"); /* 64-127 memset to 0 */ | |
110 | ASSERT_EQ(buf[127], 0, "case-64-data buf[127]"); | |
111 | ASSERT_EQ(buf[128], 1, "case-64-data buf[128]"); /* 128-191 memset to 1 */ | |
112 | ASSERT_EQ(buf[191], 1, "case-64-data buf[191]"); | |
7ae2e00e JDB |
113 | |
114 | /* Test case-128 */ | |
115 | memset(buf, 2, sizeof(buf)); | |
116 | tattr.data_size_in = 128; /* Determine test case via pkt size */ | |
117 | tattr.data_size_out = sizeof(buf); /* Copy everything */ | |
39316183 | 118 | err = bpf_prog_test_run_opts(prog_fd, &tattr); |
7ae2e00e JDB |
119 | |
120 | max_grow = 4096 - XDP_PACKET_HEADROOM - tailroom; /* 3520 */ | |
791cad02 LB |
121 | ASSERT_OK(err, "case-128"); |
122 | ASSERT_EQ(tattr.retval, XDP_TX, "case-128 retval"); | |
123 | ASSERT_EQ(tattr.data_size_out, max_grow, "case-128 data_size_out"); /* Expect max grow */ | |
7ae2e00e JDB |
124 | |
125 | /* Extra checks for data content: Count grow size, will contain zeros */ | |
126 | for (i = 0, cnt = 0; i < sizeof(buf); i++) { | |
127 | if (buf[i] == 0) | |
128 | cnt++; | |
129 | } | |
791cad02 LB |
130 | ASSERT_EQ(cnt, max_grow - tattr.data_size_in, "case-128-data cnt"); /* Grow increase */ |
131 | ASSERT_EQ(tattr.data_size_out, max_grow, "case-128-data data_size_out"); /* Total grow */ | |
7ae2e00e | 132 | |
eaf90740 SF |
133 | bpf_object__close(obj); |
134 | } | |
68545fb6 | 135 | |
5912fcb4 | 136 | static void test_xdp_adjust_frags_tail_shrink(void) |
11022108 | 137 | { |
afef88e6 | 138 | const char *file = "./test_xdp_adjust_tail_shrink.bpf.o"; |
04fcb5f9 | 139 | __u32 exp_size; |
11022108 EC |
140 | struct bpf_program *prog; |
141 | struct bpf_object *obj; | |
142 | int err, prog_fd; | |
143 | __u8 *buf; | |
04fcb5f9 | 144 | LIBBPF_OPTS(bpf_test_run_opts, topts); |
11022108 EC |
145 | |
146 | /* For the individual test cases, the first byte in the packet | |
147 | * indicates which test will be run. | |
148 | */ | |
149 | obj = bpf_object__open(file); | |
150 | if (libbpf_get_error(obj)) | |
151 | return; | |
152 | ||
153 | prog = bpf_object__next_program(obj, NULL); | |
154 | if (bpf_object__load(obj)) | |
155 | return; | |
156 | ||
157 | prog_fd = bpf_program__fd(prog); | |
158 | ||
159 | buf = malloc(9000); | |
160 | if (!ASSERT_OK_PTR(buf, "alloc buf 9Kb")) | |
161 | goto out; | |
162 | ||
163 | memset(buf, 0, 9000); | |
164 | ||
165 | /* Test case removing 10 bytes from last frag, NOT freeing it */ | |
166 | exp_size = 8990; /* 9000 - 10 */ | |
04fcb5f9 DK |
167 | topts.data_in = buf; |
168 | topts.data_out = buf; | |
169 | topts.data_size_in = 9000; | |
170 | topts.data_size_out = 9000; | |
171 | err = bpf_prog_test_run_opts(prog_fd, &topts); | |
11022108 EC |
172 | |
173 | ASSERT_OK(err, "9Kb-10b"); | |
04fcb5f9 DK |
174 | ASSERT_EQ(topts.retval, XDP_TX, "9Kb-10b retval"); |
175 | ASSERT_EQ(topts.data_size_out, exp_size, "9Kb-10b size"); | |
11022108 EC |
176 | |
177 | /* Test case removing one of two pages, assuming 4K pages */ | |
178 | buf[0] = 1; | |
179 | exp_size = 4900; /* 9000 - 4100 */ | |
04fcb5f9 DK |
180 | |
181 | topts.data_size_out = 9000; /* reset from previous invocation */ | |
182 | err = bpf_prog_test_run_opts(prog_fd, &topts); | |
11022108 EC |
183 | |
184 | ASSERT_OK(err, "9Kb-4Kb"); | |
04fcb5f9 DK |
185 | ASSERT_EQ(topts.retval, XDP_TX, "9Kb-4Kb retval"); |
186 | ASSERT_EQ(topts.data_size_out, exp_size, "9Kb-4Kb size"); | |
11022108 EC |
187 | |
188 | /* Test case removing two pages resulting in a linear xdp_buff */ | |
189 | buf[0] = 2; | |
190 | exp_size = 800; /* 9000 - 8200 */ | |
04fcb5f9 DK |
191 | topts.data_size_out = 9000; /* reset from previous invocation */ |
192 | err = bpf_prog_test_run_opts(prog_fd, &topts); | |
11022108 EC |
193 | |
194 | ASSERT_OK(err, "9Kb-9Kb"); | |
04fcb5f9 DK |
195 | ASSERT_EQ(topts.retval, XDP_TX, "9Kb-9Kb retval"); |
196 | ASSERT_EQ(topts.data_size_out, exp_size, "9Kb-9Kb size"); | |
11022108 EC |
197 | |
198 | free(buf); | |
199 | out: | |
200 | bpf_object__close(obj); | |
201 | } | |
202 | ||
5912fcb4 | 203 | static void test_xdp_adjust_frags_tail_grow(void) |
11022108 | 204 | { |
afef88e6 | 205 | const char *file = "./test_xdp_adjust_tail_grow.bpf.o"; |
04fcb5f9 | 206 | __u32 exp_size; |
11022108 EC |
207 | struct bpf_program *prog; |
208 | struct bpf_object *obj; | |
209 | int err, i, prog_fd; | |
210 | __u8 *buf; | |
04fcb5f9 | 211 | LIBBPF_OPTS(bpf_test_run_opts, topts); |
11022108 EC |
212 | |
213 | obj = bpf_object__open(file); | |
214 | if (libbpf_get_error(obj)) | |
215 | return; | |
216 | ||
217 | prog = bpf_object__next_program(obj, NULL); | |
218 | if (bpf_object__load(obj)) | |
219 | return; | |
220 | ||
221 | prog_fd = bpf_program__fd(prog); | |
222 | ||
223 | buf = malloc(16384); | |
224 | if (!ASSERT_OK_PTR(buf, "alloc buf 16Kb")) | |
225 | goto out; | |
226 | ||
227 | /* Test case add 10 bytes to last frag */ | |
228 | memset(buf, 1, 16384); | |
04fcb5f9 DK |
229 | exp_size = 9000 + 10; |
230 | ||
231 | topts.data_in = buf; | |
232 | topts.data_out = buf; | |
233 | topts.data_size_in = 9000; | |
234 | topts.data_size_out = 16384; | |
235 | err = bpf_prog_test_run_opts(prog_fd, &topts); | |
11022108 EC |
236 | |
237 | ASSERT_OK(err, "9Kb+10b"); | |
04fcb5f9 DK |
238 | ASSERT_EQ(topts.retval, XDP_TX, "9Kb+10b retval"); |
239 | ASSERT_EQ(topts.data_size_out, exp_size, "9Kb+10b size"); | |
11022108 EC |
240 | |
241 | for (i = 0; i < 9000; i++) | |
242 | ASSERT_EQ(buf[i], 1, "9Kb+10b-old"); | |
243 | ||
244 | for (i = 9000; i < 9010; i++) | |
245 | ASSERT_EQ(buf[i], 0, "9Kb+10b-new"); | |
246 | ||
247 | for (i = 9010; i < 16384; i++) | |
248 | ASSERT_EQ(buf[i], 1, "9Kb+10b-untouched"); | |
249 | ||
250 | /* Test a too large grow */ | |
251 | memset(buf, 1, 16384); | |
04fcb5f9 DK |
252 | exp_size = 9001; |
253 | ||
254 | topts.data_in = topts.data_out = buf; | |
255 | topts.data_size_in = 9001; | |
256 | topts.data_size_out = 16384; | |
257 | err = bpf_prog_test_run_opts(prog_fd, &topts); | |
11022108 EC |
258 | |
259 | ASSERT_OK(err, "9Kb+10b"); | |
04fcb5f9 DK |
260 | ASSERT_EQ(topts.retval, XDP_DROP, "9Kb+10b retval"); |
261 | ASSERT_EQ(topts.data_size_out, exp_size, "9Kb+10b size"); | |
11022108 EC |
262 | |
263 | free(buf); | |
264 | out: | |
265 | bpf_object__close(obj); | |
266 | } | |
267 | ||
68545fb6 JDB |
268 | void test_xdp_adjust_tail(void) |
269 | { | |
7ae2e00e JDB |
270 | if (test__start_subtest("xdp_adjust_tail_shrink")) |
271 | test_xdp_adjust_tail_shrink(); | |
272 | if (test__start_subtest("xdp_adjust_tail_grow")) | |
273 | test_xdp_adjust_tail_grow(); | |
274 | if (test__start_subtest("xdp_adjust_tail_grow2")) | |
275 | test_xdp_adjust_tail_grow2(); | |
11022108 EC |
276 | if (test__start_subtest("xdp_adjust_frags_tail_shrink")) |
277 | test_xdp_adjust_frags_tail_shrink(); | |
278 | if (test__start_subtest("xdp_adjust_frags_tail_grow")) | |
279 | test_xdp_adjust_frags_tail_grow(); | |
68545fb6 | 280 | } |