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