1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4# Double quotes to prevent globbing and word splitting is recommended in new
5# code but we accept it, especially because there were too many before having
6# address all other issues detected by shellcheck.
7#shellcheck disable=SC2086
8
9# ShellCheck incorrectly believes that most of the code here is unreachable
10# because it's invoked by variable name, see how the "tests" array is used
11#shellcheck disable=SC2317
12
13. "$(dirname "${0}")/mptcp_lib.sh"
14
15ret=0
16sin=""
17sinfail=""
18sout=""
19cin=""
20cinfail=""
21cinsent=""
22tmpfile=""
23cout=""
24err=""
25capout=""
26ns1=""
27ns2=""
28ksft_skip=4
29iptables="iptables"
30ip6tables="ip6tables"
31timeout_poll=30
32timeout_test=$((timeout_poll * 2 + 1))
33capture=false
34checksum=false
35ip_mptcp=0
36check_invert=0
37validate_checksum=false
38init=0
39evts_ns1=""
40evts_ns2=""
41evts_ns1_pid=0
42evts_ns2_pid=0
43last_test_failed=0
44last_test_skipped=0
45last_test_ignored=1
46
47declare -A all_tests
48declare -a only_tests_ids
49declare -a only_tests_names
50declare -A failed_tests
51MPTCP_LIB_TEST_FORMAT="%03u %s\n"
52TEST_NAME=""
53nr_blank=6
54
55# These var are used only in some tests, make sure they are not already set
56unset FAILING_LINKS
57unset test_linkfail
58unset addr_nr_ns1
59unset addr_nr_ns2
60unset cestab_ns1
61unset cestab_ns2
62unset sflags
63unset fastclose
64unset fullmesh
65unset speed
66
67# generated using "nfbpf_compile '(ip && (ip[54] & 0xf0) == 0x30) ||
68#				  (ip6 && (ip6[74] & 0xf0) == 0x30)'"
69CBPF_MPTCP_SUBOPTION_ADD_ADDR="14,
70			       48 0 0 0,
71			       84 0 0 240,
72			       21 0 3 64,
73			       48 0 0 54,
74			       84 0 0 240,
75			       21 6 7 48,
76			       48 0 0 0,
77			       84 0 0 240,
78			       21 0 4 96,
79			       48 0 0 74,
80			       84 0 0 240,
81			       21 0 1 48,
82			       6 0 0 65535,
83			       6 0 0 0"
84
85init_partial()
86{
87	capout=$(mktemp)
88
89	mptcp_lib_ns_init ns1 ns2
90
91	local netns
92	for netns in "$ns1" "$ns2"; do
93		ip netns exec $netns sysctl -q net.mptcp.pm_type=0 2>/dev/null || true
94		if $checksum; then
95			ip netns exec $netns sysctl -q net.mptcp.checksum_enabled=1
96		fi
97	done
98
99	check_invert=0
100	validate_checksum=$checksum
101
102	#  ns1         ns2
103	# ns1eth1    ns2eth1
104	# ns1eth2    ns2eth2
105	# ns1eth3    ns2eth3
106	# ns1eth4    ns2eth4
107
108	local i
109	for i in $(seq 1 4); do
110		ip link add ns1eth$i netns "$ns1" type veth peer name ns2eth$i netns "$ns2"
111		ip -net "$ns1" addr add 10.0.$i.1/24 dev ns1eth$i
112		ip -net "$ns1" addr add dead:beef:$i::1/64 dev ns1eth$i nodad
113		ip -net "$ns1" link set ns1eth$i up
114
115		ip -net "$ns2" addr add 10.0.$i.2/24 dev ns2eth$i
116		ip -net "$ns2" addr add dead:beef:$i::2/64 dev ns2eth$i nodad
117		ip -net "$ns2" link set ns2eth$i up
118
119		# let $ns2 reach any $ns1 address from any interface
120		ip -net "$ns2" route add default via 10.0.$i.1 dev ns2eth$i metric 10$i
121		ip -net "$ns2" route add default via dead:beef:$i::1 dev ns2eth$i metric 10$i
122	done
123}
124
125init_shapers()
126{
127	local i
128	for i in $(seq 1 4); do
129		tc -n $ns1 qdisc add dev ns1eth$i root netem rate 20mbit delay 1
130		tc -n $ns2 qdisc add dev ns2eth$i root netem rate 20mbit delay 1
131	done
132}
133
134cleanup_partial()
135{
136	rm -f "$capout"
137
138	mptcp_lib_ns_exit "${ns1}" "${ns2}"
139}
140
141init() {
142	init=1
143
144	mptcp_lib_check_mptcp
145	mptcp_lib_check_kallsyms
146	mptcp_lib_check_tools ip ss "${iptables}" "${ip6tables}"
147
148	sin=$(mktemp)
149	sout=$(mktemp)
150	cin=$(mktemp)
151	cinsent=$(mktemp)
152	cout=$(mktemp)
153	err=$(mktemp)
154	evts_ns1=$(mktemp)
155	evts_ns2=$(mktemp)
156
157	trap cleanup EXIT
158
159	make_file "$cin" "client" 1 >/dev/null
160	make_file "$sin" "server" 1 >/dev/null
161}
162
163cleanup()
164{
165	rm -f "$cin" "$cout" "$sinfail"
166	rm -f "$sin" "$sout" "$cinsent" "$cinfail"
167	rm -f "$tmpfile"
168	rm -rf $evts_ns1 $evts_ns2
169	rm -f "$err"
170	cleanup_partial
171}
172
173print_check()
174{
175	printf "%-${nr_blank}s%-36s" " " "${*}"
176}
177
178print_info()
179{
180	# It can be empty, no need to print anything then
181	[ -z "${1}" ] && return
182
183	mptcp_lib_print_info "      Info: ${*}"
184}
185
186print_ok()
187{
188	mptcp_lib_pr_ok "${@}"
189}
190
191print_fail()
192{
193	mptcp_lib_pr_fail "${@}"
194}
195
196print_skip()
197{
198	mptcp_lib_pr_skip "${@}"
199}
200
201# [ $1: fail msg ]
202mark_as_skipped()
203{
204	local msg="${1:-"Feature not supported"}"
205
206	mptcp_lib_fail_if_expected_feature "${msg}"
207
208	print_check "${msg}"
209	print_skip
210
211	last_test_skipped=1
212}
213
214# $@: condition
215continue_if()
216{
217	if ! "${@}"; then
218		mark_as_skipped
219		return 1
220	fi
221}
222
223skip_test()
224{
225	if [ "${#only_tests_ids[@]}" -eq 0 ] && [ "${#only_tests_names[@]}" -eq 0 ]; then
226		return 1
227	fi
228
229	local i
230	for i in "${only_tests_ids[@]}"; do
231		if [ "$((MPTCP_LIB_TEST_COUNTER+1))" -eq "${i}" ]; then
232			return 1
233		fi
234	done
235	for i in "${only_tests_names[@]}"; do
236		if [ "${TEST_NAME}" = "${i}" ]; then
237			return 1
238		fi
239	done
240
241	return 0
242}
243
244append_prev_results()
245{
246	if [ ${last_test_failed} -eq 1 ]; then
247		mptcp_lib_result_fail "${TEST_NAME}"
248	elif [ ${last_test_skipped} -eq 1 ]; then
249		mptcp_lib_result_skip "${TEST_NAME}"
250	elif [ ${last_test_ignored} -ne 1 ]; then
251		mptcp_lib_result_pass "${TEST_NAME}"
252	fi
253
254	last_test_failed=0
255	last_test_skipped=0
256	last_test_ignored=0
257}
258
259# $1: test name
260reset()
261{
262	append_prev_results
263
264	TEST_NAME="${1}"
265
266	if skip_test; then
267		MPTCP_LIB_TEST_COUNTER=$((MPTCP_LIB_TEST_COUNTER+1))
268		last_test_ignored=1
269		return 1
270	fi
271
272	mptcp_lib_print_title "${TEST_NAME}"
273
274	if [ "${init}" != "1" ]; then
275		init
276	else
277		cleanup_partial
278	fi
279
280	init_partial
281
282	return 0
283}
284
285# $1: test name ; $2: counter to check
286reset_check_counter()
287{
288	reset "${1}" || return 1
289
290	local counter="${2}"
291
292	if ! nstat -asz "${counter}" | grep -wq "${counter}"; then
293		mark_as_skipped "counter '${counter}' is not available"
294		return 1
295	fi
296}
297
298# $1: test name
299reset_with_cookies()
300{
301	reset "${1}" || return 1
302
303	local netns
304	for netns in "$ns1" "$ns2"; do
305		ip netns exec $netns sysctl -q net.ipv4.tcp_syncookies=2
306	done
307}
308
309# $1: test name
310reset_with_add_addr_timeout()
311{
312	local ip="${2:-4}"
313	local tables
314
315	reset "${1}" || return 1
316
317	tables="${iptables}"
318	if [ $ip -eq 6 ]; then
319		tables="${ip6tables}"
320	fi
321
322	ip netns exec $ns1 sysctl -q net.mptcp.add_addr_timeout=1
323
324	if ! ip netns exec $ns2 $tables -A OUTPUT -p tcp \
325			-m tcp --tcp-option 30 \
326			-m bpf --bytecode \
327			"$CBPF_MPTCP_SUBOPTION_ADD_ADDR" \
328			-j DROP; then
329		mark_as_skipped "unable to set the 'add addr' rule"
330		return 1
331	fi
332}
333
334# $1: test name
335reset_with_checksum()
336{
337	local ns1_enable=$1
338	local ns2_enable=$2
339
340	reset "checksum test ${1} ${2}" || return 1
341
342	ip netns exec $ns1 sysctl -q net.mptcp.checksum_enabled=$ns1_enable
343	ip netns exec $ns2 sysctl -q net.mptcp.checksum_enabled=$ns2_enable
344
345	validate_checksum=true
346}
347
348reset_with_allow_join_id0()
349{
350	local ns1_enable=$2
351	local ns2_enable=$3
352
353	reset "${1}" || return 1
354
355	ip netns exec $ns1 sysctl -q net.mptcp.allow_join_initial_addr_port=$ns1_enable
356	ip netns exec $ns2 sysctl -q net.mptcp.allow_join_initial_addr_port=$ns2_enable
357}
358
359# Modify TCP payload without corrupting the TCP packet
360#
361# This rule inverts a 8-bit word at byte offset 148 for the 2nd TCP ACK packets
362# carrying enough data.
363# Once it is done, the TCP Checksum field is updated so the packet is still
364# considered as valid at the TCP level.
365# Because the MPTCP checksum, covering the TCP options and data, has not been
366# updated, the modification will be detected and an MP_FAIL will be emitted:
367# what we want to validate here without corrupting "random" MPTCP options.
368#
369# To avoid having tc producing this pr_info() message for each TCP ACK packets
370# not carrying enough data:
371#
372#     tc action pedit offset 162 out of bounds
373#
374# Netfilter is used to mark packets with enough data.
375setup_fail_rules()
376{
377	check_invert=1
378	validate_checksum=true
379	local i="$1"
380	local ip="${2:-4}"
381	local tables
382
383	tables="${iptables}"
384	if [ $ip -eq 6 ]; then
385		tables="${ip6tables}"
386	fi
387
388	ip netns exec $ns2 $tables \
389		-t mangle \
390		-A OUTPUT \
391		-o ns2eth$i \
392		-p tcp \
393		-m length --length 150:9999 \
394		-m statistic --mode nth --packet 1 --every 99999 \
395		-j MARK --set-mark 42 || return ${ksft_skip}
396
397	tc -n $ns2 qdisc add dev ns2eth$i clsact || return ${ksft_skip}
398	tc -n $ns2 filter add dev ns2eth$i egress \
399		protocol ip prio 1000 \
400		handle 42 fw \
401		action pedit munge offset 148 u8 invert \
402		pipe csum tcp \
403		index 100 || return ${ksft_skip}
404}
405
406reset_with_fail()
407{
408	reset_check_counter "${1}" "MPTcpExtInfiniteMapTx" || return 1
409	shift
410
411	ip netns exec $ns1 sysctl -q net.mptcp.checksum_enabled=1
412	ip netns exec $ns2 sysctl -q net.mptcp.checksum_enabled=1
413
414	local rc=0
415	setup_fail_rules "${@}" || rc=$?
416
417	if [ ${rc} -eq ${ksft_skip} ]; then
418		mark_as_skipped "unable to set the 'fail' rules"
419		return 1
420	fi
421}
422
423reset_with_events()
424{
425	reset "${1}" || return 1
426
427	mptcp_lib_events "${ns1}" "${evts_ns1}" evts_ns1_pid
428	mptcp_lib_events "${ns2}" "${evts_ns2}" evts_ns2_pid
429}
430
431reset_with_tcp_filter()
432{
433	reset "${1}" || return 1
434	shift
435
436	local ns="${!1}"
437	local src="${2}"
438	local target="${3}"
439
440	if ! ip netns exec "${ns}" ${iptables} \
441			-A INPUT \
442			-s "${src}" \
443			-p tcp \
444			-j "${target}"; then
445		mark_as_skipped "unable to set the filter rules"
446		return 1
447	fi
448}
449
450# $1: err msg
451fail_test()
452{
453	ret=1
454
455	if [ ${#} -gt 0 ]; then
456		print_fail "${@}"
457	fi
458
459	# just in case a test is marked twice as failed
460	if [ ${last_test_failed} -eq 0 ]; then
461		failed_tests[${MPTCP_LIB_TEST_COUNTER}]="${TEST_NAME}"
462		dump_stats
463		last_test_failed=1
464	fi
465}
466
467get_failed_tests_ids()
468{
469	# sorted
470	local i
471	for i in "${!failed_tests[@]}"; do
472		echo "${i}"
473	done | sort -n
474}
475
476check_transfer()
477{
478	local in=$1
479	local out=$2
480	local what=$3
481	local bytes=$4
482	local i a b
483
484	local line
485	if [ -n "$bytes" ]; then
486		local out_size
487		# when truncating we must check the size explicitly
488		out_size=$(wc -c $out | awk '{print $1}')
489		if [ $out_size -ne $bytes ]; then
490			fail_test "$what output file has wrong size ($out_size, $bytes)"
491			return 1
492		fi
493
494		# note: BusyBox's "cmp" command doesn't support --bytes
495		tmpfile=$(mktemp)
496		head --bytes="$bytes" "$in" > "$tmpfile"
497		mv "$tmpfile" "$in"
498		head --bytes="$bytes" "$out" > "$tmpfile"
499		mv "$tmpfile" "$out"
500		tmpfile=""
501	fi
502	cmp -l "$in" "$out" | while read -r i a b; do
503		local sum=$((0${a} + 0${b}))
504		if [ $check_invert -eq 0 ] || [ $sum -ne $((0xff)) ]; then
505			fail_test "$what does not match (in, out):"
506			mptcp_lib_print_file_err "$in"
507			mptcp_lib_print_file_err "$out"
508
509			return 1
510		else
511			print_info "$what has inverted byte at ${i}"
512		fi
513	done
514
515	return 0
516}
517
518do_ping()
519{
520	local listener_ns="$1"
521	local connector_ns="$2"
522	local connect_addr="$3"
523
524	if ! ip netns exec ${connector_ns} ping -q -c 1 $connect_addr >/dev/null; then
525		fail_test "$listener_ns -> $connect_addr connectivity"
526	fi
527}
528
529link_failure()
530{
531	local ns="$1"
532
533	if [ -z "$FAILING_LINKS" ]; then
534		l=$((RANDOM%4))
535		FAILING_LINKS=$((l+1))
536	fi
537
538	local l
539	for l in $FAILING_LINKS; do
540		local veth="ns1eth$l"
541		ip -net "$ns" link set "$veth" down
542	done
543}
544
545rm_addr_count()
546{
547	mptcp_lib_get_counter "${1}" "MPTcpExtRmAddr"
548}
549
550# $1: ns, $2: old rm_addr counter in $ns
551wait_rm_addr()
552{
553	local ns="${1}"
554	local old_cnt="${2}"
555	local cnt
556
557	local i
558	for i in $(seq 10); do
559		cnt=$(rm_addr_count ${ns})
560		[ "$cnt" = "${old_cnt}" ] || break
561		sleep 0.1
562	done
563}
564
565rm_sf_count()
566{
567	mptcp_lib_get_counter "${1}" "MPTcpExtRmSubflow"
568}
569
570# $1: ns, $2: old rm_sf counter in $ns
571wait_rm_sf()
572{
573	local ns="${1}"
574	local old_cnt="${2}"
575	local cnt
576
577	local i
578	for i in $(seq 10); do
579		cnt=$(rm_sf_count ${ns})
580		[ "$cnt" = "${old_cnt}" ] || break
581		sleep 0.1
582	done
583}
584
585wait_mpj()
586{
587	local ns="${1}"
588	local cnt old_cnt
589
590	old_cnt=$(mptcp_lib_get_counter ${ns} "MPTcpExtMPJoinAckRx")
591
592	local i
593	for i in $(seq 10); do
594		cnt=$(mptcp_lib_get_counter ${ns} "MPTcpExtMPJoinAckRx")
595		[ "$cnt" = "${old_cnt}" ] || break
596		sleep 0.1
597	done
598}
599
600kill_events_pids()
601{
602	mptcp_lib_kill_wait $evts_ns1_pid
603	evts_ns1_pid=0
604	mptcp_lib_kill_wait $evts_ns2_pid
605	evts_ns2_pid=0
606}
607
608pm_nl_set_limits()
609{
610	local ns=$1
611	local addrs=$2
612	local subflows=$3
613
614	if [ $ip_mptcp -eq 1 ]; then
615		ip -n $ns mptcp limits set add_addr_accepted $addrs subflows $subflows
616	else
617		ip netns exec $ns ./pm_nl_ctl limits $addrs $subflows
618	fi
619}
620
621pm_nl_add_endpoint()
622{
623	local ns=$1
624	local addr=$2
625	local flags _flags
626	local port _port
627	local dev _dev
628	local id _id
629	local nr=2
630
631	local p
632	for p in "${@}"
633	do
634		if [ $p = "flags" ]; then
635			eval _flags=\$"$nr"
636			[ -n "$_flags" ]; flags="flags $_flags"
637		fi
638		if [ $p = "dev" ]; then
639			eval _dev=\$"$nr"
640			[ -n "$_dev" ]; dev="dev $_dev"
641		fi
642		if [ $p = "id" ]; then
643			eval _id=\$"$nr"
644			[ -n "$_id" ]; id="id $_id"
645		fi
646		if [ $p = "port" ]; then
647			eval _port=\$"$nr"
648			[ -n "$_port" ]; port="port $_port"
649		fi
650
651		nr=$((nr + 1))
652	done
653
654	if [ $ip_mptcp -eq 1 ]; then
655		ip -n $ns mptcp endpoint add $addr ${_flags//","/" "} $dev $id $port
656	else
657		ip netns exec $ns ./pm_nl_ctl add $addr $flags $dev $id $port
658	fi
659}
660
661pm_nl_del_endpoint()
662{
663	local ns=$1
664	local id=$2
665	local addr=$3
666
667	if [ $ip_mptcp -eq 1 ]; then
668		[ $id -ne 0 ] && addr=''
669		ip -n $ns mptcp endpoint delete id $id $addr
670	else
671		ip netns exec $ns ./pm_nl_ctl del $id $addr
672	fi
673}
674
675pm_nl_flush_endpoint()
676{
677	local ns=$1
678
679	if [ $ip_mptcp -eq 1 ]; then
680		ip -n $ns mptcp endpoint flush
681	else
682		ip netns exec $ns ./pm_nl_ctl flush
683	fi
684}
685
686pm_nl_show_endpoints()
687{
688	local ns=$1
689
690	if [ $ip_mptcp -eq 1 ]; then
691		ip -n $ns mptcp endpoint show
692	else
693		ip netns exec $ns ./pm_nl_ctl dump
694	fi
695}
696
697pm_nl_change_endpoint()
698{
699	local ns=$1
700	local id=$2
701	local flags=$3
702
703	if [ $ip_mptcp -eq 1 ]; then
704		ip -n $ns mptcp endpoint change id $id ${flags//","/" "}
705	else
706		ip netns exec $ns ./pm_nl_ctl set id $id flags $flags
707	fi
708}
709
710pm_nl_check_endpoint()
711{
712	local line expected_line
713	local msg="$1"
714	local ns=$2
715	local addr=$3
716	local _flags=""
717	local flags
718	local _port
719	local port
720	local dev
721	local _id
722	local id
723
724	print_check "${msg}"
725
726	shift 3
727	while [ -n "$1" ]; do
728		if [ $1 = "flags" ]; then
729			_flags=$2
730			[ -n "$_flags" ]; flags="flags $_flags"
731			shift
732		elif [ $1 = "dev" ]; then
733			[ -n "$2" ]; dev="dev $1"
734			shift
735		elif [ $1 = "id" ]; then
736			_id=$2
737			[ -n "$_id" ]; id="id $_id"
738			shift
739		elif [ $1 = "port" ]; then
740			_port=$2
741			[ -n "$_port" ]; port=" port $_port"
742			shift
743		fi
744
745		shift
746	done
747
748	if [ -z "$id" ]; then
749		test_fail "bad test - missing endpoint id"
750		return
751	fi
752
753	if [ $ip_mptcp -eq 1 ]; then
754		# get line and trim trailing whitespace
755		line=$(ip -n $ns mptcp endpoint show $id)
756		line="${line% }"
757		# the dump order is: address id flags port dev
758		[ -n "$addr" ] && expected_line="$addr"
759		expected_line+=" $id"
760		[ -n "$_flags" ] && expected_line+=" ${_flags//","/" "}"
761		[ -n "$dev" ] && expected_line+=" $dev"
762		[ -n "$port" ] && expected_line+=" $port"
763	else
764		line=$(ip netns exec $ns ./pm_nl_ctl get $_id)
765		# the dump order is: id flags dev address port
766		expected_line="$id"
767		[ -n "$flags" ] && expected_line+=" $flags"
768		[ -n "$dev" ] && expected_line+=" $dev"
769		[ -n "$addr" ] && expected_line+=" $addr"
770		[ -n "$_port" ] && expected_line+=" $_port"
771	fi
772	if [ "$line" = "$expected_line" ]; then
773		print_ok
774	else
775		fail_test "expected '$expected_line' found '$line'"
776	fi
777}
778
779pm_nl_set_endpoint()
780{
781	local listener_ns="$1"
782	local connector_ns="$2"
783	local connect_addr="$3"
784
785	local addr_nr_ns1=${addr_nr_ns1:-0}
786	local addr_nr_ns2=${addr_nr_ns2:-0}
787	local sflags=${sflags:-""}
788	local fullmesh=${fullmesh:-""}
789
790	local flags="subflow"
791	if [ -n "${fullmesh}" ]; then
792		flags="${flags},fullmesh"
793		addr_nr_ns2=${fullmesh}
794	fi
795
796	# let the mptcp subflow be established in background before
797	# do endpoint manipulation
798	if [ $addr_nr_ns1 != "0" ] || [ $addr_nr_ns2 != "0" ]; then
799		sleep 1
800	fi
801
802	if [ $addr_nr_ns1 -gt 0 ]; then
803		local counter=2
804		local add_nr_ns1=${addr_nr_ns1}
805		local id=10
806		while [ $add_nr_ns1 -gt 0 ]; do
807			local addr
808			if mptcp_lib_is_v6 "${connect_addr}"; then
809				addr="dead:beef:$counter::1"
810			else
811				addr="10.0.$counter.1"
812			fi
813			pm_nl_add_endpoint $ns1 $addr flags signal
814			counter=$((counter + 1))
815			add_nr_ns1=$((add_nr_ns1 - 1))
816			id=$((id + 1))
817		done
818	elif [ $addr_nr_ns1 -lt 0 ]; then
819		local rm_nr_ns1=$((-addr_nr_ns1))
820		if [ $rm_nr_ns1 -lt 8 ]; then
821			local counter=0
822			local line
823			pm_nl_show_endpoints ${listener_ns} | while read -r line; do
824				# shellcheck disable=SC2206 # we do want to split per word
825				local arr=($line)
826				local nr=0
827
828				local i
829				for i in "${arr[@]}"; do
830					if [ $i = "id" ]; then
831						if [ $counter -eq $rm_nr_ns1 ]; then
832							break
833						fi
834						id=${arr[$nr+1]}
835						rm_addr=$(rm_addr_count ${connector_ns})
836						pm_nl_del_endpoint ${listener_ns} $id
837						wait_rm_addr ${connector_ns} ${rm_addr}
838						counter=$((counter + 1))
839					fi
840					nr=$((nr + 1))
841				done
842			done
843		elif [ $rm_nr_ns1 -eq 8 ]; then
844			pm_nl_flush_endpoint ${listener_ns}
845		elif [ $rm_nr_ns1 -eq 9 ]; then
846			pm_nl_del_endpoint ${listener_ns} 0 ${connect_addr}
847		fi
848	fi
849
850	# if newly added endpoints must be deleted, give the background msk
851	# some time to created them
852	[ $addr_nr_ns1 -gt 0 ] && [ $addr_nr_ns2 -lt 0 ] && sleep 1
853
854	if [ $addr_nr_ns2 -gt 0 ]; then
855		local add_nr_ns2=${addr_nr_ns2}
856		local counter=3
857		local id=20
858		while [ $add_nr_ns2 -gt 0 ]; do
859			local addr
860			if mptcp_lib_is_v6 "${connect_addr}"; then
861				addr="dead:beef:$counter::2"
862			else
863				addr="10.0.$counter.2"
864			fi
865			pm_nl_add_endpoint $ns2 $addr flags $flags
866			counter=$((counter + 1))
867			add_nr_ns2=$((add_nr_ns2 - 1))
868			id=$((id + 1))
869		done
870	elif [ $addr_nr_ns2 -lt 0 ]; then
871		local rm_nr_ns2=$((-addr_nr_ns2))
872		if [ $rm_nr_ns2 -lt 8 ]; then
873			local counter=0
874			local line
875			pm_nl_show_endpoints ${connector_ns} | while read -r line; do
876				# shellcheck disable=SC2206 # we do want to split per word
877				local arr=($line)
878				local nr=0
879
880				local i
881				for i in "${arr[@]}"; do
882					if [ $i = "id" ]; then
883						if [ $counter -eq $rm_nr_ns2 ]; then
884							break
885						fi
886						local id rm_addr
887						# rm_addr are serialized, allow the previous one to
888						# complete
889						id=${arr[$nr+1]}
890						rm_addr=$(rm_addr_count ${listener_ns})
891						pm_nl_del_endpoint ${connector_ns} $id
892						wait_rm_addr ${listener_ns} ${rm_addr}
893						counter=$((counter + 1))
894					fi
895					nr=$((nr + 1))
896				done
897			done
898		elif [ $rm_nr_ns2 -eq 8 ]; then
899			pm_nl_flush_endpoint ${connector_ns}
900		elif [ $rm_nr_ns2 -eq 9 ]; then
901			local addr
902			if mptcp_lib_is_v6 "${connect_addr}"; then
903				addr="dead:beef:1::2"
904			else
905				addr="10.0.1.2"
906			fi
907			pm_nl_del_endpoint ${connector_ns} 0 $addr
908		fi
909	fi
910
911	if [ -n "${sflags}" ]; then
912		sleep 1
913
914		local netns
915		for netns in "$ns1" "$ns2"; do
916			local line
917			pm_nl_show_endpoints $netns | while read -r line; do
918				# shellcheck disable=SC2206 # we do want to split per word
919				local arr=($line)
920				local nr=0
921				local id
922
923				local i
924				for i in "${arr[@]}"; do
925					if [ $i = "id" ]; then
926						id=${arr[$nr+1]}
927					fi
928					nr=$((nr + 1))
929				done
930				pm_nl_change_endpoint $netns $id $sflags
931			done
932		done
933	fi
934}
935
936chk_cestab_nr()
937{
938	local ns=$1
939	local cestab=$2
940	local count
941
942	print_check "cestab $cestab"
943	count=$(mptcp_lib_get_counter ${ns} "MPTcpExtMPCurrEstab")
944	if [ -z "$count" ]; then
945		print_skip
946	elif [ "$count" != "$cestab" ]; then
947		fail_test "got $count current establish[s] expected $cestab"
948	else
949		print_ok
950	fi
951}
952
953# $1 namespace 1, $2 namespace 2
954check_cestab()
955{
956	if [ -n "${cestab_ns1}" ]; then
957		chk_cestab_nr ${1} ${cestab_ns1}
958	fi
959	if [ -n "${cestab_ns2}" ]; then
960		chk_cestab_nr ${2} ${cestab_ns2}
961	fi
962}
963
964do_transfer()
965{
966	local listener_ns="$1"
967	local connector_ns="$2"
968	local cl_proto="$3"
969	local srv_proto="$4"
970	local connect_addr="$5"
971
972	local port=$((10000 + MPTCP_LIB_TEST_COUNTER - 1))
973	local cappid
974	local FAILING_LINKS=${FAILING_LINKS:-""}
975	local fastclose=${fastclose:-""}
976	local speed=${speed:-"fast"}
977
978	:> "$cout"
979	:> "$sout"
980	:> "$capout"
981
982	if $capture; then
983		local capuser
984		if [ -z $SUDO_USER ] ; then
985			capuser=""
986		else
987			capuser="-Z $SUDO_USER"
988		fi
989
990		capfile=$(printf "mp_join-%02u-%s.pcap" "$MPTCP_LIB_TEST_COUNTER" "${listener_ns}")
991
992		echo "Capturing traffic for test $MPTCP_LIB_TEST_COUNTER into $capfile"
993		ip netns exec ${listener_ns} tcpdump -i any -s 65535 -B 32768 $capuser -w $capfile > "$capout" 2>&1 &
994		cappid=$!
995
996		sleep 1
997	fi
998
999	NSTAT_HISTORY=/tmp/${listener_ns}.nstat ip netns exec ${listener_ns} \
1000		nstat -n
1001	NSTAT_HISTORY=/tmp/${connector_ns}.nstat ip netns exec ${connector_ns} \
1002		nstat -n
1003
1004	local extra_args
1005	if [ $speed = "fast" ]; then
1006		extra_args="-j"
1007	elif [ $speed = "slow" ]; then
1008		extra_args="-r 50"
1009	elif [ $speed -gt 0 ]; then
1010		extra_args="-r ${speed}"
1011	fi
1012
1013	local extra_cl_args=""
1014	local extra_srv_args=""
1015	local trunc_size=""
1016	if [ -n "${fastclose}" ]; then
1017		if [ ${test_linkfail} -le 1 ]; then
1018			fail_test "fastclose tests need test_linkfail argument"
1019			return 1
1020		fi
1021
1022		# disconnect
1023		trunc_size=${test_linkfail}
1024		local side=${fastclose}
1025
1026		if [ ${side} = "client" ]; then
1027			extra_cl_args="-f ${test_linkfail}"
1028			extra_srv_args="-f -1"
1029		elif [ ${side} = "server" ]; then
1030			extra_srv_args="-f ${test_linkfail}"
1031			extra_cl_args="-f -1"
1032		else
1033			fail_test "wrong/unknown fastclose spec ${side}"
1034			return 1
1035		fi
1036	fi
1037
1038	extra_srv_args="$extra_args $extra_srv_args"
1039	if [ "$test_linkfail" -gt 1 ];then
1040		timeout ${timeout_test} \
1041			ip netns exec ${listener_ns} \
1042				./mptcp_connect -t ${timeout_poll} -l -p $port -s ${srv_proto} \
1043					$extra_srv_args "::" < "$sinfail" > "$sout" &
1044	else
1045		timeout ${timeout_test} \
1046			ip netns exec ${listener_ns} \
1047				./mptcp_connect -t ${timeout_poll} -l -p $port -s ${srv_proto} \
1048					$extra_srv_args "::" < "$sin" > "$sout" &
1049	fi
1050	local spid=$!
1051
1052	mptcp_lib_wait_local_port_listen "${listener_ns}" "${port}"
1053
1054	extra_cl_args="$extra_args $extra_cl_args"
1055	if [ "$test_linkfail" -eq 0 ];then
1056		timeout ${timeout_test} \
1057			ip netns exec ${connector_ns} \
1058				./mptcp_connect -t ${timeout_poll} -p $port -s ${cl_proto} \
1059					$extra_cl_args $connect_addr < "$cin" > "$cout" &
1060	elif [ "$test_linkfail" -eq 1 ] || [ "$test_linkfail" -eq 2 ];then
1061		( cat "$cinfail" ; sleep 2; link_failure $listener_ns ; cat "$cinfail" ) | \
1062			tee "$cinsent" | \
1063			timeout ${timeout_test} \
1064				ip netns exec ${connector_ns} \
1065					./mptcp_connect -t ${timeout_poll} -p $port -s ${cl_proto} \
1066						$extra_cl_args $connect_addr > "$cout" &
1067	else
1068		tee "$cinsent" < "$cinfail" | \
1069			timeout ${timeout_test} \
1070				ip netns exec ${connector_ns} \
1071					./mptcp_connect -t ${timeout_poll} -p $port -s ${cl_proto} \
1072						$extra_cl_args $connect_addr > "$cout" &
1073	fi
1074	local cpid=$!
1075
1076	pm_nl_set_endpoint $listener_ns $connector_ns $connect_addr
1077	check_cestab $listener_ns $connector_ns
1078
1079	wait $cpid
1080	local retc=$?
1081	wait $spid
1082	local rets=$?
1083
1084	if $capture; then
1085	    sleep 1
1086	    kill $cappid
1087	fi
1088
1089	NSTAT_HISTORY=/tmp/${listener_ns}.nstat ip netns exec ${listener_ns} \
1090		nstat | grep Tcp > /tmp/${listener_ns}.out
1091	NSTAT_HISTORY=/tmp/${connector_ns}.nstat ip netns exec ${connector_ns} \
1092		nstat | grep Tcp > /tmp/${connector_ns}.out
1093
1094	if [ ${rets} -ne 0 ] || [ ${retc} -ne 0 ]; then
1095		fail_test "client exit code $retc, server $rets"
1096		echo -e "\nnetns ${listener_ns} socket stat for ${port}:" 1>&2
1097		ip netns exec ${listener_ns} ss -Menita 1>&2 -o "sport = :$port"
1098		cat /tmp/${listener_ns}.out
1099		echo -e "\nnetns ${connector_ns} socket stat for ${port}:" 1>&2
1100		ip netns exec ${connector_ns} ss -Menita 1>&2 -o "dport = :$port"
1101		cat /tmp/${connector_ns}.out
1102
1103		cat "$capout"
1104		return 1
1105	fi
1106
1107	if [ "$test_linkfail" -gt 1 ];then
1108		check_transfer $sinfail $cout "file received by client" $trunc_size
1109	else
1110		check_transfer $sin $cout "file received by client" $trunc_size
1111	fi
1112	retc=$?
1113	if [ "$test_linkfail" -eq 0 ];then
1114		check_transfer $cin $sout "file received by server" $trunc_size
1115	else
1116		check_transfer $cinsent $sout "file received by server" $trunc_size
1117	fi
1118	rets=$?
1119
1120	if [ $retc -eq 0 ] && [ $rets -eq 0 ];then
1121		cat "$capout"
1122		return 0
1123	fi
1124
1125	cat "$capout"
1126	return 1
1127}
1128
1129make_file()
1130{
1131	local name=$1
1132	local who=$2
1133	local size=$3
1134
1135	mptcp_lib_make_file $name 1024 $size
1136
1137	print_info "Test file (size $size KB) for $who"
1138}
1139
1140run_tests()
1141{
1142	local listener_ns="$1"
1143	local connector_ns="$2"
1144	local connect_addr="$3"
1145
1146	local size
1147	local test_linkfail=${test_linkfail:-0}
1148
1149	# The values above 2 are reused to make test files
1150	# with the given sizes (KB)
1151	if [ "$test_linkfail" -gt 2 ]; then
1152		size=$test_linkfail
1153
1154		if [ -z "$cinfail" ]; then
1155			cinfail=$(mktemp)
1156		fi
1157		make_file "$cinfail" "client" $size
1158	# create the input file for the failure test when
1159	# the first failure test run
1160	elif [ "$test_linkfail" -ne 0 ] && [ -z "$cinfail" ]; then
1161		# the client file must be considerably larger
1162		# of the maximum expected cwin value, or the
1163		# link utilization will be not predicable
1164		size=$((RANDOM%2))
1165		size=$((size+1))
1166		size=$((size*8192))
1167		size=$((size + ( RANDOM % 8192) ))
1168
1169		cinfail=$(mktemp)
1170		make_file "$cinfail" "client" $size
1171	fi
1172
1173	if [ "$test_linkfail" -gt 2 ]; then
1174		size=$test_linkfail
1175
1176		if [ -z "$sinfail" ]; then
1177			sinfail=$(mktemp)
1178		fi
1179		make_file "$sinfail" "server" $size
1180	elif [ "$test_linkfail" -eq 2 ] && [ -z "$sinfail" ]; then
1181		size=$((RANDOM%16))
1182		size=$((size+1))
1183		size=$((size*2048))
1184
1185		sinfail=$(mktemp)
1186		make_file "$sinfail" "server" $size
1187	fi
1188
1189	do_transfer ${listener_ns} ${connector_ns} MPTCP MPTCP ${connect_addr}
1190}
1191
1192dump_stats()
1193{
1194	echo Server ns stats
1195	ip netns exec $ns1 nstat -as | grep Tcp
1196	echo Client ns stats
1197	ip netns exec $ns2 nstat -as | grep Tcp
1198}
1199
1200chk_csum_nr()
1201{
1202	local csum_ns1=${1:-0}
1203	local csum_ns2=${2:-0}
1204	local count
1205	local extra_msg=""
1206	local allow_multi_errors_ns1=0
1207	local allow_multi_errors_ns2=0
1208
1209	if [[ "${csum_ns1}" = "+"* ]]; then
1210		allow_multi_errors_ns1=1
1211		csum_ns1=${csum_ns1:1}
1212	fi
1213	if [[ "${csum_ns2}" = "+"* ]]; then
1214		allow_multi_errors_ns2=1
1215		csum_ns2=${csum_ns2:1}
1216	fi
1217
1218	print_check "sum"
1219	count=$(mptcp_lib_get_counter ${ns1} "MPTcpExtDataCsumErr")
1220	if [ "$count" != "$csum_ns1" ]; then
1221		extra_msg+=" ns1=$count"
1222	fi
1223	if [ -z "$count" ]; then
1224		print_skip
1225	elif { [ "$count" != $csum_ns1 ] && [ $allow_multi_errors_ns1 -eq 0 ]; } ||
1226	   { [ "$count" -lt $csum_ns1 ] && [ $allow_multi_errors_ns1 -eq 1 ]; }; then
1227		fail_test "got $count data checksum error[s] expected $csum_ns1"
1228	else
1229		print_ok
1230	fi
1231	print_check "csum"
1232	count=$(mptcp_lib_get_counter ${ns2} "MPTcpExtDataCsumErr")
1233	if [ "$count" != "$csum_ns2" ]; then
1234		extra_msg+=" ns2=$count"
1235	fi
1236	if [ -z "$count" ]; then
1237		print_skip
1238	elif { [ "$count" != $csum_ns2 ] && [ $allow_multi_errors_ns2 -eq 0 ]; } ||
1239	   { [ "$count" -lt $csum_ns2 ] && [ $allow_multi_errors_ns2 -eq 1 ]; }; then
1240		fail_test "got $count data checksum error[s] expected $csum_ns2"
1241	else
1242		print_ok
1243	fi
1244
1245	print_info "$extra_msg"
1246}
1247
1248chk_fail_nr()
1249{
1250	local fail_tx=$1
1251	local fail_rx=$2
1252	local ns_invert=${3:-""}
1253	local count
1254	local ns_tx=$ns1
1255	local ns_rx=$ns2
1256	local extra_msg=""
1257	local allow_tx_lost=0
1258	local allow_rx_lost=0
1259
1260	if [[ $ns_invert = "invert" ]]; then
1261		ns_tx=$ns2
1262		ns_rx=$ns1
1263		extra_msg="invert"
1264	fi
1265
1266	if [[ "${fail_tx}" = "-"* ]]; then
1267		allow_tx_lost=1
1268		fail_tx=${fail_tx:1}
1269	fi
1270	if [[ "${fail_rx}" = "-"* ]]; then
1271		allow_rx_lost=1
1272		fail_rx=${fail_rx:1}
1273	fi
1274
1275	print_check "ftx"
1276	count=$(mptcp_lib_get_counter ${ns_tx} "MPTcpExtMPFailTx")
1277	if [ "$count" != "$fail_tx" ]; then
1278		extra_msg+=",tx=$count"
1279	fi
1280	if [ -z "$count" ]; then
1281		print_skip
1282	elif { [ "$count" != "$fail_tx" ] && [ $allow_tx_lost -eq 0 ]; } ||
1283	   { [ "$count" -gt "$fail_tx" ] && [ $allow_tx_lost -eq 1 ]; }; then
1284		fail_test "got $count MP_FAIL[s] TX expected $fail_tx"
1285	else
1286		print_ok
1287	fi
1288
1289	print_check "failrx"
1290	count=$(mptcp_lib_get_counter ${ns_rx} "MPTcpExtMPFailRx")
1291	if [ "$count" != "$fail_rx" ]; then
1292		extra_msg+=",rx=$count"
1293	fi
1294	if [ -z "$count" ]; then
1295		print_skip
1296	elif { [ "$count" != "$fail_rx" ] && [ $allow_rx_lost -eq 0 ]; } ||
1297	   { [ "$count" -gt "$fail_rx" ] && [ $allow_rx_lost -eq 1 ]; }; then
1298		fail_test "got $count MP_FAIL[s] RX expected $fail_rx"
1299	else
1300		print_ok
1301	fi
1302
1303	print_info "$extra_msg"
1304}
1305
1306chk_fclose_nr()
1307{
1308	local fclose_tx=$1
1309	local fclose_rx=$2
1310	local ns_invert=$3
1311	local count
1312	local ns_tx=$ns2
1313	local ns_rx=$ns1
1314	local extra_msg=""
1315
1316	if [[ $ns_invert = "invert" ]]; then
1317		ns_tx=$ns1
1318		ns_rx=$ns2
1319		extra_msg="invert"
1320	fi
1321
1322	print_check "ctx"
1323	count=$(mptcp_lib_get_counter ${ns_tx} "MPTcpExtMPFastcloseTx")
1324	if [ -z "$count" ]; then
1325		print_skip
1326	elif [ "$count" != "$fclose_tx" ]; then
1327		extra_msg+=",tx=$count"
1328		fail_test "got $count MP_FASTCLOSE[s] TX expected $fclose_tx"
1329	else
1330		print_ok
1331	fi
1332
1333	print_check "fclzrx"
1334	count=$(mptcp_lib_get_counter ${ns_rx} "MPTcpExtMPFastcloseRx")
1335	if [ -z "$count" ]; then
1336		print_skip
1337	elif [ "$count" != "$fclose_rx" ]; then
1338		extra_msg+=",rx=$count"
1339		fail_test "got $count MP_FASTCLOSE[s] RX expected $fclose_rx"
1340	else
1341		print_ok
1342	fi
1343
1344	print_info "$extra_msg"
1345}
1346
1347chk_rst_nr()
1348{
1349	local rst_tx=$1
1350	local rst_rx=$2
1351	local ns_invert=${3:-""}
1352	local count
1353	local ns_tx=$ns1
1354	local ns_rx=$ns2
1355	local extra_msg=""
1356
1357	if [[ $ns_invert = "invert" ]]; then
1358		ns_tx=$ns2
1359		ns_rx=$ns1
1360		extra_msg="invert"
1361	fi
1362
1363	print_check "rtx"
1364	count=$(mptcp_lib_get_counter ${ns_tx} "MPTcpExtMPRstTx")
1365	if [ -z "$count" ]; then
1366		print_skip
1367	# accept more rst than expected except if we don't expect any
1368	elif { [ $rst_tx -ne 0 ] && [ $count -lt $rst_tx ]; } ||
1369	     { [ $rst_tx -eq 0 ] && [ $count -ne 0 ]; }; then
1370		fail_test "got $count MP_RST[s] TX expected $rst_tx"
1371	else
1372		print_ok
1373	fi
1374
1375	print_check "rstrx"
1376	count=$(mptcp_lib_get_counter ${ns_rx} "MPTcpExtMPRstRx")
1377	if [ -z "$count" ]; then
1378		print_skip
1379	# accept more rst than expected except if we don't expect any
1380	elif { [ $rst_rx -ne 0 ] && [ $count -lt $rst_rx ]; } ||
1381	     { [ $rst_rx -eq 0 ] && [ $count -ne 0 ]; }; then
1382		fail_test "got $count MP_RST[s] RX expected $rst_rx"
1383	else
1384		print_ok
1385	fi
1386
1387	print_info "$extra_msg"
1388}
1389
1390chk_infi_nr()
1391{
1392	local infi_tx=$1
1393	local infi_rx=$2
1394	local count
1395
1396	print_check "itx"
1397	count=$(mptcp_lib_get_counter ${ns2} "MPTcpExtInfiniteMapTx")
1398	if [ -z "$count" ]; then
1399		print_skip
1400	elif [ "$count" != "$infi_tx" ]; then
1401		fail_test "got $count infinite map[s] TX expected $infi_tx"
1402	else
1403		print_ok
1404	fi
1405
1406	print_check "infirx"
1407	count=$(mptcp_lib_get_counter ${ns1} "MPTcpExtInfiniteMapRx")
1408	if [ -z "$count" ]; then
1409		print_skip
1410	elif [ "$count" != "$infi_rx" ]; then
1411		fail_test "got $count infinite map[s] RX expected $infi_rx"
1412	else
1413		print_ok
1414	fi
1415}
1416
1417chk_join_nr()
1418{
1419	local syn_nr=$1
1420	local syn_ack_nr=$2
1421	local ack_nr=$3
1422	local csum_ns1=${4:-0}
1423	local csum_ns2=${5:-0}
1424	local fail_nr=${6:-0}
1425	local rst_nr=${7:-0}
1426	local infi_nr=${8:-0}
1427	local corrupted_pkts=${9:-0}
1428	local count
1429	local with_cookie
1430
1431	if [ "${corrupted_pkts}" -gt 0 ]; then
1432		print_info "${corrupted_pkts} corrupted pkts"
1433	fi
1434
1435	print_check "syn"
1436	count=$(mptcp_lib_get_counter ${ns1} "MPTcpExtMPJoinSynRx")
1437	if [ -z "$count" ]; then
1438		print_skip
1439	elif [ "$count" != "$syn_nr" ]; then
1440		fail_test "got $count JOIN[s] syn expected $syn_nr"
1441	else
1442		print_ok
1443	fi
1444
1445	print_check "synack"
1446	with_cookie=$(ip netns exec $ns2 sysctl -n net.ipv4.tcp_syncookies)
1447	count=$(mptcp_lib_get_counter ${ns2} "MPTcpExtMPJoinSynAckRx")
1448	if [ -z "$count" ]; then
1449		print_skip
1450	elif [ "$count" != "$syn_ack_nr" ]; then
1451		# simult connections exceeding the limit with cookie enabled could go up to
1452		# synack validation as the conn limit can be enforced reliably only after
1453		# the subflow creation
1454		if [ "$with_cookie" = 2 ] && [ "$count" -gt "$syn_ack_nr" ] && [ "$count" -le "$syn_nr" ]; then
1455			print_ok
1456		else
1457			fail_test "got $count JOIN[s] synack expected $syn_ack_nr"
1458		fi
1459	else
1460		print_ok
1461	fi
1462
1463	print_check "ack"
1464	count=$(mptcp_lib_get_counter ${ns1} "MPTcpExtMPJoinAckRx")
1465	if [ -z "$count" ]; then
1466		print_skip
1467	elif [ "$count" != "$ack_nr" ]; then
1468		fail_test "got $count JOIN[s] ack expected $ack_nr"
1469	else
1470		print_ok
1471	fi
1472	if $validate_checksum; then
1473		chk_csum_nr $csum_ns1 $csum_ns2
1474		chk_fail_nr $fail_nr $fail_nr
1475		chk_rst_nr $rst_nr $rst_nr
1476		chk_infi_nr $infi_nr $infi_nr
1477	fi
1478}
1479
1480# a negative value for 'stale_max' means no upper bound:
1481# for bidirectional transfer, if one peer sleep for a while
1482# - as these tests do - we can have a quite high number of
1483# stale/recover conversions, proportional to
1484# sleep duration/ MPTCP-level RTX interval.
1485chk_stale_nr()
1486{
1487	local ns=$1
1488	local stale_min=$2
1489	local stale_max=$3
1490	local stale_delta=$4
1491	local dump_stats
1492	local stale_nr
1493	local recover_nr
1494
1495	print_check "stale"
1496
1497	stale_nr=$(mptcp_lib_get_counter ${ns} "MPTcpExtSubflowStale")
1498	recover_nr=$(mptcp_lib_get_counter ${ns} "MPTcpExtSubflowRecover")
1499	if [ -z "$stale_nr" ] || [ -z "$recover_nr" ]; then
1500		print_skip
1501	elif [ $stale_nr -lt $stale_min ] ||
1502	   { [ $stale_max -gt 0 ] && [ $stale_nr -gt $stale_max ]; } ||
1503	   [ $((stale_nr - recover_nr)) -ne $stale_delta ]; then
1504		fail_test "got $stale_nr stale[s] $recover_nr recover[s], " \
1505		     " expected stale in range [$stale_min..$stale_max]," \
1506		     " stale-recover delta $stale_delta"
1507		dump_stats=1
1508	else
1509		print_ok
1510	fi
1511
1512	if [ "${dump_stats}" = 1 ]; then
1513		echo $ns stats
1514		ip netns exec $ns ip -s link show
1515		ip netns exec $ns nstat -as | grep MPTcp
1516	fi
1517}
1518
1519chk_add_nr()
1520{
1521	local add_nr=$1
1522	local echo_nr=$2
1523	local port_nr=${3:-0}
1524	local syn_nr=${4:-$port_nr}
1525	local syn_ack_nr=${5:-$port_nr}
1526	local ack_nr=${6:-$port_nr}
1527	local mis_syn_nr=${7:-0}
1528	local mis_ack_nr=${8:-0}
1529	local count
1530	local timeout
1531
1532	timeout=$(ip netns exec $ns1 sysctl -n net.mptcp.add_addr_timeout)
1533
1534	print_check "add"
1535	count=$(mptcp_lib_get_counter ${ns2} "MPTcpExtAddAddr")
1536	if [ -z "$count" ]; then
1537		print_skip
1538	# if the test configured a short timeout tolerate greater then expected
1539	# add addrs options, due to retransmissions
1540	elif [ "$count" != "$add_nr" ] && { [ "$timeout" -gt 1 ] || [ "$count" -lt "$add_nr" ]; }; then
1541		fail_test "got $count ADD_ADDR[s] expected $add_nr"
1542	else
1543		print_ok
1544	fi
1545
1546	print_check "echo"
1547	count=$(mptcp_lib_get_counter ${ns1} "MPTcpExtEchoAdd")
1548	if [ -z "$count" ]; then
1549		print_skip
1550	elif [ "$count" != "$echo_nr" ]; then
1551		fail_test "got $count ADD_ADDR echo[s] expected $echo_nr"
1552	else
1553		print_ok
1554	fi
1555
1556	if [ $port_nr -gt 0 ]; then
1557		print_check "pt"
1558		count=$(mptcp_lib_get_counter ${ns2} "MPTcpExtPortAdd")
1559		if [ -z "$count" ]; then
1560			print_skip
1561		elif [ "$count" != "$port_nr" ]; then
1562			fail_test "got $count ADD_ADDR[s] with a port-number expected $port_nr"
1563		else
1564			print_ok
1565		fi
1566
1567		print_check "syn"
1568		count=$(mptcp_lib_get_counter ${ns1} "MPTcpExtMPJoinPortSynRx")
1569		if [ -z "$count" ]; then
1570			print_skip
1571		elif [ "$count" != "$syn_nr" ]; then
1572			fail_test "got $count JOIN[s] syn with a different \
1573				   port-number expected $syn_nr"
1574		else
1575			print_ok
1576		fi
1577
1578		print_check "synack"
1579		count=$(mptcp_lib_get_counter ${ns2} "MPTcpExtMPJoinPortSynAckRx")
1580		if [ -z "$count" ]; then
1581			print_skip
1582		elif [ "$count" != "$syn_ack_nr" ]; then
1583			fail_test "got $count JOIN[s] synack with a different \
1584				   port-number expected $syn_ack_nr"
1585		else
1586			print_ok
1587		fi
1588
1589		print_check "ack"
1590		count=$(mptcp_lib_get_counter ${ns1} "MPTcpExtMPJoinPortAckRx")
1591		if [ -z "$count" ]; then
1592			print_skip
1593		elif [ "$count" != "$ack_nr" ]; then
1594			fail_test "got $count JOIN[s] ack with a different \
1595				   port-number expected $ack_nr"
1596		else
1597			print_ok
1598		fi
1599
1600		print_check "syn"
1601		count=$(mptcp_lib_get_counter ${ns1} "MPTcpExtMismatchPortSynRx")
1602		if [ -z "$count" ]; then
1603			print_skip
1604		elif [ "$count" != "$mis_syn_nr" ]; then
1605			fail_test "got $count JOIN[s] syn with a mismatched \
1606				   port-number expected $mis_syn_nr"
1607		else
1608			print_ok
1609		fi
1610
1611		print_check "ack"
1612		count=$(mptcp_lib_get_counter ${ns1} "MPTcpExtMismatchPortAckRx")
1613		if [ -z "$count" ]; then
1614			print_skip
1615		elif [ "$count" != "$mis_ack_nr" ]; then
1616			fail_test "got $count JOIN[s] ack with a mismatched \
1617				   port-number expected $mis_ack_nr"
1618		else
1619			print_ok
1620		fi
1621	fi
1622}
1623
1624chk_add_tx_nr()
1625{
1626	local add_tx_nr=$1
1627	local echo_tx_nr=$2
1628	local timeout
1629	local count
1630
1631	timeout=$(ip netns exec $ns1 sysctl -n net.mptcp.add_addr_timeout)
1632
1633	print_check "add TX"
1634	count=$(mptcp_lib_get_counter ${ns1} "MPTcpExtAddAddrTx")
1635	if [ -z "$count" ]; then
1636		print_skip
1637	# if the test configured a short timeout tolerate greater then expected
1638	# add addrs options, due to retransmissions
1639	elif [ "$count" != "$add_tx_nr" ] && { [ "$timeout" -gt 1 ] || [ "$count" -lt "$add_tx_nr" ]; }; then
1640		fail_test "got $count ADD_ADDR[s] TX, expected $add_tx_nr"
1641	else
1642		print_ok
1643	fi
1644
1645	print_check "echo TX"
1646	count=$(mptcp_lib_get_counter ${ns2} "MPTcpExtEchoAddTx")
1647	if [ -z "$count" ]; then
1648		print_skip
1649	elif [ "$count" != "$echo_tx_nr" ]; then
1650		fail_test "got $count ADD_ADDR echo[s] TX, expected $echo_tx_nr"
1651	else
1652		print_ok
1653	fi
1654}
1655
1656chk_rm_nr()
1657{
1658	local rm_addr_nr=$1
1659	local rm_subflow_nr=$2
1660	local invert
1661	local simult
1662	local count
1663	local addr_ns=$ns1
1664	local subflow_ns=$ns2
1665	local extra_msg=""
1666
1667	shift 2
1668	while [ -n "$1" ]; do
1669		[ "$1" = "invert" ] && invert=true
1670		[ "$1" = "simult" ] && simult=true
1671		shift
1672	done
1673
1674	if [ -z $invert ]; then
1675		addr_ns=$ns1
1676		subflow_ns=$ns2
1677	elif [ $invert = "true" ]; then
1678		addr_ns=$ns2
1679		subflow_ns=$ns1
1680		extra_msg="invert"
1681	fi
1682
1683	print_check "rm"
1684	count=$(mptcp_lib_get_counter ${addr_ns} "MPTcpExtRmAddr")
1685	if [ -z "$count" ]; then
1686		print_skip
1687	elif [ "$count" != "$rm_addr_nr" ]; then
1688		fail_test "got $count RM_ADDR[s] expected $rm_addr_nr"
1689	else
1690		print_ok
1691	fi
1692
1693	print_check "rmsf"
1694	count=$(mptcp_lib_get_counter ${subflow_ns} "MPTcpExtRmSubflow")
1695	if [ -z "$count" ]; then
1696		print_skip
1697	elif [ -n "$simult" ]; then
1698		local cnt suffix
1699
1700		cnt=$(mptcp_lib_get_counter ${addr_ns} "MPTcpExtRmSubflow")
1701
1702		# in case of simult flush, the subflow removal count on each side is
1703		# unreliable
1704		count=$((count + cnt))
1705		if [ "$count" != "$rm_subflow_nr" ]; then
1706			suffix="$count in [$rm_subflow_nr:$((rm_subflow_nr*2))]"
1707			extra_msg+=" simult"
1708		fi
1709		if [ $count -ge "$rm_subflow_nr" ] && \
1710		   [ "$count" -le "$((rm_subflow_nr *2 ))" ]; then
1711			print_ok "$suffix"
1712		else
1713			fail_test "got $count RM_SUBFLOW[s] expected in range [$rm_subflow_nr:$((rm_subflow_nr*2))]"
1714		fi
1715	elif [ "$count" != "$rm_subflow_nr" ]; then
1716		fail_test "got $count RM_SUBFLOW[s] expected $rm_subflow_nr"
1717	else
1718		print_ok
1719	fi
1720
1721	print_info "$extra_msg"
1722}
1723
1724chk_rm_tx_nr()
1725{
1726	local rm_addr_tx_nr=$1
1727
1728	print_check "rm TX"
1729	count=$(mptcp_lib_get_counter ${ns2} "MPTcpExtRmAddrTx")
1730	if [ -z "$count" ]; then
1731		print_skip
1732	elif [ "$count" != "$rm_addr_tx_nr" ]; then
1733		fail_test "got $count RM_ADDR[s] expected $rm_addr_tx_nr"
1734	else
1735		print_ok
1736	fi
1737}
1738
1739chk_prio_nr()
1740{
1741	local mp_prio_nr_tx=$1
1742	local mp_prio_nr_rx=$2
1743	local count
1744
1745	print_check "ptx"
1746	count=$(mptcp_lib_get_counter ${ns1} "MPTcpExtMPPrioTx")
1747	if [ -z "$count" ]; then
1748		print_skip
1749	elif [ "$count" != "$mp_prio_nr_tx" ]; then
1750		fail_test "got $count MP_PRIO[s] TX expected $mp_prio_nr_tx"
1751	else
1752		print_ok
1753	fi
1754
1755	print_check "prx"
1756	count=$(mptcp_lib_get_counter ${ns1} "MPTcpExtMPPrioRx")
1757	if [ -z "$count" ]; then
1758		print_skip
1759	elif [ "$count" != "$mp_prio_nr_rx" ]; then
1760		fail_test "got $count MP_PRIO[s] RX expected $mp_prio_nr_rx"
1761	else
1762		print_ok
1763	fi
1764}
1765
1766chk_subflow_nr()
1767{
1768	local msg="$1"
1769	local subflow_nr=$2
1770	local cnt1
1771	local cnt2
1772	local dump_stats
1773
1774	print_check "${msg}"
1775
1776	cnt1=$(ss -N $ns1 -tOni | grep -c token)
1777	cnt2=$(ss -N $ns2 -tOni | grep -c token)
1778	if [ "$cnt1" != "$subflow_nr" ] || [ "$cnt2" != "$subflow_nr" ]; then
1779		fail_test "got $cnt1:$cnt2 subflows expected $subflow_nr"
1780		dump_stats=1
1781	else
1782		print_ok
1783	fi
1784
1785	if [ "${dump_stats}" = 1 ]; then
1786		ss -N $ns1 -tOni
1787		ss -N $ns1 -tOni | grep token
1788		ip -n $ns1 mptcp endpoint
1789	fi
1790}
1791
1792chk_mptcp_info()
1793{
1794	local info1=$1
1795	local exp1=$2
1796	local info2=$3
1797	local exp2=$4
1798	local cnt1
1799	local cnt2
1800	local dump_stats
1801
1802	print_check "mptcp_info ${info1:0:15}=$exp1:$exp2"
1803
1804	cnt1=$(ss -N $ns1 -inmHM | mptcp_lib_get_info_value "$info1" "$info1")
1805	cnt2=$(ss -N $ns2 -inmHM | mptcp_lib_get_info_value "$info2" "$info2")
1806	# 'ss' only display active connections and counters that are not 0.
1807	[ -z "$cnt1" ] && cnt1=0
1808	[ -z "$cnt2" ] && cnt2=0
1809
1810	if [ "$cnt1" != "$exp1" ] || [ "$cnt2" != "$exp2" ]; then
1811		fail_test "got $cnt1:$cnt2 $info1:$info2 expected $exp1:$exp2"
1812		dump_stats=1
1813	else
1814		print_ok
1815	fi
1816
1817	if [ "$dump_stats" = 1 ]; then
1818		ss -N $ns1 -inmHM
1819		ss -N $ns2 -inmHM
1820	fi
1821}
1822
1823# $1: subflows in ns1 ; $2: subflows in ns2
1824# number of all subflows, including the initial subflow.
1825chk_subflows_total()
1826{
1827	local cnt1
1828	local cnt2
1829	local info="subflows_total"
1830	local dump_stats
1831
1832	# if subflows_total counter is supported, use it:
1833	if [ -n "$(ss -N $ns1 -inmHM | mptcp_lib_get_info_value $info $info)" ]; then
1834		chk_mptcp_info $info $1 $info $2
1835		return
1836	fi
1837
1838	print_check "$info $1:$2"
1839
1840	# if not, count the TCP connections that are in fact MPTCP subflows
1841	cnt1=$(ss -N $ns1 -ti state established state syn-sent state syn-recv |
1842	       grep -c tcp-ulp-mptcp)
1843	cnt2=$(ss -N $ns2 -ti state established state syn-sent state syn-recv |
1844	       grep -c tcp-ulp-mptcp)
1845
1846	if [ "$1" != "$cnt1" ] || [ "$2" != "$cnt2" ]; then
1847		fail_test "got subflows $cnt1:$cnt2 expected $1:$2"
1848		dump_stats=1
1849	else
1850		print_ok
1851	fi
1852
1853	if [ "$dump_stats" = 1 ]; then
1854		ss -N $ns1 -ti
1855		ss -N $ns2 -ti
1856	fi
1857}
1858
1859chk_link_usage()
1860{
1861	local ns=$1
1862	local link=$2
1863	local out=$3
1864	local expected_rate=$4
1865
1866	local tx_link tx_total
1867	tx_link=$(ip netns exec $ns cat /sys/class/net/$link/statistics/tx_bytes)
1868	tx_total=$(stat --format=%s $out)
1869	local tx_rate=$((tx_link * 100 / tx_total))
1870	local tolerance=5
1871
1872	print_check "link usage"
1873	if [ $tx_rate -lt $((expected_rate - tolerance)) ] || \
1874	   [ $tx_rate -gt $((expected_rate + tolerance)) ]; then
1875		fail_test "got $tx_rate% usage, expected $expected_rate%"
1876	else
1877		print_ok
1878	fi
1879}
1880
1881wait_attempt_fail()
1882{
1883	local timeout_ms=$((timeout_poll * 1000))
1884	local time=0
1885	local ns=$1
1886
1887	while [ $time -lt $timeout_ms ]; do
1888		local cnt
1889
1890		cnt=$(mptcp_lib_get_counter ${ns} "TcpAttemptFails")
1891
1892		[ "$cnt" = 1 ] && return 1
1893		time=$((time + 100))
1894		sleep 0.1
1895	done
1896	return 1
1897}
1898
1899set_userspace_pm()
1900{
1901	local ns=$1
1902
1903	ip netns exec $ns sysctl -q net.mptcp.pm_type=1
1904}
1905
1906subflows_tests()
1907{
1908	if reset "no JOIN"; then
1909		run_tests $ns1 $ns2 10.0.1.1
1910		chk_join_nr 0 0 0
1911	fi
1912
1913	# subflow limited by client
1914	if reset "single subflow, limited by client"; then
1915		pm_nl_set_limits $ns1 0 0
1916		pm_nl_set_limits $ns2 0 0
1917		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
1918		run_tests $ns1 $ns2 10.0.1.1
1919		chk_join_nr 0 0 0
1920	fi
1921
1922	# subflow limited by server
1923	if reset "single subflow, limited by server"; then
1924		pm_nl_set_limits $ns1 0 0
1925		pm_nl_set_limits $ns2 0 1
1926		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
1927		run_tests $ns1 $ns2 10.0.1.1
1928		chk_join_nr 1 1 0
1929	fi
1930
1931	# subflow
1932	if reset "single subflow"; then
1933		pm_nl_set_limits $ns1 0 1
1934		pm_nl_set_limits $ns2 0 1
1935		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
1936		run_tests $ns1 $ns2 10.0.1.1
1937		chk_join_nr 1 1 1
1938	fi
1939
1940	# multiple subflows
1941	if reset "multiple subflows"; then
1942		pm_nl_set_limits $ns1 0 2
1943		pm_nl_set_limits $ns2 0 2
1944		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
1945		pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow
1946		run_tests $ns1 $ns2 10.0.1.1
1947		chk_join_nr 2 2 2
1948	fi
1949
1950	# multiple subflows limited by server
1951	if reset "multiple subflows, limited by server"; then
1952		pm_nl_set_limits $ns1 0 1
1953		pm_nl_set_limits $ns2 0 2
1954		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
1955		pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow
1956		run_tests $ns1 $ns2 10.0.1.1
1957		chk_join_nr 2 2 1
1958	fi
1959
1960	# single subflow, dev
1961	if reset "single subflow, dev"; then
1962		pm_nl_set_limits $ns1 0 1
1963		pm_nl_set_limits $ns2 0 1
1964		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow dev ns2eth3
1965		run_tests $ns1 $ns2 10.0.1.1
1966		chk_join_nr 1 1 1
1967	fi
1968}
1969
1970subflows_error_tests()
1971{
1972	# If a single subflow is configured, and matches the MPC src
1973	# address, no additional subflow should be created
1974	if reset "no MPC reuse with single endpoint"; then
1975		pm_nl_set_limits $ns1 0 1
1976		pm_nl_set_limits $ns2 0 1
1977		pm_nl_add_endpoint $ns2 10.0.1.2 flags subflow
1978		speed=slow \
1979			run_tests $ns1 $ns2 10.0.1.1
1980		chk_join_nr 0 0 0
1981	fi
1982
1983	# multiple subflows, with subflow creation error
1984	if reset_with_tcp_filter "multi subflows, with failing subflow" ns1 10.0.3.2 REJECT &&
1985	   continue_if mptcp_lib_kallsyms_has "mptcp_pm_subflow_check_next$"; then
1986		pm_nl_set_limits $ns1 0 2
1987		pm_nl_set_limits $ns2 0 2
1988		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
1989		pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow
1990		speed=slow \
1991			run_tests $ns1 $ns2 10.0.1.1
1992		chk_join_nr 1 1 1
1993	fi
1994
1995	# multiple subflows, with subflow timeout on MPJ
1996	if reset_with_tcp_filter "multi subflows, with subflow timeout" ns1 10.0.3.2 DROP &&
1997	   continue_if mptcp_lib_kallsyms_has "mptcp_pm_subflow_check_next$"; then
1998		pm_nl_set_limits $ns1 0 2
1999		pm_nl_set_limits $ns2 0 2
2000		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
2001		pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow
2002		speed=slow \
2003			run_tests $ns1 $ns2 10.0.1.1
2004		chk_join_nr 1 1 1
2005	fi
2006
2007	# multiple subflows, check that the endpoint corresponding to
2008	# closed subflow (due to reset) is not reused if additional
2009	# subflows are added later
2010	if reset_with_tcp_filter "multi subflows, fair usage on close" ns1 10.0.3.2 REJECT &&
2011	   continue_if mptcp_lib_kallsyms_has "mptcp_pm_subflow_check_next$"; then
2012		pm_nl_set_limits $ns1 0 1
2013		pm_nl_set_limits $ns2 0 1
2014		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
2015		speed=slow \
2016			run_tests $ns1 $ns2 10.0.1.1 &
2017
2018		# mpj subflow will be in TW after the reset
2019		wait_attempt_fail $ns2
2020		pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow
2021		wait
2022
2023		# additional subflow could be created only if the PM select
2024		# the later endpoint, skipping the already used one
2025		chk_join_nr 1 1 1
2026	fi
2027}
2028
2029signal_address_tests()
2030{
2031	# add_address, unused
2032	if reset "unused signal address"; then
2033		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
2034		run_tests $ns1 $ns2 10.0.1.1
2035		chk_join_nr 0 0 0
2036		chk_add_tx_nr 1 1
2037		chk_add_nr 1 1
2038	fi
2039
2040	# accept and use add_addr
2041	if reset "signal address"; then
2042		pm_nl_set_limits $ns1 0 1
2043		pm_nl_set_limits $ns2 1 1
2044		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
2045		run_tests $ns1 $ns2 10.0.1.1
2046		chk_join_nr 1 1 1
2047		chk_add_nr 1 1
2048	fi
2049
2050	# accept and use add_addr with an additional subflow
2051	# note: signal address in server ns and local addresses in client ns must
2052	# belong to different subnets or one of the listed local address could be
2053	# used for 'add_addr' subflow
2054	if reset "subflow and signal"; then
2055		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
2056		pm_nl_set_limits $ns1 0 2
2057		pm_nl_set_limits $ns2 1 2
2058		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
2059		run_tests $ns1 $ns2 10.0.1.1
2060		chk_join_nr 2 2 2
2061		chk_add_nr 1 1
2062	fi
2063
2064	# accept and use add_addr with additional subflows
2065	if reset "multiple subflows and signal"; then
2066		pm_nl_set_limits $ns1 0 3
2067		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
2068		pm_nl_set_limits $ns2 1 3
2069		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
2070		pm_nl_add_endpoint $ns2 10.0.4.2 flags subflow
2071		run_tests $ns1 $ns2 10.0.1.1
2072		chk_join_nr 3 3 3
2073		chk_add_nr 1 1
2074	fi
2075
2076	# signal addresses
2077	if reset "signal addresses"; then
2078		pm_nl_set_limits $ns1 3 3
2079		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
2080		pm_nl_add_endpoint $ns1 10.0.3.1 flags signal
2081		pm_nl_add_endpoint $ns1 10.0.4.1 flags signal
2082		pm_nl_set_limits $ns2 3 3
2083		run_tests $ns1 $ns2 10.0.1.1
2084		chk_join_nr 3 3 3
2085		chk_add_nr 3 3
2086	fi
2087
2088	# signal invalid addresses
2089	if reset "signal invalid addresses"; then
2090		pm_nl_set_limits $ns1 3 3
2091		pm_nl_add_endpoint $ns1 10.0.12.1 flags signal
2092		pm_nl_add_endpoint $ns1 10.0.3.1 flags signal
2093		pm_nl_add_endpoint $ns1 10.0.14.1 flags signal
2094		pm_nl_set_limits $ns2 3 3
2095		run_tests $ns1 $ns2 10.0.1.1
2096		chk_join_nr 1 1 1
2097		chk_add_nr 3 3
2098	fi
2099
2100	# signal addresses race test
2101	if reset "signal addresses race test"; then
2102		pm_nl_set_limits $ns1 4 4
2103		pm_nl_set_limits $ns2 4 4
2104		pm_nl_add_endpoint $ns1 10.0.1.1 flags signal
2105		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
2106		pm_nl_add_endpoint $ns1 10.0.3.1 flags signal
2107		pm_nl_add_endpoint $ns1 10.0.4.1 flags signal
2108		pm_nl_add_endpoint $ns2 10.0.1.2 flags signal
2109		pm_nl_add_endpoint $ns2 10.0.2.2 flags signal
2110		pm_nl_add_endpoint $ns2 10.0.3.2 flags signal
2111		pm_nl_add_endpoint $ns2 10.0.4.2 flags signal
2112
2113		# the peer could possibly miss some addr notification, allow retransmission
2114		ip netns exec $ns1 sysctl -q net.mptcp.add_addr_timeout=1
2115		speed=slow \
2116			run_tests $ns1 $ns2 10.0.1.1
2117
2118		# It is not directly linked to the commit introducing this
2119		# symbol but for the parent one which is linked anyway.
2120		if ! mptcp_lib_kallsyms_has "mptcp_pm_subflow_check_next$"; then
2121			chk_join_nr 3 3 2
2122			chk_add_nr 4 4
2123		else
2124			chk_join_nr 3 3 3
2125			# the server will not signal the address terminating
2126			# the MPC subflow
2127			chk_add_nr 3 3
2128		fi
2129	fi
2130}
2131
2132link_failure_tests()
2133{
2134	# accept and use add_addr with additional subflows and link loss
2135	if reset "multiple flows, signal, link failure"; then
2136		# without any b/w limit each veth could spool the packets and get
2137		# them acked at xmit time, so that the corresponding subflow will
2138		# have almost always no outstanding pkts, the scheduler will pick
2139		# always the first subflow and we will have hard time testing
2140		# active backup and link switch-over.
2141		# Let's set some arbitrary (low) virtual link limits.
2142		init_shapers
2143		pm_nl_set_limits $ns1 0 3
2144		pm_nl_add_endpoint $ns1 10.0.2.1 dev ns1eth2 flags signal
2145		pm_nl_set_limits $ns2 1 3
2146		pm_nl_add_endpoint $ns2 10.0.3.2 dev ns2eth3 flags subflow
2147		pm_nl_add_endpoint $ns2 10.0.4.2 dev ns2eth4 flags subflow
2148		test_linkfail=1 \
2149			run_tests $ns1 $ns2 10.0.1.1
2150		chk_join_nr 3 3 3
2151		chk_add_nr 1 1
2152		chk_stale_nr $ns2 1 5 1
2153	fi
2154
2155	# accept and use add_addr with additional subflows and link loss
2156	# for bidirectional transfer
2157	if reset "multi flows, signal, bidi, link fail"; then
2158		init_shapers
2159		pm_nl_set_limits $ns1 0 3
2160		pm_nl_add_endpoint $ns1 10.0.2.1 dev ns1eth2 flags signal
2161		pm_nl_set_limits $ns2 1 3
2162		pm_nl_add_endpoint $ns2 10.0.3.2 dev ns2eth3 flags subflow
2163		pm_nl_add_endpoint $ns2 10.0.4.2 dev ns2eth4 flags subflow
2164		test_linkfail=2 \
2165			run_tests $ns1 $ns2 10.0.1.1
2166		chk_join_nr 3 3 3
2167		chk_add_nr 1 1
2168		chk_stale_nr $ns2 1 -1 1
2169	fi
2170
2171	# 2 subflows plus 1 backup subflow with a lossy link, backup
2172	# will never be used
2173	if reset "backup subflow unused, link failure"; then
2174		init_shapers
2175		pm_nl_set_limits $ns1 0 2
2176		pm_nl_add_endpoint $ns1 10.0.2.1 dev ns1eth2 flags signal
2177		pm_nl_set_limits $ns2 1 2
2178		pm_nl_add_endpoint $ns2 10.0.3.2 dev ns2eth3 flags subflow,backup
2179		FAILING_LINKS="1" test_linkfail=1 \
2180			run_tests $ns1 $ns2 10.0.1.1
2181		chk_join_nr 2 2 2
2182		chk_add_nr 1 1
2183		chk_link_usage $ns2 ns2eth3 $cinsent 0
2184	fi
2185
2186	# 2 lossy links after half transfer, backup will get half of
2187	# the traffic
2188	if reset "backup flow used, multi links fail"; then
2189		init_shapers
2190		pm_nl_set_limits $ns1 0 2
2191		pm_nl_add_endpoint $ns1 10.0.2.1 dev ns1eth2 flags signal
2192		pm_nl_set_limits $ns2 1 2
2193		pm_nl_add_endpoint $ns2 10.0.3.2 dev ns2eth3 flags subflow,backup
2194		FAILING_LINKS="1 2" test_linkfail=1 \
2195			run_tests $ns1 $ns2 10.0.1.1
2196		chk_join_nr 2 2 2
2197		chk_add_nr 1 1
2198		chk_stale_nr $ns2 2 4 2
2199		chk_link_usage $ns2 ns2eth3 $cinsent 50
2200	fi
2201
2202	# use a backup subflow with the first subflow on a lossy link
2203	# for bidirectional transfer
2204	if reset "backup flow used, bidi, link failure"; then
2205		init_shapers
2206		pm_nl_set_limits $ns1 0 2
2207		pm_nl_add_endpoint $ns1 10.0.2.1 dev ns1eth2 flags signal
2208		pm_nl_set_limits $ns2 1 3
2209		pm_nl_add_endpoint $ns2 10.0.3.2 dev ns2eth3 flags subflow,backup
2210		FAILING_LINKS="1 2" test_linkfail=2 \
2211			run_tests $ns1 $ns2 10.0.1.1
2212		chk_join_nr 2 2 2
2213		chk_add_nr 1 1
2214		chk_stale_nr $ns2 1 -1 2
2215		chk_link_usage $ns2 ns2eth3 $cinsent 50
2216	fi
2217}
2218
2219add_addr_timeout_tests()
2220{
2221	# add_addr timeout
2222	if reset_with_add_addr_timeout "signal address, ADD_ADDR timeout"; then
2223		pm_nl_set_limits $ns1 0 1
2224		pm_nl_set_limits $ns2 1 1
2225		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
2226		speed=slow \
2227			run_tests $ns1 $ns2 10.0.1.1
2228		chk_join_nr 1 1 1
2229		chk_add_tx_nr 4 4
2230		chk_add_nr 4 0
2231	fi
2232
2233	# add_addr timeout IPv6
2234	if reset_with_add_addr_timeout "signal address, ADD_ADDR6 timeout" 6; then
2235		pm_nl_set_limits $ns1 0 1
2236		pm_nl_set_limits $ns2 1 1
2237		pm_nl_add_endpoint $ns1 dead:beef:2::1 flags signal
2238		speed=slow \
2239			run_tests $ns1 $ns2 dead:beef:1::1
2240		chk_join_nr 1 1 1
2241		chk_add_nr 4 0
2242	fi
2243
2244	# signal addresses timeout
2245	if reset_with_add_addr_timeout "signal addresses, ADD_ADDR timeout"; then
2246		pm_nl_set_limits $ns1 2 2
2247		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
2248		pm_nl_add_endpoint $ns1 10.0.3.1 flags signal
2249		pm_nl_set_limits $ns2 2 2
2250		speed=10 \
2251			run_tests $ns1 $ns2 10.0.1.1
2252		chk_join_nr 2 2 2
2253		chk_add_nr 8 0
2254	fi
2255
2256	# signal invalid addresses timeout
2257	if reset_with_add_addr_timeout "invalid address, ADD_ADDR timeout"; then
2258		pm_nl_set_limits $ns1 2 2
2259		pm_nl_add_endpoint $ns1 10.0.12.1 flags signal
2260		pm_nl_add_endpoint $ns1 10.0.3.1 flags signal
2261		pm_nl_set_limits $ns2 2 2
2262		speed=10 \
2263			run_tests $ns1 $ns2 10.0.1.1
2264		chk_join_nr 1 1 1
2265		chk_add_nr 8 0
2266	fi
2267}
2268
2269remove_tests()
2270{
2271	# single subflow, remove
2272	if reset "remove single subflow"; then
2273		pm_nl_set_limits $ns1 0 1
2274		pm_nl_set_limits $ns2 0 1
2275		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
2276		addr_nr_ns2=-1 speed=slow \
2277			run_tests $ns1 $ns2 10.0.1.1
2278		chk_join_nr 1 1 1
2279		chk_rm_tx_nr 1
2280		chk_rm_nr 1 1
2281		chk_rst_nr 0 0
2282	fi
2283
2284	# multiple subflows, remove
2285	if reset "remove multiple subflows"; then
2286		pm_nl_set_limits $ns1 0 2
2287		pm_nl_set_limits $ns2 0 2
2288		pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow
2289		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
2290		addr_nr_ns2=-2 speed=slow \
2291			run_tests $ns1 $ns2 10.0.1.1
2292		chk_join_nr 2 2 2
2293		chk_rm_nr 2 2
2294		chk_rst_nr 0 0
2295	fi
2296
2297	# single address, remove
2298	if reset "remove single address"; then
2299		pm_nl_set_limits $ns1 0 1
2300		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
2301		pm_nl_set_limits $ns2 1 1
2302		addr_nr_ns1=-1 speed=slow \
2303			run_tests $ns1 $ns2 10.0.1.1
2304		chk_join_nr 1 1 1
2305		chk_add_nr 1 1
2306		chk_rm_nr 1 1 invert
2307		chk_rst_nr 0 0
2308	fi
2309
2310	# subflow and signal, remove
2311	if reset "remove subflow and signal"; then
2312		pm_nl_set_limits $ns1 0 2
2313		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
2314		pm_nl_set_limits $ns2 1 2
2315		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
2316		addr_nr_ns1=-1 addr_nr_ns2=-1 speed=slow \
2317			run_tests $ns1 $ns2 10.0.1.1
2318		chk_join_nr 2 2 2
2319		chk_add_nr 1 1
2320		chk_rm_nr 1 1
2321		chk_rst_nr 0 0
2322	fi
2323
2324	# subflows and signal, remove
2325	if reset "remove subflows and signal"; then
2326		pm_nl_set_limits $ns1 0 3
2327		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
2328		pm_nl_set_limits $ns2 1 3
2329		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
2330		pm_nl_add_endpoint $ns2 10.0.4.2 flags subflow
2331		addr_nr_ns1=-1 addr_nr_ns2=-2 speed=10 \
2332			run_tests $ns1 $ns2 10.0.1.1
2333		chk_join_nr 3 3 3
2334		chk_add_nr 1 1
2335		chk_rm_nr 2 2
2336		chk_rst_nr 0 0
2337	fi
2338
2339	# addresses remove
2340	if reset "remove addresses"; then
2341		pm_nl_set_limits $ns1 3 3
2342		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal id 250
2343		pm_nl_add_endpoint $ns1 10.0.3.1 flags signal
2344		pm_nl_add_endpoint $ns1 10.0.4.1 flags signal
2345		pm_nl_set_limits $ns2 3 3
2346		addr_nr_ns1=-3 speed=10 \
2347			run_tests $ns1 $ns2 10.0.1.1
2348		chk_join_nr 3 3 3
2349		chk_add_nr 3 3
2350		chk_rm_nr 3 3 invert
2351		chk_rst_nr 0 0
2352	fi
2353
2354	# invalid addresses remove
2355	if reset "remove invalid addresses"; then
2356		pm_nl_set_limits $ns1 3 3
2357		pm_nl_add_endpoint $ns1 10.0.12.1 flags signal
2358		pm_nl_add_endpoint $ns1 10.0.3.1 flags signal
2359		pm_nl_add_endpoint $ns1 10.0.14.1 flags signal
2360		pm_nl_set_limits $ns2 3 3
2361		addr_nr_ns1=-3 speed=10 \
2362			run_tests $ns1 $ns2 10.0.1.1
2363		chk_join_nr 1 1 1
2364		chk_add_nr 3 3
2365		chk_rm_nr 3 1 invert
2366		chk_rst_nr 0 0
2367	fi
2368
2369	# subflows and signal, flush
2370	if reset "flush subflows and signal"; then
2371		pm_nl_set_limits $ns1 0 3
2372		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
2373		pm_nl_set_limits $ns2 1 3
2374		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
2375		pm_nl_add_endpoint $ns2 10.0.4.2 flags subflow
2376		addr_nr_ns1=-8 addr_nr_ns2=-8 speed=slow \
2377			run_tests $ns1 $ns2 10.0.1.1
2378		chk_join_nr 3 3 3
2379		chk_add_nr 1 1
2380		chk_rm_nr 1 3 invert simult
2381		chk_rst_nr 0 0
2382	fi
2383
2384	# subflows flush
2385	if reset "flush subflows"; then
2386		pm_nl_set_limits $ns1 3 3
2387		pm_nl_set_limits $ns2 3 3
2388		pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow id 150
2389		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
2390		pm_nl_add_endpoint $ns2 10.0.4.2 flags subflow
2391		addr_nr_ns1=-8 addr_nr_ns2=-8 speed=slow \
2392			run_tests $ns1 $ns2 10.0.1.1
2393		chk_join_nr 3 3 3
2394
2395		if mptcp_lib_kversion_ge 5.18; then
2396			chk_rm_tx_nr 0
2397			chk_rm_nr 0 3 simult
2398		else
2399			chk_rm_nr 3 3
2400		fi
2401		chk_rst_nr 0 0
2402	fi
2403
2404	# addresses flush
2405	if reset "flush addresses"; then
2406		pm_nl_set_limits $ns1 3 3
2407		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal id 250
2408		pm_nl_add_endpoint $ns1 10.0.3.1 flags signal
2409		pm_nl_add_endpoint $ns1 10.0.4.1 flags signal
2410		pm_nl_set_limits $ns2 3 3
2411		addr_nr_ns1=-8 addr_nr_ns2=-8 speed=slow \
2412			run_tests $ns1 $ns2 10.0.1.1
2413		chk_join_nr 3 3 3
2414		chk_add_nr 3 3
2415		chk_rm_nr 3 3 invert simult
2416		chk_rst_nr 0 0
2417	fi
2418
2419	# invalid addresses flush
2420	if reset "flush invalid addresses"; then
2421		pm_nl_set_limits $ns1 3 3
2422		pm_nl_add_endpoint $ns1 10.0.12.1 flags signal
2423		pm_nl_add_endpoint $ns1 10.0.3.1 flags signal
2424		pm_nl_add_endpoint $ns1 10.0.14.1 flags signal
2425		pm_nl_set_limits $ns2 3 3
2426		addr_nr_ns1=-8 speed=slow \
2427			run_tests $ns1 $ns2 10.0.1.1
2428		chk_join_nr 1 1 1
2429		chk_add_nr 3 3
2430		chk_rm_nr 3 1 invert
2431		chk_rst_nr 0 0
2432	fi
2433
2434	# remove id 0 subflow
2435	if reset "remove id 0 subflow"; then
2436		pm_nl_set_limits $ns1 0 1
2437		pm_nl_set_limits $ns2 0 1
2438		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
2439		addr_nr_ns2=-9 speed=slow \
2440			run_tests $ns1 $ns2 10.0.1.1
2441		chk_join_nr 1 1 1
2442		chk_rm_nr 1 1
2443		chk_rst_nr 0 0
2444	fi
2445
2446	# remove id 0 address
2447	if reset "remove id 0 address"; then
2448		pm_nl_set_limits $ns1 0 1
2449		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
2450		pm_nl_set_limits $ns2 1 1
2451		addr_nr_ns1=-9 speed=slow \
2452			run_tests $ns1 $ns2 10.0.1.1
2453		chk_join_nr 1 1 1
2454		chk_add_nr 1 1
2455		chk_rm_nr 1 1 invert
2456		chk_rst_nr 0 0 invert
2457	fi
2458}
2459
2460add_tests()
2461{
2462	# add single subflow
2463	if reset "add single subflow"; then
2464		pm_nl_set_limits $ns1 0 1
2465		pm_nl_set_limits $ns2 0 1
2466		addr_nr_ns2=1 speed=slow cestab_ns2=1 \
2467			run_tests $ns1 $ns2 10.0.1.1
2468		chk_join_nr 1 1 1
2469		chk_cestab_nr $ns2 0
2470	fi
2471
2472	# add signal address
2473	if reset "add signal address"; then
2474		pm_nl_set_limits $ns1 0 1
2475		pm_nl_set_limits $ns2 1 1
2476		addr_nr_ns1=1 speed=slow cestab_ns1=1 \
2477			run_tests $ns1 $ns2 10.0.1.1
2478		chk_join_nr 1 1 1
2479		chk_add_nr 1 1
2480		chk_cestab_nr $ns1 0
2481	fi
2482
2483	# add multiple subflows
2484	if reset "add multiple subflows"; then
2485		pm_nl_set_limits $ns1 0 2
2486		pm_nl_set_limits $ns2 0 2
2487		addr_nr_ns2=2 speed=slow cestab_ns2=1 \
2488			run_tests $ns1 $ns2 10.0.1.1
2489		chk_join_nr 2 2 2
2490		chk_cestab_nr $ns2 0
2491	fi
2492
2493	# add multiple subflows IPv6
2494	if reset "add multiple subflows IPv6"; then
2495		pm_nl_set_limits $ns1 0 2
2496		pm_nl_set_limits $ns2 0 2
2497		addr_nr_ns2=2 speed=slow cestab_ns2=1 \
2498			run_tests $ns1 $ns2 dead:beef:1::1
2499		chk_join_nr 2 2 2
2500		chk_cestab_nr $ns2 0
2501	fi
2502
2503	# add multiple addresses IPv6
2504	if reset "add multiple addresses IPv6"; then
2505		pm_nl_set_limits $ns1 0 2
2506		pm_nl_set_limits $ns2 2 2
2507		addr_nr_ns1=2 speed=slow cestab_ns1=1 \
2508			run_tests $ns1 $ns2 dead:beef:1::1
2509		chk_join_nr 2 2 2
2510		chk_add_nr 2 2
2511		chk_cestab_nr $ns1 0
2512	fi
2513}
2514
2515ipv6_tests()
2516{
2517	# subflow IPv6
2518	if reset "single subflow IPv6"; then
2519		pm_nl_set_limits $ns1 0 1
2520		pm_nl_set_limits $ns2 0 1
2521		pm_nl_add_endpoint $ns2 dead:beef:3::2 dev ns2eth3 flags subflow
2522		speed=slow \
2523			run_tests $ns1 $ns2 dead:beef:1::1
2524		chk_join_nr 1 1 1
2525	fi
2526
2527	# add_address, unused IPv6
2528	if reset "unused signal address IPv6"; then
2529		pm_nl_add_endpoint $ns1 dead:beef:2::1 flags signal
2530		speed=slow \
2531			run_tests $ns1 $ns2 dead:beef:1::1
2532		chk_join_nr 0 0 0
2533		chk_add_nr 1 1
2534	fi
2535
2536	# signal address IPv6
2537	if reset "single address IPv6"; then
2538		pm_nl_set_limits $ns1 0 1
2539		pm_nl_add_endpoint $ns1 dead:beef:2::1 flags signal
2540		pm_nl_set_limits $ns2 1 1
2541		speed=slow \
2542			run_tests $ns1 $ns2 dead:beef:1::1
2543		chk_join_nr 1 1 1
2544		chk_add_nr 1 1
2545	fi
2546
2547	# single address IPv6, remove
2548	if reset "remove single address IPv6"; then
2549		pm_nl_set_limits $ns1 0 1
2550		pm_nl_add_endpoint $ns1 dead:beef:2::1 flags signal
2551		pm_nl_set_limits $ns2 1 1
2552		addr_nr_ns1=-1 speed=slow \
2553			run_tests $ns1 $ns2 dead:beef:1::1
2554		chk_join_nr 1 1 1
2555		chk_add_nr 1 1
2556		chk_rm_nr 1 1 invert
2557	fi
2558
2559	# subflow and signal IPv6, remove
2560	if reset "remove subflow and signal IPv6"; then
2561		pm_nl_set_limits $ns1 0 2
2562		pm_nl_add_endpoint $ns1 dead:beef:2::1 flags signal
2563		pm_nl_set_limits $ns2 1 2
2564		pm_nl_add_endpoint $ns2 dead:beef:3::2 dev ns2eth3 flags subflow
2565		addr_nr_ns1=-1 addr_nr_ns2=-1 speed=slow \
2566			run_tests $ns1 $ns2 dead:beef:1::1
2567		chk_join_nr 2 2 2
2568		chk_add_nr 1 1
2569		chk_rm_nr 1 1
2570	fi
2571}
2572
2573v4mapped_tests()
2574{
2575	# subflow IPv4-mapped to IPv4-mapped
2576	if reset "single subflow IPv4-mapped"; then
2577		pm_nl_set_limits $ns1 0 1
2578		pm_nl_set_limits $ns2 0 1
2579		pm_nl_add_endpoint $ns2 "::ffff:10.0.3.2" flags subflow
2580		run_tests $ns1 $ns2 "::ffff:10.0.1.1"
2581		chk_join_nr 1 1 1
2582	fi
2583
2584	# signal address IPv4-mapped with IPv4-mapped sk
2585	if reset "signal address IPv4-mapped"; then
2586		pm_nl_set_limits $ns1 0 1
2587		pm_nl_set_limits $ns2 1 1
2588		pm_nl_add_endpoint $ns1 "::ffff:10.0.2.1" flags signal
2589		run_tests $ns1 $ns2 "::ffff:10.0.1.1"
2590		chk_join_nr 1 1 1
2591		chk_add_nr 1 1
2592	fi
2593
2594	# subflow v4-map-v6
2595	if reset "single subflow v4-map-v6"; then
2596		pm_nl_set_limits $ns1 0 1
2597		pm_nl_set_limits $ns2 0 1
2598		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
2599		run_tests $ns1 $ns2 "::ffff:10.0.1.1"
2600		chk_join_nr 1 1 1
2601	fi
2602
2603	# signal address v4-map-v6
2604	if reset "signal address v4-map-v6"; then
2605		pm_nl_set_limits $ns1 0 1
2606		pm_nl_set_limits $ns2 1 1
2607		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
2608		run_tests $ns1 $ns2 "::ffff:10.0.1.1"
2609		chk_join_nr 1 1 1
2610		chk_add_nr 1 1
2611	fi
2612
2613	# subflow v6-map-v4
2614	if reset "single subflow v6-map-v4"; then
2615		pm_nl_set_limits $ns1 0 1
2616		pm_nl_set_limits $ns2 0 1
2617		pm_nl_add_endpoint $ns2 "::ffff:10.0.3.2" flags subflow
2618		run_tests $ns1 $ns2 10.0.1.1
2619		chk_join_nr 1 1 1
2620	fi
2621
2622	# signal address v6-map-v4
2623	if reset "signal address v6-map-v4"; then
2624		pm_nl_set_limits $ns1 0 1
2625		pm_nl_set_limits $ns2 1 1
2626		pm_nl_add_endpoint $ns1 "::ffff:10.0.2.1" flags signal
2627		run_tests $ns1 $ns2 10.0.1.1
2628		chk_join_nr 1 1 1
2629		chk_add_nr 1 1
2630	fi
2631
2632	# no subflow IPv6 to v4 address
2633	if reset "no JOIN with diff families v4-v6"; then
2634		pm_nl_set_limits $ns1 0 1
2635		pm_nl_set_limits $ns2 0 1
2636		pm_nl_add_endpoint $ns2 dead:beef:2::2 flags subflow
2637		run_tests $ns1 $ns2 10.0.1.1
2638		chk_join_nr 0 0 0
2639	fi
2640
2641	# no subflow IPv6 to v4 address even if v6 has a valid v4 at the end
2642	if reset "no JOIN with diff families v4-v6-2"; then
2643		pm_nl_set_limits $ns1 0 1
2644		pm_nl_set_limits $ns2 0 1
2645		pm_nl_add_endpoint $ns2 dead:beef:2::10.0.3.2 flags subflow
2646		run_tests $ns1 $ns2 10.0.1.1
2647		chk_join_nr 0 0 0
2648	fi
2649
2650	# no subflow IPv4 to v6 address, no need to slow down too then
2651	if reset "no JOIN with diff families v6-v4"; then
2652		pm_nl_set_limits $ns1 0 1
2653		pm_nl_set_limits $ns2 0 1
2654		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
2655		run_tests $ns1 $ns2 dead:beef:1::1
2656		chk_join_nr 0 0 0
2657	fi
2658}
2659
2660mixed_tests()
2661{
2662	if reset "IPv4 sockets do not use IPv6 addresses" &&
2663	   continue_if mptcp_lib_kversion_ge 6.3; then
2664		pm_nl_set_limits $ns1 0 1
2665		pm_nl_set_limits $ns2 1 1
2666		pm_nl_add_endpoint $ns1 dead:beef:2::1 flags signal
2667		speed=slow \
2668			run_tests $ns1 $ns2 10.0.1.1
2669		chk_join_nr 0 0 0
2670	fi
2671
2672	# Need an IPv6 mptcp socket to allow subflows of both families
2673	if reset "simult IPv4 and IPv6 subflows" &&
2674	   continue_if mptcp_lib_kversion_ge 6.3; then
2675		pm_nl_set_limits $ns1 0 1
2676		pm_nl_set_limits $ns2 1 1
2677		pm_nl_add_endpoint $ns1 10.0.1.1 flags signal
2678		speed=slow \
2679			run_tests $ns1 $ns2 dead:beef:2::1
2680		chk_join_nr 1 1 1
2681	fi
2682
2683	# cross families subflows will not be created even in fullmesh mode
2684	if reset "simult IPv4 and IPv6 subflows, fullmesh 1x1" &&
2685	   continue_if mptcp_lib_kversion_ge 6.3; then
2686		pm_nl_set_limits $ns1 0 4
2687		pm_nl_set_limits $ns2 1 4
2688		pm_nl_add_endpoint $ns2 dead:beef:2::2 flags subflow,fullmesh
2689		pm_nl_add_endpoint $ns1 10.0.1.1 flags signal
2690		speed=slow \
2691			run_tests $ns1 $ns2 dead:beef:2::1
2692		chk_join_nr 1 1 1
2693	fi
2694
2695	# fullmesh still tries to create all the possibly subflows with
2696	# matching family
2697	if reset "simult IPv4 and IPv6 subflows, fullmesh 2x2" &&
2698	   continue_if mptcp_lib_kversion_ge 6.3; then
2699		pm_nl_set_limits $ns1 0 4
2700		pm_nl_set_limits $ns2 2 4
2701		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
2702		pm_nl_add_endpoint $ns1 dead:beef:2::1 flags signal
2703		fullmesh=1 speed=slow \
2704			run_tests $ns1 $ns2 dead:beef:1::1
2705		chk_join_nr 4 4 4
2706	fi
2707}
2708
2709backup_tests()
2710{
2711	# single subflow, backup
2712	if reset "single subflow, backup" &&
2713	   continue_if mptcp_lib_kallsyms_has "subflow_rebuild_header$"; then
2714		pm_nl_set_limits $ns1 0 1
2715		pm_nl_set_limits $ns2 0 1
2716		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow,backup
2717		sflags=nobackup speed=slow \
2718			run_tests $ns1 $ns2 10.0.1.1
2719		chk_join_nr 1 1 1
2720		chk_prio_nr 0 1
2721	fi
2722
2723	# single address, backup
2724	if reset "single address, backup" &&
2725	   continue_if mptcp_lib_kallsyms_has "subflow_rebuild_header$"; then
2726		pm_nl_set_limits $ns1 0 1
2727		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
2728		pm_nl_set_limits $ns2 1 1
2729		sflags=backup speed=slow \
2730			run_tests $ns1 $ns2 10.0.1.1
2731		chk_join_nr 1 1 1
2732		chk_add_nr 1 1
2733		chk_prio_nr 1 1
2734	fi
2735
2736	# single address with port, backup
2737	if reset "single address with port, backup" &&
2738	   continue_if mptcp_lib_kallsyms_has "subflow_rebuild_header$"; then
2739		pm_nl_set_limits $ns1 0 1
2740		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal port 10100
2741		pm_nl_set_limits $ns2 1 1
2742		sflags=backup speed=slow \
2743			run_tests $ns1 $ns2 10.0.1.1
2744		chk_join_nr 1 1 1
2745		chk_add_nr 1 1
2746		chk_prio_nr 1 1
2747	fi
2748
2749	if reset "mpc backup" &&
2750	   continue_if mptcp_lib_kallsyms_doesnt_have "T mptcp_subflow_send_ack$"; then
2751		pm_nl_add_endpoint $ns2 10.0.1.2 flags subflow,backup
2752		speed=slow \
2753			run_tests $ns1 $ns2 10.0.1.1
2754		chk_join_nr 0 0 0
2755		chk_prio_nr 0 1
2756	fi
2757
2758	if reset "mpc backup both sides" &&
2759	   continue_if mptcp_lib_kallsyms_doesnt_have "T mptcp_subflow_send_ack$"; then
2760		pm_nl_add_endpoint $ns1 10.0.1.1 flags subflow,backup
2761		pm_nl_add_endpoint $ns2 10.0.1.2 flags subflow,backup
2762		speed=slow \
2763			run_tests $ns1 $ns2 10.0.1.1
2764		chk_join_nr 0 0 0
2765		chk_prio_nr 1 1
2766	fi
2767
2768	if reset "mpc switch to backup" &&
2769	   continue_if mptcp_lib_kallsyms_doesnt_have "T mptcp_subflow_send_ack$"; then
2770		pm_nl_add_endpoint $ns2 10.0.1.2 flags subflow
2771		sflags=backup speed=slow \
2772			run_tests $ns1 $ns2 10.0.1.1
2773		chk_join_nr 0 0 0
2774		chk_prio_nr 0 1
2775	fi
2776
2777	if reset "mpc switch to backup both sides" &&
2778	   continue_if mptcp_lib_kallsyms_doesnt_have "T mptcp_subflow_send_ack$"; then
2779		pm_nl_add_endpoint $ns1 10.0.1.1 flags subflow
2780		pm_nl_add_endpoint $ns2 10.0.1.2 flags subflow
2781		sflags=backup speed=slow \
2782			run_tests $ns1 $ns2 10.0.1.1
2783		chk_join_nr 0 0 0
2784		chk_prio_nr 1 1
2785	fi
2786}
2787
2788SUB_ESTABLISHED=10 # MPTCP_EVENT_SUB_ESTABLISHED
2789LISTENER_CREATED=15 #MPTCP_EVENT_LISTENER_CREATED
2790LISTENER_CLOSED=16  #MPTCP_EVENT_LISTENER_CLOSED
2791
2792AF_INET=2
2793AF_INET6=10
2794
2795verify_listener_events()
2796{
2797	local e_type=$2
2798	local e_saddr=$4
2799	local e_sport=$5
2800	local name
2801
2802	if [ $e_type = $LISTENER_CREATED ]; then
2803		name="LISTENER_CREATED"
2804	elif [ $e_type = $LISTENER_CLOSED ]; then
2805		name="LISTENER_CLOSED "
2806	else
2807		name="$e_type"
2808	fi
2809
2810	print_check "$name $e_saddr:$e_sport"
2811
2812	if ! mptcp_lib_kallsyms_has "mptcp_event_pm_listener$"; then
2813		print_skip "event not supported"
2814		return
2815	fi
2816
2817	if mptcp_lib_verify_listener_events "${@}"; then
2818		print_ok
2819		return 0
2820	fi
2821	fail_test
2822}
2823
2824add_addr_ports_tests()
2825{
2826	# signal address with port
2827	if reset "signal address with port"; then
2828		pm_nl_set_limits $ns1 0 1
2829		pm_nl_set_limits $ns2 1 1
2830		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal port 10100
2831		run_tests $ns1 $ns2 10.0.1.1
2832		chk_join_nr 1 1 1
2833		chk_add_nr 1 1 1
2834	fi
2835
2836	# subflow and signal with port
2837	if reset "subflow and signal with port"; then
2838		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal port 10100
2839		pm_nl_set_limits $ns1 0 2
2840		pm_nl_set_limits $ns2 1 2
2841		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
2842		run_tests $ns1 $ns2 10.0.1.1
2843		chk_join_nr 2 2 2
2844		chk_add_nr 1 1 1
2845	fi
2846
2847	# single address with port, remove
2848	# pm listener events
2849	if reset_with_events "remove single address with port"; then
2850		pm_nl_set_limits $ns1 0 1
2851		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal port 10100
2852		pm_nl_set_limits $ns2 1 1
2853		addr_nr_ns1=-1 speed=slow \
2854			run_tests $ns1 $ns2 10.0.1.1
2855		chk_join_nr 1 1 1
2856		chk_add_nr 1 1 1
2857		chk_rm_nr 1 1 invert
2858
2859		verify_listener_events $evts_ns1 $LISTENER_CREATED $AF_INET 10.0.2.1 10100
2860		verify_listener_events $evts_ns1 $LISTENER_CLOSED $AF_INET 10.0.2.1 10100
2861		kill_events_pids
2862	fi
2863
2864	# subflow and signal with port, remove
2865	if reset "remove subflow and signal with port"; then
2866		pm_nl_set_limits $ns1 0 2
2867		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal port 10100
2868		pm_nl_set_limits $ns2 1 2
2869		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
2870		addr_nr_ns1=-1 addr_nr_ns2=-1 speed=slow \
2871			run_tests $ns1 $ns2 10.0.1.1
2872		chk_join_nr 2 2 2
2873		chk_add_nr 1 1 1
2874		chk_rm_nr 1 1
2875	fi
2876
2877	# subflows and signal with port, flush
2878	if reset "flush subflows and signal with port"; then
2879		pm_nl_set_limits $ns1 0 3
2880		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal port 10100
2881		pm_nl_set_limits $ns2 1 3
2882		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
2883		pm_nl_add_endpoint $ns2 10.0.4.2 flags subflow
2884		addr_nr_ns1=-8 addr_nr_ns2=-2 speed=slow \
2885			run_tests $ns1 $ns2 10.0.1.1
2886		chk_join_nr 3 3 3
2887		chk_add_nr 1 1
2888		chk_rm_nr 1 3 invert simult
2889	fi
2890
2891	# multiple addresses with port
2892	if reset "multiple addresses with port"; then
2893		pm_nl_set_limits $ns1 2 2
2894		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal port 10100
2895		pm_nl_add_endpoint $ns1 10.0.3.1 flags signal port 10100
2896		pm_nl_set_limits $ns2 2 2
2897		run_tests $ns1 $ns2 10.0.1.1
2898		chk_join_nr 2 2 2
2899		chk_add_nr 2 2 2
2900	fi
2901
2902	# multiple addresses with ports
2903	if reset "multiple addresses with ports"; then
2904		pm_nl_set_limits $ns1 2 2
2905		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal port 10100
2906		pm_nl_add_endpoint $ns1 10.0.3.1 flags signal port 10101
2907		pm_nl_set_limits $ns2 2 2
2908		run_tests $ns1 $ns2 10.0.1.1
2909		chk_join_nr 2 2 2
2910		chk_add_nr 2 2 2
2911	fi
2912}
2913
2914syncookies_tests()
2915{
2916	# single subflow, syncookies
2917	if reset_with_cookies "single subflow with syn cookies"; then
2918		pm_nl_set_limits $ns1 0 1
2919		pm_nl_set_limits $ns2 0 1
2920		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
2921		run_tests $ns1 $ns2 10.0.1.1
2922		chk_join_nr 1 1 1
2923	fi
2924
2925	# multiple subflows with syn cookies
2926	if reset_with_cookies "multiple subflows with syn cookies"; then
2927		pm_nl_set_limits $ns1 0 2
2928		pm_nl_set_limits $ns2 0 2
2929		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
2930		pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow
2931		run_tests $ns1 $ns2 10.0.1.1
2932		chk_join_nr 2 2 2
2933	fi
2934
2935	# multiple subflows limited by server
2936	if reset_with_cookies "subflows limited by server w cookies"; then
2937		pm_nl_set_limits $ns1 0 1
2938		pm_nl_set_limits $ns2 0 2
2939		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
2940		pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow
2941		run_tests $ns1 $ns2 10.0.1.1
2942		chk_join_nr 2 1 1
2943	fi
2944
2945	# test signal address with cookies
2946	if reset_with_cookies "signal address with syn cookies"; then
2947		pm_nl_set_limits $ns1 0 1
2948		pm_nl_set_limits $ns2 1 1
2949		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
2950		run_tests $ns1 $ns2 10.0.1.1
2951		chk_join_nr 1 1 1
2952		chk_add_nr 1 1
2953	fi
2954
2955	# test cookie with subflow and signal
2956	if reset_with_cookies "subflow and signal w cookies"; then
2957		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
2958		pm_nl_set_limits $ns1 0 2
2959		pm_nl_set_limits $ns2 1 2
2960		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
2961		run_tests $ns1 $ns2 10.0.1.1
2962		chk_join_nr 2 2 2
2963		chk_add_nr 1 1
2964	fi
2965
2966	# accept and use add_addr with additional subflows
2967	if reset_with_cookies "subflows and signal w. cookies"; then
2968		pm_nl_set_limits $ns1 0 3
2969		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
2970		pm_nl_set_limits $ns2 1 3
2971		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
2972		pm_nl_add_endpoint $ns2 10.0.4.2 flags subflow
2973		run_tests $ns1 $ns2 10.0.1.1
2974		chk_join_nr 3 3 3
2975		chk_add_nr 1 1
2976	fi
2977}
2978
2979checksum_tests()
2980{
2981	# checksum test 0 0
2982	if reset_with_checksum 0 0; then
2983		pm_nl_set_limits $ns1 0 1
2984		pm_nl_set_limits $ns2 0 1
2985		run_tests $ns1 $ns2 10.0.1.1
2986		chk_join_nr 0 0 0
2987	fi
2988
2989	# checksum test 1 1
2990	if reset_with_checksum 1 1; then
2991		pm_nl_set_limits $ns1 0 1
2992		pm_nl_set_limits $ns2 0 1
2993		run_tests $ns1 $ns2 10.0.1.1
2994		chk_join_nr 0 0 0
2995	fi
2996
2997	# checksum test 0 1
2998	if reset_with_checksum 0 1; then
2999		pm_nl_set_limits $ns1 0 1
3000		pm_nl_set_limits $ns2 0 1
3001		run_tests $ns1 $ns2 10.0.1.1
3002		chk_join_nr 0 0 0
3003	fi
3004
3005	# checksum test 1 0
3006	if reset_with_checksum 1 0; then
3007		pm_nl_set_limits $ns1 0 1
3008		pm_nl_set_limits $ns2 0 1
3009		run_tests $ns1 $ns2 10.0.1.1
3010		chk_join_nr 0 0 0
3011	fi
3012}
3013
3014deny_join_id0_tests()
3015{
3016	# subflow allow join id0 ns1
3017	if reset_with_allow_join_id0 "single subflow allow join id0 ns1" 1 0; then
3018		pm_nl_set_limits $ns1 1 1
3019		pm_nl_set_limits $ns2 1 1
3020		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
3021		run_tests $ns1 $ns2 10.0.1.1
3022		chk_join_nr 1 1 1
3023	fi
3024
3025	# subflow allow join id0 ns2
3026	if reset_with_allow_join_id0 "single subflow allow join id0 ns2" 0 1; then
3027		pm_nl_set_limits $ns1 1 1
3028		pm_nl_set_limits $ns2 1 1
3029		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
3030		run_tests $ns1 $ns2 10.0.1.1
3031		chk_join_nr 0 0 0
3032	fi
3033
3034	# signal address allow join id0 ns1
3035	# ADD_ADDRs are not affected by allow_join_id0 value.
3036	if reset_with_allow_join_id0 "signal address allow join id0 ns1" 1 0; then
3037		pm_nl_set_limits $ns1 1 1
3038		pm_nl_set_limits $ns2 1 1
3039		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
3040		run_tests $ns1 $ns2 10.0.1.1
3041		chk_join_nr 1 1 1
3042		chk_add_nr 1 1
3043	fi
3044
3045	# signal address allow join id0 ns2
3046	# ADD_ADDRs are not affected by allow_join_id0 value.
3047	if reset_with_allow_join_id0 "signal address allow join id0 ns2" 0 1; then
3048		pm_nl_set_limits $ns1 1 1
3049		pm_nl_set_limits $ns2 1 1
3050		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
3051		run_tests $ns1 $ns2 10.0.1.1
3052		chk_join_nr 1 1 1
3053		chk_add_nr 1 1
3054	fi
3055
3056	# subflow and address allow join id0 ns1
3057	if reset_with_allow_join_id0 "subflow and address allow join id0 1" 1 0; then
3058		pm_nl_set_limits $ns1 2 2
3059		pm_nl_set_limits $ns2 2 2
3060		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
3061		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
3062		run_tests $ns1 $ns2 10.0.1.1
3063		chk_join_nr 2 2 2
3064	fi
3065
3066	# subflow and address allow join id0 ns2
3067	if reset_with_allow_join_id0 "subflow and address allow join id0 2" 0 1; then
3068		pm_nl_set_limits $ns1 2 2
3069		pm_nl_set_limits $ns2 2 2
3070		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
3071		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
3072		run_tests $ns1 $ns2 10.0.1.1
3073		chk_join_nr 1 1 1
3074	fi
3075}
3076
3077fullmesh_tests()
3078{
3079	# fullmesh 1
3080	# 2 fullmesh addrs in ns2, added before the connection,
3081	# 1 non-fullmesh addr in ns1, added during the connection.
3082	if reset "fullmesh test 2x1"; then
3083		pm_nl_set_limits $ns1 0 4
3084		pm_nl_set_limits $ns2 1 4
3085		pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow,fullmesh
3086		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow,fullmesh
3087		addr_nr_ns1=1 speed=slow \
3088			run_tests $ns1 $ns2 10.0.1.1
3089		chk_join_nr 4 4 4
3090		chk_add_nr 1 1
3091	fi
3092
3093	# fullmesh 2
3094	# 1 non-fullmesh addr in ns1, added before the connection,
3095	# 1 fullmesh addr in ns2, added during the connection.
3096	if reset "fullmesh test 1x1"; then
3097		pm_nl_set_limits $ns1 1 3
3098		pm_nl_set_limits $ns2 1 3
3099		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
3100		fullmesh=1 speed=slow \
3101			run_tests $ns1 $ns2 10.0.1.1
3102		chk_join_nr 3 3 3
3103		chk_add_nr 1 1
3104	fi
3105
3106	# fullmesh 3
3107	# 1 non-fullmesh addr in ns1, added before the connection,
3108	# 2 fullmesh addrs in ns2, added during the connection.
3109	if reset "fullmesh test 1x2"; then
3110		pm_nl_set_limits $ns1 2 5
3111		pm_nl_set_limits $ns2 1 5
3112		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
3113		fullmesh=2 speed=slow \
3114			run_tests $ns1 $ns2 10.0.1.1
3115		chk_join_nr 5 5 5
3116		chk_add_nr 1 1
3117	fi
3118
3119	# fullmesh 4
3120	# 1 non-fullmesh addr in ns1, added before the connection,
3121	# 2 fullmesh addrs in ns2, added during the connection,
3122	# limit max_subflows to 4.
3123	if reset "fullmesh test 1x2, limited"; then
3124		pm_nl_set_limits $ns1 2 4
3125		pm_nl_set_limits $ns2 1 4
3126		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
3127		fullmesh=2 speed=slow \
3128			run_tests $ns1 $ns2 10.0.1.1
3129		chk_join_nr 4 4 4
3130		chk_add_nr 1 1
3131	fi
3132
3133	# set fullmesh flag
3134	if reset "set fullmesh flag test" &&
3135	   continue_if mptcp_lib_kversion_ge 5.18; then
3136		pm_nl_set_limits $ns1 4 4
3137		pm_nl_add_endpoint $ns1 10.0.2.1 flags subflow
3138		pm_nl_set_limits $ns2 4 4
3139		addr_nr_ns2=1 sflags=fullmesh speed=slow \
3140			run_tests $ns1 $ns2 10.0.1.1
3141		chk_join_nr 2 2 2
3142		chk_rm_nr 0 1
3143	fi
3144
3145	# set nofullmesh flag
3146	if reset "set nofullmesh flag test" &&
3147	   continue_if mptcp_lib_kversion_ge 5.18; then
3148		pm_nl_set_limits $ns1 4 4
3149		pm_nl_add_endpoint $ns1 10.0.2.1 flags subflow,fullmesh
3150		pm_nl_set_limits $ns2 4 4
3151		fullmesh=1 sflags=nofullmesh speed=slow \
3152			run_tests $ns1 $ns2 10.0.1.1
3153		chk_join_nr 2 2 2
3154		chk_rm_nr 0 1
3155	fi
3156
3157	# set backup,fullmesh flags
3158	if reset "set backup,fullmesh flags test" &&
3159	   continue_if mptcp_lib_kversion_ge 5.18; then
3160		pm_nl_set_limits $ns1 4 4
3161		pm_nl_add_endpoint $ns1 10.0.2.1 flags subflow
3162		pm_nl_set_limits $ns2 4 4
3163		addr_nr_ns2=1 sflags=backup,fullmesh speed=slow \
3164			run_tests $ns1 $ns2 10.0.1.1
3165		chk_join_nr 2 2 2
3166		chk_prio_nr 0 1
3167		chk_rm_nr 0 1
3168	fi
3169
3170	# set nobackup,nofullmesh flags
3171	if reset "set nobackup,nofullmesh flags test" &&
3172	   continue_if mptcp_lib_kversion_ge 5.18; then
3173		pm_nl_set_limits $ns1 4 4
3174		pm_nl_set_limits $ns2 4 4
3175		pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow,backup,fullmesh
3176		sflags=nobackup,nofullmesh speed=slow \
3177			run_tests $ns1 $ns2 10.0.1.1
3178		chk_join_nr 2 2 2
3179		chk_prio_nr 0 1
3180		chk_rm_nr 0 1
3181	fi
3182}
3183
3184fastclose_tests()
3185{
3186	if reset_check_counter "fastclose test" "MPTcpExtMPFastcloseTx"; then
3187		test_linkfail=1024 fastclose=client \
3188			run_tests $ns1 $ns2 10.0.1.1
3189		chk_join_nr 0 0 0
3190		chk_fclose_nr 1 1
3191		chk_rst_nr 1 1 invert
3192	fi
3193
3194	if reset_check_counter "fastclose server test" "MPTcpExtMPFastcloseRx"; then
3195		test_linkfail=1024 fastclose=server \
3196			run_tests $ns1 $ns2 10.0.1.1
3197		chk_join_nr 0 0 0 0 0 0 1
3198		chk_fclose_nr 1 1 invert
3199		chk_rst_nr 1 1
3200	fi
3201}
3202
3203pedit_action_pkts()
3204{
3205	tc -n $ns2 -j -s action show action pedit index 100 | \
3206		mptcp_lib_get_info_value \"packets\" packets
3207}
3208
3209fail_tests()
3210{
3211	# single subflow
3212	if reset_with_fail "Infinite map" 1; then
3213		test_linkfail=128 \
3214			run_tests $ns1 $ns2 10.0.1.1
3215		chk_join_nr 0 0 0 +1 +0 1 0 1 "$(pedit_action_pkts)"
3216		chk_fail_nr 1 -1 invert
3217	fi
3218
3219	# multiple subflows
3220	if reset_with_fail "MP_FAIL MP_RST" 2; then
3221		tc -n $ns2 qdisc add dev ns2eth1 root netem rate 1mbit delay 5
3222		pm_nl_set_limits $ns1 0 1
3223		pm_nl_set_limits $ns2 0 1
3224		pm_nl_add_endpoint $ns2 10.0.2.2 dev ns2eth2 flags subflow
3225		test_linkfail=1024 \
3226			run_tests $ns1 $ns2 10.0.1.1
3227		chk_join_nr 1 1 1 1 0 1 1 0 "$(pedit_action_pkts)"
3228	fi
3229}
3230
3231# $1: ns ; $2: addr ; $3: id
3232userspace_pm_add_addr()
3233{
3234	local evts=$evts_ns1
3235	local tk
3236
3237	[ "$1" == "$ns2" ] && evts=$evts_ns2
3238	tk=$(mptcp_lib_evts_get_info token "$evts")
3239
3240	ip netns exec $1 ./pm_nl_ctl ann $2 token $tk id $3
3241	sleep 1
3242}
3243
3244# $1: ns ; $2: id
3245userspace_pm_rm_addr()
3246{
3247	local evts=$evts_ns1
3248	local tk
3249	local cnt
3250
3251	[ "$1" == "$ns2" ] && evts=$evts_ns2
3252	tk=$(mptcp_lib_evts_get_info token "$evts")
3253
3254	cnt=$(rm_addr_count ${1})
3255	ip netns exec $1 ./pm_nl_ctl rem token $tk id $2
3256	wait_rm_addr $1 "${cnt}"
3257}
3258
3259# $1: ns ; $2: addr ; $3: id
3260userspace_pm_add_sf()
3261{
3262	local evts=$evts_ns1
3263	local tk da dp
3264
3265	[ "$1" == "$ns2" ] && evts=$evts_ns2
3266	tk=$(mptcp_lib_evts_get_info token "$evts")
3267	da=$(mptcp_lib_evts_get_info daddr4 "$evts")
3268	dp=$(mptcp_lib_evts_get_info dport "$evts")
3269
3270	ip netns exec $1 ./pm_nl_ctl csf lip $2 lid $3 \
3271				rip $da rport $dp token $tk
3272	sleep 1
3273}
3274
3275# $1: ns ; $2: addr $3: event type
3276userspace_pm_rm_sf()
3277{
3278	local evts=$evts_ns1
3279	local t=${3:-1}
3280	local ip
3281	local tk da dp sp
3282	local cnt
3283
3284	[ "$1" == "$ns2" ] && evts=$evts_ns2
3285	[ -n "$(mptcp_lib_evts_get_info "saddr4" "$evts" $t)" ] && ip=4
3286	[ -n "$(mptcp_lib_evts_get_info "saddr6" "$evts" $t)" ] && ip=6
3287	tk=$(mptcp_lib_evts_get_info token "$evts")
3288	da=$(mptcp_lib_evts_get_info "daddr$ip" "$evts" $t $2)
3289	dp=$(mptcp_lib_evts_get_info dport "$evts" $t $2)
3290	sp=$(mptcp_lib_evts_get_info sport "$evts" $t $2)
3291
3292	cnt=$(rm_sf_count ${1})
3293	ip netns exec $1 ./pm_nl_ctl dsf lip $2 lport $sp \
3294				rip $da rport $dp token $tk
3295	wait_rm_sf $1 "${cnt}"
3296}
3297
3298check_output()
3299{
3300	local cmd="$1"
3301	local expected="$2"
3302	local msg="$3"
3303	local rc=0
3304
3305	mptcp_lib_check_output "${err}" "${cmd}" "${expected}" || rc=${?}
3306	if [ ${rc} -eq 2 ]; then
3307		fail_test "fail to check output # error ${rc}"
3308	elif [ ${rc} -eq 0 ]; then
3309		print_ok
3310	elif [ ${rc} -eq 1 ]; then
3311		fail_test "fail to check output # different output"
3312	fi
3313}
3314
3315# $1: ns
3316userspace_pm_dump()
3317{
3318	local evts=$evts_ns1
3319	local tk
3320
3321	[ "$1" == "$ns2" ] && evts=$evts_ns2
3322	tk=$(mptcp_lib_evts_get_info token "$evts")
3323
3324	ip netns exec $1 ./pm_nl_ctl dump token $tk
3325}
3326
3327# $1: ns ; $2: id
3328userspace_pm_get_addr()
3329{
3330	local evts=$evts_ns1
3331	local tk
3332
3333	[ "$1" == "$ns2" ] && evts=$evts_ns2
3334	tk=$(mptcp_lib_evts_get_info token "$evts")
3335
3336	ip netns exec $1 ./pm_nl_ctl get $2 token $tk
3337}
3338
3339userspace_pm_chk_dump_addr()
3340{
3341	local ns="${1}"
3342	local exp="${2}"
3343	local check="${3}"
3344
3345	print_check "dump addrs ${check}"
3346
3347	if mptcp_lib_kallsyms_has "mptcp_userspace_pm_dump_addr$"; then
3348		check_output "userspace_pm_dump ${ns}" "${exp}"
3349	else
3350		print_skip
3351	fi
3352}
3353
3354userspace_pm_chk_get_addr()
3355{
3356	local ns="${1}"
3357	local id="${2}"
3358	local exp="${3}"
3359
3360	print_check "get id ${id} addr"
3361
3362	if mptcp_lib_kallsyms_has "mptcp_userspace_pm_get_addr$"; then
3363		check_output "userspace_pm_get_addr ${ns} ${id}" "${exp}"
3364	else
3365		print_skip
3366	fi
3367}
3368
3369userspace_tests()
3370{
3371	# userspace pm type prevents add_addr
3372	if reset "userspace pm type prevents add_addr" &&
3373	   continue_if mptcp_lib_has_file '/proc/sys/net/mptcp/pm_type'; then
3374		set_userspace_pm $ns1
3375		pm_nl_set_limits $ns1 0 2
3376		pm_nl_set_limits $ns2 0 2
3377		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
3378		run_tests $ns1 $ns2 10.0.1.1
3379		chk_join_nr 0 0 0
3380		chk_add_nr 0 0
3381	fi
3382
3383	# userspace pm type does not echo add_addr without daemon
3384	if reset "userspace pm no echo w/o daemon" &&
3385	   continue_if mptcp_lib_has_file '/proc/sys/net/mptcp/pm_type'; then
3386		set_userspace_pm $ns2
3387		pm_nl_set_limits $ns1 0 2
3388		pm_nl_set_limits $ns2 0 2
3389		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
3390		run_tests $ns1 $ns2 10.0.1.1
3391		chk_join_nr 0 0 0
3392		chk_add_nr 1 0
3393	fi
3394
3395	# userspace pm type rejects join
3396	if reset "userspace pm type rejects join" &&
3397	   continue_if mptcp_lib_has_file '/proc/sys/net/mptcp/pm_type'; then
3398		set_userspace_pm $ns1
3399		pm_nl_set_limits $ns1 1 1
3400		pm_nl_set_limits $ns2 1 1
3401		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
3402		run_tests $ns1 $ns2 10.0.1.1
3403		chk_join_nr 1 1 0
3404	fi
3405
3406	# userspace pm type does not send join
3407	if reset "userspace pm type does not send join" &&
3408	   continue_if mptcp_lib_has_file '/proc/sys/net/mptcp/pm_type'; then
3409		set_userspace_pm $ns2
3410		pm_nl_set_limits $ns1 1 1
3411		pm_nl_set_limits $ns2 1 1
3412		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
3413		run_tests $ns1 $ns2 10.0.1.1
3414		chk_join_nr 0 0 0
3415	fi
3416
3417	# userspace pm type prevents mp_prio
3418	if reset "userspace pm type prevents mp_prio" &&
3419	   continue_if mptcp_lib_has_file '/proc/sys/net/mptcp/pm_type'; then
3420		set_userspace_pm $ns1
3421		pm_nl_set_limits $ns1 1 1
3422		pm_nl_set_limits $ns2 1 1
3423		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
3424		sflags=backup speed=slow \
3425			run_tests $ns1 $ns2 10.0.1.1
3426		chk_join_nr 1 1 0
3427		chk_prio_nr 0 0
3428	fi
3429
3430	# userspace pm type prevents rm_addr
3431	if reset "userspace pm type prevents rm_addr" &&
3432	   continue_if mptcp_lib_has_file '/proc/sys/net/mptcp/pm_type'; then
3433		set_userspace_pm $ns1
3434		set_userspace_pm $ns2
3435		pm_nl_set_limits $ns1 0 1
3436		pm_nl_set_limits $ns2 0 1
3437		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
3438		addr_nr_ns2=-1 speed=slow \
3439			run_tests $ns1 $ns2 10.0.1.1
3440		chk_join_nr 0 0 0
3441		chk_rm_nr 0 0
3442	fi
3443
3444	# userspace pm add & remove address
3445	if reset_with_events "userspace pm add & remove address" &&
3446	   continue_if mptcp_lib_has_file '/proc/sys/net/mptcp/pm_type'; then
3447		set_userspace_pm $ns1
3448		pm_nl_set_limits $ns2 2 2
3449		speed=5 \
3450			run_tests $ns1 $ns2 10.0.1.1 &
3451		local tests_pid=$!
3452		wait_mpj $ns1
3453		userspace_pm_add_addr $ns1 10.0.2.1 10
3454		userspace_pm_add_addr $ns1 10.0.3.1 20
3455		chk_join_nr 2 2 2
3456		chk_add_nr 2 2
3457		chk_mptcp_info subflows 2 subflows 2
3458		chk_subflows_total 3 3
3459		chk_mptcp_info add_addr_signal 2 add_addr_accepted 2
3460		userspace_pm_chk_dump_addr "${ns1}" \
3461			$'id 10 flags signal 10.0.2.1\nid 20 flags signal 10.0.3.1' \
3462			"signal"
3463		userspace_pm_chk_get_addr "${ns1}" "10" "id 10 flags signal 10.0.2.1"
3464		userspace_pm_chk_get_addr "${ns1}" "20" "id 20 flags signal 10.0.3.1"
3465		userspace_pm_rm_addr $ns1 10
3466		userspace_pm_rm_sf $ns1 "::ffff:10.0.2.1" $SUB_ESTABLISHED
3467		userspace_pm_chk_dump_addr "${ns1}" \
3468			"id 20 flags signal 10.0.3.1" "after rm_addr 10"
3469		userspace_pm_rm_addr $ns1 20
3470		userspace_pm_rm_sf $ns1 10.0.3.1 $SUB_ESTABLISHED
3471		userspace_pm_chk_dump_addr "${ns1}" "" "after rm_addr 20"
3472		chk_rm_nr 2 2 invert
3473		chk_mptcp_info subflows 0 subflows 0
3474		chk_subflows_total 1 1
3475		kill_events_pids
3476		mptcp_lib_kill_wait $tests_pid
3477	fi
3478
3479	# userspace pm create destroy subflow
3480	if reset_with_events "userspace pm create destroy subflow" &&
3481	   continue_if mptcp_lib_has_file '/proc/sys/net/mptcp/pm_type'; then
3482		set_userspace_pm $ns2
3483		pm_nl_set_limits $ns1 0 1
3484		speed=5 \
3485			run_tests $ns1 $ns2 10.0.1.1 &
3486		local tests_pid=$!
3487		wait_mpj $ns2
3488		userspace_pm_add_sf $ns2 10.0.3.2 20
3489		chk_join_nr 1 1 1
3490		chk_mptcp_info subflows 1 subflows 1
3491		chk_subflows_total 2 2
3492		userspace_pm_chk_dump_addr "${ns2}" \
3493			"id 20 flags subflow 10.0.3.2" \
3494			"subflow"
3495		userspace_pm_chk_get_addr "${ns2}" "20" "id 20 flags subflow 10.0.3.2"
3496		userspace_pm_rm_addr $ns2 20
3497		userspace_pm_rm_sf $ns2 10.0.3.2 $SUB_ESTABLISHED
3498		userspace_pm_chk_dump_addr "${ns2}" \
3499			"" \
3500			"after rm_addr 20"
3501		chk_rm_nr 1 1
3502		chk_mptcp_info subflows 0 subflows 0
3503		chk_subflows_total 1 1
3504		kill_events_pids
3505		mptcp_lib_kill_wait $tests_pid
3506	fi
3507
3508	# userspace pm create id 0 subflow
3509	if reset_with_events "userspace pm create id 0 subflow" &&
3510	   continue_if mptcp_lib_has_file '/proc/sys/net/mptcp/pm_type'; then
3511		set_userspace_pm $ns2
3512		pm_nl_set_limits $ns1 0 1
3513		speed=5 \
3514			run_tests $ns1 $ns2 10.0.1.1 &
3515		local tests_pid=$!
3516		wait_mpj $ns2
3517		chk_mptcp_info subflows 0 subflows 0
3518		chk_subflows_total 1 1
3519		userspace_pm_add_sf $ns2 10.0.3.2 0
3520		userspace_pm_chk_dump_addr "${ns2}" \
3521			"id 0 flags subflow 10.0.3.2" "id 0 subflow"
3522		chk_join_nr 1 1 1
3523		chk_mptcp_info subflows 1 subflows 1
3524		chk_subflows_total 2 2
3525		kill_events_pids
3526		mptcp_lib_kill_wait $tests_pid
3527	fi
3528
3529	# userspace pm remove initial subflow
3530	if reset_with_events "userspace pm remove initial subflow" &&
3531	   continue_if mptcp_lib_has_file '/proc/sys/net/mptcp/pm_type'; then
3532		set_userspace_pm $ns2
3533		pm_nl_set_limits $ns1 0 1
3534		speed=5 \
3535			run_tests $ns1 $ns2 10.0.1.1 &
3536		local tests_pid=$!
3537		wait_mpj $ns2
3538		userspace_pm_add_sf $ns2 10.0.3.2 20
3539		chk_join_nr 1 1 1
3540		chk_mptcp_info subflows 1 subflows 1
3541		chk_subflows_total 2 2
3542		userspace_pm_rm_sf $ns2 10.0.1.2
3543		# we don't look at the counter linked to the RM_ADDR but
3544		# to the one linked to the subflows that have been removed
3545		chk_rm_nr 0 1
3546		chk_rst_nr 0 0 invert
3547		chk_mptcp_info subflows 1 subflows 1
3548		chk_subflows_total 1 1
3549		kill_events_pids
3550		mptcp_lib_kill_wait $tests_pid
3551	fi
3552
3553	# userspace pm send RM_ADDR for ID 0
3554	if reset_with_events "userspace pm send RM_ADDR for ID 0" &&
3555	   continue_if mptcp_lib_has_file '/proc/sys/net/mptcp/pm_type'; then
3556		set_userspace_pm $ns1
3557		pm_nl_set_limits $ns2 1 1
3558		speed=5 \
3559			run_tests $ns1 $ns2 10.0.1.1 &
3560		local tests_pid=$!
3561		wait_mpj $ns1
3562		userspace_pm_add_addr $ns1 10.0.2.1 10
3563		chk_join_nr 1 1 1
3564		chk_add_nr 1 1
3565		chk_mptcp_info subflows 1 subflows 1
3566		chk_subflows_total 2 2
3567		chk_mptcp_info add_addr_signal 1 add_addr_accepted 1
3568		userspace_pm_rm_addr $ns1 0
3569		# we don't look at the counter linked to the subflows that
3570		# have been removed but to the one linked to the RM_ADDR
3571		chk_rm_nr 1 0 invert
3572		chk_rst_nr 0 0 invert
3573		chk_mptcp_info subflows 1 subflows 1
3574		chk_subflows_total 1 1
3575		kill_events_pids
3576		mptcp_lib_kill_wait $tests_pid
3577	fi
3578}
3579
3580endpoint_tests()
3581{
3582	# subflow_rebuild_header is needed to support the implicit flag
3583	# userspace pm type prevents add_addr
3584	if reset "implicit EP" &&
3585	   mptcp_lib_kallsyms_has "subflow_rebuild_header$"; then
3586		pm_nl_set_limits $ns1 2 2
3587		pm_nl_set_limits $ns2 2 2
3588		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
3589		speed=slow \
3590			run_tests $ns1 $ns2 10.0.1.1 &
3591		local tests_pid=$!
3592
3593		wait_mpj $ns1
3594		pm_nl_check_endpoint "creation" \
3595			$ns2 10.0.2.2 id 1 flags implicit
3596		chk_mptcp_info subflows 1 subflows 1
3597		chk_mptcp_info add_addr_signal 1 add_addr_accepted 1
3598
3599		pm_nl_add_endpoint $ns2 10.0.2.2 id 33 2>/dev/null
3600		pm_nl_check_endpoint "ID change is prevented" \
3601			$ns2 10.0.2.2 id 1 flags implicit
3602
3603		pm_nl_add_endpoint $ns2 10.0.2.2 flags signal
3604		pm_nl_check_endpoint "modif is allowed" \
3605			$ns2 10.0.2.2 id 1 flags signal
3606		mptcp_lib_kill_wait $tests_pid
3607	fi
3608
3609	if reset "delete and re-add" &&
3610	   mptcp_lib_kallsyms_has "subflow_rebuild_header$"; then
3611		pm_nl_set_limits $ns1 1 1
3612		pm_nl_set_limits $ns2 1 1
3613		pm_nl_add_endpoint $ns2 10.0.2.2 id 2 dev ns2eth2 flags subflow
3614		test_linkfail=4 speed=20 \
3615			run_tests $ns1 $ns2 10.0.1.1 &
3616		local tests_pid=$!
3617
3618		wait_mpj $ns2
3619		chk_subflow_nr "before delete" 2
3620		chk_mptcp_info subflows 1 subflows 1
3621
3622		pm_nl_del_endpoint $ns2 2 10.0.2.2
3623		sleep 0.5
3624		chk_subflow_nr "after delete" 1
3625		chk_mptcp_info subflows 0 subflows 0
3626
3627		pm_nl_add_endpoint $ns2 10.0.2.2 dev ns2eth2 flags subflow
3628		wait_mpj $ns2
3629		chk_subflow_nr "after re-add" 2
3630		chk_mptcp_info subflows 1 subflows 1
3631		mptcp_lib_kill_wait $tests_pid
3632	fi
3633}
3634
3635# [$1: error message]
3636usage()
3637{
3638	if [ -n "${1}" ]; then
3639		echo "${1}"
3640		ret=1
3641	fi
3642
3643	echo "mptcp_join usage:"
3644
3645	local key
3646	for key in "${!all_tests[@]}"; do
3647		echo "  -${key} ${all_tests[${key}]}"
3648	done
3649
3650	echo "  -c capture pcap files"
3651	echo "  -C enable data checksum"
3652	echo "  -i use ip mptcp"
3653	echo "  -h help"
3654
3655	echo "[test ids|names]"
3656
3657	exit ${ret}
3658}
3659
3660
3661# Use a "simple" array to force an specific order we cannot have with an associative one
3662all_tests_sorted=(
3663	f@subflows_tests
3664	e@subflows_error_tests
3665	s@signal_address_tests
3666	l@link_failure_tests
3667	t@add_addr_timeout_tests
3668	r@remove_tests
3669	a@add_tests
3670	6@ipv6_tests
3671	4@v4mapped_tests
3672	M@mixed_tests
3673	b@backup_tests
3674	p@add_addr_ports_tests
3675	k@syncookies_tests
3676	S@checksum_tests
3677	d@deny_join_id0_tests
3678	m@fullmesh_tests
3679	z@fastclose_tests
3680	F@fail_tests
3681	u@userspace_tests
3682	I@endpoint_tests
3683)
3684
3685all_tests_args=""
3686all_tests_names=()
3687for subtests in "${all_tests_sorted[@]}"; do
3688	key="${subtests%@*}"
3689	value="${subtests#*@}"
3690
3691	all_tests_args+="${key}"
3692	all_tests_names+=("${value}")
3693	all_tests[${key}]="${value}"
3694done
3695
3696tests=()
3697while getopts "${all_tests_args}cCih" opt; do
3698	case $opt in
3699		["${all_tests_args}"])
3700			tests+=("${all_tests[${opt}]}")
3701			;;
3702		c)
3703			capture=true
3704			;;
3705		C)
3706			checksum=true
3707			;;
3708		i)
3709			ip_mptcp=1
3710			;;
3711		h)
3712			usage
3713			;;
3714		*)
3715			usage "Unknown option: -${opt}"
3716			;;
3717	esac
3718done
3719
3720shift $((OPTIND - 1))
3721
3722for arg in "${@}"; do
3723	if [[ "${arg}" =~ ^[0-9]+$ ]]; then
3724		only_tests_ids+=("${arg}")
3725	else
3726		only_tests_names+=("${arg}")
3727	fi
3728done
3729
3730if [ ${#tests[@]} -eq 0 ]; then
3731	tests=("${all_tests_names[@]}")
3732fi
3733
3734for subtests in "${tests[@]}"; do
3735	"${subtests}"
3736done
3737
3738if [ ${ret} -ne 0 ]; then
3739	echo
3740	echo "${#failed_tests[@]} failure(s) has(ve) been detected:"
3741	for i in $(get_failed_tests_ids); do
3742		echo -e "\t- ${i}: ${failed_tests[${i}]}"
3743	done
3744	echo
3745fi
3746
3747append_prev_results
3748mptcp_lib_result_print_all_tap
3749
3750exit $ret
3751