afs: Stop implementing ->writepage()
[sfrench/cifs-2.6.git] / tools / testing / selftests / drivers / net / netdevsim / devlink_trap.sh
1 #!/bin/bash
2 # SPDX-License-Identifier: GPL-2.0
3 #
4 # This test is for checking devlink-trap functionality. It makes use of
5 # netdevsim which implements the required callbacks.
6
7 lib_dir=$(dirname $0)/../../../net/forwarding
8
9 ALL_TESTS="
10         init_test
11         trap_action_test
12         trap_metadata_test
13         bad_trap_test
14         bad_trap_action_test
15         trap_stats_test
16         trap_group_action_test
17         bad_trap_group_test
18         trap_group_stats_test
19         trap_policer_test
20         trap_policer_bind_test
21         port_del_test
22         dev_del_test
23 "
24 NETDEVSIM_PATH=/sys/bus/netdevsim/
25 DEV_ADDR=1337
26 DEV=netdevsim${DEV_ADDR}
27 DEBUGFS_DIR=/sys/kernel/debug/netdevsim/$DEV/
28 SLEEP_TIME=1
29 NETDEV=""
30 NUM_NETIFS=0
31 source $lib_dir/lib.sh
32
33 DEVLINK_DEV=
34 source $lib_dir/devlink_lib.sh
35 DEVLINK_DEV=netdevsim/${DEV}
36
37 require_command udevadm
38
39 modprobe netdevsim &> /dev/null
40 if [ ! -d "$NETDEVSIM_PATH" ]; then
41         echo "SKIP: No netdevsim support"
42         exit 1
43 fi
44
45 if [ -d "${NETDEVSIM_PATH}/devices/netdevsim${DEV_ADDR}" ]; then
46         echo "SKIP: Device netdevsim${DEV_ADDR} already exists"
47         exit 1
48 fi
49
50 init_test()
51 {
52         RET=0
53
54         test $(devlink_traps_num_get) -ne 0
55         check_err $? "No traps were registered"
56
57         log_test "Initialization"
58 }
59
60 trap_action_test()
61 {
62         local orig_action
63         local trap_name
64         local action
65
66         RET=0
67
68         for trap_name in $(devlink_traps_get); do
69                 # The action of non-drop traps cannot be changed.
70                 if [ $(devlink_trap_type_get $trap_name) = "drop" ]; then
71                         devlink_trap_action_set $trap_name "trap"
72                         action=$(devlink_trap_action_get $trap_name)
73                         if [ $action != "trap" ]; then
74                                 check_err 1 "Trap $trap_name did not change action to trap"
75                         fi
76
77                         devlink_trap_action_set $trap_name "drop"
78                         action=$(devlink_trap_action_get $trap_name)
79                         if [ $action != "drop" ]; then
80                                 check_err 1 "Trap $trap_name did not change action to drop"
81                         fi
82                 else
83                         orig_action=$(devlink_trap_action_get $trap_name)
84
85                         devlink_trap_action_set $trap_name "trap"
86                         action=$(devlink_trap_action_get $trap_name)
87                         if [ $action != $orig_action ]; then
88                                 check_err 1 "Trap $trap_name changed action when should not"
89                         fi
90
91                         devlink_trap_action_set $trap_name "drop"
92                         action=$(devlink_trap_action_get $trap_name)
93                         if [ $action != $orig_action ]; then
94                                 check_err 1 "Trap $trap_name changed action when should not"
95                         fi
96                 fi
97         done
98
99         log_test "Trap action"
100 }
101
102 trap_metadata_test()
103 {
104         local trap_name
105
106         RET=0
107
108         for trap_name in $(devlink_traps_get); do
109                 devlink_trap_metadata_test $trap_name "input_port"
110                 check_err $? "Input port not reported as metadata of trap $trap_name"
111                 if [ $trap_name == "ingress_flow_action_drop" ] ||
112                    [ $trap_name == "egress_flow_action_drop" ]; then
113                         devlink_trap_metadata_test $trap_name "flow_action_cookie"
114                         check_err $? "Flow action cookie not reported as metadata of trap $trap_name"
115                 fi
116         done
117
118         log_test "Trap metadata"
119 }
120
121 bad_trap_test()
122 {
123         RET=0
124
125         devlink_trap_action_set "made_up_trap" "drop"
126         check_fail $? "Did not get an error for non-existing trap"
127
128         log_test "Non-existing trap"
129 }
130
131 bad_trap_action_test()
132 {
133         local traps_arr
134         local trap_name
135
136         RET=0
137
138         # Pick first trap.
139         traps_arr=($(devlink_traps_get))
140         trap_name=${traps_arr[0]}
141
142         devlink_trap_action_set $trap_name "made_up_action"
143         check_fail $? "Did not get an error for non-existing trap action"
144
145         log_test "Non-existing trap action"
146 }
147
148 trap_stats_test()
149 {
150         local trap_name
151
152         RET=0
153
154         for trap_name in $(devlink_traps_get); do
155                 devlink_trap_stats_idle_test $trap_name
156                 check_err $? "Stats of trap $trap_name not idle when netdev down"
157
158                 ip link set dev $NETDEV up
159
160                 if [ $(devlink_trap_type_get $trap_name) = "drop" ]; then
161                         devlink_trap_action_set $trap_name "trap"
162                         devlink_trap_stats_idle_test $trap_name
163                         check_fail $? "Stats of trap $trap_name idle when action is trap"
164
165                         devlink_trap_action_set $trap_name "drop"
166                         devlink_trap_stats_idle_test $trap_name
167                         check_err $? "Stats of trap $trap_name not idle when action is drop"
168
169                         echo "y"> $DEBUGFS_DIR/fail_trap_drop_counter_get
170                         devlink -s trap show $DEVLINK_DEV trap $trap_name &> /dev/null
171                         check_fail $? "Managed to read trap (hard dropped) statistics when should not"
172                         echo "n"> $DEBUGFS_DIR/fail_trap_drop_counter_get
173                         devlink -s trap show $DEVLINK_DEV trap $trap_name &> /dev/null
174                         check_err $? "Did not manage to read trap (hard dropped) statistics when should"
175
176                         devlink_trap_drop_stats_idle_test $trap_name
177                         check_fail $? "Drop stats of trap $trap_name idle when should not"
178                 else
179                         devlink_trap_stats_idle_test $trap_name
180                         check_fail $? "Stats of non-drop trap $trap_name idle when should not"
181                 fi
182
183                 ip link set dev $NETDEV down
184         done
185
186         log_test "Trap statistics"
187 }
188
189 trap_group_action_test()
190 {
191         local curr_group group_name
192         local trap_name
193         local trap_type
194         local action
195
196         RET=0
197
198         for group_name in $(devlink_trap_groups_get); do
199                 devlink_trap_group_action_set $group_name "trap"
200
201                 for trap_name in $(devlink_traps_get); do
202                         curr_group=$(devlink_trap_group_get $trap_name)
203                         if [ $curr_group != $group_name ]; then
204                                 continue
205                         fi
206
207                         trap_type=$(devlink_trap_type_get $trap_name)
208                         if [ $trap_type != "drop" ]; then
209                                 continue
210                         fi
211
212                         action=$(devlink_trap_action_get $trap_name)
213                         if [ $action != "trap" ]; then
214                                 check_err 1 "Trap $trap_name did not change action to trap"
215                         fi
216                 done
217
218                 devlink_trap_group_action_set $group_name "drop"
219
220                 for trap_name in $(devlink_traps_get); do
221                         curr_group=$(devlink_trap_group_get $trap_name)
222                         if [ $curr_group != $group_name ]; then
223                                 continue
224                         fi
225
226                         trap_type=$(devlink_trap_type_get $trap_name)
227                         if [ $trap_type != "drop" ]; then
228                                 continue
229                         fi
230
231                         action=$(devlink_trap_action_get $trap_name)
232                         if [ $action != "drop" ]; then
233                                 check_err 1 "Trap $trap_name did not change action to drop"
234                         fi
235                 done
236         done
237
238         log_test "Trap group action"
239 }
240
241 bad_trap_group_test()
242 {
243         RET=0
244
245         devlink_trap_group_action_set "made_up_trap_group" "drop"
246         check_fail $? "Did not get an error for non-existing trap group"
247
248         log_test "Non-existing trap group"
249 }
250
251 trap_group_stats_test()
252 {
253         local group_name
254
255         RET=0
256
257         for group_name in $(devlink_trap_groups_get); do
258                 devlink_trap_group_stats_idle_test $group_name
259                 check_err $? "Stats of trap group $group_name not idle when netdev down"
260
261                 ip link set dev $NETDEV up
262
263                 devlink_trap_group_action_set $group_name "trap"
264                 devlink_trap_group_stats_idle_test $group_name
265                 check_fail $? "Stats of trap group $group_name idle when action is trap"
266
267                 devlink_trap_group_action_set $group_name "drop"
268                 ip link set dev $NETDEV down
269         done
270
271         log_test "Trap group statistics"
272 }
273
274 trap_policer_test()
275 {
276         local packets_t0
277         local packets_t1
278
279         RET=0
280
281         if [ $(devlink_trap_policers_num_get) -eq 0 ]; then
282                 check_err 1 "Failed to dump policers"
283         fi
284
285         devlink trap policer set $DEVLINK_DEV policer 1337 &> /dev/null
286         check_fail $? "Did not get an error for setting a non-existing policer"
287         devlink trap policer show $DEVLINK_DEV policer 1337 &> /dev/null
288         check_fail $? "Did not get an error for getting a non-existing policer"
289
290         devlink trap policer set $DEVLINK_DEV policer 1 rate 2000 burst 16
291         check_err $? "Failed to set valid parameters for a valid policer"
292         if [ $(devlink_trap_policer_rate_get 1) -ne 2000 ]; then
293                 check_err 1 "Policer rate was not changed"
294         fi
295         if [ $(devlink_trap_policer_burst_get 1) -ne 16 ]; then
296                 check_err 1 "Policer burst size was not changed"
297         fi
298
299         devlink trap policer set $DEVLINK_DEV policer 1 rate 0 &> /dev/null
300         check_fail $? "Policer rate was changed to rate lower than limit"
301         devlink trap policer set $DEVLINK_DEV policer 1 rate 9000 &> /dev/null
302         check_fail $? "Policer rate was changed to rate higher than limit"
303         devlink trap policer set $DEVLINK_DEV policer 1 burst 2 &> /dev/null
304         check_fail $? "Policer burst size was changed to burst size lower than limit"
305         devlink trap policer set $DEVLINK_DEV policer 1 rate 65537 &> /dev/null
306         check_fail $? "Policer burst size was changed to burst size higher than limit"
307         echo "y" > $DEBUGFS_DIR/fail_trap_policer_set
308         devlink trap policer set $DEVLINK_DEV policer 1 rate 3000 &> /dev/null
309         check_fail $? "Managed to set policer rate when should not"
310         echo "n" > $DEBUGFS_DIR/fail_trap_policer_set
311         if [ $(devlink_trap_policer_rate_get 1) -ne 2000 ]; then
312                 check_err 1 "Policer rate was changed to an invalid value"
313         fi
314         if [ $(devlink_trap_policer_burst_get 1) -ne 16 ]; then
315                 check_err 1 "Policer burst size was changed to an invalid value"
316         fi
317
318         packets_t0=$(devlink_trap_policer_rx_dropped_get 1)
319         sleep .5
320         packets_t1=$(devlink_trap_policer_rx_dropped_get 1)
321         if [ ! $packets_t1 -gt $packets_t0 ]; then
322                 check_err 1 "Policer drop counter was not incremented"
323         fi
324
325         echo "y"> $DEBUGFS_DIR/fail_trap_policer_counter_get
326         devlink -s trap policer show $DEVLINK_DEV policer 1 &> /dev/null
327         check_fail $? "Managed to read policer drop counter when should not"
328         echo "n"> $DEBUGFS_DIR/fail_trap_policer_counter_get
329         devlink -s trap policer show $DEVLINK_DEV policer 1 &> /dev/null
330         check_err $? "Did not manage to read policer drop counter when should"
331
332         log_test "Trap policer"
333 }
334
335 trap_group_check_policer()
336 {
337         local group_name=$1; shift
338
339         devlink -j -p trap group show $DEVLINK_DEV group $group_name \
340                 | jq -e '.[][][]["policer"]' &> /dev/null
341 }
342
343 trap_policer_bind_test()
344 {
345         RET=0
346
347         devlink trap group set $DEVLINK_DEV group l2_drops policer 1
348         check_err $? "Failed to bind a valid policer"
349         if [ $(devlink_trap_group_policer_get "l2_drops") -ne 1 ]; then
350                 check_err 1 "Bound policer was not changed"
351         fi
352
353         devlink trap group set $DEVLINK_DEV group l2_drops policer 1337 \
354                 &> /dev/null
355         check_fail $? "Did not get an error for binding a non-existing policer"
356         if [ $(devlink_trap_group_policer_get "l2_drops") -ne 1 ]; then
357                 check_err 1 "Bound policer was changed when should not"
358         fi
359
360         devlink trap group set $DEVLINK_DEV group l2_drops policer 0
361         check_err $? "Failed to unbind a policer when using ID 0"
362         trap_group_check_policer "l2_drops"
363         check_fail $? "Trap group has a policer after unbinding with ID 0"
364
365         devlink trap group set $DEVLINK_DEV group l2_drops policer 1
366         check_err $? "Failed to bind a valid policer"
367
368         devlink trap group set $DEVLINK_DEV group l2_drops nopolicer
369         check_err $? "Failed to unbind a policer when using 'nopolicer' keyword"
370         trap_group_check_policer "l2_drops"
371         check_fail $? "Trap group has a policer after unbinding with 'nopolicer' keyword"
372
373         devlink trap group set $DEVLINK_DEV group l2_drops policer 1
374         check_err $? "Failed to bind a valid policer"
375
376         echo "y"> $DEBUGFS_DIR/fail_trap_group_set
377         devlink trap group set $DEVLINK_DEV group l2_drops policer 2 \
378                 &> /dev/null
379         check_fail $? "Managed to bind a policer when should not"
380         echo "n"> $DEBUGFS_DIR/fail_trap_group_set
381         devlink trap group set $DEVLINK_DEV group l2_drops policer 2
382         check_err $? "Did not manage to bind a policer when should"
383
384         devlink trap group set $DEVLINK_DEV group l2_drops action drop \
385                 policer 1337 &> /dev/null
386         check_fail $? "Did not get an error for partially modified trap group"
387
388         log_test "Trap policer binding"
389 }
390
391 port_del_test()
392 {
393         local group_name
394         local i
395
396         # The test never fails. It is meant to exercise different code paths
397         # and make sure we properly dismantle a port while packets are
398         # in-flight.
399         RET=0
400
401         devlink_traps_enable_all
402
403         for i in $(seq 1 10); do
404                 ip link set dev $NETDEV up
405
406                 sleep $SLEEP_TIME
407
408                 netdevsim_port_destroy
409                 netdevsim_port_create
410                 udevadm settle
411         done
412
413         devlink_traps_disable_all
414
415         log_test "Port delete"
416 }
417
418 dev_del_test()
419 {
420         local group_name
421         local i
422
423         # The test never fails. It is meant to exercise different code paths
424         # and make sure we properly unregister traps while packets are
425         # in-flight.
426         RET=0
427
428         devlink_traps_enable_all
429
430         for i in $(seq 1 10); do
431                 ip link set dev $NETDEV up
432
433                 sleep $SLEEP_TIME
434
435                 cleanup
436                 setup_prepare
437         done
438
439         devlink_traps_disable_all
440
441         log_test "Device delete"
442 }
443
444 netdevsim_dev_create()
445 {
446         echo "$DEV_ADDR 0" > ${NETDEVSIM_PATH}/new_device
447 }
448
449 netdevsim_dev_destroy()
450 {
451         echo "$DEV_ADDR" > ${NETDEVSIM_PATH}/del_device
452 }
453
454 netdevsim_port_create()
455 {
456         echo 1 > ${NETDEVSIM_PATH}/devices/${DEV}/new_port
457 }
458
459 netdevsim_port_destroy()
460 {
461         echo 1 > ${NETDEVSIM_PATH}/devices/${DEV}/del_port
462 }
463
464 setup_prepare()
465 {
466         local netdev
467
468         netdevsim_dev_create
469
470         if [ ! -d "${NETDEVSIM_PATH}/devices/${DEV}" ]; then
471                 echo "Failed to create netdevsim device"
472                 exit 1
473         fi
474
475         netdevsim_port_create
476
477         if [ ! -d "${NETDEVSIM_PATH}/devices/${DEV}/net/" ]; then
478                 echo "Failed to create netdevsim port"
479                 exit 1
480         fi
481
482         # Wait for udev to rename newly created netdev.
483         udevadm settle
484
485         NETDEV=$(ls ${NETDEVSIM_PATH}/devices/${DEV}/net/)
486 }
487
488 cleanup()
489 {
490         pre_cleanup
491         netdevsim_port_destroy
492         netdevsim_dev_destroy
493 }
494
495 trap cleanup EXIT
496
497 setup_prepare
498
499 tests_run
500
501 exit $EXIT_STATUS