dect
/
libnl
Archived
13
0
Fork 0

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
This commit is contained in:
Thomas Graf 2010-11-11 22:26:11 +01:00
parent 2847cf081b
commit 7ff4deeb56
6 changed files with 144 additions and 14 deletions

View File

@ -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>

View File

@ -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 *);

View File

@ -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 *);

View File

@ -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;
@ -1539,6 +1595,25 @@ uint64_t rtnl_link_get_stat(struct rtnl_link *link, int id)
return link->l_stats[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

View File

@ -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);

View File

@ -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;