From f69acdd819b01aaa7d32b4bf27cd29fdd780a06f Mon Sep 17 00:00:00 2001 From: Nikolay Aleksandrov Date: Fri, 18 Sep 2026 18:29:45 +0300 Subject: [PATCH] net: bridge: vlan: introduce a list of port-VLANs in the master VLAN Keep a list of all port-VLANs that have been created within their master VLAN. The list is rcu-safe and will be used for optimizing the flood path. Signed-off-by: Nikolay Aleksandrov Reviewed-by: Ido Schimmel Link: https://patch.msgid.link/20260918152950.1938259-5-razor@blackwall.org Signed-off-by: Jakub Kicinski --- net/bridge/br_private.h | 2 ++ net/bridge/br_vlan.c | 11 +++++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index bda25f851342..b2a12b6298cb 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h @@ -210,6 +210,7 @@ enum { * @port_mcast_ctx: if MASTER flag unset, this is the per-port/vlan multicast * context * @msti: if MASTER flag set, this holds the VLANs MST instance + * @port_vlist: if MASTER flag set, this is the port-VLAN list * @vlist: sorted list of VLAN entries * @rcu: used for entry destruction * @@ -244,6 +245,7 @@ struct net_bridge_vlan { u16 msti; + struct list_head port_vlist; struct list_head vlist; struct rcu_head rcu; diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c index bfedd13e3fd4..34d1df59d190 100644 --- a/net/bridge/br_vlan.c +++ b/net/bridge/br_vlan.c @@ -130,10 +130,12 @@ static void __vlan_add_list(struct net_bridge_vlan *v) struct list_head *headp, *hpos; struct net_bridge_vlan *vent; - if (br_vlan_is_master(v)) + if (br_vlan_is_master(v)) { vg = br_vlan_group(v->br); - else + } else { vg = nbp_vlan_group(v->port); + list_add_rcu(&v->port_vlist, &v->brvlan->port_vlist); + } headp = &vg->vlan_list; list_for_each_prev(hpos, headp) { @@ -147,6 +149,10 @@ static void __vlan_add_list(struct net_bridge_vlan *v) static void __vlan_del_list(struct net_bridge_vlan *v) { list_del_rcu(&v->vlist); + if (br_vlan_is_master(v)) + WARN_ON(!list_empty(&v->port_vlist)); + else + list_del_rcu(&v->port_vlist); } static int __vlan_vid_del(struct net_device *dev, struct net_bridge *br, @@ -335,6 +341,7 @@ static int __vlan_add(struct net_bridge_vlan *v, u16 flags, } br_multicast_ctx_init(br, v, &v->br_mcast_ctx); v->priv_flags |= BR_VLFLAG_GLOBAL_MCAST_ENABLED; + INIT_LIST_HEAD(&v->port_vlist); } /* Add the dev mac and count the vlan only if it's usable */