public inbox for netdev@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/3] macsec: Add support for VLAN filtering in offload mode
@ 2026-03-13 10:52 Cosmin Ratiu
  2026-03-13 10:52 ` [PATCH 1/3] selftests: Migrate nsim-only MACsec tests to Python Cosmin Ratiu
                   ` (4 more replies)
  0 siblings, 5 replies; 7+ messages in thread
From: Cosmin Ratiu @ 2026-03-13 10:52 UTC (permalink / raw)
  To: netdev
  Cc: Sabrina Dubroca, Andrew Lunn, David S . Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Cosmin Ratiu, Dragos Tatulea

This short series adds support for VLANs in macsec devices when offload
mode is enabled. This allows VLAN netdevs on top of macsec netdevs to
function, which accidentally used to be the case in the past, but was
broken. This series adds back proper support.

As part of this, the existing nsim-only macsec offload tests were
translated to Python so they can run against real HW and new
traffic-based tests were added for VLAN filter propagation, since
there's currently no uAPI to check VLAN filters.

V4:
- Migrated nsim-only macsec tests to Python, usable against real hw.
- Ran these tests against both nsim and mlx5 devs.
- Gave up on nsim patches since the tests no longer use them.

V3: https://lore.kernel.org/netdev/20260306151004.2862198-1-cratiu@nvidia.com/t/#u
- Moved back to net.
- Added proper rollback support for VLAN filters in case of failure.
- Added VLAN as a requirement for the new macsec tests.

V2: https://lore.kernel.org/netdev/20260227090227.1552512-1-cratiu@nvidia.com/
- Sent to net-next instead of net because of apparent complexity.
- Changed VLAN filtering to only function in offload mode.
- Added tests.

V1: https://lore.kernel.org/netdev/20260107104723.2750725-1-cratiu@nvidia.com/


Cosmin Ratiu (3):
  selftests: Migrate nsim-only MACsec tests to Python
  selftests: Add MACsec VLAN propagation traffic test
  macsec: Support VLAN-filtering lower devices

 drivers/net/macsec.c                          |  44 +++++-
 tools/testing/selftests/drivers/net/Makefile  |   6 +
 .../selftests/drivers/net/macsec_api.py       | 103 ++++++++++++++
 .../selftests/drivers/net/macsec_lib.py       |  20 +++
 .../selftests/drivers/net/macsec_traffic.py   | 126 ++++++++++++++++++
 .../selftests/drivers/net/netdevsim/Makefile  |   1 -
 .../drivers/net/netdevsim/macsec-offload.sh   | 117 ----------------
 7 files changed, 294 insertions(+), 123 deletions(-)
 create mode 100755 tools/testing/selftests/drivers/net/macsec_api.py
 create mode 100644 tools/testing/selftests/drivers/net/macsec_lib.py
 create mode 100755 tools/testing/selftests/drivers/net/macsec_traffic.py
 delete mode 100755 tools/testing/selftests/drivers/net/netdevsim/macsec-offload.sh

-- 
2.43.0


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 1/3] selftests: Migrate nsim-only MACsec tests to Python
  2026-03-13 10:52 [PATCH 0/3] macsec: Add support for VLAN filtering in offload mode Cosmin Ratiu
@ 2026-03-13 10:52 ` Cosmin Ratiu
  2026-03-13 10:52 ` [PATCH 2/3] selftests: Add MACsec VLAN propagation traffic test Cosmin Ratiu
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: Cosmin Ratiu @ 2026-03-13 10:52 UTC (permalink / raw)
  To: netdev
  Cc: Sabrina Dubroca, Andrew Lunn, David S . Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Cosmin Ratiu, Dragos Tatulea

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_api.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.
Extract shared helpers into macsec_lib.py for reuse by upcoming traffic
tests.

Netdevsim-specific limit checks (max SecY, max RX SC) are guarded
behind cfg._ns checks to avoid failures on real hardware.

