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 suppress ipv6_rt ipv4_rt ipv6_addr_metric ipv4_addr_metric ipv6_route_metrics ipv4_route_metrics ipv4_route_v6_gw rp_filter ipv4_del_addr ipv4_mangle ipv6_mangle ipv4_bcast_neigh" 13 14VERBOSE=0 15PAUSE_ON_FAIL=no 16PAUSE=no 17IP="ip -netns ns1" 18NS_EXEC="ip netns exec ns1" 19 20which ping6 > /dev/null 2>&1 && ping6=$(which ping6) || ping6=$(which ping) 21 22log_test() 23{ 24 local rc=$1 25 local expected=$2 26 local msg="$3" 27 28 if [ ${rc} -eq ${expected} ]; then 29 printf " TEST: %-60s [ OK ]\n" "${msg}" 30 nsuccess=$((nsuccess+1)) 31 else 32 ret=1 33 nfail=$((nfail+1)) 34 printf " TEST: %-60s [FAIL]\n" "${msg}" 35 if [ "${PAUSE_ON_FAIL}" = "yes" ]; then 36 echo 37 echo "hit enter to continue, 'q' to quit" 38 read a 39 [ "$a" = "q" ] && exit 1 40 fi 41 fi 42 43 if [ "${PAUSE}" = "yes" ]; then 44 echo 45 echo "hit enter to continue, 'q' to quit" 46 read a 47 [ "$a" = "q" ] && exit 1 48 fi 49} 50 51setup() 52{ 53 set -e 54 ip netns add ns1 55 ip netns set ns1 auto 56 $IP link set dev lo up 57 ip netns exec ns1 sysctl -qw net.ipv4.ip_forward=1 58 ip netns exec ns1 sysctl -qw net.ipv6.conf.all.forwarding=1 59 60 $IP link add dummy0 type dummy 61 $IP link set dev dummy0 up 62 $IP address add 198.51.100.1/24 dev dummy0 63 $IP -6 address add 2001:db8:1::1/64 dev dummy0 64 set +e 65 66} 67 68cleanup() 69{ 70 $IP link del dev dummy0 &> /dev/null 71 ip netns del ns1 72 ip netns del ns2 &> /dev/null 73} 74 75get_linklocal() 76{ 77 local dev=$1 78 local addr 79 80 addr=$($IP -6 -br addr show dev ${dev} | \ 81 awk '{ 82 for (i = 3; i <= NF; ++i) { 83 if ($i ~ /^fe80/) 84 print $i 85 } 86 }' 87 ) 88 addr=${addr/\/*} 89 90 [ -z "$addr" ] && return 1 91 92 echo $addr 93 94 return 0 95} 96 97fib_unreg_unicast_test() 98{ 99 echo 100 echo "Single path route test" 101 102 setup 103 104 echo " Start point" 105 $IP route get fibmatch 198.51.100.2 &> /dev/null 106 log_test $? 0 "IPv4 fibmatch" 107 $IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null 108 log_test $? 0 "IPv6 fibmatch" 109 110 set -e 111 $IP link del dev dummy0 112 set +e 113 114 echo " Nexthop device deleted" 115 $IP route get fibmatch 198.51.100.2 &> /dev/null 116 log_test $? 2 "IPv4 fibmatch - no route" 117 $IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null 118 log_test $? 2 "IPv6 fibmatch - no route" 119 120 cleanup 121} 122 123fib_unreg_multipath_test() 124{ 125 126 echo 127 echo "Multipath route test" 128 129 setup 130 131 set -e 132 $IP link add dummy1 type dummy 133 $IP link set dev dummy1 up 134 $IP address add 192.0.2.1/24 dev dummy1 135 $IP -6 address add 2001:db8:2::1/64 dev dummy1 136 137 $IP route add 203.0.113.0/24 \ 138 nexthop via 198.51.100.2 dev dummy0 \ 139 nexthop via 192.0.2.2 dev dummy1 140 $IP -6 route add 2001:db8:3::/64 \ 141 nexthop via 2001:db8:1::2 dev dummy0 \ 142 nexthop via 2001:db8:2::2 dev dummy1 143 set +e 144 145 echo " Start point" 146 $IP route get fibmatch 203.0.113.1 &> /dev/null 147 log_test $? 0 "IPv4 fibmatch" 148 $IP -6 route get fibmatch 2001:db8:3::1 &> /dev/null 149 log_test $? 0 "IPv6 fibmatch" 150 151 set -e 152 $IP link del dev dummy0 153 set +e 154 155 echo " One nexthop device deleted" 156 $IP route get fibmatch 203.0.113.1 &> /dev/null 157 log_test $? 2 "IPv4 - multipath route removed on delete" 158 159 $IP -6 route get fibmatch 2001:db8:3::1 &> /dev/null 160 # In IPv6 we do not flush the entire multipath route. 161 log_test $? 0 "IPv6 - multipath down to single path" 162 163 set -e 164 $IP link del dev dummy1 165 set +e 166 167 echo " Second nexthop device deleted" 168 $IP -6 route get fibmatch 2001:db8:3::1 &> /dev/null 169 log_test $? 2 "IPv6 - no route" 170 171 cleanup 172} 173 174fib_unreg_test() 175{ 176 fib_unreg_unicast_test 177 fib_unreg_multipath_test 178} 179 180fib_down_unicast_test() 181{ 182 echo 183 echo "Single path, admin down" 184 185 setup 186 187 echo " Start point" 188 $IP route get fibmatch 198.51.100.2 &> /dev/null 189 log_test $? 0 "IPv4 fibmatch" 190 $IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null 191 log_test $? 0 "IPv6 fibmatch" 192 193 set -e 194 $IP link set dev dummy0 down 195 set +e 196 197 echo " Route deleted on down" 198 $IP route get fibmatch 198.51.100.2 &> /dev/null 199 log_test $? 2 "IPv4 fibmatch" 200 $IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null 201 log_test $? 2 "IPv6 fibmatch" 202 203 cleanup 204} 205 206fib_down_multipath_test_do() 207{ 208 local down_dev=$1 209 local up_dev=$2 210 211 $IP route get fibmatch 203.0.113.1 \ 212 oif $down_dev &> /dev/null 213 log_test $? 2 "IPv4 fibmatch on down device" 214 $IP -6 route get fibmatch 2001:db8:3::1 \ 215 oif $down_dev &> /dev/null 216 log_test $? 2 "IPv6 fibmatch on down device" 217 218 $IP route get fibmatch 203.0.113.1 \ 219 oif $up_dev &> /dev/null 220 log_test $? 0 "IPv4 fibmatch on up device" 221 $IP -6 route get fibmatch 2001:db8:3::1 \ 222 oif $up_dev &> /dev/null 223 log_test $? 0 "IPv6 fibmatch on up device" 224 225 $IP route get fibmatch 203.0.113.1 | \ 226 grep $down_dev | grep -q "dead linkdown" 227 log_test $? 0 "IPv4 flags on down device" 228 $IP -6 route get fibmatch 2001:db8:3::1 | \ 229 grep $down_dev | grep -q "dead linkdown" 230 log_test $? 0 "IPv6 flags on down device" 231 232 $IP route get fibmatch 203.0.113.1 | \ 233 grep $up_dev | grep -q "dead linkdown" 234 log_test $? 1 "IPv4 flags on up device" 235 $IP -6 route get fibmatch 2001:db8:3::1 | \ 236 grep $up_dev | grep -q "dead linkdown" 237 log_test $? 1 "IPv6 flags on up device" 238} 239 240fib_down_multipath_test() 241{ 242 echo 243 echo "Admin down multipath" 244 245 setup 246 247 set -e 248 $IP link add dummy1 type dummy 249 $IP link set dev dummy1 up 250 251 $IP address add 192.0.2.1/24 dev dummy1 252 $IP -6 address add 2001:db8:2::1/64 dev dummy1 253 254 $IP route add 203.0.113.0/24 \ 255 nexthop via 198.51.100.2 dev dummy0 \ 256 nexthop via 192.0.2.2 dev dummy1 257 $IP -6 route add 2001:db8:3::/64 \ 258 nexthop via 2001:db8:1::2 dev dummy0 \ 259 nexthop via 2001:db8:2::2 dev dummy1 260 set +e 261 262 echo " Verify start point" 263 $IP route get fibmatch 203.0.113.1 &> /dev/null 264 log_test $? 0 "IPv4 fibmatch" 265 266 $IP -6 route get fibmatch 2001:db8:3::1 &> /dev/null 267 log_test $? 0 "IPv6 fibmatch" 268 269 set -e 270 $IP link set dev dummy0 down 271 set +e 272 273 echo " One device down, one up" 274 fib_down_multipath_test_do "dummy0" "dummy1" 275 276 set -e 277 $IP link set dev dummy0 up 278 $IP link set dev dummy1 down 279 set +e 280 281 echo " Other device down and up" 282 fib_down_multipath_test_do "dummy1" "dummy0" 283 284 set -e 285 $IP link set dev dummy0 down 286 set +e 287 288 echo " Both devices down" 289 $IP route get fibmatch 203.0.113.1 &> /dev/null 290 log_test $? 2 "IPv4 fibmatch" 291 $IP -6 route get fibmatch 2001:db8:3::1 &> /dev/null 292 log_test $? 2 "IPv6 fibmatch" 293 294 $IP link del dev dummy1 295 cleanup 296} 297 298fib_down_test() 299{ 300 fib_down_unicast_test 301 fib_down_multipath_test 302} 303 304# Local routes should not be affected when carrier changes. 305fib_carrier_local_test() 306{ 307 echo 308 echo "Local carrier tests - single path" 309 310 setup 311 312 set -e 313 $IP link set dev dummy0 carrier on 314 set +e 315 316 echo " Start point" 317 $IP route get fibmatch 198.51.100.1 &> /dev/null 318 log_test $? 0 "IPv4 fibmatch" 319 $IP -6 route get fibmatch 2001:db8:1::1 &> /dev/null 320 log_test $? 0 "IPv6 fibmatch" 321 322 $IP route get fibmatch 198.51.100.1 | \ 323 grep -q "linkdown" 324 log_test $? 1 "IPv4 - no linkdown flag" 325 $IP -6 route get fibmatch 2001:db8:1::1 | \ 326 grep -q "linkdown" 327 log_test $? 1 "IPv6 - no linkdown flag" 328 329 set -e 330 $IP link set dev dummy0 carrier off 331 sleep 1 332 set +e 333 334 echo " Carrier off on nexthop" 335 $IP route get fibmatch 198.51.100.1 &> /dev/null 336 log_test $? 0 "IPv4 fibmatch" 337 $IP -6 route get fibmatch 2001:db8:1::1 &> /dev/null 338 log_test $? 0 "IPv6 fibmatch" 339 340 $IP route get fibmatch 198.51.100.1 | \ 341 grep -q "linkdown" 342 log_test $? 1 "IPv4 - linkdown flag set" 343 $IP -6 route get fibmatch 2001:db8:1::1 | \ 344 grep -q "linkdown" 345 log_test $? 1 "IPv6 - linkdown flag set" 346 347 set -e 348 $IP address add 192.0.2.1/24 dev dummy0 349 $IP -6 address add 2001:db8:2::1/64 dev dummy0 350 set +e 351 352 echo " Route to local address with carrier down" 353 $IP route get fibmatch 192.0.2.1 &> /dev/null 354 log_test $? 0 "IPv4 fibmatch" 355 $IP -6 route get fibmatch 2001:db8:2::1 &> /dev/null 356 log_test $? 0 "IPv6 fibmatch" 357 358 $IP route get fibmatch 192.0.2.1 | \ 359 grep -q "linkdown" 360 log_test $? 1 "IPv4 linkdown flag set" 361 $IP -6 route get fibmatch 2001:db8:2::1 | \ 362 grep -q "linkdown" 363 log_test $? 1 "IPv6 linkdown flag set" 364 365 cleanup 366} 367 368fib_carrier_unicast_test() 369{ 370 ret=0 371 372 echo 373 echo "Single path route carrier test" 374 375 setup 376 377 set -e 378 $IP link set dev dummy0 carrier on 379 set +e 380 381 echo " Start point" 382 $IP route get fibmatch 198.51.100.2 &> /dev/null 383 log_test $? 0 "IPv4 fibmatch" 384 $IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null 385 log_test $? 0 "IPv6 fibmatch" 386 387 $IP route get fibmatch 198.51.100.2 | \ 388 grep -q "linkdown" 389 log_test $? 1 "IPv4 no linkdown flag" 390 $IP -6 route get fibmatch 2001:db8:1::2 | \ 391 grep -q "linkdown" 392 log_test $? 1 "IPv6 no linkdown flag" 393 394 set -e 395 $IP link set dev dummy0 carrier off 396 sleep 1 397 set +e 398 399 echo " Carrier down" 400 $IP route get fibmatch 198.51.100.2 &> /dev/null 401 log_test $? 0 "IPv4 fibmatch" 402 $IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null 403 log_test $? 0 "IPv6 fibmatch" 404 405 $IP route get fibmatch 198.51.100.2 | \ 406 grep -q "linkdown" 407 log_test $? 0 "IPv4 linkdown flag set" 408 $IP -6 route get fibmatch 2001:db8:1::2 | \ 409 grep -q "linkdown" 410 log_test $? 0 "IPv6 linkdown flag set" 411 412 set -e 413 $IP address add 192.0.2.1/24 dev dummy0 414 $IP -6 address add 2001:db8:2::1/64 dev dummy0 415 set +e 416 417 echo " Second address added with carrier down" 418 $IP route get fibmatch 192.0.2.2 &> /dev/null 419 log_test $? 0 "IPv4 fibmatch" 420 $IP -6 route get fibmatch 2001:db8:2::2 &> /dev/null 421 log_test $? 0 "IPv6 fibmatch" 422 423 $IP route get fibmatch 192.0.2.2 | \ 424 grep -q "linkdown" 425 log_test $? 0 "IPv4 linkdown flag set" 426 $IP -6 route get fibmatch 2001:db8:2::2 | \ 427 grep -q "linkdown" 428 log_test $? 0 "IPv6 linkdown flag set" 429 430 cleanup 431} 432 433fib_carrier_test() 434{ 435 fib_carrier_local_test 436 fib_carrier_unicast_test 437} 438 439fib_rp_filter_test() 440{ 441 echo 442 echo "IPv4 rp_filter tests" 443 444 setup 445 446 set -e 447 ip netns add ns2 448 ip netns set ns2 auto 449 450 ip -netns ns2 link set dev lo up 451 452 $IP link add name veth1 type veth peer name veth2 453 $IP link set dev veth2 netns ns2 454 $IP address add 192.0.2.1/24 dev veth1 455 ip -netns ns2 address add 192.0.2.1/24 dev veth2 456 $IP link set dev veth1 up 457 ip -netns ns2 link set dev veth2 up 458 459 $IP link set dev lo address 52:54:00:6a:c7:5e 460 $IP link set dev veth1 address 52:54:00:6a:c7:5e 461 ip -netns ns2 link set dev lo address 52:54:00:6a:c7:5e 462 ip -netns ns2 link set dev veth2 address 52:54:00:6a:c7:5e 463 464 # 1. (ns2) redirect lo's egress to veth2's egress 465 ip netns exec ns2 tc qdisc add dev lo parent root handle 1: fq_codel 466 ip netns exec ns2 tc filter add dev lo parent 1: protocol arp basic \ 467 action mirred egress redirect dev veth2 468 ip netns exec ns2 tc filter add dev lo parent 1: protocol ip basic \ 469 action mirred egress redirect dev veth2 470 471 # 2. (ns1) redirect veth1's ingress to lo's ingress 472 $NS_EXEC tc qdisc add dev veth1 ingress 473 $NS_EXEC tc filter add dev veth1 ingress protocol arp basic \ 474 action mirred ingress redirect dev lo 475 $NS_EXEC tc filter add dev veth1 ingress protocol ip basic \ 476 action mirred ingress redirect dev lo 477 478 # 3. (ns1) redirect lo's egress to veth1's egress 479 $NS_EXEC tc qdisc add dev lo parent root handle 1: fq_codel 480 $NS_EXEC tc filter add dev lo parent 1: protocol arp basic \ 481 action mirred egress redirect dev veth1 482 $NS_EXEC tc filter add dev lo parent 1: protocol ip basic \ 483 action mirred egress redirect dev veth1 484 485 # 4. (ns2) redirect veth2's ingress to lo's ingress 486 ip netns exec ns2 tc qdisc add dev veth2 ingress 487 ip netns exec ns2 tc filter add dev veth2 ingress protocol arp basic \ 488 action mirred ingress redirect dev lo 489 ip netns exec ns2 tc filter add dev veth2 ingress protocol ip basic \ 490 action mirred ingress redirect dev lo 491 492 $NS_EXEC sysctl -qw net.ipv4.conf.all.rp_filter=1 493 $NS_EXEC sysctl -qw net.ipv4.conf.all.accept_local=1 494 $NS_EXEC sysctl -qw net.ipv4.conf.all.route_localnet=1 495 ip netns exec ns2 sysctl -qw net.ipv4.conf.all.rp_filter=1 496 ip netns exec ns2 sysctl -qw net.ipv4.conf.all.accept_local=1 497 ip netns exec ns2 sysctl -qw net.ipv4.conf.all.route_localnet=1 498 set +e 499 500 run_cmd "ip netns exec ns2 ping -w1 -c1 192.0.2.1" 501 log_test $? 0 "rp_filter passes local packets" 502 503 run_cmd "ip netns exec ns2 ping -w1 -c1 127.0.0.1" 504 log_test $? 0 "rp_filter passes loopback packets" 505 506 cleanup 507} 508 509################################################################################ 510# Tests on nexthop spec 511 512# run 'ip route add' with given spec 513add_rt() 514{ 515 local desc="$1" 516 local erc=$2 517 local vrf=$3 518 local pfx=$4 519 local gw=$5 520 local dev=$6 521 local cmd out rc 522 523 [ "$vrf" = "-" ] && vrf="default" 524 [ -n "$gw" ] && gw="via $gw" 525 [ -n "$dev" ] && dev="dev $dev" 526 527 cmd="$IP route add vrf $vrf $pfx $gw $dev" 528 if [ "$VERBOSE" = "1" ]; then 529 printf "\n COMMAND: $cmd\n" 530 fi 531 532 out=$(eval $cmd 2>&1) 533 rc=$? 534 if [ "$VERBOSE" = "1" -a -n "$out" ]; then 535 echo " $out" 536 fi 537 log_test $rc $erc "$desc" 538} 539 540fib4_nexthop() 541{ 542 echo 543 echo "IPv4 nexthop tests" 544 545 echo "<<< write me >>>" 546} 547 548fib6_nexthop() 549{ 550 local lldummy=$(get_linklocal dummy0) 551 local llv1=$(get_linklocal dummy0) 552 553 if [ -z "$lldummy" ]; then 554 echo "Failed to get linklocal address for dummy0" 555 return 1 556 fi 557 if [ -z "$llv1" ]; then 558 echo "Failed to get linklocal address for veth1" 559 return 1 560 fi 561 562 echo 563 echo "IPv6 nexthop tests" 564 565 add_rt "Directly connected nexthop, unicast address" 0 \ 566 - 2001:db8:101::/64 2001:db8:1::2 567 add_rt "Directly connected nexthop, unicast address with device" 0 \ 568 - 2001:db8:102::/64 2001:db8:1::2 "dummy0" 569 add_rt "Gateway is linklocal address" 0 \ 570 - 2001:db8:103::1/64 $llv1 "veth0" 571 572 # fails because LL address requires a device 573 add_rt "Gateway is linklocal address, no device" 2 \ 574 - 2001:db8:104::1/64 $llv1 575 576 # local address can not be a gateway 577 add_rt "Gateway can not be local unicast address" 2 \ 578 - 2001:db8:105::/64 2001:db8:1::1 579 add_rt "Gateway can not be local unicast address, with device" 2 \ 580 - 2001:db8:106::/64 2001:db8:1::1 "dummy0" 581 add_rt "Gateway can not be a local linklocal address" 2 \ 582 - 2001:db8:107::1/64 $lldummy "dummy0" 583 584 # VRF tests 585 add_rt "Gateway can be local address in a VRF" 0 \ 586 - 2001:db8:108::/64 2001:db8:51::2 587 add_rt "Gateway can be local address in a VRF, with device" 0 \ 588 - 2001:db8:109::/64 2001:db8:51::2 "veth0" 589 add_rt "Gateway can be local linklocal address in a VRF" 0 \ 590 - 2001:db8:110::1/64 $llv1 "veth0" 591 592 add_rt "Redirect to VRF lookup" 0 \ 593 - 2001:db8:111::/64 "" "red" 594 595 add_rt "VRF route, gateway can be local address in default VRF" 0 \ 596 red 2001:db8:112::/64 2001:db8:51::1 597 598 # local address in same VRF fails 599 add_rt "VRF route, gateway can not be a local address" 2 \ 600 red 2001:db8:113::1/64 2001:db8:2::1 601 add_rt "VRF route, gateway can not be a local addr with device" 2 \ 602 red 2001:db8:114::1/64 2001:db8:2::1 "dummy1" 603} 604 605# Default VRF: 606# dummy0 - 198.51.100.1/24 2001:db8:1::1/64 607# veth0 - 192.0.2.1/24 2001:db8:51::1/64 608# 609# VRF red: 610# dummy1 - 192.168.2.1/24 2001:db8:2::1/64 611# veth1 - 192.0.2.2/24 2001:db8:51::2/64 612# 613# [ dummy0 veth0 ]--[ veth1 dummy1 ] 614 615fib_nexthop_test() 616{ 617 setup 618 619 set -e 620 621 $IP -4 rule add pref 32765 table local 622 $IP -4 rule del pref 0 623 $IP -6 rule add pref 32765 table local 624 $IP -6 rule del pref 0 625 626 $IP link add red type vrf table 1 627 $IP link set red up 628 $IP -4 route add vrf red unreachable default metric 4278198272 629 $IP -6 route add vrf red unreachable default metric 4278198272 630 631 $IP link add veth0 type veth peer name veth1 632 $IP link set dev veth0 up 633 $IP address add 192.0.2.1/24 dev veth0 634 $IP -6 address add 2001:db8:51::1/64 dev veth0 635 636 $IP link set dev veth1 vrf red up 637 $IP address add 192.0.2.2/24 dev veth1 638 $IP -6 address add 2001:db8:51::2/64 dev veth1 639 640 $IP link add dummy1 type dummy 641 $IP link set dev dummy1 vrf red up 642 $IP address add 192.168.2.1/24 dev dummy1 643 $IP -6 address add 2001:db8:2::1/64 dev dummy1 644 set +e 645 646 sleep 1 647 fib4_nexthop 648 fib6_nexthop 649 650 ( 651 $IP link del dev dummy1 652 $IP link del veth0 653 $IP link del red 654 ) 2>/dev/null 655 cleanup 656} 657 658fib_suppress_test() 659{ 660 echo 661 echo "FIB rule with suppress_prefixlength" 662 setup 663 664 $IP link add dummy1 type dummy 665 $IP link set dummy1 up 666 $IP -6 route add default dev dummy1 667 $IP -6 rule add table main suppress_prefixlength 0 668 ping -f -c 1000 -W 1 1234::1 >/dev/null 2>&1 669 $IP -6 rule del table main suppress_prefixlength 0 670 $IP link del dummy1 671 672 # If we got here without crashing, we're good. 673 log_test 0 0 "FIB rule suppress test" 674 675 cleanup 676} 677 678################################################################################ 679# Tests on route add and replace 680 681run_cmd() 682{ 683 local cmd="$1" 684 local out 685 local stderr="2>/dev/null" 686 687 if [ "$VERBOSE" = "1" ]; then 688 printf " COMMAND: $cmd\n" 689 stderr= 690 fi 691 692 out=$(eval $cmd $stderr) 693 rc=$? 694 if [ "$VERBOSE" = "1" -a -n "$out" ]; then 695 echo " $out" 696 fi 697 698 [ "$VERBOSE" = "1" ] && echo 699 700 return $rc 701} 702 703check_expected() 704{ 705 local out="$1" 706 local expected="$2" 707 local rc=0 708 709 [ "${out}" = "${expected}" ] && return 0 710 711 if [ -z "${out}" ]; then 712 if [ "$VERBOSE" = "1" ]; then 713 printf "\nNo route entry found\n" 714 printf "Expected:\n" 715 printf " ${expected}\n" 716 fi 717 return 1 718 fi 719 720 # tricky way to convert output to 1-line without ip's 721 # messy '\'; this drops all extra white space 722 out=$(echo ${out}) 723 if [ "${out}" != "${expected}" ]; then 724 rc=1 725 if [ "${VERBOSE}" = "1" ]; then 726 printf " Unexpected route entry. Have:\n" 727 printf " ${out}\n" 728 printf " Expected:\n" 729 printf " ${expected}\n\n" 730 fi 731 fi 732 733 return $rc 734} 735 736# add route for a prefix, flushing any existing routes first 737# expected to be the first step of a test 738add_route6() 739{ 740 local pfx="$1" 741 local nh="$2" 742 local out 743 744 if [ "$VERBOSE" = "1" ]; then 745 echo 746 echo " ##################################################" 747 echo 748 fi 749 750 run_cmd "$IP -6 ro flush ${pfx}" 751 [ $? -ne 0 ] && exit 1 752 753 out=$($IP -6 ro ls match ${pfx}) 754 if [ -n "$out" ]; then 755 echo "Failed to flush routes for prefix used for tests." 756 exit 1 757 fi 758 759 run_cmd "$IP -6 ro add ${pfx} ${nh}" 760 if [ $? -ne 0 ]; then 761 echo "Failed to add initial route for test." 762 exit 1 763 fi 764} 765 766# add initial route - used in replace route tests 767add_initial_route6() 768{ 769 add_route6 "2001:db8:104::/64" "$1" 770} 771 772check_route6() 773{ 774 local pfx 775 local expected="$1" 776 local out 777 local rc=0 778 779 set -- $expected 780 pfx=$1 781 782 out=$($IP -6 ro ls match ${pfx} | sed -e 's/ pref medium//') 783 check_expected "${out}" "${expected}" 784} 785 786route_cleanup() 787{ 788 $IP li del red 2>/dev/null 789 $IP li del dummy1 2>/dev/null 790 $IP li del veth1 2>/dev/null 791 $IP li del veth3 2>/dev/null 792 793 cleanup &> /dev/null 794} 795 796route_setup() 797{ 798 route_cleanup 799 setup 800 801 [ "${VERBOSE}" = "1" ] && set -x 802 set -e 803 804 ip netns add ns2 805 ip netns set ns2 auto 806 ip -netns ns2 link set dev lo up 807 ip netns exec ns2 sysctl -qw net.ipv4.ip_forward=1 808 ip netns exec ns2 sysctl -qw net.ipv6.conf.all.forwarding=1 809 810 $IP li add veth1 type veth peer name veth2 811 $IP li add veth3 type veth peer name veth4 812 813 $IP li set veth1 up 814 $IP li set veth3 up 815 $IP li set veth2 netns ns2 up 816 $IP li set veth4 netns ns2 up 817 ip -netns ns2 li add dummy1 type dummy 818 ip -netns ns2 li set dummy1 up 819 820 $IP -6 addr add 2001:db8:101::1/64 dev veth1 nodad 821 $IP -6 addr add 2001:db8:103::1/64 dev veth3 nodad 822 $IP addr add 172.16.101.1/24 dev veth1 823 $IP addr add 172.16.103.1/24 dev veth3 824 825 ip -netns ns2 -6 addr add 2001:db8:101::2/64 dev veth2 nodad 826 ip -netns ns2 -6 addr add 2001:db8:103::2/64 dev veth4 nodad 827 ip -netns ns2 -6 addr add 2001:db8:104::1/64 dev dummy1 nodad 828 829 ip -netns ns2 addr add 172.16.101.2/24 dev veth2 830 ip -netns ns2 addr add 172.16.103.2/24 dev veth4 831 ip -netns ns2 addr add 172.16.104.1/24 dev dummy1 832 833 set +e 834} 835 836# assumption is that basic add of a single path route works 837# otherwise just adding an address on an interface is broken 838ipv6_rt_add() 839{ 840 local rc 841 842 echo 843 echo "IPv6 route add / append tests" 844 845 # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL 846 add_route6 "2001:db8:104::/64" "via 2001:db8:101::2" 847 run_cmd "$IP -6 ro add 2001:db8:104::/64 via 2001:db8:103::2" 848 log_test $? 2 "Attempt to add duplicate route - gw" 849 850 # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL 851 add_route6 "2001:db8:104::/64" "via 2001:db8:101::2" 852 run_cmd "$IP -6 ro add 2001:db8:104::/64 dev veth3" 853 log_test $? 2 "Attempt to add duplicate route - dev only" 854 855 # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL 856 add_route6 "2001:db8:104::/64" "via 2001:db8:101::2" 857 run_cmd "$IP -6 ro add unreachable 2001:db8:104::/64" 858 log_test $? 2 "Attempt to add duplicate route - reject route" 859 860 # route append with same prefix adds a new route 861 # - iproute2 sets NLM_F_CREATE | NLM_F_APPEND 862 add_route6 "2001:db8:104::/64" "via 2001:db8:101::2" 863 run_cmd "$IP -6 ro append 2001:db8:104::/64 via 2001:db8:103::2" 864 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" 865 log_test $? 0 "Append nexthop to existing route - gw" 866 867 # insert mpath directly 868 add_route6 "2001:db8:104::/64" "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2" 869 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" 870 log_test $? 0 "Add multipath route" 871 872 add_route6 "2001:db8:104::/64" "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2" 873 run_cmd "$IP -6 ro add 2001:db8:104::/64 nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2" 874 log_test $? 2 "Attempt to add duplicate multipath route" 875 876 # insert of a second route without append but different metric 877 add_route6 "2001:db8:104::/64" "via 2001:db8:101::2" 878 run_cmd "$IP -6 ro add 2001:db8:104::/64 via 2001:db8:103::2 metric 512" 879 rc=$? 880 if [ $rc -eq 0 ]; then 881 run_cmd "$IP -6 ro add 2001:db8:104::/64 via 2001:db8:103::3 metric 256" 882 rc=$? 883 fi 884 log_test $rc 0 "Route add with different metrics" 885 886 run_cmd "$IP -6 ro del 2001:db8:104::/64 metric 512" 887 rc=$? 888 if [ $rc -eq 0 ]; then 889 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" 890 rc=$? 891 fi 892 log_test $rc 0 "Route delete with metric" 893} 894 895ipv6_rt_replace_single() 896{ 897 # single path with single path 898 # 899 add_initial_route6 "via 2001:db8:101::2" 900 run_cmd "$IP -6 ro replace 2001:db8:104::/64 via 2001:db8:103::2" 901 check_route6 "2001:db8:104::/64 via 2001:db8:103::2 dev veth3 metric 1024" 902 log_test $? 0 "Single path with single path" 903 904 # single path with multipath 905 # 906 add_initial_route6 "nexthop via 2001:db8:101::2" 907 run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:101::3 nexthop via 2001:db8:103::2" 908 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" 909 log_test $? 0 "Single path with multipath" 910 911 # single path with single path using MULTIPATH attribute 912 # 913 add_initial_route6 "via 2001:db8:101::2" 914 run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:103::2" 915 check_route6 "2001:db8:104::/64 via 2001:db8:103::2 dev veth3 metric 1024" 916 log_test $? 0 "Single path with single path via multipath attribute" 917 918 # route replace fails - invalid nexthop 919 add_initial_route6 "via 2001:db8:101::2" 920 run_cmd "$IP -6 ro replace 2001:db8:104::/64 via 2001:db8:104::2" 921 if [ $? -eq 0 ]; then 922 # previous command is expected to fail so if it returns 0 923 # that means the test failed. 924 log_test 0 1 "Invalid nexthop" 925 else 926 check_route6 "2001:db8:104::/64 via 2001:db8:101::2 dev veth1 metric 1024" 927 log_test $? 0 "Invalid nexthop" 928 fi 929 930 # replace non-existent route 931 # - note use of change versus replace since ip adds NLM_F_CREATE 932 # for replace 933 add_initial_route6 "via 2001:db8:101::2" 934 run_cmd "$IP -6 ro change 2001:db8:105::/64 via 2001:db8:101::2" 935 log_test $? 2 "Single path - replace of non-existent route" 936} 937 938ipv6_rt_replace_mpath() 939{ 940 # multipath with multipath 941 add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2" 942 run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:101::3 nexthop via 2001:db8:103::3" 943 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" 944 log_test $? 0 "Multipath with multipath" 945 946 # multipath with single 947 add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2" 948 run_cmd "$IP -6 ro replace 2001:db8:104::/64 via 2001:db8:101::3" 949 check_route6 "2001:db8:104::/64 via 2001:db8:101::3 dev veth1 metric 1024" 950 log_test $? 0 "Multipath with single path" 951 952 # multipath with single 953 add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2" 954 run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:101::3" 955 check_route6 "2001:db8:104::/64 via 2001:db8:101::3 dev veth1 metric 1024" 956 log_test $? 0 "Multipath with single path via multipath attribute" 957 958 # multipath with dev-only 959 add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2" 960 run_cmd "$IP -6 ro replace 2001:db8:104::/64 dev veth1" 961 check_route6 "2001:db8:104::/64 dev veth1 metric 1024" 962 log_test $? 0 "Multipath with dev-only" 963 964 # route replace fails - invalid nexthop 1 965 add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2" 966 run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:111::3 nexthop via 2001:db8:103::3" 967 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" 968 log_test $? 0 "Multipath - invalid first nexthop" 969 970 # route replace fails - invalid nexthop 2 971 add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2" 972 run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:101::3 nexthop via 2001:db8:113::3" 973 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" 974 log_test $? 0 "Multipath - invalid second nexthop" 975 976 # multipath non-existent route 977 add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2" 978 run_cmd "$IP -6 ro change 2001:db8:105::/64 nexthop via 2001:db8:101::3 nexthop via 2001:db8:103::3" 979 log_test $? 2 "Multipath - replace of non-existent route" 980} 981 982ipv6_rt_replace() 983{ 984 echo 985 echo "IPv6 route replace tests" 986 987 ipv6_rt_replace_single 988 ipv6_rt_replace_mpath 989} 990 991ipv6_rt_dsfield() 992{ 993 echo 994 echo "IPv6 route with dsfield tests" 995 996 run_cmd "$IP -6 route flush 2001:db8:102::/64" 997 998 # IPv6 doesn't support routing based on dsfield 999 run_cmd "$IP -6 route add 2001:db8:102::/64 dsfield 0x04 via 2001:db8:101::2" 1000 log_test $? 2 "Reject route with dsfield" 1001} 1002 1003ipv6_route_test() 1004{ 1005 route_setup 1006 1007 ipv6_rt_add 1008 ipv6_rt_replace 1009 ipv6_rt_dsfield 1010 1011 route_cleanup 1012} 1013 1014ip_addr_metric_check() 1015{ 1016 ip addr help 2>&1 | grep -q metric 1017 if [ $? -ne 0 ]; then 1018 echo "iproute2 command does not support metric for addresses. Skipping test" 1019 return 1 1020 fi 1021 1022 return 0 1023} 1024 1025ipv6_addr_metric_test() 1026{ 1027 local rc 1028 1029 echo 1030 echo "IPv6 prefix route tests" 1031 1032 ip_addr_metric_check || return 1 1033 1034 setup 1035 1036 set -e 1037 $IP li add dummy1 type dummy 1038 $IP li add dummy2 type dummy 1039 $IP li set dummy1 up 1040 $IP li set dummy2 up 1041 1042 # default entry is metric 256 1043 run_cmd "$IP -6 addr add dev dummy1 2001:db8:104::1/64" 1044 run_cmd "$IP -6 addr add dev dummy2 2001:db8:104::2/64" 1045 set +e 1046 1047 check_route6 "2001:db8:104::/64 dev dummy1 proto kernel metric 256 2001:db8:104::/64 dev dummy2 proto kernel metric 256" 1048 log_test $? 0 "Default metric" 1049 1050 set -e 1051 run_cmd "$IP -6 addr flush dev dummy1" 1052 run_cmd "$IP -6 addr add dev dummy1 2001:db8:104::1/64 metric 257" 1053 set +e 1054 1055 check_route6 "2001:db8:104::/64 dev dummy2 proto kernel metric 256 2001:db8:104::/64 dev dummy1 proto kernel metric 257" 1056 log_test $? 0 "User specified metric on first device" 1057 1058 set -e 1059 run_cmd "$IP -6 addr flush dev dummy2" 1060 run_cmd "$IP -6 addr add dev dummy2 2001:db8:104::2/64 metric 258" 1061 set +e 1062 1063 check_route6 "2001:db8:104::/64 dev dummy1 proto kernel metric 257 2001:db8:104::/64 dev dummy2 proto kernel metric 258" 1064 log_test $? 0 "User specified metric on second device" 1065 1066 run_cmd "$IP -6 addr del dev dummy1 2001:db8:104::1/64 metric 257" 1067 rc=$? 1068 if [ $rc -eq 0 ]; then 1069 check_route6 "2001:db8:104::/64 dev dummy2 proto kernel metric 258" 1070 rc=$? 1071 fi 1072 log_test $rc 0 "Delete of address on first device" 1073 1074 run_cmd "$IP -6 addr change dev dummy2 2001:db8:104::2/64 metric 259" 1075 rc=$? 1076 if [ $rc -eq 0 ]; then 1077 check_route6 "2001:db8:104::/64 dev dummy2 proto kernel metric 259" 1078 rc=$? 1079 fi 1080 log_test $rc 0 "Modify metric of address" 1081 1082 # verify prefix route removed on down 1083 run_cmd "ip netns exec ns1 sysctl -qw net.ipv6.conf.all.keep_addr_on_down=1" 1084 run_cmd "$IP li set dev dummy2 down" 1085 rc=$? 1086 if [ $rc -eq 0 ]; then 1087 out=$($IP -6 ro ls match 2001:db8:104::/64) 1088 check_expected "${out}" "" 1089 rc=$? 1090 fi 1091 log_test $rc 0 "Prefix route removed on link down" 1092 1093 # verify prefix route re-inserted with assigned metric 1094 run_cmd "$IP li set dev dummy2 up" 1095 rc=$? 1096 if [ $rc -eq 0 ]; then 1097 check_route6 "2001:db8:104::/64 dev dummy2 proto kernel metric 259" 1098 rc=$? 1099 fi 1100 log_test $rc 0 "Prefix route with metric on link up" 1101 1102 # verify peer metric added correctly 1103 set -e 1104 run_cmd "$IP -6 addr flush dev dummy2" 1105 run_cmd "$IP -6 addr add dev dummy2 2001:db8:104::1 peer 2001:db8:104::2 metric 260" 1106 set +e 1107 1108 check_route6 "2001:db8:104::1 dev dummy2 proto kernel metric 260" 1109 log_test $? 0 "Set metric with peer route on local side" 1110 check_route6 "2001:db8:104::2 dev dummy2 proto kernel metric 260" 1111 log_test $? 0 "Set metric with peer route on peer side" 1112 1113 set -e 1114 run_cmd "$IP -6 addr change dev dummy2 2001:db8:104::1 peer 2001:db8:104::3 metric 261" 1115 set +e 1116 1117 check_route6 "2001:db8:104::1 dev dummy2 proto kernel metric 261" 1118 log_test $? 0 "Modify metric and peer address on local side" 1119 check_route6 "2001:db8:104::3 dev dummy2 proto kernel metric 261" 1120 log_test $? 0 "Modify metric and peer address on peer side" 1121 1122 $IP li del dummy1 1123 $IP li del dummy2 1124 cleanup 1125} 1126 1127ipv6_route_metrics_test() 1128{ 1129 local rc 1130 1131 echo 1132 echo "IPv6 routes with metrics" 1133 1134 route_setup 1135 1136 # 1137 # single path with metrics 1138 # 1139 run_cmd "$IP -6 ro add 2001:db8:111::/64 via 2001:db8:101::2 mtu 1400" 1140 rc=$? 1141 if [ $rc -eq 0 ]; then 1142 check_route6 "2001:db8:111::/64 via 2001:db8:101::2 dev veth1 metric 1024 mtu 1400" 1143 rc=$? 1144 fi 1145 log_test $rc 0 "Single path route with mtu metric" 1146 1147 1148 # 1149 # multipath via separate routes with metrics 1150 # 1151 run_cmd "$IP -6 ro add 2001:db8:112::/64 via 2001:db8:101::2 mtu 1400" 1152 run_cmd "$IP -6 ro append 2001:db8:112::/64 via 2001:db8:103::2" 1153 rc=$? 1154 if [ $rc -eq 0 ]; then 1155 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" 1156 rc=$? 1157 fi 1158 log_test $rc 0 "Multipath route via 2 single routes with mtu metric on first" 1159 1160 # second route is coalesced to first to make a multipath route. 1161 # MTU of the second path is hidden from display! 1162 run_cmd "$IP -6 ro add 2001:db8:113::/64 via 2001:db8:101::2" 1163 run_cmd "$IP -6 ro append 2001:db8:113::/64 via 2001:db8:103::2 mtu 1400" 1164 rc=$? 1165 if [ $rc -eq 0 ]; then 1166 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" 1167 rc=$? 1168 fi 1169 log_test $rc 0 "Multipath route via 2 single routes with mtu metric on 2nd" 1170 1171 run_cmd "$IP -6 ro del 2001:db8:113::/64 via 2001:db8:101::2" 1172 if [ $? -eq 0 ]; then 1173 check_route6 "2001:db8:113::/64 via 2001:db8:103::2 dev veth3 metric 1024 mtu 1400" 1174 log_test $? 0 " MTU of second leg" 1175 fi 1176 1177 # 1178 # multipath with metrics 1179 # 1180 run_cmd "$IP -6 ro add 2001:db8:115::/64 mtu 1400 nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2" 1181 rc=$? 1182 if [ $rc -eq 0 ]; then 1183 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" 1184 rc=$? 1185 fi 1186 log_test $rc 0 "Multipath route with mtu metric" 1187 1188 $IP -6 ro add 2001:db8:104::/64 via 2001:db8:101::2 mtu 1300 1189 run_cmd "ip netns exec ns1 ${ping6} -w1 -c1 -s 1500 2001:db8:104::1" 1190 log_test $? 0 "Using route with mtu metric" 1191 1192 run_cmd "$IP -6 ro add 2001:db8:114::/64 via 2001:db8:101::2 congctl lock foo" 1193 log_test $? 2 "Invalid metric (fails metric_convert)" 1194 1195 route_cleanup 1196} 1197 1198# add route for a prefix, flushing any existing routes first 1199# expected to be the first step of a test 1200add_route() 1201{ 1202 local pfx="$1" 1203 local nh="$2" 1204 local out 1205 1206 if [ "$VERBOSE" = "1" ]; then 1207 echo 1208 echo " ##################################################" 1209 echo 1210 fi 1211 1212 run_cmd "$IP ro flush ${pfx}" 1213 [ $? -ne 0 ] && exit 1 1214 1215 out=$($IP ro ls match ${pfx}) 1216 if [ -n "$out" ]; then 1217 echo "Failed to flush routes for prefix used for tests." 1218 exit 1 1219 fi 1220 1221 run_cmd "$IP ro add ${pfx} ${nh}" 1222 if [ $? -ne 0 ]; then 1223 echo "Failed to add initial route for test." 1224 exit 1 1225 fi 1226} 1227 1228# add initial route - used in replace route tests 1229add_initial_route() 1230{ 1231 add_route "172.16.104.0/24" "$1" 1232} 1233 1234check_route() 1235{ 1236 local pfx 1237 local expected="$1" 1238 local out 1239 1240 set -- $expected 1241 pfx=$1 1242 [ "${pfx}" = "unreachable" ] && pfx=$2 1243 1244 out=$($IP ro ls match ${pfx}) 1245 check_expected "${out}" "${expected}" 1246} 1247 1248# assumption is that basic add of a single path route works 1249# otherwise just adding an address on an interface is broken 1250ipv4_rt_add() 1251{ 1252 local rc 1253 1254 echo 1255 echo "IPv4 route add / append tests" 1256 1257 # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL 1258 add_route "172.16.104.0/24" "via 172.16.101.2" 1259 run_cmd "$IP ro add 172.16.104.0/24 via 172.16.103.2" 1260 log_test $? 2 "Attempt to add duplicate route - gw" 1261 1262 # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL 1263 add_route "172.16.104.0/24" "via 172.16.101.2" 1264 run_cmd "$IP ro add 172.16.104.0/24 dev veth3" 1265 log_test $? 2 "Attempt to add duplicate route - dev only" 1266 1267 # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL 1268 add_route "172.16.104.0/24" "via 172.16.101.2" 1269 run_cmd "$IP ro add unreachable 172.16.104.0/24" 1270 log_test $? 2 "Attempt to add duplicate route - reject route" 1271 1272 # iproute2 prepend only sets NLM_F_CREATE 1273 # - adds a new route; does NOT convert existing route to ECMP 1274 add_route "172.16.104.0/24" "via 172.16.101.2" 1275 run_cmd "$IP ro prepend 172.16.104.0/24 via 172.16.103.2" 1276 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" 1277 log_test $? 0 "Add new nexthop for existing prefix" 1278 1279 # route append with same prefix adds a new route 1280 # - iproute2 sets NLM_F_CREATE | NLM_F_APPEND 1281 add_route "172.16.104.0/24" "via 172.16.101.2" 1282 run_cmd "$IP ro append 172.16.104.0/24 via 172.16.103.2" 1283 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" 1284 log_test $? 0 "Append nexthop to existing route - gw" 1285 1286 add_route "172.16.104.0/24" "via 172.16.101.2" 1287 run_cmd "$IP ro append 172.16.104.0/24 dev veth3" 1288 check_route "172.16.104.0/24 via 172.16.101.2 dev veth1 172.16.104.0/24 dev veth3 scope link" 1289 log_test $? 0 "Append nexthop to existing route - dev only" 1290 1291 add_route "172.16.104.0/24" "via 172.16.101.2" 1292 run_cmd "$IP ro append unreachable 172.16.104.0/24" 1293 check_route "172.16.104.0/24 via 172.16.101.2 dev veth1 unreachable 172.16.104.0/24" 1294 log_test $? 0 "Append nexthop to existing route - reject route" 1295 1296 run_cmd "$IP ro flush 172.16.104.0/24" 1297 run_cmd "$IP ro add unreachable 172.16.104.0/24" 1298 run_cmd "$IP ro append 172.16.104.0/24 via 172.16.103.2" 1299 check_route "unreachable 172.16.104.0/24 172.16.104.0/24 via 172.16.103.2 dev veth3" 1300 log_test $? 0 "Append nexthop to existing reject route - gw" 1301 1302 run_cmd "$IP ro flush 172.16.104.0/24" 1303 run_cmd "$IP ro add unreachable 172.16.104.0/24" 1304 run_cmd "$IP ro append 172.16.104.0/24 dev veth3" 1305 check_route "unreachable 172.16.104.0/24 172.16.104.0/24 dev veth3 scope link" 1306 log_test $? 0 "Append nexthop to existing reject route - dev only" 1307 1308 # insert mpath directly 1309 add_route "172.16.104.0/24" "nexthop via 172.16.101.2 nexthop via 172.16.103.2" 1310 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" 1311 log_test $? 0 "add multipath route" 1312 1313 add_route "172.16.104.0/24" "nexthop via 172.16.101.2 nexthop via 172.16.103.2" 1314 run_cmd "$IP ro add 172.16.104.0/24 nexthop via 172.16.101.2 nexthop via 172.16.103.2" 1315 log_test $? 2 "Attempt to add duplicate multipath route" 1316 1317 # insert of a second route without append but different metric 1318 add_route "172.16.104.0/24" "via 172.16.101.2" 1319 run_cmd "$IP ro add 172.16.104.0/24 via 172.16.103.2 metric 512" 1320 rc=$? 1321 if [ $rc -eq 0 ]; then 1322 run_cmd "$IP ro add 172.16.104.0/24 via 172.16.103.3 metric 256" 1323 rc=$? 1324 fi 1325 log_test $rc 0 "Route add with different metrics" 1326 1327 run_cmd "$IP ro del 172.16.104.0/24 metric 512" 1328 rc=$? 1329 if [ $rc -eq 0 ]; then 1330 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" 1331 rc=$? 1332 fi 1333 log_test $rc 0 "Route delete with metric" 1334} 1335 1336ipv4_rt_replace_single() 1337{ 1338 # single path with single path 1339 # 1340 add_initial_route "via 172.16.101.2" 1341 run_cmd "$IP ro replace 172.16.104.0/24 via 172.16.103.2" 1342 check_route "172.16.104.0/24 via 172.16.103.2 dev veth3" 1343 log_test $? 0 "Single path with single path" 1344 1345 # single path with multipath 1346 # 1347 add_initial_route "nexthop via 172.16.101.2" 1348 run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.101.3 nexthop via 172.16.103.2" 1349 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" 1350 log_test $? 0 "Single path with multipath" 1351 1352 # single path with reject 1353 # 1354 add_initial_route "nexthop via 172.16.101.2" 1355 run_cmd "$IP ro replace unreachable 172.16.104.0/24" 1356 check_route "unreachable 172.16.104.0/24" 1357 log_test $? 0 "Single path with reject route" 1358 1359 # single path with single path using MULTIPATH attribute 1360 # 1361 add_initial_route "via 172.16.101.2" 1362 run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.103.2" 1363 check_route "172.16.104.0/24 via 172.16.103.2 dev veth3" 1364 log_test $? 0 "Single path with single path via multipath attribute" 1365 1366 # route replace fails - invalid nexthop 1367 add_initial_route "via 172.16.101.2" 1368 run_cmd "$IP ro replace 172.16.104.0/24 via 2001:db8:104::2" 1369 if [ $? -eq 0 ]; then 1370 # previous command is expected to fail so if it returns 0 1371 # that means the test failed. 1372 log_test 0 1 "Invalid nexthop" 1373 else 1374 check_route "172.16.104.0/24 via 172.16.101.2 dev veth1" 1375 log_test $? 0 "Invalid nexthop" 1376 fi 1377 1378 # replace non-existent route 1379 # - note use of change versus replace since ip adds NLM_F_CREATE 1380 # for replace 1381 add_initial_route "via 172.16.101.2" 1382 run_cmd "$IP ro change 172.16.105.0/24 via 172.16.101.2" 1383 log_test $? 2 "Single path - replace of non-existent route" 1384} 1385 1386ipv4_rt_replace_mpath() 1387{ 1388 # multipath with multipath 1389 add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2" 1390 run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.101.3 nexthop via 172.16.103.3" 1391 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" 1392 log_test $? 0 "Multipath with multipath" 1393 1394 # multipath with single 1395 add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2" 1396 run_cmd "$IP ro replace 172.16.104.0/24 via 172.16.101.3" 1397 check_route "172.16.104.0/24 via 172.16.101.3 dev veth1" 1398 log_test $? 0 "Multipath with single path" 1399 1400 # multipath with single 1401 add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2" 1402 run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.101.3" 1403 check_route "172.16.104.0/24 via 172.16.101.3 dev veth1" 1404 log_test $? 0 "Multipath with single path via multipath attribute" 1405 1406 # multipath with reject 1407 add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2" 1408 run_cmd "$IP ro replace unreachable 172.16.104.0/24" 1409 check_route "unreachable 172.16.104.0/24" 1410 log_test $? 0 "Multipath with reject route" 1411 1412 # route replace fails - invalid nexthop 1 1413 add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2" 1414 run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.111.3 nexthop via 172.16.103.3" 1415 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" 1416 log_test $? 0 "Multipath - invalid first nexthop" 1417 1418 # route replace fails - invalid nexthop 2 1419 add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2" 1420 run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.101.3 nexthop via 172.16.113.3" 1421 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" 1422 log_test $? 0 "Multipath - invalid second nexthop" 1423 1424 # multipath non-existent route 1425 add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2" 1426 run_cmd "$IP ro change 172.16.105.0/24 nexthop via 172.16.101.3 nexthop via 172.16.103.3" 1427 log_test $? 2 "Multipath - replace of non-existent route" 1428} 1429 1430ipv4_rt_replace() 1431{ 1432 echo 1433 echo "IPv4 route replace tests" 1434 1435 ipv4_rt_replace_single 1436 ipv4_rt_replace_mpath 1437} 1438 1439# checks that cached input route on VRF port is deleted 1440# when VRF is deleted 1441ipv4_local_rt_cache() 1442{ 1443 run_cmd "ip addr add 10.0.0.1/32 dev lo" 1444 run_cmd "ip netns add test-ns" 1445 run_cmd "ip link add veth-outside type veth peer name veth-inside" 1446 run_cmd "ip link add vrf-100 type vrf table 1100" 1447 run_cmd "ip link set veth-outside master vrf-100" 1448 run_cmd "ip link set veth-inside netns test-ns" 1449 run_cmd "ip link set veth-outside up" 1450 run_cmd "ip link set vrf-100 up" 1451 run_cmd "ip route add 10.1.1.1/32 dev veth-outside table 1100" 1452 run_cmd "ip netns exec test-ns ip link set veth-inside up" 1453 run_cmd "ip netns exec test-ns ip addr add 10.1.1.1/32 dev veth-inside" 1454 run_cmd "ip netns exec test-ns ip route add 10.0.0.1/32 dev veth-inside" 1455 run_cmd "ip netns exec test-ns ip route add default via 10.0.0.1" 1456 run_cmd "ip netns exec test-ns ping 10.0.0.1 -c 1 -i 1" 1457 run_cmd "ip link delete vrf-100" 1458 1459 # if we do not hang test is a success 1460 log_test $? 0 "Cached route removed from VRF port device" 1461} 1462 1463ipv4_rt_dsfield() 1464{ 1465 echo 1466 echo "IPv4 route with dsfield tests" 1467 1468 run_cmd "$IP route flush 172.16.102.0/24" 1469 1470 # New routes should reject dsfield options that interfere with ECN 1471 run_cmd "$IP route add 172.16.102.0/24 dsfield 0x01 via 172.16.101.2" 1472 log_test $? 2 "Reject route with dsfield 0x01" 1473 1474 run_cmd "$IP route add 172.16.102.0/24 dsfield 0x02 via 172.16.101.2" 1475 log_test $? 2 "Reject route with dsfield 0x02" 1476 1477 run_cmd "$IP route add 172.16.102.0/24 dsfield 0x03 via 172.16.101.2" 1478 log_test $? 2 "Reject route with dsfield 0x03" 1479 1480 # A generic route that doesn't take DSCP into account 1481 run_cmd "$IP route add 172.16.102.0/24 via 172.16.101.2" 1482 1483 # A more specific route for DSCP 0x10 1484 run_cmd "$IP route add 172.16.102.0/24 dsfield 0x10 via 172.16.103.2" 1485 1486 # DSCP 0x10 should match the specific route, no matter the ECN bits 1487 $IP route get fibmatch 172.16.102.1 dsfield 0x10 | \ 1488 grep -q "via 172.16.103.2" 1489 log_test $? 0 "IPv4 route with DSCP and ECN:Not-ECT" 1490 1491 $IP route get fibmatch 172.16.102.1 dsfield 0x11 | \ 1492 grep -q "via 172.16.103.2" 1493 log_test $? 0 "IPv4 route with DSCP and ECN:ECT(1)" 1494 1495 $IP route get fibmatch 172.16.102.1 dsfield 0x12 | \ 1496 grep -q "via 172.16.103.2" 1497 log_test $? 0 "IPv4 route with DSCP and ECN:ECT(0)" 1498 1499 $IP route get fibmatch 172.16.102.1 dsfield 0x13 | \ 1500 grep -q "via 172.16.103.2" 1501 log_test $? 0 "IPv4 route with DSCP and ECN:CE" 1502 1503 # Unknown DSCP should match the generic route, no matter the ECN bits 1504 $IP route get fibmatch 172.16.102.1 dsfield 0x14 | \ 1505 grep -q "via 172.16.101.2" 1506 log_test $? 0 "IPv4 route with unknown DSCP and ECN:Not-ECT" 1507 1508 $IP route get fibmatch 172.16.102.1 dsfield 0x15 | \ 1509 grep -q "via 172.16.101.2" 1510 log_test $? 0 "IPv4 route with unknown DSCP and ECN:ECT(1)" 1511 1512 $IP route get fibmatch 172.16.102.1 dsfield 0x16 | \ 1513 grep -q "via 172.16.101.2" 1514 log_test $? 0 "IPv4 route with unknown DSCP and ECN:ECT(0)" 1515 1516 $IP route get fibmatch 172.16.102.1 dsfield 0x17 | \ 1517 grep -q "via 172.16.101.2" 1518 log_test $? 0 "IPv4 route with unknown DSCP and ECN:CE" 1519 1520 # Null DSCP should match the generic route, no matter the ECN bits 1521 $IP route get fibmatch 172.16.102.1 dsfield 0x00 | \ 1522 grep -q "via 172.16.101.2" 1523 log_test $? 0 "IPv4 route with no DSCP and ECN:Not-ECT" 1524 1525 $IP route get fibmatch 172.16.102.1 dsfield 0x01 | \ 1526 grep -q "via 172.16.101.2" 1527 log_test $? 0 "IPv4 route with no DSCP and ECN:ECT(1)" 1528 1529 $IP route get fibmatch 172.16.102.1 dsfield 0x02 | \ 1530 grep -q "via 172.16.101.2" 1531 log_test $? 0 "IPv4 route with no DSCP and ECN:ECT(0)" 1532 1533 $IP route get fibmatch 172.16.102.1 dsfield 0x03 | \ 1534 grep -q "via 172.16.101.2" 1535 log_test $? 0 "IPv4 route with no DSCP and ECN:CE" 1536} 1537 1538ipv4_route_test() 1539{ 1540 route_setup 1541 1542 ipv4_rt_add 1543 ipv4_rt_replace 1544 ipv4_local_rt_cache 1545 ipv4_rt_dsfield 1546 1547 route_cleanup 1548} 1549 1550ipv4_addr_metric_test() 1551{ 1552 local rc 1553 1554 echo 1555 echo "IPv4 prefix route tests" 1556 1557 ip_addr_metric_check || return 1 1558 1559 setup 1560 1561 set -e 1562 $IP li add dummy1 type dummy 1563 $IP li add dummy2 type dummy 1564 $IP li set dummy1 up 1565 $IP li set dummy2 up 1566 1567 # default entry is metric 256 1568 run_cmd "$IP addr add dev dummy1 172.16.104.1/24" 1569 run_cmd "$IP addr add dev dummy2 172.16.104.2/24" 1570 set +e 1571 1572 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" 1573 log_test $? 0 "Default metric" 1574 1575 set -e 1576 run_cmd "$IP addr flush dev dummy1" 1577 run_cmd "$IP addr add dev dummy1 172.16.104.1/24 metric 257" 1578 set +e 1579 1580 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" 1581 log_test $? 0 "User specified metric on first device" 1582 1583 set -e 1584 run_cmd "$IP addr flush dev dummy2" 1585 run_cmd "$IP addr add dev dummy2 172.16.104.2/24 metric 258" 1586 set +e 1587 1588 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" 1589 log_test $? 0 "User specified metric on second device" 1590 1591 run_cmd "$IP addr del dev dummy1 172.16.104.1/24 metric 257" 1592 rc=$? 1593 if [ $rc -eq 0 ]; then 1594 check_route "172.16.104.0/24 dev dummy2 proto kernel scope link src 172.16.104.2 metric 258" 1595 rc=$? 1596 fi 1597 log_test $rc 0 "Delete of address on first device" 1598 1599 run_cmd "$IP addr change dev dummy2 172.16.104.2/24 metric 259" 1600 rc=$? 1601 if [ $rc -eq 0 ]; then 1602 check_route "172.16.104.0/24 dev dummy2 proto kernel scope link src 172.16.104.2 metric 259" 1603 rc=$? 1604 fi 1605 log_test $rc 0 "Modify metric of address" 1606 1607 # verify prefix route removed on down 1608 run_cmd "$IP li set dev dummy2 down" 1609 rc=$? 1610 if [ $rc -eq 0 ]; then 1611 out=$($IP ro ls match 172.16.104.0/24) 1612 check_expected "${out}" "" 1613 rc=$? 1614 fi 1615 log_test $rc 0 "Prefix route removed on link down" 1616 1617 # verify prefix route re-inserted with assigned metric 1618 run_cmd "$IP li set dev dummy2 up" 1619 rc=$? 1620 if [ $rc -eq 0 ]; then 1621 check_route "172.16.104.0/24 dev dummy2 proto kernel scope link src 172.16.104.2 metric 259" 1622 rc=$? 1623 fi 1624 log_test $rc 0 "Prefix route with metric on link up" 1625 1626 # explicitly check for metric changes on edge scenarios 1627 run_cmd "$IP addr flush dev dummy2" 1628 run_cmd "$IP addr add dev dummy2 172.16.104.0/24 metric 259" 1629 run_cmd "$IP addr change dev dummy2 172.16.104.0/24 metric 260" 1630 rc=$? 1631 if [ $rc -eq 0 ]; then 1632 check_route "172.16.104.0/24 dev dummy2 proto kernel scope link src 172.16.104.0 metric 260" 1633 rc=$? 1634 fi 1635 log_test $rc 0 "Modify metric of .0/24 address" 1636 1637 run_cmd "$IP addr flush dev dummy2" 1638 run_cmd "$IP addr add dev dummy2 172.16.104.1/32 peer 172.16.104.2 metric 260" 1639 rc=$? 1640 if [ $rc -eq 0 ]; then 1641 check_route "172.16.104.2 dev dummy2 proto kernel scope link src 172.16.104.1 metric 260" 1642 rc=$? 1643 fi 1644 log_test $rc 0 "Set metric of address with peer route" 1645 1646 run_cmd "$IP addr change dev dummy2 172.16.104.1/32 peer 172.16.104.3 metric 261" 1647 rc=$? 1648 if [ $rc -eq 0 ]; then 1649 check_route "172.16.104.3 dev dummy2 proto kernel scope link src 172.16.104.1 metric 261" 1650 rc=$? 1651 fi 1652 log_test $rc 0 "Modify metric and peer address for peer route" 1653 1654 $IP li del dummy1 1655 $IP li del dummy2 1656 cleanup 1657} 1658 1659ipv4_route_metrics_test() 1660{ 1661 local rc 1662 1663 echo 1664 echo "IPv4 route add / append tests" 1665 1666 route_setup 1667 1668 run_cmd "$IP ro add 172.16.111.0/24 via 172.16.101.2 mtu 1400" 1669 rc=$? 1670 if [ $rc -eq 0 ]; then 1671 check_route "172.16.111.0/24 via 172.16.101.2 dev veth1 mtu 1400" 1672 rc=$? 1673 fi 1674 log_test $rc 0 "Single path route with mtu metric" 1675 1676 1677 run_cmd "$IP ro add 172.16.112.0/24 mtu 1400 nexthop via 172.16.101.2 nexthop via 172.16.103.2" 1678 rc=$? 1679 if [ $rc -eq 0 ]; then 1680 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" 1681 rc=$? 1682 fi 1683 log_test $rc 0 "Multipath route with mtu metric" 1684 1685 $IP ro add 172.16.104.0/24 via 172.16.101.2 mtu 1300 1686 run_cmd "ip netns exec ns1 ping -w1 -c1 -s 1500 172.16.104.1" 1687 log_test $? 0 "Using route with mtu metric" 1688 1689 run_cmd "$IP ro add 172.16.111.0/24 via 172.16.101.2 congctl lock foo" 1690 log_test $? 2 "Invalid metric (fails metric_convert)" 1691 1692 route_cleanup 1693} 1694 1695ipv4_del_addr_test() 1696{ 1697 echo 1698 echo "IPv4 delete address route tests" 1699 1700 setup 1701 1702 set -e 1703 $IP li add dummy1 type dummy 1704 $IP li set dummy1 up 1705 $IP li add dummy2 type dummy 1706 $IP li set dummy2 up 1707 $IP li add red type vrf table 1111 1708 $IP li set red up 1709 $IP ro add vrf red unreachable default 1710 $IP li set dummy2 vrf red 1711 1712 $IP addr add dev dummy1 172.16.104.1/24 1713 $IP addr add dev dummy1 172.16.104.11/24 1714 $IP addr add dev dummy1 172.16.104.12/24 1715 $IP addr add dev dummy1 172.16.104.13/24 1716 $IP addr add dev dummy2 172.16.104.1/24 1717 $IP addr add dev dummy2 172.16.104.11/24 1718 $IP addr add dev dummy2 172.16.104.12/24 1719 $IP route add 172.16.105.0/24 via 172.16.104.2 src 172.16.104.11 1720 $IP route add 172.16.106.0/24 dev lo src 172.16.104.12 1721 $IP route add table 0 172.16.107.0/24 via 172.16.104.2 src 172.16.104.13 1722 $IP route add vrf red 172.16.105.0/24 via 172.16.104.2 src 172.16.104.11 1723 $IP route add vrf red 172.16.106.0/24 dev lo src 172.16.104.12 1724 set +e 1725 1726 # removing address from device in vrf should only remove route from vrf table 1727 echo " Regular FIB info" 1728 1729 $IP addr del dev dummy2 172.16.104.11/24 1730 $IP ro ls vrf red | grep -q 172.16.105.0/24 1731 log_test $? 1 "Route removed from VRF when source address deleted" 1732 1733 $IP ro ls | grep -q 172.16.105.0/24 1734 log_test $? 0 "Route in default VRF not removed" 1735 1736 $IP addr add dev dummy2 172.16.104.11/24 1737 $IP route add vrf red 172.16.105.0/24 via 172.16.104.2 src 172.16.104.11 1738 1739 $IP addr del dev dummy1 172.16.104.11/24 1740 $IP ro ls | grep -q 172.16.105.0/24 1741 log_test $? 1 "Route removed in default VRF when source address deleted" 1742 1743 $IP ro ls vrf red | grep -q 172.16.105.0/24 1744 log_test $? 0 "Route in VRF is not removed by address delete" 1745 1746 # removing address from device in vrf should only remove route from vrf 1747 # table even when the associated fib info only differs in table ID 1748 echo " Identical FIB info with different table ID" 1749 1750 $IP addr del dev dummy2 172.16.104.12/24 1751 $IP ro ls vrf red | grep -q 172.16.106.0/24 1752 log_test $? 1 "Route removed from VRF when source address deleted" 1753 1754 $IP ro ls | grep -q 172.16.106.0/24 1755 log_test $? 0 "Route in default VRF not removed" 1756 1757 $IP addr add dev dummy2 172.16.104.12/24 1758 $IP route add vrf red 172.16.106.0/24 dev lo src 172.16.104.12 1759 1760 $IP addr del dev dummy1 172.16.104.12/24 1761 $IP ro ls | grep -q 172.16.106.0/24 1762 log_test $? 1 "Route removed in default VRF when source address deleted" 1763 1764 $IP ro ls vrf red | grep -q 172.16.106.0/24 1765 log_test $? 0 "Route in VRF is not removed by address delete" 1766 1767 # removing address from device in default vrf should remove route from 1768 # the default vrf even when route was inserted with a table ID of 0. 1769 echo " Table ID 0" 1770 1771 $IP addr del dev dummy1 172.16.104.13/24 1772 $IP ro ls | grep -q 172.16.107.0/24 1773 log_test $? 1 "Route removed in default VRF when source address deleted" 1774 1775 $IP li del dummy1 1776 $IP li del dummy2 1777 cleanup 1778} 1779 1780 1781ipv4_route_v6_gw_test() 1782{ 1783 local rc 1784 1785 echo 1786 echo "IPv4 route with IPv6 gateway tests" 1787 1788 route_setup 1789 sleep 2 1790 1791 # 1792 # single path route 1793 # 1794 run_cmd "$IP ro add 172.16.104.0/24 via inet6 2001:db8:101::2" 1795 rc=$? 1796 log_test $rc 0 "Single path route with IPv6 gateway" 1797 if [ $rc -eq 0 ]; then 1798 check_route "172.16.104.0/24 via inet6 2001:db8:101::2 dev veth1" 1799 fi 1800 1801 run_cmd "ip netns exec ns1 ping -w1 -c1 172.16.104.1" 1802 log_test $rc 0 "Single path route with IPv6 gateway - ping" 1803 1804 run_cmd "$IP ro del 172.16.104.0/24 via inet6 2001:db8:101::2" 1805 rc=$? 1806 log_test $rc 0 "Single path route delete" 1807 if [ $rc -eq 0 ]; then 1808 check_route "172.16.112.0/24" 1809 fi 1810 1811 # 1812 # multipath - v6 then v4 1813 # 1814 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" 1815 rc=$? 1816 log_test $rc 0 "Multipath route add - v6 nexthop then v4" 1817 if [ $rc -eq 0 ]; then 1818 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" 1819 fi 1820 1821 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" 1822 log_test $? 2 " Multipath route delete - nexthops in wrong order" 1823 1824 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" 1825 log_test $? 0 " Multipath route delete exact match" 1826 1827 # 1828 # multipath - v4 then v6 1829 # 1830 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" 1831 rc=$? 1832 log_test $rc 0 "Multipath route add - v4 nexthop then v6" 1833 if [ $rc -eq 0 ]; then 1834 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" 1835 fi 1836 1837 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" 1838 log_test $? 2 " Multipath route delete - nexthops in wrong order" 1839 1840 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" 1841 log_test $? 0 " Multipath route delete exact match" 1842 1843 route_cleanup 1844} 1845 1846socat_check() 1847{ 1848 if [ ! -x "$(command -v socat)" ]; then 1849 echo "socat command not found. Skipping test" 1850 return 1 1851 fi 1852 1853 return 0 1854} 1855 1856iptables_check() 1857{ 1858 iptables -t mangle -L OUTPUT &> /dev/null 1859 if [ $? -ne 0 ]; then 1860 echo "iptables configuration not supported. Skipping test" 1861 return 1 1862 fi 1863 1864 return 0 1865} 1866 1867ip6tables_check() 1868{ 1869 ip6tables -t mangle -L OUTPUT &> /dev/null 1870 if [ $? -ne 0 ]; then 1871 echo "ip6tables configuration not supported. Skipping test" 1872 return 1 1873 fi 1874 1875 return 0 1876} 1877 1878ipv4_mangle_test() 1879{ 1880 local rc 1881 1882 echo 1883 echo "IPv4 mangling tests" 1884 1885 socat_check || return 1 1886 iptables_check || return 1 1887 1888 route_setup 1889 sleep 2 1890 1891 local tmp_file=$(mktemp) 1892 ip netns exec ns2 socat UDP4-LISTEN:54321,fork $tmp_file & 1893 1894 # Add a FIB rule and a route that will direct our connection to the 1895 # listening server. 1896 $IP rule add pref 100 ipproto udp sport 12345 dport 54321 table 123 1897 $IP route add table 123 172.16.101.0/24 dev veth1 1898 1899 # Add an unreachable route to the main table that will block our 1900 # connection in case the FIB rule is not hit. 1901 $IP route add unreachable 172.16.101.2/32 1902 1903 run_cmd "echo a | $NS_EXEC socat STDIN UDP4:172.16.101.2:54321,sourceport=12345" 1904 log_test $? 0 " Connection with correct parameters" 1905 1906 run_cmd "echo a | $NS_EXEC socat STDIN UDP4:172.16.101.2:54321,sourceport=11111" 1907 log_test $? 1 " Connection with incorrect parameters" 1908 1909 # Add a mangling rule and make sure connection is still successful. 1910 $NS_EXEC iptables -t mangle -A OUTPUT -j MARK --set-mark 1 1911 1912 run_cmd "echo a | $NS_EXEC socat STDIN UDP4:172.16.101.2:54321,sourceport=12345" 1913 log_test $? 0 " Connection with correct parameters - mangling" 1914 1915 # Delete the mangling rule and make sure connection is still 1916 # successful. 1917 $NS_EXEC iptables -t mangle -D OUTPUT -j MARK --set-mark 1 1918 1919 run_cmd "echo a | $NS_EXEC socat STDIN UDP4:172.16.101.2:54321,sourceport=12345" 1920 log_test $? 0 " Connection with correct parameters - no mangling" 1921 1922 # Verify connections were indeed successful on server side. 1923 [[ $(cat $tmp_file | wc -l) -eq 3 ]] 1924 log_test $? 0 " Connection check - server side" 1925 1926 $IP route del unreachable 172.16.101.2/32 1927 $IP route del table 123 172.16.101.0/24 dev veth1 1928 $IP rule del pref 100 1929 1930 { kill %% && wait %%; } 2>/dev/null 1931 rm $tmp_file 1932 1933 route_cleanup 1934} 1935 1936ipv6_mangle_test() 1937{ 1938 local rc 1939 1940 echo 1941 echo "IPv6 mangling tests" 1942 1943 socat_check || return 1 1944 ip6tables_check || return 1 1945 1946 route_setup 1947 sleep 2 1948 1949 local tmp_file=$(mktemp) 1950 ip netns exec ns2 socat UDP6-LISTEN:54321,fork $tmp_file & 1951 1952 # Add a FIB rule and a route that will direct our connection to the 1953 # listening server. 1954 $IP -6 rule add pref 100 ipproto udp sport 12345 dport 54321 table 123 1955 $IP -6 route add table 123 2001:db8:101::/64 dev veth1 1956 1957 # Add an unreachable route to the main table that will block our 1958 # connection in case the FIB rule is not hit. 1959 $IP -6 route add unreachable 2001:db8:101::2/128 1960 1961 run_cmd "echo a | $NS_EXEC socat STDIN UDP6:[2001:db8:101::2]:54321,sourceport=12345" 1962 log_test $? 0 " Connection with correct parameters" 1963 1964 run_cmd "echo a | $NS_EXEC socat STDIN UDP6:[2001:db8:101::2]:54321,sourceport=11111" 1965 log_test $? 1 " Connection with incorrect parameters" 1966 1967 # Add a mangling rule and make sure connection is still successful. 1968 $NS_EXEC ip6tables -t mangle -A OUTPUT -j MARK --set-mark 1 1969 1970 run_cmd "echo a | $NS_EXEC socat STDIN UDP6:[2001:db8:101::2]:54321,sourceport=12345" 1971 log_test $? 0 " Connection with correct parameters - mangling" 1972 1973 # Delete the mangling rule and make sure connection is still 1974 # successful. 1975 $NS_EXEC ip6tables -t mangle -D OUTPUT -j MARK --set-mark 1 1976 1977 run_cmd "echo a | $NS_EXEC socat STDIN UDP6:[2001:db8:101::2]:54321,sourceport=12345" 1978 log_test $? 0 " Connection with correct parameters - no mangling" 1979 1980 # Verify connections were indeed successful on server side. 1981 [[ $(cat $tmp_file | wc -l) -eq 3 ]] 1982 log_test $? 0 " Connection check - server side" 1983 1984 $IP -6 route del unreachable 2001:db8:101::2/128 1985 $IP -6 route del table 123 2001:db8:101::/64 dev veth1 1986 $IP -6 rule del pref 100 1987 1988 { kill %% && wait %%; } 2>/dev/null 1989 rm $tmp_file 1990 1991 route_cleanup 1992} 1993 1994ip_neigh_get_check() 1995{ 1996 ip neigh help 2>&1 | grep -q 'ip neigh get' 1997 if [ $? -ne 0 ]; then 1998 echo "iproute2 command does not support neigh get. Skipping test" 1999 return 1 2000 fi 2001 2002 return 0 2003} 2004 2005ipv4_bcast_neigh_test() 2006{ 2007 local rc 2008 2009 echo 2010 echo "IPv4 broadcast neighbour tests" 2011 2012 ip_neigh_get_check || return 1 2013 2014 setup 2015 2016 set -e 2017 run_cmd "$IP neigh add 192.0.2.111 lladdr 00:11:22:33:44:55 nud perm dev dummy0" 2018 run_cmd "$IP neigh add 192.0.2.255 lladdr 00:11:22:33:44:55 nud perm dev dummy0" 2019 2020 run_cmd "$IP neigh get 192.0.2.111 dev dummy0" 2021 run_cmd "$IP neigh get 192.0.2.255 dev dummy0" 2022 2023 run_cmd "$IP address add 192.0.2.1/24 broadcast 192.0.2.111 dev dummy0" 2024 2025 run_cmd "$IP neigh add 203.0.113.111 nud failed dev dummy0" 2026 run_cmd "$IP neigh add 203.0.113.255 nud failed dev dummy0" 2027 2028 run_cmd "$IP neigh get 203.0.113.111 dev dummy0" 2029 run_cmd "$IP neigh get 203.0.113.255 dev dummy0" 2030 2031 run_cmd "$IP address add 203.0.113.1/24 broadcast 203.0.113.111 dev dummy0" 2032 set +e 2033 2034 run_cmd "$IP neigh get 192.0.2.111 dev dummy0" 2035 log_test $? 0 "Resolved neighbour for broadcast address" 2036 2037 run_cmd "$IP neigh get 192.0.2.255 dev dummy0" 2038 log_test $? 0 "Resolved neighbour for network broadcast address" 2039 2040 run_cmd "$IP neigh get 203.0.113.111 dev dummy0" 2041 log_test $? 2 "Unresolved neighbour for broadcast address" 2042 2043 run_cmd "$IP neigh get 203.0.113.255 dev dummy0" 2044 log_test $? 2 "Unresolved neighbour for network broadcast address" 2045 2046 cleanup 2047} 2048 2049################################################################################ 2050# usage 2051 2052usage() 2053{ 2054 cat <<EOF 2055usage: ${0##*/} OPTS 2056 2057 -t <test> Test(s) to run (default: all) 2058 (options: $TESTS) 2059 -p Pause on fail 2060 -P Pause after each test before cleanup 2061 -v verbose mode (show commands and output) 2062EOF 2063} 2064 2065################################################################################ 2066# main 2067 2068while getopts :t:pPhv o 2069do 2070 case $o in 2071 t) TESTS=$OPTARG;; 2072 p) PAUSE_ON_FAIL=yes;; 2073 P) PAUSE=yes;; 2074 v) VERBOSE=$(($VERBOSE + 1));; 2075 h) usage; exit 0;; 2076 *) usage; exit 1;; 2077 esac 2078done 2079 2080PEER_CMD="ip netns exec ${PEER_NS}" 2081 2082# make sure we don't pause twice 2083[ "${PAUSE}" = "yes" ] && PAUSE_ON_FAIL=no 2084 2085if [ "$(id -u)" -ne 0 ];then 2086 echo "SKIP: Need root privileges" 2087 exit $ksft_skip; 2088fi 2089 2090if [ ! -x "$(command -v ip)" ]; then 2091 echo "SKIP: Could not run test without ip tool" 2092 exit $ksft_skip 2093fi 2094 2095ip route help 2>&1 | grep -q fibmatch 2096if [ $? -ne 0 ]; then 2097 echo "SKIP: iproute2 too old, missing fibmatch" 2098 exit $ksft_skip 2099fi 2100 2101# start clean 2102cleanup &> /dev/null 2103 2104for t in $TESTS 2105do 2106 case $t in 2107 fib_unreg_test|unregister) fib_unreg_test;; 2108 fib_down_test|down) fib_down_test;; 2109 fib_carrier_test|carrier) fib_carrier_test;; 2110 fib_rp_filter_test|rp_filter) fib_rp_filter_test;; 2111 fib_nexthop_test|nexthop) fib_nexthop_test;; 2112 fib_suppress_test|suppress) fib_suppress_test;; 2113 ipv6_route_test|ipv6_rt) ipv6_route_test;; 2114 ipv4_route_test|ipv4_rt) ipv4_route_test;; 2115 ipv6_addr_metric) ipv6_addr_metric_test;; 2116 ipv4_addr_metric) ipv4_addr_metric_test;; 2117 ipv4_del_addr) ipv4_del_addr_test;; 2118 ipv6_route_metrics) ipv6_route_metrics_test;; 2119 ipv4_route_metrics) ipv4_route_metrics_test;; 2120 ipv4_route_v6_gw) ipv4_route_v6_gw_test;; 2121 ipv4_mangle) ipv4_mangle_test;; 2122 ipv6_mangle) ipv6_mangle_test;; 2123 ipv4_bcast_neigh) ipv4_bcast_neigh_test;; 2124 2125 help) echo "Test names: $TESTS"; exit 0;; 2126 esac 2127done 2128 2129if [ "$TESTS" != "none" ]; then 2130 printf "\nTests passed: %3d\n" ${nsuccess} 2131 printf "Tests failed: %3d\n" ${nfail} 2132fi 2133 2134exit $ret 2135