1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4ALL_TESTS="
5	ping_ipv4
6	ping_ipv6
7	multipath_test
8	ping_ipv4_blackhole
9	ping_ipv6_blackhole
10	nh_stats_test_v4
11	nh_stats_test_v6
12"
13NUM_NETIFS=8
14source lib.sh
15source router_mpath_nh_lib.sh
16
17h1_create()
18{
19	vrf_create "vrf-h1"
20	ip link set dev $h1 master vrf-h1
21
22	ip link set dev vrf-h1 up
23	ip link set dev $h1 up
24
25	ip address add 192.0.2.2/24 dev $h1
26	ip address add 2001:db8:1::2/64 dev $h1
27
28	ip route add 198.51.100.0/24 vrf vrf-h1 nexthop via 192.0.2.1
29	ip route add 2001:db8:2::/64 vrf vrf-h1 nexthop via 2001:db8:1::1
30}
31
32h1_destroy()
33{
34	ip route del 2001:db8:2::/64 vrf vrf-h1
35	ip route del 198.51.100.0/24 vrf vrf-h1
36
37	ip address del 2001:db8:1::2/64 dev $h1
38	ip address del 192.0.2.2/24 dev $h1
39
40	ip link set dev $h1 down
41	vrf_destroy "vrf-h1"
42}
43
44h2_create()
45{
46	vrf_create "vrf-h2"
47	ip link set dev $h2 master vrf-h2
48
49	ip link set dev vrf-h2 up
50	ip link set dev $h2 up
51
52	ip address add 198.51.100.2/24 dev $h2
53	ip address add 2001:db8:2::2/64 dev $h2
54
55	ip route add 192.0.2.0/24 vrf vrf-h2 nexthop via 198.51.100.1
56	ip route add 2001:db8:1::/64 vrf vrf-h2 nexthop via 2001:db8:2::1
57}
58
59h2_destroy()
60{
61	ip route del 2001:db8:1::/64 vrf vrf-h2
62	ip route del 192.0.2.0/24 vrf vrf-h2
63
64	ip address del 2001:db8:2::2/64 dev $h2
65	ip address del 198.51.100.2/24 dev $h2
66
67	ip link set dev $h2 down
68	vrf_destroy "vrf-h2"
69}
70
71router1_create()
72{
73	vrf_create "vrf-r1"
74	ip link set dev $rp11 master vrf-r1
75	ip link set dev $rp12 master vrf-r1
76	ip link set dev $rp13 master vrf-r1
77
78	ip link set dev vrf-r1 up
79	ip link set dev $rp11 up
80	ip link set dev $rp12 up
81	ip link set dev $rp13 up
82
83	ip address add 192.0.2.1/24 dev $rp11
84	ip address add 2001:db8:1::1/64 dev $rp11
85
86	ip address add 169.254.2.12/24 dev $rp12
87	ip address add fe80:2::12/64 dev $rp12
88
89	ip address add 169.254.3.13/24 dev $rp13
90	ip address add fe80:3::13/64 dev $rp13
91}
92
93router1_destroy()
94{
95	ip route del 2001:db8:2::/64 vrf vrf-r1
96	ip route del 198.51.100.0/24 vrf vrf-r1
97
98	ip address del fe80:3::13/64 dev $rp13
99	ip address del 169.254.3.13/24 dev $rp13
100
101	ip address del fe80:2::12/64 dev $rp12
102	ip address del 169.254.2.12/24 dev $rp12
103
104	ip address del 2001:db8:1::1/64 dev $rp11
105	ip address del 192.0.2.1/24 dev $rp11
106
107	ip nexthop del id 103
108	ip nexthop del id 101
109	ip nexthop del id 102
110	ip nexthop del id 106
111	ip nexthop del id 104
112	ip nexthop del id 105
113
114	ip link set dev $rp13 down
115	ip link set dev $rp12 down
116	ip link set dev $rp11 down
117
118	vrf_destroy "vrf-r1"
119}
120
121router2_create()
122{
123	vrf_create "vrf-r2"
124	ip link set dev $rp21 master vrf-r2
125	ip link set dev $rp22 master vrf-r2
126	ip link set dev $rp23 master vrf-r2
127
128	ip link set dev vrf-r2 up
129	ip link set dev $rp21 up
130	ip link set dev $rp22 up
131	ip link set dev $rp23 up
132
133	ip address add 198.51.100.1/24 dev $rp21
134	ip address add 2001:db8:2::1/64 dev $rp21
135
136	ip address add 169.254.2.22/24 dev $rp22
137	ip address add fe80:2::22/64 dev $rp22
138
139	ip address add 169.254.3.23/24 dev $rp23
140	ip address add fe80:3::23/64 dev $rp23
141}
142
143router2_destroy()
144{
145	ip route del 2001:db8:1::/64 vrf vrf-r2
146	ip route del 192.0.2.0/24 vrf vrf-r2
147
148	ip address del fe80:3::23/64 dev $rp23
149	ip address del 169.254.3.23/24 dev $rp23
150
151	ip address del fe80:2::22/64 dev $rp22
152	ip address del 169.254.2.22/24 dev $rp22
153
154	ip address del 2001:db8:2::1/64 dev $rp21
155	ip address del 198.51.100.1/24 dev $rp21
156
157	ip nexthop del id 201
158	ip nexthop del id 202
159	ip nexthop del id 204
160	ip nexthop del id 205
161
162	ip link set dev $rp23 down
163	ip link set dev $rp22 down
164	ip link set dev $rp21 down
165
166	vrf_destroy "vrf-r2"
167}
168
169routing_nh_obj()
170{
171	ip nexthop add id 101 via 169.254.2.22 dev $rp12
172	ip nexthop add id 102 via 169.254.3.23 dev $rp13
173	ip nexthop add id 103 group 101/102
174	ip route add 198.51.100.0/24 vrf vrf-r1 nhid 103
175
176	ip nexthop add id 104 via fe80:2::22 dev $rp12
177	ip nexthop add id 105 via fe80:3::23 dev $rp13
178	ip nexthop add id 106 group 104/105
179	ip route add 2001:db8:2::/64 vrf vrf-r1 nhid 106
180
181	ip nexthop add id 201 via 169.254.2.12 dev $rp22
182	ip nexthop add id 202 via 169.254.3.13 dev $rp23
183	ip nexthop add id 203 group 201/202
184	ip route add 192.0.2.0/24 vrf vrf-r2 nhid 203
185
186	ip nexthop add id 204 via fe80:2::12 dev $rp22
187	ip nexthop add id 205 via fe80:3::13 dev $rp23
188	ip nexthop add id 206 group 204/205
189	ip route add 2001:db8:1::/64 vrf vrf-r2 nhid 206
190}
191
192multipath4_test()
193{
194	local desc="$1"
195	local weight_rp12=$2
196	local weight_rp13=$3
197	local t0_rp12 t0_rp13 t1_rp12 t1_rp13
198	local packets_rp12 packets_rp13
199
200	# Transmit multiple flows from h1 to h2 and make sure they are
201	# distributed between both multipath links (rp12 and rp13)
202	# according to the configured weights.
203	sysctl_set net.ipv4.fib_multipath_hash_policy 1
204	ip nexthop replace id 103 group 101,$weight_rp12/102,$weight_rp13
205
206	t0_rp12=$(link_stats_tx_packets_get $rp12)
207	t0_rp13=$(link_stats_tx_packets_get $rp13)
208
209	ip vrf exec vrf-h1 $MZ $h1 -q -p 64 -A 192.0.2.2 -B 198.51.100.2 \
210		-d $MZ_DELAY -t udp "sp=1024,dp=0-32768"
211
212	t1_rp12=$(link_stats_tx_packets_get $rp12)
213	t1_rp13=$(link_stats_tx_packets_get $rp13)
214
215	let "packets_rp12 = $t1_rp12 - $t0_rp12"
216	let "packets_rp13 = $t1_rp13 - $t0_rp13"
217	multipath_eval "$desc" $weight_rp12 $weight_rp13 $packets_rp12 $packets_rp13
218
219	# Restore settings.
220	ip nexthop replace id 103 group 101/102
221	sysctl_restore net.ipv4.fib_multipath_hash_policy
222}
223
224multipath6_test()
225{
226	local desc="$1"
227	local weight_rp12=$2
228	local weight_rp13=$3
229	local t0_rp12 t0_rp13 t1_rp12 t1_rp13
230	local packets_rp12 packets_rp13
231
232	# Transmit multiple flows from h1 to h2 and make sure they are
233	# distributed between both multipath links (rp12 and rp13)
234	# according to the configured weights.
235	sysctl_set net.ipv6.fib_multipath_hash_policy 1
236
237	ip nexthop replace id 106 group 104,$weight_rp12/105,$weight_rp13
238
239	t0_rp12=$(link_stats_tx_packets_get $rp12)
240	t0_rp13=$(link_stats_tx_packets_get $rp13)
241
242	$MZ $h1 -6 -q -p 64 -A 2001:db8:1::2 -B 2001:db8:2::2 \
243		-d $MZ_DELAY -t udp "sp=1024,dp=0-32768"
244
245	t1_rp12=$(link_stats_tx_packets_get $rp12)
246	t1_rp13=$(link_stats_tx_packets_get $rp13)
247
248	let "packets_rp12 = $t1_rp12 - $t0_rp12"
249	let "packets_rp13 = $t1_rp13 - $t0_rp13"
250	multipath_eval "$desc" $weight_rp12 $weight_rp13 $packets_rp12 $packets_rp13
251
252	ip nexthop replace id 106 group 104/105
253
254	sysctl_restore net.ipv6.fib_multipath_hash_policy
255}
256
257multipath_test()
258{
259	log_info "Running IPv4 multipath tests"
260	multipath4_test "ECMP" 1 1
261	multipath4_test "Weighted MP 2:1" 2 1
262	multipath4_test "Weighted MP 11:45" 11 45
263
264	log_info "Running IPv4 multipath tests with IPv6 link-local nexthops"
265	ip nexthop replace id 101 via fe80:2::22 dev $rp12
266	ip nexthop replace id 102 via fe80:3::23 dev $rp13
267
268	multipath4_test "ECMP" 1 1
269	multipath4_test "Weighted MP 2:1" 2 1
270	multipath4_test "Weighted MP 11:45" 11 45
271
272	ip nexthop replace id 102 via 169.254.3.23 dev $rp13
273	ip nexthop replace id 101 via 169.254.2.22 dev $rp12
274
275	log_info "Running IPv6 multipath tests"
276	multipath6_test "ECMP" 1 1
277	multipath6_test "Weighted MP 2:1" 2 1
278	multipath6_test "Weighted MP 11:45" 11 45
279}
280
281ping_ipv4_blackhole()
282{
283	RET=0
284
285	ip nexthop add id 1001 blackhole
286	ip nexthop add id 1002 group 1001
287
288	ip route replace 198.51.100.0/24 vrf vrf-r1 nhid 1001
289	ping_do $h1 198.51.100.2
290	check_fail $? "ping did not fail when using a blackhole nexthop"
291
292	ip route replace 198.51.100.0/24 vrf vrf-r1 nhid 1002
293	ping_do $h1 198.51.100.2
294	check_fail $? "ping did not fail when using a blackhole nexthop group"
295
296	ip route replace 198.51.100.0/24 vrf vrf-r1 nhid 103
297	ping_do $h1 198.51.100.2
298	check_err $? "ping failed with a valid nexthop"
299
300	log_test "IPv4 blackhole ping"
301
302	ip nexthop del id 1002
303	ip nexthop del id 1001
304}
305
306ping_ipv6_blackhole()
307{
308	RET=0
309
310	ip -6 nexthop add id 1001 blackhole
311	ip nexthop add id 1002 group 1001
312
313	ip route replace 2001:db8:2::/64 vrf vrf-r1 nhid 1001
314	ping6_do $h1 2001:db8:2::2
315	check_fail $? "ping did not fail when using a blackhole nexthop"
316
317	ip route replace 2001:db8:2::/64 vrf vrf-r1 nhid 1002
318	ping6_do $h1 2001:db8:2::2
319	check_fail $? "ping did not fail when using a blackhole nexthop group"
320
321	ip route replace 2001:db8:2::/64 vrf vrf-r1 nhid 106
322	ping6_do $h1 2001:db8:2::2
323	check_err $? "ping failed with a valid nexthop"
324
325	log_test "IPv6 blackhole ping"
326
327	ip nexthop del id 1002
328	ip -6 nexthop del id 1001
329}
330
331nh_stats_test_v4()
332{
333	__nh_stats_test_v4 mpath
334}
335
336nh_stats_test_v6()
337{
338	__nh_stats_test_v6 mpath
339}
340
341setup_prepare()
342{
343	h1=${NETIFS[p1]}
344	rp11=${NETIFS[p2]}
345
346	rp12=${NETIFS[p3]}
347	rp22=${NETIFS[p4]}
348
349	rp13=${NETIFS[p5]}
350	rp23=${NETIFS[p6]}
351
352	rp21=${NETIFS[p7]}
353	h2=${NETIFS[p8]}
354
355	vrf_prepare
356
357	h1_create
358	h2_create
359
360	router1_create
361	router2_create
362
363	forwarding_enable
364}
365
366cleanup()
367{
368	pre_cleanup
369
370	forwarding_restore
371
372	router2_destroy
373	router1_destroy
374
375	h2_destroy
376	h1_destroy
377
378	vrf_cleanup
379}
380
381ping_ipv4()
382{
383	ping_test $h1 198.51.100.2
384}
385
386ping_ipv6()
387{
388	ping6_test $h1 2001:db8:2::2
389}
390
391ip nexthop ls >/dev/null 2>&1
392if [ $? -ne 0 ]; then
393	echo "Nexthop objects not supported; skipping tests"
394	exit $ksft_skip
395fi
396
397trap cleanup EXIT
398
399setup_prepare
400setup_wait
401routing_nh_obj
402
403tests_run
404
405exit $EXIT_STATUS
406