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

selftests: add a selftest for sctp vrf

This patch adds 12 small test cases: 01-04 test for the sysctl
net.sctp.l3mdev_accept. 05-10 test for only binding to a right
l3mdev device, the connection can be created. 11-12 test for
two socks binding to different l3mdev devices at the same time,
each of them can process the packets from the corresponding
peer. The tests run for both IPv4 and IPv6 SCTP.

Signed-off-by: Xin Long <lucien.xin@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Xin Long and committed by
David S. Miller
a61bd7b9 b712d032

+317
+2
tools/testing/selftests/net/Makefile
··· 72 72 TEST_GEN_PROGS += sk_connect_zero_addr 73 73 TEST_PROGS += test_ingress_egress_chaining.sh 74 74 TEST_GEN_PROGS += so_incoming_cpu 75 + TEST_PROGS += sctp_vrf.sh 76 + TEST_GEN_FILES += sctp_hello 75 77 76 78 TEST_FILES := settings 77 79
+137
tools/testing/selftests/net/sctp_hello.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + 3 + #include <stdio.h> 4 + #include <stdlib.h> 5 + #include <string.h> 6 + #include <unistd.h> 7 + #include <sys/types.h> 8 + #include <netinet/in.h> 9 + #include <arpa/inet.h> 10 + 11 + static void set_addr(struct sockaddr_storage *ss, char *ip, char *port, int *len) 12 + { 13 + if (ss->ss_family == AF_INET) { 14 + struct sockaddr_in *a = (struct sockaddr_in *)ss; 15 + 16 + a->sin_addr.s_addr = inet_addr(ip); 17 + a->sin_port = htons(atoi(port)); 18 + *len = sizeof(*a); 19 + } else { 20 + struct sockaddr_in6 *a = (struct sockaddr_in6 *)ss; 21 + 22 + a->sin6_family = AF_INET6; 23 + inet_pton(AF_INET6, ip, &a->sin6_addr); 24 + a->sin6_port = htons(atoi(port)); 25 + *len = sizeof(*a); 26 + } 27 + } 28 + 29 + static int do_client(int argc, char *argv[]) 30 + { 31 + struct sockaddr_storage ss; 32 + char buf[] = "hello"; 33 + int csk, ret, len; 34 + 35 + if (argc < 5) { 36 + printf("%s client -4|6 IP PORT [IP PORT]\n", argv[0]); 37 + return -1; 38 + } 39 + 40 + bzero((void *)&ss, sizeof(ss)); 41 + ss.ss_family = !strcmp(argv[2], "-4") ? AF_INET : AF_INET6; 42 + csk = socket(ss.ss_family, SOCK_STREAM, IPPROTO_SCTP); 43 + if (csk < 0) { 44 + printf("failed to create socket\n"); 45 + return -1; 46 + } 47 + 48 + if (argc >= 7) { 49 + set_addr(&ss, argv[5], argv[6], &len); 50 + ret = bind(csk, (struct sockaddr *)&ss, len); 51 + if (ret < 0) { 52 + printf("failed to bind to address\n"); 53 + return -1; 54 + } 55 + } 56 + 57 + set_addr(&ss, argv[3], argv[4], &len); 58 + ret = connect(csk, (struct sockaddr *)&ss, len); 59 + if (ret < 0) { 60 + printf("failed to connect to peer\n"); 61 + return -1; 62 + } 63 + 64 + ret = send(csk, buf, strlen(buf) + 1, 0); 65 + if (ret < 0) { 66 + printf("failed to send msg %d\n", ret); 67 + return -1; 68 + } 69 + close(csk); 70 + 71 + return 0; 72 + } 73 + 74 + int main(int argc, char *argv[]) 75 + { 76 + struct sockaddr_storage ss; 77 + int lsk, csk, ret, len; 78 + char buf[20]; 79 + 80 + if (argc < 2 || (strcmp(argv[1], "server") && strcmp(argv[1], "client"))) { 81 + printf("%s server|client ...\n", argv[0]); 82 + return -1; 83 + } 84 + 85 + if (!strcmp(argv[1], "client")) 86 + return do_client(argc, argv); 87 + 88 + if (argc < 5) { 89 + printf("%s server -4|6 IP PORT [IFACE]\n", argv[0]); 90 + return -1; 91 + } 92 + 93 + ss.ss_family = !strcmp(argv[2], "-4") ? AF_INET : AF_INET6; 94 + lsk = socket(ss.ss_family, SOCK_STREAM, IPPROTO_SCTP); 95 + if (lsk < 0) { 96 + printf("failed to create lsk\n"); 97 + return -1; 98 + } 99 + 100 + if (argc >= 6) { 101 + ret = setsockopt(lsk, SOL_SOCKET, SO_BINDTODEVICE, 102 + argv[5], strlen(argv[5]) + 1); 103 + if (ret < 0) { 104 + printf("failed to bind to device\n"); 105 + return -1; 106 + } 107 + } 108 + 109 + set_addr(&ss, argv[3], argv[4], &len); 110 + ret = bind(lsk, (struct sockaddr *)&ss, len); 111 + if (ret < 0) { 112 + printf("failed to bind to address\n"); 113 + return -1; 114 + } 115 + 116 + ret = listen(lsk, 5); 117 + if (ret < 0) { 118 + printf("failed to listen on port\n"); 119 + return -1; 120 + } 121 + 122 + csk = accept(lsk, (struct sockaddr *)NULL, (socklen_t *)NULL); 123 + if (csk < 0) { 124 + printf("failed to accept new client\n"); 125 + return -1; 126 + } 127 + 128 + ret = recv(csk, buf, sizeof(buf), 0); 129 + if (ret <= 0) { 130 + printf("failed to recv msg %d\n", ret); 131 + return -1; 132 + } 133 + close(csk); 134 + close(lsk); 135 + 136 + return 0; 137 + }
+178
tools/testing/selftests/net/sctp_vrf.sh
··· 1 + #!/bin/bash 2 + # SPDX-License-Identifier: GPL-2.0 3 + # 4 + # Testing For SCTP VRF. 5 + # TOPO: CLIENT_NS1 (veth1) <---> (veth1) -> vrf_s1 6 + # SERVER_NS 7 + # CLIENT_NS2 (veth1) <---> (veth2) -> vrf_s2 8 + 9 + CLIENT_NS1="client-ns1" 10 + CLIENT_NS2="client-ns2" 11 + CLIENT_IP4="10.0.0.1" 12 + CLIENT_IP6="2000::1" 13 + CLIENT_PORT=1234 14 + 15 + SERVER_NS="server-ns" 16 + SERVER_IP4="10.0.0.2" 17 + SERVER_IP6="2000::2" 18 + SERVER_PORT=1234 19 + 20 + setup() { 21 + modprobe sctp 22 + modprobe sctp_diag 23 + ip netns add $CLIENT_NS1 24 + ip netns add $CLIENT_NS2 25 + ip netns add $SERVER_NS 26 + 27 + ip net exec $CLIENT_NS1 sysctl -w net.ipv6.conf.default.accept_dad=0 2>&1 >/dev/null 28 + ip net exec $CLIENT_NS2 sysctl -w net.ipv6.conf.default.accept_dad=0 2>&1 >/dev/null 29 + ip net exec $SERVER_NS sysctl -w net.ipv6.conf.default.accept_dad=0 2>&1 >/dev/null 30 + 31 + ip -n $SERVER_NS link add veth1 type veth peer name veth1 netns $CLIENT_NS1 32 + ip -n $SERVER_NS link add veth2 type veth peer name veth1 netns $CLIENT_NS2 33 + 34 + ip -n $CLIENT_NS1 link set veth1 up 35 + ip -n $CLIENT_NS1 addr add $CLIENT_IP4/24 dev veth1 36 + ip -n $CLIENT_NS1 addr add $CLIENT_IP6/24 dev veth1 37 + 38 + ip -n $CLIENT_NS2 link set veth1 up 39 + ip -n $CLIENT_NS2 addr add $CLIENT_IP4/24 dev veth1 40 + ip -n $CLIENT_NS2 addr add $CLIENT_IP6/24 dev veth1 41 + 42 + ip -n $SERVER_NS link add dummy1 type dummy 43 + ip -n $SERVER_NS link set dummy1 up 44 + ip -n $SERVER_NS link add vrf-1 type vrf table 10 45 + ip -n $SERVER_NS link add vrf-2 type vrf table 20 46 + ip -n $SERVER_NS link set vrf-1 up 47 + ip -n $SERVER_NS link set vrf-2 up 48 + ip -n $SERVER_NS link set veth1 master vrf-1 49 + ip -n $SERVER_NS link set veth2 master vrf-2 50 + 51 + ip -n $SERVER_NS addr add $SERVER_IP4/24 dev dummy1 52 + ip -n $SERVER_NS addr add $SERVER_IP4/24 dev veth1 53 + ip -n $SERVER_NS addr add $SERVER_IP4/24 dev veth2 54 + ip -n $SERVER_NS addr add $SERVER_IP6/24 dev dummy1 55 + ip -n $SERVER_NS addr add $SERVER_IP6/24 dev veth1 56 + ip -n $SERVER_NS addr add $SERVER_IP6/24 dev veth2 57 + 58 + ip -n $SERVER_NS link set veth1 up 59 + ip -n $SERVER_NS link set veth2 up 60 + ip -n $SERVER_NS route add table 10 $CLIENT_IP4 dev veth1 src $SERVER_IP4 61 + ip -n $SERVER_NS route add table 20 $CLIENT_IP4 dev veth2 src $SERVER_IP4 62 + ip -n $SERVER_NS route add $CLIENT_IP4 dev veth1 src $SERVER_IP4 63 + ip -n $SERVER_NS route add table 10 $CLIENT_IP6 dev veth1 src $SERVER_IP6 64 + ip -n $SERVER_NS route add table 20 $CLIENT_IP6 dev veth2 src $SERVER_IP6 65 + ip -n $SERVER_NS route add $CLIENT_IP6 dev veth1 src $SERVER_IP6 66 + } 67 + 68 + cleanup() { 69 + ip netns exec $SERVER_NS pkill sctp_hello 2>&1 >/dev/null 70 + ip netns del "$CLIENT_NS1" 71 + ip netns del "$CLIENT_NS2" 72 + ip netns del "$SERVER_NS" 73 + } 74 + 75 + wait_server() { 76 + local IFACE=$1 77 + local CNT=0 78 + 79 + until ip netns exec $SERVER_NS ss -lS src $SERVER_IP:$SERVER_PORT | \ 80 + grep LISTEN | grep "$IFACE" 2>&1 >/dev/null; do 81 + [ $((CNT++)) = "20" ] && { RET=3; return $RET; } 82 + sleep 0.1 83 + done 84 + } 85 + 86 + do_test() { 87 + local CLIENT_NS=$1 88 + local IFACE=$2 89 + 90 + ip netns exec $SERVER_NS pkill sctp_hello 2>&1 >/dev/null 91 + ip netns exec $SERVER_NS ./sctp_hello server $AF $SERVER_IP \ 92 + $SERVER_PORT $IFACE 2>&1 >/dev/null & 93 + disown 94 + wait_server $IFACE || return $RET 95 + timeout 3 ip netns exec $CLIENT_NS ./sctp_hello client $AF \ 96 + $SERVER_IP $SERVER_PORT $CLIENT_IP $CLIENT_PORT 2>&1 >/dev/null 97 + RET=$? 98 + return $RET 99 + } 100 + 101 + do_testx() { 102 + local IFACE1=$1 103 + local IFACE2=$2 104 + 105 + ip netns exec $SERVER_NS pkill sctp_hello 2>&1 >/dev/null 106 + ip netns exec $SERVER_NS ./sctp_hello server $AF $SERVER_IP \ 107 + $SERVER_PORT $IFACE1 2>&1 >/dev/null & 108 + disown 109 + wait_server $IFACE1 || return $RET 110 + ip netns exec $SERVER_NS ./sctp_hello server $AF $SERVER_IP \ 111 + $SERVER_PORT $IFACE2 2>&1 >/dev/null & 112 + disown 113 + wait_server $IFACE2 || return $RET 114 + timeout 3 ip netns exec $CLIENT_NS1 ./sctp_hello client $AF \ 115 + $SERVER_IP $SERVER_PORT $CLIENT_IP $CLIENT_PORT 2>&1 >/dev/null && \ 116 + timeout 3 ip netns exec $CLIENT_NS2 ./sctp_hello client $AF \ 117 + $SERVER_IP $SERVER_PORT $CLIENT_IP $CLIENT_PORT 2>&1 >/dev/null 118 + RET=$? 119 + return $RET 120 + } 121 + 122 + testup() { 123 + ip netns exec $SERVER_NS sysctl -w net.sctp.l3mdev_accept=1 2>&1 >/dev/null 124 + echo -n "TEST 01: nobind, connect from client 1, l3mdev_accept=1, Y " 125 + do_test $CLIENT_NS1 || { echo "[FAIL]"; return $RET; } 126 + echo "[PASS]" 127 + 128 + echo -n "TEST 02: nobind, connect from client 2, l3mdev_accept=1, N " 129 + do_test $CLIENT_NS2 && { echo "[FAIL]"; return $RET; } 130 + echo "[PASS]" 131 + 132 + ip netns exec $SERVER_NS sysctl -w net.sctp.l3mdev_accept=0 2>&1 >/dev/null 133 + echo -n "TEST 03: nobind, connect from client 1, l3mdev_accept=0, N " 134 + do_test $CLIENT_NS1 && { echo "[FAIL]"; return $RET; } 135 + echo "[PASS]" 136 + 137 + echo -n "TEST 04: nobind, connect from client 2, l3mdev_accept=0, N " 138 + do_test $CLIENT_NS2 && { echo "[FAIL]"; return $RET; } 139 + echo "[PASS]" 140 + 141 + echo -n "TEST 05: bind veth2 in server, connect from client 1, N " 142 + do_test $CLIENT_NS1 veth2 && { echo "[FAIL]"; return $RET; } 143 + echo "[PASS]" 144 + 145 + echo -n "TEST 06: bind veth1 in server, connect from client 1, Y " 146 + do_test $CLIENT_NS1 veth1 || { echo "[FAIL]"; return $RET; } 147 + echo "[PASS]" 148 + 149 + echo -n "TEST 07: bind vrf-1 in server, connect from client 1, Y " 150 + do_test $CLIENT_NS1 vrf-1 || { echo "[FAIL]"; return $RET; } 151 + echo "[PASS]" 152 + 153 + echo -n "TEST 08: bind vrf-2 in server, connect from client 1, N " 154 + do_test $CLIENT_NS1 vrf-2 && { echo "[FAIL]"; return $RET; } 155 + echo "[PASS]" 156 + 157 + echo -n "TEST 09: bind vrf-2 in server, connect from client 2, Y " 158 + do_test $CLIENT_NS2 vrf-2 || { echo "[FAIL]"; return $RET; } 159 + echo "[PASS]" 160 + 161 + echo -n "TEST 10: bind vrf-1 in server, connect from client 2, N " 162 + do_test $CLIENT_NS2 vrf-1 && { echo "[FAIL]"; return $RET; } 163 + echo "[PASS]" 164 + 165 + echo -n "TEST 11: bind vrf-1 & 2 in server, connect from client 1 & 2, Y " 166 + do_testx vrf-1 vrf-2 || { echo "[FAIL]"; return $RET; } 167 + echo "[PASS]" 168 + 169 + echo -n "TEST 12: bind vrf-2 & 1 in server, connect from client 1 & 2, N " 170 + do_testx vrf-2 vrf-1 || { echo "[FAIL]"; return $RET; } 171 + echo "[PASS]" 172 + } 173 + 174 + trap cleanup EXIT 175 + setup && echo "Testing For SCTP VRF:" && \ 176 + CLIENT_IP=$CLIENT_IP4 SERVER_IP=$SERVER_IP4 AF="-4" testup && echo "***v4 Tests Done***" && 177 + CLIENT_IP=$CLIENT_IP6 SERVER_IP=$SERVER_IP6 AF="-6" testup && echo "***v6 Tests Done***" 178 + exit $?