1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4# Test VLAN classification after routing and verify that the order of
5# configuration does not impact switch behavior. Verify that {RIF, Port}->VID
6# mapping is added correctly for existing {Port, VID}->FID mapping and that
7# {RIF, Port}->VID mapping is added correctly for new {Port, VID}->FID mapping.
8
9# +-------------------+                   +--------------------+
10# | H1                |                   | H2                 |
11# |                   |                   |                    |
12# |         $h1.10 +  |                   |  + $h2.10          |
13# |   192.0.2.1/28 |  |                   |  | 192.0.2.3/28    |
14# |                |  |                   |  |                 |
15# |            $h1 +  |                   |  + $h2             |
16# +----------------|--+                   +--|-----------------+
17#                  |                         |
18# +----------------|-------------------------|-----------------+
19# | SW             |                         |                 |
20# | +--------------|-------------------------|---------------+ |
21# | |        $swp1 +                         + $swp2         | |
22# | |              |                         |               | |
23# | |     $swp1.10 +                         + $swp2.10      | |
24# | |                                                        | |
25# | |                           br0                          | |
26# | |                       192.0.2.2/28                     | |
27# | +--------------------------------------------------------+ |
28# |                                                            |
29# |      $swp3.20 +                                            |
30# | 192.0.2.17/28 |                                            |
31# |               |                                            |
32# |         $swp3 +                                            |
33# +---------------|--------------------------------------------+
34#                 |
35# +---------------|--+
36# |           $h3 +  |
37# |               |  |
38# |        $h3.20 +  |
39# | 192.0.2.18/28    |
40# |                  |
41# | H3               |
42# +------------------+
43
44lib_dir=$(dirname $0)/../../../net/forwarding
45
46ALL_TESTS="
47	port_vid_map_rif
48	rif_port_vid_map
49"
50
51NUM_NETIFS=6
52source $lib_dir/lib.sh
53source $lib_dir/tc_common.sh
54source $lib_dir/devlink_lib.sh
55
56h1_create()
57{
58	simple_if_init $h1
59	vlan_create $h1 10 v$h1 192.0.2.1/28
60
61	ip route add 192.0.2.16/28 vrf v$h1 nexthop via 192.0.2.2
62}
63
64h1_destroy()
65{
66	ip route del 192.0.2.16/28 vrf v$h1 nexthop via 192.0.2.2
67
68	vlan_destroy $h1 10
69	simple_if_fini $h1
70}
71
72h2_create()
73{
74	simple_if_init $h2
75	vlan_create $h2 10 v$h2 192.0.2.3/28
76}
77
78h2_destroy()
79{
80	vlan_destroy $h2 10
81	simple_if_fini $h2
82}
83
84h3_create()
85{
86	simple_if_init $h3
87	vlan_create $h3 20 v$h3 192.0.2.18/28
88
89	ip route add 192.0.2.0/28 vrf v$h3 nexthop via 192.0.2.17
90}
91
92h3_destroy()
93{
94	ip route del 192.0.2.0/28 vrf v$h3 nexthop via 192.0.2.17
95
96	vlan_destroy $h3 20
97	simple_if_fini $h3
98}
99
100switch_create()
101{
102	ip link set dev $swp1 up
103	tc qdisc add dev $swp1 clsact
104
105	ip link add dev br0 type bridge mcast_snooping 0
106
107	# By default, a link-local address is generated when netdevice becomes
108	# up. Adding an address to the bridge will cause creating a RIF for it.
109	# Prevent generating link-local address to be able to control when the
110	# RIF is added.
111	sysctl_set net.ipv6.conf.br0.addr_gen_mode 1
112	ip link set dev br0 up
113
114	ip link set dev $swp2 up
115	vlan_create $swp2 10
116	ip link set dev $swp2.10 master br0
117
118	ip link set dev $swp3 up
119	vlan_create $swp3 20 "" 192.0.2.17/28
120
121	# Replace neighbor to avoid 1 packet which is forwarded in software due
122	# to "unresolved neigh".
123	ip neigh replace dev $swp3.20 192.0.2.18 lladdr $(mac_get $h3.20)
124}
125
126switch_destroy()
127{
128	vlan_destroy $swp3 20
129	ip link set dev $swp3 down
130
131	ip link set dev $swp2.10 nomaster
132	vlan_destroy $swp2 10
133	ip link set dev $swp2 down
134
135	ip link set dev br0 down
136	sysctl_restore net.ipv6.conf.br0.addr_gen_mode
137	ip link del dev br0
138
139	tc qdisc del dev $swp1 clsact
140	ip link set dev $swp1 down
141}
142
143setup_prepare()
144{
145	h1=${NETIFS[p1]}
146	swp1=${NETIFS[p2]}
147
148	swp2=${NETIFS[p3]}
149	h2=${NETIFS[p4]}
150
151	swp3=${NETIFS[p5]}
152	h3=${NETIFS[p6]}
153
154	vrf_prepare
155	forwarding_enable
156
157	h1_create
158	h2_create
159	h3_create
160
161	switch_create
162}
163
164cleanup()
165{
166	pre_cleanup
167
168	switch_destroy
169
170	h3_destroy
171	h2_destroy
172	h1_destroy
173
174	forwarding_restore
175	vrf_cleanup
176}
177
178bridge_rif_add()
179{
180	rifs_occ_t0=$(devlink_resource_occ_get rifs)
181	__addr_add_del br0 add 192.0.2.2/28
182	rifs_occ_t1=$(devlink_resource_occ_get rifs)
183
184	expected_rifs=$((rifs_occ_t0 + 1))
185
186	[[ $expected_rifs -eq $rifs_occ_t1 ]]
187	check_err $? "Expected $expected_rifs RIFs, $rifs_occ_t1 are used"
188
189	sleep 1
190}
191
192bridge_rif_del()
193{
194	__addr_add_del br0 del 192.0.2.2/28
195}
196
197port_vid_map_rif()
198{
199	RET=0
200
201	# First add {port, VID}->FID for swp1.10, then add a RIF and verify that
202	# packets get the correct VID after routing.
203	vlan_create $swp1 10
204	ip link set dev $swp1.10 master br0
205	bridge_rif_add
206
207	# Replace neighbor to avoid 1 packet which is forwarded in software due
208	# to "unresolved neigh".
209	ip neigh replace dev br0 192.0.2.1 lladdr $(mac_get $h1.10)
210
211	# The hardware matches on the first ethertype which is not VLAN,
212	# so the protocol should be IP.
213	tc filter add dev $swp1 egress protocol ip pref 1 handle 101 \
214		flower skip_sw dst_ip 192.0.2.1 action pass
215
216	ping_do $h1.10 192.0.2.18
217	check_err $? "Ping failed"
218
219	tc_check_at_least_x_packets "dev $swp1 egress" 101 10
220	check_err $? "Packets were not routed in hardware"
221
222	log_test "Add RIF for existing {port, VID}->FID mapping"
223
224	tc filter del dev $swp1 egress
225
226	bridge_rif_del
227	ip link set dev $swp1.10 nomaster
228	vlan_destroy $swp1 10
229}
230
231rif_port_vid_map()
232{
233	RET=0
234
235	# First add an address to the bridge, which will create a RIF on top of
236	# it, then add a new {port, VID}->FID mapping and verify that packets
237	# get the correct VID after routing.
238	bridge_rif_add
239	vlan_create $swp1 10
240	ip link set dev $swp1.10 master br0
241
242	# Replace neighbor to avoid 1 packet which is forwarded in software due
243	# to "unresolved neigh".
244	ip neigh replace dev br0 192.0.2.1 lladdr $(mac_get $h1.10)
245
246	# The hardware matches on the first ethertype which is not VLAN,
247	# so the protocol should be IP.
248	tc filter add dev $swp1 egress protocol ip pref 1 handle 101 \
249		flower skip_sw dst_ip 192.0.2.1 action pass
250
251	ping_do $h1.10 192.0.2.18
252	check_err $? "Ping failed"
253
254	tc_check_at_least_x_packets "dev $swp1 egress" 101 10
255	check_err $? "Packets were not routed in hardware"
256
257	log_test "Add {port, VID}->FID mapping for FID with a RIF"
258
259	tc filter del dev $swp1 egress
260
261	ip link set dev $swp1.10 nomaster
262	vlan_destroy $swp1 10
263	bridge_rif_del
264}
265
266trap cleanup EXIT
267
268setup_prepare
269setup_wait
270
271tests_run
272
273exit $EXIT_STATUS
274