diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index ef45c3c925be..c0cd1c022e77 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c @@ -869,6 +869,14 @@ static void vxlan_fdb_destroy(struct vxlan_dev *vxlan, struct vxlan_fdb *f, call_rcu(&f->rcu, vxlan_fdb_free); } +static void vxlan_dst_free(struct rcu_head *head) +{ + struct vxlan_rdst *rd = container_of(head, struct vxlan_rdst, rcu); + + dst_cache_destroy(&rd->dst_cache); + kfree(rd); +} + static int vxlan_fdb_update_existing(struct vxlan_dev *vxlan, union vxlan_addr *ip, __u16 state, __u16 flags, @@ -941,8 +949,10 @@ static int vxlan_fdb_update_existing(struct vxlan_dev *vxlan, err_notify: if ((flags & NLM_F_REPLACE) && rc) *rd = oldrd; - else if ((flags & NLM_F_APPEND) && rc) + else if ((flags & NLM_F_APPEND) && rc) { list_del_rcu(&rd->list); + call_rcu(&rd->rcu, vxlan_dst_free); + } return err; } @@ -1013,14 +1023,6 @@ static int vxlan_fdb_update(struct vxlan_dev *vxlan, } } -static void vxlan_dst_free(struct rcu_head *head) -{ - struct vxlan_rdst *rd = container_of(head, struct vxlan_rdst, rcu); - - dst_cache_destroy(&rd->dst_cache); - kfree(rd); -} - static void vxlan_fdb_dst_destroy(struct vxlan_dev *vxlan, struct vxlan_fdb *f, struct vxlan_rdst *rd, bool swdev_notify) {