From: Petr Machata Date: Fri, 7 Dec 2018 19:55:07 +0000 (+0000) Subject: bridge: Add br_fdb_clear_offload() X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=43920edf3b24b0a3d136019c816e84ffcbef83ab;p=openwrt%2Fstaging%2Fblogic.git bridge: Add br_fdb_clear_offload() When a driver unoffloads all FDB entries en bloc, it's inefficient to send the switchdev notification one by one. Add a helper that unsets the offload flag on FDB entries on a given bridge port and VLAN. Signed-off-by: Petr Machata Acked-by: Nikolay Aleksandrov Signed-off-by: Ido Schimmel Signed-off-by: David S. Miller --- diff --git a/include/linux/if_bridge.h b/include/linux/if_bridge.h index ef7c3d376b21..627b788ba0ff 100644 --- a/include/linux/if_bridge.h +++ b/include/linux/if_bridge.h @@ -119,6 +119,7 @@ static inline int br_vlan_get_info(const struct net_device *dev, u16 vid, struct net_device *br_fdb_find_port(const struct net_device *br_dev, const unsigned char *addr, __u16 vid); +void br_fdb_clear_offload(const struct net_device *dev, u16 vid); bool br_port_flag_is_set(const struct net_device *dev, unsigned long flag); #else static inline struct net_device * @@ -128,6 +129,11 @@ br_fdb_find_port(const struct net_device *br_dev, { return NULL; } + +static inline void br_fdb_clear_offload(const struct net_device *dev, u16 vid) +{ +} + static inline bool br_port_flag_is_set(const struct net_device *dev, unsigned long flag) { diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c index e56ba3912a90..38b1d0dd0529 100644 --- a/net/bridge/br_fdb.c +++ b/net/bridge/br_fdb.c @@ -1164,3 +1164,23 @@ void br_fdb_offloaded_set(struct net_bridge *br, struct net_bridge_port *p, spin_unlock_bh(&br->hash_lock); } + +void br_fdb_clear_offload(const struct net_device *dev, u16 vid) +{ + struct net_bridge_fdb_entry *f; + struct net_bridge_port *p; + + ASSERT_RTNL(); + + p = br_port_get_rtnl(dev); + if (!p) + return; + + spin_lock_bh(&p->br->hash_lock); + hlist_for_each_entry(f, &p->br->fdb_list, fdb_node) { + if (f->dst == p && f->key.vlan_id == vid) + f->offloaded = 0; + } + spin_unlock_bh(&p->br->hash_lock); +} +EXPORT_SYMBOL_GPL(br_fdb_clear_offload);