• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3#
4# Test devlink-trap L2 drops functionality over mlxsw. Each registered L2 drop
5# packet trap is tested to make sure it is triggered under the right
6# conditions.
7
8lib_dir=$(dirname $0)/../../../net/forwarding
9
10ALL_TESTS="
11	source_mac_is_multicast_test
12	vlan_tag_mismatch_test
13	ingress_vlan_filter_test
14	ingress_stp_filter_test
15	port_list_is_empty_test
16	port_loopback_filter_test
17"
18NUM_NETIFS=4
19source $lib_dir/tc_common.sh
20source $lib_dir/lib.sh
21source $lib_dir/devlink_lib.sh
22
23h1_create()
24{
25	simple_if_init $h1
26}
27
28h1_destroy()
29{
30	simple_if_fini $h1
31}
32
33h2_create()
34{
35	simple_if_init $h2
36}
37
38h2_destroy()
39{
40	simple_if_fini $h2
41}
42
43switch_create()
44{
45	ip link add dev br0 type bridge vlan_filtering 1 mcast_snooping 0
46
47	ip link set dev $swp1 master br0
48	ip link set dev $swp2 master br0
49
50	ip link set dev br0 up
51	ip link set dev $swp1 up
52	ip link set dev $swp2 up
53
54	tc qdisc add dev $swp2 clsact
55}
56
57switch_destroy()
58{
59	tc qdisc del dev $swp2 clsact
60
61	ip link set dev $swp2 down
62	ip link set dev $swp1 down
63
64	ip link del dev br0
65}
66
67setup_prepare()
68{
69	h1=${NETIFS[p1]}
70	swp1=${NETIFS[p2]}
71
72	swp2=${NETIFS[p3]}
73	h2=${NETIFS[p4]}
74
75	vrf_prepare
76
77	h1_create
78	h2_create
79
80	switch_create
81}
82
83cleanup()
84{
85	pre_cleanup
86
87	switch_destroy
88
89	h2_destroy
90	h1_destroy
91
92	vrf_cleanup
93}
94
95l2_drops_test()
96{
97	local trap_name=$1; shift
98	local group_name=$1; shift
99
100	# This is the common part of all the tests. It checks that stats are
101	# initially idle, then non-idle after changing the trap action and
102	# finally idle again. It also makes sure the packets are dropped and
103	# never forwarded.
104	devlink_trap_stats_idle_test $trap_name
105	check_err $? "Trap stats not idle with initial drop action"
106	devlink_trap_group_stats_idle_test $group_name
107	check_err $? "Trap group stats not idle with initial drop action"
108
109	devlink_trap_action_set $trap_name "trap"
110
111	devlink_trap_stats_idle_test $trap_name
112	check_fail $? "Trap stats idle after setting action to trap"
113	devlink_trap_group_stats_idle_test $group_name
114	check_fail $? "Trap group stats idle after setting action to trap"
115
116	devlink_trap_action_set $trap_name "drop"
117
118	devlink_trap_stats_idle_test $trap_name
119	check_err $? "Trap stats not idle after setting action to drop"
120	devlink_trap_group_stats_idle_test $group_name
121	check_err $? "Trap group stats not idle after setting action to drop"
122
123	tc_check_packets "dev $swp2 egress" 101 0
124	check_err $? "Packets were not dropped"
125}
126
127l2_drops_cleanup()
128{
129	local mz_pid=$1; shift
130
131	kill $mz_pid && wait $mz_pid &> /dev/null
132	tc filter del dev $swp2 egress protocol ip pref 1 handle 101 flower
133}
134
135source_mac_is_multicast_test()
136{
137	local trap_name="source_mac_is_multicast"
138	local smac=01:02:03:04:05:06
139	local group_name="l2_drops"
140	local mz_pid
141
142	tc filter add dev $swp2 egress protocol ip pref 1 handle 101 \
143		flower src_mac $smac action drop
144
145	$MZ $h1 -c 0 -p 100 -a $smac -b bcast -t ip -d 1msec -q &
146	mz_pid=$!
147
148	RET=0
149
150	l2_drops_test $trap_name $group_name
151
152	log_test "Source MAC is multicast"
153
154	l2_drops_cleanup $mz_pid
155}
156
157__vlan_tag_mismatch_test()
158{
159	local trap_name="vlan_tag_mismatch"
160	local dmac=de:ad:be:ef:13:37
161	local group_name="l2_drops"
162	local opt=$1; shift
163	local mz_pid
164
165	# Remove PVID flag. This should prevent untagged and prio-tagged
166	# packets from entering the bridge.
167	bridge vlan add vid 1 dev $swp1 untagged master
168
169	tc filter add dev $swp2 egress protocol ip pref 1 handle 101 \
170		flower dst_mac $dmac action drop
171
172	$MZ $h1 "$opt" -c 0 -p 100 -a own -b $dmac -t ip -d 1msec -q &
173	mz_pid=$!
174
175	l2_drops_test $trap_name $group_name
176
177	# Add PVID and make sure packets are no longer dropped.
178	bridge vlan add vid 1 dev $swp1 pvid untagged master
179	devlink_trap_action_set $trap_name "trap"
180
181	devlink_trap_stats_idle_test $trap_name
182	check_err $? "Trap stats not idle when packets should not be dropped"
183	devlink_trap_group_stats_idle_test $group_name
184	check_err $? "Trap group stats not idle with when packets should not be dropped"
185
186	tc_check_packets "dev $swp2 egress" 101 0
187	check_fail $? "Packets not forwarded when should"
188
189	devlink_trap_action_set $trap_name "drop"
190
191	l2_drops_cleanup $mz_pid
192}
193
194vlan_tag_mismatch_untagged_test()
195{
196	RET=0
197
198	__vlan_tag_mismatch_test
199
200	log_test "VLAN tag mismatch - untagged packets"
201}
202
203vlan_tag_mismatch_vid_0_test()
204{
205	RET=0
206
207	__vlan_tag_mismatch_test "-Q 0"
208
209	log_test "VLAN tag mismatch - prio-tagged packets"
210}
211
212vlan_tag_mismatch_test()
213{
214	vlan_tag_mismatch_untagged_test
215	vlan_tag_mismatch_vid_0_test
216}
217
218ingress_vlan_filter_test()
219{
220	local trap_name="ingress_vlan_filter"
221	local dmac=de:ad:be:ef:13:37
222	local group_name="l2_drops"
223	local mz_pid
224	local vid=10
225
226	bridge vlan add vid $vid dev $swp2 master
227
228	RET=0
229
230	tc filter add dev $swp2 egress protocol ip pref 1 handle 101 \
231		flower dst_mac $dmac action drop
232
233	$MZ $h1 -Q $vid -c 0 -p 100 -a own -b $dmac -t ip -d 1msec -q &
234	mz_pid=$!
235
236	l2_drops_test $trap_name $group_name
237
238	# Add the VLAN on the bridge port and make sure packets are no longer
239	# dropped.
240	bridge vlan add vid $vid dev $swp1 master
241	devlink_trap_action_set $trap_name "trap"
242
243	devlink_trap_stats_idle_test $trap_name
244	check_err $? "Trap stats not idle when packets should not be dropped"
245	devlink_trap_group_stats_idle_test $group_name
246	check_err $? "Trap group stats not idle with when packets should not be dropped"
247
248	tc_check_packets "dev $swp2 egress" 101 0
249	check_fail $? "Packets not forwarded when should"
250
251	devlink_trap_action_set $trap_name "drop"
252
253	log_test "Ingress VLAN filter"
254
255	l2_drops_cleanup $mz_pid
256
257	bridge vlan del vid $vid dev $swp1 master
258	bridge vlan del vid $vid dev $swp2 master
259}
260
261__ingress_stp_filter_test()
262{
263	local trap_name="ingress_spanning_tree_filter"
264	local dmac=de:ad:be:ef:13:37
265	local group_name="l2_drops"
266	local state=$1; shift
267	local mz_pid
268	local vid=20
269
270	bridge vlan add vid $vid dev $swp2 master
271	bridge vlan add vid $vid dev $swp1 master
272	ip link set dev $swp1 type bridge_slave state $state
273
274	tc filter add dev $swp2 egress protocol ip pref 1 handle 101 \
275		flower dst_mac $dmac action drop
276
277	$MZ $h1 -Q $vid -c 0 -p 100 -a own -b $dmac -t ip -d 1msec -q &
278	mz_pid=$!
279
280	l2_drops_test $trap_name $group_name
281
282	# Change STP state to forwarding and make sure packets are no longer
283	# dropped.
284	ip link set dev $swp1 type bridge_slave state 3
285	devlink_trap_action_set $trap_name "trap"
286
287	devlink_trap_stats_idle_test $trap_name
288	check_err $? "Trap stats not idle when packets should not be dropped"
289	devlink_trap_group_stats_idle_test $group_name
290	check_err $? "Trap group stats not idle with when packets should not be dropped"
291
292	tc_check_packets "dev $swp2 egress" 101 0
293	check_fail $? "Packets not forwarded when should"
294
295	devlink_trap_action_set $trap_name "drop"
296
297	l2_drops_cleanup $mz_pid
298
299	bridge vlan del vid $vid dev $swp1 master
300	bridge vlan del vid $vid dev $swp2 master
301}
302
303ingress_stp_filter_listening_test()
304{
305	local state=$1; shift
306
307	RET=0
308
309	__ingress_stp_filter_test $state
310
311	log_test "Ingress STP filter - listening state"
312}
313
314ingress_stp_filter_learning_test()
315{
316	local state=$1; shift
317
318	RET=0
319
320	__ingress_stp_filter_test $state
321
322	log_test "Ingress STP filter - learning state"
323}
324
325ingress_stp_filter_test()
326{
327	ingress_stp_filter_listening_test 1
328	ingress_stp_filter_learning_test 2
329}
330
331port_list_is_empty_uc_test()
332{
333	local trap_name="port_list_is_empty"
334	local dmac=de:ad:be:ef:13:37
335	local group_name="l2_drops"
336	local mz_pid
337
338	# Disable unicast flooding on both ports, so that packets cannot egress
339	# any port.
340	ip link set dev $swp1 type bridge_slave flood off
341	ip link set dev $swp2 type bridge_slave flood off
342
343	RET=0
344
345	tc filter add dev $swp2 egress protocol ip pref 1 handle 101 \
346		flower dst_mac $dmac action drop
347
348	$MZ $h1 -c 0 -p 100 -a own -b $dmac -t ip -d 1msec -q &
349	mz_pid=$!
350
351	l2_drops_test $trap_name $group_name
352
353	# Allow packets to be flooded to one port.
354	ip link set dev $swp2 type bridge_slave flood on
355	devlink_trap_action_set $trap_name "trap"
356
357	devlink_trap_stats_idle_test $trap_name
358	check_err $? "Trap stats not idle when packets should not be dropped"
359	devlink_trap_group_stats_idle_test $group_name
360	check_err $? "Trap group stats not idle with when packets should not be dropped"
361
362	tc_check_packets "dev $swp2 egress" 101 0
363	check_fail $? "Packets not forwarded when should"
364
365	devlink_trap_action_set $trap_name "drop"
366
367	log_test "Port list is empty - unicast"
368
369	l2_drops_cleanup $mz_pid
370
371	ip link set dev $swp1 type bridge_slave flood on
372}
373
374port_list_is_empty_mc_test()
375{
376	local trap_name="port_list_is_empty"
377	local dmac=01:00:5e:00:00:01
378	local group_name="l2_drops"
379	local dip=239.0.0.1
380	local mz_pid
381
382	# Disable multicast flooding on both ports, so that packets cannot
383	# egress any port. We also need to flush IP addresses from the bridge
384	# in order to prevent packets from being flooded to the router port.
385	ip link set dev $swp1 type bridge_slave mcast_flood off
386	ip link set dev $swp2 type bridge_slave mcast_flood off
387	ip address flush dev br0
388
389	RET=0
390
391	tc filter add dev $swp2 egress protocol ip pref 1 handle 101 \
392		flower dst_mac $dmac action drop
393
394	$MZ $h1 -c 0 -p 100 -a own -b $dmac -t ip -B $dip -d 1msec -q &
395	mz_pid=$!
396
397	l2_drops_test $trap_name $group_name
398
399	# Allow packets to be flooded to one port.
400	ip link set dev $swp2 type bridge_slave mcast_flood on
401	devlink_trap_action_set $trap_name "trap"
402
403	devlink_trap_stats_idle_test $trap_name
404	check_err $? "Trap stats not idle when packets should not be dropped"
405	devlink_trap_group_stats_idle_test $group_name
406	check_err $? "Trap group stats not idle with when packets should not be dropped"
407
408	tc_check_packets "dev $swp2 egress" 101 0
409	check_fail $? "Packets not forwarded when should"
410
411	devlink_trap_action_set $trap_name "drop"
412
413	log_test "Port list is empty - multicast"
414
415	l2_drops_cleanup $mz_pid
416
417	ip link set dev $swp1 type bridge_slave mcast_flood on
418}
419
420port_list_is_empty_test()
421{
422	port_list_is_empty_uc_test
423	port_list_is_empty_mc_test
424}
425
426port_loopback_filter_uc_test()
427{
428	local trap_name="port_loopback_filter"
429	local dmac=de:ad:be:ef:13:37
430	local group_name="l2_drops"
431	local mz_pid
432
433	# Make sure packets can only egress the input port.
434	ip link set dev $swp2 type bridge_slave flood off
435
436	RET=0
437
438	tc filter add dev $swp2 egress protocol ip pref 1 handle 101 \
439		flower dst_mac $dmac action drop
440
441	$MZ $h1 -c 0 -p 100 -a own -b $dmac -t ip -d 1msec -q &
442	mz_pid=$!
443
444	l2_drops_test $trap_name $group_name
445
446	# Allow packets to be flooded.
447	ip link set dev $swp2 type bridge_slave flood on
448	devlink_trap_action_set $trap_name "trap"
449
450	devlink_trap_stats_idle_test $trap_name
451	check_err $? "Trap stats not idle when packets should not be dropped"
452	devlink_trap_group_stats_idle_test $group_name
453	check_err $? "Trap group stats not idle with when packets should not be dropped"
454
455	tc_check_packets "dev $swp2 egress" 101 0
456	check_fail $? "Packets not forwarded when should"
457
458	devlink_trap_action_set $trap_name "drop"
459
460	log_test "Port loopback filter - unicast"
461
462	l2_drops_cleanup $mz_pid
463}
464
465port_loopback_filter_test()
466{
467	port_loopback_filter_uc_test
468}
469
470trap cleanup EXIT
471
472setup_prepare
473setup_wait
474
475tests_run
476
477exit $EXIT_STATUS
478