Skip to content

Commit b1a5046

Browse files
committed
Merge branch 'Multipath-tests-for-tunnel-devices'
Petr Machata says: ==================== Multipath tests for tunnel devices This patchset adds a test for ECMP and weighted ECMP between two GRE tunnels. In patches #1 and #2, the function multipath_eval() is first moved from router_multipath.sh to lib.sh for ease of reuse, and then fixed up. In patch #3, the function tc_rule_stats_get() is parameterized to be useful for egress rules as well. In patch #4, a new function __simple_if_init() is extracted from simple_if_init(). This covers the logic that needs to be done for the usual interface: VRF migration, upping and installation of IP addresses. Patch #5 then adds the test itself. Additionally in patch torvalds#6, a requirement to add diagrams to selftests is documented. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
2 parents 3463e51 + 18ec44f commit b1a5046

File tree

4 files changed

+427
-48
lines changed

4 files changed

+427
-48
lines changed

tools/testing/selftests/net/forwarding/README

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ Guidelines for Writing Tests
4646

4747
o Where possible, reuse an existing topology for different tests instead
4848
of recreating the same topology.
49+
o Tests that use anything but the most trivial topologies should include
50+
an ASCII art showing the topology.
4951
o Where possible, IPv6 and IPv4 addresses shall conform to RFC 3849 and
5052
RFC 5737, respectively.
5153
o Where possible, tests shall be written so that they can be reused by
Lines changed: 354 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,354 @@
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+
62+
ALL_TESTS="
63+
ping_ipv4
64+
ping_ipv6
65+
multipath_ipv4
66+
multipath_ipv6
67+
multipath_ipv6_l4
68+
"
69+
70+
NUM_NETIFS=6
71+
source lib.sh
72+
73+
h1_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+
80+
h1_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+
87+
sw1_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+
116+
sw1_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+
137+
sw2_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+
160+
sw2_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+
179+
h2_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+
186+
h2_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+
193+
setup_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+
211+
cleanup()
212+
{
213+
pre_cleanup
214+
215+
h2_destroy
216+
sw2_destroy
217+
sw1_destroy
218+
h1_destroy
219+
vrf_cleanup
220+
}
221+
222+
multipath4_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+
253+
multipath6_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+
284+
multipath6_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+
314+
ping_ipv4()
315+
{
316+
ping_test $h1 192.0.2.18
317+
}
318+
319+
ping_ipv6()
320+
{
321+
ping6_test $h1 2001:db8:2::2
322+
}
323+
324+
multipath_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+
332+
multipath_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+
340+
multipath_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+
348+
trap cleanup EXIT
349+
350+
setup_prepare
351+
setup_wait
352+
tests_run
353+
354+
exit $EXIT_STATUS

0 commit comments

Comments
 (0)