1#!/bin/bash 2# SPDX-License-Identifier: GPL-2.0 3 4time_start=$(date +%s) 5 6optstring="S:R:d:e:l:r:h4cm:f:tC" 7ret=0 8sin="" 9sout="" 10cin="" 11cout="" 12ksft_skip=4 13capture=false 14timeout_poll=30 15timeout_test=$((timeout_poll * 2 + 1)) 16ipv6=true 17ethtool_random_on=true 18tc_delay="$((RANDOM%50))" 19tc_loss=$((RANDOM%101)) 20testmode="" 21sndbuf=0 22rcvbuf=0 23options_log=true 24do_tcp=0 25checksum=false 26filesize=0 27 28if [ $tc_loss -eq 100 ];then 29 tc_loss=1% 30elif [ $tc_loss -ge 10 ]; then 31 tc_loss=0.$tc_loss% 32elif [ $tc_loss -ge 1 ]; then 33 tc_loss=0.0$tc_loss% 34else 35 tc_loss="" 36fi 37 38usage() { 39 echo "Usage: $0 [ -a ]" 40 echo -e "\t-d: tc/netem delay in milliseconds, e.g. \"-d 10\" (default random)" 41 echo -e "\t-l: tc/netem loss percentage, e.g. \"-l 0.02\" (default random)" 42 echo -e "\t-r: tc/netem reorder mode, e.g. \"-r 25% 50% gap 5\", use "-r 0" to disable reordering (default random)" 43 echo -e "\t-e: ethtool features to disable, e.g.: \"-e tso -e gso\" (default: randomly disable any of tso/gso/gro)" 44 echo -e "\t-4: IPv4 only: disable IPv6 tests (default: test both IPv4 and IPv6)" 45 echo -e "\t-c: capture packets for each test using tcpdump (default: no capture)" 46 echo -e "\t-f: size of file to transfer in bytes (default random)" 47 echo -e "\t-S: set sndbuf value (default: use kernel default)" 48 echo -e "\t-R: set rcvbuf value (default: use kernel default)" 49 echo -e "\t-m: test mode (poll, sendfile; default: poll)" 50 echo -e "\t-t: also run tests with TCP (use twice to non-fallback tcp)" 51 echo -e "\t-C: enable the MPTCP data checksum" 52} 53 54while getopts "$optstring" option;do 55 case "$option" in 56 "h") 57 usage $0 58 exit 0 59 ;; 60 "d") 61 if [ $OPTARG -ge 0 ];then 62 tc_delay="$OPTARG" 63 else 64 echo "-d requires numeric argument, got \"$OPTARG\"" 1>&2 65 exit 1 66 fi 67 ;; 68 "e") 69 ethtool_args="$ethtool_args $OPTARG off" 70 ethtool_random_on=false 71 ;; 72 "l") 73 tc_loss="$OPTARG" 74 ;; 75 "r") 76 tc_reorder="$OPTARG" 77 ;; 78 "4") 79 ipv6=false 80 ;; 81 "c") 82 capture=true 83 ;; 84 "S") 85 if [ $OPTARG -ge 0 ];then 86 sndbuf="$OPTARG" 87 else 88 echo "-S requires numeric argument, got \"$OPTARG\"" 1>&2 89 exit 1 90 fi 91 ;; 92 "R") 93 if [ $OPTARG -ge 0 ];then 94 rcvbuf="$OPTARG" 95 else 96 echo "-R requires numeric argument, got \"$OPTARG\"" 1>&2 97 exit 1 98 fi 99 ;; 100 "m") 101 testmode="$OPTARG" 102 ;; 103 "f") 104 filesize="$OPTARG" 105 ;; 106 "t") 107 do_tcp=$((do_tcp+1)) 108 ;; 109 "C") 110 checksum=true 111 ;; 112 "?") 113 usage $0 114 exit 1 115 ;; 116 esac 117done 118 119sec=$(date +%s) 120rndh=$(printf %x $sec)-$(mktemp -u XXXXXX) 121ns1="ns1-$rndh" 122ns2="ns2-$rndh" 123ns3="ns3-$rndh" 124ns4="ns4-$rndh" 125 126TEST_COUNT=0 127 128cleanup() 129{ 130 rm -f "$cin" "$cout" 131 rm -f "$sin" "$sout" 132 rm -f "$capout" 133 134 local netns 135 for netns in "$ns1" "$ns2" "$ns3" "$ns4";do 136 ip netns del $netns 137 rm -f /tmp/$netns.{nstat,out} 138 done 139} 140 141ip -Version > /dev/null 2>&1 142if [ $? -ne 0 ];then 143 echo "SKIP: Could not run test without ip tool" 144 exit $ksft_skip 145fi 146 147sin=$(mktemp) 148sout=$(mktemp) 149cin=$(mktemp) 150cout=$(mktemp) 151capout=$(mktemp) 152trap cleanup EXIT 153 154for i in "$ns1" "$ns2" "$ns3" "$ns4";do 155 ip netns add $i || exit $ksft_skip 156 ip -net $i link set lo up 157done 158 159# "$ns1" ns2 ns3 ns4 160# ns1eth2 ns2eth1 ns2eth3 ns3eth2 ns3eth4 ns4eth3 161# - drop 1% -> reorder 25% 162# <- TSO off - 163 164ip link add ns1eth2 netns "$ns1" type veth peer name ns2eth1 netns "$ns2" 165ip link add ns2eth3 netns "$ns2" type veth peer name ns3eth2 netns "$ns3" 166ip link add ns3eth4 netns "$ns3" type veth peer name ns4eth3 netns "$ns4" 167 168ip -net "$ns1" addr add 10.0.1.1/24 dev ns1eth2 169ip -net "$ns1" addr add dead:beef:1::1/64 dev ns1eth2 nodad 170 171ip -net "$ns1" link set ns1eth2 up 172ip -net "$ns1" route add default via 10.0.1.2 173ip -net "$ns1" route add default via dead:beef:1::2 174 175ip -net "$ns2" addr add 10.0.1.2/24 dev ns2eth1 176ip -net "$ns2" addr add dead:beef:1::2/64 dev ns2eth1 nodad 177ip -net "$ns2" link set ns2eth1 up 178 179ip -net "$ns2" addr add 10.0.2.1/24 dev ns2eth3 180ip -net "$ns2" addr add dead:beef:2::1/64 dev ns2eth3 nodad 181ip -net "$ns2" link set ns2eth3 up 182ip -net "$ns2" route add default via 10.0.2.2 183ip -net "$ns2" route add default via dead:beef:2::2 184ip netns exec "$ns2" sysctl -q net.ipv4.ip_forward=1 185ip netns exec "$ns2" sysctl -q net.ipv6.conf.all.forwarding=1 186 187ip -net "$ns3" addr add 10.0.2.2/24 dev ns3eth2 188ip -net "$ns3" addr add dead:beef:2::2/64 dev ns3eth2 nodad 189ip -net "$ns3" link set ns3eth2 up 190 191ip -net "$ns3" addr add 10.0.3.2/24 dev ns3eth4 192ip -net "$ns3" addr add dead:beef:3::2/64 dev ns3eth4 nodad 193ip -net "$ns3" link set ns3eth4 up 194ip -net "$ns3" route add default via 10.0.2.1 195ip -net "$ns3" route add default via dead:beef:2::1 196ip netns exec "$ns3" sysctl -q net.ipv4.ip_forward=1 197ip netns exec "$ns3" sysctl -q net.ipv6.conf.all.forwarding=1 198 199ip -net "$ns4" addr add 10.0.3.1/24 dev ns4eth3 200ip -net "$ns4" addr add dead:beef:3::1/64 dev ns4eth3 nodad 201ip -net "$ns4" link set ns4eth3 up 202ip -net "$ns4" route add default via 10.0.3.2 203ip -net "$ns4" route add default via dead:beef:3::2 204 205if $checksum; then 206 for i in "$ns1" "$ns2" "$ns3" "$ns4";do 207 ip netns exec $i sysctl -q net.mptcp.checksum_enabled=1 208 done 209fi 210 211set_ethtool_flags() { 212 local ns="$1" 213 local dev="$2" 214 local flags="$3" 215 216 ip netns exec $ns ethtool -K $dev $flags 2>/dev/null 217 [ $? -eq 0 ] && echo "INFO: set $ns dev $dev: ethtool -K $flags" 218} 219 220set_random_ethtool_flags() { 221 local flags="" 222 local r=$RANDOM 223 224 local pick1=$((r & 1)) 225 local pick2=$((r & 2)) 226 local pick3=$((r & 4)) 227 228 [ $pick1 -ne 0 ] && flags="tso off" 229 [ $pick2 -ne 0 ] && flags="$flags gso off" 230 [ $pick3 -ne 0 ] && flags="$flags gro off" 231 232 [ -z "$flags" ] && return 233 234 set_ethtool_flags "$1" "$2" "$flags" 235} 236 237if $ethtool_random_on;then 238 set_random_ethtool_flags "$ns3" ns3eth2 239 set_random_ethtool_flags "$ns4" ns4eth3 240else 241 set_ethtool_flags "$ns3" ns3eth2 "$ethtool_args" 242 set_ethtool_flags "$ns4" ns4eth3 "$ethtool_args" 243fi 244 245print_file_err() 246{ 247 ls -l "$1" 1>&2 248 echo "Trailing bytes are: " 249 tail -c 27 "$1" 250} 251 252check_transfer() 253{ 254 local in=$1 255 local out=$2 256 local what=$3 257 258 cmp "$in" "$out" > /dev/null 2>&1 259 if [ $? -ne 0 ] ;then 260 echo "[ FAIL ] $what does not match (in, out):" 261 print_file_err "$in" 262 print_file_err "$out" 263 264 return 1 265 fi 266 267 return 0 268} 269 270check_mptcp_disabled() 271{ 272 local disabled_ns 273 disabled_ns="ns_disabled-$sech-$(mktemp -u XXXXXX)" 274 ip netns add ${disabled_ns} || exit $ksft_skip 275 276 # net.mptcp.enabled should be enabled by default 277 if [ "$(ip netns exec ${disabled_ns} sysctl net.mptcp.enabled | awk '{ print $3 }')" -ne 1 ]; then 278 echo -e "net.mptcp.enabled sysctl is not 1 by default\t\t[ FAIL ]" 279 ret=1 280 return 1 281 fi 282 ip netns exec ${disabled_ns} sysctl -q net.mptcp.enabled=0 283 284 local err=0 285 LC_ALL=C ip netns exec ${disabled_ns} ./mptcp_connect -p 10000 -s MPTCP 127.0.0.1 < "$cin" 2>&1 | \ 286 grep -q "^socket: Protocol not available$" && err=1 287 ip netns delete ${disabled_ns} 288 289 if [ ${err} -eq 0 ]; then 290 echo -e "New MPTCP socket cannot be blocked via sysctl\t\t[ FAIL ]" 291 ret=1 292 return 1 293 fi 294 295 echo -e "New MPTCP socket can be blocked via sysctl\t\t[ OK ]" 296 return 0 297} 298 299check_mptcp_ulp_setsockopt() 300{ 301 local t retval 302 t="ns_ulp-$sech-$(mktemp -u XXXXXX)" 303 304 ip netns add ${t} || exit $ksft_skip 305 if ! ip netns exec ${t} ./mptcp_connect -u -p 10000 -s TCP 127.0.0.1 2>&1; then 306 printf "setsockopt(..., TCP_ULP, \"mptcp\", ...) allowed\t[ FAIL ]\n" 307 retval=1 308 ret=$retval 309 else 310 printf "setsockopt(..., TCP_ULP, \"mptcp\", ...) blocked\t[ OK ]\n" 311 retval=0 312 fi 313 ip netns del ${t} 314 return $retval 315} 316 317# $1: IP address 318is_v6() 319{ 320 [ -z "${1##*:*}" ] 321} 322 323do_ping() 324{ 325 local listener_ns="$1" 326 local connector_ns="$2" 327 local connect_addr="$3" 328 local ping_args="-q -c 1" 329 330 if is_v6 "${connect_addr}"; then 331 $ipv6 || return 0 332 ping_args="${ping_args} -6" 333 fi 334 335 ip netns exec ${connector_ns} ping ${ping_args} $connect_addr >/dev/null 336 if [ $? -ne 0 ] ; then 337 echo "$listener_ns -> $connect_addr connectivity [ FAIL ]" 1>&2 338 ret=1 339 340 return 1 341 fi 342 343 return 0 344} 345 346# $1: ns, $2: MIB counter 347get_mib_counter() 348{ 349 local listener_ns="${1}" 350 local mib="${2}" 351 352 # strip the header 353 ip netns exec "${listener_ns}" \ 354 nstat -z -a "${mib}" | \ 355 tail -n+2 | \ 356 while read a count c rest; do 357 echo $count 358 done 359} 360 361# $1: ns, $2: port 362wait_local_port_listen() 363{ 364 local listener_ns="${1}" 365 local port="${2}" 366 367 local port_hex i 368 369 port_hex="$(printf "%04X" "${port}")" 370 for i in $(seq 10); do 371 ip netns exec "${listener_ns}" cat /proc/net/tcp* | \ 372 awk "BEGIN {rc=1} {if (\$2 ~ /:${port_hex}\$/ && \$4 ~ /0A/) {rc=0; exit}} END {exit rc}" && 373 break 374 sleep 0.1 375 done 376} 377 378do_transfer() 379{ 380 local listener_ns="$1" 381 local connector_ns="$2" 382 local cl_proto="$3" 383 local srv_proto="$4" 384 local connect_addr="$5" 385 local local_addr="$6" 386 local extra_args="$7" 387 388 local port 389 port=$((10000+$TEST_COUNT)) 390 TEST_COUNT=$((TEST_COUNT+1)) 391 392 if [ "$rcvbuf" -gt 0 ]; then 393 extra_args="$extra_args -R $rcvbuf" 394 fi 395 396 if [ "$sndbuf" -gt 0 ]; then 397 extra_args="$extra_args -S $sndbuf" 398 fi 399 400 if [ -n "$testmode" ]; then 401 extra_args="$extra_args -m $testmode" 402 fi 403 404 if [ -n "$extra_args" ] && $options_log; then 405 echo "INFO: extra options: $extra_args" 406 fi 407 options_log=false 408 409 :> "$cout" 410 :> "$sout" 411 :> "$capout" 412 413 local addr_port 414 addr_port=$(printf "%s:%d" ${connect_addr} ${port}) 415 printf "%.3s %-5s -> %.3s (%-20s) %-5s\t" ${connector_ns} ${cl_proto} ${listener_ns} ${addr_port} ${srv_proto} 416 417 if $capture; then 418 local capuser 419 if [ -z $SUDO_USER ] ; then 420 capuser="" 421 else 422 capuser="-Z $SUDO_USER" 423 fi 424 425 local capfile="${rndh}-${connector_ns:0:3}-${listener_ns:0:3}-${cl_proto}-${srv_proto}-${connect_addr}-${port}" 426 local capopt="-i any -s 65535 -B 32768 ${capuser}" 427 428 ip netns exec ${listener_ns} tcpdump ${capopt} -w "${capfile}-listener.pcap" >> "${capout}" 2>&1 & 429 local cappid_listener=$! 430 431 ip netns exec ${connector_ns} tcpdump ${capopt} -w "${capfile}-connector.pcap" >> "${capout}" 2>&1 & 432 local cappid_connector=$! 433 434 sleep 1 435 fi 436 437 NSTAT_HISTORY=/tmp/${listener_ns}.nstat ip netns exec ${listener_ns} \ 438 nstat -n 439 if [ ${listener_ns} != ${connector_ns} ]; then 440 NSTAT_HISTORY=/tmp/${connector_ns}.nstat ip netns exec ${connector_ns} \ 441 nstat -n 442 fi 443 444 local stat_synrx_last_l=$(get_mib_counter "${listener_ns}" "MPTcpExtMPCapableSYNRX") 445 local stat_ackrx_last_l=$(get_mib_counter "${listener_ns}" "MPTcpExtMPCapableACKRX") 446 local stat_cookietx_last=$(get_mib_counter "${listener_ns}" "TcpExtSyncookiesSent") 447 local stat_cookierx_last=$(get_mib_counter "${listener_ns}" "TcpExtSyncookiesRecv") 448 449 timeout ${timeout_test} \ 450 ip netns exec ${listener_ns} \ 451 ./mptcp_connect -t ${timeout_poll} -l -p $port -s ${srv_proto} \ 452 $extra_args $local_addr < "$sin" > "$sout" & 453 local spid=$! 454 455 wait_local_port_listen "${listener_ns}" "${port}" 456 457 local start 458 start=$(date +%s%3N) 459 timeout ${timeout_test} \ 460 ip netns exec ${connector_ns} \ 461 ./mptcp_connect -t ${timeout_poll} -p $port -s ${cl_proto} \ 462 $extra_args $connect_addr < "$cin" > "$cout" & 463 local cpid=$! 464 465 wait $cpid 466 local retc=$? 467 wait $spid 468 local rets=$? 469 470 local stop 471 stop=$(date +%s%3N) 472 473 if $capture; then 474 sleep 1 475 kill ${cappid_listener} 476 kill ${cappid_connector} 477 fi 478 479 NSTAT_HISTORY=/tmp/${listener_ns}.nstat ip netns exec ${listener_ns} \ 480 nstat | grep Tcp > /tmp/${listener_ns}.out 481 if [ ${listener_ns} != ${connector_ns} ]; then 482 NSTAT_HISTORY=/tmp/${connector_ns}.nstat ip netns exec ${connector_ns} \ 483 nstat | grep Tcp > /tmp/${connector_ns}.out 484 fi 485 486 local duration 487 duration=$((stop-start)) 488 printf "(duration %05sms) " "${duration}" 489 if [ ${rets} -ne 0 ] || [ ${retc} -ne 0 ]; then 490 echo "[ FAIL ] client exit code $retc, server $rets" 1>&2 491 echo -e "\nnetns ${listener_ns} socket stat for ${port}:" 1>&2 492 ip netns exec ${listener_ns} ss -Menita 1>&2 -o "sport = :$port" 493 cat /tmp/${listener_ns}.out 494 echo -e "\nnetns ${connector_ns} socket stat for ${port}:" 1>&2 495 ip netns exec ${connector_ns} ss -Menita 1>&2 -o "dport = :$port" 496 [ ${listener_ns} != ${connector_ns} ] && cat /tmp/${connector_ns}.out 497 498 echo 499 cat "$capout" 500 return 1 501 fi 502 503 check_transfer $sin $cout "file received by client" 504 retc=$? 505 check_transfer $cin $sout "file received by server" 506 rets=$? 507 508 local stat_synrx_now_l=$(get_mib_counter "${listener_ns}" "MPTcpExtMPCapableSYNRX") 509 local stat_ackrx_now_l=$(get_mib_counter "${listener_ns}" "MPTcpExtMPCapableACKRX") 510 local stat_cookietx_now=$(get_mib_counter "${listener_ns}" "TcpExtSyncookiesSent") 511 local stat_cookierx_now=$(get_mib_counter "${listener_ns}" "TcpExtSyncookiesRecv") 512 local stat_ooo_now=$(get_mib_counter "${listener_ns}" "TcpExtTCPOFOQueue") 513 514 expect_synrx=$((stat_synrx_last_l)) 515 expect_ackrx=$((stat_ackrx_last_l)) 516 517 cookies=$(ip netns exec ${listener_ns} sysctl net.ipv4.tcp_syncookies) 518 cookies=${cookies##*=} 519 520 if [ ${cl_proto} = "MPTCP" ] && [ ${srv_proto} = "MPTCP" ]; then 521 expect_synrx=$((stat_synrx_last_l+1)) 522 expect_ackrx=$((stat_ackrx_last_l+1)) 523 fi 524 525 if [ ${stat_synrx_now_l} -lt ${expect_synrx} ]; then 526 printf "[ FAIL ] lower MPC SYN rx (%d) than expected (%d)\n" \ 527 "${stat_synrx_now_l}" "${expect_synrx}" 1>&2 528 retc=1 529 fi 530 if [ ${stat_ackrx_now_l} -lt ${expect_ackrx} -a ${stat_ooo_now} -eq 0 ]; then 531 if [ ${stat_ooo_now} -eq 0 ]; then 532 printf "[ FAIL ] lower MPC ACK rx (%d) than expected (%d)\n" \ 533 "${stat_ackrx_now_l}" "${expect_ackrx}" 1>&2 534 rets=1 535 else 536 printf "[ Note ] fallback due to TCP OoO" 537 fi 538 fi 539 540 if [ $retc -eq 0 ] && [ $rets -eq 0 ]; then 541 printf "[ OK ]" 542 fi 543 544 if [ $cookies -eq 2 ];then 545 if [ $stat_cookietx_last -ge $stat_cookietx_now ] ;then 546 printf " WARN: CookieSent: did not advance" 547 fi 548 if [ $stat_cookierx_last -ge $stat_cookierx_now ] ;then 549 printf " WARN: CookieRecv: did not advance" 550 fi 551 else 552 if [ $stat_cookietx_last -ne $stat_cookietx_now ] ;then 553 printf " WARN: CookieSent: changed" 554 fi 555 if [ $stat_cookierx_last -ne $stat_cookierx_now ] ;then 556 printf " WARN: CookieRecv: changed" 557 fi 558 fi 559 560 if [ ${stat_synrx_now_l} -gt ${expect_synrx} ]; then 561 printf " WARN: SYNRX: expect %d, got %d (probably retransmissions)" \ 562 "${expect_synrx}" "${stat_synrx_now_l}" 563 fi 564 if [ ${stat_ackrx_now_l} -gt ${expect_ackrx} ]; then 565 printf " WARN: ACKRX: expect %d, got %d (probably retransmissions)" \ 566 "${expect_ackrx}" "${stat_ackrx_now_l}" 567 fi 568 569 echo 570 cat "$capout" 571 [ $retc -eq 0 ] && [ $rets -eq 0 ] 572} 573 574make_file() 575{ 576 local name=$1 577 local who=$2 578 local SIZE=$filesize 579 local ksize 580 local rem 581 582 if [ $SIZE -eq 0 ]; then 583 local MAXSIZE=$((1024 * 1024 * 8)) 584 local MINSIZE=$((1024 * 256)) 585 586 SIZE=$(((RANDOM * RANDOM + MINSIZE) % MAXSIZE)) 587 fi 588 589 ksize=$((SIZE / 1024)) 590 rem=$((SIZE - (ksize * 1024))) 591 592 dd if=/dev/urandom of="$name" bs=1024 count=$ksize 2> /dev/null 593 dd if=/dev/urandom conv=notrunc of="$name" bs=1 count=$rem 2> /dev/null 594 echo -e "\nMPTCP_TEST_FILE_END_MARKER" >> "$name" 595 596 echo "Created $name (size $(du -b "$name")) containing data sent by $who" 597} 598 599run_tests_lo() 600{ 601 local listener_ns="$1" 602 local connector_ns="$2" 603 local connect_addr="$3" 604 local loopback="$4" 605 local extra_args="$5" 606 local lret=0 607 608 # skip if test programs are running inside same netns for subsequent runs. 609 if [ $loopback -eq 0 ] && [ ${listener_ns} = ${connector_ns} ]; then 610 return 0 611 fi 612 613 # skip if we don't want v6 614 if ! $ipv6 && is_v6 "${connect_addr}"; then 615 return 0 616 fi 617 618 local local_addr 619 if is_v6 "${connect_addr}"; then 620 local_addr="::" 621 else 622 local_addr="0.0.0.0" 623 fi 624 625 do_transfer ${listener_ns} ${connector_ns} MPTCP MPTCP \ 626 ${connect_addr} ${local_addr} "${extra_args}" 627 lret=$? 628 if [ $lret -ne 0 ]; then 629 ret=$lret 630 return 1 631 fi 632 633 if [ $do_tcp -eq 0 ]; then 634 # don't bother testing fallback tcp except for loopback case. 635 if [ ${listener_ns} != ${connector_ns} ]; then 636 return 0 637 fi 638 fi 639 640 do_transfer ${listener_ns} ${connector_ns} MPTCP TCP \ 641 ${connect_addr} ${local_addr} "${extra_args}" 642 lret=$? 643 if [ $lret -ne 0 ]; then 644 ret=$lret 645 return 1 646 fi 647 648 do_transfer ${listener_ns} ${connector_ns} TCP MPTCP \ 649 ${connect_addr} ${local_addr} "${extra_args}" 650 lret=$? 651 if [ $lret -ne 0 ]; then 652 ret=$lret 653 return 1 654 fi 655 656 if [ $do_tcp -gt 1 ] ;then 657 do_transfer ${listener_ns} ${connector_ns} TCP TCP \ 658 ${connect_addr} ${local_addr} "${extra_args}" 659 lret=$? 660 if [ $lret -ne 0 ]; then 661 ret=$lret 662 return 1 663 fi 664 fi 665 666 return 0 667} 668 669run_tests() 670{ 671 run_tests_lo $1 $2 $3 0 672} 673 674run_tests_peekmode() 675{ 676 local peekmode="$1" 677 678 echo "INFO: with peek mode: ${peekmode}" 679 run_tests_lo "$ns1" "$ns1" 10.0.1.1 1 "-P ${peekmode}" 680 run_tests_lo "$ns1" "$ns1" dead:beef:1::1 1 "-P ${peekmode}" 681} 682 683display_time() 684{ 685 time_end=$(date +%s) 686 time_run=$((time_end-time_start)) 687 688 echo "Time: ${time_run} seconds" 689} 690 691stop_if_error() 692{ 693 local msg="$1" 694 695 if [ ${ret} -ne 0 ]; then 696 echo "FAIL: ${msg}" 1>&2 697 display_time 698 exit ${ret} 699 fi 700} 701 702make_file "$cin" "client" 703make_file "$sin" "server" 704 705check_mptcp_disabled 706 707check_mptcp_ulp_setsockopt 708 709stop_if_error "The kernel configuration is not valid for MPTCP" 710 711echo "INFO: validating network environment with pings" 712for sender in "$ns1" "$ns2" "$ns3" "$ns4";do 713 do_ping "$ns1" $sender 10.0.1.1 714 do_ping "$ns1" $sender dead:beef:1::1 715 716 do_ping "$ns2" $sender 10.0.1.2 717 do_ping "$ns2" $sender dead:beef:1::2 718 do_ping "$ns2" $sender 10.0.2.1 719 do_ping "$ns2" $sender dead:beef:2::1 720 721 do_ping "$ns3" $sender 10.0.2.2 722 do_ping "$ns3" $sender dead:beef:2::2 723 do_ping "$ns3" $sender 10.0.3.2 724 do_ping "$ns3" $sender dead:beef:3::2 725 726 do_ping "$ns4" $sender 10.0.3.1 727 do_ping "$ns4" $sender dead:beef:3::1 728done 729 730stop_if_error "Could not even run ping tests" 731 732[ -n "$tc_loss" ] && tc -net "$ns2" qdisc add dev ns2eth3 root netem loss random $tc_loss delay ${tc_delay}ms 733echo -n "INFO: Using loss of $tc_loss " 734test "$tc_delay" -gt 0 && echo -n "delay $tc_delay ms " 735 736reorder_delay=$(($tc_delay / 4)) 737 738if [ -z "${tc_reorder}" ]; then 739 reorder1=$((RANDOM%10)) 740 reorder1=$((100 - reorder1)) 741 reorder2=$((RANDOM%100)) 742 743 if [ $reorder_delay -gt 0 ] && [ $reorder1 -lt 100 ] && [ $reorder2 -gt 0 ]; then 744 tc_reorder="reorder ${reorder1}% ${reorder2}%" 745 echo -n "$tc_reorder with delay ${reorder_delay}ms " 746 fi 747elif [ "$tc_reorder" = "0" ];then 748 tc_reorder="" 749elif [ "$reorder_delay" -gt 0 ];then 750 # reordering requires some delay 751 tc_reorder="reorder $tc_reorder" 752 echo -n "$tc_reorder with delay ${reorder_delay}ms " 753fi 754 755echo "on ns3eth4" 756 757tc -net "$ns3" qdisc add dev ns3eth4 root netem delay ${reorder_delay}ms $tc_reorder 758 759run_tests_lo "$ns1" "$ns1" 10.0.1.1 1 760stop_if_error "Could not even run loopback test" 761 762run_tests_lo "$ns1" "$ns1" dead:beef:1::1 1 763stop_if_error "Could not even run loopback v6 test" 764 765for sender in $ns1 $ns2 $ns3 $ns4;do 766 # ns1<->ns2 is not subject to reordering/tc delays. Use it to test 767 # mptcp syncookie support. 768 if [ $sender = $ns1 ]; then 769 ip netns exec "$ns2" sysctl -q net.ipv4.tcp_syncookies=2 770 else 771 ip netns exec "$ns2" sysctl -q net.ipv4.tcp_syncookies=1 772 fi 773 774 run_tests "$ns1" $sender 10.0.1.1 775 run_tests "$ns1" $sender dead:beef:1::1 776 777 run_tests "$ns2" $sender 10.0.1.2 778 run_tests "$ns2" $sender dead:beef:1::2 779 run_tests "$ns2" $sender 10.0.2.1 780 run_tests "$ns2" $sender dead:beef:2::1 781 782 run_tests "$ns3" $sender 10.0.2.2 783 run_tests "$ns3" $sender dead:beef:2::2 784 run_tests "$ns3" $sender 10.0.3.2 785 run_tests "$ns3" $sender dead:beef:3::2 786 787 run_tests "$ns4" $sender 10.0.3.1 788 run_tests "$ns4" $sender dead:beef:3::1 789 790 stop_if_error "Tests with $sender as a sender have failed" 791done 792 793run_tests_peekmode "saveWithPeek" 794run_tests_peekmode "saveAfterPeek" 795stop_if_error "Tests with peek mode have failed" 796 797display_time 798exit $ret 799