| #!/bin/bash |
| # SPDX-License-Identifier: GPL-2.0 |
| # |
| # This test is for checking the nexthop offload API. It makes use of netdevsim |
| # which registers a listener to the nexthop notification chain. |
| |
| lib_dir=$(dirname $0)/../../../net/forwarding |
| |
| ALL_TESTS=" |
| nexthop_single_add_test |
| nexthop_single_add_err_test |
| nexthop_group_add_test |
| nexthop_group_add_err_test |
| nexthop_res_group_add_test |
| nexthop_res_group_add_err_test |
| nexthop_group_replace_test |
| nexthop_group_replace_err_test |
| nexthop_res_group_replace_test |
| nexthop_res_group_replace_err_test |
| nexthop_res_group_idle_timer_test |
| nexthop_res_group_idle_timer_del_test |
| nexthop_res_group_increase_idle_timer_test |
| nexthop_res_group_decrease_idle_timer_test |
| nexthop_res_group_unbalanced_timer_test |
| nexthop_res_group_unbalanced_timer_del_test |
| nexthop_res_group_no_unbalanced_timer_test |
| nexthop_res_group_short_unbalanced_timer_test |
| nexthop_res_group_increase_unbalanced_timer_test |
| nexthop_res_group_decrease_unbalanced_timer_test |
| nexthop_res_group_force_migrate_busy_test |
| nexthop_single_replace_test |
| nexthop_single_replace_err_test |
| nexthop_single_in_group_replace_test |
| nexthop_single_in_group_replace_err_test |
| nexthop_single_in_res_group_replace_test |
| nexthop_single_in_res_group_replace_err_test |
| nexthop_single_in_group_delete_test |
| nexthop_single_in_group_delete_err_test |
| nexthop_single_in_res_group_delete_test |
| nexthop_single_in_res_group_delete_err_test |
| nexthop_replay_test |
| nexthop_replay_err_test |
| " |
| NETDEVSIM_PATH=/sys/bus/netdevsim/ |
| DEV_ADDR=1337 |
| DEV=netdevsim${DEV_ADDR} |
| SYSFS_NET_DIR=/sys/bus/netdevsim/devices/$DEV/net/ |
| DEBUGFS_NET_DIR=/sys/kernel/debug/netdevsim/$DEV/ |
| NUM_NETIFS=0 |
| source $lib_dir/lib.sh |
| |
| DEVLINK_DEV= |
| source $lib_dir/devlink_lib.sh |
| DEVLINK_DEV=netdevsim/${DEV} |
| |
| nexthop_check() |
| { |
| local nharg="$1"; shift |
| local expected="$1"; shift |
| |
| out=$($IP nexthop show ${nharg} | sed -e 's/ *$//') |
| if [[ "$out" != "$expected" ]]; then |
| return 1 |
| fi |
| |
| return 0 |
| } |
| |
| nexthop_bucket_nhid_count_check() |
| { |
| local group_id=$1; shift |
| local expected |
| local count |
| local nhid |
| local ret |
| |
| while (($# > 0)); do |
| nhid=$1; shift |
| expected=$1; shift |
| |
| count=$($IP nexthop bucket show id $group_id nhid $nhid | |
| grep "trap" | wc -l) |
| if ((expected != count)); then |
| return 1 |
| fi |
| done |
| |
| return 0 |
| } |
| |
| nexthop_resource_check() |
| { |
| local expected_occ=$1; shift |
| |
| occ=$($DEVLINK -jp resource show $DEVLINK_DEV \ |
| | jq '.[][][] | select(.name=="nexthops") | .["occ"]') |
| |
| if [ $expected_occ -ne $occ ]; then |
| return 1 |
| fi |
| |
| return 0 |
| } |
| |
| nexthop_resource_set() |
| { |
| local size=$1; shift |
| |
| $DEVLINK resource set $DEVLINK_DEV path nexthops size $size |
| $DEVLINK dev reload $DEVLINK_DEV |
| } |
| |
| nexthop_single_add_test() |
| { |
| RET=0 |
| |
| $IP nexthop add id 1 via 192.0.2.2 dev dummy1 |
| nexthop_check "id 1" "id 1 via 192.0.2.2 dev dummy1 scope link trap" |
| check_err $? "Unexpected nexthop entry" |
| |
| nexthop_resource_check 1 |
| check_err $? "Wrong nexthop occupancy" |
| |
| $IP nexthop del id 1 |
| nexthop_resource_check 0 |
| check_err $? "Wrong nexthop occupancy after delete" |
| |
| log_test "Single nexthop add and delete" |
| } |
| |
| nexthop_single_add_err_test() |
| { |
| RET=0 |
| |
| nexthop_resource_set 1 |
| |
| $IP nexthop add id 1 via 192.0.2.2 dev dummy1 |
| |
| $IP nexthop add id 2 via 192.0.2.3 dev dummy1 &> /dev/null |
| check_fail $? "Nexthop addition succeeded when should fail" |
| |
| nexthop_resource_check 1 |
| check_err $? "Wrong nexthop occupancy" |
| |
| log_test "Single nexthop add failure" |
| |
| $IP nexthop flush &> /dev/null |
| nexthop_resource_set 9999 |
| } |
| |
| nexthop_group_add_test() |
| { |
| RET=0 |
| |
| $IP nexthop add id 1 via 192.0.2.2 dev dummy1 |
| $IP nexthop add id 2 via 192.0.2.3 dev dummy1 |
| |
| $IP nexthop add id 10 group 1/2 |
| nexthop_check "id 10" "id 10 group 1/2 trap" |
| check_err $? "Unexpected nexthop group entry" |
| |
| nexthop_resource_check 4 |
| check_err $? "Wrong nexthop occupancy" |
| |
| $IP nexthop del id 10 |
| nexthop_resource_check 2 |
| check_err $? "Wrong nexthop occupancy after delete" |
| |
| $IP nexthop add id 10 group 1,20/2,39 |
| nexthop_check "id 10" "id 10 group 1,20/2,39 trap" |
| check_err $? "Unexpected weighted nexthop group entry" |
| |
| nexthop_resource_check 61 |
| check_err $? "Wrong weighted nexthop occupancy" |
| |
| $IP nexthop del id 10 |
| nexthop_resource_check 2 |
| check_err $? "Wrong nexthop occupancy after delete" |
| |
| log_test "Nexthop group add and delete" |
| |
| $IP nexthop flush &> /dev/null |
| } |
| |
| nexthop_group_add_err_test() |
| { |
| RET=0 |
| |
| nexthop_resource_set 2 |
| |
| $IP nexthop add id 1 via 192.0.2.2 dev dummy1 |
| $IP nexthop add id 2 via 192.0.2.3 dev dummy1 |
| |
| $IP nexthop add id 10 group 1/2 &> /dev/null |
| check_fail $? "Nexthop group addition succeeded when should fail" |
| |
| nexthop_resource_check 2 |
| check_err $? "Wrong nexthop occupancy" |
| |
| log_test "Nexthop group add failure" |
| |
| $IP nexthop flush &> /dev/null |
| nexthop_resource_set 9999 |
| } |
| |
| nexthop_res_group_add_test() |
| { |
| RET=0 |
| |
| $IP nexthop add id 1 via 192.0.2.2 dev dummy1 |
| $IP nexthop add id 2 via 192.0.2.3 dev dummy1 |
| |
| $IP nexthop add id 10 group 1/2 type resilient buckets 4 |
| nexthop_check "id 10" "id 10 group 1/2 type resilient buckets 4 idle_timer 120 unbalanced_timer 0 unbalanced_time 0 trap" |
| check_err $? "Unexpected nexthop group entry" |
| |
| nexthop_bucket_nhid_count_check 10 1 2 |
| check_err $? "Wrong nexthop buckets count" |
| nexthop_bucket_nhid_count_check 10 2 2 |
| check_err $? "Wrong nexthop buckets count" |
| |
| nexthop_resource_check 6 |
| check_err $? "Wrong nexthop occupancy" |
| |
| $IP nexthop del id 10 |
| nexthop_resource_check 2 |
| check_err $? "Wrong nexthop occupancy after delete" |
| |
| $IP nexthop add id 10 group 1,3/2,2 type resilient buckets 5 |
| nexthop_check "id 10" "id 10 group 1,3/2,2 type resilient buckets 5 idle_timer 120 unbalanced_timer 0 unbalanced_time 0 trap" |
| check_err $? "Unexpected weighted nexthop group entry" |
| |
| nexthop_bucket_nhid_count_check 10 1 3 |
| check_err $? "Wrong nexthop buckets count" |
| nexthop_bucket_nhid_count_check 10 2 2 |
| check_err $? "Wrong nexthop buckets count" |
| |
| nexthop_resource_check 7 |
| check_err $? "Wrong weighted nexthop occupancy" |
| |
| $IP nexthop del id 10 |
| nexthop_resource_check 2 |
| check_err $? "Wrong nexthop occupancy after delete" |
| |
| log_test "Resilient nexthop group add and delete" |
| |
| $IP nexthop flush &> /dev/null |
| } |
| |
| nexthop_res_group_add_err_test() |
| { |
| RET=0 |
| |
| nexthop_resource_set 2 |
| |
| $IP nexthop add id 1 via 192.0.2.2 dev dummy1 |
| $IP nexthop add id 2 via 192.0.2.3 dev dummy1 |
| |
| $IP nexthop add id 10 group 1/2 type resilient buckets 4 &> /dev/null |
| check_fail $? "Nexthop group addition succeeded when should fail" |
| |
| nexthop_resource_check 2 |
| check_err $? "Wrong nexthop occupancy" |
| |
| log_test "Resilient nexthop group add failure" |
| |
| $IP nexthop flush &> /dev/null |
| nexthop_resource_set 9999 |
| } |
| |
| nexthop_group_replace_test() |
| { |
| RET=0 |
| |
| $IP nexthop add id 1 via 192.0.2.2 dev dummy1 |
| $IP nexthop add id 2 via 192.0.2.3 dev dummy1 |
| $IP nexthop add id 3 via 192.0.2.4 dev dummy1 |
| $IP nexthop add id 10 group 1/2 |
| |
| $IP nexthop replace id 10 group 1/2/3 |
| nexthop_check "id 10" "id 10 group 1/2/3 trap" |
| check_err $? "Unexpected nexthop group entry" |
| |
| nexthop_resource_check 6 |
| check_err $? "Wrong nexthop occupancy" |
| |
| log_test "Nexthop group replace" |
| |
| $IP nexthop flush &> /dev/null |
| } |
| |
| nexthop_group_replace_err_test() |
| { |
| RET=0 |
| |
| nexthop_resource_set 5 |
| |
| $IP nexthop add id 1 via 192.0.2.2 dev dummy1 |
| $IP nexthop add id 2 via 192.0.2.3 dev dummy1 |
| $IP nexthop add id 3 via 192.0.2.4 dev dummy1 |
| $IP nexthop add id 10 group 1/2 |
| |
| $IP nexthop replace id 10 group 1/2/3 &> /dev/null |
| check_fail $? "Nexthop group replacement succeeded when should fail" |
| |
| nexthop_check "id 10" "id 10 group 1/2 trap" |
| check_err $? "Unexpected nexthop group entry after failure" |
| |
| nexthop_resource_check 5 |
| check_err $? "Wrong nexthop occupancy after failure" |
| |
| log_test "Nexthop group replace failure" |
| |
| $IP nexthop flush &> /dev/null |
| nexthop_resource_set 9999 |
| } |
| |
| nexthop_res_group_replace_test() |
| { |
| RET=0 |
| |
| $IP nexthop add id 1 via 192.0.2.2 dev dummy1 |
| $IP nexthop add id 2 via 192.0.2.3 dev dummy1 |
| $IP nexthop add id 3 via 192.0.2.4 dev dummy1 |
| $IP nexthop add id 10 group 1/2 type resilient buckets 6 |
| |
| $IP nexthop replace id 10 group 1/2/3 type resilient |
| nexthop_check "id 10" "id 10 group 1/2/3 type resilient buckets 6 idle_timer 120 unbalanced_timer 0 unbalanced_time 0 trap" |
| check_err $? "Unexpected nexthop group entry" |
| |
| nexthop_bucket_nhid_count_check 10 1 2 |
| check_err $? "Wrong nexthop buckets count" |
| nexthop_bucket_nhid_count_check 10 2 2 |
| check_err $? "Wrong nexthop buckets count" |
| nexthop_bucket_nhid_count_check 10 3 2 |
| check_err $? "Wrong nexthop buckets count" |
| |
| nexthop_resource_check 9 |
| check_err $? "Wrong nexthop occupancy" |
| |
| log_test "Resilient nexthop group replace" |
| |
| $IP nexthop flush &> /dev/null |
| } |
| |
| nexthop_res_group_replace_err_test() |
| { |
| RET=0 |
| |
| $IP nexthop add id 1 via 192.0.2.2 dev dummy1 |
| $IP nexthop add id 2 via 192.0.2.3 dev dummy1 |
| $IP nexthop add id 3 via 192.0.2.4 dev dummy1 |
| $IP nexthop add id 10 group 1/2 type resilient buckets 6 |
| |
| ip netns exec testns1 \ |
| echo 1 > $DEBUGFS_NET_DIR/fib/fail_res_nexthop_group_replace |
| $IP nexthop replace id 10 group 1/2/3 type resilient &> /dev/null |
| check_fail $? "Nexthop group replacement succeeded when should fail" |
| |
| nexthop_check "id 10" "id 10 group 1/2 type resilient buckets 6 idle_timer 120 unbalanced_timer 0 unbalanced_time 0 trap" |
| check_err $? "Unexpected nexthop group entry after failure" |
| |
| nexthop_bucket_nhid_count_check 10 1 3 |
| check_err $? "Wrong nexthop buckets count" |
| nexthop_bucket_nhid_count_check 10 2 3 |
| check_err $? "Wrong nexthop buckets count" |
| |
| nexthop_resource_check 9 |
| check_err $? "Wrong nexthop occupancy after failure" |
| |
| log_test "Resilient nexthop group replace failure" |
| |
| $IP nexthop flush &> /dev/null |
| ip netns exec testns1 \ |
| echo 0 > $DEBUGFS_NET_DIR/fib/fail_res_nexthop_group_replace |
| } |
| |
| nexthop_res_mark_buckets_busy() |
| { |
| local group_id=$1; shift |
| local nhid=$1; shift |
| local count=$1; shift |
| local index |
| |
| for index in $($IP -j nexthop bucket show id $group_id nhid $nhid | |
| jq '.[].bucket.index' | head -n ${count:--0}) |
| do |
| echo $group_id $index \ |
| > $DEBUGFS_NET_DIR/fib/nexthop_bucket_activity |
| done |
| } |
| |
| nexthop_res_num_nhid_buckets() |
| { |
| local group_id=$1; shift |
| local nhid=$1; shift |
| |
| $IP -j nexthop bucket show id $group_id nhid $nhid | jq length |
| } |
| |
| nexthop_res_group_idle_timer_test() |
| { |
| $IP nexthop add id 1 via 192.0.2.2 dev dummy1 |
| $IP nexthop add id 2 via 192.0.2.3 dev dummy1 |
| |
| RET=0 |
| |
| $IP nexthop add id 10 group 1/2 type resilient buckets 8 idle_timer 4 |
| nexthop_res_mark_buckets_busy 10 1 |
| $IP nexthop replace id 10 group 1/2,3 type resilient |
| |
| nexthop_bucket_nhid_count_check 10 1 4 2 4 |
| check_err $? "Group expected to be unbalanced" |
| |
| sleep 6 |
| |
| nexthop_bucket_nhid_count_check 10 1 2 2 6 |
| check_err $? "Group expected to be balanced" |
| |
| log_test "Bucket migration after idle timer" |
| |
| $IP nexthop flush &> /dev/null |
| } |
| |
| nexthop_res_group_idle_timer_del_test() |
| { |
| $IP nexthop add id 1 via 192.0.2.2 dev dummy1 |
| $IP nexthop add id 2 via 192.0.2.3 dev dummy1 |
| $IP nexthop add id 3 via 192.0.2.3 dev dummy1 |
| |
| RET=0 |
| |
| $IP nexthop add id 10 group 1,50/2,50/3,1 \ |
| type resilient buckets 8 idle_timer 6 |
| nexthop_res_mark_buckets_busy 10 1 |
| $IP nexthop replace id 10 group 1,50/2,150/3,1 type resilient |
| |
| nexthop_bucket_nhid_count_check 10 1 4 2 4 3 0 |
| check_err $? "Group expected to be unbalanced" |
| |
| sleep 4 |
| |
| # Deletion prompts group replacement. Check that the bucket timers |
| # are kept. |
| $IP nexthop delete id 3 |
| |
| nexthop_bucket_nhid_count_check 10 1 4 2 4 |
| check_err $? "Group expected to still be unbalanced" |
| |
| sleep 4 |
| |
| nexthop_bucket_nhid_count_check 10 1 2 2 6 |
| check_err $? "Group expected to be balanced" |
| |
| log_test "Bucket migration after idle timer (with delete)" |
| |
| $IP nexthop flush &> /dev/null |
| } |
| |
| __nexthop_res_group_increase_timer_test() |
| { |
| local timer=$1; shift |
| |
| $IP nexthop add id 1 via 192.0.2.2 dev dummy1 |
| $IP nexthop add id 2 via 192.0.2.3 dev dummy1 |
| |
| RET=0 |
| |
| $IP nexthop add id 10 group 1/2 type resilient buckets 8 $timer 4 |
| nexthop_res_mark_buckets_busy 10 1 |
| $IP nexthop replace id 10 group 1/2,3 type resilient |
| |
| nexthop_bucket_nhid_count_check 10 2 6 |
| check_fail $? "Group expected to be unbalanced" |
| |
| sleep 2 |
| $IP nexthop replace id 10 group 1/2,3 type resilient $timer 8 |
| sleep 4 |
| |
| # 6 seconds, past the original timer. |
| nexthop_bucket_nhid_count_check 10 2 6 |
| check_fail $? "Group still expected to be unbalanced" |
| |
| sleep 4 |
| |
| # 10 seconds, past the new timer. |
| nexthop_bucket_nhid_count_check 10 2 6 |
| check_err $? "Group expected to be balanced" |
| |
| log_test "Bucket migration after $timer increase" |
| |
| $IP nexthop flush &> /dev/null |
| } |
| |
| __nexthop_res_group_decrease_timer_test() |
| { |
| local timer=$1; shift |
| |
| $IP nexthop add id 1 via 192.0.2.2 dev dummy1 |
| $IP nexthop add id 2 via 192.0.2.3 dev dummy1 |
| |
| RET=0 |
| |
| $IP nexthop add id 10 group 1/2 type resilient buckets 8 $timer 8 |
| nexthop_res_mark_buckets_busy 10 1 |
| $IP nexthop replace id 10 group 1/2,3 type resilient |
| |
| nexthop_bucket_nhid_count_check 10 2 6 |
| check_fail $? "Group expected to be unbalanced" |
| |
| sleep 2 |
| $IP nexthop replace id 10 group 1/2,3 type resilient $timer 4 |
| sleep 4 |
| |
| # 6 seconds, past the new timer, before the old timer. |
| nexthop_bucket_nhid_count_check 10 2 6 |
| check_err $? "Group expected to be balanced" |
| |
| log_test "Bucket migration after $timer decrease" |
| |
| $IP nexthop flush &> /dev/null |
| } |
| |
| __nexthop_res_group_increase_timer_del_test() |
| { |
| local timer=$1; shift |
| |
| $IP nexthop add id 1 via 192.0.2.2 dev dummy1 |
| $IP nexthop add id 2 via 192.0.2.3 dev dummy1 |
| $IP nexthop add id 3 via 192.0.2.3 dev dummy1 |
| |
| RET=0 |
| |
| $IP nexthop add id 10 group 1,100/2,100/3,1 \ |
| type resilient buckets 8 $timer 4 |
| nexthop_res_mark_buckets_busy 10 1 |
| $IP nexthop replace id 10 group 1,100/2,300/3,1 type resilient |
| |
| nexthop_bucket_nhid_count_check 10 2 6 |
| check_fail $? "Group expected to be unbalanced" |
| |
| sleep 2 |
| $IP nexthop replace id 10 group 1/2,3 type resilient $timer 8 |
| sleep 4 |
| |
| # 6 seconds, past the original timer. |
| nexthop_bucket_nhid_count_check 10 2 6 |
| check_fail $? "Group still expected to be unbalanced" |
| |
| sleep 4 |
| |
| # 10 seconds, past the new timer. |
| nexthop_bucket_nhid_count_check 10 2 6 |
| check_err $? "Group expected to be balanced" |
| |
| log_test "Bucket migration after $timer increase" |
| |
| $IP nexthop flush &> /dev/null |
| } |
| |
| nexthop_res_group_increase_idle_timer_test() |
| { |
| __nexthop_res_group_increase_timer_test idle_timer |
| } |
| |
| nexthop_res_group_decrease_idle_timer_test() |
| { |
| __nexthop_res_group_decrease_timer_test idle_timer |
| } |
| |
| nexthop_res_group_unbalanced_timer_test() |
| { |
| local i |
| |
| $IP nexthop add id 1 via 192.0.2.2 dev dummy1 |
| $IP nexthop add id 2 via 192.0.2.3 dev dummy1 |
| |
| RET=0 |
| |
| $IP nexthop add id 10 group 1/2 type resilient \ |
| buckets 8 idle_timer 6 unbalanced_timer 10 |
| nexthop_res_mark_buckets_busy 10 1 |
| $IP nexthop replace id 10 group 1/2,3 type resilient |
| |
| for i in 1 2; do |
| sleep 4 |
| nexthop_bucket_nhid_count_check 10 1 4 2 4 |
| check_err $? "$i: Group expected to be unbalanced" |
| nexthop_res_mark_buckets_busy 10 1 |
| done |
| |
| # 3 x sleep 4 > unbalanced timer 10 |
| sleep 4 |
| nexthop_bucket_nhid_count_check 10 1 2 2 6 |
| check_err $? "Group expected to be balanced" |
| |
| log_test "Bucket migration after unbalanced timer" |
| |
| $IP nexthop flush &> /dev/null |
| } |
| |
| nexthop_res_group_unbalanced_timer_del_test() |
| { |
| local i |
| |
| $IP nexthop add id 1 via 192.0.2.2 dev dummy1 |
| $IP nexthop add id 2 via 192.0.2.3 dev dummy1 |
| $IP nexthop add id 3 via 192.0.2.3 dev dummy1 |
| |
| RET=0 |
| |
| $IP nexthop add id 10 group 1,50/2,50/3,1 type resilient \ |
| buckets 8 idle_timer 6 unbalanced_timer 10 |
| nexthop_res_mark_buckets_busy 10 1 |
| $IP nexthop replace id 10 group 1,50/2,150/3,1 type resilient |
| |
| # Check that NH delete does not reset unbalanced time. |
| sleep 4 |
| $IP nexthop delete id 3 |
| nexthop_bucket_nhid_count_check 10 1 4 2 4 |
| check_err $? "1: Group expected to be unbalanced" |
| nexthop_res_mark_buckets_busy 10 1 |
| |
| sleep 4 |
| nexthop_bucket_nhid_count_check 10 1 4 2 4 |
| check_err $? "2: Group expected to be unbalanced" |
| nexthop_res_mark_buckets_busy 10 1 |
| |
| # 3 x sleep 4 > unbalanced timer 10 |
| sleep 4 |
| nexthop_bucket_nhid_count_check 10 1 2 2 6 |
| check_err $? "Group expected to be balanced" |
| |
| log_test "Bucket migration after unbalanced timer (with delete)" |
| |
| $IP nexthop flush &> /dev/null |
| } |
| |
| nexthop_res_group_no_unbalanced_timer_test() |
| { |
| local i |
| |
| $IP nexthop add id 1 via 192.0.2.2 dev dummy1 |
| $IP nexthop add id 2 via 192.0.2.3 dev dummy1 |
| |
| RET=0 |
| |
| $IP nexthop add id 10 group 1/2 type resilient buckets 8 |
| nexthop_res_mark_buckets_busy 10 1 |
| $IP nexthop replace id 10 group 1/2,3 type resilient |
| |
| for i in $(seq 3); do |
| sleep 60 |
| nexthop_bucket_nhid_count_check 10 2 6 |
| check_fail $? "$i: Group expected to be unbalanced" |
| nexthop_res_mark_buckets_busy 10 1 |
| done |
| |
| log_test "Buckets never force-migrated without unbalanced timer" |
| |
| $IP nexthop flush &> /dev/null |
| } |
| |
| nexthop_res_group_short_unbalanced_timer_test() |
| { |
| $IP nexthop add id 1 via 192.0.2.2 dev dummy1 |
| $IP nexthop add id 2 via 192.0.2.3 dev dummy1 |
| |
| RET=0 |
| |
| $IP nexthop add id 10 group 1/2 type resilient \ |
| buckets 8 idle_timer 120 unbalanced_timer 4 |
| nexthop_res_mark_buckets_busy 10 1 |
| $IP nexthop replace id 10 group 1/2,3 type resilient |
| |
| nexthop_bucket_nhid_count_check 10 2 6 |
| check_fail $? "Group expected to be unbalanced" |
| |
| sleep 5 |
| |
| nexthop_bucket_nhid_count_check 10 2 6 |
| check_err $? "Group expected to be balanced" |
| |
| log_test "Bucket migration after unbalanced < idle timer" |
| |
| $IP nexthop flush &> /dev/null |
| } |
| |
| nexthop_res_group_increase_unbalanced_timer_test() |
| { |
| __nexthop_res_group_increase_timer_test unbalanced_timer |
| } |
| |
| nexthop_res_group_decrease_unbalanced_timer_test() |
| { |
| __nexthop_res_group_decrease_timer_test unbalanced_timer |
| } |
| |
| nexthop_res_group_force_migrate_busy_test() |
| { |
| $IP nexthop add id 1 via 192.0.2.2 dev dummy1 |
| $IP nexthop add id 2 via 192.0.2.3 dev dummy1 |
| |
| RET=0 |
| |
| $IP nexthop add id 10 group 1/2 type resilient \ |
| buckets 8 idle_timer 120 |
| nexthop_res_mark_buckets_busy 10 1 |
| $IP nexthop replace id 10 group 1/2,3 type resilient |
| |
| nexthop_bucket_nhid_count_check 10 2 6 |
| check_fail $? "Group expected to be unbalanced" |
| |
| $IP nexthop replace id 10 group 2 type resilient |
| nexthop_bucket_nhid_count_check 10 2 8 |
| check_err $? "All buckets expected to have migrated" |
| |
| log_test "Busy buckets force-migrated when NH removed" |
| |
| $IP nexthop flush &> /dev/null |
| } |
| |
| nexthop_single_replace_test() |
| { |
| RET=0 |
| |
| $IP nexthop add id 1 via 192.0.2.2 dev dummy1 |
| |
| $IP nexthop replace id 1 via 192.0.2.3 dev dummy1 |
| nexthop_check "id 1" "id 1 via 192.0.2.3 dev dummy1 scope link trap" |
| check_err $? "Unexpected nexthop entry" |
| |
| nexthop_resource_check 1 |
| check_err $? "Wrong nexthop occupancy" |
| |
| log_test "Single nexthop replace" |
| |
| $IP nexthop flush &> /dev/null |
| } |
| |
| nexthop_single_replace_err_test() |
| { |
| RET=0 |
| |
| # This is supposed to cause the replace to fail because the new nexthop |
| # is programmed before deleting the replaced one. |
| nexthop_resource_set 1 |
| |
| $IP nexthop add id 1 via 192.0.2.2 dev dummy1 |
| |
| $IP nexthop replace id 1 via 192.0.2.3 dev dummy1 &> /dev/null |
| check_fail $? "Nexthop replace succeeded when should fail" |
| |
| nexthop_check "id 1" "id 1 via 192.0.2.2 dev dummy1 scope link trap" |
| check_err $? "Unexpected nexthop entry after failure" |
| |
| nexthop_resource_check 1 |
| check_err $? "Wrong nexthop occupancy after failure" |
| |
| log_test "Single nexthop replace failure" |
| |
| $IP nexthop flush &> /dev/null |
| nexthop_resource_set 9999 |
| } |
| |
| nexthop_single_in_group_replace_test() |
| { |
| RET=0 |
| |
| $IP nexthop add id 1 via 192.0.2.2 dev dummy1 |
| $IP nexthop add id 2 via 192.0.2.3 dev dummy1 |
| $IP nexthop add id 10 group 1/2 |
| |
| $IP nexthop replace id 1 via 192.0.2.4 dev dummy1 |
| check_err $? "Failed to replace nexthop when should not" |
| |
| nexthop_check "id 10" "id 10 group 1/2 trap" |
| check_err $? "Unexpected nexthop group entry" |
| |
| nexthop_resource_check 4 |
| check_err $? "Wrong nexthop occupancy" |
| |
| log_test "Single nexthop replace while in group" |
| |
| $IP nexthop flush &> /dev/null |
| } |
| |
| nexthop_single_in_group_replace_err_test() |
| { |
| RET=0 |
| |
| nexthop_resource_set 5 |
| |
| $IP nexthop add id 1 via 192.0.2.2 dev dummy1 |
| $IP nexthop add id 2 via 192.0.2.3 dev dummy1 |
| $IP nexthop add id 10 group 1/2 |
| |
| $IP nexthop replace id 1 via 192.0.2.4 dev dummy1 &> /dev/null |
| check_fail $? "Nexthop replacement succeeded when should fail" |
| |
| nexthop_check "id 1" "id 1 via 192.0.2.2 dev dummy1 scope link trap" |
| check_err $? "Unexpected nexthop entry after failure" |
| |
| nexthop_check "id 10" "id 10 group 1/2 trap" |
| check_err $? "Unexpected nexthop group entry after failure" |
| |
| nexthop_resource_check 4 |
| check_err $? "Wrong nexthop occupancy" |
| |
| log_test "Single nexthop replace while in group failure" |
| |
| $IP nexthop flush &> /dev/null |
| nexthop_resource_set 9999 |
| } |
| |
| nexthop_single_in_res_group_replace_test() |
| { |
| RET=0 |
| |
| $IP nexthop add id 1 via 192.0.2.2 dev dummy1 |
| $IP nexthop add id 2 via 192.0.2.3 dev dummy1 |
| $IP nexthop add id 10 group 1/2 type resilient buckets 4 |
| |
| $IP nexthop replace id 1 via 192.0.2.4 dev dummy1 |
| check_err $? "Failed to replace nexthop when should not" |
| |
| nexthop_check "id 10" "id 10 group 1/2 type resilient buckets 4 idle_timer 120 unbalanced_timer 0 unbalanced_time 0 trap" |
| check_err $? "Unexpected nexthop group entry" |
| |
| nexthop_bucket_nhid_count_check 10 1 2 2 2 |
| check_err $? "Wrong nexthop buckets count" |
| |
| nexthop_resource_check 6 |
| check_err $? "Wrong nexthop occupancy" |
| |
| log_test "Single nexthop replace while in resilient group" |
| |
| $IP nexthop flush &> /dev/null |
| } |
| |
| nexthop_single_in_res_group_replace_err_test() |
| { |
| RET=0 |
| |
| $IP nexthop add id 1 via 192.0.2.2 dev dummy1 |
| $IP nexthop add id 2 via 192.0.2.3 dev dummy1 |
| $IP nexthop add id 10 group 1/2 type resilient buckets 4 |
| |
| ip netns exec testns1 \ |
| echo 1 > $DEBUGFS_NET_DIR/fib/fail_nexthop_bucket_replace |
| $IP nexthop replace id 1 via 192.0.2.4 dev dummy1 &> /dev/null |
| check_fail $? "Nexthop replacement succeeded when should fail" |
| |
| nexthop_check "id 1" "id 1 via 192.0.2.2 dev dummy1 scope link trap" |
| check_err $? "Unexpected nexthop entry after failure" |
| |
| nexthop_check "id 10" "id 10 group 1/2 type resilient buckets 4 idle_timer 120 unbalanced_timer 0 unbalanced_time 0 trap" |
| check_err $? "Unexpected nexthop group entry after failure" |
| |
| nexthop_bucket_nhid_count_check 10 1 2 2 2 |
| check_err $? "Wrong nexthop buckets count" |
| |
| nexthop_resource_check 6 |
| check_err $? "Wrong nexthop occupancy" |
| |
| log_test "Single nexthop replace while in resilient group failure" |
| |
| $IP nexthop flush &> /dev/null |
| ip netns exec testns1 \ |
| echo 0 > $DEBUGFS_NET_DIR/fib/fail_nexthop_bucket_replace |
| } |
| |
| nexthop_single_in_group_delete_test() |
| { |
| RET=0 |
| |
| $IP nexthop add id 1 via 192.0.2.2 dev dummy1 |
| $IP nexthop add id 2 via 192.0.2.3 dev dummy1 |
| $IP nexthop add id 10 group 1/2 |
| |
| $IP nexthop del id 1 |
| nexthop_check "id 10" "id 10 group 2 trap" |
| check_err $? "Unexpected nexthop group entry" |
| |
| nexthop_resource_check 2 |
| check_err $? "Wrong nexthop occupancy" |
| |
| log_test "Single nexthop delete while in group" |
| |
| $IP nexthop flush &> /dev/null |
| } |
| |
| nexthop_single_in_group_delete_err_test() |
| { |
| RET=0 |
| |
| # First, nexthop 1 will be deleted, which will reduce the occupancy to |
| # 5. Afterwards, a replace notification will be sent for nexthop group |
| # 10 with only two nexthops. Since the new group is allocated before |
| # the old is deleted, the replacement will fail as it will result in an |
| # occupancy of 7. |
| nexthop_resource_set 6 |
| |
| $IP nexthop add id 1 via 192.0.2.2 dev dummy1 |
| $IP nexthop add id 2 via 192.0.2.3 dev dummy1 |
| $IP nexthop add id 3 via 192.0.2.4 dev dummy1 |
| $IP nexthop add id 10 group 1/2/3 |
| |
| $IP nexthop del id 1 |
| |
| nexthop_resource_check 5 |
| check_err $? "Wrong nexthop occupancy" |
| |
| log_test "Single nexthop delete while in group failure" |
| |
| $IP nexthop flush &> /dev/null |
| nexthop_resource_set 9999 |
| } |
| |
| nexthop_single_in_res_group_delete_test() |
| { |
| RET=0 |
| |
| $IP nexthop add id 1 via 192.0.2.2 dev dummy1 |
| $IP nexthop add id 2 via 192.0.2.3 dev dummy1 |
| $IP nexthop add id 10 group 1/2 type resilient buckets 4 |
| |
| $IP nexthop del id 1 |
| nexthop_check "id 10" "id 10 group 2 type resilient buckets 4 idle_timer 120 unbalanced_timer 0 unbalanced_time 0 trap" |
| check_err $? "Unexpected nexthop group entry" |
| |
| nexthop_bucket_nhid_count_check 10 2 4 |
| check_err $? "Wrong nexthop buckets count" |
| |
| nexthop_resource_check 5 |
| check_err $? "Wrong nexthop occupancy" |
| |
| log_test "Single nexthop delete while in resilient group" |
| |
| $IP nexthop flush &> /dev/null |
| } |
| |
| nexthop_single_in_res_group_delete_err_test() |
| { |
| RET=0 |
| |
| $IP nexthop add id 1 via 192.0.2.2 dev dummy1 |
| $IP nexthop add id 2 via 192.0.2.3 dev dummy1 |
| $IP nexthop add id 3 via 192.0.2.4 dev dummy1 |
| $IP nexthop add id 10 group 1/2/3 type resilient buckets 6 |
| |
| ip netns exec testns1 \ |
| echo 1 > $DEBUGFS_NET_DIR/fib/fail_nexthop_bucket_replace |
| $IP nexthop del id 1 |
| |
| # We failed to replace the two nexthop buckets that were originally |
| # assigned to nhid 1. |
| nexthop_bucket_nhid_count_check 10 2 2 3 2 |
| check_err $? "Wrong nexthop buckets count" |
| |
| nexthop_resource_check 8 |
| check_err $? "Wrong nexthop occupancy" |
| |
| log_test "Single nexthop delete while in resilient group failure" |
| |
| $IP nexthop flush &> /dev/null |
| ip netns exec testns1 \ |
| echo 0 > $DEBUGFS_NET_DIR/fib/fail_nexthop_bucket_replace |
| } |
| |
| nexthop_replay_test() |
| { |
| RET=0 |
| |
| $IP nexthop add id 1 via 192.0.2.2 dev dummy1 |
| $IP nexthop add id 2 via 192.0.2.3 dev dummy1 |
| $IP nexthop add id 10 group 1/2 |
| |
| $DEVLINK dev reload $DEVLINK_DEV |
| check_err $? "Failed to reload when should not" |
| |
| nexthop_check "id 1" "id 1 via 192.0.2.2 dev dummy1 scope link trap" |
| check_err $? "Unexpected nexthop entry after reload" |
| |
| nexthop_check "id 2" "id 2 via 192.0.2.3 dev dummy1 scope link trap" |
| check_err $? "Unexpected nexthop entry after reload" |
| |
| nexthop_check "id 10" "id 10 group 1/2 trap" |
| check_err $? "Unexpected nexthop group entry after reload" |
| |
| nexthop_resource_check 4 |
| check_err $? "Wrong nexthop occupancy" |
| |
| log_test "Nexthop replay" |
| |
| $IP nexthop flush &> /dev/null |
| } |
| |
| nexthop_replay_err_test() |
| { |
| RET=0 |
| |
| $IP nexthop add id 1 via 192.0.2.2 dev dummy1 |
| $IP nexthop add id 2 via 192.0.2.3 dev dummy1 |
| $IP nexthop add id 10 group 1/2 |
| |
| # Reduce size of nexthop resource so that reload will fail. |
| $DEVLINK resource set $DEVLINK_DEV path nexthops size 3 |
| $DEVLINK dev reload $DEVLINK_DEV &> /dev/null |
| check_fail $? "Reload succeeded when should fail" |
| |
| $DEVLINK resource set $DEVLINK_DEV path nexthops size 9999 |
| $DEVLINK dev reload $DEVLINK_DEV |
| check_err $? "Failed to reload when should not" |
| |
| log_test "Nexthop replay failure" |
| |
| $IP nexthop flush &> /dev/null |
| } |
| |
| setup_prepare() |
| { |
| local netdev |
| |
| modprobe netdevsim &> /dev/null |
| |
| echo "$DEV_ADDR 1" > ${NETDEVSIM_PATH}/new_device |
| while [ ! -d $SYSFS_NET_DIR ] ; do :; done |
| |
| set -e |
| |
| ip netns add testns1 |
| devlink dev reload $DEVLINK_DEV netns testns1 |
| |
| IP="ip -netns testns1" |
| DEVLINK="devlink -N testns1" |
| |
| $IP link add name dummy1 up type dummy |
| $IP address add 192.0.2.1/24 dev dummy1 |
| |
| set +e |
| } |
| |
| cleanup() |
| { |
| pre_cleanup |
| ip netns del testns1 |
| echo "$DEV_ADDR" > ${NETDEVSIM_PATH}/del_device |
| modprobe -r netdevsim &> /dev/null |
| } |
| |
| trap cleanup EXIT |
| |
| setup_prepare |
| |
| tests_run |
| |
| exit $EXIT_STATUS |