[PATCH RFC net-next] net: bridge: add BRIDGE_VLAN_INFO_DYNAMIC flag
From: Luke Howard <hidden>
Date: 2026-07-03 06:54:26
Also in:
bridge, lkml
Subsystem:
ethernet bridge, networking drivers, networking [general], the rest · Maintainers:
Nikolay Aleksandrov, Ido Schimmel, Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds
Dynamic VLAN entries as specified in IEEE Std 802.1Q-2022, Clause 8.8.5. These allow a user-space VLAN registration protocol such as MVRP to mark a bridge's VLAN entries as dynamic, so they can be distinguished from administratively configured static entries. Assisted-by: Claude:claude-opus-4-8 Signed-off-by: Luke Howard <redacted> --- This patch adds support for Dynamic VLAN Entries, as specified in 802.1Q. I have marked it as RFC as a similar patch to add support for Dynamic Reservation Entries to the FDB was rejected on the argument that the dynamic bit should be stored separately. Our MVRP implementation [1] will use this flag if available. [1] https://github.com/PADL/OpenSRP --- include/uapi/linux/if_bridge.h | 1 + net/bridge/br_netlink.c | 6 ++++++ net/bridge/br_vlan.c | 18 ++++++++++++++---- 3 files changed, 21 insertions(+), 4 deletions(-)
diff --git a/include/uapi/linux/if_bridge.h b/include/uapi/linux/if_bridge.h
index 21a700c02ef76..a3abbfe79694b 100644
--- a/include/uapi/linux/if_bridge.h
+++ b/include/uapi/linux/if_bridge.h@@ -134,6 +134,7 @@ enum { #define BRIDGE_VLAN_INFO_RANGE_END (1<<4) /* VLAN is end of vlan range */ #define BRIDGE_VLAN_INFO_BRENTRY (1<<5) /* Global bridge VLAN entry */ #define BRIDGE_VLAN_INFO_ONLY_OPTS (1<<6) /* Skip create/delete/flags */ +#define BRIDGE_VLAN_INFO_DYNAMIC (1<<7) /* 802.1Q Dynamic VLAN Registration Entry */ struct bridge_vlan_info { __u16 flags;
diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c
index b2cd4e39326d0..90f2e103f53d5 100644
--- a/net/bridge/br_netlink.c
+++ b/net/bridge/br_netlink.c@@ -388,6 +388,9 @@ static int br_fill_ifvlaninfo_compressed(struct sk_buff *skb, if (v->flags & BRIDGE_VLAN_INFO_UNTAGGED) flags |= BRIDGE_VLAN_INFO_UNTAGGED; + if (v->flags & BRIDGE_VLAN_INFO_DYNAMIC) + flags |= BRIDGE_VLAN_INFO_DYNAMIC; + if (vid_range_start == 0) { goto initvars; } else if ((v->vid - vid_range_end) == 1 &&
@@ -440,6 +443,9 @@ static int br_fill_ifvlaninfo(struct sk_buff *skb, if (v->flags & BRIDGE_VLAN_INFO_UNTAGGED) vinfo.flags |= BRIDGE_VLAN_INFO_UNTAGGED; + if (v->flags & BRIDGE_VLAN_INFO_DYNAMIC) + vinfo.flags |= BRIDGE_VLAN_INFO_DYNAMIC; + if (nla_put(skb, IFLA_BRIDGE_VLAN_INFO, sizeof(vinfo), &vinfo)) goto nla_put_failure;
diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c
index 5560afcaaca32..e6bc59e3a4c4f 100644
--- a/net/bridge/br_vlan.c
+++ b/net/bridge/br_vlan.c@@ -54,9 +54,11 @@ static void __vlan_delete_pvid(struct net_bridge_vlan_group *vg, u16 vid) vg->pvid = 0; } -/* Update the BRIDGE_VLAN_INFO_PVID and BRIDGE_VLAN_INFO_UNTAGGED flags of @v. - * If @commit is false, return just whether the BRIDGE_VLAN_INFO_PVID and - * BRIDGE_VLAN_INFO_UNTAGGED bits of @flags would produce any change onto @v. +/* Update the BRIDGE_VLAN_INFO_PVID, BRIDGE_VLAN_INFO_UNTAGGED and + * BRIDGE_VLAN_INFO_DYNAMIC flags of @v. + * If @commit is false, return just whether the BRIDGE_VLAN_INFO_PVID, + * BRIDGE_VLAN_INFO_UNTAGGED and BRIDGE_VLAN_INFO_DYNAMIC bits of @flags + * would produce any change onto @v. */ static bool __vlan_flags_update(struct net_bridge_vlan *v, u16 flags, bool commit)
@@ -71,7 +73,8 @@ static bool __vlan_flags_update(struct net_bridge_vlan *v, u16 flags, /* check if anything would be changed on commit */ change = !!(flags & BRIDGE_VLAN_INFO_PVID) == !!(vg->pvid != v->vid) || - ((flags ^ v->flags) & BRIDGE_VLAN_INFO_UNTAGGED); + ((flags ^ v->flags) & (BRIDGE_VLAN_INFO_UNTAGGED | + BRIDGE_VLAN_INFO_DYNAMIC)); if (!commit) goto out;
@@ -86,6 +89,11 @@ static bool __vlan_flags_update(struct net_bridge_vlan *v, u16 flags, else v->flags &= ~BRIDGE_VLAN_INFO_UNTAGGED; + if (flags & BRIDGE_VLAN_INFO_DYNAMIC) + v->flags |= BRIDGE_VLAN_INFO_DYNAMIC; + else + v->flags &= ~BRIDGE_VLAN_INFO_DYNAMIC; + out: return change; }
@@ -1874,6 +1882,8 @@ static bool br_vlan_fill_vids(struct sk_buff *skb, u16 vid, u16 vid_range, info.flags |= BRIDGE_VLAN_INFO_UNTAGGED; if (flags & BRIDGE_VLAN_INFO_PVID) info.flags |= BRIDGE_VLAN_INFO_PVID; + if (flags & BRIDGE_VLAN_INFO_DYNAMIC) + info.flags |= BRIDGE_VLAN_INFO_DYNAMIC; if (nla_put(skb, BRIDGE_VLANDB_ENTRY_INFO, sizeof(info), &info)) goto out_err;
--- base-commit: 2bb62a85aff6d4c14a62a476dfabaada3c1cc014 change-id: 20260703-vlan-dynamic-entry-56a028e8990e Best regards, -- Luke Howard [off-list ref]