On 14/03/2022 11:52, Tobias Waldekranz wrote: > br_mst_get_info answers the question: "On this bridge, which VIDs are > mapped to the given MSTI?" > > This is useful in switchdev drivers, which might have to fan-out > operations, relating to an MSTI, per VLAN. > > An example: When a port's MST state changes from forwarding to > blocking, a driver may choose to flush the dynamic FDB entries on that > port to get faster reconvergence of the network, but this should only > be done in the VLANs that are managed by the MSTI in question. > > Signed-off-by: Tobias Waldekranz <tobias@xxxxxxxxxxxxxx> > --- > include/linux/if_bridge.h | 6 ++++++ > net/bridge/br_mst.c | 26 ++++++++++++++++++++++++++ > 2 files changed, 32 insertions(+) > > diff --git a/include/linux/if_bridge.h b/include/linux/if_bridge.h > index 3aae023a9353..46e6327fef06 100644 > --- a/include/linux/if_bridge.h > +++ b/include/linux/if_bridge.h > @@ -119,6 +119,7 @@ int br_vlan_get_info(const struct net_device *dev, u16 vid, > struct bridge_vlan_info *p_vinfo); > int br_vlan_get_info_rcu(const struct net_device *dev, u16 vid, > struct bridge_vlan_info *p_vinfo); > +int br_mst_get_info(struct net_device *dev, u16 msti, unsigned long *vids); > #else > static inline bool br_vlan_enabled(const struct net_device *dev) > { > @@ -151,6 +152,11 @@ static inline int br_vlan_get_info_rcu(const struct net_device *dev, u16 vid, > { > return -EINVAL; > } > +static inline int br_mst_get_info(struct net_device *dev, u16 msti, > + unsigned long *vids) > +{ > + return -EINVAL; > +} > #endif > > #if IS_ENABLED(CONFIG_BRIDGE) > diff --git a/net/bridge/br_mst.c b/net/bridge/br_mst.c > index 7d16926a3a31..eb18dbd5838f 100644 > --- a/net/bridge/br_mst.c > +++ b/net/bridge/br_mst.c > @@ -13,6 +13,32 @@ > > DEFINE_STATIC_KEY_FALSE(br_mst_used); > > +int br_mst_get_info(struct net_device *dev, u16 msti, unsigned long *vids) > +{ > + struct net_bridge_vlan_group *vg; > + struct net_bridge_vlan *v; > + struct net_bridge *br; const dev, vg, v, br > + > + ASSERT_RTNL(); > + > + if (!netif_is_bridge_master(dev)) > + return -EINVAL; > + > + br = netdev_priv(dev); > + if (!br_opt_get(br, BROPT_MST_ENABLED)) > + return -EINVAL; > + > + vg = br_vlan_group(br); > + > + list_for_each_entry(v, &vg->vlan_list, vlist) { > + if (v->msti == msti) > + set_bit(v->vid, vids); __set_bit() > + } > + > + return 0; > +} > +EXPORT_SYMBOL(br_mst_get_info); EXPORT_SYMBOL_GPL > + > static void br_mst_vlan_set_state(struct net_bridge_port *p, struct net_bridge_vlan *v, > u8 state) > {