Skip to content

Commit 4688adc

Browse files
lxingregkh
authored andcommitted
selftests: net: fix server bind failure in sctp_vrf.sh
[ Upstream commit a73ca04 ] sctp_vrf.sh could fail: TEST 12: bind vrf-2 & 1 in server, connect from client 1 & 2, N [FAIL] not ok 1 selftests: net: sctp_vrf.sh # exit=3 The failure happens when the server bind in a new run conflicts with an existing association from the previous run: [1] ip netns exec $SERVER_NS ./sctp_hello server ... [2] ip netns exec $CLIENT_NS ./sctp_hello client ... [3] ip netns exec $SERVER_NS pkill sctp_hello ... [4] ip netns exec $SERVER_NS ./sctp_hello server ... It occurs if the client in [2] sends a message and closes immediately. With the message unacked, no SHUTDOWN is sent. Killing the server in [3] triggers a SHUTDOWN the client also ignores due to the unacked message, leaving the old association alive. This causes the bind at [4] to fail until the message is acked and the client responds to a second SHUTDOWN after the server’s T2 timer expires (3s). This patch fixes the issue by preventing the client from sending data. Instead, the client blocks on recv() and waits for the server to close. It also waits until both the server and the client sockets are fully released in stop_server and wait_client before restarting. Additionally, replace 2>&1 >/dev/null with -q in sysctl and grep, and drop other redundant 2>&1 >/dev/null redirections, and fix a typo from N to Y (connect successfully) in the description of the last test. Fixes: a61bd7b ("selftests: add a selftest for sctp vrf") Reported-by: Hangbin Liu <liuhangbin@gmail.com> Tested-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: Xin Long <lucien.xin@gmail.com> Link: https://patch.msgid.link/be2dacf52d0917c4ba5e2e8c5a9cb640740ad2b6.1760731574.git.lucien.xin@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent 1a6ede2 commit 4688adc

File tree

2 files changed

+47
-43
lines changed

2 files changed

+47
-43
lines changed

