Commit 4f89f5b5 authored by Petr Machata's avatar Petr Machata Committed by David S. Miller

vxlan: Add vxlan_fdb_replay()

When a VXLAN device becomes relevant to a driver (such as when it is
attached to an offloaded bridge), the driver will generally need to walk
the existing FDB entries and offload them.

Add a function vxlan_fdb_replay() to call a given notifier block for
each FDB entry with a given VNI.
Signed-off-by: default avatarPetr Machata <petrm@mellanox.com>
Signed-off-by: default avatarIdo Schimmel <idosch@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent ff23b91c
...@@ -552,6 +552,53 @@ int vxlan_fdb_find_uc(struct net_device *dev, const u8 *mac, __be32 vni, ...@@ -552,6 +552,53 @@ int vxlan_fdb_find_uc(struct net_device *dev, const u8 *mac, __be32 vni,
} }
EXPORT_SYMBOL_GPL(vxlan_fdb_find_uc); EXPORT_SYMBOL_GPL(vxlan_fdb_find_uc);
static int vxlan_fdb_notify_one(struct notifier_block *nb,
const struct vxlan_dev *vxlan,
const struct vxlan_fdb *f,
const struct vxlan_rdst *rdst)
{
struct switchdev_notifier_vxlan_fdb_info fdb_info;
int rc;
vxlan_fdb_switchdev_notifier_info(vxlan, f, rdst, &fdb_info);
rc = nb->notifier_call(nb, SWITCHDEV_VXLAN_FDB_ADD_TO_DEVICE,
&fdb_info);
return notifier_to_errno(rc);
}
int vxlan_fdb_replay(const struct net_device *dev, __be32 vni,
struct notifier_block *nb)
{
struct vxlan_dev *vxlan;
struct vxlan_rdst *rdst;
struct vxlan_fdb *f;
unsigned int h;
int rc = 0;
if (!netif_is_vxlan(dev))
return -EINVAL;
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) {
rc = vxlan_fdb_notify_one(nb, vxlan,
f, rdst);
if (rc)
goto out;
}
}
}
}
out:
spin_unlock_bh(&vxlan->hash_lock);
return rc;
}
EXPORT_SYMBOL_GPL(vxlan_fdb_replay);
/* Replace destination of unicast mac */ /* Replace destination of unicast mac */
static int vxlan_fdb_replace(struct vxlan_fdb *f, static int vxlan_fdb_replace(struct vxlan_fdb *f,
union vxlan_addr *ip, __be16 port, __be32 vni, union vxlan_addr *ip, __be16 port, __be32 vni,
......
...@@ -427,6 +427,9 @@ struct switchdev_notifier_vxlan_fdb_info { ...@@ -427,6 +427,9 @@ struct switchdev_notifier_vxlan_fdb_info {
#if IS_ENABLED(CONFIG_VXLAN) #if IS_ENABLED(CONFIG_VXLAN)
int vxlan_fdb_find_uc(struct net_device *dev, const u8 *mac, __be32 vni, int vxlan_fdb_find_uc(struct net_device *dev, const u8 *mac, __be32 vni,
struct switchdev_notifier_vxlan_fdb_info *fdb_info); struct switchdev_notifier_vxlan_fdb_info *fdb_info);
int vxlan_fdb_replay(const struct net_device *dev, __be32 vni,
struct notifier_block *nb);
#else #else
static inline int static inline int
vxlan_fdb_find_uc(struct net_device *dev, const u8 *mac, __be32 vni, vxlan_fdb_find_uc(struct net_device *dev, const u8 *mac, __be32 vni,
...@@ -434,6 +437,12 @@ vxlan_fdb_find_uc(struct net_device *dev, const u8 *mac, __be32 vni, ...@@ -434,6 +437,12 @@ vxlan_fdb_find_uc(struct net_device *dev, const u8 *mac, __be32 vni,
{ {
return -ENOENT; return -ENOENT;
} }
static inline int vxlan_fdb_replay(const struct net_device *dev, __be32 vni,
struct notifier_block *nb)
{
return -EOPNOTSUPP;
}
#endif #endif
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment