cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

userspace_pm.sh (26094B)


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