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