[RFC PATCH 3/4] Add master ifindex to rtnl_neigh for AF_BRIDGE objects

roopa at cumulusnetworks.com roopa at cumulusnetworks.com
Mon Nov 5 08:39:38 EST 2012


From: roopa <roopa at cumulusnetworks.com>

A bridge fdb/neigh object belongs to a bridge.
If we assume unique lladdrs accross all bridges in a system,
bridge fdb objects can be identified using only lladdr
and family as done in the previous patch in this series.

This patch adds bridge ifindex to bridge neigh object id
attributes to identify bridge objects based on lladdr,
family and bridge ifindex.

The kernel does not send bridge ifindex in the AF_BRIDGE
fdb/neigh message. The bridge port ifindex is present in the msg.
This patch uses the bridge port ifindex to get bridge ifindex from
the link cache (This part of the code may change depending on
the bridge link cache implementation in libnl)

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       |   20 +++++++++++++++++++-
 2 files changed, 20 insertions(+), 1 deletions(-)

diff --git a/include/netlink-types.h b/include/netlink-types.h
index 23930b8..361cb79 100644
--- a/include/netlink-types.h
+++ b/include/netlink-types.h
@@ -202,6 +202,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 dec71d5..0cb5891 100644
--- a/lib/route/neigh.c
+++ b/lib/route/neigh.c
@@ -165,6 +165,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;
@@ -211,6 +212,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,
@@ -250,7 +252,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);
 }
@@ -269,6 +271,22 @@ static int neigh_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
 	if ((err = rtnl_neigh_parse(n, &neigh)) < 0)
 		return err;
 
+	/*
+	 * 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;
+			}
+		}
+	}
+
 	err = pp->pp_cb((struct nl_object *) neigh, pp);
 
 	rtnl_neigh_put(neigh);
-- 
1.7.2.5




More information about the libnl mailing list