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

bpf: adding tests for bpf_xdp_adjust_tail

adding selftests for bpf_xdp_adjust_tail helper. in this synthetic test
we are testing that 1) if data_end < data helper will return EINVAL
2) for normal use case packet's length would be reduced.

Signed-off-by: Nikita V. Shirokov <tehnerd@tehnerd.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>

authored by

Nikita V. Shirokov and committed by
Daniel Borkmann
0367d0a2 587b80cc

+75 -2
+9 -1
tools/include/uapi/linux/bpf.h
··· 755 755 * @addr: pointer to struct sockaddr to bind socket to 756 756 * @addr_len: length of sockaddr structure 757 757 * Return: 0 on success or negative error code 758 + * 759 + * int bpf_xdp_adjust_tail(xdp_md, delta) 760 + * Adjust the xdp_md.data_end by delta. Only shrinking of packet's 761 + * size is supported. 762 + * @xdp_md: pointer to xdp_md 763 + * @delta: A negative integer to be added to xdp_md.data_end 764 + * Return: 0 on success or negative on error 758 765 */ 759 766 #define __BPF_FUNC_MAPPER(FN) \ 760 767 FN(unspec), \ ··· 828 821 FN(msg_apply_bytes), \ 829 822 FN(msg_cork_bytes), \ 830 823 FN(msg_pull_data), \ 831 - FN(bind), 824 + FN(bind), \ 825 + FN(xdp_adjust_tail), 832 826 833 827 /* integer value in 'imm' field of BPF_CALL instruction selects which helper 834 828 * function eBPF program intends to call
+1 -1
tools/testing/selftests/bpf/Makefile
··· 31 31 sockmap_verdict_prog.o dev_cgroup.o sample_ret0.o test_tracepoint.o \ 32 32 test_l4lb_noinline.o test_xdp_noinline.o test_stacktrace_map.o \ 33 33 sample_map_ret0.o test_tcpbpf_kern.o test_stacktrace_build_id.o \ 34 - sockmap_tcp_msg_prog.o connect4_prog.o connect6_prog.o 34 + sockmap_tcp_msg_prog.o connect4_prog.o connect6_prog.o test_adjust_tail.o 35 35 36 36 # Order correspond to 'make run_tests' order 37 37 TEST_PROGS := test_kmod.sh \
+3
tools/testing/selftests/bpf/bpf_helpers.h
··· 96 96 (void *) BPF_FUNC_msg_pull_data; 97 97 static int (*bpf_bind)(void *ctx, void *addr, int addr_len) = 98 98 (void *) BPF_FUNC_bind; 99 + static int (*bpf_xdp_adjust_tail)(void *ctx, int offset) = 100 + (void *) BPF_FUNC_xdp_adjust_tail; 101 + 99 102 100 103 /* llvm builtin functions that eBPF C program may use to 101 104 * emit BPF_LD_ABS and BPF_LD_IND instructions
+30
tools/testing/selftests/bpf/test_adjust_tail.c
··· 1 + /* SPDX-License-Identifier: GPL-2.0 2 + * Copyright (c) 2018 Facebook 3 + * 4 + * This program is free software; you can redistribute it and/or 5 + * modify it under the terms of version 2 of the GNU General Public 6 + * License as published by the Free Software Foundation. 7 + */ 8 + #include <linux/bpf.h> 9 + #include <linux/if_ether.h> 10 + #include "bpf_helpers.h" 11 + 12 + int _version SEC("version") = 1; 13 + 14 + SEC("xdp_adjust_tail") 15 + int _xdp_adjust_tail(struct xdp_md *xdp) 16 + { 17 + void *data_end = (void *)(long)xdp->data_end; 18 + void *data = (void *)(long)xdp->data; 19 + int offset = 0; 20 + 21 + if (data_end - data == 54) 22 + offset = 256; 23 + else 24 + offset = 20; 25 + if (bpf_xdp_adjust_tail(xdp, 0 - offset)) 26 + return XDP_DROP; 27 + return XDP_TX; 28 + } 29 + 30 + char _license[] SEC("license") = "GPL";
+32
tools/testing/selftests/bpf/test_progs.c
··· 166 166 bpf_object__close(obj); 167 167 } 168 168 169 + static void test_xdp_adjust_tail(void) 170 + { 171 + const char *file = "./test_adjust_tail.o"; 172 + struct bpf_object *obj; 173 + char buf[128]; 174 + __u32 duration, retval, size; 175 + int err, prog_fd; 176 + 177 + err = bpf_prog_load(file, BPF_PROG_TYPE_XDP, &obj, &prog_fd); 178 + if (err) { 179 + error_cnt++; 180 + return; 181 + } 182 + 183 + err = bpf_prog_test_run(prog_fd, 1, &pkt_v4, sizeof(pkt_v4), 184 + buf, &size, &retval, &duration); 185 + 186 + CHECK(err || errno || retval != XDP_DROP, 187 + "ipv4", "err %d errno %d retval %d size %d\n", 188 + err, errno, retval, size); 189 + 190 + err = bpf_prog_test_run(prog_fd, 1, &pkt_v6, sizeof(pkt_v6), 191 + buf, &size, &retval, &duration); 192 + CHECK(err || errno || retval != XDP_TX || size != 54, 193 + "ipv6", "err %d errno %d retval %d size %d\n", 194 + err, errno, retval, size); 195 + bpf_object__close(obj); 196 + } 197 + 198 + 199 + 169 200 #define MAGIC_VAL 0x1234 170 201 #define NUM_ITER 100000 171 202 #define VIP_NUM 5 ··· 1208 1177 { 1209 1178 test_pkt_access(); 1210 1179 test_xdp(); 1180 + test_xdp_adjust_tail(); 1211 1181 test_l4lb_all(); 1212 1182 test_xdp_noinline(); 1213 1183 test_tcp_estats();