1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4lib_dir=$(dirname $0)/../../../net/forwarding
5
6ALL_TESTS="
7	rif_mac_profile_edit_test
8"
9NUM_NETIFS=2
10source $lib_dir/lib.sh
11source $lib_dir/devlink_lib.sh
12
13setup_prepare()
14{
15	h1=${NETIFS[p1]}
16	h2=${NETIFS[p2]}
17
18	# Disable IPv6 on the two interfaces to avoid IPv6 link-local addresses
19	# being generated and RIFs being created
20	sysctl_set net.ipv6.conf.$h1.disable_ipv6 1
21	sysctl_set net.ipv6.conf.$h2.disable_ipv6 1
22
23	ip link set $h1 up
24	ip link set $h2 up
25}
26
27cleanup()
28{
29	pre_cleanup
30
31	ip link set $h2 down
32	ip link set $h1 down
33
34	sysctl_restore net.ipv6.conf.$h2.disable_ipv6
35	sysctl_restore net.ipv6.conf.$h1.disable_ipv6
36
37	# Reload in order to clean all the RIFs and RIF MAC profiles created
38	devlink_reload
39}
40
41create_max_rif_mac_profiles()
42{
43	local count=$1; shift
44	local batch_file="$(mktemp)"
45
46	for ((i = 1; i <= count; i++)); do
47		vlan=$(( i*10 ))
48		m=$(( i*11 ))
49
50		cat >> $batch_file <<-EOF
51			link add link $h1 name $h1.$vlan \
52				address 00:$m:$m:$m:$m:$m type vlan id $vlan
53			address add 192.0.$m.1/24 dev $h1.$vlan
54		EOF
55	done
56
57	ip -b $batch_file &> /dev/null
58	rm -f $batch_file
59}
60
61rif_mac_profile_replacement_test()
62{
63	local h1_10_mac=$(mac_get $h1.10)
64
65	RET=0
66
67	ip link set $h1.10 address 00:12:34:56:78:99
68	check_err $?
69
70	log_test "RIF MAC profile replacement"
71
72	ip link set $h1.10 address $h1_10_mac
73}
74
75rif_mac_profile_consolidation_test()
76{
77	local count=$1; shift
78	local h1_20_mac
79
80	RET=0
81
82	if [[ $count -eq 1 ]]; then
83		return
84	fi
85
86	h1_20_mac=$(mac_get $h1.20)
87
88	# Set the MAC of $h1.20 to that of $h1.10 and confirm that they are
89	# using the same MAC profile.
90	ip link set $h1.20 address 00:11:11:11:11:11
91	check_err $?
92
93	occ=$(devlink -j resource show $DEVLINK_DEV \
94	      | jq '.[][][] | select(.name=="rif_mac_profiles") |.["occ"]')
95
96	[[ $occ -eq $((count - 1)) ]]
97	check_err $? "MAC profile occupancy did not decrease"
98
99	log_test "RIF MAC profile consolidation"
100
101	ip link set $h1.20 address $h1_20_mac
102}
103
104rif_mac_profile_shared_replacement_test()
105{
106	local count=$1; shift
107	local i=$((count + 1))
108	local vlan=$(( i*10 ))
109	local m=11
110
111	RET=0
112
113	# Create a VLAN netdevice that has the same MAC as the first one.
114	ip link add link $h1 name $h1.$vlan address 00:$m:$m:$m:$m:$m \
115		type vlan id $vlan
116	ip address add 192.0.$m.1/24 dev $h1.$vlan
117
118	# MAC replacement should fail because all the MAC profiles are in use
119	# and the profile is shared between multiple RIFs
120	m=$(( i*11 ))
121	ip link set $h1.$vlan address 00:$m:$m:$m:$m:$m &> /dev/null
122	check_fail $?
123
124	log_test "RIF MAC profile shared replacement"
125
126	ip link del dev $h1.$vlan
127}
128
129rif_mac_profile_edit_test()
130{
131	local count=$(devlink_resource_size_get rif_mac_profiles)
132
133	create_max_rif_mac_profiles $count
134
135	rif_mac_profile_replacement_test
136	rif_mac_profile_consolidation_test $count
137	rif_mac_profile_shared_replacement_test $count
138}
139
140trap cleanup EXIT
141
142setup_prepare
143setup_wait
144
145tests_run
146
147exit $EXIT_STATUS
148