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