diff options
Diffstat (limited to 'tools/testing/selftests/drivers/net/netdevsim')
9 files changed, 1387 insertions, 0 deletions
diff --git a/tools/testing/selftests/drivers/net/netdevsim/devlink.sh b/tools/testing/selftests/drivers/net/netdevsim/devlink.sh index de4b32fc4223..40909c254365 100755 --- a/tools/testing/selftests/drivers/net/netdevsim/devlink.sh +++ b/tools/testing/selftests/drivers/net/netdevsim/devlink.sh @@ -23,6 +23,27 @@ fw_flash_test() devlink dev flash $DL_HANDLE file dummy check_err $? "Failed to flash with status updates on" + devlink dev flash $DL_HANDLE file dummy component fw.mgmt + check_err $? "Failed to flash with component attribute" + + devlink dev flash $DL_HANDLE file dummy overwrite settings + check_fail $? "Flash with overwrite settings should be rejected" + + echo "1"> $DEBUGFS_DIR/fw_update_overwrite_mask + check_err $? "Failed to change allowed overwrite mask" + + devlink dev flash $DL_HANDLE file dummy overwrite settings + check_err $? "Failed to flash with settings overwrite enabled" + + devlink dev flash $DL_HANDLE file dummy overwrite identifiers + check_fail $? "Flash with overwrite settings should be identifiers" + + echo "3"> $DEBUGFS_DIR/fw_update_overwrite_mask + check_err $? "Failed to change allowed overwrite mask" + + devlink dev flash $DL_HANDLE file dummy overwrite identifiers overwrite settings + check_err $? "Failed to flash with settings and identifiers overwrite enabled" + echo "n"> $DEBUGFS_DIR/fw_update_status check_err $? "Failed to disable status updates" diff --git a/tools/testing/selftests/drivers/net/netdevsim/ethtool-coalesce.sh b/tools/testing/selftests/drivers/net/netdevsim/ethtool-coalesce.sh new file mode 100755 index 000000000000..9adfba8f87e6 --- /dev/null +++ b/tools/testing/selftests/drivers/net/netdevsim/ethtool-coalesce.sh @@ -0,0 +1,132 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0-only + +source ethtool-common.sh + +function get_value { + local query="${SETTINGS_MAP[$1]}" + + echo $(ethtool -c $NSIM_NETDEV | \ + awk -F':' -v pattern="$query:" '$0 ~ pattern {gsub(/[ \t]/, "", $2); print $2}') +} + +function update_current_settings { + for key in ${!SETTINGS_MAP[@]}; do + CURRENT_SETTINGS[$key]=$(get_value $key) + done + echo ${CURRENT_SETTINGS[@]} +} + +if ! ethtool -h | grep -q coalesce; then + echo "SKIP: No --coalesce support in ethtool" + exit 4 +fi + +NSIM_NETDEV=$(make_netdev) + +set -o pipefail + +declare -A SETTINGS_MAP=( + ["rx-frames-low"]="rx-frame-low" + ["tx-frames-low"]="tx-frame-low" + ["rx-frames-high"]="rx-frame-high" + ["tx-frames-high"]="tx-frame-high" + ["rx-usecs"]="rx-usecs" + ["rx-frames"]="rx-frames" + ["rx-usecs-irq"]="rx-usecs-irq" + ["rx-frames-irq"]="rx-frames-irq" + ["tx-usecs"]="tx-usecs" + ["tx-frames"]="tx-frames" + ["tx-usecs-irq"]="tx-usecs-irq" + ["tx-frames-irq"]="tx-frames-irq" + ["stats-block-usecs"]="stats-block-usecs" + ["pkt-rate-low"]="pkt-rate-low" + ["rx-usecs-low"]="rx-usecs-low" + ["tx-usecs-low"]="tx-usecs-low" + ["pkt-rate-high"]="pkt-rate-high" + ["rx-usecs-high"]="rx-usecs-high" + ["tx-usecs-high"]="tx-usecs-high" + ["sample-interval"]="sample-interval" +) + +declare -A CURRENT_SETTINGS=( + ["rx-frames-low"]="" + ["tx-frames-low"]="" + ["rx-frames-high"]="" + ["tx-frames-high"]="" + ["rx-usecs"]="" + ["rx-frames"]="" + ["rx-usecs-irq"]="" + ["rx-frames-irq"]="" + ["tx-usecs"]="" + ["tx-frames"]="" + ["tx-usecs-irq"]="" + ["tx-frames-irq"]="" + ["stats-block-usecs"]="" + ["pkt-rate-low"]="" + ["rx-usecs-low"]="" + ["tx-usecs-low"]="" + ["pkt-rate-high"]="" + ["rx-usecs-high"]="" + ["tx-usecs-high"]="" + ["sample-interval"]="" +) + +declare -A EXPECTED_SETTINGS=( + ["rx-frames-low"]="" + ["tx-frames-low"]="" + ["rx-frames-high"]="" + ["tx-frames-high"]="" + ["rx-usecs"]="" + ["rx-frames"]="" + ["rx-usecs-irq"]="" + ["rx-frames-irq"]="" + ["tx-usecs"]="" + ["tx-frames"]="" + ["tx-usecs-irq"]="" + ["tx-frames-irq"]="" + ["stats-block-usecs"]="" + ["pkt-rate-low"]="" + ["rx-usecs-low"]="" + ["tx-usecs-low"]="" + ["pkt-rate-high"]="" + ["rx-usecs-high"]="" + ["tx-usecs-high"]="" + ["sample-interval"]="" +) + +# populate the expected settings map +for key in ${!SETTINGS_MAP[@]}; do + EXPECTED_SETTINGS[$key]=$(get_value $key) +done + +# test +for key in ${!SETTINGS_MAP[@]}; do + value=$((RANDOM % $((2**32-1)))) + + ethtool -C $NSIM_NETDEV "$key" "$value" + + EXPECTED_SETTINGS[$key]="$value" + expected=${EXPECTED_SETTINGS[@]} + current=$(update_current_settings) + + check $? "$current" "$expected" + set +x +done + +# bool settings which ethtool displays on the same line +ethtool -C $NSIM_NETDEV adaptive-rx on +s=$(ethtool -c $NSIM_NETDEV | grep -q "Adaptive RX: on TX: off") +check $? "$s" "" + +ethtool -C $NSIM_NETDEV adaptive-tx on +s=$(ethtool -c $NSIM_NETDEV | grep -q "Adaptive RX: on TX: on") +check $? "$s" "" + +if [ $num_errors -eq 0 ]; then + echo "PASSED all $((num_passes)) checks" + exit 0 +else + echo "FAILED $num_errors/$((num_errors+num_passes)) checks" + exit 1 +fi diff --git a/tools/testing/selftests/drivers/net/netdevsim/ethtool-common.sh b/tools/testing/selftests/drivers/net/netdevsim/ethtool-common.sh new file mode 100644 index 000000000000..9f64d5c7107b --- /dev/null +++ b/tools/testing/selftests/drivers/net/netdevsim/ethtool-common.sh @@ -0,0 +1,53 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0-only + +NSIM_ID=$((RANDOM % 1024)) +NSIM_DEV_SYS=/sys/bus/netdevsim/devices/netdevsim$NSIM_ID +NSIM_DEV_DFS=/sys/kernel/debug/netdevsim/netdevsim$NSIM_ID/ports/0 +NSIM_NETDEV= +num_passes=0 +num_errors=0 + +function cleanup_nsim { + if [ -e $NSIM_DEV_SYS ]; then + echo $NSIM_ID > /sys/bus/netdevsim/del_device + fi +} + +function cleanup { + cleanup_nsim +} + +trap cleanup EXIT + +function check { + local code=$1 + local str=$2 + local exp_str=$3 + + if [ $code -ne 0 ]; then + ((num_errors++)) + return + fi + + if [ "$str" != "$exp_str" ]; then + echo -e "Expected: '$exp_str', got '$str'" + ((num_errors++)) + return + fi + + ((num_passes++)) +} + +function make_netdev { + # Make a netdevsim + old_netdevs=$(ls /sys/class/net) + + if ! $(lsmod | grep -q netdevsim); then + modprobe netdevsim + fi + + echo $NSIM_ID > /sys/bus/netdevsim/new_device + # get new device name + ls /sys/bus/netdevsim/devices/netdevsim${NSIM_ID}/net/ +} diff --git a/tools/testing/selftests/drivers/net/netdevsim/ethtool-pause.sh b/tools/testing/selftests/drivers/net/netdevsim/ethtool-pause.sh new file mode 100755 index 000000000000..b4a7abfe5454 --- /dev/null +++ b/tools/testing/selftests/drivers/net/netdevsim/ethtool-pause.sh @@ -0,0 +1,49 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0-only + +source ethtool-common.sh + +# Bail if ethtool is too old +if ! ethtool -h | grep include-stat 2>&1 >/dev/null; then + echo "SKIP: No --include-statistics support in ethtool" + exit 4 +fi + +NSIM_NETDEV=$(make_netdev) + +set -o pipefail + +echo n > $NSIM_DEV_DFS/ethtool/pause/report_stats_tx +echo n > $NSIM_DEV_DFS/ethtool/pause/report_stats_rx + +s=$(ethtool --json -a $NSIM_NETDEV | jq '.[].statistics') +check $? "$s" "null" + +s=$(ethtool -I --json -a $NSIM_NETDEV | jq '.[].statistics') +check $? "$s" "{}" + +echo y > $NSIM_DEV_DFS/ethtool/pause/report_stats_tx + +s=$(ethtool -I --json -a $NSIM_NETDEV | jq '.[].statistics | length') +check $? "$s" "1" + +s=$(ethtool -I --json -a $NSIM_NETDEV | jq '.[].statistics.tx_pause_frames') +check $? "$s" "2" + +echo y > $NSIM_DEV_DFS/ethtool/pause/report_stats_rx + +s=$(ethtool -I --json -a $NSIM_NETDEV | jq '.[].statistics | length') +check $? "$s" "2" + +s=$(ethtool -I --json -a $NSIM_NETDEV | jq '.[].statistics.rx_pause_frames') +check $? "$s" "1" +s=$(ethtool -I --json -a $NSIM_NETDEV | jq '.[].statistics.tx_pause_frames') +check $? "$s" "2" + +if [ $num_errors -eq 0 ]; then + echo "PASSED all $((num_passes)) checks" + exit 0 +else + echo "FAILED $num_errors/$((num_errors+num_passes)) checks" + exit 1 +fi diff --git a/tools/testing/selftests/drivers/net/netdevsim/ethtool-ring.sh b/tools/testing/selftests/drivers/net/netdevsim/ethtool-ring.sh new file mode 100755 index 000000000000..c969559ffa7a --- /dev/null +++ b/tools/testing/selftests/drivers/net/netdevsim/ethtool-ring.sh @@ -0,0 +1,85 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0-only + +source ethtool-common.sh + +function get_value { + local query="${SETTINGS_MAP[$1]}" + + echo $(ethtool -g $NSIM_NETDEV | \ + tail -n +$CURR_SETT_LINE | \ + awk -F':' -v pattern="$query:" '$0 ~ pattern {gsub(/[\t ]/, "", $2); print $2}') +} + +function update_current_settings { + for key in ${!SETTINGS_MAP[@]}; do + CURRENT_SETTINGS[$key]=$(get_value $key) + done + echo ${CURRENT_SETTINGS[@]} +} + +if ! ethtool -h | grep -q set-ring >/dev/null; then + echo "SKIP: No --set-ring support in ethtool" + exit 4 +fi + +NSIM_NETDEV=$(make_netdev) + +set -o pipefail + +declare -A SETTINGS_MAP=( + ["rx"]="RX" + ["rx-mini"]="RX Mini" + ["rx-jumbo"]="RX Jumbo" + ["tx"]="TX" +) + +declare -A EXPECTED_SETTINGS=( + ["rx"]="" + ["rx-mini"]="" + ["rx-jumbo"]="" + ["tx"]="" +) + +declare -A CURRENT_SETTINGS=( + ["rx"]="" + ["rx-mini"]="" + ["rx-jumbo"]="" + ["tx"]="" +) + +MAX_VALUE=$((RANDOM % $((2**32-1)))) +RING_MAX_LIST=$(ls $NSIM_DEV_DFS/ethtool/ring/) + +for ring_max_entry in $RING_MAX_LIST; do + echo $MAX_VALUE > $NSIM_DEV_DFS/ethtool/ring/$ring_max_entry +done + +CURR_SETT_LINE=$(ethtool -g $NSIM_NETDEV | grep -i -m1 -n 'Current hardware settings' | cut -f1 -d:) + +# populate the expected settings map +for key in ${!SETTINGS_MAP[@]}; do + EXPECTED_SETTINGS[$key]=$(get_value $key) +done + +# test +for key in ${!SETTINGS_MAP[@]}; do + value=$((RANDOM % $MAX_VALUE)) + + ethtool -G $NSIM_NETDEV "$key" "$value" + + EXPECTED_SETTINGS[$key]="$value" + expected=${EXPECTED_SETTINGS[@]} + current=$(update_current_settings) + + check $? "$current" "$expected" + set +x +done + +if [ $num_errors -eq 0 ]; then + echo "PASSED all $((num_passes)) checks" + exit 0 +else + echo "FAILED $num_errors/$((num_errors+num_passes)) checks" + exit 1 +fi diff --git a/tools/testing/selftests/drivers/net/netdevsim/fib.sh b/tools/testing/selftests/drivers/net/netdevsim/fib.sh index 2f87c3be76a9..251f228ce63e 100755 --- a/tools/testing/selftests/drivers/net/netdevsim/fib.sh +++ b/tools/testing/selftests/drivers/net/netdevsim/fib.sh @@ -302,6 +302,16 @@ ipv6_error_path() ipv6_error_path_replay } +fib_notify_on_flag_change_set() +{ + local notify=$1; shift + + ip netns exec testns1 sysctl -qw net.ipv4.fib_notify_on_flag_change=$notify + ip netns exec testns1 sysctl -qw net.ipv6.fib_notify_on_flag_change=$notify + + log_info "Set fib_notify_on_flag_change to $notify" +} + setup_prepare() { local netdev @@ -336,6 +346,10 @@ trap cleanup EXIT setup_prepare +fib_notify_on_flag_change_set 1 +tests_run + +fib_notify_on_flag_change_set 0 tests_run exit $EXIT_STATUS diff --git a/tools/testing/selftests/drivers/net/netdevsim/fib_notifications.sh b/tools/testing/selftests/drivers/net/netdevsim/fib_notifications.sh new file mode 100755 index 000000000000..8d91191a098c --- /dev/null +++ b/tools/testing/selftests/drivers/net/netdevsim/fib_notifications.sh @@ -0,0 +1,430 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 + +lib_dir=$(dirname $0)/../../../net/forwarding + +ALL_TESTS=" + ipv4_route_addition_test + ipv4_route_deletion_test + ipv4_route_replacement_test + ipv4_route_offload_failed_test + ipv6_route_addition_test + ipv6_route_deletion_test + ipv6_route_replacement_test + ipv6_route_offload_failed_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/ +DEBUGFS_DIR=/sys/kernel/debug/netdevsim/$DEV/ +NUM_NETIFS=0 +source $lib_dir/lib.sh + +check_rt_offload_failed() +{ + local outfile=$1; shift + local line + + # Make sure that the first notification was emitted without + # RTM_F_OFFLOAD_FAILED flag and the second with RTM_F_OFFLOAD_FAILED + # flag + head -n 1 $outfile | grep -q "rt_offload_failed" + if [[ $? -eq 0 ]]; then + return 1 + fi + + head -n 2 $outfile | tail -n 1 | grep -q "rt_offload_failed" +} + +check_rt_trap() +{ + local outfile=$1; shift + local line + + # Make sure that the first notification was emitted without RTM_F_TRAP + # flag and the second with RTM_F_TRAP flag + head -n 1 $outfile | grep -q "rt_trap" + if [[ $? -eq 0 ]]; then + return 1 + fi + + head -n 2 $outfile | tail -n 1 | grep -q "rt_trap" +} + +route_notify_check() +{ + local outfile=$1; shift + local expected_num_lines=$1; shift + local offload_failed=${1:-0}; shift + + # check the monitor results + lines=`wc -l $outfile | cut "-d " -f1` + test $lines -eq $expected_num_lines + check_err $? "$expected_num_lines notifications were expected but $lines were received" + + if [[ $expected_num_lines -eq 1 ]]; then + return + fi + + if [[ $offload_failed -eq 0 ]]; then + check_rt_trap $outfile + check_err $? "Wrong RTM_F_TRAP flags in notifications" + else + check_rt_offload_failed $outfile + check_err $? "Wrong RTM_F_OFFLOAD_FAILED flags in notifications" + fi +} + +route_addition_check() +{ + local ip=$1; shift + local notify=$1; shift + local route=$1; shift + local expected_num_notifications=$1; shift + local offload_failed=${1:-0}; shift + + ip netns exec testns1 sysctl -qw net.$ip.fib_notify_on_flag_change=$notify + + local outfile=$(mktemp) + + $IP monitor route &> $outfile & + sleep 1 + $IP route add $route dev dummy1 + sleep 1 + kill %% && wait %% &> /dev/null + + route_notify_check $outfile $expected_num_notifications $offload_failed + rm -f $outfile + + $IP route del $route dev dummy1 +} + +ipv4_route_addition_test() +{ + RET=0 + + local ip="ipv4" + local route=192.0.2.0/24 + + # Make sure a single notification will be emitted for the programmed + # route. + local notify=0 + local expected_num_notifications=1 + # route_addition_check will assign value to RET. + route_addition_check $ip $notify $route $expected_num_notifications + + # Make sure two notifications will be emitted for the programmed route. + notify=1 + expected_num_notifications=2 + route_addition_check $ip $notify $route $expected_num_notifications + + # notify=2 means emit notifications only for failed route installation, + # make sure a single notification will be emitted for the programmed + # route. + notify=2 + expected_num_notifications=1 + route_addition_check $ip $notify $route $expected_num_notifications + + log_test "IPv4 route addition" +} + +route_deletion_check() +{ + local ip=$1; shift + local notify=$1; shift + local route=$1; shift + local expected_num_notifications=$1; shift + + ip netns exec testns1 sysctl -qw net.$ip.fib_notify_on_flag_change=$notify + $IP route add $route dev dummy1 + sleep 1 + + local outfile=$(mktemp) + + $IP monitor route &> $outfile & + sleep 1 + $IP route del $route dev dummy1 + sleep 1 + kill %% && wait %% &> /dev/null + + route_notify_check $outfile $expected_num_notifications + rm -f $outfile +} + +ipv4_route_deletion_test() +{ + RET=0 + + local ip="ipv4" + local route=192.0.2.0/24 + local expected_num_notifications=1 + + # Make sure a single notification will be emitted for the deleted route, + # regardless of fib_notify_on_flag_change value. + local notify=0 + # route_deletion_check will assign value to RET. + route_deletion_check $ip $notify $route $expected_num_notifications + + notify=1 + route_deletion_check $ip $notify $route $expected_num_notifications + + log_test "IPv4 route deletion" +} + +route_replacement_check() +{ + local ip=$1; shift + local notify=$1; shift + local route=$1; shift + local expected_num_notifications=$1; shift + + ip netns exec testns1 sysctl -qw net.$ip.fib_notify_on_flag_change=$notify + $IP route add $route dev dummy1 + sleep 1 + + local outfile=$(mktemp) + + $IP monitor route &> $outfile & + sleep 1 + $IP route replace $route dev dummy2 + sleep 1 + kill %% && wait %% &> /dev/null + + route_notify_check $outfile $expected_num_notifications + rm -f $outfile + + $IP route del $route dev dummy2 +} + +ipv4_route_replacement_test() +{ + RET=0 + + local ip="ipv4" + local route=192.0.2.0/24 + + $IP link add name dummy2 type dummy + $IP link set dev dummy2 up + + # Make sure a single notification will be emitted for the new route. + local notify=0 + local expected_num_notifications=1 + # route_replacement_check will assign value to RET. + route_replacement_check $ip $notify $route $expected_num_notifications + + # Make sure two notifications will be emitted for the new route. + notify=1 + expected_num_notifications=2 + route_replacement_check $ip $notify $route $expected_num_notifications + + # notify=2 means emit notifications only for failed route installation, + # make sure a single notification will be emitted for the new route. + notify=2 + expected_num_notifications=1 + route_replacement_check $ip $notify $route $expected_num_notifications + + $IP link del name dummy2 + + log_test "IPv4 route replacement" +} + +ipv4_route_offload_failed_test() +{ + + RET=0 + + local ip="ipv4" + local route=192.0.2.0/24 + local offload_failed=1 + + echo "y"> $DEBUGFS_DIR/fib/fail_route_offload + check_err $? "Failed to setup route offload to fail" + + # Make sure a single notification will be emitted for the programmed + # route. + local notify=0 + local expected_num_notifications=1 + route_addition_check $ip $notify $route $expected_num_notifications \ + $offload_failed + + # Make sure two notifications will be emitted for the new route. + notify=1 + expected_num_notifications=2 + route_addition_check $ip $notify $route $expected_num_notifications \ + $offload_failed + + # notify=2 means emit notifications only for failed route installation, + # make sure two notifications will be emitted for the new route. + notify=2 + expected_num_notifications=2 + route_addition_check $ip $notify $route $expected_num_notifications \ + $offload_failed + + echo "n"> $DEBUGFS_DIR/fib/fail_route_offload + check_err $? "Failed to setup route offload not to fail" + + log_test "IPv4 route offload failed" +} + +ipv6_route_addition_test() +{ + RET=0 + + local ip="ipv6" + local route=2001:db8:1::/64 + + # Make sure a single notification will be emitted for the programmed + # route. + local notify=0 + local expected_num_notifications=1 + route_addition_check $ip $notify $route $expected_num_notifications + + # Make sure two notifications will be emitted for the programmed route. + notify=1 + expected_num_notifications=2 + route_addition_check $ip $notify $route $expected_num_notifications + + # notify=2 means emit notifications only for failed route installation, + # make sure a single notification will be emitted for the programmed + # route. + notify=2 + expected_num_notifications=1 + route_addition_check $ip $notify $route $expected_num_notifications + + log_test "IPv6 route addition" +} + +ipv6_route_deletion_test() +{ + RET=0 + + local ip="ipv6" + local route=2001:db8:1::/64 + local expected_num_notifications=1 + + # Make sure a single notification will be emitted for the deleted route, + # regardless of fib_notify_on_flag_change value. + local notify=0 + route_deletion_check $ip $notify $route $expected_num_notifications + + notify=1 + route_deletion_check $ip $notify $route $expected_num_notifications + + log_test "IPv6 route deletion" +} + +ipv6_route_replacement_test() +{ + RET=0 + + local ip="ipv6" + local route=2001:db8:1::/64 + + $IP link add name dummy2 type dummy + $IP link set dev dummy2 up + + # Make sure a single notification will be emitted for the new route. + local notify=0 + local expected_num_notifications=1 + route_replacement_check $ip $notify $route $expected_num_notifications + + # Make sure two notifications will be emitted for the new route. + notify=1 + expected_num_notifications=2 + route_replacement_check $ip $notify $route $expected_num_notifications + + # notify=2 means emit notifications only for failed route installation, + # make sure a single notification will be emitted for the new route. + notify=2 + expected_num_notifications=1 + route_replacement_check $ip $notify $route $expected_num_notifications + + $IP link del name dummy2 + + log_test "IPv6 route replacement" +} + +ipv6_route_offload_failed_test() +{ + + RET=0 + + local ip="ipv6" + local route=2001:db8:1::/64 + local offload_failed=1 + + echo "y"> $DEBUGFS_DIR/fib/fail_route_offload + check_err $? "Failed to setup route offload to fail" + + # Make sure a single notification will be emitted for the programmed + # route. + local notify=0 + local expected_num_notifications=1 + route_addition_check $ip $notify $route $expected_num_notifications \ + $offload_failed + + # Make sure two notifications will be emitted for the new route. + notify=1 + expected_num_notifications=2 + route_addition_check $ip $notify $route $expected_num_notifications \ + $offload_failed + + # notify=2 means emit notifications only for failed route installation, + # make sure two notifications will be emitted for the new route. + notify=2 + expected_num_notifications=2 + route_addition_check $ip $notify $route $expected_num_notifications \ + $offload_failed + + echo "n"> $DEBUGFS_DIR/fib/fail_route_offload + check_err $? "Failed to setup route offload not to fail" + + log_test "IPv6 route offload failed" +} + +setup_prepare() +{ + modprobe netdevsim &> /dev/null + echo "$DEV_ADDR 1" > ${NETDEVSIM_PATH}/new_device + while [ ! -d $SYSFS_NET_DIR ] ; do :; done + + ip netns add testns1 + + if [ $? -ne 0 ]; then + echo "Failed to add netns \"testns1\"" + exit 1 + fi + + devlink dev reload $DEVLINK_DEV netns testns1 + + if [ $? -ne 0 ]; then + echo "Failed to reload into netns \"testns1\"" + exit 1 + fi + + IP="ip -n testns1" + + $IP link add name dummy1 type dummy + $IP link set dev dummy1 up +} + +cleanup() +{ + pre_cleanup + + $IP link del name dummy1 + 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 diff --git a/tools/testing/selftests/drivers/net/netdevsim/nexthop.sh b/tools/testing/selftests/drivers/net/netdevsim/nexthop.sh new file mode 100755 index 000000000000..be0c1b5ee6b8 --- /dev/null +++ b/tools/testing/selftests/drivers/net/netdevsim/nexthop.sh @@ -0,0 +1,436 @@ +#!/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 diff --git a/tools/testing/selftests/drivers/net/netdevsim/udp_tunnel_nic.sh b/tools/testing/selftests/drivers/net/netdevsim/udp_tunnel_nic.sh index ba1d53b9f815..1b08e042cf94 100644..100755 --- a/tools/testing/selftests/drivers/net/netdevsim/udp_tunnel_nic.sh +++ b/tools/testing/selftests/drivers/net/netdevsim/udp_tunnel_nic.sh @@ -7,6 +7,7 @@ NSIM_DEV_SYS=/sys/bus/netdevsim/devices/netdevsim$NSIM_ID NSIM_DEV_DFS=/sys/kernel/debug/netdevsim/netdevsim$NSIM_ID NSIM_NETDEV= HAS_ETHTOOL= +STATIC_ENTRIES= EXIT_STATUS=0 num_cases=0 num_errors=0 @@ -193,6 +194,21 @@ function check_tables { sleep 0.02 ((retries--)) done + + if [ -n "$HAS_ETHTOOL" -a -n "${STATIC_ENTRIES[0]}" ]; then + fail=0 + for i in "${!STATIC_ENTRIES[@]}"; do + pp_expected=`pre_ethtool ${STATIC_ENTRIES[i]}` + cnt=$(ethtool --show-tunnels $NSIM_NETDEV | grep -c "$pp_expected") + if [ $cnt -ne 1 ]; then + err_cnt "ethtool static entry: $pfx - $msg" + echo " check_table: ethtool does not contain '$pp_expected'" + ethtool --show-tunnels $NSIM_NETDEV + fail=1 + fi + done + [ $fail == 0 ] && pass_cnt + fi } function print_table { @@ -775,6 +791,157 @@ for port in 0 1; do exp1=( 0 0 0 0 ) done +cleanup_nsim + +# shared port tables +pfx="table sharing" + +echo $NSIM_ID > /sys/bus/netdevsim/new_device +echo 0 > $NSIM_DEV_SYS/del_port + +echo 0 > $NSIM_DEV_DFS/udp_ports_open_only +echo 1 > $NSIM_DEV_DFS/udp_ports_sleep +echo 1 > $NSIM_DEV_DFS/udp_ports_shared + +old_netdevs=$(ls /sys/class/net) +echo 1 > $NSIM_DEV_SYS/new_port +NSIM_NETDEV=`get_netdev_name old_netdevs` +old_netdevs=$(ls /sys/class/net) +echo 2 > $NSIM_DEV_SYS/new_port +NSIM_NETDEV2=`get_netdev_name old_netdevs` + +msg="VxLAN v4 devices" +exp0=( `mke 4789 1` 0 0 0 ) +exp1=( 0 0 0 0 ) +new_vxlan vxlan0 4789 $NSIM_NETDEV +new_vxlan vxlan1 4789 $NSIM_NETDEV2 + +msg="VxLAN v4 devices go down" +exp0=( 0 0 0 0 ) +ifconfig vxlan1 down +ifconfig vxlan0 down +check_tables + +for ifc in vxlan0 vxlan1; do + ifconfig $ifc up +done + +msg="VxLAN v6 device" +exp0=( `mke 4789 1` `mke 4790 1` 0 0 ) +new_vxlan vxlanC 4790 $NSIM_NETDEV 6 + +msg="Geneve device" +exp1=( `mke 6081 2` 0 0 0 ) +new_geneve gnv0 6081 + +msg="NIC device goes down" +ifconfig $NSIM_NETDEV down +check_tables + +msg="NIC device goes up again" +ifconfig $NSIM_NETDEV up +check_tables + +for i in `seq 2`; do + msg="turn feature off - 1, rep $i" + ethtool -K $NSIM_NETDEV rx-udp_tunnel-port-offload off + check_tables + + msg="turn feature off - 2, rep $i" + exp0=( 0 0 0 0 ) + exp1=( 0 0 0 0 ) + ethtool -K $NSIM_NETDEV2 rx-udp_tunnel-port-offload off + check_tables + + msg="turn feature on - 1, rep $i" + exp0=( `mke 4789 1` `mke 4790 1` 0 0 ) + exp1=( `mke 6081 2` 0 0 0 ) + ethtool -K $NSIM_NETDEV rx-udp_tunnel-port-offload on + check_tables + + msg="turn feature on - 2, rep $i" + ethtool -K $NSIM_NETDEV2 rx-udp_tunnel-port-offload on + check_tables +done + +msg="tunnels destroyed 1" +cleanup_tuns +exp0=( 0 0 0 0 ) +exp1=( 0 0 0 0 ) +check_tables + +overflow_table0 "overflow NIC table" + +msg="re-add a port" + +echo 2 > $NSIM_DEV_SYS/del_port +echo 2 > $NSIM_DEV_SYS/new_port +check_tables + +msg="replace VxLAN in overflow table" +exp0=( `mke 10000 1` `mke 10004 1` `mke 10002 1` `mke 10003 1` ) +del_dev vxlan1 + +msg="vacate VxLAN in overflow table" +exp0=( `mke 10000 1` `mke 10004 1` 0 `mke 10003 1` ) +del_dev vxlan2 + +echo 1 > $NSIM_DEV_DFS/ports/$port/udp_ports_reset +check_tables + +msg="tunnels destroyed 2" +cleanup_tuns +exp0=( 0 0 0 0 ) +exp1=( 0 0 0 0 ) +check_tables + +echo 1 > $NSIM_DEV_SYS/del_port +echo 2 > $NSIM_DEV_SYS/del_port + +cleanup_nsim + +# Static IANA port +pfx="static IANA vxlan" + +echo $NSIM_ID > /sys/bus/netdevsim/new_device +echo 0 > $NSIM_DEV_SYS/del_port + +echo 1 > $NSIM_DEV_DFS/udp_ports_static_iana_vxlan +STATIC_ENTRIES=( `mke 4789 1` ) + +port=1 +old_netdevs=$(ls /sys/class/net) +echo $port > $NSIM_DEV_SYS/new_port +NSIM_NETDEV=`get_netdev_name old_netdevs` + +msg="check empty" +exp0=( 0 0 0 0 ) +exp1=( 0 0 0 0 ) +check_tables + +msg="add on static port" +new_vxlan vxlan0 4789 $NSIM_NETDEV +new_vxlan vxlan1 4789 $NSIM_NETDEV + +msg="add on different port" +exp0=( `mke 4790 1` 0 0 0 ) +new_vxlan vxlan2 4790 $NSIM_NETDEV + +cleanup_tuns + +msg="tunnels destroyed" +exp0=( 0 0 0 0 ) +exp1=( 0 0 0 0 ) +check_tables + +msg="different type" +new_geneve gnv0 4789 + +cleanup_tuns +cleanup_nsim + +# END + modprobe -r netdevsim if [ $num_errors -eq 0 ]; then |