2697 lines · bash
1#!/bin/bash2# SPDX-License-Identifier: GPL-2.03 4# This test is for checking IPv4 and IPv6 FIB behavior in response to5# different events.6source lib.sh7ret=08 9# all tests in this script. Can be overridden with -t option10TESTS="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"15 16VERBOSE=017PAUSE_ON_FAIL=no18PAUSE=no19 20which ping6 > /dev/null 2>&1 && ping6=$(which ping6) || ping6=$(which ping)21 22log_test()23{24 local rc=$125 local expected=$226 local msg="$3"27 28 if [ ${rc} -eq ${expected} ]; then29 printf " TEST: %-60s [ OK ]\n" "${msg}"30 nsuccess=$((nsuccess+1))31 else32 ret=133 nfail=$((nfail+1))34 printf " TEST: %-60s [FAIL]\n" "${msg}"35 if [ "${PAUSE_ON_FAIL}" = "yes" ]; then36 echo37 echo "hit enter to continue, 'q' to quit"38 read a39 [ "$a" = "q" ] && exit 140 fi41 fi42 43 if [ "${PAUSE}" = "yes" ]; then44 echo45 echo "hit enter to continue, 'q' to quit"46 read a47 [ "$a" = "q" ] && exit 148 fi49}50 51setup()52{53 set -e54 setup_ns ns155 IP="$(which ip) -netns $ns1"56 NS_EXEC="$(which ip) netns exec $ns1"57 ip netns exec $ns1 sysctl -qw net.ipv4.ip_forward=158 ip netns exec $ns1 sysctl -qw net.ipv6.conf.all.forwarding=159 60 $IP link add dummy0 type dummy61 $IP link set dev dummy0 up62 $IP address add 198.51.100.1/24 dev dummy063 $IP -6 address add 2001:db8:1::1/64 dev dummy064 set +e65 66}67 68cleanup()69{70 $IP link del dev dummy0 &> /dev/null71 cleanup_ns $ns1 $ns272}73 74get_linklocal()75{76 local dev=$177 local addr78 79 addr=$($IP -6 -br addr show dev ${dev} | \80 awk '{81 for (i = 3; i <= NF; ++i) {82 if ($i ~ /^fe80/)83 print $i84 }85 }'86 )87 addr=${addr/\/*}88 89 [ -z "$addr" ] && return 190 91 echo $addr92 93 return 094}95 96fib_unreg_unicast_test()97{98 echo99 echo "Single path route test"100 101 setup102 103 echo " Start point"104 $IP route get fibmatch 198.51.100.2 &> /dev/null105 log_test $? 0 "IPv4 fibmatch"106 $IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null107 log_test $? 0 "IPv6 fibmatch"108 109 set -e110 $IP link del dev dummy0111 set +e112 113 echo " Nexthop device deleted"114 $IP route get fibmatch 198.51.100.2 &> /dev/null115 log_test $? 2 "IPv4 fibmatch - no route"116 $IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null117 log_test $? 2 "IPv6 fibmatch - no route"118 119 cleanup120}121 122fib_unreg_multipath_test()123{124 125 echo126 echo "Multipath route test"127 128 setup129 130 set -e131 $IP link add dummy1 type dummy132 $IP link set dev dummy1 up133 $IP address add 192.0.2.1/24 dev dummy1134 $IP -6 address add 2001:db8:2::1/64 dev dummy1135 136 $IP route add 203.0.113.0/24 \137 nexthop via 198.51.100.2 dev dummy0 \138 nexthop via 192.0.2.2 dev dummy1139 $IP -6 route add 2001:db8:3::/64 \140 nexthop via 2001:db8:1::2 dev dummy0 \141 nexthop via 2001:db8:2::2 dev dummy1142 set +e143 144 echo " Start point"145 $IP route get fibmatch 203.0.113.1 &> /dev/null146 log_test $? 0 "IPv4 fibmatch"147 $IP -6 route get fibmatch 2001:db8:3::1 &> /dev/null148 log_test $? 0 "IPv6 fibmatch"149 150 set -e151 $IP link del dev dummy0152 set +e153 154 echo " One nexthop device deleted"155 $IP route get fibmatch 203.0.113.1 &> /dev/null156 log_test $? 2 "IPv4 - multipath route removed on delete"157 158 $IP -6 route get fibmatch 2001:db8:3::1 &> /dev/null159 # In IPv6 we do not flush the entire multipath route.160 log_test $? 0 "IPv6 - multipath down to single path"161 162 set -e163 $IP link del dev dummy1164 set +e165 166 echo " Second nexthop device deleted"167 $IP -6 route get fibmatch 2001:db8:3::1 &> /dev/null168 log_test $? 2 "IPv6 - no route"169 170 cleanup171}172 173fib_unreg_test()174{175 fib_unreg_unicast_test176 fib_unreg_multipath_test177}178 179fib_down_unicast_test()180{181 echo182 echo "Single path, admin down"183 184 setup185 186 echo " Start point"187 $IP route get fibmatch 198.51.100.2 &> /dev/null188 log_test $? 0 "IPv4 fibmatch"189 $IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null190 log_test $? 0 "IPv6 fibmatch"191 192 set -e193 $IP link set dev dummy0 down194 set +e195 196 echo " Route deleted on down"197 $IP route get fibmatch 198.51.100.2 &> /dev/null198 log_test $? 2 "IPv4 fibmatch"199 $IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null200 log_test $? 2 "IPv6 fibmatch"201 202 cleanup203}204 205fib_down_multipath_test_do()206{207 local down_dev=$1208 local up_dev=$2209 210 $IP route get fibmatch 203.0.113.1 \211 oif $down_dev &> /dev/null212 log_test $? 2 "IPv4 fibmatch on down device"213 $IP -6 route get fibmatch 2001:db8:3::1 \214 oif $down_dev &> /dev/null215 log_test $? 2 "IPv6 fibmatch on down device"216 217 $IP route get fibmatch 203.0.113.1 \218 oif $up_dev &> /dev/null219 log_test $? 0 "IPv4 fibmatch on up device"220 $IP -6 route get fibmatch 2001:db8:3::1 \221 oif $up_dev &> /dev/null222 log_test $? 0 "IPv6 fibmatch on up device"223 224 $IP route get fibmatch 203.0.113.1 | \225 grep $down_dev | grep -q "dead linkdown"226 log_test $? 0 "IPv4 flags on down device"227 $IP -6 route get fibmatch 2001:db8:3::1 | \228 grep $down_dev | grep -q "dead linkdown"229 log_test $? 0 "IPv6 flags on down device"230 231 $IP route get fibmatch 203.0.113.1 | \232 grep $up_dev | grep -q "dead linkdown"233 log_test $? 1 "IPv4 flags on up device"234 $IP -6 route get fibmatch 2001:db8:3::1 | \235 grep $up_dev | grep -q "dead linkdown"236 log_test $? 1 "IPv6 flags on up device"237}238 239fib_down_multipath_test()240{241 echo242 echo "Admin down multipath"243 244 setup245 246 set -e247 $IP link add dummy1 type dummy248 $IP link set dev dummy1 up249 250 $IP address add 192.0.2.1/24 dev dummy1251 $IP -6 address add 2001:db8:2::1/64 dev dummy1252 253 $IP route add 203.0.113.0/24 \254 nexthop via 198.51.100.2 dev dummy0 \255 nexthop via 192.0.2.2 dev dummy1256 $IP -6 route add 2001:db8:3::/64 \257 nexthop via 2001:db8:1::2 dev dummy0 \258 nexthop via 2001:db8:2::2 dev dummy1259 set +e260 261 echo " Verify start point"262 $IP route get fibmatch 203.0.113.1 &> /dev/null263 log_test $? 0 "IPv4 fibmatch"264 265 $IP -6 route get fibmatch 2001:db8:3::1 &> /dev/null266 log_test $? 0 "IPv6 fibmatch"267 268 set -e269 $IP link set dev dummy0 down270 set +e271 272 echo " One device down, one up"273 fib_down_multipath_test_do "dummy0" "dummy1"274 275 set -e276 $IP link set dev dummy0 up277 $IP link set dev dummy1 down278 set +e279 280 echo " Other device down and up"281 fib_down_multipath_test_do "dummy1" "dummy0"282 283 set -e284 $IP link set dev dummy0 down285 set +e286 287 echo " Both devices down"288 $IP route get fibmatch 203.0.113.1 &> /dev/null289 log_test $? 2 "IPv4 fibmatch"290 $IP -6 route get fibmatch 2001:db8:3::1 &> /dev/null291 log_test $? 2 "IPv6 fibmatch"292 293 $IP link del dev dummy1294 cleanup295}296 297fib_down_test()298{299 fib_down_unicast_test300 fib_down_multipath_test301}302 303# Local routes should not be affected when carrier changes.304fib_carrier_local_test()305{306 echo307 echo "Local carrier tests - single path"308 309 setup310 311 set -e312 $IP link set dev dummy0 carrier on313 set +e314 315 echo " Start point"316 $IP route get fibmatch 198.51.100.1 &> /dev/null317 log_test $? 0 "IPv4 fibmatch"318 $IP -6 route get fibmatch 2001:db8:1::1 &> /dev/null319 log_test $? 0 "IPv6 fibmatch"320 321 $IP route get fibmatch 198.51.100.1 | \322 grep -q "linkdown"323 log_test $? 1 "IPv4 - no linkdown flag"324 $IP -6 route get fibmatch 2001:db8:1::1 | \325 grep -q "linkdown"326 log_test $? 1 "IPv6 - no linkdown flag"327 328 set -e329 $IP link set dev dummy0 carrier off330 sleep 1331 set +e332 333 echo " Carrier off on nexthop"334 $IP route get fibmatch 198.51.100.1 &> /dev/null335 log_test $? 0 "IPv4 fibmatch"336 $IP -6 route get fibmatch 2001:db8:1::1 &> /dev/null337 log_test $? 0 "IPv6 fibmatch"338 339 $IP route get fibmatch 198.51.100.1 | \340 grep -q "linkdown"341 log_test $? 1 "IPv4 - linkdown flag set"342 $IP -6 route get fibmatch 2001:db8:1::1 | \343 grep -q "linkdown"344 log_test $? 1 "IPv6 - linkdown flag set"345 346 set -e347 $IP address add 192.0.2.1/24 dev dummy0348 $IP -6 address add 2001:db8:2::1/64 dev dummy0349 set +e350 351 echo " Route to local address with carrier down"352 $IP route get fibmatch 192.0.2.1 &> /dev/null353 log_test $? 0 "IPv4 fibmatch"354 $IP -6 route get fibmatch 2001:db8:2::1 &> /dev/null355 log_test $? 0 "IPv6 fibmatch"356 357 $IP route get fibmatch 192.0.2.1 | \358 grep -q "linkdown"359 log_test $? 1 "IPv4 linkdown flag set"360 $IP -6 route get fibmatch 2001:db8:2::1 | \361 grep -q "linkdown"362 log_test $? 1 "IPv6 linkdown flag set"363 364 cleanup365}366 367fib_carrier_unicast_test()368{369 ret=0370 371 echo372 echo "Single path route carrier test"373 374 setup375 376 set -e377 $IP link set dev dummy0 carrier on378 set +e379 380 echo " Start point"381 $IP route get fibmatch 198.51.100.2 &> /dev/null382 log_test $? 0 "IPv4 fibmatch"383 $IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null384 log_test $? 0 "IPv6 fibmatch"385 386 $IP route get fibmatch 198.51.100.2 | \387 grep -q "linkdown"388 log_test $? 1 "IPv4 no linkdown flag"389 $IP -6 route get fibmatch 2001:db8:1::2 | \390 grep -q "linkdown"391 log_test $? 1 "IPv6 no linkdown flag"392 393 set -e394 $IP link set dev dummy0 carrier off395 sleep 1396 set +e397 398 echo " Carrier down"399 $IP route get fibmatch 198.51.100.2 &> /dev/null400 log_test $? 0 "IPv4 fibmatch"401 $IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null402 log_test $? 0 "IPv6 fibmatch"403 404 $IP route get fibmatch 198.51.100.2 | \405 grep -q "linkdown"406 log_test $? 0 "IPv4 linkdown flag set"407 $IP -6 route get fibmatch 2001:db8:1::2 | \408 grep -q "linkdown"409 log_test $? 0 "IPv6 linkdown flag set"410 411 set -e412 $IP address add 192.0.2.1/24 dev dummy0413 $IP -6 address add 2001:db8:2::1/64 dev dummy0414 set +e415 416 echo " Second address added with carrier down"417 $IP route get fibmatch 192.0.2.2 &> /dev/null418 log_test $? 0 "IPv4 fibmatch"419 $IP -6 route get fibmatch 2001:db8:2::2 &> /dev/null420 log_test $? 0 "IPv6 fibmatch"421 422 $IP route get fibmatch 192.0.2.2 | \423 grep -q "linkdown"424 log_test $? 0 "IPv4 linkdown flag set"425 $IP -6 route get fibmatch 2001:db8:2::2 | \426 grep -q "linkdown"427 log_test $? 0 "IPv6 linkdown flag set"428 429 cleanup430}431 432fib_carrier_test()433{434 fib_carrier_local_test435 fib_carrier_unicast_test436}437 438fib_rp_filter_test()439{440 echo441 echo "IPv4 rp_filter tests"442 443 setup444 445 set -e446 setup_ns ns2447 448 $IP link add name veth1 type veth peer name veth2449 $IP link set dev veth2 netns $ns2450 $IP address add 192.0.2.1/24 dev veth1451 ip -netns $ns2 address add 192.0.2.1/24 dev veth2452 $IP link set dev veth1 up453 ip -netns $ns2 link set dev veth2 up454 455 $IP link set dev lo address 52:54:00:6a:c7:5e456 $IP link set dev veth1 address 52:54:00:6a:c7:5e457 ip -netns $ns2 link set dev lo address 52:54:00:6a:c7:5e458 ip -netns $ns2 link set dev veth2 address 52:54:00:6a:c7:5e459 460 # 1. (ns2) redirect lo's egress to veth2's egress461 ip netns exec $ns2 tc qdisc add dev lo parent root handle 1: fq_codel462 ip netns exec $ns2 tc filter add dev lo parent 1: protocol arp basic \463 action mirred egress redirect dev veth2464 ip netns exec $ns2 tc filter add dev lo parent 1: protocol ip basic \465 action mirred egress redirect dev veth2466 467 # 2. (ns1) redirect veth1's ingress to lo's ingress468 $NS_EXEC tc qdisc add dev veth1 ingress469 $NS_EXEC tc filter add dev veth1 ingress protocol arp basic \470 action mirred ingress redirect dev lo471 $NS_EXEC tc filter add dev veth1 ingress protocol ip basic \472 action mirred ingress redirect dev lo473 474 # 3. (ns1) redirect lo's egress to veth1's egress475 $NS_EXEC tc qdisc add dev lo parent root handle 1: fq_codel476 $NS_EXEC tc filter add dev lo parent 1: protocol arp basic \477 action mirred egress redirect dev veth1478 $NS_EXEC tc filter add dev lo parent 1: protocol ip basic \479 action mirred egress redirect dev veth1480 481 # 4. (ns2) redirect veth2's ingress to lo's ingress482 ip netns exec $ns2 tc qdisc add dev veth2 ingress483 ip netns exec $ns2 tc filter add dev veth2 ingress protocol arp basic \484 action mirred ingress redirect dev lo485 ip netns exec $ns2 tc filter add dev veth2 ingress protocol ip basic \486 action mirred ingress redirect dev lo487 488 $NS_EXEC sysctl -qw net.ipv4.conf.all.rp_filter=1489 $NS_EXEC sysctl -qw net.ipv4.conf.all.accept_local=1490 $NS_EXEC sysctl -qw net.ipv4.conf.all.route_localnet=1491 ip netns exec $ns2 sysctl -qw net.ipv4.conf.all.rp_filter=1492 ip netns exec $ns2 sysctl -qw net.ipv4.conf.all.accept_local=1493 ip netns exec $ns2 sysctl -qw net.ipv4.conf.all.route_localnet=1494 set +e495 496 run_cmd "ip netns exec $ns2 ping -w1 -c1 192.0.2.1"497 log_test $? 0 "rp_filter passes local packets"498 499 run_cmd "ip netns exec $ns2 ping -w1 -c1 127.0.0.1"500 log_test $? 0 "rp_filter passes loopback packets"501 502 cleanup503}504 505################################################################################506# Tests on nexthop spec507 508# run 'ip route add' with given spec509add_rt()510{511 local desc="$1"512 local erc=$2513 local vrf=$3514 local pfx=$4515 local gw=$5516 local dev=$6517 local cmd out rc518 519 [ "$vrf" = "-" ] && vrf="default"520 [ -n "$gw" ] && gw="via $gw"521 [ -n "$dev" ] && dev="dev $dev"522 523 cmd="$IP route add vrf $vrf $pfx $gw $dev"524 if [ "$VERBOSE" = "1" ]; then525 printf "\n COMMAND: $cmd\n"526 fi527 528 out=$(eval $cmd 2>&1)529 rc=$?530 if [ "$VERBOSE" = "1" -a -n "$out" ]; then531 echo " $out"532 fi533 log_test $rc $erc "$desc"534}535 536fib4_nexthop()537{538 echo539 echo "IPv4 nexthop tests"540 541 echo "<<< write me >>>"542}543 544fib6_nexthop()545{546 local lldummy=$(get_linklocal dummy0)547 local llv1=$(get_linklocal dummy0)548 549 if [ -z "$lldummy" ]; then550 echo "Failed to get linklocal address for dummy0"551 return 1552 fi553 if [ -z "$llv1" ]; then554 echo "Failed to get linklocal address for veth1"555 return 1556 fi557 558 echo559 echo "IPv6 nexthop tests"560 561 add_rt "Directly connected nexthop, unicast address" 0 \562 - 2001:db8:101::/64 2001:db8:1::2563 add_rt "Directly connected nexthop, unicast address with device" 0 \564 - 2001:db8:102::/64 2001:db8:1::2 "dummy0"565 add_rt "Gateway is linklocal address" 0 \566 - 2001:db8:103::1/64 $llv1 "veth0"567 568 # fails because LL address requires a device569 add_rt "Gateway is linklocal address, no device" 2 \570 - 2001:db8:104::1/64 $llv1571 572 # local address can not be a gateway573 add_rt "Gateway can not be local unicast address" 2 \574 - 2001:db8:105::/64 2001:db8:1::1575 add_rt "Gateway can not be local unicast address, with device" 2 \576 - 2001:db8:106::/64 2001:db8:1::1 "dummy0"577 add_rt "Gateway can not be a local linklocal address" 2 \578 - 2001:db8:107::1/64 $lldummy "dummy0"579 580 # VRF tests581 add_rt "Gateway can be local address in a VRF" 0 \582 - 2001:db8:108::/64 2001:db8:51::2583 add_rt "Gateway can be local address in a VRF, with device" 0 \584 - 2001:db8:109::/64 2001:db8:51::2 "veth0"585 add_rt "Gateway can be local linklocal address in a VRF" 0 \586 - 2001:db8:110::1/64 $llv1 "veth0"587 588 add_rt "Redirect to VRF lookup" 0 \589 - 2001:db8:111::/64 "" "red"590 591 add_rt "VRF route, gateway can be local address in default VRF" 0 \592 red 2001:db8:112::/64 2001:db8:51::1593 594 # local address in same VRF fails595 add_rt "VRF route, gateway can not be a local address" 2 \596 red 2001:db8:113::1/64 2001:db8:2::1597 add_rt "VRF route, gateway can not be a local addr with device" 2 \598 red 2001:db8:114::1/64 2001:db8:2::1 "dummy1"599}600 601# Default VRF:602# dummy0 - 198.51.100.1/24 2001:db8:1::1/64603# veth0 - 192.0.2.1/24 2001:db8:51::1/64604#605# VRF red:606# dummy1 - 192.168.2.1/24 2001:db8:2::1/64607# veth1 - 192.0.2.2/24 2001:db8:51::2/64608#609# [ dummy0 veth0 ]--[ veth1 dummy1 ]610 611fib_nexthop_test()612{613 setup614 615 set -e616 617 $IP -4 rule add pref 32765 table local618 $IP -4 rule del pref 0619 $IP -6 rule add pref 32765 table local620 $IP -6 rule del pref 0621 622 $IP link add red type vrf table 1623 $IP link set red up624 $IP -4 route add vrf red unreachable default metric 4278198272625 $IP -6 route add vrf red unreachable default metric 4278198272626 627 $IP link add veth0 type veth peer name veth1628 $IP link set dev veth0 up629 $IP address add 192.0.2.1/24 dev veth0630 $IP -6 address add 2001:db8:51::1/64 dev veth0631 632 $IP link set dev veth1 vrf red up633 $IP address add 192.0.2.2/24 dev veth1634 $IP -6 address add 2001:db8:51::2/64 dev veth1635 636 $IP link add dummy1 type dummy637 $IP link set dev dummy1 vrf red up638 $IP address add 192.168.2.1/24 dev dummy1639 $IP -6 address add 2001:db8:2::1/64 dev dummy1640 set +e641 642 sleep 1643 fib4_nexthop644 fib6_nexthop645 646 (647 $IP link del dev dummy1648 $IP link del veth0649 $IP link del red650 ) 2>/dev/null651 cleanup652}653 654fib6_notify_test()655{656 setup657 658 echo659 echo "Fib6 info length calculation in route notify test"660 set -e661 662 for i in 10 20 30 40 50 60 70;663 do664 $IP link add dummy_$i type dummy665 $IP link set dev dummy_$i up666 $IP -6 address add 2001:$i::1/64 dev dummy_$i667 done668 669 $NS_EXEC ip monitor route &> errors.txt &670 sleep 2671 672 $IP -6 route add 2001::/64 \673 nexthop via 2001:10::2 dev dummy_10 \674 nexthop encap ip6 dst 2002::20 via 2001:20::2 dev dummy_20 \675 nexthop encap ip6 dst 2002::30 via 2001:30::2 dev dummy_30 \676 nexthop encap ip6 dst 2002::40 via 2001:40::2 dev dummy_40 \677 nexthop encap ip6 dst 2002::50 via 2001:50::2 dev dummy_50 \678 nexthop encap ip6 dst 2002::60 via 2001:60::2 dev dummy_60 \679 nexthop encap ip6 dst 2002::70 via 2001:70::2 dev dummy_70680 681 set +e682 683 err=`cat errors.txt |grep "Message too long"`684 if [ -z "$err" ];then685 ret=0686 else687 ret=1688 fi689 690 log_test $ret 0 "ipv6 route add notify"691 692 { kill %% && wait %%; } 2>/dev/null693 694 #rm errors.txt695 696 cleanup &> /dev/null697}698 699 700fib_notify_test()701{702 setup703 704 echo705 echo "Fib4 info length calculation in route notify test"706 707 set -e708 709 for i in 10 20 30 40 50 60 70;710 do711 $IP link add dummy_$i type dummy712 $IP link set dev dummy_$i up713 $IP address add 20.20.$i.2/24 dev dummy_$i714 done715 716 $NS_EXEC ip monitor route &> errors.txt &717 sleep 2718 719 $IP route add 10.0.0.0/24 \720 nexthop via 20.20.10.1 dev dummy_10 \721 nexthop encap ip dst 192.168.10.20 via 20.20.20.1 dev dummy_20 \722 nexthop encap ip dst 192.168.10.30 via 20.20.30.1 dev dummy_30 \723 nexthop encap ip dst 192.168.10.40 via 20.20.40.1 dev dummy_40 \724 nexthop encap ip dst 192.168.10.50 via 20.20.50.1 dev dummy_50 \725 nexthop encap ip dst 192.168.10.60 via 20.20.60.1 dev dummy_60 \726 nexthop encap ip dst 192.168.10.70 via 20.20.70.1 dev dummy_70727 728 set +e729 730 err=`cat errors.txt |grep "Message too long"`731 if [ -z "$err" ];then732 ret=0733 else734 ret=1735 fi736 737 log_test $ret 0 "ipv4 route add notify"738 739 { kill %% && wait %%; } 2>/dev/null740 741 rm errors.txt742 743 cleanup &> /dev/null744}745 746# Create a new dummy_10 to remove all associated routes.747reset_dummy_10()748{749 $IP link del dev dummy_10750 751 $IP link add dummy_10 type dummy752 $IP link set dev dummy_10 up753 $IP -6 address add 2001:10::1/64 dev dummy_10754}755 756check_rt_num()757{758 local expected=$1759 local num=$2760 761 if [ $num -ne $expected ]; then762 echo "FAIL: Expected $expected routes, got $num"763 ret=1764 else765 ret=0766 fi767}768 769check_rt_num_clean()770{771 local expected=$1772 local num=$2773 774 if [ $num -ne $expected ]; then775 log_test 1 0 "expected $expected routes, got $num"776 set +e777 cleanup &> /dev/null778 return 1779 fi780 return 0781}782 783fib6_gc_test()784{785 setup786 787 echo788 echo "Fib6 garbage collection test"789 set -e790 791 EXPIRE=5792 GC_WAIT_TIME=$((EXPIRE * 2 + 2))793 794 # Check expiration of routes every $EXPIRE seconds (GC)795 $NS_EXEC sysctl -wq net.ipv6.route.gc_interval=$EXPIRE796 797 $IP link add dummy_10 type dummy798 $IP link set dev dummy_10 up799 $IP -6 address add 2001:10::1/64 dev dummy_10800 801 $NS_EXEC sysctl -wq net.ipv6.route.flush=1802 803 # Temporary routes804 for i in $(seq 1 5); do805 # Expire route after $EXPIRE seconds806 $IP -6 route add 2001:20::$i \807 via 2001:10::2 dev dummy_10 expires $EXPIRE808 done809 sleep $GC_WAIT_TIME810 $NS_EXEC sysctl -wq net.ipv6.route.flush=1811 check_rt_num 0 $($IP -6 route list |grep expires|wc -l)812 log_test $ret 0 "ipv6 route garbage collection"813 814 reset_dummy_10815 816 # Permanent routes817 for i in $(seq 1 5); do818 $IP -6 route add 2001:30::$i \819 via 2001:10::2 dev dummy_10820 done821 # Temporary routes822 for i in $(seq 1 5); do823 # Expire route after $EXPIRE seconds824 $IP -6 route add 2001:20::$i \825 via 2001:10::2 dev dummy_10 expires $EXPIRE826 done827 # Wait for GC828 sleep $GC_WAIT_TIME829 check_rt_num 0 $($IP -6 route list |grep expires|wc -l)830 log_test $ret 0 "ipv6 route garbage collection (with permanent routes)"831 832 reset_dummy_10833 834 # Permanent routes835 for i in $(seq 1 5); do836 $IP -6 route add 2001:20::$i \837 via 2001:10::2 dev dummy_10838 done839 # Replace with temporary routes840 for i in $(seq 1 5); do841 # Expire route after $EXPIRE seconds842 $IP -6 route replace 2001:20::$i \843 via 2001:10::2 dev dummy_10 expires $EXPIRE844 done845 # Wait for GC846 sleep $GC_WAIT_TIME847 check_rt_num 0 $($IP -6 route list |grep expires|wc -l)848 log_test $ret 0 "ipv6 route garbage collection (replace with expires)"849 850 reset_dummy_10851 852 # Temporary routes853 for i in $(seq 1 5); do854 # Expire route after $EXPIRE seconds855 $IP -6 route add 2001:20::$i \856 via 2001:10::2 dev dummy_10 expires $EXPIRE857 done858 # Replace with permanent routes859 for i in $(seq 1 5); do860 $IP -6 route replace 2001:20::$i \861 via 2001:10::2 dev dummy_10862 done863 check_rt_num_clean 0 $($IP -6 route list |grep expires|wc -l) || return864 865 # Wait for GC866 sleep $GC_WAIT_TIME867 check_rt_num 5 $($IP -6 route list |grep -v expires|grep 2001:20::|wc -l)868 log_test $ret 0 "ipv6 route garbage collection (replace with permanent)"869 870 # ra6 is required for the next test. (ipv6toolkit)871 if [ ! -x "$(command -v ra6)" ]; then872 echo "SKIP: ra6 not found."873 set +e874 cleanup &> /dev/null875 return876 fi877 878 # Delete dummy_10 and remove all routes879 $IP link del dev dummy_10880 881 # Create a pair of veth devices to send a RA message from one882 # device to another.883 $IP link add veth1 type veth peer name veth2884 $IP link set dev veth1 up885 $IP link set dev veth2 up886 $IP -6 address add 2001:10::1/64 dev veth1 nodad887 $IP -6 address add 2001:10::2/64 dev veth2 nodad888 889 # Make veth1 ready to receive RA messages.890 $NS_EXEC sysctl -wq net.ipv6.conf.veth1.accept_ra=2891 892 # Send a RA message with a route from veth2 to veth1.893 $NS_EXEC ra6 -i veth2 -d 2001:10::1 -t $EXPIRE894 895 # Wait for the RA message.896 sleep 1897 898 # systemd may mess up the test. You syould make sure that899 # systemd-networkd.service and systemd-networkd.socket are stopped.900 check_rt_num_clean 1 $($IP -6 route list|grep expires|wc -l) || return901 902 # Wait for GC903 sleep $GC_WAIT_TIME904 check_rt_num 0 $($IP -6 route list |grep expires|wc -l)905 log_test $ret 0 "ipv6 route garbage collection (RA message)"906 907 set +e908 909 cleanup &> /dev/null910}911 912fib_suppress_test()913{914 echo915 echo "FIB rule with suppress_prefixlength"916 setup917 918 $IP link add dummy1 type dummy919 $IP link set dummy1 up920 $IP -6 route add default dev dummy1921 $IP -6 rule add table main suppress_prefixlength 0922 ping -f -c 1000 -W 1 1234::1 >/dev/null 2>&1923 $IP -6 rule del table main suppress_prefixlength 0924 $IP link del dummy1925 926 # If we got here without crashing, we're good.927 log_test 0 0 "FIB rule suppress test"928 929 cleanup930}931 932################################################################################933# Tests on route add and replace934 935run_cmd()936{937 local cmd="$1"938 local out939 local stderr="2>/dev/null"940 941 if [ "$VERBOSE" = "1" ]; then942 printf " COMMAND: $cmd\n"943 stderr=944 fi945 946 out=$(eval $cmd $stderr)947 rc=$?948 if [ "$VERBOSE" = "1" -a -n "$out" ]; then949 echo " $out"950 fi951 952 [ "$VERBOSE" = "1" ] && echo953 954 return $rc955}956 957check_expected()958{959 local out="$1"960 local expected="$2"961 local rc=0962 963 [ "${out}" = "${expected}" ] && return 0964 965 if [ -z "${out}" ]; then966 if [ "$VERBOSE" = "1" ]; then967 printf "\nNo route entry found\n"968 printf "Expected:\n"969 printf " ${expected}\n"970 fi971 return 1972 fi973 974 # tricky way to convert output to 1-line without ip's975 # messy '\'; this drops all extra white space976 out=$(echo ${out})977 if [ "${out}" != "${expected}" ]; then978 rc=1979 if [ "${VERBOSE}" = "1" ]; then980 printf " Unexpected route entry. Have:\n"981 printf " ${out}\n"982 printf " Expected:\n"983 printf " ${expected}\n\n"984 fi985 fi986 987 return $rc988}989 990# add route for a prefix, flushing any existing routes first991# expected to be the first step of a test992add_route6()993{994 local pfx="$1"995 local nh="$2"996 local out997 998 if [ "$VERBOSE" = "1" ]; then999 echo1000 echo " ##################################################"1001 echo1002 fi1003 1004 run_cmd "$IP -6 ro flush ${pfx}"1005 [ $? -ne 0 ] && exit 11006 1007 out=$($IP -6 ro ls match ${pfx})1008 if [ -n "$out" ]; then1009 echo "Failed to flush routes for prefix used for tests."1010 exit 11011 fi1012 1013 run_cmd "$IP -6 ro add ${pfx} ${nh}"1014 if [ $? -ne 0 ]; then1015 echo "Failed to add initial route for test."1016 exit 11017 fi1018}1019 1020# add initial route - used in replace route tests1021add_initial_route6()1022{1023 add_route6 "2001:db8:104::/64" "$1"1024}1025 1026check_route6()1027{1028 local pfx1029 local expected="$1"1030 local out1031 local rc=01032 1033 set -- $expected1034 pfx=$11035 1036 out=$($IP -6 ro ls match ${pfx} | sed -e 's/ pref medium//')1037 check_expected "${out}" "${expected}"1038}1039 1040route_cleanup()1041{1042 $IP li del red 2>/dev/null1043 $IP li del dummy1 2>/dev/null1044 $IP li del veth1 2>/dev/null1045 $IP li del veth3 2>/dev/null1046 1047 cleanup &> /dev/null1048}1049 1050route_setup()1051{1052 route_cleanup1053 setup1054 1055 [ "${VERBOSE}" = "1" ] && set -x1056 set -e1057 1058 setup_ns ns21059 ip netns exec $ns2 sysctl -qw net.ipv4.ip_forward=11060 ip netns exec $ns2 sysctl -qw net.ipv6.conf.all.forwarding=11061 1062 $IP li add veth1 type veth peer name veth21063 $IP li add veth3 type veth peer name veth41064 1065 $IP li set veth1 up1066 $IP li set veth3 up1067 $IP li set veth2 netns $ns2 up1068 $IP li set veth4 netns $ns2 up1069 ip -netns $ns2 li add dummy1 type dummy1070 ip -netns $ns2 li set dummy1 up1071 1072 $IP -6 addr add 2001:db8:101::1/64 dev veth1 nodad1073 $IP -6 addr add 2001:db8:103::1/64 dev veth3 nodad1074 $IP addr add 172.16.101.1/24 dev veth11075 $IP addr add 172.16.103.1/24 dev veth31076 1077 ip -netns $ns2 -6 addr add 2001:db8:101::2/64 dev veth2 nodad1078 ip -netns $ns2 -6 addr add 2001:db8:103::2/64 dev veth4 nodad1079 ip -netns $ns2 -6 addr add 2001:db8:104::1/64 dev dummy1 nodad1080 1081 ip -netns $ns2 addr add 172.16.101.2/24 dev veth21082 ip -netns $ns2 addr add 172.16.103.2/24 dev veth41083 ip -netns $ns2 addr add 172.16.104.1/24 dev dummy11084 1085 set +e1086}1087 1088# assumption is that basic add of a single path route works1089# otherwise just adding an address on an interface is broken1090ipv6_rt_add()1091{1092 local rc1093 1094 echo1095 echo "IPv6 route add / append tests"1096 1097 # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL1098 add_route6 "2001:db8:104::/64" "via 2001:db8:101::2"1099 run_cmd "$IP -6 ro add 2001:db8:104::/64 via 2001:db8:103::2"1100 log_test $? 2 "Attempt to add duplicate route - gw"1101 1102 # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL1103 add_route6 "2001:db8:104::/64" "via 2001:db8:101::2"1104 run_cmd "$IP -6 ro add 2001:db8:104::/64 dev veth3"1105 log_test $? 2 "Attempt to add duplicate route - dev only"1106 1107 # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL1108 add_route6 "2001:db8:104::/64" "via 2001:db8:101::2"1109 run_cmd "$IP -6 ro add unreachable 2001:db8:104::/64"1110 log_test $? 2 "Attempt to add duplicate route - reject route"1111 1112 # route append with same prefix adds a new route1113 # - iproute2 sets NLM_F_CREATE | NLM_F_APPEND1114 add_route6 "2001:db8:104::/64" "via 2001:db8:101::2"1115 run_cmd "$IP -6 ro append 2001:db8:104::/64 via 2001:db8:103::2"1116 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"1117 log_test $? 0 "Append nexthop to existing route - gw"1118 1119 # insert mpath directly1120 add_route6 "2001:db8:104::/64" "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"1121 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"1122 log_test $? 0 "Add multipath route"1123 1124 add_route6 "2001:db8:104::/64" "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"1125 run_cmd "$IP -6 ro add 2001:db8:104::/64 nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"1126 log_test $? 2 "Attempt to add duplicate multipath route"1127 1128 # insert of a second route without append but different metric1129 add_route6 "2001:db8:104::/64" "via 2001:db8:101::2"1130 run_cmd "$IP -6 ro add 2001:db8:104::/64 via 2001:db8:103::2 metric 512"1131 rc=$?1132 if [ $rc -eq 0 ]; then1133 run_cmd "$IP -6 ro add 2001:db8:104::/64 via 2001:db8:103::3 metric 256"1134 rc=$?1135 fi1136 log_test $rc 0 "Route add with different metrics"1137 1138 run_cmd "$IP -6 ro del 2001:db8:104::/64 metric 512"1139 rc=$?1140 if [ $rc -eq 0 ]; then1141 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"1142 rc=$?1143 fi1144 log_test $rc 0 "Route delete with metric"1145}1146 1147ipv6_rt_replace_single()1148{1149 # single path with single path1150 #1151 add_initial_route6 "via 2001:db8:101::2"1152 run_cmd "$IP -6 ro replace 2001:db8:104::/64 via 2001:db8:103::2"1153 check_route6 "2001:db8:104::/64 via 2001:db8:103::2 dev veth3 metric 1024"1154 log_test $? 0 "Single path with single path"1155 1156 # single path with multipath1157 #1158 add_initial_route6 "nexthop via 2001:db8:101::2"1159 run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:101::3 nexthop via 2001:db8:103::2"1160 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"1161 log_test $? 0 "Single path with multipath"1162 1163 # single path with single path using MULTIPATH attribute1164 #1165 add_initial_route6 "via 2001:db8:101::2"1166 run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:103::2"1167 check_route6 "2001:db8:104::/64 via 2001:db8:103::2 dev veth3 metric 1024"1168 log_test $? 0 "Single path with single path via multipath attribute"1169 1170 # route replace fails - invalid nexthop1171 add_initial_route6 "via 2001:db8:101::2"1172 run_cmd "$IP -6 ro replace 2001:db8:104::/64 via 2001:db8:104::2"1173 if [ $? -eq 0 ]; then1174 # previous command is expected to fail so if it returns 01175 # that means the test failed.1176 log_test 0 1 "Invalid nexthop"1177 else1178 check_route6 "2001:db8:104::/64 via 2001:db8:101::2 dev veth1 metric 1024"1179 log_test $? 0 "Invalid nexthop"1180 fi1181 1182 # replace non-existent route1183 # - note use of change versus replace since ip adds NLM_F_CREATE1184 # for replace1185 add_initial_route6 "via 2001:db8:101::2"1186 run_cmd "$IP -6 ro change 2001:db8:105::/64 via 2001:db8:101::2"1187 log_test $? 2 "Single path - replace of non-existent route"1188}1189 1190ipv6_rt_replace_mpath()1191{1192 # multipath with multipath1193 add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"1194 run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:101::3 nexthop via 2001:db8:103::3"1195 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"1196 log_test $? 0 "Multipath with multipath"1197 1198 # multipath with single1199 add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"1200 run_cmd "$IP -6 ro replace 2001:db8:104::/64 via 2001:db8:101::3"1201 check_route6 "2001:db8:104::/64 via 2001:db8:101::3 dev veth1 metric 1024"1202 log_test $? 0 "Multipath with single path"1203 1204 # multipath with single1205 add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"1206 run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:101::3"1207 check_route6 "2001:db8:104::/64 via 2001:db8:101::3 dev veth1 metric 1024"1208 log_test $? 0 "Multipath with single path via multipath attribute"1209 1210 # multipath with dev-only1211 add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"1212 run_cmd "$IP -6 ro replace 2001:db8:104::/64 dev veth1"1213 check_route6 "2001:db8:104::/64 dev veth1 metric 1024"1214 log_test $? 0 "Multipath with dev-only"1215 1216 # route replace fails - invalid nexthop 11217 add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"1218 run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:111::3 nexthop via 2001:db8:103::3"1219 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"1220 log_test $? 0 "Multipath - invalid first nexthop"1221 1222 # route replace fails - invalid nexthop 21223 add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"1224 run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:101::3 nexthop via 2001:db8:113::3"1225 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"1226 log_test $? 0 "Multipath - invalid second nexthop"1227 1228 # multipath non-existent route1229 add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"1230 run_cmd "$IP -6 ro change 2001:db8:105::/64 nexthop via 2001:db8:101::3 nexthop via 2001:db8:103::3"1231 log_test $? 2 "Multipath - replace of non-existent route"1232}1233 1234ipv6_rt_replace()1235{1236 echo1237 echo "IPv6 route replace tests"1238 1239 ipv6_rt_replace_single1240 ipv6_rt_replace_mpath1241}1242 1243ipv6_rt_dsfield()1244{1245 echo1246 echo "IPv6 route with dsfield tests"1247 1248 run_cmd "$IP -6 route flush 2001:db8:102::/64"1249 1250 # IPv6 doesn't support routing based on dsfield1251 run_cmd "$IP -6 route add 2001:db8:102::/64 dsfield 0x04 via 2001:db8:101::2"1252 log_test $? 2 "Reject route with dsfield"1253}1254 1255ipv6_route_test()1256{1257 route_setup1258 1259 ipv6_rt_add1260 ipv6_rt_replace1261 ipv6_rt_dsfield1262 1263 route_cleanup1264}1265 1266ip_addr_metric_check()1267{1268 ip addr help 2>&1 | grep -q metric1269 if [ $? -ne 0 ]; then1270 echo "iproute2 command does not support metric for addresses. Skipping test"1271 return 11272 fi1273 1274 return 01275}1276 1277ipv6_addr_metric_test()1278{1279 local rc1280 1281 echo1282 echo "IPv6 prefix route tests"1283 1284 ip_addr_metric_check || return 11285 1286 setup1287 1288 set -e1289 $IP li add dummy1 type dummy1290 $IP li add dummy2 type dummy1291 $IP li set dummy1 up1292 $IP li set dummy2 up1293 1294 # default entry is metric 2561295 run_cmd "$IP -6 addr add dev dummy1 2001:db8:104::1/64"1296 run_cmd "$IP -6 addr add dev dummy2 2001:db8:104::2/64"1297 set +e1298 1299 check_route6 "2001:db8:104::/64 dev dummy1 proto kernel metric 256 2001:db8:104::/64 dev dummy2 proto kernel metric 256"1300 log_test $? 0 "Default metric"1301 1302 set -e1303 run_cmd "$IP -6 addr flush dev dummy1"1304 run_cmd "$IP -6 addr add dev dummy1 2001:db8:104::1/64 metric 257"1305 set +e1306 1307 check_route6 "2001:db8:104::/64 dev dummy2 proto kernel metric 256 2001:db8:104::/64 dev dummy1 proto kernel metric 257"1308 log_test $? 0 "User specified metric on first device"1309 1310 set -e1311 run_cmd "$IP -6 addr flush dev dummy2"1312 run_cmd "$IP -6 addr add dev dummy2 2001:db8:104::2/64 metric 258"1313 set +e1314 1315 check_route6 "2001:db8:104::/64 dev dummy1 proto kernel metric 257 2001:db8:104::/64 dev dummy2 proto kernel metric 258"1316 log_test $? 0 "User specified metric on second device"1317 1318 run_cmd "$IP -6 addr del dev dummy1 2001:db8:104::1/64 metric 257"1319 rc=$?1320 if [ $rc -eq 0 ]; then1321 check_route6 "2001:db8:104::/64 dev dummy2 proto kernel metric 258"1322 rc=$?1323 fi1324 log_test $rc 0 "Delete of address on first device"1325 1326 run_cmd "$IP -6 addr change dev dummy2 2001:db8:104::2/64 metric 259"1327 rc=$?1328 if [ $rc -eq 0 ]; then1329 check_route6 "2001:db8:104::/64 dev dummy2 proto kernel metric 259"1330 rc=$?1331 fi1332 log_test $rc 0 "Modify metric of address"1333 1334 # verify prefix route removed on down1335 run_cmd "ip netns exec $ns1 sysctl -qw net.ipv6.conf.all.keep_addr_on_down=1"1336 run_cmd "$IP li set dev dummy2 down"1337 rc=$?1338 if [ $rc -eq 0 ]; then1339 out=$($IP -6 ro ls match 2001:db8:104::/64)1340 check_expected "${out}" ""1341 rc=$?1342 fi1343 log_test $rc 0 "Prefix route removed on link down"1344 1345 # verify prefix route re-inserted with assigned metric1346 run_cmd "$IP li set dev dummy2 up"1347 rc=$?1348 if [ $rc -eq 0 ]; then1349 check_route6 "2001:db8:104::/64 dev dummy2 proto kernel metric 259"1350 rc=$?1351 fi1352 log_test $rc 0 "Prefix route with metric on link up"1353 1354 # verify peer metric added correctly1355 set -e1356 run_cmd "$IP -6 addr flush dev dummy2"1357 run_cmd "$IP -6 addr add dev dummy2 2001:db8:104::1 peer 2001:db8:104::2 metric 260"1358 set +e1359 1360 check_route6 "2001:db8:104::1 dev dummy2 proto kernel metric 260"1361 log_test $? 0 "Set metric with peer route on local side"1362 check_route6 "2001:db8:104::2 dev dummy2 proto kernel metric 260"1363 log_test $? 0 "Set metric with peer route on peer side"1364 1365 set -e1366 run_cmd "$IP -6 addr change dev dummy2 2001:db8:104::1 peer 2001:db8:104::3 metric 261"1367 set +e1368 1369 check_route6 "2001:db8:104::1 dev dummy2 proto kernel metric 261"1370 log_test $? 0 "Modify metric and peer address on local side"1371 check_route6 "2001:db8:104::3 dev dummy2 proto kernel metric 261"1372 log_test $? 0 "Modify metric and peer address on peer side"1373 1374 $IP li del dummy11375 $IP li del dummy21376 cleanup1377}1378 1379ipv6_route_metrics_test()1380{1381 local rc1382 1383 echo1384 echo "IPv6 routes with metrics"1385 1386 route_setup1387 1388 #1389 # single path with metrics1390 #1391 run_cmd "$IP -6 ro add 2001:db8:111::/64 via 2001:db8:101::2 mtu 1400"1392 rc=$?1393 if [ $rc -eq 0 ]; then1394 check_route6 "2001:db8:111::/64 via 2001:db8:101::2 dev veth1 metric 1024 mtu 1400"1395 rc=$?1396 fi1397 log_test $rc 0 "Single path route with mtu metric"1398 1399 1400 #1401 # multipath via separate routes with metrics1402 #1403 run_cmd "$IP -6 ro add 2001:db8:112::/64 via 2001:db8:101::2 mtu 1400"1404 run_cmd "$IP -6 ro append 2001:db8:112::/64 via 2001:db8:103::2"1405 rc=$?1406 if [ $rc -eq 0 ]; then1407 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"1408 rc=$?1409 fi1410 log_test $rc 0 "Multipath route via 2 single routes with mtu metric on first"1411 1412 # second route is coalesced to first to make a multipath route.1413 # MTU of the second path is hidden from display!1414 run_cmd "$IP -6 ro add 2001:db8:113::/64 via 2001:db8:101::2"1415 run_cmd "$IP -6 ro append 2001:db8:113::/64 via 2001:db8:103::2 mtu 1400"1416 rc=$?1417 if [ $rc -eq 0 ]; then1418 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"1419 rc=$?1420 fi1421 log_test $rc 0 "Multipath route via 2 single routes with mtu metric on 2nd"1422 1423 run_cmd "$IP -6 ro del 2001:db8:113::/64 via 2001:db8:101::2"1424 if [ $? -eq 0 ]; then1425 check_route6 "2001:db8:113::/64 via 2001:db8:103::2 dev veth3 metric 1024 mtu 1400"1426 log_test $? 0 " MTU of second leg"1427 fi1428 1429 #1430 # multipath with metrics1431 #1432 run_cmd "$IP -6 ro add 2001:db8:115::/64 mtu 1400 nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"1433 rc=$?1434 if [ $rc -eq 0 ]; then1435 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"1436 rc=$?1437 fi1438 log_test $rc 0 "Multipath route with mtu metric"1439 1440 $IP -6 ro add 2001:db8:104::/64 via 2001:db8:101::2 mtu 13001441 run_cmd "ip netns exec $ns1 ${ping6} -w1 -c1 -s 1500 2001:db8:104::1"1442 log_test $? 0 "Using route with mtu metric"1443 1444 run_cmd "$IP -6 ro add 2001:db8:114::/64 via 2001:db8:101::2 congctl lock foo"1445 log_test $? 2 "Invalid metric (fails metric_convert)"1446 1447 route_cleanup1448}1449 1450# add route for a prefix, flushing any existing routes first1451# expected to be the first step of a test1452add_route()1453{1454 local pfx="$1"1455 local nh="$2"1456 local out1457 1458 if [ "$VERBOSE" = "1" ]; then1459 echo1460 echo " ##################################################"1461 echo1462 fi1463 1464 run_cmd "$IP ro flush ${pfx}"1465 [ $? -ne 0 ] && exit 11466 1467 out=$($IP ro ls match ${pfx})1468 if [ -n "$out" ]; then1469 echo "Failed to flush routes for prefix used for tests."1470 exit 11471 fi1472 1473 run_cmd "$IP ro add ${pfx} ${nh}"1474 if [ $? -ne 0 ]; then1475 echo "Failed to add initial route for test."1476 exit 11477 fi1478}1479 1480# add initial route - used in replace route tests1481add_initial_route()1482{1483 add_route "172.16.104.0/24" "$1"1484}1485 1486check_route()1487{1488 local pfx1489 local expected="$1"1490 local out1491 1492 set -- $expected1493 pfx=$11494 [ "${pfx}" = "unreachable" ] && pfx=$21495 1496 out=$($IP ro ls match ${pfx})1497 check_expected "${out}" "${expected}"1498}1499 1500# assumption is that basic add of a single path route works1501# otherwise just adding an address on an interface is broken1502ipv4_rt_add()1503{1504 local rc1505 1506 echo1507 echo "IPv4 route add / append tests"1508 1509 # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL1510 add_route "172.16.104.0/24" "via 172.16.101.2"1511 run_cmd "$IP ro add 172.16.104.0/24 via 172.16.103.2"1512 log_test $? 2 "Attempt to add duplicate route - gw"1513 1514 # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL1515 add_route "172.16.104.0/24" "via 172.16.101.2"1516 run_cmd "$IP ro add 172.16.104.0/24 dev veth3"1517 log_test $? 2 "Attempt to add duplicate route - dev only"1518 1519 # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL1520 add_route "172.16.104.0/24" "via 172.16.101.2"1521 run_cmd "$IP ro add unreachable 172.16.104.0/24"1522 log_test $? 2 "Attempt to add duplicate route - reject route"1523 1524 # iproute2 prepend only sets NLM_F_CREATE1525 # - adds a new route; does NOT convert existing route to ECMP1526 add_route "172.16.104.0/24" "via 172.16.101.2"1527 run_cmd "$IP ro prepend 172.16.104.0/24 via 172.16.103.2"1528 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"1529 log_test $? 0 "Add new nexthop for existing prefix"1530 1531 # route append with same prefix adds a new route1532 # - iproute2 sets NLM_F_CREATE | NLM_F_APPEND1533 add_route "172.16.104.0/24" "via 172.16.101.2"1534 run_cmd "$IP ro append 172.16.104.0/24 via 172.16.103.2"1535 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"1536 log_test $? 0 "Append nexthop to existing route - gw"1537 1538 add_route "172.16.104.0/24" "via 172.16.101.2"1539 run_cmd "$IP ro append 172.16.104.0/24 dev veth3"1540 check_route "172.16.104.0/24 via 172.16.101.2 dev veth1 172.16.104.0/24 dev veth3 scope link"1541 log_test $? 0 "Append nexthop to existing route - dev only"1542 1543 add_route "172.16.104.0/24" "via 172.16.101.2"1544 run_cmd "$IP ro append unreachable 172.16.104.0/24"1545 check_route "172.16.104.0/24 via 172.16.101.2 dev veth1 unreachable 172.16.104.0/24"1546 log_test $? 0 "Append nexthop to existing route - reject route"1547 1548 run_cmd "$IP ro flush 172.16.104.0/24"1549 run_cmd "$IP ro add unreachable 172.16.104.0/24"1550 run_cmd "$IP ro append 172.16.104.0/24 via 172.16.103.2"1551 check_route "unreachable 172.16.104.0/24 172.16.104.0/24 via 172.16.103.2 dev veth3"1552 log_test $? 0 "Append nexthop to existing reject route - gw"1553 1554 run_cmd "$IP ro flush 172.16.104.0/24"1555 run_cmd "$IP ro add unreachable 172.16.104.0/24"1556 run_cmd "$IP ro append 172.16.104.0/24 dev veth3"1557 check_route "unreachable 172.16.104.0/24 172.16.104.0/24 dev veth3 scope link"1558 log_test $? 0 "Append nexthop to existing reject route - dev only"1559 1560 # insert mpath directly1561 add_route "172.16.104.0/24" "nexthop via 172.16.101.2 nexthop via 172.16.103.2"1562 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"1563 log_test $? 0 "add multipath route"1564 1565 add_route "172.16.104.0/24" "nexthop via 172.16.101.2 nexthop via 172.16.103.2"1566 run_cmd "$IP ro add 172.16.104.0/24 nexthop via 172.16.101.2 nexthop via 172.16.103.2"1567 log_test $? 2 "Attempt to add duplicate multipath route"1568 1569 # insert of a second route without append but different metric1570 add_route "172.16.104.0/24" "via 172.16.101.2"1571 run_cmd "$IP ro add 172.16.104.0/24 via 172.16.103.2 metric 512"1572 rc=$?1573 if [ $rc -eq 0 ]; then1574 run_cmd "$IP ro add 172.16.104.0/24 via 172.16.103.3 metric 256"1575 rc=$?1576 fi1577 log_test $rc 0 "Route add with different metrics"1578 1579 run_cmd "$IP ro del 172.16.104.0/24 metric 512"1580 rc=$?1581 if [ $rc -eq 0 ]; then1582 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"1583 rc=$?1584 fi1585 log_test $rc 0 "Route delete with metric"1586}1587 1588ipv4_rt_replace_single()1589{1590 # single path with single path1591 #1592 add_initial_route "via 172.16.101.2"1593 run_cmd "$IP ro replace 172.16.104.0/24 via 172.16.103.2"1594 check_route "172.16.104.0/24 via 172.16.103.2 dev veth3"1595 log_test $? 0 "Single path with single path"1596 1597 # single path with multipath1598 #1599 add_initial_route "nexthop via 172.16.101.2"1600 run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.101.3 nexthop via 172.16.103.2"1601 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"1602 log_test $? 0 "Single path with multipath"1603 1604 # single path with reject1605 #1606 add_initial_route "nexthop via 172.16.101.2"1607 run_cmd "$IP ro replace unreachable 172.16.104.0/24"1608 check_route "unreachable 172.16.104.0/24"1609 log_test $? 0 "Single path with reject route"1610 1611 # single path with single path using MULTIPATH attribute1612 #1613 add_initial_route "via 172.16.101.2"1614 run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.103.2"1615 check_route "172.16.104.0/24 via 172.16.103.2 dev veth3"1616 log_test $? 0 "Single path with single path via multipath attribute"1617 1618 # route replace fails - invalid nexthop1619 add_initial_route "via 172.16.101.2"1620 run_cmd "$IP ro replace 172.16.104.0/24 via 2001:db8:104::2"1621 if [ $? -eq 0 ]; then1622 # previous command is expected to fail so if it returns 01623 # that means the test failed.1624 log_test 0 1 "Invalid nexthop"1625 else1626 check_route "172.16.104.0/24 via 172.16.101.2 dev veth1"1627 log_test $? 0 "Invalid nexthop"1628 fi1629 1630 # replace non-existent route1631 # - note use of change versus replace since ip adds NLM_F_CREATE1632 # for replace1633 add_initial_route "via 172.16.101.2"1634 run_cmd "$IP ro change 172.16.105.0/24 via 172.16.101.2"1635 log_test $? 2 "Single path - replace of non-existent route"1636}1637 1638ipv4_rt_replace_mpath()1639{1640 # multipath with multipath1641 add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2"1642 run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.101.3 nexthop via 172.16.103.3"1643 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"1644 log_test $? 0 "Multipath with multipath"1645 1646 # multipath with single1647 add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2"1648 run_cmd "$IP ro replace 172.16.104.0/24 via 172.16.101.3"1649 check_route "172.16.104.0/24 via 172.16.101.3 dev veth1"1650 log_test $? 0 "Multipath with single path"1651 1652 # multipath with single1653 add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2"1654 run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.101.3"1655 check_route "172.16.104.0/24 via 172.16.101.3 dev veth1"1656 log_test $? 0 "Multipath with single path via multipath attribute"1657 1658 # multipath with reject1659 add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2"1660 run_cmd "$IP ro replace unreachable 172.16.104.0/24"1661 check_route "unreachable 172.16.104.0/24"1662 log_test $? 0 "Multipath with reject route"1663 1664 # route replace fails - invalid nexthop 11665 add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2"1666 run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.111.3 nexthop via 172.16.103.3"1667 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"1668 log_test $? 0 "Multipath - invalid first nexthop"1669 1670 # route replace fails - invalid nexthop 21671 add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2"1672 run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.101.3 nexthop via 172.16.113.3"1673 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"1674 log_test $? 0 "Multipath - invalid second nexthop"1675 1676 # multipath non-existent route1677 add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2"1678 run_cmd "$IP ro change 172.16.105.0/24 nexthop via 172.16.101.3 nexthop via 172.16.103.3"1679 log_test $? 2 "Multipath - replace of non-existent route"1680}1681 1682ipv4_rt_replace()1683{1684 echo1685 echo "IPv4 route replace tests"1686 1687 ipv4_rt_replace_single1688 ipv4_rt_replace_mpath1689}1690 1691# checks that cached input route on VRF port is deleted1692# when VRF is deleted1693ipv4_local_rt_cache()1694{1695 run_cmd "ip addr add 10.0.0.1/32 dev lo"1696 run_cmd "setup_ns test-ns"1697 run_cmd "ip link add veth-outside type veth peer name veth-inside"1698 run_cmd "ip link add vrf-100 type vrf table 1100"1699 run_cmd "ip link set veth-outside master vrf-100"1700 run_cmd "ip link set veth-inside netns $test-ns"1701 run_cmd "ip link set veth-outside up"1702 run_cmd "ip link set vrf-100 up"1703 run_cmd "ip route add 10.1.1.1/32 dev veth-outside table 1100"1704 run_cmd "ip netns exec $test-ns ip link set veth-inside up"1705 run_cmd "ip netns exec $test-ns ip addr add 10.1.1.1/32 dev veth-inside"1706 run_cmd "ip netns exec $test-ns ip route add 10.0.0.1/32 dev veth-inside"1707 run_cmd "ip netns exec $test-ns ip route add default via 10.0.0.1"1708 run_cmd "ip netns exec $test-ns ping 10.0.0.1 -c 1 -i 1"1709 run_cmd "ip link delete vrf-100"1710 1711 # if we do not hang test is a success1712 log_test $? 0 "Cached route removed from VRF port device"1713}1714 1715ipv4_rt_dsfield()1716{1717 echo1718 echo "IPv4 route with dsfield tests"1719 1720 run_cmd "$IP route flush 172.16.102.0/24"1721 1722 # New routes should reject dsfield options that interfere with ECN1723 run_cmd "$IP route add 172.16.102.0/24 dsfield 0x01 via 172.16.101.2"1724 log_test $? 2 "Reject route with dsfield 0x01"1725 1726 run_cmd "$IP route add 172.16.102.0/24 dsfield 0x02 via 172.16.101.2"1727 log_test $? 2 "Reject route with dsfield 0x02"1728 1729 run_cmd "$IP route add 172.16.102.0/24 dsfield 0x03 via 172.16.101.2"1730 log_test $? 2 "Reject route with dsfield 0x03"1731 1732 # A generic route that doesn't take DSCP into account1733 run_cmd "$IP route add 172.16.102.0/24 via 172.16.101.2"1734 1735 # A more specific route for DSCP 0x101736 run_cmd "$IP route add 172.16.102.0/24 dsfield 0x10 via 172.16.103.2"1737 1738 # DSCP 0x10 should match the specific route, no matter the ECN bits1739 $IP route get fibmatch 172.16.102.1 dsfield 0x10 | \1740 grep -q "172.16.102.0/24 tos 0x10 via 172.16.103.2"1741 log_test $? 0 "IPv4 route with DSCP and ECN:Not-ECT"1742 1743 $IP route get fibmatch 172.16.102.1 dsfield 0x11 | \1744 grep -q "172.16.102.0/24 tos 0x10 via 172.16.103.2"1745 log_test $? 0 "IPv4 route with DSCP and ECN:ECT(1)"1746 1747 $IP route get fibmatch 172.16.102.1 dsfield 0x12 | \1748 grep -q "172.16.102.0/24 tos 0x10 via 172.16.103.2"1749 log_test $? 0 "IPv4 route with DSCP and ECN:ECT(0)"1750 1751 $IP route get fibmatch 172.16.102.1 dsfield 0x13 | \1752 grep -q "172.16.102.0/24 tos 0x10 via 172.16.103.2"1753 log_test $? 0 "IPv4 route with DSCP and ECN:CE"1754 1755 # Unknown DSCP should match the generic route, no matter the ECN bits1756 $IP route get fibmatch 172.16.102.1 dsfield 0x14 | \1757 grep -q "172.16.102.0/24 via 172.16.101.2"1758 log_test $? 0 "IPv4 route with unknown DSCP and ECN:Not-ECT"1759 1760 $IP route get fibmatch 172.16.102.1 dsfield 0x15 | \1761 grep -q "172.16.102.0/24 via 172.16.101.2"1762 log_test $? 0 "IPv4 route with unknown DSCP and ECN:ECT(1)"1763 1764 $IP route get fibmatch 172.16.102.1 dsfield 0x16 | \1765 grep -q "172.16.102.0/24 via 172.16.101.2"1766 log_test $? 0 "IPv4 route with unknown DSCP and ECN:ECT(0)"1767 1768 $IP route get fibmatch 172.16.102.1 dsfield 0x17 | \1769 grep -q "172.16.102.0/24 via 172.16.101.2"1770 log_test $? 0 "IPv4 route with unknown DSCP and ECN:CE"1771 1772 # Null DSCP should match the generic route, no matter the ECN bits1773 $IP route get fibmatch 172.16.102.1 dsfield 0x00 | \1774 grep -q "172.16.102.0/24 via 172.16.101.2"1775 log_test $? 0 "IPv4 route with no DSCP and ECN:Not-ECT"1776 1777 $IP route get fibmatch 172.16.102.1 dsfield 0x01 | \1778 grep -q "172.16.102.0/24 via 172.16.101.2"1779 log_test $? 0 "IPv4 route with no DSCP and ECN:ECT(1)"1780 1781 $IP route get fibmatch 172.16.102.1 dsfield 0x02 | \1782 grep -q "172.16.102.0/24 via 172.16.101.2"1783 log_test $? 0 "IPv4 route with no DSCP and ECN:ECT(0)"1784 1785 $IP route get fibmatch 172.16.102.1 dsfield 0x03 | \1786 grep -q "172.16.102.0/24 via 172.16.101.2"1787 log_test $? 0 "IPv4 route with no DSCP and ECN:CE"1788}1789 1790ipv4_route_test()1791{1792 route_setup1793 1794 ipv4_rt_add1795 ipv4_rt_replace1796 ipv4_local_rt_cache1797 ipv4_rt_dsfield1798 1799 route_cleanup1800}1801 1802ipv4_addr_metric_test()1803{1804 local rc1805 1806 echo1807 echo "IPv4 prefix route tests"1808 1809 ip_addr_metric_check || return 11810 1811 setup1812 1813 set -e1814 $IP li add dummy1 type dummy1815 $IP li add dummy2 type dummy1816 $IP li set dummy1 up1817 $IP li set dummy2 up1818 1819 # default entry is metric 2561820 run_cmd "$IP addr add dev dummy1 172.16.104.1/24"1821 run_cmd "$IP addr add dev dummy2 172.16.104.2/24"1822 set +e1823 1824 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"1825 log_test $? 0 "Default metric"1826 1827 set -e1828 run_cmd "$IP addr flush dev dummy1"1829 run_cmd "$IP addr add dev dummy1 172.16.104.1/24 metric 257"1830 set +e1831 1832 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"1833 log_test $? 0 "User specified metric on first device"1834 1835 set -e1836 run_cmd "$IP addr flush dev dummy2"1837 run_cmd "$IP addr add dev dummy2 172.16.104.2/24 metric 258"1838 set +e1839 1840 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"1841 log_test $? 0 "User specified metric on second device"1842 1843 run_cmd "$IP addr del dev dummy1 172.16.104.1/24 metric 257"1844 rc=$?1845 if [ $rc -eq 0 ]; then1846 check_route "172.16.104.0/24 dev dummy2 proto kernel scope link src 172.16.104.2 metric 258"1847 rc=$?1848 fi1849 log_test $rc 0 "Delete of address on first device"1850 1851 run_cmd "$IP addr change dev dummy2 172.16.104.2/24 metric 259"1852 rc=$?1853 if [ $rc -eq 0 ]; then1854 check_route "172.16.104.0/24 dev dummy2 proto kernel scope link src 172.16.104.2 metric 259"1855 rc=$?1856 fi1857 log_test $rc 0 "Modify metric of address"1858 1859 # verify prefix route removed on down1860 run_cmd "$IP li set dev dummy2 down"1861 rc=$?1862 if [ $rc -eq 0 ]; then1863 out=$($IP ro ls match 172.16.104.0/24)1864 check_expected "${out}" ""1865 rc=$?1866 fi1867 log_test $rc 0 "Prefix route removed on link down"1868 1869 # verify prefix route re-inserted with assigned metric1870 run_cmd "$IP li set dev dummy2 up"1871 rc=$?1872 if [ $rc -eq 0 ]; then1873 check_route "172.16.104.0/24 dev dummy2 proto kernel scope link src 172.16.104.2 metric 259"1874 rc=$?1875 fi1876 log_test $rc 0 "Prefix route with metric on link up"1877 1878 # explicitly check for metric changes on edge scenarios1879 run_cmd "$IP addr flush dev dummy2"1880 run_cmd "$IP addr add dev dummy2 172.16.104.0/24 metric 259"1881 run_cmd "$IP addr change dev dummy2 172.16.104.0/24 metric 260"1882 rc=$?1883 if [ $rc -eq 0 ]; then1884 check_route "172.16.104.0/24 dev dummy2 proto kernel scope link src 172.16.104.0 metric 260"1885 rc=$?1886 fi1887 log_test $rc 0 "Modify metric of .0/24 address"1888 1889 run_cmd "$IP addr flush dev dummy2"1890 run_cmd "$IP addr add dev dummy2 172.16.104.1/32 peer 172.16.104.2 metric 260"1891 rc=$?1892 if [ $rc -eq 0 ]; then1893 check_route "172.16.104.2 dev dummy2 proto kernel scope link src 172.16.104.1 metric 260"1894 rc=$?1895 fi1896 log_test $rc 0 "Set metric of address with peer route"1897 1898 run_cmd "$IP addr change dev dummy2 172.16.104.1/32 peer 172.16.104.3 metric 261"1899 rc=$?1900 if [ $rc -eq 0 ]; then1901 check_route "172.16.104.3 dev dummy2 proto kernel scope link src 172.16.104.1 metric 261"1902 rc=$?1903 fi1904 log_test $rc 0 "Modify metric and peer address for peer route"1905 1906 $IP li del dummy11907 $IP li del dummy21908 cleanup1909}1910 1911ipv4_route_metrics_test()1912{1913 local rc1914 1915 echo1916 echo "IPv4 route add / append tests"1917 1918 route_setup1919 1920 run_cmd "$IP ro add 172.16.111.0/24 via 172.16.101.2 mtu 1400"1921 rc=$?1922 if [ $rc -eq 0 ]; then1923 check_route "172.16.111.0/24 via 172.16.101.2 dev veth1 mtu 1400"1924 rc=$?1925 fi1926 log_test $rc 0 "Single path route with mtu metric"1927 1928 1929 run_cmd "$IP ro add 172.16.112.0/24 mtu 1400 nexthop via 172.16.101.2 nexthop via 172.16.103.2"1930 rc=$?1931 if [ $rc -eq 0 ]; then1932 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"1933 rc=$?1934 fi1935 log_test $rc 0 "Multipath route with mtu metric"1936 1937 $IP ro add 172.16.104.0/24 via 172.16.101.2 mtu 13001938 run_cmd "ip netns exec $ns1 ping -w1 -c1 -s 1500 172.16.104.1"1939 log_test $? 0 "Using route with mtu metric"1940 1941 run_cmd "$IP ro add 172.16.111.0/24 via 172.16.101.2 congctl lock foo"1942 log_test $? 2 "Invalid metric (fails metric_convert)"1943 1944 route_cleanup1945}1946 1947ipv4_del_addr_test()1948{1949 echo1950 echo "IPv4 delete address route tests"1951 1952 setup1953 1954 set -e1955 $IP li add dummy1 type dummy1956 $IP li set dummy1 up1957 $IP li add dummy2 type dummy1958 $IP li set dummy2 up1959 $IP li add red type vrf table 11111960 $IP li set red up1961 $IP ro add vrf red unreachable default1962 $IP li set dummy2 vrf red1963 1964 $IP addr add dev dummy1 172.16.104.1/241965 $IP addr add dev dummy1 172.16.104.11/241966 $IP addr add dev dummy1 172.16.104.12/241967 $IP addr add dev dummy1 172.16.104.13/241968 $IP addr add dev dummy2 172.16.104.1/241969 $IP addr add dev dummy2 172.16.104.11/241970 $IP addr add dev dummy2 172.16.104.12/241971 $IP route add 172.16.105.0/24 via 172.16.104.2 src 172.16.104.111972 $IP route add 172.16.106.0/24 dev lo src 172.16.104.121973 $IP route add table 0 172.16.107.0/24 via 172.16.104.2 src 172.16.104.131974 $IP route add vrf red 172.16.105.0/24 via 172.16.104.2 src 172.16.104.111975 $IP route add vrf red 172.16.106.0/24 dev lo src 172.16.104.121976 set +e1977 1978 # removing address from device in vrf should only remove route from vrf table1979 echo " Regular FIB info"1980 1981 $IP addr del dev dummy2 172.16.104.11/241982 $IP ro ls vrf red | grep -q 172.16.105.0/241983 log_test $? 1 "Route removed from VRF when source address deleted"1984 1985 $IP ro ls | grep -q 172.16.105.0/241986 log_test $? 0 "Route in default VRF not removed"1987 1988 $IP addr add dev dummy2 172.16.104.11/241989 $IP route add vrf red 172.16.105.0/24 via 172.16.104.2 src 172.16.104.111990 1991 $IP addr del dev dummy1 172.16.104.11/241992 $IP ro ls | grep -q 172.16.105.0/241993 log_test $? 1 "Route removed in default VRF when source address deleted"1994 1995 $IP ro ls vrf red | grep -q 172.16.105.0/241996 log_test $? 0 "Route in VRF is not removed by address delete"1997 1998 # removing address from device in vrf should only remove route from vrf1999 # table even when the associated fib info only differs in table ID2000 echo " Identical FIB info with different table ID"2001 2002 $IP addr del dev dummy2 172.16.104.12/242003 $IP ro ls vrf red | grep -q 172.16.106.0/242004 log_test $? 1 "Route removed from VRF when source address deleted"2005 2006 $IP ro ls | grep -q 172.16.106.0/242007 log_test $? 0 "Route in default VRF not removed"2008 2009 $IP addr add dev dummy2 172.16.104.12/242010 $IP route add vrf red 172.16.106.0/24 dev lo src 172.16.104.122011 2012 $IP addr del dev dummy1 172.16.104.12/242013 $IP ro ls | grep -q 172.16.106.0/242014 log_test $? 1 "Route removed in default VRF when source address deleted"2015 2016 $IP ro ls vrf red | grep -q 172.16.106.0/242017 log_test $? 0 "Route in VRF is not removed by address delete"2018 2019 # removing address from device in default vrf should remove route from2020 # the default vrf even when route was inserted with a table ID of 0.2021 echo " Table ID 0"2022 2023 $IP addr del dev dummy1 172.16.104.13/242024 $IP ro ls | grep -q 172.16.107.0/242025 log_test $? 1 "Route removed in default VRF when source address deleted"2026 2027 $IP li del dummy12028 $IP li del dummy22029 cleanup2030}2031 2032ipv6_del_addr_test()2033{2034 echo2035 echo "IPv6 delete address route tests"2036 2037 setup2038 2039 set -e2040 for i in $(seq 6); do2041 $IP li add dummy${i} up type dummy2042 done2043 2044 $IP li add red up type vrf table 11112045 $IP ro add vrf red unreachable default2046 for i in $(seq 4 6); do2047 $IP li set dummy${i} vrf red2048 done2049 2050 $IP addr add dev dummy1 fe80::1/1282051 $IP addr add dev dummy1 2001:db8:101::1/642052 $IP addr add dev dummy1 2001:db8:101::10/642053 $IP addr add dev dummy1 2001:db8:101::11/642054 $IP addr add dev dummy1 2001:db8:101::12/642055 $IP addr add dev dummy1 2001:db8:101::13/642056 $IP addr add dev dummy1 2001:db8:101::14/642057 $IP addr add dev dummy1 2001:db8:101::15/642058 $IP addr add dev dummy2 fe80::1/1282059 $IP addr add dev dummy2 2001:db8:101::1/642060 $IP addr add dev dummy2 2001:db8:101::11/642061 $IP addr add dev dummy3 fe80::1/1282062 2063 $IP addr add dev dummy4 2001:db8:101::1/642064 $IP addr add dev dummy4 2001:db8:101::10/642065 $IP addr add dev dummy4 2001:db8:101::11/642066 $IP addr add dev dummy4 2001:db8:101::12/642067 $IP addr add dev dummy4 2001:db8:101::13/642068 $IP addr add dev dummy4 2001:db8:101::14/642069 $IP addr add dev dummy5 2001:db8:101::1/642070 $IP addr add dev dummy5 2001:db8:101::11/642071 2072 # Single device using src address2073 $IP route add 2001:db8:110::/64 dev dummy3 src 2001:db8:101::102074 # Two devices with the same source address2075 $IP route add 2001:db8:111::/64 dev dummy3 src 2001:db8:101::112076 # VRF with single device using src address2077 $IP route add vrf red 2001:db8:110::/64 dev dummy6 src 2001:db8:101::102078 # VRF with two devices using src address2079 $IP route add vrf red 2001:db8:111::/64 dev dummy6 src 2001:db8:101::112080 # src address and nexthop dev in same VRF2081 $IP route add 2001:db8:112::/64 dev dummy3 src 2001:db8:101::122082 $IP route add vrf red 2001:db8:112::/64 dev dummy6 src 2001:db8:101::122083 # src address and nexthop device in different VRF2084 $IP route add 2001:db8:113::/64 dev lo src 2001:db8:101::132085 $IP route add vrf red 2001:db8:113::/64 dev lo src 2001:db8:101::132086 # table ID 02087 $IP route add table 0 2001:db8:115::/64 via 2001:db8:101::2 src 2001:db8:101::152088 # Link local source route2089 $IP route add 2001:db8:116::/64 dev dummy2 src fe80::12090 $IP route add 2001:db8:117::/64 dev dummy3 src fe80::12091 set +e2092 2093 echo " Single device using src address"2094 2095 $IP addr del dev dummy1 2001:db8:101::10/642096 $IP -6 route show | grep -q "src 2001:db8:101::10 "2097 log_test $? 1 "Prefsrc removed when src address removed on other device"2098 2099 echo " Two devices with the same source address"2100 2101 $IP addr del dev dummy1 2001:db8:101::11/642102 $IP -6 route show | grep -q "src 2001:db8:101::11 "2103 log_test $? 0 "Prefsrc not removed when src address exist on other device"2104 2105 $IP addr del dev dummy2 2001:db8:101::11/642106 $IP -6 route show | grep -q "src 2001:db8:101::11 "2107 log_test $? 1 "Prefsrc removed when src address removed on all devices"2108 2109 echo " VRF with single device using src address"2110 2111 $IP addr del dev dummy4 2001:db8:101::10/642112 $IP -6 route show vrf red | grep -q "src 2001:db8:101::10 "2113 log_test $? 1 "Prefsrc removed when src address removed on other device"2114 2115 echo " VRF with two devices using src address"2116 2117 $IP addr del dev dummy4 2001:db8:101::11/642118 $IP -6 route show vrf red | grep -q "src 2001:db8:101::11 "2119 log_test $? 0 "Prefsrc not removed when src address exist on other device"2120 2121 $IP addr del dev dummy5 2001:db8:101::11/642122 $IP -6 route show vrf red | grep -q "src 2001:db8:101::11 "2123 log_test $? 1 "Prefsrc removed when src address removed on all devices"2124 2125 echo " src address and nexthop dev in same VRF"2126 2127 $IP addr del dev dummy4 2001:db8:101::12/642128 $IP -6 route show vrf red | grep -q "src 2001:db8:101::12 "2129 log_test $? 1 "Prefsrc removed from VRF when source address deleted"2130 $IP -6 route show | grep -q " src 2001:db8:101::12 "2131 log_test $? 0 "Prefsrc in default VRF not removed"2132 2133 $IP addr add dev dummy4 2001:db8:101::12/642134 $IP route replace vrf red 2001:db8:112::/64 dev dummy6 src 2001:db8:101::122135 $IP addr del dev dummy1 2001:db8:101::12/642136 $IP -6 route show vrf red | grep -q "src 2001:db8:101::12 "2137 log_test $? 0 "Prefsrc not removed from VRF when source address exist"2138 $IP -6 route show | grep -q " src 2001:db8:101::12 "2139 log_test $? 1 "Prefsrc in default VRF removed"2140 2141 echo " src address and nexthop device in different VRF"2142 2143 $IP addr del dev dummy4 2001:db8:101::13/642144 $IP -6 route show vrf red | grep -q "src 2001:db8:101::13 "2145 log_test $? 0 "Prefsrc not removed from VRF when nexthop dev in diff VRF"2146 $IP -6 route show | grep -q "src 2001:db8:101::13 "2147 log_test $? 0 "Prefsrc not removed in default VRF"2148 2149 $IP addr add dev dummy4 2001:db8:101::13/642150 $IP addr del dev dummy1 2001:db8:101::13/642151 $IP -6 route show vrf red | grep -q "src 2001:db8:101::13 "2152 log_test $? 1 "Prefsrc removed from VRF when nexthop dev in diff VRF"2153 $IP -6 route show | grep -q "src 2001:db8:101::13 "2154 log_test $? 1 "Prefsrc removed in default VRF"2155 2156 echo " Table ID 0"2157 2158 $IP addr del dev dummy1 2001:db8:101::15/642159 $IP -6 route show | grep -q "src 2001:db8:101::15"2160 log_test $? 1 "Prefsrc removed from default VRF when source address deleted"2161 2162 echo " Link local source route"2163 $IP addr del dev dummy1 fe80::1/1282164 $IP -6 route show | grep -q "2001:db8:116::/64 dev dummy2 src fe80::1"2165 log_test $? 0 "Prefsrc not removed when delete ll addr from other dev"2166 $IP addr del dev dummy2 fe80::1/1282167 $IP -6 route show | grep -q "2001:db8:116::/64 dev dummy2 src fe80::1"2168 log_test $? 1 "Prefsrc removed when delete ll addr"2169 $IP -6 route show | grep -q "2001:db8:117::/64 dev dummy3 src fe80::1"2170 log_test $? 0 "Prefsrc not removed when delete ll addr from other dev"2171 $IP addr add dev dummy1 fe80::1/1282172 $IP addr del dev dummy3 fe80::1/1282173 $IP -6 route show | grep -q "2001:db8:117::/64 dev dummy3 src fe80::1"2174 log_test $? 1 "Prefsrc removed even ll addr still exist on other dev"2175 2176 for i in $(seq 6); do2177 $IP li del dummy${i}2178 done2179 cleanup2180}2181 2182ipv4_route_v6_gw_test()2183{2184 local rc2185 2186 echo2187 echo "IPv4 route with IPv6 gateway tests"2188 2189 route_setup2190 sleep 22191 2192 #2193 # single path route2194 #2195 run_cmd "$IP ro add 172.16.104.0/24 via inet6 2001:db8:101::2"2196 rc=$?2197 log_test $rc 0 "Single path route with IPv6 gateway"2198 if [ $rc -eq 0 ]; then2199 check_route "172.16.104.0/24 via inet6 2001:db8:101::2 dev veth1"2200 fi2201 2202 run_cmd "ip netns exec $ns1 ping -w1 -c1 172.16.104.1"2203 log_test $rc 0 "Single path route with IPv6 gateway - ping"2204 2205 run_cmd "$IP ro del 172.16.104.0/24 via inet6 2001:db8:101::2"2206 rc=$?2207 log_test $rc 0 "Single path route delete"2208 if [ $rc -eq 0 ]; then2209 check_route "172.16.112.0/24"2210 fi2211 2212 #2213 # multipath - v6 then v42214 #2215 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"2216 rc=$?2217 log_test $rc 0 "Multipath route add - v6 nexthop then v4"2218 if [ $rc -eq 0 ]; then2219 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"2220 fi2221 2222 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"2223 log_test $? 2 " Multipath route delete - nexthops in wrong order"2224 2225 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"2226 log_test $? 0 " Multipath route delete exact match"2227 2228 #2229 # multipath - v4 then v62230 #2231 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"2232 rc=$?2233 log_test $rc 0 "Multipath route add - v4 nexthop then v6"2234 if [ $rc -eq 0 ]; then2235 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"2236 fi2237 2238 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"2239 log_test $? 2 " Multipath route delete - nexthops in wrong order"2240 2241 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"2242 log_test $? 0 " Multipath route delete exact match"2243 2244 route_cleanup2245}2246 2247socat_check()2248{2249 if [ ! -x "$(command -v socat)" ]; then2250 echo "socat command not found. Skipping test"2251 return 12252 fi2253 2254 return 02255}2256 2257iptables_check()2258{2259 iptables -t mangle -L OUTPUT &> /dev/null2260 if [ $? -ne 0 ]; then2261 echo "iptables configuration not supported. Skipping test"2262 return 12263 fi2264 2265 return 02266}2267 2268ip6tables_check()2269{2270 ip6tables -t mangle -L OUTPUT &> /dev/null2271 if [ $? -ne 0 ]; then2272 echo "ip6tables configuration not supported. Skipping test"2273 return 12274 fi2275 2276 return 02277}2278 2279ipv4_mangle_test()2280{2281 local rc2282 2283 echo2284 echo "IPv4 mangling tests"2285 2286 socat_check || return 12287 iptables_check || return 12288 2289 route_setup2290 sleep 22291 2292 local tmp_file=$(mktemp)2293 ip netns exec $ns2 socat UDP4-LISTEN:54321,fork $tmp_file &2294 2295 # Add a FIB rule and a route that will direct our connection to the2296 # listening server.2297 $IP rule add pref 100 ipproto udp sport 12345 dport 54321 table 1232298 $IP route add table 123 172.16.101.0/24 dev veth12299 2300 # Add an unreachable route to the main table that will block our2301 # connection in case the FIB rule is not hit.2302 $IP route add unreachable 172.16.101.2/322303 2304 run_cmd "echo a | $NS_EXEC socat STDIN UDP4:172.16.101.2:54321,sourceport=12345"2305 log_test $? 0 " Connection with correct parameters"2306 2307 run_cmd "echo a | $NS_EXEC socat STDIN UDP4:172.16.101.2:54321,sourceport=11111"2308 log_test $? 1 " Connection with incorrect parameters"2309 2310 # Add a mangling rule and make sure connection is still successful.2311 $NS_EXEC iptables -t mangle -A OUTPUT -j MARK --set-mark 12312 2313 run_cmd "echo a | $NS_EXEC socat STDIN UDP4:172.16.101.2:54321,sourceport=12345"2314 log_test $? 0 " Connection with correct parameters - mangling"2315 2316 # Delete the mangling rule and make sure connection is still2317 # successful.2318 $NS_EXEC iptables -t mangle -D OUTPUT -j MARK --set-mark 12319 2320 run_cmd "echo a | $NS_EXEC socat STDIN UDP4:172.16.101.2:54321,sourceport=12345"2321 log_test $? 0 " Connection with correct parameters - no mangling"2322 2323 # Verify connections were indeed successful on server side.2324 [[ $(cat $tmp_file | wc -l) -eq 3 ]]2325 log_test $? 0 " Connection check - server side"2326 2327 $IP route del unreachable 172.16.101.2/322328 $IP route del table 123 172.16.101.0/24 dev veth12329 $IP rule del pref 1002330 2331 { kill %% && wait %%; } 2>/dev/null2332 rm $tmp_file2333 2334 route_cleanup2335}2336 2337ipv6_mangle_test()2338{2339 local rc2340 2341 echo2342 echo "IPv6 mangling tests"2343 2344 socat_check || return 12345 ip6tables_check || return 12346 2347 route_setup2348 sleep 22349 2350 local tmp_file=$(mktemp)2351 ip netns exec $ns2 socat UDP6-LISTEN:54321,fork $tmp_file &2352 2353 # Add a FIB rule and a route that will direct our connection to the2354 # listening server.2355 $IP -6 rule add pref 100 ipproto udp sport 12345 dport 54321 table 1232356 $IP -6 route add table 123 2001:db8:101::/64 dev veth12357 2358 # Add an unreachable route to the main table that will block our2359 # connection in case the FIB rule is not hit.2360 $IP -6 route add unreachable 2001:db8:101::2/1282361 2362 run_cmd "echo a | $NS_EXEC socat STDIN UDP6:[2001:db8:101::2]:54321,sourceport=12345"2363 log_test $? 0 " Connection with correct parameters"2364 2365 run_cmd "echo a | $NS_EXEC socat STDIN UDP6:[2001:db8:101::2]:54321,sourceport=11111"2366 log_test $? 1 " Connection with incorrect parameters"2367 2368 # Add a mangling rule and make sure connection is still successful.2369 $NS_EXEC ip6tables -t mangle -A OUTPUT -j MARK --set-mark 12370 2371 run_cmd "echo a | $NS_EXEC socat STDIN UDP6:[2001:db8:101::2]:54321,sourceport=12345"2372 log_test $? 0 " Connection with correct parameters - mangling"2373 2374 # Delete the mangling rule and make sure connection is still2375 # successful.2376 $NS_EXEC ip6tables -t mangle -D OUTPUT -j MARK --set-mark 12377 2378 run_cmd "echo a | $NS_EXEC socat STDIN UDP6:[2001:db8:101::2]:54321,sourceport=12345"2379 log_test $? 0 " Connection with correct parameters - no mangling"2380 2381 # Verify connections were indeed successful on server side.2382 [[ $(cat $tmp_file | wc -l) -eq 3 ]]2383 log_test $? 0 " Connection check - server side"2384 2385 $IP -6 route del unreachable 2001:db8:101::2/1282386 $IP -6 route del table 123 2001:db8:101::/64 dev veth12387 $IP -6 rule del pref 1002388 2389 { kill %% && wait %%; } 2>/dev/null2390 rm $tmp_file2391 2392 route_cleanup2393}2394 2395ip_neigh_get_check()2396{2397 ip neigh help 2>&1 | grep -q 'ip neigh get'2398 if [ $? -ne 0 ]; then2399 echo "iproute2 command does not support neigh get. Skipping test"2400 return 12401 fi2402 2403 return 02404}2405 2406ipv4_bcast_neigh_test()2407{2408 local rc2409 2410 echo2411 echo "IPv4 broadcast neighbour tests"2412 2413 ip_neigh_get_check || return 12414 2415 setup2416 2417 set -e2418 run_cmd "$IP neigh add 192.0.2.111 lladdr 00:11:22:33:44:55 nud perm dev dummy0"2419 run_cmd "$IP neigh add 192.0.2.255 lladdr 00:11:22:33:44:55 nud perm dev dummy0"2420 2421 run_cmd "$IP neigh get 192.0.2.111 dev dummy0"2422 run_cmd "$IP neigh get 192.0.2.255 dev dummy0"2423 2424 run_cmd "$IP address add 192.0.2.1/24 broadcast 192.0.2.111 dev dummy0"2425 2426 run_cmd "$IP neigh add 203.0.113.111 nud failed dev dummy0"2427 run_cmd "$IP neigh add 203.0.113.255 nud failed dev dummy0"2428 2429 run_cmd "$IP neigh get 203.0.113.111 dev dummy0"2430 run_cmd "$IP neigh get 203.0.113.255 dev dummy0"2431 2432 run_cmd "$IP address add 203.0.113.1/24 broadcast 203.0.113.111 dev dummy0"2433 set +e2434 2435 run_cmd "$IP neigh get 192.0.2.111 dev dummy0"2436 log_test $? 0 "Resolved neighbour for broadcast address"2437 2438 run_cmd "$IP neigh get 192.0.2.255 dev dummy0"2439 log_test $? 0 "Resolved neighbour for network broadcast address"2440 2441 run_cmd "$IP neigh get 203.0.113.111 dev dummy0"2442 log_test $? 2 "Unresolved neighbour for broadcast address"2443 2444 run_cmd "$IP neigh get 203.0.113.255 dev dummy0"2445 log_test $? 2 "Unresolved neighbour for network broadcast address"2446 2447 cleanup2448}2449 2450mpath_dep_check()2451{2452 if [ ! -x "$(command -v mausezahn)" ]; then2453 echo "mausezahn command not found. Skipping test"2454 return 12455 fi2456 2457 if [ ! -x "$(command -v jq)" ]; then2458 echo "jq command not found. Skipping test"2459 return 12460 fi2461 2462 if [ ! -x "$(command -v bc)" ]; then2463 echo "bc command not found. Skipping test"2464 return 12465 fi2466 2467 if [ ! -x "$(command -v perf)" ]; then2468 echo "perf command not found. Skipping test"2469 return 12470 fi2471 2472 perf list fib:* | grep -q fib_table_lookup2473 if [ $? -ne 0 ]; then2474 echo "IPv4 FIB tracepoint not found. Skipping test"2475 return 12476 fi2477 2478 perf list fib6:* | grep -q fib6_table_lookup2479 if [ $? -ne 0 ]; then2480 echo "IPv6 FIB tracepoint not found. Skipping test"2481 return 12482 fi2483 2484 return 02485}2486 2487link_stats_get()2488{2489 local ns=$1; shift2490 local dev=$1; shift2491 local dir=$1; shift2492 local stat=$1; shift2493 2494 ip -n $ns -j -s link show dev $dev \2495 | jq '.[]["stats64"]["'$dir'"]["'$stat'"]'2496}2497 2498list_rcv_eval()2499{2500 local file=$1; shift2501 local expected=$1; shift2502 2503 local count=$(tail -n 1 $file | jq '.["counter-value"] | tonumber | floor')2504 local ratio=$(echo "scale=2; $count / $expected" | bc -l)2505 local res=$(echo "$ratio >= 0.95" | bc)2506 [[ $res -eq 1 ]]2507 log_test $? 0 "Multipath route hit ratio ($ratio)"2508}2509 2510ipv4_mpath_list_test()2511{2512 echo2513 echo "IPv4 multipath list receive tests"2514 2515 mpath_dep_check || return 12516 2517 route_setup2518 2519 set -e2520 run_cmd "ip netns exec $ns1 ethtool -K veth1 tcp-segmentation-offload off"2521 2522 run_cmd "ip netns exec $ns2 bash -c \"echo 20000 > /sys/class/net/veth2/gro_flush_timeout\""2523 run_cmd "ip netns exec $ns2 bash -c \"echo 1 > /sys/class/net/veth2/napi_defer_hard_irqs\""2524 run_cmd "ip netns exec $ns2 ethtool -K veth2 generic-receive-offload on"2525 run_cmd "ip -n $ns2 link add name nh1 up type dummy"2526 run_cmd "ip -n $ns2 link add name nh2 up type dummy"2527 run_cmd "ip -n $ns2 address add 172.16.201.1/24 dev nh1"2528 run_cmd "ip -n $ns2 address add 172.16.202.1/24 dev nh2"2529 run_cmd "ip -n $ns2 neigh add 172.16.201.2 lladdr 00:11:22:33:44:55 nud perm dev nh1"2530 run_cmd "ip -n $ns2 neigh add 172.16.202.2 lladdr 00:aa:bb:cc:dd:ee nud perm dev nh2"2531 run_cmd "ip -n $ns2 route add 203.0.113.0/242532 nexthop via 172.16.201.2 nexthop via 172.16.202.2"2533 run_cmd "ip netns exec $ns2 sysctl -qw net.ipv4.fib_multipath_hash_policy=1"2534 run_cmd "ip netns exec $ns2 sysctl -qw net.ipv4.conf.veth2.rp_filter=0"2535 run_cmd "ip netns exec $ns2 sysctl -qw net.ipv4.conf.all.rp_filter=0"2536 run_cmd "ip netns exec $ns2 sysctl -qw net.ipv4.conf.default.rp_filter=0"2537 set +e2538 2539 local dmac=$(ip -n $ns2 -j link show dev veth2 | jq -r '.[]["address"]')2540 local tmp_file=$(mktemp)2541 local cmd="ip netns exec $ns1 mausezahn veth1 -a own -b $dmac2542 -A 172.16.101.1 -B 203.0.113.1 -t udp 'sp=12345,dp=0-65535' -q"2543 2544 # Packets forwarded in a list using a multipath route must not reuse a2545 # cached result so that a flow always hits the same nexthop. In other2546 # words, the FIB lookup tracepoint needs to be triggered for every2547 # packet.2548 local t0_rx_pkts=$(link_stats_get $ns2 veth2 rx packets)2549 run_cmd "perf stat -a -e fib:fib_table_lookup --filter 'err == 0' -j -o $tmp_file -- $cmd"2550 local t1_rx_pkts=$(link_stats_get $ns2 veth2 rx packets)2551 local diff=$(echo $t1_rx_pkts - $t0_rx_pkts | bc -l)2552 list_rcv_eval $tmp_file $diff2553 2554 rm $tmp_file2555 route_cleanup2556}2557 2558ipv6_mpath_list_test()2559{2560 echo2561 echo "IPv6 multipath list receive tests"2562 2563 mpath_dep_check || return 12564 2565 route_setup2566 2567 set -e2568 run_cmd "ip netns exec $ns1 ethtool -K veth1 tcp-segmentation-offload off"2569 2570 run_cmd "ip netns exec $ns2 bash -c \"echo 20000 > /sys/class/net/veth2/gro_flush_timeout\""2571 run_cmd "ip netns exec $ns2 bash -c \"echo 1 > /sys/class/net/veth2/napi_defer_hard_irqs\""2572 run_cmd "ip netns exec $ns2 ethtool -K veth2 generic-receive-offload on"2573 run_cmd "ip -n $ns2 link add name nh1 up type dummy"2574 run_cmd "ip -n $ns2 link add name nh2 up type dummy"2575 run_cmd "ip -n $ns2 -6 address add 2001:db8:201::1/64 dev nh1"2576 run_cmd "ip -n $ns2 -6 address add 2001:db8:202::1/64 dev nh2"2577 run_cmd "ip -n $ns2 -6 neigh add 2001:db8:201::2 lladdr 00:11:22:33:44:55 nud perm dev nh1"2578 run_cmd "ip -n $ns2 -6 neigh add 2001:db8:202::2 lladdr 00:aa:bb:cc:dd:ee nud perm dev nh2"2579 run_cmd "ip -n $ns2 -6 route add 2001:db8:301::/642580 nexthop via 2001:db8:201::2 nexthop via 2001:db8:202::2"2581 run_cmd "ip netns exec $ns2 sysctl -qw net.ipv6.fib_multipath_hash_policy=1"2582 set +e2583 2584 local dmac=$(ip -n $ns2 -j link show dev veth2 | jq -r '.[]["address"]')2585 local tmp_file=$(mktemp)2586 local cmd="ip netns exec $ns1 mausezahn -6 veth1 -a own -b $dmac2587 -A 2001:db8:101::1 -B 2001:db8:301::1 -t udp 'sp=12345,dp=0-65535' -q"2588 2589 # Packets forwarded in a list using a multipath route must not reuse a2590 # cached result so that a flow always hits the same nexthop. In other2591 # words, the FIB lookup tracepoint needs to be triggered for every2592 # packet.2593 local t0_rx_pkts=$(link_stats_get $ns2 veth2 rx packets)2594 run_cmd "perf stat -a -e fib6:fib6_table_lookup --filter 'err == 0' -j -o $tmp_file -- $cmd"2595 local t1_rx_pkts=$(link_stats_get $ns2 veth2 rx packets)2596 local diff=$(echo $t1_rx_pkts - $t0_rx_pkts | bc -l)2597 list_rcv_eval $tmp_file $diff2598 2599 rm $tmp_file2600 route_cleanup2601}2602 2603################################################################################2604# usage2605 2606usage()2607{2608 cat <<EOF2609usage: ${0##*/} OPTS2610 2611 -t <test> Test(s) to run (default: all)2612 (options: $TESTS)2613 -p Pause on fail2614 -P Pause after each test before cleanup2615 -v verbose mode (show commands and output)2616EOF2617}2618 2619################################################################################2620# main2621 2622trap cleanup EXIT2623 2624while getopts :t:pPhv o2625do2626 case $o in2627 t) TESTS=$OPTARG;;2628 p) PAUSE_ON_FAIL=yes;;2629 P) PAUSE=yes;;2630 v) VERBOSE=$(($VERBOSE + 1));;2631 h) usage; exit 0;;2632 *) usage; exit 1;;2633 esac2634done2635 2636PEER_CMD="ip netns exec ${PEER_NS}"2637 2638# make sure we don't pause twice2639[ "${PAUSE}" = "yes" ] && PAUSE_ON_FAIL=no2640 2641if [ "$(id -u)" -ne 0 ];then2642 echo "SKIP: Need root privileges"2643 exit $ksft_skip;2644fi2645 2646if [ ! -x "$(command -v ip)" ]; then2647 echo "SKIP: Could not run test without ip tool"2648 exit $ksft_skip2649fi2650 2651ip route help 2>&1 | grep -q fibmatch2652if [ $? -ne 0 ]; then2653 echo "SKIP: iproute2 too old, missing fibmatch"2654 exit $ksft_skip2655fi2656 2657# start clean2658cleanup &> /dev/null2659 2660for t in $TESTS2661do2662 case $t in2663 fib_unreg_test|unregister) fib_unreg_test;;2664 fib_down_test|down) fib_down_test;;2665 fib_carrier_test|carrier) fib_carrier_test;;2666 fib_rp_filter_test|rp_filter) fib_rp_filter_test;;2667 fib_nexthop_test|nexthop) fib_nexthop_test;;2668 fib_notify_test|ipv4_notify) fib_notify_test;;2669 fib6_notify_test|ipv6_notify) fib6_notify_test;;2670 fib_suppress_test|suppress) fib_suppress_test;;2671 ipv6_route_test|ipv6_rt) ipv6_route_test;;2672 ipv4_route_test|ipv4_rt) ipv4_route_test;;2673 ipv6_addr_metric) ipv6_addr_metric_test;;2674 ipv4_addr_metric) ipv4_addr_metric_test;;2675 ipv4_del_addr) ipv4_del_addr_test;;2676 ipv6_del_addr) ipv6_del_addr_test;;2677 ipv6_route_metrics) ipv6_route_metrics_test;;2678 ipv4_route_metrics) ipv4_route_metrics_test;;2679 ipv4_route_v6_gw) ipv4_route_v6_gw_test;;2680 ipv4_mangle) ipv4_mangle_test;;2681 ipv6_mangle) ipv6_mangle_test;;2682 ipv4_bcast_neigh) ipv4_bcast_neigh_test;;2683 fib6_gc_test|ipv6_gc) fib6_gc_test;;2684 ipv4_mpath_list) ipv4_mpath_list_test;;2685 ipv6_mpath_list) ipv6_mpath_list_test;;2686 2687 help) echo "Test names: $TESTS"; exit 0;;2688 esac2689done2690 2691if [ "$TESTS" != "none" ]; then2692 printf "\nTests passed: %3d\n" ${nsuccess}2693 printf "Tests failed: %3d\n" ${nfail}2694fi2695 2696exit $ret2697