Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4# This test is for checking IPv4 and IPv6 FIB behavior in response to
5# different events.
6source lib.sh
7ret=0
8
9# all tests in this script. Can be overridden with -t option
10TESTS="unregister down carrier nexthop suppress ipv6_notify ipv4_notify \
11 ipv6_rt ipv4_rt ipv6_addr_metric ipv4_addr_metric ipv6_route_metrics \
12 ipv4_route_metrics ipv4_route_v6_gw rp_filter ipv4_del_addr \
13 ipv6_del_addr ipv4_mangle ipv6_mangle ipv4_bcast_neigh fib6_gc_test \
14 ipv4_mpath_list ipv6_mpath_list ipv4_mpath_balance ipv6_mpath_balance \
15 ipv4_mpath_balance_preferred fib6_ra_to_static"
16
17VERBOSE=0
18PAUSE_ON_FAIL=no
19PAUSE=no
20
21which ping6 > /dev/null 2>&1 && ping6=$(which ping6) || ping6=$(which ping)
22
23log_test()
24{
25 local rc=$1
26 local expected=$2
27 local msg="$3"
28
29 if [ ${rc} -eq ${expected} ]; then
30 printf " TEST: %-60s [ OK ]\n" "${msg}"
31 nsuccess=$((nsuccess+1))
32 else
33 ret=1
34 nfail=$((nfail+1))
35 printf " TEST: %-60s [FAIL]\n" "${msg}"
36 if [ "${PAUSE_ON_FAIL}" = "yes" ]; then
37 echo
38 echo "hit enter to continue, 'q' to quit"
39 read a
40 [ "$a" = "q" ] && exit 1
41 fi
42 fi
43
44 if [ "${PAUSE}" = "yes" ]; then
45 echo
46 echo "hit enter to continue, 'q' to quit"
47 read a
48 [ "$a" = "q" ] && exit 1
49 fi
50}
51
52setup()
53{
54 set -e
55 setup_ns ns1
56 IP="$(which ip) -netns $ns1"
57 NS_EXEC="$(which ip) netns exec $ns1"
58 ip netns exec $ns1 sysctl -qw net.ipv4.ip_forward=1
59 ip netns exec $ns1 sysctl -qw net.ipv6.conf.all.forwarding=1
60
61 $IP link add dummy0 type dummy
62 $IP link set dev dummy0 up
63 $IP address add 198.51.100.1/24 dev dummy0
64 $IP -6 address add 2001:db8:1::1/64 dev dummy0
65 set +e
66
67}
68
69cleanup()
70{
71 $IP link del dev dummy0 &> /dev/null
72 cleanup_ns $ns1 $ns2
73}
74
75get_linklocal()
76{
77 local dev=$1
78 local addr
79
80 addr=$($IP -6 -br addr show dev ${dev} | \
81 awk '{
82 for (i = 3; i <= NF; ++i) {
83 if ($i ~ /^fe80/)
84 print $i
85 }
86 }'
87 )
88 addr=${addr/\/*}
89
90 [ -z "$addr" ] && return 1
91
92 echo $addr
93
94 return 0
95}
96
97fib_unreg_unicast_test()
98{
99 echo
100 echo "Single path route test"
101
102 setup
103
104 echo " Start point"
105 $IP route get fibmatch 198.51.100.2 &> /dev/null
106 log_test $? 0 "IPv4 fibmatch"
107 $IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null
108 log_test $? 0 "IPv6 fibmatch"
109
110 set -e
111 $IP link del dev dummy0
112 set +e
113
114 echo " Nexthop device deleted"
115 $IP route get fibmatch 198.51.100.2 &> /dev/null
116 log_test $? 2 "IPv4 fibmatch - no route"
117 $IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null
118 log_test $? 2 "IPv6 fibmatch - no route"
119
120 cleanup
121}
122
123fib_unreg_multipath_test()
124{
125
126 echo
127 echo "Multipath route test"
128
129 setup
130
131 set -e
132 $IP link add dummy1 type dummy
133 $IP link set dev dummy1 up
134 $IP address add 192.0.2.1/24 dev dummy1
135 $IP -6 address add 2001:db8:2::1/64 dev dummy1
136
137 $IP route add 203.0.113.0/24 \
138 nexthop via 198.51.100.2 dev dummy0 \
139 nexthop via 192.0.2.2 dev dummy1
140 $IP -6 route add 2001:db8:3::/64 \
141 nexthop via 2001:db8:1::2 dev dummy0 \
142 nexthop via 2001:db8:2::2 dev dummy1
143 set +e
144
145 echo " Start point"
146 $IP route get fibmatch 203.0.113.1 &> /dev/null
147 log_test $? 0 "IPv4 fibmatch"
148 $IP -6 route get fibmatch 2001:db8:3::1 &> /dev/null
149 log_test $? 0 "IPv6 fibmatch"
150
151 set -e
152 $IP link del dev dummy0
153 set +e
154
155 echo " One nexthop device deleted"
156 $IP route get fibmatch 203.0.113.1 &> /dev/null
157 log_test $? 2 "IPv4 - multipath route removed on delete"
158
159 $IP -6 route get fibmatch 2001:db8:3::1 &> /dev/null
160 # In IPv6 we do not flush the entire multipath route.
161 log_test $? 0 "IPv6 - multipath down to single path"
162
163 set -e
164 $IP link del dev dummy1
165 set +e
166
167 echo " Second nexthop device deleted"
168 $IP -6 route get fibmatch 2001:db8:3::1 &> /dev/null
169 log_test $? 2 "IPv6 - no route"
170
171 cleanup
172}
173
174fib_unreg_test()
175{
176 fib_unreg_unicast_test
177 fib_unreg_multipath_test
178}
179
180fib_down_unicast_test()
181{
182 echo
183 echo "Single path, admin down"
184
185 setup
186
187 echo " Start point"
188 $IP route get fibmatch 198.51.100.2 &> /dev/null
189 log_test $? 0 "IPv4 fibmatch"
190 $IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null
191 log_test $? 0 "IPv6 fibmatch"
192
193 set -e
194 $IP link set dev dummy0 down
195 set +e
196
197 echo " Route deleted on down"
198 $IP route get fibmatch 198.51.100.2 &> /dev/null
199 log_test $? 2 "IPv4 fibmatch"
200 $IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null
201 log_test $? 2 "IPv6 fibmatch"
202
203 cleanup
204}
205
206fib_down_multipath_test_do()
207{
208 local down_dev=$1
209 local up_dev=$2
210
211 $IP route get fibmatch 203.0.113.1 \
212 oif $down_dev &> /dev/null
213 log_test $? 2 "IPv4 fibmatch on down device"
214 $IP -6 route get fibmatch 2001:db8:3::1 \
215 oif $down_dev &> /dev/null
216 log_test $? 2 "IPv6 fibmatch on down device"
217
218 $IP route get fibmatch 203.0.113.1 \
219 oif $up_dev &> /dev/null
220 log_test $? 0 "IPv4 fibmatch on up device"
221 $IP -6 route get fibmatch 2001:db8:3::1 \
222 oif $up_dev &> /dev/null
223 log_test $? 0 "IPv6 fibmatch on up device"
224
225 $IP route get fibmatch 203.0.113.1 | \
226 grep $down_dev | grep -q "dead linkdown"
227 log_test $? 0 "IPv4 flags on down device"
228 $IP -6 route get fibmatch 2001:db8:3::1 | \
229 grep $down_dev | grep -q "dead linkdown"
230 log_test $? 0 "IPv6 flags on down device"
231
232 $IP route get fibmatch 203.0.113.1 | \
233 grep $up_dev | grep -q "dead linkdown"
234 log_test $? 1 "IPv4 flags on up device"
235 $IP -6 route get fibmatch 2001:db8:3::1 | \
236 grep $up_dev | grep -q "dead linkdown"
237 log_test $? 1 "IPv6 flags on up device"
238}
239
240fib_down_multipath_test()
241{
242 echo
243 echo "Admin down multipath"
244
245 setup
246
247 set -e
248 $IP link add dummy1 type dummy
249 $IP link set dev dummy1 up
250
251 $IP address add 192.0.2.1/24 dev dummy1
252 $IP -6 address add 2001:db8:2::1/64 dev dummy1
253
254 $IP route add 203.0.113.0/24 \
255 nexthop via 198.51.100.2 dev dummy0 \
256 nexthop via 192.0.2.2 dev dummy1
257 $IP -6 route add 2001:db8:3::/64 \
258 nexthop via 2001:db8:1::2 dev dummy0 \
259 nexthop via 2001:db8:2::2 dev dummy1
260 set +e
261
262 echo " Verify start point"
263 $IP route get fibmatch 203.0.113.1 &> /dev/null
264 log_test $? 0 "IPv4 fibmatch"
265
266 $IP -6 route get fibmatch 2001:db8:3::1 &> /dev/null
267 log_test $? 0 "IPv6 fibmatch"
268
269 set -e
270 $IP link set dev dummy0 down
271 set +e
272
273 echo " One device down, one up"
274 fib_down_multipath_test_do "dummy0" "dummy1"
275
276 set -e
277 $IP link set dev dummy0 up
278 $IP link set dev dummy1 down
279 set +e
280
281 echo " Other device down and up"
282 fib_down_multipath_test_do "dummy1" "dummy0"
283
284 set -e
285 $IP link set dev dummy0 down
286 set +e
287
288 echo " Both devices down"
289 $IP route get fibmatch 203.0.113.1 &> /dev/null
290 log_test $? 2 "IPv4 fibmatch"
291 $IP -6 route get fibmatch 2001:db8:3::1 &> /dev/null
292 log_test $? 2 "IPv6 fibmatch"
293
294 $IP link del dev dummy1
295 cleanup
296}
297
298fib_down_test()
299{
300 fib_down_unicast_test
301 fib_down_multipath_test
302}
303
304# Local routes should not be affected when carrier changes.
305fib_carrier_local_test()
306{
307 echo
308 echo "Local carrier tests - single path"
309
310 setup
311
312 set -e
313 $IP link set dev dummy0 carrier on
314 set +e
315
316 echo " Start point"
317 $IP route get fibmatch 198.51.100.1 &> /dev/null
318 log_test $? 0 "IPv4 fibmatch"
319 $IP -6 route get fibmatch 2001:db8:1::1 &> /dev/null
320 log_test $? 0 "IPv6 fibmatch"
321
322 $IP route get fibmatch 198.51.100.1 | \
323 grep -q "linkdown"
324 log_test $? 1 "IPv4 - no linkdown flag"
325 $IP -6 route get fibmatch 2001:db8:1::1 | \
326 grep -q "linkdown"
327 log_test $? 1 "IPv6 - no linkdown flag"
328
329 set -e
330 $IP link set dev dummy0 carrier off
331 sleep 1
332 set +e
333
334 echo " Carrier off on nexthop"
335 $IP route get fibmatch 198.51.100.1 &> /dev/null
336 log_test $? 0 "IPv4 fibmatch"
337 $IP -6 route get fibmatch 2001:db8:1::1 &> /dev/null
338 log_test $? 0 "IPv6 fibmatch"
339
340 $IP route get fibmatch 198.51.100.1 | \
341 grep -q "linkdown"
342 log_test $? 1 "IPv4 - linkdown flag set"
343 $IP -6 route get fibmatch 2001:db8:1::1 | \
344 grep -q "linkdown"
345 log_test $? 1 "IPv6 - linkdown flag set"
346
347 set -e
348 $IP address add 192.0.2.1/24 dev dummy0
349 $IP -6 address add 2001:db8:2::1/64 dev dummy0
350 set +e
351
352 echo " Route to local address with carrier down"
353 $IP route get fibmatch 192.0.2.1 &> /dev/null
354 log_test $? 0 "IPv4 fibmatch"
355 $IP -6 route get fibmatch 2001:db8:2::1 &> /dev/null
356 log_test $? 0 "IPv6 fibmatch"
357
358 $IP route get fibmatch 192.0.2.1 | \
359 grep -q "linkdown"
360 log_test $? 1 "IPv4 linkdown flag set"
361 $IP -6 route get fibmatch 2001:db8:2::1 | \
362 grep -q "linkdown"
363 log_test $? 1 "IPv6 linkdown flag set"
364
365 cleanup
366}
367
368fib_carrier_unicast_test()
369{
370 ret=0
371
372 echo
373 echo "Single path route carrier test"
374
375 setup
376
377 set -e
378 $IP link set dev dummy0 carrier on
379 set +e
380
381 echo " Start point"
382 $IP route get fibmatch 198.51.100.2 &> /dev/null
383 log_test $? 0 "IPv4 fibmatch"
384 $IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null
385 log_test $? 0 "IPv6 fibmatch"
386
387 $IP route get fibmatch 198.51.100.2 | \
388 grep -q "linkdown"
389 log_test $? 1 "IPv4 no linkdown flag"
390 $IP -6 route get fibmatch 2001:db8:1::2 | \
391 grep -q "linkdown"
392 log_test $? 1 "IPv6 no linkdown flag"
393
394 set -e
395 $IP link set dev dummy0 carrier off
396 sleep 1
397 set +e
398
399 echo " Carrier down"
400 $IP route get fibmatch 198.51.100.2 &> /dev/null
401 log_test $? 0 "IPv4 fibmatch"
402 $IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null
403 log_test $? 0 "IPv6 fibmatch"
404
405 $IP route get fibmatch 198.51.100.2 | \
406 grep -q "linkdown"
407 log_test $? 0 "IPv4 linkdown flag set"
408 $IP -6 route get fibmatch 2001:db8:1::2 | \
409 grep -q "linkdown"
410 log_test $? 0 "IPv6 linkdown flag set"
411
412 set -e
413 $IP address add 192.0.2.1/24 dev dummy0
414 $IP -6 address add 2001:db8:2::1/64 dev dummy0
415 set +e
416
417 echo " Second address added with carrier down"
418 $IP route get fibmatch 192.0.2.2 &> /dev/null
419 log_test $? 0 "IPv4 fibmatch"
420 $IP -6 route get fibmatch 2001:db8:2::2 &> /dev/null
421 log_test $? 0 "IPv6 fibmatch"
422
423 $IP route get fibmatch 192.0.2.2 | \
424 grep -q "linkdown"
425 log_test $? 0 "IPv4 linkdown flag set"
426 $IP -6 route get fibmatch 2001:db8:2::2 | \
427 grep -q "linkdown"
428 log_test $? 0 "IPv6 linkdown flag set"
429
430 cleanup
431}
432
433fib_carrier_test()
434{
435 fib_carrier_local_test
436 fib_carrier_unicast_test
437}
438
439fib_rp_filter_test()
440{
441 echo
442 echo "IPv4 rp_filter tests"
443
444 setup
445
446 set -e
447 setup_ns ns2
448
449 $IP link add name veth1 type veth peer name veth2
450 $IP link set dev veth2 netns $ns2
451 $IP address add 192.0.2.1/24 dev veth1
452 ip -netns $ns2 address add 192.0.2.1/24 dev veth2
453 $IP link set dev veth1 up
454 ip -netns $ns2 link set dev veth2 up
455
456 $IP link set dev lo address 52:54:00:6a:c7:5e
457 $IP link set dev veth1 address 52:54:00:6a:c7:5e
458 ip -netns $ns2 link set dev lo address 52:54:00:6a:c7:5e
459 ip -netns $ns2 link set dev veth2 address 52:54:00:6a:c7:5e
460
461 # 1. (ns2) redirect lo's egress to veth2's egress
462 ip netns exec $ns2 tc qdisc add dev lo parent root handle 1: fq_codel
463 ip netns exec $ns2 tc filter add dev lo parent 1: protocol arp basic \
464 action mirred egress redirect dev veth2
465 ip netns exec $ns2 tc filter add dev lo parent 1: protocol ip basic \
466 action mirred egress redirect dev veth2
467
468 # 2. (ns1) redirect veth1's ingress to lo's ingress
469 $NS_EXEC tc qdisc add dev veth1 ingress
470 $NS_EXEC tc filter add dev veth1 ingress protocol arp basic \
471 action mirred ingress redirect dev lo
472 $NS_EXEC tc filter add dev veth1 ingress protocol ip basic \
473 action mirred ingress redirect dev lo
474
475 # 3. (ns1) redirect lo's egress to veth1's egress
476 $NS_EXEC tc qdisc add dev lo parent root handle 1: fq_codel
477 $NS_EXEC tc filter add dev lo parent 1: protocol arp basic \
478 action mirred egress redirect dev veth1
479 $NS_EXEC tc filter add dev lo parent 1: protocol ip basic \
480 action mirred egress redirect dev veth1
481
482 # 4. (ns2) redirect veth2's ingress to lo's ingress
483 ip netns exec $ns2 tc qdisc add dev veth2 ingress
484 ip netns exec $ns2 tc filter add dev veth2 ingress protocol arp basic \
485 action mirred ingress redirect dev lo
486 ip netns exec $ns2 tc filter add dev veth2 ingress protocol ip basic \
487 action mirred ingress redirect dev lo
488
489 $NS_EXEC sysctl -qw net.ipv4.conf.all.rp_filter=1
490 $NS_EXEC sysctl -qw net.ipv4.conf.all.accept_local=1
491 $NS_EXEC sysctl -qw net.ipv4.conf.all.route_localnet=1
492 ip netns exec $ns2 sysctl -qw net.ipv4.conf.all.rp_filter=1
493 ip netns exec $ns2 sysctl -qw net.ipv4.conf.all.accept_local=1
494 ip netns exec $ns2 sysctl -qw net.ipv4.conf.all.route_localnet=1
495 set +e
496
497 run_cmd "ip netns exec $ns2 ping -w1 -c1 192.0.2.1"
498 log_test $? 0 "rp_filter passes local packets"
499
500 run_cmd "ip netns exec $ns2 ping -w1 -c1 127.0.0.1"
501 log_test $? 0 "rp_filter passes loopback packets"
502
503 cleanup
504}
505
506################################################################################
507# Tests on nexthop spec
508
509# run 'ip route add' with given spec
510add_rt()
511{
512 local desc="$1"
513 local erc=$2
514 local vrf=$3
515 local pfx=$4
516 local gw=$5
517 local dev=$6
518 local cmd out rc
519
520 [ "$vrf" = "-" ] && vrf="default"
521 [ -n "$gw" ] && gw="via $gw"
522 [ -n "$dev" ] && dev="dev $dev"
523
524 cmd="$IP route add vrf $vrf $pfx $gw $dev"
525 if [ "$VERBOSE" = "1" ]; then
526 printf "\n COMMAND: $cmd\n"
527 fi
528
529 out=$(eval $cmd 2>&1)
530 rc=$?
531 if [ "$VERBOSE" = "1" -a -n "$out" ]; then
532 echo " $out"
533 fi
534 log_test $rc $erc "$desc"
535}
536
537fib4_nexthop()
538{
539 echo
540 echo "IPv4 nexthop tests"
541
542 echo "<<< write me >>>"
543}
544
545fib6_nexthop()
546{
547 local lldummy=$(get_linklocal dummy0)
548 local llv1=$(get_linklocal veth1)
549
550 if [ -z "$lldummy" ]; then
551 echo "Failed to get linklocal address for dummy0"
552 return 1
553 fi
554 if [ -z "$llv1" ]; then
555 echo "Failed to get linklocal address for veth1"
556 return 1
557 fi
558
559 echo
560 echo "IPv6 nexthop tests"
561
562 add_rt "Directly connected nexthop, unicast address" 0 \
563 - 2001:db8:101::/64 2001:db8:1::2
564 add_rt "Directly connected nexthop, unicast address with device" 0 \
565 - 2001:db8:102::/64 2001:db8:1::2 "dummy0"
566 add_rt "Gateway is linklocal address" 0 \
567 - 2001:db8:103::1/64 $llv1 "veth0"
568
569 # fails because LL address requires a device
570 add_rt "Gateway is linklocal address, no device" 2 \
571 - 2001:db8:104::1/64 $llv1
572
573 # local address can not be a gateway
574 add_rt "Gateway can not be local unicast address" 2 \
575 - 2001:db8:105::/64 2001:db8:1::1
576 add_rt "Gateway can not be local unicast address, with device" 2 \
577 - 2001:db8:106::/64 2001:db8:1::1 "dummy0"
578 add_rt "Gateway can not be a local linklocal address" 2 \
579 - 2001:db8:107::1/64 $lldummy "dummy0"
580
581 # VRF tests
582 add_rt "Gateway can be local address in a VRF" 0 \
583 - 2001:db8:108::/64 2001:db8:51::2
584 add_rt "Gateway can be local address in a VRF, with device" 0 \
585 - 2001:db8:109::/64 2001:db8:51::2 "veth0"
586 add_rt "Gateway can be local linklocal address in a VRF" 0 \
587 - 2001:db8:110::1/64 $llv1 "veth0"
588
589 add_rt "Redirect to VRF lookup" 0 \
590 - 2001:db8:111::/64 "" "red"
591
592 add_rt "VRF route, gateway can be local address in default VRF" 0 \
593 red 2001:db8:112::/64 2001:db8:51::1
594
595 # local address in same VRF fails
596 add_rt "VRF route, gateway can not be a local address" 2 \
597 red 2001:db8:113::1/64 2001:db8:2::1
598 add_rt "VRF route, gateway can not be a local addr with device" 2 \
599 red 2001:db8:114::1/64 2001:db8:2::1 "dummy1"
600}
601
602# Default VRF:
603# dummy0 - 198.51.100.1/24 2001:db8:1::1/64
604# veth0 - 192.0.2.1/24 2001:db8:51::1/64
605#
606# VRF red:
607# dummy1 - 192.168.2.1/24 2001:db8:2::1/64
608# veth1 - 192.0.2.2/24 2001:db8:51::2/64
609#
610# [ dummy0 veth0 ]--[ veth1 dummy1 ]
611
612fib_nexthop_test()
613{
614 setup
615
616 set -e
617
618 $IP -4 rule add pref 32765 table local
619 $IP -4 rule del pref 0
620 $IP -6 rule add pref 32765 table local
621 $IP -6 rule del pref 0
622
623 $IP link add red type vrf table 1
624 $IP link set red up
625 $IP -4 route add vrf red unreachable default metric 4278198272
626 $IP -6 route add vrf red unreachable default metric 4278198272
627
628 $IP link add veth0 type veth peer name veth1
629 $IP link set dev veth0 up
630 $IP address add 192.0.2.1/24 dev veth0
631 $IP -6 address add 2001:db8:51::1/64 dev veth0
632
633 $IP link set dev veth1 vrf red up
634 $IP address add 192.0.2.2/24 dev veth1
635 $IP -6 address add 2001:db8:51::2/64 dev veth1
636
637 $IP link add dummy1 type dummy
638 $IP link set dev dummy1 vrf red up
639 $IP address add 192.168.2.1/24 dev dummy1
640 $IP -6 address add 2001:db8:2::1/64 dev dummy1
641 set +e
642
643 sleep 1
644 fib4_nexthop
645 fib6_nexthop
646
647 (
648 $IP link del dev dummy1
649 $IP link del veth0
650 $IP link del red
651 ) 2>/dev/null
652 cleanup
653}
654
655fib6_notify_test()
656{
657 setup
658
659 echo
660 echo "Fib6 info length calculation in route notify test"
661 set -e
662
663 for i in 10 20 30 40 50 60 70;
664 do
665 $IP link add dummy_$i type dummy
666 $IP link set dev dummy_$i up
667 $IP -6 address add 2001:$i::1/64 dev dummy_$i
668 done
669
670 $NS_EXEC ip monitor route &> errors.txt &
671 sleep 2
672
673 $IP -6 route add 2001::/64 \
674 nexthop via 2001:10::2 dev dummy_10 \
675 nexthop encap ip6 dst 2002::20 via 2001:20::2 dev dummy_20 \
676 nexthop encap ip6 dst 2002::30 via 2001:30::2 dev dummy_30 \
677 nexthop encap ip6 dst 2002::40 via 2001:40::2 dev dummy_40 \
678 nexthop encap ip6 dst 2002::50 via 2001:50::2 dev dummy_50 \
679 nexthop encap ip6 dst 2002::60 via 2001:60::2 dev dummy_60 \
680 nexthop encap ip6 dst 2002::70 via 2001:70::2 dev dummy_70
681
682 set +e
683
684 err=`cat errors.txt |grep "Message too long"`
685 if [ -z "$err" ];then
686 ret=0
687 else
688 ret=1
689 fi
690
691 log_test $ret 0 "ipv6 route add notify"
692
693 kill_process %%
694
695 #rm errors.txt
696
697 cleanup &> /dev/null
698}
699
700
701fib_notify_test()
702{
703 setup
704
705 echo
706 echo "Fib4 info length calculation in route notify test"
707
708 set -e
709
710 for i in 10 20 30 40 50 60 70;
711 do
712 $IP link add dummy_$i type dummy
713 $IP link set dev dummy_$i up
714 $IP address add 20.20.$i.2/24 dev dummy_$i
715 done
716
717 $NS_EXEC ip monitor route &> errors.txt &
718 sleep 2
719
720 $IP route add 10.0.0.0/24 \
721 nexthop via 20.20.10.1 dev dummy_10 \
722 nexthop encap ip dst 192.168.10.20 via 20.20.20.1 dev dummy_20 \
723 nexthop encap ip dst 192.168.10.30 via 20.20.30.1 dev dummy_30 \
724 nexthop encap ip dst 192.168.10.40 via 20.20.40.1 dev dummy_40 \
725 nexthop encap ip dst 192.168.10.50 via 20.20.50.1 dev dummy_50 \
726 nexthop encap ip dst 192.168.10.60 via 20.20.60.1 dev dummy_60 \
727 nexthop encap ip dst 192.168.10.70 via 20.20.70.1 dev dummy_70
728
729 set +e
730
731 err=`cat errors.txt |grep "Message too long"`
732 if [ -z "$err" ];then
733 ret=0
734 else
735 ret=1
736 fi
737
738 log_test $ret 0 "ipv4 route add notify"
739
740 kill_process %%
741
742 rm errors.txt
743
744 cleanup &> /dev/null
745}
746
747# Create a new dummy_10 to remove all associated routes.
748reset_dummy_10()
749{
750 $IP link del dev dummy_10
751
752 $IP link add dummy_10 type dummy
753 $IP link set dev dummy_10 up
754 $IP -6 address add 2001:10::1/64 dev dummy_10
755}
756
757check_rt_num()
758{
759 local expected=$1
760 local num=$2
761
762 if [ $num -ne $expected ]; then
763 echo "FAIL: Expected $expected routes, got $num"
764 ret=1
765 else
766 ret=0
767 fi
768}
769
770check_rt_num_clean()
771{
772 local expected=$1
773 local num=$2
774
775 if [ $num -ne $expected ]; then
776 log_test 1 0 "expected $expected routes, got $num"
777 set +e
778 cleanup &> /dev/null
779 return 1
780 fi
781 return 0
782}
783
784fib6_gc_test()
785{
786 setup
787
788 echo
789 echo "Fib6 garbage collection test"
790 set -e
791
792 EXPIRE=5
793 GC_WAIT_TIME=$((EXPIRE * 2 + 2))
794
795 # Check expiration of routes every $EXPIRE seconds (GC)
796 $NS_EXEC sysctl -wq net.ipv6.route.gc_interval=$EXPIRE
797
798 $IP link add dummy_10 type dummy
799 $IP link set dev dummy_10 up
800 $IP -6 address add 2001:10::1/64 dev dummy_10
801
802 $NS_EXEC sysctl -wq net.ipv6.route.flush=1
803
804 # Temporary routes
805 for i in $(seq 1 5); do
806 # Expire route after $EXPIRE seconds
807 $IP -6 route add 2001:20::$i \
808 via 2001:10::2 dev dummy_10 expires $EXPIRE
809 done
810 sleep $GC_WAIT_TIME
811 $NS_EXEC sysctl -wq net.ipv6.route.flush=1
812 check_rt_num 0 $($IP -6 route list |grep expires|wc -l)
813 log_test $ret 0 "ipv6 route garbage collection"
814
815 reset_dummy_10
816
817 # Permanent routes
818 for i in $(seq 1 5); do
819 $IP -6 route add 2001:30::$i \
820 via 2001:10::2 dev dummy_10
821 done
822 # Temporary routes
823 for i in $(seq 1 5); do
824 # Expire route after $EXPIRE seconds
825 $IP -6 route add 2001:20::$i \
826 via 2001:10::2 dev dummy_10 expires $EXPIRE
827 done
828 # Wait for GC
829 sleep $GC_WAIT_TIME
830 check_rt_num 0 $($IP -6 route list |grep expires|wc -l)
831 log_test $ret 0 "ipv6 route garbage collection (with permanent routes)"
832
833 reset_dummy_10
834
835 # Permanent routes
836 for i in $(seq 1 5); do
837 $IP -6 route add 2001:20::$i \
838 via 2001:10::2 dev dummy_10
839 done
840 # Replace with temporary routes
841 for i in $(seq 1 5); do
842 # Expire route after $EXPIRE seconds
843 $IP -6 route replace 2001:20::$i \
844 via 2001:10::2 dev dummy_10 expires $EXPIRE
845 done
846 # Wait for GC
847 sleep $GC_WAIT_TIME
848 check_rt_num 0 $($IP -6 route list |grep expires|wc -l)
849 log_test $ret 0 "ipv6 route garbage collection (replace with expires)"
850
851 reset_dummy_10
852
853 # Temporary routes
854 for i in $(seq 1 5); do
855 # Expire route after $EXPIRE seconds
856 $IP -6 route add 2001:20::$i \
857 via 2001:10::2 dev dummy_10 expires $EXPIRE
858 done
859 # Replace with permanent routes
860 for i in $(seq 1 5); do
861 $IP -6 route replace 2001:20::$i \
862 via 2001:10::2 dev dummy_10
863 done
864 check_rt_num_clean 0 $($IP -6 route list |grep expires|wc -l) || return
865
866 # Wait for GC
867 sleep $GC_WAIT_TIME
868 check_rt_num 5 $($IP -6 route list |grep -v expires|grep 2001:20::|wc -l)
869 log_test $ret 0 "ipv6 route garbage collection (replace with permanent)"
870
871 # Delete dummy_10 and remove all routes
872 $IP link del dev dummy_10
873
874 # rd6 is required for the next test. (ipv6toolkit)
875 if [ ! -x "$(command -v rd6)" ]; then
876 echo "SKIP: rd6 not found."
877 set +e
878 cleanup &> /dev/null
879 return
880 fi
881
882 setup_ns ns2
883 $IP link add veth1 type veth peer veth2 netns $ns2
884 $IP link set veth1 up
885 ip -netns $ns2 link set veth2 up
886 $IP addr add fe80:dead::1/64 dev veth1
887 ip -netns $ns2 addr add fe80:dead::2/64 dev veth2
888
889 # Add NTF_ROUTER neighbour to prevent rt6_age_examine_exception()
890 # from removing not-yet-expired exceptions.
891 ip -netns $ns2 link set veth2 address 00:11:22:33:44:55
892 $IP neigh add fe80:dead::3 lladdr 00:11:22:33:44:55 dev veth1 router
893
894 $NS_EXEC sysctl -wq net.ipv6.conf.veth1.accept_redirects=1
895 $NS_EXEC sysctl -wq net.ipv6.conf.veth1.forwarding=0
896
897 # Temporary routes
898 for i in $(seq 1 5); do
899 # Expire route after $EXPIRE seconds
900 $IP -6 route add 2001:10::$i \
901 via fe80:dead::2 dev veth1 expires $EXPIRE
902
903 ip netns exec $ns2 rd6 -i veth2 \
904 -s fe80:dead::2 -d fe80:dead::1 \
905 -r 2001:10::$i -t fe80:dead::3 -p ICMP6
906 done
907
908 check_rt_num 5 $($IP -6 route list | grep expires | grep 2001:10:: | wc -l)
909
910 # Promote to permanent routes by "prepend" (w/o NLM_F_EXCL and NLM_F_REPLACE)
911 for i in $(seq 1 5); do
912 # -EEXIST, but the temporary route becomes the permanent route.
913 $IP -6 route append 2001:10::$i \
914 via fe80:dead::2 dev veth1 2>/dev/null || true
915 done
916
917 check_rt_num 5 $($IP -6 route list | grep -v expires | grep 2001:10:: | wc -l)
918 check_rt_num 5 $($IP -6 route list cache | grep 2001:10:: | wc -l)
919
920 # Trigger GC instead of waiting $GC_WAIT_TIME.
921 # rt6_nh_dump_exceptions() just skips expired exceptions.
922 $NS_EXEC sysctl -wq net.ipv6.route.flush=1
923 check_rt_num 0 $($IP -6 route list cache | grep 2001:10:: | wc -l)
924 log_test $ret 0 "ipv6 route garbage collection (promote to permanent routes)"
925
926 $IP neigh del fe80:dead::3 lladdr 00:11:22:33:44:55 dev veth1 router
927 $IP link del veth1
928
929 # ra6 is required for the next test. (ipv6toolkit)
930 if [ ! -x "$(command -v ra6)" ]; then
931 echo "SKIP: ra6 not found."
932 set +e
933 cleanup &> /dev/null
934 return
935 fi
936
937 # Create a pair of veth devices to send a RA message from one
938 # device to another.
939 $IP link add veth1 type veth peer name veth2
940 $IP link set dev veth1 up
941 $IP link set dev veth2 up
942 $IP -6 address add 2001:10::1/64 dev veth1 nodad
943 $IP -6 address add 2001:10::2/64 dev veth2 nodad
944
945 # Make veth1 ready to receive RA messages.
946 $NS_EXEC sysctl -wq net.ipv6.conf.veth1.accept_ra=2
947
948 # Send a RA message with a route from veth2 to veth1.
949 $NS_EXEC ra6 -i veth2 -d 2001:10::1 -t $EXPIRE
950
951 # Wait for the RA message.
952 sleep 1
953
954 # systemd may mess up the test. You syould make sure that
955 # systemd-networkd.service and systemd-networkd.socket are stopped.
956 check_rt_num_clean 1 $($IP -6 route list|grep expires|wc -l) || return
957
958 # Wait for GC
959 sleep $GC_WAIT_TIME
960 check_rt_num 0 $($IP -6 route list |grep expires|wc -l)
961 log_test $ret 0 "ipv6 route garbage collection (RA message)"
962
963 set +e
964
965 cleanup &> /dev/null
966}
967
968fib_suppress_test()
969{
970 echo
971 echo "FIB rule with suppress_prefixlength"
972 setup
973
974 $IP link add dummy1 type dummy
975 $IP link set dummy1 up
976 $IP -6 route add default dev dummy1
977 $IP -6 rule add table main suppress_prefixlength 0
978 ping -f -c 1000 -W 1 1234::1 >/dev/null 2>&1
979 $IP -6 rule del table main suppress_prefixlength 0
980 $IP link del dummy1
981
982 # If we got here without crashing, we're good.
983 log_test 0 0 "FIB rule suppress test"
984
985 cleanup
986}
987
988################################################################################
989# Tests on route add and replace
990
991run_cmd()
992{
993 local cmd="$1"
994 local out
995 local stderr="2>/dev/null"
996
997 if [ "$VERBOSE" = "1" ]; then
998 printf " COMMAND: $cmd\n"
999 stderr=
1000 fi
1001
1002 out=$(eval $cmd $stderr)
1003 rc=$?
1004 if [ "$VERBOSE" = "1" -a -n "$out" ]; then
1005 echo " $out"
1006 fi
1007
1008 [ "$VERBOSE" = "1" ] && echo
1009
1010 return $rc
1011}
1012
1013check_expected()
1014{
1015 local out="$1"
1016 local expected="$2"
1017 local rc=0
1018
1019 [ "${out}" = "${expected}" ] && return 0
1020
1021 if [ -z "${out}" ]; then
1022 if [ "$VERBOSE" = "1" ]; then
1023 printf "\nNo route entry found\n"
1024 printf "Expected:\n"
1025 printf " ${expected}\n"
1026 fi
1027 return 1
1028 fi
1029
1030 # tricky way to convert output to 1-line without ip's
1031 # messy '\'; this drops all extra white space
1032 out=$(echo ${out})
1033 if [ "${out}" != "${expected}" ]; then
1034 rc=1
1035 if [ "${VERBOSE}" = "1" ]; then
1036 printf " Unexpected route entry. Have:\n"
1037 printf " ${out}\n"
1038 printf " Expected:\n"
1039 printf " ${expected}\n\n"
1040 fi
1041 fi
1042
1043 return $rc
1044}
1045
1046# add route for a prefix, flushing any existing routes first
1047# expected to be the first step of a test
1048add_route6()
1049{
1050 local pfx="$1"
1051 local nh="$2"
1052 local out
1053
1054 if [ "$VERBOSE" = "1" ]; then
1055 echo
1056 echo " ##################################################"
1057 echo
1058 fi
1059
1060 run_cmd "$IP -6 ro flush ${pfx}"
1061 [ $? -ne 0 ] && exit 1
1062
1063 out=$($IP -6 ro ls match ${pfx})
1064 if [ -n "$out" ]; then
1065 echo "Failed to flush routes for prefix used for tests."
1066 exit 1
1067 fi
1068
1069 run_cmd "$IP -6 ro add ${pfx} ${nh}"
1070 if [ $? -ne 0 ]; then
1071 echo "Failed to add initial route for test."
1072 exit 1
1073 fi
1074}
1075
1076# add initial route - used in replace route tests
1077add_initial_route6()
1078{
1079 add_route6 "2001:db8:104::/64" "$1"
1080}
1081
1082check_route6()
1083{
1084 local pfx
1085 local expected="$1"
1086 local out
1087 local rc=0
1088
1089 set -- $expected
1090 pfx=$1
1091
1092 out=$($IP -6 ro ls match ${pfx} | sed -e 's/ pref medium//')
1093 check_expected "${out}" "${expected}"
1094}
1095
1096route_cleanup()
1097{
1098 $IP li del red 2>/dev/null
1099 $IP li del dummy1 2>/dev/null
1100 $IP li del veth1 2>/dev/null
1101 $IP li del veth3 2>/dev/null
1102
1103 cleanup &> /dev/null
1104}
1105
1106route_setup()
1107{
1108 route_cleanup
1109 setup
1110
1111 [ "${VERBOSE}" = "1" ] && set -x
1112 set -e
1113
1114 setup_ns ns2
1115 ip netns exec $ns2 sysctl -qw net.ipv4.ip_forward=1
1116 ip netns exec $ns2 sysctl -qw net.ipv6.conf.all.forwarding=1
1117
1118 $IP li add veth1 type veth peer name veth2
1119 $IP li add veth3 type veth peer name veth4
1120
1121 $IP li set veth1 up
1122 $IP li set veth3 up
1123 $IP li set veth2 netns $ns2 up
1124 $IP li set veth4 netns $ns2 up
1125 ip -netns $ns2 li add dummy1 type dummy
1126 ip -netns $ns2 li set dummy1 up
1127
1128 $IP -6 addr add 2001:db8:101::1/64 dev veth1 nodad
1129 $IP -6 addr add 2001:db8:103::1/64 dev veth3 nodad
1130 $IP addr add 172.16.101.1/24 dev veth1
1131 $IP addr add 172.16.103.1/24 dev veth3
1132
1133 ip -netns $ns2 -6 addr add 2001:db8:101::2/64 dev veth2 nodad
1134 ip -netns $ns2 -6 addr add 2001:db8:103::2/64 dev veth4 nodad
1135 ip -netns $ns2 -6 addr add 2001:db8:104::1/64 dev dummy1 nodad
1136
1137 ip -netns $ns2 addr add 172.16.101.2/24 dev veth2
1138 ip -netns $ns2 addr add 172.16.103.2/24 dev veth4
1139 ip -netns $ns2 addr add 172.16.104.1/24 dev dummy1
1140
1141 set +e
1142}
1143
1144forwarding_cleanup()
1145{
1146 cleanup_ns $ns3
1147
1148 route_cleanup
1149}
1150
1151# extend route_setup with an ns3 reachable through ns2 over both devices
1152forwarding_setup()
1153{
1154 forwarding_cleanup
1155
1156 route_setup
1157
1158 setup_ns ns3
1159
1160 ip link add veth5 netns $ns3 type veth peer name veth6 netns $ns2
1161 ip -netns $ns3 link set veth5 up
1162 ip -netns $ns2 link set veth6 up
1163
1164 ip -netns $ns3 -4 addr add dev veth5 172.16.105.1/24
1165 ip -netns $ns2 -4 addr add dev veth6 172.16.105.2/24
1166 ip -netns $ns3 -4 route add 172.16.100.0/22 via 172.16.105.2
1167
1168 ip -netns $ns3 -6 addr add dev veth5 2001:db8:105::1/64 nodad
1169 ip -netns $ns2 -6 addr add dev veth6 2001:db8:105::2/64 nodad
1170 ip -netns $ns3 -6 route add 2001:db8:101::/33 via 2001:db8:105::2
1171}
1172
1173# assumption is that basic add of a single path route works
1174# otherwise just adding an address on an interface is broken
1175ipv6_rt_add()
1176{
1177 local rc
1178
1179 echo
1180 echo "IPv6 route add / append tests"
1181
1182 # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL
1183 add_route6 "2001:db8:104::/64" "via 2001:db8:101::2"
1184 run_cmd "$IP -6 ro add 2001:db8:104::/64 via 2001:db8:103::2"
1185 log_test $? 2 "Attempt to add duplicate route - gw"
1186
1187 # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL
1188 add_route6 "2001:db8:104::/64" "via 2001:db8:101::2"
1189 run_cmd "$IP -6 ro add 2001:db8:104::/64 dev veth3"
1190 log_test $? 2 "Attempt to add duplicate route - dev only"
1191
1192 # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL
1193 add_route6 "2001:db8:104::/64" "via 2001:db8:101::2"
1194 run_cmd "$IP -6 ro add unreachable 2001:db8:104::/64"
1195 log_test $? 2 "Attempt to add duplicate route - reject route"
1196
1197 # route append with same prefix adds a new route
1198 # - iproute2 sets NLM_F_CREATE | NLM_F_APPEND
1199 add_route6 "2001:db8:104::/64" "via 2001:db8:101::2"
1200 run_cmd "$IP -6 ro append 2001:db8:104::/64 via 2001:db8:103::2"
1201 check_route6 "2001:db8:104::/64 metric 1024 nexthop via 2001:db8:101::2 dev veth1 weight 1 nexthop via 2001:db8:103::2 dev veth3 weight 1"
1202 log_test $? 0 "Append nexthop to existing route - gw"
1203
1204 # insert mpath directly
1205 add_route6 "2001:db8:104::/64" "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"
1206 check_route6 "2001:db8:104::/64 metric 1024 nexthop via 2001:db8:101::2 dev veth1 weight 1 nexthop via 2001:db8:103::2 dev veth3 weight 1"
1207 log_test $? 0 "Add multipath route"
1208
1209 add_route6 "2001:db8:104::/64" "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"
1210 run_cmd "$IP -6 ro add 2001:db8:104::/64 nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"
1211 log_test $? 2 "Attempt to add duplicate multipath route"
1212
1213 # insert of a second route without append but different metric
1214 add_route6 "2001:db8:104::/64" "via 2001:db8:101::2"
1215 run_cmd "$IP -6 ro add 2001:db8:104::/64 via 2001:db8:103::2 metric 512"
1216 rc=$?
1217 if [ $rc -eq 0 ]; then
1218 run_cmd "$IP -6 ro add 2001:db8:104::/64 via 2001:db8:103::3 metric 256"
1219 rc=$?
1220 fi
1221 log_test $rc 0 "Route add with different metrics"
1222
1223 run_cmd "$IP -6 ro del 2001:db8:104::/64 metric 512"
1224 rc=$?
1225 if [ $rc -eq 0 ]; then
1226 check_route6 "2001:db8:104::/64 via 2001:db8:103::3 dev veth3 metric 256 2001:db8:104::/64 via 2001:db8:101::2 dev veth1 metric 1024"
1227 rc=$?
1228 fi
1229 log_test $rc 0 "Route delete with metric"
1230}
1231
1232ipv6_rt_replace_single()
1233{
1234 # single path with single path
1235 #
1236 add_initial_route6 "via 2001:db8:101::2"
1237 run_cmd "$IP -6 ro replace 2001:db8:104::/64 via 2001:db8:103::2"
1238 check_route6 "2001:db8:104::/64 via 2001:db8:103::2 dev veth3 metric 1024"
1239 log_test $? 0 "Single path with single path"
1240
1241 # single path with multipath
1242 #
1243 add_initial_route6 "nexthop via 2001:db8:101::2"
1244 run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:101::3 nexthop via 2001:db8:103::2"
1245 check_route6 "2001:db8:104::/64 metric 1024 nexthop via 2001:db8:101::3 dev veth1 weight 1 nexthop via 2001:db8:103::2 dev veth3 weight 1"
1246 log_test $? 0 "Single path with multipath"
1247
1248 # single path with single path using MULTIPATH attribute
1249 #
1250 add_initial_route6 "via 2001:db8:101::2"
1251 run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:103::2"
1252 check_route6 "2001:db8:104::/64 via 2001:db8:103::2 dev veth3 metric 1024"
1253 log_test $? 0 "Single path with single path via multipath attribute"
1254
1255 # route replace fails - invalid nexthop
1256 add_initial_route6 "via 2001:db8:101::2"
1257 run_cmd "$IP -6 ro replace 2001:db8:104::/64 via 2001:db8:104::2"
1258 if [ $? -eq 0 ]; then
1259 # previous command is expected to fail so if it returns 0
1260 # that means the test failed.
1261 log_test 0 1 "Invalid nexthop"
1262 else
1263 check_route6 "2001:db8:104::/64 via 2001:db8:101::2 dev veth1 metric 1024"
1264 log_test $? 0 "Invalid nexthop"
1265 fi
1266
1267 # replace non-existent route
1268 # - note use of change versus replace since ip adds NLM_F_CREATE
1269 # for replace
1270 add_initial_route6 "via 2001:db8:101::2"
1271 run_cmd "$IP -6 ro change 2001:db8:105::/64 via 2001:db8:101::2"
1272 log_test $? 2 "Single path - replace of non-existent route"
1273}
1274
1275ipv6_rt_replace_mpath()
1276{
1277 # multipath with multipath
1278 add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"
1279 run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:101::3 nexthop via 2001:db8:103::3"
1280 check_route6 "2001:db8:104::/64 metric 1024 nexthop via 2001:db8:101::3 dev veth1 weight 1 nexthop via 2001:db8:103::3 dev veth3 weight 1"
1281 log_test $? 0 "Multipath with multipath"
1282
1283 # multipath with single
1284 add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"
1285 run_cmd "$IP -6 ro replace 2001:db8:104::/64 via 2001:db8:101::3"
1286 check_route6 "2001:db8:104::/64 via 2001:db8:101::3 dev veth1 metric 1024"
1287 log_test $? 0 "Multipath with single path"
1288
1289 # multipath with single
1290 add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"
1291 run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:101::3"
1292 check_route6 "2001:db8:104::/64 via 2001:db8:101::3 dev veth1 metric 1024"
1293 log_test $? 0 "Multipath with single path via multipath attribute"
1294
1295 # multipath with dev-only
1296 add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"
1297 run_cmd "$IP -6 ro replace 2001:db8:104::/64 dev veth1"
1298 check_route6 "2001:db8:104::/64 dev veth1 metric 1024"
1299 log_test $? 0 "Multipath with dev-only"
1300
1301 # route replace fails - invalid nexthop 1
1302 add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"
1303 run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:111::3 nexthop via 2001:db8:103::3"
1304 check_route6 "2001:db8:104::/64 metric 1024 nexthop via 2001:db8:101::2 dev veth1 weight 1 nexthop via 2001:db8:103::2 dev veth3 weight 1"
1305 log_test $? 0 "Multipath - invalid first nexthop"
1306
1307 # route replace fails - invalid nexthop 2
1308 add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"
1309 run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:101::3 nexthop via 2001:db8:113::3"
1310 check_route6 "2001:db8:104::/64 metric 1024 nexthop via 2001:db8:101::2 dev veth1 weight 1 nexthop via 2001:db8:103::2 dev veth3 weight 1"
1311 log_test $? 0 "Multipath - invalid second nexthop"
1312
1313 # multipath non-existent route
1314 add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"
1315 run_cmd "$IP -6 ro change 2001:db8:105::/64 nexthop via 2001:db8:101::3 nexthop via 2001:db8:103::3"
1316 log_test $? 2 "Multipath - replace of non-existent route"
1317}
1318
1319ipv6_rt_replace()
1320{
1321 echo
1322 echo "IPv6 route replace tests"
1323
1324 ipv6_rt_replace_single
1325 ipv6_rt_replace_mpath
1326}
1327
1328ipv6_rt_dsfield()
1329{
1330 echo
1331 echo "IPv6 route with dsfield tests"
1332
1333 run_cmd "$IP -6 route flush 2001:db8:102::/64"
1334
1335 # IPv6 doesn't support routing based on dsfield
1336 run_cmd "$IP -6 route add 2001:db8:102::/64 dsfield 0x04 via 2001:db8:101::2"
1337 log_test $? 2 "Reject route with dsfield"
1338}
1339
1340ipv6_route_test()
1341{
1342 route_setup
1343
1344 ipv6_rt_add
1345 ipv6_rt_replace
1346 ipv6_rt_dsfield
1347
1348 route_cleanup
1349}
1350
1351ip_addr_metric_check()
1352{
1353 ip addr help 2>&1 | grep -q metric
1354 if [ $? -ne 0 ]; then
1355 echo "iproute2 command does not support metric for addresses. Skipping test"
1356 return 1
1357 fi
1358
1359 return 0
1360}
1361
1362ipv6_addr_metric_test()
1363{
1364 local rc
1365
1366 echo
1367 echo "IPv6 prefix route tests"
1368
1369 ip_addr_metric_check || return 1
1370
1371 setup
1372
1373 set -e
1374 $IP li add dummy1 type dummy
1375 $IP li add dummy2 type dummy
1376 $IP li set dummy1 up
1377 $IP li set dummy2 up
1378
1379 # default entry is metric 256
1380 run_cmd "$IP -6 addr add dev dummy1 2001:db8:104::1/64"
1381 run_cmd "$IP -6 addr add dev dummy2 2001:db8:104::2/64"
1382 set +e
1383
1384 check_route6 "2001:db8:104::/64 dev dummy1 proto kernel metric 256 2001:db8:104::/64 dev dummy2 proto kernel metric 256"
1385 log_test $? 0 "Default metric"
1386
1387 set -e
1388 run_cmd "$IP -6 addr flush dev dummy1"
1389 run_cmd "$IP -6 addr add dev dummy1 2001:db8:104::1/64 metric 257"
1390 set +e
1391
1392 check_route6 "2001:db8:104::/64 dev dummy2 proto kernel metric 256 2001:db8:104::/64 dev dummy1 proto kernel metric 257"
1393 log_test $? 0 "User specified metric on first device"
1394
1395 set -e
1396 run_cmd "$IP -6 addr flush dev dummy2"
1397 run_cmd "$IP -6 addr add dev dummy2 2001:db8:104::2/64 metric 258"
1398 set +e
1399
1400 check_route6 "2001:db8:104::/64 dev dummy1 proto kernel metric 257 2001:db8:104::/64 dev dummy2 proto kernel metric 258"
1401 log_test $? 0 "User specified metric on second device"
1402
1403 run_cmd "$IP -6 addr del dev dummy1 2001:db8:104::1/64 metric 257"
1404 rc=$?
1405 if [ $rc -eq 0 ]; then
1406 check_route6 "2001:db8:104::/64 dev dummy2 proto kernel metric 258"
1407 rc=$?
1408 fi
1409 log_test $rc 0 "Delete of address on first device"
1410
1411 run_cmd "$IP -6 addr change dev dummy2 2001:db8:104::2/64 metric 259"
1412 rc=$?
1413 if [ $rc -eq 0 ]; then
1414 check_route6 "2001:db8:104::/64 dev dummy2 proto kernel metric 259"
1415 rc=$?
1416 fi
1417 log_test $rc 0 "Modify metric of address"
1418
1419 # verify prefix route removed on down
1420 run_cmd "ip netns exec $ns1 sysctl -qw net.ipv6.conf.all.keep_addr_on_down=1"
1421 run_cmd "$IP li set dev dummy2 down"
1422 rc=$?
1423 if [ $rc -eq 0 ]; then
1424 out=$($IP -6 ro ls match 2001:db8:104::/64)
1425 check_expected "${out}" ""
1426 rc=$?
1427 fi
1428 log_test $rc 0 "Prefix route removed on link down"
1429
1430 # verify prefix route re-inserted with assigned metric
1431 run_cmd "$IP li set dev dummy2 up"
1432 rc=$?
1433 if [ $rc -eq 0 ]; then
1434 check_route6 "2001:db8:104::/64 dev dummy2 proto kernel metric 259"
1435 rc=$?
1436 fi
1437 log_test $rc 0 "Prefix route with metric on link up"
1438
1439 # verify peer metric added correctly
1440 set -e
1441 run_cmd "$IP -6 addr flush dev dummy2"
1442 run_cmd "$IP -6 addr add dev dummy2 2001:db8:104::1 peer 2001:db8:104::2 metric 260"
1443 set +e
1444
1445 check_route6 "2001:db8:104::1 dev dummy2 proto kernel metric 260"
1446 log_test $? 0 "Set metric with peer route on local side"
1447 check_route6 "2001:db8:104::2 dev dummy2 proto kernel metric 260"
1448 log_test $? 0 "Set metric with peer route on peer side"
1449
1450 set -e
1451 run_cmd "$IP -6 addr change dev dummy2 2001:db8:104::1 peer 2001:db8:104::3 metric 261"
1452 set +e
1453
1454 check_route6 "2001:db8:104::1 dev dummy2 proto kernel metric 261"
1455 log_test $? 0 "Modify metric and peer address on local side"
1456 check_route6 "2001:db8:104::3 dev dummy2 proto kernel metric 261"
1457 log_test $? 0 "Modify metric and peer address on peer side"
1458
1459 $IP li del dummy1
1460 $IP li del dummy2
1461 cleanup
1462}
1463
1464ipv6_route_metrics_test()
1465{
1466 local rc
1467
1468 echo
1469 echo "IPv6 routes with metrics"
1470
1471 route_setup
1472
1473 #
1474 # single path with metrics
1475 #
1476 run_cmd "$IP -6 ro add 2001:db8:111::/64 via 2001:db8:101::2 mtu 1400"
1477 rc=$?
1478 if [ $rc -eq 0 ]; then
1479 check_route6 "2001:db8:111::/64 via 2001:db8:101::2 dev veth1 metric 1024 mtu 1400"
1480 rc=$?
1481 fi
1482 log_test $rc 0 "Single path route with mtu metric"
1483
1484
1485 #
1486 # multipath via separate routes with metrics
1487 #
1488 run_cmd "$IP -6 ro add 2001:db8:112::/64 via 2001:db8:101::2 mtu 1400"
1489 run_cmd "$IP -6 ro append 2001:db8:112::/64 via 2001:db8:103::2"
1490 rc=$?
1491 if [ $rc -eq 0 ]; then
1492 check_route6 "2001:db8:112::/64 metric 1024 mtu 1400 nexthop via 2001:db8:101::2 dev veth1 weight 1 nexthop via 2001:db8:103::2 dev veth3 weight 1"
1493 rc=$?
1494 fi
1495 log_test $rc 0 "Multipath route via 2 single routes with mtu metric on first"
1496
1497 # second route is coalesced to first to make a multipath route.
1498 # MTU of the second path is hidden from display!
1499 run_cmd "$IP -6 ro add 2001:db8:113::/64 via 2001:db8:101::2"
1500 run_cmd "$IP -6 ro append 2001:db8:113::/64 via 2001:db8:103::2 mtu 1400"
1501 rc=$?
1502 if [ $rc -eq 0 ]; then
1503 check_route6 "2001:db8:113::/64 metric 1024 nexthop via 2001:db8:101::2 dev veth1 weight 1 nexthop via 2001:db8:103::2 dev veth3 weight 1"
1504 rc=$?
1505 fi
1506 log_test $rc 0 "Multipath route via 2 single routes with mtu metric on 2nd"
1507
1508 run_cmd "$IP -6 ro del 2001:db8:113::/64 via 2001:db8:101::2"
1509 if [ $? -eq 0 ]; then
1510 check_route6 "2001:db8:113::/64 via 2001:db8:103::2 dev veth3 metric 1024 mtu 1400"
1511 log_test $? 0 " MTU of second leg"
1512 fi
1513
1514 #
1515 # multipath with metrics
1516 #
1517 run_cmd "$IP -6 ro add 2001:db8:115::/64 mtu 1400 nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"
1518 rc=$?
1519 if [ $rc -eq 0 ]; then
1520 check_route6 "2001:db8:115::/64 metric 1024 mtu 1400 nexthop via 2001:db8:101::2 dev veth1 weight 1 nexthop via 2001:db8:103::2 dev veth3 weight 1"
1521 rc=$?
1522 fi
1523 log_test $rc 0 "Multipath route with mtu metric"
1524
1525 $IP -6 ro add 2001:db8:104::/64 via 2001:db8:101::2 mtu 1300
1526 run_cmd "ip netns exec $ns1 ${ping6} -w1 -c1 -s 1500 2001:db8:104::1"
1527 log_test $? 0 "Using route with mtu metric"
1528
1529 run_cmd "$IP -6 ro add 2001:db8:114::/64 via 2001:db8:101::2 congctl lock foo"
1530 log_test $? 2 "Invalid metric (fails metric_convert)"
1531
1532 route_cleanup
1533}
1534
1535fib6_ra_to_static()
1536{
1537 setup
1538
1539 echo
1540 echo "Fib6 route promotion from RA-learned to static test"
1541 set -e
1542
1543 # ra6 is required for the test. (ipv6toolkit)
1544 if [ ! -x "$(command -v ra6)" ]; then
1545 echo "SKIP: ra6 not found."
1546 set +e
1547 cleanup &> /dev/null
1548 return
1549 fi
1550
1551 # Create a pair of veth devices to send a RA message from one
1552 # device to another.
1553 $IP link add veth1 type veth peer name veth2
1554 $IP link set dev veth1 up
1555 $IP link set dev veth2 up
1556 $IP -6 address add 2001:10::1/64 dev veth1 nodad
1557 $IP -6 address add 2001:10::2/64 dev veth2 nodad
1558
1559 # Make veth1 ready to receive RA messages.
1560 $NS_EXEC sysctl -wq net.ipv6.conf.veth1.accept_ra=2
1561
1562 # Send a RA message with a prefix from veth2.
1563 $NS_EXEC ra6 -i veth2 -d 2001:10::1 -P 2001:12::/64\#LA\#120\#60
1564
1565 # Wait for the RA message.
1566 sleep 1
1567
1568 # systemd may mess up the test. Make sure that
1569 # systemd-networkd.service and systemd-networkd.socket are stopped.
1570 check_rt_num_clean 2 $($IP -6 route list|grep expires|wc -l) || return
1571
1572 # Configure static address on the same prefix
1573 $IP -6 address add 2001:12::dead/64 dev veth1 nodad
1574
1575 # On-link route won't expire anymore, default route still owned by RA
1576 check_rt_num 1 $($IP -6 route list |grep expires|wc -l)
1577
1578 # Send a second RA message with a prefix from veth2.
1579 $NS_EXEC ra6 -i veth2 -d 2001:10::1 -P 2001:12::/64\#LA\#120\#60
1580 sleep 1
1581
1582 # Expire is not back, on-link route is still static
1583 check_rt_num 1 $($IP -6 route list |grep expires|wc -l)
1584
1585 $IP -6 address del 2001:12::dead/64 dev veth1 nodad
1586
1587 # Expire is back, on-link route is now owned by RA again
1588 check_rt_num 2 $($IP -6 route list |grep expires|wc -l)
1589
1590 log_test $ret 0 "ipv6 promote RA route to static"
1591
1592 # Prepare for RA route with gateway
1593 $NS_EXEC sysctl -wq net.ipv6.conf.veth1.accept_ra_rt_info_max_plen=64
1594
1595 # Add initial route to cause ECMP merging
1596 $IP -6 route add 2001:12::/64 via fe80::dead:beef dev veth1
1597
1598 $NS_EXEC ra6 -i veth2 -d 2001:10::1 -R 2001:12::/64#1#120
1599
1600 # Routes are not merged as RA routes are not elegible for ECMP
1601 check_rt_num 2 "$($IP -6 route list | grep -c "2001:12::/64 via")"
1602
1603 $IP -6 route append 2001:12::/64 via fe80::dead:feeb dev veth1
1604
1605 check_rt_num 2 "$($IP -6 route list | grep -c "nexthop via")"
1606
1607 log_test "$ret" 0 "ipv6 RA route with nexthop do not merge into ECMP with static"
1608
1609 set +e
1610
1611 cleanup &> /dev/null
1612}
1613
1614# add route for a prefix, flushing any existing routes first
1615# expected to be the first step of a test
1616add_route()
1617{
1618 local pfx="$1"
1619 local nh="$2"
1620 local out
1621
1622 if [ "$VERBOSE" = "1" ]; then
1623 echo
1624 echo " ##################################################"
1625 echo
1626 fi
1627
1628 run_cmd "$IP ro flush ${pfx}"
1629 [ $? -ne 0 ] && exit 1
1630
1631 out=$($IP ro ls match ${pfx})
1632 if [ -n "$out" ]; then
1633 echo "Failed to flush routes for prefix used for tests."
1634 exit 1
1635 fi
1636
1637 run_cmd "$IP ro add ${pfx} ${nh}"
1638 if [ $? -ne 0 ]; then
1639 echo "Failed to add initial route for test."
1640 exit 1
1641 fi
1642}
1643
1644# add initial route - used in replace route tests
1645add_initial_route()
1646{
1647 add_route "172.16.104.0/24" "$1"
1648}
1649
1650check_route()
1651{
1652 local pfx
1653 local expected="$1"
1654 local out
1655
1656 set -- $expected
1657 pfx=$1
1658 [ "${pfx}" = "unreachable" ] && pfx=$2
1659
1660 out=$($IP ro ls match ${pfx})
1661 check_expected "${out}" "${expected}"
1662}
1663
1664# assumption is that basic add of a single path route works
1665# otherwise just adding an address on an interface is broken
1666ipv4_rt_add()
1667{
1668 local rc
1669
1670 echo
1671 echo "IPv4 route add / append tests"
1672
1673 # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL
1674 add_route "172.16.104.0/24" "via 172.16.101.2"
1675 run_cmd "$IP ro add 172.16.104.0/24 via 172.16.103.2"
1676 log_test $? 2 "Attempt to add duplicate route - gw"
1677
1678 # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL
1679 add_route "172.16.104.0/24" "via 172.16.101.2"
1680 run_cmd "$IP ro add 172.16.104.0/24 dev veth3"
1681 log_test $? 2 "Attempt to add duplicate route - dev only"
1682
1683 # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL
1684 add_route "172.16.104.0/24" "via 172.16.101.2"
1685 run_cmd "$IP ro add unreachable 172.16.104.0/24"
1686 log_test $? 2 "Attempt to add duplicate route - reject route"
1687
1688 # iproute2 prepend only sets NLM_F_CREATE
1689 # - adds a new route; does NOT convert existing route to ECMP
1690 add_route "172.16.104.0/24" "via 172.16.101.2"
1691 run_cmd "$IP ro prepend 172.16.104.0/24 via 172.16.103.2"
1692 check_route "172.16.104.0/24 via 172.16.103.2 dev veth3 172.16.104.0/24 via 172.16.101.2 dev veth1"
1693 log_test $? 0 "Add new nexthop for existing prefix"
1694
1695 # route append with same prefix adds a new route
1696 # - iproute2 sets NLM_F_CREATE | NLM_F_APPEND
1697 add_route "172.16.104.0/24" "via 172.16.101.2"
1698 run_cmd "$IP ro append 172.16.104.0/24 via 172.16.103.2"
1699 check_route "172.16.104.0/24 via 172.16.101.2 dev veth1 172.16.104.0/24 via 172.16.103.2 dev veth3"
1700 log_test $? 0 "Append nexthop to existing route - gw"
1701
1702 add_route "172.16.104.0/24" "via 172.16.101.2"
1703 run_cmd "$IP ro append 172.16.104.0/24 dev veth3"
1704 check_route "172.16.104.0/24 via 172.16.101.2 dev veth1 172.16.104.0/24 dev veth3 scope link"
1705 log_test $? 0 "Append nexthop to existing route - dev only"
1706
1707 add_route "172.16.104.0/24" "via 172.16.101.2"
1708 run_cmd "$IP ro append unreachable 172.16.104.0/24"
1709 check_route "172.16.104.0/24 via 172.16.101.2 dev veth1 unreachable 172.16.104.0/24"
1710 log_test $? 0 "Append nexthop to existing route - reject route"
1711
1712 run_cmd "$IP ro flush 172.16.104.0/24"
1713 run_cmd "$IP ro add unreachable 172.16.104.0/24"
1714 run_cmd "$IP ro append 172.16.104.0/24 via 172.16.103.2"
1715 check_route "unreachable 172.16.104.0/24 172.16.104.0/24 via 172.16.103.2 dev veth3"
1716 log_test $? 0 "Append nexthop to existing reject route - gw"
1717
1718 run_cmd "$IP ro flush 172.16.104.0/24"
1719 run_cmd "$IP ro add unreachable 172.16.104.0/24"
1720 run_cmd "$IP ro append 172.16.104.0/24 dev veth3"
1721 check_route "unreachable 172.16.104.0/24 172.16.104.0/24 dev veth3 scope link"
1722 log_test $? 0 "Append nexthop to existing reject route - dev only"
1723
1724 # insert mpath directly
1725 add_route "172.16.104.0/24" "nexthop via 172.16.101.2 nexthop via 172.16.103.2"
1726 check_route "172.16.104.0/24 nexthop via 172.16.101.2 dev veth1 weight 1 nexthop via 172.16.103.2 dev veth3 weight 1"
1727 log_test $? 0 "add multipath route"
1728
1729 add_route "172.16.104.0/24" "nexthop via 172.16.101.2 nexthop via 172.16.103.2"
1730 run_cmd "$IP ro add 172.16.104.0/24 nexthop via 172.16.101.2 nexthop via 172.16.103.2"
1731 log_test $? 2 "Attempt to add duplicate multipath route"
1732
1733 # insert of a second route without append but different metric
1734 add_route "172.16.104.0/24" "via 172.16.101.2"
1735 run_cmd "$IP ro add 172.16.104.0/24 via 172.16.103.2 metric 512"
1736 rc=$?
1737 if [ $rc -eq 0 ]; then
1738 run_cmd "$IP ro add 172.16.104.0/24 via 172.16.103.3 metric 256"
1739 rc=$?
1740 fi
1741 log_test $rc 0 "Route add with different metrics"
1742
1743 run_cmd "$IP ro del 172.16.104.0/24 metric 512"
1744 rc=$?
1745 if [ $rc -eq 0 ]; then
1746 check_route "172.16.104.0/24 via 172.16.101.2 dev veth1 172.16.104.0/24 via 172.16.103.3 dev veth3 metric 256"
1747 rc=$?
1748 fi
1749 log_test $rc 0 "Route delete with metric"
1750}
1751
1752ipv4_rt_replace_single()
1753{
1754 # single path with single path
1755 #
1756 add_initial_route "via 172.16.101.2"
1757 run_cmd "$IP ro replace 172.16.104.0/24 via 172.16.103.2"
1758 check_route "172.16.104.0/24 via 172.16.103.2 dev veth3"
1759 log_test $? 0 "Single path with single path"
1760
1761 # single path with multipath
1762 #
1763 add_initial_route "nexthop via 172.16.101.2"
1764 run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.101.3 nexthop via 172.16.103.2"
1765 check_route "172.16.104.0/24 nexthop via 172.16.101.3 dev veth1 weight 1 nexthop via 172.16.103.2 dev veth3 weight 1"
1766 log_test $? 0 "Single path with multipath"
1767
1768 # single path with reject
1769 #
1770 add_initial_route "nexthop via 172.16.101.2"
1771 run_cmd "$IP ro replace unreachable 172.16.104.0/24"
1772 check_route "unreachable 172.16.104.0/24"
1773 log_test $? 0 "Single path with reject route"
1774
1775 # single path with single path using MULTIPATH attribute
1776 #
1777 add_initial_route "via 172.16.101.2"
1778 run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.103.2"
1779 check_route "172.16.104.0/24 via 172.16.103.2 dev veth3"
1780 log_test $? 0 "Single path with single path via multipath attribute"
1781
1782 # route replace fails - invalid nexthop
1783 add_initial_route "via 172.16.101.2"
1784 run_cmd "$IP ro replace 172.16.104.0/24 via 2001:db8:104::2"
1785 if [ $? -eq 0 ]; then
1786 # previous command is expected to fail so if it returns 0
1787 # that means the test failed.
1788 log_test 0 1 "Invalid nexthop"
1789 else
1790 check_route "172.16.104.0/24 via 172.16.101.2 dev veth1"
1791 log_test $? 0 "Invalid nexthop"
1792 fi
1793
1794 # replace non-existent route
1795 # - note use of change versus replace since ip adds NLM_F_CREATE
1796 # for replace
1797 add_initial_route "via 172.16.101.2"
1798 run_cmd "$IP ro change 172.16.105.0/24 via 172.16.101.2"
1799 log_test $? 2 "Single path - replace of non-existent route"
1800}
1801
1802ipv4_rt_replace_mpath()
1803{
1804 # multipath with multipath
1805 add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2"
1806 run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.101.3 nexthop via 172.16.103.3"
1807 check_route "172.16.104.0/24 nexthop via 172.16.101.3 dev veth1 weight 1 nexthop via 172.16.103.3 dev veth3 weight 1"
1808 log_test $? 0 "Multipath with multipath"
1809
1810 # multipath with single
1811 add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2"
1812 run_cmd "$IP ro replace 172.16.104.0/24 via 172.16.101.3"
1813 check_route "172.16.104.0/24 via 172.16.101.3 dev veth1"
1814 log_test $? 0 "Multipath with single path"
1815
1816 # multipath with single
1817 add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2"
1818 run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.101.3"
1819 check_route "172.16.104.0/24 via 172.16.101.3 dev veth1"
1820 log_test $? 0 "Multipath with single path via multipath attribute"
1821
1822 # multipath with reject
1823 add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2"
1824 run_cmd "$IP ro replace unreachable 172.16.104.0/24"
1825 check_route "unreachable 172.16.104.0/24"
1826 log_test $? 0 "Multipath with reject route"
1827
1828 # route replace fails - invalid nexthop 1
1829 add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2"
1830 run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.111.3 nexthop via 172.16.103.3"
1831 check_route "172.16.104.0/24 nexthop via 172.16.101.2 dev veth1 weight 1 nexthop via 172.16.103.2 dev veth3 weight 1"
1832 log_test $? 0 "Multipath - invalid first nexthop"
1833
1834 # route replace fails - invalid nexthop 2
1835 add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2"
1836 run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.101.3 nexthop via 172.16.113.3"
1837 check_route "172.16.104.0/24 nexthop via 172.16.101.2 dev veth1 weight 1 nexthop via 172.16.103.2 dev veth3 weight 1"
1838 log_test $? 0 "Multipath - invalid second nexthop"
1839
1840 # multipath non-existent route
1841 add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2"
1842 run_cmd "$IP ro change 172.16.105.0/24 nexthop via 172.16.101.3 nexthop via 172.16.103.3"
1843 log_test $? 2 "Multipath - replace of non-existent route"
1844}
1845
1846ipv4_rt_replace()
1847{
1848 echo
1849 echo "IPv4 route replace tests"
1850
1851 ipv4_rt_replace_single
1852 ipv4_rt_replace_mpath
1853}
1854
1855# checks that cached input route on VRF port is deleted
1856# when VRF is deleted
1857ipv4_local_rt_cache()
1858{
1859 run_cmd "ip addr add 10.0.0.1/32 dev lo"
1860 run_cmd "setup_ns test-ns"
1861 run_cmd "ip link add veth-outside type veth peer name veth-inside"
1862 run_cmd "ip link add vrf-100 type vrf table 1100"
1863 run_cmd "ip link set veth-outside master vrf-100"
1864 run_cmd "ip link set veth-inside netns $test-ns"
1865 run_cmd "ip link set veth-outside up"
1866 run_cmd "ip link set vrf-100 up"
1867 run_cmd "ip route add 10.1.1.1/32 dev veth-outside table 1100"
1868 run_cmd "ip netns exec $test-ns ip link set veth-inside up"
1869 run_cmd "ip netns exec $test-ns ip addr add 10.1.1.1/32 dev veth-inside"
1870 run_cmd "ip netns exec $test-ns ip route add 10.0.0.1/32 dev veth-inside"
1871 run_cmd "ip netns exec $test-ns ip route add default via 10.0.0.1"
1872 run_cmd "ip netns exec $test-ns ping 10.0.0.1 -c 1 -i 1"
1873 run_cmd "ip link delete vrf-100"
1874
1875 # if we do not hang test is a success
1876 log_test $? 0 "Cached route removed from VRF port device"
1877}
1878
1879ipv4_rt_dsfield()
1880{
1881 echo
1882 echo "IPv4 route with dsfield tests"
1883
1884 run_cmd "$IP route flush 172.16.102.0/24"
1885
1886 # New routes should reject dsfield options that interfere with ECN
1887 run_cmd "$IP route add 172.16.102.0/24 dsfield 0x01 via 172.16.101.2"
1888 log_test $? 2 "Reject route with dsfield 0x01"
1889
1890 run_cmd "$IP route add 172.16.102.0/24 dsfield 0x02 via 172.16.101.2"
1891 log_test $? 2 "Reject route with dsfield 0x02"
1892
1893 run_cmd "$IP route add 172.16.102.0/24 dsfield 0x03 via 172.16.101.2"
1894 log_test $? 2 "Reject route with dsfield 0x03"
1895
1896 # A generic route that doesn't take DSCP into account
1897 run_cmd "$IP route add 172.16.102.0/24 via 172.16.101.2"
1898
1899 # A more specific route for DSCP 0x10
1900 run_cmd "$IP route add 172.16.102.0/24 dsfield 0x10 via 172.16.103.2"
1901
1902 # DSCP 0x10 should match the specific route, no matter the ECN bits
1903 $IP route get fibmatch 172.16.102.1 dsfield 0x10 | \
1904 grep -q "172.16.102.0/24 tos 0x10 via 172.16.103.2"
1905 log_test $? 0 "IPv4 route with DSCP and ECN:Not-ECT"
1906
1907 $IP route get fibmatch 172.16.102.1 dsfield 0x11 | \
1908 grep -q "172.16.102.0/24 tos 0x10 via 172.16.103.2"
1909 log_test $? 0 "IPv4 route with DSCP and ECN:ECT(1)"
1910
1911 $IP route get fibmatch 172.16.102.1 dsfield 0x12 | \
1912 grep -q "172.16.102.0/24 tos 0x10 via 172.16.103.2"
1913 log_test $? 0 "IPv4 route with DSCP and ECN:ECT(0)"
1914
1915 $IP route get fibmatch 172.16.102.1 dsfield 0x13 | \
1916 grep -q "172.16.102.0/24 tos 0x10 via 172.16.103.2"
1917 log_test $? 0 "IPv4 route with DSCP and ECN:CE"
1918
1919 # Unknown DSCP should match the generic route, no matter the ECN bits
1920 $IP route get fibmatch 172.16.102.1 dsfield 0x14 | \
1921 grep -q "172.16.102.0/24 via 172.16.101.2"
1922 log_test $? 0 "IPv4 route with unknown DSCP and ECN:Not-ECT"
1923
1924 $IP route get fibmatch 172.16.102.1 dsfield 0x15 | \
1925 grep -q "172.16.102.0/24 via 172.16.101.2"
1926 log_test $? 0 "IPv4 route with unknown DSCP and ECN:ECT(1)"
1927
1928 $IP route get fibmatch 172.16.102.1 dsfield 0x16 | \
1929 grep -q "172.16.102.0/24 via 172.16.101.2"
1930 log_test $? 0 "IPv4 route with unknown DSCP and ECN:ECT(0)"
1931
1932 $IP route get fibmatch 172.16.102.1 dsfield 0x17 | \
1933 grep -q "172.16.102.0/24 via 172.16.101.2"
1934 log_test $? 0 "IPv4 route with unknown DSCP and ECN:CE"
1935
1936 # Null DSCP should match the generic route, no matter the ECN bits
1937 $IP route get fibmatch 172.16.102.1 dsfield 0x00 | \
1938 grep -q "172.16.102.0/24 via 172.16.101.2"
1939 log_test $? 0 "IPv4 route with no DSCP and ECN:Not-ECT"
1940
1941 $IP route get fibmatch 172.16.102.1 dsfield 0x01 | \
1942 grep -q "172.16.102.0/24 via 172.16.101.2"
1943 log_test $? 0 "IPv4 route with no DSCP and ECN:ECT(1)"
1944
1945 $IP route get fibmatch 172.16.102.1 dsfield 0x02 | \
1946 grep -q "172.16.102.0/24 via 172.16.101.2"
1947 log_test $? 0 "IPv4 route with no DSCP and ECN:ECT(0)"
1948
1949 $IP route get fibmatch 172.16.102.1 dsfield 0x03 | \
1950 grep -q "172.16.102.0/24 via 172.16.101.2"
1951 log_test $? 0 "IPv4 route with no DSCP and ECN:CE"
1952}
1953
1954ipv4_route_test()
1955{
1956 route_setup
1957
1958 ipv4_rt_add
1959 ipv4_rt_replace
1960 ipv4_local_rt_cache
1961 ipv4_rt_dsfield
1962
1963 route_cleanup
1964}
1965
1966ipv4_addr_metric_test()
1967{
1968 local rc
1969
1970 echo
1971 echo "IPv4 prefix route tests"
1972
1973 ip_addr_metric_check || return 1
1974
1975 setup
1976
1977 set -e
1978 $IP li add dummy1 type dummy
1979 $IP li add dummy2 type dummy
1980 $IP li set dummy1 up
1981 $IP li set dummy2 up
1982
1983 # default entry is metric 256
1984 run_cmd "$IP addr add dev dummy1 172.16.104.1/24"
1985 run_cmd "$IP addr add dev dummy2 172.16.104.2/24"
1986 set +e
1987
1988 check_route "172.16.104.0/24 dev dummy1 proto kernel scope link src 172.16.104.1 172.16.104.0/24 dev dummy2 proto kernel scope link src 172.16.104.2"
1989 log_test $? 0 "Default metric"
1990
1991 set -e
1992 run_cmd "$IP addr flush dev dummy1"
1993 run_cmd "$IP addr add dev dummy1 172.16.104.1/24 metric 257"
1994 set +e
1995
1996 check_route "172.16.104.0/24 dev dummy2 proto kernel scope link src 172.16.104.2 172.16.104.0/24 dev dummy1 proto kernel scope link src 172.16.104.1 metric 257"
1997 log_test $? 0 "User specified metric on first device"
1998
1999 set -e
2000 run_cmd "$IP addr flush dev dummy2"
2001 run_cmd "$IP addr add dev dummy2 172.16.104.2/24 metric 258"
2002 set +e
2003
2004 check_route "172.16.104.0/24 dev dummy1 proto kernel scope link src 172.16.104.1 metric 257 172.16.104.0/24 dev dummy2 proto kernel scope link src 172.16.104.2 metric 258"
2005 log_test $? 0 "User specified metric on second device"
2006
2007 run_cmd "$IP addr del dev dummy1 172.16.104.1/24 metric 257"
2008 rc=$?
2009 if [ $rc -eq 0 ]; then
2010 check_route "172.16.104.0/24 dev dummy2 proto kernel scope link src 172.16.104.2 metric 258"
2011 rc=$?
2012 fi
2013 log_test $rc 0 "Delete of address on first device"
2014
2015 run_cmd "$IP addr change dev dummy2 172.16.104.2/24 metric 259"
2016 rc=$?
2017 if [ $rc -eq 0 ]; then
2018 check_route "172.16.104.0/24 dev dummy2 proto kernel scope link src 172.16.104.2 metric 259"
2019 rc=$?
2020 fi
2021 log_test $rc 0 "Modify metric of address"
2022
2023 # verify prefix route removed on down
2024 run_cmd "$IP li set dev dummy2 down"
2025 rc=$?
2026 if [ $rc -eq 0 ]; then
2027 out=$($IP ro ls match 172.16.104.0/24)
2028 check_expected "${out}" ""
2029 rc=$?
2030 fi
2031 log_test $rc 0 "Prefix route removed on link down"
2032
2033 # verify prefix route re-inserted with assigned metric
2034 run_cmd "$IP li set dev dummy2 up"
2035 rc=$?
2036 if [ $rc -eq 0 ]; then
2037 check_route "172.16.104.0/24 dev dummy2 proto kernel scope link src 172.16.104.2 metric 259"
2038 rc=$?
2039 fi
2040 log_test $rc 0 "Prefix route with metric on link up"
2041
2042 # explicitly check for metric changes on edge scenarios
2043 run_cmd "$IP addr flush dev dummy2"
2044 run_cmd "$IP addr add dev dummy2 172.16.104.0/24 metric 259"
2045 run_cmd "$IP addr change dev dummy2 172.16.104.0/24 metric 260"
2046 rc=$?
2047 if [ $rc -eq 0 ]; then
2048 check_route "172.16.104.0/24 dev dummy2 proto kernel scope link src 172.16.104.0 metric 260"
2049 rc=$?
2050 fi
2051 log_test $rc 0 "Modify metric of .0/24 address"
2052
2053 run_cmd "$IP addr flush dev dummy2"
2054 run_cmd "$IP addr add dev dummy2 172.16.104.1/32 peer 172.16.104.2 metric 260"
2055 rc=$?
2056 if [ $rc -eq 0 ]; then
2057 check_route "172.16.104.2 dev dummy2 proto kernel scope link src 172.16.104.1 metric 260"
2058 rc=$?
2059 fi
2060 log_test $rc 0 "Set metric of address with peer route"
2061
2062 run_cmd "$IP addr change dev dummy2 172.16.104.1/32 peer 172.16.104.3 metric 261"
2063 rc=$?
2064 if [ $rc -eq 0 ]; then
2065 check_route "172.16.104.3 dev dummy2 proto kernel scope link src 172.16.104.1 metric 261"
2066 rc=$?
2067 fi
2068 log_test $rc 0 "Modify metric and peer address for peer route"
2069
2070 $IP li del dummy1
2071 $IP li del dummy2
2072 cleanup
2073}
2074
2075ipv4_route_metrics_test()
2076{
2077 local rc
2078
2079 echo
2080 echo "IPv4 route add / append tests"
2081
2082 route_setup
2083
2084 run_cmd "$IP ro add 172.16.111.0/24 via 172.16.101.2 mtu 1400"
2085 rc=$?
2086 if [ $rc -eq 0 ]; then
2087 check_route "172.16.111.0/24 via 172.16.101.2 dev veth1 mtu 1400"
2088 rc=$?
2089 fi
2090 log_test $rc 0 "Single path route with mtu metric"
2091
2092
2093 run_cmd "$IP ro add 172.16.112.0/24 mtu 1400 nexthop via 172.16.101.2 nexthop via 172.16.103.2"
2094 rc=$?
2095 if [ $rc -eq 0 ]; then
2096 check_route "172.16.112.0/24 mtu 1400 nexthop via 172.16.101.2 dev veth1 weight 1 nexthop via 172.16.103.2 dev veth3 weight 1"
2097 rc=$?
2098 fi
2099 log_test $rc 0 "Multipath route with mtu metric"
2100
2101 $IP ro add 172.16.104.0/24 via 172.16.101.2 mtu 1300
2102 run_cmd "ip netns exec $ns1 ping -w1 -c1 -s 1500 172.16.104.1"
2103 log_test $? 0 "Using route with mtu metric"
2104
2105 run_cmd "$IP ro add 172.16.111.0/24 via 172.16.101.2 congctl lock foo"
2106 log_test $? 2 "Invalid metric (fails metric_convert)"
2107
2108 route_cleanup
2109}
2110
2111ipv4_del_addr_test()
2112{
2113 echo
2114 echo "IPv4 delete address route tests"
2115
2116 setup
2117
2118 set -e
2119 $IP li add dummy1 type dummy
2120 $IP li set dummy1 up
2121 $IP li add dummy2 type dummy
2122 $IP li set dummy2 up
2123 $IP li add red type vrf table 1111
2124 $IP li set red up
2125 $IP ro add vrf red unreachable default
2126 $IP li set dummy2 vrf red
2127
2128 $IP addr add dev dummy1 172.16.104.1/24
2129 $IP addr add dev dummy1 172.16.104.11/24
2130 $IP addr add dev dummy1 172.16.104.12/24
2131 $IP addr add dev dummy1 172.16.104.13/24
2132 $IP addr add dev dummy2 172.16.104.1/24
2133 $IP addr add dev dummy2 172.16.104.11/24
2134 $IP addr add dev dummy2 172.16.104.12/24
2135 $IP route add 172.16.105.0/24 via 172.16.104.2 src 172.16.104.11
2136 $IP route add 172.16.106.0/24 dev lo src 172.16.104.12
2137 $IP route add table 0 172.16.107.0/24 via 172.16.104.2 src 172.16.104.13
2138 $IP route add vrf red 172.16.105.0/24 via 172.16.104.2 src 172.16.104.11
2139 $IP route add vrf red 172.16.106.0/24 dev lo src 172.16.104.12
2140 set +e
2141
2142 # removing address from device in vrf should only remove route from vrf table
2143 echo " Regular FIB info"
2144
2145 $IP addr del dev dummy2 172.16.104.11/24
2146 $IP ro ls vrf red | grep -q 172.16.105.0/24
2147 log_test $? 1 "Route removed from VRF when source address deleted"
2148
2149 $IP ro ls | grep -q 172.16.105.0/24
2150 log_test $? 0 "Route in default VRF not removed"
2151
2152 $IP addr add dev dummy2 172.16.104.11/24
2153 $IP route add vrf red 172.16.105.0/24 via 172.16.104.2 src 172.16.104.11
2154
2155 $IP addr del dev dummy1 172.16.104.11/24
2156 $IP ro ls | grep -q 172.16.105.0/24
2157 log_test $? 1 "Route removed in default VRF when source address deleted"
2158
2159 $IP ro ls vrf red | grep -q 172.16.105.0/24
2160 log_test $? 0 "Route in VRF is not removed by address delete"
2161
2162 # removing address from device in vrf should only remove route from vrf
2163 # table even when the associated fib info only differs in table ID
2164 echo " Identical FIB info with different table ID"
2165
2166 $IP addr del dev dummy2 172.16.104.12/24
2167 $IP ro ls vrf red | grep -q 172.16.106.0/24
2168 log_test $? 1 "Route removed from VRF when source address deleted"
2169
2170 $IP ro ls | grep -q 172.16.106.0/24
2171 log_test $? 0 "Route in default VRF not removed"
2172
2173 $IP addr add dev dummy2 172.16.104.12/24
2174 $IP route add vrf red 172.16.106.0/24 dev lo src 172.16.104.12
2175
2176 $IP addr del dev dummy1 172.16.104.12/24
2177 $IP ro ls | grep -q 172.16.106.0/24
2178 log_test $? 1 "Route removed in default VRF when source address deleted"
2179
2180 $IP ro ls vrf red | grep -q 172.16.106.0/24
2181 log_test $? 0 "Route in VRF is not removed by address delete"
2182
2183 # removing address from device in default vrf should remove route from
2184 # the default vrf even when route was inserted with a table ID of 0.
2185 echo " Table ID 0"
2186
2187 $IP addr del dev dummy1 172.16.104.13/24
2188 $IP ro ls | grep -q 172.16.107.0/24
2189 log_test $? 1 "Route removed in default VRF when source address deleted"
2190
2191 $IP li del dummy1
2192 $IP li del dummy2
2193 cleanup
2194}
2195
2196ipv6_del_addr_test()
2197{
2198 echo
2199 echo "IPv6 delete address route tests"
2200
2201 setup
2202
2203 set -e
2204 for i in $(seq 6); do
2205 $IP li add dummy${i} up type dummy
2206 done
2207
2208 $IP li add red up type vrf table 1111
2209 $IP ro add vrf red unreachable default
2210 for i in $(seq 4 6); do
2211 $IP li set dummy${i} vrf red
2212 done
2213
2214 $IP addr add dev dummy1 fe80::1/128
2215 $IP addr add dev dummy1 2001:db8:101::1/64
2216 $IP addr add dev dummy1 2001:db8:101::10/64
2217 $IP addr add dev dummy1 2001:db8:101::11/64
2218 $IP addr add dev dummy1 2001:db8:101::12/64
2219 $IP addr add dev dummy1 2001:db8:101::13/64
2220 $IP addr add dev dummy1 2001:db8:101::14/64
2221 $IP addr add dev dummy1 2001:db8:101::15/64
2222 $IP addr add dev dummy2 fe80::1/128
2223 $IP addr add dev dummy2 2001:db8:101::1/64
2224 $IP addr add dev dummy2 2001:db8:101::11/64
2225 $IP addr add dev dummy3 fe80::1/128
2226
2227 $IP addr add dev dummy4 2001:db8:101::1/64
2228 $IP addr add dev dummy4 2001:db8:101::10/64
2229 $IP addr add dev dummy4 2001:db8:101::11/64
2230 $IP addr add dev dummy4 2001:db8:101::12/64
2231 $IP addr add dev dummy4 2001:db8:101::13/64
2232 $IP addr add dev dummy4 2001:db8:101::14/64
2233 $IP addr add dev dummy5 2001:db8:101::1/64
2234 $IP addr add dev dummy5 2001:db8:101::11/64
2235
2236 # Single device using src address
2237 $IP route add 2001:db8:110::/64 dev dummy3 src 2001:db8:101::10
2238 # Two devices with the same source address
2239 $IP route add 2001:db8:111::/64 dev dummy3 src 2001:db8:101::11
2240 # VRF with single device using src address
2241 $IP route add vrf red 2001:db8:110::/64 dev dummy6 src 2001:db8:101::10
2242 # VRF with two devices using src address
2243 $IP route add vrf red 2001:db8:111::/64 dev dummy6 src 2001:db8:101::11
2244 # src address and nexthop dev in same VRF
2245 $IP route add 2001:db8:112::/64 dev dummy3 src 2001:db8:101::12
2246 $IP route add vrf red 2001:db8:112::/64 dev dummy6 src 2001:db8:101::12
2247 # src address and nexthop device in different VRF
2248 $IP route add 2001:db8:113::/64 dev lo src 2001:db8:101::13
2249 $IP route add vrf red 2001:db8:113::/64 dev lo src 2001:db8:101::13
2250 # table ID 0
2251 $IP route add table 0 2001:db8:115::/64 via 2001:db8:101::2 src 2001:db8:101::15
2252 # Link local source route
2253 $IP route add 2001:db8:116::/64 dev dummy2 src fe80::1
2254 $IP route add 2001:db8:117::/64 dev dummy3 src fe80::1
2255 set +e
2256
2257 echo " Single device using src address"
2258
2259 $IP addr del dev dummy1 2001:db8:101::10/64
2260 $IP -6 route show | grep -q "src 2001:db8:101::10 "
2261 log_test $? 1 "Prefsrc removed when src address removed on other device"
2262
2263 echo " Two devices with the same source address"
2264
2265 $IP addr del dev dummy1 2001:db8:101::11/64
2266 $IP -6 route show | grep -q "src 2001:db8:101::11 "
2267 log_test $? 0 "Prefsrc not removed when src address exist on other device"
2268
2269 $IP addr del dev dummy2 2001:db8:101::11/64
2270 $IP -6 route show | grep -q "src 2001:db8:101::11 "
2271 log_test $? 1 "Prefsrc removed when src address removed on all devices"
2272
2273 echo " VRF with single device using src address"
2274
2275 $IP addr del dev dummy4 2001:db8:101::10/64
2276 $IP -6 route show vrf red | grep -q "src 2001:db8:101::10 "
2277 log_test $? 1 "Prefsrc removed when src address removed on other device"
2278
2279 echo " VRF with two devices using src address"
2280
2281 $IP addr del dev dummy4 2001:db8:101::11/64
2282 $IP -6 route show vrf red | grep -q "src 2001:db8:101::11 "
2283 log_test $? 0 "Prefsrc not removed when src address exist on other device"
2284
2285 $IP addr del dev dummy5 2001:db8:101::11/64
2286 $IP -6 route show vrf red | grep -q "src 2001:db8:101::11 "
2287 log_test $? 1 "Prefsrc removed when src address removed on all devices"
2288
2289 echo " src address and nexthop dev in same VRF"
2290
2291 $IP addr del dev dummy4 2001:db8:101::12/64
2292 $IP -6 route show vrf red | grep -q "src 2001:db8:101::12 "
2293 log_test $? 1 "Prefsrc removed from VRF when source address deleted"
2294 $IP -6 route show | grep -q " src 2001:db8:101::12 "
2295 log_test $? 0 "Prefsrc in default VRF not removed"
2296
2297 $IP addr add dev dummy4 2001:db8:101::12/64
2298 $IP route replace vrf red 2001:db8:112::/64 dev dummy6 src 2001:db8:101::12
2299 $IP addr del dev dummy1 2001:db8:101::12/64
2300 $IP -6 route show vrf red | grep -q "src 2001:db8:101::12 "
2301 log_test $? 0 "Prefsrc not removed from VRF when source address exist"
2302 $IP -6 route show | grep -q " src 2001:db8:101::12 "
2303 log_test $? 1 "Prefsrc in default VRF removed"
2304
2305 echo " src address and nexthop device in different VRF"
2306
2307 $IP addr del dev dummy4 2001:db8:101::13/64
2308 $IP -6 route show vrf red | grep -q "src 2001:db8:101::13 "
2309 log_test $? 0 "Prefsrc not removed from VRF when nexthop dev in diff VRF"
2310 $IP -6 route show | grep -q "src 2001:db8:101::13 "
2311 log_test $? 0 "Prefsrc not removed in default VRF"
2312
2313 $IP addr add dev dummy4 2001:db8:101::13/64
2314 $IP addr del dev dummy1 2001:db8:101::13/64
2315 $IP -6 route show vrf red | grep -q "src 2001:db8:101::13 "
2316 log_test $? 1 "Prefsrc removed from VRF when nexthop dev in diff VRF"
2317 $IP -6 route show | grep -q "src 2001:db8:101::13 "
2318 log_test $? 1 "Prefsrc removed in default VRF"
2319
2320 echo " Table ID 0"
2321
2322 $IP addr del dev dummy1 2001:db8:101::15/64
2323 $IP -6 route show | grep -q "src 2001:db8:101::15"
2324 log_test $? 1 "Prefsrc removed from default VRF when source address deleted"
2325
2326 echo " Link local source route"
2327 $IP addr del dev dummy1 fe80::1/128
2328 $IP -6 route show | grep -q "2001:db8:116::/64 dev dummy2 src fe80::1"
2329 log_test $? 0 "Prefsrc not removed when delete ll addr from other dev"
2330 $IP addr del dev dummy2 fe80::1/128
2331 $IP -6 route show | grep -q "2001:db8:116::/64 dev dummy2 src fe80::1"
2332 log_test $? 1 "Prefsrc removed when delete ll addr"
2333 $IP -6 route show | grep -q "2001:db8:117::/64 dev dummy3 src fe80::1"
2334 log_test $? 0 "Prefsrc not removed when delete ll addr from other dev"
2335 $IP addr add dev dummy1 fe80::1/128
2336 $IP addr del dev dummy3 fe80::1/128
2337 $IP -6 route show | grep -q "2001:db8:117::/64 dev dummy3 src fe80::1"
2338 log_test $? 1 "Prefsrc removed even ll addr still exist on other dev"
2339
2340 for i in $(seq 6); do
2341 $IP li del dummy${i}
2342 done
2343 cleanup
2344}
2345
2346ipv4_route_v6_gw_test()
2347{
2348 local rc
2349
2350 echo
2351 echo "IPv4 route with IPv6 gateway tests"
2352
2353 route_setup
2354 sleep 2
2355
2356 #
2357 # single path route
2358 #
2359 run_cmd "$IP ro add 172.16.104.0/24 via inet6 2001:db8:101::2"
2360 rc=$?
2361 log_test $rc 0 "Single path route with IPv6 gateway"
2362 if [ $rc -eq 0 ]; then
2363 check_route "172.16.104.0/24 via inet6 2001:db8:101::2 dev veth1"
2364 fi
2365
2366 run_cmd "ip netns exec $ns1 ping -w1 -c1 172.16.104.1"
2367 log_test $rc 0 "Single path route with IPv6 gateway - ping"
2368
2369 run_cmd "$IP ro del 172.16.104.0/24 via inet6 2001:db8:101::2"
2370 rc=$?
2371 log_test $rc 0 "Single path route delete"
2372 if [ $rc -eq 0 ]; then
2373 check_route "172.16.112.0/24"
2374 fi
2375
2376 #
2377 # multipath - v6 then v4
2378 #
2379 run_cmd "$IP ro add 172.16.104.0/24 nexthop via inet6 2001:db8:101::2 dev veth1 nexthop via 172.16.103.2 dev veth3"
2380 rc=$?
2381 log_test $rc 0 "Multipath route add - v6 nexthop then v4"
2382 if [ $rc -eq 0 ]; then
2383 check_route "172.16.104.0/24 nexthop via inet6 2001:db8:101::2 dev veth1 weight 1 nexthop via 172.16.103.2 dev veth3 weight 1"
2384 fi
2385
2386 run_cmd "$IP ro del 172.16.104.0/24 nexthop via 172.16.103.2 dev veth3 nexthop via inet6 2001:db8:101::2 dev veth1"
2387 log_test $? 2 " Multipath route delete - nexthops in wrong order"
2388
2389 run_cmd "$IP ro del 172.16.104.0/24 nexthop via inet6 2001:db8:101::2 dev veth1 nexthop via 172.16.103.2 dev veth3"
2390 log_test $? 0 " Multipath route delete exact match"
2391
2392 #
2393 # multipath - v4 then v6
2394 #
2395 run_cmd "$IP ro add 172.16.104.0/24 nexthop via 172.16.103.2 dev veth3 nexthop via inet6 2001:db8:101::2 dev veth1"
2396 rc=$?
2397 log_test $rc 0 "Multipath route add - v4 nexthop then v6"
2398 if [ $rc -eq 0 ]; then
2399 check_route "172.16.104.0/24 nexthop via 172.16.103.2 dev veth3 weight 1 nexthop via inet6 2001:db8:101::2 dev veth1 weight 1"
2400 fi
2401
2402 run_cmd "$IP ro del 172.16.104.0/24 nexthop via inet6 2001:db8:101::2 dev veth1 nexthop via 172.16.103.2 dev veth3"
2403 log_test $? 2 " Multipath route delete - nexthops in wrong order"
2404
2405 run_cmd "$IP ro del 172.16.104.0/24 nexthop via 172.16.103.2 dev veth3 nexthop via inet6 2001:db8:101::2 dev veth1"
2406 log_test $? 0 " Multipath route delete exact match"
2407
2408 route_cleanup
2409}
2410
2411socat_check()
2412{
2413 if [ ! -x "$(command -v socat)" ]; then
2414 echo "socat command not found. Skipping test"
2415 return 1
2416 fi
2417
2418 return 0
2419}
2420
2421iptables_check()
2422{
2423 iptables -t mangle -L OUTPUT &> /dev/null
2424 if [ $? -ne 0 ]; then
2425 echo "iptables configuration not supported. Skipping test"
2426 return 1
2427 fi
2428
2429 return 0
2430}
2431
2432ip6tables_check()
2433{
2434 ip6tables -t mangle -L OUTPUT &> /dev/null
2435 if [ $? -ne 0 ]; then
2436 echo "ip6tables configuration not supported. Skipping test"
2437 return 1
2438 fi
2439
2440 return 0
2441}
2442
2443ipv4_mangle_test()
2444{
2445 local rc
2446
2447 echo
2448 echo "IPv4 mangling tests"
2449
2450 socat_check || return 1
2451 iptables_check || return 1
2452
2453 route_setup
2454 sleep 2
2455
2456 local tmp_file=$(mktemp)
2457 ip netns exec $ns2 socat UDP4-LISTEN:54321,fork $tmp_file &
2458
2459 # Add a FIB rule and a route that will direct our connection to the
2460 # listening server.
2461 $IP rule add pref 100 ipproto udp sport 12345 dport 54321 table 123
2462 $IP route add table 123 172.16.101.0/24 dev veth1
2463
2464 # Add an unreachable route to the main table that will block our
2465 # connection in case the FIB rule is not hit.
2466 $IP route add unreachable 172.16.101.2/32
2467
2468 run_cmd "echo a | $NS_EXEC socat STDIN UDP4:172.16.101.2:54321,sourceport=12345"
2469 log_test $? 0 " Connection with correct parameters"
2470
2471 run_cmd "echo a | $NS_EXEC socat STDIN UDP4:172.16.101.2:54321,sourceport=11111"
2472 log_test $? 1 " Connection with incorrect parameters"
2473
2474 # Add a mangling rule and make sure connection is still successful.
2475 $NS_EXEC iptables -t mangle -A OUTPUT -j MARK --set-mark 1
2476
2477 run_cmd "echo a | $NS_EXEC socat STDIN UDP4:172.16.101.2:54321,sourceport=12345"
2478 log_test $? 0 " Connection with correct parameters - mangling"
2479
2480 # Delete the mangling rule and make sure connection is still
2481 # successful.
2482 $NS_EXEC iptables -t mangle -D OUTPUT -j MARK --set-mark 1
2483
2484 run_cmd "echo a | $NS_EXEC socat STDIN UDP4:172.16.101.2:54321,sourceport=12345"
2485 log_test $? 0 " Connection with correct parameters - no mangling"
2486
2487 # Verify connections were indeed successful on server side.
2488 [[ $(cat $tmp_file | wc -l) -eq 3 ]]
2489 log_test $? 0 " Connection check - server side"
2490
2491 $IP route del unreachable 172.16.101.2/32
2492 $IP route del table 123 172.16.101.0/24 dev veth1
2493 $IP rule del pref 100
2494
2495 kill_process %%
2496 rm $tmp_file
2497
2498 route_cleanup
2499}
2500
2501ipv6_mangle_test()
2502{
2503 local rc
2504
2505 echo
2506 echo "IPv6 mangling tests"
2507
2508 socat_check || return 1
2509 ip6tables_check || return 1
2510
2511 route_setup
2512 sleep 2
2513
2514 local tmp_file=$(mktemp)
2515 ip netns exec $ns2 socat UDP6-LISTEN:54321,fork $tmp_file &
2516
2517 # Add a FIB rule and a route that will direct our connection to the
2518 # listening server.
2519 $IP -6 rule add pref 100 ipproto udp sport 12345 dport 54321 table 123
2520 $IP -6 route add table 123 2001:db8:101::/64 dev veth1
2521
2522 # Add an unreachable route to the main table that will block our
2523 # connection in case the FIB rule is not hit.
2524 $IP -6 route add unreachable 2001:db8:101::2/128
2525
2526 run_cmd "echo a | $NS_EXEC socat STDIN UDP6:[2001:db8:101::2]:54321,sourceport=12345"
2527 log_test $? 0 " Connection with correct parameters"
2528
2529 run_cmd "echo a | $NS_EXEC socat STDIN UDP6:[2001:db8:101::2]:54321,sourceport=11111"
2530 log_test $? 1 " Connection with incorrect parameters"
2531
2532 # Add a mangling rule and make sure connection is still successful.
2533 $NS_EXEC ip6tables -t mangle -A OUTPUT -j MARK --set-mark 1
2534
2535 run_cmd "echo a | $NS_EXEC socat STDIN UDP6:[2001:db8:101::2]:54321,sourceport=12345"
2536 log_test $? 0 " Connection with correct parameters - mangling"
2537
2538 # Delete the mangling rule and make sure connection is still
2539 # successful.
2540 $NS_EXEC ip6tables -t mangle -D OUTPUT -j MARK --set-mark 1
2541
2542 run_cmd "echo a | $NS_EXEC socat STDIN UDP6:[2001:db8:101::2]:54321,sourceport=12345"
2543 log_test $? 0 " Connection with correct parameters - no mangling"
2544
2545 # Verify connections were indeed successful on server side.
2546 [[ $(cat $tmp_file | wc -l) -eq 3 ]]
2547 log_test $? 0 " Connection check - server side"
2548
2549 $IP -6 route del unreachable 2001:db8:101::2/128
2550 $IP -6 route del table 123 2001:db8:101::/64 dev veth1
2551 $IP -6 rule del pref 100
2552
2553 kill_process %%
2554 rm $tmp_file
2555
2556 route_cleanup
2557}
2558
2559ip_neigh_get_check()
2560{
2561 ip neigh help 2>&1 | grep -q 'ip neigh get'
2562 if [ $? -ne 0 ]; then
2563 echo "iproute2 command does not support neigh get. Skipping test"
2564 return 1
2565 fi
2566
2567 return 0
2568}
2569
2570ipv4_bcast_neigh_test()
2571{
2572 local rc
2573
2574 echo
2575 echo "IPv4 broadcast neighbour tests"
2576
2577 ip_neigh_get_check || return 1
2578
2579 setup
2580
2581 set -e
2582 run_cmd "$IP neigh add 192.0.2.111 lladdr 00:11:22:33:44:55 nud perm dev dummy0"
2583 run_cmd "$IP neigh add 192.0.2.255 lladdr 00:11:22:33:44:55 nud perm dev dummy0"
2584
2585 run_cmd "$IP neigh get 192.0.2.111 dev dummy0"
2586 run_cmd "$IP neigh get 192.0.2.255 dev dummy0"
2587
2588 run_cmd "$IP address add 192.0.2.1/24 broadcast 192.0.2.111 dev dummy0"
2589
2590 run_cmd "$IP neigh add 203.0.113.111 nud failed dev dummy0"
2591 run_cmd "$IP neigh add 203.0.113.255 nud failed dev dummy0"
2592
2593 run_cmd "$IP neigh get 203.0.113.111 dev dummy0"
2594 run_cmd "$IP neigh get 203.0.113.255 dev dummy0"
2595
2596 run_cmd "$IP address add 203.0.113.1/24 broadcast 203.0.113.111 dev dummy0"
2597 set +e
2598
2599 run_cmd "$IP neigh get 192.0.2.111 dev dummy0"
2600 log_test $? 0 "Resolved neighbour for broadcast address"
2601
2602 run_cmd "$IP neigh get 192.0.2.255 dev dummy0"
2603 log_test $? 0 "Resolved neighbour for network broadcast address"
2604
2605 run_cmd "$IP neigh get 203.0.113.111 dev dummy0"
2606 log_test $? 2 "Unresolved neighbour for broadcast address"
2607
2608 run_cmd "$IP neigh get 203.0.113.255 dev dummy0"
2609 log_test $? 2 "Unresolved neighbour for network broadcast address"
2610
2611 cleanup
2612}
2613
2614mpath_dep_check()
2615{
2616 if [ ! -x "$(command -v mausezahn)" ]; then
2617 echo "mausezahn command not found. Skipping test"
2618 return 1
2619 fi
2620
2621 if [ ! -x "$(command -v jq)" ]; then
2622 echo "jq command not found. Skipping test"
2623 return 1
2624 fi
2625
2626 if [ ! -x "$(command -v bc)" ]; then
2627 echo "bc command not found. Skipping test"
2628 return 1
2629 fi
2630
2631 if [ ! -x "$(command -v perf)" ]; then
2632 echo "perf command not found. Skipping test"
2633 return 1
2634 fi
2635
2636 perf list fib:* | grep -q fib_table_lookup
2637 if [ $? -ne 0 ]; then
2638 echo "IPv4 FIB tracepoint not found. Skipping test"
2639 return 1
2640 fi
2641
2642 perf list fib6:* | grep -q fib6_table_lookup
2643 if [ $? -ne 0 ]; then
2644 echo "IPv6 FIB tracepoint not found. Skipping test"
2645 return 1
2646 fi
2647
2648 return 0
2649}
2650
2651link_stats_get()
2652{
2653 local ns=$1; shift
2654 local dev=$1; shift
2655 local dir=$1; shift
2656 local stat=$1; shift
2657
2658 ip -n $ns -j -s link show dev $dev \
2659 | jq '.[]["stats64"]["'$dir'"]["'$stat'"]'
2660}
2661
2662list_rcv_eval()
2663{
2664 local file=$1; shift
2665 local expected=$1; shift
2666
2667 local count=$(tail -n 1 $file | jq '.["counter-value"] | tonumber | floor')
2668 local ratio=$(echo "scale=2; $count / $expected" | bc -l)
2669 local res=$(echo "$ratio >= 0.95" | bc)
2670 [[ $res -eq 1 ]]
2671 log_test $? 0 "Multipath route hit ratio ($ratio)"
2672}
2673
2674ipv4_mpath_list_test()
2675{
2676 echo
2677 echo "IPv4 multipath list receive tests"
2678
2679 mpath_dep_check || return 1
2680
2681 route_setup
2682
2683 set -e
2684 run_cmd "ip netns exec $ns1 ethtool -K veth1 tcp-segmentation-offload off"
2685
2686 run_cmd "ip netns exec $ns2 bash -c \"echo 20000 > /sys/class/net/veth2/gro_flush_timeout\""
2687 run_cmd "ip netns exec $ns2 bash -c \"echo 1 > /sys/class/net/veth2/napi_defer_hard_irqs\""
2688 run_cmd "ip netns exec $ns2 ethtool -K veth2 generic-receive-offload on"
2689 run_cmd "ip -n $ns2 link add name nh1 up type dummy"
2690 run_cmd "ip -n $ns2 link add name nh2 up type dummy"
2691 run_cmd "ip -n $ns2 address add 172.16.201.1/24 dev nh1"
2692 run_cmd "ip -n $ns2 address add 172.16.202.1/24 dev nh2"
2693 run_cmd "ip -n $ns2 neigh add 172.16.201.2 lladdr 00:11:22:33:44:55 nud perm dev nh1"
2694 run_cmd "ip -n $ns2 neigh add 172.16.202.2 lladdr 00:aa:bb:cc:dd:ee nud perm dev nh2"
2695 run_cmd "ip -n $ns2 route add 203.0.113.0/24
2696 nexthop via 172.16.201.2 nexthop via 172.16.202.2"
2697 run_cmd "ip netns exec $ns2 sysctl -qw net.ipv4.fib_multipath_hash_policy=1"
2698 set +e
2699
2700 local dmac=$(ip -n $ns2 -j link show dev veth2 | jq -r '.[]["address"]')
2701 local tmp_file=$(mktemp)
2702 local cmd="ip netns exec $ns1 mausezahn veth1 -a own -b $dmac
2703 -A 172.16.101.1 -B 203.0.113.1 -t udp 'sp=12345,dp=0-65535' -q"
2704
2705 # Packets forwarded in a list using a multipath route must not reuse a
2706 # cached result so that a flow always hits the same nexthop. In other
2707 # words, the FIB lookup tracepoint needs to be triggered for every
2708 # packet.
2709 local t0_rx_pkts=$(link_stats_get $ns2 veth2 rx packets)
2710 run_cmd "perf stat -a -e fib:fib_table_lookup --filter 'err == 0' -j -o $tmp_file -- $cmd"
2711 local t1_rx_pkts=$(link_stats_get $ns2 veth2 rx packets)
2712 local diff=$(echo $t1_rx_pkts - $t0_rx_pkts | bc -l)
2713 list_rcv_eval $tmp_file $diff
2714
2715 rm $tmp_file
2716 route_cleanup
2717}
2718
2719ipv6_mpath_list_test()
2720{
2721 echo
2722 echo "IPv6 multipath list receive tests"
2723
2724 mpath_dep_check || return 1
2725
2726 route_setup
2727
2728 set -e
2729 run_cmd "ip netns exec $ns1 ethtool -K veth1 tcp-segmentation-offload off"
2730
2731 run_cmd "ip netns exec $ns2 bash -c \"echo 20000 > /sys/class/net/veth2/gro_flush_timeout\""
2732 run_cmd "ip netns exec $ns2 bash -c \"echo 1 > /sys/class/net/veth2/napi_defer_hard_irqs\""
2733 run_cmd "ip netns exec $ns2 ethtool -K veth2 generic-receive-offload on"
2734 run_cmd "ip -n $ns2 link add name nh1 up type dummy"
2735 run_cmd "ip -n $ns2 link add name nh2 up type dummy"
2736 run_cmd "ip -n $ns2 -6 address add 2001:db8:201::1/64 dev nh1"
2737 run_cmd "ip -n $ns2 -6 address add 2001:db8:202::1/64 dev nh2"
2738 run_cmd "ip -n $ns2 -6 neigh add 2001:db8:201::2 lladdr 00:11:22:33:44:55 nud perm dev nh1"
2739 run_cmd "ip -n $ns2 -6 neigh add 2001:db8:202::2 lladdr 00:aa:bb:cc:dd:ee nud perm dev nh2"
2740 run_cmd "ip -n $ns2 -6 route add 2001:db8:301::/64
2741 nexthop via 2001:db8:201::2 nexthop via 2001:db8:202::2"
2742 run_cmd "ip netns exec $ns2 sysctl -qw net.ipv6.fib_multipath_hash_policy=1"
2743 set +e
2744
2745 local dmac=$(ip -n $ns2 -j link show dev veth2 | jq -r '.[]["address"]')
2746 local tmp_file=$(mktemp)
2747 local cmd="ip netns exec $ns1 mausezahn -6 veth1 -a own -b $dmac
2748 -A 2001:db8:101::1 -B 2001:db8:301::1 -t udp 'sp=12345,dp=0-65535' -q"
2749
2750 # Packets forwarded in a list using a multipath route must not reuse a
2751 # cached result so that a flow always hits the same nexthop. In other
2752 # words, the FIB lookup tracepoint needs to be triggered for every
2753 # packet.
2754 local t0_rx_pkts=$(link_stats_get $ns2 veth2 rx packets)
2755 run_cmd "perf stat -a -e fib6:fib6_table_lookup --filter 'err == 0' -j -o $tmp_file -- $cmd"
2756 local t1_rx_pkts=$(link_stats_get $ns2 veth2 rx packets)
2757 local diff=$(echo $t1_rx_pkts - $t0_rx_pkts | bc -l)
2758 list_rcv_eval $tmp_file $diff
2759
2760 rm $tmp_file
2761 route_cleanup
2762}
2763
2764tc_set_flower_counter__saddr_syn() {
2765 tc_set_flower_counter $1 $2 $3 "src_ip $4 ip_proto tcp tcp_flags 0x2"
2766}
2767
2768ip_mpath_balance_dep_check()
2769{
2770 if [ ! -x "$(command -v socat)" ]; then
2771 echo "socat command not found. Skipping test"
2772 return 1
2773 fi
2774
2775 if [ ! -x "$(command -v jq)" ]; then
2776 echo "jq command not found. Skipping test"
2777 return 1
2778 fi
2779}
2780
2781ip_mpath_balance() {
2782 local -r ipver=$1
2783 local -r daddr=$2
2784 local -r num_conn=20
2785
2786 for i in $(seq 1 $num_conn); do
2787 ip netns exec $ns3 socat $ipver TCP-LISTEN:8000 STDIO >/dev/null &
2788 sleep 0.02
2789 echo -n a | ip netns exec $ns1 socat $ipver STDIO TCP:$daddr:8000
2790 done
2791
2792 local -r syn0="$(tc_get_flower_counter $ns1 veth1)"
2793 local -r syn1="$(tc_get_flower_counter $ns1 veth3)"
2794 local -r syns=$((syn0+syn1))
2795
2796 [ "$VERBOSE" = "1" ] && echo "multipath: syns seen: ($syn0,$syn1)"
2797
2798 [[ $syns -ge $num_conn ]] && [[ $syn0 -gt 0 ]] && [[ $syn1 -gt 0 ]]
2799}
2800
2801ipv4_mpath_balance_test()
2802{
2803 echo
2804 echo "IPv4 multipath load balance test"
2805
2806 ip_mpath_balance_dep_check || return 1
2807 forwarding_setup
2808
2809 $IP route add 172.16.105.1 \
2810 nexthop via 172.16.101.2 \
2811 nexthop via 172.16.103.2
2812
2813 ip netns exec $ns1 \
2814 sysctl -q -w net.ipv4.fib_multipath_hash_policy=1
2815
2816 tc_set_flower_counter__saddr_syn $ns1 4 veth1 172.16.101.1
2817 tc_set_flower_counter__saddr_syn $ns1 4 veth3 172.16.103.1
2818
2819 ip_mpath_balance -4 172.16.105.1
2820
2821 log_test $? 0 "IPv4 multipath loadbalance"
2822
2823 forwarding_cleanup
2824}
2825
2826get_route_dev_src()
2827{
2828 local pfx="$1"
2829 local src="$2"
2830 local out
2831
2832 if out=$($IP -j route get "$pfx" from "$src" | jq -re ".[0].dev"); then
2833 echo "$out"
2834 fi
2835}
2836
2837ipv4_mpath_preferred()
2838{
2839 local src_ip=$1
2840 local pref_dev=$2
2841 local dev routes
2842 local route0=0
2843 local route1=0
2844 local pref_route=0
2845 num_routes=254
2846
2847 for i in $(seq 1 $num_routes) ; do
2848 dev=$(get_route_dev_src 172.16.105.$i $src_ip)
2849 if [ "$dev" = "$pref_dev" ]; then
2850 pref_route=$((pref_route+1))
2851 elif [ "$dev" = "veth1" ]; then
2852 route0=$((route0+1))
2853 elif [ "$dev" = "veth3" ]; then
2854 route1=$((route1+1))
2855 fi
2856 done
2857
2858 routes=$((route0+route1))
2859
2860 [ "$VERBOSE" = "1" ] && echo "multipath: routes seen: ($route0,$route1,$pref_route)"
2861
2862 if [ x"$pref_dev" = x"" ]; then
2863 [[ $routes -ge $num_routes ]] && [[ $route0 -gt 0 ]] && [[ $route1 -gt 0 ]]
2864 else
2865 [[ $pref_route -ge $num_routes ]]
2866 fi
2867
2868}
2869
2870ipv4_mpath_balance_preferred_test()
2871{
2872 echo
2873 echo "IPv4 multipath load balance preferred route"
2874
2875 forwarding_setup
2876
2877 $IP route add 172.16.105.0/24 \
2878 nexthop via 172.16.101.2 \
2879 nexthop via 172.16.103.2
2880
2881 ipv4_mpath_preferred 172.16.101.1 veth1
2882 log_test $? 0 "IPv4 multipath loadbalance from veth1"
2883
2884 ipv4_mpath_preferred 172.16.103.1 veth3
2885 log_test $? 0 "IPv4 multipath loadbalance from veth3"
2886
2887 ipv4_mpath_preferred 198.51.100.1
2888 log_test $? 0 "IPv4 multipath loadbalance from dummy"
2889
2890 forwarding_cleanup
2891}
2892
2893ipv6_mpath_balance_test()
2894{
2895 echo
2896 echo "IPv6 multipath load balance test"
2897
2898 ip_mpath_balance_dep_check || return 1
2899 forwarding_setup
2900
2901 $IP route add 2001:db8:105::1\
2902 nexthop via 2001:db8:101::2 \
2903 nexthop via 2001:db8:103::2
2904
2905 ip netns exec $ns1 \
2906 sysctl -q -w net.ipv6.fib_multipath_hash_policy=1
2907
2908 tc_set_flower_counter__saddr_syn $ns1 6 veth1 2001:db8:101::1
2909 tc_set_flower_counter__saddr_syn $ns1 6 veth3 2001:db8:103::1
2910
2911 ip_mpath_balance -6 "[2001:db8:105::1]"
2912
2913 log_test $? 0 "IPv6 multipath loadbalance"
2914
2915 forwarding_cleanup
2916}
2917
2918################################################################################
2919# usage
2920
2921usage()
2922{
2923 cat <<EOF
2924usage: ${0##*/} OPTS
2925
2926 -t <test> Test(s) to run (default: all)
2927 (options: $TESTS)
2928 -p Pause on fail
2929 -P Pause after each test before cleanup
2930 -v verbose mode (show commands and output)
2931EOF
2932}
2933
2934################################################################################
2935# main
2936
2937trap cleanup EXIT
2938
2939while getopts :t:pPhv o
2940do
2941 case $o in
2942 t) TESTS=$OPTARG;;
2943 p) PAUSE_ON_FAIL=yes;;
2944 P) PAUSE=yes;;
2945 v) VERBOSE=$(($VERBOSE + 1));;
2946 h) usage; exit 0;;
2947 *) usage; exit 1;;
2948 esac
2949done
2950
2951PEER_CMD="ip netns exec ${PEER_NS}"
2952
2953# make sure we don't pause twice
2954[ "${PAUSE}" = "yes" ] && PAUSE_ON_FAIL=no
2955
2956if [ "$(id -u)" -ne 0 ];then
2957 echo "SKIP: Need root privileges"
2958 exit $ksft_skip;
2959fi
2960
2961if [ ! -x "$(command -v ip)" ]; then
2962 echo "SKIP: Could not run test without ip tool"
2963 exit $ksft_skip
2964fi
2965
2966ip route help 2>&1 | grep -q fibmatch
2967if [ $? -ne 0 ]; then
2968 echo "SKIP: iproute2 too old, missing fibmatch"
2969 exit $ksft_skip
2970fi
2971
2972# start clean
2973cleanup &> /dev/null
2974
2975for t in $TESTS
2976do
2977 case $t in
2978 fib_unreg_test|unregister) fib_unreg_test;;
2979 fib_down_test|down) fib_down_test;;
2980 fib_carrier_test|carrier) fib_carrier_test;;
2981 fib_rp_filter_test|rp_filter) fib_rp_filter_test;;
2982 fib_nexthop_test|nexthop) fib_nexthop_test;;
2983 fib_notify_test|ipv4_notify) fib_notify_test;;
2984 fib6_notify_test|ipv6_notify) fib6_notify_test;;
2985 fib_suppress_test|suppress) fib_suppress_test;;
2986 ipv6_route_test|ipv6_rt) ipv6_route_test;;
2987 ipv4_route_test|ipv4_rt) ipv4_route_test;;
2988 ipv6_addr_metric) ipv6_addr_metric_test;;
2989 ipv4_addr_metric) ipv4_addr_metric_test;;
2990 ipv4_del_addr) ipv4_del_addr_test;;
2991 ipv6_del_addr) ipv6_del_addr_test;;
2992 ipv6_route_metrics) ipv6_route_metrics_test;;
2993 ipv4_route_metrics) ipv4_route_metrics_test;;
2994 ipv4_route_v6_gw) ipv4_route_v6_gw_test;;
2995 ipv4_mangle) ipv4_mangle_test;;
2996 ipv6_mangle) ipv6_mangle_test;;
2997 ipv4_bcast_neigh) ipv4_bcast_neigh_test;;
2998 fib6_gc_test|ipv6_gc) fib6_gc_test;;
2999 ipv4_mpath_list) ipv4_mpath_list_test;;
3000 ipv6_mpath_list) ipv6_mpath_list_test;;
3001 ipv4_mpath_balance) ipv4_mpath_balance_test;;
3002 ipv6_mpath_balance) ipv6_mpath_balance_test;;
3003 ipv4_mpath_balance_preferred) ipv4_mpath_balance_preferred_test;;
3004 fib6_ra_to_static) fib6_ra_to_static;;
3005
3006 help) echo "Test names: $TESTS"; exit 0;;
3007 esac
3008done
3009
3010if [ "$TESTS" != "none" ]; then
3011 printf "\nTests passed: %3d\n" ${nsuccess}
3012 printf "Tests failed: %3d\n" ${nfail}
3013fi
3014
3015exit $ret