1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4# +--------------------+                               +----------------------+
5# | H1 (vrf)           |                               |             H2 (vrf) |
6# |    + h1.10         |                               |  + h2.20             |
7# |    | 192.0.2.1/28  |                               |  | 192.0.2.2/28      |
8# |    |               |                               |  |                   |
9# |    + $h1           |                               |  + $h2               |
10# |    |               |                               |  |                   |
11# +----|---------------+                               +--|-------------------+
12#      |                                                  |
13# +----|--------------------------------------------------|--------------------+
14# | SW |                                                  |                    |
15# | +--|-------------------------------+ +----------------|------------------+ |
16# | |  + $swp1         BR1 (802.1ad)   | | BR2 (802.1d)   + $swp2            | |
17# | |    vid 100 pvid untagged         | |                |                  | |
18# | |                                  | |                + $swp2.20         | |
19# | |                                  | |                                   | |
20# | |  + vx100 (vxlan)                 | |  + vx200 (vxlan)                  | |
21# | |    local 192.0.2.17              | |    local 192.0.2.17               | |
22# | |    remote 192.0.2.34             | |    remote 192.0.2.50              | |
23# | |    id 1000 dstport $VXPORT       | |    id 2000 dstport $VXPORT        | |
24# | |    vid 100 pvid untagged         | |                                   | |
25# | +--------------------------------- + +-----------------------------------+ |
26# |                                                                            |
27# |  192.0.2.32/28 via 192.0.2.18                                              |
28# |  192.0.2.48/28 via 192.0.2.18                                              |
29# |                                                                            |
30# |    + $rp1                                                                  |
31# |    | 192.0.2.17/28                                                         |
32# +----|-----------------------------------------------------------------------+
33#      |
34# +----|--------------------------------------------------------+
35# |    |                                             VRP2 (vrf) |
36# |    + $rp2                                                   |
37# |      192.0.2.18/28                                          |
38# |                                                             |   (maybe) HW
39# =============================================================================
40# |                                                             |  (likely) SW
41# |    + v1 (veth)                             + v3 (veth)      |
42# |    | 192.0.2.33/28                         | 192.0.2.49/28  |
43# +----|---------------------------------------|----------------+
44#      |                                       |
45# +----|------------------------------+   +----|------------------------------+
46# |    + v2 (veth)        NS1 (netns) |   |    + v4 (veth)        NS2 (netns) |
47# |      192.0.2.34/28                |   |      192.0.2.50/28                |
48# |                                   |   |                                   |
49# |   192.0.2.16/28 via 192.0.2.33    |   |   192.0.2.16/28 via 192.0.2.49    |
50# |   192.0.2.50/32 via 192.0.2.33    |   |   192.0.2.34/32 via 192.0.2.49    |
51# |                                   |   |                                   |
52# | +-------------------------------+ |   | +-------------------------------+ |
53# | |                 BR3 (802.1ad) | |   | |                  BR3 (802.1d) | |
54# | |  + vx100 (vxlan)              | |   | |  + vx200 (vxlan)              | |
55# | |    local 192.0.2.34           | |   | |    local 192.0.2.50           | |
56# | |    remote 192.0.2.17          | |   | |    remote 192.0.2.17          | |
57# | |    remote 192.0.2.50          | |   | |    remote 192.0.2.34          | |
58# | |    id 1000 dstport $VXPORT    | |   | |    id 2000 dstport $VXPORT    | |
59# | |    vid 100 pvid untagged      | |   | |                               | |
60# | |                               | |   | |  + w1.20                      | |
61# | |                               | |   | |  |                            | |
62# | |  + w1 (veth)                  | |   | |  + w1 (veth)                  | |
63# | |  | vid 100 pvid untagged      | |   | |  |                            | |
64# | +--|----------------------------+ |   | +--|----------------------------+ |
65# |    |                              |   |    |                              |
66# | +--|----------------------------+ |   | +--|----------------------------+ |
67# | |  |                  VW2 (vrf) | |   | |  |                  VW2 (vrf) | |
68# | |  + w2 (veth)                  | |   | |  + w2 (veth)                  | |
69# | |  |                            | |   | |  |                            | |
70# | |  |                            | |   | |  |                            | |
71# | |  + w2.10                      | |   | |  + w2.20                      | |
72# | |    192.0.2.3/28               | |   | |    192.0.2.4/28               | |
73# | +-------------------------------+ |   | +-------------------------------+ |
74# +-----------------------------------+   +-----------------------------------+
75
76: ${VXPORT:=4789}
77export VXPORT
78
79: ${ALL_TESTS:="
80	ping_ipv4
81    "}
82
83NUM_NETIFS=6
84source lib.sh
85
86h1_create()
87{
88	simple_if_init $h1
89	tc qdisc add dev $h1 clsact
90	vlan_create $h1 10 v$h1 192.0.2.1/28
91}
92
93h1_destroy()
94{
95	vlan_destroy $h1 10
96	tc qdisc del dev $h1 clsact
97	simple_if_fini $h1
98}
99
100h2_create()
101{
102	simple_if_init $h2
103	tc qdisc add dev $h2 clsact
104	vlan_create $h2 20 v$h2 192.0.2.2/28
105}
106
107h2_destroy()
108{
109	vlan_destroy $h2 20
110	tc qdisc del dev $h2 clsact
111	simple_if_fini $h2
112}
113
114rp1_set_addr()
115{
116	ip address add dev $rp1 192.0.2.17/28
117
118	ip route add 192.0.2.32/28 nexthop via 192.0.2.18
119	ip route add 192.0.2.48/28 nexthop via 192.0.2.18
120}
121
122rp1_unset_addr()
123{
124	ip route del 192.0.2.48/28 nexthop via 192.0.2.18
125	ip route del 192.0.2.32/28 nexthop via 192.0.2.18
126
127	ip address del dev $rp1 192.0.2.17/28
128}
129
130switch_create()
131{
132	#### BR1 ####
133	ip link add name br1 type bridge vlan_filtering 1 \
134		vlan_protocol 802.1ad vlan_default_pvid 0 mcast_snooping 0
135	ip link set dev br1 addrgenmode none
136	# Make sure the bridge uses the MAC address of the local port and not
137	# that of the VxLAN's device.
138	ip link set dev br1 address $(mac_get $swp1)
139	ip link set dev br1 up
140
141	#### BR2 ####
142	ip link add name br2 type bridge vlan_filtering 0 mcast_snooping 0
143	# Make sure the bridge uses the MAC address of the local port and not
144	# that of the VxLAN's device.
145	ip link set dev br2 address $(mac_get $swp2)
146	ip link set dev br2 up
147
148	ip link set dev $rp1 up
149	rp1_set_addr
150
151	#### VX100 ####
152	ip link add name vx100 type vxlan id 1000 local 192.0.2.17 \
153		dstport "$VXPORT" nolearning noudpcsum tos inherit ttl 100
154	ip link set dev vx100 up
155
156	ip link set dev vx100 master br1
157	bridge vlan add vid 100 dev vx100 pvid untagged
158
159	ip link set dev $swp1 master br1
160	ip link set dev $swp1 up
161	bridge vlan add vid 100 dev $swp1 pvid untagged
162
163	#### VX200 ####
164	ip link add name vx200 type vxlan id 2000 local 192.0.2.17 \
165		dstport "$VXPORT" nolearning noudpcsum tos inherit ttl 100
166	ip link set dev vx200 up
167
168	ip link set dev vx200 master br2
169
170	ip link set dev $swp2 up
171	ip link add name $swp2.20 link $swp2 type vlan id 20
172	ip link set dev $swp2.20 master br2
173	ip link set dev $swp2.20 up
174
175	bridge fdb append dev vx100 00:00:00:00:00:00 dst 192.0.2.34 self
176	bridge fdb append dev vx200 00:00:00:00:00:00 dst 192.0.2.50 self
177}
178
179switch_destroy()
180{
181	bridge fdb del dev vx200 00:00:00:00:00:00 dst 192.0.2.50 self
182	bridge fdb del dev vx100 00:00:00:00:00:00 dst 192.0.2.34 self
183
184	ip link set dev vx200 nomaster
185	ip link set dev vx200 down
186	ip link del dev vx200
187
188	ip link del dev $swp2.20
189	ip link set dev $swp2 down
190	ip link set dev $swp2 nomaster
191
192	bridge vlan del vid 100 dev $swp1
193	ip link set dev $swp1 down
194	ip link set dev $swp1 nomaster
195
196	ip link set dev vx100 nomaster
197	ip link set dev vx100 down
198	ip link del dev vx100
199
200	rp1_unset_addr
201	ip link set dev $rp1 down
202
203	ip link set dev br2 down
204	ip link del dev br2
205
206	ip link set dev br1 down
207	ip link del dev br1
208}
209
210vrp2_create()
211{
212	simple_if_init $rp2 192.0.2.18/28
213	__simple_if_init v1 v$rp2 192.0.2.33/28
214	__simple_if_init v3 v$rp2 192.0.2.49/28
215	tc qdisc add dev v1 clsact
216}
217
218vrp2_destroy()
219{
220	tc qdisc del dev v1 clsact
221	__simple_if_fini v3 192.0.2.49/28
222	__simple_if_fini v1 192.0.2.33/28
223	simple_if_fini $rp2 192.0.2.18/28
224}
225
226ns_init_common()
227{
228	local in_if=$1; shift
229	local in_addr=$1; shift
230	local other_in_addr=$1; shift
231	local vxlan_name=$1; shift
232	local vxlan_id=$1; shift
233	local vlan_id=$1; shift
234	local host_addr=$1; shift
235	local nh_addr=$1; shift
236
237	ip link set dev $in_if up
238	ip address add dev $in_if $in_addr/28
239	tc qdisc add dev $in_if clsact
240
241	ip link add name br3 type bridge vlan_filtering 0
242	ip link set dev br3 up
243
244	ip link add name w1 type veth peer name w2
245
246	ip link set dev w1 master br3
247	ip link set dev w1 up
248
249	ip link add name $vxlan_name type vxlan id $vxlan_id local $in_addr \
250		dstport "$VXPORT"
251	ip link set dev $vxlan_name up
252	bridge fdb append dev $vxlan_name 00:00:00:00:00:00 dst 192.0.2.17 self
253	bridge fdb append dev $vxlan_name 00:00:00:00:00:00 dst $other_in_addr self
254
255	ip link set dev $vxlan_name master br3
256	tc qdisc add dev $vxlan_name clsact
257
258	simple_if_init w2
259	vlan_create w2 $vlan_id vw2 $host_addr/28
260
261	ip route add 192.0.2.16/28 nexthop via $nh_addr
262	ip route add $other_in_addr/32 nexthop via $nh_addr
263}
264export -f ns_init_common
265
266ns1_create()
267{
268	ip netns add ns1
269	ip link set dev v2 netns ns1
270	in_ns ns1 \
271	      ns_init_common v2 192.0.2.34 192.0.2.50 vx100 1000 10 192.0.2.3 \
272	      192.0.2.33
273
274	in_ns ns1 bridge vlan add vid 100 dev vx100 pvid untagged
275}
276
277ns1_destroy()
278{
279	ip netns exec ns1 ip link set dev v2 netns 1
280	ip netns del ns1
281}
282
283ns2_create()
284{
285	ip netns add ns2
286	ip link set dev v4 netns ns2
287	in_ns ns2 \
288	      ns_init_common v4 192.0.2.50 192.0.2.34 vx200 2000 20 192.0.2.4 \
289	      192.0.2.49
290
291	in_ns ns2 ip link add name w1.20 link w1 type vlan id 20
292	in_ns ns2 ip link set dev w1.20 master br3
293	in_ns ns2 ip link set dev w1.20 up
294}
295
296ns2_destroy()
297{
298	ip netns exec ns2 ip link set dev v4 netns 1
299	ip netns del ns2
300}
301
302setup_prepare()
303{
304	h1=${NETIFS[p1]}
305	swp1=${NETIFS[p2]}
306
307	swp2=${NETIFS[p3]}
308	h2=${NETIFS[p4]}
309
310	rp1=${NETIFS[p5]}
311	rp2=${NETIFS[p6]}
312
313	vrf_prepare
314	forwarding_enable
315
316	h1_create
317	h2_create
318	switch_create
319
320	ip link add name v1 type veth peer name v2
321	ip link add name v3 type veth peer name v4
322	vrp2_create
323	ns1_create
324	ns2_create
325
326	r1_mac=$(in_ns ns1 mac_get w2)
327	r2_mac=$(in_ns ns2 mac_get w2)
328	h2_mac=$(mac_get $h2)
329}
330
331cleanup()
332{
333	pre_cleanup
334
335	ns2_destroy
336	ns1_destroy
337	vrp2_destroy
338	ip link del dev v3
339	ip link del dev v1
340
341	switch_destroy
342	h2_destroy
343	h1_destroy
344
345	forwarding_restore
346	vrf_cleanup
347}
348
349ping_ipv4()
350{
351	ping_test $h1 192.0.2.3 ": local->remote 1 through VxLAN with an 802.1ad bridge"
352	ping_test $h2 192.0.2.4 ": local->remote 2 through VxLAN with an 802.1d bridge"
353}
354
355test_all()
356{
357	echo "Running tests with UDP port $VXPORT"
358	tests_run
359}
360
361trap cleanup EXIT
362
363setup_prepare
364setup_wait
365test_all
366
367exit $EXIT_STATUS
368