]> git.ipfire.org Git - thirdparty/iproute2.git/commitdiff
iproute2: gnet_stats
authorch[shemminger]!tgraf <ch[shemminger]!tgraf>
Tue, 7 Dec 2004 23:52:52 +0000 (23:52 +0000)
committerch[shemminger]!tgraf <ch[shemminger]!tgraf>
Tue, 7 Dec 2004 23:52:52 +0000 (23:52 +0000)
(Logical change 1.107)

include/linux/gen_stats.h
include/linux/rtnetlink.h
tc/m_action.c
tc/tc_class.c
tc/tc_filter.c
tc/tc_qdisc.c
tc/tc_util.c
tc/tc_util.h

index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..ab631c3571ce3ddaa69eac073864da30e95c9085 100644 (file)
@@ -0,0 +1,62 @@
+#ifndef __LINUX_GEN_STATS_H
+#define __LINUX_GEN_STATS_H
+
+#include <linux/types.h>
+
+enum {
+       TCA_STATS_UNSPEC,
+       TCA_STATS_BASIC,
+       TCA_STATS_RATE_EST,
+       TCA_STATS_QUEUE,
+       TCA_STATS_APP,
+       __TCA_STATS_MAX,
+};
+#define TCA_STATS_MAX (__TCA_STATS_MAX - 1)
+
+/**
+ * @bytes: number of seen bytes
+ * @packets: number of seen packets
+ */
+struct gnet_stats_basic
+{
+       __u64   bytes;
+       __u32   packets;
+};
+
+/**
+ * @bps: current byte rate
+ * @pps: current packet rate
+ */
+struct gnet_stats_rate_est
+{
+       __u32   bps;
+       __u32   pps;
+};
+
+/**
+ * @qlen: queue length
+ * @backlog: backlog size of queue
+ * @drops: number of dropped packets
+ * @requeues: number of requeues
+ */
+struct gnet_stats_queue
+{
+       __u32   qlen;
+       __u32   backlog;
+       __u32   drops;
+       __u32   requeues;
+       __u32   overlimits;
+};
+
+/**
+ * @interval: sampling period
+ * @ewma_log: the log of measurement window weight
+ */
+struct gnet_estimator
+{
+       signed char     interval;
+       unsigned char   ewma_log;
+};
+
+
+#endif /* __LINUX_GEN_STATS_H */
index 17544c471a2ccbb607f1dac2e956c1a37fad0ff6..1facfe9cd4b6932e1359369e17ae0a8d326092c4 100644 (file)
@@ -698,6 +698,8 @@ enum
        TCA_XSTATS,
        TCA_RATE,
        TCA_FCNT,
+       TCA_STATS2,
+       TCA_ACT_STATS,
        __TCA_MAX
 };
 
index dc303065f262d3c0cfcf41a4782169284c4a0f16..af3b88aea9f815519f66db1604695e853758cd2a 100644 (file)
@@ -261,9 +261,9 @@ tc_print_one_action(FILE * f, struct rtattr *arg)
        if (0 > err)
                return err;
 
-       if (show_stats && tb[TCA_STATS]) {
-               fprintf(f, "\t");
-               print_tcstats_attr(f, tb[TCA_STATS]);
+       if (show_stats && tb[TCA_ACT_STATS]) {
+               fprintf(f, "\tAction statistics:\n");
+               print_tcstats2_attr(f, tb[TCA_ACT_STATS], "\t", NULL);
                fprintf(f, "\n");
        }
 
index b4aae95151a84aff2d2cc1c32cf534173b3d177c..8b0c616a6de59d36c1c139260496626eb08a6b37 100644 (file)
@@ -216,12 +216,14 @@ static int print_class(const struct sockaddr_nl *who,
        }
        fprintf(fp, "\n");
        if (show_stats) {
-               if (tb[TCA_STATS]) {
-                       print_tcstats_attr(fp, tb[TCA_STATS]);
+               struct rtattr *xstats = NULL;
+               
+               if (tb[TCA_STATS] || tb[TCA_STATS2]) {
+                       print_tcstats_attr(fp, tb, " ", &xstats);
                        fprintf(fp, "\n");
                }
-               if (q && tb[TCA_XSTATS] && q->print_xstats) {
-                       q->print_xstats(q, fp, tb[TCA_XSTATS]);
+               if (q && (xstats || tb[TCA_XSTATS]) && q->print_xstats) {
+                       q->print_xstats(q, fp, xstats ? : tb[TCA_XSTATS]);
                        fprintf(fp, "\n");
                }
        }
index af663ddf936c4d0a4aa71e9c2e862b667a55bae7..0c63a9028300940e89bd4816d019cc56a7dbe608 100644 (file)
@@ -254,8 +254,8 @@ static int print_filter(const struct sockaddr_nl *who,
        }
        fprintf(fp, "\n");
 
-       if (show_stats && tb[TCA_STATS]) {
-               print_tcstats_attr(fp, tb[TCA_STATS]);
+       if (show_stats && (tb[TCA_STATS] || tb[TCA_STATS2])) {
+               print_tcstats_attr(fp, tb, " ", NULL);
                fprintf(fp, "\n");
        }
 
index fe7e354cafcc6378b52dcb862cb477ef374eb342..3ce60829c497f2e4d804d1e18ac3997aaab5acab 100644 (file)
@@ -167,39 +167,6 @@ int tc_qdisc_modify(int cmd, unsigned flags, int argc, char **argv)
        return 0;
 }
 
-
-void print_tcstats_attr(FILE *fp, const struct rtattr *rta)
-{
-       struct tc_stats st;
-       SPRINT_BUF(b1);
-
-       /* handle case where kernel returns more/less than we know about */
-       memset(&st, 0, sizeof(st));
-       memcpy(&st, RTA_DATA(rta), MIN(RTA_PAYLOAD(rta), sizeof(st)));
-
-       fprintf(fp, " Sent %llu bytes %u pkts (dropped %u, overlimits %u) ",
-               (unsigned long long)st.bytes, st.packets, st.drops, 
-               st.overlimits);
-
-       if (st.bps || st.pps || st.qlen || st.backlog) {
-               fprintf(fp, "\n ");
-               if (st.bps || st.pps) {
-                       fprintf(fp, "rate ");
-                       if (st.bps)
-                               fprintf(fp, "%s ", sprint_rate(st.bps, b1));
-                       if (st.pps)
-                               fprintf(fp, "%upps ", st.pps);
-               }
-               if (st.qlen || st.backlog) {
-                       fprintf(fp, "backlog ");
-                       if (st.backlog)
-                               fprintf(fp, "%s ", sprint_size(st.backlog, b1));
-                       if (st.qlen)
-                               fprintf(fp, "%up ", st.qlen);
-               }
-       }
-}
-
 static int filter_ifindex;
 
 static int print_qdisc(const struct sockaddr_nl *who, 
@@ -264,13 +231,15 @@ static int print_qdisc(const struct sockaddr_nl *who,
        }
        fprintf(fp, "\n");
        if (show_stats) {
-               if (tb[TCA_STATS]) {
-                       print_tcstats_attr(fp, tb[TCA_STATS]);
+               struct rtattr *xstats = NULL;
+
+               if (tb[TCA_STATS] || tb[TCA_STATS2] || tb[TCA_XSTATS]) {
+                       print_tcstats_attr(fp, tb, " ", &xstats);
                        fprintf(fp, "\n");
                }
 
-               if (q && tb[TCA_XSTATS] && q->print_xstats) {
-                       q->print_xstats(q, fp, tb[TCA_XSTATS]);
+               if (q && xstats && q->print_xstats) {
+                       q->print_xstats(q, fp, xstats);
                        fprintf(fp, "\n");
                }
        }
index 20843de66f71a76e2b3eb1ff50bb55d5fc723cf3..45a35c4f80d6e8894fe4e72f144fbe3bd863e120 100644 (file)
@@ -425,3 +425,91 @@ void print_tm(FILE * f, const struct tcf_t *tm)
        if (tm->expires != 0)
                fprintf(f, " expires %d sec", tm->expires/hz);
 }
+
+void print_tcstats2_attr(FILE *fp, struct rtattr *rta, char *prefix, struct rtattr **xstats)
+{
+       SPRINT_BUF(b1);
+       struct rtattr *tbs[TCA_STATS_MAX + 1] = {0};
+
+       parse_rtattr(tbs, TCA_STATS_MAX, RTA_DATA(rta), RTA_PAYLOAD(rta));
+
+       if (tbs[TCA_STATS_BASIC]) {
+               struct gnet_stats_basic bs = {0};
+               memcpy(&bs, RTA_DATA(tbs[TCA_STATS_BASIC]), MIN(RTA_PAYLOAD(tbs[TCA_STATS_BASIC]), sizeof(bs)));
+               fprintf(fp, "%sSent %llu bytes %u pkt",
+                       prefix, bs.bytes, bs.packets);
+       }
+
+       if (tbs[TCA_STATS_QUEUE]) {
+               struct gnet_stats_queue q = {0};
+               memcpy(&q, RTA_DATA(tbs[TCA_STATS_QUEUE]), MIN(RTA_PAYLOAD(tbs[TCA_STATS_QUEUE]), sizeof(q)));
+               fprintf(fp, " (dropped %u, overlimits %u requeues %u) ",
+                       q.drops, q.overlimits, q.requeues);
+       }
+                       
+       if (tbs[TCA_STATS_RATE_EST]) {
+               struct gnet_stats_rate_est re = {0};
+               memcpy(&re, RTA_DATA(tbs[TCA_STATS_RATE_EST]), MIN(RTA_PAYLOAD(tbs[TCA_STATS_RATE_EST]), sizeof(re)));
+               fprintf(fp, "\n%srate %s %upps ",
+                       prefix, sprint_rate(re.bps, b1), re.pps);
+       }
+
+       if (tbs[TCA_STATS_QUEUE]) {
+               struct gnet_stats_queue q = {0};
+               memcpy(&q, RTA_DATA(tbs[TCA_STATS_QUEUE]), MIN(RTA_PAYLOAD(tbs[TCA_STATS_QUEUE]), sizeof(q)));
+               if (!tbs[TCA_STATS_RATE_EST])
+                       fprintf(fp, "\n%s", prefix);
+               fprintf(fp, "backlog %s %up requeues %u ",
+                       sprint_size(q.backlog, b1), q.qlen, q.requeues);
+       }
+
+       if (xstats)
+               *xstats = tbs[TCA_STATS_APP] ? : NULL;
+}
+
+void print_tcstats_attr(FILE *fp, struct rtattr *tb[], char *prefix, struct rtattr **xstats)
+{
+       SPRINT_BUF(b1);
+
+       if (tb[TCA_STATS2]) {
+               print_tcstats2_attr(fp, tb[TCA_STATS2], prefix, xstats);
+               if (xstats && NULL == *xstats)
+                       goto compat_xstats;
+               return;
+       }
+       /* backward compatibility */
+       if (tb[TCA_STATS]) {
+               struct tc_stats st;
+
+               /* handle case where kernel returns more/less than we know about */
+               memset(&st, 0, sizeof(st));
+               memcpy(&st, RTA_DATA(tb[TCA_STATS]), MIN(RTA_PAYLOAD(tb[TCA_STATS]), sizeof(st)));
+
+               fprintf(fp, "%sSent %llu bytes %u pkts (dropped %u, overlimits %u) ",
+                       prefix, (unsigned long long)st.bytes, st.packets, st.drops, 
+                       st.overlimits);
+
+               if (st.bps || st.pps || st.qlen || st.backlog) {
+                       fprintf(fp, "\n%s", prefix);
+                       if (st.bps || st.pps) {
+                               fprintf(fp, "rate ");
+                               if (st.bps)
+                                       fprintf(fp, "%s ", sprint_rate(st.bps, b1));
+                               if (st.pps)
+                                       fprintf(fp, "%upps ", st.pps);
+                       }
+                       if (st.qlen || st.backlog) {
+                               fprintf(fp, "backlog ");
+                               if (st.backlog)
+                                       fprintf(fp, "%s ", sprint_size(st.backlog, b1));
+                               if (st.qlen)
+                                       fprintf(fp, "%up ", st.qlen);
+                       }
+               }
+       }
+
+compat_xstats:
+       if (tb[TCA_XSTATS] && xstats)
+               *xstats = tb[TCA_XSTATS];
+}
+
index f739befa6bb273fd7a3ffc613a8ea788bff0f950..1aa1bdafb6923653e87316eabaafecd27671eead 100644 (file)
@@ -4,6 +4,7 @@
 #define MAX_MSG 16384
 #include <linux/pkt_sched.h>
 #include <linux/pkt_cls.h>
+#include <linux/gen_stats.h>
 #include "tc_core.h"
 
 struct qdisc_util
@@ -58,7 +59,8 @@ extern char * sprint_tc_classid(__u32 h, char *buf);
 extern char * sprint_usecs(__u32 usecs, char *buf);
 extern char * sprint_percent(__u32 percent, char *buf);
 
-extern void print_tcstats_attr(FILE *fp, const struct rtattr *ts);
+extern void print_tcstats_attr(FILE *fp, struct rtattr *tb[], char *prefix, struct rtattr **xstats);
+extern void print_tcstats2_attr(FILE *fp, struct rtattr *rta, char *prefix, struct rtattr **xstats);
 
 extern int get_tc_classid(__u32 *h, const char *str);
 extern int print_tc_classid(char *buf, int len, __u32 h);