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