Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
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,SC2329
12
13. "$(dirname "${0}")/mptcp_lib.sh"
14
15ret=0
16sin=""
17sinfail=""
18sout=""
19cin=""
20cinfail=""
21cinsent=""
22tmpfile=""
23cout=""
24err=""
25capout=""
26cappid=""
27ns1=""
28ns2=""
29iptables="iptables"
30ip6tables="ip6tables"
31timeout_poll=30
32timeout_test=$((timeout_poll * 2 + 1))
33capture=false
34checksum=false
35check_invert=0
36validate_checksum=false
37init=0
38evts_ns1=""
39evts_ns2=""
40evts_ns1_pid=0
41evts_ns2_pid=0
42last_test_failed=0
43last_test_skipped=0
44last_test_ignored=1
45
46declare -A all_tests
47declare -a only_tests_ids
48declare -a only_tests_names
49declare -A failed_tests
50MPTCP_LIB_TEST_FORMAT="%03u %s\n"
51TEST_NAME=""
52nr_blank=6
53
54# These var are used only in some tests, make sure they are not already set
55unset FAILING_LINKS
56unset test_linkfail
57unset addr_nr_ns1
58unset addr_nr_ns2
59unset cestab_ns1
60unset cestab_ns2
61unset sflags
62unset fastclose
63unset fullmesh
64unset speed
65unset bind_addr
66unset join_syn_rej
67unset join_csum_ns1
68unset join_csum_ns2
69unset join_fail_nr
70unset join_rst_nr
71unset join_infi_nr
72unset join_corrupted_pkts
73unset join_syn_tx
74unset join_create_err
75unset join_bind_err
76unset join_connect_err
77
78unset fb_ns1
79unset fb_ns2
80unset fb_infinite_map_tx
81unset fb_dss_corruption
82unset fb_simult_conn
83unset fb_mpc_passive
84unset fb_mpc_active
85unset fb_mpc_data
86unset fb_md5_sig
87unset fb_dss
88
89# generated using "nfbpf_compile '(ip && (ip[54] & 0xf0) == 0x30) ||
90# (ip6 && (ip6[74] & 0xf0) == 0x30)'"
91CBPF_MPTCP_SUBOPTION_ADD_ADDR="14,
92 48 0 0 0,
93 84 0 0 240,
94 21 0 3 64,
95 48 0 0 54,
96 84 0 0 240,
97 21 6 7 48,
98 48 0 0 0,
99 84 0 0 240,
100 21 0 4 96,
101 48 0 0 74,
102 84 0 0 240,
103 21 0 1 48,
104 6 0 0 65535,
105 6 0 0 0"
106
107init_partial()
108{
109 capout=$(mktemp)
110
111 mptcp_lib_ns_init ns1 ns2
112
113 local netns
114 for netns in "$ns1" "$ns2"; do
115 ip netns exec $netns sysctl -q net.mptcp.pm_type=0 2>/dev/null || true
116 if $checksum; then
117 ip netns exec $netns sysctl -q net.mptcp.checksum_enabled=1
118 fi
119 done
120
121 check_invert=0
122 validate_checksum=$checksum
123
124 # ns1 ns2
125 # ns1eth1 ns2eth1
126 # ns1eth2 ns2eth2
127 # ns1eth3 ns2eth3
128 # ns1eth4 ns2eth4
129
130 local i
131 for i in $(seq 1 4); do
132 ip link add ns1eth$i netns "$ns1" type veth peer name ns2eth$i netns "$ns2"
133 ip -net "$ns1" addr add 10.0.$i.1/24 dev ns1eth$i
134 ip -net "$ns1" addr add dead:beef:$i::1/64 dev ns1eth$i nodad
135 ip -net "$ns1" link set ns1eth$i up
136
137 ip -net "$ns2" addr add 10.0.$i.2/24 dev ns2eth$i
138 ip -net "$ns2" addr add dead:beef:$i::2/64 dev ns2eth$i nodad
139 ip -net "$ns2" link set ns2eth$i up
140
141 # let $ns2 reach any $ns1 address from any interface
142 ip -net "$ns2" route add default via 10.0.$i.1 dev ns2eth$i metric 10$i
143 ip -net "$ns2" route add default via dead:beef:$i::1 dev ns2eth$i metric 10$i
144 done
145}
146
147init_shapers()
148{
149 local i
150 for i in $(seq 1 4); do
151 tc -n $ns1 qdisc add dev ns1eth$i root netem rate 20mbit delay 1ms
152 tc -n $ns2 qdisc add dev ns2eth$i root netem rate 20mbit delay 1ms
153 done
154}
155
156cleanup_partial()
157{
158 rm -f "$capout"
159
160 mptcp_lib_ns_exit "${ns1}" "${ns2}"
161}
162
163init() {
164 init=1
165
166 mptcp_lib_check_mptcp
167 mptcp_lib_check_kallsyms
168 mptcp_lib_check_tools ip tc ss "${iptables}" "${ip6tables}"
169
170 sin=$(mktemp)
171 sout=$(mktemp)
172 cin=$(mktemp)
173 cinsent=$(mktemp)
174 cout=$(mktemp)
175 err=$(mktemp)
176 evts_ns1=$(mktemp)
177 evts_ns2=$(mktemp)
178
179 trap cleanup EXIT
180
181 make_file "$cin" "client" 1 >/dev/null
182 make_file "$sin" "server" 1 >/dev/null
183}
184
185cleanup()
186{
187 rm -f "$cin" "$cout" "$sinfail"
188 rm -f "$sin" "$sout" "$cinsent" "$cinfail"
189 rm -f "$tmpfile"
190 rm -rf $evts_ns1 $evts_ns2
191 rm -f "$err"
192 cleanup_partial
193}
194
195print_check()
196{
197 printf "%-${nr_blank}s%-36s" " " "${*}"
198}
199
200print_info()
201{
202 # It can be empty, no need to print anything then
203 [ -z "${1}" ] && return
204
205 mptcp_lib_print_info " Info: ${*}"
206}
207
208print_ok()
209{
210 mptcp_lib_pr_ok "${@}"
211}
212
213print_fail()
214{
215 mptcp_lib_pr_fail "${@}"
216}
217
218print_skip()
219{
220 mptcp_lib_pr_skip "${@}"
221}
222
223# $1: check name; $2: rc
224print_results()
225{
226 local check="${1}"
227 local rc=${2}
228
229 print_check "${check}"
230 if [ ${rc} = ${KSFT_PASS} ]; then
231 print_ok
232 elif [ ${rc} = ${KSFT_SKIP} ]; then
233 print_skip
234 else
235 fail_test "see above"
236 fi
237}
238
239# [ $1: fail msg ]
240mark_as_skipped()
241{
242 local msg="${1:-"Feature not supported"}"
243
244 mptcp_lib_fail_if_expected_feature "${msg}"
245
246 print_check "${msg}"
247 print_skip
248
249 last_test_skipped=1
250}
251
252# $@: condition
253continue_if()
254{
255 if ! "${@}"; then
256 mark_as_skipped
257 return 1
258 fi
259}
260
261skip_test()
262{
263 if [ "${#only_tests_ids[@]}" -eq 0 ] && [ "${#only_tests_names[@]}" -eq 0 ]; then
264 return 1
265 fi
266
267 local i
268 for i in "${only_tests_ids[@]}"; do
269 if [ "$((MPTCP_LIB_TEST_COUNTER+1))" -eq "${i}" ]; then
270 return 1
271 fi
272 done
273 for i in "${only_tests_names[@]}"; do
274 if [ "${TEST_NAME}" = "${i}" ]; then
275 return 1
276 fi
277 done
278
279 return 0
280}
281
282append_prev_results()
283{
284 if [ ${last_test_failed} -eq 1 ]; then
285 mptcp_lib_result_fail "${TEST_NAME}"
286 elif [ ${last_test_skipped} -eq 1 ]; then
287 mptcp_lib_result_skip "${TEST_NAME}"
288 elif [ ${last_test_ignored} -ne 1 ]; then
289 mptcp_lib_result_pass "${TEST_NAME}"
290 fi
291
292 last_test_failed=0
293 last_test_skipped=0
294 last_test_ignored=0
295}
296
297# $1: test name
298reset()
299{
300 append_prev_results
301
302 TEST_NAME="${1}"
303
304 MPTCP_LIB_SUBTEST_FLAKY=0 # reset if modified
305
306 if skip_test; then
307 MPTCP_LIB_TEST_COUNTER=$((MPTCP_LIB_TEST_COUNTER+1))
308 last_test_ignored=1
309 return 1
310 fi
311
312 mptcp_lib_print_title "${TEST_NAME}"
313
314 if [ "${init}" != "1" ]; then
315 init
316 else
317 cleanup_partial
318 fi
319
320 init_partial
321
322 return 0
323}
324
325# $1: test name ; $2: counter to check
326reset_check_counter()
327{
328 reset "${1}" || return 1
329
330 local counter="${2}"
331
332 if ! nstat -asz "${counter}" | grep -wq "${counter}"; then
333 mark_as_skipped "counter '${counter}' is not available"
334 return 1
335 fi
336}
337
338# $1: test name
339reset_with_cookies()
340{
341 reset "${1}" || return 1
342
343 local netns
344 for netns in "$ns1" "$ns2"; do
345 ip netns exec $netns sysctl -q net.ipv4.tcp_syncookies=2
346 done
347}
348
349# $1: test name
350reset_with_add_addr_timeout()
351{
352 local ip="${2:-4}"
353 local tables
354
355 reset "${1}" || return 1
356
357 tables="${iptables}"
358 if [ $ip -eq 6 ]; then
359 tables="${ip6tables}"
360 fi
361
362 # set a maximum, to avoid too long timeout with exponential backoff
363 ip netns exec $ns1 sysctl -q net.mptcp.add_addr_timeout=1
364
365 if ! ip netns exec $ns2 $tables -A OUTPUT -p tcp \
366 -m tcp --tcp-option 30 \
367 -m bpf --bytecode \
368 "$CBPF_MPTCP_SUBOPTION_ADD_ADDR" \
369 -j DROP; then
370 mark_as_skipped "unable to set the 'add addr' rule"
371 return 1
372 fi
373}
374
375# $1: test name
376reset_with_checksum()
377{
378 local ns1_enable=$1
379 local ns2_enable=$2
380
381 reset "checksum test ${ns1_enable} ${ns2_enable}" || return 1
382
383 ip netns exec $ns1 sysctl -q net.mptcp.checksum_enabled=$ns1_enable
384 ip netns exec $ns2 sysctl -q net.mptcp.checksum_enabled=$ns2_enable
385
386 validate_checksum=true
387}
388
389reset_with_allow_join_id0()
390{
391 local ns1_enable=$2
392 local ns2_enable=$3
393
394 reset "${1}" || return 1
395
396 ip netns exec $ns1 sysctl -q net.mptcp.allow_join_initial_addr_port=$ns1_enable
397 ip netns exec $ns2 sysctl -q net.mptcp.allow_join_initial_addr_port=$ns2_enable
398}
399
400# Modify TCP payload without corrupting the TCP packet
401#
402# This rule inverts a 8-bit word at byte offset 148 for the 2nd TCP ACK packets
403# carrying enough data.
404# Once it is done, the TCP Checksum field is updated so the packet is still
405# considered as valid at the TCP level.
406# Because the MPTCP checksum, covering the TCP options and data, has not been
407# updated, the modification will be detected and an MP_FAIL will be emitted:
408# what we want to validate here without corrupting "random" MPTCP options.
409#
410# To avoid having tc producing this pr_info() message for each TCP ACK packets
411# not carrying enough data:
412#
413# tc action pedit offset 162 out of bounds
414#
415# Netfilter is used to mark packets with enough data.
416setup_fail_rules()
417{
418 check_invert=1
419 validate_checksum=true
420 local i="$1"
421 local ip="${2:-4}"
422 local tables
423
424 tables="${iptables}"
425 if [ $ip -eq 6 ]; then
426 tables="${ip6tables}"
427 fi
428
429 ip netns exec $ns2 $tables \
430 -t mangle \
431 -A OUTPUT \
432 -o ns2eth$i \
433 -p tcp \
434 -m length --length 150:9999 \
435 -m statistic --mode nth --packet 1 --every 99999 \
436 -j MARK --set-mark 42 || return ${KSFT_SKIP}
437
438 tc -n $ns2 qdisc add dev ns2eth$i clsact || return ${KSFT_SKIP}
439 tc -n $ns2 filter add dev ns2eth$i egress \
440 protocol ip prio 1000 \
441 handle 42 fw \
442 action pedit munge offset 148 u8 invert \
443 pipe csum tcp \
444 index 100 || return ${KSFT_SKIP}
445}
446
447reset_with_fail()
448{
449 reset_check_counter "${1}" "MPTcpExtInfiniteMapTx" || return 1
450 shift
451
452 ip netns exec $ns1 sysctl -q net.mptcp.checksum_enabled=1
453 ip netns exec $ns2 sysctl -q net.mptcp.checksum_enabled=1
454
455 local rc=0
456 setup_fail_rules "${@}" || rc=$?
457
458 if [ ${rc} -eq ${KSFT_SKIP} ]; then
459 mark_as_skipped "unable to set the 'fail' rules"
460 return 1
461 fi
462}
463
464start_events()
465{
466 mptcp_lib_events "${ns1}" "${evts_ns1}" evts_ns1_pid
467 mptcp_lib_events "${ns2}" "${evts_ns2}" evts_ns2_pid
468}
469
470reset_with_events()
471{
472 reset "${1}" || return 1
473
474 start_events
475}
476
477reset_with_tcp_filter()
478{
479 reset "${1}" || return 1
480 shift
481
482 local ns="${!1}"
483 local src="${2}"
484 local target="${3}"
485 local chain="${4:-INPUT}"
486
487 if ! ip netns exec "${ns}" ${iptables} \
488 -A "${chain}" \
489 -s "${src}" \
490 -p tcp \
491 -j "${target}"; then
492 mark_as_skipped "unable to set the filter rules"
493 return 1
494 fi
495}
496
497# $1: err msg
498fail_test()
499{
500 if ! mptcp_lib_subtest_is_flaky; then
501 ret=${KSFT_FAIL}
502 fi
503
504 if [ ${#} -gt 0 ]; then
505 print_fail "${@}"
506 fi
507
508 # just in case a test is marked twice as failed
509 if [ ${last_test_failed} -eq 0 ]; then
510 failed_tests[${MPTCP_LIB_TEST_COUNTER}]="${TEST_NAME}"
511 dump_stats
512 last_test_failed=1
513 fi
514}
515
516get_failed_tests_ids()
517{
518 # sorted
519 local i
520 for i in "${!failed_tests[@]}"; do
521 echo "${i}"
522 done | sort -n
523}
524
525check_transfer()
526{
527 local in=$1
528 local out=$2
529 local what=$3
530 local bytes=$4
531 local i a b
532
533 local line
534 if [ -n "$bytes" ]; then
535 local out_size
536 # when truncating we must check the size explicitly
537 out_size=$(wc -c $out | awk '{print $1}')
538 if [ $out_size -ne $bytes ]; then
539 fail_test "$what output file has wrong size ($out_size, $bytes)"
540 return 1
541 fi
542
543 # note: BusyBox's "cmp" command doesn't support --bytes
544 tmpfile=$(mktemp)
545 head --bytes="$bytes" "$in" > "$tmpfile"
546 mv "$tmpfile" "$in"
547 head --bytes="$bytes" "$out" > "$tmpfile"
548 mv "$tmpfile" "$out"
549 tmpfile=""
550 fi
551 cmp -l "$in" "$out" | while read -r i a b; do
552 local sum=$((0${a} + 0${b}))
553 if [ $check_invert -eq 0 ] || [ $sum -ne $((0xff)) ]; then
554 fail_test "$what does not match (in, out):"
555 mptcp_lib_print_file_err "$in"
556 mptcp_lib_print_file_err "$out"
557
558 return 1
559 else
560 print_info "$what has inverted byte at ${i}"
561 fi
562 done
563
564 return 0
565}
566
567do_ping()
568{
569 local listener_ns="$1"
570 local connector_ns="$2"
571 local connect_addr="$3"
572
573 if ! ip netns exec ${connector_ns} ping -q -c 1 $connect_addr >/dev/null; then
574 fail_test "$listener_ns -> $connect_addr connectivity"
575 fi
576}
577
578link_failure()
579{
580 local ns="$1"
581
582 if [ -z "$FAILING_LINKS" ]; then
583 l=$((RANDOM%4))
584 FAILING_LINKS=$((l+1))
585 fi
586
587 local l
588 for l in $FAILING_LINKS; do
589 local veth="ns1eth$l"
590 ip -net "$ns" link set "$veth" down
591 done
592}
593
594rm_addr_count()
595{
596 mptcp_lib_get_counter "${1}" "MPTcpExtRmAddr"
597}
598
599# $1: ns, $2: old rm_addr counter in $ns
600wait_rm_addr()
601{
602 local ns="${1}"
603 local old_cnt="${2}"
604 local cnt
605
606 local i
607 for i in $(seq 10); do
608 cnt=$(rm_addr_count ${ns})
609 [ "$cnt" = "${old_cnt}" ] || break
610 sleep 0.1
611 done
612}
613
614rm_sf_count()
615{
616 mptcp_lib_get_counter "${1}" "MPTcpExtRmSubflow"
617}
618
619# $1: ns, $2: old rm_sf counter in $ns
620wait_rm_sf()
621{
622 local ns="${1}"
623 local old_cnt="${2}"
624 local cnt
625
626 local i
627 for i in $(seq 10); do
628 cnt=$(rm_sf_count ${ns})
629 [ "$cnt" = "${old_cnt}" ] || break
630 sleep 0.1
631 done
632}
633
634wait_mpj()
635{
636 local ns="${1}"
637 local cnt old_cnt
638
639 old_cnt=$(mptcp_lib_get_counter ${ns} "MPTcpExtMPJoinAckRx")
640
641 local i
642 for i in $(seq 10); do
643 cnt=$(mptcp_lib_get_counter ${ns} "MPTcpExtMPJoinAckRx")
644 [ "$cnt" = "${old_cnt}" ] || break
645 sleep 0.1
646 done
647}
648
649wait_ll_ready()
650{
651 local ns="${1}"
652
653 local i
654 for i in $(seq 50); do
655 ip -n "${ns}" -6 addr show scope link | grep "inet6 fe80" |
656 grep -qw "tentative" || break
657 sleep 0.1
658 done
659}
660
661get_ll_addr()
662{
663 local ns="${1}"
664 local iface="${2}"
665
666 ip -n "${ns}" -6 addr show dev "${iface}" scope link |
667 grep "inet6 fe80" | sed 's#.*\(fe80::.*\)/.*#\1#'
668}
669
670kill_events_pids()
671{
672 mptcp_lib_kill_wait $evts_ns1_pid
673 evts_ns1_pid=0
674 mptcp_lib_kill_wait $evts_ns2_pid
675 evts_ns2_pid=0
676}
677
678pm_nl_set_limits()
679{
680 mptcp_lib_pm_nl_set_limits "${@}"
681}
682
683pm_nl_add_endpoint()
684{
685 mptcp_lib_pm_nl_add_endpoint "${@}"
686}
687
688pm_nl_del_endpoint()
689{
690 mptcp_lib_pm_nl_del_endpoint "${@}"
691}
692
693pm_nl_flush_endpoint()
694{
695 mptcp_lib_pm_nl_flush_endpoint "${@}"
696}
697
698pm_nl_show_endpoints()
699{
700 mptcp_lib_pm_nl_show_endpoints "${@}"
701}
702
703pm_nl_change_endpoint()
704{
705 mptcp_lib_pm_nl_change_endpoint "${@}"
706}
707
708pm_nl_check_endpoint()
709{
710 local msg="$1"
711 local ns=$2
712 local addr=$3
713 local flags dev id port
714
715 print_check "${msg}"
716
717 shift 3
718 while [ -n "$1" ]; do
719 case "${1}" in
720 "flags" | "dev" | "id" | "port")
721 eval "${1}"="${2}"
722 shift
723 ;;
724 *)
725 ;;
726 esac
727
728 shift
729 done
730
731 if [ -z "${id}" ]; then
732 fail_test "bad test - missing endpoint id"
733 return
734 fi
735
736 check_output "mptcp_lib_pm_nl_get_endpoint ${ns} ${id}" \
737 "$(mptcp_lib_pm_nl_format_endpoints \
738 "${id},${addr},${flags//","/" "},${dev},${port}")"
739}
740
741pm_nl_set_endpoint()
742{
743 local listener_ns="$1"
744 local connector_ns="$2"
745 local connect_addr="$3"
746
747 local addr_nr_ns1=${addr_nr_ns1:-0}
748 local addr_nr_ns2=${addr_nr_ns2:-0}
749 local sflags=${sflags:-""}
750 local fullmesh=${fullmesh:-""}
751
752 local flags="subflow"
753 if [ -n "${fullmesh}" ]; then
754 flags="${flags},fullmesh"
755 addr_nr_ns2=${fullmesh}
756 fi
757
758 # let the mptcp subflow be established in background before
759 # do endpoint manipulation
760 if [ $addr_nr_ns1 != "0" ] || [ $addr_nr_ns2 != "0" ]; then
761 sleep 1
762 fi
763
764 if [ $addr_nr_ns1 -gt 0 ]; then
765 local counter=2
766 local add_nr_ns1=${addr_nr_ns1}
767 local id=10
768 while [ $add_nr_ns1 -gt 0 ]; do
769 local addr
770 if mptcp_lib_is_v6 "${connect_addr}"; then
771 addr="dead:beef:$counter::1"
772 else
773 addr="10.0.$counter.1"
774 fi
775 pm_nl_add_endpoint $ns1 $addr flags signal
776 counter=$((counter + 1))
777 add_nr_ns1=$((add_nr_ns1 - 1))
778 id=$((id + 1))
779 done
780 elif [ $addr_nr_ns1 -lt 0 ]; then
781 local rm_nr_ns1=$((-addr_nr_ns1))
782 if [ $rm_nr_ns1 -lt 8 ]; then
783 local counter=0
784 local line
785 pm_nl_show_endpoints ${listener_ns} | while read -r line; do
786 # shellcheck disable=SC2206 # we do want to split per word
787 local arr=($line)
788 local nr=0
789
790 local i
791 for i in "${arr[@]}"; do
792 if [ $i = "id" ]; then
793 if [ $counter -eq $rm_nr_ns1 ]; then
794 break
795 fi
796 id=${arr[$nr+1]}
797 rm_addr=$(rm_addr_count ${connector_ns})
798 pm_nl_del_endpoint ${listener_ns} $id
799 wait_rm_addr ${connector_ns} ${rm_addr}
800 counter=$((counter + 1))
801 fi
802 nr=$((nr + 1))
803 done
804 done
805 elif [ $rm_nr_ns1 -eq 8 ]; then
806 pm_nl_flush_endpoint ${listener_ns}
807 elif [ $rm_nr_ns1 -eq 9 ]; then
808 pm_nl_del_endpoint ${listener_ns} 0 ${connect_addr}
809 fi
810 fi
811
812 # if newly added endpoints must be deleted, give the background msk
813 # some time to created them
814 [ $addr_nr_ns1 -gt 0 ] && [ $addr_nr_ns2 -lt 0 ] && sleep 1
815
816 if [ $addr_nr_ns2 -gt 0 ]; then
817 local add_nr_ns2=${addr_nr_ns2}
818 local counter=3
819 local id=20
820 while [ $add_nr_ns2 -gt 0 ]; do
821 local addr
822 if mptcp_lib_is_v6 "${connect_addr}"; then
823 addr="dead:beef:$counter::2"
824 else
825 addr="10.0.$counter.2"
826 fi
827 pm_nl_add_endpoint $ns2 $addr flags $flags
828 counter=$((counter + 1))
829 add_nr_ns2=$((add_nr_ns2 - 1))
830 id=$((id + 1))
831 done
832 elif [ $addr_nr_ns2 -lt 0 ]; then
833 local rm_nr_ns2=$((-addr_nr_ns2))
834 if [ $rm_nr_ns2 -lt 8 ]; then
835 local counter=0
836 local line
837 pm_nl_show_endpoints ${connector_ns} | while read -r line; do
838 # shellcheck disable=SC2206 # we do want to split per word
839 local arr=($line)
840 local nr=0
841
842 local i
843 for i in "${arr[@]}"; do
844 if [ $i = "id" ]; then
845 if [ $counter -eq $rm_nr_ns2 ]; then
846 break
847 fi
848 local id rm_addr
849 # rm_addr are serialized, allow the previous one to
850 # complete
851 id=${arr[$nr+1]}
852 rm_addr=$(rm_addr_count ${listener_ns})
853 pm_nl_del_endpoint ${connector_ns} $id
854 wait_rm_addr ${listener_ns} ${rm_addr}
855 counter=$((counter + 1))
856 fi
857 nr=$((nr + 1))
858 done
859 done
860 elif [ $rm_nr_ns2 -eq 8 ]; then
861 pm_nl_flush_endpoint ${connector_ns}
862 elif [ $rm_nr_ns2 -eq 9 ]; then
863 local addr
864 if mptcp_lib_is_v6 "${connect_addr}"; then
865 addr="dead:beef:1::2"
866 else
867 addr="10.0.1.2"
868 fi
869 pm_nl_del_endpoint ${connector_ns} 0 $addr
870 fi
871 fi
872
873 if [ -n "${sflags}" ]; then
874 sleep 1
875
876 local netns
877 for netns in "$ns1" "$ns2"; do
878 local line
879 pm_nl_show_endpoints $netns | while read -r line; do
880 # shellcheck disable=SC2206 # we do want to split per word
881 local arr=($line)
882 local nr=0
883 local id
884
885 local i
886 for i in "${arr[@]}"; do
887 if [ $i = "id" ]; then
888 id=${arr[$nr+1]}
889 fi
890 nr=$((nr + 1))
891 done
892 pm_nl_change_endpoint $netns $id $sflags
893 done
894 done
895 fi
896}
897
898chk_cestab_nr()
899{
900 local ns=$1
901 local cestab=$2
902 local count
903
904 print_check "currently established: $cestab"
905 count=$(mptcp_lib_get_counter ${ns} "MPTcpExtMPCurrEstab")
906 if [ -z "$count" ]; then
907 print_skip
908 elif [ "$count" != "$cestab" ]; then
909 fail_test "got $count current establish[s] expected $cestab"
910 else
911 print_ok
912 fi
913}
914
915# $1 namespace 1, $2 namespace 2
916check_cestab()
917{
918 if [ -n "${cestab_ns1}" ]; then
919 chk_cestab_nr ${1} ${cestab_ns1}
920 fi
921 if [ -n "${cestab_ns2}" ]; then
922 chk_cestab_nr ${2} ${cestab_ns2}
923 fi
924}
925
926cond_start_capture()
927{
928 local ns="$1"
929
930 :> "$capout"
931
932 if $capture; then
933 local capuser capfile
934 if [ -z $SUDO_USER ]; then
935 capuser=""
936 else
937 capuser="-Z $SUDO_USER"
938 fi
939
940 capfile=$(printf "mp_join-%02u-%s.pcap" "$MPTCP_LIB_TEST_COUNTER" "$ns")
941
942 echo "Capturing traffic for test $MPTCP_LIB_TEST_COUNTER into $capfile"
943 ip netns exec "$ns" tcpdump -i any -s 65535 -B 32768 $capuser -w "$capfile" > "$capout" 2>&1 &
944 cappid=$!
945
946 sleep 1
947 fi
948}
949
950cond_stop_capture()
951{
952 if $capture; then
953 sleep 1
954 kill $cappid
955 cat "$capout"
956 fi
957}
958
959get_port()
960{
961 echo "$((10000 + MPTCP_LIB_TEST_COUNTER - 1))"
962}
963
964do_transfer()
965{
966 local listener_ns="$1"
967 local connector_ns="$2"
968 local cl_proto="$3"
969 local srv_proto="$4"
970 local connect_addr="$5"
971 local port
972
973 local FAILING_LINKS=${FAILING_LINKS:-""}
974 local fastclose=${fastclose:-""}
975 local speed=${speed:-"fast"}
976 local bind_addr=${bind_addr:-"::"}
977 local listener_in="${sin}"
978 local connector_in="${cin}"
979 port=$(get_port)
980
981 :> "$cout"
982 :> "$sout"
983
984 cond_start_capture ${listener_ns}
985
986 mptcp_lib_nstat_init "${listener_ns}"
987 mptcp_lib_nstat_init "${connector_ns}"
988
989 local extra_args
990 if [ $speed = "fast" ]; then
991 extra_args="-j"
992 elif [ $speed = "slow" ]; then
993 extra_args="-r 50"
994 elif [ $speed -gt 0 ]; then
995 extra_args="-r ${speed}"
996 fi
997
998 local extra_cl_args=""
999 local extra_srv_args=""
1000 local trunc_size=""
1001 if [ -n "${fastclose}" ]; then
1002 if [ ${test_linkfail} -le 1 ]; then
1003 fail_test "fastclose tests need test_linkfail argument"
1004 return 1
1005 fi
1006
1007 # disconnect
1008 trunc_size=${test_linkfail}
1009 local side=${fastclose}
1010
1011 if [ ${side} = "client" ]; then
1012 extra_cl_args="-f ${test_linkfail}"
1013 extra_srv_args="-f -1"
1014 elif [ ${side} = "server" ]; then
1015 extra_srv_args="-f ${test_linkfail}"
1016 extra_cl_args="-f -1"
1017 else
1018 fail_test "wrong/unknown fastclose spec ${side}"
1019 return 1
1020 fi
1021 fi
1022
1023 extra_srv_args="$extra_args $extra_srv_args"
1024 if [ "$test_linkfail" -gt 1 ];then
1025 listener_in="${sinfail}"
1026 fi
1027 ip netns exec ${listener_ns} \
1028 ./mptcp_connect -t ${timeout_poll} -l -p ${port} -s ${srv_proto} \
1029 ${extra_srv_args} "${bind_addr}" < "${listener_in}" > "${sout}" &
1030 local spid=$!
1031
1032 mptcp_lib_wait_local_port_listen "${listener_ns}" "${port}"
1033
1034 extra_cl_args="$extra_args $extra_cl_args"
1035 if [ "$test_linkfail" -eq 0 ];then
1036 ip netns exec ${connector_ns} \
1037 ./mptcp_connect -t ${timeout_poll} -p $port -s ${cl_proto} \
1038 $extra_cl_args $connect_addr < "$cin" > "$cout" &
1039 elif [ "$test_linkfail" -eq 1 ] || [ "$test_linkfail" -eq 2 ];then
1040 connector_in="${cinsent}"
1041 ( cat "$cinfail" ; sleep 2; link_failure $listener_ns ; cat "$cinfail" ) | \
1042 tee "$cinsent" | \
1043 ip netns exec ${connector_ns} \
1044 ./mptcp_connect -t ${timeout_poll} -p $port -s ${cl_proto} \
1045 $extra_cl_args $connect_addr > "$cout" &
1046 else
1047 connector_in="${cinsent}"
1048 tee "$cinsent" < "$cinfail" | \
1049 ip netns exec ${connector_ns} \
1050 ./mptcp_connect -t ${timeout_poll} -p $port -s ${cl_proto} \
1051 $extra_cl_args $connect_addr > "$cout" &
1052 fi
1053 local cpid=$!
1054
1055 mptcp_lib_wait_timeout "${timeout_test}" "${listener_ns}" \
1056 "${connector_ns}" "${port}" "${cpid}" "${spid}" &
1057 local timeout_pid=$!
1058
1059 pm_nl_set_endpoint $listener_ns $connector_ns $connect_addr
1060 check_cestab $listener_ns $connector_ns
1061
1062 wait $cpid
1063 local retc=$?
1064 wait $spid
1065 local rets=$?
1066
1067 if kill -0 $timeout_pid; then
1068 # Finished before the timeout: kill the background job
1069 mptcp_lib_kill_group_wait $timeout_pid
1070 timeout_pid=0
1071 fi
1072
1073 cond_stop_capture
1074
1075 mptcp_lib_nstat_get "${listener_ns}"
1076 mptcp_lib_nstat_get "${connector_ns}"
1077
1078 if [ ${rets} -ne 0 ] || [ ${retc} -ne 0 ] || [ ${timeout_pid} -ne 0 ]; then
1079 fail_test "client exit code $retc, server $rets"
1080 mptcp_lib_pr_err_stats "${listener_ns}" "${connector_ns}" "${port}"
1081 return 1
1082 fi
1083
1084 check_transfer $listener_in $cout "file received by client" $trunc_size
1085 retc=$?
1086 check_transfer $connector_in $sout "file received by server" $trunc_size
1087 rets=$?
1088
1089 [ $retc -eq 0 ] && [ $rets -eq 0 ]
1090}
1091
1092make_file()
1093{
1094 local name=$1
1095 local who=$2
1096 local size=$3
1097
1098 mptcp_lib_make_file $name 1024 $size
1099
1100 print_info "Test file (size $size KB) for $who"
1101}
1102
1103run_tests()
1104{
1105 local listener_ns="$1"
1106 local connector_ns="$2"
1107 local connect_addr="$3"
1108
1109 local size
1110 local test_linkfail=${test_linkfail:-0}
1111
1112 # The values above 2 are reused to make test files
1113 # with the given sizes (KB)
1114 if [ "$test_linkfail" -gt 2 ]; then
1115 size=$test_linkfail
1116
1117 if [ -z "$cinfail" ]; then
1118 cinfail=$(mktemp)
1119 fi
1120 make_file "$cinfail" "client" $size
1121 # create the input file for the failure test when
1122 # the first failure test run
1123 elif [ "$test_linkfail" -ne 0 ] && [ -z "$cinfail" ]; then
1124 # the client file must be considerably larger
1125 # of the maximum expected cwin value, or the
1126 # link utilization will be not predicable
1127 size=$((RANDOM%2))
1128 size=$((size+1))
1129 size=$((size*8192))
1130 size=$((size + ( RANDOM % 8192) ))
1131
1132 cinfail=$(mktemp)
1133 make_file "$cinfail" "client" $size
1134 fi
1135
1136 if [ "$test_linkfail" -gt 2 ]; then
1137 size=$test_linkfail
1138
1139 if [ -z "$sinfail" ]; then
1140 sinfail=$(mktemp)
1141 fi
1142 make_file "$sinfail" "server" $size
1143 elif [ "$test_linkfail" -eq 2 ] && [ -z "$sinfail" ]; then
1144 size=$((RANDOM%16))
1145 size=$((size+1))
1146 size=$((size*2048))
1147
1148 sinfail=$(mktemp)
1149 make_file "$sinfail" "server" $size
1150 fi
1151
1152 do_transfer ${listener_ns} ${connector_ns} MPTCP MPTCP ${connect_addr}
1153}
1154
1155_dump_stats()
1156{
1157 local ns="${1}"
1158 local side="${2}"
1159
1160 mptcp_lib_print_err "${side} ns stats (${ns2})"
1161 mptcp_lib_pr_nstat "${ns}"
1162 echo
1163}
1164
1165dump_stats()
1166{
1167 _dump_stats "${ns1}" "Server"
1168 _dump_stats "${ns2}" "Client"
1169}
1170
1171chk_csum_nr()
1172{
1173 local csum_ns1=${1:-0}
1174 local csum_ns2=${2:-0}
1175 local count
1176 local extra_msg=""
1177 local allow_multi_errors_ns1=0
1178 local allow_multi_errors_ns2=0
1179
1180 if [[ "${csum_ns1}" = "+"* ]]; then
1181 allow_multi_errors_ns1=1
1182 csum_ns1=${csum_ns1:1}
1183 fi
1184 if [[ "${csum_ns2}" = "+"* ]]; then
1185 allow_multi_errors_ns2=1
1186 csum_ns2=${csum_ns2:1}
1187 fi
1188
1189 print_check "checksum server"
1190 count=$(mptcp_lib_get_counter ${ns1} "MPTcpExtDataCsumErr")
1191 if [ -n "$count" ] && [ "$count" != "$csum_ns1" ]; then
1192 extra_msg+=" ns1=$count"
1193 fi
1194 if [ -z "$count" ]; then
1195 print_skip
1196 elif { [ "$count" != $csum_ns1 ] && [ $allow_multi_errors_ns1 -eq 0 ]; } ||
1197 { [ "$count" -lt $csum_ns1 ] && [ $allow_multi_errors_ns1 -eq 1 ]; }; then
1198 fail_test "got $count data checksum error[s] expected $csum_ns1"
1199 else
1200 print_ok
1201 fi
1202
1203 print_check "checksum client"
1204 count=$(mptcp_lib_get_counter ${ns2} "MPTcpExtDataCsumErr")
1205 if [ -n "$count" ] && [ "$count" != "$csum_ns2" ]; then
1206 extra_msg+=" ns2=$count"
1207 fi
1208 if [ -z "$count" ]; then
1209 print_skip
1210 elif { [ "$count" != $csum_ns2 ] && [ $allow_multi_errors_ns2 -eq 0 ]; } ||
1211 { [ "$count" -lt $csum_ns2 ] && [ $allow_multi_errors_ns2 -eq 1 ]; }; then
1212 fail_test "got $count data checksum error[s] expected $csum_ns2"
1213 else
1214 print_ok
1215 fi
1216
1217 print_info "$extra_msg"
1218}
1219
1220chk_fail_nr()
1221{
1222 local fail_tx=$1
1223 local fail_rx=$2
1224 local ns_invert=${3:-""}
1225 local count
1226 local ns_tx=$ns1
1227 local ns_rx=$ns2
1228 local tx="server"
1229 local rx="client"
1230 local extra_msg=""
1231 local allow_tx_lost=0
1232 local allow_rx_lost=0
1233
1234 if [[ $ns_invert = "invert" ]]; then
1235 ns_tx=$ns2
1236 ns_rx=$ns1
1237 tx="client"
1238 rx="server"
1239 fi
1240
1241 if [[ "${fail_tx}" = "-"* ]]; then
1242 allow_tx_lost=1
1243 fail_tx=${fail_tx:1}
1244 fi
1245 if [[ "${fail_rx}" = "-"* ]]; then
1246 allow_rx_lost=1
1247 fail_rx=${fail_rx:1}
1248 fi
1249
1250 print_check "fail tx ${tx}"
1251 count=$(mptcp_lib_get_counter ${ns_tx} "MPTcpExtMPFailTx")
1252 if [ -n "$count" ] && [ "$count" != "$fail_tx" ]; then
1253 extra_msg+=" tx=$count"
1254 fi
1255 if [ -z "$count" ]; then
1256 print_skip
1257 elif { [ "$count" != "$fail_tx" ] && [ $allow_tx_lost -eq 0 ]; } ||
1258 { [ "$count" -gt "$fail_tx" ] && [ $allow_tx_lost -eq 1 ]; }; then
1259 fail_test "got $count MP_FAIL[s] TX expected $fail_tx"
1260 else
1261 print_ok
1262 fi
1263
1264 print_check "fail rx ${rx}"
1265 count=$(mptcp_lib_get_counter ${ns_rx} "MPTcpExtMPFailRx")
1266 if [ -n "$count" ] && [ "$count" != "$fail_rx" ]; then
1267 extra_msg+=" rx=$count"
1268 fi
1269 if [ -z "$count" ]; then
1270 print_skip
1271 elif { [ "$count" != "$fail_rx" ] && [ $allow_rx_lost -eq 0 ]; } ||
1272 { [ "$count" -gt "$fail_rx" ] && [ $allow_rx_lost -eq 1 ]; }; then
1273 fail_test "got $count MP_FAIL[s] RX expected $fail_rx"
1274 else
1275 print_ok
1276 fi
1277
1278 print_info "$extra_msg"
1279}
1280
1281chk_fclose_nr()
1282{
1283 local fclose_tx=$1
1284 local fclose_rx=$2
1285 local ns_invert=$3
1286 local count
1287 local ns_tx=$ns2
1288 local ns_rx=$ns1
1289 local tx="client"
1290 local rx="server"
1291
1292 if [[ $ns_invert = "invert" ]]; then
1293 ns_tx=$ns1
1294 ns_rx=$ns2
1295 tx="server"
1296 rx="client"
1297 fi
1298
1299 print_check "fast close tx ${tx}"
1300 count=$(mptcp_lib_get_counter ${ns_tx} "MPTcpExtMPFastcloseTx")
1301 if [ -z "$count" ]; then
1302 print_skip
1303 elif [ "$count" != "$fclose_tx" ]; then
1304 fail_test "got $count MP_FASTCLOSE[s] TX expected $fclose_tx"
1305 else
1306 print_ok
1307 fi
1308
1309 print_check "fast close rx ${rx}"
1310 count=$(mptcp_lib_get_counter ${ns_rx} "MPTcpExtMPFastcloseRx")
1311 if [ -z "$count" ]; then
1312 print_skip
1313 elif [ "$count" != "$fclose_rx" ]; then
1314 fail_test "got $count MP_FASTCLOSE[s] RX expected $fclose_rx"
1315 else
1316 print_ok
1317 fi
1318}
1319
1320chk_rst_nr()
1321{
1322 local rst_tx=$1
1323 local rst_rx=$2
1324 local ns_invert=${3:-""}
1325 local count
1326 local ns_tx=$ns1
1327 local ns_rx=$ns2
1328 local tx="server"
1329 local rx="client"
1330
1331 if [[ $ns_invert = "invert" ]]; then
1332 ns_tx=$ns2
1333 ns_rx=$ns1
1334 tx="client"
1335 rx="server"
1336 fi
1337
1338 print_check "reset tx ${tx}"
1339 count=$(mptcp_lib_get_counter ${ns_tx} "MPTcpExtMPRstTx")
1340 if [ -z "$count" ]; then
1341 print_skip
1342 # accept more rst than expected except if we don't expect any
1343 elif { [ $rst_tx -ne 0 ] && [ $count -lt $rst_tx ]; } ||
1344 { [ $rst_tx -eq 0 ] && [ $count -ne 0 ]; }; then
1345 fail_test "got $count MP_RST[s] TX expected $rst_tx"
1346 else
1347 print_ok
1348 fi
1349
1350 print_check "reset rx ${rx}"
1351 count=$(mptcp_lib_get_counter ${ns_rx} "MPTcpExtMPRstRx")
1352 if [ -z "$count" ]; then
1353 print_skip
1354 # accept more rst than expected except if we don't expect any
1355 elif { [ $rst_rx -ne 0 ] && [ $count -lt $rst_rx ]; } ||
1356 { [ $rst_rx -eq 0 ] && [ $count -ne 0 ]; }; then
1357 fail_test "got $count MP_RST[s] RX expected $rst_rx"
1358 else
1359 print_ok
1360 fi
1361}
1362
1363chk_infi_nr()
1364{
1365 local infi_tx=$1
1366 local infi_rx=$2
1367 local count
1368
1369 print_check "infi tx client"
1370 count=$(mptcp_lib_get_counter ${ns2} "MPTcpExtInfiniteMapTx")
1371 if [ -z "$count" ]; then
1372 print_skip
1373 elif [ "$count" != "$infi_tx" ]; then
1374 fail_test "got $count infinite map[s] TX expected $infi_tx"
1375 else
1376 print_ok
1377 fi
1378
1379 print_check "infi rx server"
1380 count=$(mptcp_lib_get_counter ${ns1} "MPTcpExtInfiniteMapRx")
1381 if [ -z "$count" ]; then
1382 print_skip
1383 elif [ "$count" != "$infi_rx" ]; then
1384 fail_test "got $count infinite map[s] RX expected $infi_rx"
1385 else
1386 print_ok
1387 fi
1388}
1389
1390chk_join_tx_nr()
1391{
1392 local syn_tx=${join_syn_tx:-0}
1393 local create=${join_create_err:-0}
1394 local bind=${join_bind_err:-0}
1395 local connect=${join_connect_err:-0}
1396 local rc=${KSFT_PASS}
1397 local count
1398
1399 count=$(mptcp_lib_get_counter ${ns2} "MPTcpExtMPJoinSynTx")
1400 if [ -z "$count" ]; then
1401 rc=${KSFT_SKIP}
1402 elif [ "$count" != "$syn_tx" ]; then
1403 rc=${KSFT_FAIL}
1404 print_check "syn tx"
1405 fail_test "got $count JOIN[s] syn tx expected $syn_tx"
1406 fi
1407
1408 count=$(mptcp_lib_get_counter ${ns2} "MPTcpExtMPJoinSynTxCreatSkErr")
1409 if [ -z "$count" ]; then
1410 rc=${KSFT_SKIP}
1411 elif [ "$count" != "$create" ]; then
1412 rc=${KSFT_FAIL}
1413 print_check "syn tx create socket error"
1414 fail_test "got $count JOIN[s] syn tx create socket error expected $create"
1415 fi
1416
1417 count=$(mptcp_lib_get_counter ${ns2} "MPTcpExtMPJoinSynTxBindErr")
1418 if [ -z "$count" ]; then
1419 rc=${KSFT_SKIP}
1420 elif [ "$count" != "$bind" ]; then
1421 rc=${KSFT_FAIL}
1422 print_check "syn tx bind error"
1423 fail_test "got $count JOIN[s] syn tx bind error expected $bind"
1424 fi
1425
1426 count=$(mptcp_lib_get_counter ${ns2} "MPTcpExtMPJoinSynTxConnectErr")
1427 if [ -z "$count" ]; then
1428 rc=${KSFT_SKIP}
1429 elif [ "$count" != "$connect" ]; then
1430 rc=${KSFT_FAIL}
1431 print_check "syn tx connect error"
1432 fail_test "got $count JOIN[s] syn tx connect error expected $connect"
1433 fi
1434
1435 print_results "join Tx" ${rc}
1436}
1437
1438chk_fallback_nr()
1439{
1440 local infinite_map_tx=${fb_infinite_map_tx:-0}
1441 local dss_corruption=${fb_dss_corruption:-0}
1442 local simult_conn=${fb_simult_conn:-0}
1443 local mpc_passive=${fb_mpc_passive:-0}
1444 local mpc_active=${fb_mpc_active:-0}
1445 local mpc_data=${fb_mpc_data:-0}
1446 local md5_sig=${fb_md5_sig:-0}
1447 local dss=${fb_dss:-0}
1448 local rc=${KSFT_PASS}
1449 local ns=$1
1450 local count
1451
1452 count=$(mptcp_lib_get_counter ${!ns} "MPTcpExtInfiniteMapTx")
1453 if [ -z "$count" ]; then
1454 rc=${KSFT_SKIP}
1455 elif [ "$count" != "$infinite_map_tx" ]; then
1456 rc=${KSFT_FAIL}
1457 print_check "$ns infinite map tx fallback"
1458 fail_test "got $count infinite map tx fallback[s] in $ns expected $infinite_map_tx"
1459 fi
1460
1461 count=$(mptcp_lib_get_counter ${!ns} "MPTcpExtDSSCorruptionFallback")
1462 if [ -z "$count" ]; then
1463 rc=${KSFT_SKIP}
1464 elif [ "$count" != "$dss_corruption" ]; then
1465 rc=${KSFT_FAIL}
1466 print_check "$ns dss corruption fallback"
1467 fail_test "got $count dss corruption fallback[s] in $ns expected $dss_corruption"
1468 fi
1469
1470 count=$(mptcp_lib_get_counter ${!ns} "MPTcpExtSimultConnectFallback")
1471 if [ -z "$count" ]; then
1472 rc=${KSFT_SKIP}
1473 elif [ "$count" != "$simult_conn" ]; then
1474 rc=${KSFT_FAIL}
1475 print_check "$ns simult conn fallback"
1476 fail_test "got $count simult conn fallback[s] in $ns expected $simult_conn"
1477 fi
1478
1479 count=$(mptcp_lib_get_counter ${!ns} "MPTcpExtMPCapableFallbackACK")
1480 if [ -z "$count" ]; then
1481 rc=${KSFT_SKIP}
1482 elif [ "$count" != "$mpc_passive" ]; then
1483 rc=${KSFT_FAIL}
1484 print_check "$ns mpc passive fallback"
1485 fail_test "got $count mpc passive fallback[s] in $ns expected $mpc_passive"
1486 fi
1487
1488 count=$(mptcp_lib_get_counter ${!ns} "MPTcpExtMPCapableFallbackSYNACK")
1489 if [ -z "$count" ]; then
1490 rc=${KSFT_SKIP}
1491 elif [ "$count" != "$mpc_active" ]; then
1492 rc=${KSFT_FAIL}
1493 print_check "$ns mpc active fallback"
1494 fail_test "got $count mpc active fallback[s] in $ns expected $mpc_active"
1495 fi
1496
1497 count=$(mptcp_lib_get_counter ${!ns} "MPTcpExtMPCapableDataFallback")
1498 if [ -z "$count" ]; then
1499 rc=${KSFT_SKIP}
1500 elif [ "$count" != "$mpc_data" ]; then
1501 rc=${KSFT_FAIL}
1502 print_check "$ns mpc data fallback"
1503 fail_test "got $count mpc data fallback[s] in $ns expected $mpc_data"
1504 fi
1505
1506 count=$(mptcp_lib_get_counter ${!ns} "MPTcpExtMD5SigFallback")
1507 if [ -z "$count" ]; then
1508 rc=${KSFT_SKIP}
1509 elif [ "$count" != "$md5_sig" ]; then
1510 rc=${KSFT_FAIL}
1511 print_check "$ns MD5 Sig fallback"
1512 fail_test "got $count MD5 Sig fallback[s] in $ns expected $md5_sig"
1513 fi
1514
1515 count=$(mptcp_lib_get_counter ${!ns} "MPTcpExtDssFallback")
1516 if [ -z "$count" ]; then
1517 rc=${KSFT_SKIP}
1518 elif [ "$count" != "$dss" ]; then
1519 rc=${KSFT_FAIL}
1520 print_check "$ns dss fallback"
1521 fail_test "got $count dss fallback[s] in $ns expected $dss"
1522 fi
1523
1524 return $rc
1525}
1526
1527chk_fallback_nr_all()
1528{
1529 local netns=("ns1" "ns2")
1530 local fb_ns=("fb_ns1" "fb_ns2")
1531 local rc=${KSFT_PASS}
1532
1533 for i in 0 1; do
1534 if [ -n "${!fb_ns[i]}" ]; then
1535 eval "${!fb_ns[i]}" \
1536 chk_fallback_nr ${netns[i]} || rc=${?}
1537 else
1538 chk_fallback_nr ${netns[i]} || rc=${?}
1539 fi
1540 done
1541
1542 if [ "${rc}" != "${KSFT_PASS}" ]; then
1543 print_results "fallback" ${rc}
1544 fi
1545}
1546
1547chk_join_nr()
1548{
1549 local syn_nr=$1
1550 local syn_ack_nr=$2
1551 local ack_nr=$3
1552 local syn_rej=${join_syn_rej:-0}
1553 local csum_ns1=${join_csum_ns1:-0}
1554 local csum_ns2=${join_csum_ns2:-0}
1555 local fail_nr=${join_fail_nr:-0}
1556 local rst_nr=${join_rst_nr:-0}
1557 local infi_nr=${join_infi_nr:-0}
1558 local corrupted_pkts=${join_corrupted_pkts:-0}
1559 local rc=${KSFT_PASS}
1560 local count
1561 local with_cookie
1562
1563 if [ "${corrupted_pkts}" -gt 0 ]; then
1564 print_info "${corrupted_pkts} corrupted pkts"
1565 fi
1566
1567 count=$(mptcp_lib_get_counter ${ns1} "MPTcpExtMPJoinSynRx")
1568 if [ -z "$count" ]; then
1569 rc=${KSFT_SKIP}
1570 elif [ "$count" != "$syn_nr" ]; then
1571 rc=${KSFT_FAIL}
1572 print_check "syn rx"
1573 fail_test "got $count JOIN[s] syn rx expected $syn_nr"
1574 fi
1575
1576 with_cookie=$(ip netns exec $ns2 sysctl -n net.ipv4.tcp_syncookies)
1577 count=$(mptcp_lib_get_counter ${ns2} "MPTcpExtMPJoinSynAckRx")
1578 if [ -z "$count" ]; then
1579 rc=${KSFT_SKIP}
1580 elif [ "$count" != "$syn_ack_nr" ]; then
1581 # simult connections exceeding the limit with cookie enabled could go up to
1582 # synack validation as the conn limit can be enforced reliably only after
1583 # the subflow creation
1584 if [ "$with_cookie" != 2 ] || [ "$count" -le "$syn_ack_nr" ] || [ "$count" -gt "$syn_nr" ]; then
1585 rc=${KSFT_FAIL}
1586 print_check "synack rx"
1587 fail_test "got $count JOIN[s] synack rx expected $syn_ack_nr"
1588 fi
1589 fi
1590
1591 count=$(mptcp_lib_get_counter ${ns2} "MPTcpExtMPJoinSynAckHMacFailure")
1592 if [ -z "$count" ]; then
1593 rc=${KSFT_SKIP}
1594 elif [ "$count" != "0" ]; then
1595 rc=${KSFT_FAIL}
1596 print_check "synack HMAC"
1597 fail_test "got $count JOIN[s] synack HMAC failure expected 0"
1598 fi
1599
1600 count=$(mptcp_lib_get_counter ${ns1} "MPTcpExtMPJoinAckRx")
1601 if [ -z "$count" ]; then
1602 rc=${KSFT_SKIP}
1603 elif [ "$count" != "$ack_nr" ]; then
1604 rc=${KSFT_FAIL}
1605 print_check "ack rx"
1606 fail_test "got $count JOIN[s] ack rx expected $ack_nr"
1607 fi
1608
1609 count=$(mptcp_lib_get_counter ${ns1} "MPTcpExtMPJoinAckHMacFailure")
1610 if [ -z "$count" ]; then
1611 rc=${KSFT_SKIP}
1612 elif [ "$count" != "0" ]; then
1613 rc=${KSFT_FAIL}
1614 print_check "ack HMAC"
1615 fail_test "got $count JOIN[s] ack HMAC failure expected 0"
1616 fi
1617
1618 count=$(mptcp_lib_get_counter ${ns1} "MPTcpExtMPJoinRejected")
1619 if [ -z "$count" ]; then
1620 rc=${KSFT_SKIP}
1621 elif [ "$count" != "$syn_rej" ]; then
1622 rc=${KSFT_FAIL}
1623 print_check "syn rejected"
1624 fail_test "got $count JOIN[s] syn rejected expected $syn_rej"
1625 fi
1626
1627 print_results "join Rx" ${rc}
1628
1629 join_syn_tx="${join_syn_tx:-${syn_nr}}" \
1630 chk_join_tx_nr
1631
1632 chk_fallback_nr_all
1633
1634 if $validate_checksum; then
1635 chk_csum_nr $csum_ns1 $csum_ns2
1636 chk_fail_nr $fail_nr $fail_nr
1637 chk_rst_nr $rst_nr $rst_nr
1638 chk_infi_nr $infi_nr $infi_nr
1639 fi
1640}
1641
1642# a negative value for 'stale_max' means no upper bound:
1643# for bidirectional transfer, if one peer sleep for a while
1644# - as these tests do - we can have a quite high number of
1645# stale/recover conversions, proportional to
1646# sleep duration/ MPTCP-level RTX interval.
1647chk_stale_nr()
1648{
1649 local ns=$1
1650 local stale_min=$2
1651 local stale_max=$3
1652 local stale_delta=$4
1653 local dump_stats
1654 local stale_nr
1655 local recover_nr
1656
1657 print_check "stale"
1658
1659 stale_nr=$(mptcp_lib_get_counter ${ns} "MPTcpExtSubflowStale")
1660 recover_nr=$(mptcp_lib_get_counter ${ns} "MPTcpExtSubflowRecover")
1661 if [ -z "$stale_nr" ] || [ -z "$recover_nr" ]; then
1662 print_skip
1663 elif [ $stale_nr -lt $stale_min ] ||
1664 { [ $stale_max -gt 0 ] && [ $stale_nr -gt $stale_max ]; } ||
1665 [ $((stale_nr - recover_nr)) -ne $stale_delta ]; then
1666 fail_test "got $stale_nr stale[s] $recover_nr recover[s], " \
1667 " expected stale in range [$stale_min..$stale_max]," \
1668 " stale-recover delta $stale_delta"
1669 dump_stats=1
1670 else
1671 print_ok
1672 fi
1673
1674 if [ "${dump_stats}" = 1 ]; then
1675 echo $ns stats
1676 ip netns exec $ns ip -s link show
1677 ip netns exec $ns nstat -as | grep MPTcp
1678 fi
1679}
1680
1681chk_add_nr()
1682{
1683 local add_nr=$1
1684 local echo_nr=$2
1685 local port_nr=${3:-0}
1686 local ns_invert=${4:-""}
1687 local syn_nr=$port_nr
1688 local syn_ack_nr=$port_nr
1689 local ack_nr=$port_nr
1690 local mis_syn_nr=0
1691 local mis_ack_nr=0
1692 local ns_tx=$ns1
1693 local ns_rx=$ns2
1694 local tx=""
1695 local rx=""
1696 local count
1697
1698 if [[ $ns_invert = "invert" ]]; then
1699 ns_tx=$ns2
1700 ns_rx=$ns1
1701 tx=" client"
1702 rx=" server"
1703 fi
1704
1705 print_check "add addr rx${rx}"
1706 count=$(mptcp_lib_get_counter ${ns_rx} "MPTcpExtAddAddr")
1707 if [ -z "$count" ]; then
1708 print_skip
1709 # Tolerate more ADD_ADDR then expected (if any), due to retransmissions
1710 elif [ "$count" != "$add_nr" ] &&
1711 { [ "$add_nr" -eq 0 ] || [ "$count" -lt "$add_nr" ]; }; then
1712 fail_test "got $count ADD_ADDR[s] expected $add_nr"
1713 else
1714 print_ok
1715 fi
1716
1717 print_check "add addr echo rx${tx}"
1718 count=$(mptcp_lib_get_counter ${ns_tx} "MPTcpExtEchoAdd")
1719 if [ -z "$count" ]; then
1720 print_skip
1721 elif [ "$count" != "$echo_nr" ]; then
1722 fail_test "got $count ADD_ADDR echo[s] expected $echo_nr"
1723 else
1724 print_ok
1725 fi
1726
1727 if [ $port_nr -gt 0 ]; then
1728 print_check "add addr rx with port${rx}"
1729 count=$(mptcp_lib_get_counter ${ns_rx} "MPTcpExtPortAdd")
1730 if [ -z "$count" ]; then
1731 print_skip
1732 elif [ "$count" != "$port_nr" ]; then
1733 fail_test "got $count ADD_ADDR[s] with a port-number expected $port_nr"
1734 else
1735 print_ok
1736 fi
1737
1738 print_check "syn rx port${tx}"
1739 count=$(mptcp_lib_get_counter ${ns_tx} "MPTcpExtMPJoinPortSynRx")
1740 if [ -z "$count" ]; then
1741 print_skip
1742 elif [ "$count" != "$syn_nr" ]; then
1743 fail_test "got $count JOIN[s] syn with a different \
1744 port-number expected $syn_nr"
1745 else
1746 print_ok
1747 fi
1748
1749 print_check "synack rx port${rx}"
1750 count=$(mptcp_lib_get_counter ${ns_rx} "MPTcpExtMPJoinPortSynAckRx")
1751 if [ -z "$count" ]; then
1752 print_skip
1753 elif [ "$count" != "$syn_ack_nr" ]; then
1754 fail_test "got $count JOIN[s] synack with a different \
1755 port-number expected $syn_ack_nr"
1756 else
1757 print_ok
1758 fi
1759
1760 print_check "ack rx port${tx}"
1761 count=$(mptcp_lib_get_counter ${ns_tx} "MPTcpExtMPJoinPortAckRx")
1762 if [ -z "$count" ]; then
1763 print_skip
1764 elif [ "$count" != "$ack_nr" ]; then
1765 fail_test "got $count JOIN[s] ack with a different \
1766 port-number expected $ack_nr"
1767 else
1768 print_ok
1769 fi
1770
1771 print_check "syn rx port mismatch${tx}"
1772 count=$(mptcp_lib_get_counter ${ns_tx} "MPTcpExtMismatchPortSynRx")
1773 if [ -z "$count" ]; then
1774 print_skip
1775 elif [ "$count" != "$mis_syn_nr" ]; then
1776 fail_test "got $count JOIN[s] syn with a mismatched \
1777 port-number expected $mis_syn_nr"
1778 else
1779 print_ok
1780 fi
1781
1782 print_check "ack rx port mismatch${tx}"
1783 count=$(mptcp_lib_get_counter ${ns_tx} "MPTcpExtMismatchPortAckRx")
1784 if [ -z "$count" ]; then
1785 print_skip
1786 elif [ "$count" != "$mis_ack_nr" ]; then
1787 fail_test "got $count JOIN[s] ack with a mismatched \
1788 port-number expected $mis_ack_nr"
1789 else
1790 print_ok
1791 fi
1792 fi
1793}
1794
1795chk_add_tx_nr()
1796{
1797 local add_tx_nr=$1
1798 local echo_tx_nr=$2
1799 local count
1800
1801 print_check "add addr tx"
1802 count=$(mptcp_lib_get_counter ${ns1} "MPTcpExtAddAddrTx")
1803 if [ -z "$count" ]; then
1804 print_skip
1805 # Tolerate more ADD_ADDR then expected (if any), due to retransmissions
1806 elif [ "$count" != "$add_tx_nr" ] &&
1807 { [ "$add_tx_nr" -eq 0 ] || [ "$count" -lt "$add_tx_nr" ]; }; then
1808 fail_test "got $count ADD_ADDR[s] TX, expected $add_tx_nr"
1809 else
1810 print_ok
1811 fi
1812
1813 print_check "add addr echo tx"
1814 count=$(mptcp_lib_get_counter ${ns2} "MPTcpExtEchoAddTx")
1815 if [ -z "$count" ]; then
1816 print_skip
1817 elif [ "$count" != "$echo_tx_nr" ]; then
1818 fail_test "got $count ADD_ADDR echo[s] TX, expected $echo_tx_nr"
1819 else
1820 print_ok
1821 fi
1822}
1823
1824chk_rm_nr()
1825{
1826 local rm_addr_nr=$1
1827 local rm_subflow_nr=$2
1828 local invert
1829 local simult
1830 local count
1831 local addr_ns=$ns1
1832 local subflow_ns=$ns2
1833 local addr="server"
1834 local subflow="client"
1835 local extra_msg=""
1836
1837 shift 2
1838 while [ -n "$1" ]; do
1839 [ "$1" = "invert" ] && invert=true
1840 [ "$1" = "simult" ] && simult=true
1841 shift
1842 done
1843
1844 if [ "$invert" = "true" ]; then
1845 addr_ns=$ns2
1846 subflow_ns=$ns1
1847 addr="client"
1848 subflow="server"
1849 fi
1850
1851 print_check "rm addr rx ${addr}"
1852 count=$(mptcp_lib_get_counter ${addr_ns} "MPTcpExtRmAddr")
1853 if [ -z "$count" ]; then
1854 print_skip
1855 elif [ "$count" != "$rm_addr_nr" ]; then
1856 fail_test "got $count RM_ADDR[s] expected $rm_addr_nr"
1857 else
1858 print_ok
1859 fi
1860
1861 print_check "rm subflow ${subflow}"
1862 count=$(mptcp_lib_get_counter ${subflow_ns} "MPTcpExtRmSubflow")
1863 if [ -z "$count" ]; then
1864 print_skip
1865 elif [ -n "$simult" ]; then
1866 local cnt suffix
1867
1868 cnt=$(mptcp_lib_get_counter ${addr_ns} "MPTcpExtRmSubflow")
1869
1870 # in case of simult flush, the subflow removal count on each side is
1871 # unreliable
1872 count=$((count + cnt))
1873 if [ "$count" != "$rm_subflow_nr" ]; then
1874 suffix="$count in [$rm_subflow_nr:$((rm_subflow_nr*2))]"
1875 extra_msg="simult"
1876 fi
1877 if [ $count -ge "$rm_subflow_nr" ] && \
1878 [ "$count" -le "$((rm_subflow_nr *2 ))" ]; then
1879 print_ok "$suffix"
1880 else
1881 fail_test "got $count RM_SUBFLOW[s] expected in range [$rm_subflow_nr:$((rm_subflow_nr*2))]"
1882 fi
1883 elif [ "$count" != "$rm_subflow_nr" ]; then
1884 fail_test "got $count RM_SUBFLOW[s] expected $rm_subflow_nr"
1885 else
1886 print_ok
1887 fi
1888
1889 print_info "$extra_msg"
1890}
1891
1892chk_rm_tx_nr()
1893{
1894 local rm_addr_tx_nr=$1
1895
1896 print_check "rm addr tx client"
1897 count=$(mptcp_lib_get_counter ${ns2} "MPTcpExtRmAddrTx")
1898 if [ -z "$count" ]; then
1899 print_skip
1900 elif [ "$count" != "$rm_addr_tx_nr" ]; then
1901 fail_test "got $count RM_ADDR[s] expected $rm_addr_tx_nr"
1902 else
1903 print_ok
1904 fi
1905}
1906
1907chk_prio_nr()
1908{
1909 local mp_prio_nr_tx=$1
1910 local mp_prio_nr_rx=$2
1911 local mpj_syn=$3
1912 local mpj_syn_ack=$4
1913 local count
1914
1915 print_check "mp_prio tx server"
1916 count=$(mptcp_lib_get_counter ${ns1} "MPTcpExtMPPrioTx")
1917 if [ -z "$count" ]; then
1918 print_skip
1919 elif [ "$count" != "$mp_prio_nr_tx" ]; then
1920 fail_test "got $count MP_PRIO[s] TX expected $mp_prio_nr_tx"
1921 else
1922 print_ok
1923 fi
1924
1925 print_check "mp_prio rx client"
1926 count=$(mptcp_lib_get_counter ${ns1} "MPTcpExtMPPrioRx")
1927 if [ -z "$count" ]; then
1928 print_skip
1929 elif [ "$count" != "$mp_prio_nr_rx" ]; then
1930 fail_test "got $count MP_PRIO[s] RX expected $mp_prio_nr_rx"
1931 else
1932 print_ok
1933 fi
1934
1935 print_check "syn backup"
1936 count=$(mptcp_lib_get_counter ${ns1} "MPTcpExtMPJoinSynBackupRx")
1937 if [ -z "$count" ]; then
1938 print_skip
1939 elif [ "$count" != "$mpj_syn" ]; then
1940 fail_test "got $count JOIN[s] syn with Backup expected $mpj_syn"
1941 else
1942 print_ok
1943 fi
1944
1945 print_check "synack backup"
1946 count=$(mptcp_lib_get_counter ${ns2} "MPTcpExtMPJoinSynAckBackupRx")
1947 if [ -z "$count" ]; then
1948 print_skip
1949 elif [ "$count" != "$mpj_syn_ack" ]; then
1950 fail_test "got $count JOIN[s] synack with Backup expected $mpj_syn_ack"
1951 else
1952 print_ok
1953 fi
1954}
1955
1956chk_subflow_nr()
1957{
1958 local msg="$1"
1959 local subflow_nr=$2
1960 local cnt1
1961 local cnt2
1962 local dump_stats
1963
1964 print_check "${msg}"
1965
1966 cnt1=$(ss -N $ns1 -tOni | grep -c token)
1967 cnt2=$(ss -N $ns2 -tOni | grep -c token)
1968 if [ "$cnt1" != "$subflow_nr" ] || [ "$cnt2" != "$subflow_nr" ]; then
1969 fail_test "got $cnt1:$cnt2 subflows expected $subflow_nr"
1970 dump_stats=1
1971 else
1972 print_ok
1973 fi
1974
1975 if [ "${dump_stats}" = 1 ]; then
1976 ss -N $ns1 -tOni
1977 ss -N $ns1 -tOni | grep token
1978 ip -n $ns1 mptcp endpoint
1979 fi
1980}
1981
1982chk_mptcp_info()
1983{
1984 local info1=$1
1985 local exp1=$2
1986 local info2=$3
1987 local exp2=$4
1988 local cnt1
1989 local cnt2
1990 local dump_stats
1991
1992 print_check "mptcp_info ${info1:0:15}=$exp1:$exp2"
1993
1994 cnt1=$(ss -N $ns1 -inmHM | mptcp_lib_get_info_value "$info1" "$info1")
1995 cnt2=$(ss -N $ns2 -inmHM | mptcp_lib_get_info_value "$info2" "$info2")
1996 # 'ss' only display active connections and counters that are not 0.
1997 [ -z "$cnt1" ] && cnt1=0
1998 [ -z "$cnt2" ] && cnt2=0
1999
2000 if [ "$cnt1" != "$exp1" ] || [ "$cnt2" != "$exp2" ]; then
2001 fail_test "got $cnt1:$cnt2 $info1:$info2 expected $exp1:$exp2"
2002 dump_stats=1
2003 else
2004 print_ok
2005 fi
2006
2007 if [ "$dump_stats" = 1 ]; then
2008 ss -N $ns1 -inmHM
2009 ss -N $ns2 -inmHM
2010 fi
2011}
2012
2013# $1: subflows in ns1 ; $2: subflows in ns2
2014# number of all subflows, including the initial subflow.
2015chk_subflows_total()
2016{
2017 local cnt1
2018 local cnt2
2019 local info="subflows_total"
2020 local dump_stats
2021
2022 # if subflows_total counter is supported, use it:
2023 if [ -n "$(ss -N $ns1 -inmHM | mptcp_lib_get_info_value $info $info)" ]; then
2024 chk_mptcp_info $info $1 $info $2
2025 return
2026 fi
2027
2028 print_check "$info $1:$2"
2029
2030 # if not, count the TCP connections that are in fact MPTCP subflows
2031 cnt1=$(ss -N $ns1 -ti state established state syn-sent state syn-recv |
2032 grep -c tcp-ulp-mptcp)
2033 cnt2=$(ss -N $ns2 -ti state established state syn-sent state syn-recv |
2034 grep -c tcp-ulp-mptcp)
2035
2036 if [ "$1" != "$cnt1" ] || [ "$2" != "$cnt2" ]; then
2037 fail_test "got subflows $cnt1:$cnt2 expected $1:$2"
2038 dump_stats=1
2039 else
2040 print_ok
2041 fi
2042
2043 if [ "$dump_stats" = 1 ]; then
2044 ss -N $ns1 -ti
2045 ss -N $ns2 -ti
2046 fi
2047}
2048
2049chk_link_usage()
2050{
2051 local ns=$1
2052 local link=$2
2053 local out=$3
2054 local expected_rate=$4
2055
2056 local tx_link tx_total
2057 tx_link=$(ip netns exec $ns cat /sys/class/net/$link/statistics/tx_bytes)
2058 tx_total=$(stat --format=%s $out)
2059 local tx_rate=$((tx_link * 100 / tx_total))
2060 local tolerance=5
2061
2062 print_check "link usage"
2063 if [ $tx_rate -lt $((expected_rate - tolerance)) ] || \
2064 [ $tx_rate -gt $((expected_rate + tolerance)) ]; then
2065 fail_test "got $tx_rate% usage, expected $expected_rate%"
2066 else
2067 print_ok
2068 fi
2069}
2070
2071wait_attempt_fail()
2072{
2073 local timeout_ms=$((timeout_poll * 1000))
2074 local time=0
2075 local ns=$1
2076
2077 while [ $time -lt $timeout_ms ]; do
2078 local cnt
2079
2080 cnt=$(mptcp_lib_get_counter ${ns} "TcpAttemptFails")
2081
2082 [ "$cnt" = 1 ] && return 1
2083 time=$((time + 100))
2084 sleep 0.1
2085 done
2086 return 1
2087}
2088
2089set_userspace_pm()
2090{
2091 local ns=$1
2092
2093 ip netns exec $ns sysctl -q net.mptcp.pm_type=1
2094}
2095
2096subflows_tests()
2097{
2098 if reset "no JOIN"; then
2099 run_tests $ns1 $ns2 10.0.1.1
2100 chk_join_nr 0 0 0
2101 fi
2102
2103 # subflow limited by client
2104 if reset "single subflow, limited by client"; then
2105 pm_nl_set_limits $ns1 0 0
2106 pm_nl_set_limits $ns2 0 0
2107 pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
2108 run_tests $ns1 $ns2 10.0.1.1
2109 chk_join_nr 0 0 0
2110 fi
2111
2112 # subflow limited by server
2113 if reset "single subflow, limited by server"; then
2114 pm_nl_set_limits $ns1 0 0
2115 pm_nl_set_limits $ns2 0 1
2116 pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
2117 run_tests $ns1 $ns2 10.0.1.1
2118 join_syn_rej=1 \
2119 chk_join_nr 1 1 0
2120 fi
2121
2122 # subflow
2123 if reset "single subflow"; then
2124 pm_nl_set_limits $ns1 0 1
2125 pm_nl_set_limits $ns2 0 1
2126 pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
2127 run_tests $ns1 $ns2 10.0.1.1
2128 chk_join_nr 1 1 1
2129 fi
2130
2131 # multiple subflows
2132 if reset "multiple subflows"; then
2133 pm_nl_set_limits $ns1 0 2
2134 pm_nl_set_limits $ns2 0 2
2135 pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
2136 pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow
2137 run_tests $ns1 $ns2 10.0.1.1
2138 chk_join_nr 2 2 2
2139 fi
2140
2141 # multiple subflows limited by server
2142 if reset "multiple subflows, limited by server"; then
2143 pm_nl_set_limits $ns1 0 1
2144 pm_nl_set_limits $ns2 0 2
2145 pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
2146 pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow
2147 run_tests $ns1 $ns2 10.0.1.1
2148 join_syn_rej=1 \
2149 chk_join_nr 2 2 1
2150 fi
2151
2152 # single subflow, dev
2153 if reset "single subflow, dev"; then
2154 pm_nl_set_limits $ns1 0 1
2155 pm_nl_set_limits $ns2 0 1
2156 pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow dev ns2eth3
2157 run_tests $ns1 $ns2 10.0.1.1
2158 chk_join_nr 1 1 1
2159 fi
2160}
2161
2162subflows_error_tests()
2163{
2164 # If a single subflow is configured, and matches the MPC src
2165 # address, no additional subflow should be created
2166 if reset "no MPC reuse with single endpoint"; then
2167 pm_nl_set_limits $ns1 0 1
2168 pm_nl_set_limits $ns2 0 1
2169 pm_nl_add_endpoint $ns2 10.0.1.2 flags subflow
2170 pm_nl_add_endpoint $ns2 10.0.12.2 flags subflow
2171 speed=slow \
2172 run_tests $ns1 $ns2 10.0.1.1
2173 join_bind_err=1 \
2174 chk_join_nr 0 0 0
2175 fi
2176
2177 # multiple subflows, with subflow creation error
2178 if reset_with_tcp_filter "multi subflows, with failing subflow" ns1 10.0.3.2 REJECT &&
2179 continue_if mptcp_lib_kallsyms_has "mptcp_pm_subflow_check_next$"; then
2180 pm_nl_set_limits $ns1 0 2
2181 pm_nl_set_limits $ns2 0 2
2182 pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
2183 pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow
2184 speed=slow \
2185 run_tests $ns1 $ns2 10.0.1.1
2186 join_syn_tx=2 \
2187 chk_join_nr 1 1 1
2188 fi
2189
2190 # multiple subflows, with subflow timeout on MPJ
2191 if reset_with_tcp_filter "multi subflows, with subflow timeout" ns1 10.0.3.2 DROP &&
2192 continue_if mptcp_lib_kallsyms_has "mptcp_pm_subflow_check_next$"; then
2193 pm_nl_set_limits $ns1 0 2
2194 pm_nl_set_limits $ns2 0 2
2195 pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
2196 pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow
2197 speed=slow \
2198 run_tests $ns1 $ns2 10.0.1.1
2199 join_syn_tx=2 \
2200 chk_join_nr 1 1 1
2201 fi
2202
2203 # multiple subflows, check that the endpoint corresponding to
2204 # closed subflow (due to reset) is not reused if additional
2205 # subflows are added later
2206 if reset_with_tcp_filter "multi subflows, fair usage on close" ns1 10.0.3.2 REJECT &&
2207 continue_if mptcp_lib_kallsyms_has "mptcp_pm_subflow_check_next$"; then
2208 pm_nl_set_limits $ns1 0 1
2209 pm_nl_set_limits $ns2 0 1
2210 pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
2211 speed=slow \
2212 run_tests $ns1 $ns2 10.0.1.1 &
2213
2214 # mpj subflow will be in TW after the reset
2215 wait_attempt_fail $ns2
2216 pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow
2217 wait
2218
2219 # additional subflow could be created only if the PM select
2220 # the later endpoint, skipping the already used one
2221 join_syn_tx=2 \
2222 chk_join_nr 1 1 1
2223 fi
2224}
2225
2226signal_address_tests()
2227{
2228 # add_address, unused
2229 if reset "unused signal address"; then
2230 pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
2231 run_tests $ns1 $ns2 10.0.1.1
2232 chk_join_nr 0 0 0
2233 chk_add_tx_nr 1 1
2234 chk_add_nr 1 1
2235 fi
2236
2237 # accept and use add_addr
2238 if reset "signal address"; then
2239 pm_nl_set_limits $ns1 0 1
2240 pm_nl_set_limits $ns2 1 1
2241 pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
2242 run_tests $ns1 $ns2 10.0.1.1
2243 chk_join_nr 1 1 1
2244 chk_add_nr 1 1
2245 fi
2246
2247 # accept and use add_addr with an additional subflow
2248 # note: signal address in server ns and local addresses in client ns must
2249 # belong to different subnets or one of the listed local address could be
2250 # used for 'add_addr' subflow
2251 if reset "subflow and signal"; then
2252 pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
2253 pm_nl_set_limits $ns1 0 2
2254 pm_nl_set_limits $ns2 1 2
2255 pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
2256 run_tests $ns1 $ns2 10.0.1.1
2257 chk_join_nr 2 2 2
2258 chk_add_nr 1 1
2259 fi
2260
2261 # uncommon: subflow and signal flags on the same endpoint
2262 # or because the user wrongly picked both, but still expects the client
2263 # to create additional subflows
2264 if reset "subflow and signal together"; then
2265 pm_nl_set_limits $ns1 0 2
2266 pm_nl_set_limits $ns2 0 2
2267 pm_nl_add_endpoint $ns2 10.0.3.2 flags signal,subflow
2268 run_tests $ns1 $ns2 10.0.1.1
2269 chk_join_nr 1 1 1
2270 chk_add_nr 1 1 0 invert # only initiated by ns2
2271 chk_add_nr 0 0 0 # none initiated by ns1
2272 chk_rst_nr 0 0 invert # no RST sent by the client
2273 chk_rst_nr 0 0 # no RST sent by the server
2274 fi
2275
2276 # accept and use add_addr with additional subflows
2277 if reset "multiple subflows and signal"; then
2278 pm_nl_set_limits $ns1 0 3
2279 pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
2280 pm_nl_set_limits $ns2 1 3
2281 pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
2282 pm_nl_add_endpoint $ns2 10.0.4.2 flags subflow
2283 run_tests $ns1 $ns2 10.0.1.1
2284 chk_join_nr 3 3 3
2285 chk_add_nr 1 1
2286 fi
2287
2288 # signal addresses
2289 if reset "signal addresses"; then
2290 pm_nl_set_limits $ns1 3 3
2291 pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
2292 pm_nl_add_endpoint $ns1 10.0.3.1 flags signal
2293 pm_nl_add_endpoint $ns1 10.0.4.1 flags signal
2294 pm_nl_set_limits $ns2 3 3
2295 speed=slow \
2296 run_tests $ns1 $ns2 10.0.1.1
2297 chk_join_nr 3 3 3
2298 chk_add_nr 3 3
2299 fi
2300
2301 # signal invalid addresses
2302 if reset "signal invalid addresses"; then
2303 pm_nl_set_limits $ns1 3 3
2304 pm_nl_add_endpoint $ns1 10.0.12.1 flags signal
2305 pm_nl_add_endpoint $ns1 10.0.3.1 flags signal
2306 pm_nl_add_endpoint $ns1 10.0.14.1 flags signal
2307 pm_nl_set_limits $ns2 3 3
2308 speed=slow \
2309 run_tests $ns1 $ns2 10.0.1.1
2310 join_syn_tx=3 \
2311 chk_join_nr 1 1 1
2312 chk_add_nr 3 3
2313 fi
2314
2315 # signal addresses race test
2316 if reset "signal addresses race test"; then
2317 pm_nl_set_limits $ns1 4 4
2318 pm_nl_set_limits $ns2 4 4
2319 pm_nl_add_endpoint $ns1 10.0.1.1 flags signal
2320 pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
2321 pm_nl_add_endpoint $ns1 10.0.3.1 flags signal
2322 pm_nl_add_endpoint $ns1 10.0.4.1 flags signal
2323 pm_nl_add_endpoint $ns2 10.0.1.2 flags signal
2324 pm_nl_add_endpoint $ns2 10.0.2.2 flags signal
2325 pm_nl_add_endpoint $ns2 10.0.3.2 flags signal
2326 pm_nl_add_endpoint $ns2 10.0.4.2 flags signal
2327
2328 # the peer could possibly miss some addr notification, allow retransmission
2329 ip netns exec $ns1 sysctl -q net.mptcp.add_addr_timeout=1
2330 speed=slow \
2331 run_tests $ns1 $ns2 10.0.1.1
2332 chk_join_nr 3 3 3
2333
2334 # It is not directly linked to the commit introducing this
2335 # symbol but for the parent one which is linked anyway.
2336 if mptcp_lib_kallsyms_has "mptcp_pm_subflow_check_next$"; then
2337 # the server will not signal the address terminating
2338 # the MPC subflow
2339 chk_add_nr 3 3
2340 else
2341 chk_add_nr 4 4
2342 fi
2343 fi
2344}
2345
2346laminar_endp_tests()
2347{
2348 # no laminar endpoints: routing rules are used
2349 if reset_with_tcp_filter "without a laminar endpoint" ns1 10.0.2.2 REJECT &&
2350 continue_if mptcp_lib_kallsyms_has "mptcp_pm_get_endp_laminar_max$"; then
2351 pm_nl_set_limits $ns1 0 2
2352 pm_nl_set_limits $ns2 2 2
2353 pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
2354 run_tests $ns1 $ns2 10.0.1.1
2355 join_syn_tx=1 \
2356 chk_join_nr 0 0 0
2357 chk_add_nr 1 1
2358 fi
2359
2360 # laminar endpoints: this endpoint is used
2361 if reset_with_tcp_filter "with a laminar endpoint" ns1 10.0.2.2 REJECT &&
2362 continue_if mptcp_lib_kallsyms_has "mptcp_pm_get_endp_laminar_max$"; then
2363 pm_nl_set_limits $ns1 0 2
2364 pm_nl_set_limits $ns2 2 2
2365 pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
2366 pm_nl_add_endpoint $ns2 10.0.3.2 flags laminar
2367 run_tests $ns1 $ns2 10.0.1.1
2368 chk_join_nr 1 1 1
2369 chk_add_nr 1 1
2370 fi
2371
2372 # laminar endpoints: these endpoints are used
2373 if reset_with_tcp_filter "with multiple laminar endpoints" ns1 10.0.2.2 REJECT &&
2374 continue_if mptcp_lib_kallsyms_has "mptcp_pm_get_endp_laminar_max$"; then
2375 pm_nl_set_limits $ns1 0 2
2376 pm_nl_set_limits $ns2 2 2
2377 pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
2378 pm_nl_add_endpoint $ns1 10.0.3.1 flags signal
2379 pm_nl_add_endpoint $ns2 dead:beef:3::2 flags laminar
2380 pm_nl_add_endpoint $ns2 10.0.3.2 flags laminar
2381 pm_nl_add_endpoint $ns2 10.0.4.2 flags laminar
2382 run_tests $ns1 $ns2 10.0.1.1
2383 chk_join_nr 2 2 2
2384 chk_add_nr 2 2
2385 fi
2386
2387 # laminar endpoints: only one endpoint is used
2388 if reset_with_tcp_filter "single laminar endpoint" ns1 10.0.2.2 REJECT &&
2389 continue_if mptcp_lib_kallsyms_has "mptcp_pm_get_endp_laminar_max$"; then
2390 pm_nl_set_limits $ns1 0 2
2391 pm_nl_set_limits $ns2 2 2
2392 pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
2393 pm_nl_add_endpoint $ns1 10.0.3.1 flags signal
2394 pm_nl_add_endpoint $ns2 10.0.3.2 flags laminar
2395 run_tests $ns1 $ns2 10.0.1.1
2396 chk_join_nr 1 1 1
2397 chk_add_nr 2 2
2398 fi
2399
2400 # laminar endpoints: subflow and laminar flags
2401 if reset_with_tcp_filter "sublow + laminar endpoints" ns1 10.0.2.2 REJECT &&
2402 continue_if mptcp_lib_kallsyms_has "mptcp_pm_get_endp_laminar_max$"; then
2403 pm_nl_set_limits $ns1 0 4
2404 pm_nl_set_limits $ns2 2 4
2405 pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
2406 pm_nl_add_endpoint $ns2 10.0.1.2 flags subflow,laminar
2407 pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow,laminar
2408 run_tests $ns1 $ns2 10.0.1.1
2409 chk_join_nr 1 1 1
2410 chk_add_nr 1 1
2411 fi
2412}
2413
2414link_failure_tests()
2415{
2416 # accept and use add_addr with additional subflows and link loss
2417 if reset "multiple flows, signal, link failure"; then
2418 # without any b/w limit each veth could spool the packets and get
2419 # them acked at xmit time, so that the corresponding subflow will
2420 # have almost always no outstanding pkts, the scheduler will pick
2421 # always the first subflow and we will have hard time testing
2422 # active backup and link switch-over.
2423 # Let's set some arbitrary (low) virtual link limits.
2424 init_shapers
2425 pm_nl_set_limits $ns1 0 3
2426 pm_nl_add_endpoint $ns1 10.0.2.1 dev ns1eth2 flags signal
2427 pm_nl_set_limits $ns2 1 3
2428 pm_nl_add_endpoint $ns2 10.0.3.2 dev ns2eth3 flags subflow
2429 pm_nl_add_endpoint $ns2 10.0.4.2 dev ns2eth4 flags subflow
2430 test_linkfail=1 \
2431 run_tests $ns1 $ns2 10.0.1.1
2432 chk_join_nr 3 3 3
2433 chk_add_nr 1 1
2434 chk_stale_nr $ns2 1 5 1
2435 fi
2436
2437 # accept and use add_addr with additional subflows and link loss
2438 # for bidirectional transfer
2439 if reset "multi flows, signal, bidi, link fail"; then
2440 init_shapers
2441 pm_nl_set_limits $ns1 0 3
2442 pm_nl_add_endpoint $ns1 10.0.2.1 dev ns1eth2 flags signal
2443 pm_nl_set_limits $ns2 1 3
2444 pm_nl_add_endpoint $ns2 10.0.3.2 dev ns2eth3 flags subflow
2445 pm_nl_add_endpoint $ns2 10.0.4.2 dev ns2eth4 flags subflow
2446 test_linkfail=2 \
2447 run_tests $ns1 $ns2 10.0.1.1
2448 chk_join_nr 3 3 3
2449 chk_add_nr 1 1
2450 chk_stale_nr $ns2 1 -1 1
2451 fi
2452
2453 # 2 subflows plus 1 backup subflow with a lossy link, backup
2454 # will never be used
2455 if reset "backup subflow unused, link failure"; then
2456 init_shapers
2457 pm_nl_set_limits $ns1 0 2
2458 pm_nl_add_endpoint $ns1 10.0.2.1 dev ns1eth2 flags signal
2459 pm_nl_set_limits $ns2 1 2
2460 pm_nl_add_endpoint $ns2 10.0.3.2 dev ns2eth3 flags subflow,backup
2461 FAILING_LINKS="1" test_linkfail=1 \
2462 run_tests $ns1 $ns2 10.0.1.1
2463 chk_join_nr 2 2 2
2464 chk_add_nr 1 1
2465 chk_link_usage $ns2 ns2eth3 $cinsent 0
2466 fi
2467
2468 # 2 lossy links after half transfer, backup will get half of
2469 # the traffic
2470 if reset "backup flow used, multi links fail"; then
2471 init_shapers
2472 pm_nl_set_limits $ns1 0 2
2473 pm_nl_add_endpoint $ns1 10.0.2.1 dev ns1eth2 flags signal
2474 pm_nl_set_limits $ns2 1 2
2475 pm_nl_add_endpoint $ns2 10.0.3.2 dev ns2eth3 flags subflow,backup
2476 FAILING_LINKS="1 2" test_linkfail=1 \
2477 run_tests $ns1 $ns2 10.0.1.1
2478 chk_join_nr 2 2 2
2479 chk_add_nr 1 1
2480 chk_stale_nr $ns2 2 4 2
2481 chk_link_usage $ns2 ns2eth3 $cinsent 50
2482 fi
2483
2484 # use a backup subflow with the first subflow on a lossy link
2485 # for bidirectional transfer
2486 if reset "backup flow used, bidi, link failure"; then
2487 init_shapers
2488 pm_nl_set_limits $ns1 0 2
2489 pm_nl_add_endpoint $ns1 10.0.2.1 dev ns1eth2 flags signal
2490 pm_nl_set_limits $ns2 1 3
2491 pm_nl_add_endpoint $ns2 10.0.3.2 dev ns2eth3 flags subflow,backup
2492 FAILING_LINKS="1 2" test_linkfail=2 \
2493 run_tests $ns1 $ns2 10.0.1.1
2494 chk_join_nr 2 2 2
2495 chk_add_nr 1 1
2496 chk_stale_nr $ns2 1 -1 2
2497 chk_link_usage $ns2 ns2eth3 $cinsent 50
2498 fi
2499}
2500
2501add_addr_timeout_tests()
2502{
2503 # add_addr timeout
2504 if reset_with_add_addr_timeout "signal address, ADD_ADDR timeout"; then
2505 pm_nl_set_limits $ns1 0 1
2506 pm_nl_set_limits $ns2 1 1
2507 pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
2508 speed=slow \
2509 run_tests $ns1 $ns2 10.0.1.1
2510 chk_join_nr 1 1 1
2511 chk_add_tx_nr 4 4
2512 chk_add_nr 4 0
2513 fi
2514
2515 # add_addr timeout IPv6
2516 if reset_with_add_addr_timeout "signal address, ADD_ADDR6 timeout" 6; then
2517 pm_nl_set_limits $ns1 0 1
2518 pm_nl_set_limits $ns2 1 1
2519 pm_nl_add_endpoint $ns1 dead:beef:2::1 flags signal
2520 speed=slow \
2521 run_tests $ns1 $ns2 dead:beef:1::1
2522 chk_join_nr 1 1 1
2523 chk_add_nr 4 0
2524 fi
2525
2526 # signal addresses timeout
2527 if reset_with_add_addr_timeout "signal addresses, ADD_ADDR timeout"; then
2528 pm_nl_set_limits $ns1 2 2
2529 pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
2530 pm_nl_add_endpoint $ns1 10.0.3.1 flags signal
2531 pm_nl_set_limits $ns2 2 2
2532 speed=10 \
2533 run_tests $ns1 $ns2 10.0.1.1
2534 chk_join_nr 2 2 2
2535 chk_add_nr 8 0
2536 fi
2537
2538 # signal invalid addresses timeout
2539 if reset_with_add_addr_timeout "invalid address, ADD_ADDR timeout"; then
2540 pm_nl_set_limits $ns1 2 2
2541 pm_nl_add_endpoint $ns1 10.0.12.1 flags signal
2542 pm_nl_add_endpoint $ns1 10.0.3.1 flags signal
2543 pm_nl_set_limits $ns2 2 2
2544 speed=10 \
2545 run_tests $ns1 $ns2 10.0.1.1
2546 join_syn_tx=2 \
2547 chk_join_nr 1 1 1
2548 chk_add_nr 8 0
2549 fi
2550}
2551
2552remove_tests()
2553{
2554 # single subflow, remove
2555 if reset "remove single subflow"; 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,backup
2559 addr_nr_ns2=-1 speed=slow \
2560 run_tests $ns1 $ns2 10.0.1.1
2561 chk_join_nr 1 1 1
2562 chk_rm_tx_nr 1
2563 chk_rm_nr 1 1
2564 chk_rst_nr 0 0
2565 fi
2566
2567 # multiple subflows, remove
2568 if reset "remove multiple subflows"; then
2569 pm_nl_set_limits $ns1 0 2
2570 pm_nl_set_limits $ns2 0 2
2571 pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow,backup
2572 pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow,backup
2573 addr_nr_ns2=-2 speed=slow \
2574 run_tests $ns1 $ns2 10.0.1.1
2575 chk_join_nr 2 2 2
2576 chk_rm_nr 2 2
2577 chk_rst_nr 0 0
2578 fi
2579
2580 # single address, remove
2581 if reset "remove single address"; then
2582 pm_nl_set_limits $ns1 0 1
2583 pm_nl_add_endpoint $ns1 10.0.2.1 flags signal,backup
2584 pm_nl_set_limits $ns2 1 1
2585 addr_nr_ns1=-1 speed=slow \
2586 run_tests $ns1 $ns2 10.0.1.1
2587 chk_join_nr 1 1 1
2588 chk_add_nr 1 1
2589 chk_rm_nr 1 1 invert
2590 chk_rst_nr 0 0
2591 fi
2592
2593 # subflow and signal, remove
2594 if reset "remove subflow and signal"; then
2595 pm_nl_set_limits $ns1 0 2
2596 pm_nl_add_endpoint $ns1 10.0.2.1 flags signal,backup
2597 pm_nl_set_limits $ns2 1 2
2598 pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow,backup
2599 addr_nr_ns1=-1 addr_nr_ns2=-1 speed=slow \
2600 run_tests $ns1 $ns2 10.0.1.1
2601 chk_join_nr 2 2 2
2602 chk_add_nr 1 1
2603 chk_rm_nr 1 1
2604 chk_rst_nr 0 0
2605 fi
2606
2607 # subflows and signal, remove
2608 if reset "remove subflows and signal"; then
2609 pm_nl_set_limits $ns1 0 3
2610 pm_nl_add_endpoint $ns1 10.0.2.1 flags signal,backup
2611 pm_nl_set_limits $ns2 1 3
2612 pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow,backup
2613 pm_nl_add_endpoint $ns2 10.0.4.2 flags subflow,backup
2614 addr_nr_ns1=-1 addr_nr_ns2=-2 speed=10 \
2615 run_tests $ns1 $ns2 10.0.1.1
2616 chk_join_nr 3 3 3
2617 chk_add_nr 1 1
2618 chk_rm_nr 2 2
2619 chk_rst_nr 0 0
2620 fi
2621
2622 # addresses remove
2623 if reset "remove addresses"; then
2624 pm_nl_set_limits $ns1 3 3
2625 pm_nl_add_endpoint $ns1 10.0.2.1 flags signal,backup id 250
2626 pm_nl_add_endpoint $ns1 10.0.3.1 flags signal,backup
2627 pm_nl_add_endpoint $ns1 10.0.4.1 flags signal,backup
2628 pm_nl_set_limits $ns2 3 3
2629 addr_nr_ns1=-3 speed=10 \
2630 run_tests $ns1 $ns2 10.0.1.1
2631 chk_join_nr 3 3 3
2632 chk_add_nr 3 3
2633 chk_rm_nr 3 3 invert
2634 chk_rst_nr 0 0
2635 fi
2636
2637 # invalid addresses remove
2638 if reset "remove invalid addresses"; then
2639 pm_nl_set_limits $ns1 3 3
2640 pm_nl_add_endpoint $ns1 10.0.12.1 flags signal,backup
2641 # broadcast IP: no packet for this address will be received on ns1
2642 pm_nl_add_endpoint $ns1 224.0.0.1 flags signal,backup
2643 pm_nl_add_endpoint $ns1 10.0.3.1 flags signal,backup
2644 pm_nl_set_limits $ns2 2 2
2645 addr_nr_ns1=-3 speed=10 \
2646 run_tests $ns1 $ns2 10.0.1.1
2647 join_syn_tx=2 join_connect_err=1 \
2648 chk_join_nr 1 1 1
2649 chk_add_nr 3 3
2650 chk_rm_nr 3 1 invert
2651 chk_rst_nr 0 0
2652 fi
2653
2654 # subflows and signal, flush
2655 if reset "flush subflows and signal"; then
2656 pm_nl_set_limits $ns1 0 3
2657 pm_nl_add_endpoint $ns1 10.0.2.1 flags signal,backup
2658 pm_nl_set_limits $ns2 1 3
2659 pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow,backup
2660 pm_nl_add_endpoint $ns2 10.0.4.2 flags subflow,backup
2661 addr_nr_ns1=-8 addr_nr_ns2=-8 speed=slow \
2662 run_tests $ns1 $ns2 10.0.1.1
2663 chk_join_nr 3 3 3
2664 chk_add_nr 1 1
2665 chk_rm_nr 1 3 invert simult
2666 chk_rst_nr 0 0
2667 fi
2668
2669 # subflows flush
2670 if reset "flush subflows"; then
2671 pm_nl_set_limits $ns1 3 3
2672 pm_nl_set_limits $ns2 3 3
2673 pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow,backup id 150
2674 pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow,backup
2675 pm_nl_add_endpoint $ns2 10.0.4.2 flags subflow,backup
2676 addr_nr_ns1=-8 addr_nr_ns2=-8 speed=slow \
2677 run_tests $ns1 $ns2 10.0.1.1
2678 chk_join_nr 3 3 3
2679
2680 if mptcp_lib_kversion_ge 5.18; then
2681 chk_rm_tx_nr 0
2682 chk_rm_nr 0 3 simult
2683 else
2684 chk_rm_nr 3 3
2685 fi
2686 chk_rst_nr 0 0
2687 fi
2688
2689 # addresses flush
2690 if reset "flush addresses"; then
2691 pm_nl_set_limits $ns1 3 3
2692 pm_nl_add_endpoint $ns1 10.0.2.1 flags signal,backup id 250
2693 pm_nl_add_endpoint $ns1 10.0.3.1 flags signal,backup
2694 pm_nl_add_endpoint $ns1 10.0.4.1 flags signal,backup
2695 pm_nl_set_limits $ns2 3 3
2696 addr_nr_ns1=-8 addr_nr_ns2=-8 speed=slow \
2697 run_tests $ns1 $ns2 10.0.1.1
2698 chk_join_nr 3 3 3
2699 chk_add_nr 3 3
2700 chk_rm_nr 3 3 invert simult
2701 chk_rst_nr 0 0
2702 fi
2703
2704 # invalid addresses flush
2705 if reset "flush invalid addresses"; then
2706 pm_nl_set_limits $ns1 3 3
2707 pm_nl_add_endpoint $ns1 10.0.12.1 flags signal,backup
2708 pm_nl_add_endpoint $ns1 10.0.3.1 flags signal,backup
2709 pm_nl_add_endpoint $ns1 10.0.14.1 flags signal,backup
2710 pm_nl_set_limits $ns2 3 3
2711 addr_nr_ns1=-8 speed=slow \
2712 run_tests $ns1 $ns2 10.0.1.1
2713 join_syn_tx=3 \
2714 chk_join_nr 1 1 1
2715 chk_add_nr 3 3
2716 chk_rm_nr 3 1 invert
2717 chk_rst_nr 0 0
2718 fi
2719
2720 # remove id 0 subflow
2721 if reset "remove id 0 subflow"; then
2722 pm_nl_set_limits $ns1 0 1
2723 pm_nl_set_limits $ns2 0 1
2724 pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
2725 addr_nr_ns2=-9 speed=slow \
2726 run_tests $ns1 $ns2 10.0.1.1
2727 chk_join_nr 1 1 1
2728 chk_rm_nr 1 1
2729 chk_rst_nr 0 0
2730 fi
2731
2732 # remove id 0 address
2733 if reset "remove id 0 address"; then
2734 pm_nl_set_limits $ns1 0 1
2735 pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
2736 pm_nl_set_limits $ns2 1 1
2737 addr_nr_ns1=-9 speed=slow \
2738 run_tests $ns1 $ns2 10.0.1.1
2739 chk_join_nr 1 1 1
2740 chk_add_nr 1 1
2741 chk_rm_nr 1 1 invert
2742 chk_rst_nr 0 0 invert
2743 fi
2744}
2745
2746add_tests()
2747{
2748 # add single subflow
2749 if reset "add single subflow"; then
2750 pm_nl_set_limits $ns1 0 1
2751 pm_nl_set_limits $ns2 0 1
2752 addr_nr_ns2=1 speed=slow cestab_ns2=1 \
2753 run_tests $ns1 $ns2 10.0.1.1
2754 chk_join_nr 1 1 1
2755 chk_cestab_nr $ns2 0
2756 fi
2757
2758 # add signal address
2759 if reset "add signal address"; then
2760 pm_nl_set_limits $ns1 0 1
2761 pm_nl_set_limits $ns2 1 1
2762 addr_nr_ns1=1 speed=slow cestab_ns1=1 \
2763 run_tests $ns1 $ns2 10.0.1.1
2764 chk_join_nr 1 1 1
2765 chk_add_nr 1 1
2766 chk_cestab_nr $ns1 0
2767 fi
2768
2769 # add multiple subflows
2770 if reset "add multiple subflows"; then
2771 pm_nl_set_limits $ns1 0 2
2772 pm_nl_set_limits $ns2 0 2
2773 addr_nr_ns2=2 speed=slow cestab_ns2=1 \
2774 run_tests $ns1 $ns2 10.0.1.1
2775 chk_join_nr 2 2 2
2776 chk_cestab_nr $ns2 0
2777 fi
2778
2779 # add multiple subflows IPv6
2780 if reset "add multiple subflows IPv6"; then
2781 pm_nl_set_limits $ns1 0 2
2782 pm_nl_set_limits $ns2 0 2
2783 addr_nr_ns2=2 speed=slow cestab_ns2=1 \
2784 run_tests $ns1 $ns2 dead:beef:1::1
2785 chk_join_nr 2 2 2
2786 chk_cestab_nr $ns2 0
2787 fi
2788
2789 # add multiple addresses IPv6
2790 if reset "add multiple addresses IPv6"; then
2791 pm_nl_set_limits $ns1 0 2
2792 pm_nl_set_limits $ns2 2 2
2793 addr_nr_ns1=2 speed=slow cestab_ns1=1 \
2794 run_tests $ns1 $ns2 dead:beef:1::1
2795 chk_join_nr 2 2 2
2796 chk_add_nr 2 2
2797 chk_cestab_nr $ns1 0
2798 fi
2799}
2800
2801ipv6_tests()
2802{
2803 # subflow IPv6
2804 if reset "single subflow IPv6"; then
2805 pm_nl_set_limits $ns1 0 1
2806 pm_nl_set_limits $ns2 0 1
2807 pm_nl_add_endpoint $ns2 dead:beef:3::2 dev ns2eth3 flags subflow
2808 speed=slow \
2809 run_tests $ns1 $ns2 dead:beef:1::1
2810 chk_join_nr 1 1 1
2811 fi
2812
2813 # add_address, unused IPv6
2814 if reset "unused signal address IPv6"; then
2815 pm_nl_add_endpoint $ns1 dead:beef:2::1 flags signal
2816 speed=slow \
2817 run_tests $ns1 $ns2 dead:beef:1::1
2818 chk_join_nr 0 0 0
2819 chk_add_nr 1 1
2820 fi
2821
2822 # signal address IPv6
2823 if reset "single address IPv6"; then
2824 pm_nl_set_limits $ns1 0 1
2825 pm_nl_add_endpoint $ns1 dead:beef:2::1 flags signal
2826 pm_nl_set_limits $ns2 1 1
2827 speed=slow \
2828 run_tests $ns1 $ns2 dead:beef:1::1
2829 chk_join_nr 1 1 1
2830 chk_add_nr 1 1
2831 fi
2832
2833 # single address IPv6, remove
2834 if reset "remove single address IPv6"; then
2835 pm_nl_set_limits $ns1 0 1
2836 pm_nl_add_endpoint $ns1 dead:beef:2::1 flags signal
2837 pm_nl_set_limits $ns2 1 1
2838 addr_nr_ns1=-1 speed=slow \
2839 run_tests $ns1 $ns2 dead:beef:1::1
2840 chk_join_nr 1 1 1
2841 chk_add_nr 1 1
2842 chk_rm_nr 1 1 invert
2843 fi
2844
2845 # subflow and signal IPv6, remove
2846 if reset "remove subflow and signal IPv6"; then
2847 pm_nl_set_limits $ns1 0 2
2848 pm_nl_add_endpoint $ns1 dead:beef:2::1 flags signal
2849 pm_nl_set_limits $ns2 1 2
2850 pm_nl_add_endpoint $ns2 dead:beef:3::2 dev ns2eth3 flags subflow
2851 addr_nr_ns1=-1 addr_nr_ns2=-1 speed=slow \
2852 run_tests $ns1 $ns2 dead:beef:1::1
2853 chk_join_nr 2 2 2
2854 chk_add_nr 1 1
2855 chk_rm_nr 1 1
2856 fi
2857}
2858
2859v4mapped_tests()
2860{
2861 # subflow IPv4-mapped to IPv4-mapped
2862 if reset "single subflow IPv4-mapped"; then
2863 pm_nl_set_limits $ns1 0 1
2864 pm_nl_set_limits $ns2 0 1
2865 pm_nl_add_endpoint $ns2 "::ffff:10.0.3.2" flags subflow
2866 run_tests $ns1 $ns2 "::ffff:10.0.1.1"
2867 chk_join_nr 1 1 1
2868 fi
2869
2870 # signal address IPv4-mapped with IPv4-mapped sk
2871 if reset "signal address IPv4-mapped"; then
2872 pm_nl_set_limits $ns1 0 1
2873 pm_nl_set_limits $ns2 1 1
2874 pm_nl_add_endpoint $ns1 "::ffff:10.0.2.1" flags signal
2875 run_tests $ns1 $ns2 "::ffff:10.0.1.1"
2876 chk_join_nr 1 1 1
2877 chk_add_nr 1 1
2878 fi
2879
2880 # subflow v4-map-v6
2881 if reset "single subflow v4-map-v6"; then
2882 pm_nl_set_limits $ns1 0 1
2883 pm_nl_set_limits $ns2 0 1
2884 pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
2885 run_tests $ns1 $ns2 "::ffff:10.0.1.1"
2886 chk_join_nr 1 1 1
2887 fi
2888
2889 # signal address v4-map-v6
2890 if reset "signal address v4-map-v6"; then
2891 pm_nl_set_limits $ns1 0 1
2892 pm_nl_set_limits $ns2 1 1
2893 pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
2894 run_tests $ns1 $ns2 "::ffff:10.0.1.1"
2895 chk_join_nr 1 1 1
2896 chk_add_nr 1 1
2897 fi
2898
2899 # subflow v6-map-v4
2900 if reset "single subflow v6-map-v4"; then
2901 pm_nl_set_limits $ns1 0 1
2902 pm_nl_set_limits $ns2 0 1
2903 pm_nl_add_endpoint $ns2 "::ffff:10.0.3.2" flags subflow
2904 run_tests $ns1 $ns2 10.0.1.1
2905 chk_join_nr 1 1 1
2906 fi
2907
2908 # signal address v6-map-v4
2909 if reset "signal address v6-map-v4"; then
2910 pm_nl_set_limits $ns1 0 1
2911 pm_nl_set_limits $ns2 1 1
2912 pm_nl_add_endpoint $ns1 "::ffff:10.0.2.1" flags signal
2913 run_tests $ns1 $ns2 10.0.1.1
2914 chk_join_nr 1 1 1
2915 chk_add_nr 1 1
2916 fi
2917
2918 # no subflow IPv6 to v4 address
2919 if reset "no JOIN with diff families v4-v6"; then
2920 pm_nl_set_limits $ns1 0 1
2921 pm_nl_set_limits $ns2 0 1
2922 pm_nl_add_endpoint $ns2 dead:beef:2::2 flags subflow
2923 run_tests $ns1 $ns2 10.0.1.1
2924 chk_join_nr 0 0 0
2925 fi
2926
2927 # no subflow IPv6 to v4 address even if v6 has a valid v4 at the end
2928 if reset "no JOIN with diff families v4-v6-2"; then
2929 pm_nl_set_limits $ns1 0 1
2930 pm_nl_set_limits $ns2 0 1
2931 pm_nl_add_endpoint $ns2 dead:beef:2::10.0.3.2 flags subflow
2932 run_tests $ns1 $ns2 10.0.1.1
2933 chk_join_nr 0 0 0
2934 fi
2935
2936 # no subflow IPv4 to v6 address, no need to slow down too then
2937 if reset "no JOIN with diff families v6-v4"; then
2938 pm_nl_set_limits $ns1 0 1
2939 pm_nl_set_limits $ns2 0 1
2940 pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
2941 run_tests $ns1 $ns2 dead:beef:1::1
2942 chk_join_nr 0 0 0
2943 fi
2944}
2945
2946mixed_tests()
2947{
2948 if reset "IPv4 sockets do not use IPv6 addresses" &&
2949 continue_if mptcp_lib_kversion_ge 6.3; then
2950 pm_nl_set_limits $ns1 0 1
2951 pm_nl_set_limits $ns2 1 1
2952 pm_nl_add_endpoint $ns1 dead:beef:2::1 flags signal
2953 speed=slow \
2954 run_tests $ns1 $ns2 10.0.1.1
2955 chk_join_nr 0 0 0
2956 fi
2957
2958 # Need an IPv6 mptcp socket to allow subflows of both families
2959 if reset "simult IPv4 and IPv6 subflows" &&
2960 continue_if mptcp_lib_kversion_ge 6.3; then
2961 pm_nl_set_limits $ns1 0 1
2962 pm_nl_set_limits $ns2 1 1
2963 pm_nl_add_endpoint $ns1 10.0.1.1 flags signal
2964 speed=slow \
2965 run_tests $ns1 $ns2 dead:beef:2::1
2966 chk_join_nr 1 1 1
2967 fi
2968
2969 # cross families subflows will not be created even in fullmesh mode
2970 if reset "simult IPv4 and IPv6 subflows, fullmesh 1x1" &&
2971 continue_if mptcp_lib_kversion_ge 6.3; then
2972 pm_nl_set_limits $ns1 0 4
2973 pm_nl_set_limits $ns2 1 4
2974 pm_nl_add_endpoint $ns2 dead:beef:2::2 flags subflow,fullmesh
2975 pm_nl_add_endpoint $ns1 10.0.1.1 flags signal
2976 speed=slow \
2977 run_tests $ns1 $ns2 dead:beef:2::1
2978 if mptcp_lib_kallsyms_has "mptcp_pm_get_endp_fullmesh_max$"; then
2979 chk_join_nr 0 0 0
2980 else
2981 chk_join_nr 1 1 1
2982 fi
2983 fi
2984
2985 # fullmesh still tries to create all the possibly subflows with
2986 # matching family
2987 if reset "simult IPv4 and IPv6 subflows, fullmesh 2x2" &&
2988 continue_if mptcp_lib_kversion_ge 6.3; then
2989 pm_nl_set_limits $ns1 0 4
2990 pm_nl_set_limits $ns2 2 4
2991 pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
2992 pm_nl_add_endpoint $ns1 dead:beef:2::1 flags signal
2993 fullmesh=1 speed=slow \
2994 run_tests $ns1 $ns2 dead:beef:1::1
2995 chk_join_nr 4 4 4
2996 fi
2997}
2998
2999backup_tests()
3000{
3001 # single subflow, backup
3002 if reset "single subflow, backup" &&
3003 continue_if mptcp_lib_kallsyms_has "subflow_rebuild_header$"; then
3004 pm_nl_set_limits $ns1 0 1
3005 pm_nl_set_limits $ns2 0 1
3006 pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow,backup
3007 sflags=nobackup speed=slow \
3008 run_tests $ns1 $ns2 10.0.1.1
3009 chk_join_nr 1 1 1
3010 chk_prio_nr 0 1 1 0
3011 fi
3012
3013 # single address, backup
3014 if reset "single address, backup" &&
3015 continue_if mptcp_lib_kallsyms_has "subflow_rebuild_header$"; then
3016 pm_nl_set_limits $ns1 0 1
3017 pm_nl_add_endpoint $ns1 10.0.2.1 flags signal,backup
3018 pm_nl_set_limits $ns2 1 1
3019 sflags=nobackup speed=slow \
3020 run_tests $ns1 $ns2 10.0.1.1
3021 chk_join_nr 1 1 1
3022 chk_add_nr 1 1
3023 chk_prio_nr 1 0 0 1
3024 fi
3025
3026 # single address, switch to backup
3027 if reset "single address, switch to backup" &&
3028 continue_if mptcp_lib_kallsyms_has "subflow_rebuild_header$"; then
3029 pm_nl_set_limits $ns1 0 1
3030 pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
3031 pm_nl_set_limits $ns2 1 1
3032 sflags=backup speed=slow \
3033 run_tests $ns1 $ns2 10.0.1.1
3034 chk_join_nr 1 1 1
3035 chk_add_nr 1 1
3036 chk_prio_nr 1 1 0 0
3037 fi
3038
3039 # single address with port, backup
3040 if reset "single address with port, backup" &&
3041 continue_if mptcp_lib_kallsyms_has "subflow_rebuild_header$"; then
3042 pm_nl_set_limits $ns1 0 1
3043 pm_nl_add_endpoint $ns1 10.0.2.1 flags signal,backup port 10100
3044 pm_nl_set_limits $ns2 1 1
3045 sflags=nobackup speed=slow \
3046 run_tests $ns1 $ns2 10.0.1.1
3047 chk_join_nr 1 1 1
3048 chk_add_nr 1 1
3049 chk_prio_nr 1 0 0 1
3050 fi
3051
3052 if reset "mpc backup" &&
3053 continue_if mptcp_lib_kallsyms_doesnt_have "T mptcp_subflow_send_ack$"; then
3054 pm_nl_add_endpoint $ns2 10.0.1.2 flags subflow,backup
3055 speed=slow \
3056 run_tests $ns1 $ns2 10.0.1.1
3057 chk_join_nr 0 0 0
3058 chk_prio_nr 0 1 0 0
3059 fi
3060
3061 if reset "mpc backup both sides" &&
3062 continue_if mptcp_lib_kallsyms_doesnt_have "T mptcp_subflow_send_ack$"; then
3063 pm_nl_set_limits $ns1 0 2
3064 pm_nl_set_limits $ns2 1 2
3065 pm_nl_add_endpoint $ns1 10.0.1.1 flags signal,backup
3066 pm_nl_add_endpoint $ns2 10.0.1.2 flags subflow,backup
3067
3068 # 10.0.2.2 (non-backup) -> 10.0.1.1 (backup)
3069 pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow
3070 # 10.0.1.2 (backup) -> 10.0.2.1 (non-backup)
3071 pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
3072 ip -net "$ns2" route add 10.0.2.1 via 10.0.1.1 dev ns2eth1 # force this path
3073
3074 speed=slow \
3075 run_tests $ns1 $ns2 10.0.1.1
3076 chk_join_nr 2 2 2
3077 chk_prio_nr 1 1 1 1
3078 fi
3079
3080 if reset "mpc switch to backup" &&
3081 continue_if mptcp_lib_kallsyms_doesnt_have "T mptcp_subflow_send_ack$"; then
3082 pm_nl_add_endpoint $ns2 10.0.1.2 flags subflow
3083 sflags=backup speed=slow \
3084 run_tests $ns1 $ns2 10.0.1.1
3085 chk_join_nr 0 0 0
3086 chk_prio_nr 0 1 0 0
3087 fi
3088
3089 if reset "mpc switch to backup both sides" &&
3090 continue_if mptcp_lib_kallsyms_doesnt_have "T mptcp_subflow_send_ack$"; then
3091 pm_nl_add_endpoint $ns1 10.0.1.1 flags subflow
3092 pm_nl_add_endpoint $ns2 10.0.1.2 flags subflow
3093 sflags=backup speed=slow \
3094 run_tests $ns1 $ns2 10.0.1.1
3095 chk_join_nr 0 0 0
3096 chk_prio_nr 1 1 0 0
3097 fi
3098}
3099
3100verify_listener_events()
3101{
3102 local e_type=$2
3103 local e_saddr=$4
3104 local e_sport=$5
3105 local name
3106
3107 if [ $e_type = $MPTCP_LIB_EVENT_LISTENER_CREATED ]; then
3108 name="LISTENER_CREATED"
3109 elif [ $e_type = $MPTCP_LIB_EVENT_LISTENER_CLOSED ]; then
3110 name="LISTENER_CLOSED "
3111 else
3112 name="$e_type"
3113 fi
3114
3115 print_check "$name $e_saddr:$e_sport"
3116
3117 if ! mptcp_lib_kallsyms_has "mptcp_event_pm_listener$"; then
3118 print_skip "event not supported"
3119 return
3120 fi
3121
3122 if mptcp_lib_verify_listener_events "${@}"; then
3123 print_ok
3124 return 0
3125 fi
3126 fail_test
3127}
3128
3129chk_mpc_endp_attempt()
3130{
3131 local retl=$1
3132 local attempts=$2
3133
3134 print_check "Connect"
3135
3136 if [ ${retl} = 124 ]; then
3137 fail_test "timeout on connect"
3138 elif [ ${retl} = 0 ]; then
3139 fail_test "unexpected successful connect"
3140 else
3141 print_ok
3142
3143 print_check "Attempts"
3144 count=$(mptcp_lib_get_counter ${ns1} "MPTcpExtMPCapableEndpAttempt")
3145 if [ -z "$count" ]; then
3146 print_skip
3147 elif [ "$count" != "$attempts" ]; then
3148 fail_test "got ${count} MPC attempt[s] on port-based endpoint, expected ${attempts}"
3149 else
3150 print_ok
3151 fi
3152 fi
3153}
3154
3155add_addr_ports_tests()
3156{
3157 # signal address with port
3158 if reset "signal address with port"; then
3159 pm_nl_set_limits $ns1 0 1
3160 pm_nl_set_limits $ns2 1 1
3161 pm_nl_add_endpoint $ns1 10.0.2.1 flags signal port 10100
3162 run_tests $ns1 $ns2 10.0.1.1
3163 chk_join_nr 1 1 1
3164 chk_add_nr 1 1 1
3165 fi
3166
3167 # subflow and signal with port
3168 if reset "subflow and signal with port"; then
3169 pm_nl_add_endpoint $ns1 10.0.2.1 flags signal port 10100
3170 pm_nl_set_limits $ns1 0 2
3171 pm_nl_set_limits $ns2 1 2
3172 pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
3173 run_tests $ns1 $ns2 10.0.1.1
3174 chk_join_nr 2 2 2
3175 chk_add_nr 1 1 1
3176 fi
3177
3178 # single address with port, remove
3179 # pm listener events
3180 if reset_with_events "remove single address with port"; then
3181 pm_nl_set_limits $ns1 0 1
3182 pm_nl_add_endpoint $ns1 10.0.2.1 flags signal port 10100
3183 pm_nl_set_limits $ns2 1 1
3184 addr_nr_ns1=-1 speed=slow \
3185 run_tests $ns1 $ns2 10.0.1.1
3186 chk_join_nr 1 1 1
3187 chk_add_nr 1 1 1
3188 chk_rm_nr 1 1 invert
3189
3190 verify_listener_events $evts_ns1 $MPTCP_LIB_EVENT_LISTENER_CREATED \
3191 $MPTCP_LIB_AF_INET 10.0.2.1 10100
3192 verify_listener_events $evts_ns1 $MPTCP_LIB_EVENT_LISTENER_CLOSED \
3193 $MPTCP_LIB_AF_INET 10.0.2.1 10100
3194 kill_events_pids
3195 fi
3196
3197 # subflow and signal with port, remove
3198 if reset "remove subflow and signal with port"; then
3199 pm_nl_set_limits $ns1 0 2
3200 pm_nl_add_endpoint $ns1 10.0.2.1 flags signal port 10100
3201 pm_nl_set_limits $ns2 1 2
3202 pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
3203 addr_nr_ns1=-1 addr_nr_ns2=-1 speed=slow \
3204 run_tests $ns1 $ns2 10.0.1.1
3205 chk_join_nr 2 2 2
3206 chk_add_nr 1 1 1
3207 chk_rm_nr 1 1
3208 fi
3209
3210 # subflows and signal with port, flush
3211 if reset "flush subflows and signal with port"; then
3212 pm_nl_set_limits $ns1 0 3
3213 pm_nl_add_endpoint $ns1 10.0.2.1 flags signal port 10100
3214 pm_nl_set_limits $ns2 1 3
3215 pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
3216 pm_nl_add_endpoint $ns2 10.0.4.2 flags subflow
3217 addr_nr_ns1=-8 addr_nr_ns2=-2 speed=slow \
3218 run_tests $ns1 $ns2 10.0.1.1
3219 chk_join_nr 3 3 3
3220 chk_add_nr 1 1
3221 chk_rm_nr 1 3 invert simult
3222 fi
3223
3224 # multiple addresses with port
3225 if reset "multiple addresses with port"; then
3226 pm_nl_set_limits $ns1 2 2
3227 pm_nl_add_endpoint $ns1 10.0.2.1 flags signal port 10100
3228 pm_nl_add_endpoint $ns1 10.0.3.1 flags signal port 10100
3229 pm_nl_set_limits $ns2 2 2
3230 run_tests $ns1 $ns2 10.0.1.1
3231 chk_join_nr 2 2 2
3232 chk_add_nr 2 2 2
3233 fi
3234
3235 # multiple addresses with ports
3236 if reset "multiple addresses with ports"; then
3237 pm_nl_set_limits $ns1 2 2
3238 pm_nl_add_endpoint $ns1 10.0.2.1 flags signal port 10100
3239 pm_nl_add_endpoint $ns1 10.0.3.1 flags signal port 10101
3240 pm_nl_set_limits $ns2 2 2
3241 run_tests $ns1 $ns2 10.0.1.1
3242 chk_join_nr 2 2 2
3243 chk_add_nr 2 2 2
3244 fi
3245
3246 if reset "port-based signal endpoint must not accept mpc"; then
3247 local port retl count
3248 port=$(get_port)
3249
3250 cond_start_capture ${ns1}
3251 pm_nl_add_endpoint ${ns1} 10.0.2.1 flags signal port ${port}
3252 mptcp_lib_wait_local_port_listen ${ns1} ${port}
3253
3254 timeout 1 ip netns exec ${ns2} \
3255 ./mptcp_connect -t ${timeout_poll} -p $port -s MPTCP 10.0.2.1 >/dev/null 2>&1
3256 retl=$?
3257 cond_stop_capture
3258
3259 chk_mpc_endp_attempt ${retl} 1
3260 fi
3261}
3262
3263bind_tests()
3264{
3265 # bind to one address should not allow extra subflows to other addresses
3266 if reset "bind main address v4, no join v4"; then
3267 pm_nl_set_limits $ns1 0 2
3268 pm_nl_set_limits $ns2 2 2
3269 pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
3270 bind_addr="10.0.1.1" \
3271 run_tests $ns1 $ns2 10.0.1.1
3272 join_syn_tx=1 \
3273 chk_join_nr 0 0 0
3274 chk_add_nr 1 1
3275 fi
3276
3277 # bind to one address should not allow extra subflows to other addresses
3278 if reset "bind main address v6, no join v6"; then
3279 pm_nl_set_limits $ns1 0 2
3280 pm_nl_set_limits $ns2 2 2
3281 pm_nl_add_endpoint $ns1 dead:beef:2::1 flags signal
3282 bind_addr="dead:beef:1::1" \
3283 run_tests $ns1 $ns2 dead:beef:1::1
3284 join_syn_tx=1 \
3285 chk_join_nr 0 0 0
3286 chk_add_nr 1 1
3287 fi
3288
3289 # multiple binds to allow extra subflows to other addresses
3290 if reset "multiple bind to allow joins v4"; then
3291 local extra_bind
3292
3293 pm_nl_set_limits $ns1 0 2
3294 pm_nl_set_limits $ns2 2 2
3295 pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
3296
3297 # Launching another app listening on a different address
3298 # Note: it could be a totally different app, e.g. nc, socat, ...
3299 ip netns exec ${ns1} ./mptcp_connect -l -t -1 -p "$(get_port)" \
3300 -s MPTCP 10.0.2.1 &
3301 extra_bind=$!
3302
3303 bind_addr="10.0.1.1" \
3304 run_tests $ns1 $ns2 10.0.1.1
3305 chk_join_nr 1 1 1
3306 chk_add_nr 1 1
3307
3308 kill ${extra_bind}
3309 fi
3310
3311 # multiple binds to allow extra subflows to other addresses
3312 if reset "multiple bind to allow joins v6"; then
3313 local extra_bind
3314
3315 pm_nl_set_limits $ns1 0 2
3316 pm_nl_set_limits $ns2 2 2
3317 pm_nl_add_endpoint $ns1 dead:beef:2::1 flags signal
3318
3319 # Launching another app listening on a different address
3320 # Note: it could be a totally different app, e.g. nc, socat, ...
3321 ip netns exec ${ns1} ./mptcp_connect -l -t -1 -p "$(get_port)" \
3322 -s MPTCP dead:beef:2::1 &
3323 extra_bind=$!
3324
3325 bind_addr="dead:beef:1::1" \
3326 run_tests $ns1 $ns2 dead:beef:1::1
3327 chk_join_nr 1 1 1
3328 chk_add_nr 1 1
3329
3330 kill ${extra_bind}
3331 fi
3332
3333 # multiple binds to allow extra subflows to other addresses: v6 LL case
3334 if reset "multiple bind to allow joins v6 link-local routing"; then
3335 local extra_bind ns1ll1 ns1ll2
3336
3337 ns1ll1="$(get_ll_addr $ns1 ns1eth1)"
3338 ns1ll2="$(get_ll_addr $ns1 ns1eth2)"
3339
3340 pm_nl_set_limits $ns1 0 2
3341 pm_nl_set_limits $ns2 2 2
3342 pm_nl_add_endpoint $ns1 "${ns1ll2}" flags signal
3343
3344 wait_ll_ready $ns1 # to be able to bind
3345 wait_ll_ready $ns2 # also needed to bind on the client side
3346 ip netns exec ${ns1} ./mptcp_connect -l -t -1 -p "$(get_port)" \
3347 -s MPTCP "${ns1ll2}%ns1eth2" &
3348 extra_bind=$!
3349
3350 bind_addr="${ns1ll1}%ns1eth1" \
3351 run_tests $ns1 $ns2 "${ns1ll1}%ns2eth1"
3352 # it is not possible to connect to the announced LL addr without
3353 # specifying the outgoing interface.
3354 join_connect_err=1 \
3355 chk_join_nr 0 0 0
3356 chk_add_nr 1 1
3357
3358 kill ${extra_bind}
3359 fi
3360
3361 # multiple binds to allow extra subflows to v6 LL addresses: laminar
3362 if reset "multiple bind to allow joins v6 link-local laminar" &&
3363 continue_if mptcp_lib_kallsyms_has "mptcp_pm_get_endp_laminar_max$"; then
3364 local extra_bind ns1ll1 ns1ll2 ns2ll2
3365
3366 ns1ll1="$(get_ll_addr $ns1 ns1eth1)"
3367 ns1ll2="$(get_ll_addr $ns1 ns1eth2)"
3368 ns2ll2="$(get_ll_addr $ns2 ns2eth2)"
3369
3370 pm_nl_set_limits $ns1 0 2
3371 pm_nl_set_limits $ns2 2 2
3372 pm_nl_add_endpoint $ns1 "${ns1ll2}" flags signal
3373 pm_nl_add_endpoint $ns2 "${ns2ll2}" flags laminar dev ns2eth2
3374
3375 wait_ll_ready $ns1 # to be able to bind
3376 wait_ll_ready $ns2 # also needed to bind on the client side
3377 ip netns exec ${ns1} ./mptcp_connect -l -t -1 -p "$(get_port)" \
3378 -s MPTCP "${ns1ll2}%ns1eth2" &
3379 extra_bind=$!
3380
3381 bind_addr="${ns1ll1}%ns1eth1" \
3382 run_tests $ns1 $ns2 "${ns1ll1}%ns2eth1"
3383 chk_join_nr 1 1 1
3384 chk_add_nr 1 1
3385
3386 kill ${extra_bind}
3387 fi
3388}
3389
3390syncookies_tests()
3391{
3392 # single subflow, syncookies
3393 if reset_with_cookies "single subflow with syn cookies"; then
3394 pm_nl_set_limits $ns1 0 1
3395 pm_nl_set_limits $ns2 0 1
3396 pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
3397 run_tests $ns1 $ns2 10.0.1.1
3398 chk_join_nr 1 1 1
3399 fi
3400
3401 # multiple subflows with syn cookies
3402 if reset_with_cookies "multiple subflows with syn cookies"; then
3403 pm_nl_set_limits $ns1 0 2
3404 pm_nl_set_limits $ns2 0 2
3405 pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
3406 pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow
3407 run_tests $ns1 $ns2 10.0.1.1
3408 chk_join_nr 2 2 2
3409 fi
3410
3411 # multiple subflows limited by server
3412 if reset_with_cookies "subflows limited by server w cookies"; then
3413 pm_nl_set_limits $ns1 0 1
3414 pm_nl_set_limits $ns2 0 2
3415 pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
3416 pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow
3417 run_tests $ns1 $ns2 10.0.1.1
3418 join_syn_rej=1 \
3419 chk_join_nr 2 1 1
3420 fi
3421
3422 # test signal address with cookies
3423 if reset_with_cookies "signal address with syn cookies"; then
3424 pm_nl_set_limits $ns1 0 1
3425 pm_nl_set_limits $ns2 1 1
3426 pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
3427 run_tests $ns1 $ns2 10.0.1.1
3428 chk_join_nr 1 1 1
3429 chk_add_nr 1 1
3430 fi
3431
3432 # test cookie with subflow and signal
3433 if reset_with_cookies "subflow and signal w cookies"; then
3434 pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
3435 pm_nl_set_limits $ns1 0 2
3436 pm_nl_set_limits $ns2 1 2
3437 pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
3438 run_tests $ns1 $ns2 10.0.1.1
3439 chk_join_nr 2 2 2
3440 chk_add_nr 1 1
3441 fi
3442
3443 # accept and use add_addr with additional subflows
3444 if reset_with_cookies "subflows and signal w. cookies"; then
3445 pm_nl_set_limits $ns1 0 3
3446 pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
3447 pm_nl_set_limits $ns2 1 3
3448 pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
3449 pm_nl_add_endpoint $ns2 10.0.4.2 flags subflow
3450 run_tests $ns1 $ns2 10.0.1.1
3451 chk_join_nr 3 3 3
3452 chk_add_nr 1 1
3453 fi
3454}
3455
3456checksum_tests()
3457{
3458 local checksum_enable
3459 for checksum_enable in "0 0" "1 1" "0 1" "1 0"; do
3460 # checksum test 0 0, 1 1, 0 1, 1 0
3461 if reset_with_checksum ${checksum_enable}; then
3462 pm_nl_set_limits $ns1 0 1
3463 pm_nl_set_limits $ns2 0 1
3464 run_tests $ns1 $ns2 10.0.1.1
3465 chk_join_nr 0 0 0
3466 fi
3467 done
3468}
3469
3470deny_join_id0_tests()
3471{
3472 # subflow allow join id0 ns1
3473 if reset_with_allow_join_id0 "single subflow allow join id0 ns1" 1 0; then
3474 pm_nl_set_limits $ns1 1 1
3475 pm_nl_set_limits $ns2 1 1
3476 pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
3477 run_tests $ns1 $ns2 10.0.1.1
3478 chk_join_nr 1 1 1
3479 fi
3480
3481 # subflow allow join id0 ns2
3482 if reset_with_allow_join_id0 "single subflow allow join id0 ns2" 0 1; then
3483 pm_nl_set_limits $ns1 1 1
3484 pm_nl_set_limits $ns2 1 1
3485 pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
3486 run_tests $ns1 $ns2 10.0.1.1
3487 chk_join_nr 0 0 0
3488 fi
3489
3490 # signal address allow join id0 ns1
3491 # ADD_ADDRs are not affected by allow_join_id0 value.
3492 if reset_with_allow_join_id0 "signal address allow join id0 ns1" 1 0; then
3493 pm_nl_set_limits $ns1 1 1
3494 pm_nl_set_limits $ns2 1 1
3495 pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
3496 run_tests $ns1 $ns2 10.0.1.1
3497 chk_join_nr 1 1 1
3498 chk_add_nr 1 1
3499 fi
3500
3501 # signal address allow join id0 ns2
3502 # ADD_ADDRs are not affected by allow_join_id0 value.
3503 if reset_with_allow_join_id0 "signal address allow join id0 ns2" 0 1; then
3504 pm_nl_set_limits $ns1 1 1
3505 pm_nl_set_limits $ns2 1 1
3506 pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
3507 run_tests $ns1 $ns2 10.0.1.1
3508 chk_join_nr 1 1 1
3509 chk_add_nr 1 1
3510 fi
3511
3512 # subflow and address allow join id0 ns1
3513 if reset_with_allow_join_id0 "subflow and address allow join id0 1" 1 0; then
3514 pm_nl_set_limits $ns1 2 2
3515 pm_nl_set_limits $ns2 2 2
3516 pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
3517 pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
3518 run_tests $ns1 $ns2 10.0.1.1
3519 chk_join_nr 2 2 2
3520 fi
3521
3522 # subflow and address allow join id0 ns2
3523 if reset_with_allow_join_id0 "subflow and address allow join id0 2" 0 1; then
3524 pm_nl_set_limits $ns1 2 2
3525 pm_nl_set_limits $ns2 2 2
3526 pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
3527 pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
3528 run_tests $ns1 $ns2 10.0.1.1
3529 chk_join_nr 1 1 1
3530 fi
3531
3532 # default limits, server deny join id 0 + signal
3533 if reset_with_allow_join_id0 "default limits, server deny join id 0" 0 1; then
3534 pm_nl_set_limits $ns1 0 2
3535 pm_nl_set_limits $ns2 0 2
3536 pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
3537 pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
3538 pm_nl_add_endpoint $ns2 10.0.4.2 flags subflow
3539 run_tests $ns1 $ns2 10.0.1.1
3540 chk_join_nr 2 2 2
3541 fi
3542}
3543
3544fullmesh_tests()
3545{
3546 # fullmesh 1
3547 # 2 fullmesh addrs in ns2, added before the connection,
3548 # 1 non-fullmesh addr in ns1, added during the connection.
3549 if reset "fullmesh test 2x1"; then
3550 pm_nl_set_limits $ns1 0 4
3551 pm_nl_set_limits $ns2 1 4
3552 pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow,fullmesh
3553 pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow,fullmesh
3554 addr_nr_ns1=1 speed=slow \
3555 run_tests $ns1 $ns2 10.0.1.1
3556 chk_join_nr 4 4 4
3557 chk_add_nr 1 1
3558 fi
3559
3560 # fullmesh 2
3561 # 1 non-fullmesh addr in ns1, added before the connection,
3562 # 1 fullmesh addr in ns2, added during the connection.
3563 if reset "fullmesh test 1x1"; then
3564 pm_nl_set_limits $ns1 1 3
3565 pm_nl_set_limits $ns2 1 3
3566 pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
3567 if mptcp_lib_kallsyms_has "mptcp_pm_subflow_check_next$"; then
3568 pm_nl_add_endpoint $ns2 10.0.1.2 flags subflow,fullmesh
3569 fi
3570 fullmesh=1 speed=slow \
3571 run_tests $ns1 $ns2 10.0.1.1
3572 chk_join_nr 3 3 3
3573 chk_add_nr 1 1
3574 fi
3575
3576 # fullmesh 3
3577 # 1 non-fullmesh addr in ns1, added before the connection,
3578 # 2 fullmesh addrs in ns2, added during the connection.
3579 if reset "fullmesh test 1x2"; then
3580 pm_nl_set_limits $ns1 2 5
3581 pm_nl_set_limits $ns2 1 5
3582 pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
3583 fullmesh=2 speed=slow \
3584 run_tests $ns1 $ns2 10.0.1.1
3585 chk_join_nr 5 5 5
3586 chk_add_nr 1 1
3587 fi
3588
3589 # fullmesh 4
3590 # 1 non-fullmesh addr in ns1, added before the connection,
3591 # 2 fullmesh addrs in ns2, added during the connection,
3592 # limit max_subflows to 4.
3593 if reset "fullmesh test 1x2, limited"; then
3594 pm_nl_set_limits $ns1 2 4
3595 pm_nl_set_limits $ns2 1 4
3596 pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
3597 fullmesh=2 speed=slow \
3598 run_tests $ns1 $ns2 10.0.1.1
3599 chk_join_nr 4 4 4
3600 chk_add_nr 1 1
3601 fi
3602
3603 # set fullmesh flag
3604 if reset "set fullmesh flag test" &&
3605 continue_if mptcp_lib_kversion_ge 5.18; then
3606 pm_nl_set_limits $ns1 4 4
3607 pm_nl_add_endpoint $ns1 10.0.2.1 flags subflow
3608 pm_nl_set_limits $ns2 4 4
3609 addr_nr_ns2=1 sflags=fullmesh speed=slow \
3610 run_tests $ns1 $ns2 10.0.1.1
3611 chk_join_nr 2 2 2
3612 chk_rm_nr 0 1
3613 fi
3614
3615 # set nofullmesh flag
3616 if reset "set nofullmesh flag test" &&
3617 continue_if mptcp_lib_kversion_ge 5.18; then
3618 pm_nl_set_limits $ns1 4 4
3619 pm_nl_add_endpoint $ns1 10.0.2.1 flags subflow,fullmesh
3620 pm_nl_set_limits $ns2 4 4
3621 fullmesh=1 sflags=nofullmesh speed=slow \
3622 run_tests $ns1 $ns2 10.0.1.1
3623 chk_join_nr 2 2 2
3624 chk_rm_nr 0 1
3625 fi
3626
3627 # set backup,fullmesh flags
3628 if reset "set backup,fullmesh flags test" &&
3629 continue_if mptcp_lib_kversion_ge 5.18; then
3630 pm_nl_set_limits $ns1 4 4
3631 pm_nl_add_endpoint $ns1 10.0.2.1 flags subflow
3632 pm_nl_set_limits $ns2 4 4
3633 addr_nr_ns2=1 sflags=backup,fullmesh speed=slow \
3634 run_tests $ns1 $ns2 10.0.1.1
3635 chk_join_nr 2 2 2
3636 chk_prio_nr 0 1 1 0
3637 chk_rm_nr 0 1
3638 fi
3639
3640 # set nobackup,nofullmesh flags
3641 if reset "set nobackup,nofullmesh flags test" &&
3642 continue_if mptcp_lib_kversion_ge 5.18; then
3643 pm_nl_set_limits $ns1 4 4
3644 pm_nl_set_limits $ns2 4 4
3645 pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow,backup,fullmesh
3646 sflags=nobackup,nofullmesh speed=slow \
3647 run_tests $ns1 $ns2 10.0.1.1
3648 chk_join_nr 2 2 2
3649 chk_prio_nr 0 1 1 0
3650 chk_rm_nr 0 1
3651 fi
3652}
3653
3654fastclose_tests()
3655{
3656 if reset_check_counter "fastclose test" "MPTcpExtMPFastcloseTx"; then
3657 test_linkfail=1024 fastclose=client \
3658 run_tests $ns1 $ns2 10.0.1.1
3659 chk_join_nr 0 0 0
3660 chk_fclose_nr 1 1
3661 chk_rst_nr 1 1 invert
3662 fi
3663
3664 if reset_check_counter "fastclose server test" "MPTcpExtMPFastcloseRx"; then
3665 test_linkfail=1024 fastclose=server \
3666 run_tests $ns1 $ns2 10.0.1.1
3667 join_rst_nr=1 \
3668 chk_join_nr 0 0 0
3669 chk_fclose_nr 1 1 invert
3670 chk_rst_nr 1 1
3671 fi
3672}
3673
3674pedit_action_pkts()
3675{
3676 tc -n $ns2 -j -s action show action pedit index 100 | \
3677 mptcp_lib_get_info_value \"packets\" packets
3678}
3679
3680fail_tests()
3681{
3682 # single subflow
3683 if reset_with_fail "Infinite map" 1; then
3684 MPTCP_LIB_SUBTEST_FLAKY=1
3685 test_linkfail=128 \
3686 run_tests $ns1 $ns2 10.0.1.1
3687 join_csum_ns1=+1 join_csum_ns2=+0 \
3688 join_fail_nr=1 join_rst_nr=0 join_infi_nr=1 \
3689 join_corrupted_pkts="$(pedit_action_pkts)" \
3690 fb_ns1="fb_dss=1" fb_ns2="fb_infinite_map_tx=1" \
3691 chk_join_nr 0 0 0
3692 chk_fail_nr 1 -1 invert
3693 fi
3694
3695 # multiple subflows
3696 if reset_with_fail "MP_FAIL MP_RST" 2; then
3697 MPTCP_LIB_SUBTEST_FLAKY=1
3698 tc -n $ns2 qdisc add dev ns2eth1 root netem rate 1mbit delay 5ms
3699 pm_nl_set_limits $ns1 0 1
3700 pm_nl_set_limits $ns2 0 1
3701 pm_nl_add_endpoint $ns2 10.0.2.2 dev ns2eth2 flags subflow
3702 test_linkfail=1024 \
3703 run_tests $ns1 $ns2 10.0.1.1
3704 join_csum_ns1=1 join_csum_ns2=0 \
3705 join_fail_nr=1 join_rst_nr=1 join_infi_nr=0 \
3706 join_corrupted_pkts="$(pedit_action_pkts)" \
3707 chk_join_nr 1 1 1
3708 fi
3709}
3710
3711# $1: ns ; $2: addr ; $3: id
3712userspace_pm_add_addr()
3713{
3714 local evts=$evts_ns1
3715 local tk
3716
3717 [ "$1" == "$ns2" ] && evts=$evts_ns2
3718 tk=$(mptcp_lib_evts_get_info token "$evts")
3719
3720 ip netns exec $1 ./pm_nl_ctl ann $2 token $tk id $3
3721 sleep 1
3722}
3723
3724# $1: ns ; $2: id
3725userspace_pm_rm_addr()
3726{
3727 local evts=$evts_ns1
3728 local tk
3729 local cnt
3730
3731 [ "$1" == "$ns2" ] && evts=$evts_ns2
3732 tk=$(mptcp_lib_evts_get_info token "$evts")
3733
3734 cnt=$(rm_addr_count ${1})
3735 ip netns exec $1 ./pm_nl_ctl rem token $tk id $2
3736 wait_rm_addr $1 "${cnt}"
3737}
3738
3739# $1: ns ; $2: addr ; $3: id
3740userspace_pm_add_sf()
3741{
3742 local evts=$evts_ns1
3743 local tk da dp
3744
3745 [ "$1" == "$ns2" ] && evts=$evts_ns2
3746 tk=$(mptcp_lib_evts_get_info token "$evts")
3747 da=$(mptcp_lib_evts_get_info daddr4 "$evts")
3748 dp=$(mptcp_lib_evts_get_info dport "$evts")
3749
3750 ip netns exec $1 ./pm_nl_ctl csf lip $2 lid $3 \
3751 rip $da rport $dp token $tk
3752 sleep 1
3753}
3754
3755# $1: ns ; $2: addr $3: event type
3756userspace_pm_rm_sf()
3757{
3758 local evts=$evts_ns1
3759 local t=${3:-1}
3760 local ip
3761 local tk da dp sp
3762 local cnt
3763
3764 [ "$1" == "$ns2" ] && evts=$evts_ns2
3765 [ -n "$(mptcp_lib_evts_get_info "saddr4" "$evts" $t)" ] && ip=4
3766 [ -n "$(mptcp_lib_evts_get_info "saddr6" "$evts" $t)" ] && ip=6
3767 tk=$(mptcp_lib_evts_get_info token "$evts")
3768 da=$(mptcp_lib_evts_get_info "daddr$ip" "$evts" $t $2)
3769 dp=$(mptcp_lib_evts_get_info dport "$evts" $t $2)
3770 sp=$(mptcp_lib_evts_get_info sport "$evts" $t $2)
3771
3772 cnt=$(rm_sf_count ${1})
3773 ip netns exec $1 ./pm_nl_ctl dsf lip $2 lport $sp \
3774 rip $da rport $dp token $tk
3775 wait_rm_sf $1 "${cnt}"
3776}
3777
3778check_output()
3779{
3780 local cmd="$1"
3781 local expected="$2"
3782 local msg="$3"
3783 local rc=0
3784
3785 mptcp_lib_check_output "${err}" "${cmd}" "${expected}" || rc=${?}
3786 if [ ${rc} -eq 2 ]; then
3787 fail_test "fail to check output # error ${rc}"
3788 elif [ ${rc} -eq 0 ]; then
3789 print_ok
3790 elif [ ${rc} -eq 1 ]; then
3791 fail_test "fail to check output # different output"
3792 fi
3793}
3794
3795# $1: ns
3796userspace_pm_dump()
3797{
3798 local evts=$evts_ns1
3799 local tk
3800
3801 [ "$1" == "$ns2" ] && evts=$evts_ns2
3802 tk=$(mptcp_lib_evts_get_info token "$evts")
3803
3804 ip netns exec $1 ./pm_nl_ctl dump token $tk
3805}
3806
3807# $1: ns ; $2: id
3808userspace_pm_get_addr()
3809{
3810 local evts=$evts_ns1
3811 local tk
3812
3813 [ "$1" == "$ns2" ] && evts=$evts_ns2
3814 tk=$(mptcp_lib_evts_get_info token "$evts")
3815
3816 ip netns exec $1 ./pm_nl_ctl get $2 token $tk
3817}
3818
3819userspace_pm_chk_dump_addr()
3820{
3821 local ns="${1}"
3822 local exp="${2}"
3823 local check="${3}"
3824
3825 print_check "dump addrs ${check}"
3826
3827 if mptcp_lib_kallsyms_has "mptcp_userspace_pm_dump_addr$"; then
3828 check_output "userspace_pm_dump ${ns}" "${exp}"
3829 else
3830 print_skip
3831 fi
3832}
3833
3834userspace_pm_chk_get_addr()
3835{
3836 local ns="${1}"
3837 local id="${2}"
3838 local exp="${3}"
3839
3840 print_check "get id ${id} addr"
3841
3842 if mptcp_lib_kallsyms_has "mptcp_userspace_pm_get_addr$"; then
3843 check_output "userspace_pm_get_addr ${ns} ${id}" "${exp}"
3844 else
3845 print_skip
3846 fi
3847}
3848
3849# $1: ns ; $2: event type ; $3: count ; [ $4: attr ; $5: attr count ]
3850chk_evt_nr()
3851{
3852 local ns=${1}
3853 local evt_name="${2}"
3854 local exp="${3}"
3855 local attr="${4}"
3856 local attr_exp="${5}"
3857
3858 local evts="${evts_ns1}"
3859 local evt="${!evt_name}"
3860 local attr_name
3861 local count
3862
3863 if [ -n "${attr}" ]; then
3864 attr_name=", ${attr}: ${attr_exp}"
3865 fi
3866
3867 evt_name="${evt_name:16}" # without MPTCP_LIB_EVENT_
3868 [ "${ns}" == "ns2" ] && evts="${evts_ns2}"
3869
3870 print_check "event ${ns} ${evt_name} (${exp}${attr_name})"
3871
3872 if [[ "${evt_name}" = "LISTENER_"* ]] &&
3873 ! mptcp_lib_kallsyms_has "mptcp_event_pm_listener$"; then
3874 print_skip "event not supported"
3875 return
3876 fi
3877
3878 count=$(grep -cw "type:${evt}" "${evts}")
3879 if [ "${count}" != "${exp}" ]; then
3880 fail_test "got ${count} events, expected ${exp}"
3881 cat "${evts}"
3882 return
3883 elif [ -z "${attr}" ]; then
3884 print_ok
3885 return
3886 fi
3887
3888 count=$(grep -w "type:${evt}" "${evts}" | grep -c ",${attr}:")
3889 if [ "${count}" != "${attr_exp}" ]; then
3890 fail_test "got ${count} event attributes, expected ${attr_exp}"
3891 grep -w "type:${evt}" "${evts}"
3892 else
3893 print_ok
3894 fi
3895}
3896
3897# $1: ns ; $2: event type ; $3: expected count
3898wait_event()
3899{
3900 local ns="${1}"
3901 local evt_name="${2}"
3902 local exp="${3}"
3903
3904 local evt="${!evt_name}"
3905 local evts="${evts_ns1}"
3906 local count
3907
3908 [ "${ns}" == "ns2" ] && evts="${evts_ns2}"
3909
3910 for _ in $(seq 100); do
3911 count=$(grep -cw "type:${evt}" "${evts}")
3912 [ "${count}" -ge "${exp}" ] && break
3913 sleep 0.1
3914 done
3915}
3916
3917userspace_tests()
3918{
3919 # userspace pm type prevents add_addr
3920 if reset "userspace pm type prevents add_addr" &&
3921 continue_if mptcp_lib_has_file '/proc/sys/net/mptcp/pm_type'; then
3922 set_userspace_pm $ns1
3923 pm_nl_set_limits $ns1 0 2
3924 pm_nl_set_limits $ns2 0 2
3925 pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
3926 run_tests $ns1 $ns2 10.0.1.1
3927 chk_join_nr 0 0 0
3928 chk_add_nr 0 0
3929 fi
3930
3931 # userspace pm type does not echo add_addr without daemon
3932 if reset "userspace pm no echo w/o daemon" &&
3933 continue_if mptcp_lib_has_file '/proc/sys/net/mptcp/pm_type'; then
3934 set_userspace_pm $ns2
3935 pm_nl_set_limits $ns1 0 2
3936 pm_nl_set_limits $ns2 0 2
3937 pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
3938 run_tests $ns1 $ns2 10.0.1.1
3939 chk_join_nr 0 0 0
3940 chk_add_nr 1 0
3941 fi
3942
3943 # userspace pm type rejects join
3944 if reset "userspace pm type rejects join" &&
3945 continue_if mptcp_lib_has_file '/proc/sys/net/mptcp/pm_type'; then
3946 set_userspace_pm $ns1
3947 pm_nl_set_limits $ns1 1 1
3948 pm_nl_set_limits $ns2 1 1
3949 pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
3950 run_tests $ns1 $ns2 10.0.1.1
3951 join_syn_rej=1 \
3952 chk_join_nr 1 1 0
3953 fi
3954
3955 # userspace pm type does not send join
3956 if reset "userspace pm type does not send join" &&
3957 continue_if mptcp_lib_has_file '/proc/sys/net/mptcp/pm_type'; then
3958 set_userspace_pm $ns2
3959 pm_nl_set_limits $ns1 1 1
3960 pm_nl_set_limits $ns2 1 1
3961 pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
3962 run_tests $ns1 $ns2 10.0.1.1
3963 chk_join_nr 0 0 0
3964 fi
3965
3966 # userspace pm type prevents mp_prio
3967 if reset "userspace pm type prevents mp_prio" &&
3968 continue_if mptcp_lib_has_file '/proc/sys/net/mptcp/pm_type'; then
3969 set_userspace_pm $ns1
3970 pm_nl_set_limits $ns1 1 1
3971 pm_nl_set_limits $ns2 1 1
3972 pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
3973 sflags=backup speed=slow \
3974 run_tests $ns1 $ns2 10.0.1.1
3975 join_syn_rej=1 \
3976 chk_join_nr 1 1 0
3977 chk_prio_nr 0 0 0 0
3978 fi
3979
3980 # userspace pm type prevents rm_addr
3981 if reset "userspace pm type prevents rm_addr" &&
3982 continue_if mptcp_lib_has_file '/proc/sys/net/mptcp/pm_type'; then
3983 set_userspace_pm $ns1
3984 set_userspace_pm $ns2
3985 pm_nl_set_limits $ns1 0 1
3986 pm_nl_set_limits $ns2 0 1
3987 pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
3988 addr_nr_ns2=-1 speed=slow \
3989 run_tests $ns1 $ns2 10.0.1.1
3990 chk_join_nr 0 0 0
3991 chk_rm_nr 0 0
3992 fi
3993
3994 # userspace pm add & remove address
3995 if reset_with_events "userspace pm add & remove address" &&
3996 continue_if mptcp_lib_has_file '/proc/sys/net/mptcp/pm_type'; then
3997 set_userspace_pm $ns1
3998 pm_nl_set_limits $ns2 2 2
3999 { timeout_test=120 test_linkfail=128 speed=5 \
4000 run_tests $ns1 $ns2 10.0.1.1 & } 2>/dev/null
4001 local tests_pid=$!
4002 wait_mpj $ns1
4003 userspace_pm_add_addr $ns1 10.0.2.1 10
4004 userspace_pm_add_addr $ns1 10.0.3.1 20
4005 chk_join_nr 2 2 2
4006 chk_add_nr 2 2
4007 chk_mptcp_info subflows 2 subflows 2
4008 chk_subflows_total 3 3
4009 chk_mptcp_info add_addr_signal 2 add_addr_accepted 2
4010 userspace_pm_chk_dump_addr "${ns1}" \
4011 $'id 10 flags signal 10.0.2.1\nid 20 flags signal 10.0.3.1' \
4012 "signal"
4013 userspace_pm_chk_get_addr "${ns1}" "10" "id 10 flags signal 10.0.2.1"
4014 userspace_pm_chk_get_addr "${ns1}" "20" "id 20 flags signal 10.0.3.1"
4015 userspace_pm_rm_sf $ns1 "::ffff:10.0.2.1" $MPTCP_LIB_EVENT_SUB_ESTABLISHED
4016 userspace_pm_chk_dump_addr "${ns1}" \
4017 "id 20 flags signal 10.0.3.1" "after rm_sf 10"
4018 userspace_pm_rm_addr $ns1 20
4019 userspace_pm_chk_dump_addr "${ns1}" "" "after rm_addr 20"
4020 chk_rm_nr 1 1 invert
4021 chk_mptcp_info subflows 0 subflows 0
4022 chk_subflows_total 1 1
4023 kill_events_pids
4024 mptcp_lib_kill_group_wait $tests_pid
4025 fi
4026
4027 # userspace pm create destroy subflow
4028 if reset_with_events "userspace pm create destroy subflow" &&
4029 continue_if mptcp_lib_has_file '/proc/sys/net/mptcp/pm_type'; then
4030 set_userspace_pm $ns2
4031 pm_nl_set_limits $ns1 0 1
4032 { timeout_test=120 test_linkfail=128 speed=5 \
4033 run_tests $ns1 $ns2 10.0.1.1 & } 2>/dev/null
4034 local tests_pid=$!
4035 wait_mpj $ns2
4036 userspace_pm_add_sf $ns2 10.0.3.2 20
4037 chk_join_nr 1 1 1
4038 chk_mptcp_info subflows 1 subflows 1
4039 chk_subflows_total 2 2
4040 userspace_pm_chk_dump_addr "${ns2}" \
4041 "id 20 flags subflow 10.0.3.2" \
4042 "subflow"
4043 userspace_pm_chk_get_addr "${ns2}" "20" "id 20 flags subflow 10.0.3.2"
4044 userspace_pm_rm_sf $ns2 10.0.3.2 $MPTCP_LIB_EVENT_SUB_ESTABLISHED
4045 userspace_pm_chk_dump_addr "${ns2}" \
4046 "" \
4047 "after rm_sf 20"
4048 chk_rm_nr 0 1
4049 chk_mptcp_info subflows 0 subflows 0
4050 chk_subflows_total 1 1
4051 kill_events_pids
4052 mptcp_lib_kill_group_wait $tests_pid
4053 fi
4054
4055 # userspace pm create id 0 subflow
4056 if reset_with_events "userspace pm create id 0 subflow" &&
4057 continue_if mptcp_lib_has_file '/proc/sys/net/mptcp/pm_type'; then
4058 set_userspace_pm $ns2
4059 pm_nl_set_limits $ns1 0 1
4060 { timeout_test=120 test_linkfail=128 speed=5 \
4061 run_tests $ns1 $ns2 10.0.1.1 & } 2>/dev/null
4062 local tests_pid=$!
4063 wait_mpj $ns2
4064 chk_mptcp_info subflows 0 subflows 0
4065 chk_subflows_total 1 1
4066 userspace_pm_add_sf $ns2 10.0.3.2 0
4067 userspace_pm_chk_dump_addr "${ns2}" \
4068 "id 0 flags subflow 10.0.3.2" "id 0 subflow"
4069 chk_join_nr 1 1 1
4070 chk_mptcp_info subflows 1 subflows 1
4071 chk_subflows_total 2 2
4072 kill_events_pids
4073 mptcp_lib_kill_group_wait $tests_pid
4074 fi
4075
4076 # userspace pm remove initial subflow
4077 if reset_with_events "userspace pm remove initial subflow" &&
4078 continue_if mptcp_lib_has_file '/proc/sys/net/mptcp/pm_type'; then
4079 set_userspace_pm $ns2
4080 pm_nl_set_limits $ns1 0 1
4081 { timeout_test=120 test_linkfail=128 speed=5 \
4082 run_tests $ns1 $ns2 10.0.1.1 & } 2>/dev/null
4083 local tests_pid=$!
4084 wait_mpj $ns2
4085 userspace_pm_add_sf $ns2 10.0.3.2 20
4086 chk_join_nr 1 1 1
4087 chk_mptcp_info subflows 1 subflows 1
4088 chk_subflows_total 2 2
4089 userspace_pm_rm_sf $ns2 10.0.1.2
4090 # we don't look at the counter linked to the RM_ADDR but
4091 # to the one linked to the subflows that have been removed
4092 chk_rm_nr 0 1
4093 chk_rst_nr 0 0 invert
4094 chk_mptcp_info subflows 1 subflows 1
4095 chk_subflows_total 1 1
4096 kill_events_pids
4097 mptcp_lib_kill_group_wait $tests_pid
4098 fi
4099
4100 # userspace pm send RM_ADDR for ID 0
4101 if reset_with_events "userspace pm send RM_ADDR for ID 0" &&
4102 continue_if mptcp_lib_has_file '/proc/sys/net/mptcp/pm_type'; then
4103 set_userspace_pm $ns1
4104 pm_nl_set_limits $ns2 1 1
4105 { timeout_test=120 test_linkfail=128 speed=5 \
4106 run_tests $ns1 $ns2 10.0.1.1 & } 2>/dev/null
4107 local tests_pid=$!
4108 wait_mpj $ns1
4109 userspace_pm_add_addr $ns1 10.0.2.1 10
4110 chk_join_nr 1 1 1
4111 chk_add_nr 1 1
4112 chk_mptcp_info subflows 1 subflows 1
4113 chk_subflows_total 2 2
4114 chk_mptcp_info add_addr_signal 1 add_addr_accepted 1
4115 userspace_pm_rm_addr $ns1 0
4116 # we don't look at the counter linked to the subflows that
4117 # have been removed but to the one linked to the RM_ADDR
4118 chk_rm_nr 1 0 invert
4119 chk_rst_nr 0 0 invert
4120 chk_mptcp_info subflows 1 subflows 1
4121 chk_subflows_total 1 1
4122 kill_events_pids
4123 mptcp_lib_kill_group_wait $tests_pid
4124 fi
4125
4126 # userspace pm no duplicated spurious close events after an error
4127 if reset_with_events "userspace pm no dup close events after error" &&
4128 continue_if mptcp_lib_has_file '/proc/sys/net/mptcp/pm_type'; then
4129 set_userspace_pm $ns2
4130 pm_nl_set_limits $ns1 0 2
4131 { timeout_test=120 test_linkfail=128 speed=slow \
4132 run_tests $ns1 $ns2 10.0.1.1 & } 2>/dev/null
4133 local tests_pid=$!
4134 wait_event ns2 MPTCP_LIB_EVENT_ESTABLISHED 1
4135 userspace_pm_add_sf $ns2 10.0.3.2 20
4136 chk_mptcp_info subflows 1 subflows 1
4137 chk_subflows_total 2 2
4138
4139 # force quick loss
4140 ip netns exec $ns2 sysctl -q net.ipv4.tcp_syn_retries=1
4141 if ip netns exec "${ns1}" ${iptables} -A INPUT -s "10.0.1.2" \
4142 -p tcp --tcp-option 30 -j REJECT --reject-with tcp-reset &&
4143 ip netns exec "${ns2}" ${iptables} -A INPUT -d "10.0.1.2" \
4144 -p tcp --tcp-option 30 -j REJECT --reject-with tcp-reset; then
4145 wait_event ns2 MPTCP_LIB_EVENT_SUB_CLOSED 1
4146 wait_event ns1 MPTCP_LIB_EVENT_SUB_CLOSED 1
4147 chk_subflows_total 1 1
4148 userspace_pm_add_sf $ns2 10.0.1.2 0
4149 wait_event ns2 MPTCP_LIB_EVENT_SUB_CLOSED 2
4150 chk_evt_nr ns2 MPTCP_LIB_EVENT_SUB_CLOSED 2 error 2
4151 fi
4152 kill_events_pids
4153 mptcp_lib_kill_group_wait $tests_pid
4154 fi
4155}
4156
4157endpoint_tests()
4158{
4159 # subflow_rebuild_header is needed to support the implicit flag
4160 # userspace pm type prevents add_addr
4161 if reset "implicit EP" &&
4162 continue_if mptcp_lib_kallsyms_has "subflow_rebuild_header$"; then
4163 pm_nl_set_limits $ns1 2 2
4164 pm_nl_set_limits $ns2 2 2
4165 pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
4166 { timeout_test=120 test_linkfail=128 speed=slow \
4167 run_tests $ns1 $ns2 10.0.1.1 & } 2>/dev/null
4168 local tests_pid=$!
4169
4170 wait_mpj $ns1
4171 pm_nl_check_endpoint "creation" \
4172 $ns2 10.0.2.2 id 1 flags implicit
4173 chk_mptcp_info subflows 1 subflows 1
4174 chk_mptcp_info add_addr_signal 1 add_addr_accepted 1
4175
4176 pm_nl_add_endpoint $ns2 10.0.2.2 id 33 2>/dev/null
4177 pm_nl_check_endpoint "ID change is prevented" \
4178 $ns2 10.0.2.2 id 1 flags implicit
4179
4180 pm_nl_add_endpoint $ns2 10.0.2.2 flags signal
4181 pm_nl_check_endpoint "modif is allowed" \
4182 $ns2 10.0.2.2 id 1 flags signal
4183 mptcp_lib_kill_group_wait $tests_pid
4184 fi
4185
4186 if reset_with_tcp_filter "delete and re-add" ns2 10.0.3.2 REJECT OUTPUT &&
4187 continue_if mptcp_lib_kallsyms_has "subflow_rebuild_header$"; then
4188 start_events
4189 pm_nl_set_limits $ns1 0 3
4190 pm_nl_set_limits $ns2 0 3
4191 pm_nl_add_endpoint $ns2 10.0.1.2 id 1 dev ns2eth1 flags subflow
4192 pm_nl_add_endpoint $ns2 10.0.2.2 id 2 dev ns2eth2 flags subflow
4193 { timeout_test=120 test_linkfail=128 speed=5 \
4194 run_tests $ns1 $ns2 10.0.1.1 & } 2>/dev/null
4195 local tests_pid=$!
4196
4197 wait_mpj $ns2
4198 pm_nl_check_endpoint "creation" \
4199 $ns2 10.0.2.2 id 2 flags subflow dev ns2eth2
4200 chk_subflow_nr "before delete id 2" 2
4201 chk_mptcp_info subflows 1 subflows 1
4202
4203 pm_nl_del_endpoint $ns2 2 10.0.2.2
4204 sleep 0.5
4205 chk_subflow_nr "after delete id 2" 1
4206 chk_mptcp_info subflows 0 subflows 0
4207
4208 pm_nl_add_endpoint $ns2 10.0.2.2 id 2 dev ns2eth2 flags subflow
4209 wait_mpj $ns2
4210 chk_subflow_nr "after re-add id 2" 2
4211 chk_mptcp_info subflows 1 subflows 1
4212
4213 pm_nl_add_endpoint $ns2 10.0.3.2 id 3 flags subflow
4214 wait_attempt_fail $ns2
4215 chk_subflow_nr "after new reject" 2
4216 chk_mptcp_info subflows 1 subflows 1
4217
4218 ip netns exec "${ns2}" ${iptables} -D OUTPUT -s "10.0.3.2" -p tcp -j REJECT
4219 pm_nl_del_endpoint $ns2 3 10.0.3.2
4220 pm_nl_add_endpoint $ns2 10.0.3.2 id 3 flags subflow
4221 wait_mpj $ns2
4222 chk_subflow_nr "after no reject" 3
4223 chk_mptcp_info subflows 2 subflows 2
4224
4225 local i
4226 for i in $(seq 3); do
4227 pm_nl_del_endpoint $ns2 1 10.0.1.2
4228 sleep 0.5
4229 chk_subflow_nr "after delete id 0 ($i)" 2
4230 chk_mptcp_info subflows 2 subflows 2 # only decr for additional sf
4231
4232 pm_nl_add_endpoint $ns2 10.0.1.2 id 1 dev ns2eth1 flags subflow
4233 wait_mpj $ns2
4234 chk_subflow_nr "after re-add id 0 ($i)" 3
4235 chk_mptcp_info subflows 3 subflows 3
4236 done
4237
4238 mptcp_lib_kill_group_wait $tests_pid
4239
4240 kill_events_pids
4241 chk_evt_nr ns1 MPTCP_LIB_EVENT_LISTENER_CREATED 1
4242 chk_evt_nr ns1 MPTCP_LIB_EVENT_CREATED 1
4243 chk_evt_nr ns1 MPTCP_LIB_EVENT_ESTABLISHED 1
4244 chk_evt_nr ns1 MPTCP_LIB_EVENT_ANNOUNCED 0
4245 chk_evt_nr ns1 MPTCP_LIB_EVENT_REMOVED 4
4246 chk_evt_nr ns1 MPTCP_LIB_EVENT_SUB_ESTABLISHED 6
4247 chk_evt_nr ns1 MPTCP_LIB_EVENT_SUB_CLOSED 4
4248
4249 chk_evt_nr ns2 MPTCP_LIB_EVENT_CREATED 1
4250 chk_evt_nr ns2 MPTCP_LIB_EVENT_ESTABLISHED 1
4251 chk_evt_nr ns2 MPTCP_LIB_EVENT_ANNOUNCED 0
4252 chk_evt_nr ns2 MPTCP_LIB_EVENT_REMOVED 0
4253 chk_evt_nr ns2 MPTCP_LIB_EVENT_SUB_ESTABLISHED 6
4254 chk_evt_nr ns2 MPTCP_LIB_EVENT_SUB_CLOSED 5 # one has been closed before estab
4255
4256 join_syn_tx=7 \
4257 chk_join_nr 6 6 6
4258 chk_rm_nr 4 4
4259 fi
4260
4261 # remove and re-add
4262 if reset_with_events "delete re-add signal" &&
4263 continue_if mptcp_lib_kallsyms_has "subflow_rebuild_header$"; then
4264 ip netns exec $ns1 sysctl -q net.mptcp.add_addr_timeout=0
4265 pm_nl_set_limits $ns1 0 3
4266 pm_nl_set_limits $ns2 3 3
4267 pm_nl_add_endpoint $ns1 10.0.2.1 id 1 flags signal
4268 # broadcast IP: no packet for this address will be received on ns1
4269 pm_nl_add_endpoint $ns1 224.0.0.1 id 2 flags signal
4270 pm_nl_add_endpoint $ns1 10.0.1.1 id 42 flags signal
4271 { timeout_test=120 test_linkfail=128 speed=5 \
4272 run_tests $ns1 $ns2 10.0.1.1 & } 2>/dev/null
4273 local tests_pid=$!
4274
4275 wait_mpj $ns2
4276 pm_nl_check_endpoint "creation" \
4277 $ns1 10.0.2.1 id 1 flags signal
4278 chk_subflow_nr "before delete" 2
4279 chk_mptcp_info subflows 1 subflows 1
4280 chk_mptcp_info add_addr_signal 2 add_addr_accepted 1
4281
4282 pm_nl_del_endpoint $ns1 1 10.0.2.1
4283 pm_nl_del_endpoint $ns1 2 224.0.0.1
4284 sleep 0.5
4285 chk_subflow_nr "after delete" 1
4286 chk_mptcp_info subflows 0 subflows 0
4287 chk_mptcp_info add_addr_signal 0 add_addr_accepted 0
4288
4289 pm_nl_add_endpoint $ns1 10.0.2.1 id 1 flags signal
4290 pm_nl_add_endpoint $ns1 10.0.3.1 id 2 flags signal
4291 wait_mpj $ns2
4292 chk_subflow_nr "after re-add" 3
4293 chk_mptcp_info subflows 2 subflows 2
4294 chk_mptcp_info add_addr_signal 2 add_addr_accepted 2
4295
4296 pm_nl_del_endpoint $ns1 42 10.0.1.1
4297 sleep 0.5
4298 chk_subflow_nr "after delete ID 0" 2
4299 chk_mptcp_info subflows 2 subflows 2
4300 chk_mptcp_info add_addr_signal 2 add_addr_accepted 2
4301
4302 pm_nl_add_endpoint $ns1 10.0.1.1 id 99 flags signal
4303 wait_mpj $ns2
4304 chk_subflow_nr "after re-add ID 0" 3
4305 chk_mptcp_info subflows 3 subflows 3
4306 chk_mptcp_info add_addr_signal 3 add_addr_accepted 2
4307
4308 pm_nl_del_endpoint $ns1 99 10.0.1.1
4309 sleep 0.5
4310 chk_subflow_nr "after re-delete ID 0" 2
4311 chk_mptcp_info subflows 2 subflows 2
4312 chk_mptcp_info add_addr_signal 2 add_addr_accepted 2
4313
4314 pm_nl_add_endpoint $ns1 10.0.1.1 id 88 flags signal
4315 wait_mpj $ns2
4316 chk_subflow_nr "after re-re-add ID 0" 3
4317 chk_mptcp_info subflows 3 subflows 3
4318 chk_mptcp_info add_addr_signal 3 add_addr_accepted 2
4319 mptcp_lib_kill_group_wait $tests_pid
4320
4321 kill_events_pids
4322 chk_evt_nr ns1 MPTCP_LIB_EVENT_LISTENER_CREATED 1
4323 chk_evt_nr ns1 MPTCP_LIB_EVENT_CREATED 1
4324 chk_evt_nr ns1 MPTCP_LIB_EVENT_ESTABLISHED 1
4325 chk_evt_nr ns1 MPTCP_LIB_EVENT_ANNOUNCED 0
4326 chk_evt_nr ns1 MPTCP_LIB_EVENT_REMOVED 0
4327 chk_evt_nr ns1 MPTCP_LIB_EVENT_SUB_ESTABLISHED 5
4328 chk_evt_nr ns1 MPTCP_LIB_EVENT_SUB_CLOSED 3
4329
4330 chk_evt_nr ns2 MPTCP_LIB_EVENT_CREATED 1
4331 chk_evt_nr ns2 MPTCP_LIB_EVENT_ESTABLISHED 1
4332 chk_evt_nr ns2 MPTCP_LIB_EVENT_ANNOUNCED 6
4333 chk_evt_nr ns2 MPTCP_LIB_EVENT_REMOVED 4
4334 chk_evt_nr ns2 MPTCP_LIB_EVENT_SUB_ESTABLISHED 5
4335 chk_evt_nr ns2 MPTCP_LIB_EVENT_SUB_CLOSED 3
4336
4337 join_connect_err=1 \
4338 chk_join_nr 5 5 5
4339 chk_add_nr 6 6
4340 chk_rm_nr 4 3 invert
4341 fi
4342
4343 # flush and re-add
4344 if reset_with_tcp_filter "flush re-add" ns2 10.0.3.2 REJECT OUTPUT &&
4345 continue_if mptcp_lib_kallsyms_has "subflow_rebuild_header$"; then
4346 pm_nl_set_limits $ns1 0 2
4347 pm_nl_set_limits $ns2 1 2
4348 # broadcast IP: no packet for this address will be received on ns1
4349 pm_nl_add_endpoint $ns1 224.0.0.1 id 2 flags signal
4350 pm_nl_add_endpoint $ns2 10.0.3.2 id 3 flags subflow
4351 { timeout_test=120 test_linkfail=128 speed=20 \
4352 run_tests $ns1 $ns2 10.0.1.1 & } 2>/dev/null
4353 local tests_pid=$!
4354
4355 wait_attempt_fail $ns2
4356 chk_subflow_nr "before flush" 1
4357 chk_mptcp_info subflows 0 subflows 0
4358
4359 pm_nl_flush_endpoint $ns2
4360 pm_nl_flush_endpoint $ns1
4361 wait_rm_addr $ns2 0
4362 ip netns exec "${ns2}" ${iptables} -D OUTPUT -s "10.0.3.2" -p tcp -j REJECT
4363 pm_nl_add_endpoint $ns2 10.0.3.2 id 3 flags subflow
4364 wait_mpj $ns2
4365 pm_nl_add_endpoint $ns1 10.0.3.1 id 2 flags signal
4366 wait_mpj $ns2
4367 mptcp_lib_kill_group_wait $tests_pid
4368
4369 join_syn_tx=3 join_connect_err=1 \
4370 chk_join_nr 2 2 2
4371 chk_add_nr 2 2
4372 chk_rm_nr 1 0 invert
4373 fi
4374}
4375
4376# [$1: error message]
4377usage()
4378{
4379 if [ -n "${1}" ]; then
4380 echo "${1}"
4381 ret=${KSFT_FAIL}
4382 fi
4383
4384 echo "mptcp_join usage:"
4385
4386 local key
4387 for key in "${!all_tests[@]}"; do
4388 echo " -${key} ${all_tests[${key}]}"
4389 done
4390
4391 echo " -c capture pcap files"
4392 echo " -C enable data checksum"
4393 echo " -i use ip mptcp"
4394 echo " -h help"
4395
4396 echo "[test ids|names]"
4397
4398 exit ${ret}
4399}
4400
4401
4402# Use a "simple" array to force an specific order we cannot have with an associative one
4403all_tests_sorted=(
4404 f@subflows_tests
4405 e@subflows_error_tests
4406 s@signal_address_tests
4407 L@laminar_endp_tests
4408 l@link_failure_tests
4409 t@add_addr_timeout_tests
4410 r@remove_tests
4411 a@add_tests
4412 6@ipv6_tests
4413 4@v4mapped_tests
4414 M@mixed_tests
4415 b@backup_tests
4416 p@add_addr_ports_tests
4417 B@bind_tests
4418 k@syncookies_tests
4419 S@checksum_tests
4420 d@deny_join_id0_tests
4421 m@fullmesh_tests
4422 z@fastclose_tests
4423 F@fail_tests
4424 u@userspace_tests
4425 I@endpoint_tests
4426)
4427
4428all_tests_args=""
4429all_tests_names=()
4430for subtests in "${all_tests_sorted[@]}"; do
4431 key="${subtests%@*}"
4432 value="${subtests#*@}"
4433
4434 all_tests_args+="${key}"
4435 all_tests_names+=("${value}")
4436 all_tests[${key}]="${value}"
4437done
4438
4439tests=()
4440while getopts "${all_tests_args}cCih" opt; do
4441 case $opt in
4442 ["${all_tests_args}"])
4443 tests+=("${all_tests[${opt}]}")
4444 ;;
4445 c)
4446 capture=true
4447 ;;
4448 C)
4449 checksum=true
4450 ;;
4451 i)
4452 mptcp_lib_set_ip_mptcp
4453 ;;
4454 h)
4455 usage
4456 ;;
4457 *)
4458 usage "Unknown option: -${opt}"
4459 ;;
4460 esac
4461done
4462
4463shift $((OPTIND - 1))
4464
4465for arg in "${@}"; do
4466 if [[ "${arg}" =~ ^[0-9]+$ ]]; then
4467 only_tests_ids+=("${arg}")
4468 else
4469 only_tests_names+=("${arg}")
4470 fi
4471done
4472
4473if [ ${#tests[@]} -eq 0 ]; then
4474 tests=("${all_tests_names[@]}")
4475fi
4476
4477mptcp_lib_subtests_last_ts_reset
4478for subtests in "${tests[@]}"; do
4479 "${subtests}"
4480done
4481append_prev_results
4482
4483if [ ${ret} -ne 0 ]; then
4484 echo
4485 echo "${#failed_tests[@]} failure(s) has(ve) been detected:"
4486 for i in $(get_failed_tests_ids); do
4487 echo -e "\t- ${i}: ${failed_tests[${i}]}"
4488 done
4489 echo
4490fi
4491
4492mptcp_lib_result_print_all_tap
4493
4494exit $ret