1#!/bin/bash 2# SPDX-License-Identifier: GPL-2.0 3# 4# ns: me | ns: peer | ns: remote 5# 2001:db8:91::1 | 2001:db8:91::2 | 6# 172.16.1.1 | 172.16.1.2 | 7# veth1 <---|---> veth2 | 8# | veth5 <--|--> veth6 172.16.101.1 9# veth3 <---|---> veth4 | 2001:db8:101::1 10# 172.16.2.1 | 172.16.2.2 | 11# 2001:db8:92::1 | 2001:db8:92::2 | 12# 13# This test is for checking IPv4 and IPv6 FIB behavior with nexthop 14# objects. Device reference counts and network namespace cleanup tested 15# by use of network namespace for peer. 16 17ret=0 18# Kselftest framework requirement - SKIP code is 4. 19ksft_skip=4 20 21# all tests in this script. Can be overridden with -t option 22IPV4_TESTS=" 23 ipv4_fcnal 24 ipv4_grp_fcnal 25 ipv4_res_grp_fcnal 26 ipv4_withv6_fcnal 27 ipv4_fcnal_runtime 28 ipv4_large_grp 29 ipv4_large_res_grp 30 ipv4_compat_mode 31 ipv4_fdb_grp_fcnal 32 ipv4_torture 33 ipv4_res_torture 34" 35 36IPV6_TESTS=" 37 ipv6_fcnal 38 ipv6_grp_fcnal 39 ipv6_res_grp_fcnal 40 ipv6_fcnal_runtime 41 ipv6_large_grp 42 ipv6_large_res_grp 43 ipv6_compat_mode 44 ipv6_fdb_grp_fcnal 45 ipv6_torture 46 ipv6_res_torture 47" 48 49ALL_TESTS=" 50 basic 51 basic_res 52 ${IPV4_TESTS} 53 ${IPV6_TESTS} 54" 55TESTS="${ALL_TESTS}" 56VERBOSE=0 57PAUSE_ON_FAIL=no 58PAUSE=no 59 60nsid=100 61 62################################################################################ 63# utilities 64 65log_test() 66{ 67 local rc=$1 68 local expected=$2 69 local msg="$3" 70 71 if [ ${rc} -eq ${expected} ]; then 72 printf "TEST: %-60s [ OK ]\n" "${msg}" 73 nsuccess=$((nsuccess+1)) 74 else 75 ret=1 76 nfail=$((nfail+1)) 77 printf "TEST: %-60s [FAIL]\n" "${msg}" 78 if [ "$VERBOSE" = "1" ]; then 79 echo " rc=$rc, expected $expected" 80 fi 81 82 if [ "${PAUSE_ON_FAIL}" = "yes" ]; then 83 echo 84 echo "hit enter to continue, 'q' to quit" 85 read a 86 [ "$a" = "q" ] && exit 1 87 fi 88 fi 89 90 if [ "${PAUSE}" = "yes" ]; then 91 echo 92 echo "hit enter to continue, 'q' to quit" 93 read a 94 [ "$a" = "q" ] && exit 1 95 fi 96 97 [ "$VERBOSE" = "1" ] && echo 98} 99 100run_cmd() 101{ 102 local cmd="$1" 103 local out 104 local stderr="2>/dev/null" 105 106 if [ "$VERBOSE" = "1" ]; then 107 printf "COMMAND: $cmd\n" 108 stderr= 109 fi 110 111 out=$(eval $cmd $stderr) 112 rc=$? 113 if [ "$VERBOSE" = "1" -a -n "$out" ]; then 114 echo " $out" 115 fi 116 117 return $rc 118} 119 120get_linklocal() 121{ 122 local dev=$1 123 local ns 124 local addr 125 126 [ -n "$2" ] && ns="-netns $2" 127 addr=$(ip $ns -6 -br addr show dev ${dev} | \ 128 awk '{ 129 for (i = 3; i <= NF; ++i) { 130 if ($i ~ /^fe80/) 131 print $i 132 } 133 }' 134 ) 135 addr=${addr/\/*} 136 137 [ -z "$addr" ] && return 1 138 139 echo $addr 140 141 return 0 142} 143 144create_ns() 145{ 146 local n=${1} 147 148 ip netns del ${n} 2>/dev/null 149 150 set -e 151 ip netns add ${n} 152 ip netns set ${n} $((nsid++)) 153 ip -netns ${n} addr add 127.0.0.1/8 dev lo 154 ip -netns ${n} link set lo up 155 156 ip netns exec ${n} sysctl -qw net.ipv4.ip_forward=1 157 ip netns exec ${n} sysctl -qw net.ipv4.fib_multipath_use_neigh=1 158 ip netns exec ${n} sysctl -qw net.ipv4.conf.default.ignore_routes_with_linkdown=1 159 ip netns exec ${n} sysctl -qw net.ipv6.conf.all.keep_addr_on_down=1 160 ip netns exec ${n} sysctl -qw net.ipv6.conf.all.forwarding=1 161 ip netns exec ${n} sysctl -qw net.ipv6.conf.default.forwarding=1 162 ip netns exec ${n} sysctl -qw net.ipv6.conf.default.ignore_routes_with_linkdown=1 163 ip netns exec ${n} sysctl -qw net.ipv6.conf.all.accept_dad=0 164 ip netns exec ${n} sysctl -qw net.ipv6.conf.default.accept_dad=0 165 166 set +e 167} 168 169setup() 170{ 171 cleanup 172 173 create_ns me 174 create_ns peer 175 create_ns remote 176 177 IP="ip -netns me" 178 BRIDGE="bridge -netns me" 179 set -e 180 $IP li add veth1 type veth peer name veth2 181 $IP li set veth1 up 182 $IP addr add 172.16.1.1/24 dev veth1 183 $IP -6 addr add 2001:db8:91::1/64 dev veth1 nodad 184 185 $IP li add veth3 type veth peer name veth4 186 $IP li set veth3 up 187 $IP addr add 172.16.2.1/24 dev veth3 188 $IP -6 addr add 2001:db8:92::1/64 dev veth3 nodad 189 190 $IP li set veth2 netns peer up 191 ip -netns peer addr add 172.16.1.2/24 dev veth2 192 ip -netns peer -6 addr add 2001:db8:91::2/64 dev veth2 nodad 193 194 $IP li set veth4 netns peer up 195 ip -netns peer addr add 172.16.2.2/24 dev veth4 196 ip -netns peer -6 addr add 2001:db8:92::2/64 dev veth4 nodad 197 198 ip -netns remote li add veth5 type veth peer name veth6 199 ip -netns remote li set veth5 up 200 ip -netns remote addr add dev veth5 172.16.101.1/24 201 ip -netns remote -6 addr add dev veth5 2001:db8:101::1/64 nodad 202 ip -netns remote ro add 172.16.0.0/22 via 172.16.101.2 203 ip -netns remote -6 ro add 2001:db8:90::/40 via 2001:db8:101::2 204 205 ip -netns remote li set veth6 netns peer up 206 ip -netns peer addr add dev veth6 172.16.101.2/24 207 ip -netns peer -6 addr add dev veth6 2001:db8:101::2/64 nodad 208 set +e 209} 210 211cleanup() 212{ 213 local ns 214 215 for ns in me peer remote; do 216 ip netns del ${ns} 2>/dev/null 217 done 218} 219 220check_output() 221{ 222 local out="$1" 223 local expected="$2" 224 local rc=0 225 226 [ "${out}" = "${expected}" ] && return 0 227 228 if [ -z "${out}" ]; then 229 if [ "$VERBOSE" = "1" ]; then 230 printf "\nNo entry found\n" 231 printf "Expected:\n" 232 printf " ${expected}\n" 233 fi 234 return 1 235 fi 236 237 out=$(echo ${out}) 238 if [ "${out}" != "${expected}" ]; then 239 rc=1 240 if [ "${VERBOSE}" = "1" ]; then 241 printf " Unexpected entry. Have:\n" 242 printf " ${out}\n" 243 printf " Expected:\n" 244 printf " ${expected}\n\n" 245 else 246 echo " WARNING: Unexpected route entry" 247 fi 248 fi 249 250 return $rc 251} 252 253check_nexthop() 254{ 255 local nharg="$1" 256 local expected="$2" 257 local out 258 259 out=$($IP nexthop ls ${nharg} 2>/dev/null) 260 261 check_output "${out}" "${expected}" 262} 263 264check_nexthop_bucket() 265{ 266 local nharg="$1" 267 local expected="$2" 268 local out 269 270 # remove the idle time since we cannot match it 271 out=$($IP nexthop bucket ${nharg} \ 272 | sed s/idle_time\ [0-9.]*\ // 2>/dev/null) 273 274 check_output "${out}" "${expected}" 275} 276 277check_route() 278{ 279 local pfx="$1" 280 local expected="$2" 281 local out 282 283 out=$($IP route ls match ${pfx} 2>/dev/null) 284 285 check_output "${out}" "${expected}" 286} 287 288check_route6() 289{ 290 local pfx="$1" 291 local expected="$2" 292 local out 293 294 out=$($IP -6 route ls match ${pfx} 2>/dev/null | sed -e 's/pref medium//') 295 296 check_output "${out}" "${expected}" 297} 298 299check_large_grp() 300{ 301 local ipv=$1 302 local ecmp=$2 303 local grpnum=100 304 local nhidstart=100 305 local grpidstart=1000 306 local iter=0 307 local nhidstr="" 308 local grpidstr="" 309 local grpstr="" 310 local ipstr="" 311 312 if [ $ipv -eq 4 ]; then 313 ipstr="172.16.1." 314 else 315 ipstr="2001:db8:91::" 316 fi 317 318 # 319 # Create $grpnum groups with specified $ecmp and dump them 320 # 321 322 # create nexthops with different gateways 323 iter=2 324 while [ $iter -le $(($ecmp + 1)) ] 325 do 326 nhidstr="$(($nhidstart + $iter))" 327 run_cmd "$IP nexthop add id $nhidstr via $ipstr$iter dev veth1" 328 check_nexthop "id $nhidstr" "id $nhidstr via $ipstr$iter dev veth1 scope link" 329 330 if [ $iter -le $ecmp ]; then 331 grpstr+="$nhidstr/" 332 else 333 grpstr+="$nhidstr" 334 fi 335 ((iter++)) 336 done 337 338 # create duplicate large ecmp groups 339 iter=0 340 while [ $iter -le $grpnum ] 341 do 342 grpidstr="$(($grpidstart + $iter))" 343 run_cmd "$IP nexthop add id $grpidstr group $grpstr" 344 check_nexthop "id $grpidstr" "id $grpidstr group $grpstr" 345 ((iter++)) 346 done 347 348 # dump large groups 349 run_cmd "$IP nexthop list" 350 log_test $? 0 "Dump large (x$ecmp) ecmp groups" 351} 352 353check_large_res_grp() 354{ 355 local ipv=$1 356 local buckets=$2 357 local ipstr="" 358 359 if [ $ipv -eq 4 ]; then 360 ipstr="172.16.1.2" 361 else 362 ipstr="2001:db8:91::2" 363 fi 364 365 # create a resilient group with $buckets buckets and dump them 366 run_cmd "$IP nexthop add id 100 via $ipstr dev veth1" 367 run_cmd "$IP nexthop add id 1000 group 100 type resilient buckets $buckets" 368 run_cmd "$IP nexthop bucket list" 369 log_test $? 0 "Dump large (x$buckets) nexthop buckets" 370} 371 372start_ip_monitor() 373{ 374 local mtype=$1 375 376 # start the monitor in the background 377 tmpfile=`mktemp /var/run/nexthoptestXXX` 378 mpid=`($IP monitor $mtype > $tmpfile & echo $!) 2>/dev/null` 379 sleep 0.2 380 echo "$mpid $tmpfile" 381} 382 383stop_ip_monitor() 384{ 385 local mpid=$1 386 local tmpfile=$2 387 local el=$3 388 389 # check the monitor results 390 kill $mpid 391 lines=`wc -l $tmpfile | cut "-d " -f1` 392 test $lines -eq $el 393 rc=$? 394 rm -rf $tmpfile 395 396 return $rc 397} 398 399check_nexthop_fdb_support() 400{ 401 $IP nexthop help 2>&1 | grep -q fdb 402 if [ $? -ne 0 ]; then 403 echo "SKIP: iproute2 too old, missing fdb nexthop support" 404 return $ksft_skip 405 fi 406} 407 408check_nexthop_res_support() 409{ 410 $IP nexthop help 2>&1 | grep -q resilient 411 if [ $? -ne 0 ]; then 412 echo "SKIP: iproute2 too old, missing resilient nexthop group support" 413 return $ksft_skip 414 fi 415} 416 417ipv6_fdb_grp_fcnal() 418{ 419 local rc 420 421 echo 422 echo "IPv6 fdb groups functional" 423 echo "--------------------------" 424 425 check_nexthop_fdb_support 426 if [ $? -eq $ksft_skip ]; then 427 return $ksft_skip 428 fi 429 430 # create group with multiple nexthops 431 run_cmd "$IP nexthop add id 61 via 2001:db8:91::2 fdb" 432 run_cmd "$IP nexthop add id 62 via 2001:db8:91::3 fdb" 433 run_cmd "$IP nexthop add id 102 group 61/62 fdb" 434 check_nexthop "id 102" "id 102 group 61/62 fdb" 435 log_test $? 0 "Fdb Nexthop group with multiple nexthops" 436 437 ## get nexthop group 438 run_cmd "$IP nexthop get id 102" 439 check_nexthop "id 102" "id 102 group 61/62 fdb" 440 log_test $? 0 "Get Fdb nexthop group by id" 441 442 # fdb nexthop group can only contain fdb nexthops 443 run_cmd "$IP nexthop add id 63 via 2001:db8:91::4" 444 run_cmd "$IP nexthop add id 64 via 2001:db8:91::5" 445 run_cmd "$IP nexthop add id 103 group 63/64 fdb" 446 log_test $? 2 "Fdb Nexthop group with non-fdb nexthops" 447 448 # Non fdb nexthop group can not contain fdb nexthops 449 run_cmd "$IP nexthop add id 65 via 2001:db8:91::5 fdb" 450 run_cmd "$IP nexthop add id 66 via 2001:db8:91::6 fdb" 451 run_cmd "$IP nexthop add id 104 group 65/66" 452 log_test $? 2 "Non-Fdb Nexthop group with fdb nexthops" 453 454 # fdb nexthop cannot have blackhole 455 run_cmd "$IP nexthop add id 67 blackhole fdb" 456 log_test $? 2 "Fdb Nexthop with blackhole" 457 458 # fdb nexthop with oif 459 run_cmd "$IP nexthop add id 68 via 2001:db8:91::7 dev veth1 fdb" 460 log_test $? 2 "Fdb Nexthop with oif" 461 462 # fdb nexthop with onlink 463 run_cmd "$IP nexthop add id 68 via 2001:db8:91::7 onlink fdb" 464 log_test $? 2 "Fdb Nexthop with onlink" 465 466 # fdb nexthop with encap 467 run_cmd "$IP nexthop add id 69 encap mpls 101 via 2001:db8:91::8 dev veth1 fdb" 468 log_test $? 2 "Fdb Nexthop with encap" 469 470 run_cmd "$IP link add name vx10 type vxlan id 1010 local 2001:db8:91::9 remote 2001:db8:91::10 dstport 4789 nolearning noudpcsum tos inherit ttl 100" 471 run_cmd "$BRIDGE fdb add 02:02:00:00:00:13 dev vx10 nhid 102 self" 472 log_test $? 0 "Fdb mac add with nexthop group" 473 474 ## fdb nexthops can only reference nexthop groups and not nexthops 475 run_cmd "$BRIDGE fdb add 02:02:00:00:00:14 dev vx10 nhid 61 self" 476 log_test $? 255 "Fdb mac add with nexthop" 477 478 run_cmd "$IP -6 ro add 2001:db8:101::1/128 nhid 66" 479 log_test $? 2 "Route add with fdb nexthop" 480 481 run_cmd "$IP -6 ro add 2001:db8:101::1/128 nhid 103" 482 log_test $? 2 "Route add with fdb nexthop group" 483 484 run_cmd "$IP nexthop del id 61" 485 run_cmd "$BRIDGE fdb get to 02:02:00:00:00:13 dev vx10 self" 486 log_test $? 0 "Fdb entry after deleting a single nexthop" 487 488 run_cmd "$IP nexthop del id 102" 489 log_test $? 0 "Fdb nexthop delete" 490 491 run_cmd "$BRIDGE fdb get to 02:02:00:00:00:13 dev vx10 self" 492 log_test $? 254 "Fdb entry after deleting a nexthop group" 493 494 $IP link del dev vx10 495} 496 497ipv4_fdb_grp_fcnal() 498{ 499 local rc 500 501 echo 502 echo "IPv4 fdb groups functional" 503 echo "--------------------------" 504 505 check_nexthop_fdb_support 506 if [ $? -eq $ksft_skip ]; then 507 return $ksft_skip 508 fi 509 510 # create group with multiple nexthops 511 run_cmd "$IP nexthop add id 12 via 172.16.1.2 fdb" 512 run_cmd "$IP nexthop add id 13 via 172.16.1.3 fdb" 513 run_cmd "$IP nexthop add id 102 group 12/13 fdb" 514 check_nexthop "id 102" "id 102 group 12/13 fdb" 515 log_test $? 0 "Fdb Nexthop group with multiple nexthops" 516 517 # get nexthop group 518 run_cmd "$IP nexthop get id 102" 519 check_nexthop "id 102" "id 102 group 12/13 fdb" 520 log_test $? 0 "Get Fdb nexthop group by id" 521 522 # fdb nexthop group can only contain fdb nexthops 523 run_cmd "$IP nexthop add id 14 via 172.16.1.2" 524 run_cmd "$IP nexthop add id 15 via 172.16.1.3" 525 run_cmd "$IP nexthop add id 103 group 14/15 fdb" 526 log_test $? 2 "Fdb Nexthop group with non-fdb nexthops" 527 528 # Non fdb nexthop group can not contain fdb nexthops 529 run_cmd "$IP nexthop add id 16 via 172.16.1.2 fdb" 530 run_cmd "$IP nexthop add id 17 via 172.16.1.3 fdb" 531 run_cmd "$IP nexthop add id 104 group 14/15" 532 log_test $? 2 "Non-Fdb Nexthop group with fdb nexthops" 533 534 # fdb nexthop cannot have blackhole 535 run_cmd "$IP nexthop add id 18 blackhole fdb" 536 log_test $? 2 "Fdb Nexthop with blackhole" 537 538 # fdb nexthop with oif 539 run_cmd "$IP nexthop add id 16 via 172.16.1.2 dev veth1 fdb" 540 log_test $? 2 "Fdb Nexthop with oif" 541 542 # fdb nexthop with onlink 543 run_cmd "$IP nexthop add id 16 via 172.16.1.2 onlink fdb" 544 log_test $? 2 "Fdb Nexthop with onlink" 545 546 # fdb nexthop with encap 547 run_cmd "$IP nexthop add id 17 encap mpls 101 via 172.16.1.2 dev veth1 fdb" 548 log_test $? 2 "Fdb Nexthop with encap" 549 550 run_cmd "$IP link add name vx10 type vxlan id 1010 local 10.0.0.1 remote 10.0.0.2 dstport 4789 nolearning noudpcsum tos inherit ttl 100" 551 run_cmd "$BRIDGE fdb add 02:02:00:00:00:13 dev vx10 nhid 102 self" 552 log_test $? 0 "Fdb mac add with nexthop group" 553 554 # fdb nexthops can only reference nexthop groups and not nexthops 555 run_cmd "$BRIDGE fdb add 02:02:00:00:00:14 dev vx10 nhid 12 self" 556 log_test $? 255 "Fdb mac add with nexthop" 557 558 run_cmd "$IP ro add 172.16.0.0/22 nhid 15" 559 log_test $? 2 "Route add with fdb nexthop" 560 561 run_cmd "$IP ro add 172.16.0.0/22 nhid 103" 562 log_test $? 2 "Route add with fdb nexthop group" 563 564 run_cmd "$IP nexthop del id 12" 565 run_cmd "$BRIDGE fdb get to 02:02:00:00:00:13 dev vx10 self" 566 log_test $? 0 "Fdb entry after deleting a single nexthop" 567 568 run_cmd "$IP nexthop del id 102" 569 log_test $? 0 "Fdb nexthop delete" 570 571 run_cmd "$BRIDGE fdb get to 02:02:00:00:00:13 dev vx10 self" 572 log_test $? 254 "Fdb entry after deleting a nexthop group" 573 574 $IP link del dev vx10 575} 576 577################################################################################ 578# basic operations (add, delete, replace) on nexthops and nexthop groups 579# 580# IPv6 581 582ipv6_fcnal() 583{ 584 local rc 585 586 echo 587 echo "IPv6" 588 echo "----------------------" 589 590 run_cmd "$IP nexthop add id 52 via 2001:db8:91::2 dev veth1" 591 rc=$? 592 log_test $rc 0 "Create nexthop with id, gw, dev" 593 if [ $rc -ne 0 ]; then 594 echo "Basic IPv6 create fails; can not continue" 595 return 1 596 fi 597 598 run_cmd "$IP nexthop get id 52" 599 log_test $? 0 "Get nexthop by id" 600 check_nexthop "id 52" "id 52 via 2001:db8:91::2 dev veth1 scope link" 601 602 run_cmd "$IP nexthop del id 52" 603 log_test $? 0 "Delete nexthop by id" 604 check_nexthop "id 52" "" 605 606 # 607 # gw, device spec 608 # 609 # gw validation, no device - fails since dev required 610 run_cmd "$IP nexthop add id 52 via 2001:db8:92::3" 611 log_test $? 2 "Create nexthop - gw only" 612 613 # gw is not reachable throught given dev 614 run_cmd "$IP nexthop add id 53 via 2001:db8:3::3 dev veth1" 615 log_test $? 2 "Create nexthop - invalid gw+dev combination" 616 617 # onlink arg overrides gw+dev lookup 618 run_cmd "$IP nexthop add id 53 via 2001:db8:3::3 dev veth1 onlink" 619 log_test $? 0 "Create nexthop - gw+dev and onlink" 620 621 # admin down should delete nexthops 622 set -e 623 run_cmd "$IP -6 nexthop add id 55 via 2001:db8:91::3 dev veth1" 624 run_cmd "$IP nexthop add id 56 via 2001:db8:91::4 dev veth1" 625 run_cmd "$IP nexthop add id 57 via 2001:db8:91::5 dev veth1" 626 run_cmd "$IP li set dev veth1 down" 627 set +e 628 check_nexthop "dev veth1" "" 629 log_test $? 0 "Nexthops removed on admin down" 630} 631 632ipv6_grp_refs() 633{ 634 if [ ! -x "$(command -v mausezahn)" ]; then 635 echo "SKIP: Could not run test; need mausezahn tool" 636 return 637 fi 638 639 run_cmd "$IP link set dev veth1 up" 640 run_cmd "$IP link add veth1.10 link veth1 up type vlan id 10" 641 run_cmd "$IP link add veth1.20 link veth1 up type vlan id 20" 642 run_cmd "$IP -6 addr add 2001:db8:91::1/64 dev veth1.10" 643 run_cmd "$IP -6 addr add 2001:db8:92::1/64 dev veth1.20" 644 run_cmd "$IP -6 neigh add 2001:db8:91::2 lladdr 00:11:22:33:44:55 dev veth1.10" 645 run_cmd "$IP -6 neigh add 2001:db8:92::2 lladdr 00:11:22:33:44:55 dev veth1.20" 646 run_cmd "$IP nexthop add id 100 via 2001:db8:91::2 dev veth1.10" 647 run_cmd "$IP nexthop add id 101 via 2001:db8:92::2 dev veth1.20" 648 run_cmd "$IP nexthop add id 102 group 100" 649 run_cmd "$IP route add 2001:db8:101::1/128 nhid 102" 650 651 # create per-cpu dsts through nh 100 652 run_cmd "ip netns exec me mausezahn -6 veth1.10 -B 2001:db8:101::1 -A 2001:db8:91::1 -c 5 -t tcp "dp=1-1023, flags=syn" >/dev/null 2>&1" 653 654 # remove nh 100 from the group to delete the route potentially leaving 655 # a stale per-cpu dst which holds a reference to the nexthop's net 656 # device and to the IPv6 route 657 run_cmd "$IP nexthop replace id 102 group 101" 658 run_cmd "$IP route del 2001:db8:101::1/128" 659 660 # add both nexthops to the group so a reference is taken on them 661 run_cmd "$IP nexthop replace id 102 group 100/101" 662 663 # if the bug described in commit "net: nexthop: release IPv6 per-cpu 664 # dsts when replacing a nexthop group" exists at this point we have 665 # an unlinked IPv6 route (but not freed due to stale dst) with a 666 # reference over the group so we delete the group which will again 667 # only unlink it due to the route reference 668 run_cmd "$IP nexthop del id 102" 669 670 # delete the nexthop with stale dst, since we have an unlinked 671 # group with a ref to it and an unlinked IPv6 route with ref to the 672 # group, the nh will only be unlinked and not freed so the stale dst 673 # remains forever and we get a net device refcount imbalance 674 run_cmd "$IP nexthop del id 100" 675 676 # if a reference was lost this command will hang because the net device 677 # cannot be removed 678 timeout -s KILL 5 ip netns exec me ip link del veth1.10 >/dev/null 2>&1 679 680 # we can't cleanup if the command is hung trying to delete the netdev 681 if [ $? -eq 137 ]; then 682 return 1 683 fi 684 685 # cleanup 686 run_cmd "$IP link del veth1.20" 687 run_cmd "$IP nexthop flush" 688 689 return 0 690} 691 692ipv6_grp_fcnal() 693{ 694 local rc 695 696 echo 697 echo "IPv6 groups functional" 698 echo "----------------------" 699 700 # basic functionality: create a nexthop group, default weight 701 run_cmd "$IP nexthop add id 61 via 2001:db8:91::2 dev veth1" 702 run_cmd "$IP nexthop add id 101 group 61" 703 log_test $? 0 "Create nexthop group with single nexthop" 704 705 # get nexthop group 706 run_cmd "$IP nexthop get id 101" 707 log_test $? 0 "Get nexthop group by id" 708 check_nexthop "id 101" "id 101 group 61" 709 710 # delete nexthop group 711 run_cmd "$IP nexthop del id 101" 712 log_test $? 0 "Delete nexthop group by id" 713 check_nexthop "id 101" "" 714 715 $IP nexthop flush >/dev/null 2>&1 716 check_nexthop "id 101" "" 717 718 # 719 # create group with multiple nexthops - mix of gw and dev only 720 # 721 run_cmd "$IP nexthop add id 62 via 2001:db8:91::2 dev veth1" 722 run_cmd "$IP nexthop add id 63 via 2001:db8:91::3 dev veth1" 723 run_cmd "$IP nexthop add id 64 via 2001:db8:91::4 dev veth1" 724 run_cmd "$IP nexthop add id 65 dev veth1" 725 run_cmd "$IP nexthop add id 102 group 62/63/64/65" 726 log_test $? 0 "Nexthop group with multiple nexthops" 727 check_nexthop "id 102" "id 102 group 62/63/64/65" 728 729 # Delete nexthop in a group and group is updated 730 run_cmd "$IP nexthop del id 63" 731 check_nexthop "id 102" "id 102 group 62/64/65" 732 log_test $? 0 "Nexthop group updated when entry is deleted" 733 734 # create group with multiple weighted nexthops 735 run_cmd "$IP nexthop add id 63 via 2001:db8:91::3 dev veth1" 736 run_cmd "$IP nexthop add id 103 group 62/63,2/64,3/65,4" 737 log_test $? 0 "Nexthop group with weighted nexthops" 738 check_nexthop "id 103" "id 103 group 62/63,2/64,3/65,4" 739 740 # Delete nexthop in a weighted group and group is updated 741 run_cmd "$IP nexthop del id 63" 742 check_nexthop "id 103" "id 103 group 62/64,3/65,4" 743 log_test $? 0 "Weighted nexthop group updated when entry is deleted" 744 745 # admin down - nexthop is removed from group 746 run_cmd "$IP li set dev veth1 down" 747 check_nexthop "dev veth1" "" 748 log_test $? 0 "Nexthops in groups removed on admin down" 749 750 # expect groups to have been deleted as well 751 check_nexthop "" "" 752 753 run_cmd "$IP li set dev veth1 up" 754 755 $IP nexthop flush >/dev/null 2>&1 756 757 # group with nexthops using different devices 758 set -e 759 run_cmd "$IP nexthop add id 62 via 2001:db8:91::2 dev veth1" 760 run_cmd "$IP nexthop add id 63 via 2001:db8:91::3 dev veth1" 761 run_cmd "$IP nexthop add id 64 via 2001:db8:91::4 dev veth1" 762 run_cmd "$IP nexthop add id 65 via 2001:db8:91::5 dev veth1" 763 764 run_cmd "$IP nexthop add id 72 via 2001:db8:92::2 dev veth3" 765 run_cmd "$IP nexthop add id 73 via 2001:db8:92::3 dev veth3" 766 run_cmd "$IP nexthop add id 74 via 2001:db8:92::4 dev veth3" 767 run_cmd "$IP nexthop add id 75 via 2001:db8:92::5 dev veth3" 768 set +e 769 770 # multiple groups with same nexthop 771 run_cmd "$IP nexthop add id 104 group 62" 772 run_cmd "$IP nexthop add id 105 group 62" 773 check_nexthop "group" "id 104 group 62 id 105 group 62" 774 log_test $? 0 "Multiple groups with same nexthop" 775 776 run_cmd "$IP nexthop flush groups" 777 [ $? -ne 0 ] && return 1 778 779 # on admin down of veth1, it should be removed from the group 780 run_cmd "$IP nexthop add id 105 group 62/63/72/73/64" 781 run_cmd "$IP li set veth1 down" 782 check_nexthop "id 105" "id 105 group 72/73" 783 log_test $? 0 "Nexthops in group removed on admin down - mixed group" 784 785 run_cmd "$IP nexthop add id 106 group 105/74" 786 log_test $? 2 "Nexthop group can not have a group as an entry" 787 788 # a group can have a blackhole entry only if it is the only 789 # nexthop in the group. Needed for atomic replace with an 790 # actual nexthop group 791 run_cmd "$IP -6 nexthop add id 31 blackhole" 792 run_cmd "$IP nexthop add id 107 group 31" 793 log_test $? 0 "Nexthop group with a blackhole entry" 794 795 run_cmd "$IP nexthop add id 108 group 31/24" 796 log_test $? 2 "Nexthop group can not have a blackhole and another nexthop" 797 798 ipv6_grp_refs 799 log_test $? 0 "Nexthop group replace refcounts" 800} 801 802ipv6_res_grp_fcnal() 803{ 804 local rc 805 806 echo 807 echo "IPv6 resilient groups functional" 808 echo "--------------------------------" 809 810 check_nexthop_res_support 811 if [ $? -eq $ksft_skip ]; then 812 return $ksft_skip 813 fi 814 815 # 816 # migration of nexthop buckets - equal weights 817 # 818 run_cmd "$IP nexthop add id 62 via 2001:db8:91::2 dev veth1" 819 run_cmd "$IP nexthop add id 63 via 2001:db8:91::3 dev veth1" 820 run_cmd "$IP nexthop add id 102 group 62/63 type resilient buckets 2 idle_timer 0" 821 822 run_cmd "$IP nexthop del id 63" 823 check_nexthop "id 102" \ 824 "id 102 group 62 type resilient buckets 2 idle_timer 0 unbalanced_timer 0 unbalanced_time 0" 825 log_test $? 0 "Nexthop group updated when entry is deleted" 826 check_nexthop_bucket "list id 102" \ 827 "id 102 index 0 nhid 62 id 102 index 1 nhid 62" 828 log_test $? 0 "Nexthop buckets updated when entry is deleted" 829 830 run_cmd "$IP nexthop add id 63 via 2001:db8:91::3 dev veth1" 831 run_cmd "$IP nexthop replace id 102 group 62/63 type resilient buckets 2 idle_timer 0" 832 check_nexthop "id 102" \ 833 "id 102 group 62/63 type resilient buckets 2 idle_timer 0 unbalanced_timer 0 unbalanced_time 0" 834 log_test $? 0 "Nexthop group updated after replace" 835 check_nexthop_bucket "list id 102" \ 836 "id 102 index 0 nhid 63 id 102 index 1 nhid 62" 837 log_test $? 0 "Nexthop buckets updated after replace" 838 839 $IP nexthop flush >/dev/null 2>&1 840 841 # 842 # migration of nexthop buckets - unequal weights 843 # 844 run_cmd "$IP nexthop add id 62 via 2001:db8:91::2 dev veth1" 845 run_cmd "$IP nexthop add id 63 via 2001:db8:91::3 dev veth1" 846 run_cmd "$IP nexthop add id 102 group 62,3/63,1 type resilient buckets 4 idle_timer 0" 847 848 run_cmd "$IP nexthop del id 63" 849 check_nexthop "id 102" \ 850 "id 102 group 62,3 type resilient buckets 4 idle_timer 0 unbalanced_timer 0 unbalanced_time 0" 851 log_test $? 0 "Nexthop group updated when entry is deleted - nECMP" 852 check_nexthop_bucket "list id 102" \ 853 "id 102 index 0 nhid 62 id 102 index 1 nhid 62 id 102 index 2 nhid 62 id 102 index 3 nhid 62" 854 log_test $? 0 "Nexthop buckets updated when entry is deleted - nECMP" 855 856 run_cmd "$IP nexthop add id 63 via 2001:db8:91::3 dev veth1" 857 run_cmd "$IP nexthop replace id 102 group 62,3/63,1 type resilient buckets 4 idle_timer 0" 858 check_nexthop "id 102" \ 859 "id 102 group 62,3/63 type resilient buckets 4 idle_timer 0 unbalanced_timer 0 unbalanced_time 0" 860 log_test $? 0 "Nexthop group updated after replace - nECMP" 861 check_nexthop_bucket "list id 102" \ 862 "id 102 index 0 nhid 63 id 102 index 1 nhid 62 id 102 index 2 nhid 62 id 102 index 3 nhid 62" 863 log_test $? 0 "Nexthop buckets updated after replace - nECMP" 864} 865 866ipv6_fcnal_runtime() 867{ 868 local rc 869 870 echo 871 echo "IPv6 functional runtime" 872 echo "-----------------------" 873 874 # 875 # IPv6 - the basics 876 # 877 run_cmd "$IP nexthop add id 81 via 2001:db8:91::2 dev veth1" 878 run_cmd "$IP ro add 2001:db8:101::1/128 nhid 81" 879 log_test $? 0 "Route add" 880 881 run_cmd "$IP ro delete 2001:db8:101::1/128 nhid 81" 882 log_test $? 0 "Route delete" 883 884 run_cmd "$IP ro add 2001:db8:101::1/128 nhid 81" 885 run_cmd "ip netns exec me ping -c1 -w1 2001:db8:101::1" 886 log_test $? 0 "Ping with nexthop" 887 888 run_cmd "$IP nexthop add id 82 via 2001:db8:92::2 dev veth3" 889 run_cmd "$IP nexthop add id 122 group 81/82" 890 run_cmd "$IP ro replace 2001:db8:101::1/128 nhid 122" 891 run_cmd "ip netns exec me ping -c1 -w1 2001:db8:101::1" 892 log_test $? 0 "Ping - multipath" 893 894 # 895 # IPv6 with blackhole nexthops 896 # 897 run_cmd "$IP -6 nexthop add id 83 blackhole" 898 run_cmd "$IP ro replace 2001:db8:101::1/128 nhid 83" 899 run_cmd "ip netns exec me ping -c1 -w1 2001:db8:101::1" 900 log_test $? 2 "Ping - blackhole" 901 902 run_cmd "$IP nexthop replace id 83 via 2001:db8:91::2 dev veth1" 903 run_cmd "ip netns exec me ping -c1 -w1 2001:db8:101::1" 904 log_test $? 0 "Ping - blackhole replaced with gateway" 905 906 run_cmd "$IP -6 nexthop replace id 83 blackhole" 907 run_cmd "ip netns exec me ping -c1 -w1 2001:db8:101::1" 908 log_test $? 2 "Ping - gateway replaced by blackhole" 909 910 run_cmd "$IP ro replace 2001:db8:101::1/128 nhid 122" 911 run_cmd "ip netns exec me ping -c1 -w1 2001:db8:101::1" 912 if [ $? -eq 0 ]; then 913 run_cmd "$IP nexthop replace id 122 group 83" 914 run_cmd "ip netns exec me ping -c1 -w1 2001:db8:101::1" 915 log_test $? 2 "Ping - group with blackhole" 916 917 run_cmd "$IP nexthop replace id 122 group 81/82" 918 run_cmd "ip netns exec me ping -c1 -w1 2001:db8:101::1" 919 log_test $? 0 "Ping - group blackhole replaced with gateways" 920 else 921 log_test 2 0 "Ping - multipath failed" 922 fi 923 924 # 925 # device only and gw + dev only mix 926 # 927 run_cmd "$IP -6 nexthop add id 85 dev veth1" 928 run_cmd "$IP ro replace 2001:db8:101::1/128 nhid 85" 929 log_test $? 0 "IPv6 route with device only nexthop" 930 check_route6 "2001:db8:101::1" "2001:db8:101::1 nhid 85 dev veth1 metric 1024" 931 932 run_cmd "$IP nexthop add id 123 group 81/85" 933 run_cmd "$IP ro replace 2001:db8:101::1/128 nhid 123" 934 log_test $? 0 "IPv6 multipath route with nexthop mix - dev only + gw" 935 check_route6 "2001:db8:101::1" "2001:db8:101::1 nhid 123 metric 1024 nexthop via 2001:db8:91::2 dev veth1 weight 1 nexthop dev veth1 weight 1" 936 937 # 938 # IPv6 route with v4 nexthop - not allowed 939 # 940 run_cmd "$IP ro delete 2001:db8:101::1/128" 941 run_cmd "$IP nexthop add id 84 via 172.16.1.1 dev veth1" 942 run_cmd "$IP ro add 2001:db8:101::1/128 nhid 84" 943 log_test $? 2 "IPv6 route can not have a v4 gateway" 944 945 run_cmd "$IP ro replace 2001:db8:101::1/128 nhid 81" 946 run_cmd "$IP nexthop replace id 81 via 172.16.1.1 dev veth1" 947 log_test $? 2 "Nexthop replace - v6 route, v4 nexthop" 948 949 run_cmd "$IP ro replace 2001:db8:101::1/128 nhid 122" 950 run_cmd "$IP nexthop replace id 81 via 172.16.1.1 dev veth1" 951 log_test $? 2 "Nexthop replace of group entry - v6 route, v4 nexthop" 952 953 run_cmd "$IP nexthop add id 86 via 2001:db8:92::2 dev veth3" 954 run_cmd "$IP nexthop add id 87 via 172.16.1.1 dev veth1" 955 run_cmd "$IP nexthop add id 88 via 172.16.1.1 dev veth1" 956 run_cmd "$IP nexthop add id 124 group 86/87/88" 957 run_cmd "$IP ro replace 2001:db8:101::1/128 nhid 124" 958 log_test $? 2 "IPv6 route can not have a group with v4 and v6 gateways" 959 960 run_cmd "$IP nexthop del id 88" 961 run_cmd "$IP ro replace 2001:db8:101::1/128 nhid 124" 962 log_test $? 2 "IPv6 route can not have a group with v4 and v6 gateways" 963 964 run_cmd "$IP nexthop del id 87" 965 run_cmd "$IP ro replace 2001:db8:101::1/128 nhid 124" 966 log_test $? 0 "IPv6 route using a group after removing v4 gateways" 967 968 run_cmd "$IP ro delete 2001:db8:101::1/128" 969 run_cmd "$IP nexthop add id 87 via 172.16.1.1 dev veth1" 970 run_cmd "$IP nexthop add id 88 via 172.16.1.1 dev veth1" 971 run_cmd "$IP nexthop replace id 124 group 86/87/88" 972 run_cmd "$IP ro replace 2001:db8:101::1/128 nhid 124" 973 log_test $? 2 "IPv6 route can not have a group with v4 and v6 gateways" 974 975 run_cmd "$IP nexthop replace id 88 via 2001:db8:92::2 dev veth3" 976 run_cmd "$IP ro replace 2001:db8:101::1/128 nhid 124" 977 log_test $? 2 "IPv6 route can not have a group with v4 and v6 gateways" 978 979 run_cmd "$IP nexthop replace id 87 via 2001:db8:92::2 dev veth3" 980 run_cmd "$IP ro replace 2001:db8:101::1/128 nhid 124" 981 log_test $? 0 "IPv6 route using a group after replacing v4 gateways" 982 983 $IP nexthop flush >/dev/null 2>&1 984 985 # 986 # weird IPv6 cases 987 # 988 run_cmd "$IP nexthop add id 86 via 2001:db8:91::2 dev veth1" 989 run_cmd "$IP ro add 2001:db8:101::1/128 nhid 81" 990 991 # route can not use prefsrc with nexthops 992 run_cmd "$IP ro add 2001:db8:101::2/128 nhid 86 from 2001:db8:91::1" 993 log_test $? 2 "IPv6 route can not use src routing with external nexthop" 994 995 # check cleanup path on invalid metric 996 run_cmd "$IP ro add 2001:db8:101::2/128 nhid 86 congctl lock foo" 997 log_test $? 2 "IPv6 route with invalid metric" 998 999 # rpfilter and default route 1000 $IP nexthop flush >/dev/null 2>&1 1001 run_cmd "ip netns exec me ip6tables -t mangle -I PREROUTING 1 -m rpfilter --invert -j DROP" 1002 run_cmd "$IP nexthop add id 91 via 2001:db8:91::2 dev veth1" 1003 run_cmd "$IP nexthop add id 92 via 2001:db8:92::2 dev veth3" 1004 run_cmd "$IP nexthop add id 93 group 91/92" 1005 run_cmd "$IP -6 ro add default nhid 91" 1006 run_cmd "ip netns exec me ping -c1 -w1 2001:db8:101::1" 1007 log_test $? 0 "Nexthop with default route and rpfilter" 1008 run_cmd "$IP -6 ro replace default nhid 93" 1009 run_cmd "ip netns exec me ping -c1 -w1 2001:db8:101::1" 1010 log_test $? 0 "Nexthop with multipath default route and rpfilter" 1011 1012 # TO-DO: 1013 # existing route with old nexthop; append route with new nexthop 1014 # existing route with old nexthop; replace route with new 1015 # existing route with new nexthop; replace route with old 1016 # route with src address and using nexthop - not allowed 1017} 1018 1019ipv6_large_grp() 1020{ 1021 local ecmp=32 1022 1023 echo 1024 echo "IPv6 large groups (x$ecmp)" 1025 echo "---------------------" 1026 1027 check_large_grp 6 $ecmp 1028 1029 $IP nexthop flush >/dev/null 2>&1 1030} 1031 1032ipv6_large_res_grp() 1033{ 1034 echo 1035 echo "IPv6 large resilient group (128k buckets)" 1036 echo "-----------------------------------------" 1037 1038 check_nexthop_res_support 1039 if [ $? -eq $ksft_skip ]; then 1040 return $ksft_skip 1041 fi 1042 1043 check_large_res_grp 6 $((128 * 1024)) 1044 1045 $IP nexthop flush >/dev/null 2>&1 1046} 1047 1048ipv6_del_add_loop1() 1049{ 1050 while :; do 1051 $IP nexthop del id 100 1052 $IP nexthop add id 100 via 2001:db8:91::2 dev veth1 1053 done >/dev/null 2>&1 1054} 1055 1056ipv6_grp_replace_loop() 1057{ 1058 while :; do 1059 $IP nexthop replace id 102 group 100/101 1060 done >/dev/null 2>&1 1061} 1062 1063ipv6_torture() 1064{ 1065 local pid1 1066 local pid2 1067 local pid3 1068 local pid4 1069 local pid5 1070 1071 echo 1072 echo "IPv6 runtime torture" 1073 echo "--------------------" 1074 if [ ! -x "$(command -v mausezahn)" ]; then 1075 echo "SKIP: Could not run test; need mausezahn tool" 1076 return 1077 fi 1078 1079 run_cmd "$IP nexthop add id 100 via 2001:db8:91::2 dev veth1" 1080 run_cmd "$IP nexthop add id 101 via 2001:db8:92::2 dev veth3" 1081 run_cmd "$IP nexthop add id 102 group 100/101" 1082 run_cmd "$IP route add 2001:db8:101::1 nhid 102" 1083 run_cmd "$IP route add 2001:db8:101::2 nhid 102" 1084 1085 ipv6_del_add_loop1 & 1086 pid1=$! 1087 ipv6_grp_replace_loop & 1088 pid2=$! 1089 ip netns exec me ping -f 2001:db8:101::1 >/dev/null 2>&1 & 1090 pid3=$! 1091 ip netns exec me ping -f 2001:db8:101::2 >/dev/null 2>&1 & 1092 pid4=$! 1093 ip netns exec me mausezahn -6 veth1 -B 2001:db8:101::2 -A 2001:db8:91::1 -c 0 -t tcp "dp=1-1023, flags=syn" >/dev/null 2>&1 & 1094 pid5=$! 1095 1096 sleep 300 1097 kill -9 $pid1 $pid2 $pid3 $pid4 $pid5 1098 wait $pid1 $pid2 $pid3 $pid4 $pid5 2>/dev/null 1099 1100 # if we did not crash, success 1101 log_test 0 0 "IPv6 torture test" 1102} 1103 1104ipv6_res_grp_replace_loop() 1105{ 1106 while :; do 1107 $IP nexthop replace id 102 group 100/101 type resilient 1108 done >/dev/null 2>&1 1109} 1110 1111ipv6_res_torture() 1112{ 1113 local pid1 1114 local pid2 1115 local pid3 1116 local pid4 1117 local pid5 1118 1119 echo 1120 echo "IPv6 runtime resilient nexthop group torture" 1121 echo "--------------------------------------------" 1122 1123 check_nexthop_res_support 1124 if [ $? -eq $ksft_skip ]; then 1125 return $ksft_skip 1126 fi 1127 1128 if [ ! -x "$(command -v mausezahn)" ]; then 1129 echo "SKIP: Could not run test; need mausezahn tool" 1130 return 1131 fi 1132 1133 run_cmd "$IP nexthop add id 100 via 2001:db8:91::2 dev veth1" 1134 run_cmd "$IP nexthop add id 101 via 2001:db8:92::2 dev veth3" 1135 run_cmd "$IP nexthop add id 102 group 100/101 type resilient buckets 512 idle_timer 0" 1136 run_cmd "$IP route add 2001:db8:101::1 nhid 102" 1137 run_cmd "$IP route add 2001:db8:101::2 nhid 102" 1138 1139 ipv6_del_add_loop1 & 1140 pid1=$! 1141 ipv6_res_grp_replace_loop & 1142 pid2=$! 1143 ip netns exec me ping -f 2001:db8:101::1 >/dev/null 2>&1 & 1144 pid3=$! 1145 ip netns exec me ping -f 2001:db8:101::2 >/dev/null 2>&1 & 1146 pid4=$! 1147 ip netns exec me mausezahn -6 veth1 \ 1148 -B 2001:db8:101::2 -A 2001:db8:91::1 -c 0 \ 1149 -t tcp "dp=1-1023, flags=syn" >/dev/null 2>&1 & 1150 pid5=$! 1151 1152 sleep 300 1153 kill -9 $pid1 $pid2 $pid3 $pid4 $pid5 1154 wait $pid1 $pid2 $pid3 $pid4 $pid5 2>/dev/null 1155 1156 # if we did not crash, success 1157 log_test 0 0 "IPv6 resilient nexthop group torture test" 1158} 1159 1160ipv4_fcnal() 1161{ 1162 local rc 1163 1164 echo 1165 echo "IPv4 functional" 1166 echo "----------------------" 1167 1168 # 1169 # basic IPv4 ops - add, get, delete 1170 # 1171 run_cmd "$IP nexthop add id 12 via 172.16.1.2 dev veth1" 1172 rc=$? 1173 log_test $rc 0 "Create nexthop with id, gw, dev" 1174 if [ $rc -ne 0 ]; then 1175 echo "Basic IPv4 create fails; can not continue" 1176 return 1 1177 fi 1178 1179 run_cmd "$IP nexthop get id 12" 1180 log_test $? 0 "Get nexthop by id" 1181 check_nexthop "id 12" "id 12 via 172.16.1.2 dev veth1 scope link" 1182 1183 run_cmd "$IP nexthop del id 12" 1184 log_test $? 0 "Delete nexthop by id" 1185 check_nexthop "id 52" "" 1186 1187 # 1188 # gw, device spec 1189 # 1190 # gw validation, no device - fails since dev is required 1191 run_cmd "$IP nexthop add id 12 via 172.16.2.3" 1192 log_test $? 2 "Create nexthop - gw only" 1193 1194 # gw not reachable through given dev 1195 run_cmd "$IP nexthop add id 13 via 172.16.3.2 dev veth1" 1196 log_test $? 2 "Create nexthop - invalid gw+dev combination" 1197 1198 # onlink flag overrides gw+dev lookup 1199 run_cmd "$IP nexthop add id 13 via 172.16.3.2 dev veth1 onlink" 1200 log_test $? 0 "Create nexthop - gw+dev and onlink" 1201 1202 # admin down should delete nexthops 1203 set -e 1204 run_cmd "$IP nexthop add id 15 via 172.16.1.3 dev veth1" 1205 run_cmd "$IP nexthop add id 16 via 172.16.1.4 dev veth1" 1206 run_cmd "$IP nexthop add id 17 via 172.16.1.5 dev veth1" 1207 run_cmd "$IP li set dev veth1 down" 1208 set +e 1209 check_nexthop "dev veth1" "" 1210 log_test $? 0 "Nexthops removed on admin down" 1211} 1212 1213ipv4_grp_fcnal() 1214{ 1215 local rc 1216 1217 echo 1218 echo "IPv4 groups functional" 1219 echo "----------------------" 1220 1221 # basic functionality: create a nexthop group, default weight 1222 run_cmd "$IP nexthop add id 11 via 172.16.1.2 dev veth1" 1223 run_cmd "$IP nexthop add id 101 group 11" 1224 log_test $? 0 "Create nexthop group with single nexthop" 1225 1226 # get nexthop group 1227 run_cmd "$IP nexthop get id 101" 1228 log_test $? 0 "Get nexthop group by id" 1229 check_nexthop "id 101" "id 101 group 11" 1230 1231 # delete nexthop group 1232 run_cmd "$IP nexthop del id 101" 1233 log_test $? 0 "Delete nexthop group by id" 1234 check_nexthop "id 101" "" 1235 1236 $IP nexthop flush >/dev/null 2>&1 1237 1238 # 1239 # create group with multiple nexthops 1240 run_cmd "$IP nexthop add id 12 via 172.16.1.2 dev veth1" 1241 run_cmd "$IP nexthop add id 13 via 172.16.1.3 dev veth1" 1242 run_cmd "$IP nexthop add id 14 via 172.16.1.4 dev veth1" 1243 run_cmd "$IP nexthop add id 15 via 172.16.1.5 dev veth1" 1244 run_cmd "$IP nexthop add id 102 group 12/13/14/15" 1245 log_test $? 0 "Nexthop group with multiple nexthops" 1246 check_nexthop "id 102" "id 102 group 12/13/14/15" 1247 1248 # Delete nexthop in a group and group is updated 1249 run_cmd "$IP nexthop del id 13" 1250 check_nexthop "id 102" "id 102 group 12/14/15" 1251 log_test $? 0 "Nexthop group updated when entry is deleted" 1252 1253 # create group with multiple weighted nexthops 1254 run_cmd "$IP nexthop add id 13 via 172.16.1.3 dev veth1" 1255 run_cmd "$IP nexthop add id 103 group 12/13,2/14,3/15,4" 1256 log_test $? 0 "Nexthop group with weighted nexthops" 1257 check_nexthop "id 103" "id 103 group 12/13,2/14,3/15,4" 1258 1259 # Delete nexthop in a weighted group and group is updated 1260 run_cmd "$IP nexthop del id 13" 1261 check_nexthop "id 103" "id 103 group 12/14,3/15,4" 1262 log_test $? 0 "Weighted nexthop group updated when entry is deleted" 1263 1264 # admin down - nexthop is removed from group 1265 run_cmd "$IP li set dev veth1 down" 1266 check_nexthop "dev veth1" "" 1267 log_test $? 0 "Nexthops in groups removed on admin down" 1268 1269 # expect groups to have been deleted as well 1270 check_nexthop "" "" 1271 1272 run_cmd "$IP li set dev veth1 up" 1273 1274 $IP nexthop flush >/dev/null 2>&1 1275 1276 # group with nexthops using different devices 1277 set -e 1278 run_cmd "$IP nexthop add id 12 via 172.16.1.2 dev veth1" 1279 run_cmd "$IP nexthop add id 13 via 172.16.1.3 dev veth1" 1280 run_cmd "$IP nexthop add id 14 via 172.16.1.4 dev veth1" 1281 run_cmd "$IP nexthop add id 15 via 172.16.1.5 dev veth1" 1282 1283 run_cmd "$IP nexthop add id 22 via 172.16.2.2 dev veth3" 1284 run_cmd "$IP nexthop add id 23 via 172.16.2.3 dev veth3" 1285 run_cmd "$IP nexthop add id 24 via 172.16.2.4 dev veth3" 1286 run_cmd "$IP nexthop add id 25 via 172.16.2.5 dev veth3" 1287 set +e 1288 1289 # multiple groups with same nexthop 1290 run_cmd "$IP nexthop add id 104 group 12" 1291 run_cmd "$IP nexthop add id 105 group 12" 1292 check_nexthop "group" "id 104 group 12 id 105 group 12" 1293 log_test $? 0 "Multiple groups with same nexthop" 1294 1295 run_cmd "$IP nexthop flush groups" 1296 [ $? -ne 0 ] && return 1 1297 1298 # on admin down of veth1, it should be removed from the group 1299 run_cmd "$IP nexthop add id 105 group 12/13/22/23/14" 1300 run_cmd "$IP li set veth1 down" 1301 check_nexthop "id 105" "id 105 group 22/23" 1302 log_test $? 0 "Nexthops in group removed on admin down - mixed group" 1303 1304 run_cmd "$IP nexthop add id 106 group 105/24" 1305 log_test $? 2 "Nexthop group can not have a group as an entry" 1306 1307 # a group can have a blackhole entry only if it is the only 1308 # nexthop in the group. Needed for atomic replace with an 1309 # actual nexthop group 1310 run_cmd "$IP nexthop add id 31 blackhole" 1311 run_cmd "$IP nexthop add id 107 group 31" 1312 log_test $? 0 "Nexthop group with a blackhole entry" 1313 1314 run_cmd "$IP nexthop add id 108 group 31/24" 1315 log_test $? 2 "Nexthop group can not have a blackhole and another nexthop" 1316} 1317 1318ipv4_res_grp_fcnal() 1319{ 1320 local rc 1321 1322 echo 1323 echo "IPv4 resilient groups functional" 1324 echo "--------------------------------" 1325 1326 check_nexthop_res_support 1327 if [ $? -eq $ksft_skip ]; then 1328 return $ksft_skip 1329 fi 1330 1331 # 1332 # migration of nexthop buckets - equal weights 1333 # 1334 run_cmd "$IP nexthop add id 12 via 172.16.1.2 dev veth1" 1335 run_cmd "$IP nexthop add id 13 via 172.16.1.3 dev veth1" 1336 run_cmd "$IP nexthop add id 102 group 12/13 type resilient buckets 2 idle_timer 0" 1337 1338 run_cmd "$IP nexthop del id 13" 1339 check_nexthop "id 102" \ 1340 "id 102 group 12 type resilient buckets 2 idle_timer 0 unbalanced_timer 0 unbalanced_time 0" 1341 log_test $? 0 "Nexthop group updated when entry is deleted" 1342 check_nexthop_bucket "list id 102" \ 1343 "id 102 index 0 nhid 12 id 102 index 1 nhid 12" 1344 log_test $? 0 "Nexthop buckets updated when entry is deleted" 1345 1346 run_cmd "$IP nexthop add id 13 via 172.16.1.3 dev veth1" 1347 run_cmd "$IP nexthop replace id 102 group 12/13 type resilient buckets 2 idle_timer 0" 1348 check_nexthop "id 102" \ 1349 "id 102 group 12/13 type resilient buckets 2 idle_timer 0 unbalanced_timer 0 unbalanced_time 0" 1350 log_test $? 0 "Nexthop group updated after replace" 1351 check_nexthop_bucket "list id 102" \ 1352 "id 102 index 0 nhid 13 id 102 index 1 nhid 12" 1353 log_test $? 0 "Nexthop buckets updated after replace" 1354 1355 $IP nexthop flush >/dev/null 2>&1 1356 1357 # 1358 # migration of nexthop buckets - unequal weights 1359 # 1360 run_cmd "$IP nexthop add id 12 via 172.16.1.2 dev veth1" 1361 run_cmd "$IP nexthop add id 13 via 172.16.1.3 dev veth1" 1362 run_cmd "$IP nexthop add id 102 group 12,3/13,1 type resilient buckets 4 idle_timer 0" 1363 1364 run_cmd "$IP nexthop del id 13" 1365 check_nexthop "id 102" \ 1366 "id 102 group 12,3 type resilient buckets 4 idle_timer 0 unbalanced_timer 0 unbalanced_time 0" 1367 log_test $? 0 "Nexthop group updated when entry is deleted - nECMP" 1368 check_nexthop_bucket "list id 102" \ 1369 "id 102 index 0 nhid 12 id 102 index 1 nhid 12 id 102 index 2 nhid 12 id 102 index 3 nhid 12" 1370 log_test $? 0 "Nexthop buckets updated when entry is deleted - nECMP" 1371 1372 run_cmd "$IP nexthop add id 13 via 172.16.1.3 dev veth1" 1373 run_cmd "$IP nexthop replace id 102 group 12,3/13,1 type resilient buckets 4 idle_timer 0" 1374 check_nexthop "id 102" \ 1375 "id 102 group 12,3/13 type resilient buckets 4 idle_timer 0 unbalanced_timer 0 unbalanced_time 0" 1376 log_test $? 0 "Nexthop group updated after replace - nECMP" 1377 check_nexthop_bucket "list id 102" \ 1378 "id 102 index 0 nhid 13 id 102 index 1 nhid 12 id 102 index 2 nhid 12 id 102 index 3 nhid 12" 1379 log_test $? 0 "Nexthop buckets updated after replace - nECMP" 1380} 1381 1382ipv4_withv6_fcnal() 1383{ 1384 local lladdr 1385 1386 set -e 1387 lladdr=$(get_linklocal veth2 peer) 1388 run_cmd "$IP nexthop add id 11 via ${lladdr} dev veth1" 1389 set +e 1390 run_cmd "$IP ro add 172.16.101.1/32 nhid 11" 1391 log_test $? 0 "IPv6 nexthop with IPv4 route" 1392 check_route "172.16.101.1" "172.16.101.1 nhid 11 via inet6 ${lladdr} dev veth1" 1393 1394 set -e 1395 run_cmd "$IP nexthop add id 12 via 172.16.1.2 dev veth1" 1396 run_cmd "$IP nexthop add id 101 group 11/12" 1397 set +e 1398 run_cmd "$IP ro replace 172.16.101.1/32 nhid 101" 1399 log_test $? 0 "IPv6 nexthop with IPv4 route" 1400 1401 check_route "172.16.101.1" "172.16.101.1 nhid 101 nexthop via inet6 ${lladdr} dev veth1 weight 1 nexthop via 172.16.1.2 dev veth1 weight 1" 1402 1403 run_cmd "$IP ro replace 172.16.101.1/32 via inet6 ${lladdr} dev veth1" 1404 log_test $? 0 "IPv4 route with IPv6 gateway" 1405 check_route "172.16.101.1" "172.16.101.1 via inet6 ${lladdr} dev veth1" 1406 1407 run_cmd "$IP ro replace 172.16.101.1/32 via inet6 2001:db8:50::1 dev veth1" 1408 log_test $? 2 "IPv4 route with invalid IPv6 gateway" 1409} 1410 1411ipv4_fcnal_runtime() 1412{ 1413 local lladdr 1414 local rc 1415 1416 echo 1417 echo "IPv4 functional runtime" 1418 echo "-----------------------" 1419 1420 run_cmd "$IP nexthop add id 21 via 172.16.1.2 dev veth1" 1421 run_cmd "$IP ro add 172.16.101.1/32 nhid 21" 1422 log_test $? 0 "Route add" 1423 check_route "172.16.101.1" "172.16.101.1 nhid 21 via 172.16.1.2 dev veth1" 1424 1425 run_cmd "$IP ro delete 172.16.101.1/32 nhid 21" 1426 log_test $? 0 "Route delete" 1427 1428 # 1429 # scope mismatch 1430 # 1431 run_cmd "$IP nexthop add id 22 via 172.16.1.2 dev veth1" 1432 run_cmd "$IP ro add 172.16.101.1/32 nhid 22 scope host" 1433 log_test $? 2 "Route add - scope conflict with nexthop" 1434 1435 run_cmd "$IP nexthop replace id 22 dev veth3" 1436 run_cmd "$IP ro add 172.16.101.1/32 nhid 22 scope host" 1437 run_cmd "$IP nexthop replace id 22 via 172.16.2.2 dev veth3" 1438 log_test $? 2 "Nexthop replace with invalid scope for existing route" 1439 1440 # check cleanup path on invalid metric 1441 run_cmd "$IP ro add 172.16.101.2/32 nhid 22 congctl lock foo" 1442 log_test $? 2 "IPv4 route with invalid metric" 1443 1444 # 1445 # add route with nexthop and check traffic 1446 # 1447 run_cmd "$IP nexthop replace id 21 via 172.16.1.2 dev veth1" 1448 run_cmd "$IP ro replace 172.16.101.1/32 nhid 21" 1449 run_cmd "ip netns exec me ping -c1 -w1 172.16.101.1" 1450 log_test $? 0 "Basic ping" 1451 1452 run_cmd "$IP nexthop replace id 22 via 172.16.2.2 dev veth3" 1453 run_cmd "$IP nexthop add id 122 group 21/22" 1454 run_cmd "$IP ro replace 172.16.101.1/32 nhid 122" 1455 run_cmd "ip netns exec me ping -c1 -w1 172.16.101.1" 1456 log_test $? 0 "Ping - multipath" 1457 1458 run_cmd "$IP ro delete 172.16.101.1/32 nhid 122" 1459 1460 # 1461 # multiple default routes 1462 # - tests fib_select_default 1463 run_cmd "$IP nexthop add id 501 via 172.16.1.2 dev veth1" 1464 run_cmd "$IP ro add default nhid 501" 1465 run_cmd "$IP ro add default via 172.16.1.3 dev veth1 metric 20" 1466 run_cmd "ip netns exec me ping -c1 -w1 172.16.101.1" 1467 log_test $? 0 "Ping - multiple default routes, nh first" 1468 1469 # flip the order 1470 run_cmd "$IP ro del default nhid 501" 1471 run_cmd "$IP ro del default via 172.16.1.3 dev veth1 metric 20" 1472 run_cmd "$IP ro add default via 172.16.1.2 dev veth1 metric 20" 1473 run_cmd "$IP nexthop replace id 501 via 172.16.1.3 dev veth1" 1474 run_cmd "$IP ro add default nhid 501 metric 20" 1475 run_cmd "ip netns exec me ping -c1 -w1 172.16.101.1" 1476 log_test $? 0 "Ping - multiple default routes, nh second" 1477 1478 run_cmd "$IP nexthop delete nhid 501" 1479 run_cmd "$IP ro del default" 1480 1481 # 1482 # IPv4 with blackhole nexthops 1483 # 1484 run_cmd "$IP nexthop add id 23 blackhole" 1485 run_cmd "$IP ro replace 172.16.101.1/32 nhid 23" 1486 run_cmd "ip netns exec me ping -c1 -w1 172.16.101.1" 1487 log_test $? 2 "Ping - blackhole" 1488 1489 run_cmd "$IP nexthop replace id 23 via 172.16.1.2 dev veth1" 1490 run_cmd "ip netns exec me ping -c1 -w1 172.16.101.1" 1491 log_test $? 0 "Ping - blackhole replaced with gateway" 1492 1493 run_cmd "$IP nexthop replace id 23 blackhole" 1494 run_cmd "ip netns exec me ping -c1 -w1 172.16.101.1" 1495 log_test $? 2 "Ping - gateway replaced by blackhole" 1496 1497 run_cmd "$IP ro replace 172.16.101.1/32 nhid 122" 1498 run_cmd "ip netns exec me ping -c1 -w1 172.16.101.1" 1499 if [ $? -eq 0 ]; then 1500 run_cmd "$IP nexthop replace id 122 group 23" 1501 run_cmd "ip netns exec me ping -c1 -w1 172.16.101.1" 1502 log_test $? 2 "Ping - group with blackhole" 1503 1504 run_cmd "$IP nexthop replace id 122 group 21/22" 1505 run_cmd "ip netns exec me ping -c1 -w1 172.16.101.1" 1506 log_test $? 0 "Ping - group blackhole replaced with gateways" 1507 else 1508 log_test 2 0 "Ping - multipath failed" 1509 fi 1510 1511 # 1512 # device only and gw + dev only mix 1513 # 1514 run_cmd "$IP nexthop add id 85 dev veth1" 1515 run_cmd "$IP ro replace 172.16.101.1/32 nhid 85" 1516 log_test $? 0 "IPv4 route with device only nexthop" 1517 check_route "172.16.101.1" "172.16.101.1 nhid 85 dev veth1" 1518 1519 run_cmd "$IP nexthop add id 123 group 21/85" 1520 run_cmd "$IP ro replace 172.16.101.1/32 nhid 123" 1521 log_test $? 0 "IPv4 multipath route with nexthop mix - dev only + gw" 1522 check_route "172.16.101.1" "172.16.101.1 nhid 123 nexthop via 172.16.1.2 dev veth1 weight 1 nexthop dev veth1 weight 1" 1523 1524 # 1525 # IPv4 with IPv6 1526 # 1527 set -e 1528 lladdr=$(get_linklocal veth2 peer) 1529 run_cmd "$IP nexthop add id 24 via ${lladdr} dev veth1" 1530 set +e 1531 run_cmd "$IP ro replace 172.16.101.1/32 nhid 24" 1532 run_cmd "ip netns exec me ping -c1 -w1 172.16.101.1" 1533 log_test $? 0 "IPv6 nexthop with IPv4 route" 1534 1535 $IP neigh sh | grep -q "${lladdr} dev veth1" 1536 if [ $? -eq 1 ]; then 1537 echo " WARNING: Neigh entry missing for ${lladdr}" 1538 $IP neigh sh | grep 'dev veth1' 1539 fi 1540 1541 $IP neigh sh | grep -q "172.16.101.1 dev eth1" 1542 if [ $? -eq 0 ]; then 1543 echo " WARNING: Neigh entry exists for 172.16.101.1" 1544 $IP neigh sh | grep 'dev veth1' 1545 fi 1546 1547 set -e 1548 run_cmd "$IP nexthop add id 25 via 172.16.1.2 dev veth1" 1549 run_cmd "$IP nexthop add id 101 group 24/25" 1550 set +e 1551 run_cmd "$IP ro replace 172.16.101.1/32 nhid 101" 1552 log_test $? 0 "IPv4 route with mixed v4-v6 multipath route" 1553 1554 check_route "172.16.101.1" "172.16.101.1 nhid 101 nexthop via inet6 ${lladdr} dev veth1 weight 1 nexthop via 172.16.1.2 dev veth1 weight 1" 1555 1556 run_cmd "ip netns exec me ping -c1 -w1 172.16.101.1" 1557 log_test $? 0 "IPv6 nexthop with IPv4 route" 1558 1559 run_cmd "$IP ro replace 172.16.101.1/32 via inet6 ${lladdr} dev veth1" 1560 run_cmd "ip netns exec me ping -c1 -w1 172.16.101.1" 1561 log_test $? 0 "IPv4 route with IPv6 gateway" 1562 1563 $IP neigh sh | grep -q "${lladdr} dev veth1" 1564 if [ $? -eq 1 ]; then 1565 echo " WARNING: Neigh entry missing for ${lladdr}" 1566 $IP neigh sh | grep 'dev veth1' 1567 fi 1568 1569 $IP neigh sh | grep -q "172.16.101.1 dev eth1" 1570 if [ $? -eq 0 ]; then 1571 echo " WARNING: Neigh entry exists for 172.16.101.1" 1572 $IP neigh sh | grep 'dev veth1' 1573 fi 1574 1575 run_cmd "$IP ro del 172.16.101.1/32 via inet6 ${lladdr} dev veth1" 1576 run_cmd "$IP -4 ro add default via inet6 ${lladdr} dev veth1" 1577 run_cmd "ip netns exec me ping -c1 -w1 172.16.101.1" 1578 log_test $? 0 "IPv4 default route with IPv6 gateway" 1579 1580 # 1581 # MPLS as an example of LWT encap 1582 # 1583 run_cmd "$IP nexthop add id 51 encap mpls 101 via 172.16.1.2 dev veth1" 1584 log_test $? 0 "IPv4 route with MPLS encap" 1585 check_nexthop "id 51" "id 51 encap mpls 101 via 172.16.1.2 dev veth1 scope link" 1586 log_test $? 0 "IPv4 route with MPLS encap - check" 1587 1588 run_cmd "$IP nexthop add id 52 encap mpls 102 via inet6 2001:db8:91::2 dev veth1" 1589 log_test $? 0 "IPv4 route with MPLS encap and v6 gateway" 1590 check_nexthop "id 52" "id 52 encap mpls 102 via 2001:db8:91::2 dev veth1 scope link" 1591 log_test $? 0 "IPv4 route with MPLS encap, v6 gw - check" 1592} 1593 1594ipv4_large_grp() 1595{ 1596 local ecmp=32 1597 1598 echo 1599 echo "IPv4 large groups (x$ecmp)" 1600 echo "---------------------" 1601 1602 check_large_grp 4 $ecmp 1603 1604 $IP nexthop flush >/dev/null 2>&1 1605} 1606 1607ipv4_large_res_grp() 1608{ 1609 echo 1610 echo "IPv4 large resilient group (128k buckets)" 1611 echo "-----------------------------------------" 1612 1613 check_nexthop_res_support 1614 if [ $? -eq $ksft_skip ]; then 1615 return $ksft_skip 1616 fi 1617 1618 check_large_res_grp 4 $((128 * 1024)) 1619 1620 $IP nexthop flush >/dev/null 2>&1 1621} 1622 1623sysctl_nexthop_compat_mode_check() 1624{ 1625 local sysctlname="net.ipv4.nexthop_compat_mode" 1626 local lprefix=$1 1627 1628 IPE="ip netns exec me" 1629 1630 $IPE sysctl -q $sysctlname 2>&1 >/dev/null 1631 if [ $? -ne 0 ]; then 1632 echo "SKIP: kernel lacks nexthop compat mode sysctl control" 1633 return $ksft_skip 1634 fi 1635 1636 out=$($IPE sysctl $sysctlname 2>/dev/null) 1637 log_test $? 0 "$lprefix default nexthop compat mode check" 1638 check_output "${out}" "$sysctlname = 1" 1639} 1640 1641sysctl_nexthop_compat_mode_set() 1642{ 1643 local sysctlname="net.ipv4.nexthop_compat_mode" 1644 local mode=$1 1645 local lprefix=$2 1646 1647 IPE="ip netns exec me" 1648 1649 out=$($IPE sysctl -w $sysctlname=$mode) 1650 log_test $? 0 "$lprefix set compat mode - $mode" 1651 check_output "${out}" "net.ipv4.nexthop_compat_mode = $mode" 1652} 1653 1654ipv6_compat_mode() 1655{ 1656 local rc 1657 1658 echo 1659 echo "IPv6 nexthop api compat mode test" 1660 echo "--------------------------------" 1661 1662 sysctl_nexthop_compat_mode_check "IPv6" 1663 if [ $? -eq $ksft_skip ]; then 1664 return $ksft_skip 1665 fi 1666 1667 run_cmd "$IP nexthop add id 62 via 2001:db8:91::2 dev veth1" 1668 run_cmd "$IP nexthop add id 63 via 2001:db8:91::3 dev veth1" 1669 run_cmd "$IP nexthop add id 122 group 62/63" 1670 ipmout=$(start_ip_monitor route) 1671 1672 run_cmd "$IP -6 ro add 2001:db8:101::1/128 nhid 122" 1673 # route add notification should contain expanded nexthops 1674 stop_ip_monitor $ipmout 3 1675 log_test $? 0 "IPv6 compat mode on - route add notification" 1676 1677 # route dump should contain expanded nexthops 1678 check_route6 "2001:db8:101::1" "2001:db8:101::1 nhid 122 metric 1024 nexthop via 2001:db8:91::2 dev veth1 weight 1 nexthop via 2001:db8:91::3 dev veth1 weight 1" 1679 log_test $? 0 "IPv6 compat mode on - route dump" 1680 1681 # change in nexthop group should generate route notification 1682 run_cmd "$IP nexthop add id 64 via 2001:db8:91::4 dev veth1" 1683 ipmout=$(start_ip_monitor route) 1684 run_cmd "$IP nexthop replace id 122 group 62/64" 1685 stop_ip_monitor $ipmout 3 1686 1687 log_test $? 0 "IPv6 compat mode on - nexthop change" 1688 1689 # set compat mode off 1690 sysctl_nexthop_compat_mode_set 0 "IPv6" 1691 1692 run_cmd "$IP -6 ro del 2001:db8:101::1/128 nhid 122" 1693 1694 run_cmd "$IP nexthop add id 62 via 2001:db8:91::2 dev veth1" 1695 run_cmd "$IP nexthop add id 63 via 2001:db8:91::3 dev veth1" 1696 run_cmd "$IP nexthop add id 122 group 62/63" 1697 ipmout=$(start_ip_monitor route) 1698 1699 run_cmd "$IP -6 ro add 2001:db8:101::1/128 nhid 122" 1700 # route add notification should not contain expanded nexthops 1701 stop_ip_monitor $ipmout 1 1702 log_test $? 0 "IPv6 compat mode off - route add notification" 1703 1704 # route dump should not contain expanded nexthops 1705 check_route6 "2001:db8:101::1" "2001:db8:101::1 nhid 122 metric 1024" 1706 log_test $? 0 "IPv6 compat mode off - route dump" 1707 1708 # change in nexthop group should not generate route notification 1709 run_cmd "$IP nexthop add id 64 via 2001:db8:91::4 dev veth1" 1710 ipmout=$(start_ip_monitor route) 1711 run_cmd "$IP nexthop replace id 122 group 62/64" 1712 stop_ip_monitor $ipmout 0 1713 log_test $? 0 "IPv6 compat mode off - nexthop change" 1714 1715 # nexthop delete should not generate route notification 1716 ipmout=$(start_ip_monitor route) 1717 run_cmd "$IP nexthop del id 122" 1718 stop_ip_monitor $ipmout 0 1719 log_test $? 0 "IPv6 compat mode off - nexthop delete" 1720 1721 # set compat mode back on 1722 sysctl_nexthop_compat_mode_set 1 "IPv6" 1723} 1724 1725ipv4_compat_mode() 1726{ 1727 local rc 1728 1729 echo 1730 echo "IPv4 nexthop api compat mode" 1731 echo "----------------------------" 1732 1733 sysctl_nexthop_compat_mode_check "IPv4" 1734 if [ $? -eq $ksft_skip ]; then 1735 return $ksft_skip 1736 fi 1737 1738 run_cmd "$IP nexthop add id 21 via 172.16.1.2 dev veth1" 1739 run_cmd "$IP nexthop add id 22 via 172.16.1.2 dev veth1" 1740 run_cmd "$IP nexthop add id 122 group 21/22" 1741 ipmout=$(start_ip_monitor route) 1742 1743 run_cmd "$IP ro add 172.16.101.1/32 nhid 122" 1744 stop_ip_monitor $ipmout 3 1745 1746 # route add notification should contain expanded nexthops 1747 log_test $? 0 "IPv4 compat mode on - route add notification" 1748 1749 # route dump should contain expanded nexthops 1750 check_route "172.16.101.1" "172.16.101.1 nhid 122 nexthop via 172.16.1.2 dev veth1 weight 1 nexthop via 172.16.1.2 dev veth1 weight 1" 1751 log_test $? 0 "IPv4 compat mode on - route dump" 1752 1753 # change in nexthop group should generate route notification 1754 run_cmd "$IP nexthop add id 23 via 172.16.1.3 dev veth1" 1755 ipmout=$(start_ip_monitor route) 1756 run_cmd "$IP nexthop replace id 122 group 21/23" 1757 stop_ip_monitor $ipmout 3 1758 log_test $? 0 "IPv4 compat mode on - nexthop change" 1759 1760 sysctl_nexthop_compat_mode_set 0 "IPv4" 1761 1762 # cleanup 1763 run_cmd "$IP ro del 172.16.101.1/32 nhid 122" 1764 1765 ipmout=$(start_ip_monitor route) 1766 run_cmd "$IP ro add 172.16.101.1/32 nhid 122" 1767 stop_ip_monitor $ipmout 1 1768 # route add notification should not contain expanded nexthops 1769 log_test $? 0 "IPv4 compat mode off - route add notification" 1770 1771 # route dump should not contain expanded nexthops 1772 check_route "172.16.101.1" "172.16.101.1 nhid 122" 1773 log_test $? 0 "IPv4 compat mode off - route dump" 1774 1775 # change in nexthop group should not generate route notification 1776 ipmout=$(start_ip_monitor route) 1777 run_cmd "$IP nexthop replace id 122 group 21/22" 1778 stop_ip_monitor $ipmout 0 1779 log_test $? 0 "IPv4 compat mode off - nexthop change" 1780 1781 # nexthop delete should not generate route notification 1782 ipmout=$(start_ip_monitor route) 1783 run_cmd "$IP nexthop del id 122" 1784 stop_ip_monitor $ipmout 0 1785 log_test $? 0 "IPv4 compat mode off - nexthop delete" 1786 1787 sysctl_nexthop_compat_mode_set 1 "IPv4" 1788} 1789 1790ipv4_del_add_loop1() 1791{ 1792 while :; do 1793 $IP nexthop del id 100 1794 $IP nexthop add id 100 via 172.16.1.2 dev veth1 1795 done >/dev/null 2>&1 1796} 1797 1798ipv4_grp_replace_loop() 1799{ 1800 while :; do 1801 $IP nexthop replace id 102 group 100/101 1802 done >/dev/null 2>&1 1803} 1804 1805ipv4_torture() 1806{ 1807 local pid1 1808 local pid2 1809 local pid3 1810 local pid4 1811 local pid5 1812 1813 echo 1814 echo "IPv4 runtime torture" 1815 echo "--------------------" 1816 if [ ! -x "$(command -v mausezahn)" ]; then 1817 echo "SKIP: Could not run test; need mausezahn tool" 1818 return 1819 fi 1820 1821 run_cmd "$IP nexthop add id 100 via 172.16.1.2 dev veth1" 1822 run_cmd "$IP nexthop add id 101 via 172.16.2.2 dev veth3" 1823 run_cmd "$IP nexthop add id 102 group 100/101" 1824 run_cmd "$IP route add 172.16.101.1 nhid 102" 1825 run_cmd "$IP route add 172.16.101.2 nhid 102" 1826 1827 ipv4_del_add_loop1 & 1828 pid1=$! 1829 ipv4_grp_replace_loop & 1830 pid2=$! 1831 ip netns exec me ping -f 172.16.101.1 >/dev/null 2>&1 & 1832 pid3=$! 1833 ip netns exec me ping -f 172.16.101.2 >/dev/null 2>&1 & 1834 pid4=$! 1835 ip netns exec me mausezahn veth1 -B 172.16.101.2 -A 172.16.1.1 -c 0 -t tcp "dp=1-1023, flags=syn" >/dev/null 2>&1 & 1836 pid5=$! 1837 1838 sleep 300 1839 kill -9 $pid1 $pid2 $pid3 $pid4 $pid5 1840 wait $pid1 $pid2 $pid3 $pid4 $pid5 2>/dev/null 1841 1842 # if we did not crash, success 1843 log_test 0 0 "IPv4 torture test" 1844} 1845 1846ipv4_res_grp_replace_loop() 1847{ 1848 while :; do 1849 $IP nexthop replace id 102 group 100/101 type resilient 1850 done >/dev/null 2>&1 1851} 1852 1853ipv4_res_torture() 1854{ 1855 local pid1 1856 local pid2 1857 local pid3 1858 local pid4 1859 local pid5 1860 1861 echo 1862 echo "IPv4 runtime resilient nexthop group torture" 1863 echo "--------------------------------------------" 1864 1865 check_nexthop_res_support 1866 if [ $? -eq $ksft_skip ]; then 1867 return $ksft_skip 1868 fi 1869 1870 if [ ! -x "$(command -v mausezahn)" ]; then 1871 echo "SKIP: Could not run test; need mausezahn tool" 1872 return 1873 fi 1874 1875 run_cmd "$IP nexthop add id 100 via 172.16.1.2 dev veth1" 1876 run_cmd "$IP nexthop add id 101 via 172.16.2.2 dev veth3" 1877 run_cmd "$IP nexthop add id 102 group 100/101 type resilient buckets 512 idle_timer 0" 1878 run_cmd "$IP route add 172.16.101.1 nhid 102" 1879 run_cmd "$IP route add 172.16.101.2 nhid 102" 1880 1881 ipv4_del_add_loop1 & 1882 pid1=$! 1883 ipv4_res_grp_replace_loop & 1884 pid2=$! 1885 ip netns exec me ping -f 172.16.101.1 >/dev/null 2>&1 & 1886 pid3=$! 1887 ip netns exec me ping -f 172.16.101.2 >/dev/null 2>&1 & 1888 pid4=$! 1889 ip netns exec me mausezahn veth1 \ 1890 -B 172.16.101.2 -A 172.16.1.1 -c 0 \ 1891 -t tcp "dp=1-1023, flags=syn" >/dev/null 2>&1 & 1892 pid5=$! 1893 1894 sleep 300 1895 kill -9 $pid1 $pid2 $pid3 $pid4 $pid5 1896 wait $pid1 $pid2 $pid3 $pid4 $pid5 2>/dev/null 1897 1898 # if we did not crash, success 1899 log_test 0 0 "IPv4 resilient nexthop group torture test" 1900} 1901 1902basic() 1903{ 1904 echo 1905 echo "Basic functional tests" 1906 echo "----------------------" 1907 run_cmd "$IP nexthop ls" 1908 log_test $? 0 "List with nothing defined" 1909 1910 run_cmd "$IP nexthop get id 1" 1911 log_test $? 2 "Nexthop get on non-existent id" 1912 1913 # attempt to create nh without a device or gw - fails 1914 run_cmd "$IP nexthop add id 1" 1915 log_test $? 2 "Nexthop with no device or gateway" 1916 1917 # attempt to create nh with down device - fails 1918 $IP li set veth1 down 1919 run_cmd "$IP nexthop add id 1 dev veth1" 1920 log_test $? 2 "Nexthop with down device" 1921 1922 # create nh with linkdown device - fails 1923 $IP li set veth1 up 1924 ip -netns peer li set veth2 down 1925 run_cmd "$IP nexthop add id 1 dev veth1" 1926 log_test $? 2 "Nexthop with device that is linkdown" 1927 ip -netns peer li set veth2 up 1928 1929 # device only 1930 run_cmd "$IP nexthop add id 1 dev veth1" 1931 log_test $? 0 "Nexthop with device only" 1932 1933 # create nh with duplicate id 1934 run_cmd "$IP nexthop add id 1 dev veth3" 1935 log_test $? 2 "Nexthop with duplicate id" 1936 1937 # blackhole nexthop 1938 run_cmd "$IP nexthop add id 2 blackhole" 1939 log_test $? 0 "Blackhole nexthop" 1940 1941 # blackhole nexthop can not have other specs 1942 run_cmd "$IP nexthop replace id 2 blackhole dev veth1" 1943 log_test $? 2 "Blackhole nexthop with other attributes" 1944 1945 # blackhole nexthop should not be affected by the state of the loopback 1946 # device 1947 run_cmd "$IP link set dev lo down" 1948 check_nexthop "id 2" "id 2 blackhole" 1949 log_test $? 0 "Blackhole nexthop with loopback device down" 1950 1951 run_cmd "$IP link set dev lo up" 1952 1953 # 1954 # groups 1955 # 1956 1957 run_cmd "$IP nexthop add id 101 group 1" 1958 log_test $? 0 "Create group" 1959 1960 run_cmd "$IP nexthop add id 102 group 2" 1961 log_test $? 0 "Create group with blackhole nexthop" 1962 1963 # multipath group can not have a blackhole as 1 path 1964 run_cmd "$IP nexthop add id 103 group 1/2" 1965 log_test $? 2 "Create multipath group where 1 path is a blackhole" 1966 1967 # multipath group can not have a member replaced by a blackhole 1968 run_cmd "$IP nexthop replace id 2 dev veth3" 1969 run_cmd "$IP nexthop replace id 102 group 1/2" 1970 run_cmd "$IP nexthop replace id 2 blackhole" 1971 log_test $? 2 "Multipath group can not have a member replaced by blackhole" 1972 1973 # attempt to create group with non-existent nexthop 1974 run_cmd "$IP nexthop add id 103 group 12" 1975 log_test $? 2 "Create group with non-existent nexthop" 1976 1977 # attempt to create group with same nexthop 1978 run_cmd "$IP nexthop add id 103 group 1/1" 1979 log_test $? 2 "Create group with same nexthop multiple times" 1980 1981 # replace nexthop with a group - fails 1982 run_cmd "$IP nexthop replace id 2 group 1" 1983 log_test $? 2 "Replace nexthop with nexthop group" 1984 1985 # replace nexthop group with a nexthop - fails 1986 run_cmd "$IP nexthop replace id 101 dev veth1" 1987 log_test $? 2 "Replace nexthop group with nexthop" 1988 1989 # nexthop group with other attributes fail 1990 run_cmd "$IP nexthop add id 104 group 1 dev veth1" 1991 log_test $? 2 "Nexthop group and device" 1992 1993 # Tests to ensure that flushing works as expected. 1994 run_cmd "$IP nexthop add id 105 blackhole proto 99" 1995 run_cmd "$IP nexthop add id 106 blackhole proto 100" 1996 run_cmd "$IP nexthop add id 107 blackhole proto 99" 1997 run_cmd "$IP nexthop flush proto 99" 1998 check_nexthop "id 105" "" 1999 check_nexthop "id 106" "id 106 blackhole proto 100" 2000 check_nexthop "id 107" "" 2001 run_cmd "$IP nexthop flush proto 100" 2002 check_nexthop "id 106" "" 2003 2004 run_cmd "$IP nexthop flush proto 100" 2005 log_test $? 0 "Test proto flush" 2006 2007 run_cmd "$IP nexthop add id 104 group 1 blackhole" 2008 log_test $? 2 "Nexthop group and blackhole" 2009 2010 $IP nexthop flush >/dev/null 2>&1 2011 2012 # Test to ensure that flushing with a multi-part nexthop dump works as 2013 # expected. 2014 local batch_file=$(mktemp) 2015 2016 for i in $(seq 1 $((64 * 1024))); do 2017 echo "nexthop add id $i blackhole" >> $batch_file 2018 done 2019 2020 $IP -b $batch_file 2021 $IP nexthop flush >/dev/null 2>&1 2022 [[ $($IP nexthop | wc -l) -eq 0 ]] 2023 log_test $? 0 "Large scale nexthop flushing" 2024 2025 rm $batch_file 2026} 2027 2028check_nexthop_buckets_balance() 2029{ 2030 local nharg=$1; shift 2031 local ret 2032 2033 while (($# > 0)); do 2034 local selector=$1; shift 2035 local condition=$1; shift 2036 local count 2037 2038 count=$($IP -j nexthop bucket ${nharg} ${selector} | jq length) 2039 (( $count $condition )) 2040 ret=$? 2041 if ((ret != 0)); then 2042 return $ret 2043 fi 2044 done 2045 2046 return 0 2047} 2048 2049basic_res() 2050{ 2051 echo 2052 echo "Basic resilient nexthop group functional tests" 2053 echo "----------------------------------------------" 2054 2055 check_nexthop_res_support 2056 if [ $? -eq $ksft_skip ]; then 2057 return $ksft_skip 2058 fi 2059 2060 run_cmd "$IP nexthop add id 1 dev veth1" 2061 2062 # 2063 # resilient nexthop group addition 2064 # 2065 2066 run_cmd "$IP nexthop add id 101 group 1 type resilient buckets 8" 2067 log_test $? 0 "Add a nexthop group with default parameters" 2068 2069 run_cmd "$IP nexthop get id 101" 2070 check_nexthop "id 101" \ 2071 "id 101 group 1 type resilient buckets 8 idle_timer 120 unbalanced_timer 0 unbalanced_time 0" 2072 log_test $? 0 "Get a nexthop group with default parameters" 2073 2074 run_cmd "$IP nexthop add id 102 group 1 type resilient 2075 buckets 4 idle_timer 100 unbalanced_timer 5" 2076 run_cmd "$IP nexthop get id 102" 2077 check_nexthop "id 102" \ 2078 "id 102 group 1 type resilient buckets 4 idle_timer 100 unbalanced_timer 5 unbalanced_time 0" 2079 log_test $? 0 "Get a nexthop group with non-default parameters" 2080 2081 run_cmd "$IP nexthop add id 103 group 1 type resilient buckets 0" 2082 log_test $? 2 "Add a nexthop group with 0 buckets" 2083 2084 # 2085 # resilient nexthop group replacement 2086 # 2087 2088 run_cmd "$IP nexthop replace id 101 group 1 type resilient 2089 buckets 8 idle_timer 240 unbalanced_timer 80" 2090 log_test $? 0 "Replace nexthop group parameters" 2091 check_nexthop "id 101" \ 2092 "id 101 group 1 type resilient buckets 8 idle_timer 240 unbalanced_timer 80 unbalanced_time 0" 2093 log_test $? 0 "Get a nexthop group after replacing parameters" 2094 2095 run_cmd "$IP nexthop replace id 101 group 1 type resilient idle_timer 512" 2096 log_test $? 0 "Replace idle timer" 2097 check_nexthop "id 101" \ 2098 "id 101 group 1 type resilient buckets 8 idle_timer 512 unbalanced_timer 80 unbalanced_time 0" 2099 log_test $? 0 "Get a nexthop group after replacing idle timer" 2100 2101 run_cmd "$IP nexthop replace id 101 group 1 type resilient unbalanced_timer 256" 2102 log_test $? 0 "Replace unbalanced timer" 2103 check_nexthop "id 101" \ 2104 "id 101 group 1 type resilient buckets 8 idle_timer 512 unbalanced_timer 256 unbalanced_time 0" 2105 log_test $? 0 "Get a nexthop group after replacing unbalanced timer" 2106 2107 run_cmd "$IP nexthop replace id 101 group 1 type resilient" 2108 log_test $? 0 "Replace with no parameters" 2109 check_nexthop "id 101" \ 2110 "id 101 group 1 type resilient buckets 8 idle_timer 512 unbalanced_timer 256 unbalanced_time 0" 2111 log_test $? 0 "Get a nexthop group after replacing no parameters" 2112 2113 run_cmd "$IP nexthop replace id 101 group 1" 2114 log_test $? 2 "Replace nexthop group type - implicit" 2115 2116 run_cmd "$IP nexthop replace id 101 group 1 type mpath" 2117 log_test $? 2 "Replace nexthop group type - explicit" 2118 2119 run_cmd "$IP nexthop replace id 101 group 1 type resilient buckets 1024" 2120 log_test $? 2 "Replace number of nexthop buckets" 2121 2122 check_nexthop "id 101" \ 2123 "id 101 group 1 type resilient buckets 8 idle_timer 512 unbalanced_timer 256 unbalanced_time 0" 2124 log_test $? 0 "Get a nexthop group after replacing with invalid parameters" 2125 2126 # 2127 # resilient nexthop buckets dump 2128 # 2129 2130 $IP nexthop flush >/dev/null 2>&1 2131 run_cmd "$IP nexthop add id 1 dev veth1" 2132 run_cmd "$IP nexthop add id 2 dev veth3" 2133 run_cmd "$IP nexthop add id 101 group 1/2 type resilient buckets 4" 2134 run_cmd "$IP nexthop add id 201 group 1/2" 2135 2136 check_nexthop_bucket "" \ 2137 "id 101 index 0 nhid 2 id 101 index 1 nhid 2 id 101 index 2 nhid 1 id 101 index 3 nhid 1" 2138 log_test $? 0 "Dump all nexthop buckets" 2139 2140 check_nexthop_bucket "list id 101" \ 2141 "id 101 index 0 nhid 2 id 101 index 1 nhid 2 id 101 index 2 nhid 1 id 101 index 3 nhid 1" 2142 log_test $? 0 "Dump all nexthop buckets in a group" 2143 2144 sleep 0.1 2145 (( $($IP -j nexthop bucket list id 101 | 2146 jq '[.[] | select(.bucket.idle_time > 0 and 2147 .bucket.idle_time < 2)] | length') == 4 )) 2148 log_test $? 0 "All nexthop buckets report a positive near-zero idle time" 2149 2150 check_nexthop_bucket "list dev veth1" \ 2151 "id 101 index 2 nhid 1 id 101 index 3 nhid 1" 2152 log_test $? 0 "Dump all nexthop buckets with a specific nexthop device" 2153 2154 check_nexthop_bucket "list nhid 2" \ 2155 "id 101 index 0 nhid 2 id 101 index 1 nhid 2" 2156 log_test $? 0 "Dump all nexthop buckets with a specific nexthop identifier" 2157 2158 run_cmd "$IP nexthop bucket list id 111" 2159 log_test $? 2 "Dump all nexthop buckets in a non-existent group" 2160 2161 run_cmd "$IP nexthop bucket list id 201" 2162 log_test $? 2 "Dump all nexthop buckets in a non-resilient group" 2163 2164 run_cmd "$IP nexthop bucket list dev bla" 2165 log_test $? 255 "Dump all nexthop buckets using a non-existent device" 2166 2167 run_cmd "$IP nexthop bucket list groups" 2168 log_test $? 255 "Dump all nexthop buckets with invalid 'groups' keyword" 2169 2170 run_cmd "$IP nexthop bucket list fdb" 2171 log_test $? 255 "Dump all nexthop buckets with invalid 'fdb' keyword" 2172 2173 # 2174 # resilient nexthop buckets get requests 2175 # 2176 2177 check_nexthop_bucket "get id 101 index 0" "id 101 index 0 nhid 2" 2178 log_test $? 0 "Get a valid nexthop bucket" 2179 2180 run_cmd "$IP nexthop bucket get id 101 index 999" 2181 log_test $? 2 "Get a nexthop bucket with valid group, but invalid index" 2182 2183 run_cmd "$IP nexthop bucket get id 201 index 0" 2184 log_test $? 2 "Get a nexthop bucket from a non-resilient group" 2185 2186 run_cmd "$IP nexthop bucket get id 999 index 0" 2187 log_test $? 2 "Get a nexthop bucket from a non-existent group" 2188 2189 # 2190 # tests for bucket migration 2191 # 2192 2193 $IP nexthop flush >/dev/null 2>&1 2194 2195 run_cmd "$IP nexthop add id 1 dev veth1" 2196 run_cmd "$IP nexthop add id 2 dev veth3" 2197 run_cmd "$IP nexthop add id 101 2198 group 1/2 type resilient buckets 10 2199 idle_timer 1 unbalanced_timer 20" 2200 2201 check_nexthop_buckets_balance "list id 101" \ 2202 "nhid 1" "== 5" \ 2203 "nhid 2" "== 5" 2204 log_test $? 0 "Initial bucket allocation" 2205 2206 run_cmd "$IP nexthop replace id 101 2207 group 1,2/2,3 type resilient" 2208 check_nexthop_buckets_balance "list id 101" \ 2209 "nhid 1" "== 4" \ 2210 "nhid 2" "== 6" 2211 log_test $? 0 "Bucket allocation after replace" 2212 2213 # Check that increase in idle timer does not make buckets appear busy. 2214 run_cmd "$IP nexthop replace id 101 2215 group 1,2/2,3 type resilient 2216 idle_timer 10" 2217 run_cmd "$IP nexthop replace id 101 2218 group 1/2 type resilient" 2219 check_nexthop_buckets_balance "list id 101" \ 2220 "nhid 1" "== 5" \ 2221 "nhid 2" "== 5" 2222 log_test $? 0 "Buckets migrated after idle timer change" 2223 2224 $IP nexthop flush >/dev/null 2>&1 2225} 2226 2227################################################################################ 2228# usage 2229 2230usage() 2231{ 2232 cat <<EOF 2233usage: ${0##*/} OPTS 2234 2235 -t <test> Test(s) to run (default: all) 2236 (options: $ALL_TESTS) 2237 -4 IPv4 tests only 2238 -6 IPv6 tests only 2239 -p Pause on fail 2240 -P Pause after each test before cleanup 2241 -v verbose mode (show commands and output) 2242 2243 Runtime test 2244 -n num Number of nexthops to target 2245 -N Use new style to install routes in DUT 2246 2247done 2248EOF 2249} 2250 2251################################################################################ 2252# main 2253 2254while getopts :t:pP46hv o 2255do 2256 case $o in 2257 t) TESTS=$OPTARG;; 2258 4) TESTS=${IPV4_TESTS};; 2259 6) TESTS=${IPV6_TESTS};; 2260 p) PAUSE_ON_FAIL=yes;; 2261 P) PAUSE=yes;; 2262 v) VERBOSE=$(($VERBOSE + 1));; 2263 h) usage; exit 0;; 2264 *) usage; exit 1;; 2265 esac 2266done 2267 2268# make sure we don't pause twice 2269[ "${PAUSE}" = "yes" ] && PAUSE_ON_FAIL=no 2270 2271if [ "$(id -u)" -ne 0 ];then 2272 echo "SKIP: Need root privileges" 2273 exit $ksft_skip; 2274fi 2275 2276if [ ! -x "$(command -v ip)" ]; then 2277 echo "SKIP: Could not run test without ip tool" 2278 exit $ksft_skip 2279fi 2280 2281ip help 2>&1 | grep -q nexthop 2282if [ $? -ne 0 ]; then 2283 echo "SKIP: iproute2 too old, missing nexthop command" 2284 exit $ksft_skip 2285fi 2286 2287out=$(ip nexthop ls 2>&1 | grep -q "Operation not supported") 2288if [ $? -eq 0 ]; then 2289 echo "SKIP: kernel lacks nexthop support" 2290 exit $ksft_skip 2291fi 2292 2293for t in $TESTS 2294do 2295 case $t in 2296 none) IP="ip -netns peer"; setup; exit 0;; 2297 *) setup; $t; cleanup;; 2298 esac 2299done 2300 2301if [ "$TESTS" != "none" ]; then 2302 printf "\nTests passed: %3d\n" ${nsuccess} 2303 printf "Tests failed: %3d\n" ${nfail} 2304fi 2305 2306exit $ret 2307