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