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