Signed-off-by: Cosmin Ratiu <cratiu@nvidia.com>
---
 tools/testing/selftests/drivers/net/Makefile  |   5 +
 .../selftests/drivers/net/macsec_api.py       | 103 +++++++++++++++
 .../selftests/drivers/net/macsec_lib.py       |  20 +++
 .../selftests/drivers/net/netdevsim/Makefile  |   1 -
 .../drivers/net/netdevsim/macsec-offload.sh   | 117 ------------------
 5 files changed, 128 insertions(+), 118 deletions(-)
 create mode 100755 tools/testing/selftests/drivers/net/macsec_api.py
 create mode 100644 tools/testing/selftests/drivers/net/macsec_lib.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..511346b7d9ec 100644
--- a/tools/testing/selftests/drivers/net/Makefile
+++ b/tools/testing/selftests/drivers/net/Makefile
@@ -10,9 +10,14 @@ TEST_GEN_FILES := \
 	napi_id_helper \
 # end of TEST_GEN_FILES
 
+TEST_FILES := \
+	macsec_lib.py \
+# end of TEST_FILES
+
 TEST_PROGS := \
 	gro.py \
 	hds.py \
+	macsec_api.py \
 	napi_id.py \
 	napi_threaded.py \
 	netpoll_basic.py \
