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