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