linux/tools/testing/selftests/drivers/net/hw/ethtool_rmon.sh
Ioana Ciornei abe4929bc7 selftests: drivers: hw: update ethtool_rmon to work with a single local interface
This patch finalizes the transition to work with a single local
interface for the ethtool_rmon.sh test. Each 'ip link' and 'ethtool'
command used by the test is annotated with the necessary run_on in
order to be executed on the necessary target system, be it local, in
another network namespace or through ssh.

Since we need NETIF up and running also for control traffic, we now
expect that the interfaces are up and running and do not touch bring
them up or down at the end of the test. This is also documented in the
drivers/net/README.rst.

The ethtool_rmon.sh script can still be used in the older fashion by
passing two interfaces as command line arguments, the only restriction
is that those interfaces need to be already up.

 $ DRIVER_TEST_CONFORMANT=no ./ethtool_rmon.sh eth0 eth1

As part of the kselftest infrastructure, this test can be run in the
following manner:

 $ make -C tools/testing/selftests/ TARGETS="drivers/net drivers/net/hw" \
 install INSTALL_PATH=/tmp/ksft-net-drv
 $ cd /tmp/ksft-net-drv/
 $ cat > ./drivers/net/net.config <<EOF
 NETIF=endpmac17
 LOCAL_V4=17.0.0.1
 REMOTE_V4=17.0.0.2
 REMOTE_TYPE=ssh
 REMOTE_ARGS=root@192.168.5.200
 EOF

 $ ./run_kselftest.sh -t drivers/net/hw:ethtool_rmon.sh
 TAP version 13
 1..1
 # timeout set to 0
 # selftests: drivers/net/hw: ethtool_rmon.sh
 # TAP version 13
 # 1..14
 # ok 1 ethtool_rmon.rx-pkts64to64
 # ok 2 ethtool_rmon.rx-pkts65to127
 # ok 3 ethtool_rmon.rx-pkts128to255
 # ok 4 ethtool_rmon.rx-pkts256to511
 # ok 5 ethtool_rmon.rx-pkts512to1023
 # ok 6 ethtool_rmon.rx-pkts1024to1518
 # ok 7 ethtool_rmon.rx-pkts1519to10240
 # ok 8 ethtool_rmon.tx-pkts64to64
 # ok 9 ethtool_rmon.tx-pkts65to127
 # ok 10 ethtool_rmon.tx-pkts128to255
 # ok 11 ethtool_rmon.tx-pkts256to511
 # ok 12 ethtool_rmon.tx-pkts512to1023
 # ok 13 ethtool_rmon.tx-pkts1024to1518
 # ok 14 ethtool_rmon.tx-pkts1519to10240
 # # Totals: pass:14 fail:0 xfail:0 xpass:0 skip:0 error:0
 ok 1 selftests: drivers/net/hw: ethtool_rmon.sh

Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
Reviewed-by: Petr Machata <petrm@nvidia.com>
Link: https://patch.msgid.link/20260330152933.2195885-9-ioana.ciornei@nxp.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2026-04-02 12:11:04 +02:00

160 lines
3.5 KiB
Bash
Executable File

