1#!/bin/bash 2# SPDX-License-Identifier: GPL-2.0 3 4ret=0 5sin="" 6sout="" 7cin="" 8cout="" 9ksft_skip=4 10timeout=30 11capture=0 12 13TEST_COUNT=0 14 15init() 16{ 17 capout=$(mktemp) 18 19 rndh=$(printf %x $sec)-$(mktemp -u XXXXXX) 20 21 ns1="ns1-$rndh" 22 ns2="ns2-$rndh" 23 24 for netns in "$ns1" "$ns2";do 25 ip netns add $netns || exit $ksft_skip 26 ip -net $netns link set lo up 27 ip netns exec $netns sysctl -q net.mptcp.enabled=1 28 ip netns exec $netns sysctl -q net.ipv4.conf.all.rp_filter=0 29 ip netns exec $netns sysctl -q net.ipv4.conf.default.rp_filter=0 30 done 31 32 # ns1 ns2 33 # ns1eth1 ns2eth1 34 # ns1eth2 ns2eth2 35 # ns1eth3 ns2eth3 36 # ns1eth4 ns2eth4 37 38 for i in `seq 1 4`; do 39 ip link add ns1eth$i netns "$ns1" type veth peer name ns2eth$i netns "$ns2" 40 ip -net "$ns1" addr add 10.0.$i.1/24 dev ns1eth$i 41 ip -net "$ns1" addr add dead:beef:$i::1/64 dev ns1eth$i nodad 42 ip -net "$ns1" link set ns1eth$i up 43 44 ip -net "$ns2" addr add 10.0.$i.2/24 dev ns2eth$i 45 ip -net "$ns2" addr add dead:beef:$i::2/64 dev ns2eth$i nodad 46 ip -net "$ns2" link set ns2eth$i up 47 48 # let $ns2 reach any $ns1 address from any interface 49 ip -net "$ns2" route add default via 10.0.$i.1 dev ns2eth$i metric 10$i 50 done 51} 52 53cleanup_partial() 54{ 55 rm -f "$capout" 56 57 for netns in "$ns1" "$ns2"; do 58 ip netns del $netns 59 done 60} 61 62cleanup() 63{ 64 rm -f "$cin" "$cout" 65 rm -f "$sin" "$sout" 66 cleanup_partial 67} 68 69reset() 70{ 71 cleanup_partial 72 init 73} 74 75reset_with_cookies() 76{ 77 reset 78 79 for netns in "$ns1" "$ns2";do 80 ip netns exec $netns sysctl -q net.ipv4.tcp_syncookies=2 81 done 82} 83 84for arg in "$@"; do 85 if [ "$arg" = "-c" ]; then 86 capture=1 87 fi 88done 89 90ip -Version > /dev/null 2>&1 91if [ $? -ne 0 ];then 92 echo "SKIP: Could not run test without ip tool" 93 exit $ksft_skip 94fi 95 96 97check_transfer() 98{ 99 in=$1 100 out=$2 101 what=$3 102 103 cmp "$in" "$out" > /dev/null 2>&1 104 if [ $? -ne 0 ] ;then 105 echo "[ FAIL ] $what does not match (in, out):" 106 print_file_err "$in" 107 print_file_err "$out" 108 109 return 1 110 fi 111 112 return 0 113} 114 115do_ping() 116{ 117 listener_ns="$1" 118 connector_ns="$2" 119 connect_addr="$3" 120 121 ip netns exec ${connector_ns} ping -q -c 1 $connect_addr >/dev/null 122 if [ $? -ne 0 ] ; then 123 echo "$listener_ns -> $connect_addr connectivity [ FAIL ]" 1>&2 124 ret=1 125 fi 126} 127 128do_transfer() 129{ 130 listener_ns="$1" 131 connector_ns="$2" 132 cl_proto="$3" 133 srv_proto="$4" 134 connect_addr="$5" 135 136 port=$((10000+$TEST_COUNT)) 137 TEST_COUNT=$((TEST_COUNT+1)) 138 139 :> "$cout" 140 :> "$sout" 141 :> "$capout" 142 143 if [ $capture -eq 1 ]; then 144 if [ -z $SUDO_USER ] ; then 145 capuser="" 146 else 147 capuser="-Z $SUDO_USER" 148 fi 149 150 capfile=$(printf "mp_join-%02u-%s.pcap" "$TEST_COUNT" "${listener_ns}") 151 152 echo "Capturing traffic for test $TEST_COUNT into $capfile" 153 ip netns exec ${listener_ns} tcpdump -i any -s 65535 -B 32768 $capuser -w $capfile > "$capout" 2>&1 & 154 cappid=$! 155 156 sleep 1 157 fi 158 159 ip netns exec ${listener_ns} ./mptcp_connect -j -t $timeout -l -p $port -s ${srv_proto} 0.0.0.0 < "$sin" > "$sout" & 160 spid=$! 161 162 sleep 1 163 164 ip netns exec ${connector_ns} ./mptcp_connect -j -t $timeout -p $port -s ${cl_proto} $connect_addr < "$cin" > "$cout" & 165 cpid=$! 166 167 wait $cpid 168 retc=$? 169 wait $spid 170 rets=$? 171 172 if [ $capture -eq 1 ]; then 173 sleep 1 174 kill $cappid 175 fi 176 177 if [ ${rets} -ne 0 ] || [ ${retc} -ne 0 ]; then 178 echo " client exit code $retc, server $rets" 1>&2 179 echo "\nnetns ${listener_ns} socket stat for $port:" 1>&2 180 ip netns exec ${listener_ns} ss -nita 1>&2 -o "sport = :$port" 181 echo "\nnetns ${connector_ns} socket stat for $port:" 1>&2 182 ip netns exec ${connector_ns} ss -nita 1>&2 -o "dport = :$port" 183 184 cat "$capout" 185 return 1 186 fi 187 188 check_transfer $sin $cout "file received by client" 189 retc=$? 190 check_transfer $cin $sout "file received by server" 191 rets=$? 192 193 if [ $retc -eq 0 ] && [ $rets -eq 0 ];then 194 cat "$capout" 195 return 0 196 fi 197 198 cat "$capout" 199 return 1 200} 201 202make_file() 203{ 204 name=$1 205 who=$2 206 207 SIZE=1 208 209 dd if=/dev/urandom of="$name" bs=1024 count=$SIZE 2> /dev/null 210 echo -e "\nMPTCP_TEST_FILE_END_MARKER" >> "$name" 211 212 echo "Created $name (size $SIZE KB) containing data sent by $who" 213} 214 215run_tests() 216{ 217 listener_ns="$1" 218 connector_ns="$2" 219 connect_addr="$3" 220 lret=0 221 222 do_transfer ${listener_ns} ${connector_ns} MPTCP MPTCP ${connect_addr} 223 lret=$? 224 if [ $lret -ne 0 ]; then 225 ret=$lret 226 return 227 fi 228} 229 230chk_join_nr() 231{ 232 local msg="$1" 233 local syn_nr=$2 234 local syn_ack_nr=$3 235 local ack_nr=$4 236 local count 237 local dump_stats 238 239 printf "%02u %-36s %s" "$TEST_COUNT" "$msg" "syn" 240 count=`ip netns exec $ns1 nstat -as | grep MPTcpExtMPJoinSynRx | awk '{print $2}'` 241 [ -z "$count" ] && count=0 242 if [ "$count" != "$syn_nr" ]; then 243 echo "[fail] got $count JOIN[s] syn expected $syn_nr" 244 ret=1 245 dump_stats=1 246 else 247 echo -n "[ ok ]" 248 fi 249 250 echo -n " - synack" 251 count=`ip netns exec $ns2 nstat -as | grep MPTcpExtMPJoinSynAckRx | awk '{print $2}'` 252 [ -z "$count" ] && count=0 253 if [ "$count" != "$syn_ack_nr" ]; then 254 echo "[fail] got $count JOIN[s] synack expected $syn_ack_nr" 255 ret=1 256 dump_stats=1 257 else 258 echo -n "[ ok ]" 259 fi 260 261 echo -n " - ack" 262 count=`ip netns exec $ns1 nstat -as | grep MPTcpExtMPJoinAckRx | awk '{print $2}'` 263 [ -z "$count" ] && count=0 264 if [ "$count" != "$ack_nr" ]; then 265 echo "[fail] got $count JOIN[s] ack expected $ack_nr" 266 ret=1 267 dump_stats=1 268 else 269 echo "[ ok ]" 270 fi 271 if [ "${dump_stats}" = 1 ]; then 272 echo Server ns stats 273 ip netns exec $ns1 nstat -as | grep MPTcp 274 echo Client ns stats 275 ip netns exec $ns2 nstat -as | grep MPTcp 276 fi 277} 278 279sin=$(mktemp) 280sout=$(mktemp) 281cin=$(mktemp) 282cout=$(mktemp) 283init 284make_file "$cin" "client" 285make_file "$sin" "server" 286trap cleanup EXIT 287 288run_tests $ns1 $ns2 10.0.1.1 289chk_join_nr "no JOIN" "0" "0" "0" 290 291# subflow limted by client 292reset 293ip netns exec $ns2 ./pm_nl_ctl add 10.0.3.2 flags subflow 294run_tests $ns1 $ns2 10.0.1.1 295chk_join_nr "single subflow, limited by client" 0 0 0 296 297# subflow limted by server 298reset 299ip netns exec $ns2 ./pm_nl_ctl limits 0 1 300ip netns exec $ns2 ./pm_nl_ctl add 10.0.3.2 flags subflow 301run_tests $ns1 $ns2 10.0.1.1 302chk_join_nr "single subflow, limited by server" 1 1 0 303 304# subflow 305reset 306ip netns exec $ns1 ./pm_nl_ctl limits 0 1 307ip netns exec $ns2 ./pm_nl_ctl limits 0 1 308ip netns exec $ns2 ./pm_nl_ctl add 10.0.3.2 flags subflow 309run_tests $ns1 $ns2 10.0.1.1 310chk_join_nr "single subflow" 1 1 1 311 312# multiple subflows 313reset 314ip netns exec $ns1 ./pm_nl_ctl limits 0 2 315ip netns exec $ns2 ./pm_nl_ctl limits 0 2 316ip netns exec $ns2 ./pm_nl_ctl add 10.0.3.2 flags subflow 317ip netns exec $ns2 ./pm_nl_ctl add 10.0.2.2 flags subflow 318run_tests $ns1 $ns2 10.0.1.1 319chk_join_nr "multiple subflows" 2 2 2 320 321# multiple subflows limited by serverf 322reset 323ip netns exec $ns1 ./pm_nl_ctl limits 0 1 324ip netns exec $ns2 ./pm_nl_ctl limits 0 2 325ip netns exec $ns2 ./pm_nl_ctl add 10.0.3.2 flags subflow 326ip netns exec $ns2 ./pm_nl_ctl add 10.0.2.2 flags subflow 327run_tests $ns1 $ns2 10.0.1.1 328chk_join_nr "multiple subflows, limited by server" 2 2 1 329 330# add_address, unused 331reset 332ip netns exec $ns1 ./pm_nl_ctl add 10.0.2.1 flags signal 333run_tests $ns1 $ns2 10.0.1.1 334chk_join_nr "unused signal address" 0 0 0 335 336# accept and use add_addr 337reset 338ip netns exec $ns1 ./pm_nl_ctl limits 0 1 339ip netns exec $ns2 ./pm_nl_ctl limits 1 1 340ip netns exec $ns1 ./pm_nl_ctl add 10.0.2.1 flags signal 341run_tests $ns1 $ns2 10.0.1.1 342chk_join_nr "signal address" 1 1 1 343 344# accept and use add_addr with an additional subflow 345# note: signal address in server ns and local addresses in client ns must 346# belong to different subnets or one of the listed local address could be 347# used for 'add_addr' subflow 348reset 349ip netns exec $ns1 ./pm_nl_ctl add 10.0.2.1 flags signal 350ip netns exec $ns1 ./pm_nl_ctl limits 0 2 351ip netns exec $ns2 ./pm_nl_ctl limits 1 2 352ip netns exec $ns2 ./pm_nl_ctl add 10.0.3.2 flags subflow 353run_tests $ns1 $ns2 10.0.1.1 354chk_join_nr "subflow and signal" 2 2 2 355 356# accept and use add_addr with additional subflows 357reset 358ip netns exec $ns1 ./pm_nl_ctl limits 0 3 359ip netns exec $ns1 ./pm_nl_ctl add 10.0.2.1 flags signal 360ip netns exec $ns2 ./pm_nl_ctl limits 1 3 361ip netns exec $ns2 ./pm_nl_ctl add 10.0.3.2 flags subflow 362ip netns exec $ns2 ./pm_nl_ctl add 10.0.4.2 flags subflow 363run_tests $ns1 $ns2 10.0.1.1 364chk_join_nr "multiple subflows and signal" 3 3 3 365 366# single subflow, syncookies 367reset_with_cookies 368ip netns exec $ns1 ./pm_nl_ctl limits 0 1 369ip netns exec $ns2 ./pm_nl_ctl limits 0 1 370ip netns exec $ns2 ./pm_nl_ctl add 10.0.3.2 flags subflow 371run_tests $ns1 $ns2 10.0.1.1 372chk_join_nr "single subflow with syn cookies" 1 1 1 373 374# multiple subflows with syn cookies 375reset_with_cookies 376ip netns exec $ns1 ./pm_nl_ctl limits 0 2 377ip netns exec $ns2 ./pm_nl_ctl limits 0 2 378ip netns exec $ns2 ./pm_nl_ctl add 10.0.3.2 flags subflow 379ip netns exec $ns2 ./pm_nl_ctl add 10.0.2.2 flags subflow 380run_tests $ns1 $ns2 10.0.1.1 381chk_join_nr "multiple subflows with syn cookies" 2 2 2 382 383# multiple subflows limited by server 384reset_with_cookies 385ip netns exec $ns1 ./pm_nl_ctl limits 0 1 386ip netns exec $ns2 ./pm_nl_ctl limits 0 2 387ip netns exec $ns2 ./pm_nl_ctl add 10.0.3.2 flags subflow 388ip netns exec $ns2 ./pm_nl_ctl add 10.0.2.2 flags subflow 389run_tests $ns1 $ns2 10.0.1.1 390chk_join_nr "subflows limited by server w cookies" 2 2 1 391 392# test signal address with cookies 393reset_with_cookies 394ip netns exec $ns1 ./pm_nl_ctl limits 0 1 395ip netns exec $ns2 ./pm_nl_ctl limits 1 1 396ip netns exec $ns1 ./pm_nl_ctl add 10.0.2.1 flags signal 397run_tests $ns1 $ns2 10.0.1.1 398chk_join_nr "signal address with syn cookies" 1 1 1 399 400# test cookie with subflow and signal 401reset_with_cookies 402ip netns exec $ns1 ./pm_nl_ctl add 10.0.2.1 flags signal 403ip netns exec $ns1 ./pm_nl_ctl limits 0 2 404ip netns exec $ns2 ./pm_nl_ctl limits 1 2 405ip netns exec $ns2 ./pm_nl_ctl add 10.0.3.2 flags subflow 406run_tests $ns1 $ns2 10.0.1.1 407chk_join_nr "subflow and signal w cookies" 2 2 2 408 409# accept and use add_addr with additional subflows 410reset_with_cookies 411ip netns exec $ns1 ./pm_nl_ctl limits 0 3 412ip netns exec $ns1 ./pm_nl_ctl add 10.0.2.1 flags signal 413ip netns exec $ns2 ./pm_nl_ctl limits 1 3 414ip netns exec $ns2 ./pm_nl_ctl add 10.0.3.2 flags subflow 415ip netns exec $ns2 ./pm_nl_ctl add 10.0.4.2 flags subflow 416run_tests $ns1 $ns2 10.0.1.1 417chk_join_nr "subflows and signal w. cookies" 3 3 3 418 419exit $ret 420