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