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