1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3#
4# This test is for checking the FIB offload API. It makes use of netdevsim
5# which registers a listener to the FIB notification chain.
6
7lib_dir=$(dirname $0)/../../../net/forwarding
8
9ALL_TESTS="
10	ipv4_identical_routes
11	ipv4_tos
12	ipv4_metric
13	ipv4_replace
14	ipv4_delete
15	ipv4_plen
16	ipv4_replay
17	ipv4_flush
18	ipv4_error_path
19	ipv4_delete_fail
20	ipv6_add
21	ipv6_metric
22	ipv6_append_single
23	ipv6_replace_single
24	ipv6_metric_multipath
25	ipv6_append_multipath
26	ipv6_replace_multipath
27	ipv6_append_multipath_to_single
28	ipv6_delete_single
29	ipv6_delete_multipath
30	ipv6_replay_single
31	ipv6_replay_multipath
32	ipv6_error_path
33	ipv6_delete_fail
34"
35NETDEVSIM_PATH=/sys/bus/netdevsim/
36DEV_ADDR=1337
37DEV=netdevsim${DEV_ADDR}
38SYSFS_NET_DIR=/sys/bus/netdevsim/devices/$DEV/net/
39DEBUGFS_DIR=/sys/kernel/debug/netdevsim/$DEV/
40NUM_NETIFS=0
41source $lib_dir/lib.sh
42source $lib_dir/fib_offload_lib.sh
43
44DEVLINK_DEV=
45source $lib_dir/devlink_lib.sh
46DEVLINK_DEV=netdevsim/${DEV}
47
48ipv4_identical_routes()
49{
50	fib_ipv4_identical_routes_test "testns1"
51}
52
53ipv4_tos()
54{
55	fib_ipv4_tos_test "testns1"
56}
57
58ipv4_metric()
59{
60	fib_ipv4_metric_test "testns1"
61}
62
63ipv4_replace()
64{
65	fib_ipv4_replace_test "testns1"
66}
67
68ipv4_delete()
69{
70	fib_ipv4_delete_test "testns1"
71}
72
73ipv4_plen()
74{
75	fib_ipv4_plen_test "testns1"
76}
77
78ipv4_replay_metric()
79{
80	fib_ipv4_replay_metric_test "testns1" "$DEVLINK_DEV"
81}
82
83ipv4_replay_tos()
84{
85	fib_ipv4_replay_tos_test "testns1" "$DEVLINK_DEV"
86}
87
88ipv4_replay_plen()
89{
90	fib_ipv4_replay_plen_test "testns1" "$DEVLINK_DEV"
91}
92
93ipv4_replay()
94{
95	ipv4_replay_metric
96	ipv4_replay_tos
97	ipv4_replay_plen
98}
99
100ipv4_flush()
101{
102	fib_ipv4_flush_test "testns1"
103}
104
105ipv4_error_path_add()
106{
107	local lsb
108
109	RET=0
110
111	ip -n testns1 link add name dummy1 type dummy
112	ip -n testns1 link set dev dummy1 up
113
114	devlink -N testns1 resource set $DEVLINK_DEV path IPv4/fib size 10
115	devlink -N testns1 dev reload $DEVLINK_DEV
116
117	for lsb in $(seq 1 20); do
118		ip -n testns1 route add 192.0.2.${lsb}/32 dev dummy1 \
119			&> /dev/null
120	done
121
122	log_test "IPv4 error path - add"
123
124	ip -n testns1 link del dev dummy1
125}
126
127ipv4_error_path_replay()
128{
129	local lsb
130
131	RET=0
132
133	ip -n testns1 link add name dummy1 type dummy
134	ip -n testns1 link set dev dummy1 up
135
136	devlink -N testns1 resource set $DEVLINK_DEV path IPv4/fib size 100
137	devlink -N testns1 dev reload $DEVLINK_DEV
138
139	for lsb in $(seq 1 20); do
140		ip -n testns1 route add 192.0.2.${lsb}/32 dev dummy1
141	done
142
143	devlink -N testns1 resource set $DEVLINK_DEV path IPv4/fib size 10
144	devlink -N testns1 dev reload $DEVLINK_DEV &> /dev/null
145
146	log_test "IPv4 error path - replay"
147
148	ip -n testns1 link del dev dummy1
149
150	# Successfully reload after deleting all the routes.
151	devlink -N testns1 resource set $DEVLINK_DEV path IPv4/fib size 100
152	devlink -N testns1 dev reload $DEVLINK_DEV
153}
154
155ipv4_error_path()
156{
157	# Test the different error paths of the notifiers by limiting the size
158	# of the "IPv4/fib" resource.
159	ipv4_error_path_add
160	ipv4_error_path_replay
161}
162
163ipv4_delete_fail()
164{
165	RET=0
166
167	echo "y" > $DEBUGFS_DIR/fib/fail_route_delete
168
169	ip -n testns1 link add name dummy1 type dummy
170	ip -n testns1 link set dev dummy1 up
171
172	ip -n testns1 route add 192.0.2.0/24 dev dummy1
173	ip -n testns1 route del 192.0.2.0/24 dev dummy1 &> /dev/null
174
175	# We should not be able to delete the netdev if we are leaking a
176	# reference.
177	ip -n testns1 link del dev dummy1
178
179	log_test "IPv4 route delete failure"
180
181	echo "n" > $DEBUGFS_DIR/fib/fail_route_delete
182}
183
184ipv6_add()
185{
186	fib_ipv6_add_test "testns1"
187}
188
189ipv6_metric()
190{
191	fib_ipv6_metric_test "testns1"
192}
193
194ipv6_append_single()
195{
196	fib_ipv6_append_single_test "testns1"
197}
198
199ipv6_replace_single()
200{
201	fib_ipv6_replace_single_test "testns1"
202}
203
204ipv6_metric_multipath()
205{
206	fib_ipv6_metric_multipath_test "testns1"
207}
208
209ipv6_append_multipath()
210{
211	fib_ipv6_append_multipath_test "testns1"
212}
213
214ipv6_replace_multipath()
215{
216	fib_ipv6_replace_multipath_test "testns1"
217}
218
219ipv6_append_multipath_to_single()
220{
221	fib_ipv6_append_multipath_to_single_test "testns1"
222}
223
224ipv6_delete_single()
225{
226	fib_ipv6_delete_single_test "testns1"
227}
228
229ipv6_delete_multipath()
230{
231	fib_ipv6_delete_multipath_test "testns1"
232}
233
234ipv6_replay_single()
235{
236	fib_ipv6_replay_single_test "testns1" "$DEVLINK_DEV"
237}
238
239ipv6_replay_multipath()
240{
241	fib_ipv6_replay_multipath_test "testns1" "$DEVLINK_DEV"
242}
243
244ipv6_error_path_add_single()
245{
246	local lsb
247
248	RET=0
249
250	ip -n testns1 link add name dummy1 type dummy
251	ip -n testns1 link set dev dummy1 up
252
253	devlink -N testns1 resource set $DEVLINK_DEV path IPv6/fib size 10
254	devlink -N testns1 dev reload $DEVLINK_DEV
255
256	for lsb in $(seq 1 20); do
257		ip -n testns1 route add 2001:db8:1::${lsb}/128 dev dummy1 \
258			&> /dev/null
259	done
260
261	log_test "IPv6 error path - add single"
262
263	ip -n testns1 link del dev dummy1
264}
265
266ipv6_error_path_add_multipath()
267{
268	local lsb
269
270	RET=0
271
272	for i in $(seq 1 2); do
273		ip -n testns1 link add name dummy$i type dummy
274		ip -n testns1 link set dev dummy$i up
275		ip -n testns1 address add 2001:db8:$i::1/64 dev dummy$i
276	done
277
278	devlink -N testns1 resource set $DEVLINK_DEV path IPv6/fib size 10
279	devlink -N testns1 dev reload $DEVLINK_DEV
280
281	for lsb in $(seq 1 20); do
282		ip -n testns1 route add 2001:db8:10::${lsb}/128 \
283			nexthop via 2001:db8:1::2 dev dummy1 \
284			nexthop via 2001:db8:2::2 dev dummy2 &> /dev/null
285	done
286
287	log_test "IPv6 error path - add multipath"
288
289	for i in $(seq 1 2); do
290		ip -n testns1 link del dev dummy$i
291	done
292}
293
294ipv6_error_path_replay()
295{
296	local lsb
297
298	RET=0
299
300	ip -n testns1 link add name dummy1 type dummy
301	ip -n testns1 link set dev dummy1 up
302
303	devlink -N testns1 resource set $DEVLINK_DEV path IPv6/fib size 100
304	devlink -N testns1 dev reload $DEVLINK_DEV
305
306	for lsb in $(seq 1 20); do
307		ip -n testns1 route add 2001:db8:1::${lsb}/128 dev dummy1
308	done
309
310	devlink -N testns1 resource set $DEVLINK_DEV path IPv6/fib size 10
311	devlink -N testns1 dev reload $DEVLINK_DEV &> /dev/null
312
313	log_test "IPv6 error path - replay"
314
315	ip -n testns1 link del dev dummy1
316
317	# Successfully reload after deleting all the routes.
318	devlink -N testns1 resource set $DEVLINK_DEV path IPv6/fib size 100
319	devlink -N testns1 dev reload $DEVLINK_DEV
320}
321
322ipv6_error_path()
323{
324	# Test the different error paths of the notifiers by limiting the size
325	# of the "IPv6/fib" resource.
326	ipv6_error_path_add_single
327	ipv6_error_path_add_multipath
328	ipv6_error_path_replay
329}
330
331ipv6_delete_fail()
332{
333	RET=0
334
335	echo "y" > $DEBUGFS_DIR/fib/fail_route_delete
336
337	ip -n testns1 link add name dummy1 type dummy
338	ip -n testns1 link set dev dummy1 up
339
340	ip -n testns1 route add 2001:db8:1::/64 dev dummy1
341	ip -n testns1 route del 2001:db8:1::/64 dev dummy1 &> /dev/null
342
343	# We should not be able to delete the netdev if we are leaking a
344	# reference.
345	ip -n testns1 link del dev dummy1
346
347	log_test "IPv6 route delete failure"
348
349	echo "n" > $DEBUGFS_DIR/fib/fail_route_delete
350}
351
352fib_notify_on_flag_change_set()
353{
354	local notify=$1; shift
355
356	ip netns exec testns1 sysctl -qw net.ipv4.fib_notify_on_flag_change=$notify
357	ip netns exec testns1 sysctl -qw net.ipv6.fib_notify_on_flag_change=$notify
358
359	log_info "Set fib_notify_on_flag_change to $notify"
360}
361
362setup_prepare()
363{
364	local netdev
365
366	modprobe netdevsim &> /dev/null
367
368	echo "$DEV_ADDR 1" > ${NETDEVSIM_PATH}/new_device
369	while [ ! -d $SYSFS_NET_DIR ] ; do :; done
370
371	ip netns add testns1
372	if [ $? -ne 0 ]; then
373		echo "Failed to add netns \"testns1\""
374		exit 1
375	fi
376
377	devlink dev reload $DEVLINK_DEV netns testns1
378	if [ $? -ne 0 ]; then
379		echo "Failed to reload into netns \"testns1\""
380		exit 1
381	fi
382}
383
384cleanup()
385{
386	pre_cleanup
387	ip netns del testns1
388	echo "$DEV_ADDR" > ${NETDEVSIM_PATH}/del_device
389	modprobe -r netdevsim &> /dev/null
390}
391
392trap cleanup EXIT
393
394setup_prepare
395
396fib_notify_on_flag_change_set 1
397tests_run
398
399fib_notify_on_flag_change_set 0
400tests_run
401
402exit $EXIT_STATUS
403