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