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