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 exit 1 427 fi 428 429 # RM_ADDR using an invalid addr id should result in no action 430 local invalid_id=$(( client_addr_id + 1 )) 431 ip netns exec "$ns2" ./pm_nl_ctl rem token "$client4_token" id\ 432 $invalid_id > /dev/null 2>&1 433 stdbuf -o0 -e0 printf "RM_ADDR id:%d ns2 => ns1, invalid id \t"\ 434 $invalid_id 435 type=$(sed --unbuffered -n 's/.*\(type:\)\([[:digit:]]*\).*$/\2/p;q' "$server_evts") 436 if [ "$type" = "" ] 437 then 438 stdbuf -o0 -e0 printf "[OK]\n" 439 else 440 stdbuf -o0 -e0 printf "[FAIL]\n" 441 exit 1 442 fi 443 444 # RM_ADDR from the client to server machine 445 :>"$server_evts" 446 ip netns exec "$ns2" ./pm_nl_ctl rem token "$client4_token" id\ 447 $client_addr_id > /dev/null 2>&1 448 stdbuf -o0 -e0 printf "RM_ADDR id:%d ns2 => ns1 \t"\ 449 $client_addr_id 450 sleep 0.5 451 verify_remove_event "$server_evts" "$REMOVED" "$server4_token" "$client_addr_id" 452 453 # RM_ADDR from the client to server machine 454 :>"$server_evts" 455 client_addr_id=$(( client_addr_id - 1 )) 456 ip netns exec "$ns2" ./pm_nl_ctl rem token "$client4_token" id\ 457 $client_addr_id > /dev/null 2>&1 458 stdbuf -o0 -e0 printf "RM_ADDR id:%d ns2 => ns1 \t"\ 459 $client_addr_id 460 sleep 0.5 461 verify_remove_event "$server_evts" "$REMOVED" "$server4_token" "$client_addr_id" 462 463 # RM_ADDR6 from the client to server machine 464 :>"$server_evts" 465 ip netns exec "$ns2" ./pm_nl_ctl rem token "$client6_token" id\ 466 $client_addr_id > /dev/null 2>&1 467 stdbuf -o0 -e0 printf "RM_ADDR6 id:%d ns2 => ns1 \t"\ 468 $client_addr_id 469 sleep 0.5 470 verify_remove_event "$server_evts" "$REMOVED" "$server6_token" "$client_addr_id" 471 472 # Capture events on the network namespace running the client 473 :>"$client_evts" 474 475 # RM_ADDR from the server to client machine 476 ip netns exec "$ns1" ./pm_nl_ctl rem token "$server4_token" id\ 477 $server_addr_id > /dev/null 2>&1 478 stdbuf -o0 -e0 printf "RM_ADDR id:%d ns1 => ns2 \t"\ 479 $server_addr_id 480 sleep 0.5 481 verify_remove_event "$client_evts" "$REMOVED" "$client4_token" "$server_addr_id" 482 483 # RM_ADDR from the server to client machine 484 :>"$client_evts" 485 server_addr_id=$(( server_addr_id - 1 )) 486 ip netns exec "$ns1" ./pm_nl_ctl rem token "$server4_token" id\ 487 $server_addr_id > /dev/null 2>&1 488 stdbuf -o0 -e0 printf "RM_ADDR id:%d ns1 => ns2 \t" $server_addr_id 489 sleep 0.5 490 verify_remove_event "$client_evts" "$REMOVED" "$client4_token" "$server_addr_id" 491 492 # RM_ADDR6 from the server to client machine 493 :>"$client_evts" 494 ip netns exec "$ns1" ./pm_nl_ctl rem token "$server6_token" id\ 495 $server_addr_id > /dev/null 2>&1 496 stdbuf -o0 -e0 printf "RM_ADDR6 id:%d ns1 => ns2 \t" $server_addr_id 497 sleep 0.5 498 verify_remove_event "$client_evts" "$REMOVED" "$client6_token" "$server_addr_id" 499} 500 501verify_subflow_events() 502{ 503 local evt=$1 504 local e_type=$2 505 local e_token=$3 506 local e_family=$4 507 local e_saddr=$5 508 local e_daddr=$6 509 local e_dport=$7 510 local e_locid=$8 511 local e_remid=$9 512 shift 2 513 local e_from=$8 514 local e_to=$9 515 local type 516 local token 517 local family 518 local saddr 519 local daddr 520 local dport 521 local locid 522 local remid 523 524 if [ "$e_type" = "$SUB_ESTABLISHED" ] 525 then 526 if [ "$e_family" = "$AF_INET6" ] 527 then 528 stdbuf -o0 -e0 printf "CREATE_SUBFLOW6 %s (%s) => %s (%s) "\ 529 "$e_saddr" "$e_from" "$e_daddr" "$e_to" 530 else 531 stdbuf -o0 -e0 printf "CREATE_SUBFLOW %s (%s) => %s (%s) \t"\ 532 "$e_saddr" "$e_from" "$e_daddr" "$e_to" 533 fi 534 else 535 if [ "$e_family" = "$AF_INET6" ] 536 then 537 stdbuf -o0 -e0 printf "DESTROY_SUBFLOW6 %s (%s) => %s (%s) "\ 538 "$e_saddr" "$e_from" "$e_daddr" "$e_to" 539 else 540 stdbuf -o0 -e0 printf "DESTROY_SUBFLOW %s (%s) => %s (%s) \t"\ 541 "$e_saddr" "$e_from" "$e_daddr" "$e_to" 542 fi 543 fi 544 545 type=$(sed --unbuffered -n 's/.*\(type:\)\([[:digit:]]*\).*$/\2/p;q' "$evt") 546 token=$(sed --unbuffered -n 's/.*\(token:\)\([[:digit:]]*\).*$/\2/p;q' "$evt") 547 family=$(sed --unbuffered -n 's/.*\(family:\)\([[:digit:]]*\).*$/\2/p;q' "$evt") 548 dport=$(sed --unbuffered -n 's/.*\(dport:\)\([[:digit:]]*\).*$/\2/p;q' "$evt") 549 locid=$(sed --unbuffered -n 's/.*\(loc_id:\)\([[:digit:]]*\).*$/\2/p;q' "$evt") 550 remid=$(sed --unbuffered -n 's/.*\(rem_id:\)\([[:digit:]]*\).*$/\2/p;q' "$evt") 551 if [ "$family" = "$AF_INET6" ] 552 then 553 saddr=$(sed --unbuffered -n 's/.*\(saddr6:\)\([0-9a-f:.]*\).*$/\2/p;q' "$evt") 554 daddr=$(sed --unbuffered -n 's/.*\(daddr6:\)\([0-9a-f:.]*\).*$/\2/p;q' "$evt") 555 else 556 saddr=$(sed --unbuffered -n 's/.*\(saddr4:\)\([0-9.]*\).*$/\2/p;q' "$evt") 557 daddr=$(sed --unbuffered -n 's/.*\(daddr4:\)\([0-9.]*\).*$/\2/p;q' "$evt") 558 fi 559 560 check_expected "type" "token" "daddr" "dport" "family" "saddr" "locid" "remid" 561} 562 563test_subflows() 564{ 565 print_title "Subflows v4 or v6 only tests" 566 567 # Capture events on the network namespace running the server 568 :>"$server_evts" 569 570 # Attempt to add a listener at 10.0.2.2:<subflow-port> 571 ip netns exec "$ns2" ./pm_nl_ctl listen 10.0.2.2\ 572 "$client4_port" > /dev/null 2>&1 & 573 local listener_pid=$! 574 575 # ADD_ADDR from client to server machine reusing the subflow port 576 ip netns exec "$ns2" ./pm_nl_ctl ann 10.0.2.2 token "$client4_token" id\ 577 $client_addr_id > /dev/null 2>&1 578 sleep 0.5 579 580 # CREATE_SUBFLOW from server to client machine 581 :>"$server_evts" 582 ip netns exec "$ns1" ./pm_nl_ctl csf lip 10.0.2.1 lid 23 rip 10.0.2.2\ 583 rport "$client4_port" token "$server4_token" > /dev/null 2>&1 584 sleep 0.5 585 verify_subflow_events $server_evts $SUB_ESTABLISHED $server4_token $AF_INET "10.0.2.1" \ 586 "10.0.2.2" "$client4_port" "23" "$client_addr_id" "ns1" "ns2" 587 588 # Delete the listener from the client ns, if one was created 589 kill_wait $listener_pid 590 591 local sport 592 sport=$(sed --unbuffered -n 's/.*\(sport:\)\([[:digit:]]*\).*$/\2/p;q' "$server_evts") 593 594 # DESTROY_SUBFLOW from server to client machine 595 :>"$server_evts" 596 ip netns exec "$ns1" ./pm_nl_ctl dsf lip 10.0.2.1 lport "$sport" rip 10.0.2.2 rport\ 597 "$client4_port" token "$server4_token" > /dev/null 2>&1 598 sleep 0.5 599 verify_subflow_events "$server_evts" "$SUB_CLOSED" "$server4_token" "$AF_INET" "10.0.2.1"\ 600 "10.0.2.2" "$client4_port" "23" "$client_addr_id" "ns1" "ns2" 601 602 # RM_ADDR from client to server machine 603 ip netns exec "$ns2" ./pm_nl_ctl rem id $client_addr_id token\ 604 "$client4_token" > /dev/null 2>&1 605 sleep 0.5 606 607 # Attempt to add a listener at dead:beef:2::2:<subflow-port> 608 ip netns exec "$ns2" ./pm_nl_ctl listen dead:beef:2::2\ 609 "$client6_port" > /dev/null 2>&1 & 610 listener_pid=$! 611 612 # ADD_ADDR6 from client to server machine reusing the subflow port 613 :>"$server_evts" 614 ip netns exec "$ns2" ./pm_nl_ctl ann dead:beef:2::2 token "$client6_token" id\ 615 $client_addr_id > /dev/null 2>&1 616 sleep 0.5 617 618 # CREATE_SUBFLOW6 from server to client machine 619 :>"$server_evts" 620 ip netns exec "$ns1" ./pm_nl_ctl csf lip dead:beef:2::1 lid 23 rip\ 621 dead:beef:2::2 rport "$client6_port" token "$server6_token" > /dev/null 2>&1 622 sleep 0.5 623 verify_subflow_events "$server_evts" "$SUB_ESTABLISHED" "$server6_token" "$AF_INET6"\ 624 "dead:beef:2::1" "dead:beef:2::2" "$client6_port" "23"\ 625 "$client_addr_id" "ns1" "ns2" 626 627 # Delete the listener from the client ns, if one was created 628 kill_wait $listener_pid 629 630 sport=$(sed --unbuffered -n 's/.*\(sport:\)\([[:digit:]]*\).*$/\2/p;q' "$server_evts") 631 632 # DESTROY_SUBFLOW6 from server to client machine 633 :>"$server_evts" 634 ip netns exec "$ns1" ./pm_nl_ctl dsf lip dead:beef:2::1 lport "$sport" rip\ 635 dead:beef:2::2 rport "$client6_port" token "$server6_token" > /dev/null 2>&1 636 sleep 0.5 637 verify_subflow_events "$server_evts" "$SUB_CLOSED" "$server6_token" "$AF_INET6"\ 638 "dead:beef:2::1" "dead:beef:2::2" "$client6_port" "23"\ 639 "$client_addr_id" "ns1" "ns2" 640 641 # RM_ADDR from client to server machine 642 ip netns exec "$ns2" ./pm_nl_ctl rem id $client_addr_id token\ 643 "$client6_token" > /dev/null 2>&1 644 sleep 0.5 645 646 # Attempt to add a listener at 10.0.2.2:<new-port> 647 ip netns exec "$ns2" ./pm_nl_ctl listen 10.0.2.2\ 648 $new4_port > /dev/null 2>&1 & 649 listener_pid=$! 650 651 # ADD_ADDR from client to server machine using a new port 652 :>"$server_evts" 653 ip netns exec "$ns2" ./pm_nl_ctl ann 10.0.2.2 token "$client4_token" id\ 654 $client_addr_id port $new4_port > /dev/null 2>&1 655 sleep 0.5 656 657 # CREATE_SUBFLOW from server to client machine 658 :>"$server_evts" 659 ip netns exec "$ns1" ./pm_nl_ctl csf lip 10.0.2.1 lid 23 rip 10.0.2.2 rport\ 660 $new4_port token "$server4_token" > /dev/null 2>&1 661 sleep 0.5 662 verify_subflow_events "$server_evts" "$SUB_ESTABLISHED" "$server4_token" "$AF_INET"\ 663 "10.0.2.1" "10.0.2.2" "$new4_port" "23"\ 664 "$client_addr_id" "ns1" "ns2" 665 666 # Delete the listener from the client ns, if one was created 667 kill_wait $listener_pid 668 669 sport=$(sed --unbuffered -n 's/.*\(sport:\)\([[:digit:]]*\).*$/\2/p;q' "$server_evts") 670 671 # DESTROY_SUBFLOW from server to client machine 672 :>"$server_evts" 673 ip netns exec "$ns1" ./pm_nl_ctl dsf lip 10.0.2.1 lport "$sport" rip 10.0.2.2 rport\ 674 $new4_port token "$server4_token" > /dev/null 2>&1 675 sleep 0.5 676 verify_subflow_events "$server_evts" "$SUB_CLOSED" "$server4_token" "$AF_INET" "10.0.2.1"\ 677 "10.0.2.2" "$new4_port" "23" "$client_addr_id" "ns1" "ns2" 678 679 # RM_ADDR from client to server machine 680 ip netns exec "$ns2" ./pm_nl_ctl rem id $client_addr_id token\ 681 "$client4_token" > /dev/null 2>&1 682 683 # Capture events on the network namespace running the client 684 :>"$client_evts" 685 686 # Attempt to add a listener at 10.0.2.1:<subflow-port> 687 ip netns exec "$ns1" ./pm_nl_ctl listen 10.0.2.1\ 688 $app4_port > /dev/null 2>&1 & 689 listener_pid=$! 690 691 # ADD_ADDR from server to client machine reusing the subflow port 692 ip netns exec "$ns1" ./pm_nl_ctl ann 10.0.2.1 token "$server4_token" id\ 693 $server_addr_id > /dev/null 2>&1 694 sleep 0.5 695 696 # CREATE_SUBFLOW from client to server machine 697 :>"$client_evts" 698 ip netns exec "$ns2" ./pm_nl_ctl csf lip 10.0.2.2 lid 23 rip 10.0.2.1 rport\ 699 $app4_port token "$client4_token" > /dev/null 2>&1 700 sleep 0.5 701 verify_subflow_events $client_evts $SUB_ESTABLISHED $client4_token $AF_INET "10.0.2.2"\ 702 "10.0.2.1" "$app4_port" "23" "$server_addr_id" "ns2" "ns1" 703 704 # Delete the listener from the server ns, if one was created 705 kill_wait $listener_pid 706 707 sport=$(sed --unbuffered -n 's/.*\(sport:\)\([[:digit:]]*\).*$/\2/p;q' "$client_evts") 708 709 # DESTROY_SUBFLOW from client to server machine 710 :>"$client_evts" 711 ip netns exec "$ns2" ./pm_nl_ctl dsf lip 10.0.2.2 lport "$sport" rip 10.0.2.1 rport\ 712 $app4_port token "$client4_token" > /dev/null 2>&1 713 sleep 0.5 714 verify_subflow_events "$client_evts" "$SUB_CLOSED" "$client4_token" "$AF_INET" "10.0.2.2"\ 715 "10.0.2.1" "$app4_port" "23" "$server_addr_id" "ns2" "ns1" 716 717 # RM_ADDR from server to client machine 718 ip netns exec "$ns1" ./pm_nl_ctl rem id $server_addr_id token\ 719 "$server4_token" > /dev/null 2>&1 720 sleep 0.5 721 722 # Attempt to add a listener at dead:beef:2::1:<subflow-port> 723 ip netns exec "$ns1" ./pm_nl_ctl listen dead:beef:2::1\ 724 $app6_port > /dev/null 2>&1 & 725 listener_pid=$! 726 727 # ADD_ADDR6 from server to client machine reusing the subflow port 728 :>"$client_evts" 729 ip netns exec "$ns1" ./pm_nl_ctl ann dead:beef:2::1 token "$server6_token" id\ 730 $server_addr_id > /dev/null 2>&1 731 sleep 0.5 732 733 # CREATE_SUBFLOW6 from client to server machine 734 :>"$client_evts" 735 ip netns exec "$ns2" ./pm_nl_ctl csf lip dead:beef:2::2 lid 23 rip\ 736 dead:beef:2::1 rport $app6_port token "$client6_token" > /dev/null 2>&1 737 sleep 0.5 738 verify_subflow_events "$client_evts" "$SUB_ESTABLISHED" "$client6_token"\ 739 "$AF_INET6" "dead:beef:2::2"\ 740 "dead:beef:2::1" "$app6_port" "23"\ 741 "$server_addr_id" "ns2" "ns1" 742 743 # Delete the listener from the server ns, if one was created 744 kill_wait $listener_pid 745 746 sport=$(sed --unbuffered -n 's/.*\(sport:\)\([[:digit:]]*\).*$/\2/p;q' "$client_evts") 747 748 # DESTROY_SUBFLOW6 from client to server machine 749 :>"$client_evts" 750 ip netns exec "$ns2" ./pm_nl_ctl dsf lip dead:beef:2::2 lport "$sport" rip\ 751 dead:beef:2::1 rport $app6_port token "$client6_token" > /dev/null 2>&1 752 sleep 0.5 753 verify_subflow_events $client_evts $SUB_CLOSED $client6_token $AF_INET6 "dead:beef:2::2"\ 754 "dead:beef:2::1" "$app6_port" "23" "$server_addr_id" "ns2" "ns1" 755 756 # RM_ADDR6 from server to client machine 757 ip netns exec "$ns1" ./pm_nl_ctl rem id $server_addr_id token\ 758 "$server6_token" > /dev/null 2>&1 759 sleep 0.5 760 761 # Attempt to add a listener at 10.0.2.1:<new-port> 762 ip netns exec "$ns1" ./pm_nl_ctl listen 10.0.2.1\ 763 $new4_port > /dev/null 2>&1 & 764 listener_pid=$! 765 766 # ADD_ADDR from server to client machine using a new port 767 :>"$client_evts" 768 ip netns exec "$ns1" ./pm_nl_ctl ann 10.0.2.1 token "$server4_token" id\ 769 $server_addr_id port $new4_port > /dev/null 2>&1 770 sleep 0.5 771 772 # CREATE_SUBFLOW from client to server machine 773 :>"$client_evts" 774 ip netns exec "$ns2" ./pm_nl_ctl csf lip 10.0.2.2 lid 23 rip 10.0.2.1 rport\ 775 $new4_port token "$client4_token" > /dev/null 2>&1 776 sleep 0.5 777 verify_subflow_events "$client_evts" "$SUB_ESTABLISHED" "$client4_token" "$AF_INET"\ 778 "10.0.2.2" "10.0.2.1" "$new4_port" "23" "$server_addr_id" "ns2" "ns1" 779 780 # Delete the listener from the server ns, if one was created 781 kill_wait $listener_pid 782 783 sport=$(sed --unbuffered -n 's/.*\(sport:\)\([[:digit:]]*\).*$/\2/p;q' "$client_evts") 784 785 # DESTROY_SUBFLOW from client to server machine 786 :>"$client_evts" 787 ip netns exec "$ns2" ./pm_nl_ctl dsf lip 10.0.2.2 lport "$sport" rip 10.0.2.1 rport\ 788 $new4_port token "$client4_token" > /dev/null 2>&1 789 sleep 0.5 790 verify_subflow_events "$client_evts" "$SUB_CLOSED" "$client4_token" "$AF_INET" "10.0.2.2"\ 791 "10.0.2.1" "$new4_port" "23" "$server_addr_id" "ns2" "ns1" 792 793 # RM_ADDR from server to client machine 794 ip netns exec "$ns1" ./pm_nl_ctl rem id $server_addr_id token\ 795 "$server4_token" > /dev/null 2>&1 796} 797 798test_subflows_v4_v6_mix() 799{ 800 print_title "Subflows v4 and v6 mix tests" 801 802 # Attempt to add a listener at 10.0.2.1:<subflow-port> 803 ip netns exec "$ns1" ./pm_nl_ctl listen 10.0.2.1\ 804 $app6_port > /dev/null 2>&1 & 805 local listener_pid=$! 806 807 # ADD_ADDR4 from server to client machine reusing the subflow port on 808 # the established v6 connection 809 :>"$client_evts" 810 ip netns exec "$ns1" ./pm_nl_ctl ann 10.0.2.1 token "$server6_token" id\ 811 $server_addr_id dev ns1eth2 > /dev/null 2>&1 812 stdbuf -o0 -e0 printf "ADD_ADDR4 id:%d 10.0.2.1 (ns1) => ns2, reuse port\t\t" $server_addr_id 813 sleep 0.5 814 verify_announce_event "$client_evts" "$ANNOUNCED" "$client6_token" "10.0.2.1"\ 815 "$server_addr_id" "$app6_port" 816 817 # CREATE_SUBFLOW from client to server machine 818 :>"$client_evts" 819 ip netns exec "$ns2" ./pm_nl_ctl csf lip 10.0.2.2 lid 23 rip 10.0.2.1 rport\ 820 $app6_port token "$client6_token" > /dev/null 2>&1 821 sleep 0.5 822 verify_subflow_events "$client_evts" "$SUB_ESTABLISHED" "$client6_token"\ 823 "$AF_INET" "10.0.2.2" "10.0.2.1" "$app6_port" "23"\ 824 "$server_addr_id" "ns2" "ns1" 825 826 # Delete the listener from the server ns, if one was created 827 kill_wait $listener_pid 828 829 sport=$(sed --unbuffered -n 's/.*\(sport:\)\([[:digit:]]*\).*$/\2/p;q' "$client_evts") 830 831 # DESTROY_SUBFLOW from client to server machine 832 :>"$client_evts" 833 ip netns exec "$ns2" ./pm_nl_ctl dsf lip 10.0.2.2 lport "$sport" rip 10.0.2.1 rport\ 834 $app6_port token "$client6_token" > /dev/null 2>&1 835 sleep 0.5 836 verify_subflow_events "$client_evts" "$SUB_CLOSED" "$client6_token" \ 837 "$AF_INET" "10.0.2.2" "10.0.2.1" "$app6_port" "23"\ 838 "$server_addr_id" "ns2" "ns1" 839 840 # RM_ADDR from server to client machine 841 ip netns exec "$ns1" ./pm_nl_ctl rem id $server_addr_id token\ 842 "$server6_token" > /dev/null 2>&1 843 sleep 0.5 844} 845 846test_prio() 847{ 848 print_title "Prio tests" 849 850 local count 851 852 # Send MP_PRIO signal from client to server machine 853 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" 854 sleep 0.5 855 856 # Check TX 857 stdbuf -o0 -e0 printf "MP_PRIO TX \t" 858 count=$(ip netns exec "$ns2" nstat -as | grep MPTcpExtMPPrioTx | awk '{print $2}') 859 [ -z "$count" ] && count=0 860 if [ $count != 1 ]; then 861 stdbuf -o0 -e0 printf "[FAIL]\n\tCount != 1: %d\n" "${count}" 862 exit 1 863 else 864 stdbuf -o0 -e0 printf "[OK]\n" 865 fi 866 867 # Check RX 868 stdbuf -o0 -e0 printf "MP_PRIO RX \t" 869 count=$(ip netns exec "$ns1" nstat -as | grep MPTcpExtMPPrioRx | awk '{print $2}') 870 [ -z "$count" ] && count=0 871 if [ $count != 1 ]; then 872 stdbuf -o0 -e0 printf "[FAIL]\n\tCount != 1: %d\n" "${count}" 873 exit 1 874 else 875 stdbuf -o0 -e0 printf "[OK]\n" 876 fi 877} 878 879verify_listener_events() 880{ 881 local evt=$1 882 local e_type=$2 883 local e_family=$3 884 local e_saddr=$4 885 local e_sport=$5 886 local type 887 local family 888 local saddr 889 local sport 890 891 if [ $e_type = $LISTENER_CREATED ]; then 892 stdbuf -o0 -e0 printf "CREATE_LISTENER %s:%s\t\t\t\t\t"\ 893 $e_saddr $e_sport 894 elif [ $e_type = $LISTENER_CLOSED ]; then 895 stdbuf -o0 -e0 printf "CLOSE_LISTENER %s:%s\t\t\t\t\t"\ 896 $e_saddr $e_sport 897 fi 898 899 type=$(grep "type:$e_type," $evt | 900 sed --unbuffered -n 's/.*\(type:\)\([[:digit:]]*\).*$/\2/p;q') 901 family=$(grep "type:$e_type," $evt | 902 sed --unbuffered -n 's/.*\(family:\)\([[:digit:]]*\).*$/\2/p;q') 903 sport=$(grep "type:$e_type," $evt | 904 sed --unbuffered -n 's/.*\(sport:\)\([[:digit:]]*\).*$/\2/p;q') 905 if [ $family ] && [ $family = $AF_INET6 ]; then 906 saddr=$(grep "type:$e_type," $evt | 907 sed --unbuffered -n 's/.*\(saddr6:\)\([0-9a-f:.]*\).*$/\2/p;q') 908 else 909 saddr=$(grep "type:$e_type," $evt | 910 sed --unbuffered -n 's/.*\(saddr4:\)\([0-9.]*\).*$/\2/p;q') 911 fi 912 913 check_expected "type" "family" "saddr" "sport" 914} 915 916test_listener() 917{ 918 print_title "Listener tests" 919 920 if ! mptcp_lib_kallsyms_has "mptcp_event_pm_listener$"; then 921 stdbuf -o0 -e0 printf "LISTENER events \t[SKIP] Not supported\n" 922 return 923 fi 924 925 # Capture events on the network namespace running the client 926 :>$client_evts 927 928 # Attempt to add a listener at 10.0.2.2:<subflow-port> 929 ip netns exec $ns2 ./pm_nl_ctl listen 10.0.2.2\ 930 $client4_port > /dev/null 2>&1 & 931 local listener_pid=$! 932 933 sleep 0.5 934 verify_listener_events $client_evts $LISTENER_CREATED $AF_INET 10.0.2.2 $client4_port 935 936 # ADD_ADDR from client to server machine reusing the subflow port 937 ip netns exec $ns2 ./pm_nl_ctl ann 10.0.2.2 token $client4_token id\ 938 $client_addr_id > /dev/null 2>&1 939 sleep 0.5 940 941 # CREATE_SUBFLOW from server to client machine 942 ip netns exec $ns1 ./pm_nl_ctl csf lip 10.0.2.1 lid 23 rip 10.0.2.2\ 943 rport $client4_port token $server4_token > /dev/null 2>&1 944 sleep 0.5 945 946 # Delete the listener from the client ns, if one was created 947 kill_wait $listener_pid 948 949 sleep 0.5 950 verify_listener_events $client_evts $LISTENER_CLOSED $AF_INET 10.0.2.2 $client4_port 951} 952 953print_title "Make connections" 954make_connection 955make_connection "v6" 956 957test_announce 958test_remove 959test_subflows 960test_subflows_v4_v6_mix 961test_prio 962test_listener 963 964exit 0 965