diff --git a/tools/testing/selftests/drivers/net/macsec_api.py b/tools/testing/selftests/drivers/net/macsec_api.py
new file mode 100755
index 000000000000..1d1185582bcd
--- /dev/null
+++ b/tools/testing/selftests/drivers/net/macsec_api.py
@@ -0,0 +1,103 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0
+
+"""MACsec offload API and ethtool feature tests."""
+
+from lib.py import ksft_run, ksft_exit, ksft_eq, ksft_raises
+from lib.py import CmdExitFailure
+from lib.py import NetDrvEnv
+from lib.py import ip, defer
+from macsec_lib import require_macsec_offload, get_macsec_offload
+
+
+def test_offload_api(cfg) -> None:
+    """MACsec offload API: create SecY, add SA/rx, toggle offload."""
+
+    require_macsec_offload(cfg)
+    # Create 3 SecY with offload
+    ip(f"link add link {cfg.ifname} macsec0 type macsec "
+       f"port 4 encrypt on offload mac")
+    defer(ip, f"link del macsec0")
+
+    ip(f"link add link {cfg.ifname} macsec1 type macsec "
+       f"address aa:bb:cc:dd:ee:ff port 5 encrypt on offload mac")
+    defer(ip, f"link del macsec1")
+
+    ip(f"link add link {cfg.ifname} macsec2 type macsec "
+       f"sci abbacdde01020304 encrypt on offload mac")
+    defer(ip, f"link del macsec2")
+
+    # nsim-only: 4th SecY should fail (max 3)
+    if cfg._ns is not None:
+        with ksft_raises(CmdExitFailure):
+            ip(f"link add link {cfg.ifname} macsec3 "
+               f"type macsec port 8 encrypt on offload mac")
+
+    # Add TX SA
+    ip(f"macsec add macsec0 tx sa 0 pn 1024 on "
+       f"key 01 12345678901234567890123456789012")
+
+    # Add RX SC + SA
+    ip(f'macsec add macsec0 rx port 1234 address 1c:ed:de:ad:be:ef')
+    ip(f'macsec add macsec0 rx port 1234 address 1c:ed:de:ad:be:ef '
+       f"sa 0 pn 1 on key 00 0123456789abcdef0123456789abcdef")
+
+    # nsim-only: 2nd RX SC should fail (max 1)
+    if cfg._ns is not None:
+        with ksft_raises(CmdExitFailure):
+            ip(f'macsec add macsec0 rx port 1235 address 1c:ed:de:ad:be:ef')
+
+    # Can't disable offload when SAs are configured
+    with ksft_raises(CmdExitFailure):
+        ip(f"link set macsec0 type macsec offload off")
+    with ksft_raises(CmdExitFailure):
+        ip(f"macsec offload macsec0 off")
+
+    # Toggle offload via rtnetlink on SA-free device
+    ip(f"link set macsec2 type macsec offload off")
+    ip(f"link set macsec2 type macsec encrypt on offload mac")
+
+    # Toggle offload via genetlink
+    ip(f"macsec offload macsec2 off")
+    ip(f"macsec offload macsec2 mac")
+
+
+def test_offload_state(cfg) -> None:
+    """Offload state reflects configuration changes."""
+
+    require_macsec_offload(cfg)
+    # Create with offload on
+    ip(f"link add link {cfg.ifname} macsec0 type macsec "
+       f"encrypt on offload mac")
+    ksft_eq(get_macsec_offload("macsec0"), "mac",
+            "created with offload: should be mac")
+
+    ip(f"link set macsec0 type macsec offload off")
+    ksft_eq(get_macsec_offload("macsec0"), "off",
+            "offload disabled: should be off")
+
+    ip(f"link set macsec0 type macsec encrypt on offload mac")
+    ksft_eq(get_macsec_offload("macsec0"), "mac",
+            "offload re-enabled: should be mac")
+
+    # Delete and recreate without offload
+    ip(f"link del macsec0")
+    ip(f"link add link {cfg.ifname} macsec0 type macsec")
+    defer(ip, f"link del macsec0")
+    ksft_eq(get_macsec_offload("macsec0"), "off",
+            "created without offload: should be off")
+
+    ip(f"link set macsec0 type macsec encrypt on offload mac")
+    ksft_eq(get_macsec_offload("macsec0"), "mac",
+            "offload enabled after create: should be mac")
+
+
+def main() -> None:
+    with NetDrvEnv(__file__) as cfg:
+        ksft_run([test_offload_api,
+                  test_offload_state], args=(cfg,))
+    ksft_exit()
+
+
+if __name__ == "__main__":
+    main()
diff --git a/tools/testing/selftests/drivers/net/macsec_lib.py b/tools/testing/selftests/drivers/net/macsec_lib.py
new file mode 100644
index 000000000000..452b0f9026c8
--- /dev/null
+++ b/tools/testing/selftests/drivers/net/macsec_lib.py
@@ -0,0 +1,20 @@
+# SPDX-License-Identifier: GPL-2.0
+
+"""Shared helpers for MACsec offload tests."""
+
+from lib.py import KsftSkipEx, ethtool, ip
+
+MACSEC_KEY = "12345678901234567890123456789012"
+
+
+def get_macsec_offload(dev):
+    """Return 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_macsec_offload(cfg):
+    """SKIP if lower device doesn't support macsec-hw-offload."""
+    feat = ethtool(f"-k {cfg.ifname}", json=True)[0]
+    if not feat.get("macsec-hw-offload", {}).get("active"):
+        raise KsftSkipEx("macsec-hw-offload not supported")
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.43.0


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 2/3] selftests: Add MACsec VLAN propagation traffic test
  2026-03-13 10:52 [PATCH 0/3] macsec: Add support for VLAN filtering in offload mode Cosmin Ratiu
  2026-03-13 10:52 ` [PATCH 1/3] selftests: Migrate nsim-only MACsec tests to Python Cosmin Ratiu
@ 2026-03-13 10:52 ` Cosmin Ratiu
  2026-03-13 10:52 ` [PATCH 3/3] macsec: Support VLAN-filtering lower devices Cosmin Ratiu
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: Cosmin Ratiu @ 2026-03-13 10:52 UTC (permalink / raw)
  To: netdev
  Cc: Sabrina Dubroca, Andrew Lunn, David S . Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Cosmin Ratiu, Dragos Tatulea

Add macsec_traffic.py using NetDrvEpEnv to verify VLAN filter
propagation through offloaded macsec devices via actual traffic.

Test creates macsec tunnels with matching SAs on both endpoints,
stacks VLANs on top, and verifies connectivity with ping. Covers:
- Offloaded macsec with VLAN (filters propagate to HW)
- Software macsec with VLAN (no HW filter propagation)
- Toggle offload on/off and verify traffic still works

On netdevsim this is a smoke test (stub offload, no real encryption).
On real hardware this validates actual VLAN filter propagation.

Signed-off-by: Cosmin Ratiu <cratiu@nvidia.com>
---
 tools/testing/selftests/drivers/net/Makefile  |   1 +
 .../selftests/drivers/net/macsec_traffic.py   | 126 ++++++++++++++++++
 2 files changed, 127 insertions(+)
 create mode 100755 tools/testing/selftests/drivers/net/macsec_traffic.py

diff --git a/tools/testing/selftests/drivers/net/Makefile b/tools/testing/selftests/drivers/net/Makefile
index 511346b7d9ec..102aba3b2518 100644
--- a/tools/testing/selftests/drivers/net/Makefile
+++ b/tools/testing/selftests/drivers/net/Makefile
@@ -18,6 +18,7 @@ TEST_PROGS := \
 	gro.py \
 	hds.py \
 	macsec_api.py \
+	macsec_traffic.py \
 	napi_id.py \
 	napi_threaded.py \
 	netpoll_basic.py \
diff --git a/tools/testing/selftests/drivers/net/macsec_traffic.py b/tools/testing/selftests/drivers/net/macsec_traffic.py
new file mode 100755
index 000000000000..c446c264a749
--- /dev/null
+++ b/tools/testing/selftests/drivers/net/macsec_traffic.py
@@ -0,0 +1,126 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0
+
+"""MACsec VLAN propagation traffic tests."""
+
+from lib.py import ksft_run, ksft_exit, ksft_pr, ksft_variants, KsftNamedVariant
+from lib.py import CmdExitFailure
+from lib.py import NetDrvEpEnv
+from lib.py import cmd, ip, defer
+from macsec_lib import require_macsec_offload
+
+MACSEC_KEY = "12345678901234567890123456789012"
+MACSEC_NAME = "macsec_t"
+MACSEC_VLAN_VID = 10
+
+
+def _get_mac(ifname, host=None):
+    """Gets MAC address of an interface."""
+    dev = ip(f"-d link show dev {ifname}", json=True, host=host)
+    return dev[0]["address"]
+
+
+def _setup_macsec_sa(cfg, name):
+    """Adds matching TX/RX SAs on both ends."""
+    local_mac = _get_mac(name)
+    remote_mac = _get_mac(name, host=cfg.remote)
+
+    ip(f"macsec add {name} tx sa 0 pn 1 on key 01 {MACSEC_KEY}")
+    ip(f"macsec add {name} rx port 1 address {remote_mac}")
+    ip(f"macsec add {name} rx port 1 address {remote_mac} "
+       f"sa 0 pn 1 on key 02 {MACSEC_KEY}")
+
+    ip(f"macsec add {name} tx sa 0 pn 1 on key 02 {MACSEC_KEY}",
+       host=cfg.remote)
+    ip(f"macsec add {name} rx port 1 address {local_mac}", host=cfg.remote)
+    ip(f"macsec add {name} rx port 1 address {local_mac} "
+       f"sa 0 pn 1 on key 01 {MACSEC_KEY}", host=cfg.remote)
+
+
+def _setup_macsec_devs(cfg, name, offload):
+    """Creates macsec devices on both ends."""
+    offload_arg = "mac" if offload else "off"
+    macsec_args = f"type macsec encrypt on offload {offload_arg}"
+
+    ip(f"link add link {cfg.ifname} {name} {macsec_args}")
+    defer(ip, f"link del {name}")
+    ip(f"link add link {cfg.remote_ifname} {name} {macsec_args}",
+       host=cfg.remote)
+    defer(ip, f"link del {name}", host=cfg.remote)
+
+
+def _set_offload(cfg, name, offload):
+    """Sets offload on both macsec devices."""
+    offload_arg = "mac" if offload else "off"
+
+    ip(f"link set {name} type macsec encrypt on offload {offload_arg}")
+    ip(f"link set {name} type macsec encrypt on offload {offload_arg}",
+       host=cfg.remote)
+
+
+def _setup_vlans(cfg, name, vid):
+    """Adds VLANs on top of existing macsec devs."""
+    vlan_name = f"{name}.{vid}"
+
+    ip(f"link add link {name} {vlan_name} type vlan id {vid}")
+    defer(ip, f"link del {vlan_name}")
+    ip(f"link add link {name} {vlan_name} type vlan id {vid}", host=cfg.remote)
+    defer(ip, f"link del {vlan_name}", host=cfg.remote)
+
+
+def _setup_vlan_ips(cfg, name, vid):
+    """Adds VLAN IPs."""
+    local_ip = f"10.0.{vid}.1"
+    remote_ip = f"10.0.{vid}.2"
+    vlan_name = f"{name}.{vid}"
+
+    ip(f"addr add {local_ip}/24 dev {vlan_name}")
+    ip(f"addr add {remote_ip}/24 dev {vlan_name}", host=cfg.remote)
+    ip(f"link set {name} up")
+    ip(f"link set {name} up", host=cfg.remote)
+    ip(f"link set {vlan_name} up")
+    ip(f"link set {vlan_name} up", host=cfg.remote)
+
+    return remote_ip
+
+
+@ksft_variants([
+    KsftNamedVariant("offloaded", True),
+    KsftNamedVariant("software", False),
+])
+def test_vlan(cfg, offload) -> None:
+    """Ping through VLAN-over-macsec."""
+
+    require_macsec_offload(cfg)
+    _setup_macsec_devs(cfg, MACSEC_NAME, offload=offload)
+    _setup_macsec_sa(cfg, MACSEC_NAME)
+    _setup_vlans(cfg, MACSEC_NAME, MACSEC_VLAN_VID)
+    remote_ip = _setup_vlan_ips(cfg, MACSEC_NAME, MACSEC_VLAN_VID)
+    cmd(f"ping -c 1 -W 5 {remote_ip}")
+
+
+@ksft_variants([
+    KsftNamedVariant("toggle_on", True),
+    KsftNamedVariant("toggle_off", False),
+])
+def test_vlan_toggle(cfg, offload) -> None:
+    """Toggle offload: VLAN filters propagate/remove correctly."""
+
+    require_macsec_offload(cfg)
+    _setup_macsec_devs(cfg, MACSEC_NAME, offload=offload)
+    _setup_vlans(cfg, MACSEC_NAME, MACSEC_VLAN_VID)
+    _set_offload(cfg, MACSEC_NAME, offload=not offload)
+    remote_ip = _setup_vlan_ips(cfg, MACSEC_NAME, MACSEC_VLAN_VID)
+    _setup_macsec_sa(cfg, MACSEC_NAME)
+    cmd(f"ping -c 1 -W 5 {remote_ip}")
+
+
+def main() -> None:
+    with NetDrvEpEnv(__file__) as cfg:
+        ksft_run([test_vlan,
+                  test_vlan_toggle], args=(cfg,))
+    ksft_exit()
+
+
+if __name__ == "__main__":
+    main()
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 3/3] macsec: Support VLAN-filtering lower devices
  2026-03-13 10:52 [PATCH 0/3] macsec: Add support for VLAN filtering in offload mode Cosmin Ratiu
  2026-03-13 10:52 ` [PATCH 1/3] selftests: Migrate nsim-only MACsec tests to Python Cosmin Ratiu
  2026-03-13 10:52 ` [PATCH 2/3] selftests: Add MACsec VLAN propagation traffic test Cosmin Ratiu
@ 2026-03-13 10:52 ` Cosmin Ratiu
  2026-03-13 10:56 ` [PATCH 0/3] macsec: Add support for VLAN filtering in offload mode Cosmin Ratiu
  2026-03-13 17:31 ` Jakub Kicinski
  4 siblings, 0 replies; 7+ messages in thread
