diff options
author | David S. Miller <davem@davemloft.net> | 2019-07-08 19:48:57 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-07-08 19:48:57 -0700 |
commit | af144a983402f7fd324ce556d9f9011a8b3e01fe (patch) | |
tree | 7a0250b960a36976bc683789d9fe86b9f60a97a5 /drivers/net/vxlan.c | |
parent | 6413139dfc641aaaa30580b59696a5f7ea274194 (diff) | |
parent | e858faf556d4e14c750ba1e8852783c6f9520a0e (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Two cases of overlapping changes, nothing fancy.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/vxlan.c')
-rw-r--r-- | drivers/net/vxlan.c | 37 |
1 files changed, 27 insertions, 10 deletions
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index 5e2323592e08..3d9bcc957f7d 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c @@ -812,6 +812,14 @@ static struct vxlan_fdb *vxlan_fdb_alloc(struct vxlan_dev *vxlan, return f; } +static void vxlan_fdb_insert(struct vxlan_dev *vxlan, const u8 *mac, + __be32 src_vni, struct vxlan_fdb *f) +{ + ++vxlan->addrcnt; + hlist_add_head_rcu(&f->hlist, + vxlan_fdb_head(vxlan, mac, src_vni)); +} + static int vxlan_fdb_create(struct vxlan_dev *vxlan, const u8 *mac, union vxlan_addr *ip, __u16 state, __be16 port, __be32 src_vni, @@ -837,18 +845,13 @@ static int vxlan_fdb_create(struct vxlan_dev *vxlan, return rc; } - ++vxlan->addrcnt; - hlist_add_head_rcu(&f->hlist, - vxlan_fdb_head(vxlan, mac, src_vni)); - *fdb = f; return 0; } -static void vxlan_fdb_free(struct rcu_head *head) +static void __vxlan_fdb_free(struct vxlan_fdb *f) { - struct vxlan_fdb *f = container_of(head, struct vxlan_fdb, rcu); struct vxlan_rdst *rd, *nd; list_for_each_entry_safe(rd, nd, &f->remotes, list) { @@ -858,6 +861,13 @@ static void vxlan_fdb_free(struct rcu_head *head) kfree(f); } +static void vxlan_fdb_free(struct rcu_head *head) +{ + struct vxlan_fdb *f = container_of(head, struct vxlan_fdb, rcu); + + __vxlan_fdb_free(f); +} + static void vxlan_fdb_destroy(struct vxlan_dev *vxlan, struct vxlan_fdb *f, bool do_notify, bool swdev_notify) { @@ -985,6 +995,7 @@ static int vxlan_fdb_update_create(struct vxlan_dev *vxlan, if (rc < 0) return rc; + vxlan_fdb_insert(vxlan, mac, src_vni, f); rc = vxlan_fdb_notify(vxlan, f, first_remote_rtnl(f), RTM_NEWNEIGH, swdev_notify, extack); if (rc) @@ -3588,12 +3599,17 @@ static int __vxlan_dev_create(struct net *net, struct net_device *dev, if (err) goto errout; - /* notify default fdb entry */ if (f) { + vxlan_fdb_insert(vxlan, all_zeros_mac, + vxlan->default_dst.remote_vni, f); + + /* notify default fdb entry */ err = vxlan_fdb_notify(vxlan, f, first_remote_rtnl(f), RTM_NEWNEIGH, true, extack); - if (err) - goto errout; + if (err) { + vxlan_fdb_destroy(vxlan, f, false, false); + goto unregister; + } } list_add(&vxlan->next, &vn->vxlan_list); @@ -3605,7 +3621,8 @@ errout: * destroy the entry by hand here. */ if (f) - vxlan_fdb_destroy(vxlan, f, false, false); + __vxlan_fdb_free(f); +unregister: if (unregister) unregister_netdevice(dev); return err; |