Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

selftests: fib_nexthops: Test resilient nexthop groups

Add test cases for resilient nexthop groups. Exhaustive forwarding tests
are added separately under net/forwarding/.

Examples:

# ./fib_nexthops.sh -t basic_res

Basic resilient nexthop group functional tests
----------------------------------------------
TEST: Add a nexthop group with default parameters [ OK ]
TEST: Get a nexthop group with default parameters [ OK ]
TEST: Get a nexthop group with non-default parameters [ OK ]
TEST: Add a nexthop group with 0 buckets [ OK ]
TEST: Replace nexthop group parameters [ OK ]
TEST: Get a nexthop group after replacing parameters [ OK ]
TEST: Replace idle timer [ OK ]
TEST: Get a nexthop group after replacing idle timer [ OK ]
TEST: Replace unbalanced timer [ OK ]
TEST: Get a nexthop group after replacing unbalanced timer [ OK ]
TEST: Replace with no parameters [ OK ]
TEST: Get a nexthop group after replacing no parameters [ OK ]
TEST: Replace nexthop group type - implicit [ OK ]
TEST: Replace nexthop group type - explicit [ OK ]
TEST: Replace number of nexthop buckets [ OK ]
TEST: Get a nexthop group after replacing with invalid parameters [ OK ]
TEST: Dump all nexthop buckets [ OK ]
TEST: Dump all nexthop buckets in a group [ OK ]
TEST: Dump all nexthop buckets with a specific nexthop device [ OK ]
TEST: Dump all nexthop buckets with a specific nexthop identifier [ OK ]
TEST: Dump all nexthop buckets in a non-existent group [ OK ]
TEST: Dump all nexthop buckets in a non-resilient group [ OK ]
TEST: Dump all nexthop buckets using a non-existent device [ OK ]
TEST: Dump all nexthop buckets with invalid 'groups' keyword [ OK ]
TEST: Dump all nexthop buckets with invalid 'fdb' keyword [ OK ]
TEST: Get a valid nexthop bucket [ OK ]
TEST: Get a nexthop bucket with valid group, but invalid index [ OK ]
TEST: Get a nexthop bucket from a non-resilient group [ OK ]
TEST: Get a nexthop bucket from a non-existent group [ OK ]

Tests passed: 29
Tests failed: 0

# ./fib_nexthops.sh -t ipv4_large_res_grp

IPv4 large resilient group (128k buckets)
-----------------------------------------
TEST: Dump large (x131072) nexthop buckets [ OK ]

Tests passed: 1
Tests failed: 0

# ./fib_nexthops.sh -t ipv6_large_res_grp

IPv6 large resilient group (128k buckets)
-----------------------------------------
TEST: Dump large (x131072) nexthop buckets [ OK ]

Tests passed: 1
Tests failed: 0

# ./fib_nexthops.sh -t ipv4_res_torture

IPv4 runtime resilient nexthop group torture
--------------------------------------------
TEST: IPv4 resilient nexthop group torture test [ OK ]

Tests passed: 1
Tests failed: 0

# ./fib_nexthops.sh -t ipv6_res_torture

IPv6 runtime resilient nexthop group torture
--------------------------------------------
TEST: IPv6 resilient nexthop group torture test [ OK ]

Tests passed: 1
Tests failed: 0

# ./fib_nexthops.sh -t ipv4_res_grp_fcnal

IPv4 resilient groups functional
--------------------------------
TEST: Nexthop group updated when entry is deleted [ OK ]
TEST: Nexthop buckets updated when entry is deleted [ OK ]
TEST: Nexthop group updated after replace [ OK ]
TEST: Nexthop buckets updated after replace [ OK ]
TEST: Nexthop group updated when entry is deleted - nECMP [ OK ]
TEST: Nexthop buckets updated when entry is deleted - nECMP [ OK ]
TEST: Nexthop group updated after replace - nECMP [ OK ]
TEST: Nexthop buckets updated after replace - nECMP [ OK ]

Tests passed: 8
Tests failed: 0

# ./fib_nexthops.sh -t ipv6_res_grp_fcnal

