xref: /openbmc/linux/tools/testing/selftests/net/fib_tests.sh (revision 93707cbabcc8baf2b2b5f4a99c1f08ee83eb7abd)
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4# This test is for checking IPv4 and IPv6 FIB behavior in response to
5# different events.
6
7ret=0
8
9PAUSE_ON_FAIL=${PAUSE_ON_FAIL:=no}
10
11log_test()
12{
13	local rc=$1
14	local expected=$2
15	local msg="$3"
16
17	if [ ${rc} -eq ${expected} ]; then
18		printf "        %-60s  [ OK ]\n" "${msg}"
19	else
20		ret=1
21		printf "        %-60s  [FAIL]\n" "${msg}"
22		if [ "${PAUSE_ON_FAIL}" = "yes" ]; then
23		echo
24			echo "hit enter to continue, 'q' to quit"
25			read a
26			[ "$a" = "q" ] && exit 1
27		fi
28	fi
29}
30
31setup()
32{
33	set -e
34	ip netns add testns
35	ip -netns testns link set dev lo up
36
37	ip -netns testns link add dummy0 type dummy
38	ip -netns testns link set dev dummy0 up
39	ip -netns testns address add 198.51.100.1/24 dev dummy0
40	ip -netns testns -6 address add 2001:db8:1::1/64 dev dummy0
41	set +e
42
43}
44
45cleanup()
46{
47	ip -netns testns link del dev dummy0 &> /dev/null
48	ip netns del testns
49}
50
51fib_unreg_unicast_test()
52{
53	echo
54	echo "Single path route test"
55
56	setup
57
58	echo "    Start point"
59	ip -netns testns route get fibmatch 198.51.100.2 &> /dev/null
60	log_test $? 0 "IPv4 fibmatch"
61	ip -netns testns -6 route get fibmatch 2001:db8:1::2 &> /dev/null
62	log_test $? 0 "IPv6 fibmatch"
63
64	set -e
65	ip -netns testns link del dev dummy0
66	set +e
67
68	echo "    Nexthop device deleted"
69	ip -netns testns route get fibmatch 198.51.100.2 &> /dev/null
70	log_test $? 2 "IPv4 fibmatch - no route"
71	ip -netns testns -6 route get fibmatch 2001:db8:1::2 &> /dev/null
72	log_test $? 2 "IPv6 fibmatch - no route"
73
74	cleanup
75}
76
77fib_unreg_multipath_test()
78{
79
80	echo
81	echo "Multipath route test"
82
83	setup
84
85	set -e
86	ip -netns testns link add dummy1 type dummy
87	ip -netns testns link set dev dummy1 up
88	ip -netns testns address add 192.0.2.1/24 dev dummy1
89	ip -netns testns -6 address add 2001:db8:2::1/64 dev dummy1
90
91	ip -netns testns route add 203.0.113.0/24 \
92		nexthop via 198.51.100.2 dev dummy0 \
93		nexthop via 192.0.2.2 dev dummy1
94	ip -netns testns -6 route add 2001:db8:3::/64 \
95		nexthop via 2001:db8:1::2 dev dummy0 \
96		nexthop via 2001:db8:2::2 dev dummy1
97	set +e
98
99	echo "    Start point"
100	ip -netns testns route get fibmatch 203.0.113.1 &> /dev/null
101	log_test $? 0 "IPv4 fibmatch"
102	ip -netns testns -6 route get fibmatch 2001:db8:3::1 &> /dev/null
103	log_test $? 0 "IPv6 fibmatch"
104
105	set -e
106	ip -netns testns link del dev dummy0
107	set +e
108
109	echo "    One nexthop device deleted"
110	ip -netns testns route get fibmatch 203.0.113.1 &> /dev/null
111	log_test $? 2 "IPv4 - multipath route removed on delete"
112
113	ip -netns testns -6 route get fibmatch 2001:db8:3::1 &> /dev/null
114	# In IPv6 we do not flush the entire multipath route.
115	log_test $? 0 "IPv6 - multipath down to single path"
116
117	set -e
118	ip -netns testns link del dev dummy1
119	set +e
120
121	echo "    Second nexthop device deleted"
122	ip -netns testns -6 route get fibmatch 2001:db8:3::1 &> /dev/null
123	log_test $? 2 "IPv6 - no route"
124
125	cleanup
126}
127
128fib_unreg_test()
129{
130	fib_unreg_unicast_test
131	fib_unreg_multipath_test
132}
133
134fib_down_unicast_test()
135{
136	echo
137	echo "Single path, admin down"
138
139	setup
140
141	echo "    Start point"
142	ip -netns testns route get fibmatch 198.51.100.2 &> /dev/null
143	log_test $? 0 "IPv4 fibmatch"
144	ip -netns testns -6 route get fibmatch 2001:db8:1::2 &> /dev/null
145	log_test $? 0 "IPv6 fibmatch"
146
147	set -e
148	ip -netns testns link set dev dummy0 down
149	set +e
150
151	echo "    Route deleted on down"
152	ip -netns testns route get fibmatch 198.51.100.2 &> /dev/null
153	log_test $? 2 "IPv4 fibmatch"
154	ip -netns testns -6 route get fibmatch 2001:db8:1::2 &> /dev/null
155	log_test $? 2 "IPv6 fibmatch"
156
157	cleanup
158}
159
160fib_down_multipath_test_do()
161{
162	local down_dev=$1
163	local up_dev=$2
164
165	ip -netns testns route get fibmatch 203.0.113.1 \
166		oif $down_dev &> /dev/null
167	log_test $? 2 "IPv4 fibmatch on down device"
168	ip -netns testns -6 route get fibmatch 2001:db8:3::1 \
169		oif $down_dev &> /dev/null
170	log_test $? 2 "IPv6 fibmatch on down device"
171
172	ip -netns testns route get fibmatch 203.0.113.1 \
173		oif $up_dev &> /dev/null
174	log_test $? 0 "IPv4 fibmatch on up device"
175	ip -netns testns -6 route get fibmatch 2001:db8:3::1 \
176		oif $up_dev &> /dev/null
177	log_test $? 0 "IPv6 fibmatch on up device"
178
179	ip -netns testns route get fibmatch 203.0.113.1 | \
180		grep $down_dev | grep -q "dead linkdown"
181	log_test $? 0 "IPv4 flags on down device"
182	ip -netns testns -6 route get fibmatch 2001:db8:3::1 | \
183		grep $down_dev | grep -q "dead linkdown"
184	log_test $? 0 "IPv6 flags on down device"
185
186	ip -netns testns route get fibmatch 203.0.113.1 | \
187		grep $up_dev | grep -q "dead linkdown"
188	log_test $? 1 "IPv4 flags on up device"
189	ip -netns testns -6 route get fibmatch 2001:db8:3::1 | \
190		grep $up_dev | grep -q "dead linkdown"
191	log_test $? 1 "IPv6 flags on up device"
192}
193
194fib_down_multipath_test()
195{
196	echo
197	echo "Admin down multipath"
198
199	setup
200
201	set -e
202	ip -netns testns link add dummy1 type dummy
203	ip -netns testns link set dev dummy1 up
204
205	ip -netns testns address add 192.0.2.1/24 dev dummy1
206	ip -netns testns -6 address add 2001:db8:2::1/64 dev dummy1
207
208	ip -netns testns route add 203.0.113.0/24 \
209		nexthop via 198.51.100.2 dev dummy0 \
210		nexthop via 192.0.2.2 dev dummy1
211	ip -netns testns -6 route add 2001:db8:3::/64 \
212		nexthop via 2001:db8:1::2 dev dummy0 \
213		nexthop via 2001:db8:2::2 dev dummy1
214	set +e
215
216	echo "    Verify start point"
217	ip -netns testns route get fibmatch 203.0.113.1 &> /dev/null
218	log_test $? 0 "IPv4 fibmatch"
219
220	ip -netns testns -6 route get fibmatch 2001:db8:3::1 &> /dev/null
221	log_test $? 0 "IPv6 fibmatch"
222
223	set -e
224	ip -netns testns link set dev dummy0 down
225	set +e
226
227	echo "    One device down, one up"
228	fib_down_multipath_test_do "dummy0" "dummy1"
229
230	set -e
231	ip -netns testns link set dev dummy0 up
232	ip -netns testns link set dev dummy1 down
233	set +e
234
235	echo "    Other device down and up"
236	fib_down_multipath_test_do "dummy1" "dummy0"
237
238	set -e
239	ip -netns testns link set dev dummy0 down
240	set +e
241
242	echo "    Both devices down"
243	ip -netns testns route get fibmatch 203.0.113.1 &> /dev/null
244	log_test $? 2 "IPv4 fibmatch"
245	ip -netns testns -6 route get fibmatch 2001:db8:3::1 &> /dev/null
246	log_test $? 2 "IPv6 fibmatch"
247
248	ip -netns testns link del dev dummy1
249	cleanup
250}
251
252fib_down_test()
253{
254	fib_down_unicast_test
255	fib_down_multipath_test
256}
257
258# Local routes should not be affected when carrier changes.
259fib_carrier_local_test()
260{
261	echo
262	echo "Local carrier tests - single path"
263
264	setup
265
266	set -e
267	ip -netns testns link set dev dummy0 carrier on
268	set +e
269
270	echo "    Start point"
271	ip -netns testns route get fibmatch 198.51.100.1 &> /dev/null
272	log_test $? 0 "IPv4 fibmatch"
273	ip -netns testns -6 route get fibmatch 2001:db8:1::1 &> /dev/null
274	log_test $? 0 "IPv6 fibmatch"
275
276	ip -netns testns route get fibmatch 198.51.100.1 | \
277		grep -q "linkdown"
278	log_test $? 1 "IPv4 - no linkdown flag"
279	ip -netns testns -6 route get fibmatch 2001:db8:1::1 | \
280		grep -q "linkdown"
281	log_test $? 1 "IPv6 - no linkdown flag"
282
283	set -e
284	ip -netns testns link set dev dummy0 carrier off
285	sleep 1
286	set +e
287
288	echo "    Carrier off on nexthop"
289	ip -netns testns route get fibmatch 198.51.100.1 &> /dev/null
290	log_test $? 0 "IPv4 fibmatch"
291	ip -netns testns -6 route get fibmatch 2001:db8:1::1 &> /dev/null
292	log_test $? 0 "IPv6 fibmatch"
293
294	ip -netns testns route get fibmatch 198.51.100.1 | \
295		grep -q "linkdown"
296	log_test $? 1 "IPv4 - linkdown flag set"
297	ip -netns testns -6 route get fibmatch 2001:db8:1::1 | \
298		grep -q "linkdown"
299	log_test $? 1 "IPv6 - linkdown flag set"
300
301	set -e
302	ip -netns testns address add 192.0.2.1/24 dev dummy0
303	ip -netns testns -6 address add 2001:db8:2::1/64 dev dummy0
304	set +e
305
306	echo "    Route to local address with carrier down"
307	ip -netns testns route get fibmatch 192.0.2.1 &> /dev/null
308	log_test $? 0 "IPv4 fibmatch"
309	ip -netns testns -6 route get fibmatch 2001:db8:2::1 &> /dev/null
310	log_test $? 0 "IPv6 fibmatch"
311
312	ip -netns testns route get fibmatch 192.0.2.1 | \
313		grep -q "linkdown"
314	log_test $? 1 "IPv4 linkdown flag set"
315	ip -netns testns -6 route get fibmatch 2001:db8:2::1 | \
316		grep -q "linkdown"
317	log_test $? 1 "IPv6 linkdown flag set"
318
319	cleanup
320}
321
322fib_carrier_unicast_test()
323{
324	ret=0
325
326	echo
327	echo "Single path route carrier test"
328
329	setup
330
331	set -e
332	ip -netns testns link set dev dummy0 carrier on
333	set +e
334
335	echo "    Start point"
336	ip -netns testns route get fibmatch 198.51.100.2 &> /dev/null
337	log_test $? 0 "IPv4 fibmatch"
338	ip -netns testns -6 route get fibmatch 2001:db8:1::2 &> /dev/null
339	log_test $? 0 "IPv6 fibmatch"
340
341	ip -netns testns route get fibmatch 198.51.100.2 | \
342		grep -q "linkdown"
343	log_test $? 1 "IPv4 no linkdown flag"
344	ip -netns testns -6 route get fibmatch 2001:db8:1::2 | \
345		grep -q "linkdown"
346	log_test $? 1 "IPv6 no linkdown flag"
347
348	set -e
349	ip -netns testns link set dev dummy0 carrier off
350	set +e
351
352	echo "    Carrier down"
353	ip -netns testns route get fibmatch 198.51.100.2 &> /dev/null
354	log_test $? 0 "IPv4 fibmatch"
355	ip -netns testns -6 route get fibmatch 2001:db8:1::2 &> /dev/null
356	log_test $? 0 "IPv6 fibmatch"
357
358	ip -netns testns route get fibmatch 198.51.100.2 | \
359		grep -q "linkdown"
360	log_test $? 0 "IPv4 linkdown flag set"
361	ip -netns testns -6 route get fibmatch 2001:db8:1::2 | \
362		grep -q "linkdown"
363	log_test $? 0 "IPv6 linkdown flag set"
364
365	set -e
366	ip -netns testns address add 192.0.2.1/24 dev dummy0
367	ip -netns testns -6 address add 2001:db8:2::1/64 dev dummy0
368	set +e
369
370	echo "    Second address added with carrier down"
371	ip -netns testns route get fibmatch 192.0.2.2 &> /dev/null
372	log_test $? 0 "IPv4 fibmatch"
373	ip -netns testns -6 route get fibmatch 2001:db8:2::2 &> /dev/null
374	log_test $? 0 "IPv6 fibmatch"
375
376	ip -netns testns route get fibmatch 192.0.2.2 | \
377		grep -q "linkdown"
378	log_test $? 0 "IPv4 linkdown flag set"
379	ip -netns testns -6 route get fibmatch 2001:db8:2::2 | \
380		grep -q "linkdown"
381	log_test $? 0 "IPv6 linkdown flag set"
382
383	cleanup
384}
385
386fib_carrier_test()
387{
388	fib_carrier_local_test
389	fib_carrier_unicast_test
390}
391
392fib_test()
393{
394	fib_unreg_test
395	fib_down_test
396	fib_carrier_test
397}
398
399if [ "$(id -u)" -ne 0 ];then
400	echo "SKIP: Need root privileges"
401	exit 0
402fi
403
404if [ ! -x "$(command -v ip)" ]; then
405	echo "SKIP: Could not run test without ip tool"
406	exit 0
407fi
408
409ip route help 2>&1 | grep -q fibmatch
410if [ $? -ne 0 ]; then
411	echo "SKIP: iproute2 too old, missing fibmatch"
412	exit 0
413fi
414
415# start clean
416cleanup &> /dev/null
417
418fib_test
419
420exit $ret
421