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 --- 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