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