Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'mptcp-pm-listener-events-selftests-cleanup'

Matthieu Baerts says:

====================
mptcp: PM listener events + selftests cleanup

Thanks to the patch 6/11, the MPTCP path manager now sends Netlink events
when MPTCP listening sockets are created and closed. The reason why it is
needed is explained in the linked ticket [1]:

MPTCP for Linux, when not using the in-kernel PM, depends on the
userspace PM to create extra listening sockets before announcing
addresses and ports. Let's call these "PM listeners".

With the existing MPTCP netlink events, a userspace PM can create
PM listeners at startup time, or in response to an incoming connection.
Creating sockets in response to connections is not optimal: ADD_ADDRs
can't be sent until the sockets are created and listen()ed, and if all
connections are closed then it may not be clear to the userspace
PM daemon that PM listener sockets should be cleaned up.

Hence this feature request: to add MPTCP netlink events for listening
socket close & create, so PM listening sockets can be managed based
on application activity.

[1] https://github.com/multipath-tcp/mptcp_net-next/issues/313

Selftests for these new Netlink events have been added in patches 9,11/11.

The remaining patches introduce different cleanups and small improvements
in MPTCP selftests to ease the maintenance and the addition of new tests.
====================

Link: https://lore.kernel.org/r/20221130140637.409926-1-matthieu.baerts@tessares.net
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+375 -192
+9
include/uapi/linux/mptcp.h
··· 160 160 * daddr4 | daddr6, sport, dport, backup, if_idx 161 161 * [, error] 162 162 * The priority of a subflow has changed. 'error' should not be set. 163 + * 164 + * MPTCP_EVENT_LISTENER_CREATED: family, sport, saddr4 | saddr6 165 + * A new PM listener is created. 166 + * 167 + * MPTCP_EVENT_LISTENER_CLOSED: family, sport, saddr4 | saddr6 168 + * A PM listener is closed. 163 169 */ 164 170 enum mptcp_event_type { 165 171 MPTCP_EVENT_UNSPEC = 0, ··· 180 174 MPTCP_EVENT_SUB_CLOSED = 11, 181 175 182 176 MPTCP_EVENT_SUB_PRIORITY = 13, 177 + 178 + MPTCP_EVENT_LISTENER_CREATED = 15, 179 + MPTCP_EVENT_LISTENER_CLOSED = 16, 183 180 }; 184 181 185 182 enum mptcp_event_attr {
+57
net/mptcp/pm_netlink.c
··· 1029 1029 if (err) 1030 1030 return err; 1031 1031 1032 + mptcp_event_pm_listener(ssock->sk, MPTCP_EVENT_LISTENER_CREATED); 1033 + 1032 1034 return 0; 1033 1035 } 1034 1036 ··· 2154 2152 kfree_skb(skb); 2155 2153 } 2156 2154 2155 + void mptcp_event_pm_listener(const struct sock *ssk, 2156 + enum mptcp_event_type event) 2157 + { 2158 + const struct inet_sock *issk = inet_sk(ssk); 2159 + struct net *net = sock_net(ssk); 2160 + struct nlmsghdr *nlh; 2161 + struct sk_buff *skb; 2162 + 2163 + if (!genl_has_listeners(&mptcp_genl_family, net, MPTCP_PM_EV_GRP_OFFSET)) 2164 + return; 2165 + 2166 + skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 2167 + if (!skb) 2168 + return; 2169 + 2170 + nlh = genlmsg_put(skb, 0, 0, &mptcp_genl_family, 0, event); 2171 + if (!nlh) 2172 + goto nla_put_failure; 2173 + 2174 + if (nla_put_u16(skb, MPTCP_ATTR_FAMILY, ssk->sk_family)) 2175 + goto nla_put_failure; 2176 + 2177 + if (nla_put_be16(skb, MPTCP_ATTR_SPORT, issk->inet_sport)) 2178 + goto nla_put_failure; 2179 + 2180 + switch (ssk->sk_family) { 2181 + case AF_INET: 2182 + if (nla_put_in_addr(skb, MPTCP_ATTR_SADDR4, issk->inet_saddr)) 2183 + goto nla_put_failure; 2184 + break; 2185 + #if IS_ENABLED(CONFIG_MPTCP_IPV6) 2186 + case AF_INET6: { 2187 + const struct ipv6_pinfo *np = inet6_sk(ssk); 2188 + 2189 + if (nla_put_in6_addr(skb, MPTCP_ATTR_SADDR6, &np->saddr)) 2190 + goto nla_put_failure; 2191 + break; 2192 + } 2193 + #endif 2194 + default: 2195 + WARN_ON_ONCE(1); 2196 + goto nla_put_failure; 2197 + } 2198 + 2199 + genlmsg_end(skb, nlh); 2200 + mptcp_nl_mcast_send(net, skb, GFP_KERNEL); 2201 + return; 2202 + 2203 + nla_put_failure: 2204 + kfree_skb(skb); 2205 + } 2206 + 2157 2207 void mptcp_event(enum mptcp_event_type type, const struct mptcp_sock *msk, 2158 2208 const struct sock *ssk, gfp_t gfp) 2159 2209 { ··· 2250 2196 case MPTCP_EVENT_SUB_CLOSED: 2251 2197 if (mptcp_event_sub_closed(skb, msk, ssk) < 0) 2252 2198 goto nla_put_failure; 2199 + break; 2200 + case MPTCP_EVENT_LISTENER_CREATED: 2201 + case MPTCP_EVENT_LISTENER_CLOSED: 2253 2202 break; 2254 2203 } 2255 2204
+3
net/mptcp/protocol.c
··· 2355 2355 tcp_set_state(ssk, TCP_CLOSE); 2356 2356 mptcp_subflow_queue_clean(ssk); 2357 2357 inet_csk_listen_stop(ssk); 2358 + mptcp_event_pm_listener(ssk, MPTCP_EVENT_LISTENER_CLOSED); 2358 2359 } 2359 2360 __tcp_close(ssk, 0); 2360 2361 ··· 3647 3646 inet_sk_state_store(sock->sk, inet_sk_state_load(ssock->sk)); 3648 3647 if (!err) 3649 3648 mptcp_copy_inaddrs(sock->sk, ssock->sk); 3649 + 3650 + mptcp_event_pm_listener(ssock->sk, MPTCP_EVENT_LISTENER_CREATED); 3650 3651 3651 3652 unlock: 3652 3653 release_sock(sock->sk);
+2
net/mptcp/protocol.h
··· 839 839 const struct sock *ssk, gfp_t gfp); 840 840 void mptcp_event_addr_announced(const struct sock *ssk, const struct mptcp_addr_info *info); 841 841 void mptcp_event_addr_removed(const struct mptcp_sock *msk, u8 id); 842 + void mptcp_event_pm_listener(const struct sock *ssk, 843 + enum mptcp_event_type event); 842 844 bool mptcp_userspace_pm_active(const struct mptcp_sock *msk); 843 845 844 846 void mptcp_fastopen_gen_msk_ackseq(struct mptcp_sock *msk, struct mptcp_subflow_context *subflow,
+1
tools/testing/selftests/net/mptcp/diag.sh
··· 1 1 #!/bin/bash 2 2 # SPDX-License-Identifier: GPL-2.0 3 3 4 + sec=$(date +%s) 4 5 rndh=$(printf %x $sec)-$(mktemp -u XXXXXX) 5 6 ns="ns1-$rndh" 6 7 ksft_skip=4
+1 -5
tools/testing/selftests/net/mptcp/mptcp_connect.sh
··· 274 274 275 275 check_mptcp_disabled() 276 276 { 277 - local disabled_ns 278 - disabled_ns="ns_disabled-$sech-$(mktemp -u XXXXXX)" 277 + local disabled_ns="ns_disabled-$rndh" 279 278 ip netns add ${disabled_ns} || exit $ksft_skip 280 279 281 280 # net.mptcp.enabled should be enabled by default ··· 780 781 781 782 run_tests_disconnect() 782 783 { 783 - local peekmode="$1" 784 784 local old_cin=$cin 785 785 local old_sin=$sin 786 786 ··· 787 789 788 790 # force do_transfer to cope with the multiple tranmissions 789 791 sin="$cin.disconnect" 790 - sin_disconnect=$old_sin 791 792 cin="$cin.disconnect" 792 793 cin_disconnect="$old_cin" 793 794 connect_per_transfer=3 ··· 797 800 798 801 # restore previous status 799 802 sin=$old_sin 800 - sin_disconnect="$cout".disconnect 801 803 cin=$old_cin 802 804 cin_disconnect="$cin".disconnect 803 805 connect_per_transfer=1
+91 -27
tools/testing/selftests/net/mptcp/mptcp_join.sh
··· 26 26 check_invert=0 27 27 validate_checksum=0 28 28 init=0 29 + evts_ns1="" 30 + evts_ns2="" 31 + evts_ns1_pid=0 32 + evts_ns2_pid=0 29 33 30 34 declare -A all_tests 31 35 declare -a only_tests_ids ··· 63 59 { 64 60 capout=$(mktemp) 65 61 66 - local rndh 67 - rndh=$(mktemp -u XXXXXX) 62 + local sec rndh 63 + sec=$(date +%s) 64 + rndh=$(printf %x $sec)-$(mktemp -u XXXXXX) 68 65 69 66 ns1="ns1-$rndh" 70 67 ns2="ns2-$rndh" ··· 158 153 cin=$(mktemp) 159 154 cinsent=$(mktemp) 160 155 cout=$(mktemp) 156 + evts_ns1=$(mktemp) 157 + evts_ns2=$(mktemp) 161 158 162 159 trap cleanup EXIT 163 160 ··· 171 164 { 172 165 rm -f "$cin" "$cout" "$sinfail" 173 166 rm -f "$sin" "$sout" "$cinsent" "$cinfail" 167 + rm -rf $evts_ns1 $evts_ns2 174 168 cleanup_partial 175 169 } 176 170 ··· 327 319 index 100 || exit 1 328 320 } 329 321 322 + reset_with_events() 323 + { 324 + reset "${1}" || return 1 325 + 326 + :> "$evts_ns1" 327 + :> "$evts_ns2" 328 + ip netns exec $ns1 ./pm_nl_ctl events >> "$evts_ns1" 2>&1 & 329 + evts_ns1_pid=$! 330 + ip netns exec $ns2 ./pm_nl_ctl events >> "$evts_ns2" 2>&1 & 331 + evts_ns2_pid=$! 332 + } 333 + 330 334 fail_test() 331 335 { 332 336 ret=1 ··· 490 470 { 491 471 kill $1 > /dev/null 2>&1 492 472 wait $1 2>/dev/null 473 + } 474 + 475 + kill_events_pids() 476 + { 477 + kill_wait $evts_ns1_pid 478 + kill_wait $evts_ns2_pid 493 479 } 494 480 495 481 pm_nl_set_limits() ··· 698 672 local port=$((10000 + TEST_COUNT - 1)) 699 673 local cappid 700 674 local userspace_pm=0 701 - local evts_ns1 702 - local evts_ns1_pid 703 - local evts_ns2 704 - local evts_ns2_pid 705 675 706 676 :> "$cout" 707 677 :> "$sout" ··· 774 752 addr_nr_ns2=${addr_nr_ns2:9} 775 753 fi 776 754 777 - if [ $userspace_pm -eq 1 ]; then 778 - evts_ns1=$(mktemp) 779 - evts_ns2=$(mktemp) 780 - :> "$evts_ns1" 781 - :> "$evts_ns2" 782 - ip netns exec ${listener_ns} ./pm_nl_ctl events >> "$evts_ns1" 2>&1 & 783 - evts_ns1_pid=$! 784 - ip netns exec ${connector_ns} ./pm_nl_ctl events >> "$evts_ns2" 2>&1 & 785 - evts_ns2_pid=$! 786 - fi 787 - 788 755 local local_addr 789 756 if is_v6 "${connect_addr}"; then 790 757 local_addr="::" ··· 840 829 if [ $userspace_pm -eq 0 ]; then 841 830 pm_nl_add_endpoint $ns1 $addr flags signal 842 831 else 843 - tk=$(sed -n 's/.*\(token:\)\([[:digit:]]*\).*$/\2/p;q' "$evts_ns1") 832 + tk=$(grep "type:1," "$evts_ns1" | 833 + sed -n 's/.*\(token:\)\([[:digit:]]*\).*$/\2/p;q') 844 834 ip netns exec ${listener_ns} ./pm_nl_ctl ann $addr token $tk id $id 845 835 sleep 1 846 836 ip netns exec ${listener_ns} ./pm_nl_ctl rem token $tk id $id ··· 990 978 if [ $capture -eq 1 ]; then 991 979 sleep 1 992 980 kill $cappid 993 - fi 994 - 995 - if [ $userspace_pm -eq 1 ]; then 996 - kill_wait $evts_ns1_pid 997 - kill_wait $evts_ns2_pid 998 - rm -rf $evts_ns1 $evts_ns2 999 981 fi 1000 982 1001 983 NSTAT_HISTORY=/tmp/${listener_ns}.nstat ip netns exec ${listener_ns} \ ··· 2513 2507 fi 2514 2508 } 2515 2509 2510 + LISTENER_CREATED=15 #MPTCP_EVENT_LISTENER_CREATED 2511 + LISTENER_CLOSED=16 #MPTCP_EVENT_LISTENER_CLOSED 2512 + 2513 + AF_INET=2 2514 + AF_INET6=10 2515 + 2516 + verify_listener_events() 2517 + { 2518 + local evt=$1 2519 + local e_type=$2 2520 + local e_family=$3 2521 + local e_saddr=$4 2522 + local e_sport=$5 2523 + local type 2524 + local family 2525 + local saddr 2526 + local sport 2527 + 2528 + if [ $e_type = $LISTENER_CREATED ]; then 2529 + stdbuf -o0 -e0 printf "\t\t\t\t\t CREATE_LISTENER %s:%s"\ 2530 + $e_saddr $e_sport 2531 + elif [ $e_type = $LISTENER_CLOSED ]; then 2532 + stdbuf -o0 -e0 printf "\t\t\t\t\t CLOSE_LISTENER %s:%s "\ 2533 + $e_saddr $e_sport 2534 + fi 2535 + 2536 + type=$(grep "type:$e_type," $evt | 2537 + sed --unbuffered -n 's/.*\(type:\)\([[:digit:]]*\).*$/\2/p;q') 2538 + family=$(grep "type:$e_type," $evt | 2539 + sed --unbuffered -n 's/.*\(family:\)\([[:digit:]]*\).*$/\2/p;q') 2540 + sport=$(grep "type:$e_type," $evt | 2541 + sed --unbuffered -n 's/.*\(sport:\)\([[:digit:]]*\).*$/\2/p;q') 2542 + if [ $family ] && [ $family = $AF_INET6 ]; then 2543 + saddr=$(grep "type:$e_type," $evt | 2544 + sed --unbuffered -n 's/.*\(saddr6:\)\([0-9a-f:.]*\).*$/\2/p;q') 2545 + else 2546 + saddr=$(grep "type:$e_type," $evt | 2547 + sed --unbuffered -n 's/.*\(saddr4:\)\([0-9.]*\).*$/\2/p;q') 2548 + fi 2549 + 2550 + if [ $type ] && [ $type = $e_type ] && 2551 + [ $family ] && [ $family = $e_family ] && 2552 + [ $saddr ] && [ $saddr = $e_saddr ] && 2553 + [ $sport ] && [ $sport = $e_sport ]; then 2554 + stdbuf -o0 -e0 printf "[ ok ]\n" 2555 + return 0 2556 + fi 2557 + fail_test 2558 + stdbuf -o0 -e0 printf "[fail]\n" 2559 + } 2560 + 2516 2561 add_addr_ports_tests() 2517 2562 { 2518 2563 # signal address with port ··· 2588 2531 fi 2589 2532 2590 2533 # single address with port, remove 2591 - if reset "remove single address with port"; then 2534 + # pm listener events 2535 + if reset_with_events "remove single address with port"; then 2592 2536 pm_nl_set_limits $ns1 0 1 2593 2537 pm_nl_add_endpoint $ns1 10.0.2.1 flags signal port 10100 2594 2538 pm_nl_set_limits $ns2 1 1 ··· 2597 2539 chk_join_nr 1 1 1 2598 2540 chk_add_nr 1 1 1 2599 2541 chk_rm_nr 1 1 invert 2542 + 2543 + verify_listener_events $evts_ns1 $LISTENER_CREATED $AF_INET 10.0.2.1 10100 2544 + verify_listener_events $evts_ns1 $LISTENER_CLOSED $AF_INET 10.0.2.1 10100 2545 + kill_events_pids 2600 2546 fi 2601 2547 2602 2548 # subflow and signal with port, remove ··· 3021 2959 fi 3022 2960 3023 2961 # userspace pm add & remove address 3024 - if reset "userspace pm add & remove address"; then 2962 + if reset_with_events "userspace pm add & remove address"; then 3025 2963 set_userspace_pm $ns1 3026 2964 pm_nl_set_limits $ns2 1 1 3027 2965 run_tests $ns1 $ns2 10.0.1.1 0 userspace_1 0 slow 3028 2966 chk_join_nr 1 1 1 3029 2967 chk_add_nr 1 1 3030 2968 chk_rm_nr 1 1 invert 2969 + kill_events_pids 3031 2970 fi 3032 2971 3033 2972 # userspace pm create destroy subflow 3034 - if reset "userspace pm create destroy subflow"; then 2973 + if reset_with_events "userspace pm create destroy subflow"; then 3035 2974 set_userspace_pm $ns2 3036 2975 pm_nl_set_limits $ns1 0 1 3037 2976 run_tests $ns1 $ns2 10.0.1.1 0 0 userspace_1 slow 3038 2977 chk_join_nr 1 1 1 3039 2978 chk_rm_nr 0 1 2979 + kill_events_pids 3040 2980 fi 3041 2981 } 3042 2982
+36 -33
tools/testing/selftests/net/mptcp/mptcp_sockopt.sh
··· 10 10 timeout_poll=30 11 11 timeout_test=$((timeout_poll * 2 + 1)) 12 12 mptcp_connect="" 13 - do_all_tests=1 13 + 14 + sec=$(date +%s) 15 + rndh=$(printf %x $sec)-$(mktemp -u XXXXXX) 16 + ns1="ns1-$rndh" 17 + ns2="ns2-$rndh" 18 + ns_sbox="ns_sbox-$rndh" 14 19 15 20 add_mark_rules() 16 21 { 17 22 local ns=$1 18 23 local m=$2 19 24 25 + local t 20 26 for t in iptables ip6tables; do 21 27 # just to debug: check we have multiple subflows connection requests 22 28 ip netns exec $ns $t -A OUTPUT -p tcp --syn -m mark --mark $m -j ACCEPT ··· 37 31 38 32 init() 39 33 { 40 - rndh=$(printf %x $sec)-$(mktemp -u XXXXXX) 41 - 42 - ns1="ns1-$rndh" 43 - ns2="ns2-$rndh" 44 - ns_sbox="ns_sbox-$rndh" 45 - 34 + local netns 46 35 for netns in "$ns1" "$ns2" "$ns_sbox";do 47 36 ip netns add $netns || exit $ksft_skip 48 37 ip -net $netns link set lo up ··· 46 45 ip netns exec $netns sysctl -q net.ipv4.conf.default.rp_filter=0 47 46 done 48 47 48 + local i 49 49 for i in `seq 1 4`; do 50 50 ip link add ns1eth$i netns "$ns1" type veth peer name ns2eth$i netns "$ns2" 51 51 ip -net "$ns1" addr add 10.0.$i.1/24 dev ns1eth$i ··· 76 74 77 75 cleanup() 78 76 { 77 + local netns 79 78 for netns in "$ns1" "$ns2" "$ns_sbox"; do 80 79 ip netns del $netns 81 80 done ··· 107 104 local ns=$1 108 105 local af=$2 109 106 110 - tables=iptables 107 + local tables=iptables 111 108 112 109 if [ $af -eq 6 ];then 113 110 tables=ip6tables 114 111 fi 115 112 113 + local counters values 116 114 counters=$(ip netns exec $ns $tables -v -L OUTPUT | grep DROP) 117 115 values=${counters%DROP*} 118 116 117 + local v 119 118 for v in $values; do 120 119 if [ $v -ne 0 ]; then 121 120 echo "FAIL: got $tables $values in ns $ns , not 0 - not all expected packets marked" 1>&2 ··· 137 132 138 133 check_transfer() 139 134 { 140 - in=$1 141 - out=$2 142 - what=$3 135 + local in=$1 136 + local out=$2 137 + local what=$3 143 138 144 139 cmp "$in" "$out" > /dev/null 2>&1 145 140 if [ $? -ne 0 ] ;then ··· 162 157 163 158 do_transfer() 164 159 { 165 - listener_ns="$1" 166 - connector_ns="$2" 167 - cl_proto="$3" 168 - srv_proto="$4" 169 - connect_addr="$5" 160 + local listener_ns="$1" 161 + local connector_ns="$2" 162 + local cl_proto="$3" 163 + local srv_proto="$4" 164 + local connect_addr="$5" 170 165 171 - port=12001 166 + local port=12001 172 167 173 168 :> "$cout" 174 169 :> "$sout" 175 170 176 - mptcp_connect="./mptcp_connect -r 20" 171 + local mptcp_connect="./mptcp_connect -r 20" 177 172 178 173 local local_addr 179 174 if is_v6 "${connect_addr}"; then ··· 186 181 ip netns exec ${listener_ns} \ 187 182 $mptcp_connect -t ${timeout_poll} -l -M 1 -p $port -s ${srv_proto} -c TIMESTAMPNS,TCPINQ \ 188 183 ${local_addr} < "$sin" > "$sout" & 189 - spid=$! 184 + local spid=$! 190 185 191 186 sleep 1 192 187 ··· 195 190 $mptcp_connect -t ${timeout_poll} -M 2 -p $port -s ${cl_proto} -c TIMESTAMPNS,TCPINQ \ 196 191 $connect_addr < "$cin" > "$cout" & 197 192 198 - cpid=$! 193 + local cpid=$! 199 194 200 195 wait $cpid 201 - retc=$? 196 + local retc=$? 202 197 wait $spid 203 - rets=$? 198 + local rets=$? 204 199 205 200 if [ ${rets} -ne 0 ] || [ ${retc} -ne 0 ]; then 206 201 echo " client exit code $retc, server $rets" 1>&2 ··· 235 230 236 231 make_file() 237 232 { 238 - name=$1 239 - who=$2 240 - size=$3 233 + local name=$1 234 + local who=$2 235 + local size=$3 241 236 242 237 dd if=/dev/urandom of="$name" bs=1024 count=$size 2> /dev/null 243 238 echo -e "\nMPTCP_TEST_FILE_END_MARKER" >> "$name" ··· 270 265 271 266 run_tests() 272 267 { 273 - listener_ns="$1" 274 - connector_ns="$2" 275 - connect_addr="$3" 268 + local listener_ns="$1" 269 + local connector_ns="$2" 270 + local connect_addr="$3" 276 271 local lret=0 277 272 278 273 do_transfer ${listener_ns} ${connector_ns} MPTCP MPTCP ${connect_addr} ··· 287 282 288 283 do_tcpinq_test() 289 284 { 290 - ip netns exec "$ns1" ./mptcp_inq "$@" 291 - lret=$? 285 + ip netns exec "$ns_sbox" ./mptcp_inq "$@" 286 + local lret=$? 292 287 if [ $lret -ne 0 ];then 293 288 ret=$lret 294 289 echo "FAIL: mptcp_inq $@" 1>&2 ··· 303 298 { 304 299 local lret=0 305 300 306 - ip netns exec "$ns1" iptables -F 307 - ip netns exec "$ns1" ip6tables -F 308 - 301 + local args 309 302 for args in "-t tcp" "-r tcp"; do 310 303 do_tcpinq_test $args 311 304 lret=$?
+1 -3
tools/testing/selftests/net/mptcp/simult_flows.sh
··· 1 1 #!/bin/bash 2 2 # SPDX-License-Identifier: GPL-2.0 3 3 4 + sec=$(date +%s) 4 5 rndh=$(printf %x $sec)-$(mktemp -u XXXXXX) 5 6 ns1="ns1-$rndh" 6 7 ns2="ns2-$rndh" ··· 148 147 :> "$cout" 149 148 :> "$sout" 150 149 :> "$capout" 151 - 152 - local addr_port 153 - addr_port=$(printf "%s:%d" ${connect_addr} ${port}) 154 150 155 151 if $capture; then 156 152 local capuser
+174 -124
tools/testing/selftests/net/mptcp/userspace_pm.sh
··· 11 11 REMOVED=7 # MPTCP_EVENT_REMOVED 12 12 SUB_ESTABLISHED=10 # MPTCP_EVENT_SUB_ESTABLISHED 13 13 SUB_CLOSED=11 # MPTCP_EVENT_SUB_CLOSED 14 + LISTENER_CREATED=15 #MPTCP_EVENT_LISTENER_CREATED 15 + LISTENER_CLOSED=16 #MPTCP_EVENT_LISTENER_CLOSED 14 16 15 17 AF_INET=2 16 18 AF_INET6=10 17 19 18 - evts_pid=0 20 + file="" 21 + server_evts="" 22 + client_evts="" 23 + server_evts_pid=0 24 + client_evts_pid=0 19 25 client4_pid=0 20 26 server4_pid=0 21 27 client6_pid=0 ··· 39 33 server_addr_id=${RANDOM:0:2} 40 34 41 35 sec=$(date +%s) 42 - rndh=$(stdbuf -o0 -e0 printf %x "$sec")-$(mktemp -u XXXXXX) 36 + rndh=$(printf %x "$sec")-$(mktemp -u XXXXXX) 43 37 ns1="ns1-$rndh" 44 38 ns2="ns2-$rndh" 45 39 ··· 53 47 { 54 48 echo "cleanup" 55 49 56 - rm -rf $file 50 + rm -rf $file $client_evts $server_evts 57 51 58 52 # Terminate the MPTCP connection and related processes 59 53 if [ $client4_pid -ne 0 ]; then ··· 68 62 if [ $server6_pid -ne 0 ]; then 69 63 kill_wait $server6_pid 70 64 fi 71 - if [ $evts_pid -ne 0 ]; then 72 - kill_wait $evts_pid 65 + if [ $server_evts_pid -ne 0 ]; then 66 + kill_wait $server_evts_pid 67 + fi 68 + if [ $client_evts_pid -ne 0 ]; then 69 + kill_wait $client_evts_pid 73 70 fi 74 71 local netns 75 72 for netns in "$ns1" "$ns2" ;do ··· 122 113 123 114 make_connection() 124 115 { 125 - local file 126 - file=$(mktemp) 116 + if [ -z "$file" ]; then 117 + file=$(mktemp) 118 + fi 127 119 make_file "$file" "client" 128 120 129 121 local is_v6=$1 ··· 142 132 143 133 # Capture netlink events over the two network namespaces running 144 134 # the MPTCP client and server 145 - local client_evts 146 - client_evts=$(mktemp) 135 + if [ -z "$client_evts" ]; then 136 + client_evts=$(mktemp) 137 + fi 147 138 :>"$client_evts" 139 + if [ $client_evts_pid -ne 0 ]; then 140 + kill_wait $client_evts_pid 141 + fi 148 142 ip netns exec "$ns2" ./pm_nl_ctl events >> "$client_evts" 2>&1 & 149 - local client_evts_pid=$! 150 - local server_evts 151 - server_evts=$(mktemp) 143 + client_evts_pid=$! 144 + if [ -z "$server_evts" ]; then 145 + server_evts=$(mktemp) 146 + fi 152 147 :>"$server_evts" 148 + if [ $server_evts_pid -ne 0 ]; then 149 + kill_wait $server_evts_pid 150 + fi 153 151 ip netns exec "$ns1" ./pm_nl_ctl events >> "$server_evts" 2>&1 & 154 - local server_evts_pid=$! 152 + server_evts_pid=$! 155 153 sleep 0.5 156 154 157 155 # Run the server ··· 177 159 sleep 1 178 160 179 161 # Capture client/server attributes from MPTCP connection netlink events 180 - kill_wait $client_evts_pid 181 162 182 163 local client_token 183 164 local client_port ··· 188 171 client_port=$(sed --unbuffered -n 's/.*\(sport:\)\([[:digit:]]*\).*$/\2/p;q' "$client_evts") 189 172 client_serverside=$(sed --unbuffered -n 's/.*\(server_side:\)\([[:digit:]]*\).*$/\2/p;q'\ 190 173 "$client_evts") 191 - kill_wait $server_evts_pid 192 - server_token=$(sed --unbuffered -n 's/.*\(token:\)\([[:digit:]]*\).*$/\2/p;q' "$server_evts") 193 - server_serverside=$(sed --unbuffered -n 's/.*\(server_side:\)\([[:digit:]]*\).*$/\2/p;q'\ 194 - "$server_evts") 195 - rm -f "$client_evts" "$server_evts" "$file" 174 + server_token=$(grep "type:1," "$server_evts" | 175 + sed --unbuffered -n 's/.*\(token:\)\([[:digit:]]*\).*$/\2/p;q') 176 + server_serverside=$(grep "type:1," "$server_evts" | 177 + sed --unbuffered -n 's/.*\(server_side:\)\([[:digit:]]*\).*$/\2/p;q') 196 178 197 179 if [ "$client_token" != "" ] && [ "$server_token" != "" ] && [ "$client_serverside" = 0 ] && 198 180 [ "$server_serverside" = 1 ] ··· 255 239 256 240 test_announce() 257 241 { 258 - local evts 259 - evts=$(mktemp) 260 242 # Capture events on the network namespace running the server 261 - :>"$evts" 262 - ip netns exec "$ns1" ./pm_nl_ctl events >> "$evts" 2>&1 & 263 - evts_pid=$! 264 - sleep 0.5 243 + :>"$server_evts" 265 244 266 245 # ADD_ADDR using an invalid token should result in no action 267 246 local invalid_token=$(( client4_token - 1)) ··· 264 253 $client_addr_id dev ns2eth1 > /dev/null 2>&1 265 254 266 255 local type 267 - type=$(sed --unbuffered -n 's/.*\(type:\)\([[:digit:]]*\).*$/\2/p;q' "$evts") 256 + type=$(sed --unbuffered -n 's/.*\(type:\)\([[:digit:]]*\).*$/\2/p;q' "$server_evts") 268 257 stdbuf -o0 -e0 printf "ADD_ADDR 10.0.2.2 (ns2) => ns1, invalid token \t\t" 269 258 if [ "$type" = "" ] 270 259 then ··· 275 264 fi 276 265 277 266 # ADD_ADDR from the client to server machine reusing the subflow port 278 - :>"$evts" 267 + :>"$server_evts" 279 268 ip netns exec "$ns2"\ 280 269 ./pm_nl_ctl ann 10.0.2.2 token "$client4_token" id $client_addr_id dev\ 281 270 ns2eth1 > /dev/null 2>&1 282 271 stdbuf -o0 -e0 printf "ADD_ADDR id:%d 10.0.2.2 (ns2) => ns1, reuse port \t\t" $client_addr_id 283 272 sleep 0.5 284 - verify_announce_event "$evts" "$ANNOUNCED" "$server4_token" "10.0.2.2" "$client_addr_id"\ 273 + verify_announce_event $server_evts $ANNOUNCED $server4_token "10.0.2.2" $client_addr_id \ 285 274 "$client4_port" 286 275 287 276 # ADD_ADDR6 from the client to server machine reusing the subflow port 288 - :>"$evts" 277 + :>"$server_evts" 289 278 ip netns exec "$ns2" ./pm_nl_ctl ann\ 290 279 dead:beef:2::2 token "$client6_token" id $client_addr_id dev ns2eth1 > /dev/null 2>&1 291 280 stdbuf -o0 -e0 printf "ADD_ADDR6 id:%d dead:beef:2::2 (ns2) => ns1, reuse port\t\t" $client_addr_id 292 281 sleep 0.5 293 - verify_announce_event "$evts" "$ANNOUNCED" "$server6_token" "dead:beef:2::2"\ 282 + verify_announce_event "$server_evts" "$ANNOUNCED" "$server6_token" "dead:beef:2::2"\ 294 283 "$client_addr_id" "$client6_port" "v6" 295 284 296 285 # ADD_ADDR from the client to server machine using a new port 297 - :>"$evts" 286 + :>"$server_evts" 298 287 client_addr_id=$((client_addr_id+1)) 299 288 ip netns exec "$ns2" ./pm_nl_ctl ann 10.0.2.2 token "$client4_token" id\ 300 289 $client_addr_id dev ns2eth1 port $new4_port > /dev/null 2>&1 301 290 stdbuf -o0 -e0 printf "ADD_ADDR id:%d 10.0.2.2 (ns2) => ns1, new port \t\t\t" $client_addr_id 302 291 sleep 0.5 303 - verify_announce_event "$evts" "$ANNOUNCED" "$server4_token" "10.0.2.2"\ 292 + verify_announce_event "$server_evts" "$ANNOUNCED" "$server4_token" "10.0.2.2"\ 304 293 "$client_addr_id" "$new4_port" 305 294 306 - kill_wait $evts_pid 307 - 308 295 # Capture events on the network namespace running the client 309 - :>"$evts" 310 - ip netns exec "$ns2" ./pm_nl_ctl events >> "$evts" 2>&1 & 311 - evts_pid=$! 312 - sleep 0.5 296 + :>"$client_evts" 313 297 314 298 # ADD_ADDR from the server to client machine reusing the subflow port 315 299 ip netns exec "$ns1" ./pm_nl_ctl ann 10.0.2.1 token "$server4_token" id\ 316 300 $server_addr_id dev ns1eth2 > /dev/null 2>&1 317 301 stdbuf -o0 -e0 printf "ADD_ADDR id:%d 10.0.2.1 (ns1) => ns2, reuse port \t\t" $server_addr_id 318 302 sleep 0.5 319 - verify_announce_event "$evts" "$ANNOUNCED" "$client4_token" "10.0.2.1"\ 303 + verify_announce_event "$client_evts" "$ANNOUNCED" "$client4_token" "10.0.2.1"\ 320 304 "$server_addr_id" "$app4_port" 321 305 322 306 # ADD_ADDR6 from the server to client machine reusing the subflow port 323 - :>"$evts" 307 + :>"$client_evts" 324 308 ip netns exec "$ns1" ./pm_nl_ctl ann dead:beef:2::1 token "$server6_token" id\ 325 309 $server_addr_id dev ns1eth2 > /dev/null 2>&1 326 310 stdbuf -o0 -e0 printf "ADD_ADDR6 id:%d dead:beef:2::1 (ns1) => ns2, reuse port\t\t" $server_addr_id 327 311 sleep 0.5 328 - verify_announce_event "$evts" "$ANNOUNCED" "$client6_token" "dead:beef:2::1"\ 312 + verify_announce_event "$client_evts" "$ANNOUNCED" "$client6_token" "dead:beef:2::1"\ 329 313 "$server_addr_id" "$app6_port" "v6" 330 314 331 315 # ADD_ADDR from the server to client machine using a new port 332 - :>"$evts" 316 + :>"$client_evts" 333 317 server_addr_id=$((server_addr_id+1)) 334 318 ip netns exec "$ns1" ./pm_nl_ctl ann 10.0.2.1 token "$server4_token" id\ 335 319 $server_addr_id dev ns1eth2 port $new4_port > /dev/null 2>&1 336 320 stdbuf -o0 -e0 printf "ADD_ADDR id:%d 10.0.2.1 (ns1) => ns2, new port \t\t\t" $server_addr_id 337 321 sleep 0.5 338 - verify_announce_event "$evts" "$ANNOUNCED" "$client4_token" "10.0.2.1"\ 322 + verify_announce_event "$client_evts" "$ANNOUNCED" "$client4_token" "10.0.2.1"\ 339 323 "$server_addr_id" "$new4_port" 340 - 341 - kill_wait $evts_pid 342 - rm -f "$evts" 343 324 } 344 325 345 326 verify_remove_event() ··· 359 356 360 357 test_remove() 361 358 { 362 - local evts 363 - evts=$(mktemp) 364 - 365 359 # Capture events on the network namespace running the server 366 - :>"$evts" 367 - ip netns exec "$ns1" ./pm_nl_ctl events >> "$evts" 2>&1 & 368 - evts_pid=$! 369 - sleep 0.5 360 + :>"$server_evts" 370 361 371 362 # RM_ADDR using an invalid token should result in no action 372 363 local invalid_token=$(( client4_token - 1 )) ··· 369 372 stdbuf -o0 -e0 printf "RM_ADDR id:%d ns2 => ns1, invalid token \t"\ 370 373 $client_addr_id 371 374 local type 372 - type=$(sed --unbuffered -n 's/.*\(type:\)\([[:digit:]]*\).*$/\2/p;q' "$evts") 375 + type=$(sed --unbuffered -n 's/.*\(type:\)\([[:digit:]]*\).*$/\2/p;q' "$server_evts") 373 376 if [ "$type" = "" ] 374 377 then 375 378 stdbuf -o0 -e0 printf "[OK]\n" ··· 383 386 $invalid_id > /dev/null 2>&1 384 387 stdbuf -o0 -e0 printf "RM_ADDR id:%d ns2 => ns1, invalid id \t"\ 385 388 $invalid_id 386 - type=$(sed --unbuffered -n 's/.*\(type:\)\([[:digit:]]*\).*$/\2/p;q' "$evts") 389 + type=$(sed --unbuffered -n 's/.*\(type:\)\([[:digit:]]*\).*$/\2/p;q' "$server_evts") 387 390 if [ "$type" = "" ] 388 391 then 389 392 stdbuf -o0 -e0 printf "[OK]\n" ··· 392 395 fi 393 396 394 397 # RM_ADDR from the client to server machine 395 - :>"$evts" 398 + :>"$server_evts" 396 399 ip netns exec "$ns2" ./pm_nl_ctl rem token "$client4_token" id\ 397 400 $client_addr_id > /dev/null 2>&1 398 401 stdbuf -o0 -e0 printf "RM_ADDR id:%d ns2 => ns1 \t"\ 399 402 $client_addr_id 400 403 sleep 0.5 401 - verify_remove_event "$evts" "$REMOVED" "$server4_token" "$client_addr_id" 404 + verify_remove_event "$server_evts" "$REMOVED" "$server4_token" "$client_addr_id" 402 405 403 406 # RM_ADDR from the client to server machine 404 - :>"$evts" 407 + :>"$server_evts" 405 408 client_addr_id=$(( client_addr_id - 1 )) 406 409 ip netns exec "$ns2" ./pm_nl_ctl rem token "$client4_token" id\ 407 410 $client_addr_id > /dev/null 2>&1 408 411 stdbuf -o0 -e0 printf "RM_ADDR id:%d ns2 => ns1 \t"\ 409 412 $client_addr_id 410 413 sleep 0.5 411 - verify_remove_event "$evts" "$REMOVED" "$server4_token" "$client_addr_id" 414 + verify_remove_event "$server_evts" "$REMOVED" "$server4_token" "$client_addr_id" 412 415 413 416 # RM_ADDR6 from the client to server machine 414 - :>"$evts" 417 + :>"$server_evts" 415 418 ip netns exec "$ns2" ./pm_nl_ctl rem token "$client6_token" id\ 416 419 $client_addr_id > /dev/null 2>&1 417 420 stdbuf -o0 -e0 printf "RM_ADDR6 id:%d ns2 => ns1 \t"\ 418 421 $client_addr_id 419 422 sleep 0.5 420 - verify_remove_event "$evts" "$REMOVED" "$server6_token" "$client_addr_id" 421 - 422 - kill_wait $evts_pid 423 + verify_remove_event "$server_evts" "$REMOVED" "$server6_token" "$client_addr_id" 423 424 424 425 # Capture events on the network namespace running the client 425 - :>"$evts" 426 - ip netns exec "$ns2" ./pm_nl_ctl events >> "$evts" 2>&1 & 427 - evts_pid=$! 428 - sleep 0.5 426 + :>"$client_evts" 429 427 430 428 # RM_ADDR from the server to client machine 431 429 ip netns exec "$ns1" ./pm_nl_ctl rem token "$server4_token" id\ ··· 428 436 stdbuf -o0 -e0 printf "RM_ADDR id:%d ns1 => ns2 \t"\ 429 437 $server_addr_id 430 438 sleep 0.5 431 - verify_remove_event "$evts" "$REMOVED" "$client4_token" "$server_addr_id" 439 + verify_remove_event "$client_evts" "$REMOVED" "$client4_token" "$server_addr_id" 432 440 433 441 # RM_ADDR from the server to client machine 434 - :>"$evts" 442 + :>"$client_evts" 435 443 server_addr_id=$(( server_addr_id - 1 )) 436 444 ip netns exec "$ns1" ./pm_nl_ctl rem token "$server4_token" id\ 437 445 $server_addr_id > /dev/null 2>&1 438 446 stdbuf -o0 -e0 printf "RM_ADDR id:%d ns1 => ns2 \t" $server_addr_id 439 447 sleep 0.5 440 - verify_remove_event "$evts" "$REMOVED" "$client4_token" "$server_addr_id" 448 + verify_remove_event "$client_evts" "$REMOVED" "$client4_token" "$server_addr_id" 441 449 442 450 # RM_ADDR6 from the server to client machine 443 - :>"$evts" 451 + :>"$client_evts" 444 452 ip netns exec "$ns1" ./pm_nl_ctl rem token "$server6_token" id\ 445 453 $server_addr_id > /dev/null 2>&1 446 454 stdbuf -o0 -e0 printf "RM_ADDR6 id:%d ns1 => ns2 \t" $server_addr_id 447 455 sleep 0.5 448 - verify_remove_event "$evts" "$REMOVED" "$client6_token" "$server_addr_id" 449 - 450 - kill_wait $evts_pid 451 - rm -f "$evts" 456 + verify_remove_event "$client_evts" "$REMOVED" "$client6_token" "$server_addr_id" 452 457 } 453 458 454 459 verify_subflow_events() ··· 521 532 522 533 test_subflows() 523 534 { 524 - local evts 525 - evts=$(mktemp) 526 535 # Capture events on the network namespace running the server 527 - :>"$evts" 528 - ip netns exec "$ns1" ./pm_nl_ctl events >> "$evts" 2>&1 & 529 - evts_pid=$! 530 - sleep 0.5 536 + :>"$server_evts" 531 537 532 538 # Attempt to add a listener at 10.0.2.2:<subflow-port> 533 539 ip netns exec "$ns2" ./pm_nl_ctl listen 10.0.2.2\ ··· 535 551 sleep 0.5 536 552 537 553 # CREATE_SUBFLOW from server to client machine 538 - :>"$evts" 554 + :>"$server_evts" 539 555 ip netns exec "$ns1" ./pm_nl_ctl csf lip 10.0.2.1 lid 23 rip 10.0.2.2\ 540 556 rport "$client4_port" token "$server4_token" > /dev/null 2>&1 541 557 sleep 0.5 542 - verify_subflow_events "$evts" "$SUB_ESTABLISHED" "$server4_token" "$AF_INET" "10.0.2.1"\ 558 + verify_subflow_events $server_evts $SUB_ESTABLISHED $server4_token $AF_INET "10.0.2.1" \ 543 559 "10.0.2.2" "$client4_port" "23" "$client_addr_id" "ns1" "ns2" 544 560 545 561 # Delete the listener from the client ns, if one was created 546 562 kill_wait $listener_pid 547 563 548 564 local sport 549 - sport=$(sed --unbuffered -n 's/.*\(sport:\)\([[:digit:]]*\).*$/\2/p;q' "$evts") 565 + sport=$(sed --unbuffered -n 's/.*\(sport:\)\([[:digit:]]*\).*$/\2/p;q' "$server_evts") 550 566 551 567 # DESTROY_SUBFLOW from server to client machine 552 - :>"$evts" 568 + :>"$server_evts" 553 569 ip netns exec "$ns1" ./pm_nl_ctl dsf lip 10.0.2.1 lport "$sport" rip 10.0.2.2 rport\ 554 570 "$client4_port" token "$server4_token" > /dev/null 2>&1 555 571 sleep 0.5 556 - verify_subflow_events "$evts" "$SUB_CLOSED" "$server4_token" "$AF_INET" "10.0.2.1"\ 572 + verify_subflow_events "$server_evts" "$SUB_CLOSED" "$server4_token" "$AF_INET" "10.0.2.1"\ 557 573 "10.0.2.2" "$client4_port" "23" "$client_addr_id" "ns1" "ns2" 558 574 559 575 # RM_ADDR from client to server machine ··· 567 583 listener_pid=$! 568 584 569 585 # ADD_ADDR6 from client to server machine reusing the subflow port 570 - :>"$evts" 586 + :>"$server_evts" 571 587 ip netns exec "$ns2" ./pm_nl_ctl ann dead:beef:2::2 token "$client6_token" id\ 572 588 $client_addr_id > /dev/null 2>&1 573 589 sleep 0.5 574 590 575 591 # CREATE_SUBFLOW6 from server to client machine 576 - :>"$evts" 592 + :>"$server_evts" 577 593 ip netns exec "$ns1" ./pm_nl_ctl csf lip dead:beef:2::1 lid 23 rip\ 578 594 dead:beef:2::2 rport "$client6_port" token "$server6_token" > /dev/null 2>&1 579 595 sleep 0.5 580 - verify_subflow_events "$evts" "$SUB_ESTABLISHED" "$server6_token" "$AF_INET6"\ 596 + verify_subflow_events "$server_evts" "$SUB_ESTABLISHED" "$server6_token" "$AF_INET6"\ 581 597 "dead:beef:2::1" "dead:beef:2::2" "$client6_port" "23"\ 582 598 "$client_addr_id" "ns1" "ns2" 583 599 584 600 # Delete the listener from the client ns, if one was created 585 601 kill_wait $listener_pid 586 602 587 - sport=$(sed --unbuffered -n 's/.*\(sport:\)\([[:digit:]]*\).*$/\2/p;q' "$evts") 603 + sport=$(sed --unbuffered -n 's/.*\(sport:\)\([[:digit:]]*\).*$/\2/p;q' "$server_evts") 588 604 589 605 # DESTROY_SUBFLOW6 from server to client machine 590 - :>"$evts" 606 + :>"$server_evts" 591 607 ip netns exec "$ns1" ./pm_nl_ctl dsf lip dead:beef:2::1 lport "$sport" rip\ 592 608 dead:beef:2::2 rport "$client6_port" token "$server6_token" > /dev/null 2>&1 593 609 sleep 0.5 594 - verify_subflow_events "$evts" "$SUB_CLOSED" "$server6_token" "$AF_INET6"\ 610 + verify_subflow_events "$server_evts" "$SUB_CLOSED" "$server6_token" "$AF_INET6"\ 595 611 "dead:beef:2::1" "dead:beef:2::2" "$client6_port" "23"\ 596 612 "$client_addr_id" "ns1" "ns2" 597 613 ··· 606 622 listener_pid=$! 607 623 608 624 # ADD_ADDR from client to server machine using a new port 609 - :>"$evts" 625 + :>"$server_evts" 610 626 ip netns exec "$ns2" ./pm_nl_ctl ann 10.0.2.2 token "$client4_token" id\ 611 627 $client_addr_id port $new4_port > /dev/null 2>&1 612 628 sleep 0.5 613 629 614 630 # CREATE_SUBFLOW from server to client machine 615 - :>"$evts" 631 + :>"$server_evts" 616 632 ip netns exec "$ns1" ./pm_nl_ctl csf lip 10.0.2.1 lid 23 rip 10.0.2.2 rport\ 617 633 $new4_port token "$server4_token" > /dev/null 2>&1 618 634 sleep 0.5 619 - verify_subflow_events "$evts" "$SUB_ESTABLISHED" "$server4_token" "$AF_INET"\ 635 + verify_subflow_events "$server_evts" "$SUB_ESTABLISHED" "$server4_token" "$AF_INET"\ 620 636 "10.0.2.1" "10.0.2.2" "$new4_port" "23"\ 621 637 "$client_addr_id" "ns1" "ns2" 622 638 623 639 # Delete the listener from the client ns, if one was created 624 640 kill_wait $listener_pid 625 641 626 - sport=$(sed --unbuffered -n 's/.*\(sport:\)\([[:digit:]]*\).*$/\2/p;q' "$evts") 642 + sport=$(sed --unbuffered -n 's/.*\(sport:\)\([[:digit:]]*\).*$/\2/p;q' "$server_evts") 627 643 628 644 # DESTROY_SUBFLOW from server to client machine 629 - :>"$evts" 645 + :>"$server_evts" 630 646 ip netns exec "$ns1" ./pm_nl_ctl dsf lip 10.0.2.1 lport "$sport" rip 10.0.2.2 rport\ 631 647 $new4_port token "$server4_token" > /dev/null 2>&1 632 648 sleep 0.5 633 - verify_subflow_events "$evts" "$SUB_CLOSED" "$server4_token" "$AF_INET" "10.0.2.1"\ 649 + verify_subflow_events "$server_evts" "$SUB_CLOSED" "$server4_token" "$AF_INET" "10.0.2.1"\ 634 650 "10.0.2.2" "$new4_port" "23" "$client_addr_id" "ns1" "ns2" 635 651 636 652 # RM_ADDR from client to server machine 637 653 ip netns exec "$ns2" ./pm_nl_ctl rem id $client_addr_id token\ 638 654 "$client4_token" > /dev/null 2>&1 639 655 640 - kill_wait $evts_pid 641 - 642 656 # Capture events on the network namespace running the client 643 - :>"$evts" 644 - ip netns exec "$ns2" ./pm_nl_ctl events >> "$evts" 2>&1 & 645 - evts_pid=$! 646 - sleep 0.5 657 + :>"$client_evts" 647 658 648 659 # Attempt to add a listener at 10.0.2.1:<subflow-port> 649 660 ip netns exec "$ns1" ./pm_nl_ctl listen 10.0.2.1\ ··· 651 672 sleep 0.5 652 673 653 674 # CREATE_SUBFLOW from client to server machine 654 - :>"$evts" 675 + :>"$client_evts" 655 676 ip netns exec "$ns2" ./pm_nl_ctl csf lip 10.0.2.2 lid 23 rip 10.0.2.1 rport\ 656 677 $app4_port token "$client4_token" > /dev/null 2>&1 657 678 sleep 0.5 658 - verify_subflow_events "$evts" "$SUB_ESTABLISHED" "$client4_token" "$AF_INET" "10.0.2.2"\ 679 + verify_subflow_events $client_evts $SUB_ESTABLISHED $client4_token $AF_INET "10.0.2.2"\ 659 680 "10.0.2.1" "$app4_port" "23" "$server_addr_id" "ns2" "ns1" 660 681 661 682 # Delete the listener from the server ns, if one was created 662 683 kill_wait $listener_pid 663 684 664 - sport=$(sed --unbuffered -n 's/.*\(sport:\)\([[:digit:]]*\).*$/\2/p;q' "$evts") 685 + sport=$(sed --unbuffered -n 's/.*\(sport:\)\([[:digit:]]*\).*$/\2/p;q' "$client_evts") 665 686 666 687 # DESTROY_SUBFLOW from client to server machine 667 - :>"$evts" 688 + :>"$client_evts" 668 689 ip netns exec "$ns2" ./pm_nl_ctl dsf lip 10.0.2.2 lport "$sport" rip 10.0.2.1 rport\ 669 690 $app4_port token "$client4_token" > /dev/null 2>&1 670 691 sleep 0.5 671 - verify_subflow_events "$evts" "$SUB_CLOSED" "$client4_token" "$AF_INET" "10.0.2.2"\ 692 + verify_subflow_events "$client_evts" "$SUB_CLOSED" "$client4_token" "$AF_INET" "10.0.2.2"\ 672 693 "10.0.2.1" "$app4_port" "23" "$server_addr_id" "ns2" "ns1" 673 694 674 695 # RM_ADDR from server to client machine ··· 682 703 listener_pid=$! 683 704 684 705 # ADD_ADDR6 from server to client machine reusing the subflow port 685 - :>"$evts" 706 + :>"$client_evts" 686 707 ip netns exec "$ns1" ./pm_nl_ctl ann dead:beef:2::1 token "$server6_token" id\ 687 708 $server_addr_id > /dev/null 2>&1 688 709 sleep 0.5 689 710 690 711 # CREATE_SUBFLOW6 from client to server machine 691 - :>"$evts" 712 + :>"$client_evts" 692 713 ip netns exec "$ns2" ./pm_nl_ctl csf lip dead:beef:2::2 lid 23 rip\ 693 714 dead:beef:2::1 rport $app6_port token "$client6_token" > /dev/null 2>&1 694 715 sleep 0.5 695 - verify_subflow_events "$evts" "$SUB_ESTABLISHED" "$client6_token"\ 716 + verify_subflow_events "$client_evts" "$SUB_ESTABLISHED" "$client6_token"\ 696 717 "$AF_INET6" "dead:beef:2::2"\ 697 718 "dead:beef:2::1" "$app6_port" "23"\ 698 719 "$server_addr_id" "ns2" "ns1" ··· 700 721 # Delete the listener from the server ns, if one was created 701 722 kill_wait $listener_pid 702 723 703 - sport=$(sed --unbuffered -n 's/.*\(sport:\)\([[:digit:]]*\).*$/\2/p;q' "$evts") 724 + sport=$(sed --unbuffered -n 's/.*\(sport:\)\([[:digit:]]*\).*$/\2/p;q' "$client_evts") 704 725 705 726 # DESTROY_SUBFLOW6 from client to server machine 706 - :>"$evts" 727 + :>"$client_evts" 707 728 ip netns exec "$ns2" ./pm_nl_ctl dsf lip dead:beef:2::2 lport "$sport" rip\ 708 729 dead:beef:2::1 rport $app6_port token "$client6_token" > /dev/null 2>&1 709 730 sleep 0.5 710 - verify_subflow_events "$evts" "$SUB_CLOSED" "$client6_token" "$AF_INET6" "dead:beef:2::2"\ 731 + verify_subflow_events $client_evts $SUB_CLOSED $client6_token $AF_INET6 "dead:beef:2::2"\ 711 732 "dead:beef:2::1" "$app6_port" "23" "$server_addr_id" "ns2" "ns1" 712 733 713 734 # RM_ADDR6 from server to client machine ··· 721 742 listener_pid=$! 722 743 723 744 # ADD_ADDR from server to client machine using a new port 724 - :>"$evts" 745 + :>"$client_evts" 725 746 ip netns exec "$ns1" ./pm_nl_ctl ann 10.0.2.1 token "$server4_token" id\ 726 747 $server_addr_id port $new4_port > /dev/null 2>&1 727 748 sleep 0.5 728 749 729 750 # CREATE_SUBFLOW from client to server machine 730 - :>"$evts" 751 + :>"$client_evts" 731 752 ip netns exec "$ns2" ./pm_nl_ctl csf lip 10.0.2.2 lid 23 rip 10.0.2.1 rport\ 732 753 $new4_port token "$client4_token" > /dev/null 2>&1 733 754 sleep 0.5 734 - verify_subflow_events "$evts" "$SUB_ESTABLISHED" "$client4_token" "$AF_INET"\ 755 + verify_subflow_events "$client_evts" "$SUB_ESTABLISHED" "$client4_token" "$AF_INET"\ 735 756 "10.0.2.2" "10.0.2.1" "$new4_port" "23" "$server_addr_id" "ns2" "ns1" 736 757 737 758 # Delete the listener from the server ns, if one was created 738 759 kill_wait $listener_pid 739 760 740 - sport=$(sed --unbuffered -n 's/.*\(sport:\)\([[:digit:]]*\).*$/\2/p;q' "$evts") 761 + sport=$(sed --unbuffered -n 's/.*\(sport:\)\([[:digit:]]*\).*$/\2/p;q' "$client_evts") 741 762 742 763 # DESTROY_SUBFLOW from client to server machine 743 - :>"$evts" 764 + :>"$client_evts" 744 765 ip netns exec "$ns2" ./pm_nl_ctl dsf lip 10.0.2.2 lport "$sport" rip 10.0.2.1 rport\ 745 766 $new4_port token "$client4_token" > /dev/null 2>&1 746 767 sleep 0.5 747 - verify_subflow_events "$evts" "$SUB_CLOSED" "$client4_token" "$AF_INET" "10.0.2.2"\ 768 + verify_subflow_events "$client_evts" "$SUB_CLOSED" "$client4_token" "$AF_INET" "10.0.2.2"\ 748 769 "10.0.2.1" "$new4_port" "23" "$server_addr_id" "ns2" "ns1" 749 770 750 771 # RM_ADDR from server to client machine 751 772 ip netns exec "$ns1" ./pm_nl_ctl rem id $server_addr_id token\ 752 773 "$server4_token" > /dev/null 2>&1 753 - 754 - kill_wait $evts_pid 755 - rm -f "$evts" 756 774 } 757 775 758 776 test_prio() ··· 783 807 fi 784 808 } 785 809 810 + verify_listener_events() 811 + { 812 + local evt=$1 813 + local e_type=$2 814 + local e_family=$3 815 + local e_saddr=$4 816 + local e_sport=$5 817 + local type 818 + local family 819 + local saddr 820 + local sport 821 + 822 + if [ $e_type = $LISTENER_CREATED ]; then 823 + stdbuf -o0 -e0 printf "CREATE_LISTENER %s:%s\t\t\t\t\t"\ 824 + $e_saddr $e_sport 825 + elif [ $e_type = $LISTENER_CLOSED ]; then 826 + stdbuf -o0 -e0 printf "CLOSE_LISTENER %s:%s\t\t\t\t\t"\ 827 + $e_saddr $e_sport 828 + fi 829 + 830 + type=$(grep "type:$e_type," $evt | 831 + sed --unbuffered -n 's/.*\(type:\)\([[:digit:]]*\).*$/\2/p;q') 832 + family=$(grep "type:$e_type," $evt | 833 + sed --unbuffered -n 's/.*\(family:\)\([[:digit:]]*\).*$/\2/p;q') 834 + sport=$(grep "type:$e_type," $evt | 835 + sed --unbuffered -n 's/.*\(sport:\)\([[:digit:]]*\).*$/\2/p;q') 836 + if [ $family ] && [ $family = $AF_INET6 ]; then 837 + saddr=$(grep "type:$e_type," $evt | 838 + sed --unbuffered -n 's/.*\(saddr6:\)\([0-9a-f:.]*\).*$/\2/p;q') 839 + else 840 + saddr=$(grep "type:$e_type," $evt | 841 + sed --unbuffered -n 's/.*\(saddr4:\)\([0-9.]*\).*$/\2/p;q') 842 + fi 843 + 844 + if [ $type ] && [ $type = $e_type ] && 845 + [ $family ] && [ $family = $e_family ] && 846 + [ $saddr ] && [ $saddr = $e_saddr ] && 847 + [ $sport ] && [ $sport = $e_sport ]; then 848 + stdbuf -o0 -e0 printf "[OK]\n" 849 + return 0 850 + fi 851 + stdbuf -o0 -e0 printf "[FAIL]\n" 852 + exit 1 853 + } 854 + 855 + test_listener() 856 + { 857 + # Capture events on the network namespace running the client 858 + :>$client_evts 859 + 860 + # Attempt to add a listener at 10.0.2.2:<subflow-port> 861 + ip netns exec $ns2 ./pm_nl_ctl listen 10.0.2.2\ 862 + $client4_port > /dev/null 2>&1 & 863 + local listener_pid=$! 864 + 865 + verify_listener_events $client_evts $LISTENER_CREATED $AF_INET 10.0.2.2 $client4_port 866 + 867 + # ADD_ADDR from client to server machine reusing the subflow port 868 + ip netns exec $ns2 ./pm_nl_ctl ann 10.0.2.2 token $client4_token id\ 869 + $client_addr_id > /dev/null 2>&1 870 + sleep 0.5 871 + 872 + # CREATE_SUBFLOW from server to client machine 873 + ip netns exec $ns1 ./pm_nl_ctl csf lip 10.0.2.1 lid 23 rip 10.0.2.2\ 874 + rport $client4_port token $server4_token > /dev/null 2>&1 875 + sleep 0.5 876 + 877 + # Delete the listener from the client ns, if one was created 878 + kill_wait $listener_pid 879 + 880 + verify_listener_events $client_evts $LISTENER_CLOSED $AF_INET 10.0.2.2 $client4_port 881 + } 882 + 786 883 make_connection 787 884 make_connection "v6" 788 885 test_announce 789 886 test_remove 790 887 test_subflows 791 888 test_prio 889 + test_listener 792 890 793 891 exit 0