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
18a673321aSMat Martineaudo_all_tests=1
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
62b08fbf24SPaolo Abeni	#  ns1              ns2
63b08fbf24SPaolo Abeni	# ns1eth1    ns2eth1
64b08fbf24SPaolo Abeni	# ns1eth2    ns2eth2
65b08fbf24SPaolo Abeni	# ns1eth3    ns2eth3
66b08fbf24SPaolo Abeni	# ns1eth4    ns2eth4
67b08fbf24SPaolo Abeni
68b08fbf24SPaolo Abeni	for i in `seq 1 4`; do
69b08fbf24SPaolo Abeni		ip link add ns1eth$i netns "$ns1" type veth peer name ns2eth$i netns "$ns2"
70b08fbf24SPaolo Abeni		ip -net "$ns1" addr add 10.0.$i.1/24 dev ns1eth$i
71b08fbf24SPaolo Abeni		ip -net "$ns1" addr add dead:beef:$i::1/64 dev ns1eth$i nodad
72b08fbf24SPaolo Abeni		ip -net "$ns1" link set ns1eth$i up
73b08fbf24SPaolo Abeni
74b08fbf24SPaolo Abeni		ip -net "$ns2" addr add 10.0.$i.2/24 dev ns2eth$i
75b08fbf24SPaolo Abeni		ip -net "$ns2" addr add dead:beef:$i::2/64 dev ns2eth$i nodad
76b08fbf24SPaolo Abeni		ip -net "$ns2" link set ns2eth$i up
77b08fbf24SPaolo Abeni
78b08fbf24SPaolo Abeni		# let $ns2 reach any $ns1 address from any interface
79b08fbf24SPaolo Abeni		ip -net "$ns2" route add default via 10.0.$i.1 dev ns2eth$i metric 10$i
809846921dSPaolo Abeni		ip -net "$ns2" route add default via dead:beef:$i::1 dev ns2eth$i metric 10$i
81b08fbf24SPaolo Abeni	done
82b08fbf24SPaolo Abeni}
83b08fbf24SPaolo Abeni
847d1e6f16SPaolo Abeniinit_shapers()
857d1e6f16SPaolo Abeni{
867d1e6f16SPaolo Abeni	for i in `seq 1 4`; do
877d1e6f16SPaolo Abeni		tc -n $ns1 qdisc add dev ns1eth$i root netem rate 20mbit delay 1
887d1e6f16SPaolo Abeni		tc -n $ns2 qdisc add dev ns2eth$i root netem rate 20mbit delay 1
897d1e6f16SPaolo Abeni	done
907d1e6f16SPaolo Abeni}
917d1e6f16SPaolo Abeni
92b08fbf24SPaolo Abenicleanup_partial()
93b08fbf24SPaolo Abeni{
94b08fbf24SPaolo Abeni	rm -f "$capout"
95b08fbf24SPaolo Abeni
96b08fbf24SPaolo Abeni	for netns in "$ns1" "$ns2"; do
97b08fbf24SPaolo Abeni		ip netns del $netns
98c2a55e8fSMatthieu Baerts		rm -f /tmp/$netns.{nstat,out}
99b08fbf24SPaolo Abeni	done
100b08fbf24SPaolo Abeni}
101b08fbf24SPaolo Abeni
10287154755SMatthieu Baertscheck_tools()
10387154755SMatthieu Baerts{
10487154755SMatthieu Baerts	if ! ip -Version &> /dev/null; then
10587154755SMatthieu Baerts		echo "SKIP: Could not run test without ip tool"
10687154755SMatthieu Baerts		exit $ksft_skip
10787154755SMatthieu Baerts	fi
10887154755SMatthieu Baerts
10987154755SMatthieu Baerts	if ! iptables -V &> /dev/null; then
11087154755SMatthieu Baerts		echo "SKIP: Could not run all tests without iptables tool"
11187154755SMatthieu Baerts		exit $ksft_skip
11287154755SMatthieu Baerts	fi
11387154755SMatthieu Baerts
11487154755SMatthieu Baerts	if ! ip6tables -V &> /dev/null; then
11587154755SMatthieu Baerts		echo "SKIP: Could not run all tests without ip6tables tool"
11687154755SMatthieu Baerts		exit $ksft_skip
11787154755SMatthieu Baerts	fi
11887154755SMatthieu Baerts}
11987154755SMatthieu Baerts
12093827ad5SMatthieu Baertsinit() {
12193827ad5SMatthieu Baerts	init=1
12293827ad5SMatthieu Baerts
12387154755SMatthieu Baerts	check_tools
12487154755SMatthieu Baerts
12593827ad5SMatthieu Baerts	sin=$(mktemp)
12693827ad5SMatthieu Baerts	sout=$(mktemp)
12793827ad5SMatthieu Baerts	cin=$(mktemp)
12893827ad5SMatthieu Baerts	cinsent=$(mktemp)
12993827ad5SMatthieu Baerts	cout=$(mktemp)
13093827ad5SMatthieu Baerts
13193827ad5SMatthieu Baerts	trap cleanup EXIT
13293827ad5SMatthieu Baerts
13393827ad5SMatthieu Baerts	make_file "$cin" "client" 1
13493827ad5SMatthieu Baerts	make_file "$sin" "server" 1
13593827ad5SMatthieu Baerts}
13693827ad5SMatthieu Baerts
137b08fbf24SPaolo Abenicleanup()
138b08fbf24SPaolo Abeni{
1397d1e6f16SPaolo Abeni	rm -f "$cin" "$cout" "$sinfail"
1407d1e6f16SPaolo Abeni	rm -f "$sin" "$sout" "$cinsent" "$cinfail"
141b08fbf24SPaolo Abeni	cleanup_partial
142b08fbf24SPaolo Abeni}
143b08fbf24SPaolo Abeni
144b08fbf24SPaolo Abenireset()
145b08fbf24SPaolo Abeni{
14693827ad5SMatthieu Baerts	if [ "${init}" != "1" ]; then
147b08fbf24SPaolo Abeni		init
14893827ad5SMatthieu Baerts	else
14993827ad5SMatthieu Baerts		cleanup_partial
15093827ad5SMatthieu Baerts	fi
15193827ad5SMatthieu Baerts
15293827ad5SMatthieu Baerts	init_partial
153b08fbf24SPaolo Abeni}
154b08fbf24SPaolo Abeni
15500587187SFlorian Westphalreset_with_cookies()
15600587187SFlorian Westphal{
15700587187SFlorian Westphal	reset
15800587187SFlorian Westphal
15900587187SFlorian Westphal	for netns in "$ns1" "$ns2";do
16000587187SFlorian Westphal		ip netns exec $netns sysctl -q net.ipv4.tcp_syncookies=2
16100587187SFlorian Westphal	done
16200587187SFlorian Westphal}
16300587187SFlorian Westphal
1648d014eaaSGeliang Tangreset_with_add_addr_timeout()
1658d014eaaSGeliang Tang{
1668d014eaaSGeliang Tang	local ip="${1:-4}"
1678d014eaaSGeliang Tang	local tables
1688d014eaaSGeliang Tang
1698d014eaaSGeliang Tang	tables="iptables"
1708d014eaaSGeliang Tang	if [ $ip -eq 6 ]; then
1718d014eaaSGeliang Tang		tables="ip6tables"
1728d014eaaSGeliang Tang	fi
1738d014eaaSGeliang Tang
1748d014eaaSGeliang Tang	reset
1758d014eaaSGeliang Tang
1768d014eaaSGeliang Tang	ip netns exec $ns1 sysctl -q net.mptcp.add_addr_timeout=1
1778d014eaaSGeliang Tang	ip netns exec $ns2 $tables -A OUTPUT -p tcp \
1788d014eaaSGeliang Tang		-m tcp --tcp-option 30 \
1798d014eaaSGeliang Tang		-m bpf --bytecode \
1808d014eaaSGeliang Tang		"$CBPF_MPTCP_SUBOPTION_ADD_ADDR" \
1818d014eaaSGeliang Tang		-j DROP
1828d014eaaSGeliang Tang}
1838d014eaaSGeliang Tang
184af66d3e1SGeliang Tangreset_with_checksum()
185af66d3e1SGeliang Tang{
186af66d3e1SGeliang Tang	local ns1_enable=$1
187af66d3e1SGeliang Tang	local ns2_enable=$2
188af66d3e1SGeliang Tang
189af66d3e1SGeliang Tang	reset
190af66d3e1SGeliang Tang
191af66d3e1SGeliang Tang	ip netns exec $ns1 sysctl -q net.mptcp.checksum_enabled=$ns1_enable
192af66d3e1SGeliang Tang	ip netns exec $ns2 sysctl -q net.mptcp.checksum_enabled=$ns2_enable
193af66d3e1SGeliang Tang}
194af66d3e1SGeliang Tang
1950cddb4a6SGeliang Tangreset_with_allow_join_id0()
1960cddb4a6SGeliang Tang{
1970cddb4a6SGeliang Tang	local ns1_enable=$1
1980cddb4a6SGeliang Tang	local ns2_enable=$2
1990cddb4a6SGeliang Tang
2000cddb4a6SGeliang Tang	reset
2010cddb4a6SGeliang Tang
2020cddb4a6SGeliang Tang	ip netns exec $ns1 sysctl -q net.mptcp.allow_join_initial_addr_port=$ns1_enable
2030cddb4a6SGeliang Tang	ip netns exec $ns2 sysctl -q net.mptcp.allow_join_initial_addr_port=$ns2_enable
2040cddb4a6SGeliang Tang}
2050cddb4a6SGeliang Tang
2068b819a84SFlorian Westphalprint_file_err()
2078b819a84SFlorian Westphal{
2088b819a84SFlorian Westphal	ls -l "$1" 1>&2
2098b819a84SFlorian Westphal	echo "Trailing bytes are: "
2108b819a84SFlorian Westphal	tail -c 27 "$1"
2118b819a84SFlorian Westphal}
2128b819a84SFlorian Westphal
213b08fbf24SPaolo Abenicheck_transfer()
214b08fbf24SPaolo Abeni{
215b08fbf24SPaolo Abeni	in=$1
216b08fbf24SPaolo Abeni	out=$2
217b08fbf24SPaolo Abeni	what=$3
218b08fbf24SPaolo Abeni
219b08fbf24SPaolo Abeni	cmp "$in" "$out" > /dev/null 2>&1
220b08fbf24SPaolo Abeni	if [ $? -ne 0 ] ;then
221b08fbf24SPaolo Abeni		echo "[ FAIL ] $what does not match (in, out):"
222b08fbf24SPaolo Abeni		print_file_err "$in"
223b08fbf24SPaolo Abeni		print_file_err "$out"
2248b819a84SFlorian Westphal		ret=1
225b08fbf24SPaolo Abeni
226b08fbf24SPaolo Abeni		return 1
227b08fbf24SPaolo Abeni	fi
228b08fbf24SPaolo Abeni
229b08fbf24SPaolo Abeni	return 0
230b08fbf24SPaolo Abeni}
231b08fbf24SPaolo Abeni
232b08fbf24SPaolo Abenido_ping()
233b08fbf24SPaolo Abeni{
234b08fbf24SPaolo Abeni	listener_ns="$1"
235b08fbf24SPaolo Abeni	connector_ns="$2"
236b08fbf24SPaolo Abeni	connect_addr="$3"
237b08fbf24SPaolo Abeni
238b08fbf24SPaolo Abeni	ip netns exec ${connector_ns} ping -q -c 1 $connect_addr >/dev/null
239b08fbf24SPaolo Abeni	if [ $? -ne 0 ] ; then
240b08fbf24SPaolo Abeni		echo "$listener_ns -> $connect_addr connectivity [ FAIL ]" 1>&2
241b08fbf24SPaolo Abeni		ret=1
242b08fbf24SPaolo Abeni	fi
243b08fbf24SPaolo Abeni}
244b08fbf24SPaolo Abeni
2458b819a84SFlorian Westphallink_failure()
2468b819a84SFlorian Westphal{
2478b819a84SFlorian Westphal	ns="$1"
2488b819a84SFlorian Westphal
2497d1e6f16SPaolo Abeni	if [ -z "$FAILING_LINKS" ]; then
2508b819a84SFlorian Westphal		l=$((RANDOM%4))
2517d1e6f16SPaolo Abeni		FAILING_LINKS=$((l+1))
2527d1e6f16SPaolo Abeni	fi
2538b819a84SFlorian Westphal
2547d1e6f16SPaolo Abeni	for l in $FAILING_LINKS; do
2558b819a84SFlorian Westphal		veth="ns1eth$l"
2568b819a84SFlorian Westphal		ip -net "$ns" link set "$veth" down
2577d1e6f16SPaolo Abeni	done
2588b819a84SFlorian Westphal}
2598b819a84SFlorian Westphal
260523514edSGeliang Tang# $1: IP address
261523514edSGeliang Tangis_v6()
262523514edSGeliang Tang{
263523514edSGeliang Tang	[ -z "${1##*:*}" ]
264523514edSGeliang Tang}
265523514edSGeliang Tang
266327b9a94SPaolo Abeni# $1: ns, $2: port
267327b9a94SPaolo Abeniwait_local_port_listen()
268327b9a94SPaolo Abeni{
269327b9a94SPaolo Abeni	local listener_ns="${1}"
270327b9a94SPaolo Abeni	local port="${2}"
271327b9a94SPaolo Abeni
272327b9a94SPaolo Abeni	local port_hex i
273327b9a94SPaolo Abeni
274327b9a94SPaolo Abeni	port_hex="$(printf "%04X" "${port}")"
275327b9a94SPaolo Abeni	for i in $(seq 10); do
276327b9a94SPaolo Abeni		ip netns exec "${listener_ns}" cat /proc/net/tcp* | \
277327b9a94SPaolo Abeni			awk "BEGIN {rc=1} {if (\$2 ~ /:${port_hex}\$/ && \$4 ~ /0A/) {rc=0; exit}} END {exit rc}" &&
278327b9a94SPaolo Abeni			break
279327b9a94SPaolo Abeni		sleep 0.1
280327b9a94SPaolo Abeni	done
281327b9a94SPaolo Abeni}
282327b9a94SPaolo Abeni
283327b9a94SPaolo Abenirm_addr_count()
284327b9a94SPaolo Abeni{
285327b9a94SPaolo Abeni	ns=${1}
286327b9a94SPaolo Abeni
287327b9a94SPaolo Abeni	ip netns exec ${ns} nstat -as | grep MPTcpExtRmAddr | awk '{print $2}'
288327b9a94SPaolo Abeni}
289327b9a94SPaolo Abeni
290327b9a94SPaolo Abeni# $1: ns, $2: old rm_addr counter in $ns
291327b9a94SPaolo Abeniwait_rm_addr()
292327b9a94SPaolo Abeni{
293327b9a94SPaolo Abeni	local ns="${1}"
294327b9a94SPaolo Abeni	local old_cnt="${2}"
295327b9a94SPaolo Abeni	local cnt
296327b9a94SPaolo Abeni	local i
297327b9a94SPaolo Abeni
298327b9a94SPaolo Abeni	for i in $(seq 10); do
299327b9a94SPaolo Abeni		cnt=$(rm_addr_count ${ns})
300327b9a94SPaolo Abeni		[ "$cnt" = "${old_cnt}" ] || break
301327b9a94SPaolo Abeni		sleep 0.1
302327b9a94SPaolo Abeni	done
303327b9a94SPaolo Abeni}
304327b9a94SPaolo Abeni
30534aa6e3bSGeliang Tangpm_nl_set_limits()
30634aa6e3bSGeliang Tang{
30734aa6e3bSGeliang Tang	local ns=$1
30834aa6e3bSGeliang Tang	local addrs=$2
30934aa6e3bSGeliang Tang	local subflows=$3
31034aa6e3bSGeliang Tang
31134aa6e3bSGeliang Tang	if [ $ip_mptcp -eq 1 ]; then
31234aa6e3bSGeliang Tang		ip -n $ns mptcp limits set add_addr_accepted $addrs subflows $subflows
31334aa6e3bSGeliang Tang	else
31434aa6e3bSGeliang Tang		ip netns exec $ns ./pm_nl_ctl limits $addrs $subflows
31534aa6e3bSGeliang Tang	fi
31634aa6e3bSGeliang Tang}
31734aa6e3bSGeliang Tang
31834aa6e3bSGeliang Tangpm_nl_add_endpoint()
31934aa6e3bSGeliang Tang{
32034aa6e3bSGeliang Tang	local ns=$1
32134aa6e3bSGeliang Tang	local addr=$2
32234aa6e3bSGeliang Tang	local flags
32334aa6e3bSGeliang Tang	local port
32434aa6e3bSGeliang Tang	local dev
32534aa6e3bSGeliang Tang	local id
32634aa6e3bSGeliang Tang	local nr=2
32734aa6e3bSGeliang Tang
32834aa6e3bSGeliang Tang	for p in $@
32934aa6e3bSGeliang Tang	do
33034aa6e3bSGeliang Tang		if [ $p = "flags" ]; then
33134aa6e3bSGeliang Tang			eval _flags=\$"$nr"
33234aa6e3bSGeliang Tang			[ ! -z $_flags ]; flags="flags $_flags"
33334aa6e3bSGeliang Tang		fi
33434aa6e3bSGeliang Tang		if [ $p = "dev" ]; then
33534aa6e3bSGeliang Tang			eval _dev=\$"$nr"
33634aa6e3bSGeliang Tang			[ ! -z $_dev ]; dev="dev $_dev"
33734aa6e3bSGeliang Tang		fi
33834aa6e3bSGeliang Tang		if [ $p = "id" ]; then
33934aa6e3bSGeliang Tang			eval _id=\$"$nr"
34034aa6e3bSGeliang Tang			[ ! -z $_id ]; id="id $_id"
34134aa6e3bSGeliang Tang		fi
34234aa6e3bSGeliang Tang		if [ $p = "port" ]; then
34334aa6e3bSGeliang Tang			eval _port=\$"$nr"
34434aa6e3bSGeliang Tang			[ ! -z $_port ]; port="port $_port"
34534aa6e3bSGeliang Tang		fi
34634aa6e3bSGeliang Tang
34734aa6e3bSGeliang Tang		let nr+=1
34834aa6e3bSGeliang Tang	done
34934aa6e3bSGeliang Tang
35034aa6e3bSGeliang Tang	if [ $ip_mptcp -eq 1 ]; then
35134aa6e3bSGeliang Tang		ip -n $ns mptcp endpoint add $addr ${_flags//","/" "} $dev $id $port
35234aa6e3bSGeliang Tang	else
35334aa6e3bSGeliang Tang		ip netns exec $ns ./pm_nl_ctl add $addr $flags $dev $id $port
35434aa6e3bSGeliang Tang	fi
35534aa6e3bSGeliang Tang}
35634aa6e3bSGeliang Tang
35734aa6e3bSGeliang Tangpm_nl_del_endpoint()
35834aa6e3bSGeliang Tang{
35934aa6e3bSGeliang Tang	local ns=$1
36034aa6e3bSGeliang Tang	local id=$2
36134aa6e3bSGeliang Tang	local addr=$3
36234aa6e3bSGeliang Tang
36334aa6e3bSGeliang Tang	if [ $ip_mptcp -eq 1 ]; then
36434aa6e3bSGeliang Tang		ip -n $ns mptcp endpoint delete id $id $addr
36534aa6e3bSGeliang Tang	else
36634aa6e3bSGeliang Tang		ip netns exec $ns ./pm_nl_ctl del $id $addr
36734aa6e3bSGeliang Tang	fi
36834aa6e3bSGeliang Tang}
36934aa6e3bSGeliang Tang
37034aa6e3bSGeliang Tangpm_nl_flush_endpoint()
37134aa6e3bSGeliang Tang{
37234aa6e3bSGeliang Tang	local ns=$1
37334aa6e3bSGeliang Tang
37434aa6e3bSGeliang Tang	if [ $ip_mptcp -eq 1 ]; then
37534aa6e3bSGeliang Tang		ip -n $ns mptcp endpoint flush
37634aa6e3bSGeliang Tang	else
37734aa6e3bSGeliang Tang		ip netns exec $ns ./pm_nl_ctl flush
37834aa6e3bSGeliang Tang	fi
37934aa6e3bSGeliang Tang}
38034aa6e3bSGeliang Tang
381dda61b3dSGeliang Tangpm_nl_show_endpoints()
382dda61b3dSGeliang Tang{
383dda61b3dSGeliang Tang	local ns=$1
384dda61b3dSGeliang Tang
385dda61b3dSGeliang Tang	if [ $ip_mptcp -eq 1 ]; then
386dda61b3dSGeliang Tang		ip -n $ns mptcp endpoint show
387dda61b3dSGeliang Tang	else
388dda61b3dSGeliang Tang		ip netns exec $ns ./pm_nl_ctl dump
389dda61b3dSGeliang Tang	fi
390dda61b3dSGeliang Tang}
391dda61b3dSGeliang Tang
392f0140386SGeliang Tangpm_nl_change_endpoint()
393f0140386SGeliang Tang{
394f0140386SGeliang Tang	local ns=$1
395bccefb76SGeliang Tang	local id=$2
396bccefb76SGeliang Tang	local flags=$3
397f0140386SGeliang Tang
398f0140386SGeliang Tang	if [ $ip_mptcp -eq 1 ]; then
399f0140386SGeliang Tang		ip -n $ns mptcp endpoint change id $id ${flags//","/" "}
400f0140386SGeliang Tang	else
401bccefb76SGeliang Tang		ip netns exec $ns ./pm_nl_ctl set id $id flags $flags
402f0140386SGeliang Tang	fi
403f0140386SGeliang Tang}
404f0140386SGeliang Tang
405b08fbf24SPaolo Abenido_transfer()
406b08fbf24SPaolo Abeni{
407b08fbf24SPaolo Abeni	listener_ns="$1"
408b08fbf24SPaolo Abeni	connector_ns="$2"
409b08fbf24SPaolo Abeni	cl_proto="$3"
410b08fbf24SPaolo Abeni	srv_proto="$4"
411b08fbf24SPaolo Abeni	connect_addr="$5"
4128b819a84SFlorian Westphal	test_link_fail="$6"
4132e8cbf45SGeliang Tang	addr_nr_ns1="$7"
4142e8cbf45SGeliang Tang	addr_nr_ns2="$8"
4158b819a84SFlorian Westphal	speed="$9"
4166a0653b9SGeliang Tang	sflags="${10}"
417b08fbf24SPaolo Abeni
418b08fbf24SPaolo Abeni	port=$((10000+$TEST_COUNT))
419b08fbf24SPaolo Abeni	TEST_COUNT=$((TEST_COUNT+1))
420b08fbf24SPaolo Abeni
421b08fbf24SPaolo Abeni	:> "$cout"
422b08fbf24SPaolo Abeni	:> "$sout"
423b08fbf24SPaolo Abeni	:> "$capout"
424b08fbf24SPaolo Abeni
425b08fbf24SPaolo Abeni	if [ $capture -eq 1 ]; then
426b08fbf24SPaolo Abeni		if [ -z $SUDO_USER ] ; then
427b08fbf24SPaolo Abeni			capuser=""
428b08fbf24SPaolo Abeni		else
429b08fbf24SPaolo Abeni			capuser="-Z $SUDO_USER"
430b08fbf24SPaolo Abeni		fi
431b08fbf24SPaolo Abeni
43200587187SFlorian Westphal		capfile=$(printf "mp_join-%02u-%s.pcap" "$TEST_COUNT" "${listener_ns}")
433b08fbf24SPaolo Abeni
434b08fbf24SPaolo Abeni		echo "Capturing traffic for test $TEST_COUNT into $capfile"
435b08fbf24SPaolo Abeni		ip netns exec ${listener_ns} tcpdump -i any -s 65535 -B 32768 $capuser -w $capfile > "$capout" 2>&1 &
436b08fbf24SPaolo Abeni		cappid=$!
437b08fbf24SPaolo Abeni
438b08fbf24SPaolo Abeni		sleep 1
439b08fbf24SPaolo Abeni	fi
440b08fbf24SPaolo Abeni
441c2a55e8fSMatthieu Baerts	NSTAT_HISTORY=/tmp/${listener_ns}.nstat ip netns exec ${listener_ns} \
442c2a55e8fSMatthieu Baerts		nstat -n
443c2a55e8fSMatthieu Baerts	NSTAT_HISTORY=/tmp/${connector_ns}.nstat ip netns exec ${connector_ns} \
444c2a55e8fSMatthieu Baerts		nstat -n
445c2a55e8fSMatthieu Baerts
446*cbfafac4SGeliang Tang	local extra_args
4478d014eaaSGeliang Tang	if [ $speed = "fast" ]; then
448*cbfafac4SGeliang Tang		extra_args="-j"
4498da6229bSGeliang Tang	elif [ $speed = "slow" ]; then
450*cbfafac4SGeliang Tang		extra_args="-r 50"
451*cbfafac4SGeliang Tang	elif [[ $speed = "speed_"* ]]; then
452*cbfafac4SGeliang Tang		extra_args="-r ${speed:6}"
453dd72b0feSGeliang Tang	fi
454dd72b0feSGeliang Tang
455523514edSGeliang Tang	local local_addr
456523514edSGeliang Tang	if is_v6 "${connect_addr}"; then
457523514edSGeliang Tang		local_addr="::"
458523514edSGeliang Tang	else
459523514edSGeliang Tang		local_addr="0.0.0.0"
460523514edSGeliang Tang	fi
461523514edSGeliang Tang
4627d1e6f16SPaolo Abeni	if [ "$test_link_fail" -eq 2 ];then
4637d1e6f16SPaolo Abeni		timeout ${timeout_test} \
4647d1e6f16SPaolo Abeni			ip netns exec ${listener_ns} \
465*cbfafac4SGeliang Tang				./mptcp_connect -t ${timeout_poll} -l -p $port -s ${srv_proto} \
466*cbfafac4SGeliang Tang					$extra_args ${local_addr} < "$sinfail" > "$sout" &
4677d1e6f16SPaolo Abeni	else
4685888a61cSMatthieu Baerts		timeout ${timeout_test} \
4695888a61cSMatthieu Baerts			ip netns exec ${listener_ns} \
470*cbfafac4SGeliang Tang				./mptcp_connect -t ${timeout_poll} -l -p $port -s ${srv_proto} \
471*cbfafac4SGeliang Tang					$extra_args ${local_addr} < "$sin" > "$sout" &
4727d1e6f16SPaolo Abeni	fi
473b08fbf24SPaolo Abeni	spid=$!
474b08fbf24SPaolo Abeni
475327b9a94SPaolo Abeni	wait_local_port_listen "${listener_ns}" "${port}"
476b08fbf24SPaolo Abeni
4778b819a84SFlorian Westphal	if [ "$test_link_fail" -eq 0 ];then
4785888a61cSMatthieu Baerts		timeout ${timeout_test} \
4795888a61cSMatthieu Baerts			ip netns exec ${connector_ns} \
480*cbfafac4SGeliang Tang				./mptcp_connect -t ${timeout_poll} -p $port -s ${cl_proto} \
481*cbfafac4SGeliang Tang					$extra_args $connect_addr < "$cin" > "$cout" &
4828b819a84SFlorian Westphal	else
4837d1e6f16SPaolo Abeni		( cat "$cinfail" ; sleep 2; link_failure $listener_ns ; cat "$cinfail" ) | \
4845888a61cSMatthieu Baerts			tee "$cinsent" | \
4855888a61cSMatthieu Baerts			timeout ${timeout_test} \
4865888a61cSMatthieu Baerts				ip netns exec ${connector_ns} \
487*cbfafac4SGeliang Tang					./mptcp_connect -t ${timeout_poll} -p $port -s ${cl_proto} \
488*cbfafac4SGeliang Tang						$extra_args $connect_addr > "$cout" &
4898b819a84SFlorian Westphal	fi
490b08fbf24SPaolo Abeni	cpid=$!
491b08fbf24SPaolo Abeni
492327b9a94SPaolo Abeni	# let the mptcp subflow be established in background before
493327b9a94SPaolo Abeni	# do endpoint manipulation
494327b9a94SPaolo Abeni	[ $addr_nr_ns1 = "0" -a $addr_nr_ns2 = "0" ] || sleep 1
495327b9a94SPaolo Abeni
4966208fd82SGeliang Tang	if [ $addr_nr_ns1 -gt 0 ]; then
4976208fd82SGeliang Tang		let add_nr_ns1=addr_nr_ns1
4986208fd82SGeliang Tang		counter=2
4996208fd82SGeliang Tang		while [ $add_nr_ns1 -gt 0 ]; do
5006208fd82SGeliang Tang			local addr
5016208fd82SGeliang Tang			if is_v6 "${connect_addr}"; then
5026208fd82SGeliang Tang				addr="dead:beef:$counter::1"
5036208fd82SGeliang Tang			else
5046208fd82SGeliang Tang				addr="10.0.$counter.1"
5056208fd82SGeliang Tang			fi
50634aa6e3bSGeliang Tang			pm_nl_add_endpoint $ns1 $addr flags signal
5076208fd82SGeliang Tang			let counter+=1
5086208fd82SGeliang Tang			let add_nr_ns1-=1
5096208fd82SGeliang Tang		done
5106208fd82SGeliang Tang	elif [ $addr_nr_ns1 -lt 0 ]; then
5112e8cbf45SGeliang Tang		let rm_nr_ns1=-addr_nr_ns1
5126fe4ccdcSGeliang Tang		if [ $rm_nr_ns1 -lt 8 ]; then
513dda61b3dSGeliang Tang			counter=0
514dda61b3dSGeliang Tang			pm_nl_show_endpoints ${listener_ns} | while read line; do
515dda61b3dSGeliang Tang				local arr=($line)
516dda61b3dSGeliang Tang				local nr=0
517dda61b3dSGeliang Tang
518dda61b3dSGeliang Tang				for i in ${arr[@]}; do
519dda61b3dSGeliang Tang					if [ $i = "id" ]; then
520dda61b3dSGeliang Tang						if [ $counter -eq $rm_nr_ns1 ]; then
521dda61b3dSGeliang Tang							break
522dda61b3dSGeliang Tang						fi
523dda61b3dSGeliang Tang						id=${arr[$nr+1]}
524327b9a94SPaolo Abeni						rm_addr=$(rm_addr_count ${connector_ns})
52534aa6e3bSGeliang Tang						pm_nl_del_endpoint ${listener_ns} $id
526327b9a94SPaolo Abeni						wait_rm_addr ${connector_ns} ${rm_addr}
527dd72b0feSGeliang Tang						let counter+=1
528f87744adSGeliang Tang					fi
529dda61b3dSGeliang Tang					let nr+=1
530dda61b3dSGeliang Tang				done
531dda61b3dSGeliang Tang			done
5325e287fe7SGeliang Tang		elif [ $rm_nr_ns1 -eq 8 ]; then
53334aa6e3bSGeliang Tang			pm_nl_flush_endpoint ${listener_ns}
5345e287fe7SGeliang Tang		elif [ $rm_nr_ns1 -eq 9 ]; then
53534aa6e3bSGeliang Tang			pm_nl_del_endpoint ${listener_ns} 0 ${connect_addr}
5366fe4ccdcSGeliang Tang		fi
537dd72b0feSGeliang Tang	fi
538dd72b0feSGeliang Tang
5394f49d633SGeliang Tang	flags="subflow"
5404f49d633SGeliang Tang	if [[ "${addr_nr_ns2}" = "fullmesh_"* ]]; then
5414f49d633SGeliang Tang		flags="${flags},fullmesh"
5424f49d633SGeliang Tang		addr_nr_ns2=${addr_nr_ns2:9}
5434f49d633SGeliang Tang	fi
5444f49d633SGeliang Tang
545327b9a94SPaolo Abeni	# if newly added endpoints must be deleted, give the background msk
546327b9a94SPaolo Abeni	# some time to created them
547327b9a94SPaolo Abeni	[ $addr_nr_ns1 -gt 0 -a $addr_nr_ns2 -lt 0 ] && sleep 1
548327b9a94SPaolo Abeni
5496208fd82SGeliang Tang	if [ $addr_nr_ns2 -gt 0 ]; then
5506208fd82SGeliang Tang		let add_nr_ns2=addr_nr_ns2
5516208fd82SGeliang Tang		counter=3
5526208fd82SGeliang Tang		while [ $add_nr_ns2 -gt 0 ]; do
5536208fd82SGeliang Tang			local addr
5546208fd82SGeliang Tang			if is_v6 "${connect_addr}"; then
5556208fd82SGeliang Tang				addr="dead:beef:$counter::2"
5566208fd82SGeliang Tang			else
5576208fd82SGeliang Tang				addr="10.0.$counter.2"
5586208fd82SGeliang Tang			fi
55934aa6e3bSGeliang Tang			pm_nl_add_endpoint $ns2 $addr flags $flags
5606208fd82SGeliang Tang			let counter+=1
5616208fd82SGeliang Tang			let add_nr_ns2-=1
5626208fd82SGeliang Tang		done
5636208fd82SGeliang Tang	elif [ $addr_nr_ns2 -lt 0 ]; then
5642e8cbf45SGeliang Tang		let rm_nr_ns2=-addr_nr_ns2
5656fe4ccdcSGeliang Tang		if [ $rm_nr_ns2 -lt 8 ]; then
566dda61b3dSGeliang Tang			counter=0
567dda61b3dSGeliang Tang			pm_nl_show_endpoints ${connector_ns} | while read line; do
568dda61b3dSGeliang Tang				local arr=($line)
569dda61b3dSGeliang Tang				local nr=0
570dda61b3dSGeliang Tang
571dda61b3dSGeliang Tang				for i in ${arr[@]}; do
572dda61b3dSGeliang Tang					if [ $i = "id" ]; then
573dda61b3dSGeliang Tang						if [ $counter -eq $rm_nr_ns2 ]; then
574dda61b3dSGeliang Tang							break
575dda61b3dSGeliang Tang						fi
576dda61b3dSGeliang Tang						# rm_addr are serialized, allow the previous one to
577dda61b3dSGeliang Tang						# complete
578dda61b3dSGeliang Tang						id=${arr[$nr+1]}
579327b9a94SPaolo Abeni						rm_addr=$(rm_addr_count ${listener_ns})
58034aa6e3bSGeliang Tang						pm_nl_del_endpoint ${connector_ns} $id
581327b9a94SPaolo Abeni						wait_rm_addr ${listener_ns} ${rm_addr}
582dd72b0feSGeliang Tang						let counter+=1
583f87744adSGeliang Tang					fi
584dda61b3dSGeliang Tang					let nr+=1
585dda61b3dSGeliang Tang				done
586dda61b3dSGeliang Tang			done
5875e287fe7SGeliang Tang		elif [ $rm_nr_ns2 -eq 8 ]; then
58834aa6e3bSGeliang Tang			pm_nl_flush_endpoint ${connector_ns}
5895e287fe7SGeliang Tang		elif [ $rm_nr_ns2 -eq 9 ]; then
5905e287fe7SGeliang Tang			local addr
5915e287fe7SGeliang Tang			if is_v6 "${connect_addr}"; then
5925e287fe7SGeliang Tang				addr="dead:beef:1::2"
5935e287fe7SGeliang Tang			else
5945e287fe7SGeliang Tang				addr="10.0.1.2"
5955e287fe7SGeliang Tang			fi
59634aa6e3bSGeliang Tang			pm_nl_del_endpoint ${connector_ns} 0 $addr
5976fe4ccdcSGeliang Tang		fi
598dd72b0feSGeliang Tang	fi
599dd72b0feSGeliang Tang
6006a0653b9SGeliang Tang	if [ ! -z $sflags ]; then
601718eb44eSGeliang Tang		sleep 1
602718eb44eSGeliang Tang		for netns in "$ns1" "$ns2"; do
603dda61b3dSGeliang Tang			pm_nl_show_endpoints $netns | while read line; do
60433397b83SGeliang Tang				local arr=($line)
605bccefb76SGeliang Tang				local nr=0
606f0140386SGeliang Tang				local id
60733397b83SGeliang Tang
60833397b83SGeliang Tang				for i in ${arr[@]}; do
609bccefb76SGeliang Tang					if [ $i = "id" ]; then
610bccefb76SGeliang Tang						id=${arr[$nr+1]}
611718eb44eSGeliang Tang					fi
612bccefb76SGeliang Tang					let nr+=1
61333397b83SGeliang Tang				done
614bccefb76SGeliang Tang				pm_nl_change_endpoint $netns $id $sflags
61533397b83SGeliang Tang			done
616718eb44eSGeliang Tang		done
617718eb44eSGeliang Tang	fi
618718eb44eSGeliang Tang
619b08fbf24SPaolo Abeni	wait $cpid
620b08fbf24SPaolo Abeni	retc=$?
621b08fbf24SPaolo Abeni	wait $spid
622b08fbf24SPaolo Abeni	rets=$?
623b08fbf24SPaolo Abeni
624b08fbf24SPaolo Abeni	if [ $capture -eq 1 ]; then
625b08fbf24SPaolo Abeni	    sleep 1
626b08fbf24SPaolo Abeni	    kill $cappid
627b08fbf24SPaolo Abeni	fi
628b08fbf24SPaolo Abeni
629c2a55e8fSMatthieu Baerts	NSTAT_HISTORY=/tmp/${listener_ns}.nstat ip netns exec ${listener_ns} \
630c2a55e8fSMatthieu Baerts		nstat | grep Tcp > /tmp/${listener_ns}.out
631c2a55e8fSMatthieu Baerts	NSTAT_HISTORY=/tmp/${connector_ns}.nstat ip netns exec ${connector_ns} \
632c2a55e8fSMatthieu Baerts		nstat | grep Tcp > /tmp/${connector_ns}.out
633c2a55e8fSMatthieu Baerts
634b08fbf24SPaolo Abeni	if [ ${rets} -ne 0 ] || [ ${retc} -ne 0 ]; then
635b08fbf24SPaolo Abeni		echo " client exit code $retc, server $rets" 1>&2
6368b974778SMatthieu Baerts		echo -e "\nnetns ${listener_ns} socket stat for ${port}:" 1>&2
637c2a55e8fSMatthieu Baerts		ip netns exec ${listener_ns} ss -Menita 1>&2 -o "sport = :$port"
638c2a55e8fSMatthieu Baerts		cat /tmp/${listener_ns}.out
6398b974778SMatthieu Baerts		echo -e "\nnetns ${connector_ns} socket stat for ${port}:" 1>&2
640c2a55e8fSMatthieu Baerts		ip netns exec ${connector_ns} ss -Menita 1>&2 -o "dport = :$port"
641c2a55e8fSMatthieu Baerts		cat /tmp/${connector_ns}.out
642b08fbf24SPaolo Abeni
643b08fbf24SPaolo Abeni		cat "$capout"
6448b819a84SFlorian Westphal		ret=1
645b08fbf24SPaolo Abeni		return 1
646b08fbf24SPaolo Abeni	fi
647b08fbf24SPaolo Abeni
6487d1e6f16SPaolo Abeni	if [ "$test_link_fail" -eq 2 ];then
6497d1e6f16SPaolo Abeni		check_transfer $sinfail $cout "file received by client"
6507d1e6f16SPaolo Abeni	else
651b08fbf24SPaolo Abeni		check_transfer $sin $cout "file received by client"
6527d1e6f16SPaolo Abeni	fi
653b08fbf24SPaolo Abeni	retc=$?
6548b819a84SFlorian Westphal	if [ "$test_link_fail" -eq 0 ];then
655b08fbf24SPaolo Abeni		check_transfer $cin $sout "file received by server"
6568b819a84SFlorian Westphal	else
6578b819a84SFlorian Westphal		check_transfer $cinsent $sout "file received by server"
6588b819a84SFlorian Westphal	fi
659b08fbf24SPaolo Abeni	rets=$?
660b08fbf24SPaolo Abeni
661b08fbf24SPaolo Abeni	if [ $retc -eq 0 ] && [ $rets -eq 0 ];then
662b08fbf24SPaolo Abeni		cat "$capout"
663b08fbf24SPaolo Abeni		return 0
664b08fbf24SPaolo Abeni	fi
665b08fbf24SPaolo Abeni
666b08fbf24SPaolo Abeni	cat "$capout"
667b08fbf24SPaolo Abeni	return 1
668b08fbf24SPaolo Abeni}
669b08fbf24SPaolo Abeni
670b08fbf24SPaolo Abenimake_file()
671b08fbf24SPaolo Abeni{
672b08fbf24SPaolo Abeni	name=$1
673b08fbf24SPaolo Abeni	who=$2
6748b819a84SFlorian Westphal	size=$3
675b08fbf24SPaolo Abeni
6768b819a84SFlorian Westphal	dd if=/dev/urandom of="$name" bs=1024 count=$size 2> /dev/null
677b08fbf24SPaolo Abeni	echo -e "\nMPTCP_TEST_FILE_END_MARKER" >> "$name"
678b08fbf24SPaolo Abeni
6798b819a84SFlorian Westphal	echo "Created $name (size $size KB) containing data sent by $who"
680b08fbf24SPaolo Abeni}
681b08fbf24SPaolo Abeni
682b08fbf24SPaolo Abenirun_tests()
683b08fbf24SPaolo Abeni{
684b08fbf24SPaolo Abeni	listener_ns="$1"
685b08fbf24SPaolo Abeni	connector_ns="$2"
686b08fbf24SPaolo Abeni	connect_addr="$3"
6878b819a84SFlorian Westphal	test_linkfail="${4:-0}"
6882e8cbf45SGeliang Tang	addr_nr_ns1="${5:-0}"
6892e8cbf45SGeliang Tang	addr_nr_ns2="${6:-0}"
6908b819a84SFlorian Westphal	speed="${7:-fast}"
6916a0653b9SGeliang Tang	sflags="${8:-""}"
6928b819a84SFlorian Westphal
6937d1e6f16SPaolo Abeni	# create the input file for the failure test when
6947d1e6f16SPaolo Abeni	# the first failure test run
6957d1e6f16SPaolo Abeni	if [ "$test_linkfail" -ne 0 -a -z "$cinfail" ]; then
6967d1e6f16SPaolo Abeni		# the client file must be considerably larger
6977d1e6f16SPaolo Abeni		# of the maximum expected cwin value, or the
6987d1e6f16SPaolo Abeni		# link utilization will be not predicable
6997d1e6f16SPaolo Abeni		size=$((RANDOM%2))
7008b819a84SFlorian Westphal		size=$((size+1))
7017d1e6f16SPaolo Abeni		size=$((size*8192))
7027d1e6f16SPaolo Abeni		size=$((size + ( $RANDOM % 8192) ))
7038b819a84SFlorian Westphal
7047d1e6f16SPaolo Abeni		cinfail=$(mktemp)
7057d1e6f16SPaolo Abeni		make_file "$cinfail" "client" $size
7067d1e6f16SPaolo Abeni	fi
7077d1e6f16SPaolo Abeni
7087d1e6f16SPaolo Abeni	if [ "$test_linkfail" -eq 2 -a -z "$sinfail" ]; then
7097d1e6f16SPaolo Abeni		size=$((RANDOM%16))
7107d1e6f16SPaolo Abeni		size=$((size+1))
7117d1e6f16SPaolo Abeni		size=$((size*2048))
7127d1e6f16SPaolo Abeni
7137d1e6f16SPaolo Abeni		sinfail=$(mktemp)
7147d1e6f16SPaolo Abeni		make_file "$sinfail" "server" $size
7158b819a84SFlorian Westphal	fi
716b08fbf24SPaolo Abeni
7178d014eaaSGeliang Tang	do_transfer ${listener_ns} ${connector_ns} MPTCP MPTCP ${connect_addr} \
7186a0653b9SGeliang Tang		${test_linkfail} ${addr_nr_ns1} ${addr_nr_ns2} ${speed} ${sflags}
719b08fbf24SPaolo Abeni}
720b08fbf24SPaolo Abeni
721327b9a94SPaolo Abenidump_stats()
722327b9a94SPaolo Abeni{
723327b9a94SPaolo Abeni	echo Server ns stats
724327b9a94SPaolo Abeni	ip netns exec $ns1 nstat -as | grep Tcp
725327b9a94SPaolo Abeni	echo Client ns stats
726327b9a94SPaolo Abeni	ip netns exec $ns2 nstat -as | grep Tcp
727327b9a94SPaolo Abeni}
728327b9a94SPaolo Abeni
729af66d3e1SGeliang Tangchk_csum_nr()
730af66d3e1SGeliang Tang{
731af66d3e1SGeliang Tang	local msg=${1:-""}
732af66d3e1SGeliang Tang	local count
733af66d3e1SGeliang Tang	local dump_stats
734af66d3e1SGeliang Tang
735af66d3e1SGeliang Tang	if [ ! -z "$msg" ]; then
7369a0a9367SGeliang Tang		printf "%03u" "$TEST_COUNT"
737af66d3e1SGeliang Tang	else
738af66d3e1SGeliang Tang		echo -n "   "
739af66d3e1SGeliang Tang	fi
740af66d3e1SGeliang Tang	printf " %-36s %s" "$msg" "sum"
741af66d3e1SGeliang Tang	count=`ip netns exec $ns1 nstat -as | grep MPTcpExtDataCsumErr | awk '{print $2}'`
742af66d3e1SGeliang Tang	[ -z "$count" ] && count=0
743af66d3e1SGeliang Tang	if [ "$count" != 0 ]; then
744af66d3e1SGeliang Tang		echo "[fail] got $count data checksum error[s] expected 0"
745af66d3e1SGeliang Tang		ret=1
746af66d3e1SGeliang Tang		dump_stats=1
747af66d3e1SGeliang Tang	else
748af66d3e1SGeliang Tang		echo -n "[ ok ]"
749af66d3e1SGeliang Tang	fi
750af66d3e1SGeliang Tang	echo -n " - csum  "
751af66d3e1SGeliang Tang	count=`ip netns exec $ns2 nstat -as | grep MPTcpExtDataCsumErr | awk '{print $2}'`
752af66d3e1SGeliang Tang	[ -z "$count" ] && count=0
753af66d3e1SGeliang Tang	if [ "$count" != 0 ]; then
754af66d3e1SGeliang Tang		echo "[fail] got $count data checksum error[s] expected 0"
755af66d3e1SGeliang Tang		ret=1
756af66d3e1SGeliang Tang		dump_stats=1
757af66d3e1SGeliang Tang	else
758af66d3e1SGeliang Tang		echo "[ ok ]"
759af66d3e1SGeliang Tang	fi
760327b9a94SPaolo Abeni	[ "${dump_stats}" = 1 ] && dump_stats
761af66d3e1SGeliang Tang}
762af66d3e1SGeliang Tang
7636bb3ab49SGeliang Tangchk_fail_nr()
7646bb3ab49SGeliang Tang{
7656bb3ab49SGeliang Tang	local mp_fail_nr_tx=$1
7666bb3ab49SGeliang Tang	local mp_fail_nr_rx=$2
7676bb3ab49SGeliang Tang	local count
7686bb3ab49SGeliang Tang	local dump_stats
7696bb3ab49SGeliang Tang
7709a0a9367SGeliang Tang	printf "%-${nr_blank}s %s" " " "ftx"
7716bb3ab49SGeliang Tang	count=`ip netns exec $ns1 nstat -as | grep MPTcpExtMPFailTx | awk '{print $2}'`
7726bb3ab49SGeliang Tang	[ -z "$count" ] && count=0
7736bb3ab49SGeliang Tang	if [ "$count" != "$mp_fail_nr_tx" ]; then
7746bb3ab49SGeliang Tang		echo "[fail] got $count MP_FAIL[s] TX expected $mp_fail_nr_tx"
7756bb3ab49SGeliang Tang		ret=1
7766bb3ab49SGeliang Tang		dump_stats=1
7776bb3ab49SGeliang Tang	else
7786bb3ab49SGeliang Tang		echo -n "[ ok ]"
7796bb3ab49SGeliang Tang	fi
7806bb3ab49SGeliang Tang
7816bb3ab49SGeliang Tang	echo -n " - frx   "
7826bb3ab49SGeliang Tang	count=`ip netns exec $ns2 nstat -as | grep MPTcpExtMPFailRx | awk '{print $2}'`
7836bb3ab49SGeliang Tang	[ -z "$count" ] && count=0
7846bb3ab49SGeliang Tang	if [ "$count" != "$mp_fail_nr_rx" ]; then
7856bb3ab49SGeliang Tang		echo "[fail] got $count MP_FAIL[s] RX expected $mp_fail_nr_rx"
7866bb3ab49SGeliang Tang		ret=1
7876bb3ab49SGeliang Tang		dump_stats=1
7886bb3ab49SGeliang Tang	else
7896bb3ab49SGeliang Tang		echo "[ ok ]"
7906bb3ab49SGeliang Tang	fi
7916bb3ab49SGeliang Tang
792327b9a94SPaolo Abeni	[ "${dump_stats}" = 1 ] && dump_stats
7936bb3ab49SGeliang Tang}
7946bb3ab49SGeliang Tang
795e8e947efSGeliang Tangchk_fclose_nr()
796e8e947efSGeliang Tang{
797e8e947efSGeliang Tang	local fclose_tx=$1
798e8e947efSGeliang Tang	local fclose_rx=$2
799e8e947efSGeliang Tang	local count
800e8e947efSGeliang Tang	local dump_stats
801e8e947efSGeliang Tang
802e8e947efSGeliang Tang	printf "%-${nr_blank}s %s" " " "ctx"
803e8e947efSGeliang Tang	count=$(ip netns exec $ns2 nstat -as | grep MPTcpExtMPFastcloseTx | awk '{print $2}')
804e8e947efSGeliang Tang	[ -z "$count" ] && count=0
805e8e947efSGeliang Tang	if [ "$count" != "$fclose_tx" ]; then
806e8e947efSGeliang Tang		echo "[fail] got $count MP_FASTCLOSE[s] TX expected $fclose_tx"
807e8e947efSGeliang Tang		ret=1
808e8e947efSGeliang Tang		dump_stats=1
809e8e947efSGeliang Tang	else
810e8e947efSGeliang Tang		echo -n "[ ok ]"
811e8e947efSGeliang Tang	fi
812e8e947efSGeliang Tang
813e8e947efSGeliang Tang	echo -n " - fclzrx"
814e8e947efSGeliang Tang	count=$(ip netns exec $ns1 nstat -as | grep MPTcpExtMPFastcloseRx | awk '{print $2}')
815e8e947efSGeliang Tang	[ -z "$count" ] && count=0
816e8e947efSGeliang Tang	if [ "$count" != "$fclose_rx" ]; then
817e8e947efSGeliang Tang		echo "[fail] got $count MP_FASTCLOSE[s] RX expected $fclose_rx"
818e8e947efSGeliang Tang		ret=1
819e8e947efSGeliang Tang		dump_stats=1
820e8e947efSGeliang Tang	else
821e8e947efSGeliang Tang		echo "[ ok ]"
822e8e947efSGeliang Tang	fi
823e8e947efSGeliang Tang
824e8e947efSGeliang Tang	[ "${dump_stats}" = 1 ] && dump_stats
825e8e947efSGeliang Tang}
826e8e947efSGeliang Tang
827922fd2b3SGeliang Tangchk_rst_nr()
828922fd2b3SGeliang Tang{
829922fd2b3SGeliang Tang	local rst_tx=$1
830922fd2b3SGeliang Tang	local rst_rx=$2
831922fd2b3SGeliang Tang	local ns_invert=${3:-""}
832922fd2b3SGeliang Tang	local count
833922fd2b3SGeliang Tang	local dump_stats
834922fd2b3SGeliang Tang	local ns_tx=$ns1
835922fd2b3SGeliang Tang	local ns_rx=$ns2
836922fd2b3SGeliang Tang	local extra_msg=""
837922fd2b3SGeliang Tang
838922fd2b3SGeliang Tang	if [[ $ns_invert = "invert" ]]; then
839922fd2b3SGeliang Tang		ns_tx=$ns2
840922fd2b3SGeliang Tang		ns_rx=$ns1
841922fd2b3SGeliang Tang		extra_msg="   invert"
842922fd2b3SGeliang Tang	fi
843922fd2b3SGeliang Tang
844922fd2b3SGeliang Tang	printf "%-${nr_blank}s %s" " " "rtx"
845922fd2b3SGeliang Tang	count=$(ip netns exec $ns_tx nstat -as | grep MPTcpExtMPRstTx | awk '{print $2}')
846922fd2b3SGeliang Tang	[ -z "$count" ] && count=0
847922fd2b3SGeliang Tang	if [ "$count" != "$rst_tx" ]; then
848922fd2b3SGeliang Tang		echo "[fail] got $count MP_RST[s] TX expected $rst_tx"
849922fd2b3SGeliang Tang		ret=1
850922fd2b3SGeliang Tang		dump_stats=1
851922fd2b3SGeliang Tang	else
852922fd2b3SGeliang Tang		echo -n "[ ok ]"
853922fd2b3SGeliang Tang	fi
854922fd2b3SGeliang Tang
855922fd2b3SGeliang Tang	echo -n " - rstrx "
856922fd2b3SGeliang Tang	count=$(ip netns exec $ns_rx nstat -as | grep MPTcpExtMPRstRx | awk '{print $2}')
857922fd2b3SGeliang Tang	[ -z "$count" ] && count=0
858922fd2b3SGeliang Tang	if [ "$count" != "$rst_rx" ]; then
859922fd2b3SGeliang Tang		echo "[fail] got $count MP_RST[s] RX expected $rst_rx"
860922fd2b3SGeliang Tang		ret=1
861922fd2b3SGeliang Tang		dump_stats=1
862922fd2b3SGeliang Tang	else
863922fd2b3SGeliang Tang		echo -n "[ ok ]"
864922fd2b3SGeliang Tang	fi
865922fd2b3SGeliang Tang
866922fd2b3SGeliang Tang	[ "${dump_stats}" = 1 ] && dump_stats
867922fd2b3SGeliang Tang
868922fd2b3SGeliang Tang	echo "$extra_msg"
869922fd2b3SGeliang Tang}
870922fd2b3SGeliang Tang
871b08fbf24SPaolo Abenichk_join_nr()
872b08fbf24SPaolo Abeni{
873b08fbf24SPaolo Abeni	local msg="$1"
874b08fbf24SPaolo Abeni	local syn_nr=$2
875b08fbf24SPaolo Abeni	local syn_ack_nr=$3
876b08fbf24SPaolo Abeni	local ack_nr=$4
877b08fbf24SPaolo Abeni	local count
878b08fbf24SPaolo Abeni	local dump_stats
879e35f885bSPaolo Abeni	local with_cookie
880b08fbf24SPaolo Abeni
8819a0a9367SGeliang Tang	printf "%03u %-36s %s" "$TEST_COUNT" "$msg" "syn"
882b08fbf24SPaolo Abeni	count=`ip netns exec $ns1 nstat -as | grep MPTcpExtMPJoinSynRx | awk '{print $2}'`
883b08fbf24SPaolo Abeni	[ -z "$count" ] && count=0
884b08fbf24SPaolo Abeni	if [ "$count" != "$syn_nr" ]; then
885b08fbf24SPaolo Abeni		echo "[fail] got $count JOIN[s] syn expected $syn_nr"
886b08fbf24SPaolo Abeni		ret=1
887b08fbf24SPaolo Abeni		dump_stats=1
888b08fbf24SPaolo Abeni	else
889b08fbf24SPaolo Abeni		echo -n "[ ok ]"
890b08fbf24SPaolo Abeni	fi
891b08fbf24SPaolo Abeni
892b08fbf24SPaolo Abeni	echo -n " - synack"
893e35f885bSPaolo Abeni	with_cookie=`ip netns exec $ns2 sysctl -n net.ipv4.tcp_syncookies`
894b08fbf24SPaolo Abeni	count=`ip netns exec $ns2 nstat -as | grep MPTcpExtMPJoinSynAckRx | awk '{print $2}'`
895b08fbf24SPaolo Abeni	[ -z "$count" ] && count=0
896b08fbf24SPaolo Abeni	if [ "$count" != "$syn_ack_nr" ]; then
897e35f885bSPaolo Abeni		# simult connections exceeding the limit with cookie enabled could go up to
898e35f885bSPaolo Abeni		# synack validation as the conn limit can be enforced reliably only after
899e35f885bSPaolo Abeni		# the subflow creation
900e35f885bSPaolo Abeni		if [ "$with_cookie" = 2 ] && [ "$count" -gt "$syn_ack_nr" ] && [ "$count" -le "$syn_nr" ]; then
901e35f885bSPaolo Abeni			echo -n "[ ok ]"
902e35f885bSPaolo Abeni		else
903b08fbf24SPaolo Abeni			echo "[fail] got $count JOIN[s] synack expected $syn_ack_nr"
904b08fbf24SPaolo Abeni			ret=1
905b08fbf24SPaolo Abeni			dump_stats=1
906e35f885bSPaolo Abeni		fi
907b08fbf24SPaolo Abeni	else
908b08fbf24SPaolo Abeni		echo -n "[ ok ]"
909b08fbf24SPaolo Abeni	fi
910b08fbf24SPaolo Abeni
911b08fbf24SPaolo Abeni	echo -n " - ack"
912b08fbf24SPaolo Abeni	count=`ip netns exec $ns1 nstat -as | grep MPTcpExtMPJoinAckRx | awk '{print $2}'`
913b08fbf24SPaolo Abeni	[ -z "$count" ] && count=0
914b08fbf24SPaolo Abeni	if [ "$count" != "$ack_nr" ]; then
915b08fbf24SPaolo Abeni		echo "[fail] got $count JOIN[s] ack expected $ack_nr"
916b08fbf24SPaolo Abeni		ret=1
917b08fbf24SPaolo Abeni		dump_stats=1
918b08fbf24SPaolo Abeni	else
919b08fbf24SPaolo Abeni		echo "[ ok ]"
920b08fbf24SPaolo Abeni	fi
921327b9a94SPaolo Abeni	[ "${dump_stats}" = 1 ] && dump_stats
922af66d3e1SGeliang Tang	if [ $checksum -eq 1 ]; then
923af66d3e1SGeliang Tang		chk_csum_nr
9246bb3ab49SGeliang Tang		chk_fail_nr 0 0
925922fd2b3SGeliang Tang		chk_rst_nr 0 0
926af66d3e1SGeliang Tang	fi
927b08fbf24SPaolo Abeni}
928b08fbf24SPaolo Abeni
9297d1e6f16SPaolo Abeni# a negative value for 'stale_max' means no upper bound:
9307d1e6f16SPaolo Abeni# for bidirectional transfer, if one peer sleep for a while
9317d1e6f16SPaolo Abeni# - as these tests do - we can have a quite high number of
9327d1e6f16SPaolo Abeni# stale/recover conversions, proportional to
9337d1e6f16SPaolo Abeni# sleep duration/ MPTCP-level RTX interval.
9347d1e6f16SPaolo Abenichk_stale_nr()
9357d1e6f16SPaolo Abeni{
9367d1e6f16SPaolo Abeni	local ns=$1
9377d1e6f16SPaolo Abeni	local stale_min=$2
9387d1e6f16SPaolo Abeni	local stale_max=$3
9397d1e6f16SPaolo Abeni	local stale_delta=$4
9407d1e6f16SPaolo Abeni	local dump_stats
9417d1e6f16SPaolo Abeni	local stale_nr
9427d1e6f16SPaolo Abeni	local recover_nr
9437d1e6f16SPaolo Abeni
9449a0a9367SGeliang Tang	printf "%-${nr_blank}s %-18s" " " "stale"
9457d1e6f16SPaolo Abeni	stale_nr=`ip netns exec $ns nstat -as | grep MPTcpExtSubflowStale | awk '{print $2}'`
9467d1e6f16SPaolo Abeni	[ -z "$stale_nr" ] && stale_nr=0
9477d1e6f16SPaolo Abeni	recover_nr=`ip netns exec $ns nstat -as | grep MPTcpExtSubflowRecover | awk '{print $2}'`
9487d1e6f16SPaolo Abeni	[ -z "$recover_nr" ] && recover_nr=0
9497d1e6f16SPaolo Abeni
9507d1e6f16SPaolo Abeni	if [ $stale_nr -lt $stale_min ] ||
9517d1e6f16SPaolo Abeni	   [ $stale_max -gt 0 -a $stale_nr -gt $stale_max ] ||
9527d1e6f16SPaolo Abeni	   [ $((stale_nr - $recover_nr)) -ne $stale_delta ]; then
9537d1e6f16SPaolo Abeni		echo "[fail] got $stale_nr stale[s] $recover_nr recover[s], " \
9547d1e6f16SPaolo Abeni		     " expected stale in range [$stale_min..$stale_max]," \
9557d1e6f16SPaolo Abeni		     " stale-recover delta $stale_delta "
9567d1e6f16SPaolo Abeni		ret=1
9577d1e6f16SPaolo Abeni		dump_stats=1
9587d1e6f16SPaolo Abeni	else
9597d1e6f16SPaolo Abeni		echo "[ ok ]"
9607d1e6f16SPaolo Abeni	fi
9617d1e6f16SPaolo Abeni
9627d1e6f16SPaolo Abeni	if [ "${dump_stats}" = 1 ]; then
9637d1e6f16SPaolo Abeni		echo $ns stats
9647d1e6f16SPaolo Abeni		ip netns exec $ns ip -s link show
9657d1e6f16SPaolo Abeni		ip netns exec $ns nstat -as | grep MPTcp
9667d1e6f16SPaolo Abeni	fi
9677d1e6f16SPaolo Abeni}
9687d1e6f16SPaolo Abeni
969be613160SGeliang Tangchk_add_nr()
970be613160SGeliang Tang{
971be613160SGeliang Tang	local add_nr=$1
972be613160SGeliang Tang	local echo_nr=$2
9738a127bf6SGeliang Tang	local port_nr=${3:-0}
9748a127bf6SGeliang Tang	local syn_nr=${4:-$port_nr}
9758a127bf6SGeliang Tang	local syn_ack_nr=${5:-$port_nr}
9768a127bf6SGeliang Tang	local ack_nr=${6:-$port_nr}
9778a127bf6SGeliang Tang	local mis_syn_nr=${7:-0}
9788a127bf6SGeliang Tang	local mis_ack_nr=${8:-0}
979be613160SGeliang Tang	local count
980be613160SGeliang Tang	local dump_stats
9816ef84b15SPaolo Abeni	local timeout
9826ef84b15SPaolo Abeni
9836ef84b15SPaolo Abeni	timeout=`ip netns exec $ns1 sysctl -n net.mptcp.add_addr_timeout`
984be613160SGeliang Tang
9859a0a9367SGeliang Tang	printf "%-${nr_blank}s %s" " " "add"
9866ef84b15SPaolo Abeni	count=`ip netns exec $ns2 nstat -as MPTcpExtAddAddr | grep MPTcpExtAddAddr | awk '{print $2}'`
987be613160SGeliang Tang	[ -z "$count" ] && count=0
9886ef84b15SPaolo Abeni
9896ef84b15SPaolo Abeni	# if the test configured a short timeout tolerate greater then expected
9906ef84b15SPaolo Abeni	# add addrs options, due to retransmissions
9916ef84b15SPaolo Abeni	if [ "$count" != "$add_nr" ] && [ "$timeout" -gt 1 -o "$count" -lt "$add_nr" ]; then
992be613160SGeliang Tang		echo "[fail] got $count ADD_ADDR[s] expected $add_nr"
993be613160SGeliang Tang		ret=1
994be613160SGeliang Tang		dump_stats=1
995be613160SGeliang Tang	else
996be613160SGeliang Tang		echo -n "[ ok ]"
997be613160SGeliang Tang	fi
998be613160SGeliang Tang
999be613160SGeliang Tang	echo -n " - echo  "
1000be613160SGeliang Tang	count=`ip netns exec $ns1 nstat -as | grep MPTcpExtEchoAdd | awk '{print $2}'`
1001be613160SGeliang Tang	[ -z "$count" ] && count=0
1002be613160SGeliang Tang	if [ "$count" != "$echo_nr" ]; then
1003be613160SGeliang Tang		echo "[fail] got $count ADD_ADDR echo[s] expected $echo_nr"
1004be613160SGeliang Tang		ret=1
1005be613160SGeliang Tang		dump_stats=1
1006be613160SGeliang Tang	else
10078a127bf6SGeliang Tang		echo -n "[ ok ]"
10088a127bf6SGeliang Tang	fi
10098a127bf6SGeliang Tang
10108a127bf6SGeliang Tang	if [ $port_nr -gt 0 ]; then
10118a127bf6SGeliang Tang		echo -n " - pt "
10128a127bf6SGeliang Tang		count=`ip netns exec $ns2 nstat -as | grep MPTcpExtPortAdd | awk '{print $2}'`
10138a127bf6SGeliang Tang		[ -z "$count" ] && count=0
10148a127bf6SGeliang Tang		if [ "$count" != "$port_nr" ]; then
10158a127bf6SGeliang Tang			echo "[fail] got $count ADD_ADDR[s] with a port-number expected $port_nr"
10168a127bf6SGeliang Tang			ret=1
10178a127bf6SGeliang Tang			dump_stats=1
10188a127bf6SGeliang Tang		else
1019be613160SGeliang Tang			echo "[ ok ]"
1020be613160SGeliang Tang		fi
1021be613160SGeliang Tang
10229a0a9367SGeliang Tang		printf "%-${nr_blank}s %s" " " "syn"
10238a127bf6SGeliang Tang		count=`ip netns exec $ns1 nstat -as | grep MPTcpExtMPJoinPortSynRx |
10248a127bf6SGeliang Tang			awk '{print $2}'`
10258a127bf6SGeliang Tang		[ -z "$count" ] && count=0
10268a127bf6SGeliang Tang		if [ "$count" != "$syn_nr" ]; then
10278a127bf6SGeliang Tang			echo "[fail] got $count JOIN[s] syn with a different \
10288a127bf6SGeliang Tang				port-number expected $syn_nr"
10298a127bf6SGeliang Tang			ret=1
10308a127bf6SGeliang Tang			dump_stats=1
10318a127bf6SGeliang Tang		else
10328a127bf6SGeliang Tang			echo -n "[ ok ]"
10338a127bf6SGeliang Tang		fi
10348a127bf6SGeliang Tang
10358a127bf6SGeliang Tang		echo -n " - synack"
10368a127bf6SGeliang Tang		count=`ip netns exec $ns2 nstat -as | grep MPTcpExtMPJoinPortSynAckRx |
10378a127bf6SGeliang Tang			awk '{print $2}'`
10388a127bf6SGeliang Tang		[ -z "$count" ] && count=0
10398a127bf6SGeliang Tang		if [ "$count" != "$syn_ack_nr" ]; then
10408a127bf6SGeliang Tang			echo "[fail] got $count JOIN[s] synack with a different \
10418a127bf6SGeliang Tang				port-number expected $syn_ack_nr"
10428a127bf6SGeliang Tang			ret=1
10438a127bf6SGeliang Tang			dump_stats=1
10448a127bf6SGeliang Tang		else
10458a127bf6SGeliang Tang			echo -n "[ ok ]"
10468a127bf6SGeliang Tang		fi
10478a127bf6SGeliang Tang
10488a127bf6SGeliang Tang		echo -n " - ack"
10498a127bf6SGeliang Tang		count=`ip netns exec $ns1 nstat -as | grep MPTcpExtMPJoinPortAckRx |
10508a127bf6SGeliang Tang			awk '{print $2}'`
10518a127bf6SGeliang Tang		[ -z "$count" ] && count=0
10528a127bf6SGeliang Tang		if [ "$count" != "$ack_nr" ]; then
10538a127bf6SGeliang Tang			echo "[fail] got $count JOIN[s] ack with a different \
10548a127bf6SGeliang Tang				port-number expected $ack_nr"
10558a127bf6SGeliang Tang			ret=1
10568a127bf6SGeliang Tang			dump_stats=1
10578a127bf6SGeliang Tang		else
10588a127bf6SGeliang Tang			echo "[ ok ]"
10598a127bf6SGeliang Tang		fi
10608a127bf6SGeliang Tang
10619a0a9367SGeliang Tang		printf "%-${nr_blank}s %s" " " "syn"
10628a127bf6SGeliang Tang		count=`ip netns exec $ns1 nstat -as | grep MPTcpExtMismatchPortSynRx |
10638a127bf6SGeliang Tang			awk '{print $2}'`
10648a127bf6SGeliang Tang		[ -z "$count" ] && count=0
10658a127bf6SGeliang Tang		if [ "$count" != "$mis_syn_nr" ]; then
10668a127bf6SGeliang Tang			echo "[fail] got $count JOIN[s] syn with a mismatched \
10678a127bf6SGeliang Tang				port-number expected $mis_syn_nr"
10688a127bf6SGeliang Tang			ret=1
10698a127bf6SGeliang Tang			dump_stats=1
10708a127bf6SGeliang Tang		else
10718a127bf6SGeliang Tang			echo -n "[ ok ]"
10728a127bf6SGeliang Tang		fi
10738a127bf6SGeliang Tang
10748a127bf6SGeliang Tang		echo -n " - ack   "
10758a127bf6SGeliang Tang		count=`ip netns exec $ns1 nstat -as | grep MPTcpExtMismatchPortAckRx |
10768a127bf6SGeliang Tang			awk '{print $2}'`
10778a127bf6SGeliang Tang		[ -z "$count" ] && count=0
10788a127bf6SGeliang Tang		if [ "$count" != "$mis_ack_nr" ]; then
10798a127bf6SGeliang Tang			echo "[fail] got $count JOIN[s] ack with a mismatched \
10808a127bf6SGeliang Tang				port-number expected $mis_ack_nr"
10818a127bf6SGeliang Tang			ret=1
10828a127bf6SGeliang Tang			dump_stats=1
10838a127bf6SGeliang Tang		else
10848a127bf6SGeliang Tang			echo "[ ok ]"
10858a127bf6SGeliang Tang		fi
10868a127bf6SGeliang Tang	else
10878a127bf6SGeliang Tang		echo ""
10888a127bf6SGeliang Tang	fi
10898a127bf6SGeliang Tang
1090327b9a94SPaolo Abeni	[ "${dump_stats}" = 1 ] && dump_stats
1091be613160SGeliang Tang}
1092be613160SGeliang Tang
1093dd72b0feSGeliang Tangchk_rm_nr()
1094dd72b0feSGeliang Tang{
1095dd72b0feSGeliang Tang	local rm_addr_nr=$1
1096dd72b0feSGeliang Tang	local rm_subflow_nr=$2
10977028ba8aSGeliang Tang	local invert=${3:-""}
1098dd72b0feSGeliang Tang	local count
1099dd72b0feSGeliang Tang	local dump_stats
11007028ba8aSGeliang Tang	local addr_ns
11017028ba8aSGeliang Tang	local subflow_ns
11027028ba8aSGeliang Tang
11037028ba8aSGeliang Tang	if [ -z $invert ]; then
11047028ba8aSGeliang Tang		addr_ns=$ns1
11057028ba8aSGeliang Tang		subflow_ns=$ns2
11067028ba8aSGeliang Tang	elif [ $invert = "invert" ]; then
11077028ba8aSGeliang Tang		addr_ns=$ns2
11087028ba8aSGeliang Tang		subflow_ns=$ns1
11097028ba8aSGeliang Tang	fi
1110dd72b0feSGeliang Tang
11119a0a9367SGeliang Tang	printf "%-${nr_blank}s %s" " " "rm "
11127028ba8aSGeliang Tang	count=`ip netns exec $addr_ns nstat -as | grep MPTcpExtRmAddr | awk '{print $2}'`
1113dd72b0feSGeliang Tang	[ -z "$count" ] && count=0
1114dd72b0feSGeliang Tang	if [ "$count" != "$rm_addr_nr" ]; then
1115dd72b0feSGeliang Tang		echo "[fail] got $count RM_ADDR[s] expected $rm_addr_nr"
1116dd72b0feSGeliang Tang		ret=1
1117dd72b0feSGeliang Tang		dump_stats=1
1118dd72b0feSGeliang Tang	else
1119dd72b0feSGeliang Tang		echo -n "[ ok ]"
1120dd72b0feSGeliang Tang	fi
1121dd72b0feSGeliang Tang
1122dd72b0feSGeliang Tang	echo -n " - sf    "
11237028ba8aSGeliang Tang	count=`ip netns exec $subflow_ns nstat -as | grep MPTcpExtRmSubflow | awk '{print $2}'`
1124dd72b0feSGeliang Tang	[ -z "$count" ] && count=0
1125dd72b0feSGeliang Tang	if [ "$count" != "$rm_subflow_nr" ]; then
1126dd72b0feSGeliang Tang		echo "[fail] got $count RM_SUBFLOW[s] expected $rm_subflow_nr"
1127dd72b0feSGeliang Tang		ret=1
1128dd72b0feSGeliang Tang		dump_stats=1
1129dd72b0feSGeliang Tang	else
1130dd72b0feSGeliang Tang		echo "[ ok ]"
1131dd72b0feSGeliang Tang	fi
1132dd72b0feSGeliang Tang
1133327b9a94SPaolo Abeni	[ "${dump_stats}" = 1 ] && dump_stats
1134dd72b0feSGeliang Tang}
1135dd72b0feSGeliang Tang
1136718eb44eSGeliang Tangchk_prio_nr()
1137718eb44eSGeliang Tang{
1138718eb44eSGeliang Tang	local mp_prio_nr_tx=$1
1139718eb44eSGeliang Tang	local mp_prio_nr_rx=$2
1140718eb44eSGeliang Tang	local count
1141718eb44eSGeliang Tang	local dump_stats
1142718eb44eSGeliang Tang
11439a0a9367SGeliang Tang	printf "%-${nr_blank}s %s" " " "ptx"
1144718eb44eSGeliang Tang	count=`ip netns exec $ns1 nstat -as | grep MPTcpExtMPPrioTx | awk '{print $2}'`
1145718eb44eSGeliang Tang	[ -z "$count" ] && count=0
1146718eb44eSGeliang Tang	if [ "$count" != "$mp_prio_nr_tx" ]; then
1147718eb44eSGeliang Tang		echo "[fail] got $count MP_PRIO[s] TX expected $mp_prio_nr_tx"
1148718eb44eSGeliang Tang		ret=1
1149718eb44eSGeliang Tang		dump_stats=1
1150718eb44eSGeliang Tang	else
1151718eb44eSGeliang Tang		echo -n "[ ok ]"
1152718eb44eSGeliang Tang	fi
1153718eb44eSGeliang Tang
1154718eb44eSGeliang Tang	echo -n " - prx   "
1155718eb44eSGeliang Tang	count=`ip netns exec $ns1 nstat -as | grep MPTcpExtMPPrioRx | awk '{print $2}'`
1156718eb44eSGeliang Tang	[ -z "$count" ] && count=0
1157718eb44eSGeliang Tang	if [ "$count" != "$mp_prio_nr_rx" ]; then
1158718eb44eSGeliang Tang		echo "[fail] got $count MP_PRIO[s] RX expected $mp_prio_nr_rx"
1159718eb44eSGeliang Tang		ret=1
1160718eb44eSGeliang Tang		dump_stats=1
1161718eb44eSGeliang Tang	else
1162718eb44eSGeliang Tang		echo "[ ok ]"
1163718eb44eSGeliang Tang	fi
1164718eb44eSGeliang Tang
1165327b9a94SPaolo Abeni	[ "${dump_stats}" = 1 ] && dump_stats
1166718eb44eSGeliang Tang}
1167718eb44eSGeliang Tang
11687d1e6f16SPaolo Abenichk_link_usage()
11697d1e6f16SPaolo Abeni{
11707d1e6f16SPaolo Abeni	local ns=$1
11717d1e6f16SPaolo Abeni	local link=$2
11727d1e6f16SPaolo Abeni	local out=$3
11737d1e6f16SPaolo Abeni	local expected_rate=$4
11747d1e6f16SPaolo Abeni	local tx_link=`ip netns exec $ns cat /sys/class/net/$link/statistics/tx_bytes`
11757d1e6f16SPaolo Abeni	local tx_total=`ls -l $out | awk '{print $5}'`
11767d1e6f16SPaolo Abeni	local tx_rate=$((tx_link * 100 / $tx_total))
11777d1e6f16SPaolo Abeni	local tolerance=5
11787d1e6f16SPaolo Abeni
11799a0a9367SGeliang Tang	printf "%-${nr_blank}s %-18s" " " "link usage"
11807d1e6f16SPaolo Abeni	if [ $tx_rate -lt $((expected_rate - $tolerance)) -o \
11817d1e6f16SPaolo Abeni	     $tx_rate -gt $((expected_rate + $tolerance)) ]; then
11827d1e6f16SPaolo Abeni		echo "[fail] got $tx_rate% usage, expected $expected_rate%"
11837d1e6f16SPaolo Abeni		ret=1
11847d1e6f16SPaolo Abeni	else
11857d1e6f16SPaolo Abeni		echo "[ ok ]"
11867d1e6f16SPaolo Abeni	fi
11877d1e6f16SPaolo Abeni}
11887d1e6f16SPaolo Abeni
118946e967d1SPaolo Abeniwait_for_tw()
119046e967d1SPaolo Abeni{
119146e967d1SPaolo Abeni	local timeout_ms=$((timeout_poll * 1000))
119246e967d1SPaolo Abeni	local time=0
119346e967d1SPaolo Abeni	local ns=$1
119446e967d1SPaolo Abeni
119546e967d1SPaolo Abeni	while [ $time -lt $timeout_ms ]; do
11965b31dda7SPaolo Abeni		local cnt=$(ip netns exec $ns nstat -as TcpAttemptFails | grep TcpAttemptFails | awk '{print $2}')
119746e967d1SPaolo Abeni
119846e967d1SPaolo Abeni		[ "$cnt" = 1 ] && return 1
119946e967d1SPaolo Abeni		time=$((time + 100))
120046e967d1SPaolo Abeni		sleep 0.1
120146e967d1SPaolo Abeni	done
120246e967d1SPaolo Abeni	return 1
120346e967d1SPaolo Abeni}
120446e967d1SPaolo Abeni
12051002b89fSGeliang Tangsubflows_tests()
12061002b89fSGeliang Tang{
12071002b89fSGeliang Tang	reset
1208b08fbf24SPaolo Abeni	run_tests $ns1 $ns2 10.0.1.1
1209b08fbf24SPaolo Abeni	chk_join_nr "no JOIN" "0" "0" "0"
1210b08fbf24SPaolo Abeni
12111002b89fSGeliang Tang	# subflow limited by client
1212b08fbf24SPaolo Abeni	reset
121334aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 0
121434aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 0 0
121534aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
1216b08fbf24SPaolo Abeni	run_tests $ns1 $ns2 10.0.1.1
1217b08fbf24SPaolo Abeni	chk_join_nr "single subflow, limited by client" 0 0 0
1218b08fbf24SPaolo Abeni
12191002b89fSGeliang Tang	# subflow limited by server
1220b08fbf24SPaolo Abeni	reset
122134aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 0
122234aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 0 1
122334aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
1224b08fbf24SPaolo Abeni	run_tests $ns1 $ns2 10.0.1.1
1225b08fbf24SPaolo Abeni	chk_join_nr "single subflow, limited by server" 1 1 0
1226b08fbf24SPaolo Abeni
1227b08fbf24SPaolo Abeni	# subflow
1228b08fbf24SPaolo Abeni	reset
122934aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
123034aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 0 1
123134aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
1232b08fbf24SPaolo Abeni	run_tests $ns1 $ns2 10.0.1.1
1233b08fbf24SPaolo Abeni	chk_join_nr "single subflow" 1 1 1
1234b08fbf24SPaolo Abeni
1235b08fbf24SPaolo Abeni	# multiple subflows
1236b08fbf24SPaolo Abeni	reset
123734aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 2
123834aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 0 2
123934aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
124034aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow
1241b08fbf24SPaolo Abeni	run_tests $ns1 $ns2 10.0.1.1
1242b08fbf24SPaolo Abeni	chk_join_nr "multiple subflows" 2 2 2
1243b08fbf24SPaolo Abeni
124472bcbc46SPaolo Abeni	# multiple subflows limited by server
1245b08fbf24SPaolo Abeni	reset
124634aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
124734aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 0 2
124834aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
124934aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow
1250b08fbf24SPaolo Abeni	run_tests $ns1 $ns2 10.0.1.1
1251b08fbf24SPaolo Abeni	chk_join_nr "multiple subflows, limited by server" 2 2 1
1252c3eaa5f6SGeliang Tang
1253c3eaa5f6SGeliang Tang	# single subflow, dev
1254c3eaa5f6SGeliang Tang	reset
125534aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
125634aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 0 1
125734aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow dev ns2eth3
1258c3eaa5f6SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1
1259c3eaa5f6SGeliang Tang	chk_join_nr "single subflow, dev" 1 1 1
12601002b89fSGeliang Tang}
1261b08fbf24SPaolo Abeni
126246e967d1SPaolo Abenisubflows_error_tests()
126346e967d1SPaolo Abeni{
126446e967d1SPaolo Abeni	# If a single subflow is configured, and matches the MPC src
126546e967d1SPaolo Abeni	# address, no additional subflow should be created
126646e967d1SPaolo Abeni	reset
126734aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
126834aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 0 1
126934aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.1.2 flags subflow
127046e967d1SPaolo Abeni	run_tests $ns1 $ns2 10.0.1.1 0 0 0 slow
127146e967d1SPaolo Abeni	chk_join_nr "no MPC reuse with single endpoint" 0 0 0
127246e967d1SPaolo Abeni
127346e967d1SPaolo Abeni	# multiple subflows, with subflow creation error
127446e967d1SPaolo Abeni	reset
127534aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 2
127634aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 0 2
127734aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
127834aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow
127946e967d1SPaolo Abeni	ip netns exec $ns1 iptables -A INPUT -s 10.0.3.2 -p tcp -j REJECT
128046e967d1SPaolo Abeni	run_tests $ns1 $ns2 10.0.1.1 0 0 0 slow
128146e967d1SPaolo Abeni	chk_join_nr "multi subflows, with failing subflow" 1 1 1
128246e967d1SPaolo Abeni
128346e967d1SPaolo Abeni	# multiple subflows, with subflow timeout on MPJ
128446e967d1SPaolo Abeni	reset
128534aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 2
128634aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 0 2
128734aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
128834aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow
128946e967d1SPaolo Abeni	ip netns exec $ns1 iptables -A INPUT -s 10.0.3.2 -p tcp -j DROP
129046e967d1SPaolo Abeni	run_tests $ns1 $ns2 10.0.1.1 0 0 0 slow
129146e967d1SPaolo Abeni	chk_join_nr "multi subflows, with subflow timeout" 1 1 1
129246e967d1SPaolo Abeni
129346e967d1SPaolo Abeni	# multiple subflows, check that the endpoint corresponding to
129446e967d1SPaolo Abeni	# closed subflow (due to reset) is not reused if additional
129546e967d1SPaolo Abeni	# subflows are added later
129646e967d1SPaolo Abeni	reset
129734aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
129834aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 0 1
129934aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
130046e967d1SPaolo Abeni	ip netns exec $ns1 iptables -A INPUT -s 10.0.3.2 -p tcp -j REJECT
130146e967d1SPaolo Abeni	run_tests $ns1 $ns2 10.0.1.1 0 0 0 slow &
130246e967d1SPaolo Abeni
130346e967d1SPaolo Abeni	# updates in the child shell do not have any effect here, we
130446e967d1SPaolo Abeni	# need to bump the test counter for the above case
130546e967d1SPaolo Abeni	TEST_COUNT=$((TEST_COUNT+1))
130646e967d1SPaolo Abeni
130746e967d1SPaolo Abeni	# mpj subflow will be in TW after the reset
130846e967d1SPaolo Abeni	wait_for_tw $ns2
130934aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow
131046e967d1SPaolo Abeni	wait
131146e967d1SPaolo Abeni
131246e967d1SPaolo Abeni	# additional subflow could be created only if the PM select
131346e967d1SPaolo Abeni	# the later endpoint, skipping the already used one
131446e967d1SPaolo Abeni	chk_join_nr "multi subflows, fair usage on close" 1 1 1
131546e967d1SPaolo Abeni}
131646e967d1SPaolo Abeni
13171002b89fSGeliang Tangsignal_address_tests()
13181002b89fSGeliang Tang{
1319b08fbf24SPaolo Abeni	# add_address, unused
1320b08fbf24SPaolo Abeni	reset
132134aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
1322b08fbf24SPaolo Abeni	run_tests $ns1 $ns2 10.0.1.1
1323b08fbf24SPaolo Abeni	chk_join_nr "unused signal address" 0 0 0
1324be613160SGeliang Tang	chk_add_nr 1 1
1325b08fbf24SPaolo Abeni
1326b08fbf24SPaolo Abeni	# accept and use add_addr
1327b08fbf24SPaolo Abeni	reset
132834aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
132934aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 1
133034aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
1331b08fbf24SPaolo Abeni	run_tests $ns1 $ns2 10.0.1.1
1332b08fbf24SPaolo Abeni	chk_join_nr "signal address" 1 1 1
1333be613160SGeliang Tang	chk_add_nr 1 1
1334b08fbf24SPaolo Abeni
1335b08fbf24SPaolo Abeni	# accept and use add_addr with an additional subflow
1336b08fbf24SPaolo Abeni	# note: signal address in server ns and local addresses in client ns must
1337b08fbf24SPaolo Abeni	# belong to different subnets or one of the listed local address could be
1338b08fbf24SPaolo Abeni	# used for 'add_addr' subflow
1339b08fbf24SPaolo Abeni	reset
134034aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
134134aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 2
134234aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 2
134334aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
1344b08fbf24SPaolo Abeni	run_tests $ns1 $ns2 10.0.1.1
1345b08fbf24SPaolo Abeni	chk_join_nr "subflow and signal" 2 2 2
1346be613160SGeliang Tang	chk_add_nr 1 1
1347b08fbf24SPaolo Abeni
1348b08fbf24SPaolo Abeni	# accept and use add_addr with additional subflows
1349b08fbf24SPaolo Abeni	reset
135034aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 3
135134aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
135234aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 3
135334aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
135434aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.4.2 flags subflow
1355b08fbf24SPaolo Abeni	run_tests $ns1 $ns2 10.0.1.1
1356b08fbf24SPaolo Abeni	chk_join_nr "multiple subflows and signal" 3 3 3
1357be613160SGeliang Tang	chk_add_nr 1 1
1358ef360019SGeliang Tang
1359ef360019SGeliang Tang	# signal addresses
1360ef360019SGeliang Tang	reset
136134aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 3 3
136234aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
136334aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.3.1 flags signal
136434aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.4.1 flags signal
136534aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 3 3
1366ef360019SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1
1367ef360019SGeliang Tang	chk_join_nr "signal addresses" 3 3 3
1368ef360019SGeliang Tang	chk_add_nr 3 3
1369ef360019SGeliang Tang
1370ef360019SGeliang Tang	# signal invalid addresses
1371ef360019SGeliang Tang	reset
137234aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 3 3
137334aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.12.1 flags signal
137434aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.3.1 flags signal
137534aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.14.1 flags signal
137634aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 3 3
1377ef360019SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1
1378ef360019SGeliang Tang	chk_join_nr "signal invalid addresses" 1 1 1
1379ef360019SGeliang Tang	chk_add_nr 3 3
138033c563adSYonglong Li
138133c563adSYonglong Li	# signal addresses race test
138233c563adSYonglong Li	reset
138334aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 4 4
138434aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 4 4
138534aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.1.1 flags signal
138634aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
138734aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.3.1 flags signal
138834aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.4.1 flags signal
138934aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.1.2 flags signal
139034aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.2.2 flags signal
139134aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 flags signal
139234aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.4.2 flags signal
13936ef84b15SPaolo Abeni
13946ef84b15SPaolo Abeni	# the peer could possibly miss some addr notification, allow retransmission
13956ef84b15SPaolo Abeni	ip netns exec $ns1 sysctl -q net.mptcp.add_addr_timeout=1
13966ef84b15SPaolo Abeni	run_tests $ns1 $ns2 10.0.1.1 0 0 0 slow
1397857898ebSMatthieu Baerts	chk_join_nr "signal addresses race test" 3 3 3
139886e39e04SPaolo Abeni
139986e39e04SPaolo Abeni	# the server will not signal the address terminating
140086e39e04SPaolo Abeni	# the MPC subflow
140186e39e04SPaolo Abeni	chk_add_nr 3 3
14021002b89fSGeliang Tang}
1403b08fbf24SPaolo Abeni
14041002b89fSGeliang Tanglink_failure_tests()
14051002b89fSGeliang Tang{
14068b819a84SFlorian Westphal	# accept and use add_addr with additional subflows and link loss
14078b819a84SFlorian Westphal	reset
14087d1e6f16SPaolo Abeni
14097d1e6f16SPaolo Abeni	# without any b/w limit each veth could spool the packets and get
14107d1e6f16SPaolo Abeni	# them acked at xmit time, so that the corresponding subflow will
14117d1e6f16SPaolo Abeni	# have almost always no outstanding pkts, the scheduler will pick
14127d1e6f16SPaolo Abeni	# always the first subflow and we will have hard time testing
14137d1e6f16SPaolo Abeni	# active backup and link switch-over.
14147d1e6f16SPaolo Abeni	# Let's set some arbitrary (low) virtual link limits.
14157d1e6f16SPaolo Abeni	init_shapers
141634aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 3
141734aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 dev ns1eth2 flags signal
141834aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 3
141934aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 dev ns2eth3 flags subflow
142034aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.4.2 dev ns2eth4 flags subflow
14218b819a84SFlorian Westphal	run_tests $ns1 $ns2 10.0.1.1 1
14228b819a84SFlorian Westphal	chk_join_nr "multiple flows, signal, link failure" 3 3 3
14238b819a84SFlorian Westphal	chk_add_nr 1 1
14247d1e6f16SPaolo Abeni	chk_stale_nr $ns2 1 5 1
14257d1e6f16SPaolo Abeni
14267d1e6f16SPaolo Abeni	# accept and use add_addr with additional subflows and link loss
14277d1e6f16SPaolo Abeni	# for bidirectional transfer
14287d1e6f16SPaolo Abeni	reset
14297d1e6f16SPaolo Abeni	init_shapers
143034aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 3
143134aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 dev ns1eth2 flags signal
143234aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 3
143334aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 dev ns2eth3 flags subflow
143434aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.4.2 dev ns2eth4 flags subflow
14357d1e6f16SPaolo Abeni	run_tests $ns1 $ns2 10.0.1.1 2
14367d1e6f16SPaolo Abeni	chk_join_nr "multi flows, signal, bidi, link fail" 3 3 3
14377d1e6f16SPaolo Abeni	chk_add_nr 1 1
14387d1e6f16SPaolo Abeni	chk_stale_nr $ns2 1 -1 1
14397d1e6f16SPaolo Abeni
14407d1e6f16SPaolo Abeni	# 2 subflows plus 1 backup subflow with a lossy link, backup
14417d1e6f16SPaolo Abeni	# will never be used
14427d1e6f16SPaolo Abeni	reset
14437d1e6f16SPaolo Abeni	init_shapers
144434aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 2
144534aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 dev ns1eth2 flags signal
144634aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 2
14477d1e6f16SPaolo Abeni	export FAILING_LINKS="1"
144834aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 dev ns2eth3 flags subflow,backup
14497d1e6f16SPaolo Abeni	run_tests $ns1 $ns2 10.0.1.1 1
14507d1e6f16SPaolo Abeni	chk_join_nr "backup subflow unused, link failure" 2 2 2
14517d1e6f16SPaolo Abeni	chk_add_nr 1 1
14527d1e6f16SPaolo Abeni	chk_link_usage $ns2 ns2eth3 $cinsent 0
14537d1e6f16SPaolo Abeni
14547d1e6f16SPaolo Abeni	# 2 lossy links after half transfer, backup will get half of
14557d1e6f16SPaolo Abeni	# the traffic
14567d1e6f16SPaolo Abeni	reset
14577d1e6f16SPaolo Abeni	init_shapers
145834aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 2
145934aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 dev ns1eth2 flags signal
146034aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 2
146134aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 dev ns2eth3 flags subflow,backup
14627d1e6f16SPaolo Abeni	export FAILING_LINKS="1 2"
14637d1e6f16SPaolo Abeni	run_tests $ns1 $ns2 10.0.1.1 1
14647d1e6f16SPaolo Abeni	chk_join_nr "backup flow used, multi links fail" 2 2 2
14657d1e6f16SPaolo Abeni	chk_add_nr 1 1
14667d1e6f16SPaolo Abeni	chk_stale_nr $ns2 2 4 2
14677d1e6f16SPaolo Abeni	chk_link_usage $ns2 ns2eth3 $cinsent 50
14687d1e6f16SPaolo Abeni
14697d1e6f16SPaolo Abeni	# use a backup subflow with the first subflow on a lossy link
14707d1e6f16SPaolo Abeni	# for bidirectional transfer
14717d1e6f16SPaolo Abeni	reset
14727d1e6f16SPaolo Abeni	init_shapers
147334aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 2
147434aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 dev ns1eth2 flags signal
147534aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 3
147634aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 dev ns2eth3 flags subflow,backup
14777d1e6f16SPaolo Abeni	run_tests $ns1 $ns2 10.0.1.1 2
14787d1e6f16SPaolo Abeni	chk_join_nr "backup flow used, bidi, link failure" 2 2 2
14797d1e6f16SPaolo Abeni	chk_add_nr 1 1
14807d1e6f16SPaolo Abeni	chk_stale_nr $ns2 1 -1 2
14817d1e6f16SPaolo Abeni	chk_link_usage $ns2 ns2eth3 $cinsent 50
14821002b89fSGeliang Tang}
14838b819a84SFlorian Westphal
14841002b89fSGeliang Tangadd_addr_timeout_tests()
14851002b89fSGeliang Tang{
14868d014eaaSGeliang Tang	# add_addr timeout
14878d014eaaSGeliang Tang	reset_with_add_addr_timeout
148834aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
148934aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 1
149034aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
14918b819a84SFlorian Westphal	run_tests $ns1 $ns2 10.0.1.1 0 0 0 slow
14928d014eaaSGeliang Tang	chk_join_nr "signal address, ADD_ADDR timeout" 1 1 1
14938d014eaaSGeliang Tang	chk_add_nr 4 0
14948d014eaaSGeliang Tang
14951002b89fSGeliang Tang	# add_addr timeout IPv6
14961002b89fSGeliang Tang	reset_with_add_addr_timeout 6
149734aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
149834aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 1
149934aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 dead:beef:2::1 flags signal
15001002b89fSGeliang Tang	run_tests $ns1 $ns2 dead:beef:1::1 0 0 0 slow
15011002b89fSGeliang Tang	chk_join_nr "signal address, ADD_ADDR6 timeout" 1 1 1
15021002b89fSGeliang Tang	chk_add_nr 4 0
15038da6229bSGeliang Tang
15048da6229bSGeliang Tang	# signal addresses timeout
15058da6229bSGeliang Tang	reset_with_add_addr_timeout
150634aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 2 2
150734aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
150834aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.3.1 flags signal
150934aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 2 2
1510*cbfafac4SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1 0 0 0 speed_10
15118da6229bSGeliang Tang	chk_join_nr "signal addresses, ADD_ADDR timeout" 2 2 2
15128da6229bSGeliang Tang	chk_add_nr 8 0
15138da6229bSGeliang Tang
15148da6229bSGeliang Tang	# signal invalid addresses timeout
15158da6229bSGeliang Tang	reset_with_add_addr_timeout
151634aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 2 2
151734aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.12.1 flags signal
151834aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.3.1 flags signal
151934aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 2 2
1520*cbfafac4SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1 0 0 0 speed_10
15218da6229bSGeliang Tang	chk_join_nr "invalid address, ADD_ADDR timeout" 1 1 1
15228da6229bSGeliang Tang	chk_add_nr 8 0
15231002b89fSGeliang Tang}
15241002b89fSGeliang Tang
15251002b89fSGeliang Tangremove_tests()
15261002b89fSGeliang Tang{
1527dd72b0feSGeliang Tang	# single subflow, remove
1528dd72b0feSGeliang Tang	reset
152934aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
153034aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 0 1
153134aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
15322e8cbf45SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1 0 0 -1 slow
1533dd72b0feSGeliang Tang	chk_join_nr "remove single subflow" 1 1 1
1534dd72b0feSGeliang Tang	chk_rm_nr 1 1
1535dd72b0feSGeliang Tang
1536dd72b0feSGeliang Tang	# multiple subflows, remove
1537dd72b0feSGeliang Tang	reset
153834aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 2
153934aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 0 2
154034aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow
154134aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
15422e8cbf45SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1 0 0 -2 slow
1543dd72b0feSGeliang Tang	chk_join_nr "remove multiple subflows" 2 2 2
1544dd72b0feSGeliang Tang	chk_rm_nr 2 2
1545dd72b0feSGeliang Tang
1546dd72b0feSGeliang Tang	# single address, remove
1547dd72b0feSGeliang Tang	reset
154834aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
154934aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
155034aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 1
15512e8cbf45SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1 0 -1 0 slow
1552dd72b0feSGeliang Tang	chk_join_nr "remove single address" 1 1 1
1553dd72b0feSGeliang Tang	chk_add_nr 1 1
15547028ba8aSGeliang Tang	chk_rm_nr 1 1 invert
1555dd72b0feSGeliang Tang
1556dd72b0feSGeliang Tang	# subflow and signal, remove
1557dd72b0feSGeliang Tang	reset
155834aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 2
155934aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
156034aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 2
156134aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
15622e8cbf45SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1 0 -1 -1 slow
1563dd72b0feSGeliang Tang	chk_join_nr "remove subflow and signal" 2 2 2
1564dd72b0feSGeliang Tang	chk_add_nr 1 1
1565dd72b0feSGeliang Tang	chk_rm_nr 1 1
1566dd72b0feSGeliang Tang
1567dd72b0feSGeliang Tang	# subflows and signal, remove
1568dd72b0feSGeliang Tang	reset
156934aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 3
157034aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
157134aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 3
157234aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
157334aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.4.2 flags subflow
15742e8cbf45SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1 0 -1 -2 slow
1575dd72b0feSGeliang Tang	chk_join_nr "remove subflows and signal" 3 3 3
1576dd72b0feSGeliang Tang	chk_add_nr 1 1
1577dd72b0feSGeliang Tang	chk_rm_nr 2 2
1578dd72b0feSGeliang Tang
1579ef360019SGeliang Tang	# addresses remove
1580ef360019SGeliang Tang	reset
158134aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 3 3
158234aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags signal id 250
158334aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.3.1 flags signal
158434aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.4.1 flags signal
158534aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 3 3
1586ef360019SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1 0 -3 0 slow
1587ef360019SGeliang Tang	chk_join_nr "remove addresses" 3 3 3
1588ef360019SGeliang Tang	chk_add_nr 3 3
1589ef360019SGeliang Tang	chk_rm_nr 3 3 invert
1590ef360019SGeliang Tang
1591ef360019SGeliang Tang	# invalid addresses remove
1592ef360019SGeliang Tang	reset
159334aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 3 3
159434aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.12.1 flags signal
159534aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.3.1 flags signal
159634aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.14.1 flags signal
159734aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 3 3
1598ef360019SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1 0 -3 0 slow
1599ef360019SGeliang Tang	chk_join_nr "remove invalid addresses" 1 1 1
1600ef360019SGeliang Tang	chk_add_nr 3 3
1601ef360019SGeliang Tang	chk_rm_nr 3 1 invert
1602ef360019SGeliang Tang
16036fe4ccdcSGeliang Tang	# subflows and signal, flush
16046fe4ccdcSGeliang Tang	reset
160534aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 3
160634aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
160734aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 3
160834aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
160934aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.4.2 flags subflow
16102e8cbf45SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1 0 -8 -8 slow
16116fe4ccdcSGeliang Tang	chk_join_nr "flush subflows and signal" 3 3 3
16126fe4ccdcSGeliang Tang	chk_add_nr 1 1
16136fe4ccdcSGeliang Tang	chk_rm_nr 2 2
1614d2c4333aSGeliang Tang
1615d2c4333aSGeliang Tang	# subflows flush
1616d2c4333aSGeliang Tang	reset
161734aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 3 3
161834aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 3 3
161934aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow id 150
162034aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
162134aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.4.2 flags subflow
1622d2c4333aSGeliang Tang	run_tests $ns1 $ns2 10.0.1.1 0 -8 -8 slow
1623d2c4333aSGeliang Tang	chk_join_nr "flush subflows" 3 3 3
1624d2c4333aSGeliang Tang	chk_rm_nr 3 3
1625d2c4333aSGeliang Tang
1626d2c4333aSGeliang Tang	# addresses flush
1627d2c4333aSGeliang Tang	reset
162834aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 3 3
162934aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags signal id 250
163034aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.3.1 flags signal
163134aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.4.1 flags signal
163234aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 3 3
1633d2c4333aSGeliang Tang	run_tests $ns1 $ns2 10.0.1.1 0 -8 -8 slow
1634d2c4333aSGeliang Tang	chk_join_nr "flush addresses" 3 3 3
1635d2c4333aSGeliang Tang	chk_add_nr 3 3
1636d2c4333aSGeliang Tang	chk_rm_nr 3 3 invert
1637ef360019SGeliang Tang
1638ef360019SGeliang Tang	# invalid addresses flush
1639ef360019SGeliang Tang	reset
164034aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 3 3
164134aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.12.1 flags signal
164234aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.3.1 flags signal
164334aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.14.1 flags signal
164434aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 3 3
1645ef360019SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1 0 -8 0 slow
1646ef360019SGeliang Tang	chk_join_nr "flush invalid addresses" 1 1 1
1647ef360019SGeliang Tang	chk_add_nr 3 3
1648ef360019SGeliang Tang	chk_rm_nr 3 1 invert
16495e287fe7SGeliang Tang
16505e287fe7SGeliang Tang	# remove id 0 subflow
16515e287fe7SGeliang Tang	reset
165234aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
165334aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 0 1
165434aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
16555e287fe7SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1 0 0 -9 slow
16565e287fe7SGeliang Tang	chk_join_nr "remove id 0 subflow" 1 1 1
16575e287fe7SGeliang Tang	chk_rm_nr 1 1
16585e287fe7SGeliang Tang
16595e287fe7SGeliang Tang	# remove id 0 address
16605e287fe7SGeliang Tang	reset
166134aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
166234aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
166334aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 1
16645e287fe7SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1 0 -9 0 slow
16655e287fe7SGeliang Tang	chk_join_nr "remove id 0 address" 1 1 1
16665e287fe7SGeliang Tang	chk_add_nr 1 1
16675e287fe7SGeliang Tang	chk_rm_nr 1 1 invert
16681002b89fSGeliang Tang}
16696fe4ccdcSGeliang Tang
16701002b89fSGeliang Tangadd_tests()
16711002b89fSGeliang Tang{
16726208fd82SGeliang Tang	# add single subflow
16736208fd82SGeliang Tang	reset
167434aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
167534aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 0 1
16766208fd82SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1 0 0 1 slow
16776208fd82SGeliang Tang	chk_join_nr "add single subflow" 1 1 1
16786208fd82SGeliang Tang
16796208fd82SGeliang Tang	# add signal address
16806208fd82SGeliang Tang	reset
168134aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
168234aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 1
16836208fd82SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1 0 1 0 slow
16846208fd82SGeliang Tang	chk_join_nr "add signal address" 1 1 1
16856208fd82SGeliang Tang	chk_add_nr 1 1
16866208fd82SGeliang Tang
16876208fd82SGeliang Tang	# add multiple subflows
16886208fd82SGeliang Tang	reset
168934aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 2
169034aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 0 2
16916208fd82SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1 0 0 2 slow
16926208fd82SGeliang Tang	chk_join_nr "add multiple subflows" 2 2 2
16936208fd82SGeliang Tang
16946208fd82SGeliang Tang	# add multiple subflows IPv6
16956208fd82SGeliang Tang	reset
169634aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 2
169734aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 0 2
16986208fd82SGeliang Tang	run_tests $ns1 $ns2 dead:beef:1::1 0 0 2 slow
16996208fd82SGeliang Tang	chk_join_nr "add multiple subflows IPv6" 2 2 2
17006208fd82SGeliang Tang
17016208fd82SGeliang Tang	# add multiple addresses IPv6
17026208fd82SGeliang Tang	reset
170334aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 2
170434aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 2 2
17056208fd82SGeliang Tang	run_tests $ns1 $ns2 dead:beef:1::1 0 2 0 slow
17066208fd82SGeliang Tang	chk_join_nr "add multiple addresses IPv6" 2 2 2
17076208fd82SGeliang Tang	chk_add_nr 2 2
17081002b89fSGeliang Tang}
17096208fd82SGeliang Tang
17101002b89fSGeliang Tangipv6_tests()
17111002b89fSGeliang Tang{
1712523514edSGeliang Tang	# subflow IPv6
1713523514edSGeliang Tang	reset
171434aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
171534aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 0 1
171634aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 dead:beef:3::2 dev ns2eth3 flags subflow
1717523514edSGeliang Tang	run_tests $ns1 $ns2 dead:beef:1::1 0 0 0 slow
1718523514edSGeliang Tang	chk_join_nr "single subflow IPv6" 1 1 1
1719523514edSGeliang Tang
1720523514edSGeliang Tang	# add_address, unused IPv6
1721523514edSGeliang Tang	reset
172234aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 dead:beef:2::1 flags signal
1723523514edSGeliang Tang	run_tests $ns1 $ns2 dead:beef:1::1 0 0 0 slow
1724523514edSGeliang Tang	chk_join_nr "unused signal address IPv6" 0 0 0
1725523514edSGeliang Tang	chk_add_nr 1 1
1726523514edSGeliang Tang
1727523514edSGeliang Tang	# signal address IPv6
1728523514edSGeliang Tang	reset
172934aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
173034aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 dead:beef:2::1 flags signal
173134aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 1
1732523514edSGeliang Tang	run_tests $ns1 $ns2 dead:beef:1::1 0 0 0 slow
1733523514edSGeliang Tang	chk_join_nr "single address IPv6" 1 1 1
1734523514edSGeliang Tang	chk_add_nr 1 1
1735523514edSGeliang Tang
1736523514edSGeliang Tang	# single address IPv6, remove
1737523514edSGeliang Tang	reset
173834aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
173934aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 dead:beef:2::1 flags signal
174034aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 1
17412e8cbf45SGeliang Tang	run_tests $ns1 $ns2 dead:beef:1::1 0 -1 0 slow
1742523514edSGeliang Tang	chk_join_nr "remove single address IPv6" 1 1 1
1743523514edSGeliang Tang	chk_add_nr 1 1
17447028ba8aSGeliang Tang	chk_rm_nr 1 1 invert
1745523514edSGeliang Tang
1746523514edSGeliang Tang	# subflow and signal IPv6, remove
1747523514edSGeliang Tang	reset
174834aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 2
174934aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 dead:beef:2::1 flags signal
175034aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 2
175134aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 dead:beef:3::2 dev ns2eth3 flags subflow
17522e8cbf45SGeliang Tang	run_tests $ns1 $ns2 dead:beef:1::1 0 -1 -1 slow
1753523514edSGeliang Tang	chk_join_nr "remove subflow and signal IPv6" 2 2 2
1754523514edSGeliang Tang	chk_add_nr 1 1
1755523514edSGeliang Tang	chk_rm_nr 1 1
17561002b89fSGeliang Tang}
1757523514edSGeliang Tang
17581002b89fSGeliang Tangv4mapped_tests()
17591002b89fSGeliang Tang{
1760a6094788SGeliang Tang	# subflow IPv4-mapped to IPv4-mapped
1761a6094788SGeliang Tang	reset
176234aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
176334aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 0 1
176434aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 "::ffff:10.0.3.2" flags subflow
1765a6094788SGeliang Tang	run_tests $ns1 $ns2 "::ffff:10.0.1.1"
1766a6094788SGeliang Tang	chk_join_nr "single subflow IPv4-mapped" 1 1 1
1767a6094788SGeliang Tang
1768a6094788SGeliang Tang	# signal address IPv4-mapped with IPv4-mapped sk
1769a6094788SGeliang Tang	reset
177034aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
177134aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 1
177234aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 "::ffff:10.0.2.1" flags signal
1773a6094788SGeliang Tang	run_tests $ns1 $ns2 "::ffff:10.0.1.1"
1774a6094788SGeliang Tang	chk_join_nr "signal address IPv4-mapped" 1 1 1
1775a6094788SGeliang Tang	chk_add_nr 1 1
1776a6094788SGeliang Tang
1777a6094788SGeliang Tang	# subflow v4-map-v6
1778a6094788SGeliang Tang	reset
177934aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
178034aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 0 1
178134aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
1782a6094788SGeliang Tang	run_tests $ns1 $ns2 "::ffff:10.0.1.1"
1783a6094788SGeliang Tang	chk_join_nr "single subflow v4-map-v6" 1 1 1
1784a6094788SGeliang Tang
1785a6094788SGeliang Tang	# signal address v4-map-v6
1786a6094788SGeliang Tang	reset
178734aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
178834aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 1
178934aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
1790a6094788SGeliang Tang	run_tests $ns1 $ns2 "::ffff:10.0.1.1"
1791a6094788SGeliang Tang	chk_join_nr "signal address v4-map-v6" 1 1 1
1792a6094788SGeliang Tang	chk_add_nr 1 1
1793a6094788SGeliang Tang
1794a6094788SGeliang Tang	# subflow v6-map-v4
1795a6094788SGeliang Tang	reset
179634aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
179734aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 0 1
179834aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 "::ffff:10.0.3.2" flags subflow
1799a6094788SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1
1800a6094788SGeliang Tang	chk_join_nr "single subflow v6-map-v4" 1 1 1
1801a6094788SGeliang Tang
1802a6094788SGeliang Tang	# signal address v6-map-v4
1803a6094788SGeliang Tang	reset
180434aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
180534aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 1
180634aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 "::ffff:10.0.2.1" flags signal
1807a6094788SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1
1808a6094788SGeliang Tang	chk_join_nr "signal address v6-map-v4" 1 1 1
1809a6094788SGeliang Tang	chk_add_nr 1 1
1810a6094788SGeliang Tang
1811a6094788SGeliang Tang	# no subflow IPv6 to v4 address
1812a6094788SGeliang Tang	reset
181334aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
181434aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 0 1
181534aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 dead:beef:2::2 flags subflow
1816a6094788SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1
1817a6094788SGeliang Tang	chk_join_nr "no JOIN with diff families v4-v6" 0 0 0
1818a6094788SGeliang Tang
1819a6094788SGeliang Tang	# no subflow IPv6 to v4 address even if v6 has a valid v4 at the end
1820a6094788SGeliang Tang	reset
182134aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
182234aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 0 1
182334aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 dead:beef:2::10.0.3.2 flags subflow
1824a6094788SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1
1825a6094788SGeliang Tang	chk_join_nr "no JOIN with diff families v4-v6-2" 0 0 0
1826a6094788SGeliang Tang
1827a6094788SGeliang Tang	# no subflow IPv4 to v6 address, no need to slow down too then
1828a6094788SGeliang Tang	reset
182934aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
183034aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 0 1
183134aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
1832a6094788SGeliang Tang	run_tests $ns1 $ns2 dead:beef:1::1
1833a6094788SGeliang Tang	chk_join_nr "no JOIN with diff families v6-v4" 0 0 0
18341002b89fSGeliang Tang}
1835a6094788SGeliang Tang
18361002b89fSGeliang Tangbackup_tests()
18371002b89fSGeliang Tang{
1838718eb44eSGeliang Tang	# single subflow, backup
1839718eb44eSGeliang Tang	reset
184034aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
184134aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 0 1
184234aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow,backup
1843718eb44eSGeliang Tang	run_tests $ns1 $ns2 10.0.1.1 0 0 0 slow nobackup
1844718eb44eSGeliang Tang	chk_join_nr "single subflow, backup" 1 1 1
1845718eb44eSGeliang Tang	chk_prio_nr 0 1
1846718eb44eSGeliang Tang
1847718eb44eSGeliang Tang	# single address, backup
1848718eb44eSGeliang Tang	reset
184934aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
185034aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
185134aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 1
1852718eb44eSGeliang Tang	run_tests $ns1 $ns2 10.0.1.1 0 0 0 slow backup
1853718eb44eSGeliang Tang	chk_join_nr "single address, backup" 1 1 1
1854718eb44eSGeliang Tang	chk_add_nr 1 1
1855718eb44eSGeliang Tang	chk_prio_nr 1 0
185633397b83SGeliang Tang
185733397b83SGeliang Tang	# single address with port, backup
185833397b83SGeliang Tang	reset
185934aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
186034aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags signal port 10100
186134aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 1
186233397b83SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1 0 0 0 slow backup
186333397b83SGeliang Tang	chk_join_nr "single address with port, backup" 1 1 1
186433397b83SGeliang Tang	chk_add_nr 1 1
186533397b83SGeliang Tang	chk_prio_nr 1 0
18661002b89fSGeliang Tang}
1867718eb44eSGeliang Tang
18681002b89fSGeliang Tangadd_addr_ports_tests()
18691002b89fSGeliang Tang{
18708a127bf6SGeliang Tang	# signal address with port
18718a127bf6SGeliang Tang	reset
187234aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
187334aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 1
187434aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags signal port 10100
18758a127bf6SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1
18768a127bf6SGeliang Tang	chk_join_nr "signal address with port" 1 1 1
18778a127bf6SGeliang Tang	chk_add_nr 1 1 1
18788a127bf6SGeliang Tang
18798a127bf6SGeliang Tang	# subflow and signal with port
18808a127bf6SGeliang Tang	reset
188134aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags signal port 10100
188234aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 2
188334aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 2
188434aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
18858a127bf6SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1
18868a127bf6SGeliang Tang	chk_join_nr "subflow and signal with port" 2 2 2
18878a127bf6SGeliang Tang	chk_add_nr 1 1 1
18888a127bf6SGeliang Tang
18898a127bf6SGeliang Tang	# single address with port, remove
18908a127bf6SGeliang Tang	reset
189134aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
189234aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags signal port 10100
189334aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 1
18948a127bf6SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1 0 -1 0 slow
18958a127bf6SGeliang Tang	chk_join_nr "remove single address with port" 1 1 1
18968a127bf6SGeliang Tang	chk_add_nr 1 1 1
18977028ba8aSGeliang Tang	chk_rm_nr 1 1 invert
18988a127bf6SGeliang Tang
18998a127bf6SGeliang Tang	# subflow and signal with port, remove
19008a127bf6SGeliang Tang	reset
190134aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 2
190234aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags signal port 10100
190334aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 2
190434aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
19058a127bf6SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1 0 -1 -1 slow
19068a127bf6SGeliang Tang	chk_join_nr "remove subflow and signal with port" 2 2 2
19078a127bf6SGeliang Tang	chk_add_nr 1 1 1
19088a127bf6SGeliang Tang	chk_rm_nr 1 1
19098a127bf6SGeliang Tang
19108a127bf6SGeliang Tang	# subflows and signal with port, flush
19118a127bf6SGeliang Tang	reset
191234aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 3
191334aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags signal port 10100
191434aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 3
191534aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
191634aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.4.2 flags subflow
1917327b9a94SPaolo Abeni	run_tests $ns1 $ns2 10.0.1.1 0 -8 -2 slow
19188a127bf6SGeliang Tang	chk_join_nr "flush subflows and signal with port" 3 3 3
19198a127bf6SGeliang Tang	chk_add_nr 1 1
19208a127bf6SGeliang Tang	chk_rm_nr 2 2
19218a127bf6SGeliang Tang
19228a127bf6SGeliang Tang	# multiple addresses with port
19238a127bf6SGeliang Tang	reset
192434aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 2 2
192534aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags signal port 10100
192634aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.3.1 flags signal port 10100
192734aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 2 2
19288a127bf6SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1
19298a127bf6SGeliang Tang	chk_join_nr "multiple addresses with port" 2 2 2
19308a127bf6SGeliang Tang	chk_add_nr 2 2 2
19318a127bf6SGeliang Tang
19328a127bf6SGeliang Tang	# multiple addresses with ports
19338a127bf6SGeliang Tang	reset
193434aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 2 2
193534aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags signal port 10100
193634aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.3.1 flags signal port 10101
193734aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 2 2
19388a127bf6SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1
19398a127bf6SGeliang Tang	chk_join_nr "multiple addresses with ports" 2 2 2
19408a127bf6SGeliang Tang	chk_add_nr 2 2 2
19411002b89fSGeliang Tang}
19428a127bf6SGeliang Tang
19431002b89fSGeliang Tangsyncookies_tests()
19441002b89fSGeliang Tang{
194500587187SFlorian Westphal	# single subflow, syncookies
194600587187SFlorian Westphal	reset_with_cookies
194734aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
194834aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 0 1
194934aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
195000587187SFlorian Westphal	run_tests $ns1 $ns2 10.0.1.1
195100587187SFlorian Westphal	chk_join_nr "single subflow with syn cookies" 1 1 1
195200587187SFlorian Westphal
195300587187SFlorian Westphal	# multiple subflows with syn cookies
195400587187SFlorian Westphal	reset_with_cookies
195534aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 2
195634aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 0 2
195734aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
195834aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow
195900587187SFlorian Westphal	run_tests $ns1 $ns2 10.0.1.1
196000587187SFlorian Westphal	chk_join_nr "multiple subflows with syn cookies" 2 2 2
196100587187SFlorian Westphal
196200587187SFlorian Westphal	# multiple subflows limited by server
196300587187SFlorian Westphal	reset_with_cookies
196434aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
196534aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 0 2
196634aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
196734aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow
196800587187SFlorian Westphal	run_tests $ns1 $ns2 10.0.1.1
1969a7da4416SJianguo Wu	chk_join_nr "subflows limited by server w cookies" 2 1 1
197000587187SFlorian Westphal
197100587187SFlorian Westphal	# test signal address with cookies
197200587187SFlorian Westphal	reset_with_cookies
197334aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
197434aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 1
197534aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
197600587187SFlorian Westphal	run_tests $ns1 $ns2 10.0.1.1
197700587187SFlorian Westphal	chk_join_nr "signal address with syn cookies" 1 1 1
1978be613160SGeliang Tang	chk_add_nr 1 1
197900587187SFlorian Westphal
198000587187SFlorian Westphal	# test cookie with subflow and signal
198100587187SFlorian Westphal	reset_with_cookies
198234aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
198334aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 2
198434aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 2
198534aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
198600587187SFlorian Westphal	run_tests $ns1 $ns2 10.0.1.1
198700587187SFlorian Westphal	chk_join_nr "subflow and signal w cookies" 2 2 2
1988be613160SGeliang Tang	chk_add_nr 1 1
198900587187SFlorian Westphal
199000587187SFlorian Westphal	# accept and use add_addr with additional subflows
199100587187SFlorian Westphal	reset_with_cookies
199234aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 3
199334aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
199434aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 3
199534aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
199634aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.4.2 flags subflow
199700587187SFlorian Westphal	run_tests $ns1 $ns2 10.0.1.1
199800587187SFlorian Westphal	chk_join_nr "subflows and signal w. cookies" 3 3 3
1999be613160SGeliang Tang	chk_add_nr 1 1
20001002b89fSGeliang Tang}
20011002b89fSGeliang Tang
2002af66d3e1SGeliang Tangchecksum_tests()
2003af66d3e1SGeliang Tang{
2004af66d3e1SGeliang Tang	# checksum test 0 0
2005af66d3e1SGeliang Tang	reset_with_checksum 0 0
200634aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
200734aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 0 1
2008af66d3e1SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1
2009af66d3e1SGeliang Tang	chk_csum_nr "checksum test 0 0"
2010af66d3e1SGeliang Tang
2011af66d3e1SGeliang Tang	# checksum test 1 1
2012af66d3e1SGeliang Tang	reset_with_checksum 1 1
201334aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
201434aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 0 1
2015af66d3e1SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1
2016af66d3e1SGeliang Tang	chk_csum_nr "checksum test 1 1"
2017af66d3e1SGeliang Tang
2018af66d3e1SGeliang Tang	# checksum test 0 1
2019af66d3e1SGeliang Tang	reset_with_checksum 0 1
202034aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
202134aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 0 1
2022af66d3e1SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1
2023af66d3e1SGeliang Tang	chk_csum_nr "checksum test 0 1"
2024af66d3e1SGeliang Tang
2025af66d3e1SGeliang Tang	# checksum test 1 0
2026af66d3e1SGeliang Tang	reset_with_checksum 1 0
202734aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 1
202834aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 0 1
2029af66d3e1SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1
2030af66d3e1SGeliang Tang	chk_csum_nr "checksum test 1 0"
2031af66d3e1SGeliang Tang}
2032af66d3e1SGeliang Tang
20330cddb4a6SGeliang Tangdeny_join_id0_tests()
20340cddb4a6SGeliang Tang{
20350cddb4a6SGeliang Tang	# subflow allow join id0 ns1
20360cddb4a6SGeliang Tang	reset_with_allow_join_id0 1 0
203734aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 1 1
203834aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 1
203934aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
20400cddb4a6SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1
20410cddb4a6SGeliang Tang	chk_join_nr "single subflow allow join id0 ns1" 1 1 1
20420cddb4a6SGeliang Tang
20430cddb4a6SGeliang Tang	# subflow allow join id0 ns2
20440cddb4a6SGeliang Tang	reset_with_allow_join_id0 0 1
204534aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 1 1
204634aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 1
204734aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
20480cddb4a6SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1
20490cddb4a6SGeliang Tang	chk_join_nr "single subflow allow join id0 ns2" 0 0 0
20500cddb4a6SGeliang Tang
20510cddb4a6SGeliang Tang	# signal address allow join id0 ns1
20520cddb4a6SGeliang Tang	# ADD_ADDRs are not affected by allow_join_id0 value.
20530cddb4a6SGeliang Tang	reset_with_allow_join_id0 1 0
205434aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 1 1
205534aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 1
205634aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
20570cddb4a6SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1
20580cddb4a6SGeliang Tang	chk_join_nr "signal address allow join id0 ns1" 1 1 1
20590cddb4a6SGeliang Tang	chk_add_nr 1 1
20600cddb4a6SGeliang Tang
20610cddb4a6SGeliang Tang	# signal address allow join id0 ns2
20620cddb4a6SGeliang Tang	# ADD_ADDRs are not affected by allow_join_id0 value.
20630cddb4a6SGeliang Tang	reset_with_allow_join_id0 0 1
206434aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 1 1
206534aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 1
206634aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
20670cddb4a6SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1
20680cddb4a6SGeliang Tang	chk_join_nr "signal address allow join id0 ns2" 1 1 1
20690cddb4a6SGeliang Tang	chk_add_nr 1 1
20700cddb4a6SGeliang Tang
20710cddb4a6SGeliang Tang	# subflow and address allow join id0 ns1
20720cddb4a6SGeliang Tang	reset_with_allow_join_id0 1 0
207334aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 2 2
207434aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 2 2
207534aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
207634aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
20770cddb4a6SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1
20780cddb4a6SGeliang Tang	chk_join_nr "subflow and address allow join id0 1" 2 2 2
20790cddb4a6SGeliang Tang
20800cddb4a6SGeliang Tang	# subflow and address allow join id0 ns2
20810cddb4a6SGeliang Tang	reset_with_allow_join_id0 0 1
208234aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 2 2
208334aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 2 2
208434aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
208534aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
20860cddb4a6SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1
20870cddb4a6SGeliang Tang	chk_join_nr "subflow and address allow join id0 2" 1 1 1
20880cddb4a6SGeliang Tang}
20890cddb4a6SGeliang Tang
20904f49d633SGeliang Tangfullmesh_tests()
20914f49d633SGeliang Tang{
20924f49d633SGeliang Tang	# fullmesh 1
20934f49d633SGeliang Tang	# 2 fullmesh addrs in ns2, added before the connection,
20944f49d633SGeliang Tang	# 1 non-fullmesh addr in ns1, added during the connection.
20954f49d633SGeliang Tang	reset
209634aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 0 4
209734aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 4
209834aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow,fullmesh
209934aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow,fullmesh
21004f49d633SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1 0 1 0 slow
21014f49d633SGeliang Tang	chk_join_nr "fullmesh test 2x1" 4 4 4
21024f49d633SGeliang Tang	chk_add_nr 1 1
21034f49d633SGeliang Tang
21044f49d633SGeliang Tang	# fullmesh 2
21054f49d633SGeliang Tang	# 1 non-fullmesh addr in ns1, added before the connection,
21064f49d633SGeliang Tang	# 1 fullmesh addr in ns2, added during the connection.
21074f49d633SGeliang Tang	reset
210834aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 1 3
210934aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 3
211034aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
21114f49d633SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1 0 0 fullmesh_1 slow
21124f49d633SGeliang Tang	chk_join_nr "fullmesh test 1x1" 3 3 3
21134f49d633SGeliang Tang	chk_add_nr 1 1
21144f49d633SGeliang Tang
21154f49d633SGeliang Tang	# fullmesh 3
21164f49d633SGeliang Tang	# 1 non-fullmesh addr in ns1, added before the connection,
21174f49d633SGeliang Tang	# 2 fullmesh addrs in ns2, added during the connection.
21184f49d633SGeliang Tang	reset
211934aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 2 5
212034aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 5
212134aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
21224f49d633SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1 0 0 fullmesh_2 slow
21234f49d633SGeliang Tang	chk_join_nr "fullmesh test 1x2" 5 5 5
21244f49d633SGeliang Tang	chk_add_nr 1 1
21254f49d633SGeliang Tang
21264f49d633SGeliang Tang	# fullmesh 4
21274f49d633SGeliang Tang	# 1 non-fullmesh addr in ns1, added before the connection,
21284f49d633SGeliang Tang	# 2 fullmesh addrs in ns2, added during the connection,
21294f49d633SGeliang Tang	# limit max_subflows to 4.
21304f49d633SGeliang Tang	reset
213134aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 2 4
213234aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 1 4
213334aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
21344f49d633SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1 0 0 fullmesh_2 slow
21354f49d633SGeliang Tang	chk_join_nr "fullmesh test 1x2, limited" 4 4 4
21364f49d633SGeliang Tang	chk_add_nr 1 1
21376a0653b9SGeliang Tang
21386a0653b9SGeliang Tang	# set fullmesh flag
21396a0653b9SGeliang Tang	reset
214034aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 4 4
214134aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags subflow
214234aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 4 4
21436a0653b9SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1 0 0 1 slow fullmesh
21446a0653b9SGeliang Tang	chk_join_nr "set fullmesh flag test" 2 2 2
21456a0653b9SGeliang Tang	chk_rm_nr 0 1
21466a0653b9SGeliang Tang
21476a0653b9SGeliang Tang	# set nofullmesh flag
21486a0653b9SGeliang Tang	reset
214934aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 4 4
215034aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags subflow,fullmesh
215134aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 4 4
21526a0653b9SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1 0 0 fullmesh_1 slow nofullmesh
21536a0653b9SGeliang Tang	chk_join_nr "set nofullmesh flag test" 2 2 2
21546a0653b9SGeliang Tang	chk_rm_nr 0 1
21556a0653b9SGeliang Tang
21566a0653b9SGeliang Tang	# set backup,fullmesh flags
21576a0653b9SGeliang Tang	reset
215834aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 4 4
215934aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns1 10.0.2.1 flags subflow
216034aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 4 4
21616a0653b9SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1 0 0 1 slow backup,fullmesh
21626a0653b9SGeliang Tang	chk_join_nr "set backup,fullmesh flags test" 2 2 2
21636a0653b9SGeliang Tang	chk_prio_nr 0 1
21646a0653b9SGeliang Tang	chk_rm_nr 0 1
21656a0653b9SGeliang Tang
21666a0653b9SGeliang Tang	# set nobackup,nofullmesh flags
21676a0653b9SGeliang Tang	reset
216834aa6e3bSGeliang Tang	pm_nl_set_limits $ns1 4 4
216934aa6e3bSGeliang Tang	pm_nl_set_limits $ns2 4 4
217034aa6e3bSGeliang Tang	pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow,backup,fullmesh
21716a0653b9SGeliang Tang	run_tests $ns1 $ns2 10.0.1.1 0 0 0 slow nobackup,nofullmesh
21726a0653b9SGeliang Tang	chk_join_nr "set nobackup,nofullmesh flags test" 2 2 2
21736a0653b9SGeliang Tang	chk_prio_nr 0 1
21746a0653b9SGeliang Tang	chk_rm_nr 0 1
21754f49d633SGeliang Tang}
21764f49d633SGeliang Tang
21771002b89fSGeliang Tangall_tests()
21781002b89fSGeliang Tang{
21791002b89fSGeliang Tang	subflows_tests
218046e967d1SPaolo Abeni	subflows_error_tests
21811002b89fSGeliang Tang	signal_address_tests
21821002b89fSGeliang Tang	link_failure_tests
21831002b89fSGeliang Tang	add_addr_timeout_tests
21841002b89fSGeliang Tang	remove_tests
21851002b89fSGeliang Tang	add_tests
21861002b89fSGeliang Tang	ipv6_tests
21871002b89fSGeliang Tang	v4mapped_tests
21881002b89fSGeliang Tang	backup_tests
21891002b89fSGeliang Tang	add_addr_ports_tests
21901002b89fSGeliang Tang	syncookies_tests
2191af66d3e1SGeliang Tang	checksum_tests
21920cddb4a6SGeliang Tang	deny_join_id0_tests
21934f49d633SGeliang Tang	fullmesh_tests
21941002b89fSGeliang Tang}
21951002b89fSGeliang Tang
219622514d52SMatthieu Baerts# [$1: error message]
21971002b89fSGeliang Tangusage()
21981002b89fSGeliang Tang{
219922514d52SMatthieu Baerts	if [ -n "${1}" ]; then
220022514d52SMatthieu Baerts		echo "${1}"
220122514d52SMatthieu Baerts		ret=1
220222514d52SMatthieu Baerts	fi
220322514d52SMatthieu Baerts
22041002b89fSGeliang Tang	echo "mptcp_join usage:"
22051002b89fSGeliang Tang	echo "  -f subflows_tests"
220646e967d1SPaolo Abeni	echo "  -e subflows_error_tests"
22071002b89fSGeliang Tang	echo "  -s signal_address_tests"
22081002b89fSGeliang Tang	echo "  -l link_failure_tests"
22091002b89fSGeliang Tang	echo "  -t add_addr_timeout_tests"
22101002b89fSGeliang Tang	echo "  -r remove_tests"
22111002b89fSGeliang Tang	echo "  -a add_tests"
22121002b89fSGeliang Tang	echo "  -6 ipv6_tests"
22131002b89fSGeliang Tang	echo "  -4 v4mapped_tests"
22141002b89fSGeliang Tang	echo "  -b backup_tests"
22151002b89fSGeliang Tang	echo "  -p add_addr_ports_tests"
2216a673321aSMat Martineau	echo "  -k syncookies_tests"
2217af66d3e1SGeliang Tang	echo "  -S checksum_tests"
22180cddb4a6SGeliang Tang	echo "  -d deny_join_id0_tests"
22194f49d633SGeliang Tang	echo "  -m fullmesh_tests"
2220a673321aSMat Martineau	echo "  -c capture pcap files"
2221af66d3e1SGeliang Tang	echo "  -C enable data checksum"
2222621bd393SGeliang Tang	echo "  -i use ip mptcp"
22231002b89fSGeliang Tang	echo "  -h help"
222422514d52SMatthieu Baerts
222522514d52SMatthieu Baerts	exit ${ret}
22261002b89fSGeliang Tang}
22271002b89fSGeliang Tang
2228a673321aSMat Martineaufor arg in "$@"; do
2229af66d3e1SGeliang Tang	# check for "capture/checksum" args before launching tests
2230a673321aSMat Martineau	if [[ "${arg}" =~ ^"-"[0-9a-zA-Z]*"c"[0-9a-zA-Z]*$ ]]; then
2231a673321aSMat Martineau		capture=1
2232a673321aSMat Martineau	fi
2233af66d3e1SGeliang Tang	if [[ "${arg}" =~ ^"-"[0-9a-zA-Z]*"C"[0-9a-zA-Z]*$ ]]; then
2234af66d3e1SGeliang Tang		checksum=1
2235af66d3e1SGeliang Tang	fi
2236621bd393SGeliang Tang	if [[ "${arg}" =~ ^"-"[0-9a-zA-Z]*"i"[0-9a-zA-Z]*$ ]]; then
2237621bd393SGeliang Tang		ip_mptcp=1
2238621bd393SGeliang Tang	fi
2239a673321aSMat Martineau
2240621bd393SGeliang Tang	# exception for the capture/checksum/ip_mptcp options, the rest means: a part of the tests
2241621bd393SGeliang Tang	if [ "${arg}" != "-c" ] && [ "${arg}" != "-C" ] && [ "${arg}" != "-i" ]; then
2242a673321aSMat Martineau		do_all_tests=0
2243a673321aSMat Martineau	fi
2244a673321aSMat Martineaudone
2245a673321aSMat Martineau
2246a673321aSMat Martineauif [ $do_all_tests -eq 1 ]; then
22471002b89fSGeliang Tang	all_tests
22481002b89fSGeliang Tang	exit $ret
22491002b89fSGeliang Tangfi
22501002b89fSGeliang Tang
2251621bd393SGeliang Tangwhile getopts 'fesltra64bpkdmchCSi' opt; do
22521002b89fSGeliang Tang	case $opt in
22531002b89fSGeliang Tang		f)
22541002b89fSGeliang Tang			subflows_tests
22551002b89fSGeliang Tang			;;
225646e967d1SPaolo Abeni		e)
225746e967d1SPaolo Abeni			subflows_error_tests
225846e967d1SPaolo Abeni			;;
22591002b89fSGeliang Tang		s)
22601002b89fSGeliang Tang			signal_address_tests
22611002b89fSGeliang Tang			;;
22621002b89fSGeliang Tang		l)
22631002b89fSGeliang Tang			link_failure_tests
22641002b89fSGeliang Tang			;;
22651002b89fSGeliang Tang		t)
22661002b89fSGeliang Tang			add_addr_timeout_tests
22671002b89fSGeliang Tang			;;
22681002b89fSGeliang Tang		r)
22691002b89fSGeliang Tang			remove_tests
22701002b89fSGeliang Tang			;;
22711002b89fSGeliang Tang		a)
22721002b89fSGeliang Tang			add_tests
22731002b89fSGeliang Tang			;;
22741002b89fSGeliang Tang		6)
22751002b89fSGeliang Tang			ipv6_tests
22761002b89fSGeliang Tang			;;
22771002b89fSGeliang Tang		4)
22781002b89fSGeliang Tang			v4mapped_tests
22791002b89fSGeliang Tang			;;
22801002b89fSGeliang Tang		b)
22811002b89fSGeliang Tang			backup_tests
22821002b89fSGeliang Tang			;;
22831002b89fSGeliang Tang		p)
22841002b89fSGeliang Tang			add_addr_ports_tests
22851002b89fSGeliang Tang			;;
2286a673321aSMat Martineau		k)
22871002b89fSGeliang Tang			syncookies_tests
22881002b89fSGeliang Tang			;;
2289af66d3e1SGeliang Tang		S)
2290af66d3e1SGeliang Tang			checksum_tests
2291af66d3e1SGeliang Tang			;;
22920cddb4a6SGeliang Tang		d)
22930cddb4a6SGeliang Tang			deny_join_id0_tests
22940cddb4a6SGeliang Tang			;;
22954f49d633SGeliang Tang		m)
22964f49d633SGeliang Tang			fullmesh_tests
22974f49d633SGeliang Tang			;;
2298a673321aSMat Martineau		c)
2299a673321aSMat Martineau			;;
2300af66d3e1SGeliang Tang		C)
2301af66d3e1SGeliang Tang			;;
2302621bd393SGeliang Tang		i)
2303621bd393SGeliang Tang			;;
230422514d52SMatthieu Baerts		h)
23051002b89fSGeliang Tang			usage
23061002b89fSGeliang Tang			;;
230722514d52SMatthieu Baerts		*)
230822514d52SMatthieu Baerts			usage "Unknown option: -${opt}"
230922514d52SMatthieu Baerts			;;
23101002b89fSGeliang Tang	esac
23111002b89fSGeliang Tangdone
231200587187SFlorian Westphal
2313b08fbf24SPaolo Abeniexit $ret
2314