| #!/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_group_replace_test |
| nexthop_group_replace_err_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_group_delete_test |
| nexthop_single_in_group_delete_err_test |
| nexthop_replay_test |
| nexthop_replay_err_test |
| " |
| NETDEVSIM_PATH=/sys/bus/netdevsim/ |
| DEV_ADDR=1337 |
| DEV=netdevsim${DEV_ADDR} |
| DEVLINK_DEV=netdevsim/${DEV} |
| SYSFS_NET_DIR=/sys/bus/netdevsim/devices/$DEV/net/ |
| NUM_NETIFS=0 |
| source $lib_dir/lib.sh |
| source $lib_dir/devlink_lib.sh |
| |
| 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_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_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_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_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_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 |