1#!/bin/bash 2# SPDX-License-Identifier: GPL-2.0 3 4. "$(dirname "${0}")/mptcp_lib.sh" 5 6mptcp_lib_check_mptcp 7 8ip -Version > /dev/null 2>&1 9if [ $? -ne 0 ];then 10 echo "SKIP: Cannot not run test without ip tool" 11 exit 1 12fi 13 14ANNOUNCED=6 # MPTCP_EVENT_ANNOUNCED 15REMOVED=7 # MPTCP_EVENT_REMOVED 16SUB_ESTABLISHED=10 # MPTCP_EVENT_SUB_ESTABLISHED 17SUB_CLOSED=11 # MPTCP_EVENT_SUB_CLOSED 18LISTENER_CREATED=15 #MPTCP_EVENT_LISTENER_CREATED 19LISTENER_CLOSED=16 #MPTCP_EVENT_LISTENER_CLOSED 20 21AF_INET=2 22AF_INET6=10 23 24file="" 25server_evts="" 26client_evts="" 27server_evts_pid=0 28client_evts_pid=0 29client4_pid=0 30server4_pid=0 31client6_pid=0 32server6_pid=0 33client4_token="" 34server4_token="" 35client6_token="" 36server6_token="" 37client4_port=0; 38client6_port=0; 39app4_port=50002 40new4_port=50003 41app6_port=50004 42client_addr_id=${RANDOM:0:2} 43server_addr_id=${RANDOM:0:2} 44 45sec=$(date +%s) 46rndh=$(printf %x "$sec")-$(mktemp -u XXXXXX) 47ns1="ns1-$rndh" 48ns2="ns2-$rndh" 49 50print_title() 51{ 52 stdbuf -o0 -e0 printf "INFO: %s\n" "${1}" 53} 54 55kill_wait() 56{ 57 [ $1 -eq 0 ] && return 0 58 59 kill -SIGUSR1 $1 > /dev/null 2>&1 60 kill $1 > /dev/null 2>&1 61 wait $1 2>/dev/null 62} 63 64cleanup() 65{ 66 print_title "Cleanup" 67 68 # Terminate the MPTCP connection and related processes 69 local pid 70 for pid in $client4_pid $server4_pid $client6_pid $server6_pid\ 71 $server_evts_pid $client_evts_pid 72 do 73 kill_wait $pid 74 done 75 76 local netns 77 for netns in "$ns1" "$ns2" ;do 78 ip netns del "$netns" 79 done 80 81 rm -rf $file $client_evts $server_evts 82 83 stdbuf -o0 -e0 printf "Done\n" 84} 85 86trap cleanup EXIT 87 88# Create and configure network namespaces for testing 89for i in "$ns1" "$ns2" ;do 90 ip netns add "$i" || exit 1 91 ip -net "$i" link set lo up 92 ip netns exec "$i" sysctl -q net.mptcp.enabled=1 93 ip netns exec "$i" sysctl -q net.mptcp.pm_type=1 94done 95 96# "$ns1" ns2 97# ns1eth2 ns2eth1 98 99ip link add ns1eth2 netns "$ns1" type veth peer name ns2eth1 netns "$ns2" 100 101# Add IPv4/v6 addresses to the namespaces 102ip -net "$ns1" addr add 10.0.1.1/24 dev ns1eth2 103ip -net "$ns1" addr add 10.0.2.1/24 dev ns1eth2 104ip -net "$ns1" addr add dead:beef:1::1/64 dev ns1eth2 nodad 105ip -net "$ns1" addr add dead:beef:2::1/64 dev ns1eth2 nodad 106ip -net "$ns1" link set ns1eth2 up 107 108ip -net "$ns2" addr add 10.0.1.2/24 dev ns2eth1 109ip -net "$ns2" addr add 10.0.2.2/24 dev ns2eth1 110ip -net "$ns2" addr add dead:beef:1::2/64 dev ns2eth1 nodad 111ip -net "$ns2" addr add dead:beef:2::2/64 dev ns2eth1 nodad 112ip -net "$ns2" link set ns2eth1 up 113 114print_title "Init" 115stdbuf -o0 -e0 printf "Created network namespaces ns1, ns2 \t\t\t[OK]\n" 116 117make_file() 118{ 119 # Store a chunk of data in a file to transmit over an MPTCP connection 120 local name=$1 121 local ksize=1 122 123 dd if=/dev/urandom of="$name" bs=2 count=$ksize 2> /dev/null 124 echo -e "\nMPTCP_TEST_FILE_END_MARKER" >> "$name" 125} 126 127make_connection() 128{ 129 if [ -z "$file" ]; then 130 file=$(mktemp) 131 fi 132 make_file "$file" "client" 133 134 local is_v6=$1 135 local app_port=$app4_port 136 local connect_addr="10.0.1.1" 137 local listen_addr="0.0.0.0" 138 if [ "$is_v6" = "v6" ] 139 then 140 connect_addr="dead:beef:1::1" 141 listen_addr="::" 142 app_port=$app6_port 143 else 144 is_v6="v4" 145 fi 146 147 # Capture netlink events over the two network namespaces running 148 # the MPTCP client and server 149 if [ -z "$client_evts" ]; then 150 client_evts=$(mktemp) 151 fi 152 :>"$client_evts" 153 if [ $client_evts_pid -ne 0 ]; then 154 kill_wait $client_evts_pid 155 fi 156 ip netns exec "$ns2" ./pm_nl_ctl events >> "$client_evts" 2>&1 & 157 client_evts_pid=$! 158 if [ -z "$server_evts" ]; then 159 server_evts=$(mktemp) 160 fi 161 :>"$server_evts" 162 if [ $server_evts_pid -ne 0 ]; then 163 kill_wait $server_evts_pid 164 fi 165 ip netns exec "$ns1" ./pm_nl_ctl events >> "$server_evts" 2>&1 & 166 server_evts_pid=$! 167 sleep 0.5 168 169 # Run the server 170 ip netns exec "$ns1" \ 171 ./mptcp_connect -s MPTCP -w 300 -p $app_port -l $listen_addr > /dev/null 2>&1 & 172 local server_pid=$! 173 sleep 0.5 174 175 # Run the client, transfer $file and stay connected to the server 176 # to conduct tests 177 ip netns exec "$ns2" \ 178 ./mptcp_connect -s MPTCP -w 300 -m sendfile -p $app_port $connect_addr\ 179 2>&1 > /dev/null < "$file" & 180 local client_pid=$! 181 sleep 1 182 183 # Capture client/server attributes from MPTCP connection netlink events 184 185 local client_token 186 local client_port 187 local client_serverside 188 local server_token 189 local server_serverside 190 191 client_token=$(sed --unbuffered -n 's/.*\(token:\)\([[:digit:]]*\).*$/\2/p;q' "$client_evts") 192 client_port=$(sed --unbuffered -n 's/.*\(sport:\)\([[:digit:]]*\).*$/\2/p;q' "$client_evts") 193 client_serverside=$(sed --unbuffered -n 's/.*\(server_side:\)\([[:digit:]]*\).*$/\2/p;q'\ 194 "$client_evts") 195 server_token=$(grep "type:1," "$server_evts" | 196 sed --unbuffered -n 's/.*\(token:\)\([[:digit:]]*\).*$/\2/p;q') 197 server_serverside=$(grep "type:1," "$server_evts" | 198 sed --unbuffered -n 's/.*\(server_side:\)\([[:digit:]]*\).*$/\2/p;q') 199 200 stdbuf -o0 -e0 printf "Established IP%s MPTCP Connection ns2 => ns1 \t\t" $is_v6 201 if [ "$client_token" != "" ] && [ "$server_token" != "" ] && [ "$client_serverside" = 0 ] && 202 [ "$server_serverside" = 1 ] 203 then 204 stdbuf -o0 -e0 printf "[OK]\n" 205 else 206 stdbuf -o0 -e0 printf "[FAIL]\n" 207 stdbuf -o0 -e0 printf "\tExpected tokens (c:%s - s:%s) and server (c:%d - s:%d)\n" \ 208 "${client_token}" "${server_token}" \ 209 "${client_serverside}" "${server_serverside}" 210 exit 1 211 fi 212 213 if [ "$is_v6" = "v6" ] 214 then 215 client6_token=$client_token 216 server6_token=$server_token 217 client6_port=$client_port 218 client6_pid=$client_pid 219 server6_pid=$server_pid 220 else 221 client4_token=$client_token 222 server4_token=$server_token 223 client4_port=$client_port 224 client4_pid=$client_pid 225 server4_pid=$server_pid 226 fi 227} 228 229# $1: var name ; $2: prev ret 230check_expected_one() 231{ 232 local var="${1}" 233 local exp="e_${var}" 234 local prev_ret="${2}" 235 236 if [ "${!var}" = "${!exp}" ] 237 then 238 return 0 239 fi 240 241 if [ "${prev_ret}" = "0" ] 242 then 243 stdbuf -o0 -e0 printf "[FAIL]\n" 244 fi 245 246 stdbuf -o0 -e0 printf "\tExpected value for '%s': '%s', got '%s'.\n" \ 247 "${var}" "${!exp}" "${!var}" 248 return 1 249} 250 251# $@: all var names to check 252check_expected() 253{ 254 local ret=0 255 local var 256 257 for var in "${@}" 258 do 259 check_expected_one "${var}" "${ret}" || ret=1 260 done 261 262 if [ ${ret} -eq 0 ] 263 then 264 stdbuf -o0 -e0 printf "[OK]\n" 265 return 0 266 fi 267 268 exit 1 269} 270 271verify_announce_event() 272{ 273 local evt=$1 274 local e_type=$2 275 local e_token=$3 276 local e_addr=$4 277 local e_id=$5 278 local e_dport=$6 279 local e_af=$7 280 local type 281 local token 282 local addr 283 local dport 284 local id 285 286 type=$(sed --unbuffered -n 's/.*\(type:\)\([[:digit:]]*\).*$/\2/p;q' "$evt") 287 token=$(sed --unbuffered -n 's/.*\(token:\)\([[:digit:]]*\).*$/\2/p;q' "$evt") 288 if [ "$e_af" = "v6" ] 289 then 290 addr=$(sed --unbuffered -n 's/.*\(daddr6:\)\([0-9a-f:.]*\).*$/\2/p;q' "$evt") 291 else 292 addr=$(sed --unbuffered -n 's/.*\(daddr4:\)\([0-9.]*\).*$/\2/p;q' "$evt") 293 fi 294 dport=$(sed --unbuffered -n 's/.*\(dport:\)\([[:digit:]]*\).*$/\2/p;q' "$evt") 295 id=$(sed --unbuffered -n 's/.*\(rem_id:\)\([[:digit:]]*\).*$/\2/p;q' "$evt") 296 297 check_expected "type" "token" "addr" "dport" "id" 298} 299 300test_announce() 301{ 302 print_title "Announce tests" 303 304 # Capture events on the network namespace running the server 305 :>"$server_evts" 306 307 # ADD_ADDR using an invalid token should result in no action 308 local invalid_token=$(( client4_token - 1)) 309 ip netns exec "$ns2" ./pm_nl_ctl ann 10.0.2.2 token $invalid_token id\ 310 $client_addr_id dev ns2eth1 > /dev/null 2>&1 311 312 local type 313 type=$(sed --unbuffered -n 's/.*\(type:\)\([[:digit:]]*\).*$/\2/p;q' "$server_evts") 314 stdbuf -o0 -e0 printf "ADD_ADDR 10.0.2.2 (ns2) => ns1, invalid token \t\t" 315 if [ "$type" = "" ] 316 then 317 stdbuf -o0 -e0 printf "[OK]\n" 318 else 319 stdbuf -o0 -e0 printf "[FAIL]\n\ttype defined: %s\n" "${type}" 320 exit 1 321 fi 322 323 # ADD_ADDR from the client to server machine reusing the subflow port 324 :>"$server_evts" 325 ip netns exec "$ns2"\ 326 ./pm_nl_ctl ann 10.0.2.2 token "$client4_token" id $client_addr_id dev\ 327 ns2eth1 > /dev/null 2>&1 328 stdbuf -o0 -e0 printf "ADD_ADDR id:%d 10.0.2.2 (ns2) => ns1, reuse port \t\t" $client_addr_id 329 sleep 0.5 330 verify_announce_event $server_evts $ANNOUNCED $server4_token "10.0.2.2" $client_addr_id \ 331 "$client4_port" 332 333 # ADD_ADDR6 from the client to server machine reusing the subflow port 334 :>"$server_evts" 335 ip netns exec "$ns2" ./pm_nl_ctl ann\ 336 dead:beef:2::2 token "$client6_token" id $client_addr_id dev ns2eth1 > /dev/null 2>&1 337 stdbuf -o0 -e0 printf "ADD_ADDR6 id:%d dead:beef:2::2 (ns2) => ns1, reuse port\t\t" $client_addr_id 338 sleep 0.5 339 verify_announce_event "$server_evts" "$ANNOUNCED" "$server6_token" "dead:beef:2::2"\ 340 "$client_addr_id" "$client6_port" "v6" 341 342 # ADD_ADDR from the client to server machine using a new port 343 :>"$server_evts" 344 client_addr_id=$((client_addr_id+1)) 345 ip netns exec "$ns2" ./pm_nl_ctl ann 10.0.2.2 token "$client4_token" id\ 346 $client_addr_id dev ns2eth1 port $new4_port > /dev/null 2>&1 347 stdbuf -o0 -e0 printf "ADD_ADDR id:%d 10.0.2.2 (ns2) => ns1, new port \t\t\t" $client_addr_id 348 sleep 0.5 349 verify_announce_event "$server_evts" "$ANNOUNCED" "$server4_token" "10.0.2.2"\ 350 "$client_addr_id" "$new4_port" 351 352 # Capture events on the network namespace running the client 353 :>"$client_evts" 354 355 # ADD_ADDR from the server to client machine reusing the subflow port 356 ip netns exec "$ns1" ./pm_nl_ctl ann 10.0.2.1 token "$server4_token" id\ 357 $server_addr_id dev ns1eth2 > /dev/null 2>&1 358 stdbuf -o0 -e0 printf "ADD_ADDR id:%d 10.0.2.1 (ns1) => ns2, reuse port \t\t" $server_addr_id 359 sleep 0.5 360 verify_announce_event "$client_evts" "$ANNOUNCED" "$client4_token" "10.0.2.1"\ 361 "$server_addr_id" "$app4_port" 362 363 # ADD_ADDR6 from the server to client machine reusing the subflow port 364 :>"$client_evts" 365 ip netns exec "$ns1" ./pm_nl_ctl ann dead:beef:2::1 token "$server6_token" id\ 366 $server_addr_id dev ns1eth2 > /dev/null 2>&1 367 stdbuf -o0 -e0 printf "ADD_ADDR6 id:%d dead:beef:2::1 (ns1) => ns2, reuse port\t\t" $server_addr_id 368 sleep 0.5 369 verify_announce_event "$client_evts" "$ANNOUNCED" "$client6_token" "dead:beef:2::1"\ 370 "$server_addr_id" "$app6_port" "v6" 371 372 # ADD_ADDR from the server to client machine using a new port 373 :>"$client_evts" 374 server_addr_id=$((server_addr_id+1)) 375 ip netns exec "$ns1" ./pm_nl_ctl ann 10.0.2.1 token "$server4_token" id\ 376 $server_addr_id dev ns1eth2 port $new4_port > /dev/null 2>&1 377 stdbuf -o0 -e0 printf "ADD_ADDR id:%d 10.0.2.1 (ns1) => ns2, new port \t\t\t" $server_addr_id 378 sleep 0.5 379 verify_announce_event "$client_evts" "$ANNOUNCED" "$client4_token" "10.0.2.1"\ 380 "$server_addr_id" "$new4_port" 381} 382 383verify_remove_event() 384{ 385 local evt=$1 386 local e_type=$2 387 local e_token=$3 388 local e_id=$4 389 local type 390 local token 391 local id 392 393 type=$(sed --unbuffered -n 's/.*\(type:\)\([[:digit:]]*\).*$/\2/p;q' "$evt") 394 token=$(sed --unbuffered -n 's/.*\(token:\)\([[:digit:]]*\).*$/\2/p;q' "$evt") 395 id=$(sed --unbuffered -n 's/.*\(rem_id:\)\([[:digit:]]*\).*$/\2/p;q' "$evt") 396 397 check_expected "type" "token" "id" 398} 399 400test_remove() 401{ 402 print_title "Remove tests" 403 404 # Capture events on the network namespace running the server 405 :>"$server_evts" 406 407 # RM_ADDR using an invalid token should result in no action 408 local invalid_token=$(( client4_token - 1 )) 409 ip netns exec "$ns2" ./pm_nl_ctl rem token $invalid_token id\ 410 $client_addr_id > /dev/null 2>&1 411 stdbuf -o0 -e0 printf "RM_ADDR id:%d ns2 => ns1, invalid token \t"\ 412 $client_addr_id 413 local type 414 type=$(sed --unbuffered -n 's/.*\(type:\)\([[:digit:]]*\).*$/\2/p;q' "$server_evts") 415 if [ "$type" = "" ] 416 then 417 stdbuf -o0 -e0 printf "[OK]\n" 418 else 419 stdbuf -o0 -e0 printf "[FAIL]\n" 420 fi 421 422 # RM_ADDR using an invalid addr id should result in no action 423 local invalid_id=$(( client_addr_id + 1 )) 424 ip netns exec "$ns2" ./pm_nl_ctl rem token "$client4_token" id\ 425 $invalid_id > /dev/null 2>&1 426 stdbuf -o0 -e0 printf "RM_ADDR id:%d ns2 => ns1, invalid id \t"\ 427 $invalid_id 428 type=$(sed --unbuffered -n 's/.*\(type:\)\([[:digit:]]*\).*$/\2/p;q' "$server_evts") 429 if [ "$type" = "" ] 430 then 431 stdbuf -o0 -e0 printf "[OK]\n" 432 else 433 stdbuf -o0 -e0 printf "[FAIL]\n" 434 fi 435 436 # RM_ADDR from the client to server machine 437 :>"$server_evts" 438 ip netns exec "$ns2" ./pm_nl_ctl rem token "$client4_token" id\ 439 $client_addr_id > /dev/null 2>&1 440 stdbuf -o0 -e0 printf "RM_ADDR id:%d ns2 => ns1 \t"\ 441 $client_addr_id 442 sleep 0.5 443 verify_remove_event "$server_evts" "$REMOVED" "$server4_token" "$client_addr_id" 444 445 # RM_ADDR from the client to server machine 446 :>"$server_evts" 447 client_addr_id=$(( client_addr_id - 1 )) 448 ip netns exec "$ns2" ./pm_nl_ctl rem token "$client4_token" id\ 449 $client_addr_id > /dev/null 2>&1 450 stdbuf -o0 -e0 printf "RM_ADDR id:%d ns2 => ns1 \t"\ 451 $client_addr_id 452 sleep 0.5 453 verify_remove_event "$server_evts" "$REMOVED" "$server4_token" "$client_addr_id" 454 455 # RM_ADDR6 from the client to server machine 456 :>"$server_evts" 457 ip netns exec "$ns2" ./pm_nl_ctl rem token "$client6_token" id\ 458 $client_addr_id > /dev/null 2>&1 459 stdbuf -o0 -e0 printf "RM_ADDR6 id:%d ns2 => ns1 \t"\ 460 $client_addr_id 461 sleep 0.5 462 verify_remove_event "$server_evts" "$REMOVED" "$server6_token" "$client_addr_id" 463 464 # Capture events on the network namespace running the client 465 :>"$client_evts" 466 467 # RM_ADDR from the server to client machine 468 ip netns exec "$ns1" ./pm_nl_ctl rem token "$server4_token" id\ 469 $server_addr_id > /dev/null 2>&1 470 stdbuf -o0 -e0 printf "RM_ADDR id:%d ns1 => ns2 \t"\ 471 $server_addr_id 472 sleep 0.5 473 verify_remove_event "$client_evts" "$REMOVED" "$client4_token" "$server_addr_id" 474 475 # RM_ADDR from the server to client machine 476 :>"$client_evts" 477 server_addr_id=$(( server_addr_id - 1 )) 478 ip netns exec "$ns1" ./pm_nl_ctl rem token "$server4_token" id\ 479 $server_addr_id > /dev/null 2>&1 480 stdbuf -o0 -e0 printf "RM_ADDR id:%d ns1 => ns2 \t" $server_addr_id 481 sleep 0.5 482 verify_remove_event "$client_evts" "$REMOVED" "$client4_token" "$server_addr_id" 483 484 # RM_ADDR6 from the server to client machine 485 :>"$client_evts" 486 ip netns exec "$ns1" ./pm_nl_ctl rem token "$server6_token" id\ 487 $server_addr_id > /dev/null 2>&1 488 stdbuf -o0 -e0 printf "RM_ADDR6 id:%d ns1 => ns2 \t" $server_addr_id 489 sleep 0.5 490 verify_remove_event "$client_evts" "$REMOVED" "$client6_token" "$server_addr_id" 491} 492 493verify_subflow_events() 494{ 495 local evt=$1 496 local e_type=$2 497 local e_token=$3 498 local e_family=$4 499 local e_saddr=$5 500 local e_daddr=$6 501 local e_dport=$7 502 local e_locid=$8 503 local e_remid=$9 504 shift 2 505 local e_from=$8 506 local e_to=$9 507 local type 508 local token 509 local family 510 local saddr 511 local daddr 512 local dport 513 local locid 514 local remid 515 516 if [ "$e_type" = "$SUB_ESTABLISHED" ] 517 then 518 if [ "$e_family" = "$AF_INET6" ] 519 then 520 stdbuf -o0 -e0 printf "CREATE_SUBFLOW6 %s (%s) => %s (%s) "\ 521 "$e_saddr" "$e_from" "$e_daddr" "$e_to" 522 else 523 stdbuf -o0 -e0 printf "CREATE_SUBFLOW %s (%s) => %s (%s) \t"\ 524 "$e_saddr" "$e_from" "$e_daddr" "$e_to" 525 fi 526 else 527 if [ "$e_family" = "$AF_INET6" ] 528 then 529 stdbuf -o0 -e0 printf "DESTROY_SUBFLOW6 %s (%s) => %s (%s) "\ 530 "$e_saddr" "$e_from" "$e_daddr" "$e_to" 531 else 532 stdbuf -o0 -e0 printf "DESTROY_SUBFLOW %s (%s) => %s (%s) \t"\ 533 "$e_saddr" "$e_from" "$e_daddr" "$e_to" 534 fi 535 fi 536 537 type=$(sed --unbuffered -n 's/.*\(type:\)\([[:digit:]]*\).*$/\2/p;q' "$evt") 538 token=$(sed --unbuffered -n 's/.*\(token:\)\([[:digit:]]*\).*$/\2/p;q' "$evt") 539 family=$(sed --unbuffered -n 's/.*\(family:\)\([[:digit:]]*\).*$/\2/p;q' "$evt") 540 dport=$(sed --unbuffered -n 's/.*\(dport:\)\([[:digit:]]*\).*$/\2/p;q' "$evt") 541 locid=$(sed --unbuffered -n 's/.*\(loc_id:\)\([[:digit:]]*\).*$/\2/p;q' "$evt") 542 remid=$(sed --unbuffered -n 's/.*\(rem_id:\)\([[:digit:]]*\).*$/\2/p;q' "$evt") 543 if [ "$family" = "$AF_INET6" ] 544 then 545 saddr=$(sed --unbuffered -n 's/.*\(saddr6:\)\([0-9a-f:.]*\).*$/\2/p;q' "$evt") 546 daddr=$(sed --unbuffered -n 's/.*\(daddr6:\)\([0-9a-f:.]*\).*$/\2/p;q' "$evt") 547 else 548 saddr=$(sed --unbuffered -n 's/.*\(saddr4:\)\([0-9.]*\).*$/\2/p;q' "$evt") 549 daddr=$(sed --unbuffered -n 's/.*\(daddr4:\)\([0-9.]*\).*$/\2/p;q' "$evt") 550 fi 551 552 check_expected "type" "token" "daddr" "dport" "family" "saddr" "locid" "remid" 553} 554 555test_subflows() 556{ 557 print_title "Subflows v4 or v6 only tests" 558 559 # Capture events on the network namespace running the server 560 :>"$server_evts" 561 562 # Attempt to add a listener at 10.0.2.2:<subflow-port> 563 ip netns exec "$ns2" ./pm_nl_ctl listen 10.0.2.2\ 564 "$client4_port" > /dev/null 2>&1 & 565 local listener_pid=$! 566 567 # ADD_ADDR from client to server machine reusing the subflow port 568 ip netns exec "$ns2" ./pm_nl_ctl ann 10.0.2.2 token "$client4_token" id\ 569 $client_addr_id > /dev/null 2>&1 570 sleep 0.5 571 572 # CREATE_SUBFLOW from server to client machine 573 :>"$server_evts" 574 ip netns exec "$ns1" ./pm_nl_ctl csf lip 10.0.2.1 lid 23 rip 10.0.2.2\ 575 rport "$client4_port" token "$server4_token" > /dev/null 2>&1 576 sleep 0.5 577 verify_subflow_events $server_evts $SUB_ESTABLISHED $server4_token $AF_INET "10.0.2.1" \ 578 "10.0.2.2" "$client4_port" "23" "$client_addr_id" "ns1" "ns2" 579 580 # Delete the listener from the client ns, if one was created 581 kill_wait $listener_pid 582 583 local sport 584 sport=$(sed --unbuffered -n 's/.*\(sport:\)\([[:digit:]]*\).*$/\2/p;q' "$server_evts") 585 586 # DESTROY_SUBFLOW from server to client machine 587 :>"$server_evts" 588 ip netns exec "$ns1" ./pm_nl_ctl dsf lip 10.0.2.1 lport "$sport" rip 10.0.2.2 rport\ 589 "$client4_port" token "$server4_token" > /dev/null 2>&1 590 sleep 0.5 591 verify_subflow_events "$server_evts" "$SUB_CLOSED" "$server4_token" "$AF_INET" "10.0.2.1"\ 592 "10.0.2.2" "$client4_port" "23" "$client_addr_id" "ns1" "ns2" 593 594 # RM_ADDR from client to server machine 595 ip netns exec "$ns2" ./pm_nl_ctl rem id $client_addr_id token\ 596 "$client4_token" > /dev/null 2>&1 597 sleep 0.5 598 599 # Attempt to add a listener at dead:beef:2::2:<subflow-port> 600 ip netns exec "$ns2" ./pm_nl_ctl listen dead:beef:2::2\ 601 "$client6_port" > /dev/null 2>&1 & 602 listener_pid=$! 603 604 # ADD_ADDR6 from client to server machine reusing the subflow port 605 :>"$server_evts" 606 ip netns exec "$ns2" ./pm_nl_ctl ann dead:beef:2::2 token "$client6_token" id\ 607 $client_addr_id > /dev/null 2>&1 608 sleep 0.5 609 610 # CREATE_SUBFLOW6 from server to client machine 611 :>"$server_evts" 612 ip netns exec "$ns1" ./pm_nl_ctl csf lip dead:beef:2::1 lid 23 rip\ 613 dead:beef:2::2 rport "$client6_port" token "$server6_token" > /dev/null 2>&1 614 sleep 0.5 615 verify_subflow_events "$server_evts" "$SUB_ESTABLISHED" "$server6_token" "$AF_INET6"\ 616 "dead:beef:2::1" "dead:beef:2::2" "$client6_port" "23"\ 617 "$client_addr_id" "ns1" "ns2" 618 619 # Delete the listener from the client ns, if one was created 620 kill_wait $listener_pid 621 622 sport=$(sed --unbuffered -n 's/.*\(sport:\)\([[:digit:]]*\).*$/\2/p;q' "$server_evts") 623 624 # DESTROY_SUBFLOW6 from server to client machine 625 :>"$server_evts" 626 ip netns exec "$ns1" ./pm_nl_ctl dsf lip dead:beef:2::1 lport "$sport" rip\ 627 dead:beef:2::2 rport "$client6_port" token "$server6_token" > /dev/null 2>&1 628 sleep 0.5 629 verify_subflow_events "$server_evts" "$SUB_CLOSED" "$server6_token" "$AF_INET6"\ 630 "dead:beef:2::1" "dead:beef:2::2" "$client6_port" "23"\ 631 "$client_addr_id" "ns1" "ns2" 632 633 # RM_ADDR from client to server machine 634 ip netns exec "$ns2" ./pm_nl_ctl rem id $client_addr_id token\ 635 "$client6_token" > /dev/null 2>&1 636 sleep 0.5 637 638 # Attempt to add a listener at 10.0.2.2:<new-port> 639 ip netns exec "$ns2" ./pm_nl_ctl listen 10.0.2.2\ 640 $new4_port > /dev/null 2>&1 & 641 listener_pid=$! 642 643 # ADD_ADDR from client to server machine using a new port 644 :>"$server_evts" 645 ip netns exec "$ns2" ./pm_nl_ctl ann 10.0.2.2 token "$client4_token" id\ 646 $client_addr_id port $new4_port > /dev/null 2>&1 647 sleep 0.5 648 649 # CREATE_SUBFLOW from server to client machine 650 :>"$server_evts" 651 ip netns exec "$ns1" ./pm_nl_ctl csf lip 10.0.2.1 lid 23 rip 10.0.2.2 rport\ 652 $new4_port token "$server4_token" > /dev/null 2>&1 653 sleep 0.5 654 verify_subflow_events "$server_evts" "$SUB_ESTABLISHED" "$server4_token" "$AF_INET"\ 655 "10.0.2.1" "10.0.2.2" "$new4_port" "23"\ 656 "$client_addr_id" "ns1" "ns2" 657 658 # Delete the listener from the client ns, if one was created 659 kill_wait $listener_pid 660 661 sport=$(sed --unbuffered -n 's/.*\(sport:\)\([[:digit:]]*\).*$/\2/p;q' "$server_evts") 662 663 # DESTROY_SUBFLOW from server to client machine 664 :>"$server_evts" 665 ip netns exec "$ns1" ./pm_nl_ctl dsf lip 10.0.2.1 lport "$sport" rip 10.0.2.2 rport\ 666 $new4_port token "$server4_token" > /dev/null 2>&1 667 sleep 0.5 668 verify_subflow_events "$server_evts" "$SUB_CLOSED" "$server4_token" "$AF_INET" "10.0.2.1"\ 669 "10.0.2.2" "$new4_port" "23" "$client_addr_id" "ns1" "ns2" 670 671 # RM_ADDR from client to server machine 672 ip netns exec "$ns2" ./pm_nl_ctl rem id $client_addr_id token\ 673 "$client4_token" > /dev/null 2>&1 674 675 # Capture events on the network namespace running the client 676 :>"$client_evts" 677 678 # Attempt to add a listener at 10.0.2.1:<subflow-port> 679 ip netns exec "$ns1" ./pm_nl_ctl listen 10.0.2.1\ 680 $app4_port > /dev/null 2>&1 & 681 listener_pid=$! 682 683 # ADD_ADDR from server to client machine reusing the subflow port 684 ip netns exec "$ns1" ./pm_nl_ctl ann 10.0.2.1 token "$server4_token" id\ 685 $server_addr_id > /dev/null 2>&1 686 sleep 0.5 687 688 # CREATE_SUBFLOW from client to server machine 689 :>"$client_evts" 690 ip netns exec "$ns2" ./pm_nl_ctl csf lip 10.0.2.2 lid 23 rip 10.0.2.1 rport\ 691 $app4_port token "$client4_token" > /dev/null 2>&1 692 sleep 0.5 693 verify_subflow_events $client_evts $SUB_ESTABLISHED $client4_token $AF_INET "10.0.2.2"\ 694 "10.0.2.1" "$app4_port" "23" "$server_addr_id" "ns2" "ns1" 695 696 # Delete the listener from the server ns, if one was created 697 kill_wait $listener_pid 698 699 sport=$(sed --unbuffered -n 's/.*\(sport:\)\([[:digit:]]*\).*$/\2/p;q' "$client_evts") 700 701 # DESTROY_SUBFLOW from client to server machine 702 :>"$client_evts" 703 ip netns exec "$ns2" ./pm_nl_ctl dsf lip 10.0.2.2 lport "$sport" rip 10.0.2.1 rport\ 704 $app4_port token "$client4_token" > /dev/null 2>&1 705 sleep 0.5 706 verify_subflow_events "$client_evts" "$SUB_CLOSED" "$client4_token" "$AF_INET" "10.0.2.2"\ 707 "10.0.2.1" "$app4_port" "23" "$server_addr_id" "ns2" "ns1" 708 709 # RM_ADDR from server to client machine 710 ip netns exec "$ns1" ./pm_nl_ctl rem id $server_addr_id token\ 711 "$server4_token" > /dev/null 2>&1 712 sleep 0.5 713 714 # Attempt to add a listener at dead:beef:2::1:<subflow-port> 715 ip netns exec "$ns1" ./pm_nl_ctl listen dead:beef:2::1\ 716 $app6_port > /dev/null 2>&1 & 717 listener_pid=$! 718 719 # ADD_ADDR6 from server to client machine reusing the subflow port 720 :>"$client_evts" 721 ip netns exec "$ns1" ./pm_nl_ctl ann dead:beef:2::1 token "$server6_token" id\ 722 $server_addr_id > /dev/null 2>&1 723 sleep 0.5 724 725 # CREATE_SUBFLOW6 from client to server machine 726 :>"$client_evts" 727 ip netns exec "$ns2" ./pm_nl_ctl csf lip dead:beef:2::2 lid 23 rip\ 728 dead:beef:2::1 rport $app6_port token "$client6_token" > /dev/null 2>&1 729 sleep 0.5 730 verify_subflow_events "$client_evts" "$SUB_ESTABLISHED" "$client6_token"\ 731 "$AF_INET6" "dead:beef:2::2"\ 732 "dead:beef:2::1" "$app6_port" "23"\ 733 "$server_addr_id" "ns2" "ns1" 734 735 # Delete the listener from the server ns, if one was created 736 kill_wait $listener_pid 737 738 sport=$(sed --unbuffered -n 's/.*\(sport:\)\([[:digit:]]*\).*$/\2/p;q' "$client_evts") 739 740 # DESTROY_SUBFLOW6 from client to server machine 741 :>"$client_evts" 742 ip netns exec "$ns2" ./pm_nl_ctl dsf lip dead:beef:2::2 lport "$sport" rip\ 743 dead:beef:2::1 rport $app6_port token "$client6_token" > /dev/null 2>&1 744 sleep 0.5 745 verify_subflow_events $client_evts $SUB_CLOSED $client6_token $AF_INET6 "dead:beef:2::2"\ 746 "dead:beef:2::1" "$app6_port" "23" "$server_addr_id" "ns2" "ns1" 747 748 # RM_ADDR6 from server to client machine 749 ip netns exec "$ns1" ./pm_nl_ctl rem id $server_addr_id token\ 750 "$server6_token" > /dev/null 2>&1 751 sleep 0.5 752 753 # Attempt to add a listener at 10.0.2.1:<new-port> 754 ip netns exec "$ns1" ./pm_nl_ctl listen 10.0.2.1\ 755 $new4_port > /dev/null 2>&1 & 756 listener_pid=$! 757 758 # ADD_ADDR from server to client machine using a new port 759 :>"$client_evts" 760 ip netns exec "$ns1" ./pm_nl_ctl ann 10.0.2.1 token "$server4_token" id\ 761 $server_addr_id port $new4_port > /dev/null 2>&1 762 sleep 0.5 763 764 # CREATE_SUBFLOW from client to server machine 765 :>"$client_evts" 766 ip netns exec "$ns2" ./pm_nl_ctl csf lip 10.0.2.2 lid 23 rip 10.0.2.1 rport\ 767 $new4_port token "$client4_token" > /dev/null 2>&1 768 sleep 0.5 769 verify_subflow_events "$client_evts" "$SUB_ESTABLISHED" "$client4_token" "$AF_INET"\ 770 "10.0.2.2" "10.0.2.1" "$new4_port" "23" "$server_addr_id" "ns2" "ns1" 771 772 # Delete the listener from the server ns, if one was created 773 kill_wait $listener_pid 774 775 sport=$(sed --unbuffered -n 's/.*\(sport:\)\([[:digit:]]*\).*$/\2/p;q' "$client_evts") 776 777 # DESTROY_SUBFLOW from client to server machine 778 :>"$client_evts" 779 ip netns exec "$ns2" ./pm_nl_ctl dsf lip 10.0.2.2 lport "$sport" rip 10.0.2.1 rport\ 780 $new4_port token "$client4_token" > /dev/null 2>&1 781 sleep 0.5 782 verify_subflow_events "$client_evts" "$SUB_CLOSED" "$client4_token" "$AF_INET" "10.0.2.2"\ 783 "10.0.2.1" "$new4_port" "23" "$server_addr_id" "ns2" "ns1" 784 785 # RM_ADDR from server to client machine 786 ip netns exec "$ns1" ./pm_nl_ctl rem id $server_addr_id token\ 787 "$server4_token" > /dev/null 2>&1 788} 789 790test_subflows_v4_v6_mix() 791{ 792 print_title "Subflows v4 and v6 mix tests" 793 794 # Attempt to add a listener at 10.0.2.1:<subflow-port> 795 ip netns exec "$ns1" ./pm_nl_ctl listen 10.0.2.1\ 796 $app6_port > /dev/null 2>&1 & 797 local listener_pid=$! 798 799 # ADD_ADDR4 from server to client machine reusing the subflow port on 800 # the established v6 connection 801 :>"$client_evts" 802 ip netns exec "$ns1" ./pm_nl_ctl ann 10.0.2.1 token "$server6_token" id\ 803 $server_addr_id dev ns1eth2 > /dev/null 2>&1 804 stdbuf -o0 -e0 printf "ADD_ADDR4 id:%d 10.0.2.1 (ns1) => ns2, reuse port\t\t" $server_addr_id 805 sleep 0.5 806 verify_announce_event "$client_evts" "$ANNOUNCED" "$client6_token" "10.0.2.1"\ 807 "$server_addr_id" "$app6_port" 808 809 # CREATE_SUBFLOW from client to server machine 810 :>"$client_evts" 811 ip netns exec "$ns2" ./pm_nl_ctl csf lip 10.0.2.2 lid 23 rip 10.0.2.1 rport\ 812 $app6_port token "$client6_token" > /dev/null 2>&1 813 sleep 0.5 814 verify_subflow_events "$client_evts" "$SUB_ESTABLISHED" "$client6_token"\ 815 "$AF_INET" "10.0.2.2" "10.0.2.1" "$app6_port" "23"\ 816 "$server_addr_id" "ns2" "ns1" 817 818 # Delete the listener from the server ns, if one was created 819 kill_wait $listener_pid 820 821 sport=$(sed --unbuffered -n 's/.*\(sport:\)\([[:digit:]]*\).*$/\2/p;q' "$client_evts") 822 823 # DESTROY_SUBFLOW from client to server machine 824 :>"$client_evts" 825 ip netns exec "$ns2" ./pm_nl_ctl dsf lip 10.0.2.2 lport "$sport" rip 10.0.2.1 rport\ 826 $app6_port token "$client6_token" > /dev/null 2>&1 827 sleep 0.5 828 verify_subflow_events "$client_evts" "$SUB_CLOSED" "$client6_token" \ 829 "$AF_INET" "10.0.2.2" "10.0.2.1" "$app6_port" "23"\ 830 "$server_addr_id" "ns2" "ns1" 831 832 # RM_ADDR from server to client machine 833 ip netns exec "$ns1" ./pm_nl_ctl rem id $server_addr_id token\ 834 "$server6_token" > /dev/null 2>&1 835 sleep 0.5 836} 837 838test_prio() 839{ 840 print_title "Prio tests" 841 842 local count 843 844 # Send MP_PRIO signal from client to server machine 845 ip netns exec "$ns2" ./pm_nl_ctl set 10.0.1.2 port "$client4_port" flags backup token "$client4_token" rip 10.0.1.1 rport "$server4_port" 846 sleep 0.5 847 848 # Check TX 849 stdbuf -o0 -e0 printf "MP_PRIO TX \t" 850 count=$(ip netns exec "$ns2" nstat -as | grep MPTcpExtMPPrioTx | awk '{print $2}') 851 [ -z "$count" ] && count=0 852 if [ $count != 1 ]; then 853 stdbuf -o0 -e0 printf "[FAIL]\n\tCount != 1: %d\n" "${count}" 854 exit 1 855 else 856 stdbuf -o0 -e0 printf "[OK]\n" 857 fi 858 859 # Check RX 860 stdbuf -o0 -e0 printf "MP_PRIO RX \t" 861 count=$(ip netns exec "$ns1" nstat -as | grep MPTcpExtMPPrioRx | awk '{print $2}') 862 [ -z "$count" ] && count=0 863 if [ $count != 1 ]; then 864 stdbuf -o0 -e0 printf "[FAIL]\n\tCount != 1: %d\n" "${count}" 865 exit 1 866 else 867 stdbuf -o0 -e0 printf "[OK]\n" 868 fi 869} 870 871verify_listener_events() 872{ 873 local evt=$1 874 local e_type=$2 875 local e_family=$3 876 local e_saddr=$4 877 local e_sport=$5 878 local type 879 local family 880 local saddr 881 local sport 882 883 if [ $e_type = $LISTENER_CREATED ]; then 884 stdbuf -o0 -e0 printf "CREATE_LISTENER %s:%s\t\t\t\t\t"\ 885 $e_saddr $e_sport 886 elif [ $e_type = $LISTENER_CLOSED ]; then 887 stdbuf -o0 -e0 printf "CLOSE_LISTENER %s:%s\t\t\t\t\t"\ 888 $e_saddr $e_sport 889 fi 890 891 type=$(grep "type:$e_type," $evt | 892 sed --unbuffered -n 's/.*\(type:\)\([[:digit:]]*\).*$/\2/p;q') 893 family=$(grep "type:$e_type," $evt | 894 sed --unbuffered -n 's/.*\(family:\)\([[:digit:]]*\).*$/\2/p;q') 895 sport=$(grep "type:$e_type," $evt | 896 sed --unbuffered -n 's/.*\(sport:\)\([[:digit:]]*\).*$/\2/p;q') 897 if [ $family ] && [ $family = $AF_INET6 ]; then 898 saddr=$(grep "type:$e_type," $evt | 899 sed --unbuffered -n 's/.*\(saddr6:\)\([0-9a-f:.]*\).*$/\2/p;q') 900 else 901 saddr=$(grep "type:$e_type," $evt | 902 sed --unbuffered -n 's/.*\(saddr4:\)\([0-9.]*\).*$/\2/p;q') 903 fi 904 905 check_expected "type" "family" "saddr" "sport" 906} 907 908test_listener() 909{ 910 print_title "Listener tests" 911 912 # Capture events on the network namespace running the client 913 :>$client_evts 914 915 # Attempt to add a listener at 10.0.2.2:<subflow-port> 916 ip netns exec $ns2 ./pm_nl_ctl listen 10.0.2.2\ 917 $client4_port > /dev/null 2>&1 & 918 local listener_pid=$! 919 920 sleep 0.5 921 verify_listener_events $client_evts $LISTENER_CREATED $AF_INET 10.0.2.2 $client4_port 922 923 # ADD_ADDR from client to server machine reusing the subflow port 924 ip netns exec $ns2 ./pm_nl_ctl ann 10.0.2.2 token $client4_token id\ 925 $client_addr_id > /dev/null 2>&1 926 sleep 0.5 927 928 # CREATE_SUBFLOW from server to client machine 929 ip netns exec $ns1 ./pm_nl_ctl csf lip 10.0.2.1 lid 23 rip 10.0.2.2\ 930 rport $client4_port token $server4_token > /dev/null 2>&1 931 sleep 0.5 932 933 # Delete the listener from the client ns, if one was created 934 kill_wait $listener_pid 935 936 sleep 0.5 937 verify_listener_events $client_evts $LISTENER_CLOSED $AF_INET 10.0.2.2 $client4_port 938} 939 940print_title "Make connections" 941make_connection 942make_connection "v6" 943 944test_announce 945test_remove 946test_subflows 947test_subflows_v4_v6_mix 948test_prio 949test_listener 950 951exit 0 952