From patchwork Tue Apr 2 01:05:13 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Kicinski X-Patchwork-Id: 13613207 X-Patchwork-Delegate: kuba@kernel.org Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 591617490; Tue, 2 Apr 2024 01:05:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712019940; cv=none; b=OukAnGUgrBuHiQGpwpONYP90sGhsQTEh7Adiy7xCnXVBBo3y6NZxkGb+K0K1lzxqlIqkfX0SvohotWfjVDovQy2qJDUYc9lLbT7VaT9UmU9cd6OR+BayeGZZ/lT29tXliQh/rgYqSLc4/IUI987evWOLkmjTwIC+tXpugbvLAV8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712019940; c=relaxed/simple; bh=QJKk6PY4omTLAaqc+5v7chjkm+B7XrZ45POhQ+8kgTc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=hXRhQ8aMrmLaTiBMApBopTceZrLj4/DO1mknLN73AGqT+GAN7xfJ7LOH4FNwO5g9rdnxL28WwmXrJHAi/baUMccW1RBBNgIGnAxaVH8vaJq8rpJETD0qnLRJxq5EOASRzmD3D/XyBjkvWrTLjpY9C7bPj0g2M19ai0vn1cD0hes= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=cRi/V0RM; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="cRi/V0RM" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 49F5AC43399; Tue, 2 Apr 2024 01:05:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1712019939; bh=QJKk6PY4omTLAaqc+5v7chjkm+B7XrZ45POhQ+8kgTc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=cRi/V0RMIhcuYss+pMPUz8drmYBPdzwWP0LQedlThGdlIwZJRqOOMUcGYXaqc9alj Yw9YBTvvM3NlH4Zui/zVXnXGz0BjLdRsBgJElxdeO+11i1QhY4w8nIidEqjtNcSH4q Aae9WXo++nqIMGa6QqNsWqwbmA32p3jADoR0j5Mf5bAcKUFvoTdgGGCoD0RnUIiBUv nQuKBjXMhSPjesKZE0tE721xo4NbCZ7Zns+4mDNRmpL1UKth/QzP28deu/zF1LD0+4 cw/070uu9bhyplGRCbER1/4ivVSuxxHJ53tccukYG3+SPqqySva5jeP0fqfIDCxo62 woGO5O4DJ8zPg== From: Jakub Kicinski To: davem@davemloft.net Cc: netdev@vger.kernel.org, edumazet@google.com, pabeni@redhat.com, shuah@kernel.org, sdf@google.com, donald.hunter@gmail.com, linux-kselftest@vger.kernel.org, petrm@nvidia.com, Jakub Kicinski Subject: [PATCH net-next 1/7] netlink: specs: define ethtool header flags Date: Mon, 1 Apr 2024 18:05:13 -0700 Message-ID: <20240402010520.1209517-2-kuba@kernel.org> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20240402010520.1209517-1-kuba@kernel.org> References: <20240402010520.1209517-1-kuba@kernel.org> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: kuba@kernel.org 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 --- Documentation/netlink/specs/ethtool.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Documentation/netlink/specs/ethtool.yaml b/Documentation/netlink/specs/ethtool.yaml index 197208f419dc..616bb3eb545f 100644 --- a/Documentation/netlink/specs/ethtool.yaml +++ b/Documentation/netlink/specs/ethtool.yaml @@ -16,6 +16,10 @@ doc: Partial family for Ethtool Netlink. name: stringset type: enum entries: [] + - + name: header-flags + type: flags + entries: [ compact-bitsets, omit-reply, stats ] attribute-sets: - @@ -30,6 +34,7 @@ doc: Partial family for Ethtool Netlink. - name: flags type: u32 + enum: header-flags - name: bitset-bit From patchwork Tue Apr 2 01:05:14 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Kicinski X-Patchwork-Id: 13613208 X-Patchwork-Delegate: kuba@kernel.org Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BC5428C13; Tue, 2 Apr 2024 01:05:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712019940; cv=none; b=YM0aToOfhaW+VQyBuTFBeHL4xE9sit7aZO5M2jqLTSgxnm54vGGmUu9NrvqauH9XIwF7TpPaK5Yr4Y7pP54atMhhpLt0KBj9FamFyH1FIgCy6zpya/NVSxWs68bLZIAwOZ6pFujP5Yxcylv6IF0JAec7o2lKxiGI/8XTfeDDPVQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712019940; c=relaxed/simple; bh=qMDSBPwJr3ShI0X/pT3ZBrb1Z8HIj3lJ315yAx7FL18=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=iokVnwkW/cXJy5HyBOxSBtaGEnJYi5ikI99k/WqJUXqqpxjsHkhFxv4hM6HsQXw3BjIWIS9me1OFLIIOJLMmpp30O42MrZFwqfR/k7+UMu8mH07FNiaF7Ek0hVUB4SapHcs9fMYUZapyQ82hkKcDKAcwzJQ2yw98zaaaV+4Polo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=JyWCcDLQ; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="JyWCcDLQ" Received: by smtp.kernel.org (Postfix) with ESMTPSA id ECF94C433C7; Tue, 2 Apr 2024 01:05:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1712019940; bh=qMDSBPwJr3ShI0X/pT3ZBrb1Z8HIj3lJ315yAx7FL18=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=JyWCcDLQFj/mck9sF5z5umEQiqstOnWzrmQps5Cmtno1XkljIeqJhRXJ0I6HSWU1e OFdgm3NRqkiGCMJuhFTivnTj9q+eM5RlK1iApB74Nlth8vSdACxjKm5KFkywvWzIQn +DU/uzkSkAVAIeRg6tY2PibPGqY8s6ZMHSHMlc0ZVWawxJGtU9Ci6Pm8xL170/t3r3 cEBAB9ZEBZ4P6Ro26ZZn8OigocDFc/ImrChLSXyVtykKWkGcr/U2hZ4dElIv7SlMts v2+8KuUqv8SNsjCv7MkFO3D7/B6mMycqN3cfnfMNUWMIgJkUeCEOsVLf7je2o76rNj y7gy1F/qaNSUg== From: Jakub Kicinski To: davem@davemloft.net Cc: netdev@vger.kernel.org, edumazet@google.com, pabeni@redhat.com, shuah@kernel.org, sdf@google.com, donald.hunter@gmail.com, linux-kselftest@vger.kernel.org, petrm@nvidia.com, Jakub Kicinski , jiri@resnulli.us Subject: [PATCH net-next 2/7] tools: ynl: copy netlink error to NlError Date: Mon, 1 Apr 2024 18:05:14 -0700 Message-ID: <20240402010520.1209517-3-kuba@kernel.org> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20240402010520.1209517-1-kuba@kernel.org> References: <20240402010520.1209517-1-kuba@kernel.org> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: kuba@kernel.org 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 --- 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): From patchwork Tue Apr 2 01:05:15 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Kicinski X-Patchwork-Id: 13613209 X-Patchwork-Delegate: kuba@kernel.org Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BCD21D520; Tue, 2 Apr 2024 01:05:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712019941; cv=none; b=SFXJaYx1i5SVfLi/1GsoGf9JrKh6PIwvaO+VJFtalTtJ9sQkH4CYkL69f06CXUg3fpJBYt56AiRwfbRB28Kiiyj4yEz7zy5Ew2aTFauN3meyCmn/psuzZmzV6+ZapUs5AR+EHv9DSU6Jy0VX8b0NHwLN/FcucIcQrCFMWJl04/c= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712019941; c=relaxed/simple; bh=6PXClB3QUgVAViliO7MIV0iqQSkf9RfbD9PiDXdhfuU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Du/5PVqhJxdhK60FRVUkDtlBy9wFgGK6zVTDqXXh4vjSKDs3Qrc9YicUPdc6bEYcQGKhgoHJ/+1MHkAqipMd0lBOAywmVuh0Maqj3LEsA8Mx4lRsPyrxY53Zq9V060E1AkgHgn9FD59gtY2ObwII4d57LHS9NrpgQ7YTjxihjVs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=GUBTr+hw; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="GUBTr+hw" Received: by smtp.kernel.org (Postfix) with ESMTPSA id BC1E7C4166C; Tue, 2 Apr 2024 01:05:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1712019941; bh=6PXClB3QUgVAViliO7MIV0iqQSkf9RfbD9PiDXdhfuU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=GUBTr+hw4X2Wm3mEc8wJHh2UUi1mlqMqj3HfYMjCWVCzgEWWIOUr60v7NS4M1XOx3 uRqhl4c8Q5AXvRvXFg6FimXHACvTbSVumiBcjH5V4zPGaLgKWtH9iy6LUarR2hSGXB fA2m70LDrAzIYhVXDvA5vmjOUSGntSS+GVcHXL2I1xoW+Kpw6cA4ddRAkdO9DDbmRY E2qY5LEUXEIJQCPj+m3YA6kHimAGg9JIiS1w2eje59Mgafs5DAmTjqqWU9gfsx/2P+ UCFyJufdB/0wh2CSe4MD16KzYEcS2EINBh4m7Vsqa6xxi44MqrrqG+9DKt/GD7qWPa Vo7j9040ydNVw== From: Jakub Kicinski To: davem@davemloft.net Cc: netdev@vger.kernel.org, edumazet@google.com, pabeni@redhat.com, shuah@kernel.org, sdf@google.com, donald.hunter@gmail.com, linux-kselftest@vger.kernel.org, petrm@nvidia.com, Jakub Kicinski Subject: [PATCH net-next 3/7] selftests: net: add scaffolding for Netlink tests in Python Date: Mon, 1 Apr 2024 18:05:15 -0700 Message-ID: <20240402010520.1209517-4-kuba@kernel.org> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20240402010520.1209517-1-kuba@kernel.org> References: <20240402010520.1209517-1-kuba@kernel.org> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: kuba@kernel.org 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 --- CC: shuah@kernel.org CC: linux-kselftest@vger.kernel.org --- tools/testing/selftests/Makefile | 7 ++ 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, 222 insertions(+) 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..0cffdfb4b116 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)),) + override TARGETS := $(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. 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..81a8d14b68f0 --- /dev/null +++ b/tools/testing/selftests/net/lib/py/__init__.py @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0 + +from .ksft import * +from .ynl import NlError, YnlFamily, EthtoolFamily, NetdevFamily, RtnlFamily +from .consts import KSRC +from .utils import * 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..7c296fe5e438 --- /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): + 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() + 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..298bbc6b93c5 --- /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 = Path(KSRC) / "tools" + SPEC_PATH = 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='') From patchwork Tue Apr 2 01:05:16 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Kicinski X-Patchwork-Id: 13613210 X-Patchwork-Delegate: kuba@kernel.org Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 100D7D530; Tue, 2 Apr 2024 01:05:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712019942; cv=none; b=fYReej8cQfcex9IDU1mx+oh7eIbD9VqaXbTP6fd7x9ApPuRQh7QHB/KiBIr73VtAtd5Eh26jnQjnyLeDaRZOPeD6DTMwaytoGw1kk4rAe2emO3FynB2jrhp648UdXkvAznUJSVJ2Cfs9dgbHwM6zs1u2h1QOETtK1phmNuSB5q8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712019942; c=relaxed/simple; bh=e738ql/dcNvxSZzrbxZnMLoXdMlLsFew81kY5MkzfRA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=i0qY7908dem/R+EI2nEMXoDOf7QzKZGjoThKO/NIenz6Uqiu91Hn00Z8gEJizWMJCnyw3yxZgXmZt+Lf4kV5oGdry2SxnKu3Rvkhav0b4YCixLxraqDNnLLjRSAiDiOSL8dQwpkUocdNtdkTPb/5hDVHjPViNn3J508NFVtulRA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=pn4YOBaT; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="pn4YOBaT" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6E9A6C43390; Tue, 2 Apr 2024 01:05:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1712019941; bh=e738ql/dcNvxSZzrbxZnMLoXdMlLsFew81kY5MkzfRA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=pn4YOBaThzOJu5TyKthc4sC3yewky7tamDpCgBeLW11H0pfa6yH75yu+4yqM9lSXd yCLwTzAkbnkzi32JHyEH8BAOqiNtY0ct9x6tyHbmcx4fvjnXIkY/NBLRBWvjy8UMcI W2dDLemwBd7ny67hjwdPzJs44i+hHoxzW8fEno5wfYGxRj4UP2+s8s2pd5ru5V+WUX 945rln1gxQlRhu68ucYVERAiuDGUAf0zHy+AYt9jKnOXmT9fb/v6dL3amyUI+aygky k/HvnNu6+8hkUcCB31PeVfVbKpkfcrI6azGJ0ADUnLj0MwkQVirEdBGbGNLALMtwFJ Mld1411oRJKCQ== From: Jakub Kicinski To: davem@davemloft.net Cc: netdev@vger.kernel.org, edumazet@google.com, pabeni@redhat.com, shuah@kernel.org, sdf@google.com, donald.hunter@gmail.com, linux-kselftest@vger.kernel.org, petrm@nvidia.com, Jakub Kicinski Subject: [PATCH net-next 4/7] selftests: nl_netdev: add a trivial Netlink netdev test Date: Mon, 1 Apr 2024 18:05:16 -0700 Message-ID: <20240402010520.1209517-5-kuba@kernel.org> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20240402010520.1209517-1-kuba@kernel.org> References: <20240402010520.1209517-1-kuba@kernel.org> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: kuba@kernel.org 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 --- 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..40a59857f984 --- /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 + + +nf = NetdevFamily() + + +def empty_check() -> None: + global nf + devs = nf.dev_get({}, dump=True) + ksft_ge(len(devs), 1) + + +def lo_check() -> None: + global nf + 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) + + +if __name__ == "__main__": + ksft_run([empty_check, lo_check]) From patchwork Tue Apr 2 01:05:17 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Kicinski X-Patchwork-Id: 13613211 X-Patchwork-Delegate: kuba@kernel.org Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AFA4ADDC4; Tue, 2 Apr 2024 01:05:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712019942; cv=none; b=MILE70OxPfkHxrFVxh7dvaSbo3T05qQPfpPG5ZlEniQNfuzeCSXp6J7taJItY7HojuZFIls90mAybdmfsBblGuJ82hAYH+p0jF+3v80+mxwAiVo089ej2KLMnGJgKVtfRfQSdfnhBmNkUASXMAsDQ3+0X3rpLjr0ijCfqgMHMJI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712019942; c=relaxed/simple; bh=mB0I4kjtTnexpmnvDZ8oN+gQdUayrzeuXIYIsr+D/5c=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=N7hdv6D+GgHpPwDyQp+QIn2QadD1+0bBUlo07RmQXRoxB+SssJNeASwPr8cLYV+DZ9q+8K7KrM9AcbRdOt6g8y8wR79vTxleE/1BlPXo8rK0L66ZkD723p5pPrE9LZVbx74oaRvH+jOarv/wH5Vfl1IEB+uhi3fZFFDkzr6Zra0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=pov85QyX; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="pov85QyX" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 12E4EC433F1; Tue, 2 Apr 2024 01:05:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1712019942; bh=mB0I4kjtTnexpmnvDZ8oN+gQdUayrzeuXIYIsr+D/5c=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=pov85QyXJ3pVzdPuhagSJlJpaJP4eNWXK1C3qkdgtYXOxI2T+YB/lA4EASxiqW2Ek 14ust3zTRqPDpuSxZ+2CEnR+OY+0EtdYPrNMPw6JGCJ66g93x2inW4v3VBTzMLgdRv YKybm1gWIzM7crk1YWAQci24rkG4q48vjmfzKqgxV7WHM6Ro5uRLVx4Z2/F5Xr/jef +d/Ihy03xoVFU5zSVDI+XdtLtGDYJ+0mGr7CGv+hvf3R2VZTxcsxNxXWkpGSnfIwE1 EMjqdIrH03YEESfWztq4X8xV9eQ2q/1wV6WGf9JMeJQb+Wf5MS2y/n0iWbQz1t3uMf 9u61BNFiUJbIA== From: Jakub Kicinski To: davem@davemloft.net Cc: netdev@vger.kernel.org, edumazet@google.com, pabeni@redhat.com, shuah@kernel.org, sdf@google.com, donald.hunter@gmail.com, linux-kselftest@vger.kernel.org, petrm@nvidia.com, Jakub Kicinski Subject: [PATCH net-next 5/7] netdevsim: report stats by default, like a real device Date: Mon, 1 Apr 2024 18:05:17 -0700 Message-ID: <20240402010520.1209517-6-kuba@kernel.org> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20240402010520.1209517-1-kuba@kernel.org> References: <20240402010520.1209517-1-kuba@kernel.org> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: kuba@kernel.org 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 --- 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 #include #include +#include #include #include #include @@ -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) From patchwork Tue Apr 2 01:05:18 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Kicinski X-Patchwork-Id: 13613212 X-Patchwork-Delegate: kuba@kernel.org Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 64FFDEAC2; Tue, 2 Apr 2024 01:05:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712019943; cv=none; b=hvYOps7iudExJ8Gr8Em/MFnsYvA2LDvgO0Zw73zsnNB660h0RbqGJksTQVQipMJ29DuJ8FNmRlVCgf5aDi/xG8/o5Hb6JvxNVOvfRtwBijc21sBWtU3OcaYKTXSyWcaCb8zvxwTsLMObmm3YbDguV3L768xYyJrCujhJCIThDjU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712019943; c=relaxed/simple; bh=Mw9I6Uypg+jQLzr2jAZ12QsyroezwcvVbTtzxoX68TI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=PF31aUZwkSMJwo47T/Lpinr6YGzlUaRL3CpRSCpuhF9Ecg4PsbcPxXuLUJ2td48u88XOO9ZzoQDS87NWxay+p9OMNMaheVRKl3ZaTVjv7QeVMMGzrF3fr6JrndTuAdnoArUEe1gnA3uq0xyZESwKo4uUDtjIN8IBut5Lw70OJuI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=sYHq2/v4; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="sYHq2/v4" Received: by smtp.kernel.org (Postfix) with ESMTPSA id B106BC43390; Tue, 2 Apr 2024 01:05:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1712019943; bh=Mw9I6Uypg+jQLzr2jAZ12QsyroezwcvVbTtzxoX68TI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=sYHq2/v41d+8ohH7+fJ83Oix/iHD+D1yrw7ZwNjqL9kI26/iQkI0r01+17zv7Cc7o GaTUVbyVl+mrPFRhOv3sdzr17vp2eV/WOBsFxBUq4qum9xNnlYNz+okHAusNSjB+Kd eDXDU8axyc61jr6yvNK6R1VcMHhWp6otFnEEAyVyse7SgPrh01VzH5ibY6ISbaiy01 90bihq7H0z60fqDhWkrL1iBw7gD8WZybSuDNKLRCJM7DS6MK5DxUPx9K2gugqIs8hi Qxlc77p+DeWKeFwI2cfvoYM/yT2c0EIZziOVydmBuhPOYEUaZlWwKqJTwoUzsc87j9 RANuV959cEIMQ== From: Jakub Kicinski To: davem@davemloft.net Cc: netdev@vger.kernel.org, edumazet@google.com, pabeni@redhat.com, shuah@kernel.org, sdf@google.com, donald.hunter@gmail.com, linux-kselftest@vger.kernel.org, petrm@nvidia.com, Jakub Kicinski Subject: [PATCH net-next 6/7] selftests: drivers: add scaffolding for Netlink tests in Python Date: Mon, 1 Apr 2024 18:05:18 -0700 Message-ID: <20240402010520.1209517-7-kuba@kernel.org> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20240402010520.1209517-1-kuba@kernel.org> References: <20240402010520.1209517-1-kuba@kernel.org> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: kuba@kernel.org 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 --- 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 | 41 ++++++ .../testing/selftests/net/lib/py/__init__.py | 1 + tools/testing/selftests/net/lib/py/nsim.py | 118 ++++++++++++++++++ 7 files changed, 216 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 0cffdfb4b116..d015ec14a85e 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)),) override TARGETS := $(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..ee4a44555d83 --- /dev/null +++ b/tools/testing/selftests/drivers/net/lib/py/env.py @@ -0,0 +1,41 @@ +# 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.env = os.environ.copy() + self._load_env_file(src_path) + + if 'NETIF' in self.env: + self._ns = None + 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 __del__(self): + if self._ns: + self._ns.remove() + + 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 81a8d14b68f0..99cfc8dc4dca 100644 --- a/tools/testing/selftests/net/lib/py/__init__.py +++ b/tools/testing/selftests/net/lib/py/__init__.py @@ -3,4 +3,5 @@ from .ksft import * from .ynl import NlError, YnlFamily, EthtoolFamily, NetdevFamily, RtnlFamily from .consts import KSRC +from .nsim import * from .utils import * 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..13eb42c82829 --- /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("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, )) From patchwork Tue Apr 2 01:05:19 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Kicinski X-Patchwork-Id: 13613213 X-Patchwork-Delegate: kuba@kernel.org Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 455DFFBE8; Tue, 2 Apr 2024 01:05:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712019944; cv=none; b=AxwYwCs8QHyuTubp13wRHkRXWxRWV5Qzzo0/8uuqmPZX35tE6NqdWCbFeQjxIjJiziFsJCqXNQ3pNuqrB0nkC62UsleVH8pr3fo2sGm+rcPvk+8YduFzZHURpep2eqX27mPjd9BcpGodihB20G9DWvicRYtSktK1S5zeC/2YpgI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712019944; c=relaxed/simple; bh=Y71nP2zwtbVSLu5riks8Otndx5/nVc0R0gnKxEK2tWA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=WQLP43HcNYr46etSG73ApQD//cvHlMtvPqz76Ssg3S+UvtZ66msOOmkfTQrJSoZjjR6Ysp69ucDRi39QYEeTpKaWcQsSyBGO+33PeGrTD54cT5lV/kpAM0AJZxm2HOxz2xrrp0PflRp3CA0T88RZjSPwzouSgoy8XV+MSutIoRg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=KTkj8xdq; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="KTkj8xdq" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6C95CC433C7; Tue, 2 Apr 2024 01:05:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1712019943; bh=Y71nP2zwtbVSLu5riks8Otndx5/nVc0R0gnKxEK2tWA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=KTkj8xdq7COZKzT3990rY8X67gBnDEg9Xc4A/GWfqB/XFwbIhQurlG34TNAuds5eM XDNBx+6j2C1FX5+pwEsvu0uW68YR1WyOz+L+yD1HquHCddmvAI2U3OvtrcTR3UcJDc 2h1aZR7DsB2JW/n5mYueSFXCPper2Al8zjAXh3kplUIIv/7NjHjRULpgwT5Ca9Tgne Z1T+INAKNB0ejtyeXGUcdXHph1VcqBBOTIxBRzraPpy3ymmYvn28KkhbpWrVphRzG6 svtRwaCEH32wlSCWGD3C6z6VVZnvRsIupA9RseaiBAI9o4jevmyikUBiwKrwtNULRH 8NUQg+4CGWx2A== From: Jakub Kicinski To: davem@davemloft.net Cc: netdev@vger.kernel.org, edumazet@google.com, pabeni@redhat.com, shuah@kernel.org, sdf@google.com, donald.hunter@gmail.com, linux-kselftest@vger.kernel.org, petrm@nvidia.com, Jakub Kicinski Subject: [PATCH net-next 7/7] testing: net-drv: add a driver test for stats reporting Date: Mon, 1 Apr 2024 18:05:19 -0700 Message-ID: <20240402010520.1209517-8-kuba@kernel.org> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20240402010520.1209517-1-kuba@kernel.org> References: <20240402010520.1209517-1-kuba@kernel.org> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: kuba@kernel.org 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 --- tools/testing/selftests/drivers/net/stats.py | 85 ++++++++++++++++++++ 1 file changed, 85 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..751cca2869b8 --- /dev/null +++ b/tools/testing/selftests/drivers/net/stats.py @@ -0,0 +1,85 @@ +#!/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 + +cfg = None +ethnl = EthtoolFamily() +netfam = NetdevFamily() +rtnl = RtnlFamily() + + +def check_pause() -> None: + global cfg, 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() -> 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() -> None: + global cfg, 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") + + +if __name__ == "__main__": + cfg = NetDrvEnv(__file__) + try: + ksft_run([check_pause, check_fec, pkt_byte_sum]) + finally: + del cfg