aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/vxlan.c20
1 files changed, 11 insertions, 9 deletions
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)
{