lib: Move print_rate() from tc here; modernize

The functions print_rate() and sprint_rate() are useful for formatting
rate-like values. The DCB tool would find these useful in the maxrate
subtool. However, the current interface to these functions uses a global
variable use_iec as a flag indicating whether 1024- or 1000-based powers
should be used when formatting the rate value. For general use, a global
variable is not a great way of passing arguments to a function. Besides, it
is unlike most other printing functions in that it deals in buffers and
ignores JSON.

Therefore make the interface to print_rate() explicit by converting use_iec
to an ordinary parameter. Since the interface changes anyway, convert it to
follow the pattern of other json_print functions (except for the
now-explicit use_iec parameter). Move to json_print.c.

Add a wrapper to tc, so that all the call sites do not need to repeat the
use_iec global variable argument, and convert all call sites.

In q_cake.c, the conversion is not straightforward due to usage of a macro
that is shared across numerous data types. Simply hand-roll the
corresponding code, which seems better than making an extra helper for one
call site.

Drop sprint_rate() now that everybody just uses print_rate().

Signed-off-by: Petr Machata <me@pmachata.org>
Signed-off-by: David Ahern <dsahern@gmail.com>
This commit is contained in:
Petr Machata 2020-12-05 22:13:30 +01:00 committed by David Ahern
parent cdd9425315
commit 60265cc226
13 changed files with 93 additions and 91 deletions

View File

@ -86,4 +86,14 @@ _PRINT_NAME_VALUE_FUNC(uint, unsigned int, u);
_PRINT_NAME_VALUE_FUNC(string, const char*, s); _PRINT_NAME_VALUE_FUNC(string, const char*, s);
#undef _PRINT_NAME_VALUE_FUNC #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);
}
#endif /* _JSON_PRINT_H_ */ #endif /* _JSON_PRINT_H_ */

View File

@ -308,3 +308,35 @@ void print_nl(void)
if (!_jw) if (!_jw)
printf("%s", _SL_); 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], str);
if (rc < 0)
return -1;
rc = print_color_string(type, color, key, fmt, buf);
free(buf);
return rc;
}

View File

@ -269,7 +269,7 @@ static int print_police(struct action_util *a, FILE *f, struct rtattr *arg)
rate64 = rta_getattr_u64(tb[TCA_POLICE_RATE64]); rate64 = rta_getattr_u64(tb[TCA_POLICE_RATE64]);
fprintf(f, " police 0x%x ", p->index); 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); buffer = tc_calc_xmitsize(rate64, p->burst);
fprintf(f, "burst %s ", sprint_size(buffer, b1)); fprintf(f, "burst %s ", sprint_size(buffer, b1));
fprintf(f, "mtu %s ", sprint_size(p->mtu, b1)); fprintf(f, "mtu %s ", sprint_size(p->mtu, b1));
@ -282,12 +282,11 @@ static int print_police(struct action_util *a, FILE *f, struct rtattr *arg)
prate64 = rta_getattr_u64(tb[TCA_POLICE_PEAKRATE64]); prate64 = rta_getattr_u64(tb[TCA_POLICE_PEAKRATE64]);
if (prate64) if (prate64)
fprintf(f, "peakrate %s ", sprint_rate(prate64, b1)); tc_print_rate(PRINT_FP, NULL, "peakrate %s ", prate64);
if (tb[TCA_POLICE_AVRATE]) if (tb[TCA_POLICE_AVRATE])
fprintf(f, "avrate %s ", tc_print_rate(PRINT_FP, NULL, "avrate %s ",
sprint_rate(rta_getattr_u32(tb[TCA_POLICE_AVRATE]), rta_getattr_u32(tb[TCA_POLICE_AVRATE]));
b1));
print_action_control(f, "action ", p->action, ""); print_action_control(f, "action ", p->action, "");

View File

