1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4# Test traffic distribution when there are multiple routes between an IPv6
5# GRE tunnel. The tunnel carries IPv6 traffic between multiple hosts.
6# Multiple routes are in the underlay network. With the default multipath
7# policy, SW2 will only look at the outer IP addresses, hence only a single
8# route would be used.
9#
10# +-------------------------+
11# | H1                      |
12# |               $h1 +     |
13# |  2001:db8:1::2/64 |     |
14# +-------------------|-----+
15#                     |
16# +-------------------|-------------------------+
17# | SW1               |                         |
18# |              $ol1 +                         |
19# |  2001:db8:1::1/64                           |
20# |                                             |
21# |  + g1 (gre)                                 |
22# |    loc=2001:db8:40::1                       |
23# |    rem=2001:db8:40::2 --.                   |
24# |    tos=inherit          |                   |
25# |                         v                   |
26# |                         + $ul1              |
27# |                         | 2001:db8:80::1/64 |
28# +-------------------------|-------------------+
29#                           |
30# +-------------------------|-------------------+
31# | SW2                     |                   |
32# |                   $ul21 +                   |
33# |       2001:db8:80::2/64                     |
34# |                   |                         |
35# !   ________________|_____                    |
36# |  /                      \                   |
37# |  |                      |                   |
38# |  + $ul22.111 (vlan)     + $ul22.222 (vlan)  |
39# |  | 2001:db8:81::1/64    | 2001:db8:82::1/64 |
40# |  |                      |                   |
41# +--|----------------------|-------------------+
42#    |                      |
43# +--|----------------------|-------------------+
44# |  |                      |                   |
45# |  + $ul32.111 (vlan)     + $ul32.222 (vlan)  |
46# |  | 2001:db8:81::2/64    | 2001:db8:82::2/64 |
47# |  |                      |                   |
48# |  \______________________/                   |
49# |                   |                         |
50# |                   |                         |
51# |                   $ul31 +                   |
52# |       2001:db8:83::2/64 |               SW3 |
53# +-------------------------|-------------------+
54#                           |
55# +-------------------------|-------------------+
56# |                         + $ul4              |
57# |                         ^ 2001:db8:83::1/64 |
58# |  + g2 (gre)             |                   |
59# |    loc=2001:db8:40::2   |                   |
60# |    rem=2001:db8:40::1 --'                   |
61# |    tos=inherit                              |
62# |                                             |
63# |               $ol4 +                        |
64# |   2001:db8:2::1/64 |                    SW4 |
65# +--------------------|------------------------+
66#                      |
67# +--------------------|---------+
68# |                    |         |
69# |                $h2 +         |
70# |   2001:db8:2::2/64        H2 |
71# +------------------------------+
72
73ALL_TESTS="
74	ping_ipv6
75	multipath_ipv6
76"
77
78NUM_NETIFS=10
79source lib.sh
80
81h1_create()
82{
83	simple_if_init $h1 2001:db8:1::2/64
84	ip -6 route add vrf v$h1 2001:db8:2::/64 via 2001:db8:1::1
85}
86
87h1_destroy()
88{
89	ip -6 route del vrf v$h1 2001:db8:2::/64 via 2001:db8:1::1
90	simple_if_fini $h1 2001:db8:1::2/64
91}
92
93sw1_create()
94{
95	simple_if_init $ol1 2001:db8:1::1/64
96	__simple_if_init $ul1 v$ol1 2001:db8:80::1/64
97
98	tunnel_create g1 ip6gre 2001:db8:40::1 2001:db8:40::2 tos inherit dev v$ol1
99	__simple_if_init g1 v$ol1 2001:db8:40::1/128
100	ip -6 route add vrf v$ol1 2001:db8:40::2/128 via 2001:db8:80::2
101
102	ip -6 route add vrf v$ol1 2001:db8:2::/64 dev g1
103}
104
105sw1_destroy()
106{
107	ip -6 route del vrf v$ol1 2001:db8:2::/64
108
109	ip -6 route del vrf v$ol1 2001:db8:40::2/128
110	__simple_if_fini g1 2001:db8:40::1/128
111	tunnel_destroy g1
112
113	__simple_if_fini $ul1 2001:db8:80::1/64
114	simple_if_fini $ol1 2001:db8:1::1/64
115}
116
117sw2_create()
118{
119	simple_if_init $ul21 2001:db8:80::2/64
120	__simple_if_init $ul22 v$ul21
121	vlan_create $ul22 111 v$ul21 2001:db8:81::1/64
122	vlan_create $ul22 222 v$ul21 2001:db8:82::1/64
123
124	ip -6 route add vrf v$ul21 2001:db8:40::1/128 via 2001:db8:80::1
125	ip -6 route add vrf v$ul21 2001:db8:40::2/128 \
126	   nexthop via 2001:db8:81::2 \
127	   nexthop via 2001:db8:82::2
128}
129
130sw2_destroy()
131{
132	ip -6 route del vrf v$ul21 2001:db8:40::2/128
133	ip -6 route del vrf v$ul21 2001:db8:40::1/128
134
135	vlan_destroy $ul22 222
136	vlan_destroy $ul22 111
137	__simple_if_fini $ul22
138	simple_if_fini $ul21 2001:db8:80::2/64
139}
140
141sw3_create()
142{
143	simple_if_init $ul31 2001:db8:83::2/64
144	__simple_if_init $ul32 v$ul31
145	vlan_create $ul32 111 v$ul31 2001:db8:81::2/64
146	vlan_create $ul32 222 v$ul31 2001:db8:82::2/64
147
148	ip -6 route add vrf v$ul31 2001:db8:40::2/128 via 2001:db8:83::1
149	ip -6 route add vrf v$ul31 2001:db8:40::1/128 \
150	   nexthop via 2001:db8:81::1 \
151	   nexthop via 2001:db8:82::1
152
153	tc qdisc add dev $ul32 clsact
154	tc filter add dev $ul32 ingress pref 111 prot 802.1Q \
155	   flower vlan_id 111 action pass
156	tc filter add dev $ul32 ingress pref 222 prot 802.1Q \
157	   flower vlan_id 222 action pass
158}
159
160sw3_destroy()
161{
162	tc qdisc del dev $ul32 clsact
163
164	ip -6 route del vrf v$ul31 2001:db8:40::1/128
165	ip -6 route del vrf v$ul31 2001:db8:40::2/128
166
167	vlan_destroy $ul32 222
168	vlan_destroy $ul32 111
169	__simple_if_fini $ul32
170	simple_if_fini $ul31 2001:Db8:83::2/64
171}
172
173sw4_create()
174{
175	simple_if_init $ol4 2001:db8:2::1/64
176	__simple_if_init $ul4 v$ol4 2001:db8:83::1/64
177
178	tunnel_create g2 ip6gre 2001:db8:40::2 2001:db8:40::1 tos inherit dev v$ol4
179	__simple_if_init g2 v$ol4 2001:db8:40::2/128
180	ip -6 route add vrf v$ol4 2001:db8:40::1/128 via 2001:db8:83::2
181
182	ip -6 route add vrf v$ol4 2001:db8:1::/64 dev g2
183}
184
185sw4_destroy()
186{
187	ip -6 route del vrf v$ol4 2001:db8:1::/64
188
189	ip -6 route del vrf v$ol4 2001:db8:40::1/128
190	__simple_if_fini g2 2001:db8:40::2/128
191	tunnel_destroy g2
192
193	__simple_if_fini $ul4 2001:db8:83::1/64
194	simple_if_fini $ol4 2001:db8:2::1/64
195}
196
197h2_create()
198{
199	simple_if_init $h2 2001:db8:2::2/64
200	ip -6 route add vrf v$h2 2001:db8:1::/64 via 2001:db8:2::1
201}
202
203h2_destroy()
204{
205	ip -6 route del vrf v$h2 2001:db8:1::/64 via 2001:db8:2::1
206	simple_if_fini $h2 2001:db8:2::2/64
207}
208
209setup_prepare()
210{
211	h1=${NETIFS[p1]}
212
213	ol1=${NETIFS[p2]}
214	ul1=${NETIFS[p3]}
215
216	ul21=${NETIFS[p4]}
217	ul22=${NETIFS[p5]}
218
219	ul32=${NETIFS[p6]}
220	ul31=${NETIFS[p7]}
221
222	ul4=${NETIFS[p8]}
223	ol4=${NETIFS[p9]}
224
225	h2=${NETIFS[p10]}
226
227	vrf_prepare
228	h1_create
229	sw1_create
230	sw2_create
231	sw3_create
232	sw4_create
233	h2_create
234
235	forwarding_enable
236}
237
238cleanup()
239{
240	pre_cleanup
241
242	forwarding_restore
243
244	h2_destroy
245	sw4_destroy
246	sw3_destroy
247	sw2_destroy
248	sw1_destroy
249	h1_destroy
250	vrf_cleanup
251}
252
253multipath6_test()
254{
255	local what=$1; shift
256	local weight1=$1; shift
257	local weight2=$1; shift
258
259	sysctl_set net.ipv6.fib_multipath_hash_policy 2
260	ip route replace vrf v$ul21 2001:db8:40::2/128 \
261	   nexthop via 2001:db8:81::2 weight $weight1 \
262	   nexthop via 2001:db8:82::2 weight $weight2
263
264	local t0_111=$(tc_rule_stats_get $ul32 111 ingress)
265	local t0_222=$(tc_rule_stats_get $ul32 222 ingress)
266
267	ip vrf exec v$h1 \
268	   $MZ $h1 -6 -q -p 64 -A "2001:db8:1::2-2001:db8:1::1e" \
269	       -B "2001:db8:2::2-2001:db8:2::1e" \
270	       -d 1msec -c 50 -t udp "sp=1024,dp=1024"
271	sleep 1
272
273	local t1_111=$(tc_rule_stats_get $ul32 111 ingress)
274	local t1_222=$(tc_rule_stats_get $ul32 222 ingress)
275
276	local d111=$((t1_111 - t0_111))
277	local d222=$((t1_222 - t0_222))
278	multipath_eval "$what" $weight1 $weight2 $d111 $d222
279
280	ip route replace vrf v$ul21 2001:db8:40::2/128 \
281	   nexthop via 2001:db8:81::2 \
282	   nexthop via 2001:db8:82::2
283	sysctl_restore net.ipv6.fib_multipath_hash_policy
284}
285
286ping_ipv6()
287{
288	ping_test $h1 2001:db8:2::2
289}
290
291multipath_ipv6()
292{
293	log_info "Running IPv6 over GRE over IPv6 multipath tests"
294	multipath6_test "ECMP" 1 1
295	multipath6_test "Weighted MP 2:1" 2 1
296	multipath6_test "Weighted MP 11:45" 11 45
297}
298
299trap cleanup EXIT
300
301setup_prepare
302setup_wait
303tests_run
304
305exit $EXIT_STATUS
306