diff --git a/include/json_print.h b/include/json_print.h index 096a999a..1a1ad5ff 100644 --- a/include/json_print.h +++ b/include/json_print.h @@ -69,6 +69,7 @@ _PRINT_FUNC(on_off, bool) _PRINT_FUNC(null, const char*) _PRINT_FUNC(string, const char*) _PRINT_FUNC(uint, unsigned int) +_PRINT_FUNC(size, __u32) _PRINT_FUNC(u64, uint64_t) _PRINT_FUNC(hhu, unsigned char) _PRINT_FUNC(hu, unsigned short) @@ -86,4 +87,17 @@ _PRINT_NAME_VALUE_FUNC(uint, unsigned int, u); _PRINT_NAME_VALUE_FUNC(string, const char*, s); #undef _PRINT_NAME_VALUE_FUNC +int print_color_rate(bool use_iec, enum output_type t, enum color_attr color, + const char *key, const char *fmt, unsigned long long rate); + +static inline int print_rate(bool use_iec, enum output_type t, + const char *key, const char *fmt, + unsigned long long rate) +{ + return print_color_rate(use_iec, t, COLOR_NONE, key, fmt, rate); +} + +/* A backdoor to the size formatter. Please use print_size() instead. */ +char *sprint_size(__u32 sz, char *buf); + #endif /* _JSON_PRINT_H_ */ diff --git a/include/utils.h b/include/utils.h index 588fceb7..17043925 100644 --- a/include/utils.h +++ b/include/utils.h @@ -20,7 +20,6 @@ extern int preferred_family; extern int human_readable; -extern int use_iec; extern int show_stats; extern int show_details; extern int show_raw; @@ -163,6 +162,9 @@ int get_be64(__be64 *val, const char *arg, int base); int get_be32(__be32 *val, const char *arg, int base); int get_be16(__be16 *val, const char *arg, int base); int get_addr64(__u64 *ap, const char *cp); +int get_rate(unsigned int *rate, const char *str); +int get_rate64(__u64 *rate, const char *str); +int get_size(unsigned int *size, const char *str); int hex2mem(const char *buf, uint8_t *mem, int count); char *hexstring_n2a(const __u8 *str, int len, char *buf, int blen); diff --git a/ip/ip_common.h b/ip/ip_common.h index 227eddd3..9a31e837 100644 --- a/ip/ip_common.h +++ b/ip/ip_common.h @@ -6,6 +6,8 @@ #include "json_print.h" +extern int use_iec; + struct link_filter { int ifindex; int family; diff --git a/lib/json_print.c b/lib/json_print.c index 62eeb1f1..b086123a 100644 --- a/lib/json_print.c +++ b/lib/json_print.c @@ -11,6 +11,7 @@ #include #include +#include #include "utils.h" #include "json_print.h" @@ -308,3 +309,65 @@ void print_nl(void) if (!_jw) printf("%s", _SL_); } + +int print_color_rate(bool use_iec, enum output_type type, enum color_attr color, + const char *key, const char *fmt, unsigned long long rate) +{ + unsigned long kilo = use_iec ? 1024 : 1000; + const char *str = use_iec ? "i" : ""; + static char *units[5] = {"", "K", "M", "G", "T"}; + char *buf; + int rc; + int i; + + if (_IS_JSON_CONTEXT(type)) + return print_color_lluint(type, color, key, "%llu", rate); + + rate <<= 3; /* bytes/sec -> bits/sec */ + + for (i = 0; i < ARRAY_SIZE(units) - 1; i++) { + if (rate < kilo) + break; + if (((rate % kilo) != 0) && rate < 1000*kilo) + break; + rate /= kilo; + } + + rc = asprintf(&buf, "%.0f%s%sbit", (double)rate, units[i], + i > 0 ? str : ""); + if (rc < 0) + return -1; + + rc = print_color_string(type, color, key, fmt, buf); + free(buf); + return rc; +} + +char *sprint_size(__u32 sz, char *buf) +{ + long kilo = 1024; + long mega = kilo * kilo; + size_t len = SPRINT_BSIZE - 1; + double tmp = sz; + + if (sz >= mega && fabs(mega * rint(tmp / mega) - sz) < 1024) + snprintf(buf, len, "%gMb", rint(tmp / mega)); + else if (sz >= kilo && fabs(kilo * rint(tmp / kilo) - sz) < 16) + snprintf(buf, len, "%gKb", rint(tmp / kilo)); + else + snprintf(buf, len, "%ub", sz); + + return buf; +} + +int print_color_size(enum output_type type, enum color_attr color, + const char *key, const char *fmt, __u32 sz) +{ + SPRINT_BUF(buf); + + if (_IS_JSON_CONTEXT(type)) + return print_color_uint(type, color, key, "%u", sz); + + sprint_size(sz, buf); + return print_color_string(type, color, key, fmt, buf); +} diff --git a/lib/utils.c b/lib/utils.c index a0ba5181..de875639 100644 --- a/lib/utils.c +++ b/lib/utils.c @@ -513,6 +513,120 @@ int get_addr64(__u64 *ap, const char *cp) return 1; } +/* See http://physics.nist.gov/cuu/Units/binary.html */ +static const struct rate_suffix { + const char *name; + double scale; +} suffixes[] = { + { "bit", 1. }, + { "Kibit", 1024. }, + { "kbit", 1000. }, + { "mibit", 1024.*1024. }, + { "mbit", 1000000. }, + { "gibit", 1024.*1024.*1024. }, + { "gbit", 1000000000. }, + { "tibit", 1024.*1024.*1024.*1024. }, + { "tbit", 1000000000000. }, + { "Bps", 8. }, + { "KiBps", 8.*1024. }, + { "KBps", 8000. }, + { "MiBps", 8.*1024*1024. }, + { "MBps", 8000000. }, + { "GiBps", 8.*1024.*1024.*1024. }, + { "GBps", 8000000000. }, + { "TiBps", 8.*1024.*1024.*1024.*1024. }, + { "TBps", 8000000000000. }, + { NULL } +}; + +int get_rate(unsigned int *rate, const char *str) +{ + char *p; + double bps = strtod(str, &p); + const struct rate_suffix *s; + + if (p == str) + return -1; + + for (s = suffixes; s->name; ++s) { + if (strcasecmp(s->name, p) == 0) { + bps *= s->scale; + p += strlen(p); + break; + } + } + + if (*p) + return -1; /* unknown suffix */ + + bps /= 8; /* -> bytes per second */ + *rate = bps; + /* detect if an overflow happened */ + if (*rate != floor(bps)) + return -1; + return 0; +} + +int get_rate64(__u64 *rate, const char *str) +{ + char *p; + double bps = strtod(str, &p); + const struct rate_suffix *s; + + if (p == str) + return -1; + + for (s = suffixes; s->name; ++s) { + if (strcasecmp(s->name, p) == 0) { + bps *= s->scale; + p += strlen(p); + break; + } + } + + if (*p) + return -1; /* unknown suffix */ + + bps /= 8; /* -> bytes per second */ + *rate = bps; + return 0; +} + +int get_size(unsigned int *size, const char *str) +{ + double sz; + char *p; + + sz = strtod(str, &p); + if (p == str) + return -1; + + if (*p) { + if (strcasecmp(p, "kb") == 0 || strcasecmp(p, "k") == 0) + sz *= 1024; + else if (strcasecmp(p, "gb") == 0 || strcasecmp(p, "g") == 0) + sz *= 1024*1024*1024; + else if (strcasecmp(p, "gbit") == 0) + sz *= 1024*1024*1024/8; + else if (strcasecmp(p, "mb") == 0 || strcasecmp(p, "m") == 0) + sz *= 1024*1024; + else if (strcasecmp(p, "mbit") == 0) + sz *= 1024*1024/8; + else if (strcasecmp(p, "kbit") == 0) + sz *= 1024/8; + else if (strcasecmp(p, "b") != 0) + return -1; + } + + *size = sz; + + /* detect if an overflow happened */ + if (*size != floor(sz)) + return -1; + + return 0; +} + static void set_address_type(inet_prefix *addr) { switch (addr->family) { diff --git a/tc/m_gate.c b/tc/m_gate.c index 4bae86ed..892775a3 100644 --- a/tc/m_gate.c +++ b/tc/m_gate.c @@ -465,10 +465,8 @@ static int print_gate_list(struct rtattr *list) } if (maxoctets != -1) { - memset(buf, 0, sizeof(buf)); - print_uint(PRINT_JSON, "max_octets", NULL, maxoctets); - print_string(PRINT_FP, NULL, "\t max-octets %s", - sprint_size(maxoctets, buf)); + print_size(PRINT_ANY, "max_octets", "\t max-octets %s", + maxoctets); } else { print_string(PRINT_FP, NULL, "\t max-octets %s", "wildcard"); diff --git a/tc/m_police.c b/tc/m_police.c index 83b25db4..bb51df68 100644 --- a/tc/m_police.c +++ b/tc/m_police.c @@ -238,7 +238,6 @@ int parse_police(int *argc_p, char ***argv_p, int tca_id, struct nlmsghdr *n) static int print_police(struct action_util *a, FILE *f, struct rtattr *arg) { - SPRINT_BUF(b1); SPRINT_BUF(b2); struct tc_police *p; struct rtattr *tb[TCA_POLICE_MAX+1]; @@ -269,10 +268,10 @@ static int print_police(struct action_util *a, FILE *f, struct rtattr *arg) rate64 = rta_getattr_u64(tb[TCA_POLICE_RATE64]); fprintf(f, " police 0x%x ", p->index); - fprintf(f, "rate %s ", sprint_rate(rate64, b1)); + tc_print_rate(PRINT_FP, NULL, "rate %s ", rate64); buffer = tc_calc_xmitsize(rate64, p->burst); - fprintf(f, "burst %s ", sprint_size(buffer, b1)); - fprintf(f, "mtu %s ", sprint_size(p->mtu, b1)); + print_size(PRINT_FP, NULL, "burst %s ", buffer); + print_size(PRINT_FP, NULL, "mtu %s ", p->mtu); if (show_raw) fprintf(f, "[%08x] ", p->burst); @@ -282,12 +281,11 @@ static int print_police(struct action_util *a, FILE *f, struct rtattr *arg) prate64 = rta_getattr_u64(tb[TCA_POLICE_PEAKRATE64]); if (prate64) - fprintf(f, "peakrate %s ", sprint_rate(prate64, b1)); + tc_print_rate(PRINT_FP, NULL, "peakrate %s ", prate64); if (tb[TCA_POLICE_AVRATE]) - fprintf(f, "avrate %s ", - sprint_rate(rta_getattr_u32(tb[TCA_POLICE_AVRATE]), - b1)); + tc_print_rate(PRINT_FP, NULL, "avrate %s ", + rta_getattr_u32(tb[TCA_POLICE_AVRATE])); print_action_control(f, "action ", p->action, ""); diff --git a/tc/q_cake.c b/tc/q_cake.c index bf116e80..b7da731b 100644 --- a/tc/q_cake.c +++ b/tc/q_cake.c @@ -434,7 +434,6 @@ static int cake_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) int atm = 0; int nat = 0; - SPRINT_BUF(b1); SPRINT_BUF(b2); if (opt == NULL) @@ -445,11 +444,10 @@ static int cake_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) if (tb[TCA_CAKE_BASE_RATE64] && RTA_PAYLOAD(tb[TCA_CAKE_BASE_RATE64]) >= sizeof(bandwidth)) { bandwidth = rta_getattr_u64(tb[TCA_CAKE_BASE_RATE64]); - if (bandwidth) { - print_uint(PRINT_JSON, "bandwidth", NULL, bandwidth); - print_string(PRINT_FP, NULL, "bandwidth %s ", - sprint_rate(bandwidth, b1)); - } else + if (bandwidth) + tc_print_rate(PRINT_ANY, "bandwidth", "bandwidth %s ", + bandwidth); + else print_string(PRINT_ANY, "bandwidth", "bandwidth %s ", "unlimited"); } @@ -574,11 +572,8 @@ static int cake_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) if (mpu) print_uint(PRINT_ANY, "mpu", "mpu %u ", mpu); - if (memlimit) { - print_uint(PRINT_JSON, "memlimit", NULL, memlimit); - print_string(PRINT_FP, NULL, "memlimit %s ", - sprint_size(memlimit, b1)); - } + if (memlimit) + print_size(PRINT_ANY, "memlimit", "memlimit %s ", memlimit); if (fwmark) print_uint(PRINT_FP, NULL, "fwmark 0x%x ", fwmark); @@ -638,11 +633,11 @@ static int cake_print_xstats(struct qdisc_util *qu, FILE *f, if (st[TCA_CAKE_STATS_MEMORY_USED] && st[TCA_CAKE_STATS_MEMORY_LIMIT]) { - print_string(PRINT_FP, NULL, " memory used: %s", - sprint_size(GET_STAT_U32(MEMORY_USED), b1)); + print_size(PRINT_FP, NULL, " memory used: %s", + GET_STAT_U32(MEMORY_USED)); - print_string(PRINT_FP, NULL, " of %s\n", - sprint_size(GET_STAT_U32(MEMORY_LIMIT), b1)); + print_size(PRINT_FP, NULL, " of %s\n", + GET_STAT_U32(MEMORY_LIMIT)); print_uint(PRINT_JSON, "memory_used", NULL, GET_STAT_U32(MEMORY_USED)); @@ -650,12 +645,10 @@ static int cake_print_xstats(struct qdisc_util *qu, FILE *f, GET_STAT_U32(MEMORY_LIMIT)); } - if (st[TCA_CAKE_STATS_CAPACITY_ESTIMATE64]) { - print_string(PRINT_FP, NULL, " capacity estimate: %s\n", - sprint_rate(GET_STAT_U64(CAPACITY_ESTIMATE64), b1)); - print_uint(PRINT_JSON, "capacity_estimate", NULL, - GET_STAT_U64(CAPACITY_ESTIMATE64)); - } + if (st[TCA_CAKE_STATS_CAPACITY_ESTIMATE64]) + tc_print_rate(PRINT_ANY, "capacity_estimate", + " capacity estimate: %s\n", + GET_STAT_U64(CAPACITY_ESTIMATE64)); if (st[TCA_CAKE_STATS_MIN_NETLEN] && st[TCA_CAKE_STATS_MAX_NETLEN]) { @@ -790,7 +783,14 @@ static int cake_print_xstats(struct qdisc_util *qu, FILE *f, #define PRINT_TSTAT_U64(name, attr) PRINT_TSTAT( \ name, attr, "llu", rta_getattr_u64(GET_TSTAT(i, attr))) - SPRINT_TSTAT(rate, u64, " thresh ", THRESHOLD_RATE64); + if (GET_TSTAT(0, THRESHOLD_RATE64)) { + fprintf(f, " thresh "); + for (i = 0; i < num_tins; i++) + tc_print_rate(PRINT_FP, NULL, " %12s", + rta_getattr_u64(GET_TSTAT(i, THRESHOLD_RATE64))); + fprintf(f, "%s", _SL_); + } + SPRINT_TSTAT(time, u32, " target ", TARGET_US); SPRINT_TSTAT(time, u32, " interval", INTERVAL_US); SPRINT_TSTAT(time, u32, " pk_delay", PEAK_DELAY_US); diff --git a/tc/q_cbq.c b/tc/q_cbq.c index 6518ef46..4619a37b 100644 --- a/tc/q_cbq.c +++ b/tc/q_cbq.c @@ -497,10 +497,7 @@ static int cbq_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) } if (r) { - char buf[64]; - - print_rate(buf, sizeof(buf), r->rate); - fprintf(f, "rate %s ", buf); + tc_print_rate(PRINT_FP, NULL, "rate %s ", r->rate); linklayer = (r->linklayer & TC_LINKLAYER_MASK); if (linklayer > TC_LINKLAYER_ETHERNET || show_details) fprintf(f, "linklayer %s ", sprint_linklayer(linklayer, b2)); @@ -533,13 +530,10 @@ static int cbq_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) else fprintf(f, "prio no-transmit"); if (show_details) { - char buf[64]; - fprintf(f, "/%u ", wrr->cpriority); - if (wrr->weight != 1) { - print_rate(buf, sizeof(buf), wrr->weight); - fprintf(f, "weight %s ", buf); - } + if (wrr->weight != 1) + tc_print_rate(PRINT_FP, NULL, "weight %s ", + wrr->weight); if (wrr->allot) fprintf(f, "allot %ub ", wrr->allot); } diff --git a/tc/q_drr.c b/tc/q_drr.c index f9c90f30..4e829ce3 100644 --- a/tc/q_drr.c +++ b/tc/q_drr.c @@ -84,16 +84,14 @@ static int drr_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) { struct rtattr *tb[TCA_DRR_MAX + 1]; - SPRINT_BUF(b1); - if (opt == NULL) return 0; parse_rtattr_nested(tb, TCA_DRR_MAX, opt); if (tb[TCA_DRR_QUANTUM]) - fprintf(f, "quantum %s ", - sprint_size(rta_getattr_u32(tb[TCA_DRR_QUANTUM]), b1)); + print_size(PRINT_FP, NULL, "quantum %s ", + rta_getattr_u32(tb[TCA_DRR_QUANTUM])); return 0; } @@ -101,15 +99,13 @@ static int drr_print_xstats(struct qdisc_util *qu, FILE *f, struct rtattr *xstat { struct tc_drr_stats *x; - SPRINT_BUF(b1); - if (xstats == NULL) return 0; if (RTA_PAYLOAD(xstats) < sizeof(*x)) return -1; x = RTA_DATA(xstats); - fprintf(f, " deficit %s ", sprint_size(x->deficit, b1)); + print_size(PRINT_FP, NULL, " deficit %s ", x->deficit); return 0; } diff --git a/tc/q_fifo.c b/tc/q_fifo.c index 61493fbb..ce82e74d 100644 --- a/tc/q_fifo.c +++ b/tc/q_fifo.c @@ -67,14 +67,10 @@ static int fifo_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) if (RTA_PAYLOAD(opt) < sizeof(*qopt)) return -1; qopt = RTA_DATA(opt); - if (strcmp(qu->id, "bfifo") == 0) { - SPRINT_BUF(b1); - print_uint(PRINT_JSON, "limit", NULL, qopt->limit); - print_string(PRINT_FP, NULL, "limit %s", - sprint_size(qopt->limit, b1)); - } else { + if (strcmp(qu->id, "bfifo") == 0) + print_size(PRINT_ANY, "limit", "limit %s", qopt->limit); + else print_uint(PRINT_ANY, "limit", "limit %up", qopt->limit); - } return 0; } diff --git a/tc/q_fq.c b/tc/q_fq.c index b10d01e9..cff21975 100644 --- a/tc/q_fq.c +++ b/tc/q_fq.c @@ -315,47 +315,37 @@ static int fq_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) if (tb[TCA_FQ_QUANTUM] && RTA_PAYLOAD(tb[TCA_FQ_QUANTUM]) >= sizeof(__u32)) { quantum = rta_getattr_u32(tb[TCA_FQ_QUANTUM]); - print_uint(PRINT_JSON, "quantum", NULL, quantum); - print_string(PRINT_FP, NULL, "quantum %s ", - sprint_size(quantum, b1)); + print_size(PRINT_ANY, "quantum", "quantum %s ", quantum); } if (tb[TCA_FQ_INITIAL_QUANTUM] && RTA_PAYLOAD(tb[TCA_FQ_INITIAL_QUANTUM]) >= sizeof(__u32)) { quantum = rta_getattr_u32(tb[TCA_FQ_INITIAL_QUANTUM]); - print_uint(PRINT_JSON, "initial_quantum", NULL, quantum); - print_string(PRINT_FP, NULL, "initial_quantum %s ", - sprint_size(quantum, b1)); + print_size(PRINT_ANY, "initial_quantum", "initial_quantum %s ", + quantum); } if (tb[TCA_FQ_FLOW_MAX_RATE] && RTA_PAYLOAD(tb[TCA_FQ_FLOW_MAX_RATE]) >= sizeof(__u32)) { rate = rta_getattr_u32(tb[TCA_FQ_FLOW_MAX_RATE]); - if (rate != ~0U) { - print_uint(PRINT_JSON, "maxrate", NULL, rate); - print_string(PRINT_FP, NULL, "maxrate %s ", - sprint_rate(rate, b1)); - } + if (rate != ~0U) + tc_print_rate(PRINT_ANY, + "maxrate", "maxrate %s ", rate); } if (tb[TCA_FQ_FLOW_DEFAULT_RATE] && RTA_PAYLOAD(tb[TCA_FQ_FLOW_DEFAULT_RATE]) >= sizeof(__u32)) { rate = rta_getattr_u32(tb[TCA_FQ_FLOW_DEFAULT_RATE]); - if (rate != 0) { - print_uint(PRINT_JSON, "defrate", NULL, rate); - print_string(PRINT_FP, NULL, "defrate %s ", - sprint_rate(rate, b1)); - } + if (rate != 0) + tc_print_rate(PRINT_ANY, + "defrate", "defrate %s ", rate); } if (tb[TCA_FQ_LOW_RATE_THRESHOLD] && RTA_PAYLOAD(tb[TCA_FQ_LOW_RATE_THRESHOLD]) >= sizeof(__u32)) { rate = rta_getattr_u32(tb[TCA_FQ_LOW_RATE_THRESHOLD]); - if (rate != 0) { - print_uint(PRINT_JSON, "low_rate_threshold", NULL, - rate); - print_string(PRINT_FP, NULL, "low_rate_threshold %s ", - sprint_rate(rate, b1)); - } + if (rate != 0) + tc_print_rate(PRINT_ANY, "low_rate_threshold", + "low_rate_threshold %s ", rate); } if (tb[TCA_FQ_FLOW_REFILL_DELAY] && RTA_PAYLOAD(tb[TCA_FQ_FLOW_REFILL_DELAY]) >= sizeof(__u32)) { diff --git a/tc/q_fq_codel.c b/tc/q_fq_codel.c index 1a51302e..30098065 100644 --- a/tc/q_fq_codel.c +++ b/tc/q_fq_codel.c @@ -221,9 +221,8 @@ static int fq_codel_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt if (tb[TCA_FQ_CODEL_MEMORY_LIMIT] && RTA_PAYLOAD(tb[TCA_FQ_CODEL_MEMORY_LIMIT]) >= sizeof(__u32)) { memory_limit = rta_getattr_u32(tb[TCA_FQ_CODEL_MEMORY_LIMIT]); - print_uint(PRINT_JSON, "memory_limit", NULL, memory_limit); - print_string(PRINT_FP, NULL, "memory_limit %s ", - sprint_size(memory_limit, b1)); + print_size(PRINT_ANY, "memory_limit", "memory_limit %s ", + memory_limit); } if (tb[TCA_FQ_CODEL_ECN] && RTA_PAYLOAD(tb[TCA_FQ_CODEL_ECN]) >= sizeof(__u32)) { diff --git a/tc/q_fq_pie.c b/tc/q_fq_pie.c index c136cd1a..9cbef47e 100644 --- a/tc/q_fq_pie.c +++ b/tc/q_fq_pie.c @@ -232,16 +232,13 @@ static int fq_pie_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) if (tb[TCA_FQ_PIE_QUANTUM] && RTA_PAYLOAD(tb[TCA_FQ_PIE_QUANTUM]) >= sizeof(__u32)) { quantum = rta_getattr_u32(tb[TCA_FQ_PIE_QUANTUM]); - print_uint(PRINT_JSON, "quantum", NULL, quantum); - print_string(PRINT_FP, NULL, "quantum %s ", - sprint_size(quantum, b1)); + print_size(PRINT_ANY, "quantum", "quantum %s ", quantum); } if (tb[TCA_FQ_PIE_MEMORY_LIMIT] && RTA_PAYLOAD(tb[TCA_FQ_PIE_MEMORY_LIMIT]) >= sizeof(__u32)) { memory_limit = rta_getattr_u32(tb[TCA_FQ_PIE_MEMORY_LIMIT]); - print_uint(PRINT_JSON, "memory_limit", NULL, memory_limit); - print_string(PRINT_FP, NULL, "memory_limit %s ", - sprint_size(memory_limit, b1)); + print_size(PRINT_ANY, "memory_limit", "memory_limit %s ", + memory_limit); } if (tb[TCA_FQ_PIE_ECN_PROB] && RTA_PAYLOAD(tb[TCA_FQ_PIE_ECN_PROB]) >= sizeof(__u32)) { diff --git a/tc/q_gred.c b/tc/q_gred.c index 8a1cecff..89aeb086 100644 --- a/tc/q_gred.c +++ b/tc/q_gred.c @@ -373,18 +373,11 @@ gred_print_stats(struct tc_gred_info *info, struct tc_gred_qopt *qopt) { __u64 bytes = info ? info->bytes : qopt->bytesin; - SPRINT_BUF(b1); - if (!is_json_context()) printf("\n Queue size: "); - print_uint(PRINT_JSON, "qave", NULL, qopt->qave); - print_string(PRINT_FP, NULL, "average %s ", - sprint_size(qopt->qave, b1)); - - print_uint(PRINT_JSON, "backlog", NULL, qopt->backlog); - print_string(PRINT_FP, NULL, "current %s ", - sprint_size(qopt->backlog, b1)); + print_size(PRINT_ANY, "qave", "average %s ", qopt->qave); + print_size(PRINT_ANY, "backlog", "current %s ", qopt->backlog); if (!is_json_context()) printf("\n Dropped packets: "); @@ -415,9 +408,7 @@ gred_print_stats(struct tc_gred_info *info, struct tc_gred_qopt *qopt) printf("\n Total packets: "); print_uint(PRINT_ANY, "packets", "%u ", qopt->packets); - - print_uint(PRINT_JSON, "bytes", NULL, bytes); - print_string(PRINT_FP, NULL, "(%s) ", sprint_size(bytes, b1)); + print_size(PRINT_ANY, "bytes", "(%s) ", bytes); } static int gred_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) @@ -431,8 +422,6 @@ static int gred_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) __u32 *limit = NULL; unsigned int i; - SPRINT_BUF(b1); - if (opt == NULL) return 0; @@ -470,11 +459,8 @@ static int gred_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) else print_bool(PRINT_ANY, "grio", NULL, false); - if (limit) { - print_uint(PRINT_JSON, "limit", NULL, *limit); - print_string(PRINT_FP, NULL, "limit %s ", - sprint_size(*limit, b1)); - } + if (limit) + print_size(PRINT_ANY, "limit", "limit %s ", *limit); tc_red_print_flags(sopt->flags); @@ -487,18 +473,9 @@ static int gred_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) print_uint(PRINT_ANY, "vq", "\n vq %u ", qopt->DP); print_hhu(PRINT_ANY, "prio", "prio %hhu ", qopt->prio); - - print_uint(PRINT_JSON, "limit", NULL, qopt->limit); - print_string(PRINT_FP, NULL, "limit %s ", - sprint_size(qopt->limit, b1)); - - print_uint(PRINT_JSON, "min", NULL, qopt->qth_min); - print_string(PRINT_FP, NULL, "min %s ", - sprint_size(qopt->qth_min, b1)); - - print_uint(PRINT_JSON, "max", NULL, qopt->qth_max); - print_string(PRINT_FP, NULL, "max %s ", - sprint_size(qopt->qth_max, b1)); + print_size(PRINT_ANY, "limit", "limit %s ", qopt->limit); + print_size(PRINT_ANY, "min", "min %s ", qopt->qth_min); + print_size(PRINT_ANY, "max", "max %s ", qopt->qth_max); if (infos[i].flags_present) tc_red_print_flags(infos[i].flags); diff --git a/tc/q_hfsc.c b/tc/q_hfsc.c index f34b1b2f..81c10210 100644 --- a/tc/q_hfsc.c +++ b/tc/q_hfsc.c @@ -219,9 +219,9 @@ hfsc_print_sc(FILE *f, char *name, struct tc_service_curve *sc) SPRINT_BUF(b1); fprintf(f, "%s ", name); - fprintf(f, "m1 %s ", sprint_rate(sc->m1, b1)); + tc_print_rate(PRINT_FP, NULL, "m1 %s ", sc->m1); fprintf(f, "d %s ", sprint_time(tc_core_ktime2time(sc->d), b1)); - fprintf(f, "m2 %s ", sprint_rate(sc->m2, b1)); + tc_print_rate(PRINT_FP, NULL, "m2 %s ", sc->m2); } static int diff --git a/tc/q_hhf.c b/tc/q_hhf.c index f8888011..95e49f3d 100644 --- a/tc/q_hhf.c +++ b/tc/q_hhf.c @@ -143,9 +143,7 @@ static int hhf_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) if (tb[TCA_HHF_QUANTUM] && RTA_PAYLOAD(tb[TCA_HHF_QUANTUM]) >= sizeof(__u32)) { quantum = rta_getattr_u32(tb[TCA_HHF_QUANTUM]); - print_uint(PRINT_JSON, "quantum", NULL, quantum); - print_string(PRINT_FP, NULL, "quantum %s ", - sprint_size(quantum, b1)); + print_size(PRINT_ANY, "quantum", "quantum %s ", quantum); } if (tb[TCA_HHF_HH_FLOWS_LIMIT] && RTA_PAYLOAD(tb[TCA_HHF_HH_FLOWS_LIMIT]) >= sizeof(__u32)) { @@ -162,9 +160,8 @@ static int hhf_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) if (tb[TCA_HHF_ADMIT_BYTES] && RTA_PAYLOAD(tb[TCA_HHF_ADMIT_BYTES]) >= sizeof(__u32)) { admit_bytes = rta_getattr_u32(tb[TCA_HHF_ADMIT_BYTES]); - print_uint(PRINT_JSON, "admit_bytes", NULL, admit_bytes); - print_string(PRINT_FP, NULL, "admit_bytes %s ", - sprint_size(admit_bytes, b1)); + print_size(PRINT_ANY, "admit_bytes", "admit_bytes %s ", + admit_bytes); } if (tb[TCA_HHF_EVICT_TIMEOUT] && RTA_PAYLOAD(tb[TCA_HHF_EVICT_TIMEOUT]) >= sizeof(__u32)) { diff --git a/tc/q_htb.c b/tc/q_htb.c index 52052226..c609e974 100644 --- a/tc/q_htb.c +++ b/tc/q_htb.c @@ -269,7 +269,6 @@ static int htb_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) __u64 rate64, ceil64; SPRINT_BUF(b1); - SPRINT_BUF(b2); SPRINT_BUF(b3); if (opt == NULL) @@ -299,29 +298,27 @@ static int htb_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) RTA_PAYLOAD(tb[TCA_HTB_CEIL64]) >= sizeof(ceil64)) ceil64 = rta_getattr_u64(tb[TCA_HTB_CEIL64]); - fprintf(f, "rate %s ", sprint_rate(rate64, b1)); + tc_print_rate(PRINT_FP, NULL, "rate %s ", rate64); if (hopt->rate.overhead) fprintf(f, "overhead %u ", hopt->rate.overhead); buffer = tc_calc_xmitsize(rate64, hopt->buffer); - fprintf(f, "ceil %s ", sprint_rate(ceil64, b1)); + tc_print_rate(PRINT_FP, NULL, "ceil %s ", ceil64); cbuffer = tc_calc_xmitsize(ceil64, hopt->cbuffer); linklayer = (hopt->rate.linklayer & TC_LINKLAYER_MASK); if (linklayer > TC_LINKLAYER_ETHERNET || show_details) fprintf(f, "linklayer %s ", sprint_linklayer(linklayer, b3)); if (show_details) { - fprintf(f, "burst %s/%u mpu %s ", - sprint_size(buffer, b1), - 1<rate.cell_log, - sprint_size(hopt->rate.mpu, b2)); - fprintf(f, "cburst %s/%u mpu %s ", - sprint_size(cbuffer, b1), - 1<ceil.cell_log, - sprint_size(hopt->ceil.mpu, b2)); + print_size(PRINT_FP, NULL, "burst %s/", buffer); + fprintf(f, "%u ", 1<rate.cell_log); + print_size(PRINT_FP, NULL, "mpu %s ", hopt->rate.mpu); + print_size(PRINT_FP, NULL, "cburst %s/", cbuffer); + fprintf(f, "%u ", 1<ceil.cell_log); + print_size(PRINT_FP, NULL, "mpu %s ", hopt->ceil.mpu); fprintf(f, "level %d ", (int)hopt->level); } else { - fprintf(f, "burst %s ", sprint_size(buffer, b1)); - fprintf(f, "cburst %s ", sprint_size(cbuffer, b1)); + print_size(PRINT_FP, NULL, "burst %s ", buffer); + print_size(PRINT_FP, NULL, "cburst %s ", cbuffer); } if (show_raw) fprintf(f, "buffer [%08x] cbuffer [%08x] ", diff --git a/tc/q_mqprio.c b/tc/q_mqprio.c index 5499f621..706452d0 100644 --- a/tc/q_mqprio.c +++ b/tc/q_mqprio.c @@ -230,8 +230,6 @@ static int mqprio_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) __u64 max_rate64[TC_QOPT_MAX_QUEUE] = {0}; int len; - SPRINT_BUF(b1); - if (opt == NULL) return 0; @@ -295,7 +293,7 @@ static int mqprio_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) } open_json_array(PRINT_ANY, is_json_context() ? "min_rate" : " min_rate:"); for (i = 0; i < qopt->num_tc; i++) - print_string(PRINT_ANY, NULL, "%s ", sprint_rate(min_rate64[i], b1)); + tc_print_rate(PRINT_ANY, NULL, "%s ", min_rate64[i]); close_json_array(PRINT_ANY, ""); } @@ -312,7 +310,7 @@ static int mqprio_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) } open_json_array(PRINT_ANY, is_json_context() ? "max_rate" : " max_rate:"); for (i = 0; i < qopt->num_tc; i++) - print_string(PRINT_ANY, NULL, "%s ", sprint_rate(max_rate64[i], b1)); + tc_print_rate(PRINT_ANY, NULL, "%s ", max_rate64[i]); close_json_array(PRINT_ANY, ""); } } diff --git a/tc/q_netem.c b/tc/q_netem.c index d01450fc..d93e1c73 100644 --- a/tc/q_netem.c +++ b/tc/q_netem.c @@ -800,9 +800,7 @@ static int netem_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) if (rate && rate->rate) { open_json_object("rate"); rate64 = rate64 ? : rate->rate; - print_string(PRINT_FP, NULL, " rate %s", - sprint_rate(rate64, b1)); - print_lluint(PRINT_JSON, "rate", NULL, rate64); + tc_print_rate(PRINT_ANY, "rate", " rate %s", rate64); PRINT_INT_OPT("packetoverhead", rate->packet_overhead); print_uint(PRINT_ANY, "cellsize", rate->cell_size ? " cellsize %u" : "", diff --git a/tc/q_red.c b/tc/q_red.c index df788f8f..fd50d37d 100644 --- a/tc/q_red.c +++ b/tc/q_red.c @@ -192,10 +192,6 @@ static int red_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) struct tc_red_qopt *qopt; __u32 max_P = 0; - SPRINT_BUF(b1); - SPRINT_BUF(b2); - SPRINT_BUF(b3); - if (opt == NULL) return 0; @@ -217,12 +213,9 @@ static int red_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) qopt->flags = flags_bf->value; } - print_uint(PRINT_JSON, "limit", NULL, qopt->limit); - print_string(PRINT_FP, NULL, "limit %s ", sprint_size(qopt->limit, b1)); - print_uint(PRINT_JSON, "min", NULL, qopt->qth_min); - print_string(PRINT_FP, NULL, "min %s ", sprint_size(qopt->qth_min, b2)); - print_uint(PRINT_JSON, "max", NULL, qopt->qth_max); - print_string(PRINT_FP, NULL, "max %s ", sprint_size(qopt->qth_max, b3)); + print_size(PRINT_ANY, "limit", "limit %s ", qopt->limit); + print_size(PRINT_ANY, "min", "min %s ", qopt->qth_min); + print_size(PRINT_ANY, "max", "max %s ", qopt->qth_max); tc_red_print_flags(qopt->flags); diff --git a/tc/q_sfq.c b/tc/q_sfq.c index 2b9bbcd2..d04a440c 100644 --- a/tc/q_sfq.c +++ b/tc/q_sfq.c @@ -206,9 +206,6 @@ static int sfq_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) struct tc_sfq_qopt *qopt; struct tc_sfq_qopt_v1 *qopt_ext = NULL; - SPRINT_BUF(b1); - SPRINT_BUF(b2); - SPRINT_BUF(b3); if (opt == NULL) return 0; @@ -219,9 +216,7 @@ static int sfq_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) qopt = RTA_DATA(opt); print_uint(PRINT_ANY, "limit", "limit %up ", qopt->limit); - print_uint(PRINT_JSON, "quantum", NULL, qopt->quantum); - print_string(PRINT_FP, NULL, "quantum %s ", - sprint_size(qopt->quantum, b1)); + print_size(PRINT_ANY, "quantum", "quantum %s ", qopt->quantum); if (qopt_ext && qopt_ext->depth) print_uint(PRINT_ANY, "depth", "depth %u ", qopt_ext->depth); @@ -237,12 +232,8 @@ static int sfq_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) qopt->perturb_period); if (qopt_ext && qopt_ext->qth_min) { print_uint(PRINT_ANY, "ewma", "ewma %u ", qopt_ext->Wlog); - print_uint(PRINT_JSON, "min", NULL, qopt_ext->qth_min); - print_string(PRINT_FP, NULL, "min %s ", - sprint_size(qopt_ext->qth_min, b2)); - print_uint(PRINT_JSON, "max", NULL, qopt_ext->qth_max); - print_string(PRINT_FP, NULL, "max %s ", - sprint_size(qopt_ext->qth_max, b3)); + print_size(PRINT_ANY, "min", "min %s ", qopt_ext->qth_min); + print_size(PRINT_ANY, "max", "max %s ", qopt_ext->qth_max); print_float(PRINT_ANY, "probability", "probability %lg ", qopt_ext->max_P / pow(2, 32)); tc_red_print_flags(qopt_ext->flags); diff --git a/tc/q_tbf.c b/tc/q_tbf.c index 5135b1d6..4e5bf382 100644 --- a/tc/q_tbf.c +++ b/tc/q_tbf.c @@ -286,20 +286,15 @@ static int tbf_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) if (tb[TCA_TBF_RATE64] && RTA_PAYLOAD(tb[TCA_TBF_RATE64]) >= sizeof(rate64)) rate64 = rta_getattr_u64(tb[TCA_TBF_RATE64]); - print_u64(PRINT_JSON, "rate", NULL, rate64); - print_string(PRINT_FP, NULL, "rate %s ", sprint_rate(rate64, b1)); + tc_print_rate(PRINT_ANY, "rate", "rate %s ", rate64); buffer = tc_calc_xmitsize(rate64, qopt->buffer); if (show_details) { sprintf(b1, "%s/%u", sprint_size(buffer, b2), 1 << qopt->rate.cell_log); print_string(PRINT_ANY, "burst", "burst %s ", b1); - print_uint(PRINT_JSON, "mpu", NULL, qopt->rate.mpu); - print_string(PRINT_FP, NULL, "mpu %s ", - sprint_size(qopt->rate.mpu, b1)); + print_size(PRINT_ANY, "mpu", "mpu %s ", qopt->rate.mpu); } else { - print_u64(PRINT_JSON, "burst", NULL, buffer); - print_string(PRINT_FP, NULL, "burst %s ", - sprint_size(buffer, b1)); + print_size(PRINT_ANY, "burst", "burst %s ", buffer); } if (show_raw) print_hex(PRINT_ANY, "burst_raw", "[%08x] ", qopt->buffer); @@ -308,24 +303,18 @@ static int tbf_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) RTA_PAYLOAD(tb[TCA_TBF_PRATE64]) >= sizeof(prate64)) prate64 = rta_getattr_u64(tb[TCA_TBF_PRATE64]); if (prate64) { - print_u64(PRINT_JSON, "peakrate", NULL, prate64); - print_string(PRINT_FP, NULL, "peakrate %s ", - sprint_rate(prate64, b1)); + tc_print_rate(PRINT_FP, "peakrate", "peakrate %s ", prate64); if (qopt->mtu || qopt->peakrate.mpu) { mtu = tc_calc_xmitsize(prate64, qopt->mtu); if (show_details) { sprintf(b1, "%s/%u", sprint_size(mtu, b2), 1 << qopt->peakrate.cell_log); print_string(PRINT_ANY, "mtu", "mtu %s ", b1); - print_uint(PRINT_JSON, "mpu", NULL, + print_size(PRINT_ANY, "mpu", "mpu %s ", qopt->peakrate.mpu); - print_string(PRINT_FP, NULL, "mpu %s ", - sprint_size(qopt->peakrate.mpu, - b1)); } else { - print_u64(PRINT_JSON, "minburst", NULL, mtu); - print_string(PRINT_FP, NULL, "minburst %s ", - sprint_size(mtu, b1)); + print_size(PRINT_ANY, "minburst", + "minburst %s ", mtu); } if (show_raw) print_hex(PRINT_ANY, "mtu_raw", "[%08x] ", @@ -347,11 +336,8 @@ static int tbf_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) print_string(PRINT_FP, NULL, "lat %s ", sprint_time(latency, b1)); } - if (show_raw || latency < 0.0) { - print_uint(PRINT_JSON, "limit", NULL, qopt->limit); - print_string(PRINT_FP, NULL, "limit %s ", - sprint_size(qopt->limit, b1)); - } + if (show_raw || latency < 0.0) + print_size(PRINT_ANY, "limit", "limit %s ", qopt->limit); if (qopt->rate.overhead) print_int(PRINT_ANY, "overhead", "overhead %d ", qopt->rate.overhead); diff --git a/tc/tc_common.h b/tc/tc_common.h index 802fb7f0..58dc9d6a 100644 --- a/tc/tc_common.h +++ b/tc/tc_common.h @@ -27,3 +27,4 @@ int check_size_table_opts(struct tc_sizespec *s); extern int show_graph; extern bool use_names; +extern int use_iec; diff --git a/tc/tc_util.c b/tc/tc_util.c index b7ff911b..48065897 100644 --- a/tc/tc_util.c +++ b/tc/tc_util.c @@ -164,32 +164,6 @@ char *sprint_tc_classid(__u32 h, char *buf) return buf; } -/* See http://physics.nist.gov/cuu/Units/binary.html */ -static const struct rate_suffix { - const char *name; - double scale; -} suffixes[] = { - { "bit", 1. }, - { "Kibit", 1024. }, - { "kbit", 1000. }, - { "mibit", 1024.*1024. }, - { "mbit", 1000000. }, - { "gibit", 1024.*1024.*1024. }, - { "gbit", 1000000000. }, - { "tibit", 1024.*1024.*1024.*1024. }, - { "tbit", 1000000000000. }, - { "Bps", 8. }, - { "KiBps", 8.*1024. }, - { "KBps", 8000. }, - { "MiBps", 8.*1024*1024. }, - { "MBps", 8000000. }, - { "GiBps", 8.*1024.*1024.*1024. }, - { "GBps", 8000000000. }, - { "TiBps", 8.*1024.*1024.*1024.*1024. }, - { "TBps", 8000000000000. }, - { NULL } -}; - /* Parse a percent e.g: '30%' * return: 0 = ok, -1 = error, 1 = out of range */ @@ -273,84 +247,10 @@ int get_percent_rate64(__u64 *rate, const char *str, const char *dev) return get_rate64(rate, r_str); } -int get_rate(unsigned int *rate, const char *str) +void tc_print_rate(enum output_type t, const char *key, const char *fmt, + unsigned long long rate) { - char *p; - double bps = strtod(str, &p); - const struct rate_suffix *s; - - if (p == str) - return -1; - - for (s = suffixes; s->name; ++s) { - if (strcasecmp(s->name, p) == 0) { - bps *= s->scale; - p += strlen(p); - break; - } - } - - if (*p) - return -1; /* unknown suffix */ - - bps /= 8; /* -> bytes per second */ - *rate = bps; - /* detect if an overflow happened */ - if (*rate != floor(bps)) - return -1; - return 0; -} - -int get_rate64(__u64 *rate, const char *str) -{ - char *p; - double bps = strtod(str, &p); - const struct rate_suffix *s; - - if (p == str) - return -1; - - for (s = suffixes; s->name; ++s) { - if (strcasecmp(s->name, p) == 0) { - bps *= s->scale; - p += strlen(p); - break; - } - } - - if (*p) - return -1; /* unknown suffix */ - - bps /= 8; /* -> bytes per second */ - *rate = bps; - return 0; -} - -void print_rate(char *buf, int len, __u64 rate) -{ - extern int use_iec; - unsigned long kilo = use_iec ? 1024 : 1000; - const char *str = use_iec ? "i" : ""; - static char *units[5] = {"", "K", "M", "G", "T"}; - int i; - - rate <<= 3; /* bytes/sec -> bits/sec */ - - for (i = 0; i < ARRAY_SIZE(units) - 1; i++) { - if (rate < kilo) - break; - if (((rate % kilo) != 0) && rate < 1000*kilo) - break; - rate /= kilo; - } - - snprintf(buf, len, "%.0f%s%sbit", (double)rate, units[i], str); -} - -char *sprint_rate(__u64 rate, char *buf) -{ - print_rate(buf, SPRINT_BSIZE-1, rate); - return buf; + print_rate(use_iec, t, key, fmt, rate); } char *sprint_ticks(__u32 ticks, char *buf) @@ -358,41 +258,6 @@ char *sprint_ticks(__u32 ticks, char *buf) return sprint_time(tc_core_tick2time(ticks), buf); } -int get_size(unsigned int *size, const char *str) -{ - double sz; - char *p; - - sz = strtod(str, &p); - if (p == str) - return -1; - - if (*p) { - if (strcasecmp(p, "kb") == 0 || strcasecmp(p, "k") == 0) - sz *= 1024; - else if (strcasecmp(p, "gb") == 0 || strcasecmp(p, "g") == 0) - sz *= 1024*1024*1024; - else if (strcasecmp(p, "gbit") == 0) - sz *= 1024*1024*1024/8; - else if (strcasecmp(p, "mb") == 0 || strcasecmp(p, "m") == 0) - sz *= 1024*1024; - else if (strcasecmp(p, "mbit") == 0) - sz *= 1024*1024/8; - else if (strcasecmp(p, "kbit") == 0) - sz *= 1024/8; - else if (strcasecmp(p, "b") != 0) - return -1; - } - - *size = sz; - - /* detect if an overflow happened */ - if (*size != floor(sz)) - return -1; - - return 0; -} - int get_size_and_cell(unsigned int *size, int *cell_log, char *str) { char *slash = strchr(str, '/'); @@ -433,24 +298,6 @@ void print_devname(enum output_type type, int ifindex) "dev", "%s ", ifname); } -static void print_size(char *buf, int len, __u32 sz) -{ - double tmp = sz; - - if (sz >= 1024*1024 && fabs(1024*1024*rint(tmp/(1024*1024)) - sz) < 1024) - snprintf(buf, len, "%gMb", rint(tmp/(1024*1024))); - else if (sz >= 1024 && fabs(1024*rint(tmp/1024) - sz) < 16) - snprintf(buf, len, "%gKb", rint(tmp/1024)); - else - snprintf(buf, len, "%ub", sz); -} - -char *sprint_size(__u32 size, char *buf) -{ - print_size(buf, SPRINT_BSIZE-1, size); - return buf; -} - static const char *action_n2a(int action) { static char buf[64]; @@ -807,7 +654,6 @@ static void print_tcstats_basic_hw(struct rtattr **tbs, char *prefix) void print_tcstats2_attr(FILE *fp, struct rtattr *rta, char *prefix, struct rtattr **xstats) { - SPRINT_BUF(b1); struct rtattr *tbs[TCA_STATS_MAX + 1]; parse_rtattr_nested(tbs, TCA_STATS_MAX, rta); @@ -853,8 +699,7 @@ void print_tcstats2_attr(FILE *fp, struct rtattr *rta, char *prefix, struct rtat sizeof(re))); print_string(PRINT_FP, NULL, "\n%s", prefix); print_lluint(PRINT_JSON, "rate", NULL, re.bps); - print_string(PRINT_FP, NULL, "rate %s", - sprint_rate(re.bps, b1)); + tc_print_rate(PRINT_FP, NULL, "rate %s", re.bps); print_lluint(PRINT_ANY, "pps", " %llupps", re.pps); } else if (tbs[TCA_STATS_RATE_EST]) { struct gnet_stats_rate_est re = {0}; @@ -863,8 +708,7 @@ void print_tcstats2_attr(FILE *fp, struct rtattr *rta, char *prefix, struct rtat MIN(RTA_PAYLOAD(tbs[TCA_STATS_RATE_EST]), sizeof(re))); print_string(PRINT_FP, NULL, "\n%s", prefix); print_uint(PRINT_JSON, "rate", NULL, re.bps); - print_string(PRINT_FP, NULL, "rate %s", - sprint_rate(re.bps, b1)); + tc_print_rate(PRINT_FP, NULL, "rate %s", re.bps); print_uint(PRINT_ANY, "pps", " %upps", re.pps); } @@ -875,10 +719,8 @@ void print_tcstats2_attr(FILE *fp, struct rtattr *rta, char *prefix, struct rtat MIN(RTA_PAYLOAD(tbs[TCA_STATS_QUEUE]), sizeof(q))); if (!tbs[TCA_STATS_RATE_EST]) print_nl(); - print_uint(PRINT_JSON, "backlog", NULL, q.backlog); print_string(PRINT_FP, NULL, "%s", prefix); - print_string(PRINT_FP, NULL, "backlog %s", - sprint_size(q.backlog, b1)); + print_size(PRINT_ANY, "backlog", "backlog %s", q.backlog); print_uint(PRINT_ANY, "qlen", " %up", q.qlen); print_uint(PRINT_FP, NULL, " requeues %u", q.requeues); } @@ -890,8 +732,6 @@ void print_tcstats2_attr(FILE *fp, struct rtattr *rta, char *prefix, struct rtat 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 && !*xstats) @@ -916,16 +756,16 @@ void print_tcstats_attr(FILE *fp, struct rtattr *tb[], char *prefix, if (st.bps || st.pps) { fprintf(fp, "rate "); if (st.bps) - fprintf(fp, "%s ", - sprint_rate(st.bps, b1)); + tc_print_rate(PRINT_FP, NULL, "%s ", + st.bps); 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)); + print_size(PRINT_FP, NULL, "%s ", + st.backlog); if (st.qlen) fprintf(fp, "%up ", st.qlen); } diff --git a/tc/tc_util.h b/tc/tc_util.h index c8af4e95..b197bcdd 100644 --- a/tc/tc_util.h +++ b/tc/tc_util.h @@ -76,19 +76,15 @@ struct qdisc_util *get_qdisc_kind(const char *str); struct filter_util *get_filter_kind(const char *str); int get_qdisc_handle(__u32 *h, const char *str); -int get_rate(unsigned int *rate, const char *str); int get_percent_rate(unsigned int *rate, const char *str, const char *dev); -int get_rate64(__u64 *rate, const char *str); int get_percent_rate64(__u64 *rate, const char *str, const char *dev); -int get_size(unsigned int *size, const char *str); int get_size_and_cell(unsigned int *size, int *cell_log, char *str); int get_linklayer(unsigned int *val, const char *arg); -void print_rate(char *buf, int len, __u64 rate); +void tc_print_rate(enum output_type t, const char *key, const char *fmt, + unsigned long long rate); void print_devname(enum output_type type, int ifindex); -char *sprint_rate(__u64 rate, char *buf); -char *sprint_size(__u32 size, char *buf); char *sprint_tc_classid(__u32 h, char *buf); char *sprint_ticks(__u32 ticks, char *buf); char *sprint_linklayer(unsigned int linklayer, char *buf);