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