[RFC PATCH 1/5] Add support for AF_BRIDGE family in link cache

roopa at cumulusnetworks.com roopa at cumulusnetworks.com
Mon Nov 5 08:37:34 EST 2012


From: roopa <roopa at cumulusnetworks.com>

This patch adds support for AF_BRIDGE family in link cache
and adds link family attribute to link object oo_id_attrs.
With this the key for link object lookups will be ifindex and family.

This allows for base rtnl link objects to co-exist with the AF_BRIDGE
link objects in the same cache.

Note that this patch also adds a new kind of cache fill api for use during
resync and cache creation times. This is needed because the current AF_UNSPEC
based link cache fill only gets AF_UNSPEC interface objects from the kernel.
And not the AF_BRIDGE objects. This is true only for link cache. Its a kernel
behaviour. For all other families and msgtypes a AF_UNSPEC get from the kernel
gets you all objects belonging to all families that support the msgtype.

So this new refill api, does a refill for each supported family one at a time.
Again, this is needed only for the link cache fill, but there was no cleaner way to
only change it for the link cache. This should not harm any other caches.
For all other caches, libnl will loop through the families, whereas previously the
kernel would.

Note: I am considering the option of fixing the kernel link cache AF_UNSPEC get
at some point if possible. Also the link cache get api's today only look for
ifindex match and not family. These will need to be fixed or new api's introduced.
I can submit patches to fix this if we choose to take this path.

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/cache.h |    2 +
 lib/cache.c             |   65 +++++++++++++++++++++++++++++++++++++++-------
 lib/cache_mngr.c        |    2 +-
 lib/route/link.c        |   17 +-----------
 4 files changed, 60 insertions(+), 26 deletions(-)

