xref: /openbmc/linux/tools/testing/selftests/net/rtnetlink.sh (revision 28efb0046512e8a13ed9f9bdf0d68d10bbfbe9cf)
1#!/bin/sh
2#
3# This test is for checking rtnetlink callpaths, and get as much coverage as possible.
4#
5# set -e
6
7devdummy="test-dummy0"
8ret=0
9
10# set global exit status, but never reset nonzero one.
11check_err()
12{
13	if [ $ret -eq 0 ]; then
14		ret=$1
15	fi
16}
17
18# same but inverted -- used when command must fail for test to pass
19check_fail()
20{
21	if [ $1 -eq 0 ]; then
22		ret=1
23	fi
24}
25
26kci_add_dummy()
27{
28	ip link add name "$devdummy" type dummy
29	check_err $?
30	ip link set "$devdummy" up
31	check_err $?
32}
33
34kci_del_dummy()
35{
36	ip link del dev "$devdummy"
37	check_err $?
38}
39
40# add a bridge with vlans on top
41kci_test_bridge()
42{
43	devbr="test-br0"
44	vlandev="testbr-vlan1"
45
46	ret=0
47	ip link add name "$devbr" type bridge
48	check_err $?
49
50	ip link set dev "$devdummy" master "$devbr"
51	check_err $?
52
53	ip link set "$devbr" up
54	check_err $?
55
56	ip link add link "$devbr" name "$vlandev" type vlan id 1
57	check_err $?
58	ip addr add dev "$vlandev" 10.200.7.23/30
59	check_err $?
60	ip -6 addr add dev "$vlandev" dead:42::1234/64
61	check_err $?
62	ip -d link > /dev/null
63	check_err $?
64	ip r s t all > /dev/null
65	check_err $?
66	ip -6 addr del dev "$vlandev" dead:42::1234/64
67	check_err $?
68
69	ip link del dev "$vlandev"
70	check_err $?
71	ip link del dev "$devbr"
72	check_err $?
73
74	if [ $ret -ne 0 ];then
75		echo "FAIL: bridge setup"
76		return 1
77	fi
78	echo "PASS: bridge setup"
79
80}
81
82kci_test_gre()
83{
84	gredev=neta
85	rem=10.42.42.1
86	loc=10.0.0.1
87
88	ret=0
89	ip tunnel add $gredev mode gre remote $rem local $loc ttl 1
90	check_err $?
91	ip link set $gredev up
92	check_err $?
93	ip addr add 10.23.7.10 dev $gredev
94	check_err $?
95	ip route add 10.23.8.0/30 dev $gredev
96	check_err $?
97	ip addr add dev "$devdummy" 10.23.7.11/24
98	check_err $?
99	ip link > /dev/null
100	check_err $?
101	ip addr > /dev/null
102	check_err $?
103	ip addr del dev "$devdummy" 10.23.7.11/24
104	check_err $?
105
106	ip link del $gredev
107	check_err $?
108
109	if [ $ret -ne 0 ];then
110		echo "FAIL: gre tunnel endpoint"
111		return 1
112	fi
113	echo "PASS: gre tunnel endpoint"
114}
115
116# tc uses rtnetlink too, for full tc testing
117# please see tools/testing/selftests/tc-testing.
118kci_test_tc()
119{
120	dev=lo
121	ret=0
122
123	tc qdisc add dev "$dev" root handle 1: htb
124	check_err $?
125	tc class add dev "$dev" parent 1: classid 1:10 htb rate 1mbit
126	check_err $?
127	tc filter add dev "$dev" parent 1:0 prio 5 handle ffe: protocol ip u32 divisor 256
128	check_err $?
129	tc filter add dev "$dev" parent 1:0 prio 5 handle ffd: protocol ip u32 divisor 256
130	check_err $?
131	tc filter add dev "$dev" parent 1:0 prio 5 handle ffc: protocol ip u32 divisor 256
132	check_err $?
133	tc filter add dev "$dev" protocol ip parent 1: prio 5 handle ffe:2:3 u32 ht ffe:2: match ip src 10.0.0.3 flowid 1:10
134	check_err $?
135	tc filter add dev "$dev" protocol ip parent 1: prio 5 handle ffe:2:2 u32 ht ffe:2: match ip src 10.0.0.2 flowid 1:10
136	check_err $?
137	tc filter show dev "$dev" parent  1:0 > /dev/null
138	check_err $?
139	tc filter del dev "$dev" protocol ip parent 1: prio 5 handle ffe:2:3 u32
140	check_err $?
141	tc filter show dev "$dev" parent  1:0 > /dev/null
142	check_err $?
143	tc qdisc del dev "$dev" root handle 1: htb
144	check_err $?
145
146	if [ $ret -ne 0 ];then
147		echo "FAIL: tc htb hierarchy"
148		return 1
149	fi
150	echo "PASS: tc htb hierarchy"
151
152}
153
154kci_test_polrouting()
155{
156	ret=0
157	ip rule add fwmark 1 lookup 100
158	check_err $?
159	ip route add local 0.0.0.0/0 dev lo table 100
160	check_err $?
161	ip r s t all > /dev/null
162	check_err $?
163	ip rule del fwmark 1 lookup 100
164	check_err $?
165	ip route del local 0.0.0.0/0 dev lo table 100
166	check_err $?
167
168	if [ $ret -ne 0 ];then
169		echo "FAIL: policy route test"
170		return 1
171	fi
172	echo "PASS: policy routing"
173}
174
175kci_test_route_get()
176{
177	ret=0
178
179	ip route get 127.0.0.1 > /dev/null
180	check_err $?
181	ip route get 127.0.0.1 dev "$devdummy" > /dev/null
182	check_err $?
183	ip route get ::1 > /dev/null
184	check_err $?
185	ip route get fe80::1 dev "$devdummy" > /dev/null
186	check_err $?
187	ip route get 127.0.0.1 from 127.0.0.1 oif lo tos 0x1 mark 0x1 > /dev/null
188	check_err $?
189	ip route get ::1 from ::1 iif lo oif lo tos 0x1 mark 0x1 > /dev/null
190	check_err $?
191	ip addr add dev "$devdummy" 10.23.7.11/24
192	check_err $?
193	ip route get 10.23.7.11 from 10.23.7.12 iif "$devdummy" > /dev/null
194	check_err $?
195	ip addr del dev "$devdummy" 10.23.7.11/24
196	check_err $?
197
198	if [ $ret -ne 0 ];then
199		echo "FAIL: route get"
200		return 1
201	fi
202
203	echo "PASS: route get"
204}
205
206kci_test_addrlabel()
207{
208	ret=0
209
210	ip addrlabel add prefix dead::/64 dev lo label 1
211	check_err $?
212
213	ip addrlabel list |grep -q "prefix dead::/64 dev lo label 1"
214	check_err $?
215
216	ip addrlabel del prefix dead::/64 dev lo label 1 2> /dev/null
217	check_err $?
218
219	ip addrlabel add prefix dead::/64 label 1 2> /dev/null
220	check_err $?
221
222	ip addrlabel del prefix dead::/64 label 1 2> /dev/null
223	check_err $?
224
225	# concurrent add/delete
226	for i in $(seq 1 1000); do
227		ip addrlabel add prefix 1c3::/64 label 12345 2>/dev/null
228	done &
229
230	for i in $(seq 1 1000); do
231		ip addrlabel del prefix 1c3::/64 label 12345 2>/dev/null
232	done
233
234	wait
235
236	ip addrlabel del prefix 1c3::/64 label 12345 2>/dev/null
237
238	if [ $ret -ne 0 ];then
239		echo "FAIL: ipv6 addrlabel"
240		return 1
241	fi
242
243	echo "PASS: ipv6 addrlabel"
244}
245
246kci_test_ifalias()
247{
248	ret=0
249	namewant=$(uuidgen)
250	syspathname="/sys/class/net/$devdummy/ifalias"
251
252	ip link set dev "$devdummy" alias "$namewant"
253	check_err $?
254
255	if [ $ret -ne 0 ]; then
256		echo "FAIL: cannot set interface alias of $devdummy to $namewant"
257		return 1
258	fi
259
260	ip link show "$devdummy" | grep -q "alias $namewant"
261	check_err $?
262
263	if [ -r "$syspathname" ] ; then
264		read namehave < "$syspathname"
265		if [ "$namewant" != "$namehave" ]; then
266			echo "FAIL: did set ifalias $namewant but got $namehave"
267			return 1
268		fi
269
270		namewant=$(uuidgen)
271		echo "$namewant" > "$syspathname"
272	        ip link show "$devdummy" | grep -q "alias $namewant"
273		check_err $?
274
275		# sysfs interface allows to delete alias again
276		echo "" > "$syspathname"
277
278	        ip link show "$devdummy" | grep -q "alias $namewant"
279		check_fail $?
280
281		# re-add the alias -- kernel should free mem when dummy dev is removed
282		ip link set dev "$devdummy" alias "$namewant"
283		check_err $?
284	fi
285
286	if [ $ret -ne 0 ]; then
287		echo "FAIL: set interface alias $devdummy to $namewant"
288		return 1
289	fi
290
291	echo "PASS: set ifalias $namewant for $devdummy"
292}
293
294kci_test_vrf()
295{
296	vrfname="test-vrf"
297	ret=0
298
299	ip link show type vrf 2>/dev/null
300	if [ $? -ne 0 ]; then
301		echo "SKIP: vrf: iproute2 too old"
302		return 0
303	fi
304
305	ip link add "$vrfname" type vrf table 10
306	check_err $?
307	if [ $ret -ne 0 ];then
308		echo "FAIL: can't add vrf interface, skipping test"
309		return 0
310	fi
311
312	ip -br link show type vrf | grep -q "$vrfname"
313	check_err $?
314	if [ $ret -ne 0 ];then
315		echo "FAIL: created vrf device not found"
316		return 1
317	fi
318
319	ip link set dev "$vrfname" up
320	check_err $?
321
322	ip link set dev "$devdummy" master "$vrfname"
323	check_err $?
324	ip link del dev "$vrfname"
325	check_err $?
326
327	if [ $ret -ne 0 ];then
328		echo "FAIL: vrf"
329		return 1
330	fi
331
332	echo "PASS: vrf"
333}
334
335kci_test_encap_vxlan()
336{
337	ret=0
338	vxlan="test-vxlan0"
339	vlan="test-vlan0"
340	testns="$1"
341
342	ip netns exec "$testns" ip link add "$vxlan" type vxlan id 42 group 239.1.1.1 \
343		dev "$devdummy" dstport 4789 2>/dev/null
344	if [ $? -ne 0 ]; then
345		echo "FAIL: can't add vxlan interface, skipping test"
346		return 0
347	fi
348	check_err $?
349
350	ip netns exec "$testns" ip addr add 10.2.11.49/24 dev "$vxlan"
351	check_err $?
352
353	ip netns exec "$testns" ip link set up dev "$vxlan"
354	check_err $?
355
356	ip netns exec "$testns" ip link add link "$vxlan" name "$vlan" type vlan id 1
357	check_err $?
358
359	ip netns exec "$testns" ip link del "$vxlan"
360	check_err $?
361
362	if [ $ret -ne 0 ]; then
363		echo "FAIL: vxlan"
364		return 1
365	fi
366	echo "PASS: vxlan"
367}
368
369kci_test_encap_fou()
370{
371	ret=0
372	name="test-fou"
373	testns="$1"
374
375	ip fou help 2>&1 |grep -q 'Usage: ip fou'
376	if [ $? -ne 0 ];then
377		echo "SKIP: fou: iproute2 too old"
378		return 1
379	fi
380
381	ip netns exec "$testns" ip fou add port 7777 ipproto 47 2>/dev/null
382	if [ $? -ne 0 ];then
383		echo "FAIL: can't add fou port 7777, skipping test"
384		return 1
385	fi
386
387	ip netns exec "$testns" ip fou add port 8888 ipproto 4
388	check_err $?
389
390	ip netns exec "$testns" ip fou del port 9999 2>/dev/null
391	check_fail $?
392
393	ip netns exec "$testns" ip fou del port 7777
394	check_err $?
395
396	if [ $ret -ne 0 ]; then
397		echo "FAIL: fou"
398		return 1
399	fi
400
401	echo "PASS: fou"
402}
403
404# test various encap methods, use netns to avoid unwanted interference
405kci_test_encap()
406{
407	testns="testns"
408	ret=0
409
410	ip netns add "$testns"
411	if [ $? -ne 0 ]; then
412		echo "SKIP encap tests: cannot add net namespace $testns"
413		return 1
414	fi
415
416	ip netns exec "$testns" ip link set lo up
417	check_err $?
418
419	ip netns exec "$testns" ip link add name "$devdummy" type dummy
420	check_err $?
421	ip netns exec "$testns" ip link set "$devdummy" up
422	check_err $?
423
424	kci_test_encap_vxlan "$testns"
425	kci_test_encap_fou "$testns"
426
427	ip netns del "$testns"
428}
429
430kci_test_rtnl()
431{
432	kci_add_dummy
433	if [ $ret -ne 0 ];then
434		echo "FAIL: cannot add dummy interface"
435		return 1
436	fi
437
438	kci_test_polrouting
439	kci_test_route_get
440	kci_test_tc
441	kci_test_gre
442	kci_test_bridge
443	kci_test_addrlabel
444	kci_test_ifalias
445	kci_test_vrf
446	kci_test_encap
447
448	kci_del_dummy
449}
450
451#check for needed privileges
452if [ "$(id -u)" -ne 0 ];then
453	echo "SKIP: Need root privileges"
454	exit 0
455fi
456
457for x in ip tc;do
458	$x -Version 2>/dev/null >/dev/null
459	if [ $? -ne 0 ];then
460		echo "SKIP: Could not run test without the $x tool"
461		exit 0
462	fi
463done
464
465kci_test_rtnl
466
467exit $ret
468