[PATCH v2 2/2] Add master support to rtnl_neigh for AF_BRIDGE objects

roopa at cumulusnetworks.com roopa at cumulusnetworks.com
Wed Nov 14 14:33:51 EST 2012


From: roopa <roopa at cumulusnetworks.com>

AF_BRIDGE neigh objects can be uniquely identified by
the family, lladdr and bridge ifindex. This patch adds
bridge ifindex to AF_BRIDGE neigh objects.

Things will be ok even without this patch with just family and
lladdr if we assume that we will have unique lladdr's
accross bridges in a system.

Kernel does not send the bridge ifindex in the AF_BRIDGE
fdb/neigh message. This patch tries to get that info by a
link cache lookup and adds it to the bridge neigh object

Signed-off-by: Roopa Prabhu <roopa at cumulusnetworks.com>
Reviewed-by: Nolan Leake <nolan at cumulusnetworks.com>
Reviewed-by: Shrijeet Mukherjee <shm at cumulusnetworks.com>
Reviewed-by: Wilson Kok <wkok at cumulusnetworks.com>

---
 include/netlink-types.h |    1 +
 lib/route/neigh.c       |   24 ++++++++++++++++++++++--
 2 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/include/netlink-types.h b/include/netlink-types.h
index 01b4505..02ecf04 100644
--- a/include/netlink-types.h
+++ b/include/netlink-types.h
@@ -205,6 +205,7 @@ struct rtnl_neigh
 	struct rtnl_ncacheinfo n_cacheinfo;
 	uint32_t                n_state_mask;
 	uint32_t                n_flag_mask;
+	uint32_t		n_master;
 };
 
 
diff --git a/lib/route/neigh.c b/lib/route/neigh.c
index 8e1f422..4b5893a 100644
--- a/lib/route/neigh.c
+++ b/lib/route/neigh.c
@@ -167,6 +167,7 @@
 #define NEIGH_ATTR_FAMILY       0x40
 #define NEIGH_ATTR_TYPE         0x80
 #define NEIGH_ATTR_PROBES       0x100
+#define NEIGH_ATTR_MASTER       0x200
 
 static struct nl_cache_ops rtnl_neigh_ops;
 static struct nl_object_ops neigh_obj_ops;
@@ -229,7 +230,9 @@ static void neigh_keygen(struct nl_object *obj, uint32_t *hashkey,
 		return;
 	}
 	nkey->n_family = neigh->n_family;
-	if (neigh->n_family != AF_BRIDGE)
+	if (neigh->n_family == AF_BRIDGE)
+		nkey->n_ifindex = neigh->n_master;
+	else
 		nkey->n_ifindex = neigh->n_ifindex;
 	if (addr)
 		memcpy(nkey->n_addr,
@@ -262,6 +265,7 @@ static int neigh_compare(struct nl_object *_a, struct nl_object *_b,
 	diff |= NEIGH_DIFF(TYPE,	a->n_type != b->n_type);
 	diff |= NEIGH_DIFF(LLADDR,	nl_addr_cmp(a->n_lladdr, b->n_lladdr));
 	diff |= NEIGH_DIFF(DST,		nl_addr_cmp(a->n_dst, b->n_dst));
+	diff |= NEIGH_DIFF(MASTER,	a->n_master != b->n_master);
 
 	if (flags & LOOSE_COMPARISON) {
 		diff |= NEIGH_DIFF(STATE,
@@ -301,7 +305,7 @@ static uint32_t neigh_id_attrs_get(struct nl_object *obj)
 	struct rtnl_neigh *neigh = (struct rtnl_neigh *)obj;
 
 	if (neigh->n_family == AF_BRIDGE)
-		return (NEIGH_ATTR_LLADDR | NEIGH_ATTR_FAMILY);
+		return (NEIGH_ATTR_LLADDR | NEIGH_ATTR_FAMILY | NEIGH_ATTR_MASTER);
 	else
 		return (NEIGH_ATTR_IFINDEX | NEIGH_ATTR_DST | NEIGH_ATTR_FAMILY);
 }
@@ -393,6 +397,22 @@ int rtnl_neigh_parse(struct nlmsghdr *n, struct rtnl_neigh **result)
 		neigh->ce_mask |= NEIGH_ATTR_PROBES;
 	}
 
+	/*
+	 * Get the bridge index for AF_BRIDGE family entries
+	 */
+	if (neigh->n_family == AF_BRIDGE) {
+		struct nl_cache *lcache = nl_cache_mngt_require("route/link");
+		if (lcache ) {
+			struct rtnl_link *link = rtnl_link_get(lcache,
+							neigh->n_ifindex);
+			if (link) {
+				neigh->n_master = link->l_master;
+				rtnl_link_put(link);
+				neigh->ce_mask |= NEIGH_ATTR_MASTER;
+			}
+		}
+	}
+
 	*result = neigh;
 	return 0;
 
-- 
1.7.2.5




More information about the libnl mailing list