tools/testing/selftests/net/sctp_hello.c

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ static void set_addr(struct sockaddr_storage *ss, char *ip, char *port, int *len
2929
static int do_client(int argc, char *argv[])
3030
{
3131
struct sockaddr_storage ss;
32-
char buf[] = "hello";
3332
int csk, ret, len;
3433

3534
if (argc < 5) {
@@ -56,16 +55,10 @@ static int do_client(int argc, char *argv[])
5655

5756
set_addr(&ss, argv[3], argv[4], &len);
5857
ret = connect(csk, (struct sockaddr *)&ss, len);
59-
if (ret < 0) {
60-
printf("failed to connect to peer\n");
58+
if (ret < 0)
6159
return -1;
62-
}
6360

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-
}
61+
recv(csk, NULL, 0, 0);
6962
close(csk);
7063

7164
return 0;
@@ -75,7 +68,6 @@ int main(int argc, char *argv[])
7568
{
7669
struct sockaddr_storage ss;
7770
int lsk, csk, ret, len;
78-
char buf[20];
7971

8072
if (argc < 2 || (strcmp(argv[1], "server") && strcmp(argv[1], "client"))) {
8173
printf("%s server|client ...\n", argv[0]);
@@ -125,11 +117,6 @@ int main(int argc, char *argv[])
125117
return -1;
126118
}
127119

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-
}
133120
close(csk);
134121
close(lsk);
135122

tools/testing/selftests/net/sctp_vrf.sh

Lines changed: 45 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@ setup() {
2020
modprobe sctp_diag
2121
setup_ns CLIENT_NS1 CLIENT_NS2 SERVER_NS
2222

23-
ip net exec $CLIENT_NS1 sysctl -w net.ipv6.conf.default.accept_dad=0 2>&1 >/dev/null
24-
ip net exec $CLIENT_NS2 sysctl -w net.ipv6.conf.default.accept_dad=0 2>&1 >/dev/null
25-
ip net exec $SERVER_NS sysctl -w net.ipv6.conf.default.accept_dad=0 2>&1 >/dev/null
23+
ip net exec $CLIENT_NS1 sysctl -wq net.ipv6.conf.default.accept_dad=0
24+
ip net exec $CLIENT_NS2 sysctl -wq net.ipv6.conf.default.accept_dad=0
25+
ip net exec $SERVER_NS sysctl -wq net.ipv6.conf.default.accept_dad=0
2626

2727
ip -n $SERVER_NS link add veth1 type veth peer name veth1 netns $CLIENT_NS1
2828
ip -n $SERVER_NS link add veth2 type veth peer name veth1 netns $CLIENT_NS2
@@ -62,17 +62,40 @@ setup() {
6262
}
6363

6464
cleanup() {
65-
ip netns exec $SERVER_NS pkill sctp_hello 2>&1 >/dev/null
65+
wait_client $CLIENT_NS1
66+
wait_client $CLIENT_NS2
67+
stop_server
6668
cleanup_ns $CLIENT_NS1 $CLIENT_NS2 $SERVER_NS
6769
}
6870

69-
wait_server() {
71+
start_server() {
7072
local IFACE=$1
7173
local CNT=0
7274

73-
until ip netns exec $SERVER_NS ss -lS src $SERVER_IP:$SERVER_PORT | \
74-
grep LISTEN | grep "$IFACE" 2>&1 >/dev/null; do
75-
[ $((CNT++)) = "20" ] && { RET=3; return $RET; }
75+
ip netns exec $SERVER_NS ./sctp_hello server $AF $SERVER_IP $SERVER_PORT $IFACE &
76+
disown
77+
until ip netns exec $SERVER_NS ss -SlH | grep -q "$IFACE"; do
78+
[ $((CNT++)) -eq 30 ] && { RET=3; return $RET; }
79+
sleep 0.1
80+
done
81+
}
82+
83+
stop_server() {
84+
local CNT=0
85+
86+
ip netns exec $SERVER_NS pkill sctp_hello
87+
while ip netns exec $SERVER_NS ss -SaH | grep -q .; do
88+
[ $((CNT++)) -eq 30 ] && break
89+
sleep 0.1
90+
done
91+
}
92+
93+
wait_client() {
94+
local CLIENT_NS=$1
95+
local CNT=0
96+
97+
while ip netns exec $CLIENT_NS ss -SaH | grep -q .; do
98+
[ $((CNT++)) -eq 30 ] && break
7699
sleep 0.1
77100
done
78101
}
@@ -81,40 +104,34 @@ do_test() {
81104
local CLIENT_NS=$1
82105
local IFACE=$2
83106

84-
ip netns exec $SERVER_NS pkill sctp_hello 2>&1 >/dev/null
85-
ip netns exec $SERVER_NS ./sctp_hello server $AF $SERVER_IP \
86-
$SERVER_PORT $IFACE 2>&1 >/dev/null &
87-
disown
88-
wait_server $IFACE || return $RET
107+
start_server $IFACE || return $RET
89108
timeout 3 ip netns exec $CLIENT_NS ./sctp_hello client $AF \
90-
$SERVER_IP $SERVER_PORT $CLIENT_IP $CLIENT_PORT 2>&1 >/dev/null
109+
$SERVER_IP $SERVER_PORT $CLIENT_IP $CLIENT_PORT
91110
RET=$?
111+
wait_client $CLIENT_NS
112+
stop_server
92113
return $RET
93114
}
94115

95116
do_testx() {
96117
local IFACE1=$1
97118
local IFACE2=$2
98119

99-
ip netns exec $SERVER_NS pkill sctp_hello 2>&1 >/dev/null
100-
ip netns exec $SERVER_NS ./sctp_hello server $AF $SERVER_IP \
101-
$SERVER_PORT $IFACE1 2>&1 >/dev/null &
102-
disown
103-
wait_server $IFACE1 || return $RET
104-
ip netns exec $SERVER_NS ./sctp_hello server $AF $SERVER_IP \
105-
$SERVER_PORT $IFACE2 2>&1 >/dev/null &
106-
disown
107-
wait_server $IFACE2 || return $RET
120+
start_server $IFACE1 || return $RET
121+
start_server $IFACE2 || return $RET
108122
timeout 3 ip netns exec $CLIENT_NS1 ./sctp_hello client $AF \
109-
$SERVER_IP $SERVER_PORT $CLIENT_IP $CLIENT_PORT 2>&1 >/dev/null && \
123+
$SERVER_IP $SERVER_PORT $CLIENT_IP $CLIENT_PORT && \
110124
timeout 3 ip netns exec $CLIENT_NS2 ./sctp_hello client $AF \
111-
$SERVER_IP $SERVER_PORT $CLIENT_IP $CLIENT_PORT 2>&1 >/dev/null
125+
$SERVER_IP $SERVER_PORT $CLIENT_IP $CLIENT_PORT
112126
RET=$?
127+
wait_client $CLIENT_NS1
128+
wait_client $CLIENT_NS2
129+
stop_server
113130
return $RET
114131
}
115132

116133
testup() {
117-
ip netns exec $SERVER_NS sysctl -w net.sctp.l3mdev_accept=1 2>&1 >/dev/null
134+
ip netns exec $SERVER_NS sysctl -wq net.sctp.l3mdev_accept=1
118135
echo -n "TEST 01: nobind, connect from client 1, l3mdev_accept=1, Y "
119136
do_test $CLIENT_NS1 || { echo "[FAIL]"; return $RET; }
120137
echo "[PASS]"
@@ -123,7 +140,7 @@ testup() {
123140
do_test $CLIENT_NS2 && { echo "[FAIL]"; return $RET; }
124141
echo "[PASS]"
125142

126-
ip netns exec $SERVER_NS sysctl -w net.sctp.l3mdev_accept=0 2>&1 >/dev/null
143+
ip netns exec $SERVER_NS sysctl -wq net.sctp.l3mdev_accept=0
127144
echo -n "TEST 03: nobind, connect from client 1, l3mdev_accept=0, N "
128145
do_test $CLIENT_NS1 && { echo "[FAIL]"; return $RET; }
129146
echo "[PASS]"
@@ -160,7 +177,7 @@ testup() {
160177
do_testx vrf-1 vrf-2 || { echo "[FAIL]"; return $RET; }
161178
echo "[PASS]"
162179

163-
echo -n "TEST 12: bind vrf-2 & 1 in server, connect from client 1 & 2, N "
180+
echo -n "TEST 12: bind vrf-2 & 1 in server, connect from client 1 & 2, Y "
164181
do_testx vrf-2 vrf-1 || { echo "[FAIL]"; return $RET; }
165182
echo "[PASS]"
166183
}

0 commit comments

Comments
 (0)