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 sleep 1 389 set +e 390 391 echo " Carrier down" 392 $IP route get fibmatch 198.51.100.2 &> /dev/null 393 log_test $? 0 "IPv4 fibmatch" 394 $IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null 395 log_test $? 0 "IPv6 fibmatch" 396 397 $IP route get fibmatch 198.51.100.2 | \ 398 grep -q "linkdown" 399 log_test $? 0 "IPv4 linkdown flag set" 400 $IP -6 route get fibmatch 2001:db8:1::2 | \ 401 grep -q "linkdown" 402 log_test $? 0 "IPv6 linkdown flag set" 403 404 set -e 405 $IP address add 192.0.2.1/24 dev dummy0 406 $IP -6 address add 2001:db8:2::1/64 dev dummy0 407 set +e 408 409 echo " Second address added with carrier down" 410 $IP route get fibmatch 192.0.2.2 &> /dev/null 411 log_test $? 0 "IPv4 fibmatch" 412 $IP -6 route get fibmatch 2001:db8:2::2 &> /dev/null 413 log_test $? 0 "IPv6 fibmatch" 414 415 $IP route get fibmatch 192.0.2.2 | \ 416 grep -q "linkdown" 417 log_test $? 0 "IPv4 linkdown flag set" 418 $IP -6 route get fibmatch 2001:db8:2::2 | \ 419 grep -q "linkdown" 420 log_test $? 0 "IPv6 linkdown flag set" 421 422 cleanup 423} 424 425fib_carrier_test() 426{ 427 fib_carrier_local_test 428 fib_carrier_unicast_test 429} 430 431################################################################################ 432# Tests on nexthop spec 433 434# run 'ip route add' with given spec 435add_rt() 436{ 437 local desc="$1" 438 local erc=$2 439 local vrf=$3 440 local pfx=$4 441 local gw=$5 442 local dev=$6 443 local cmd out rc 444 445 [ "$vrf" = "-" ] && vrf="default" 446 [ -n "$gw" ] && gw="via $gw" 447 [ -n "$dev" ] && dev="dev $dev" 448 449 cmd="$IP route add vrf $vrf $pfx $gw $dev" 450 if [ "$VERBOSE" = "1" ]; then 451 printf "\n COMMAND: $cmd\n" 452 fi 453 454 out=$(eval $cmd 2>&1) 455 rc=$? 456 if [ "$VERBOSE" = "1" -a -n "$out" ]; then 457 echo " $out" 458 fi 459 log_test $rc $erc "$desc" 460} 461 462fib4_nexthop() 463{ 464 echo 465 echo "IPv4 nexthop tests" 466 467 echo "<<< write me >>>" 468} 469 470fib6_nexthop() 471{ 472 local lldummy=$(get_linklocal dummy0) 473 local llv1=$(get_linklocal dummy0) 474 475 if [ -z "$lldummy" ]; then 476 echo "Failed to get linklocal address for dummy0" 477 return 1 478 fi 479 if [ -z "$llv1" ]; then 480 echo "Failed to get linklocal address for veth1" 481 return 1 482 fi 483 484 echo 485 echo "IPv6 nexthop tests" 486 487 add_rt "Directly connected nexthop, unicast address" 0 \ 488 - 2001:db8:101::/64 2001:db8:1::2 489 add_rt "Directly connected nexthop, unicast address with device" 0 \ 490 - 2001:db8:102::/64 2001:db8:1::2 "dummy0" 491 add_rt "Gateway is linklocal address" 0 \ 492 - 2001:db8:103::1/64 $llv1 "veth0" 493 494 # fails because LL address requires a device 495 add_rt "Gateway is linklocal address, no device" 2 \ 496 - 2001:db8:104::1/64 $llv1 497 498 # local address can not be a gateway 499 add_rt "Gateway can not be local unicast address" 2 \ 500 - 2001:db8:105::/64 2001:db8:1::1 501 add_rt "Gateway can not be local unicast address, with device" 2 \ 502 - 2001:db8:106::/64 2001:db8:1::1 "dummy0" 503 add_rt "Gateway can not be a local linklocal address" 2 \ 504 - 2001:db8:107::1/64 $lldummy "dummy0" 505 506 # VRF tests 507 add_rt "Gateway can be local address in a VRF" 0 \ 508 - 2001:db8:108::/64 2001:db8:51::2 509 add_rt "Gateway can be local address in a VRF, with device" 0 \ 510 - 2001:db8:109::/64 2001:db8:51::2 "veth0" 511 add_rt "Gateway can be local linklocal address in a VRF" 0 \ 512 - 2001:db8:110::1/64 $llv1 "veth0" 513 514 add_rt "Redirect to VRF lookup" 0 \ 515 - 2001:db8:111::/64 "" "red" 516 517 add_rt "VRF route, gateway can be local address in default VRF" 0 \ 518 red 2001:db8:112::/64 2001:db8:51::1 519 520 # local address in same VRF fails 521 add_rt "VRF route, gateway can not be a local address" 2 \ 522 red 2001:db8:113::1/64 2001:db8:2::1 523 add_rt "VRF route, gateway can not be a local addr with device" 2 \ 524 red 2001:db8:114::1/64 2001:db8:2::1 "dummy1" 525} 526 527# Default VRF: 528# dummy0 - 198.51.100.1/24 2001:db8:1::1/64 529# veth0 - 192.0.2.1/24 2001:db8:51::1/64 530# 531# VRF red: 532# dummy1 - 192.168.2.1/24 2001:db8:2::1/64 533# veth1 - 192.0.2.2/24 2001:db8:51::2/64 534# 535# [ dummy0 veth0 ]--[ veth1 dummy1 ] 536 537fib_nexthop_test() 538{ 539 setup 540 541 set -e 542 543 $IP -4 rule add pref 32765 table local 544 $IP -4 rule del pref 0 545 $IP -6 rule add pref 32765 table local 546 $IP -6 rule del pref 0 547 548 $IP link add red type vrf table 1 549 $IP link set red up 550 $IP -4 route add vrf red unreachable default metric 4278198272 551 $IP -6 route add vrf red unreachable default metric 4278198272 552 553 $IP link add veth0 type veth peer name veth1 554 $IP link set dev veth0 up 555 $IP address add 192.0.2.1/24 dev veth0 556 $IP -6 address add 2001:db8:51::1/64 dev veth0 557 558 $IP link set dev veth1 vrf red up 559 $IP address add 192.0.2.2/24 dev veth1 560 $IP -6 address add 2001:db8:51::2/64 dev veth1 561 562 $IP link add dummy1 type dummy 563 $IP link set dev dummy1 vrf red up 564 $IP address add 192.168.2.1/24 dev dummy1 565 $IP -6 address add 2001:db8:2::1/64 dev dummy1 566 set +e 567 568 sleep 1 569 fib4_nexthop 570 fib6_nexthop 571 572 ( 573 $IP link del dev dummy1 574 $IP link del veth0 575 $IP link del red 576 ) 2>/dev/null 577 cleanup 578} 579 580################################################################################ 581# Tests on route add and replace 582 583run_cmd() 584{ 585 local cmd="$1" 586 local out 587 local stderr="2>/dev/null" 588 589 if [ "$VERBOSE" = "1" ]; then 590 printf " COMMAND: $cmd\n" 591 stderr= 592 fi 593 594 out=$(eval $cmd $stderr) 595 rc=$? 596 if [ "$VERBOSE" = "1" -a -n "$out" ]; then 597 echo " $out" 598 fi 599 600 [ "$VERBOSE" = "1" ] && echo 601 602 return $rc 603} 604 605check_expected() 606{ 607 local out="$1" 608 local expected="$2" 609 local rc=0 610 611 [ "${out}" = "${expected}" ] && return 0 612 613 if [ -z "${out}" ]; then 614 if [ "$VERBOSE" = "1" ]; then 615 printf "\nNo route entry found\n" 616 printf "Expected:\n" 617 printf " ${expected}\n" 618 fi 619 return 1 620 fi 621 622 # tricky way to convert output to 1-line without ip's 623 # messy '\'; this drops all extra white space 624 out=$(echo ${out}) 625 if [ "${out}" != "${expected}" ]; then 626 rc=1 627 if [ "${VERBOSE}" = "1" ]; then 628 printf " Unexpected route entry. Have:\n" 629 printf " ${out}\n" 630 printf " Expected:\n" 631 printf " ${expected}\n\n" 632 fi 633 fi 634 635 return $rc 636} 637 638# add route for a prefix, flushing any existing routes first 639# expected to be the first step of a test 640add_route6() 641{ 642 local pfx="$1" 643 local nh="$2" 644 local out 645 646 if [ "$VERBOSE" = "1" ]; then 647 echo 648 echo " ##################################################" 649 echo 650 fi 651 652 run_cmd "$IP -6 ro flush ${pfx}" 653 [ $? -ne 0 ] && exit 1 654 655 out=$($IP -6 ro ls match ${pfx}) 656 if [ -n "$out" ]; then 657 echo "Failed to flush routes for prefix used for tests." 658 exit 1 659 fi 660 661 run_cmd "$IP -6 ro add ${pfx} ${nh}" 662 if [ $? -ne 0 ]; then 663 echo "Failed to add initial route for test." 664 exit 1 665 fi 666} 667 668# add initial route - used in replace route tests 669add_initial_route6() 670{ 671 add_route6 "2001:db8:104::/64" "$1" 672} 673 674check_route6() 675{ 676 local pfx="2001:db8:104::/64" 677 local expected="$1" 678 local out 679 local rc=0 680 681 out=$($IP -6 ro ls match ${pfx} | sed -e 's/ pref medium//') 682 check_expected "${out}" "${expected}" 683} 684 685route_cleanup() 686{ 687 $IP li del red 2>/dev/null 688 $IP li del dummy1 2>/dev/null 689 $IP li del veth1 2>/dev/null 690 $IP li del veth3 2>/dev/null 691 692 cleanup &> /dev/null 693} 694 695route_setup() 696{ 697 route_cleanup 698 setup 699 700 [ "${VERBOSE}" = "1" ] && set -x 701 set -e 702 703 $IP li add red up type vrf table 101 704 $IP li add veth1 type veth peer name veth2 705 $IP li add veth3 type veth peer name veth4 706 707 $IP li set veth1 up 708 $IP li set veth3 up 709 $IP li set veth2 vrf red up 710 $IP li set veth4 vrf red up 711 $IP li add dummy1 type dummy 712 $IP li set dummy1 vrf red up 713 714 $IP -6 addr add 2001:db8:101::1/64 dev veth1 715 $IP -6 addr add 2001:db8:101::2/64 dev veth2 716 $IP -6 addr add 2001:db8:103::1/64 dev veth3 717 $IP -6 addr add 2001:db8:103::2/64 dev veth4 718 $IP -6 addr add 2001:db8:104::1/64 dev dummy1 719 720 $IP addr add 172.16.101.1/24 dev veth1 721 $IP addr add 172.16.101.2/24 dev veth2 722 $IP addr add 172.16.103.1/24 dev veth3 723 $IP addr add 172.16.103.2/24 dev veth4 724 $IP addr add 172.16.104.1/24 dev dummy1 725 726 set +e 727} 728 729# assumption is that basic add of a single path route works 730# otherwise just adding an address on an interface is broken 731ipv6_rt_add() 732{ 733 local rc 734 735 echo 736 echo "IPv6 route add / append tests" 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 2001:db8:104::/64 via 2001:db8:103::2" 741 log_test $? 2 "Attempt to add duplicate route - gw" 742 743 # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL 744 add_route6 "2001:db8:104::/64" "via 2001:db8:101::2" 745 run_cmd "$IP -6 ro add 2001:db8:104::/64 dev veth3" 746 log_test $? 2 "Attempt to add duplicate route - dev only" 747 748 # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL 749 add_route6 "2001:db8:104::/64" "via 2001:db8:101::2" 750 run_cmd "$IP -6 ro add unreachable 2001:db8:104::/64" 751 log_test $? 2 "Attempt to add duplicate route - reject route" 752 753 # route append with same prefix adds a new route 754 # - iproute2 sets NLM_F_CREATE | NLM_F_APPEND 755 add_route6 "2001:db8:104::/64" "via 2001:db8:101::2" 756 run_cmd "$IP -6 ro append 2001:db8:104::/64 via 2001:db8:103::2" 757 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" 758 log_test $? 0 "Append nexthop to existing route - gw" 759 760 # insert mpath directly 761 add_route6 "2001:db8:104::/64" "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2" 762 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" 763 log_test $? 0 "Add multipath route" 764 765 add_route6 "2001:db8:104::/64" "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2" 766 run_cmd "$IP -6 ro add 2001:db8:104::/64 nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2" 767 log_test $? 2 "Attempt to add duplicate multipath route" 768 769 # insert of a second route without append but different metric 770 add_route6 "2001:db8:104::/64" "via 2001:db8:101::2" 771 run_cmd "$IP -6 ro add 2001:db8:104::/64 via 2001:db8:103::2 metric 512" 772 rc=$? 773 if [ $rc -eq 0 ]; then 774 run_cmd "$IP -6 ro add 2001:db8:104::/64 via 2001:db8:103::3 metric 256" 775 rc=$? 776 fi 777 log_test $rc 0 "Route add with different metrics" 778 779 run_cmd "$IP -6 ro del 2001:db8:104::/64 metric 512" 780 rc=$? 781 if [ $rc -eq 0 ]; then 782 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" 783 rc=$? 784 fi 785 log_test $rc 0 "Route delete with metric" 786} 787 788ipv6_rt_replace_single() 789{ 790 # single path with single path 791 # 792 add_initial_route6 "via 2001:db8:101::2" 793 run_cmd "$IP -6 ro replace 2001:db8:104::/64 via 2001:db8:103::2" 794 check_route6 "2001:db8:104::/64 via 2001:db8:103::2 dev veth3 metric 1024" 795 log_test $? 0 "Single path with single path" 796 797 # single path with multipath 798 # 799 add_initial_route6 "nexthop via 2001:db8:101::2" 800 run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:101::3 nexthop via 2001:db8:103::2" 801 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" 802 log_test $? 0 "Single path with multipath" 803 804 # single path with single path using MULTIPATH attribute 805 # 806 add_initial_route6 "via 2001:db8:101::2" 807 run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:103::2" 808 check_route6 "2001:db8:104::/64 via 2001:db8:103::2 dev veth3 metric 1024" 809 log_test $? 0 "Single path with single path via multipath attribute" 810 811 # route replace fails - invalid nexthop 812 add_initial_route6 "via 2001:db8:101::2" 813 run_cmd "$IP -6 ro replace 2001:db8:104::/64 via 2001:db8:104::2" 814 if [ $? -eq 0 ]; then 815 # previous command is expected to fail so if it returns 0 816 # that means the test failed. 817 log_test 0 1 "Invalid nexthop" 818 else 819 check_route6 "2001:db8:104::/64 via 2001:db8:101::2 dev veth1 metric 1024" 820 log_test $? 0 "Invalid nexthop" 821 fi 822 823 # replace non-existent route 824 # - note use of change versus replace since ip adds NLM_F_CREATE 825 # for replace 826 add_initial_route6 "via 2001:db8:101::2" 827 run_cmd "$IP -6 ro change 2001:db8:105::/64 via 2001:db8:101::2" 828 log_test $? 2 "Single path - replace of non-existent route" 829} 830 831ipv6_rt_replace_mpath() 832{ 833 # multipath with multipath 834 add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2" 835 run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:101::3 nexthop via 2001:db8:103::3" 836 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" 837 log_test $? 0 "Multipath with multipath" 838 839 # multipath with single 840 add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2" 841 run_cmd "$IP -6 ro replace 2001:db8:104::/64 via 2001:db8:101::3" 842 check_route6 "2001:db8:104::/64 via 2001:db8:101::3 dev veth1 metric 1024" 843 log_test $? 0 "Multipath with single path" 844 845 # multipath with single 846 add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2" 847 run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:101::3" 848 check_route6 "2001:db8:104::/64 via 2001:db8:101::3 dev veth1 metric 1024" 849 log_test $? 0 "Multipath with single path via multipath attribute" 850 851 # multipath with dev-only 852 add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2" 853 run_cmd "$IP -6 ro replace 2001:db8:104::/64 dev veth1" 854 check_route6 "2001:db8:104::/64 dev veth1 metric 1024" 855 log_test $? 0 "Multipath with dev-only" 856 857 # route replace fails - invalid nexthop 1 858 add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2" 859 run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:111::3 nexthop via 2001:db8:103::3" 860 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" 861 log_test $? 0 "Multipath - invalid first nexthop" 862 863 # route replace fails - invalid nexthop 2 864 add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2" 865 run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:101::3 nexthop via 2001:db8:113::3" 866 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" 867 log_test $? 0 "Multipath - invalid second nexthop" 868 869 # multipath non-existent route 870 add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2" 871 run_cmd "$IP -6 ro change 2001:db8:105::/64 nexthop via 2001:db8:101::3 nexthop via 2001:db8:103::3" 872 log_test $? 2 "Multipath - replace of non-existent route" 873} 874 875ipv6_rt_replace() 876{ 877 echo 878 echo "IPv6 route replace tests" 879 880 ipv6_rt_replace_single 881 ipv6_rt_replace_mpath 882} 883 884ipv6_route_test() 885{ 886 route_setup 887 888 ipv6_rt_add 889 ipv6_rt_replace 890 891 route_cleanup 892} 893 894ip_addr_metric_check() 895{ 896 ip addr help 2>&1 | grep -q metric 897 if [ $? -ne 0 ]; then 898 echo "iproute2 command does not support metric for addresses. Skipping test" 899 return 1 900 fi 901 902 return 0 903} 904 905ipv6_addr_metric_test() 906{ 907 local rc 908 909 echo 910 echo "IPv6 prefix route tests" 911 912 ip_addr_metric_check || return 1 913 914 setup 915 916 set -e 917 $IP li add dummy1 type dummy 918 $IP li add dummy2 type dummy 919 $IP li set dummy1 up 920 $IP li set dummy2 up 921 922 # default entry is metric 256 923 run_cmd "$IP -6 addr add dev dummy1 2001:db8:104::1/64" 924 run_cmd "$IP -6 addr add dev dummy2 2001:db8:104::2/64" 925 set +e 926 927 check_route6 "2001:db8:104::/64 dev dummy1 proto kernel metric 256 2001:db8:104::/64 dev dummy2 proto kernel metric 256" 928 log_test $? 0 "Default metric" 929 930 set -e 931 run_cmd "$IP -6 addr flush dev dummy1" 932 run_cmd "$IP -6 addr add dev dummy1 2001:db8:104::1/64 metric 257" 933 set +e 934 935 check_route6 "2001:db8:104::/64 dev dummy2 proto kernel metric 256 2001:db8:104::/64 dev dummy1 proto kernel metric 257" 936 log_test $? 0 "User specified metric on first device" 937 938 set -e 939 run_cmd "$IP -6 addr flush dev dummy2" 940 run_cmd "$IP -6 addr add dev dummy2 2001:db8:104::2/64 metric 258" 941 set +e 942 943 check_route6 "2001:db8:104::/64 dev dummy1 proto kernel metric 257 2001:db8:104::/64 dev dummy2 proto kernel metric 258" 944 log_test $? 0 "User specified metric on second device" 945 946 run_cmd "$IP -6 addr del dev dummy1 2001:db8:104::1/64 metric 257" 947 rc=$? 948 if [ $rc -eq 0 ]; then 949 check_route6 "2001:db8:104::/64 dev dummy2 proto kernel metric 258" 950 rc=$? 951 fi 952 log_test $rc 0 "Delete of address on first device" 953 954 run_cmd "$IP -6 addr change dev dummy2 2001:db8:104::2/64 metric 259" 955 rc=$? 956 if [ $rc -eq 0 ]; then 957 check_route6 "2001:db8:104::/64 dev dummy2 proto kernel metric 259" 958 rc=$? 959 fi 960 log_test $rc 0 "Modify metric of address" 961 962 # verify prefix route removed on down 963 run_cmd "ip netns exec testns sysctl -qw net.ipv6.conf.all.keep_addr_on_down=1" 964 run_cmd "$IP li set dev dummy2 down" 965 rc=$? 966 if [ $rc -eq 0 ]; then 967 out=$($IP -6 ro ls match 2001:db8:104::/64) 968 check_expected "${out}" "" 969 rc=$? 970 fi 971 log_test $rc 0 "Prefix route removed on link down" 972 973 # verify prefix route re-inserted with assigned metric 974 run_cmd "$IP li set dev dummy2 up" 975 rc=$? 976 if [ $rc -eq 0 ]; then 977 check_route6 "2001:db8:104::/64 dev dummy2 proto kernel metric 259" 978 rc=$? 979 fi 980 log_test $rc 0 "Prefix route with metric on link up" 981 982 # verify peer metric added correctly 983 set -e 984 run_cmd "$IP -6 addr flush dev dummy2" 985 run_cmd "$IP -6 addr add dev dummy2 2001:db8:104::1 peer 2001:db8:104::2 metric 260" 986 set +e 987 988 check_route6 "2001:db8:104::1 dev dummy2 proto kernel metric 260" 989 log_test $? 0 "Set metric with peer route on local side" 990 log_test $? 0 "User specified metric on local address" 991 check_route6 "2001:db8:104::2 dev dummy2 proto kernel metric 260" 992 log_test $? 0 "Set metric with peer route on peer side" 993 994 set -e 995 run_cmd "$IP -6 addr change dev dummy2 2001:db8:104::1 peer 2001:db8:104::3 metric 261" 996 set +e 997 998 check_route6 "2001:db8:104::1 dev dummy2 proto kernel metric 261" 999 log_test $? 0 "Modify metric and peer address on local side" 1000 check_route6 "2001:db8:104::3 dev dummy2 proto kernel metric 261" 1001 log_test $? 0 "Modify metric and peer address on peer side" 1002 1003 $IP li del dummy1 1004 $IP li del dummy2 1005 cleanup 1006} 1007 1008# add route for a prefix, flushing any existing routes first 1009# expected to be the first step of a test 1010add_route() 1011{ 1012 local pfx="$1" 1013 local nh="$2" 1014 local out 1015 1016 if [ "$VERBOSE" = "1" ]; then 1017 echo 1018 echo " ##################################################" 1019 echo 1020 fi 1021 1022 run_cmd "$IP ro flush ${pfx}" 1023 [ $? -ne 0 ] && exit 1 1024 1025 out=$($IP ro ls match ${pfx}) 1026 if [ -n "$out" ]; then 1027 echo "Failed to flush routes for prefix used for tests." 1028 exit 1 1029 fi 1030 1031 run_cmd "$IP ro add ${pfx} ${nh}" 1032 if [ $? -ne 0 ]; then 1033 echo "Failed to add initial route for test." 1034 exit 1 1035 fi 1036} 1037 1038# add initial route - used in replace route tests 1039add_initial_route() 1040{ 1041 add_route "172.16.104.0/24" "$1" 1042} 1043 1044check_route() 1045{ 1046 local pfx="172.16.104.0/24" 1047 local expected="$1" 1048 local out 1049 1050 out=$($IP ro ls match ${pfx}) 1051 check_expected "${out}" "${expected}" 1052} 1053 1054# assumption is that basic add of a single path route works 1055# otherwise just adding an address on an interface is broken 1056ipv4_rt_add() 1057{ 1058 local rc 1059 1060 echo 1061 echo "IPv4 route add / append tests" 1062 1063 # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL 1064 add_route "172.16.104.0/24" "via 172.16.101.2" 1065 run_cmd "$IP ro add 172.16.104.0/24 via 172.16.103.2" 1066 log_test $? 2 "Attempt to add duplicate route - gw" 1067 1068 # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL 1069 add_route "172.16.104.0/24" "via 172.16.101.2" 1070 run_cmd "$IP ro add 172.16.104.0/24 dev veth3" 1071 log_test $? 2 "Attempt to add duplicate route - dev only" 1072 1073 # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL 1074 add_route "172.16.104.0/24" "via 172.16.101.2" 1075 run_cmd "$IP ro add unreachable 172.16.104.0/24" 1076 log_test $? 2 "Attempt to add duplicate route - reject route" 1077 1078 # iproute2 prepend only sets NLM_F_CREATE 1079 # - adds a new route; does NOT convert existing route to ECMP 1080 add_route "172.16.104.0/24" "via 172.16.101.2" 1081 run_cmd "$IP ro prepend 172.16.104.0/24 via 172.16.103.2" 1082 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" 1083 log_test $? 0 "Add new nexthop for existing prefix" 1084 1085 # route append with same prefix adds a new route 1086 # - iproute2 sets NLM_F_CREATE | NLM_F_APPEND 1087 add_route "172.16.104.0/24" "via 172.16.101.2" 1088 run_cmd "$IP ro append 172.16.104.0/24 via 172.16.103.2" 1089 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" 1090 log_test $? 0 "Append nexthop to existing route - gw" 1091 1092 add_route "172.16.104.0/24" "via 172.16.101.2" 1093 run_cmd "$IP ro append 172.16.104.0/24 dev veth3" 1094 check_route "172.16.104.0/24 via 172.16.101.2 dev veth1 172.16.104.0/24 dev veth3 scope link" 1095 log_test $? 0 "Append nexthop to existing route - dev only" 1096 1097 add_route "172.16.104.0/24" "via 172.16.101.2" 1098 run_cmd "$IP ro append unreachable 172.16.104.0/24" 1099 check_route "172.16.104.0/24 via 172.16.101.2 dev veth1 unreachable 172.16.104.0/24" 1100 log_test $? 0 "Append nexthop to existing route - reject route" 1101 1102 run_cmd "$IP ro flush 172.16.104.0/24" 1103 run_cmd "$IP ro add unreachable 172.16.104.0/24" 1104 run_cmd "$IP ro append 172.16.104.0/24 via 172.16.103.2" 1105 check_route "unreachable 172.16.104.0/24 172.16.104.0/24 via 172.16.103.2 dev veth3" 1106 log_test $? 0 "Append nexthop to existing reject route - gw" 1107 1108 run_cmd "$IP ro flush 172.16.104.0/24" 1109 run_cmd "$IP ro add unreachable 172.16.104.0/24" 1110 run_cmd "$IP ro append 172.16.104.0/24 dev veth3" 1111 check_route "unreachable 172.16.104.0/24 172.16.104.0/24 dev veth3 scope link" 1112 log_test $? 0 "Append nexthop to existing reject route - dev only" 1113 1114 # insert mpath directly 1115 add_route "172.16.104.0/24" "nexthop via 172.16.101.2 nexthop via 172.16.103.2" 1116 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" 1117 log_test $? 0 "add multipath route" 1118 1119 add_route "172.16.104.0/24" "nexthop via 172.16.101.2 nexthop via 172.16.103.2" 1120 run_cmd "$IP ro add 172.16.104.0/24 nexthop via 172.16.101.2 nexthop via 172.16.103.2" 1121 log_test $? 2 "Attempt to add duplicate multipath route" 1122 1123 # insert of a second route without append but different metric 1124 add_route "172.16.104.0/24" "via 172.16.101.2" 1125 run_cmd "$IP ro add 172.16.104.0/24 via 172.16.103.2 metric 512" 1126 rc=$? 1127 if [ $rc -eq 0 ]; then 1128 run_cmd "$IP ro add 172.16.104.0/24 via 172.16.103.3 metric 256" 1129 rc=$? 1130 fi 1131 log_test $rc 0 "Route add with different metrics" 1132 1133 run_cmd "$IP ro del 172.16.104.0/24 metric 512" 1134 rc=$? 1135 if [ $rc -eq 0 ]; then 1136 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" 1137 rc=$? 1138 fi 1139 log_test $rc 0 "Route delete with metric" 1140} 1141 1142ipv4_rt_replace_single() 1143{ 1144 # single path with single path 1145 # 1146 add_initial_route "via 172.16.101.2" 1147 run_cmd "$IP ro replace 172.16.104.0/24 via 172.16.103.2" 1148 check_route "172.16.104.0/24 via 172.16.103.2 dev veth3" 1149 log_test $? 0 "Single path with single path" 1150 1151 # single path with multipath 1152 # 1153 add_initial_route "nexthop via 172.16.101.2" 1154 run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.101.3 nexthop via 172.16.103.2" 1155 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" 1156 log_test $? 0 "Single path with multipath" 1157 1158 # single path with reject 1159 # 1160 add_initial_route "nexthop via 172.16.101.2" 1161 run_cmd "$IP ro replace unreachable 172.16.104.0/24" 1162 check_route "unreachable 172.16.104.0/24" 1163 log_test $? 0 "Single path with reject route" 1164 1165 # single path with single path using MULTIPATH attribute 1166 # 1167 add_initial_route "via 172.16.101.2" 1168 run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.103.2" 1169 check_route "172.16.104.0/24 via 172.16.103.2 dev veth3" 1170 log_test $? 0 "Single path with single path via multipath attribute" 1171 1172 # route replace fails - invalid nexthop 1173 add_initial_route "via 172.16.101.2" 1174 run_cmd "$IP ro replace 172.16.104.0/24 via 2001:db8:104::2" 1175 if [ $? -eq 0 ]; then 1176 # previous command is expected to fail so if it returns 0 1177 # that means the test failed. 1178 log_test 0 1 "Invalid nexthop" 1179 else 1180 check_route "172.16.104.0/24 via 172.16.101.2 dev veth1" 1181 log_test $? 0 "Invalid nexthop" 1182 fi 1183 1184 # replace non-existent route 1185 # - note use of change versus replace since ip adds NLM_F_CREATE 1186 # for replace 1187 add_initial_route "via 172.16.101.2" 1188 run_cmd "$IP ro change 172.16.105.0/24 via 172.16.101.2" 1189 log_test $? 2 "Single path - replace of non-existent route" 1190} 1191 1192ipv4_rt_replace_mpath() 1193{ 1194 # multipath with multipath 1195 add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2" 1196 run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.101.3 nexthop via 172.16.103.3" 1197 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" 1198 log_test $? 0 "Multipath with multipath" 1199 1200 # multipath with single 1201 add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2" 1202 run_cmd "$IP ro replace 172.16.104.0/24 via 172.16.101.3" 1203 check_route "172.16.104.0/24 via 172.16.101.3 dev veth1" 1204 log_test $? 0 "Multipath with single path" 1205 1206 # multipath with single 1207 add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2" 1208 run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.101.3" 1209 check_route "172.16.104.0/24 via 172.16.101.3 dev veth1" 1210 log_test $? 0 "Multipath with single path via multipath attribute" 1211 1212 # multipath with reject 1213 add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2" 1214 run_cmd "$IP ro replace unreachable 172.16.104.0/24" 1215 check_route "unreachable 172.16.104.0/24" 1216 log_test $? 0 "Multipath with reject route" 1217 1218 # route replace fails - invalid nexthop 1 1219 add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2" 1220 run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.111.3 nexthop via 172.16.103.3" 1221 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" 1222 log_test $? 0 "Multipath - invalid first nexthop" 1223 1224 # route replace fails - invalid nexthop 2 1225 add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2" 1226 run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.101.3 nexthop via 172.16.113.3" 1227 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" 1228 log_test $? 0 "Multipath - invalid second nexthop" 1229 1230 # multipath non-existent route 1231 add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2" 1232 run_cmd "$IP ro change 172.16.105.0/24 nexthop via 172.16.101.3 nexthop via 172.16.103.3" 1233 log_test $? 2 "Multipath - replace of non-existent route" 1234} 1235 1236ipv4_rt_replace() 1237{ 1238 echo 1239 echo "IPv4 route replace tests" 1240 1241 ipv4_rt_replace_single 1242 ipv4_rt_replace_mpath 1243} 1244 1245ipv4_route_test() 1246{ 1247 route_setup 1248 1249 ipv4_rt_add 1250 ipv4_rt_replace 1251 1252 route_cleanup 1253} 1254 1255ipv4_addr_metric_test() 1256{ 1257 local rc 1258 1259 echo 1260 echo "IPv4 prefix route tests" 1261 1262 ip_addr_metric_check || return 1 1263 1264 setup 1265 1266 set -e 1267 $IP li add dummy1 type dummy 1268 $IP li add dummy2 type dummy 1269 $IP li set dummy1 up 1270 $IP li set dummy2 up 1271 1272 # default entry is metric 256 1273 run_cmd "$IP addr add dev dummy1 172.16.104.1/24" 1274 run_cmd "$IP addr add dev dummy2 172.16.104.2/24" 1275 set +e 1276 1277 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" 1278 log_test $? 0 "Default metric" 1279 1280 set -e 1281 run_cmd "$IP addr flush dev dummy1" 1282 run_cmd "$IP addr add dev dummy1 172.16.104.1/24 metric 257" 1283 set +e 1284 1285 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" 1286 log_test $? 0 "User specified metric on first device" 1287 1288 set -e 1289 run_cmd "$IP addr flush dev dummy2" 1290 run_cmd "$IP addr add dev dummy2 172.16.104.2/24 metric 258" 1291 set +e 1292 1293 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" 1294 log_test $? 0 "User specified metric on second device" 1295 1296 run_cmd "$IP addr del dev dummy1 172.16.104.1/24 metric 257" 1297 rc=$? 1298 if [ $rc -eq 0 ]; then 1299 check_route "172.16.104.0/24 dev dummy2 proto kernel scope link src 172.16.104.2 metric 258" 1300 rc=$? 1301 fi 1302 log_test $rc 0 "Delete of address on first device" 1303 1304 run_cmd "$IP addr change dev dummy2 172.16.104.2/24 metric 259" 1305 rc=$? 1306 if [ $rc -eq 0 ]; then 1307 check_route "172.16.104.0/24 dev dummy2 proto kernel scope link src 172.16.104.2 metric 259" 1308 rc=$? 1309 fi 1310 log_test $rc 0 "Modify metric of address" 1311 1312 # verify prefix route removed on down 1313 run_cmd "$IP li set dev dummy2 down" 1314 rc=$? 1315 if [ $rc -eq 0 ]; then 1316 out=$($IP ro ls match 172.16.104.0/24) 1317 check_expected "${out}" "" 1318 rc=$? 1319 fi 1320 log_test $rc 0 "Prefix route removed on link down" 1321 1322 # verify prefix route re-inserted with assigned metric 1323 run_cmd "$IP li set dev dummy2 up" 1324 rc=$? 1325 if [ $rc -eq 0 ]; then 1326 check_route "172.16.104.0/24 dev dummy2 proto kernel scope link src 172.16.104.2 metric 259" 1327 rc=$? 1328 fi 1329 log_test $rc 0 "Prefix route with metric on link up" 1330 1331 # explicitly check for metric changes on edge scenarios 1332 run_cmd "$IP addr flush dev dummy2" 1333 run_cmd "$IP addr add dev dummy2 172.16.104.0/24 metric 259" 1334 run_cmd "$IP addr change dev dummy2 172.16.104.0/24 metric 260" 1335 rc=$? 1336 if [ $rc -eq 0 ]; then 1337 check_route "172.16.104.0/24 dev dummy2 proto kernel scope link src 172.16.104.0 metric 260" 1338 rc=$? 1339 fi 1340 log_test $rc 0 "Modify metric of .0/24 address" 1341 1342 run_cmd "$IP addr flush dev dummy2" 1343 run_cmd "$IP addr add dev dummy2 172.16.104.1/32 peer 172.16.104.2 metric 260" 1344 rc=$? 1345 if [ $rc -eq 0 ]; then 1346 check_route "172.16.104.2 dev dummy2 proto kernel scope link src 172.16.104.1 metric 260" 1347 rc=$? 1348 fi 1349 log_test $rc 0 "Set metric of address with peer route" 1350 1351 run_cmd "$IP addr change dev dummy2 172.16.104.1/32 peer 172.16.104.3 metric 261" 1352 rc=$? 1353 if [ $rc -eq 0 ]; then 1354 check_route "172.16.104.3 dev dummy2 proto kernel scope link src 172.16.104.1 metric 261" 1355 rc=$? 1356 fi 1357 log_test $rc 0 "Modify metric and peer address for peer route" 1358 1359 $IP li del dummy1 1360 $IP li del dummy2 1361 cleanup 1362} 1363 1364################################################################################ 1365# usage 1366 1367usage() 1368{ 1369 cat <<EOF 1370usage: ${0##*/} OPTS 1371 1372 -t <test> Test(s) to run (default: all) 1373 (options: $TESTS) 1374 -p Pause on fail 1375 -P Pause after each test before cleanup 1376 -v verbose mode (show commands and output) 1377EOF 1378} 1379 1380################################################################################ 1381# main 1382 1383while getopts :t:pPhv o 1384do 1385 case $o in 1386 t) TESTS=$OPTARG;; 1387 p) PAUSE_ON_FAIL=yes;; 1388 P) PAUSE=yes;; 1389 v) VERBOSE=$(($VERBOSE + 1));; 1390 h) usage; exit 0;; 1391 *) usage; exit 1;; 1392 esac 1393done 1394 1395PEER_CMD="ip netns exec ${PEER_NS}" 1396 1397# make sure we don't pause twice 1398[ "${PAUSE}" = "yes" ] && PAUSE_ON_FAIL=no 1399 1400if [ "$(id -u)" -ne 0 ];then 1401 echo "SKIP: Need root privileges" 1402 exit $ksft_skip; 1403fi 1404 1405if [ ! -x "$(command -v ip)" ]; then 1406 echo "SKIP: Could not run test without ip tool" 1407 exit $ksft_skip 1408fi 1409 1410ip route help 2>&1 | grep -q fibmatch 1411if [ $? -ne 0 ]; then 1412 echo "SKIP: iproute2 too old, missing fibmatch" 1413 exit $ksft_skip 1414fi 1415 1416# start clean 1417cleanup &> /dev/null 1418 1419for t in $TESTS 1420do 1421 case $t in 1422 fib_unreg_test|unregister) fib_unreg_test;; 1423 fib_down_test|down) fib_down_test;; 1424 fib_carrier_test|carrier) fib_carrier_test;; 1425 fib_nexthop_test|nexthop) fib_nexthop_test;; 1426 ipv6_route_test|ipv6_rt) ipv6_route_test;; 1427 ipv4_route_test|ipv4_rt) ipv4_route_test;; 1428 ipv6_addr_metric) ipv6_addr_metric_test;; 1429 ipv4_addr_metric) ipv4_addr_metric_test;; 1430 1431 help) echo "Test names: $TESTS"; exit 0;; 1432 esac 1433done 1434 1435if [ "$TESTS" != "none" ]; then 1436 printf "\nTests passed: %3d\n" ${nsuccess} 1437 printf "Tests failed: %3d\n" ${nfail} 1438fi 1439 1440exit $ret 1441