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 75for arg in "$@"; do 76 if [ "$arg" = "-c" ]; then 77 capture=1 78 fi 79done 80 81ip -Version > /dev/null 2>&1 82if [ $? -ne 0 ];then 83 echo "SKIP: Could not run test without ip tool" 84 exit $ksft_skip 85fi 86 87 88check_transfer() 89{ 90 in=$1 91 out=$2 92 what=$3 93 94 cmp "$in" "$out" > /dev/null 2>&1 95 if [ $? -ne 0 ] ;then 96 echo "[ FAIL ] $what does not match (in, out):" 97 print_file_err "$in" 98 print_file_err "$out" 99 100 return 1 101 fi 102 103 return 0 104} 105 106do_ping() 107{ 108 listener_ns="$1" 109 connector_ns="$2" 110 connect_addr="$3" 111 112 ip netns exec ${connector_ns} ping -q -c 1 $connect_addr >/dev/null 113 if [ $? -ne 0 ] ; then 114 echo "$listener_ns -> $connect_addr connectivity [ FAIL ]" 1>&2 115 ret=1 116 fi 117} 118 119do_transfer() 120{ 121 listener_ns="$1" 122 connector_ns="$2" 123 cl_proto="$3" 124 srv_proto="$4" 125 connect_addr="$5" 126 127 port=$((10000+$TEST_COUNT)) 128 TEST_COUNT=$((TEST_COUNT+1)) 129 130 :> "$cout" 131 :> "$sout" 132 :> "$capout" 133 134 if [ $capture -eq 1 ]; then 135 if [ -z $SUDO_USER ] ; then 136 capuser="" 137 else 138 capuser="-Z $SUDO_USER" 139 fi 140 141 capfile="mp_join-${listener_ns}.pcap" 142 143 echo "Capturing traffic for test $TEST_COUNT into $capfile" 144 ip netns exec ${listener_ns} tcpdump -i any -s 65535 -B 32768 $capuser -w $capfile > "$capout" 2>&1 & 145 cappid=$! 146 147 sleep 1 148 fi 149 150 ip netns exec ${listener_ns} ./mptcp_connect -j -t $timeout -l -p $port -s ${srv_proto} 0.0.0.0 < "$sin" > "$sout" & 151 spid=$! 152 153 sleep 1 154 155 ip netns exec ${connector_ns} ./mptcp_connect -j -t $timeout -p $port -s ${cl_proto} $connect_addr < "$cin" > "$cout" & 156 cpid=$! 157 158 wait $cpid 159 retc=$? 160 wait $spid 161 rets=$? 162 163 if [ $capture -eq 1 ]; then 164 sleep 1 165 kill $cappid 166 fi 167 168 if [ ${rets} -ne 0 ] || [ ${retc} -ne 0 ]; then 169 echo " client exit code $retc, server $rets" 1>&2 170 echo "\nnetns ${listener_ns} socket stat for $port:" 1>&2 171 ip netns exec ${listener_ns} ss -nita 1>&2 -o "sport = :$port" 172 echo "\nnetns ${connector_ns} socket stat for $port:" 1>&2 173 ip netns exec ${connector_ns} ss -nita 1>&2 -o "dport = :$port" 174 175 cat "$capout" 176 return 1 177 fi 178 179 check_transfer $sin $cout "file received by client" 180 retc=$? 181 check_transfer $cin $sout "file received by server" 182 rets=$? 183 184 if [ $retc -eq 0 ] && [ $rets -eq 0 ];then 185 cat "$capout" 186 return 0 187 fi 188 189 cat "$capout" 190 return 1 191} 192 193make_file() 194{ 195 name=$1 196 who=$2 197 198 SIZE=1 199 200 dd if=/dev/urandom of="$name" bs=1024 count=$SIZE 2> /dev/null 201 echo -e "\nMPTCP_TEST_FILE_END_MARKER" >> "$name" 202 203 echo "Created $name (size $SIZE KB) containing data sent by $who" 204} 205 206run_tests() 207{ 208 listener_ns="$1" 209 connector_ns="$2" 210 connect_addr="$3" 211 lret=0 212 213 do_transfer ${listener_ns} ${connector_ns} MPTCP MPTCP ${connect_addr} 214 lret=$? 215 if [ $lret -ne 0 ]; then 216 ret=$lret 217 return 218 fi 219} 220 221chk_join_nr() 222{ 223 local msg="$1" 224 local syn_nr=$2 225 local syn_ack_nr=$3 226 local ack_nr=$4 227 local count 228 local dump_stats 229 230 printf "%-36s %s" "$msg" "syn" 231 count=`ip netns exec $ns1 nstat -as | grep MPTcpExtMPJoinSynRx | awk '{print $2}'` 232 [ -z "$count" ] && count=0 233 if [ "$count" != "$syn_nr" ]; then 234 echo "[fail] got $count JOIN[s] syn expected $syn_nr" 235 ret=1 236 dump_stats=1 237 else 238 echo -n "[ ok ]" 239 fi 240 241 echo -n " - synack" 242 count=`ip netns exec $ns2 nstat -as | grep MPTcpExtMPJoinSynAckRx | awk '{print $2}'` 243 [ -z "$count" ] && count=0 244 if [ "$count" != "$syn_ack_nr" ]; then 245 echo "[fail] got $count JOIN[s] synack expected $syn_ack_nr" 246 ret=1 247 dump_stats=1 248 else 249 echo -n "[ ok ]" 250 fi 251 252 echo -n " - ack" 253 count=`ip netns exec $ns1 nstat -as | grep MPTcpExtMPJoinAckRx | awk '{print $2}'` 254 [ -z "$count" ] && count=0 255 if [ "$count" != "$ack_nr" ]; then 256 echo "[fail] got $count JOIN[s] ack expected $ack_nr" 257 ret=1 258 dump_stats=1 259 else 260 echo "[ ok ]" 261 fi 262 if [ "${dump_stats}" = 1 ]; then 263 echo Server ns stats 264 ip netns exec $ns1 nstat -as | grep MPTcp 265 echo Client ns stats 266 ip netns exec $ns2 nstat -as | grep MPTcp 267 fi 268} 269 270sin=$(mktemp) 271sout=$(mktemp) 272cin=$(mktemp) 273cout=$(mktemp) 274init 275make_file "$cin" "client" 276make_file "$sin" "server" 277trap cleanup EXIT 278 279run_tests $ns1 $ns2 10.0.1.1 280chk_join_nr "no JOIN" "0" "0" "0" 281 282# subflow limted by client 283reset 284ip netns exec $ns2 ./pm_nl_ctl add 10.0.3.2 flags subflow 285run_tests $ns1 $ns2 10.0.1.1 286chk_join_nr "single subflow, limited by client" 0 0 0 287 288# subflow limted by server 289reset 290ip netns exec $ns2 ./pm_nl_ctl limits 0 1 291ip netns exec $ns2 ./pm_nl_ctl add 10.0.3.2 flags subflow 292run_tests $ns1 $ns2 10.0.1.1 293chk_join_nr "single subflow, limited by server" 1 1 0 294 295# subflow 296reset 297ip netns exec $ns1 ./pm_nl_ctl limits 0 1 298ip netns exec $ns2 ./pm_nl_ctl limits 0 1 299ip netns exec $ns2 ./pm_nl_ctl add 10.0.3.2 flags subflow 300run_tests $ns1 $ns2 10.0.1.1 301chk_join_nr "single subflow" 1 1 1 302 303# multiple subflows 304reset 305ip netns exec $ns1 ./pm_nl_ctl limits 0 2 306ip netns exec $ns2 ./pm_nl_ctl limits 0 2 307ip netns exec $ns2 ./pm_nl_ctl add 10.0.3.2 flags subflow 308ip netns exec $ns2 ./pm_nl_ctl add 10.0.2.2 flags subflow 309run_tests $ns1 $ns2 10.0.1.1 310chk_join_nr "multiple subflows" 2 2 2 311 312# multiple subflows limited by serverf 313reset 314ip netns exec $ns1 ./pm_nl_ctl limits 0 1 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, limited by server" 2 2 1 320 321# add_address, unused 322reset 323ip netns exec $ns1 ./pm_nl_ctl add 10.0.2.1 flags signal 324run_tests $ns1 $ns2 10.0.1.1 325chk_join_nr "unused signal address" 0 0 0 326 327# accept and use add_addr 328reset 329ip netns exec $ns1 ./pm_nl_ctl limits 0 1 330ip netns exec $ns2 ./pm_nl_ctl limits 1 1 331ip netns exec $ns1 ./pm_nl_ctl add 10.0.2.1 flags signal 332run_tests $ns1 $ns2 10.0.1.1 333chk_join_nr "signal address" 1 1 1 334 335# accept and use add_addr with an additional subflow 336# note: signal address in server ns and local addresses in client ns must 337# belong to different subnets or one of the listed local address could be 338# used for 'add_addr' subflow 339reset 340ip netns exec $ns1 ./pm_nl_ctl add 10.0.2.1 flags signal 341ip netns exec $ns1 ./pm_nl_ctl limits 0 2 342ip netns exec $ns2 ./pm_nl_ctl limits 1 2 343ip netns exec $ns2 ./pm_nl_ctl add 10.0.3.2 flags subflow 344run_tests $ns1 $ns2 10.0.1.1 345chk_join_nr "subflow and signal" 2 2 2 346 347# accept and use add_addr with additional subflows 348reset 349ip netns exec $ns1 ./pm_nl_ctl limits 0 3 350ip netns exec $ns1 ./pm_nl_ctl add 10.0.2.1 flags signal 351ip netns exec $ns2 ./pm_nl_ctl limits 1 3 352ip netns exec $ns2 ./pm_nl_ctl add 10.0.3.2 flags subflow 353ip netns exec $ns2 ./pm_nl_ctl add 10.0.4.2 flags subflow 354run_tests $ns1 $ns2 10.0.1.1 355chk_join_nr "multiple subflows and signal" 3 3 3 356 357exit $ret 358