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_fcnal() 633{ 634 local rc 635 636 echo 637 echo "IPv6 groups functional" 638 echo "----------------------" 639 640 # basic functionality: create a nexthop group, default weight 641 run_cmd "$IP nexthop add id 61 via 2001:db8:91::2 dev veth1" 642 run_cmd "$IP nexthop add id 101 group 61" 643 log_test $? 0 "Create nexthop group with single nexthop" 644 645 # get nexthop group 646 run_cmd "$IP nexthop get id 101" 647 log_test $? 0 "Get nexthop group by id" 648 check_nexthop "id 101" "id 101 group 61" 649 650 # delete nexthop group 651 run_cmd "$IP nexthop del id 101" 652 log_test $? 0 "Delete nexthop group by id" 653 check_nexthop "id 101" "" 654 655 $IP nexthop flush >/dev/null 2>&1 656 check_nexthop "id 101" "" 657 658 # 659 # create group with multiple nexthops - mix of gw and dev only 660 # 661 run_cmd "$IP nexthop add id 62 via 2001:db8:91::2 dev veth1" 662 run_cmd "$IP nexthop add id 63 via 2001:db8:91::3 dev veth1" 663 run_cmd "$IP nexthop add id 64 via 2001:db8:91::4 dev veth1" 664 run_cmd "$IP nexthop add id 65 dev veth1" 665 run_cmd "$IP nexthop add id 102 group 62/63/64/65" 666 log_test $? 0 "Nexthop group with multiple nexthops" 667 check_nexthop "id 102" "id 102 group 62/63/64/65" 668 669 # Delete nexthop in a group and group is updated 670 run_cmd "$IP nexthop del id 63" 671 check_nexthop "id 102" "id 102 group 62/64/65" 672 log_test $? 0 "Nexthop group updated when entry is deleted" 673 674 # create group with multiple weighted nexthops 675 run_cmd "$IP nexthop add id 63 via 2001:db8:91::3 dev veth1" 676 run_cmd "$IP nexthop add id 103 group 62/63,2/64,3/65,4" 677 log_test $? 0 "Nexthop group with weighted nexthops" 678 check_nexthop "id 103" "id 103 group 62/63,2/64,3/65,4" 679 680 # Delete nexthop in a weighted group and group is updated 681 run_cmd "$IP nexthop del id 63" 682 check_nexthop "id 103" "id 103 group 62/64,3/65,4" 683 log_test $? 0 "Weighted nexthop group updated when entry is deleted" 684 685 # admin down - nexthop is removed from group 686 run_cmd "$IP li set dev veth1 down" 687 check_nexthop "dev veth1" "" 688 log_test $? 0 "Nexthops in groups removed on admin down" 689 690 # expect groups to have been deleted as well 691 check_nexthop "" "" 692 693 run_cmd "$IP li set dev veth1 up" 694 695 $IP nexthop flush >/dev/null 2>&1 696 697 # group with nexthops using different devices 698 set -e 699 run_cmd "$IP nexthop add id 62 via 2001:db8:91::2 dev veth1" 700 run_cmd "$IP nexthop add id 63 via 2001:db8:91::3 dev veth1" 701 run_cmd "$IP nexthop add id 64 via 2001:db8:91::4 dev veth1" 702 run_cmd "$IP nexthop add id 65 via 2001:db8:91::5 dev veth1" 703 704 run_cmd "$IP nexthop add id 72 via 2001:db8:92::2 dev veth3" 705 run_cmd "$IP nexthop add id 73 via 2001:db8:92::3 dev veth3" 706 run_cmd "$IP nexthop add id 74 via 2001:db8:92::4 dev veth3" 707 run_cmd "$IP nexthop add id 75 via 2001:db8:92::5 dev veth3" 708 set +e 709 710 # multiple groups with same nexthop 711 run_cmd "$IP nexthop add id 104 group 62" 712 run_cmd "$IP nexthop add id 105 group 62" 713 check_nexthop "group" "id 104 group 62 id 105 group 62" 714 log_test $? 0 "Multiple groups with same nexthop" 715 716 run_cmd "$IP nexthop flush groups" 717 [ $? -ne 0 ] && return 1 718 719 # on admin down of veth1, it should be removed from the group 720 run_cmd "$IP nexthop add id 105 group 62/63/72/73/64" 721 run_cmd "$IP li set veth1 down" 722 check_nexthop "id 105" "id 105 group 72/73" 723 log_test $? 0 "Nexthops in group removed on admin down - mixed group" 724 725 run_cmd "$IP nexthop add id 106 group 105/74" 726 log_test $? 2 "Nexthop group can not have a group as an entry" 727 728 # a group can have a blackhole entry only if it is the only 729 # nexthop in the group. Needed for atomic replace with an 730 # actual nexthop group 731 run_cmd "$IP -6 nexthop add id 31 blackhole" 732 run_cmd "$IP nexthop add id 107 group 31" 733 log_test $? 0 "Nexthop group with a blackhole entry" 734 735 run_cmd "$IP nexthop add id 108 group 31/24" 736 log_test $? 2 "Nexthop group can not have a blackhole and another nexthop" 737} 738 739ipv6_res_grp_fcnal() 740{ 741 local rc 742 743 echo 744 echo "IPv6 resilient groups functional" 745 echo "--------------------------------" 746 747 check_nexthop_res_support 748 if [ $? -eq $ksft_skip ]; then 749 return $ksft_skip 750 fi 751 752 # 753 # migration of nexthop buckets - equal weights 754 # 755 run_cmd "$IP nexthop add id 62 via 2001:db8:91::2 dev veth1" 756 run_cmd "$IP nexthop add id 63 via 2001:db8:91::3 dev veth1" 757 run_cmd "$IP nexthop add id 102 group 62/63 type resilient buckets 2 idle_timer 0" 758 759 run_cmd "$IP nexthop del id 63" 760 check_nexthop "id 102" \ 761 "id 102 group 62 type resilient buckets 2 idle_timer 0 unbalanced_timer 0 unbalanced_time 0" 762 log_test $? 0 "Nexthop group updated when entry is deleted" 763 check_nexthop_bucket "list id 102" \ 764 "id 102 index 0 nhid 62 id 102 index 1 nhid 62" 765 log_test $? 0 "Nexthop buckets updated when entry is deleted" 766 767 run_cmd "$IP nexthop add id 63 via 2001:db8:91::3 dev veth1" 768 run_cmd "$IP nexthop replace id 102 group 62/63 type resilient buckets 2 idle_timer 0" 769 check_nexthop "id 102" \ 770 "id 102 group 62/63 type resilient buckets 2 idle_timer 0 unbalanced_timer 0 unbalanced_time 0" 771 log_test $? 0 "Nexthop group updated after replace" 772 check_nexthop_bucket "list id 102" \ 773 "id 102 index 0 nhid 63 id 102 index 1 nhid 62" 774 log_test $? 0 "Nexthop buckets updated after replace" 775 776 $IP nexthop flush >/dev/null 2>&1 777 778 # 779 # migration of nexthop buckets - unequal weights 780 # 781 run_cmd "$IP nexthop add id 62 via 2001:db8:91::2 dev veth1" 782 run_cmd "$IP nexthop add id 63 via 2001:db8:91::3 dev veth1" 783 run_cmd "$IP nexthop add id 102 group 62,3/63,1 type resilient buckets 4 idle_timer 0" 784 785 run_cmd "$IP nexthop del id 63" 786 check_nexthop "id 102" \ 787 "id 102 group 62,3 type resilient buckets 4 idle_timer 0 unbalanced_timer 0 unbalanced_time 0" 788 log_test $? 0 "Nexthop group updated when entry is deleted - nECMP" 789 check_nexthop_bucket "list id 102" \ 790 "id 102 index 0 nhid 62 id 102 index 1 nhid 62 id 102 index 2 nhid 62 id 102 index 3 nhid 62" 791 log_test $? 0 "Nexthop buckets updated when entry is deleted - nECMP" 792 793 run_cmd "$IP nexthop add id 63 via 2001:db8:91::3 dev veth1" 794 run_cmd "$IP nexthop replace id 102 group 62,3/63,1 type resilient buckets 4 idle_timer 0" 795 check_nexthop "id 102" \ 796 "id 102 group 62,3/63 type resilient buckets 4 idle_timer 0 unbalanced_timer 0 unbalanced_time 0" 797 log_test $? 0 "Nexthop group updated after replace - nECMP" 798 check_nexthop_bucket "list id 102" \ 799 "id 102 index 0 nhid 63 id 102 index 1 nhid 62 id 102 index 2 nhid 62 id 102 index 3 nhid 62" 800 log_test $? 0 "Nexthop buckets updated after replace - nECMP" 801} 802 803ipv6_fcnal_runtime() 804{ 805 local rc 806 807 echo 808 echo "IPv6 functional runtime" 809 echo "-----------------------" 810 811 # 812 # IPv6 - the basics 813 # 814 run_cmd "$IP nexthop add id 81 via 2001:db8:91::2 dev veth1" 815 run_cmd "$IP ro add 2001:db8:101::1/128 nhid 81" 816 log_test $? 0 "Route add" 817 818 run_cmd "$IP ro delete 2001:db8:101::1/128 nhid 81" 819 log_test $? 0 "Route delete" 820 821 run_cmd "$IP ro add 2001:db8:101::1/128 nhid 81" 822 run_cmd "ip netns exec me ping -c1 -w1 2001:db8:101::1" 823 log_test $? 0 "Ping with nexthop" 824 825 run_cmd "$IP nexthop add id 82 via 2001:db8:92::2 dev veth3" 826 run_cmd "$IP nexthop add id 122 group 81/82" 827 run_cmd "$IP ro replace 2001:db8:101::1/128 nhid 122" 828 run_cmd "ip netns exec me ping -c1 -w1 2001:db8:101::1" 829 log_test $? 0 "Ping - multipath" 830 831 # 832 # IPv6 with blackhole nexthops 833 # 834 run_cmd "$IP -6 nexthop add id 83 blackhole" 835 run_cmd "$IP ro replace 2001:db8:101::1/128 nhid 83" 836 run_cmd "ip netns exec me ping -c1 -w1 2001:db8:101::1" 837 log_test $? 2 "Ping - blackhole" 838 839 run_cmd "$IP nexthop replace id 83 via 2001:db8:91::2 dev veth1" 840 run_cmd "ip netns exec me ping -c1 -w1 2001:db8:101::1" 841 log_test $? 0 "Ping - blackhole replaced with gateway" 842 843 run_cmd "$IP -6 nexthop replace id 83 blackhole" 844 run_cmd "ip netns exec me ping -c1 -w1 2001:db8:101::1" 845 log_test $? 2 "Ping - gateway replaced by blackhole" 846 847 run_cmd "$IP ro replace 2001:db8:101::1/128 nhid 122" 848 run_cmd "ip netns exec me ping -c1 -w1 2001:db8:101::1" 849 if [ $? -eq 0 ]; then 850 run_cmd "$IP nexthop replace id 122 group 83" 851 run_cmd "ip netns exec me ping -c1 -w1 2001:db8:101::1" 852 log_test $? 2 "Ping - group with blackhole" 853 854 run_cmd "$IP nexthop replace id 122 group 81/82" 855 run_cmd "ip netns exec me ping -c1 -w1 2001:db8:101::1" 856 log_test $? 0 "Ping - group blackhole replaced with gateways" 857 else 858 log_test 2 0 "Ping - multipath failed" 859 fi 860 861 # 862 # device only and gw + dev only mix 863 # 864 run_cmd "$IP -6 nexthop add id 85 dev veth1" 865 run_cmd "$IP ro replace 2001:db8:101::1/128 nhid 85" 866 log_test $? 0 "IPv6 route with device only nexthop" 867 check_route6 "2001:db8:101::1" "2001:db8:101::1 nhid 85 dev veth1 metric 1024" 868 869 run_cmd "$IP nexthop add id 123 group 81/85" 870 run_cmd "$IP ro replace 2001:db8:101::1/128 nhid 123" 871 log_test $? 0 "IPv6 multipath route with nexthop mix - dev only + gw" 872 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" 873 874 # 875 # IPv6 route with v4 nexthop - not allowed 876 # 877 run_cmd "$IP ro delete 2001:db8:101::1/128" 878 run_cmd "$IP nexthop add id 84 via 172.16.1.1 dev veth1" 879 run_cmd "$IP ro add 2001:db8:101::1/128 nhid 84" 880 log_test $? 2 "IPv6 route can not have a v4 gateway" 881 882 run_cmd "$IP ro replace 2001:db8:101::1/128 nhid 81" 883 run_cmd "$IP nexthop replace id 81 via 172.16.1.1 dev veth1" 884 log_test $? 2 "Nexthop replace - v6 route, v4 nexthop" 885 886 run_cmd "$IP ro replace 2001:db8:101::1/128 nhid 122" 887 run_cmd "$IP nexthop replace id 81 via 172.16.1.1 dev veth1" 888 log_test $? 2 "Nexthop replace of group entry - v6 route, v4 nexthop" 889 890 run_cmd "$IP nexthop add id 86 via 2001:db8:92::2 dev veth3" 891 run_cmd "$IP nexthop add id 87 via 172.16.1.1 dev veth1" 892 run_cmd "$IP nexthop add id 88 via 172.16.1.1 dev veth1" 893 run_cmd "$IP nexthop add id 124 group 86/87/88" 894 run_cmd "$IP ro replace 2001:db8:101::1/128 nhid 124" 895 log_test $? 2 "IPv6 route can not have a group with v4 and v6 gateways" 896 897 run_cmd "$IP nexthop del id 88" 898 run_cmd "$IP ro replace 2001:db8:101::1/128 nhid 124" 899 log_test $? 2 "IPv6 route can not have a group with v4 and v6 gateways" 900 901 run_cmd "$IP nexthop del id 87" 902 run_cmd "$IP ro replace 2001:db8:101::1/128 nhid 124" 903 log_test $? 0 "IPv6 route using a group after removing v4 gateways" 904 905 run_cmd "$IP ro delete 2001:db8:101::1/128" 906 run_cmd "$IP nexthop add id 87 via 172.16.1.1 dev veth1" 907 run_cmd "$IP nexthop add id 88 via 172.16.1.1 dev veth1" 908 run_cmd "$IP nexthop replace id 124 group 86/87/88" 909 run_cmd "$IP ro replace 2001:db8:101::1/128 nhid 124" 910 log_test $? 2 "IPv6 route can not have a group with v4 and v6 gateways" 911 912 run_cmd "$IP nexthop replace id 88 via 2001:db8:92::2 dev veth3" 913 run_cmd "$IP ro replace 2001:db8:101::1/128 nhid 124" 914 log_test $? 2 "IPv6 route can not have a group with v4 and v6 gateways" 915 916 run_cmd "$IP nexthop replace id 87 via 2001:db8:92::2 dev veth3" 917 run_cmd "$IP ro replace 2001:db8:101::1/128 nhid 124" 918 log_test $? 0 "IPv6 route using a group after replacing v4 gateways" 919 920 $IP nexthop flush >/dev/null 2>&1 921 922 # 923 # weird IPv6 cases 924 # 925 run_cmd "$IP nexthop add id 86 via 2001:db8:91::2 dev veth1" 926 run_cmd "$IP ro add 2001:db8:101::1/128 nhid 81" 927 928 # route can not use prefsrc with nexthops 929 run_cmd "$IP ro add 2001:db8:101::2/128 nhid 86 from 2001:db8:91::1" 930 log_test $? 2 "IPv6 route can not use src routing with external nexthop" 931 932 # check cleanup path on invalid metric 933 run_cmd "$IP ro add 2001:db8:101::2/128 nhid 86 congctl lock foo" 934 log_test $? 2 "IPv6 route with invalid metric" 935 936 # rpfilter and default route 937 $IP nexthop flush >/dev/null 2>&1 938 run_cmd "ip netns exec me ip6tables -t mangle -I PREROUTING 1 -m rpfilter --invert -j DROP" 939 run_cmd "$IP nexthop add id 91 via 2001:db8:91::2 dev veth1" 940 run_cmd "$IP nexthop add id 92 via 2001:db8:92::2 dev veth3" 941 run_cmd "$IP nexthop add id 93 group 91/92" 942 run_cmd "$IP -6 ro add default nhid 91" 943 run_cmd "ip netns exec me ping -c1 -w1 2001:db8:101::1" 944 log_test $? 0 "Nexthop with default route and rpfilter" 945 run_cmd "$IP -6 ro replace default nhid 93" 946 run_cmd "ip netns exec me ping -c1 -w1 2001:db8:101::1" 947 log_test $? 0 "Nexthop with multipath default route and rpfilter" 948 949 # TO-DO: 950 # existing route with old nexthop; append route with new nexthop 951 # existing route with old nexthop; replace route with new 952 # existing route with new nexthop; replace route with old 953 # route with src address and using nexthop - not allowed 954} 955 956ipv6_large_grp() 957{ 958 local ecmp=32 959 960 echo 961 echo "IPv6 large groups (x$ecmp)" 962 echo "---------------------" 963 964 check_large_grp 6 $ecmp 965 966 $IP nexthop flush >/dev/null 2>&1 967} 968 969ipv6_large_res_grp() 970{ 971 echo 972 echo "IPv6 large resilient group (128k buckets)" 973 echo "-----------------------------------------" 974 975 check_nexthop_res_support 976 if [ $? -eq $ksft_skip ]; then 977 return $ksft_skip 978 fi 979 980 check_large_res_grp 6 $((128 * 1024)) 981 982 $IP nexthop flush >/dev/null 2>&1 983} 984 985ipv6_del_add_loop1() 986{ 987 while :; do 988 $IP nexthop del id 100 989 $IP nexthop add id 100 via 2001:db8:91::2 dev veth1 990 done >/dev/null 2>&1 991} 992 993ipv6_grp_replace_loop() 994{ 995 while :; do 996 $IP nexthop replace id 102 group 100/101 997 done >/dev/null 2>&1 998} 999 1000ipv6_torture() 1001{ 1002 local pid1 1003 local pid2 1004 local pid3 1005 local pid4 1006 local pid5 1007 1008 echo 1009 echo "IPv6 runtime torture" 1010 echo "--------------------" 1011 if [ ! -x "$(command -v mausezahn)" ]; then 1012 echo "SKIP: Could not run test; need mausezahn tool" 1013 return 1014 fi 1015 1016 run_cmd "$IP nexthop add id 100 via 2001:db8:91::2 dev veth1" 1017 run_cmd "$IP nexthop add id 101 via 2001:db8:92::2 dev veth3" 1018 run_cmd "$IP nexthop add id 102 group 100/101" 1019 run_cmd "$IP route add 2001:db8:101::1 nhid 102" 1020 run_cmd "$IP route add 2001:db8:101::2 nhid 102" 1021 1022 ipv6_del_add_loop1 & 1023 pid1=$! 1024 ipv6_grp_replace_loop & 1025 pid2=$! 1026 ip netns exec me ping -f 2001:db8:101::1 >/dev/null 2>&1 & 1027 pid3=$! 1028 ip netns exec me ping -f 2001:db8:101::2 >/dev/null 2>&1 & 1029 pid4=$! 1030 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 & 1031 pid5=$! 1032 1033 sleep 300 1034 kill -9 $pid1 $pid2 $pid3 $pid4 $pid5 1035 wait $pid1 $pid2 $pid3 $pid4 $pid5 2>/dev/null 1036 1037 # if we did not crash, success 1038 log_test 0 0 "IPv6 torture test" 1039} 1040 1041ipv6_res_grp_replace_loop() 1042{ 1043 while :; do 1044 $IP nexthop replace id 102 group 100/101 type resilient 1045 done >/dev/null 2>&1 1046} 1047 1048ipv6_res_torture() 1049{ 1050 local pid1 1051 local pid2 1052 local pid3 1053 local pid4 1054 local pid5 1055 1056 echo 1057 echo "IPv6 runtime resilient nexthop group torture" 1058 echo "--------------------------------------------" 1059 1060 check_nexthop_res_support 1061 if [ $? -eq $ksft_skip ]; then 1062 return $ksft_skip 1063 fi 1064 1065 if [ ! -x "$(command -v mausezahn)" ]; then 1066 echo "SKIP: Could not run test; need mausezahn tool" 1067 return 1068 fi 1069 1070 run_cmd "$IP nexthop add id 100 via 2001:db8:91::2 dev veth1" 1071 run_cmd "$IP nexthop add id 101 via 2001:db8:92::2 dev veth3" 1072 run_cmd "$IP nexthop add id 102 group 100/101 type resilient buckets 512 idle_timer 0" 1073 run_cmd "$IP route add 2001:db8:101::1 nhid 102" 1074 run_cmd "$IP route add 2001:db8:101::2 nhid 102" 1075 1076 ipv6_del_add_loop1 & 1077 pid1=$! 1078 ipv6_res_grp_replace_loop & 1079 pid2=$! 1080 ip netns exec me ping -f 2001:db8:101::1 >/dev/null 2>&1 & 1081 pid3=$! 1082 ip netns exec me ping -f 2001:db8:101::2 >/dev/null 2>&1 & 1083 pid4=$! 1084 ip netns exec me mausezahn -6 veth1 \ 1085 -B 2001:db8:101::2 -A 2001:db8:91::1 -c 0 \ 1086 -t tcp "dp=1-1023, flags=syn" >/dev/null 2>&1 & 1087 pid5=$! 1088 1089 sleep 300 1090 kill -9 $pid1 $pid2 $pid3 $pid4 $pid5 1091 wait $pid1 $pid2 $pid3 $pid4 $pid5 2>/dev/null 1092 1093 # if we did not crash, success 1094 log_test 0 0 "IPv6 resilient nexthop group torture test" 1095} 1096 1097ipv4_fcnal() 1098{ 1099 local rc 1100 1101 echo 1102 echo "IPv4 functional" 1103 echo "----------------------" 1104 1105 # 1106 # basic IPv4 ops - add, get, delete 1107 # 1108 run_cmd "$IP nexthop add id 12 via 172.16.1.2 dev veth1" 1109 rc=$? 1110 log_test $rc 0 "Create nexthop with id, gw, dev" 1111 if [ $rc -ne 0 ]; then 1112 echo "Basic IPv4 create fails; can not continue" 1113 return 1 1114 fi 1115 1116 run_cmd "$IP nexthop get id 12" 1117 log_test $? 0 "Get nexthop by id" 1118 check_nexthop "id 12" "id 12 via 172.16.1.2 dev veth1 scope link" 1119 1120 run_cmd "$IP nexthop del id 12" 1121 log_test $? 0 "Delete nexthop by id" 1122 check_nexthop "id 52" "" 1123 1124 # 1125 # gw, device spec 1126 # 1127 # gw validation, no device - fails since dev is required 1128 run_cmd "$IP nexthop add id 12 via 172.16.2.3" 1129 log_test $? 2 "Create nexthop - gw only" 1130 1131 # gw not reachable through given dev 1132 run_cmd "$IP nexthop add id 13 via 172.16.3.2 dev veth1" 1133 log_test $? 2 "Create nexthop - invalid gw+dev combination" 1134 1135 # onlink flag overrides gw+dev lookup 1136 run_cmd "$IP nexthop add id 13 via 172.16.3.2 dev veth1 onlink" 1137 log_test $? 0 "Create nexthop - gw+dev and onlink" 1138 1139 # admin down should delete nexthops 1140 set -e 1141 run_cmd "$IP nexthop add id 15 via 172.16.1.3 dev veth1" 1142 run_cmd "$IP nexthop add id 16 via 172.16.1.4 dev veth1" 1143 run_cmd "$IP nexthop add id 17 via 172.16.1.5 dev veth1" 1144 run_cmd "$IP li set dev veth1 down" 1145 set +e 1146 check_nexthop "dev veth1" "" 1147 log_test $? 0 "Nexthops removed on admin down" 1148 1149 # nexthop route delete warning: route add with nhid and delete 1150 # using device 1151 run_cmd "$IP li set dev veth1 up" 1152 run_cmd "$IP nexthop add id 12 via 172.16.1.3 dev veth1" 1153 out1=`dmesg | grep "WARNING:.*fib_nh_match.*" | wc -l` 1154 run_cmd "$IP route add 172.16.101.1/32 nhid 12" 1155 run_cmd "$IP route delete 172.16.101.1/32 dev veth1" 1156 out2=`dmesg | grep "WARNING:.*fib_nh_match.*" | wc -l` 1157 [ $out1 -eq $out2 ] 1158 rc=$? 1159 log_test $rc 0 "Delete nexthop route warning" 1160 run_cmd "$IP route delete 172.16.101.1/32 nhid 12" 1161 run_cmd "$IP nexthop del id 12" 1162 1163 run_cmd "$IP nexthop add id 21 via 172.16.1.6 dev veth1" 1164 run_cmd "$IP ro add 172.16.101.0/24 nhid 21" 1165 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" 1166 log_test $? 2 "Delete multipath route with only nh id based entry" 1167 1168 run_cmd "$IP nexthop add id 22 via 172.16.1.6 dev veth1" 1169 run_cmd "$IP ro add 172.16.102.0/24 nhid 22" 1170 run_cmd "$IP ro del 172.16.102.0/24 dev veth1" 1171 log_test $? 2 "Delete route when specifying only nexthop device" 1172 1173 run_cmd "$IP ro del 172.16.102.0/24 via 172.16.1.6" 1174 log_test $? 2 "Delete route when specifying only gateway" 1175 1176 run_cmd "$IP ro del 172.16.102.0/24" 1177 log_test $? 0 "Delete route when not specifying nexthop attributes" 1178} 1179 1180ipv4_grp_fcnal() 1181{ 1182 local rc 1183 1184 echo 1185 echo "IPv4 groups functional" 1186 echo "----------------------" 1187 1188 # basic functionality: create a nexthop group, default weight 1189 run_cmd "$IP nexthop add id 11 via 172.16.1.2 dev veth1" 1190 run_cmd "$IP nexthop add id 101 group 11" 1191 log_test $? 0 "Create nexthop group with single nexthop" 1192 1193 # get nexthop group 1194 run_cmd "$IP nexthop get id 101" 1195 log_test $? 0 "Get nexthop group by id" 1196 check_nexthop "id 101" "id 101 group 11" 1197 1198 # delete nexthop group 1199 run_cmd "$IP nexthop del id 101" 1200 log_test $? 0 "Delete nexthop group by id" 1201 check_nexthop "id 101" "" 1202 1203 $IP nexthop flush >/dev/null 2>&1 1204 1205 # 1206 # create group with multiple nexthops 1207 run_cmd "$IP nexthop add id 12 via 172.16.1.2 dev veth1" 1208 run_cmd "$IP nexthop add id 13 via 172.16.1.3 dev veth1" 1209 run_cmd "$IP nexthop add id 14 via 172.16.1.4 dev veth1" 1210 run_cmd "$IP nexthop add id 15 via 172.16.1.5 dev veth1" 1211 run_cmd "$IP nexthop add id 102 group 12/13/14/15" 1212 log_test $? 0 "Nexthop group with multiple nexthops" 1213 check_nexthop "id 102" "id 102 group 12/13/14/15" 1214 1215 # Delete nexthop in a group and group is updated 1216 run_cmd "$IP nexthop del id 13" 1217 check_nexthop "id 102" "id 102 group 12/14/15" 1218 log_test $? 0 "Nexthop group updated when entry is deleted" 1219 1220 # create group with multiple weighted nexthops 1221 run_cmd "$IP nexthop add id 13 via 172.16.1.3 dev veth1" 1222 run_cmd "$IP nexthop add id 103 group 12/13,2/14,3/15,4" 1223 log_test $? 0 "Nexthop group with weighted nexthops" 1224 check_nexthop "id 103" "id 103 group 12/13,2/14,3/15,4" 1225 1226 # Delete nexthop in a weighted group and group is updated 1227 run_cmd "$IP nexthop del id 13" 1228 check_nexthop "id 103" "id 103 group 12/14,3/15,4" 1229 log_test $? 0 "Weighted nexthop group updated when entry is deleted" 1230 1231 # admin down - nexthop is removed from group 1232 run_cmd "$IP li set dev veth1 down" 1233 check_nexthop "dev veth1" "" 1234 log_test $? 0 "Nexthops in groups removed on admin down" 1235 1236 # expect groups to have been deleted as well 1237 check_nexthop "" "" 1238 1239 run_cmd "$IP li set dev veth1 up" 1240 1241 $IP nexthop flush >/dev/null 2>&1 1242 1243 # group with nexthops using different devices 1244 set -e 1245 run_cmd "$IP nexthop add id 12 via 172.16.1.2 dev veth1" 1246 run_cmd "$IP nexthop add id 13 via 172.16.1.3 dev veth1" 1247 run_cmd "$IP nexthop add id 14 via 172.16.1.4 dev veth1" 1248 run_cmd "$IP nexthop add id 15 via 172.16.1.5 dev veth1" 1249 1250 run_cmd "$IP nexthop add id 22 via 172.16.2.2 dev veth3" 1251 run_cmd "$IP nexthop add id 23 via 172.16.2.3 dev veth3" 1252 run_cmd "$IP nexthop add id 24 via 172.16.2.4 dev veth3" 1253 run_cmd "$IP nexthop add id 25 via 172.16.2.5 dev veth3" 1254 set +e 1255 1256 # multiple groups with same nexthop 1257 run_cmd "$IP nexthop add id 104 group 12" 1258 run_cmd "$IP nexthop add id 105 group 12" 1259 check_nexthop "group" "id 104 group 12 id 105 group 12" 1260 log_test $? 0 "Multiple groups with same nexthop" 1261 1262 run_cmd "$IP nexthop flush groups" 1263 [ $? -ne 0 ] && return 1 1264 1265 # on admin down of veth1, it should be removed from the group 1266 run_cmd "$IP nexthop add id 105 group 12/13/22/23/14" 1267 run_cmd "$IP li set veth1 down" 1268 check_nexthop "id 105" "id 105 group 22/23" 1269 log_test $? 0 "Nexthops in group removed on admin down - mixed group" 1270 1271 run_cmd "$IP nexthop add id 106 group 105/24" 1272 log_test $? 2 "Nexthop group can not have a group as an entry" 1273 1274 # a group can have a blackhole entry only if it is the only 1275 # nexthop in the group. Needed for atomic replace with an 1276 # actual nexthop group 1277 run_cmd "$IP nexthop add id 31 blackhole" 1278 run_cmd "$IP nexthop add id 107 group 31" 1279 log_test $? 0 "Nexthop group with a blackhole entry" 1280 1281 run_cmd "$IP nexthop add id 108 group 31/24" 1282 log_test $? 2 "Nexthop group can not have a blackhole and another nexthop" 1283} 1284 1285ipv4_res_grp_fcnal() 1286{ 1287 local rc 1288 1289 echo 1290 echo "IPv4 resilient groups functional" 1291 echo "--------------------------------" 1292 1293 check_nexthop_res_support 1294 if [ $? -eq $ksft_skip ]; then 1295 return $ksft_skip 1296 fi 1297 1298 # 1299 # migration of nexthop buckets - equal weights 1300 # 1301 run_cmd "$IP nexthop add id 12 via 172.16.1.2 dev veth1" 1302 run_cmd "$IP nexthop add id 13 via 172.16.1.3 dev veth1" 1303 run_cmd "$IP nexthop add id 102 group 12/13 type resilient buckets 2 idle_timer 0" 1304 1305 run_cmd "$IP nexthop del id 13" 1306 check_nexthop "id 102" \ 1307 "id 102 group 12 type resilient buckets 2 idle_timer 0 unbalanced_timer 0 unbalanced_time 0" 1308 log_test $? 0 "Nexthop group updated when entry is deleted" 1309 check_nexthop_bucket "list id 102" \ 1310 "id 102 index 0 nhid 12 id 102 index 1 nhid 12" 1311 log_test $? 0 "Nexthop buckets updated when entry is deleted" 1312 1313 run_cmd "$IP nexthop add id 13 via 172.16.1.3 dev veth1" 1314 run_cmd "$IP nexthop replace id 102 group 12/13 type resilient buckets 2 idle_timer 0" 1315 check_nexthop "id 102" \ 1316 "id 102 group 12/13 type resilient buckets 2 idle_timer 0 unbalanced_timer 0 unbalanced_time 0" 1317 log_test $? 0 "Nexthop group updated after replace" 1318 check_nexthop_bucket "list id 102" \ 1319 "id 102 index 0 nhid 13 id 102 index 1 nhid 12" 1320 log_test $? 0 "Nexthop buckets updated after replace" 1321 1322 $IP nexthop flush >/dev/null 2>&1 1323 1324 # 1325 # migration of nexthop buckets - unequal weights 1326 # 1327 run_cmd "$IP nexthop add id 12 via 172.16.1.2 dev veth1" 1328 run_cmd "$IP nexthop add id 13 via 172.16.1.3 dev veth1" 1329 run_cmd "$IP nexthop add id 102 group 12,3/13,1 type resilient buckets 4 idle_timer 0" 1330 1331 run_cmd "$IP nexthop del id 13" 1332 check_nexthop "id 102" \ 1333 "id 102 group 12,3 type resilient buckets 4 idle_timer 0 unbalanced_timer 0 unbalanced_time 0" 1334 log_test $? 0 "Nexthop group updated when entry is deleted - nECMP" 1335 check_nexthop_bucket "list id 102" \ 1336 "id 102 index 0 nhid 12 id 102 index 1 nhid 12 id 102 index 2 nhid 12 id 102 index 3 nhid 12" 1337 log_test $? 0 "Nexthop buckets updated when entry is deleted - nECMP" 1338 1339 run_cmd "$IP nexthop add id 13 via 172.16.1.3 dev veth1" 1340 run_cmd "$IP nexthop replace id 102 group 12,3/13,1 type resilient buckets 4 idle_timer 0" 1341 check_nexthop "id 102" \ 1342 "id 102 group 12,3/13 type resilient buckets 4 idle_timer 0 unbalanced_timer 0 unbalanced_time 0" 1343 log_test $? 0 "Nexthop group updated after replace - nECMP" 1344 check_nexthop_bucket "list id 102" \ 1345 "id 102 index 0 nhid 13 id 102 index 1 nhid 12 id 102 index 2 nhid 12 id 102 index 3 nhid 12" 1346 log_test $? 0 "Nexthop buckets updated after replace - nECMP" 1347} 1348 1349ipv4_withv6_fcnal() 1350{ 1351 local lladdr 1352 1353 set -e 1354 lladdr=$(get_linklocal veth2 peer) 1355 run_cmd "$IP nexthop add id 11 via ${lladdr} dev veth1" 1356 set +e 1357 run_cmd "$IP ro add 172.16.101.1/32 nhid 11" 1358 log_test $? 0 "IPv6 nexthop with IPv4 route" 1359 check_route "172.16.101.1" "172.16.101.1 nhid 11 via inet6 ${lladdr} dev veth1" 1360 1361 set -e 1362 run_cmd "$IP nexthop add id 12 via 172.16.1.2 dev veth1" 1363 run_cmd "$IP nexthop add id 101 group 11/12" 1364 set +e 1365 run_cmd "$IP ro replace 172.16.101.1/32 nhid 101" 1366 log_test $? 0 "IPv6 nexthop with IPv4 route" 1367 1368 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" 1369 1370 run_cmd "$IP ro replace 172.16.101.1/32 via inet6 ${lladdr} dev veth1" 1371 log_test $? 0 "IPv4 route with IPv6 gateway" 1372 check_route "172.16.101.1" "172.16.101.1 via inet6 ${lladdr} dev veth1" 1373 1374 run_cmd "$IP ro replace 172.16.101.1/32 via inet6 2001:db8:50::1 dev veth1" 1375 log_test $? 2 "IPv4 route with invalid IPv6 gateway" 1376} 1377 1378ipv4_fcnal_runtime() 1379{ 1380 local lladdr 1381 local rc 1382 1383 echo 1384 echo "IPv4 functional runtime" 1385 echo "-----------------------" 1386 1387 run_cmd "$IP nexthop add id 21 via 172.16.1.2 dev veth1" 1388 run_cmd "$IP ro add 172.16.101.1/32 nhid 21" 1389 log_test $? 0 "Route add" 1390 check_route "172.16.101.1" "172.16.101.1 nhid 21 via 172.16.1.2 dev veth1" 1391 1392 run_cmd "$IP ro delete 172.16.101.1/32 nhid 21" 1393 log_test $? 0 "Route delete" 1394 1395 # 1396 # scope mismatch 1397 # 1398 run_cmd "$IP nexthop add id 22 via 172.16.1.2 dev veth1" 1399 run_cmd "$IP ro add 172.16.101.1/32 nhid 22 scope host" 1400 log_test $? 2 "Route add - scope conflict with nexthop" 1401 1402 run_cmd "$IP nexthop replace id 22 dev veth3" 1403 run_cmd "$IP ro add 172.16.101.1/32 nhid 22 scope host" 1404 run_cmd "$IP nexthop replace id 22 via 172.16.2.2 dev veth3" 1405 log_test $? 2 "Nexthop replace with invalid scope for existing route" 1406 1407 # check cleanup path on invalid metric 1408 run_cmd "$IP ro add 172.16.101.2/32 nhid 22 congctl lock foo" 1409 log_test $? 2 "IPv4 route with invalid metric" 1410 1411 # 1412 # add route with nexthop and check traffic 1413 # 1414 run_cmd "$IP nexthop replace id 21 via 172.16.1.2 dev veth1" 1415 run_cmd "$IP ro replace 172.16.101.1/32 nhid 21" 1416 run_cmd "ip netns exec me ping -c1 -w1 172.16.101.1" 1417 log_test $? 0 "Basic ping" 1418 1419 run_cmd "$IP nexthop replace id 22 via 172.16.2.2 dev veth3" 1420 run_cmd "$IP nexthop add id 122 group 21/22" 1421 run_cmd "$IP ro replace 172.16.101.1/32 nhid 122" 1422 run_cmd "ip netns exec me ping -c1 -w1 172.16.101.1" 1423 log_test $? 0 "Ping - multipath" 1424 1425 run_cmd "$IP ro delete 172.16.101.1/32 nhid 122" 1426 1427 # 1428 # multiple default routes 1429 # - tests fib_select_default 1430 run_cmd "$IP nexthop add id 501 via 172.16.1.2 dev veth1" 1431 run_cmd "$IP ro add default nhid 501" 1432 run_cmd "$IP ro add default via 172.16.1.3 dev veth1 metric 20" 1433 run_cmd "ip netns exec me ping -c1 -w1 172.16.101.1" 1434 log_test $? 0 "Ping - multiple default routes, nh first" 1435 1436 # flip the order 1437 run_cmd "$IP ro del default nhid 501" 1438 run_cmd "$IP ro del default via 172.16.1.3 dev veth1 metric 20" 1439 run_cmd "$IP ro add default via 172.16.1.2 dev veth1 metric 20" 1440 run_cmd "$IP nexthop replace id 501 via 172.16.1.3 dev veth1" 1441 run_cmd "$IP ro add default nhid 501 metric 20" 1442 run_cmd "ip netns exec me ping -c1 -w1 172.16.101.1" 1443 log_test $? 0 "Ping - multiple default routes, nh second" 1444 1445 run_cmd "$IP nexthop delete nhid 501" 1446 run_cmd "$IP ro del default" 1447 1448 # 1449 # IPv4 with blackhole nexthops 1450 # 1451 run_cmd "$IP nexthop add id 23 blackhole" 1452 run_cmd "$IP ro replace 172.16.101.1/32 nhid 23" 1453 run_cmd "ip netns exec me ping -c1 -w1 172.16.101.1" 1454 log_test $? 2 "Ping - blackhole" 1455 1456 run_cmd "$IP nexthop replace id 23 via 172.16.1.2 dev veth1" 1457 run_cmd "ip netns exec me ping -c1 -w1 172.16.101.1" 1458 log_test $? 0 "Ping - blackhole replaced with gateway" 1459 1460 run_cmd "$IP nexthop replace id 23 blackhole" 1461 run_cmd "ip netns exec me ping -c1 -w1 172.16.101.1" 1462 log_test $? 2 "Ping - gateway replaced by blackhole" 1463 1464 run_cmd "$IP ro replace 172.16.101.1/32 nhid 122" 1465 run_cmd "ip netns exec me ping -c1 -w1 172.16.101.1" 1466 if [ $? -eq 0 ]; then 1467 run_cmd "$IP nexthop replace id 122 group 23" 1468 run_cmd "ip netns exec me ping -c1 -w1 172.16.101.1" 1469 log_test $? 2 "Ping - group with blackhole" 1470 1471 run_cmd "$IP nexthop replace id 122 group 21/22" 1472 run_cmd "ip netns exec me ping -c1 -w1 172.16.101.1" 1473 log_test $? 0 "Ping - group blackhole replaced with gateways" 1474 else 1475 log_test 2 0 "Ping - multipath failed" 1476 fi 1477 1478 # 1479 # device only and gw + dev only mix 1480 # 1481 run_cmd "$IP nexthop add id 85 dev veth1" 1482 run_cmd "$IP ro replace 172.16.101.1/32 nhid 85" 1483 log_test $? 0 "IPv4 route with device only nexthop" 1484 check_route "172.16.101.1" "172.16.101.1 nhid 85 dev veth1" 1485 1486 run_cmd "$IP nexthop add id 123 group 21/85" 1487 run_cmd "$IP ro replace 172.16.101.1/32 nhid 123" 1488 log_test $? 0 "IPv4 multipath route with nexthop mix - dev only + gw" 1489 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" 1490 1491 # 1492 # IPv4 with IPv6 1493 # 1494 set -e 1495 lladdr=$(get_linklocal veth2 peer) 1496 run_cmd "$IP nexthop add id 24 via ${lladdr} dev veth1" 1497 set +e 1498 run_cmd "$IP ro replace 172.16.101.1/32 nhid 24" 1499 run_cmd "ip netns exec me ping -c1 -w1 172.16.101.1" 1500 log_test $? 0 "IPv6 nexthop with IPv4 route" 1501 1502 $IP neigh sh | grep -q "${lladdr} dev veth1" 1503 if [ $? -eq 1 ]; then 1504 echo " WARNING: Neigh entry missing for ${lladdr}" 1505 $IP neigh sh | grep 'dev veth1' 1506 fi 1507 1508 $IP neigh sh | grep -q "172.16.101.1 dev eth1" 1509 if [ $? -eq 0 ]; then 1510 echo " WARNING: Neigh entry exists for 172.16.101.1" 1511 $IP neigh sh | grep 'dev veth1' 1512 fi 1513 1514 set -e 1515 run_cmd "$IP nexthop add id 25 via 172.16.1.2 dev veth1" 1516 run_cmd "$IP nexthop add id 101 group 24/25" 1517 set +e 1518 run_cmd "$IP ro replace 172.16.101.1/32 nhid 101" 1519 log_test $? 0 "IPv4 route with mixed v4-v6 multipath route" 1520 1521 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" 1522 1523 run_cmd "ip netns exec me ping -c1 -w1 172.16.101.1" 1524 log_test $? 0 "IPv6 nexthop with IPv4 route" 1525 1526 run_cmd "$IP ro replace 172.16.101.1/32 via inet6 ${lladdr} dev veth1" 1527 run_cmd "ip netns exec me ping -c1 -w1 172.16.101.1" 1528 log_test $? 0 "IPv4 route with IPv6 gateway" 1529 1530 $IP neigh sh | grep -q "${lladdr} dev veth1" 1531 if [ $? -eq 1 ]; then 1532 echo " WARNING: Neigh entry missing for ${lladdr}" 1533 $IP neigh sh | grep 'dev veth1' 1534 fi 1535 1536 $IP neigh sh | grep -q "172.16.101.1 dev eth1" 1537 if [ $? -eq 0 ]; then 1538 echo " WARNING: Neigh entry exists for 172.16.101.1" 1539 $IP neigh sh | grep 'dev veth1' 1540 fi 1541 1542 run_cmd "$IP ro del 172.16.101.1/32 via inet6 ${lladdr} dev veth1" 1543 run_cmd "$IP -4 ro add default via inet6 ${lladdr} dev veth1" 1544 run_cmd "ip netns exec me ping -c1 -w1 172.16.101.1" 1545 log_test $? 0 "IPv4 default route with IPv6 gateway" 1546 1547 # 1548 # MPLS as an example of LWT encap 1549 # 1550 run_cmd "$IP nexthop add id 51 encap mpls 101 via 172.16.1.2 dev veth1" 1551 log_test $? 0 "IPv4 route with MPLS encap" 1552 check_nexthop "id 51" "id 51 encap mpls 101 via 172.16.1.2 dev veth1 scope link" 1553 log_test $? 0 "IPv4 route with MPLS encap - check" 1554 1555 run_cmd "$IP nexthop add id 52 encap mpls 102 via inet6 2001:db8:91::2 dev veth1" 1556 log_test $? 0 "IPv4 route with MPLS encap and v6 gateway" 1557 check_nexthop "id 52" "id 52 encap mpls 102 via 2001:db8:91::2 dev veth1 scope link" 1558 log_test $? 0 "IPv4 route with MPLS encap, v6 gw - check" 1559} 1560 1561ipv4_large_grp() 1562{ 1563 local ecmp=32 1564 1565 echo 1566 echo "IPv4 large groups (x$ecmp)" 1567 echo "---------------------" 1568 1569 check_large_grp 4 $ecmp 1570 1571 $IP nexthop flush >/dev/null 2>&1 1572} 1573 1574ipv4_large_res_grp() 1575{ 1576 echo 1577 echo "IPv4 large resilient group (128k buckets)" 1578 echo "-----------------------------------------" 1579 1580 check_nexthop_res_support 1581 if [ $? -eq $ksft_skip ]; then 1582 return $ksft_skip 1583 fi 1584 1585 check_large_res_grp 4 $((128 * 1024)) 1586 1587 $IP nexthop flush >/dev/null 2>&1 1588} 1589 1590sysctl_nexthop_compat_mode_check() 1591{ 1592 local sysctlname="net.ipv4.nexthop_compat_mode" 1593 local lprefix=$1 1594 1595 IPE="ip netns exec me" 1596 1597 $IPE sysctl -q $sysctlname 2>&1 >/dev/null 1598 if [ $? -ne 0 ]; then 1599 echo "SKIP: kernel lacks nexthop compat mode sysctl control" 1600 return $ksft_skip 1601 fi 1602 1603 out=$($IPE sysctl $sysctlname 2>/dev/null) 1604 log_test $? 0 "$lprefix default nexthop compat mode check" 1605 check_output "${out}" "$sysctlname = 1" 1606} 1607 1608sysctl_nexthop_compat_mode_set() 1609{ 1610 local sysctlname="net.ipv4.nexthop_compat_mode" 1611 local mode=$1 1612 local lprefix=$2 1613 1614 IPE="ip netns exec me" 1615 1616 out=$($IPE sysctl -w $sysctlname=$mode) 1617 log_test $? 0 "$lprefix set compat mode - $mode" 1618 check_output "${out}" "net.ipv4.nexthop_compat_mode = $mode" 1619} 1620 1621ipv6_compat_mode() 1622{ 1623 local rc 1624 1625 echo 1626 echo "IPv6 nexthop api compat mode test" 1627 echo "--------------------------------" 1628 1629 sysctl_nexthop_compat_mode_check "IPv6" 1630 if [ $? -eq $ksft_skip ]; then 1631 return $ksft_skip 1632 fi 1633 1634 run_cmd "$IP nexthop add id 62 via 2001:db8:91::2 dev veth1" 1635 run_cmd "$IP nexthop add id 63 via 2001:db8:91::3 dev veth1" 1636 run_cmd "$IP nexthop add id 122 group 62/63" 1637 ipmout=$(start_ip_monitor route) 1638 1639 run_cmd "$IP -6 ro add 2001:db8:101::1/128 nhid 122" 1640 # route add notification should contain expanded nexthops 1641 stop_ip_monitor $ipmout 3 1642 log_test $? 0 "IPv6 compat mode on - route add notification" 1643 1644 # route dump should contain expanded nexthops 1645 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" 1646 log_test $? 0 "IPv6 compat mode on - route dump" 1647 1648 # change in nexthop group should generate route notification 1649 run_cmd "$IP nexthop add id 64 via 2001:db8:91::4 dev veth1" 1650 ipmout=$(start_ip_monitor route) 1651 run_cmd "$IP nexthop replace id 122 group 62/64" 1652 stop_ip_monitor $ipmout 3 1653 1654 log_test $? 0 "IPv6 compat mode on - nexthop change" 1655 1656 # set compat mode off 1657 sysctl_nexthop_compat_mode_set 0 "IPv6" 1658 1659 run_cmd "$IP -6 ro del 2001:db8:101::1/128 nhid 122" 1660 1661 run_cmd "$IP nexthop add id 62 via 2001:db8:91::2 dev veth1" 1662 run_cmd "$IP nexthop add id 63 via 2001:db8:91::3 dev veth1" 1663 run_cmd "$IP nexthop add id 122 group 62/63" 1664 ipmout=$(start_ip_monitor route) 1665 1666 run_cmd "$IP -6 ro add 2001:db8:101::1/128 nhid 122" 1667 # route add notification should not contain expanded nexthops 1668 stop_ip_monitor $ipmout 1 1669 log_test $? 0 "IPv6 compat mode off - route add notification" 1670 1671 # route dump should not contain expanded nexthops 1672 check_route6 "2001:db8:101::1" "2001:db8:101::1 nhid 122 metric 1024" 1673 log_test $? 0 "IPv6 compat mode off - route dump" 1674 1675 # change in nexthop group should not generate route notification 1676 run_cmd "$IP nexthop add id 64 via 2001:db8:91::4 dev veth1" 1677 ipmout=$(start_ip_monitor route) 1678 run_cmd "$IP nexthop replace id 122 group 62/64" 1679 stop_ip_monitor $ipmout 0 1680 log_test $? 0 "IPv6 compat mode off - nexthop change" 1681 1682 # nexthop delete should not generate route notification 1683 ipmout=$(start_ip_monitor route) 1684 run_cmd "$IP nexthop del id 122" 1685 stop_ip_monitor $ipmout 0 1686 log_test $? 0 "IPv6 compat mode off - nexthop delete" 1687 1688 # set compat mode back on 1689 sysctl_nexthop_compat_mode_set 1 "IPv6" 1690} 1691 1692ipv4_compat_mode() 1693{ 1694 local rc 1695 1696 echo 1697 echo "IPv4 nexthop api compat mode" 1698 echo "----------------------------" 1699 1700 sysctl_nexthop_compat_mode_check "IPv4" 1701 if [ $? -eq $ksft_skip ]; then 1702 return $ksft_skip 1703 fi 1704 1705 run_cmd "$IP nexthop add id 21 via 172.16.1.2 dev veth1" 1706 run_cmd "$IP nexthop add id 22 via 172.16.1.2 dev veth1" 1707 run_cmd "$IP nexthop add id 122 group 21/22" 1708 ipmout=$(start_ip_monitor route) 1709 1710 run_cmd "$IP ro add 172.16.101.1/32 nhid 122" 1711 stop_ip_monitor $ipmout 3 1712 1713 # route add notification should contain expanded nexthops 1714 log_test $? 0 "IPv4 compat mode on - route add notification" 1715 1716 # route dump should contain expanded nexthops 1717 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" 1718 log_test $? 0 "IPv4 compat mode on - route dump" 1719 1720 # change in nexthop group should generate route notification 1721 run_cmd "$IP nexthop add id 23 via 172.16.1.3 dev veth1" 1722 ipmout=$(start_ip_monitor route) 1723 run_cmd "$IP nexthop replace id 122 group 21/23" 1724 stop_ip_monitor $ipmout 3 1725 log_test $? 0 "IPv4 compat mode on - nexthop change" 1726 1727 sysctl_nexthop_compat_mode_set 0 "IPv4" 1728 1729 # cleanup 1730 run_cmd "$IP ro del 172.16.101.1/32 nhid 122" 1731 1732 ipmout=$(start_ip_monitor route) 1733 run_cmd "$IP ro add 172.16.101.1/32 nhid 122" 1734 stop_ip_monitor $ipmout 1 1735 # route add notification should not contain expanded nexthops 1736 log_test $? 0 "IPv4 compat mode off - route add notification" 1737 1738 # route dump should not contain expanded nexthops 1739 check_route "172.16.101.1" "172.16.101.1 nhid 122" 1740 log_test $? 0 "IPv4 compat mode off - route dump" 1741 1742 # change in nexthop group should not generate route notification 1743 ipmout=$(start_ip_monitor route) 1744 run_cmd "$IP nexthop replace id 122 group 21/22" 1745 stop_ip_monitor $ipmout 0 1746 log_test $? 0 "IPv4 compat mode off - nexthop change" 1747 1748 # nexthop delete should not generate route notification 1749 ipmout=$(start_ip_monitor route) 1750 run_cmd "$IP nexthop del id 122" 1751 stop_ip_monitor $ipmout 0 1752 log_test $? 0 "IPv4 compat mode off - nexthop delete" 1753 1754 sysctl_nexthop_compat_mode_set 1 "IPv4" 1755} 1756 1757ipv4_del_add_loop1() 1758{ 1759 while :; do 1760 $IP nexthop del id 100 1761 $IP nexthop add id 100 via 172.16.1.2 dev veth1 1762 done >/dev/null 2>&1 1763} 1764 1765ipv4_grp_replace_loop() 1766{ 1767 while :; do 1768 $IP nexthop replace id 102 group 100/101 1769 done >/dev/null 2>&1 1770} 1771 1772ipv4_torture() 1773{ 1774 local pid1 1775 local pid2 1776 local pid3 1777 local pid4 1778 local pid5 1779 1780 echo 1781 echo "IPv4 runtime torture" 1782 echo "--------------------" 1783 if [ ! -x "$(command -v mausezahn)" ]; then 1784 echo "SKIP: Could not run test; need mausezahn tool" 1785 return 1786 fi 1787 1788 run_cmd "$IP nexthop add id 100 via 172.16.1.2 dev veth1" 1789 run_cmd "$IP nexthop add id 101 via 172.16.2.2 dev veth3" 1790 run_cmd "$IP nexthop add id 102 group 100/101" 1791 run_cmd "$IP route add 172.16.101.1 nhid 102" 1792 run_cmd "$IP route add 172.16.101.2 nhid 102" 1793 1794 ipv4_del_add_loop1 & 1795 pid1=$! 1796 ipv4_grp_replace_loop & 1797 pid2=$! 1798 ip netns exec me ping -f 172.16.101.1 >/dev/null 2>&1 & 1799 pid3=$! 1800 ip netns exec me ping -f 172.16.101.2 >/dev/null 2>&1 & 1801 pid4=$! 1802 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 & 1803 pid5=$! 1804 1805 sleep 300 1806 kill -9 $pid1 $pid2 $pid3 $pid4 $pid5 1807 wait $pid1 $pid2 $pid3 $pid4 $pid5 2>/dev/null 1808 1809 # if we did not crash, success 1810 log_test 0 0 "IPv4 torture test" 1811} 1812 1813ipv4_res_grp_replace_loop() 1814{ 1815 while :; do 1816 $IP nexthop replace id 102 group 100/101 type resilient 1817 done >/dev/null 2>&1 1818} 1819 1820ipv4_res_torture() 1821{ 1822 local pid1 1823 local pid2 1824 local pid3 1825 local pid4 1826 local pid5 1827 1828 echo 1829 echo "IPv4 runtime resilient nexthop group torture" 1830 echo "--------------------------------------------" 1831 1832 check_nexthop_res_support 1833 if [ $? -eq $ksft_skip ]; then 1834 return $ksft_skip 1835 fi 1836 1837 if [ ! -x "$(command -v mausezahn)" ]; then 1838 echo "SKIP: Could not run test; need mausezahn tool" 1839 return 1840 fi 1841 1842 run_cmd "$IP nexthop add id 100 via 172.16.1.2 dev veth1" 1843 run_cmd "$IP nexthop add id 101 via 172.16.2.2 dev veth3" 1844 run_cmd "$IP nexthop add id 102 group 100/101 type resilient buckets 512 idle_timer 0" 1845 run_cmd "$IP route add 172.16.101.1 nhid 102" 1846 run_cmd "$IP route add 172.16.101.2 nhid 102" 1847 1848 ipv4_del_add_loop1 & 1849 pid1=$! 1850 ipv4_res_grp_replace_loop & 1851 pid2=$! 1852 ip netns exec me ping -f 172.16.101.1 >/dev/null 2>&1 & 1853 pid3=$! 1854 ip netns exec me ping -f 172.16.101.2 >/dev/null 2>&1 & 1855 pid4=$! 1856 ip netns exec me mausezahn veth1 \ 1857 -B 172.16.101.2 -A 172.16.1.1 -c 0 \ 1858 -t tcp "dp=1-1023, flags=syn" >/dev/null 2>&1 & 1859 pid5=$! 1860 1861 sleep 300 1862 kill -9 $pid1 $pid2 $pid3 $pid4 $pid5 1863 wait $pid1 $pid2 $pid3 $pid4 $pid5 2>/dev/null 1864 1865 # if we did not crash, success 1866 log_test 0 0 "IPv4 resilient nexthop group torture test" 1867} 1868 1869basic() 1870{ 1871 echo 1872 echo "Basic functional tests" 1873 echo "----------------------" 1874 run_cmd "$IP nexthop ls" 1875 log_test $? 0 "List with nothing defined" 1876 1877 run_cmd "$IP nexthop get id 1" 1878 log_test $? 2 "Nexthop get on non-existent id" 1879 1880 # attempt to create nh without a device or gw - fails 1881 run_cmd "$IP nexthop add id 1" 1882 log_test $? 2 "Nexthop with no device or gateway" 1883 1884 # attempt to create nh with down device - fails 1885 $IP li set veth1 down 1886 run_cmd "$IP nexthop add id 1 dev veth1" 1887 log_test $? 2 "Nexthop with down device" 1888 1889 # create nh with linkdown device - fails 1890 $IP li set veth1 up 1891 ip -netns peer li set veth2 down 1892 run_cmd "$IP nexthop add id 1 dev veth1" 1893 log_test $? 2 "Nexthop with device that is linkdown" 1894 ip -netns peer li set veth2 up 1895 1896 # device only 1897 run_cmd "$IP nexthop add id 1 dev veth1" 1898 log_test $? 0 "Nexthop with device only" 1899 1900 # create nh with duplicate id 1901 run_cmd "$IP nexthop add id 1 dev veth3" 1902 log_test $? 2 "Nexthop with duplicate id" 1903 1904 # blackhole nexthop 1905 run_cmd "$IP nexthop add id 2 blackhole" 1906 log_test $? 0 "Blackhole nexthop" 1907 1908 # blackhole nexthop can not have other specs 1909 run_cmd "$IP nexthop replace id 2 blackhole dev veth1" 1910 log_test $? 2 "Blackhole nexthop with other attributes" 1911 1912 # blackhole nexthop should not be affected by the state of the loopback 1913 # device 1914 run_cmd "$IP link set dev lo down" 1915 check_nexthop "id 2" "id 2 blackhole" 1916 log_test $? 0 "Blackhole nexthop with loopback device down" 1917 1918 run_cmd "$IP link set dev lo up" 1919 1920 # Dump should not loop endlessly when maximum nexthop ID is configured. 1921 run_cmd "$IP nexthop add id $((2**32-1)) blackhole" 1922 run_cmd "timeout 5 $IP nexthop" 1923 log_test $? 0 "Maximum nexthop ID dump" 1924 1925 # 1926 # groups 1927 # 1928 1929 run_cmd "$IP nexthop add id 101 group 1" 1930 log_test $? 0 "Create group" 1931 1932 run_cmd "$IP nexthop add id 102 group 2" 1933 log_test $? 0 "Create group with blackhole nexthop" 1934 1935 # multipath group can not have a blackhole as 1 path 1936 run_cmd "$IP nexthop add id 103 group 1/2" 1937 log_test $? 2 "Create multipath group where 1 path is a blackhole" 1938 1939 # multipath group can not have a member replaced by a blackhole 1940 run_cmd "$IP nexthop replace id 2 dev veth3" 1941 run_cmd "$IP nexthop replace id 102 group 1/2" 1942 run_cmd "$IP nexthop replace id 2 blackhole" 1943 log_test $? 2 "Multipath group can not have a member replaced by blackhole" 1944 1945 # attempt to create group with non-existent nexthop 1946 run_cmd "$IP nexthop add id 103 group 12" 1947 log_test $? 2 "Create group with non-existent nexthop" 1948 1949 # attempt to create group with same nexthop 1950 run_cmd "$IP nexthop add id 103 group 1/1" 1951 log_test $? 2 "Create group with same nexthop multiple times" 1952 1953 # replace nexthop with a group - fails 1954 run_cmd "$IP nexthop replace id 2 group 1" 1955 log_test $? 2 "Replace nexthop with nexthop group" 1956 1957 # replace nexthop group with a nexthop - fails 1958 run_cmd "$IP nexthop replace id 101 dev veth1" 1959 log_test $? 2 "Replace nexthop group with nexthop" 1960 1961 # nexthop group with other attributes fail 1962 run_cmd "$IP nexthop add id 104 group 1 dev veth1" 1963 log_test $? 2 "Nexthop group and device" 1964 1965 # Tests to ensure that flushing works as expected. 1966 run_cmd "$IP nexthop add id 105 blackhole proto 99" 1967 run_cmd "$IP nexthop add id 106 blackhole proto 100" 1968 run_cmd "$IP nexthop add id 107 blackhole proto 99" 1969 run_cmd "$IP nexthop flush proto 99" 1970 check_nexthop "id 105" "" 1971 check_nexthop "id 106" "id 106 blackhole proto 100" 1972 check_nexthop "id 107" "" 1973 run_cmd "$IP nexthop flush proto 100" 1974 check_nexthop "id 106" "" 1975 1976 run_cmd "$IP nexthop flush proto 100" 1977 log_test $? 0 "Test proto flush" 1978 1979 run_cmd "$IP nexthop add id 104 group 1 blackhole" 1980 log_test $? 2 "Nexthop group and blackhole" 1981 1982 $IP nexthop flush >/dev/null 2>&1 1983 1984 # Test to ensure that flushing with a multi-part nexthop dump works as 1985 # expected. 1986 local batch_file=$(mktemp) 1987 1988 for i in $(seq 1 $((64 * 1024))); do 1989 echo "nexthop add id $i blackhole" >> $batch_file 1990 done 1991 1992 $IP -b $batch_file 1993 $IP nexthop flush >/dev/null 2>&1 1994 [[ $($IP nexthop | wc -l) -eq 0 ]] 1995 log_test $? 0 "Large scale nexthop flushing" 1996 1997 rm $batch_file 1998} 1999 2000check_nexthop_buckets_balance() 2001{ 2002 local nharg=$1; shift 2003 local ret 2004 2005 while (($# > 0)); do 2006 local selector=$1; shift 2007 local condition=$1; shift 2008 local count 2009 2010 count=$($IP -j nexthop bucket ${nharg} ${selector} | jq length) 2011 (( $count $condition )) 2012 ret=$? 2013 if ((ret != 0)); then 2014 return $ret 2015 fi 2016 done 2017 2018 return 0 2019} 2020 2021basic_res() 2022{ 2023 echo 2024 echo "Basic resilient nexthop group functional tests" 2025 echo "----------------------------------------------" 2026 2027 check_nexthop_res_support 2028 if [ $? -eq $ksft_skip ]; then 2029 return $ksft_skip 2030 fi 2031 2032 run_cmd "$IP nexthop add id 1 dev veth1" 2033 2034 # 2035 # resilient nexthop group addition 2036 # 2037 2038 run_cmd "$IP nexthop add id 101 group 1 type resilient buckets 8" 2039 log_test $? 0 "Add a nexthop group with default parameters" 2040 2041 run_cmd "$IP nexthop get id 101" 2042 check_nexthop "id 101" \ 2043 "id 101 group 1 type resilient buckets 8 idle_timer 120 unbalanced_timer 0 unbalanced_time 0" 2044 log_test $? 0 "Get a nexthop group with default parameters" 2045 2046 run_cmd "$IP nexthop add id 102 group 1 type resilient 2047 buckets 4 idle_timer 100 unbalanced_timer 5" 2048 run_cmd "$IP nexthop get id 102" 2049 check_nexthop "id 102" \ 2050 "id 102 group 1 type resilient buckets 4 idle_timer 100 unbalanced_timer 5 unbalanced_time 0" 2051 log_test $? 0 "Get a nexthop group with non-default parameters" 2052 2053 run_cmd "$IP nexthop add id 103 group 1 type resilient buckets 0" 2054 log_test $? 2 "Add a nexthop group with 0 buckets" 2055 2056 # 2057 # resilient nexthop group replacement 2058 # 2059 2060 run_cmd "$IP nexthop replace id 101 group 1 type resilient 2061 buckets 8 idle_timer 240 unbalanced_timer 80" 2062 log_test $? 0 "Replace nexthop group parameters" 2063 check_nexthop "id 101" \ 2064 "id 101 group 1 type resilient buckets 8 idle_timer 240 unbalanced_timer 80 unbalanced_time 0" 2065 log_test $? 0 "Get a nexthop group after replacing parameters" 2066 2067 run_cmd "$IP nexthop replace id 101 group 1 type resilient idle_timer 512" 2068 log_test $? 0 "Replace idle timer" 2069 check_nexthop "id 101" \ 2070 "id 101 group 1 type resilient buckets 8 idle_timer 512 unbalanced_timer 80 unbalanced_time 0" 2071 log_test $? 0 "Get a nexthop group after replacing idle timer" 2072 2073 run_cmd "$IP nexthop replace id 101 group 1 type resilient unbalanced_timer 256" 2074 log_test $? 0 "Replace unbalanced timer" 2075 check_nexthop "id 101" \ 2076 "id 101 group 1 type resilient buckets 8 idle_timer 512 unbalanced_timer 256 unbalanced_time 0" 2077 log_test $? 0 "Get a nexthop group after replacing unbalanced timer" 2078 2079 run_cmd "$IP nexthop replace id 101 group 1 type resilient" 2080 log_test $? 0 "Replace with no parameters" 2081 check_nexthop "id 101" \ 2082 "id 101 group 1 type resilient buckets 8 idle_timer 512 unbalanced_timer 256 unbalanced_time 0" 2083 log_test $? 0 "Get a nexthop group after replacing no parameters" 2084 2085 run_cmd "$IP nexthop replace id 101 group 1" 2086 log_test $? 2 "Replace nexthop group type - implicit" 2087 2088 run_cmd "$IP nexthop replace id 101 group 1 type mpath" 2089 log_test $? 2 "Replace nexthop group type - explicit" 2090 2091 run_cmd "$IP nexthop replace id 101 group 1 type resilient buckets 1024" 2092 log_test $? 2 "Replace number of nexthop buckets" 2093 2094 check_nexthop "id 101" \ 2095 "id 101 group 1 type resilient buckets 8 idle_timer 512 unbalanced_timer 256 unbalanced_time 0" 2096 log_test $? 0 "Get a nexthop group after replacing with invalid parameters" 2097 2098 # 2099 # resilient nexthop buckets dump 2100 # 2101 2102 $IP nexthop flush >/dev/null 2>&1 2103 run_cmd "$IP nexthop add id 1 dev veth1" 2104 run_cmd "$IP nexthop add id 2 dev veth3" 2105 run_cmd "$IP nexthop add id 101 group 1/2 type resilient buckets 4" 2106 run_cmd "$IP nexthop add id 201 group 1/2" 2107 2108 check_nexthop_bucket "" \ 2109 "id 101 index 0 nhid 2 id 101 index 1 nhid 2 id 101 index 2 nhid 1 id 101 index 3 nhid 1" 2110 log_test $? 0 "Dump all nexthop buckets" 2111 2112 check_nexthop_bucket "list id 101" \ 2113 "id 101 index 0 nhid 2 id 101 index 1 nhid 2 id 101 index 2 nhid 1 id 101 index 3 nhid 1" 2114 log_test $? 0 "Dump all nexthop buckets in a group" 2115 2116 sleep 0.1 2117 (( $($IP -j nexthop bucket list id 101 | 2118 jq '[.[] | select(.bucket.idle_time > 0 and 2119 .bucket.idle_time < 2)] | length') == 4 )) 2120 log_test $? 0 "All nexthop buckets report a positive near-zero idle time" 2121 2122 check_nexthop_bucket "list dev veth1" \ 2123 "id 101 index 2 nhid 1 id 101 index 3 nhid 1" 2124 log_test $? 0 "Dump all nexthop buckets with a specific nexthop device" 2125 2126 check_nexthop_bucket "list nhid 2" \ 2127 "id 101 index 0 nhid 2 id 101 index 1 nhid 2" 2128 log_test $? 0 "Dump all nexthop buckets with a specific nexthop identifier" 2129 2130 run_cmd "$IP nexthop bucket list id 111" 2131 log_test $? 2 "Dump all nexthop buckets in a non-existent group" 2132 2133 run_cmd "$IP nexthop bucket list id 201" 2134 log_test $? 2 "Dump all nexthop buckets in a non-resilient group" 2135 2136 run_cmd "$IP nexthop bucket list dev bla" 2137 log_test $? 255 "Dump all nexthop buckets using a non-existent device" 2138 2139 run_cmd "$IP nexthop bucket list groups" 2140 log_test $? 255 "Dump all nexthop buckets with invalid 'groups' keyword" 2141 2142 run_cmd "$IP nexthop bucket list fdb" 2143 log_test $? 255 "Dump all nexthop buckets with invalid 'fdb' keyword" 2144 2145 # Dump should not loop endlessly when maximum nexthop ID is configured. 2146 run_cmd "$IP nexthop add id $((2**32-1)) group 1/2 type resilient buckets 4" 2147 run_cmd "timeout 5 $IP nexthop bucket" 2148 log_test $? 0 "Maximum nexthop ID dump" 2149 2150 # 2151 # resilient nexthop buckets get requests 2152 # 2153 2154 check_nexthop_bucket "get id 101 index 0" "id 101 index 0 nhid 2" 2155 log_test $? 0 "Get a valid nexthop bucket" 2156 2157 run_cmd "$IP nexthop bucket get id 101 index 999" 2158 log_test $? 2 "Get a nexthop bucket with valid group, but invalid index" 2159 2160 run_cmd "$IP nexthop bucket get id 201 index 0" 2161 log_test $? 2 "Get a nexthop bucket from a non-resilient group" 2162 2163 run_cmd "$IP nexthop bucket get id 999 index 0" 2164 log_test $? 2 "Get a nexthop bucket from a non-existent group" 2165 2166 # 2167 # tests for bucket migration 2168 # 2169 2170 $IP nexthop flush >/dev/null 2>&1 2171 2172 run_cmd "$IP nexthop add id 1 dev veth1" 2173 run_cmd "$IP nexthop add id 2 dev veth3" 2174 run_cmd "$IP nexthop add id 101 2175 group 1/2 type resilient buckets 10 2176 idle_timer 1 unbalanced_timer 20" 2177 2178 check_nexthop_buckets_balance "list id 101" \ 2179 "nhid 1" "== 5" \ 2180 "nhid 2" "== 5" 2181 log_test $? 0 "Initial bucket allocation" 2182 2183 run_cmd "$IP nexthop replace id 101 2184 group 1,2/2,3 type resilient" 2185 check_nexthop_buckets_balance "list id 101" \ 2186 "nhid 1" "== 4" \ 2187 "nhid 2" "== 6" 2188 log_test $? 0 "Bucket allocation after replace" 2189 2190 # Check that increase in idle timer does not make buckets appear busy. 2191 run_cmd "$IP nexthop replace id 101 2192 group 1,2/2,3 type resilient 2193 idle_timer 10" 2194 run_cmd "$IP nexthop replace id 101 2195 group 1/2 type resilient" 2196 check_nexthop_buckets_balance "list id 101" \ 2197 "nhid 1" "== 5" \ 2198 "nhid 2" "== 5" 2199 log_test $? 0 "Buckets migrated after idle timer change" 2200 2201 $IP nexthop flush >/dev/null 2>&1 2202} 2203 2204################################################################################ 2205# usage 2206 2207usage() 2208{ 2209 cat <<EOF 2210usage: ${0##*/} OPTS 2211 2212 -t <test> Test(s) to run (default: all) 2213 (options: $ALL_TESTS) 2214 -4 IPv4 tests only 2215 -6 IPv6 tests only 2216 -p Pause on fail 2217 -P Pause after each test before cleanup 2218 -v verbose mode (show commands and output) 2219 2220 Runtime test 2221 -n num Number of nexthops to target 2222 -N Use new style to install routes in DUT 2223 2224done 2225EOF 2226} 2227 2228################################################################################ 2229# main 2230 2231while getopts :t:pP46hv o 2232do 2233 case $o in 2234 t) TESTS=$OPTARG;; 2235 4) TESTS=${IPV4_TESTS};; 2236 6) TESTS=${IPV6_TESTS};; 2237 p) PAUSE_ON_FAIL=yes;; 2238 P) PAUSE=yes;; 2239 v) VERBOSE=$(($VERBOSE + 1));; 2240 h) usage; exit 0;; 2241 *) usage; exit 1;; 2242 esac 2243done 2244 2245# make sure we don't pause twice 2246[ "${PAUSE}" = "yes" ] && PAUSE_ON_FAIL=no 2247 2248if [ "$(id -u)" -ne 0 ];then 2249 echo "SKIP: Need root privileges" 2250 exit $ksft_skip; 2251fi 2252 2253if [ ! -x "$(command -v ip)" ]; then 2254 echo "SKIP: Could not run test without ip tool" 2255 exit $ksft_skip 2256fi 2257 2258ip help 2>&1 | grep -q nexthop 2259if [ $? -ne 0 ]; then 2260 echo "SKIP: iproute2 too old, missing nexthop command" 2261 exit $ksft_skip 2262fi 2263 2264out=$(ip nexthop ls 2>&1 | grep -q "Operation not supported") 2265if [ $? -eq 0 ]; then 2266 echo "SKIP: kernel lacks nexthop support" 2267 exit $ksft_skip 2268fi 2269 2270for t in $TESTS 2271do 2272 case $t in 2273 none) IP="ip -netns peer"; setup; exit 0;; 2274 *) setup; $t; cleanup;; 2275 esac 2276done 2277 2278if [ "$TESTS" != "none" ]; then 2279 printf "\nTests passed: %3d\n" ${nsuccess} 2280 printf "Tests failed: %3d\n" ${nfail} 2281fi 2282 2283exit $ret 2284