xref: /openbmc/linux/tools/testing/selftests/net/mptcp/mptcp_connect.sh (revision aeddf9a2731de8235b2b433533d06ee7dc73d233)
1048d19d4SFlorian Westphal#!/bin/bash
2048d19d4SFlorian Westphal# SPDX-License-Identifier: GPL-2.0
3048d19d4SFlorian Westphal
45b5ff824SMatthieu Baerts (NGI0)# Double quotes to prevent globbing and word splitting is recommended in new
55b5ff824SMatthieu Baerts (NGI0)# code but we accept it, especially because there were too many before having
65b5ff824SMatthieu Baerts (NGI0)# address all other issues detected by shellcheck.
75b5ff824SMatthieu Baerts (NGI0)#shellcheck disable=SC2086
85b5ff824SMatthieu Baerts (NGI0)
9d83013bdSMatthieu Baerts. "$(dirname "${0}")/mptcp_lib.sh"
10d83013bdSMatthieu Baerts
11048d19d4SFlorian Westphaltime_start=$(date +%s)
12048d19d4SFlorian Westphal
1394d66ba1SGeliang Tangoptstring="S:R:d:e:l:r:h4cm:f:tC"
14048d19d4SFlorian Westphalret=0
15edbc16c4SMatthieu Baertsfinal_ret=0
16048d19d4SFlorian Westphalsin=""
17048d19d4SFlorian Westphalsout=""
1805be5e27SPaolo Abenicin_disconnect=""
19048d19d4SFlorian Westphalcin=""
20048d19d4SFlorian Westphalcout=""
21048d19d4SFlorian Westphalcapture=false
225888a61cSMatthieu Baertstimeout_poll=30
235888a61cSMatthieu Baertstimeout_test=$((timeout_poll * 2 + 1))
24048d19d4SFlorian Westphalipv6=true
25048d19d4SFlorian Westphalethtool_random_on=true
26e5484658SChristoph Paaschtc_delay="$((RANDOM%50))"
27048d19d4SFlorian Westphaltc_loss=$((RANDOM%101))
28048d19d4SFlorian Westphaltestmode=""
29048d19d4SFlorian Westphalsndbuf=0
308a4b910dSFlorian Westphalrcvbuf=0
31048d19d4SFlorian Westphaloptions_log=true
32767659f6SFlorian Westphaldo_tcp=0
3394d66ba1SGeliang Tangchecksum=false
34767659f6SFlorian Westphalfilesize=0
3505be5e27SPaolo Abeniconnect_per_transfer=1
36048d19d4SFlorian Westphal
37048d19d4SFlorian Westphalif [ $tc_loss -eq 100 ];then
38048d19d4SFlorian Westphal	tc_loss=1%
39048d19d4SFlorian Westphalelif [ $tc_loss -ge 10 ]; then
40048d19d4SFlorian Westphal	tc_loss=0.$tc_loss%
41048d19d4SFlorian Westphalelif [ $tc_loss -ge 1 ]; then
42048d19d4SFlorian Westphal	tc_loss=0.0$tc_loss%
43048d19d4SFlorian Westphalelse
44048d19d4SFlorian Westphal	tc_loss=""
45048d19d4SFlorian Westphalfi
46048d19d4SFlorian Westphal
47048d19d4SFlorian Westphalusage() {
48048d19d4SFlorian Westphal	echo "Usage: $0 [ -a ]"
49048d19d4SFlorian Westphal	echo -e "\t-d: tc/netem delay in milliseconds, e.g. \"-d 10\" (default random)"
50048d19d4SFlorian Westphal	echo -e "\t-l: tc/netem loss percentage, e.g. \"-l 0.02\" (default random)"
51048d19d4SFlorian Westphal	echo -e "\t-r: tc/netem reorder mode, e.g. \"-r 25% 50% gap 5\", use "-r 0" to disable reordering (default random)"
52048d19d4SFlorian Westphal	echo -e "\t-e: ethtool features to disable, e.g.: \"-e tso -e gso\" (default: randomly disable any of tso/gso/gro)"
53048d19d4SFlorian Westphal	echo -e "\t-4: IPv4 only: disable IPv6 tests (default: test both IPv4 and IPv6)"
54048d19d4SFlorian Westphal	echo -e "\t-c: capture packets for each test using tcpdump (default: no capture)"
55767659f6SFlorian Westphal	echo -e "\t-f: size of file to transfer in bytes (default random)"
568a4b910dSFlorian Westphal	echo -e "\t-S: set sndbuf value (default: use kernel default)"
578a4b910dSFlorian Westphal	echo -e "\t-R: set rcvbuf value (default: use kernel default)"
58048d19d4SFlorian Westphal	echo -e "\t-m: test mode (poll, sendfile; default: poll)"
59767659f6SFlorian Westphal	echo -e "\t-t: also run tests with TCP (use twice to non-fallback tcp)"
6094d66ba1SGeliang Tang	echo -e "\t-C: enable the MPTCP data checksum"
61048d19d4SFlorian Westphal}
62048d19d4SFlorian Westphal
63048d19d4SFlorian Westphalwhile getopts "$optstring" option;do
64048d19d4SFlorian Westphal	case "$option" in
65048d19d4SFlorian Westphal	"h")
66048d19d4SFlorian Westphal		usage $0
67048d19d4SFlorian Westphal		exit 0
68048d19d4SFlorian Westphal		;;
69048d19d4SFlorian Westphal	"d")
70048d19d4SFlorian Westphal		if [ $OPTARG -ge 0 ];then
71048d19d4SFlorian Westphal			tc_delay="$OPTARG"
72048d19d4SFlorian Westphal		else
73048d19d4SFlorian Westphal			echo "-d requires numeric argument, got \"$OPTARG\"" 1>&2
74048d19d4SFlorian Westphal			exit 1
75048d19d4SFlorian Westphal		fi
76048d19d4SFlorian Westphal		;;
77048d19d4SFlorian Westphal	"e")
78048d19d4SFlorian Westphal		ethtool_args="$ethtool_args $OPTARG off"
79048d19d4SFlorian Westphal		ethtool_random_on=false
80048d19d4SFlorian Westphal		;;
81048d19d4SFlorian Westphal	"l")
82048d19d4SFlorian Westphal		tc_loss="$OPTARG"
83048d19d4SFlorian Westphal		;;
84048d19d4SFlorian Westphal	"r")
85048d19d4SFlorian Westphal		tc_reorder="$OPTARG"
86048d19d4SFlorian Westphal		;;
87048d19d4SFlorian Westphal	"4")
88048d19d4SFlorian Westphal		ipv6=false
89048d19d4SFlorian Westphal		;;
90048d19d4SFlorian Westphal	"c")
91048d19d4SFlorian Westphal		capture=true
92048d19d4SFlorian Westphal		;;
938a4b910dSFlorian Westphal	"S")
94048d19d4SFlorian Westphal		if [ $OPTARG -ge 0 ];then
95048d19d4SFlorian Westphal			sndbuf="$OPTARG"
96048d19d4SFlorian Westphal		else
978a4b910dSFlorian Westphal			echo "-S requires numeric argument, got \"$OPTARG\"" 1>&2
988a4b910dSFlorian Westphal			exit 1
998a4b910dSFlorian Westphal		fi
1008a4b910dSFlorian Westphal		;;
1018a4b910dSFlorian Westphal	"R")
1028a4b910dSFlorian Westphal		if [ $OPTARG -ge 0 ];then
1038a4b910dSFlorian Westphal			rcvbuf="$OPTARG"
1048a4b910dSFlorian Westphal		else
1058a4b910dSFlorian Westphal			echo "-R requires numeric argument, got \"$OPTARG\"" 1>&2
106048d19d4SFlorian Westphal			exit 1
107048d19d4SFlorian Westphal		fi
108048d19d4SFlorian Westphal		;;
109048d19d4SFlorian Westphal	"m")
110048d19d4SFlorian Westphal		testmode="$OPTARG"
111048d19d4SFlorian Westphal		;;
112767659f6SFlorian Westphal	"f")
113767659f6SFlorian Westphal		filesize="$OPTARG"
114767659f6SFlorian Westphal		;;
115767659f6SFlorian Westphal	"t")
116767659f6SFlorian Westphal		do_tcp=$((do_tcp+1))
117767659f6SFlorian Westphal		;;
11894d66ba1SGeliang Tang	"C")
11994d66ba1SGeliang Tang		checksum=true
12094d66ba1SGeliang Tang		;;
121048d19d4SFlorian Westphal	"?")
122048d19d4SFlorian Westphal		usage $0
123048d19d4SFlorian Westphal		exit 1
124048d19d4SFlorian Westphal		;;
125048d19d4SFlorian Westphal	esac
126048d19d4SFlorian Westphaldone
127048d19d4SFlorian Westphal
128048d19d4SFlorian Westphalsec=$(date +%s)
129048d19d4SFlorian Westphalrndh=$(printf %x $sec)-$(mktemp -u XXXXXX)
130048d19d4SFlorian Westphalns1="ns1-$rndh"
131048d19d4SFlorian Westphalns2="ns2-$rndh"
132048d19d4SFlorian Westphalns3="ns3-$rndh"
133048d19d4SFlorian Westphalns4="ns4-$rndh"
134048d19d4SFlorian Westphal
135048d19d4SFlorian WestphalTEST_COUNT=0
136dd350f46SMatthieu BaertsTEST_GROUP=""
137048d19d4SFlorian Westphal
1385b5ff824SMatthieu Baerts (NGI0)# This function is used in the cleanup trap
1395b5ff824SMatthieu Baerts (NGI0)#shellcheck disable=SC2317
140048d19d4SFlorian Westphalcleanup()
141048d19d4SFlorian Westphal{
14205be5e27SPaolo Abeni	rm -f "$cin_disconnect" "$cout_disconnect"
143048d19d4SFlorian Westphal	rm -f "$cin" "$cout"
144048d19d4SFlorian Westphal	rm -f "$sin" "$sout"
145048d19d4SFlorian Westphal	rm -f "$capout"
146048d19d4SFlorian Westphal
147048d19d4SFlorian Westphal	local netns
148048d19d4SFlorian Westphal	for netns in "$ns1" "$ns2" "$ns3" "$ns4";do
149048d19d4SFlorian Westphal		ip netns del $netns
150767389c8SPaolo Abeni		rm -f /tmp/$netns.{nstat,out}
151048d19d4SFlorian Westphal	done
152048d19d4SFlorian Westphal}
153048d19d4SFlorian Westphal
154d83013bdSMatthieu Baertsmptcp_lib_check_mptcp
15507bf4940SMatthieu Baertsmptcp_lib_check_kallsyms
156d83013bdSMatthieu Baerts
157048d19d4SFlorian Westphalip -Version > /dev/null 2>&1
158048d19d4SFlorian Westphalif [ $? -ne 0 ];then
159048d19d4SFlorian Westphal	echo "SKIP: Could not run test without ip tool"
160048d19d4SFlorian Westphal	exit $ksft_skip
161048d19d4SFlorian Westphalfi
162048d19d4SFlorian Westphal
163048d19d4SFlorian Westphalsin=$(mktemp)
164048d19d4SFlorian Westphalsout=$(mktemp)
165048d19d4SFlorian Westphalcin=$(mktemp)
166048d19d4SFlorian Westphalcout=$(mktemp)
167048d19d4SFlorian Westphalcapout=$(mktemp)
16805be5e27SPaolo Abenicin_disconnect="$cin".disconnect
16905be5e27SPaolo Abenicout_disconnect="$cout".disconnect
170048d19d4SFlorian Westphaltrap cleanup EXIT
171048d19d4SFlorian Westphal
172048d19d4SFlorian Westphalfor i in "$ns1" "$ns2" "$ns3" "$ns4";do
173048d19d4SFlorian Westphal	ip netns add $i || exit $ksft_skip
174048d19d4SFlorian Westphal	ip -net $i link set lo up
175048d19d4SFlorian Westphaldone
176048d19d4SFlorian Westphal
177048d19d4SFlorian Westphal#  "$ns1"              ns2                    ns3                     ns4
178048d19d4SFlorian Westphal# ns1eth2    ns2eth1   ns2eth3      ns3eth2   ns3eth4       ns4eth3
179048d19d4SFlorian Westphal#                           - drop 1% ->            reorder 25%
180048d19d4SFlorian Westphal#                           <- TSO off -
181048d19d4SFlorian Westphal
182048d19d4SFlorian Westphalip link add ns1eth2 netns "$ns1" type veth peer name ns2eth1 netns "$ns2"
183048d19d4SFlorian Westphalip link add ns2eth3 netns "$ns2" type veth peer name ns3eth2 netns "$ns3"
184048d19d4SFlorian Westphalip link add ns3eth4 netns "$ns3" type veth peer name ns4eth3 netns "$ns4"
185048d19d4SFlorian Westphal
186048d19d4SFlorian Westphalip -net "$ns1" addr add 10.0.1.1/24 dev ns1eth2
187048d19d4SFlorian Westphalip -net "$ns1" addr add dead:beef:1::1/64 dev ns1eth2 nodad
188048d19d4SFlorian Westphal
189048d19d4SFlorian Westphalip -net "$ns1" link set ns1eth2 up
190048d19d4SFlorian Westphalip -net "$ns1" route add default via 10.0.1.2
191048d19d4SFlorian Westphalip -net "$ns1" route add default via dead:beef:1::2
192048d19d4SFlorian Westphal
193048d19d4SFlorian Westphalip -net "$ns2" addr add 10.0.1.2/24 dev ns2eth1
194048d19d4SFlorian Westphalip -net "$ns2" addr add dead:beef:1::2/64 dev ns2eth1 nodad
195048d19d4SFlorian Westphalip -net "$ns2" link set ns2eth1 up
196048d19d4SFlorian Westphal
197048d19d4SFlorian Westphalip -net "$ns2" addr add 10.0.2.1/24 dev ns2eth3
198048d19d4SFlorian Westphalip -net "$ns2" addr add dead:beef:2::1/64 dev ns2eth3 nodad
199048d19d4SFlorian Westphalip -net "$ns2" link set ns2eth3 up
200048d19d4SFlorian Westphalip -net "$ns2" route add default via 10.0.2.2
201048d19d4SFlorian Westphalip -net "$ns2" route add default via dead:beef:2::2
202048d19d4SFlorian Westphalip netns exec "$ns2" sysctl -q net.ipv4.ip_forward=1
203048d19d4SFlorian Westphalip netns exec "$ns2" sysctl -q net.ipv6.conf.all.forwarding=1
204048d19d4SFlorian Westphal
205048d19d4SFlorian Westphalip -net "$ns3" addr add 10.0.2.2/24 dev ns3eth2
206048d19d4SFlorian Westphalip -net "$ns3" addr add dead:beef:2::2/64 dev ns3eth2 nodad
207048d19d4SFlorian Westphalip -net "$ns3" link set ns3eth2 up
208048d19d4SFlorian Westphal
209048d19d4SFlorian Westphalip -net "$ns3" addr add 10.0.3.2/24 dev ns3eth4
210048d19d4SFlorian Westphalip -net "$ns3" addr add dead:beef:3::2/64 dev ns3eth4 nodad
211048d19d4SFlorian Westphalip -net "$ns3" link set ns3eth4 up
212048d19d4SFlorian Westphalip -net "$ns3" route add default via 10.0.2.1
213048d19d4SFlorian Westphalip -net "$ns3" route add default via dead:beef:2::1
214048d19d4SFlorian Westphalip netns exec "$ns3" sysctl -q net.ipv4.ip_forward=1
215048d19d4SFlorian Westphalip netns exec "$ns3" sysctl -q net.ipv6.conf.all.forwarding=1
216048d19d4SFlorian Westphal
217048d19d4SFlorian Westphalip -net "$ns4" addr add 10.0.3.1/24 dev ns4eth3
218048d19d4SFlorian Westphalip -net "$ns4" addr add dead:beef:3::1/64 dev ns4eth3 nodad
219048d19d4SFlorian Westphalip -net "$ns4" link set ns4eth3 up
220048d19d4SFlorian Westphalip -net "$ns4" route add default via 10.0.3.2
221048d19d4SFlorian Westphalip -net "$ns4" route add default via dead:beef:3::2
222048d19d4SFlorian Westphal
22394d66ba1SGeliang Tangif $checksum; then
22494d66ba1SGeliang Tang	for i in "$ns1" "$ns2" "$ns3" "$ns4";do
22594d66ba1SGeliang Tang		ip netns exec $i sysctl -q net.mptcp.checksum_enabled=1
22694d66ba1SGeliang Tang	done
22794d66ba1SGeliang Tangfi
22894d66ba1SGeliang Tang
229048d19d4SFlorian Westphalset_ethtool_flags() {
230048d19d4SFlorian Westphal	local ns="$1"
231048d19d4SFlorian Westphal	local dev="$2"
232048d19d4SFlorian Westphal	local flags="$3"
233048d19d4SFlorian Westphal
2345b5ff824SMatthieu Baerts (NGI0)	if ip netns exec $ns ethtool -K $dev $flags 2>/dev/null; then
2355b5ff824SMatthieu Baerts (NGI0)		echo "INFO: set $ns dev $dev: ethtool -K $flags"
2365b5ff824SMatthieu Baerts (NGI0)	fi
237048d19d4SFlorian Westphal}
238048d19d4SFlorian Westphal
239048d19d4SFlorian Westphalset_random_ethtool_flags() {
240048d19d4SFlorian Westphal	local flags=""
241048d19d4SFlorian Westphal	local r=$RANDOM
242048d19d4SFlorian Westphal
243048d19d4SFlorian Westphal	local pick1=$((r & 1))
244048d19d4SFlorian Westphal	local pick2=$((r & 2))
245048d19d4SFlorian Westphal	local pick3=$((r & 4))
246048d19d4SFlorian Westphal
247048d19d4SFlorian Westphal	[ $pick1 -ne 0 ] && flags="tso off"
248048d19d4SFlorian Westphal	[ $pick2 -ne 0 ] && flags="$flags gso off"
249048d19d4SFlorian Westphal	[ $pick3 -ne 0 ] && flags="$flags gro off"
250048d19d4SFlorian Westphal
251048d19d4SFlorian Westphal	[ -z "$flags" ] && return
252048d19d4SFlorian Westphal
253048d19d4SFlorian Westphal	set_ethtool_flags "$1" "$2" "$flags"
254048d19d4SFlorian Westphal}
255048d19d4SFlorian Westphal
256048d19d4SFlorian Westphalif $ethtool_random_on;then
257048d19d4SFlorian Westphal	set_random_ethtool_flags "$ns3" ns3eth2
258048d19d4SFlorian Westphal	set_random_ethtool_flags "$ns4" ns4eth3
259048d19d4SFlorian Westphalelse
260048d19d4SFlorian Westphal	set_ethtool_flags "$ns3" ns3eth2 "$ethtool_args"
261048d19d4SFlorian Westphal	set_ethtool_flags "$ns4" ns4eth3 "$ethtool_args"
262048d19d4SFlorian Westphalfi
263048d19d4SFlorian Westphal
264048d19d4SFlorian Westphalprint_file_err()
265048d19d4SFlorian Westphal{
266048d19d4SFlorian Westphal	ls -l "$1" 1>&2
267048d19d4SFlorian Westphal	echo "Trailing bytes are: "
268048d19d4SFlorian Westphal	tail -c 27 "$1"
269048d19d4SFlorian Westphal}
270048d19d4SFlorian Westphal
271048d19d4SFlorian Westphalcheck_transfer()
272048d19d4SFlorian Westphal{
273048d19d4SFlorian Westphal	local in=$1
274048d19d4SFlorian Westphal	local out=$2
275048d19d4SFlorian Westphal	local what=$3
276048d19d4SFlorian Westphal
277048d19d4SFlorian Westphal	cmp "$in" "$out" > /dev/null 2>&1
278048d19d4SFlorian Westphal	if [ $? -ne 0 ] ;then
279048d19d4SFlorian Westphal		echo "[ FAIL ] $what does not match (in, out):"
280048d19d4SFlorian Westphal		print_file_err "$in"
281048d19d4SFlorian Westphal		print_file_err "$out"
282048d19d4SFlorian Westphal
283048d19d4SFlorian Westphal		return 1
284048d19d4SFlorian Westphal	fi
285048d19d4SFlorian Westphal
286048d19d4SFlorian Westphal	return 0
287048d19d4SFlorian Westphal}
288048d19d4SFlorian Westphal
289048d19d4SFlorian Westphalcheck_mptcp_disabled()
290048d19d4SFlorian Westphal{
291787eb1e4SMatthieu Baerts	local disabled_ns="ns_disabled-$rndh"
292048d19d4SFlorian Westphal	ip netns add ${disabled_ns} || exit $ksft_skip
293048d19d4SFlorian Westphal
294048d19d4SFlorian Westphal	# net.mptcp.enabled should be enabled by default
295048d19d4SFlorian Westphal	if [ "$(ip netns exec ${disabled_ns} sysctl net.mptcp.enabled | awk '{ print $3 }')" -ne 1 ]; then
296048d19d4SFlorian Westphal		echo -e "net.mptcp.enabled sysctl is not 1 by default\t\t[ FAIL ]"
297dd350f46SMatthieu Baerts		mptcp_lib_result_fail "net.mptcp.enabled sysctl is not 1 by default"
298048d19d4SFlorian Westphal		ret=1
299048d19d4SFlorian Westphal		return 1
300048d19d4SFlorian Westphal	fi
301048d19d4SFlorian Westphal	ip netns exec ${disabled_ns} sysctl -q net.mptcp.enabled=0
302048d19d4SFlorian Westphal
303048d19d4SFlorian Westphal	local err=0
30477a88274SMasahiro Yamada	LC_ALL=C ip netns exec ${disabled_ns} ./mptcp_connect -p 10000 -s MPTCP 127.0.0.1 < "$cin" 2>&1 | \
305048d19d4SFlorian Westphal		grep -q "^socket: Protocol not available$" && err=1
306048d19d4SFlorian Westphal	ip netns delete ${disabled_ns}
307048d19d4SFlorian Westphal
308048d19d4SFlorian Westphal	if [ ${err} -eq 0 ]; then
309048d19d4SFlorian Westphal		echo -e "New MPTCP socket cannot be blocked via sysctl\t\t[ FAIL ]"
310dd350f46SMatthieu Baerts		mptcp_lib_result_fail "New MPTCP socket cannot be blocked via sysctl"
311048d19d4SFlorian Westphal		ret=1
312048d19d4SFlorian Westphal		return 1
313048d19d4SFlorian Westphal	fi
314048d19d4SFlorian Westphal
315048d19d4SFlorian Westphal	echo -e "New MPTCP socket can be blocked via sysctl\t\t[ OK ]"
316dd350f46SMatthieu Baerts	mptcp_lib_result_pass "New MPTCP socket can be blocked via sysctl"
317048d19d4SFlorian Westphal	return 0
318048d19d4SFlorian Westphal}
319048d19d4SFlorian Westphal
320048d19d4SFlorian Westphaldo_ping()
321048d19d4SFlorian Westphal{
322048d19d4SFlorian Westphal	local listener_ns="$1"
323048d19d4SFlorian Westphal	local connector_ns="$2"
324048d19d4SFlorian Westphal	local connect_addr="$3"
325048d19d4SFlorian Westphal	local ping_args="-q -c 1"
326dd350f46SMatthieu Baerts	local rc=0
327048d19d4SFlorian Westphal
3288e7f31bfSGeliang Tang	if mptcp_lib_is_v6 "${connect_addr}"; then
329048d19d4SFlorian Westphal		$ipv6 || return 0
330048d19d4SFlorian Westphal		ping_args="${ping_args} -6"
331048d19d4SFlorian Westphal	fi
332048d19d4SFlorian Westphal
333dd350f46SMatthieu Baerts	ip netns exec ${connector_ns} ping ${ping_args} $connect_addr >/dev/null || rc=1
334dd350f46SMatthieu Baerts
335dd350f46SMatthieu Baerts	if [ $rc -ne 0 ] ; then
336048d19d4SFlorian Westphal		echo "$listener_ns -> $connect_addr connectivity [ FAIL ]" 1>&2
337048d19d4SFlorian Westphal		ret=1
338048d19d4SFlorian Westphal
339048d19d4SFlorian Westphal		return 1
340048d19d4SFlorian Westphal	fi
341048d19d4SFlorian Westphal
342048d19d4SFlorian Westphal	return 0
343048d19d4SFlorian Westphal}
344048d19d4SFlorian Westphal
345048d19d4SFlorian Westphal# $1: ns, $2: port
346048d19d4SFlorian Westphalwait_local_port_listen()
347048d19d4SFlorian Westphal{
348048d19d4SFlorian Westphal	local listener_ns="${1}"
349048d19d4SFlorian Westphal	local port="${2}"
350048d19d4SFlorian Westphal
351048d19d4SFlorian Westphal	local port_hex i
352048d19d4SFlorian Westphal
353048d19d4SFlorian Westphal	port_hex="$(printf "%04X" "${port}")"
354048d19d4SFlorian Westphal	for i in $(seq 10); do
355048d19d4SFlorian Westphal		ip netns exec "${listener_ns}" cat /proc/net/tcp* | \
356048d19d4SFlorian Westphal			awk "BEGIN {rc=1} {if (\$2 ~ /:${port_hex}\$/ && \$4 ~ /0A/) {rc=0; exit}} END {exit rc}" &&
357048d19d4SFlorian Westphal			break
358048d19d4SFlorian Westphal		sleep 0.1
359048d19d4SFlorian Westphal	done
360048d19d4SFlorian Westphal}
361048d19d4SFlorian Westphal
362048d19d4SFlorian Westphaldo_transfer()
363048d19d4SFlorian Westphal{
364048d19d4SFlorian Westphal	local listener_ns="$1"
365048d19d4SFlorian Westphal	local connector_ns="$2"
366048d19d4SFlorian Westphal	local cl_proto="$3"
367048d19d4SFlorian Westphal	local srv_proto="$4"
368048d19d4SFlorian Westphal	local connect_addr="$5"
369048d19d4SFlorian Westphal	local local_addr="$6"
370df8aee6dSYonglong Li	local extra_args="$7"
371048d19d4SFlorian Westphal
372048d19d4SFlorian Westphal	local port
3735b5ff824SMatthieu Baerts (NGI0)	port=$((10000+TEST_COUNT))
374048d19d4SFlorian Westphal	TEST_COUNT=$((TEST_COUNT+1))
375048d19d4SFlorian Westphal
3768a4b910dSFlorian Westphal	if [ "$rcvbuf" -gt 0 ]; then
377*732752baSGeliang Tang		extra_args+=" -R $rcvbuf"
3788a4b910dSFlorian Westphal	fi
3798a4b910dSFlorian Westphal
380048d19d4SFlorian Westphal	if [ "$sndbuf" -gt 0 ]; then
381*732752baSGeliang Tang		extra_args+=" -S $sndbuf"
382048d19d4SFlorian Westphal	fi
383048d19d4SFlorian Westphal
384048d19d4SFlorian Westphal	if [ -n "$testmode" ]; then
385*732752baSGeliang Tang		extra_args+=" -m $testmode"
386048d19d4SFlorian Westphal	fi
387048d19d4SFlorian Westphal
388048d19d4SFlorian Westphal	if [ -n "$extra_args" ] && $options_log; then
389048d19d4SFlorian Westphal		echo "INFO: extra options: $extra_args"
390048d19d4SFlorian Westphal	fi
391df8aee6dSYonglong Li	options_log=false
392048d19d4SFlorian Westphal
393048d19d4SFlorian Westphal	:> "$cout"
394048d19d4SFlorian Westphal	:> "$sout"
395048d19d4SFlorian Westphal	:> "$capout"
396048d19d4SFlorian Westphal
397048d19d4SFlorian Westphal	local addr_port
398048d19d4SFlorian Westphal	addr_port=$(printf "%s:%d" ${connect_addr} ${port})
399dd350f46SMatthieu Baerts	local result_msg
400dd350f46SMatthieu Baerts	result_msg="$(printf "%.3s %-5s -> %.3s (%-20s) %-5s" ${connector_ns} ${cl_proto} ${listener_ns} ${addr_port} ${srv_proto})"
401dd350f46SMatthieu Baerts	printf "%s\t" "${result_msg}"
402048d19d4SFlorian Westphal
403048d19d4SFlorian Westphal	if $capture; then
404048d19d4SFlorian Westphal		local capuser
405048d19d4SFlorian Westphal		if [ -z $SUDO_USER ] ; then
406048d19d4SFlorian Westphal			capuser=""
407048d19d4SFlorian Westphal		else
408048d19d4SFlorian Westphal			capuser="-Z $SUDO_USER"
409048d19d4SFlorian Westphal		fi
410048d19d4SFlorian Westphal
4110b8241feSMatthieu Baerts		local capfile="${rndh}-${connector_ns:0:3}-${listener_ns:0:3}-${cl_proto}-${srv_proto}-${connect_addr}-${port}"
4120b8241feSMatthieu Baerts		local capopt="-i any -s 65535 -B 32768 ${capuser}"
413048d19d4SFlorian Westphal
4140b8241feSMatthieu Baerts		ip netns exec ${listener_ns}  tcpdump ${capopt} -w "${capfile}-listener.pcap"  >> "${capout}" 2>&1 &
4150b8241feSMatthieu Baerts		local cappid_listener=$!
4160b8241feSMatthieu Baerts
4170b8241feSMatthieu Baerts		ip netns exec ${connector_ns} tcpdump ${capopt} -w "${capfile}-connector.pcap" >> "${capout}" 2>&1 &
4180b8241feSMatthieu Baerts		local cappid_connector=$!
419048d19d4SFlorian Westphal
420048d19d4SFlorian Westphal		sleep 1
421048d19d4SFlorian Westphal	fi
422048d19d4SFlorian Westphal
42376e5e27cSMatthieu Baerts	NSTAT_HISTORY=/tmp/${listener_ns}.nstat ip netns exec ${listener_ns} \
42476e5e27cSMatthieu Baerts		nstat -n
42576e5e27cSMatthieu Baerts	if [ ${listener_ns} != ${connector_ns} ]; then
42676e5e27cSMatthieu Baerts		NSTAT_HISTORY=/tmp/${connector_ns}.nstat ip netns exec ${connector_ns} \
42776e5e27cSMatthieu Baerts			nstat -n
42876e5e27cSMatthieu Baerts	fi
42976e5e27cSMatthieu Baerts
4305b5ff824SMatthieu Baerts (NGI0)	local stat_synrx_last_l
4315b5ff824SMatthieu Baerts (NGI0)	local stat_ackrx_last_l
4325b5ff824SMatthieu Baerts (NGI0)	local stat_cookietx_last
4335b5ff824SMatthieu Baerts (NGI0)	local stat_cookierx_last
4345b5ff824SMatthieu Baerts (NGI0)	local stat_csum_err_s
4355b5ff824SMatthieu Baerts (NGI0)	local stat_csum_err_c
43643eca11bSDavide Caratti	local stat_tcpfb_last_l
4375b5ff824SMatthieu Baerts (NGI0)	stat_synrx_last_l=$(mptcp_lib_get_counter "${listener_ns}" "MPTcpExtMPCapableSYNRX")
4385b5ff824SMatthieu Baerts (NGI0)	stat_ackrx_last_l=$(mptcp_lib_get_counter "${listener_ns}" "MPTcpExtMPCapableACKRX")
4395b5ff824SMatthieu Baerts (NGI0)	stat_cookietx_last=$(mptcp_lib_get_counter "${listener_ns}" "TcpExtSyncookiesSent")
4405b5ff824SMatthieu Baerts (NGI0)	stat_cookierx_last=$(mptcp_lib_get_counter "${listener_ns}" "TcpExtSyncookiesRecv")
4415b5ff824SMatthieu Baerts (NGI0)	stat_csum_err_s=$(mptcp_lib_get_counter "${listener_ns}" "MPTcpExtDataCsumErr")
4425b5ff824SMatthieu Baerts (NGI0)	stat_csum_err_c=$(mptcp_lib_get_counter "${connector_ns}" "MPTcpExtDataCsumErr")
44343eca11bSDavide Caratti	stat_tcpfb_last_l=$(mptcp_lib_get_counter "${listener_ns}" "MPTcpExtMPCapableFallbackACK")
444fed61c4bSFlorian Westphal
4455888a61cSMatthieu Baerts	timeout ${timeout_test} \
4465888a61cSMatthieu Baerts		ip netns exec ${listener_ns} \
4475888a61cSMatthieu Baerts			./mptcp_connect -t ${timeout_poll} -l -p $port -s ${srv_proto} \
4485888a61cSMatthieu Baerts				$extra_args $local_addr < "$sin" > "$sout" &
449048d19d4SFlorian Westphal	local spid=$!
450048d19d4SFlorian Westphal
451048d19d4SFlorian Westphal	wait_local_port_listen "${listener_ns}" "${port}"
452048d19d4SFlorian Westphal
453048d19d4SFlorian Westphal	local start
454048d19d4SFlorian Westphal	start=$(date +%s%3N)
4555888a61cSMatthieu Baerts	timeout ${timeout_test} \
4565888a61cSMatthieu Baerts		ip netns exec ${connector_ns} \
4575888a61cSMatthieu Baerts			./mptcp_connect -t ${timeout_poll} -p $port -s ${cl_proto} \
4585888a61cSMatthieu Baerts				$extra_args $connect_addr < "$cin" > "$cout" &
459048d19d4SFlorian Westphal	local cpid=$!
460048d19d4SFlorian Westphal
461048d19d4SFlorian Westphal	wait $cpid
462048d19d4SFlorian Westphal	local retc=$?
463048d19d4SFlorian Westphal	wait $spid
464048d19d4SFlorian Westphal	local rets=$?
465048d19d4SFlorian Westphal
466048d19d4SFlorian Westphal	local stop
467048d19d4SFlorian Westphal	stop=$(date +%s%3N)
468048d19d4SFlorian Westphal
469048d19d4SFlorian Westphal	if $capture; then
470048d19d4SFlorian Westphal		sleep 1
4710b8241feSMatthieu Baerts		kill ${cappid_listener}
4720b8241feSMatthieu Baerts		kill ${cappid_connector}
473048d19d4SFlorian Westphal	fi
474048d19d4SFlorian Westphal
475767389c8SPaolo Abeni	NSTAT_HISTORY=/tmp/${listener_ns}.nstat ip netns exec ${listener_ns} \
476767389c8SPaolo Abeni		nstat | grep Tcp > /tmp/${listener_ns}.out
477767389c8SPaolo Abeni	if [ ${listener_ns} != ${connector_ns} ]; then
478767389c8SPaolo Abeni		NSTAT_HISTORY=/tmp/${connector_ns}.nstat ip netns exec ${connector_ns} \
479767389c8SPaolo Abeni			nstat | grep Tcp > /tmp/${connector_ns}.out
480767389c8SPaolo Abeni	fi
481767389c8SPaolo Abeni
482048d19d4SFlorian Westphal	local duration
483048d19d4SFlorian Westphal	duration=$((stop-start))
484dd350f46SMatthieu Baerts	result_msg+=" # time=${duration}ms"
48545759a87SMatthieu Baerts	printf "(duration %05sms) " "${duration}"
486048d19d4SFlorian Westphal	if [ ${rets} -ne 0 ] || [ ${retc} -ne 0 ]; then
48745759a87SMatthieu Baerts		echo "[ FAIL ] client exit code $retc, server $rets" 1>&2
4888b974778SMatthieu Baerts		echo -e "\nnetns ${listener_ns} socket stat for ${port}:" 1>&2
489767389c8SPaolo Abeni		ip netns exec ${listener_ns} ss -Menita 1>&2 -o "sport = :$port"
490767389c8SPaolo Abeni		cat /tmp/${listener_ns}.out
4918b974778SMatthieu Baerts		echo -e "\nnetns ${connector_ns} socket stat for ${port}:" 1>&2
492767389c8SPaolo Abeni		ip netns exec ${connector_ns} ss -Menita 1>&2 -o "dport = :$port"
493767389c8SPaolo Abeni		[ ${listener_ns} != ${connector_ns} ] && cat /tmp/${connector_ns}.out
49445759a87SMatthieu Baerts
49545759a87SMatthieu Baerts		echo
496048d19d4SFlorian Westphal		cat "$capout"
497dd350f46SMatthieu Baerts		mptcp_lib_result_fail "${TEST_GROUP}: ${result_msg}"
498048d19d4SFlorian Westphal		return 1
499048d19d4SFlorian Westphal	fi
500048d19d4SFlorian Westphal
501048d19d4SFlorian Westphal	check_transfer $sin $cout "file received by client"
502048d19d4SFlorian Westphal	retc=$?
503048d19d4SFlorian Westphal	check_transfer $cin $sout "file received by server"
504048d19d4SFlorian Westphal	rets=$?
505048d19d4SFlorian Westphal
506*732752baSGeliang Tang	local extra=""
5075b5ff824SMatthieu Baerts (NGI0)	local stat_synrx_now_l
5085b5ff824SMatthieu Baerts (NGI0)	local stat_ackrx_now_l
5095b5ff824SMatthieu Baerts (NGI0)	local stat_cookietx_now
5105b5ff824SMatthieu Baerts (NGI0)	local stat_cookierx_now
5115b5ff824SMatthieu Baerts (NGI0)	local stat_ooo_now
51243eca11bSDavide Caratti	local stat_tcpfb_now_l
5135b5ff824SMatthieu Baerts (NGI0)	stat_synrx_now_l=$(mptcp_lib_get_counter "${listener_ns}" "MPTcpExtMPCapableSYNRX")
5145b5ff824SMatthieu Baerts (NGI0)	stat_ackrx_now_l=$(mptcp_lib_get_counter "${listener_ns}" "MPTcpExtMPCapableACKRX")
5155b5ff824SMatthieu Baerts (NGI0)	stat_cookietx_now=$(mptcp_lib_get_counter "${listener_ns}" "TcpExtSyncookiesSent")
5165b5ff824SMatthieu Baerts (NGI0)	stat_cookierx_now=$(mptcp_lib_get_counter "${listener_ns}" "TcpExtSyncookiesRecv")
5175b5ff824SMatthieu Baerts (NGI0)	stat_ooo_now=$(mptcp_lib_get_counter "${listener_ns}" "TcpExtTCPOFOQueue")
51843eca11bSDavide Caratti	stat_tcpfb_now_l=$(mptcp_lib_get_counter "${listener_ns}" "MPTcpExtMPCapableFallbackACK")
519fed61c4bSFlorian Westphal
520fed61c4bSFlorian Westphal	expect_synrx=$((stat_synrx_last_l))
521fed61c4bSFlorian Westphal	expect_ackrx=$((stat_ackrx_last_l))
522fed61c4bSFlorian Westphal
523fed61c4bSFlorian Westphal	cookies=$(ip netns exec ${listener_ns} sysctl net.ipv4.tcp_syncookies)
524fed61c4bSFlorian Westphal	cookies=${cookies##*=}
525fed61c4bSFlorian Westphal
526fed61c4bSFlorian Westphal	if [ ${cl_proto} = "MPTCP" ] && [ ${srv_proto} = "MPTCP" ]; then
5275b5ff824SMatthieu Baerts (NGI0)		expect_synrx=$((stat_synrx_last_l+connect_per_transfer))
5285b5ff824SMatthieu Baerts (NGI0)		expect_ackrx=$((stat_ackrx_last_l+connect_per_transfer))
529fed61c4bSFlorian Westphal	fi
5305f88117fSMatthieu Baerts
5315f88117fSMatthieu Baerts	if [ ${stat_synrx_now_l} -lt ${expect_synrx} ]; then
5325f88117fSMatthieu Baerts		printf "[ FAIL ] lower MPC SYN rx (%d) than expected (%d)\n" \
5335f88117fSMatthieu Baerts			"${stat_synrx_now_l}" "${expect_synrx}" 1>&2
5345f88117fSMatthieu Baerts		retc=1
5355f88117fSMatthieu Baerts	fi
5365b5ff824SMatthieu Baerts (NGI0)	if [ ${stat_ackrx_now_l} -lt ${expect_ackrx} ] && [ ${stat_ooo_now} -eq 0 ]; then
53769ca3d29SPaolo Abeni		if [ ${stat_ooo_now} -eq 0 ]; then
5385f88117fSMatthieu Baerts			printf "[ FAIL ] lower MPC ACK rx (%d) than expected (%d)\n" \
5395f88117fSMatthieu Baerts				"${stat_ackrx_now_l}" "${expect_ackrx}" 1>&2
5405f88117fSMatthieu Baerts			rets=1
54169ca3d29SPaolo Abeni		else
542*732752baSGeliang Tang			extra+=" [ Note ] fallback due to TCP OoO"
54369ca3d29SPaolo Abeni		fi
5445f88117fSMatthieu Baerts	fi
5455f88117fSMatthieu Baerts
54624720d74SGeliang Tang	if $checksum; then
5475b5ff824SMatthieu Baerts (NGI0)		local csum_err_s
5485b5ff824SMatthieu Baerts (NGI0)		local csum_err_c
5495b5ff824SMatthieu Baerts (NGI0)		csum_err_s=$(mptcp_lib_get_counter "${listener_ns}" "MPTcpExtDataCsumErr")
5505b5ff824SMatthieu Baerts (NGI0)		csum_err_c=$(mptcp_lib_get_counter "${connector_ns}" "MPTcpExtDataCsumErr")
55124720d74SGeliang Tang
55224720d74SGeliang Tang		local csum_err_s_nr=$((csum_err_s - stat_csum_err_s))
55324720d74SGeliang Tang		if [ $csum_err_s_nr -gt 0 ]; then
5545b5ff824SMatthieu Baerts (NGI0)			printf "[ FAIL ]\nserver got %d data checksum error[s]" ${csum_err_s_nr}
55524720d74SGeliang Tang			rets=1
55624720d74SGeliang Tang		fi
55724720d74SGeliang Tang
55824720d74SGeliang Tang		local csum_err_c_nr=$((csum_err_c - stat_csum_err_c))
55924720d74SGeliang Tang		if [ $csum_err_c_nr -gt 0 ]; then
5605b5ff824SMatthieu Baerts (NGI0)			printf "[ FAIL ]\nclient got %d data checksum error[s]" ${csum_err_c_nr}
56124720d74SGeliang Tang			retc=1
56224720d74SGeliang Tang		fi
56324720d74SGeliang Tang	fi
56424720d74SGeliang Tang
56543eca11bSDavide Caratti	if [ ${stat_ooo_now} -eq 0 ] && [ ${stat_tcpfb_last_l} -ne ${stat_tcpfb_now_l} ]; then
56643eca11bSDavide Caratti		mptcp_lib_pr_fail "unexpected fallback to TCP"
56743eca11bSDavide Caratti		rets=1
56843eca11bSDavide Caratti	fi
56943eca11bSDavide Caratti
570fed61c4bSFlorian Westphal	if [ $cookies -eq 2 ];then
571fed61c4bSFlorian Westphal		if [ $stat_cookietx_last -ge $stat_cookietx_now ] ;then
572*732752baSGeliang Tang			extra+=" WARN: CookieSent: did not advance"
573fed61c4bSFlorian Westphal		fi
574fed61c4bSFlorian Westphal		if [ $stat_cookierx_last -ge $stat_cookierx_now ] ;then
575*732752baSGeliang Tang			extra+=" WARN: CookieRecv: did not advance"
576fed61c4bSFlorian Westphal		fi
577fed61c4bSFlorian Westphal	else
578fed61c4bSFlorian Westphal		if [ $stat_cookietx_last -ne $stat_cookietx_now ] ;then
579*732752baSGeliang Tang			extra+=" WARN: CookieSent: changed"
580fed61c4bSFlorian Westphal		fi
581fed61c4bSFlorian Westphal		if [ $stat_cookierx_last -ne $stat_cookierx_now ] ;then
582*732752baSGeliang Tang			extra+=" WARN: CookieRecv: changed"
583fed61c4bSFlorian Westphal		fi
584fed61c4bSFlorian Westphal	fi
585fed61c4bSFlorian Westphal
5865f88117fSMatthieu Baerts	if [ ${stat_synrx_now_l} -gt ${expect_synrx} ]; then
587*732752baSGeliang Tang		extra+=" WARN: SYNRX: expect ${expect_synrx},"
588*732752baSGeliang Tang		extra+=" got ${stat_synrx_now_l} (probably retransmissions)"
589fed61c4bSFlorian Westphal	fi
5905f88117fSMatthieu Baerts	if [ ${stat_ackrx_now_l} -gt ${expect_ackrx} ]; then
591*732752baSGeliang Tang		extra+=" WARN: ACKRX: expect ${expect_ackrx},"
592*732752baSGeliang Tang		extra+=" got ${stat_ackrx_now_l} (probably retransmissions)"
593fed61c4bSFlorian Westphal	fi
594fed61c4bSFlorian Westphal
595*732752baSGeliang Tang	if [ $retc -eq 0 ] && [ $rets -eq 0 ]; then
596*732752baSGeliang Tang		printf "[ OK ]%s\n" "${extra}"
597*732752baSGeliang Tang		mptcp_lib_result_pass "${TEST_GROUP}: ${result_msg}"
598*732752baSGeliang Tang	else
599*732752baSGeliang Tang		if [ -n "${extra}" ]; then
600*732752baSGeliang Tang			printf "%s\n" "${extra:1}"
601*732752baSGeliang Tang		fi
602*732752baSGeliang Tang		mptcp_lib_result_fail "${TEST_GROUP}: ${result_msg}"
603*732752baSGeliang Tang	fi
604*732752baSGeliang Tang
605048d19d4SFlorian Westphal	cat "$capout"
60645759a87SMatthieu Baerts	[ $retc -eq 0 ] && [ $rets -eq 0 ]
607048d19d4SFlorian Westphal}
608048d19d4SFlorian Westphal
609048d19d4SFlorian Westphalmake_file()
610048d19d4SFlorian Westphal{
611048d19d4SFlorian Westphal	local name=$1
612048d19d4SFlorian Westphal	local who=$2
613767659f6SFlorian Westphal	local SIZE=$filesize
614767659f6SFlorian Westphal	local ksize
615767659f6SFlorian Westphal	local rem
616048d19d4SFlorian Westphal
617767659f6SFlorian Westphal	if [ $SIZE -eq 0 ]; then
618767659f6SFlorian Westphal		local MAXSIZE=$((1024 * 1024 * 8))
619767659f6SFlorian Westphal		local MINSIZE=$((1024 * 256))
620048d19d4SFlorian Westphal
621767659f6SFlorian Westphal		SIZE=$(((RANDOM * RANDOM + MINSIZE) % MAXSIZE))
622767659f6SFlorian Westphal	fi
623048d19d4SFlorian Westphal
624767659f6SFlorian Westphal	ksize=$((SIZE / 1024))
625767659f6SFlorian Westphal	rem=$((SIZE - (ksize * 1024)))
626767659f6SFlorian Westphal
627767659f6SFlorian Westphal	dd if=/dev/urandom of="$name" bs=1024 count=$ksize 2> /dev/null
628767659f6SFlorian Westphal	dd if=/dev/urandom conv=notrunc of="$name" bs=1 count=$rem 2> /dev/null
629048d19d4SFlorian Westphal	echo -e "\nMPTCP_TEST_FILE_END_MARKER" >> "$name"
630048d19d4SFlorian Westphal
631767659f6SFlorian Westphal	echo "Created $name (size $(du -b "$name")) containing data sent by $who"
632048d19d4SFlorian Westphal}
633048d19d4SFlorian Westphal
634048d19d4SFlorian Westphalrun_tests_lo()
635048d19d4SFlorian Westphal{
636048d19d4SFlorian Westphal	local listener_ns="$1"
637048d19d4SFlorian Westphal	local connector_ns="$2"
638048d19d4SFlorian Westphal	local connect_addr="$3"
639048d19d4SFlorian Westphal	local loopback="$4"
640df8aee6dSYonglong Li	local extra_args="$5"
641048d19d4SFlorian Westphal	local lret=0
642048d19d4SFlorian Westphal
643048d19d4SFlorian Westphal	# skip if test programs are running inside same netns for subsequent runs.
644048d19d4SFlorian Westphal	if [ $loopback -eq 0 ] && [ ${listener_ns} = ${connector_ns} ]; then
645048d19d4SFlorian Westphal		return 0
646048d19d4SFlorian Westphal	fi
647048d19d4SFlorian Westphal
648048d19d4SFlorian Westphal	# skip if we don't want v6
6498e7f31bfSGeliang Tang	if ! $ipv6 && mptcp_lib_is_v6 "${connect_addr}"; then
650048d19d4SFlorian Westphal		return 0
651048d19d4SFlorian Westphal	fi
652048d19d4SFlorian Westphal
653048d19d4SFlorian Westphal	local local_addr
6548e7f31bfSGeliang Tang	if mptcp_lib_is_v6 "${connect_addr}"; then
655048d19d4SFlorian Westphal		local_addr="::"
656048d19d4SFlorian Westphal	else
657048d19d4SFlorian Westphal		local_addr="0.0.0.0"
658048d19d4SFlorian Westphal	fi
659048d19d4SFlorian Westphal
660df8aee6dSYonglong Li	do_transfer ${listener_ns} ${connector_ns} MPTCP MPTCP \
661df8aee6dSYonglong Li		    ${connect_addr} ${local_addr} "${extra_args}"
662048d19d4SFlorian Westphal	lret=$?
663048d19d4SFlorian Westphal	if [ $lret -ne 0 ]; then
664048d19d4SFlorian Westphal		ret=$lret
665048d19d4SFlorian Westphal		return 1
666048d19d4SFlorian Westphal	fi
667048d19d4SFlorian Westphal
668767659f6SFlorian Westphal	if [ $do_tcp -eq 0 ]; then
669048d19d4SFlorian Westphal		# don't bother testing fallback tcp except for loopback case.
670048d19d4SFlorian Westphal		if [ ${listener_ns} != ${connector_ns} ]; then
671048d19d4SFlorian Westphal			return 0
672048d19d4SFlorian Westphal		fi
673767659f6SFlorian Westphal	fi
674048d19d4SFlorian Westphal
675df8aee6dSYonglong Li	do_transfer ${listener_ns} ${connector_ns} MPTCP TCP \
676df8aee6dSYonglong Li		    ${connect_addr} ${local_addr} "${extra_args}"
677048d19d4SFlorian Westphal	lret=$?
678048d19d4SFlorian Westphal	if [ $lret -ne 0 ]; then
679048d19d4SFlorian Westphal		ret=$lret
680048d19d4SFlorian Westphal		return 1
681048d19d4SFlorian Westphal	fi
682048d19d4SFlorian Westphal
683df8aee6dSYonglong Li	do_transfer ${listener_ns} ${connector_ns} TCP MPTCP \
684df8aee6dSYonglong Li		    ${connect_addr} ${local_addr} "${extra_args}"
685048d19d4SFlorian Westphal	lret=$?
686048d19d4SFlorian Westphal	if [ $lret -ne 0 ]; then
687048d19d4SFlorian Westphal		ret=$lret
688048d19d4SFlorian Westphal		return 1
689048d19d4SFlorian Westphal	fi
690048d19d4SFlorian Westphal
691767659f6SFlorian Westphal	if [ $do_tcp -gt 1 ] ;then
692df8aee6dSYonglong Li		do_transfer ${listener_ns} ${connector_ns} TCP TCP \
693df8aee6dSYonglong Li			    ${connect_addr} ${local_addr} "${extra_args}"
694767659f6SFlorian Westphal		lret=$?
695767659f6SFlorian Westphal		if [ $lret -ne 0 ]; then
696767659f6SFlorian Westphal			ret=$lret
697767659f6SFlorian Westphal			return 1
698767659f6SFlorian Westphal		fi
699767659f6SFlorian Westphal	fi
700767659f6SFlorian Westphal
701048d19d4SFlorian Westphal	return 0
702048d19d4SFlorian Westphal}
703048d19d4SFlorian Westphal
704048d19d4SFlorian Westphalrun_tests()
705048d19d4SFlorian Westphal{
706048d19d4SFlorian Westphal	run_tests_lo $1 $2 $3 0
707048d19d4SFlorian Westphal}
708048d19d4SFlorian Westphal
7095fb62e9cSFlorian Westphalrun_test_transparent()
7105fb62e9cSFlorian Westphal{
7115fb62e9cSFlorian Westphal	local connect_addr="$1"
7125fb62e9cSFlorian Westphal	local msg="$2"
7135fb62e9cSFlorian Westphal
7145fb62e9cSFlorian Westphal	local connector_ns="$ns1"
7155fb62e9cSFlorian Westphal	local listener_ns="$ns2"
7165fb62e9cSFlorian Westphal	local lret=0
7175fb62e9cSFlorian Westphal	local r6flag=""
7185fb62e9cSFlorian Westphal
719dd350f46SMatthieu Baerts	TEST_GROUP="${msg}"
720dd350f46SMatthieu Baerts
7215fb62e9cSFlorian Westphal	# skip if we don't want v6
7228e7f31bfSGeliang Tang	if ! $ipv6 && mptcp_lib_is_v6 "${connect_addr}"; then
7235fb62e9cSFlorian Westphal		return 0
7245fb62e9cSFlorian Westphal	fi
7255fb62e9cSFlorian Westphal
72607bf4940SMatthieu Baerts	# IP(V6)_TRANSPARENT has been added after TOS support which came with
72707bf4940SMatthieu Baerts	# the required infrastructure in MPTCP sockopt code. To support TOS, the
72807bf4940SMatthieu Baerts	# following function has been exported (T). Not great but better than
72907bf4940SMatthieu Baerts	# checking for a specific kernel version.
73007bf4940SMatthieu Baerts	if ! mptcp_lib_kallsyms_has "T __ip_sock_set_tos$"; then
73107bf4940SMatthieu Baerts		echo "INFO: ${msg} not supported by the kernel: SKIP"
732dd350f46SMatthieu Baerts		mptcp_lib_result_skip "${TEST_GROUP}"
73307bf4940SMatthieu Baerts		return
73407bf4940SMatthieu Baerts	fi
73507bf4940SMatthieu Baerts
7365b5ff824SMatthieu Baerts (NGI0)	if ! ip netns exec "$listener_ns" nft -f /dev/stdin <<"EOF"
7375fb62e9cSFlorian Westphalflush ruleset
7385fb62e9cSFlorian Westphaltable inet mangle {
7395fb62e9cSFlorian Westphal	chain divert {
7405fb62e9cSFlorian Westphal		type filter hook prerouting priority -150;
7415fb62e9cSFlorian Westphal
7425fb62e9cSFlorian Westphal		meta l4proto tcp socket transparent 1 meta mark set 1 accept
7435fb62e9cSFlorian Westphal		tcp dport 20000 tproxy to :20000 meta mark set 1 accept
7445fb62e9cSFlorian Westphal	}
7455fb62e9cSFlorian Westphal}
7465fb62e9cSFlorian WestphalEOF
7475b5ff824SMatthieu Baerts (NGI0)	then
7485fb62e9cSFlorian Westphal		echo "SKIP: $msg, could not load nft ruleset"
749221e4550SMatthieu Baerts		mptcp_lib_fail_if_expected_feature "nft rules"
750dd350f46SMatthieu Baerts		mptcp_lib_result_skip "${TEST_GROUP}"
7515fb62e9cSFlorian Westphal		return
7525fb62e9cSFlorian Westphal	fi
7535fb62e9cSFlorian Westphal
7545fb62e9cSFlorian Westphal	local local_addr
7558e7f31bfSGeliang Tang	if mptcp_lib_is_v6 "${connect_addr}"; then
7565fb62e9cSFlorian Westphal		local_addr="::"
7575fb62e9cSFlorian Westphal		r6flag="-6"
7585fb62e9cSFlorian Westphal	else
7595fb62e9cSFlorian Westphal		local_addr="0.0.0.0"
7605fb62e9cSFlorian Westphal	fi
7615fb62e9cSFlorian Westphal
7625b5ff824SMatthieu Baerts (NGI0)	if ! ip -net "$listener_ns" $r6flag rule add fwmark 1 lookup 100; then
7635fb62e9cSFlorian Westphal		ip netns exec "$listener_ns" nft flush ruleset
7645fb62e9cSFlorian Westphal		echo "SKIP: $msg, ip $r6flag rule failed"
765221e4550SMatthieu Baerts		mptcp_lib_fail_if_expected_feature "ip rule"
766dd350f46SMatthieu Baerts		mptcp_lib_result_skip "${TEST_GROUP}"
7675fb62e9cSFlorian Westphal		return
7685fb62e9cSFlorian Westphal	fi
7695fb62e9cSFlorian Westphal
7705b5ff824SMatthieu Baerts (NGI0)	if ! ip -net "$listener_ns" route add local $local_addr/0 dev lo table 100; then
7715fb62e9cSFlorian Westphal		ip netns exec "$listener_ns" nft flush ruleset
7725fb62e9cSFlorian Westphal		ip -net "$listener_ns" $r6flag rule del fwmark 1 lookup 100
7735fb62e9cSFlorian Westphal		echo "SKIP: $msg, ip route add local $local_addr failed"
774221e4550SMatthieu Baerts		mptcp_lib_fail_if_expected_feature "ip route"
775dd350f46SMatthieu Baerts		mptcp_lib_result_skip "${TEST_GROUP}"
7765fb62e9cSFlorian Westphal		return
7775fb62e9cSFlorian Westphal	fi
7785fb62e9cSFlorian Westphal
7795fb62e9cSFlorian Westphal	echo "INFO: test $msg"
7805fb62e9cSFlorian Westphal
7815fb62e9cSFlorian Westphal	TEST_COUNT=10000
7825fb62e9cSFlorian Westphal	local extra_args="-o TRANSPARENT"
7835fb62e9cSFlorian Westphal	do_transfer ${listener_ns} ${connector_ns} MPTCP MPTCP \
7845fb62e9cSFlorian Westphal		    ${connect_addr} ${local_addr} "${extra_args}"
7855fb62e9cSFlorian Westphal	lret=$?
7865fb62e9cSFlorian Westphal
7875fb62e9cSFlorian Westphal	ip netns exec "$listener_ns" nft flush ruleset
7885fb62e9cSFlorian Westphal	ip -net "$listener_ns" $r6flag rule del fwmark 1 lookup 100
7895fb62e9cSFlorian Westphal	ip -net "$listener_ns" route del local $local_addr/0 dev lo table 100
7905fb62e9cSFlorian Westphal
7915fb62e9cSFlorian Westphal	if [ $lret -ne 0 ]; then
7925fb62e9cSFlorian Westphal		echo "FAIL: $msg, mptcp connection error" 1>&2
7935fb62e9cSFlorian Westphal		ret=$lret
7945fb62e9cSFlorian Westphal		return 1
7955fb62e9cSFlorian Westphal	fi
7965fb62e9cSFlorian Westphal
7975fb62e9cSFlorian Westphal	echo "PASS: $msg"
7985fb62e9cSFlorian Westphal	return 0
7995fb62e9cSFlorian Westphal}
8005fb62e9cSFlorian Westphal
801df8aee6dSYonglong Lirun_tests_peekmode()
802df8aee6dSYonglong Li{
803df8aee6dSYonglong Li	local peekmode="$1"
804df8aee6dSYonglong Li
805dd350f46SMatthieu Baerts	TEST_GROUP="peek mode: ${peekmode}"
806df8aee6dSYonglong Li	echo "INFO: with peek mode: ${peekmode}"
807df8aee6dSYonglong Li	run_tests_lo "$ns1" "$ns1" 10.0.1.1 1 "-P ${peekmode}"
808df8aee6dSYonglong Li	run_tests_lo "$ns1" "$ns1" dead:beef:1::1 1 "-P ${peekmode}"
809df8aee6dSYonglong Li}
810df8aee6dSYonglong Li
811ca7ae891SDmytro Shytyirun_tests_mptfo()
812ca7ae891SDmytro Shytyi{
813dd350f46SMatthieu Baerts	TEST_GROUP="MPTFO"
814dd350f46SMatthieu Baerts
81506b03083SMatthieu Baerts	if ! mptcp_lib_kallsyms_has "mptcp_fastopen_"; then
81606b03083SMatthieu Baerts		echo "INFO: TFO not supported by the kernel: SKIP"
817dd350f46SMatthieu Baerts		mptcp_lib_result_skip "${TEST_GROUP}"
81806b03083SMatthieu Baerts		return
81906b03083SMatthieu Baerts	fi
82006b03083SMatthieu Baerts
821ca7ae891SDmytro Shytyi	echo "INFO: with MPTFO start"
822ca7ae891SDmytro Shytyi	ip netns exec "$ns1" sysctl -q net.ipv4.tcp_fastopen=2
823ca7ae891SDmytro Shytyi	ip netns exec "$ns2" sysctl -q net.ipv4.tcp_fastopen=1
824ca7ae891SDmytro Shytyi
825ca7ae891SDmytro Shytyi	run_tests_lo "$ns1" "$ns2" 10.0.1.1 0 "-o MPTFO"
826ca7ae891SDmytro Shytyi	run_tests_lo "$ns1" "$ns2" 10.0.1.1 0 "-o MPTFO"
827ca7ae891SDmytro Shytyi
828ca7ae891SDmytro Shytyi	run_tests_lo "$ns1" "$ns2" dead:beef:1::1 0 "-o MPTFO"
829ca7ae891SDmytro Shytyi	run_tests_lo "$ns1" "$ns2" dead:beef:1::1 0 "-o MPTFO"
830ca7ae891SDmytro Shytyi
831ca7ae891SDmytro Shytyi	ip netns exec "$ns1" sysctl -q net.ipv4.tcp_fastopen=0
832ca7ae891SDmytro Shytyi	ip netns exec "$ns2" sysctl -q net.ipv4.tcp_fastopen=0
833ca7ae891SDmytro Shytyi	echo "INFO: with MPTFO end"
834ca7ae891SDmytro Shytyi}
835ca7ae891SDmytro Shytyi
83605be5e27SPaolo Abenirun_tests_disconnect()
83705be5e27SPaolo Abeni{
83805be5e27SPaolo Abeni	local old_cin=$cin
83905be5e27SPaolo Abeni	local old_sin=$sin
84005be5e27SPaolo Abeni
841dd350f46SMatthieu Baerts	TEST_GROUP="full disconnect"
842dd350f46SMatthieu Baerts
8434ad39a42SMatthieu Baerts	if ! mptcp_lib_kallsyms_has "mptcp_pm_data_reset$"; then
8444ad39a42SMatthieu Baerts		echo "INFO: Full disconnect not supported: SKIP"
845dd350f46SMatthieu Baerts		mptcp_lib_result_skip "${TEST_GROUP}"
8464ad39a42SMatthieu Baerts		return
8474ad39a42SMatthieu Baerts	fi
8484ad39a42SMatthieu Baerts
84905be5e27SPaolo Abeni	cat $cin $cin $cin > "$cin".disconnect
85005be5e27SPaolo Abeni
851e6b8a78eSYueh-Shun Li	# force do_transfer to cope with the multiple transmissions
85205be5e27SPaolo Abeni	sin="$cin.disconnect"
85305be5e27SPaolo Abeni	cin="$cin.disconnect"
85405be5e27SPaolo Abeni	cin_disconnect="$old_cin"
85505be5e27SPaolo Abeni	connect_per_transfer=3
85605be5e27SPaolo Abeni
85705be5e27SPaolo Abeni	echo "INFO: disconnect"
85805be5e27SPaolo Abeni	run_tests_lo "$ns1" "$ns1" 10.0.1.1 1 "-I 3 -i $old_cin"
85905be5e27SPaolo Abeni	run_tests_lo "$ns1" "$ns1" dead:beef:1::1 1 "-I 3 -i $old_cin"
86005be5e27SPaolo Abeni
86105be5e27SPaolo Abeni	# restore previous status
86263bb8239SPaolo Abeni	sin=$old_sin
86305be5e27SPaolo Abeni	cin=$old_cin
86405be5e27SPaolo Abeni	cin_disconnect="$cin".disconnect
86505be5e27SPaolo Abeni	connect_per_transfer=1
86605be5e27SPaolo Abeni}
86705be5e27SPaolo Abeni
868a4debc47SMatthieu Baertsdisplay_time()
869a4debc47SMatthieu Baerts{
870a4debc47SMatthieu Baerts	time_end=$(date +%s)
871a4debc47SMatthieu Baerts	time_run=$((time_end-time_start))
872a4debc47SMatthieu Baerts
873a4debc47SMatthieu Baerts	echo "Time: ${time_run} seconds"
874a4debc47SMatthieu Baerts}
875a4debc47SMatthieu Baerts
876edbc16c4SMatthieu Baertslog_if_error()
877a4debc47SMatthieu Baerts{
878a4debc47SMatthieu Baerts	local msg="$1"
879a4debc47SMatthieu Baerts
880a4debc47SMatthieu Baerts	if [ ${ret} -ne 0 ]; then
881a4debc47SMatthieu Baerts		echo "FAIL: ${msg}" 1>&2
882edbc16c4SMatthieu Baerts
883edbc16c4SMatthieu Baerts		final_ret=${ret}
884edbc16c4SMatthieu Baerts		ret=0
885edbc16c4SMatthieu Baerts
886edbc16c4SMatthieu Baerts		return ${final_ret}
887edbc16c4SMatthieu Baerts	fi
888edbc16c4SMatthieu Baerts}
889edbc16c4SMatthieu Baerts
890edbc16c4SMatthieu Baertsstop_if_error()
891edbc16c4SMatthieu Baerts{
892edbc16c4SMatthieu Baerts	if ! log_if_error "${@}"; then
893a4debc47SMatthieu Baerts		display_time
894dd350f46SMatthieu Baerts		mptcp_lib_result_print_all_tap
895edbc16c4SMatthieu Baerts		exit ${final_ret}
896a4debc47SMatthieu Baerts	fi
897a4debc47SMatthieu Baerts}
898a4debc47SMatthieu Baerts
899048d19d4SFlorian Westphalmake_file "$cin" "client"
900048d19d4SFlorian Westphalmake_file "$sin" "server"
901048d19d4SFlorian Westphal
902048d19d4SFlorian Westphalcheck_mptcp_disabled
903048d19d4SFlorian Westphal
904a4debc47SMatthieu Baertsstop_if_error "The kernel configuration is not valid for MPTCP"
905a4debc47SMatthieu Baerts
906048d19d4SFlorian Westphalecho "INFO: validating network environment with pings"
907048d19d4SFlorian Westphalfor sender in "$ns1" "$ns2" "$ns3" "$ns4";do
908048d19d4SFlorian Westphal	do_ping "$ns1" $sender 10.0.1.1
909048d19d4SFlorian Westphal	do_ping "$ns1" $sender dead:beef:1::1
910048d19d4SFlorian Westphal
911048d19d4SFlorian Westphal	do_ping "$ns2" $sender 10.0.1.2
912048d19d4SFlorian Westphal	do_ping "$ns2" $sender dead:beef:1::2
913048d19d4SFlorian Westphal	do_ping "$ns2" $sender 10.0.2.1
914048d19d4SFlorian Westphal	do_ping "$ns2" $sender dead:beef:2::1
915048d19d4SFlorian Westphal
916048d19d4SFlorian Westphal	do_ping "$ns3" $sender 10.0.2.2
917048d19d4SFlorian Westphal	do_ping "$ns3" $sender dead:beef:2::2
918048d19d4SFlorian Westphal	do_ping "$ns3" $sender 10.0.3.2
919048d19d4SFlorian Westphal	do_ping "$ns3" $sender dead:beef:3::2
920048d19d4SFlorian Westphal
921048d19d4SFlorian Westphal	do_ping "$ns4" $sender 10.0.3.1
922048d19d4SFlorian Westphal	do_ping "$ns4" $sender dead:beef:3::1
923048d19d4SFlorian Westphaldone
924048d19d4SFlorian Westphal
925dd350f46SMatthieu Baertsmptcp_lib_result_code "${ret}" "ping tests"
926dd350f46SMatthieu Baerts
927a4debc47SMatthieu Baertsstop_if_error "Could not even run ping tests"
928a4debc47SMatthieu Baerts
929e5484658SChristoph Paasch[ -n "$tc_loss" ] && tc -net "$ns2" qdisc add dev ns2eth3 root netem loss random $tc_loss delay ${tc_delay}ms
930*732752baSGeliang Tangtc_info="loss of $tc_loss "
931*732752baSGeliang Tangtest "$tc_delay" -gt 0 && tc_info+="delay $tc_delay ms "
932048d19d4SFlorian Westphal
9335b5ff824SMatthieu Baerts (NGI0)reorder_delay=$((tc_delay / 4))
934e5484658SChristoph Paasch
935048d19d4SFlorian Westphalif [ -z "${tc_reorder}" ]; then
936048d19d4SFlorian Westphal	reorder1=$((RANDOM%10))
937048d19d4SFlorian Westphal	reorder1=$((100 - reorder1))
938048d19d4SFlorian Westphal	reorder2=$((RANDOM%100))
939048d19d4SFlorian Westphal
940e5484658SChristoph Paasch	if [ $reorder_delay -gt 0 ] && [ $reorder1 -lt 100 ] && [ $reorder2 -gt 0 ]; then
941048d19d4SFlorian Westphal		tc_reorder="reorder ${reorder1}% ${reorder2}%"
942*732752baSGeliang Tang		tc_info+="$tc_reorder with delay ${reorder_delay}ms "
943048d19d4SFlorian Westphal	fi
944048d19d4SFlorian Westphalelif [ "$tc_reorder" = "0" ];then
945048d19d4SFlorian Westphal	tc_reorder=""
946e5484658SChristoph Paaschelif [ "$reorder_delay" -gt 0 ];then
947048d19d4SFlorian Westphal	# reordering requires some delay
948048d19d4SFlorian Westphal	tc_reorder="reorder $tc_reorder"
949*732752baSGeliang Tang	tc_info+="$tc_reorder with delay ${reorder_delay}ms "
950048d19d4SFlorian Westphalfi
951048d19d4SFlorian Westphal
952*732752baSGeliang Tangecho "INFO: Using ${tc_info}on ns3eth4"
953048d19d4SFlorian Westphal
954e5484658SChristoph Paaschtc -net "$ns3" qdisc add dev ns3eth4 root netem delay ${reorder_delay}ms $tc_reorder
955048d19d4SFlorian Westphal
956dd350f46SMatthieu BaertsTEST_GROUP="loopback v4"
957a4debc47SMatthieu Baertsrun_tests_lo "$ns1" "$ns1" 10.0.1.1 1
958a4debc47SMatthieu Baertsstop_if_error "Could not even run loopback test"
959048d19d4SFlorian Westphal
960dd350f46SMatthieu BaertsTEST_GROUP="loopback v6"
961a4debc47SMatthieu Baertsrun_tests_lo "$ns1" "$ns1" dead:beef:1::1 1
962a4debc47SMatthieu Baertsstop_if_error "Could not even run loopback v6 test"
963a4debc47SMatthieu Baerts
964dd350f46SMatthieu BaertsTEST_GROUP="multihosts"
965a4debc47SMatthieu Baertsfor sender in $ns1 $ns2 $ns3 $ns4;do
9662395da0eSPaolo Abeni	# ns1<->ns2 is not subject to reordering/tc delays. Use it to test
9672395da0eSPaolo Abeni	# mptcp syncookie support.
9682395da0eSPaolo Abeni	if [ $sender = $ns1 ]; then
9692395da0eSPaolo Abeni		ip netns exec "$ns2" sysctl -q net.ipv4.tcp_syncookies=2
9702395da0eSPaolo Abeni	else
9712395da0eSPaolo Abeni		ip netns exec "$ns2" sysctl -q net.ipv4.tcp_syncookies=1
9722395da0eSPaolo Abeni	fi
9732395da0eSPaolo Abeni
974a4debc47SMatthieu Baerts	run_tests "$ns1" $sender 10.0.1.1
975a4debc47SMatthieu Baerts	run_tests "$ns1" $sender dead:beef:1::1
976a4debc47SMatthieu Baerts
977048d19d4SFlorian Westphal	run_tests "$ns2" $sender 10.0.1.2
978048d19d4SFlorian Westphal	run_tests "$ns2" $sender dead:beef:1::2
979048d19d4SFlorian Westphal	run_tests "$ns2" $sender 10.0.2.1
980048d19d4SFlorian Westphal	run_tests "$ns2" $sender dead:beef:2::1
981048d19d4SFlorian Westphal
982048d19d4SFlorian Westphal	run_tests "$ns3" $sender 10.0.2.2
983048d19d4SFlorian Westphal	run_tests "$ns3" $sender dead:beef:2::2
984048d19d4SFlorian Westphal	run_tests "$ns3" $sender 10.0.3.2
985048d19d4SFlorian Westphal	run_tests "$ns3" $sender dead:beef:3::2
986048d19d4SFlorian Westphal
987048d19d4SFlorian Westphal	run_tests "$ns4" $sender 10.0.3.1
988048d19d4SFlorian Westphal	run_tests "$ns4" $sender dead:beef:3::1
989a4debc47SMatthieu Baerts
990edbc16c4SMatthieu Baerts	log_if_error "Tests with $sender as a sender have failed"
991048d19d4SFlorian Westphaldone
992048d19d4SFlorian Westphal
993df8aee6dSYonglong Lirun_tests_peekmode "saveWithPeek"
994df8aee6dSYonglong Lirun_tests_peekmode "saveAfterPeek"
995edbc16c4SMatthieu Baertslog_if_error "Tests with peek mode have failed"
996df8aee6dSYonglong Li
997ca7ae891SDmytro Shytyi# MPTFO (MultiPath TCP Fatopen tests)
998ca7ae891SDmytro Shytyirun_tests_mptfo
999edbc16c4SMatthieu Baertslog_if_error "Tests with MPTFO have failed"
1000ca7ae891SDmytro Shytyi
10015fb62e9cSFlorian Westphal# connect to ns4 ip address, ns2 should intercept/proxy
10025fb62e9cSFlorian Westphalrun_test_transparent 10.0.3.1 "tproxy ipv4"
10035fb62e9cSFlorian Westphalrun_test_transparent dead:beef:3::1 "tproxy ipv6"
1004edbc16c4SMatthieu Baertslog_if_error "Tests with tproxy have failed"
100505be5e27SPaolo Abeni
100605be5e27SPaolo Abenirun_tests_disconnect
1007edbc16c4SMatthieu Baertslog_if_error "Tests of the full disconnection have failed"
10085fb62e9cSFlorian Westphal
1009a4debc47SMatthieu Baertsdisplay_time
1010dd350f46SMatthieu Baertsmptcp_lib_result_print_all_tap
1011edbc16c4SMatthieu Baertsexit ${final_ret}
1012