xref: /linux/tools/testing/selftests/net/mptcp/pm_netlink.sh (revision fcee7d82f27d6a8b1ddc5bbefda59b4e441e9bc0)
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4. "$(dirname "${0}")/mptcp_lib.sh"
5
6ret=0
7
8usage() {
9	echo "Usage: $0 [ -i ] [ -h ]"
10	echo -e "\t-i: use 'ip mptcp' instead of 'pm_nl_ctl'"
11	echo -e "\t-h: help"
12}
13
14optstring=hi
15while getopts "$optstring" option;do
16	case "$option" in
17	"h")
18		usage "$0"
19		exit ${KSFT_PASS}
20		;;
21	"i")
22		mptcp_lib_set_ip_mptcp
23		;;
24	"?")
25		usage "$0"
26		exit ${KSFT_FAIL}
27		;;
28	esac
29done
30
31ns1=""
32err=$(mktemp)
33
34# This function is used in the cleanup trap
35#shellcheck disable=SC2317,SC2329
36cleanup()
37{
38	rm -f "${err}"
39	mptcp_lib_ns_exit "${ns1}"
40}
41
42mptcp_lib_check_mptcp
43mptcp_lib_check_tools ip
44
45trap cleanup EXIT
46
47mptcp_lib_ns_init ns1
48
49format_limits() {
50	local accept="${1}"
51	local subflows="${2}"
52
53	if mptcp_lib_is_ip_mptcp; then
54		# with a space at the end
55		printf "add_addr_accepted %d subflows %d \n" "${accept}" "${subflows}"
56	else
57		printf "accept %d\nsubflows %d\n" "${accept}" "${subflows}"
58	fi
59}
60
61get_limits() {
62	if mptcp_lib_is_ip_mptcp; then
63		ip -n "${ns1}" mptcp limits
64	else
65		ip netns exec "${ns1}" ./pm_nl_ctl limits
66	fi
67}
68
69format_endpoints() {
70	mptcp_lib_pm_nl_format_endpoints "${@}"
71}
72
73# This function is invoked indirectly
74#shellcheck disable=SC2317,SC2329
75get_endpoint() {
76	mptcp_lib_pm_nl_get_endpoint "${ns1}" "${@}"
77}
78
79change_address() {
80	local addr=${1}
81	local flags=${2}
82
83	if mptcp_lib_is_ip_mptcp; then
84		ip -n "${ns1}" mptcp endpoint change "${addr}" "${flags}"
85	else
86		ip netns exec "${ns1}" ./pm_nl_ctl set "${addr}" flags "${flags}"
87	fi
88}
89
90set_limits()
91{
92	mptcp_lib_pm_nl_set_limits "${ns1}" "${@}"
93}
94
95add_endpoint()
96{
97	mptcp_lib_pm_nl_add_endpoint "${ns1}" "${@}"
98}
99
100del_endpoint()
101{
102	mptcp_lib_pm_nl_del_endpoint "${ns1}" "${@}"
103}
104
105flush_endpoint()
106{
107	mptcp_lib_pm_nl_flush_endpoint "${ns1}"
108}
109
110show_endpoints()
111{
112	mptcp_lib_pm_nl_show_endpoints "${ns1}"
113}
114
115change_endpoint()
116{
117	mptcp_lib_pm_nl_change_endpoint "${ns1}" "${@}"
118}
119
120check()
121{
122	local cmd="$1"
123	local expected="$2"
124	local msg="$3"
125	local exp_error="$4"
126	local rc=0
127
128	mptcp_lib_print_title "$msg"
129	mptcp_lib_check_output "${err}" "${cmd}" "${expected}" "${exp_error}" ||
130		rc=${?}
131	if [ ${rc} -eq 2 ]; then
132		mptcp_lib_result_fail "${msg} # error ${rc}"
133		ret=${KSFT_FAIL}
134	elif [ ${rc} -eq 0 ]; then
135		mptcp_lib_print_ok "[ OK ]"
136		mptcp_lib_result_pass "${msg}"
137	elif [ ${rc} -eq 1 ]; then
138		mptcp_lib_result_fail "${msg} # different output"
139		ret=${KSFT_FAIL}
140	fi
141}
142
143mptcp_lib_subtests_last_ts_reset
144
145check "show_endpoints" "" "defaults addr list"
146
147default_limits="$(get_limits)"
148if mptcp_lib_expect_all_features; then
149	check "get_limits" "$(format_limits 0 2)" "defaults limits"
150fi
151
152add_endpoint 10.0.1.1
153add_endpoint 10.0.1.2 flags subflow dev lo
154add_endpoint 10.0.1.3 flags signal,backup
155check "get_endpoint 1" "$(format_endpoints "1,10.0.1.1")" "simple add/get addr"
156
157check "show_endpoints" \
158	"$(format_endpoints "1,10.0.1.1" \
159			    "2,10.0.1.2,subflow,lo" \
160			    "3,10.0.1.3,signal backup")" "dump addrs"
161
162del_endpoint 2
163check "get_endpoint 2" "" "simple del addr" 1
164check "show_endpoints" \
165	"$(format_endpoints "1,10.0.1.1" \
166			    "3,10.0.1.3,signal backup")" "dump addrs after del"
167
168add_endpoint 10.0.1.3 2>/dev/null
169check "get_endpoint 4" "" "duplicate addr" 1
170
171add_endpoint 10.0.1.4 flags signal
172check "get_endpoint 4" "$(format_endpoints "4,10.0.1.4,signal")" "id addr increment"
173
174for i in $(seq 5 9); do
175	add_endpoint "10.0.1.${i}" flags signal >/dev/null 2>&1
176done
177check "get_endpoint 9" "$(format_endpoints "9,10.0.1.9,signal")" "hard addr limit"
178check "get_endpoint 10" "" "above hard addr limit" 1
179
180del_endpoint 9
181for i in $(seq 10 255); do
182	add_endpoint 10.0.0.9 id "${i}"
183	del_endpoint "${i}"
184done
185check "show_endpoints" \
186	"$(format_endpoints "1,10.0.1.1" \
187			    "3,10.0.1.3,signal backup" \
188			    "4,10.0.1.4,signal" \
189			    "5,10.0.1.5,signal" \
190			    "6,10.0.1.6,signal" \
191			    "7,10.0.1.7,signal" \
192			    "8,10.0.1.8,signal")" "id limit"
193
194flush_endpoint
195check "show_endpoints" "" "flush addrs"
196
197# "unknown" flag is only supported by pm_nl_ctl
198if ! mptcp_lib_is_ip_mptcp; then
199	add_endpoint 10.0.1.1 flags unknown
200	check "show_endpoints" "$(format_endpoints "1,10.0.1.1")" \
201	      "ignore unknown flags"
202	flush_endpoint
203fi
204
205set_limits 9 1 2>/dev/null
206check "get_limits" "${default_limits}" "rcv addrs above hard limit"
207
208set_limits 1 9 2>/dev/null
209check "get_limits" "${default_limits}" "subflows above hard limit"
210
211set_limits 8 8
212flush_endpoint  ## to make sure it doesn't affect the limits
213check "get_limits" "$(format_limits 8 8)" "set limits"
214
215flush_endpoint
216add_endpoint 10.0.1.1
217add_endpoint 10.0.1.2
218add_endpoint 10.0.1.3 id 100
219add_endpoint 10.0.1.4
220add_endpoint 10.0.1.5 id 254
221add_endpoint 10.0.1.6
222add_endpoint 10.0.1.7
223add_endpoint 10.0.1.8
224check "show_endpoints" \
225	"$(format_endpoints "1,10.0.1.1" \
226			    "2,10.0.1.2" \
227			    "3,10.0.1.7" \
228			    "4,10.0.1.8" \
229			    "100,10.0.1.3" \
230			    "101,10.0.1.4" \
231			    "254,10.0.1.5" \
232			    "255,10.0.1.6")" "set ids"
233
234flush_endpoint
235add_endpoint 10.0.0.1
236add_endpoint 10.0.0.2 id 254
237add_endpoint 10.0.0.3
238add_endpoint 10.0.0.4
239add_endpoint 10.0.0.5 id 253
240add_endpoint 10.0.0.6
241add_endpoint 10.0.0.7
242add_endpoint 10.0.0.8
243check "show_endpoints" \
244	"$(format_endpoints "1,10.0.0.1" \
245			    "2,10.0.0.4" \
246			    "3,10.0.0.6" \
247			    "4,10.0.0.7" \
248			    "5,10.0.0.8" \
249			    "253,10.0.0.5" \
250			    "254,10.0.0.2" \
251			    "255,10.0.0.3")" "wrap-around ids"
252
253flush_endpoint
254add_endpoint 10.0.1.1 flags subflow
255change_address 10.0.1.1 backup
256check "show_endpoints" "$(format_endpoints "1,10.0.1.1,subflow backup")" \
257	"set flags (backup)"
258change_address 10.0.1.1 nobackup
259check "show_endpoints" "$(format_endpoints "1,10.0.1.1,subflow")" \
260	"          (nobackup)"
261
262# fullmesh support has been added later
263change_endpoint 1 fullmesh 2>/dev/null
264if show_endpoints | grep -q "fullmesh" ||
265   mptcp_lib_expect_all_features; then
266	check "show_endpoints" "$(format_endpoints "1,10.0.1.1,subflow fullmesh")" \
267		"          (fullmesh)"
268	change_endpoint 1 nofullmesh
269	check "show_endpoints" "$(format_endpoints "1,10.0.1.1,subflow")" \
270		"          (nofullmesh)"
271	change_endpoint 1 backup,fullmesh
272	check "show_endpoints" "$(format_endpoints "1,10.0.1.1,subflow backup fullmesh")" \
273		"          (backup,fullmesh)"
274else
275	for st in fullmesh nofullmesh backup,fullmesh; do
276		st="          (${st})"
277		mptcp_lib_print_title "${st}"
278		mptcp_lib_pr_skip
279		mptcp_lib_result_skip "${st}"
280	done
281fi
282
283mptcp_lib_result_print_all_tap
284exit $ret
285