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

Merge branch 'selftests-bpf-move-test_lwt_seg6local-to-test_progs'

Bastien Curutchet says:

====================
This patch series continues the work to migrate the script tests into
prog_tests.

test_lwt_seg6local.sh tests some bpf_lwt_* helpers. It contains only one
test that uses a network topology quite different than the ones that
can be found in others prog_tests/lwt_*.c files so I add a new
prog_tests/lwt_seg6local.c file.

While working on the migration I noticed that some routes present in the
script weren't needed so PATCH 1 deletes them and then PATCH 2 migrates
the test into the test_progs framework.
====================

Acked-by: Stanislav Fomichev <sdf@fomichev.me>
Link: https://patch.msgid.link/20250307-seg6local-v1-0-990fff8f180d@bootlin.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>

+176 -157
-1
tools/testing/selftests/bpf/Makefile
··· 100 100 101 101 # Order correspond to 'make run_tests' order 102 102 TEST_PROGS := test_kmod.sh \ 103 - test_lwt_seg6local.sh \ 104 103 test_lirc_mode2.sh \ 105 104 test_xdp_vlan_mode_generic.sh \ 106 105 test_xdp_vlan_mode_native.sh \
+176
tools/testing/selftests/bpf/prog_tests/lwt_seg6local.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + 3 + /* Connects 6 network namespaces through veths. 4 + * Each NS may have different IPv6 global scope addresses : 5 + * 6 + * NS1 NS2 NS3 NS4 NS5 NS6 7 + * lo veth1 <-> veth2 veth3 <-> veth4 veth5 <-> veth6 lo veth7 <-> veth8 veth9 <-> veth10 lo 8 + * fb00 ::1 ::12 ::21 ::34 ::43 ::56 ::65 ::78 ::87 ::910 ::109 ::6 9 + * fd00 ::4 10 + * fc42 ::1 11 + * 12 + * All IPv6 packets going to fb00::/16 through NS2 will be encapsulated in a 13 + * IPv6 header with a Segment Routing Header, with segments : 14 + * fd00::1 -> fd00::2 -> fd00::3 -> fd00::4 15 + * 16 + * 3 fd00::/16 IPv6 addresses are binded to seg6local End.BPF actions : 17 + * - fd00::1 : add a TLV, change the flags and apply a End.X action to fc42::1 18 + * - fd00::2 : remove the TLV, change the flags, add a tag 19 + * - fd00::3 : apply an End.T action to fd00::4, through routing table 117 20 + * 21 + * fd00::4 is a simple Segment Routing node decapsulating the inner IPv6 packet. 22 + * Each End.BPF action will validate the operations applied on the SRH by the 23 + * previous BPF program in the chain, otherwise the packet is dropped. 24 + * 25 + * An UDP datagram is sent from fb00::1 to fb00::6. The test succeeds if this 26 + * datagram can be read on NS6 when binding to fb00::6. 27 + */ 28 + 29 + #include "network_helpers.h" 30 + #include "test_progs.h" 31 + 32 + #define NETNS_BASE "lwt-seg6local-" 33 + #define BPF_FILE "test_lwt_seg6local.bpf.o" 34 + 35 + static void cleanup(void) 36 + { 37 + int ns; 38 + 39 + for (ns = 1; ns < 7; ns++) 40 + SYS_NOFAIL("ip netns del %s%d", NETNS_BASE, ns); 41 + } 42 + 43 + static int setup(void) 44 + { 45 + int ns; 46 + 47 + for (ns = 1; ns < 7; ns++) 48 + SYS(fail, "ip netns add %s%d", NETNS_BASE, ns); 49 + 50 + SYS(fail, "ip -n %s6 link set dev lo up", NETNS_BASE); 51 + 52 + for (ns = 1; ns < 6; ns++) { 53 + int local_id = ns * 2 - 1; 54 + int peer_id = ns * 2; 55 + int next_ns = ns + 1; 56 + 57 + SYS(fail, "ip -n %s%d link add veth%d type veth peer name veth%d netns %s%d", 58 + NETNS_BASE, ns, local_id, peer_id, NETNS_BASE, next_ns); 59 + 60 + SYS(fail, "ip -n %s%d link set dev veth%d up", NETNS_BASE, ns, local_id); 61 + SYS(fail, "ip -n %s%d link set dev veth%d up", NETNS_BASE, next_ns, peer_id); 62 + 63 + /* All link scope addresses to veths */ 64 + SYS(fail, "ip -n %s%d -6 addr add fb00::%d%d/16 dev veth%d scope link", 65 + NETNS_BASE, ns, local_id, peer_id, local_id); 66 + SYS(fail, "ip -n %s%d -6 addr add fb00::%d%d/16 dev veth%d scope link", 67 + NETNS_BASE, next_ns, peer_id, local_id, peer_id); 68 + } 69 + 70 + 71 + SYS(fail, "ip -n %s5 -6 route add fb00::109 table 117 dev veth9 scope link", NETNS_BASE); 72 + 73 + SYS(fail, "ip -n %s1 -6 addr add fb00::1/16 dev lo", NETNS_BASE); 74 + SYS(fail, "ip -n %s1 -6 route add fb00::6 dev veth1 via fb00::21", NETNS_BASE); 75 + 76 + SYS(fail, "ip -n %s2 -6 route add fb00::6 encap bpf in obj %s sec encap_srh dev veth2", 77 + NETNS_BASE, BPF_FILE); 78 + SYS(fail, "ip -n %s2 -6 route add fd00::1 dev veth3 via fb00::43 scope link", NETNS_BASE); 79 + 80 + SYS(fail, "ip -n %s3 -6 route add fc42::1 dev veth5 via fb00::65", NETNS_BASE); 81 + SYS(fail, 82 + "ip -n %s3 -6 route add fd00::1 encap seg6local action End.BPF endpoint obj %s sec add_egr_x dev veth4", 83 + NETNS_BASE, BPF_FILE); 84 + 85 + SYS(fail, 86 + "ip -n %s4 -6 route add fd00::2 encap seg6local action End.BPF endpoint obj %s sec pop_egr dev veth6", 87 + NETNS_BASE, BPF_FILE); 88 + SYS(fail, "ip -n %s4 -6 addr add fc42::1 dev lo", NETNS_BASE); 89 + SYS(fail, "ip -n %s4 -6 route add fd00::3 dev veth7 via fb00::87", NETNS_BASE); 90 + 91 + SYS(fail, "ip -n %s5 -6 route add fd00::4 table 117 dev veth9 via fb00::109", NETNS_BASE); 92 + SYS(fail, 93 + "ip -n %s5 -6 route add fd00::3 encap seg6local action End.BPF endpoint obj %s sec inspect_t dev veth8", 94 + NETNS_BASE, BPF_FILE); 95 + 96 + SYS(fail, "ip -n %s6 -6 addr add fb00::6/16 dev lo", NETNS_BASE); 97 + SYS(fail, "ip -n %s6 -6 addr add fd00::4/16 dev lo", NETNS_BASE); 98 + 99 + for (ns = 1; ns < 6; ns++) 100 + SYS(fail, "ip netns exec %s%d sysctl -wq net.ipv6.conf.all.forwarding=1", 101 + NETNS_BASE, ns); 102 + 103 + SYS(fail, "ip netns exec %s6 sysctl -wq net.ipv6.conf.all.seg6_enabled=1", NETNS_BASE); 104 + SYS(fail, "ip netns exec %s6 sysctl -wq net.ipv6.conf.lo.seg6_enabled=1", NETNS_BASE); 105 + SYS(fail, "ip netns exec %s6 sysctl -wq net.ipv6.conf.veth10.seg6_enabled=1", NETNS_BASE); 106 + 107 + return 0; 108 + fail: 109 + return -1; 110 + } 111 + 112 + #define SERVER_PORT 7330 113 + #define CLIENT_PORT 2121 114 + void test_lwt_seg6local(void) 115 + { 116 + struct sockaddr_in6 server_addr = {}; 117 + const char *ns1 = NETNS_BASE "1"; 118 + const char *ns6 = NETNS_BASE "6"; 119 + struct nstoken *nstoken = NULL; 120 + const char *foobar = "foobar"; 121 + ssize_t bytes; 122 + int sfd, cfd; 123 + char buf[7]; 124 + 125 + if (!ASSERT_OK(setup(), "setup")) 126 + goto out; 127 + 128 + nstoken = open_netns(ns6); 129 + if (!ASSERT_OK_PTR(nstoken, "open ns6")) 130 + goto out; 131 + 132 + sfd = start_server_str(AF_INET6, SOCK_DGRAM, "fb00::6", SERVER_PORT, NULL); 133 + if (!ASSERT_OK_FD(sfd, "start server")) 134 + goto close_netns; 135 + 136 + close_netns(nstoken); 137 + 138 + nstoken = open_netns(ns1); 139 + if (!ASSERT_OK_PTR(nstoken, "open ns1")) 140 + goto close_server; 141 + 142 + cfd = start_server_str(AF_INET6, SOCK_DGRAM, "fb00::1", CLIENT_PORT, NULL); 143 + if (!ASSERT_OK_FD(cfd, "start client")) 144 + goto close_server; 145 + 146 + close_netns(nstoken); 147 + nstoken = NULL; 148 + 149 + /* Send a packet larger than MTU */ 150 + server_addr.sin6_family = AF_INET6; 151 + server_addr.sin6_port = htons(SERVER_PORT); 152 + if (!ASSERT_EQ(inet_pton(AF_INET6, "fb00::6", &server_addr.sin6_addr), 1, 153 + "build target addr")) 154 + goto close_client; 155 + 156 + bytes = sendto(cfd, foobar, sizeof(foobar), 0, 157 + (struct sockaddr *)&server_addr, sizeof(server_addr)); 158 + if (!ASSERT_EQ(bytes, sizeof(foobar), "send packet")) 159 + goto close_client; 160 + 161 + /* Verify we received all expected bytes */ 162 + bytes = read(sfd, buf, sizeof(buf)); 163 + if (!ASSERT_EQ(bytes, sizeof(buf), "receive packet")) 164 + goto close_client; 165 + ASSERT_STREQ(buf, foobar, "check udp packet"); 166 + 167 + close_client: 168 + close(cfd); 169 + close_server: 170 + close(sfd); 171 + close_netns: 172 + close_netns(nstoken); 173 + 174 + out: 175 + cleanup(); 176 + }
-156
tools/testing/selftests/bpf/test_lwt_seg6local.sh
··· 1 - #!/bin/bash 2 - # Connects 6 network namespaces through veths. 3 - # Each NS may have different IPv6 global scope addresses : 4 - # NS1 ---- NS2 ---- NS3 ---- NS4 ---- NS5 ---- NS6 5 - # fb00::1 fd00::1 fd00::2 fd00::3 fb00::6 6 - # fc42::1 fd00::4 7 - # 8 - # All IPv6 packets going to fb00::/16 through NS2 will be encapsulated in a 9 - # IPv6 header with a Segment Routing Header, with segments : 10 - # fd00::1 -> fd00::2 -> fd00::3 -> fd00::4 11 - # 12 - # 3 fd00::/16 IPv6 addresses are binded to seg6local End.BPF actions : 13 - # - fd00::1 : add a TLV, change the flags and apply a End.X action to fc42::1 14 - # - fd00::2 : remove the TLV, change the flags, add a tag 15 - # - fd00::3 : apply an End.T action to fd00::4, through routing table 117 16 - # 17 - # fd00::4 is a simple Segment Routing node decapsulating the inner IPv6 packet. 18 - # Each End.BPF action will validate the operations applied on the SRH by the 19 - # previous BPF program in the chain, otherwise the packet is dropped. 20 - # 21 - # An UDP datagram is sent from fb00::1 to fb00::6. The test succeeds if this 22 - # datagram can be read on NS6 when binding to fb00::6. 23 - 24 - # Kselftest framework requirement - SKIP code is 4. 25 - ksft_skip=4 26 - BPF_FILE="test_lwt_seg6local.bpf.o" 27 - readonly NS1="ns1-$(mktemp -u XXXXXX)" 28 - readonly NS2="ns2-$(mktemp -u XXXXXX)" 29 - readonly NS3="ns3-$(mktemp -u XXXXXX)" 30 - readonly NS4="ns4-$(mktemp -u XXXXXX)" 31 - readonly NS5="ns5-$(mktemp -u XXXXXX)" 32 - readonly NS6="ns6-$(mktemp -u XXXXXX)" 33 - 34 - msg="skip all tests:" 35 - if [ $UID != 0 ]; then 36 - echo $msg please run this as root >&2 37 - exit $ksft_skip 38 - fi 39 - 40 - TMP_FILE="/tmp/selftest_lwt_seg6local.txt" 41 - 42 - cleanup() 43 - { 44 - if [ "$?" = "0" ]; then 45 - echo "selftests: test_lwt_seg6local [PASS]"; 46 - else 47 - echo "selftests: test_lwt_seg6local [FAILED]"; 48 - fi 49 - 50 - set +e 51 - ip netns del ${NS1} 2> /dev/null 52 - ip netns del ${NS2} 2> /dev/null 53 - ip netns del ${NS3} 2> /dev/null 54 - ip netns del ${NS4} 2> /dev/null 55 - ip netns del ${NS5} 2> /dev/null 56 - ip netns del ${NS6} 2> /dev/null 57 - rm -f $TMP_FILE 58 - } 59 - 60 - set -e 61 - 62 - ip netns add ${NS1} 63 - ip netns add ${NS2} 64 - ip netns add ${NS3} 65 - ip netns add ${NS4} 66 - ip netns add ${NS5} 67 - ip netns add ${NS6} 68 - 69 - trap cleanup 0 2 3 6 9 70 - 71 - ip link add veth1 type veth peer name veth2 72 - ip link add veth3 type veth peer name veth4 73 - ip link add veth5 type veth peer name veth6 74 - ip link add veth7 type veth peer name veth8 75 - ip link add veth9 type veth peer name veth10 76 - 77 - ip link set veth1 netns ${NS1} 78 - ip link set veth2 netns ${NS2} 79 - ip link set veth3 netns ${NS2} 80 - ip link set veth4 netns ${NS3} 81 - ip link set veth5 netns ${NS3} 82 - ip link set veth6 netns ${NS4} 83 - ip link set veth7 netns ${NS4} 84 - ip link set veth8 netns ${NS5} 85 - ip link set veth9 netns ${NS5} 86 - ip link set veth10 netns ${NS6} 87 - 88 - ip netns exec ${NS1} ip link set dev veth1 up 89 - ip netns exec ${NS2} ip link set dev veth2 up 90 - ip netns exec ${NS2} ip link set dev veth3 up 91 - ip netns exec ${NS3} ip link set dev veth4 up 92 - ip netns exec ${NS3} ip link set dev veth5 up 93 - ip netns exec ${NS4} ip link set dev veth6 up 94 - ip netns exec ${NS4} ip link set dev veth7 up 95 - ip netns exec ${NS5} ip link set dev veth8 up 96 - ip netns exec ${NS5} ip link set dev veth9 up 97 - ip netns exec ${NS6} ip link set dev veth10 up 98 - ip netns exec ${NS6} ip link set dev lo up 99 - 100 - # All link scope addresses and routes required between veths 101 - ip netns exec ${NS1} ip -6 addr add fb00::12/16 dev veth1 scope link 102 - ip netns exec ${NS1} ip -6 route add fb00::21 dev veth1 scope link 103 - ip netns exec ${NS2} ip -6 addr add fb00::21/16 dev veth2 scope link 104 - ip netns exec ${NS2} ip -6 addr add fb00::34/16 dev veth3 scope link 105 - ip netns exec ${NS2} ip -6 route add fb00::43 dev veth3 scope link 106 - ip netns exec ${NS3} ip -6 route add fb00::65 dev veth5 scope link 107 - ip netns exec ${NS3} ip -6 addr add fb00::43/16 dev veth4 scope link 108 - ip netns exec ${NS3} ip -6 addr add fb00::56/16 dev veth5 scope link 109 - ip netns exec ${NS4} ip -6 addr add fb00::65/16 dev veth6 scope link 110 - ip netns exec ${NS4} ip -6 addr add fb00::78/16 dev veth7 scope link 111 - ip netns exec ${NS4} ip -6 route add fb00::87 dev veth7 scope link 112 - ip netns exec ${NS5} ip -6 addr add fb00::87/16 dev veth8 scope link 113 - ip netns exec ${NS5} ip -6 addr add fb00::910/16 dev veth9 scope link 114 - ip netns exec ${NS5} ip -6 route add fb00::109 dev veth9 scope link 115 - ip netns exec ${NS5} ip -6 route add fb00::109 table 117 dev veth9 scope link 116 - ip netns exec ${NS6} ip -6 addr add fb00::109/16 dev veth10 scope link 117 - 118 - ip netns exec ${NS1} ip -6 addr add fb00::1/16 dev lo 119 - ip netns exec ${NS1} ip -6 route add fb00::6 dev veth1 via fb00::21 120 - 121 - ip netns exec ${NS2} ip -6 route add fb00::6 encap bpf in obj ${BPF_FILE} sec encap_srh dev veth2 122 - ip netns exec ${NS2} ip -6 route add fd00::1 dev veth3 via fb00::43 scope link 123 - 124 - ip netns exec ${NS3} ip -6 route add fc42::1 dev veth5 via fb00::65 125 - ip netns exec ${NS3} ip -6 route add fd00::1 encap seg6local action End.BPF endpoint obj ${BPF_FILE} sec add_egr_x dev veth4 126 - 127 - ip netns exec ${NS4} ip -6 route add fd00::2 encap seg6local action End.BPF endpoint obj ${BPF_FILE} sec pop_egr dev veth6 128 - ip netns exec ${NS4} ip -6 addr add fc42::1 dev lo 129 - ip netns exec ${NS4} ip -6 route add fd00::3 dev veth7 via fb00::87 130 - 131 - ip netns exec ${NS5} ip -6 route add fd00::4 table 117 dev veth9 via fb00::109 132 - ip netns exec ${NS5} ip -6 route add fd00::3 encap seg6local action End.BPF endpoint obj ${BPF_FILE} sec inspect_t dev veth8 133 - 134 - ip netns exec ${NS6} ip -6 addr add fb00::6/16 dev lo 135 - ip netns exec ${NS6} ip -6 addr add fd00::4/16 dev lo 136 - 137 - ip netns exec ${NS1} sysctl net.ipv6.conf.all.forwarding=1 > /dev/null 138 - ip netns exec ${NS2} sysctl net.ipv6.conf.all.forwarding=1 > /dev/null 139 - ip netns exec ${NS3} sysctl net.ipv6.conf.all.forwarding=1 > /dev/null 140 - ip netns exec ${NS4} sysctl net.ipv6.conf.all.forwarding=1 > /dev/null 141 - ip netns exec ${NS5} sysctl net.ipv6.conf.all.forwarding=1 > /dev/null 142 - 143 - ip netns exec ${NS6} sysctl net.ipv6.conf.all.seg6_enabled=1 > /dev/null 144 - ip netns exec ${NS6} sysctl net.ipv6.conf.lo.seg6_enabled=1 > /dev/null 145 - ip netns exec ${NS6} sysctl net.ipv6.conf.veth10.seg6_enabled=1 > /dev/null 146 - 147 - ip netns exec ${NS6} nc -l -6 -u -d 7330 > $TMP_FILE & 148 - ip netns exec ${NS1} bash -c "echo 'foobar' | nc -w0 -6 -u -p 2121 -s fb00::1 fb00::6 7330" 149 - sleep 5 # wait enough time to ensure the UDP datagram arrived to the last segment 150 - kill -TERM $! 151 - 152 - if [[ $(< $TMP_FILE) != "foobar" ]]; then 153 - exit 1 154 - fi 155 - 156 - exit 0