[RFC PATCH 4/4] Add a new cache fill API that does a kernel get on each supported family.
roopa at cumulusnetworks.com
roopa at cumulusnetworks.com
Mon Nov 5 08:39:39 EST 2012
From: roopa <roopa at cumulusnetworks.com>
The current cache fill API does a get on AF_UNSPEC family.
And a kernel get on AF_UNSPEC family for neigh does not return AF_BRIDGE
objects.
To get objects from all families supported by a cache, this patch adds a
new kind of cache fill api for use during resync and cache creation times.
This new refill api, does a refill for each supported family one at a time.
I have also proposed this change in the context of adding AF_BRIDGE
support to link cache.
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 +++++++++++++++++++++++++++++++++++++++-------
2 files changed, 57 insertions(+), 10 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;
}
--
1.7.2.5
More information about the libnl
mailing list