[PATCH 1/2] link cache: Add new link api to get link object by family

roopa at cumulusnetworks.com roopa at cumulusnetworks.com
Wed Dec 12 17:10:50 EST 2012


From: roopa <roopa at cumulusnetworks.com>

This patch adds two new api's to get a link object by family:

struct rtnl_link *rtnl_link_get_by_family(struct nl_cache *cache,
                                          int family, int ifindex)
struct rtnl_link *rtnl_link_get_by_family_and_name(struct nl_cache *cache,
                                                   int family,
                                                   const char *name)

This change comes with the recent addition of AF_BRIDGE support.
link cache can now contain objects of more than one family.
And the current link get api's only return objects of type AF_UNSPEC.
The above new apis will let users query a link object by family.

Signed-off-by: Roopa Prabhu <roopa at cumulusnetworks.com>
---
 doc/route.txt                |    4 ++-
 include/netlink/route/link.h |    3 ++
 lib/route/link.c             |   75 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 81 insertions(+), 1 deletions(-)

diff --git a/doc/route.txt b/doc/route.txt
index 61a84c4..baf2d21 100644
--- a/doc/route.txt
+++ b/doc/route.txt
@@ -198,7 +198,7 @@ and can be accessed using the standard cache functions. By setting the
 +family+ parameter to an address familly other than +AF_UNSPEC+, the resulting
 cache will only contain links supporting the specified address family.
 
-The following direct search functions are provided to search by interface
+The following direct search functions are provided to search by family, interface
 index and by link name:
 
 [source,c]
@@ -207,6 +207,8 @@ index and by link name:
 
 struct rtnl_link *rtnl_link_get(struct nl_cache *cache, int ifindex);
 struct rtnl_link *rtnl_link_get_by_name(struct nl_cache *cache, const char *name);
+struct rtnl_link *rtnl_link_get_by_family(struct nl_cache *cache, int family, int ifindex);
+struct rtnl_link *rtnl_link_get_by_family_and_name(struct nl_cache *cache, int family, const char *name);
 -----
 
 .Example: Link Cache
diff --git a/include/netlink/route/link.h b/include/netlink/route/link.h
index 8268b13..3d3b988 100644
--- a/include/netlink/route/link.h
+++ b/include/netlink/route/link.h
@@ -105,6 +105,9 @@ extern int	rtnl_link_alloc_cache(struct nl_sock *, int, struct nl_cache **);
 extern struct rtnl_link *rtnl_link_get(struct nl_cache *, int);
 extern struct rtnl_link *rtnl_link_get_by_name(struct nl_cache *, const char *);
 
+extern struct rtnl_link *rtnl_link_get_by_family(struct nl_cache *, int, int);
+extern struct rtnl_link *rtnl_link_get_by_family_and_name(struct nl_cache *,
+							  int, const char *);
 
 extern int	rtnl_link_build_add_request(struct rtnl_link *, int,
 					    struct nl_msg **);
diff --git a/lib/route/link.c b/lib/route/link.c
index 1cecd54..51cac0d 100644
--- a/lib/route/link.c
+++ b/lib/route/link.c
@@ -910,6 +910,8 @@ static char *link_attrs2str(int attrs, char *buf, size_t len)
  * @route_doc{link_list, Get List of Links}
  * @see rtnl_link_get()
  * @see rtnl_link_get_by_name()
+ * @see rtnl_link_get_by_family()
+ * @see rtnl_link_get_by_family_and_name()
  * @return 0 on success or a negative error code.
  */
 int rtnl_link_alloc_cache(struct nl_sock *sk, int family, struct nl_cache **result)
@@ -999,6 +1001,79 @@ struct rtnl_link *rtnl_link_get_by_name(struct nl_cache *cache,
 }
 
 /**
+ * Lookup link in cache by family and interface index
+ * @arg cache		Link cache
+ * @arg family		Family
+ * @arg ifindex 	Interface index
+ *
+ * Searches through the provided cache looking for a link with matching
+ * family and interface index.
+ *
+ * @attention The reference counter of the returned link object will be
+ *            incremented. Use rtnl_link_put() to release the reference.
+ *
+ * @route_doc{link_list, Get List of Links}
+ * @see rtnl_link_get_by_family_and_name()
+ * @return Link object or NULL if error or no match was found.
+ */
+struct rtnl_link *rtnl_link_get_by_family(struct nl_cache *cache,
+					  int family, int ifindex)
+{
+	struct rtnl_link *link, *link_needle;
+
+	if (cache->c_ops != &rtnl_link_ops)
+		return NULL;
+
+	if (!(link_needle = rtnl_link_alloc()))
+		return NULL;
+
+	rtnl_link_set_family(link_needle, family);
+	rtnl_link_set_ifindex(link_needle, ifindex);
+
+	link = nl_cache_search(cache, link_needle);
+
+	rtnl_link_put(link_needle);
+
+	return link;
+}
+
+/**
+ * Lookup link in cache by link family and name
+ * @arg cache		Link cache
+ * @arg family		Family
+ * @arg name		Name of link
+ *
+ * Searches through the provided cache looking for a link with matching
+ * family and link name
+ *
+ * @attention The reference counter of the returned link object will be
+ *            incremented. Use rtnl_link_put() to release the reference.
+ *
+ * @route_doc{link_list, Get List of Links}
+ * @see rtnl_link_get_by_family()
+ * @return Link object or NULL if no match was found.
+ */
+struct rtnl_link *rtnl_link_get_by_family_and_name(struct nl_cache *cache,
+						   int family,
+						   const char *name)
+{
+	struct rtnl_link *link;
+
+	if (cache->c_ops != &rtnl_link_ops)
+		return NULL;
+
+	nl_list_for_each_entry(link, &cache->c_items, ce_list) {
+		if (link->l_family == family &&
+			!strcmp(name, link->l_name)) {
+			nl_object_get((struct nl_object *) link);
+			return link;
+		}
+	}
+
+	return NULL;
+}
+
+/**
  * Construct RTM_GETLINK netlink message
  * @arg ifindex		Interface index
  * @arg name		Name of link
-- 
1.7.2.5




More information about the libnl mailing list