mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-15 09:34:17 +00:00
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: Petr Machata <petrm@mellanox.com> Signed-off-by: Ido Schimmel <idosch@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
ff23b91ce1
commit
4f89f5b535
@ -552,6 +552,53 @@ out:
|
||||
}
|
||||
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 */
|
||||
static int vxlan_fdb_replace(struct vxlan_fdb *f,
|
||||
union vxlan_addr *ip, __be16 port, __be32 vni,
|
||||
|
@ -427,6 +427,9 @@ struct switchdev_notifier_vxlan_fdb_info {
|
||||
#if IS_ENABLED(CONFIG_VXLAN)
|
||||
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);
|
||||
|
||||
#else
|
||||
static inline int
|
||||
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;
|
||||
}
|
||||
|
||||
static inline int vxlan_fdb_replay(const struct net_device *dev, __be32 vni,
|
||||
struct notifier_block *nb)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user