File Index
Files and directories
Sign in
FILE

devlink_trap.sh

File preview with syntax highlighting.

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