summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Ahern <dsa@cumulusnetworks.com>2015-10-27 22:40:48 (GMT)
committerThomas Haller <thaller@redhat.com>2015-11-19 15:48:21 (GMT)
commit18d60cb9d72f61f2070f3758bcd347bb2e3747c1 (patch)
tree56b5794a49531dc4ebaa6d1511196ba8e3b8a95d
parent7ea15f60a726de67f02e6868a8125a59570e956d (diff)
downloadlibnl-18d60cb9d72f61f2070f3758bcd347bb2e3747c1.zip
libnl-18d60cb9d72f61f2070f3758bcd347bb2e3747c1.tar.gz
libnl-18d60cb9d72f61f2070f3758bcd347bb2e3747c1.tar.bz2
link/neigh: add flags option to link and neighbor caches
Both link and neighbor cache support specify multiple groups (nl_af_group), but the alloc_cache functions for both do not set the NL_CACHE_AF_ITER flag before populating the cache so only the first group is used by default. This patch adds an API to pass in flags to make that happen and updates the nl-neigh-list command to make use of it. http://lists.infradead.org/pipermail/libnl/2015-October/001996.html Signed-off-by: David Ahern <dsa@cumulusnetworks.com> Signed-off-by: Thomas Haller <thaller@redhat.com>
-rw-r--r--include/netlink/cli/link.h4
-rw-r--r--include/netlink/cli/neigh.h3
-rw-r--r--include/netlink/cli/utils.h4
-rw-r--r--include/netlink/route/link.h3
-rw-r--r--include/netlink/route/neighbour.h3
-rw-r--r--lib/route/link.c39
-rw-r--r--lib/route/neigh.c32
-rw-r--r--libnl-cli-3.sym7
-rw-r--r--libnl-route-3.sym2
-rw-r--r--src/lib/link.c17
-rw-r--r--src/lib/utils.c17
-rw-r--r--src/nl-neigh-list.c2
12 files changed, 127 insertions, 6 deletions
diff --git a/include/netlink/cli/link.h b/include/netlink/cli/link.h
index 3f37948..f2c720b 100644
--- a/include/netlink/cli/link.h
+++ b/include/netlink/cli/link.h
@@ -17,7 +17,11 @@
extern struct rtnl_link *nl_cli_link_alloc(void);
extern struct nl_cache *nl_cli_link_alloc_cache_family(struct nl_sock *, int);
+extern struct nl_cache *nl_cli_link_alloc_cache_family_flags(struct nl_sock *, int,
+ unsigned int);
extern struct nl_cache *nl_cli_link_alloc_cache(struct nl_sock *);
+extern struct nl_cache *nl_cli_link_alloc_cache_flags(struct nl_sock *,
+ unsigned int);
extern void nl_cli_link_parse_family(struct rtnl_link *, char *);
extern void nl_cli_link_parse_name(struct rtnl_link *, char *);
diff --git a/include/netlink/cli/neigh.h b/include/netlink/cli/neigh.h
index 5440012..1c1be91 100644
--- a/include/netlink/cli/neigh.h
+++ b/include/netlink/cli/neigh.h
@@ -15,7 +15,8 @@
#include <netlink/route/neighbour.h>
#define nl_cli_neigh_alloc_cache(sk) \
- nl_cli_alloc_cache((sk), "neighbour", rtnl_neigh_alloc_cache)
+ nl_cli_alloc_cache_flags((sk), "neighbour", NL_CACHE_AF_ITER, \
+ rtnl_neigh_alloc_cache_flags)
extern struct rtnl_neigh *nl_cli_neigh_alloc(void);
extern void nl_cli_neigh_parse_dst(struct rtnl_neigh *, char *);
diff --git a/include/netlink/cli/utils.h b/include/netlink/cli/utils.h
index da41c10..ea89fc6 100644
--- a/include/netlink/cli/utils.h
+++ b/include/netlink/cli/utils.h
@@ -73,6 +73,10 @@ extern int nl_cli_confirm(struct nl_object *,
extern struct nl_cache *nl_cli_alloc_cache(struct nl_sock *, const char *,
int (*ac)(struct nl_sock *, struct nl_cache **));
+extern struct nl_cache *nl_cli_alloc_cache_flags(struct nl_sock *, const char *,
+ unsigned int flags,
+ int (*ac)(struct nl_sock *, struct nl_cache **, unsigned int));
+
extern void nl_cli_load_module(const char *, const char *);
#ifdef __cplusplus
diff --git a/include/netlink/route/link.h b/include/netlink/route/link.h
index f7303f2..23b0183 100644
--- a/include/netlink/route/link.h
+++ b/include/netlink/route/link.h
@@ -109,6 +109,9 @@ extern struct rtnl_link *rtnl_link_alloc(void);
extern void rtnl_link_put(struct rtnl_link *);
extern int rtnl_link_alloc_cache(struct nl_sock *, int, struct nl_cache **);
+extern int rtnl_link_alloc_cache_flags(struct nl_sock *, int,
+ struct nl_cache **,
+ unsigned int flags);
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 *);
diff --git a/include/netlink/route/neighbour.h b/include/netlink/route/neighbour.h
index b653cff..fb98113 100644
--- a/include/netlink/route/neighbour.h
+++ b/include/netlink/route/neighbour.h
@@ -26,6 +26,9 @@ extern struct rtnl_neigh *rtnl_neigh_alloc(void);
extern void rtnl_neigh_put(struct rtnl_neigh *);
extern int rtnl_neigh_alloc_cache(struct nl_sock *, struct nl_cache **);
+extern int rtnl_neigh_alloc_cache_flags(struct nl_sock *,
+ struct nl_cache **,
+ unsigned int);
extern struct rtnl_neigh *rtnl_neigh_get(struct nl_cache *, int,
struct nl_addr *);
diff --git a/lib/route/link.c b/lib/route/link.c
index 5c32550..6dc416b 100644
--- a/lib/route/link.c
+++ b/lib/route/link.c
@@ -1008,6 +1008,7 @@ static char *link_attrs2str(int attrs, char *buf, size_t len)
* @arg sk Netlink socket.
* @arg family Link address family or AF_UNSPEC
* @arg result Pointer to store resulting cache.
+ * @arg flags Flags to set in link cache before filling
*
* Allocates and initializes a new link cache. If \c sk is valid, a netlink
* message is sent to the kernel requesting a full dump of all configured
@@ -1027,7 +1028,8 @@ static char *link_attrs2str(int attrs, char *buf, size_t len)
* @see rtnl_link_get_by_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)
+int rtnl_link_alloc_cache_flags(struct nl_sock *sk, int family,
+ struct nl_cache **result, unsigned int flags)
{
struct nl_cache * cache;
int err;
@@ -1037,7 +1039,10 @@ int rtnl_link_alloc_cache(struct nl_sock *sk, int family, struct nl_cache **resu
return -NLE_NOMEM;
cache->c_iarg1 = family;
-
+
+ if (flags)
+ nl_cache_set_flags(cache, flags);
+
if (sk && (err = nl_cache_refill(sk, cache)) < 0) {
nl_cache_free(cache);
return err;
@@ -1048,6 +1053,36 @@ int rtnl_link_alloc_cache(struct nl_sock *sk, int family, struct nl_cache **resu
}
/**
+ * Allocate link cache and fill in all configured links.
+ * @arg sk Netlink socket.
+ * @arg family Link address family or AF_UNSPEC
+ * @arg result Pointer to store resulting cache.
+ *
+ * Allocates and initializes a new link cache. If \c sk is valid, a netlink
+ * message is sent to the kernel requesting a full dump of all configured
+ * links. The returned messages are parsed and filled into the cache. If
+ * the operation succeeds, the resulting cache will contain a link object for
+ * each link configured in the kernel. If \c sk is NULL, returns 0 but the
+ * cache is still empty.
+ *
+ * If \c family is set to an address family other than \c AF_UNSPEC the
+ * contents of the cache can be limited to a specific address family.
+ * Currently the following address families are supported:
+ * - AF_BRIDGE
+ * - AF_INET6
+ *
+ * @route_doc{link_list, Get List of Links}
+ * @see rtnl_link_get()
+ * @see rtnl_link_get_by_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)
+{
+ return rtnl_link_alloc_cache_flags(sk, family, result, 0);
+}
+
+
+/**
* Lookup link in cache by interface index
* @arg cache Link cache
* @arg ifindex Interface index
diff --git a/lib/route/neigh.c b/lib/route/neigh.c
index ab07ec9..6059e7f 100644
--- a/lib/route/neigh.c
+++ b/lib/route/neigh.c
@@ -546,6 +546,38 @@ int rtnl_neigh_alloc_cache(struct nl_sock *sock, struct nl_cache **result)
}
/**
+ * Build a neighbour cache including all neighbours currently configured in the kernel.
+ * @arg sock Netlink socket.
+ * @arg result Pointer to store resulting cache.
+ * @arg flags Flags to apply to cache before filling
+ *
+ * Allocates a new neighbour cache, initializes it properly and updates it
+ * to include all neighbours currently configured in the kernel.
+ *
+ * @return 0 on success or a negative error code.
+ */
+int rtnl_neigh_alloc_cache_flags(struct nl_sock *sock, struct nl_cache **result,
+ unsigned int flags)
+{
+ struct nl_cache * cache;
+ int err;
+
+ cache = nl_cache_alloc(&rtnl_neigh_ops);
+ if (!cache)
+ return -NLE_NOMEM;
+
+ nl_cache_set_flags(cache, flags);
+
+ if (sock && (err = nl_cache_refill(sock, cache)) < 0) {
+ nl_cache_free(cache);
+ return err;
+ }
+
+ *result = cache;
+ return 0;
+}
+
+/**
* Look up a neighbour by interface index and destination address
* @arg cache neighbour cache
* @arg ifindex interface index the neighbour is on
diff --git a/libnl-cli-3.sym b/libnl-cli-3.sym
index 3d433f6..71ff2eb 100644
--- a/libnl-cli-3.sym
+++ b/libnl-cli-3.sym
@@ -108,3 +108,10 @@ global:
local:
*;
};
+
+libnl_3_2_28 {
+global:
+ nl_cli_alloc_cache_flags;
+ nl_cli_link_alloc_cache_flags;
+ nl_cli_link_alloc_cache_family_flags;
+} libnl_3;
diff --git a/libnl-route-3.sym b/libnl-route-3.sym
index 23b839a..f18a11d 100644
--- a/libnl-route-3.sym
+++ b/libnl-route-3.sym
@@ -887,8 +887,10 @@ global:
libnl_3_2_28 {
global:
+ rtnl_link_alloc_cache_flags;
rtnl_link_is_vrf;
rtnl_link_vrf_alloc;
rtnl_link_vrf_get_tableid;
rtnl_link_vrf_set_tableid;
+ rtnl_neigh_alloc_cache_flags;
} libnl_3_2_27;
diff --git a/src/lib/link.c b/src/lib/link.c
index 5bce824..eb5b54b 100644
--- a/src/lib/link.c
+++ b/src/lib/link.c
@@ -31,12 +31,14 @@ struct rtnl_link *nl_cli_link_alloc(void)
return link;
}
-struct nl_cache *nl_cli_link_alloc_cache_family(struct nl_sock *sock, int family)
+struct nl_cache *nl_cli_link_alloc_cache_family_flags(struct nl_sock *sock,
+ int family,
+ unsigned int flags)
{
struct nl_cache *cache;
int err;
- if ((err = rtnl_link_alloc_cache(sock, family, &cache)) < 0)
+ if ((err = rtnl_link_alloc_cache_flags(sock, family, &cache, flags)) < 0)
nl_cli_fatal(err, "Unable to allocate link cache: %s",
nl_geterror(err));
@@ -45,11 +47,22 @@ struct nl_cache *nl_cli_link_alloc_cache_family(struct nl_sock *sock, int family
return cache;
}
+struct nl_cache *nl_cli_link_alloc_cache_family(struct nl_sock *sock, int family)
+{
+ return nl_cli_link_alloc_cache_family_flags(sock, family, 0);
+}
+
struct nl_cache *nl_cli_link_alloc_cache(struct nl_sock *sock)
{
return nl_cli_link_alloc_cache_family(sock, AF_UNSPEC);
}
+struct nl_cache *nl_cli_link_alloc_cache_flags(struct nl_sock *sock,
+ unsigned int flags)
+{
+ return nl_cli_link_alloc_cache_family_flags(sock, AF_UNSPEC, flags);
+}
+
void nl_cli_link_parse_family(struct rtnl_link *link, char *arg)
{
int family;
diff --git a/src/lib/utils.c b/src/lib/utils.c
index e5eacde..467aaed 100644
--- a/src/lib/utils.c
+++ b/src/lib/utils.c
@@ -180,6 +180,23 @@ struct nl_cache *nl_cli_alloc_cache(struct nl_sock *sock, const char *name,
return cache;
}
+struct nl_cache *nl_cli_alloc_cache_flags(struct nl_sock *sock,
+ const char *name, unsigned int flags,
+ int (*ac)(struct nl_sock *, struct nl_cache **,
+ unsigned int))
+{
+ struct nl_cache *cache;
+ int err;
+
+ if ((err = ac(sock, &cache, flags)) < 0)
+ nl_cli_fatal(err, "Unable to allocate %s cache: %s",
+ name, nl_geterror(err));
+
+ nl_cache_mngt_provide(cache);
+
+ return cache;
+}
+
void nl_cli_load_module(const char *prefix, const char *name)
{
char path[FILENAME_MAX+1];
diff --git a/src/nl-neigh-list.c b/src/nl-neigh-list.c
index ebf5486..8390d4b 100644
--- a/src/nl-neigh-list.c
+++ b/src/nl-neigh-list.c
@@ -45,7 +45,7 @@ int main(int argc, char *argv[])
sock = nl_cli_alloc_socket();
nl_cli_connect(sock, NETLINK_ROUTE);
- link_cache = nl_cli_link_alloc_cache(sock);
+ link_cache = nl_cli_link_alloc_cache_flags(sock, NL_CACHE_AF_ITER);
neigh_cache = nl_cli_neigh_alloc_cache(sock);
neigh = nl_cli_neigh_alloc();