* [PATCH net-next v4 00/10] selftests: drivers: bash support for remote traffic generators
@ 2026-03-26 13:28 Ioana Ciornei
2026-03-26 13:28 ` [PATCH net-next v4 01/10] selftests: forwarding: extend ethtool_std_stats_get with pause statistics Ioana Ciornei
` (10 more replies)
0 siblings, 11 replies; 26+ messages in thread
From: Ioana Ciornei @ 2026-03-26 13:28 UTC (permalink / raw)
To: netdev
Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Simon Horman, linux-kernel, petrm, willemb,
linux-kselftest
This patch set aims to add the necessary support so that bash written
selftests are also able to easily run with a remote traffic generator
system, either be it in another netns or one accessible through ssh.
This patch set is a result of the discussion from v1:
https://lore.kernel.org/all/20260303084330.340b6459@kernel.org/
Even though the python infrastructure is already established, some
things are easier in bash and it would be a shame to leave behind the
bash tests that we already have.
This support is based on the requirements described in the
tools/testing/selftests/drivers/net/README.rst file.
Mainly, the drivers/net selftests should be able to run on a interface
specified through the NETIF env variable. On top of that, variables such
as REMOTE_TYPE and REMOTE_ARGS define how the remote traffic generator
can be accessed. Patch 3/10 parses these env variables and constructs the
NETIFS array that bash tests are accustomed to. This is with the
intention of enabling already written tests to incur minimal changes.
The second patch also defines the TARGETS array which will hold the
necessary information about the target on which a specific interface
is located.
For example, a net.config which looks like below:
NETIF=eth0
LOCAL_V4=192.168.1.1
REMOTE_V4=192.168.1.2
REMOTE_TYPE=ssh
REMOTE_ARGS=root@192.168.1.2
will generate the NETIFS and TARGETS arrays with the following data.
NETIFS[p1]="eth0"
NETIFS[p2]="eth2"
TARGETS[eth0]="local:"
TARGETS[eth2]="ssh:root@192.168.1.2"
The above will be true if on the remote target, the interface which has
the 192.168.1.2 address is named eth2.
The values held in the TARGETS array will be used by the new 'run_on'
helper added in patch 2/10 to know how to run a specific command, on the
local system, on another netns or by using ssh. Patch 4/10 updates some
helpers to use run_on so that, for example, lib.sh is able to ensure
stable MAC addresses even with the remote interface located in another
netns.
The next 5 patches, 5/10-9/10 update the ethtool_rmon.sh script so that it
can work with the kselftest infrastructure and the new
NETIF/REMOTE_TYPE etc way of working. Beside updating each ip link or
ethtool command to use the run_on helper, the patches also remove any
testing done on the remote interface.
The last patch adds a new test which checks the standard counters -
eth-ctrl, eth-mac and pause - and uses the new infrastructure put in
place by the first patches.
With this patch set, both tests can be run using a net.config file and
run_kselftest.sh as shown below.
$ 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
$ ./run_kselftest.sh -t drivers/net/hw:ethtool_std_stats.sh
TAP version 13
1..1
# timeout set to 0
# selftests: drivers/net/hw: ethtool_std_stats.sh
# TAP version 13
# 1..26
# ok 1 ethtool_std_stats.eth-ctrl-MACControlFramesTransmitted
# ok 2 ethtool_std_stats.eth-ctrl-MACControlFramesReceived
# ok 3 ethtool_std_stats.eth-mac-FrameCheckSequenceErrors
# ok 4 ethtool_std_stats.eth-mac-AlignmentErrors
# ok 5 ethtool_std_stats.eth-mac-FramesLostDueToIntMACXmitError
# ok 6 ethtool_std_stats.eth-mac-CarrierSenseErrors # SKIP
# ok 7 ethtool_std_stats.eth-mac-FramesLostDueToIntMACRcvError
# ok 8 ethtool_std_stats.eth-mac-InRangeLengthErrors # SKIP
# ok 9 ethtool_std_stats.eth-mac-OutOfRangeLengthField # SKIP
# ok 10 ethtool_std_stats.eth-mac-FrameTooLongErrors # SKIP
# ok 11 ethtool_std_stats.eth-mac-FramesAbortedDueToXSColls # SKIP
# ok 12 ethtool_std_stats.eth-mac-SingleCollisionFrames # SKIP
# ok 13 ethtool_std_stats.eth-mac-MultipleCollisionFrames # SKIP
# ok 14 ethtool_std_stats.eth-mac-FramesWithDeferredXmissions # SKIP
# ok 15 ethtool_std_stats.eth-mac-LateCollisions # SKIP
# ok 16 ethtool_std_stats.eth-mac-FramesWithExcessiveDeferral # SKIP
# ok 17 ethtool_std_stats.eth-mac-BroadcastFramesXmittedOK
# ok 18 ethtool_std_stats.eth-mac-OctetsTransmittedOK
# ok 19 ethtool_std_stats.eth-mac-BroadcastFramesReceivedOK
# ok 20 ethtool_std_stats.eth-mac-OctetsReceivedOK
# ok 21 ethtool_std_stats.eth-mac-FramesTransmittedOK
# ok 22 ethtool_std_stats.eth-mac-MulticastFramesXmittedOK
# ok 23 ethtool_std_stats.eth-mac-FramesReceivedOK
# ok 24 ethtool_std_stats.eth-mac-MulticastFramesReceivedOK
# ok 25 ethtool_std_stats.pause-tx_pause_frames
# ok 26 ethtool_std_stats.pause-rx_pause_frames
# # 10 skipped test(s) detected. Consider enabling relevant config options to improve coverage.
# # Totals: pass:16 fail:0 xfail:0 xpass:0 skip:10 error:0
ok 1 selftests: drivers/net/hw: ethtool_std_stats.sh
Changes in v4:
- 1/10: wrap the lines to max 80 chars
- 1/10: replace the if-else with a simple if and return in order to be
easier to maintain the 80 chars limit.
- 2/10: reworked the helpers so that no global variable is used and
information is passed only through parameters
- 3/10: reword the entry in README.rst to mention that the different
interface names is only a bash restriction and the python
infrastructure does not have the same problem.
- 3/10: only declare the TARGETS array when necessary
- 3/10: add a new flags - DRIVER_TEST_CONFORMANT - that needs to be set
by the test
- 3/10: rework the check_env() function so that its logic is simpler
- 3/10: source drivers/net/net.config only if DRIVER_TEST_CONFORMANT ==
yes
- 3/10: check that NETIF and the remote netif have different names and
abort test is not
- 4/10: split some lines to 80 chars
- 5/10: split one line to 80 chars
- 8/10: patch is added in this version so that ethtool_rmon.sh is
converted to KTAP output
- 9/10: set DRIVER_TEST_CONFORMANT to yes
- 9/10: update the commit message to reflect the current output
- 9/10: split some more lines to 80 chars
- 10/10: move to a the KTAP format output by using ktap_helpers.sh
- 10/10: update commit message to reflect the current output
- 10/10: use DRIVER_TEST_CONFORMANT
Changes in v3:
- Change the TARGET variable into CUR_TARGET
- Always fallback on running a command locally when either TARGETS is
not declared or there is no entry for a specific interface
- Swap patches 2 & 3 between them so that the run_cmd used in now patch
#2 is defined in patch #2
- Add some more double quoting
Changes in v2:
- 1/9: Convert jq to the --arg usage form
- Patches 2/9-8/9 are new in this version
- 9/9: Use the new run_on helper
- 9/9: No longer checking that each counter has a 1% tolerance against the
target. The only upper limit is UINT32_MAX.
- 9/9: Check that both the error counters and the collision related ones are
zero since this is the most probable scenario (we don't expect errors
with the traffic that we are sending).
- 9/9: Removed any checks performed on the remot interface counters since
that is being used only as a traffic generator.
Ioana Ciornei (10):
selftests: forwarding: extend ethtool_std_stats_get with pause
statistics
selftests: net: add helpers for running a command on other targets
selftests: net: extend lib.sh to parse drivers/net/net.config
selftests: net: update some helpers to use run_on
selftests: drivers: hw: cleanup shellcheck warnings in the rmon test
selftests: drivers: hw: test rmon counters only on first interface
selftests: drivers: hw: replace counter upper limit with UINT32_MAX in
rmon test
selftests: drivers: hw: move to KTAP output
selftests: drivers: hw: update ethtool_rmon to work with a single
local interface
selftests: drivers: hw: add test for the ethtool standard counters
.../testing/selftests/drivers/net/README.rst | 4 +
.../testing/selftests/drivers/net/hw/Makefile | 1 +
.../selftests/drivers/net/hw/ethtool_rmon.sh | 82 ++++---
.../drivers/net/hw/ethtool_std_stats.sh | 206 ++++++++++++++++++
tools/testing/selftests/net/forwarding/lib.sh | 131 +++++++++--
tools/testing/selftests/net/lib.sh | 41 +++-
6 files changed, 414 insertions(+), 51 deletions(-)
create mode 100755 tools/testing/selftests/drivers/net/hw/ethtool_std_stats.sh
--
2.25.1
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH net-next v4 01/10] selftests: forwarding: extend ethtool_std_stats_get with pause statistics
2026-03-26 13:28 [PATCH net-next v4 00/10] selftests: drivers: bash support for remote traffic generators Ioana Ciornei
@ 2026-03-26 13:28 ` Ioana Ciornei
2026-03-26 13:28 ` [PATCH net-next v4 02/10] selftests: net: add helpers for running a command on other targets Ioana Ciornei
` (9 subsequent siblings)
10 siblings, 0 replies; 26+ messages in thread
From: Ioana Ciornei @ 2026-03-26 13:28 UTC (permalink / raw)
To: netdev
Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Simon Horman, linux-kernel, petrm, willemb,
linux-kselftest
Even though pause frame statistics are not exported through the same
ethtool command, there is no point in adding another helper just for
them. Extent the ethtool_std_stats_get() function so that we are able to
interrogate using the same helper all the standard statistics.
And since we are touching the function, convert the initial ethtool call
as well to the jq --arg form in order to be easier to read.
Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
Reviewed-by: Petr Machata <petrm@nvidia.com>
---
Changes in v4:
- wrap the lines to max 80 chars
- replace the if-else with a simple if and return in order to be easier
to maintain the 80 chars limit.
Changes in v3:
- none
Changes in v2:
- convert jq to the --arg usage form
tools/testing/selftests/net/forwarding/lib.sh | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/net/forwarding/lib.sh b/tools/testing/selftests/net/forwarding/lib.sh
index a9034f0bb58b..3009ce00c5dc 100644
--- a/tools/testing/selftests/net/forwarding/lib.sh
+++ b/tools/testing/selftests/net/forwarding/lib.sh
@@ -831,8 +831,14 @@ ethtool_std_stats_get()
local name=$1; shift
local src=$1; shift
- ethtool --json -S $dev --groups $grp -- --src $src | \
- jq '.[]."'"$grp"'"."'$name'"'
+ if [[ "$grp" == "pause" ]]; then
+ ethtool -I --json -a "$dev" --src "$src" | \
+ jq --arg name "$name" '.[].statistics[$name]'
+ return
+ fi
+
+ ethtool --json -S "$dev" --groups "$grp" -- --src "$src" | \
+ jq --arg grp "$grp" --arg name "$name" '.[][$grp][$name]'
}
qdisc_stats_get()
--
2.25.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH net-next v4 02/10] selftests: net: add helpers for running a command on other targets
2026-03-26 13:28 [PATCH net-next v4 00/10] selftests: drivers: bash support for remote traffic generators Ioana Ciornei
2026-03-26 13:28 ` [PATCH net-next v4 01/10] selftests: forwarding: extend ethtool_std_stats_get with pause statistics Ioana Ciornei
@ 2026-03-26 13:28 ` Ioana Ciornei
2026-03-30 11:02 ` Petr Machata
2026-03-26 13:28 ` [PATCH net-next v4 03/10] selftests: net: extend lib.sh to parse drivers/net/net.config Ioana Ciornei
` (8 subsequent siblings)
10 siblings, 1 reply; 26+ messages in thread
From: Ioana Ciornei @ 2026-03-26 13:28 UTC (permalink / raw)
To: netdev
Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Simon Horman, linux-kernel, petrm, willemb,
linux-kselftest
Add a couple of helpers which can be used by tests which need to run a
specific bash command on a different target than the local system, be it
either another netns or a remote system accessible through ssh.
The __run_on() function is passed through $1 the target on which the
command should be executed while run_on() is passed the name of the
interface that is then used to retrieve the target from the TARGETS
array.
Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
---
Changes in v4:
- reworked the helpers so that no global variable is used and
information is passed only through parameters
Changes in v3:
- s/TARGET/CUR_TARGET
- always fallback on running a command locally when either TARGETS is
not declared or there is no entry for a specific interface
Changes in v2:
- patch is new
tools/testing/selftests/net/lib.sh | 38 ++++++++++++++++++++++++++++++
1 file changed, 38 insertions(+)
diff --git a/tools/testing/selftests/net/lib.sh b/tools/testing/selftests/net/lib.sh
index b40694573f4c..6c0d613a4de5 100644
--- a/tools/testing/selftests/net/lib.sh
+++ b/tools/testing/selftests/net/lib.sh
@@ -670,3 +670,41 @@ cmd_jq()
# return success only in case of non-empty output
[ ! -z "$output" ]
}
+
+__run_on()
+{
+ local target=$1; shift
+ local type args
+
+ IFS=':' read -r type args <<< "$target"
+
+ case "$type" in
+ netns)
+ # Execute command in network namespace
+ # args contains the namespace name
+ ip netns exec "$args" "$@"
+ ;;
+ ssh)
+ # Execute command via SSH args contains user@host
+ ssh -n "$args" "$@"
+ ;;
+ local|*)
+ # Execute command locally. This is also the fallback
+ # case for when the interface's target is not found in
+ # the TARGETS array.
+ "$@"
+ ;;
+ esac
+}
+
+run_on()
+{
+ local iface=$1; shift
+ local target="local:"
+
+ if declare -p TARGETS &>/dev/null; then
+ target="${TARGETS[$iface]}"
+ fi
+
+ __run_on "$target" "$@"
+}
--
2.25.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH net-next v4 03/10] selftests: net: extend lib.sh to parse drivers/net/net.config
2026-03-26 13:28 [PATCH net-next v4 00/10] selftests: drivers: bash support for remote traffic generators Ioana Ciornei
2026-03-26 13:28 ` [PATCH net-next v4 01/10] selftests: forwarding: extend ethtool_std_stats_get with pause statistics Ioana Ciornei
2026-03-26 13:28 ` [PATCH net-next v4 02/10] selftests: net: add helpers for running a command on other targets Ioana Ciornei
@ 2026-03-26 13:28 ` Ioana Ciornei
2026-03-30 11:28 ` Petr Machata
2026-03-26 13:28 ` [PATCH net-next v4 04/10] selftests: net: update some helpers to use run_on Ioana Ciornei
` (7 subsequent siblings)
10 siblings, 1 reply; 26+ messages in thread
From: Ioana Ciornei @ 2026-03-26 13:28 UTC (permalink / raw)
To: netdev
Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Simon Horman, linux-kernel, petrm, willemb,
linux-kselftest
Extend lib.sh so that it's able to parse driver/net/net.config and
environment variables such as NETIF, REMOTE_TYPE, LOCAL_V4 etc described
in drivers/net/README.rst.
In order to make the transition towards running with a single local
interface smoother for the bash networking driver tests, beside sourcing
the net.config file also translate the new env variables into the old
style based on the NETIFS array. Since the NETIFS array only holds the
network interface names, also add a new array - TARGETS - which keeps
track of the target on which a specific interfaces resides - local,
netns or accesible through an ssh command.
For example, a net.config which looks like below:
NETIF=eth0
LOCAL_V4=192.168.1.1
REMOTE_V4=192.168.1.2
REMOTE_TYPE=ssh
REMOTE_ARGS=root@192.168.1.2
will generate the NETIFS and TARGETS arrays with the following data.
NETIFS[p1]="eth0"
NETIFS[p2]="eth2"
TARGETS[eth0]="local:"
TARGETS[eth2]="ssh:root@192.168.1.2"
The above will be true if on the remote target, the interface which has
the 192.168.1.2 address is named eth2.
Since the TARGETS array is indexed by the network interface name,
document a new restriction README.rst which states that the remote
interface cannot have the same name as the local one.
Also keep the old way of populating the NETIFS variable based on the
command line arguments. This will be invoked in case NETIF is not
defined.
Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
---
Changes in v4:
- reword the entry in README.rst to mention that the different interface
names is only a bash restriction and the python infrastructure does
not have the same problem.
- only declare the TARGETS array when necessary
- add a new flags - DRIVER_TEST_CONFORMANT - that needs to be set by the
test
- rework the check_env() function so that its logic is simpler
- source drivers/net/net.config only if DRIVER_TEST_CONFORMANT == yes
- check that NETIF and the remote netif have different names and abort
test is not
Changes in v3:
- s/TARGET/CUR_TARGET
- this used to be patch #2/9 in v2. Swapped the two patches so that the
run_cmd used in this patch is defined earlier, not later.
Changes in v2:
- patch is new
.../testing/selftests/drivers/net/README.rst | 4 +
tools/testing/selftests/net/forwarding/lib.sh | 106 ++++++++++++++++--
2 files changed, 101 insertions(+), 9 deletions(-)
diff --git a/tools/testing/selftests/drivers/net/README.rst b/tools/testing/selftests/drivers/net/README.rst
index c94992acf10b..1897aa1583ec 100644
--- a/tools/testing/selftests/drivers/net/README.rst
+++ b/tools/testing/selftests/drivers/net/README.rst
@@ -26,6 +26,10 @@ The netdevice against which tests will be run must exist, be running
Refer to list of :ref:`Variables` later in this file to set up running
the tests against a real device.
+The current support for bash tests restricts the use of the same interface name
+on the local system and the remote one and will bail if this case is
+encountered.
+
Both modes required
~~~~~~~~~~~~~~~~~~~
diff --git a/tools/testing/selftests/net/forwarding/lib.sh b/tools/testing/selftests/net/forwarding/lib.sh
index 3009ce00c5dc..93b865681840 100644
--- a/tools/testing/selftests/net/forwarding/lib.sh
+++ b/tools/testing/selftests/net/forwarding/lib.sh
@@ -3,6 +3,7 @@
##############################################################################
# Topology description. p1 looped back to p2, p3 to p4 and so on.
+#shellcheck disable=SC2034 # SC doesn't see our uses of global variables
declare -A NETIFS=(
[p1]=veth0
@@ -85,6 +86,9 @@ declare -A NETIFS=(
# e.g. a low-power board.
: "${KSFT_MACHINE_SLOW:=no}"
+# Whether the test is conforming to the requirements and usage described in
+# drivers/net/README.rst.
+: "${DRIVER_TEST_CONFORMANT:=no}"
##############################################################################
# Find netifs by test-specified driver name
@@ -340,17 +344,101 @@ fi
##############################################################################
# Command line options handling
-count=0
+check_env() {
+ if [[ ! (( -n "$LOCAL_V4" && -n "$REMOTE_V4") ||
+ ( -n "$LOCAL_V6" && -n "$REMOTE_V6" )) ]]; then
+ echo "SKIP: Invalid environment, missing or inconsistent LOCAL_V4/REMOTE_V4/LOCAL_V6/REMOTE_V6"
+ echo "Please see tools/testing/selftests/drivers/net/README.rst"
+ exit "$ksft_skip"
+ fi
-while [[ $# -gt 0 ]]; do
- if [[ "$count" -eq "0" ]]; then
- unset NETIFS
- declare -A NETIFS
+ if [[ -z "$REMOTE_TYPE" ]]; then
+ echo "SKIP: Invalid environment, missing REMOTE_TYPE"
+ exit "$ksft_skip"
fi
- count=$((count + 1))
- NETIFS[p$count]="$1"
- shift
-done
+
+ if [[ -z "$REMOTE_ARGS" ]]; then
+ echo "SKIP: Invalid environment, missing REMOTE_ARGS"
+ exit "$ksft_skip"
+ fi
+}
+
+get_ifname_by_ip()
+{
+ local target=$1; shift
+ local ip_addr=$1; shift
+
+ __run_on "$target" ip -j addr show to "$ip_addr" | jq -r '.[].ifname'
+}
+
+# Based on DRIVER_TEST_CONFORMANT, decide if to source drivers/net/net.config
+# or not. In the "yes" case, the test expects to pass the arguments through the
+# variables specified in drivers/net/README.rst file. If not, fallback on
+# parsing the script arguments for interface names.
+if [ "${DRIVER_TEST_CONFORMANT}" = "yes" ]; then
+ if [[ -f $net_forwarding_dir/../../drivers/net/net.config ]]; then
+ source "$net_forwarding_dir/../../drivers/net/net.config"
+ fi
+
+ if (( NUM_NETIFS > 2)); then
+ echo "SKIP: DRIVER_TEST_CONFORMANT=yes and NUM_NETIFS is bigger than 2"
+ exit "$ksft_skip"
+ fi
+
+ check_env
+
+ # Populate the NETIFS and TARGETS arrays automatically based on the
+ # environment variables. The TARGETS array is indexed by the network
+ # interface name keeping track of the target on which the interface
+ # resides. Values will be strings of the following format -
+ # <type>:<args>.
+ #
+ # TARGETS[eth0]="local:" - meaning that the eth0 interface is
+ # accessible locally
+ # TARGETS[eth1]="netns:foo" - eth1 is in the foo netns
+ # TARGETS[eth2]="ssh:root@10.0.0.2" - eth2 is accessible through
+ # running the 'ssh root@10.0.0.2' command.
+
+ unset NETIFS
+ declare -A NETIFS
+ declare -A TARGETS
+
+ NETIFS[p1]="$NETIF"
+ TARGETS[$NETIF]="local:"
+
+ # Locate the name of the remote interface
+ remote_target="$REMOTE_TYPE:$REMOTE_ARGS"
+ if [[ -v REMOTE_V4 ]]; then
+ remote_netif=$(get_ifname_by_ip "$remote_target" "$REMOTE_V4")
+ else
+ remote_netif=$(get_ifname_by_ip "$remote_target" "$REMOTE_V6")
+ fi
+ if [[ ! -n "$remote_netif" ]]; then
+ echo "SKIP: cannot find remote interface"
+ exit "$ksft_skip"
+ fi
+
+ if [[ "$NETIF" == "$remote_netif" ]]; then
+ echo "SKIP: local and remote interfaces cannot have the same name"
+ exit "$ksft_skip"
+ fi
+
+ NETIFS[p2]="$remote_netif"
+ TARGETS[$remote_netif]="$REMOTE_TYPE:$REMOTE_ARGS"
+else
+ count=0
+
+ while [[ $# -gt 0 ]]; do
+ if [[ "$count" -eq "0" ]]; then
+ unset NETIFS
+ declare -A NETIFS
+ fi
+ count=$((count + 1))
+ NETIFS[p$count]="$1"
+ TARGETS[$1]="local:"
+ shift
+ done
+fi
##############################################################################
# Network interfaces configuration
--
2.25.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH net-next v4 04/10] selftests: net: update some helpers to use run_on
2026-03-26 13:28 [PATCH net-next v4 00/10] selftests: drivers: bash support for remote traffic generators Ioana Ciornei
` (2 preceding siblings ...)
2026-03-26 13:28 ` [PATCH net-next v4 03/10] selftests: net: extend lib.sh to parse drivers/net/net.config Ioana Ciornei
@ 2026-03-26 13:28 ` Ioana Ciornei
2026-03-30 11:55 ` Petr Machata
2026-03-26 13:28 ` [PATCH net-next v4 05/10] selftests: drivers: hw: cleanup shellcheck warnings in the rmon test Ioana Ciornei
` (6 subsequent siblings)
10 siblings, 1 reply; 26+ messages in thread
From: Ioana Ciornei @ 2026-03-26 13:28 UTC (permalink / raw)
To: netdev
Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Simon Horman, linux-kernel, petrm, willemb,
linux-kselftest
Update some helpers so that they are capable to run commands on
different targets than the local one. This patch makes the necesasy
modification for those helpers / sections of code which are needed for
the ethtool_rmon.sh test that will be converted in the next patches.
For example, mac_addr_prepare() and mac_addr_restore() used when
STABLE_MAC_ADDRS=yes need to ensure stable MAC addresses on interfaces
located even in other namespaces. In order to do that, append the 'ip
link' commands with a 'run_on $dev' tag.
The same run_on is necessary also when verifying if all the interfaces
listed in NETIFS are indeed available.
Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
---
Changes in v4:
- split some lines to 80 chars
Changes in v3:
- added some more double quotes
Changes in v2:
- patch is new
tools/testing/selftests/net/forwarding/lib.sh | 19 ++++++++++++-------
tools/testing/selftests/net/lib.sh | 3 ++-
2 files changed, 14 insertions(+), 8 deletions(-)
diff --git a/tools/testing/selftests/net/forwarding/lib.sh b/tools/testing/selftests/net/forwarding/lib.sh
index 93b865681840..98434da6e36b 100644
--- a/tools/testing/selftests/net/forwarding/lib.sh
+++ b/tools/testing/selftests/net/forwarding/lib.sh
@@ -506,10 +506,11 @@ mac_addr_prepare()
dev=${NETIFS[p$i]}
new_addr=$(printf "00:01:02:03:04:%02x" $i)
- MAC_ADDR_ORIG["$dev"]=$(ip -j link show dev $dev | jq -e '.[].address')
+ MAC_ADDR_ORIG["$dev"]=$(run_on "$dev" \
+ ip -j link show dev "$dev" | jq -e '.[].address')
# Strip quotes
MAC_ADDR_ORIG["$dev"]=${MAC_ADDR_ORIG["$dev"]//\"/}
- ip link set dev $dev address $new_addr
+ run_on "$dev" ip link set dev "$dev" address $new_addr
done
}
@@ -519,7 +520,8 @@ mac_addr_restore()
for ((i = 1; i <= NUM_NETIFS; ++i)); do
dev=${NETIFS[p$i]}
- ip link set dev $dev address ${MAC_ADDR_ORIG["$dev"]}
+ run_on "$dev" \
+ ip link set dev "$dev" address ${MAC_ADDR_ORIG["$dev"]}
done
}
@@ -532,7 +534,9 @@ if [[ "$STABLE_MAC_ADDRS" = "yes" ]]; then
fi
for ((i = 1; i <= NUM_NETIFS; ++i)); do
- ip link show dev ${NETIFS[p$i]} &> /dev/null
+ int="${NETIFS[p$i]}"
+
+ run_on "$int" ip link show dev "$int" &> /dev/null
if [[ $? -ne 0 ]]; then
echo "SKIP: could not find all required interfaces"
exit $ksft_skip
@@ -615,7 +619,7 @@ setup_wait_dev_with_timeout()
local i
for ((i = 1; i <= $max_iterations; ++i)); do
- ip link show dev $dev up \
+ run_on "$dev" ip link show dev "$dev" up \
| grep 'state UP' &> /dev/null
if [[ $? -ne 0 ]]; then
sleep 1
@@ -920,12 +924,13 @@ ethtool_std_stats_get()
local src=$1; shift
if [[ "$grp" == "pause" ]]; then
- ethtool -I --json -a "$dev" --src "$src" | \
+ run_on "$dev" ethtool -I --json -a "$dev" --src "$src" | \
jq --arg name "$name" '.[].statistics[$name]'
return
fi
- ethtool --json -S "$dev" --groups "$grp" -- --src "$src" | \
+ run_on "$dev" \
+ ethtool --json -S "$dev" --groups "$grp" -- --src "$src" | \
jq --arg grp "$grp" --arg name "$name" '.[][$grp][$name]'
}
diff --git a/tools/testing/selftests/net/lib.sh b/tools/testing/selftests/net/lib.sh
index 6c0d613a4de5..ed2291588a67 100644
--- a/tools/testing/selftests/net/lib.sh
+++ b/tools/testing/selftests/net/lib.sh
@@ -514,7 +514,8 @@ mac_get()
{
local if_name=$1
- ip -j link show dev $if_name | jq -r '.[]["address"]'
+ run_on "$if_name" \
+ ip -j link show dev "$if_name" | jq -r '.[]["address"]'
}
kill_process()
--
2.25.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH net-next v4 05/10] selftests: drivers: hw: cleanup shellcheck warnings in the rmon test
2026-03-26 13:28 [PATCH net-next v4 00/10] selftests: drivers: bash support for remote traffic generators Ioana Ciornei
` (3 preceding siblings ...)
2026-03-26 13:28 ` [PATCH net-next v4 04/10] selftests: net: update some helpers to use run_on Ioana Ciornei
@ 2026-03-26 13:28 ` Ioana Ciornei
2026-03-26 13:28 ` [PATCH net-next v4 06/10] selftests: drivers: hw: test rmon counters only on first interface Ioana Ciornei
` (5 subsequent siblings)
10 siblings, 0 replies; 26+ messages in thread
From: Ioana Ciornei @ 2026-03-26 13:28 UTC (permalink / raw)
To: netdev
Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Simon Horman, linux-kernel, petrm, willemb,
linux-kselftest
If run on the ethtool_rmon.sh script, shellcheck generates a bunch of
false positive errors. Suppress those checks that generate them.
Also cleanup the remaining warnings by using double quoting around the
used variables.
Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
Reviewed-by: Petr Machata <petrm@nvidia.com>
---
Changes in v4:
- split one line to 80 chars
Changes in v3:
- none
Changes in v2:
- patch is new
.../selftests/drivers/net/hw/ethtool_rmon.sh | 54 ++++++++++---------
1 file changed, 29 insertions(+), 25 deletions(-)
diff --git a/tools/testing/selftests/drivers/net/hw/ethtool_rmon.sh b/tools/testing/selftests/drivers/net/hw/ethtool_rmon.sh
index 8f60c1685ad4..13b3760e3a40 100755
--- a/tools/testing/selftests/drivers/net/hw/ethtool_rmon.sh
+++ b/tools/testing/selftests/drivers/net/hw/ethtool_rmon.sh
@@ -1,5 +1,7 @@
#!/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
@@ -19,11 +21,12 @@ 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))
+ local current
- if [ $current -lt $required ]; then
- ip link set dev $iface mtu $required || return 1
+ current=$(ip -j link show dev "$iface" | jq -r '.[0].mtu')
+ if [ "$current" -lt "$required" ]; then
+ ip link set dev "$iface" mtu "$required" || return 1
fi
}
@@ -46,23 +49,23 @@ bucket_test()
len=$((len - ETH_FCS_LEN))
len=$((len > 0 ? len : 0))
- before=$(ethtool --json -S $iface --groups rmon | \
+ 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
+ "$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 | \
+ 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)
+ 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)) ]
+ [ "$delta" -ge "$expected" ] && [ "$delta" -le $((expected + 100)) ]
}
rmon_histogram()
@@ -78,23 +81,23 @@ rmon_histogram()
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
+ for if in "$iface" "$neigh"; do
+ if ! ensure_mtu "$if" "${bucket[0]}"; then
log_test_xfail "$if does not support the required MTU for $step"
return
fi
done
- if ! bucket_test $iface $neigh $set $nbuckets ${bucket[0]}; then
+ 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 | \
+ done < <(ethtool --json -S "$iface" --groups rmon | \
jq -r ".[0].rmon[\"${set}-pktsNtoM\"][]|[.low, .high]|@tsv" 2>/dev/null)
- if [ $nbuckets -eq 0 ]; then
+ if [ "$nbuckets" -eq 0 ]; then
log_test_xfail "$iface does not support $set histogram counters"
return
fi
@@ -102,14 +105,14 @@ rmon_histogram()
rmon_rx_histogram()
{
- rmon_histogram $h1 $h2 rx
- rmon_histogram $h2 $h1 rx
+ rmon_histogram "$h1" "$h2" rx
+ rmon_histogram "$h2" "$h1" rx
}
rmon_tx_histogram()
{
- rmon_histogram $h1 $h2 tx
- rmon_histogram $h2 $h1 tx
+ rmon_histogram "$h1" "$h2" tx
+ rmon_histogram "$h2" "$h1" tx
}
setup_prepare()
@@ -117,9 +120,10 @@ 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
+ 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
}
@@ -127,9 +131,9 @@ cleanup()
{
pre_cleanup
- for iface in $h2 $h1; do
- ip link set dev $iface \
- mtu ${netif_mtu[$iface]} \
+ for iface in "$h2" "$h1"; do
+ ip link set dev "$iface" \
+ mtu "${netif_mtu[$iface]}" \
down
done
}
@@ -142,4 +146,4 @@ setup_wait
tests_run
-exit $EXIT_STATUS
+exit "$EXIT_STATUS"
--
2.25.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH net-next v4 06/10] selftests: drivers: hw: test rmon counters only on first interface
2026-03-26 13:28 [PATCH net-next v4 00/10] selftests: drivers: bash support for remote traffic generators Ioana Ciornei
` (4 preceding siblings ...)
2026-03-26 13:28 ` [PATCH net-next v4 05/10] selftests: drivers: hw: cleanup shellcheck warnings in the rmon test Ioana Ciornei
@ 2026-03-26 13:28 ` Ioana Ciornei
2026-03-26 13:28 ` [PATCH net-next v4 07/10] selftests: drivers: hw: replace counter upper limit with UINT32_MAX in rmon test Ioana Ciornei
` (4 subsequent siblings)
10 siblings, 0 replies; 26+ messages in thread
From: Ioana Ciornei @ 2026-03-26 13:28 UTC (permalink / raw)
To: netdev
Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Simon Horman, linux-kernel, petrm, willemb,
linux-kselftest
The selftests in drivers/net are slowly transitioning to being able to
be used on systems with a single network interface. The first step for the
ethtool_rmon.sh test is to only validate that the rmon counters are
properly exported on the first interface supplied as an argument.
Remove the rmon_histogram calls which intend to test also the rmon
counters on the 2nd interface. This also removes the need for the remote
system, which should be used only to inject traffic, to also support
rmon counters.
Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
Reviewed-by: Petr Machata <petrm@nvidia.com>
---
Changes in v4:
- none
Changes in v3:
- none
Changes in v2:
- patch is new
tools/testing/selftests/drivers/net/hw/ethtool_rmon.sh | 2 --
1 file changed, 2 deletions(-)
diff --git a/tools/testing/selftests/drivers/net/hw/ethtool_rmon.sh b/tools/testing/selftests/drivers/net/hw/ethtool_rmon.sh
index 13b3760e3a40..80e75b9b40fd 100755
--- a/tools/testing/selftests/drivers/net/hw/ethtool_rmon.sh
+++ b/tools/testing/selftests/drivers/net/hw/ethtool_rmon.sh
@@ -106,13 +106,11 @@ rmon_histogram()
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()
--
2.25.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH net-next v4 07/10] selftests: drivers: hw: replace counter upper limit with UINT32_MAX in rmon test
2026-03-26 13:28 [PATCH net-next v4 00/10] selftests: drivers: bash support for remote traffic generators Ioana Ciornei
` (5 preceding siblings ...)
2026-03-26 13:28 ` [PATCH net-next v4 06/10] selftests: drivers: hw: test rmon counters only on first interface Ioana Ciornei
@ 2026-03-26 13:28 ` Ioana Ciornei
2026-03-26 13:28 ` [PATCH net-next v4 08/10] selftests: drivers: hw: move to KTAP output Ioana Ciornei
` (3 subsequent siblings)
10 siblings, 0 replies; 26+ messages in thread
From: Ioana Ciornei @ 2026-03-26 13:28 UTC (permalink / raw)
To: netdev
Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Simon Horman, linux-kernel, petrm, willemb,
linux-kselftest
The ethtool_rmon.sh script checks that the number of packets sent /
received during a test matches the expected value with a 1% tolerance.
Since in the next patches this test will gain the capability to also be
run on systems with a single interface where the traffic generator is
accesible through ssh, use the UINT32_MAX as the upper limit. This is
necessary since the same interface will be used also for control traffic
(the ssh commands) as well as the mausezahn generated one.
Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
Reviewed-by: Petr Machata <petrm@nvidia.com>
---
Changes in v4:
- none
Changes in v3:
- none
Changes in v2:
- patch is new
tools/testing/selftests/drivers/net/hw/ethtool_rmon.sh | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/drivers/net/hw/ethtool_rmon.sh b/tools/testing/selftests/drivers/net/hw/ethtool_rmon.sh
index 80e75b9b40fd..f290ce1832f1 100755
--- a/tools/testing/selftests/drivers/net/hw/ethtool_rmon.sh
+++ b/tools/testing/selftests/drivers/net/hw/ethtool_rmon.sh
@@ -12,6 +12,7 @@ NUM_NETIFS=2
lib_dir=$(dirname "$0")
source "$lib_dir"/../../../net/forwarding/lib.sh
+UINT32_MAX=$((2**32 - 1))
ETH_FCS_LEN=4
ETH_HLEN=$((6+6+2))
@@ -64,8 +65,7 @@ bucket_test()
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)) ]
+ [ "$delta" -ge "$expected" ] && [ "$delta" -le "$UINT32_MAX" ]
}
rmon_histogram()
--
2.25.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH net-next v4 08/10] selftests: drivers: hw: move to KTAP output
2026-03-26 13:28 [PATCH net-next v4 00/10] selftests: drivers: bash support for remote traffic generators Ioana Ciornei
` (6 preceding siblings ...)
2026-03-26 13:28 ` [PATCH net-next v4 07/10] selftests: drivers: hw: replace counter upper limit with UINT32_MAX in rmon test Ioana Ciornei
@ 2026-03-26 13:28 ` Ioana Ciornei
2026-03-30 12:01 ` Petr Machata
2026-03-26 13:28 ` [PATCH net-next v4 09/10] selftests: drivers: hw: update ethtool_rmon to work with a single local interface Ioana Ciornei
` (2 subsequent siblings)
10 siblings, 1 reply; 26+ messages in thread
From: Ioana Ciornei @ 2026-03-26 13:28 UTC (permalink / raw)
To: netdev
Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Simon Horman, linux-kernel, petrm, willemb,
linux-kselftest
Update the ethtool_rmon.sh test so that it uses the KTAP format for its
output. This is achieved by using the helpers found in ktap_helpers.sh.
An example output can be found below.
$ ./ethtool_rmon.sh endpmac3 endpmac4
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
Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
---
Changes in v4:
- patch is added in this version so that ethtool_rmon.sh is converted to
KTAP output
.../selftests/drivers/net/hw/ethtool_rmon.sh | 24 ++++++++++++-------
1 file changed, 16 insertions(+), 8 deletions(-)
diff --git a/tools/testing/selftests/drivers/net/hw/ethtool_rmon.sh b/tools/testing/selftests/drivers/net/hw/ethtool_rmon.sh
index f290ce1832f1..ed81bdc33536 100755
--- a/tools/testing/selftests/drivers/net/hw/ethtool_rmon.sh
+++ b/tools/testing/selftests/drivers/net/hw/ethtool_rmon.sh
@@ -11,10 +11,12 @@ ALL_TESTS="
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
@@ -76,29 +78,28 @@ rmon_histogram()
local nbuckets=0
local step=
- RET=0
-
while read -r -a bucket; do
- step="$set-pkts${bucket[0]}to${bucket[1]} on $iface"
+ step="$set-pkts${bucket[0]}to${bucket[1]}"
for if in "$iface" "$neigh"; do
if ! ensure_mtu "$if" "${bucket[0]}"; then
- log_test_xfail "$if does not support the required MTU for $step"
+ 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
- check_err 1 "$step failed"
+ ktap_test_fail "$TEST_NAME.$step"
return 1
fi
- log_test "$step"
+ ktap_test_pass "$TEST_NAME.$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_xfail "$iface does not support $set histogram counters"
+ ktap_print_msg "$iface does not support $set histogram counters"
return
fi
}
@@ -139,9 +140,16 @@ cleanup()
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
-exit "$EXIT_STATUS"
+ktap_finished
--
2.25.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH net-next v4 09/10] selftests: drivers: hw: update ethtool_rmon to work with a single local interface
2026-03-26 13:28 [PATCH net-next v4 00/10] selftests: drivers: bash support for remote traffic generators Ioana Ciornei
` (7 preceding siblings ...)
2026-03-26 13:28 ` [PATCH net-next v4 08/10] selftests: drivers: hw: move to KTAP output Ioana Ciornei
@ 2026-03-26 13:28 ` Ioana Ciornei
2026-03-26 13:28 ` [PATCH net-next v4 10/10] selftests: drivers: hw: add test for the ethtool standard counters Ioana Ciornei
2026-03-26 19:03 ` [PATCH net-next v4 00/10] selftests: drivers: bash support for remote traffic generators Jakub Kicinski
10 siblings, 0 replies; 26+ messages in thread
From: Ioana Ciornei @ 2026-03-26 13:28 UTC (permalink / raw)
To: netdev
Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Simon Horman, linux-kernel, petrm, willemb,
linux-kselftest
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>
---
Changes in v4:
- set DRIVER_TEST_CONFORMANT to yes
- update the commit message to reflect the current output
- split some more lines to 80 chars
Changes in v3:
- none
Changes in v2:
- patch is new
.../selftests/drivers/net/hw/ethtool_rmon.sh | 30 +++++++++++--------
1 file changed, 17 insertions(+), 13 deletions(-)
diff --git a/tools/testing/selftests/drivers/net/hw/ethtool_rmon.sh b/tools/testing/selftests/drivers/net/hw/ethtool_rmon.sh
index ed81bdc33536..2ec19edddfaa 100755
--- a/tools/testing/selftests/drivers/net/hw/ethtool_rmon.sh
+++ b/tools/testing/selftests/drivers/net/hw/ethtool_rmon.sh
@@ -8,6 +8,7 @@ ALL_TESTS="
rmon_tx_histogram
"
+: "${DRIVER_TEST_CONFORMANT:=yes}"
NUM_NETIFS=2
lib_dir=$(dirname "$0")
source "$lib_dir"/../../../net/forwarding/lib.sh
@@ -27,9 +28,11 @@ ensure_mtu()
local required=$((len - ETH_HLEN - ETH_FCS_LEN))
local current
- current=$(ip -j link show dev "$iface" | jq -r '.[0].mtu')
+ current=$(run_on "$iface" \
+ ip -j link show dev "$iface" | jq -r '.[0].mtu')
if [ "$current" -lt "$required" ]; then
- ip link set dev "$iface" mtu "$required" || return 1
+ run_on "$iface" ip link set dev "$iface" mtu "$required" \
+ || return 1
fi
}
@@ -52,15 +55,17 @@ bucket_test()
len=$((len - ETH_FCS_LEN))
len=$((len > 0 ? len : 0))
- before=$(ethtool --json -S "$iface" --groups rmon | \
+ 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
- "$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
+ 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=$(ethtool --json -S "$iface" --groups rmon | \
+ after=$(run_on "$iface" ethtool --json -S "$iface" --groups rmon | \
jq -r ".[0].rmon[\"${set}-pktsNtoM\"][$bucket].val")
delta=$((after - before))
@@ -95,7 +100,7 @@ rmon_histogram()
fi
ktap_test_pass "$TEST_NAME.$step"
nbuckets=$((nbuckets + 1))
- done < <(ethtool --json -S "$iface" --groups rmon | \
+ 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
@@ -120,9 +125,8 @@ setup_prepare()
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
+ netif_mtu["$iface"]=$(run_on "$iface" \
+ ip -j link show dev "$iface" | jq -r '.[0].mtu')
done
}
@@ -130,10 +134,10 @@ cleanup()
{
pre_cleanup
+ # Do not bring down the interfaces, just configure the initial MTU
for iface in "$h2" "$h1"; do
- ip link set dev "$iface" \
- mtu "${netif_mtu[$iface]}" \
- down
+ run_on "$iface" ip link set dev "$iface" \
+ mtu "${netif_mtu[$iface]}"
done
}
--
2.25.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH net-next v4 10/10] selftests: drivers: hw: add test for the ethtool standard counters
2026-03-26 13:28 [PATCH net-next v4 00/10] selftests: drivers: bash support for remote traffic generators Ioana Ciornei
` (8 preceding siblings ...)
2026-03-26 13:28 ` [PATCH net-next v4 09/10] selftests: drivers: hw: update ethtool_rmon to work with a single local interface Ioana Ciornei
@ 2026-03-26 13:28 ` Ioana Ciornei
2026-03-30 12:03 ` Petr Machata
2026-03-26 19:03 ` [PATCH net-next v4 00/10] selftests: drivers: bash support for remote traffic generators Jakub Kicinski
10 siblings, 1 reply; 26+ messages in thread
From: Ioana Ciornei @ 2026-03-26 13:28 UTC (permalink / raw)
To: netdev
Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Simon Horman, linux-kernel, petrm, willemb,
linux-kselftest
Add a new selftest - ethtool_std_stats.sh - which validates the
eth-ctrl, eth-mac and pause standard statistics exported by an
interface. Collision related eth-mac counters as well as the error ones
will be checked against zero since that is the most likely correct
scenario.
The central part of this patch is the traffic_test() function which
gathers the 'before' counter values, sends a batch of traffic and then
interrogates again the same counters in order to determine if the delta
is on target. The function receives an array through which the caller
can request what counters to be interrogated and, for each of them, what
is their target delta value.
The output from this selftest looks as follows on a LX2160ARDB board:
$ ./run_kselftest.sh -t drivers/net/hw:ethtool_std_stats.sh
TAP version 13
1..1
# timeout set to 0
# selftests: drivers/net/hw: ethtool_std_stats.sh
# TAP version 13
# 1..26
# ok 1 ethtool_std_stats.eth-ctrl-MACControlFramesTransmitted
# ok 2 ethtool_std_stats.eth-ctrl-MACControlFramesReceived
# ok 3 ethtool_std_stats.eth-mac-FrameCheckSequenceErrors
# ok 4 ethtool_std_stats.eth-mac-AlignmentErrors
# ok 5 ethtool_std_stats.eth-mac-FramesLostDueToIntMACXmitError
# ok 6 ethtool_std_stats.eth-mac-CarrierSenseErrors # SKIP
# ok 7 ethtool_std_stats.eth-mac-FramesLostDueToIntMACRcvError
# ok 8 ethtool_std_stats.eth-mac-InRangeLengthErrors # SKIP
# ok 9 ethtool_std_stats.eth-mac-OutOfRangeLengthField # SKIP
# ok 10 ethtool_std_stats.eth-mac-FrameTooLongErrors # SKIP
# ok 11 ethtool_std_stats.eth-mac-FramesAbortedDueToXSColls # SKIP
# ok 12 ethtool_std_stats.eth-mac-SingleCollisionFrames # SKIP
# ok 13 ethtool_std_stats.eth-mac-MultipleCollisionFrames # SKIP
# ok 14 ethtool_std_stats.eth-mac-FramesWithDeferredXmissions # SKIP
# ok 15 ethtool_std_stats.eth-mac-LateCollisions # SKIP
# ok 16 ethtool_std_stats.eth-mac-FramesWithExcessiveDeferral # SKIP
# ok 17 ethtool_std_stats.eth-mac-BroadcastFramesXmittedOK
# ok 18 ethtool_std_stats.eth-mac-OctetsTransmittedOK
# ok 19 ethtool_std_stats.eth-mac-BroadcastFramesReceivedOK
# ok 20 ethtool_std_stats.eth-mac-OctetsReceivedOK
# ok 21 ethtool_std_stats.eth-mac-FramesTransmittedOK
# ok 22 ethtool_std_stats.eth-mac-MulticastFramesXmittedOK
# ok 23 ethtool_std_stats.eth-mac-FramesReceivedOK
# ok 24 ethtool_std_stats.eth-mac-MulticastFramesReceivedOK
# ok 25 ethtool_std_stats.pause-tx_pause_frames
# ok 26 ethtool_std_stats.pause-rx_pause_frames
# # 10 skipped test(s) detected. Consider enabling relevant config options to improve coverage.
# # Totals: pass:16 fail:0 xfail:0 xpass:0 skip:10 error:0
ok 1 selftests: drivers/net/hw: ethtool_std_stats.sh
Please note that not all MACs are counting the software injected pause
frames as real Tx pause. For example, on a LS1028ARDB the selftest
output will reflect the fact that neither the ENETC MAC, nor the Felix
switch MAC are able to detect Tx pause frames injected by software.
$ ./run_kselftest.sh -t drivers/net/hw:ethtool_std_stats.sh
(...)
# # software sent pause frames not detected
# ok 25 ethtool_std_stats.pause-tx_pause_frames # XFAIL
# ok 26 ethtool_std_stats.pause-rx_pause_frames
Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
---
Changes in v4:
- move to a the KTAP format output by using ktap_helpers.sh
- update commit message to reflect the current output
- use DRIVER_TEST_CONFORMANT
Changes in v3:
- none
Changes in v2:
- Use the new run_on helper
- No longer checking that each counter has a 1% tolerance against the
target. The only upper limit is UINT32_MAX.
- Check that both the error counters and the collision related ones are
zero since this is the most probable scenario (we don't expect errors
with the traffic that we are sending).
- Removed any checks performed on the remot interface counters since
that is being used only as a traffic generator.
.../testing/selftests/drivers/net/hw/Makefile | 1 +
.../drivers/net/hw/ethtool_std_stats.sh | 206 ++++++++++++++++++
2 files changed, 207 insertions(+)
create mode 100755 tools/testing/selftests/drivers/net/hw/ethtool_std_stats.sh
diff --git a/tools/testing/selftests/drivers/net/hw/Makefile b/tools/testing/selftests/drivers/net/hw/Makefile
index 3c97dac9baaa..442dba3d6a03 100644
--- a/tools/testing/selftests/drivers/net/hw/Makefile
+++ b/tools/testing/selftests/drivers/net/hw/Makefile
@@ -26,6 +26,7 @@ TEST_PROGS = \
ethtool_extended_state.sh \
ethtool_mm.sh \
ethtool_rmon.sh \
+ ethtool_std_stats.sh \
gro_hw.py \
hw_stats_l3.sh \
hw_stats_l3_gre.sh \
diff --git a/tools/testing/selftests/drivers/net/hw/ethtool_std_stats.sh b/tools/testing/selftests/drivers/net/hw/ethtool_std_stats.sh
new file mode 100755
index 000000000000..c085d2a4c989
--- /dev/null
+++ b/tools/testing/selftests/drivers/net/hw/ethtool_std_stats.sh
@@ -0,0 +1,206 @@
+#!/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="
+ test_eth_ctrl_stats
+ test_eth_mac_stats
+ test_pause_stats
+"
+: "${DRIVER_TEST_CONFORMANT:=yes}"
+STABLE_MAC_ADDRS=yes
+NUM_NETIFS=2
+lib_dir=$(dirname "$0")
+# shellcheck source=./../../../net/forwarding/lib.sh
+source "$lib_dir"/../../../net/forwarding/lib.sh
+# shellcheck source=./../../../kselftest/ktap_helpers.sh
+source "$lib_dir"/../../../kselftest/ktap_helpers.sh
+
+UINT32_MAX=$((2**32 - 1))
+SUBTESTS=0
+TEST_NAME=$(basename "$0" .sh)
+
+traffic_test()
+{
+ local iface=$1; shift
+ local neigh=$1; shift
+ local num_tx=$1; shift
+ local pkt_format="$1"; shift
+ local -a counters=("$@")
+ local int grp cnt target exact_check
+ local before after delta
+ local num_rx=$((num_tx * 2))
+ local xfail_message
+ local src="aggregate"
+ local i
+
+ for i in "${!counters[@]}"; do
+ read -r int grp cnt target exact_check xfail_message \
+ <<< "${counters[$i]}"
+
+ before[i]=$(ethtool_std_stats_get "$int" "$grp" "$cnt" "$src")
+ done
+
+ # shellcheck disable=SC2086 # needs split options
+ run_on "$iface" "$MZ" "$iface" -q -c "$num_tx" $pkt_format
+
+ # shellcheck disable=SC2086 # needs split options
+ run_on "$neigh" "$MZ" "$neigh" -q -c "$num_rx" $pkt_format
+
+ for i in "${!counters[@]}"; do
+ read -r int grp cnt target exact_check xfail_message \
+ <<< "${counters[$i]}"
+
+ after[i]=$(ethtool_std_stats_get "$int" "$grp" "$cnt" "$src")
+ if [[ "${after[$i]}" == "null" ]]; then
+ ktap_test_skip "$TEST_NAME.$grp-$cnt"
+ continue;
+ fi
+
+ delta=$((after[i] - before[i]))
+
+ if [ "$exact_check" -ne 0 ]; then
+ [ "$delta" -eq "$target" ]
+ else
+ [ "$delta" -ge "$target" ] && \
+ [ "$delta" -le "$UINT32_MAX" ]
+ fi
+ err="$?"
+
+ if [[ $err != 0 ]] && [[ -n $xfail_message ]]; then
+ ktap_print_msg "$xfail_message"
+ ktap_test_xfail "$TEST_NAME.$grp-$cnt"
+ continue;
+ fi
+
+ if [[ $err != 0 ]]; then
+ ktap_print_msg "$grp-$cnt is not valid on $int (expected $target, got $delta)"
+ ktap_test_fail "$TEST_NAME.$grp-$cnt"
+ else
+ ktap_test_pass "$TEST_NAME.$grp-$cnt"
+ fi
+ done
+}
+
+test_eth_ctrl_stats()
+{
+ local pkt_format="-a own -b bcast 88:08 -p 64"
+ local num_pkts=1000
+ local -a counters
+
+ counters=("$h1 eth-ctrl MACControlFramesTransmitted $num_pkts 0")
+ traffic_test "$h1" "$h2" "$num_pkts" "$pkt_format" \
+ "${counters[@]}"
+
+ counters=("$h1 eth-ctrl MACControlFramesReceived $num_pkts 0")
+ traffic_test "$h2" "$h1" "$num_pkts" "$pkt_format" \
+ "${counters[@]}"
+}
+SUBTESTS=$((SUBTESTS + 2))
+
+test_eth_mac_stats()
+{
+ local pkt_size=100
+ local pkt_size_fcs=$((pkt_size + 4))
+ local bcast_pkt_format="-a own -b bcast -p $pkt_size"
+ local mcast_pkt_format="-a own -b 01:00:5E:00:00:01 -p $pkt_size"
+ local num_pkts=2000
+ local octets=$((pkt_size_fcs * num_pkts))
+ local -a counters error_cnt collision_cnt
+
+ # Error counters should be exactly zero
+ counters=("$h1 eth-mac FrameCheckSequenceErrors 0 1"
+ "$h1 eth-mac AlignmentErrors 0 1"
+ "$h1 eth-mac FramesLostDueToIntMACXmitError 0 1"
+ "$h1 eth-mac CarrierSenseErrors 0 1"
+ "$h1 eth-mac FramesLostDueToIntMACRcvError 0 1"
+ "$h1 eth-mac InRangeLengthErrors 0 1"
+ "$h1 eth-mac OutOfRangeLengthField 0 1"
+ "$h1 eth-mac FrameTooLongErrors 0 1"
+ "$h1 eth-mac FramesAbortedDueToXSColls 0 1")
+ traffic_test "$h1" "$h2" "$num_pkts" "$bcast_pkt_format" \
+ "${counters[@]}"
+
+ # Collision related counters should also be zero
+ counters=("$h1 eth-mac SingleCollisionFrames 0 1"
+ "$h1 eth-mac MultipleCollisionFrames 0 1"
+ "$h1 eth-mac FramesWithDeferredXmissions 0 1"
+ "$h1 eth-mac LateCollisions 0 1"
+ "$h1 eth-mac FramesWithExcessiveDeferral 0 1")
+ traffic_test "$h1" "$h2" "$num_pkts" "$bcast_pkt_format" \
+ "${counters[@]}"
+
+ counters=("$h1 eth-mac BroadcastFramesXmittedOK $num_pkts 0"
+ "$h1 eth-mac OctetsTransmittedOK $octets 0")
+ traffic_test "$h1" "$h2" "$num_pkts" "$bcast_pkt_format" \
+ "${counters[@]}"
+
+ counters=("$h1 eth-mac BroadcastFramesReceivedOK $num_pkts 0"
+ "$h1 eth-mac OctetsReceivedOK $octets 0")
+ traffic_test "$h2" "$h1" "$num_pkts" "$bcast_pkt_format" \
+ "${counters[@]}"
+
+ counters=("$h1 eth-mac FramesTransmittedOK $num_pkts 0"
+ "$h1 eth-mac MulticastFramesXmittedOK $num_pkts 0")
+ traffic_test "$h1" "$h2" "$num_pkts" "$mcast_pkt_format" \
+ "${counters[@]}"
+
+ counters=("$h1 eth-mac FramesReceivedOK $num_pkts 0"
+ "$h1 eth-mac MulticastFramesReceivedOK $num_pkts 0")
+ traffic_test "$h2" "$h1" "$num_pkts" "$mcast_pkt_format" \
+ "${counters[@]}"
+}
+SUBTESTS=$((SUBTESTS + 22))
+
+test_pause_stats()
+{
+ local pkt_format="-a own -b 01:80:c2:00:00:01 88:08:00:01:00:01"
+ local xfail_message="software sent pause frames not detected"
+ local num_pkts=2000
+ local -a counters
+ local int
+ local i
+
+ # Check that there is pause frame support
+ for ((i = 1; i <= NUM_NETIFS; ++i)); do
+ int="${NETIFS[p$i]}"
+ if ! run_on "$int" ethtool -I --json -a "$int" > /dev/null 2>&1; then
+ ktap_test_skip "$TEST_NAME.tx_pause_frames"
+ ktap_test_skip "$TEST_NAME.rx_pause_frames"
+ return
+ fi
+ done
+
+ counters=("$h1 pause tx_pause_frames $num_pkts 0 $xfail_message")
+ traffic_test "$h1" "$h2" "$num_pkts" "$pkt_format" \
+ "${counters[@]}"
+
+ counters=("$h1 pause rx_pause_frames $num_pkts 0")
+ traffic_test "$h2" "$h1" "$num_pkts" "$pkt_format" \
+ "${counters[@]}"
+}
+SUBTESTS=$((SUBTESTS + 2))
+
+setup_prepare()
+{
+ local iface
+
+ h1=${NETIFS[p1]}
+ h2=${NETIFS[p2]}
+
+ h2_mac=$(mac_get "$h2")
+}
+
+ktap_print_header
+ktap_set_plan $SUBTESTS
+
+check_ethtool_counter_group_support
+trap cleanup EXIT
+
+setup_prepare
+setup_wait
+
+tests_run
+
+ktap_finished
--
2.25.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* Re: [PATCH net-next v4 00/10] selftests: drivers: bash support for remote traffic generators
2026-03-26 13:28 [PATCH net-next v4 00/10] selftests: drivers: bash support for remote traffic generators Ioana Ciornei
` (9 preceding siblings ...)
2026-03-26 13:28 ` [PATCH net-next v4 10/10] selftests: drivers: hw: add test for the ethtool standard counters Ioana Ciornei
@ 2026-03-26 19:03 ` Jakub Kicinski
2026-03-27 7:32 ` Ioana Ciornei
10 siblings, 1 reply; 26+ messages in thread
From: Jakub Kicinski @ 2026-03-26 19:03 UTC (permalink / raw)
To: Ioana Ciornei
Cc: netdev, Andrew Lunn, David S. Miller, Eric Dumazet, Paolo Abeni,
Simon Horman, linux-kernel, petrm, willemb, linux-kselftest
On Thu, 26 Mar 2026 15:28:18 +0200 Ioana Ciornei wrote:
> This patch set aims to add the necessary support so that bash written
> selftests are also able to easily run with a remote traffic generator
> system, either be it in another netns or one accessible through ssh.
>
> This patch set is a result of the discussion from v1:
> https://lore.kernel.org/all/20260303084330.340b6459@kernel.org/
> Even though the python infrastructure is already established, some
> things are easier in bash and it would be a shame to leave behind the
> bash tests that we already have.
I think this introduces a bunch of regressions, eg:
https://netdev-ctrl.bots.linux.dev/logs/vmksft/forwarding/results/575622/4-local-termination-sh/stdout
https://netdev-ctrl.bots.linux.dev/logs/vmksft/netdevsim/results/575802/18-netcons-resume-sh/stdout
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH net-next v4 00/10] selftests: drivers: bash support for remote traffic generators
2026-03-26 19:03 ` [PATCH net-next v4 00/10] selftests: drivers: bash support for remote traffic generators Jakub Kicinski
@ 2026-03-27 7:32 ` Ioana Ciornei
2026-03-28 0:24 ` Jakub Kicinski
0 siblings, 1 reply; 26+ messages in thread
From: Ioana Ciornei @ 2026-03-27 7:32 UTC (permalink / raw)
To: Jakub Kicinski
Cc: netdev, Andrew Lunn, David S. Miller, Eric Dumazet, Paolo Abeni,
Simon Horman, linux-kernel, petrm, willemb, linux-kselftest
On Thu, Mar 26, 2026 at 12:03:42PM -0700, Jakub Kicinski wrote:
> On Thu, 26 Mar 2026 15:28:18 +0200 Ioana Ciornei wrote:
> > This patch set aims to add the necessary support so that bash written
> > selftests are also able to easily run with a remote traffic generator
> > system, either be it in another netns or one accessible through ssh.
> >
> > This patch set is a result of the discussion from v1:
> > https://lore.kernel.org/all/20260303084330.340b6459@kernel.org/
> > Even though the python infrastructure is already established, some
> > things are easier in bash and it would be a shame to leave behind the
> > bash tests that we already have.
>
> I think this introduces a bunch of regressions, eg:
>
> https://netdev-ctrl.bots.linux.dev/logs/vmksft/forwarding/results/575622/4-local-termination-sh/stdout
>
> https://netdev-ctrl.bots.linux.dev/logs/vmksft/netdevsim/results/575802/18-netcons-resume-sh/stdout
I cannot reproduce this unfortunately. For example, local_termination.sh
gives me the following result with the exact patches that I submitted.
Any idea on what might be the difference?
root@localhost:~/ksft-net-drv# ./run_kselftest.sh -t net/forwarding:local_termination.sh
[71318.022491] kselftest: Running tests in net/forwarding
TAP version 13
1..1
# timeout set to 0
# selftests: net/forwarding: local_termination.sh
# TEST: veth1: Unicast IPv4 to primary MAC address [ OK ]
# TEST: veth1: Unicast IPv4 to macvlan MAC address [ OK ]
# TEST: veth1: Unicast IPv4 to unknown MAC address [ OK ]
# TEST: veth1: Unicast IPv4 to unknown MAC address, promisc [ OK ]
# TEST: veth1: Unicast IPv4 to unknown MAC address, allmulti [ OK ]
# TEST: veth1: Multicast IPv4 to joined group [ OK ]
# TEST: veth1: Multicast IPv4 to unknown group [XFAIL]
# reception succeeded, but should have failed
# TEST: veth1: Multicast IPv4 to unknown group, promisc [ OK ]
# TEST: veth1: Multicast IPv4 to unknown group, allmulti [ OK ]
# TEST: veth1: Multicast IPv6 to joined group [ OK ]
# TEST: veth1: Multicast IPv6 to unknown group [XFAIL]
# reception succeeded, but should have failed
# TEST: veth1: Multicast IPv6 to unknown group, promisc [ OK ]
# TEST: veth1: Multicast IPv6 to unknown group, allmulti [ OK ]
# TEST: veth1: Link-local STP BPDU [ OK ]
# TEST: veth1: Link-local LLDP [ OK ]
# TEST: veth1: 1588v2 over L2 transport, Sync [ OK ]
# TEST: veth1: 1588v2 over L2 transport, Follow-Up [ OK ]
# TEST: veth1: 1588v2 over L2 transport, Peer Delay Request [ OK ]
# TEST: veth1: 1588v2 over IPv4, Sync [ OK ]
# TEST: veth1: 1588v2 over IPv4, Follow-Up [ OK ]
# TEST: veth1: 1588v2 over IPv4, Peer Delay Request [ OK ]
# TEST: veth1: 1588v2 over IPv6, Sync [ OK ]
# TEST: veth1: 1588v2 over IPv6, Follow-Up [ OK ]
# TEST: veth1: 1588v2 over IPv6, Peer Delay Request [ OK ]
# TEST: vlan_filtering=0 bridge: Unicast IPv4 to primary MAC address [ OK ]
# TEST: vlan_filtering=0 bridge: Unicast IPv4 to macvlan MAC address [ OK ]
# TEST: vlan_filtering=0 bridge: Unicast IPv4 to unknown MAC address [ OK ]
# TEST: vlan_filtering=0 bridge: Unicast IPv4 to unknown MAC address, promisc [ OK ]
# TEST: vlan_filtering=0 bridge: Unicast IPv4 to unknown MAC address, allmulti [ OK ]
# TEST: vlan_filtering=0 bridge: Multicast IPv4 to joined group [ OK ]
# TEST: vlan_filtering=0 bridge: Multicast IPv4 to unknown group [XFAIL]
# reception succeeded, but should have failed
# TEST: vlan_filtering=0 bridge: Multicast IPv4 to unknown group, promisc [ OK ]
# TEST: vlan_filtering=0 bridge: Multicast IPv4 to unknown group, allmulti [ OK ]
# TEST: vlan_filtering=0 bridge: Multicast IPv6 to joined group [ OK ]
# TEST: vlan_filtering=0 bridge: Multicast IPv6 to unknown group [XFAIL]
# reception succeeded, but should have failed
# TEST: vlan_filtering=0 bridge: Multicast IPv6 to unknown group, promisc [ OK ]
# TEST: vlan_filtering=0 bridge: Multicast IPv6 to unknown group, allmulti [ OK ]
# TEST: vlan_filtering=0 bridge: Link-local STP BPDU [ OK ]
# TEST: vlan_filtering=1 bridge: Unicast IPv4 to primary MAC address [ OK ]
# TEST: vlan_filtering=1 bridge: Unicast IPv4 to macvlan MAC address [ OK ]
# TEST: vlan_filtering=1 bridge: Unicast IPv4 to unknown MAC address [ OK ]
# TEST: vlan_filtering=1 bridge: Unicast IPv4 to unknown MAC address, promisc [ OK ]
# TEST: vlan_filtering=1 bridge: Unicast IPv4 to unknown MAC address, allmulti [ OK ]
# TEST: vlan_filtering=1 bridge: Multicast IPv4 to joined group [ OK ]
# TEST: vlan_filtering=1 bridge: Multicast IPv4 to unknown group [XFAIL]
# reception succeeded, but should have failed
# TEST: vlan_filtering=1 bridge: Multicast IPv4 to unknown group, promisc [ OK ]
# TEST: vlan_filtering=1 bridge: Multicast IPv4 to unknown group, allmulti [ OK ]
# TEST: vlan_filtering=1 bridge: Multicast IPv6 to joined group [ OK ]
# TEST: vlan_filtering=1 bridge: Multicast IPv6 to unknown group [XFAIL]
# reception succeeded, but should have failed
# TEST: vlan_filtering=1 bridge: Multicast IPv6 to unknown group, promisc [ OK ]
# TEST: vlan_filtering=1 bridge: Multicast IPv6 to unknown group, allmulti [ OK ]
# TEST: vlan_filtering=1 bridge: Link-local STP BPDU [ OK ]
# TEST: VLAN upper: Unicast IPv4 to primary MAC address [ OK ]
# TEST: VLAN upper: Unicast IPv4 to macvlan MAC address [ OK ]
# TEST: VLAN upper: Unicast IPv4 to unknown MAC address [ OK ]
# TEST: VLAN upper: Unicast IPv4 to unknown MAC address, promisc [ OK ]
# TEST: VLAN upper: Unicast IPv4 to unknown MAC address, allmulti [ OK ]
# TEST: VLAN upper: Multicast IPv4 to joined group [ OK ]
# TEST: VLAN upper: Multicast IPv4 to unknown group [XFAIL]
# reception succeeded, but should have failed
# TEST: VLAN upper: Multicast IPv4 to unknown group, promisc [ OK ]
# TEST: VLAN upper: Multicast IPv4 to unknown group, allmulti [ OK ]
# TEST: VLAN upper: Multicast IPv6 to joined group [ OK ]
# TEST: VLAN upper: Multicast IPv6 to unknown group [XFAIL]
# reception succeeded, but should have failed
# TEST: VLAN upper: Multicast IPv6 to unknown group, promisc [ OK ]
# TEST: VLAN upper: Multicast IPv6 to unknown group, allmulti [ OK ]
# TEST: VLAN upper: Link-local STP BPDU [ OK ]
# TEST: VLAN upper: Link-local LLDP [ OK ]
# TEST: VLAN upper: 1588v2 over L2 transport, Sync [ OK ]
# TEST: VLAN upper: 1588v2 over L2 transport, Follow-Up [ OK ]
# TEST: VLAN upper: 1588v2 over L2 transport, Peer Delay Request [ OK ]
# TEST: VLAN upper: 1588v2 over IPv4, Sync [ OK ]
# TEST: VLAN upper: 1588v2 over IPv4, Follow-Up [ OK ]
# TEST: VLAN upper: 1588v2 over IPv4, Peer Delay Request [ OK ]
# TEST: VLAN upper: 1588v2 over IPv6, Sync [ OK ]
# TEST: VLAN upper: 1588v2 over IPv6, Follow-Up [ OK ]
# TEST: VLAN upper: 1588v2 over IPv6, Peer Delay Request [ OK ]
# TEST: VLAN over vlan_filtering=0 bridged port: Unicast IPv4 to primary MAC address [ OK ]
# TEST: VLAN over vlan_filtering=0 bridged port: Unicast IPv4 to macvlan MAC address [ OK ]
# TEST: VLAN over vlan_filtering=0 bridged port: Unicast IPv4 to unknown MAC address [ OK ]
# TEST: VLAN over vlan_filtering=0 bridged port: Unicast IPv4 to unknown MAC address, promisc [ OK ]
# TEST: VLAN over vlan_filtering=0 bridged port: Unicast IPv4 to unknown MAC address, allmulti [ OK ]
# TEST: VLAN over vlan_filtering=0 bridged port: Multicast IPv4 to joined group [ OK ]
# TEST: VLAN over vlan_filtering=0 bridged port: Multicast IPv4 to unknown group [XFAIL]
# reception succeeded, but should have failed
# TEST: VLAN over vlan_filtering=0 bridged port: Multicast IPv4 to unknown group, promisc [ OK ]
# TEST: VLAN over vlan_filtering=0 bridged port: Multicast IPv4 to unknown group, allmulti [ OK ]
# TEST: VLAN over vlan_filtering=0 bridged port: Multicast IPv6 to joined group [ OK ]
# TEST: VLAN over vlan_filtering=0 bridged port: Multicast IPv6 to unknown group [XFAIL]
# reception succeeded, but should have failed
# TEST: VLAN over vlan_filtering=0 bridged port: Multicast IPv6 to unknown group, promisc [ OK ]
# TEST: VLAN over vlan_filtering=0 bridged port: Multicast IPv6 to unknown group, allmulti [ OK ]
# TEST: VLAN over vlan_filtering=0 bridged port: Link-local STP BPDU [ OK ]
# TEST: VLAN over vlan_filtering=0 bridged port: Link-local LLDP [ OK ]
# TEST: VLAN over vlan_filtering=0 bridged port: 1588v2 over L2 transport, Sync [ OK ]
# TEST: VLAN over vlan_filtering=0 bridged port: 1588v2 over L2 transport, Follow-Up [ OK ]
# TEST: VLAN over vlan_filtering=0 bridged port: 1588v2 over L2 transport, Peer Delay Request [ OK ]
# TEST: VLAN over vlan_filtering=0 bridged port: 1588v2 over IPv4, Sync [ OK ]
# TEST: VLAN over vlan_filtering=0 bridged port: 1588v2 over IPv4, Follow-Up [ OK ]
# TEST: VLAN over vlan_filtering=0 bridged port: 1588v2 over IPv4, Peer Delay Request [ OK ]
# TEST: VLAN over vlan_filtering=0 bridged port: 1588v2 over IPv6, Sync [ OK ]
# TEST: VLAN over vlan_filtering=0 bridged port: 1588v2 over IPv6, Follow-Up [ OK ]
# TEST: VLAN over vlan_filtering=0 bridged port: 1588v2 over IPv6, Peer Delay Request [ OK ]
# TEST: VLAN over vlan_filtering=1 bridged port: Unicast IPv4 to primary MAC address [ OK ]
# TEST: VLAN over vlan_filtering=1 bridged port: Unicast IPv4 to macvlan MAC address [ OK ]
# TEST: VLAN over vlan_filtering=1 bridged port: Unicast IPv4 to unknown MAC address [ OK ]
# TEST: VLAN over vlan_filtering=1 bridged port: Unicast IPv4 to unknown MAC address, promisc [ OK ]
# TEST: VLAN over vlan_filtering=1 bridged port: Unicast IPv4 to unknown MAC address, allmulti [ OK ]
# TEST: VLAN over vlan_filtering=1 bridged port: Multicast IPv4 to joined group [ OK ]
# TEST: VLAN over vlan_filtering=1 bridged port: Multicast IPv4 to unknown group [XFAIL]
# reception succeeded, but should have failed
# TEST: VLAN over vlan_filtering=1 bridged port: Multicast IPv4 to unknown group, promisc [ OK ]
# TEST: VLAN over vlan_filtering=1 bridged port: Multicast IPv4 to unknown group, allmulti [ OK ]
# TEST: VLAN over vlan_filtering=1 bridged port: Multicast IPv6 to joined group [ OK ]
# TEST: VLAN over vlan_filtering=1 bridged port: Multicast IPv6 to unknown group [XFAIL]
# reception succeeded, but should have failed
# TEST: VLAN over vlan_filtering=1 bridged port: Multicast IPv6 to unknown group, promisc [ OK ]
# TEST: VLAN over vlan_filtering=1 bridged port: Multicast IPv6 to unknown group, allmulti [ OK ]
# TEST: VLAN over vlan_filtering=1 bridged port: Link-local STP BPDU [ OK ]
# TEST: VLAN over vlan_filtering=1 bridged port: Link-local LLDP [ OK ]
# TEST: VLAN over vlan_filtering=1 bridged port: 1588v2 over L2 transport, Sync [ OK ]
# TEST: VLAN over vlan_filtering=1 bridged port: 1588v2 over L2 transport, Follow-Up [ OK ]
# TEST: VLAN over vlan_filtering=1 bridged port: 1588v2 over L2 transport, Peer Delay Request [ OK ]
# TEST: VLAN over vlan_filtering=1 bridged port: 1588v2 over IPv4, Sync [ OK ]
# TEST: VLAN over vlan_filtering=1 bridged port: 1588v2 over IPv4, Follow-Up [ OK ]
# TEST: VLAN over vlan_filtering=1 bridged port: 1588v2 over IPv4, Peer Delay Request [ OK ]
# TEST: VLAN over vlan_filtering=1 bridged port: 1588v2 over IPv6, Sync [ OK ]
# TEST: VLAN over vlan_filtering=1 bridged port: 1588v2 over IPv6, Follow-Up [ OK ]
# TEST: VLAN over vlan_filtering=1 bridged port: 1588v2 over IPv6, Peer Delay Request [ OK ]
# TEST: VLAN over vlan_filtering=0 bridge: Unicast IPv4 to primary MAC address [ OK ]
# TEST: VLAN over vlan_filtering=0 bridge: Unicast IPv4 to macvlan MAC address [ OK ]
# TEST: VLAN over vlan_filtering=0 bridge: Unicast IPv4 to unknown MAC address [ OK ]
# TEST: VLAN over vlan_filtering=0 bridge: Unicast IPv4 to unknown MAC address, promisc [ OK ]
# TEST: VLAN over vlan_filtering=0 bridge: Unicast IPv4 to unknown MAC address, allmulti [ OK ]
# TEST: VLAN over vlan_filtering=0 bridge: Multicast IPv4 to joined group [ OK ]
# TEST: VLAN over vlan_filtering=0 bridge: Multicast IPv4 to unknown group [XFAIL]
# reception succeeded, but should have failed
# TEST: VLAN over vlan_filtering=0 bridge: Multicast IPv4 to unknown group, promisc [ OK ]
# TEST: VLAN over vlan_filtering=0 bridge: Multicast IPv4 to unknown group, allmulti [ OK ]
# TEST: VLAN over vlan_filtering=0 bridge: Multicast IPv6 to joined group [ OK ]
# TEST: VLAN over vlan_filtering=0 bridge: Multicast IPv6 to unknown group [XFAIL]
# reception succeeded, but should have failed
# TEST: VLAN over vlan_filtering=0 bridge: Multicast IPv6 to unknown group, promisc [ OK ]
# TEST: VLAN over vlan_filtering=0 bridge: Multicast IPv6 to unknown group, allmulti [ OK ]
# TEST: VLAN over vlan_filtering=0 bridge: Link-local STP BPDU [ OK ]
# TEST: VLAN over vlan_filtering=1 bridge: Unicast IPv4 to primary MAC address [ OK ]
# TEST: VLAN over vlan_filtering=1 bridge: Unicast IPv4 to macvlan MAC address [ OK ]
# TEST: VLAN over vlan_filtering=1 bridge: Unicast IPv4 to unknown MAC address [ OK ]
# TEST: VLAN over vlan_filtering=1 bridge: Unicast IPv4 to unknown MAC address, promisc [ OK ]
# TEST: VLAN over vlan_filtering=1 bridge: Unicast IPv4 to unknown MAC address, allmulti [ OK ]
# TEST: VLAN over vlan_filtering=1 bridge: Multicast IPv4 to joined group [ OK ]
# TEST: VLAN over vlan_filtering=1 bridge: Multicast IPv4 to unknown group [XFAIL]
# reception succeeded, but should have failed
# TEST: VLAN over vlan_filtering=1 bridge: Multicast IPv4 to unknown group, promisc [ OK ]
# TEST: VLAN over vlan_filtering=1 bridge: Multicast IPv4 to unknown group, allmulti [ OK ]
# TEST: VLAN over vlan_filtering=1 bridge: Multicast IPv6 to joined group [ OK ]
# TEST: VLAN over vlan_filtering=1 bridge: Multicast IPv6 to unknown group [XFAIL]
# reception succeeded, but should have failed
# TEST: VLAN over vlan_filtering=1 bridge: Multicast IPv6 to unknown group, promisc [ OK ]
# TEST: VLAN over vlan_filtering=1 bridge: Multicast IPv6 to unknown group, allmulti [ OK ]
# TEST: VLAN over vlan_filtering=1 bridge: Link-local STP BPDU [ OK ]
ok 1 selftests: net/forwarding: local_termination.sh
root@localhost:~/ksft-net-drv# cat VERSION
v7.0-rc3-1494-g8122e23405fc
root@localhost:~/git/linux# git log --oneline -11
8122e23405fc (HEAD -> 2026-03-04-net-selftests) selftests: drivers: hw: add test for the ethtool standard counters
120c98910361 selftests: drivers: hw: update ethtool_rmon to work with a single local interface
67eea516922b selftests: drivers: hw: move to KTAP output
4dc0de1901c8 selftests: drivers: hw: replace counter upper limit with UINT32_MAX in rmon test
adf6caeb2d0b selftests: drivers: hw: test rmon counters only on first interface
1ef526c90f90 selftests: drivers: hw: cleanup shellcheck warnings in the rmon test
a5a27ccb4231 selftests: net: update some helpers to use run_on
ca2fe56c8938 selftests: net: extend lib.sh to parse drivers/net/net.config
dc88ab221117 selftests: net: add helpers for running a command on other targets
8bc9c8a32701 selftests: forwarding: extend ethtool_std_stats_get with pause statistics
b08a76290c4e Merge branch 'net-dpaa2-mac-export-standard-statistics'
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH net-next v4 00/10] selftests: drivers: bash support for remote traffic generators
2026-03-27 7:32 ` Ioana Ciornei
@ 2026-03-28 0:24 ` Jakub Kicinski
2026-03-30 10:38 ` Petr Machata
0 siblings, 1 reply; 26+ messages in thread
From: Jakub Kicinski @ 2026-03-28 0:24 UTC (permalink / raw)
To: Ioana Ciornei
Cc: netdev, Andrew Lunn, David S. Miller, Eric Dumazet, Paolo Abeni,
Simon Horman, linux-kernel, petrm, willemb, linux-kselftest
On Fri, 27 Mar 2026 09:32:22 +0200 Ioana Ciornei wrote:
> On Thu, Mar 26, 2026 at 12:03:42PM -0700, Jakub Kicinski wrote:
> > On Thu, 26 Mar 2026 15:28:18 +0200 Ioana Ciornei wrote:
> > > This patch set aims to add the necessary support so that bash written
> > > selftests are also able to easily run with a remote traffic generator
> > > system, either be it in another netns or one accessible through ssh.
> > >
> > > This patch set is a result of the discussion from v1:
> > > https://lore.kernel.org/all/20260303084330.340b6459@kernel.org/
> > > Even though the python infrastructure is already established, some
> > > things are easier in bash and it would be a shame to leave behind the
> > > bash tests that we already have.
> >
> > I think this introduces a bunch of regressions, eg:
> >
> > https://netdev-ctrl.bots.linux.dev/logs/vmksft/forwarding/results/575622/4-local-termination-sh/stdout
> >
> > https://netdev-ctrl.bots.linux.dev/logs/vmksft/netdevsim/results/575802/18-netcons-resume-sh/stdout
>
> I cannot reproduce this unfortunately. For example, local_termination.sh
> gives me the following result with the exact patches that I submitted.
> Any idea on what might be the difference?
Hm, the system that runs this on our end is:
# cat /etc/redhat-release
Fedora release 43 (Forty Three)
And it has this added on top of default install:
# cat /etc/systemd/network/99-default.link
[Match]
OriginalName=*
[Link]
NamePolicy=keep kernel database onboard slot path
AlternativeNamesPolicy=database onboard slot path mac
MACAddressPolicy=none
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH net-next v4 00/10] selftests: drivers: bash support for remote traffic generators
2026-03-28 0:24 ` Jakub Kicinski
@ 2026-03-30 10:38 ` Petr Machata
2026-03-30 11:10 ` Petr Machata
2026-03-30 11:11 ` Ioana Ciornei
0 siblings, 2 replies; 26+ messages in thread
From: Petr Machata @ 2026-03-30 10:38 UTC (permalink / raw)
To: Jakub Kicinski
Cc: Ioana Ciornei, netdev, Andrew Lunn, David S. Miller,
Eric Dumazet, Paolo Abeni, Simon Horman, linux-kernel, petrm,
willemb, linux-kselftest
Jakub Kicinski <kuba@kernel.org> writes:
> On Fri, 27 Mar 2026 09:32:22 +0200 Ioana Ciornei wrote:
>> On Thu, Mar 26, 2026 at 12:03:42PM -0700, Jakub Kicinski wrote:
>> > On Thu, 26 Mar 2026 15:28:18 +0200 Ioana Ciornei wrote:
>> > > This patch set aims to add the necessary support so that bash written
>> > > selftests are also able to easily run with a remote traffic generator
>> > > system, either be it in another netns or one accessible through ssh.
>> > >
>> > > This patch set is a result of the discussion from v1:
>> > > https://lore.kernel.org/all/20260303084330.340b6459@kernel.org/
>> > > Even though the python infrastructure is already established, some
>> > > things are easier in bash and it would be a shame to leave behind the
>> > > bash tests that we already have.
>> >
>> > I think this introduces a bunch of regressions, eg:
>> >
>> > https://netdev-ctrl.bots.linux.dev/logs/vmksft/forwarding/results/575622/4-local-termination-sh/stdout
>> >
>> > https://netdev-ctrl.bots.linux.dev/logs/vmksft/netdevsim/results/575802/18-netcons-resume-sh/stdout
>>
>> I cannot reproduce this unfortunately. For example, local_termination.sh
>> gives me the following result with the exact patches that I submitted.
>> Any idea on what might be the difference?
>
> Hm, the system that runs this on our end is:
>
> # cat /etc/redhat-release
> Fedora release 43 (Forty Three)
>
> And it has this added on top of default install:
>
> # cat /etc/systemd/network/99-default.link
> [Match]
> OriginalName=*
>
> [Link]
> NamePolicy=keep kernel database onboard slot path
> AlternativeNamesPolicy=database onboard slot path mac
> MACAddressPolicy=none
The observed issues are consistent with TARGETS being defined, but not
an array:
$ declare -A T
$ T=([a.100]=b)
$ U=foo
$ if declare -p T &>/dev/null; then echo "${T[a.100]}"; else echo fail; fi
b
$ if declare -p U &>/dev/null; then echo "${U[a.100]}"; else echo fail; fi
bash: a.100: syntax error: invalid arithmetic operator (error token is ".100")
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH net-next v4 02/10] selftests: net: add helpers for running a command on other targets
2026-03-26 13:28 ` [PATCH net-next v4 02/10] selftests: net: add helpers for running a command on other targets Ioana Ciornei
@ 2026-03-30 11:02 ` Petr Machata
2026-03-30 11:32 ` Petr Machata
0 siblings, 1 reply; 26+ messages in thread
From: Petr Machata @ 2026-03-30 11:02 UTC (permalink / raw)
To: Ioana Ciornei
Cc: netdev, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Simon Horman, linux-kernel, petrm,
willemb, linux-kselftest
Ioana Ciornei <ioana.ciornei@nxp.com> writes:
> Add a couple of helpers which can be used by tests which need to run a
> specific bash command on a different target than the local system, be it
> either another netns or a remote system accessible through ssh.
>
> The __run_on() function is passed through $1 the target on which the
> command should be executed while run_on() is passed the name of the
> interface that is then used to retrieve the target from the TARGETS
> array.
>
> Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
> ---
> Changes in v4:
> - reworked the helpers so that no global variable is used and
> information is passed only through parameters
> Changes in v3:
> - s/TARGET/CUR_TARGET
> - always fallback on running a command locally when either TARGETS is
> not declared or there is no entry for a specific interface
> Changes in v2:
> - patch is new
>
> tools/testing/selftests/net/lib.sh | 38 ++++++++++++++++++++++++++++++
> 1 file changed, 38 insertions(+)
>
> diff --git a/tools/testing/selftests/net/lib.sh b/tools/testing/selftests/net/lib.sh
> index b40694573f4c..6c0d613a4de5 100644
> --- a/tools/testing/selftests/net/lib.sh
> +++ b/tools/testing/selftests/net/lib.sh
> @@ -670,3 +670,41 @@ cmd_jq()
> # return success only in case of non-empty output
> [ ! -z "$output" ]
> }
> +
> +__run_on()
> +{
> + local target=$1; shift
> + local type args
> +
> + IFS=':' read -r type args <<< "$target"
> +
> + case "$type" in
> + netns)
> + # Execute command in network namespace
> + # args contains the namespace name
> + ip netns exec "$args" "$@"
> + ;;
> + ssh)
> + # Execute command via SSH args contains user@host
> + ssh -n "$args" "$@"
> + ;;
> + local|*)
> + # Execute command locally. This is also the fallback
> + # case for when the interface's target is not found in
> + # the TARGETS array.
> + "$@"
> + ;;
> + esac
> +}
> +
> +run_on()
> +{
> + local iface=$1; shift
> + local target="local:"
> +
> + if declare -p TARGETS &>/dev/null; then
> + target="${TARGETS[$iface]}"
So I think Jakub's runs fail because there's a shell export somewhere
that gets inherited through make to the launched test. I guess it would
be enough for the test to validate that TARGETS is an array, because
those don't get inherited.
Is there a reason not to reuse DRIVER_TEST_CONFORMANT as a tell though?
> + fi
> +
> + __run_on "$target" "$@"
> +}
Does the latter helper need to be in net/lib.sh? Since it uses TARGETS,
which are a forwarding/lib.sh concept, it seems misplaced there.
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH net-next v4 00/10] selftests: drivers: bash support for remote traffic generators
2026-03-30 10:38 ` Petr Machata
@ 2026-03-30 11:10 ` Petr Machata
2026-03-30 11:11 ` Ioana Ciornei
1 sibling, 0 replies; 26+ messages in thread
From: Petr Machata @ 2026-03-30 11:10 UTC (permalink / raw)
To: Petr Machata
Cc: Jakub Kicinski, Ioana Ciornei, netdev, Andrew Lunn,
David S. Miller, Eric Dumazet, Paolo Abeni, Simon Horman,
linux-kernel, willemb, linux-kselftest
Petr Machata <petrm@nvidia.com> writes:
> Jakub Kicinski <kuba@kernel.org> writes:
>
>> On Fri, 27 Mar 2026 09:32:22 +0200 Ioana Ciornei wrote:
>>> On Thu, Mar 26, 2026 at 12:03:42PM -0700, Jakub Kicinski wrote:
>>> > On Thu, 26 Mar 2026 15:28:18 +0200 Ioana Ciornei wrote:
>>> > > This patch set aims to add the necessary support so that bash written
>>> > > selftests are also able to easily run with a remote traffic generator
>>> > > system, either be it in another netns or one accessible through ssh.
>>> > >
>>> > > This patch set is a result of the discussion from v1:
>>> > > https://lore.kernel.org/all/20260303084330.340b6459@kernel.org/
>>> > > Even though the python infrastructure is already established, some
>>> > > things are easier in bash and it would be a shame to leave behind the
>>> > > bash tests that we already have.
>>> >
>>> > I think this introduces a bunch of regressions, eg:
>>> >
>>> > https://netdev-ctrl.bots.linux.dev/logs/vmksft/forwarding/results/575622/4-local-termination-sh/stdout
>>> >
>>> > https://netdev-ctrl.bots.linux.dev/logs/vmksft/netdevsim/results/575802/18-netcons-resume-sh/stdout
>>>
>>> I cannot reproduce this unfortunately. For example, local_termination.sh
>>> gives me the following result with the exact patches that I submitted.
>>> Any idea on what might be the difference?
>>
>> Hm, the system that runs this on our end is:
>>
>> # cat /etc/redhat-release
>> Fedora release 43 (Forty Three)
>>
>> And it has this added on top of default install:
>>
>> # cat /etc/systemd/network/99-default.link
>> [Match]
>> OriginalName=*
>>
>> [Link]
>> NamePolicy=keep kernel database onboard slot path
>> AlternativeNamesPolicy=database onboard slot path mac
>> MACAddressPolicy=none
>
> The observed issues are consistent with TARGETS being defined, but not
> an array:
>
> $ declare -A T
> $ T=([a.100]=b)
> $ U=foo
> $ if declare -p T &>/dev/null; then echo "${T[a.100]}"; else echo fail; fi
> b
> $ if declare -p U &>/dev/null; then echo "${U[a.100]}"; else echo fail; fi
> bash: a.100: syntax error: invalid arithmetic operator (error token is ".100")
I'm wondering if there is a shell export of the variable for make to use
for build process, and then it gets inherited by tests launched from
make as well.
Whatever the cause, the test will have to be more careful in how it uses
the variable.
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH net-next v4 00/10] selftests: drivers: bash support for remote traffic generators
2026-03-30 10:38 ` Petr Machata
2026-03-30 11:10 ` Petr Machata
@ 2026-03-30 11:11 ` Ioana Ciornei
2026-03-30 11:52 ` Petr Machata
1 sibling, 1 reply; 26+ messages in thread
From: Ioana Ciornei @ 2026-03-30 11:11 UTC (permalink / raw)
To: Petr Machata
Cc: Jakub Kicinski, netdev, Andrew Lunn, David S. Miller,
Eric Dumazet, Paolo Abeni, Simon Horman, linux-kernel, willemb,
linux-kselftest
On Mon, Mar 30, 2026 at 12:38:54PM +0200, Petr Machata wrote:
>
> Jakub Kicinski <kuba@kernel.org> writes:
>
> > On Fri, 27 Mar 2026 09:32:22 +0200 Ioana Ciornei wrote:
> >> On Thu, Mar 26, 2026 at 12:03:42PM -0700, Jakub Kicinski wrote:
> >> > On Thu, 26 Mar 2026 15:28:18 +0200 Ioana Ciornei wrote:
> >> > > This patch set aims to add the necessary support so that bash written
> >> > > selftests are also able to easily run with a remote traffic generator
> >> > > system, either be it in another netns or one accessible through ssh.
> >> > >
> >> > > This patch set is a result of the discussion from v1:
> >> > > https://lore.kernel.org/all/20260303084330.340b6459@kernel.org/
> >> > > Even though the python infrastructure is already established, some
> >> > > things are easier in bash and it would be a shame to leave behind the
> >> > > bash tests that we already have.
> >> >
> >> > I think this introduces a bunch of regressions, eg:
> >> >
> >> > https://netdev-ctrl.bots.linux.dev/logs/vmksft/forwarding/results/575622/4-local-termination-sh/stdout
> >> >
> >> > https://netdev-ctrl.bots.linux.dev/logs/vmksft/netdevsim/results/575802/18-netcons-resume-sh/stdout
> >>
> >> I cannot reproduce this unfortunately. For example, local_termination.sh
> >> gives me the following result with the exact patches that I submitted.
> >> Any idea on what might be the difference?
> >
> > Hm, the system that runs this on our end is:
> >
> > # cat /etc/redhat-release
> > Fedora release 43 (Forty Three)
> >
> > And it has this added on top of default install:
> >
> > # cat /etc/systemd/network/99-default.link
> > [Match]
> > OriginalName=*
> >
> > [Link]
> > NamePolicy=keep kernel database onboard slot path
> > AlternativeNamesPolicy=database onboard slot path mac
> > MACAddressPolicy=none
>
> The observed issues are consistent with TARGETS being defined, but not
> an array:
>
> $ declare -A T
> $ T=([a.100]=b)
> $ U=foo
> $ if declare -p T &>/dev/null; then echo "${T[a.100]}"; else echo fail; fi
> b
> $ if declare -p U &>/dev/null; then echo "${U[a.100]}"; else echo fail; fi
> bash: a.100: syntax error: invalid arithmetic operator (error token is ".100")
Totally agree, that's what it looks like.
On the other hand, I don't see any other use of the TARGETS variable in
tools/testing/selftests. The only way I can trigger that kind of error
is by setting and exporting TARGETS before running the test.
root@localhost:~/ksft-net-drv# export TARGETS=test
root@localhost:~/ksft-net-drv# ./run_kselftest.sh -t drivers/net/netconsole:netcons_resume.sh
[ 1895.134633] kselftest: Running tests in drivers/net/netconsole
TAP version 13
1..1
# timeout set to 45
# selftests: drivers/net/netconsole: netcons_resume.sh
# Running with bind mode: ifname
# /root/ksft-net-drv/drivers/net/lib/sh/../../../../net/lib.sh: line 707: eni497np1: unbound variable
not ok 1 selftests: drivers/net/netconsole: netcons_resume.sh # exit=1
So this means that TARGETS is used by the netdev testing
infrastructure, I presume.
Anyhow, I can change the variable name to avoid this. Something like
NETIF_TARGETS?
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH net-next v4 03/10] selftests: net: extend lib.sh to parse drivers/net/net.config
2026-03-26 13:28 ` [PATCH net-next v4 03/10] selftests: net: extend lib.sh to parse drivers/net/net.config Ioana Ciornei
@ 2026-03-30 11:28 ` Petr Machata
2026-03-30 12:28 ` Ioana Ciornei
0 siblings, 1 reply; 26+ messages in thread
From: Petr Machata @ 2026-03-30 11:28 UTC (permalink / raw)
To: Ioana Ciornei
Cc: netdev, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Simon Horman, linux-kernel, petrm,
willemb, linux-kselftest
Ioana Ciornei <ioana.ciornei@nxp.com> writes:
> Extend lib.sh so that it's able to parse driver/net/net.config and
> environment variables such as NETIF, REMOTE_TYPE, LOCAL_V4 etc described
> in drivers/net/README.rst.
>
> In order to make the transition towards running with a single local
> interface smoother for the bash networking driver tests, beside sourcing
> the net.config file also translate the new env variables into the old
> style based on the NETIFS array. Since the NETIFS array only holds the
> network interface names, also add a new array - TARGETS - which keeps
> track of the target on which a specific interfaces resides - local,
> netns or accesible through an ssh command.
>
> For example, a net.config which looks like below:
>
> NETIF=eth0
> LOCAL_V4=192.168.1.1
> REMOTE_V4=192.168.1.2
> REMOTE_TYPE=ssh
> REMOTE_ARGS=root@192.168.1.2
>
> will generate the NETIFS and TARGETS arrays with the following data.
>
> NETIFS[p1]="eth0"
> NETIFS[p2]="eth2"
>
> TARGETS[eth0]="local:"
> TARGETS[eth2]="ssh:root@192.168.1.2"
>
> The above will be true if on the remote target, the interface which has
> the 192.168.1.2 address is named eth2.
>
> Since the TARGETS array is indexed by the network interface name,
> document a new restriction README.rst which states that the remote
> interface cannot have the same name as the local one.
>
> Also keep the old way of populating the NETIFS variable based on the
> command line arguments. This will be invoked in case NETIF is not
> defined.
>
> Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
> ---
> Changes in v4:
> - reword the entry in README.rst to mention that the different interface
> names is only a bash restriction and the python infrastructure does
> not have the same problem.
> - only declare the TARGETS array when necessary
I guess you mean at the point where it's necessary, instead of it being
a user API. Right now TARGETS is defined always, and I think that's
better than having it only defined sometimes.
> - add a new flags - DRIVER_TEST_CONFORMANT - that needs to be set by the
> test
> - rework the check_env() function so that its logic is simpler
> - source drivers/net/net.config only if DRIVER_TEST_CONFORMANT == yes
> - check that NETIF and the remote netif have different names and abort
> test is not
>
> Changes in v3:
> - s/TARGET/CUR_TARGET
> - this used to be patch #2/9 in v2. Swapped the two patches so that the
> run_cmd used in this patch is defined earlier, not later.
> Changes in v2:
> - patch is new
>
> .../testing/selftests/drivers/net/README.rst | 4 +
> tools/testing/selftests/net/forwarding/lib.sh | 106 ++++++++++++++++--
> 2 files changed, 101 insertions(+), 9 deletions(-)
>
> diff --git a/tools/testing/selftests/drivers/net/README.rst b/tools/testing/selftests/drivers/net/README.rst
> index c94992acf10b..1897aa1583ec 100644
> --- a/tools/testing/selftests/drivers/net/README.rst
> +++ b/tools/testing/selftests/drivers/net/README.rst
> @@ -26,6 +26,10 @@ The netdevice against which tests will be run must exist, be running
> Refer to list of :ref:`Variables` later in this file to set up running
> the tests against a real device.
>
> +The current support for bash tests restricts the use of the same interface name
> +on the local system and the remote one and will bail if this case is
> +encountered.
> +
> Both modes required
> ~~~~~~~~~~~~~~~~~~~
>
> diff --git a/tools/testing/selftests/net/forwarding/lib.sh b/tools/testing/selftests/net/forwarding/lib.sh
> index 3009ce00c5dc..93b865681840 100644
> --- a/tools/testing/selftests/net/forwarding/lib.sh
> +++ b/tools/testing/selftests/net/forwarding/lib.sh
> @@ -3,6 +3,7 @@
>
> ##############################################################################
> # Topology description. p1 looped back to p2, p3 to p4 and so on.
> +#shellcheck disable=SC2034 # SC doesn't see our uses of global variables
The shellcheck line should be moved elsewhere. The comment is related to
NETIFS, and it's weird there's a shellcheck declaration between a
comment and the thing it's commenting.
> declare -A NETIFS=(
> [p1]=veth0
> @@ -85,6 +86,9 @@ declare -A NETIFS=(
> # e.g. a low-power board.
> : "${KSFT_MACHINE_SLOW:=no}"
>
> +# Whether the test is conforming to the requirements and usage described in
> +# drivers/net/README.rst.
> +: "${DRIVER_TEST_CONFORMANT:=no}"
Not sure this makes sense as user API either honestly. Given the
differences between requirements of the two test types I can't imagine a
non-conformant test would be runnable like that. The actual line is OK,
but it should be moved probably above the if check, so as not to
indicate it's usable as a user API.
> ##############################################################################
> # Find netifs by test-specified driver name
>
> @@ -340,17 +344,101 @@ fi
> ##############################################################################
> # Command line options handling
>
> -count=0
> +check_env() {
> + if [[ ! (( -n "$LOCAL_V4" && -n "$REMOTE_V4") ||
> + ( -n "$LOCAL_V6" && -n "$REMOTE_V6" )) ]]; then
> + echo "SKIP: Invalid environment, missing or inconsistent LOCAL_V4/REMOTE_V4/LOCAL_V6/REMOTE_V6"
> + echo "Please see tools/testing/selftests/drivers/net/README.rst"
> + exit "$ksft_skip"
> + fi
>
> -while [[ $# -gt 0 ]]; do
> - if [[ "$count" -eq "0" ]]; then
> - unset NETIFS
> - declare -A NETIFS
> + if [[ -z "$REMOTE_TYPE" ]]; then
> + echo "SKIP: Invalid environment, missing REMOTE_TYPE"
> + exit "$ksft_skip"
> fi
> - count=$((count + 1))
> - NETIFS[p$count]="$1"
> - shift
> -done
> +
> + if [[ -z "$REMOTE_ARGS" ]]; then
> + echo "SKIP: Invalid environment, missing REMOTE_ARGS"
> + exit "$ksft_skip"
> + fi
> +}
> +
> +get_ifname_by_ip()
> +{
> + local target=$1; shift
> + local ip_addr=$1; shift
> +
> + __run_on "$target" ip -j addr show to "$ip_addr" | jq -r '.[].ifname'
> +}
> +
> +# Based on DRIVER_TEST_CONFORMANT, decide if to source drivers/net/net.config
> +# or not. In the "yes" case, the test expects to pass the arguments through the
> +# variables specified in drivers/net/README.rst file. If not, fallback on
> +# parsing the script arguments for interface names.
> +if [ "${DRIVER_TEST_CONFORMANT}" = "yes" ]; then
> + if [[ -f $net_forwarding_dir/../../drivers/net/net.config ]]; then
> + source "$net_forwarding_dir/../../drivers/net/net.config"
> + fi
> +
> + if (( NUM_NETIFS > 2)); then
> + echo "SKIP: DRIVER_TEST_CONFORMANT=yes and NUM_NETIFS is bigger than 2"
> + exit "$ksft_skip"
> + fi
> +
> + check_env
> +
> + # Populate the NETIFS and TARGETS arrays automatically based on the
> + # environment variables. The TARGETS array is indexed by the network
> + # interface name keeping track of the target on which the interface
> + # resides. Values will be strings of the following format -
> + # <type>:<args>.
> + #
> + # TARGETS[eth0]="local:" - meaning that the eth0 interface is
> + # accessible locally
> + # TARGETS[eth1]="netns:foo" - eth1 is in the foo netns
> + # TARGETS[eth2]="ssh:root@10.0.0.2" - eth2 is accessible through
> + # running the 'ssh root@10.0.0.2' command.
> +
> + unset NETIFS
> + declare -A NETIFS
> + declare -A TARGETS
> +
> + NETIFS[p1]="$NETIF"
> + TARGETS[$NETIF]="local:"
> +
> + # Locate the name of the remote interface
> + remote_target="$REMOTE_TYPE:$REMOTE_ARGS"
> + if [[ -v REMOTE_V4 ]]; then
> + remote_netif=$(get_ifname_by_ip "$remote_target" "$REMOTE_V4")
> + else
> + remote_netif=$(get_ifname_by_ip "$remote_target" "$REMOTE_V6")
> + fi
> + if [[ ! -n "$remote_netif" ]]; then
> + echo "SKIP: cannot find remote interface"
> + exit "$ksft_skip"
> + fi
> +
> + if [[ "$NETIF" == "$remote_netif" ]]; then
> + echo "SKIP: local and remote interfaces cannot have the same name"
> + exit "$ksft_skip"
> + fi
> +
> + NETIFS[p2]="$remote_netif"
> + TARGETS[$remote_netif]="$REMOTE_TYPE:$REMOTE_ARGS"
> +else
> + count=0
This leg is missing declare -A TARGETS.
Since both legs need to declare it, why not move it up above the if?
> + while [[ $# -gt 0 ]]; do
> + if [[ "$count" -eq "0" ]]; then
> + unset NETIFS
> + declare -A NETIFS
> + fi
> + count=$((count + 1))
> + NETIFS[p$count]="$1"
> + TARGETS[$1]="local:"
> + shift
> + done
> +fi
>
> ##############################################################################
> # Network interfaces configuration
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH net-next v4 02/10] selftests: net: add helpers for running a command on other targets
2026-03-30 11:02 ` Petr Machata
@ 2026-03-30 11:32 ` Petr Machata
2026-03-30 12:12 ` Ioana Ciornei
0 siblings, 1 reply; 26+ messages in thread
From: Petr Machata @ 2026-03-30 11:32 UTC (permalink / raw)
To: Petr Machata
Cc: Ioana Ciornei, netdev, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Simon Horman,
linux-kernel, willemb, linux-kselftest
Petr Machata <petrm@nvidia.com> writes:
> Ioana Ciornei <ioana.ciornei@nxp.com> writes:
>
>> Add a couple of helpers which can be used by tests which need to run a
>> specific bash command on a different target than the local system, be it
>> either another netns or a remote system accessible through ssh.
>>
>> The __run_on() function is passed through $1 the target on which the
>> command should be executed while run_on() is passed the name of the
>> interface that is then used to retrieve the target from the TARGETS
>> array.
>>
>> Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
>> ---
>> Changes in v4:
>> - reworked the helpers so that no global variable is used and
>> information is passed only through parameters
>> Changes in v3:
>> - s/TARGET/CUR_TARGET
>> - always fallback on running a command locally when either TARGETS is
>> not declared or there is no entry for a specific interface
>> Changes in v2:
>> - patch is new
>>
>> tools/testing/selftests/net/lib.sh | 38 ++++++++++++++++++++++++++++++
>> 1 file changed, 38 insertions(+)
>>
>> diff --git a/tools/testing/selftests/net/lib.sh b/tools/testing/selftests/net/lib.sh
>> index b40694573f4c..6c0d613a4de5 100644
>> --- a/tools/testing/selftests/net/lib.sh
>> +++ b/tools/testing/selftests/net/lib.sh
>> @@ -670,3 +670,41 @@ cmd_jq()
>> # return success only in case of non-empty output
>> [ ! -z "$output" ]
>> }
>> +
>> +__run_on()
>> +{
>> + local target=$1; shift
>> + local type args
>> +
>> + IFS=':' read -r type args <<< "$target"
>> +
>> + case "$type" in
>> + netns)
>> + # Execute command in network namespace
>> + # args contains the namespace name
>> + ip netns exec "$args" "$@"
>> + ;;
>> + ssh)
>> + # Execute command via SSH args contains user@host
>> + ssh -n "$args" "$@"
>> + ;;
>> + local|*)
>> + # Execute command locally. This is also the fallback
>> + # case for when the interface's target is not found in
>> + # the TARGETS array.
>> + "$@"
>> + ;;
>> + esac
>> +}
>> +
>> +run_on()
>> +{
>> + local iface=$1; shift
>> + local target="local:"
>> +
>> + if declare -p TARGETS &>/dev/null; then
>> + target="${TARGETS[$iface]}"
>
> So I think Jakub's runs fail because there's a shell export somewhere
> that gets inherited through make to the launched test. I guess it would
> be enough for the test to validate that TARGETS is an array, because
> those don't get inherited.
>
> Is there a reason not to reuse DRIVER_TEST_CONFORMANT as a tell though?
>
>> + fi
>> +
>> + __run_on "$target" "$@"
>> +}
>
> Does the latter helper need to be in net/lib.sh? Since it uses TARGETS,
> which are a forwarding/lib.sh concept, it seems misplaced there.
Oh, I see, there's an invocation from mac_get() in net/lib.sh itself.
Hummm. Not sure how to tackle this.
I think lib.sh might unset TARGETS explicitly? Or declare -A, but leave
empty? Since it's now an API, net/lib.sh needs to set it to a reasonable
value (or erase). Then forwarding/lib.sh might in theory rely on
existence of that variable and not have to declare it at all.
Or, maybe have a stub run_on() like this to satisfy the run_on() API:
run_on()
{
"$@"
}
And have the full-blown thing in forward/lib.sh. All the magic with
TARGETS really belongs to forwarding/lib.sh. Bash allows function
redefinition just fine, so a user importing just net/lib.sh would get
the stub, and forwarding/lib.sh users would get the full thing.
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH net-next v4 00/10] selftests: drivers: bash support for remote traffic generators
2026-03-30 11:11 ` Ioana Ciornei
@ 2026-03-30 11:52 ` Petr Machata
0 siblings, 0 replies; 26+ messages in thread
From: Petr Machata @ 2026-03-30 11:52 UTC (permalink / raw)
To: Ioana Ciornei
Cc: Petr Machata, Jakub Kicinski, netdev, Andrew Lunn,
David S. Miller, Eric Dumazet, Paolo Abeni, Simon Horman,
linux-kernel, willemb, linux-kselftest
Ioana Ciornei <ioana.ciornei@nxp.com> writes:
> On Mon, Mar 30, 2026 at 12:38:54PM +0200, Petr Machata wrote:
>>
>> Jakub Kicinski <kuba@kernel.org> writes:
>>
>> > On Fri, 27 Mar 2026 09:32:22 +0200 Ioana Ciornei wrote:
>> >> On Thu, Mar 26, 2026 at 12:03:42PM -0700, Jakub Kicinski wrote:
>> >> > On Thu, 26 Mar 2026 15:28:18 +0200 Ioana Ciornei wrote:
>> >> > > This patch set aims to add the necessary support so that bash written
>> >> > > selftests are also able to easily run with a remote traffic generator
>> >> > > system, either be it in another netns or one accessible through ssh.
>> >> > >
>> >> > > This patch set is a result of the discussion from v1:
>> >> > > https://lore.kernel.org/all/20260303084330.340b6459@kernel.org/
>> >> > > Even though the python infrastructure is already established, some
>> >> > > things are easier in bash and it would be a shame to leave behind the
>> >> > > bash tests that we already have.
>> >> >
>> >> > I think this introduces a bunch of regressions, eg:
>> >> >
>> >> > https://netdev-ctrl.bots.linux.dev/logs/vmksft/forwarding/results/575622/4-local-termination-sh/stdout
>> >> >
>> >> > https://netdev-ctrl.bots.linux.dev/logs/vmksft/netdevsim/results/575802/18-netcons-resume-sh/stdout
>> >>
>> >> I cannot reproduce this unfortunately. For example, local_termination.sh
>> >> gives me the following result with the exact patches that I submitted.
>> >> Any idea on what might be the difference?
>> >
>> > Hm, the system that runs this on our end is:
>> >
>> > # cat /etc/redhat-release
>> > Fedora release 43 (Forty Three)
>> >
>> > And it has this added on top of default install:
>> >
>> > # cat /etc/systemd/network/99-default.link
>> > [Match]
>> > OriginalName=*
>> >
>> > [Link]
>> > NamePolicy=keep kernel database onboard slot path
>> > AlternativeNamesPolicy=database onboard slot path mac
>> > MACAddressPolicy=none
>>
>> The observed issues are consistent with TARGETS being defined, but not
>> an array:
>>
>> $ declare -A T
>> $ T=([a.100]=b)
>> $ U=foo
>> $ if declare -p T &>/dev/null; then echo "${T[a.100]}"; else echo fail; fi
>> b
>> $ if declare -p U &>/dev/null; then echo "${U[a.100]}"; else echo fail; fi
>> bash: a.100: syntax error: invalid arithmetic operator (error token is ".100")
>
> Totally agree, that's what it looks like.
>
> On the other hand, I don't see any other use of the TARGETS variable in
> tools/testing/selftests. The only way I can trigger that kind of error
> is by setting and exporting TARGETS before running the test.
>
> root@localhost:~/ksft-net-drv# export TARGETS=test
> root@localhost:~/ksft-net-drv# ./run_kselftest.sh -t drivers/net/netconsole:netcons_resume.sh
> [ 1895.134633] kselftest: Running tests in drivers/net/netconsole
> TAP version 13
> 1..1
> # timeout set to 45
> # selftests: drivers/net/netconsole: netcons_resume.sh
> # Running with bind mode: ifname
> # /root/ksft-net-drv/drivers/net/lib/sh/../../../../net/lib.sh: line 707: eni497np1: unbound variable
> not ok 1 selftests: drivers/net/netconsole: netcons_resume.sh # exit=1
>
> So this means that TARGETS is used by the netdev testing
> infrastructure, I presume.
I think Jakub has the export for make to pick up, and then tests inherit
it.
> Anyhow, I can change the variable name to avoid this. Something like
> NETIF_TARGETS?
I sent some thoughts about how to fix the issue in my review of 02/10,
so let's move the discussion there.
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH net-next v4 04/10] selftests: net: update some helpers to use run_on
2026-03-26 13:28 ` [PATCH net-next v4 04/10] selftests: net: update some helpers to use run_on Ioana Ciornei
@ 2026-03-30 11:55 ` Petr Machata
0 siblings, 0 replies; 26+ messages in thread
From: Petr Machata @ 2026-03-30 11:55 UTC (permalink / raw)
To: Ioana Ciornei
Cc: netdev, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Simon Horman, linux-kernel, petrm,
willemb, linux-kselftest
Ioana Ciornei <ioana.ciornei@nxp.com> writes:
> Update some helpers so that they are capable to run commands on
> different targets than the local one. This patch makes the necesasy
> modification for those helpers / sections of code which are needed for
> the ethtool_rmon.sh test that will be converted in the next patches.
>
> For example, mac_addr_prepare() and mac_addr_restore() used when
> STABLE_MAC_ADDRS=yes need to ensure stable MAC addresses on interfaces
> located even in other namespaces. In order to do that, append the 'ip
> link' commands with a 'run_on $dev' tag.
>
> The same run_on is necessary also when verifying if all the interfaces
> listed in NETIFS are indeed available.
>
> Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
Looking good.
Reviewed-by: Petr Machata <petrm@nvidia.com>
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH net-next v4 08/10] selftests: drivers: hw: move to KTAP output
2026-03-26 13:28 ` [PATCH net-next v4 08/10] selftests: drivers: hw: move to KTAP output Ioana Ciornei
@ 2026-03-30 12:01 ` Petr Machata
0 siblings, 0 replies; 26+ messages in thread
From: Petr Machata @ 2026-03-30 12:01 UTC (permalink / raw)
To: Ioana Ciornei
Cc: netdev, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Simon Horman, linux-kernel, petrm,
willemb, linux-kselftest
Ioana Ciornei <ioana.ciornei@nxp.com> writes:
> Update the ethtool_rmon.sh test so that it uses the KTAP format for its
> output. This is achieved by using the helpers found in ktap_helpers.sh.
> An example output can be found below.
>
> $ ./ethtool_rmon.sh endpmac3 endpmac4
> 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
>
> Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
Reviewed-by: Petr Machata <petrm@nvidia.com>
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH net-next v4 10/10] selftests: drivers: hw: add test for the ethtool standard counters
2026-03-26 13:28 ` [PATCH net-next v4 10/10] selftests: drivers: hw: add test for the ethtool standard counters Ioana Ciornei
@ 2026-03-30 12:03 ` Petr Machata
0 siblings, 0 replies; 26+ messages in thread
From: Petr Machata @ 2026-03-30 12:03 UTC (permalink / raw)
To: Ioana Ciornei
Cc: netdev, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Simon Horman, linux-kernel, petrm,
willemb, linux-kselftest
Ioana Ciornei <ioana.ciornei@nxp.com> writes:
> Add a new selftest - ethtool_std_stats.sh - which validates the
> eth-ctrl, eth-mac and pause standard statistics exported by an
> interface. Collision related eth-mac counters as well as the error ones
> will be checked against zero since that is the most likely correct
> scenario.
>
> The central part of this patch is the traffic_test() function which
> gathers the 'before' counter values, sends a batch of traffic and then
> interrogates again the same counters in order to determine if the delta
> is on target. The function receives an array through which the caller
> can request what counters to be interrogated and, for each of them, what
> is their target delta value.
>
> The output from this selftest looks as follows on a LX2160ARDB board:
>
> $ ./run_kselftest.sh -t drivers/net/hw:ethtool_std_stats.sh
> TAP version 13
> 1..1
> # timeout set to 0
> # selftests: drivers/net/hw: ethtool_std_stats.sh
> # TAP version 13
> # 1..26
> # ok 1 ethtool_std_stats.eth-ctrl-MACControlFramesTransmitted
> # ok 2 ethtool_std_stats.eth-ctrl-MACControlFramesReceived
> # ok 3 ethtool_std_stats.eth-mac-FrameCheckSequenceErrors
> # ok 4 ethtool_std_stats.eth-mac-AlignmentErrors
> # ok 5 ethtool_std_stats.eth-mac-FramesLostDueToIntMACXmitError
> # ok 6 ethtool_std_stats.eth-mac-CarrierSenseErrors # SKIP
> # ok 7 ethtool_std_stats.eth-mac-FramesLostDueToIntMACRcvError
> # ok 8 ethtool_std_stats.eth-mac-InRangeLengthErrors # SKIP
> # ok 9 ethtool_std_stats.eth-mac-OutOfRangeLengthField # SKIP
> # ok 10 ethtool_std_stats.eth-mac-FrameTooLongErrors # SKIP
> # ok 11 ethtool_std_stats.eth-mac-FramesAbortedDueToXSColls # SKIP
> # ok 12 ethtool_std_stats.eth-mac-SingleCollisionFrames # SKIP
> # ok 13 ethtool_std_stats.eth-mac-MultipleCollisionFrames # SKIP
> # ok 14 ethtool_std_stats.eth-mac-FramesWithDeferredXmissions # SKIP
> # ok 15 ethtool_std_stats.eth-mac-LateCollisions # SKIP
> # ok 16 ethtool_std_stats.eth-mac-FramesWithExcessiveDeferral # SKIP
> # ok 17 ethtool_std_stats.eth-mac-BroadcastFramesXmittedOK
> # ok 18 ethtool_std_stats.eth-mac-OctetsTransmittedOK
> # ok 19 ethtool_std_stats.eth-mac-BroadcastFramesReceivedOK
> # ok 20 ethtool_std_stats.eth-mac-OctetsReceivedOK
> # ok 21 ethtool_std_stats.eth-mac-FramesTransmittedOK
> # ok 22 ethtool_std_stats.eth-mac-MulticastFramesXmittedOK
> # ok 23 ethtool_std_stats.eth-mac-FramesReceivedOK
> # ok 24 ethtool_std_stats.eth-mac-MulticastFramesReceivedOK
> # ok 25 ethtool_std_stats.pause-tx_pause_frames
> # ok 26 ethtool_std_stats.pause-rx_pause_frames
> # # 10 skipped test(s) detected. Consider enabling relevant config options to improve coverage.
> # # Totals: pass:16 fail:0 xfail:0 xpass:0 skip:10 error:0
> ok 1 selftests: drivers/net/hw: ethtool_std_stats.sh
>
> Please note that not all MACs are counting the software injected pause
> frames as real Tx pause. For example, on a LS1028ARDB the selftest
> output will reflect the fact that neither the ENETC MAC, nor the Felix
> switch MAC are able to detect Tx pause frames injected by software.
>
> $ ./run_kselftest.sh -t drivers/net/hw:ethtool_std_stats.sh
> (...)
> # # software sent pause frames not detected
> # ok 25 ethtool_std_stats.pause-tx_pause_frames # XFAIL
> # ok 26 ethtool_std_stats.pause-rx_pause_frames
>
> Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
I didn't go into details much, but the code looks broadly correct.
Acked-by: Petr Machata <petrm@nvidia.com>
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH net-next v4 02/10] selftests: net: add helpers for running a command on other targets
2026-03-30 11:32 ` Petr Machata
@ 2026-03-30 12:12 ` Ioana Ciornei
0 siblings, 0 replies; 26+ messages in thread
From: Ioana Ciornei @ 2026-03-30 12:12 UTC (permalink / raw)
To: Petr Machata
Cc: netdev, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Simon Horman, linux-kernel, willemb,
linux-kselftest
On Mon, Mar 30, 2026 at 01:32:41PM +0200, Petr Machata wrote:
>
> Petr Machata <petrm@nvidia.com> writes:
>
> > Ioana Ciornei <ioana.ciornei@nxp.com> writes:
> >
> >> Add a couple of helpers which can be used by tests which need to run a
> >> specific bash command on a different target than the local system, be it
> >> either another netns or a remote system accessible through ssh.
> >>
> >> The __run_on() function is passed through $1 the target on which the
> >> command should be executed while run_on() is passed the name of the
> >> interface that is then used to retrieve the target from the TARGETS
> >> array.
> >>
> >> Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
> >> ---
> >> Changes in v4:
> >> - reworked the helpers so that no global variable is used and
> >> information is passed only through parameters
> >> Changes in v3:
> >> - s/TARGET/CUR_TARGET
> >> - always fallback on running a command locally when either TARGETS is
> >> not declared or there is no entry for a specific interface
> >> Changes in v2:
> >> - patch is new
> >>
> >> tools/testing/selftests/net/lib.sh | 38 ++++++++++++++++++++++++++++++
> >> 1 file changed, 38 insertions(+)
> >>
> >> diff --git a/tools/testing/selftests/net/lib.sh b/tools/testing/selftests/net/lib.sh
> >> index b40694573f4c..6c0d613a4de5 100644
> >> --- a/tools/testing/selftests/net/lib.sh
> >> +++ b/tools/testing/selftests/net/lib.sh
> >> @@ -670,3 +670,41 @@ cmd_jq()
> >> # return success only in case of non-empty output
> >> [ ! -z "$output" ]
> >> }
> >> +
> >> +__run_on()
> >> +{
> >> + local target=$1; shift
> >> + local type args
> >> +
> >> + IFS=':' read -r type args <<< "$target"
> >> +
> >> + case "$type" in
> >> + netns)
> >> + # Execute command in network namespace
> >> + # args contains the namespace name
> >> + ip netns exec "$args" "$@"
> >> + ;;
> >> + ssh)
> >> + # Execute command via SSH args contains user@host
> >> + ssh -n "$args" "$@"
> >> + ;;
> >> + local|*)
> >> + # Execute command locally. This is also the fallback
> >> + # case for when the interface's target is not found in
> >> + # the TARGETS array.
> >> + "$@"
> >> + ;;
> >> + esac
> >> +}
> >> +
> >> +run_on()
> >> +{
> >> + local iface=$1; shift
> >> + local target="local:"
> >> +
> >> + if declare -p TARGETS &>/dev/null; then
> >> + target="${TARGETS[$iface]}"
> >
> > So I think Jakub's runs fail because there's a shell export somewhere
> > that gets inherited through make to the launched test. I guess it would
> > be enough for the test to validate that TARGETS is an array, because
> > those don't get inherited.
> >
> > Is there a reason not to reuse DRIVER_TEST_CONFORMANT as a tell though?
> >
> >> + fi
> >> +
> >> + __run_on "$target" "$@"
> >> +}
> >
> > Does the latter helper need to be in net/lib.sh? Since it uses TARGETS,
> > which are a forwarding/lib.sh concept, it seems misplaced there.
>
> Oh, I see, there's an invocation from mac_get() in net/lib.sh itself.
> Hummm. Not sure how to tackle this.
>
> I think lib.sh might unset TARGETS explicitly? Or declare -A, but leave
> empty? Since it's now an API, net/lib.sh needs to set it to a reasonable
> value (or erase). Then forwarding/lib.sh might in theory rely on
> existence of that variable and not have to declare it at all.
>
> Or, maybe have a stub run_on() like this to satisfy the run_on() API:
>
> run_on()
> {
> "$@"
shift; "$@"
> }
>
> And have the full-blown thing in forward/lib.sh. All the magic with
> TARGETS really belongs to forwarding/lib.sh. Bash allows function
> redefinition just fine, so a user importing just net/lib.sh would get
> the stub, and forwarding/lib.sh users would get the full thing.
I really like the idea of the stub run_on() in net/lib.sh. This would
also give me the possibility to check for DRIVER_TEST_CONFORMANT = "yes"
in the full-blown run_on() without having to move its default
definition in net/lib.sh.
I quickly changed to this approach and it seems to look good.
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH net-next v4 03/10] selftests: net: extend lib.sh to parse drivers/net/net.config
2026-03-30 11:28 ` Petr Machata
@ 2026-03-30 12:28 ` Ioana Ciornei
0 siblings, 0 replies; 26+ messages in thread
From: Ioana Ciornei @ 2026-03-30 12:28 UTC (permalink / raw)
To: Petr Machata
Cc: netdev, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Simon Horman, linux-kernel, willemb,
linux-kselftest
On Mon, Mar 30, 2026 at 01:28:49PM +0200, Petr Machata wrote:
>
> Ioana Ciornei <ioana.ciornei@nxp.com> writes:
>
> > Extend lib.sh so that it's able to parse driver/net/net.config and
> > environment variables such as NETIF, REMOTE_TYPE, LOCAL_V4 etc described
> > in drivers/net/README.rst.
> >
> > In order to make the transition towards running with a single local
> > interface smoother for the bash networking driver tests, beside sourcing
> > the net.config file also translate the new env variables into the old
> > style based on the NETIFS array. Since the NETIFS array only holds the
> > network interface names, also add a new array - TARGETS - which keeps
> > track of the target on which a specific interfaces resides - local,
> > netns or accesible through an ssh command.
> >
> > For example, a net.config which looks like below:
> >
> > NETIF=eth0
> > LOCAL_V4=192.168.1.1
> > REMOTE_V4=192.168.1.2
> > REMOTE_TYPE=ssh
> > REMOTE_ARGS=root@192.168.1.2
> >
> > will generate the NETIFS and TARGETS arrays with the following data.
> >
> > NETIFS[p1]="eth0"
> > NETIFS[p2]="eth2"
> >
> > TARGETS[eth0]="local:"
> > TARGETS[eth2]="ssh:root@192.168.1.2"
> >
> > The above will be true if on the remote target, the interface which has
> > the 192.168.1.2 address is named eth2.
> >
> > Since the TARGETS array is indexed by the network interface name,
> > document a new restriction README.rst which states that the remote
> > interface cannot have the same name as the local one.
> >
> > Also keep the old way of populating the NETIFS variable based on the
> > command line arguments. This will be invoked in case NETIF is not
> > defined.
> >
> > Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
> > ---
> > Changes in v4:
> > - reword the entry in README.rst to mention that the different interface
> > names is only a bash restriction and the python infrastructure does
> > not have the same problem.
> > - only declare the TARGETS array when necessary
>
> I guess you mean at the point where it's necessary, instead of it being
> a user API. Right now TARGETS is defined always, and I think that's
> better than having it only defined sometimes.
Yes.
(...)
> > diff --git a/tools/testing/selftests/net/forwarding/lib.sh b/tools/testing/selftests/net/forwarding/lib.sh
> > index 3009ce00c5dc..93b865681840 100644
> > --- a/tools/testing/selftests/net/forwarding/lib.sh
> > +++ b/tools/testing/selftests/net/forwarding/lib.sh
> > @@ -3,6 +3,7 @@
> >
> > ##############################################################################
> > # Topology description. p1 looped back to p2, p3 to p4 and so on.
> > +#shellcheck disable=SC2034 # SC doesn't see our uses of global variables
>
> The shellcheck line should be moved elsewhere. The comment is related to
> NETIFS, and it's weird there's a shellcheck declaration between a
> comment and the thing it's commenting.
Ok.
>
> > declare -A NETIFS=(
> > [p1]=veth0
> > @@ -85,6 +86,9 @@ declare -A NETIFS=(
> > # e.g. a low-power board.
> > : "${KSFT_MACHINE_SLOW:=no}"
> >
> > +# Whether the test is conforming to the requirements and usage described in
> > +# drivers/net/README.rst.
> > +: "${DRIVER_TEST_CONFORMANT:=no}"
>
> Not sure this makes sense as user API either honestly. Given the
> differences between requirements of the two test types I can't imagine a
> non-conformant test would be runnable like that. The actual line is OK,
> but it should be moved probably above the if check, so as not to
> indicate it's usable as a user API.
Ok, will move it before the if statement.
(...)
> > +
> > + NETIFS[p2]="$remote_netif"
> > + TARGETS[$remote_netif]="$REMOTE_TYPE:$REMOTE_ARGS"
> > +else
> > + count=0
>
> This leg is missing declare -A TARGETS.
>
> Since both legs need to declare it, why not move it up above the if?
Ok, will declare it above the if.
Thanks!
Ioana
^ permalink raw reply [flat|nested] 26+ messages in thread
end of thread, other threads:[~2026-03-30 12:28 UTC | newest]
Thread overview: 26+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-26 13:28 [PATCH net-next v4 00/10] selftests: drivers: bash support for remote traffic generators Ioana Ciornei
2026-03-26 13:28 ` [PATCH net-next v4 01/10] selftests: forwarding: extend ethtool_std_stats_get with pause statistics Ioana Ciornei
2026-03-26 13:28 ` [PATCH net-next v4 02/10] selftests: net: add helpers for running a command on other targets Ioana Ciornei
2026-03-30 11:02 ` Petr Machata
2026-03-30 11:32 ` Petr Machata
2026-03-30 12:12 ` Ioana Ciornei
2026-03-26 13:28 ` [PATCH net-next v4 03/10] selftests: net: extend lib.sh to parse drivers/net/net.config Ioana Ciornei
2026-03-30 11:28 ` Petr Machata
2026-03-30 12:28 ` Ioana Ciornei
2026-03-26 13:28 ` [PATCH net-next v4 04/10] selftests: net: update some helpers to use run_on Ioana Ciornei
2026-03-30 11:55 ` Petr Machata
2026-03-26 13:28 ` [PATCH net-next v4 05/10] selftests: drivers: hw: cleanup shellcheck warnings in the rmon test Ioana Ciornei
2026-03-26 13:28 ` [PATCH net-next v4 06/10] selftests: drivers: hw: test rmon counters only on first interface Ioana Ciornei
2026-03-26 13:28 ` [PATCH net-next v4 07/10] selftests: drivers: hw: replace counter upper limit with UINT32_MAX in rmon test Ioana Ciornei
2026-03-26 13:28 ` [PATCH net-next v4 08/10] selftests: drivers: hw: move to KTAP output Ioana Ciornei
2026-03-30 12:01 ` Petr Machata
2026-03-26 13:28 ` [PATCH net-next v4 09/10] selftests: drivers: hw: update ethtool_rmon to work with a single local interface Ioana Ciornei
2026-03-26 13:28 ` [PATCH net-next v4 10/10] selftests: drivers: hw: add test for the ethtool standard counters Ioana Ciornei
2026-03-30 12:03 ` Petr Machata
2026-03-26 19:03 ` [PATCH net-next v4 00/10] selftests: drivers: bash support for remote traffic generators Jakub Kicinski
2026-03-27 7:32 ` Ioana Ciornei
2026-03-28 0:24 ` Jakub Kicinski
2026-03-30 10:38 ` Petr Machata
2026-03-30 11:10 ` Petr Machata
2026-03-30 11:11 ` Ioana Ciornei
2026-03-30 11:52 ` Petr Machata
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox