1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* Converted from tools/testing/selftests/bpf/verifier/helper_packet_access.c */ |
3 | |
4 | #include <linux/bpf.h> |
5 | #include <bpf/bpf_helpers.h> |
6 | #include "bpf_misc.h" |
7 | |
8 | struct { |
9 | __uint(type, BPF_MAP_TYPE_HASH); |
10 | __uint(max_entries, 1); |
11 | __type(key, long long); |
12 | __type(value, long long); |
13 | } map_hash_8b SEC(".maps" ); |
14 | |
15 | SEC("xdp" ) |
16 | __description("helper access to packet: test1, valid packet_ptr range" ) |
17 | __success __retval(0) |
18 | __naked void test1_valid_packet_ptr_range(void) |
19 | { |
20 | asm volatile (" \ |
21 | r2 = *(u32*)(r1 + %[xdp_md_data]); \ |
22 | r3 = *(u32*)(r1 + %[xdp_md_data_end]); \ |
23 | r1 = r2; \ |
24 | r1 += 8; \ |
25 | if r1 > r3 goto l0_%=; \ |
26 | r1 = %[map_hash_8b] ll; \ |
27 | r3 = r2; \ |
28 | r4 = 0; \ |
29 | call %[bpf_map_update_elem]; \ |
30 | l0_%=: r0 = 0; \ |
31 | exit; \ |
32 | " : |
33 | : __imm(bpf_map_update_elem), |
34 | __imm_addr(map_hash_8b), |
35 | __imm_const(xdp_md_data, offsetof(struct xdp_md, data)), |
36 | __imm_const(xdp_md_data_end, offsetof(struct xdp_md, data_end)) |
37 | : __clobber_all); |
38 | } |
39 | |
40 | SEC("xdp" ) |
41 | __description("helper access to packet: test2, unchecked packet_ptr" ) |
42 | __failure __msg("invalid access to packet" ) |
43 | __naked void packet_test2_unchecked_packet_ptr(void) |
44 | { |
45 | asm volatile (" \ |
46 | r2 = *(u32*)(r1 + %[xdp_md_data]); \ |
47 | r1 = %[map_hash_8b] ll; \ |
48 | call %[bpf_map_lookup_elem]; \ |
49 | r0 = 0; \ |
50 | exit; \ |
51 | " : |
52 | : __imm(bpf_map_lookup_elem), |
53 | __imm_addr(map_hash_8b), |
54 | __imm_const(xdp_md_data, offsetof(struct xdp_md, data)) |
55 | : __clobber_all); |
56 | } |
57 | |
58 | SEC("xdp" ) |
59 | __description("helper access to packet: test3, variable add" ) |
60 | __success __retval(0) |
61 | __naked void to_packet_test3_variable_add(void) |
62 | { |
63 | asm volatile (" \ |
64 | r2 = *(u32*)(r1 + %[xdp_md_data]); \ |
65 | r3 = *(u32*)(r1 + %[xdp_md_data_end]); \ |
66 | r4 = r2; \ |
67 | r4 += 8; \ |
68 | if r4 > r3 goto l0_%=; \ |
69 | r5 = *(u8*)(r2 + 0); \ |
70 | r4 = r2; \ |
71 | r4 += r5; \ |
72 | r5 = r4; \ |
73 | r5 += 8; \ |
74 | if r5 > r3 goto l0_%=; \ |
75 | r1 = %[map_hash_8b] ll; \ |
76 | r2 = r4; \ |
77 | call %[bpf_map_lookup_elem]; \ |
78 | l0_%=: r0 = 0; \ |
79 | exit; \ |
80 | " : |
81 | : __imm(bpf_map_lookup_elem), |
82 | __imm_addr(map_hash_8b), |
83 | __imm_const(xdp_md_data, offsetof(struct xdp_md, data)), |
84 | __imm_const(xdp_md_data_end, offsetof(struct xdp_md, data_end)) |
85 | : __clobber_all); |
86 | } |
87 | |
88 | SEC("xdp" ) |
89 | __description("helper access to packet: test4, packet_ptr with bad range" ) |
90 | __failure __msg("invalid access to packet" ) |
91 | __naked void packet_ptr_with_bad_range_1(void) |
92 | { |
93 | asm volatile (" \ |
94 | r2 = *(u32*)(r1 + %[xdp_md_data]); \ |
95 | r3 = *(u32*)(r1 + %[xdp_md_data_end]); \ |
96 | r4 = r2; \ |
97 | r4 += 4; \ |
98 | if r4 > r3 goto l0_%=; \ |
99 | r0 = 0; \ |
100 | exit; \ |
101 | l0_%=: r1 = %[map_hash_8b] ll; \ |
102 | call %[bpf_map_lookup_elem]; \ |
103 | r0 = 0; \ |
104 | exit; \ |
105 | " : |
106 | : __imm(bpf_map_lookup_elem), |
107 | __imm_addr(map_hash_8b), |
108 | __imm_const(xdp_md_data, offsetof(struct xdp_md, data)), |
109 | __imm_const(xdp_md_data_end, offsetof(struct xdp_md, data_end)) |
110 | : __clobber_all); |
111 | } |
112 | |
113 | SEC("xdp" ) |
114 | __description("helper access to packet: test5, packet_ptr with too short range" ) |
115 | __failure __msg("invalid access to packet" ) |
116 | __naked void ptr_with_too_short_range_1(void) |
117 | { |
118 | asm volatile (" \ |
119 | r2 = *(u32*)(r1 + %[xdp_md_data]); \ |
120 | r3 = *(u32*)(r1 + %[xdp_md_data_end]); \ |
121 | r2 += 1; \ |
122 | r4 = r2; \ |
123 | r4 += 7; \ |
124 | if r4 > r3 goto l0_%=; \ |
125 | r1 = %[map_hash_8b] ll; \ |
126 | call %[bpf_map_lookup_elem]; \ |
127 | l0_%=: r0 = 0; \ |
128 | exit; \ |
129 | " : |
130 | : __imm(bpf_map_lookup_elem), |
131 | __imm_addr(map_hash_8b), |
132 | __imm_const(xdp_md_data, offsetof(struct xdp_md, data)), |
133 | __imm_const(xdp_md_data_end, offsetof(struct xdp_md, data_end)) |
134 | : __clobber_all); |
135 | } |
136 | |
137 | SEC("tc" ) |
138 | __description("helper access to packet: test6, cls valid packet_ptr range" ) |
139 | __success __retval(0) |
140 | __naked void cls_valid_packet_ptr_range(void) |
141 | { |
142 | asm volatile (" \ |
143 | r2 = *(u32*)(r1 + %[__sk_buff_data]); \ |
144 | r3 = *(u32*)(r1 + %[__sk_buff_data_end]); \ |
145 | r1 = r2; \ |
146 | r1 += 8; \ |
147 | if r1 > r3 goto l0_%=; \ |
148 | r1 = %[map_hash_8b] ll; \ |
149 | r3 = r2; \ |
150 | r4 = 0; \ |
151 | call %[bpf_map_update_elem]; \ |
152 | l0_%=: r0 = 0; \ |
153 | exit; \ |
154 | " : |
155 | : __imm(bpf_map_update_elem), |
156 | __imm_addr(map_hash_8b), |
157 | __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)), |
158 | __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end)) |
159 | : __clobber_all); |
160 | } |
161 | |
162 | SEC("tc" ) |
163 | __description("helper access to packet: test7, cls unchecked packet_ptr" ) |
164 | __failure __msg("invalid access to packet" ) |
165 | __naked void test7_cls_unchecked_packet_ptr(void) |
166 | { |
167 | asm volatile (" \ |
168 | r2 = *(u32*)(r1 + %[__sk_buff_data]); \ |
169 | r1 = %[map_hash_8b] ll; \ |
170 | call %[bpf_map_lookup_elem]; \ |
171 | r0 = 0; \ |
172 | exit; \ |
173 | " : |
174 | : __imm(bpf_map_lookup_elem), |
175 | __imm_addr(map_hash_8b), |
176 | __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)) |
177 | : __clobber_all); |
178 | } |
179 | |
180 | SEC("tc" ) |
181 | __description("helper access to packet: test8, cls variable add" ) |
182 | __success __retval(0) |
183 | __naked void packet_test8_cls_variable_add(void) |
184 | { |
185 | asm volatile (" \ |
186 | r2 = *(u32*)(r1 + %[__sk_buff_data]); \ |
187 | r3 = *(u32*)(r1 + %[__sk_buff_data_end]); \ |
188 | r4 = r2; \ |
189 | r4 += 8; \ |
190 | if r4 > r3 goto l0_%=; \ |
191 | r5 = *(u8*)(r2 + 0); \ |
192 | r4 = r2; \ |
193 | r4 += r5; \ |
194 | r5 = r4; \ |
195 | r5 += 8; \ |
196 | if r5 > r3 goto l0_%=; \ |
197 | r1 = %[map_hash_8b] ll; \ |
198 | r2 = r4; \ |
199 | call %[bpf_map_lookup_elem]; \ |
200 | l0_%=: r0 = 0; \ |
201 | exit; \ |
202 | " : |
203 | : __imm(bpf_map_lookup_elem), |
204 | __imm_addr(map_hash_8b), |
205 | __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)), |
206 | __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end)) |
207 | : __clobber_all); |
208 | } |
209 | |
210 | SEC("tc" ) |
211 | __description("helper access to packet: test9, cls packet_ptr with bad range" ) |
212 | __failure __msg("invalid access to packet" ) |
213 | __naked void packet_ptr_with_bad_range_2(void) |
214 | { |
215 | asm volatile (" \ |
216 | r2 = *(u32*)(r1 + %[__sk_buff_data]); \ |
217 | r3 = *(u32*)(r1 + %[__sk_buff_data_end]); \ |
218 | r4 = r2; \ |
219 | r4 += 4; \ |
220 | if r4 > r3 goto l0_%=; \ |
221 | r0 = 0; \ |
222 | exit; \ |
223 | l0_%=: r1 = %[map_hash_8b] ll; \ |
224 | call %[bpf_map_lookup_elem]; \ |
225 | r0 = 0; \ |
226 | exit; \ |
227 | " : |
228 | : __imm(bpf_map_lookup_elem), |
229 | __imm_addr(map_hash_8b), |
230 | __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)), |
231 | __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end)) |
232 | : __clobber_all); |
233 | } |
234 | |
235 | SEC("tc" ) |
236 | __description("helper access to packet: test10, cls packet_ptr with too short range" ) |
237 | __failure __msg("invalid access to packet" ) |
238 | __naked void ptr_with_too_short_range_2(void) |
239 | { |
240 | asm volatile (" \ |
241 | r2 = *(u32*)(r1 + %[__sk_buff_data]); \ |
242 | r3 = *(u32*)(r1 + %[__sk_buff_data_end]); \ |
243 | r2 += 1; \ |
244 | r4 = r2; \ |
245 | r4 += 7; \ |
246 | if r4 > r3 goto l0_%=; \ |
247 | r1 = %[map_hash_8b] ll; \ |
248 | call %[bpf_map_lookup_elem]; \ |
249 | l0_%=: r0 = 0; \ |
250 | exit; \ |
251 | " : |
252 | : __imm(bpf_map_lookup_elem), |
253 | __imm_addr(map_hash_8b), |
254 | __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)), |
255 | __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end)) |
256 | : __clobber_all); |
257 | } |
258 | |
259 | SEC("tc" ) |
260 | __description("helper access to packet: test11, cls unsuitable helper 1" ) |
261 | __failure __msg("helper access to the packet" ) |
262 | __naked void test11_cls_unsuitable_helper_1(void) |
263 | { |
264 | asm volatile (" \ |
265 | r6 = *(u32*)(r1 + %[__sk_buff_data]); \ |
266 | r7 = *(u32*)(r1 + %[__sk_buff_data_end]); \ |
267 | r6 += 1; \ |
268 | r3 = r6; \ |
269 | r3 += 7; \ |
270 | if r3 > r7 goto l0_%=; \ |
271 | r2 = 0; \ |
272 | r4 = 42; \ |
273 | r5 = 0; \ |
274 | call %[bpf_skb_store_bytes]; \ |
275 | l0_%=: r0 = 0; \ |
276 | exit; \ |
277 | " : |
278 | : __imm(bpf_skb_store_bytes), |
279 | __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)), |
280 | __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end)) |
281 | : __clobber_all); |
282 | } |
283 | |
284 | SEC("tc" ) |
285 | __description("helper access to packet: test12, cls unsuitable helper 2" ) |
286 | __failure __msg("helper access to the packet" ) |
287 | __naked void test12_cls_unsuitable_helper_2(void) |
288 | { |
289 | asm volatile (" \ |
290 | r6 = *(u32*)(r1 + %[__sk_buff_data]); \ |
291 | r7 = *(u32*)(r1 + %[__sk_buff_data_end]); \ |
292 | r3 = r6; \ |
293 | r6 += 8; \ |
294 | if r6 > r7 goto l0_%=; \ |
295 | r2 = 0; \ |
296 | r4 = 4; \ |
297 | call %[bpf_skb_load_bytes]; \ |
298 | l0_%=: r0 = 0; \ |
299 | exit; \ |
300 | " : |
301 | : __imm(bpf_skb_load_bytes), |
302 | __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)), |
303 | __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end)) |
304 | : __clobber_all); |
305 | } |
306 | |
307 | SEC("tc" ) |
308 | __description("helper access to packet: test13, cls helper ok" ) |
309 | __success __retval(0) |
310 | __naked void packet_test13_cls_helper_ok(void) |
311 | { |
312 | asm volatile (" \ |
313 | r6 = *(u32*)(r1 + %[__sk_buff_data]); \ |
314 | r7 = *(u32*)(r1 + %[__sk_buff_data_end]); \ |
315 | r6 += 1; \ |
316 | r1 = r6; \ |
317 | r1 += 7; \ |
318 | if r1 > r7 goto l0_%=; \ |
319 | r1 = r6; \ |
320 | r2 = 4; \ |
321 | r3 = 0; \ |
322 | r4 = 0; \ |
323 | r5 = 0; \ |
324 | call %[bpf_csum_diff]; \ |
325 | l0_%=: r0 = 0; \ |
326 | exit; \ |
327 | " : |
328 | : __imm(bpf_csum_diff), |
329 | __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)), |
330 | __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end)) |
331 | : __clobber_all); |
332 | } |
333 | |
334 | SEC("tc" ) |
335 | __description("helper access to packet: test14, cls helper ok sub" ) |
336 | __success __retval(0) |
337 | __naked void test14_cls_helper_ok_sub(void) |
338 | { |
339 | asm volatile (" \ |
340 | r6 = *(u32*)(r1 + %[__sk_buff_data]); \ |
341 | r7 = *(u32*)(r1 + %[__sk_buff_data_end]); \ |
342 | r6 += 1; \ |
343 | r1 = r6; \ |
344 | r1 += 7; \ |
345 | if r1 > r7 goto l0_%=; \ |
346 | r1 -= 4; \ |
347 | r2 = 4; \ |
348 | r3 = 0; \ |
349 | r4 = 0; \ |
350 | r5 = 0; \ |
351 | call %[bpf_csum_diff]; \ |
352 | l0_%=: r0 = 0; \ |
353 | exit; \ |
354 | " : |
355 | : __imm(bpf_csum_diff), |
356 | __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)), |
357 | __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end)) |
358 | : __clobber_all); |
359 | } |
360 | |
361 | SEC("tc" ) |
362 | __description("helper access to packet: test15, cls helper fail sub" ) |
363 | __failure __msg("invalid access to packet" ) |
364 | __naked void test15_cls_helper_fail_sub(void) |
365 | { |
366 | asm volatile (" \ |
367 | r6 = *(u32*)(r1 + %[__sk_buff_data]); \ |
368 | r7 = *(u32*)(r1 + %[__sk_buff_data_end]); \ |
369 | r6 += 1; \ |
370 | r1 = r6; \ |
371 | r1 += 7; \ |
372 | if r1 > r7 goto l0_%=; \ |
373 | r1 -= 12; \ |
374 | r2 = 4; \ |
375 | r3 = 0; \ |
376 | r4 = 0; \ |
377 | r5 = 0; \ |
378 | call %[bpf_csum_diff]; \ |
379 | l0_%=: r0 = 0; \ |
380 | exit; \ |
381 | " : |
382 | : __imm(bpf_csum_diff), |
383 | __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)), |
384 | __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end)) |
385 | : __clobber_all); |
386 | } |
387 | |
388 | SEC("tc" ) |
389 | __description("helper access to packet: test16, cls helper fail range 1" ) |
390 | __failure __msg("invalid access to packet" ) |
391 | __naked void cls_helper_fail_range_1(void) |
392 | { |
393 | asm volatile (" \ |
394 | r6 = *(u32*)(r1 + %[__sk_buff_data]); \ |
395 | r7 = *(u32*)(r1 + %[__sk_buff_data_end]); \ |
396 | r6 += 1; \ |
397 | r1 = r6; \ |
398 | r1 += 7; \ |
399 | if r1 > r7 goto l0_%=; \ |
400 | r1 = r6; \ |
401 | r2 = 8; \ |
402 | r3 = 0; \ |
403 | r4 = 0; \ |
404 | r5 = 0; \ |
405 | call %[bpf_csum_diff]; \ |
406 | l0_%=: r0 = 0; \ |
407 | exit; \ |
408 | " : |
409 | : __imm(bpf_csum_diff), |
410 | __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)), |
411 | __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end)) |
412 | : __clobber_all); |
413 | } |
414 | |
415 | SEC("tc" ) |
416 | __description("helper access to packet: test17, cls helper fail range 2" ) |
417 | __failure __msg("R2 min value is negative" ) |
418 | __naked void cls_helper_fail_range_2(void) |
419 | { |
420 | asm volatile (" \ |
421 | r6 = *(u32*)(r1 + %[__sk_buff_data]); \ |
422 | r7 = *(u32*)(r1 + %[__sk_buff_data_end]); \ |
423 | r6 += 1; \ |
424 | r1 = r6; \ |
425 | r1 += 7; \ |
426 | if r1 > r7 goto l0_%=; \ |
427 | r1 = r6; \ |
428 | r2 = -9; \ |
429 | r3 = 0; \ |
430 | r4 = 0; \ |
431 | r5 = 0; \ |
432 | call %[bpf_csum_diff]; \ |
433 | l0_%=: r0 = 0; \ |
434 | exit; \ |
435 | " : |
436 | : __imm(bpf_csum_diff), |
437 | __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)), |
438 | __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end)) |
439 | : __clobber_all); |
440 | } |
441 | |
442 | SEC("tc" ) |
443 | __description("helper access to packet: test18, cls helper fail range 3" ) |
444 | __failure __msg("R2 min value is negative" ) |
445 | __naked void cls_helper_fail_range_3(void) |
446 | { |
447 | asm volatile (" \ |
448 | r6 = *(u32*)(r1 + %[__sk_buff_data]); \ |
449 | r7 = *(u32*)(r1 + %[__sk_buff_data_end]); \ |
450 | r6 += 1; \ |
451 | r1 = r6; \ |
452 | r1 += 7; \ |
453 | if r1 > r7 goto l0_%=; \ |
454 | r1 = r6; \ |
455 | r2 = %[__imm_0]; \ |
456 | r3 = 0; \ |
457 | r4 = 0; \ |
458 | r5 = 0; \ |
459 | call %[bpf_csum_diff]; \ |
460 | l0_%=: r0 = 0; \ |
461 | exit; \ |
462 | " : |
463 | : __imm(bpf_csum_diff), |
464 | __imm_const(__imm_0, ~0), |
465 | __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)), |
466 | __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end)) |
467 | : __clobber_all); |
468 | } |
469 | |
470 | SEC("tc" ) |
471 | __description("helper access to packet: test19, cls helper range zero" ) |
472 | __success __retval(0) |
473 | __naked void test19_cls_helper_range_zero(void) |
474 | { |
475 | asm volatile (" \ |
476 | r6 = *(u32*)(r1 + %[__sk_buff_data]); \ |
477 | r7 = *(u32*)(r1 + %[__sk_buff_data_end]); \ |
478 | r6 += 1; \ |
479 | r1 = r6; \ |
480 | r1 += 7; \ |
481 | if r1 > r7 goto l0_%=; \ |
482 | r1 = r6; \ |
483 | r2 = 0; \ |
484 | r3 = 0; \ |
485 | r4 = 0; \ |
486 | r5 = 0; \ |
487 | call %[bpf_csum_diff]; \ |
488 | l0_%=: r0 = 0; \ |
489 | exit; \ |
490 | " : |
491 | : __imm(bpf_csum_diff), |
492 | __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)), |
493 | __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end)) |
494 | : __clobber_all); |
495 | } |
496 | |
497 | SEC("tc" ) |
498 | __description("helper access to packet: test20, pkt end as input" ) |
499 | __failure __msg("R1 type=pkt_end expected=fp" ) |
500 | __naked void test20_pkt_end_as_input(void) |
501 | { |
502 | asm volatile (" \ |
503 | r6 = *(u32*)(r1 + %[__sk_buff_data]); \ |
504 | r7 = *(u32*)(r1 + %[__sk_buff_data_end]); \ |
505 | r6 += 1; \ |
506 | r1 = r6; \ |
507 | r1 += 7; \ |
508 | if r1 > r7 goto l0_%=; \ |
509 | r1 = r7; \ |
510 | r2 = 4; \ |
511 | r3 = 0; \ |
512 | r4 = 0; \ |
513 | r5 = 0; \ |
514 | call %[bpf_csum_diff]; \ |
515 | l0_%=: r0 = 0; \ |
516 | exit; \ |
517 | " : |
518 | : __imm(bpf_csum_diff), |
519 | __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)), |
520 | __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end)) |
521 | : __clobber_all); |
522 | } |
523 | |
524 | SEC("tc" ) |
525 | __description("helper access to packet: test21, wrong reg" ) |
526 | __failure __msg("invalid access to packet" ) |
527 | __naked void to_packet_test21_wrong_reg(void) |
528 | { |
529 | asm volatile (" \ |
530 | r6 = *(u32*)(r1 + %[__sk_buff_data]); \ |
531 | r7 = *(u32*)(r1 + %[__sk_buff_data_end]); \ |
532 | r6 += 1; \ |
533 | r1 = r6; \ |
534 | r1 += 7; \ |
535 | if r1 > r7 goto l0_%=; \ |
536 | r2 = 4; \ |
537 | r3 = 0; \ |
538 | r4 = 0; \ |
539 | r5 = 0; \ |
540 | call %[bpf_csum_diff]; \ |
541 | r0 = 0; \ |
542 | l0_%=: exit; \ |
543 | " : |
544 | : __imm(bpf_csum_diff), |
545 | __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)), |
546 | __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end)) |
547 | : __clobber_all); |
548 | } |
549 | |
550 | char _license[] SEC("license" ) = "GPL" ; |
551 | |