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:
parent
2847cf081b
commit
7ff4deeb56
|
@ -49,6 +49,9 @@
|
||||||
#include <linux/ip_mp_alg.h>
|
#include <linux/ip_mp_alg.h>
|
||||||
#include <linux/atm.h>
|
#include <linux/atm.h>
|
||||||
|
|
||||||
|
#include <linux/ipv6.h>
|
||||||
|
#include <linux/snmp.h>
|
||||||
|
|
||||||
#include <netlink/netlink.h>
|
#include <netlink/netlink.h>
|
||||||
#include <netlink/handlers.h>
|
#include <netlink/handlers.h>
|
||||||
#include <netlink/cache.h>
|
#include <netlink/cache.h>
|
||||||
|
|
|
@ -15,10 +15,9 @@
|
||||||
#include <netlink/route/link.h>
|
#include <netlink/route/link.h>
|
||||||
#include <netlink/cli/utils.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 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_family(struct rtnl_link *, char *);
|
||||||
extern void nl_cli_link_parse_name(struct rtnl_link *, char *);
|
extern void nl_cli_link_parse_name(struct rtnl_link *, char *);
|
||||||
|
|
|
@ -46,6 +46,36 @@ enum rtnl_link_st {
|
||||||
RTNL_LINK_TX_WIN_ERR,
|
RTNL_LINK_TX_WIN_ERR,
|
||||||
RTNL_LINK_COLLISIONS,
|
RTNL_LINK_COLLISIONS,
|
||||||
RTNL_LINK_MULTICAST,
|
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,
|
__RTNL_LINK_STATS_MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -57,7 +87,7 @@ extern void rtnl_link_put(struct rtnl_link *);
|
||||||
extern void rtnl_link_free(struct rtnl_link *);
|
extern void rtnl_link_free(struct rtnl_link *);
|
||||||
|
|
||||||
/* link cache management */
|
/* 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(struct nl_cache *, int);
|
||||||
extern struct rtnl_link *rtnl_link_get_by_name(struct nl_cache *, const char *);
|
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 int rtnl_link_get_num_vf(struct rtnl_link *, uint32_t *);
|
||||||
|
|
||||||
extern uint64_t rtnl_link_get_stat(struct rtnl_link *, int);
|
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 int rtnl_link_set_info_type(struct rtnl_link *, const char *);
|
||||||
extern char * rtnl_link_get_info_type(struct rtnl_link *);
|
extern char * rtnl_link_get_info_type(struct rtnl_link *);
|
||||||
|
|
|
@ -354,7 +354,7 @@ static int link_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
|
||||||
struct ifinfomsg *ifi;
|
struct ifinfomsg *ifi;
|
||||||
struct nlattr *tb[IFLA_MAX+1];
|
struct nlattr *tb[IFLA_MAX+1];
|
||||||
struct rtnl_link_af_ops *af_ops = NULL;
|
struct rtnl_link_af_ops *af_ops = NULL;
|
||||||
int err;
|
int err, family;
|
||||||
|
|
||||||
link = rtnl_link_alloc();
|
link = rtnl_link_alloc();
|
||||||
if (link == NULL) {
|
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;
|
return -NLE_MSG_TOOSHORT;
|
||||||
|
|
||||||
ifi = nlmsg_data(n);
|
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_arptype = ifi->ifi_type;
|
||||||
link->l_index = ifi->ifi_index;
|
link->l_index = ifi->ifi_index;
|
||||||
link->l_flags = ifi->ifi_flags;
|
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_ARPTYPE| LINK_ATTR_IFINDEX |
|
||||||
LINK_ATTR_FLAGS | LINK_ATTR_CHANGE);
|
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) {
|
if (af_ops->ao_protinfo_policy) {
|
||||||
memcpy(&link_policy[IFLA_PROTINFO],
|
memcpy(&link_policy[IFLA_PROTINFO],
|
||||||
af_ops->ao_protinfo_policy,
|
af_ops->ao_protinfo_policy,
|
||||||
|
@ -589,7 +597,9 @@ errout:
|
||||||
|
|
||||||
static int link_request_update(struct nl_cache *cache, struct nl_sock *sk)
|
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)
|
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.
|
* Allocate link cache and fill in all configured links.
|
||||||
* @arg sk Netlink socket.
|
* @arg sk Netlink socket.
|
||||||
|
* @arg family Link address family or AF_UNSPEC
|
||||||
* @arg result Pointer to store resulting cache.
|
* @arg result Pointer to store resulting cache.
|
||||||
*
|
*
|
||||||
* Allocates a new link cache, initializes it properly and updates it
|
* 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.
|
* @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_TX_WIN_ERR, tx_win_err)
|
||||||
__ADD(RTNL_LINK_COLLISIONS, collisions)
|
__ADD(RTNL_LINK_COLLISIONS, collisions)
|
||||||
__ADD(RTNL_LINK_MULTICAST, multicast)
|
__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)
|
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)
|
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;
|
return link->l_family;
|
||||||
else
|
else
|
||||||
return AF_UNSPEC;
|
return AF_UNSPEC;
|
||||||
|
@ -1539,6 +1595,25 @@ uint64_t rtnl_link_get_stat(struct rtnl_link *link, int id)
|
||||||
return link->l_stats[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
|
* Specify the info type of a link
|
||||||
* @arg link link object
|
* @arg link link object
|
||||||
|
|
|
@ -31,11 +31,30 @@ struct rtnl_link *nl_cli_link_alloc(void)
|
||||||
return link;
|
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)
|
void nl_cli_link_parse_family(struct rtnl_link *link, char *arg)
|
||||||
{
|
{
|
||||||
int family;
|
int family;
|
||||||
|
|
||||||
if ((family = nl_str2af(arg)) == AF_UNSPEC)
|
if ((family = nl_str2af(arg)) < 0)
|
||||||
nl_cli_fatal(EINVAL,
|
nl_cli_fatal(EINVAL,
|
||||||
"Unable to translate address family \"%s\"", arg);
|
"Unable to translate address family \"%s\"", arg);
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
* License as published by the Free Software Foundation version 2.1
|
* License as published by the Free Software Foundation version 2.1
|
||||||
* of the License.
|
* of the License.
|
||||||
*
|
*
|
||||||
* Copyright (c) 2003-2009 Thomas Graf <tgraf@suug.ch>
|
* Copyright (c) 2003-2010 Thomas Graf <tgraf@suug.ch>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
@ -59,7 +59,6 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
sock = nl_cli_alloc_socket();
|
sock = nl_cli_alloc_socket();
|
||||||
nl_cli_connect(sock, NETLINK_ROUTE);
|
nl_cli_connect(sock, NETLINK_ROUTE);
|
||||||
link_cache = nl_cli_link_alloc_cache(sock);
|
|
||||||
link = nl_cli_link_alloc();
|
link = nl_cli_link_alloc();
|
||||||
|
|
||||||
for (;;) {
|
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));
|
nl_cache_dump_filter(link_cache, ¶ms, OBJ_CAST(link));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Reference in New Issue