Resguardo inicial

This commit is contained in:
lastdragon
2026-09-06 12:53:21 -06:00
parent 662efe3c2a
commit ad2088d178
94853 changed files with 43200404 additions and 0 deletions
@@ -0,0 +1,25 @@
# SPDX-License-Identifier: GPL-2.0+ OR MIT
TEST_PROGS := \
devlink.sh \
devlink_in_netns.sh \
devlink_trap.sh \
ethtool-coalesce.sh \
ethtool-features.sh \
ethtool-fec.sh \
ethtool-pause.sh \
fib.sh \
fib_notifications.sh \
hw_stats_l3.sh \
nexthop.sh \
peer.sh \
psample.sh \
tc-mq-visibility.sh \
udp_tunnel_nic.sh \
# end of TEST_PROGS
TEST_FILES := \
ethtool-common.sh
# end of TEST_FILES
include ../../../lib.mk
@@ -0,0 +1,11 @@
CONFIG_DUMMY=y
CONFIG_GENEVE=m
CONFIG_IPV6=y
CONFIG_MACSEC=m
CONFIG_NETDEVSIM=m
CONFIG_NET_SCH_MQPRIO=y
CONFIG_NET_SCH_MULTIQ=y
CONFIG_NET_SCH_PRIO=y
CONFIG_PSAMPLE=y
CONFIG_PTP_1588_CLOCK_MOCK=y
CONFIG_VXLAN=m
@@ -0,0 +1,956 @@
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0
lib_dir=$(dirname $0)/../../../net/forwarding
ALL_TESTS="fw_flash_test params_test \
params_default_test regions_test reload_test \
netns_reload_test resource_test resource_dump_test \
port_resource_doit_test dev_info_test \
empty_reporter_test dummy_reporter_test rate_test"
NUM_NETIFS=0
source $lib_dir/lib.sh
BUS_ADDR=10
PORT_COUNT=4
VF_COUNT=4
DEV_NAME=netdevsim$BUS_ADDR
SYSFS_NET_DIR=/sys/bus/netdevsim/devices/$DEV_NAME/net/
DEBUGFS_DIR=/sys/kernel/debug/netdevsim/$DEV_NAME/
DL_HANDLE=netdevsim/$DEV_NAME
wait_for_devlink()
{
"$@" | grep -q $DL_HANDLE
}
devlink_wait()
{
local timeout=$1
busywait "$timeout" wait_for_devlink devlink dev
}
fw_flash_test()
{
DUMMYFILE=$(find /lib/firmware -type f -printf '%P\n' | head -1)
RET=0
if [ -z "$DUMMYFILE" ]
then
echo "SKIP: unable to find suitable dummy firmware file"
return
fi
echo "10"> $DEBUGFS_DIR/fw_update_flash_chunk_time_ms
devlink dev flash $DL_HANDLE file $DUMMYFILE
check_err $? "Failed to flash with status updates on"
devlink dev flash $DL_HANDLE file $DUMMYFILE component fw.mgmt
check_err $? "Failed to flash with component attribute"
devlink dev flash $DL_HANDLE file $DUMMYFILE 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 $DUMMYFILE overwrite settings
check_err $? "Failed to flash with settings overwrite enabled"
devlink dev flash $DL_HANDLE file $DUMMYFILE 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 $DUMMYFILE 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"
devlink dev flash $DL_HANDLE file $DUMMYFILE
check_err $? "Failed to flash with status updates off"
log_test "fw flash test"
}
param_get()
{
local name=$1
local attr=${2:-value}
local cmode=${3:-driverinit}
cmd_jq "devlink dev param show $DL_HANDLE name $name -j" \
'.[][][].values[] | select(.cmode == "'"$cmode"'").'"$attr"
}
param_set()
{
local name=$1
local value=$2
local cmode=${3:-driverinit}
devlink dev param set $DL_HANDLE name $name cmode $cmode value $value
}
param_set_default()
{
local name=$1
local cmode=${2:-driverinit}
devlink dev param set $DL_HANDLE name $name default cmode $cmode
}
check_value()
{
local name=$1
local phase_name=$2
local expected_param_value=$3
local expected_debugfs_value=$4
local cmode=${5:-driverinit}
local value
local attr="value"
if [[ "$phase_name" == *"default"* ]]; then
attr="default"
fi
value=$(param_get $name $attr $cmode)
check_err $? "Failed to get $name param $attr"
[ "$value" == "$expected_param_value" ]
check_err $? "Unexpected $phase_name $name param $attr"
value=$(<$DEBUGFS_DIR/$name)
check_err $? "Failed to get $name debugfs value"
[ "$value" == "$expected_debugfs_value" ]
check_err $? "Unexpected $phase_name $name debugfs value"
}
params_test()
{
RET=0
local max_macs
local test1
check_value max_macs initial 32 32
check_value test1 initial true Y
param_set max_macs 16
check_err $? "Failed to set max_macs param value"
param_set test1 false
check_err $? "Failed to set test1 param value"
check_value max_macs post-set 16 32
check_value test1 post-set false Y
devlink dev reload $DL_HANDLE
check_value max_macs post-reload 16 16
check_value test1 post-reload false N
log_test "params test"
}
value_to_debugfs()
{
local value=$1
case "$value" in
true)
echo "Y"
;;
false)
echo "N"
;;
*)
echo "$value"
;;
esac
}
test_default()
{
local param_name=$1
local new_value=$2
local expected_default=$3
local cmode=${4:-driverinit}
local default_debugfs
local new_debugfs
local expected_debugfs
default_debugfs=$(value_to_debugfs $expected_default)
new_debugfs=$(value_to_debugfs $new_value)
expected_debugfs=$default_debugfs
check_value $param_name initial-default $expected_default $expected_debugfs $cmode
param_set $param_name $new_value $cmode
check_err $? "Failed to set $param_name to $new_value"
expected_debugfs=$([ "$cmode" == "runtime" ] && echo "$new_debugfs" || echo "$default_debugfs")
check_value $param_name post-set $new_value $expected_debugfs $cmode
devlink dev reload $DL_HANDLE
check_err $? "Failed to reload device"
expected_debugfs=$new_debugfs
check_value $param_name post-reload-new-value $new_value $expected_debugfs $cmode
param_set_default $param_name $cmode
check_err $? "Failed to set $param_name to default"
expected_debugfs=$([ "$cmode" == "runtime" ] && echo "$default_debugfs" || echo "$new_debugfs")
check_value $param_name post-set-default $expected_default $expected_debugfs $cmode
devlink dev reload $DL_HANDLE
check_err $? "Failed to reload device"
expected_debugfs=$default_debugfs
check_value $param_name post-reload-default $expected_default $expected_debugfs $cmode
}
params_default_test()
{
RET=0
if ! devlink dev param help 2>&1 | grep -q "value VALUE | default"; then
echo "SKIP: devlink cli missing default feature"
return
fi
# Remove side effects of previous tests. Use plain param_set, because
# param_set_default is a feature under test here.
param_set max_macs 32 driverinit
check_err $? "Failed to reset max_macs to default value"
param_set test1 true driverinit
check_err $? "Failed to reset test1 to default value"
param_set test2 1234 runtime
check_err $? "Failed to reset test2 to default value"
devlink dev reload $DL_HANDLE
check_err $? "Failed to reload device for clean state"
test_default max_macs 16 32 driverinit
test_default test1 false true driverinit
test_default test2 100 1234 runtime
log_test "params default test"
}
check_region_size()
{
local name=$1
local size
size=$(devlink region show $DL_HANDLE/$name -j | jq -e -r '.[][].size')
check_err $? "Failed to get $name region size"
[ $size -eq 32768 ]
check_err $? "Invalid $name region size"
}
check_region_snapshot_count()
{
local name=$1
local phase_name=$2
local expected_count=$3
local count
count=$(devlink region show $DL_HANDLE/$name -j | jq -e -r '.[][].snapshot | length')
[ $count -eq $expected_count ]
check_err $? "Unexpected $phase_name snapshot count"
}
regions_test()
{
RET=0
local count
check_region_size dummy
check_region_snapshot_count dummy initial 0
echo ""> $DEBUGFS_DIR/take_snapshot
check_err $? "Failed to take first dummy region snapshot"
check_region_snapshot_count dummy post-first-snapshot 1
echo ""> $DEBUGFS_DIR/take_snapshot
check_err $? "Failed to take second dummy region snapshot"
check_region_snapshot_count dummy post-second-snapshot 2
echo ""> $DEBUGFS_DIR/take_snapshot
check_err $? "Failed to take third dummy region snapshot"
check_region_snapshot_count dummy post-third-snapshot 3
devlink region del $DL_HANDLE/dummy snapshot 1
check_err $? "Failed to delete first dummy region snapshot"
check_region_snapshot_count dummy post-first-delete 2
devlink region new $DL_HANDLE/dummy snapshot 25
check_err $? "Failed to create a new snapshot with id 25"
check_region_snapshot_count dummy post-first-request 3
devlink region dump $DL_HANDLE/dummy snapshot 25 >> /dev/null
check_err $? "Failed to dump snapshot with id 25"
devlink region read $DL_HANDLE/dummy snapshot 25 addr 0 len 1 >> /dev/null
check_err $? "Failed to read snapshot with id 25 (1 byte)"
devlink region read $DL_HANDLE/dummy snapshot 25 addr 128 len 128 >> /dev/null
check_err $? "Failed to read snapshot with id 25 (128 bytes)"
devlink region read $DL_HANDLE/dummy snapshot 25 addr 128 len $((1<<32)) >> /dev/null
check_err $? "Failed to read snapshot with id 25 (oversized)"
devlink region read $DL_HANDLE/dummy snapshot 25 addr $((1<<32)) len 128 >> /dev/null 2>&1
check_fail $? "Bad read of snapshot with id 25 did not fail"
devlink region del $DL_HANDLE/dummy snapshot 25
check_err $? "Failed to delete snapshot with id 25"
check_region_snapshot_count dummy post-second-delete 2
sid=$(devlink -j region new $DL_HANDLE/dummy | jq '.[][][][]')
check_err $? "Failed to create a new snapshot with id allocated by the kernel"
check_region_snapshot_count dummy post-first-request 3
devlink region dump $DL_HANDLE/dummy snapshot $sid >> /dev/null
check_err $? "Failed to dump a snapshot with id allocated by the kernel"
devlink region del $DL_HANDLE/dummy snapshot $sid
check_err $? "Failed to delete snapshot with id allocated by the kernel"
check_region_snapshot_count dummy post-first-request 2
log_test "regions test"
}
reload_test()
{
RET=0
devlink dev reload $DL_HANDLE
check_err $? "Failed to reload"
echo "y"> $DEBUGFS_DIR/fail_reload
check_err $? "Failed to setup devlink reload to fail"
devlink dev reload $DL_HANDLE
check_fail $? "Unexpected success of devlink reload"
echo "n"> $DEBUGFS_DIR/fail_reload
check_err $? "Failed to setup devlink reload not to fail"
devlink dev reload $DL_HANDLE
check_err $? "Failed to reload after set not to fail"
echo "y"> $DEBUGFS_DIR/dont_allow_reload
check_err $? "Failed to forbid devlink reload"
devlink dev reload $DL_HANDLE
check_fail $? "Unexpected success of devlink reload"
echo "n"> $DEBUGFS_DIR/dont_allow_reload
check_err $? "Failed to re-enable devlink reload"
devlink dev reload $DL_HANDLE
check_err $? "Failed to reload after re-enable"
log_test "reload test"
}
netns_reload_test()
{
RET=0
ip netns add testns1
check_err $? "Failed add netns \"testns1\""
ip netns add testns2
check_err $? "Failed add netns \"testns2\""
devlink dev reload $DL_HANDLE netns testns1
check_err $? "Failed to reload into netns \"testns1\""
devlink -N testns1 dev reload $DL_HANDLE netns testns2
check_err $? "Failed to reload from netns \"testns1\" into netns \"testns2\""
ip netns del testns2
ip netns del testns1
# Wait until netns async cleanup is done.
devlink_wait 2000
log_test "netns reload test"
}
DUMMYDEV="dummytest"
res_val_get()
{
local netns=$1
local parentname=$2
local name=$3
local type=$4
cmd_jq "devlink -N $netns resource show $DL_HANDLE -j" \
".[][][] | select(.name == \"$parentname\").resources[] \
| select(.name == \"$name\").$type"
}
resource_test()
{
RET=0
ip netns add testns1
check_err $? "Failed add netns \"testns1\""
ip netns add testns2
check_err $? "Failed add netns \"testns2\""
devlink dev reload $DL_HANDLE netns testns1
check_err $? "Failed to reload into netns \"testns1\""
# Create dummy dev to add the address and routes on.
ip -n testns1 link add name $DUMMYDEV type dummy
check_err $? "Failed create dummy device"
ip -n testns1 link set $DUMMYDEV up
check_err $? "Failed bring up dummy device"
ip -n testns1 a a 192.0.1.1/24 dev $DUMMYDEV
check_err $? "Failed add an IP address to dummy device"
local occ=$(res_val_get testns1 IPv4 fib occ)
local limit=$((occ+1))
# Set fib size limit to handle one another route only.
devlink -N testns1 resource set $DL_HANDLE path IPv4/fib size $limit
check_err $? "Failed to set IPv4/fib resource size"
local size_new=$(res_val_get testns1 IPv4 fib size_new)
[ "$size_new" -eq "$limit" ]
check_err $? "Unexpected \"size_new\" value (got $size_new, expected $limit)"
devlink -N testns1 dev reload $DL_HANDLE
check_err $? "Failed to reload"
local size=$(res_val_get testns1 IPv4 fib size)
[ "$size" -eq "$limit" ]
check_err $? "Unexpected \"size\" value (got $size, expected $limit)"
# Insert 2 routes, the first is going to be inserted,
# the second is expected to fail to be inserted.
ip -n testns1 r a 192.0.2.0/24 via 192.0.1.2
check_err $? "Failed to add route"
ip -n testns1 r a 192.0.3.0/24 via 192.0.1.2
check_fail $? "Unexpected successful route add over limit"
# Now create another dummy in second network namespace and
# insert two routes. That is over the limit of the netdevsim
# instance in the first namespace. Move the netdevsim instance
# into the second namespace and expect it to fail.
ip -n testns2 link add name $DUMMYDEV type dummy
check_err $? "Failed create dummy device"
ip -n testns2 link set $DUMMYDEV up
check_err $? "Failed bring up dummy device"
ip -n testns2 a a 192.0.1.1/24 dev $DUMMYDEV
check_err $? "Failed add an IP address to dummy device"
ip -n testns2 r a 192.0.2.0/24 via 192.0.1.2
check_err $? "Failed to add route"
ip -n testns2 r a 192.0.3.0/24 via 192.0.1.2
check_err $? "Failed to add route"
devlink -N testns1 dev reload $DL_HANDLE netns testns2
check_fail $? "Unexpected successful reload from netns \"testns1\" into netns \"testns2\""
devlink -N testns2 resource set $DL_HANDLE path IPv4/fib size ' -1'
check_err $? "Failed to reset IPv4/fib resource size"
devlink -N testns2 dev reload $DL_HANDLE netns 1
check_err $? "Failed to reload devlink back"
ip netns del testns2
ip netns del testns1
# Wait until netns async cleanup is done.
devlink_wait 2000
log_test "resource test"
}
resource_dump_test()
{
RET=0
local port_jq
local dev_jq
local dl_jq
local count
dl_jq="with_entries(select(.key | startswith(\"$DL_HANDLE\")))"
port_jq="[.[] | $dl_jq | keys |"
port_jq+=" map(select(test(\"/.+/\"))) | length] | add"
dev_jq="[.[] | $dl_jq | keys |"
dev_jq+=" map(select(test(\"/.+/\")|not)) | length] | add"
if ! devlink resource help 2>&1 | grep -q "scope"; then
echo "SKIP: devlink resource show not supported"
return
fi
devlink resource show > /dev/null 2>&1
check_err $? "Failed to dump all resources"
count=$(cmd_jq "devlink resource show -j" "$port_jq")
[ "$count" -gt "0" ]
check_err $? "missing port resources in resource dump"
count=$(cmd_jq "devlink resource show -j" "$dev_jq")
[ "$count" -gt "0" ]
check_err $? "missing device resources in resource dump"
count=$(cmd_jq "devlink resource show scope dev -j" "$dev_jq")
[ "$count" -gt "0" ]
check_err $? "dev scope missing device resources"
count=$(cmd_jq "devlink resource show scope dev -j" "$port_jq")
[ "$count" -eq "0" ]
check_err $? "dev scope returned port resources"
count=$(cmd_jq "devlink resource show scope port -j" "$port_jq")
[ "$count" -gt "0" ]
check_err $? "port scope missing port resources"
count=$(cmd_jq "devlink resource show scope port -j" "$dev_jq")
[ "$count" -eq "0" ]
check_err $? "port scope returned device resources"
log_test "resource dump test"
}
info_get()
{
local name=$1
cmd_jq "devlink dev info $DL_HANDLE -j" ".[][][\"$name\"]" "-e"
}
dev_info_test()
{
RET=0
driver=$(info_get "driver")
check_err $? "Failed to get driver name"
[ "$driver" == "netdevsim" ]
check_err $? "Unexpected driver name $driver"
log_test "dev_info test"
}
empty_reporter_test()
{
RET=0
devlink health show $DL_HANDLE reporter empty >/dev/null
check_err $? "Failed show empty reporter"
devlink health dump show $DL_HANDLE reporter empty >/dev/null
check_err $? "Failed show dump of empty reporter"
devlink health diagnose $DL_HANDLE reporter empty >/dev/null
check_err $? "Failed diagnose empty reporter"
devlink health recover $DL_HANDLE reporter empty
check_err $? "Failed recover empty reporter"
log_test "empty reporter test"
}
check_reporter_info()
{
local name=$1
local expected_state=$2
local expected_error=$3
local expected_recover=$4
local expected_grace_period=$5
local expected_auto_recover=$6
local show=$(devlink health show $DL_HANDLE reporter $name -j | jq -e -r ".[][][]")
check_err $? "Failed show $name reporter"
local state=$(echo $show | jq -r ".state")
[ "$state" == "$expected_state" ]
check_err $? "Unexpected \"state\" value (got $state, expected $expected_state)"
local error=$(echo $show | jq -r ".error")
[ "$error" == "$expected_error" ]
check_err $? "Unexpected \"error\" value (got $error, expected $expected_error)"
local recover=`echo $show | jq -r ".recover"`
[ "$recover" == "$expected_recover" ]
check_err $? "Unexpected \"recover\" value (got $recover, expected $expected_recover)"
local grace_period=$(echo $show | jq -r ".grace_period")
check_err $? "Failed get $name reporter grace_period"
[ "$grace_period" == "$expected_grace_period" ]
check_err $? "Unexpected \"grace_period\" value (got $grace_period, expected $expected_grace_period)"
local auto_recover=$(echo $show | jq -r ".auto_recover")
[ "$auto_recover" == "$expected_auto_recover" ]
check_err $? "Unexpected \"auto_recover\" value (got $auto_recover, expected $expected_auto_recover)"
}
dummy_reporter_test()
{
RET=0
check_reporter_info dummy healthy 0 0 0 true
devlink health set $DL_HANDLE reporter dummy auto_recover false
check_err $? "Failed to dummy reporter auto_recover option"
check_reporter_info dummy healthy 0 0 0 false
local BREAK_MSG="foo bar"
echo "$BREAK_MSG"> $DEBUGFS_DIR/health/break_health
check_err $? "Failed to break dummy reporter"
check_reporter_info dummy error 1 0 0 false
local dump=$(devlink health dump show $DL_HANDLE reporter dummy -j)
check_err $? "Failed show dump of dummy reporter"
local dump_break_msg=$(echo $dump | jq -r ".break_message")
[ "$dump_break_msg" == "$BREAK_MSG" ]
check_err $? "Unexpected dump break message value (got $dump_break_msg, expected $BREAK_MSG)"
devlink health dump clear $DL_HANDLE reporter dummy
check_err $? "Failed clear dump of dummy reporter"
devlink health recover $DL_HANDLE reporter dummy
check_err $? "Failed recover dummy reporter"
check_reporter_info dummy healthy 1 1 0 false
devlink health set $DL_HANDLE reporter dummy auto_recover true
check_err $? "Failed to dummy reporter auto_recover option"
check_reporter_info dummy healthy 1 1 0 true
echo "$BREAK_MSG"> $DEBUGFS_DIR/health/break_health
check_err $? "Failed to break dummy reporter"
check_reporter_info dummy healthy 2 2 0 true
local diagnose=$(devlink health diagnose $DL_HANDLE reporter dummy -j -p)
check_err $? "Failed show diagnose of dummy reporter"
local rcvrd_break_msg=$(echo $diagnose | jq -r ".recovered_break_message")
[ "$rcvrd_break_msg" == "$BREAK_MSG" ]
check_err $? "Unexpected recovered break message value (got $rcvrd_break_msg, expected $BREAK_MSG)"
devlink health set $DL_HANDLE reporter dummy grace_period 10
check_err $? "Failed to dummy reporter grace_period option"
check_reporter_info dummy healthy 2 2 10 true
echo "Y"> $DEBUGFS_DIR/health/fail_recover
check_err $? "Failed set dummy reporter recovery to fail"
echo "$BREAK_MSG"> $DEBUGFS_DIR/health/break_health
check_fail $? "Unexpected success of dummy reporter break"
check_reporter_info dummy error 3 2 10 true
devlink health recover $DL_HANDLE reporter dummy
check_fail $? "Unexpected success of dummy reporter recover"
echo "N"> $DEBUGFS_DIR/health/fail_recover
check_err $? "Failed set dummy reporter recovery to be successful"
devlink health recover $DL_HANDLE reporter dummy
check_err $? "Failed recover dummy reporter"
check_reporter_info dummy healthy 3 3 10 true
echo 8192 > $DEBUGFS_DIR/health/binary_len
check_err $? "Failed set dummy reporter binary len to 8192"
local dump=$(devlink health dump show $DL_HANDLE reporter dummy -j)
check_err $? "Failed show dump of dummy reporter"
devlink health dump clear $DL_HANDLE reporter dummy
check_err $? "Failed clear dump of dummy reporter"
log_test "dummy reporter test"
}
rate_leafs_get()
{
local handle=$1
cmd_jq "devlink port function rate show -j" \
'.[] | to_entries | .[] | select(.value.type == "leaf") | .key | select(contains("'$handle'"))'
}
rate_nodes_get()
{
local handle=$1
cmd_jq "devlink port function rate show -j" \
'.[] | to_entries | .[] | select(.value.type == "node") | .key | select(contains("'$handle'"))'
}
rate_attr_set()
{
local handle=$1
local name=$2
local value=$3
local units=$4
devlink port function rate set $handle $name $value$units
}
rate_attr_get()
{
local handle=$1
local name=$2
cmd_jq "devlink port function rate show $handle -j" '.[][].'$name
}
rate_attr_tx_rate_check()
{
local handle=$1
local name=$2
local rate=$3
local debug_file=$4
rate_attr_set $handle $name $rate mbit
check_err $? "Failed to set $name value"
local debug_value=$(cat $debug_file)
check_err $? "Failed to read $name value from debugfs"
[ "$debug_value" == "$rate" ]
check_err $? "Unexpected $name debug value $debug_value != $rate"
local api_value=$(( $(rate_attr_get $handle $name) * 8 / 1000000 ))
check_err $? "Failed to get $name attr value"
[ "$api_value" == "$rate" ]
check_err $? "Unexpected $name attr value $api_value != $rate"
}
rate_attr_parent_check()
{
local handle=$1
local parent=$2
local debug_file=$3
rate_attr_set $handle parent $parent
check_err $? "Failed to set parent"
debug_value=$(cat $debug_file)
check_err $? "Failed to get parent debugfs value"
[ "$debug_value" == "$parent" ]
check_err $? "Unexpected parent debug value $debug_value != $parent"
api_value=$(rate_attr_get $r_obj parent)
check_err $? "Failed to get parent attr value"
[ "$api_value" == "$parent" ]
check_err $? "Unexpected parent attr value $api_value != $parent"
}
rate_attr_tc_bw_check()
{
local handle=$1
local tc_bw=$2
local debug_file=$3
local tc_bw_str=""
for bw in $tc_bw; do
local tc=${bw%%:*}
local value=${bw##*:}
tc_bw_str="$tc_bw_str $tc:$value"
done
tc_bw_str=${tc_bw_str# }
rate_attr_set "$handle" tc-bw "$tc_bw_str"
check_err $? "Failed to set tc-bw values"
for bw in $tc_bw; do
local tc=${bw%%:*}
local value=${bw##*:}
local debug_value
debug_value=$(cat "$debug_file"/tc"${tc}"_bw)
check_err $? "Failed to read tc-bw value from debugfs for tc$tc"
[ "$debug_value" == "$value" ]
check_err $? "Unexpected tc-bw debug value for tc$tc: $debug_value != $value"
done
for bw in $tc_bw; do
local tc=${bw%%:*}
local expected_value=${bw##*:}
local api_value
api_value=$(rate_attr_get "$handle" tc_"$tc")
if [ "$api_value" = "null" ]; then
api_value=0
fi
[ "$api_value" == "$expected_value" ]
check_err $? "Unexpected tc-bw value for tc$tc: $api_value != $expected_value"
done
}
rate_node_add()
{
local handle=$1
devlink port function rate add $handle
}
rate_node_del()
{
local handle=$1
devlink port function rate del $handle
}
port_resource_doit_test()
{
RET=0
local port_handle="${DL_HANDLE}/0"
local name
local size
if ! devlink resource help 2>&1 | grep -q "PORT_INDEX"; then
echo "SKIP: devlink resource show with port not supported"
return
fi
name=$(cmd_jq "devlink resource show $port_handle -j" \
'.[][][].name')
[ "$name" == "test_resource" ]
check_err $? "wrong port resource name (got $name)"
size=$(cmd_jq "devlink resource show $port_handle -j" \
'.[][][].size')
[ "$size" == "20" ]
check_err $? "wrong port resource size (got $size)"
log_test "port resource doit test"
}
rate_test()
{
RET=0
echo $VF_COUNT > /sys/bus/netdevsim/devices/$DEV_NAME/sriov_numvfs
devlink dev eswitch set $DL_HANDLE mode switchdev
local leafs=`rate_leafs_get $DL_HANDLE`
local num_leafs=`echo $leafs | wc -w`
[ "$num_leafs" == "$VF_COUNT" ]
check_err $? "Expected $VF_COUNT rate leafs but got $num_leafs"
rate=10
for r_obj in $leafs
do
rate_attr_tx_rate_check $r_obj tx_share $rate \
$DEBUGFS_DIR/ports/${r_obj##*/}/tx_share
rate=$(($rate+10))
done
rate=100
for r_obj in $leafs
do
rate_attr_tx_rate_check $r_obj tx_max $rate \
$DEBUGFS_DIR/ports/${r_obj##*/}/tx_max
rate=$(($rate+100))
done
local tc_bw="0:0 1:40 2:0 3:0 4:0 5:0 6:60 7:0"
for r_obj in $leafs
do
rate_attr_tc_bw_check "$r_obj" "$tc_bw" \
"$DEBUGFS_DIR"/ports/"${r_obj##*/}"
done
local node1_name='group1'
local node1="$DL_HANDLE/$node1_name"
rate_node_add "$node1"
check_err $? "Failed to add node $node1"
local num_nodes=`rate_nodes_get $DL_HANDLE | wc -w`
[ $num_nodes == 1 ]
check_err $? "Expected 1 rate node in output but got $num_nodes"
local node_tx_share=10
rate_attr_tx_rate_check $node1 tx_share $node_tx_share \
$DEBUGFS_DIR/rate_nodes/${node1##*/}/tx_share
local node_tx_max=100
rate_attr_tx_rate_check $node1 tx_max $node_tx_max \
$DEBUGFS_DIR/rate_nodes/${node1##*/}/tx_max
local tc_bw="0:20 1:0 2:0 3:0 4:0 5:20 6:60 7:0"
rate_attr_tc_bw_check $node1 "$tc_bw" \
"$DEBUGFS_DIR"/rate_nodes/"${node1##*/}"
rate_node_del "$node1"
check_err $? "Failed to delete node $node1"
local num_nodes=`rate_nodes_get $DL_HANDLE | wc -w`
[ $num_nodes == 0 ]
check_err $? "Expected 0 rate node but got $num_nodes"
local node1_name='group1'
local node1="$DL_HANDLE/$node1_name"
rate_node_add "$node1"
check_err $? "Failed to add node $node1"
rate_attr_parent_check $r_obj $node1_name \
$DEBUGFS_DIR/ports/${r_obj##*/}/rate_parent
local node2_name='group2'
local node2="$DL_HANDLE/$node2_name"
rate_node_add "$node2"
check_err $? "Failed to add node $node2"
rate_attr_parent_check $node2 $node1_name \
$DEBUGFS_DIR/rate_nodes/$node2_name/rate_parent
rate_node_del "$node2"
check_err $? "Failed to delete node $node2"
rate_attr_set "$r_obj" noparent
check_err $? "Failed to unset $r_obj parent node"
rate_node_del "$node1"
check_err $? "Failed to delete node $node1"
log_test "rate test"
}
setup_prepare()
{
modprobe netdevsim
echo "$BUS_ADDR $PORT_COUNT" > /sys/bus/netdevsim/new_device
while [ ! -d $SYSFS_NET_DIR ] ; do :; done
}
cleanup()
{
pre_cleanup
echo "$BUS_ADDR" > /sys/bus/netdevsim/del_device
modprobe -r netdevsim
}
trap cleanup EXIT
setup_prepare
tests_run
exit $EXIT_STATUS
@@ -0,0 +1,72 @@
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0
lib_dir=$(dirname $0)/../../../net/forwarding
ALL_TESTS="check_devlink_test check_ports_test"
NUM_NETIFS=0
source $lib_dir/lib.sh
BUS_ADDR=10
PORT_COUNT=4
DEV_NAME=netdevsim$BUS_ADDR
SYSFS_NET_DIR=/sys/bus/netdevsim/devices/$DEV_NAME/net/
DL_HANDLE=netdevsim/$DEV_NAME
NETNS_NAME=testns1
port_netdev_get()
{
local port_index=$1
cmd_jq "devlink -N $NETNS_NAME port show -j" \
".[][\"$DL_HANDLE/$port_index\"].netdev" "-e"
}
check_ports_test()
{
RET=0
for i in $(seq 0 $(expr $PORT_COUNT - 1)); do
netdev_name=$(port_netdev_get $i)
check_err $? "Failed to get netdev name for port $DL_HANDLE/$i"
ip -n $NETNS_NAME link show $netdev_name &> /dev/null
check_err $? "Failed to find netdev $netdev_name"
done
log_test "check ports test"
}
check_devlink_test()
{
RET=0
devlink -N $NETNS_NAME dev show $DL_HANDLE &> /dev/null
check_err $? "Failed to show devlink instance"
log_test "check devlink test"
}
setup_prepare()
{
modprobe netdevsim
ip netns add $NETNS_NAME
ip netns exec $NETNS_NAME \
echo "$BUS_ADDR $PORT_COUNT" > /sys/bus/netdevsim/new_device
while [ ! -d $SYSFS_NET_DIR ] ; do :; done
}
cleanup()
{
pre_cleanup
echo "$BUS_ADDR" > /sys/bus/netdevsim/del_device
ip netns del $NETNS_NAME
modprobe -r netdevsim
}
trap cleanup EXIT
setup_prepare
tests_run
exit $EXIT_STATUS
@@ -0,0 +1,514 @@
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0
#
# This test is for checking devlink-trap functionality. It makes use of
# netdevsim which implements the required callbacks.
lib_dir=$(dirname $0)/../../../net/forwarding
ALL_TESTS="
init_test
trap_action_test
trap_metadata_test
bad_trap_test
bad_trap_action_test
trap_stats_test
trap_group_action_test
bad_trap_group_test
trap_group_stats_test
trap_policer_test
trap_policer_bind_test
port_del_test
dev_del_test
"
NETDEVSIM_PATH=/sys/bus/netdevsim/
DEV_ADDR=1337
DEV=netdevsim${DEV_ADDR}
DEBUGFS_DIR=/sys/kernel/debug/netdevsim/$DEV/
SLEEP_TIME=1
NETDEV=""
NUM_NETIFS=0
source $lib_dir/lib.sh
DEVLINK_DEV=
source $lib_dir/devlink_lib.sh
DEVLINK_DEV=netdevsim/${DEV}
require_command udevadm
modprobe netdevsim &> /dev/null
if [ ! -d "$NETDEVSIM_PATH" ]; then
echo "SKIP: No netdevsim support"
exit 1
fi
if [ -d "${NETDEVSIM_PATH}/devices/netdevsim${DEV_ADDR}" ]; then
echo "SKIP: Device netdevsim${DEV_ADDR} already exists"
exit 1
fi
check_netdev_down()
{
state=$(cat /sys/class/net/${NETDEV}/flags)
if [ $((state & 1)) -ne 0 ]; then
echo "WARNING: unexpected interface UP, disable NetworkManager?"
ip link set dev $NETDEV down
fi
}
init_test()
{
RET=0
test $(devlink_traps_num_get) -ne 0
check_err $? "No traps were registered"
log_test "Initialization"
}
trap_action_test()
{
local orig_action
local trap_name
local action
RET=0
for trap_name in $(devlink_traps_get); do
# The action of non-drop traps cannot be changed.
if [ $(devlink_trap_type_get $trap_name) = "drop" ]; then
devlink_trap_action_set $trap_name "trap"
action=$(devlink_trap_action_get $trap_name)
if [ $action != "trap" ]; then
check_err 1 "Trap $trap_name did not change action to trap"
fi
devlink_trap_action_set $trap_name "drop"
action=$(devlink_trap_action_get $trap_name)
if [ $action != "drop" ]; then
check_err 1 "Trap $trap_name did not change action to drop"
fi
else
orig_action=$(devlink_trap_action_get $trap_name)
devlink_trap_action_set $trap_name "trap"
action=$(devlink_trap_action_get $trap_name)
if [ $action != $orig_action ]; then
check_err 1 "Trap $trap_name changed action when should not"
fi
devlink_trap_action_set $trap_name "drop"
action=$(devlink_trap_action_get $trap_name)
if [ $action != $orig_action ]; then
check_err 1 "Trap $trap_name changed action when should not"
fi
fi
done
log_test "Trap action"
}
trap_metadata_test()
{
local trap_name
RET=0
for trap_name in $(devlink_traps_get); do
devlink_trap_metadata_test $trap_name "input_port"
check_err $? "Input port not reported as metadata of trap $trap_name"
if [ $trap_name == "ingress_flow_action_drop" ] ||
[ $trap_name == "egress_flow_action_drop" ]; then
devlink_trap_metadata_test $trap_name "flow_action_cookie"
check_err $? "Flow action cookie not reported as metadata of trap $trap_name"
fi
done
log_test "Trap metadata"
}
bad_trap_test()
{
RET=0
devlink_trap_action_set "made_up_trap" "drop"
check_fail $? "Did not get an error for non-existing trap"
log_test "Non-existing trap"
}
bad_trap_action_test()
{
local traps_arr
local trap_name
RET=0
# Pick first trap.
traps_arr=($(devlink_traps_get))
trap_name=${traps_arr[0]}
devlink_trap_action_set $trap_name "made_up_action"
check_fail $? "Did not get an error for non-existing trap action"
log_test "Non-existing trap action"
}
trap_stats_test()
{
local trap_name
RET=0
check_netdev_down
for trap_name in $(devlink_traps_get); do
devlink_trap_stats_idle_test $trap_name
check_err $? "Stats of trap $trap_name not idle when netdev down"
ip link set dev $NETDEV up
if [ $(devlink_trap_type_get $trap_name) = "drop" ]; then
devlink_trap_action_set $trap_name "trap"
devlink_trap_stats_idle_test $trap_name
check_fail $? "Stats of trap $trap_name idle when action is trap"
devlink_trap_action_set $trap_name "drop"
devlink_trap_stats_idle_test $trap_name
check_err $? "Stats of trap $trap_name not idle when action is drop"
echo "y"> $DEBUGFS_DIR/fail_trap_drop_counter_get
devlink -s trap show $DEVLINK_DEV trap $trap_name &> /dev/null
check_fail $? "Managed to read trap (hard dropped) statistics when should not"
echo "n"> $DEBUGFS_DIR/fail_trap_drop_counter_get
devlink -s trap show $DEVLINK_DEV trap $trap_name &> /dev/null
check_err $? "Did not manage to read trap (hard dropped) statistics when should"
devlink_trap_drop_stats_idle_test $trap_name
check_fail $? "Drop stats of trap $trap_name idle when should not"
else
devlink_trap_stats_idle_test $trap_name
check_fail $? "Stats of non-drop trap $trap_name idle when should not"
fi
ip link set dev $NETDEV down
done
log_test "Trap statistics"
}
trap_group_action_test()
{
local curr_group group_name
local trap_name
local trap_type
local action
RET=0
for group_name in $(devlink_trap_groups_get); do
devlink_trap_group_action_set $group_name "trap"
for trap_name in $(devlink_traps_get); do
curr_group=$(devlink_trap_group_get $trap_name)
if [ $curr_group != $group_name ]; then
continue
fi
trap_type=$(devlink_trap_type_get $trap_name)
if [ $trap_type != "drop" ]; then
continue
fi
action=$(devlink_trap_action_get $trap_name)
if [ $action != "trap" ]; then
check_err 1 "Trap $trap_name did not change action to trap"
fi
done
devlink_trap_group_action_set $group_name "drop"
for trap_name in $(devlink_traps_get); do
curr_group=$(devlink_trap_group_get $trap_name)
if [ $curr_group != $group_name ]; then
continue
fi
trap_type=$(devlink_trap_type_get $trap_name)
if [ $trap_type != "drop" ]; then
continue
fi
action=$(devlink_trap_action_get $trap_name)
if [ $action != "drop" ]; then
check_err 1 "Trap $trap_name did not change action to drop"
fi
done
done
log_test "Trap group action"
}
bad_trap_group_test()
{
RET=0
devlink_trap_group_action_set "made_up_trap_group" "drop"
check_fail $? "Did not get an error for non-existing trap group"
log_test "Non-existing trap group"
}
trap_group_stats_test()
{
local group_name
RET=0
check_netdev_down
for group_name in $(devlink_trap_groups_get); do
devlink_trap_group_stats_idle_test $group_name
check_err $? "Stats of trap group $group_name not idle when netdev down"
ip link set dev $NETDEV up
devlink_trap_group_action_set $group_name "trap"
devlink_trap_group_stats_idle_test $group_name
check_fail $? "Stats of trap group $group_name idle when action is trap"
devlink_trap_group_action_set $group_name "drop"
ip link set dev $NETDEV down
done
log_test "Trap group statistics"
}
trap_policer_test()
{
local packets_t0
local packets_t1
RET=0
if [ $(devlink_trap_policers_num_get) -eq 0 ]; then
check_err 1 "Failed to dump policers"
fi
devlink trap policer set $DEVLINK_DEV policer 1337 &> /dev/null
check_fail $? "Did not get an error for setting a non-existing policer"
devlink trap policer show $DEVLINK_DEV policer 1337 &> /dev/null
check_fail $? "Did not get an error for getting a non-existing policer"
devlink trap policer set $DEVLINK_DEV policer 1 rate 2000 burst 16
check_err $? "Failed to set valid parameters for a valid policer"
if [ $(devlink_trap_policer_rate_get 1) -ne 2000 ]; then
check_err 1 "Policer rate was not changed"
fi
if [ $(devlink_trap_policer_burst_get 1) -ne 16 ]; then
check_err 1 "Policer burst size was not changed"
fi
devlink trap policer set $DEVLINK_DEV policer 1 rate 0 &> /dev/null
check_fail $? "Policer rate was changed to rate lower than limit"
devlink trap policer set $DEVLINK_DEV policer 1 rate 9000 &> /dev/null
check_fail $? "Policer rate was changed to rate higher than limit"
devlink trap policer set $DEVLINK_DEV policer 1 burst 2 &> /dev/null
check_fail $? "Policer burst size was changed to burst size lower than limit"
devlink trap policer set $DEVLINK_DEV policer 1 rate 65537 &> /dev/null
check_fail $? "Policer burst size was changed to burst size higher than limit"
echo "y" > $DEBUGFS_DIR/fail_trap_policer_set
devlink trap policer set $DEVLINK_DEV policer 1 rate 3000 &> /dev/null
check_fail $? "Managed to set policer rate when should not"
echo "n" > $DEBUGFS_DIR/fail_trap_policer_set
if [ $(devlink_trap_policer_rate_get 1) -ne 2000 ]; then
check_err 1 "Policer rate was changed to an invalid value"
fi
if [ $(devlink_trap_policer_burst_get 1) -ne 16 ]; then
check_err 1 "Policer burst size was changed to an invalid value"
fi
packets_t0=$(devlink_trap_policer_rx_dropped_get 1)
sleep .5
packets_t1=$(devlink_trap_policer_rx_dropped_get 1)
if [ ! $packets_t1 -gt $packets_t0 ]; then
check_err 1 "Policer drop counter was not incremented"
fi
echo "y"> $DEBUGFS_DIR/fail_trap_policer_counter_get
devlink -s trap policer show $DEVLINK_DEV policer 1 &> /dev/null
check_fail $? "Managed to read policer drop counter when should not"
echo "n"> $DEBUGFS_DIR/fail_trap_policer_counter_get
devlink -s trap policer show $DEVLINK_DEV policer 1 &> /dev/null
check_err $? "Did not manage to read policer drop counter when should"
log_test "Trap policer"
}
trap_group_check_policer()
{
local group_name=$1; shift
devlink -j -p trap group show $DEVLINK_DEV group $group_name \
| jq -e '.[][][]["policer"]' &> /dev/null
}
trap_policer_bind_test()
{
RET=0
devlink trap group set $DEVLINK_DEV group l2_drops policer 1
check_err $? "Failed to bind a valid policer"
if [ $(devlink_trap_group_policer_get "l2_drops") -ne 1 ]; then
check_err 1 "Bound policer was not changed"
fi
devlink trap group set $DEVLINK_DEV group l2_drops policer 1337 \
&> /dev/null
check_fail $? "Did not get an error for binding a non-existing policer"
if [ $(devlink_trap_group_policer_get "l2_drops") -ne 1 ]; then
check_err 1 "Bound policer was changed when should not"
fi
devlink trap group set $DEVLINK_DEV group l2_drops policer 0
check_err $? "Failed to unbind a policer when using ID 0"
trap_group_check_policer "l2_drops"
check_fail $? "Trap group has a policer after unbinding with ID 0"
devlink trap group set $DEVLINK_DEV group l2_drops policer 1
check_err $? "Failed to bind a valid policer"
devlink trap group set $DEVLINK_DEV group l2_drops nopolicer
check_err $? "Failed to unbind a policer when using 'nopolicer' keyword"
trap_group_check_policer "l2_drops"
check_fail $? "Trap group has a policer after unbinding with 'nopolicer' keyword"
devlink trap group set $DEVLINK_DEV group l2_drops policer 1
check_err $? "Failed to bind a valid policer"
echo "y"> $DEBUGFS_DIR/fail_trap_group_set
devlink trap group set $DEVLINK_DEV group l2_drops policer 2 \
&> /dev/null
check_fail $? "Managed to bind a policer when should not"
echo "n"> $DEBUGFS_DIR/fail_trap_group_set
devlink trap group set $DEVLINK_DEV group l2_drops policer 2
check_err $? "Did not manage to bind a policer when should"
devlink trap group set $DEVLINK_DEV group l2_drops action drop \
policer 1337 &> /dev/null
check_fail $? "Did not get an error for partially modified trap group"
log_test "Trap policer binding"
}
port_del_test()
{
local group_name
local i
# The test never fails. It is meant to exercise different code paths
# and make sure we properly dismantle a port while packets are
# in-flight.
RET=0
devlink_traps_enable_all
for i in $(seq 1 10); do
ip link set dev $NETDEV up
sleep $SLEEP_TIME
netdevsim_port_destroy
netdevsim_port_create
udevadm settle
done
devlink_traps_disable_all
log_test "Port delete"
}
dev_del_test()
{
local group_name
local i
# The test never fails. It is meant to exercise different code paths
# and make sure we properly unregister traps while packets are
# in-flight.
RET=0
devlink_traps_enable_all
for i in $(seq 1 10); do
ip link set dev $NETDEV up
sleep $SLEEP_TIME
cleanup
setup_prepare
done
devlink_traps_disable_all
log_test "Device delete"
}
netdevsim_dev_create()
{
echo "$DEV_ADDR 0" > ${NETDEVSIM_PATH}/new_device
}
netdevsim_dev_destroy()
{
echo "$DEV_ADDR" > ${NETDEVSIM_PATH}/del_device
}
netdevsim_port_create()
{
echo 1 > ${NETDEVSIM_PATH}/devices/${DEV}/new_port
}
netdevsim_port_destroy()
{
echo 1 > ${NETDEVSIM_PATH}/devices/${DEV}/del_port
}
setup_prepare()
{
local netdev
netdevsim_dev_create
if [ ! -d "${NETDEVSIM_PATH}/devices/${DEV}" ]; then
echo "Failed to create netdevsim device"
exit 1
fi
netdevsim_port_create
if [ ! -d "${NETDEVSIM_PATH}/devices/${DEV}/net/" ]; then
echo "Failed to create netdevsim port"
exit 1
fi
# Wait for udev to rename newly created netdev.
udevadm settle
NETDEV=$(ls ${NETDEVSIM_PATH}/devices/${DEV}/net/)
}
cleanup()
{
pre_cleanup
netdevsim_port_destroy
netdevsim_dev_destroy
}
trap cleanup EXIT
setup_prepare
tests_run
exit $EXIT_STATUS
@@ -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
@@ -0,0 +1,57 @@
#!/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
local exp_fail=$4
[ -z "$exp_fail" ] && cop="-ne" || cop="-eq"
if [ $code $cop 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
udevadm settle
# get new device name
ls /sys/bus/netdevsim/devices/netdevsim${NSIM_ID}/net/
}
@@ -0,0 +1,31 @@
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0-only
source ethtool-common.sh
NSIM_NETDEV=$(make_netdev)
set -o pipefail
FEATS="
tx-checksum-ip-generic
tx-scatter-gather
tx-tcp-segmentation
generic-segmentation-offload
generic-receive-offload"
for feat in $FEATS ; do
s=$(ethtool --json -k $NSIM_NETDEV | jq ".[].\"$feat\".active" 2>/dev/null)
check $? "$s" true
s=$(ethtool --json -k $NSIM_NETDEV | jq ".[].\"$feat\".fixed" 2>/dev/null)
check $? "$s" false
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
@@ -0,0 +1,114 @@
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0-only
source ethtool-common.sh
NSIM_NETDEV=$(make_netdev)
[ a$ETHTOOL == a ] && ETHTOOL=ethtool
set -o pipefail
# Since commit 2b3ddcb35357 ("ethtool: fec: Change the prompt ...")
# in ethtool CLI the Configured lines start with Supported/Configured.
configured=$($ETHTOOL --show-fec $NSIM_NETDEV | tail -2 | head -1 | cut -d' ' -f1)
# netdevsim starts out with None/None
s=$($ETHTOOL --show-fec $NSIM_NETDEV | tail -2)
check $? "$s" "$configured FEC encodings: None
Active FEC encoding: None"
# Test Auto
$ETHTOOL --set-fec $NSIM_NETDEV encoding auto
check $?
s=$($ETHTOOL --show-fec $NSIM_NETDEV | tail -2)
check $? "$s" "$configured FEC encodings: Auto
Active FEC encoding: Off"
# Test case in-sensitivity
for o in off Off OFF; do
$ETHTOOL --set-fec $NSIM_NETDEV encoding $o
check $?
s=$($ETHTOOL --show-fec $NSIM_NETDEV | tail -2)
check $? "$s" "$configured FEC encodings: Off
Active FEC encoding: Off"
done
for o in BaseR baser BAser; do
$ETHTOOL --set-fec $NSIM_NETDEV encoding $o
check $?
s=$($ETHTOOL --show-fec $NSIM_NETDEV | tail -2)
check $? "$s" "$configured FEC encodings: BaseR
Active FEC encoding: BaseR"
done
for o in llrs rs; do
$ETHTOOL --set-fec $NSIM_NETDEV encoding $o
check $?
s=$($ETHTOOL --show-fec $NSIM_NETDEV | tail -2)
check $? "$s" "$configured FEC encodings: ${o^^}
Active FEC encoding: ${o^^}"
done
# Test multiple bits
$ETHTOOL --set-fec $NSIM_NETDEV encoding rs llrs
check $?
s=$($ETHTOOL --show-fec $NSIM_NETDEV | tail -2)
check $? "$s" "$configured FEC encodings: RS LLRS
Active FEC encoding: LLRS"
$ETHTOOL --set-fec $NSIM_NETDEV encoding rs off auto
check $?
s=$($ETHTOOL --show-fec $NSIM_NETDEV | tail -2)
check $? "$s" "$configured FEC encodings: Auto Off RS
Active FEC encoding: RS"
# Make sure other link modes are rejected
$ETHTOOL --set-fec $NSIM_NETDEV encoding FIBRE 2>/dev/null
check $? '' '' 1
$ETHTOOL --set-fec $NSIM_NETDEV encoding bla-bla-bla 2>/dev/null
check $? '' '' 1
# Try JSON
$ETHTOOL --json --show-fec $NSIM_NETDEV | jq empty >>/dev/null 2>&1
if [ $? -eq 0 ]; then
$ETHTOOL --set-fec $NSIM_NETDEV encoding auto
check $?
s=$($ETHTOOL --json --show-fec $NSIM_NETDEV | jq '.[].config[]')
check $? "$s" '"Auto"'
s=$($ETHTOOL --json --show-fec $NSIM_NETDEV | jq '.[].active[]')
check $? "$s" '"Off"'
$ETHTOOL --set-fec $NSIM_NETDEV encoding auto RS
check $?
s=$($ETHTOOL --json --show-fec $NSIM_NETDEV | jq '.[].config[]')
check $? "$s" '"Auto"
"RS"'
s=$($ETHTOOL --json --show-fec $NSIM_NETDEV | jq '.[].active[]')
check $? "$s" '"RS"'
fi
# Test error injection
echo 11 > $NSIM_DEV_DFS/ethtool/get_err
$ETHTOOL --show-fec $NSIM_NETDEV >>/dev/null 2>&1
check $? '' '' 1
echo 0 > $NSIM_DEV_DFS/ethtool/get_err
echo 11 > $NSIM_DEV_DFS/ethtool/set_err
$ETHTOOL --show-fec $NSIM_NETDEV >>/dev/null 2>&1
check $?
$ETHTOOL --set-fec $NSIM_NETDEV encoding RS 2>/dev/null
check $? '' '' 1
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
@@ -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
@@ -0,0 +1,402 @@
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0
#
# This test is for checking the FIB offload API. It makes use of netdevsim
# which registers a listener to the FIB notification chain.
lib_dir=$(dirname $0)/../../../net/forwarding
ALL_TESTS="
ipv4_identical_routes
ipv4_tos
ipv4_metric
ipv4_replace
ipv4_delete
ipv4_plen
ipv4_replay
ipv4_flush
ipv4_error_path
ipv4_delete_fail
ipv6_add
ipv6_metric
ipv6_append_single
ipv6_replace_single
ipv6_metric_multipath
ipv6_append_multipath
ipv6_replace_multipath
ipv6_append_multipath_to_single
ipv6_delete_single
ipv6_delete_multipath
ipv6_replay_single
ipv6_replay_multipath
ipv6_error_path
ipv6_delete_fail
"
NETDEVSIM_PATH=/sys/bus/netdevsim/
DEV_ADDR=1337
DEV=netdevsim${DEV_ADDR}
SYSFS_NET_DIR=/sys/bus/netdevsim/devices/$DEV/net/
DEBUGFS_DIR=/sys/kernel/debug/netdevsim/$DEV/
NUM_NETIFS=0
source $lib_dir/lib.sh
source $lib_dir/fib_offload_lib.sh
DEVLINK_DEV=
source $lib_dir/devlink_lib.sh
DEVLINK_DEV=netdevsim/${DEV}
ipv4_identical_routes()
{
fib_ipv4_identical_routes_test "testns1"
}
ipv4_tos()
{
fib_ipv4_tos_test "testns1"
}
ipv4_metric()
{
fib_ipv4_metric_test "testns1"
}
ipv4_replace()
{
fib_ipv4_replace_test "testns1"
}
ipv4_delete()
{
fib_ipv4_delete_test "testns1"
}
ipv4_plen()
{
fib_ipv4_plen_test "testns1"
}
ipv4_replay_metric()
{
fib_ipv4_replay_metric_test "testns1" "$DEVLINK_DEV"
}
ipv4_replay_tos()
{
fib_ipv4_replay_tos_test "testns1" "$DEVLINK_DEV"
}
ipv4_replay_plen()
{
fib_ipv4_replay_plen_test "testns1" "$DEVLINK_DEV"
}
ipv4_replay()
{
ipv4_replay_metric
ipv4_replay_tos
ipv4_replay_plen
}
ipv4_flush()
{
fib_ipv4_flush_test "testns1"
}
ipv4_error_path_add()
{
local lsb
RET=0
ip -n testns1 link add name dummy1 type dummy
ip -n testns1 link set dev dummy1 up
devlink -N testns1 resource set $DEVLINK_DEV path IPv4/fib size 10
devlink -N testns1 dev reload $DEVLINK_DEV
for lsb in $(seq 1 20); do
ip -n testns1 route add 192.0.2.${lsb}/32 dev dummy1 \
&> /dev/null
done
log_test "IPv4 error path - add"
ip -n testns1 link del dev dummy1
}
ipv4_error_path_replay()
{
local lsb
RET=0
ip -n testns1 link add name dummy1 type dummy
ip -n testns1 link set dev dummy1 up
devlink -N testns1 resource set $DEVLINK_DEV path IPv4/fib size 100
devlink -N testns1 dev reload $DEVLINK_DEV
for lsb in $(seq 1 20); do
ip -n testns1 route add 192.0.2.${lsb}/32 dev dummy1
done
devlink -N testns1 resource set $DEVLINK_DEV path IPv4/fib size 10
devlink -N testns1 dev reload $DEVLINK_DEV &> /dev/null
log_test "IPv4 error path - replay"
ip -n testns1 link del dev dummy1
# Successfully reload after deleting all the routes.
devlink -N testns1 resource set $DEVLINK_DEV path IPv4/fib size 100
devlink -N testns1 dev reload $DEVLINK_DEV
}
ipv4_error_path()
{
# Test the different error paths of the notifiers by limiting the size
# of the "IPv4/fib" resource.
ipv4_error_path_add
ipv4_error_path_replay
}
ipv4_delete_fail()
{
RET=0
echo "y" > $DEBUGFS_DIR/fib/fail_route_delete
ip -n testns1 link add name dummy1 type dummy
ip -n testns1 link set dev dummy1 up
ip -n testns1 route add 192.0.2.0/24 dev dummy1
ip -n testns1 route del 192.0.2.0/24 dev dummy1 &> /dev/null
# We should not be able to delete the netdev if we are leaking a
# reference.
ip -n testns1 link del dev dummy1
log_test "IPv4 route delete failure"
echo "n" > $DEBUGFS_DIR/fib/fail_route_delete
}
ipv6_add()
{
fib_ipv6_add_test "testns1"
}
ipv6_metric()
{
fib_ipv6_metric_test "testns1"
}
ipv6_append_single()
{
fib_ipv6_append_single_test "testns1"
}
ipv6_replace_single()
{
fib_ipv6_replace_single_test "testns1"
}
ipv6_metric_multipath()
{
fib_ipv6_metric_multipath_test "testns1"
}
ipv6_append_multipath()
{
fib_ipv6_append_multipath_test "testns1"
}
ipv6_replace_multipath()
{
fib_ipv6_replace_multipath_test "testns1"
}
ipv6_append_multipath_to_single()
{
fib_ipv6_append_multipath_to_single_test "testns1"
}
ipv6_delete_single()
{
fib_ipv6_delete_single_test "testns1"
}
ipv6_delete_multipath()
{
fib_ipv6_delete_multipath_test "testns1"
}
ipv6_replay_single()
{
fib_ipv6_replay_single_test "testns1" "$DEVLINK_DEV"
}
ipv6_replay_multipath()
{
fib_ipv6_replay_multipath_test "testns1" "$DEVLINK_DEV"
}
ipv6_error_path_add_single()
{
local lsb
RET=0
ip -n testns1 link add name dummy1 type dummy
ip -n testns1 link set dev dummy1 up
devlink -N testns1 resource set $DEVLINK_DEV path IPv6/fib size 10
devlink -N testns1 dev reload $DEVLINK_DEV
for lsb in $(seq 1 20); do
ip -n testns1 route add 2001:db8:1::${lsb}/128 dev dummy1 \
&> /dev/null
done
log_test "IPv6 error path - add single"
ip -n testns1 link del dev dummy1
}
ipv6_error_path_add_multipath()
{
local lsb
RET=0
for i in $(seq 1 2); do
ip -n testns1 link add name dummy$i type dummy
ip -n testns1 link set dev dummy$i up
ip -n testns1 address add 2001:db8:$i::1/64 dev dummy$i
done
devlink -N testns1 resource set $DEVLINK_DEV path IPv6/fib size 10
devlink -N testns1 dev reload $DEVLINK_DEV
for lsb in $(seq 1 20); do
ip -n testns1 route add 2001:db8:10::${lsb}/128 \
nexthop via 2001:db8:1::2 dev dummy1 \
nexthop via 2001:db8:2::2 dev dummy2 &> /dev/null
done
log_test "IPv6 error path - add multipath"
for i in $(seq 1 2); do
ip -n testns1 link del dev dummy$i
done
}
ipv6_error_path_replay()
{
local lsb
RET=0
ip -n testns1 link add name dummy1 type dummy
ip -n testns1 link set dev dummy1 up
devlink -N testns1 resource set $DEVLINK_DEV path IPv6/fib size 100
devlink -N testns1 dev reload $DEVLINK_DEV
for lsb in $(seq 1 20); do
ip -n testns1 route add 2001:db8:1::${lsb}/128 dev dummy1
done
devlink -N testns1 resource set $DEVLINK_DEV path IPv6/fib size 10
devlink -N testns1 dev reload $DEVLINK_DEV &> /dev/null
log_test "IPv6 error path - replay"
ip -n testns1 link del dev dummy1
# Successfully reload after deleting all the routes.
devlink -N testns1 resource set $DEVLINK_DEV path IPv6/fib size 100
devlink -N testns1 dev reload $DEVLINK_DEV
}
ipv6_error_path()
{
# Test the different error paths of the notifiers by limiting the size
# of the "IPv6/fib" resource.
ipv6_error_path_add_single
ipv6_error_path_add_multipath
ipv6_error_path_replay
}
ipv6_delete_fail()
{
RET=0
echo "y" > $DEBUGFS_DIR/fib/fail_route_delete
ip -n testns1 link add name dummy1 type dummy
ip -n testns1 link set dev dummy1 up
ip -n testns1 route add 2001:db8:1::/64 dev dummy1
ip -n testns1 route del 2001:db8:1::/64 dev dummy1 &> /dev/null
# We should not be able to delete the netdev if we are leaking a
# reference.
ip -n testns1 link del dev dummy1
log_test "IPv6 route delete failure"
echo "n" > $DEBUGFS_DIR/fib/fail_route_delete
}
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
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
}
cleanup()
{
pre_cleanup
ip netns del testns1
echo "$DEV_ADDR" > ${NETDEVSIM_PATH}/del_device
modprobe -r netdevsim &> /dev/null
}
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
@@ -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_process %%
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_process %%
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_process %%
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
@@ -0,0 +1,421 @@
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0
lib_dir=$(dirname $0)/../../../net/forwarding
ALL_TESTS="
l3_reporting_test
l3_fail_next_test
l3_counter_test
l3_rollback_test
l3_monitor_test
"
NETDEVSIM_PATH=/sys/bus/netdevsim/
DEV_ADDR_1=1337
DEV_ADDR_2=1057
DEV_ADDR_3=5417
NUM_NETIFS=0
source $lib_dir/lib.sh
DUMMY_IFINDEX=
DEV_ADDR()
{
local n=$1; shift
local var=DEV_ADDR_$n
echo ${!var}
}
DEV()
{
echo netdevsim$(DEV_ADDR $1)
}
DEVLINK_DEV()
{
echo netdevsim/$(DEV $1)
}
SYSFS_NET_DIR()
{
echo /sys/bus/netdevsim/devices/$(DEV $1)/net/
}
DEBUGFS_DIR()
{
echo /sys/kernel/debug/netdevsim/$(DEV $1)/
}
nsim_add()
{
local n=$1; shift
echo "$(DEV_ADDR $n) 1" > ${NETDEVSIM_PATH}/new_device
while [ ! -d $(SYSFS_NET_DIR $n) ] ; do :; done
}
nsim_reload()
{
local n=$1; shift
local ns=$1; shift
devlink dev reload $(DEVLINK_DEV $n) netns $ns
if [ $? -ne 0 ]; then
echo "Failed to reload $(DEV $n) into netns \"testns1\""
exit 1
fi
}
nsim_del()
{
local n=$1; shift
echo "$(DEV_ADDR $n)" > ${NETDEVSIM_PATH}/del_device
}
nsim_hwstats_toggle()
{
local action=$1; shift
local instance=$1; shift
local netdev=$1; shift
local type=$1; shift
local ifindex=$($IP -j link show dev $netdev | jq '.[].ifindex')
echo $ifindex > $(DEBUGFS_DIR $instance)/hwstats/$type/$action
}
nsim_hwstats_enable()
{
nsim_hwstats_toggle enable_ifindex "$@"
}
nsim_hwstats_disable()
{
nsim_hwstats_toggle disable_ifindex "$@"
}
nsim_hwstats_fail_next_enable()
{
nsim_hwstats_toggle fail_next_enable "$@"
}
setup_prepare()
{
modprobe netdevsim &> /dev/null
nsim_add 1
nsim_add 2
nsim_add 3
ip netns add testns1
if [ $? -ne 0 ]; then
echo "Failed to add netns \"testns1\""
exit 1
fi
nsim_reload 1 testns1
nsim_reload 2 testns1
nsim_reload 3 testns1
IP="ip -n testns1"
$IP link add name dummy1 type dummy
$IP link set dev dummy1 up
DUMMY_IFINDEX=$($IP -j link show dev dummy1 | jq '.[].ifindex')
}
cleanup()
{
pre_cleanup
$IP link del name dummy1
ip netns del testns1
nsim_del 3
nsim_del 2
nsim_del 1
modprobe -r netdevsim &> /dev/null
}
netdev_hwstats_used()
{
local netdev=$1; shift
local type=$1; shift
$IP -j stats show dev "$netdev" group offload subgroup hw_stats_info |
jq '.[].info.l3_stats.used'
}
netdev_check_used()
{
local netdev=$1; shift
local type=$1; shift
[[ $(netdev_hwstats_used $netdev $type) == "true" ]]
}
netdev_check_unused()
{
local netdev=$1; shift
local type=$1; shift
[[ $(netdev_hwstats_used $netdev $type) == "false" ]]
}
netdev_hwstats_request()
{
local netdev=$1; shift
local type=$1; shift
$IP -j stats show dev "$netdev" group offload subgroup hw_stats_info |
jq ".[].info.${type}_stats.request"
}
netdev_check_requested()
{
local netdev=$1; shift
local type=$1; shift
[[ $(netdev_hwstats_request $netdev $type) == "true" ]]
}
netdev_check_unrequested()
{
local netdev=$1; shift
local type=$1; shift
[[ $(netdev_hwstats_request $netdev $type) == "false" ]]
}
reporting_test()
{
local type=$1; shift
local instance=1
RET=0
[[ -n $(netdev_hwstats_used dummy1 $type) ]]
check_err $? "$type stats not reported"
netdev_check_unused dummy1 $type
check_err $? "$type stats reported as used before either device or netdevsim request"
nsim_hwstats_enable $instance dummy1 $type
netdev_check_unused dummy1 $type
check_err $? "$type stats reported as used before device request"
netdev_check_unrequested dummy1 $type
check_err $? "$type stats reported as requested before device request"
$IP stats set dev dummy1 ${type}_stats on
netdev_check_used dummy1 $type
check_err $? "$type stats reported as not used after both device and netdevsim request"
netdev_check_requested dummy1 $type
check_err $? "$type stats reported as not requested after device request"
nsim_hwstats_disable $instance dummy1 $type
netdev_check_unused dummy1 $type
check_err $? "$type stats reported as used after netdevsim request withdrawn"
nsim_hwstats_enable $instance dummy1 $type
netdev_check_used dummy1 $type
check_err $? "$type stats reported as not used after netdevsim request reenabled"
$IP stats set dev dummy1 ${type}_stats off
netdev_check_unused dummy1 $type
check_err $? "$type stats reported as used after device request withdrawn"
netdev_check_unrequested dummy1 $type
check_err $? "$type stats reported as requested after device request withdrawn"
nsim_hwstats_disable $instance dummy1 $type
netdev_check_unused dummy1 $type
check_err $? "$type stats reported as used after both requests withdrawn"
log_test "Reporting of $type stats usage"
}
l3_reporting_test()
{
reporting_test l3
}
__fail_next_test()
{
local instance=$1; shift
local type=$1; shift
RET=0
netdev_check_unused dummy1 $type
check_err $? "$type stats reported as used before either device or netdevsim request"
nsim_hwstats_enable $instance dummy1 $type
nsim_hwstats_fail_next_enable $instance dummy1 $type
netdev_check_unused dummy1 $type
check_err $? "$type stats reported as used before device request"
netdev_check_unrequested dummy1 $type
check_err $? "$type stats reported as requested before device request"
$IP stats set dev dummy1 ${type}_stats on 2>/dev/null
check_fail $? "$type stats request not bounced as it should have been"
netdev_check_unused dummy1 $type
check_err $? "$type stats reported as used after bounce"
netdev_check_unrequested dummy1 $type
check_err $? "$type stats reported as requested after bounce"
$IP stats set dev dummy1 ${type}_stats on
check_err $? "$type stats request failed when it shouldn't have"
netdev_check_used dummy1 $type
check_err $? "$type stats reported as not used after both device and netdevsim request"
netdev_check_requested dummy1 $type
check_err $? "$type stats reported as not requested after device request"
$IP stats set dev dummy1 ${type}_stats off
nsim_hwstats_disable $instance dummy1 $type
log_test "Injected failure of $type stats enablement (netdevsim #$instance)"
}
fail_next_test()
{
__fail_next_test 1 "$@"
__fail_next_test 2 "$@"
__fail_next_test 3 "$@"
}
l3_fail_next_test()
{
fail_next_test l3
}
get_hwstat()
{
local netdev=$1; shift
local type=$1; shift
local selector=$1; shift
$IP -j stats show dev $netdev group offload subgroup ${type}_stats |
jq ".[0].stats64.${selector}"
}
counter_test()
{
local type=$1; shift
local instance=1
RET=0
nsim_hwstats_enable $instance dummy1 $type
$IP stats set dev dummy1 ${type}_stats on
netdev_check_used dummy1 $type
check_err $? "$type stats reported as not used after both device and netdevsim request"
# Netdevsim counts 10pps on ingress. We should see maybe a couple
# packets, unless things take a reeealy long time.
local pkts=$(get_hwstat dummy1 l3 rx.packets)
((pkts < 10))
check_err $? "$type stats show >= 10 packets after first enablement"
sleep 2.5
local pkts=$(get_hwstat dummy1 l3 rx.packets)
((pkts >= 20))
check_err $? "$type stats show < 20 packets after 2.5s passed"
$IP stats set dev dummy1 ${type}_stats off
sleep 2
$IP stats set dev dummy1 ${type}_stats on
local pkts=$(get_hwstat dummy1 l3 rx.packets)
((pkts < 10))
check_err $? "$type stats show >= 10 packets after second enablement"
$IP stats set dev dummy1 ${type}_stats off
nsim_hwstats_fail_next_enable $instance dummy1 $type
$IP stats set dev dummy1 ${type}_stats on 2>/dev/null
check_fail $? "$type stats request not bounced as it should have been"
sleep 2
$IP stats set dev dummy1 ${type}_stats on
local pkts=$(get_hwstat dummy1 l3 rx.packets)
((pkts < 10))
check_err $? "$type stats show >= 10 packets after post-fail enablement"
$IP stats set dev dummy1 ${type}_stats off
log_test "Counter values in $type stats"
}
l3_counter_test()
{
counter_test l3
}
rollback_test()
{
local type=$1; shift
RET=0
nsim_hwstats_enable 1 dummy1 l3
nsim_hwstats_enable 2 dummy1 l3
nsim_hwstats_enable 3 dummy1 l3
# The three netdevsim instances are registered in order of their number
# one after another. It is reasonable to expect that whatever
# notifications take place hit no. 2 in between hitting nos. 1 and 3,
# whatever the actual order. This allows us to test that a fail caused
# by no. 2 does not leave the system in a partial state, and rolls
# everything back.
nsim_hwstats_fail_next_enable 2 dummy1 l3
$IP stats set dev dummy1 ${type}_stats on 2>/dev/null
check_fail $? "$type stats request not bounced as it should have been"
netdev_check_unused dummy1 $type
check_err $? "$type stats reported as used after bounce"
netdev_check_unrequested dummy1 $type
check_err $? "$type stats reported as requested after bounce"
sleep 2
$IP stats set dev dummy1 ${type}_stats on
check_err $? "$type stats request not upheld as it should have been"
local pkts=$(get_hwstat dummy1 l3 rx.packets)
((pkts < 10))
check_err $? "$type stats show $pkts packets after post-fail enablement"
$IP stats set dev dummy1 ${type}_stats off
nsim_hwstats_disable 3 dummy1 l3
nsim_hwstats_disable 2 dummy1 l3
nsim_hwstats_disable 1 dummy1 l3
log_test "Failure in $type stats enablement rolled back"
}
l3_rollback_test()
{
rollback_test l3
}
l3_monitor_test()
{
hw_stats_monitor_test dummy1 l3 \
"nsim_hwstats_enable 1 dummy1 l3" \
"nsim_hwstats_disable 1 dummy1 l3" \
"$IP"
}
trap cleanup EXIT
setup_prepare
tests_run
exit $EXIT_STATUS
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,203 @@
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0-only
lib_dir=$(dirname $0)/../../../net
source $lib_dir/lib.sh
NSIM_DEV_1_ID=$((256 + RANDOM % 256))
NSIM_DEV_1_SYS=/sys/bus/netdevsim/devices/netdevsim$NSIM_DEV_1_ID
NSIM_DEV_2_ID=$((512 + RANDOM % 256))
NSIM_DEV_2_SYS=/sys/bus/netdevsim/devices/netdevsim$NSIM_DEV_2_ID
NSIM_DEV_SYS_NEW=/sys/bus/netdevsim/new_device
NSIM_DEV_SYS_DEL=/sys/bus/netdevsim/del_device
NSIM_DEV_SYS_LINK=/sys/bus/netdevsim/link_device
NSIM_DEV_SYS_UNLINK=/sys/bus/netdevsim/unlink_device
socat_check()
{
if [ ! -x "$(command -v socat)" ]; then
echo "socat command not found. Skipping test"
return 1
fi
return 0
}
setup_ns()
{
set -e
ip netns add nssv
ip netns add nscl
NSIM_DEV_1_NAME=$(find $NSIM_DEV_1_SYS/net -maxdepth 1 -type d ! \
-path $NSIM_DEV_1_SYS/net -exec basename {} \;)
NSIM_DEV_2_NAME=$(find $NSIM_DEV_2_SYS/net -maxdepth 1 -type d ! \
-path $NSIM_DEV_2_SYS/net -exec basename {} \;)
ip link set $NSIM_DEV_1_NAME netns nssv
ip link set $NSIM_DEV_2_NAME netns nscl
ip netns exec nssv ip addr add '192.168.1.1/24' dev $NSIM_DEV_1_NAME
ip netns exec nscl ip addr add '192.168.1.2/24' dev $NSIM_DEV_2_NAME
ip netns exec nssv ip link set dev $NSIM_DEV_1_NAME up
ip netns exec nscl ip link set dev $NSIM_DEV_2_NAME up
set +e
}
cleanup_ns()
{
ip netns del nscl
ip netns del nssv
}
is_carrier_up()
{
local netns="$1"
local nsim_dev="$2"
test "$(ip netns exec "$netns" \
cat /sys/class/net/"$nsim_dev"/carrier 2>/dev/null)" -eq 1
}
assert_carrier_up()
{
local netns="$1"
local nsim_dev="$2"
if ! is_carrier_up "$netns" "$nsim_dev"; then
echo "$nsim_dev's carrier should be UP, but it isn't"
cleanup_ns
exit 1
fi
}
assert_carrier_down()
{
local netns="$1"
local nsim_dev="$2"
if is_carrier_up "$netns" "$nsim_dev"; then
echo "$nsim_dev's carrier should be DOWN, but it isn't"
cleanup_ns
exit 1
fi
}
###
### Code start
###
socat_check || exit 4
modprobe netdevsim
# linking
echo $NSIM_DEV_1_ID > $NSIM_DEV_SYS_NEW
echo $NSIM_DEV_2_ID > $NSIM_DEV_SYS_NEW
udevadm settle
setup_ns
NSIM_DEV_1_FD=$((256 + RANDOM % 256))
exec {NSIM_DEV_1_FD}</var/run/netns/nssv
NSIM_DEV_1_IFIDX=$(ip netns exec nssv cat /sys/class/net/$NSIM_DEV_1_NAME/ifindex)
NSIM_DEV_2_FD=$((256 + RANDOM % 256))
exec {NSIM_DEV_2_FD}</var/run/netns/nscl
NSIM_DEV_2_IFIDX=$(ip netns exec nscl cat /sys/class/net/$NSIM_DEV_2_NAME/ifindex)
echo "$NSIM_DEV_1_FD:$NSIM_DEV_1_IFIDX $NSIM_DEV_2_FD:2000" > $NSIM_DEV_SYS_LINK 2>/dev/null
if [ $? -eq 0 ]; then
echo "linking with non-existent netdevsim should fail"
cleanup_ns
exit 1
fi
echo "$NSIM_DEV_1_FD:$NSIM_DEV_1_IFIDX 2000:$NSIM_DEV_2_IFIDX" > $NSIM_DEV_SYS_LINK 2>/dev/null
if [ $? -eq 0 ]; then
echo "linking with non-existent netnsid should fail"
cleanup_ns
exit 1
fi
echo "$NSIM_DEV_1_FD:$NSIM_DEV_1_IFIDX $NSIM_DEV_1_FD:$NSIM_DEV_1_IFIDX" > $NSIM_DEV_SYS_LINK 2>/dev/null
if [ $? -eq 0 ]; then
echo "linking with self should fail"
cleanup_ns
exit 1
fi
echo "$NSIM_DEV_1_FD:$NSIM_DEV_1_IFIDX $NSIM_DEV_2_FD:$NSIM_DEV_2_IFIDX" > $NSIM_DEV_SYS_LINK
if [ $? -ne 0 ]; then
echo "linking netdevsim1 with netdevsim2 should succeed"
cleanup_ns
exit 1
fi
# argument error checking
echo "$NSIM_DEV_1_FD:$NSIM_DEV_1_IFIDX $NSIM_DEV_2_FD:a" > $NSIM_DEV_SYS_LINK 2>/dev/null
if [ $? -eq 0 ]; then
echo "invalid arg should fail"
cleanup_ns
exit 1
fi
# netdevsim carrier state consistency checking
assert_carrier_up nssv "$NSIM_DEV_1_NAME"
assert_carrier_up nscl "$NSIM_DEV_2_NAME"
echo "$NSIM_DEV_1_FD:$NSIM_DEV_1_IFIDX" > "$NSIM_DEV_SYS_UNLINK"
assert_carrier_down nssv "$NSIM_DEV_1_NAME"
assert_carrier_down nscl "$NSIM_DEV_2_NAME"
ip netns exec nssv ip link set dev "$NSIM_DEV_1_NAME" down
ip netns exec nssv ip link set dev "$NSIM_DEV_1_NAME" up
assert_carrier_down nssv "$NSIM_DEV_1_NAME"
assert_carrier_down nscl "$NSIM_DEV_2_NAME"
echo "$NSIM_DEV_1_FD:$NSIM_DEV_1_IFIDX $NSIM_DEV_2_FD:$NSIM_DEV_2_IFIDX" > $NSIM_DEV_SYS_LINK
assert_carrier_up nssv "$NSIM_DEV_1_NAME"
assert_carrier_up nscl "$NSIM_DEV_2_NAME"
ip netns exec nssv ip link set dev "$NSIM_DEV_1_NAME" down
ip netns exec nssv ip link set dev "$NSIM_DEV_1_NAME" up
assert_carrier_up nssv "$NSIM_DEV_1_NAME"
assert_carrier_up nscl "$NSIM_DEV_2_NAME"
# send/recv packets
tmp_file=$(mktemp)
ip netns exec nssv socat TCP-LISTEN:1234,fork $tmp_file &
pid=$!
res=0
wait_local_port_listen nssv 1234 tcp
echo "HI" | ip netns exec nscl socat STDIN TCP:192.168.1.1:1234
count=$(cat $tmp_file | wc -c)
if [[ $count -ne 3 ]]; then
echo "expected 3 bytes, got $count"
res=1
fi
echo "$NSIM_DEV_1_FD:$NSIM_DEV_1_IFIDX" > $NSIM_DEV_SYS_UNLINK
echo $NSIM_DEV_2_ID > $NSIM_DEV_SYS_DEL
kill $pid
echo $NSIM_DEV_1_ID > $NSIM_DEV_SYS_DEL
cleanup_ns
modprobe -r netdevsim
exit $res
@@ -0,0 +1,183 @@
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0
#
# This test is for checking the psample module. It makes use of netdevsim
# which periodically generates "sampled" packets.
lib_dir=$(dirname $0)/../../../net/forwarding
ALL_TESTS="
psample_enable_test
psample_group_num_test
psample_md_test
"
NETDEVSIM_PATH=/sys/bus/netdevsim/
DEV_ADDR=1337
DEV=netdevsim${DEV_ADDR}
SYSFS_NET_DIR=/sys/bus/netdevsim/devices/$DEV/net/
PSAMPLE_DIR=/sys/kernel/debug/netdevsim/$DEV/psample/
CAPTURE_FILE=$(mktemp)
NUM_NETIFS=0
source $lib_dir/lib.sh
DEVLINK_DEV=
source $lib_dir/devlink_lib.sh
DEVLINK_DEV=netdevsim/${DEV}
# Available at https://github.com/Mellanox/libpsample
require_command psample
psample_capture()
{
rm -f $CAPTURE_FILE
timeout 2 ip netns exec testns1 psample &> $CAPTURE_FILE
}
psample_enable_test()
{
RET=0
echo 1 > $PSAMPLE_DIR/enable
check_err $? "Failed to enable sampling when should not"
echo 1 > $PSAMPLE_DIR/enable 2>/dev/null
check_fail $? "Sampling enablement succeeded when should fail"
psample_capture
if [ $(cat $CAPTURE_FILE | wc -l) -eq 0 ]; then
check_err 1 "Failed to capture sampled packets"
fi
echo 0 > $PSAMPLE_DIR/enable
check_err $? "Failed to disable sampling when should not"
echo 0 > $PSAMPLE_DIR/enable 2>/dev/null
check_fail $? "Sampling disablement succeeded when should fail"
psample_capture
if [ $(cat $CAPTURE_FILE | wc -l) -ne 0 ]; then
check_err 1 "Captured sampled packets when should not"
fi
log_test "psample enable / disable"
}
psample_group_num_test()
{
RET=0
echo 1234 > $PSAMPLE_DIR/group_num
echo 1 > $PSAMPLE_DIR/enable
psample_capture
grep -q -e "group 1234" $CAPTURE_FILE
check_err $? "Sampled packets reported with wrong group number"
# New group number should only be used after disable / enable.
echo 4321 > $PSAMPLE_DIR/group_num
psample_capture
grep -q -e "group 4321" $CAPTURE_FILE
check_fail $? "Group number changed while sampling is active"
echo 0 > $PSAMPLE_DIR/enable && echo 1 > $PSAMPLE_DIR/enable
psample_capture
grep -q -e "group 4321" $CAPTURE_FILE
check_err $? "Group number did not change after restarting sampling"
log_test "psample group number"
echo 0 > $PSAMPLE_DIR/enable
}
psample_md_test()
{
RET=0
echo 1 > $PSAMPLE_DIR/enable
echo 1234 > $PSAMPLE_DIR/in_ifindex
echo 4321 > $PSAMPLE_DIR/out_ifindex
psample_capture
grep -q -e "in-ifindex 1234" $CAPTURE_FILE
check_err $? "Sampled packets reported with wrong in-ifindex"
grep -q -e "out-ifindex 4321" $CAPTURE_FILE
check_err $? "Sampled packets reported with wrong out-ifindex"
echo 5 > $PSAMPLE_DIR/out_tc
psample_capture
grep -q -e "out-tc 5" $CAPTURE_FILE
check_err $? "Sampled packets reported with wrong out-tc"
echo $((2**16 - 1)) > $PSAMPLE_DIR/out_tc
psample_capture
grep -q -e "out-tc " $CAPTURE_FILE
check_fail $? "Sampled packets reported with out-tc when should not"
echo 1 > $PSAMPLE_DIR/out_tc
echo 10000 > $PSAMPLE_DIR/out_tc_occ_max
psample_capture
grep -q -e "out-tc-occ " $CAPTURE_FILE
check_err $? "Sampled packets not reported with out-tc-occ when should"
echo 0 > $PSAMPLE_DIR/out_tc_occ_max
psample_capture
grep -q -e "out-tc-occ " $CAPTURE_FILE
check_fail $? "Sampled packets reported with out-tc-occ when should not"
echo 10000 > $PSAMPLE_DIR/latency_max
psample_capture
grep -q -e "latency " $CAPTURE_FILE
check_err $? "Sampled packets not reported with latency when should"
echo 0 > $PSAMPLE_DIR/latency_max
psample_capture
grep -q -e "latency " $CAPTURE_FILE
check_fail $? "Sampled packets reported with latency when should not"
log_test "psample metadata"
echo 0 > $PSAMPLE_DIR/enable
}
setup_prepare()
{
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
set +e
}
cleanup()
{
pre_cleanup
rm -f $CAPTURE_FILE
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
@@ -0,0 +1 @@
timeout=600
@@ -0,0 +1,80 @@
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0-only
source ethtool-common.sh
set -o pipefail
n_children() {
n=$(tc qdisc show dev $NDEV | grep '^qdisc' | wc -l)
echo $((n - 1))
}
tcq() {
tc qdisc $1 dev $NDEV ${@:2}
}
n_child_assert() {
n=$(n_children)
if [ $n -ne $1 ]; then
echo "ERROR ($root): ${@:2}, expected $1 have $n"
((num_errors++))
else
((num_passes++))
fi
}
for root in mq mqprio; do
NDEV=$(make_netdev 1 4)
opts=
[ $root == "mqprio" ] && opts='hw 0 num_tc 1 map 0 0 0 0 queues 1@0'
tcq add root handle 100: $root $opts
n_child_assert 4 'Init'
# All defaults
for n in 3 2 1 2 3 4 1 4; do
ethtool -L $NDEV combined $n
n_child_assert $n "Change queues to $n while down"
done
ip link set dev $NDEV up
for n in 3 2 1 2 3 4 1 4; do
ethtool -L $NDEV combined $n
n_child_assert $n "Change queues to $n while up"
done
# One real one
tcq replace parent 100:4 handle 204: pfifo_fast
n_child_assert 4 "One real queue"
ethtool -L $NDEV combined 1
n_child_assert 2 "One real queue, one default"
ethtool -L $NDEV combined 4
n_child_assert 4 "One real queue, rest default"
# Remove real one
tcq del parent 100:4 handle 204:
# Replace default with pfifo
tcq replace parent 100:1 handle 205: pfifo limit 1000
n_child_assert 3 "Deleting real one, replacing default one with pfifo"
ethtool -L $NDEV combined 1
n_child_assert 1 "Grafted, one"
cleanup_nsim
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
@@ -0,0 +1,942 @@
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0-only
VNI_GEN=$RANDOM
NSIM_ID=$((RANDOM % 1024))
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
clean_up_devs=( )
function err_cnt {
echo "ERROR:" $@
EXIT_STATUS=1
((num_errors++))
((num_cases++))
}
function pass_cnt {
((num_cases++))
}
function cleanup_tuns {
for dev in "${clean_up_devs[@]}"; do
[ -e /sys/class/net/$dev ] && ip link del dev $dev
done
clean_up_devs=( )
}
function cleanup_nsim {
if [ -e $NSIM_DEV_SYS ]; then
echo $NSIM_ID > /sys/bus/netdevsim/del_device
fi
}
function cleanup {
cleanup_tuns
cleanup_nsim
}
trap cleanup EXIT
function new_vxlan {
local dev=$1
local dstport=$2
local lower=$3
local ipver=$4
local flags=$5
local group ipfl
[ "$ipver" != '6' ] && group=239.1.1.1 || group=fff1::1
[ "$ipver" != '6' ] || ipfl="-6"
[[ ! "$flags" =~ "external" ]] && flags="$flags id $((VNI_GEN++))"
ip $ipfl link add $dev type vxlan \
group $group \
dev $lower \
dstport $dstport \
$flags
ip link set dev $dev up
clean_up_devs=("${clean_up_devs[@]}" $dev)
check_tables
}
function new_geneve {
local dev=$1
local dstport=$2
local ipver=$3
local flags=$4
local group ipfl
[ "$ipver" != '6' ] && remote=1.1.1.2 || group=::2
[ "$ipver" != '6' ] || ipfl="-6"
[[ ! "$flags" =~ "external" ]] && flags="$flags vni $((VNI_GEN++))"
ip $ipfl link add $dev type geneve \
remote $remote \
dstport $dstport \
$flags
ip link set dev $dev up
clean_up_devs=("${clean_up_devs[@]}" $dev)
check_tables
}
function del_dev {
local dev=$1
ip link del dev $dev
check_tables
}
# Helpers for netdevsim port/type encoding
function mke {
local port=$1
local type=$2
echo $((port << 16 | type))
}
function pre {
local val=$1
echo -e "port: $((val >> 16))\ttype: $((val & 0xffff))"
}
function pre_ethtool {
local val=$1
local port=$((val >> 16))
local type=$((val & 0xffff))
case $type in
1)
type_name="vxlan"
;;
2)
type_name="geneve"
;;
4)
type_name="vxlan-gpe"
;;
*)
type_name="bit X"
;;
esac
echo "port $port, $type_name"
}
function check_table {
local path=$NSIM_DEV_DFS/ports/$port/udp_ports/table$1
local -n expected=$2
local last=$3
read -a have < $path
if [ ${#expected[@]} -ne ${#have[@]} ]; then
echo "check_table: BAD NUMBER OF ITEMS"
return 0
fi
for i in "${!expected[@]}"; do
if [ -n "$HAS_ETHTOOL" -a ${expected[i]} -ne 0 ]; then
pp_expected=`pre_ethtool ${expected[i]}`
ethtool --show-tunnels $NSIM_NETDEV | grep "$pp_expected" >/dev/null
if [ $? -ne 0 -a $last -ne 0 ]; then
err_cnt "ethtool table $1 on port $port: $pfx - $msg"
echo " check_table: ethtool does not contain '$pp_expected'"
ethtool --show-tunnels $NSIM_NETDEV
return 0
fi
fi
if [ ${expected[i]} != ${have[i]} ]; then
if [ $last -ne 0 ]; then
err_cnt "table $1 on port $port: $pfx - $msg"
echo " check_table: wrong entry $i"
echo " expected: `pre ${expected[i]}`"
echo " have: `pre ${have[i]}`"
return 0
fi
return 1
fi
done
pass_cnt
return 0
}
function check_tables {
# Need retries in case we have workqueue making the changes
local retries=10
while ! check_table 0 exp0 $((retries == 0)); do
sleep 0.02
((retries--))
done
while ! check_table 1 exp1 $((retries == 0)); do
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 {
local path=$NSIM_DEV_DFS/ports/$port/udp_ports/table$1
read -a have < $path
tree $NSIM_DEV_DFS/
echo "Port $port table $1:"
for i in "${!have[@]}"; do
echo " `pre ${have[i]}`"
done
}
function print_tables {
print_table 0
print_table 1
}
function get_netdev_name {
local -n old=$1
udevadm settle
new=$(ls /sys/class/net)
for netdev in $new; do
for check in $old; do
[ $netdev == $check ] && break
done
if [ $netdev != $check ]; then
echo $netdev
break
fi
done
}
###
### Code start
###
# Probe ethtool support
ethtool -h | grep show-tunnels 2>&1 >/dev/null && HAS_ETHTOOL=y
modprobe netdevsim
# Basic test
pfx="basic"
for port in 0 1; do
old_netdevs=$(ls /sys/class/net)
if [ $port -eq 0 ]; then
echo $NSIM_ID > /sys/bus/netdevsim/new_device
else
echo 1 > $NSIM_DEV_DFS/udp_ports_open_only
echo 1 > $NSIM_DEV_SYS/new_port
fi
NSIM_NETDEV=`get_netdev_name old_netdevs`
ip link set dev $NSIM_NETDEV up
msg="new NIC device created"
exp0=( 0 0 0 0 )
exp1=( 0 0 0 0 )
check_tables
msg="VxLAN v4 devices"
exp0=( `mke 4789 1` 0 0 0 )
new_vxlan vxlan0 4789 $NSIM_NETDEV
new_vxlan vxlan1 4789 $NSIM_NETDEV
msg="VxLAN v4 devices go down"
exp0=( 0 0 0 0 )
ip link set dev vxlan1 down
ip link set dev vxlan0 down
check_tables
msg="VxLAN v6 devices"
exp0=( `mke 4789 1` 0 0 0 )
new_vxlan vxlanA 4789 $NSIM_NETDEV 6
for ifc in vxlan0 vxlan1; do
ip link set dev $ifc up
done
new_vxlan vxlanB 4789 $NSIM_NETDEV 6
msg="another VxLAN v6 devices"
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"
ip link set dev $NSIM_NETDEV down
if [ $port -eq 1 ]; then
exp0=( 0 0 0 0 )
exp1=( 0 0 0 0 )
fi
check_tables
msg="NIC device goes up again"
ip link set dev $NSIM_NETDEV up
exp0=( `mke 4789 1` `mke 4790 1` 0 0 )
exp1=( `mke 6081 2` 0 0 0 )
check_tables
cleanup_tuns
msg="tunnels destroyed"
exp0=( 0 0 0 0 )
exp1=( 0 0 0 0 )
check_tables
modprobe -r geneve
modprobe -r vxlan
modprobe -r udp_tunnel
check_tables
done
modprobe -r netdevsim
# Module tests
pfx="module tests"
if modinfo netdevsim | grep udp_tunnel >/dev/null; then
err_cnt "netdevsim depends on udp_tunnel"
else
pass_cnt
fi
modprobe netdevsim
old_netdevs=$(ls /sys/class/net)
port=0
echo $NSIM_ID > /sys/bus/netdevsim/new_device
echo 0 > $NSIM_DEV_SYS/del_port
echo 0 > $NSIM_DEV_SYS/new_port
NSIM_NETDEV=`get_netdev_name old_netdevs`
msg="create VxLANs"
exp0=( `mke 10000 1` 0 0 0 )
new_vxlan vxlan0 10000 $NSIM_NETDEV
exp0=( 0 0 0 0 )
modprobe -r netdevsim
modprobe netdevsim
# Overflow the table
function overflow_table0 {
local pfx=$1
msg="create VxLANs 1/5"
exp0=( `mke 10000 1` 0 0 0 )
new_vxlan vxlan0 10000 $NSIM_NETDEV
msg="create VxLANs 2/5"
exp0=( `mke 10000 1` `mke 10001 1` 0 0 )
new_vxlan vxlan1 10001 $NSIM_NETDEV
msg="create VxLANs 3/5"
exp0=( `mke 10000 1` `mke 10001 1` `mke 10002 1` 0 )
new_vxlan vxlan2 10002 $NSIM_NETDEV
msg="create VxLANs 4/5"
exp0=( `mke 10000 1` `mke 10001 1` `mke 10002 1` `mke 10003 1` )
new_vxlan vxlan3 10003 $NSIM_NETDEV
msg="create VxLANs 5/5"
new_vxlan vxlan4 10004 $NSIM_NETDEV
}
function overflow_table1 {
local pfx=$1
msg="create GENEVE 1/5"
exp1=( `mke 20000 2` 0 0 0 )
new_geneve gnv0 20000
msg="create GENEVE 2/5"
exp1=( `mke 20000 2` `mke 20001 2` 0 0 )
new_geneve gnv1 20001
msg="create GENEVE 3/5"
exp1=( `mke 20000 2` `mke 20001 2` `mke 20002 2` 0 )
new_geneve gnv2 20002
msg="create GENEVE 4/5"
exp1=( `mke 20000 2` `mke 20001 2` `mke 20002 2` `mke 20003 2` )
new_geneve gnv3 20003
msg="create GENEVE 5/5"
new_geneve gnv4 20004
}
echo $NSIM_ID > /sys/bus/netdevsim/new_device
echo 0 > $NSIM_DEV_SYS/del_port
for port in 0 1; do
if [ $port -ne 0 ]; then
echo 1 > $NSIM_DEV_DFS/udp_ports_open_only
fi
echo $port > $NSIM_DEV_SYS/new_port
NSIM_NETDEV=`get_netdev_name old_netdevs`
ip link set dev $NSIM_NETDEV up
overflow_table0 "overflow NIC table"
overflow_table1 "overflow NIC table"
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
msg="replace GENEVE in overflow table"
exp1=( `mke 20000 2` `mke 20004 2` `mke 20002 2` `mke 20003 2` )
del_dev gnv1
msg="vacate GENEVE in overflow table"
exp1=( `mke 20000 2` `mke 20004 2` 0 `mke 20003 2` )
del_dev gnv2
msg="table sharing - share"
exp1=( `mke 20000 2` `mke 20004 2` `mke 30001 4` `mke 20003 2` )
new_vxlan vxlanG0 30001 $NSIM_NETDEV 4 "gpe external"
msg="table sharing - overflow"
new_vxlan vxlanG1 30002 $NSIM_NETDEV 4 "gpe external"
msg="table sharing - overflow v6"
new_vxlan vxlanG2 30002 $NSIM_NETDEV 6 "gpe external"
exp1=( `mke 20000 2` `mke 30002 4` `mke 30001 4` `mke 20003 2` )
del_dev gnv4
msg="destroy NIC"
echo $port > $NSIM_DEV_SYS/del_port
cleanup_tuns
exp0=( 0 0 0 0 )
exp1=( 0 0 0 0 )
done
cleanup_nsim
# Sync all
pfx="sync all"
echo $NSIM_ID > /sys/bus/netdevsim/new_device
echo 0 > $NSIM_DEV_SYS/del_port
echo 1 > $NSIM_DEV_DFS/udp_ports_sync_all
for port in 0 1; do
if [ $port -ne 0 ]; then
echo 1 > $NSIM_DEV_DFS/udp_ports_open_only
fi
echo $port > $NSIM_DEV_SYS/new_port
NSIM_NETDEV=`get_netdev_name old_netdevs`
ip link set dev $NSIM_NETDEV up
overflow_table0 "overflow NIC table"
overflow_table1 "overflow NIC table"
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
msg="replace GENEVE in overflow table"
exp1=( `mke 20000 2` `mke 20004 2` `mke 20002 2` `mke 20003 2` )
del_dev gnv1
msg="vacate GENEVE in overflow table"
exp1=( `mke 20000 2` `mke 20004 2` 0 `mke 20003 2` )
del_dev gnv2
msg="table sharing - share"
exp1=( `mke 20000 2` `mke 20004 2` `mke 30001 4` `mke 20003 2` )
new_vxlan vxlanG0 30001 $NSIM_NETDEV 4 "gpe external"
msg="table sharing - overflow"
new_vxlan vxlanG1 30002 $NSIM_NETDEV 4 "gpe external"
msg="table sharing - overflow v6"
new_vxlan vxlanG2 30002 $NSIM_NETDEV 6 "gpe external"
exp1=( `mke 20000 2` `mke 30002 4` `mke 30001 4` `mke 20003 2` )
del_dev gnv4
msg="destroy NIC"
echo $port > $NSIM_DEV_SYS/del_port
cleanup_tuns
exp0=( 0 0 0 0 )
exp1=( 0 0 0 0 )
done
cleanup_nsim
# Destroy full NIC
pfx="destroy full"
echo $NSIM_ID > /sys/bus/netdevsim/new_device
echo 0 > $NSIM_DEV_SYS/del_port
for port in 0 1; do
if [ $port -ne 0 ]; then
echo 1 > $NSIM_DEV_DFS/udp_ports_open_only
fi
echo $port > $NSIM_DEV_SYS/new_port
NSIM_NETDEV=`get_netdev_name old_netdevs`
ip link set dev $NSIM_NETDEV up
overflow_table0 "destroy NIC"
overflow_table1 "destroy NIC"
msg="destroy NIC"
echo $port > $NSIM_DEV_SYS/del_port
cleanup_tuns
exp0=( 0 0 0 0 )
exp1=( 0 0 0 0 )
done
cleanup_nsim
# IPv4 only
pfx="IPv4 only"
echo $NSIM_ID > /sys/bus/netdevsim/new_device
echo 0 > $NSIM_DEV_SYS/del_port
echo 1 > $NSIM_DEV_DFS/udp_ports_ipv4_only
for port in 0 1; do
if [ $port -ne 0 ]; then
echo 1 > $NSIM_DEV_DFS/udp_ports_open_only
fi
echo $port > $NSIM_DEV_SYS/new_port
NSIM_NETDEV=`get_netdev_name old_netdevs`
ip link set dev $NSIM_NETDEV up
msg="create VxLANs v6"
new_vxlan vxlanA0 10000 $NSIM_NETDEV 6
msg="create VxLANs v6"
new_vxlan vxlanA1 10000 $NSIM_NETDEV 6
ip link set dev vxlanA0 down
ip link set dev vxlanA0 up
check_tables
msg="create VxLANs v4"
exp0=( `mke 10000 1` 0 0 0 )
new_vxlan vxlan0 10000 $NSIM_NETDEV
msg="down VxLANs v4"
exp0=( 0 0 0 0 )
ip link set dev vxlan0 down
check_tables
msg="up VxLANs v4"
exp0=( `mke 10000 1` 0 0 0 )
ip link set dev vxlan0 up
check_tables
msg="destroy VxLANs v4"
exp0=( 0 0 0 0 )
del_dev vxlan0
msg="recreate VxLANs v4"
exp0=( `mke 10000 1` 0 0 0 )
new_vxlan vxlan0 10000 $NSIM_NETDEV
del_dev vxlanA0
del_dev vxlanA1
msg="destroy NIC"
echo $port > $NSIM_DEV_SYS/del_port
cleanup_tuns
exp0=( 0 0 0 0 )
exp1=( 0 0 0 0 )
done
cleanup_nsim
# Failures
pfx="error injection"
echo $NSIM_ID > /sys/bus/netdevsim/new_device
echo 0 > $NSIM_DEV_SYS/del_port
for port in 0 1; do
if [ $port -ne 0 ]; then
echo 1 > $NSIM_DEV_DFS/udp_ports_open_only
fi
echo $port > $NSIM_DEV_SYS/new_port
NSIM_NETDEV=`get_netdev_name old_netdevs`
ip link set dev $NSIM_NETDEV up
echo 110 > $NSIM_DEV_DFS/ports/$port/udp_ports/inject_error
msg="1 - create VxLANs v6"
exp0=( 0 0 0 0 )
new_vxlan vxlanA0 10000 $NSIM_NETDEV 6
msg="1 - create VxLANs v4"
exp0=( `mke 10000 1` 0 0 0 )
new_vxlan vxlan0 10000 $NSIM_NETDEV
msg="1 - remove VxLANs v4"
del_dev vxlan0
msg="1 - remove VxLANs v6"
exp0=( 0 0 0 0 )
del_dev vxlanA0
msg="2 - create GENEVE"
exp1=( `mke 20000 2` 0 0 0 )
new_geneve gnv0 20000
msg="2 - destroy GENEVE"
echo 2 > $NSIM_DEV_DFS/ports/$port/udp_ports/inject_error
exp1=( `mke 20000 2` 0 0 0 )
del_dev gnv0
msg="2 - create second GENEVE"
exp1=( 0 `mke 20001 2` 0 0 )
new_geneve gnv0 20001
msg="destroy NIC"
echo $port > $NSIM_DEV_SYS/del_port
cleanup_tuns
exp0=( 0 0 0 0 )
exp1=( 0 0 0 0 )
done
cleanup_nsim
# netdev flags
pfx="netdev flags"
echo $NSIM_ID > /sys/bus/netdevsim/new_device
echo 0 > $NSIM_DEV_SYS/del_port
for port in 0 1; do
if [ $port -ne 0 ]; then
echo 1 > $NSIM_DEV_DFS/udp_ports_open_only
fi
echo $port > $NSIM_DEV_SYS/new_port
NSIM_NETDEV=`get_netdev_name old_netdevs`
ip link set dev $NSIM_NETDEV up
msg="create VxLANs v6"
exp0=( `mke 10000 1` 0 0 0 )
new_vxlan vxlanA0 10000 $NSIM_NETDEV 6
msg="create VxLANs v4"
new_vxlan vxlan0 10000 $NSIM_NETDEV
msg="turn off"
exp0=( 0 0 0 0 )
ethtool -K $NSIM_NETDEV rx-udp_tunnel-port-offload off
check_tables
msg="turn on"
exp0=( `mke 10000 1` 0 0 0 )
ethtool -K $NSIM_NETDEV rx-udp_tunnel-port-offload on
check_tables
msg="remove both"
del_dev vxlanA0
exp0=( 0 0 0 0 )
del_dev vxlan0
check_tables
ethtool -K $NSIM_NETDEV rx-udp_tunnel-port-offload off
msg="create VxLANs v4 - off"
exp0=( 0 0 0 0 )
new_vxlan vxlan0 10000 $NSIM_NETDEV
msg="created off - turn on"
exp0=( `mke 10000 1` 0 0 0 )
ethtool -K $NSIM_NETDEV rx-udp_tunnel-port-offload on
check_tables
msg="destroy NIC"
echo $port > $NSIM_DEV_SYS/del_port
cleanup_tuns
exp0=( 0 0 0 0 )
exp1=( 0 0 0 0 )
done
cleanup_nsim
# device initiated reset
pfx="reset notification"
echo $NSIM_ID > /sys/bus/netdevsim/new_device
echo 0 > $NSIM_DEV_SYS/del_port
for port in 0 1; do
if [ $port -ne 0 ]; then
echo 1 > $NSIM_DEV_DFS/udp_ports_open_only
fi
echo $port > $NSIM_DEV_SYS/new_port
NSIM_NETDEV=`get_netdev_name old_netdevs`
ip link set dev $NSIM_NETDEV up
msg="create VxLANs v6"
exp0=( `mke 10000 1` 0 0 0 )
new_vxlan vxlanA0 10000 $NSIM_NETDEV 6
msg="create VxLANs v4"
new_vxlan vxlan0 10000 $NSIM_NETDEV
echo 1 > $NSIM_DEV_DFS/ports/$port/udp_ports/reset
check_tables
msg="NIC device goes down"
ip link set dev $NSIM_NETDEV down
if [ $port -eq 1 ]; then
exp0=( 0 0 0 0 )
exp1=( 0 0 0 0 )
fi
check_tables
echo 1 > $NSIM_DEV_DFS/ports/$port/udp_ports/reset
check_tables
msg="NIC device goes up again"
ip link set dev $NSIM_NETDEV up
exp0=( `mke 10000 1` 0 0 0 )
check_tables
msg="remove both"
del_dev vxlanA0
exp0=( 0 0 0 0 )
del_dev vxlan0
check_tables
echo 1 > $NSIM_DEV_DFS/ports/$port/udp_ports/reset
check_tables
msg="destroy NIC"
echo $port > $NSIM_DEV_SYS/del_port
cleanup_tuns
exp0=( 0 0 0 0 )
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_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 )
ip link set dev vxlan1 down
ip link set dev vxlan0 down
check_tables
for ifc in vxlan0 vxlan1; do
ip link set dev $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"
ip link set dev $NSIM_NETDEV down
check_tables
msg="NIC device goes up again"
ip link set dev $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
NSIM_NETDEV=`get_netdev_name old_netdevs`
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
echo "PASSED all $num_cases checks"
else
echo "FAILED $num_errors/$num_cases checks"
fi
exit $EXIT_STATUS