* [PATCH net-next v2 0/7] selftests: net: groundwork for YNL-based tests
@ 2024-04-03 2:34 Jakub Kicinski
2024-04-03 2:34 ` [PATCH net-next v2 1/7] netlink: specs: define ethtool header flags Jakub Kicinski
` (7 more replies)
0 siblings, 8 replies; 19+ messages in thread
From: Jakub Kicinski @ 2024-04-03 2:34 UTC (permalink / raw)
To: davem
Cc: netdev, edumazet, pabeni, shuah, sdf, donald.hunter,
linux-kselftest, petrm, Jakub Kicinski
Currently the options for writing networking tests are C, bash or
some mix of the two. YAML/Netlink gives us the ability to easily
interface with Netlink in higher level laguages. In particular,
there is a Python library already available in tree, under tools/net.
Add the scaffolding which allows writing tests using this library.
The "scaffolding" is needed because the library lives under
tools/net and uses YAML files from under Documentation/.
So we need a small amount of glue code to find those things
and add them to TEST_FILES.
This series adds both a basic SW sanity test and driver
test which can be run against netdevsim or a real device.
When I develop core code I usually test with netdevsim,
then a real device, and then a backport to Meta's kernel.
Because of the lack of integration, until now I had
to throw away the (YNL-based) test script and netdevsim code.
Running tests in tree directly:
$ ./tools/testing/selftests/net/nl_netdev.py
KTAP version 1
1..2
ok 1 nl_netdev.empty_check
ok 2 nl_netdev.lo_check
# Totals: pass:2 fail:0 xfail:0 xpass:0 skip:0 error:0
in tree via make:
$ make -C tools/testing/selftests/ TARGETS=net \
TEST_PROGS=nl_netdev.py TEST_GEN_PROGS="" run_tests
[ ... ]
and installed externally, all seem to work:
$ make -C tools/testing/selftests/ TARGETS=net \
install INSTALL_PATH=/tmp/ksft-net
$ /tmp/ksft-net/run_kselftest.sh -t net:nl_netdev.py
[ ... ]
For driver tests I followed the lead of net/forwarding and
get the device name from env and/or a config file.
v2: (see patches for minor changes)
- don't add to TARGETS, create a deperate variable with deps
- support and use with
- support and use passing arguments to tests
v1: https://lore.kernel.org/all/20240402010520.1209517-1-kuba@kernel.org/
Jakub Kicinski (7):
netlink: specs: define ethtool header flags
tools: ynl: copy netlink error to NlError
selftests: net: add scaffolding for Netlink tests in Python
selftests: nl_netdev: add a trivial Netlink netdev test
netdevsim: report stats by default, like a real device
selftests: drivers: add scaffolding for Netlink tests in Python
testing: net-drv: add a driver test for stats reporting
Documentation/netlink/specs/ethtool.yaml | 6 +
drivers/net/netdevsim/ethtool.c | 11 ++
drivers/net/netdevsim/netdev.c | 45 +++++++
tools/net/ynl/lib/ynl.py | 3 +-
tools/testing/selftests/Makefile | 10 +-
tools/testing/selftests/drivers/net/Makefile | 7 ++
.../testing/selftests/drivers/net/README.rst | 30 +++++
.../selftests/drivers/net/lib/py/__init__.py | 17 +++
.../selftests/drivers/net/lib/py/env.py | 52 ++++++++
tools/testing/selftests/drivers/net/stats.py | 86 +++++++++++++
tools/testing/selftests/net/Makefile | 1 +
tools/testing/selftests/net/lib/Makefile | 8 ++
.../testing/selftests/net/lib/py/__init__.py | 7 ++
tools/testing/selftests/net/lib/py/consts.py | 9 ++
tools/testing/selftests/net/lib/py/ksft.py | 96 ++++++++++++++
tools/testing/selftests/net/lib/py/nsim.py | 118 ++++++++++++++++++
tools/testing/selftests/net/lib/py/utils.py | 47 +++++++
tools/testing/selftests/net/lib/py/ynl.py | 49 ++++++++
tools/testing/selftests/net/nl_netdev.py | 24 ++++
19 files changed, 624 insertions(+), 2 deletions(-)
create mode 100644 tools/testing/selftests/drivers/net/Makefile
create mode 100644 tools/testing/selftests/drivers/net/README.rst
create mode 100644 tools/testing/selftests/drivers/net/lib/py/__init__.py
create mode 100644 tools/testing/selftests/drivers/net/lib/py/env.py
create mode 100755 tools/testing/selftests/drivers/net/stats.py
create mode 100644 tools/testing/selftests/net/lib/Makefile
create mode 100644 tools/testing/selftests/net/lib/py/__init__.py
create mode 100644 tools/testing/selftests/net/lib/py/consts.py
create mode 100644 tools/testing/selftests/net/lib/py/ksft.py
create mode 100644 tools/testing/selftests/net/lib/py/nsim.py
create mode 100644 tools/testing/selftests/net/lib/py/utils.py
create mode 100644 tools/testing/selftests/net/lib/py/ynl.py
create mode 100755 tools/testing/selftests/net/nl_netdev.py
--
2.44.0
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH net-next v2 1/7] netlink: specs: define ethtool header flags
2024-04-03 2:34 [PATCH net-next v2 0/7] selftests: net: groundwork for YNL-based tests Jakub Kicinski
@ 2024-04-03 2:34 ` Jakub Kicinski
2024-04-04 10:38 ` Petr Machata
2024-04-03 2:34 ` [PATCH net-next v2 2/7] tools: ynl: copy netlink error to NlError Jakub Kicinski
` (6 subsequent siblings)
7 siblings, 1 reply; 19+ messages in thread
From: Jakub Kicinski @ 2024-04-03 2:34 UTC (permalink / raw)
To: davem
Cc: netdev, edumazet, pabeni, shuah, sdf, donald.hunter,
linux-kselftest, petrm, Jakub Kicinski
When interfacing with the ethtool commands it's handy to
be able to use the names of the flags. Example:
ethnl.pause_get({"header": {"dev-index": cfg.ifindex,
"flags": {'stats'}}})
Note that not all commands accept all the flags,
but the meaning of the bits does not change command
to command.
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
v2:
- make sure we don't try to code gen enum (add enum-name:)
---
Documentation/netlink/specs/ethtool.yaml | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/Documentation/netlink/specs/ethtool.yaml b/Documentation/netlink/specs/ethtool.yaml
index 197208f419dc..d0e4a47e0f21 100644
--- a/Documentation/netlink/specs/ethtool.yaml
+++ b/Documentation/netlink/specs/ethtool.yaml
@@ -16,6 +16,11 @@ doc: Partial family for Ethtool Netlink.
name: stringset
type: enum
entries: []
+ -
+ name: header-flags
+ enum-name:
+ type: flags
+ entries: [ compact-bitsets, omit-reply, stats ]
attribute-sets:
-
@@ -30,6 +35,7 @@ doc: Partial family for Ethtool Netlink.
-
name: flags
type: u32
+ enum: header-flags
-
name: bitset-bit
--
2.44.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH net-next v2 2/7] tools: ynl: copy netlink error to NlError
2024-04-03 2:34 [PATCH net-next v2 0/7] selftests: net: groundwork for YNL-based tests Jakub Kicinski
2024-04-03 2:34 ` [PATCH net-next v2 1/7] netlink: specs: define ethtool header flags Jakub Kicinski
@ 2024-04-03 2:34 ` Jakub Kicinski
2024-04-04 10:39 ` Petr Machata
2024-04-03 2:34 ` [PATCH net-next v2 3/7] selftests: net: add scaffolding for Netlink tests in Python Jakub Kicinski
` (5 subsequent siblings)
7 siblings, 1 reply; 19+ messages in thread
From: Jakub Kicinski @ 2024-04-03 2:34 UTC (permalink / raw)
To: davem
Cc: netdev, edumazet, pabeni, shuah, sdf, donald.hunter,
linux-kselftest, petrm, Jakub Kicinski, jiri
Typing e.nl_msg.error when processing exception is a bit tedious
and counter-intuitive. Set a local .error member to the positive
value of the netlink level error.
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
CC: donald.hunter@gmail.com
CC: jiri@resnulli.us
---
tools/net/ynl/lib/ynl.py | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/tools/net/ynl/lib/ynl.py b/tools/net/ynl/lib/ynl.py
index 82d3c98067aa..b30210f537f7 100644
--- a/tools/net/ynl/lib/ynl.py
+++ b/tools/net/ynl/lib/ynl.py
@@ -100,9 +100,10 @@ from .nlspec import SpecFamily
class NlError(Exception):
def __init__(self, nl_msg):
self.nl_msg = nl_msg
+ self.error = -nl_msg.error
def __str__(self):
- return f"Netlink error: {os.strerror(-self.nl_msg.error)}\n{self.nl_msg}"
+ return f"Netlink error: {os.strerror(self.error)}\n{self.nl_msg}"
class ConfigError(Exception):
--
2.44.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH net-next v2 3/7] selftests: net: add scaffolding for Netlink tests in Python
2024-04-03 2:34 [PATCH net-next v2 0/7] selftests: net: groundwork for YNL-based tests Jakub Kicinski
2024-04-03 2:34 ` [PATCH net-next v2 1/7] netlink: specs: define ethtool header flags Jakub Kicinski
2024-04-03 2:34 ` [PATCH net-next v2 2/7] tools: ynl: copy netlink error to NlError Jakub Kicinski
@ 2024-04-03 2:34 ` Jakub Kicinski
2024-04-04 9:11 ` Petr Machata
2024-04-03 2:34 ` [PATCH net-next v2 4/7] selftests: nl_netdev: add a trivial Netlink netdev test Jakub Kicinski
` (4 subsequent siblings)
7 siblings, 1 reply; 19+ messages in thread
From: Jakub Kicinski @ 2024-04-03 2:34 UTC (permalink / raw)
To: davem
Cc: netdev, edumazet, pabeni, shuah, sdf, donald.hunter,
linux-kselftest, petrm, Jakub Kicinski
Add glue code for accessing the YNL library which lives under
tools/net and YAML spec files from under Documentation/.
Automatically figure out if tests are run in tree or not.
Since we'll want to use this library both from net and
drivers/net test targets make the library a target as well,
and automatically include it when net or drivers/net are
included. Making net/lib a target ensures that we end up
with only one copy of it, and saves us some path guessing.
Add a tiny bit of formatting support to be able to output KTAP
from the start.
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
v2:
- include the net/lib only in install
- support passing state to tests
- don't apply Path() on what's already a Path()
- fix spacing in Makefile's filter()
- sort imports
CC: shuah@kernel.org
CC: linux-kselftest@vger.kernel.org
---
tools/testing/selftests/Makefile | 9 +-
tools/testing/selftests/net/lib/Makefile | 8 ++
.../testing/selftests/net/lib/py/__init__.py | 6 ++
tools/testing/selftests/net/lib/py/consts.py | 9 ++
tools/testing/selftests/net/lib/py/ksft.py | 96 +++++++++++++++++++
tools/testing/selftests/net/lib/py/utils.py | 47 +++++++++
tools/testing/selftests/net/lib/py/ynl.py | 49 ++++++++++
7 files changed, 223 insertions(+), 1 deletion(-)
create mode 100644 tools/testing/selftests/net/lib/Makefile
create mode 100644 tools/testing/selftests/net/lib/py/__init__.py
create mode 100644 tools/testing/selftests/net/lib/py/consts.py
create mode 100644 tools/testing/selftests/net/lib/py/ksft.py
create mode 100644 tools/testing/selftests/net/lib/py/utils.py
create mode 100644 tools/testing/selftests/net/lib/py/ynl.py
diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile
index e1504833654d..f533eb7054fe 100644
--- a/tools/testing/selftests/Makefile
+++ b/tools/testing/selftests/Makefile
@@ -116,6 +116,13 @@ TARGETS += zram
TARGETS_HOTPLUG = cpu-hotplug
TARGETS_HOTPLUG += memory-hotplug
+# Networking tests want the net/lib target, include it automatically
+ifneq ($(filter net,$(TARGETS)),)
+ifeq ($(filter net/lib,$(TARGETS)),)
+ INSTALL_DEP_TARGETS := net/lib
+endif
+endif
+
# User can optionally provide a TARGETS skiplist. By default we skip
# BPF since it has cutting edge build time dependencies which require
# more effort to install.
@@ -245,7 +252,7 @@ ifdef INSTALL_PATH
install -m 744 run_kselftest.sh $(INSTALL_PATH)/
rm -f $(TEST_LIST)
@ret=1; \
- for TARGET in $(TARGETS); do \
+ for TARGET in $(TARGETS) $(INSTALL_DEP_TARGETS); do \
BUILD_TARGET=$$BUILD/$$TARGET; \
$(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET install \
INSTALL_PATH=$(INSTALL_PATH)/$$TARGET \
diff --git a/tools/testing/selftests/net/lib/Makefile b/tools/testing/selftests/net/lib/Makefile
new file mode 100644
index 000000000000..5730682aeffb
--- /dev/null
+++ b/tools/testing/selftests/net/lib/Makefile
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: GPL-2.0
+
+TEST_FILES := ../../../../../Documentation/netlink/s*
+TEST_FILES += ../../../../net/*
+
+TEST_INCLUDES := $(wildcard py/*.py)
+
+include ../../lib.mk
diff --git a/tools/testing/selftests/net/lib/py/__init__.py b/tools/testing/selftests/net/lib/py/__init__.py
new file mode 100644
index 000000000000..7823b5c1f8d7
--- /dev/null
+++ b/tools/testing/selftests/net/lib/py/__init__.py
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0
+
+from .consts import KSRC
+from .ksft import *
+from .utils import *
+from .ynl import NlError, YnlFamily, EthtoolFamily, NetdevFamily, RtnlFamily
diff --git a/tools/testing/selftests/net/lib/py/consts.py b/tools/testing/selftests/net/lib/py/consts.py
new file mode 100644
index 000000000000..f518ce79d82c
--- /dev/null
+++ b/tools/testing/selftests/net/lib/py/consts.py
@@ -0,0 +1,9 @@
+# SPDX-License-Identifier: GPL-2.0
+
+import sys
+from pathlib import Path
+
+KSFT_DIR = (Path(__file__).parent / "../../..").resolve()
+KSRC = (Path(__file__).parent / "../../../../../..").resolve()
+
+KSFT_MAIN_NAME = Path(sys.argv[0]).with_suffix("").name
diff --git a/tools/testing/selftests/net/lib/py/ksft.py b/tools/testing/selftests/net/lib/py/ksft.py
new file mode 100644
index 000000000000..c7210525981c
--- /dev/null
+++ b/tools/testing/selftests/net/lib/py/ksft.py
@@ -0,0 +1,96 @@
+# SPDX-License-Identifier: GPL-2.0
+
+import builtins
+from .consts import KSFT_MAIN_NAME
+
+KSFT_RESULT = None
+
+
+class KsftSkipEx(Exception):
+ pass
+
+
+class KsftXfailEx(Exception):
+ pass
+
+
+def ksft_pr(*objs, **kwargs):
+ print("#", *objs, **kwargs)
+
+
+def ksft_eq(a, b, comment=""):
+ global KSFT_RESULT
+ if a != b:
+ KSFT_RESULT = False
+ ksft_pr("Check failed", a, "!=", b, comment)
+
+
+def ksft_true(a, comment=""):
+ global KSFT_RESULT
+ if not a:
+ KSFT_RESULT = False
+ ksft_pr("Check failed", a, "does not eval to True", comment)
+
+
+def ksft_in(a, b, comment=""):
+ global KSFT_RESULT
+ if a not in b:
+ KSFT_RESULT = False
+ ksft_pr("Check failed", a, "not in", b, comment)
+
+
+def ksft_ge(a, b, comment=""):
+ global KSFT_RESULT
+ if a < b:
+ KSFT_RESULT = False
+ ksft_pr("Check failed", a, "<", b, comment)
+
+
+def ktap_result(ok, cnt=1, case="", comment=""):
+ res = ""
+ if not ok:
+ res += "not "
+ res += "ok "
+ res += str(cnt) + " "
+ res += KSFT_MAIN_NAME
+ if case:
+ res += "." + str(case.__name__)
+ if comment:
+ res += " # " + comment
+ print(res)
+
+
+def ksft_run(cases, args=()):
+ totals = {"pass": 0, "fail": 0, "skip": 0, "xfail": 0}
+
+ print("KTAP version 1")
+ print("1.." + str(len(cases)))
+
+ global KSFT_RESULT
+ cnt = 0
+ for case in cases:
+ KSFT_RESULT = True
+ cnt += 1
+ try:
+ case(*args)
+ except KsftSkipEx as e:
+ ktap_result(True, cnt, case, comment="SKIP " + str(e))
+ totals['skip'] += 1
+ continue
+ except KsftXfailEx as e:
+ ktap_result(True, cnt, case, comment="XFAIL " + str(e))
+ totals['xfail'] += 1
+ continue
+ except Exception as e:
+ for line in str(e).split('\n'):
+ ksft_pr("Exception|", line)
+ ktap_result(False, cnt, case)
+ totals['fail'] += 1
+ continue
+
+ ktap_result(KSFT_RESULT, cnt, case)
+ totals['pass'] += 1
+
+ print(
+ f"# Totals: pass:{totals['pass']} fail:{totals['fail']} xfail:{totals['xfail']} xpass:0 skip:{totals['skip']} error:0"
+ )
diff --git a/tools/testing/selftests/net/lib/py/utils.py b/tools/testing/selftests/net/lib/py/utils.py
new file mode 100644
index 000000000000..f0d425731fd4
--- /dev/null
+++ b/tools/testing/selftests/net/lib/py/utils.py
@@ -0,0 +1,47 @@
+# SPDX-License-Identifier: GPL-2.0
+
+import json as _json
+import subprocess
+
+class cmd:
+ def __init__(self, comm, shell=True, fail=True, ns=None, background=False):
+ if ns:
+ if isinstance(ns, NetNS):
+ ns = ns.name
+ comm = f'ip netns exec {ns} ' + comm
+
+ self.stdout = None
+ self.stderr = None
+ self.ret = None
+
+ self.comm = comm
+ self.proc = subprocess.Popen(comm, shell=shell, stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+ if not background:
+ self.process(terminate=False, fail=fail)
+
+ def process(self, terminate=True, fail=None):
+ if terminate:
+ self.proc.terminate()
+ stdout, stderr = self.proc.communicate()
+ self.stdout = stdout.decode("utf-8")
+ self.stderr = stderr.decode("utf-8")
+ self.proc.stdout.close()
+ self.proc.stderr.close()
+ self.ret = self.proc.returncode
+
+ if self.proc.returncode != 0 and fail:
+ if len(stderr) > 0 and stderr[-1] == "\n":
+ stderr = stderr[:-1]
+ raise Exception("Command failed: %s\n%s" % (self.proc.args, stderr))
+
+
+def ip(args, json=None, ns=None):
+ cmd_str = "ip "
+ if json:
+ cmd_str += '-j '
+ cmd_str += args
+ cmd_obj = cmd(cmd_str, ns=ns)
+ if json:
+ return _json.loads(cmd_obj.stdout)
+ return cmd_obj
diff --git a/tools/testing/selftests/net/lib/py/ynl.py b/tools/testing/selftests/net/lib/py/ynl.py
new file mode 100644
index 000000000000..1ace58370c06
--- /dev/null
+++ b/tools/testing/selftests/net/lib/py/ynl.py
@@ -0,0 +1,49 @@
+# SPDX-License-Identifier: GPL-2.0
+
+import sys
+from pathlib import Path
+from .consts import KSRC, KSFT_DIR
+from .ksft import ksft_pr, ktap_result
+
+# Resolve paths
+try:
+ if (KSFT_DIR / "kselftest-list.txt").exists():
+ # Running in "installed" selftests
+ tools_full_path = KSFT_DIR
+ SPEC_PATH = KSFT_DIR / "net/lib/specs"
+
+ sys.path.append(tools_full_path.as_posix())
+ from net.lib.ynl.lib import YnlFamily, NlError
+ else:
+ # Running in tree
+ tools_full_path = KSRC / "tools"
+ SPEC_PATH = KSRC / "Documentation/netlink/specs"
+
+ sys.path.append(tools_full_path.as_posix())
+ from net.ynl.lib import YnlFamily, NlError
+except ModuleNotFoundError as e:
+ ksft_pr("Failed importing `ynl` library from kernel sources")
+ ksft_pr(str(e))
+ ktap_result(True, comment="SKIP")
+ sys.exit(4)
+
+#
+# Wrapper classes, loading the right specs
+# Set schema='' to avoid jsonschema validation, it's slow
+#
+class EthtoolFamily(YnlFamily):
+ def __init__(self):
+ super().__init__((SPEC_PATH / Path('ethtool.yaml')).as_posix(),
+ schema='')
+
+
+class RtnlFamily(YnlFamily):
+ def __init__(self):
+ super().__init__((SPEC_PATH / Path('rt_link.yaml')).as_posix(),
+ schema='')
+
+
+class NetdevFamily(YnlFamily):
+ def __init__(self):
+ super().__init__((SPEC_PATH / Path('netdev.yaml')).as_posix(),
+ schema='')
--
2.44.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH net-next v2 4/7] selftests: nl_netdev: add a trivial Netlink netdev test
2024-04-03 2:34 [PATCH net-next v2 0/7] selftests: net: groundwork for YNL-based tests Jakub Kicinski
` (2 preceding siblings ...)
2024-04-03 2:34 ` [PATCH net-next v2 3/7] selftests: net: add scaffolding for Netlink tests in Python Jakub Kicinski
@ 2024-04-03 2:34 ` Jakub Kicinski
2024-04-04 10:39 ` Petr Machata
2024-04-03 2:34 ` [PATCH net-next v2 5/7] netdevsim: report stats by default, like a real device Jakub Kicinski
` (3 subsequent siblings)
7 siblings, 1 reply; 19+ messages in thread
From: Jakub Kicinski @ 2024-04-03 2:34 UTC (permalink / raw)
To: davem
Cc: netdev, edumazet, pabeni, shuah, sdf, donald.hunter,
linux-kselftest, petrm, Jakub Kicinski
Add a trivial test using YNL.
$ ./tools/testing/selftests/net/nl_netdev.py
KTAP version 1
1..2
ok 1 nl_netdev.empty_check
ok 2 nl_netdev.lo_check
Instantiate the family once, it takes longer than the test itself.
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
v2:
- pass family as argument
CC: shuah@kernel.org
CC: linux-kselftest@vger.kernel.org
---
tools/testing/selftests/net/Makefile | 1 +
tools/testing/selftests/net/nl_netdev.py | 24 ++++++++++++++++++++++++
2 files changed, 25 insertions(+)
create mode 100755 tools/testing/selftests/net/nl_netdev.py
diff --git a/tools/testing/selftests/net/Makefile b/tools/testing/selftests/net/Makefile
index cb418a2346bc..5e34c93aa51b 100644
--- a/tools/testing/selftests/net/Makefile
+++ b/tools/testing/selftests/net/Makefile
@@ -34,6 +34,7 @@ TEST_PROGS += gre_gso.sh
TEST_PROGS += cmsg_so_mark.sh
TEST_PROGS += cmsg_time.sh cmsg_ipv6.sh
TEST_PROGS += netns-name.sh
+TEST_PROGS += nl_netdev.py
TEST_PROGS += srv6_end_dt46_l3vpn_test.sh
TEST_PROGS += srv6_end_dt4_l3vpn_test.sh
TEST_PROGS += srv6_end_dt6_l3vpn_test.sh
diff --git a/tools/testing/selftests/net/nl_netdev.py b/tools/testing/selftests/net/nl_netdev.py
new file mode 100755
index 000000000000..2b8b488fb419
--- /dev/null
+++ b/tools/testing/selftests/net/nl_netdev.py
@@ -0,0 +1,24 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0
+
+from lib.py import ksft_run, ksft_pr, ksft_eq, ksft_ge, NetdevFamily
+
+
+def empty_check(nf) -> None:
+ devs = nf.dev_get({}, dump=True)
+ ksft_ge(len(devs), 1)
+
+
+def lo_check(nf) -> None:
+ lo_info = nf.dev_get({"ifindex": 1})
+ ksft_eq(len(lo_info['xdp-features']), 0)
+ ksft_eq(len(lo_info['xdp-rx-metadata-features']), 0)
+
+
+def main() -> None:
+ nf = NetdevFamily()
+ ksft_run([empty_check, lo_check], args=(nf, ))
+
+
+if __name__ == "__main__":
+ main()
--
2.44.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH net-next v2 5/7] netdevsim: report stats by default, like a real device
2024-04-03 2:34 [PATCH net-next v2 0/7] selftests: net: groundwork for YNL-based tests Jakub Kicinski
` (3 preceding siblings ...)
2024-04-03 2:34 ` [PATCH net-next v2 4/7] selftests: nl_netdev: add a trivial Netlink netdev test Jakub Kicinski
@ 2024-04-03 2:34 ` Jakub Kicinski
2024-04-04 10:40 ` Petr Machata
2024-04-04 13:40 ` Paolo Abeni
2024-04-03 2:34 ` [PATCH net-next v2 6/7] selftests: drivers: add scaffolding for Netlink tests in Python Jakub Kicinski
` (2 subsequent siblings)
7 siblings, 2 replies; 19+ messages in thread
From: Jakub Kicinski @ 2024-04-03 2:34 UTC (permalink / raw)
To: davem
Cc: netdev, edumazet, pabeni, shuah, sdf, donald.hunter,
linux-kselftest, petrm, Jakub Kicinski
Real devices should implement qstats. Devices which support
pause or FEC configuration should also report the relevant stats.
nsim was missing FEC stats completely, some of the qstats
and pause stats required toggling a debugfs knob.
Note that the tests which used pause always initialize the setting
so they shouldn't be affected by the different starting value.
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
drivers/net/netdevsim/ethtool.c | 11 ++++++++
drivers/net/netdevsim/netdev.c | 45 +++++++++++++++++++++++++++++++++
2 files changed, 56 insertions(+)
diff --git a/drivers/net/netdevsim/ethtool.c b/drivers/net/netdevsim/ethtool.c
index bd546d4d26c6..3f9c9327f149 100644
--- a/drivers/net/netdevsim/ethtool.c
+++ b/drivers/net/netdevsim/ethtool.c
@@ -140,6 +140,13 @@ nsim_set_fecparam(struct net_device *dev, struct ethtool_fecparam *fecparam)
return 0;
}
+static void
+nsim_get_fec_stats(struct net_device *dev, struct ethtool_fec_stats *fec_stats)
+{
+ fec_stats->corrected_blocks.total = 123;
+ fec_stats->uncorrectable_blocks.total = 4;
+}
+
static int nsim_get_ts_info(struct net_device *dev,
struct ethtool_ts_info *info)
{
@@ -163,6 +170,7 @@ static const struct ethtool_ops nsim_ethtool_ops = {
.set_channels = nsim_set_channels,
.get_fecparam = nsim_get_fecparam,
.set_fecparam = nsim_set_fecparam,
+ .get_fec_stats = nsim_get_fec_stats,
.get_ts_info = nsim_get_ts_info,
};
@@ -182,6 +190,9 @@ void nsim_ethtool_init(struct netdevsim *ns)
nsim_ethtool_ring_init(ns);
+ ns->ethtool.pauseparam.report_stats_rx = true;
+ ns->ethtool.pauseparam.report_stats_tx = true;
+
ns->ethtool.fec.fec = ETHTOOL_FEC_NONE;
ns->ethtool.fec.active_fec = ETHTOOL_FEC_NONE;
diff --git a/drivers/net/netdevsim/netdev.c b/drivers/net/netdevsim/netdev.c
index 8330bc0bcb7e..096ac0abbc02 100644
--- a/drivers/net/netdevsim/netdev.c
+++ b/drivers/net/netdevsim/netdev.c
@@ -19,6 +19,7 @@
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/slab.h>
+#include <net/netdev_queues.h>
#include <net/netlink.h>
#include <net/pkt_cls.h>
#include <net/rtnetlink.h>
@@ -330,6 +331,49 @@ static const struct net_device_ops nsim_vf_netdev_ops = {
.ndo_set_features = nsim_set_features,
};
+/* We don't have true par-queue stats, yet, so do some random fakery here. */
+static void nsim_get_queue_stats_rx(struct net_device *dev, int idx,
+ struct netdev_queue_stats_rx *stats)
+{
+ struct rtnl_link_stats64 rtstats = {};
+
+ nsim_get_stats64(dev, &rtstats);
+
+ stats->packets = rtstats.rx_packets - !!rtstats.rx_packets;
+ stats->bytes = rtstats.rx_bytes;
+}
+
+static void nsim_get_queue_stats_tx(struct net_device *dev, int idx,
+ struct netdev_queue_stats_tx *stats)
+{
+ struct rtnl_link_stats64 rtstats = {};
+
+ nsim_get_stats64(dev, &rtstats);
+
+ stats->packets = rtstats.tx_packets - !!rtstats.tx_packets;
+ stats->bytes = rtstats.tx_bytes;
+}
+
+static void nsim_get_base_stats(struct net_device *dev,
+ struct netdev_queue_stats_rx *rx,
+ struct netdev_queue_stats_tx *tx)
+{
+ struct rtnl_link_stats64 rtstats = {};
+
+ nsim_get_stats64(dev, &rtstats);
+
+ rx->packets = !!rtstats.rx_packets;
+ rx->bytes = 0;
+ tx->packets = !!rtstats.tx_packets;
+ tx->bytes = 0;
+}
+
+static const struct netdev_stat_ops nsim_stat_ops = {
+ .get_queue_stats_tx = nsim_get_queue_stats_tx,
+ .get_queue_stats_rx = nsim_get_queue_stats_rx,
+ .get_base_stats = nsim_get_base_stats,
+};
+
static void nsim_setup(struct net_device *dev)
{
ether_setup(dev);
@@ -360,6 +404,7 @@ static int nsim_init_netdevsim(struct netdevsim *ns)
ns->phc = phc;
ns->netdev->netdev_ops = &nsim_netdev_ops;
+ ns->netdev->stat_ops = &nsim_stat_ops;
err = nsim_udp_tunnels_info_create(ns->nsim_dev, ns->netdev);
if (err)
--
2.44.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH net-next v2 6/7] selftests: drivers: add scaffolding for Netlink tests in Python
2024-04-03 2:34 [PATCH net-next v2 0/7] selftests: net: groundwork for YNL-based tests Jakub Kicinski
` (4 preceding siblings ...)
2024-04-03 2:34 ` [PATCH net-next v2 5/7] netdevsim: report stats by default, like a real device Jakub Kicinski
@ 2024-04-03 2:34 ` Jakub Kicinski
2024-04-04 10:42 ` Petr Machata
2024-04-03 2:34 ` [PATCH net-next v2 7/7] testing: net-drv: add a driver test for stats reporting Jakub Kicinski
2024-04-04 17:40 ` [PATCH net-next v2 0/7] selftests: net: groundwork for YNL-based tests patchwork-bot+netdevbpf
7 siblings, 1 reply; 19+ messages in thread
From: Jakub Kicinski @ 2024-04-03 2:34 UTC (permalink / raw)
To: davem
Cc: netdev, edumazet, pabeni, shuah, sdf, donald.hunter,
linux-kselftest, petrm, Jakub Kicinski
Add drivers/net as a target for mixed-use tests.
The setup is expected to work similarly to the forwarding tests.
Since we only need one interface (unlike forwarding tests)
read the target device name from NETIF. If not present we'll
try to run the test against netdevsim.
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
v2:
- mark regex as r""
- add support of using env as with
---
tools/testing/selftests/Makefile | 3 +-
tools/testing/selftests/drivers/net/Makefile | 7 ++
.../testing/selftests/drivers/net/README.rst | 30 +++++
.../selftests/drivers/net/lib/py/__init__.py | 17 +++
.../selftests/drivers/net/lib/py/env.py | 52 ++++++++
.../testing/selftests/net/lib/py/__init__.py | 1 +
tools/testing/selftests/net/lib/py/nsim.py | 118 ++++++++++++++++++
7 files changed, 227 insertions(+), 1 deletion(-)
create mode 100644 tools/testing/selftests/drivers/net/Makefile
create mode 100644 tools/testing/selftests/drivers/net/README.rst
create mode 100644 tools/testing/selftests/drivers/net/lib/py/__init__.py
create mode 100644 tools/testing/selftests/drivers/net/lib/py/env.py
create mode 100644 tools/testing/selftests/net/lib/py/nsim.py
diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile
index f533eb7054fe..6dab886d6f7a 100644
--- a/tools/testing/selftests/Makefile
+++ b/tools/testing/selftests/Makefile
@@ -17,6 +17,7 @@ TARGETS += devices
TARGETS += dmabuf-heaps
TARGETS += drivers/dma-buf
TARGETS += drivers/s390x/uvdevice
+TARGETS += drivers/net
TARGETS += drivers/net/bonding
TARGETS += drivers/net/team
TARGETS += dt
@@ -117,7 +118,7 @@ TARGETS_HOTPLUG = cpu-hotplug
TARGETS_HOTPLUG += memory-hotplug
# Networking tests want the net/lib target, include it automatically
-ifneq ($(filter net,$(TARGETS)),)
+ifneq ($(filter net drivers/net,$(TARGETS)),)
ifeq ($(filter net/lib,$(TARGETS)),)
INSTALL_DEP_TARGETS := net/lib
endif
diff --git a/tools/testing/selftests/drivers/net/Makefile b/tools/testing/selftests/drivers/net/Makefile
new file mode 100644
index 000000000000..379cdb1960a7
--- /dev/null
+++ b/tools/testing/selftests/drivers/net/Makefile
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0
+
+TEST_INCLUDES := $(wildcard lib/py/*.py)
+
+TEST_PROGS := stats.py
+
+include ../../lib.mk
diff --git a/tools/testing/selftests/drivers/net/README.rst b/tools/testing/selftests/drivers/net/README.rst
new file mode 100644
index 000000000000..5ef7c417d431
--- /dev/null
+++ b/tools/testing/selftests/drivers/net/README.rst
@@ -0,0 +1,30 @@
+Running tests
+=============
+
+Tests are executed within kselftest framework like any other tests.
+By default tests execute against software drivers such as netdevsim.
+All tests must support running against a real device (SW-only tests
+should instead be placed in net/ or drivers/net/netdevsim, HW-only
+tests in drivers/net/hw).
+
+Set appropriate variables to point the tests at a real device.
+
+Variables
+=========
+
+Variables can be set in the environment or by creating a net.config
+file in the same directory as this README file. Example::
+
+ $ NETIF=eth0 ./some_test.sh
+
+or::
+
+ $ cat tools/testing/selftests/drivers/net/net.config
+ # Variable set in a file
+ NETIF=eth0
+
+NETIF
+~~~~~
+
+Name of the netdevice against which the test should be executed.
+When empty or not set software devices will be used.
diff --git a/tools/testing/selftests/drivers/net/lib/py/__init__.py b/tools/testing/selftests/drivers/net/lib/py/__init__.py
new file mode 100644
index 000000000000..4653dffcd962
--- /dev/null
+++ b/tools/testing/selftests/drivers/net/lib/py/__init__.py
@@ -0,0 +1,17 @@
+# SPDX-License-Identifier: GPL-2.0
+
+import sys
+from pathlib import Path
+
+KSFT_DIR = (Path(__file__).parent / "../../../..").resolve()
+
+try:
+ sys.path.append(KSFT_DIR.as_posix())
+ from net.lib.py import *
+except ModuleNotFoundError as e:
+ ksft_pr("Failed importing `net` library from kernel sources")
+ ksft_pr(str(e))
+ ktap_result(True, comment="SKIP")
+ sys.exit(4)
+
+from .env import *
diff --git a/tools/testing/selftests/drivers/net/lib/py/env.py b/tools/testing/selftests/drivers/net/lib/py/env.py
new file mode 100644
index 000000000000..e1abe9491daf
--- /dev/null
+++ b/tools/testing/selftests/drivers/net/lib/py/env.py
@@ -0,0 +1,52 @@
+# SPDX-License-Identifier: GPL-2.0
+
+import os
+import shlex
+from pathlib import Path
+from lib.py import ip
+from lib.py import NetdevSimDev
+
+class NetDrvEnv:
+ def __init__(self, src_path):
+ self._ns = None
+
+ self.env = os.environ.copy()
+ self._load_env_file(src_path)
+
+ if 'NETIF' in self.env:
+ self.dev = ip("link show dev " + self.env['NETIF'], json=True)[0]
+ else:
+ self._ns = NetdevSimDev()
+ self.dev = self._ns.nsims[0].dev
+ self.ifindex = self.dev['ifindex']
+
+ def __enter__(self):
+ return self
+
+ def __exit__(self, ex_type, ex_value, ex_tb):
+ """
+ __exit__ gets called at the end of a "with" block.
+ """
+ self.__del__()
+
+ def __del__(self):
+ if self._ns:
+ self._ns.remove()
+ self._ns = None
+
+ def _load_env_file(self, src_path):
+ src_dir = Path(src_path).parent.resolve()
+ if not (src_dir / "net.config").exists():
+ return
+
+ lexer = shlex.shlex(open((src_dir / "net.config").as_posix(), 'r').read())
+ k = None
+ for token in lexer:
+ if k is None:
+ k = token
+ self.env[k] = ""
+ elif token == "=":
+ pass
+ else:
+ self.env[k] = token
+ k = None
diff --git a/tools/testing/selftests/net/lib/py/__init__.py b/tools/testing/selftests/net/lib/py/__init__.py
index 7823b5c1f8d7..ded7102df18a 100644
--- a/tools/testing/selftests/net/lib/py/__init__.py
+++ b/tools/testing/selftests/net/lib/py/__init__.py
@@ -2,5 +2,6 @@
from .consts import KSRC
from .ksft import *
+from .nsim import *
from .utils import *
from .ynl import NlError, YnlFamily, EthtoolFamily, NetdevFamily, RtnlFamily
diff --git a/tools/testing/selftests/net/lib/py/nsim.py b/tools/testing/selftests/net/lib/py/nsim.py
new file mode 100644
index 000000000000..25ae0d081788
--- /dev/null
+++ b/tools/testing/selftests/net/lib/py/nsim.py
@@ -0,0 +1,118 @@
+# SPDX-License-Identifier: GPL-2.0
+
+import json
+import os
+import random
+import re
+import time
+from .utils import cmd, ip
+
+
+class NetdevSim:
+ """
+ Class for netdevsim netdevice and its attributes.
+ """
+
+ def __init__(self, nsimdev, port_index, ifname, ns=None):
+ # In case udev renamed the netdev to according to new schema,
+ # check if the name matches the port_index.
+ nsimnamere = re.compile(r"eni\d+np(\d+)")
+ match = nsimnamere.match(ifname)
+ if match and int(match.groups()[0]) != port_index + 1:
+ raise Exception("netdevice name mismatches the expected one")
+
+ self.ifname = ifname
+ self.nsimdev = nsimdev
+ self.port_index = port_index
+ self.ns = ns
+ self.dfs_dir = "%s/ports/%u/" % (nsimdev.dfs_dir, port_index)
+ ret = ip("-j link show dev %s" % ifname, ns=ns)
+ self.dev = json.loads(ret.stdout)[0]
+
+ def dfs_write(self, path, val):
+ self.nsimdev.dfs_write(f'ports/{self.port_index}/' + path, val)
+
+
+class NetdevSimDev:
+ """
+ Class for netdevsim bus device and its attributes.
+ """
+ @staticmethod
+ def ctrl_write(path, val):
+ fullpath = os.path.join("/sys/bus/netdevsim/", path)
+ with open(fullpath, "w") as f:
+ f.write(val)
+
+ def dfs_write(self, path, val):
+ fullpath = os.path.join(f"/sys/kernel/debug/netdevsim/netdevsim{self.addr}/", path)
+ with open(fullpath, "w") as f:
+ f.write(val)
+
+ def __init__(self, port_count=1, ns=None):
+ # nsim will spawn in init_net, we'll set to actual ns once we switch it the.sre
+ self.ns = None
+
+ if not os.path.exists("/sys/bus/netdevsim"):
+ cmd("modprobe netdevsim")
+
+ addr = random.randrange(1 << 15)
+ while True:
+ try:
+ self.ctrl_write("new_device", "%u %u" % (addr, port_count))
+ except OSError as e:
+ if e.errno == errno.ENOSPC:
+ addr = random.randrange(1 << 15)
+ continue
+ raise e
+ break
+ self.addr = addr
+
+ # As probe of netdevsim device might happen from a workqueue,
+ # so wait here until all netdevs appear.
+ self.wait_for_netdevs(port_count)
+
+ if ns:
+ cmd(f"devlink dev reload netdevsim/netdevsim{addr} netns {ns.name}")
+ self.ns = ns
+
+ cmd("udevadm settle", ns=self.ns)
+ ifnames = self.get_ifnames()
+
+ self.dfs_dir = "/sys/kernel/debug/netdevsim/netdevsim%u/" % addr
+
+ self.nsims = []
+ for port_index in range(port_count):
+ self.nsims.append(NetdevSim(self, port_index, ifnames[port_index],
+ ns=ns))
+
+ def get_ifnames(self):
+ ifnames = []
+ listdir = cmd(f"ls /sys/bus/netdevsim/devices/netdevsim{self.addr}/net/",
+ ns=self.ns).stdout.split()
+ for ifname in listdir:
+ ifnames.append(ifname)
+ ifnames.sort()
+ return ifnames
+
+ def wait_for_netdevs(self, port_count):
+ timeout = 5
+ timeout_start = time.time()
+
+ while True:
+ try:
+ ifnames = self.get_ifnames()
+ except FileNotFoundError as e:
+ ifnames = []
+ if len(ifnames) == port_count:
+ break
+ if time.time() < timeout_start + timeout:
+ continue
+ raise Exception("netdevices did not appear within timeout")
+
+ def remove(self):
+ self.ctrl_write("del_device", "%u" % (self.addr, ))
+
+ def remove_nsim(self, nsim):
+ self.nsims.remove(nsim)
+ self.ctrl_write("devices/netdevsim%u/del_port" % (self.addr, ),
+ "%u" % (nsim.port_index, ))
--
2.44.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH net-next v2 7/7] testing: net-drv: add a driver test for stats reporting
2024-04-03 2:34 [PATCH net-next v2 0/7] selftests: net: groundwork for YNL-based tests Jakub Kicinski
` (5 preceding siblings ...)
2024-04-03 2:34 ` [PATCH net-next v2 6/7] selftests: drivers: add scaffolding for Netlink tests in Python Jakub Kicinski
@ 2024-04-03 2:34 ` Jakub Kicinski
2024-04-04 17:40 ` [PATCH net-next v2 0/7] selftests: net: groundwork for YNL-based tests patchwork-bot+netdevbpf
7 siblings, 0 replies; 19+ messages in thread
From: Jakub Kicinski @ 2024-04-03 2:34 UTC (permalink / raw)
To: davem
Cc: netdev, edumazet, pabeni, shuah, sdf, donald.hunter,
linux-kselftest, petrm, Jakub Kicinski
Add a very simple test to make sure drivers report expected
stats. Drivers which implement FEC or pause configuration
should report relevant stats. Qstats must be reported,
at least packet and byte counts, and they must match
total device stats.
Tested with netdevsim, bnxt, in-tree and installed.
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
v2:
- pass cfg as argument
- use with
---
tools/testing/selftests/drivers/net/stats.py | 86 ++++++++++++++++++++
1 file changed, 86 insertions(+)
create mode 100755 tools/testing/selftests/drivers/net/stats.py
diff --git a/tools/testing/selftests/drivers/net/stats.py b/tools/testing/selftests/drivers/net/stats.py
new file mode 100755
index 000000000000..5a9d4e56b28b
--- /dev/null
+++ b/tools/testing/selftests/drivers/net/stats.py
@@ -0,0 +1,86 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0
+
+from lib.py import ksft_run, ksft_in, ksft_true, KsftSkipEx, KsftXfailEx
+from lib.py import EthtoolFamily, NetdevFamily, RtnlFamily, NlError
+from lib.py import NetDrvEnv
+
+ethnl = EthtoolFamily()
+netfam = NetdevFamily()
+rtnl = RtnlFamily()
+
+
+def check_pause(cfg) -> None:
+ global ethnl
+
+ try:
+ ethnl.pause_get({"header": {"dev-index": cfg.ifindex}})
+ except NlError as e:
+ if e.error == 95:
+ raise KsftXfailEx("pause not supported by the device")
+ raise
+
+ data = ethnl.pause_get({"header": {"dev-index": cfg.ifindex,
+ "flags": {'stats'}}})
+ ksft_true(data['stats'], "driver does not report stats")
+
+
+def check_fec(cfg) -> None:
+ global ethnl
+
+ try:
+ ethnl.fec_get({"header": {"dev-index": cfg.ifindex}})
+ except NlError as e:
+ if e.error == 95:
+ raise KsftXfailEx("FEC not supported by the device")
+ raise
+
+ data = ethnl.fec_get({"header": {"dev-index": cfg.ifindex,
+ "flags": {'stats'}}})
+ ksft_true(data['stats'], "driver does not report stats")
+
+
+def pkt_byte_sum(cfg) -> None:
+ global netfam, rtnl
+
+ def get_qstat(test):
+ global netfam
+ stats = netfam.qstats_get({}, dump=True)
+ if stats:
+ for qs in stats:
+ if qs["ifindex"]== test.ifindex:
+ return qs
+
+ qstat = get_qstat(cfg)
+ if qstat is None:
+ raise KsftSkipEx("qstats not supported by the device")
+
+ for key in ['tx-packets', 'tx-bytes', 'rx-packets', 'rx-bytes']:
+ ksft_in(key, qstat, "Drivers should always report basic keys")
+
+ # Compare stats, rtnl stats and qstats must match,
+ # but the interface may be up, so do a series of dumps
+ # each time the more "recent" stats must be higher or same.
+ def stat_cmp(rstat, qstat):
+ for key in ['tx-packets', 'tx-bytes', 'rx-packets', 'rx-bytes']:
+ if rstat[key] != qstat[key]:
+ return rstat[key] - qstat[key]
+ return 0
+
+ for _ in range(10):
+ rtstat = rtnl.getlink({"ifi-index": cfg.ifindex})['stats']
+ if stat_cmp(rtstat, qstat) < 0:
+ raise Exception("RTNL stats are lower, fetched later")
+ qstat = get_qstat(cfg)
+ if stat_cmp(rtstat, qstat) > 0:
+ raise Exception("Qstats are lower, fetched later")
+
+
+def main() -> None:
+ with NetDrvEnv(__file__) as cfg:
+ ksft_run([check_pause, check_fec, pkt_byte_sum],
+ args=(cfg, ))
+
+
+if __name__ == "__main__":
+ main()
--
2.44.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH net-next v2 3/7] selftests: net: add scaffolding for Netlink tests in Python
2024-04-03 2:34 ` [PATCH net-next v2 3/7] selftests: net: add scaffolding for Netlink tests in Python Jakub Kicinski
@ 2024-04-04 9:11 ` Petr Machata
0 siblings, 0 replies; 19+ messages in thread
From: Petr Machata @ 2024-04-04 9:11 UTC (permalink / raw)
To: Jakub Kicinski
Cc: davem, netdev, edumazet, pabeni, shuah, sdf, donald.hunter,
linux-kselftest, petrm
Jakub Kicinski <kuba@kernel.org> writes:
> Add glue code for accessing the YNL library which lives under
> tools/net and YAML spec files from under Documentation/.
> Automatically figure out if tests are run in tree or not.
> Since we'll want to use this library both from net and
> drivers/net test targets make the library a target as well,
> and automatically include it when net or drivers/net are
> included. Making net/lib a target ensures that we end up
> with only one copy of it, and saves us some path guessing.
>
> Add a tiny bit of formatting support to be able to output KTAP
> from the start.
>
> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
> ---
> v2:
> - include the net/lib only in install
> - support passing state to tests
> - don't apply Path() on what's already a Path()
> - fix spacing in Makefile's filter()
> - sort imports
>
> CC: shuah@kernel.org
> CC: linux-kselftest@vger.kernel.org
> ---
> tools/testing/selftests/Makefile | 9 +-
> tools/testing/selftests/net/lib/Makefile | 8 ++
> .../testing/selftests/net/lib/py/__init__.py | 6 ++
> tools/testing/selftests/net/lib/py/consts.py | 9 ++
> tools/testing/selftests/net/lib/py/ksft.py | 96 +++++++++++++++++++
> tools/testing/selftests/net/lib/py/utils.py | 47 +++++++++
> tools/testing/selftests/net/lib/py/ynl.py | 49 ++++++++++
> 7 files changed, 223 insertions(+), 1 deletion(-)
> create mode 100644 tools/testing/selftests/net/lib/Makefile
> create mode 100644 tools/testing/selftests/net/lib/py/__init__.py
> create mode 100644 tools/testing/selftests/net/lib/py/consts.py
> create mode 100644 tools/testing/selftests/net/lib/py/ksft.py
> create mode 100644 tools/testing/selftests/net/lib/py/utils.py
> create mode 100644 tools/testing/selftests/net/lib/py/ynl.py
>
> diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile
> index e1504833654d..f533eb7054fe 100644
> --- a/tools/testing/selftests/Makefile
> +++ b/tools/testing/selftests/Makefile
> @@ -116,6 +116,13 @@ TARGETS += zram
> TARGETS_HOTPLUG = cpu-hotplug
> TARGETS_HOTPLUG += memory-hotplug
>
> +# Networking tests want the net/lib target, include it automatically
> +ifneq ($(filter net,$(TARGETS)),)
> +ifeq ($(filter net/lib,$(TARGETS)),)
> + INSTALL_DEP_TARGETS := net/lib
> +endif
> +endif
> +
> # User can optionally provide a TARGETS skiplist. By default we skip
> # BPF since it has cutting edge build time dependencies which require
> # more effort to install.
> @@ -245,7 +252,7 @@ ifdef INSTALL_PATH
> install -m 744 run_kselftest.sh $(INSTALL_PATH)/
> rm -f $(TEST_LIST)
> @ret=1; \
> - for TARGET in $(TARGETS); do \
> + for TARGET in $(TARGETS) $(INSTALL_DEP_TARGETS); do \
> BUILD_TARGET=$$BUILD/$$TARGET; \
> $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET install \
> INSTALL_PATH=$(INSTALL_PATH)/$$TARGET \
> diff --git a/tools/testing/selftests/net/lib/Makefile b/tools/testing/selftests/net/lib/Makefile
> new file mode 100644
> index 000000000000..5730682aeffb
> --- /dev/null
> +++ b/tools/testing/selftests/net/lib/Makefile
> @@ -0,0 +1,8 @@
> +# SPDX-License-Identifier: GPL-2.0
> +
> +TEST_FILES := ../../../../../Documentation/netlink/s*
Not sure I understand the motivation for the wildcard. Currently this
matches Documentation/netlink/specs. Do you expect everything that
starts with s to be a testfile?
> +TEST_FILES += ../../../../net/*
Likewise this -- it's just tools/net/ynl? Will everything that's there
be a testfile?
> +TEST_INCLUDES := $(wildcard py/*.py)
> +
> +include ../../lib.mk
Other than that it looks OK.
Reviewed-by: Petr Machata <petrm@nvidia.com>
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH net-next v2 1/7] netlink: specs: define ethtool header flags
2024-04-03 2:34 ` [PATCH net-next v2 1/7] netlink: specs: define ethtool header flags Jakub Kicinski
@ 2024-04-04 10:38 ` Petr Machata
0 siblings, 0 replies; 19+ messages in thread
From: Petr Machata @ 2024-04-04 10:38 UTC (permalink / raw)
To: Jakub Kicinski
Cc: davem, netdev, edumazet, pabeni, shuah, sdf, donald.hunter,
linux-kselftest, petrm
Jakub Kicinski <kuba@kernel.org> writes:
> When interfacing with the ethtool commands it's handy to
> be able to use the names of the flags. Example:
>
> ethnl.pause_get({"header": {"dev-index": cfg.ifindex,
> "flags": {'stats'}}})
>
> Note that not all commands accept all the flags,
> but the meaning of the bits does not change command
> to command.
>
> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Reviewed-by: Petr Machata <petrm@nvidia.com>
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH net-next v2 2/7] tools: ynl: copy netlink error to NlError
2024-04-03 2:34 ` [PATCH net-next v2 2/7] tools: ynl: copy netlink error to NlError Jakub Kicinski
@ 2024-04-04 10:39 ` Petr Machata
0 siblings, 0 replies; 19+ messages in thread
From: Petr Machata @ 2024-04-04 10:39 UTC (permalink / raw)
To: Jakub Kicinski
Cc: davem, netdev, edumazet, pabeni, shuah, sdf, donald.hunter,
linux-kselftest, petrm, jiri
Jakub Kicinski <kuba@kernel.org> writes:
> Typing e.nl_msg.error when processing exception is a bit tedious
> and counter-intuitive. Set a local .error member to the positive
> value of the netlink level error.
>
> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Reviewed-by: Petr Machata <petrm@nvidia.com>
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH net-next v2 4/7] selftests: nl_netdev: add a trivial Netlink netdev test
2024-04-03 2:34 ` [PATCH net-next v2 4/7] selftests: nl_netdev: add a trivial Netlink netdev test Jakub Kicinski
@ 2024-04-04 10:39 ` Petr Machata
0 siblings, 0 replies; 19+ messages in thread
From: Petr Machata @ 2024-04-04 10:39 UTC (permalink / raw)
To: Jakub Kicinski
Cc: davem, netdev, edumazet, pabeni, shuah, sdf, donald.hunter,
linux-kselftest, petrm
Jakub Kicinski <kuba@kernel.org> writes:
> Add a trivial test using YNL.
>
> $ ./tools/testing/selftests/net/nl_netdev.py
> KTAP version 1
> 1..2
> ok 1 nl_netdev.empty_check
> ok 2 nl_netdev.lo_check
>
> Instantiate the family once, it takes longer than the test itself.
>
> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Reviewed-by: Petr Machata <petrm@nvidia.com>
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH net-next v2 5/7] netdevsim: report stats by default, like a real device
2024-04-03 2:34 ` [PATCH net-next v2 5/7] netdevsim: report stats by default, like a real device Jakub Kicinski
@ 2024-04-04 10:40 ` Petr Machata
2024-04-04 13:52 ` Jakub Kicinski
2024-04-04 13:40 ` Paolo Abeni
1 sibling, 1 reply; 19+ messages in thread
From: Petr Machata @ 2024-04-04 10:40 UTC (permalink / raw)
To: Jakub Kicinski
Cc: davem, netdev, edumazet, pabeni, shuah, sdf, donald.hunter,
linux-kselftest, petrm
Jakub Kicinski <kuba@kernel.org> writes:
> Real devices should implement qstats. Devices which support
> pause or FEC configuration should also report the relevant stats.
>
> nsim was missing FEC stats completely, some of the qstats
> and pause stats required toggling a debugfs knob.
>
> Note that the tests which used pause always initialize the setting
> so they shouldn't be affected by the different starting value.
>
> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Reviewed-by: Petr Machata <petrm@nvidia.com>
Just:
> @@ -330,6 +331,49 @@ static const struct net_device_ops nsim_vf_netdev_ops = {
> .ndo_set_features = nsim_set_features,
> };
>
> +/* We don't have true par-queue stats, yet, so do some random fakery here. */
per
> +static void nsim_get_queue_stats_rx(struct net_device *dev, int idx,
> + struct netdev_queue_stats_rx *stats)
> +{
> + struct rtnl_link_stats64 rtstats = {};
> +
> + nsim_get_stats64(dev, &rtstats);
> +
> + stats->packets = rtstats.rx_packets - !!rtstats.rx_packets;
This is just to make sure that per-queue stats are lower than the
overall rtstats I presume?
> + stats->bytes = rtstats.rx_bytes;
> +}
> +
> +static void nsim_get_queue_stats_tx(struct net_device *dev, int idx,
> + struct netdev_queue_stats_tx *stats)
> +{
> + struct rtnl_link_stats64 rtstats = {};
> +
> + nsim_get_stats64(dev, &rtstats);
> +
> + stats->packets = rtstats.tx_packets - !!rtstats.tx_packets;
> + stats->bytes = rtstats.tx_bytes;
> +}
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH net-next v2 6/7] selftests: drivers: add scaffolding for Netlink tests in Python
2024-04-03 2:34 ` [PATCH net-next v2 6/7] selftests: drivers: add scaffolding for Netlink tests in Python Jakub Kicinski
@ 2024-04-04 10:42 ` Petr Machata
2024-04-05 1:58 ` Jakub Kicinski
0 siblings, 1 reply; 19+ messages in thread
From: Petr Machata @ 2024-04-04 10:42 UTC (permalink / raw)
To: Jakub Kicinski
Cc: davem, netdev, edumazet, pabeni, shuah, sdf, donald.hunter,
linux-kselftest, petrm
Jakub Kicinski <kuba@kernel.org> writes:
> Add drivers/net as a target for mixed-use tests.
> The setup is expected to work similarly to the forwarding tests.
> Since we only need one interface (unlike forwarding tests)
> read the target device name from NETIF. If not present we'll
> try to run the test against netdevsim.
>
> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Reviewed-by: Petr Machata <petrm@nvidia.com>
However:
> diff --git a/tools/testing/selftests/net/lib/py/nsim.py b/tools/testing/selftests/net/lib/py/nsim.py
> new file mode 100644
> index 000000000000..25ae0d081788
> --- /dev/null
> +++ b/tools/testing/selftests/net/lib/py/nsim.py
> @@ -0,0 +1,118 @@
> +# SPDX-License-Identifier: GPL-2.0
> +
> +import json
> +import os
> +import random
> +import re
> +import time
> +from .utils import cmd, ip
> +
> +
> +class NetdevSim:
> + """
> + Class for netdevsim netdevice and its attributes.
> + """
> +
> + def __init__(self, nsimdev, port_index, ifname, ns=None):
> + # In case udev renamed the netdev to according to new schema,
> + # check if the name matches the port_index.
> + nsimnamere = re.compile(r"eni\d+np(\d+)")
> + match = nsimnamere.match(ifname)
> + if match and int(match.groups()[0]) != port_index + 1:
> + raise Exception("netdevice name mismatches the expected one")
> +
> + self.ifname = ifname
> + self.nsimdev = nsimdev
> + self.port_index = port_index
> + self.ns = ns
> + self.dfs_dir = "%s/ports/%u/" % (nsimdev.dfs_dir, port_index)
> + ret = ip("-j link show dev %s" % ifname, ns=ns)
> + self.dev = json.loads(ret.stdout)[0]
I don't think self.ifname, .ns, .dfs_dir, .dev are actually used outside
of this function.
> +
> + def dfs_write(self, path, val):
> + self.nsimdev.dfs_write(f'ports/{self.port_index}/' + path, val)
> +
> +
> +class NetdevSimDev:
> + """
> + Class for netdevsim bus device and its attributes.
> + """
> + @staticmethod
> + def ctrl_write(path, val):
> + fullpath = os.path.join("/sys/bus/netdevsim/", path)
> + with open(fullpath, "w") as f:
> + f.write(val)
> +
> + def dfs_write(self, path, val):
> + fullpath = os.path.join(f"/sys/kernel/debug/netdevsim/netdevsim{self.addr}/", path)
> + with open(fullpath, "w") as f:
> + f.write(val)
> +
> + def __init__(self, port_count=1, ns=None):
> + # nsim will spawn in init_net, we'll set to actual ns once we switch it the.sre
the.sre?
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH net-next v2 5/7] netdevsim: report stats by default, like a real device
2024-04-03 2:34 ` [PATCH net-next v2 5/7] netdevsim: report stats by default, like a real device Jakub Kicinski
2024-04-04 10:40 ` Petr Machata
@ 2024-04-04 13:40 ` Paolo Abeni
2024-04-04 13:53 ` Jakub Kicinski
1 sibling, 1 reply; 19+ messages in thread
From: Paolo Abeni @ 2024-04-04 13:40 UTC (permalink / raw)
To: Jakub Kicinski, davem
Cc: netdev, edumazet, shuah, sdf, donald.hunter, linux-kselftest,
petrm
On Tue, 2024-04-02 at 19:34 -0700, Jakub Kicinski wrote:
> Real devices should implement qstats. Devices which support
> pause or FEC configuration should also report the relevant stats.
>
> nsim was missing FEC stats completely, some of the qstats
> and pause stats required toggling a debugfs knob.
>
> Note that the tests which used pause always initialize the setting
> so they shouldn't be affected by the different starting value.
>
> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
> ---
> drivers/net/netdevsim/ethtool.c | 11 ++++++++
> drivers/net/netdevsim/netdev.c | 45 +++++++++++++++++++++++++++++++++
> 2 files changed, 56 insertions(+)
>
> diff --git a/drivers/net/netdevsim/ethtool.c b/drivers/net/netdevsim/ethtool.c
> index bd546d4d26c6..3f9c9327f149 100644
> --- a/drivers/net/netdevsim/ethtool.c
> +++ b/drivers/net/netdevsim/ethtool.c
> @@ -140,6 +140,13 @@ nsim_set_fecparam(struct net_device *dev, struct ethtool_fecparam *fecparam)
> return 0;
> }
>
> +static void
> +nsim_get_fec_stats(struct net_device *dev, struct ethtool_fec_stats *fec_stats)
> +{
> + fec_stats->corrected_blocks.total = 123;
> + fec_stats->uncorrectable_blocks.total = 4;
> +}
> +
> static int nsim_get_ts_info(struct net_device *dev,
> struct ethtool_ts_info *info)
> {
> @@ -163,6 +170,7 @@ static const struct ethtool_ops nsim_ethtool_ops = {
> .set_channels = nsim_set_channels,
> .get_fecparam = nsim_get_fecparam,
> .set_fecparam = nsim_set_fecparam,
> + .get_fec_stats = nsim_get_fec_stats,
> .get_ts_info = nsim_get_ts_info,
> };
>
> @@ -182,6 +190,9 @@ void nsim_ethtool_init(struct netdevsim *ns)
>
> nsim_ethtool_ring_init(ns);
>
> + ns->ethtool.pauseparam.report_stats_rx = true;
> + ns->ethtool.pauseparam.report_stats_tx = true;
> +
> ns->ethtool.fec.fec = ETHTOOL_FEC_NONE;
> ns->ethtool.fec.active_fec = ETHTOOL_FEC_NONE;
>
> diff --git a/drivers/net/netdevsim/netdev.c b/drivers/net/netdevsim/netdev.c
> index 8330bc0bcb7e..096ac0abbc02 100644
> --- a/drivers/net/netdevsim/netdev.c
> +++ b/drivers/net/netdevsim/netdev.c
> @@ -19,6 +19,7 @@
> #include <linux/module.h>
> #include <linux/netdevice.h>
> #include <linux/slab.h>
> +#include <net/netdev_queues.h>
> #include <net/netlink.h>
> #include <net/pkt_cls.h>
> #include <net/rtnetlink.h>
> @@ -330,6 +331,49 @@ static const struct net_device_ops nsim_vf_netdev_ops = {
> .ndo_set_features = nsim_set_features,
> };
>
> +/* We don't have true par-queue stats, yet, so do some random fakery here. */
> +static void nsim_get_queue_stats_rx(struct net_device *dev, int idx,
> + struct netdev_queue_stats_rx *stats)
> +{
> + struct rtnl_link_stats64 rtstats = {};
> +
> + nsim_get_stats64(dev, &rtstats);
> +
> + stats->packets = rtstats.rx_packets - !!rtstats.rx_packets;
> + stats->bytes = rtstats.rx_bytes;
> +}
> +
> +static void nsim_get_queue_stats_tx(struct net_device *dev, int idx,
> + struct netdev_queue_stats_tx *stats)
> +{
> + struct rtnl_link_stats64 rtstats = {};
> +
> + nsim_get_stats64(dev, &rtstats);
> +
> + stats->packets = rtstats.tx_packets - !!rtstats.tx_packets;
> + stats->bytes = rtstats.tx_bytes;
It looks the stats will not be self-consistent with multiple queues
enabled.
What about zeroing 'stats' when idx > 0 ?
/P
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH net-next v2 5/7] netdevsim: report stats by default, like a real device
2024-04-04 10:40 ` Petr Machata
@ 2024-04-04 13:52 ` Jakub Kicinski
0 siblings, 0 replies; 19+ messages in thread
From: Jakub Kicinski @ 2024-04-04 13:52 UTC (permalink / raw)
To: Petr Machata
Cc: davem, netdev, edumazet, pabeni, shuah, sdf, donald.hunter,
linux-kselftest
On Thu, 4 Apr 2024 12:40:04 +0200 Petr Machata wrote:
> > + stats->packets = rtstats.rx_packets - !!rtstats.rx_packets;
>
> This is just to make sure that per-queue stats are lower than the
> overall rtstats I presume?
Yes, to fake some "non-queue" stats.
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH net-next v2 5/7] netdevsim: report stats by default, like a real device
2024-04-04 13:40 ` Paolo Abeni
@ 2024-04-04 13:53 ` Jakub Kicinski
0 siblings, 0 replies; 19+ messages in thread
From: Jakub Kicinski @ 2024-04-04 13:53 UTC (permalink / raw)
To: Paolo Abeni
Cc: davem, netdev, edumazet, shuah, sdf, donald.hunter,
linux-kselftest, petrm
On Thu, 04 Apr 2024 15:40:33 +0200 Paolo Abeni wrote:
> > + nsim_get_stats64(dev, &rtstats);
> > +
> > + stats->packets = rtstats.tx_packets - !!rtstats.tx_packets;
> > + stats->bytes = rtstats.tx_bytes;
>
> It looks the stats will not be self-consistent with multiple queues
> enabled.
>
> What about zeroing 'stats' when idx > 0 ?
Ah, good catch. We do allow allocating multiple queues, even tho
we don't do anything with them on the driver side, yet..
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH net-next v2 0/7] selftests: net: groundwork for YNL-based tests
2024-04-03 2:34 [PATCH net-next v2 0/7] selftests: net: groundwork for YNL-based tests Jakub Kicinski
` (6 preceding siblings ...)
2024-04-03 2:34 ` [PATCH net-next v2 7/7] testing: net-drv: add a driver test for stats reporting Jakub Kicinski
@ 2024-04-04 17:40 ` patchwork-bot+netdevbpf
7 siblings, 0 replies; 19+ messages in thread
From: patchwork-bot+netdevbpf @ 2024-04-04 17:40 UTC (permalink / raw)
To: Jakub Kicinski
Cc: davem, netdev, edumazet, pabeni, shuah, sdf, donald.hunter,
linux-kselftest, petrm
Hello:
This series was applied to netdev/net-next.git (main)
by Jakub Kicinski <kuba@kernel.org>:
On Tue, 2 Apr 2024 19:34:19 -0700 you wrote:
> Currently the options for writing networking tests are C, bash or
> some mix of the two. YAML/Netlink gives us the ability to easily
> interface with Netlink in higher level laguages. In particular,
> there is a Python library already available in tree, under tools/net.
> Add the scaffolding which allows writing tests using this library.
>
> The "scaffolding" is needed because the library lives under
> tools/net and uses YAML files from under Documentation/.
> So we need a small amount of glue code to find those things
> and add them to TEST_FILES.
>
> [...]
Here is the summary with links:
- [net-next,v2,1/7] netlink: specs: define ethtool header flags
https://git.kernel.org/netdev/net-next/c/1d056bf9a4c1
- [net-next,v2,2/7] tools: ynl: copy netlink error to NlError
https://git.kernel.org/netdev/net-next/c/b269d2b4a523
- [net-next,v2,3/7] selftests: net: add scaffolding for Netlink tests in Python
(no matching commit)
- [net-next,v2,4/7] selftests: nl_netdev: add a trivial Netlink netdev test
(no matching commit)
- [net-next,v2,5/7] netdevsim: report stats by default, like a real device
(no matching commit)
- [net-next,v2,6/7] selftests: drivers: add scaffolding for Netlink tests in Python
(no matching commit)
- [net-next,v2,7/7] testing: net-drv: add a driver test for stats reporting
(no matching commit)
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH net-next v2 6/7] selftests: drivers: add scaffolding for Netlink tests in Python
2024-04-04 10:42 ` Petr Machata
@ 2024-04-05 1:58 ` Jakub Kicinski
0 siblings, 0 replies; 19+ messages in thread
From: Jakub Kicinski @ 2024-04-05 1:58 UTC (permalink / raw)
To: Petr Machata
Cc: davem, netdev, edumazet, pabeni, shuah, sdf, donald.hunter,
linux-kselftest
On Thu, 4 Apr 2024 12:42:24 +0200 Petr Machata wrote:
> > + def __init__(self, nsimdev, port_index, ifname, ns=None):
> > + # In case udev renamed the netdev to according to new schema,
> > + # check if the name matches the port_index.
> > + nsimnamere = re.compile(r"eni\d+np(\d+)")
> > + match = nsimnamere.match(ifname)
> > + if match and int(match.groups()[0]) != port_index + 1:
> > + raise Exception("netdevice name mismatches the expected one")
> > +
> > + self.ifname = ifname
> > + self.nsimdev = nsimdev
> > + self.port_index = port_index
> > + self.ns = ns
> > + self.dfs_dir = "%s/ports/%u/" % (nsimdev.dfs_dir, port_index)
> > + ret = ip("-j link show dev %s" % ifname, ns=ns)
> > + self.dev = json.loads(ret.stdout)[0]
>
> I don't think self.ifname, .ns, .dfs_dir, .dev are actually used outside
> of this function.
Right, one of the "further down the line" tests need these.
I'll remove for now.
> > + def dfs_write(self, path, val):
> > + self.nsimdev.dfs_write(f'ports/{self.port_index}/' + path, val)
> > +
> > +
> > +class NetdevSimDev:
> > + """
> > + Class for netdevsim bus device and its attributes.
> > + """
> > + @staticmethod
> > + def ctrl_write(path, val):
> > + fullpath = os.path.join("/sys/bus/netdevsim/", path)
> > + with open(fullpath, "w") as f:
> > + f.write(val)
> > +
> > + def dfs_write(self, path, val):
> > + fullpath = os.path.join(f"/sys/kernel/debug/netdevsim/netdevsim{self.addr}/", path)
> > + with open(fullpath, "w") as f:
> > + f.write(val)
> > +
> > + def __init__(self, port_count=1, ns=None):
> > + # nsim will spawn in init_net, we'll set to actual ns once we switch it the.sre
>
> the.sre?
Ha, must have started typing with focus on the wrong window.
Good it wasn't my password :D
^ permalink raw reply [flat|nested] 19+ messages in thread
end of thread, other threads:[~2024-04-05 1:58 UTC | newest]
Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-04-03 2:34 [PATCH net-next v2 0/7] selftests: net: groundwork for YNL-based tests Jakub Kicinski
2024-04-03 2:34 ` [PATCH net-next v2 1/7] netlink: specs: define ethtool header flags Jakub Kicinski
2024-04-04 10:38 ` Petr Machata
2024-04-03 2:34 ` [PATCH net-next v2 2/7] tools: ynl: copy netlink error to NlError Jakub Kicinski
2024-04-04 10:39 ` Petr Machata
2024-04-03 2:34 ` [PATCH net-next v2 3/7] selftests: net: add scaffolding for Netlink tests in Python Jakub Kicinski
2024-04-04 9:11 ` Petr Machata
2024-04-03 2:34 ` [PATCH net-next v2 4/7] selftests: nl_netdev: add a trivial Netlink netdev test Jakub Kicinski
2024-04-04 10:39 ` Petr Machata
2024-04-03 2:34 ` [PATCH net-next v2 5/7] netdevsim: report stats by default, like a real device Jakub Kicinski
2024-04-04 10:40 ` Petr Machata
2024-04-04 13:52 ` Jakub Kicinski
2024-04-04 13:40 ` Paolo Abeni
2024-04-04 13:53 ` Jakub Kicinski
2024-04-03 2:34 ` [PATCH net-next v2 6/7] selftests: drivers: add scaffolding for Netlink tests in Python Jakub Kicinski
2024-04-04 10:42 ` Petr Machata
2024-04-05 1:58 ` Jakub Kicinski
2024-04-03 2:34 ` [PATCH net-next v2 7/7] testing: net-drv: add a driver test for stats reporting Jakub Kicinski
2024-04-04 17:40 ` [PATCH net-next v2 0/7] selftests: net: groundwork for YNL-based tests patchwork-bot+netdevbpf
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).