1048d19d4SFlorian Westphal#!/bin/bash 2048d19d4SFlorian Westphal# SPDX-License-Identifier: GPL-2.0 3048d19d4SFlorian Westphal 45b5ff824SMatthieu Baerts (NGI0)# Double quotes to prevent globbing and word splitting is recommended in new 55b5ff824SMatthieu Baerts (NGI0)# code but we accept it, especially because there were too many before having 65b5ff824SMatthieu Baerts (NGI0)# address all other issues detected by shellcheck. 75b5ff824SMatthieu Baerts (NGI0)#shellcheck disable=SC2086 85b5ff824SMatthieu Baerts (NGI0) 9d83013bdSMatthieu Baerts. "$(dirname "${0}")/mptcp_lib.sh" 10d83013bdSMatthieu Baerts 11048d19d4SFlorian Westphaltime_start=$(date +%s) 12048d19d4SFlorian Westphal 1394d66ba1SGeliang Tangoptstring="S:R:d:e:l:r:h4cm:f:tC" 14048d19d4SFlorian Westphalret=0 15edbc16c4SMatthieu Baertsfinal_ret=0 16048d19d4SFlorian Westphalsin="" 17048d19d4SFlorian Westphalsout="" 1805be5e27SPaolo Abenicin_disconnect="" 19048d19d4SFlorian Westphalcin="" 20048d19d4SFlorian Westphalcout="" 21048d19d4SFlorian Westphalcapture=false 225888a61cSMatthieu Baertstimeout_poll=30 235888a61cSMatthieu Baertstimeout_test=$((timeout_poll * 2 + 1)) 24048d19d4SFlorian Westphalipv6=true 25048d19d4SFlorian Westphalethtool_random_on=true 26e5484658SChristoph Paaschtc_delay="$((RANDOM%50))" 27048d19d4SFlorian Westphaltc_loss=$((RANDOM%101)) 28048d19d4SFlorian Westphaltestmode="" 29048d19d4SFlorian Westphalsndbuf=0 308a4b910dSFlorian Westphalrcvbuf=0 31048d19d4SFlorian Westphaloptions_log=true 32767659f6SFlorian Westphaldo_tcp=0 3394d66ba1SGeliang Tangchecksum=false 34767659f6SFlorian Westphalfilesize=0 3505be5e27SPaolo Abeniconnect_per_transfer=1 36048d19d4SFlorian Westphal 37048d19d4SFlorian Westphalif [ $tc_loss -eq 100 ];then 38048d19d4SFlorian Westphal tc_loss=1% 39048d19d4SFlorian Westphalelif [ $tc_loss -ge 10 ]; then 40048d19d4SFlorian Westphal tc_loss=0.$tc_loss% 41048d19d4SFlorian Westphalelif [ $tc_loss -ge 1 ]; then 42048d19d4SFlorian Westphal tc_loss=0.0$tc_loss% 43048d19d4SFlorian Westphalelse 44048d19d4SFlorian Westphal tc_loss="" 45048d19d4SFlorian Westphalfi 46048d19d4SFlorian Westphal 47048d19d4SFlorian Westphalusage() { 48048d19d4SFlorian Westphal echo "Usage: $0 [ -a ]" 49048d19d4SFlorian Westphal echo -e "\t-d: tc/netem delay in milliseconds, e.g. \"-d 10\" (default random)" 50048d19d4SFlorian Westphal echo -e "\t-l: tc/netem loss percentage, e.g. \"-l 0.02\" (default random)" 51048d19d4SFlorian Westphal echo -e "\t-r: tc/netem reorder mode, e.g. \"-r 25% 50% gap 5\", use "-r 0" to disable reordering (default random)" 52048d19d4SFlorian Westphal echo -e "\t-e: ethtool features to disable, e.g.: \"-e tso -e gso\" (default: randomly disable any of tso/gso/gro)" 53048d19d4SFlorian Westphal echo -e "\t-4: IPv4 only: disable IPv6 tests (default: test both IPv4 and IPv6)" 54048d19d4SFlorian Westphal echo -e "\t-c: capture packets for each test using tcpdump (default: no capture)" 55767659f6SFlorian Westphal echo -e "\t-f: size of file to transfer in bytes (default random)" 568a4b910dSFlorian Westphal echo -e "\t-S: set sndbuf value (default: use kernel default)" 578a4b910dSFlorian Westphal echo -e "\t-R: set rcvbuf value (default: use kernel default)" 58048d19d4SFlorian Westphal echo -e "\t-m: test mode (poll, sendfile; default: poll)" 59767659f6SFlorian Westphal echo -e "\t-t: also run tests with TCP (use twice to non-fallback tcp)" 6094d66ba1SGeliang Tang echo -e "\t-C: enable the MPTCP data checksum" 61048d19d4SFlorian Westphal} 62048d19d4SFlorian Westphal 63048d19d4SFlorian Westphalwhile getopts "$optstring" option;do 64048d19d4SFlorian Westphal case "$option" in 65048d19d4SFlorian Westphal "h") 66048d19d4SFlorian Westphal usage $0 67048d19d4SFlorian Westphal exit 0 68048d19d4SFlorian Westphal ;; 69048d19d4SFlorian Westphal "d") 70048d19d4SFlorian Westphal if [ $OPTARG -ge 0 ];then 71048d19d4SFlorian Westphal tc_delay="$OPTARG" 72048d19d4SFlorian Westphal else 73048d19d4SFlorian Westphal echo "-d requires numeric argument, got \"$OPTARG\"" 1>&2 74048d19d4SFlorian Westphal exit 1 75048d19d4SFlorian Westphal fi 76048d19d4SFlorian Westphal ;; 77048d19d4SFlorian Westphal "e") 78048d19d4SFlorian Westphal ethtool_args="$ethtool_args $OPTARG off" 79048d19d4SFlorian Westphal ethtool_random_on=false 80048d19d4SFlorian Westphal ;; 81048d19d4SFlorian Westphal "l") 82048d19d4SFlorian Westphal tc_loss="$OPTARG" 83048d19d4SFlorian Westphal ;; 84048d19d4SFlorian Westphal "r") 85048d19d4SFlorian Westphal tc_reorder="$OPTARG" 86048d19d4SFlorian Westphal ;; 87048d19d4SFlorian Westphal "4") 88048d19d4SFlorian Westphal ipv6=false 89048d19d4SFlorian Westphal ;; 90048d19d4SFlorian Westphal "c") 91048d19d4SFlorian Westphal capture=true 92048d19d4SFlorian Westphal ;; 938a4b910dSFlorian Westphal "S") 94048d19d4SFlorian Westphal if [ $OPTARG -ge 0 ];then 95048d19d4SFlorian Westphal sndbuf="$OPTARG" 96048d19d4SFlorian Westphal else 978a4b910dSFlorian Westphal echo "-S requires numeric argument, got \"$OPTARG\"" 1>&2 988a4b910dSFlorian Westphal exit 1 998a4b910dSFlorian Westphal fi 1008a4b910dSFlorian Westphal ;; 1018a4b910dSFlorian Westphal "R") 1028a4b910dSFlorian Westphal if [ $OPTARG -ge 0 ];then 1038a4b910dSFlorian Westphal rcvbuf="$OPTARG" 1048a4b910dSFlorian Westphal else 1058a4b910dSFlorian Westphal echo "-R requires numeric argument, got \"$OPTARG\"" 1>&2 106048d19d4SFlorian Westphal exit 1 107048d19d4SFlorian Westphal fi 108048d19d4SFlorian Westphal ;; 109048d19d4SFlorian Westphal "m") 110048d19d4SFlorian Westphal testmode="$OPTARG" 111048d19d4SFlorian Westphal ;; 112767659f6SFlorian Westphal "f") 113767659f6SFlorian Westphal filesize="$OPTARG" 114767659f6SFlorian Westphal ;; 115767659f6SFlorian Westphal "t") 116767659f6SFlorian Westphal do_tcp=$((do_tcp+1)) 117767659f6SFlorian Westphal ;; 11894d66ba1SGeliang Tang "C") 11994d66ba1SGeliang Tang checksum=true 12094d66ba1SGeliang Tang ;; 121048d19d4SFlorian Westphal "?") 122048d19d4SFlorian Westphal usage $0 123048d19d4SFlorian Westphal exit 1 124048d19d4SFlorian Westphal ;; 125048d19d4SFlorian Westphal esac 126048d19d4SFlorian Westphaldone 127048d19d4SFlorian Westphal 128048d19d4SFlorian Westphalsec=$(date +%s) 129048d19d4SFlorian Westphalrndh=$(printf %x $sec)-$(mktemp -u XXXXXX) 130048d19d4SFlorian Westphalns1="ns1-$rndh" 131048d19d4SFlorian Westphalns2="ns2-$rndh" 132048d19d4SFlorian Westphalns3="ns3-$rndh" 133048d19d4SFlorian Westphalns4="ns4-$rndh" 134048d19d4SFlorian Westphal 135048d19d4SFlorian WestphalTEST_COUNT=0 136dd350f46SMatthieu BaertsTEST_GROUP="" 137048d19d4SFlorian Westphal 1385b5ff824SMatthieu Baerts (NGI0)# This function is used in the cleanup trap 1395b5ff824SMatthieu Baerts (NGI0)#shellcheck disable=SC2317 140048d19d4SFlorian Westphalcleanup() 141048d19d4SFlorian Westphal{ 14205be5e27SPaolo Abeni rm -f "$cin_disconnect" "$cout_disconnect" 143048d19d4SFlorian Westphal rm -f "$cin" "$cout" 144048d19d4SFlorian Westphal rm -f "$sin" "$sout" 145048d19d4SFlorian Westphal rm -f "$capout" 146048d19d4SFlorian Westphal 147048d19d4SFlorian Westphal local netns 148048d19d4SFlorian Westphal for netns in "$ns1" "$ns2" "$ns3" "$ns4";do 149048d19d4SFlorian Westphal ip netns del $netns 150767389c8SPaolo Abeni rm -f /tmp/$netns.{nstat,out} 151048d19d4SFlorian Westphal done 152048d19d4SFlorian Westphal} 153048d19d4SFlorian Westphal 154d83013bdSMatthieu Baertsmptcp_lib_check_mptcp 15507bf4940SMatthieu Baertsmptcp_lib_check_kallsyms 156d83013bdSMatthieu Baerts 157048d19d4SFlorian Westphalip -Version > /dev/null 2>&1 158048d19d4SFlorian Westphalif [ $? -ne 0 ];then 159048d19d4SFlorian Westphal echo "SKIP: Could not run test without ip tool" 160048d19d4SFlorian Westphal exit $ksft_skip 161048d19d4SFlorian Westphalfi 162048d19d4SFlorian Westphal 163048d19d4SFlorian Westphalsin=$(mktemp) 164048d19d4SFlorian Westphalsout=$(mktemp) 165048d19d4SFlorian Westphalcin=$(mktemp) 166048d19d4SFlorian Westphalcout=$(mktemp) 167048d19d4SFlorian Westphalcapout=$(mktemp) 16805be5e27SPaolo Abenicin_disconnect="$cin".disconnect 16905be5e27SPaolo Abenicout_disconnect="$cout".disconnect 170048d19d4SFlorian Westphaltrap cleanup EXIT 171048d19d4SFlorian Westphal 172048d19d4SFlorian Westphalfor i in "$ns1" "$ns2" "$ns3" "$ns4";do 173048d19d4SFlorian Westphal ip netns add $i || exit $ksft_skip 174048d19d4SFlorian Westphal ip -net $i link set lo up 175048d19d4SFlorian Westphaldone 176048d19d4SFlorian Westphal 177048d19d4SFlorian Westphal# "$ns1" ns2 ns3 ns4 178048d19d4SFlorian Westphal# ns1eth2 ns2eth1 ns2eth3 ns3eth2 ns3eth4 ns4eth3 179048d19d4SFlorian Westphal# - drop 1% -> reorder 25% 180048d19d4SFlorian Westphal# <- TSO off - 181048d19d4SFlorian Westphal 182048d19d4SFlorian Westphalip link add ns1eth2 netns "$ns1" type veth peer name ns2eth1 netns "$ns2" 183048d19d4SFlorian Westphalip link add ns2eth3 netns "$ns2" type veth peer name ns3eth2 netns "$ns3" 184048d19d4SFlorian Westphalip link add ns3eth4 netns "$ns3" type veth peer name ns4eth3 netns "$ns4" 185048d19d4SFlorian Westphal 186048d19d4SFlorian Westphalip -net "$ns1" addr add 10.0.1.1/24 dev ns1eth2 187048d19d4SFlorian Westphalip -net "$ns1" addr add dead:beef:1::1/64 dev ns1eth2 nodad 188048d19d4SFlorian Westphal 189048d19d4SFlorian Westphalip -net "$ns1" link set ns1eth2 up 190048d19d4SFlorian Westphalip -net "$ns1" route add default via 10.0.1.2 191048d19d4SFlorian Westphalip -net "$ns1" route add default via dead:beef:1::2 192048d19d4SFlorian Westphal 193048d19d4SFlorian Westphalip -net "$ns2" addr add 10.0.1.2/24 dev ns2eth1 194048d19d4SFlorian Westphalip -net "$ns2" addr add dead:beef:1::2/64 dev ns2eth1 nodad 195048d19d4SFlorian Westphalip -net "$ns2" link set ns2eth1 up 196048d19d4SFlorian Westphal 197048d19d4SFlorian Westphalip -net "$ns2" addr add 10.0.2.1/24 dev ns2eth3 198048d19d4SFlorian Westphalip -net "$ns2" addr add dead:beef:2::1/64 dev ns2eth3 nodad 199048d19d4SFlorian Westphalip -net "$ns2" link set ns2eth3 up 200048d19d4SFlorian Westphalip -net "$ns2" route add default via 10.0.2.2 201048d19d4SFlorian Westphalip -net "$ns2" route add default via dead:beef:2::2 202048d19d4SFlorian Westphalip netns exec "$ns2" sysctl -q net.ipv4.ip_forward=1 203048d19d4SFlorian Westphalip netns exec "$ns2" sysctl -q net.ipv6.conf.all.forwarding=1 204048d19d4SFlorian Westphal 205048d19d4SFlorian Westphalip -net "$ns3" addr add 10.0.2.2/24 dev ns3eth2 206048d19d4SFlorian Westphalip -net "$ns3" addr add dead:beef:2::2/64 dev ns3eth2 nodad 207048d19d4SFlorian Westphalip -net "$ns3" link set ns3eth2 up 208048d19d4SFlorian Westphal 209048d19d4SFlorian Westphalip -net "$ns3" addr add 10.0.3.2/24 dev ns3eth4 210048d19d4SFlorian Westphalip -net "$ns3" addr add dead:beef:3::2/64 dev ns3eth4 nodad 211048d19d4SFlorian Westphalip -net "$ns3" link set ns3eth4 up 212048d19d4SFlorian Westphalip -net "$ns3" route add default via 10.0.2.1 213048d19d4SFlorian Westphalip -net "$ns3" route add default via dead:beef:2::1 214048d19d4SFlorian Westphalip netns exec "$ns3" sysctl -q net.ipv4.ip_forward=1 215048d19d4SFlorian Westphalip netns exec "$ns3" sysctl -q net.ipv6.conf.all.forwarding=1 216048d19d4SFlorian Westphal 217048d19d4SFlorian Westphalip -net "$ns4" addr add 10.0.3.1/24 dev ns4eth3 218048d19d4SFlorian Westphalip -net "$ns4" addr add dead:beef:3::1/64 dev ns4eth3 nodad 219048d19d4SFlorian Westphalip -net "$ns4" link set ns4eth3 up 220048d19d4SFlorian Westphalip -net "$ns4" route add default via 10.0.3.2 221048d19d4SFlorian Westphalip -net "$ns4" route add default via dead:beef:3::2 222048d19d4SFlorian Westphal 22394d66ba1SGeliang Tangif $checksum; then 22494d66ba1SGeliang Tang for i in "$ns1" "$ns2" "$ns3" "$ns4";do 22594d66ba1SGeliang Tang ip netns exec $i sysctl -q net.mptcp.checksum_enabled=1 22694d66ba1SGeliang Tang done 22794d66ba1SGeliang Tangfi 22894d66ba1SGeliang Tang 229048d19d4SFlorian Westphalset_ethtool_flags() { 230048d19d4SFlorian Westphal local ns="$1" 231048d19d4SFlorian Westphal local dev="$2" 232048d19d4SFlorian Westphal local flags="$3" 233048d19d4SFlorian Westphal 2345b5ff824SMatthieu Baerts (NGI0) if ip netns exec $ns ethtool -K $dev $flags 2>/dev/null; then 2355b5ff824SMatthieu Baerts (NGI0) echo "INFO: set $ns dev $dev: ethtool -K $flags" 2365b5ff824SMatthieu Baerts (NGI0) fi 237048d19d4SFlorian Westphal} 238048d19d4SFlorian Westphal 239048d19d4SFlorian Westphalset_random_ethtool_flags() { 240048d19d4SFlorian Westphal local flags="" 241048d19d4SFlorian Westphal local r=$RANDOM 242048d19d4SFlorian Westphal 243048d19d4SFlorian Westphal local pick1=$((r & 1)) 244048d19d4SFlorian Westphal local pick2=$((r & 2)) 245048d19d4SFlorian Westphal local pick3=$((r & 4)) 246048d19d4SFlorian Westphal 247048d19d4SFlorian Westphal [ $pick1 -ne 0 ] && flags="tso off" 248048d19d4SFlorian Westphal [ $pick2 -ne 0 ] && flags="$flags gso off" 249048d19d4SFlorian Westphal [ $pick3 -ne 0 ] && flags="$flags gro off" 250048d19d4SFlorian Westphal 251048d19d4SFlorian Westphal [ -z "$flags" ] && return 252048d19d4SFlorian Westphal 253048d19d4SFlorian Westphal set_ethtool_flags "$1" "$2" "$flags" 254048d19d4SFlorian Westphal} 255048d19d4SFlorian Westphal 256048d19d4SFlorian Westphalif $ethtool_random_on;then 257048d19d4SFlorian Westphal set_random_ethtool_flags "$ns3" ns3eth2 258048d19d4SFlorian Westphal set_random_ethtool_flags "$ns4" ns4eth3 259048d19d4SFlorian Westphalelse 260048d19d4SFlorian Westphal set_ethtool_flags "$ns3" ns3eth2 "$ethtool_args" 261048d19d4SFlorian Westphal set_ethtool_flags "$ns4" ns4eth3 "$ethtool_args" 262048d19d4SFlorian Westphalfi 263048d19d4SFlorian Westphal 264048d19d4SFlorian Westphalprint_file_err() 265048d19d4SFlorian Westphal{ 266048d19d4SFlorian Westphal ls -l "$1" 1>&2 267048d19d4SFlorian Westphal echo "Trailing bytes are: " 268048d19d4SFlorian Westphal tail -c 27 "$1" 269048d19d4SFlorian Westphal} 270048d19d4SFlorian Westphal 271048d19d4SFlorian Westphalcheck_transfer() 272048d19d4SFlorian Westphal{ 273048d19d4SFlorian Westphal local in=$1 274048d19d4SFlorian Westphal local out=$2 275048d19d4SFlorian Westphal local what=$3 276048d19d4SFlorian Westphal 277048d19d4SFlorian Westphal cmp "$in" "$out" > /dev/null 2>&1 278048d19d4SFlorian Westphal if [ $? -ne 0 ] ;then 279048d19d4SFlorian Westphal echo "[ FAIL ] $what does not match (in, out):" 280048d19d4SFlorian Westphal print_file_err "$in" 281048d19d4SFlorian Westphal print_file_err "$out" 282048d19d4SFlorian Westphal 283048d19d4SFlorian Westphal return 1 284048d19d4SFlorian Westphal fi 285048d19d4SFlorian Westphal 286048d19d4SFlorian Westphal return 0 287048d19d4SFlorian Westphal} 288048d19d4SFlorian Westphal 289048d19d4SFlorian Westphalcheck_mptcp_disabled() 290048d19d4SFlorian Westphal{ 291787eb1e4SMatthieu Baerts local disabled_ns="ns_disabled-$rndh" 292048d19d4SFlorian Westphal ip netns add ${disabled_ns} || exit $ksft_skip 293048d19d4SFlorian Westphal 294048d19d4SFlorian Westphal # net.mptcp.enabled should be enabled by default 295048d19d4SFlorian Westphal if [ "$(ip netns exec ${disabled_ns} sysctl net.mptcp.enabled | awk '{ print $3 }')" -ne 1 ]; then 296048d19d4SFlorian Westphal echo -e "net.mptcp.enabled sysctl is not 1 by default\t\t[ FAIL ]" 297dd350f46SMatthieu Baerts mptcp_lib_result_fail "net.mptcp.enabled sysctl is not 1 by default" 298048d19d4SFlorian Westphal ret=1 299048d19d4SFlorian Westphal return 1 300048d19d4SFlorian Westphal fi 301048d19d4SFlorian Westphal ip netns exec ${disabled_ns} sysctl -q net.mptcp.enabled=0 302048d19d4SFlorian Westphal 303048d19d4SFlorian Westphal local err=0 30477a88274SMasahiro Yamada LC_ALL=C ip netns exec ${disabled_ns} ./mptcp_connect -p 10000 -s MPTCP 127.0.0.1 < "$cin" 2>&1 | \ 305048d19d4SFlorian Westphal grep -q "^socket: Protocol not available$" && err=1 306048d19d4SFlorian Westphal ip netns delete ${disabled_ns} 307048d19d4SFlorian Westphal 308048d19d4SFlorian Westphal if [ ${err} -eq 0 ]; then 309048d19d4SFlorian Westphal echo -e "New MPTCP socket cannot be blocked via sysctl\t\t[ FAIL ]" 310dd350f46SMatthieu Baerts mptcp_lib_result_fail "New MPTCP socket cannot be blocked via sysctl" 311048d19d4SFlorian Westphal ret=1 312048d19d4SFlorian Westphal return 1 313048d19d4SFlorian Westphal fi 314048d19d4SFlorian Westphal 315048d19d4SFlorian Westphal echo -e "New MPTCP socket can be blocked via sysctl\t\t[ OK ]" 316dd350f46SMatthieu Baerts mptcp_lib_result_pass "New MPTCP socket can be blocked via sysctl" 317048d19d4SFlorian Westphal return 0 318048d19d4SFlorian Westphal} 319048d19d4SFlorian Westphal 320048d19d4SFlorian Westphaldo_ping() 321048d19d4SFlorian Westphal{ 322048d19d4SFlorian Westphal local listener_ns="$1" 323048d19d4SFlorian Westphal local connector_ns="$2" 324048d19d4SFlorian Westphal local connect_addr="$3" 325048d19d4SFlorian Westphal local ping_args="-q -c 1" 326dd350f46SMatthieu Baerts local rc=0 327048d19d4SFlorian Westphal 3288e7f31bfSGeliang Tang if mptcp_lib_is_v6 "${connect_addr}"; then 329048d19d4SFlorian Westphal $ipv6 || return 0 330048d19d4SFlorian Westphal ping_args="${ping_args} -6" 331048d19d4SFlorian Westphal fi 332048d19d4SFlorian Westphal 333dd350f46SMatthieu Baerts ip netns exec ${connector_ns} ping ${ping_args} $connect_addr >/dev/null || rc=1 334dd350f46SMatthieu Baerts 335dd350f46SMatthieu Baerts if [ $rc -ne 0 ] ; then 336048d19d4SFlorian Westphal echo "$listener_ns -> $connect_addr connectivity [ FAIL ]" 1>&2 337048d19d4SFlorian Westphal ret=1 338048d19d4SFlorian Westphal 339048d19d4SFlorian Westphal return 1 340048d19d4SFlorian Westphal fi 341048d19d4SFlorian Westphal 342048d19d4SFlorian Westphal return 0 343048d19d4SFlorian Westphal} 344048d19d4SFlorian Westphal 345048d19d4SFlorian Westphal# $1: ns, $2: port 346048d19d4SFlorian Westphalwait_local_port_listen() 347048d19d4SFlorian Westphal{ 348048d19d4SFlorian Westphal local listener_ns="${1}" 349048d19d4SFlorian Westphal local port="${2}" 350048d19d4SFlorian Westphal 351048d19d4SFlorian Westphal local port_hex i 352048d19d4SFlorian Westphal 353048d19d4SFlorian Westphal port_hex="$(printf "%04X" "${port}")" 354048d19d4SFlorian Westphal for i in $(seq 10); do 355048d19d4SFlorian Westphal ip netns exec "${listener_ns}" cat /proc/net/tcp* | \ 356048d19d4SFlorian Westphal awk "BEGIN {rc=1} {if (\$2 ~ /:${port_hex}\$/ && \$4 ~ /0A/) {rc=0; exit}} END {exit rc}" && 357048d19d4SFlorian Westphal break 358048d19d4SFlorian Westphal sleep 0.1 359048d19d4SFlorian Westphal done 360048d19d4SFlorian Westphal} 361048d19d4SFlorian Westphal 362048d19d4SFlorian Westphaldo_transfer() 363048d19d4SFlorian Westphal{ 364048d19d4SFlorian Westphal local listener_ns="$1" 365048d19d4SFlorian Westphal local connector_ns="$2" 366048d19d4SFlorian Westphal local cl_proto="$3" 367048d19d4SFlorian Westphal local srv_proto="$4" 368048d19d4SFlorian Westphal local connect_addr="$5" 369048d19d4SFlorian Westphal local local_addr="$6" 370df8aee6dSYonglong Li local extra_args="$7" 371048d19d4SFlorian Westphal 372048d19d4SFlorian Westphal local port 3735b5ff824SMatthieu Baerts (NGI0) port=$((10000+TEST_COUNT)) 374048d19d4SFlorian Westphal TEST_COUNT=$((TEST_COUNT+1)) 375048d19d4SFlorian Westphal 3768a4b910dSFlorian Westphal if [ "$rcvbuf" -gt 0 ]; then 377*732752baSGeliang Tang extra_args+=" -R $rcvbuf" 3788a4b910dSFlorian Westphal fi 3798a4b910dSFlorian Westphal 380048d19d4SFlorian Westphal if [ "$sndbuf" -gt 0 ]; then 381*732752baSGeliang Tang extra_args+=" -S $sndbuf" 382048d19d4SFlorian Westphal fi 383048d19d4SFlorian Westphal 384048d19d4SFlorian Westphal if [ -n "$testmode" ]; then 385*732752baSGeliang Tang extra_args+=" -m $testmode" 386048d19d4SFlorian Westphal fi 387048d19d4SFlorian Westphal 388048d19d4SFlorian Westphal if [ -n "$extra_args" ] && $options_log; then 389048d19d4SFlorian Westphal echo "INFO: extra options: $extra_args" 390048d19d4SFlorian Westphal fi 391df8aee6dSYonglong Li options_log=false 392048d19d4SFlorian Westphal 393048d19d4SFlorian Westphal :> "$cout" 394048d19d4SFlorian Westphal :> "$sout" 395048d19d4SFlorian Westphal :> "$capout" 396048d19d4SFlorian Westphal 397048d19d4SFlorian Westphal local addr_port 398048d19d4SFlorian Westphal addr_port=$(printf "%s:%d" ${connect_addr} ${port}) 399dd350f46SMatthieu Baerts local result_msg 400dd350f46SMatthieu Baerts result_msg="$(printf "%.3s %-5s -> %.3s (%-20s) %-5s" ${connector_ns} ${cl_proto} ${listener_ns} ${addr_port} ${srv_proto})" 401dd350f46SMatthieu Baerts printf "%s\t" "${result_msg}" 402048d19d4SFlorian Westphal 403048d19d4SFlorian Westphal if $capture; then 404048d19d4SFlorian Westphal local capuser 405048d19d4SFlorian Westphal if [ -z $SUDO_USER ] ; then 406048d19d4SFlorian Westphal capuser="" 407048d19d4SFlorian Westphal else 408048d19d4SFlorian Westphal capuser="-Z $SUDO_USER" 409048d19d4SFlorian Westphal fi 410048d19d4SFlorian Westphal 4110b8241feSMatthieu Baerts local capfile="${rndh}-${connector_ns:0:3}-${listener_ns:0:3}-${cl_proto}-${srv_proto}-${connect_addr}-${port}" 4120b8241feSMatthieu Baerts local capopt="-i any -s 65535 -B 32768 ${capuser}" 413048d19d4SFlorian Westphal 4140b8241feSMatthieu Baerts ip netns exec ${listener_ns} tcpdump ${capopt} -w "${capfile}-listener.pcap" >> "${capout}" 2>&1 & 4150b8241feSMatthieu Baerts local cappid_listener=$! 4160b8241feSMatthieu Baerts 4170b8241feSMatthieu Baerts ip netns exec ${connector_ns} tcpdump ${capopt} -w "${capfile}-connector.pcap" >> "${capout}" 2>&1 & 4180b8241feSMatthieu Baerts local cappid_connector=$! 419048d19d4SFlorian Westphal 420048d19d4SFlorian Westphal sleep 1 421048d19d4SFlorian Westphal fi 422048d19d4SFlorian Westphal 42376e5e27cSMatthieu Baerts NSTAT_HISTORY=/tmp/${listener_ns}.nstat ip netns exec ${listener_ns} \ 42476e5e27cSMatthieu Baerts nstat -n 42576e5e27cSMatthieu Baerts if [ ${listener_ns} != ${connector_ns} ]; then 42676e5e27cSMatthieu Baerts NSTAT_HISTORY=/tmp/${connector_ns}.nstat ip netns exec ${connector_ns} \ 42776e5e27cSMatthieu Baerts nstat -n 42876e5e27cSMatthieu Baerts fi 42976e5e27cSMatthieu Baerts 4305b5ff824SMatthieu Baerts (NGI0) local stat_synrx_last_l 4315b5ff824SMatthieu Baerts (NGI0) local stat_ackrx_last_l 4325b5ff824SMatthieu Baerts (NGI0) local stat_cookietx_last 4335b5ff824SMatthieu Baerts (NGI0) local stat_cookierx_last 4345b5ff824SMatthieu Baerts (NGI0) local stat_csum_err_s 4355b5ff824SMatthieu Baerts (NGI0) local stat_csum_err_c 43643eca11bSDavide Caratti local stat_tcpfb_last_l 4375b5ff824SMatthieu Baerts (NGI0) stat_synrx_last_l=$(mptcp_lib_get_counter "${listener_ns}" "MPTcpExtMPCapableSYNRX") 4385b5ff824SMatthieu Baerts (NGI0) stat_ackrx_last_l=$(mptcp_lib_get_counter "${listener_ns}" "MPTcpExtMPCapableACKRX") 4395b5ff824SMatthieu Baerts (NGI0) stat_cookietx_last=$(mptcp_lib_get_counter "${listener_ns}" "TcpExtSyncookiesSent") 4405b5ff824SMatthieu Baerts (NGI0) stat_cookierx_last=$(mptcp_lib_get_counter "${listener_ns}" "TcpExtSyncookiesRecv") 4415b5ff824SMatthieu Baerts (NGI0) stat_csum_err_s=$(mptcp_lib_get_counter "${listener_ns}" "MPTcpExtDataCsumErr") 4425b5ff824SMatthieu Baerts (NGI0) stat_csum_err_c=$(mptcp_lib_get_counter "${connector_ns}" "MPTcpExtDataCsumErr") 44343eca11bSDavide Caratti stat_tcpfb_last_l=$(mptcp_lib_get_counter "${listener_ns}" "MPTcpExtMPCapableFallbackACK") 444fed61c4bSFlorian Westphal 4455888a61cSMatthieu Baerts timeout ${timeout_test} \ 4465888a61cSMatthieu Baerts ip netns exec ${listener_ns} \ 4475888a61cSMatthieu Baerts ./mptcp_connect -t ${timeout_poll} -l -p $port -s ${srv_proto} \ 4485888a61cSMatthieu Baerts $extra_args $local_addr < "$sin" > "$sout" & 449048d19d4SFlorian Westphal local spid=$! 450048d19d4SFlorian Westphal 451048d19d4SFlorian Westphal wait_local_port_listen "${listener_ns}" "${port}" 452048d19d4SFlorian Westphal 453048d19d4SFlorian Westphal local start 454048d19d4SFlorian Westphal start=$(date +%s%3N) 4555888a61cSMatthieu Baerts timeout ${timeout_test} \ 4565888a61cSMatthieu Baerts ip netns exec ${connector_ns} \ 4575888a61cSMatthieu Baerts ./mptcp_connect -t ${timeout_poll} -p $port -s ${cl_proto} \ 4585888a61cSMatthieu Baerts $extra_args $connect_addr < "$cin" > "$cout" & 459048d19d4SFlorian Westphal local cpid=$! 460048d19d4SFlorian Westphal 461048d19d4SFlorian Westphal wait $cpid 462048d19d4SFlorian Westphal local retc=$? 463048d19d4SFlorian Westphal wait $spid 464048d19d4SFlorian Westphal local rets=$? 465048d19d4SFlorian Westphal 466048d19d4SFlorian Westphal local stop 467048d19d4SFlorian Westphal stop=$(date +%s%3N) 468048d19d4SFlorian Westphal 469048d19d4SFlorian Westphal if $capture; then 470048d19d4SFlorian Westphal sleep 1 4710b8241feSMatthieu Baerts kill ${cappid_listener} 4720b8241feSMatthieu Baerts kill ${cappid_connector} 473048d19d4SFlorian Westphal fi 474048d19d4SFlorian Westphal 475767389c8SPaolo Abeni NSTAT_HISTORY=/tmp/${listener_ns}.nstat ip netns exec ${listener_ns} \ 476767389c8SPaolo Abeni nstat | grep Tcp > /tmp/${listener_ns}.out 477767389c8SPaolo Abeni if [ ${listener_ns} != ${connector_ns} ]; then 478767389c8SPaolo Abeni NSTAT_HISTORY=/tmp/${connector_ns}.nstat ip netns exec ${connector_ns} \ 479767389c8SPaolo Abeni nstat | grep Tcp > /tmp/${connector_ns}.out 480767389c8SPaolo Abeni fi 481767389c8SPaolo Abeni 482048d19d4SFlorian Westphal local duration 483048d19d4SFlorian Westphal duration=$((stop-start)) 484dd350f46SMatthieu Baerts result_msg+=" # time=${duration}ms" 48545759a87SMatthieu Baerts printf "(duration %05sms) " "${duration}" 486048d19d4SFlorian Westphal if [ ${rets} -ne 0 ] || [ ${retc} -ne 0 ]; then 48745759a87SMatthieu Baerts echo "[ FAIL ] client exit code $retc, server $rets" 1>&2 4888b974778SMatthieu Baerts echo -e "\nnetns ${listener_ns} socket stat for ${port}:" 1>&2 489767389c8SPaolo Abeni ip netns exec ${listener_ns} ss -Menita 1>&2 -o "sport = :$port" 490767389c8SPaolo Abeni cat /tmp/${listener_ns}.out 4918b974778SMatthieu Baerts echo -e "\nnetns ${connector_ns} socket stat for ${port}:" 1>&2 492767389c8SPaolo Abeni ip netns exec ${connector_ns} ss -Menita 1>&2 -o "dport = :$port" 493767389c8SPaolo Abeni [ ${listener_ns} != ${connector_ns} ] && cat /tmp/${connector_ns}.out 49445759a87SMatthieu Baerts 49545759a87SMatthieu Baerts echo 496048d19d4SFlorian Westphal cat "$capout" 497dd350f46SMatthieu Baerts mptcp_lib_result_fail "${TEST_GROUP}: ${result_msg}" 498048d19d4SFlorian Westphal return 1 499048d19d4SFlorian Westphal fi 500048d19d4SFlorian Westphal 501048d19d4SFlorian Westphal check_transfer $sin $cout "file received by client" 502048d19d4SFlorian Westphal retc=$? 503048d19d4SFlorian Westphal check_transfer $cin $sout "file received by server" 504048d19d4SFlorian Westphal rets=$? 505048d19d4SFlorian Westphal 506*732752baSGeliang Tang local extra="" 5075b5ff824SMatthieu Baerts (NGI0) local stat_synrx_now_l 5085b5ff824SMatthieu Baerts (NGI0) local stat_ackrx_now_l 5095b5ff824SMatthieu Baerts (NGI0) local stat_cookietx_now 5105b5ff824SMatthieu Baerts (NGI0) local stat_cookierx_now 5115b5ff824SMatthieu Baerts (NGI0) local stat_ooo_now 51243eca11bSDavide Caratti local stat_tcpfb_now_l 5135b5ff824SMatthieu Baerts (NGI0) stat_synrx_now_l=$(mptcp_lib_get_counter "${listener_ns}" "MPTcpExtMPCapableSYNRX") 5145b5ff824SMatthieu Baerts (NGI0) stat_ackrx_now_l=$(mptcp_lib_get_counter "${listener_ns}" "MPTcpExtMPCapableACKRX") 5155b5ff824SMatthieu Baerts (NGI0) stat_cookietx_now=$(mptcp_lib_get_counter "${listener_ns}" "TcpExtSyncookiesSent") 5165b5ff824SMatthieu Baerts (NGI0) stat_cookierx_now=$(mptcp_lib_get_counter "${listener_ns}" "TcpExtSyncookiesRecv") 5175b5ff824SMatthieu Baerts (NGI0) stat_ooo_now=$(mptcp_lib_get_counter "${listener_ns}" "TcpExtTCPOFOQueue") 51843eca11bSDavide Caratti stat_tcpfb_now_l=$(mptcp_lib_get_counter "${listener_ns}" "MPTcpExtMPCapableFallbackACK") 519fed61c4bSFlorian Westphal 520fed61c4bSFlorian Westphal expect_synrx=$((stat_synrx_last_l)) 521fed61c4bSFlorian Westphal expect_ackrx=$((stat_ackrx_last_l)) 522fed61c4bSFlorian Westphal 523fed61c4bSFlorian Westphal cookies=$(ip netns exec ${listener_ns} sysctl net.ipv4.tcp_syncookies) 524fed61c4bSFlorian Westphal cookies=${cookies##*=} 525fed61c4bSFlorian Westphal 526fed61c4bSFlorian Westphal if [ ${cl_proto} = "MPTCP" ] && [ ${srv_proto} = "MPTCP" ]; then 5275b5ff824SMatthieu Baerts (NGI0) expect_synrx=$((stat_synrx_last_l+connect_per_transfer)) 5285b5ff824SMatthieu Baerts (NGI0) expect_ackrx=$((stat_ackrx_last_l+connect_per_transfer)) 529fed61c4bSFlorian Westphal fi 5305f88117fSMatthieu Baerts 5315f88117fSMatthieu Baerts if [ ${stat_synrx_now_l} -lt ${expect_synrx} ]; then 5325f88117fSMatthieu Baerts printf "[ FAIL ] lower MPC SYN rx (%d) than expected (%d)\n" \ 5335f88117fSMatthieu Baerts "${stat_synrx_now_l}" "${expect_synrx}" 1>&2 5345f88117fSMatthieu Baerts retc=1 5355f88117fSMatthieu Baerts fi 5365b5ff824SMatthieu Baerts (NGI0) if [ ${stat_ackrx_now_l} -lt ${expect_ackrx} ] && [ ${stat_ooo_now} -eq 0 ]; then 53769ca3d29SPaolo Abeni if [ ${stat_ooo_now} -eq 0 ]; then 5385f88117fSMatthieu Baerts printf "[ FAIL ] lower MPC ACK rx (%d) than expected (%d)\n" \ 5395f88117fSMatthieu Baerts "${stat_ackrx_now_l}" "${expect_ackrx}" 1>&2 5405f88117fSMatthieu Baerts rets=1 54169ca3d29SPaolo Abeni else 542*732752baSGeliang Tang extra+=" [ Note ] fallback due to TCP OoO" 54369ca3d29SPaolo Abeni fi 5445f88117fSMatthieu Baerts fi 5455f88117fSMatthieu Baerts 54624720d74SGeliang Tang if $checksum; then 5475b5ff824SMatthieu Baerts (NGI0) local csum_err_s 5485b5ff824SMatthieu Baerts (NGI0) local csum_err_c 5495b5ff824SMatthieu Baerts (NGI0) csum_err_s=$(mptcp_lib_get_counter "${listener_ns}" "MPTcpExtDataCsumErr") 5505b5ff824SMatthieu Baerts (NGI0) csum_err_c=$(mptcp_lib_get_counter "${connector_ns}" "MPTcpExtDataCsumErr") 55124720d74SGeliang Tang 55224720d74SGeliang Tang local csum_err_s_nr=$((csum_err_s - stat_csum_err_s)) 55324720d74SGeliang Tang if [ $csum_err_s_nr -gt 0 ]; then 5545b5ff824SMatthieu Baerts (NGI0) printf "[ FAIL ]\nserver got %d data checksum error[s]" ${csum_err_s_nr} 55524720d74SGeliang Tang rets=1 55624720d74SGeliang Tang fi 55724720d74SGeliang Tang 55824720d74SGeliang Tang local csum_err_c_nr=$((csum_err_c - stat_csum_err_c)) 55924720d74SGeliang Tang if [ $csum_err_c_nr -gt 0 ]; then 5605b5ff824SMatthieu Baerts (NGI0) printf "[ FAIL ]\nclient got %d data checksum error[s]" ${csum_err_c_nr} 56124720d74SGeliang Tang retc=1 56224720d74SGeliang Tang fi 56324720d74SGeliang Tang fi 56424720d74SGeliang Tang 56543eca11bSDavide Caratti if [ ${stat_ooo_now} -eq 0 ] && [ ${stat_tcpfb_last_l} -ne ${stat_tcpfb_now_l} ]; then 56643eca11bSDavide Caratti mptcp_lib_pr_fail "unexpected fallback to TCP" 56743eca11bSDavide Caratti rets=1 56843eca11bSDavide Caratti fi 56943eca11bSDavide Caratti 570fed61c4bSFlorian Westphal if [ $cookies -eq 2 ];then 571fed61c4bSFlorian Westphal if [ $stat_cookietx_last -ge $stat_cookietx_now ] ;then 572*732752baSGeliang Tang extra+=" WARN: CookieSent: did not advance" 573fed61c4bSFlorian Westphal fi 574fed61c4bSFlorian Westphal if [ $stat_cookierx_last -ge $stat_cookierx_now ] ;then 575*732752baSGeliang Tang extra+=" WARN: CookieRecv: did not advance" 576fed61c4bSFlorian Westphal fi 577fed61c4bSFlorian Westphal else 578fed61c4bSFlorian Westphal if [ $stat_cookietx_last -ne $stat_cookietx_now ] ;then 579*732752baSGeliang Tang extra+=" WARN: CookieSent: changed" 580fed61c4bSFlorian Westphal fi 581fed61c4bSFlorian Westphal if [ $stat_cookierx_last -ne $stat_cookierx_now ] ;then 582*732752baSGeliang Tang extra+=" WARN: CookieRecv: changed" 583fed61c4bSFlorian Westphal fi 584fed61c4bSFlorian Westphal fi 585fed61c4bSFlorian Westphal 5865f88117fSMatthieu Baerts if [ ${stat_synrx_now_l} -gt ${expect_synrx} ]; then 587*732752baSGeliang Tang extra+=" WARN: SYNRX: expect ${expect_synrx}," 588*732752baSGeliang Tang extra+=" got ${stat_synrx_now_l} (probably retransmissions)" 589fed61c4bSFlorian Westphal fi 5905f88117fSMatthieu Baerts if [ ${stat_ackrx_now_l} -gt ${expect_ackrx} ]; then 591*732752baSGeliang Tang extra+=" WARN: ACKRX: expect ${expect_ackrx}," 592*732752baSGeliang Tang extra+=" got ${stat_ackrx_now_l} (probably retransmissions)" 593fed61c4bSFlorian Westphal fi 594fed61c4bSFlorian Westphal 595*732752baSGeliang Tang if [ $retc -eq 0 ] && [ $rets -eq 0 ]; then 596*732752baSGeliang Tang printf "[ OK ]%s\n" "${extra}" 597*732752baSGeliang Tang mptcp_lib_result_pass "${TEST_GROUP}: ${result_msg}" 598*732752baSGeliang Tang else 599*732752baSGeliang Tang if [ -n "${extra}" ]; then 600*732752baSGeliang Tang printf "%s\n" "${extra:1}" 601*732752baSGeliang Tang fi 602*732752baSGeliang Tang mptcp_lib_result_fail "${TEST_GROUP}: ${result_msg}" 603*732752baSGeliang Tang fi 604*732752baSGeliang Tang 605048d19d4SFlorian Westphal cat "$capout" 60645759a87SMatthieu Baerts [ $retc -eq 0 ] && [ $rets -eq 0 ] 607048d19d4SFlorian Westphal} 608048d19d4SFlorian Westphal 609048d19d4SFlorian Westphalmake_file() 610048d19d4SFlorian Westphal{ 611048d19d4SFlorian Westphal local name=$1 612048d19d4SFlorian Westphal local who=$2 613767659f6SFlorian Westphal local SIZE=$filesize 614767659f6SFlorian Westphal local ksize 615767659f6SFlorian Westphal local rem 616048d19d4SFlorian Westphal 617767659f6SFlorian Westphal if [ $SIZE -eq 0 ]; then 618767659f6SFlorian Westphal local MAXSIZE=$((1024 * 1024 * 8)) 619767659f6SFlorian Westphal local MINSIZE=$((1024 * 256)) 620048d19d4SFlorian Westphal 621767659f6SFlorian Westphal SIZE=$(((RANDOM * RANDOM + MINSIZE) % MAXSIZE)) 622767659f6SFlorian Westphal fi 623048d19d4SFlorian Westphal 624767659f6SFlorian Westphal ksize=$((SIZE / 1024)) 625767659f6SFlorian Westphal rem=$((SIZE - (ksize * 1024))) 626767659f6SFlorian Westphal 627767659f6SFlorian Westphal dd if=/dev/urandom of="$name" bs=1024 count=$ksize 2> /dev/null 628767659f6SFlorian Westphal dd if=/dev/urandom conv=notrunc of="$name" bs=1 count=$rem 2> /dev/null 629048d19d4SFlorian Westphal echo -e "\nMPTCP_TEST_FILE_END_MARKER" >> "$name" 630048d19d4SFlorian Westphal 631767659f6SFlorian Westphal echo "Created $name (size $(du -b "$name")) containing data sent by $who" 632048d19d4SFlorian Westphal} 633048d19d4SFlorian Westphal 634048d19d4SFlorian Westphalrun_tests_lo() 635048d19d4SFlorian Westphal{ 636048d19d4SFlorian Westphal local listener_ns="$1" 637048d19d4SFlorian Westphal local connector_ns="$2" 638048d19d4SFlorian Westphal local connect_addr="$3" 639048d19d4SFlorian Westphal local loopback="$4" 640df8aee6dSYonglong Li local extra_args="$5" 641048d19d4SFlorian Westphal local lret=0 642048d19d4SFlorian Westphal 643048d19d4SFlorian Westphal # skip if test programs are running inside same netns for subsequent runs. 644048d19d4SFlorian Westphal if [ $loopback -eq 0 ] && [ ${listener_ns} = ${connector_ns} ]; then 645048d19d4SFlorian Westphal return 0 646048d19d4SFlorian Westphal fi 647048d19d4SFlorian Westphal 648048d19d4SFlorian Westphal # skip if we don't want v6 6498e7f31bfSGeliang Tang if ! $ipv6 && mptcp_lib_is_v6 "${connect_addr}"; then 650048d19d4SFlorian Westphal return 0 651048d19d4SFlorian Westphal fi 652048d19d4SFlorian Westphal 653048d19d4SFlorian Westphal local local_addr 6548e7f31bfSGeliang Tang if mptcp_lib_is_v6 "${connect_addr}"; then 655048d19d4SFlorian Westphal local_addr="::" 656048d19d4SFlorian Westphal else 657048d19d4SFlorian Westphal local_addr="0.0.0.0" 658048d19d4SFlorian Westphal fi 659048d19d4SFlorian Westphal 660df8aee6dSYonglong Li do_transfer ${listener_ns} ${connector_ns} MPTCP MPTCP \ 661df8aee6dSYonglong Li ${connect_addr} ${local_addr} "${extra_args}" 662048d19d4SFlorian Westphal lret=$? 663048d19d4SFlorian Westphal if [ $lret -ne 0 ]; then 664048d19d4SFlorian Westphal ret=$lret 665048d19d4SFlorian Westphal return 1 666048d19d4SFlorian Westphal fi 667048d19d4SFlorian Westphal 668767659f6SFlorian Westphal if [ $do_tcp -eq 0 ]; then 669048d19d4SFlorian Westphal # don't bother testing fallback tcp except for loopback case. 670048d19d4SFlorian Westphal if [ ${listener_ns} != ${connector_ns} ]; then 671048d19d4SFlorian Westphal return 0 672048d19d4SFlorian Westphal fi 673767659f6SFlorian Westphal fi 674048d19d4SFlorian Westphal 675df8aee6dSYonglong Li do_transfer ${listener_ns} ${connector_ns} MPTCP TCP \ 676df8aee6dSYonglong Li ${connect_addr} ${local_addr} "${extra_args}" 677048d19d4SFlorian Westphal lret=$? 678048d19d4SFlorian Westphal if [ $lret -ne 0 ]; then 679048d19d4SFlorian Westphal ret=$lret 680048d19d4SFlorian Westphal return 1 681048d19d4SFlorian Westphal fi 682048d19d4SFlorian Westphal 683df8aee6dSYonglong Li do_transfer ${listener_ns} ${connector_ns} TCP MPTCP \ 684df8aee6dSYonglong Li ${connect_addr} ${local_addr} "${extra_args}" 685048d19d4SFlorian Westphal lret=$? 686048d19d4SFlorian Westphal if [ $lret -ne 0 ]; then 687048d19d4SFlorian Westphal ret=$lret 688048d19d4SFlorian Westphal return 1 689048d19d4SFlorian Westphal fi 690048d19d4SFlorian Westphal 691767659f6SFlorian Westphal if [ $do_tcp -gt 1 ] ;then 692df8aee6dSYonglong Li do_transfer ${listener_ns} ${connector_ns} TCP TCP \ 693df8aee6dSYonglong Li ${connect_addr} ${local_addr} "${extra_args}" 694767659f6SFlorian Westphal lret=$? 695767659f6SFlorian Westphal if [ $lret -ne 0 ]; then 696767659f6SFlorian Westphal ret=$lret 697767659f6SFlorian Westphal return 1 698767659f6SFlorian Westphal fi 699767659f6SFlorian Westphal fi 700767659f6SFlorian Westphal 701048d19d4SFlorian Westphal return 0 702048d19d4SFlorian Westphal} 703048d19d4SFlorian Westphal 704048d19d4SFlorian Westphalrun_tests() 705048d19d4SFlorian Westphal{ 706048d19d4SFlorian Westphal run_tests_lo $1 $2 $3 0 707048d19d4SFlorian Westphal} 708048d19d4SFlorian Westphal 7095fb62e9cSFlorian Westphalrun_test_transparent() 7105fb62e9cSFlorian Westphal{ 7115fb62e9cSFlorian Westphal local connect_addr="$1" 7125fb62e9cSFlorian Westphal local msg="$2" 7135fb62e9cSFlorian Westphal 7145fb62e9cSFlorian Westphal local connector_ns="$ns1" 7155fb62e9cSFlorian Westphal local listener_ns="$ns2" 7165fb62e9cSFlorian Westphal local lret=0 7175fb62e9cSFlorian Westphal local r6flag="" 7185fb62e9cSFlorian Westphal 719dd350f46SMatthieu Baerts TEST_GROUP="${msg}" 720dd350f46SMatthieu Baerts 7215fb62e9cSFlorian Westphal # skip if we don't want v6 7228e7f31bfSGeliang Tang if ! $ipv6 && mptcp_lib_is_v6 "${connect_addr}"; then 7235fb62e9cSFlorian Westphal return 0 7245fb62e9cSFlorian Westphal fi 7255fb62e9cSFlorian Westphal 72607bf4940SMatthieu Baerts # IP(V6)_TRANSPARENT has been added after TOS support which came with 72707bf4940SMatthieu Baerts # the required infrastructure in MPTCP sockopt code. To support TOS, the 72807bf4940SMatthieu Baerts # following function has been exported (T). Not great but better than 72907bf4940SMatthieu Baerts # checking for a specific kernel version. 73007bf4940SMatthieu Baerts if ! mptcp_lib_kallsyms_has "T __ip_sock_set_tos$"; then 73107bf4940SMatthieu Baerts echo "INFO: ${msg} not supported by the kernel: SKIP" 732dd350f46SMatthieu Baerts mptcp_lib_result_skip "${TEST_GROUP}" 73307bf4940SMatthieu Baerts return 73407bf4940SMatthieu Baerts fi 73507bf4940SMatthieu Baerts 7365b5ff824SMatthieu Baerts (NGI0) if ! ip netns exec "$listener_ns" nft -f /dev/stdin <<"EOF" 7375fb62e9cSFlorian Westphalflush ruleset 7385fb62e9cSFlorian Westphaltable inet mangle { 7395fb62e9cSFlorian Westphal chain divert { 7405fb62e9cSFlorian Westphal type filter hook prerouting priority -150; 7415fb62e9cSFlorian Westphal 7425fb62e9cSFlorian Westphal meta l4proto tcp socket transparent 1 meta mark set 1 accept 7435fb62e9cSFlorian Westphal tcp dport 20000 tproxy to :20000 meta mark set 1 accept 7445fb62e9cSFlorian Westphal } 7455fb62e9cSFlorian Westphal} 7465fb62e9cSFlorian WestphalEOF 7475b5ff824SMatthieu Baerts (NGI0) then 7485fb62e9cSFlorian Westphal echo "SKIP: $msg, could not load nft ruleset" 749221e4550SMatthieu Baerts mptcp_lib_fail_if_expected_feature "nft rules" 750dd350f46SMatthieu Baerts mptcp_lib_result_skip "${TEST_GROUP}" 7515fb62e9cSFlorian Westphal return 7525fb62e9cSFlorian Westphal fi 7535fb62e9cSFlorian Westphal 7545fb62e9cSFlorian Westphal local local_addr 7558e7f31bfSGeliang Tang if mptcp_lib_is_v6 "${connect_addr}"; then 7565fb62e9cSFlorian Westphal local_addr="::" 7575fb62e9cSFlorian Westphal r6flag="-6" 7585fb62e9cSFlorian Westphal else 7595fb62e9cSFlorian Westphal local_addr="0.0.0.0" 7605fb62e9cSFlorian Westphal fi 7615fb62e9cSFlorian Westphal 7625b5ff824SMatthieu Baerts (NGI0) if ! ip -net "$listener_ns" $r6flag rule add fwmark 1 lookup 100; then 7635fb62e9cSFlorian Westphal ip netns exec "$listener_ns" nft flush ruleset 7645fb62e9cSFlorian Westphal echo "SKIP: $msg, ip $r6flag rule failed" 765221e4550SMatthieu Baerts mptcp_lib_fail_if_expected_feature "ip rule" 766dd350f46SMatthieu Baerts mptcp_lib_result_skip "${TEST_GROUP}" 7675fb62e9cSFlorian Westphal return 7685fb62e9cSFlorian Westphal fi 7695fb62e9cSFlorian Westphal 7705b5ff824SMatthieu Baerts (NGI0) if ! ip -net "$listener_ns" route add local $local_addr/0 dev lo table 100; then 7715fb62e9cSFlorian Westphal ip netns exec "$listener_ns" nft flush ruleset 7725fb62e9cSFlorian Westphal ip -net "$listener_ns" $r6flag rule del fwmark 1 lookup 100 7735fb62e9cSFlorian Westphal echo "SKIP: $msg, ip route add local $local_addr failed" 774221e4550SMatthieu Baerts mptcp_lib_fail_if_expected_feature "ip route" 775dd350f46SMatthieu Baerts mptcp_lib_result_skip "${TEST_GROUP}" 7765fb62e9cSFlorian Westphal return 7775fb62e9cSFlorian Westphal fi 7785fb62e9cSFlorian Westphal 7795fb62e9cSFlorian Westphal echo "INFO: test $msg" 7805fb62e9cSFlorian Westphal 7815fb62e9cSFlorian Westphal TEST_COUNT=10000 7825fb62e9cSFlorian Westphal local extra_args="-o TRANSPARENT" 7835fb62e9cSFlorian Westphal do_transfer ${listener_ns} ${connector_ns} MPTCP MPTCP \ 7845fb62e9cSFlorian Westphal ${connect_addr} ${local_addr} "${extra_args}" 7855fb62e9cSFlorian Westphal lret=$? 7865fb62e9cSFlorian Westphal 7875fb62e9cSFlorian Westphal ip netns exec "$listener_ns" nft flush ruleset 7885fb62e9cSFlorian Westphal ip -net "$listener_ns" $r6flag rule del fwmark 1 lookup 100 7895fb62e9cSFlorian Westphal ip -net "$listener_ns" route del local $local_addr/0 dev lo table 100 7905fb62e9cSFlorian Westphal 7915fb62e9cSFlorian Westphal if [ $lret -ne 0 ]; then 7925fb62e9cSFlorian Westphal echo "FAIL: $msg, mptcp connection error" 1>&2 7935fb62e9cSFlorian Westphal ret=$lret 7945fb62e9cSFlorian Westphal return 1 7955fb62e9cSFlorian Westphal fi 7965fb62e9cSFlorian Westphal 7975fb62e9cSFlorian Westphal echo "PASS: $msg" 7985fb62e9cSFlorian Westphal return 0 7995fb62e9cSFlorian Westphal} 8005fb62e9cSFlorian Westphal 801df8aee6dSYonglong Lirun_tests_peekmode() 802df8aee6dSYonglong Li{ 803df8aee6dSYonglong Li local peekmode="$1" 804df8aee6dSYonglong Li 805dd350f46SMatthieu Baerts TEST_GROUP="peek mode: ${peekmode}" 806df8aee6dSYonglong Li echo "INFO: with peek mode: ${peekmode}" 807df8aee6dSYonglong Li run_tests_lo "$ns1" "$ns1" 10.0.1.1 1 "-P ${peekmode}" 808df8aee6dSYonglong Li run_tests_lo "$ns1" "$ns1" dead:beef:1::1 1 "-P ${peekmode}" 809df8aee6dSYonglong Li} 810df8aee6dSYonglong Li 811ca7ae891SDmytro Shytyirun_tests_mptfo() 812ca7ae891SDmytro Shytyi{ 813dd350f46SMatthieu Baerts TEST_GROUP="MPTFO" 814dd350f46SMatthieu Baerts 81506b03083SMatthieu Baerts if ! mptcp_lib_kallsyms_has "mptcp_fastopen_"; then 81606b03083SMatthieu Baerts echo "INFO: TFO not supported by the kernel: SKIP" 817dd350f46SMatthieu Baerts mptcp_lib_result_skip "${TEST_GROUP}" 81806b03083SMatthieu Baerts return 81906b03083SMatthieu Baerts fi 82006b03083SMatthieu Baerts 821ca7ae891SDmytro Shytyi echo "INFO: with MPTFO start" 822ca7ae891SDmytro Shytyi ip netns exec "$ns1" sysctl -q net.ipv4.tcp_fastopen=2 823ca7ae891SDmytro Shytyi ip netns exec "$ns2" sysctl -q net.ipv4.tcp_fastopen=1 824ca7ae891SDmytro Shytyi 825ca7ae891SDmytro Shytyi run_tests_lo "$ns1" "$ns2" 10.0.1.1 0 "-o MPTFO" 826ca7ae891SDmytro Shytyi run_tests_lo "$ns1" "$ns2" 10.0.1.1 0 "-o MPTFO" 827ca7ae891SDmytro Shytyi 828ca7ae891SDmytro Shytyi run_tests_lo "$ns1" "$ns2" dead:beef:1::1 0 "-o MPTFO" 829ca7ae891SDmytro Shytyi run_tests_lo "$ns1" "$ns2" dead:beef:1::1 0 "-o MPTFO" 830ca7ae891SDmytro Shytyi 831ca7ae891SDmytro Shytyi ip netns exec "$ns1" sysctl -q net.ipv4.tcp_fastopen=0 832ca7ae891SDmytro Shytyi ip netns exec "$ns2" sysctl -q net.ipv4.tcp_fastopen=0 833ca7ae891SDmytro Shytyi echo "INFO: with MPTFO end" 834ca7ae891SDmytro Shytyi} 835ca7ae891SDmytro Shytyi 83605be5e27SPaolo Abenirun_tests_disconnect() 83705be5e27SPaolo Abeni{ 83805be5e27SPaolo Abeni local old_cin=$cin 83905be5e27SPaolo Abeni local old_sin=$sin 84005be5e27SPaolo Abeni 841dd350f46SMatthieu Baerts TEST_GROUP="full disconnect" 842dd350f46SMatthieu Baerts 8434ad39a42SMatthieu Baerts if ! mptcp_lib_kallsyms_has "mptcp_pm_data_reset$"; then 8444ad39a42SMatthieu Baerts echo "INFO: Full disconnect not supported: SKIP" 845dd350f46SMatthieu Baerts mptcp_lib_result_skip "${TEST_GROUP}" 8464ad39a42SMatthieu Baerts return 8474ad39a42SMatthieu Baerts fi 8484ad39a42SMatthieu Baerts 84905be5e27SPaolo Abeni cat $cin $cin $cin > "$cin".disconnect 85005be5e27SPaolo Abeni 851e6b8a78eSYueh-Shun Li # force do_transfer to cope with the multiple transmissions 85205be5e27SPaolo Abeni sin="$cin.disconnect" 85305be5e27SPaolo Abeni cin="$cin.disconnect" 85405be5e27SPaolo Abeni cin_disconnect="$old_cin" 85505be5e27SPaolo Abeni connect_per_transfer=3 85605be5e27SPaolo Abeni 85705be5e27SPaolo Abeni echo "INFO: disconnect" 85805be5e27SPaolo Abeni run_tests_lo "$ns1" "$ns1" 10.0.1.1 1 "-I 3 -i $old_cin" 85905be5e27SPaolo Abeni run_tests_lo "$ns1" "$ns1" dead:beef:1::1 1 "-I 3 -i $old_cin" 86005be5e27SPaolo Abeni 86105be5e27SPaolo Abeni # restore previous status 86263bb8239SPaolo Abeni sin=$old_sin 86305be5e27SPaolo Abeni cin=$old_cin 86405be5e27SPaolo Abeni cin_disconnect="$cin".disconnect 86505be5e27SPaolo Abeni connect_per_transfer=1 86605be5e27SPaolo Abeni} 86705be5e27SPaolo Abeni 868a4debc47SMatthieu Baertsdisplay_time() 869a4debc47SMatthieu Baerts{ 870a4debc47SMatthieu Baerts time_end=$(date +%s) 871a4debc47SMatthieu Baerts time_run=$((time_end-time_start)) 872a4debc47SMatthieu Baerts 873a4debc47SMatthieu Baerts echo "Time: ${time_run} seconds" 874a4debc47SMatthieu Baerts} 875a4debc47SMatthieu Baerts 876edbc16c4SMatthieu Baertslog_if_error() 877a4debc47SMatthieu Baerts{ 878a4debc47SMatthieu Baerts local msg="$1" 879a4debc47SMatthieu Baerts 880a4debc47SMatthieu Baerts if [ ${ret} -ne 0 ]; then 881a4debc47SMatthieu Baerts echo "FAIL: ${msg}" 1>&2 882edbc16c4SMatthieu Baerts 883edbc16c4SMatthieu Baerts final_ret=${ret} 884edbc16c4SMatthieu Baerts ret=0 885edbc16c4SMatthieu Baerts 886edbc16c4SMatthieu Baerts return ${final_ret} 887edbc16c4SMatthieu Baerts fi 888edbc16c4SMatthieu Baerts} 889edbc16c4SMatthieu Baerts 890edbc16c4SMatthieu Baertsstop_if_error() 891edbc16c4SMatthieu Baerts{ 892edbc16c4SMatthieu Baerts if ! log_if_error "${@}"; then 893a4debc47SMatthieu Baerts display_time 894dd350f46SMatthieu Baerts mptcp_lib_result_print_all_tap 895edbc16c4SMatthieu Baerts exit ${final_ret} 896a4debc47SMatthieu Baerts fi 897a4debc47SMatthieu Baerts} 898a4debc47SMatthieu Baerts 899048d19d4SFlorian Westphalmake_file "$cin" "client" 900048d19d4SFlorian Westphalmake_file "$sin" "server" 901048d19d4SFlorian Westphal 902048d19d4SFlorian Westphalcheck_mptcp_disabled 903048d19d4SFlorian Westphal 904a4debc47SMatthieu Baertsstop_if_error "The kernel configuration is not valid for MPTCP" 905a4debc47SMatthieu Baerts 906048d19d4SFlorian Westphalecho "INFO: validating network environment with pings" 907048d19d4SFlorian Westphalfor sender in "$ns1" "$ns2" "$ns3" "$ns4";do 908048d19d4SFlorian Westphal do_ping "$ns1" $sender 10.0.1.1 909048d19d4SFlorian Westphal do_ping "$ns1" $sender dead:beef:1::1 910048d19d4SFlorian Westphal 911048d19d4SFlorian Westphal do_ping "$ns2" $sender 10.0.1.2 912048d19d4SFlorian Westphal do_ping "$ns2" $sender dead:beef:1::2 913048d19d4SFlorian Westphal do_ping "$ns2" $sender 10.0.2.1 914048d19d4SFlorian Westphal do_ping "$ns2" $sender dead:beef:2::1 915048d19d4SFlorian Westphal 916048d19d4SFlorian Westphal do_ping "$ns3" $sender 10.0.2.2 917048d19d4SFlorian Westphal do_ping "$ns3" $sender dead:beef:2::2 918048d19d4SFlorian Westphal do_ping "$ns3" $sender 10.0.3.2 919048d19d4SFlorian Westphal do_ping "$ns3" $sender dead:beef:3::2 920048d19d4SFlorian Westphal 921048d19d4SFlorian Westphal do_ping "$ns4" $sender 10.0.3.1 922048d19d4SFlorian Westphal do_ping "$ns4" $sender dead:beef:3::1 923048d19d4SFlorian Westphaldone 924048d19d4SFlorian Westphal 925dd350f46SMatthieu Baertsmptcp_lib_result_code "${ret}" "ping tests" 926dd350f46SMatthieu Baerts 927a4debc47SMatthieu Baertsstop_if_error "Could not even run ping tests" 928a4debc47SMatthieu Baerts 929e5484658SChristoph Paasch[ -n "$tc_loss" ] && tc -net "$ns2" qdisc add dev ns2eth3 root netem loss random $tc_loss delay ${tc_delay}ms 930*732752baSGeliang Tangtc_info="loss of $tc_loss " 931*732752baSGeliang Tangtest "$tc_delay" -gt 0 && tc_info+="delay $tc_delay ms " 932048d19d4SFlorian Westphal 9335b5ff824SMatthieu Baerts (NGI0)reorder_delay=$((tc_delay / 4)) 934e5484658SChristoph Paasch 935048d19d4SFlorian Westphalif [ -z "${tc_reorder}" ]; then 936048d19d4SFlorian Westphal reorder1=$((RANDOM%10)) 937048d19d4SFlorian Westphal reorder1=$((100 - reorder1)) 938048d19d4SFlorian Westphal reorder2=$((RANDOM%100)) 939048d19d4SFlorian Westphal 940e5484658SChristoph Paasch if [ $reorder_delay -gt 0 ] && [ $reorder1 -lt 100 ] && [ $reorder2 -gt 0 ]; then 941048d19d4SFlorian Westphal tc_reorder="reorder ${reorder1}% ${reorder2}%" 942*732752baSGeliang Tang tc_info+="$tc_reorder with delay ${reorder_delay}ms " 943048d19d4SFlorian Westphal fi 944048d19d4SFlorian Westphalelif [ "$tc_reorder" = "0" ];then 945048d19d4SFlorian Westphal tc_reorder="" 946e5484658SChristoph Paaschelif [ "$reorder_delay" -gt 0 ];then 947048d19d4SFlorian Westphal # reordering requires some delay 948048d19d4SFlorian Westphal tc_reorder="reorder $tc_reorder" 949*732752baSGeliang Tang tc_info+="$tc_reorder with delay ${reorder_delay}ms " 950048d19d4SFlorian Westphalfi 951048d19d4SFlorian Westphal 952*732752baSGeliang Tangecho "INFO: Using ${tc_info}on ns3eth4" 953048d19d4SFlorian Westphal 954e5484658SChristoph Paaschtc -net "$ns3" qdisc add dev ns3eth4 root netem delay ${reorder_delay}ms $tc_reorder 955048d19d4SFlorian Westphal 956dd350f46SMatthieu BaertsTEST_GROUP="loopback v4" 957a4debc47SMatthieu Baertsrun_tests_lo "$ns1" "$ns1" 10.0.1.1 1 958a4debc47SMatthieu Baertsstop_if_error "Could not even run loopback test" 959048d19d4SFlorian Westphal 960dd350f46SMatthieu BaertsTEST_GROUP="loopback v6" 961a4debc47SMatthieu Baertsrun_tests_lo "$ns1" "$ns1" dead:beef:1::1 1 962a4debc47SMatthieu Baertsstop_if_error "Could not even run loopback v6 test" 963a4debc47SMatthieu Baerts 964dd350f46SMatthieu BaertsTEST_GROUP="multihosts" 965a4debc47SMatthieu Baertsfor sender in $ns1 $ns2 $ns3 $ns4;do 9662395da0eSPaolo Abeni # ns1<->ns2 is not subject to reordering/tc delays. Use it to test 9672395da0eSPaolo Abeni # mptcp syncookie support. 9682395da0eSPaolo Abeni if [ $sender = $ns1 ]; then 9692395da0eSPaolo Abeni ip netns exec "$ns2" sysctl -q net.ipv4.tcp_syncookies=2 9702395da0eSPaolo Abeni else 9712395da0eSPaolo Abeni ip netns exec "$ns2" sysctl -q net.ipv4.tcp_syncookies=1 9722395da0eSPaolo Abeni fi 9732395da0eSPaolo Abeni 974a4debc47SMatthieu Baerts run_tests "$ns1" $sender 10.0.1.1 975a4debc47SMatthieu Baerts run_tests "$ns1" $sender dead:beef:1::1 976a4debc47SMatthieu Baerts 977048d19d4SFlorian Westphal run_tests "$ns2" $sender 10.0.1.2 978048d19d4SFlorian Westphal run_tests "$ns2" $sender dead:beef:1::2 979048d19d4SFlorian Westphal run_tests "$ns2" $sender 10.0.2.1 980048d19d4SFlorian Westphal run_tests "$ns2" $sender dead:beef:2::1 981048d19d4SFlorian Westphal 982048d19d4SFlorian Westphal run_tests "$ns3" $sender 10.0.2.2 983048d19d4SFlorian Westphal run_tests "$ns3" $sender dead:beef:2::2 984048d19d4SFlorian Westphal run_tests "$ns3" $sender 10.0.3.2 985048d19d4SFlorian Westphal run_tests "$ns3" $sender dead:beef:3::2 986048d19d4SFlorian Westphal 987048d19d4SFlorian Westphal run_tests "$ns4" $sender 10.0.3.1 988048d19d4SFlorian Westphal run_tests "$ns4" $sender dead:beef:3::1 989a4debc47SMatthieu Baerts 990edbc16c4SMatthieu Baerts log_if_error "Tests with $sender as a sender have failed" 991048d19d4SFlorian Westphaldone 992048d19d4SFlorian Westphal 993df8aee6dSYonglong Lirun_tests_peekmode "saveWithPeek" 994df8aee6dSYonglong Lirun_tests_peekmode "saveAfterPeek" 995edbc16c4SMatthieu Baertslog_if_error "Tests with peek mode have failed" 996df8aee6dSYonglong Li 997ca7ae891SDmytro Shytyi# MPTFO (MultiPath TCP Fatopen tests) 998ca7ae891SDmytro Shytyirun_tests_mptfo 999edbc16c4SMatthieu Baertslog_if_error "Tests with MPTFO have failed" 1000ca7ae891SDmytro Shytyi 10015fb62e9cSFlorian Westphal# connect to ns4 ip address, ns2 should intercept/proxy 10025fb62e9cSFlorian Westphalrun_test_transparent 10.0.3.1 "tproxy ipv4" 10035fb62e9cSFlorian Westphalrun_test_transparent dead:beef:3::1 "tproxy ipv6" 1004edbc16c4SMatthieu Baertslog_if_error "Tests with tproxy have failed" 100505be5e27SPaolo Abeni 100605be5e27SPaolo Abenirun_tests_disconnect 1007edbc16c4SMatthieu Baertslog_if_error "Tests of the full disconnection have failed" 10085fb62e9cSFlorian Westphal 1009a4debc47SMatthieu Baertsdisplay_time 1010dd350f46SMatthieu Baertsmptcp_lib_result_print_all_tap 1011edbc16c4SMatthieu Baertsexit ${final_ret} 1012