vxlan: Add vxlan_fdb_clear_offload()
authorPetr Machata <petrm@mellanox.com>
Fri, 7 Dec 2018 19:55:06 +0000 (19:55 +0000)
committerDavid S. Miller <davem@davemloft.net>
Fri, 7 Dec 2018 20:59:08 +0000 (12:59 -0800)
When a driver unoffloads all FDB entries en bloc, it's inefficient to
send the switchdev notification one by one. Add a helper that walks the
FDB table, unsetting the offload flag on RDST with a given VNI.

Signed-off-by: Petr Machata <petrm@mellanox.com>
Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/vxlan.c
include/net/vxlan.h

index d9cb0d903283f9976c38f719d9cdc0c7915c2a45..b56ef684ecacb466f12e196976179900d537b2a5 100644 (file)
@@ -599,6 +599,28 @@ out:
 }
 EXPORT_SYMBOL_GPL(vxlan_fdb_replay);
 
+void vxlan_fdb_clear_offload(const struct net_device *dev, __be32 vni)
+{
+       struct vxlan_dev *vxlan;
+       struct vxlan_rdst *rdst;
+       struct vxlan_fdb *f;
+       unsigned int h;
+
+       if (!netif_is_vxlan(dev))
+               return;
+       vxlan = netdev_priv(dev);
+
+       spin_lock_bh(&vxlan->hash_lock);
+       for (h = 0; h < FDB_HASH_SIZE; ++h) {
+               hlist_for_each_entry(f, &vxlan->fdb_head[h], hlist)
+                       if (f->vni == vni)
+                               list_for_each_entry(rdst, &f->remotes, list)
+                                       rdst->offloaded = false;
+       }
+       spin_unlock_bh(&vxlan->hash_lock);
+}
+EXPORT_SYMBOL_GPL(vxlan_fdb_clear_offload);
+
 /* Replace destination of unicast mac */
 static int vxlan_fdb_replace(struct vxlan_fdb *f,
                             union vxlan_addr *ip, __be16 port, __be32 vni,
index f49aa9afe598fe995f0bbaee77b45d76ae57febe..236403eb5ba6079b4f8b4d7865355056f3fe412a 100644 (file)
@@ -429,6 +429,7 @@ int vxlan_fdb_find_uc(struct net_device *dev, const u8 *mac, __be32 vni,
                      struct switchdev_notifier_vxlan_fdb_info *fdb_info);
 int vxlan_fdb_replay(const struct net_device *dev, __be32 vni,
                     struct notifier_block *nb);
+void vxlan_fdb_clear_offload(const struct net_device *dev, __be32 vni);
 
 #else
 static inline int
@@ -443,6 +444,11 @@ static inline int vxlan_fdb_replay(const struct net_device *dev, __be32 vni,
 {
        return -EOPNOTSUPP;
 }
+
+static inline void
+vxlan_fdb_clear_offload(const struct net_device *dev, __be32 vni)
+{
+}
 #endif
 
 #endif