summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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();