selftests: forwarding: ethtool_rmon: Add histogram counter test
authorTobias Waldekranz <tobias@waldekranz.com>
Thu, 14 Dec 2023 13:50:29 +0000 (14:50 +0100)
committerDavid S. Miller <davem@davemloft.net>
Fri, 15 Dec 2023 11:05:03 +0000 (11:05 +0000)
Validate the operation of rx and tx histogram counters, if supported
by the interface, by sending batches of packets targeted for each
bucket.

Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
Tested-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
tools/testing/selftests/net/forwarding/Makefile
tools/testing/selftests/net/forwarding/ethtool_rmon.sh [new file with mode: 0755]
tools/testing/selftests/net/forwarding/lib.sh

index df593b7b3e6bf3670e08fab139d007cbaf754ad9..452693514be4b06842dbe32088c5495c2c933f0b 100644 (file)
@@ -17,6 +17,7 @@ TEST_PROGS = bridge_fdb_learning_limit.sh \
        dual_vxlan_bridge.sh \
        ethtool_extended_state.sh \
        ethtool_mm.sh \
+       ethtool_rmon.sh \
        ethtool.sh \
        gre_custom_multipath_hash.sh \
        gre_inner_v4_multipath.sh \
diff --git a/tools/testing/selftests/net/forwarding/ethtool_rmon.sh b/tools/testing/selftests/net/forwarding/ethtool_rmon.sh
new file mode 100755 (executable)
index 0000000..41a34a6
--- /dev/null
@@ -0,0 +1,143 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
+
+ALL_TESTS="
+       rmon_rx_histogram
+       rmon_tx_histogram
+"
+
+NUM_NETIFS=2
+source lib.sh
+
+ETH_FCS_LEN=4
+ETH_HLEN=$((6+6+2))
+
+declare -A netif_mtu
+
+ensure_mtu()
+{
+       local iface=$1; shift
+       local len=$1; shift
+       local current=$(ip -j link show dev $iface | jq -r '.[0].mtu')
+       local required=$((len - ETH_HLEN - ETH_FCS_LEN))
+
+       if [ $current -lt $required ]; then
+               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))
+
+       before=$(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
+       $MZ $neigh -q -c $num_rx -p $len -a own -b bcast -d 10us
+       $MZ $iface -q -c $num_tx -p $len -a own -b bcast -d 10us
+
+       after=$(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)
+
+       # Allow some extra tolerance for other packets sent by the stack
+       [ $delta -ge $expected ] && [ $delta -le $((expected + 100)) ]
+}
+
+rmon_histogram()
+{
+       local iface=$1; shift
+       local neigh=$1; shift
+       local set=$1; shift
+       local nbuckets=0
+       local step=
+
+       RET=0
+
+       while read -r -a bucket; do
+               step="$set-pkts${bucket[0]}to${bucket[1]} on $iface"
+
+               for if in $iface $neigh; do
+                       if ! ensure_mtu $if ${bucket[0]}; then
+                               log_test_skip "$if does not support the required MTU for $step"
+                               return
+                       fi
+               done
+
+               if ! bucket_test $iface $neigh $set $nbuckets ${bucket[0]}; then
+                       check_err 1 "$step failed"
+                       return 1
+               fi
+               log_test "$step"
+               nbuckets=$((nbuckets + 1))
+       done < <(ethtool --json -S $iface --groups rmon | \
+               jq -r ".[0].rmon[\"${set}-pktsNtoM\"][]|[.low, .high]|@tsv" 2>/dev/null)
+
+       if [ $nbuckets -eq 0 ]; then
+               log_test_skip "$iface does not support $set histogram counters"
+               return
+       fi
+}
+
+rmon_rx_histogram()
+{
+       rmon_histogram $h1 $h2 rx
+       rmon_histogram $h2 $h1 rx
+}
+
+rmon_tx_histogram()
+{
+       rmon_histogram $h1 $h2 tx
+       rmon_histogram $h2 $h1 tx
+}
+
+setup_prepare()
+{
+       h1=${NETIFS[p1]}
+       h2=${NETIFS[p2]}
+
+       for iface in $h1 $h2; do
+               netif_mtu[$iface]=$(ip -j link show dev $iface | jq -r '.[0].mtu')
+               ip link set dev $iface up
+       done
+}
+
+cleanup()
+{
+       pre_cleanup
+
+       for iface in $h2 $h1; do
+               ip link set dev $iface \
+                       mtu ${netif_mtu[$iface]} \
+                       down
+       done
+}
+
+check_ethtool_counter_group_support
+trap cleanup EXIT
+
+setup_prepare
+setup_wait
+
+tests_run
+
+exit $EXIT_STATUS
index 8f6ca458af9a8dde1b93e2a64ad582e8b54e6cdb..e3740163c384fdfaa9e9b29a6ca79e1295d688e9 100755 (executable)
@@ -146,6 +146,15 @@ check_ethtool_mm_support()
        fi
 }
 
+check_ethtool_counter_group_support()
+{
+       ethtool --help 2>&1| grep -- '--all-groups' &> /dev/null
+       if [[ $? -ne 0 ]]; then
+               echo "SKIP: ethtool too old; it is missing standard counter group support"
+               exit $ksft_skip
+       fi
+}
+
 check_locked_port_support()
 {
        if ! bridge -d link show | grep -q " locked"; then