selftests: netdevsim: Test route offload failure notifications
[linux-2.6-microblaze.git] / tools / testing / selftests / drivers / net / netdevsim / fib_notifications.sh
1 #!/bin/bash
2 # SPDX-License-Identifier: GPL-2.0
3
4 lib_dir=$(dirname $0)/../../../net/forwarding
5
6 ALL_TESTS="
7         ipv4_route_addition_test
8         ipv4_route_deletion_test
9         ipv4_route_replacement_test
10         ipv4_route_offload_failed_test
11         ipv6_route_addition_test
12         ipv6_route_deletion_test
13         ipv6_route_replacement_test
14         ipv6_route_offload_failed_test
15 "
16
17 NETDEVSIM_PATH=/sys/bus/netdevsim/
18 DEV_ADDR=1337
19 DEV=netdevsim${DEV_ADDR}
20 DEVLINK_DEV=netdevsim/${DEV}
21 SYSFS_NET_DIR=/sys/bus/netdevsim/devices/$DEV/net/
22 DEBUGFS_DIR=/sys/kernel/debug/netdevsim/$DEV/
23 NUM_NETIFS=0
24 source $lib_dir/lib.sh
25
26 check_rt_offload_failed()
27 {
28         local outfile=$1; shift
29         local line
30
31         # Make sure that the first notification was emitted without
32         # RTM_F_OFFLOAD_FAILED flag and the second with RTM_F_OFFLOAD_FAILED
33         # flag
34         head -n 1 $outfile | grep -q "rt_offload_failed"
35         if [[ $? -eq 0 ]]; then
36                 return 1
37         fi
38
39         head -n 2 $outfile | tail -n 1 | grep -q "rt_offload_failed"
40 }
41
42 check_rt_trap()
43 {
44         local outfile=$1; shift
45         local line
46
47         # Make sure that the first notification was emitted without RTM_F_TRAP
48         # flag and the second with RTM_F_TRAP flag
49         head -n 1 $outfile | grep -q "rt_trap"
50         if [[ $? -eq 0 ]]; then
51                 return 1
52         fi
53
54         head -n 2 $outfile | tail -n 1 | grep -q "rt_trap"
55 }
56
57 route_notify_check()
58 {
59         local outfile=$1; shift
60         local expected_num_lines=$1; shift
61         local offload_failed=${1:-0}; shift
62
63         # check the monitor results
64         lines=`wc -l $outfile | cut "-d " -f1`
65         test $lines -eq $expected_num_lines
66         check_err $? "$expected_num_lines notifications were expected but $lines were received"
67
68         if [[ $expected_num_lines -eq 1 ]]; then
69                 return
70         fi
71
72         if [[ $offload_failed -eq 0 ]]; then
73                 check_rt_trap $outfile
74                 check_err $? "Wrong RTM_F_TRAP flags in notifications"
75         else
76                 check_rt_offload_failed $outfile
77                 check_err $? "Wrong RTM_F_OFFLOAD_FAILED flags in notifications"
78         fi
79 }
80
81 route_addition_check()
82 {
83         local ip=$1; shift
84         local notify=$1; shift
85         local route=$1; shift
86         local expected_num_notifications=$1; shift
87         local offload_failed=${1:-0}; shift
88
89         ip netns exec testns1 sysctl -qw net.$ip.fib_notify_on_flag_change=$notify
90
91         local outfile=$(mktemp)
92
93         $IP monitor route &> $outfile &
94         sleep 1
95         $IP route add $route dev dummy1
96         sleep 1
97         kill %% && wait %% &> /dev/null
98
99         route_notify_check $outfile $expected_num_notifications $offload_failed
100         rm -f $outfile
101
102         $IP route del $route dev dummy1
103 }
104
105 ipv4_route_addition_test()
106 {
107         RET=0
108
109         local ip="ipv4"
110         local route=192.0.2.0/24
111
112         # Make sure a single notification will be emitted for the programmed
113         # route.
114         local notify=0
115         local expected_num_notifications=1
116         # route_addition_check will assign value to RET.
117         route_addition_check $ip $notify $route $expected_num_notifications
118
119         # Make sure two notifications will be emitted for the programmed route.
120         notify=1
121         expected_num_notifications=2
122         route_addition_check $ip $notify $route $expected_num_notifications
123
124         # notify=2 means emit notifications only for failed route installation,
125         # make sure a single notification will be emitted for the programmed
126         # route.
127         notify=2
128         expected_num_notifications=1
129         route_addition_check $ip $notify $route $expected_num_notifications
130
131         log_test "IPv4 route addition"
132 }
133
134 route_deletion_check()
135 {
136         local ip=$1; shift
137         local notify=$1; shift
138         local route=$1; shift
139         local expected_num_notifications=$1; shift
140
141         ip netns exec testns1 sysctl -qw net.$ip.fib_notify_on_flag_change=$notify
142         $IP route add $route dev dummy1
143         sleep 1
144
145         local outfile=$(mktemp)
146
147         $IP monitor route &> $outfile &
148         sleep 1
149         $IP route del $route dev dummy1
150         sleep 1
151         kill %% && wait %% &> /dev/null
152
153         route_notify_check $outfile $expected_num_notifications
154         rm -f $outfile
155 }
156
157 ipv4_route_deletion_test()
158 {
159         RET=0
160
161         local ip="ipv4"
162         local route=192.0.2.0/24
163         local expected_num_notifications=1
164
165         # Make sure a single notification will be emitted for the deleted route,
166         # regardless of fib_notify_on_flag_change value.
167         local notify=0
168         # route_deletion_check will assign value to RET.
169         route_deletion_check $ip $notify $route $expected_num_notifications
170
171         notify=1
172         route_deletion_check $ip $notify $route $expected_num_notifications
173
174         log_test "IPv4 route deletion"
175 }
176
177 route_replacement_check()
178 {
179         local ip=$1; shift
180         local notify=$1; shift
181         local route=$1; shift
182         local expected_num_notifications=$1; shift
183
184         ip netns exec testns1 sysctl -qw net.$ip.fib_notify_on_flag_change=$notify
185         $IP route add $route dev dummy1
186         sleep 1
187
188         local outfile=$(mktemp)
189
190         $IP monitor route &> $outfile &
191         sleep 1
192         $IP route replace $route dev dummy2
193         sleep 1
194         kill %% && wait %% &> /dev/null
195
196         route_notify_check $outfile $expected_num_notifications
197         rm -f $outfile
198
199         $IP route del $route dev dummy2
200 }
201
202 ipv4_route_replacement_test()
203 {
204         RET=0
205
206         local ip="ipv4"
207         local route=192.0.2.0/24
208
209         $IP link add name dummy2 type dummy
210         $IP link set dev dummy2 up
211
212         # Make sure a single notification will be emitted for the new route.
213         local notify=0
214         local expected_num_notifications=1
215         # route_replacement_check will assign value to RET.
216         route_replacement_check $ip $notify $route $expected_num_notifications
217
218         # Make sure two notifications will be emitted for the new route.
219         notify=1
220         expected_num_notifications=2
221         route_replacement_check $ip $notify $route $expected_num_notifications
222
223         # notify=2 means emit notifications only for failed route installation,
224         # make sure a single notification will be emitted for the new route.
225         notify=2
226         expected_num_notifications=1
227         route_replacement_check $ip $notify $route $expected_num_notifications
228
229         $IP link del name dummy2
230
231         log_test "IPv4 route replacement"
232 }
233
234 ipv4_route_offload_failed_test()
235 {
236
237         RET=0
238
239         local ip="ipv4"
240         local route=192.0.2.0/24
241         local offload_failed=1
242
243         echo "y"> $DEBUGFS_DIR/fib/fail_route_offload
244         check_err $? "Failed to setup route offload to fail"
245
246         # Make sure a single notification will be emitted for the programmed
247         # route.
248         local notify=0
249         local expected_num_notifications=1
250         route_addition_check $ip $notify $route $expected_num_notifications \
251                 $offload_failed
252
253         # Make sure two notifications will be emitted for the new route.
254         notify=1
255         expected_num_notifications=2
256         route_addition_check $ip $notify $route $expected_num_notifications \
257                 $offload_failed
258
259         # notify=2 means emit notifications only for failed route installation,
260         # make sure two notifications will be emitted for the new route.
261         notify=2
262         expected_num_notifications=2
263         route_addition_check $ip $notify $route $expected_num_notifications \
264                 $offload_failed
265
266         echo "n"> $DEBUGFS_DIR/fib/fail_route_offload
267         check_err $? "Failed to setup route offload not to fail"
268
269         log_test "IPv4 route offload failed"
270 }
271
272 ipv6_route_addition_test()
273 {
274         RET=0
275
276         local ip="ipv6"
277         local route=2001:db8:1::/64
278
279         # Make sure a single notification will be emitted for the programmed
280         # route.
281         local notify=0
282         local expected_num_notifications=1
283         route_addition_check $ip $notify $route $expected_num_notifications
284
285         # Make sure two notifications will be emitted for the programmed route.
286         notify=1
287         expected_num_notifications=2
288         route_addition_check $ip $notify $route $expected_num_notifications
289
290         # notify=2 means emit notifications only for failed route installation,
291         # make sure a single notification will be emitted for the programmed
292         # route.
293         notify=2
294         expected_num_notifications=1
295         route_addition_check $ip $notify $route $expected_num_notifications
296
297         log_test "IPv6 route addition"
298 }
299
300 ipv6_route_deletion_test()
301 {
302         RET=0
303
304         local ip="ipv6"
305         local route=2001:db8:1::/64
306         local expected_num_notifications=1
307
308         # Make sure a single notification will be emitted for the deleted route,
309         # regardless of fib_notify_on_flag_change value.
310         local notify=0
311         route_deletion_check $ip $notify $route $expected_num_notifications
312
313         notify=1
314         route_deletion_check $ip $notify $route $expected_num_notifications
315
316         log_test "IPv6 route deletion"
317 }
318
319 ipv6_route_replacement_test()
320 {
321         RET=0
322
323         local ip="ipv6"
324         local route=2001:db8:1::/64
325
326         $IP link add name dummy2 type dummy
327         $IP link set dev dummy2 up
328
329         # Make sure a single notification will be emitted for the new route.
330         local notify=0
331         local expected_num_notifications=1
332         route_replacement_check $ip $notify $route $expected_num_notifications
333
334         # Make sure two notifications will be emitted for the new route.
335         notify=1
336         expected_num_notifications=2
337         route_replacement_check $ip $notify $route $expected_num_notifications
338
339         # notify=2 means emit notifications only for failed route installation,
340         # make sure a single notification will be emitted for the new route.
341         notify=2
342         expected_num_notifications=1
343         route_replacement_check $ip $notify $route $expected_num_notifications
344
345         $IP link del name dummy2
346
347         log_test "IPv6 route replacement"
348 }
349
350 ipv6_route_offload_failed_test()
351 {
352
353         RET=0
354
355         local ip="ipv6"
356         local route=2001:db8:1::/64
357         local offload_failed=1
358
359         echo "y"> $DEBUGFS_DIR/fib/fail_route_offload
360         check_err $? "Failed to setup route offload to fail"
361
362         # Make sure a single notification will be emitted for the programmed
363         # route.
364         local notify=0
365         local expected_num_notifications=1
366         route_addition_check $ip $notify $route $expected_num_notifications \
367                 $offload_failed
368
369         # Make sure two notifications will be emitted for the new route.
370         notify=1
371         expected_num_notifications=2
372         route_addition_check $ip $notify $route $expected_num_notifications \
373                 $offload_failed
374
375         # notify=2 means emit notifications only for failed route installation,
376         # make sure two notifications will be emitted for the new route.
377         notify=2
378         expected_num_notifications=2
379         route_addition_check $ip $notify $route $expected_num_notifications \
380                 $offload_failed
381
382         echo "n"> $DEBUGFS_DIR/fib/fail_route_offload
383         check_err $? "Failed to setup route offload not to fail"
384
385         log_test "IPv6 route offload failed"
386 }
387
388 setup_prepare()
389 {
390         modprobe netdevsim &> /dev/null
391         echo "$DEV_ADDR 1" > ${NETDEVSIM_PATH}/new_device
392         while [ ! -d $SYSFS_NET_DIR ] ; do :; done
393
394         ip netns add testns1
395
396         if [ $? -ne 0 ]; then
397                 echo "Failed to add netns \"testns1\""
398                 exit 1
399         fi
400
401         devlink dev reload $DEVLINK_DEV netns testns1
402
403         if [ $? -ne 0 ]; then
404                 echo "Failed to reload into netns \"testns1\""
405                 exit 1
406         fi
407
408         IP="ip -n testns1"
409
410         $IP link add name dummy1 type dummy
411         $IP link set dev dummy1 up
412 }
413
414 cleanup()
415 {
416         pre_cleanup
417
418         $IP link del name dummy1
419         ip netns del testns1
420         echo "$DEV_ADDR" > ${NETDEVSIM_PATH}/del_device
421         modprobe -r netdevsim &> /dev/null
422 }
423
424 trap cleanup EXIT
425
426 setup_prepare
427
428 tests_run
429
430 exit $EXIT_STATUS