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_notify ipv4_notify 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 &> /dev/null 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 658fib6_notify_test() 659{ 660 setup 661 662 echo 663 echo "Fib6 info length calculation in route notify test" 664 set -e 665 666 for i in 10 20 30 40 50 60 70; 667 do 668 $IP link add dummy_$i type dummy 669 $IP link set dev dummy_$i up 670 $IP -6 address add 2001:$i::1/64 dev dummy_$i 671 done 672 673 $NS_EXEC ip monitor route &> errors.txt & 674 sleep 2 675 676 $IP -6 route add 2001::/64 \ 677 nexthop via 2001:10::2 dev dummy_10 \ 678 nexthop encap ip6 dst 2002::20 via 2001:20::2 dev dummy_20 \ 679 nexthop encap ip6 dst 2002::30 via 2001:30::2 dev dummy_30 \ 680 nexthop encap ip6 dst 2002::40 via 2001:40::2 dev dummy_40 \ 681 nexthop encap ip6 dst 2002::50 via 2001:50::2 dev dummy_50 \ 682 nexthop encap ip6 dst 2002::60 via 2001:60::2 dev dummy_60 \ 683 nexthop encap ip6 dst 2002::70 via 2001:70::2 dev dummy_70 684 685 set +e 686 687 err=`cat errors.txt |grep "Message too long"` 688 if [ -z "$err" ];then 689 ret=0 690 else 691 ret=1 692 fi 693 694 log_test $ret 0 "ipv6 route add notify" 695 696 { kill %% && wait %%; } 2>/dev/null 697 698 #rm errors.txt 699 700 cleanup &> /dev/null 701} 702 703 704fib_notify_test() 705{ 706 setup 707 708 echo 709 echo "Fib4 info length calculation in route notify test" 710 711 set -e 712 713 for i in 10 20 30 40 50 60 70; 714 do 715 $IP link add dummy_$i type dummy 716 $IP link set dev dummy_$i up 717 $IP address add 20.20.$i.2/24 dev dummy_$i 718 done 719 720 $NS_EXEC ip monitor route &> errors.txt & 721 sleep 2 722 723 $IP route add 10.0.0.0/24 \ 724 nexthop via 20.20.10.1 dev dummy_10 \ 725 nexthop encap ip dst 192.168.10.20 via 20.20.20.1 dev dummy_20 \ 726 nexthop encap ip dst 192.168.10.30 via 20.20.30.1 dev dummy_30 \ 727 nexthop encap ip dst 192.168.10.40 via 20.20.40.1 dev dummy_40 \ 728 nexthop encap ip dst 192.168.10.50 via 20.20.50.1 dev dummy_50 \ 729 nexthop encap ip dst 192.168.10.60 via 20.20.60.1 dev dummy_60 \ 730 nexthop encap ip dst 192.168.10.70 via 20.20.70.1 dev dummy_70 731 732 set +e 733 734 err=`cat errors.txt |grep "Message too long"` 735 if [ -z "$err" ];then 736 ret=0 737 else 738 ret=1 739 fi 740 741 log_test $ret 0 "ipv4 route add notify" 742 743 { kill %% && wait %%; } 2>/dev/null 744 745 rm errors.txt 746 747 cleanup &> /dev/null 748} 749 750fib_suppress_test() 751{ 752 echo 753 echo "FIB rule with suppress_prefixlength" 754 setup 755 756 $IP link add dummy1 type dummy 757 $IP link set dummy1 up 758 $IP -6 route add default dev dummy1 759 $IP -6 rule add table main suppress_prefixlength 0 760 ping -f -c 1000 -W 1 1234::1 >/dev/null 2>&1 761 $IP -6 rule del table main suppress_prefixlength 0 762 $IP link del dummy1 763 764 # If we got here without crashing, we're good. 765 log_test 0 0 "FIB rule suppress test" 766 767 cleanup 768} 769 770################################################################################ 771# Tests on route add and replace 772 773run_cmd() 774{ 775 local cmd="$1" 776 local out 777 local stderr="2>/dev/null" 778 779 if [ "$VERBOSE" = "1" ]; then 780 printf " COMMAND: $cmd\n" 781 stderr= 782 fi 783 784 out=$(eval $cmd $stderr) 785 rc=$? 786 if [ "$VERBOSE" = "1" -a -n "$out" ]; then 787 echo " $out" 788 fi 789 790 [ "$VERBOSE" = "1" ] && echo 791 792 return $rc 793} 794 795check_expected() 796{ 797 local out="$1" 798 local expected="$2" 799 local rc=0 800 801 [ "${out}" = "${expected}" ] && return 0 802 803 if [ -z "${out}" ]; then 804 if [ "$VERBOSE" = "1" ]; then 805 printf "\nNo route entry found\n" 806 printf "Expected:\n" 807 printf " ${expected}\n" 808 fi 809 return 1 810 fi 811 812 # tricky way to convert output to 1-line without ip's 813 # messy '\'; this drops all extra white space 814 out=$(echo ${out}) 815 if [ "${out}" != "${expected}" ]; then 816 rc=1 817 if [ "${VERBOSE}" = "1" ]; then 818 printf " Unexpected route entry. Have:\n" 819 printf " ${out}\n" 820 printf " Expected:\n" 821 printf " ${expected}\n\n" 822 fi 823 fi 824 825 return $rc 826} 827 828# add route for a prefix, flushing any existing routes first 829# expected to be the first step of a test 830add_route6() 831{ 832 local pfx="$1" 833 local nh="$2" 834 local out 835 836 if [ "$VERBOSE" = "1" ]; then 837 echo 838 echo " ##################################################" 839 echo 840 fi 841 842 run_cmd "$IP -6 ro flush ${pfx}" 843 [ $? -ne 0 ] && exit 1 844 845 out=$($IP -6 ro ls match ${pfx}) 846 if [ -n "$out" ]; then 847 echo "Failed to flush routes for prefix used for tests." 848 exit 1 849 fi 850 851 run_cmd "$IP -6 ro add ${pfx} ${nh}" 852 if [ $? -ne 0 ]; then 853 echo "Failed to add initial route for test." 854 exit 1 855 fi 856} 857 858# add initial route - used in replace route tests 859add_initial_route6() 860{ 861 add_route6 "2001:db8:104::/64" "$1" 862} 863 864check_route6() 865{ 866 local pfx 867 local expected="$1" 868 local out 869 local rc=0 870 871 set -- $expected 872 pfx=$1 873 874 out=$($IP -6 ro ls match ${pfx} | sed -e 's/ pref medium//') 875 check_expected "${out}" "${expected}" 876} 877 878route_cleanup() 879{ 880 $IP li del red 2>/dev/null 881 $IP li del dummy1 2>/dev/null 882 $IP li del veth1 2>/dev/null 883 $IP li del veth3 2>/dev/null 884 885 cleanup &> /dev/null 886} 887 888route_setup() 889{ 890 route_cleanup 891 setup 892 893 [ "${VERBOSE}" = "1" ] && set -x 894 set -e 895 896 ip netns add ns2 897 ip netns set ns2 auto 898 ip -netns ns2 link set dev lo up 899 ip netns exec ns2 sysctl -qw net.ipv4.ip_forward=1 900 ip netns exec ns2 sysctl -qw net.ipv6.conf.all.forwarding=1 901 902 $IP li add veth1 type veth peer name veth2 903 $IP li add veth3 type veth peer name veth4 904 905 $IP li set veth1 up 906 $IP li set veth3 up 907 $IP li set veth2 netns ns2 up 908 $IP li set veth4 netns ns2 up 909 ip -netns ns2 li add dummy1 type dummy 910 ip -netns ns2 li set dummy1 up 911 912 $IP -6 addr add 2001:db8:101::1/64 dev veth1 nodad 913 $IP -6 addr add 2001:db8:103::1/64 dev veth3 nodad 914 $IP addr add 172.16.101.1/24 dev veth1 915 $IP addr add 172.16.103.1/24 dev veth3 916 917 ip -netns ns2 -6 addr add 2001:db8:101::2/64 dev veth2 nodad 918 ip -netns ns2 -6 addr add 2001:db8:103::2/64 dev veth4 nodad 919 ip -netns ns2 -6 addr add 2001:db8:104::1/64 dev dummy1 nodad 920 921 ip -netns ns2 addr add 172.16.101.2/24 dev veth2 922 ip -netns ns2 addr add 172.16.103.2/24 dev veth4 923 ip -netns ns2 addr add 172.16.104.1/24 dev dummy1 924 925 set +e 926} 927 928# assumption is that basic add of a single path route works 929# otherwise just adding an address on an interface is broken 930ipv6_rt_add() 931{ 932 local rc 933 934 echo 935 echo "IPv6 route add / append tests" 936 937 # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL 938 add_route6 "2001:db8:104::/64" "via 2001:db8:101::2" 939 run_cmd "$IP -6 ro add 2001:db8:104::/64 via 2001:db8:103::2" 940 log_test $? 2 "Attempt to add duplicate route - gw" 941 942 # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL 943 add_route6 "2001:db8:104::/64" "via 2001:db8:101::2" 944 run_cmd "$IP -6 ro add 2001:db8:104::/64 dev veth3" 945 log_test $? 2 "Attempt to add duplicate route - dev only" 946 947 # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL 948 add_route6 "2001:db8:104::/64" "via 2001:db8:101::2" 949 run_cmd "$IP -6 ro add unreachable 2001:db8:104::/64" 950 log_test $? 2 "Attempt to add duplicate route - reject route" 951 952 # route append with same prefix adds a new route 953 # - iproute2 sets NLM_F_CREATE | NLM_F_APPEND 954 add_route6 "2001:db8:104::/64" "via 2001:db8:101::2" 955 run_cmd "$IP -6 ro append 2001:db8:104::/64 via 2001:db8:103::2" 956 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" 957 log_test $? 0 "Append nexthop to existing route - gw" 958 959 # insert mpath directly 960 add_route6 "2001:db8:104::/64" "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2" 961 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" 962 log_test $? 0 "Add multipath route" 963 964 add_route6 "2001:db8:104::/64" "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2" 965 run_cmd "$IP -6 ro add 2001:db8:104::/64 nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2" 966 log_test $? 2 "Attempt to add duplicate multipath route" 967 968 # insert of a second route without append but different metric 969 add_route6 "2001:db8:104::/64" "via 2001:db8:101::2" 970 run_cmd "$IP -6 ro add 2001:db8:104::/64 via 2001:db8:103::2 metric 512" 971 rc=$? 972 if [ $rc -eq 0 ]; then 973 run_cmd "$IP -6 ro add 2001:db8:104::/64 via 2001:db8:103::3 metric 256" 974 rc=$? 975 fi 976 log_test $rc 0 "Route add with different metrics" 977 978 run_cmd "$IP -6 ro del 2001:db8:104::/64 metric 512" 979 rc=$? 980 if [ $rc -eq 0 ]; then 981 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" 982 rc=$? 983 fi 984 log_test $rc 0 "Route delete with metric" 985} 986 987ipv6_rt_replace_single() 988{ 989 # single path with single path 990 # 991 add_initial_route6 "via 2001:db8:101::2" 992 run_cmd "$IP -6 ro replace 2001:db8:104::/64 via 2001:db8:103::2" 993 check_route6 "2001:db8:104::/64 via 2001:db8:103::2 dev veth3 metric 1024" 994 log_test $? 0 "Single path with single path" 995 996 # single path with multipath 997 # 998 add_initial_route6 "nexthop via 2001:db8:101::2" 999 run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:101::3 nexthop via 2001:db8:103::2" 1000 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" 1001 log_test $? 0 "Single path with multipath" 1002 1003 # single path with single path using MULTIPATH attribute 1004 # 1005 add_initial_route6 "via 2001:db8:101::2" 1006 run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:103::2" 1007 check_route6 "2001:db8:104::/64 via 2001:db8:103::2 dev veth3 metric 1024" 1008 log_test $? 0 "Single path with single path via multipath attribute" 1009 1010 # route replace fails - invalid nexthop 1011 add_initial_route6 "via 2001:db8:101::2" 1012 run_cmd "$IP -6 ro replace 2001:db8:104::/64 via 2001:db8:104::2" 1013 if [ $? -eq 0 ]; then 1014 # previous command is expected to fail so if it returns 0 1015 # that means the test failed. 1016 log_test 0 1 "Invalid nexthop" 1017 else 1018 check_route6 "2001:db8:104::/64 via 2001:db8:101::2 dev veth1 metric 1024" 1019 log_test $? 0 "Invalid nexthop" 1020 fi 1021 1022 # replace non-existent route 1023 # - note use of change versus replace since ip adds NLM_F_CREATE 1024 # for replace 1025 add_initial_route6 "via 2001:db8:101::2" 1026 run_cmd "$IP -6 ro change 2001:db8:105::/64 via 2001:db8:101::2" 1027 log_test $? 2 "Single path - replace of non-existent route" 1028} 1029 1030ipv6_rt_replace_mpath() 1031{ 1032 # multipath with multipath 1033 add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2" 1034 run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:101::3 nexthop via 2001:db8:103::3" 1035 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" 1036 log_test $? 0 "Multipath with multipath" 1037 1038 # multipath with single 1039 add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2" 1040 run_cmd "$IP -6 ro replace 2001:db8:104::/64 via 2001:db8:101::3" 1041 check_route6 "2001:db8:104::/64 via 2001:db8:101::3 dev veth1 metric 1024" 1042 log_test $? 0 "Multipath with single path" 1043 1044 # multipath with single 1045 add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2" 1046 run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:101::3" 1047 check_route6 "2001:db8:104::/64 via 2001:db8:101::3 dev veth1 metric 1024" 1048 log_test $? 0 "Multipath with single path via multipath attribute" 1049 1050 # multipath with dev-only 1051 add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2" 1052 run_cmd "$IP -6 ro replace 2001:db8:104::/64 dev veth1" 1053 check_route6 "2001:db8:104::/64 dev veth1 metric 1024" 1054 log_test $? 0 "Multipath with dev-only" 1055 1056 # route replace fails - invalid nexthop 1 1057 add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2" 1058 run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:111::3 nexthop via 2001:db8:103::3" 1059 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" 1060 log_test $? 0 "Multipath - invalid first nexthop" 1061 1062 # route replace fails - invalid nexthop 2 1063 add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2" 1064 run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:101::3 nexthop via 2001:db8:113::3" 1065 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" 1066 log_test $? 0 "Multipath - invalid second nexthop" 1067 1068 # multipath non-existent route 1069 add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2" 1070 run_cmd "$IP -6 ro change 2001:db8:105::/64 nexthop via 2001:db8:101::3 nexthop via 2001:db8:103::3" 1071 log_test $? 2 "Multipath - replace of non-existent route" 1072} 1073 1074ipv6_rt_replace() 1075{ 1076 echo 1077 echo "IPv6 route replace tests" 1078 1079 ipv6_rt_replace_single 1080 ipv6_rt_replace_mpath 1081} 1082 1083ipv6_rt_dsfield() 1084{ 1085 echo 1086 echo "IPv6 route with dsfield tests" 1087 1088 run_cmd "$IP -6 route flush 2001:db8:102::/64" 1089 1090 # IPv6 doesn't support routing based on dsfield 1091 run_cmd "$IP -6 route add 2001:db8:102::/64 dsfield 0x04 via 2001:db8:101::2" 1092 log_test $? 2 "Reject route with dsfield" 1093} 1094 1095ipv6_route_test() 1096{ 1097 route_setup 1098 1099 ipv6_rt_add 1100 ipv6_rt_replace 1101 ipv6_rt_dsfield 1102 1103 route_cleanup 1104} 1105 1106ip_addr_metric_check() 1107{ 1108 ip addr help 2>&1 | grep -q metric 1109 if [ $? -ne 0 ]; then 1110 echo "iproute2 command does not support metric for addresses. Skipping test" 1111 return 1 1112 fi 1113 1114 return 0 1115} 1116 1117ipv6_addr_metric_test() 1118{ 1119 local rc 1120 1121 echo 1122 echo "IPv6 prefix route tests" 1123 1124 ip_addr_metric_check || return 1 1125 1126 setup 1127 1128 set -e 1129 $IP li add dummy1 type dummy 1130 $IP li add dummy2 type dummy 1131 $IP li set dummy1 up 1132 $IP li set dummy2 up 1133 1134 # default entry is metric 256 1135 run_cmd "$IP -6 addr add dev dummy1 2001:db8:104::1/64" 1136 run_cmd "$IP -6 addr add dev dummy2 2001:db8:104::2/64" 1137 set +e 1138 1139 check_route6 "2001:db8:104::/64 dev dummy1 proto kernel metric 256 2001:db8:104::/64 dev dummy2 proto kernel metric 256" 1140 log_test $? 0 "Default metric" 1141 1142 set -e 1143 run_cmd "$IP -6 addr flush dev dummy1" 1144 run_cmd "$IP -6 addr add dev dummy1 2001:db8:104::1/64 metric 257" 1145 set +e 1146 1147 check_route6 "2001:db8:104::/64 dev dummy2 proto kernel metric 256 2001:db8:104::/64 dev dummy1 proto kernel metric 257" 1148 log_test $? 0 "User specified metric on first device" 1149 1150 set -e 1151 run_cmd "$IP -6 addr flush dev dummy2" 1152 run_cmd "$IP -6 addr add dev dummy2 2001:db8:104::2/64 metric 258" 1153 set +e 1154 1155 check_route6 "2001:db8:104::/64 dev dummy1 proto kernel metric 257 2001:db8:104::/64 dev dummy2 proto kernel metric 258" 1156 log_test $? 0 "User specified metric on second device" 1157 1158 run_cmd "$IP -6 addr del dev dummy1 2001:db8:104::1/64 metric 257" 1159 rc=$? 1160 if [ $rc -eq 0 ]; then 1161 check_route6 "2001:db8:104::/64 dev dummy2 proto kernel metric 258" 1162 rc=$? 1163 fi 1164 log_test $rc 0 "Delete of address on first device" 1165 1166 run_cmd "$IP -6 addr change dev dummy2 2001:db8:104::2/64 metric 259" 1167 rc=$? 1168 if [ $rc -eq 0 ]; then 1169 check_route6 "2001:db8:104::/64 dev dummy2 proto kernel metric 259" 1170 rc=$? 1171 fi 1172 log_test $rc 0 "Modify metric of address" 1173 1174 # verify prefix route removed on down 1175 run_cmd "ip netns exec ns1 sysctl -qw net.ipv6.conf.all.keep_addr_on_down=1" 1176 run_cmd "$IP li set dev dummy2 down" 1177 rc=$? 1178 if [ $rc -eq 0 ]; then 1179 out=$($IP -6 ro ls match 2001:db8:104::/64) 1180 check_expected "${out}" "" 1181 rc=$? 1182 fi 1183 log_test $rc 0 "Prefix route removed on link down" 1184 1185 # verify prefix route re-inserted with assigned metric 1186 run_cmd "$IP li set dev dummy2 up" 1187 rc=$? 1188 if [ $rc -eq 0 ]; then 1189 check_route6 "2001:db8:104::/64 dev dummy2 proto kernel metric 259" 1190 rc=$? 1191 fi 1192 log_test $rc 0 "Prefix route with metric on link up" 1193 1194 # verify peer metric added correctly 1195 set -e 1196 run_cmd "$IP -6 addr flush dev dummy2" 1197 run_cmd "$IP -6 addr add dev dummy2 2001:db8:104::1 peer 2001:db8:104::2 metric 260" 1198 set +e 1199 1200 check_route6 "2001:db8:104::1 dev dummy2 proto kernel metric 260" 1201 log_test $? 0 "Set metric with peer route on local side" 1202 check_route6 "2001:db8:104::2 dev dummy2 proto kernel metric 260" 1203 log_test $? 0 "Set metric with peer route on peer side" 1204 1205 set -e 1206 run_cmd "$IP -6 addr change dev dummy2 2001:db8:104::1 peer 2001:db8:104::3 metric 261" 1207 set +e 1208 1209 check_route6 "2001:db8:104::1 dev dummy2 proto kernel metric 261" 1210 log_test $? 0 "Modify metric and peer address on local side" 1211 check_route6 "2001:db8:104::3 dev dummy2 proto kernel metric 261" 1212 log_test $? 0 "Modify metric and peer address on peer side" 1213 1214 $IP li del dummy1 1215 $IP li del dummy2 1216 cleanup 1217} 1218 1219ipv6_route_metrics_test() 1220{ 1221 local rc 1222 1223 echo 1224 echo "IPv6 routes with metrics" 1225 1226 route_setup 1227 1228 # 1229 # single path with metrics 1230 # 1231 run_cmd "$IP -6 ro add 2001:db8:111::/64 via 2001:db8:101::2 mtu 1400" 1232 rc=$? 1233 if [ $rc -eq 0 ]; then 1234 check_route6 "2001:db8:111::/64 via 2001:db8:101::2 dev veth1 metric 1024 mtu 1400" 1235 rc=$? 1236 fi 1237 log_test $rc 0 "Single path route with mtu metric" 1238 1239 1240 # 1241 # multipath via separate routes with metrics 1242 # 1243 run_cmd "$IP -6 ro add 2001:db8:112::/64 via 2001:db8:101::2 mtu 1400" 1244 run_cmd "$IP -6 ro append 2001:db8:112::/64 via 2001:db8:103::2" 1245 rc=$? 1246 if [ $rc -eq 0 ]; then 1247 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" 1248 rc=$? 1249 fi 1250 log_test $rc 0 "Multipath route via 2 single routes with mtu metric on first" 1251 1252 # second route is coalesced to first to make a multipath route. 1253 # MTU of the second path is hidden from display! 1254 run_cmd "$IP -6 ro add 2001:db8:113::/64 via 2001:db8:101::2" 1255 run_cmd "$IP -6 ro append 2001:db8:113::/64 via 2001:db8:103::2 mtu 1400" 1256 rc=$? 1257 if [ $rc -eq 0 ]; then 1258 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" 1259 rc=$? 1260 fi 1261 log_test $rc 0 "Multipath route via 2 single routes with mtu metric on 2nd" 1262 1263 run_cmd "$IP -6 ro del 2001:db8:113::/64 via 2001:db8:101::2" 1264 if [ $? -eq 0 ]; then 1265 check_route6 "2001:db8:113::/64 via 2001:db8:103::2 dev veth3 metric 1024 mtu 1400" 1266 log_test $? 0 " MTU of second leg" 1267 fi 1268 1269 # 1270 # multipath with metrics 1271 # 1272 run_cmd "$IP -6 ro add 2001:db8:115::/64 mtu 1400 nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2" 1273 rc=$? 1274 if [ $rc -eq 0 ]; then 1275 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" 1276 rc=$? 1277 fi 1278 log_test $rc 0 "Multipath route with mtu metric" 1279 1280 $IP -6 ro add 2001:db8:104::/64 via 2001:db8:101::2 mtu 1300 1281 run_cmd "ip netns exec ns1 ${ping6} -w1 -c1 -s 1500 2001:db8:104::1" 1282 log_test $? 0 "Using route with mtu metric" 1283 1284 run_cmd "$IP -6 ro add 2001:db8:114::/64 via 2001:db8:101::2 congctl lock foo" 1285 log_test $? 2 "Invalid metric (fails metric_convert)" 1286 1287 route_cleanup 1288} 1289 1290# add route for a prefix, flushing any existing routes first 1291# expected to be the first step of a test 1292add_route() 1293{ 1294 local pfx="$1" 1295 local nh="$2" 1296 local out 1297 1298 if [ "$VERBOSE" = "1" ]; then 1299 echo 1300 echo " ##################################################" 1301 echo 1302 fi 1303 1304 run_cmd "$IP ro flush ${pfx}" 1305 [ $? -ne 0 ] && exit 1 1306 1307 out=$($IP ro ls match ${pfx}) 1308 if [ -n "$out" ]; then 1309 echo "Failed to flush routes for prefix used for tests." 1310 exit 1 1311 fi 1312 1313 run_cmd "$IP ro add ${pfx} ${nh}" 1314 if [ $? -ne 0 ]; then 1315 echo "Failed to add initial route for test." 1316 exit 1 1317 fi 1318} 1319 1320# add initial route - used in replace route tests 1321add_initial_route() 1322{ 1323 add_route "172.16.104.0/24" "$1" 1324} 1325 1326check_route() 1327{ 1328 local pfx 1329 local expected="$1" 1330 local out 1331 1332 set -- $expected 1333 pfx=$1 1334 [ "${pfx}" = "unreachable" ] && pfx=$2 1335 1336 out=$($IP ro ls match ${pfx}) 1337 check_expected "${out}" "${expected}" 1338} 1339 1340# assumption is that basic add of a single path route works 1341# otherwise just adding an address on an interface is broken 1342ipv4_rt_add() 1343{ 1344 local rc 1345 1346 echo 1347 echo "IPv4 route add / append tests" 1348 1349 # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL 1350 add_route "172.16.104.0/24" "via 172.16.101.2" 1351 run_cmd "$IP ro add 172.16.104.0/24 via 172.16.103.2" 1352 log_test $? 2 "Attempt to add duplicate route - gw" 1353 1354 # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL 1355 add_route "172.16.104.0/24" "via 172.16.101.2" 1356 run_cmd "$IP ro add 172.16.104.0/24 dev veth3" 1357 log_test $? 2 "Attempt to add duplicate route - dev only" 1358 1359 # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL 1360 add_route "172.16.104.0/24" "via 172.16.101.2" 1361 run_cmd "$IP ro add unreachable 172.16.104.0/24" 1362 log_test $? 2 "Attempt to add duplicate route - reject route" 1363 1364 # iproute2 prepend only sets NLM_F_CREATE 1365 # - adds a new route; does NOT convert existing route to ECMP 1366 add_route "172.16.104.0/24" "via 172.16.101.2" 1367 run_cmd "$IP ro prepend 172.16.104.0/24 via 172.16.103.2" 1368 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" 1369 log_test $? 0 "Add new nexthop for existing prefix" 1370 1371 # route append with same prefix adds a new route 1372 # - iproute2 sets NLM_F_CREATE | NLM_F_APPEND 1373 add_route "172.16.104.0/24" "via 172.16.101.2" 1374 run_cmd "$IP ro append 172.16.104.0/24 via 172.16.103.2" 1375 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" 1376 log_test $? 0 "Append nexthop to existing route - gw" 1377 1378 add_route "172.16.104.0/24" "via 172.16.101.2" 1379 run_cmd "$IP ro append 172.16.104.0/24 dev veth3" 1380 check_route "172.16.104.0/24 via 172.16.101.2 dev veth1 172.16.104.0/24 dev veth3 scope link" 1381 log_test $? 0 "Append nexthop to existing route - dev only" 1382 1383 add_route "172.16.104.0/24" "via 172.16.101.2" 1384 run_cmd "$IP ro append unreachable 172.16.104.0/24" 1385 check_route "172.16.104.0/24 via 172.16.101.2 dev veth1 unreachable 172.16.104.0/24" 1386 log_test $? 0 "Append nexthop to existing route - reject route" 1387 1388 run_cmd "$IP ro flush 172.16.104.0/24" 1389 run_cmd "$IP ro add unreachable 172.16.104.0/24" 1390 run_cmd "$IP ro append 172.16.104.0/24 via 172.16.103.2" 1391 check_route "unreachable 172.16.104.0/24 172.16.104.0/24 via 172.16.103.2 dev veth3" 1392 log_test $? 0 "Append nexthop to existing reject route - gw" 1393 1394 run_cmd "$IP ro flush 172.16.104.0/24" 1395 run_cmd "$IP ro add unreachable 172.16.104.0/24" 1396 run_cmd "$IP ro append 172.16.104.0/24 dev veth3" 1397 check_route "unreachable 172.16.104.0/24 172.16.104.0/24 dev veth3 scope link" 1398 log_test $? 0 "Append nexthop to existing reject route - dev only" 1399 1400 # insert mpath directly 1401 add_route "172.16.104.0/24" "nexthop via 172.16.101.2 nexthop via 172.16.103.2" 1402 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" 1403 log_test $? 0 "add multipath route" 1404 1405 add_route "172.16.104.0/24" "nexthop via 172.16.101.2 nexthop via 172.16.103.2" 1406 run_cmd "$IP ro add 172.16.104.0/24 nexthop via 172.16.101.2 nexthop via 172.16.103.2" 1407 log_test $? 2 "Attempt to add duplicate multipath route" 1408 1409 # insert of a second route without append but different metric 1410 add_route "172.16.104.0/24" "via 172.16.101.2" 1411 run_cmd "$IP ro add 172.16.104.0/24 via 172.16.103.2 metric 512" 1412 rc=$? 1413 if [ $rc -eq 0 ]; then 1414 run_cmd "$IP ro add 172.16.104.0/24 via 172.16.103.3 metric 256" 1415 rc=$? 1416 fi 1417 log_test $rc 0 "Route add with different metrics" 1418 1419 run_cmd "$IP ro del 172.16.104.0/24 metric 512" 1420 rc=$? 1421 if [ $rc -eq 0 ]; then 1422 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" 1423 rc=$? 1424 fi 1425 log_test $rc 0 "Route delete with metric" 1426} 1427 1428ipv4_rt_replace_single() 1429{ 1430 # single path with single path 1431 # 1432 add_initial_route "via 172.16.101.2" 1433 run_cmd "$IP ro replace 172.16.104.0/24 via 172.16.103.2" 1434 check_route "172.16.104.0/24 via 172.16.103.2 dev veth3" 1435 log_test $? 0 "Single path with single path" 1436 1437 # single path with multipath 1438 # 1439 add_initial_route "nexthop via 172.16.101.2" 1440 run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.101.3 nexthop via 172.16.103.2" 1441 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" 1442 log_test $? 0 "Single path with multipath" 1443 1444 # single path with reject 1445 # 1446 add_initial_route "nexthop via 172.16.101.2" 1447 run_cmd "$IP ro replace unreachable 172.16.104.0/24" 1448 check_route "unreachable 172.16.104.0/24" 1449 log_test $? 0 "Single path with reject route" 1450 1451 # single path with single path using MULTIPATH attribute 1452 # 1453 add_initial_route "via 172.16.101.2" 1454 run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.103.2" 1455 check_route "172.16.104.0/24 via 172.16.103.2 dev veth3" 1456 log_test $? 0 "Single path with single path via multipath attribute" 1457 1458 # route replace fails - invalid nexthop 1459 add_initial_route "via 172.16.101.2" 1460 run_cmd "$IP ro replace 172.16.104.0/24 via 2001:db8:104::2" 1461 if [ $? -eq 0 ]; then 1462 # previous command is expected to fail so if it returns 0 1463 # that means the test failed. 1464 log_test 0 1 "Invalid nexthop" 1465 else 1466 check_route "172.16.104.0/24 via 172.16.101.2 dev veth1" 1467 log_test $? 0 "Invalid nexthop" 1468 fi 1469 1470 # replace non-existent route 1471 # - note use of change versus replace since ip adds NLM_F_CREATE 1472 # for replace 1473 add_initial_route "via 172.16.101.2" 1474 run_cmd "$IP ro change 172.16.105.0/24 via 172.16.101.2" 1475 log_test $? 2 "Single path - replace of non-existent route" 1476} 1477 1478ipv4_rt_replace_mpath() 1479{ 1480 # multipath with multipath 1481 add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2" 1482 run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.101.3 nexthop via 172.16.103.3" 1483 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" 1484 log_test $? 0 "Multipath with multipath" 1485 1486 # multipath with single 1487 add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2" 1488 run_cmd "$IP ro replace 172.16.104.0/24 via 172.16.101.3" 1489 check_route "172.16.104.0/24 via 172.16.101.3 dev veth1" 1490 log_test $? 0 "Multipath with single path" 1491 1492 # multipath with single 1493 add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2" 1494 run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.101.3" 1495 check_route "172.16.104.0/24 via 172.16.101.3 dev veth1" 1496 log_test $? 0 "Multipath with single path via multipath attribute" 1497 1498 # multipath with reject 1499 add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2" 1500 run_cmd "$IP ro replace unreachable 172.16.104.0/24" 1501 check_route "unreachable 172.16.104.0/24" 1502 log_test $? 0 "Multipath with reject route" 1503 1504 # route replace fails - invalid nexthop 1 1505 add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2" 1506 run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.111.3 nexthop via 172.16.103.3" 1507 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" 1508 log_test $? 0 "Multipath - invalid first nexthop" 1509 1510 # route replace fails - invalid nexthop 2 1511 add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2" 1512 run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.101.3 nexthop via 172.16.113.3" 1513 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" 1514 log_test $? 0 "Multipath - invalid second nexthop" 1515 1516 # multipath non-existent route 1517 add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2" 1518 run_cmd "$IP ro change 172.16.105.0/24 nexthop via 172.16.101.3 nexthop via 172.16.103.3" 1519 log_test $? 2 "Multipath - replace of non-existent route" 1520} 1521 1522ipv4_rt_replace() 1523{ 1524 echo 1525 echo "IPv4 route replace tests" 1526 1527 ipv4_rt_replace_single 1528 ipv4_rt_replace_mpath 1529} 1530 1531# checks that cached input route on VRF port is deleted 1532# when VRF is deleted 1533ipv4_local_rt_cache() 1534{ 1535 run_cmd "ip addr add 10.0.0.1/32 dev lo" 1536 run_cmd "ip netns add test-ns" 1537 run_cmd "ip link add veth-outside type veth peer name veth-inside" 1538 run_cmd "ip link add vrf-100 type vrf table 1100" 1539 run_cmd "ip link set veth-outside master vrf-100" 1540 run_cmd "ip link set veth-inside netns test-ns" 1541 run_cmd "ip link set veth-outside up" 1542 run_cmd "ip link set vrf-100 up" 1543 run_cmd "ip route add 10.1.1.1/32 dev veth-outside table 1100" 1544 run_cmd "ip netns exec test-ns ip link set veth-inside up" 1545 run_cmd "ip netns exec test-ns ip addr add 10.1.1.1/32 dev veth-inside" 1546 run_cmd "ip netns exec test-ns ip route add 10.0.0.1/32 dev veth-inside" 1547 run_cmd "ip netns exec test-ns ip route add default via 10.0.0.1" 1548 run_cmd "ip netns exec test-ns ping 10.0.0.1 -c 1 -i 1" 1549 run_cmd "ip link delete vrf-100" 1550 1551 # if we do not hang test is a success 1552 log_test $? 0 "Cached route removed from VRF port device" 1553} 1554 1555ipv4_rt_dsfield() 1556{ 1557 echo 1558 echo "IPv4 route with dsfield tests" 1559 1560 run_cmd "$IP route flush 172.16.102.0/24" 1561 1562 # New routes should reject dsfield options that interfere with ECN 1563 run_cmd "$IP route add 172.16.102.0/24 dsfield 0x01 via 172.16.101.2" 1564 log_test $? 2 "Reject route with dsfield 0x01" 1565 1566 run_cmd "$IP route add 172.16.102.0/24 dsfield 0x02 via 172.16.101.2" 1567 log_test $? 2 "Reject route with dsfield 0x02" 1568 1569 run_cmd "$IP route add 172.16.102.0/24 dsfield 0x03 via 172.16.101.2" 1570 log_test $? 2 "Reject route with dsfield 0x03" 1571 1572 # A generic route that doesn't take DSCP into account 1573 run_cmd "$IP route add 172.16.102.0/24 via 172.16.101.2" 1574 1575 # A more specific route for DSCP 0x10 1576 run_cmd "$IP route add 172.16.102.0/24 dsfield 0x10 via 172.16.103.2" 1577 1578 # DSCP 0x10 should match the specific route, no matter the ECN bits 1579 $IP route get fibmatch 172.16.102.1 dsfield 0x10 | \ 1580 grep -q "via 172.16.103.2" 1581 log_test $? 0 "IPv4 route with DSCP and ECN:Not-ECT" 1582 1583 $IP route get fibmatch 172.16.102.1 dsfield 0x11 | \ 1584 grep -q "via 172.16.103.2" 1585 log_test $? 0 "IPv4 route with DSCP and ECN:ECT(1)" 1586 1587 $IP route get fibmatch 172.16.102.1 dsfield 0x12 | \ 1588 grep -q "via 172.16.103.2" 1589 log_test $? 0 "IPv4 route with DSCP and ECN:ECT(0)" 1590 1591 $IP route get fibmatch 172.16.102.1 dsfield 0x13 | \ 1592 grep -q "via 172.16.103.2" 1593 log_test $? 0 "IPv4 route with DSCP and ECN:CE" 1594 1595 # Unknown DSCP should match the generic route, no matter the ECN bits 1596 $IP route get fibmatch 172.16.102.1 dsfield 0x14 | \ 1597 grep -q "via 172.16.101.2" 1598 log_test $? 0 "IPv4 route with unknown DSCP and ECN:Not-ECT" 1599 1600 $IP route get fibmatch 172.16.102.1 dsfield 0x15 | \ 1601 grep -q "via 172.16.101.2" 1602 log_test $? 0 "IPv4 route with unknown DSCP and ECN:ECT(1)" 1603 1604 $IP route get fibmatch 172.16.102.1 dsfield 0x16 | \ 1605 grep -q "via 172.16.101.2" 1606 log_test $? 0 "IPv4 route with unknown DSCP and ECN:ECT(0)" 1607 1608 $IP route get fibmatch 172.16.102.1 dsfield 0x17 | \ 1609 grep -q "via 172.16.101.2" 1610 log_test $? 0 "IPv4 route with unknown DSCP and ECN:CE" 1611 1612 # Null DSCP should match the generic route, no matter the ECN bits 1613 $IP route get fibmatch 172.16.102.1 dsfield 0x00 | \ 1614 grep -q "via 172.16.101.2" 1615 log_test $? 0 "IPv4 route with no DSCP and ECN:Not-ECT" 1616 1617 $IP route get fibmatch 172.16.102.1 dsfield 0x01 | \ 1618 grep -q "via 172.16.101.2" 1619 log_test $? 0 "IPv4 route with no DSCP and ECN:ECT(1)" 1620 1621 $IP route get fibmatch 172.16.102.1 dsfield 0x02 | \ 1622 grep -q "via 172.16.101.2" 1623 log_test $? 0 "IPv4 route with no DSCP and ECN:ECT(0)" 1624 1625 $IP route get fibmatch 172.16.102.1 dsfield 0x03 | \ 1626 grep -q "via 172.16.101.2" 1627 log_test $? 0 "IPv4 route with no DSCP and ECN:CE" 1628} 1629 1630ipv4_route_test() 1631{ 1632 route_setup 1633 1634 ipv4_rt_add 1635 ipv4_rt_replace 1636 ipv4_local_rt_cache 1637 ipv4_rt_dsfield 1638 1639 route_cleanup 1640} 1641 1642ipv4_addr_metric_test() 1643{ 1644 local rc 1645 1646 echo 1647 echo "IPv4 prefix route tests" 1648 1649 ip_addr_metric_check || return 1 1650 1651 setup 1652 1653 set -e 1654 $IP li add dummy1 type dummy 1655 $IP li add dummy2 type dummy 1656 $IP li set dummy1 up 1657 $IP li set dummy2 up 1658 1659 # default entry is metric 256 1660 run_cmd "$IP addr add dev dummy1 172.16.104.1/24" 1661 run_cmd "$IP addr add dev dummy2 172.16.104.2/24" 1662 set +e 1663 1664 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" 1665 log_test $? 0 "Default metric" 1666 1667 set -e 1668 run_cmd "$IP addr flush dev dummy1" 1669 run_cmd "$IP addr add dev dummy1 172.16.104.1/24 metric 257" 1670 set +e 1671 1672 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" 1673 log_test $? 0 "User specified metric on first device" 1674 1675 set -e 1676 run_cmd "$IP addr flush dev dummy2" 1677 run_cmd "$IP addr add dev dummy2 172.16.104.2/24 metric 258" 1678 set +e 1679 1680 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" 1681 log_test $? 0 "User specified metric on second device" 1682 1683 run_cmd "$IP addr del dev dummy1 172.16.104.1/24 metric 257" 1684 rc=$? 1685 if [ $rc -eq 0 ]; then 1686 check_route "172.16.104.0/24 dev dummy2 proto kernel scope link src 172.16.104.2 metric 258" 1687 rc=$? 1688 fi 1689 log_test $rc 0 "Delete of address on first device" 1690 1691 run_cmd "$IP addr change dev dummy2 172.16.104.2/24 metric 259" 1692 rc=$? 1693 if [ $rc -eq 0 ]; then 1694 check_route "172.16.104.0/24 dev dummy2 proto kernel scope link src 172.16.104.2 metric 259" 1695 rc=$? 1696 fi 1697 log_test $rc 0 "Modify metric of address" 1698 1699 # verify prefix route removed on down 1700 run_cmd "$IP li set dev dummy2 down" 1701 rc=$? 1702 if [ $rc -eq 0 ]; then 1703 out=$($IP ro ls match 172.16.104.0/24) 1704 check_expected "${out}" "" 1705 rc=$? 1706 fi 1707 log_test $rc 0 "Prefix route removed on link down" 1708 1709 # verify prefix route re-inserted with assigned metric 1710 run_cmd "$IP li set dev dummy2 up" 1711 rc=$? 1712 if [ $rc -eq 0 ]; then 1713 check_route "172.16.104.0/24 dev dummy2 proto kernel scope link src 172.16.104.2 metric 259" 1714 rc=$? 1715 fi 1716 log_test $rc 0 "Prefix route with metric on link up" 1717 1718 # explicitly check for metric changes on edge scenarios 1719 run_cmd "$IP addr flush dev dummy2" 1720 run_cmd "$IP addr add dev dummy2 172.16.104.0/24 metric 259" 1721 run_cmd "$IP addr change dev dummy2 172.16.104.0/24 metric 260" 1722 rc=$? 1723 if [ $rc -eq 0 ]; then 1724 check_route "172.16.104.0/24 dev dummy2 proto kernel scope link src 172.16.104.0 metric 260" 1725 rc=$? 1726 fi 1727 log_test $rc 0 "Modify metric of .0/24 address" 1728 1729 run_cmd "$IP addr flush dev dummy2" 1730 run_cmd "$IP addr add dev dummy2 172.16.104.1/32 peer 172.16.104.2 metric 260" 1731 rc=$? 1732 if [ $rc -eq 0 ]; then 1733 check_route "172.16.104.2 dev dummy2 proto kernel scope link src 172.16.104.1 metric 260" 1734 rc=$? 1735 fi 1736 log_test $rc 0 "Set metric of address with peer route" 1737 1738 run_cmd "$IP addr change dev dummy2 172.16.104.1/32 peer 172.16.104.3 metric 261" 1739 rc=$? 1740 if [ $rc -eq 0 ]; then 1741 check_route "172.16.104.3 dev dummy2 proto kernel scope link src 172.16.104.1 metric 261" 1742 rc=$? 1743 fi 1744 log_test $rc 0 "Modify metric and peer address for peer route" 1745 1746 $IP li del dummy1 1747 $IP li del dummy2 1748 cleanup 1749} 1750 1751ipv4_route_metrics_test() 1752{ 1753 local rc 1754 1755 echo 1756 echo "IPv4 route add / append tests" 1757 1758 route_setup 1759 1760 run_cmd "$IP ro add 172.16.111.0/24 via 172.16.101.2 mtu 1400" 1761 rc=$? 1762 if [ $rc -eq 0 ]; then 1763 check_route "172.16.111.0/24 via 172.16.101.2 dev veth1 mtu 1400" 1764 rc=$? 1765 fi 1766 log_test $rc 0 "Single path route with mtu metric" 1767 1768 1769 run_cmd "$IP ro add 172.16.112.0/24 mtu 1400 nexthop via 172.16.101.2 nexthop via 172.16.103.2" 1770 rc=$? 1771 if [ $rc -eq 0 ]; then 1772 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" 1773 rc=$? 1774 fi 1775 log_test $rc 0 "Multipath route with mtu metric" 1776 1777 $IP ro add 172.16.104.0/24 via 172.16.101.2 mtu 1300 1778 run_cmd "ip netns exec ns1 ping -w1 -c1 -s 1500 172.16.104.1" 1779 log_test $? 0 "Using route with mtu metric" 1780 1781 run_cmd "$IP ro add 172.16.111.0/24 via 172.16.101.2 congctl lock foo" 1782 log_test $? 2 "Invalid metric (fails metric_convert)" 1783 1784 route_cleanup 1785} 1786 1787ipv4_del_addr_test() 1788{ 1789 echo 1790 echo "IPv4 delete address route tests" 1791 1792 setup 1793 1794 set -e 1795 $IP li add dummy1 type dummy 1796 $IP li set dummy1 up 1797 $IP li add dummy2 type dummy 1798 $IP li set dummy2 up 1799 $IP li add red type vrf table 1111 1800 $IP li set red up 1801 $IP ro add vrf red unreachable default 1802 $IP li set dummy2 vrf red 1803 1804 $IP addr add dev dummy1 172.16.104.1/24 1805 $IP addr add dev dummy1 172.16.104.11/24 1806 $IP addr add dev dummy1 172.16.104.12/24 1807 $IP addr add dev dummy1 172.16.104.13/24 1808 $IP addr add dev dummy2 172.16.104.1/24 1809 $IP addr add dev dummy2 172.16.104.11/24 1810 $IP addr add dev dummy2 172.16.104.12/24 1811 $IP route add 172.16.105.0/24 via 172.16.104.2 src 172.16.104.11 1812 $IP route add 172.16.106.0/24 dev lo src 172.16.104.12 1813 $IP route add table 0 172.16.107.0/24 via 172.16.104.2 src 172.16.104.13 1814 $IP route add vrf red 172.16.105.0/24 via 172.16.104.2 src 172.16.104.11 1815 $IP route add vrf red 172.16.106.0/24 dev lo src 172.16.104.12 1816 set +e 1817 1818 # removing address from device in vrf should only remove route from vrf table 1819 echo " Regular FIB info" 1820 1821 $IP addr del dev dummy2 172.16.104.11/24 1822 $IP ro ls vrf red | grep -q 172.16.105.0/24 1823 log_test $? 1 "Route removed from VRF when source address deleted" 1824 1825 $IP ro ls | grep -q 172.16.105.0/24 1826 log_test $? 0 "Route in default VRF not removed" 1827 1828 $IP addr add dev dummy2 172.16.104.11/24 1829 $IP route add vrf red 172.16.105.0/24 via 172.16.104.2 src 172.16.104.11 1830 1831 $IP addr del dev dummy1 172.16.104.11/24 1832 $IP ro ls | grep -q 172.16.105.0/24 1833 log_test $? 1 "Route removed in default VRF when source address deleted" 1834 1835 $IP ro ls vrf red | grep -q 172.16.105.0/24 1836 log_test $? 0 "Route in VRF is not removed by address delete" 1837 1838 # removing address from device in vrf should only remove route from vrf 1839 # table even when the associated fib info only differs in table ID 1840 echo " Identical FIB info with different table ID" 1841 1842 $IP addr del dev dummy2 172.16.104.12/24 1843 $IP ro ls vrf red | grep -q 172.16.106.0/24 1844 log_test $? 1 "Route removed from VRF when source address deleted" 1845 1846 $IP ro ls | grep -q 172.16.106.0/24 1847 log_test $? 0 "Route in default VRF not removed" 1848 1849 $IP addr add dev dummy2 172.16.104.12/24 1850 $IP route add vrf red 172.16.106.0/24 dev lo src 172.16.104.12 1851 1852 $IP addr del dev dummy1 172.16.104.12/24 1853 $IP ro ls | grep -q 172.16.106.0/24 1854 log_test $? 1 "Route removed in default VRF when source address deleted" 1855 1856 $IP ro ls vrf red | grep -q 172.16.106.0/24 1857 log_test $? 0 "Route in VRF is not removed by address delete" 1858 1859 # removing address from device in default vrf should remove route from 1860 # the default vrf even when route was inserted with a table ID of 0. 1861 echo " Table ID 0" 1862 1863 $IP addr del dev dummy1 172.16.104.13/24 1864 $IP ro ls | grep -q 172.16.107.0/24 1865 log_test $? 1 "Route removed in default VRF when source address deleted" 1866 1867 $IP li del dummy1 1868 $IP li del dummy2 1869 cleanup 1870} 1871 1872 1873ipv4_route_v6_gw_test() 1874{ 1875 local rc 1876 1877 echo 1878 echo "IPv4 route with IPv6 gateway tests" 1879 1880 route_setup 1881 sleep 2 1882 1883 # 1884 # single path route 1885 # 1886 run_cmd "$IP ro add 172.16.104.0/24 via inet6 2001:db8:101::2" 1887 rc=$? 1888 log_test $rc 0 "Single path route with IPv6 gateway" 1889 if [ $rc -eq 0 ]; then 1890 check_route "172.16.104.0/24 via inet6 2001:db8:101::2 dev veth1" 1891 fi 1892 1893 run_cmd "ip netns exec ns1 ping -w1 -c1 172.16.104.1" 1894 log_test $rc 0 "Single path route with IPv6 gateway - ping" 1895 1896 run_cmd "$IP ro del 172.16.104.0/24 via inet6 2001:db8:101::2" 1897 rc=$? 1898 log_test $rc 0 "Single path route delete" 1899 if [ $rc -eq 0 ]; then 1900 check_route "172.16.112.0/24" 1901 fi 1902 1903 # 1904 # multipath - v6 then v4 1905 # 1906 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" 1907 rc=$? 1908 log_test $rc 0 "Multipath route add - v6 nexthop then v4" 1909 if [ $rc -eq 0 ]; then 1910 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" 1911 fi 1912 1913 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" 1914 log_test $? 2 " Multipath route delete - nexthops in wrong order" 1915 1916 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" 1917 log_test $? 0 " Multipath route delete exact match" 1918 1919 # 1920 # multipath - v4 then v6 1921 # 1922 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" 1923 rc=$? 1924 log_test $rc 0 "Multipath route add - v4 nexthop then v6" 1925 if [ $rc -eq 0 ]; then 1926 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" 1927 fi 1928 1929 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" 1930 log_test $? 2 " Multipath route delete - nexthops in wrong order" 1931 1932 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" 1933 log_test $? 0 " Multipath route delete exact match" 1934 1935 route_cleanup 1936} 1937 1938socat_check() 1939{ 1940 if [ ! -x "$(command -v socat)" ]; then 1941 echo "socat command not found. Skipping test" 1942 return 1 1943 fi 1944 1945 return 0 1946} 1947 1948iptables_check() 1949{ 1950 iptables -t mangle -L OUTPUT &> /dev/null 1951 if [ $? -ne 0 ]; then 1952 echo "iptables configuration not supported. Skipping test" 1953 return 1 1954 fi 1955 1956 return 0 1957} 1958 1959ip6tables_check() 1960{ 1961 ip6tables -t mangle -L OUTPUT &> /dev/null 1962 if [ $? -ne 0 ]; then 1963 echo "ip6tables configuration not supported. Skipping test" 1964 return 1 1965 fi 1966 1967 return 0 1968} 1969 1970ipv4_mangle_test() 1971{ 1972 local rc 1973 1974 echo 1975 echo "IPv4 mangling tests" 1976 1977 socat_check || return 1 1978 iptables_check || return 1 1979 1980 route_setup 1981 sleep 2 1982 1983 local tmp_file=$(mktemp) 1984 ip netns exec ns2 socat UDP4-LISTEN:54321,fork $tmp_file & 1985 1986 # Add a FIB rule and a route that will direct our connection to the 1987 # listening server. 1988 $IP rule add pref 100 ipproto udp sport 12345 dport 54321 table 123 1989 $IP route add table 123 172.16.101.0/24 dev veth1 1990 1991 # Add an unreachable route to the main table that will block our 1992 # connection in case the FIB rule is not hit. 1993 $IP route add unreachable 172.16.101.2/32 1994 1995 run_cmd "echo a | $NS_EXEC socat STDIN UDP4:172.16.101.2:54321,sourceport=12345" 1996 log_test $? 0 " Connection with correct parameters" 1997 1998 run_cmd "echo a | $NS_EXEC socat STDIN UDP4:172.16.101.2:54321,sourceport=11111" 1999 log_test $? 1 " Connection with incorrect parameters" 2000 2001 # Add a mangling rule and make sure connection is still successful. 2002 $NS_EXEC iptables -t mangle -A OUTPUT -j MARK --set-mark 1 2003 2004 run_cmd "echo a | $NS_EXEC socat STDIN UDP4:172.16.101.2:54321,sourceport=12345" 2005 log_test $? 0 " Connection with correct parameters - mangling" 2006 2007 # Delete the mangling rule and make sure connection is still 2008 # successful. 2009 $NS_EXEC iptables -t mangle -D OUTPUT -j MARK --set-mark 1 2010 2011 run_cmd "echo a | $NS_EXEC socat STDIN UDP4:172.16.101.2:54321,sourceport=12345" 2012 log_test $? 0 " Connection with correct parameters - no mangling" 2013 2014 # Verify connections were indeed successful on server side. 2015 [[ $(cat $tmp_file | wc -l) -eq 3 ]] 2016 log_test $? 0 " Connection check - server side" 2017 2018 $IP route del unreachable 172.16.101.2/32 2019 $IP route del table 123 172.16.101.0/24 dev veth1 2020 $IP rule del pref 100 2021 2022 { kill %% && wait %%; } 2>/dev/null 2023 rm $tmp_file 2024 2025 route_cleanup 2026} 2027 2028ipv6_mangle_test() 2029{ 2030 local rc 2031 2032 echo 2033 echo "IPv6 mangling tests" 2034 2035 socat_check || return 1 2036 ip6tables_check || return 1 2037 2038 route_setup 2039 sleep 2 2040 2041 local tmp_file=$(mktemp) 2042 ip netns exec ns2 socat UDP6-LISTEN:54321,fork $tmp_file & 2043 2044 # Add a FIB rule and a route that will direct our connection to the 2045 # listening server. 2046 $IP -6 rule add pref 100 ipproto udp sport 12345 dport 54321 table 123 2047 $IP -6 route add table 123 2001:db8:101::/64 dev veth1 2048 2049 # Add an unreachable route to the main table that will block our 2050 # connection in case the FIB rule is not hit. 2051 $IP -6 route add unreachable 2001:db8:101::2/128 2052 2053 run_cmd "echo a | $NS_EXEC socat STDIN UDP6:[2001:db8:101::2]:54321,sourceport=12345" 2054 log_test $? 0 " Connection with correct parameters" 2055 2056 run_cmd "echo a | $NS_EXEC socat STDIN UDP6:[2001:db8:101::2]:54321,sourceport=11111" 2057 log_test $? 1 " Connection with incorrect parameters" 2058 2059 # Add a mangling rule and make sure connection is still successful. 2060 $NS_EXEC ip6tables -t mangle -A OUTPUT -j MARK --set-mark 1 2061 2062 run_cmd "echo a | $NS_EXEC socat STDIN UDP6:[2001:db8:101::2]:54321,sourceport=12345" 2063 log_test $? 0 " Connection with correct parameters - mangling" 2064 2065 # Delete the mangling rule and make sure connection is still 2066 # successful. 2067 $NS_EXEC ip6tables -t mangle -D OUTPUT -j MARK --set-mark 1 2068 2069 run_cmd "echo a | $NS_EXEC socat STDIN UDP6:[2001:db8:101::2]:54321,sourceport=12345" 2070 log_test $? 0 " Connection with correct parameters - no mangling" 2071 2072 # Verify connections were indeed successful on server side. 2073 [[ $(cat $tmp_file | wc -l) -eq 3 ]] 2074 log_test $? 0 " Connection check - server side" 2075 2076 $IP -6 route del unreachable 2001:db8:101::2/128 2077 $IP -6 route del table 123 2001:db8:101::/64 dev veth1 2078 $IP -6 rule del pref 100 2079 2080 { kill %% && wait %%; } 2>/dev/null 2081 rm $tmp_file 2082 2083 route_cleanup 2084} 2085 2086ip_neigh_get_check() 2087{ 2088 ip neigh help 2>&1 | grep -q 'ip neigh get' 2089 if [ $? -ne 0 ]; then 2090 echo "iproute2 command does not support neigh get. Skipping test" 2091 return 1 2092 fi 2093 2094 return 0 2095} 2096 2097ipv4_bcast_neigh_test() 2098{ 2099 local rc 2100 2101 echo 2102 echo "IPv4 broadcast neighbour tests" 2103 2104 ip_neigh_get_check || return 1 2105 2106 setup 2107 2108 set -e 2109 run_cmd "$IP neigh add 192.0.2.111 lladdr 00:11:22:33:44:55 nud perm dev dummy0" 2110 run_cmd "$IP neigh add 192.0.2.255 lladdr 00:11:22:33:44:55 nud perm dev dummy0" 2111 2112 run_cmd "$IP neigh get 192.0.2.111 dev dummy0" 2113 run_cmd "$IP neigh get 192.0.2.255 dev dummy0" 2114 2115 run_cmd "$IP address add 192.0.2.1/24 broadcast 192.0.2.111 dev dummy0" 2116 2117 run_cmd "$IP neigh add 203.0.113.111 nud failed dev dummy0" 2118 run_cmd "$IP neigh add 203.0.113.255 nud failed dev dummy0" 2119 2120 run_cmd "$IP neigh get 203.0.113.111 dev dummy0" 2121 run_cmd "$IP neigh get 203.0.113.255 dev dummy0" 2122 2123 run_cmd "$IP address add 203.0.113.1/24 broadcast 203.0.113.111 dev dummy0" 2124 set +e 2125 2126 run_cmd "$IP neigh get 192.0.2.111 dev dummy0" 2127 log_test $? 0 "Resolved neighbour for broadcast address" 2128 2129 run_cmd "$IP neigh get 192.0.2.255 dev dummy0" 2130 log_test $? 0 "Resolved neighbour for network broadcast address" 2131 2132 run_cmd "$IP neigh get 203.0.113.111 dev dummy0" 2133 log_test $? 2 "Unresolved neighbour for broadcast address" 2134 2135 run_cmd "$IP neigh get 203.0.113.255 dev dummy0" 2136 log_test $? 2 "Unresolved neighbour for network broadcast address" 2137 2138 cleanup 2139} 2140 2141################################################################################ 2142# usage 2143 2144usage() 2145{ 2146 cat <<EOF 2147usage: ${0##*/} OPTS 2148 2149 -t <test> Test(s) to run (default: all) 2150 (options: $TESTS) 2151 -p Pause on fail 2152 -P Pause after each test before cleanup 2153 -v verbose mode (show commands and output) 2154EOF 2155} 2156 2157################################################################################ 2158# main 2159 2160trap cleanup EXIT 2161 2162while getopts :t:pPhv o 2163do 2164 case $o in 2165 t) TESTS=$OPTARG;; 2166 p) PAUSE_ON_FAIL=yes;; 2167 P) PAUSE=yes;; 2168 v) VERBOSE=$(($VERBOSE + 1));; 2169 h) usage; exit 0;; 2170 *) usage; exit 1;; 2171 esac 2172done 2173 2174PEER_CMD="ip netns exec ${PEER_NS}" 2175 2176# make sure we don't pause twice 2177[ "${PAUSE}" = "yes" ] && PAUSE_ON_FAIL=no 2178 2179if [ "$(id -u)" -ne 0 ];then 2180 echo "SKIP: Need root privileges" 2181 exit $ksft_skip; 2182fi 2183 2184if [ ! -x "$(command -v ip)" ]; then 2185 echo "SKIP: Could not run test without ip tool" 2186 exit $ksft_skip 2187fi 2188 2189ip route help 2>&1 | grep -q fibmatch 2190if [ $? -ne 0 ]; then 2191 echo "SKIP: iproute2 too old, missing fibmatch" 2192 exit $ksft_skip 2193fi 2194 2195# start clean 2196cleanup &> /dev/null 2197 2198for t in $TESTS 2199do 2200 case $t in 2201 fib_unreg_test|unregister) fib_unreg_test;; 2202 fib_down_test|down) fib_down_test;; 2203 fib_carrier_test|carrier) fib_carrier_test;; 2204 fib_rp_filter_test|rp_filter) fib_rp_filter_test;; 2205 fib_nexthop_test|nexthop) fib_nexthop_test;; 2206 fib_notify_test|ipv4_notify) fib_notify_test;; 2207 fib6_notify_test|ipv6_notify) fib6_notify_test;; 2208 fib_suppress_test|suppress) fib_suppress_test;; 2209 ipv6_route_test|ipv6_rt) ipv6_route_test;; 2210 ipv4_route_test|ipv4_rt) ipv4_route_test;; 2211 ipv6_addr_metric) ipv6_addr_metric_test;; 2212 ipv4_addr_metric) ipv4_addr_metric_test;; 2213 ipv4_del_addr) ipv4_del_addr_test;; 2214 ipv6_route_metrics) ipv6_route_metrics_test;; 2215 ipv4_route_metrics) ipv4_route_metrics_test;; 2216 ipv4_route_v6_gw) ipv4_route_v6_gw_test;; 2217 ipv4_mangle) ipv4_mangle_test;; 2218 ipv6_mangle) ipv6_mangle_test;; 2219 ipv4_bcast_neigh) ipv4_bcast_neigh_test;; 2220 2221 help) echo "Test names: $TESTS"; exit 0;; 2222 esac 2223done 2224 2225if [ "$TESTS" != "none" ]; then 2226 printf "\nTests passed: %3d\n" ${nsuccess} 2227 printf "Tests failed: %3d\n" ${nfail} 2228fi 2229 2230exit $ret 2231