* [PATCH iproute2 WIP] ifstat: use new RTM_GETSTATS api
@ 2016-04-20 16:16 Roopa Prabhu
2016-04-20 18:53 ` Stephen Hemminger
0 siblings, 1 reply; 3+ messages in thread
From: Roopa Prabhu @ 2016-04-20 16:16 UTC (permalink / raw)
To: davem; +Cc: netdev
From: Roopa Prabhu <roopa@cumulusnetworks.com>
sample hacked up patch currently used for testing.
needs re-work if ifstat will move to RTM_GETSTATS.
Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
---
include/libnetlink.h | 6 ++++++
include/linux/if_link.h | 22 ++++++++++++++++++++++
include/linux/rtnetlink.h | 5 +++++
lib/libnetlink.c | 31 +++++++++++++++++++++++++++++++
misc/ifstat.c | 37 ++++++++++++++++++++-----------------
5 files changed, 84 insertions(+), 17 deletions(-)
diff --git a/include/libnetlink.h b/include/libnetlink.h
index 491263f..ccaab46 100644
--- a/include/libnetlink.h
+++ b/include/libnetlink.h
@@ -44,6 +44,12 @@ int rtnl_dump_request(struct rtnl_handle *rth, int type, void *req,
int rtnl_dump_request_n(struct rtnl_handle *rth, struct nlmsghdr *n)
__attribute__((warn_unused_result));
+int rtnl_wilddump_stats_request(struct rtnl_handle *rth, int family, int type)
+ __attribute__((warn_unused_result));
+int rtnl_wilddump_stats_req_filter(struct rtnl_handle *rth, int family,
+ int type, __u32 filt_mask)
+ __attribute__((warn_unused_result));
+
struct rtnl_ctrl_data {
int nsid;
};
diff --git a/include/linux/if_link.h b/include/linux/if_link.h
index 6a688e8..eb1064a 100644
--- a/include/linux/if_link.h
+++ b/include/linux/if_link.h
@@ -165,6 +165,8 @@ enum {
#define IFLA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifinfomsg))))
#define IFLA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ifinfomsg))
+#define IFLA_RTA_STATS(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct if_stats_msg))))
+
enum {
IFLA_INET_UNSPEC,
IFLA_INET_CONF,
@@ -777,4 +779,24 @@ enum {
#define IFLA_HSR_MAX (__IFLA_HSR_MAX - 1)
+/* STATS section */
+
+struct if_stats_msg {
+ __u8 family;
+ __u8 pad1;
+ __u16 pad2;
+ __u32 ifindex;
+ __u32 filter_mask;
+};
+
+enum {
+ IFLA_STATS_UNSPEC,
+ IFLA_STATS_LINK_64,
+ __IFLA_STATS_MAX,
+};
+
+#define IFLA_STATS_MAX (__IFLA_STATS_MAX - 1)
+
+#define IFLA_STATS_FILTER_BIT(ATTR) (1 << (ATTR - 1))
+
#endif /* _LINUX_IF_LINK_H */
diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h
index 6aaa2a3..e8cdff5 100644
--- a/include/linux/rtnetlink.h
+++ b/include/linux/rtnetlink.h
@@ -139,6 +139,11 @@ enum {
RTM_GETNSID = 90,
#define RTM_GETNSID RTM_GETNSID
+ RTM_NEWSTATS = 92,
+#define RTM_NEWSTATS RTM_NEWSTATS
+ RTM_GETSTATS = 94,
+#define RTM_GETSTATS RTM_GETSTATS
+
__RTM_MAX,
#define RTM_MAX (((__RTM_MAX + 3) & ~3) - 1)
};
diff --git a/lib/libnetlink.c b/lib/libnetlink.c
index a90e52c..f7baf51 100644
--- a/lib/libnetlink.c
+++ b/lib/libnetlink.c
@@ -838,3 +838,34 @@ int __parse_rtattr_nested_compat(struct rtattr *tb[], int max, struct rtattr *rt
memset(tb, 0, sizeof(struct rtattr *) * (max + 1));
return 0;
}
+
+int rtnl_wilddump_stats_req_filter(struct rtnl_handle *rth, int family, int type,
+ __u32 filt_mask)
+{
+ struct {
+ struct nlmsghdr nlh;
+ struct if_stats_msg ifsm;
+ } req;
+
+ int err;
+
+ memset(&req, 0, sizeof(req));
+ req.nlh.nlmsg_len = sizeof(req);
+ req.nlh.nlmsg_type = type;
+ req.nlh.nlmsg_flags = NLM_F_DUMP|NLM_F_REQUEST;
+ req.nlh.nlmsg_pid = 0;
+ req.nlh.nlmsg_seq = rth->dump = ++rth->seq;
+ req.ifsm.family = family;
+ req.ifsm.filter_mask = filt_mask;
+
+ err = send(rth->fd, (void*)&req, sizeof(req), 0);
+
+ return err;
+}
+
+int rtnl_wilddump_stats_request(struct rtnl_handle *rth, int family, int type)
+{
+ return rtnl_wilddump_stats_req_filter(rth, family, type,
+ IFLA_STATS_FILTER_BIT(IFLA_STATS_LINK_64));
+}
+
diff --git a/misc/ifstat.c b/misc/ifstat.c
index abbb4e7..e517c9a 100644
--- a/misc/ifstat.c
+++ b/misc/ifstat.c
@@ -35,6 +35,8 @@
#include <SNAPSHOT.h>
+#include "utils.h"
+
int dump_zeros;
int reset_history;
int ignore_history;
@@ -49,6 +51,8 @@ double W;
char **patterns;
int npatterns;
+struct rtnl_handle rth;
+
char info_source[128];
int source_mismatch;
@@ -58,9 +62,9 @@ struct ifstat_ent {
struct ifstat_ent *next;
char *name;
int ifindex;
- unsigned long long val[MAXS];
+ __u64 val[MAXS];
double rate[MAXS];
- __u32 ival[MAXS];
+ __u64 ival[MAXS];
};
static const char *stats[MAXS] = {
@@ -109,32 +113,29 @@ static int match(const char *id)
static int get_nlmsg(const struct sockaddr_nl *who,
struct nlmsghdr *m, void *arg)
{
- struct ifinfomsg *ifi = NLMSG_DATA(m);
- struct rtattr *tb[IFLA_MAX+1];
+ struct if_stats_msg *ifsm = NLMSG_DATA(m);
+ struct rtattr * tb[IFLA_STATS_MAX+1];
int len = m->nlmsg_len;
struct ifstat_ent *n;
int i;
- if (m->nlmsg_type != RTM_NEWLINK)
+ if (m->nlmsg_type != RTM_NEWSTATS)
return 0;
- len -= NLMSG_LENGTH(sizeof(*ifi));
+ len -= NLMSG_LENGTH(sizeof(*ifsm));
if (len < 0)
return -1;
- if (!(ifi->ifi_flags&IFF_UP))
- return 0;
-
- parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
- if (tb[IFLA_IFNAME] == NULL || tb[IFLA_STATS] == NULL)
+ parse_rtattr(tb, IFLA_STATS_MAX, IFLA_RTA_STATS(ifsm), len);
+ if (tb[IFLA_STATS_LINK_64] == NULL)
return 0;
n = malloc(sizeof(*n));
if (!n)
abort();
- n->ifindex = ifi->ifi_index;
- n->name = strdup(RTA_DATA(tb[IFLA_IFNAME]));
- memcpy(&n->ival, RTA_DATA(tb[IFLA_STATS]), sizeof(n->ival));
+ n->ifindex = ifsm->ifindex;
+ n->name = strdup(ll_index_to_name(ifsm->ifindex));
+ memcpy(&n->ival, RTA_DATA(tb[IFLA_STATS_LINK_64]), sizeof(n->ival));
memset(&n->rate, 0, sizeof(n->rate));
for (i = 0; i < MAXS; i++)
n->val[i] = n->ival[i];
@@ -151,9 +152,11 @@ static void load_info(void)
if (rtnl_open(&rth, 0) < 0)
exit(1);
- if (rtnl_wilddump_request(&rth, AF_INET, RTM_GETLINK) < 0) {
+ ll_init_map(&rth);
+
+ if (rtnl_wilddump_stats_request(&rth, AF_UNSPEC, RTM_GETSTATS) < 0) {
perror("Cannot send dump request");
- exit(1);
+ exit(1);
}
if (rtnl_dump_filter(&rth, get_nlmsg, NULL) < 0) {
@@ -216,7 +219,7 @@ static void load_raw_table(FILE *fp)
*next++ = 0;
if (sscanf(p, "%llu", n->val+i) != 1)
abort();
- n->ival[i] = (__u32)n->val[i];
+ n->ival[i] = (__u64)n->val[i];
p = next;
if (!(next = strchr(p, ' ')))
abort();
--
1.9.1
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH iproute2 WIP] ifstat: use new RTM_GETSTATS api
2016-04-20 16:16 [PATCH iproute2 WIP] ifstat: use new RTM_GETSTATS api Roopa Prabhu
@ 2016-04-20 18:53 ` Stephen Hemminger
2016-04-20 20:25 ` Roopa Prabhu
0 siblings, 1 reply; 3+ messages in thread
From: Stephen Hemminger @ 2016-04-20 18:53 UTC (permalink / raw)
To: Roopa Prabhu; +Cc: davem, netdev
On Wed, 20 Apr 2016 09:16:15 -0700
Roopa Prabhu <roopa@cumulusnetworks.com> wrote:
> +int rtnl_wilddump_stats_req_filter(struct rtnl_handle *rth, int family, int type,
> + __u32 filt_mask)
> +{
> + struct {
> + struct nlmsghdr nlh;
> + struct if_stats_msg ifsm;
> + } req;
Please use C99 initialization instead of memset in new code.
> + int err;
> +
> + memset(&req, 0, sizeof(req));
> + req.nlh.nlmsg_len = sizeof(req);
> + req.nlh.nlmsg_type = type;
> + req.nlh.nlmsg_flags = NLM_F_DUMP|NLM_F_REQUEST;
> + req.nlh.nlmsg_pid = 0;
> + req.nlh.nlmsg_seq = rth->dump = ++rth->seq;
> + req.ifsm.family = family;
> + req.ifsm.filter_mask = filt_mask;
> +
> + err = send(rth->fd, (void*)&req, sizeof(req), 0);
> +
> + return err;
Why not just:
return send(rth->fd, &req, sizoef(req), 0);
> +}
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH iproute2 WIP] ifstat: use new RTM_GETSTATS api
2016-04-20 18:53 ` Stephen Hemminger
@ 2016-04-20 20:25 ` Roopa Prabhu
0 siblings, 0 replies; 3+ messages in thread
From: Roopa Prabhu @ 2016-04-20 20:25 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: davem, netdev
On 4/20/16, 11:53 AM, Stephen Hemminger wrote:
> On Wed, 20 Apr 2016 09:16:15 -0700
> Roopa Prabhu <roopa@cumulusnetworks.com> wrote:
>
>> +int rtnl_wilddump_stats_req_filter(struct rtnl_handle *rth, int family, int type,
>> + __u32 filt_mask)
>> +{
>> + struct {
>> + struct nlmsghdr nlh;
>> + struct if_stats_msg ifsm;
>> + } req;
> Please use C99 initialization instead of memset in new code.
yes, ack.
>
>> + int err;
>> +
>> + memset(&req, 0, sizeof(req));
>> + req.nlh.nlmsg_len = sizeof(req);
>> + req.nlh.nlmsg_type = type;
>> + req.nlh.nlmsg_flags = NLM_F_DUMP|NLM_F_REQUEST;
>> + req.nlh.nlmsg_pid = 0;
>> + req.nlh.nlmsg_seq = rth->dump = ++rth->seq;
>> + req.ifsm.family = family;
>> + req.ifsm.filter_mask = filt_mask;
>> +
>> + err = send(rth->fd, (void*)&req, sizeof(req), 0);
>> +
>> + return err;
> Why not just:
> return send(rth->fd, &req, sizoef(req), 0);
yes, i had that initially. and then changed it to add some debugs before returning.
this is all WIP. will clean it up.
thanks.
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2016-04-20 20:25 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-04-20 16:16 [PATCH iproute2 WIP] ifstat: use new RTM_GETSTATS api Roopa Prabhu
2016-04-20 18:53 ` Stephen Hemminger
2016-04-20 20:25 ` Roopa Prabhu
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).