xref: /linux/tools/testing/selftests/net/vrf_strict_mode_test.sh (revision 0e59523b440c90ed1899476f32ad4e949282f43e)
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4# This test is designed for testing the new VRF strict_mode functionality.
5
6source lib.sh
7ret=0
8
9# identifies the "init" network namespace which is often called root network
10# namespace.
11INIT_NETNS_NAME="init"
12
13PAUSE_ON_FAIL=${PAUSE_ON_FAIL:=no}
14
15TESTS="init testns mix"
16
17log_test()
18{
19	log_test_expected "$1" "$2" "$3"
20}
21
22print_log_test_results()
23{
24	if [ "$TESTS" != "none" ]; then
25		printf "\nTests passed: %3d\n" ${nsuccess}
26		printf "Tests failed: %3d\n"   ${nfail}
27	fi
28}
29
30log_section()
31{
32	echo
33	echo "################################################################################"
34	echo "TEST SECTION: $*"
35	echo "################################################################################"
36}
37
38ip_expand_args()
39{
40	local nsname=$1
41	local nsarg=""
42
43	if [ "${nsname}" != "${INIT_NETNS_NAME}" ]; then
44		nsarg="-netns ${nsname}"
45	fi
46
47	echo "${nsarg}"
48}
49
50vrf_count()
51{
52	local nsname=$1
53	local nsarg="$(ip_expand_args ${nsname})"
54
55	ip ${nsarg} -o link show type vrf | wc -l
56}
57
58count_vrf_by_table_id()
59{
60	local nsname=$1
61	local tableid=$2
62	local nsarg="$(ip_expand_args ${nsname})"
63
64	ip ${nsarg} -d -o link show type vrf | grep "table ${tableid}" | wc -l
65}
66
67add_vrf()
68{
69	local nsname=$1
70	local vrfname=$2
71	local vrftable=$3
72	local nsarg="$(ip_expand_args ${nsname})"
73
74	ip ${nsarg} link add ${vrfname} type vrf table ${vrftable} &>/dev/null
75}
76
77add_vrf_and_check()
78{
79	local nsname=$1
80	local vrfname=$2
81	local vrftable=$3
82	local cnt
83	local rc
84
85	add_vrf ${nsname} ${vrfname} ${vrftable}; rc=$?
86
87	cnt=$(count_vrf_by_table_id ${nsname} ${vrftable})
88
89	log_test ${rc} 0 "${nsname}: add vrf ${vrfname}, ${cnt} vrfs for table ${vrftable}"
90}
91
92add_vrf_and_check_fail()
93{
94	local nsname=$1
95	local vrfname=$2
96	local vrftable=$3
97	local cnt
98	local rc
99
100	add_vrf ${nsname} ${vrfname} ${vrftable}; rc=$?
101
102	cnt=$(count_vrf_by_table_id ${nsname} ${vrftable})
103
104	log_test ${rc} 2 "${nsname}: CANNOT add vrf ${vrfname}, ${cnt} vrfs for table ${vrftable}"
105}
106
107del_vrf_and_check()
108{
109	local nsname=$1
110	local vrfname=$2
111	local nsarg="$(ip_expand_args ${nsname})"
112
113	ip ${nsarg} link del ${vrfname}
114	log_test $? 0 "${nsname}: remove vrf ${vrfname}"
115}
116
117config_vrf_and_check()
118{
119	local nsname=$1
120	local addr=$2
121	local vrfname=$3
122	local nsarg="$(ip_expand_args ${nsname})"
123
124	ip ${nsarg} link set dev ${vrfname} up && \
125		ip ${nsarg} addr add ${addr} dev ${vrfname}
126	log_test $? 0 "${nsname}: vrf ${vrfname} up, addr ${addr}"
127}
128
129read_strict_mode()
130{
131	local nsname=$1
132	local rval
133	local rc=0
134	local nsexec=""
135
136	if [ "${nsname}" != "${INIT_NETNS_NAME}" ]; then
137		# a custom network namespace is provided
138		nsexec="ip netns exec ${nsname}"
139	fi
140
141	rval="$(${nsexec} bash -c "cat /proc/sys/net/vrf/strict_mode" | \
142		grep -E "^[0-1]$")" &> /dev/null
143	if [ $? -ne 0 ]; then
144		# set errors
145		rval=255
146		rc=1
147	fi
148
149	# on success, rval can be only 0 or 1; on error, rval is equal to 255
150	echo ${rval}
151	return ${rc}
152}
153
154read_strict_mode_compare_and_check()
155{
156	local nsname=$1
157	local expected=$2
158	local res
159
160	res="$(read_strict_mode ${nsname})"
161	log_test ${res} ${expected} "${nsname}: check strict_mode=${res}"
162}
163
164set_strict_mode()
165{
166	local nsname=$1
167	local val=$2
168	local nsexec=""
169
170	if [ "${nsname}" != "${INIT_NETNS_NAME}" ]; then
171		# a custom network namespace is provided
172		nsexec="ip netns exec ${nsname}"
173	fi
174
175	${nsexec} bash -c "echo ${val} >/proc/sys/net/vrf/strict_mode" &>/dev/null
176}
177
178enable_strict_mode()
179{
180	local nsname=$1
181
182	set_strict_mode ${nsname} 1
183}
184
185disable_strict_mode()
186{
187	local nsname=$1
188
189	set_strict_mode ${nsname} 0
190}
191
192disable_strict_mode_and_check()
193{
194	local nsname=$1
195
196	disable_strict_mode ${nsname}
197	log_test $? 0 "${nsname}: disable strict_mode (=0)"
198}
199
200enable_strict_mode_and_check()
201{
202	local nsname=$1
203
204	enable_strict_mode ${nsname}
205	log_test $? 0 "${nsname}: enable strict_mode (=1)"
206}
207
208enable_strict_mode_and_check_fail()
209{
210	local nsname=$1
211
212	enable_strict_mode ${nsname}
213	log_test $? 1 "${nsname}: CANNOT enable strict_mode"
214}
215
216strict_mode_check_default()
217{
218	local nsname=$1
219	local strictmode
220	local vrfcnt
221
222	vrfcnt=$(vrf_count ${nsname})
223	strictmode=$(read_strict_mode ${nsname})
224	log_test ${strictmode} 0 "${nsname}: strict_mode=0 by default, ${vrfcnt} vrfs"
225}
226
227setup()
228{
229	modprobe vrf
230
231	setup_ns testns
232}
233
234cleanup()
235{
236	ip netns del $testns 2>/dev/null
237
238	ip link del vrf100 2>/dev/null
239	ip link del vrf101 2>/dev/null
240	ip link del vrf102 2>/dev/null
241
242	echo 0 >/proc/sys/net/vrf/strict_mode 2>/dev/null
243}
244
245vrf_strict_mode_tests_init()
246{
247	log_section "VRF strict_mode test on init network namespace"
248
249	vrf_strict_mode_check_support init
250
251	strict_mode_check_default init
252
253	add_vrf_and_check init vrf100 100
254	config_vrf_and_check init 172.16.100.1/24 vrf100
255
256	enable_strict_mode_and_check init
257
258	add_vrf_and_check_fail init vrf101 100
259
260	disable_strict_mode_and_check init
261
262	add_vrf_and_check init vrf101 100
263	config_vrf_and_check init 172.16.101.1/24 vrf101
264
265	enable_strict_mode_and_check_fail init
266
267	del_vrf_and_check init vrf101
268
269	enable_strict_mode_and_check init
270
271	add_vrf_and_check init vrf102 102
272	config_vrf_and_check init 172.16.102.1/24 vrf102
273
274	# the strict_modle is enabled in the init
275}
276
277vrf_strict_mode_tests_testns()
278{
279	log_section "VRF strict_mode test on testns network namespace"
280
281	vrf_strict_mode_check_support $testns
282
283	strict_mode_check_default $testns
284
285	enable_strict_mode_and_check $testns
286
287	add_vrf_and_check $testns vrf100 100
288	config_vrf_and_check $testns 10.0.100.1/24 vrf100
289
290	add_vrf_and_check_fail $testns vrf101 100
291
292	add_vrf_and_check_fail $testns vrf102 100
293
294	add_vrf_and_check $testns vrf200 200
295
296	disable_strict_mode_and_check $testns
297
298	add_vrf_and_check $testns vrf101 100
299
300	add_vrf_and_check $testns vrf102 100
301
302	#the strict_mode is disabled in the $testns
303}
304
305vrf_strict_mode_tests_mix()
306{
307	log_section "VRF strict_mode test mixing init and testns network namespaces"
308
309	read_strict_mode_compare_and_check init 1
310
311	read_strict_mode_compare_and_check $testns 0
312
313	del_vrf_and_check $testns vrf101
314
315	del_vrf_and_check $testns vrf102
316
317	disable_strict_mode_and_check init
318
319	enable_strict_mode_and_check $testns
320
321	enable_strict_mode_and_check init
322	enable_strict_mode_and_check init
323
324	disable_strict_mode_and_check $testns
325	disable_strict_mode_and_check $testns
326
327	read_strict_mode_compare_and_check init 1
328
329	read_strict_mode_compare_and_check $testns 0
330}
331
332################################################################################
333# usage
334
335usage()
336{
337	cat <<EOF
338usage: ${0##*/} OPTS
339
340	-t <test>	Test(s) to run (default: all)
341			(options: $TESTS)
342EOF
343}
344
345################################################################################
346# main
347
348while getopts ":t:h" opt; do
349	case $opt in
350		t) TESTS=$OPTARG;;
351		h) usage; exit 0;;
352		*) usage; exit 1;;
353	esac
354done
355
356vrf_strict_mode_check_support()
357{
358	local nsname=$1
359	local output
360	local rc
361
362	output="$(lsmod | grep '^vrf' | awk '{print $1}')"
363	if [ -z "${output}" ]; then
364		modinfo vrf || return $?
365	fi
366
367	# we do not care about the value of the strict_mode; we only check if
368	# the strict_mode parameter is available or not.
369	read_strict_mode ${nsname} &>/dev/null; rc=$?
370	log_test ${rc} 0 "${nsname}: net.vrf.strict_mode is available"
371
372	return ${rc}
373}
374
375if [ "$(id -u)" -ne 0 ];then
376	echo "SKIP: Need root privileges"
377	exit $ksft_skip
378fi
379
380if [ ! -x "$(command -v ip)" ]; then
381	echo "SKIP: Could not run test without ip tool"
382	exit $ksft_skip
383fi
384
385modprobe vrf &>/dev/null
386if [ ! -e /proc/sys/net/vrf/strict_mode ]; then
387	echo "SKIP: vrf sysctl does not exist"
388	exit $ksft_skip
389fi
390
391cleanup &> /dev/null
392
393setup
394for t in $TESTS
395do
396	case $t in
397	vrf_strict_mode_tests_init|init) vrf_strict_mode_tests_init;;
398	vrf_strict_mode_tests_testns|testns) vrf_strict_mode_tests_testns;;
399	vrf_strict_mode_tests_mix|mix) vrf_strict_mode_tests_mix;;
400
401	help) echo "Test names: $TESTS"; exit 0;;
402
403	esac
404done
405cleanup
406
407print_log_test_results
408
409exit $ret
410