| #!/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 |