diff options
author | Thomas Graf <tgraf@suug.ch> | 2010-11-11 21:26:11 (GMT) |
---|---|---|
committer | Thomas Graf <tgraf@suug.ch> | 2010-11-11 21:26:11 (GMT) |
commit | 7ff4deeb56300a83a1bee091d3664fd588ac7837 (patch) | |
tree | dda1f357ef9b91e9fe1bef82229f1aeb3215579a | |
parent | 2847cf081b88678a2bb780c59a2678131d47c11d (diff) | |
download | libnl-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.h | 3 | ||||
-rw-r--r-- | include/netlink/cli/link.h | 5 | ||||
-rw-r--r-- | include/netlink/route/link.h | 34 | ||||
-rw-r--r-- | lib/route/link.c | 89 | ||||
-rw-r--r-- | src/lib/link.c | 21 | ||||
-rw-r--r-- | src/nl-link-list.c | 6 |
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, ¶ms, OBJ_CAST(link)); return 0; |