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

selftests/bpf: Extend netkit tests to validate set {head,tail}room

Extend the netkit selftests to specify and validate the {head,tail}room
on the netdevice:

# ./vmtest.sh -- ./test_progs -t netkit
[...]
./test_progs -t netkit
[ 1.174147] bpf_testmod: loading out-of-tree module taints kernel.
[ 1.174585] bpf_testmod: module verification failed: signature and/or required key missing - tainting kernel
[ 1.422307] tsc: Refined TSC clocksource calibration: 3407.983 MHz
[ 1.424511] clocksource: tsc: mask: 0xffffffffffffffff max_cycles: 0x311fc3e5084, max_idle_ns: 440795359833 ns
[ 1.428092] clocksource: Switched to clocksource tsc
#363 tc_netkit_basic:OK
#364 tc_netkit_device:OK
#365 tc_netkit_multi_links:OK
#366 tc_netkit_multi_opts:OK
#367 tc_netkit_neigh_links:OK
#368 tc_netkit_pkt_type:OK
#369 tc_netkit_scrub:OK
Summary: 7/0 PASSED, 0 SKIPPED, 0 FAILED

Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Nikolay Aleksandrov <razor@blackwall.org>
Link: https://lore.kernel.org/bpf/20241220234658.490686-3-daniel@iogearbox.net