diff --git a/include/netlink/cache.h b/include/netlink/cache.h
index fd137e1..7acfa40 100644
--- a/include/netlink/cache.h
+++ b/include/netlink/cache.h
@@ -54,6 +54,8 @@ extern int			nl_cache_parse_and_add(struct nl_cache *,
 extern void			nl_cache_remove(struct nl_object *);
 extern int			nl_cache_refill(struct nl_sock *,
 						struct nl_cache *);
+extern int			nl_cache_refill_assoc_families(struct nl_sock *,
+							       struct nl_cache *);
 extern int			nl_cache_pickup(struct nl_sock *,
 						struct nl_cache *);
 extern int			nl_cache_resync(struct nl_sock *,
diff --git a/lib/cache.c b/lib/cache.c
index 45a1a27..9abed0c 100644
--- a/lib/cache.c
+++ b/lib/cache.c
@@ -698,6 +698,7 @@ int nl_cache_resync(struct nl_sock *sk, struct nl_cache *cache,
 		    change_func_t change_cb, void *data)
 {
 	struct nl_object *obj, *next;
+	struct nl_af_group *grp;
 	struct nl_cache_assoc ca = {
 		.ca_cache = cache,
 		.ca_change = change_cb,
@@ -711,19 +712,22 @@ int nl_cache_resync(struct nl_sock *sk, struct nl_cache *cache,
 
 	NL_DBG(1, "Resyncing cache %p <%s>...\n", cache, nl_cache_name(cache));
 
-restart:
 	/* Mark all objects so we can see if some of them are obsolete */
 	nl_cache_mark_all(cache);
 
-	err = nl_cache_request_full_dump(sk, cache);
-	if (err < 0)
-		goto errout;
-
-	err = __cache_pickup(sk, cache, &p);
-	if (err == -NLE_DUMP_INTR)
-		goto restart;
-	else if (err < 0)
-		goto errout;
+        for (grp = cache->c_ops->co_groups; grp->ag_group; grp++) {
+		nl_cache_set_arg1(cache, grp->ag_family);
+restart:
+		err = nl_cache_request_full_dump(sk, cache);
+		if (err < 0)
+			goto errout;
+
+		err = __cache_pickup(sk, cache, &p);
+		if (err == -NLE_DUMP_INTR)
+			goto restart;
+		else if (err < 0)
+			goto errout;
+	}
 
 	nl_list_for_each_entry_safe(obj, next, &cache->c_items, ce_list) {
 		if (nl_object_is_marked(obj)) {
@@ -821,6 +825,47 @@ restart:
 		fprintf(stderr, "dump interrupted, restarting!\n");
 		goto restart;
 	}
+
+	return err;
+}
+
+/**
+ * (Re)fill a cache with the contents in the kernel for all
+ * families the cache is associated with
+ * @arg sk		Netlink socket.
+ * @arg cache		cache to update
+ *
+ * Clears the specified cache and fills it with the current state in
+ * the kernel.
+ *
+ * @return 0 or a negative error code.
+ */
+int nl_cache_refill_assoc_families(struct nl_sock *sk, struct nl_cache *cache)
+{
+	int err = 0;
+	struct nl_af_group *grp;
+
+	nl_cache_clear(cache);
+
+	for (grp = cache->c_ops->co_groups; grp->ag_group; grp++) {
+		nl_cache_set_arg1(cache, grp->ag_family);
+
+restart:
+		err = nl_cache_request_full_dump(sk, cache);
+		if (err < 0)
+			return err;
+
+		NL_DBG(2, "Upading cache %p <%s>, request sent, waiting for dump...\n",
+		       cache, nl_cache_name(cache));
+
+		err = nl_cache_pickup(sk, cache);
+		if (err == -NLE_DUMP_INTR) {
+			fprintf(stderr, "dump interrupted, restarting!\n");
+			goto restart;
+		}
+		else if (err < 0)
+			break;
+	}
 	
 	return err;
 }
diff --git a/lib/cache_mngr.c b/lib/cache_mngr.c
index cdf2b7b..6b5a1cf 100644
--- a/lib/cache_mngr.c
+++ b/lib/cache_mngr.c
@@ -264,7 +264,7 @@ retry:
 			goto errout_free_cache;
 	}
 
-	err = nl_cache_refill(mngr->cm_sock, cache);
+	err = nl_cache_refill_assoc_families(mngr->cm_sock, cache);
 	if (err < 0)
 		goto errout_drop_membership;
 
diff --git a/lib/route/link.c b/lib/route/link.c
index 3f9d9dc..b71291b 100644
--- a/lib/route/link.c
+++ b/lib/route/link.c
@@ -570,19 +570,6 @@ errout:
 	return err;
 }
 
-static int link_event_filter(struct nl_cache *cache, struct nl_object *obj)
-{
-	struct rtnl_link *link = (struct rtnl_link *) obj;
-
-	/*
-	 * Ignore bridging messages when keeping the cache manager up to date.
-	 */
-	if (link->l_family == AF_BRIDGE)
-		return NL_SKIP;
-
-	return NL_OK;
-}
-
 static int link_request_update(struct nl_cache *cache, struct nl_sock *sk)
 {
 	int family = cache->c_iarg1;
@@ -2501,11 +2488,12 @@ static struct nl_object_ops link_obj_ops = {
 	},
 	.oo_compare		= link_compare,
 	.oo_attrs2str		= link_attrs2str,
-	.oo_id_attrs		= LINK_ATTR_IFINDEX,
+	.oo_id_attrs		= LINK_ATTR_IFINDEX | LINK_ATTR_FAMILY,
 };
 
 static struct nl_af_group link_groups[] = {
 	{ AF_UNSPEC,	RTNLGRP_LINK },
+	{ AF_BRIDGE,	RTNLGRP_LINK },
 	{ END_OF_GROUP_LIST },
 };
 
@@ -2523,7 +2511,6 @@ static struct nl_cache_ops rtnl_link_ops = {
 	.co_groups		= link_groups,
 	.co_request_update	= link_request_update,
 	.co_msg_parser		= link_msg_parser,
-	.co_event_filter	= link_event_filter,
 	.co_obj_ops		= &link_obj_ops,
 };
 
-- 
1.7.2.5




More information about the libnl mailing list