1#!/bin/bash 2# SPDX-License-Identifier: GPL-2.0 3 4# This test is for checking IPv4 and IPv6 FIB behavior in response to 5# different events. 6 7ret=0 8# Kselftest framework requirement - SKIP code is 4. 9ksft_skip=4 10 11# all tests in this script. Can be overridden with -t option 12TESTS="unregister down carrier nexthop ipv6_rt ipv4_rt ipv6_addr_metric ipv4_addr_metric" 13VERBOSE=0 14PAUSE_ON_FAIL=no 15PAUSE=no 16IP="ip -netns testns" 17 18log_test() 19{ 20 local rc=$1 21 local expected=$2 22 local msg="$3" 23 24 if [ ${rc} -eq ${expected} ]; then 25 printf " TEST: %-60s [ OK ]\n" "${msg}" 26 nsuccess=$((nsuccess+1)) 27 else 28 ret=1 29 nfail=$((nfail+1)) 30 printf " TEST: %-60s [FAIL]\n" "${msg}" 31 if [ "${PAUSE_ON_FAIL}" = "yes" ]; then 32 echo 33 echo "hit enter to continue, 'q' to quit" 34 read a 35 [ "$a" = "q" ] && exit 1 36 fi 37 fi 38 39 if [ "${PAUSE}" = "yes" ]; then 40 echo 41 echo "hit enter to continue, 'q' to quit" 42 read a 43 [ "$a" = "q" ] && exit 1 44 fi 45} 46 47setup() 48{ 49 set -e 50 ip netns add testns 51 $IP link set dev lo up 52 53 $IP link add dummy0 type dummy 54 $IP link set dev dummy0 up 55 $IP address add 198.51.100.1/24 dev dummy0 56 $IP -6 address add 2001:db8:1::1/64 dev dummy0 57 set +e 58 59} 60 61cleanup() 62{ 63 $IP link del dev dummy0 &> /dev/null 64 ip netns del testns 65} 66 67get_linklocal() 68{ 69 local dev=$1 70 local addr 71 72 addr=$($IP -6 -br addr show dev ${dev} | \ 73 awk '{ 74 for (i = 3; i <= NF; ++i) { 75 if ($i ~ /^fe80/) 76 print $i 77 } 78 }' 79 ) 80 addr=${addr/\/*} 81 82 [ -z "$addr" ] && return 1 83 84 echo $addr 85 86 return 0 87} 88 89fib_unreg_unicast_test() 90{ 91 echo 92 echo "Single path route test" 93 94 setup 95 96 echo " Start point" 97 $IP route get fibmatch 198.51.100.2 &> /dev/null 98 log_test $? 0 "IPv4 fibmatch" 99 $IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null 100 log_test $? 0 "IPv6 fibmatch" 101 102 set -e 103 $IP link del dev dummy0 104 set +e 105 106 echo " Nexthop device deleted" 107 $IP route get fibmatch 198.51.100.2 &> /dev/null 108 log_test $? 2 "IPv4 fibmatch - no route" 109 $IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null 110 log_test $? 2 "IPv6 fibmatch - no route" 111 112 cleanup 113} 114 115fib_unreg_multipath_test() 116{ 117 118 echo 119 echo "Multipath route test" 120 121 setup 122 123 set -e 124 $IP link add dummy1 type dummy 125 $IP link set dev dummy1 up 126 $IP address add 192.0.2.1/24 dev dummy1 127 $IP -6 address add 2001:db8:2::1/64 dev dummy1 128 129 $IP route add 203.0.113.0/24 \ 130 nexthop via 198.51.100.2 dev dummy0 \ 131 nexthop via 192.0.2.2 dev dummy1 132 $IP -6 route add 2001:db8:3::/64 \ 133 nexthop via 2001:db8:1::2 dev dummy0 \ 134 nexthop via 2001:db8:2::2 dev dummy1 135 set +e 136 137 echo " Start point" 138 $IP route get fibmatch 203.0.113.1 &> /dev/null 139 log_test $? 0 "IPv4 fibmatch" 140 $IP -6 route get fibmatch 2001:db8:3::1 &> /dev/null 141 log_test $? 0 "IPv6 fibmatch" 142 143 set -e 144 $IP link del dev dummy0 145 set +e 146 147 echo " One nexthop device deleted" 148 $IP route get fibmatch 203.0.113.1 &> /dev/null 149 log_test $? 2 "IPv4 - multipath route removed on delete" 150 151 $IP -6 route get fibmatch 2001:db8:3::1 &> /dev/null 152 # In IPv6 we do not flush the entire multipath route. 153 log_test $? 0 "IPv6 - multipath down to single path" 154 155 set -e 156 $IP link del dev dummy1 157 set +e 158 159 echo " Second nexthop device deleted" 160 $IP -6 route get fibmatch 2001:db8:3::1 &> /dev/null 161 log_test $? 2 "IPv6 - no route" 162 163 cleanup 164} 165 166fib_unreg_test() 167{ 168 fib_unreg_unicast_test 169 fib_unreg_multipath_test 170} 171 172fib_down_unicast_test() 173{ 174 echo 175 echo "Single path, admin down" 176 177 setup 178 179 echo " Start point" 180 $IP route get fibmatch 198.51.100.2 &> /dev/null 181 log_test $? 0 "IPv4 fibmatch" 182 $IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null 183 log_test $? 0 "IPv6 fibmatch" 184 185 set -e 186 $IP link set dev dummy0 down 187 set +e 188 189 echo " Route deleted on down" 190 $IP route get fibmatch 198.51.100.2 &> /dev/null 191 log_test $? 2 "IPv4 fibmatch" 192 $IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null 193 log_test $? 2 "IPv6 fibmatch" 194 195 cleanup 196} 197 198fib_down_multipath_test_do() 199{ 200 local down_dev=$1 201 local up_dev=$2 202 203 $IP route get fibmatch 203.0.113.1 \ 204 oif $down_dev &> /dev/null 205 log_test $? 2 "IPv4 fibmatch on down device" 206 $IP -6 route get fibmatch 2001:db8:3::1 \ 207 oif $down_dev &> /dev/null 208 log_test $? 2 "IPv6 fibmatch on down device" 209 210 $IP route get fibmatch 203.0.113.1 \ 211 oif $up_dev &> /dev/null 212 log_test $? 0 "IPv4 fibmatch on up device" 213 $IP -6 route get fibmatch 2001:db8:3::1 \ 214 oif $up_dev &> /dev/null 215 log_test $? 0 "IPv6 fibmatch on up device" 216 217 $IP route get fibmatch 203.0.113.1 | \ 218 grep $down_dev | grep -q "dead linkdown" 219 log_test $? 0 "IPv4 flags on down device" 220 $IP -6 route get fibmatch 2001:db8:3::1 | \ 221 grep $down_dev | grep -q "dead linkdown" 222 log_test $? 0 "IPv6 flags on down device" 223 224 $IP route get fibmatch 203.0.113.1 | \ 225 grep $up_dev | grep -q "dead linkdown" 226 log_test $? 1 "IPv4 flags on up device" 227 $IP -6 route get fibmatch 2001:db8:3::1 | \ 228 grep $up_dev | grep -q "dead linkdown" 229 log_test $? 1 "IPv6 flags on up device" 230} 231 232fib_down_multipath_test() 233{ 234 echo 235 echo "Admin down multipath" 236 237 setup 238 239 set -e 240 $IP link add dummy1 type dummy 241 $IP link set dev dummy1 up 242 243 $IP address add 192.0.2.1/24 dev dummy1 244 $IP -6 address add 2001:db8:2::1/64 dev dummy1 245 246 $IP route add 203.0.113.0/24 \ 247 nexthop via 198.51.100.2 dev dummy0 \ 248 nexthop via 192.0.2.2 dev dummy1 249 $IP -6 route add 2001:db8:3::/64 \ 250 nexthop via 2001:db8:1::2 dev dummy0 \ 251 nexthop via 2001:db8:2::2 dev dummy1 252 set +e 253 254 echo " Verify start point" 255 $IP route get fibmatch 203.0.113.1 &> /dev/null 256 log_test $? 0 "IPv4 fibmatch" 257 258 $IP -6 route get fibmatch 2001:db8:3::1 &> /dev/null 259 log_test $? 0 "IPv6 fibmatch" 260 261 set -e 262 $IP link set dev dummy0 down 263 set +e 264 265 echo " One device down, one up" 266 fib_down_multipath_test_do "dummy0" "dummy1" 267 268 set -e 269 $IP link set dev dummy0 up 270 $IP link set dev dummy1 down 271 set +e 272 273 echo " Other device down and up" 274 fib_down_multipath_test_do "dummy1" "dummy0" 275 276 set -e 277 $IP link set dev dummy0 down 278 set +e 279 280 echo " Both devices down" 281 $IP route get fibmatch 203.0.113.1 &> /dev/null 282 log_test $? 2 "IPv4 fibmatch" 283 $IP -6 route get fibmatch 2001:db8:3::1 &> /dev/null 284 log_test $? 2 "IPv6 fibmatch" 285 286 $IP link del dev dummy1 287 cleanup 288} 289 290fib_down_test() 291{ 292 fib_down_unicast_test 293 fib_down_multipath_test 294} 295 296# Local routes should not be affected when carrier changes. 297fib_carrier_local_test() 298{ 299 echo 300 echo "Local carrier tests - single path" 301 302 setup 303 304 set -e 305 $IP link set dev dummy0 carrier on 306 set +e 307 308 echo " Start point" 309 $IP route get fibmatch 198.51.100.1 &> /dev/null 310 log_test $? 0 "IPv4 fibmatch" 311 $IP -6 route get fibmatch 2001:db8:1::1 &> /dev/null 312 log_test $? 0 "IPv6 fibmatch" 313 314 $IP route get fibmatch 198.51.100.1 | \ 315 grep -q "linkdown" 316 log_test $? 1 "IPv4 - no linkdown flag" 317 $IP -6 route get fibmatch 2001:db8:1::1 | \ 318 grep -q "linkdown" 319 log_test $? 1 "IPv6 - no linkdown flag" 320 321 set -e 322 $IP link set dev dummy0 carrier off 323 sleep 1 324 set +e 325 326 echo " Carrier off on nexthop" 327 $IP route get fibmatch 198.51.100.1 &> /dev/null 328 log_test $? 0 "IPv4 fibmatch" 329 $IP -6 route get fibmatch 2001:db8:1::1 &> /dev/null 330 log_test $? 0 "IPv6 fibmatch" 331 332 $IP route get fibmatch 198.51.100.1 | \ 333 grep -q "linkdown" 334 log_test $? 1 "IPv4 - linkdown flag set" 335 $IP -6 route get fibmatch 2001:db8:1::1 | \ 336 grep -q "linkdown" 337 log_test $? 1 "IPv6 - linkdown flag set" 338 339 set -e 340 $IP address add 192.0.2.1/24 dev dummy0 341 $IP -6 address add 2001:db8:2::1/64 dev dummy0 342 set +e 343 344 echo " Route to local address with carrier down" 345 $IP route get fibmatch 192.0.2.1 &> /dev/null 346 log_test $? 0 "IPv4 fibmatch" 347 $IP -6 route get fibmatch 2001:db8:2::1 &> /dev/null 348 log_test $? 0 "IPv6 fibmatch" 349 350 $IP route get fibmatch 192.0.2.1 | \ 351 grep -q "linkdown" 352 log_test $? 1 "IPv4 linkdown flag set" 353 $IP -6 route get fibmatch 2001:db8:2::1 | \ 354 grep -q "linkdown" 355 log_test $? 1 "IPv6 linkdown flag set" 356 357 cleanup 358} 359 360fib_carrier_unicast_test() 361{ 362 ret=0 363 364 echo 365 echo "Single path route carrier test" 366 367 setup 368 369 set -e 370 $IP link set dev dummy0 carrier on 371 set +e 372 373 echo " Start point" 374 $IP route get fibmatch 198.51.100.2 &> /dev/null 375 log_test $? 0 "IPv4 fibmatch" 376 $IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null 377 log_test $? 0 "IPv6 fibmatch" 378 379 $IP route get fibmatch 198.51.100.2 | \ 380 grep -q "linkdown" 381 log_test $? 1 "IPv4 no linkdown flag" 382 $IP -6 route get fibmatch 2001:db8:1::2 | \ 383 grep -q "linkdown" 384 log_test $? 1 "IPv6 no linkdown flag" 385 386 set -e 387 $IP link set dev dummy0 carrier off 388 set +e 389 390 echo " Carrier down" 391 $IP route get fibmatch 198.51.100.2 &> /dev/null 392 log_test $? 0 "IPv4 fibmatch" 393 $IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null 394 log_test $? 0 "IPv6 fibmatch" 395 396 $IP route get fibmatch 198.51.100.2 | \ 397 grep -q "linkdown" 398 log_test $? 0 "IPv4 linkdown flag set" 399 $IP -6 route get fibmatch 2001:db8:1::2 | \ 400 grep -q "linkdown" 401 log_test $? 0 "IPv6 linkdown flag set" 402 403 set -e 404 $IP address add 192.0.2.1/24 dev dummy0 405 $IP -6 address add 2001:db8:2::1/64 dev dummy0 406 set +e 407 408 echo " Second address added with carrier down" 409 $IP route get fibmatch 192.0.2.2 &> /dev/null 410 log_test $? 0 "IPv4 fibmatch" 411 $IP -6 route get fibmatch 2001:db8:2::2 &> /dev/null 412 log_test $? 0 "IPv6 fibmatch" 413 414 $IP route get fibmatch 192.0.2.2 | \ 415 grep -q "linkdown" 416 log_test $? 0 "IPv4 linkdown flag set" 417 $IP -6 route get fibmatch 2001:db8:2::2 | \ 418 grep -q "linkdown" 419 log_test $? 0 "IPv6 linkdown flag set" 420 421 cleanup 422} 423 424fib_carrier_test() 425{ 426 fib_carrier_local_test 427 fib_carrier_unicast_test 428} 429 430################################################################################ 431# Tests on nexthop spec 432 433# run 'ip route add' with given spec 434add_rt() 435{ 436 local desc="$1" 437 local erc=$2 438 local vrf=$3 439 local pfx=$4 440 local gw=$5 441 local dev=$6 442 local cmd out rc 443 444 [ "$vrf" = "-" ] && vrf="default" 445 [ -n "$gw" ] && gw="via $gw" 446 [ -n "$dev" ] && dev="dev $dev" 447 448 cmd="$IP route add vrf $vrf $pfx $gw $dev" 449 if [ "$VERBOSE" = "1" ]; then 450 printf "\n COMMAND: $cmd\n" 451 fi 452 453 out=$(eval $cmd 2>&1) 454 rc=$? 455 if [ "$VERBOSE" = "1" -a -n "$out" ]; then 456 echo " $out" 457 fi 458 log_test $rc $erc "$desc" 459} 460 461fib4_nexthop() 462{ 463 echo 464 echo "IPv4 nexthop tests" 465 466 echo "<<< write me >>>" 467} 468 469fib6_nexthop() 470{ 471 local lldummy=$(get_linklocal dummy0) 472 local llv1=$(get_linklocal dummy0) 473 474 if [ -z "$lldummy" ]; then 475 echo "Failed to get linklocal address for dummy0" 476 return 1 477 fi 478 if [ -z "$llv1" ]; then 479 echo "Failed to get linklocal address for veth1" 480 return 1 481 fi 482 483 echo 484 echo "IPv6 nexthop tests" 485 486 add_rt "Directly connected nexthop, unicast address" 0 \ 487 - 2001:db8:101::/64 2001:db8:1::2 488 add_rt "Directly connected nexthop, unicast address with device" 0 \ 489 - 2001:db8:102::/64 2001:db8:1::2 "dummy0" 490 add_rt "Gateway is linklocal address" 0 \ 491 - 2001:db8:103::1/64 $llv1 "veth0" 492 493 # fails because LL address requires a device 494 add_rt "Gateway is linklocal address, no device" 2 \ 495 - 2001:db8:104::1/64 $llv1 496 497 # local address can not be a gateway 498 add_rt "Gateway can not be local unicast address" 2 \ 499 - 2001:db8:105::/64 2001:db8:1::1 500 add_rt "Gateway can not be local unicast address, with device" 2 \ 501 - 2001:db8:106::/64 2001:db8:1::1 "dummy0" 502 add_rt "Gateway can not be a local linklocal address" 2 \ 503 - 2001:db8:107::1/64 $lldummy "dummy0" 504 505 # VRF tests 506 add_rt "Gateway can be local address in a VRF" 0 \ 507 - 2001:db8:108::/64 2001:db8:51::2 508 add_rt "Gateway can be local address in a VRF, with device" 0 \ 509 - 2001:db8:109::/64 2001:db8:51::2 "veth0" 510 add_rt "Gateway can be local linklocal address in a VRF" 0 \ 511 - 2001:db8:110::1/64 $llv1 "veth0" 512 513 add_rt "Redirect to VRF lookup" 0 \ 514 - 2001:db8:111::/64 "" "red" 515 516 add_rt "VRF route, gateway can be local address in default VRF" 0 \ 517 red 2001:db8:112::/64 2001:db8:51::1 518 519 # local address in same VRF fails 520 add_rt "VRF route, gateway can not be a local address" 2 \ 521 red 2001:db8:113::1/64 2001:db8:2::1 522 add_rt "VRF route, gateway can not be a local addr with device" 2 \ 523 red 2001:db8:114::1/64 2001:db8:2::1 "dummy1" 524} 525 526# Default VRF: 527# dummy0 - 198.51.100.1/24 2001:db8:1::1/64 528# veth0 - 192.0.2.1/24 2001:db8:51::1/64 529# 530# VRF red: 531# dummy1 - 192.168.2.1/24 2001:db8:2::1/64 532# veth1 - 192.0.2.2/24 2001:db8:51::2/64 533# 534# [ dummy0 veth0 ]--[ veth1 dummy1 ] 535 536fib_nexthop_test() 537{ 538 setup 539 540 set -e 541 542 $IP -4 rule add pref 32765 table local 543 $IP -4 rule del pref 0 544 $IP -6 rule add pref 32765 table local 545 $IP -6 rule del pref 0 546 547 $IP link add red type vrf table 1 548 $IP link set red up 549 $IP -4 route add vrf red unreachable default metric 4278198272 550 $IP -6 route add vrf red unreachable default metric 4278198272 551 552 $IP link add veth0 type veth peer name veth1 553 $IP link set dev veth0 up 554 $IP address add 192.0.2.1/24 dev veth0 555 $IP -6 address add 2001:db8:51::1/64 dev veth0 556 557 $IP link set dev veth1 vrf red up 558 $IP address add 192.0.2.2/24 dev veth1 559 $IP -6 address add 2001:db8:51::2/64 dev veth1 560 561 $IP link add dummy1 type dummy 562 $IP link set dev dummy1 vrf red up 563 $IP address add 192.168.2.1/24 dev dummy1 564 $IP -6 address add 2001:db8:2::1/64 dev dummy1 565 set +e 566 567 sleep 1 568 fib4_nexthop 569 fib6_nexthop 570 571 ( 572 $IP link del dev dummy1 573 $IP link del veth0 574 $IP link del red 575 ) 2>/dev/null 576 cleanup 577} 578 579################################################################################ 580# Tests on route add and replace 581 582run_cmd() 583{ 584 local cmd="$1" 585 local out 586 local stderr="2>/dev/null" 587 588 if [ "$VERBOSE" = "1" ]; then 589 printf " COMMAND: $cmd\n" 590 stderr= 591 fi 592 593 out=$(eval $cmd $stderr) 594 rc=$? 595 if [ "$VERBOSE" = "1" -a -n "$out" ]; then 596 echo " $out" 597 fi 598 599 [ "$VERBOSE" = "1" ] && echo 600 601 return $rc 602} 603 604# add route for a prefix, flushing any existing routes first 605# expected to be the first step of a test 606add_route6() 607{ 608 local pfx="$1" 609 local nh="$2" 610 local out 611 612 if [ "$VERBOSE" = "1" ]; then 613 echo 614 echo " ##################################################" 615 echo 616 fi 617 618 run_cmd "$IP -6 ro flush ${pfx}" 619 [ $? -ne 0 ] && exit 1 620 621 out=$($IP -6 ro ls match ${pfx}) 622 if [ -n "$out" ]; then 623 echo "Failed to flush routes for prefix used for tests." 624 exit 1 625 fi 626 627 run_cmd "$IP -6 ro add ${pfx} ${nh}" 628 if [ $? -ne 0 ]; then 629 echo "Failed to add initial route for test." 630 exit 1 631 fi 632} 633 634# add initial route - used in replace route tests 635add_initial_route6() 636{ 637 add_route6 "2001:db8:104::/64" "$1" 638} 639 640check_route6() 641{ 642 local pfx="2001:db8:104::/64" 643 local expected="$1" 644 local out 645 local rc=0 646 647 out=$($IP -6 ro ls match ${pfx} | sed -e 's/ pref medium//') 648 [ "${out}" = "${expected}" ] && return 0 649 650 if [ -z "${out}" ]; then 651 if [ "$VERBOSE" = "1" ]; then 652 printf "\nNo route entry found\n" 653 printf "Expected:\n" 654 printf " ${expected}\n" 655 fi 656 return 1 657 fi 658 659 # tricky way to convert output to 1-line without ip's 660 # messy '\'; this drops all extra white space 661 out=$(echo ${out}) 662 if [ "${out}" != "${expected}" ]; then 663 rc=1 664 if [ "${VERBOSE}" = "1" ]; then 665 printf " Unexpected route entry. Have:\n" 666 printf " ${out}\n" 667 printf " Expected:\n" 668 printf " ${expected}\n\n" 669 fi 670 fi 671 672 return $rc 673} 674 675route_cleanup() 676{ 677 $IP li del red 2>/dev/null 678 $IP li del dummy1 2>/dev/null 679 $IP li del veth1 2>/dev/null 680 $IP li del veth3 2>/dev/null 681 682 cleanup &> /dev/null 683} 684 685route_setup() 686{ 687 route_cleanup 688 setup 689 690 [ "${VERBOSE}" = "1" ] && set -x 691 set -e 692 693 $IP li add red up type vrf table 101 694 $IP li add veth1 type veth peer name veth2 695 $IP li add veth3 type veth peer name veth4 696 697 $IP li set veth1 up 698 $IP li set veth3 up 699 $IP li set veth2 vrf red up 700 $IP li set veth4 vrf red up 701 $IP li add dummy1 type dummy 702 $IP li set dummy1 vrf red up 703 704 $IP -6 addr add 2001:db8:101::1/64 dev veth1 705 $IP -6 addr add 2001:db8:101::2/64 dev veth2 706 $IP -6 addr add 2001:db8:103::1/64 dev veth3 707 $IP -6 addr add 2001:db8:103::2/64 dev veth4 708 $IP -6 addr add 2001:db8:104::1/64 dev dummy1 709 710 $IP addr add 172.16.101.1/24 dev veth1 711 $IP addr add 172.16.101.2/24 dev veth2 712 $IP addr add 172.16.103.1/24 dev veth3 713 $IP addr add 172.16.103.2/24 dev veth4 714 $IP addr add 172.16.104.1/24 dev dummy1 715 716 set +ex 717} 718 719# assumption is that basic add of a single path route works 720# otherwise just adding an address on an interface is broken 721ipv6_rt_add() 722{ 723 local rc 724 725 echo 726 echo "IPv6 route add / append tests" 727 728 # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL 729 add_route6 "2001:db8:104::/64" "via 2001:db8:101::2" 730 run_cmd "$IP -6 ro add 2001:db8:104::/64 via 2001:db8:103::2" 731 log_test $? 2 "Attempt to add duplicate route - gw" 732 733 # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL 734 add_route6 "2001:db8:104::/64" "via 2001:db8:101::2" 735 run_cmd "$IP -6 ro add 2001:db8:104::/64 dev veth3" 736 log_test $? 2 "Attempt to add duplicate route - dev only" 737 738 # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL 739 add_route6 "2001:db8:104::/64" "via 2001:db8:101::2" 740 run_cmd "$IP -6 ro add unreachable 2001:db8:104::/64" 741 log_test $? 2 "Attempt to add duplicate route - reject route" 742 743 # iproute2 prepend only sets NLM_F_CREATE 744 # - adds a new route; does NOT convert existing route to ECMP 745 add_route6 "2001:db8:104::/64" "via 2001:db8:101::2" 746 run_cmd "$IP -6 ro prepend 2001:db8:104::/64 via 2001:db8:103::2" 747 check_route6 "2001:db8:104::/64 via 2001:db8:101::2 dev veth1 metric 1024 2001:db8:104::/64 via 2001:db8:103::2 dev veth3 metric 1024" 748 log_test $? 0 "Add new route for existing prefix (w/o NLM_F_EXCL)" 749 750 # route append with same prefix adds a new route 751 # - iproute2 sets NLM_F_CREATE | NLM_F_APPEND 752 add_route6 "2001:db8:104::/64" "via 2001:db8:101::2" 753 run_cmd "$IP -6 ro append 2001:db8:104::/64 via 2001:db8:103::2" 754 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" 755 log_test $? 0 "Append nexthop to existing route - gw" 756 757 add_route6 "2001:db8:104::/64" "via 2001:db8:101::2" 758 run_cmd "$IP -6 ro append 2001:db8:104::/64 dev veth3" 759 check_route6 "2001:db8:104::/64 metric 1024 nexthop via 2001:db8:101::2 dev veth1 weight 1 nexthop dev veth3 weight 1" 760 log_test $? 0 "Append nexthop to existing route - dev only" 761 762 # multipath route can not have a nexthop that is a reject route 763 add_route6 "2001:db8:104::/64" "via 2001:db8:101::2" 764 run_cmd "$IP -6 ro append unreachable 2001:db8:104::/64" 765 log_test $? 2 "Append nexthop to existing route - reject route" 766 767 # reject route can not be converted to multipath route 768 run_cmd "$IP -6 ro flush 2001:db8:104::/64" 769 run_cmd "$IP -6 ro add unreachable 2001:db8:104::/64" 770 run_cmd "$IP -6 ro append 2001:db8:104::/64 via 2001:db8:103::2" 771 log_test $? 2 "Append nexthop to existing reject route - gw" 772 773 run_cmd "$IP -6 ro flush 2001:db8:104::/64" 774 run_cmd "$IP -6 ro add unreachable 2001:db8:104::/64" 775 run_cmd "$IP -6 ro append 2001:db8:104::/64 dev veth3" 776 log_test $? 2 "Append nexthop to existing reject route - dev only" 777 778 # insert mpath directly 779 add_route6 "2001:db8:104::/64" "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2" 780 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" 781 log_test $? 0 "Add multipath route" 782 783 add_route6 "2001:db8:104::/64" "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2" 784 run_cmd "$IP -6 ro add 2001:db8:104::/64 nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2" 785 log_test $? 2 "Attempt to add duplicate multipath route" 786 787 # insert of a second route without append but different metric 788 add_route6 "2001:db8:104::/64" "via 2001:db8:101::2" 789 run_cmd "$IP -6 ro add 2001:db8:104::/64 via 2001:db8:103::2 metric 512" 790 rc=$? 791 if [ $rc -eq 0 ]; then 792 run_cmd "$IP -6 ro add 2001:db8:104::/64 via 2001:db8:103::3 metric 256" 793 rc=$? 794 fi 795 log_test $rc 0 "Route add with different metrics" 796 797 run_cmd "$IP -6 ro del 2001:db8:104::/64 metric 512" 798 rc=$? 799 if [ $rc -eq 0 ]; then 800 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" 801 rc=$? 802 fi 803 log_test $rc 0 "Route delete with metric" 804} 805 806ipv6_rt_replace_single() 807{ 808 # single path with single path 809 # 810 add_initial_route6 "via 2001:db8:101::2" 811 run_cmd "$IP -6 ro replace 2001:db8:104::/64 via 2001:db8:103::2" 812 check_route6 "2001:db8:104::/64 via 2001:db8:103::2 dev veth3 metric 1024" 813 log_test $? 0 "Single path with single path" 814 815 # single path with multipath 816 # 817 add_initial_route6 "nexthop via 2001:db8:101::2" 818 run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:101::3 nexthop via 2001:db8:103::2" 819 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" 820 log_test $? 0 "Single path with multipath" 821 822 # single path with reject 823 # 824 add_initial_route6 "nexthop via 2001:db8:101::2" 825 run_cmd "$IP -6 ro replace unreachable 2001:db8:104::/64" 826 check_route6 "unreachable 2001:db8:104::/64 dev lo metric 1024" 827 log_test $? 0 "Single path with reject route" 828 829 # single path with single path using MULTIPATH attribute 830 # 831 add_initial_route6 "via 2001:db8:101::2" 832 run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:103::2" 833 check_route6 "2001:db8:104::/64 via 2001:db8:103::2 dev veth3 metric 1024" 834 log_test $? 0 "Single path with single path via multipath attribute" 835 836 # route replace fails - invalid nexthop 837 add_initial_route6 "via 2001:db8:101::2" 838 run_cmd "$IP -6 ro replace 2001:db8:104::/64 via 2001:db8:104::2" 839 if [ $? -eq 0 ]; then 840 # previous command is expected to fail so if it returns 0 841 # that means the test failed. 842 log_test 0 1 "Invalid nexthop" 843 else 844 check_route6 "2001:db8:104::/64 via 2001:db8:101::2 dev veth1 metric 1024" 845 log_test $? 0 "Invalid nexthop" 846 fi 847 848 # replace non-existent route 849 # - note use of change versus replace since ip adds NLM_F_CREATE 850 # for replace 851 add_initial_route6 "via 2001:db8:101::2" 852 run_cmd "$IP -6 ro change 2001:db8:105::/64 via 2001:db8:101::2" 853 log_test $? 2 "Single path - replace of non-existent route" 854} 855 856ipv6_rt_replace_mpath() 857{ 858 # multipath with multipath 859 add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2" 860 run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:101::3 nexthop via 2001:db8:103::3" 861 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" 862 log_test $? 0 "Multipath with multipath" 863 864 # multipath with single 865 add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2" 866 run_cmd "$IP -6 ro replace 2001:db8:104::/64 via 2001:db8:101::3" 867 check_route6 "2001:db8:104::/64 via 2001:db8:101::3 dev veth1 metric 1024" 868 log_test $? 0 "Multipath with single path" 869 870 # multipath with single 871 add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2" 872 run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:101::3" 873 check_route6 "2001:db8:104::/64 via 2001:db8:101::3 dev veth1 metric 1024" 874 log_test $? 0 "Multipath with single path via multipath attribute" 875 876 # multipath with reject 877 add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2" 878 run_cmd "$IP -6 ro replace unreachable 2001:db8:104::/64" 879 check_route6 "unreachable 2001:db8:104::/64 dev lo metric 1024" 880 log_test $? 0 "Multipath with reject route" 881 882 # route replace fails - invalid nexthop 1 883 add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2" 884 run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:111::3 nexthop via 2001:db8:103::3" 885 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" 886 log_test $? 0 "Multipath - invalid first nexthop" 887 888 # route replace fails - invalid nexthop 2 889 add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2" 890 run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:101::3 nexthop via 2001:db8:113::3" 891 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" 892 log_test $? 0 "Multipath - invalid second nexthop" 893 894 # multipath non-existent route 895 add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2" 896 run_cmd "$IP -6 ro change 2001:db8:105::/64 nexthop via 2001:db8:101::3 nexthop via 2001:db8:103::3" 897 log_test $? 2 "Multipath - replace of non-existent route" 898} 899 900ipv6_rt_replace() 901{ 902 echo 903 echo "IPv6 route replace tests" 904 905 ipv6_rt_replace_single 906 ipv6_rt_replace_mpath 907} 908 909ipv6_route_test() 910{ 911 route_setup 912 913 ipv6_rt_add 914 ipv6_rt_replace 915 916 route_cleanup 917} 918 919ip_addr_metric_check() 920{ 921 ip addr help 2>&1 | grep -q metric 922 if [ $? -ne 0 ]; then 923 echo "iproute2 command does not support metric for addresses. Skipping test" 924 return 1 925 fi 926 927 return 0 928} 929 930ipv6_addr_metric_test() 931{ 932 local rc 933 934 echo 935 echo "IPv6 prefix route tests" 936 937 ip_addr_metric_check || return 1 938 939 setup 940 941 set -e 942 $IP li add dummy1 type dummy 943 $IP li add dummy2 type dummy 944 $IP li set dummy1 up 945 $IP li set dummy2 up 946 947 # default entry is metric 256 948 run_cmd "$IP -6 addr add dev dummy1 2001:db8:104::1/64" 949 run_cmd "$IP -6 addr add dev dummy2 2001:db8:104::2/64" 950 set +e 951 952 check_route6 "2001:db8:104::/64 dev dummy1 proto kernel metric 256 2001:db8:104::/64 dev dummy2 proto kernel metric 256" 953 log_test $? 0 "Default metric" 954 955 set -e 956 run_cmd "$IP -6 addr flush dev dummy1" 957 run_cmd "$IP -6 addr add dev dummy1 2001:db8:104::1/64 metric 257" 958 set +e 959 960 check_route6 "2001:db8:104::/64 dev dummy2 proto kernel metric 256 2001:db8:104::/64 dev dummy1 proto kernel metric 257" 961 log_test $? 0 "User specified metric on first device" 962 963 set -e 964 run_cmd "$IP -6 addr flush dev dummy2" 965 run_cmd "$IP -6 addr add dev dummy2 2001:db8:104::2/64 metric 258" 966 set +e 967 968 check_route6 "2001:db8:104::/64 dev dummy1 proto kernel metric 257 2001:db8:104::/64 dev dummy2 proto kernel metric 258" 969 log_test $? 0 "User specified metric on second device" 970 971 run_cmd "$IP -6 addr del dev dummy1 2001:db8:104::1/64 metric 257" 972 rc=$? 973 if [ $rc -eq 0 ]; then 974 check_route6 "2001:db8:104::/64 dev dummy2 proto kernel metric 258" 975 rc=$? 976 fi 977 log_test $rc 0 "Delete of address on first device" 978 979 run_cmd "$IP -6 addr change dev dummy2 2001:db8:104::2/64 metric 259" 980 rc=$? 981 if [ $rc -eq 0 ]; then 982 check_route6 "2001:db8:104::/64 dev dummy2 proto kernel metric 259" 983 rc=$? 984 fi 985 log_test $rc 0 "Modify metric of address" 986 987 # verify prefix route removed on down 988 run_cmd "ip netns exec testns sysctl -qw net.ipv6.conf.all.keep_addr_on_down=1" 989 run_cmd "$IP li set dev dummy2 down" 990 rc=$? 991 if [ $rc -eq 0 ]; then 992 check_route6 "" 993 rc=$? 994 fi 995 log_test $rc 0 "Prefix route removed on link down" 996 997 # verify prefix route re-inserted with assigned metric 998 run_cmd "$IP li set dev dummy2 up" 999 rc=$? 1000 if [ $rc -eq 0 ]; then 1001 check_route6 "2001:db8:104::/64 dev dummy2 proto kernel metric 259" 1002 rc=$? 1003 fi 1004 log_test $rc 0 "Prefix route with metric on link up" 1005 1006 $IP li del dummy1 1007 $IP li del dummy2 1008 cleanup 1009} 1010 1011# add route for a prefix, flushing any existing routes first 1012# expected to be the first step of a test 1013add_route() 1014{ 1015 local pfx="$1" 1016 local nh="$2" 1017 local out 1018 1019 if [ "$VERBOSE" = "1" ]; then 1020 echo 1021 echo " ##################################################" 1022 echo 1023 fi 1024 1025 run_cmd "$IP ro flush ${pfx}" 1026 [ $? -ne 0 ] && exit 1 1027 1028 out=$($IP ro ls match ${pfx}) 1029 if [ -n "$out" ]; then 1030 echo "Failed to flush routes for prefix used for tests." 1031 exit 1 1032 fi 1033 1034 run_cmd "$IP ro add ${pfx} ${nh}" 1035 if [ $? -ne 0 ]; then 1036 echo "Failed to add initial route for test." 1037 exit 1 1038 fi 1039} 1040 1041# add initial route - used in replace route tests 1042add_initial_route() 1043{ 1044 add_route "172.16.104.0/24" "$1" 1045} 1046 1047check_route() 1048{ 1049 local pfx="172.16.104.0/24" 1050 local expected="$1" 1051 local out 1052 local rc=0 1053 1054 out=$($IP ro ls match ${pfx}) 1055 [ "${out}" = "${expected}" ] && return 0 1056 1057 if [ -z "${out}" ]; then 1058 if [ "$VERBOSE" = "1" ]; then 1059 printf "\nNo route entry found\n" 1060 printf "Expected:\n" 1061 printf " ${expected}\n" 1062 fi 1063 return 1 1064 fi 1065 1066 # tricky way to convert output to 1-line without ip's 1067 # messy '\'; this drops all extra white space 1068 out=$(echo ${out}) 1069 if [ "${out}" != "${expected}" ]; then 1070 rc=1 1071 if [ "${VERBOSE}" = "1" ]; then 1072 printf " Unexpected route entry. Have:\n" 1073 printf " ${out}\n" 1074 printf " Expected:\n" 1075 printf " ${expected}\n\n" 1076 fi 1077 fi 1078 1079 return $rc 1080} 1081 1082# assumption is that basic add of a single path route works 1083# otherwise just adding an address on an interface is broken 1084ipv4_rt_add() 1085{ 1086 local rc 1087 1088 echo 1089 echo "IPv4 route add / append tests" 1090 1091 # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL 1092 add_route "172.16.104.0/24" "via 172.16.101.2" 1093 run_cmd "$IP ro add 172.16.104.0/24 via 172.16.103.2" 1094 log_test $? 2 "Attempt to add duplicate route - gw" 1095 1096 # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL 1097 add_route "172.16.104.0/24" "via 172.16.101.2" 1098 run_cmd "$IP ro add 172.16.104.0/24 dev veth3" 1099 log_test $? 2 "Attempt to add duplicate route - dev only" 1100 1101 # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL 1102 add_route "172.16.104.0/24" "via 172.16.101.2" 1103 run_cmd "$IP ro add unreachable 172.16.104.0/24" 1104 log_test $? 2 "Attempt to add duplicate route - reject route" 1105 1106 # iproute2 prepend only sets NLM_F_CREATE 1107 # - adds a new route; does NOT convert existing route to ECMP 1108 add_route "172.16.104.0/24" "via 172.16.101.2" 1109 run_cmd "$IP ro prepend 172.16.104.0/24 via 172.16.103.2" 1110 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" 1111 log_test $? 0 "Add new nexthop for existing prefix" 1112 1113 # route append with same prefix adds a new route 1114 # - iproute2 sets NLM_F_CREATE | NLM_F_APPEND 1115 add_route "172.16.104.0/24" "via 172.16.101.2" 1116 run_cmd "$IP ro append 172.16.104.0/24 via 172.16.103.2" 1117 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" 1118 log_test $? 0 "Append nexthop to existing route - gw" 1119 1120 add_route "172.16.104.0/24" "via 172.16.101.2" 1121 run_cmd "$IP ro append 172.16.104.0/24 dev veth3" 1122 check_route "172.16.104.0/24 via 172.16.101.2 dev veth1 172.16.104.0/24 dev veth3 scope link" 1123 log_test $? 0 "Append nexthop to existing route - dev only" 1124 1125 add_route "172.16.104.0/24" "via 172.16.101.2" 1126 run_cmd "$IP ro append unreachable 172.16.104.0/24" 1127 check_route "172.16.104.0/24 via 172.16.101.2 dev veth1 unreachable 172.16.104.0/24" 1128 log_test $? 0 "Append nexthop to existing route - reject route" 1129 1130 run_cmd "$IP ro flush 172.16.104.0/24" 1131 run_cmd "$IP ro add unreachable 172.16.104.0/24" 1132 run_cmd "$IP ro append 172.16.104.0/24 via 172.16.103.2" 1133 check_route "unreachable 172.16.104.0/24 172.16.104.0/24 via 172.16.103.2 dev veth3" 1134 log_test $? 0 "Append nexthop to existing reject route - gw" 1135 1136 run_cmd "$IP ro flush 172.16.104.0/24" 1137 run_cmd "$IP ro add unreachable 172.16.104.0/24" 1138 run_cmd "$IP ro append 172.16.104.0/24 dev veth3" 1139 check_route "unreachable 172.16.104.0/24 172.16.104.0/24 dev veth3 scope link" 1140 log_test $? 0 "Append nexthop to existing reject route - dev only" 1141 1142 # insert mpath directly 1143 add_route "172.16.104.0/24" "nexthop via 172.16.101.2 nexthop via 172.16.103.2" 1144 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" 1145 log_test $? 0 "add multipath route" 1146 1147 add_route "172.16.104.0/24" "nexthop via 172.16.101.2 nexthop via 172.16.103.2" 1148 run_cmd "$IP ro add 172.16.104.0/24 nexthop via 172.16.101.2 nexthop via 172.16.103.2" 1149 log_test $? 2 "Attempt to add duplicate multipath route" 1150 1151 # insert of a second route without append but different metric 1152 add_route "172.16.104.0/24" "via 172.16.101.2" 1153 run_cmd "$IP ro add 172.16.104.0/24 via 172.16.103.2 metric 512" 1154 rc=$? 1155 if [ $rc -eq 0 ]; then 1156 run_cmd "$IP ro add 172.16.104.0/24 via 172.16.103.3 metric 256" 1157 rc=$? 1158 fi 1159 log_test $rc 0 "Route add with different metrics" 1160 1161 run_cmd "$IP ro del 172.16.104.0/24 metric 512" 1162 rc=$? 1163 if [ $rc -eq 0 ]; then 1164 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" 1165 rc=$? 1166 fi 1167 log_test $rc 0 "Route delete with metric" 1168} 1169 1170ipv4_rt_replace_single() 1171{ 1172 # single path with single path 1173 # 1174 add_initial_route "via 172.16.101.2" 1175 run_cmd "$IP ro replace 172.16.104.0/24 via 172.16.103.2" 1176 check_route "172.16.104.0/24 via 172.16.103.2 dev veth3" 1177 log_test $? 0 "Single path with single path" 1178 1179 # single path with multipath 1180 # 1181 add_initial_route "nexthop via 172.16.101.2" 1182 run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.101.3 nexthop via 172.16.103.2" 1183 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" 1184 log_test $? 0 "Single path with multipath" 1185 1186 # single path with reject 1187 # 1188 add_initial_route "nexthop via 172.16.101.2" 1189 run_cmd "$IP ro replace unreachable 172.16.104.0/24" 1190 check_route "unreachable 172.16.104.0/24" 1191 log_test $? 0 "Single path with reject route" 1192 1193 # single path with single path using MULTIPATH attribute 1194 # 1195 add_initial_route "via 172.16.101.2" 1196 run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.103.2" 1197 check_route "172.16.104.0/24 via 172.16.103.2 dev veth3" 1198 log_test $? 0 "Single path with single path via multipath attribute" 1199 1200 # route replace fails - invalid nexthop 1201 add_initial_route "via 172.16.101.2" 1202 run_cmd "$IP ro replace 172.16.104.0/24 via 2001:db8:104::2" 1203 if [ $? -eq 0 ]; then 1204 # previous command is expected to fail so if it returns 0 1205 # that means the test failed. 1206 log_test 0 1 "Invalid nexthop" 1207 else 1208 check_route "172.16.104.0/24 via 172.16.101.2 dev veth1" 1209 log_test $? 0 "Invalid nexthop" 1210 fi 1211 1212 # replace non-existent route 1213 # - note use of change versus replace since ip adds NLM_F_CREATE 1214 # for replace 1215 add_initial_route "via 172.16.101.2" 1216 run_cmd "$IP ro change 172.16.105.0/24 via 172.16.101.2" 1217 log_test $? 2 "Single path - replace of non-existent route" 1218} 1219 1220ipv4_rt_replace_mpath() 1221{ 1222 # multipath with multipath 1223 add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2" 1224 run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.101.3 nexthop via 172.16.103.3" 1225 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" 1226 log_test $? 0 "Multipath with multipath" 1227 1228 # multipath with single 1229 add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2" 1230 run_cmd "$IP ro replace 172.16.104.0/24 via 172.16.101.3" 1231 check_route "172.16.104.0/24 via 172.16.101.3 dev veth1" 1232 log_test $? 0 "Multipath with single path" 1233 1234 # multipath with single 1235 add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2" 1236 run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.101.3" 1237 check_route "172.16.104.0/24 via 172.16.101.3 dev veth1" 1238 log_test $? 0 "Multipath with single path via multipath attribute" 1239 1240 # multipath with reject 1241 add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2" 1242 run_cmd "$IP ro replace unreachable 172.16.104.0/24" 1243 check_route "unreachable 172.16.104.0/24" 1244 log_test $? 0 "Multipath with reject route" 1245 1246 # route replace fails - invalid nexthop 1 1247 add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2" 1248 run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.111.3 nexthop via 172.16.103.3" 1249 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" 1250 log_test $? 0 "Multipath - invalid first nexthop" 1251 1252 # route replace fails - invalid nexthop 2 1253 add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2" 1254 run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.101.3 nexthop via 172.16.113.3" 1255 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" 1256 log_test $? 0 "Multipath - invalid second nexthop" 1257 1258 # multipath non-existent route 1259 add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2" 1260 run_cmd "$IP ro change 172.16.105.0/24 nexthop via 172.16.101.3 nexthop via 172.16.103.3" 1261 log_test $? 2 "Multipath - replace of non-existent route" 1262} 1263 1264ipv4_rt_replace() 1265{ 1266 echo 1267 echo "IPv4 route replace tests" 1268 1269 ipv4_rt_replace_single 1270 ipv4_rt_replace_mpath 1271} 1272 1273ipv4_route_test() 1274{ 1275 route_setup 1276 1277 ipv4_rt_add 1278 ipv4_rt_replace 1279 1280 route_cleanup 1281} 1282 1283ipv4_addr_metric_test() 1284{ 1285 local rc 1286 1287 echo 1288 echo "IPv4 prefix route tests" 1289 1290 ip_addr_metric_check || return 1 1291 1292 setup 1293 1294 set -e 1295 $IP li add dummy1 type dummy 1296 $IP li add dummy2 type dummy 1297 $IP li set dummy1 up 1298 $IP li set dummy2 up 1299 1300 # default entry is metric 256 1301 run_cmd "$IP addr add dev dummy1 172.16.104.1/24" 1302 run_cmd "$IP addr add dev dummy2 172.16.104.2/24" 1303 set +e 1304 1305 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" 1306 log_test $? 0 "Default metric" 1307 1308 set -e 1309 run_cmd "$IP addr flush dev dummy1" 1310 run_cmd "$IP addr add dev dummy1 172.16.104.1/24 metric 257" 1311 set +e 1312 1313 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" 1314 log_test $? 0 "User specified metric on first device" 1315 1316 set -e 1317 run_cmd "$IP addr flush dev dummy2" 1318 run_cmd "$IP addr add dev dummy2 172.16.104.2/24 metric 258" 1319 set +e 1320 1321 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" 1322 log_test $? 0 "User specified metric on second device" 1323 1324 run_cmd "$IP addr del dev dummy1 172.16.104.1/24 metric 257" 1325 rc=$? 1326 if [ $rc -eq 0 ]; then 1327 check_route "172.16.104.0/24 dev dummy2 proto kernel scope link src 172.16.104.2 metric 258" 1328 rc=$? 1329 fi 1330 log_test $rc 0 "Delete of address on first device" 1331 1332 run_cmd "$IP addr change dev dummy2 172.16.104.2/24 metric 259" 1333 rc=$? 1334 if [ $rc -eq 0 ]; then 1335 check_route "172.16.104.0/24 dev dummy2 proto kernel scope link src 172.16.104.2 metric 259" 1336 rc=$? 1337 fi 1338 log_test $rc 0 "Modify metric of address" 1339 1340 # verify prefix route removed on down 1341 run_cmd "$IP li set dev dummy2 down" 1342 rc=$? 1343 if [ $rc -eq 0 ]; then 1344 check_route "" 1345 rc=$? 1346 fi 1347 log_test $rc 0 "Prefix route removed on link down" 1348 1349 # verify prefix route re-inserted with assigned metric 1350 run_cmd "$IP li set dev dummy2 up" 1351 rc=$? 1352 if [ $rc -eq 0 ]; then 1353 check_route "172.16.104.0/24 dev dummy2 proto kernel scope link src 172.16.104.2 metric 259" 1354 rc=$? 1355 fi 1356 log_test $rc 0 "Prefix route with metric on link up" 1357 1358 $IP li del dummy1 1359 $IP li del dummy2 1360 cleanup 1361} 1362 1363################################################################################ 1364# usage 1365 1366usage() 1367{ 1368 cat <<EOF 1369usage: ${0##*/} OPTS 1370 1371 -t <test> Test(s) to run (default: all) 1372 (options: $TESTS) 1373 -p Pause on fail 1374 -P Pause after each test before cleanup 1375 -v verbose mode (show commands and output) 1376EOF 1377} 1378 1379################################################################################ 1380# main 1381 1382while getopts :t:pPhv o 1383do 1384 case $o in 1385 t) TESTS=$OPTARG;; 1386 p) PAUSE_ON_FAIL=yes;; 1387 P) PAUSE=yes;; 1388 v) VERBOSE=$(($VERBOSE + 1));; 1389 h) usage; exit 0;; 1390 *) usage; exit 1;; 1391 esac 1392done 1393 1394PEER_CMD="ip netns exec ${PEER_NS}" 1395 1396# make sure we don't pause twice 1397[ "${PAUSE}" = "yes" ] && PAUSE_ON_FAIL=no 1398 1399if [ "$(id -u)" -ne 0 ];then 1400 echo "SKIP: Need root privileges" 1401 exit $ksft_skip; 1402fi 1403 1404if [ ! -x "$(command -v ip)" ]; then 1405 echo "SKIP: Could not run test without ip tool" 1406 exit $ksft_skip 1407fi 1408 1409ip route help 2>&1 | grep -q fibmatch 1410if [ $? -ne 0 ]; then 1411 echo "SKIP: iproute2 too old, missing fibmatch" 1412 exit $ksft_skip 1413fi 1414 1415# start clean 1416cleanup &> /dev/null 1417 1418for t in $TESTS 1419do 1420 case $t in 1421 fib_unreg_test|unregister) fib_unreg_test;; 1422 fib_down_test|down) fib_down_test;; 1423 fib_carrier_test|carrier) fib_carrier_test;; 1424 fib_nexthop_test|nexthop) fib_nexthop_test;; 1425 ipv6_route_test|ipv6_rt) ipv6_route_test;; 1426 ipv4_route_test|ipv4_rt) ipv4_route_test;; 1427 ipv6_addr_metric) ipv6_addr_metric_test;; 1428 ipv4_addr_metric) ipv4_addr_metric_test;; 1429 1430 help) echo "Test names: $TESTS"; exit 0;; 1431 esac 1432done 1433 1434if [ "$TESTS" != "none" ]; then 1435 printf "\nTests passed: %3d\n" ${nsuccess} 1436 printf "Tests failed: %3d\n" ${nfail} 1437fi 1438 1439exit $ret 1440