[PATCH] neigh: add function to look up neighbour (fdb) by ifindex, mac and vlan

Jonas Johansson jonasj76 at gmail.com
Mon May 16 23:28:04 PDT 2016


The rtnl_neigh_get() function can not be used to look up a fdb entry in the
neigh cache. This is due to that the function searches among destination
addresses (NDA_DST) and not among link layer addresses (NDA_LLADDR), which is
used by fdb entries. A fdb entry can also exist in several vlans, so a vlan id
parameter is also needed to find a unique entry.
This commit adds a function, rtnl_neigh_get_by_vlan() which searches the neigh
cache for a specific neighbour (fdb) entry by interface index, link layer
address and vlan id.

Signed-off-by: Jonas Johansson <jonas.johansson at westermo.se>
---
 include/netlink/route/neighbour.h |  2 ++
 lib/route/neigh.c                 | 26 ++++++++++++++++++++++++++
 libnl-route-3.sym                 |  1 +
 3 files changed, 29 insertions(+)

diff --git a/include/netlink/route/neighbour.h b/include/netlink/route/neighbour.h
index fb98113..6ea4753 100644
--- a/include/netlink/route/neighbour.h
+++ b/include/netlink/route/neighbour.h
@@ -31,6 +31,8 @@ extern int	rtnl_neigh_alloc_cache_flags(struct nl_sock *,
 					     unsigned int);
 extern struct rtnl_neigh *rtnl_neigh_get(struct nl_cache *, int,
 					       struct nl_addr *);
+extern struct rtnl_neigh *rtnl_neigh_get_by_vlan(struct nl_cache *, int,
+						 struct nl_addr *, int);
 
 extern int      rtnl_neigh_parse(struct nlmsghdr *, struct rtnl_neigh **);
 
diff --git a/lib/route/neigh.c b/lib/route/neigh.c
index 260e8b4..c8979ab 100644
--- a/lib/route/neigh.c
+++ b/lib/route/neigh.c
@@ -607,6 +607,32 @@ struct rtnl_neigh * rtnl_neigh_get(struct nl_cache *cache, int ifindex,
 	return NULL;
 }
 
+/**
+ * Look up a neighbour by interface index, link layer address and vlan id
+ * @arg cache		neighbour cache
+ * @arg ifindex 	interface index the neighbour is on
+ * @arg lladdr		link layer address of the neighbour
+ * @arg vlan		vlan id of the neighbour
+ *
+ * @return neighbour handle or NULL if no match was found.
+ */
+struct rtnl_neigh * rtnl_neigh_get_by_vlan(struct nl_cache *cache, int ifindex,
+					   struct nl_addr *lladdr, int vlan)
+{
+	struct rtnl_neigh *neigh;
+
+	nl_list_for_each_entry(neigh, &cache->c_items, ce_list) {
+		if (neigh->n_ifindex == ifindex &&
+		    neigh->n_vlan == vlan &&
+		    neigh->n_lladdr && !nl_addr_cmp(neigh->n_lladdr, lladdr)) {
+			nl_object_get((struct nl_object *) neigh);
+			return neigh;
+		}
+	}
+
+	return NULL;
+}
+
 /** @} */
 
 /**
diff --git a/libnl-route-3.sym b/libnl-route-3.sym
index 2c72498..ee1677b 100644
--- a/libnl-route-3.sym
+++ b/libnl-route-3.sym
@@ -917,5 +917,6 @@ global:
 	rtnl_link_vrf_get_tableid;
 	rtnl_link_vrf_set_tableid;
 	rtnl_neigh_alloc_cache_flags;
+	rtnl_neigh_ll_get;
 } libnl_3_2_27;
 
-- 
2.5.0




More information about the libnl mailing list