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 # route append with same prefix adds a new route 744 # - iproute2 sets NLM_F_CREATE | NLM_F_APPEND 745 add_route6 "2001:db8:104::/64" "via 2001:db8:101::2" 746 run_cmd "$IP -6 ro append 2001:db8:104::/64 via 2001:db8:103::2" 747 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" 748 log_test $? 0 "Append nexthop to existing route - gw" 749 750 # insert mpath directly 751 add_route6 "2001:db8:104::/64" "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2" 752 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" 753 log_test $? 0 "Add multipath route" 754 755 add_route6 "2001:db8:104::/64" "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2" 756 run_cmd "$IP -6 ro add 2001:db8:104::/64 nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2" 757 log_test $? 2 "Attempt to add duplicate multipath route" 758 759 # insert of a second route without append but different metric 760 add_route6 "2001:db8:104::/64" "via 2001:db8:101::2" 761 run_cmd "$IP -6 ro add 2001:db8:104::/64 via 2001:db8:103::2 metric 512" 762 rc=$? 763 if [ $rc -eq 0 ]; then 764 run_cmd "$IP -6 ro add 2001:db8:104::/64 via 2001:db8:103::3 metric 256" 765 rc=$? 766 fi 767 log_test $rc 0 "Route add with different metrics" 768 769 run_cmd "$IP -6 ro del 2001:db8:104::/64 metric 512" 770 rc=$? 771 if [ $rc -eq 0 ]; then 772 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" 773 rc=$? 774 fi 775 log_test $rc 0 "Route delete with metric" 776} 777 778ipv6_rt_replace_single() 779{ 780 # single path with single path 781 # 782 add_initial_route6 "via 2001:db8:101::2" 783 run_cmd "$IP -6 ro replace 2001:db8:104::/64 via 2001:db8:103::2" 784 check_route6 "2001:db8:104::/64 via 2001:db8:103::2 dev veth3 metric 1024" 785 log_test $? 0 "Single path with single path" 786 787 # single path with multipath 788 # 789 add_initial_route6 "nexthop via 2001:db8:101::2" 790 run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:101::3 nexthop via 2001:db8:103::2" 791 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" 792 log_test $? 0 "Single path with multipath" 793 794 # single path with single path using MULTIPATH attribute 795 # 796 add_initial_route6 "via 2001:db8:101::2" 797 run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:103::2" 798 check_route6 "2001:db8:104::/64 via 2001:db8:103::2 dev veth3 metric 1024" 799 log_test $? 0 "Single path with single path via multipath attribute" 800 801 # route replace fails - invalid nexthop 802 add_initial_route6 "via 2001:db8:101::2" 803 run_cmd "$IP -6 ro replace 2001:db8:104::/64 via 2001:db8:104::2" 804 if [ $? -eq 0 ]; then 805 # previous command is expected to fail so if it returns 0 806 # that means the test failed. 807 log_test 0 1 "Invalid nexthop" 808 else 809 check_route6 "2001:db8:104::/64 via 2001:db8:101::2 dev veth1 metric 1024" 810 log_test $? 0 "Invalid nexthop" 811 fi 812 813 # replace non-existent route 814 # - note use of change versus replace since ip adds NLM_F_CREATE 815 # for replace 816 add_initial_route6 "via 2001:db8:101::2" 817 run_cmd "$IP -6 ro change 2001:db8:105::/64 via 2001:db8:101::2" 818 log_test $? 2 "Single path - replace of non-existent route" 819} 820 821ipv6_rt_replace_mpath() 822{ 823 # multipath with multipath 824 add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2" 825 run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:101::3 nexthop via 2001:db8:103::3" 826 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" 827 log_test $? 0 "Multipath with multipath" 828 829 # multipath with single 830 add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2" 831 run_cmd "$IP -6 ro replace 2001:db8:104::/64 via 2001:db8:101::3" 832 check_route6 "2001:db8:104::/64 via 2001:db8:101::3 dev veth1 metric 1024" 833 log_test $? 0 "Multipath with single path" 834 835 # multipath with single 836 add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2" 837 run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:101::3" 838 check_route6 "2001:db8:104::/64 via 2001:db8:101::3 dev veth1 metric 1024" 839 log_test $? 0 "Multipath with single path via multipath attribute" 840 841 # route replace fails - invalid nexthop 1 842 add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2" 843 run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:111::3 nexthop via 2001:db8:103::3" 844 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" 845 log_test $? 0 "Multipath - invalid first nexthop" 846 847 # route replace fails - invalid nexthop 2 848 add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2" 849 run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:101::3 nexthop via 2001:db8:113::3" 850 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" 851 log_test $? 0 "Multipath - invalid second nexthop" 852 853 # multipath non-existent route 854 add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2" 855 run_cmd "$IP -6 ro change 2001:db8:105::/64 nexthop via 2001:db8:101::3 nexthop via 2001:db8:103::3" 856 log_test $? 2 "Multipath - replace of non-existent route" 857} 858 859ipv6_rt_replace() 860{ 861 echo 862 echo "IPv6 route replace tests" 863 864 ipv6_rt_replace_single 865 ipv6_rt_replace_mpath 866} 867 868ipv6_route_test() 869{ 870 route_setup 871 872 ipv6_rt_add 873 ipv6_rt_replace 874 875 route_cleanup 876} 877 878ip_addr_metric_check() 879{ 880 ip addr help 2>&1 | grep -q metric 881 if [ $? -ne 0 ]; then 882 echo "iproute2 command does not support metric for addresses. Skipping test" 883 return 1 884 fi 885 886 return 0 887} 888 889ipv6_addr_metric_test() 890{ 891 local rc 892 893 echo 894 echo "IPv6 prefix route tests" 895 896 ip_addr_metric_check || return 1 897 898 setup 899 900 set -e 901 $IP li add dummy1 type dummy 902 $IP li add dummy2 type dummy 903 $IP li set dummy1 up 904 $IP li set dummy2 up 905 906 # default entry is metric 256 907 run_cmd "$IP -6 addr add dev dummy1 2001:db8:104::1/64" 908 run_cmd "$IP -6 addr add dev dummy2 2001:db8:104::2/64" 909 set +e 910 911 check_route6 "2001:db8:104::/64 dev dummy1 proto kernel metric 256 2001:db8:104::/64 dev dummy2 proto kernel metric 256" 912 log_test $? 0 "Default metric" 913 914 set -e 915 run_cmd "$IP -6 addr flush dev dummy1" 916 run_cmd "$IP -6 addr add dev dummy1 2001:db8:104::1/64 metric 257" 917 set +e 918 919 check_route6 "2001:db8:104::/64 dev dummy2 proto kernel metric 256 2001:db8:104::/64 dev dummy1 proto kernel metric 257" 920 log_test $? 0 "User specified metric on first device" 921 922 set -e 923 run_cmd "$IP -6 addr flush dev dummy2" 924 run_cmd "$IP -6 addr add dev dummy2 2001:db8:104::2/64 metric 258" 925 set +e 926 927 check_route6 "2001:db8:104::/64 dev dummy1 proto kernel metric 257 2001:db8:104::/64 dev dummy2 proto kernel metric 258" 928 log_test $? 0 "User specified metric on second device" 929 930 run_cmd "$IP -6 addr del dev dummy1 2001:db8:104::1/64 metric 257" 931 rc=$? 932 if [ $rc -eq 0 ]; then 933 check_route6 "2001:db8:104::/64 dev dummy2 proto kernel metric 258" 934 rc=$? 935 fi 936 log_test $rc 0 "Delete of address on first device" 937 938 run_cmd "$IP -6 addr change dev dummy2 2001:db8:104::2/64 metric 259" 939 rc=$? 940 if [ $rc -eq 0 ]; then 941 check_route6 "2001:db8:104::/64 dev dummy2 proto kernel metric 259" 942 rc=$? 943 fi 944 log_test $rc 0 "Modify metric of address" 945 946 # verify prefix route removed on down 947 run_cmd "ip netns exec testns sysctl -qw net.ipv6.conf.all.keep_addr_on_down=1" 948 run_cmd "$IP li set dev dummy2 down" 949 rc=$? 950 if [ $rc -eq 0 ]; then 951 check_route6 "" 952 rc=$? 953 fi 954 log_test $rc 0 "Prefix route removed on link down" 955 956 # verify prefix route re-inserted with assigned metric 957 run_cmd "$IP li set dev dummy2 up" 958 rc=$? 959 if [ $rc -eq 0 ]; then 960 check_route6 "2001:db8:104::/64 dev dummy2 proto kernel metric 259" 961 rc=$? 962 fi 963 log_test $rc 0 "Prefix route with metric on link up" 964 965 $IP li del dummy1 966 $IP li del dummy2 967 cleanup 968} 969 970# add route for a prefix, flushing any existing routes first 971# expected to be the first step of a test 972add_route() 973{ 974 local pfx="$1" 975 local nh="$2" 976 local out 977 978 if [ "$VERBOSE" = "1" ]; then 979 echo 980 echo " ##################################################" 981 echo 982 fi 983 984 run_cmd "$IP ro flush ${pfx}" 985 [ $? -ne 0 ] && exit 1 986 987 out=$($IP ro ls match ${pfx}) 988 if [ -n "$out" ]; then 989 echo "Failed to flush routes for prefix used for tests." 990 exit 1 991 fi 992 993 run_cmd "$IP ro add ${pfx} ${nh}" 994 if [ $? -ne 0 ]; then 995 echo "Failed to add initial route for test." 996 exit 1 997 fi 998} 999 1000# add initial route - used in replace route tests 1001add_initial_route() 1002{ 1003 add_route "172.16.104.0/24" "$1" 1004} 1005 1006check_route() 1007{ 1008 local pfx="172.16.104.0/24" 1009 local expected="$1" 1010 local out 1011 local rc=0 1012 1013 out=$($IP ro ls match ${pfx}) 1014 [ "${out}" = "${expected}" ] && return 0 1015 1016 if [ -z "${out}" ]; then 1017 if [ "$VERBOSE" = "1" ]; then 1018 printf "\nNo route entry found\n" 1019 printf "Expected:\n" 1020 printf " ${expected}\n" 1021 fi 1022 return 1 1023 fi 1024 1025 # tricky way to convert output to 1-line without ip's 1026 # messy '\'; this drops all extra white space 1027 out=$(echo ${out}) 1028 if [ "${out}" != "${expected}" ]; then 1029 rc=1 1030 if [ "${VERBOSE}" = "1" ]; then 1031 printf " Unexpected route entry. Have:\n" 1032 printf " ${out}\n" 1033 printf " Expected:\n" 1034 printf " ${expected}\n\n" 1035 fi 1036 fi 1037 1038 return $rc 1039} 1040 1041# assumption is that basic add of a single path route works 1042# otherwise just adding an address on an interface is broken 1043ipv4_rt_add() 1044{ 1045 local rc 1046 1047 echo 1048 echo "IPv4 route add / append tests" 1049 1050 # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL 1051 add_route "172.16.104.0/24" "via 172.16.101.2" 1052 run_cmd "$IP ro add 172.16.104.0/24 via 172.16.103.2" 1053 log_test $? 2 "Attempt to add duplicate route - gw" 1054 1055 # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL 1056 add_route "172.16.104.0/24" "via 172.16.101.2" 1057 run_cmd "$IP ro add 172.16.104.0/24 dev veth3" 1058 log_test $? 2 "Attempt to add duplicate route - dev only" 1059 1060 # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL 1061 add_route "172.16.104.0/24" "via 172.16.101.2" 1062 run_cmd "$IP ro add unreachable 172.16.104.0/24" 1063 log_test $? 2 "Attempt to add duplicate route - reject route" 1064 1065 # iproute2 prepend only sets NLM_F_CREATE 1066 # - adds a new route; does NOT convert existing route to ECMP 1067 add_route "172.16.104.0/24" "via 172.16.101.2" 1068 run_cmd "$IP ro prepend 172.16.104.0/24 via 172.16.103.2" 1069 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" 1070 log_test $? 0 "Add new nexthop for existing prefix" 1071 1072 # route append with same prefix adds a new route 1073 # - iproute2 sets NLM_F_CREATE | NLM_F_APPEND 1074 add_route "172.16.104.0/24" "via 172.16.101.2" 1075 run_cmd "$IP ro append 172.16.104.0/24 via 172.16.103.2" 1076 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" 1077 log_test $? 0 "Append nexthop to existing route - gw" 1078 1079 add_route "172.16.104.0/24" "via 172.16.101.2" 1080 run_cmd "$IP ro append 172.16.104.0/24 dev veth3" 1081 check_route "172.16.104.0/24 via 172.16.101.2 dev veth1 172.16.104.0/24 dev veth3 scope link" 1082 log_test $? 0 "Append nexthop to existing route - dev only" 1083 1084 add_route "172.16.104.0/24" "via 172.16.101.2" 1085 run_cmd "$IP ro append unreachable 172.16.104.0/24" 1086 check_route "172.16.104.0/24 via 172.16.101.2 dev veth1 unreachable 172.16.104.0/24" 1087 log_test $? 0 "Append nexthop to existing route - reject route" 1088 1089 run_cmd "$IP ro flush 172.16.104.0/24" 1090 run_cmd "$IP ro add unreachable 172.16.104.0/24" 1091 run_cmd "$IP ro append 172.16.104.0/24 via 172.16.103.2" 1092 check_route "unreachable 172.16.104.0/24 172.16.104.0/24 via 172.16.103.2 dev veth3" 1093 log_test $? 0 "Append nexthop to existing reject route - gw" 1094 1095 run_cmd "$IP ro flush 172.16.104.0/24" 1096 run_cmd "$IP ro add unreachable 172.16.104.0/24" 1097 run_cmd "$IP ro append 172.16.104.0/24 dev veth3" 1098 check_route "unreachable 172.16.104.0/24 172.16.104.0/24 dev veth3 scope link" 1099 log_test $? 0 "Append nexthop to existing reject route - dev only" 1100 1101 # insert mpath directly 1102 add_route "172.16.104.0/24" "nexthop via 172.16.101.2 nexthop via 172.16.103.2" 1103 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" 1104 log_test $? 0 "add multipath route" 1105 1106 add_route "172.16.104.0/24" "nexthop via 172.16.101.2 nexthop via 172.16.103.2" 1107 run_cmd "$IP ro add 172.16.104.0/24 nexthop via 172.16.101.2 nexthop via 172.16.103.2" 1108 log_test $? 2 "Attempt to add duplicate multipath route" 1109 1110 # insert of a second route without append but different metric 1111 add_route "172.16.104.0/24" "via 172.16.101.2" 1112 run_cmd "$IP ro add 172.16.104.0/24 via 172.16.103.2 metric 512" 1113 rc=$? 1114 if [ $rc -eq 0 ]; then 1115 run_cmd "$IP ro add 172.16.104.0/24 via 172.16.103.3 metric 256" 1116 rc=$? 1117 fi 1118 log_test $rc 0 "Route add with different metrics" 1119 1120 run_cmd "$IP ro del 172.16.104.0/24 metric 512" 1121 rc=$? 1122 if [ $rc -eq 0 ]; then 1123 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" 1124 rc=$? 1125 fi 1126 log_test $rc 0 "Route delete with metric" 1127} 1128 1129ipv4_rt_replace_single() 1130{ 1131 # single path with single path 1132 # 1133 add_initial_route "via 172.16.101.2" 1134 run_cmd "$IP ro replace 172.16.104.0/24 via 172.16.103.2" 1135 check_route "172.16.104.0/24 via 172.16.103.2 dev veth3" 1136 log_test $? 0 "Single path with single path" 1137 1138 # single path with multipath 1139 # 1140 add_initial_route "nexthop via 172.16.101.2" 1141 run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.101.3 nexthop via 172.16.103.2" 1142 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" 1143 log_test $? 0 "Single path with multipath" 1144 1145 # single path with reject 1146 # 1147 add_initial_route "nexthop via 172.16.101.2" 1148 run_cmd "$IP ro replace unreachable 172.16.104.0/24" 1149 check_route "unreachable 172.16.104.0/24" 1150 log_test $? 0 "Single path with reject route" 1151 1152 # single path with single path using MULTIPATH attribute 1153 # 1154 add_initial_route "via 172.16.101.2" 1155 run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.103.2" 1156 check_route "172.16.104.0/24 via 172.16.103.2 dev veth3" 1157 log_test $? 0 "Single path with single path via multipath attribute" 1158 1159 # route replace fails - invalid nexthop 1160 add_initial_route "via 172.16.101.2" 1161 run_cmd "$IP ro replace 172.16.104.0/24 via 2001:db8:104::2" 1162 if [ $? -eq 0 ]; then 1163 # previous command is expected to fail so if it returns 0 1164 # that means the test failed. 1165 log_test 0 1 "Invalid nexthop" 1166 else 1167 check_route "172.16.104.0/24 via 172.16.101.2 dev veth1" 1168 log_test $? 0 "Invalid nexthop" 1169 fi 1170 1171 # replace non-existent route 1172 # - note use of change versus replace since ip adds NLM_F_CREATE 1173 # for replace 1174 add_initial_route "via 172.16.101.2" 1175 run_cmd "$IP ro change 172.16.105.0/24 via 172.16.101.2" 1176 log_test $? 2 "Single path - replace of non-existent route" 1177} 1178 1179ipv4_rt_replace_mpath() 1180{ 1181 # multipath with multipath 1182 add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2" 1183 run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.101.3 nexthop via 172.16.103.3" 1184 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" 1185 log_test $? 0 "Multipath with multipath" 1186 1187 # multipath with single 1188 add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2" 1189 run_cmd "$IP ro replace 172.16.104.0/24 via 172.16.101.3" 1190 check_route "172.16.104.0/24 via 172.16.101.3 dev veth1" 1191 log_test $? 0 "Multipath with single path" 1192 1193 # multipath with single 1194 add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2" 1195 run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.101.3" 1196 check_route "172.16.104.0/24 via 172.16.101.3 dev veth1" 1197 log_test $? 0 "Multipath with single path via multipath attribute" 1198 1199 # multipath with reject 1200 add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2" 1201 run_cmd "$IP ro replace unreachable 172.16.104.0/24" 1202 check_route "unreachable 172.16.104.0/24" 1203 log_test $? 0 "Multipath with reject route" 1204 1205 # route replace fails - invalid nexthop 1 1206 add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2" 1207 run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.111.3 nexthop via 172.16.103.3" 1208 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" 1209 log_test $? 0 "Multipath - invalid first nexthop" 1210 1211 # route replace fails - invalid nexthop 2 1212 add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2" 1213 run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.101.3 nexthop via 172.16.113.3" 1214 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" 1215 log_test $? 0 "Multipath - invalid second nexthop" 1216 1217 # multipath non-existent route 1218 add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2" 1219 run_cmd "$IP ro change 172.16.105.0/24 nexthop via 172.16.101.3 nexthop via 172.16.103.3" 1220 log_test $? 2 "Multipath - replace of non-existent route" 1221} 1222 1223ipv4_rt_replace() 1224{ 1225 echo 1226 echo "IPv4 route replace tests" 1227 1228 ipv4_rt_replace_single 1229 ipv4_rt_replace_mpath 1230} 1231 1232ipv4_route_test() 1233{ 1234 route_setup 1235 1236 ipv4_rt_add 1237 ipv4_rt_replace 1238 1239 route_cleanup 1240} 1241 1242ipv4_addr_metric_test() 1243{ 1244 local rc 1245 1246 echo 1247 echo "IPv4 prefix route tests" 1248 1249 ip_addr_metric_check || return 1 1250 1251 setup 1252 1253 set -e 1254 $IP li add dummy1 type dummy 1255 $IP li add dummy2 type dummy 1256 $IP li set dummy1 up 1257 $IP li set dummy2 up 1258 1259 # default entry is metric 256 1260 run_cmd "$IP addr add dev dummy1 172.16.104.1/24" 1261 run_cmd "$IP addr add dev dummy2 172.16.104.2/24" 1262 set +e 1263 1264 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" 1265 log_test $? 0 "Default metric" 1266 1267 set -e 1268 run_cmd "$IP addr flush dev dummy1" 1269 run_cmd "$IP addr add dev dummy1 172.16.104.1/24 metric 257" 1270 set +e 1271 1272 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" 1273 log_test $? 0 "User specified metric on first device" 1274 1275 set -e 1276 run_cmd "$IP addr flush dev dummy2" 1277 run_cmd "$IP addr add dev dummy2 172.16.104.2/24 metric 258" 1278 set +e 1279 1280 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" 1281 log_test $? 0 "User specified metric on second device" 1282 1283 run_cmd "$IP addr del dev dummy1 172.16.104.1/24 metric 257" 1284 rc=$? 1285 if [ $rc -eq 0 ]; then 1286 check_route "172.16.104.0/24 dev dummy2 proto kernel scope link src 172.16.104.2 metric 258" 1287 rc=$? 1288 fi 1289 log_test $rc 0 "Delete of address on first device" 1290 1291 run_cmd "$IP addr change dev dummy2 172.16.104.2/24 metric 259" 1292 rc=$? 1293 if [ $rc -eq 0 ]; then 1294 check_route "172.16.104.0/24 dev dummy2 proto kernel scope link src 172.16.104.2 metric 259" 1295 rc=$? 1296 fi 1297 log_test $rc 0 "Modify metric of address" 1298 1299 # verify prefix route removed on down 1300 run_cmd "$IP li set dev dummy2 down" 1301 rc=$? 1302 if [ $rc -eq 0 ]; then 1303 check_route "" 1304 rc=$? 1305 fi 1306 log_test $rc 0 "Prefix route removed on link down" 1307 1308 # verify prefix route re-inserted with assigned metric 1309 run_cmd "$IP li set dev dummy2 up" 1310 rc=$? 1311 if [ $rc -eq 0 ]; then 1312 check_route "172.16.104.0/24 dev dummy2 proto kernel scope link src 172.16.104.2 metric 259" 1313 rc=$? 1314 fi 1315 log_test $rc 0 "Prefix route with metric on link up" 1316 1317 $IP li del dummy1 1318 $IP li del dummy2 1319 cleanup 1320} 1321 1322################################################################################ 1323# usage 1324 1325usage() 1326{ 1327 cat <<EOF 1328usage: ${0##*/} OPTS 1329 1330 -t <test> Test(s) to run (default: all) 1331 (options: $TESTS) 1332 -p Pause on fail 1333 -P Pause after each test before cleanup 1334 -v verbose mode (show commands and output) 1335EOF 1336} 1337 1338################################################################################ 1339# main 1340 1341while getopts :t:pPhv o 1342do 1343 case $o in 1344 t) TESTS=$OPTARG;; 1345 p) PAUSE_ON_FAIL=yes;; 1346 P) PAUSE=yes;; 1347 v) VERBOSE=$(($VERBOSE + 1));; 1348 h) usage; exit 0;; 1349 *) usage; exit 1;; 1350 esac 1351done 1352 1353PEER_CMD="ip netns exec ${PEER_NS}" 1354 1355# make sure we don't pause twice 1356[ "${PAUSE}" = "yes" ] && PAUSE_ON_FAIL=no 1357 1358if [ "$(id -u)" -ne 0 ];then 1359 echo "SKIP: Need root privileges" 1360 exit $ksft_skip; 1361fi 1362 1363if [ ! -x "$(command -v ip)" ]; then 1364 echo "SKIP: Could not run test without ip tool" 1365 exit $ksft_skip 1366fi 1367 1368ip route help 2>&1 | grep -q fibmatch 1369if [ $? -ne 0 ]; then 1370 echo "SKIP: iproute2 too old, missing fibmatch" 1371 exit $ksft_skip 1372fi 1373 1374# start clean 1375cleanup &> /dev/null 1376 1377for t in $TESTS 1378do 1379 case $t in 1380 fib_unreg_test|unregister) fib_unreg_test;; 1381 fib_down_test|down) fib_down_test;; 1382 fib_carrier_test|carrier) fib_carrier_test;; 1383 fib_nexthop_test|nexthop) fib_nexthop_test;; 1384 ipv6_route_test|ipv6_rt) ipv6_route_test;; 1385 ipv4_route_test|ipv4_rt) ipv4_route_test;; 1386 ipv6_addr_metric) ipv6_addr_metric_test;; 1387 ipv4_addr_metric) ipv4_addr_metric_test;; 1388 1389 help) echo "Test names: $TESTS"; exit 0;; 1390 esac 1391done 1392 1393if [ "$TESTS" != "none" ]; then 1394 printf "\nTests passed: %3d\n" ${nsuccess} 1395 printf "Tests failed: %3d\n" ${nfail} 1396fi 1397 1398exit $ret 1399