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