[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1372165316-17647-5-git-send-email-mike.rapoport@ravellosystems.com>
Date: Tue, 25 Jun 2013 16:01:54 +0300
From: Mike Rapoport <mike.rapoport@...ellosystems.com>
To: netdev@...r.kernel.org
Cc: Stephen Hemminger <stephen@...workplumber.org>,
David Stevens <dlstevens@...ibm.com>,
Thomas Graf <tgraf@...g.ch>,
Cong Wang <xiyou.wangcong@...il.com>,
Mike Rapoport <mike.rapoport@...ellosystems.com>
Subject: [PATCH net-next v5 4/6] vxlan: allow removal of single destination from fdb entry
When the last item is deleted from the remote destinations list, the
fdb entry is destroyed.
Signed-off-by: Mike Rapoport <mike.rapoport@...ellosystems.com>
---
drivers/net/vxlan.c | 44 ++++++++++++++++++++++++++++++++++++++++----
1 file changed, 40 insertions(+), 4 deletions(-)
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index ee7cc71..c182520 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -105,6 +105,7 @@ struct vxlan_rdst {
u32 remote_vni;
u32 remote_ifindex;
struct list_head list;
+ struct rcu_head rcu;
};
/* Forwarding table entry */
@@ -496,6 +497,12 @@ static int vxlan_fdb_create(struct vxlan_dev *vxlan,
return 0;
}
+static void vxlan_fdb_free_rdst(struct rcu_head *head)
+{
+ struct vxlan_rdst *rd = container_of(head, struct vxlan_rdst, rcu);
+ kfree(rd);
+}
+
static void vxlan_fdb_free(struct rcu_head *head)
{
struct vxlan_fdb *f = container_of(head, struct vxlan_fdb, rcu);
@@ -605,14 +612,43 @@ static int vxlan_fdb_delete(struct ndmsg *ndm, struct nlattr *tb[],
{
struct vxlan_dev *vxlan = netdev_priv(dev);
struct vxlan_fdb *f;
- int err = -ENOENT;
+ struct vxlan_rdst *rd = NULL;
+ __be32 ip;
+ __be16 port;
+ u32 vni, ifindex;
+ int err;
+
+ err = vxlan_fdb_parse(tb, vxlan, &ip, &port, &vni, &ifindex);
+ if (err)
+ return err;
+
+ err = -ENOENT;
spin_lock_bh(&vxlan->hash_lock);
f = vxlan_find_mac(vxlan, addr);
- if (f) {
- vxlan_fdb_destroy(vxlan, f);
- err = 0;
+ if (!f)
+ goto out;
+
+ if (ip != htonl(INADDR_ANY)) {
+ rd = vxlan_fdb_find_rdst(f, ip, port, vni, ifindex);
+ if (!rd)
+ goto out;
+ }
+
+ err = 0;
+
+ /* remove a destination if it's not the only one on the list,
+ * otherwise destroy the fdb entry
+ */
+ if (rd && !list_is_singular(&f->remotes)) {
+ list_del_rcu(&rd->list);
+ call_rcu(&rd->rcu, vxlan_fdb_free_rdst);
+ goto out;
}
+
+ vxlan_fdb_destroy(vxlan, f);
+
+out:
spin_unlock_bh(&vxlan->hash_lock);
return err;
--
1.8.1.5
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Powered by blists - more mailing lists