1b08fbf24SPaolo Abeni#!/bin/bash
2b08fbf24SPaolo Abeni# SPDX-License-Identifier: GPL-2.0
3b08fbf24SPaolo Abeni
4d8d08302SMatthieu Baerts# Double quotes to prevent globbing and word splitting is recommended in new
5d8d08302SMatthieu Baerts# code but we accept it, especially because there were too many before having
6d8d08302SMatthieu Baerts# address all other issues detected by shellcheck.
7d8d08302SMatthieu Baerts#shellcheck disable=SC2086
8d8d08302SMatthieu Baerts
9b08fbf24SPaolo Abeniret=0
10b08fbf24SPaolo Abenisin=""
117d1e6f16SPaolo Abenisinfail=""
12b08fbf24SPaolo Abenisout=""
13b08fbf24SPaolo Abenicin=""
147d1e6f16SPaolo Abenicinfail=""
158b819a84SFlorian Westphalcinsent=""
16b08fbf24SPaolo Abenicout=""
171e777bd8SMatthieu Baertscapout=""
181e777bd8SMatthieu Baertsns1=""
191e777bd8SMatthieu Baertsns2=""
20b08fbf24SPaolo Abeniksft_skip=4
215888a61cSMatthieu Baertstimeout_poll=30
225888a61cSMatthieu Baertstimeout_test=$((timeout_poll * 2 + 1))
23b08fbf24SPaolo Abenicapture=0
24af66d3e1SGeliang Tangchecksum=0
2534aa6e3bSGeliang Tangip_mptcp=0
268117dac3SGeliang Tangcheck_invert=0
273c082695SGeliang Tangvalidate_checksum=0
2893827ad5SMatthieu Baertsinit=0
29b08fbf24SPaolo Abeni
303afd0280SMatthieu Baertsdeclare -A all_tests
31c7d49c03SMatthieu Baertsdeclare -a only_tests_ids
32c7d49c03SMatthieu Baertsdeclare -a only_tests_names
3339aab882SMatthieu Baertsdeclare -A failed_tests
34b08fbf24SPaolo AbeniTEST_COUNT=0
35c7d49c03SMatthieu BaertsTEST_NAME=""
369a0a9367SGeliang Tangnr_blank=40
37b08fbf24SPaolo Abeni
38e59300ceSMatthieu Baertsexport FAILING_LINKS=""
39e59300ceSMatthieu Baerts
408d014eaaSGeliang Tang# generated using "nfbpf_compile '(ip && (ip[54] & 0xf0) == 0x30) ||
418d014eaaSGeliang Tang#				  (ip6 && (ip6[74] & 0xf0) == 0x30)'"
428d014eaaSGeliang TangCBPF_MPTCP_SUBOPTION_ADD_ADDR="14,
438d014eaaSGeliang Tang			       48 0 0 0,
448d014eaaSGeliang Tang			       84 0 0 240,
458d014eaaSGeliang Tang			       21 0 3 64,
468d014eaaSGeliang Tang			       48 0 0 54,
478d014eaaSGeliang Tang			       84 0 0 240,
488d014eaaSGeliang Tang			       21 6 7 48,
498d014eaaSGeliang Tang			       48 0 0 0,
508d014eaaSGeliang Tang			       84 0 0 240,
518d014eaaSGeliang Tang			       21 0 4 96,
528d014eaaSGeliang Tang			       48 0 0 74,
538d014eaaSGeliang Tang			       84 0 0 240,
548d014eaaSGeliang Tang			       21 0 1 48,
558d014eaaSGeliang Tang			       6 0 0 65535,
568d014eaaSGeliang Tang			       6 0 0 0"
578d014eaaSGeliang Tang
5893827ad5SMatthieu Baertsinit_partial()
59b08fbf24SPaolo Abeni{
60b08fbf24SPaolo Abeni	capout=$(mktemp)
61b08fbf24SPaolo Abeni
621e777bd8SMatthieu Baerts	local rndh
630a40e273SMatthieu Baerts	rndh=$(mktemp -u XXXXXX)
64b08fbf24SPaolo Abeni
65b08fbf24SPaolo Abeni	ns1="ns1-$rndh"
66b08fbf24SPaolo Abeni	ns2="ns2-$rndh"
67b08fbf24SPaolo Abeni
681e777bd8SMatthieu Baerts	local netns
69b08fbf24SPaolo Abeni	for netns in "$ns1" "$ns2"; do
70b08fbf24SPaolo Abeni		ip netns add $netns || exit $ksft_skip
71b08fbf24SPaolo Abeni		ip -net $netns link set lo up
72b08fbf24SPaolo Abeni		ip netns exec $netns sysctl -q net.mptcp.enabled=1
73b08fbf24SPaolo Abeni		ip netns exec $netns sysctl -q net.ipv4.conf.all.rp_filter=0
74b08fbf24SPaolo Abeni		ip netns exec $netns sysctl -q net.ipv4.conf.default.rp_filter=0
75af66d3e1SGeliang Tang		if [ $checksum -eq 1 ]; then
76af66d3e1SGeliang Tang			ip netns exec $netns sysctl -q net.mptcp.checksum_enabled=1
77af66d3e1SGeliang Tang		fi
78b08fbf24SPaolo Abeni	done
79b08fbf24SPaolo Abeni
808117dac3SGeliang Tang	check_invert=0
813c082695SGeliang Tang	validate_checksum=$checksum
82e59300ceSMatthieu Baerts	FAILING_LINKS=""
838117dac3SGeliang Tang
84b08fbf24SPaolo Abeni	#  ns1         ns2
85b08fbf24SPaolo Abeni	# ns1eth1    ns2eth1
86b08fbf24SPaolo Abeni	# ns1eth2    ns2eth2
87b08fbf24SPaolo Abeni	# ns1eth3    ns2eth3
88b08fbf24SPaolo Abeni	# ns1eth4    ns2eth4
89b08fbf24SPaolo Abeni
901e777bd8SMatthieu Baerts	local i
914bfadd71SMatthieu Baerts	for i in $(seq 1 4); do
92b08fbf24SPaolo Abeni		ip link add ns1eth$i netns "$ns1" type veth peer name ns2eth$i netns "$ns2"
93b08fbf24SPaolo Abeni		ip -net "$ns1" addr add 10.0.$i.1/24 dev ns1eth$i
94b08fbf24SPaolo Abeni		ip -net "$ns1" addr add dead:beef:$i::1/64 dev ns1eth$i nodad
95b08fbf24SPaolo Abeni		ip -net "$ns1" link set ns1eth$i up
96b08fbf24SPaolo Abeni
97b08fbf24SPaolo Abeni		ip -net "$ns2" addr add 10.0.$i.2/24 dev ns2eth$i
98b08fbf24SPaolo Abeni		ip -net "$ns2" addr add dead:beef:$i::2/64 dev ns2eth$i nodad
99b08fbf24SPaolo Abeni		ip -net "$ns2" link set ns2eth$i up
100b08fbf24SPaolo Abeni
101b08fbf24SPaolo Abeni		# let $ns2 reach any $ns1 address from any interface
102b08fbf24SPaolo Abeni		ip -net "$ns2" route add default via 10.0.$i.1 dev ns2eth$i metric 10$i
1039846921dSPaolo Abeni		ip -net "$ns2" route add default via dead:beef:$i::1 dev ns2eth$i metric 10$i
104b08fbf24SPaolo Abeni	done
105b08fbf24SPaolo Abeni}
106b08fbf24SPaolo Abeni
1077d1e6f16SPaolo Abeniinit_shapers()
1087d1e6f16SPaolo Abeni{
1091e777bd8SMatthieu Baerts	local i
1104bfadd71SMatthieu Baerts	for i in $(seq 1 4); do
1117d1e6f16SPaolo Abeni		tc -n $ns1 qdisc add dev ns1eth$i root netem rate 20mbit delay 1
1127d1e6f16SPaolo Abeni		tc -n $ns2 qdisc add dev ns2eth$i root netem rate 20mbit delay 1
1137d1e6f16SPaolo Abeni	done
1147d1e6f16SPaolo Abeni}
1157d1e6f16SPaolo Abeni
116b08fbf24SPaolo Abenicleanup_partial()
117b08fbf24SPaolo Abeni{
118b08fbf24SPaolo Abeni	rm -f "$capout"
119b08fbf24SPaolo Abeni
1201e777bd8SMatthieu Baerts	local netns
121b08fbf24SPaolo Abeni	for netns in "$ns1" "$ns2"; do
122b08fbf24SPaolo Abeni		ip netns del $netns
123c2a55e8fSMatthieu Baerts		rm -f /tmp/$netns.{nstat,out}
124b08fbf24SPaolo Abeni	done
125b08fbf24SPaolo Abeni}
126b08fbf24SPaolo Abeni
12787154755SMatthieu Baertscheck_tools()
12887154755SMatthieu Baerts{
12987154755SMatthieu Baerts	if ! ip -Version &> /dev/null; then
13087154755SMatthieu Baerts		echo "SKIP: Could not run test without ip tool"
13187154755SMatthieu Baerts		exit $ksft_skip
13287154755SMatthieu Baerts	fi
13387154755SMatthieu Baerts
13487154755SMatthieu Baerts	if ! iptables -V &> /dev/null; then
13587154755SMatthieu Baerts		echo "SKIP: Could not run all tests without iptables tool"
13687154755SMatthieu Baerts		exit $ksft_skip
13787154755SMatthieu Baerts	fi
13887154755SMatthieu Baerts
13987154755SMatthieu Baerts	if ! ip6tables -V &> /dev/null; then
14087154755SMatthieu Baerts		echo "SKIP: Could not run all tests without ip6tables tool"
14187154755SMatthieu Baerts		exit $ksft_skip
14287154755SMatthieu Baerts	fi
14387154755SMatthieu Baerts}
14487154755SMatthieu Baerts
14593827ad5SMatthieu Baertsinit() {
14693827ad5SMatthieu Baerts	init=1
14793827ad5SMatthieu Baerts
14887154755SMatthieu Baerts	check_tools
14987154755SMatthieu Baerts
15093827ad5SMatthieu Baerts	sin=$(mktemp)
15193827ad5SMatthieu Baerts	sout=$(mktemp)
15293827ad5SMatthieu Baerts	cin=$(mktemp)
15393827ad5SMatthieu Baerts	cinsent=$(mktemp)
15493827ad5SMatthieu Baerts	cout=$(mktemp)
15593827ad5SMatthieu Baerts
15693827ad5SMatthieu Baerts	trap cleanup EXIT
15793827ad5SMatthieu Baerts
15893827ad5SMatthieu Baerts	make_file "$cin" "client" 1
15993827ad5SMatthieu Baerts	make_file "$sin" "server" 1
16093827ad5SMatthieu Baerts}
16193827ad5SMatthieu Baerts
162b08fbf24SPaolo Abenicleanup()
163b08fbf24SPaolo Abeni{
1647d1e6f16SPaolo Abeni	rm -f "$cin" "$cout" "$sinfail"
1657d1e6f16SPaolo Abeni	rm -f "$sin" "$sout" "$cinsent" "$cinfail"
166b08fbf24SPaolo Abeni	cleanup_partial
167b08fbf24SPaolo Abeni}
168b08fbf24SPaolo Abeni
169ae7bd9ccSMatthieu Baertsskip_test()
170ae7bd9ccSMatthieu Baerts{
171c7d49c03SMatthieu Baerts	if [ "${#only_tests_ids[@]}" -eq 0 ] && [ "${#only_tests_names[@]}" -eq 0 ]; then
172ae7bd9ccSMatthieu Baerts		return 1
173ae7bd9ccSMatthieu Baerts	fi
174ae7bd9ccSMatthieu Baerts
175ae7bd9ccSMatthieu Baerts	local i
176c7d49c03SMatthieu Baerts	for i in "${only_tests_ids[@]}"; do
177ae7bd9ccSMatthieu Baerts		if [ "${TEST_COUNT}" -eq "${i}" ]; then
178ae7bd9ccSMatthieu Baerts			return 1
179ae7bd9ccSMatthieu Baerts		fi
180ae7bd9ccSMatthieu Baerts	done
181c7d49c03SMatthieu Baerts	for i in "${only_tests_names[@]}"; do
182c7d49c03SMatthieu Baerts		if [ "${TEST_NAME}" = "${i}" ]; then
183c7d49c03SMatthieu Baerts			return 1
184c7d49c03SMatthieu Baerts		fi
185c7d49c03SMatthieu Baerts	done
186ae7bd9ccSMatthieu Baerts
187ae7bd9ccSMatthieu Baerts	return 0
188ae7bd9ccSMatthieu Baerts}
189ae7bd9ccSMatthieu Baerts
190c7d49c03SMatthieu Baerts# $1: test name
191b08fbf24SPaolo Abenireset()
192b08fbf24SPaolo Abeni{
193c7d49c03SMatthieu Baerts	TEST_NAME="${1}"
194c7d49c03SMatthieu Baerts
195ae7bd9ccSMatthieu Baerts	TEST_COUNT=$((TEST_COUNT+1))
196ae7bd9ccSMatthieu Baerts
197ae7bd9ccSMatthieu Baerts	if skip_test; then
198ae7bd9ccSMatthieu Baerts		return 1
199ae7bd9ccSMatthieu Baerts	fi
200ae7bd9ccSMatthieu Baerts
20193827ad5SMatthieu Baerts	if [ "${init}" != "1" ]; then
202b08fbf24SPaolo Abeni		init
20393827ad5SMatthieu Baerts	else
20493827ad5SMatthieu Baerts		cleanup_partial
20593827ad5SMatthieu Baerts	fi
20693827ad5SMatthieu Baerts
20793827ad5SMatthieu Baerts	init_partial
208ae7bd9ccSMatthieu Baerts
209ae7bd9ccSMatthieu Baerts	return 0
210b08fbf24SPaolo Abeni}
211b08fbf24SPaolo Abeni
212c7d49c03SMatthieu Baerts# $1: test name
21300587187SFlorian Westphalreset_with_cookies()
21400587187SFlorian Westphal{
215c7d49c03SMatthieu Baerts	reset "${1}" || return 1
21600587187SFlorian Westphal
2171e777bd8SMatthieu Baerts	local netns
21800587187SFlorian Westphal	for netns in "$ns1" "$ns2"; do
21900587187SFlorian Westphal		ip netns exec $netns sysctl -q net.ipv4.tcp_syncookies=2
22000587187SFlorian Westphal	done
22100587187SFlorian Westphal}
22200587187SFlorian Westphal
223c7d49c03SMatthieu Baerts# $1: test name
2248d014eaaSGeliang Tangreset_with_add_addr_timeout()
2258d014eaaSGeliang Tang{
226c7d49c03SMatthieu Baerts	local ip="${2:-4}"
2278d014eaaSGeliang Tang	local tables
2288d014eaaSGeliang Tang
229c7d49c03SMatthieu Baerts	reset "${1}" || return 1
230c7d49c03SMatthieu Baerts
2318d014eaaSGeliang Tang	tables="iptables"
2328d014eaaSGeliang Tang	if [ $ip -eq 6 ]; then
2338d014eaaSGeliang Tang		tables="ip6tables"
2348d014eaaSGeliang Tang	fi
2358d014eaaSGeliang Tang
2368d014eaaSGeliang Tang	ip netns exec $ns1 sysctl -q net.mptcp.add_addr_timeout=1
2378d014eaaSGeliang Tang	ip netns exec $ns2 $tables -A OUTPUT -p tcp \
2388d014eaaSGeliang Tang		-m tcp --tcp-option 30 \
2398d014eaaSGeliang Tang		-m bpf --bytecode \
2408d014eaaSGeliang Tang		"$CBPF_MPTCP_SUBOPTION_ADD_ADDR" \
2418d014eaaSGeliang Tang		-j DROP
2428d014eaaSGeliang Tang}
2438d014eaaSGeliang Tang
244c7d49c03SMatthieu Baerts# $1: test name
245af66d3e1SGeliang Tangreset_with_checksum()
246af66d3e1SGeliang Tang{
247af66d3e1SGeliang Tang	local ns1_enable=$1
248af66d3e1SGeliang Tang	local ns2_enable=$2
249af66d3e1SGeliang Tang
250c7d49c03SMatthieu Baerts	reset "checksum test ${1} ${2}" || return 1
251af66d3e1SGeliang Tang
252af66d3e1SGeliang Tang	ip netns exec $ns1 sysctl -q net.mptcp.checksum_enabled=$ns1_enable
253af66d3e1SGeliang Tang	ip netns exec $ns2 sysctl -q net.mptcp.checksum_enabled=$ns2_enable
2543c082695SGeliang Tang
2553c082695SGeliang Tang	validate_checksum=1
256af66d3e1SGeliang Tang}
257af66d3e1SGeliang Tang
2580cddb4a6SGeliang Tangreset_with_allow_join_id0()
2590cddb4a6SGeliang Tang{
260c7d49c03SMatthieu Baerts	local ns1_enable=$2
261c7d49c03SMatthieu Baerts	local ns2_enable=$3
2620cddb4a6SGeliang Tang
263c7d49c03SMatthieu Baerts	reset "${1}" || return 1
2640cddb4a6SGeliang Tang
2650cddb4a6SGeliang Tang	ip netns exec $ns1 sysctl -q net.mptcp.allow_join_initial_addr_port=$ns1_enable
2660cddb4a6SGeliang Tang	ip netns exec $ns2 sysctl -q net.mptcp.allow_join_initial_addr_port=$ns2_enable
2670cddb4a6SGeliang Tang}
2680cddb4a6SGeliang Tang
269*b6e074e1SGeliang Tang# Modify TCP payload without corrupting the TCP packet
270*b6e074e1SGeliang Tang#
271*b6e074e1SGeliang Tang# This rule inverts a 8-bit word at byte offset 148 for the 2nd TCP ACK packets
272*b6e074e1SGeliang Tang# carrying enough data.
273*b6e074e1SGeliang Tang# Once it is done, the TCP Checksum field is updated so the packet is still
274*b6e074e1SGeliang Tang# considered as valid at the TCP level.
275*b6e074e1SGeliang Tang# Because the MPTCP checksum, covering the TCP options and data, has not been
276*b6e074e1SGeliang Tang# updated, the modification will be detected and an MP_FAIL will be emitted:
277*b6e074e1SGeliang Tang# what we want to validate here without corrupting "random" MPTCP options.
278*b6e074e1SGeliang Tang#
279*b6e074e1SGeliang Tang# To avoid having tc producing this pr_info() message for each TCP ACK packets
280*b6e074e1SGeliang Tang# not carrying enough data:
281*b6e074e1SGeliang Tang#
282*b6e074e1SGeliang Tang#     tc action pedit offset 162 out of bounds
283*b6e074e1SGeliang Tang#
284*b6e074e1SGeliang Tang# Netfilter is used to mark packets with enough data.
285*b6e074e1SGeliang Tangreset_with_fail()
286*b6e074e1SGeliang Tang{
287*b6e074e1SGeliang Tang	reset "${1}" || return 1
288*b6e074e1SGeliang Tang
289*b6e074e1SGeliang Tang	ip netns exec $ns1 sysctl -q net.mptcp.checksum_enabled=1
290*b6e074e1SGeliang Tang	ip netns exec $ns2 sysctl -q net.mptcp.checksum_enabled=1
291*b6e074e1SGeliang Tang
292*b6e074e1SGeliang Tang	check_invert=1
293*b6e074e1SGeliang Tang	validate_checksum=1
294*b6e074e1SGeliang Tang	local i="$2"
295*b6e074e1SGeliang Tang	local ip="${3:-4}"
296*b6e074e1SGeliang Tang	local tables
297*b6e074e1SGeliang Tang
298*b6e074e1SGeliang Tang	tables="iptables"
299*b6e074e1SGeliang Tang	if [ $ip -eq 6 ]; then
300*b6e074e1SGeliang Tang		tables="ip6tables"
301*b6e074e1SGeliang Tang	fi
302*b6e074e1SGeliang Tang
303*b6e074e1SGeliang Tang	ip netns exec $ns2 $tables \
304*b6e074e1SGeliang Tang		-t mangle \
305*b6e074e1SGeliang Tang		-A OUTPUT \
306*b6e074e1SGeliang Tang		-o ns2eth$i \
307*b6e074e1SGeliang Tang		-p tcp \
308*b6e074e1SGeliang Tang		-m length --length 150:9999 \
309*b6e074e1SGeliang Tang		-m statistic --mode nth --packet 1 --every 99999 \
310*b6e074e1SGeliang Tang		-j MARK --set-mark 42 || exit 1
311*b6e074e1SGeliang Tang
312*b6e074e1SGeliang Tang	tc -n $ns2 qdisc add dev ns2eth$i clsact || exit 1
313*b6e074e1SGeliang Tang	tc -n $ns2 filter add dev ns2eth$i egress \
314*b6e074e1SGeliang Tang		protocol ip prio 1000 \
315*b6e074e1SGeliang Tang		handle 42 fw \
316*b6e074e1SGeliang Tang		action pedit munge offset 148 u8 invert \
317*b6e074e1SGeliang Tang		pipe csum tcp \
318*b6e074e1SGeliang Tang		index 100 || exit 1
319*b6e074e1SGeliang Tang}
320*b6e074e1SGeliang Tang
32139aab882SMatthieu Baertsfail_test()
32239aab882SMatthieu Baerts{
32339aab882SMatthieu Baerts	ret=1
32439aab882SMatthieu Baerts	failed_tests[${TEST_COUNT}]="${TEST_NAME}"
32539aab882SMatthieu Baerts}
32639aab882SMatthieu Baerts
32739aab882SMatthieu Baertsget_failed_tests_ids()
32839aab882SMatthieu Baerts{
32939aab882SMatthieu Baerts	# sorted
33039aab882SMatthieu Baerts	local i
33139aab882SMatthieu Baerts	for i in "${!failed_tests[@]}"; do
33239aab882SMatthieu Baerts		echo "${i}"
33339aab882SMatthieu Baerts	done | sort -n
33439aab882SMatthieu Baerts}
33539aab882SMatthieu Baerts
3368b819a84SFlorian Westphalprint_file_err()
3378b819a84SFlorian Westphal{
3388b819a84SFlorian Westphal	ls -l "$1" 1>&2
3398b819a84SFlorian Westphal	echo "Trailing bytes are: "
3408b819a84SFlorian Westphal	tail -c 27 "$1"
3418b819a84SFlorian Westphal}
3428b819a84SFlorian Westphal
343b08fbf24SPaolo Abenicheck_transfer()
344b08fbf24SPaolo Abeni{
3451e777bd8SMatthieu Baerts	local in=$1
3461e777bd8SMatthieu Baerts	local out=$2
3471e777bd8SMatthieu Baerts	local what=$3
348d8d08302SMatthieu Baerts	local i a b
349b08fbf24SPaolo Abeni
3501e777bd8SMatthieu Baerts	local line
351d8d08302SMatthieu Baerts	cmp -l "$in" "$out" | while read -r i a b; do
352d8d08302SMatthieu Baerts		local sum=$((0${a} + 0${b}))
3538117dac3SGeliang Tang		if [ $check_invert -eq 0 ] || [ $sum -ne $((0xff)) ]; then
354b08fbf24SPaolo Abeni			echo "[ FAIL ] $what does not match (in, out):"
355b08fbf24SPaolo Abeni			print_file_err "$in"
356b08fbf24SPaolo Abeni			print_file_err "$out"
35739aab882SMatthieu Baerts			fail_test
358b08fbf24SPaolo Abeni
359b08fbf24SPaolo Abeni			return 1
3608117dac3SGeliang Tang		else
361d8d08302SMatthieu Baerts			echo "$what has inverted byte at ${i}"
362b08fbf24SPaolo Abeni		fi
3638117dac3SGeliang Tang	done
364b08fbf24SPaolo Abeni
365b08fbf24SPaolo Abeni	return 0
366b08fbf24SPaolo Abeni}
367b08fbf24SPaolo Abeni
368b08fbf24SPaolo Abenido_ping()
369b08fbf24SPaolo Abeni{
3701e777bd8SMatthieu Baerts	local listener_ns="$1"
3711e777bd8SMatthieu Baerts	local connector_ns="$2"
3721e777bd8SMatthieu Baerts	local connect_addr="$3"
373b08fbf24SPaolo Abeni
374d8d08302SMatthieu Baerts	if ! ip netns exec ${connector_ns} ping -q -c 1 $connect_addr >/dev/null; then
375b08fbf24SPaolo Abeni		echo "$listener_ns -> $connect_addr connectivity [ FAIL ]" 1>&2
37639aab882SMatthieu Baerts		fail_test
377b08fbf24SPaolo Abeni	fi
378b08fbf24SPaolo Abeni}
379b08fbf24SPaolo Abeni
3808b819a84SFlorian Westphallink_failure()
3818b819a84SFlorian Westphal{
3821e777bd8SMatthieu Baerts	local ns="$1"
3838b819a84SFlorian Westphal
3847d1e6f16SPaolo Abeni	if [ -z "$FAILING_LINKS" ]; then
3858b819a84SFlorian Westphal		l=$((RANDOM%4))
3867d1e6f16SPaolo Abeni		FAILING_LINKS=$((l+1))
3877d1e6f16SPaolo Abeni	fi
3888b819a84SFlorian Westphal
3891e777bd8SMatthieu Baerts	local l
3907d1e6f16SPaolo Abeni	for l in $FAILING_LINKS; do
3911e777bd8SMatthieu Baerts		local veth="ns1eth$l"
3928b819a84SFlorian Westphal		ip -net "$ns" link set "$veth" down
3937d1e6f16SPaolo Abeni	done
3948b819a84SFlorian Westphal}
3958b819a84SFlorian Westphal
396523514edSGeliang Tang# $1: IP address
397523514edSGeliang Tangis_v6()
398523514edSGeliang Tang{
399523514edSGeliang Tang	[ -z "${1##*:*}" ]
400523514edSGeliang Tang}
401523514edSGeliang Tang
402327b9a94SPaolo Abeni# $1: ns, $2: port
403327b9a94SPaolo Abeniwait_local_port_listen()
404327b9a94SPaolo Abeni{
405327b9a94SPaolo Abeni	local listener_ns="${1}"
406327b9a94SPaolo Abeni	local port="${2}"
407327b9a94SPaolo Abeni
4081e777bd8SMatthieu Baerts	local port_hex
409327b9a94SPaolo Abeni	port_hex="$(printf "%04X" "${port}")"
4101e777bd8SMatthieu Baerts
4111e777bd8SMatthieu Baerts	local i
412327b9a94SPaolo Abeni	for i in $(seq 10); do
413327b9a94SPaolo Abeni		ip netns exec "${listener_ns}" cat /proc/net/tcp* | \
414327b9a94SPaolo Abeni			awk "BEGIN {rc=1} {if (\$2 ~ /:${port_hex}\$/ && \$4 ~ /0A/) {rc=0; exit}} END {exit rc}" &&
415327b9a94SPaolo Abeni			break
416327b9a94SPaolo Abeni		sleep 0.1
417327b9a94SPaolo Abeni	done
418327b9a94SPaolo Abeni}
419327b9a94SPaolo Abeni
420327b9a94SPaolo Abenirm_addr_count()
421327b9a94SPaolo Abeni{
4221e777bd8SMatthieu Baerts	local ns=${1}
423327b9a94SPaolo Abeni
424327b9a94SPaolo Abeni	ip netns exec ${ns} nstat -as | grep MPTcpExtRmAddr | awk '{print $2}'
425327b9a94SPaolo Abeni}
426327b9a94SPaolo Abeni
427327b9a94SPaolo Abeni# $1: ns, $2: old rm_addr counter in $ns
428327b9a94SPaolo Abeniwait_rm_addr()
429327b9a94SPaolo Abeni{
430327b9a94SPaolo Abeni	local ns="${1}"
431327b9a94SPaolo Abeni	local old_cnt="${2}"
432327b9a94SPaolo Abeni	local cnt
433327b9a94SPaolo Abeni
4341e777bd8SMatthieu Baerts	local i
435327b9a94SPaolo Abeni	for i in $(seq 10); do
436327b9a94SPaolo Abeni		cnt=$(rm_addr_count ${ns})
437327b9a94SPaolo Abeni		[ "$cnt" = "${old_cnt}" ] || break
438327b9a94SPaolo Abeni		sleep 0.1
439327b9a94SPaolo Abeni	done
440327b9a94SPaolo Abeni}
441327b9a94SPaolo Abeni
44269c6ce7bSPaolo Abeniwait_mpj()
44369c6ce7bSPaolo Abeni{
44469c6ce7bSPaolo Abeni	local ns="${1}"
44569c6ce7bSPaolo Abeni	local cnt old_cnt
44669c6ce7bSPaolo Abeni
44769c6ce7bSPaolo Abeni	old_cnt=$(ip netns exec ${ns} nstat -as | grep MPJoinAckRx | awk '{print $2}')
44869c6ce7bSPaolo Abeni
44969c6ce7bSPaolo Abeni	local i
45069c6ce7bSPaolo Abeni	for i in $(seq 10); do
45169c6ce7bSPaolo Abeni		cnt=$(ip netns exec ${ns} nstat -as | grep MPJoinAckRx | awk '{print $2}')
45269c6ce7bSPaolo Abeni		[ "$cnt" = "${old_cnt}" ] || break
45369c6ce7bSPaolo Abeni		sleep 0.1
45469c6ce7bSPaolo Abeni	done
45569c6ce7bSPaolo Abeni}
45669c6ce7bSPaolo Abeni
45734aa6e3bSGeliang Tangpm_nl_set_limits()
45834aa6e3bSGeliang Tang{
45934aa6e3bSGeliang Tang	local ns=$1
46034aa6e3bSGeliang Tang	local addrs=$2
46134aa6e3bSGeliang Tang	local subflows=$3
46234aa6e3bSGeliang Tang
46334aa6e3bSGeliang Tang	if [ $ip_mptcp -eq 1 ]; then
46434aa6e3bSGeliang Tang		ip -n $ns mptcp limits set add_addr_accepted $addrs subflows $subflows
46534aa6e3bSGeliang Tang	else
46634aa6e3bSGeliang Tang		ip netns exec $ns ./pm_nl_ctl limits $addrs $subflows
46734aa6e3bSGeliang Tang	fi
46834aa6e3bSGeliang Tang}
46934aa6e3bSGeliang Tang
47034aa6e3bSGeliang Tangpm_nl_add_endpoint()
47134aa6e3bSGeliang Tang{
47234aa6e3bSGeliang Tang	local ns=$1
47334aa6e3bSGeliang Tang	local addr=$2
4741e777bd8SMatthieu Baerts	local flags _flags
4751e777bd8SMatthieu Baerts	local port _port
4761e777bd8SMatthieu Baerts	local dev _dev
4771e777bd8SMatthieu Baerts	local id _id
47834aa6e3bSGeliang Tang	local nr=2
47934aa6e3bSGeliang Tang
4801e777bd8SMatthieu Baerts	local p
481d8d08302SMatthieu Baerts	for p in "${@}"
48234aa6e3bSGeliang Tang	do
48334aa6e3bSGeliang Tang		if [ $p = "flags" ]; then
48434aa6e3bSGeliang Tang			eval _flags=\$"$nr"
485d8d08302SMatthieu Baerts			[ -n "$_flags" ]; flags="flags $_flags"
48634aa6e3bSGeliang Tang		fi
48734aa6e3bSGeliang Tang		if [ $p = "dev" ]; then
48834aa6e3bSGeliang Tang			eval _dev=\$"$nr"
489d8d08302SMatthieu Baerts			[ -n "$_dev" ]; dev="dev $_dev"
49034aa6e3bSGeliang Tang		fi
49134aa6e3bSGeliang Tang		if [ $p = "id" ]; then
49234aa6e3bSGeliang Tang			eval _id=\$"$nr"
493d8d08302SMatthieu Baerts			[ -n "$_id" ]; id="id $_id"
49434aa6e3bSGeliang Tang		fi
49534aa6e3bSGeliang Tang		if [ $p = "port" ]; then
49634aa6e3bSGeliang Tang			eval _port=\$"$nr"
497d8d08302SMatthieu Baerts			[ -n "$_port" ]; port="port $_port"
49834aa6e3bSGeliang Tang		fi
49934aa6e3bSGeliang Tang
500d8d08302SMatthieu Baerts		nr=$((nr + 1))
50134aa6e3bSGeliang Tang	done
50234aa6e3bSGeliang Tang
50334aa6e3bSGeliang Tang	if [ $ip_mptcp -eq 1 ]; then
50434aa6e3bSGeliang Tang		ip -n $ns mptcp endpoint add $addr ${_flags//","/" "} $dev $id $port
50534aa6e3bSGeliang Tang	else
50634aa6e3bSGeliang Tang		ip netns exec $ns ./pm_nl_ctl add $addr $flags $dev $id $port
50734aa6e3bSGeliang Tang	fi
50834aa6e3bSGeliang Tang}
50934aa6e3bSGeliang Tang
51034aa6e3bSGeliang Tangpm_nl_del_endpoint()
51134aa6e3bSGeliang Tang{
51234aa6e3bSGeliang Tang	local ns=$1
51334aa6e3bSGeliang Tang	local id=$2
51434aa6e3bSGeliang Tang	local addr=$3
51534aa6e3bSGeliang Tang
51634aa6e3bSGeliang Tang	if [ $ip_mptcp -eq 1 ]; then
51734aa6e3bSGeliang Tang		ip -n $ns mptcp endpoint delete id $id $addr
51834aa6e3bSGeliang Tang	else
51934aa6e3bSGeliang Tang		ip netns exec $ns ./pm_nl_ctl del $id $addr
52034aa6e3bSGeliang Tang	fi
52134aa6e3bSGeliang Tang}
52234aa6e3bSGeliang Tang
52334aa6e3bSGeliang Tangpm_nl_flush_endpoint()
52434aa6e3bSGeliang Tang{
52534aa6e3bSGeliang Tang	local ns=$1
52634aa6e3bSGeliang Tang
52734aa6e3bSGeliang Tang	if [ $ip_mptcp -eq 1 ]; then
52834aa6e3bSGeliang Tang		ip -n $ns mptcp endpoint flush
52934aa6e3bSGeliang Tang	else
53034aa6e3bSGeliang Tang		ip netns exec $ns ./pm_nl_ctl flush
53134aa6e3bSGeliang Tang	fi
53234aa6e3bSGeliang Tang}
53334aa6e3bSGeliang Tang
534dda61b3dSGeliang Tangpm_nl_show_endpoints()
535dda61b3dSGeliang Tang{
536dda61b3dSGeliang Tang	local ns=$1
537dda61b3dSGeliang Tang
538dda61b3dSGeliang Tang	if [ $ip_mptcp -eq 1 ]; then
539dda61b3dSGeliang Tang		ip -n $ns mptcp endpoint show
540dda61b3dSGeliang Tang	else
541dda61b3dSGeliang Tang		ip netns exec $ns ./pm_nl_ctl dump
542dda61b3dSGeliang Tang	fi
543dda61b3dSGeliang Tang}
544dda61b3dSGeliang Tang
545f0140386SGeliang Tangpm_nl_change_endpoint()
546f0140386SGeliang Tang{
547f0140386SGeliang Tang	local ns=$1
548bccefb76SGeliang Tang	local id=$2
549bccefb76SGeliang Tang	local flags=$3
550f0140386SGeliang Tang
551f0140386SGeliang Tang	if [ $ip_mptcp -eq 1 ]; then
552f0140386SGeliang Tang		ip -n $ns mptcp endpoint change id $id ${flags//","/" "}
553f0140386SGeliang Tang	else
554bccefb76SGeliang Tang		ip netns exec $ns ./pm_nl_ctl set id $id flags $flags
555f0140386SGeliang Tang	fi
556f0140386SGeliang Tang}
557f0140386SGeliang Tang
55869c6ce7bSPaolo Abenipm_nl_check_endpoint()
55969c6ce7bSPaolo Abeni{
56069c6ce7bSPaolo Abeni	local line expected_line
561c7d49c03SMatthieu Baerts	local need_title=$1
56269c6ce7bSPaolo Abeni	local msg="$2"
56369c6ce7bSPaolo Abeni	local ns=$3
56469c6ce7bSPaolo Abeni	local addr=$4
56569c6ce7bSPaolo Abeni	local _flags=""
56669c6ce7bSPaolo Abeni	local flags
56769c6ce7bSPaolo Abeni	local _port
56869c6ce7bSPaolo Abeni	local port
56969c6ce7bSPaolo Abeni	local dev
57069c6ce7bSPaolo Abeni	local _id
57169c6ce7bSPaolo Abeni	local id
57269c6ce7bSPaolo Abeni
573c7d49c03SMatthieu Baerts	if [ "${need_title}" = 1 ]; then
574c7d49c03SMatthieu Baerts		printf "%03u %-36s %s" "${TEST_COUNT}" "${TEST_NAME}" "${msg}"
57569c6ce7bSPaolo Abeni	else
57669c6ce7bSPaolo Abeni		printf "%-${nr_blank}s %s" " " "${msg}"
57769c6ce7bSPaolo Abeni	fi
57869c6ce7bSPaolo Abeni
57969c6ce7bSPaolo Abeni	shift 4
58069c6ce7bSPaolo Abeni	while [ -n "$1" ]; do
58169c6ce7bSPaolo Abeni		if [ $1 = "flags" ]; then
58269c6ce7bSPaolo Abeni			_flags=$2
583d8d08302SMatthieu Baerts			[ -n "$_flags" ]; flags="flags $_flags"
58469c6ce7bSPaolo Abeni			shift
58569c6ce7bSPaolo Abeni		elif [ $1 = "dev" ]; then
586d8d08302SMatthieu Baerts			[ -n "$2" ]; dev="dev $1"
58769c6ce7bSPaolo Abeni			shift
58869c6ce7bSPaolo Abeni		elif [ $1 = "id" ]; then
58969c6ce7bSPaolo Abeni			_id=$2
590d8d08302SMatthieu Baerts			[ -n "$_id" ]; id="id $_id"
59169c6ce7bSPaolo Abeni			shift
59269c6ce7bSPaolo Abeni		elif [ $1 = "port" ]; then
59369c6ce7bSPaolo Abeni			_port=$2
594d8d08302SMatthieu Baerts			[ -n "$_port" ]; port=" port $_port"
59569c6ce7bSPaolo Abeni			shift
59669c6ce7bSPaolo Abeni		fi
59769c6ce7bSPaolo Abeni
59869c6ce7bSPaolo Abeni		shift
59969c6ce7bSPaolo Abeni	done
60069c6ce7bSPaolo Abeni
60169c6ce7bSPaolo Abeni	if [ -z "$id" ]; then
60269c6ce7bSPaolo Abeni		echo "[skip] bad test - missing endpoint id"
60369c6ce7bSPaolo Abeni		return
60469c6ce7bSPaolo Abeni	fi
60569c6ce7bSPaolo Abeni
60669c6ce7bSPaolo Abeni	if [ $ip_mptcp -eq 1 ]; then
60769c6ce7bSPaolo Abeni		line=$(ip -n $ns mptcp endpoint show $id)
60869c6ce7bSPaolo Abeni		# the dump order is: address id flags port dev
60969c6ce7bSPaolo Abeni		expected_line="$addr"
61069c6ce7bSPaolo Abeni		[ -n "$addr" ] && expected_line="$expected_line $addr"
61169c6ce7bSPaolo Abeni		expected_line="$expected_line $id"
61269c6ce7bSPaolo Abeni		[ -n "$_flags" ] && expected_line="$expected_line ${_flags//","/" "}"
61369c6ce7bSPaolo Abeni		[ -n "$dev" ] && expected_line="$expected_line $dev"
61469c6ce7bSPaolo Abeni		[ -n "$port" ] && expected_line="$expected_line $port"
61569c6ce7bSPaolo Abeni	else
61669c6ce7bSPaolo Abeni		line=$(ip netns exec $ns ./pm_nl_ctl get $_id)
61769c6ce7bSPaolo Abeni		# the dump order is: id flags dev address port
61869c6ce7bSPaolo Abeni		expected_line="$id"
61969c6ce7bSPaolo Abeni		[ -n "$flags" ] && expected_line="$expected_line $flags"
62069c6ce7bSPaolo Abeni		[ -n "$dev" ] && expected_line="$expected_line $dev"
62169c6ce7bSPaolo Abeni		[ -n "$addr" ] && expected_line="$expected_line $addr"
62269c6ce7bSPaolo Abeni		[ -n "$_port" ] && expected_line="$expected_line $_port"
62369c6ce7bSPaolo Abeni	fi
62469c6ce7bSPaolo Abeni	if [ "$line" = "$expected_line" ]; then
62569c6ce7bSPaolo Abeni		echo "[ ok ]"
62669c6ce7bSPaolo Abeni	else
62769c6ce7bSPaolo Abeni		echo "[fail] expected '$expected_line' found '$line'"
62839aab882SMatthieu Baerts		fail_test
62969c6ce7bSPaolo Abeni	fi
63069c6ce7bSPaolo Abeni}
63169c6ce7bSPaolo Abeni
6323469d72fSMatthieu Baertsfilter_tcp_from()
6333469d72fSMatthieu Baerts{
6343469d72fSMatthieu Baerts	local ns="${1}"
6353469d72fSMatthieu Baerts	local src="${2}"
6363469d72fSMatthieu Baerts	local target="${3}"
6373469d72fSMatthieu Baerts
6383469d72fSMatthieu Baerts	ip netns exec "${ns}" iptables -A INPUT -s "${src}" -p tcp -j "${target}"
6393469d72fSMatthieu Baerts}
6403469d72fSMatthieu Baerts
641b08fbf24SPaolo Abenido_transfer()
642b08fbf24SPaolo Abeni{
6431e777bd8SMatthieu Baerts	local listener_ns="$1"
6441e777bd8SMatthieu Baerts	local connector_ns="$2"
6451e777bd8SMatthieu Baerts	local cl_proto="$3"
6461e777bd8SMatthieu Baerts	local srv_proto="$4"
6471e777bd8SMatthieu Baerts	local connect_addr="$5"
6481e777bd8SMatthieu Baerts	local test_link_fail="$6"
6491e777bd8SMatthieu Baerts	local addr_nr_ns1="$7"
6501e777bd8SMatthieu Baerts	local addr_nr_ns2="$8"
6511e777bd8SMatthieu Baerts	local speed="$9"
6521e777bd8SMatthieu Baerts	local sflags="${10}"
653b08fbf24SPaolo Abeni
6541e777bd8SMatthieu Baerts	local port=$((10000 + TEST_COUNT - 1))
6551e777bd8SMatthieu Baerts	local cappid
656b08fbf24SPaolo Abeni
657b08fbf24SPaolo Abeni	:> "$cout"
658b08fbf24SPaolo Abeni	:> "$sout"
659b08fbf24SPaolo Abeni	:> "$capout"
660b08fbf24SPaolo Abeni
661b08fbf24SPaolo Abeni	if [ $capture -eq 1 ]; then
6621e777bd8SMatthieu Baerts		local capuser
663b08fbf24SPaolo Abeni		if [ -z $SUDO_USER ] ; then
664b08fbf24SPaolo Abeni			capuser=""
665b08fbf24SPaolo Abeni		else
666b08fbf24SPaolo Abeni			capuser="-Z $SUDO_USER"
667b08fbf24SPaolo Abeni		fi
668b08fbf24SPaolo Abeni
66900587187SFlorian Westphal		capfile=$(printf "mp_join-%02u-%s.pcap" "$TEST_COUNT" "${listener_ns}")
670b08fbf24SPaolo Abeni
671b08fbf24SPaolo Abeni		echo "Capturing traffic for test $TEST_COUNT into $capfile"
672b08fbf24SPaolo Abeni		ip netns exec ${listener_ns} tcpdump -i any -s 65535 -B 32768 $capuser -w $capfile > "$capout" 2>&1 &
673b08fbf24SPaolo Abeni		cappid=$!
674b08fbf24SPaolo Abeni
675b08fbf24SPaolo Abeni		sleep 1
676b08fbf24SPaolo Abeni	fi
677b08fbf24SPaolo Abeni
678c2a55e8fSMatthieu Baerts	NSTAT_HISTORY=/tmp/${listener_ns}.nstat ip netns exec ${listener_ns} \
679c2a55e8fSMatthieu Baerts		nstat -n
680c2a55e8fSMatthieu Baerts	NSTAT_HISTORY=/tmp/${connector_ns}.nstat ip netns exec ${connector_ns} \
681c2a55e8fSMatthieu Baerts		nstat -n
682c2a55e8fSMatthieu Baerts
683cbfafac4SGeliang Tang	local extra_args
6848d014eaaSGeliang Tang	if [ $speed = "fast" ]; then
685cbfafac4SGeliang Tang		extra_args="-j"
6868da6229bSGeliang Tang	elif [ $speed = "slow" ]; then
687cbfafac4SGeliang Tang		extra_args="-r 50"
688cbfafac4SGeliang Tang	elif [[ $speed = "speed_"* ]]; then
689cbfafac4SGeliang Tang		extra_args="-r ${speed:6}"
690dd72b0feSGeliang Tang	fi
691dd72b0feSGeliang Tang
69201542c9bSGeliang Tang	if [[ "${addr_nr_ns2}" = "fastclose_"* ]]; then
69301542c9bSGeliang Tang		# disconnect
69401542c9bSGeliang Tang		extra_args="$extra_args -I ${addr_nr_ns2:10}"
69501542c9bSGeliang Tang		addr_nr_ns2=0
69601542c9bSGeliang Tang	fi
69701542c9bSGeliang Tang
698523514edSGeliang Tang	local local_addr
699523514edSGeliang Tang	if is_v6 "${connect_addr}"; then
700523514edSGeliang Tang		local_addr="::"
701523514edSGeliang Tang	else
702523514edSGeliang Tang		local_addr="0.0.0.0"
703523514edSGeliang Tang	fi
704523514edSGeliang Tang
70534b572b7SGeliang Tang	if [ "$test_link_fail" -gt 1 ];then
7067d1e6f16SPaolo Abeni		timeout ${timeout_test} \
7077d1e6f16SPaolo Abeni			ip netns exec ${listener_ns} \
708cbfafac4SGeliang Tang				./mptcp_connect -t ${timeout_poll} -l -p $port -s ${srv_proto} \
709cbfafac4SGeliang Tang					$extra_args ${local_addr} < "$sinfail" > "$sout" &
7107d1e6f16SPaolo Abeni	else
7115888a61cSMatthieu Baerts		timeout ${timeout_test} \
7125888a61cSMatthieu Baerts			ip netns exec ${listener_ns} \
713cbfafac4SGeliang Tang				./mptcp_connect -t ${timeout_poll} -l -p $port -s ${srv_proto} \
714cbfafac4SGeliang Tang					$extra_args ${local_addr} < "$sin" > "$sout" &
7157d1e6f16SPaolo Abeni	fi
7161e777bd8SMatthieu Baerts	local spid=$!
717b08fbf24SPaolo Abeni
718327b9a94SPaolo Abeni	wait_local_port_listen "${listener_ns}" "${port}"
719b08fbf24SPaolo Abeni
7208b819a84SFlorian Westphal	if [ "$test_link_fail" -eq 0 ];then
7215888a61cSMatthieu Baerts		timeout ${timeout_test} \
7225888a61cSMatthieu Baerts			ip netns exec ${connector_ns} \
723cbfafac4SGeliang Tang				./mptcp_connect -t ${timeout_poll} -p $port -s ${cl_proto} \
724cbfafac4SGeliang Tang					$extra_args $connect_addr < "$cin" > "$cout" &
72534b572b7SGeliang Tang	elif [ "$test_link_fail" -eq 1 ] || [ "$test_link_fail" -eq 2 ];then
7267d1e6f16SPaolo Abeni		( cat "$cinfail" ; sleep 2; link_failure $listener_ns ; cat "$cinfail" ) | \
7275888a61cSMatthieu Baerts			tee "$cinsent" | \
7285888a61cSMatthieu Baerts			timeout ${timeout_test} \
7295888a61cSMatthieu Baerts				ip netns exec ${connector_ns} \
730cbfafac4SGeliang Tang					./mptcp_connect -t ${timeout_poll} -p $port -s ${cl_proto} \
731cbfafac4SGeliang Tang						$extra_args $connect_addr > "$cout" &
73234b572b7SGeliang Tang	else
733d8d08302SMatthieu Baerts		tee "$cinsent" < "$cinfail" | \
73434b572b7SGeliang Tang			timeout ${timeout_test} \
73534b572b7SGeliang Tang				ip netns exec ${connector_ns} \
73634b572b7SGeliang Tang					./mptcp_connect -t ${timeout_poll} -p $port -s ${cl_proto} \
73734b572b7SGeliang Tang						$extra_args $connect_addr > "$cout" &
7388b819a84SFlorian Westphal	fi
7391e777bd8SMatthieu Baerts	local cpid=$!
740b08fbf24SPaolo Abeni
741327b9a94SPaolo Abeni	# let the mptcp subflow be established in background before
742327b9a94SPaolo Abeni	# do endpoint manipulation
743d8d08302SMatthieu Baerts	if [ $addr_nr_ns1 != "0" ] || [ $addr_nr_ns2 != "0" ]; then
744d8d08302SMatthieu Baerts		sleep 1
745d8d08302SMatthieu Baerts	fi
746327b9a94SPaolo Abeni
7476208fd82SGeliang Tang	if [ $addr_nr_ns1 -gt 0 ]; then
7481e777bd8SMatthieu Baerts		local counter=2
749d8d08302SMatthieu Baerts		local add_nr_ns1=${addr_nr_ns1}
7506208fd82SGeliang Tang		while [ $add_nr_ns1 -gt 0 ]; do
7516208fd82SGeliang Tang			local addr
7526208fd82SGeliang Tang			if is_v6 "${connect_addr}"; then
7536208fd82SGeliang Tang				addr="dead:beef:$counter::1"
7546208fd82SGeliang Tang			else
7556208fd82SGeliang Tang				addr="10.0.$counter.1"
7566208fd82SGeliang Tang			fi
75734aa6e3bSGeliang Tang			pm_nl_add_endpoint $ns1 $addr flags signal
758d8d08302SMatthieu Baerts			counter=$((counter + 1))
759d8d08302SMatthieu Baerts			add_nr_ns1=$((add_nr_ns1 - 1))
7606208fd82SGeliang Tang		done
7616208fd82SGeliang Tang	elif [ $addr_nr_ns1 -lt 0 ]; then
762d8d08302SMatthieu Baerts		local rm_nr_ns1=$((-addr_nr_ns1))
7636fe4ccdcSGeliang Tang		if [ $rm_nr_ns1 -lt 8 ]; then
7641e777bd8SMatthieu Baerts			local counter=0
7651e777bd8SMatthieu Baerts			local line
766d8d08302SMatthieu Baerts			pm_nl_show_endpoints ${listener_ns} | while read -r line; do
767d8d08302SMatthieu Baerts				# shellcheck disable=SC2206 # we do want to split per word
768dda61b3dSGeliang Tang				local arr=($line)
769dda61b3dSGeliang Tang				local nr=0
770dda61b3dSGeliang Tang
7711e777bd8SMatthieu Baerts				local i
772d8d08302SMatthieu Baerts				for i in "${arr[@]}"; do
773dda61b3dSGeliang Tang					if [ $i = "id" ]; then
774dda61b3dSGeliang Tang						if [ $counter -eq $rm_nr_ns1 ]; then
775dda61b3dSGeliang Tang							break
776dda61b3dSGeliang Tang						fi
777dda61b3dSGeliang Tang						id=${arr[$nr+1]}
778327b9a94SPaolo Abeni						rm_addr=$(rm_addr_count ${connector_ns})
77934aa6e3bSGeliang Tang						pm_nl_del_endpoint ${listener_ns} $id
780327b9a94SPaolo Abeni						wait_rm_addr ${connector_ns} ${rm_addr}
781d8d08302SMatthieu Baerts						counter=$((counter + 1))
782f87744adSGeliang Tang					fi
783d8d08302SMatthieu Baerts					nr=$((nr + 1))
784dda61b3dSGeliang Tang				done
785dda61b3dSGeliang Tang			done
7865e287fe7SGeliang Tang		elif [ $rm_nr_ns1 -eq 8 ]; then
78734aa6e3bSGeliang Tang			pm_nl_flush_endpoint ${listener_ns}
7885e287fe7SGeliang Tang		elif [ $rm_nr_ns1 -eq 9 ]; then
78934aa6e3bSGeliang Tang			pm_nl_del_endpoint ${listener_ns} 0 ${connect_addr}
7906fe4ccdcSGeliang Tang		fi
791dd72b0feSGeliang Tang	fi
792dd72b0feSGeliang Tang
7931e777bd8SMatthieu Baerts	local flags="subflow"
7944f49d633SGeliang Tang	if [[ "${addr_nr_ns2}" = "fullmesh_"* ]]; then
7954f49d633SGeliang Tang		flags="${flags},fullmesh"
7964f49d633SGeliang Tang		addr_nr_ns2=${addr_nr_ns2:9}
7974f49d633SGeliang Tang	fi
7984f49d633SGeliang Tang
799327b9a94SPaolo Abeni	# if newly added endpoints must be deleted, give the background msk
800327b9a94SPaolo Abeni	# some time to created them
801d8d08302SMatthieu Baerts	[ $addr_nr_ns1 -gt 0 ] && [ $addr_nr_ns2 -lt 0 ] && sleep 1
802327b9a94SPaolo Abeni
8036208fd82SGeliang Tang	if [ $addr_nr_ns2 -gt 0 ]; then
804d8d08302SMatthieu Baerts		local add_nr_ns2=${addr_nr_ns2}
8051e777bd8SMatthieu Baerts		local counter=3
8066208fd82SGeliang Tang		while [ $add_nr_ns2 -gt 0 ]; do
8076208fd82SGeliang Tang			local addr
8086208fd82SGeliang Tang			if is_v6 "${connect_addr}"; then
8096208fd82SGeliang Tang				addr="dead:beef:$counter::2"
8106208fd82SGeliang Tang			else
8116208fd82SGeliang Tang				addr="10.0.$counter.2"
8126208fd82SGeliang Tang			fi
81334aa6e3bSGeliang Tang			pm_nl_add_endpoint $ns2 $addr flags $flags
814d8d08302SMatthieu Baerts			counter=$((counter + 1))
815d8d08302SMatthieu Baerts			add_nr_ns2=$((add_nr_ns2 - 1))
8166208fd82SGeliang Tang		done
8176208fd82SGeliang Tang	elif [ $addr_nr_ns2 -lt 0 ]; then
818d8d08302SMatthieu Baerts		local rm_nr_ns2=$((-addr_nr_ns2))
8196fe4ccdcSGeliang Tang		if [ $rm_nr_ns2 -lt 8 ]; then
8201e777bd8SMatthieu Baerts			local counter=0
8211e777bd8SMatthieu Baerts			local line
822d8d08302SMatthieu Baerts			pm_nl_show_endpoints ${connector_ns} | while read -r line; do
823d8d08302SMatthieu Baerts				# shellcheck disable=SC2206 # we do want to split per word
824dda61b3dSGeliang Tang				local arr=($line)
825dda61b3dSGeliang Tang				local nr=0
826dda61b3dSGeliang Tang
8271e777bd8SMatthieu Baerts				local i
828d8d08302SMatthieu Baerts				for i in "${arr[@]}"; do
829dda61b3dSGeliang Tang					if [ $i = "id" ]; then
830dda61b3dSGeliang Tang						if [ $counter -eq $rm_nr_ns2 ]; then
831dda61b3dSGeliang Tang							break
832dda61b3dSGeliang Tang						fi
8331e777bd8SMatthieu Baerts						local id rm_addr
834dda61b3dSGeliang Tang						# rm_addr are serialized, allow the previous one to
835dda61b3dSGeliang Tang						# complete
836dda61b3dSGeliang Tang						id=${arr[$nr+1]}
837327b9a94SPaolo Abeni						rm_addr=$(rm_addr_count ${listener_ns})
83834aa6e3bSGeliang Tang						pm_nl_del_endpoint ${connector_ns} $id
839327b9a94SPaolo Abeni						wait_rm_addr ${listener_ns} ${rm_addr}
840d8d08302SMatthieu Baerts						counter=$((counter + 1))
841f87744adSGeliang Tang					fi
842d8d08302SMatthieu Baerts					nr=$((nr + 1))
843dda61b3dSGeliang Tang				done
844dda61b3dSGeliang Tang			done
8455e287fe7SGeliang Tang		elif [ $rm_nr_ns2 -eq 8 ]; then
84634aa6e3bSGeliang Tang			pm_nl_flush_endpoint ${connector_ns}
8475e287fe7SGeliang Tang		elif [ $rm_nr_ns2 -eq 9 ]; then
8485e287fe7SGeliang Tang			local addr
8495e287fe7SGeliang Tang			if is_v6 "${connect_addr}"; then
8505e287fe7SGeliang Tang				addr="dead:beef:1::2"
8515e287fe7SGeliang Tang			else
8525e287fe7SGeliang Tang				addr="10.0.1.2"
8535e287fe7SGeliang Tang			fi
85434aa6e3bSGeliang Tang			pm_nl_del_endpoint ${connector_ns} 0 $addr
8556fe4ccdcSGeliang Tang		fi
856dd72b0feSGeliang Tang	fi
857dd72b0feSGeliang Tang
858d8d08302SMatthieu Baerts	if [ -n "${sflags}" ]; then
859718eb44eSGeliang Tang		sleep 1
8601e777bd8SMatthieu Baerts
8611e777bd8SMatthieu Baerts		local netns
862718eb44eSGeliang Tang		for netns in "$ns1" "$ns2"; do
8631e777bd8SMatthieu Baerts			local line
864d8d08302SMatthieu Baerts			pm_nl_show_endpoints $netns | while read -r line; do
865d8d08302SMatthieu Baerts				# shellcheck disable=SC2206 # we do want to split per word
86633397b83SGeliang Tang				local arr=($line)
867bccefb76SGeliang Tang				local nr=0
868f0140386SGeliang Tang				local id
86933397b83SGeliang Tang
8701e777bd8SMatthieu Baerts				local i
871d8d08302SMatthieu Baerts				for i in "${arr[@]}"; do
872bccefb76SGeliang Tang					if [ $i = "id" ]; then
873bccefb76SGeliang Tang						id=${arr[$nr+1]}
874718eb44eSGeliang Tang					fi
875d8d08302SMatthieu Baerts					nr=$((nr + 1))
87633397b83SGeliang Tang				done
877bccefb76SGeliang Tang				pm_nl_change_endpoint $netns $id $sflags
87833397b83SGeliang Tang			done
879718eb44eSGeliang Tang		done
880718eb44eSGeliang Tang	fi
881718eb44eSGeliang Tang
882b08fbf24SPaolo Abeni	wait $cpid
8831e777bd8SMatthieu Baerts	local retc=$?
884b08fbf24SPaolo Abeni	wait $spid
8851e777bd8SMatthieu Baerts	local rets=$?
886b08fbf24SPaolo Abeni
887b08fbf24SPaolo Abeni	if [ $capture -eq 1 ]; then
888b08fbf24SPaolo Abeni	    sleep 1
889b08fbf24SPaolo Abeni	    kill $cappid
890b08fbf24SPaolo Abeni	fi
891b08fbf24SPaolo Abeni
892c2a55e8fSMatthieu Baerts	NSTAT_HISTORY=/tmp/${listener_ns}.nstat ip netns exec ${listener_ns} \
893c2a55e8fSMatthieu Baerts		nstat | grep Tcp > /tmp/${listener_ns}.out
894c2a55e8fSMatthieu Baerts	NSTAT_HISTORY=/tmp/${connector_ns}.nstat ip netns exec ${connector_ns} \
895c2a55e8fSMatthieu Baerts		nstat | grep Tcp > /tmp/${connector_ns}.out
896c2a55e8fSMatthieu Baerts
897b08fbf24SPaolo Abeni	if [ ${rets} -ne 0 ] || [ ${retc} -ne 0 ]; then
898b08fbf24SPaolo Abeni		echo " client exit code $retc, server $rets" 1>&2
8998b974778SMatthieu Baerts		echo -e "\nnetns ${listener_ns} socket stat for ${port}:" 1>&2
900c2a55e8fSMatthieu Baerts		ip netns exec ${listener_ns} ss -Menita 1>&2 -o "sport = :$port"
901c2a55e8fSMatthieu Baerts		cat /tmp/${listener_ns}.out
9028b974778SMatthieu Baerts		echo -e "\nnetns ${connector_ns} socket stat for ${port}:" 1>&2
903c2a55e8fSMatthieu Baerts		ip netns exec ${connector_ns} ss -Menita 1>&2 -o "dport = :$port"
904c2a55e8fSMatthieu Baerts		cat /tmp/${connector_ns}.out
905b08fbf24SPaolo Abeni
906b08fbf24SPaolo Abeni		cat "$capout"
90739aab882SMatthieu Baerts		fail_test
908b08fbf24SPaolo Abeni		return 1
909b08fbf24SPaolo Abeni	fi
910b08fbf24SPaolo Abeni
91134b572b7SGeliang Tang	if [ "$test_link_fail" -gt 1 ];then
9127d1e6f16SPaolo Abeni		check_transfer $sinfail $cout "file received by client"
9137d1e6f16SPaolo Abeni	else
914b08fbf24SPaolo Abeni		check_transfer $sin $cout "file received by client"
9157d1e6f16SPaolo Abeni	fi
916b08fbf24SPaolo Abeni	retc=$?
9178b819a84SFlorian Westphal	if [ "$test_link_fail" -eq 0 ];then
918b08fbf24SPaolo Abeni		check_transfer $cin $sout "file received by server"
9198b819a84SFlorian Westphal	else
9208b819a84SFlorian Westphal		check_transfer $cinsent $sout "file received by server"
9218b819a84SFlorian Westphal	fi
922b08fbf24SPaolo Abeni	rets=$?
923b08fbf24SPaolo Abeni
924b08fbf24SPaolo Abeni	if [ $retc -eq 0 ] && [ $rets -eq 0 ];then
925b08fbf24SPaolo Abeni		cat "$capout"
926b08fbf24SPaolo Abeni		return 0
927b08fbf24SPaolo Abeni	fi
928b08fbf24SPaolo Abeni
929b08fbf24SPaolo Abeni	cat "$capout"
930b08fbf24SPaolo Abeni	return 1
931b08fbf24SPaolo Abeni}
932b08fbf24SPaolo Abeni
933b08fbf24SPaolo Abenimake_file()
934b08fbf24SPaolo Abeni{
9351e777bd8SMatthieu Baerts	local name=$1
9361e777bd8SMatthieu Baerts	local who=$2
9371e777bd8SMatthieu Baerts	local size=$3
938b08fbf24SPaolo Abeni
9398b819a84SFlorian Westphal	dd if=/dev/urandom of="$name" bs=1024 count=$size 2> /dev/null
940b08fbf24SPaolo Abeni	echo -e "\nMPTCP_TEST_FILE_END_MARKER" >> "$name"
941b08fbf24SPaolo Abeni
9428b819a84SFlorian Westphal	echo "Created $name (size $size KB) containing data sent by $who"
943b08fbf24SPaolo Abeni}
944b08fbf24SPaolo Abeni
945b08fbf24SPaolo Abenirun_tests()
946b08fbf24SPaolo Abeni{
9471e777bd8SMatthieu Baerts	local listener_ns="$1"
9481e777bd8SMatthieu Baerts	local connector_ns="$2"
9491e777bd8SMatthieu Baerts	local connect_addr="$3"
9501e777bd8SMatthieu Baerts	local test_linkfail="${4:-0}"
9511e777bd8SMatthieu Baerts	local addr_nr_ns1="${5:-0}"
9521e777bd8SMatthieu Baerts	local addr_nr_ns2="${6:-0}"
9531e777bd8SMatthieu Baerts	local speed="${7:-fast}"
9541e777bd8SMatthieu Baerts	local sflags="${8:-""}"
9551e777bd8SMatthieu Baerts
9561e777bd8SMatthieu Baerts	local size
9578b819a84SFlorian Westphal
95834b572b7SGeliang Tang	# The values above 2 are reused to make test files
95934b572b7SGeliang Tang	# with the given sizes (KB)
96034b572b7SGeliang Tang	if [ "$test_linkfail" -gt 2 ]; then
96134b572b7SGeliang Tang		size=$test_linkfail
96234b572b7SGeliang Tang
96334b572b7SGeliang Tang		if [ -z "$cinfail" ]; then
96434b572b7SGeliang Tang			cinfail=$(mktemp)
96534b572b7SGeliang Tang		fi
96634b572b7SGeliang Tang		make_file "$cinfail" "client" $size
9677d1e6f16SPaolo Abeni	# create the input file for the failure test when
9687d1e6f16SPaolo Abeni	# the first failure test run
969d8d08302SMatthieu Baerts	elif [ "$test_linkfail" -ne 0 ] && [ -z "$cinfail" ]; then
9707d1e6f16SPaolo Abeni		# the client file must be considerably larger
9717d1e6f16SPaolo Abeni		# of the maximum expected cwin value, or the
9727d1e6f16SPaolo Abeni		# link utilization will be not predicable
9737d1e6f16SPaolo Abeni		size=$((RANDOM%2))
9748b819a84SFlorian Westphal		size=$((size+1))
9757d1e6f16SPaolo Abeni		size=$((size*8192))
976d8d08302SMatthieu Baerts		size=$((size + ( RANDOM % 8192) ))
9778b819a84SFlorian Westphal
9787d1e6f16SPaolo Abeni		cinfail=$(mktemp)
9797d1e6f16SPaolo Abeni		make_file "$cinfail" "client" $size
9807d1e6f16SPaolo Abeni	fi
9817d1e6f16SPaolo Abeni
98234b572b7SGeliang Tang	if [ "$test_linkfail" -gt 2 ]; then
98334b572b7SGeliang Tang		size=$test_linkfail
98434b572b7SGeliang Tang
98534b572b7SGeliang Tang		if [ -z "$sinfail" ]; then
98634b572b7SGeliang Tang			sinfail=$(mktemp)
98734b572b7SGeliang Tang		fi
98834b572b7SGeliang Tang		make_file "$sinfail" "server" $size
989d8d08302SMatthieu Baerts	elif [ "$test_linkfail" -eq 2 ] && [ -z "$sinfail" ]; then
9907d1e6f16SPaolo Abeni		size=$((RANDOM%16))
9917d1e6f16SPaolo Abeni		size=$((size+1))
9927d1e6f16SPaolo Abeni		size=$((size*2048))
9937d1e6f16SPaolo Abeni
9947d1e6f16SPaolo Abeni		sinfail=$(mktemp)
9957d1e6f16SPaolo Abeni		make_file "$sinfail" "server" $size
9968b819a84SFlorian Westphal	fi
997b08fbf24SPaolo Abeni
9988d014eaaSGeliang Tang	do_transfer ${listener_ns} ${connector_ns} MPTCP MPTCP ${connect_addr} \
9996a0653b9SGeliang Tang		${test_linkfail} ${addr_nr_ns1} ${addr_nr_ns2} ${speed} ${sflags}
1000b08fbf24SPaolo Abeni}
1001b08fbf24SPaolo Abeni
1002327b9a94SPaolo Abenidump_stats()
1003327b9a94SPaolo Abeni{
1004327b9a94SPaolo Abeni	echo Server ns stats
1005327b9a94SPaolo Abeni	ip netns exec $ns1 nstat -as | grep Tcp
1006327b9a94SPaolo Abeni	echo Client ns stats
1007327b9a94SPaolo Abeni	ip netns exec $ns2 nstat -as | grep Tcp
1008327b9a94SPaolo Abeni}
1009327b9a94SPaolo Abeni
1010af66d3e1SGeliang Tangchk_csum_nr()
1011af66d3e1SGeliang Tang{
10123c082695SGeliang Tang	local csum_ns1=${1:-0}
10133c082695SGeliang Tang	local csum_ns2=${2:-0}
1014af66d3e1SGeliang Tang	local count
1015af66d3e1SGeliang Tang	local dump_stats
101626516e10SGeliang Tang	local allow_multi_errors_ns1=0
101726516e10SGeliang Tang	local allow_multi_errors_ns2=0
101826516e10SGeliang Tang
101926516e10SGeliang Tang	if [[ "${csum_ns1}" = "+"* ]]; then
102026516e10SGeliang Tang		allow_multi_errors_ns1=1
102126516e10SGeliang Tang		csum_ns1=${csum_ns1:1}
102226516e10SGeliang Tang	fi
102326516e10SGeliang Tang	if [[ "${csum_ns2}" = "+"* ]]; then
102426516e10SGeliang Tang		allow_multi_errors_ns2=1
102526516e10SGeliang Tang		csum_ns2=${csum_ns2:1}
102626516e10SGeliang Tang	fi
1027af66d3e1SGeliang Tang
10283c082695SGeliang Tang	printf "%-${nr_blank}s %s" " " "sum"
10294bfadd71SMatthieu Baerts	count=$(ip netns exec $ns1 nstat -as | grep MPTcpExtDataCsumErr | awk '{print $2}')
1030af66d3e1SGeliang Tang	[ -z "$count" ] && count=0
1031d8d08302SMatthieu Baerts	if { [ "$count" != $csum_ns1 ] && [ $allow_multi_errors_ns1 -eq 0 ]; } ||
1032d8d08302SMatthieu Baerts	   { [ "$count" -lt $csum_ns1 ] && [ $allow_multi_errors_ns1 -eq 1 ]; }; then
103326516e10SGeliang Tang		echo "[fail] got $count data checksum error[s] expected $csum_ns1"
103439aab882SMatthieu Baerts		fail_test
1035af66d3e1SGeliang Tang		dump_stats=1
1036af66d3e1SGeliang Tang	else
1037af66d3e1SGeliang Tang		echo -n "[ ok ]"
1038af66d3e1SGeliang Tang	fi
1039af66d3e1SGeliang Tang	echo -n " - csum  "
10404bfadd71SMatthieu Baerts	count=$(ip netns exec $ns2 nstat -as | grep MPTcpExtDataCsumErr | awk '{print $2}')
1041af66d3e1SGeliang Tang	[ -z "$count" ] && count=0
1042d8d08302SMatthieu Baerts	if { [ "$count" != $csum_ns2 ] && [ $allow_multi_errors_ns2 -eq 0 ]; } ||
1043d8d08302SMatthieu Baerts	   { [ "$count" -lt $csum_ns2 ] && [ $allow_multi_errors_ns2 -eq 1 ]; }; then
104426516e10SGeliang Tang		echo "[fail] got $count data checksum error[s] expected $csum_ns2"
104539aab882SMatthieu Baerts		fail_test
1046af66d3e1SGeliang Tang		dump_stats=1
1047af66d3e1SGeliang Tang	else
1048af66d3e1SGeliang Tang		echo "[ ok ]"
1049af66d3e1SGeliang Tang	fi
1050327b9a94SPaolo Abeni	[ "${dump_stats}" = 1 ] && dump_stats
1051af66d3e1SGeliang Tang}
1052af66d3e1SGeliang Tang
10536bb3ab49SGeliang Tangchk_fail_nr()
10546bb3ab49SGeliang Tang{
105526516e10SGeliang Tang	local fail_tx=$1
105626516e10SGeliang Tang	local fail_rx=$2
10576bb3ab49SGeliang Tang	local count
10586bb3ab49SGeliang Tang	local dump_stats
10596bb3ab49SGeliang Tang
10609a0a9367SGeliang Tang	printf "%-${nr_blank}s %s" " " "ftx"
10614bfadd71SMatthieu Baerts	count=$(ip netns exec $ns1 nstat -as | grep MPTcpExtMPFailTx | awk '{print $2}')
10626bb3ab49SGeliang Tang	[ -z "$count" ] && count=0
106326516e10SGeliang Tang	if [ "$count" != "$fail_tx" ]; then
106426516e10SGeliang Tang		echo "[fail] got $count MP_FAIL[s] TX expected $fail_tx"
106539aab882SMatthieu Baerts		fail_test
10666bb3ab49SGeliang Tang		dump_stats=1
10676bb3ab49SGeliang Tang	else
10686bb3ab49SGeliang Tang		echo -n "[ ok ]"
10696bb3ab49SGeliang Tang	fi
10706bb3ab49SGeliang Tang
107126516e10SGeliang Tang	echo -n " - failrx"
10724bfadd71SMatthieu Baerts	count=$(ip netns exec $ns2 nstat -as | grep MPTcpExtMPFailRx | awk '{print $2}')
10736bb3ab49SGeliang Tang	[ -z "$count" ] && count=0
107426516e10SGeliang Tang	if [ "$count" != "$fail_rx" ]; then
107526516e10SGeliang Tang		echo "[fail] got $count MP_FAIL[s] RX expected $fail_rx"
107639aab882SMatthieu Baerts		fail_test
10776bb3ab49SGeliang Tang		dump_stats=1
10786bb3ab49SGeliang Tang	else
10796bb3ab49SGeliang Tang		echo "[ ok ]"
10806bb3ab49SGeliang Tang	fi
10816bb3ab49SGeliang Tang
1082327b9a94SPaolo Abeni	[ "${dump_stats}" = 1 ] && dump_stats
10836bb3ab49SGeliang Tang}
10846bb3ab49SGeliang Tang
1085e8e947efSGeliang Tangchk_fclose_nr()
1086e8e947efSGeliang Tang{
1087e8e947efSGeliang Tang	local fclose_tx=$1
1088e8e947efSGeliang Tang	local fclose_rx=$2
1089e8e947efSGeliang Tang	local count
1090e8e947efSGeliang Tang	local dump_stats
1091e8e947efSGeliang Tang
1092e8e947efSGeliang Tang	printf "%-${nr_blank}s %s" " " "ctx"
1093e8e947efSGeliang Tang	count=$(ip netns exec $ns2 nstat -as | grep MPTcpExtMPFastcloseTx | awk '{print $2}')
1094e8e947efSGeliang Tang	[ -z "$count" ] && count=0
1095e8e947efSGeliang Tang	if [ "$count" != "$fclose_tx" ]; then
1096e8e947efSGeliang Tang		echo "[fail] got $count MP_FASTCLOSE[s] TX expected $fclose_tx"
109739aab882SMatthieu Baerts		fail_test
1098e8e947efSGeliang Tang		dump_stats=1
1099e8e947efSGeliang Tang	else
1100e8e947efSGeliang Tang		echo -n "[ ok ]"
1101e8e947efSGeliang Tang	fi
1102e8e947efSGeliang Tang
1103e8e947efSGeliang Tang	echo -n " - fclzrx"
1104e8e947efSGeliang Tang	count=$(ip netns exec $ns1 nstat -as | grep MPTcpExtMPFastcloseRx | awk '{print $2}')
1105e8e947efSGeliang Tang	[ -z "$count" ] && count=0
1106e8e947efSGeliang Tang	if [ "$count" != "$fclose_rx" ]; then
1107e8e947efSGeliang Tang		echo "[fail] got $count MP_FASTCLOSE[s] RX expected $fclose_rx"
110839aab882SMatthieu Baerts		fail_test
1109e8e947efSGeliang Tang		dump_stats=1
1110e8e947efSGeliang Tang	else
1111e8e947efSGeliang Tang		echo "[ ok ]"
1112e8e947efSGeliang Tang	fi
1113e8e947efSGeliang Tang
1114e8e947efSGeliang Tang	[ "${dump_stats}" = 1 ] && dump_stats
1115e8e947efSGeliang Tang}
1116e8e947efSGeliang Tang
1117922fd2b3SGeliang Tangchk_rst_nr()
1118922fd2b3SGeliang Tang{
1119922fd2b3SGeliang Tang	local rst_tx=$1
1120922fd2b3SGeliang Tang	local rst_rx=$2
1121922fd2b3SGeliang Tang	local ns_invert=${3:-""}
1122922fd2b3SGeliang Tang	local count
1123922fd2b3SGeliang Tang	local dump_stats
1124922fd2b3SGeliang Tang	local ns_tx=$ns1
1125922fd2b3SGeliang Tang	local ns_rx=$ns2
1126922fd2b3SGeliang Tang	local extra_msg=""
1127922fd2b3SGeliang Tang
1128922fd2b3SGeliang Tang	if [[ $ns_invert = "invert" ]]; then
1129922fd2b3SGeliang Tang		ns_tx=$ns2
1130922fd2b3SGeliang Tang		ns_rx=$ns1
1131922fd2b3SGeliang Tang		extra_msg="   invert"
1132922fd2b3SGeliang Tang	fi
1133922fd2b3SGeliang Tang
1134922fd2b3SGeliang Tang	printf "%-${nr_blank}s %s" " " "rtx"
1135922fd2b3SGeliang Tang	count=$(ip netns exec $ns_tx nstat -as | grep MPTcpExtMPRstTx | awk '{print $2}')
1136922fd2b3SGeliang Tang	[ -z "$count" ] && count=0
1137922fd2b3SGeliang Tang	if [ "$count" != "$rst_tx" ]; then
1138922fd2b3SGeliang Tang		echo "[fail] got $count MP_RST[s] TX expected $rst_tx"
113939aab882SMatthieu Baerts		fail_test
1140922fd2b3SGeliang Tang		dump_stats=1
1141922fd2b3SGeliang Tang	else
1142922fd2b3SGeliang Tang		echo -n "[ ok ]"
1143922fd2b3SGeliang Tang	fi
1144922fd2b3SGeliang Tang
1145922fd2b3SGeliang Tang	echo -n " - rstrx "
1146922fd2b3SGeliang Tang	count=$(ip netns exec $ns_rx nstat -as | grep MPTcpExtMPRstRx | awk '{print $2}')
1147922fd2b3SGeliang Tang	[ -z "$count" ] && count=0
1148922fd2b3SGeliang Tang	if [ "$count" != "$rst_rx" ]; then
1149922fd2b3SGeliang Tang		echo "[fail] got $count MP_RST[s] RX expected $rst_rx"
115039aab882SMatthieu Baerts		fail_test
1151922fd2b3SGeliang Tang		dump_stats=1
1152922fd2b3SGeliang Tang	else
1153922fd2b3SGeliang Tang		echo -n "[ ok ]"
1154922fd2b3SGeliang Tang	fi
1155922fd2b3SGeliang Tang
1156922fd2b3SGeliang Tang	[ "${dump_stats}" = 1 ] && dump_stats
1157922fd2b3SGeliang Tang
1158922fd2b3SGeliang Tang	echo "$extra_msg"
1159922fd2b3SGeliang Tang}
1160922fd2b3SGeliang Tang
11618bd03be3SGeliang Tangchk_infi_nr()
11628bd03be3SGeliang Tang{
11638bd03be3SGeliang Tang	local infi_tx=$1
11648bd03be3SGeliang Tang	local infi_rx=$2
11658bd03be3SGeliang Tang	local count
11668bd03be3SGeliang Tang	local dump_stats
11678bd03be3SGeliang Tang
11688bd03be3SGeliang Tang	printf "%-${nr_blank}s %s" " " "itx"
11698bd03be3SGeliang Tang	count=$(ip netns exec $ns2 nstat -as | grep InfiniteMapTx | awk '{print $2}')
11708bd03be3SGeliang Tang	[ -z "$count" ] && count=0
11718bd03be3SGeliang Tang	if [ "$count" != "$infi_tx" ]; then
11728bd03be3SGeliang Tang		echo "[fail] got $count infinite map[s] TX expected $infi_tx"
11738bd03be3SGeliang Tang		fail_test
11748bd03be3SGeliang Tang		dump_stats=1
11758bd03be3SGeliang Tang	else
11768bd03be3SGeliang Tang		echo -n "[ ok ]"
11778bd03be3SGeliang Tang	fi
11788bd03be3SGeliang Tang
11798bd03be3SGeliang Tang	echo -n " - infirx"
11808bd03be3SGeliang Tang	count=$(ip netns exec $ns1 nstat -as | grep InfiniteMapRx | awk '{print $2}')
11818bd03be3SGeliang Tang	[ -z "$count" ] && count=0
11828bd03be3SGeliang Tang	if [ "$count" != "$infi_rx" ]; then
11838bd03be3SGeliang Tang		echo "[fail] got $count infinite map[s] RX expected $infi_rx"
11848bd03be3SGeliang Tang		fail_test
11858bd03be3SGeliang Tang		dump_stats=1
11868bd03be3SGeliang Tang	else
11878bd03be3SGeliang Tang		echo "[ ok ]"
11888bd03be3SGeliang Tang	fi
11898bd03be3SGeliang Tang
11908bd03be3SGeliang Tang	[ "${dump_stats}" = 1 ] && dump_stats
11918bd03be3SGeliang Tang}
11928bd03be3SGeliang Tang
1193b08fbf24SPaolo Abenichk_join_nr()
1194b08fbf24SPaolo Abeni{
1195c7d49c03SMatthieu Baerts	local syn_nr=$1
1196c7d49c03SMatthieu Baerts	local syn_ack_nr=$2
1197c7d49c03SMatthieu Baerts	local ack_nr=$3
1198c7d49c03SMatthieu Baerts	local csum_ns1=${4:-0}
1199c7d49c03SMatthieu Baerts	local csum_ns2=${5:-0}
1200c7d49c03SMatthieu Baerts	local fail_nr=${6:-0}
1201c7d49c03SMatthieu Baerts	local rst_nr=${7:-0}
12028bd03be3SGeliang Tang	local infi_nr=${8:-0}
12038bd03be3SGeliang Tang	local corrupted_pkts=${9:-0}
1204b08fbf24SPaolo Abeni	local count
1205b08fbf24SPaolo Abeni	local dump_stats
1206e35f885bSPaolo Abeni	local with_cookie
1207c7d49c03SMatthieu Baerts	local title="${TEST_NAME}"
1208b08fbf24SPaolo Abeni
1209c7d49c03SMatthieu Baerts	if [ "${corrupted_pkts}" -gt 0 ]; then
1210c7d49c03SMatthieu Baerts		title+=": ${corrupted_pkts} corrupted pkts"
1211c7d49c03SMatthieu Baerts	fi
1212c7d49c03SMatthieu Baerts
1213c7d49c03SMatthieu Baerts	printf "%03u %-36s %s" "${TEST_COUNT}" "${title}" "syn"
12144bfadd71SMatthieu Baerts	count=$(ip netns exec $ns1 nstat -as | grep MPTcpExtMPJoinSynRx | awk '{print $2}')
1215b08fbf24SPaolo Abeni	[ -z "$count" ] && count=0
1216b08fbf24SPaolo Abeni	if [ "$count" != "$syn_nr" ]; then
1217b08fbf24SPaolo Abeni		echo "[fail] got $count JOIN[s] syn expected $syn_nr"
121839aab882SMatthieu Baerts		fail_test
1219b08fbf24SPaolo Abeni		dump_stats=1
1220b08fbf24SPaolo Abeni	else
1221b08fbf24SPaolo Abeni		echo -n "[ ok ]"
1222b08fbf24SPaolo Abeni	fi
1223b08fbf24SPaolo Abeni
1224b08fbf24SPaolo Abeni	echo -n " - synack"
12254bfadd71SMatthieu Baerts	with_cookie=$(ip netns exec $ns2 sysctl -n net.ipv4.tcp_syncookies)
12264bfadd71SMatthieu Baerts	count=$(ip netns exec $ns2 nstat -as | grep MPTcpExtMPJoinSynAckRx | awk '{print $2}')
1227b08fbf24SPaolo Abeni	[ -z "$count" ] && count=0
1228b08fbf24SPaolo Abeni	if [ "$count" != "$syn_ack_nr" ]; then
1229e35f885bSPaolo Abeni		# simult connections exceeding the limit with cookie enabled could go up to
1230e35f885bSPaolo Abeni		# synack validation as the conn limit can be enforced reliably only after
1231e35f885bSPaolo Abeni		# the subflow creation
1232e35f885bSPaolo Abeni		if [ "$with_cookie" = 2 ] && [ "$count" -gt "$syn_ack_nr" ] && [ "$count" -le "$syn_nr" ]; then
1233e35f885bSPaolo Abeni			echo -n "[ ok ]"
1234e35f885bSPaolo Abeni		else
1235b08fbf24SPaolo Abeni			echo "[fail] got $count JOIN[s] synack expected $syn_ack_nr"
123639aab882SMatthieu Baerts			fail_test
1237b08fbf24SPaolo Abeni			dump_stats=1
1238e35f885bSPaolo Abeni		fi
1239b08fbf24SPaolo Abeni	else
1240b08fbf24SPaolo Abeni		echo -n "[ ok ]"
1241b08fbf24SPaolo Abeni	fi
1242b08fbf24SPaolo Abeni
1243b08fbf24SPaolo Abeni	echo -n " - ack"
12444bfadd71SMatthieu Baerts	count=$(ip netns exec $ns1 nstat -as | grep MPTcpExtMPJoinAckRx | awk '{print $2}')
1245b08fbf24SPaolo Abeni	[ -z "$count" ] && count=0
1246b08fbf24SPaolo Abeni	if [ "$count" != "$ack_nr" ]; then
1247b08fbf24SPaolo Abeni		echo "[fail] got $count JOIN[s] ack expected $ack_nr"
124839aab882SMatthieu Baerts		fail_test
1249b08fbf24SPaolo Abeni		dump_stats=1
1250b08fbf24SPaolo Abeni	else
1251b08fbf24SPaolo Abeni		echo "[ ok ]"
1252b08fbf24SPaolo Abeni	fi
1253327b9a94SPaolo Abeni	[ "${dump_stats}" = 1 ] && dump_stats
1254*b6e074e1SGeliang Tang	if [ $validate_checksum -eq 1 ]; then
12553c082695SGeliang Tang		chk_csum_nr $csum_ns1 $csum_ns2
125626516e10SGeliang Tang		chk_fail_nr $fail_nr $fail_nr
125726516e10SGeliang Tang		chk_rst_nr $rst_nr $rst_nr
12588bd03be3SGeliang Tang		chk_infi_nr $infi_nr $infi_nr
1259af66d3e1SGeliang Tang	fi
1260b08fbf24SPaolo Abeni}
1261b08fbf24SPaolo Abeni
12627d1e6f16SPaolo Abeni# a negative value for 'stale_max' means no upper bound:
12637d1e6f16SPaolo Abeni# for bidirectional transfer, if one peer sleep for a while
12647d1e6f16SPaolo Abeni# - as these tests do - we can have a quite high number of
12657d1e6f16SPaolo Abeni# stale/recover conversions, proportional to
12667d1e6f16SPaolo Abeni# sleep duration/ MPTCP-level RTX interval.
12677d1e6f16SPaolo Abenichk_stale_nr()
12687d1e6f16SPaolo Abeni{
12697d1e6f16SPaolo Abeni	local ns=$1
12707d1e6f16SPaolo Abeni	local stale_min=$2
12717d1e6f16SPaolo Abeni	local stale_max=$3
12727d1e6f16SPaolo Abeni	local stale_delta=$4
12737d1e6f16SPaolo Abeni	local dump_stats
12747d1e6f16SPaolo Abeni	local stale_nr
12757d1e6f16SPaolo Abeni	local recover_nr
12767d1e6f16SPaolo Abeni
12779a0a9367SGeliang Tang	printf "%-${nr_blank}s %-18s" " " "stale"
12784bfadd71SMatthieu Baerts	stale_nr=$(ip netns exec $ns nstat -as | grep MPTcpExtSubflowStale | awk '{print $2}')
12797d1e6f16SPaolo Abeni	[ -z "$stale_nr" ] && stale_nr=0
12804bfadd71SMatthieu Baerts	recover_nr=$(ip netns exec $ns nstat -as | grep MPTcpExtSubflowRecover | awk '{print $2}')
12817d1e6f16SPaolo Abeni	[ -z "$recover_nr" ] && recover_nr=0
12827d1e6f16SPaolo Abeni
12837d1e6f16SPaolo Abeni	if [ $stale_nr -lt $stale_min ] ||
1284d8d08302SMatthieu Baerts	   { [ $stale_max -gt 0 ] && [ $stale_nr -gt $stale_max ]; } ||
1285d8d08302SMatthieu Baerts	   [ $((stale_nr - recover_nr)) -ne $stale_delta ]; then
12867d1e6f16SPaolo Abeni		echo "[fail] got $stale_nr stale[s] $recover_nr recover[s], " \
12877d1e6f16SPaolo Abeni		     " expected stale in range [$stale_min..$stale_max]," \
12887d1e6f16SPaolo Abeni		     " stale-recover delta $stale_delta "
128939aab882SMatthieu Baerts		fail_test
12907d1e6f16SPaolo Abeni		dump_stats=1
12917d1e6f16SPaolo Abeni	else
12927d1e6f16SPaolo Abeni		echo "[ ok ]"
12937d1e6f16SPaolo Abeni	fi
12947d1e6f16SPaolo Abeni
12957d1e6f16SPaolo Abeni	if [ "${dump_stats}" = 1 ]; then
12967d1e6f16SPaolo Abeni		echo $ns stats
12977d1e6f16SPaolo Abeni		ip netns exec $ns ip -s link show
12987d1e6f16SPaolo Abeni		ip netns exec $ns nstat -as | grep MPTcp
12997d1e6f16SPaolo Abeni	fi
13007d1e6f16SPaolo Abeni}
13017d1e6f16SPaolo Abeni
1302be613160SGeliang Tangchk_add_nr()
1303be613160SGeliang Tang{
1304be613160SGeliang Tang	local add_nr=$1
1305be613160SGeliang Tang	local echo_nr=$2
13068a127bf6SGeliang Tang	local port_nr=${3:-0}
13078a127bf6SGeliang Tang	local syn_nr=${4:-$port_nr}
13088a127bf6SGeliang Tang	local syn_ack_nr=${5:-$port_nr}
13098a127bf6SGeliang Tang	local ack_nr=${6:-$port_nr}
13108a127bf6SGeliang Tang	local mis_syn_nr=${7:-0}
13118a127bf6SGeliang Tang	local mis_ack_nr=${8:-0}
1312be613160SGeliang Tang	local count
1313be613160SGeliang Tang	local dump_stats
13146ef84b15SPaolo Abeni	local timeout
13156ef84b15SPaolo Abeni
13164bfadd71SMatthieu Baerts	timeout=$(ip netns exec $ns1 sysctl -n net.mptcp.add_addr_timeout)
1317be613160SGeliang Tang
13189a0a9367SGeliang Tang	printf "%-${nr_blank}s %s" " " "add"
13194bfadd71SMatthieu Baerts	count=$(ip netns exec $ns2 nstat -as MPTcpExtAddAddr | grep MPTcpExtAddAddr | awk '{print $2}')
1320be613160SGeliang Tang	[ -z "$count" ] && count=0
13216ef84b15SPaolo Abeni
13226ef84b15SPaolo Abeni	# if the test configured a short timeout tolerate greater then expected
13236ef84b15SPaolo Abeni	# add addrs options, due to retransmissions
1324d8d08302SMatthieu Baerts	if [ "$count" != "$add_nr" ] && { [ "$timeout" -gt 1 ] || [ "$count" -lt "$add_nr" ]; }; then
1325be613160SGeliang Tang		echo "[fail] got $count ADD_ADDR[s] expected $add_nr"
132639aab882SMatthieu Baerts		fail_test
1327be613160SGeliang Tang		dump_stats=1
1328be613160SGeliang Tang	else
1329be613160SGeliang Tang		echo -n "[ ok ]"
1330be613160SGeliang Tang	fi
1331be613160SGeliang Tang
1332be613160SGeliang Tang	echo -n " - echo  "
13334bfadd71SMatthieu Baerts	count=$(ip netns exec $ns1 nstat -as | grep MPTcpExtEchoAdd | awk '{print $2}')
1334be613160SGeliang Tang	[ -z "$count" ] && count=0
1335be613160SGeliang Tang	if [ "$count" != "$echo_nr" ]; then
1336be613160SGeliang Tang		echo "[fail] got $count ADD_ADDR echo[s] expected $echo_nr"
133739aab882SMatthieu Baerts		fail_test
1338be613160SGeliang Tang		dump_stats=1
1339be613160SGeliang Tang	else
13408a127bf6SGeliang Tang		echo -n "[ ok ]"
13418a127bf6SGeliang Tang	fi
13428a127bf6SGeliang Tang
13438a127bf6SGeliang Tang	if [ $port_nr -gt 0 ]; then
13448a127bf6SGeliang Tang		echo -n " - pt "
13454bfadd71SMatthieu Baerts		count=$(ip netns exec $ns2 nstat -as | grep MPTcpExtPortAdd | awk '{print $2}')
13468a127bf6SGeliang Tang		[ -z "$count" ] && count=0
13478a127bf6SGeliang Tang		if [ "$count" != "$port_nr" ]; then
13488a127bf6SGeliang Tang			echo "[fail] got $count ADD_ADDR[s] with a port-number expected $port_nr"
134939aab882SMatthieu Baerts			fail_test
13508a127bf6SGeliang Tang			dump_stats=1
13518a127bf6SGeliang Tang		else
1352be613160SGeliang Tang			echo "[ ok ]"
1353be613160SGeliang Tang		fi
1354be613160SGeliang Tang
13559a0a9367SGeliang Tang		printf "%-${nr_blank}s %s" " " "syn"
13564bfadd71SMatthieu Baerts		count=$(ip netns exec $ns1 nstat -as | grep MPTcpExtMPJoinPortSynRx |
13574bfadd71SMatthieu Baerts			awk '{print $2}')
13588a127bf6SGeliang Tang		[ -z "$count" ] && count=0
13598a127bf6SGeliang Tang		if [ "$count" != "$syn_nr" ]; then
13608a127bf6SGeliang Tang			echo "[fail] got $count JOIN[s] syn with a different \
13618a127bf6SGeliang Tang				port-number expected $syn_nr"
136239aab882SMatthieu Baerts			fail_test
13638a127bf6SGeliang Tang			dump_stats=1
13648a127bf6SGeliang Tang		else
13658a127bf6SGeliang Tang			echo -n "[ ok ]"
13668a127bf6SGeliang Tang		fi
13678a127bf6SGeliang Tang
13688a127bf6SGeliang Tang		echo -n " - synack"
13694bfadd71SMatthieu Baerts		count=$(ip netns exec $ns2 nstat -as | grep MPTcpExtMPJoinPortSynAckRx |
13704bfadd71SMatthieu Baerts			awk '{print $2}')
13718a127bf6SGeliang Tang		[ -z "$count" ] && count=0
13728a127bf6SGeliang Tang		if [ "$count" != "$syn_ack_nr" ]; then
13738a127bf6SGeliang Tang			echo "[fail] got $count JOIN[s] synack with a different \
13748a127bf6SGeliang Tang				port-number expected $syn_ack_nr"
137539aab882SMatthieu Baerts			fail_test
13768a127bf6SGeliang Tang			dump_stats=1
13778a127bf6SGeliang Tang		else
13788a127bf6SGeliang Tang			echo -n "[ ok ]"
13798a127bf6SGeliang Tang		fi
13808a127bf6SGeliang Tang
13818a127bf6SGeliang Tang		echo -n " - ack"
13824bfadd71SMatthieu Baerts		count=$(ip netns exec $ns1 nstat -as | grep MPTcpExtMPJoinPortAckRx |
13834bfadd71SMatthieu Baerts			awk '{print $2}')
13848a127bf6SGeliang Tang		[ -z "$count" ] && count=0
13858a127bf6SGeliang Tang		if [ "$count" != "$ack_nr" ]; then
13868a127bf6SGeliang Tang			echo "[fail] got $count JOIN[s] ack with a different \
13878a127bf6SGeliang Tang				port-number expected $ack_nr"
138839aab882SMatthieu Baerts			fail_test
13898a127bf6SGeliang Tang			dump_stats=1
13908a127bf6SGeliang Tang		else
13918a127bf6SGeliang Tang			echo "[ ok ]"
13928a127bf6SGeliang Tang		fi
13938a127bf6SGeliang Tang
13949a0a9367SGeliang Tang		printf "%-${nr_blank}s %s" " " "syn"
13954bfadd71SMatthieu Baerts		count=$(ip netns exec $ns1 nstat -as | grep MPTcpExtMismatchPortSynRx |
13964bfadd71SMatthieu Baerts			awk '{print $2}')
13978a127bf6SGeliang Tang		[ -z "$count" ] && count=0
13988a127bf6SGeliang Tang		if [ "$count" != "$mis_syn_nr" ]; then
13998a127bf6SGeliang Tang			echo "[fail] got $count JOIN[s] syn with a mismatched \
14008a127bf6SGeliang Tang				port-number expected $mis_syn_nr"
140139aab882SMatthieu Baerts			fail_test
14028a127bf6SGeliang Tang			dump_stats=1
14038a127bf6SGeliang Tang		else
14048a127bf6SGeliang Tang			echo -n "[ ok ]"
14058a127bf6SGeliang Tang		fi
14068a127bf6SGeliang Tang
14078a127bf6SGeliang Tang		echo -n " - ack   "
14084bfadd71SMatthieu Baerts		count=$(ip netns exec $ns1 nstat -as | grep MPTcpExtMismatchPortAckRx |
14094bfadd71SMatthieu Baerts			awk '{print $2}')
14108a127bf6SGeliang Tang		[ -z "$count" ] && count=0
14118a127bf6SGeliang Tang		if [ "$count" != "$mis_ack_nr" ]; then
14128a127bf6SGeliang Tang			echo "[fail] got $count JOIN[s] ack with a mismatched \
14138a127bf6SGeliang Tang				port-number expected $mis_ack_nr"
141439aab882SMatthieu Baerts			fail_test
14158a127bf6SGeliang Tang			dump_stats=1
14168a127bf6SGeliang Tang		else
14178a127bf6SGeliang Tang			echo "[ ok ]"
14188a127bf6SGeliang Tang		fi
14198a127bf6SGeliang Tang	else
14208a127bf6SGeliang Tang		echo ""
14218a127bf6SGeliang Tang	fi
14228a127bf6SGeliang Tang
1423327b9a94SPaolo Abeni	[ "${dump_stats}" = 1 ] && dump_stats
1424be613160SGeliang Tang}
1425be613160SGeliang Tang
1426dd72b0feSGeliang Tangchk_rm_nr()
1427dd72b0feSGeliang Tang{
1428dd72b0feSGeliang Tang	local rm_addr_nr=$1
1429dd72b0feSGeliang Tang	local rm_subflow_nr=$2
14306fa0174aSPaolo Abeni	local invert
14316fa0174aSPaolo Abeni	local simult
1432dd72b0feSGeliang Tang	local count
1433dd72b0feSGeliang Tang	local dump_stats
14347d9bf018SGeliang Tang	local addr_ns=$ns1
14357d9bf018SGeliang Tang	local subflow_ns=$ns2
14367d9bf018SGeliang Tang	local extra_msg=""
14377028ba8aSGeliang Tang
14386fa0174aSPaolo Abeni	shift 2
14396fa0174aSPaolo Abeni	while [ -n "$1" ]; do
14406fa0174aSPaolo Abeni		[ "$1" = "invert" ] && invert=true
14416fa0174aSPaolo Abeni		[ "$1" = "simult" ] && simult=true
14426fa0174aSPaolo Abeni		shift
14436fa0174aSPaolo Abeni	done
14446fa0174aSPaolo Abeni
14456fa0174aSPaolo Abeni	if [ -z $invert ]; then
14466fa0174aSPaolo Abeni		addr_ns=$ns1
14476fa0174aSPaolo Abeni		subflow_ns=$ns2
14486fa0174aSPaolo Abeni	elif [ $invert = "true" ]; then
14497028ba8aSGeliang Tang		addr_ns=$ns2
14507028ba8aSGeliang Tang		subflow_ns=$ns1
14517d9bf018SGeliang Tang		extra_msg="   invert"
14527028ba8aSGeliang Tang	fi
1453dd72b0feSGeliang Tang
14549a0a9367SGeliang Tang	printf "%-${nr_blank}s %s" " " "rm "
14554bfadd71SMatthieu Baerts	count=$(ip netns exec $addr_ns nstat -as | grep MPTcpExtRmAddr | awk '{print $2}')
1456dd72b0feSGeliang Tang	[ -z "$count" ] && count=0
1457dd72b0feSGeliang Tang	if [ "$count" != "$rm_addr_nr" ]; then
1458dd72b0feSGeliang Tang		echo "[fail] got $count RM_ADDR[s] expected $rm_addr_nr"
145939aab882SMatthieu Baerts		fail_test
1460dd72b0feSGeliang Tang		dump_stats=1
1461dd72b0feSGeliang Tang	else
1462dd72b0feSGeliang Tang		echo -n "[ ok ]"
1463dd72b0feSGeliang Tang	fi
1464dd72b0feSGeliang Tang
14657d9bf018SGeliang Tang	echo -n " - rmsf  "
14664bfadd71SMatthieu Baerts	count=$(ip netns exec $subflow_ns nstat -as | grep MPTcpExtRmSubflow | awk '{print $2}')
1467dd72b0feSGeliang Tang	[ -z "$count" ] && count=0
14686fa0174aSPaolo Abeni	if [ -n "$simult" ]; then
1469d8d08302SMatthieu Baerts		local cnt suffix
1470d8d08302SMatthieu Baerts
1471d8d08302SMatthieu Baerts		cnt=$(ip netns exec $addr_ns nstat -as | grep MPTcpExtRmSubflow | awk '{print $2}')
14726fa0174aSPaolo Abeni
14736fa0174aSPaolo Abeni		# in case of simult flush, the subflow removal count on each side is
14746fa0174aSPaolo Abeni		# unreliable
14756fa0174aSPaolo Abeni		[ -z "$cnt" ] && cnt=0
14766fa0174aSPaolo Abeni		count=$((count + cnt))
14776fa0174aSPaolo Abeni		[ "$count" != "$rm_subflow_nr" ] && suffix="$count in [$rm_subflow_nr:$((rm_subflow_nr*2))]"
14786fa0174aSPaolo Abeni		if [ $count -ge "$rm_subflow_nr" ] && \
14796fa0174aSPaolo Abeni		   [ "$count" -le "$((rm_subflow_nr *2 ))" ]; then
14806fa0174aSPaolo Abeni			echo "[ ok ] $suffix"
14816fa0174aSPaolo Abeni		else
14826fa0174aSPaolo Abeni			echo "[fail] got $count RM_SUBFLOW[s] expected in range [$rm_subflow_nr:$((rm_subflow_nr*2))]"
148339aab882SMatthieu Baerts			fail_test
14846fa0174aSPaolo Abeni			dump_stats=1
14856fa0174aSPaolo Abeni		fi
14866fa0174aSPaolo Abeni		return
14876fa0174aSPaolo Abeni	fi
1488dd72b0feSGeliang Tang	if [ "$count" != "$rm_subflow_nr" ]; then
1489dd72b0feSGeliang Tang		echo "[fail] got $count RM_SUBFLOW[s] expected $rm_subflow_nr"
149039aab882SMatthieu Baerts		fail_test
1491dd72b0feSGeliang Tang		dump_stats=1
1492dd72b0feSGeliang Tang	else
14937d9bf018SGeliang Tang		echo -n "[ ok ]"
1494dd72b0feSGeliang Tang	fi
1495dd72b0feSGeliang Tang
1496327b9a94SPaolo Abeni	[ "${dump_stats}" = 1 ] && dump_stats
14977d9bf018SGeliang Tang
14987d9bf018SGeliang Tang	echo "$extra_msg"
1499dd72b0feSGeliang Tang}
1500dd72b0feSGeliang Tang
1501718eb44eSGeliang Tangchk_prio_nr()
1502718eb44eSGeliang Tang{
1503718eb44eSGeliang Tang	local mp_prio_nr_tx=$1
1504718eb44eSGeliang Tang	local mp_prio_nr_rx=$2
1505718eb44eSGeliang Tang	local count
1506718eb44eSGeliang Tang	local dump_stats
1507718eb44eSGeliang Tang
15089a0a9367SGeliang Tang	printf "%-${nr_blank}s %s" " " "ptx"
15094bfadd71SMatthieu Baerts	count=$(ip netns exec $ns1 nstat -as | grep MPTcpExtMPPrioTx | awk '{print $2}')
1510718eb44eSGeliang Tang	[ -z "$count" ] && count=0
1511718eb44eSGeliang Tang	if [ "$count" != "$mp_prio_nr_tx" ]; then
1512718eb44eSGeliang Tang		echo "[fail] got $count MP_PRIO[s] TX expected $mp_prio_nr_tx"
151339aab882SMatthieu Baerts		fail_test
1514718eb44eSGeliang Tang		dump_stats=1
1515718eb44eSGeliang Tang	else
1516718eb44eSGeliang Tang		echo -n "[ ok ]"
1517718eb44eSGeliang Tang	fi
1518718eb44eSGeliang Tang
1519718eb44eSGeliang Tang	echo -n " - prx   "
15204bfadd71SMatthieu Baerts	count=$(ip netns exec $ns1 nstat -as | grep MPTcpExtMPPrioRx | awk '{print $2}')
1521718eb44eSGeliang Tang	[ -z "$count" ] && count=0
1522718eb44eSGeliang Tang	if [ "$count" != "$mp_prio_nr_rx" ]; then
1523718eb44eSGeliang Tang		echo "[fail] got $count MP_PRIO[s] RX expected $mp_prio_nr_rx"
152439aab882SMatthieu Baerts		fail_test
1525718eb44eSGeliang Tang		dump_stats=1
1526718eb44eSGeliang Tang	else
1527718eb44eSGeliang Tang		echo "[ ok ]"
1528718eb44eSGeliang Tang	fi
1529718eb44eSGeliang Tang
1530327b9a94SPaolo Abeni	[ "${dump_stats}" = 1 ] && dump_stats
1531718eb44eSGeliang Tang}
1532718eb44eSGeliang Tang
15337d1e6f16SPaolo Abenichk_link_usage()
15347d1e6f16SPaolo Abeni{
15357d1e6f16SPaolo Abeni	local ns=$1
15367d1e6f16SPaolo Abeni	local link=$2
15377d1e6f16SPaolo Abeni	local out=$3
15387d1e6f16SPaolo Abeni	local expected_rate=$4
15394bfadd71SMatthieu Baerts
15404bfadd71SMatthieu Baerts	local tx_link tx_total
15414bfadd71SMatthieu Baerts	tx_link=$(ip netns exec $ns cat /sys/class/net/$link/statistics/tx_bytes)
1542d8d08302SMatthieu Baerts	tx_total=$(stat --format=%s $out)
1543d8d08302SMatthieu Baerts	local tx_rate=$((tx_link * 100 / tx_total))
15447d1e6f16SPaolo Abeni	local tolerance=5
15457d1e6f16SPaolo Abeni
15469a0a9367SGeliang Tang	printf "%-${nr_blank}s %-18s" " " "link usage"
1547d8d08302SMatthieu Baerts	if [ $tx_rate -lt $((expected_rate - tolerance)) ] || \
1548d8d08302SMatthieu Baerts	   [ $tx_rate -gt $((expected_rate + tolerance)) ]; then
15497d1e6f16SPaolo Abeni		echo "[fail] got $tx_rate% usage, expected $expected_rate%"
155039aab882SMatthieu Baerts		fail_test
15517d1e6f16SPaolo Abeni	else
15527d1e6f16SPaolo Abeni		echo "[ ok ]"
15537d1e6f16SPaolo Abeni	fi
15547d1e6f16SPaolo Abeni}
15557d1e6f16SPaolo Abeni
1556f98c2bcaSMat Martineauwait_attempt_fail()
155746e967d1SPaolo Abeni{
155846e967d1SPaolo Abeni	local timeout_ms=$((timeout_poll * 1000))
155946e967d1SPaolo Abeni	local time=0
156046e967d1SPaolo Abeni	local ns=$1
156146e967d1SPaolo Abeni
156246e967d1SPaolo Abeni	while [ $time -lt $timeout_ms ]; do
15631e777bd8SMatthieu Baerts		local cnt
15641e777bd8SMatthieu Baerts
15651e777bd8SMatthieu Baerts		cnt=$(ip netns exec $ns nstat -as TcpAttemptFails | grep TcpAttemptFails | awk '{print $2}')
156646e967d1SPaolo Abeni
156746e967d1SPaolo Abeni		[ "$cnt" = 1 ] && return 1
156846e967d1SPaolo Abeni		time=$((time + 100))
156946e967d1SPaolo Abeni		sleep 0.1
157046e967d1SPaolo Abeni	done
157146e967d1SPaolo Abeni	return 1
157246e967d1SPaolo Abeni}
157346e967d1SPaolo Abeni
15741002b89fSGeliang Tangsubflows_tests()
15751002b89fSGeliang Tang{
1576c7d49c03SMatthieu Baerts	if reset "no JOIN"; then
1577b08fbf24SPaolo Abeni		run_tests $ns1 $ns2 10.0.1.1
1578c7d49c03SMatthieu Baerts		chk_join_nr 0 0 0
1579ae7bd9ccSMatthieu Baerts	fi
1580b08fbf24SPaolo Abeni
15811002b89fSGeliang Tang	# subflow limited by client
1582c7d49c03SMatthieu Baerts	if reset "single subflow, limited by client"; then
158334aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 0 0
158434aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 0 0
158534aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
1586b08fbf24SPaolo Abeni		run_tests $ns1 $ns2 10.0.1.1
1587c7d49c03SMatthieu Baerts		chk_join_nr 0 0 0
1588ae7bd9ccSMatthieu Baerts	fi
1589b08fbf24SPaolo Abeni
15901002b89fSGeliang Tang	# subflow limited by server
1591c7d49c03SMatthieu Baerts	if reset "single subflow, limited by server"; then
159234aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 0 0
159334aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 0 1
159434aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
1595b08fbf24SPaolo Abeni		run_tests $ns1 $ns2 10.0.1.1
1596c7d49c03SMatthieu Baerts		chk_join_nr 1 1 0
1597ae7bd9ccSMatthieu Baerts	fi
1598b08fbf24SPaolo Abeni
1599b08fbf24SPaolo Abeni	# subflow
1600c7d49c03SMatthieu Baerts	if reset "single subflow"; then
160134aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 0 1
160234aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 0 1
160334aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
1604b08fbf24SPaolo Abeni		run_tests $ns1 $ns2 10.0.1.1
1605c7d49c03SMatthieu Baerts		chk_join_nr 1 1 1
1606ae7bd9ccSMatthieu Baerts	fi
1607b08fbf24SPaolo Abeni
1608b08fbf24SPaolo Abeni	# multiple subflows
1609c7d49c03SMatthieu Baerts	if reset "multiple subflows"; then
161034aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 0 2
161134aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 0 2
161234aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
161334aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow
1614b08fbf24SPaolo Abeni		run_tests $ns1 $ns2 10.0.1.1
1615c7d49c03SMatthieu Baerts		chk_join_nr 2 2 2
1616ae7bd9ccSMatthieu Baerts	fi
1617b08fbf24SPaolo Abeni
161872bcbc46SPaolo Abeni	# multiple subflows limited by server
1619c7d49c03SMatthieu Baerts	if reset "multiple subflows, limited by server"; then
162034aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 0 1
162134aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 0 2
162234aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
162334aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow
1624b08fbf24SPaolo Abeni		run_tests $ns1 $ns2 10.0.1.1
1625c7d49c03SMatthieu Baerts		chk_join_nr 2 2 1
1626ae7bd9ccSMatthieu Baerts	fi
1627c3eaa5f6SGeliang Tang
1628c3eaa5f6SGeliang Tang	# single subflow, dev
1629c7d49c03SMatthieu Baerts	if reset "single subflow, dev"; then
163034aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 0 1
163134aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 0 1
163234aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow dev ns2eth3
1633c3eaa5f6SGeliang Tang		run_tests $ns1 $ns2 10.0.1.1
1634c7d49c03SMatthieu Baerts		chk_join_nr 1 1 1
1635ae7bd9ccSMatthieu Baerts	fi
16361002b89fSGeliang Tang}
1637b08fbf24SPaolo Abeni
163846e967d1SPaolo Abenisubflows_error_tests()
163946e967d1SPaolo Abeni{
164046e967d1SPaolo Abeni	# If a single subflow is configured, and matches the MPC src
164146e967d1SPaolo Abeni	# address, no additional subflow should be created
1642c7d49c03SMatthieu Baerts	if reset "no MPC reuse with single endpoint"; then
164334aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 0 1
164434aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 0 1
164534aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns2 10.0.1.2 flags subflow
164646e967d1SPaolo Abeni		run_tests $ns1 $ns2 10.0.1.1 0 0 0 slow
1647c7d49c03SMatthieu Baerts		chk_join_nr 0 0 0
1648ae7bd9ccSMatthieu Baerts	fi
164946e967d1SPaolo Abeni
165046e967d1SPaolo Abeni	# multiple subflows, with subflow creation error
1651c7d49c03SMatthieu Baerts	if reset "multi subflows, with failing subflow"; then
165234aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 0 2
165334aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 0 2
165434aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
165534aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow
16563469d72fSMatthieu Baerts		filter_tcp_from $ns1 10.0.3.2 REJECT
165746e967d1SPaolo Abeni		run_tests $ns1 $ns2 10.0.1.1 0 0 0 slow
1658c7d49c03SMatthieu Baerts		chk_join_nr 1 1 1
1659ae7bd9ccSMatthieu Baerts	fi
166046e967d1SPaolo Abeni
166146e967d1SPaolo Abeni	# multiple subflows, with subflow timeout on MPJ
1662c7d49c03SMatthieu Baerts	if reset "multi subflows, with subflow timeout"; then
166334aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 0 2
166434aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 0 2
166534aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
166634aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow
16673469d72fSMatthieu Baerts		filter_tcp_from $ns1 10.0.3.2 DROP
166846e967d1SPaolo Abeni		run_tests $ns1 $ns2 10.0.1.1 0 0 0 slow
1669c7d49c03SMatthieu Baerts		chk_join_nr 1 1 1
1670ae7bd9ccSMatthieu Baerts	fi
167146e967d1SPaolo Abeni
167246e967d1SPaolo Abeni	# multiple subflows, check that the endpoint corresponding to
167346e967d1SPaolo Abeni	# closed subflow (due to reset) is not reused if additional
167446e967d1SPaolo Abeni	# subflows are added later
1675c7d49c03SMatthieu Baerts	if reset "multi subflows, fair usage on close"; then
167634aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 0 1
167734aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 0 1
167834aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
16793469d72fSMatthieu Baerts		filter_tcp_from $ns1 10.0.3.2 REJECT
168046e967d1SPaolo Abeni		run_tests $ns1 $ns2 10.0.1.1 0 0 0 slow &
168146e967d1SPaolo Abeni
168246e967d1SPaolo Abeni		# mpj subflow will be in TW after the reset
1683f98c2bcaSMat Martineau		wait_attempt_fail $ns2
168434aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow
168546e967d1SPaolo Abeni		wait
168646e967d1SPaolo Abeni
168746e967d1SPaolo Abeni		# additional subflow could be created only if the PM select
168846e967d1SPaolo Abeni		# the later endpoint, skipping the already used one
1689c7d49c03SMatthieu Baerts		chk_join_nr 1 1 1
1690ae7bd9ccSMatthieu Baerts	fi
169146e967d1SPaolo Abeni}
169246e967d1SPaolo Abeni
16931002b89fSGeliang Tangsignal_address_tests()
16941002b89fSGeliang Tang{
1695b08fbf24SPaolo Abeni	# add_address, unused
1696c7d49c03SMatthieu Baerts	if reset "unused signal address"; then
169734aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
1698b08fbf24SPaolo Abeni		run_tests $ns1 $ns2 10.0.1.1
1699c7d49c03SMatthieu Baerts		chk_join_nr 0 0 0
1700be613160SGeliang Tang		chk_add_nr 1 1
1701ae7bd9ccSMatthieu Baerts	fi
1702b08fbf24SPaolo Abeni
1703b08fbf24SPaolo Abeni	# accept and use add_addr
1704c7d49c03SMatthieu Baerts	if reset "signal address"; then
170534aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 0 1
170634aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 1 1
170734aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
1708b08fbf24SPaolo Abeni		run_tests $ns1 $ns2 10.0.1.1
1709c7d49c03SMatthieu Baerts		chk_join_nr 1 1 1
1710be613160SGeliang Tang		chk_add_nr 1 1
1711ae7bd9ccSMatthieu Baerts	fi
1712b08fbf24SPaolo Abeni
1713b08fbf24SPaolo Abeni	# accept and use add_addr with an additional subflow
1714b08fbf24SPaolo Abeni	# note: signal address in server ns and local addresses in client ns must
1715b08fbf24SPaolo Abeni	# belong to different subnets or one of the listed local address could be
1716b08fbf24SPaolo Abeni	# used for 'add_addr' subflow
1717c7d49c03SMatthieu Baerts	if reset "subflow and signal"; then
171834aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
171934aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 0 2
172034aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 1 2
172134aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
1722b08fbf24SPaolo Abeni		run_tests $ns1 $ns2 10.0.1.1
1723c7d49c03SMatthieu Baerts		chk_join_nr 2 2 2
1724be613160SGeliang Tang		chk_add_nr 1 1
1725ae7bd9ccSMatthieu Baerts	fi
1726b08fbf24SPaolo Abeni
1727b08fbf24SPaolo Abeni	# accept and use add_addr with additional subflows
1728c7d49c03SMatthieu Baerts	if reset "multiple subflows and signal"; then
172934aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 0 3
173034aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
173134aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 1 3
173234aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
173334aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns2 10.0.4.2 flags subflow
1734b08fbf24SPaolo Abeni		run_tests $ns1 $ns2 10.0.1.1
1735c7d49c03SMatthieu Baerts		chk_join_nr 3 3 3
1736be613160SGeliang Tang		chk_add_nr 1 1
1737ae7bd9ccSMatthieu Baerts	fi
1738ef360019SGeliang Tang
1739ef360019SGeliang Tang	# signal addresses
1740c7d49c03SMatthieu Baerts	if reset "signal addresses"; then
174134aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 3 3
174234aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
174334aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 10.0.3.1 flags signal
174434aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 10.0.4.1 flags signal
174534aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 3 3
1746ef360019SGeliang Tang		run_tests $ns1 $ns2 10.0.1.1
1747c7d49c03SMatthieu Baerts		chk_join_nr 3 3 3
1748ef360019SGeliang Tang		chk_add_nr 3 3
1749ae7bd9ccSMatthieu Baerts	fi
1750ef360019SGeliang Tang
1751ef360019SGeliang Tang	# signal invalid addresses
1752c7d49c03SMatthieu Baerts	if reset "signal invalid addresses"; then
175334aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 3 3
175434aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 10.0.12.1 flags signal
175534aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 10.0.3.1 flags signal
175634aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 10.0.14.1 flags signal
175734aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 3 3
1758ef360019SGeliang Tang		run_tests $ns1 $ns2 10.0.1.1
1759c7d49c03SMatthieu Baerts		chk_join_nr 1 1 1
1760ef360019SGeliang Tang		chk_add_nr 3 3
1761ae7bd9ccSMatthieu Baerts	fi
176233c563adSYonglong Li
176333c563adSYonglong Li	# signal addresses race test
1764c7d49c03SMatthieu Baerts	if reset "signal addresses race test"; then
176534aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 4 4
176634aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 4 4
176734aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 10.0.1.1 flags signal
176834aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
176934aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 10.0.3.1 flags signal
177034aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 10.0.4.1 flags signal
177134aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns2 10.0.1.2 flags signal
177234aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns2 10.0.2.2 flags signal
177334aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns2 10.0.3.2 flags signal
177434aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns2 10.0.4.2 flags signal
17756ef84b15SPaolo Abeni
17766ef84b15SPaolo Abeni		# the peer could possibly miss some addr notification, allow retransmission
17776ef84b15SPaolo Abeni		ip netns exec $ns1 sysctl -q net.mptcp.add_addr_timeout=1
17786ef84b15SPaolo Abeni		run_tests $ns1 $ns2 10.0.1.1 0 0 0 slow
1779c7d49c03SMatthieu Baerts		chk_join_nr 3 3 3
178086e39e04SPaolo Abeni
178186e39e04SPaolo Abeni		# the server will not signal the address terminating
178286e39e04SPaolo Abeni		# the MPC subflow
178386e39e04SPaolo Abeni		chk_add_nr 3 3
1784ae7bd9ccSMatthieu Baerts	fi
17851002b89fSGeliang Tang}
1786b08fbf24SPaolo Abeni
17871002b89fSGeliang Tanglink_failure_tests()
17881002b89fSGeliang Tang{
17898b819a84SFlorian Westphal	# accept and use add_addr with additional subflows and link loss
1790c7d49c03SMatthieu Baerts	if reset "multiple flows, signal, link failure"; then
17917d1e6f16SPaolo Abeni		# without any b/w limit each veth could spool the packets and get
17927d1e6f16SPaolo Abeni		# them acked at xmit time, so that the corresponding subflow will
17937d1e6f16SPaolo Abeni		# have almost always no outstanding pkts, the scheduler will pick
17947d1e6f16SPaolo Abeni		# always the first subflow and we will have hard time testing
17957d1e6f16SPaolo Abeni		# active backup and link switch-over.
17967d1e6f16SPaolo Abeni		# Let's set some arbitrary (low) virtual link limits.
17977d1e6f16SPaolo Abeni		init_shapers
179834aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 0 3
179934aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 10.0.2.1 dev ns1eth2 flags signal
180034aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 1 3
180134aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns2 10.0.3.2 dev ns2eth3 flags subflow
180234aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns2 10.0.4.2 dev ns2eth4 flags subflow
18038b819a84SFlorian Westphal		run_tests $ns1 $ns2 10.0.1.1 1
1804c7d49c03SMatthieu Baerts		chk_join_nr 3 3 3
18058b819a84SFlorian Westphal		chk_add_nr 1 1
18067d1e6f16SPaolo Abeni		chk_stale_nr $ns2 1 5 1
1807ae7bd9ccSMatthieu Baerts	fi
18087d1e6f16SPaolo Abeni
18097d1e6f16SPaolo Abeni	# accept and use add_addr with additional subflows and link loss
18107d1e6f16SPaolo Abeni	# for bidirectional transfer
1811c7d49c03SMatthieu Baerts	if reset "multi flows, signal, bidi, link fail"; then
18127d1e6f16SPaolo Abeni		init_shapers
181334aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 0 3
181434aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 10.0.2.1 dev ns1eth2 flags signal
181534aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 1 3
181634aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns2 10.0.3.2 dev ns2eth3 flags subflow
181734aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns2 10.0.4.2 dev ns2eth4 flags subflow
18187d1e6f16SPaolo Abeni		run_tests $ns1 $ns2 10.0.1.1 2
1819c7d49c03SMatthieu Baerts		chk_join_nr 3 3 3
18207d1e6f16SPaolo Abeni		chk_add_nr 1 1
18217d1e6f16SPaolo Abeni		chk_stale_nr $ns2 1 -1 1
1822ae7bd9ccSMatthieu Baerts	fi
18237d1e6f16SPaolo Abeni
18247d1e6f16SPaolo Abeni	# 2 subflows plus 1 backup subflow with a lossy link, backup
18257d1e6f16SPaolo Abeni	# will never be used
1826c7d49c03SMatthieu Baerts	if reset "backup subflow unused, link failure"; then
18277d1e6f16SPaolo Abeni		init_shapers
182834aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 0 2
182934aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 10.0.2.1 dev ns1eth2 flags signal
183034aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 1 2
1831e59300ceSMatthieu Baerts		FAILING_LINKS="1"
183234aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns2 10.0.3.2 dev ns2eth3 flags subflow,backup
18337d1e6f16SPaolo Abeni		run_tests $ns1 $ns2 10.0.1.1 1
1834c7d49c03SMatthieu Baerts		chk_join_nr 2 2 2
18357d1e6f16SPaolo Abeni		chk_add_nr 1 1
18367d1e6f16SPaolo Abeni		chk_link_usage $ns2 ns2eth3 $cinsent 0
1837ae7bd9ccSMatthieu Baerts	fi
18387d1e6f16SPaolo Abeni
18397d1e6f16SPaolo Abeni	# 2 lossy links after half transfer, backup will get half of
18407d1e6f16SPaolo Abeni	# the traffic
1841c7d49c03SMatthieu Baerts	if reset "backup flow used, multi links fail"; then
18427d1e6f16SPaolo Abeni		init_shapers
184334aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 0 2
184434aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 10.0.2.1 dev ns1eth2 flags signal
184534aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 1 2
184634aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns2 10.0.3.2 dev ns2eth3 flags subflow,backup
1847e59300ceSMatthieu Baerts		FAILING_LINKS="1 2"
18487d1e6f16SPaolo Abeni		run_tests $ns1 $ns2 10.0.1.1 1
1849c7d49c03SMatthieu Baerts		chk_join_nr 2 2 2
18507d1e6f16SPaolo Abeni		chk_add_nr 1 1
18517d1e6f16SPaolo Abeni		chk_stale_nr $ns2 2 4 2
18527d1e6f16SPaolo Abeni		chk_link_usage $ns2 ns2eth3 $cinsent 50
1853ae7bd9ccSMatthieu Baerts	fi
18547d1e6f16SPaolo Abeni
18557d1e6f16SPaolo Abeni	# use a backup subflow with the first subflow on a lossy link
18567d1e6f16SPaolo Abeni	# for bidirectional transfer
1857c7d49c03SMatthieu Baerts	if reset "backup flow used, bidi, link failure"; then
18587d1e6f16SPaolo Abeni		init_shapers
185934aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 0 2
186034aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 10.0.2.1 dev ns1eth2 flags signal
186134aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 1 3
186234aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns2 10.0.3.2 dev ns2eth3 flags subflow,backup
1863e59300ceSMatthieu Baerts		FAILING_LINKS="1 2"
18647d1e6f16SPaolo Abeni		run_tests $ns1 $ns2 10.0.1.1 2
1865c7d49c03SMatthieu Baerts		chk_join_nr 2 2 2
18667d1e6f16SPaolo Abeni		chk_add_nr 1 1
18677d1e6f16SPaolo Abeni		chk_stale_nr $ns2 1 -1 2
18687d1e6f16SPaolo Abeni		chk_link_usage $ns2 ns2eth3 $cinsent 50
1869ae7bd9ccSMatthieu Baerts	fi
18701002b89fSGeliang Tang}
18718b819a84SFlorian Westphal
18721002b89fSGeliang Tangadd_addr_timeout_tests()
18731002b89fSGeliang Tang{
18748d014eaaSGeliang Tang	# add_addr timeout
1875c7d49c03SMatthieu Baerts	if reset_with_add_addr_timeout "signal address, ADD_ADDR timeout"; then
187634aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 0 1
187734aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 1 1
187834aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
18798b819a84SFlorian Westphal		run_tests $ns1 $ns2 10.0.1.1 0 0 0 slow
1880c7d49c03SMatthieu Baerts		chk_join_nr 1 1 1
18818d014eaaSGeliang Tang		chk_add_nr 4 0
1882ae7bd9ccSMatthieu Baerts	fi
18838d014eaaSGeliang Tang
18841002b89fSGeliang Tang	# add_addr timeout IPv6
1885c7d49c03SMatthieu Baerts	if reset_with_add_addr_timeout "signal address, ADD_ADDR6 timeout" 6; then
188634aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 0 1
188734aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 1 1
188834aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 dead:beef:2::1 flags signal
18891002b89fSGeliang Tang		run_tests $ns1 $ns2 dead:beef:1::1 0 0 0 slow
1890c7d49c03SMatthieu Baerts		chk_join_nr 1 1 1
18911002b89fSGeliang Tang		chk_add_nr 4 0
1892ae7bd9ccSMatthieu Baerts	fi
18938da6229bSGeliang Tang
18948da6229bSGeliang Tang	# signal addresses timeout
1895c7d49c03SMatthieu Baerts	if reset_with_add_addr_timeout "signal addresses, ADD_ADDR timeout"; then
189634aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 2 2
189734aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
189834aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 10.0.3.1 flags signal
189934aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 2 2
1900cbfafac4SGeliang Tang		run_tests $ns1 $ns2 10.0.1.1 0 0 0 speed_10
1901c7d49c03SMatthieu Baerts		chk_join_nr 2 2 2
19028da6229bSGeliang Tang		chk_add_nr 8 0
1903ae7bd9ccSMatthieu Baerts	fi
19048da6229bSGeliang Tang
19058da6229bSGeliang Tang	# signal invalid addresses timeout
1906c7d49c03SMatthieu Baerts	if reset_with_add_addr_timeout "invalid address, ADD_ADDR timeout"; then
190734aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 2 2
190834aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 10.0.12.1 flags signal
190934aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 10.0.3.1 flags signal
191034aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 2 2
1911cbfafac4SGeliang Tang		run_tests $ns1 $ns2 10.0.1.1 0 0 0 speed_10
1912c7d49c03SMatthieu Baerts		chk_join_nr 1 1 1
19138da6229bSGeliang Tang		chk_add_nr 8 0
1914ae7bd9ccSMatthieu Baerts	fi
19151002b89fSGeliang Tang}
19161002b89fSGeliang Tang
19171002b89fSGeliang Tangremove_tests()
19181002b89fSGeliang Tang{
1919dd72b0feSGeliang Tang	# single subflow, remove
1920c7d49c03SMatthieu Baerts	if reset "remove single subflow"; then
192134aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 0 1
192234aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 0 1
192334aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
19242e8cbf45SGeliang Tang		run_tests $ns1 $ns2 10.0.1.1 0 0 -1 slow
1925c7d49c03SMatthieu Baerts		chk_join_nr 1 1 1
1926dd72b0feSGeliang Tang		chk_rm_nr 1 1
1927ae7bd9ccSMatthieu Baerts	fi
1928dd72b0feSGeliang Tang
1929dd72b0feSGeliang Tang	# multiple subflows, remove
1930c7d49c03SMatthieu Baerts	if reset "remove multiple subflows"; then
193134aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 0 2
193234aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 0 2
193334aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow
193434aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
19352e8cbf45SGeliang Tang		run_tests $ns1 $ns2 10.0.1.1 0 0 -2 slow
1936c7d49c03SMatthieu Baerts		chk_join_nr 2 2 2
1937dd72b0feSGeliang Tang		chk_rm_nr 2 2
1938ae7bd9ccSMatthieu Baerts	fi
1939dd72b0feSGeliang Tang
1940dd72b0feSGeliang Tang	# single address, remove
1941c7d49c03SMatthieu Baerts	if reset "remove single address"; then
194234aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 0 1
194334aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
194434aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 1 1
19452e8cbf45SGeliang Tang		run_tests $ns1 $ns2 10.0.1.1 0 -1 0 slow
1946c7d49c03SMatthieu Baerts		chk_join_nr 1 1 1
1947dd72b0feSGeliang Tang		chk_add_nr 1 1
19487028ba8aSGeliang Tang		chk_rm_nr 1 1 invert
1949ae7bd9ccSMatthieu Baerts	fi
1950dd72b0feSGeliang Tang
1951dd72b0feSGeliang Tang	# subflow and signal, remove
1952c7d49c03SMatthieu Baerts	if reset "remove subflow and signal"; then
195334aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 0 2
195434aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
195534aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 1 2
195634aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
19572e8cbf45SGeliang Tang		run_tests $ns1 $ns2 10.0.1.1 0 -1 -1 slow
1958c7d49c03SMatthieu Baerts		chk_join_nr 2 2 2
1959dd72b0feSGeliang Tang		chk_add_nr 1 1
1960dd72b0feSGeliang Tang		chk_rm_nr 1 1
1961ae7bd9ccSMatthieu Baerts	fi
1962dd72b0feSGeliang Tang
1963dd72b0feSGeliang Tang	# subflows and signal, remove
1964c7d49c03SMatthieu Baerts	if reset "remove subflows and signal"; then
196534aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 0 3
196634aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
196734aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 1 3
196834aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
196934aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns2 10.0.4.2 flags subflow
19702e8cbf45SGeliang Tang		run_tests $ns1 $ns2 10.0.1.1 0 -1 -2 slow
1971c7d49c03SMatthieu Baerts		chk_join_nr 3 3 3
1972dd72b0feSGeliang Tang		chk_add_nr 1 1
1973dd72b0feSGeliang Tang		chk_rm_nr 2 2
1974ae7bd9ccSMatthieu Baerts	fi
1975dd72b0feSGeliang Tang
1976ef360019SGeliang Tang	# addresses remove
1977c7d49c03SMatthieu Baerts	if reset "remove addresses"; then
197834aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 3 3
197934aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal id 250
198034aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 10.0.3.1 flags signal
198134aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 10.0.4.1 flags signal
198234aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 3 3
1983ef360019SGeliang Tang		run_tests $ns1 $ns2 10.0.1.1 0 -3 0 slow
1984c7d49c03SMatthieu Baerts		chk_join_nr 3 3 3
1985ef360019SGeliang Tang		chk_add_nr 3 3
1986ef360019SGeliang Tang		chk_rm_nr 3 3 invert
1987ae7bd9ccSMatthieu Baerts	fi
1988ef360019SGeliang Tang
1989ef360019SGeliang Tang	# invalid addresses remove
1990c7d49c03SMatthieu Baerts	if reset "remove invalid addresses"; then
199134aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 3 3
199234aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 10.0.12.1 flags signal
199334aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 10.0.3.1 flags signal
199434aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 10.0.14.1 flags signal
199534aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 3 3
1996ef360019SGeliang Tang		run_tests $ns1 $ns2 10.0.1.1 0 -3 0 slow
1997c7d49c03SMatthieu Baerts		chk_join_nr 1 1 1
1998ef360019SGeliang Tang		chk_add_nr 3 3
1999ef360019SGeliang Tang		chk_rm_nr 3 1 invert
2000ae7bd9ccSMatthieu Baerts	fi
2001ef360019SGeliang Tang
20026fe4ccdcSGeliang Tang	# subflows and signal, flush
2003c7d49c03SMatthieu Baerts	if reset "flush subflows and signal"; then
200434aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 0 3
200534aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
200634aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 1 3
200734aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
200834aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns2 10.0.4.2 flags subflow
20092e8cbf45SGeliang Tang		run_tests $ns1 $ns2 10.0.1.1 0 -8 -8 slow
2010c7d49c03SMatthieu Baerts		chk_join_nr 3 3 3
20116fe4ccdcSGeliang Tang		chk_add_nr 1 1
20126fa0174aSPaolo Abeni		chk_rm_nr 1 3 invert simult
2013ae7bd9ccSMatthieu Baerts	fi
2014d2c4333aSGeliang Tang
2015d2c4333aSGeliang Tang	# subflows flush
2016c7d49c03SMatthieu Baerts	if reset "flush subflows"; then
201734aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 3 3
201834aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 3 3
201934aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow id 150
202034aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
202134aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns2 10.0.4.2 flags subflow
2022d2c4333aSGeliang Tang		run_tests $ns1 $ns2 10.0.1.1 0 -8 -8 slow
2023c7d49c03SMatthieu Baerts		chk_join_nr 3 3 3
20246fa0174aSPaolo Abeni		chk_rm_nr 0 3 simult
2025ae7bd9ccSMatthieu Baerts	fi
2026d2c4333aSGeliang Tang
2027d2c4333aSGeliang Tang	# addresses flush
2028c7d49c03SMatthieu Baerts	if reset "flush addresses"; then
202934aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 3 3
203034aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal id 250
203134aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 10.0.3.1 flags signal
203234aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 10.0.4.1 flags signal
203334aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 3 3
2034d2c4333aSGeliang Tang		run_tests $ns1 $ns2 10.0.1.1 0 -8 -8 slow
2035c7d49c03SMatthieu Baerts		chk_join_nr 3 3 3
2036d2c4333aSGeliang Tang		chk_add_nr 3 3
20376fa0174aSPaolo Abeni		chk_rm_nr 3 3 invert simult
2038ae7bd9ccSMatthieu Baerts	fi
2039ef360019SGeliang Tang
2040ef360019SGeliang Tang	# invalid addresses flush
2041c7d49c03SMatthieu Baerts	if reset "flush invalid addresses"; then
204234aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 3 3
204334aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 10.0.12.1 flags signal
204434aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 10.0.3.1 flags signal
204534aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 10.0.14.1 flags signal
204634aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 3 3
2047ef360019SGeliang Tang		run_tests $ns1 $ns2 10.0.1.1 0 -8 0 slow
2048c7d49c03SMatthieu Baerts		chk_join_nr 1 1 1
2049ef360019SGeliang Tang		chk_add_nr 3 3
2050ef360019SGeliang Tang		chk_rm_nr 3 1 invert
2051ae7bd9ccSMatthieu Baerts	fi
20525e287fe7SGeliang Tang
20535e287fe7SGeliang Tang	# remove id 0 subflow
2054c7d49c03SMatthieu Baerts	if reset "remove id 0 subflow"; then
205534aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 0 1
205634aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 0 1
205734aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
20585e287fe7SGeliang Tang		run_tests $ns1 $ns2 10.0.1.1 0 0 -9 slow
2059c7d49c03SMatthieu Baerts		chk_join_nr 1 1 1
20605e287fe7SGeliang Tang		chk_rm_nr 1 1
2061ae7bd9ccSMatthieu Baerts	fi
20625e287fe7SGeliang Tang
20635e287fe7SGeliang Tang	# remove id 0 address
2064c7d49c03SMatthieu Baerts	if reset "remove id 0 address"; then
206534aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 0 1
206634aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
206734aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 1 1
20685e287fe7SGeliang Tang		run_tests $ns1 $ns2 10.0.1.1 0 -9 0 slow
2069c7d49c03SMatthieu Baerts		chk_join_nr 1 1 1
20705e287fe7SGeliang Tang		chk_add_nr 1 1
20715e287fe7SGeliang Tang		chk_rm_nr 1 1 invert
2072ae7bd9ccSMatthieu Baerts	fi
20731002b89fSGeliang Tang}
20746fe4ccdcSGeliang Tang
20751002b89fSGeliang Tangadd_tests()
20761002b89fSGeliang Tang{
20776208fd82SGeliang Tang	# add single subflow
2078c7d49c03SMatthieu Baerts	if reset "add single subflow"; then
207934aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 0 1
208034aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 0 1
20816208fd82SGeliang Tang		run_tests $ns1 $ns2 10.0.1.1 0 0 1 slow
2082c7d49c03SMatthieu Baerts		chk_join_nr 1 1 1
2083ae7bd9ccSMatthieu Baerts	fi
20846208fd82SGeliang Tang
20856208fd82SGeliang Tang	# add signal address
2086c7d49c03SMatthieu Baerts	if reset "add signal address"; then
208734aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 0 1
208834aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 1 1
20896208fd82SGeliang Tang		run_tests $ns1 $ns2 10.0.1.1 0 1 0 slow
2090c7d49c03SMatthieu Baerts		chk_join_nr 1 1 1
20916208fd82SGeliang Tang		chk_add_nr 1 1
2092ae7bd9ccSMatthieu Baerts	fi
20936208fd82SGeliang Tang
20946208fd82SGeliang Tang	# add multiple subflows
2095c7d49c03SMatthieu Baerts	if reset "add multiple subflows"; then
209634aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 0 2
209734aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 0 2
20986208fd82SGeliang Tang		run_tests $ns1 $ns2 10.0.1.1 0 0 2 slow
2099c7d49c03SMatthieu Baerts		chk_join_nr 2 2 2
2100ae7bd9ccSMatthieu Baerts	fi
21016208fd82SGeliang Tang
21026208fd82SGeliang Tang	# add multiple subflows IPv6
2103c7d49c03SMatthieu Baerts	if reset "add multiple subflows IPv6"; then
210434aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 0 2
210534aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 0 2
21066208fd82SGeliang Tang		run_tests $ns1 $ns2 dead:beef:1::1 0 0 2 slow
2107c7d49c03SMatthieu Baerts		chk_join_nr 2 2 2
2108ae7bd9ccSMatthieu Baerts	fi
21096208fd82SGeliang Tang
21106208fd82SGeliang Tang	# add multiple addresses IPv6
2111c7d49c03SMatthieu Baerts	if reset "add multiple addresses IPv6"; then
211234aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 0 2
211334aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 2 2
21146208fd82SGeliang Tang		run_tests $ns1 $ns2 dead:beef:1::1 0 2 0 slow
2115c7d49c03SMatthieu Baerts		chk_join_nr 2 2 2
21166208fd82SGeliang Tang		chk_add_nr 2 2
2117ae7bd9ccSMatthieu Baerts	fi
21181002b89fSGeliang Tang}
21196208fd82SGeliang Tang
21201002b89fSGeliang Tangipv6_tests()
21211002b89fSGeliang Tang{
2122523514edSGeliang Tang	# subflow IPv6
2123c7d49c03SMatthieu Baerts	if reset "single subflow IPv6"; then
212434aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 0 1
212534aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 0 1
212634aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns2 dead:beef:3::2 dev ns2eth3 flags subflow
2127523514edSGeliang Tang		run_tests $ns1 $ns2 dead:beef:1::1 0 0 0 slow
2128c7d49c03SMatthieu Baerts		chk_join_nr 1 1 1
2129ae7bd9ccSMatthieu Baerts	fi
2130523514edSGeliang Tang
2131523514edSGeliang Tang	# add_address, unused IPv6
2132c7d49c03SMatthieu Baerts	if reset "unused signal address IPv6"; then
213334aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 dead:beef:2::1 flags signal
2134523514edSGeliang Tang		run_tests $ns1 $ns2 dead:beef:1::1 0 0 0 slow
2135c7d49c03SMatthieu Baerts		chk_join_nr 0 0 0
2136523514edSGeliang Tang		chk_add_nr 1 1
2137ae7bd9ccSMatthieu Baerts	fi
2138523514edSGeliang Tang
2139523514edSGeliang Tang	# signal address IPv6
2140c7d49c03SMatthieu Baerts	if reset "single address IPv6"; then
214134aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 0 1
214234aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 dead:beef:2::1 flags signal
214334aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 1 1
2144523514edSGeliang Tang		run_tests $ns1 $ns2 dead:beef:1::1 0 0 0 slow
2145c7d49c03SMatthieu Baerts		chk_join_nr 1 1 1
2146523514edSGeliang Tang		chk_add_nr 1 1
2147ae7bd9ccSMatthieu Baerts	fi
2148523514edSGeliang Tang
2149523514edSGeliang Tang	# single address IPv6, remove
2150c7d49c03SMatthieu Baerts	if reset "remove single address IPv6"; then
215134aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 0 1
215234aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 dead:beef:2::1 flags signal
215334aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 1 1
21542e8cbf45SGeliang Tang		run_tests $ns1 $ns2 dead:beef:1::1 0 -1 0 slow
2155c7d49c03SMatthieu Baerts		chk_join_nr 1 1 1
2156523514edSGeliang Tang		chk_add_nr 1 1
21577028ba8aSGeliang Tang		chk_rm_nr 1 1 invert
2158ae7bd9ccSMatthieu Baerts	fi
2159523514edSGeliang Tang
2160523514edSGeliang Tang	# subflow and signal IPv6, remove
2161c7d49c03SMatthieu Baerts	if reset "remove subflow and signal IPv6"; then
216234aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 0 2
216334aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 dead:beef:2::1 flags signal
216434aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 1 2
216534aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns2 dead:beef:3::2 dev ns2eth3 flags subflow
21662e8cbf45SGeliang Tang		run_tests $ns1 $ns2 dead:beef:1::1 0 -1 -1 slow
2167c7d49c03SMatthieu Baerts		chk_join_nr 2 2 2
2168523514edSGeliang Tang		chk_add_nr 1 1
2169523514edSGeliang Tang		chk_rm_nr 1 1
2170ae7bd9ccSMatthieu Baerts	fi
21711002b89fSGeliang Tang}
2172523514edSGeliang Tang
21731002b89fSGeliang Tangv4mapped_tests()
21741002b89fSGeliang Tang{
2175a6094788SGeliang Tang	# subflow IPv4-mapped to IPv4-mapped
2176c7d49c03SMatthieu Baerts	if reset "single subflow IPv4-mapped"; then
217734aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 0 1
217834aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 0 1
217934aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns2 "::ffff:10.0.3.2" flags subflow
2180a6094788SGeliang Tang		run_tests $ns1 $ns2 "::ffff:10.0.1.1"
2181c7d49c03SMatthieu Baerts		chk_join_nr 1 1 1
2182ae7bd9ccSMatthieu Baerts	fi
2183a6094788SGeliang Tang
2184a6094788SGeliang Tang	# signal address IPv4-mapped with IPv4-mapped sk
2185c7d49c03SMatthieu Baerts	if reset "signal address IPv4-mapped"; then
218634aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 0 1
218734aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 1 1
218834aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 "::ffff:10.0.2.1" flags signal
2189a6094788SGeliang Tang		run_tests $ns1 $ns2 "::ffff:10.0.1.1"
2190c7d49c03SMatthieu Baerts		chk_join_nr 1 1 1
2191a6094788SGeliang Tang		chk_add_nr 1 1
2192ae7bd9ccSMatthieu Baerts	fi
2193a6094788SGeliang Tang
2194a6094788SGeliang Tang	# subflow v4-map-v6
2195c7d49c03SMatthieu Baerts	if reset "single subflow v4-map-v6"; then
219634aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 0 1
219734aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 0 1
219834aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
2199a6094788SGeliang Tang		run_tests $ns1 $ns2 "::ffff:10.0.1.1"
2200c7d49c03SMatthieu Baerts		chk_join_nr 1 1 1
2201ae7bd9ccSMatthieu Baerts	fi
2202a6094788SGeliang Tang
2203a6094788SGeliang Tang	# signal address v4-map-v6
2204c7d49c03SMatthieu Baerts	if reset "signal address v4-map-v6"; then
220534aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 0 1
220634aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 1 1
220734aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
2208a6094788SGeliang Tang		run_tests $ns1 $ns2 "::ffff:10.0.1.1"
2209c7d49c03SMatthieu Baerts		chk_join_nr 1 1 1
2210a6094788SGeliang Tang		chk_add_nr 1 1
2211ae7bd9ccSMatthieu Baerts	fi
2212a6094788SGeliang Tang
2213a6094788SGeliang Tang	# subflow v6-map-v4
2214c7d49c03SMatthieu Baerts	if reset "single subflow v6-map-v4"; then
221534aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 0 1
221634aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 0 1
221734aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns2 "::ffff:10.0.3.2" flags subflow
2218a6094788SGeliang Tang		run_tests $ns1 $ns2 10.0.1.1
2219c7d49c03SMatthieu Baerts		chk_join_nr 1 1 1
2220ae7bd9ccSMatthieu Baerts	fi
2221a6094788SGeliang Tang
2222a6094788SGeliang Tang	# signal address v6-map-v4
2223c7d49c03SMatthieu Baerts	if reset "signal address v6-map-v4"; then
222434aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 0 1
222534aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 1 1
222634aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 "::ffff:10.0.2.1" flags signal
2227a6094788SGeliang Tang		run_tests $ns1 $ns2 10.0.1.1
2228c7d49c03SMatthieu Baerts		chk_join_nr 1 1 1
2229a6094788SGeliang Tang		chk_add_nr 1 1
2230ae7bd9ccSMatthieu Baerts	fi
2231a6094788SGeliang Tang
2232a6094788SGeliang Tang	# no subflow IPv6 to v4 address
2233c7d49c03SMatthieu Baerts	if reset "no JOIN with diff families v4-v6"; then
223434aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 0 1
223534aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 0 1
223634aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns2 dead:beef:2::2 flags subflow
2237a6094788SGeliang Tang		run_tests $ns1 $ns2 10.0.1.1
2238c7d49c03SMatthieu Baerts		chk_join_nr 0 0 0
2239ae7bd9ccSMatthieu Baerts	fi
2240a6094788SGeliang Tang
2241a6094788SGeliang Tang	# no subflow IPv6 to v4 address even if v6 has a valid v4 at the end
2242c7d49c03SMatthieu Baerts	if reset "no JOIN with diff families v4-v6-2"; then
224334aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 0 1
224434aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 0 1
224534aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns2 dead:beef:2::10.0.3.2 flags subflow
2246a6094788SGeliang Tang		run_tests $ns1 $ns2 10.0.1.1
2247c7d49c03SMatthieu Baerts		chk_join_nr 0 0 0
2248ae7bd9ccSMatthieu Baerts	fi
2249a6094788SGeliang Tang
2250a6094788SGeliang Tang	# no subflow IPv4 to v6 address, no need to slow down too then
2251c7d49c03SMatthieu Baerts	if reset "no JOIN with diff families v6-v4"; then
225234aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 0 1
225334aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 0 1
225434aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
2255a6094788SGeliang Tang		run_tests $ns1 $ns2 dead:beef:1::1
2256c7d49c03SMatthieu Baerts		chk_join_nr 0 0 0
2257ae7bd9ccSMatthieu Baerts	fi
22581002b89fSGeliang Tang}
2259a6094788SGeliang Tang
22601002b89fSGeliang Tangbackup_tests()
22611002b89fSGeliang Tang{
2262718eb44eSGeliang Tang	# single subflow, backup
2263c7d49c03SMatthieu Baerts	if reset "single subflow, backup"; then
226434aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 0 1
226534aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 0 1
226634aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow,backup
2267718eb44eSGeliang Tang		run_tests $ns1 $ns2 10.0.1.1 0 0 0 slow nobackup
2268c7d49c03SMatthieu Baerts		chk_join_nr 1 1 1
2269718eb44eSGeliang Tang		chk_prio_nr 0 1
2270ae7bd9ccSMatthieu Baerts	fi
2271718eb44eSGeliang Tang
2272718eb44eSGeliang Tang	# single address, backup
2273c7d49c03SMatthieu Baerts	if reset "single address, backup"; then
227434aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 0 1
227534aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
227634aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 1 1
2277718eb44eSGeliang Tang		run_tests $ns1 $ns2 10.0.1.1 0 0 0 slow backup
2278c7d49c03SMatthieu Baerts		chk_join_nr 1 1 1
2279718eb44eSGeliang Tang		chk_add_nr 1 1
2280d045b9ebSPaolo Abeni		chk_prio_nr 1 1
2281ae7bd9ccSMatthieu Baerts	fi
228233397b83SGeliang Tang
228333397b83SGeliang Tang	# single address with port, backup
2284c7d49c03SMatthieu Baerts	if reset "single address with port, backup"; then
228534aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 0 1
228634aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal port 10100
228734aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 1 1
228833397b83SGeliang Tang		run_tests $ns1 $ns2 10.0.1.1 0 0 0 slow backup
2289c7d49c03SMatthieu Baerts		chk_join_nr 1 1 1
229033397b83SGeliang Tang		chk_add_nr 1 1
2291d045b9ebSPaolo Abeni		chk_prio_nr 1 1
2292ae7bd9ccSMatthieu Baerts	fi
22931002b89fSGeliang Tang}
2294718eb44eSGeliang Tang
22951002b89fSGeliang Tangadd_addr_ports_tests()
22961002b89fSGeliang Tang{
22978a127bf6SGeliang Tang	# signal address with port
2298c7d49c03SMatthieu Baerts	if reset "signal address with port"; then
229934aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 0 1
230034aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 1 1
230134aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal port 10100
23028a127bf6SGeliang Tang		run_tests $ns1 $ns2 10.0.1.1
2303c7d49c03SMatthieu Baerts		chk_join_nr 1 1 1
23048a127bf6SGeliang Tang		chk_add_nr 1 1 1
2305ae7bd9ccSMatthieu Baerts	fi
23068a127bf6SGeliang Tang
23078a127bf6SGeliang Tang	# subflow and signal with port
2308c7d49c03SMatthieu Baerts	if reset "subflow and signal with port"; then
230934aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal port 10100
231034aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 0 2
231134aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 1 2
231234aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
23138a127bf6SGeliang Tang		run_tests $ns1 $ns2 10.0.1.1
2314c7d49c03SMatthieu Baerts		chk_join_nr 2 2 2
23158a127bf6SGeliang Tang		chk_add_nr 1 1 1
2316ae7bd9ccSMatthieu Baerts	fi
23178a127bf6SGeliang Tang
23188a127bf6SGeliang Tang	# single address with port, remove
2319c7d49c03SMatthieu Baerts	if reset "remove single address with port"; then
232034aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 0 1
232134aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal port 10100
232234aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 1 1
23238a127bf6SGeliang Tang		run_tests $ns1 $ns2 10.0.1.1 0 -1 0 slow
2324c7d49c03SMatthieu Baerts		chk_join_nr 1 1 1
23258a127bf6SGeliang Tang		chk_add_nr 1 1 1
23267028ba8aSGeliang Tang		chk_rm_nr 1 1 invert
2327ae7bd9ccSMatthieu Baerts	fi
23288a127bf6SGeliang Tang
23298a127bf6SGeliang Tang	# subflow and signal with port, remove
2330c7d49c03SMatthieu Baerts	if reset "remove subflow and signal with port"; then
233134aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 0 2
233234aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal port 10100
233334aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 1 2
233434aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
23358a127bf6SGeliang Tang		run_tests $ns1 $ns2 10.0.1.1 0 -1 -1 slow
2336c7d49c03SMatthieu Baerts		chk_join_nr 2 2 2
23378a127bf6SGeliang Tang		chk_add_nr 1 1 1
23388a127bf6SGeliang Tang		chk_rm_nr 1 1
2339ae7bd9ccSMatthieu Baerts	fi
23408a127bf6SGeliang Tang
23418a127bf6SGeliang Tang	# subflows and signal with port, flush
2342c7d49c03SMatthieu Baerts	if reset "flush subflows and signal with port"; then
234334aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 0 3
234434aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal port 10100
234534aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 1 3
234634aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
234734aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns2 10.0.4.2 flags subflow
2348327b9a94SPaolo Abeni		run_tests $ns1 $ns2 10.0.1.1 0 -8 -2 slow
2349c7d49c03SMatthieu Baerts		chk_join_nr 3 3 3
23508a127bf6SGeliang Tang		chk_add_nr 1 1
23516fa0174aSPaolo Abeni		chk_rm_nr 1 3 invert simult
2352ae7bd9ccSMatthieu Baerts	fi
23538a127bf6SGeliang Tang
23548a127bf6SGeliang Tang	# multiple addresses with port
2355c7d49c03SMatthieu Baerts	if reset "multiple addresses with port"; then
235634aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 2 2
235734aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal port 10100
235834aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 10.0.3.1 flags signal port 10100
235934aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 2 2
23608a127bf6SGeliang Tang		run_tests $ns1 $ns2 10.0.1.1
2361c7d49c03SMatthieu Baerts		chk_join_nr 2 2 2
23628a127bf6SGeliang Tang		chk_add_nr 2 2 2
2363ae7bd9ccSMatthieu Baerts	fi
23648a127bf6SGeliang Tang
23658a127bf6SGeliang Tang	# multiple addresses with ports
2366c7d49c03SMatthieu Baerts	if reset "multiple addresses with ports"; then
236734aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 2 2
236834aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal port 10100
236934aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 10.0.3.1 flags signal port 10101
237034aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 2 2
23718a127bf6SGeliang Tang		run_tests $ns1 $ns2 10.0.1.1
2372c7d49c03SMatthieu Baerts		chk_join_nr 2 2 2
23738a127bf6SGeliang Tang		chk_add_nr 2 2 2
2374ae7bd9ccSMatthieu Baerts	fi
23751002b89fSGeliang Tang}
23768a127bf6SGeliang Tang
23771002b89fSGeliang Tangsyncookies_tests()
23781002b89fSGeliang Tang{
237900587187SFlorian Westphal	# single subflow, syncookies
2380c7d49c03SMatthieu Baerts	if reset_with_cookies "single subflow with syn cookies"; then
238134aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 0 1
238234aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 0 1
238334aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
238400587187SFlorian Westphal		run_tests $ns1 $ns2 10.0.1.1
2385c7d49c03SMatthieu Baerts		chk_join_nr 1 1 1
2386ae7bd9ccSMatthieu Baerts	fi
238700587187SFlorian Westphal
238800587187SFlorian Westphal	# multiple subflows with syn cookies
2389c7d49c03SMatthieu Baerts	if reset_with_cookies "multiple subflows with syn cookies"; then
239034aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 0 2
239134aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 0 2
239234aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
239334aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow
239400587187SFlorian Westphal		run_tests $ns1 $ns2 10.0.1.1
2395c7d49c03SMatthieu Baerts		chk_join_nr 2 2 2
2396ae7bd9ccSMatthieu Baerts	fi
239700587187SFlorian Westphal
239800587187SFlorian Westphal	# multiple subflows limited by server
2399c7d49c03SMatthieu Baerts	if reset_with_cookies "subflows limited by server w cookies"; then
240034aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 0 1
240134aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 0 2
240234aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
240334aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow
240400587187SFlorian Westphal		run_tests $ns1 $ns2 10.0.1.1
2405c7d49c03SMatthieu Baerts		chk_join_nr 2 1 1
2406ae7bd9ccSMatthieu Baerts	fi
240700587187SFlorian Westphal
240800587187SFlorian Westphal	# test signal address with cookies
2409c7d49c03SMatthieu Baerts	if reset_with_cookies "signal address with syn cookies"; then
241034aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 0 1
241134aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 1 1
241234aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
241300587187SFlorian Westphal		run_tests $ns1 $ns2 10.0.1.1
2414c7d49c03SMatthieu Baerts		chk_join_nr 1 1 1
2415be613160SGeliang Tang		chk_add_nr 1 1
2416ae7bd9ccSMatthieu Baerts	fi
241700587187SFlorian Westphal
241800587187SFlorian Westphal	# test cookie with subflow and signal
2419c7d49c03SMatthieu Baerts	if reset_with_cookies "subflow and signal w cookies"; then
242034aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
242134aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 0 2
242234aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 1 2
242334aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
242400587187SFlorian Westphal		run_tests $ns1 $ns2 10.0.1.1
2425c7d49c03SMatthieu Baerts		chk_join_nr 2 2 2
2426be613160SGeliang Tang		chk_add_nr 1 1
2427ae7bd9ccSMatthieu Baerts	fi
242800587187SFlorian Westphal
242900587187SFlorian Westphal	# accept and use add_addr with additional subflows
2430c7d49c03SMatthieu Baerts	if reset_with_cookies "subflows and signal w. cookies"; then
243134aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 0 3
243234aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
243334aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 1 3
243434aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
243534aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns2 10.0.4.2 flags subflow
243600587187SFlorian Westphal		run_tests $ns1 $ns2 10.0.1.1
2437c7d49c03SMatthieu Baerts		chk_join_nr 3 3 3
2438be613160SGeliang Tang		chk_add_nr 1 1
2439ae7bd9ccSMatthieu Baerts	fi
24401002b89fSGeliang Tang}
24411002b89fSGeliang Tang
2442af66d3e1SGeliang Tangchecksum_tests()
2443af66d3e1SGeliang Tang{
2444af66d3e1SGeliang Tang	# checksum test 0 0
2445ae7bd9ccSMatthieu Baerts	if reset_with_checksum 0 0; then
244634aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 0 1
244734aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 0 1
2448af66d3e1SGeliang Tang		run_tests $ns1 $ns2 10.0.1.1
2449c7d49c03SMatthieu Baerts		chk_join_nr 0 0 0
2450ae7bd9ccSMatthieu Baerts	fi
2451af66d3e1SGeliang Tang
2452af66d3e1SGeliang Tang	# checksum test 1 1
2453ae7bd9ccSMatthieu Baerts	if reset_with_checksum 1 1; then
245434aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 0 1
245534aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 0 1
2456af66d3e1SGeliang Tang		run_tests $ns1 $ns2 10.0.1.1
2457c7d49c03SMatthieu Baerts		chk_join_nr 0 0 0
2458ae7bd9ccSMatthieu Baerts	fi
2459af66d3e1SGeliang Tang
2460af66d3e1SGeliang Tang	# checksum test 0 1
2461ae7bd9ccSMatthieu Baerts	if reset_with_checksum 0 1; then
246234aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 0 1
246334aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 0 1
2464af66d3e1SGeliang Tang		run_tests $ns1 $ns2 10.0.1.1
2465c7d49c03SMatthieu Baerts		chk_join_nr 0 0 0
2466ae7bd9ccSMatthieu Baerts	fi
2467af66d3e1SGeliang Tang
2468af66d3e1SGeliang Tang	# checksum test 1 0
2469ae7bd9ccSMatthieu Baerts	if reset_with_checksum 1 0; then
247034aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 0 1
247134aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 0 1
2472af66d3e1SGeliang Tang		run_tests $ns1 $ns2 10.0.1.1
2473c7d49c03SMatthieu Baerts		chk_join_nr 0 0 0
2474ae7bd9ccSMatthieu Baerts	fi
2475af66d3e1SGeliang Tang}
2476af66d3e1SGeliang Tang
24770cddb4a6SGeliang Tangdeny_join_id0_tests()
24780cddb4a6SGeliang Tang{
24790cddb4a6SGeliang Tang	# subflow allow join id0 ns1
2480c7d49c03SMatthieu Baerts	if reset_with_allow_join_id0 "single subflow allow join id0 ns1" 1 0; then
248134aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 1 1
248234aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 1 1
248334aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
24840cddb4a6SGeliang Tang		run_tests $ns1 $ns2 10.0.1.1
2485c7d49c03SMatthieu Baerts		chk_join_nr 1 1 1
2486ae7bd9ccSMatthieu Baerts	fi
24870cddb4a6SGeliang Tang
24880cddb4a6SGeliang Tang	# subflow allow join id0 ns2
2489c7d49c03SMatthieu Baerts	if reset_with_allow_join_id0 "single subflow allow join id0 ns2" 0 1; then
249034aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 1 1
249134aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 1 1
249234aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
24930cddb4a6SGeliang Tang		run_tests $ns1 $ns2 10.0.1.1
2494c7d49c03SMatthieu Baerts		chk_join_nr 0 0 0
2495ae7bd9ccSMatthieu Baerts	fi
24960cddb4a6SGeliang Tang
24970cddb4a6SGeliang Tang	# signal address allow join id0 ns1
24980cddb4a6SGeliang Tang	# ADD_ADDRs are not affected by allow_join_id0 value.
2499c7d49c03SMatthieu Baerts	if reset_with_allow_join_id0 "signal address allow join id0 ns1" 1 0; then
250034aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 1 1
250134aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 1 1
250234aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
25030cddb4a6SGeliang Tang		run_tests $ns1 $ns2 10.0.1.1
2504c7d49c03SMatthieu Baerts		chk_join_nr 1 1 1
25050cddb4a6SGeliang Tang		chk_add_nr 1 1
2506ae7bd9ccSMatthieu Baerts	fi
25070cddb4a6SGeliang Tang
25080cddb4a6SGeliang Tang	# signal address allow join id0 ns2
25090cddb4a6SGeliang Tang	# ADD_ADDRs are not affected by allow_join_id0 value.
2510c7d49c03SMatthieu Baerts	if reset_with_allow_join_id0 "signal address allow join id0 ns2" 0 1; then
251134aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 1 1
251234aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 1 1
251334aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
25140cddb4a6SGeliang Tang		run_tests $ns1 $ns2 10.0.1.1
2515c7d49c03SMatthieu Baerts		chk_join_nr 1 1 1
25160cddb4a6SGeliang Tang		chk_add_nr 1 1
2517ae7bd9ccSMatthieu Baerts	fi
25180cddb4a6SGeliang Tang
25190cddb4a6SGeliang Tang	# subflow and address allow join id0 ns1
2520c7d49c03SMatthieu Baerts	if reset_with_allow_join_id0 "subflow and address allow join id0 1" 1 0; then
252134aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 2 2
252234aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 2 2
252334aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
252434aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
25250cddb4a6SGeliang Tang		run_tests $ns1 $ns2 10.0.1.1
2526c7d49c03SMatthieu Baerts		chk_join_nr 2 2 2
2527ae7bd9ccSMatthieu Baerts	fi
25280cddb4a6SGeliang Tang
25290cddb4a6SGeliang Tang	# subflow and address allow join id0 ns2
2530c7d49c03SMatthieu Baerts	if reset_with_allow_join_id0 "subflow and address allow join id0 2" 0 1; then
253134aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 2 2
253234aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 2 2
253334aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
253434aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
25350cddb4a6SGeliang Tang		run_tests $ns1 $ns2 10.0.1.1
2536c7d49c03SMatthieu Baerts		chk_join_nr 1 1 1
2537ae7bd9ccSMatthieu Baerts	fi
25380cddb4a6SGeliang Tang}
25390cddb4a6SGeliang Tang
25404f49d633SGeliang Tangfullmesh_tests()
25414f49d633SGeliang Tang{
25424f49d633SGeliang Tang	# fullmesh 1
25434f49d633SGeliang Tang	# 2 fullmesh addrs in ns2, added before the connection,
25444f49d633SGeliang Tang	# 1 non-fullmesh addr in ns1, added during the connection.
2545c7d49c03SMatthieu Baerts	if reset "fullmesh test 2x1"; then
254634aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 0 4
254734aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 1 4
254834aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow,fullmesh
254934aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow,fullmesh
25504f49d633SGeliang Tang		run_tests $ns1 $ns2 10.0.1.1 0 1 0 slow
2551c7d49c03SMatthieu Baerts		chk_join_nr 4 4 4
25524f49d633SGeliang Tang		chk_add_nr 1 1
2553ae7bd9ccSMatthieu Baerts	fi
25544f49d633SGeliang Tang
25554f49d633SGeliang Tang	# fullmesh 2
25564f49d633SGeliang Tang	# 1 non-fullmesh addr in ns1, added before the connection,
25574f49d633SGeliang Tang	# 1 fullmesh addr in ns2, added during the connection.
2558c7d49c03SMatthieu Baerts	if reset "fullmesh test 1x1"; then
255934aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 1 3
256034aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 1 3
256134aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
25624f49d633SGeliang Tang		run_tests $ns1 $ns2 10.0.1.1 0 0 fullmesh_1 slow
2563c7d49c03SMatthieu Baerts		chk_join_nr 3 3 3
25644f49d633SGeliang Tang		chk_add_nr 1 1
2565ae7bd9ccSMatthieu Baerts	fi
25664f49d633SGeliang Tang
25674f49d633SGeliang Tang	# fullmesh 3
25684f49d633SGeliang Tang	# 1 non-fullmesh addr in ns1, added before the connection,
25694f49d633SGeliang Tang	# 2 fullmesh addrs in ns2, added during the connection.
2570c7d49c03SMatthieu Baerts	if reset "fullmesh test 1x2"; then
257134aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 2 5
257234aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 1 5
257334aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
25744f49d633SGeliang Tang		run_tests $ns1 $ns2 10.0.1.1 0 0 fullmesh_2 slow
2575c7d49c03SMatthieu Baerts		chk_join_nr 5 5 5
25764f49d633SGeliang Tang		chk_add_nr 1 1
2577ae7bd9ccSMatthieu Baerts	fi
25784f49d633SGeliang Tang
25794f49d633SGeliang Tang	# fullmesh 4
25804f49d633SGeliang Tang	# 1 non-fullmesh addr in ns1, added before the connection,
25814f49d633SGeliang Tang	# 2 fullmesh addrs in ns2, added during the connection,
25824f49d633SGeliang Tang	# limit max_subflows to 4.
2583c7d49c03SMatthieu Baerts	if reset "fullmesh test 1x2, limited"; then
258434aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 2 4
258534aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 1 4
258634aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
25874f49d633SGeliang Tang		run_tests $ns1 $ns2 10.0.1.1 0 0 fullmesh_2 slow
2588c7d49c03SMatthieu Baerts		chk_join_nr 4 4 4
25894f49d633SGeliang Tang		chk_add_nr 1 1
2590ae7bd9ccSMatthieu Baerts	fi
25916a0653b9SGeliang Tang
25926a0653b9SGeliang Tang	# set fullmesh flag
2593c7d49c03SMatthieu Baerts	if reset "set fullmesh flag test"; then
259434aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 4 4
259534aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 10.0.2.1 flags subflow
259634aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 4 4
25976a0653b9SGeliang Tang		run_tests $ns1 $ns2 10.0.1.1 0 0 1 slow fullmesh
2598c7d49c03SMatthieu Baerts		chk_join_nr 2 2 2
25996a0653b9SGeliang Tang		chk_rm_nr 0 1
2600ae7bd9ccSMatthieu Baerts	fi
26016a0653b9SGeliang Tang
26026a0653b9SGeliang Tang	# set nofullmesh flag
2603c7d49c03SMatthieu Baerts	if reset "set nofullmesh flag test"; then
260434aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 4 4
260534aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 10.0.2.1 flags subflow,fullmesh
260634aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 4 4
26076a0653b9SGeliang Tang		run_tests $ns1 $ns2 10.0.1.1 0 0 fullmesh_1 slow nofullmesh
2608c7d49c03SMatthieu Baerts		chk_join_nr 2 2 2
26096a0653b9SGeliang Tang		chk_rm_nr 0 1
2610ae7bd9ccSMatthieu Baerts	fi
26116a0653b9SGeliang Tang
26126a0653b9SGeliang Tang	# set backup,fullmesh flags
2613c7d49c03SMatthieu Baerts	if reset "set backup,fullmesh flags test"; then
261434aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 4 4
261534aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns1 10.0.2.1 flags subflow
261634aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 4 4
26176a0653b9SGeliang Tang		run_tests $ns1 $ns2 10.0.1.1 0 0 1 slow backup,fullmesh
2618c7d49c03SMatthieu Baerts		chk_join_nr 2 2 2
26196a0653b9SGeliang Tang		chk_prio_nr 0 1
26206a0653b9SGeliang Tang		chk_rm_nr 0 1
2621ae7bd9ccSMatthieu Baerts	fi
26226a0653b9SGeliang Tang
26236a0653b9SGeliang Tang	# set nobackup,nofullmesh flags
2624c7d49c03SMatthieu Baerts	if reset "set nobackup,nofullmesh flags test"; then
262534aa6e3bSGeliang Tang		pm_nl_set_limits $ns1 4 4
262634aa6e3bSGeliang Tang		pm_nl_set_limits $ns2 4 4
262734aa6e3bSGeliang Tang		pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow,backup,fullmesh
26286a0653b9SGeliang Tang		run_tests $ns1 $ns2 10.0.1.1 0 0 0 slow nobackup,nofullmesh
2629c7d49c03SMatthieu Baerts		chk_join_nr 2 2 2
26306a0653b9SGeliang Tang		chk_prio_nr 0 1
26316a0653b9SGeliang Tang		chk_rm_nr 0 1
2632ae7bd9ccSMatthieu Baerts	fi
26334f49d633SGeliang Tang}
26344f49d633SGeliang Tang
263501542c9bSGeliang Tangfastclose_tests()
263601542c9bSGeliang Tang{
2637c7d49c03SMatthieu Baerts	if reset "fastclose test"; then
263801542c9bSGeliang Tang		run_tests $ns1 $ns2 10.0.1.1 1024 0 fastclose_2
2639c7d49c03SMatthieu Baerts		chk_join_nr 0 0 0
264001542c9bSGeliang Tang		chk_fclose_nr 1 1
264101542c9bSGeliang Tang		chk_rst_nr 1 1 invert
2642ae7bd9ccSMatthieu Baerts	fi
264301542c9bSGeliang Tang}
264401542c9bSGeliang Tang
2645*b6e074e1SGeliang Tangpedit_action_pkts()
2646*b6e074e1SGeliang Tang{
2647*b6e074e1SGeliang Tang	tc -n $ns2 -j -s action show action pedit index 100 | \
2648*b6e074e1SGeliang Tang		sed 's/.*"packets":\([0-9]\+\),.*/\1/'
2649*b6e074e1SGeliang Tang}
2650*b6e074e1SGeliang Tang
2651*b6e074e1SGeliang Tangfail_tests()
2652*b6e074e1SGeliang Tang{
2653*b6e074e1SGeliang Tang	# single subflow
2654*b6e074e1SGeliang Tang	if reset_with_fail "Infinite map" 1; then
2655*b6e074e1SGeliang Tang		run_tests $ns1 $ns2 10.0.1.1 128
2656*b6e074e1SGeliang Tang		chk_join_nr 0 0 0 +1 +0 1 0 1 "$(pedit_action_pkts)"
2657*b6e074e1SGeliang Tang	fi
2658*b6e074e1SGeliang Tang}
2659*b6e074e1SGeliang Tang
266069c6ce7bSPaolo Abeniimplicit_tests()
266169c6ce7bSPaolo Abeni{
266269c6ce7bSPaolo Abeni	# userspace pm type prevents add_addr
2663c7d49c03SMatthieu Baerts	if reset "implicit EP"; then
266469c6ce7bSPaolo Abeni		pm_nl_set_limits $ns1 2 2
266569c6ce7bSPaolo Abeni		pm_nl_set_limits $ns2 2 2
266669c6ce7bSPaolo Abeni		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
266769c6ce7bSPaolo Abeni		run_tests $ns1 $ns2 10.0.1.1 0 0 0 slow &
266869c6ce7bSPaolo Abeni
266969c6ce7bSPaolo Abeni		wait_mpj $ns1
2670c7d49c03SMatthieu Baerts		pm_nl_check_endpoint 1 "creation" \
267169c6ce7bSPaolo Abeni			$ns2 10.0.2.2 id 1 flags implicit
267269c6ce7bSPaolo Abeni
267369c6ce7bSPaolo Abeni		pm_nl_add_endpoint $ns2 10.0.2.2 id 33
2674c7d49c03SMatthieu Baerts		pm_nl_check_endpoint 0 "ID change is prevented" \
267569c6ce7bSPaolo Abeni			$ns2 10.0.2.2 id 1 flags implicit
267669c6ce7bSPaolo Abeni
267769c6ce7bSPaolo Abeni		pm_nl_add_endpoint $ns2 10.0.2.2 flags signal
2678c7d49c03SMatthieu Baerts		pm_nl_check_endpoint 0 "modif is allowed" \
267969c6ce7bSPaolo Abeni			$ns2 10.0.2.2 id 1 flags signal
268069c6ce7bSPaolo Abeni		wait
2681ae7bd9ccSMatthieu Baerts	fi
268269c6ce7bSPaolo Abeni}
268369c6ce7bSPaolo Abeni
268422514d52SMatthieu Baerts# [$1: error message]
26851002b89fSGeliang Tangusage()
26861002b89fSGeliang Tang{
268722514d52SMatthieu Baerts	if [ -n "${1}" ]; then
268822514d52SMatthieu Baerts		echo "${1}"
268922514d52SMatthieu Baerts		ret=1
269022514d52SMatthieu Baerts	fi
269122514d52SMatthieu Baerts
26921002b89fSGeliang Tang	echo "mptcp_join usage:"
26933afd0280SMatthieu Baerts
26943afd0280SMatthieu Baerts	local key
26953afd0280SMatthieu Baerts	for key in "${!all_tests[@]}"; do
26963afd0280SMatthieu Baerts		echo "  -${key} ${all_tests[${key}]}"
26973afd0280SMatthieu Baerts	done
26983afd0280SMatthieu Baerts
2699a673321aSMat Martineau	echo "  -c capture pcap files"
2700af66d3e1SGeliang Tang	echo "  -C enable data checksum"
2701621bd393SGeliang Tang	echo "  -i use ip mptcp"
27021002b89fSGeliang Tang	echo "  -h help"
270322514d52SMatthieu Baerts
2704c7d49c03SMatthieu Baerts	echo "[test ids|names]"
2705ae7bd9ccSMatthieu Baerts
270622514d52SMatthieu Baerts	exit ${ret}
27071002b89fSGeliang Tang}
27081002b89fSGeliang Tang
2709a673321aSMat Martineau
27103afd0280SMatthieu Baerts# Use a "simple" array to force an specific order we cannot have with an associative one
27113afd0280SMatthieu Baertsall_tests_sorted=(
27123afd0280SMatthieu Baerts	f@subflows_tests
27133afd0280SMatthieu Baerts	e@subflows_error_tests
27143afd0280SMatthieu Baerts	s@signal_address_tests
27153afd0280SMatthieu Baerts	l@link_failure_tests
27163afd0280SMatthieu Baerts	t@add_addr_timeout_tests
27173afd0280SMatthieu Baerts	r@remove_tests
27183afd0280SMatthieu Baerts	a@add_tests
27193afd0280SMatthieu Baerts	6@ipv6_tests
27203afd0280SMatthieu Baerts	4@v4mapped_tests
27213afd0280SMatthieu Baerts	b@backup_tests
27223afd0280SMatthieu Baerts	p@add_addr_ports_tests
27233afd0280SMatthieu Baerts	k@syncookies_tests
27243afd0280SMatthieu Baerts	S@checksum_tests
27253afd0280SMatthieu Baerts	d@deny_join_id0_tests
27263afd0280SMatthieu Baerts	m@fullmesh_tests
27273afd0280SMatthieu Baerts	z@fastclose_tests
2728*b6e074e1SGeliang Tang	F@fail_tests
27293afd0280SMatthieu Baerts	I@implicit_tests
27303afd0280SMatthieu Baerts)
27313afd0280SMatthieu Baerts
27323afd0280SMatthieu Baertsall_tests_args=""
27333afd0280SMatthieu Baertsall_tests_names=()
27343afd0280SMatthieu Baertsfor subtests in "${all_tests_sorted[@]}"; do
27353afd0280SMatthieu Baerts	key="${subtests%@*}"
27363afd0280SMatthieu Baerts	value="${subtests#*@}"
27373afd0280SMatthieu Baerts
27383afd0280SMatthieu Baerts	all_tests_args+="${key}"
27393afd0280SMatthieu Baerts	all_tests_names+=("${value}")
27403afd0280SMatthieu Baerts	all_tests[${key}]="${value}"
27413afd0280SMatthieu Baertsdone
27423afd0280SMatthieu Baerts
2743826d7bdcSMatthieu Baertstests=()
27443afd0280SMatthieu Baertswhile getopts "${all_tests_args}cCih" opt; do
27451002b89fSGeliang Tang	case $opt in
27463afd0280SMatthieu Baerts		["${all_tests_args}"])
27473afd0280SMatthieu Baerts			tests+=("${all_tests[${opt}]}")
274869c6ce7bSPaolo Abeni			;;
2749a673321aSMat Martineau		c)
2750826d7bdcSMatthieu Baerts			capture=1
2751a673321aSMat Martineau			;;
2752af66d3e1SGeliang Tang		C)
2753826d7bdcSMatthieu Baerts			checksum=1
2754af66d3e1SGeliang Tang			;;
2755621bd393SGeliang Tang		i)
2756826d7bdcSMatthieu Baerts			ip_mptcp=1
2757621bd393SGeliang Tang			;;
275822514d52SMatthieu Baerts		h)
27591002b89fSGeliang Tang			usage
27601002b89fSGeliang Tang			;;
276122514d52SMatthieu Baerts		*)
276222514d52SMatthieu Baerts			usage "Unknown option: -${opt}"
276322514d52SMatthieu Baerts			;;
27641002b89fSGeliang Tang	esac
27651002b89fSGeliang Tangdone
276600587187SFlorian Westphal
2767ae7bd9ccSMatthieu Baertsshift $((OPTIND - 1))
2768ae7bd9ccSMatthieu Baerts
2769ae7bd9ccSMatthieu Baertsfor arg in "${@}"; do
2770ae7bd9ccSMatthieu Baerts	if [[ "${arg}" =~ ^[0-9]+$ ]]; then
2771c7d49c03SMatthieu Baerts		only_tests_ids+=("${arg}")
2772ae7bd9ccSMatthieu Baerts	else
2773c7d49c03SMatthieu Baerts		only_tests_names+=("${arg}")
2774ae7bd9ccSMatthieu Baerts	fi
2775ae7bd9ccSMatthieu Baertsdone
2776ae7bd9ccSMatthieu Baerts
2777826d7bdcSMatthieu Baertsif [ ${#tests[@]} -eq 0 ]; then
27783afd0280SMatthieu Baerts	tests=("${all_tests_names[@]}")
27793afd0280SMatthieu Baertsfi
27803afd0280SMatthieu Baerts
2781826d7bdcSMatthieu Baertsfor subtests in "${tests[@]}"; do
2782826d7bdcSMatthieu Baerts	"${subtests}"
2783826d7bdcSMatthieu Baertsdone
2784826d7bdcSMatthieu Baerts
278539aab882SMatthieu Baertsif [ ${ret} -ne 0 ]; then
278639aab882SMatthieu Baerts	echo
278739aab882SMatthieu Baerts	echo "${#failed_tests[@]} failure(s) has(ve) been detected:"
278839aab882SMatthieu Baerts	for i in $(get_failed_tests_ids); do
278939aab882SMatthieu Baerts		echo -e "\t- ${i}: ${failed_tests[${i}]}"
279039aab882SMatthieu Baerts	done
279139aab882SMatthieu Baerts	echo
279239aab882SMatthieu Baertsfi
279339aab882SMatthieu Baerts
2794b08fbf24SPaolo Abeniexit $ret
2795