xref: /linux/tools/testing/selftests/net/forwarding/router_mpath_nh_res.sh (revision 9410645520e9b820069761f3450ef6661418e279)
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4# +-------------------------+
5# |  H1                     |
6# |               $h1 +     |
7# |      192.0.2.2/24 |     |
8# |  2001:db8:1::2/64 |     |
9# +-------------------|-----+
10#                     |
11# +-------------------|----------------------+
12# |                   |                   R1 |
13# |             $rp11 +                      |
14# |      192.0.2.1/24                        |
15# |  2001:db8:1::1/64                        |
16# |                                          |
17# |  + $rp12              + $rp13            |
18# |  | 169.254.2.12/24    | 169.254.3.13/24  |
19# |  | fe80:2::12/64      | fe80:3::13/64    |
20# +--|--------------------|------------------+
21#    |                    |
22# +--|--------------------|------------------+
23# |  + $rp22              + $rp23            |
24# |    169.254.2.22/24      169.254.3.23/24  |
25# |    fe80:2::22/64        fe80:3::23/64    |
26# |                                          |
27# |             $rp21 +                      |
28# |   198.51.100.1/24 |                      |
29# |  2001:db8:2::1/64 |                   R2 |
30# +-------------------|----------------------+
31#                     |
32# +-------------------|-----+
33# |                   |     |
34# |               $h2 +     |
35# |   198.51.100.2/24       |
36# |  2001:db8:2::2/64    H2 |
37# +-------------------------+
38
39ALL_TESTS="
40	ping_ipv4
41	ping_ipv6
42	multipath_test
43	multipath16_test
44	nh_stats_test_v4
45	nh_stats_test_v6
46"
47NUM_NETIFS=8
48source lib.sh
49source router_mpath_nh_lib.sh
50
51h1_create()
52{
53	vrf_create "vrf-h1"
54	ip link set dev $h1 master vrf-h1
55
56	ip link set dev vrf-h1 up
57	ip link set dev $h1 up
58
59	ip address add 192.0.2.2/24 dev $h1
60	ip address add 2001:db8:1::2/64 dev $h1
61
62	ip route add 198.51.100.0/24 vrf vrf-h1 nexthop via 192.0.2.1
63	ip route add 2001:db8:2::/64 vrf vrf-h1 nexthop via 2001:db8:1::1
64}
65
66h1_destroy()
67{
68	ip route del 2001:db8:2::/64 vrf vrf-h1
69	ip route del 198.51.100.0/24 vrf vrf-h1
70
71	ip address del 2001:db8:1::2/64 dev $h1
72	ip address del 192.0.2.2/24 dev $h1
73
74	ip link set dev $h1 down
75	vrf_destroy "vrf-h1"
76}
77
78h2_create()
79{
80	vrf_create "vrf-h2"
81	ip link set dev $h2 master vrf-h2
82
83	ip link set dev vrf-h2 up
84	ip link set dev $h2 up
85
86	ip address add 198.51.100.2/24 dev $h2
87	ip address add 2001:db8:2::2/64 dev $h2
88
89	ip route add 192.0.2.0/24 vrf vrf-h2 nexthop via 198.51.100.1
90	ip route add 2001:db8:1::/64 vrf vrf-h2 nexthop via 2001:db8:2::1
91}
92
93h2_destroy()
94{
95	ip route del 2001:db8:1::/64 vrf vrf-h2
96	ip route del 192.0.2.0/24 vrf vrf-h2
97
98	ip address del 2001:db8:2::2/64 dev $h2
99	ip address del 198.51.100.2/24 dev $h2
100
101	ip link set dev $h2 down
102	vrf_destroy "vrf-h2"
103}
104
105router1_create()
106{
107	vrf_create "vrf-r1"
108	ip link set dev $rp11 master vrf-r1
109	ip link set dev $rp12 master vrf-r1
110	ip link set dev $rp13 master vrf-r1
111
112	ip link set dev vrf-r1 up
113	ip link set dev $rp11 up
114	ip link set dev $rp12 up
115	ip link set dev $rp13 up
116
117	ip address add 192.0.2.1/24 dev $rp11
118	ip address add 2001:db8:1::1/64 dev $rp11
119
120	ip address add 169.254.2.12/24 dev $rp12
121	ip address add fe80:2::12/64 dev $rp12
122
123	ip address add 169.254.3.13/24 dev $rp13
124	ip address add fe80:3::13/64 dev $rp13
125}
126
127router1_destroy()
128{
129	ip route del 2001:db8:2::/64 vrf vrf-r1
130	ip route del 198.51.100.0/24 vrf vrf-r1
131
132	ip address del fe80:3::13/64 dev $rp13
133	ip address del 169.254.3.13/24 dev $rp13
134
135	ip address del fe80:2::12/64 dev $rp12
136	ip address del 169.254.2.12/24 dev $rp12
137
138	ip address del 2001:db8:1::1/64 dev $rp11
139	ip address del 192.0.2.1/24 dev $rp11
140
141	ip nexthop del id 103
142	ip nexthop del id 101
143	ip nexthop del id 102
144	ip nexthop del id 106
145	ip nexthop del id 104
146	ip nexthop del id 105
147
148	ip link set dev $rp13 down
149	ip link set dev $rp12 down
150	ip link set dev $rp11 down
151
152	vrf_destroy "vrf-r1"
153}
154
155router2_create()
156{
157	vrf_create "vrf-r2"
158	ip link set dev $rp21 master vrf-r2
159	ip link set dev $rp22 master vrf-r2
160	ip link set dev $rp23 master vrf-r2
161
162	ip link set dev vrf-r2 up
163	ip link set dev $rp21 up
164	ip link set dev $rp22 up
165	ip link set dev $rp23 up
166
167	ip address add 198.51.100.1/24 dev $rp21
168	ip address add 2001:db8:2::1/64 dev $rp21
169
170	ip address add 169.254.2.22/24 dev $rp22
171	ip address add fe80:2::22/64 dev $rp22
172
173	ip address add 169.254.3.23/24 dev $rp23
174	ip address add fe80:3::23/64 dev $rp23
175}
176
177router2_destroy()
178{
179	ip route del 2001:db8:1::/64 vrf vrf-r2
180	ip route del 192.0.2.0/24 vrf vrf-r2
181
182	ip address del fe80:3::23/64 dev $rp23
183	ip address del 169.254.3.23/24 dev $rp23
184
185	ip address del fe80:2::22/64 dev $rp22
186	ip address del 169.254.2.22/24 dev $rp22
187
188	ip address del 2001:db8:2::1/64 dev $rp21
189	ip address del 198.51.100.1/24 dev $rp21
190
191	ip nexthop del id 201
192	ip nexthop del id 202
193	ip nexthop del id 204
194	ip nexthop del id 205
195
196	ip link set dev $rp23 down
197	ip link set dev $rp22 down
198	ip link set dev $rp21 down
199
200	vrf_destroy "vrf-r2"
201}
202
203routing_nh_obj()
204{
205	ip nexthop add id 101 via 169.254.2.22 dev $rp12
206	ip nexthop add id 102 via 169.254.3.23 dev $rp13
207	ip nexthop add id 103 group 101/102 type resilient buckets 512 \
208		idle_timer 0
209	ip route add 198.51.100.0/24 vrf vrf-r1 nhid 103
210
211	ip nexthop add id 104 via fe80:2::22 dev $rp12
212	ip nexthop add id 105 via fe80:3::23 dev $rp13
213	ip nexthop add id 106 group 104/105 type resilient buckets 512 \
214		idle_timer 0
215	ip route add 2001:db8:2::/64 vrf vrf-r1 nhid 106
216
217	ip nexthop add id 201 via 169.254.2.12 dev $rp22
218	ip nexthop add id 202 via 169.254.3.13 dev $rp23
219	ip nexthop add id 203 group 201/202 type resilient buckets 512 \
220		idle_timer 0
221	ip route add 192.0.2.0/24 vrf vrf-r2 nhid 203
222
223	ip nexthop add id 204 via fe80:2::12 dev $rp22
224	ip nexthop add id 205 via fe80:3::13 dev $rp23
225	ip nexthop add id 206 group 204/205 type resilient buckets 512 \
226		idle_timer 0
227	ip route add 2001:db8:1::/64 vrf vrf-r2 nhid 206
228}
229
230multipath4_test()
231{
232	local desc=$1; shift
233	local weight_rp12=$1; shift
234	local weight_rp13=$1; shift
235	local ports=${1-sp=1024,dp=0-32768}; shift
236
237	local t0_rp12 t0_rp13 t1_rp12 t1_rp13
238	local packets_rp12 packets_rp13
239
240	# Transmit multiple flows from h1 to h2 and make sure they are
241	# distributed between both multipath links (rp12 and rp13)
242	# according to the provided weights.
243	sysctl_set net.ipv4.fib_multipath_hash_policy 1
244
245	t0_rp12=$(link_stats_tx_packets_get $rp12)
246	t0_rp13=$(link_stats_tx_packets_get $rp13)
247
248	ip vrf exec vrf-h1 $MZ $h1 -q -p 64 -A 192.0.2.2 -B 198.51.100.2 \
249		-d $MZ_DELAY -t udp "$ports"
250	sleep 1
251
252	t1_rp12=$(link_stats_tx_packets_get $rp12)
253	t1_rp13=$(link_stats_tx_packets_get $rp13)
254
255	let "packets_rp12 = $t1_rp12 - $t0_rp12"
256	let "packets_rp13 = $t1_rp13 - $t0_rp13"
257	multipath_eval "$desc" $weight_rp12 $weight_rp13 $packets_rp12 $packets_rp13
258
259	# Restore settings.
260	sysctl_restore net.ipv4.fib_multipath_hash_policy
261}
262
263multipath6_l4_test()
264{
265	local desc=$1; shift
266	local weight_rp12=$1; shift
267	local weight_rp13=$1; shift
268	local ports=${1-sp=1024,dp=0-32768}; shift
269
270	local t0_rp12 t0_rp13 t1_rp12 t1_rp13
271	local packets_rp12 packets_rp13
272
273	# Transmit multiple flows from h1 to h2 and make sure they are
274	# distributed between both multipath links (rp12 and rp13)
275	# according to the provided weights.
276	sysctl_set net.ipv6.fib_multipath_hash_policy 1
277
278	t0_rp12=$(link_stats_tx_packets_get $rp12)
279	t0_rp13=$(link_stats_tx_packets_get $rp13)
280
281	$MZ $h1 -6 -q -p 64 -A 2001:db8:1::2 -B 2001:db8:2::2 \
282		-d $MZ_DELAY -t udp "$ports"
283	sleep 1
284
285	t1_rp12=$(link_stats_tx_packets_get $rp12)
286	t1_rp13=$(link_stats_tx_packets_get $rp13)
287
288	let "packets_rp12 = $t1_rp12 - $t0_rp12"
289	let "packets_rp13 = $t1_rp13 - $t0_rp13"
290	multipath_eval "$desc" $weight_rp12 $weight_rp13 $packets_rp12 $packets_rp13
291
292	sysctl_restore net.ipv6.fib_multipath_hash_policy
293}
294
295multipath_test()
296{
297	# Without an idle timer, weight replacement should happen immediately.
298	log_info "Running multipath tests without an idle timer"
299	ip nexthop replace id 103 group 101/102 type resilient idle_timer 0
300	ip nexthop replace id 106 group 104/105 type resilient idle_timer 0
301
302	log_info "Running IPv4 multipath tests"
303	ip nexthop replace id 103 group 101,1/102,1 type resilient
304	multipath4_test "ECMP" 1 1
305	ip nexthop replace id 103 group 101,2/102,1 type resilient
306	multipath4_test "Weighted MP 2:1" 2 1
307	ip nexthop replace id 103 group 101,11/102,45 type resilient
308	multipath4_test "Weighted MP 11:45" 11 45
309
310	ip nexthop replace id 103 group 101,1/102,1 type resilient
311
312	log_info "Running IPv6 L4 hash multipath tests"
313	ip nexthop replace id 106 group 104,1/105,1 type resilient
314	multipath6_l4_test "ECMP" 1 1
315	ip nexthop replace id 106 group 104,2/105,1 type resilient
316	multipath6_l4_test "Weighted MP 2:1" 2 1
317	ip nexthop replace id 106 group 104,11/105,45 type resilient
318	multipath6_l4_test "Weighted MP 11:45" 11 45
319
320	ip nexthop replace id 106 group 104,1/105,1 type resilient
321
322	# With an idle timer, weight replacement should not happen, so the
323	# expected ratio should always be the initial one (1:1).
324	log_info "Running multipath tests with an idle timer of 120 seconds"
325	ip nexthop replace id 103 group 101/102 type resilient idle_timer 120
326	ip nexthop replace id 106 group 104/105 type resilient idle_timer 120
327
328	log_info "Running IPv4 multipath tests"
329	ip nexthop replace id 103 group 101,1/102,1 type resilient
330	multipath4_test "ECMP" 1 1
331	ip nexthop replace id 103 group 101,2/102,1 type resilient
332	multipath4_test "Weighted MP 2:1" 1 1
333	ip nexthop replace id 103 group 101,11/102,45 type resilient
334	multipath4_test "Weighted MP 11:45" 1 1
335
336	ip nexthop replace id 103 group 101,1/102,1 type resilient
337
338	log_info "Running IPv6 L4 hash multipath tests"
339	ip nexthop replace id 106 group 104,1/105,1 type resilient
340	multipath6_l4_test "ECMP" 1 1
341	ip nexthop replace id 106 group 104,2/105,1 type resilient
342	multipath6_l4_test "Weighted MP 2:1" 1 1
343	ip nexthop replace id 106 group 104,11/105,45 type resilient
344	multipath6_l4_test "Weighted MP 11:45" 1 1
345
346	ip nexthop replace id 106 group 104,1/105,1 type resilient
347
348	# With a short idle timer and enough idle time, weight replacement
349	# should happen.
350	log_info "Running multipath tests with an idle timer of 5 seconds"
351	ip nexthop replace id 103 group 101/102 type resilient idle_timer 5
352	ip nexthop replace id 106 group 104/105 type resilient idle_timer 5
353
354	log_info "Running IPv4 multipath tests"
355	sleep 10
356	ip nexthop replace id 103 group 101,1/102,1 type resilient
357	multipath4_test "ECMP" 1 1
358	sleep 10
359	ip nexthop replace id 103 group 101,2/102,1 type resilient
360	multipath4_test "Weighted MP 2:1" 2 1
361	sleep 10
362	ip nexthop replace id 103 group 101,11/102,45 type resilient
363	multipath4_test "Weighted MP 11:45" 11 45
364
365	ip nexthop replace id 103 group 101,1/102,1 type resilient
366
367	log_info "Running IPv6 L4 hash multipath tests"
368	sleep 10
369	ip nexthop replace id 106 group 104,1/105,1 type resilient
370	multipath6_l4_test "ECMP" 1 1
371	sleep 10
372	ip nexthop replace id 106 group 104,2/105,1 type resilient
373	multipath6_l4_test "Weighted MP 2:1" 2 1
374	sleep 10
375	ip nexthop replace id 106 group 104,11/105,45 type resilient
376	multipath6_l4_test "Weighted MP 11:45" 11 45
377
378	ip nexthop replace id 106 group 104,1/105,1 type resilient
379}
380
381multipath16_test()
382{
383	check_nhgw16 104 || return
384
385	log_info "Running 16-bit IPv4 multipath tests"
386	ip nexthop replace id 103 group 101/102 type resilient idle_timer 0
387
388	ip nexthop replace id 103 group 101,65535/102,65535 type resilient
389	multipath4_test "65535:65535" 65535 65535
390
391	ip nexthop replace id 103 group 101,128/102,512 type resilient
392	multipath4_test "128:512" 128 512
393
394	ip nexthop replace id 103 group 101,255/102,65535 type resilient
395	omit_on_slow \
396		multipath4_test "255:65535" 255 65535 sp=1024-1026,dp=0-65535
397
398	ip nexthop replace id 103 group 101,1/102,1 type resilient
399
400	log_info "Running 16-bit IPv6 L4 hash multipath tests"
401	ip nexthop replace id 106 group 104/105 type resilient idle_timer 0
402
403	ip nexthop replace id 106 group 104,65535/105,65535 type resilient
404	multipath6_l4_test "65535:65535" 65535 65535
405
406	ip nexthop replace id 106 group 104,128/105,512 type resilient
407	multipath6_l4_test "128:512" 128 512
408
409	ip nexthop replace id 106 group 104,255/105,65535 type resilient
410	omit_on_slow \
411		multipath6_l4_test "255:65535" 255 65535 sp=1024-1026,dp=0-65535
412
413	ip nexthop replace id 106 group 104,1/105,1 type resilient
414}
415
416nh_stats_test_v4()
417{
418	__nh_stats_test_v4 resilient
419}
420
421nh_stats_test_v6()
422{
423	__nh_stats_test_v6 resilient
424}
425
426setup_prepare()
427{
428	h1=${NETIFS[p1]}
429	rp11=${NETIFS[p2]}
430
431	rp12=${NETIFS[p3]}
432	rp22=${NETIFS[p4]}
433
434	rp13=${NETIFS[p5]}
435	rp23=${NETIFS[p6]}
436
437	rp21=${NETIFS[p7]}
438	h2=${NETIFS[p8]}
439
440	vrf_prepare
441
442	h1_create
443	h2_create
444
445	router1_create
446	router2_create
447
448	forwarding_enable
449}
450
451cleanup()
452{
453	pre_cleanup
454
455	forwarding_restore
456
457	router2_destroy
458	router1_destroy
459
460	h2_destroy
461	h1_destroy
462
463	vrf_cleanup
464}
465
466ping_ipv4()
467{
468	ping_test $h1 198.51.100.2
469}
470
471ping_ipv6()
472{
473	ping6_test $h1 2001:db8:2::2
474}
475
476ip nexthop ls >/dev/null 2>&1
477if [ $? -ne 0 ]; then
478	echo "Nexthop objects not supported; skipping tests"
479	exit $ksft_skip
480fi
481
482trap cleanup EXIT
483
484setup_prepare
485setup_wait
486routing_nh_obj
487
488tests_run
489
490exit $EXIT_STATUS
491