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