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