Commit 193025e8 authored by David S. Miller's avatar David S. Miller

Merge branch 'vxlan-fdb-nexthop-misc-fixes'

Roopa Prabhu says:

====================
vxlan fdb nexthop misc fixes

Roopa Prabhu (2):
  vxlan: add check to prevent use of remote ip attributes with NDA_NH_ID
  vxlan: few locking fixes in nexthop event handler
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents d9f0d660 79472fe8
...@@ -81,7 +81,7 @@ struct vxlan_fdb { ...@@ -81,7 +81,7 @@ struct vxlan_fdb {
u16 flags; /* see ndm_flags and below */ u16 flags; /* see ndm_flags and below */
struct list_head nh_list; struct list_head nh_list;
struct nexthop __rcu *nh; struct nexthop __rcu *nh;
struct vxlan_dev *vdev; struct vxlan_dev __rcu *vdev;
}; };
#define NTF_VXLAN_ADDED_BY_USER 0x100 #define NTF_VXLAN_ADDED_BY_USER 0x100
...@@ -837,7 +837,7 @@ static struct vxlan_fdb *vxlan_fdb_alloc(struct vxlan_dev *vxlan, const u8 *mac, ...@@ -837,7 +837,7 @@ static struct vxlan_fdb *vxlan_fdb_alloc(struct vxlan_dev *vxlan, const u8 *mac,
f->updated = f->used = jiffies; f->updated = f->used = jiffies;
f->vni = src_vni; f->vni = src_vni;
f->nh = NULL; f->nh = NULL;
f->vdev = vxlan; RCU_INIT_POINTER(f->vdev, vxlan);
INIT_LIST_HEAD(&f->nh_list); INIT_LIST_HEAD(&f->nh_list);
INIT_LIST_HEAD(&f->remotes); INIT_LIST_HEAD(&f->remotes);
memcpy(f->eth_addr, mac, ETH_ALEN); memcpy(f->eth_addr, mac, ETH_ALEN);
...@@ -963,7 +963,7 @@ static void __vxlan_fdb_free(struct vxlan_fdb *f) ...@@ -963,7 +963,7 @@ static void __vxlan_fdb_free(struct vxlan_fdb *f)
nh = rcu_dereference_raw(f->nh); nh = rcu_dereference_raw(f->nh);
if (nh) { if (nh) {
rcu_assign_pointer(f->nh, NULL); rcu_assign_pointer(f->nh, NULL);
list_del_rcu(&f->nh_list); rcu_assign_pointer(f->vdev, NULL);
nexthop_put(nh); nexthop_put(nh);
} }
...@@ -1000,7 +1000,7 @@ static void vxlan_fdb_destroy(struct vxlan_dev *vxlan, struct vxlan_fdb *f, ...@@ -1000,7 +1000,7 @@ static void vxlan_fdb_destroy(struct vxlan_dev *vxlan, struct vxlan_fdb *f,
} }
hlist_del_rcu(&f->hlist); hlist_del_rcu(&f->hlist);
f->vdev = NULL; list_del_rcu(&f->nh_list);
call_rcu(&f->rcu, vxlan_fdb_free); call_rcu(&f->rcu, vxlan_fdb_free);
} }
...@@ -1196,6 +1196,10 @@ static int vxlan_fdb_parse(struct nlattr *tb[], struct vxlan_dev *vxlan, ...@@ -1196,6 +1196,10 @@ static int vxlan_fdb_parse(struct nlattr *tb[], struct vxlan_dev *vxlan,
struct net *net = dev_net(vxlan->dev); struct net *net = dev_net(vxlan->dev);
int err; int err;
if (tb[NDA_NH_ID] && (tb[NDA_DST] || tb[NDA_VNI] || tb[NDA_IFINDEX] ||
tb[NDA_PORT]))
return -EINVAL;
if (tb[NDA_DST]) { if (tb[NDA_DST]) {
err = vxlan_nla_get_addr(ip, tb[NDA_DST]); err = vxlan_nla_get_addr(ip, tb[NDA_DST]);
if (err) if (err)
...@@ -4611,17 +4615,35 @@ static struct notifier_block vxlan_switchdev_notifier_block __read_mostly = { ...@@ -4611,17 +4615,35 @@ static struct notifier_block vxlan_switchdev_notifier_block __read_mostly = {
.notifier_call = vxlan_switchdev_event, .notifier_call = vxlan_switchdev_event,
}; };
static void vxlan_fdb_nh_flush(struct nexthop *nh)
{
struct vxlan_fdb *fdb;
struct vxlan_dev *vxlan;
u32 hash_index;
rcu_read_lock();
list_for_each_entry_rcu(fdb, &nh->fdb_list, nh_list) {
vxlan = rcu_dereference(fdb->vdev);
WARN_ON(!vxlan);
hash_index = fdb_head_index(vxlan, fdb->eth_addr,
vxlan->default_dst.remote_vni);
spin_lock_bh(&vxlan->hash_lock[hash_index]);
if (!hlist_unhashed(&fdb->hlist))
vxlan_fdb_destroy(vxlan, fdb, false, false);
spin_unlock_bh(&vxlan->hash_lock[hash_index]);
}
rcu_read_unlock();
}
static int vxlan_nexthop_event(struct notifier_block *nb, static int vxlan_nexthop_event(struct notifier_block *nb,
unsigned long event, void *ptr) unsigned long event, void *ptr)
{ {
struct nexthop *nh = ptr; struct nexthop *nh = ptr;
struct vxlan_fdb *fdb, *tmp;
if (!nh || event != NEXTHOP_EVENT_DEL) if (!nh || event != NEXTHOP_EVENT_DEL)
return NOTIFY_DONE; return NOTIFY_DONE;
list_for_each_entry_safe(fdb, tmp, &nh->fdb_list, nh_list) vxlan_fdb_nh_flush(nh);
vxlan_fdb_destroy(fdb->vdev, fdb, false, false);
return NOTIFY_DONE; return NOTIFY_DONE;
} }
......
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