1#!/bin/bash 2# SPDX-License-Identifier: GPL-2.0 3 4. "$(dirname "${0}")/mptcp_lib.sh" 5 6ret=0 7sin="" 8sout="" 9cin="" 10cout="" 11ksft_skip=4 12timeout=30 13mptcp_connect="" 14capture=0 15 16TEST_COUNT=0 17 18init() 19{ 20 capout=$(mktemp) 21 22 rndh=$(printf %x $sec)-$(mktemp -u XXXXXX) 23 24 ns1="ns1-$rndh" 25 ns2="ns2-$rndh" 26 27 for netns in "$ns1" "$ns2";do 28 ip netns add $netns || exit $ksft_skip 29 ip -net $netns link set lo up 30 ip netns exec $netns sysctl -q net.mptcp.enabled=1 31 ip netns exec $netns sysctl -q net.ipv4.conf.all.rp_filter=0 32 ip netns exec $netns sysctl -q net.ipv4.conf.default.rp_filter=0 33 done 34 35 # ns1 ns2 36 # ns1eth1 ns2eth1 37 # ns1eth2 ns2eth2 38 # ns1eth3 ns2eth3 39 # ns1eth4 ns2eth4 40 41 for i in `seq 1 4`; do 42 ip link add ns1eth$i netns "$ns1" type veth peer name ns2eth$i netns "$ns2" 43 ip -net "$ns1" addr add 10.0.$i.1/24 dev ns1eth$i 44 ip -net "$ns1" addr add dead:beef:$i::1/64 dev ns1eth$i nodad 45 ip -net "$ns1" link set ns1eth$i up 46 47 ip -net "$ns2" addr add 10.0.$i.2/24 dev ns2eth$i 48 ip -net "$ns2" addr add dead:beef:$i::2/64 dev ns2eth$i nodad 49 ip -net "$ns2" link set ns2eth$i up 50 51 # let $ns2 reach any $ns1 address from any interface 52 ip -net "$ns2" route add default via 10.0.$i.1 dev ns2eth$i metric 10$i 53 done 54} 55 56cleanup_partial() 57{ 58 rm -f "$capout" 59 60 for netns in "$ns1" "$ns2"; do 61 ip netns del $netns 62 done 63} 64 65cleanup() 66{ 67 rm -f "$cin" "$cout" 68 rm -f "$sin" "$sout" 69 cleanup_partial 70} 71 72reset() 73{ 74 cleanup_partial 75 init 76} 77 78reset_with_cookies() 79{ 80 reset 81 82 for netns in "$ns1" "$ns2";do 83 ip netns exec $netns sysctl -q net.ipv4.tcp_syncookies=2 84 done 85} 86 87for arg in "$@"; do 88 if [ "$arg" = "-c" ]; then 89 capture=1 90 fi 91done 92 93mptcp_lib_check_mptcp 94 95ip -Version > /dev/null 2>&1 96if [ $? -ne 0 ];then 97 echo "SKIP: Could not run test without ip tool" 98 exit $ksft_skip 99fi 100 101 102check_transfer() 103{ 104 in=$1 105 out=$2 106 what=$3 107 108 cmp "$in" "$out" > /dev/null 2>&1 109 if [ $? -ne 0 ] ;then 110 echo "[ FAIL ] $what does not match (in, out):" 111 print_file_err "$in" 112 print_file_err "$out" 113 114 return 1 115 fi 116 117 return 0 118} 119 120do_ping() 121{ 122 listener_ns="$1" 123 connector_ns="$2" 124 connect_addr="$3" 125 126 ip netns exec ${connector_ns} ping -q -c 1 $connect_addr >/dev/null 127 if [ $? -ne 0 ] ; then 128 echo "$listener_ns -> $connect_addr connectivity [ FAIL ]" 1>&2 129 ret=1 130 fi 131} 132 133# $1: ns ; $2: counter 134get_counter() 135{ 136 local ns="${1}" 137 local counter="${2}" 138 local count 139 140 count=$(ip netns exec ${ns} nstat -asz "${counter}" | awk 'NR==1 {next} {print $2}') 141 if [ -z "${count}" ]; then 142 mptcp_lib_fail_if_expected_feature "${counter} counter" 143 return 1 144 fi 145 146 echo "${count}" 147} 148 149do_transfer() 150{ 151 listener_ns="$1" 152 connector_ns="$2" 153 cl_proto="$3" 154 srv_proto="$4" 155 connect_addr="$5" 156 rm_nr_ns1="$6" 157 rm_nr_ns2="$7" 158 159 port=$((10000+$TEST_COUNT)) 160 TEST_COUNT=$((TEST_COUNT+1)) 161 162 :> "$cout" 163 :> "$sout" 164 :> "$capout" 165 166 if [ $capture -eq 1 ]; then 167 if [ -z $SUDO_USER ] ; then 168 capuser="" 169 else 170 capuser="-Z $SUDO_USER" 171 fi 172 173 capfile=$(printf "mp_join-%02u-%s.pcap" "$TEST_COUNT" "${listener_ns}") 174 175 echo "Capturing traffic for test $TEST_COUNT into $capfile" 176 ip netns exec ${listener_ns} tcpdump -i any -s 65535 -B 32768 $capuser -w $capfile > "$capout" 2>&1 & 177 cappid=$! 178 179 sleep 1 180 fi 181 182 if [[ $rm_nr_ns1 -eq 0 && $rm_nr_ns2 -eq 0 ]]; then 183 mptcp_connect="./mptcp_connect -j" 184 else 185 mptcp_connect="./mptcp_connect -r" 186 fi 187 188 ip netns exec ${listener_ns} $mptcp_connect -t $timeout -l -p $port -s ${srv_proto} 0.0.0.0 < "$sin" > "$sout" & 189 spid=$! 190 191 sleep 1 192 193 ip netns exec ${connector_ns} $mptcp_connect -t $timeout -p $port -s ${cl_proto} $connect_addr < "$cin" > "$cout" & 194 cpid=$! 195 196 if [ $rm_nr_ns1 -gt 0 ]; then 197 counter=1 198 sleep 1 199 200 while [ $counter -le $rm_nr_ns1 ] 201 do 202 ip netns exec ${listener_ns} ./pm_nl_ctl del $counter 203 sleep 1 204 let counter+=1 205 done 206 fi 207 208 if [ $rm_nr_ns2 -gt 0 ]; then 209 counter=1 210 sleep 1 211 212 while [ $counter -le $rm_nr_ns2 ] 213 do 214 ip netns exec ${connector_ns} ./pm_nl_ctl del $counter 215 sleep 1 216 let counter+=1 217 done 218 fi 219 220 wait $cpid 221 retc=$? 222 wait $spid 223 rets=$? 224 225 if [ $capture -eq 1 ]; then 226 sleep 1 227 kill $cappid 228 fi 229 230 if [ ${rets} -ne 0 ] || [ ${retc} -ne 0 ]; then 231 echo " client exit code $retc, server $rets" 1>&2 232 echo -e "\nnetns ${listener_ns} socket stat for ${port}:" 1>&2 233 ip netns exec ${listener_ns} ss -nita 1>&2 -o "sport = :$port" 234 echo -e "\nnetns ${connector_ns} socket stat for ${port}:" 1>&2 235 ip netns exec ${connector_ns} ss -nita 1>&2 -o "dport = :$port" 236 237 cat "$capout" 238 return 1 239 fi 240 241 check_transfer $sin $cout "file received by client" 242 retc=$? 243 check_transfer $cin $sout "file received by server" 244 rets=$? 245 246 if [ $retc -eq 0 ] && [ $rets -eq 0 ];then 247 cat "$capout" 248 return 0 249 fi 250 251 cat "$capout" 252 return 1 253} 254 255make_file() 256{ 257 name=$1 258 who=$2 259 260 SIZE=1 261 262 dd if=/dev/urandom of="$name" bs=1024 count=$SIZE 2> /dev/null 263 echo -e "\nMPTCP_TEST_FILE_END_MARKER" >> "$name" 264 265 echo "Created $name (size $SIZE KB) containing data sent by $who" 266} 267 268run_tests() 269{ 270 listener_ns="$1" 271 connector_ns="$2" 272 connect_addr="$3" 273 lret=0 274 275 do_transfer ${listener_ns} ${connector_ns} MPTCP MPTCP ${connect_addr} 0 0 276 lret=$? 277 if [ $lret -ne 0 ]; then 278 ret=$lret 279 return 280 fi 281} 282 283run_remove_tests() 284{ 285 listener_ns="$1" 286 connector_ns="$2" 287 connect_addr="$3" 288 rm_nr_ns1="$4" 289 rm_nr_ns2="$5" 290 lret=0 291 292 do_transfer ${listener_ns} ${connector_ns} MPTCP MPTCP ${connect_addr} ${rm_nr_ns1} ${rm_nr_ns2} 293 lret=$? 294 if [ $lret -ne 0 ]; then 295 ret=$lret 296 return 297 fi 298} 299 300chk_join_nr() 301{ 302 local msg="$1" 303 local syn_nr=$2 304 local syn_ack_nr=$3 305 local ack_nr=$4 306 local count 307 local dump_stats 308 309 printf "%02u %-36s %s" "$TEST_COUNT" "$msg" "syn" 310 count=$(get_counter ${ns1} "MPTcpExtMPJoinSynRx") 311 if [ -z "$count" ]; then 312 echo -n "[skip]" 313 elif [ "$count" != "$syn_nr" ]; then 314 echo "[fail] got $count JOIN[s] syn expected $syn_nr" 315 ret=1 316 dump_stats=1 317 else 318 echo -n "[ ok ]" 319 fi 320 321 echo -n " - synack" 322 count=$(get_counter ${ns2} "MPTcpExtMPJoinSynAckRx") 323 if [ -z "$count" ]; then 324 echo -n "[skip]" 325 elif [ "$count" != "$syn_ack_nr" ]; then 326 echo "[fail] got $count JOIN[s] synack expected $syn_ack_nr" 327 ret=1 328 dump_stats=1 329 else 330 echo -n "[ ok ]" 331 fi 332 333 echo -n " - ack" 334 count=$(get_counter ${ns1} "MPTcpExtMPJoinAckRx") 335 if [ -z "$count" ]; then 336 echo "[skip]" 337 elif [ "$count" != "$ack_nr" ]; then 338 echo "[fail] got $count JOIN[s] ack expected $ack_nr" 339 ret=1 340 dump_stats=1 341 else 342 echo "[ ok ]" 343 fi 344 if [ "${dump_stats}" = 1 ]; then 345 echo Server ns stats 346 ip netns exec $ns1 nstat -as | grep MPTcp 347 echo Client ns stats 348 ip netns exec $ns2 nstat -as | grep MPTcp 349 fi 350} 351 352chk_add_nr() 353{ 354 local add_nr=$1 355 local echo_nr=$2 356 local count 357 local dump_stats 358 359 printf "%-39s %s" " " "add" 360 count=$(get_counter ${ns2} "MPTcpExtAddAddr") 361 if [ -z "$count" ]; then 362 echo -n "[skip]" 363 elif [ "$count" != "$add_nr" ]; then 364 echo "[fail] got $count ADD_ADDR[s] expected $add_nr" 365 ret=1 366 dump_stats=1 367 else 368 echo -n "[ ok ]" 369 fi 370 371 echo -n " - echo " 372 count=$(get_counter ${ns1} "MPTcpExtEchoAdd") 373 if [ -z "$count" ]; then 374 echo "[skip]" 375 elif [ "$count" != "$echo_nr" ]; then 376 echo "[fail] got $count ADD_ADDR echo[s] expected $echo_nr" 377 ret=1 378 dump_stats=1 379 else 380 echo "[ ok ]" 381 fi 382 383 if [ "${dump_stats}" = 1 ]; then 384 echo Server ns stats 385 ip netns exec $ns1 nstat -as | grep MPTcp 386 echo Client ns stats 387 ip netns exec $ns2 nstat -as | grep MPTcp 388 fi 389} 390 391chk_rm_nr() 392{ 393 local rm_addr_nr=$1 394 local rm_subflow_nr=$2 395 local count 396 local dump_stats 397 398 printf "%-39s %s" " " "rm " 399 count=$(get_counter ${ns1} "MPTcpExtRmAddr") 400 if [ -z "$count" ]; then 401 echo -n "[skip]" 402 elif [ "$count" != "$rm_addr_nr" ]; then 403 echo "[fail] got $count RM_ADDR[s] expected $rm_addr_nr" 404 ret=1 405 dump_stats=1 406 else 407 echo -n "[ ok ]" 408 fi 409 410 echo -n " - sf " 411 count=$(get_counter ${ns2} "MPTcpExtRmSubflow") 412 if [ -z "$count" ]; then 413 echo "[skip]" 414 elif [ "$count" != "$rm_subflow_nr" ]; then 415 echo "[fail] got $count RM_SUBFLOW[s] expected $rm_subflow_nr" 416 ret=1 417 dump_stats=1 418 else 419 echo "[ ok ]" 420 fi 421 422 if [ "${dump_stats}" = 1 ]; then 423 echo Server ns stats 424 ip netns exec $ns1 nstat -as | grep MPTcp 425 echo Client ns stats 426 ip netns exec $ns2 nstat -as | grep MPTcp 427 fi 428} 429 430sin=$(mktemp) 431sout=$(mktemp) 432cin=$(mktemp) 433cout=$(mktemp) 434init 435make_file "$cin" "client" 436make_file "$sin" "server" 437trap cleanup EXIT 438 439run_tests $ns1 $ns2 10.0.1.1 440chk_join_nr "no JOIN" "0" "0" "0" 441 442# subflow limted by client 443reset 444ip netns exec $ns2 ./pm_nl_ctl add 10.0.3.2 flags subflow 445run_tests $ns1 $ns2 10.0.1.1 446chk_join_nr "single subflow, limited by client" 0 0 0 447 448# subflow limted by server 449reset 450ip netns exec $ns2 ./pm_nl_ctl limits 0 1 451ip netns exec $ns2 ./pm_nl_ctl add 10.0.3.2 flags subflow 452run_tests $ns1 $ns2 10.0.1.1 453chk_join_nr "single subflow, limited by server" 1 1 0 454 455# subflow 456reset 457ip netns exec $ns1 ./pm_nl_ctl limits 0 1 458ip netns exec $ns2 ./pm_nl_ctl limits 0 1 459ip netns exec $ns2 ./pm_nl_ctl add 10.0.3.2 flags subflow 460run_tests $ns1 $ns2 10.0.1.1 461chk_join_nr "single subflow" 1 1 1 462 463# multiple subflows 464reset 465ip netns exec $ns1 ./pm_nl_ctl limits 0 2 466ip netns exec $ns2 ./pm_nl_ctl limits 0 2 467ip netns exec $ns2 ./pm_nl_ctl add 10.0.3.2 flags subflow 468ip netns exec $ns2 ./pm_nl_ctl add 10.0.2.2 flags subflow 469run_tests $ns1 $ns2 10.0.1.1 470chk_join_nr "multiple subflows" 2 2 2 471 472# multiple subflows limited by serverf 473reset 474ip netns exec $ns1 ./pm_nl_ctl limits 0 1 475ip netns exec $ns2 ./pm_nl_ctl limits 0 2 476ip netns exec $ns2 ./pm_nl_ctl add 10.0.3.2 flags subflow 477ip netns exec $ns2 ./pm_nl_ctl add 10.0.2.2 flags subflow 478run_tests $ns1 $ns2 10.0.1.1 479chk_join_nr "multiple subflows, limited by server" 2 2 1 480 481# add_address, unused 482reset 483ip netns exec $ns1 ./pm_nl_ctl add 10.0.2.1 flags signal 484run_tests $ns1 $ns2 10.0.1.1 485chk_join_nr "unused signal address" 0 0 0 486chk_add_nr 1 1 487 488# accept and use add_addr 489reset 490ip netns exec $ns1 ./pm_nl_ctl limits 0 1 491ip netns exec $ns2 ./pm_nl_ctl limits 1 1 492ip netns exec $ns1 ./pm_nl_ctl add 10.0.2.1 flags signal 493run_tests $ns1 $ns2 10.0.1.1 494chk_join_nr "signal address" 1 1 1 495chk_add_nr 1 1 496 497# accept and use add_addr with an additional subflow 498# note: signal address in server ns and local addresses in client ns must 499# belong to different subnets or one of the listed local address could be 500# used for 'add_addr' subflow 501reset 502ip netns exec $ns1 ./pm_nl_ctl add 10.0.2.1 flags signal 503ip netns exec $ns1 ./pm_nl_ctl limits 0 2 504ip netns exec $ns2 ./pm_nl_ctl limits 1 2 505ip netns exec $ns2 ./pm_nl_ctl add 10.0.3.2 flags subflow 506run_tests $ns1 $ns2 10.0.1.1 507chk_join_nr "subflow and signal" 2 2 2 508chk_add_nr 1 1 509 510# accept and use add_addr with additional subflows 511reset 512ip netns exec $ns1 ./pm_nl_ctl limits 0 3 513ip netns exec $ns1 ./pm_nl_ctl add 10.0.2.1 flags signal 514ip netns exec $ns2 ./pm_nl_ctl limits 1 3 515ip netns exec $ns2 ./pm_nl_ctl add 10.0.3.2 flags subflow 516ip netns exec $ns2 ./pm_nl_ctl add 10.0.4.2 flags subflow 517run_tests $ns1 $ns2 10.0.1.1 518chk_join_nr "multiple subflows and signal" 3 3 3 519chk_add_nr 1 1 520 521# single subflow, remove 522reset 523ip netns exec $ns1 ./pm_nl_ctl limits 0 1 524ip netns exec $ns2 ./pm_nl_ctl limits 0 1 525ip netns exec $ns2 ./pm_nl_ctl add 10.0.3.2 flags subflow 526run_remove_tests $ns1 $ns2 10.0.1.1 0 1 527chk_join_nr "remove single subflow" 1 1 1 528chk_rm_nr 1 1 529 530# multiple subflows, remove 531reset 532ip netns exec $ns1 ./pm_nl_ctl limits 0 2 533ip netns exec $ns2 ./pm_nl_ctl limits 0 2 534ip netns exec $ns2 ./pm_nl_ctl add 10.0.2.2 flags subflow 535ip netns exec $ns2 ./pm_nl_ctl add 10.0.3.2 flags subflow 536run_remove_tests $ns1 $ns2 10.0.1.1 0 2 537chk_join_nr "remove multiple subflows" 2 2 2 538chk_rm_nr 2 2 539 540# single address, remove 541reset 542ip netns exec $ns1 ./pm_nl_ctl limits 0 1 543ip netns exec $ns1 ./pm_nl_ctl add 10.0.2.1 flags signal 544ip netns exec $ns2 ./pm_nl_ctl limits 1 1 545run_remove_tests $ns1 $ns2 10.0.1.1 1 0 546chk_join_nr "remove single address" 1 1 1 547chk_add_nr 1 1 548chk_rm_nr 0 0 549 550# subflow and signal, remove 551reset 552ip netns exec $ns1 ./pm_nl_ctl limits 0 2 553ip netns exec $ns1 ./pm_nl_ctl add 10.0.2.1 flags signal 554ip netns exec $ns2 ./pm_nl_ctl limits 1 2 555ip netns exec $ns2 ./pm_nl_ctl add 10.0.3.2 flags subflow 556run_remove_tests $ns1 $ns2 10.0.1.1 1 1 557chk_join_nr "remove subflow and signal" 2 2 2 558chk_add_nr 1 1 559chk_rm_nr 1 1 560 561# subflows and signal, remove 562reset 563ip netns exec $ns1 ./pm_nl_ctl limits 0 3 564ip netns exec $ns1 ./pm_nl_ctl add 10.0.2.1 flags signal 565ip netns exec $ns2 ./pm_nl_ctl limits 1 3 566ip netns exec $ns2 ./pm_nl_ctl add 10.0.3.2 flags subflow 567ip netns exec $ns2 ./pm_nl_ctl add 10.0.4.2 flags subflow 568run_remove_tests $ns1 $ns2 10.0.1.1 1 2 569chk_join_nr "remove subflows and signal" 3 3 3 570chk_add_nr 1 1 571chk_rm_nr 2 2 572 573# single subflow, syncookies 574reset_with_cookies 575ip netns exec $ns1 ./pm_nl_ctl limits 0 1 576ip netns exec $ns2 ./pm_nl_ctl limits 0 1 577ip netns exec $ns2 ./pm_nl_ctl add 10.0.3.2 flags subflow 578run_tests $ns1 $ns2 10.0.1.1 579chk_join_nr "single subflow with syn cookies" 1 1 1 580 581# multiple subflows with syn cookies 582reset_with_cookies 583ip netns exec $ns1 ./pm_nl_ctl limits 0 2 584ip netns exec $ns2 ./pm_nl_ctl limits 0 2 585ip netns exec $ns2 ./pm_nl_ctl add 10.0.3.2 flags subflow 586ip netns exec $ns2 ./pm_nl_ctl add 10.0.2.2 flags subflow 587run_tests $ns1 $ns2 10.0.1.1 588chk_join_nr "multiple subflows with syn cookies" 2 2 2 589 590# multiple subflows limited by server 591reset_with_cookies 592ip netns exec $ns1 ./pm_nl_ctl limits 0 1 593ip netns exec $ns2 ./pm_nl_ctl limits 0 2 594ip netns exec $ns2 ./pm_nl_ctl add 10.0.3.2 flags subflow 595ip netns exec $ns2 ./pm_nl_ctl add 10.0.2.2 flags subflow 596run_tests $ns1 $ns2 10.0.1.1 597chk_join_nr "subflows limited by server w cookies" 2 2 1 598 599# test signal address with cookies 600reset_with_cookies 601ip netns exec $ns1 ./pm_nl_ctl limits 0 1 602ip netns exec $ns2 ./pm_nl_ctl limits 1 1 603ip netns exec $ns1 ./pm_nl_ctl add 10.0.2.1 flags signal 604run_tests $ns1 $ns2 10.0.1.1 605chk_join_nr "signal address with syn cookies" 1 1 1 606chk_add_nr 1 1 607 608# test cookie with subflow and signal 609reset_with_cookies 610ip netns exec $ns1 ./pm_nl_ctl add 10.0.2.1 flags signal 611ip netns exec $ns1 ./pm_nl_ctl limits 0 2 612ip netns exec $ns2 ./pm_nl_ctl limits 1 2 613ip netns exec $ns2 ./pm_nl_ctl add 10.0.3.2 flags subflow 614run_tests $ns1 $ns2 10.0.1.1 615chk_join_nr "subflow and signal w cookies" 2 2 2 616chk_add_nr 1 1 617 618# accept and use add_addr with additional subflows 619reset_with_cookies 620ip netns exec $ns1 ./pm_nl_ctl limits 0 3 621ip netns exec $ns1 ./pm_nl_ctl add 10.0.2.1 flags signal 622ip netns exec $ns2 ./pm_nl_ctl limits 1 3 623ip netns exec $ns2 ./pm_nl_ctl add 10.0.3.2 flags subflow 624ip netns exec $ns2 ./pm_nl_ctl add 10.0.4.2 flags subflow 625run_tests $ns1 $ns2 10.0.1.1 626chk_join_nr "subflows and signal w. cookies" 3 3 3 627chk_add_nr 1 1 628 629exit $ret 630