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