1fda29d5d69f816b9bf5f573bbe0ce1d3faddd80
[platform/kernel/linux-rpi.git] / tools / testing / selftests / net / mptcp / mptcp_join.sh
1 #!/bin/bash
2 # SPDX-License-Identifier: GPL-2.0
3
4 ret=0
5 sin=""
6 sinfail=""
7 sout=""
8 cin=""
9 cinfail=""
10 cinsent=""
11 cout=""
12 ksft_skip=4
13 timeout_poll=30
14 timeout_test=$((timeout_poll * 2 + 1))
15 capture=0
16 checksum=0
17 ip_mptcp=0
18 do_all_tests=1
19 init=0
20
21 TEST_COUNT=0
22 nr_blank=40
23
24 # generated using "nfbpf_compile '(ip && (ip[54] & 0xf0) == 0x30) ||
25 #                                 (ip6 && (ip6[74] & 0xf0) == 0x30)'"
26 CBPF_MPTCP_SUBOPTION_ADD_ADDR="14,
27                                48 0 0 0,
28                                84 0 0 240,
29                                21 0 3 64,
30                                48 0 0 54,
31                                84 0 0 240,
32                                21 6 7 48,
33                                48 0 0 0,
34                                84 0 0 240,
35                                21 0 4 96,
36                                48 0 0 74,
37                                84 0 0 240,
38                                21 0 1 48,
39                                6 0 0 65535,
40                                6 0 0 0"
41
42 init_partial()
43 {
44         capout=$(mktemp)
45
46         rndh=$(mktemp -u XXXXXX)
47
48         ns1="ns1-$rndh"
49         ns2="ns2-$rndh"
50
51         for netns in "$ns1" "$ns2";do
52                 ip netns add $netns || exit $ksft_skip
53                 ip -net $netns link set lo up
54                 ip netns exec $netns sysctl -q net.mptcp.enabled=1
55                 ip netns exec $netns sysctl -q net.ipv4.conf.all.rp_filter=0
56                 ip netns exec $netns sysctl -q net.ipv4.conf.default.rp_filter=0
57                 if [ $checksum -eq 1 ]; then
58                         ip netns exec $netns sysctl -q net.mptcp.checksum_enabled=1
59                 fi
60         done
61
62         #  ns1              ns2
63         # ns1eth1    ns2eth1
64         # ns1eth2    ns2eth2
65         # ns1eth3    ns2eth3
66         # ns1eth4    ns2eth4
67
68         for i in `seq 1 4`; do
69                 ip link add ns1eth$i netns "$ns1" type veth peer name ns2eth$i netns "$ns2"
70                 ip -net "$ns1" addr add 10.0.$i.1/24 dev ns1eth$i
71                 ip -net "$ns1" addr add dead:beef:$i::1/64 dev ns1eth$i nodad
72                 ip -net "$ns1" link set ns1eth$i up
73
74                 ip -net "$ns2" addr add 10.0.$i.2/24 dev ns2eth$i
75                 ip -net "$ns2" addr add dead:beef:$i::2/64 dev ns2eth$i nodad
76                 ip -net "$ns2" link set ns2eth$i up
77
78                 # let $ns2 reach any $ns1 address from any interface
79                 ip -net "$ns2" route add default via 10.0.$i.1 dev ns2eth$i metric 10$i
80                 ip -net "$ns2" route add default via dead:beef:$i::1 dev ns2eth$i metric 10$i
81         done
82 }
83
84 init_shapers()
85 {
86         for i in `seq 1 4`; do
87                 tc -n $ns1 qdisc add dev ns1eth$i root netem rate 20mbit delay 1
88                 tc -n $ns2 qdisc add dev ns2eth$i root netem rate 20mbit delay 1
89         done
90 }
91
92 cleanup_partial()
93 {
94         rm -f "$capout"
95
96         for netns in "$ns1" "$ns2"; do
97                 ip netns del $netns
98                 rm -f /tmp/$netns.{nstat,out}
99         done
100 }
101
102 check_tools()
103 {
104         if ! ip -Version &> /dev/null; then
105                 echo "SKIP: Could not run test without ip tool"
106                 exit $ksft_skip
107         fi
108
109         if ! iptables -V &> /dev/null; then
110                 echo "SKIP: Could not run all tests without iptables tool"
111                 exit $ksft_skip
112         fi
113
114         if ! ip6tables -V &> /dev/null; then
115                 echo "SKIP: Could not run all tests without ip6tables tool"
116                 exit $ksft_skip
117         fi
118 }
119
120 init() {
121         init=1
122
123         check_tools
124
125         sin=$(mktemp)
126         sout=$(mktemp)
127         cin=$(mktemp)
128         cinsent=$(mktemp)
129         cout=$(mktemp)
130
131         trap cleanup EXIT
132
133         make_file "$cin" "client" 1
134         make_file "$sin" "server" 1
135 }
136
137 cleanup()
138 {
139         rm -f "$cin" "$cout" "$sinfail"
140         rm -f "$sin" "$sout" "$cinsent" "$cinfail"
141         cleanup_partial
142 }
143
144 reset()
145 {
146         if [ "${init}" != "1" ]; then
147                 init
148         else
149                 cleanup_partial
150         fi
151
152         init_partial
153 }
154
155 reset_with_cookies()
156 {
157         reset
158
159         for netns in "$ns1" "$ns2";do
160                 ip netns exec $netns sysctl -q net.ipv4.tcp_syncookies=2
161         done
162 }
163
164 reset_with_add_addr_timeout()
165 {
166         local ip="${1:-4}"
167         local tables
168
169         tables="iptables"
170         if [ $ip -eq 6 ]; then
171                 tables="ip6tables"
172         fi
173
174         reset
175
176         ip netns exec $ns1 sysctl -q net.mptcp.add_addr_timeout=1
177         ip netns exec $ns2 $tables -A OUTPUT -p tcp \
178                 -m tcp --tcp-option 30 \
179                 -m bpf --bytecode \
180                 "$CBPF_MPTCP_SUBOPTION_ADD_ADDR" \
181                 -j DROP
182 }
183
184 reset_with_checksum()
185 {
186         local ns1_enable=$1
187         local ns2_enable=$2
188
189         reset
190
191         ip netns exec $ns1 sysctl -q net.mptcp.checksum_enabled=$ns1_enable
192         ip netns exec $ns2 sysctl -q net.mptcp.checksum_enabled=$ns2_enable
193 }
194
195 reset_with_allow_join_id0()
196 {
197         local ns1_enable=$1
198         local ns2_enable=$2
199
200         reset
201
202         ip netns exec $ns1 sysctl -q net.mptcp.allow_join_initial_addr_port=$ns1_enable
203         ip netns exec $ns2 sysctl -q net.mptcp.allow_join_initial_addr_port=$ns2_enable
204 }
205
206 print_file_err()
207 {
208         ls -l "$1" 1>&2
209         echo "Trailing bytes are: "
210         tail -c 27 "$1"
211 }
212
213 check_transfer()
214 {
215         in=$1
216         out=$2
217         what=$3
218
219         cmp "$in" "$out" > /dev/null 2>&1
220         if [ $? -ne 0 ] ;then
221                 echo "[ FAIL ] $what does not match (in, out):"
222                 print_file_err "$in"
223                 print_file_err "$out"
224                 ret=1
225
226                 return 1
227         fi
228
229         return 0
230 }
231
232 do_ping()
233 {
234         listener_ns="$1"
235         connector_ns="$2"
236         connect_addr="$3"
237
238         ip netns exec ${connector_ns} ping -q -c 1 $connect_addr >/dev/null
239         if [ $? -ne 0 ] ; then
240                 echo "$listener_ns -> $connect_addr connectivity [ FAIL ]" 1>&2
241                 ret=1
242         fi
243 }
244
245 link_failure()
246 {
247         ns="$1"
248
249         if [ -z "$FAILING_LINKS" ]; then
250                 l=$((RANDOM%4))
251                 FAILING_LINKS=$((l+1))
252         fi
253
254         for l in $FAILING_LINKS; do
255                 veth="ns1eth$l"
256                 ip -net "$ns" link set "$veth" down
257         done
258 }
259
260 # $1: IP address
261 is_v6()
262 {
263         [ -z "${1##*:*}" ]
264 }
265
266 # $1: ns, $2: port
267 wait_local_port_listen()
268 {
269         local listener_ns="${1}"
270         local port="${2}"
271
272         local port_hex i
273
274         port_hex="$(printf "%04X" "${port}")"
275         for i in $(seq 10); do
276                 ip netns exec "${listener_ns}" cat /proc/net/tcp* | \
277                         awk "BEGIN {rc=1} {if (\$2 ~ /:${port_hex}\$/ && \$4 ~ /0A/) {rc=0; exit}} END {exit rc}" &&
278                         break
279                 sleep 0.1
280         done
281 }
282
283 rm_addr_count()
284 {
285         ns=${1}
286
287         ip netns exec ${ns} nstat -as | grep MPTcpExtRmAddr | awk '{print $2}'
288 }
289
290 # $1: ns, $2: old rm_addr counter in $ns
291 wait_rm_addr()
292 {
293         local ns="${1}"
294         local old_cnt="${2}"
295         local cnt
296         local i
297
298         for i in $(seq 10); do
299                 cnt=$(rm_addr_count ${ns})
300                 [ "$cnt" = "${old_cnt}" ] || break
301                 sleep 0.1
302         done
303 }
304
305 pm_nl_set_limits()
306 {
307         local ns=$1
308         local addrs=$2
309         local subflows=$3
310
311         if [ $ip_mptcp -eq 1 ]; then
312                 ip -n $ns mptcp limits set add_addr_accepted $addrs subflows $subflows
313         else
314                 ip netns exec $ns ./pm_nl_ctl limits $addrs $subflows
315         fi
316 }
317
318 pm_nl_add_endpoint()
319 {
320         local ns=$1
321         local addr=$2
322         local flags
323         local port
324         local dev
325         local id
326         local nr=2
327
328         for p in $@
329         do
330                 if [ $p = "flags" ]; then
331                         eval _flags=\$"$nr"
332                         [ ! -z $_flags ]; flags="flags $_flags"
333                 fi
334                 if [ $p = "dev" ]; then
335                         eval _dev=\$"$nr"
336                         [ ! -z $_dev ]; dev="dev $_dev"
337                 fi
338                 if [ $p = "id" ]; then
339                         eval _id=\$"$nr"
340                         [ ! -z $_id ]; id="id $_id"
341                 fi
342                 if [ $p = "port" ]; then
343                         eval _port=\$"$nr"
344                         [ ! -z $_port ]; port="port $_port"
345                 fi
346
347                 let nr+=1
348         done
349
350         if [ $ip_mptcp -eq 1 ]; then
351                 ip -n $ns mptcp endpoint add $addr ${_flags//","/" "} $dev $id $port
352         else
353                 ip netns exec $ns ./pm_nl_ctl add $addr $flags $dev $id $port
354         fi
355 }
356
357 pm_nl_del_endpoint()
358 {
359         local ns=$1
360         local id=$2
361         local addr=$3
362
363         if [ $ip_mptcp -eq 1 ]; then
364                 ip -n $ns mptcp endpoint delete id $id $addr
365         else
366                 ip netns exec $ns ./pm_nl_ctl del $id $addr
367         fi
368 }
369
370 pm_nl_flush_endpoint()
371 {
372         local ns=$1
373
374         if [ $ip_mptcp -eq 1 ]; then
375                 ip -n $ns mptcp endpoint flush
376         else
377                 ip netns exec $ns ./pm_nl_ctl flush
378         fi
379 }
380
381 pm_nl_show_endpoints()
382 {
383         local ns=$1
384
385         if [ $ip_mptcp -eq 1 ]; then
386                 ip -n $ns mptcp endpoint show
387         else
388                 ip netns exec $ns ./pm_nl_ctl dump
389         fi
390 }
391
392 pm_nl_change_endpoint()
393 {
394         local ns=$1
395         local id=$2
396         local flags=$3
397
398         if [ $ip_mptcp -eq 1 ]; then
399                 ip -n $ns mptcp endpoint change id $id ${flags//","/" "}
400         else
401                 ip netns exec $ns ./pm_nl_ctl set id $id flags $flags
402         fi
403 }
404
405 do_transfer()
406 {
407         listener_ns="$1"
408         connector_ns="$2"
409         cl_proto="$3"
410         srv_proto="$4"
411         connect_addr="$5"
412         test_link_fail="$6"
413         addr_nr_ns1="$7"
414         addr_nr_ns2="$8"
415         speed="$9"
416         sflags="${10}"
417
418         port=$((10000+$TEST_COUNT))
419         TEST_COUNT=$((TEST_COUNT+1))
420
421         :> "$cout"
422         :> "$sout"
423         :> "$capout"
424
425         if [ $capture -eq 1 ]; then
426                 if [ -z $SUDO_USER ] ; then
427                         capuser=""
428                 else
429                         capuser="-Z $SUDO_USER"
430                 fi
431
432                 capfile=$(printf "mp_join-%02u-%s.pcap" "$TEST_COUNT" "${listener_ns}")
433
434                 echo "Capturing traffic for test $TEST_COUNT into $capfile"
435                 ip netns exec ${listener_ns} tcpdump -i any -s 65535 -B 32768 $capuser -w $capfile > "$capout" 2>&1 &
436                 cappid=$!
437
438                 sleep 1
439         fi
440
441         NSTAT_HISTORY=/tmp/${listener_ns}.nstat ip netns exec ${listener_ns} \
442                 nstat -n
443         NSTAT_HISTORY=/tmp/${connector_ns}.nstat ip netns exec ${connector_ns} \
444                 nstat -n
445
446         local extra_args
447         if [ $speed = "fast" ]; then
448                 extra_args="-j"
449         elif [ $speed = "slow" ]; then
450                 extra_args="-r 50"
451         elif [[ $speed = "speed_"* ]]; then
452                 extra_args="-r ${speed:6}"
453         fi
454
455         local local_addr
456         if is_v6 "${connect_addr}"; then
457                 local_addr="::"
458         else
459                 local_addr="0.0.0.0"
460         fi
461
462         if [ "$test_link_fail" -gt 1 ];then
463                 timeout ${timeout_test} \
464                         ip netns exec ${listener_ns} \
465                                 ./mptcp_connect -t ${timeout_poll} -l -p $port -s ${srv_proto} \
466                                         $extra_args ${local_addr} < "$sinfail" > "$sout" &
467         else
468                 timeout ${timeout_test} \
469                         ip netns exec ${listener_ns} \
470                                 ./mptcp_connect -t ${timeout_poll} -l -p $port -s ${srv_proto} \
471                                         $extra_args ${local_addr} < "$sin" > "$sout" &
472         fi
473         spid=$!
474
475         wait_local_port_listen "${listener_ns}" "${port}"
476
477         if [ "$test_link_fail" -eq 0 ];then
478                 timeout ${timeout_test} \
479                         ip netns exec ${connector_ns} \
480                                 ./mptcp_connect -t ${timeout_poll} -p $port -s ${cl_proto} \
481                                         $extra_args $connect_addr < "$cin" > "$cout" &
482         elif [ "$test_link_fail" -eq 1 ] || [ "$test_link_fail" -eq 2 ];then
483                 ( cat "$cinfail" ; sleep 2; link_failure $listener_ns ; cat "$cinfail" ) | \
484                         tee "$cinsent" | \
485                         timeout ${timeout_test} \
486                                 ip netns exec ${connector_ns} \
487                                         ./mptcp_connect -t ${timeout_poll} -p $port -s ${cl_proto} \
488                                                 $extra_args $connect_addr > "$cout" &
489         else
490                 cat "$cinfail" | tee "$cinsent" | \
491                         timeout ${timeout_test} \
492                                 ip netns exec ${connector_ns} \
493                                         ./mptcp_connect -t ${timeout_poll} -p $port -s ${cl_proto} \
494                                                 $extra_args $connect_addr > "$cout" &
495         fi
496         cpid=$!
497
498         # let the mptcp subflow be established in background before
499         # do endpoint manipulation
500         [ $addr_nr_ns1 = "0" -a $addr_nr_ns2 = "0" ] || sleep 1
501
502         if [ $addr_nr_ns1 -gt 0 ]; then
503                 let add_nr_ns1=addr_nr_ns1
504                 counter=2
505                 while [ $add_nr_ns1 -gt 0 ]; do
506                         local addr
507                         if is_v6 "${connect_addr}"; then
508                                 addr="dead:beef:$counter::1"
509                         else
510                                 addr="10.0.$counter.1"
511                         fi
512                         pm_nl_add_endpoint $ns1 $addr flags signal
513                         let counter+=1
514                         let add_nr_ns1-=1
515                 done
516         elif [ $addr_nr_ns1 -lt 0 ]; then
517                 let rm_nr_ns1=-addr_nr_ns1
518                 if [ $rm_nr_ns1 -lt 8 ]; then
519                         counter=0
520                         pm_nl_show_endpoints ${listener_ns} | while read line; do
521                                 local arr=($line)
522                                 local nr=0
523
524                                 for i in ${arr[@]}; do
525                                         if [ $i = "id" ]; then
526                                                 if [ $counter -eq $rm_nr_ns1 ]; then
527                                                         break
528                                                 fi
529                                                 id=${arr[$nr+1]}
530                                                 rm_addr=$(rm_addr_count ${connector_ns})
531                                                 pm_nl_del_endpoint ${listener_ns} $id
532                                                 wait_rm_addr ${connector_ns} ${rm_addr}
533                                                 let counter+=1
534                                         fi
535                                         let nr+=1
536                                 done
537                         done
538                 elif [ $rm_nr_ns1 -eq 8 ]; then
539                         pm_nl_flush_endpoint ${listener_ns}
540                 elif [ $rm_nr_ns1 -eq 9 ]; then
541                         pm_nl_del_endpoint ${listener_ns} 0 ${connect_addr}
542                 fi
543         fi
544
545         flags="subflow"
546         if [[ "${addr_nr_ns2}" = "fullmesh_"* ]]; then
547                 flags="${flags},fullmesh"
548                 addr_nr_ns2=${addr_nr_ns2:9}
549         fi
550
551         # if newly added endpoints must be deleted, give the background msk
552         # some time to created them
553         [ $addr_nr_ns1 -gt 0 -a $addr_nr_ns2 -lt 0 ] && sleep 1
554
555         if [ $addr_nr_ns2 -gt 0 ]; then
556                 let add_nr_ns2=addr_nr_ns2
557                 counter=3
558                 while [ $add_nr_ns2 -gt 0 ]; do
559                         local addr
560                         if is_v6 "${connect_addr}"; then
561                                 addr="dead:beef:$counter::2"
562                         else
563                                 addr="10.0.$counter.2"
564                         fi
565                         pm_nl_add_endpoint $ns2 $addr flags $flags
566                         let counter+=1
567                         let add_nr_ns2-=1
568                 done
569         elif [ $addr_nr_ns2 -lt 0 ]; then
570                 let rm_nr_ns2=-addr_nr_ns2
571                 if [ $rm_nr_ns2 -lt 8 ]; then
572                         counter=0
573                         pm_nl_show_endpoints ${connector_ns} | while read line; do
574                                 local arr=($line)
575                                 local nr=0
576
577                                 for i in ${arr[@]}; do
578                                         if [ $i = "id" ]; then
579                                                 if [ $counter -eq $rm_nr_ns2 ]; then
580                                                         break
581                                                 fi
582                                                 # rm_addr are serialized, allow the previous one to
583                                                 # complete
584                                                 id=${arr[$nr+1]}
585                                                 rm_addr=$(rm_addr_count ${listener_ns})
586                                                 pm_nl_del_endpoint ${connector_ns} $id
587                                                 wait_rm_addr ${listener_ns} ${rm_addr}
588                                                 let counter+=1
589                                         fi
590                                         let nr+=1
591                                 done
592                         done
593                 elif [ $rm_nr_ns2 -eq 8 ]; then
594                         pm_nl_flush_endpoint ${connector_ns}
595                 elif [ $rm_nr_ns2 -eq 9 ]; then
596                         local addr
597                         if is_v6 "${connect_addr}"; then
598                                 addr="dead:beef:1::2"
599                         else
600                                 addr="10.0.1.2"
601                         fi
602                         pm_nl_del_endpoint ${connector_ns} 0 $addr
603                 fi
604         fi
605
606         if [ ! -z $sflags ]; then
607                 sleep 1
608                 for netns in "$ns1" "$ns2"; do
609                         pm_nl_show_endpoints $netns | while read line; do
610                                 local arr=($line)
611                                 local nr=0
612                                 local id
613
614                                 for i in ${arr[@]}; do
615                                         if [ $i = "id" ]; then
616                                                 id=${arr[$nr+1]}
617                                         fi
618                                         let nr+=1
619                                 done
620                                 pm_nl_change_endpoint $netns $id $sflags
621                         done
622                 done
623         fi
624
625         wait $cpid
626         retc=$?
627         wait $spid
628         rets=$?
629
630         if [ $capture -eq 1 ]; then
631             sleep 1
632             kill $cappid
633         fi
634
635         NSTAT_HISTORY=/tmp/${listener_ns}.nstat ip netns exec ${listener_ns} \
636                 nstat | grep Tcp > /tmp/${listener_ns}.out
637         NSTAT_HISTORY=/tmp/${connector_ns}.nstat ip netns exec ${connector_ns} \
638                 nstat | grep Tcp > /tmp/${connector_ns}.out
639
640         if [ ${rets} -ne 0 ] || [ ${retc} -ne 0 ]; then
641                 echo " client exit code $retc, server $rets" 1>&2
642                 echo -e "\nnetns ${listener_ns} socket stat for ${port}:" 1>&2
643                 ip netns exec ${listener_ns} ss -Menita 1>&2 -o "sport = :$port"
644                 cat /tmp/${listener_ns}.out
645                 echo -e "\nnetns ${connector_ns} socket stat for ${port}:" 1>&2
646                 ip netns exec ${connector_ns} ss -Menita 1>&2 -o "dport = :$port"
647                 cat /tmp/${connector_ns}.out
648
649                 cat "$capout"
650                 ret=1
651                 return 1
652         fi
653
654         if [ "$test_link_fail" -gt 1 ];then
655                 check_transfer $sinfail $cout "file received by client"
656         else
657                 check_transfer $sin $cout "file received by client"
658         fi
659         retc=$?
660         if [ "$test_link_fail" -eq 0 ];then
661                 check_transfer $cin $sout "file received by server"
662         else
663                 check_transfer $cinsent $sout "file received by server"
664         fi
665         rets=$?
666
667         if [ $retc -eq 0 ] && [ $rets -eq 0 ];then
668                 cat "$capout"
669                 return 0
670         fi
671
672         cat "$capout"
673         return 1
674 }
675
676 make_file()
677 {
678         name=$1
679         who=$2
680         size=$3
681
682         dd if=/dev/urandom of="$name" bs=1024 count=$size 2> /dev/null
683         echo -e "\nMPTCP_TEST_FILE_END_MARKER" >> "$name"
684
685         echo "Created $name (size $size KB) containing data sent by $who"
686 }
687
688 run_tests()
689 {
690         listener_ns="$1"
691         connector_ns="$2"
692         connect_addr="$3"
693         test_linkfail="${4:-0}"
694         addr_nr_ns1="${5:-0}"
695         addr_nr_ns2="${6:-0}"
696         speed="${7:-fast}"
697         sflags="${8:-""}"
698
699         # The values above 2 are reused to make test files
700         # with the given sizes (KB)
701         if [ "$test_linkfail" -gt 2 ]; then
702                 size=$test_linkfail
703
704                 if [ -z "$cinfail" ]; then
705                         cinfail=$(mktemp)
706                 fi
707                 make_file "$cinfail" "client" $size
708         # create the input file for the failure test when
709         # the first failure test run
710         elif [ "$test_linkfail" -ne 0 -a -z "$cinfail" ]; then
711                 # the client file must be considerably larger
712                 # of the maximum expected cwin value, or the
713                 # link utilization will be not predicable
714                 size=$((RANDOM%2))
715                 size=$((size+1))
716                 size=$((size*8192))
717                 size=$((size + ( $RANDOM % 8192) ))
718
719                 cinfail=$(mktemp)
720                 make_file "$cinfail" "client" $size
721         fi
722
723         if [ "$test_linkfail" -gt 2 ]; then
724                 size=$test_linkfail
725
726                 if [ -z "$sinfail" ]; then
727                         sinfail=$(mktemp)
728                 fi
729                 make_file "$sinfail" "server" $size
730         elif [ "$test_linkfail" -eq 2 -a -z "$sinfail" ]; then
731                 size=$((RANDOM%16))
732                 size=$((size+1))
733                 size=$((size*2048))
734
735                 sinfail=$(mktemp)
736                 make_file "$sinfail" "server" $size
737         fi
738
739         do_transfer ${listener_ns} ${connector_ns} MPTCP MPTCP ${connect_addr} \
740                 ${test_linkfail} ${addr_nr_ns1} ${addr_nr_ns2} ${speed} ${sflags}
741 }
742
743 dump_stats()
744 {
745         echo Server ns stats
746         ip netns exec $ns1 nstat -as | grep Tcp
747         echo Client ns stats
748         ip netns exec $ns2 nstat -as | grep Tcp
749 }
750
751 chk_csum_nr()
752 {
753         local msg=${1:-""}
754         local count
755         local dump_stats
756
757         if [ ! -z "$msg" ]; then
758                 printf "%03u" "$TEST_COUNT"
759         else
760                 echo -n "   "
761         fi
762         printf " %-36s %s" "$msg" "sum"
763         count=`ip netns exec $ns1 nstat -as | grep MPTcpExtDataCsumErr | awk '{print $2}'`
764         [ -z "$count" ] && count=0
765         if [ "$count" != 0 ]; then
766                 echo "[fail] got $count data checksum error[s] expected 0"
767                 ret=1
768                 dump_stats=1
769         else
770                 echo -n "[ ok ]"
771         fi
772         echo -n " - csum  "
773         count=`ip netns exec $ns2 nstat -as | grep MPTcpExtDataCsumErr | awk '{print $2}'`
774         [ -z "$count" ] && count=0
775         if [ "$count" != 0 ]; then
776                 echo "[fail] got $count data checksum error[s] expected 0"
777                 ret=1
778                 dump_stats=1
779         else
780                 echo "[ ok ]"
781         fi
782         [ "${dump_stats}" = 1 ] && dump_stats
783 }
784
785 chk_fail_nr()
786 {
787         local mp_fail_nr_tx=$1
788         local mp_fail_nr_rx=$2
789         local count
790         local dump_stats
791
792         printf "%-${nr_blank}s %s" " " "ftx"
793         count=`ip netns exec $ns1 nstat -as | grep MPTcpExtMPFailTx | awk '{print $2}'`
794         [ -z "$count" ] && count=0
795         if [ "$count" != "$mp_fail_nr_tx" ]; then
796                 echo "[fail] got $count MP_FAIL[s] TX expected $mp_fail_nr_tx"
797                 ret=1
798                 dump_stats=1
799         else
800                 echo -n "[ ok ]"
801         fi
802
803         echo -n " - frx   "
804         count=`ip netns exec $ns2 nstat -as | grep MPTcpExtMPFailRx | awk '{print $2}'`
805         [ -z "$count" ] && count=0
806         if [ "$count" != "$mp_fail_nr_rx" ]; then
807                 echo "[fail] got $count MP_FAIL[s] RX expected $mp_fail_nr_rx"
808                 ret=1
809                 dump_stats=1
810         else
811                 echo "[ ok ]"
812         fi
813
814         [ "${dump_stats}" = 1 ] && dump_stats
815 }
816
817 chk_fclose_nr()
818 {
819         local fclose_tx=$1
820         local fclose_rx=$2
821         local count
822         local dump_stats
823
824         printf "%-${nr_blank}s %s" " " "ctx"
825         count=$(ip netns exec $ns2 nstat -as | grep MPTcpExtMPFastcloseTx | awk '{print $2}')
826         [ -z "$count" ] && count=0
827         if [ "$count" != "$fclose_tx" ]; then
828                 echo "[fail] got $count MP_FASTCLOSE[s] TX expected $fclose_tx"
829                 ret=1
830                 dump_stats=1
831         else
832                 echo -n "[ ok ]"
833         fi
834
835         echo -n " - fclzrx"
836         count=$(ip netns exec $ns1 nstat -as | grep MPTcpExtMPFastcloseRx | awk '{print $2}')
837         [ -z "$count" ] && count=0
838         if [ "$count" != "$fclose_rx" ]; then
839                 echo "[fail] got $count MP_FASTCLOSE[s] RX expected $fclose_rx"
840                 ret=1
841                 dump_stats=1
842         else
843                 echo "[ ok ]"
844         fi
845
846         [ "${dump_stats}" = 1 ] && dump_stats
847 }
848
849 chk_rst_nr()
850 {
851         local rst_tx=$1
852         local rst_rx=$2
853         local ns_invert=${3:-""}
854         local count
855         local dump_stats
856         local ns_tx=$ns1
857         local ns_rx=$ns2
858         local extra_msg=""
859
860         if [[ $ns_invert = "invert" ]]; then
861                 ns_tx=$ns2
862                 ns_rx=$ns1
863                 extra_msg="   invert"
864         fi
865
866         printf "%-${nr_blank}s %s" " " "rtx"
867         count=$(ip netns exec $ns_tx nstat -as | grep MPTcpExtMPRstTx | awk '{print $2}')
868         [ -z "$count" ] && count=0
869         if [ "$count" != "$rst_tx" ]; then
870                 echo "[fail] got $count MP_RST[s] TX expected $rst_tx"
871                 ret=1
872                 dump_stats=1
873         else
874                 echo -n "[ ok ]"
875         fi
876
877         echo -n " - rstrx "
878         count=$(ip netns exec $ns_rx nstat -as | grep MPTcpExtMPRstRx | awk '{print $2}')
879         [ -z "$count" ] && count=0
880         if [ "$count" != "$rst_rx" ]; then
881                 echo "[fail] got $count MP_RST[s] RX expected $rst_rx"
882                 ret=1
883                 dump_stats=1
884         else
885                 echo -n "[ ok ]"
886         fi
887
888         [ "${dump_stats}" = 1 ] && dump_stats
889
890         echo "$extra_msg"
891 }
892
893 chk_join_nr()
894 {
895         local msg="$1"
896         local syn_nr=$2
897         local syn_ack_nr=$3
898         local ack_nr=$4
899         local count
900         local dump_stats
901         local with_cookie
902
903         printf "%03u %-36s %s" "$TEST_COUNT" "$msg" "syn"
904         count=`ip netns exec $ns1 nstat -as | grep MPTcpExtMPJoinSynRx | awk '{print $2}'`
905         [ -z "$count" ] && count=0
906         if [ "$count" != "$syn_nr" ]; then
907                 echo "[fail] got $count JOIN[s] syn expected $syn_nr"
908                 ret=1
909                 dump_stats=1
910         else
911                 echo -n "[ ok ]"
912         fi
913
914         echo -n " - synack"
915         with_cookie=`ip netns exec $ns2 sysctl -n net.ipv4.tcp_syncookies`
916         count=`ip netns exec $ns2 nstat -as | grep MPTcpExtMPJoinSynAckRx | awk '{print $2}'`
917         [ -z "$count" ] && count=0
918         if [ "$count" != "$syn_ack_nr" ]; then
919                 # simult connections exceeding the limit with cookie enabled could go up to
920                 # synack validation as the conn limit can be enforced reliably only after
921                 # the subflow creation
922                 if [ "$with_cookie" = 2 ] && [ "$count" -gt "$syn_ack_nr" ] && [ "$count" -le "$syn_nr" ]; then
923                         echo -n "[ ok ]"
924                 else
925                         echo "[fail] got $count JOIN[s] synack expected $syn_ack_nr"
926                         ret=1
927                         dump_stats=1
928                 fi
929         else
930                 echo -n "[ ok ]"
931         fi
932
933         echo -n " - ack"
934         count=`ip netns exec $ns1 nstat -as | grep MPTcpExtMPJoinAckRx | awk '{print $2}'`
935         [ -z "$count" ] && count=0
936         if [ "$count" != "$ack_nr" ]; then
937                 echo "[fail] got $count JOIN[s] ack expected $ack_nr"
938                 ret=1
939                 dump_stats=1
940         else
941                 echo "[ ok ]"
942         fi
943         [ "${dump_stats}" = 1 ] && dump_stats
944         if [ $checksum -eq 1 ]; then
945                 chk_csum_nr
946                 chk_fail_nr 0 0
947                 chk_rst_nr 0 0
948         fi
949 }
950
951 # a negative value for 'stale_max' means no upper bound:
952 # for bidirectional transfer, if one peer sleep for a while
953 # - as these tests do - we can have a quite high number of
954 # stale/recover conversions, proportional to
955 # sleep duration/ MPTCP-level RTX interval.
956 chk_stale_nr()
957 {
958         local ns=$1
959         local stale_min=$2
960         local stale_max=$3
961         local stale_delta=$4
962         local dump_stats
963         local stale_nr
964         local recover_nr
965
966         printf "%-${nr_blank}s %-18s" " " "stale"
967         stale_nr=`ip netns exec $ns nstat -as | grep MPTcpExtSubflowStale | awk '{print $2}'`
968         [ -z "$stale_nr" ] && stale_nr=0
969         recover_nr=`ip netns exec $ns nstat -as | grep MPTcpExtSubflowRecover | awk '{print $2}'`
970         [ -z "$recover_nr" ] && recover_nr=0
971
972         if [ $stale_nr -lt $stale_min ] ||
973            [ $stale_max -gt 0 -a $stale_nr -gt $stale_max ] ||
974            [ $((stale_nr - $recover_nr)) -ne $stale_delta ]; then
975                 echo "[fail] got $stale_nr stale[s] $recover_nr recover[s], " \
976                      " expected stale in range [$stale_min..$stale_max]," \
977                      " stale-recover delta $stale_delta "
978                 ret=1
979                 dump_stats=1
980         else
981                 echo "[ ok ]"
982         fi
983
984         if [ "${dump_stats}" = 1 ]; then
985                 echo $ns stats
986                 ip netns exec $ns ip -s link show
987                 ip netns exec $ns nstat -as | grep MPTcp
988         fi
989 }
990
991 chk_add_nr()
992 {
993         local add_nr=$1
994         local echo_nr=$2
995         local port_nr=${3:-0}
996         local syn_nr=${4:-$port_nr}
997         local syn_ack_nr=${5:-$port_nr}
998         local ack_nr=${6:-$port_nr}
999         local mis_syn_nr=${7:-0}
1000         local mis_ack_nr=${8:-0}
1001         local count
1002         local dump_stats
1003         local timeout
1004
1005         timeout=`ip netns exec $ns1 sysctl -n net.mptcp.add_addr_timeout`
1006
1007         printf "%-${nr_blank}s %s" " " "add"
1008         count=`ip netns exec $ns2 nstat -as MPTcpExtAddAddr | grep MPTcpExtAddAddr | awk '{print $2}'`
1009         [ -z "$count" ] && count=0
1010
1011         # if the test configured a short timeout tolerate greater then expected
1012         # add addrs options, due to retransmissions
1013         if [ "$count" != "$add_nr" ] && [ "$timeout" -gt 1 -o "$count" -lt "$add_nr" ]; then
1014                 echo "[fail] got $count ADD_ADDR[s] expected $add_nr"
1015                 ret=1
1016                 dump_stats=1
1017         else
1018                 echo -n "[ ok ]"
1019         fi
1020
1021         echo -n " - echo  "
1022         count=`ip netns exec $ns1 nstat -as | grep MPTcpExtEchoAdd | awk '{print $2}'`
1023         [ -z "$count" ] && count=0
1024         if [ "$count" != "$echo_nr" ]; then
1025                 echo "[fail] got $count ADD_ADDR echo[s] expected $echo_nr"
1026                 ret=1
1027                 dump_stats=1
1028         else
1029                 echo -n "[ ok ]"
1030         fi
1031
1032         if [ $port_nr -gt 0 ]; then
1033                 echo -n " - pt "
1034                 count=`ip netns exec $ns2 nstat -as | grep MPTcpExtPortAdd | awk '{print $2}'`
1035                 [ -z "$count" ] && count=0
1036                 if [ "$count" != "$port_nr" ]; then
1037                         echo "[fail] got $count ADD_ADDR[s] with a port-number expected $port_nr"
1038                         ret=1
1039                         dump_stats=1
1040                 else
1041                         echo "[ ok ]"
1042                 fi
1043
1044                 printf "%-${nr_blank}s %s" " " "syn"
1045                 count=`ip netns exec $ns1 nstat -as | grep MPTcpExtMPJoinPortSynRx |
1046                         awk '{print $2}'`
1047                 [ -z "$count" ] && count=0
1048                 if [ "$count" != "$syn_nr" ]; then
1049                         echo "[fail] got $count JOIN[s] syn with a different \
1050                                 port-number expected $syn_nr"
1051                         ret=1
1052                         dump_stats=1
1053                 else
1054                         echo -n "[ ok ]"
1055                 fi
1056
1057                 echo -n " - synack"
1058                 count=`ip netns exec $ns2 nstat -as | grep MPTcpExtMPJoinPortSynAckRx |
1059                         awk '{print $2}'`
1060                 [ -z "$count" ] && count=0
1061                 if [ "$count" != "$syn_ack_nr" ]; then
1062                         echo "[fail] got $count JOIN[s] synack with a different \
1063                                 port-number expected $syn_ack_nr"
1064                         ret=1
1065                         dump_stats=1
1066                 else
1067                         echo -n "[ ok ]"
1068                 fi
1069
1070                 echo -n " - ack"
1071                 count=`ip netns exec $ns1 nstat -as | grep MPTcpExtMPJoinPortAckRx |
1072                         awk '{print $2}'`
1073                 [ -z "$count" ] && count=0
1074                 if [ "$count" != "$ack_nr" ]; then
1075                         echo "[fail] got $count JOIN[s] ack with a different \
1076                                 port-number expected $ack_nr"
1077                         ret=1
1078                         dump_stats=1
1079                 else
1080                         echo "[ ok ]"
1081                 fi
1082
1083                 printf "%-${nr_blank}s %s" " " "syn"
1084                 count=`ip netns exec $ns1 nstat -as | grep MPTcpExtMismatchPortSynRx |
1085                         awk '{print $2}'`
1086                 [ -z "$count" ] && count=0
1087                 if [ "$count" != "$mis_syn_nr" ]; then
1088                         echo "[fail] got $count JOIN[s] syn with a mismatched \
1089                                 port-number expected $mis_syn_nr"
1090                         ret=1
1091                         dump_stats=1
1092                 else
1093                         echo -n "[ ok ]"
1094                 fi
1095
1096                 echo -n " - ack   "
1097                 count=`ip netns exec $ns1 nstat -as | grep MPTcpExtMismatchPortAckRx |
1098                         awk '{print $2}'`
1099                 [ -z "$count" ] && count=0
1100                 if [ "$count" != "$mis_ack_nr" ]; then
1101                         echo "[fail] got $count JOIN[s] ack with a mismatched \
1102                                 port-number expected $mis_ack_nr"
1103                         ret=1
1104                         dump_stats=1
1105                 else
1106                         echo "[ ok ]"
1107                 fi
1108         else
1109                 echo ""
1110         fi
1111
1112         [ "${dump_stats}" = 1 ] && dump_stats
1113 }
1114
1115 chk_rm_nr()
1116 {
1117         local rm_addr_nr=$1
1118         local rm_subflow_nr=$2
1119         local invert=${3:-""}
1120         local count
1121         local dump_stats
1122         local addr_ns
1123         local subflow_ns
1124
1125         if [ -z $invert ]; then
1126                 addr_ns=$ns1
1127                 subflow_ns=$ns2
1128         elif [ $invert = "invert" ]; then
1129                 addr_ns=$ns2
1130                 subflow_ns=$ns1
1131         fi
1132
1133         printf "%-${nr_blank}s %s" " " "rm "
1134         count=`ip netns exec $addr_ns nstat -as | grep MPTcpExtRmAddr | awk '{print $2}'`
1135         [ -z "$count" ] && count=0
1136         if [ "$count" != "$rm_addr_nr" ]; then
1137                 echo "[fail] got $count RM_ADDR[s] expected $rm_addr_nr"
1138                 ret=1
1139                 dump_stats=1
1140         else
1141                 echo -n "[ ok ]"
1142         fi
1143
1144         echo -n " - sf    "
1145         count=`ip netns exec $subflow_ns nstat -as | grep MPTcpExtRmSubflow | awk '{print $2}'`
1146         [ -z "$count" ] && count=0
1147         if [ "$count" != "$rm_subflow_nr" ]; then
1148                 echo "[fail] got $count RM_SUBFLOW[s] expected $rm_subflow_nr"
1149                 ret=1
1150                 dump_stats=1
1151         else
1152                 echo "[ ok ]"
1153         fi
1154
1155         [ "${dump_stats}" = 1 ] && dump_stats
1156 }
1157
1158 chk_prio_nr()
1159 {
1160         local mp_prio_nr_tx=$1
1161         local mp_prio_nr_rx=$2
1162         local count
1163         local dump_stats
1164
1165         printf "%-${nr_blank}s %s" " " "ptx"
1166         count=`ip netns exec $ns1 nstat -as | grep MPTcpExtMPPrioTx | awk '{print $2}'`
1167         [ -z "$count" ] && count=0
1168         if [ "$count" != "$mp_prio_nr_tx" ]; then
1169                 echo "[fail] got $count MP_PRIO[s] TX expected $mp_prio_nr_tx"
1170                 ret=1
1171                 dump_stats=1
1172         else
1173                 echo -n "[ ok ]"
1174         fi
1175
1176         echo -n " - prx   "
1177         count=`ip netns exec $ns1 nstat -as | grep MPTcpExtMPPrioRx | awk '{print $2}'`
1178         [ -z "$count" ] && count=0
1179         if [ "$count" != "$mp_prio_nr_rx" ]; then
1180                 echo "[fail] got $count MP_PRIO[s] RX expected $mp_prio_nr_rx"
1181                 ret=1
1182                 dump_stats=1
1183         else
1184                 echo "[ ok ]"
1185         fi
1186
1187         [ "${dump_stats}" = 1 ] && dump_stats
1188 }
1189
1190 chk_link_usage()
1191 {
1192         local ns=$1
1193         local link=$2
1194         local out=$3
1195         local expected_rate=$4
1196         local tx_link=`ip netns exec $ns cat /sys/class/net/$link/statistics/tx_bytes`
1197         local tx_total=`ls -l $out | awk '{print $5}'`
1198         local tx_rate=$((tx_link * 100 / $tx_total))
1199         local tolerance=5
1200
1201         printf "%-${nr_blank}s %-18s" " " "link usage"
1202         if [ $tx_rate -lt $((expected_rate - $tolerance)) -o \
1203              $tx_rate -gt $((expected_rate + $tolerance)) ]; then
1204                 echo "[fail] got $tx_rate% usage, expected $expected_rate%"
1205                 ret=1
1206         else
1207                 echo "[ ok ]"
1208         fi
1209 }
1210
1211 wait_for_tw()
1212 {
1213         local timeout_ms=$((timeout_poll * 1000))
1214         local time=0
1215         local ns=$1
1216
1217         while [ $time -lt $timeout_ms ]; do
1218                 local cnt=$(ip netns exec $ns nstat -as TcpAttemptFails | grep TcpAttemptFails | awk '{print $2}')
1219
1220                 [ "$cnt" = 1 ] && return 1
1221                 time=$((time + 100))
1222                 sleep 0.1
1223         done
1224         return 1
1225 }
1226
1227 subflows_tests()
1228 {
1229         reset
1230         run_tests $ns1 $ns2 10.0.1.1
1231         chk_join_nr "no JOIN" "0" "0" "0"
1232
1233         # subflow limited by client
1234         reset
1235         pm_nl_set_limits $ns1 0 0
1236         pm_nl_set_limits $ns2 0 0
1237         pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
1238         run_tests $ns1 $ns2 10.0.1.1
1239         chk_join_nr "single subflow, limited by client" 0 0 0
1240
1241         # subflow limited by server
1242         reset
1243         pm_nl_set_limits $ns1 0 0
1244         pm_nl_set_limits $ns2 0 1
1245         pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
1246         run_tests $ns1 $ns2 10.0.1.1
1247         chk_join_nr "single subflow, limited by server" 1 1 0
1248
1249         # subflow
1250         reset
1251         pm_nl_set_limits $ns1 0 1
1252         pm_nl_set_limits $ns2 0 1
1253         pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
1254         run_tests $ns1 $ns2 10.0.1.1
1255         chk_join_nr "single subflow" 1 1 1
1256
1257         # multiple subflows
1258         reset
1259         pm_nl_set_limits $ns1 0 2
1260         pm_nl_set_limits $ns2 0 2
1261         pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
1262         pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow
1263         run_tests $ns1 $ns2 10.0.1.1
1264         chk_join_nr "multiple subflows" 2 2 2
1265
1266         # multiple subflows limited by server
1267         reset
1268         pm_nl_set_limits $ns1 0 1
1269         pm_nl_set_limits $ns2 0 2
1270         pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
1271         pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow
1272         run_tests $ns1 $ns2 10.0.1.1
1273         chk_join_nr "multiple subflows, limited by server" 2 2 1
1274
1275         # single subflow, dev
1276         reset
1277         pm_nl_set_limits $ns1 0 1
1278         pm_nl_set_limits $ns2 0 1
1279         pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow dev ns2eth3
1280         run_tests $ns1 $ns2 10.0.1.1
1281         chk_join_nr "single subflow, dev" 1 1 1
1282 }
1283
1284 subflows_error_tests()
1285 {
1286         # If a single subflow is configured, and matches the MPC src
1287         # address, no additional subflow should be created
1288         reset
1289         pm_nl_set_limits $ns1 0 1
1290         pm_nl_set_limits $ns2 0 1
1291         pm_nl_add_endpoint $ns2 10.0.1.2 flags subflow
1292         run_tests $ns1 $ns2 10.0.1.1 0 0 0 slow
1293         chk_join_nr "no MPC reuse with single endpoint" 0 0 0
1294
1295         # multiple subflows, with subflow creation error
1296         reset
1297         pm_nl_set_limits $ns1 0 2
1298         pm_nl_set_limits $ns2 0 2
1299         pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
1300         pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow
1301         ip netns exec $ns1 iptables -A INPUT -s 10.0.3.2 -p tcp -j REJECT
1302         run_tests $ns1 $ns2 10.0.1.1 0 0 0 slow
1303         chk_join_nr "multi subflows, with failing subflow" 1 1 1
1304
1305         # multiple subflows, with subflow timeout on MPJ
1306         reset
1307         pm_nl_set_limits $ns1 0 2
1308         pm_nl_set_limits $ns2 0 2
1309         pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
1310         pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow
1311         ip netns exec $ns1 iptables -A INPUT -s 10.0.3.2 -p tcp -j DROP
1312         run_tests $ns1 $ns2 10.0.1.1 0 0 0 slow
1313         chk_join_nr "multi subflows, with subflow timeout" 1 1 1
1314
1315         # multiple subflows, check that the endpoint corresponding to
1316         # closed subflow (due to reset) is not reused if additional
1317         # subflows are added later
1318         reset
1319         pm_nl_set_limits $ns1 0 1
1320         pm_nl_set_limits $ns2 0 1
1321         pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
1322         ip netns exec $ns1 iptables -A INPUT -s 10.0.3.2 -p tcp -j REJECT
1323         run_tests $ns1 $ns2 10.0.1.1 0 0 0 slow &
1324
1325         # updates in the child shell do not have any effect here, we
1326         # need to bump the test counter for the above case
1327         TEST_COUNT=$((TEST_COUNT+1))
1328
1329         # mpj subflow will be in TW after the reset
1330         wait_for_tw $ns2
1331         pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow
1332         wait
1333
1334         # additional subflow could be created only if the PM select
1335         # the later endpoint, skipping the already used one
1336         chk_join_nr "multi subflows, fair usage on close" 1 1 1
1337 }
1338
1339 signal_address_tests()
1340 {
1341         # add_address, unused
1342         reset
1343         pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
1344         run_tests $ns1 $ns2 10.0.1.1
1345         chk_join_nr "unused signal address" 0 0 0
1346         chk_add_nr 1 1
1347
1348         # accept and use add_addr
1349         reset
1350         pm_nl_set_limits $ns1 0 1
1351         pm_nl_set_limits $ns2 1 1
1352         pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
1353         run_tests $ns1 $ns2 10.0.1.1
1354         chk_join_nr "signal address" 1 1 1
1355         chk_add_nr 1 1
1356
1357         # accept and use add_addr with an additional subflow
1358         # note: signal address in server ns and local addresses in client ns must
1359         # belong to different subnets or one of the listed local address could be
1360         # used for 'add_addr' subflow
1361         reset
1362         pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
1363         pm_nl_set_limits $ns1 0 2
1364         pm_nl_set_limits $ns2 1 2
1365         pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
1366         run_tests $ns1 $ns2 10.0.1.1
1367         chk_join_nr "subflow and signal" 2 2 2
1368         chk_add_nr 1 1
1369
1370         # accept and use add_addr with additional subflows
1371         reset
1372         pm_nl_set_limits $ns1 0 3
1373         pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
1374         pm_nl_set_limits $ns2 1 3
1375         pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
1376         pm_nl_add_endpoint $ns2 10.0.4.2 flags subflow
1377         run_tests $ns1 $ns2 10.0.1.1
1378         chk_join_nr "multiple subflows and signal" 3 3 3
1379         chk_add_nr 1 1
1380
1381         # signal addresses
1382         reset
1383         pm_nl_set_limits $ns1 3 3
1384         pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
1385         pm_nl_add_endpoint $ns1 10.0.3.1 flags signal
1386         pm_nl_add_endpoint $ns1 10.0.4.1 flags signal
1387         pm_nl_set_limits $ns2 3 3
1388         run_tests $ns1 $ns2 10.0.1.1
1389         chk_join_nr "signal addresses" 3 3 3
1390         chk_add_nr 3 3
1391
1392         # signal invalid addresses
1393         reset
1394         pm_nl_set_limits $ns1 3 3
1395         pm_nl_add_endpoint $ns1 10.0.12.1 flags signal
1396         pm_nl_add_endpoint $ns1 10.0.3.1 flags signal
1397         pm_nl_add_endpoint $ns1 10.0.14.1 flags signal
1398         pm_nl_set_limits $ns2 3 3
1399         run_tests $ns1 $ns2 10.0.1.1
1400         chk_join_nr "signal invalid addresses" 1 1 1
1401         chk_add_nr 3 3
1402
1403         # signal addresses race test
1404         reset
1405         pm_nl_set_limits $ns1 4 4
1406         pm_nl_set_limits $ns2 4 4
1407         pm_nl_add_endpoint $ns1 10.0.1.1 flags signal
1408         pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
1409         pm_nl_add_endpoint $ns1 10.0.3.1 flags signal
1410         pm_nl_add_endpoint $ns1 10.0.4.1 flags signal
1411         pm_nl_add_endpoint $ns2 10.0.1.2 flags signal
1412         pm_nl_add_endpoint $ns2 10.0.2.2 flags signal
1413         pm_nl_add_endpoint $ns2 10.0.3.2 flags signal
1414         pm_nl_add_endpoint $ns2 10.0.4.2 flags signal
1415
1416         # the peer could possibly miss some addr notification, allow retransmission
1417         ip netns exec $ns1 sysctl -q net.mptcp.add_addr_timeout=1
1418         run_tests $ns1 $ns2 10.0.1.1 0 0 0 slow
1419         chk_join_nr "signal addresses race test" 3 3 3
1420
1421         # the server will not signal the address terminating
1422         # the MPC subflow
1423         chk_add_nr 3 3
1424 }
1425
1426 link_failure_tests()
1427 {
1428         # accept and use add_addr with additional subflows and link loss
1429         reset
1430
1431         # without any b/w limit each veth could spool the packets and get
1432         # them acked at xmit time, so that the corresponding subflow will
1433         # have almost always no outstanding pkts, the scheduler will pick
1434         # always the first subflow and we will have hard time testing
1435         # active backup and link switch-over.
1436         # Let's set some arbitrary (low) virtual link limits.
1437         init_shapers
1438         pm_nl_set_limits $ns1 0 3
1439         pm_nl_add_endpoint $ns1 10.0.2.1 dev ns1eth2 flags signal
1440         pm_nl_set_limits $ns2 1 3
1441         pm_nl_add_endpoint $ns2 10.0.3.2 dev ns2eth3 flags subflow
1442         pm_nl_add_endpoint $ns2 10.0.4.2 dev ns2eth4 flags subflow
1443         run_tests $ns1 $ns2 10.0.1.1 1
1444         chk_join_nr "multiple flows, signal, link failure" 3 3 3
1445         chk_add_nr 1 1
1446         chk_stale_nr $ns2 1 5 1
1447
1448         # accept and use add_addr with additional subflows and link loss
1449         # for bidirectional transfer
1450         reset
1451         init_shapers
1452         pm_nl_set_limits $ns1 0 3
1453         pm_nl_add_endpoint $ns1 10.0.2.1 dev ns1eth2 flags signal
1454         pm_nl_set_limits $ns2 1 3
1455         pm_nl_add_endpoint $ns2 10.0.3.2 dev ns2eth3 flags subflow
1456         pm_nl_add_endpoint $ns2 10.0.4.2 dev ns2eth4 flags subflow
1457         run_tests $ns1 $ns2 10.0.1.1 2
1458         chk_join_nr "multi flows, signal, bidi, link fail" 3 3 3
1459         chk_add_nr 1 1
1460         chk_stale_nr $ns2 1 -1 1
1461
1462         # 2 subflows plus 1 backup subflow with a lossy link, backup
1463         # will never be used
1464         reset
1465         init_shapers
1466         pm_nl_set_limits $ns1 0 2
1467         pm_nl_add_endpoint $ns1 10.0.2.1 dev ns1eth2 flags signal
1468         pm_nl_set_limits $ns2 1 2
1469         export FAILING_LINKS="1"
1470         pm_nl_add_endpoint $ns2 10.0.3.2 dev ns2eth3 flags subflow,backup
1471         run_tests $ns1 $ns2 10.0.1.1 1
1472         chk_join_nr "backup subflow unused, link failure" 2 2 2
1473         chk_add_nr 1 1
1474         chk_link_usage $ns2 ns2eth3 $cinsent 0
1475
1476         # 2 lossy links after half transfer, backup will get half of
1477         # the traffic
1478         reset
1479         init_shapers
1480         pm_nl_set_limits $ns1 0 2
1481         pm_nl_add_endpoint $ns1 10.0.2.1 dev ns1eth2 flags signal
1482         pm_nl_set_limits $ns2 1 2
1483         pm_nl_add_endpoint $ns2 10.0.3.2 dev ns2eth3 flags subflow,backup
1484         export FAILING_LINKS="1 2"
1485         run_tests $ns1 $ns2 10.0.1.1 1
1486         chk_join_nr "backup flow used, multi links fail" 2 2 2
1487         chk_add_nr 1 1
1488         chk_stale_nr $ns2 2 4 2
1489         chk_link_usage $ns2 ns2eth3 $cinsent 50
1490
1491         # use a backup subflow with the first subflow on a lossy link
1492         # for bidirectional transfer
1493         reset
1494         init_shapers
1495         pm_nl_set_limits $ns1 0 2
1496         pm_nl_add_endpoint $ns1 10.0.2.1 dev ns1eth2 flags signal
1497         pm_nl_set_limits $ns2 1 3
1498         pm_nl_add_endpoint $ns2 10.0.3.2 dev ns2eth3 flags subflow,backup
1499         run_tests $ns1 $ns2 10.0.1.1 2
1500         chk_join_nr "backup flow used, bidi, link failure" 2 2 2
1501         chk_add_nr 1 1
1502         chk_stale_nr $ns2 1 -1 2
1503         chk_link_usage $ns2 ns2eth3 $cinsent 50
1504 }
1505
1506 add_addr_timeout_tests()
1507 {
1508         # add_addr timeout
1509         reset_with_add_addr_timeout
1510         pm_nl_set_limits $ns1 0 1
1511         pm_nl_set_limits $ns2 1 1
1512         pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
1513         run_tests $ns1 $ns2 10.0.1.1 0 0 0 slow
1514         chk_join_nr "signal address, ADD_ADDR timeout" 1 1 1
1515         chk_add_nr 4 0
1516
1517         # add_addr timeout IPv6
1518         reset_with_add_addr_timeout 6
1519         pm_nl_set_limits $ns1 0 1
1520         pm_nl_set_limits $ns2 1 1
1521         pm_nl_add_endpoint $ns1 dead:beef:2::1 flags signal
1522         run_tests $ns1 $ns2 dead:beef:1::1 0 0 0 slow
1523         chk_join_nr "signal address, ADD_ADDR6 timeout" 1 1 1
1524         chk_add_nr 4 0
1525
1526         # signal addresses timeout
1527         reset_with_add_addr_timeout
1528         pm_nl_set_limits $ns1 2 2
1529         pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
1530         pm_nl_add_endpoint $ns1 10.0.3.1 flags signal
1531         pm_nl_set_limits $ns2 2 2
1532         run_tests $ns1 $ns2 10.0.1.1 0 0 0 speed_10
1533         chk_join_nr "signal addresses, ADD_ADDR timeout" 2 2 2
1534         chk_add_nr 8 0
1535
1536         # signal invalid addresses timeout
1537         reset_with_add_addr_timeout
1538         pm_nl_set_limits $ns1 2 2
1539         pm_nl_add_endpoint $ns1 10.0.12.1 flags signal
1540         pm_nl_add_endpoint $ns1 10.0.3.1 flags signal
1541         pm_nl_set_limits $ns2 2 2
1542         run_tests $ns1 $ns2 10.0.1.1 0 0 0 speed_10
1543         chk_join_nr "invalid address, ADD_ADDR timeout" 1 1 1
1544         chk_add_nr 8 0
1545 }
1546
1547 remove_tests()
1548 {
1549         # single subflow, remove
1550         reset
1551         pm_nl_set_limits $ns1 0 1
1552         pm_nl_set_limits $ns2 0 1
1553         pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
1554         run_tests $ns1 $ns2 10.0.1.1 0 0 -1 slow
1555         chk_join_nr "remove single subflow" 1 1 1
1556         chk_rm_nr 1 1
1557
1558         # multiple subflows, remove
1559         reset
1560         pm_nl_set_limits $ns1 0 2
1561         pm_nl_set_limits $ns2 0 2
1562         pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow
1563         pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
1564         run_tests $ns1 $ns2 10.0.1.1 0 0 -2 slow
1565         chk_join_nr "remove multiple subflows" 2 2 2
1566         chk_rm_nr 2 2
1567
1568         # single address, remove
1569         reset
1570         pm_nl_set_limits $ns1 0 1
1571         pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
1572         pm_nl_set_limits $ns2 1 1
1573         run_tests $ns1 $ns2 10.0.1.1 0 -1 0 slow
1574         chk_join_nr "remove single address" 1 1 1
1575         chk_add_nr 1 1
1576         chk_rm_nr 1 1 invert
1577
1578         # subflow and signal, remove
1579         reset
1580         pm_nl_set_limits $ns1 0 2
1581         pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
1582         pm_nl_set_limits $ns2 1 2
1583         pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
1584         run_tests $ns1 $ns2 10.0.1.1 0 -1 -1 slow
1585         chk_join_nr "remove subflow and signal" 2 2 2
1586         chk_add_nr 1 1
1587         chk_rm_nr 1 1
1588
1589         # subflows and signal, remove
1590         reset
1591         pm_nl_set_limits $ns1 0 3
1592         pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
1593         pm_nl_set_limits $ns2 1 3
1594         pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
1595         pm_nl_add_endpoint $ns2 10.0.4.2 flags subflow
1596         run_tests $ns1 $ns2 10.0.1.1 0 -1 -2 slow
1597         chk_join_nr "remove subflows and signal" 3 3 3
1598         chk_add_nr 1 1
1599         chk_rm_nr 2 2
1600
1601         # addresses remove
1602         reset
1603         pm_nl_set_limits $ns1 3 3
1604         pm_nl_add_endpoint $ns1 10.0.2.1 flags signal id 250
1605         pm_nl_add_endpoint $ns1 10.0.3.1 flags signal
1606         pm_nl_add_endpoint $ns1 10.0.4.1 flags signal
1607         pm_nl_set_limits $ns2 3 3
1608         run_tests $ns1 $ns2 10.0.1.1 0 -3 0 slow
1609         chk_join_nr "remove addresses" 3 3 3
1610         chk_add_nr 3 3
1611         chk_rm_nr 3 3 invert
1612
1613         # invalid addresses remove
1614         reset
1615         pm_nl_set_limits $ns1 3 3
1616         pm_nl_add_endpoint $ns1 10.0.12.1 flags signal
1617         pm_nl_add_endpoint $ns1 10.0.3.1 flags signal
1618         pm_nl_add_endpoint $ns1 10.0.14.1 flags signal
1619         pm_nl_set_limits $ns2 3 3
1620         run_tests $ns1 $ns2 10.0.1.1 0 -3 0 slow
1621         chk_join_nr "remove invalid addresses" 1 1 1
1622         chk_add_nr 3 3
1623         chk_rm_nr 3 1 invert
1624
1625         # subflows and signal, flush
1626         reset
1627         pm_nl_set_limits $ns1 0 3
1628         pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
1629         pm_nl_set_limits $ns2 1 3
1630         pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
1631         pm_nl_add_endpoint $ns2 10.0.4.2 flags subflow
1632         run_tests $ns1 $ns2 10.0.1.1 0 -8 -8 slow
1633         chk_join_nr "flush subflows and signal" 3 3 3
1634         chk_add_nr 1 1
1635         chk_rm_nr 2 2
1636
1637         # subflows flush
1638         reset
1639         pm_nl_set_limits $ns1 3 3
1640         pm_nl_set_limits $ns2 3 3
1641         pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow id 150
1642         pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
1643         pm_nl_add_endpoint $ns2 10.0.4.2 flags subflow
1644         run_tests $ns1 $ns2 10.0.1.1 0 -8 -8 slow
1645         chk_join_nr "flush subflows" 3 3 3
1646         chk_rm_nr 3 3
1647
1648         # addresses flush
1649         reset
1650         pm_nl_set_limits $ns1 3 3
1651         pm_nl_add_endpoint $ns1 10.0.2.1 flags signal id 250
1652         pm_nl_add_endpoint $ns1 10.0.3.1 flags signal
1653         pm_nl_add_endpoint $ns1 10.0.4.1 flags signal
1654         pm_nl_set_limits $ns2 3 3
1655         run_tests $ns1 $ns2 10.0.1.1 0 -8 -8 slow
1656         chk_join_nr "flush addresses" 3 3 3
1657         chk_add_nr 3 3
1658         chk_rm_nr 3 3 invert
1659
1660         # invalid addresses flush
1661         reset
1662         pm_nl_set_limits $ns1 3 3
1663         pm_nl_add_endpoint $ns1 10.0.12.1 flags signal
1664         pm_nl_add_endpoint $ns1 10.0.3.1 flags signal
1665         pm_nl_add_endpoint $ns1 10.0.14.1 flags signal
1666         pm_nl_set_limits $ns2 3 3
1667         run_tests $ns1 $ns2 10.0.1.1 0 -8 0 slow
1668         chk_join_nr "flush invalid addresses" 1 1 1
1669         chk_add_nr 3 3
1670         chk_rm_nr 3 1 invert
1671
1672         # remove id 0 subflow
1673         reset
1674         pm_nl_set_limits $ns1 0 1
1675         pm_nl_set_limits $ns2 0 1
1676         pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
1677         run_tests $ns1 $ns2 10.0.1.1 0 0 -9 slow
1678         chk_join_nr "remove id 0 subflow" 1 1 1
1679         chk_rm_nr 1 1
1680
1681         # remove id 0 address
1682         reset
1683         pm_nl_set_limits $ns1 0 1
1684         pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
1685         pm_nl_set_limits $ns2 1 1
1686         run_tests $ns1 $ns2 10.0.1.1 0 -9 0 slow
1687         chk_join_nr "remove id 0 address" 1 1 1
1688         chk_add_nr 1 1
1689         chk_rm_nr 1 1 invert
1690 }
1691
1692 add_tests()
1693 {
1694         # add single subflow
1695         reset
1696         pm_nl_set_limits $ns1 0 1
1697         pm_nl_set_limits $ns2 0 1
1698         run_tests $ns1 $ns2 10.0.1.1 0 0 1 slow
1699         chk_join_nr "add single subflow" 1 1 1
1700
1701         # add signal address
1702         reset
1703         pm_nl_set_limits $ns1 0 1
1704         pm_nl_set_limits $ns2 1 1
1705         run_tests $ns1 $ns2 10.0.1.1 0 1 0 slow
1706         chk_join_nr "add signal address" 1 1 1
1707         chk_add_nr 1 1
1708
1709         # add multiple subflows
1710         reset
1711         pm_nl_set_limits $ns1 0 2
1712         pm_nl_set_limits $ns2 0 2
1713         run_tests $ns1 $ns2 10.0.1.1 0 0 2 slow
1714         chk_join_nr "add multiple subflows" 2 2 2
1715
1716         # add multiple subflows IPv6
1717         reset
1718         pm_nl_set_limits $ns1 0 2
1719         pm_nl_set_limits $ns2 0 2
1720         run_tests $ns1 $ns2 dead:beef:1::1 0 0 2 slow
1721         chk_join_nr "add multiple subflows IPv6" 2 2 2
1722
1723         # add multiple addresses IPv6
1724         reset
1725         pm_nl_set_limits $ns1 0 2
1726         pm_nl_set_limits $ns2 2 2
1727         run_tests $ns1 $ns2 dead:beef:1::1 0 2 0 slow
1728         chk_join_nr "add multiple addresses IPv6" 2 2 2
1729         chk_add_nr 2 2
1730 }
1731
1732 ipv6_tests()
1733 {
1734         # subflow IPv6
1735         reset
1736         pm_nl_set_limits $ns1 0 1
1737         pm_nl_set_limits $ns2 0 1
1738         pm_nl_add_endpoint $ns2 dead:beef:3::2 dev ns2eth3 flags subflow
1739         run_tests $ns1 $ns2 dead:beef:1::1 0 0 0 slow
1740         chk_join_nr "single subflow IPv6" 1 1 1
1741
1742         # add_address, unused IPv6
1743         reset
1744         pm_nl_add_endpoint $ns1 dead:beef:2::1 flags signal
1745         run_tests $ns1 $ns2 dead:beef:1::1 0 0 0 slow
1746         chk_join_nr "unused signal address IPv6" 0 0 0
1747         chk_add_nr 1 1
1748
1749         # signal address IPv6
1750         reset
1751         pm_nl_set_limits $ns1 0 1
1752         pm_nl_add_endpoint $ns1 dead:beef:2::1 flags signal
1753         pm_nl_set_limits $ns2 1 1
1754         run_tests $ns1 $ns2 dead:beef:1::1 0 0 0 slow
1755         chk_join_nr "single address IPv6" 1 1 1
1756         chk_add_nr 1 1
1757
1758         # single address IPv6, remove
1759         reset
1760         pm_nl_set_limits $ns1 0 1
1761         pm_nl_add_endpoint $ns1 dead:beef:2::1 flags signal
1762         pm_nl_set_limits $ns2 1 1
1763         run_tests $ns1 $ns2 dead:beef:1::1 0 -1 0 slow
1764         chk_join_nr "remove single address IPv6" 1 1 1
1765         chk_add_nr 1 1
1766         chk_rm_nr 1 1 invert
1767
1768         # subflow and signal IPv6, remove
1769         reset
1770         pm_nl_set_limits $ns1 0 2
1771         pm_nl_add_endpoint $ns1 dead:beef:2::1 flags signal
1772         pm_nl_set_limits $ns2 1 2
1773         pm_nl_add_endpoint $ns2 dead:beef:3::2 dev ns2eth3 flags subflow
1774         run_tests $ns1 $ns2 dead:beef:1::1 0 -1 -1 slow
1775         chk_join_nr "remove subflow and signal IPv6" 2 2 2
1776         chk_add_nr 1 1
1777         chk_rm_nr 1 1
1778 }
1779
1780 v4mapped_tests()
1781 {
1782         # subflow IPv4-mapped to IPv4-mapped
1783         reset
1784         pm_nl_set_limits $ns1 0 1
1785         pm_nl_set_limits $ns2 0 1
1786         pm_nl_add_endpoint $ns2 "::ffff:10.0.3.2" flags subflow
1787         run_tests $ns1 $ns2 "::ffff:10.0.1.1"
1788         chk_join_nr "single subflow IPv4-mapped" 1 1 1
1789
1790         # signal address IPv4-mapped with IPv4-mapped sk
1791         reset
1792         pm_nl_set_limits $ns1 0 1
1793         pm_nl_set_limits $ns2 1 1
1794         pm_nl_add_endpoint $ns1 "::ffff:10.0.2.1" flags signal
1795         run_tests $ns1 $ns2 "::ffff:10.0.1.1"
1796         chk_join_nr "signal address IPv4-mapped" 1 1 1
1797         chk_add_nr 1 1
1798
1799         # subflow v4-map-v6
1800         reset
1801         pm_nl_set_limits $ns1 0 1
1802         pm_nl_set_limits $ns2 0 1
1803         pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
1804         run_tests $ns1 $ns2 "::ffff:10.0.1.1"
1805         chk_join_nr "single subflow v4-map-v6" 1 1 1
1806
1807         # signal address v4-map-v6
1808         reset
1809         pm_nl_set_limits $ns1 0 1
1810         pm_nl_set_limits $ns2 1 1
1811         pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
1812         run_tests $ns1 $ns2 "::ffff:10.0.1.1"
1813         chk_join_nr "signal address v4-map-v6" 1 1 1
1814         chk_add_nr 1 1
1815
1816         # subflow v6-map-v4
1817         reset
1818         pm_nl_set_limits $ns1 0 1
1819         pm_nl_set_limits $ns2 0 1
1820         pm_nl_add_endpoint $ns2 "::ffff:10.0.3.2" flags subflow
1821         run_tests $ns1 $ns2 10.0.1.1
1822         chk_join_nr "single subflow v6-map-v4" 1 1 1
1823
1824         # signal address v6-map-v4
1825         reset
1826         pm_nl_set_limits $ns1 0 1
1827         pm_nl_set_limits $ns2 1 1
1828         pm_nl_add_endpoint $ns1 "::ffff:10.0.2.1" flags signal
1829         run_tests $ns1 $ns2 10.0.1.1
1830         chk_join_nr "signal address v6-map-v4" 1 1 1
1831         chk_add_nr 1 1
1832
1833         # no subflow IPv6 to v4 address
1834         reset
1835         pm_nl_set_limits $ns1 0 1
1836         pm_nl_set_limits $ns2 0 1
1837         pm_nl_add_endpoint $ns2 dead:beef:2::2 flags subflow
1838         run_tests $ns1 $ns2 10.0.1.1
1839         chk_join_nr "no JOIN with diff families v4-v6" 0 0 0
1840
1841         # no subflow IPv6 to v4 address even if v6 has a valid v4 at the end
1842         reset
1843         pm_nl_set_limits $ns1 0 1
1844         pm_nl_set_limits $ns2 0 1
1845         pm_nl_add_endpoint $ns2 dead:beef:2::10.0.3.2 flags subflow
1846         run_tests $ns1 $ns2 10.0.1.1
1847         chk_join_nr "no JOIN with diff families v4-v6-2" 0 0 0
1848
1849         # no subflow IPv4 to v6 address, no need to slow down too then
1850         reset
1851         pm_nl_set_limits $ns1 0 1
1852         pm_nl_set_limits $ns2 0 1
1853         pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
1854         run_tests $ns1 $ns2 dead:beef:1::1
1855         chk_join_nr "no JOIN with diff families v6-v4" 0 0 0
1856 }
1857
1858 backup_tests()
1859 {
1860         # single subflow, backup
1861         reset
1862         pm_nl_set_limits $ns1 0 1
1863         pm_nl_set_limits $ns2 0 1
1864         pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow,backup
1865         run_tests $ns1 $ns2 10.0.1.1 0 0 0 slow nobackup
1866         chk_join_nr "single subflow, backup" 1 1 1
1867         chk_prio_nr 0 1
1868
1869         # single address, backup
1870         reset
1871         pm_nl_set_limits $ns1 0 1
1872         pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
1873         pm_nl_set_limits $ns2 1 1
1874         run_tests $ns1 $ns2 10.0.1.1 0 0 0 slow backup
1875         chk_join_nr "single address, backup" 1 1 1
1876         chk_add_nr 1 1
1877         chk_prio_nr 1 0
1878
1879         # single address with port, backup
1880         reset
1881         pm_nl_set_limits $ns1 0 1
1882         pm_nl_add_endpoint $ns1 10.0.2.1 flags signal port 10100
1883         pm_nl_set_limits $ns2 1 1
1884         run_tests $ns1 $ns2 10.0.1.1 0 0 0 slow backup
1885         chk_join_nr "single address with port, backup" 1 1 1
1886         chk_add_nr 1 1
1887         chk_prio_nr 1 0
1888 }
1889
1890 add_addr_ports_tests()
1891 {
1892         # signal address with port
1893         reset
1894         pm_nl_set_limits $ns1 0 1
1895         pm_nl_set_limits $ns2 1 1
1896         pm_nl_add_endpoint $ns1 10.0.2.1 flags signal port 10100
1897         run_tests $ns1 $ns2 10.0.1.1
1898         chk_join_nr "signal address with port" 1 1 1
1899         chk_add_nr 1 1 1
1900
1901         # subflow and signal with port
1902         reset
1903         pm_nl_add_endpoint $ns1 10.0.2.1 flags signal port 10100
1904         pm_nl_set_limits $ns1 0 2
1905         pm_nl_set_limits $ns2 1 2
1906         pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
1907         run_tests $ns1 $ns2 10.0.1.1
1908         chk_join_nr "subflow and signal with port" 2 2 2
1909         chk_add_nr 1 1 1
1910
1911         # single address with port, remove
1912         reset
1913         pm_nl_set_limits $ns1 0 1
1914         pm_nl_add_endpoint $ns1 10.0.2.1 flags signal port 10100
1915         pm_nl_set_limits $ns2 1 1
1916         run_tests $ns1 $ns2 10.0.1.1 0 -1 0 slow
1917         chk_join_nr "remove single address with port" 1 1 1
1918         chk_add_nr 1 1 1
1919         chk_rm_nr 1 1 invert
1920
1921         # subflow and signal with port, remove
1922         reset
1923         pm_nl_set_limits $ns1 0 2
1924         pm_nl_add_endpoint $ns1 10.0.2.1 flags signal port 10100
1925         pm_nl_set_limits $ns2 1 2
1926         pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
1927         run_tests $ns1 $ns2 10.0.1.1 0 -1 -1 slow
1928         chk_join_nr "remove subflow and signal with port" 2 2 2
1929         chk_add_nr 1 1 1
1930         chk_rm_nr 1 1
1931
1932         # subflows and signal with port, flush
1933         reset
1934         pm_nl_set_limits $ns1 0 3
1935         pm_nl_add_endpoint $ns1 10.0.2.1 flags signal port 10100
1936         pm_nl_set_limits $ns2 1 3
1937         pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
1938         pm_nl_add_endpoint $ns2 10.0.4.2 flags subflow
1939         run_tests $ns1 $ns2 10.0.1.1 0 -8 -2 slow
1940         chk_join_nr "flush subflows and signal with port" 3 3 3
1941         chk_add_nr 1 1
1942         chk_rm_nr 2 2
1943
1944         # multiple addresses with port
1945         reset
1946         pm_nl_set_limits $ns1 2 2
1947         pm_nl_add_endpoint $ns1 10.0.2.1 flags signal port 10100
1948         pm_nl_add_endpoint $ns1 10.0.3.1 flags signal port 10100
1949         pm_nl_set_limits $ns2 2 2
1950         run_tests $ns1 $ns2 10.0.1.1
1951         chk_join_nr "multiple addresses with port" 2 2 2
1952         chk_add_nr 2 2 2
1953
1954         # multiple addresses with ports
1955         reset
1956         pm_nl_set_limits $ns1 2 2
1957         pm_nl_add_endpoint $ns1 10.0.2.1 flags signal port 10100
1958         pm_nl_add_endpoint $ns1 10.0.3.1 flags signal port 10101
1959         pm_nl_set_limits $ns2 2 2
1960         run_tests $ns1 $ns2 10.0.1.1
1961         chk_join_nr "multiple addresses with ports" 2 2 2
1962         chk_add_nr 2 2 2
1963 }
1964
1965 syncookies_tests()
1966 {
1967         # single subflow, syncookies
1968         reset_with_cookies
1969         pm_nl_set_limits $ns1 0 1
1970         pm_nl_set_limits $ns2 0 1
1971         pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
1972         run_tests $ns1 $ns2 10.0.1.1
1973         chk_join_nr "single subflow with syn cookies" 1 1 1
1974
1975         # multiple subflows with syn cookies
1976         reset_with_cookies
1977         pm_nl_set_limits $ns1 0 2
1978         pm_nl_set_limits $ns2 0 2
1979         pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
1980         pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow
1981         run_tests $ns1 $ns2 10.0.1.1
1982         chk_join_nr "multiple subflows with syn cookies" 2 2 2
1983
1984         # multiple subflows limited by server
1985         reset_with_cookies
1986         pm_nl_set_limits $ns1 0 1
1987         pm_nl_set_limits $ns2 0 2
1988         pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
1989         pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow
1990         run_tests $ns1 $ns2 10.0.1.1
1991         chk_join_nr "subflows limited by server w cookies" 2 1 1
1992
1993         # test signal address with cookies
1994         reset_with_cookies
1995         pm_nl_set_limits $ns1 0 1
1996         pm_nl_set_limits $ns2 1 1
1997         pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
1998         run_tests $ns1 $ns2 10.0.1.1
1999         chk_join_nr "signal address with syn cookies" 1 1 1
2000         chk_add_nr 1 1
2001
2002         # test cookie with subflow and signal
2003         reset_with_cookies
2004         pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
2005         pm_nl_set_limits $ns1 0 2
2006         pm_nl_set_limits $ns2 1 2
2007         pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
2008         run_tests $ns1 $ns2 10.0.1.1
2009         chk_join_nr "subflow and signal w cookies" 2 2 2
2010         chk_add_nr 1 1
2011
2012         # accept and use add_addr with additional subflows
2013         reset_with_cookies
2014         pm_nl_set_limits $ns1 0 3
2015         pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
2016         pm_nl_set_limits $ns2 1 3
2017         pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
2018         pm_nl_add_endpoint $ns2 10.0.4.2 flags subflow
2019         run_tests $ns1 $ns2 10.0.1.1
2020         chk_join_nr "subflows and signal w. cookies" 3 3 3
2021         chk_add_nr 1 1
2022 }
2023
2024 checksum_tests()
2025 {
2026         # checksum test 0 0
2027         reset_with_checksum 0 0
2028         pm_nl_set_limits $ns1 0 1
2029         pm_nl_set_limits $ns2 0 1
2030         run_tests $ns1 $ns2 10.0.1.1
2031         chk_csum_nr "checksum test 0 0"
2032
2033         # checksum test 1 1
2034         reset_with_checksum 1 1
2035         pm_nl_set_limits $ns1 0 1
2036         pm_nl_set_limits $ns2 0 1
2037         run_tests $ns1 $ns2 10.0.1.1
2038         chk_csum_nr "checksum test 1 1"
2039
2040         # checksum test 0 1
2041         reset_with_checksum 0 1
2042         pm_nl_set_limits $ns1 0 1
2043         pm_nl_set_limits $ns2 0 1
2044         run_tests $ns1 $ns2 10.0.1.1
2045         chk_csum_nr "checksum test 0 1"
2046
2047         # checksum test 1 0
2048         reset_with_checksum 1 0
2049         pm_nl_set_limits $ns1 0 1
2050         pm_nl_set_limits $ns2 0 1
2051         run_tests $ns1 $ns2 10.0.1.1
2052         chk_csum_nr "checksum test 1 0"
2053 }
2054
2055 deny_join_id0_tests()
2056 {
2057         # subflow allow join id0 ns1
2058         reset_with_allow_join_id0 1 0
2059         pm_nl_set_limits $ns1 1 1
2060         pm_nl_set_limits $ns2 1 1
2061         pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
2062         run_tests $ns1 $ns2 10.0.1.1
2063         chk_join_nr "single subflow allow join id0 ns1" 1 1 1
2064
2065         # subflow allow join id0 ns2
2066         reset_with_allow_join_id0 0 1
2067         pm_nl_set_limits $ns1 1 1
2068         pm_nl_set_limits $ns2 1 1
2069         pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
2070         run_tests $ns1 $ns2 10.0.1.1
2071         chk_join_nr "single subflow allow join id0 ns2" 0 0 0
2072
2073         # signal address allow join id0 ns1
2074         # ADD_ADDRs are not affected by allow_join_id0 value.
2075         reset_with_allow_join_id0 1 0
2076         pm_nl_set_limits $ns1 1 1
2077         pm_nl_set_limits $ns2 1 1
2078         pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
2079         run_tests $ns1 $ns2 10.0.1.1
2080         chk_join_nr "signal address allow join id0 ns1" 1 1 1
2081         chk_add_nr 1 1
2082
2083         # signal address allow join id0 ns2
2084         # ADD_ADDRs are not affected by allow_join_id0 value.
2085         reset_with_allow_join_id0 0 1
2086         pm_nl_set_limits $ns1 1 1
2087         pm_nl_set_limits $ns2 1 1
2088         pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
2089         run_tests $ns1 $ns2 10.0.1.1
2090         chk_join_nr "signal address allow join id0 ns2" 1 1 1
2091         chk_add_nr 1 1
2092
2093         # subflow and address allow join id0 ns1
2094         reset_with_allow_join_id0 1 0
2095         pm_nl_set_limits $ns1 2 2
2096         pm_nl_set_limits $ns2 2 2
2097         pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
2098         pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
2099         run_tests $ns1 $ns2 10.0.1.1
2100         chk_join_nr "subflow and address allow join id0 1" 2 2 2
2101
2102         # subflow and address allow join id0 ns2
2103         reset_with_allow_join_id0 0 1
2104         pm_nl_set_limits $ns1 2 2
2105         pm_nl_set_limits $ns2 2 2
2106         pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
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 "subflow and address allow join id0 2" 1 1 1
2110 }
2111
2112 fullmesh_tests()
2113 {
2114         # fullmesh 1
2115         # 2 fullmesh addrs in ns2, added before the connection,
2116         # 1 non-fullmesh addr in ns1, added during the connection.
2117         reset
2118         pm_nl_set_limits $ns1 0 4
2119         pm_nl_set_limits $ns2 1 4
2120         pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow,fullmesh
2121         pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow,fullmesh
2122         run_tests $ns1 $ns2 10.0.1.1 0 1 0 slow
2123         chk_join_nr "fullmesh test 2x1" 4 4 4
2124         chk_add_nr 1 1
2125
2126         # fullmesh 2
2127         # 1 non-fullmesh addr in ns1, added before the connection,
2128         # 1 fullmesh addr in ns2, added during the connection.
2129         reset
2130         pm_nl_set_limits $ns1 1 3
2131         pm_nl_set_limits $ns2 1 3
2132         pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
2133         run_tests $ns1 $ns2 10.0.1.1 0 0 fullmesh_1 slow
2134         chk_join_nr "fullmesh test 1x1" 3 3 3
2135         chk_add_nr 1 1
2136
2137         # fullmesh 3
2138         # 1 non-fullmesh addr in ns1, added before the connection,
2139         # 2 fullmesh addrs in ns2, added during the connection.
2140         reset
2141         pm_nl_set_limits $ns1 2 5
2142         pm_nl_set_limits $ns2 1 5
2143         pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
2144         run_tests $ns1 $ns2 10.0.1.1 0 0 fullmesh_2 slow
2145         chk_join_nr "fullmesh test 1x2" 5 5 5
2146         chk_add_nr 1 1
2147
2148         # fullmesh 4
2149         # 1 non-fullmesh addr in ns1, added before the connection,
2150         # 2 fullmesh addrs in ns2, added during the connection,
2151         # limit max_subflows to 4.
2152         reset
2153         pm_nl_set_limits $ns1 2 4
2154         pm_nl_set_limits $ns2 1 4
2155         pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
2156         run_tests $ns1 $ns2 10.0.1.1 0 0 fullmesh_2 slow
2157         chk_join_nr "fullmesh test 1x2, limited" 4 4 4
2158         chk_add_nr 1 1
2159
2160         # set fullmesh flag
2161         reset
2162         pm_nl_set_limits $ns1 4 4
2163         pm_nl_add_endpoint $ns1 10.0.2.1 flags subflow
2164         pm_nl_set_limits $ns2 4 4
2165         run_tests $ns1 $ns2 10.0.1.1 0 0 1 slow fullmesh
2166         chk_join_nr "set fullmesh flag test" 2 2 2
2167         chk_rm_nr 0 1
2168
2169         # set nofullmesh flag
2170         reset
2171         pm_nl_set_limits $ns1 4 4
2172         pm_nl_add_endpoint $ns1 10.0.2.1 flags subflow,fullmesh
2173         pm_nl_set_limits $ns2 4 4
2174         run_tests $ns1 $ns2 10.0.1.1 0 0 fullmesh_1 slow nofullmesh
2175         chk_join_nr "set nofullmesh flag test" 2 2 2
2176         chk_rm_nr 0 1
2177
2178         # set backup,fullmesh flags
2179         reset
2180         pm_nl_set_limits $ns1 4 4
2181         pm_nl_add_endpoint $ns1 10.0.2.1 flags subflow
2182         pm_nl_set_limits $ns2 4 4
2183         run_tests $ns1 $ns2 10.0.1.1 0 0 1 slow backup,fullmesh
2184         chk_join_nr "set backup,fullmesh flags test" 2 2 2
2185         chk_prio_nr 0 1
2186         chk_rm_nr 0 1
2187
2188         # set nobackup,nofullmesh flags
2189         reset
2190         pm_nl_set_limits $ns1 4 4
2191         pm_nl_set_limits $ns2 4 4
2192         pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow,backup,fullmesh
2193         run_tests $ns1 $ns2 10.0.1.1 0 0 0 slow nobackup,nofullmesh
2194         chk_join_nr "set nobackup,nofullmesh flags test" 2 2 2
2195         chk_prio_nr 0 1
2196         chk_rm_nr 0 1
2197 }
2198
2199 all_tests()
2200 {
2201         subflows_tests
2202         subflows_error_tests
2203         signal_address_tests
2204         link_failure_tests
2205         add_addr_timeout_tests
2206         remove_tests
2207         add_tests
2208         ipv6_tests
2209         v4mapped_tests
2210         backup_tests
2211         add_addr_ports_tests
2212         syncookies_tests
2213         checksum_tests
2214         deny_join_id0_tests
2215         fullmesh_tests
2216 }
2217
2218 # [$1: error message]
2219 usage()
2220 {
2221         if [ -n "${1}" ]; then
2222                 echo "${1}"
2223                 ret=1
2224         fi
2225
2226         echo "mptcp_join usage:"
2227         echo "  -f subflows_tests"
2228         echo "  -e subflows_error_tests"
2229         echo "  -s signal_address_tests"
2230         echo "  -l link_failure_tests"
2231         echo "  -t add_addr_timeout_tests"
2232         echo "  -r remove_tests"
2233         echo "  -a add_tests"
2234         echo "  -6 ipv6_tests"
2235         echo "  -4 v4mapped_tests"
2236         echo "  -b backup_tests"
2237         echo "  -p add_addr_ports_tests"
2238         echo "  -k syncookies_tests"
2239         echo "  -S checksum_tests"
2240         echo "  -d deny_join_id0_tests"
2241         echo "  -m fullmesh_tests"
2242         echo "  -c capture pcap files"
2243         echo "  -C enable data checksum"
2244         echo "  -i use ip mptcp"
2245         echo "  -h help"
2246
2247         exit ${ret}
2248 }
2249
2250 for arg in "$@"; do
2251         # check for "capture/checksum" args before launching tests
2252         if [[ "${arg}" =~ ^"-"[0-9a-zA-Z]*"c"[0-9a-zA-Z]*$ ]]; then
2253                 capture=1
2254         fi
2255         if [[ "${arg}" =~ ^"-"[0-9a-zA-Z]*"C"[0-9a-zA-Z]*$ ]]; then
2256                 checksum=1
2257         fi
2258         if [[ "${arg}" =~ ^"-"[0-9a-zA-Z]*"i"[0-9a-zA-Z]*$ ]]; then
2259                 ip_mptcp=1
2260         fi
2261
2262         # exception for the capture/checksum/ip_mptcp options, the rest means: a part of the tests
2263         if [ "${arg}" != "-c" ] && [ "${arg}" != "-C" ] && [ "${arg}" != "-i" ]; then
2264                 do_all_tests=0
2265         fi
2266 done
2267
2268 if [ $do_all_tests -eq 1 ]; then
2269         all_tests
2270         exit $ret
2271 fi
2272
2273 while getopts 'fesltra64bpkdmchCSi' opt; do
2274         case $opt in
2275                 f)
2276                         subflows_tests
2277                         ;;
2278                 e)
2279                         subflows_error_tests
2280                         ;;
2281                 s)
2282                         signal_address_tests
2283                         ;;
2284                 l)
2285                         link_failure_tests
2286                         ;;
2287                 t)
2288                         add_addr_timeout_tests
2289                         ;;
2290                 r)
2291                         remove_tests
2292                         ;;
2293                 a)
2294                         add_tests
2295                         ;;
2296                 6)
2297                         ipv6_tests
2298                         ;;
2299                 4)
2300                         v4mapped_tests
2301                         ;;
2302                 b)
2303                         backup_tests
2304                         ;;
2305                 p)
2306                         add_addr_ports_tests
2307                         ;;
2308                 k)
2309                         syncookies_tests
2310                         ;;
2311                 S)
2312                         checksum_tests
2313                         ;;
2314                 d)
2315                         deny_join_id0_tests
2316                         ;;
2317                 m)
2318                         fullmesh_tests
2319                         ;;
2320                 c)
2321                         ;;
2322                 C)
2323                         ;;
2324                 i)
2325                         ;;
2326                 h)
2327                         usage
2328                         ;;
2329                 *)
2330                         usage "Unknown option: -${opt}"
2331                         ;;
2332         esac
2333 done
2334
2335 exit $ret