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