Skip to content

Commit a61bd7b

Browse files
lxindavem330
authored andcommitted
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 <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent b712d03 commit a61bd7b

File tree

3 files changed

+317
-0
lines changed

3 files changed

+317
-0
lines changed

tools/testing/selftests/net/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ TEST_GEN_PROGS += sk_bind_sendto_listen
7272
TEST_GEN_PROGS += sk_connect_zero_addr
7373
TEST_PROGS += test_ingress_egress_chaining.sh
7474
TEST_GEN_PROGS += so_incoming_cpu
75+
TEST_PROGS += sctp_vrf.sh
76+
TEST_GEN_FILES += sctp_hello
7577

7678
TEST_FILES := settings
7779

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
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+
}
Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
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 $?

0 commit comments

Comments
 (0)