iproute2: gnet_stats
(Logical change 1.107)
diff --git a/tc/tc_util.c b/tc/tc_util.c
index 20843de..45a35c4 100644
--- a/tc/tc_util.c
+++ b/tc/tc_util.c
@@ -425,3 +425,91 @@
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];
+}
+