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