Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
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
7lib_dir=$(dirname $0)/../../../net/forwarding
8
9ALL_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"
24NETDEVSIM_PATH=/sys/bus/netdevsim/
25DEV_ADDR=1337
26DEV=netdevsim${DEV_ADDR}
27DEBUGFS_DIR=/sys/kernel/debug/netdevsim/$DEV/
28SLEEP_TIME=1
29NETDEV=""
30NUM_NETIFS=0
31source $lib_dir/lib.sh
32
33DEVLINK_DEV=
34source $lib_dir/devlink_lib.sh
35DEVLINK_DEV=netdevsim/${DEV}
36
37require_command udevadm
38
39modprobe netdevsim &> /dev/null
40if [ ! -d "$NETDEVSIM_PATH" ]; then
41 echo "SKIP: No netdevsim support"
42 exit 1
43fi
44
45if [ -d "${NETDEVSIM_PATH}/devices/netdevsim${DEV_ADDR}" ]; then
46 echo "SKIP: Device netdevsim${DEV_ADDR} already exists"
47 exit 1
48fi
49
50init_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
60trap_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
102trap_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
121bad_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
131bad_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
148trap_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
189trap_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
241bad_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
251trap_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
274trap_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
335trap_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
343trap_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
391port_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
418dev_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
444netdevsim_dev_create()
445{
446 echo "$DEV_ADDR 0" > ${NETDEVSIM_PATH}/new_device
447}
448
449netdevsim_dev_destroy()
450{
451 echo "$DEV_ADDR" > ${NETDEVSIM_PATH}/del_device
452}
453
454netdevsim_port_create()
455{
456 echo 1 > ${NETDEVSIM_PATH}/devices/${DEV}/new_port
457}
458
459netdevsim_port_destroy()
460{
461 echo 1 > ${NETDEVSIM_PATH}/devices/${DEV}/del_port
462}
463
464setup_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
488cleanup()
489{
490 pre_cleanup
491 netdevsim_port_destroy
492 netdevsim_dev_destroy
493}
494
495trap cleanup EXIT
496
497setup_prepare
498
499tests_run
500
501exit $EXIT_STATUS