2 # SPDX-License-Identifier: GPL-2.0
4 # This test is for checking IPv4 and IPv6 FIB behavior in response to
8 # Kselftest framework requirement - SKIP code is 4.
11 # all tests in this script. Can be overridden with -t option
12 TESTS="unregister down carrier nexthop suppress ipv6_notify ipv4_notify \
13 ipv6_rt ipv4_rt ipv6_addr_metric ipv4_addr_metric ipv6_route_metrics \
14 ipv4_route_metrics ipv4_route_v6_gw rp_filter ipv4_del_addr \
15 ipv6_del_addr ipv4_mangle ipv6_mangle ipv4_bcast_neigh fib6_gc_test"
20 IP="$(which ip) -netns ns1"
21 NS_EXEC="$(which ip) netns exec ns1"
23 which ping6 > /dev/null 2>&1 && ping6=$(which ping6) || ping6=$(which ping)
31 if [ ${rc} -eq ${expected} ]; then
32 printf " TEST: %-60s [ OK ]\n" "${msg}"
33 nsuccess=$((nsuccess+1))
37 printf " TEST: %-60s [FAIL]\n" "${msg}"
38 if [ "${PAUSE_ON_FAIL}" = "yes" ]; then
40 echo "hit enter to continue, 'q' to quit"
42 [ "$a" = "q" ] && exit 1
46 if [ "${PAUSE}" = "yes" ]; then
48 echo "hit enter to continue, 'q' to quit"
50 [ "$a" = "q" ] && exit 1
59 $IP link set dev lo up
60 ip netns exec ns1 sysctl -qw net.ipv4.ip_forward=1
61 ip netns exec ns1 sysctl -qw net.ipv6.conf.all.forwarding=1
63 $IP link add dummy0 type dummy
64 $IP link set dev dummy0 up
65 $IP address add 198.51.100.1/24 dev dummy0
66 $IP -6 address add 2001:db8:1::1/64 dev dummy0
73 $IP link del dev dummy0 &> /dev/null
74 ip netns del ns1 &> /dev/null
75 ip netns del ns2 &> /dev/null
83 addr=$($IP -6 -br addr show dev ${dev} | \
85 for (i = 3; i <= NF; ++i) {
93 [ -z "$addr" ] && return 1
100 fib_unreg_unicast_test()
103 echo "Single path route test"
108 $IP route get fibmatch 198.51.100.2 &> /dev/null
109 log_test $? 0 "IPv4 fibmatch"
110 $IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null
111 log_test $? 0 "IPv6 fibmatch"
114 $IP link del dev dummy0
117 echo " Nexthop device deleted"
118 $IP route get fibmatch 198.51.100.2 &> /dev/null
119 log_test $? 2 "IPv4 fibmatch - no route"
120 $IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null
121 log_test $? 2 "IPv6 fibmatch - no route"
126 fib_unreg_multipath_test()
130 echo "Multipath route test"
135 $IP link add dummy1 type dummy
136 $IP link set dev dummy1 up
137 $IP address add 192.0.2.1/24 dev dummy1
138 $IP -6 address add 2001:db8:2::1/64 dev dummy1
140 $IP route add 203.0.113.0/24 \
141 nexthop via 198.51.100.2 dev dummy0 \
142 nexthop via 192.0.2.2 dev dummy1
143 $IP -6 route add 2001:db8:3::/64 \
144 nexthop via 2001:db8:1::2 dev dummy0 \
145 nexthop via 2001:db8:2::2 dev dummy1
149 $IP route get fibmatch 203.0.113.1 &> /dev/null
150 log_test $? 0 "IPv4 fibmatch"
151 $IP -6 route get fibmatch 2001:db8:3::1 &> /dev/null
152 log_test $? 0 "IPv6 fibmatch"
155 $IP link del dev dummy0
158 echo " One nexthop device deleted"
159 $IP route get fibmatch 203.0.113.1 &> /dev/null
160 log_test $? 2 "IPv4 - multipath route removed on delete"
162 $IP -6 route get fibmatch 2001:db8:3::1 &> /dev/null
163 # In IPv6 we do not flush the entire multipath route.
164 log_test $? 0 "IPv6 - multipath down to single path"
167 $IP link del dev dummy1
170 echo " Second nexthop device deleted"
171 $IP -6 route get fibmatch 2001:db8:3::1 &> /dev/null
172 log_test $? 2 "IPv6 - no route"
179 fib_unreg_unicast_test
180 fib_unreg_multipath_test
183 fib_down_unicast_test()
186 echo "Single path, admin down"
191 $IP route get fibmatch 198.51.100.2 &> /dev/null
192 log_test $? 0 "IPv4 fibmatch"
193 $IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null
194 log_test $? 0 "IPv6 fibmatch"
197 $IP link set dev dummy0 down
200 echo " Route deleted on down"
201 $IP route get fibmatch 198.51.100.2 &> /dev/null
202 log_test $? 2 "IPv4 fibmatch"
203 $IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null
204 log_test $? 2 "IPv6 fibmatch"
209 fib_down_multipath_test_do()
214 $IP route get fibmatch 203.0.113.1 \
215 oif $down_dev &> /dev/null
216 log_test $? 2 "IPv4 fibmatch on down device"
217 $IP -6 route get fibmatch 2001:db8:3::1 \
218 oif $down_dev &> /dev/null
219 log_test $? 2 "IPv6 fibmatch on down device"
221 $IP route get fibmatch 203.0.113.1 \
222 oif $up_dev &> /dev/null
223 log_test $? 0 "IPv4 fibmatch on up device"
224 $IP -6 route get fibmatch 2001:db8:3::1 \
225 oif $up_dev &> /dev/null
226 log_test $? 0 "IPv6 fibmatch on up device"
228 $IP route get fibmatch 203.0.113.1 | \
229 grep $down_dev | grep -q "dead linkdown"
230 log_test $? 0 "IPv4 flags on down device"
231 $IP -6 route get fibmatch 2001:db8:3::1 | \
232 grep $down_dev | grep -q "dead linkdown"
233 log_test $? 0 "IPv6 flags on down device"
235 $IP route get fibmatch 203.0.113.1 | \
236 grep $up_dev | grep -q "dead linkdown"
237 log_test $? 1 "IPv4 flags on up device"
238 $IP -6 route get fibmatch 2001:db8:3::1 | \
239 grep $up_dev | grep -q "dead linkdown"
240 log_test $? 1 "IPv6 flags on up device"
243 fib_down_multipath_test()
246 echo "Admin down multipath"
251 $IP link add dummy1 type dummy
252 $IP link set dev dummy1 up
254 $IP address add 192.0.2.1/24 dev dummy1
255 $IP -6 address add 2001:db8:2::1/64 dev dummy1
257 $IP route add 203.0.113.0/24 \
258 nexthop via 198.51.100.2 dev dummy0 \
259 nexthop via 192.0.2.2 dev dummy1
260 $IP -6 route add 2001:db8:3::/64 \
261 nexthop via 2001:db8:1::2 dev dummy0 \
262 nexthop via 2001:db8:2::2 dev dummy1
265 echo " Verify start point"
266 $IP route get fibmatch 203.0.113.1 &> /dev/null
267 log_test $? 0 "IPv4 fibmatch"
269 $IP -6 route get fibmatch 2001:db8:3::1 &> /dev/null
270 log_test $? 0 "IPv6 fibmatch"
273 $IP link set dev dummy0 down
276 echo " One device down, one up"
277 fib_down_multipath_test_do "dummy0" "dummy1"
280 $IP link set dev dummy0 up
281 $IP link set dev dummy1 down
284 echo " Other device down and up"
285 fib_down_multipath_test_do "dummy1" "dummy0"
288 $IP link set dev dummy0 down
291 echo " Both devices down"
292 $IP route get fibmatch 203.0.113.1 &> /dev/null
293 log_test $? 2 "IPv4 fibmatch"
294 $IP -6 route get fibmatch 2001:db8:3::1 &> /dev/null
295 log_test $? 2 "IPv6 fibmatch"
297 $IP link del dev dummy1
303 fib_down_unicast_test
304 fib_down_multipath_test
307 # Local routes should not be affected when carrier changes.
308 fib_carrier_local_test()
311 echo "Local carrier tests - single path"
316 $IP link set dev dummy0 carrier on
320 $IP route get fibmatch 198.51.100.1 &> /dev/null
321 log_test $? 0 "IPv4 fibmatch"
322 $IP -6 route get fibmatch 2001:db8:1::1 &> /dev/null
323 log_test $? 0 "IPv6 fibmatch"
325 $IP route get fibmatch 198.51.100.1 | \
327 log_test $? 1 "IPv4 - no linkdown flag"
328 $IP -6 route get fibmatch 2001:db8:1::1 | \
330 log_test $? 1 "IPv6 - no linkdown flag"
333 $IP link set dev dummy0 carrier off
337 echo " Carrier off on nexthop"
338 $IP route get fibmatch 198.51.100.1 &> /dev/null
339 log_test $? 0 "IPv4 fibmatch"
340 $IP -6 route get fibmatch 2001:db8:1::1 &> /dev/null
341 log_test $? 0 "IPv6 fibmatch"
343 $IP route get fibmatch 198.51.100.1 | \
345 log_test $? 1 "IPv4 - linkdown flag set"
346 $IP -6 route get fibmatch 2001:db8:1::1 | \
348 log_test $? 1 "IPv6 - linkdown flag set"
351 $IP address add 192.0.2.1/24 dev dummy0
352 $IP -6 address add 2001:db8:2::1/64 dev dummy0
355 echo " Route to local address with carrier down"
356 $IP route get fibmatch 192.0.2.1 &> /dev/null
357 log_test $? 0 "IPv4 fibmatch"
358 $IP -6 route get fibmatch 2001:db8:2::1 &> /dev/null
359 log_test $? 0 "IPv6 fibmatch"
361 $IP route get fibmatch 192.0.2.1 | \
363 log_test $? 1 "IPv4 linkdown flag set"
364 $IP -6 route get fibmatch 2001:db8:2::1 | \
366 log_test $? 1 "IPv6 linkdown flag set"
371 fib_carrier_unicast_test()
376 echo "Single path route carrier test"
381 $IP link set dev dummy0 carrier on
385 $IP route get fibmatch 198.51.100.2 &> /dev/null
386 log_test $? 0 "IPv4 fibmatch"
387 $IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null
388 log_test $? 0 "IPv6 fibmatch"
390 $IP route get fibmatch 198.51.100.2 | \
392 log_test $? 1 "IPv4 no linkdown flag"
393 $IP -6 route get fibmatch 2001:db8:1::2 | \
395 log_test $? 1 "IPv6 no linkdown flag"
398 $IP link set dev dummy0 carrier off
403 $IP route get fibmatch 198.51.100.2 &> /dev/null
404 log_test $? 0 "IPv4 fibmatch"
405 $IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null
406 log_test $? 0 "IPv6 fibmatch"
408 $IP route get fibmatch 198.51.100.2 | \
410 log_test $? 0 "IPv4 linkdown flag set"
411 $IP -6 route get fibmatch 2001:db8:1::2 | \
413 log_test $? 0 "IPv6 linkdown flag set"
416 $IP address add 192.0.2.1/24 dev dummy0
417 $IP -6 address add 2001:db8:2::1/64 dev dummy0
420 echo " Second address added with carrier down"
421 $IP route get fibmatch 192.0.2.2 &> /dev/null
422 log_test $? 0 "IPv4 fibmatch"
423 $IP -6 route get fibmatch 2001:db8:2::2 &> /dev/null
424 log_test $? 0 "IPv6 fibmatch"
426 $IP route get fibmatch 192.0.2.2 | \
428 log_test $? 0 "IPv4 linkdown flag set"
429 $IP -6 route get fibmatch 2001:db8:2::2 | \
431 log_test $? 0 "IPv6 linkdown flag set"
438 fib_carrier_local_test
439 fib_carrier_unicast_test
445 echo "IPv4 rp_filter tests"
451 ip netns set ns2 auto
453 ip -netns ns2 link set dev lo up
455 $IP link add name veth1 type veth peer name veth2
456 $IP link set dev veth2 netns ns2
457 $IP address add 192.0.2.1/24 dev veth1
458 ip -netns ns2 address add 192.0.2.1/24 dev veth2
459 $IP link set dev veth1 up
460 ip -netns ns2 link set dev veth2 up
462 $IP link set dev lo address 52:54:00:6a:c7:5e
463 $IP link set dev veth1 address 52:54:00:6a:c7:5e
464 ip -netns ns2 link set dev lo address 52:54:00:6a:c7:5e
465 ip -netns ns2 link set dev veth2 address 52:54:00:6a:c7:5e
467 # 1. (ns2) redirect lo's egress to veth2's egress
468 ip netns exec ns2 tc qdisc add dev lo parent root handle 1: fq_codel
469 ip netns exec ns2 tc filter add dev lo parent 1: protocol arp basic \
470 action mirred egress redirect dev veth2
471 ip netns exec ns2 tc filter add dev lo parent 1: protocol ip basic \
472 action mirred egress redirect dev veth2
474 # 2. (ns1) redirect veth1's ingress to lo's ingress
475 $NS_EXEC tc qdisc add dev veth1 ingress
476 $NS_EXEC tc filter add dev veth1 ingress protocol arp basic \
477 action mirred ingress redirect dev lo
478 $NS_EXEC tc filter add dev veth1 ingress protocol ip basic \
479 action mirred ingress redirect dev lo
481 # 3. (ns1) redirect lo's egress to veth1's egress
482 $NS_EXEC tc qdisc add dev lo parent root handle 1: fq_codel
483 $NS_EXEC tc filter add dev lo parent 1: protocol arp basic \
484 action mirred egress redirect dev veth1
485 $NS_EXEC tc filter add dev lo parent 1: protocol ip basic \
486 action mirred egress redirect dev veth1
488 # 4. (ns2) redirect veth2's ingress to lo's ingress
489 ip netns exec ns2 tc qdisc add dev veth2 ingress
490 ip netns exec ns2 tc filter add dev veth2 ingress protocol arp basic \
491 action mirred ingress redirect dev lo
492 ip netns exec ns2 tc filter add dev veth2 ingress protocol ip basic \
493 action mirred ingress redirect dev lo
495 $NS_EXEC sysctl -qw net.ipv4.conf.all.rp_filter=1
496 $NS_EXEC sysctl -qw net.ipv4.conf.all.accept_local=1
497 $NS_EXEC sysctl -qw net.ipv4.conf.all.route_localnet=1
498 ip netns exec ns2 sysctl -qw net.ipv4.conf.all.rp_filter=1
499 ip netns exec ns2 sysctl -qw net.ipv4.conf.all.accept_local=1
500 ip netns exec ns2 sysctl -qw net.ipv4.conf.all.route_localnet=1
503 run_cmd "ip netns exec ns2 ping -w1 -c1 192.0.2.1"
504 log_test $? 0 "rp_filter passes local packets"
506 run_cmd "ip netns exec ns2 ping -w1 -c1 127.0.0.1"
507 log_test $? 0 "rp_filter passes loopback packets"
512 ################################################################################
513 # Tests on nexthop spec
515 # run 'ip route add' with given spec
526 [ "$vrf" = "-" ] && vrf="default"
527 [ -n "$gw" ] && gw="via $gw"
528 [ -n "$dev" ] && dev="dev $dev"
530 cmd="$IP route add vrf $vrf $pfx $gw $dev"
531 if [ "$VERBOSE" = "1" ]; then
532 printf "\n COMMAND: $cmd\n"
535 out=$(eval $cmd 2>&1)
537 if [ "$VERBOSE" = "1" -a -n "$out" ]; then
540 log_test $rc $erc "$desc"
546 echo "IPv4 nexthop tests"
548 echo "<<< write me >>>"
553 local lldummy=$(get_linklocal dummy0)
554 local llv1=$(get_linklocal dummy0)
556 if [ -z "$lldummy" ]; then
557 echo "Failed to get linklocal address for dummy0"
560 if [ -z "$llv1" ]; then
561 echo "Failed to get linklocal address for veth1"
566 echo "IPv6 nexthop tests"
568 add_rt "Directly connected nexthop, unicast address" 0 \
569 - 2001:db8:101::/64 2001:db8:1::2
570 add_rt "Directly connected nexthop, unicast address with device" 0 \
571 - 2001:db8:102::/64 2001:db8:1::2 "dummy0"
572 add_rt "Gateway is linklocal address" 0 \
573 - 2001:db8:103::1/64 $llv1 "veth0"
575 # fails because LL address requires a device
576 add_rt "Gateway is linklocal address, no device" 2 \
577 - 2001:db8:104::1/64 $llv1
579 # local address can not be a gateway
580 add_rt "Gateway can not be local unicast address" 2 \
581 - 2001:db8:105::/64 2001:db8:1::1
582 add_rt "Gateway can not be local unicast address, with device" 2 \
583 - 2001:db8:106::/64 2001:db8:1::1 "dummy0"
584 add_rt "Gateway can not be a local linklocal address" 2 \
585 - 2001:db8:107::1/64 $lldummy "dummy0"
588 add_rt "Gateway can be local address in a VRF" 0 \
589 - 2001:db8:108::/64 2001:db8:51::2
590 add_rt "Gateway can be local address in a VRF, with device" 0 \
591 - 2001:db8:109::/64 2001:db8:51::2 "veth0"
592 add_rt "Gateway can be local linklocal address in a VRF" 0 \
593 - 2001:db8:110::1/64 $llv1 "veth0"
595 add_rt "Redirect to VRF lookup" 0 \
596 - 2001:db8:111::/64 "" "red"
598 add_rt "VRF route, gateway can be local address in default VRF" 0 \
599 red 2001:db8:112::/64 2001:db8:51::1
601 # local address in same VRF fails
602 add_rt "VRF route, gateway can not be a local address" 2 \
603 red 2001:db8:113::1/64 2001:db8:2::1
604 add_rt "VRF route, gateway can not be a local addr with device" 2 \
605 red 2001:db8:114::1/64 2001:db8:2::1 "dummy1"
609 # dummy0 - 198.51.100.1/24 2001:db8:1::1/64
610 # veth0 - 192.0.2.1/24 2001:db8:51::1/64
613 # dummy1 - 192.168.2.1/24 2001:db8:2::1/64
614 # veth1 - 192.0.2.2/24 2001:db8:51::2/64
616 # [ dummy0 veth0 ]--[ veth1 dummy1 ]
624 $IP -4 rule add pref 32765 table local
625 $IP -4 rule del pref 0
626 $IP -6 rule add pref 32765 table local
627 $IP -6 rule del pref 0
629 $IP link add red type vrf table 1
631 $IP -4 route add vrf red unreachable default metric 4278198272
632 $IP -6 route add vrf red unreachable default metric 4278198272
634 $IP link add veth0 type veth peer name veth1
635 $IP link set dev veth0 up
636 $IP address add 192.0.2.1/24 dev veth0
637 $IP -6 address add 2001:db8:51::1/64 dev veth0
639 $IP link set dev veth1 vrf red up
640 $IP address add 192.0.2.2/24 dev veth1
641 $IP -6 address add 2001:db8:51::2/64 dev veth1
643 $IP link add dummy1 type dummy
644 $IP link set dev dummy1 vrf red up
645 $IP address add 192.168.2.1/24 dev dummy1
646 $IP -6 address add 2001:db8:2::1/64 dev dummy1
654 $IP link del dev dummy1
666 echo "Fib6 info length calculation in route notify test"
669 for i in 10 20 30 40 50 60 70;
671 $IP link add dummy_$i type dummy
672 $IP link set dev dummy_$i up
673 $IP -6 address add 2001:$i::1/64 dev dummy_$i
676 $NS_EXEC ip monitor route &> errors.txt &
679 $IP -6 route add 2001::/64 \
680 nexthop via 2001:10::2 dev dummy_10 \
681 nexthop encap ip6 dst 2002::20 via 2001:20::2 dev dummy_20 \
682 nexthop encap ip6 dst 2002::30 via 2001:30::2 dev dummy_30 \
683 nexthop encap ip6 dst 2002::40 via 2001:40::2 dev dummy_40 \
684 nexthop encap ip6 dst 2002::50 via 2001:50::2 dev dummy_50 \
685 nexthop encap ip6 dst 2002::60 via 2001:60::2 dev dummy_60 \
686 nexthop encap ip6 dst 2002::70 via 2001:70::2 dev dummy_70
690 err=`cat errors.txt |grep "Message too long"`
691 if [ -z "$err" ];then
697 log_test $ret 0 "ipv6 route add notify"
699 { kill %% && wait %%; } 2>/dev/null
712 echo "Fib4 info length calculation in route notify test"
716 for i in 10 20 30 40 50 60 70;
718 $IP link add dummy_$i type dummy
719 $IP link set dev dummy_$i up
720 $IP address add 20.20.$i.2/24 dev dummy_$i
723 $NS_EXEC ip monitor route &> errors.txt &
726 $IP route add 10.0.0.0/24 \
727 nexthop via 20.20.10.1 dev dummy_10 \
728 nexthop encap ip dst 192.168.10.20 via 20.20.20.1 dev dummy_20 \
729 nexthop encap ip dst 192.168.10.30 via 20.20.30.1 dev dummy_30 \
730 nexthop encap ip dst 192.168.10.40 via 20.20.40.1 dev dummy_40 \
731 nexthop encap ip dst 192.168.10.50 via 20.20.50.1 dev dummy_50 \
732 nexthop encap ip dst 192.168.10.60 via 20.20.60.1 dev dummy_60 \
733 nexthop encap ip dst 192.168.10.70 via 20.20.70.1 dev dummy_70
737 err=`cat errors.txt |grep "Message too long"`
738 if [ -z "$err" ];then
744 log_test $ret 0 "ipv4 route add notify"
746 { kill %% && wait %%; } 2>/dev/null
758 echo "Fib6 garbage collection test"
763 # Check expiration of routes every $EXPIRE seconds (GC)
764 $NS_EXEC sysctl -wq net.ipv6.route.gc_interval=$EXPIRE
766 $IP link add dummy_10 type dummy
767 $IP link set dev dummy_10 up
768 $IP -6 address add 2001:10::1/64 dev dummy_10
770 $NS_EXEC sysctl -wq net.ipv6.route.flush=1
773 for i in $(seq 1 1000); do
774 # Expire route after $EXPIRE seconds
775 $IP -6 route add 2001:20::$i \
776 via 2001:10::2 dev dummy_10 expires $EXPIRE
778 sleep $(($EXPIRE * 2))
779 N_EXP_SLEEP=$($IP -6 route list |grep expires|wc -l)
780 if [ $N_EXP_SLEEP -ne 0 ]; then
781 echo "FAIL: expected 0 routes with expires, got $N_EXP_SLEEP"
788 for i in $(seq 1 5000); do
789 $IP -6 route add 2001:30::$i \
790 via 2001:10::2 dev dummy_10
793 for i in $(seq 1 1000); do
794 # Expire route after $EXPIRE seconds
795 $IP -6 route add 2001:20::$i \
796 via 2001:10::2 dev dummy_10 expires $EXPIRE
798 sleep $(($EXPIRE * 2))
799 N_EXP_SLEEP=$($IP -6 route list |grep expires|wc -l)
800 if [ $N_EXP_SLEEP -ne 0 ]; then
801 echo "FAIL: expected 0 routes with expires," \
802 "got $N_EXP_SLEEP (5000 permanent routes)"
810 log_test $ret 0 "ipv6 route garbage collection"
818 echo "FIB rule with suppress_prefixlength"
821 $IP link add dummy1 type dummy
822 $IP link set dummy1 up
823 $IP -6 route add default dev dummy1
824 $IP -6 rule add table main suppress_prefixlength 0
825 ping -f -c 1000 -W 1 1234::1 >/dev/null 2>&1
826 $IP -6 rule del table main suppress_prefixlength 0
829 # If we got here without crashing, we're good.
830 log_test 0 0 "FIB rule suppress test"
835 ################################################################################
836 # Tests on route add and replace
842 local stderr="2>/dev/null"
844 if [ "$VERBOSE" = "1" ]; then
845 printf " COMMAND: $cmd\n"
849 out=$(eval $cmd $stderr)
851 if [ "$VERBOSE" = "1" -a -n "$out" ]; then
855 [ "$VERBOSE" = "1" ] && echo
866 [ "${out}" = "${expected}" ] && return 0
868 if [ -z "${out}" ]; then
869 if [ "$VERBOSE" = "1" ]; then
870 printf "\nNo route entry found\n"
872 printf " ${expected}\n"
877 # tricky way to convert output to 1-line without ip's
878 # messy '\'; this drops all extra white space
880 if [ "${out}" != "${expected}" ]; then
882 if [ "${VERBOSE}" = "1" ]; then
883 printf " Unexpected route entry. Have:\n"
885 printf " Expected:\n"
886 printf " ${expected}\n\n"
893 # add route for a prefix, flushing any existing routes first
894 # expected to be the first step of a test
901 if [ "$VERBOSE" = "1" ]; then
903 echo " ##################################################"
907 run_cmd "$IP -6 ro flush ${pfx}"
908 [ $? -ne 0 ] && exit 1
910 out=$($IP -6 ro ls match ${pfx})
911 if [ -n "$out" ]; then
912 echo "Failed to flush routes for prefix used for tests."
916 run_cmd "$IP -6 ro add ${pfx} ${nh}"
917 if [ $? -ne 0 ]; then
918 echo "Failed to add initial route for test."
923 # add initial route - used in replace route tests
926 add_route6 "2001:db8:104::/64" "$1"
939 out=$($IP -6 ro ls match ${pfx} | sed -e 's/ pref medium//')
940 check_expected "${out}" "${expected}"
945 $IP li del red 2>/dev/null
946 $IP li del dummy1 2>/dev/null
947 $IP li del veth1 2>/dev/null
948 $IP li del veth3 2>/dev/null
958 [ "${VERBOSE}" = "1" ] && set -x
962 ip netns set ns2 auto
963 ip -netns ns2 link set dev lo up
964 ip netns exec ns2 sysctl -qw net.ipv4.ip_forward=1
965 ip netns exec ns2 sysctl -qw net.ipv6.conf.all.forwarding=1
967 $IP li add veth1 type veth peer name veth2
968 $IP li add veth3 type veth peer name veth4
972 $IP li set veth2 netns ns2 up
973 $IP li set veth4 netns ns2 up
974 ip -netns ns2 li add dummy1 type dummy
975 ip -netns ns2 li set dummy1 up
977 $IP -6 addr add 2001:db8:101::1/64 dev veth1 nodad
978 $IP -6 addr add 2001:db8:103::1/64 dev veth3 nodad
979 $IP addr add 172.16.101.1/24 dev veth1
980 $IP addr add 172.16.103.1/24 dev veth3
982 ip -netns ns2 -6 addr add 2001:db8:101::2/64 dev veth2 nodad
983 ip -netns ns2 -6 addr add 2001:db8:103::2/64 dev veth4 nodad
984 ip -netns ns2 -6 addr add 2001:db8:104::1/64 dev dummy1 nodad
986 ip -netns ns2 addr add 172.16.101.2/24 dev veth2
987 ip -netns ns2 addr add 172.16.103.2/24 dev veth4
988 ip -netns ns2 addr add 172.16.104.1/24 dev dummy1
993 # assumption is that basic add of a single path route works
994 # otherwise just adding an address on an interface is broken
1000 echo "IPv6 route add / append tests"
1002 # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL
1003 add_route6 "2001:db8:104::/64" "via 2001:db8:101::2"
1004 run_cmd "$IP -6 ro add 2001:db8:104::/64 via 2001:db8:103::2"
1005 log_test $? 2 "Attempt to add duplicate route - gw"
1007 # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL
1008 add_route6 "2001:db8:104::/64" "via 2001:db8:101::2"
1009 run_cmd "$IP -6 ro add 2001:db8:104::/64 dev veth3"
1010 log_test $? 2 "Attempt to add duplicate route - dev only"
1012 # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL
1013 add_route6 "2001:db8:104::/64" "via 2001:db8:101::2"
1014 run_cmd "$IP -6 ro add unreachable 2001:db8:104::/64"
1015 log_test $? 2 "Attempt to add duplicate route - reject route"
1017 # route append with same prefix adds a new route
1018 # - iproute2 sets NLM_F_CREATE | NLM_F_APPEND
1019 add_route6 "2001:db8:104::/64" "via 2001:db8:101::2"
1020 run_cmd "$IP -6 ro append 2001:db8:104::/64 via 2001:db8:103::2"
1021 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"
1022 log_test $? 0 "Append nexthop to existing route - gw"
1024 # insert mpath directly
1025 add_route6 "2001:db8:104::/64" "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"
1026 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"
1027 log_test $? 0 "Add multipath route"
1029 add_route6 "2001:db8:104::/64" "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"
1030 run_cmd "$IP -6 ro add 2001:db8:104::/64 nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"
1031 log_test $? 2 "Attempt to add duplicate multipath route"
1033 # insert of a second route without append but different metric
1034 add_route6 "2001:db8:104::/64" "via 2001:db8:101::2"
1035 run_cmd "$IP -6 ro add 2001:db8:104::/64 via 2001:db8:103::2 metric 512"
1037 if [ $rc -eq 0 ]; then
1038 run_cmd "$IP -6 ro add 2001:db8:104::/64 via 2001:db8:103::3 metric 256"
1041 log_test $rc 0 "Route add with different metrics"
1043 run_cmd "$IP -6 ro del 2001:db8:104::/64 metric 512"
1045 if [ $rc -eq 0 ]; then
1046 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"
1049 log_test $rc 0 "Route delete with metric"
1052 ipv6_rt_replace_single()
1054 # single path with single path
1056 add_initial_route6 "via 2001:db8:101::2"
1057 run_cmd "$IP -6 ro replace 2001:db8:104::/64 via 2001:db8:103::2"
1058 check_route6 "2001:db8:104::/64 via 2001:db8:103::2 dev veth3 metric 1024"
1059 log_test $? 0 "Single path with single path"
1061 # single path with multipath
1063 add_initial_route6 "nexthop via 2001:db8:101::2"
1064 run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:101::3 nexthop via 2001:db8:103::2"
1065 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"
1066 log_test $? 0 "Single path with multipath"
1068 # single path with single path using MULTIPATH attribute
1070 add_initial_route6 "via 2001:db8:101::2"
1071 run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:103::2"
1072 check_route6 "2001:db8:104::/64 via 2001:db8:103::2 dev veth3 metric 1024"
1073 log_test $? 0 "Single path with single path via multipath attribute"
1075 # route replace fails - invalid nexthop
1076 add_initial_route6 "via 2001:db8:101::2"
1077 run_cmd "$IP -6 ro replace 2001:db8:104::/64 via 2001:db8:104::2"
1078 if [ $? -eq 0 ]; then
1079 # previous command is expected to fail so if it returns 0
1080 # that means the test failed.
1081 log_test 0 1 "Invalid nexthop"
1083 check_route6 "2001:db8:104::/64 via 2001:db8:101::2 dev veth1 metric 1024"
1084 log_test $? 0 "Invalid nexthop"
1087 # replace non-existent route
1088 # - note use of change versus replace since ip adds NLM_F_CREATE
1090 add_initial_route6 "via 2001:db8:101::2"
1091 run_cmd "$IP -6 ro change 2001:db8:105::/64 via 2001:db8:101::2"
1092 log_test $? 2 "Single path - replace of non-existent route"
1095 ipv6_rt_replace_mpath()
1097 # multipath with multipath
1098 add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"
1099 run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:101::3 nexthop via 2001:db8:103::3"
1100 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"
1101 log_test $? 0 "Multipath with multipath"
1103 # multipath with single
1104 add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"
1105 run_cmd "$IP -6 ro replace 2001:db8:104::/64 via 2001:db8:101::3"
1106 check_route6 "2001:db8:104::/64 via 2001:db8:101::3 dev veth1 metric 1024"
1107 log_test $? 0 "Multipath with single path"
1109 # multipath with single
1110 add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"
1111 run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:101::3"
1112 check_route6 "2001:db8:104::/64 via 2001:db8:101::3 dev veth1 metric 1024"
1113 log_test $? 0 "Multipath with single path via multipath attribute"
1115 # multipath with dev-only
1116 add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"
1117 run_cmd "$IP -6 ro replace 2001:db8:104::/64 dev veth1"
1118 check_route6 "2001:db8:104::/64 dev veth1 metric 1024"
1119 log_test $? 0 "Multipath with dev-only"
1121 # route replace fails - invalid nexthop 1
1122 add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"
1123 run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:111::3 nexthop via 2001:db8:103::3"
1124 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"
1125 log_test $? 0 "Multipath - invalid first nexthop"
1127 # route replace fails - invalid nexthop 2
1128 add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"
1129 run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:101::3 nexthop via 2001:db8:113::3"
1130 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"
1131 log_test $? 0 "Multipath - invalid second nexthop"
1133 # multipath non-existent route
1134 add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"
1135 run_cmd "$IP -6 ro change 2001:db8:105::/64 nexthop via 2001:db8:101::3 nexthop via 2001:db8:103::3"
1136 log_test $? 2 "Multipath - replace of non-existent route"
1142 echo "IPv6 route replace tests"
1144 ipv6_rt_replace_single
1145 ipv6_rt_replace_mpath
1151 echo "IPv6 route with dsfield tests"
1153 run_cmd "$IP -6 route flush 2001:db8:102::/64"
1155 # IPv6 doesn't support routing based on dsfield
1156 run_cmd "$IP -6 route add 2001:db8:102::/64 dsfield 0x04 via 2001:db8:101::2"
1157 log_test $? 2 "Reject route with dsfield"
1171 ip_addr_metric_check()
1173 ip addr help 2>&1 | grep -q metric
1174 if [ $? -ne 0 ]; then
1175 echo "iproute2 command does not support metric for addresses. Skipping test"
1182 ipv6_addr_metric_test()
1187 echo "IPv6 prefix route tests"
1189 ip_addr_metric_check || return 1
1194 $IP li add dummy1 type dummy
1195 $IP li add dummy2 type dummy
1196 $IP li set dummy1 up
1197 $IP li set dummy2 up
1199 # default entry is metric 256
1200 run_cmd "$IP -6 addr add dev dummy1 2001:db8:104::1/64"
1201 run_cmd "$IP -6 addr add dev dummy2 2001:db8:104::2/64"
1204 check_route6 "2001:db8:104::/64 dev dummy1 proto kernel metric 256 2001:db8:104::/64 dev dummy2 proto kernel metric 256"
1205 log_test $? 0 "Default metric"
1208 run_cmd "$IP -6 addr flush dev dummy1"
1209 run_cmd "$IP -6 addr add dev dummy1 2001:db8:104::1/64 metric 257"
1212 check_route6 "2001:db8:104::/64 dev dummy2 proto kernel metric 256 2001:db8:104::/64 dev dummy1 proto kernel metric 257"
1213 log_test $? 0 "User specified metric on first device"
1216 run_cmd "$IP -6 addr flush dev dummy2"
1217 run_cmd "$IP -6 addr add dev dummy2 2001:db8:104::2/64 metric 258"
1220 check_route6 "2001:db8:104::/64 dev dummy1 proto kernel metric 257 2001:db8:104::/64 dev dummy2 proto kernel metric 258"
1221 log_test $? 0 "User specified metric on second device"
1223 run_cmd "$IP -6 addr del dev dummy1 2001:db8:104::1/64 metric 257"
1225 if [ $rc -eq 0 ]; then
1226 check_route6 "2001:db8:104::/64 dev dummy2 proto kernel metric 258"
1229 log_test $rc 0 "Delete of address on first device"
1231 run_cmd "$IP -6 addr change dev dummy2 2001:db8:104::2/64 metric 259"
1233 if [ $rc -eq 0 ]; then
1234 check_route6 "2001:db8:104::/64 dev dummy2 proto kernel metric 259"
1237 log_test $rc 0 "Modify metric of address"
1239 # verify prefix route removed on down
1240 run_cmd "ip netns exec ns1 sysctl -qw net.ipv6.conf.all.keep_addr_on_down=1"
1241 run_cmd "$IP li set dev dummy2 down"
1243 if [ $rc -eq 0 ]; then
1244 out=$($IP -6 ro ls match 2001:db8:104::/64)
1245 check_expected "${out}" ""
1248 log_test $rc 0 "Prefix route removed on link down"
1250 # verify prefix route re-inserted with assigned metric
1251 run_cmd "$IP li set dev dummy2 up"
1253 if [ $rc -eq 0 ]; then
1254 check_route6 "2001:db8:104::/64 dev dummy2 proto kernel metric 259"
1257 log_test $rc 0 "Prefix route with metric on link up"
1259 # verify peer metric added correctly
1261 run_cmd "$IP -6 addr flush dev dummy2"
1262 run_cmd "$IP -6 addr add dev dummy2 2001:db8:104::1 peer 2001:db8:104::2 metric 260"
1265 check_route6 "2001:db8:104::1 dev dummy2 proto kernel metric 260"
1266 log_test $? 0 "Set metric with peer route on local side"
1267 check_route6 "2001:db8:104::2 dev dummy2 proto kernel metric 260"
1268 log_test $? 0 "Set metric with peer route on peer side"
1271 run_cmd "$IP -6 addr change dev dummy2 2001:db8:104::1 peer 2001:db8:104::3 metric 261"
1274 check_route6 "2001:db8:104::1 dev dummy2 proto kernel metric 261"
1275 log_test $? 0 "Modify metric and peer address on local side"
1276 check_route6 "2001:db8:104::3 dev dummy2 proto kernel metric 261"
1277 log_test $? 0 "Modify metric and peer address on peer side"
1284 ipv6_route_metrics_test()
1289 echo "IPv6 routes with metrics"
1294 # single path with metrics
1296 run_cmd "$IP -6 ro add 2001:db8:111::/64 via 2001:db8:101::2 mtu 1400"
1298 if [ $rc -eq 0 ]; then
1299 check_route6 "2001:db8:111::/64 via 2001:db8:101::2 dev veth1 metric 1024 mtu 1400"
1302 log_test $rc 0 "Single path route with mtu metric"
1306 # multipath via separate routes with metrics
1308 run_cmd "$IP -6 ro add 2001:db8:112::/64 via 2001:db8:101::2 mtu 1400"
1309 run_cmd "$IP -6 ro append 2001:db8:112::/64 via 2001:db8:103::2"
1311 if [ $rc -eq 0 ]; then
1312 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"
1315 log_test $rc 0 "Multipath route via 2 single routes with mtu metric on first"
1317 # second route is coalesced to first to make a multipath route.
1318 # MTU of the second path is hidden from display!
1319 run_cmd "$IP -6 ro add 2001:db8:113::/64 via 2001:db8:101::2"
1320 run_cmd "$IP -6 ro append 2001:db8:113::/64 via 2001:db8:103::2 mtu 1400"
1322 if [ $rc -eq 0 ]; then
1323 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"
1326 log_test $rc 0 "Multipath route via 2 single routes with mtu metric on 2nd"
1328 run_cmd "$IP -6 ro del 2001:db8:113::/64 via 2001:db8:101::2"
1329 if [ $? -eq 0 ]; then
1330 check_route6 "2001:db8:113::/64 via 2001:db8:103::2 dev veth3 metric 1024 mtu 1400"
1331 log_test $? 0 " MTU of second leg"
1335 # multipath with metrics
1337 run_cmd "$IP -6 ro add 2001:db8:115::/64 mtu 1400 nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"
1339 if [ $rc -eq 0 ]; then
1340 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"
1343 log_test $rc 0 "Multipath route with mtu metric"
1345 $IP -6 ro add 2001:db8:104::/64 via 2001:db8:101::2 mtu 1300
1346 run_cmd "ip netns exec ns1 ${ping6} -w1 -c1 -s 1500 2001:db8:104::1"
1347 log_test $? 0 "Using route with mtu metric"
1349 run_cmd "$IP -6 ro add 2001:db8:114::/64 via 2001:db8:101::2 congctl lock foo"
1350 log_test $? 2 "Invalid metric (fails metric_convert)"
1355 # add route for a prefix, flushing any existing routes first
1356 # expected to be the first step of a test
1363 if [ "$VERBOSE" = "1" ]; then
1365 echo " ##################################################"
1369 run_cmd "$IP ro flush ${pfx}"
1370 [ $? -ne 0 ] && exit 1
1372 out=$($IP ro ls match ${pfx})
1373 if [ -n "$out" ]; then
1374 echo "Failed to flush routes for prefix used for tests."
1378 run_cmd "$IP ro add ${pfx} ${nh}"
1379 if [ $? -ne 0 ]; then
1380 echo "Failed to add initial route for test."
1385 # add initial route - used in replace route tests
1388 add_route "172.16.104.0/24" "$1"
1399 [ "${pfx}" = "unreachable" ] && pfx=$2
1401 out=$($IP ro ls match ${pfx})
1402 check_expected "${out}" "${expected}"
1405 # assumption is that basic add of a single path route works
1406 # otherwise just adding an address on an interface is broken
1412 echo "IPv4 route add / append tests"
1414 # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL
1415 add_route "172.16.104.0/24" "via 172.16.101.2"
1416 run_cmd "$IP ro add 172.16.104.0/24 via 172.16.103.2"
1417 log_test $? 2 "Attempt to add duplicate route - gw"
1419 # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL
1420 add_route "172.16.104.0/24" "via 172.16.101.2"
1421 run_cmd "$IP ro add 172.16.104.0/24 dev veth3"
1422 log_test $? 2 "Attempt to add duplicate route - dev only"
1424 # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL
1425 add_route "172.16.104.0/24" "via 172.16.101.2"
1426 run_cmd "$IP ro add unreachable 172.16.104.0/24"
1427 log_test $? 2 "Attempt to add duplicate route - reject route"
1429 # iproute2 prepend only sets NLM_F_CREATE
1430 # - adds a new route; does NOT convert existing route to ECMP
1431 add_route "172.16.104.0/24" "via 172.16.101.2"
1432 run_cmd "$IP ro prepend 172.16.104.0/24 via 172.16.103.2"
1433 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"
1434 log_test $? 0 "Add new nexthop for existing prefix"
1436 # route append with same prefix adds a new route
1437 # - iproute2 sets NLM_F_CREATE | NLM_F_APPEND
1438 add_route "172.16.104.0/24" "via 172.16.101.2"
1439 run_cmd "$IP ro append 172.16.104.0/24 via 172.16.103.2"
1440 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"
1441 log_test $? 0 "Append nexthop to existing route - gw"
1443 add_route "172.16.104.0/24" "via 172.16.101.2"
1444 run_cmd "$IP ro append 172.16.104.0/24 dev veth3"
1445 check_route "172.16.104.0/24 via 172.16.101.2 dev veth1 172.16.104.0/24 dev veth3 scope link"
1446 log_test $? 0 "Append nexthop to existing route - dev only"
1448 add_route "172.16.104.0/24" "via 172.16.101.2"
1449 run_cmd "$IP ro append unreachable 172.16.104.0/24"
1450 check_route "172.16.104.0/24 via 172.16.101.2 dev veth1 unreachable 172.16.104.0/24"
1451 log_test $? 0 "Append nexthop to existing route - reject route"
1453 run_cmd "$IP ro flush 172.16.104.0/24"
1454 run_cmd "$IP ro add unreachable 172.16.104.0/24"
1455 run_cmd "$IP ro append 172.16.104.0/24 via 172.16.103.2"
1456 check_route "unreachable 172.16.104.0/24 172.16.104.0/24 via 172.16.103.2 dev veth3"
1457 log_test $? 0 "Append nexthop to existing reject route - gw"
1459 run_cmd "$IP ro flush 172.16.104.0/24"
1460 run_cmd "$IP ro add unreachable 172.16.104.0/24"
1461 run_cmd "$IP ro append 172.16.104.0/24 dev veth3"
1462 check_route "unreachable 172.16.104.0/24 172.16.104.0/24 dev veth3 scope link"
1463 log_test $? 0 "Append nexthop to existing reject route - dev only"
1465 # insert mpath directly
1466 add_route "172.16.104.0/24" "nexthop via 172.16.101.2 nexthop via 172.16.103.2"
1467 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"
1468 log_test $? 0 "add multipath route"
1470 add_route "172.16.104.0/24" "nexthop via 172.16.101.2 nexthop via 172.16.103.2"
1471 run_cmd "$IP ro add 172.16.104.0/24 nexthop via 172.16.101.2 nexthop via 172.16.103.2"
1472 log_test $? 2 "Attempt to add duplicate multipath route"
1474 # insert of a second route without append but different metric
1475 add_route "172.16.104.0/24" "via 172.16.101.2"
1476 run_cmd "$IP ro add 172.16.104.0/24 via 172.16.103.2 metric 512"
1478 if [ $rc -eq 0 ]; then
1479 run_cmd "$IP ro add 172.16.104.0/24 via 172.16.103.3 metric 256"
1482 log_test $rc 0 "Route add with different metrics"
1484 run_cmd "$IP ro del 172.16.104.0/24 metric 512"
1486 if [ $rc -eq 0 ]; then
1487 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"
1490 log_test $rc 0 "Route delete with metric"
1493 ipv4_rt_replace_single()
1495 # single path with single path
1497 add_initial_route "via 172.16.101.2"
1498 run_cmd "$IP ro replace 172.16.104.0/24 via 172.16.103.2"
1499 check_route "172.16.104.0/24 via 172.16.103.2 dev veth3"
1500 log_test $? 0 "Single path with single path"
1502 # single path with multipath
1504 add_initial_route "nexthop via 172.16.101.2"
1505 run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.101.3 nexthop via 172.16.103.2"
1506 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"
1507 log_test $? 0 "Single path with multipath"
1509 # single path with reject
1511 add_initial_route "nexthop via 172.16.101.2"
1512 run_cmd "$IP ro replace unreachable 172.16.104.0/24"
1513 check_route "unreachable 172.16.104.0/24"
1514 log_test $? 0 "Single path with reject route"
1516 # single path with single path using MULTIPATH attribute
1518 add_initial_route "via 172.16.101.2"
1519 run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.103.2"
1520 check_route "172.16.104.0/24 via 172.16.103.2 dev veth3"
1521 log_test $? 0 "Single path with single path via multipath attribute"
1523 # route replace fails - invalid nexthop
1524 add_initial_route "via 172.16.101.2"
1525 run_cmd "$IP ro replace 172.16.104.0/24 via 2001:db8:104::2"
1526 if [ $? -eq 0 ]; then
1527 # previous command is expected to fail so if it returns 0
1528 # that means the test failed.
1529 log_test 0 1 "Invalid nexthop"
1531 check_route "172.16.104.0/24 via 172.16.101.2 dev veth1"
1532 log_test $? 0 "Invalid nexthop"
1535 # replace non-existent route
1536 # - note use of change versus replace since ip adds NLM_F_CREATE
1538 add_initial_route "via 172.16.101.2"
1539 run_cmd "$IP ro change 172.16.105.0/24 via 172.16.101.2"
1540 log_test $? 2 "Single path - replace of non-existent route"
1543 ipv4_rt_replace_mpath()
1545 # multipath with multipath
1546 add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2"
1547 run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.101.3 nexthop via 172.16.103.3"
1548 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"
1549 log_test $? 0 "Multipath with multipath"
1551 # multipath with single
1552 add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2"
1553 run_cmd "$IP ro replace 172.16.104.0/24 via 172.16.101.3"
1554 check_route "172.16.104.0/24 via 172.16.101.3 dev veth1"
1555 log_test $? 0 "Multipath with single path"
1557 # multipath with single
1558 add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2"
1559 run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.101.3"
1560 check_route "172.16.104.0/24 via 172.16.101.3 dev veth1"
1561 log_test $? 0 "Multipath with single path via multipath attribute"
1563 # multipath with reject
1564 add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2"
1565 run_cmd "$IP ro replace unreachable 172.16.104.0/24"
1566 check_route "unreachable 172.16.104.0/24"
1567 log_test $? 0 "Multipath with reject route"
1569 # route replace fails - invalid nexthop 1
1570 add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2"
1571 run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.111.3 nexthop via 172.16.103.3"
1572 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"
1573 log_test $? 0 "Multipath - invalid first nexthop"
1575 # route replace fails - invalid nexthop 2
1576 add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2"
1577 run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.101.3 nexthop via 172.16.113.3"
1578 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"
1579 log_test $? 0 "Multipath - invalid second nexthop"
1581 # multipath non-existent route
1582 add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2"
1583 run_cmd "$IP ro change 172.16.105.0/24 nexthop via 172.16.101.3 nexthop via 172.16.103.3"
1584 log_test $? 2 "Multipath - replace of non-existent route"
1590 echo "IPv4 route replace tests"
1592 ipv4_rt_replace_single
1593 ipv4_rt_replace_mpath
1596 # checks that cached input route on VRF port is deleted
1597 # when VRF is deleted
1598 ipv4_local_rt_cache()
1600 run_cmd "ip addr add 10.0.0.1/32 dev lo"
1601 run_cmd "ip netns add test-ns"
1602 run_cmd "ip link add veth-outside type veth peer name veth-inside"
1603 run_cmd "ip link add vrf-100 type vrf table 1100"
1604 run_cmd "ip link set veth-outside master vrf-100"
1605 run_cmd "ip link set veth-inside netns test-ns"
1606 run_cmd "ip link set veth-outside up"
1607 run_cmd "ip link set vrf-100 up"
1608 run_cmd "ip route add 10.1.1.1/32 dev veth-outside table 1100"
1609 run_cmd "ip netns exec test-ns ip link set veth-inside up"
1610 run_cmd "ip netns exec test-ns ip addr add 10.1.1.1/32 dev veth-inside"
1611 run_cmd "ip netns exec test-ns ip route add 10.0.0.1/32 dev veth-inside"
1612 run_cmd "ip netns exec test-ns ip route add default via 10.0.0.1"
1613 run_cmd "ip netns exec test-ns ping 10.0.0.1 -c 1 -i 1"
1614 run_cmd "ip link delete vrf-100"
1616 # if we do not hang test is a success
1617 log_test $? 0 "Cached route removed from VRF port device"
1623 echo "IPv4 route with dsfield tests"
1625 run_cmd "$IP route flush 172.16.102.0/24"
1627 # New routes should reject dsfield options that interfere with ECN
1628 run_cmd "$IP route add 172.16.102.0/24 dsfield 0x01 via 172.16.101.2"
1629 log_test $? 2 "Reject route with dsfield 0x01"
1631 run_cmd "$IP route add 172.16.102.0/24 dsfield 0x02 via 172.16.101.2"
1632 log_test $? 2 "Reject route with dsfield 0x02"
1634 run_cmd "$IP route add 172.16.102.0/24 dsfield 0x03 via 172.16.101.2"
1635 log_test $? 2 "Reject route with dsfield 0x03"
1637 # A generic route that doesn't take DSCP into account
1638 run_cmd "$IP route add 172.16.102.0/24 via 172.16.101.2"
1640 # A more specific route for DSCP 0x10
1641 run_cmd "$IP route add 172.16.102.0/24 dsfield 0x10 via 172.16.103.2"
1643 # DSCP 0x10 should match the specific route, no matter the ECN bits
1644 $IP route get fibmatch 172.16.102.1 dsfield 0x10 | \
1645 grep -q "via 172.16.103.2"
1646 log_test $? 0 "IPv4 route with DSCP and ECN:Not-ECT"
1648 $IP route get fibmatch 172.16.102.1 dsfield 0x11 | \
1649 grep -q "via 172.16.103.2"
1650 log_test $? 0 "IPv4 route with DSCP and ECN:ECT(1)"
1652 $IP route get fibmatch 172.16.102.1 dsfield 0x12 | \
1653 grep -q "via 172.16.103.2"
1654 log_test $? 0 "IPv4 route with DSCP and ECN:ECT(0)"
1656 $IP route get fibmatch 172.16.102.1 dsfield 0x13 | \
1657 grep -q "via 172.16.103.2"
1658 log_test $? 0 "IPv4 route with DSCP and ECN:CE"
1660 # Unknown DSCP should match the generic route, no matter the ECN bits
1661 $IP route get fibmatch 172.16.102.1 dsfield 0x14 | \
1662 grep -q "via 172.16.101.2"
1663 log_test $? 0 "IPv4 route with unknown DSCP and ECN:Not-ECT"
1665 $IP route get fibmatch 172.16.102.1 dsfield 0x15 | \
1666 grep -q "via 172.16.101.2"
1667 log_test $? 0 "IPv4 route with unknown DSCP and ECN:ECT(1)"
1669 $IP route get fibmatch 172.16.102.1 dsfield 0x16 | \
1670 grep -q "via 172.16.101.2"
1671 log_test $? 0 "IPv4 route with unknown DSCP and ECN:ECT(0)"
1673 $IP route get fibmatch 172.16.102.1 dsfield 0x17 | \
1674 grep -q "via 172.16.101.2"
1675 log_test $? 0 "IPv4 route with unknown DSCP and ECN:CE"
1677 # Null DSCP should match the generic route, no matter the ECN bits
1678 $IP route get fibmatch 172.16.102.1 dsfield 0x00 | \
1679 grep -q "via 172.16.101.2"
1680 log_test $? 0 "IPv4 route with no DSCP and ECN:Not-ECT"
1682 $IP route get fibmatch 172.16.102.1 dsfield 0x01 | \
1683 grep -q "via 172.16.101.2"
1684 log_test $? 0 "IPv4 route with no DSCP and ECN:ECT(1)"
1686 $IP route get fibmatch 172.16.102.1 dsfield 0x02 | \
1687 grep -q "via 172.16.101.2"
1688 log_test $? 0 "IPv4 route with no DSCP and ECN:ECT(0)"
1690 $IP route get fibmatch 172.16.102.1 dsfield 0x03 | \
1691 grep -q "via 172.16.101.2"
1692 log_test $? 0 "IPv4 route with no DSCP and ECN:CE"
1707 ipv4_addr_metric_test()
1712 echo "IPv4 prefix route tests"
1714 ip_addr_metric_check || return 1
1719 $IP li add dummy1 type dummy
1720 $IP li add dummy2 type dummy
1721 $IP li set dummy1 up
1722 $IP li set dummy2 up
1724 # default entry is metric 256
1725 run_cmd "$IP addr add dev dummy1 172.16.104.1/24"
1726 run_cmd "$IP addr add dev dummy2 172.16.104.2/24"
1729 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"
1730 log_test $? 0 "Default metric"
1733 run_cmd "$IP addr flush dev dummy1"
1734 run_cmd "$IP addr add dev dummy1 172.16.104.1/24 metric 257"
1737 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"
1738 log_test $? 0 "User specified metric on first device"
1741 run_cmd "$IP addr flush dev dummy2"
1742 run_cmd "$IP addr add dev dummy2 172.16.104.2/24 metric 258"
1745 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"
1746 log_test $? 0 "User specified metric on second device"
1748 run_cmd "$IP addr del dev dummy1 172.16.104.1/24 metric 257"
1750 if [ $rc -eq 0 ]; then
1751 check_route "172.16.104.0/24 dev dummy2 proto kernel scope link src 172.16.104.2 metric 258"
1754 log_test $rc 0 "Delete of address on first device"
1756 run_cmd "$IP addr change dev dummy2 172.16.104.2/24 metric 259"
1758 if [ $rc -eq 0 ]; then
1759 check_route "172.16.104.0/24 dev dummy2 proto kernel scope link src 172.16.104.2 metric 259"
1762 log_test $rc 0 "Modify metric of address"
1764 # verify prefix route removed on down
1765 run_cmd "$IP li set dev dummy2 down"
1767 if [ $rc -eq 0 ]; then
1768 out=$($IP ro ls match 172.16.104.0/24)
1769 check_expected "${out}" ""
1772 log_test $rc 0 "Prefix route removed on link down"
1774 # verify prefix route re-inserted with assigned metric
1775 run_cmd "$IP li set dev dummy2 up"
1777 if [ $rc -eq 0 ]; then
1778 check_route "172.16.104.0/24 dev dummy2 proto kernel scope link src 172.16.104.2 metric 259"
1781 log_test $rc 0 "Prefix route with metric on link up"
1783 # explicitly check for metric changes on edge scenarios
1784 run_cmd "$IP addr flush dev dummy2"
1785 run_cmd "$IP addr add dev dummy2 172.16.104.0/24 metric 259"
1786 run_cmd "$IP addr change dev dummy2 172.16.104.0/24 metric 260"
1788 if [ $rc -eq 0 ]; then
1789 check_route "172.16.104.0/24 dev dummy2 proto kernel scope link src 172.16.104.0 metric 260"
1792 log_test $rc 0 "Modify metric of .0/24 address"
1794 run_cmd "$IP addr flush dev dummy2"
1795 run_cmd "$IP addr add dev dummy2 172.16.104.1/32 peer 172.16.104.2 metric 260"
1797 if [ $rc -eq 0 ]; then
1798 check_route "172.16.104.2 dev dummy2 proto kernel scope link src 172.16.104.1 metric 260"
1801 log_test $rc 0 "Set metric of address with peer route"
1803 run_cmd "$IP addr change dev dummy2 172.16.104.1/32 peer 172.16.104.3 metric 261"
1805 if [ $rc -eq 0 ]; then
1806 check_route "172.16.104.3 dev dummy2 proto kernel scope link src 172.16.104.1 metric 261"
1809 log_test $rc 0 "Modify metric and peer address for peer route"
1816 ipv4_route_metrics_test()
1821 echo "IPv4 route add / append tests"
1825 run_cmd "$IP ro add 172.16.111.0/24 via 172.16.101.2 mtu 1400"
1827 if [ $rc -eq 0 ]; then
1828 check_route "172.16.111.0/24 via 172.16.101.2 dev veth1 mtu 1400"
1831 log_test $rc 0 "Single path route with mtu metric"
1834 run_cmd "$IP ro add 172.16.112.0/24 mtu 1400 nexthop via 172.16.101.2 nexthop via 172.16.103.2"
1836 if [ $rc -eq 0 ]; then
1837 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"
1840 log_test $rc 0 "Multipath route with mtu metric"
1842 $IP ro add 172.16.104.0/24 via 172.16.101.2 mtu 1300
1843 run_cmd "ip netns exec ns1 ping -w1 -c1 -s 1500 172.16.104.1"
1844 log_test $? 0 "Using route with mtu metric"
1846 run_cmd "$IP ro add 172.16.111.0/24 via 172.16.101.2 congctl lock foo"
1847 log_test $? 2 "Invalid metric (fails metric_convert)"
1852 ipv4_del_addr_test()
1855 echo "IPv4 delete address route tests"
1860 $IP li add dummy1 type dummy
1861 $IP li set dummy1 up
1862 $IP li add dummy2 type dummy
1863 $IP li set dummy2 up
1864 $IP li add red type vrf table 1111
1866 $IP ro add vrf red unreachable default
1867 $IP li set dummy2 vrf red
1869 $IP addr add dev dummy1 172.16.104.1/24
1870 $IP addr add dev dummy1 172.16.104.11/24
1871 $IP addr add dev dummy1 172.16.104.12/24
1872 $IP addr add dev dummy1 172.16.104.13/24
1873 $IP addr add dev dummy2 172.16.104.1/24
1874 $IP addr add dev dummy2 172.16.104.11/24
1875 $IP addr add dev dummy2 172.16.104.12/24
1876 $IP route add 172.16.105.0/24 via 172.16.104.2 src 172.16.104.11
1877 $IP route add 172.16.106.0/24 dev lo src 172.16.104.12
1878 $IP route add table 0 172.16.107.0/24 via 172.16.104.2 src 172.16.104.13
1879 $IP route add vrf red 172.16.105.0/24 via 172.16.104.2 src 172.16.104.11
1880 $IP route add vrf red 172.16.106.0/24 dev lo src 172.16.104.12
1883 # removing address from device in vrf should only remove route from vrf table
1884 echo " Regular FIB info"
1886 $IP addr del dev dummy2 172.16.104.11/24
1887 $IP ro ls vrf red | grep -q 172.16.105.0/24
1888 log_test $? 1 "Route removed from VRF when source address deleted"
1890 $IP ro ls | grep -q 172.16.105.0/24
1891 log_test $? 0 "Route in default VRF not removed"
1893 $IP addr add dev dummy2 172.16.104.11/24
1894 $IP route add vrf red 172.16.105.0/24 via 172.16.104.2 src 172.16.104.11
1896 $IP addr del dev dummy1 172.16.104.11/24
1897 $IP ro ls | grep -q 172.16.105.0/24
1898 log_test $? 1 "Route removed in default VRF when source address deleted"
1900 $IP ro ls vrf red | grep -q 172.16.105.0/24
1901 log_test $? 0 "Route in VRF is not removed by address delete"
1903 # removing address from device in vrf should only remove route from vrf
1904 # table even when the associated fib info only differs in table ID
1905 echo " Identical FIB info with different table ID"
1907 $IP addr del dev dummy2 172.16.104.12/24
1908 $IP ro ls vrf red | grep -q 172.16.106.0/24
1909 log_test $? 1 "Route removed from VRF when source address deleted"
1911 $IP ro ls | grep -q 172.16.106.0/24
1912 log_test $? 0 "Route in default VRF not removed"
1914 $IP addr add dev dummy2 172.16.104.12/24
1915 $IP route add vrf red 172.16.106.0/24 dev lo src 172.16.104.12
1917 $IP addr del dev dummy1 172.16.104.12/24
1918 $IP ro ls | grep -q 172.16.106.0/24
1919 log_test $? 1 "Route removed in default VRF when source address deleted"
1921 $IP ro ls vrf red | grep -q 172.16.106.0/24
1922 log_test $? 0 "Route in VRF is not removed by address delete"
1924 # removing address from device in default vrf should remove route from
1925 # the default vrf even when route was inserted with a table ID of 0.
1928 $IP addr del dev dummy1 172.16.104.13/24
1929 $IP ro ls | grep -q 172.16.107.0/24
1930 log_test $? 1 "Route removed in default VRF when source address deleted"
1937 ipv6_del_addr_test()
1940 echo "IPv6 delete address route tests"
1945 for i in $(seq 6); do
1946 $IP li add dummy${i} up type dummy
1949 $IP li add red up type vrf table 1111
1950 $IP ro add vrf red unreachable default
1951 for i in $(seq 4 6); do
1952 $IP li set dummy${i} vrf red
1955 $IP addr add dev dummy1 fe80::1/128
1956 $IP addr add dev dummy1 2001:db8:101::1/64
1957 $IP addr add dev dummy1 2001:db8:101::10/64
1958 $IP addr add dev dummy1 2001:db8:101::11/64
1959 $IP addr add dev dummy1 2001:db8:101::12/64
1960 $IP addr add dev dummy1 2001:db8:101::13/64
1961 $IP addr add dev dummy1 2001:db8:101::14/64
1962 $IP addr add dev dummy1 2001:db8:101::15/64
1963 $IP addr add dev dummy2 fe80::1/128
1964 $IP addr add dev dummy2 2001:db8:101::1/64
1965 $IP addr add dev dummy2 2001:db8:101::11/64
1966 $IP addr add dev dummy3 fe80::1/128
1968 $IP addr add dev dummy4 2001:db8:101::1/64
1969 $IP addr add dev dummy4 2001:db8:101::10/64
1970 $IP addr add dev dummy4 2001:db8:101::11/64
1971 $IP addr add dev dummy4 2001:db8:101::12/64
1972 $IP addr add dev dummy4 2001:db8:101::13/64
1973 $IP addr add dev dummy4 2001:db8:101::14/64
1974 $IP addr add dev dummy5 2001:db8:101::1/64
1975 $IP addr add dev dummy5 2001:db8:101::11/64
1977 # Single device using src address
1978 $IP route add 2001:db8:110::/64 dev dummy3 src 2001:db8:101::10
1979 # Two devices with the same source address
1980 $IP route add 2001:db8:111::/64 dev dummy3 src 2001:db8:101::11
1981 # VRF with single device using src address
1982 $IP route add vrf red 2001:db8:110::/64 dev dummy6 src 2001:db8:101::10
1983 # VRF with two devices using src address
1984 $IP route add vrf red 2001:db8:111::/64 dev dummy6 src 2001:db8:101::11
1985 # src address and nexthop dev in same VRF
1986 $IP route add 2001:db8:112::/64 dev dummy3 src 2001:db8:101::12
1987 $IP route add vrf red 2001:db8:112::/64 dev dummy6 src 2001:db8:101::12
1988 # src address and nexthop device in different VRF
1989 $IP route add 2001:db8:113::/64 dev lo src 2001:db8:101::13
1990 $IP route add vrf red 2001:db8:113::/64 dev lo src 2001:db8:101::13
1992 $IP route add table 0 2001:db8:115::/64 via 2001:db8:101::2 src 2001:db8:101::15
1993 # Link local source route
1994 $IP route add 2001:db8:116::/64 dev dummy2 src fe80::1
1995 $IP route add 2001:db8:117::/64 dev dummy3 src fe80::1
1998 echo " Single device using src address"
2000 $IP addr del dev dummy1 2001:db8:101::10/64
2001 $IP -6 route show | grep -q "src 2001:db8:101::10 "
2002 log_test $? 1 "Prefsrc removed when src address removed on other device"
2004 echo " Two devices with the same source address"
2006 $IP addr del dev dummy1 2001:db8:101::11/64
2007 $IP -6 route show | grep -q "src 2001:db8:101::11 "
2008 log_test $? 0 "Prefsrc not removed when src address exist on other device"
2010 $IP addr del dev dummy2 2001:db8:101::11/64
2011 $IP -6 route show | grep -q "src 2001:db8:101::11 "
2012 log_test $? 1 "Prefsrc removed when src address removed on all devices"
2014 echo " VRF with single device using src address"
2016 $IP addr del dev dummy4 2001:db8:101::10/64
2017 $IP -6 route show vrf red | grep -q "src 2001:db8:101::10 "
2018 log_test $? 1 "Prefsrc removed when src address removed on other device"
2020 echo " VRF with two devices using src address"
2022 $IP addr del dev dummy4 2001:db8:101::11/64
2023 $IP -6 route show vrf red | grep -q "src 2001:db8:101::11 "
2024 log_test $? 0 "Prefsrc not removed when src address exist on other device"
2026 $IP addr del dev dummy5 2001:db8:101::11/64
2027 $IP -6 route show vrf red | grep -q "src 2001:db8:101::11 "
2028 log_test $? 1 "Prefsrc removed when src address removed on all devices"
2030 echo " src address and nexthop dev in same VRF"
2032 $IP addr del dev dummy4 2001:db8:101::12/64
2033 $IP -6 route show vrf red | grep -q "src 2001:db8:101::12 "
2034 log_test $? 1 "Prefsrc removed from VRF when source address deleted"
2035 $IP -6 route show | grep -q " src 2001:db8:101::12 "
2036 log_test $? 0 "Prefsrc in default VRF not removed"
2038 $IP addr add dev dummy4 2001:db8:101::12/64
2039 $IP route replace vrf red 2001:db8:112::/64 dev dummy6 src 2001:db8:101::12
2040 $IP addr del dev dummy1 2001:db8:101::12/64
2041 $IP -6 route show vrf red | grep -q "src 2001:db8:101::12 "
2042 log_test $? 0 "Prefsrc not removed from VRF when source address exist"
2043 $IP -6 route show | grep -q " src 2001:db8:101::12 "
2044 log_test $? 1 "Prefsrc in default VRF removed"
2046 echo " src address and nexthop device in different VRF"
2048 $IP addr del dev dummy4 2001:db8:101::13/64
2049 $IP -6 route show vrf red | grep -q "src 2001:db8:101::13 "
2050 log_test $? 0 "Prefsrc not removed from VRF when nexthop dev in diff VRF"
2051 $IP -6 route show | grep -q "src 2001:db8:101::13 "
2052 log_test $? 0 "Prefsrc not removed in default VRF"
2054 $IP addr add dev dummy4 2001:db8:101::13/64
2055 $IP addr del dev dummy1 2001:db8:101::13/64
2056 $IP -6 route show vrf red | grep -q "src 2001:db8:101::13 "
2057 log_test $? 1 "Prefsrc removed from VRF when nexthop dev in diff VRF"
2058 $IP -6 route show | grep -q "src 2001:db8:101::13 "
2059 log_test $? 1 "Prefsrc removed in default VRF"
2063 $IP addr del dev dummy1 2001:db8:101::15/64
2064 $IP -6 route show | grep -q "src 2001:db8:101::15"
2065 log_test $? 1 "Prefsrc removed from default VRF when source address deleted"
2067 echo " Link local source route"
2068 $IP addr del dev dummy1 fe80::1/128
2069 $IP -6 route show | grep -q "2001:db8:116::/64 dev dummy2 src fe80::1"
2070 log_test $? 0 "Prefsrc not removed when delete ll addr from other dev"
2071 $IP addr del dev dummy2 fe80::1/128
2072 $IP -6 route show | grep -q "2001:db8:116::/64 dev dummy2 src fe80::1"
2073 log_test $? 1 "Prefsrc removed when delete ll addr"
2074 $IP -6 route show | grep -q "2001:db8:117::/64 dev dummy3 src fe80::1"
2075 log_test $? 0 "Prefsrc not removed when delete ll addr from other dev"
2076 $IP addr add dev dummy1 fe80::1/128
2077 $IP addr del dev dummy3 fe80::1/128
2078 $IP -6 route show | grep -q "2001:db8:117::/64 dev dummy3 src fe80::1"
2079 log_test $? 1 "Prefsrc removed even ll addr still exist on other dev"
2081 for i in $(seq 6); do
2082 $IP li del dummy${i}
2087 ipv4_route_v6_gw_test()
2092 echo "IPv4 route with IPv6 gateway tests"
2100 run_cmd "$IP ro add 172.16.104.0/24 via inet6 2001:db8:101::2"
2102 log_test $rc 0 "Single path route with IPv6 gateway"
2103 if [ $rc -eq 0 ]; then
2104 check_route "172.16.104.0/24 via inet6 2001:db8:101::2 dev veth1"
2107 run_cmd "ip netns exec ns1 ping -w1 -c1 172.16.104.1"
2108 log_test $rc 0 "Single path route with IPv6 gateway - ping"
2110 run_cmd "$IP ro del 172.16.104.0/24 via inet6 2001:db8:101::2"
2112 log_test $rc 0 "Single path route delete"
2113 if [ $rc -eq 0 ]; then
2114 check_route "172.16.112.0/24"
2118 # multipath - v6 then v4
2120 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"
2122 log_test $rc 0 "Multipath route add - v6 nexthop then v4"
2123 if [ $rc -eq 0 ]; then
2124 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"
2127 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"
2128 log_test $? 2 " Multipath route delete - nexthops in wrong order"
2130 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"
2131 log_test $? 0 " Multipath route delete exact match"
2134 # multipath - v4 then v6
2136 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"
2138 log_test $rc 0 "Multipath route add - v4 nexthop then v6"
2139 if [ $rc -eq 0 ]; then
2140 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"
2143 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"
2144 log_test $? 2 " Multipath route delete - nexthops in wrong order"
2146 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"
2147 log_test $? 0 " Multipath route delete exact match"
2154 if [ ! -x "$(command -v socat)" ]; then
2155 echo "socat command not found. Skipping test"
2164 iptables -t mangle -L OUTPUT &> /dev/null
2165 if [ $? -ne 0 ]; then
2166 echo "iptables configuration not supported. Skipping test"
2175 ip6tables -t mangle -L OUTPUT &> /dev/null
2176 if [ $? -ne 0 ]; then
2177 echo "ip6tables configuration not supported. Skipping test"
2189 echo "IPv4 mangling tests"
2191 socat_check || return 1
2192 iptables_check || return 1
2197 local tmp_file=$(mktemp)
2198 ip netns exec ns2 socat UDP4-LISTEN:54321,fork $tmp_file &
2200 # Add a FIB rule and a route that will direct our connection to the
2202 $IP rule add pref 100 ipproto udp sport 12345 dport 54321 table 123
2203 $IP route add table 123 172.16.101.0/24 dev veth1
2205 # Add an unreachable route to the main table that will block our
2206 # connection in case the FIB rule is not hit.
2207 $IP route add unreachable 172.16.101.2/32
2209 run_cmd "echo a | $NS_EXEC socat STDIN UDP4:172.16.101.2:54321,sourceport=12345"
2210 log_test $? 0 " Connection with correct parameters"
2212 run_cmd "echo a | $NS_EXEC socat STDIN UDP4:172.16.101.2:54321,sourceport=11111"
2213 log_test $? 1 " Connection with incorrect parameters"
2215 # Add a mangling rule and make sure connection is still successful.
2216 $NS_EXEC iptables -t mangle -A OUTPUT -j MARK --set-mark 1
2218 run_cmd "echo a | $NS_EXEC socat STDIN UDP4:172.16.101.2:54321,sourceport=12345"
2219 log_test $? 0 " Connection with correct parameters - mangling"
2221 # Delete the mangling rule and make sure connection is still
2223 $NS_EXEC iptables -t mangle -D OUTPUT -j MARK --set-mark 1
2225 run_cmd "echo a | $NS_EXEC socat STDIN UDP4:172.16.101.2:54321,sourceport=12345"
2226 log_test $? 0 " Connection with correct parameters - no mangling"
2228 # Verify connections were indeed successful on server side.
2229 [[ $(cat $tmp_file | wc -l) -eq 3 ]]
2230 log_test $? 0 " Connection check - server side"
2232 $IP route del unreachable 172.16.101.2/32
2233 $IP route del table 123 172.16.101.0/24 dev veth1
2234 $IP rule del pref 100
2236 { kill %% && wait %%; } 2>/dev/null
2247 echo "IPv6 mangling tests"
2249 socat_check || return 1
2250 ip6tables_check || return 1
2255 local tmp_file=$(mktemp)
2256 ip netns exec ns2 socat UDP6-LISTEN:54321,fork $tmp_file &
2258 # Add a FIB rule and a route that will direct our connection to the
2260 $IP -6 rule add pref 100 ipproto udp sport 12345 dport 54321 table 123
2261 $IP -6 route add table 123 2001:db8:101::/64 dev veth1
2263 # Add an unreachable route to the main table that will block our
2264 # connection in case the FIB rule is not hit.
2265 $IP -6 route add unreachable 2001:db8:101::2/128
2267 run_cmd "echo a | $NS_EXEC socat STDIN UDP6:[2001:db8:101::2]:54321,sourceport=12345"
2268 log_test $? 0 " Connection with correct parameters"
2270 run_cmd "echo a | $NS_EXEC socat STDIN UDP6:[2001:db8:101::2]:54321,sourceport=11111"
2271 log_test $? 1 " Connection with incorrect parameters"
2273 # Add a mangling rule and make sure connection is still successful.
2274 $NS_EXEC ip6tables -t mangle -A OUTPUT -j MARK --set-mark 1
2276 run_cmd "echo a | $NS_EXEC socat STDIN UDP6:[2001:db8:101::2]:54321,sourceport=12345"
2277 log_test $? 0 " Connection with correct parameters - mangling"
2279 # Delete the mangling rule and make sure connection is still
2281 $NS_EXEC ip6tables -t mangle -D OUTPUT -j MARK --set-mark 1
2283 run_cmd "echo a | $NS_EXEC socat STDIN UDP6:[2001:db8:101::2]:54321,sourceport=12345"
2284 log_test $? 0 " Connection with correct parameters - no mangling"
2286 # Verify connections were indeed successful on server side.
2287 [[ $(cat $tmp_file | wc -l) -eq 3 ]]
2288 log_test $? 0 " Connection check - server side"
2290 $IP -6 route del unreachable 2001:db8:101::2/128
2291 $IP -6 route del table 123 2001:db8:101::/64 dev veth1
2292 $IP -6 rule del pref 100
2294 { kill %% && wait %%; } 2>/dev/null
2300 ip_neigh_get_check()
2302 ip neigh help 2>&1 | grep -q 'ip neigh get'
2303 if [ $? -ne 0 ]; then
2304 echo "iproute2 command does not support neigh get. Skipping test"
2311 ipv4_bcast_neigh_test()
2316 echo "IPv4 broadcast neighbour tests"
2318 ip_neigh_get_check || return 1
2323 run_cmd "$IP neigh add 192.0.2.111 lladdr 00:11:22:33:44:55 nud perm dev dummy0"
2324 run_cmd "$IP neigh add 192.0.2.255 lladdr 00:11:22:33:44:55 nud perm dev dummy0"
2326 run_cmd "$IP neigh get 192.0.2.111 dev dummy0"
2327 run_cmd "$IP neigh get 192.0.2.255 dev dummy0"
2329 run_cmd "$IP address add 192.0.2.1/24 broadcast 192.0.2.111 dev dummy0"
2331 run_cmd "$IP neigh add 203.0.113.111 nud failed dev dummy0"
2332 run_cmd "$IP neigh add 203.0.113.255 nud failed dev dummy0"
2334 run_cmd "$IP neigh get 203.0.113.111 dev dummy0"
2335 run_cmd "$IP neigh get 203.0.113.255 dev dummy0"
2337 run_cmd "$IP address add 203.0.113.1/24 broadcast 203.0.113.111 dev dummy0"
2340 run_cmd "$IP neigh get 192.0.2.111 dev dummy0"
2341 log_test $? 0 "Resolved neighbour for broadcast address"
2343 run_cmd "$IP neigh get 192.0.2.255 dev dummy0"
2344 log_test $? 0 "Resolved neighbour for network broadcast address"
2346 run_cmd "$IP neigh get 203.0.113.111 dev dummy0"
2347 log_test $? 2 "Unresolved neighbour for broadcast address"
2349 run_cmd "$IP neigh get 203.0.113.255 dev dummy0"
2350 log_test $? 2 "Unresolved neighbour for network broadcast address"
2355 ################################################################################
2361 usage: ${0##*/} OPTS
2363 -t <test> Test(s) to run (default: all)
2366 -P Pause after each test before cleanup
2367 -v verbose mode (show commands and output)
2371 ################################################################################
2376 while getopts :t:pPhv o
2380 p) PAUSE_ON_FAIL=yes;;
2382 v) VERBOSE=$(($VERBOSE + 1));;
2388 PEER_CMD="ip netns exec ${PEER_NS}"
2390 # make sure we don't pause twice
2391 [ "${PAUSE}" = "yes" ] && PAUSE_ON_FAIL=no
2393 if [ "$(id -u)" -ne 0 ];then
2394 echo "SKIP: Need root privileges"
2398 if [ ! -x "$(command -v ip)" ]; then
2399 echo "SKIP: Could not run test without ip tool"
2403 ip route help 2>&1 | grep -q fibmatch
2404 if [ $? -ne 0 ]; then
2405 echo "SKIP: iproute2 too old, missing fibmatch"
2410 cleanup &> /dev/null
2415 fib_unreg_test|unregister) fib_unreg_test;;
2416 fib_down_test|down) fib_down_test;;
2417 fib_carrier_test|carrier) fib_carrier_test;;
2418 fib_rp_filter_test|rp_filter) fib_rp_filter_test;;
2419 fib_nexthop_test|nexthop) fib_nexthop_test;;
2420 fib_notify_test|ipv4_notify) fib_notify_test;;
2421 fib6_notify_test|ipv6_notify) fib6_notify_test;;
2422 fib_suppress_test|suppress) fib_suppress_test;;
2423 ipv6_route_test|ipv6_rt) ipv6_route_test;;
2424 ipv4_route_test|ipv4_rt) ipv4_route_test;;
2425 ipv6_addr_metric) ipv6_addr_metric_test;;
2426 ipv4_addr_metric) ipv4_addr_metric_test;;
2427 ipv4_del_addr) ipv4_del_addr_test;;
2428 ipv6_del_addr) ipv6_del_addr_test;;
2429 ipv6_route_metrics) ipv6_route_metrics_test;;
2430 ipv4_route_metrics) ipv4_route_metrics_test;;
2431 ipv4_route_v6_gw) ipv4_route_v6_gw_test;;
2432 ipv4_mangle) ipv4_mangle_test;;
2433 ipv6_mangle) ipv6_mangle_test;;
2434 ipv4_bcast_neigh) ipv4_bcast_neigh_test;;
2435 fib6_gc_test|ipv6_gc) fib6_gc_test;;
2437 help) echo "Test names: $TESTS"; exit 0;;
2441 if [ "$TESTS" != "none" ]; then
2442 printf "\nTests passed: %3d\n" ${nsuccess}
2443 printf "Tests failed: %3d\n" ${nfail}