From: Cosmin Ratiu @ 2026-03-13 10:52 UTC (permalink / raw)
  To: netdev
  Cc: Sabrina Dubroca, Andrew Lunn, David S . Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Cosmin Ratiu, Dragos Tatulea

VLAN-filtering is done through two netdev features
(NETIF_F_HW_VLAN_CTAG_FILTER and NETIF_F_HW_VLAN_STAG_FILTER) and two
netdev ops (ndo_vlan_rx_add_vid and ndo_vlan_rx_kill_vid).

Implement these and advertise the features if the lower device supports
them. This allows proper VLAN filtering to work on top of macsec
devices, when the lower device is capable of VLAN filtering.
As a concrete example, having this chain of interfaces now works:
vlan_filtering_capable_dev(1) -> macsec_dev(2) -> macsec_vlan_dev(3)

Before commit [1] this used to accidentally work because the macsec
device (and thus the lower device) was put in promiscuous mode and the
VLAN filter was not used. But after commit [1] correctly made the macsec
driver expose the IFF_UNICAST_FLT flag, promiscuous mode was no longer
used and VLAN filters on dev 1 kicked in. Without support in dev 2 for
propagating VLAN filters down, the register_vlan_dev -> vlan_vid_add ->
__vlan_vid_add -> vlan_add_rx_filter_info call from dev 3 is silently
eaten (because vlan_hw_filter_capable returns false and
vlan_add_rx_filter_info silently succeeds).

