17ae2e00eSJesper Dangaard Brouer // SPDX-License-Identifier: GPL-2.0
27ae2e00eSJesper Dangaard Brouer #include <linux/bpf.h>
37ae2e00eSJesper Dangaard Brouer #include <bpf/bpf_helpers.h>
47ae2e00eSJesper Dangaard Brouer 
58fffa0e3SAndrii Nakryiko SEC("xdp")
_xdp_adjust_tail_grow(struct xdp_md * xdp)67ae2e00eSJesper Dangaard Brouer int _xdp_adjust_tail_grow(struct xdp_md *xdp)
77ae2e00eSJesper Dangaard Brouer {
811022108SEelco Chaudron 	int data_len = bpf_xdp_get_buff_len(xdp);
97ae2e00eSJesper Dangaard Brouer 	int offset = 0;
10*26e8a014SIlya Leoshkevich 	/* SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) */
11*26e8a014SIlya Leoshkevich #if defined(__TARGET_ARCH_s390)
12*26e8a014SIlya Leoshkevich 	int tailroom = 512;
13*26e8a014SIlya Leoshkevich #else
14*26e8a014SIlya Leoshkevich 	int tailroom = 320;
15*26e8a014SIlya Leoshkevich #endif
167ae2e00eSJesper Dangaard Brouer 
177ae2e00eSJesper Dangaard Brouer 	/* Data length determine test case */
187ae2e00eSJesper Dangaard Brouer 
197ae2e00eSJesper Dangaard Brouer 	if (data_len == 54) { /* sizeof(pkt_v4) */
207ae2e00eSJesper Dangaard Brouer 		offset = 4096; /* test too large offset */
217ae2e00eSJesper Dangaard Brouer 	} else if (data_len == 74) { /* sizeof(pkt_v6) */
227ae2e00eSJesper Dangaard Brouer 		offset = 40;
237ae2e00eSJesper Dangaard Brouer 	} else if (data_len == 64) {
247ae2e00eSJesper Dangaard Brouer 		offset = 128;
257ae2e00eSJesper Dangaard Brouer 	} else if (data_len == 128) {
2611022108SEelco Chaudron 		/* Max tail grow 3520 */
27*26e8a014SIlya Leoshkevich 		offset = 4096 - 256 - tailroom - data_len;
2811022108SEelco Chaudron 	} else if (data_len == 9000) {
2911022108SEelco Chaudron 		offset = 10;
3011022108SEelco Chaudron 	} else if (data_len == 9001) {
3111022108SEelco Chaudron 		offset = 4096;
327ae2e00eSJesper Dangaard Brouer 	} else {
337ae2e00eSJesper Dangaard Brouer 		return XDP_ABORTED; /* No matching test */
347ae2e00eSJesper Dangaard Brouer 	}
357ae2e00eSJesper Dangaard Brouer 
367ae2e00eSJesper Dangaard Brouer 	if (bpf_xdp_adjust_tail(xdp, offset))
377ae2e00eSJesper Dangaard Brouer 		return XDP_DROP;
387ae2e00eSJesper Dangaard Brouer 	return XDP_TX;
397ae2e00eSJesper Dangaard Brouer }
407ae2e00eSJesper Dangaard Brouer 
417ae2e00eSJesper Dangaard Brouer char _license[] SEC("license") = "GPL";
42