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