For macsec, VLAN filters are only relevant for offload, otherwise
the VLANs are encrypted and the lower devices don't care about them. So
VLAN filters are only passed on to lower devices in offload mode.
Flipping between offload modes now needs to offload/unoffload the
filters with vlan_{get,drop}_rx_*_filter_info().

To avoid the back-and-forth filter updating during rollback, the setting
of macsec->offload is moved after the add/del secy ops. This is safe
since none of the code called from those requires macsec->offload.

[1] commit 0349659fd72f ("macsec: set IFF_UNICAST_FLT priv flag")
Signed-off-by: Cosmin Ratiu <cratiu@nvidia.com>
---
 drivers/net/macsec.c | 44 +++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 39 insertions(+), 5 deletions(-)

diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c
index f6cad0746a02..3bdb6f3fae8e 100644
--- a/drivers/net/macsec.c
+++ b/drivers/net/macsec.c
@@ -2616,14 +2616,22 @@ static int macsec_update_offload(struct net_device *dev, enum macsec_offload off
 	if (!ops)
 		return -EOPNOTSUPP;
 
-	macsec->offload = offload;
-
 	ctx.secy = &macsec->secy;
 	ret = offload == MACSEC_OFFLOAD_OFF ? macsec_offload(ops->mdo_del_secy, &ctx)
 					    : macsec_offload(ops->mdo_add_secy, &ctx);
-	if (ret) {
-		macsec->offload = prev_offload;
+	if (ret)
 		return ret;
+
+	/* Remove VLAN filters when disabling offload. */
+	if (offload == MACSEC_OFFLOAD_OFF) {
+		vlan_drop_rx_ctag_filter_info(dev);
+		vlan_drop_rx_stag_filter_info(dev);
+	}
+	macsec->offload = offload;
+	/* Add VLAN filters when enabling offload. */
+	if (prev_offload == MACSEC_OFFLOAD_OFF) {
+		vlan_get_rx_ctag_filter_info(dev);
+		vlan_get_rx_stag_filter_info(dev);
 	}
 
 	macsec_set_head_tail_room(dev);
@@ -3486,7 +3494,8 @@ static netdev_tx_t macsec_start_xmit(struct sk_buff *skb,
 }
 
 #define MACSEC_FEATURES \
-	(NETIF_F_SG | NETIF_F_HIGHDMA | NETIF_F_FRAGLIST)
+	(NETIF_F_SG | NETIF_F_HIGHDMA | NETIF_F_FRAGLIST | \
+	 NETIF_F_HW_VLAN_STAG_FILTER | NETIF_F_HW_VLAN_CTAG_FILTER)
 
 #define MACSEC_OFFLOAD_FEATURES \
 	(MACSEC_FEATURES | NETIF_F_GSO_SOFTWARE | NETIF_F_SOFT_FEATURES | \
@@ -3707,6 +3716,29 @@ static int macsec_set_mac_address(struct net_device *dev, void *p)
 	return err;
 }
 
+static int macsec_vlan_rx_add_vid(struct net_device *dev,
+				  __be16 proto, u16 vid)
+{
+	struct macsec_dev *macsec = netdev_priv(dev);
+
+	if (!macsec_is_offloaded(macsec))
+		return 0;
+
+	return vlan_vid_add(macsec->real_dev, proto, vid);
+}
+
+static int macsec_vlan_rx_kill_vid(struct net_device *dev,
+				   __be16 proto, u16 vid)
+{
+	struct macsec_dev *macsec = netdev_priv(dev);
+
+	if (!macsec_is_offloaded(macsec))
+		return 0;
+
+	vlan_vid_del(macsec->real_dev, proto, vid);
+	return 0;
+}
+
 static int macsec_change_mtu(struct net_device *dev, int new_mtu)
 {
 	struct macsec_dev *macsec = macsec_priv(dev);
@@ -3748,6 +3780,8 @@ static const struct net_device_ops macsec_netdev_ops = {
 	.ndo_set_rx_mode	= macsec_dev_set_rx_mode,
 	.ndo_change_rx_flags	= macsec_dev_change_rx_flags,
 	.ndo_set_mac_address	= macsec_set_mac_address,
+	.ndo_vlan_rx_add_vid	= macsec_vlan_rx_add_vid,
+	.ndo_vlan_rx_kill_vid	= macsec_vlan_rx_kill_vid,
 	.ndo_start_xmit		= macsec_start_xmit,
 	.ndo_get_stats64	= macsec_get_stats64,
 	.ndo_get_iflink		= macsec_get_iflink,
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH 0/3] macsec: Add support for VLAN filtering in offload mode
  2026-03-13 10:52 [PATCH 0/3] macsec: Add support for VLAN filtering in offload mode Cosmin Ratiu
                   ` (2 preceding siblings ...)
  2026-03-13 10:52 ` [PATCH 3/3] macsec: Support VLAN-filtering lower devices Cosmin Ratiu
@ 2026-03-13 10:56 ` Cosmin Ratiu
  2026-03-13 14:18   ` Cosmin Ratiu
  2026-03-13 17:31 ` Jakub Kicinski
  4 siblings, 1 reply; 7+ messages in thread
From: Cosmin Ratiu @ 2026-03-13 10:56 UTC (permalink / raw)
  To: netdev@vger.kernel.org
  Cc: pabeni@redhat.com, Dragos Tatulea, edumazet@google.com,
	andrew+netdev@lunn.ch, davem@davemloft.net, sd@queasysnail.net,
	kuba@kernel.org

On Fri, 2026-03-13 at 11:52 +0100, Cosmin Ratiu wrote:
> This short series adds support for VLANs in macsec devices when
> offload mode is enabled.

Seems I forgot the "PATCH net" prefix, even though the series is based
on and intended for net. Will that be a problem? Should I resend?

Cosmin.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 0/3] macsec: Add support for VLAN filtering in offload mode
  2026-03-13 10:56 ` [PATCH 0/3] macsec: Add support for VLAN filtering in offload mode Cosmin Ratiu
@ 2026-03-13 14:18   ` Cosmin Ratiu
  0 siblings, 0 replies; 7+ messages in thread
From: Cosmin Ratiu @ 2026-03-13 14:18 UTC (permalink / raw)
  To: netdev@vger.kernel.org
  Cc: sd@queasysnail.net, kuba@kernel.org, Dragos Tatulea,
	edumazet@google.com, andrew+netdev@lunn.ch, pabeni@redhat.com,
	davem@davemloft.net

On Fri, 2026-03-13 at 10:56 +0000, Cosmin Ratiu wrote:
> On Fri, 2026-03-13 at 11:52 +0100, Cosmin Ratiu wrote:
> > This short series adds support for VLANs in macsec devices when
> > offload mode is enabled.
> 
> Seems I forgot the "PATCH net" prefix, even though the series is
> based
> on and intended for net. Will that be a problem? Should I resend?
> 

To answer my own question (somewhat): I'll need to resend, as it seems
I also forgot to run pylint (relied on checkpatch.pl only).

But please provide additional feedback on the tests if possible.

Thank you,
Cosmin.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 0/3] macsec: Add support for VLAN filtering in offload mode
  2026-03-13 10:52 [PATCH 0/3] macsec: Add support for VLAN filtering in offload mode Cosmin Ratiu
                   ` (3 preceding siblings ...)
  2026-03-13 10:56 ` [PATCH 0/3] macsec: Add support for VLAN filtering in offload mode Cosmin Ratiu
@ 2026-03-13 17:31 ` Jakub Kicinski
  4 siblings, 0 replies; 7+ messages in thread
From: Jakub Kicinski @ 2026-03-13 17:31 UTC (permalink / raw)
  To: Cosmin Ratiu
  Cc: netdev, Sabrina Dubroca, Andrew Lunn, David S . Miller,
	Eric Dumazet, Paolo Abeni, Dragos Tatulea

On Fri, 13 Mar 2026 11:52:23 +0100 Cosmin Ratiu wrote:
>  .../selftests/drivers/net/macsec_api.py       | 103 ++++++++++++++
>  .../selftests/drivers/net/macsec_lib.py       |  20 +++
>  .../selftests/drivers/net/macsec_traffic.py   | 126 ++++++++++++++++++

Thanks for converting! I think we're missing MACSEC from
selftests/drivers/net/config cause kernels end up getting built without
it. And we see:

# ok 1 macsec_traffic.test_vlan.offloaded # SKIP macsec-hw-offload not supported
# ok 2 macsec_traffic.test_vlan.software # SKIP macsec-hw-offload not supported
# ok 3 macsec_traffic.test_vlan_toggle.toggle_on # SKIP macsec-hw-offload not supported
# ok 4 macsec_traffic.test_vlan_toggle.toggle_off # SKIP macsec-hw-offload not supported
# # Totals: pass:0 fail:0 xfail:0 xpass:0 skip:4 error:0


Also I'm slightly weary about "frameworkification" of the selftests so
since the selftests aren't huge maybe avoid creating the lib and just
squash all the macsec tests into one file? Or is there a reason?
I know that it feels cleaner to separate things out but in case of
tests which mostly get fly-by contributions having to teach people
about libraries is quite a lift..

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2026-03-13 17:31 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-13 10:52 [PATCH 0/3] macsec: Add support for VLAN filtering in offload mode Cosmin Ratiu
2026-03-13 10:52 ` [PATCH 1/3] selftests: Migrate nsim-only MACsec tests to Python Cosmin Ratiu
2026-03-13 10:52 ` [PATCH 2/3] selftests: Add MACsec VLAN propagation traffic test Cosmin Ratiu
2026-03-13 10:52 ` [PATCH 3/3] macsec: Support VLAN-filtering lower devices Cosmin Ratiu
2026-03-13 10:56 ` [PATCH 0/3] macsec: Add support for VLAN filtering in offload mode Cosmin Ratiu
2026-03-13 14:18   ` Cosmin Ratiu
2026-03-13 17:31 ` Jakub Kicinski

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox