From: Cosmin Ratiu <cratiu@nvidia.com>
To: <netdev@vger.kernel.org>
Cc: Sabrina Dubroca <sd@queasysnail.net>,
Andrew Lunn <andrew+netdev@lunn.ch>,
"David S . Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@google.com>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
Shuah Khan <shuah@kernel.org>, <linux-kselftest@vger.kernel.org>,
Cosmin Ratiu <cratiu@nvidia.com>,
Dragos Tatulea <dtatulea@nvidia.com>
Subject: [PATCH net v5 1/3] selftests: Migrate nsim-only MACsec tests to Python
Date: Mon, 23 Mar 2026 14:36:31 +0200 [thread overview]
Message-ID: <20260323123633.756163-2-cratiu@nvidia.com> (raw)
In-Reply-To: <20260323123633.756163-1-cratiu@nvidia.com>
Move MACsec offload API and ethtool feature tests from
tools/testing/selftests/drivers/net/netdevsim/macsec-offload.sh to
tools/testing/selftests/drivers/net/macsec.py using the NetDrvEnv
framework so tests can run against both netdevsim (default) and real
hardware (NETIF=ethX). As some real hardware requires macsec to use
encryption, add that to the tests.
Netdevsim-specific limit checks (max SecY, max RX SC) were moved into
separate test cases to avoid failures on real hardware.
Finally, MACSEC was added as a config option to drivers/net/config.
Signed-off-by: Cosmin Ratiu <cratiu@nvidia.com>
---
tools/testing/selftests/drivers/net/Makefile | 1 +
tools/testing/selftests/drivers/net/config | 1 +
tools/testing/selftests/drivers/net/macsec.py | 179 ++++++++++++++++++
.../selftests/drivers/net/netdevsim/Makefile | 1 -
.../drivers/net/netdevsim/macsec-offload.sh | 117 ------------
5 files changed, 181 insertions(+), 118 deletions(-)
create mode 100755 tools/testing/selftests/drivers/net/macsec.py
delete mode 100755 tools/testing/selftests/drivers/net/netdevsim/macsec-offload.sh
diff --git a/tools/testing/selftests/drivers/net/Makefile b/tools/testing/selftests/drivers/net/Makefile
index 8154d6d429d3..5e045dde0273 100644
--- a/tools/testing/selftests/drivers/net/Makefile
+++ b/tools/testing/selftests/drivers/net/Makefile
@@ -13,6 +13,7 @@ TEST_GEN_FILES := \
TEST_PROGS := \
gro.py \
hds.py \
+ macsec.py \
napi_id.py \
napi_threaded.py \
netpoll_basic.py \
diff --git a/tools/testing/selftests/drivers/net/config b/tools/testing/selftests/drivers/net/config
index 77ccf83d87e0..d4b31a317c09 100644
--- a/tools/testing/selftests/drivers/net/config
+++ b/tools/testing/selftests/drivers/net/config
@@ -3,6 +3,7 @@ CONFIG_DEBUG_INFO_BTF=y
CONFIG_DEBUG_INFO_BTF_MODULES=n
CONFIG_INET_PSP=y
CONFIG_IPV6=y
+CONFIG_MACSEC=m
CONFIG_NETCONSOLE=m
CONFIG_NETCONSOLE_DYNAMIC=y
CONFIG_NETCONSOLE_EXTENDED_LOG=y
diff --git a/tools/testing/selftests/drivers/net/macsec.py b/tools/testing/selftests/drivers/net/macsec.py
new file mode 100755
index 000000000000..a17b9f7ef584
--- /dev/null
+++ b/tools/testing/selftests/drivers/net/macsec.py
@@ -0,0 +1,179 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0
+
+"""MACsec tests."""
+
+import os
+
+from lib.py import ksft_run, ksft_exit, ksft_eq, ksft_raises
+from lib.py import CmdExitFailure, KsftSkipEx
+from lib.py import NetDrvEpEnv
+from lib.py import cmd, ip, defer, ethtool
+
+# Unique prefix per run to avoid collisions in the shared netns.
+# Keep it short: IFNAMSIZ is 16 (incl. NUL), and VLAN names append ".<vid>".
+MACSEC_PFX = f"ms{os.getpid()}_"
+
+
+def _macsec_name(idx=0):
+ return f"{MACSEC_PFX}{idx}"
+
+
+def _get_macsec_offload(dev):
+ """Returns macsec offload mode string from ip -d link show."""
+ info = ip(f"-d link show dev {dev}", json=True)[0]
+ return info.get("linkinfo", {}).get("info_data", {}).get("offload")
+
+
+def _require_ip_macsec_offload():
+ """SKIP if local iproute2 doesn't understand 'ip macsec offload'."""
+ out = cmd("ip macsec help", fail=False)
+ if "offload" not in out.stdout + out.stderr:
+ raise KsftSkipEx("iproute2 too old, missing macsec offload")
+
+
+def _require_macsec_offload(cfg):
+ """SKIP if local device doesn't support macsec-hw-offload."""
+ _require_ip_macsec_offload()
+ try:
+ feat = ethtool(f"-k {cfg.ifname}", json=True)[0]
+ except (CmdExitFailure, IndexError) as e:
+ raise KsftSkipEx(
+ f"can't query features: {e}") from e
+ if not feat.get("macsec-hw-offload", {}).get("active"):
+ raise KsftSkipEx("macsec-hw-offload not supported")
+
+
+def test_offload_api(cfg) -> None:
+ """MACsec offload API: create SecY, add SA/rx, toggle offload."""
+
+ _require_macsec_offload(cfg)
+ ms0 = _macsec_name(0)
+ ms1 = _macsec_name(1)
+ ms2 = _macsec_name(2)
+
+ # Create 3 SecY with offload
+ ip(f"link add link {cfg.ifname} {ms0} type macsec "
+ f"port 4 encrypt on offload mac")
+ defer(ip, f"link del {ms0}")
+
+ ip(f"link add link {cfg.ifname} {ms1} type macsec "
+ f"address aa:bb:cc:dd:ee:ff port 5 encrypt on offload mac")
+ defer(ip, f"link del {ms1}")
+
+ ip(f"link add link {cfg.ifname} {ms2} type macsec "
+ f"sci abbacdde01020304 encrypt on offload mac")
+ defer(ip, f"link del {ms2}")
+
+ # Add TX SA
+ ip(f"macsec add {ms0} tx sa 0 pn 1024 on "
+ "key 01 12345678901234567890123456789012")
+
+ # Add RX SC + SA
+ ip(f"macsec add {ms0} rx port 1234 address 1c:ed:de:ad:be:ef")
+ ip(f"macsec add {ms0} rx port 1234 address 1c:ed:de:ad:be:ef "
+ "sa 0 pn 1 on key 00 0123456789abcdef0123456789abcdef")
+
+ # Can't disable offload when SAs are configured
+ with ksft_raises(CmdExitFailure):
+ ip(f"link set {ms0} type macsec offload off")
+ with ksft_raises(CmdExitFailure):
+ ip(f"macsec offload {ms0} off")
+
+ # Toggle offload via rtnetlink on SA-free device
+ ip(f"link set {ms2} type macsec offload off")
+ ip(f"link set {ms2} type macsec encrypt on offload mac")
+
+ # Toggle offload via genetlink
+ ip(f"macsec offload {ms2} off")
+ ip(f"macsec offload {ms2} mac")
+
+
+def test_max_secy(cfg) -> None:
+ """nsim-only test for max number of SecYs."""
+
+ cfg.require_nsim()
+ _require_ip_macsec_offload()
+ ms0 = _macsec_name(0)
+ ms1 = _macsec_name(1)
+ ms2 = _macsec_name(2)
+ ms3 = _macsec_name(3)
+
+ ip(f"link add link {cfg.ifname} {ms0} type macsec "
+ f"port 4 encrypt on offload mac")
+ defer(ip, f"link del {ms0}")
+
+ ip(f"link add link {cfg.ifname} {ms1} type macsec "
+ f"address aa:bb:cc:dd:ee:ff port 5 encrypt on offload mac")
+ defer(ip, f"link del {ms1}")
+
+ ip(f"link add link {cfg.ifname} {ms2} type macsec "
+ f"sci abbacdde01020304 encrypt on offload mac")
+ defer(ip, f"link del {ms2}")
+ with ksft_raises(CmdExitFailure):
+ ip(f"link add link {cfg.ifname} {ms3} "
+ f"type macsec port 8 encrypt on offload mac")
+
+
+def test_max_sc(cfg) -> None:
+ """nsim-only test for max number of SCs."""
+
+ cfg.require_nsim()
+ _require_ip_macsec_offload()
+ ms0 = _macsec_name(0)
+
+ ip(f"link add link {cfg.ifname} {ms0} type macsec "
+ f"port 4 encrypt on offload mac")
+ defer(ip, f"link del {ms0}")
+ ip(f"macsec add {ms0} rx port 1234 address 1c:ed:de:ad:be:ef")
+ with ksft_raises(CmdExitFailure):
+ ip(f"macsec add {ms0} rx port 1235 address 1c:ed:de:ad:be:ef")
+
+
+def test_offload_state(cfg) -> None:
+ """Offload state reflects configuration changes."""
+
+ _require_macsec_offload(cfg)
+ ms0 = _macsec_name(0)
+
+ # Create with offload on
+ ip(f"link add link {cfg.ifname} {ms0} type macsec "
+ f"encrypt on offload mac")
+ cleanup = defer(ip, f"link del {ms0}")
+
+ ksft_eq(_get_macsec_offload(ms0), "mac",
+ "created with offload: should be mac")
+
+ ip(f"link set {ms0} type macsec offload off")
+ ksft_eq(_get_macsec_offload(ms0), "off",
+ "offload disabled: should be off")
+
+ ip(f"link set {ms0} type macsec encrypt on offload mac")
+ ksft_eq(_get_macsec_offload(ms0), "mac",
+ "offload re-enabled: should be mac")
+
+ # Delete and recreate without offload
+ cleanup.exec()
+ ip(f"link add link {cfg.ifname} {ms0} type macsec")
+ defer(ip, f"link del {ms0}")
+ ksft_eq(_get_macsec_offload(ms0), "off",
+ "created without offload: should be off")
+
+ ip(f"link set {ms0} type macsec encrypt on offload mac")
+ ksft_eq(_get_macsec_offload(ms0), "mac",
+ "offload enabled after create: should be mac")
+
+
+def main() -> None:
+ """Main program."""
+ with NetDrvEpEnv(__file__) as cfg:
+ ksft_run([test_offload_api,
+ test_max_secy,
+ test_max_sc,
+ test_offload_state,
+ ], args=(cfg,))
+ ksft_exit()
+
+
+if __name__ == "__main__":
+ main()
diff --git a/tools/testing/selftests/drivers/net/netdevsim/Makefile b/tools/testing/selftests/drivers/net/netdevsim/Makefile
index 1a228c5430f5..9808c2fbae9e 100644
--- a/tools/testing/selftests/drivers/net/netdevsim/Makefile
+++ b/tools/testing/selftests/drivers/net/netdevsim/Makefile
@@ -11,7 +11,6 @@ TEST_PROGS := \
fib.sh \
fib_notifications.sh \
hw_stats_l3.sh \
- macsec-offload.sh \
nexthop.sh \
peer.sh \
psample.sh \
diff --git a/tools/testing/selftests/drivers/net/netdevsim/macsec-offload.sh b/tools/testing/selftests/drivers/net/netdevsim/macsec-offload.sh
deleted file mode 100755
index 98033e6667d2..000000000000
--- a/tools/testing/selftests/drivers/net/netdevsim/macsec-offload.sh
+++ /dev/null
@@ -1,117 +0,0 @@
-#!/bin/bash
-# SPDX-License-Identifier: GPL-2.0-only
-
-source ethtool-common.sh
-
-NSIM_NETDEV=$(make_netdev)
-MACSEC_NETDEV=macsec_nsim
-
-set -o pipefail
-
-if ! ethtool -k $NSIM_NETDEV | grep -q 'macsec-hw-offload: on'; then
- echo "SKIP: netdevsim doesn't support MACsec offload"
- exit 4
-fi
-
-if ! ip link add link $NSIM_NETDEV $MACSEC_NETDEV type macsec offload mac 2>/dev/null; then
- echo "SKIP: couldn't create macsec device"
- exit 4
-fi
-ip link del $MACSEC_NETDEV
-
-#
-# test macsec offload API
-#
-
-ip link add link $NSIM_NETDEV "${MACSEC_NETDEV}" type macsec port 4 offload mac
-check $?
-
-ip link add link $NSIM_NETDEV "${MACSEC_NETDEV}2" type macsec address "aa:bb:cc:dd:ee:ff" port 5 offload mac
-check $?
-
-ip link add link $NSIM_NETDEV "${MACSEC_NETDEV}3" type macsec sci abbacdde01020304 offload mac
-check $?
-
-ip link add link $NSIM_NETDEV "${MACSEC_NETDEV}4" type macsec port 8 offload mac 2> /dev/null
-check $? '' '' 1
-
-ip macsec add "${MACSEC_NETDEV}" tx sa 0 pn 1024 on key 01 12345678901234567890123456789012
-check $?
-
-ip macsec add "${MACSEC_NETDEV}" rx port 1234 address "1c:ed:de:ad:be:ef"
-check $?
-
-ip macsec add "${MACSEC_NETDEV}" rx port 1234 address "1c:ed:de:ad:be:ef" sa 0 pn 1 on \
- key 00 0123456789abcdef0123456789abcdef
-check $?
-
-ip macsec add "${MACSEC_NETDEV}" rx port 1235 address "1c:ed:de:ad:be:ef" 2> /dev/null
-check $? '' '' 1
-
-# can't disable macsec offload when SAs are configured
-ip link set "${MACSEC_NETDEV}" type macsec offload off 2> /dev/null
-check $? '' '' 1
-
-ip macsec offload "${MACSEC_NETDEV}" off 2> /dev/null
-check $? '' '' 1
-
-# toggle macsec offload via rtnetlink
-ip link set "${MACSEC_NETDEV}2" type macsec offload off
-check $?
-
-ip link set "${MACSEC_NETDEV}2" type macsec offload mac
-check $?
-
-# toggle macsec offload via genetlink
-ip macsec offload "${MACSEC_NETDEV}2" off
-check $?
-
-ip macsec offload "${MACSEC_NETDEV}2" mac
-check $?
-
-for dev in ${MACSEC_NETDEV}{,2,3} ; do
- ip link del $dev
- check $?
-done
-
-
-#
-# test ethtool features when toggling offload
-#
-
-ip link add link $NSIM_NETDEV $MACSEC_NETDEV type macsec offload mac
-TMP_FEATS_ON_1="$(ethtool -k $MACSEC_NETDEV)"
-
-ip link set $MACSEC_NETDEV type macsec offload off
-TMP_FEATS_OFF_1="$(ethtool -k $MACSEC_NETDEV)"
-
-ip link set $MACSEC_NETDEV type macsec offload mac
-TMP_FEATS_ON_2="$(ethtool -k $MACSEC_NETDEV)"
-
-[ "$TMP_FEATS_ON_1" = "$TMP_FEATS_ON_2" ]
-check $?
-
-ip link del $MACSEC_NETDEV
-
-ip link add link $NSIM_NETDEV $MACSEC_NETDEV type macsec
-check $?
-
-TMP_FEATS_OFF_2="$(ethtool -k $MACSEC_NETDEV)"
-[ "$TMP_FEATS_OFF_1" = "$TMP_FEATS_OFF_2" ]
-check $?
-
-ip link set $MACSEC_NETDEV type macsec offload mac
-check $?
-
-TMP_FEATS_ON_3="$(ethtool -k $MACSEC_NETDEV)"
-[ "$TMP_FEATS_ON_1" = "$TMP_FEATS_ON_3" ]
-check $?
-
-
-if [ $num_errors -eq 0 ]; then
- echo "PASSED all $((num_passes)) checks"
- exit 0
-else
- echo "FAILED $num_errors/$((num_errors+num_passes)) checks"
- exit 1
-fi
--
2.53.0
next prev parent reply other threads:[~2026-03-23 12:37 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-23 12:36 [PATCH net v5 0/3] macsec: Add support for VLAN filtering in offload mode Cosmin Ratiu
2026-03-23 12:36 ` Cosmin Ratiu [this message]
2026-03-23 12:36 ` [PATCH net v5 2/3] selftests: Add MACsec VLAN propagation traffic test Cosmin Ratiu
2026-03-23 16:26 ` Jakub Kicinski
2026-03-23 12:36 ` [PATCH net v5 3/3] macsec: Support VLAN-filtering lower devices Cosmin Ratiu
2026-03-23 14:28 ` [PATCH net v5 0/3] macsec: Add support for VLAN filtering in offload mode Sabrina Dubroca
2026-03-23 14:42 ` Cosmin Ratiu
2026-03-23 15:02 ` Sabrina Dubroca
2026-03-23 16:32 ` Jakub Kicinski
2026-03-23 17:17 ` Sabrina Dubroca
2026-03-24 14:27 ` Cosmin Ratiu
2026-03-24 15:18 ` Sabrina Dubroca
2026-03-25 3:55 ` Jakub Kicinski
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260323123633.756163-2-cratiu@nvidia.com \
--to=cratiu@nvidia.com \
--cc=andrew+netdev@lunn.ch \
--cc=davem@davemloft.net \
--cc=dtatulea@nvidia.com \
--cc=edumazet@google.com \
--cc=kuba@kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=sd@queasysnail.net \
--cc=shuah@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox