1b08fbf24SPaolo Abeni#!/bin/bash
2b08fbf24SPaolo Abeni# SPDX-License-Identifier: GPL-2.0
3b08fbf24SPaolo Abeni
4b08fbf24SPaolo Abeniret=0
5b08fbf24SPaolo Abenisin=""
67d1e6f16SPaolo Abenisinfail=""
7b08fbf24SPaolo Abenisout=""
8b08fbf24SPaolo Abenicin=""
97d1e6f16SPaolo Abenicinfail=""
108b819a84SFlorian Westphalcinsent=""
11b08fbf24SPaolo Abenicout=""
12b08fbf24SPaolo Abeniksft_skip=4
135888a61cSMatthieu Baertstimeout_poll=30
145888a61cSMatthieu Baertstimeout_test=$((timeout_poll * 2 + 1))
15b08fbf24SPaolo Abenicapture=0
16af66d3e1SGeliang Tangchecksum=0
1734aa6e3bSGeliang Tangip_mptcp=0
188117dac3SGeliang Tangcheck_invert=0
1993827ad5SMatthieu Baertsinit=0
20b08fbf24SPaolo Abeni
21b08fbf24SPaolo AbeniTEST_COUNT=0
229a0a9367SGeliang Tangnr_blank=40
23b08fbf24SPaolo Abeni
248d014eaaSGeliang Tang# generated using "nfbpf_compile '(ip && (ip[54] & 0xf0) == 0x30) ||
258d014eaaSGeliang Tang#				  (ip6 && (ip6[74] & 0xf0) == 0x30)'"
268d014eaaSGeliang TangCBPF_MPTCP_SUBOPTION_ADD_ADDR="14,
278d014eaaSGeliang Tang			       48 0 0 0,
288d014eaaSGeliang Tang			       84 0 0 240,
298d014eaaSGeliang Tang			       21 0 3 64,
308d014eaaSGeliang Tang			       48 0 0 54,
318d014eaaSGeliang Tang			       84 0 0 240,
328d014eaaSGeliang Tang			       21 6 7 48,
338d014eaaSGeliang Tang			       48 0 0 0,
348d014eaaSGeliang Tang			       84 0 0 240,
358d014eaaSGeliang Tang			       21 0 4 96,
368d014eaaSGeliang Tang			       48 0 0 74,
378d014eaaSGeliang Tang			       84 0 0 240,
388d014eaaSGeliang Tang			       21 0 1 48,
398d014eaaSGeliang Tang			       6 0 0 65535,
408d014eaaSGeliang Tang			       6 0 0 0"
418d014eaaSGeliang Tang
4293827ad5SMatthieu Baertsinit_partial()
43b08fbf24SPaolo Abeni{
44b08fbf24SPaolo Abeni	capout=$(mktemp)
45b08fbf24SPaolo Abeni
460a40e273SMatthieu Baerts	rndh=$(mktemp -u XXXXXX)
47b08fbf24SPaolo Abeni
48b08fbf24SPaolo Abeni	ns1="ns1-$rndh"
49b08fbf24SPaolo Abeni	ns2="ns2-$rndh"
50b08fbf24SPaolo Abeni
51b08fbf24SPaolo Abeni	for netns in "$ns1" "$ns2";do
52b08fbf24SPaolo Abeni		ip netns add $netns || exit $ksft_skip
53b08fbf24SPaolo Abeni		ip -net $netns link set lo up
54b08fbf24SPaolo Abeni		ip netns exec $netns sysctl -q net.mptcp.enabled=1
55b08fbf24SPaolo Abeni		ip netns exec $netns sysctl -q net.ipv4.conf.all.rp_filter=0
56b08fbf24SPaolo Abeni		ip netns exec $netns sysctl -q net.ipv4.conf.default.rp_filter=0
57af66d3e1SGeliang Tang		if [ $checksum -eq 1 ]; then
58af66d3e1SGeliang Tang			ip netns exec $netns sysctl -q net.mptcp.checksum_enabled=1
59af66d3e1SGeliang Tang		fi
60b08fbf24SPaolo Abeni	done
61b08fbf24SPaolo Abeni
628117dac3SGeliang Tang	check_invert=0
638117dac3SGeliang Tang
64b08fbf24SPaolo Abeni	#  ns1              ns2
65b08fbf24SPaolo Abeni	# ns1eth1    ns2eth1
66b08fbf24SPaolo Abeni	# ns1eth2    ns2eth2
67b08fbf24SPaolo Abeni	# ns1eth3    ns2eth3
68b08fbf24SPaolo Abeni	# ns1eth4    ns2eth4
69b08fbf24SPaolo Abeni
70b08fbf24SPaolo Abeni	for i in `seq 1 4`; do
71b08fbf24SPaolo Abeni		ip link add ns1eth$i netns "$ns1" type veth peer name ns2eth$i netns "$ns2"
72b08fbf24SPaolo Abeni		ip -net "$ns1" addr add 10.0.$i.1/24 dev ns1eth$i
73b08fbf24SPaolo Abeni		ip -net "$ns1" addr add dead:beef:$i::1/64 dev ns1eth$i nodad
74b08fbf24SPaolo Abeni		ip -net "$ns1" link set ns1eth$i up
75b08fbf24SPaolo Abeni
76b08fbf24SPaolo Abeni		ip -net "$ns2" addr add 10.0.$i.2/24 dev ns2eth$i
77b08fbf24SPaolo Abeni		ip -net "$ns2" addr add dead:beef:$i::2/64 dev ns2eth$i nodad
78b08fbf24SPaolo Abeni		ip -net "$ns2" link set ns2eth$i up
79b08fbf24SPaolo Abeni
80b08fbf24SPaolo Abeni		# let $ns2 reach any $ns1 address from any interface
81b08fbf24SPaolo Abeni		ip -net "$ns2" route add default via 10.0.$i.1 dev ns2eth$i metric 10$i
829846921dSPaolo Abeni		ip -net "$ns2" route add default via dead:beef:$i::1 dev ns2eth$i metric 10$i
83b08fbf24SPaolo Abeni	done
84b08fbf24SPaolo Abeni}
85b08fbf24SPaolo Abeni
867d1e6f16SPaolo Abeniinit_shapers()
877d1e6f16SPaolo Abeni{
887d1e6f16SPaolo Abeni	for i in `seq 1 4`; do
897d1e6f16SPaolo Abeni		tc -n $ns1 qdisc add dev ns1eth$i root netem rate 20mbit delay 1
907d1e6f16SPaolo Abeni		tc -n $ns2 qdisc add dev ns2eth$i root netem rate 20mbit delay 1
917d1e6f16SPaolo Abeni	done
927d1e6f16SPaolo Abeni}
937d1e6f16SPaolo Abeni
94b08fbf24SPaolo Abenicleanup_partial()
95b08fbf24SPaolo Abeni{
96b08fbf24SPaolo Abeni	rm -f "$capout"
97b08fbf24SPaolo Abeni
98b08fbf24SPaolo Abeni	for netns in "$ns1" "$ns2"; do
99b08fbf24SPaolo Abeni		ip netns del $netns
100c2a55e8fSMatthieu Baerts		rm -f /tmp/$netns.{nstat,out}
101b08fbf24SPaolo Abeni	done
102b08fbf24SPaolo Abeni}
103b08fbf24SPaolo Abeni
10487154755SMatthieu Baertscheck_tools()
10587154755SMatthieu Baerts{
10687154755SMatthieu Baerts	if ! ip -Version &> /dev/null; then
10787154755SMatthieu Baerts		echo "SKIP: Could not run test without ip tool"
10887154755SMatthieu Baerts		exit $ksft_skip
10987154755SMatthieu Baerts	fi
11087154755SMatthieu Baerts
11187154755SMatthieu Baerts	if ! iptables -V &> /dev/null; then
11287154755SMatthieu Baerts		echo "SKIP: Could not run all tests without iptables tool"
11387154755SMatthieu Baerts		exit $ksft_skip
11487154755SMatthieu Baerts	fi
11587154755SMatthieu Baerts
11687154755SMatthieu Baerts	if ! ip6tables -V &> /dev/null; then
11787154755SMatthieu Baerts		echo "SKIP: Could not run all tests without ip6tables tool"
11887154755SMatthieu Baerts		exit $ksft_skip
11987154755SMatthieu Baerts	fi
12087154755SMatthieu Baerts}
12187154755SMatthieu Baerts
12293827ad5SMatthieu Baertsinit() {
12393827ad5SMatthieu Baerts	init=1
12493827ad5SMatthieu Baerts
12587154755SMatthieu Baerts	check_tools
12687154755SMatthieu Baerts
12793827ad5SMatthieu Baerts	sin=$(mktemp)
12893827ad5SMatthieu Baerts	sout=$(mktemp)
12993827ad5SMatthieu Baerts	cin=$(mktemp)
13093827ad5SMatthieu Baerts	cinsent=$(mktemp)
13193827ad5SMatthieu Baerts	cout=$(mktemp)
13293827ad5SMatthieu Baerts
13393827ad5SMatthieu Baerts	trap cleanup EXIT
13493827ad5SMatthieu Baerts
13593827ad5SMatthieu Baerts	make_file "$cin" "client" 1
13693827ad5SMatthieu Baerts	make_file "$sin" "server" 1
13793827ad5SMatthieu Baerts}
13893827ad5SMatthieu Baerts
139b08fbf24SPaolo Abenicleanup()
140b08fbf24SPaolo Abeni{
1417d1e6f16SPaolo Abeni	rm -f "$cin" "$cout" "$sinfail"
1427d1e6f16SPaolo Abeni	rm -f "$sin" "$sout" "$cinsent" "$cinfail"
143b08fbf24SPaolo Abeni	cleanup_partial
144b08fbf24SPaolo Abeni}
145b08fbf24SPaolo Abeni
146b08fbf24SPaolo Abenireset()
147b08fbf24SPaolo Abeni{
14893827ad5SMatthieu Baerts	if [ "${init}" != "1" ]; then
149b08fbf24SPaolo Abeni		init
15093827ad5SMatthieu Baerts	else
15193827ad5SMatthieu Baerts		cleanup_partial
15293827ad5SMatthieu Baerts	fi
15393827ad5SMatthieu Baerts
15493827ad5SMatthieu Baerts	init_partial
155b08fbf24SPaolo Abeni}
156b08fbf24SPaolo Abeni
15700587187SFlorian Westphalreset_with_cookies()
15800587187SFlorian Westphal{
15900587187SFlorian Westphal	reset
16000587187SFlorian Westphal
16100587187SFlorian Westphal	for netns in "$ns1" "$ns2";do
16200587187SFlorian Westphal		ip netns exec $netns sysctl -q net.ipv4.tcp_syncookies=2
16300587187SFlorian Westphal	done
16400587187SFlorian Westphal}
16500587187SFlorian Westphal
1668d014eaaSGeliang Tangreset_with_add_addr_timeout()
1678d014eaaSGeliang Tang{
1688d014eaaSGeliang Tang	local ip="${1:-4}"
1698d014eaaSGeliang Tang	local tables
1708d014eaaSGeliang Tang
1718d014eaaSGeliang Tang	tables="iptables"
1728d014eaaSGeliang Tang	if [ $ip -eq 6 ]; then
1738d014eaaSGeliang Tang		tables="ip6tables"
1748d014eaaSGeliang Tang	fi
1758d014eaaSGeliang Tang
1768d014eaaSGeliang Tang	reset
1778d014eaaSGeliang Tang
1788d014eaaSGeliang Tang	ip netns exec $ns1 sysctl -q net.mptcp.add_addr_timeout=1
1798d014eaaSGeliang Tang	ip netns exec $ns2 $tables -A OUTPUT -p tcp \
1808d014eaaSGeliang Tang		-m tcp --tcp-option 30 \
1818d014eaaSGeliang Tang		-m bpf --bytecode \
1828d014eaaSGeliang Tang		"$CBPF_MPTCP_SUBOPTION_ADD_ADDR" \
1838d014eaaSGeliang Tang		-j DROP
1848d014eaaSGeliang Tang}
1858d014eaaSGeliang Tang
186af66d3e1SGeliang Tangreset_with_checksum()
187af66d3e1SGeliang Tang{
188af66d3e1SGeliang Tang	local ns1_enable=$1
189af66d3e1SGeliang Tang	local ns2_enable=$2
190af66d3e1SGeliang Tang
191af66d3e1SGeliang Tang	reset
192af66d3e1SGeliang Tang
193af66d3e1SGeliang Tang	ip netns exec $ns1 sysctl -q net.mptcp.checksum_enabled=$ns1_enable
194af66d3e1SGeliang Tang	ip netns exec $ns2 sysctl -q net.mptcp.checksum_enabled=$ns2_enable
195af66d3e1SGeliang Tang}
196af66d3e1SGeliang Tang
1970cddb4a6SGeliang Tangreset_with_allow_join_id0()
1980cddb4a6SGeliang Tang{
1990cddb4a6SGeliang Tang	local ns1_enable=$1
2000cddb4a6SGeliang Tang	local ns2_enable=$2
2010cddb4a6SGeliang Tang
2020cddb4a6SGeliang Tang	reset
2030cddb4a6SGeliang Tang
2040cddb4a6SGeliang Tang	ip netns exec $ns1 sysctl -q net.mptcp.allow_join_initial_addr_port=$ns1_enable
2050cddb4a6SGeliang Tang	ip netns exec $ns2 sysctl -q net.mptcp.allow_join_initial_addr_port=$ns2_enable
2060cddb4a6SGeliang Tang}
2070cddb4a6SGeliang Tang
2088b819a84SFlorian Westphalprint_file_err()
2098b819a84SFlorian Westphal{
2108b819a84SFlorian Westphal	ls -l "$1" 1>&2
2118b819a84SFlorian Westphal	echo "Trailing bytes are: "
2128b819a84SFlorian Westphal	tail -c 27 "$1"
2138b819a84SFlorian Westphal}
2148b819a84SFlorian Westphal
215b08fbf24SPaolo Abenicheck_transfer()
216b08fbf24SPaolo Abeni{
217b08fbf24SPaolo Abeni	in=$1
218b08fbf24SPaolo Abeni	out=$2
219b08fbf24SPaolo Abeni	what=$3
220b08fbf24SPaolo Abeni
2218117dac3SGeliang Tang	cmp -l "$in" "$out" | while read line; do
2228117dac3SGeliang Tang		local arr=($line)
2238117dac3SGeliang Tang
2248117dac3SGeliang Tang		let sum=0${arr[1]}+0${arr[2]}
2258117dac3SGeliang Tang		if [ $check_invert -eq 0 ] || [ $sum -ne $((0xff)) ]; then
226b08fbf24SPaolo Abeni			echo "[ FAIL ] $what does not match (in, out):"
227b08fbf24SPaolo Abeni			print_file_err "$in"
228b08fbf24SPaolo Abeni			print_file_err "$out"
2298b819a84SFlorian Westphal			ret=1
230b08fbf24SPaolo Abeni
231b08fbf24SPaolo Abeni			return 1
2328117dac3SGeliang Tang		else
2338117dac3SGeliang Tang			echo "$what has inverted byte at ${arr[0]}"
234b08fbf24SPaolo Abeni		fi
2358117dac3SGeliang Tang	done
236b08fbf24SPaolo Abeni
237b08fbf24SPaolo Abeni	return 0
238b08fbf24SPaolo Abeni}
239b08fbf24SPaolo Abeni
240b08fbf24SPaolo Abenido_ping()
241b08fbf24SPaolo Abeni{
242b08fbf24SPaolo Abeni	listener_ns="$1"
243b08fbf24SPaolo Abeni	connector_ns="$2"
244b08fbf24SPaolo Abeni	connect_addr="$3"
245b08fbf24SPaolo Abeni
246b08fbf24SPaolo Abeni	ip netns exec ${connector_ns} ping -q -c 1 $connect_addr >/dev/null
247b08fbf24SPaolo Abeni	if [ $? -ne 0 ] ; then
248b08fbf24SPaolo Abeni		echo "$listener_ns -> $connect_addr connectivity [ FAIL ]" 1>&2
249b08fbf24SPaolo Abeni		ret=1
250b08fbf24SPaolo Abeni	fi
251b08fbf24SPaolo Abeni}
252b08fbf24SPaolo Abeni
2538b819a84SFlorian Westphallink_failure()
2548b819a84SFlorian Westphal{
2558b819a84SFlorian Westphal	ns="$1"
2568b819a84SFlorian Westphal
2577d1e6f16SPaolo Abeni	if [ -z "$FAILING_LINKS" ]; then
2588b819a84SFlorian Westphal		l=$((RANDOM%4))
2597d1e6f16SPaolo Abeni		FAILING_LINKS=$((l+1))
2607d1e6f16SPaolo Abeni	fi
2618b819a84SFlorian Westphal
2627d1e6f16SPaolo Abeni	for l in $FAILING_LINKS; do
2638b819a84SFlorian Westphal		veth="ns1eth$l"
2648b819a84SFlorian Westphal		ip -net "$ns" link set "$veth" down
2657d1e6f16SPaolo Abeni	done
2668b819a84SFlorian Westphal}
2678b819a84SFlorian Westphal
268523514edSGeliang Tang# $1: IP address
269523514edSGeliang Tangis_v6()
270523514edSGeliang Tang{
271523514edSGeliang Tang	[ -z "${1##*:*}" ]
272523514edSGeliang Tang}
273523514edSGeliang Tang
274327b9a94SPaolo Abeni# $1: ns, $2: port
275327b9a94SPaolo Abeniwait_local_port_listen()
276327b9a94SPaolo Abeni{
277327b9a94SPaolo Abeni	local listener_ns="${1}"
278327b9a94SPaolo Abeni	local port="${2}"
279327b9a94SPaolo Abeni
280327b9a94SPaolo Abeni	local port_hex i
281327b9a94SPaolo Abeni
282327b9a94SPaolo Abeni	port_hex="$(printf "%04X" "${port}")"
283327b9a94SPaolo Abeni	for i in $(seq 10); do
284327b9a94SPaolo Abeni		ip netns exec "${listener_ns}" cat /proc/net/tcp* | \
285327b9a94SPaolo Abeni			awk "BEGIN {rc=1} {if (\$2 ~ /:${port_hex}\$/ && \$4 ~ /0A/) {rc=0; exit}} END {exit rc}" &&
286327b9a94SPaolo Abeni			break
287327b9a94SPaolo Abeni		sleep 0.1
288327b9a94SPaolo Abeni	done
289327b9a94SPaolo Abeni}
290327b9a94SPaolo Abeni
291327b9a94SPaolo Abenirm_addr_count()
292327b9a94SPaolo Abeni{
293327b9a94SPaolo Abeni	ns=${1}
294327b9a94SPaolo Abeni
295327b9a94SPaolo Abeni	ip netns exec ${ns} nstat -as | grep MPTcpExtRmAddr | awk '{print $2}'
296327b9a94SPaolo Abeni}
297327b9a94SPaolo Abeni
298327b9a94SPaolo Abeni# $1: ns, $2: old rm_addr counter in $ns
299327b9a94SPaolo Abeniwait_rm_addr()
300327b9a94SPaolo Abeni{
301327b9a94SPaolo Abeni	local ns="${1}"
302327b9a94SPaolo Abeni	local old_cnt="${2}"
303327b9a94SPaolo Abeni	local cnt
304327b9a94SPaolo Abeni	local i
305327b9a94SPaolo Abeni
306327b9a94SPaolo Abeni	for i in $(seq 10); do
307327b9a94SPaolo Abeni		cnt=$(rm_addr_count ${ns})
308327b9a94SPaolo Abeni		[ "$cnt" = "${old_cnt}" ] || break
309327b9a94SPaolo Abeni		sleep 0.1
310327b9a94SPaolo Abeni	done
311327b9a94SPaolo Abeni}
312327b9a94SPaolo Abeni
31334aa6e3bSGeliang Tangpm_nl_set_limits()
31434aa6e3bSGeliang Tang{
31534aa6e3bSGeliang Tang	local ns=$1
31634aa6e3bSGeliang Tang	local addrs=$2
31734aa6e3bSGeliang Tang	local subflows=$3
31834aa6e3bSGeliang Tang
31934aa6e3bSGeliang Tang	if [ $ip_mptcp -eq 1 ]; then
32034aa6e3bSGeliang Tang		ip -n $ns mptcp limits set add_addr_accepted $addrs subflows $subflows
32134aa6e3bSGeliang Tang	else
32234aa6e3bSGeliang Tang		ip netns exec $ns ./pm_nl_ctl limits $addrs $subflows
32334aa6e3bSGeliang Tang	fi
32434aa6e3bSGeliang Tang}
32534aa6e3bSGeliang Tang
32634aa6e3bSGeliang Tangpm_nl_add_endpoint()
32734aa6e3bSGeliang Tang{
32834aa6e3bSGeliang Tang	local ns=$1
32934aa6e3bSGeliang Tang	local addr=$2
33034aa6e3bSGeliang Tang	local flags
33134aa6e3bSGeliang Tang	local port
33234aa6e3bSGeliang Tang	local dev
33334aa6e3bSGeliang Tang	local id
33434aa6e3bSGeliang Tang	local nr=2
33534aa6e3bSGeliang Tang
33634aa6e3bSGeliang Tang	for p in $@
33734aa6e3bSGeliang Tang	do
33834aa6e3bSGeliang Tang		if [ $p = "flags" ]; then
33934aa6e3bSGeliang Tang			eval _flags=\$"$nr"
34034aa6e3bSGeliang Tang			[ ! -z $_flags ]; flags="flags $_flags"
34134aa6e3bSGeliang Tang		fi
34234aa6e3bSGeliang Tang		if [ $p = "dev" ]; then
34334aa6e3bSGeliang Tang			eval _dev=\$"$nr"
34434aa6e3bSGeliang Tang			[ ! -z $_dev ]; dev="dev $_dev"
34534aa6e3bSGeliang Tang		fi
34634aa6e3bSGeliang Tang		if [ $p = "id" ]; then
34734aa6e3bSGeliang Tang			eval _id=\$"$nr"
34834aa6e3bSGeliang Tang			[ ! -z $_id ]; id="id $_id"
34934aa6e3bSGeliang Tang		fi
35034aa6e3bSGeliang Tang		if [ $p = "port" ]; then
35134aa6e3bSGeliang Tang			eval _port=\$"$nr"
35234aa6e3bSGeliang Tang			[ ! -z $_port ]; port="port $_port"
35334aa6e3bSGeliang Tang		fi
35434aa6e3bSGeliang Tang
35534aa6e3bSGeliang Tang		let nr+=1
35634aa6e3bSGeliang Tang	done
35734aa6e3bSGeliang Tang
35834aa6e3bSGeliang Tang	if [ $ip_mptcp -eq 1 ]; then
35934aa6e3bSGeliang Tang		ip -n $ns mptcp endpoint add $addr ${_flags//","/" "} $dev $id $port
36034aa6e3bSGeliang Tang	else
36134aa6e3bSGeliang Tang		ip netns exec $ns ./pm_nl_ctl add $addr $flags $dev $id $port
36234aa6e3bSGeliang Tang	fi
36334aa6e3bSGeliang Tang}
36434aa6e3bSGeliang Tang
36534aa6e3bSGeliang Tangpm_nl_del_endpoint()
36634aa6e3bSGeliang Tang{
36734aa6e3bSGeliang Tang	local ns=$1
36834aa6e3bSGeliang Tang	local id=$2
36934aa6e3bSGeliang Tang	local addr=$3
37034aa6e3bSGeliang Tang
37134aa6e3bSGeliang Tang	if [ $ip_mptcp -eq 1 ]; then
37234aa6e3bSGeliang Tang		ip -n $ns mptcp endpoint delete id $id $addr
37334aa6e3bSGeliang Tang	else
37434aa6e3bSGeliang Tang		ip netns exec $ns ./pm_nl_ctl del $id $addr
37534aa6e3bSGeliang Tang	fi
37634aa6e3bSGeliang Tang}
37734aa6e3bSGeliang Tang
37834aa6e3bSGeliang Tangpm_nl_flush_endpoint()
37934aa6e3bSGeliang Tang{
38034aa6e3bSGeliang Tang	local ns=$1
38134aa6e3bSGeliang Tang
38234aa6e3bSGeliang Tang	if [ $ip_mptcp -eq 1 ]; then
38334aa6e3bSGeliang Tang		ip -n $ns mptcp endpoint flush
38434aa6e3bSGeliang Tang	else
38534aa6e3bSGeliang Tang		ip netns exec $ns ./pm_nl_ctl flush
38634aa6e3bSGeliang Tang	fi
38734aa6e3bSGeliang Tang}
38834aa6e3bSGeliang Tang
389dda61b3dSGeliang Tangpm_nl_show_endpoints()
390dda61b3dSGeliang Tang{
391dda61b3dSGeliang Tang	local ns=$1
392dda61b3dSGeliang Tang
393dda61b3dSGeliang Tang	if [ $ip_mptcp -eq 1 ]; then
394dda61b3dSGeliang Tang		ip -n $ns mptcp endpoint show
395dda61b3dSGeliang Tang	else
396dda61b3dSGeliang Tang		ip netns exec $ns ./pm_nl_ctl dump
397dda61b3dSGeliang Tang	fi
398dda61b3dSGeliang Tang}
399dda61b3dSGeliang Tang
400f0140386SGeliang Tangpm_nl_change_endpoint()
401f0140386SGeliang Tang{
402f0140386SGeliang Tang	local ns=$1
403bccefb76SGeliang Tang	local id=$2
404bccefb76SGeliang Tang	local flags=$3
405f0140386SGeliang Tang
406f0140386SGeliang Tang	if [ $ip_mptcp -eq 1 ]; then
407f0140386SGeliang Tang		ip -n $ns mptcp endpoint change id $id ${flags//","/" "}
408f0140386SGeliang Tang	else
409bccefb76SGeliang Tang		ip netns exec $ns ./pm_nl_ctl set id $id flags $flags
410f0140386SGeliang Tang	fi
411f0140386SGeliang Tang}
412f0140386SGeliang Tang
413b08fbf24SPaolo Abenido_transfer()
414b08fbf24SPaolo Abeni{
415b08fbf24SPaolo Abeni	listener_ns="$1"
416b08fbf24SPaolo Abeni	connector_ns="$2"
417b08fbf24SPaolo Abeni	cl_proto="$3"
418b08fbf24SPaolo Abeni	srv_proto="$4"
419b08fbf24SPaolo Abeni	connect_addr="$5"
4208b819a84SFlorian Westphal	test_link_fail="$6"
4212e8cbf45SGeliang Tang	addr_nr_ns1="$7"
4222e8cbf45SGeliang Tang	addr_nr_ns2="$8"
4238b819a84SFlorian Westphal	speed="$9"
4246a0653b9SGeliang Tang	sflags="${10}"
425b08fbf24SPaolo Abeni
426b08fbf24SPaolo Abeni	port=$((10000+$TEST_COUNT))
427b08fbf24SPaolo Abeni	TEST_COUNT=$((TEST_COUNT+1))
428b08fbf24SPaolo Abeni
429b08fbf24SPaolo Abeni	:> "$cout"
430b08fbf24SPaolo Abeni	:> "$sout"
431b08fbf24SPaolo Abeni	:> "$capout"
432b08fbf24SPaolo Abeni
433b08fbf24SPaolo Abeni	if [ $capture -eq 1 ]; then
434b08fbf24SPaolo Abeni		if [ -z $SUDO_USER ] ; then
435b08fbf24SPaolo Abeni			capuser=""
436b08fbf24SPaolo Abeni		else
437b08fbf24SPaolo Abeni			capuser="-Z $SUDO_USER"
438b08fbf24SPaolo Abeni		fi
439b08fbf24SPaolo Abeni
44000587187SFlorian Westphal		capfile=$(printf "mp_join-%02u-%s.pcap" "$TEST_COUNT" "${listener_ns}")
441b08fbf24SPaolo Abeni
442b08fbf24SPaolo Abeni		echo "Capturing traffic for test $TEST_COUNT into $capfile"
443b08fbf24SPaolo Abeni		ip netns exec ${listener_ns} tcpdump -i any -s 65535 -B 32768 $capuser -w $capfile > "$capout" 2>&1 &
444b08fbf24SPaolo Abeni		cappid=$!
445b08fbf24SPaolo Abeni
446b08fbf24SPaolo Abeni		sleep 1
447b08fbf24SPaolo Abeni	fi
448b08fbf24SPaolo Abeni
449c2a55e8fSMatthieu Baerts	NSTAT_HISTORY=/tmp/${listener_ns}.nstat ip netns exec ${listener_ns} \
450c2a55e8fSMatthieu Baerts		nstat -n
451c2a55e8fSMatthieu Baerts	NSTAT_HISTORY=/tmp/${connector_ns}.nstat ip netns exec ${connector_ns} \
452c2a55e8fSMatthieu Baerts		nstat -n
453c2a55e8fSMatthieu Baerts
454cbfafac4SGeliang Tang	local extra_args
4558d014eaaSGeliang Tang	if [ $speed = "fast" ]; then
456cbfafac4SGeliang Tang		extra_args="-j"
4578da6229bSGeliang Tang	elif [ $speed = "slow" ]; then
458cbfafac4SGeliang Tang		extra_args="-r 50"
459cbfafac4SGeliang Tang	elif [[ $speed = "speed_"* ]]; then
460cbfafac4SGeliang Tang		extra_args="-r ${speed:6}"
461dd72b0feSGeliang Tang	fi
462dd72b0feSGeliang Tang
46301542c9bSGeliang Tang	if [[ "${addr_nr_ns2}" = "fastclose_"* ]]; then
46401542c9bSGeliang Tang		# disconnect
46501542c9bSGeliang Tang		extra_args="$extra_args -I ${addr_nr_ns2:10}"
46601542c9bSGeliang Tang		addr_nr_ns2=0
46701542c9bSGeliang Tang	fi
46801542c9bSGeliang Tang
469523514edSGeliang Tang	local local_addr
470523514edSGeliang Tang	if is_v6 "${connect_addr}"; then
471523514edSGeliang Tang		local_addr="::"
472523514edSGeliang Tang	else
473523514edSGeliang Tang		local_addr="0.0.0.0"
474523514edSGeliang Tang	fi
475523514edSGeliang Tang
47634b572b7SGeliang Tang	if [ "$test_link_fail" -gt 1 ];then
4777d1e6f16SPaolo Abeni		timeout ${timeout_test} \
4787d1e6f16SPaolo Abeni			ip netns exec ${listener_ns} \
479cbfafac4SGeliang Tang				./mptcp_connect -t ${timeout_poll} -l -p $port -s ${srv_proto} \
480cbfafac4SGeliang Tang					$extra_args ${local_addr} < "$sinfail" > "$sout" &
4817d1e6f16SPaolo Abeni	else
4825888a61cSMatthieu Baerts		timeout ${timeout_test} \
4835888a61cSMatthieu Baerts			ip netns exec ${listener_ns} \
484cbfafac4SGeliang Tang				./mptcp_connect -t ${timeout_poll} -l -p $port -s ${srv_proto} \
485cbfafac4SGeliang Tang					$extra_args ${local_addr} < "$sin" > "$sout" &
4867d1e6f16SPaolo Abeni	fi
487b08fbf24SPaolo Abeni	spid=$!
488b08fbf24SPaolo Abeni
489327b9a94SPaolo Abeni	wait_local_port_listen "${listener_ns}" "${port}"
490b08fbf24SPaolo Abeni
4918b819a84SFlorian Westphal	if [ "$test_link_fail" -eq 0 ];then
4925888a61cSMatthieu Baerts		timeout ${timeout_test} \
4935888a61cSMatthieu Baerts			ip netns exec ${connector_ns} \
494cbfafac4SGeliang Tang				./mptcp_connect -t ${timeout_poll} -p $port -s ${cl_proto} \
495cbfafac4SGeliang Tang					$extra_args $connect_addr < "$cin" > "$cout" &
49634b572b7SGeliang Tang	elif [ "$test_link_fail" -eq 1 ] || [ "$test_link_fail" -eq 2 ];then
4977d1e6f16SPaolo Abeni		( cat "$cinfail" ; sleep 2; link_failure $listener_ns ; cat "$cinfail" ) | \
4985888a61cSMatthieu Baerts			tee "$cinsent" | \
4995888a61cSMatthieu Baerts			timeout ${timeout_test} \
5005888a61cSMatthieu Baerts				ip netns exec ${connector_ns} \
501cbfafac4SGeliang Tang					./mptcp_connect -t ${timeout_poll} -p $port -s ${cl_proto} \
502cbfafac4SGeliang Tang						$extra_args $connect_addr > "$cout" &
50334b572b7SGeliang Tang	else
50434b572b7SGeliang Tang		cat "$cinfail" | tee "$cinsent" | \
50534b572b7SGeliang Tang			timeout ${timeout_test} \
50634b572b7SGeliang Tang				ip netns exec ${connector_ns} \
50734b572b7SGeliang Tang					./mptcp_connect -t ${timeout_poll} -p $port -s ${cl_proto} \
50834b572b7SGeliang Tang						$extra_args $connect_addr > "$cout" &
5098b819a84SFlorian Westphal	fi
510b08fbf24SPaolo Abeni	cpid=$!
511b08fbf24SPaolo Abeni
512327b9a94SPaolo Abeni	# let the mptcp subflow be established in background before
513327b9a94SPaolo Abeni	# do endpoint manipulation
514327b9a94SPaolo Abeni	[ $addr_nr_ns1 = "0" -a $addr_nr_ns2 = "0" ] || sleep 1
515327b9a94SPaolo Abeni
5166208fd82SGeliang Tang	if [ $addr_nr_ns1 -gt 0 ]; then
5176208fd82SGeliang Tang		let add_nr_ns1=addr_nr_ns1
5186208fd82SGeliang Tang		counter=2
5196208fd82SGeliang Tang		while [ $add_nr_ns1 -gt 0 ]; do
5206208fd82SGeliang Tang			local addr
5216208fd82SGeliang Tang			if is_v6 "${connect_addr}"; then
5226208fd82SGeliang Tang				addr="dead:beef:$counter::1"
5236208fd82SGeliang Tang			else
5246208fd82SGeliang Tang				addr="10.0.$counter.1"
5256208fd82SGeliang Tang			fi
52634aa6e3bSGeliang Tang			pm_nl_add_endpoint $ns1 $addr flags signal
5276208fd82SGeliang Tang			let counter+=1
5286208fd82SGeliang Tang			let add_nr_ns1-=1
5296208fd82SGeliang Tang		done
5306208fd82SGeliang Tang	elif [ $addr_nr_ns1 -lt 0 ]; then
5312e8cbf45SGeliang Tang		let rm_nr_ns1=-addr_nr_ns1
5326fe4ccdcSGeliang Tang		if [ $rm_nr_ns1 -lt 8 ]; then
533dda61b3dSGeliang Tang			counter=0
534dda61b3dSGeliang Tang			pm_nl_show_endpoints ${listener_ns} | while read line; do
535dda61b3dSGeliang Tang				local arr=($line)
536dda61b3dSGeliang Tang				local nr=0
537dda61b3dSGeliang Tang
538dda61b3dSGeliang Tang				for i in ${arr[@]}; do
539dda61b3dSGeliang Tang					if [ $i = "id" ]; then
540dda61b3dSGeliang Tang						if [ $counter -eq $rm_nr_ns1 ]; then
541dda61b3dSGeliang Tang							break
542dda61b3dSGeliang Tang						fi
543dda61b3dSGeliang Tang						id=${arr[$nr+1]}
544327b9a94SPaolo Abeni						rm_addr=$(rm_addr_count ${connector_ns})
54534aa6e3bSGeliang Tang						pm_nl_del_endpoint ${listener_ns} $id
546327b9a94SPaolo Abeni						wait_rm_addr ${connector_ns} ${rm_addr}
547dd72b0feSGeliang Tang						let counter+=1
548f87744adSGeliang Tang					fi
549dda61b3dSGeliang Tang					let nr+=1
550dda61b3dSGeliang Tang				done
551dda61b3dSGeliang Tang			done
5525e287fe7SGeliang Tang		elif [ $rm_nr_ns1 -eq 8 ]; then
55334aa6e3bSGeliang Tang			pm_nl_flush_endpoint ${listener_ns}
5545e287fe7SGeliang Tang		elif [ $rm_nr_ns1 -eq 9 ]; then
55534aa6e3bSGeliang Tang			pm_nl_del_endpoint ${listener_ns} 0 ${connect_addr}
5566fe4ccdcSGeliang Tang		fi
557dd72b0feSGeliang Tang	fi
558dd72b0feSGeliang Tang
5594f49d633SGeliang Tang	flags="subflow"
5604f49d633SGeliang Tang	if [[ "${addr_nr_ns2}" = "fullmesh_"* ]]; then
5614f49d633SGeliang Tang		flags="${flags},fullmesh"
5624f49d633SGeliang Tang		addr_nr_ns2=${addr_nr_ns2:9}
5634f49d633SGeliang Tang	fi
5644f49d633SGeliang Tang
565327b9a94SPaolo Abeni	# if newly added endpoints must be deleted, give the background msk
566327b9a94SPaolo Abeni	# some time to created them
567327b9a94SPaolo Abeni	[ $addr_nr_ns1 -gt 0 -a $addr_nr_ns2 -lt 0 ] && sleep 1
568327b9a94SPaolo Abeni
5696208fd82SGeliang Tang	if [ $addr_nr_ns2 -gt 0 ]; then
5706208fd82SGeliang Tang		let add_nr_ns2=addr_nr_ns2
5716208fd82SGeliang Tang		counter=3
5726208fd82SGeliang Tang		while [ $add_nr_ns2 -gt 0 ]; do
5736208fd82SGeliang Tang			local addr
5746208fd82SGeliang Tang			if is_v6 "${connect_addr}"; then
5756208fd82SGeliang Tang				addr="dead:beef:$counter::2"
5766208fd82SGeliang Tang			else
5776208fd82SGeliang Tang				addr="10.0.$counter.2"
5786208fd82SGeliang Tang			fi
57934aa6e3bSGeliang Tang			pm_nl_add_endpoint $ns2 $addr flags $flags
5806208fd82SGeliang Tang			let counter+=1
5816208fd82SGeliang Tang			let add_nr_ns2-=1
5826208fd82SGeliang Tang		done
5836208fd82SGeliang Tang	elif [ $addr_nr_ns2 -lt 0 ]; then
5842e8cbf45SGeliang Tang		let rm_nr_ns2=-addr_nr_ns2
5856fe4ccdcSGeliang Tang		if [ $rm_nr_ns2 -lt 8 ]; then
586dda61b3dSGeliang Tang			counter=0
587dda61b3dSGeliang Tang			pm_nl_show_endpoints ${connector_ns} | while read line; do
588dda61b3dSGeliang Tang				local arr=($line)
589dda61b3dSGeliang Tang				local nr=0
590dda61b3dSGeliang Tang
591dda61b3dSGeliang Tang				for i in ${arr[@]}; do
592dda61b3dSGeliang Tang					if [ $i = "id" ]; then
593dda61b3dSGeliang Tang						if [ $counter -eq $rm_nr_ns2 ]; then
594dda61b3dSGeliang Tang							break
595dda61b3dSGeliang Tang						fi
596dda61b3dSGeliang Tang						# rm_addr are serialized, allow the previous one to
597dda61b3dSGeliang Tang						# complete
598dda61b3dSGeliang Tang						id=${arr[$nr+1]}
599327b9a94SPaolo Abeni						rm_addr=$(rm_addr_count ${listener_ns})
60034aa6e3bSGeliang Tang						pm_nl_del_endpoint ${connector_ns} $id
601327b9a94SPaolo Abeni						wait_rm_addr ${listener_ns} ${rm_addr}
602dd72b0feSGeliang Tang						let counter+=1
603f87744adSGeliang Tang					fi
604dda61b3dSGeliang Tang					let nr+=1
605dda61b3dSGeliang Tang				done
606dda61b3dSGeliang Tang			done
6075e287fe7SGeliang Tang		elif [ $rm_nr_ns2 -eq 8 ]; then
60834aa6e3bSGeliang Tang			pm_nl_flush_endpoint ${connector_ns}
6095e287fe7SGeliang Tang		elif [ $rm_nr_ns2 -eq 9 ]; then
6105e287fe7SGeliang Tang			local addr
6115e287fe7SGeliang Tang			if is_v6 "${connect_addr}"; then
6125e287fe7SGeliang Tang				addr="dead:beef:1::2"
6135e287fe7SGeliang Tang			else
6145e287fe7SGeliang Tang				addr="10.0.1.2"
6155e287fe7SGeliang Tang			fi
61634aa6e3bSGeliang Tang			pm_nl_del_endpoint ${connector_ns} 0 $addr
6176fe4ccdcSGeliang Tang		fi
618dd72b0feSGeliang Tang	fi
619dd72b0feSGeliang Tang
6206a0653b9SGeliang Tang	if [ ! -z $sflags ]; then
621718eb44eSGeliang Tang		sleep 1
622718eb44eSGeliang Tang		for netns in "$ns1" "$ns2"; do
623dda61b3dSGeliang Tang			pm_nl_show_endpoints $netns | while read line; do
62433397b83SGeliang Tang				local arr=($line)
625bccefb76SGeliang Tang				local nr=0
626f0140386SGeliang Tang				local id
62733397b83SGeliang Tang
62833397b83SGeliang Tang				for i in ${arr[@]}; do
629bccefb76SGeliang Tang					if [ $i = "id" ]; then
630bccefb76SGeliang Tang						id=${arr[$nr+1]}
631718eb44eSGeliang Tang					fi
632bccefb76SGeliang Tang					let nr+=1
63333397b83SGeliang Tang				done
634bccefb76SGeliang Tang				pm_nl_change_endpoint $netns $id $sflags
63533397b83SGeliang Tang			done
636718eb44eSGeliang Tang		done
637718eb44eSGeliang Tang	fi
638718eb44eSGeliang Tang
639b08fbf24SPaolo Abeni	wait $cpid
640b08fbf24SPaolo Abeni	retc=$?
641b08fbf24SPaolo Abeni	wait $spid
642b08fbf24SPaolo Abeni	rets=$?
643b08fbf24SPaolo Abeni
644b08fbf24SPaolo Abeni	if [ $capture -eq 1 ]; then
645b08fbf24SPaolo Abeni	    sleep 1
646b08fbf24SPaolo Abeni	    kill $cappid
647b08fbf24SPaolo Abeni	fi
648b08fbf24SPaolo Abeni
649c2a55e8fSMatthieu Baerts	NSTAT_HISTORY=/tmp/${listener_ns}.nstat ip netns exec ${listener_ns} \
650c2a55e8fSMatthieu Baerts		nstat | grep Tcp > /tmp/${listener_ns}.out
651c2a55e8fSMatthieu Baerts	NSTAT_HISTORY=/tmp/${connector_ns}.nstat ip netns exec ${connector_ns} \
652c2a55e8fSMatthieu Baerts		nstat | grep Tcp > /tmp/${connector_ns}.out
653c2a55e8fSMatthieu Baerts
654b08fbf24SPaolo Abeni	if [ ${rets} -ne 0 ] || [ ${retc} -ne 0 ]; then
655b08fbf24SPaolo Abeni		echo " client exit code $retc, server $rets" 1>&2
6568b974778SMatthieu Baerts		echo -e "\nnetns ${listener_ns} socket stat for ${port}:" 1>&2
657c2a55e8fSMatthieu Baerts		ip netns exec ${listener_ns} ss -Menita 1>&2 -o "sport = :$port"
658c2a55e8fSMatthieu Baerts		cat /tmp/${listener_ns}.out
6598b974778SMatthieu Baerts		echo -e "\nnetns ${connector_ns} socket stat for ${port}:" 1>&2
660c2a55e8fSMatthieu Baerts		ip netns exec ${connector_ns} ss -Menita 1>&2 -o "dport = :$port"
661c2a55e8fSMatthieu Baerts		cat /tmp/${connector_ns}.out
662b08fbf24SPaolo Abeni
663b08fbf24SPaolo Abeni		cat "$capout"
6648b819a84SFlorian Westphal		ret=1
665b08fbf24SPaolo Abeni		return 1
666b08fbf24SPaolo Abeni	fi
667b08fbf24SPaolo Abeni
66834b572b7SGeliang Tang	if [ "$test_link_fail" -gt 1 ];then
6697d1e6f16SPaolo Abeni		check_transfer $sinfail $cout "file received by client"
6707d1e6f16SPaolo Abeni	else
671b08fbf24SPaolo Abeni		check_transfer $sin $cout "file received by client"
6727d1e6f16SPaolo Abeni	fi
673b08fbf24SPaolo Abeni	retc=$?
6748b819a84SFlorian Westphal	if [ "$test_link_fail" -eq 0 ];then
675b08fbf24SPaolo Abeni		check_transfer $cin $sout "file received by server"
6768b819a84SFlorian Westphal	else
6778b819a84SFlorian Westphal		check_transfer $cinsent $sout "file received by server"
6788b819a84SFlorian Westphal	fi
679b08fbf24SPaolo Abeni	rets=$?
680b08fbf24SPaolo Abeni
681b08fbf24SPaolo Abeni	if [ $retc -eq 0 ] && [ $rets -eq 0 ];then
682b08fbf24SPaolo Abeni		cat "$capout"
683b08fbf24SPaolo Abeni		return 0
684b08fbf24SPaolo Abeni	fi
685b08fbf24SPaolo Abeni
686b08fbf24SPaolo Abeni	cat "$capout"
687b08fbf24SPaolo Abeni	return 1
688b08fbf24SPaolo Abeni}
689b08fbf24SPaolo Abeni
690b08fbf24SPaolo Abenimake_file()
691b08fbf24SPaolo Abeni{
692b08fbf24SPaolo Abeni	name=$1
693b08fbf24SPaolo Abeni	who=$2
6948b819a84SFlorian Westphal	size=$3
695b08fbf24SPaolo Abeni
6968b819a84SFlorian Westphal	dd if=/dev/urandom of="$name" bs=1024 count=$size 2> /dev/null
697b08fbf24SPaolo Abeni	echo -e "\nMPTCP_TEST_FILE_END_MARKER" >> "$name"
698b08fbf24SPaolo Abeni
6998b819a84SFlorian Westphal	echo "Created $name (size $size KB) containing data sent by $who"
700b08fbf24SPaolo Abeni}
701b08fbf24SPaolo Abeni
702b08fbf24SPaolo Abenirun_tests()
703b08fbf24SPaolo Abeni{
704b08fbf24SPaolo Abeni	listener_ns="$1"
705b08fbf24SPaolo Abeni	connector_ns="$2"
706b08fbf24SPaolo Abeni	connect_addr="$3"
7078b819a84SFlorian Westphal	test_linkfail="${4:-0}"
7082e8cbf45SGeliang Tang	addr_nr_ns1="${5:-0}"
7092e8cbf45SGeliang Tang	addr_nr_ns2="${6:-0}"
7108b819a84SFlorian Westphal	speed="${7:-fast}"
7116a0653b9SGeliang Tang	sflags="${8:-""}"
7128b819a84SFlorian Westphal
71334b572b7SGeliang Tang	# The values above 2 are reused to make test files
71434b572b7SGeliang Tang	# with the given sizes (KB)
71534b572b7SGeliang Tang	if [ "$test_linkfail" -gt 2 ]; then
71634b572b7SGeliang Tang		size=$test_linkfail
71734b572b7SGeliang Tang
71834b572b7SGeliang Tang		if [ -z "$cinfail" ]; then
71934b572b7SGeliang Tang			cinfail=$(mktemp)
72034b572b7SGeliang Tang		fi
72134b572b7SGeliang Tang		make_file "$cinfail" "client" $size
7227d1e6f16SPaolo Abeni	# create the input file for the failure test when
7237d1e6f16SPaolo Abeni	# the first failure test run
72434b572b7SGeliang Tang	elif [ "$test_linkfail" -ne 0 -a -z "$cinfail" ]; then
7257d1e6f16SPaolo Abeni		# the client file must be considerably larger
7267d1e6f16SPaolo Abeni		# of the maximum expected cwin value, or the
7277d1e6f16SPaolo Abeni		# link utilization will be not predicable
7287d1e6f16SPaolo Abeni		size=$((RANDOM%2))
7298b819a84SFlorian Westphal		size=$((size+1))
7307d1e6f16SPaolo Abeni		size=$((size*8192))
7317d1e6f16SPaolo Abeni		size=$((size + ( $RANDOM % 8192) ))
7328b819a84SFlorian Westphal
7337d1e6f16SPaolo Abeni		cinfail=$(mktemp)
7347d1e6f16SPaolo Abeni		make_file "$cinfail" "client" $size
7357d1e6f16SPaolo Abeni	fi
7367d1e6f16SPaolo Abeni
73734b572b7SGeliang Tang	if [ "$test_linkfail" -gt 2 ]; then
73834b572b7SGeliang Tang		size=$test_linkfail
73934b572b7SGeliang Tang
74034b572b7SGeliang Tang		if [ -z "$sinfail" ]; then
74134b572b7SGeliang Tang			sinfail=$(mktemp)
74234b572b7SGeliang Tang		fi
74334b572b7SGeliang Tang		make_file "$sinfail" "server" $size
74434b572b7SGeliang Tang	elif [ "$test_linkfail" -eq 2 -a -z "$sinfail" ]; then
7457d1e6f16SPaolo Abeni		size=$((RANDOM%16))
7467d1e6f16SPaolo Abeni		size=$((size+1))
7477d1e6f16SPaolo Abeni		size=$((size*2048))
7487d1e6f16SPaolo Abeni
7497d1e6f16SPaolo Abeni		sinfail=$(mktemp)
7507d1e6f16SPaolo Abeni		make_file "$sinfail" "server" $size
7518b819a84SFlorian Westphal	fi
752b08fbf24SPaolo Abeni
7538d014eaaSGeliang Tang	do_transfer ${listener_ns} ${connector_ns} MPTCP MPTCP ${connect_addr} \
7546a0653b9SGeliang Tang		${test_linkfail} ${addr_nr_ns1} ${addr_nr_ns2} ${speed} ${sflags}
755b08fbf24SPaolo Abeni}
756b08fbf24SPaolo Abeni
757327b9a94SPaolo Abenidump_stats()
758327b9a94SPaolo Abeni{
759327b9a94SPaolo Abeni	echo Server ns stats
760327b9a94SPaolo Abeni	ip netns exec $ns1 nstat -as | grep Tcp
761327b9a94SPaolo Abeni	echo Client ns stats
762327b9a94SPaolo Abeni	ip netns exec $ns2 nstat -as | grep Tcp
763327b9a94SPaolo Abeni}
764327b9a94SPaolo Abeni
765af66d3e1SGeliang Tangchk_csum_nr()
766af66d3e1SGeliang Tang{
767af66d3e1SGeliang Tang	local msg=${1:-""}
76826516e10SGeliang Tang	local csum_ns1=${2:-0}
76926516e10SGeliang Tang	local csum_ns2=${3:-0}
770af66d3e1SGeliang Tang	local count
771af66d3e1SGeliang Tang	local dump_stats
77226516e10SGeliang Tang	local allow_multi_errors_ns1=0
77326516e10SGeliang Tang	local allow_multi_errors_ns2=0
77426516e10SGeliang Tang
77526516e10SGeliang Tang	if [[ "${csum_ns1}" = "+"* ]]; then
77626516e10SGeliang Tang		allow_multi_errors_ns1=1
77726516e10SGeliang Tang		csum_ns1=${csum_ns1:1}
77826516e10SGeliang Tang	fi
77926516e10SGeliang Tang	if [[ "${csum_ns2}" = "+"* ]]; then
78026516e10SGeliang Tang		allow_multi_errors_ns2=1
78126516e10SGeliang Tang		csum_ns2=${csum_ns2:1}
78226516e10SGeliang Tang	fi
783af66d3e1SGeliang Tang
784af66d3e1SGeliang Tang	if [ ! -z "$msg" ]; then
7859a0a9367SGeliang Tang		printf "%03u" "$TEST_COUNT"
786af66d3e1SGeliang Tang	else
787af66d3e1SGeliang Tang		echo -n "   "
788af66d3e1SGeliang Tang	fi
789af66d3e1SGeliang Tang	printf " %-36s %s" "$msg" "sum"
790af66d3e1SGeliang Tang	count=`ip netns exec $ns1 nstat -as | grep MPTcpExtDataCsumErr | awk '{print $2}'`
791af66d3e1SGeliang Tang	[ -z "$count" ] && count=0
79226516e10SGeliang Tang	if [ "$count" != $csum_ns1 -a $allow_multi_errors_ns1 -eq 0 ] ||
79326516e10SGeliang Tang	   [ "$count" -lt $csum_ns1 -a $allow_multi_errors_ns1 -eq 1 ]; then
79426516e10SGeliang Tang		echo "[fail] got $count data checksum error[s] expected $csum_ns1"
795af66d3e1SGeliang Tang		ret=1
796af66d3e1SGeliang Tang		dump_stats=1
797af66d3e1SGeliang Tang	else
798af66d3e1SGeliang Tang		echo -n "[ ok ]"
799af66d3e1SGeliang Tang	fi
800af66d3e1SGeliang Tang	echo -n " - csum  "
801af66d3e1SGeliang Tang	count=`ip netns exec $ns2 nstat -as | grep MPTcpExtDataCsumErr | awk '{print $2}'`
802af66d3e1SGeliang Tang	[ -z "$count" ] && count=0
80326516e10SGeliang Tang	if [ "$count" != $csum_ns2 -a $allow_multi_errors_ns2 -eq 0 ] ||
80426516e10SGeliang Tang	   [ "$count" -lt $csum_ns2 -a $allow_multi_errors_ns2 -eq 1 ]; then
80526516e10SGeliang Tang		echo "[fail] got $count data checksum error[s] expected $csum_ns2"
806af66d3e1SGeliang Tang		ret=1
807af66d3e1SGeliang Tang		dump_stats=1
808af66d3e1SGeliang Tang	else
809af66d3e1SGeliang Tang		echo "[ ok ]"
810af66d3e1SGeliang Tang	fi
811327b9a94SPaolo Abeni	[ "${dump_stats}" = 1 ] && dump_stats
812af66d3e1SGeliang Tang}
813af66d3e1SGeliang Tang
8146bb3ab49SGeliang Tangchk_fail_nr()
8156bb3ab49SGeliang Tang{
81626516e10SGeliang Tang	local fail_tx=$1
81726516e10SGeliang Tang	local fail_rx=$2
8186bb3ab49SGeliang Tang	local count
8196bb3ab49SGeliang Tang	local dump_stats
8206bb3ab49SGeliang Tang
8219a0a9367SGeliang Tang	printf "%-${nr_blank}s %s" " " "ftx"
8226bb3ab49SGeliang Tang	count=`ip netns exec $ns1 nstat -as | grep MPTcpExtMPFailTx | awk '{print $2}'`
8236bb3ab49SGeliang Tang	[ -z "$count" ] && count=0
82426516e10SGeliang Tang	if [ "$count" != "$fail_tx" ]; then
82526516e10SGeliang Tang		echo "[fail] got $count MP_FAIL[s] TX expected $fail_tx"
8266bb3ab49SGeliang Tang		ret=1
8276bb3ab49SGeliang Tang		dump_stats=1
8286bb3ab49SGeliang Tang	else
8296bb3ab49SGeliang Tang		echo -n "[ ok ]"
8306bb3ab49SGeliang Tang	fi
8316bb3ab49SGeliang Tang
83226516e10SGeliang Tang	echo -n " - failrx"
8336bb3ab49SGeliang Tang	count=`ip netns exec $ns2 nstat -as | grep MPTcpExtMPFailRx | awk '{print $2}'`
8346bb3ab49SGeliang Tang	[ -z "$count" ] && count=0
83526516e10SGeliang Tang	if [ "$count" != "$fail_rx" ]; then
83626516e10SGeliang Tang		echo "[fail] got $count MP_FAIL[s] RX expected $fail_rx"
8376bb3ab49SGeliang Tang		ret=1
8386bb3ab49SGeliang Tang		dump_stats=1
8396bb3ab49SGeliang Tang	else
8406bb3ab49SGeliang Tang		echo "[ ok ]"
8416bb3ab49SGeliang Tang	fi
8426bb3ab49SGeliang Tang
843327b9a94SPaolo Abeni	[ "${dump_stats}" = 1 ] && dump_stats
8446bb3ab49SGeliang Tang}
8456bb3ab49SGeliang Tang
846e8e947efSGeliang Tangchk_fclose_nr()
847e8e947efSGeliang Tang{
848e8e947efSGeliang Tang	local fclose_tx=$1
849e8e947efSGeliang Tang	local fclose_rx=$2
850e8e947efSGeliang Tang	local count
851e8e947efSGeliang Tang	local dump_stats
852e8e947efSGeliang Tang
853e8e947efSGeliang Tang	printf "%-${nr_blank}s %s" " " "ctx"
854e8e947efSGeliang Tang	count=$(ip netns exec $ns2 nstat -as | grep MPTcpExtMPFastcloseTx | awk '{print $2}')
855e8e947efSGeliang Tang	[ -z "$count" ] && count=0
856e8e947efSGeliang Tang	if [ "$count" != "$fclose_tx" ]; then
857e8e947efSGeliang Tang		echo "[fail] got $count MP_FASTCLOSE[s] TX expected $fclose_tx"
858e8e947efSGeliang Tang		ret=1
859e8e947efSGeliang Tang		dump_stats=1
860e8e947efSGeliang Tang	else
861e8e947efSGeliang Tang		echo -n "[ ok ]"
862e8e947efSGeliang Tang	fi
863e8e947efSGeliang Tang
864e8e947efSGeliang Tang	echo -n " - fclzrx"
865e8e947efSGeliang Tang	count=$(ip netns exec $ns1 nstat -as | grep MPTcpExtMPFastcloseRx | awk '{print $2}')
866e8e947efSGeliang Tang	[ -z "$count" ] && count=0
867e8e947efSGeliang Tang	if [ "$count" != "$fclose_rx" ]; then
868e8e947efSGeliang Tang		echo "[fail] got $count MP_FASTCLOSE[s] RX expected $fclose_rx"
869e8e947efSGeliang Tang		ret=1
870e8e947efSGeliang Tang		dump_stats=1
871e8e947efSGeliang Tang	else
872e8e947efSGeliang Tang		echo "[ ok ]"
873e8e947efSGeliang Tang	fi
874e8e947efSGeliang Tang
875e8e947efSGeliang Tang	[ "${dump_stats}" = 1 ] && dump_stats
876e8e947efSGeliang Tang}
877e8e947efSGeliang Tang
878922fd2b3SGeliang Tangchk_rst_nr()
879922fd2b3SGeliang Tang{
880922fd2b3SGeliang Tang	local rst_tx=$1
881922fd2b3SGeliang Tang	local rst_rx=$2
882922fd2b3SGeliang Tang	local ns_invert=${3:-""}
883922fd2b3SGeliang Tang	local count
884922fd2b3SGeliang Tang	local dump_stats
885922fd2b3SGeliang Tang	local ns_tx=$ns1
886922fd2b3SGeliang Tang	local ns_rx=$ns2
887922fd2b3SGeliang Tang	local extra_msg=""
888922fd2b3SGeliang Tang
889922fd2b3SGeliang Tang	if [[ $ns_invert = "invert" ]]; then
890922fd2b3SGeliang Tang		ns_tx=$ns2
891922fd2b3SGeliang Tang		ns_rx=$ns1
892922fd2b3SGeliang Tang		extra_msg="   invert"
893922fd2b3SGeliang Tang	fi
894922fd2b3SGeliang Tang
895922fd2b3SGeliang Tang	printf "%-${nr_blank}s %s" " " "rtx"
896922fd2b3SGeliang Tang	count=$(ip netns exec $ns_tx nstat -as | grep MPTcpExtMPRstTx | awk '{print $2}')
897922fd2b3SGeliang Tang	[ -z "$count" ] && count=0
898922fd2b3SGeliang Tang	if [ "$count" != "$rst_tx" ]; then
899922fd2b3SGeliang Tang		echo "[fail] got $count MP_RST[s] TX expected $rst_tx"
900922fd2b3SGeliang Tang		ret=1
901922fd2b3SGeliang Tang		dump_stats=1
902922fd2b3SGeliang Tang	else
903922fd2b3SGeliang Tang		echo -n "[ ok ]"
904922fd2b3SGeliang Tang	fi
905922fd2b3SGeliang Tang
906922fd2b3SGeliang Tang	echo -n " - rstrx "
907922fd2b3SGeliang Tang	count=$(ip netns exec $ns_rx nstat -as | grep MPTcpExtMPRstRx | awk '{print $2}')
908922fd2b3SGeliang Tang	[ -z "$count" ] && count=0
909922fd2b3SGeliang Tang	if [ "$count" != "$rst_rx" ]; then
910922fd2b3SGeliang Tang		echo "[fail] got $count MP_RST[s] RX expected $rst_rx"
911922fd2b3SGeliang Tang		ret=1
912922fd2b3SGeliang Tang		dump_stats=1
913922fd2b3SGeliang Tang	else
914922fd2b3SGeliang Tang		echo -n "[ ok ]"
915922fd2b3SGeliang Tang	fi
916922fd2b3SGeliang Tang
917922fd2b3SGeliang Tang	[ "${dump_stats}" = 1 ] && dump_stats
918922fd2b3SGeliang Tang
919922fd2b3SGeliang Tang	echo "$extra_msg"
920922fd2b3SGeliang Tang}
921922fd2b3SGeliang Tang
922b08fbf24SPaolo Abenichk_join_nr()
923b08fbf24SPaolo Abeni{
924b08fbf24SPaolo Abeni	local msg="$1"
925b08fbf24SPaolo Abeni	local syn_nr=$2
926b08fbf24SPaolo Abeni	local syn_ack_nr=$3
927b08fbf24SPaolo Abeni	local ack_nr=$4
92826516e10SGeliang Tang	local csum_ns1=${5:-0}
92926516e10SGeliang Tang	local csum_ns2=${6:-0}
93026516e10SGeliang Tang	local fail_nr=${7:-0}
93126516e10SGeliang Tang	local rst_nr=${8:-0}
932b08fbf24SPaolo Abeni	local count
933b08fbf24SPaolo Abeni	local dump_stats
934e35f885bSPaolo Abeni	local with_cookie
935b08fbf24SPaolo Abeni
9369a0a9367SGeliang Tang	printf "%03u %-36s %s" "$TEST_COUNT" "$msg" "syn"
937b08fbf24SPaolo Abeni	count=`ip netns exec $ns1 nstat -as | grep MPTcpExtMPJoinSynRx | awk '{print $2}'`
938b08fbf24SPaolo Abeni	[ -z "$count" ] && count=0
939b08fbf24SPaolo Abeni	if [ "$count" != "$syn_nr" ]; then
940b08fbf24SPaolo Abeni		echo "[fail] got $count JOIN[s] syn expected $syn_nr"
941b08fbf24SPaolo Abeni		ret=1
942b08fbf24SPaolo Abeni		dump_stats=1
943b08fbf24SPaolo Abeni	else
944b08fbf24SPaolo Abeni		echo -n "[ ok ]"
945b08fbf24SPaolo Abeni	fi
946b08fbf24SPaolo Abeni
947b08fbf24SPaolo Abeni	echo -n " - synack"
948e35f885bSPaolo Abeni	with_cookie=`ip netns exec $ns2 sysctl -n net.ipv4.tcp_syncookies`
949b08fbf24SPaolo Abeni	count=`ip netns exec $ns2 nstat -as | grep MPTcpExtMPJoinSynAckRx | awk '{print $2}'`
950b08fbf24SPaolo Abeni	[ -z "$count" ] && count=0
951b08fbf24SPaolo Abeni	if [ "$count" != "$syn_ack_nr" ]; then
952e35f885bSPaolo Abeni		# simult connections exceeding the limit with cookie enabled could go up to
953e35f885bSPaolo Abeni		# synack validation as the conn limit can be enforced reliably only after
954e35f885bSPaolo Abeni		# the subflow creation
955e35f885bSPaolo Abeni		if [ "$with_cookie" = 2 ] && [ "$count" -gt "$syn_ack_nr" ] && [ "$count" -le "$syn_nr" ]; then
956e35f885bSPaolo Abeni			echo -n "[ ok ]"
957e35f885bSPaolo Abeni		else
958b08fbf24SPaolo Abeni			echo "[fail] got $count JOIN[s] synack expected $syn_ack_nr"
959b08fbf24SPaolo Abeni			ret=1
960b08fbf24SPaolo Abeni			dump_stats=1
961e35f885bSPaolo Abeni		fi
962b08fbf24SPaolo Abeni	else
963b08fbf24SPaolo Abeni		echo -n "[ ok ]"
964b08fbf24SPaolo Abeni	fi
965b08fbf24SPaolo Abeni
966b08fbf24SPaolo Abeni	echo -n " - ack"
967b08fbf24SPaolo Abeni	count=`ip netns exec $ns1 nstat -as | grep MPTcpExtMPJoinAckRx | awk '{print $2}'`
968b08fbf24SPaolo Abeni	[ -z "$count" ] && count=0
969b08fbf24SPaolo Abeni	if [ "$count" != "$ack_nr" ]; then
970b08fbf24SPaolo Abeni		echo "[fail] got $count JOIN[s] ack expected $ack_nr"
971b08fbf24SPaolo Abeni		ret=1
972b08fbf24SPaolo Abeni		dump_stats=1
973b08fbf24SPaolo Abeni	else
974b08fbf24SPaolo Abeni		echo "[ ok ]"
975b08fbf24SPaolo Abeni	fi
976327b9a94SPaolo Abeni	[ "${dump_stats}" = 1 ] && dump_stats
977af66d3e1SGeliang Tang	if [ $checksum -eq 1 ]; then
97826516e10SGeliang Tang		chk_csum_nr "" $csum_ns1 $csum_ns2
97926516e10SGeliang Tang		chk_fail_nr $fail_nr $fail_nr
98026516e10SGeliang Tang		chk_rst_nr $rst_nr $rst_nr
981af66d3e1SGeliang Tang	fi
982b08fbf24SPaolo Abeni}
983b08fbf24SPaolo Abeni
9847d1e6f16SPaolo Abeni# a negative value for 'stale_max' means no upper bound:
9857d1e6f16SPaolo Abeni# for bidirectional transfer, if one peer sleep for a while
9867d1e6f16SPaolo Abeni# - as these tests do - we can have a quite high number of
9877d1e6f16SPaolo Abeni# stale/recover conversions, proportional to
9887d1e6f16SPaolo Abeni# sleep duration/ MPTCP-level RTX interval.
9897d1e6f16SPaolo Abenichk_stale_nr()
9907d1e6f16SPaolo Abeni{
9917d1e6f16SPaolo Abeni	local ns=$1
9927d1e6f16SPaolo Abeni	local stale_min=$2
9937d1e6f16SPaolo Abeni	local stale_max=$3
9947d1e6f16SPaolo Abeni	local stale_delta=$4
9957d1e6f16SPaolo Abeni	local dump_stats
9967d1e6f16SPaolo Abeni	local stale_nr
9977d1e6f16SPaolo Abeni	local recover_nr
9987d1e6f16SPaolo Abeni
9999a0a9367SGeliang Tang	printf "%-${nr_blank}s %-18s" " " "stale"
10007d1e6f16SPaolo Abeni	stale_nr=`ip netns exec $ns nstat -as | grep MPTcpExtSubflowStale | awk '{print $2}'`
10017d1e6f16SPaolo Abeni	[ -z "$stale_nr" ] && stale_nr=0
10027d1e6f16SPaolo Abeni	recover_nr=`ip netns exec $ns nstat -as | grep MPTcpExtSubflowRecover | awk '{print $2}'`
10037d1e6f16SPaolo Abeni	[ -z "$recover_nr" ] && recover_nr=0
10047d1e6f16SPaolo Abeni
10057d1e6f16SPaolo Abeni	if [ $stale_nr -lt $stale_min ] ||
10067d1e6f16SPaolo Abeni	   [ $stale_max -gt 0 -a $stale_nr -gt $stale_max ] ||
10077d1e6f16SPaolo Abeni	   [ $((stale_nr - $recover_nr)) -ne $stale_delta ]; then
10087d1e6f16SPaolo Abeni		echo "[fail] got $stale_nr stale[s] $recover_nr recover[s], " \
10097d1e6f16SPaolo Abeni		     " expected stale in range [$stale_min..$stale_max]," \
10107d1e6f16SPaolo Abeni		     " stale-recover delta $stale_delta "
10117d1e6f16SPaolo Abeni		ret=1
10127d1e6f16SPaolo Abeni		dump_stats=1
10137d1e6f16SPaolo Abeni	else
10147d1e6f16SPaolo Abeni		echo "[ ok ]"
10157d1e6f16SPaolo Abeni	fi
10167d1e6f16SPaolo Abeni
10177d1e6f16SPaolo Abeni	if [ "${dump_stats}" = 1 ]; then
10187d1e6f16SPaolo Abeni		echo $ns stats
10197d1e6f16SPaolo Abeni		ip netns exec $ns ip -s link show
10207d1e6f16SPaolo Abeni		ip netns exec $ns nstat -as | grep MPTcp
10217d1e6f16SPaolo Abeni	fi
10227d1e6f16SPaolo Abeni}
10237d1e6f16SPaolo Abeni
1024be613160SGeliang Tangchk_add_nr()
1025be613160SGeliang Tang{
1026be613160SGeliang Tang	local add_nr=$1
1027be613160SGeliang Tang	local echo_nr=$2
10288a127bf6SGeliang Tang	local port_nr=${3:-0}
10298a127bf6SGeliang Tang	local syn_nr=${4:-$port_nr}
10308a127bf6SGeliang Tang	local syn_ack_nr=${5:-$port_nr}
10318a127bf6SGeliang Tang	local ack_nr=${6:-$port_nr}
10328a127bf6SGeliang Tang	local mis_syn_nr=${7:-0}
10338a127bf6SGeliang Tang	local mis_ack_nr=${8:-0}
1034be613160SGeliang Tang	local count
1035be613160SGeliang Tang	local dump_stats
10366ef84b15SPaolo Abeni	local timeout
10376ef84b15SPaolo Abeni
10386ef84b15SPaolo Abeni	timeout=`ip netns exec $ns1 sysctl -n net.mptcp.add_addr_timeout`
1039be613160SGeliang Tang
10409a0a9367SGeliang Tang	printf "%-${nr_blank}s %s" " " "add"
10416ef84b15SPaolo Abeni	count=`ip netns exec $ns2 nstat -as MPTcpExtAddAddr | grep MPTcpExtAddAddr | awk '{print $2}'`
1042be613160SGeliang Tang	[ -z "$count" ] && count=0
10436ef84b15SPaolo Abeni
10446ef84b15SPaolo Abeni	# if the test configured a short timeout tolerate greater then expected
10456ef84b15SPaolo Abeni	# add addrs options, due to retransmissions
10466ef84b15SPaolo Abeni	if [ "$count" != "$add_nr" ] && [ "$timeout" -gt 1 -o "$count" -lt "$add_nr" ]; then
1047be613160SGeliang Tang		echo "[fail] got $count ADD_ADDR[s] expected $add_nr"
1048be613160SGeliang Tang		ret=1
1049be613160SGeliang Tang		dump_stats=1
1050be613160SGeliang Tang	else
1051be613160SGeliang Tang		echo -n "[ ok ]"
1052be613160SGeliang Tang	fi
1053be613160SGeliang Tang
1054be613160SGeliang Tang	echo -n " - echo  "
1055be613160SGeliang Tang	count=`ip netns exec $ns1 nstat -as | grep MPTcpExtEchoAdd | awk '{print $2}'`
1056be613160SGeliang Tang	[ -z "$count" ] && count=0
1057be613160SGeliang Tang	if [ "$count" != "$echo_nr" ]; then
1058be613160SGeliang Tang		echo "[fail] got $count ADD_ADDR echo[s] expected $echo_nr"
1059be613160SGeliang Tang		ret=1
1060be613160SGeliang Tang		dump_stats=1
1061be613160SGeliang Tang	else
10628a127bf6SGeliang Tang		echo -n "[ ok ]"
10638a127bf6SGeliang Tang	fi
10648a127bf6SGeliang Tang
10658a127bf6SGeliang Tang	if [ $port_nr -gt 0 ]; then
10668a127bf6SGeliang Tang		echo -n " - pt "
10678a127bf6SGeliang Tang		count=`ip netns exec $ns2 nstat -as | grep MPTcpExtPortAdd | awk '{print $2}'`
10688a127bf6SGeliang Tang		[ -z "$count" ] && count=0
10698a127bf6SGeliang Tang		if [ "$count" != "$port_nr" ]; then
10708a127bf6SGeliang Tang			echo "[fail] got $count ADD_ADDR[s] with a port-number expected $port_nr"
10718a127bf6SGeliang Tang			ret=1
10728a127bf6SGeliang Tang			dump_stats=1
10738a127bf6SGeliang Tang		else
1074be613160SGeliang Tang			echo "[ ok ]"
1075be613160SGeliang Tang		fi
1076be613160SGeliang Tang
10779a0a9367SGeliang Tang		printf "%-${nr_blank}s %s" " " "syn"
10788a127bf6SGeliang Tang		count=`ip netns exec $ns1 nstat -as | grep MPTcpExtMPJoinPortSynRx |
10798a127bf6SGeliang Tang			awk '{print $2}'`
10808a127bf6SGeliang Tang		[ -z "$count" ] && count=0
10818a127bf6SGeliang Tang		if [ "$count" != "$syn_nr" ]; then
10828a127bf6SGeliang Tang			echo "[fail] got $count JOIN[s] syn with a different \
10838a127bf6SGeliang Tang				port-number expected $syn_nr"
10848a127bf6SGeliang Tang			ret=1
10858a127bf6SGeliang Tang			dump_stats=1
10868a127bf6SGeliang Tang		else
10878a127bf6SGeliang Tang			echo -n "[ ok ]"
10888a127bf6SGeliang Tang		fi
10898a127bf6SGeliang Tang
10908a127bf6SGeliang Tang		echo -n " - synack"
10918a127bf6SGeliang Tang		count=`ip netns exec $ns2 nstat -as | grep MPTcpExtMPJoinPortSynAckRx |
10928a127bf6SGeliang Tang			awk '{print $2}'`
10938a127bf6SGeliang Tang		[ -z "$count" ] && count=0
10948a127bf6SGeliang Tang		if [ "$count" != "$syn_ack_nr" ]; then
10958a127bf6SGeliang Tang			echo "[fail] got $count JOIN[s] synack with a different \
10968a127bf6SGeliang Tang				port-number expected $syn_ack_nr"
10978a127bf6SGeliang Tang			ret=1
10988a127bf6SGeliang Tang			dump_stats=1
10998a127bf6SGeliang Tang		else
11008a127bf6SGeliang Tang			echo -n "[ ok ]"
11018a127bf6SGeliang Tang		fi
11028a127bf6SGeliang Tang
11038a127bf6SGeliang Tang		echo -n " - ack"
11048a127bf6SGeliang Tang		count=`ip netns exec $ns1 nstat -as | grep MPTcpExtMPJoinPortAckRx |
11058a127bf6SGeliang Tang			awk '{print $2}'`
11068a127bf6SGeliang Tang		[ -z "$count" ] && count=0
11078a127bf6SGeliang Tang		if [ "$count" != "$ack_nr" ]; then
11088a127bf6SGeliang Tang			echo "[fail] got $count JOIN[s] ack with a different \
11098a127bf6SGeliang Tang				port-number expected $ack_nr"
11108a127bf6SGeliang Tang			ret=1
11118a127bf6SGeliang Tang			dump_stats=1
11128a127bf6SGeliang Tang		else
11138a127bf6SGeliang Tang			echo "[ ok ]"
11148a127bf6SGeliang Tang		fi
11158a127bf6SGeliang Tang
11169a0a9367SGeliang Tang		printf "%-${nr_blank}s %s" " " "syn"
11178a127bf6SGeliang Tang		count=`ip netns exec $ns1 nstat -as | grep MPTcpExtMismatchPortSynRx |
11188a127bf6SGeliang Tang			awk '{print $2}'`
11198a127bf6SGeliang Tang		[ -z "$count" ] && count=0
11208a127bf6SGeliang Tang		if [ "$count" != "$mis_syn_nr" ]; then
11218a127bf6SGeliang Tang			echo "[fail] got $count JOIN[s] syn with a mismatched \
11228a127bf6SGeliang Tang				port-number expected $mis_syn_nr"
11238a127bf6SGeliang Tang			ret=1
11248a127bf6SGeliang Tang			dump_stats=1
11258a127bf6SGeliang Tang		else
11268a127bf6SGeliang Tang			echo -n "[ ok ]"
11278a127bf6SGeliang Tang		fi
11288a127bf6SGeliang Tang
11298a127bf6SGeliang Tang		echo -n " - ack   "
11308a127bf6SGeliang Tang		count=`ip netns exec $ns1 nstat -as | grep MPTcpExtMismatchPortAckRx |
11318a127bf6SGeliang Tang			awk '{print $2}'`
11328a127bf6SGeliang Tang		[ -z "$count" ] && count=0
11338a127bf6SGeliang Tang		if [ "$count" != "$mis_ack_nr" ]; then
11348a127bf6SGeliang Tang			echo "[fail] got $count JOIN[s] ack with a mismatched \
11358a127bf6SGeliang Tang				port-number expected $mis_ack_nr"
11368a127bf6SGeliang Tang			ret=1
11378a127bf6SGeliang Tang			dump_stats=1
11388a127bf6SGeliang Tang		else
11398a127bf6SGeliang Tang			echo "[ ok ]"
11408a127bf6SGeliang Tang		fi
11418a127bf6SGeliang Tang	else
11428a127bf6SGeliang Tang		echo ""
11438a127bf6SGeliang Tang	fi
11448a127bf6SGeliang Tang
1145327b9a94SPaolo Abeni	[ "${dump_stats}" = 1 ] && dump_stats
1146be613160SGeliang Tang}
1147be613160SGeliang Tang
1148dd72b0feSGeliang Tangchk_rm_nr()
1149dd72b0feSGeliang Tang{
1150dd72b0feSGeliang Tang	local rm_addr_nr=$1
1151dd72b0feSGeliang Tang	local rm_subflow_nr=$2
1152*6fa0174aSPaolo Abeni	local invert
1153*6fa0174aSPaolo Abeni	local simult
1154dd72b0feSGeliang Tang	local count
1155dd72b0feSGeliang Tang	local dump_stats
11567d9bf018SGeliang Tang	local addr_ns=$ns1
11577d9bf018SGeliang Tang	local subflow_ns=$ns2
11587d9bf018SGeliang Tang	local extra_msg=""
11597028ba8aSGeliang Tang
1160*6fa0174aSPaolo Abeni	shift 2
1161*6fa0174aSPaolo Abeni	while [ -n "$1" ]; do
1162*6fa0174aSPaolo Abeni		[ "$1" = "invert" ] && invert=true
1163*6fa0174aSPaolo Abeni		[ "$1" = "simult" ] && simult=true
1164*6fa0174aSPaolo Abeni		shift
1165*6fa0174aSPaolo Abeni	done
1166*6fa0174aSPaolo Abeni
1167*6fa0174aSPaolo Abeni	if [ -z $invert ]; then
1168*6fa0174aSPaolo Abeni		addr_ns=$ns1
1169*6fa0174aSPaolo Abeni		subflow_ns=$ns2
1170*6fa0174aSPaolo Abeni	elif [ $invert = "true" ]; then
11717028ba8aSGeliang Tang		addr_ns=$ns2
11727028ba8aSGeliang Tang		subflow_ns=$ns1
11737d9bf018SGeliang Tang		extra_msg="   invert"
11747028ba8aSGeliang Tang	fi
1175dd72b0feSGeliang Tang
11769a0a9367SGeliang Tang	printf "%-${nr_blank}s %s" " " "rm "
11777028ba8aSGeliang Tang	count=`ip netns exec $addr_ns nstat -as | grep MPTcpExtRmAddr | awk '{print $2}'`
1178dd72b0feSGeliang Tang	[ -z "$count" ] && count=0
1179dd72b0feSGeliang Tang	if [ "$count" != "$rm_addr_nr" ]; then
1180dd72b0feSGeliang Tang		echo "[fail] got $count RM_ADDR[s] expected $rm_addr_nr"
1181dd72b0feSGeliang Tang		ret=1
1182dd72b0feSGeliang Tang		dump_stats=1
1183dd72b0feSGeliang Tang	else
1184dd72b0feSGeliang Tang		echo -n "[ ok ]"
1185dd72b0feSGeliang Tang	fi
1186dd72b0feSGeliang Tang
11877d9bf018SGeliang Tang	echo -n " - rmsf  "
11887028ba8aSGeliang Tang	count=`ip netns exec $subflow_ns nstat -as | grep MPTcpExtRmSubflow | awk '{print $2}'`
1189dd72b0feSGeliang Tang	[ -z "$count" ] && count=0
1190*6fa0174aSPaolo Abeni	if [ -n "$simult" ]; then
1191*6fa0174aSPaolo Abeni		local cnt=$(ip netns exec $addr_ns nstat -as | grep MPTcpExtRmSubflow | awk '{print $2}')
1192*6fa0174aSPaolo Abeni		local suffix
1193*6fa0174aSPaolo Abeni
1194*6fa0174aSPaolo Abeni		# in case of simult flush, the subflow removal count on each side is
1195*6fa0174aSPaolo Abeni		# unreliable
1196*6fa0174aSPaolo Abeni		[ -z "$cnt" ] && cnt=0
1197*6fa0174aSPaolo Abeni		count=$((count + cnt))
1198*6fa0174aSPaolo Abeni		[ "$count" != "$rm_subflow_nr" ] && suffix="$count in [$rm_subflow_nr:$((rm_subflow_nr*2))]"
1199*6fa0174aSPaolo Abeni		if [ $count -ge "$rm_subflow_nr" ] && \
1200*6fa0174aSPaolo Abeni		   [ "$count" -le "$((rm_subflow_nr *2 ))" ]; then
1201*6fa0174aSPaolo Abeni			echo "[ ok ] $suffix"
1202*6fa0174aSPaolo Abeni		else
1203*6fa0174aSPaolo Abeni			echo "[fail] got $count RM_SUBFLOW[s] expected in range [$rm_subflow_nr:$((rm_subflow_nr*2))]"
1204*6fa0174aSPaolo Abeni			ret=1
1205*6fa0174aSPaolo Abeni			dump_stats=1
1206*6fa0174aSPaolo Abeni		fi
1207*6fa0174aSPaolo Abeni		return
1208*6fa0174aSPaolo Abeni	fi
1209dd72b0feSGeliang Tang	if [ "$count" != "$rm_subflow_nr" ]; then
1210dd72b0feSGeliang Tang		echo "[fail] got $count RM_SUBFLOW[s] expected $rm_subflow_nr"
1211dd72b0feSGeliang Tang		ret=1
1212dd72b0feSGeliang Tang		dump_stats=1
1213dd72b0feSGeliang Tang	else
12147d9bf018SGeliang Tang		echo -n "[ ok ]"
1215dd72b0feSGeliang Tang	fi
1216dd72b0feSGeliang Tang
1217327b9a94SPaolo Abeni	[ "${dump_stats}" = 1 ] && dump_stats
12187d9bf018SGeliang Tang
12197d9bf018SGeliang Tang	echo "$extra_msg"
1220dd72b0feSGeliang Tang}
1221dd72b0feSGeliang Tang
1222718eb44eSGeliang Tangchk_prio_nr()
1223718eb44eSGeliang Tang{
1224718eb44eSGeliang Tang	local mp_prio_nr_tx=$1
1225718eb44eSGeliang Tang	local mp_prio_nr_rx=$2
1226718eb44eSGeliang Tang	local count
1227718eb44eSGeliang Tang	local dump_stats
1228718eb44eSGeliang Tang
12299a0a9367SGeliang Tang	printf "%-${nr_blank}s %s" " " "ptx"
1230718eb44eSGeliang Tang	count=`ip netns exec $ns1 nstat -as | grep MPTcpExtMPPrioTx | awk '{print $2}'`
1231718eb44eSGeliang Tang	[ -z "$count" ] && count=0
1232718eb44eSGeliang Tang	if [ "$count" != "$mp_prio_nr_tx" ]; then
1233718eb44eSGeliang Tang		echo "[fail] got $count MP_PRIO[s] TX expected $mp_prio_nr_tx"
1234718eb44eSGeliang Tang		ret=1
1235718eb44eSGeliang Tang		dump_stats=1
1236718eb44eSGeliang Tang	else
1237718eb44eSGeliang Tang		echo -n "[ ok ]"
1238718eb44eSGeliang Tang	fi
1239718eb44eSGeliang Tang
1240718eb44eSGeliang Tang	echo -n " - prx   "
1241718eb44eSGeliang Tang	count=`ip netns exec $ns1 nstat -as | grep MPTcpExtMPPrioRx | awk '{print $2}'`
1242718eb44eSGeliang Tang	[ -z "$count" ] && count=0
1243718eb44eSGeliang Tang	if [ "$count" != "$mp_prio_nr_rx" ]; then
1244718eb44eSGeliang Tang		echo "[fail] got $count MP_PRIO[s] RX expected $mp_prio_nr_rx"
1245718eb44eSGeliang Tang		ret=1
1246718eb44eSGeliang Tang		dump_stats=1
1247718eb44eSGeliang Tang	else
1248718eb44eSGeliang Tang		echo "[ ok ]"
1249718eb44eSGeliang Tang	fi
1250718eb44eSGeliang Tang
1251327b9a94SPaolo Abeni	[ "${dump_stats}" = 1 ] && dump_stats
1252718eb44eSGeliang Tang}
1253718eb44eSGeliang Tang
12547d1e6f16SPaolo Abenichk_link_usage()
12557d1e6f16SPaolo Abeni{
12567d1e6f16SPaolo Abeni	local ns=$1
12577d1e6f16SPaolo Abeni	local link=$2
12587d1e6f16SPaolo Abeni	local out=$3
12597d1e6f16SPaolo Abeni	local expected_rate=$4
12607d1e6f16SPaolo Abeni	local tx_link=`ip netns exec $ns cat /sys/class/net/$link/statistics/tx_bytes`
12617d1e6f16SPaolo Abeni	local tx_total=`ls -l $out | awk '{print $5}'`
12627d1e6f16SPaolo Abeni	local tx_rate=$((tx_link * 100 / $tx_total))
12637d1e6f16SPaolo Abeni	local tolerance=5
12647d1e6f16SPaolo Abeni
12659a0a9367SGeliang Tang	printf "%-${nr_blank}s %-18s" " " "link usage"
12667d1e6f16SPaolo Abeni	if [ $tx_rate -lt $((expected_rate - $tolerance)) -o \
12677d1e6f16SPaolo Abeni	     $tx_rate -gt $((expected_rate + $tolerance)) ]; then
12687d1e6f16SPaolo Abeni		echo "[fail] got $tx_rate% usage, expected $expected_rate%"
12697d1e6f16SPaolo Abeni		ret=1
12707d1e6f16SPaolo Abeni	else
12717d1e6f16SPaolo Abeni		echo "[ ok ]"
12727d1e6f16SPaolo Abeni	fi
12737d1e6f16SPaolo Abeni}
12747d1e6f16SPaolo Abeni
1275f98c2bcaSMat Martineauwait_attempt_fail()
127646e967d1SPaolo Abeni{
127746e967d1SPaolo Abeni	local timeout_ms=$((timeout_poll * 1000))
127846e967d1SPaolo Abeni	local time=0
127946e967d1SPaolo Abeni	local ns=$1
128046e967d1SPaolo Abeni
128146e967d1SPaolo Abeni	while [ $time -lt $timeout_ms ]; do
12825b31dda7SPaolo Abeni		local cnt=$(ip netns exec $ns nstat -as TcpAttemptFails | grep TcpAttemptFails | awk '{print $2}')
128346e967d1SPaolo Abeni
128446e967d1SPaolo Abeni		[ "$cnt" = 1 ] && return 1
128546e967d1SPaolo Abeni		time=$((time + 100))
128646e967d1SPaolo Abeni		sleep 0.1
128746e967d1SPaolo Abeni	done
128846e967d1SPaolo Abeni	return 1
128946e967d1SPaolo Abeni}
129046e967d1SPaolo Abeni
12911002b89fSGeliang Tangsubflows_tests()
12921002b89fSGeliang Tang{
12931002b89fSGeliang Tang	reset
1294b08fbf24SPaolo Abeni	run_tests $ns1 $ns2 10.0.1.1
1295b08fbf24SPaolo Abeni	chk_join_nr "no JOIN" "0" "0" "0"
1296b08fbf24SPaolo Abeni
12971002b89fSGeliang Tang	# subflow limited by client
1298b08fbf24SPaolo Abeni	reset
129934aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 0
130034aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 0 0
130134aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
1302b08fbf24SPaolo Abeni	run_tests $ns1 $ns2 10.0.1.1
1303b08fbf24SPaolo Abeni	chk_join_nr "single subflow, limited by client" 0 0 0
1304b08fbf24SPaolo Abeni
13051002b89fSGeliang Tang	# subflow limited by server
1306b08fbf24SPaolo Abeni	reset
130734aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 0
130834aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 0 1
130934aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
1310b08fbf24SPaolo Abeni	run_tests $ns1 $ns2 10.0.1.1
1311b08fbf24SPaolo Abeni	chk_join_nr "single subflow, limited by server" 1 1 0
1312b08fbf24SPaolo Abeni
1313b08fbf24SPaolo Abeni	# subflow
1314b08fbf24SPaolo Abeni	reset
131534aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
131634aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 0 1
131734aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
1318b08fbf24SPaolo Abeni	run_tests $ns1 $ns2 10.0.1.1
1319b08fbf24SPaolo Abeni	chk_join_nr "single subflow" 1 1 1
1320b08fbf24SPaolo Abeni
1321b08fbf24SPaolo Abeni	# multiple subflows
1322b08fbf24SPaolo Abeni	reset
132334aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 2
132434aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 0 2
132534aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
132634aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow
1327b08fbf24SPaolo Abeni	run_tests $ns1 $ns2 10.0.1.1
1328b08fbf24SPaolo Abeni	chk_join_nr "multiple subflows" 2 2 2
1329b08fbf24SPaolo Abeni
133072bcbc46SPaolo Abeni	# multiple subflows limited by server
1331b08fbf24SPaolo Abeni	reset
133234aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
133334aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 0 2
133434aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
133534aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow
1336b08fbf24SPaolo Abeni	run_tests $ns1 $ns2 10.0.1.1
1337b08fbf24SPaolo Abeni	chk_join_nr "multiple subflows, limited by server" 2 2 1
1338c3eaa5f6SGeliang Tang
1339c3eaa5f6SGeliang Tang	# single subflow, dev
1340c3eaa5f6SGeliang Tang	reset
134134aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
134234aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 0 1
134334aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow dev ns2eth3
1344c3eaa5f6SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1
1345c3eaa5f6SGeliang Tang	chk_join_nr "single subflow, dev" 1 1 1
13461002b89fSGeliang Tang}
1347b08fbf24SPaolo Abeni
134846e967d1SPaolo Abenisubflows_error_tests()
134946e967d1SPaolo Abeni{
135046e967d1SPaolo Abeni	# If a single subflow is configured, and matches the MPC src
135146e967d1SPaolo Abeni	# address, no additional subflow should be created
135246e967d1SPaolo Abeni	reset
135334aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
135434aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 0 1
135534aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.1.2 flags subflow
135646e967d1SPaolo Abeni	run_tests $ns1 $ns2 10.0.1.1 0 0 0 slow
135746e967d1SPaolo Abeni	chk_join_nr "no MPC reuse with single endpoint" 0 0 0
135846e967d1SPaolo Abeni
135946e967d1SPaolo Abeni	# multiple subflows, with subflow creation error
136046e967d1SPaolo Abeni	reset
136134aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 2
136234aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 0 2
136334aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
136434aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow
136546e967d1SPaolo Abeni	ip netns exec $ns1 iptables -A INPUT -s 10.0.3.2 -p tcp -j REJECT
136646e967d1SPaolo Abeni	run_tests $ns1 $ns2 10.0.1.1 0 0 0 slow
136746e967d1SPaolo Abeni	chk_join_nr "multi subflows, with failing subflow" 1 1 1
136846e967d1SPaolo Abeni
136946e967d1SPaolo Abeni	# multiple subflows, with subflow timeout on MPJ
137046e967d1SPaolo Abeni	reset
137134aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 2
137234aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 0 2
137334aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
137434aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow
137546e967d1SPaolo Abeni	ip netns exec $ns1 iptables -A INPUT -s 10.0.3.2 -p tcp -j DROP
137646e967d1SPaolo Abeni	run_tests $ns1 $ns2 10.0.1.1 0 0 0 slow
137746e967d1SPaolo Abeni	chk_join_nr "multi subflows, with subflow timeout" 1 1 1
137846e967d1SPaolo Abeni
137946e967d1SPaolo Abeni	# multiple subflows, check that the endpoint corresponding to
138046e967d1SPaolo Abeni	# closed subflow (due to reset) is not reused if additional
138146e967d1SPaolo Abeni	# subflows are added later
138246e967d1SPaolo Abeni	reset
138334aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
138434aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 0 1
138534aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
138646e967d1SPaolo Abeni	ip netns exec $ns1 iptables -A INPUT -s 10.0.3.2 -p tcp -j REJECT
138746e967d1SPaolo Abeni	run_tests $ns1 $ns2 10.0.1.1 0 0 0 slow &
138846e967d1SPaolo Abeni
138946e967d1SPaolo Abeni	# updates in the child shell do not have any effect here, we
139046e967d1SPaolo Abeni	# need to bump the test counter for the above case
139146e967d1SPaolo Abeni	TEST_COUNT=$((TEST_COUNT+1))
139246e967d1SPaolo Abeni
139346e967d1SPaolo Abeni	# mpj subflow will be in TW after the reset
1394f98c2bcaSMat Martineau	wait_attempt_fail $ns2
139534aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow
139646e967d1SPaolo Abeni	wait
139746e967d1SPaolo Abeni
139846e967d1SPaolo Abeni	# additional subflow could be created only if the PM select
139946e967d1SPaolo Abeni	# the later endpoint, skipping the already used one
140046e967d1SPaolo Abeni	chk_join_nr "multi subflows, fair usage on close" 1 1 1
140146e967d1SPaolo Abeni}
140246e967d1SPaolo Abeni
14031002b89fSGeliang Tangsignal_address_tests()
14041002b89fSGeliang Tang{
1405b08fbf24SPaolo Abeni	# add_address, unused
1406b08fbf24SPaolo Abeni	reset
140734aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
1408b08fbf24SPaolo Abeni	run_tests $ns1 $ns2 10.0.1.1
1409b08fbf24SPaolo Abeni	chk_join_nr "unused signal address" 0 0 0
1410be613160SGeliang Tang	chk_add_nr 1 1
1411b08fbf24SPaolo Abeni
1412b08fbf24SPaolo Abeni	# accept and use add_addr
1413b08fbf24SPaolo Abeni	reset
141434aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
141534aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 1
141634aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
1417b08fbf24SPaolo Abeni	run_tests $ns1 $ns2 10.0.1.1
1418b08fbf24SPaolo Abeni	chk_join_nr "signal address" 1 1 1
1419be613160SGeliang Tang	chk_add_nr 1 1
1420b08fbf24SPaolo Abeni
1421b08fbf24SPaolo Abeni	# accept and use add_addr with an additional subflow
1422b08fbf24SPaolo Abeni	# note: signal address in server ns and local addresses in client ns must
1423b08fbf24SPaolo Abeni	# belong to different subnets or one of the listed local address could be
1424b08fbf24SPaolo Abeni	# used for 'add_addr' subflow
1425b08fbf24SPaolo Abeni	reset
142634aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
142734aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 2
142834aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 2
142934aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
1430b08fbf24SPaolo Abeni	run_tests $ns1 $ns2 10.0.1.1
1431b08fbf24SPaolo Abeni	chk_join_nr "subflow and signal" 2 2 2
1432be613160SGeliang Tang	chk_add_nr 1 1
1433b08fbf24SPaolo Abeni
1434b08fbf24SPaolo Abeni	# accept and use add_addr with additional subflows
1435b08fbf24SPaolo Abeni	reset
143634aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 3
143734aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
143834aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 3
143934aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
144034aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.4.2 flags subflow
1441b08fbf24SPaolo Abeni	run_tests $ns1 $ns2 10.0.1.1
1442b08fbf24SPaolo Abeni	chk_join_nr "multiple subflows and signal" 3 3 3
1443be613160SGeliang Tang	chk_add_nr 1 1
1444ef360019SGeliang Tang
1445ef360019SGeliang Tang	# signal addresses
1446ef360019SGeliang Tang	reset
144734aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 3 3
144834aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
144934aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.3.1 flags signal
145034aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.4.1 flags signal
145134aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 3 3
1452ef360019SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1
1453ef360019SGeliang Tang	chk_join_nr "signal addresses" 3 3 3
1454ef360019SGeliang Tang	chk_add_nr 3 3
1455ef360019SGeliang Tang
1456ef360019SGeliang Tang	# signal invalid addresses
1457ef360019SGeliang Tang	reset
145834aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 3 3
145934aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.12.1 flags signal
146034aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.3.1 flags signal
146134aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.14.1 flags signal
146234aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 3 3
1463ef360019SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1
1464ef360019SGeliang Tang	chk_join_nr "signal invalid addresses" 1 1 1
1465ef360019SGeliang Tang	chk_add_nr 3 3
146633c563adSYonglong Li
146733c563adSYonglong Li	# signal addresses race test
146833c563adSYonglong Li	reset
146934aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 4 4
147034aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 4 4
147134aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.1.1 flags signal
147234aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
147334aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.3.1 flags signal
147434aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.4.1 flags signal
147534aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.1.2 flags signal
147634aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.2.2 flags signal
147734aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 flags signal
147834aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.4.2 flags signal
14796ef84b15SPaolo Abeni
14806ef84b15SPaolo Abeni	# the peer could possibly miss some addr notification, allow retransmission
14816ef84b15SPaolo Abeni	ip netns exec $ns1 sysctl -q net.mptcp.add_addr_timeout=1
14826ef84b15SPaolo Abeni	run_tests $ns1 $ns2 10.0.1.1 0 0 0 slow
1483857898ebSMatthieu Baerts	chk_join_nr "signal addresses race test" 3 3 3
148486e39e04SPaolo Abeni
148586e39e04SPaolo Abeni	# the server will not signal the address terminating
148686e39e04SPaolo Abeni	# the MPC subflow
148786e39e04SPaolo Abeni	chk_add_nr 3 3
14881002b89fSGeliang Tang}
1489b08fbf24SPaolo Abeni
14901002b89fSGeliang Tanglink_failure_tests()
14911002b89fSGeliang Tang{
14928b819a84SFlorian Westphal	# accept and use add_addr with additional subflows and link loss
14938b819a84SFlorian Westphal	reset
14947d1e6f16SPaolo Abeni
14957d1e6f16SPaolo Abeni	# without any b/w limit each veth could spool the packets and get
14967d1e6f16SPaolo Abeni	# them acked at xmit time, so that the corresponding subflow will
14977d1e6f16SPaolo Abeni	# have almost always no outstanding pkts, the scheduler will pick
14987d1e6f16SPaolo Abeni	# always the first subflow and we will have hard time testing
14997d1e6f16SPaolo Abeni	# active backup and link switch-over.
15007d1e6f16SPaolo Abeni	# Let's set some arbitrary (low) virtual link limits.
15017d1e6f16SPaolo Abeni	init_shapers
150234aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 3
150334aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 dev ns1eth2 flags signal
150434aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 3
150534aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 dev ns2eth3 flags subflow
150634aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.4.2 dev ns2eth4 flags subflow
15078b819a84SFlorian Westphal	run_tests $ns1 $ns2 10.0.1.1 1
15088b819a84SFlorian Westphal	chk_join_nr "multiple flows, signal, link failure" 3 3 3
15098b819a84SFlorian Westphal	chk_add_nr 1 1
15107d1e6f16SPaolo Abeni	chk_stale_nr $ns2 1 5 1
15117d1e6f16SPaolo Abeni
15127d1e6f16SPaolo Abeni	# accept and use add_addr with additional subflows and link loss
15137d1e6f16SPaolo Abeni	# for bidirectional transfer
15147d1e6f16SPaolo Abeni	reset
15157d1e6f16SPaolo Abeni	init_shapers
151634aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 3
151734aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 dev ns1eth2 flags signal
151834aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 3
151934aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 dev ns2eth3 flags subflow
152034aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.4.2 dev ns2eth4 flags subflow
15217d1e6f16SPaolo Abeni	run_tests $ns1 $ns2 10.0.1.1 2
15227d1e6f16SPaolo Abeni	chk_join_nr "multi flows, signal, bidi, link fail" 3 3 3
15237d1e6f16SPaolo Abeni	chk_add_nr 1 1
15247d1e6f16SPaolo Abeni	chk_stale_nr $ns2 1 -1 1
15257d1e6f16SPaolo Abeni
15267d1e6f16SPaolo Abeni	# 2 subflows plus 1 backup subflow with a lossy link, backup
15277d1e6f16SPaolo Abeni	# will never be used
15287d1e6f16SPaolo Abeni	reset
15297d1e6f16SPaolo Abeni	init_shapers
153034aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 2
153134aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 dev ns1eth2 flags signal
153234aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 2
15337d1e6f16SPaolo Abeni	export FAILING_LINKS="1"
153434aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 dev ns2eth3 flags subflow,backup
15357d1e6f16SPaolo Abeni	run_tests $ns1 $ns2 10.0.1.1 1
15367d1e6f16SPaolo Abeni	chk_join_nr "backup subflow unused, link failure" 2 2 2
15377d1e6f16SPaolo Abeni	chk_add_nr 1 1
15387d1e6f16SPaolo Abeni	chk_link_usage $ns2 ns2eth3 $cinsent 0
15397d1e6f16SPaolo Abeni
15407d1e6f16SPaolo Abeni	# 2 lossy links after half transfer, backup will get half of
15417d1e6f16SPaolo Abeni	# the traffic
15427d1e6f16SPaolo Abeni	reset
15437d1e6f16SPaolo Abeni	init_shapers
154434aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 2
154534aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 dev ns1eth2 flags signal
154634aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 2
154734aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 dev ns2eth3 flags subflow,backup
15487d1e6f16SPaolo Abeni	export FAILING_LINKS="1 2"
15497d1e6f16SPaolo Abeni	run_tests $ns1 $ns2 10.0.1.1 1
15507d1e6f16SPaolo Abeni	chk_join_nr "backup flow used, multi links fail" 2 2 2
15517d1e6f16SPaolo Abeni	chk_add_nr 1 1
15527d1e6f16SPaolo Abeni	chk_stale_nr $ns2 2 4 2
15537d1e6f16SPaolo Abeni	chk_link_usage $ns2 ns2eth3 $cinsent 50
15547d1e6f16SPaolo Abeni
15557d1e6f16SPaolo Abeni	# use a backup subflow with the first subflow on a lossy link
15567d1e6f16SPaolo Abeni	# for bidirectional transfer
15577d1e6f16SPaolo Abeni	reset
15587d1e6f16SPaolo Abeni	init_shapers
155934aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 2
156034aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 dev ns1eth2 flags signal
156134aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 3
156234aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 dev ns2eth3 flags subflow,backup
15637d1e6f16SPaolo Abeni	run_tests $ns1 $ns2 10.0.1.1 2
15647d1e6f16SPaolo Abeni	chk_join_nr "backup flow used, bidi, link failure" 2 2 2
15657d1e6f16SPaolo Abeni	chk_add_nr 1 1
15667d1e6f16SPaolo Abeni	chk_stale_nr $ns2 1 -1 2
15677d1e6f16SPaolo Abeni	chk_link_usage $ns2 ns2eth3 $cinsent 50
15681002b89fSGeliang Tang}
15698b819a84SFlorian Westphal
15701002b89fSGeliang Tangadd_addr_timeout_tests()
15711002b89fSGeliang Tang{
15728d014eaaSGeliang Tang	# add_addr timeout
15738d014eaaSGeliang Tang	reset_with_add_addr_timeout
157434aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
157534aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 1
157634aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
15778b819a84SFlorian Westphal	run_tests $ns1 $ns2 10.0.1.1 0 0 0 slow
15788d014eaaSGeliang Tang	chk_join_nr "signal address, ADD_ADDR timeout" 1 1 1
15798d014eaaSGeliang Tang	chk_add_nr 4 0
15808d014eaaSGeliang Tang
15811002b89fSGeliang Tang	# add_addr timeout IPv6
15821002b89fSGeliang Tang	reset_with_add_addr_timeout 6
158334aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
158434aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 1
158534aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 dead:beef:2::1 flags signal
15861002b89fSGeliang Tang	run_tests $ns1 $ns2 dead:beef:1::1 0 0 0 slow
15871002b89fSGeliang Tang	chk_join_nr "signal address, ADD_ADDR6 timeout" 1 1 1
15881002b89fSGeliang Tang	chk_add_nr 4 0
15898da6229bSGeliang Tang
15908da6229bSGeliang Tang	# signal addresses timeout
15918da6229bSGeliang Tang	reset_with_add_addr_timeout
159234aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 2 2
159334aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
159434aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.3.1 flags signal
159534aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 2 2
1596cbfafac4SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1 0 0 0 speed_10
15978da6229bSGeliang Tang	chk_join_nr "signal addresses, ADD_ADDR timeout" 2 2 2
15988da6229bSGeliang Tang	chk_add_nr 8 0
15998da6229bSGeliang Tang
16008da6229bSGeliang Tang	# signal invalid addresses timeout
16018da6229bSGeliang Tang	reset_with_add_addr_timeout
160234aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 2 2
160334aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.12.1 flags signal
160434aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.3.1 flags signal
160534aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 2 2
1606cbfafac4SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1 0 0 0 speed_10
16078da6229bSGeliang Tang	chk_join_nr "invalid address, ADD_ADDR timeout" 1 1 1
16088da6229bSGeliang Tang	chk_add_nr 8 0
16091002b89fSGeliang Tang}
16101002b89fSGeliang Tang
16111002b89fSGeliang Tangremove_tests()
16121002b89fSGeliang Tang{
1613dd72b0feSGeliang Tang	# single subflow, remove
1614dd72b0feSGeliang Tang	reset
161534aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
161634aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 0 1
161734aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
16182e8cbf45SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1 0 0 -1 slow
1619dd72b0feSGeliang Tang	chk_join_nr "remove single subflow" 1 1 1
1620dd72b0feSGeliang Tang	chk_rm_nr 1 1
1621dd72b0feSGeliang Tang
1622dd72b0feSGeliang Tang	# multiple subflows, remove
1623dd72b0feSGeliang Tang	reset
162434aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 2
162534aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 0 2
162634aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow
162734aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
16282e8cbf45SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1 0 0 -2 slow
1629dd72b0feSGeliang Tang	chk_join_nr "remove multiple subflows" 2 2 2
1630dd72b0feSGeliang Tang	chk_rm_nr 2 2
1631dd72b0feSGeliang Tang
1632dd72b0feSGeliang Tang	# single address, remove
1633dd72b0feSGeliang Tang	reset
163434aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
163534aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
163634aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 1
16372e8cbf45SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1 0 -1 0 slow
1638dd72b0feSGeliang Tang	chk_join_nr "remove single address" 1 1 1
1639dd72b0feSGeliang Tang	chk_add_nr 1 1
16407028ba8aSGeliang Tang	chk_rm_nr 1 1 invert
1641dd72b0feSGeliang Tang
1642dd72b0feSGeliang Tang	# subflow and signal, remove
1643dd72b0feSGeliang Tang	reset
164434aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 2
164534aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
164634aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 2
164734aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
16482e8cbf45SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1 0 -1 -1 slow
1649dd72b0feSGeliang Tang	chk_join_nr "remove subflow and signal" 2 2 2
1650dd72b0feSGeliang Tang	chk_add_nr 1 1
1651dd72b0feSGeliang Tang	chk_rm_nr 1 1
1652dd72b0feSGeliang Tang
1653dd72b0feSGeliang Tang	# subflows and signal, remove
1654dd72b0feSGeliang Tang	reset
165534aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 3
165634aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
165734aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 3
165834aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
165934aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.4.2 flags subflow
16602e8cbf45SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1 0 -1 -2 slow
1661dd72b0feSGeliang Tang	chk_join_nr "remove subflows and signal" 3 3 3
1662dd72b0feSGeliang Tang	chk_add_nr 1 1
1663dd72b0feSGeliang Tang	chk_rm_nr 2 2
1664dd72b0feSGeliang Tang
1665ef360019SGeliang Tang	# addresses remove
1666ef360019SGeliang Tang	reset
166734aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 3 3
166834aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags signal id 250
166934aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.3.1 flags signal
167034aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.4.1 flags signal
167134aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 3 3
1672ef360019SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1 0 -3 0 slow
1673ef360019SGeliang Tang	chk_join_nr "remove addresses" 3 3 3
1674ef360019SGeliang Tang	chk_add_nr 3 3
1675ef360019SGeliang Tang	chk_rm_nr 3 3 invert
1676ef360019SGeliang Tang
1677ef360019SGeliang Tang	# invalid addresses remove
1678ef360019SGeliang Tang	reset
167934aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 3 3
168034aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.12.1 flags signal
168134aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.3.1 flags signal
168234aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.14.1 flags signal
168334aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 3 3
1684ef360019SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1 0 -3 0 slow
1685ef360019SGeliang Tang	chk_join_nr "remove invalid addresses" 1 1 1
1686ef360019SGeliang Tang	chk_add_nr 3 3
1687ef360019SGeliang Tang	chk_rm_nr 3 1 invert
1688ef360019SGeliang Tang
16896fe4ccdcSGeliang Tang	# subflows and signal, flush
16906fe4ccdcSGeliang Tang	reset
169134aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 3
169234aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
169334aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 3
169434aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
169534aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.4.2 flags subflow
16962e8cbf45SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1 0 -8 -8 slow
16976fe4ccdcSGeliang Tang	chk_join_nr "flush subflows and signal" 3 3 3
16986fe4ccdcSGeliang Tang	chk_add_nr 1 1
1699*6fa0174aSPaolo Abeni	chk_rm_nr 1 3 invert simult
1700d2c4333aSGeliang Tang
1701d2c4333aSGeliang Tang	# subflows flush
1702d2c4333aSGeliang Tang	reset
170334aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 3 3
170434aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 3 3
170534aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow id 150
170634aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
170734aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.4.2 flags subflow
1708d2c4333aSGeliang Tang	run_tests $ns1 $ns2 10.0.1.1 0 -8 -8 slow
1709d2c4333aSGeliang Tang	chk_join_nr "flush subflows" 3 3 3
1710*6fa0174aSPaolo Abeni	chk_rm_nr 0 3 simult
1711d2c4333aSGeliang Tang
1712d2c4333aSGeliang Tang	# addresses flush
1713d2c4333aSGeliang Tang	reset
171434aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 3 3
171534aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags signal id 250
171634aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.3.1 flags signal
171734aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.4.1 flags signal
171834aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 3 3
1719d2c4333aSGeliang Tang	run_tests $ns1 $ns2 10.0.1.1 0 -8 -8 slow
1720d2c4333aSGeliang Tang	chk_join_nr "flush addresses" 3 3 3
1721d2c4333aSGeliang Tang	chk_add_nr 3 3
1722*6fa0174aSPaolo Abeni	chk_rm_nr 3 3 invert simult
1723ef360019SGeliang Tang
1724ef360019SGeliang Tang	# invalid addresses flush
1725ef360019SGeliang Tang	reset
172634aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 3 3
172734aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.12.1 flags signal
172834aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.3.1 flags signal
172934aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.14.1 flags signal
173034aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 3 3
1731ef360019SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1 0 -8 0 slow
1732ef360019SGeliang Tang	chk_join_nr "flush invalid addresses" 1 1 1
1733ef360019SGeliang Tang	chk_add_nr 3 3
1734ef360019SGeliang Tang	chk_rm_nr 3 1 invert
17355e287fe7SGeliang Tang
17365e287fe7SGeliang Tang	# remove id 0 subflow
17375e287fe7SGeliang Tang	reset
173834aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
173934aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 0 1
174034aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
17415e287fe7SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1 0 0 -9 slow
17425e287fe7SGeliang Tang	chk_join_nr "remove id 0 subflow" 1 1 1
17435e287fe7SGeliang Tang	chk_rm_nr 1 1
17445e287fe7SGeliang Tang
17455e287fe7SGeliang Tang	# remove id 0 address
17465e287fe7SGeliang Tang	reset
174734aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
174834aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
174934aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 1
17505e287fe7SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1 0 -9 0 slow
17515e287fe7SGeliang Tang	chk_join_nr "remove id 0 address" 1 1 1
17525e287fe7SGeliang Tang	chk_add_nr 1 1
17535e287fe7SGeliang Tang	chk_rm_nr 1 1 invert
17541002b89fSGeliang Tang}
17556fe4ccdcSGeliang Tang
17561002b89fSGeliang Tangadd_tests()
17571002b89fSGeliang Tang{
17586208fd82SGeliang Tang	# add single subflow
17596208fd82SGeliang Tang	reset
176034aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
176134aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 0 1
17626208fd82SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1 0 0 1 slow
17636208fd82SGeliang Tang	chk_join_nr "add single subflow" 1 1 1
17646208fd82SGeliang Tang
17656208fd82SGeliang Tang	# add signal address
17666208fd82SGeliang Tang	reset
176734aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
176834aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 1
17696208fd82SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1 0 1 0 slow
17706208fd82SGeliang Tang	chk_join_nr "add signal address" 1 1 1
17716208fd82SGeliang Tang	chk_add_nr 1 1
17726208fd82SGeliang Tang
17736208fd82SGeliang Tang	# add multiple subflows
17746208fd82SGeliang Tang	reset
177534aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 2
177634aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 0 2
17776208fd82SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1 0 0 2 slow
17786208fd82SGeliang Tang	chk_join_nr "add multiple subflows" 2 2 2
17796208fd82SGeliang Tang
17806208fd82SGeliang Tang	# add multiple subflows IPv6
17816208fd82SGeliang Tang	reset
178234aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 2
178334aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 0 2
17846208fd82SGeliang Tang	run_tests $ns1 $ns2 dead:beef:1::1 0 0 2 slow
17856208fd82SGeliang Tang	chk_join_nr "add multiple subflows IPv6" 2 2 2
17866208fd82SGeliang Tang
17876208fd82SGeliang Tang	# add multiple addresses IPv6
17886208fd82SGeliang Tang	reset
178934aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 2
179034aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 2 2
17916208fd82SGeliang Tang	run_tests $ns1 $ns2 dead:beef:1::1 0 2 0 slow
17926208fd82SGeliang Tang	chk_join_nr "add multiple addresses IPv6" 2 2 2
17936208fd82SGeliang Tang	chk_add_nr 2 2
17941002b89fSGeliang Tang}
17956208fd82SGeliang Tang
17961002b89fSGeliang Tangipv6_tests()
17971002b89fSGeliang Tang{
1798523514edSGeliang Tang	# subflow IPv6
1799523514edSGeliang Tang	reset
180034aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
180134aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 0 1
180234aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 dead:beef:3::2 dev ns2eth3 flags subflow
1803523514edSGeliang Tang	run_tests $ns1 $ns2 dead:beef:1::1 0 0 0 slow
1804523514edSGeliang Tang	chk_join_nr "single subflow IPv6" 1 1 1
1805523514edSGeliang Tang
1806523514edSGeliang Tang	# add_address, unused IPv6
1807523514edSGeliang Tang	reset
180834aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 dead:beef:2::1 flags signal
1809523514edSGeliang Tang	run_tests $ns1 $ns2 dead:beef:1::1 0 0 0 slow
1810523514edSGeliang Tang	chk_join_nr "unused signal address IPv6" 0 0 0
1811523514edSGeliang Tang	chk_add_nr 1 1
1812523514edSGeliang Tang
1813523514edSGeliang Tang	# signal address IPv6
1814523514edSGeliang Tang	reset
181534aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
181634aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 dead:beef:2::1 flags signal
181734aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 1
1818523514edSGeliang Tang	run_tests $ns1 $ns2 dead:beef:1::1 0 0 0 slow
1819523514edSGeliang Tang	chk_join_nr "single address IPv6" 1 1 1
1820523514edSGeliang Tang	chk_add_nr 1 1
1821523514edSGeliang Tang
1822523514edSGeliang Tang	# single address IPv6, remove
1823523514edSGeliang Tang	reset
182434aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
182534aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 dead:beef:2::1 flags signal
182634aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 1
18272e8cbf45SGeliang Tang	run_tests $ns1 $ns2 dead:beef:1::1 0 -1 0 slow
1828523514edSGeliang Tang	chk_join_nr "remove single address IPv6" 1 1 1
1829523514edSGeliang Tang	chk_add_nr 1 1
18307028ba8aSGeliang Tang	chk_rm_nr 1 1 invert
1831523514edSGeliang Tang
1832523514edSGeliang Tang	# subflow and signal IPv6, remove
1833523514edSGeliang Tang	reset
183434aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 2
183534aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 dead:beef:2::1 flags signal
183634aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 2
183734aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 dead:beef:3::2 dev ns2eth3 flags subflow
18382e8cbf45SGeliang Tang	run_tests $ns1 $ns2 dead:beef:1::1 0 -1 -1 slow
1839523514edSGeliang Tang	chk_join_nr "remove subflow and signal IPv6" 2 2 2
1840523514edSGeliang Tang	chk_add_nr 1 1
1841523514edSGeliang Tang	chk_rm_nr 1 1
18421002b89fSGeliang Tang}
1843523514edSGeliang Tang
18441002b89fSGeliang Tangv4mapped_tests()
18451002b89fSGeliang Tang{
1846a6094788SGeliang Tang	# subflow IPv4-mapped to IPv4-mapped
1847a6094788SGeliang Tang	reset
184834aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
184934aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 0 1
185034aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 "::ffff:10.0.3.2" flags subflow
1851a6094788SGeliang Tang	run_tests $ns1 $ns2 "::ffff:10.0.1.1"
1852a6094788SGeliang Tang	chk_join_nr "single subflow IPv4-mapped" 1 1 1
1853a6094788SGeliang Tang
1854a6094788SGeliang Tang	# signal address IPv4-mapped with IPv4-mapped sk
1855a6094788SGeliang Tang	reset
185634aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
185734aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 1
185834aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 "::ffff:10.0.2.1" flags signal
1859a6094788SGeliang Tang	run_tests $ns1 $ns2 "::ffff:10.0.1.1"
1860a6094788SGeliang Tang	chk_join_nr "signal address IPv4-mapped" 1 1 1
1861a6094788SGeliang Tang	chk_add_nr 1 1
1862a6094788SGeliang Tang
1863a6094788SGeliang Tang	# subflow v4-map-v6
1864a6094788SGeliang Tang	reset
186534aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
186634aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 0 1
186734aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
1868a6094788SGeliang Tang	run_tests $ns1 $ns2 "::ffff:10.0.1.1"
1869a6094788SGeliang Tang	chk_join_nr "single subflow v4-map-v6" 1 1 1
1870a6094788SGeliang Tang
1871a6094788SGeliang Tang	# signal address v4-map-v6
1872a6094788SGeliang Tang	reset
187334aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
187434aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 1
187534aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
1876a6094788SGeliang Tang	run_tests $ns1 $ns2 "::ffff:10.0.1.1"
1877a6094788SGeliang Tang	chk_join_nr "signal address v4-map-v6" 1 1 1
1878a6094788SGeliang Tang	chk_add_nr 1 1
1879a6094788SGeliang Tang
1880a6094788SGeliang Tang	# subflow v6-map-v4
1881a6094788SGeliang Tang	reset
188234aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
188334aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 0 1
188434aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 "::ffff:10.0.3.2" flags subflow
1885a6094788SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1
1886a6094788SGeliang Tang	chk_join_nr "single subflow v6-map-v4" 1 1 1
1887a6094788SGeliang Tang
1888a6094788SGeliang Tang	# signal address v6-map-v4
1889a6094788SGeliang Tang	reset
189034aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
189134aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 1
189234aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 "::ffff:10.0.2.1" flags signal
1893a6094788SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1
1894a6094788SGeliang Tang	chk_join_nr "signal address v6-map-v4" 1 1 1
1895a6094788SGeliang Tang	chk_add_nr 1 1
1896a6094788SGeliang Tang
1897a6094788SGeliang Tang	# no subflow IPv6 to v4 address
1898a6094788SGeliang Tang	reset
189934aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
190034aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 0 1
190134aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 dead:beef:2::2 flags subflow
1902a6094788SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1
1903a6094788SGeliang Tang	chk_join_nr "no JOIN with diff families v4-v6" 0 0 0
1904a6094788SGeliang Tang
1905a6094788SGeliang Tang	# no subflow IPv6 to v4 address even if v6 has a valid v4 at the end
1906a6094788SGeliang Tang	reset
190734aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
190834aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 0 1
190934aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 dead:beef:2::10.0.3.2 flags subflow
1910a6094788SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1
1911a6094788SGeliang Tang	chk_join_nr "no JOIN with diff families v4-v6-2" 0 0 0
1912a6094788SGeliang Tang
1913a6094788SGeliang Tang	# no subflow IPv4 to v6 address, no need to slow down too then
1914a6094788SGeliang Tang	reset
191534aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
191634aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 0 1
191734aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
1918a6094788SGeliang Tang	run_tests $ns1 $ns2 dead:beef:1::1
1919a6094788SGeliang Tang	chk_join_nr "no JOIN with diff families v6-v4" 0 0 0
19201002b89fSGeliang Tang}
1921a6094788SGeliang Tang
19221002b89fSGeliang Tangbackup_tests()
19231002b89fSGeliang Tang{
1924718eb44eSGeliang Tang	# single subflow, backup
1925718eb44eSGeliang Tang	reset
192634aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
192734aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 0 1
192834aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow,backup
1929718eb44eSGeliang Tang	run_tests $ns1 $ns2 10.0.1.1 0 0 0 slow nobackup
1930718eb44eSGeliang Tang	chk_join_nr "single subflow, backup" 1 1 1
1931718eb44eSGeliang Tang	chk_prio_nr 0 1
1932718eb44eSGeliang Tang
1933718eb44eSGeliang Tang	# single address, backup
1934718eb44eSGeliang Tang	reset
193534aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
193634aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
193734aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 1
1938718eb44eSGeliang Tang	run_tests $ns1 $ns2 10.0.1.1 0 0 0 slow backup
1939718eb44eSGeliang Tang	chk_join_nr "single address, backup" 1 1 1
1940718eb44eSGeliang Tang	chk_add_nr 1 1
1941718eb44eSGeliang Tang	chk_prio_nr 1 0
194233397b83SGeliang Tang
194333397b83SGeliang Tang	# single address with port, backup
194433397b83SGeliang Tang	reset
194534aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
194634aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags signal port 10100
194734aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 1
194833397b83SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1 0 0 0 slow backup
194933397b83SGeliang Tang	chk_join_nr "single address with port, backup" 1 1 1
195033397b83SGeliang Tang	chk_add_nr 1 1
195133397b83SGeliang Tang	chk_prio_nr 1 0
19521002b89fSGeliang Tang}
1953718eb44eSGeliang Tang
19541002b89fSGeliang Tangadd_addr_ports_tests()
19551002b89fSGeliang Tang{
19568a127bf6SGeliang Tang	# signal address with port
19578a127bf6SGeliang Tang	reset
195834aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
195934aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 1
196034aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags signal port 10100
19618a127bf6SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1
19628a127bf6SGeliang Tang	chk_join_nr "signal address with port" 1 1 1
19638a127bf6SGeliang Tang	chk_add_nr 1 1 1
19648a127bf6SGeliang Tang
19658a127bf6SGeliang Tang	# subflow and signal with port
19668a127bf6SGeliang Tang	reset
196734aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags signal port 10100
196834aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 2
196934aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 2
197034aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
19718a127bf6SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1
19728a127bf6SGeliang Tang	chk_join_nr "subflow and signal with port" 2 2 2
19738a127bf6SGeliang Tang	chk_add_nr 1 1 1
19748a127bf6SGeliang Tang
19758a127bf6SGeliang Tang	# single address with port, remove
19768a127bf6SGeliang Tang	reset
197734aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
197834aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags signal port 10100
197934aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 1
19808a127bf6SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1 0 -1 0 slow
19818a127bf6SGeliang Tang	chk_join_nr "remove single address with port" 1 1 1
19828a127bf6SGeliang Tang	chk_add_nr 1 1 1
19837028ba8aSGeliang Tang	chk_rm_nr 1 1 invert
19848a127bf6SGeliang Tang
19858a127bf6SGeliang Tang	# subflow and signal with port, remove
19868a127bf6SGeliang Tang	reset
198734aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 2
198834aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags signal port 10100
198934aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 2
199034aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
19918a127bf6SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1 0 -1 -1 slow
19928a127bf6SGeliang Tang	chk_join_nr "remove subflow and signal with port" 2 2 2
19938a127bf6SGeliang Tang	chk_add_nr 1 1 1
19948a127bf6SGeliang Tang	chk_rm_nr 1 1
19958a127bf6SGeliang Tang
19968a127bf6SGeliang Tang	# subflows and signal with port, flush
19978a127bf6SGeliang Tang	reset
199834aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 3
199934aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags signal port 10100
200034aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 3
200134aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
200234aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.4.2 flags subflow
2003327b9a94SPaolo Abeni	run_tests $ns1 $ns2 10.0.1.1 0 -8 -2 slow
20048a127bf6SGeliang Tang	chk_join_nr "flush subflows and signal with port" 3 3 3
20058a127bf6SGeliang Tang	chk_add_nr 1 1
2006*6fa0174aSPaolo Abeni	chk_rm_nr 1 3 invert simult
20078a127bf6SGeliang Tang
20088a127bf6SGeliang Tang	# multiple addresses with port
20098a127bf6SGeliang Tang	reset
201034aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 2 2
201134aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags signal port 10100
201234aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.3.1 flags signal port 10100
201334aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 2 2
20148a127bf6SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1
20158a127bf6SGeliang Tang	chk_join_nr "multiple addresses with port" 2 2 2
20168a127bf6SGeliang Tang	chk_add_nr 2 2 2
20178a127bf6SGeliang Tang
20188a127bf6SGeliang Tang	# multiple addresses with ports
20198a127bf6SGeliang Tang	reset
202034aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 2 2
202134aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags signal port 10100
202234aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.3.1 flags signal port 10101
202334aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 2 2
20248a127bf6SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1
20258a127bf6SGeliang Tang	chk_join_nr "multiple addresses with ports" 2 2 2
20268a127bf6SGeliang Tang	chk_add_nr 2 2 2
20271002b89fSGeliang Tang}
20288a127bf6SGeliang Tang
20291002b89fSGeliang Tangsyncookies_tests()
20301002b89fSGeliang Tang{
203100587187SFlorian Westphal	# single subflow, syncookies
203200587187SFlorian Westphal	reset_with_cookies
203334aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
203434aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 0 1
203534aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
203600587187SFlorian Westphal	run_tests $ns1 $ns2 10.0.1.1
203700587187SFlorian Westphal	chk_join_nr "single subflow with syn cookies" 1 1 1
203800587187SFlorian Westphal
203900587187SFlorian Westphal	# multiple subflows with syn cookies
204000587187SFlorian Westphal	reset_with_cookies
204134aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 2
204234aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 0 2
204334aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
204434aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow
204500587187SFlorian Westphal	run_tests $ns1 $ns2 10.0.1.1
204600587187SFlorian Westphal	chk_join_nr "multiple subflows with syn cookies" 2 2 2
204700587187SFlorian Westphal
204800587187SFlorian Westphal	# multiple subflows limited by server
204900587187SFlorian Westphal	reset_with_cookies
205034aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
205134aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 0 2
205234aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
205334aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow
205400587187SFlorian Westphal	run_tests $ns1 $ns2 10.0.1.1
2055a7da4416SJianguo Wu	chk_join_nr "subflows limited by server w cookies" 2 1 1
205600587187SFlorian Westphal
205700587187SFlorian Westphal	# test signal address with cookies
205800587187SFlorian Westphal	reset_with_cookies
205934aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
206034aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 1
206134aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
206200587187SFlorian Westphal	run_tests $ns1 $ns2 10.0.1.1
206300587187SFlorian Westphal	chk_join_nr "signal address with syn cookies" 1 1 1
2064be613160SGeliang Tang	chk_add_nr 1 1
206500587187SFlorian Westphal
206600587187SFlorian Westphal	# test cookie with subflow and signal
206700587187SFlorian Westphal	reset_with_cookies
206834aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
206934aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 2
207034aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 2
207134aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
207200587187SFlorian Westphal	run_tests $ns1 $ns2 10.0.1.1
207300587187SFlorian Westphal	chk_join_nr "subflow and signal w cookies" 2 2 2
2074be613160SGeliang Tang	chk_add_nr 1 1
207500587187SFlorian Westphal
207600587187SFlorian Westphal	# accept and use add_addr with additional subflows
207700587187SFlorian Westphal	reset_with_cookies
207834aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 3
207934aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
208034aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 3
208134aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
208234aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.4.2 flags subflow
208300587187SFlorian Westphal	run_tests $ns1 $ns2 10.0.1.1
208400587187SFlorian Westphal	chk_join_nr "subflows and signal w. cookies" 3 3 3
2085be613160SGeliang Tang	chk_add_nr 1 1
20861002b89fSGeliang Tang}
20871002b89fSGeliang Tang
2088af66d3e1SGeliang Tangchecksum_tests()
2089af66d3e1SGeliang Tang{
2090af66d3e1SGeliang Tang	# checksum test 0 0
2091af66d3e1SGeliang Tang	reset_with_checksum 0 0
209234aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
209334aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 0 1
2094af66d3e1SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1
2095af66d3e1SGeliang Tang	chk_csum_nr "checksum test 0 0"
2096af66d3e1SGeliang Tang
2097af66d3e1SGeliang Tang	# checksum test 1 1
2098af66d3e1SGeliang Tang	reset_with_checksum 1 1
209934aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
210034aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 0 1
2101af66d3e1SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1
2102af66d3e1SGeliang Tang	chk_csum_nr "checksum test 1 1"
2103af66d3e1SGeliang Tang
2104af66d3e1SGeliang Tang	# checksum test 0 1
2105af66d3e1SGeliang Tang	reset_with_checksum 0 1
210634aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
210734aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 0 1
2108af66d3e1SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1
2109af66d3e1SGeliang Tang	chk_csum_nr "checksum test 0 1"
2110af66d3e1SGeliang Tang
2111af66d3e1SGeliang Tang	# checksum test 1 0
2112af66d3e1SGeliang Tang	reset_with_checksum 1 0
211334aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
211434aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 0 1
2115af66d3e1SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1
2116af66d3e1SGeliang Tang	chk_csum_nr "checksum test 1 0"
2117af66d3e1SGeliang Tang}
2118af66d3e1SGeliang Tang
21190cddb4a6SGeliang Tangdeny_join_id0_tests()
21200cddb4a6SGeliang Tang{
21210cddb4a6SGeliang Tang	# subflow allow join id0 ns1
21220cddb4a6SGeliang Tang	reset_with_allow_join_id0 1 0
212334aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 1 1
212434aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 1
212534aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
21260cddb4a6SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1
21270cddb4a6SGeliang Tang	chk_join_nr "single subflow allow join id0 ns1" 1 1 1
21280cddb4a6SGeliang Tang
21290cddb4a6SGeliang Tang	# subflow allow join id0 ns2
21300cddb4a6SGeliang Tang	reset_with_allow_join_id0 0 1
213134aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 1 1
213234aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 1
213334aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
21340cddb4a6SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1
21350cddb4a6SGeliang Tang	chk_join_nr "single subflow allow join id0 ns2" 0 0 0
21360cddb4a6SGeliang Tang
21370cddb4a6SGeliang Tang	# signal address allow join id0 ns1
21380cddb4a6SGeliang Tang	# ADD_ADDRs are not affected by allow_join_id0 value.
21390cddb4a6SGeliang Tang	reset_with_allow_join_id0 1 0
214034aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 1 1
214134aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 1
214234aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
21430cddb4a6SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1
21440cddb4a6SGeliang Tang	chk_join_nr "signal address allow join id0 ns1" 1 1 1
21450cddb4a6SGeliang Tang	chk_add_nr 1 1
21460cddb4a6SGeliang Tang
21470cddb4a6SGeliang Tang	# signal address allow join id0 ns2
21480cddb4a6SGeliang Tang	# ADD_ADDRs are not affected by allow_join_id0 value.
21490cddb4a6SGeliang Tang	reset_with_allow_join_id0 0 1
215034aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 1 1
215134aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 1
215234aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
21530cddb4a6SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1
21540cddb4a6SGeliang Tang	chk_join_nr "signal address allow join id0 ns2" 1 1 1
21550cddb4a6SGeliang Tang	chk_add_nr 1 1
21560cddb4a6SGeliang Tang
21570cddb4a6SGeliang Tang	# subflow and address allow join id0 ns1
21580cddb4a6SGeliang Tang	reset_with_allow_join_id0 1 0
215934aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 2 2
216034aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 2 2
216134aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
216234aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
21630cddb4a6SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1
21640cddb4a6SGeliang Tang	chk_join_nr "subflow and address allow join id0 1" 2 2 2
21650cddb4a6SGeliang Tang
21660cddb4a6SGeliang Tang	# subflow and address allow join id0 ns2
21670cddb4a6SGeliang Tang	reset_with_allow_join_id0 0 1
216834aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 2 2
216934aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 2 2
217034aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
217134aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
21720cddb4a6SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1
21730cddb4a6SGeliang Tang	chk_join_nr "subflow and address allow join id0 2" 1 1 1
21740cddb4a6SGeliang Tang}
21750cddb4a6SGeliang Tang
21764f49d633SGeliang Tangfullmesh_tests()
21774f49d633SGeliang Tang{
21784f49d633SGeliang Tang	# fullmesh 1
21794f49d633SGeliang Tang	# 2 fullmesh addrs in ns2, added before the connection,
21804f49d633SGeliang Tang	# 1 non-fullmesh addr in ns1, added during the connection.
21814f49d633SGeliang Tang	reset
218234aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 4
218334aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 4
218434aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow,fullmesh
218534aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow,fullmesh
21864f49d633SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1 0 1 0 slow
21874f49d633SGeliang Tang	chk_join_nr "fullmesh test 2x1" 4 4 4
21884f49d633SGeliang Tang	chk_add_nr 1 1
21894f49d633SGeliang Tang
21904f49d633SGeliang Tang	# fullmesh 2
21914f49d633SGeliang Tang	# 1 non-fullmesh addr in ns1, added before the connection,
21924f49d633SGeliang Tang	# 1 fullmesh addr in ns2, added during the connection.
21934f49d633SGeliang Tang	reset
219434aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 1 3
219534aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 3
219634aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
21974f49d633SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1 0 0 fullmesh_1 slow
21984f49d633SGeliang Tang	chk_join_nr "fullmesh test 1x1" 3 3 3
21994f49d633SGeliang Tang	chk_add_nr 1 1
22004f49d633SGeliang Tang
22014f49d633SGeliang Tang	# fullmesh 3
22024f49d633SGeliang Tang	# 1 non-fullmesh addr in ns1, added before the connection,
22034f49d633SGeliang Tang	# 2 fullmesh addrs in ns2, added during the connection.
22044f49d633SGeliang Tang	reset
220534aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 2 5
220634aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 5
220734aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
22084f49d633SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1 0 0 fullmesh_2 slow
22094f49d633SGeliang Tang	chk_join_nr "fullmesh test 1x2" 5 5 5
22104f49d633SGeliang Tang	chk_add_nr 1 1
22114f49d633SGeliang Tang
22124f49d633SGeliang Tang	# fullmesh 4
22134f49d633SGeliang Tang	# 1 non-fullmesh addr in ns1, added before the connection,
22144f49d633SGeliang Tang	# 2 fullmesh addrs in ns2, added during the connection,
22154f49d633SGeliang Tang	# limit max_subflows to 4.
22164f49d633SGeliang Tang	reset
221734aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 2 4
221834aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 4
221934aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
22204f49d633SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1 0 0 fullmesh_2 slow
22214f49d633SGeliang Tang	chk_join_nr "fullmesh test 1x2, limited" 4 4 4
22224f49d633SGeliang Tang	chk_add_nr 1 1
22236a0653b9SGeliang Tang
22246a0653b9SGeliang Tang	# set fullmesh flag
22256a0653b9SGeliang Tang	reset
222634aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 4 4
222734aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags subflow
222834aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 4 4
22296a0653b9SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1 0 0 1 slow fullmesh
22306a0653b9SGeliang Tang	chk_join_nr "set fullmesh flag test" 2 2 2
22316a0653b9SGeliang Tang	chk_rm_nr 0 1
22326a0653b9SGeliang Tang
22336a0653b9SGeliang Tang	# set nofullmesh flag
22346a0653b9SGeliang Tang	reset
223534aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 4 4
223634aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags subflow,fullmesh
223734aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 4 4
22386a0653b9SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1 0 0 fullmesh_1 slow nofullmesh
22396a0653b9SGeliang Tang	chk_join_nr "set nofullmesh flag test" 2 2 2
22406a0653b9SGeliang Tang	chk_rm_nr 0 1
22416a0653b9SGeliang Tang
22426a0653b9SGeliang Tang	# set backup,fullmesh flags
22436a0653b9SGeliang Tang	reset
224434aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 4 4
224534aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags subflow
224634aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 4 4
22476a0653b9SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1 0 0 1 slow backup,fullmesh
22486a0653b9SGeliang Tang	chk_join_nr "set backup,fullmesh flags test" 2 2 2
22496a0653b9SGeliang Tang	chk_prio_nr 0 1
22506a0653b9SGeliang Tang	chk_rm_nr 0 1
22516a0653b9SGeliang Tang
22526a0653b9SGeliang Tang	# set nobackup,nofullmesh flags
22536a0653b9SGeliang Tang	reset
225434aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 4 4
225534aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 4 4
225634aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow,backup,fullmesh
22576a0653b9SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1 0 0 0 slow nobackup,nofullmesh
22586a0653b9SGeliang Tang	chk_join_nr "set nobackup,nofullmesh flags test" 2 2 2
22596a0653b9SGeliang Tang	chk_prio_nr 0 1
22606a0653b9SGeliang Tang	chk_rm_nr 0 1
22614f49d633SGeliang Tang}
22624f49d633SGeliang Tang
226301542c9bSGeliang Tangfastclose_tests()
226401542c9bSGeliang Tang{
226501542c9bSGeliang Tang	reset
226601542c9bSGeliang Tang	run_tests $ns1 $ns2 10.0.1.1 1024 0 fastclose_2
226701542c9bSGeliang Tang	chk_join_nr "fastclose test" 0 0 0
226801542c9bSGeliang Tang	chk_fclose_nr 1 1
226901542c9bSGeliang Tang	chk_rst_nr 1 1 invert
227001542c9bSGeliang Tang}
227101542c9bSGeliang Tang
22721002b89fSGeliang Tangall_tests()
22731002b89fSGeliang Tang{
22741002b89fSGeliang Tang	subflows_tests
227546e967d1SPaolo Abeni	subflows_error_tests
22761002b89fSGeliang Tang	signal_address_tests
22771002b89fSGeliang Tang	link_failure_tests
22781002b89fSGeliang Tang	add_addr_timeout_tests
22791002b89fSGeliang Tang	remove_tests
22801002b89fSGeliang Tang	add_tests
22811002b89fSGeliang Tang	ipv6_tests
22821002b89fSGeliang Tang	v4mapped_tests
22831002b89fSGeliang Tang	backup_tests
22841002b89fSGeliang Tang	add_addr_ports_tests
22851002b89fSGeliang Tang	syncookies_tests
2286af66d3e1SGeliang Tang	checksum_tests
22870cddb4a6SGeliang Tang	deny_join_id0_tests
22884f49d633SGeliang Tang	fullmesh_tests
228901542c9bSGeliang Tang	fastclose_tests
22901002b89fSGeliang Tang}
22911002b89fSGeliang Tang
229222514d52SMatthieu Baerts# [$1: error message]
22931002b89fSGeliang Tangusage()
22941002b89fSGeliang Tang{
229522514d52SMatthieu Baerts	if [ -n "${1}" ]; then
229622514d52SMatthieu Baerts		echo "${1}"
229722514d52SMatthieu Baerts		ret=1
229822514d52SMatthieu Baerts	fi
229922514d52SMatthieu Baerts
23001002b89fSGeliang Tang	echo "mptcp_join usage:"
23011002b89fSGeliang Tang	echo "  -f subflows_tests"
230246e967d1SPaolo Abeni	echo "  -e subflows_error_tests"
23031002b89fSGeliang Tang	echo "  -s signal_address_tests"
23041002b89fSGeliang Tang	echo "  -l link_failure_tests"
23051002b89fSGeliang Tang	echo "  -t add_addr_timeout_tests"
23061002b89fSGeliang Tang	echo "  -r remove_tests"
23071002b89fSGeliang Tang	echo "  -a add_tests"
23081002b89fSGeliang Tang	echo "  -6 ipv6_tests"
23091002b89fSGeliang Tang	echo "  -4 v4mapped_tests"
23101002b89fSGeliang Tang	echo "  -b backup_tests"
23111002b89fSGeliang Tang	echo "  -p add_addr_ports_tests"
2312a673321aSMat Martineau	echo "  -k syncookies_tests"
2313af66d3e1SGeliang Tang	echo "  -S checksum_tests"
23140cddb4a6SGeliang Tang	echo "  -d deny_join_id0_tests"
23154f49d633SGeliang Tang	echo "  -m fullmesh_tests"
231601542c9bSGeliang Tang	echo "  -z fastclose_tests"
2317a673321aSMat Martineau	echo "  -c capture pcap files"
2318af66d3e1SGeliang Tang	echo "  -C enable data checksum"
2319621bd393SGeliang Tang	echo "  -i use ip mptcp"
23201002b89fSGeliang Tang	echo "  -h help"
232122514d52SMatthieu Baerts
232222514d52SMatthieu Baerts	exit ${ret}
23231002b89fSGeliang Tang}
23241002b89fSGeliang Tang
2325a673321aSMat Martineau
2326826d7bdcSMatthieu Baertstests=()
232701542c9bSGeliang Tangwhile getopts 'fesltra64bpkdmchzCSi' opt; do
23281002b89fSGeliang Tang	case $opt in
23291002b89fSGeliang Tang		f)
2330826d7bdcSMatthieu Baerts			tests+=(subflows_tests)
23311002b89fSGeliang Tang			;;
233246e967d1SPaolo Abeni		e)
2333826d7bdcSMatthieu Baerts			tests+=(subflows_error_tests)
233446e967d1SPaolo Abeni			;;
23351002b89fSGeliang Tang		s)
2336826d7bdcSMatthieu Baerts			tests+=(signal_address_tests)
23371002b89fSGeliang Tang			;;
23381002b89fSGeliang Tang		l)
2339826d7bdcSMatthieu Baerts			tests+=(link_failure_tests)
23401002b89fSGeliang Tang			;;
23411002b89fSGeliang Tang		t)
2342826d7bdcSMatthieu Baerts			tests+=(add_addr_timeout_tests)
23431002b89fSGeliang Tang			;;
23441002b89fSGeliang Tang		r)
2345826d7bdcSMatthieu Baerts			tests+=(remove_tests)
23461002b89fSGeliang Tang			;;
23471002b89fSGeliang Tang		a)
2348826d7bdcSMatthieu Baerts			tests+=(add_tests)
23491002b89fSGeliang Tang			;;
23501002b89fSGeliang Tang		6)
2351826d7bdcSMatthieu Baerts			tests+=(ipv6_tests)
23521002b89fSGeliang Tang			;;
23531002b89fSGeliang Tang		4)
2354826d7bdcSMatthieu Baerts			tests+=(v4mapped_tests)
23551002b89fSGeliang Tang			;;
23561002b89fSGeliang Tang		b)
2357826d7bdcSMatthieu Baerts			tests+=(backup_tests)
23581002b89fSGeliang Tang			;;
23591002b89fSGeliang Tang		p)
2360826d7bdcSMatthieu Baerts			tests+=(add_addr_ports_tests)
23611002b89fSGeliang Tang			;;
2362a673321aSMat Martineau		k)
2363826d7bdcSMatthieu Baerts			tests+=(syncookies_tests)
23641002b89fSGeliang Tang			;;
2365af66d3e1SGeliang Tang		S)
2366826d7bdcSMatthieu Baerts			tests+=(checksum_tests)
2367af66d3e1SGeliang Tang			;;
23680cddb4a6SGeliang Tang		d)
2369826d7bdcSMatthieu Baerts			tests+=(deny_join_id0_tests)
23700cddb4a6SGeliang Tang			;;
23714f49d633SGeliang Tang		m)
2372826d7bdcSMatthieu Baerts			tests+=(fullmesh_tests)
23734f49d633SGeliang Tang			;;
237401542c9bSGeliang Tang		z)
2375826d7bdcSMatthieu Baerts			tests+=(fastclose_tests)
237601542c9bSGeliang Tang			;;
2377a673321aSMat Martineau		c)
2378826d7bdcSMatthieu Baerts			capture=1
2379a673321aSMat Martineau			;;
2380af66d3e1SGeliang Tang		C)
2381826d7bdcSMatthieu Baerts			checksum=1
2382af66d3e1SGeliang Tang			;;
2383621bd393SGeliang Tang		i)
2384826d7bdcSMatthieu Baerts			ip_mptcp=1
2385621bd393SGeliang Tang			;;
238622514d52SMatthieu Baerts		h)
23871002b89fSGeliang Tang			usage
23881002b89fSGeliang Tang			;;
238922514d52SMatthieu Baerts		*)
239022514d52SMatthieu Baerts			usage "Unknown option: -${opt}"
239122514d52SMatthieu Baerts			;;
23921002b89fSGeliang Tang	esac
23931002b89fSGeliang Tangdone
239400587187SFlorian Westphal
2395826d7bdcSMatthieu Baertsif [ ${#tests[@]} -eq 0 ]; then
2396826d7bdcSMatthieu Baerts	all_tests
2397826d7bdcSMatthieu Baertselse
2398826d7bdcSMatthieu Baerts	for subtests in "${tests[@]}"; do
2399826d7bdcSMatthieu Baerts		"${subtests}"
2400826d7bdcSMatthieu Baerts	done
2401826d7bdcSMatthieu Baertsfi
2402826d7bdcSMatthieu Baerts
2403b08fbf24SPaolo Abeniexit $ret
2404