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