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