xref: /openbmc/linux/tools/testing/selftests/drivers/net/netdevsim/fib_notifications.sh (revision 19d36d2971e671cd1b7f4174ef5e21c341ec7690)
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4lib_dir=$(dirname $0)/../../../net/forwarding
5
6ALL_TESTS="
7	ipv4_route_addition_test
8	ipv4_route_deletion_test
9	ipv4_route_replacement_test
10	ipv6_route_addition_test
11	ipv6_route_deletion_test
12	ipv6_route_replacement_test
13"
14
15NETDEVSIM_PATH=/sys/bus/netdevsim/
16DEV_ADDR=1337
17DEV=netdevsim${DEV_ADDR}
18DEVLINK_DEV=netdevsim/${DEV}
19SYSFS_NET_DIR=/sys/bus/netdevsim/devices/$DEV/net/
20NUM_NETIFS=0
21source $lib_dir/lib.sh
22
23check_rt_trap()
24{
25	local outfile=$1; shift
26	local line
27
28	# Make sure that the first notification was emitted without RTM_F_TRAP
29	# flag and the second with RTM_F_TRAP flag
30	head -n 1 $outfile | grep -q "rt_trap"
31	if [[ $? -eq 0 ]]; then
32		return 1
33	fi
34
35	head -n 2 $outfile | tail -n 1 | grep -q "rt_trap"
36}
37
38route_notify_check()
39{
40	local outfile=$1; shift
41	local expected_num_lines=$1; shift
42
43	# check the monitor results
44	lines=`wc -l $outfile | cut "-d " -f1`
45	test $lines -eq $expected_num_lines
46	check_err $? "$expected_num_lines notifications were expected but $lines were received"
47
48	if [[ $expected_num_lines -eq 2 ]]; then
49		check_rt_trap $outfile
50		check_err $? "Wrong RTM_F_TRAP flags in notifications"
51	fi
52}
53
54route_addition_check()
55{
56	local ip=$1; shift
57	local notify=$1; shift
58	local route=$1; shift
59	local expected_num_notifications=$1; shift
60
61	ip netns exec testns1 sysctl -qw net.$ip.fib_notify_on_flag_change=$notify
62
63	local outfile=$(mktemp)
64
65	$IP monitor route &> $outfile &
66	sleep 1
67	$IP route add $route dev dummy1
68	sleep 1
69	kill %% && wait %% &> /dev/null
70
71	route_notify_check $outfile $expected_num_notifications
72	rm -f $outfile
73
74	$IP route del $route dev dummy1
75}
76
77ipv4_route_addition_test()
78{
79	RET=0
80
81	local ip="ipv4"
82	local route=192.0.2.0/24
83
84	# Make sure a single notification will be emitted for the programmed
85	# route.
86	local notify=0
87	local expected_num_notifications=1
88	# route_addition_check will assign value to RET.
89	route_addition_check $ip $notify $route $expected_num_notifications
90
91	# Make sure two notifications will be emitted for the programmed route.
92	notify=1
93	expected_num_notifications=2
94	route_addition_check $ip $notify $route $expected_num_notifications
95
96	log_test "IPv4 route addition"
97}
98
99route_deletion_check()
100{
101	local ip=$1; shift
102	local notify=$1; shift
103	local route=$1; shift
104	local expected_num_notifications=$1; shift
105
106	ip netns exec testns1 sysctl -qw net.$ip.fib_notify_on_flag_change=$notify
107	$IP route add $route dev dummy1
108	sleep 1
109
110	local outfile=$(mktemp)
111
112	$IP monitor route &> $outfile &
113	sleep 1
114	$IP route del $route dev dummy1
115	sleep 1
116	kill %% && wait %% &> /dev/null
117
118	route_notify_check $outfile $expected_num_notifications
119	rm -f $outfile
120}
121
122ipv4_route_deletion_test()
123{
124	RET=0
125
126	local ip="ipv4"
127	local route=192.0.2.0/24
128	local expected_num_notifications=1
129
130	# Make sure a single notification will be emitted for the deleted route,
131	# regardless of fib_notify_on_flag_change value.
132	local notify=0
133	# route_deletion_check will assign value to RET.
134	route_deletion_check $ip $notify $route $expected_num_notifications
135
136	notify=1
137	route_deletion_check $ip $notify $route $expected_num_notifications
138
139	log_test "IPv4 route deletion"
140}
141
142route_replacement_check()
143{
144	local ip=$1; shift
145	local notify=$1; shift
146	local route=$1; shift
147	local expected_num_notifications=$1; shift
148
149	ip netns exec testns1 sysctl -qw net.$ip.fib_notify_on_flag_change=$notify
150	$IP route add $route dev dummy1
151	sleep 1
152
153	local outfile=$(mktemp)
154
155	$IP monitor route &> $outfile &
156	sleep 1
157	$IP route replace $route dev dummy2
158	sleep 1
159	kill %% && wait %% &> /dev/null
160
161	route_notify_check $outfile $expected_num_notifications
162	rm -f $outfile
163
164	$IP route del $route dev dummy2
165}
166
167ipv4_route_replacement_test()
168{
169	RET=0
170
171	local ip="ipv4"
172	local route=192.0.2.0/24
173
174	$IP link add name dummy2 type dummy
175	$IP link set dev dummy2 up
176
177	# Make sure a single notification will be emitted for the new route.
178	local notify=0
179	local expected_num_notifications=1
180	# route_replacement_check will assign value to RET.
181	route_replacement_check $ip $notify $route $expected_num_notifications
182
183	# Make sure two notifications will be emitted for the new route.
184	notify=1
185	expected_num_notifications=2
186	route_replacement_check $ip $notify $route $expected_num_notifications
187
188	$IP link del name dummy2
189
190	log_test "IPv4 route replacement"
191}
192
193ipv6_route_addition_test()
194{
195	RET=0
196
197	local ip="ipv6"
198	local route=2001:db8:1::/64
199
200	# Make sure a single notification will be emitted for the programmed
201	# route.
202	local notify=0
203	local expected_num_notifications=1
204	route_addition_check $ip $notify $route $expected_num_notifications
205
206	# Make sure two notifications will be emitted for the programmed route.
207	notify=1
208	expected_num_notifications=2
209	route_addition_check $ip $notify $route $expected_num_notifications
210
211	log_test "IPv6 route addition"
212}
213
214ipv6_route_deletion_test()
215{
216	RET=0
217
218	local ip="ipv6"
219	local route=2001:db8:1::/64
220	local expected_num_notifications=1
221
222	# Make sure a single notification will be emitted for the deleted route,
223	# regardless of fib_notify_on_flag_change value.
224	local notify=0
225	route_deletion_check $ip $notify $route $expected_num_notifications
226
227	notify=1
228	route_deletion_check $ip $notify $route $expected_num_notifications
229
230	log_test "IPv6 route deletion"
231}
232
233ipv6_route_replacement_test()
234{
235	RET=0
236
237	local ip="ipv6"
238	local route=2001:db8:1::/64
239
240	$IP link add name dummy2 type dummy
241	$IP link set dev dummy2 up
242
243	# Make sure a single notification will be emitted for the new route.
244	local notify=0
245	local expected_num_notifications=1
246	route_replacement_check $ip $notify $route $expected_num_notifications
247
248	# Make sure two notifications will be emitted for the new route.
249	notify=1
250	expected_num_notifications=2
251	route_replacement_check $ip $notify $route $expected_num_notifications
252
253	$IP link del name dummy2
254
255	log_test "IPv6 route replacement"
256}
257
258setup_prepare()
259{
260	modprobe netdevsim &> /dev/null
261	echo "$DEV_ADDR 1" > ${NETDEVSIM_PATH}/new_device
262	while [ ! -d $SYSFS_NET_DIR ] ; do :; done
263
264	ip netns add testns1
265
266	if [ $? -ne 0 ]; then
267		echo "Failed to add netns \"testns1\""
268		exit 1
269	fi
270
271	devlink dev reload $DEVLINK_DEV netns testns1
272
273	if [ $? -ne 0 ]; then
274		echo "Failed to reload into netns \"testns1\""
275		exit 1
276	fi
277
278	IP="ip -n testns1"
279
280	$IP link add name dummy1 type dummy
281	$IP link set dev dummy1 up
282}
283
284cleanup()
285{
286	pre_cleanup
287
288	$IP link del name dummy1
289	ip netns del testns1
290	echo "$DEV_ADDR" > ${NETDEVSIM_PATH}/del_device
291	modprobe -r netdevsim &> /dev/null
292}
293
294trap cleanup EXIT
295
296setup_prepare
297
298tests_run
299
300exit $EXIT_STATUS
301