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