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>,
"Cosmin Ratiu" <cratiu@nvidia.com>,
Dragos Tatulea <dtatulea@nvidia.com>
Subject: [PATCH net v3 3/3] macsec: Support VLAN-filtering lower devices
Date: Fri, 6 Mar 2026 17:10:04 +0200 [thread overview]
Message-ID: <20260306151004.2862198-4-cratiu@nvidia.com> (raw)
In-Reply-To: <20260306151004.2862198-1-cratiu@nvidia.com>
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 c2cb2d20976b..dec6a89aae2c 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.49.0
next prev parent reply other threads:[~2026-03-06 15:11 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-06 15:10 [PATCH net v3 0/3] macsec: Add support for VLAN filtering in offload mode Cosmin Ratiu
2026-03-06 15:10 ` [PATCH net v3 1/3] nsim: Add support for VLAN filters Cosmin Ratiu
2026-03-06 15:10 ` [PATCH net v3 2/3] selftests: Add macsec offload VLAN tests Cosmin Ratiu
2026-03-06 15:10 ` Cosmin Ratiu [this message]
2026-03-06 19:53 ` [PATCH net v3 0/3] macsec: Add support for VLAN filtering in offload mode Jakub Kicinski
2026-03-06 19:54 ` Jakub Kicinski
2026-03-09 16:23 ` Cosmin Ratiu
2026-03-09 21:21 ` Jakub Kicinski
2026-03-09 16:19 ` Cosmin Ratiu
2026-03-09 16:43 ` Sabrina Dubroca
2026-03-07 18:59 ` [syzbot ci] " syzbot ci
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=20260306151004.2862198-4-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=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=sd@queasysnail.net \
/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