@ -445,11 +445,10 @@ static int cake_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
if (tb[TCA_CAKE_BASE_RATE64] && if (tb[TCA_CAKE_BASE_RATE64] &&
RTA_PAYLOAD(tb[TCA_CAKE_BASE_RATE64]) >= sizeof(bandwidth)) { RTA_PAYLOAD(tb[TCA_CAKE_BASE_RATE64]) >= sizeof(bandwidth)) {
bandwidth = rta_getattr_u64(tb[TCA_CAKE_BASE_RATE64]); bandwidth = rta_getattr_u64(tb[TCA_CAKE_BASE_RATE64]);
if (bandwidth) { if (bandwidth)
print_uint(PRINT_JSON, "bandwidth", NULL, bandwidth); tc_print_rate(PRINT_ANY, "bandwidth", "bandwidth %s ",
print_string(PRINT_FP, NULL, "bandwidth %s ", bandwidth);
sprint_rate(bandwidth, b1)); else
} else
print_string(PRINT_ANY, "bandwidth", "bandwidth %s ", print_string(PRINT_ANY, "bandwidth", "bandwidth %s ",
"unlimited"); "unlimited");
} }
@ -650,12 +649,10 @@ static int cake_print_xstats(struct qdisc_util *qu, FILE *f,
GET_STAT_U32(MEMORY_LIMIT)); GET_STAT_U32(MEMORY_LIMIT));
} }
if (st[TCA_CAKE_STATS_CAPACITY_ESTIMATE64]) { if (st[TCA_CAKE_STATS_CAPACITY_ESTIMATE64])
print_string(PRINT_FP, NULL, " capacity estimate: %s\n", tc_print_rate(PRINT_ANY, "capacity_estimate",
sprint_rate(GET_STAT_U64(CAPACITY_ESTIMATE64), b1)); " capacity estimate: %s\n",
print_uint(PRINT_JSON, "capacity_estimate", NULL,
GET_STAT_U64(CAPACITY_ESTIMATE64)); GET_STAT_U64(CAPACITY_ESTIMATE64));
}
if (st[TCA_CAKE_STATS_MIN_NETLEN] && if (st[TCA_CAKE_STATS_MIN_NETLEN] &&
st[TCA_CAKE_STATS_MAX_NETLEN]) { st[TCA_CAKE_STATS_MAX_NETLEN]) {
@ -790,7 +787,14 @@ static int cake_print_xstats(struct qdisc_util *qu, FILE *f,
#define PRINT_TSTAT_U64(name, attr) PRINT_TSTAT( \ #define PRINT_TSTAT_U64(name, attr) PRINT_TSTAT( \
name, attr, "llu", rta_getattr_u64(GET_TSTAT(i, attr))) 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, " target ", TARGET_US);
SPRINT_TSTAT(time, u32, " interval", INTERVAL_US); SPRINT_TSTAT(time, u32, " interval", INTERVAL_US);
SPRINT_TSTAT(time, u32, " pk_delay", PEAK_DELAY_US); SPRINT_TSTAT(time, u32, " pk_delay", PEAK_DELAY_US);

View File

@ -497,10 +497,7 @@ static int cbq_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
} }
if (r) { if (r) {
char buf[64]; tc_print_rate(PRINT_FP, NULL, "rate %s ", r->rate);
print_rate(buf, sizeof(buf), r->rate);
fprintf(f, "rate %s ", buf);
linklayer = (r->linklayer & TC_LINKLAYER_MASK); linklayer = (r->linklayer & TC_LINKLAYER_MASK);
if (linklayer > TC_LINKLAYER_ETHERNET || show_details) if (linklayer > TC_LINKLAYER_ETHERNET || show_details)
fprintf(f, "linklayer %s ", sprint_linklayer(linklayer, b2)); 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 else
fprintf(f, "prio no-transmit"); fprintf(f, "prio no-transmit");
if (show_details) { if (show_details) {
char buf[64];
fprintf(f, "/%u ", wrr->cpriority); fprintf(f, "/%u ", wrr->cpriority);
if (wrr->weight != 1) { if (wrr->weight != 1)
print_rate(buf, sizeof(buf), wrr->weight); tc_print_rate(PRINT_FP, NULL, "weight %s ",
fprintf(f, "weight %s ", buf); wrr->weight);
}
if (wrr->allot) if (wrr->allot)
fprintf(f, "allot %ub ", wrr->allot); fprintf(f, "allot %ub ", wrr->allot);
} }

View File

@ -330,32 +330,25 @@ static int fq_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
RTA_PAYLOAD(tb[TCA_FQ_FLOW_MAX_RATE]) >= sizeof(__u32)) { RTA_PAYLOAD(tb[TCA_FQ_FLOW_MAX_RATE]) >= sizeof(__u32)) {
rate = rta_getattr_u32(tb[TCA_FQ_FLOW_MAX_RATE]); rate = rta_getattr_u32(tb[TCA_FQ_FLOW_MAX_RATE]);
if (rate != ~0U) { if (rate != ~0U)
print_uint(PRINT_JSON, "maxrate", NULL, rate); tc_print_rate(PRINT_ANY,
print_string(PRINT_FP, NULL, "maxrate %s ", "maxrate", "maxrate %s ", rate);
sprint_rate(rate, b1));
}
} }
if (tb[TCA_FQ_FLOW_DEFAULT_RATE] && if (tb[TCA_FQ_FLOW_DEFAULT_RATE] &&
RTA_PAYLOAD(tb[TCA_FQ_FLOW_DEFAULT_RATE]) >= sizeof(__u32)) { RTA_PAYLOAD(tb[TCA_FQ_FLOW_DEFAULT_RATE]) >= sizeof(__u32)) {
rate = rta_getattr_u32(tb[TCA_FQ_FLOW_DEFAULT_RATE]); rate = rta_getattr_u32(tb[TCA_FQ_FLOW_DEFAULT_RATE]);
if (rate != 0) { if (rate != 0)
print_uint(PRINT_JSON, "defrate", NULL, rate); tc_print_rate(PRINT_ANY,
print_string(PRINT_FP, NULL, "defrate %s ", "defrate", "defrate %s ", rate);
sprint_rate(rate, b1));
}
} }
if (tb[TCA_FQ_LOW_RATE_THRESHOLD] && if (tb[TCA_FQ_LOW_RATE_THRESHOLD] &&
RTA_PAYLOAD(tb[TCA_FQ_LOW_RATE_THRESHOLD]) >= sizeof(__u32)) { RTA_PAYLOAD(tb[TCA_FQ_LOW_RATE_THRESHOLD]) >= sizeof(__u32)) {
rate = rta_getattr_u32(tb[TCA_FQ_LOW_RATE_THRESHOLD]); rate = rta_getattr_u32(tb[TCA_FQ_LOW_RATE_THRESHOLD]);
if (rate != 0) { if (rate != 0)
print_uint(PRINT_JSON, "low_rate_threshold", NULL, tc_print_rate(PRINT_ANY, "low_rate_threshold",
rate); "low_rate_threshold %s ", rate);
print_string(PRINT_FP, NULL, "low_rate_threshold %s ",
sprint_rate(rate, b1));
}
} }
if (tb[TCA_FQ_FLOW_REFILL_DELAY] && if (tb[TCA_FQ_FLOW_REFILL_DELAY] &&
RTA_PAYLOAD(tb[TCA_FQ_FLOW_REFILL_DELAY]) >= sizeof(__u32)) { RTA_PAYLOAD(tb[TCA_FQ_FLOW_REFILL_DELAY]) >= sizeof(__u32)) {

View File

@ -219,9 +219,9 @@ hfsc_print_sc(FILE *f, char *name, struct tc_service_curve *sc)
SPRINT_BUF(b1); SPRINT_BUF(b1);
fprintf(f, "%s ", name); 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, "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 static int

View File

@ -299,12 +299,12 @@ static int htb_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
RTA_PAYLOAD(tb[TCA_HTB_CEIL64]) >= sizeof(ceil64)) RTA_PAYLOAD(tb[TCA_HTB_CEIL64]) >= sizeof(ceil64))
ceil64 = rta_getattr_u64(tb[TCA_HTB_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) if (hopt->rate.overhead)
fprintf(f, "overhead %u ", hopt->rate.overhead); fprintf(f, "overhead %u ", hopt->rate.overhead);
buffer = tc_calc_xmitsize(rate64, hopt->buffer); 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); cbuffer = tc_calc_xmitsize(ceil64, hopt->cbuffer);
linklayer = (hopt->rate.linklayer & TC_LINKLAYER_MASK); linklayer = (hopt->rate.linklayer & TC_LINKLAYER_MASK);
if (linklayer > TC_LINKLAYER_ETHERNET || show_details) if (linklayer > TC_LINKLAYER_ETHERNET || show_details)

