|
|
@@ -740,6 +740,22 @@ 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 void vxlan_fdb_dst_destroy(struct vxlan_dev *vxlan, struct vxlan_fdb *f,
|
|
|
+ struct vxlan_rdst *rd)
|
|
|
+{
|
|
|
+ list_del_rcu(&rd->list);
|
|
|
+ vxlan_fdb_notify(vxlan, f, rd, RTM_DELNEIGH);
|
|
|
+ call_rcu(&rd->rcu, vxlan_dst_free);
|
|
|
+}
|
|
|
+
|
|
|
static int vxlan_fdb_parse(struct nlattr *tb[], struct vxlan_dev *vxlan,
|
|
|
union vxlan_addr *ip, __be16 *port, __be32 *src_vni,
|
|
|
__be32 *vni, u32 *ifindex)
|
|
|
@@ -864,9 +880,7 @@ static int __vxlan_fdb_delete(struct vxlan_dev *vxlan,
|
|
|
* otherwise destroy the fdb entry
|
|
|
*/
|
|
|
if (rd && !list_is_singular(&f->remotes)) {
|
|
|
- list_del_rcu(&rd->list);
|
|
|
- vxlan_fdb_notify(vxlan, f, rd, RTM_DELNEIGH);
|
|
|
- kfree_rcu(rd, rcu);
|
|
|
+ vxlan_fdb_dst_destroy(vxlan, f, rd);
|
|
|
goto out;
|
|
|
}
|
|
|
|