ifstat used to get it data from the kernel with RTM_GETLINK.
Change the interface to get this data to RTM_GETSTATS that supports more
stats type beside the default one. It also change the default stats to be
64 bits based.

Signed-off-by: Nogah Frankel <nog...@mellanox.com>
Reviewed-by: Jiri Pirko <j...@mellanox.com>
---
 misc/ifstat.c | 41 ++++++++++++++++++++++-------------------
 1 file changed, 22 insertions(+), 19 deletions(-)

diff --git a/misc/ifstat.c b/misc/ifstat.c
index d551973..25a8fc1 100644
--- a/misc/ifstat.c
+++ b/misc/ifstat.c
@@ -35,6 +35,7 @@
 
 #include <SNAPSHOT.h>
 
+#include "utils.h"
 int dump_zeros;
 int reset_history;
 int ignore_history;
@@ -52,15 +53,15 @@ int npatterns;
 char info_source[128];
 int source_mismatch;
 
-#define MAXS (sizeof(struct rtnl_link_stats)/sizeof(__u32))
+#define MAXS (sizeof(struct rtnl_link_stats64)/sizeof(__u64))
 
 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 +110,30 @@ 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_STATS_RTA(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];
@@ -147,11 +146,15 @@ static void load_info(void)
 {
        struct ifstat_ent *db, *n;
        struct rtnl_handle rth;
+       __u32 filt_mask;
 
        if (rtnl_open(&rth, 0) < 0)
                exit(1);
 
-       if (rtnl_wilddump_request(&rth, AF_INET, RTM_GETLINK) < 0) {
+       ll_init_map(&rth);
+       filt_mask = IFLA_STATS_FILTER_BIT(IFLA_STATS_LINK_64);
+       if (rtnl_wilddump_stats_req_filter(&rth, AF_UNSPEC, RTM_GETSTATS,
+                                          filt_mask) < 0) {
                perror("Cannot send dump request");
                exit(1);
        }
@@ -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();
@@ -546,14 +549,14 @@ static void update_db(int interval)
                                int i;
 
                                for (i = 0; i < MAXS; i++) {
-                                       if ((long)(h1->ival[i] - n->ival[i]) < 
0) {
+                                       if ((long long)(h1->ival[i] - 
n->ival[i]) < 0) {
                                                memset(n->ival, 0, 
sizeof(n->ival));
                                                break;
                                        }
                                }
                                for (i = 0; i < MAXS; i++) {
                                        double sample;
-                                       unsigned long incr = h1->ival[i] - 
n->ival[i];
+                                       unsigned long long incr = h1->ival[i] - 
n->ival[i];
 
                                        n->val[i] += incr;
                                        n->ival[i] = h1->ival[i];
-- 
2.4.3

Reply via email to