IPv6 resilient groups functional
--------------------------------
TEST: Nexthop group updated when entry is deleted [ OK ]
TEST: Nexthop buckets updated when entry is deleted [ OK ]
TEST: Nexthop group updated after replace [ OK ]
TEST: Nexthop buckets updated after replace [ OK ]
TEST: Nexthop group updated when entry is deleted - nECMP [ OK ]
TEST: Nexthop buckets updated when entry is deleted - nECMP [ OK ]
TEST: Nexthop group updated after replace - nECMP [ OK ]
TEST: Nexthop buckets updated after replace - nECMP [ OK ]

Tests passed: 8
Tests failed: 0

Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Co-developed-by: Petr Machata <petrm@nvidia.com>
Signed-off-by: Petr Machata <petrm@nvidia.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Ido Schimmel and committed by
David S. Miller
557205f4 a8f9952d

+517
+517
tools/testing/selftests/net/fib_nexthops.sh
··· 22 22 IPV4_TESTS=" 23 23 ipv4_fcnal 24 24 ipv4_grp_fcnal 25 + ipv4_res_grp_fcnal 25 26 ipv4_withv6_fcnal 26 27 ipv4_fcnal_runtime 27 28 ipv4_large_grp 29 + ipv4_large_res_grp 28 30 ipv4_compat_mode 29 31 ipv4_fdb_grp_fcnal 30 32 ipv4_torture 33 + ipv4_res_torture 31 34 " 32 35 33 36 IPV6_TESTS=" 34 37 ipv6_fcnal 35 38 ipv6_grp_fcnal 39 + ipv6_res_grp_fcnal 36 40 ipv6_fcnal_runtime 37 41 ipv6_large_grp 42 + ipv6_large_res_grp 38 43 ipv6_compat_mode 39 44 ipv6_fdb_grp_fcnal 40 45 ipv6_torture 46 + ipv6_res_torture 41 47 " 42 48 43 49 ALL_TESTS=" 44 50 basic 51 + basic_res 45 52 ${IPV4_TESTS} 46 53 ${IPV6_TESTS} 47 54 " ··· 261 254 check_output "${out}" "${expected}" 262 255 } 263 256 257 + check_nexthop_bucket() 258 + { 259 + local nharg="$1" 260 + local expected="$2" 261 + local out 262 + 263 + # remove the idle time since we cannot match it 264 + out=$($IP nexthop bucket ${nharg} \ 265 + | sed s/idle_time\ [0-9.]*\ // 2>/dev/null) 266 + 267 + check_output "${out}" "${expected}" 268 + } 269 + 264 270 check_route() 265 271 { 266 272 local pfx="$1" ··· 350 330 log_test $? 0 "Dump large (x$ecmp) ecmp groups" 351 331 } 352 332 333 + check_large_res_grp() 334 + { 335 + local ipv=$1 336 + local buckets=$2 337 + local ipstr="" 338 + 339 + if [ $ipv -eq 4 ]; then 340 + ipstr="172.16.1.2" 341 + else 342 + ipstr="2001:db8:91::2" 343 + fi 344 + 345 + # create a resilient group with $buckets buckets and dump them 346 + run_cmd "$IP nexthop add id 100 via $ipstr dev veth1" 347 + run_cmd "$IP nexthop add id 1000 group 100 type resilient buckets $buckets" 348 + run_cmd "$IP nexthop bucket list" 349 + log_test $? 0 "Dump large (x$buckets) nexthop buckets" 350 + } 351 + 353 352 start_ip_monitor() 354 353 { 355 354 local mtype=$1 ··· 401 362 $IP nexthop help 2>&1 | grep -q fdb 402 363 if [ $? -ne 0 ]; then 403 364 echo "SKIP: iproute2 too old, missing fdb nexthop support" 365 + return $ksft_skip 366 + fi 367 + } 368 + 369 + check_nexthop_res_support() 370 + { 371 + $IP nexthop help 2>&1 | grep -q resilient 372 + if [ $? -ne 0 ]; then 373 + echo "SKIP: iproute2 too old, missing resilient nexthop group support" 404 374 return $ksft_skip 405 375 fi 406 376 } ··· 736 688 log_test $? 2 "Nexthop group can not have a blackhole and another nexthop" 737 689 } 738 690 691 + ipv6_res_grp_fcnal() 692 + { 693 + local rc 694 + 695 + echo 696 + echo "IPv6 resilient groups functional" 697 + echo "--------------------------------" 698 + 699 + check_nexthop_res_support 700 + if [ $? -eq $ksft_skip ]; then 701 + return $ksft_skip 702 + fi 703 + 704 + # 705 + # migration of nexthop buckets - equal weights 706 + # 707 + run_cmd "$IP nexthop add id 62 via 2001:db8:91::2 dev veth1" 708 + run_cmd "$IP nexthop add id 63 via 2001:db8:91::3 dev veth1" 709 + run_cmd "$IP nexthop add id 102 group 62/63 type resilient buckets 2 idle_timer 0" 710 + 711 + run_cmd "$IP nexthop del id 63" 712 + check_nexthop "id 102" \ 713 + "id 102 group 62 type resilient buckets 2 idle_timer 0 unbalanced_timer 0 unbalanced_time 0" 714 + log_test $? 0 "Nexthop group updated when entry is deleted" 715 + check_nexthop_bucket "list id 102" \ 716 + "id 102 index 0 nhid 62 id 102 index 1 nhid 62" 717 + log_test $? 0 "Nexthop buckets updated when entry is deleted" 718 + 719 + run_cmd "$IP nexthop add id 63 via 2001:db8:91::3 dev veth1" 720 + run_cmd "$IP nexthop replace id 102 group 62/63 type resilient buckets 2 idle_timer 0" 721 + check_nexthop "id 102" \ 722 + "id 102 group 62/63 type resilient buckets 2 idle_timer 0 unbalanced_timer 0 unbalanced_time 0" 723 + log_test $? 0 "Nexthop group updated after replace" 724 + check_nexthop_bucket "list id 102" \ 725 + "id 102 index 0 nhid 63 id 102 index 1 nhid 62" 726 + log_test $? 0 "Nexthop buckets updated after replace" 727 + 728 + $IP nexthop flush >/dev/null 2>&1 729 + 730 + # 731 + # migration of nexthop buckets - unequal weights 732 + # 733 + run_cmd "$IP nexthop add id 62 via 2001:db8:91::2 dev veth1" 734 + run_cmd "$IP nexthop add id 63 via 2001:db8:91::3 dev veth1" 735 + run_cmd "$IP nexthop add id 102 group 62,3/63,1 type resilient buckets 4 idle_timer 0" 736 + 737 + run_cmd "$IP nexthop del id 63" 738 + check_nexthop "id 102" \ 739 + "id 102 group 62,3 type resilient buckets 4 idle_timer 0 unbalanced_timer 0 unbalanced_time 0" 740 + log_test $? 0 "Nexthop group updated when entry is deleted - nECMP" 741 + check_nexthop_bucket "list id 102" \ 742 + "id 102 index 0 nhid 62 id 102 index 1 nhid 62 id 102 index 2 nhid 62 id 102 index 3 nhid 62" 743 + log_test $? 0 "Nexthop buckets updated when entry is deleted - nECMP" 744 + 745 + run_cmd "$IP nexthop add id 63 via 2001:db8:91::3 dev veth1" 746 + run_cmd "$IP nexthop replace id 102 group 62,3/63,1 type resilient buckets 4 idle_timer 0" 747 + check_nexthop "id 102" \ 748 + "id 102 group 62,3/63 type resilient buckets 4 idle_timer 0 unbalanced_timer 0 unbalanced_time 0" 749 + log_test $? 0 "Nexthop group updated after replace - nECMP" 750 + check_nexthop_bucket "list id 102" \ 751 + "id 102 index 0 nhid 63 id 102 index 1 nhid 62 id 102 index 2 nhid 62 id 102 index 3 nhid 62" 752 + log_test $? 0 "Nexthop buckets updated after replace - nECMP" 753 + } 754 + 739 755 ipv6_fcnal_runtime() 740 756 { 741 757 local rc ··· 958 846 $IP nexthop flush >/dev/null 2>&1 959 847 } 960 848 849 + ipv6_large_res_grp() 850 + { 851 + echo 852 + echo "IPv6 large resilient group (128k buckets)" 853 + echo "-----------------------------------------" 854 + 855 + check_nexthop_res_support 856 + if [ $? -eq $ksft_skip ]; then 857 + return $ksft_skip 858 + fi 859 + 860 + check_large_res_grp 6 $((128 * 1024)) 861 + 862 + $IP nexthop flush >/dev/null 2>&1 863 + } 864 + 961 865 ipv6_del_add_loop1() 962 866 { 963 867 while :; do ··· 1030 902 log_test 0 0 "IPv6 torture test" 1031 903 } 1032 904 905 + ipv6_res_grp_replace_loop() 906 + { 907 + while :; do 908 + $IP nexthop replace id 102 group 100/101 type resilient 909 + done >/dev/null 2>&1 910 + } 911 + 912 + ipv6_res_torture() 913 + { 914 + local pid1 915 + local pid2 916 + local pid3 917 + local pid4 918 + local pid5 919 + 920 + echo 921 + echo "IPv6 runtime resilient nexthop group torture" 922 + echo "--------------------------------------------" 923 + 924 + check_nexthop_res_support 925 + if [ $? -eq $ksft_skip ]; then 926 + return $ksft_skip 927 + fi 928 + 929 + if [ ! -x "$(command -v mausezahn)" ]; then 930 + echo "SKIP: Could not run test; need mausezahn tool" 931 + return 932 + fi 933 + 934 + run_cmd "$IP nexthop add id 100 via 2001:db8:91::2 dev veth1" 935 + run_cmd "$IP nexthop add id 101 via 2001:db8:92::2 dev veth3" 936 + run_cmd "$IP nexthop add id 102 group 100/101 type resilient buckets 512 idle_timer 0" 937 + run_cmd "$IP route add 2001:db8:101::1 nhid 102" 938 + run_cmd "$IP route add 2001:db8:101::2 nhid 102" 939 + 940 + ipv6_del_add_loop1 & 941 + pid1=$! 942 + ipv6_res_grp_replace_loop & 943 + pid2=$! 944 + ip netns exec me ping -f 2001:db8:101::1 >/dev/null 2>&1 & 945 + pid3=$! 946 + ip netns exec me ping -f 2001:db8:101::2 >/dev/null 2>&1 & 947 + pid4=$! 948 + ip netns exec me mausezahn -6 veth1 \ 949 + -B 2001:db8:101::2 -A 2001:db8:91::1 -c 0 \ 950 + -t tcp "dp=1-1023, flags=syn" >/dev/null 2>&1 & 951 + pid5=$! 952 + 953 + sleep 300 954 + kill -9 $pid1 $pid2 $pid3 $pid4 $pid5 955 + wait $pid1 $pid2 $pid3 $pid4 $pid5 2>/dev/null 956 + 957 + # if we did not crash, success 958 + log_test 0 0 "IPv6 resilient nexthop group torture test" 959 + } 1033 960 1034 961 ipv4_fcnal() 1035 962 { ··· 1242 1059 1243 1060 run_cmd "$IP nexthop add id 108 group 31/24" 1244 1061 log_test $? 2 "Nexthop group can not have a blackhole and another nexthop" 1062 + } 1063 + 1064 + ipv4_res_grp_fcnal() 1065 + { 1066 + local rc 1067 + 1068 + echo 1069 + echo "IPv4 resilient groups functional" 1070 + echo "--------------------------------" 1071 + 1072 + check_nexthop_res_support 1073 + if [ $? -eq $ksft_skip ]; then 1074 + return $ksft_skip 1075 + fi 1076 + 1077 + # 1078 + # migration of nexthop buckets - equal weights 1079 + # 1080 + run_cmd "$IP nexthop add id 12 via 172.16.1.2 dev veth1" 1081 + run_cmd "$IP nexthop add id 13 via 172.16.1.3 dev veth1" 1082 + run_cmd "$IP nexthop add id 102 group 12/13 type resilient buckets 2 idle_timer 0" 1083 + 1084 + run_cmd "$IP nexthop del id 13" 1085 + check_nexthop "id 102" \ 1086 + "id 102 group 12 type resilient buckets 2 idle_timer 0 unbalanced_timer 0 unbalanced_time 0" 1087 + log_test $? 0 "Nexthop group updated when entry is deleted" 1088 + check_nexthop_bucket "list id 102" \ 1089 + "id 102 index 0 nhid 12 id 102 index 1 nhid 12" 1090 + log_test $? 0 "Nexthop buckets updated when entry is deleted" 1091 + 1092 + run_cmd "$IP nexthop add id 13 via 172.16.1.3 dev veth1" 1093 + run_cmd "$IP nexthop replace id 102 group 12/13 type resilient buckets 2 idle_timer 0" 1094 + check_nexthop "id 102" \ 1095 + "id 102 group 12/13 type resilient buckets 2 idle_timer 0 unbalanced_timer 0 unbalanced_time 0" 1096 + log_test $? 0 "Nexthop group updated after replace" 1097 + check_nexthop_bucket "list id 102" \ 1098 + "id 102 index 0 nhid 13 id 102 index 1 nhid 12" 1099 + log_test $? 0 "Nexthop buckets updated after replace" 1100 + 1101 + $IP nexthop flush >/dev/null 2>&1 1102 + 1103 + # 1104 + # migration of nexthop buckets - unequal weights 1105 + # 1106 + run_cmd "$IP nexthop add id 12 via 172.16.1.2 dev veth1" 1107 + run_cmd "$IP nexthop add id 13 via 172.16.1.3 dev veth1" 1108 + run_cmd "$IP nexthop add id 102 group 12,3/13,1 type resilient buckets 4 idle_timer 0" 1109 + 1110 + run_cmd "$IP nexthop del id 13" 1111 + check_nexthop "id 102" \ 1112 + "id 102 group 12,3 type resilient buckets 4 idle_timer 0 unbalanced_timer 0 unbalanced_time 0" 1113 + log_test $? 0 "Nexthop group updated when entry is deleted - nECMP" 1114 + check_nexthop_bucket "list id 102" \ 1115 + "id 102 index 0 nhid 12 id 102 index 1 nhid 12 id 102 index 2 nhid 12 id 102 index 3 nhid 12" 1116 + log_test $? 0 "Nexthop buckets updated when entry is deleted - nECMP" 1117 + 1118 + run_cmd "$IP nexthop add id 13 via 172.16.1.3 dev veth1" 1119 + run_cmd "$IP nexthop replace id 102 group 12,3/13,1 type resilient buckets 4 idle_timer 0" 1120 + check_nexthop "id 102" \ 1121 + "id 102 group 12,3/13 type resilient buckets 4 idle_timer 0 unbalanced_timer 0 unbalanced_time 0" 1122 + log_test $? 0 "Nexthop group updated after replace - nECMP" 1123 + check_nexthop_bucket "list id 102" \ 1124 + "id 102 index 0 nhid 13 id 102 index 1 nhid 12 id 102 index 2 nhid 12 id 102 index 3 nhid 12" 1125 + log_test $? 0 "Nexthop buckets updated after replace - nECMP" 1245 1126 } 1246 1127 1247 1128 ipv4_withv6_fcnal() ··· 1525 1278 echo "---------------------" 1526 1279 1527 1280 check_large_grp 4 $ecmp 1281 + 1282 + $IP nexthop flush >/dev/null 2>&1 1283 + } 1284 + 1285 + ipv4_large_res_grp() 1286 + { 1287 + echo 1288 + echo "IPv4 large resilient group (128k buckets)" 1289 + echo "-----------------------------------------" 1290 + 1291 + check_nexthop_res_support 1292 + if [ $? -eq $ksft_skip ]; then 1293 + return $ksft_skip 1294 + fi 1295 + 1296 + check_large_res_grp 4 $((128 * 1024)) 1528 1297 1529 1298 $IP nexthop flush >/dev/null 2>&1 1530 1299 } ··· 1768 1505 log_test 0 0 "IPv4 torture test" 1769 1506 } 1770 1507 1508 + ipv4_res_grp_replace_loop() 1509 + { 1510 + while :; do 1511 + $IP nexthop replace id 102 group 100/101 type resilient 1512 + done >/dev/null 2>&1 1513 + } 1514 + 1515 + ipv4_res_torture() 1516 + { 1517 + local pid1 1518 + local pid2 1519 + local pid3 1520 + local pid4 1521 + local pid5 1522 + 1523 + echo 1524 + echo "IPv4 runtime resilient nexthop group torture" 1525 + echo "--------------------------------------------" 1526 + 1527 + check_nexthop_res_support 1528 + if [ $? -eq $ksft_skip ]; then 1529 + return $ksft_skip 1530 + fi 1531 + 1532 + if [ ! -x "$(command -v mausezahn)" ]; then 1533 + echo "SKIP: Could not run test; need mausezahn tool" 1534 + return 1535 + fi 1536 + 1537 + run_cmd "$IP nexthop add id 100 via 172.16.1.2 dev veth1" 1538 + run_cmd "$IP nexthop add id 101 via 172.16.2.2 dev veth3" 1539 + run_cmd "$IP nexthop add id 102 group 100/101 type resilient buckets 512 idle_timer 0" 1540 + run_cmd "$IP route add 172.16.101.1 nhid 102" 1541 + run_cmd "$IP route add 172.16.101.2 nhid 102" 1542 + 1543 + ipv4_del_add_loop1 & 1544 + pid1=$! 1545 + ipv4_res_grp_replace_loop & 1546 + pid2=$! 1547 + ip netns exec me ping -f 172.16.101.1 >/dev/null 2>&1 & 1548 + pid3=$! 1549 + ip netns exec me ping -f 172.16.101.2 >/dev/null 2>&1 & 1550 + pid4=$! 1551 + ip netns exec me mausezahn veth1 \ 1552 + -B 172.16.101.2 -A 172.16.1.1 -c 0 \ 1553 + -t tcp "dp=1-1023, flags=syn" >/dev/null 2>&1 & 1554 + pid5=$! 1555 + 1556 + sleep 300 1557 + kill -9 $pid1 $pid2 $pid3 $pid4 $pid5 1558 + wait $pid1 $pid2 $pid3 $pid4 $pid5 2>/dev/null 1559 + 1560 + # if we did not crash, success 1561 + log_test 0 0 "IPv4 resilient nexthop group torture test" 1562 + } 1563 + 1771 1564 basic() 1772 1565 { 1773 1566 echo ··· 1931 1612 1932 1613 run_cmd "$IP nexthop add id 104 group 1 blackhole" 1933 1614 log_test $? 2 "Nexthop group and blackhole" 1615 + 1616 + $IP nexthop flush >/dev/null 2>&1 1617 + } 1618 + 1619 + check_nexthop_buckets_balance() 1620 + { 1621 + local nharg=$1; shift 1622 + local ret 1623 + 1624 + while (($# > 0)); do 1625 + local selector=$1; shift 1626 + local condition=$1; shift 1627 + local count 1628 + 1629 + count=$($IP -j nexthop bucket ${nharg} ${selector} | jq length) 1630 + (( $count $condition )) 1631 + ret=$? 1632 + if ((ret != 0)); then 1633 + return $ret 1634 + fi 1635 + done 1636 + 1637 + return 0 1638 + } 1639 + 1640 + basic_res() 1641 + { 1642 + echo 1643 + echo "Basic resilient nexthop group functional tests" 1644 + echo "----------------------------------------------" 1645 + 1646 + check_nexthop_res_support 1647 + if [ $? -eq $ksft_skip ]; then 1648 + return $ksft_skip 1649 + fi 1650 + 1651 + run_cmd "$IP nexthop add id 1 dev veth1" 1652 + 1653 + # 1654 + # resilient nexthop group addition 1655 + # 1656 + 1657 + run_cmd "$IP nexthop add id 101 group 1 type resilient buckets 8" 1658 + log_test $? 0 "Add a nexthop group with default parameters" 1659 + 1660 + run_cmd "$IP nexthop get id 101" 1661 + check_nexthop "id 101" \ 1662 + "id 101 group 1 type resilient buckets 8 idle_timer 120 unbalanced_timer 0 unbalanced_time 0" 1663 + log_test $? 0 "Get a nexthop group with default parameters" 1664 + 1665 + run_cmd "$IP nexthop add id 102 group 1 type resilient 1666 + buckets 4 idle_timer 100 unbalanced_timer 5" 1667 + run_cmd "$IP nexthop get id 102" 1668 + check_nexthop "id 102" \ 1669 + "id 102 group 1 type resilient buckets 4 idle_timer 100 unbalanced_timer 5 unbalanced_time 0" 1670 + log_test $? 0 "Get a nexthop group with non-default parameters" 1671 + 1672 + run_cmd "$IP nexthop add id 103 group 1 type resilient buckets 0" 1673 + log_test $? 2 "Add a nexthop group with 0 buckets" 1674 + 1675 + # 1676 + # resilient nexthop group replacement 1677 + # 1678 + 1679 + run_cmd "$IP nexthop replace id 101 group 1 type resilient 1680 + buckets 8 idle_timer 240 unbalanced_timer 80" 1681 + log_test $? 0 "Replace nexthop group parameters" 1682 + check_nexthop "id 101" \ 1683 + "id 101 group 1 type resilient buckets 8 idle_timer 240 unbalanced_timer 80 unbalanced_time 0" 1684 + log_test $? 0 "Get a nexthop group after replacing parameters" 1685 + 1686 + run_cmd "$IP nexthop replace id 101 group 1 type resilient idle_timer 512" 1687 + log_test $? 0 "Replace idle timer" 1688 + check_nexthop "id 101" \ 1689 + "id 101 group 1 type resilient buckets 8 idle_timer 512 unbalanced_timer 80 unbalanced_time 0" 1690 + log_test $? 0 "Get a nexthop group after replacing idle timer" 1691 + 1692 + run_cmd "$IP nexthop replace id 101 group 1 type resilient unbalanced_timer 256" 1693 + log_test $? 0 "Replace unbalanced timer" 1694 + check_nexthop "id 101" \ 1695 + "id 101 group 1 type resilient buckets 8 idle_timer 512 unbalanced_timer 256 unbalanced_time 0" 1696 + log_test $? 0 "Get a nexthop group after replacing unbalanced timer" 1697 + 1698 + run_cmd "$IP nexthop replace id 101 group 1 type resilient" 1699 + log_test $? 0 "Replace with no parameters" 1700 + check_nexthop "id 101" \ 1701 + "id 101 group 1 type resilient buckets 8 idle_timer 512 unbalanced_timer 256 unbalanced_time 0" 1702 + log_test $? 0 "Get a nexthop group after replacing no parameters" 1703 + 1704 + run_cmd "$IP nexthop replace id 101 group 1" 1705 + log_test $? 2 "Replace nexthop group type - implicit" 1706 + 1707 + run_cmd "$IP nexthop replace id 101 group 1 type mpath" 1708 + log_test $? 2 "Replace nexthop group type - explicit" 1709 + 1710 + run_cmd "$IP nexthop replace id 101 group 1 type resilient buckets 1024" 1711 + log_test $? 2 "Replace number of nexthop buckets" 1712 + 1713 + check_nexthop "id 101" \ 1714 + "id 101 group 1 type resilient buckets 8 idle_timer 512 unbalanced_timer 256 unbalanced_time 0" 1715 + log_test $? 0 "Get a nexthop group after replacing with invalid parameters" 1716 + 1717 + # 1718 + # resilient nexthop buckets dump 1719 + # 1720 + 1721 + $IP nexthop flush >/dev/null 2>&1 1722 + run_cmd "$IP nexthop add id 1 dev veth1" 1723 + run_cmd "$IP nexthop add id 2 dev veth3" 1724 + run_cmd "$IP nexthop add id 101 group 1/2 type resilient buckets 4" 1725 + run_cmd "$IP nexthop add id 201 group 1/2" 1726 + 1727 + check_nexthop_bucket "" \ 1728 + "id 101 index 0 nhid 2 id 101 index 1 nhid 2 id 101 index 2 nhid 1 id 101 index 3 nhid 1" 1729 + log_test $? 0 "Dump all nexthop buckets" 1730 + 1731 + check_nexthop_bucket "list id 101" \ 1732 + "id 101 index 0 nhid 2 id 101 index 1 nhid 2 id 101 index 2 nhid 1 id 101 index 3 nhid 1" 1733 + log_test $? 0 "Dump all nexthop buckets in a group" 1734 + 1735 + (( $($IP -j nexthop bucket list id 101 | 1736 + jq '[.[] | select(.bucket.idle_time > 0 and 1737 + .bucket.idle_time < 2)] | length') == 4 )) 1738 + log_test $? 0 "All nexthop buckets report a positive near-zero idle time" 1739 + 1740 + check_nexthop_bucket "list dev veth1" \ 1741 + "id 101 index 2 nhid 1 id 101 index 3 nhid 1" 1742 + log_test $? 0 "Dump all nexthop buckets with a specific nexthop device" 1743 + 1744 + check_nexthop_bucket "list nhid 2" \ 1745 + "id 101 index 0 nhid 2 id 101 index 1 nhid 2" 1746 + log_test $? 0 "Dump all nexthop buckets with a specific nexthop identifier" 1747 + 1748 + run_cmd "$IP nexthop bucket list id 111" 1749 + log_test $? 2 "Dump all nexthop buckets in a non-existent group" 1750 + 1751 + run_cmd "$IP nexthop bucket list id 201" 1752 + log_test $? 2 "Dump all nexthop buckets in a non-resilient group" 1753 + 1754 + run_cmd "$IP nexthop bucket list dev bla" 1755 + log_test $? 255 "Dump all nexthop buckets using a non-existent device" 1756 + 1757 + run_cmd "$IP nexthop bucket list groups" 1758 + log_test $? 255 "Dump all nexthop buckets with invalid 'groups' keyword" 1759 + 1760 + run_cmd "$IP nexthop bucket list fdb" 1761 + log_test $? 255 "Dump all nexthop buckets with invalid 'fdb' keyword" 1762 + 1763 + # 1764 + # resilient nexthop buckets get requests 1765 + # 1766 + 1767 + check_nexthop_bucket "get id 101 index 0" "id 101 index 0 nhid 2" 1768 + log_test $? 0 "Get a valid nexthop bucket" 1769 + 1770 + run_cmd "$IP nexthop bucket get id 101 index 999" 1771 + log_test $? 2 "Get a nexthop bucket with valid group, but invalid index" 1772 + 1773 + run_cmd "$IP nexthop bucket get id 201 index 0" 1774 + log_test $? 2 "Get a nexthop bucket from a non-resilient group" 1775 + 1776 + run_cmd "$IP nexthop bucket get id 999 index 0" 1777 + log_test $? 2 "Get a nexthop bucket from a non-existent group" 1778 + 1779 + # 1780 + # tests for bucket migration 1781 + # 1782 + 1783 + $IP nexthop flush >/dev/null 2>&1 1784 + 1785 + run_cmd "$IP nexthop add id 1 dev veth1" 1786 + run_cmd "$IP nexthop add id 2 dev veth3" 1787 + run_cmd "$IP nexthop add id 101 1788 + group 1/2 type resilient buckets 10 1789 + idle_timer 1 unbalanced_timer 20" 1790 + 1791 + check_nexthop_buckets_balance "list id 101" \ 1792 + "nhid 1" "== 5" \ 1793 + "nhid 2" "== 5" 1794 + log_test $? 0 "Initial bucket allocation" 1795 + 1796 + run_cmd "$IP nexthop replace id 101 1797 + group 1,2/2,3 type resilient" 1798 + check_nexthop_buckets_balance "list id 101" \ 1799 + "nhid 1" "== 4" \ 1800 + "nhid 2" "== 6" 1801 + log_test $? 0 "Bucket allocation after replace" 1802 + 1803 + # Check that increase in idle timer does not make buckets appear busy. 1804 + run_cmd "$IP nexthop replace id 101 1805 + group 1,2/2,3 type resilient 1806 + idle_timer 10" 1807 + run_cmd "$IP nexthop replace id 101 1808 + group 1/2 type resilient" 1809 + check_nexthop_buckets_balance "list id 101" \ 1810 + "nhid 1" "== 5" \ 1811 + "nhid 2" "== 5" 1812 + log_test $? 0 "Buckets migrated after idle timer change" 1934 1813 1935 1814 $IP nexthop flush >/dev/null 2>&1 1936 1815 }