View File

@ -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}; __u64 max_rate64[TC_QOPT_MAX_QUEUE] = {0};
int len; int len;
SPRINT_BUF(b1);
if (opt == NULL) if (opt == NULL)
return 0; 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:"); open_json_array(PRINT_ANY, is_json_context() ? "min_rate" : " min_rate:");
for (i = 0; i < qopt->num_tc; i++) 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, ""); 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:"); open_json_array(PRINT_ANY, is_json_context() ? "max_rate" : " max_rate:");
for (i = 0; i < qopt->num_tc; i++) 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, ""); close_json_array(PRINT_ANY, "");
} }
} }

View File

@ -800,9 +800,7 @@ static int netem_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
if (rate && rate->rate) { if (rate && rate->rate) {
open_json_object("rate"); open_json_object("rate");
rate64 = rate64 ? : rate->rate; rate64 = rate64 ? : rate->rate;
print_string(PRINT_FP, NULL, " rate %s", tc_print_rate(PRINT_ANY, "rate", " rate %s", rate64);
sprint_rate(rate64, b1));
print_lluint(PRINT_JSON, "rate", NULL, rate64);
PRINT_INT_OPT("packetoverhead", rate->packet_overhead); PRINT_INT_OPT("packetoverhead", rate->packet_overhead);
print_uint(PRINT_ANY, "cellsize", print_uint(PRINT_ANY, "cellsize",
rate->cell_size ? " cellsize %u" : "", rate->cell_size ? " cellsize %u" : "",

View File

@ -286,8 +286,7 @@ static int tbf_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
if (tb[TCA_TBF_RATE64] && if (tb[TCA_TBF_RATE64] &&
RTA_PAYLOAD(tb[TCA_TBF_RATE64]) >= sizeof(rate64)) RTA_PAYLOAD(tb[TCA_TBF_RATE64]) >= sizeof(rate64))
rate64 = rta_getattr_u64(tb[TCA_TBF_RATE64]); rate64 = rta_getattr_u64(tb[TCA_TBF_RATE64]);
print_u64(PRINT_JSON, "rate", NULL, rate64); tc_print_rate(PRINT_ANY, "rate", "rate %s ", rate64);
print_string(PRINT_FP, NULL, "rate %s ", sprint_rate(rate64, b1));
buffer = tc_calc_xmitsize(rate64, qopt->buffer); buffer = tc_calc_xmitsize(rate64, qopt->buffer);
if (show_details) { if (show_details) {
sprintf(b1, "%s/%u", sprint_size(buffer, b2), sprintf(b1, "%s/%u", sprint_size(buffer, b2),
@ -308,9 +307,7 @@ static int tbf_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
RTA_PAYLOAD(tb[TCA_TBF_PRATE64]) >= sizeof(prate64)) RTA_PAYLOAD(tb[TCA_TBF_PRATE64]) >= sizeof(prate64))
prate64 = rta_getattr_u64(tb[TCA_TBF_PRATE64]); prate64 = rta_getattr_u64(tb[TCA_TBF_PRATE64]);
if (prate64) { if (prate64) {
print_u64(PRINT_JSON, "peakrate", NULL, prate64); tc_print_rate(PRINT_FP, "peakrate", "peakrate %s ", prate64);
print_string(PRINT_FP, NULL, "peakrate %s ",
sprint_rate(prate64, b1));
if (qopt->mtu || qopt->peakrate.mpu) { if (qopt->mtu || qopt->peakrate.mpu) {
mtu = tc_calc_xmitsize(prate64, qopt->mtu); mtu = tc_calc_xmitsize(prate64, qopt->mtu);
if (show_details) { if (show_details) {

View File

@ -326,31 +326,10 @@ int get_rate64(__u64 *rate, const char *str)
return 0; return 0;
} }
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)
{ {
extern int use_iec; print_rate(use_iec, t, key, fmt, rate);
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;
} }
char *sprint_ticks(__u32 ticks, char *buf) char *sprint_ticks(__u32 ticks, char *buf)
@ -853,8 +832,7 @@ void print_tcstats2_attr(FILE *fp, struct rtattr *rta, char *prefix, struct rtat
sizeof(re))); sizeof(re)));
print_string(PRINT_FP, NULL, "\n%s", prefix); print_string(PRINT_FP, NULL, "\n%s", prefix);
print_lluint(PRINT_JSON, "rate", NULL, re.bps); print_lluint(PRINT_JSON, "rate", NULL, re.bps);
print_string(PRINT_FP, NULL, "rate %s", tc_print_rate(PRINT_FP, NULL, "rate %s", re.bps);
sprint_rate(re.bps, b1));
print_lluint(PRINT_ANY, "pps", " %llupps", re.pps); print_lluint(PRINT_ANY, "pps", " %llupps", re.pps);
} else if (tbs[TCA_STATS_RATE_EST]) { } else if (tbs[TCA_STATS_RATE_EST]) {
struct gnet_stats_rate_est re = {0}; struct gnet_stats_rate_est re = {0};
@ -863,8 +841,7 @@ void print_tcstats2_attr(FILE *fp, struct rtattr *rta, char *prefix, struct rtat
MIN(RTA_PAYLOAD(tbs[TCA_STATS_RATE_EST]), sizeof(re))); MIN(RTA_PAYLOAD(tbs[TCA_STATS_RATE_EST]), sizeof(re)));
print_string(PRINT_FP, NULL, "\n%s", prefix); print_string(PRINT_FP, NULL, "\n%s", prefix);
print_uint(PRINT_JSON, "rate", NULL, re.bps); print_uint(PRINT_JSON, "rate", NULL, re.bps);
print_string(PRINT_FP, NULL, "rate %s", tc_print_rate(PRINT_FP, NULL, "rate %s", re.bps);
sprint_rate(re.bps, b1));
print_uint(PRINT_ANY, "pps", " %upps", re.pps); print_uint(PRINT_ANY, "pps", " %upps", re.pps);
} }
@ -916,8 +893,8 @@ void print_tcstats_attr(FILE *fp, struct rtattr *tb[], char *prefix,
if (st.bps || st.pps) { if (st.bps || st.pps) {
fprintf(fp, "rate "); fprintf(fp, "rate ");
if (st.bps) if (st.bps)
fprintf(fp, "%s ", tc_print_rate(PRINT_FP, NULL, "%s ",
sprint_rate(st.bps, b1)); st.bps);
if (st.pps) if (st.pps)
fprintf(fp, "%upps ", st.pps); fprintf(fp, "%upps ", st.pps);
} }

View File

@ -84,10 +84,10 @@ int get_size(unsigned int *size, const char *str);
int get_size_and_cell(unsigned int *size, int *cell_log, char *str); int get_size_and_cell(unsigned int *size, int *cell_log, char *str);
int get_linklayer(unsigned int *val, const char *arg); 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); 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_size(__u32 size, char *buf);
char *sprint_tc_classid(__u32 h, char *buf); char *sprint_tc_classid(__u32 h, char *buf);
char *sprint_ticks(__u32 ticks, char *buf); char *sprint_ticks(__u32 ticks, char *buf);