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