From: Stephen Hemminger <sthem...@microsoft.com> Output queue options in JSON if requested.
Signed-off-by: Stephen Hemminger <step...@networkplumber.org> --- tc/q_mqprio.c | 134 +++++++++++++++++++++++++++----------------------- 1 file changed, 72 insertions(+), 62 deletions(-) diff --git a/tc/q_mqprio.c b/tc/q_mqprio.c index 207d6441d8fa..3d78f9cec996 100644 --- a/tc/q_mqprio.c +++ b/tc/q_mqprio.c @@ -213,15 +213,37 @@ static int mqprio_parse_opt(struct qdisc_util *qu, int argc, return 0; } +static void print_rate_table(const struct tc_mqprio_qopt *qopt, + const struct rtattr *tbl, + const char *key, unsigned short type) +{ + __u64 rate64[TC_QOPT_MAX_QUEUE] = { 0 }; + unsigned int rem = RTA_PAYLOAD(tbl); + const struct rtattr *r; + int i = 0; + + for (r = RTA_DATA(tbl); RTA_OK(r, rem); r = RTA_NEXT(r, rem)) { + if (r->rta_type != type) { + fprintf(stderr, "invalid rate table response\n"); + return; + } + if (i == TC_QOPT_MAX_QUEUE) + break; + rate64[i++] = rta_getattr_u64(r); + } + + print_string(PRINT_FP, NULL, " %s:", key); + open_json_array(PRINT_JSON, key); + for (i = 0; i < qopt->num_tc; i++) + print_rate(NULL, "%s ", rate64[i]); + close_json_array(PRINT_JSON, ""); +} + static int mqprio_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) { - int i; struct tc_mqprio_qopt *qopt; - __u64 min_rate64[TC_QOPT_MAX_QUEUE] = {0}; - __u64 max_rate64[TC_QOPT_MAX_QUEUE] = {0}; - int len; - - SPRINT_BUF(b1); + struct rtattr *tb[TCA_MQPRIO_MAX + 1]; + int i, len; if (opt == NULL) return 0; @@ -234,71 +256,59 @@ static int mqprio_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) qopt = RTA_DATA(opt); - fprintf(f, " tc %u map ", qopt->num_tc); - for (i = 0; i <= TC_PRIO_MAX; i++) - fprintf(f, "%u ", qopt->prio_tc_map[i]); - fprintf(f, "\n queues:"); - for (i = 0; i < qopt->num_tc; i++) - fprintf(f, "(%u:%u) ", qopt->offset[i], - qopt->offset[i] + qopt->count[i] - 1); + print_uint(PRINT_ANY, "num_tc", + " tc %u map ", qopt->num_tc); - if (len > 0) { - struct rtattr *tb[TCA_MQPRIO_MAX + 1]; - - parse_rtattr(tb, TCA_MQPRIO_MAX, - RTA_DATA(opt) + RTA_ALIGN(sizeof(*qopt)), - len); + open_json_array(PRINT_JSON, "priomap"); + for (i = 0; i <= TC_PRIO_MAX; i++) + print_uint(PRINT_ANY, NULL, "%u ", qopt->prio_tc_map[i]); + close_json_array(PRINT_JSON, ""); + + print_string(PRINT_FP, NULL, "%s queues:", _SL_); + open_json_array(PRINT_JSON, "queues"); + for (i = 0; i < qopt->num_tc; i++) { + open_json_object(NULL); + print_uint(PRINT_ANY, "offset", "(%u", qopt->offset[i]); + print_uint(PRINT_ANY, "length", ":%u) ", + qopt->offset[i] + qopt->count[i] - 1); + close_json_object(); + } + close_json_array(PRINT_JSON, NULL); - if (tb[TCA_MQPRIO_MODE]) { - __u16 *mode = RTA_DATA(tb[TCA_MQPRIO_MODE]); + if (len == 0) + return 0; - if (*mode == TC_MQPRIO_MODE_CHANNEL) - fprintf(f, "\n mode:channel"); - } else { - fprintf(f, "\n mode:dcb"); - } + parse_rtattr(tb, TCA_MQPRIO_MAX, + RTA_DATA(opt) + RTA_ALIGN(sizeof(*qopt)), + len); - if (tb[TCA_MQPRIO_SHAPER]) { - __u16 *shaper = RTA_DATA(tb[TCA_MQPRIO_SHAPER]); + if (tb[TCA_MQPRIO_MODE]) { + __u16 mode = rta_getattr_u16(tb[TCA_MQPRIO_MODE]); - if (*shaper == TC_MQPRIO_SHAPER_BW_RATE) - fprintf(f, "\n shaper:bw_rlimit"); - } else { - fprintf(f, "\n shaper:dcb"); - } + print_string(PRINT_FP, NULL, "%s ", _SL_); + print_string(PRINT_ANY, "mode", "mode:%s", + mode == TC_MQPRIO_MODE_CHANNEL ? "channel" : + mode == TC_MQPRIO_MODE_DCB ? "dcb" : + "unknown"); + } - if (tb[TCA_MQPRIO_MIN_RATE64]) { - struct rtattr *r; - int rem = RTA_PAYLOAD(tb[TCA_MQPRIO_MIN_RATE64]); - __u64 *min = min_rate64; + if (tb[TCA_MQPRIO_SHAPER]) { + __u16 shaper = rta_getattr_u16(tb[TCA_MQPRIO_SHAPER]); - for (r = RTA_DATA(tb[TCA_MQPRIO_MIN_RATE64]); - RTA_OK(r, rem); r = RTA_NEXT(r, rem)) { - if (r->rta_type != TCA_MQPRIO_MIN_RATE64) - return -1; - *(min++) = rta_getattr_u64(r); - } - fprintf(f, " min_rate:"); - for (i = 0; i < qopt->num_tc; i++) - fprintf(f, "%s ", sprint_rate(min_rate64[i], b1)); - } + print_string(PRINT_FP, NULL, "%s ", _SL_); + print_string(PRINT_ANY, "shaper", "shaper:%s", + shaper == TC_MQPRIO_SHAPER_BW_RATE ? "bw_rlimit" : + shaper == TC_MQPRIO_SHAPER_DCB ? "dcb" : + "unknown"); + } - if (tb[TCA_MQPRIO_MAX_RATE64]) { - struct rtattr *r; - int rem = RTA_PAYLOAD(tb[TCA_MQPRIO_MAX_RATE64]); - __u64 *max = max_rate64; + if (tb[TCA_MQPRIO_MIN_RATE64]) + print_rate_table(qopt, tb[TCA_MQPRIO_MIN_RATE64], + "min_rate", TCA_MQPRIO_MIN_RATE64); - for (r = RTA_DATA(tb[TCA_MQPRIO_MAX_RATE64]); - RTA_OK(r, rem); r = RTA_NEXT(r, rem)) { - if (r->rta_type != TCA_MQPRIO_MAX_RATE64) - return -1; - *(max++) = rta_getattr_u64(r); - } - fprintf(f, " max_rate:"); - for (i = 0; i < qopt->num_tc; i++) - fprintf(f, "%s ", sprint_rate(max_rate64[i], b1)); - } - } + if (tb[TCA_MQPRIO_MAX_RATE64]) + print_rate_table(qopt, tb[TCA_MQPRIO_MAX_RATE64], + "max_rate", TCA_MQPRIO_MAX_RATE64); return 0; } -- 2.18.0