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