[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