+46 -18
+31 -18
tools/testing/selftests/bpf/prog_tests/tc_netkit.c
··· 14 14 #include "netlink_helpers.h" 15 15 #include "tc_helpers.h" 16 16 17 + #define NETKIT_HEADROOM 32 18 + #define NETKIT_TAILROOM 8 19 + 17 20 #define MARK 42 18 21 #define PRIO 0xeb9f 19 22 #define ICMP_ECHO 8 23 + 24 + #define FLAG_ADJUST_ROOM (1 << 0) 25 + #define FLAG_SAME_NETNS (1 << 1) 20 26 21 27 struct icmphdr { 22 28 __u8 type; ··· 41 35 }; 42 36 43 37 static int create_netkit(int mode, int policy, int peer_policy, int *ifindex, 44 - bool same_netns, int scrub, int peer_scrub) 38 + int scrub, int peer_scrub, __u32 flags) 45 39 { 46 40 struct rtnl_handle rth = { .fd = -1 }; 47 41 struct iplink_req req = {}; ··· 69 63 addattr32(&req.n, sizeof(req), IFLA_NETKIT_SCRUB, scrub); 70 64 addattr32(&req.n, sizeof(req), IFLA_NETKIT_PEER_SCRUB, peer_scrub); 71 65 addattr32(&req.n, sizeof(req), IFLA_NETKIT_MODE, mode); 66 + if (flags & FLAG_ADJUST_ROOM) { 67 + addattr16(&req.n, sizeof(req), IFLA_NETKIT_HEADROOM, NETKIT_HEADROOM); 68 + addattr16(&req.n, sizeof(req), IFLA_NETKIT_TAILROOM, NETKIT_TAILROOM); 69 + } 72 70 addattr_nest_end(&req.n, data); 73 71 addattr_nest_end(&req.n, linkinfo); 74 72 ··· 97 87 " addr ee:ff:bb:cc:aa:dd"), 98 88 "set hwaddress"); 99 89 } 100 - if (same_netns) { 90 + if (flags & FLAG_SAME_NETNS) { 101 91 ASSERT_OK(system("ip link set dev " netkit_peer " up"), 102 92 "up peer"); 103 93 ASSERT_OK(system("ip addr add dev " netkit_peer " 10.0.0.2/24"), ··· 194 184 int err, ifindex; 195 185 196 186 err = create_netkit(NETKIT_L2, NETKIT_PASS, NETKIT_PASS, 197 - &ifindex, false, NETKIT_SCRUB_DEFAULT, 198 - NETKIT_SCRUB_DEFAULT); 187 + &ifindex, NETKIT_SCRUB_DEFAULT, 188 + NETKIT_SCRUB_DEFAULT, 0); 199 189 if (err) 200 190 return; 201 191 ··· 309 299 int err, ifindex; 310 300 311 301 err = create_netkit(mode, NETKIT_PASS, NETKIT_PASS, 312 - &ifindex, false, NETKIT_SCRUB_DEFAULT, 313 - NETKIT_SCRUB_DEFAULT); 302 + &ifindex, NETKIT_SCRUB_DEFAULT, 303 + NETKIT_SCRUB_DEFAULT, 0); 314 304 if (err) 315 305 return; 316 306 ··· 438 428 int err, ifindex; 439 429 440 430 err = create_netkit(mode, NETKIT_PASS, NETKIT_PASS, 441 - &ifindex, false, NETKIT_SCRUB_DEFAULT, 442 - NETKIT_SCRUB_DEFAULT); 431 + &ifindex, NETKIT_SCRUB_DEFAULT, 432 + NETKIT_SCRUB_DEFAULT, 0); 443 433 if (err) 444 434 return; 445 435 ··· 553 543 int err, ifindex, ifindex2; 554 544 555 545 err = create_netkit(NETKIT_L3, NETKIT_PASS, NETKIT_PASS, 556 - &ifindex, true, NETKIT_SCRUB_DEFAULT, 557 - NETKIT_SCRUB_DEFAULT); 546 + &ifindex, NETKIT_SCRUB_DEFAULT, 547 + NETKIT_SCRUB_DEFAULT, FLAG_SAME_NETNS); 558 548 if (err) 559 549 return; 560 550 ··· 665 655 int err, ifindex; 666 656 667 657 err = create_netkit(mode, NETKIT_PASS, NETKIT_PASS, 668 - &ifindex, false, NETKIT_SCRUB_DEFAULT, 669 - NETKIT_SCRUB_DEFAULT); 658 + &ifindex, NETKIT_SCRUB_DEFAULT, 659 + NETKIT_SCRUB_DEFAULT, 0); 670 660 if (err) 671 661 return; 672 662 ··· 743 733 struct bpf_link *link; 744 734 745 735 err = create_netkit(mode, NETKIT_PASS, NETKIT_PASS, 746 - &ifindex, true, NETKIT_SCRUB_DEFAULT, 747 - NETKIT_SCRUB_DEFAULT); 736 + &ifindex, NETKIT_SCRUB_DEFAULT, 737 + NETKIT_SCRUB_DEFAULT, FLAG_SAME_NETNS); 748 738 if (err) 749 739 return; 750 740 ··· 809 799 serial_test_tc_netkit_pkt_type_mode(NETKIT_L3); 810 800 } 811 801 812 - static void serial_test_tc_netkit_scrub_type(int scrub) 802 + static void serial_test_tc_netkit_scrub_type(int scrub, bool room) 813 803 { 814 804 LIBBPF_OPTS(bpf_netkit_opts, optl); 815 805 struct test_tc_link *skel; ··· 817 807 int err, ifindex; 818 808 819 809 err = create_netkit(NETKIT_L2, NETKIT_PASS, NETKIT_PASS, 820 - &ifindex, false, scrub, scrub); 810 + &ifindex, scrub, scrub, 811 + room ? FLAG_ADJUST_ROOM : 0); 821 812 if (err) 822 813 return; 823 814 ··· 853 842 ASSERT_EQ(skel->bss->seen_tc8, true, "seen_tc8"); 854 843 ASSERT_EQ(skel->bss->mark, scrub == NETKIT_SCRUB_NONE ? MARK : 0, "mark"); 855 844 ASSERT_EQ(skel->bss->prio, scrub == NETKIT_SCRUB_NONE ? PRIO : 0, "prio"); 845 + ASSERT_EQ(skel->bss->headroom, room ? NETKIT_HEADROOM : 0, "headroom"); 846 + ASSERT_EQ(skel->bss->tailroom, room ? NETKIT_TAILROOM : 0, "tailroom"); 856 847 cleanup: 857 848 test_tc_link__destroy(skel); 858 849 ··· 865 852 866 853 void serial_test_tc_netkit_scrub(void) 867 854 { 868 - serial_test_tc_netkit_scrub_type(NETKIT_SCRUB_DEFAULT); 869 - serial_test_tc_netkit_scrub_type(NETKIT_SCRUB_NONE); 855 + serial_test_tc_netkit_scrub_type(NETKIT_SCRUB_DEFAULT, false); 856 + serial_test_tc_netkit_scrub_type(NETKIT_SCRUB_NONE, true); 870 857 }
+15
tools/testing/selftests/bpf/progs/test_tc_link.c
··· 8 8 #include <linux/if_packet.h> 9 9 #include <bpf/bpf_endian.h> 10 10 #include <bpf/bpf_helpers.h> 11 + #include <bpf/bpf_core_read.h> 11 12 12 13 char LICENSE[] SEC("license") = "GPL"; 13 14 ··· 28 27 bool seen_mcast; 29 28 30 29 int mark, prio; 30 + unsigned short headroom, tailroom; 31 31 32 32 SEC("tc/ingress") 33 33 int tc1(struct __sk_buff *skb) ··· 106 104 return TCX_PASS; 107 105 } 108 106 107 + struct sk_buff { 108 + struct net_device *dev; 109 + }; 110 + 111 + struct net_device { 112 + unsigned short needed_headroom; 113 + unsigned short needed_tailroom; 114 + }; 115 + 109 116 SEC("tc/egress") 110 117 int tc8(struct __sk_buff *skb) 111 118 { 119 + struct net_device *dev = BPF_CORE_READ((struct sk_buff *)skb, dev); 120 + 112 121 seen_tc8 = true; 113 122 mark = skb->mark; 114 123 prio = skb->priority; 124 + headroom = BPF_CORE_READ(dev, needed_headroom); 125 + tailroom = BPF_CORE_READ(dev, needed_tailroom); 115 126 return TCX_PASS; 116 127 }