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