#!/bin/bash
# SPDX-License-Identifier: GPL-2.0
#shellcheck disable=SC2034 # SC does not see the global variables
#shellcheck disable=SC2317,SC2329 # unused functions
ALL_TESTS="
rmon_rx_histogram
rmon_tx_histogram
"
: "${DRIVER_TEST_CONFORMANT:=yes}"
NUM_NETIFS=2
lib_dir=$(dirname "$0")
source "$lib_dir"/../../../net/forwarding/lib.sh
source "$lib_dir"/../../../kselftest/ktap_helpers.sh
UINT32_MAX=$((2**32 - 1))
ETH_FCS_LEN=4
ETH_HLEN=$((6+6+2))
TEST_NAME=$(basename "$0" .sh)
declare -A netif_mtu
ensure_mtu()
{
local iface=$1; shift
local len=$1; shift
local required=$((len - ETH_HLEN - ETH_FCS_LEN))
local current
current=$(run_on "$iface" \
ip -j link show dev "$iface" | jq -r '.[0].mtu')
if [ "$current" -lt "$required" ]; then
run_on "$iface" ip link set dev "$iface" mtu "$required" \
|| return 1
fi
}
bucket_test()
{
local iface=$1; shift
local neigh=$1; shift
local set=$1; shift
local bucket=$1; shift
local len=$1; shift
local num_rx=10000
local num_tx=20000
local expected=
local before=
local after=
local delta=
# Mausezahn does not include FCS bytes in its length - but the
# histogram counters do
len=$((len - ETH_FCS_LEN))
len=$((len > 0 ? len : 0))
before=$(run_on "$iface" ethtool --json -S "$iface" --groups rmon | \
jq -r ".[0].rmon[\"${set}-pktsNtoM\"][$bucket].val")
# Send 10k one way and 20k in the other, to detect counters
# mapped to the wrong direction
run_on "$neigh" \
"$MZ" "$neigh" -q -c "$num_rx" -p "$len" -a own -b bcast -d 10us
run_on "$iface" \
"$MZ" "$iface" -q -c "$num_tx" -p "$len" -a own -b bcast -d 10us
after=$(run_on "$iface" ethtool --json -S "$iface" --groups rmon | \
jq -r ".[0].rmon[\"${set}-pktsNtoM\"][$bucket].val")
delta=$((after - before))
expected=$([ "$set" = rx ] && echo "$num_rx" || echo "$num_tx")
[ "$delta" -ge "$expected" ] && [ "$delta" -le "$UINT32_MAX" ]
}
rmon_histogram()
{
local iface=$1; shift
local neigh=$1; shift
local set=$1; shift
local nbuckets=0
local step=
while read -r -a bucket; do
step="$set-pkts${bucket[0]}to${bucket[1]}"
for if in "$iface" "$neigh"; do
if ! ensure_mtu "$if" "${bucket[0]}"; then
ktap_print_msg "$if does not support the required MTU for $step"
ktap_test_xfail "$TEST_NAME.$step"
return
fi
done
if ! bucket_test "$iface" "$neigh" "$set" "$nbuckets" "${bucket[0]}"; then
ktap_test_fail "$TEST_NAME.$step"
return 1
fi
ktap_test_pass "$TEST_NAME.$step"
nbuckets=$((nbuckets + 1))
done < <(run_on "$iface" ethtool --json -S "$iface" --groups rmon | \
jq -r ".[0].rmon[\"${set}-pktsNtoM\"][]|[.low, .high]|@tsv" 2>/dev/null)
if [ "$nbuckets" -eq 0 ]; then
ktap_print_msg "$iface does not support $set histogram counters"
return
fi
}
rmon_rx_histogram()
{
rmon_histogram "$h1" "$h2" rx
}
rmon_tx_histogram()
{
rmon_histogram "$h1" "$h2" tx
}
setup_prepare()
{
h1=${NETIFS[p1]}
h2=${NETIFS[p2]}
for iface in "$h1" "$h2"; do
netif_mtu["$iface"]=$(run_on "$iface" \
ip -j link show dev "$iface" | jq -r '.[0].mtu')
done
}
cleanup()
{
pre_cleanup
# Do not bring down the interfaces, just configure the initial MTU
for iface in "$h2" "$h1"; do
run_on "$iface" ip link set dev "$iface" \
mtu "${netif_mtu[$iface]}"
done
}
check_ethtool_counter_group_support
trap cleanup EXIT
bucket_count=$(ethtool --json -S "${NETIFS[p1]}" --groups rmon | \
jq -r '.[0].rmon |
"\((."rx-pktsNtoM" | length) +
(."tx-pktsNtoM" | length))"')
ktap_print_header
ktap_set_plan "$bucket_count"
setup_prepare
setup_wait
tests_run
ktap_finished