summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Graf <tgraf@suug.ch>2010-11-11 21:26:11 (GMT)
committerThomas Graf <tgraf@suug.ch>2010-11-11 21:26:11 (GMT)
commit7ff4deeb56300a83a1bee091d3664fd588ac7837 (patch)
treedda1f357ef9b91e9fe1bef82229f1aeb3215579a
parent2847cf081b88678a2bb780c59a2678131d47c11d (diff)
downloadlibnl-7ff4deeb56300a83a1bee091d3664fd588ac7837.zip
libnl-7ff4deeb56300a83a1bee091d3664fd588ac7837.tar.gz
libnl-7ff4deeb56300a83a1bee091d3664fd588ac7837.tar.bz2
Extend rtnl_link_alloc_cache() to support address families
Adds a family argument which allows to request link dumps for a certain address family. This allows to f.e. dump ipv6 specific statistics and data. nl-link-list --family inet6
-rw-r--r--include/netlink-local.h3
-rw-r--r--include/netlink/cli/link.h5
-rw-r--r--include/netlink/route/link.h34
-rw-r--r--lib/route/link.c89
-rw-r--r--src/lib/link.c21
-rw-r--r--src/nl-link-list.c6
6 files changed, 144 insertions, 14 deletions
diff --git a/include/netlink-local.h b/include/netlink-local.h
index e9310ea..59f1d61 100644
--- a/include/netlink-local.h
+++ b/include/netlink-local.h
@@ -49,6 +49,9 @@
#include <linux/ip_mp_alg.h>
#include <linux/atm.h>
+#include <linux/ipv6.h>
+#include <linux/snmp.h>
+
#include <netlink/netlink.h>
#include <netlink/handlers.h>
#include <netlink/cache.h>
diff --git a/include/netlink/cli/link.h b/include/netlink/cli/link.h
index 7fe4972..3f37948 100644
--- a/include/netlink/cli/link.h
+++ b/include/netlink/cli/link.h
@@ -15,10 +15,9 @@
#include <netlink/route/link.h>
#include <netlink/cli/utils.h>
-#define nl_cli_link_alloc_cache(sk) \
- nl_cli_alloc_cache((sk), "link", rtnl_link_alloc_cache)
-
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(struct nl_sock *);
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/route/link.h b/include/netlink/route/link.h
index 39eea0a..1949353 100644
--- a/include/netlink/route/link.h
+++ b/include/netlink/route/link.h
@@ -46,6 +46,36 @@ enum rtnl_link_st {
RTNL_LINK_TX_WIN_ERR,
RTNL_LINK_COLLISIONS,
RTNL_LINK_MULTICAST,
+ RTNL_LINK_INPKTS, /* InReceives */
+ RTNL_LINK_INHDRERRORS, /* InHdrErrors */
+ RTNL_LINK_INTOOBIGERRORS, /* InTooBigErrors */
+ RTNL_LINK_INNOROUTES, /* InNoRoutes */
+ RTNL_LINK_INADDRERRORS, /* InAddrErrors */
+ RTNL_LINK_INUNKNOWNPROTOS, /* InUnknownProtos */
+ RTNL_LINK_INTRUNCATEDPKTS, /* InTruncatedPkts */
+ RTNL_LINK_INDISCARDS, /* InDiscards */
+ RTNL_LINK_INDELIVERS, /* InDelivers */
+ RTNL_LINK_OUTFORWDATAGRAMS, /* OutForwDatagrams */
+ RTNL_LINK_OUTPKTS, /* OutRequests */
+ RTNL_LINK_OUTDISCARDS, /* OutDiscards */
+ RTNL_LINK_OUTNOROUTES, /* OutNoRoutes */
+ RTNL_LINK_REASMTIMEOUT, /* ReasmTimeout */
+ RTNL_LINK_REASMREQDS, /* ReasmReqds */
+ RTNL_LINK_REASMOKS, /* ReasmOKs */
+ RTNL_LINK_REASMFAILS, /* ReasmFails */
+ RTNL_LINK_FRAGOKS, /* FragOKs */
+ RTNL_LINK_FRAGFAILS, /* FragFails */
+ RTNL_LINK_FRAGCREATES, /* FragCreates */
+ RTNL_LINK_INMCASTPKTS, /* InMcastPkts */
+ RTNL_LINK_OUTMCASTPKTS, /* OutMcastPkts */
+ RTNL_LINK_INBCASTPKTS, /* InBcastPkts */
+ RTNL_LINK_OUTBCASTPKTS, /* OutBcastPkts */
+ RTNL_LINK_INOCTETS, /* InOctets */
+ RTNL_LINK_OUTOCTETS, /* OutOctets */
+ RTNL_LINK_INMCASTOCTETS, /* InMcastOctets */
+ RTNL_LINK_OUTMCASTOCTETS, /* OutMcastOctets */
+ RTNL_LINK_INBCASTOCTETS, /* InBcastOctets */
+ RTNL_LINK_OUTBCASTOCTETS, /* OutBcastOctets */
__RTNL_LINK_STATS_MAX,
};
@@ -57,7 +87,7 @@ extern void rtnl_link_put(struct rtnl_link *);
extern void rtnl_link_free(struct rtnl_link *);
/* link cache management */
-extern int rtnl_link_alloc_cache(struct nl_sock *, struct nl_cache **);
+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 *);
@@ -139,6 +169,8 @@ extern void rtnl_link_set_ifalias(struct rtnl_link *, const char *);
extern int rtnl_link_get_num_vf(struct rtnl_link *, uint32_t *);
extern uint64_t rtnl_link_get_stat(struct rtnl_link *, int);
+extern int rtnl_link_set_stat(struct rtnl_link *, const unsigned int,
+ const uint64_t);
extern int rtnl_link_set_info_type(struct rtnl_link *, const char *);
extern char * rtnl_link_get_info_type(struct rtnl_link *);
diff --git a/lib/route/link.c b/lib/route/link.c
index 7aed708..d54082a 100644
--- a/lib/route/link.c
+++ b/lib/route/link.c
@@ -354,7 +354,7 @@ static int link_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
struct ifinfomsg *ifi;
struct nlattr *tb[IFLA_MAX+1];
struct rtnl_link_af_ops *af_ops = NULL;
- int err;
+ int err, family;
link = rtnl_link_alloc();
if (link == NULL) {
@@ -368,7 +368,7 @@ static int link_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
return -NLE_MSG_TOOSHORT;
ifi = nlmsg_data(n);
- link->l_family = ifi->ifi_family;
+ link->l_family = family = ifi->ifi_family;
link->l_arptype = ifi->ifi_type;
link->l_index = ifi->ifi_index;
link->l_flags = ifi->ifi_flags;
@@ -377,7 +377,15 @@ static int link_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
LINK_ATTR_ARPTYPE| LINK_ATTR_IFINDEX |
LINK_ATTR_FLAGS | LINK_ATTR_CHANGE);
- if ((af_ops = rtnl_link_af_ops_lookup(ifi->ifi_family))) {
+ if ((af_ops = rtnl_link_af_ops_lookup(family))) {
+ if (af_ops->ao_alloc) {
+ link->l_af_data[family] = af_ops->ao_alloc(link);
+ if (!link->l_af_data[family]) {
+ err = -NLE_NOMEM;
+ goto errout;
+ }
+ }
+
if (af_ops->ao_protinfo_policy) {
memcpy(&link_policy[IFLA_PROTINFO],
af_ops->ao_protinfo_policy,
@@ -589,7 +597,9 @@ errout:
static int link_request_update(struct nl_cache *cache, struct nl_sock *sk)
{
- return nl_rtgen_request(sk, RTM_GETLINK, AF_UNSPEC, NLM_F_DUMP);
+ int family = cache->c_iarg1;
+
+ return nl_rtgen_request(sk, RTM_GETLINK, family, NLM_F_DUMP);
}
static void link_dump_line(struct nl_object *obj, struct nl_dump_params *p)
@@ -881,6 +891,7 @@ void rtnl_link_put(struct rtnl_link *link)
/**
* 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 a new link cache, initializes it properly and updates it
@@ -888,9 +899,24 @@ void rtnl_link_put(struct rtnl_link *link)
*
* @return 0 on success or a negative error code.
*/
-int rtnl_link_alloc_cache(struct nl_sock *sk, struct nl_cache **result)
+int rtnl_link_alloc_cache(struct nl_sock *sk, int family, struct nl_cache **result)
{
- return nl_cache_alloc_and_fill(&rtnl_link_ops, sk, result);
+ struct nl_cache * cache;
+ int err;
+
+ cache = nl_cache_alloc(&rtnl_link_ops);
+ if (!cache)
+ return -NLE_NOMEM;
+
+ cache->c_iarg1 = family;
+
+ if (sk && (err = nl_cache_refill(sk, cache)) < 0) {
+ nl_cache_free(cache);
+ return err;
+ }
+
+ *result = cache;
+ return 0;
}
/**
@@ -1202,6 +1228,36 @@ static struct trans_tbl link_stats[] = {
__ADD(RTNL_LINK_TX_WIN_ERR, tx_win_err)
__ADD(RTNL_LINK_COLLISIONS, collisions)
__ADD(RTNL_LINK_MULTICAST, multicast)
+ __ADD(RTNL_LINK_INPKTS, InReceives)
+ __ADD(RTNL_LINK_INHDRERRORS, InHdrErrors)
+ __ADD(RTNL_LINK_INTOOBIGERRORS, InTooBigErrors)
+ __ADD(RTNL_LINK_INNOROUTES, InNoRoutes)
+ __ADD(RTNL_LINK_INADDRERRORS, InAddrErrors)
+ __ADD(RTNL_LINK_INUNKNOWNPROTOS, InUnknownProtos)
+ __ADD(RTNL_LINK_INTRUNCATEDPKTS, InTruncatedPkts)
+ __ADD(RTNL_LINK_INDISCARDS, InDiscards)
+ __ADD(RTNL_LINK_INDELIVERS, InDelivers)
+ __ADD(RTNL_LINK_OUTFORWDATAGRAMS, OutForwDatagrams)
+ __ADD(RTNL_LINK_OUTPKTS, OutRequests)
+ __ADD(RTNL_LINK_OUTDISCARDS, OutDiscards)
+ __ADD(RTNL_LINK_OUTNOROUTES, OutNoRoutes)
+ __ADD(RTNL_LINK_REASMTIMEOUT, ReasmTimeout)
+ __ADD(RTNL_LINK_REASMREQDS, ReasmReqds)
+ __ADD(RTNL_LINK_REASMOKS, ReasmOKs)
+ __ADD(RTNL_LINK_REASMFAILS, ReasmFails)
+ __ADD(RTNL_LINK_FRAGOKS, FragOKs)
+ __ADD(RTNL_LINK_FRAGFAILS, FragFails)
+ __ADD(RTNL_LINK_FRAGCREATES, FragCreates)
+ __ADD(RTNL_LINK_INMCASTPKTS, InMcastPkts)
+ __ADD(RTNL_LINK_OUTMCASTPKTS, OutMcastPkts)
+ __ADD(RTNL_LINK_INBCASTPKTS, InBcastPkts)
+ __ADD(RTNL_LINK_OUTBCASTPKTS, OutBcastPkts)
+ __ADD(RTNL_LINK_INOCTETS, InOctets)
+ __ADD(RTNL_LINK_OUTOCTETS, OutOctets)
+ __ADD(RTNL_LINK_INMCASTOCTETS, InMcastOctets)
+ __ADD(RTNL_LINK_OUTMCASTOCTETS, OutMcastOctets)
+ __ADD(RTNL_LINK_INBCASTOCTETS, InBcastOctets)
+ __ADD(RTNL_LINK_OUTBCASTOCTETS, OutBcastOctets)
};
char *rtnl_link_stat2str(int st, char *buf, size_t len)
@@ -1365,7 +1421,7 @@ void rtnl_link_set_family(struct rtnl_link *link, int family)
int rtnl_link_get_family(struct rtnl_link *link)
{
- if (link->l_family & LINK_ATTR_FAMILY)
+ if (link->ce_mask & LINK_ATTR_FAMILY)
return link->l_family;
else
return AF_UNSPEC;
@@ -1540,6 +1596,25 @@ uint64_t rtnl_link_get_stat(struct rtnl_link *link, int id)
}
/**
+ * Set value of a link statistics counter
+ * @arg link Link object
+ * @arg id Counter ID
+ * @arg value New value
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_set_stat(struct rtnl_link *link, const unsigned int id,
+ const uint64_t value)
+{
+ if (id > RTNL_LINK_STATS_MAX)
+ return -NLE_INVAL;
+
+ link->l_stats[id] = value;
+
+ return 0;
+}
+
+/**
* Specify the info type of a link
* @arg link link object
* @arg type info type
diff --git a/src/lib/link.c b/src/lib/link.c
index 88cea55..db90558 100644
--- a/src/lib/link.c
+++ b/src/lib/link.c
@@ -31,11 +31,30 @@ 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 *cache;
+ int err;
+
+ if ((err = rtnl_link_alloc_cache(sock, family, &cache)) < 0)
+ nl_cli_fatal(err, "Unable to allocate link cache: %s",
+ nl_geterror(err));
+
+ nl_cache_mngt_provide(cache);
+
+ return cache;
+}
+
+struct nl_cache *nl_cli_link_alloc_cache(struct nl_sock *sock)
+{
+ return nl_cli_link_alloc_cache_family(sock, AF_UNSPEC);
+}
+
void nl_cli_link_parse_family(struct rtnl_link *link, char *arg)
{
int family;
- if ((family = nl_str2af(arg)) == AF_UNSPEC)
+ if ((family = nl_str2af(arg)) < 0)
nl_cli_fatal(EINVAL,
"Unable to translate address family \"%s\"", arg);
diff --git a/src/nl-link-list.c b/src/nl-link-list.c
index 5e1e3f6..b1f75ce 100644
--- a/src/nl-link-list.c
+++ b/src/nl-link-list.c
@@ -6,7 +6,7 @@
* License as published by the Free Software Foundation version 2.1
* of the License.
*
- * Copyright (c) 2003-2009 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2003-2010 Thomas Graf <tgraf@suug.ch>
*/
#if 0
@@ -59,7 +59,6 @@ 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 = nl_cli_link_alloc();
for (;;) {
@@ -100,6 +99,9 @@ int main(int argc, char *argv[])
}
}
+ link_cache = nl_cli_link_alloc_cache_family(sock,
+ rtnl_link_get_family(link));
+
nl_cache_dump_filter(link_cache, &params, OBJ_CAST(link));
return 0;