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