1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4# +--------------------------------+            +-----------------------------+
5# |                         vrf-h1 |            |                      vrf-h2 |
6# |    + $h1                       |            | + $h2                       |
7# |    | 2001:db8:1::1/64          |            | | 2001:db8:2::1/64          |
8# |    | default via 2001:db8:1::3 |            | | default via 2001:db8:2::3 |
9# +----|---------------------------+            +-|---------------------------+
10#      |                                          |
11# +----|------------------------------------------|---------------------------+
12# | SW |                                          |                           |
13# | +--|------------------------------------------|-------------------------+ |
14# | |  + $swp1                         br1        + $swp2                   | |
15# | |     vid 10 pvid untagged                       vid 20 pvid untagged   | |
16# | |                                                                       | |
17# | |  + vx10                                     + vx20                    | |
18# | |    local 2001:db8:3::1                        local 2001:db8:3::1     | |
19# | |    remote 2001:db8:3::2                       remote 2001:db8:3::2    | |
20# | |    id 1000                                    id 2000                 | |
21# | |    dstport 4789                               dstport 4789            | |
22# | |    vid 10 pvid untagged                       vid 20 pvid untagged    | |
23# | |                                                                       | |
24# | +-----------------------------------+-----------------------------------+ |
25# |                                     |                                     |
26# | +-----------------------------------|-----------------------------------+ |
27# | |                                   |                                   | |
28# | |  +--------------------------------+--------------------------------+  | |
29# | |  |                                                                 |  | |
30# | |  + vlan10                                                   vlan20 +  | |
31# | |  | 2001:db8:1::2/64                               2001:db8:2::2/64 |  | |
32# | |  |                                                                 |  | |
33# | |  + vlan10-v (macvlan)                           vlan20-v (macvlan) +  | |
34# | |    2001:db8:1::3/64                               2001:db8:2::3/64    | |
35# | |    00:00:5e:00:01:01                             00:00:5e:00:01:01    | |
36# | |                               vrf-green                               | |
37# | +-----------------------------------------------------------------------+ |
38# |                                                                           |
39# |    + $rp1                                       +lo                       |
40# |    | 2001:db8:4::1/64                            2001:db8:3::1/128        |
41# +----|----------------------------------------------------------------------+
42#      |
43# +----|--------------------------------------------------------+
44# |    |                            vrf-spine                   |
45# |    + $rp2                                                   |
46# |      2001:db8:4::2/64                                       |
47# |                                                             |   (maybe) HW
48# =============================================================================
49# |                                                             |  (likely) SW
50# |                                                             |
51# |    + v1 (veth)                                              |
52# |    | 2001:db8:5::2/64                                       |
53# +----|--------------------------------------------------------+
54#      |
55# +----|----------------------------------------------------------------------+
56# |    + v2 (veth)                                  +lo           NS1 (netns) |
57# |      2001:db8:5::1/64                            2001:db8:3::2/128        |
58# |                                                                           |
59# | +-----------------------------------------------------------------------+ |
60# | |                               vrf-green                               | |
61# | |  + vlan10-v (macvlan)                           vlan20-v (macvlan) +  | |
62# | |  | 2001:db8:1::3/64                               2001:db8:2::3/64 |  | |
63# | |  | 00:00:5e:00:01:01                             00:00:5e:00:01:01 |  | |
64# | |  |                                                                 |  | |
65# | |  + vlan10                                                   vlan20 +  | |
66# | |  | 2001:db8:1::3/64                               2001:db8:2::3/64 |  | |
67# | |  |                                                                 |  | |
68# | |  +--------------------------------+--------------------------------+  | |
69# | |                                   |                                   | |
70# | +-----------------------------------|-----------------------------------+ |
71# |                                     |                                     |
72# | +-----------------------------------+-----------------------------------+ |
73# | |                                                                       | |
74# | |  + vx10                                     + vx20                    | |
75# | |    local 2001:db8:3::2                        local 2001:db8:3::2     | |
76# | |    remote 2001:db8:3::1                       remote 2001:db8:3::1    | |
77# | |    id 1000                                    id 2000                 | |
78# | |    dstport 4789                               dstport 4789            | |
79# | |    vid 10 pvid untagged                       vid 20 pvid untagged    | |
80# | |                                                                       | |
81# | |  + w1 (veth)                                + w3 (veth)               | |
82# | |  | vid 10 pvid untagged          br1        | vid 20 pvid untagged    | |
83# | +--|------------------------------------------|-------------------------+ |
84# |    |                                          |                           |
85# |    |                                          |                           |
86# | +--|----------------------+                +--|-------------------------+ |
87# | |  |               vrf-h1 |                |  |                  vrf-h2 | |
88# | |  + w2 (veth)            |                |  + w4 (veth)               | |
89# | |    2001:db8:1::4/64     |                |    2001:db8:2::4/64        | |
90# | |    default via          |                |    default via             | |
91# | |    2001:db8:1::3/64     |                |    2001:db8:2::3/64        | |
92# | +-------------------------+                +----------------------------+ |
93# +---------------------------------------------------------------------------+
94
95ALL_TESTS="
96	ping_ipv6
97	arp_decap
98"
99NUM_NETIFS=6
100source lib.sh
101
102require_command $ARPING
103
104hx_create()
105{
106	local vrf_name=$1; shift
107	local if_name=$1; shift
108	local ip_addr=$1; shift
109	local gw_ip=$1; shift
110
111	vrf_create $vrf_name
112	ip link set dev $if_name master $vrf_name
113	ip link set dev $vrf_name up
114	ip link set dev $if_name up
115
116	ip address add $ip_addr/64 dev $if_name
117	ip neigh replace $gw_ip lladdr 00:00:5e:00:01:01 nud permanent \
118		dev $if_name
119	ip route add default vrf $vrf_name nexthop via $gw_ip
120}
121export -f hx_create
122
123hx_destroy()
124{
125	local vrf_name=$1; shift
126	local if_name=$1; shift
127	local ip_addr=$1; shift
128	local gw_ip=$1; shift
129
130	ip route del default vrf $vrf_name nexthop via $gw_ip
131	ip neigh del $gw_ip dev $if_name
132	ip address del $ip_addr/64 dev $if_name
133
134	ip link set dev $if_name down
135	vrf_destroy $vrf_name
136}
137
138h1_create()
139{
140	hx_create "vrf-h1" $h1 2001:db8:1::1 2001:db8:1::3
141}
142
143h1_destroy()
144{
145	hx_destroy "vrf-h1" $h1 2001:db8:1::1 2001:db8:1::3
146}
147
148h2_create()
149{
150	hx_create "vrf-h2" $h2 2001:db8:2::1 2001:db8:2::3
151}
152
153h2_destroy()
154{
155	hx_destroy "vrf-h2" $h2 2001:db8:2::1 2001:db8:2::3
156}
157
158switch_create()
159{
160	ip link add name br1 type bridge vlan_filtering 1 vlan_default_pvid 0 \
161		mcast_snooping 0
162	# Make sure the bridge uses the MAC address of the local port and not
163	# that of the VxLAN's device.
164	ip link set dev br1 address $(mac_get $swp1)
165	ip link set dev br1 up
166
167	ip link set dev $rp1 up
168	ip address add dev $rp1 2001:db8:4::1/64
169	ip route add 2001:db8:3::2/128 nexthop via 2001:db8:4::2
170
171	ip link add name vx10 type vxlan id 1000		\
172		local 2001:db8:3::1 remote 2001:db8:3::2 dstport 4789	\
173		nolearning udp6zerocsumrx udp6zerocsumtx tos inherit ttl 100
174	ip link set dev vx10 up
175
176	ip link set dev vx10 master br1
177	bridge vlan add vid 10 dev vx10 pvid untagged
178
179	ip link add name vx20 type vxlan id 2000		\
180		local 2001:db8:3::1 remote 2001:db8:3::2 dstport 4789	\
181		nolearning udp6zerocsumrx udp6zerocsumtx tos inherit ttl 100
182	ip link set dev vx20 up
183
184	ip link set dev vx20 master br1
185	bridge vlan add vid 20 dev vx20 pvid untagged
186
187	ip link set dev $swp1 master br1
188	ip link set dev $swp1 up
189	bridge vlan add vid 10 dev $swp1 pvid untagged
190
191	ip link set dev $swp2 master br1
192	ip link set dev $swp2 up
193	bridge vlan add vid 20 dev $swp2 pvid untagged
194
195	ip address add 2001:db8:3::1/128 dev lo
196
197	# Create SVIs
198	vrf_create "vrf-green"
199	ip link set dev vrf-green up
200
201	ip link add link br1 name vlan10 up master vrf-green type vlan id 10
202	ip address add 2001:db8:1::2/64 dev vlan10
203	ip link add link vlan10 name vlan10-v up master vrf-green \
204		address 00:00:5e:00:01:01 type macvlan mode private
205	ip address add 2001:db8:1::3/64 dev vlan10-v
206
207	ip link add link br1 name vlan20 up master vrf-green type vlan id 20
208	ip address add 2001:db8:2::2/64 dev vlan20
209	ip link add link vlan20 name vlan20-v up master vrf-green \
210		address 00:00:5e:00:01:01 type macvlan mode private
211	ip address add 2001:db8:2::3/64 dev vlan20-v
212
213	bridge vlan add vid 10 dev br1 self
214	bridge vlan add vid 20 dev br1 self
215
216	bridge fdb add 00:00:5e:00:01:01 dev br1 self local vlan 10
217	bridge fdb add 00:00:5e:00:01:01 dev br1 self local vlan 20
218
219}
220
221switch_destroy()
222{
223	bridge fdb del 00:00:5e:00:01:01 dev br1 self local vlan 20
224	bridge fdb del 00:00:5e:00:01:01 dev br1 self local vlan 10
225
226	bridge vlan del vid 20 dev br1 self
227	bridge vlan del vid 10 dev br1 self
228
229	ip link del dev vlan20
230
231	ip link del dev vlan10
232
233	vrf_destroy "vrf-green"
234
235	ip address del 2001:db8:3::1/128 dev lo
236
237	bridge vlan del vid 20 dev $swp2
238	ip link set dev $swp2 down
239	ip link set dev $swp2 nomaster
240
241	bridge vlan del vid 10 dev $swp1
242	ip link set dev $swp1 down
243	ip link set dev $swp1 nomaster
244
245	bridge vlan del vid 20 dev vx20
246	ip link set dev vx20 nomaster
247
248	ip link set dev vx20 down
249	ip link del dev vx20
250
251	bridge vlan del vid 10 dev vx10
252	ip link set dev vx10 nomaster
253
254	ip link set dev vx10 down
255	ip link del dev vx10
256
257	ip route del 2001:db8:3::2 nexthop via 2001:db8:4::2
258	ip address del dev $rp1 2001:db8:4::1/64
259	ip link set dev $rp1 down
260
261	ip link set dev br1 down
262	ip link del dev br1
263}
264
265spine_create()
266{
267	vrf_create "vrf-spine"
268	ip link set dev $rp2 master vrf-spine
269	ip link set dev v1 master vrf-spine
270	ip link set dev vrf-spine up
271	ip link set dev $rp2 up
272	ip link set dev v1 up
273
274	ip address add 2001:db8:4::2/64 dev $rp2
275	ip address add 2001:db8:5::2/64 dev v1
276
277	ip route add 2001:db8:3::1/128 vrf vrf-spine nexthop via \
278		2001:db8:4::1
279	ip route add 2001:db8:3::2/128 vrf vrf-spine nexthop via \
280		2001:db8:5::1
281}
282
283spine_destroy()
284{
285	ip route del 2001:db8:3::2/128 vrf vrf-spine nexthop via \
286		2001:db8:5::1
287	ip route del 2001:db8:3::1/128 vrf vrf-spine nexthop via \
288		2001:db8:4::1
289
290	ip address del 2001:db8:5::2/64 dev v1
291	ip address del 2001:db8:4::2/64 dev $rp2
292
293	ip link set dev v1 down
294	ip link set dev $rp2 down
295	vrf_destroy "vrf-spine"
296}
297
298ns_h1_create()
299{
300	hx_create "vrf-h1" w2 2001:db8:1::4 2001:db8:1::3
301}
302export -f ns_h1_create
303
304ns_h2_create()
305{
306	hx_create "vrf-h2" w4 2001:db8:2::4 2001:db8:2::3
307}
308export -f ns_h2_create
309
310ns_switch_create()
311{
312	ip link add name br1 type bridge vlan_filtering 1 vlan_default_pvid 0 \
313		mcast_snooping 0
314	ip link set dev br1 up
315
316	ip link set dev v2 up
317	ip address add dev v2 2001:db8:5::1/64
318	ip route add 2001:db8:3::1 nexthop via 2001:db8:5::2
319
320	ip link add name vx10 type vxlan id 1000		\
321		local 2001:db8:3::2 remote 2001:db8:3::1 dstport 4789	\
322		nolearning udp6zerocsumrx udp6zerocsumtx tos inherit ttl 100
323	ip link set dev vx10 up
324
325	ip link set dev vx10 master br1
326	bridge vlan add vid 10 dev vx10 pvid untagged
327
328	ip link add name vx20 type vxlan id 2000		\
329		local 2001:db8:3::2 remote 2001:db8:3::1 dstport 4789	\
330		nolearning udp6zerocsumrx udp6zerocsumtx tos inherit ttl 100
331	ip link set dev vx20 up
332
333	ip link set dev vx20 master br1
334	bridge vlan add vid 20 dev vx20 pvid untagged
335
336	ip link set dev w1 master br1
337	ip link set dev w1 up
338	bridge vlan add vid 10 dev w1 pvid untagged
339
340	ip link set dev w3 master br1
341	ip link set dev w3 up
342	bridge vlan add vid 20 dev w3 pvid untagged
343
344	ip address add 2001:db8:3::2/128 dev lo
345
346	# Create SVIs
347	vrf_create "vrf-green"
348	ip link set dev vrf-green up
349
350	ip link add link br1 name vlan10 up master vrf-green type vlan id 10
351	ip address add 2001:db8:1::3/64 dev vlan10
352	ip link add link vlan10 name vlan10-v up master vrf-green \
353		address 00:00:5e:00:01:01 type macvlan mode private
354	ip address add 2001:db8:1::3/64 dev vlan10-v
355
356	ip link add link br1 name vlan20 up master vrf-green type vlan id 20
357	ip address add 2001:db8:2::3/64 dev vlan20
358	ip link add link vlan20 name vlan20-v up master vrf-green \
359		address 00:00:5e:00:01:01 type macvlan mode private
360	ip address add 2001:db8:2::3/64 dev vlan20-v
361
362	bridge vlan add vid 10 dev br1 self
363	bridge vlan add vid 20 dev br1 self
364
365	bridge fdb add 00:00:5e:00:01:01 dev br1 self local vlan 10
366	bridge fdb add 00:00:5e:00:01:01 dev br1 self local vlan 20
367}
368export -f ns_switch_create
369
370ns_init()
371{
372	ip link add name w1 type veth peer name w2
373	ip link add name w3 type veth peer name w4
374
375	ip link set dev lo up
376
377	ns_h1_create
378	ns_h2_create
379	ns_switch_create
380}
381export -f ns_init
382
383ns1_create()
384{
385	ip netns add ns1
386	ip link set dev v2 netns ns1
387	in_ns ns1 ns_init
388}
389
390ns1_destroy()
391{
392	ip netns exec ns1 ip link set dev v2 netns 1
393	ip netns del ns1
394}
395
396macs_populate()
397{
398	local mac1=$1; shift
399	local mac2=$1; shift
400	local ip1=$1; shift
401	local ip2=$1; shift
402	local dst=$1; shift
403
404	bridge fdb add $mac1 dev vx10 self master extern_learn static \
405		dst $dst vlan 10
406	bridge fdb add $mac2 dev vx20 self master extern_learn static \
407		dst $dst vlan 20
408
409	ip neigh add $ip1 lladdr $mac1 nud noarp dev vlan10 \
410		extern_learn
411	ip neigh add $ip2 lladdr $mac2 nud noarp dev vlan20 \
412		extern_learn
413}
414export -f macs_populate
415
416macs_initialize()
417{
418	local h1_ns_mac=$(in_ns ns1 mac_get w2)
419	local h2_ns_mac=$(in_ns ns1 mac_get w4)
420	local h1_mac=$(mac_get $h1)
421	local h2_mac=$(mac_get $h2)
422
423	macs_populate $h1_ns_mac $h2_ns_mac 2001:db8:1::4 2001:db8:2::4 \
424		2001:db8:3::2
425	in_ns ns1 macs_populate $h1_mac $h2_mac 2001:db8:1::1 2001:db8:2::1 \
426		2001:db8:3::1
427}
428
429setup_prepare()
430{
431	h1=${NETIFS[p1]}
432	swp1=${NETIFS[p2]}
433
434	swp2=${NETIFS[p3]}
435	h2=${NETIFS[p4]}
436
437	rp1=${NETIFS[p5]}
438	rp2=${NETIFS[p6]}
439
440	vrf_prepare
441	forwarding_enable
442
443	h1_create
444	h2_create
445	switch_create
446
447	ip link add name v1 type veth peer name v2
448	spine_create
449	ns1_create
450	in_ns ns1 forwarding_enable
451
452	macs_initialize
453}
454
455cleanup()
456{
457	pre_cleanup
458
459	ns1_destroy
460	spine_destroy
461	ip link del dev v1
462
463	switch_destroy
464	h2_destroy
465	h1_destroy
466
467	forwarding_restore
468	vrf_cleanup
469}
470
471ping_ipv6()
472{
473	ping6_test $h1 2001:db8:2::1 ": local->local vid 10->vid 20"
474	ping6_test $h1 2001:db8:1::4 ": local->remote vid 10->vid 10"
475	ping6_test $h2 2001:db8:2::4 ": local->remote vid 20->vid 20"
476	ping6_test $h1 2001:db8:2::4 ": local->remote vid 10->vid 20"
477	ping6_test $h2 2001:db8:1::4 ": local->remote vid 20->vid 10"
478}
479
480arp_decap()
481{
482	# Repeat the ping tests, but without populating the neighbours. This
483	# makes sure we correctly decapsulate ARP packets
484	log_info "deleting neighbours from vlan interfaces"
485
486	ip neigh del 2001:db8:1::4 dev vlan10
487	ip neigh del 2001:db8:2::4 dev vlan20
488
489	ping_ipv6
490
491	ip neigh replace 2001:db8:1::4 lladdr $(in_ns ns1 mac_get w2) \
492		nud noarp dev vlan10 extern_learn
493	ip neigh replace 2001:db8:2::4 lladdr $(in_ns ns1 mac_get w4) \
494		nud noarp dev vlan20 extern_learn
495}
496
497trap cleanup EXIT
498
499setup_prepare
500setup_wait
501
502tests_run
503
504exit $EXIT_STATUS
505