xref: /openbmc/linux/tools/testing/selftests/net/forwarding/gre_multipath.sh (revision a0ae2562c6c4b2721d9fddba63b7286c13517d9f)
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4# Test traffic distribution when a wECMP route forwards traffic to two GRE
5# tunnels.
6#
7# +-------------------------+
8# | H1                      |
9# |               $h1 +     |
10# |      192.0.2.1/28 |     |
11# |  2001:db8:1::1/64 |     |
12# +-------------------|-----+
13#                     |
14# +-------------------|------------------------+
15# | SW1               |                        |
16# |              $ol1 +                        |
17# |      192.0.2.2/28                          |
18# |  2001:db8:1::2/64                          |
19# |                                            |
20# |  + g1a (gre)          + g1b (gre)          |
21# |    loc=192.0.2.65       loc=192.0.2.81     |
22# |    rem=192.0.2.66 --.   rem=192.0.2.82 --. |
23# |    tos=inherit      |   tos=inherit      | |
24# |  .------------------'                    | |
25# |  |                    .------------------' |
26# |  v                    v                    |
27# |  + $ul1.111 (vlan)    + $ul1.222 (vlan)    |
28# |  | 192.0.2.129/28     | 192.0.2.145/28     |
29# |   \                  /                     |
30# |    \________________/                      |
31# |            |                               |
32# |            + $ul1                          |
33# +------------|-------------------------------+
34#              |
35# +------------|-------------------------------+
36# | SW2        + $ul2                          |
37# |     _______|________                       |
38# |    /                \                      |
39# |   /                  \                     |
40# |  + $ul2.111 (vlan)    + $ul2.222 (vlan)    |
41# |  ^ 192.0.2.130/28     ^ 192.0.2.146/28     |
42# |  |                    |                    |
43# |  |                    '------------------. |
44# |  '------------------.                    | |
45# |  + g2a (gre)        | + g2b (gre)        | |
46# |    loc=192.0.2.66   |   loc=192.0.2.82   | |
47# |    rem=192.0.2.65 --'   rem=192.0.2.81 --' |
48# |    tos=inherit          tos=inherit        |
49# |                                            |
50# |              $ol2 +                        |
51# |     192.0.2.17/28 |                        |
52# |  2001:db8:2::1/64 |                        |
53# +-------------------|------------------------+
54#                     |
55# +-------------------|-----+
56# | H2                |     |
57# |               $h2 +     |
58# |     192.0.2.18/28       |
59# |  2001:db8:2::2/64       |
60# +-------------------------+
61
62ALL_TESTS="
63	ping_ipv4
64	ping_ipv6
65	multipath_ipv4
66	multipath_ipv6
67	multipath_ipv6_l4
68"
69
70NUM_NETIFS=6
71source lib.sh
72
73h1_create()
74{
75	simple_if_init $h1 192.0.2.1/28 2001:db8:1::1/64
76	ip route add vrf v$h1 192.0.2.16/28 via 192.0.2.2
77	ip route add vrf v$h1 2001:db8:2::/64 via 2001:db8:1::2
78}
79
80h1_destroy()
81{
82	ip route del vrf v$h1 2001:db8:2::/64 via 2001:db8:1::2
83	ip route del vrf v$h1 192.0.2.16/28 via 192.0.2.2
84	simple_if_fini $h1 192.0.2.1/28
85}
86
87sw1_create()
88{
89	simple_if_init $ol1 192.0.2.2/28 2001:db8:1::2/64
90	__simple_if_init $ul1 v$ol1
91	vlan_create $ul1 111 v$ol1 192.0.2.129/28
92	vlan_create $ul1 222 v$ol1 192.0.2.145/28
93
94	tunnel_create g1a gre 192.0.2.65 192.0.2.66 tos inherit dev v$ol1
95	__simple_if_init g1a v$ol1 192.0.2.65/32
96	ip route add vrf v$ol1 192.0.2.66/32 via 192.0.2.130
97
98	tunnel_create g1b gre 192.0.2.81 192.0.2.82 tos inherit dev v$ol1
99	__simple_if_init g1b v$ol1 192.0.2.81/32
100	ip route add vrf v$ol1 192.0.2.82/32 via 192.0.2.146
101
102	ip route add vrf v$ol1 192.0.2.16/28 \
103	   nexthop dev g1a \
104	   nexthop dev g1b
105	ip route add vrf v$ol1 2001:db8:2::/64 \
106	   nexthop dev g1a \
107	   nexthop dev g1b
108
109	tc qdisc add dev $ul1 clsact
110	tc filter add dev $ul1 egress pref 111 prot 802.1q \
111	   flower vlan_id 111 action pass
112	tc filter add dev $ul1 egress pref 222 prot 802.1q \
113	   flower vlan_id 222 action pass
114}
115
116sw1_destroy()
117{
118	tc qdisc del dev $ul1 clsact
119
120	ip route del vrf v$ol1 2001:db8:2::/64
121	ip route del vrf v$ol1 192.0.2.16/28
122
123	ip route del vrf v$ol1 192.0.2.82/32 via 192.0.2.146
124	__simple_if_fini g1b 192.0.2.81/32
125	tunnel_destroy g1b
126
127	ip route del vrf v$ol1 192.0.2.66/32 via 192.0.2.130
128	__simple_if_fini g1a 192.0.2.65/32
129	tunnel_destroy g1a
130
131	vlan_destroy $ul1 222
132	vlan_destroy $ul1 111
133	__simple_if_fini $ul1
134	simple_if_fini $ol1 192.0.2.2/28 2001:db8:1::2/64
135}
136
137sw2_create()
138{
139	simple_if_init $ol2 192.0.2.17/28 2001:db8:2::1/64
140	__simple_if_init $ul2 v$ol2
141	vlan_create $ul2 111 v$ol2 192.0.2.130/28
142	vlan_create $ul2 222 v$ol2 192.0.2.146/28
143
144	tunnel_create g2a gre 192.0.2.66 192.0.2.65 tos inherit dev v$ol2
145	__simple_if_init g2a v$ol2 192.0.2.66/32
146	ip route add vrf v$ol2 192.0.2.65/32 via 192.0.2.129
147
148	tunnel_create g2b gre 192.0.2.82 192.0.2.81 tos inherit dev v$ol2
149	__simple_if_init g2b v$ol2 192.0.2.82/32
150	ip route add vrf v$ol2 192.0.2.81/32 via 192.0.2.145
151
152	ip route add vrf v$ol2 192.0.2.0/28 \
153	   nexthop dev g2a \
154	   nexthop dev g2b
155	ip route add vrf v$ol2 2001:db8:1::/64 \
156	   nexthop dev g2a \
157	   nexthop dev g2b
158}
159
160sw2_destroy()
161{
162	ip route del vrf v$ol2 2001:db8:1::/64
163	ip route del vrf v$ol2 192.0.2.0/28
164
165	ip route del vrf v$ol2 192.0.2.81/32 via 192.0.2.145
166	__simple_if_fini g2b 192.0.2.82/32
167	tunnel_destroy g2b
168
169	ip route del vrf v$ol2 192.0.2.65/32 via 192.0.2.129
170	__simple_if_fini g2a 192.0.2.66/32
171	tunnel_destroy g2a
172
173	vlan_destroy $ul2 222
174	vlan_destroy $ul2 111
175	__simple_if_fini $ul2
176	simple_if_fini $ol2 192.0.2.17/28 2001:db8:2::1/64
177}
178
179h2_create()
180{
181	simple_if_init $h2 192.0.2.18/28 2001:db8:2::2/64
182	ip route add vrf v$h2 192.0.2.0/28 via 192.0.2.17
183	ip route add vrf v$h2 2001:db8:1::/64 via 2001:db8:2::1
184}
185
186h2_destroy()
187{
188	ip route del vrf v$h2 2001:db8:1::/64 via 2001:db8:2::1
189	ip route del vrf v$h2 192.0.2.0/28 via 192.0.2.17
190	simple_if_fini $h2 192.0.2.18/28 2001:db8:2::2/64
191}
192
193setup_prepare()
194{
195	h1=${NETIFS[p1]}
196	ol1=${NETIFS[p2]}
197
198	ul1=${NETIFS[p3]}
199	ul2=${NETIFS[p4]}
200
201	ol2=${NETIFS[p5]}
202	h2=${NETIFS[p6]}
203
204	vrf_prepare
205	h1_create
206	sw1_create
207	sw2_create
208	h2_create
209}
210
211cleanup()
212{
213	pre_cleanup
214
215	h2_destroy
216	sw2_destroy
217	sw1_destroy
218	h1_destroy
219	vrf_cleanup
220}
221
222multipath4_test()
223{
224	local what=$1; shift
225	local weight1=$1; shift
226	local weight2=$1; shift
227
228	sysctl_set net.ipv4.fib_multipath_hash_policy 1
229	ip route replace vrf v$ol1 192.0.2.16/28 \
230	   nexthop dev g1a weight $weight1 \
231	   nexthop dev g1b weight $weight2
232
233	local t0_111=$(tc_rule_stats_get $ul1 111 egress)
234	local t0_222=$(tc_rule_stats_get $ul1 222 egress)
235
236	ip vrf exec v$h1 \
237	   $MZ $h1 -q -p 64 -A 192.0.2.1 -B 192.0.2.18 \
238	       -d 1msec -t udp "sp=1024,dp=0-32768"
239
240	local t1_111=$(tc_rule_stats_get $ul1 111 egress)
241	local t1_222=$(tc_rule_stats_get $ul1 222 egress)
242
243	local d111=$((t1_111 - t0_111))
244	local d222=$((t1_222 - t0_222))
245	multipath_eval "$what" $weight1 $weight2 $d111 $d222
246
247	ip route replace vrf v$ol1 192.0.2.16/28 \
248	   nexthop dev g1a \
249	   nexthop dev g1b
250	sysctl_restore net.ipv4.fib_multipath_hash_policy
251}
252
253multipath6_l4_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 1
260	ip route replace vrf v$ol1 2001:db8:2::/64 \
261	   nexthop dev g1a weight $weight1 \
262	   nexthop dev g1b weight $weight2
263
264	local t0_111=$(tc_rule_stats_get $ul1 111 egress)
265	local t0_222=$(tc_rule_stats_get $ul1 222 egress)
266
267	ip vrf exec v$h1 \
268	   $MZ $h1 -6 -q -p 64 -A 2001:db8:1::1 -B 2001:db8:2::2 \
269	       -d 1msec -t udp "sp=1024,dp=0-32768"
270
271	local t1_111=$(tc_rule_stats_get $ul1 111 egress)
272	local t1_222=$(tc_rule_stats_get $ul1 222 egress)
273
274	local d111=$((t1_111 - t0_111))
275	local d222=$((t1_222 - t0_222))
276	multipath_eval "$what" $weight1 $weight2 $d111 $d222
277
278	ip route replace vrf v$ol1 2001:db8:2::/64 \
279	   nexthop dev g1a \
280	   nexthop dev g1b
281	sysctl_restore net.ipv6.fib_multipath_hash_policy
282}
283
284multipath6_test()
285{
286	local what=$1; shift
287	local weight1=$1; shift
288	local weight2=$1; shift
289
290	ip route replace vrf v$ol1 2001:db8:2::/64 \
291	   nexthop dev g1a weight $weight1 \
292	   nexthop dev g1b weight $weight2
293
294	local t0_111=$(tc_rule_stats_get $ul1 111 egress)
295	local t0_222=$(tc_rule_stats_get $ul1 222 egress)
296
297        # Generate 16384 echo requests, each with a random flow label.
298	for ((i=0; i < 16384; ++i)); do
299		ip vrf exec v$h1 $PING6 2001:db8:2::2 -F 0 -c 1 -q &> /dev/null
300	done
301
302	local t1_111=$(tc_rule_stats_get $ul1 111 egress)
303	local t1_222=$(tc_rule_stats_get $ul1 222 egress)
304
305	local d111=$((t1_111 - t0_111))
306	local d222=$((t1_222 - t0_222))
307	multipath_eval "$what" $weight1 $weight2 $d111 $d222
308
309	ip route replace vrf v$ol1 2001:db8:2::/64 \
310	   nexthop dev g1a \
311	   nexthop dev g1b
312}
313
314ping_ipv4()
315{
316	ping_test $h1 192.0.2.18
317}
318
319ping_ipv6()
320{
321	ping6_test $h1 2001:db8:2::2
322}
323
324multipath_ipv4()
325{
326	log_info "Running IPv4 multipath tests"
327	multipath4_test "ECMP" 1 1
328	multipath4_test "Weighted MP 2:1" 2 1
329	multipath4_test "Weighted MP 11:45" 11 45
330}
331
332multipath_ipv6()
333{
334	log_info "Running IPv6 multipath tests"
335	multipath6_test "ECMP" 1 1
336	multipath6_test "Weighted MP 2:1" 2 1
337	multipath6_test "Weighted MP 11:45" 11 45
338}
339
340multipath_ipv6_l4()
341{
342	log_info "Running IPv6 L4 hash multipath tests"
343	multipath6_l4_test "ECMP" 1 1
344	multipath6_l4_test "Weighted MP 2:1" 2 1
345	multipath6_l4_test "Weighted MP 11:45" 11 45
346}
347
348trap cleanup EXIT
349
350setup_prepare
351setup_wait
352tests_run
353
354exit $EXIT_STATUS
355