mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-14 06:24:53 +08:00
selftests: netdevsim: hw_stats_l3: Add a new test
Add a test that verifies basic UAPI contracts, netdevsim operation, rollbacks after partial enablement in core, and UAPI notifications. Signed-off-by: Petr Machata <petrm@nvidia.com> Signed-off-by: Paolo Abeni <pabeni@redhat.com>
This commit is contained in:
parent
1a6d7ae7d6
commit
9b18942e99
421
tools/testing/selftests/drivers/net/netdevsim/hw_stats_l3.sh
Executable file
421
tools/testing/selftests/drivers/net/netdevsim/hw_stats_l3.sh
Executable file
@ -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
|
||||
|
||||
local pkts=$(get_hwstat dummy1 l3 rx.packets)
|
||||
((pkts >= 20))
|
||||
check_err $? "$type stats show < 20 packets after 2s 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
|
@ -1498,3 +1498,63 @@ brmcast_check_sg_state()
|
||||
check_err_fail $should_fail $? "Entry $src has blocked flag"
|
||||
done
|
||||
}
|
||||
|
||||
start_ip_monitor()
|
||||
{
|
||||
local mtype=$1; shift
|
||||
local ip=${1-ip}; shift
|
||||
|
||||
# start the monitor in the background
|
||||
tmpfile=`mktemp /var/run/nexthoptestXXX`
|
||||
mpid=`($ip monitor $mtype > $tmpfile & echo $!) 2>/dev/null`
|
||||
sleep 0.2
|
||||
echo "$mpid $tmpfile"
|
||||
}
|
||||
|
||||
stop_ip_monitor()
|
||||
{
|
||||
local mpid=$1; shift
|
||||
local tmpfile=$1; shift
|
||||
local el=$1; shift
|
||||
local what=$1; shift
|
||||
|
||||
sleep 0.2
|
||||
kill $mpid
|
||||
local lines=`grep '^\w' $tmpfile | wc -l`
|
||||
test $lines -eq $el
|
||||
check_err $? "$what: $lines lines of events, expected $el"
|
||||
rm -rf $tmpfile
|
||||
}
|
||||
|
||||
hw_stats_monitor_test()
|
||||
{
|
||||
local dev=$1; shift
|
||||
local type=$1; shift
|
||||
local make_suitable=$1; shift
|
||||
local make_unsuitable=$1; shift
|
||||
local ip=${1-ip}; shift
|
||||
|
||||
RET=0
|
||||
|
||||
# Expect a notification about enablement.
|
||||
local ipmout=$(start_ip_monitor stats "$ip")
|
||||
$ip stats set dev $dev ${type}_stats on
|
||||
stop_ip_monitor $ipmout 1 "${type}_stats enablement"
|
||||
|
||||
# Expect a notification about offload.
|
||||
local ipmout=$(start_ip_monitor stats "$ip")
|
||||
$make_suitable
|
||||
stop_ip_monitor $ipmout 1 "${type}_stats installation"
|
||||
|
||||
# Expect a notification about loss of offload.
|
||||
local ipmout=$(start_ip_monitor stats "$ip")
|
||||
$make_unsuitable
|
||||
stop_ip_monitor $ipmout 1 "${type}_stats deinstallation"
|
||||
|
||||
# Expect a notification about disablement
|
||||
local ipmout=$(start_ip_monitor stats "$ip")
|
||||
$ip stats set dev $dev ${type}_stats off
|
||||
stop_ip_monitor $ipmout 1 "${type}_stats disablement"
|
||||
|
||||
log_test "${type}_stats notifications"
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user