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