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