1# SPDX-License-Identifier: GPL-2.0
2
3# This test sends a >1Gbps stream of traffic from H1, to the switch, which
4# forwards it to a 1Gbps port. This 1Gbps stream is then looped back to the
5# switch and forwarded to the port under test $swp3, which is also 1Gbps.
6#
7# This way, $swp3 should be 100% filled with traffic without any of it spilling
8# to the backlog. Any extra packets sent should almost 1:1 go to backlog. That
9# is what H2 is used for--it sends the extra traffic to create backlog.
10#
11# A RED Qdisc is installed on $swp3. The configuration is such that the minimum
12# and maximum size are 1 byte apart, so there is a very clear border under which
13# no marking or dropping takes place, and above which everything is marked or
14# dropped.
15#
16# The test uses the buffer build-up behavior to test the installed RED.
17#
18# In order to test WRED, $swp3 actually contains RED under PRIO, with two
19# different configurations. Traffic is prioritized using 802.1p and relies on
20# the implicit mlxsw configuration, where packet priority is taken 1:1 from the
21# 802.1p marking.
22#
23# +--------------------------+                     +--------------------------+
24# | H1                       |                     | H2                       |
25# |     + $h1.10             |                     |     + $h2.10             |
26# |     | 192.0.2.1/28       |                     |     | 192.0.2.2/28       |
27# |     |                    |                     |     |                    |
28# |     |         $h1.11 +   |                     |     |         $h2.11 +   |
29# |     |  192.0.2.17/28 |   |                     |     |  192.0.2.18/28 |   |
30# |     |                |   |                     |     |                |   |
31# |     \______    ______/   |                     |     \______    ______/   |
32# |            \ /           |                     |            \ /           |
33# |             + $h1        |                     |             + $h2        |
34# +-------------|------------+                     +-------------|------------+
35#               | >1Gbps                                         |
36# +-------------|------------------------------------------------|------------+
37# | SW          + $swp1                                          + $swp2      |
38# |     _______/ \___________                        ___________/ \_______    |
39# |    /                     \                      /                     \   |
40# |  +-|-----------------+   |                    +-|-----------------+   |   |
41# |  | + $swp1.10        |   |                    | + $swp2.10        |   |   |
42# |  |                   |   |        .-------------+ $swp5.10        |   |   |
43# |  |     BR1_10        |   |        |           |                   |   |   |
44# |  |                   |   |        |           |     BR2_10        |   |   |
45# |  | + $swp2.10        |   |        |           |                   |   |   |
46# |  +-|-----------------+   |        |           | + $swp3.10        |   |   |
47# |    |                     |        |           +-|-----------------+   |   |
48# |    |   +-----------------|-+      |             |   +-----------------|-+ |
49# |    |   |        $swp1.11 + |      |             |   |        $swp2.11 + | |
50# |    |   |                   |      | .-----------------+ $swp5.11        | |
51# |    |   |      BR1_11       |      | |           |   |                   | |
52# |    |   |                   |      | |           |   |      BR2_11       | |
53# |    |   |        $swp2.11 + |      | |           |   |                   | |
54# |    |   +-----------------|-+      | |           |   |        $swp3.11 + | |
55# |    |                     |        | |           |   +-----------------|-+ |
56# |    \_______   ___________/        | |           \___________   _______/   |
57# |            \ /                    \ /                       \ /           |
58# |             + $swp4                + $swp5                   + $swp3      |
59# +-------------|----------------------|-------------------------|------------+
60#               |                      |                         | 1Gbps
61#               \________1Gbps_________/                         |
62#                                   +----------------------------|------------+
63#                                   | H3                         + $h3        |
64#                                   |      _____________________/ \_______    |
65#                                   |     /                               \   |
66#                                   |     |                               |   |
67#                                   |     + $h3.10                 $h3.11 +   |
68#                                   |       192.0.2.3/28    192.0.2.19/28     |
69#                                   +-----------------------------------------+
70
71NUM_NETIFS=8
72CHECK_TC="yes"
73lib_dir=$(dirname $0)/../../../net/forwarding
74source $lib_dir/lib.sh
75source $lib_dir/devlink_lib.sh
76source mlxsw_lib.sh
77
78ipaddr()
79{
80	local host=$1; shift
81	local vlan=$1; shift
82
83	echo 192.0.2.$((16 * (vlan - 10) + host))
84}
85
86host_create()
87{
88	local dev=$1; shift
89	local host=$1; shift
90
91	simple_if_init $dev
92	mtu_set $dev 10000
93
94	vlan_create $dev 10 v$dev $(ipaddr $host 10)/28
95	ip link set dev $dev.10 type vlan egress 0:0
96
97	vlan_create $dev 11 v$dev $(ipaddr $host 11)/28
98	ip link set dev $dev.11 type vlan egress 0:1
99}
100
101host_destroy()
102{
103	local dev=$1; shift
104
105	vlan_destroy $dev 11
106	vlan_destroy $dev 10
107	mtu_restore $dev
108	simple_if_fini $dev
109}
110
111h1_create()
112{
113	host_create $h1 1
114}
115
116h1_destroy()
117{
118	host_destroy $h1
119}
120
121h2_create()
122{
123	host_create $h2 2
124	tc qdisc add dev $h2 clsact
125
126	# Some of the tests in this suite use multicast traffic. As this traffic
127	# enters BR2_10 resp. BR2_11, it is flooded to all other ports. Thus
128	# e.g. traffic ingressing through $swp2 is flooded to $swp3 (the
129	# intended destination) and $swp5 (which is intended as ingress for
130	# another stream of traffic).
131	#
132	# This is generally not a problem, but if the $swp5 throughput is lower
133	# than $swp2 throughput, there will be a build-up at $swp5. That may
134	# cause packets to fail to queue up at $swp3 due to shared buffer
135	# quotas, and the test to spuriously fail.
136	#
137	# Prevent this by adding a shaper which limits the traffic in $h2 to
138	# 1Gbps.
139
140	tc qdisc replace dev $h2 root handle 10: tbf rate 1gbit \
141		burst 128K limit 1G
142}
143
144h2_destroy()
145{
146	tc qdisc del dev $h2 root handle 10:
147	tc qdisc del dev $h2 clsact
148	host_destroy $h2
149}
150
151h3_create()
152{
153	host_create $h3 3
154}
155
156h3_destroy()
157{
158	host_destroy $h3
159}
160
161switch_create()
162{
163	local intf
164	local vlan
165
166	ip link add dev br1_10 type bridge
167	ip link add dev br1_11 type bridge
168
169	ip link add dev br2_10 type bridge
170	ip link add dev br2_11 type bridge
171
172	for intf in $swp1 $swp2 $swp3 $swp4 $swp5; do
173		ip link set dev $intf up
174		mtu_set $intf 10000
175	done
176
177	for intf in $swp1 $swp4; do
178		for vlan in 10 11; do
179			vlan_create $intf $vlan
180			ip link set dev $intf.$vlan master br1_$vlan
181			ip link set dev $intf.$vlan up
182		done
183	done
184
185	for intf in $swp2 $swp3 $swp5; do
186		for vlan in 10 11; do
187			vlan_create $intf $vlan
188			ip link set dev $intf.$vlan master br2_$vlan
189			ip link set dev $intf.$vlan up
190		done
191	done
192
193	ip link set dev $swp4.10 type vlan egress 0:0
194	ip link set dev $swp4.11 type vlan egress 0:1
195	for intf in $swp1 $swp2 $swp5; do
196		for vlan in 10 11; do
197			ip link set dev $intf.$vlan type vlan ingress 0:0 1:1
198		done
199	done
200
201	for intf in $swp3 $swp4; do
202		tc qdisc replace dev $intf root handle 1: tbf rate 1gbit \
203			burst 128K limit 1G
204	done
205
206	ip link set dev br1_10 up
207	ip link set dev br1_11 up
208	ip link set dev br2_10 up
209	ip link set dev br2_11 up
210
211	local size=$(devlink_pool_size_thtype 0 | cut -d' ' -f 1)
212	devlink_port_pool_th_save $swp3 8
213	devlink_port_pool_th_set $swp3 8 $size
214}
215
216switch_destroy()
217{
218	local intf
219	local vlan
220
221	devlink_port_pool_th_restore $swp3 8
222
223	ip link set dev br2_11 down
224	ip link set dev br2_10 down
225	ip link set dev br1_11 down
226	ip link set dev br1_10 down
227
228	for intf in $swp4 $swp3; do
229		tc qdisc del dev $intf root handle 1:
230	done
231
232	for intf in $swp5 $swp3 $swp2 $swp4 $swp1; do
233		for vlan in 11 10; do
234			ip link set dev $intf.$vlan down
235			ip link set dev $intf.$vlan nomaster
236			vlan_destroy $intf $vlan
237		done
238
239		mtu_restore $intf
240		ip link set dev $intf down
241	done
242
243	ip link del dev br2_11
244	ip link del dev br2_10
245	ip link del dev br1_11
246	ip link del dev br1_10
247}
248
249setup_prepare()
250{
251	h1=${NETIFS[p1]}
252	swp1=${NETIFS[p2]}
253
254	swp2=${NETIFS[p3]}
255	h2=${NETIFS[p4]}
256
257	swp3=${NETIFS[p5]}
258	h3=${NETIFS[p6]}
259
260	swp4=${NETIFS[p7]}
261	swp5=${NETIFS[p8]}
262
263	h3_mac=$(mac_get $h3)
264
265	vrf_prepare
266
267	h1_create
268	h2_create
269	h3_create
270	switch_create
271}
272
273cleanup()
274{
275	pre_cleanup
276
277	switch_destroy
278	h3_destroy
279	h2_destroy
280	h1_destroy
281
282	vrf_cleanup
283}
284
285ping_ipv4()
286{
287	ping_test $h1.10 $(ipaddr 3 10) " from host 1, vlan 10"
288	ping_test $h1.11 $(ipaddr 3 11) " from host 1, vlan 11"
289	ping_test $h2.10 $(ipaddr 3 10) " from host 2, vlan 10"
290	ping_test $h2.11 $(ipaddr 3 11) " from host 2, vlan 11"
291}
292
293get_tc()
294{
295	local vlan=$1; shift
296
297	echo $((vlan - 10))
298}
299
300get_qdisc_handle()
301{
302	local vlan=$1; shift
303
304	local tc=$(get_tc $vlan)
305	local band=$((8 - tc))
306
307	# Handle is 107: for TC1, 108: for TC0.
308	echo "10$band:"
309}
310
311get_qdisc_backlog()
312{
313	local vlan=$1; shift
314
315	qdisc_stats_get $swp3 $(get_qdisc_handle $vlan) .backlog
316}
317
318get_mc_transmit_queue()
319{
320	local vlan=$1; shift
321
322	local tc=$(($(get_tc $vlan) + 8))
323	ethtool_stats_get $swp3 tc_transmit_queue_tc_$tc
324}
325
326get_nmarked()
327{
328	local vlan=$1; shift
329
330	ethtool_stats_get $swp3 ecn_marked
331}
332
333get_qdisc_nmarked()
334{
335	local vlan=$1; shift
336
337	busywait_for_counter 1100 +1 \
338		qdisc_stats_get $swp3 $(get_qdisc_handle $vlan) .marked
339}
340
341get_qdisc_npackets()
342{
343	local vlan=$1; shift
344
345	busywait_for_counter 1100 +1 \
346		qdisc_stats_get $swp3 $(get_qdisc_handle $vlan) .packets
347}
348
349send_packets()
350{
351	local vlan=$1; shift
352	local proto=$1; shift
353	local pkts=$1; shift
354
355	$MZ $h2.$vlan -p 8000 -a own -b $h3_mac \
356	    -A $(ipaddr 2 $vlan) -B $(ipaddr 3 $vlan) \
357	    -t $proto -q -c $pkts "$@"
358}
359
360# This sends traffic in an attempt to build a backlog of $size. Returns 0 on
361# success. After 10 failed attempts it bails out and returns 1. It dumps the
362# backlog size to stdout.
363build_backlog()
364{
365	local vlan=$1; shift
366	local size=$1; shift
367	local proto=$1; shift
368
369	local tc=$((vlan - 10))
370	local band=$((8 - tc))
371	local cur=-1
372	local i=0
373
374	while :; do
375		local cur=$(busywait 1100 until_counter_is "> $cur" \
376					    get_qdisc_backlog $vlan)
377		local diff=$((size - cur))
378		local pkts=$(((diff + 7999) / 8000))
379
380		if ((cur >= size)); then
381			echo $cur
382			return 0
383		elif ((i++ > 10)); then
384			echo $cur
385			return 1
386		fi
387
388		send_packets $vlan $proto $pkts "$@"
389	done
390}
391
392check_marking()
393{
394	local get_nmarked=$1; shift
395	local vlan=$1; shift
396	local cond=$1; shift
397
398	local npackets_0=$(get_qdisc_npackets $vlan)
399	local nmarked_0=$($get_nmarked $vlan)
400	sleep 5
401	local npackets_1=$(get_qdisc_npackets $vlan)
402	local nmarked_1=$($get_nmarked $vlan)
403
404	local nmarked_d=$((nmarked_1 - nmarked_0))
405	local npackets_d=$((npackets_1 - npackets_0))
406	local pct=$((100 * nmarked_d / npackets_d))
407
408	echo $pct
409	((pct $cond))
410}
411
412ecn_test_common()
413{
414	local name=$1; shift
415	local get_nmarked=$1; shift
416	local vlan=$1; shift
417	local limit=$1; shift
418	local backlog
419	local pct
420
421	# Build the below-the-limit backlog using UDP. We could use TCP just
422	# fine, but this way we get a proof that UDP is accepted when queue
423	# length is below the limit. The main stream is using TCP, and if the
424	# limit is misconfigured, we would see this traffic being ECN marked.
425	RET=0
426	backlog=$(build_backlog $vlan $((2 * limit / 3)) udp)
427	check_err $? "Could not build the requested backlog"
428	pct=$(check_marking "$get_nmarked" $vlan "== 0")
429	check_err $? "backlog $backlog / $limit Got $pct% marked packets, expected == 0."
430	log_test "TC $((vlan - 10)): $name backlog < limit"
431
432	# Now push TCP, because non-TCP traffic would be early-dropped after the
433	# backlog crosses the limit, and we want to make sure that the backlog
434	# is above the limit.
435	RET=0
436	backlog=$(build_backlog $vlan $((3 * limit / 2)) tcp tos=0x01)
437	check_err $? "Could not build the requested backlog"
438	pct=$(check_marking "$get_nmarked" $vlan ">= 95")
439	check_err $? "backlog $backlog / $limit Got $pct% marked packets, expected >= 95."
440	log_test "TC $((vlan - 10)): $name backlog > limit"
441}
442
443__do_ecn_test()
444{
445	local get_nmarked=$1; shift
446	local vlan=$1; shift
447	local limit=$1; shift
448	local name=${1-ECN}; shift
449
450	start_tcp_traffic $h1.$vlan $(ipaddr 1 $vlan) $(ipaddr 3 $vlan) \
451			  $h3_mac tos=0x01
452	sleep 1
453
454	ecn_test_common "$name" "$get_nmarked" $vlan $limit
455
456	# Up there we saw that UDP gets accepted when backlog is below the
457	# limit. Now that it is above, it should all get dropped, and backlog
458	# building should fail.
459	RET=0
460	build_backlog $vlan $((2 * limit)) udp >/dev/null
461	check_fail $? "UDP traffic went into backlog instead of being early-dropped"
462	log_test "TC $((vlan - 10)): $name backlog > limit: UDP early-dropped"
463
464	stop_traffic
465	sleep 1
466}
467
468do_ecn_test()
469{
470	local vlan=$1; shift
471	local limit=$1; shift
472
473	__do_ecn_test get_nmarked "$vlan" "$limit"
474}
475
476do_ecn_test_perband()
477{
478	local vlan=$1; shift
479	local limit=$1; shift
480
481	mlxsw_only_on_spectrum 3+ || return
482	__do_ecn_test get_qdisc_nmarked "$vlan" "$limit" "per-band ECN"
483}
484
485do_ecn_nodrop_test()
486{
487	local vlan=$1; shift
488	local limit=$1; shift
489	local name="ECN nodrop"
490
491	start_tcp_traffic $h1.$vlan $(ipaddr 1 $vlan) $(ipaddr 3 $vlan) \
492			  $h3_mac tos=0x01
493	sleep 1
494
495	ecn_test_common "$name" get_nmarked $vlan $limit
496
497	# Up there we saw that UDP gets accepted when backlog is below the
498	# limit. Now that it is above, in nodrop mode, make sure it goes to
499	# backlog as well.
500	RET=0
501	build_backlog $vlan $((2 * limit)) udp >/dev/null
502	check_err $? "UDP traffic was early-dropped instead of getting into backlog"
503	log_test "TC $((vlan - 10)): $name backlog > limit: UDP not dropped"
504
505	stop_traffic
506	sleep 1
507}
508
509do_red_test()
510{
511	local vlan=$1; shift
512	local limit=$1; shift
513	local backlog
514	local pct
515
516	# Use ECN-capable TCP to verify there's no marking even though the queue
517	# is above limit.
518	start_tcp_traffic $h1.$vlan $(ipaddr 1 $vlan) $(ipaddr 3 $vlan) \
519			  $h3_mac tos=0x01
520
521	# Pushing below the queue limit should work.
522	RET=0
523	backlog=$(build_backlog $vlan $((2 * limit / 3)) tcp tos=0x01)
524	check_err $? "Could not build the requested backlog"
525	pct=$(check_marking get_nmarked $vlan "== 0")
526	check_err $? "backlog $backlog / $limit Got $pct% marked packets, expected == 0."
527	log_test "TC $((vlan - 10)): RED backlog < limit"
528
529	# Pushing above should not.
530	RET=0
531	backlog=$(build_backlog $vlan $((3 * limit / 2)) tcp tos=0x01)
532	check_fail $? "Traffic went into backlog instead of being early-dropped"
533	pct=$(check_marking get_nmarked $vlan "== 0")
534	check_err $? "backlog $backlog / $limit Got $pct% marked packets, expected == 0."
535	local diff=$((limit - backlog))
536	pct=$((100 * diff / limit))
537	((-10 <= pct && pct <= 10))
538	check_err $? "backlog $backlog / $limit expected <= 10% distance"
539	log_test "TC $((vlan - 10)): RED backlog > limit"
540
541	stop_traffic
542	sleep 1
543}
544
545do_mc_backlog_test()
546{
547	local vlan=$1; shift
548	local limit=$1; shift
549	local backlog
550	local pct
551
552	RET=0
553
554	start_tcp_traffic $h1.$vlan $(ipaddr 1 $vlan) $(ipaddr 3 $vlan) bc
555	start_tcp_traffic $h2.$vlan $(ipaddr 2 $vlan) $(ipaddr 3 $vlan) bc
556
557	qbl=$(busywait 5000 until_counter_is ">= 500000" \
558		       get_qdisc_backlog $vlan)
559	check_err $? "Could not build MC backlog"
560
561	# Verify that we actually see the backlog on BUM TC. Do a busywait as
562	# well, performance blips might cause false fail.
563	local ebl
564	ebl=$(busywait 5000 until_counter_is ">= 500000" \
565		       get_mc_transmit_queue $vlan)
566	check_err $? "MC backlog reported by qdisc not visible in ethtool"
567
568	stop_traffic
569	stop_traffic
570
571	log_test "TC $((vlan - 10)): Qdisc reports MC backlog"
572}
573
574do_mark_test()
575{
576	local vlan=$1; shift
577	local limit=$1; shift
578	local subtest=$1; shift
579	local fetch_counter=$1; shift
580	local should_fail=$1; shift
581	local base
582
583	mlxsw_only_on_spectrum 2+ || return
584
585	RET=0
586
587	start_tcp_traffic $h1.$vlan $(ipaddr 1 $vlan) $(ipaddr 3 $vlan) \
588			  $h3_mac tos=0x01
589
590	# Create a bit of a backlog and observe no mirroring due to marks.
591	qevent_rule_install_$subtest
592
593	build_backlog $vlan $((2 * limit / 3)) tcp tos=0x01 >/dev/null
594
595	base=$($fetch_counter)
596	count=$(busywait 1100 until_counter_is ">= $((base + 1))" \
597		$fetch_counter)
598	check_fail $? "Spurious packets ($base -> $count) observed without buffer pressure"
599
600	# Above limit, everything should be mirrored, we should see lots of
601	# packets.
602	build_backlog $vlan $((3 * limit / 2)) tcp tos=0x01 >/dev/null
603	busywait_for_counter 1100 +10000 \
604		 $fetch_counter > /dev/null
605	check_err_fail "$should_fail" $? "ECN-marked packets $subtest'd"
606
607	# When the rule is uninstalled, there should be no mirroring.
608	qevent_rule_uninstall_$subtest
609	busywait_for_counter 1100 +10 \
610		 $fetch_counter > /dev/null
611	check_fail $? "Spurious packets observed after uninstall"
612
613	if ((should_fail)); then
614		log_test "TC $((vlan - 10)): marked packets not $subtest'd"
615	else
616		log_test "TC $((vlan - 10)): marked packets $subtest'd"
617	fi
618
619	stop_traffic
620	sleep 1
621}
622
623do_drop_test()
624{
625	local vlan=$1; shift
626	local limit=$1; shift
627	local trigger=$1; shift
628	local subtest=$1; shift
629	local fetch_counter=$1; shift
630	local base
631	local now
632
633	mlxsw_only_on_spectrum 2+ || return
634
635	RET=0
636
637	start_traffic $h1.$vlan $(ipaddr 1 $vlan) $(ipaddr 3 $vlan) $h3_mac
638
639	# Create a bit of a backlog and observe no mirroring due to drops.
640	qevent_rule_install_$subtest
641	base=$($fetch_counter)
642
643	build_backlog $vlan $((2 * limit / 3)) udp >/dev/null
644
645	busywait 1100 until_counter_is ">= $((base + 1))" $fetch_counter >/dev/null
646	check_fail $? "Spurious packets observed without buffer pressure"
647
648	# Push to the queue until it's at the limit. The configured limit is
649	# rounded by the qdisc and then by the driver, so this is the best we
650	# can do to get to the real limit of the system.
651	build_backlog $vlan $((3 * limit / 2)) udp >/dev/null
652
653	base=$($fetch_counter)
654	send_packets $vlan udp 11
655
656	now=$(busywait 1100 until_counter_is ">= $((base + 10))" $fetch_counter)
657	check_err $? "Dropped packets not observed: 11 expected, $((now - base)) seen"
658
659	# When no extra traffic is injected, there should be no mirroring.
660	busywait 1100 until_counter_is ">= $((base + 20))" $fetch_counter >/dev/null
661	check_fail $? "Spurious packets observed"
662
663	# When the rule is uninstalled, there should be no mirroring.
664	qevent_rule_uninstall_$subtest
665	send_packets $vlan udp 11
666	busywait 1100 until_counter_is ">= $((base + 20))" $fetch_counter >/dev/null
667	check_fail $? "Spurious packets observed after uninstall"
668
669	log_test "TC $((vlan - 10)): ${trigger}ped packets $subtest'd"
670
671	stop_traffic
672	sleep 1
673}
674
675qevent_rule_install_mirror()
676{
677	tc filter add block 10 pref 1234 handle 102 matchall skip_sw \
678	   action mirred egress mirror dev $swp2 hw_stats disabled
679}
680
681qevent_rule_uninstall_mirror()
682{
683	tc filter del block 10 pref 1234 handle 102 matchall
684}
685
686qevent_counter_fetch_mirror()
687{
688	tc_rule_handle_stats_get "dev $h2 ingress" 101
689}
690
691do_drop_mirror_test()
692{
693	local vlan=$1; shift
694	local limit=$1; shift
695	local qevent_name=$1; shift
696
697	tc filter add dev $h2 ingress pref 1 handle 101 prot ip \
698	   flower skip_sw ip_proto udp \
699	   action drop
700
701	do_drop_test "$vlan" "$limit" "$qevent_name" mirror \
702		     qevent_counter_fetch_mirror
703
704	tc filter del dev $h2 ingress pref 1 handle 101 flower
705}
706
707do_mark_mirror_test()
708{
709	local vlan=$1; shift
710	local limit=$1; shift
711
712	tc filter add dev $h2 ingress pref 1 handle 101 prot ip \
713	   flower skip_sw ip_proto tcp \
714	   action drop
715
716	do_mark_test "$vlan" "$limit" mirror \
717		     qevent_counter_fetch_mirror \
718		     $(: should_fail=)0
719
720	tc filter del dev $h2 ingress pref 1 handle 101 flower
721}
722
723qevent_rule_install_trap()
724{
725	tc filter add block 10 pref 1234 handle 102 matchall skip_sw \
726	   action trap hw_stats disabled
727}
728
729qevent_rule_uninstall_trap()
730{
731	tc filter del block 10 pref 1234 handle 102 matchall
732}
733
734qevent_counter_fetch_trap()
735{
736	local trap_name=$1; shift
737
738	devlink_trap_rx_packets_get "$trap_name"
739}
740
741do_drop_trap_test()
742{
743	local vlan=$1; shift
744	local limit=$1; shift
745	local trap_name=$1; shift
746
747	do_drop_test "$vlan" "$limit" "$trap_name" trap \
748		     "qevent_counter_fetch_trap $trap_name"
749}
750
751qevent_rule_install_trap_fwd()
752{
753	tc filter add block 10 pref 1234 handle 102 matchall skip_sw \
754	   action trap_fwd hw_stats disabled
755}
756
757qevent_rule_uninstall_trap_fwd()
758{
759	tc filter del block 10 pref 1234 handle 102 matchall
760}
761