1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3#
4# Test various interface configuration scenarios. Observe that configurations
5# deemed valid by mlxsw succeed, invalid configurations fail and that no traces
6# are produced. To prevent the test from passing in case traces are produced,
7# the user can set the 'kernel.panic_on_warn' and 'kernel.panic_on_oops'
8# sysctls in its environment.
9
10lib_dir=$(dirname $0)/../../../net/forwarding
11
12ALL_TESTS="
13	rif_set_addr_test
14	rif_inherit_bridge_addr_test
15	rif_non_inherit_bridge_addr_test
16	vlan_interface_deletion_test
17	bridge_deletion_test
18	bridge_vlan_flags_test
19	vlan_1_test
20	lag_bridge_upper_test
21	duplicate_vlans_test
22	vlan_rif_refcount_test
23	subport_rif_refcount_test
24	vlan_dev_deletion_test
25	lag_unlink_slaves_test
26	lag_dev_deletion_test
27	vlan_interface_uppers_test
28	bridge_extern_learn_test
29	devlink_reload_test
30"
31NUM_NETIFS=2
32source $lib_dir/lib.sh
33source $lib_dir/devlink_lib.sh
34
35setup_prepare()
36{
37	swp1=${NETIFS[p1]}
38	swp2=${NETIFS[p2]}
39
40	ip link set dev $swp1 up
41	ip link set dev $swp2 up
42}
43
44cleanup()
45{
46	pre_cleanup
47
48	ip link set dev $swp2 down
49	ip link set dev $swp1 down
50}
51
52rif_set_addr_test()
53{
54	local swp1_mac=$(mac_get $swp1)
55	local swp2_mac=$(mac_get $swp2)
56
57	RET=0
58
59	# $swp1 and $swp2 likely got their IPv6 local addresses already, but
60	# here we need to test the transition to RIF.
61	ip addr flush dev $swp1
62	ip addr flush dev $swp2
63	sleep .1
64
65	ip addr add dev $swp1 192.0.2.1/28
66	check_err $?
67
68	ip link set dev $swp1 addr 00:11:22:33:44:55
69	check_err $?
70
71	# IP address enablement should be rejected if the MAC address prefix
72	# doesn't match other RIFs.
73	ip addr add dev $swp2 192.0.2.2/28 &>/dev/null
74	check_fail $? "IP address addition passed for a device with a wrong MAC"
75	ip addr add dev $swp2 192.0.2.2/28 2>&1 >/dev/null \
76	    | grep -q mlxsw_spectrum
77	check_err $? "no extack for IP address addition"
78
79	ip link set dev $swp2 addr 00:11:22:33:44:66
80	check_err $?
81	ip addr add dev $swp2 192.0.2.2/28 &>/dev/null
82	check_err $?
83
84	# Change of MAC address of a RIF should be forbidden if the new MAC
85	# doesn't share the prefix with other MAC addresses.
86	ip link set dev $swp2 addr 00:11:22:33:00:66 &>/dev/null
87	check_fail $? "change of MAC address passed for a wrong MAC"
88	ip link set dev $swp2 addr 00:11:22:33:00:66 2>&1 >/dev/null \
89	    | grep -q mlxsw_spectrum
90	check_err $? "no extack for MAC address change"
91
92	log_test "RIF - bad MAC change"
93
94	ip addr del dev $swp2 192.0.2.2/28
95	ip addr del dev $swp1 192.0.2.1/28
96
97	ip link set dev $swp2 addr $swp2_mac
98	ip link set dev $swp1 addr $swp1_mac
99}
100
101rif_inherit_bridge_addr_test()
102{
103	RET=0
104
105	# Create first RIF
106	ip addr add dev $swp1 192.0.2.1/28
107	check_err $?
108
109	# Create a FID RIF
110	ip link add name br1 up type bridge vlan_filtering 0
111	ip link set dev $swp2 master br1
112	ip addr add dev br1 192.0.2.17/28
113	check_err $?
114
115	# Prepare a device with a low MAC address
116	ip link add name d up type dummy
117	ip link set dev d addr 00:11:22:33:44:55
118
119	# Attach the device to br1. That prompts bridge address change, which
120	# should be vetoed, thus preventing the attachment.
121	ip link set dev d master br1 &>/dev/null
122	check_fail $? "Device with low MAC was permitted to attach a bridge with RIF"
123	ip link set dev d master br1 2>&1 >/dev/null \
124	    | grep -q mlxsw_spectrum
125	check_err $? "no extack for bridge attach rejection"
126
127	ip link set dev $swp2 addr 00:11:22:33:44:55 &>/dev/null
128	check_fail $? "Changing swp2's MAC address permitted"
129	ip link set dev $swp2 addr 00:11:22:33:44:55 2>&1 >/dev/null \
130	    | grep -q mlxsw_spectrum
131	check_err $? "no extack for bridge port MAC address change rejection"
132
133	log_test "RIF - attach port with bad MAC to bridge"
134
135	ip link del dev d
136	ip link del dev br1
137	ip addr del dev $swp1 192.0.2.1/28
138}
139
140rif_non_inherit_bridge_addr_test()
141{
142	local swp2_mac=$(mac_get $swp2)
143
144	RET=0
145
146	# Create first RIF
147	ip addr add dev $swp1 192.0.2.1/28
148	check_err $?
149
150	# Create a FID RIF
151	ip link add name br1 up type bridge vlan_filtering 0
152	ip link set dev br1 addr $swp2_mac
153	ip link set dev $swp2 master br1
154	ip addr add dev br1 192.0.2.17/28
155	check_err $?
156
157	# Prepare a device with a low MAC address
158	ip link add name d up type dummy
159	ip link set dev d addr 00:11:22:33:44:55
160
161	# Attach the device to br1. Since the bridge address was set, it should
162	# work.
163	ip link set dev d master br1 &>/dev/null
164	check_err $? "Could not attach a device with low MAC to a bridge with RIF"
165
166	# Port MAC address change should be allowed for a bridge with set MAC.
167	ip link set dev $swp2 addr 00:11:22:33:44:55
168	check_err $? "Changing swp2's MAC address not permitted"
169
170	log_test "RIF - attach port with bad MAC to bridge with set MAC"
171
172	ip link set dev $swp2 addr $swp2_mac
173	ip link del dev d
174	ip link del dev br1
175	ip addr del dev $swp1 192.0.2.1/28
176}
177
178vlan_interface_deletion_test()
179{
180	# Test that when a VLAN interface is deleted, its associated router
181	# interface (RIF) is correctly deleted and not leaked. See commit
182	# c360867ec46a ("mlxsw: spectrum: Delete RIF when VLAN device is
183	# removed") for more details
184	RET=0
185
186	ip link add name br0 type bridge vlan_filtering 1
187	ip link set dev $swp1 master br0
188
189	ip link add link br0 name br0.10 type vlan id 10
190	ip -6 address add 2001:db8:1::1/64 dev br0.10
191	ip link del dev br0.10
192
193	# If we leaked the previous RIF, then this should produce a trace
194	ip link add link br0 name br0.20 type vlan id 20
195	ip -6 address add 2001:db8:1::1/64 dev br0.20
196	ip link del dev br0.20
197
198	log_test "vlan interface deletion"
199
200	ip link del dev br0
201}
202
203bridge_deletion_test()
204{
205	# Test that when a bridge with VLAN interfaces is deleted, we correctly
206	# delete the associated RIFs. See commit 602b74eda813 ("mlxsw:
207	# spectrum_switchdev: Do not leak RIFs when removing bridge") for more
208	# details
209	RET=0
210
211	ip link add name br0 type bridge vlan_filtering 1
212	ip link set dev $swp1 master br0
213	ip -6 address add 2001:db8::1/64 dev br0
214
215	ip link add link br0 name br0.10 type vlan id 10
216	ip -6 address add 2001:db8:1::1/64 dev br0.10
217
218	ip link add link br0 name br0.20 type vlan id 20
219	ip -6 address add 2001:db8:2::1/64 dev br0.20
220
221	ip link del dev br0
222
223	# If we leaked previous RIFs, then this should produce a trace
224	ip -6 address add 2001:db8:1::1/64 dev $swp1
225	ip -6 address del 2001:db8:1::1/64 dev $swp1
226
227	log_test "bridge deletion"
228}
229
230bridge_vlan_flags_test()
231{
232	# Test that when bridge VLAN flags are toggled, we do not take
233	# unnecessary references on related structs. See commit 9e25826ffc94
234	# ("mlxsw: spectrum_switchdev: Fix port_vlan refcounting") for more
235	# details
236	RET=0
237
238	ip link add name br0 type bridge vlan_filtering 1
239	ip link set dev $swp1 master br0
240
241	bridge vlan add vid 10 dev $swp1 pvid untagged
242	bridge vlan add vid 10 dev $swp1 untagged
243	bridge vlan add vid 10 dev $swp1 pvid
244	bridge vlan add vid 10 dev $swp1
245	ip link del dev br0
246
247	# If we did not handle references correctly, then this should produce a
248	# trace
249	devlink dev reload "$DEVLINK_DEV"
250
251	# Allow netdevices to be re-created following the reload
252	sleep 20
253
254	log_test "bridge vlan flags"
255}
256
257vlan_1_test()
258{
259	# Test that VLAN 1 can be configured over mlxsw ports. In the past it
260	# was used internally for untagged traffic. See commit 47bf9df2e820
261	# ("mlxsw: spectrum: Forbid creation of VLAN 1 over port/LAG") for more
262	# details
263	RET=0
264
265	ip link add link $swp1 name $swp1.1 type vlan id 1
266	check_err $? "did not manage to create vlan 1 when should"
267
268	log_test "vlan 1"
269
270	ip link del dev $swp1.1
271}
272
273lag_bridge_upper_test()
274{
275	# Test that ports cannot be enslaved to LAG devices that have uppers
276	# and that failure is handled gracefully. See commit b3529af6bb0d
277	# ("spectrum: Reference count VLAN entries") for more details
278	RET=0
279
280	ip link add name bond1 type bond mode 802.3ad
281
282	ip link add name br0 type bridge vlan_filtering 1
283	ip link set dev bond1 master br0
284
285	ip link set dev $swp1 down
286	ip link set dev $swp1 master bond1 &> /dev/null
287	check_fail $? "managed to enslave port to lag when should not"
288
289	# This might generate a trace, if we did not handle the failure
290	# correctly
291	ip -6 address add 2001:db8:1::1/64 dev $swp1
292	ip -6 address del 2001:db8:1::1/64 dev $swp1
293
294	log_test "lag with bridge upper"
295
296	ip link del dev br0
297	ip link del dev bond1
298}
299
300duplicate_vlans_test()
301{
302	# Test that on a given port a VLAN is only used once. Either as VLAN
303	# in a VLAN-aware bridge or as a VLAN device
304	RET=0
305
306	ip link add name br0 type bridge vlan_filtering 1
307	ip link set dev $swp1 master br0
308	bridge vlan add vid 10 dev $swp1
309
310	ip link add link $swp1 name $swp1.10 type vlan id 10 &> /dev/null
311	check_fail $? "managed to create vlan device when should not"
312
313	bridge vlan del vid 10 dev $swp1
314	ip link add link $swp1 name $swp1.10 type vlan id 10
315	check_err $? "did not manage to create vlan device when should"
316	bridge vlan add vid 10 dev $swp1 &> /dev/null
317	check_fail $? "managed to add bridge vlan when should not"
318
319	log_test "duplicate vlans"
320
321	ip link del dev $swp1.10
322	ip link del dev br0
323}
324
325vlan_rif_refcount_test()
326{
327	# Test that RIFs representing VLAN interfaces are not affected from
328	# ports member in the VLAN. We use the offload indication on routes
329	# configured on the RIF to understand if it was created / destroyed
330	RET=0
331
332	ip link add name br0 type bridge vlan_filtering 1
333	ip link set dev $swp1 master br0
334
335	ip link set dev $swp1 up
336	ip link set dev br0 up
337
338	ip link add link br0 name br0.10 up type vlan id 10
339	ip -6 address add 2001:db8:1::1/64 dev br0.10
340
341	ip -6 route get fibmatch 2001:db8:1::2 dev br0.10 | grep -q offload
342	check_err $? "vlan rif was not created before adding port to vlan"
343
344	bridge vlan add vid 10 dev $swp1
345	ip -6 route get fibmatch 2001:db8:1::2 dev br0.10 | grep -q offload
346	check_err $? "vlan rif was destroyed after adding port to vlan"
347
348	bridge vlan del vid 10 dev $swp1
349	ip -6 route get fibmatch 2001:db8:1::2 dev br0.10 | grep -q offload
350	check_err $? "vlan rif was destroyed after removing port from vlan"
351
352	ip link set dev $swp1 nomaster
353	ip -6 route get fibmatch 2001:db8:1::2 dev br0.10 | grep -q offload
354	check_fail $? "vlan rif was not destroyed after unlinking port from bridge"
355
356	log_test "vlan rif refcount"
357
358	ip link del dev br0.10
359	ip link set dev $swp1 down
360	ip link del dev br0
361}
362
363subport_rif_refcount_test()
364{
365	# Test that RIFs representing upper devices of physical ports are
366	# reference counted correctly and destroyed when should. We use the
367	# offload indication on routes configured on the RIF to understand if
368	# it was created / destroyed
369	RET=0
370
371	ip link add name bond1 type bond mode 802.3ad
372	ip link set dev $swp1 down
373	ip link set dev $swp2 down
374	ip link set dev $swp1 master bond1
375	ip link set dev $swp2 master bond1
376
377	ip link set dev bond1 up
378	ip link add link bond1 name bond1.10 up type vlan id 10
379	ip -6 address add 2001:db8:1::1/64 dev bond1
380	ip -6 address add 2001:db8:2::1/64 dev bond1.10
381
382	ip -6 route get fibmatch 2001:db8:1::2 dev bond1 | grep -q offload
383	check_err $? "subport rif was not created on lag device"
384	ip -6 route get fibmatch 2001:db8:2::2 dev bond1.10 | grep -q offload
385	check_err $? "subport rif was not created on vlan device"
386
387	ip link set dev $swp1 nomaster
388	ip -6 route get fibmatch 2001:db8:1::2 dev bond1 | grep -q offload
389	check_err $? "subport rif of lag device was destroyed when should not"
390	ip -6 route get fibmatch 2001:db8:2::2 dev bond1.10 | grep -q offload
391	check_err $? "subport rif of vlan device was destroyed when should not"
392
393	ip link set dev $swp2 nomaster
394	ip -6 route get fibmatch 2001:db8:1::2 dev bond1 | grep -q offload
395	check_fail $? "subport rif of lag device was not destroyed when should"
396	ip -6 route get fibmatch 2001:db8:2::2 dev bond1.10 | grep -q offload
397	check_fail $? "subport rif of vlan device was not destroyed when should"
398
399	log_test "subport rif refcount"
400
401	ip link del dev bond1.10
402	ip link del dev bond1
403}
404
405vlan_dev_deletion_test()
406{
407	# Test that VLAN devices are correctly deleted / unlinked when enslaved
408	# to bridge
409	RET=0
410
411	ip link add name br10 type bridge
412	ip link add name br20 type bridge
413	ip link add name br30 type bridge
414	ip link add link $swp1 name $swp1.10 type vlan id 10
415	ip link add link $swp1 name $swp1.20 type vlan id 20
416	ip link add link $swp1 name $swp1.30 type vlan id 30
417	ip link set dev $swp1.10 master br10
418	ip link set dev $swp1.20 master br20
419	ip link set dev $swp1.30 master br30
420
421	# If we did not handle the situation correctly, then these operations
422	# might produce a trace
423	ip link set dev $swp1.30 nomaster
424	ip link del dev $swp1.20
425	# Deletion via ioctl uses different code paths from netlink
426	vconfig rem $swp1.10 &> /dev/null
427
428	log_test "vlan device deletion"
429
430	ip link del dev $swp1.30
431	ip link del dev br30
432	ip link del dev br20
433	ip link del dev br10
434}
435
436lag_create()
437{
438	ip link add name bond1 type bond mode 802.3ad
439	ip link set dev $swp1 down
440	ip link set dev $swp2 down
441	ip link set dev $swp1 master bond1
442	ip link set dev $swp2 master bond1
443
444	ip link add link bond1 name bond1.10 type vlan id 10
445	ip link add link bond1 name bond1.20 type vlan id 20
446
447	ip link add name br0 type bridge vlan_filtering 1
448	ip link set dev bond1 master br0
449
450	ip link add name br10 type bridge
451	ip link set dev bond1.10 master br10
452
453	ip link add name br20 type bridge
454	ip link set dev bond1.20 master br20
455}
456
457lag_unlink_slaves_test()
458{
459	# Test that ports are correctly unlinked from their LAG master, when
460	# the LAG and its VLAN uppers are enslaved to bridges
461	RET=0
462
463	lag_create
464
465	ip link set dev $swp1 nomaster
466	check_err $? "lag slave $swp1 was not unlinked from master"
467	ip link set dev $swp2 nomaster
468	check_err $? "lag slave $swp2 was not unlinked from master"
469
470	# Try to configure corresponding VLANs as router interfaces
471	ip -6 address add 2001:db8:1::1/64 dev $swp1
472	check_err $? "failed to configure ip address on $swp1"
473
474	ip link add link $swp1 name $swp1.10 type vlan id 10
475	ip -6 address add 2001:db8:10::1/64 dev $swp1.10
476	check_err $? "failed to configure ip address on $swp1.10"
477
478	ip link add link $swp1 name $swp1.20 type vlan id 20
479	ip -6 address add 2001:db8:20::1/64 dev $swp1.20
480	check_err $? "failed to configure ip address on $swp1.20"
481
482	log_test "lag slaves unlinking"
483
484	ip link del dev $swp1.20
485	ip link del dev $swp1.10
486	ip address flush dev $swp1
487
488	ip link del dev br20
489	ip link del dev br10
490	ip link del dev br0
491	ip link del dev bond1
492}
493
494lag_dev_deletion_test()
495{
496	# Test that LAG device is correctly deleted, when the LAG and its VLAN
497	# uppers are enslaved to bridges
498	RET=0
499
500	lag_create
501
502	ip link del dev bond1
503
504	log_test "lag device deletion"
505
506	ip link del dev br20
507	ip link del dev br10
508	ip link del dev br0
509}
510
511vlan_interface_uppers_test()
512{
513	# Test that uppers of a VLAN interface are correctly sanitized
514	RET=0
515
516	ip link add name br0 type bridge vlan_filtering 1
517	ip link set dev $swp1 master br0
518
519	ip link add link br0 name br0.10 type vlan id 10
520	ip link add link br0.10 name macvlan0 \
521		type macvlan mode private &> /dev/null
522	check_fail $? "managed to create a macvlan when should not"
523
524	ip -6 address add 2001:db8:1::1/64 dev br0.10
525	ip link add link br0.10 name macvlan0 type macvlan mode private
526	check_err $? "did not manage to create a macvlan when should"
527
528	ip link del dev macvlan0
529
530	ip link add name vrf-test type vrf table 10
531	ip link set dev br0.10 master vrf-test
532	check_err $? "did not manage to enslave vlan interface to vrf"
533	ip link del dev vrf-test
534
535	ip link add name br-test type bridge
536	ip link set dev br0.10 master br-test &> /dev/null
537	check_fail $? "managed to enslave vlan interface to bridge when should not"
538	ip link del dev br-test
539
540	log_test "vlan interface uppers"
541
542	ip link del dev br0
543}
544
545bridge_extern_learn_test()
546{
547	# Test that externally learned entries added from user space are
548	# marked as offloaded
549	RET=0
550
551	ip link add name br0 type bridge
552	ip link set dev $swp1 master br0
553
554	bridge fdb add de:ad:be:ef:13:37 dev $swp1 master extern_learn
555
556	bridge fdb show brport $swp1 | grep de:ad:be:ef:13:37 | grep -q offload
557	check_err $? "fdb entry not marked as offloaded when should"
558
559	log_test "externally learned fdb entry"
560
561	ip link del dev br0
562}
563
564devlink_reload_test()
565{
566	# Test that after executing all the above configuration tests, a
567	# devlink reload can be performed without errors
568	RET=0
569
570	devlink dev reload "$DEVLINK_DEV"
571	check_err $? "devlink reload failed"
572
573	log_test "devlink reload - last test"
574
575	sleep 20
576}
577
578trap cleanup EXIT
579
580setup_prepare
581setup_wait
582
583tests_run
584
585exit $EXIT_STATUS
586