1# SPDX-License-Identifier: GPL-2.0
2#!/bin/bash
3
4# Handles creation and destruction of IP-in-IP or GRE tunnels over the given
5# topology. Supports both flat and hierarchical models.
6#
7# Flat Model:
8# Overlay and underlay share the same VRF.
9# SW1 uses default VRF so tunnel has no bound dev.
10# SW2 uses non-default VRF tunnel has a bound dev.
11# +--------------------------------+
12# | H1                             |
13# |                     $h1 +      |
14# |        198.51.100.1/24  |      |
15# |        2001:db8:1::1/64 |      |
16# +-------------------------|------+
17#                           |
18# +-------------------------|-------------------+
19# | SW1                     |                   |
20# |                    $ol1 +                   |
21# |        198.51.100.2/24                      |
22# |        2001:db8:1::2/64                     |
23# |                                             |
24# |      + g1a (ip6gre)                         |
25# |        loc=2001:db8:3::1                    |
26# |        rem=2001:db8:3::2 --.                |
27# |        tos=inherit         |                |
28# |                            .                |
29# |      .---------------------                 |
30# |      |                                      |
31# |      v                                      |
32# |      + $ul1.111 (vlan)                      |
33# |      | 2001:db8:10::1/64                    |
34# |       \                                     |
35# |        \____________                        |
36# |                     |                       |
37# | VRF default         + $ul1                  |
38# +---------------------|-----------------------+
39#                       |
40# +---------------------|-----------------------+
41# | SW2                 |                       |
42# |                $ul2 +                       |
43# |          ___________|                       |
44# |         /                                   |
45# |        /                                    |
46# |       + $ul2.111 (vlan)                     |
47# |       ^ 2001:db8:10::2/64                   |
48# |       |                                     |
49# |       |                                     |
50# |       '----------------------.              |
51# |       + g2a (ip6gre)         |              |
52# |         loc=2001:db8:3::2    |              |
53# |         rem=2001:db8:3::1  --'              |
54# |         tos=inherit                         |
55# |                                             |
56# |                     + $ol2                  |
57# |                     | 203.0.113.2/24        |
58# | VRF v$ol2           | 2001:db8:2::2/64      |
59# +---------------------|-----------------------+
60# +---------------------|----------+
61# | H2                  |          |
62# |                 $h2 +          |
63# |    203.0.113.1/24              |
64# |    2001:db8:2::1/64            |
65# +--------------------------------+
66#
67# Hierarchical model:
68# The tunnel is bound to a device in a different VRF
69#
70# +--------------------------------+
71# | H1                             |
72# |                     $h1 +      |
73# |        198.51.100.1/24  |      |
74# |        2001:db8:1::1/64 |      |
75# +-------------------------|------+
76#                           |
77# +-------------------------|-------------------+
78# | SW1                     |                   |
79# | +-----------------------|-----------------+ |
80# | |                  $ol1 +                 | |
81# | |      198.51.100.2/24                    | |
82# | |      2001:db8:1::2/64                   | |
83# | |                                         | |
84# | |              + g1a (ip6gre)             | |
85# | |                loc=2001:db8:3::1        | |
86# | |                rem=2001:db8:3::2        | |
87# | |                tos=inherit              | |
88# | |                    ^                    | |
89# | |   VRF v$ol1        |                    | |
90# | +--------------------|--------------------+ |
91# |                      |                      |
92# | +--------------------|--------------------+ |
93# | |   VRF v$ul1        |                    | |
94# | |                    |                    | |
95# | |                    v                    | |
96# | |             dummy1 +                    | |
97# | |       2001:db8:3::1/64                  | |
98# | |         .-----------'                   | |
99# | |         |                               | |
100# | |         v                               | |
101# | |         + $ul1.111 (vlan)               | |
102# | |         | 2001:db8:10::1/64             | |
103# | |         \                               | |
104# | |          \__________                    | |
105# | |                     |                   | |
106# | |                     + $ul1              | |
107# | +---------------------|-------------------+ |
108# +-----------------------|---------------------+
109#                         |
110# +-----------------------|---------------------+
111# | SW2                   |                     |
112# | +---------------------|-------------------+ |
113# | |                     + $ul2              | |
114# | |                _____|                   | |
115# | |               /                         | |
116# | |              /                          | |
117# | |              | $ul2.111 (vlan)          | |
118# | |              + 2001:db8:10::2/64        | |
119# | |              ^                          | |
120# | |              |                          | |
121# | |              '------.                   | |
122# | |              dummy2 +                   | |
123# | |              2001:db8:3::2/64           | |
124# | |                     ^                   | |
125# | |                     |                   | |
126# | |                     |                   | |
127# | | VRF v$ul2           |                   | |
128# | +---------------------|-------------------+ |
129# |                       |                     |
130# | +---------------------|-------------------+ |
131# | | VRF v$ol2           |                   | |
132# | |                     |                   | |
133# | |                     v                   | |
134# | |        g2a (ip6gre) +                   | |
135# | |        loc=2001:db8:3::2                | |
136# | |        rem=2001:db8:3::1                | |
137# | |        tos=inherit                      | |
138# | |                                         | |
139# | |                $ol2 +                   | |
140# | |    203.0.113.2/24   |                   | |
141# | |    2001:db8:2::2/64 |                   | |
142# | +---------------------|-------------------+ |
143# +-----------------------|---------------------+
144#                         |
145# +-----------------------|--------+
146# | H2                    |        |
147# |                   $h2 +        |
148# |      203.0.113.1/24            |
149# |      2001:db8:2::1/64          |
150# +--------------------------------+
151
152source lib.sh
153source tc_common.sh
154
155h1_create()
156{
157	simple_if_init $h1 198.51.100.1/24 2001:db8:1::1/64
158	ip route add vrf v$h1 203.0.113.0/24 via 198.51.100.2
159	ip -6 route add vrf v$h1 2001:db8:2::/64 via 2001:db8:1::2
160}
161
162h1_destroy()
163{
164	ip -6 route del vrf v$h1 2001:db8:2::/64 via 2001:db8:1::2
165	ip route del vrf v$h1 203.0.113.0/24 via 198.51.100.2
166	simple_if_fini $h1 198.51.100.1/24 2001:db8:1::1/64
167}
168
169h2_create()
170{
171	simple_if_init $h2 203.0.113.1/24 2001:db8:2::1/64
172	ip route add vrf v$h2 198.51.100.0/24 via 203.0.113.2
173	ip -6 route add vrf v$h2 2001:db8:1::/64 via 2001:db8:2::2
174}
175
176h2_destroy()
177{
178	ip -6 route del vrf v$h2 2001:db8:1::/64 via 2001:db8:2::2
179	ip route del vrf v$h2 198.51.100.0/24 via 203.0.113.2
180	simple_if_fini $h2 203.0.113.1/24 2001:db8:2::1/64
181}
182
183sw1_flat_create()
184{
185	local ol1=$1; shift
186	local ul1=$1; shift
187
188	ip link set dev $ol1 up
189        __addr_add_del $ol1 add 198.51.100.2/24 2001:db8:1::2/64
190
191	ip link set dev $ul1 up
192	vlan_create $ul1 111 "" 2001:db8:10::1/64
193
194	tunnel_create g1a ip6gre 2001:db8:3::1 2001:db8:3::2 tos inherit \
195		ttl inherit "$@"
196	ip link set dev g1a up
197        __addr_add_del g1a add "2001:db8:3::1/128"
198
199	ip -6 route add 2001:db8:3::2/128 via 2001:db8:10::2
200	ip route add 203.0.113.0/24 dev g1a
201	ip -6 route add 2001:db8:2::/64 dev g1a
202}
203
204sw1_flat_destroy()
205{
206	local ol1=$1; shift
207	local ul1=$1; shift
208
209	ip -6 route del 2001:db8:2::/64
210	ip route del 203.0.113.0/24
211	ip -6 route del 2001:db8:3::2/128 via 2001:db8:10::2
212
213	__simple_if_fini g1a 2001:db8:3::1/128
214	tunnel_destroy g1a
215
216	vlan_destroy $ul1 111
217	__simple_if_fini $ul1
218	__simple_if_fini $ol1 198.51.100.2/24 2001:db8:1::2/64
219}
220
221sw2_flat_create()
222{
223	local ol2=$1; shift
224	local ul2=$1; shift
225
226	simple_if_init $ol2 203.0.113.2/24 2001:db8:2::2/64
227	__simple_if_init $ul2 v$ol2
228	vlan_create $ul2 111 v$ol2 2001:db8:10::2/64
229
230	tunnel_create g2a ip6gre 2001:db8:3::2 2001:db8:3::1 tos inherit \
231		ttl inherit dev v$ol2 "$@"
232	__simple_if_init g2a v$ol2 2001:db8:3::2/128
233
234	# Replace neighbor to avoid 1 dropped packet due to "unresolved neigh"
235	ip neigh replace dev $ol2 203.0.113.1 lladdr $(mac_get $h2)
236	ip -6 neigh replace dev $ol2 2001:db8:2::1 lladdr $(mac_get $h2)
237
238	ip -6 route add vrf v$ol2 2001:db8:3::1/128 via 2001:db8:10::1
239	ip route add vrf v$ol2 198.51.100.0/24 dev g2a
240	ip -6 route add vrf v$ol2 2001:db8:1::/64 dev g2a
241}
242
243sw2_flat_destroy()
244{
245	local ol2=$1; shift
246	local ul2=$1; shift
247
248	ip -6 route del vrf v$ol2 2001:db8:2::/64
249	ip route del vrf v$ol2 198.51.100.0/24
250	ip -6 route del vrf v$ol2 2001:db8:3::1/128 via 2001:db8:10::1
251
252	__simple_if_fini g2a 2001:db8:3::2/128
253	tunnel_destroy g2a
254
255	vlan_destroy $ul2 111
256	__simple_if_fini $ul2
257	simple_if_fini $ol2 203.0.113.2/24 2001:db8:2::2/64
258}
259
260sw1_hierarchical_create()
261{
262	local ol1=$1; shift
263	local ul1=$1; shift
264
265	simple_if_init $ol1 198.51.100.2/24 2001:db8:1::2/64
266	simple_if_init $ul1
267	ip link add name dummy1 type dummy
268	__simple_if_init dummy1 v$ul1 2001:db8:3::1/64
269
270	vlan_create $ul1 111 v$ul1 2001:db8:10::1/64
271	tunnel_create g1a ip6gre 2001:db8:3::1 2001:db8:3::2 tos inherit \
272		ttl inherit dev dummy1 "$@"
273	ip link set dev g1a master v$ol1
274
275	ip -6 route add vrf v$ul1 2001:db8:3::2/128 via 2001:db8:10::2
276	ip route add vrf v$ol1 203.0.113.0/24 dev g1a
277	ip -6 route add vrf v$ol1 2001:db8:2::/64 dev g1a
278}
279
280sw1_hierarchical_destroy()
281{
282	local ol1=$1; shift
283	local ul1=$1; shift
284
285	ip -6 route del vrf v$ol1 2001:db8:2::/64
286	ip route del vrf v$ol1 203.0.113.0/24
287	ip -6 route del vrf v$ul1 2001:db8:3::2/128
288
289	tunnel_destroy g1a
290	vlan_destroy $ul1 111
291
292	__simple_if_fini dummy1 2001:db8:3::1/64
293	ip link del dev dummy1
294
295	simple_if_fini $ul1
296	simple_if_fini $ol1 198.51.100.2/24 2001:db8:1::2/64
297}
298
299sw2_hierarchical_create()
300{
301	local ol2=$1; shift
302	local ul2=$1; shift
303
304	simple_if_init $ol2 203.0.113.2/24 2001:db8:2::2/64
305	simple_if_init $ul2
306
307	ip link add name dummy2 type dummy
308	__simple_if_init dummy2 v$ul2 2001:db8:3::2/64
309
310	vlan_create $ul2 111 v$ul2 2001:db8:10::2/64
311	tunnel_create g2a ip6gre 2001:db8:3::2 2001:db8:3::1 tos inherit \
312		ttl inherit dev dummy2 "$@"
313	ip link set dev g2a master v$ol2
314
315	# Replace neighbor to avoid 1 dropped packet due to "unresolved neigh"
316	ip neigh replace dev $ol2 203.0.113.1 lladdr $(mac_get $h2)
317	ip -6 neigh replace dev $ol2 2001:db8:2::1 lladdr $(mac_get $h2)
318
319	ip -6 route add vrf v$ul2 2001:db8:3::1/128 via 2001:db8:10::1
320	ip route add vrf v$ol2 198.51.100.0/24 dev g2a
321	ip -6 route add vrf v$ol2 2001:db8:1::/64 dev g2a
322}
323
324sw2_hierarchical_destroy()
325{
326	local ol2=$1; shift
327	local ul2=$1; shift
328
329	ip -6 route del vrf v$ol2 2001:db8:2::/64
330	ip route del vrf v$ol2 198.51.100.0/24
331	ip -6 route del vrf v$ul2 2001:db8:3::1/128
332
333	tunnel_destroy g2a
334	vlan_destroy $ul2 111
335
336	__simple_if_fini dummy2 2001:db8:3::2/64
337	ip link del dev dummy2
338
339	simple_if_fini $ul2
340	simple_if_fini $ol2 203.0.113.2/24 2001:db8:2::2/64
341}
342
343test_traffic_ip4ip6()
344{
345	RET=0
346
347	h1mac=$(mac_get $h1)
348	ol1mac=$(mac_get $ol1)
349
350	tc qdisc add dev $ul1 clsact
351	tc filter add dev $ul1 egress proto all pref 1 handle 101 \
352		flower $TC_FLAG action pass
353
354	tc qdisc add dev $ol2 clsact
355	tc filter add dev $ol2 egress protocol ipv4 pref 1 handle 101 \
356		flower $TC_FLAG dst_ip 203.0.113.1 action pass
357
358	$MZ $h1 -c 1000 -p 64 -a $h1mac -b $ol1mac -A 198.51.100.1 \
359		-B 203.0.113.1 -t ip -q -d $MZ_DELAY
360
361	# Check ports after encap and after decap.
362	tc_check_at_least_x_packets "dev $ul1 egress" 101 1000
363	check_err $? "Packets did not go through $ul1, tc_flag = $TC_FLAG"
364
365	tc_check_at_least_x_packets "dev $ol2 egress" 101 1000
366	check_err $? "Packets did not go through $ol2, tc_flag = $TC_FLAG"
367
368	log_test "$@"
369
370	tc filter del dev $ol2 egress protocol ipv4 pref 1 handle 101 flower
371	tc qdisc del dev $ol2 clsact
372	tc filter del dev $ul1 egress proto all pref 1 handle 101 flower
373	tc qdisc del dev $ul1 clsact
374}
375
376test_traffic_ip6ip6()
377{
378	RET=0
379
380	h1mac=$(mac_get $h1)
381	ol1mac=$(mac_get $ol1)
382
383	tc qdisc add dev $ul1 clsact
384	tc filter add dev $ul1 egress proto all pref 1 handle 101 \
385		flower $TC_FLAG action pass
386
387	tc qdisc add dev $ol2 clsact
388	tc filter add dev $ol2 egress protocol ipv6 pref 1 handle 101 \
389		flower $TC_FLAG dst_ip 2001:db8:2::1 action pass
390
391	$MZ -6 $h1 -c 1000 -p 64 -a $h1mac -b $ol1mac -A 2001:db8:1::1 \
392		-B 2001:db8:2::1 -t ip -q -d $MZ_DELAY
393
394	# Check ports after encap and after decap.
395	tc_check_at_least_x_packets "dev $ul1 egress" 101 1000
396	check_err $? "Packets did not go through $ul1, tc_flag = $TC_FLAG"
397
398	tc_check_at_least_x_packets "dev $ol2 egress" 101 1000
399	check_err $? "Packets did not go through $ol2, tc_flag = $TC_FLAG"
400
401	log_test "$@"
402
403	tc filter del dev $ol2 egress protocol ipv6 pref 1 handle 101 flower
404	tc qdisc del dev $ol2 clsact
405	tc filter del dev $ul1 egress proto all pref 1 handle 101 flower
406	tc qdisc del dev $ul1 clsact
407}
408
409topo_mtu_change()
410{
411	local mtu=$1
412
413	ip link set mtu $mtu dev $h1
414	ip link set mtu $mtu dev $ol1
415	ip link set mtu $mtu dev g1a
416	ip link set mtu $mtu dev $ul1
417	ip link set mtu $mtu dev $ul1.111
418	ip link set mtu $mtu dev $h2
419	ip link set mtu $mtu dev $ol2
420	ip link set mtu $mtu dev g2a
421	ip link set mtu $mtu dev $ul2
422	ip link set mtu $mtu dev $ul2.111
423}
424
425test_mtu_change()
426{
427	RET=0
428
429	ping6_do $h1 2001:db8:2::1 "-s 1800 -w 3"
430	check_fail $? "ping GRE IPv6 should not pass with packet size 1800"
431
432	RET=0
433
434	topo_mtu_change	2000
435	ping6_do $h1 2001:db8:2::1 "-s 1800 -w 3"
436	check_err $?
437	log_test "ping GRE IPv6, packet size 1800 after MTU change"
438}
439