From patchwork Sat Nov 28 12:21:48 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Luca Boccassi X-Patchwork-Id: 1407691 Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=debian.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4Ck5PZ44XQz9sSn for ; Sun, 29 Nov 2020 09:14:10 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2387603AbgK1Vtz (ORCPT ); Sat, 28 Nov 2020 16:49:55 -0500 Received: from mail-wm1-f66.google.com ([209.85.128.66]:38692 "EHLO mail-wm1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2387494AbgK1TP0 (ORCPT ); Sat, 28 Nov 2020 14:15:26 -0500 Received: by mail-wm1-f66.google.com with SMTP id g185so2378139wmf.3 for ; Sat, 28 Nov 2020 11:15:10 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=rsr49og+ZESDXNirKTEjxBe+wkS8D/EyhyHD+MGd43E=; b=b9I+Zs49bCLyFhIaXWAqPmH2pb8RVNkqiZ+bGz93ZcBs7pLnl0dL3P9YN8Rcs80Jcp 28PauwS1E+bp9rhd+IkH7pbBcydtkW7ZKXKIoD22i/GaGSD6ITEWwoh2RCbGYs5KCpiT KbnY+Ajkr/76jnJzcRKYJgEJJ4DM9BaSc9oQzPFLtOFXfba7Mu+IBhv2dntyoQmkCuUB +BHNYEAlgj9JrG3T+AZj88Sf2QCKirinVLe16c6rwtRhAJRFa4lx+7dN/lmLAfGqfDEI VRNNyCoMsnffojzu9mOxvzAxwOghHjBX9vRKX9wYOZNrHXEfiZtDcz2YJEVkoSlrPQ8A wTig== X-Gm-Message-State: AOAM533rq/uV2iA9T1sljfRlNZ5D6e3b+QXCt+aiMURMqKJsGLj6c1u2 5Et90gpLj0g2pMDNb8Nrm5zePlhcuEiH/g== X-Google-Smtp-Source: ABdhPJyynfmehjJTpJ/g55ecDQRGQbNIBauOIddOQK/2BYvcq14q/kGphBPhOwDG7qK0K7Jb6lmOoA== X-Received: by 2002:a7b:cb41:: with SMTP id v1mr2229743wmj.36.1606566116309; Sat, 28 Nov 2020 04:21:56 -0800 (PST) Received: from localhost ([2a01:4b00:f419:6f00:e2db:6a88:4676:d01b]) by smtp.gmail.com with ESMTPSA id j14sm19088394wrs.49.2020.11.28.04.21.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 28 Nov 2020 04:21:55 -0800 (PST) From: Luca Boccassi To: netdev@vger.kernel.org Cc: stephen@networkplumber.org Subject: [PATCH iproute2 v2] tc/mqprio: json-ify output Date: Sat, 28 Nov 2020 12:21:48 +0000 Message-Id: <20201128122148.6904-1-bluca@debian.org> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20201127152625.61874-1-bluca@debian.org> References: <20201127152625.61874-1-bluca@debian.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org As reported by a Debian user, mqprio output in json mode is invalid: { "kind": "mqprio", "handle": "8021:", "dev": "enp1s0f0", "root": true, "options": { tc 2 map 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 queues:(0:3) (4:7) mode:channel shaper:dcb} } json-ify it, while trying to maintain the same formatting for standard output. https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=972784 Reported-by: Roméo GINON Signed-off-by: Luca Boccassi --- v1: I do not have hardware where I can configure mqprio, so I can't really test this apart from compiling it. Stephen and David, do you have machines where you can quickly check that this works as expected? Thanks! v2: the original reporter tested the patch and reported this is the new output: { "kind": "mqprio", "handle": "8001:", "root": true, "options": { "tc": 2, "map": [ 0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0 ], "queues": [ "": [ 0,3 ], "": [ 4,7 ] ], "mode": "channel", "shaper": "dcb" } } Changed in v2 to make the inner queues arrays anonymous ("" -> NULL for open/close_json_array) Still would appreciate testing from someone else who has hardware that supports this feature and can enable this, as I am flying blind. tc/q_mqprio.c | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/tc/q_mqprio.c b/tc/q_mqprio.c index f26ba8d7..a128fc11 100644 --- a/tc/q_mqprio.c +++ b/tc/q_mqprio.c @@ -243,13 +243,19 @@ 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); + print_uint(PRINT_ANY, "tc", "tc %u ", qopt->num_tc); + open_json_array(PRINT_ANY, is_json_context() ? "map" : "map "); 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, NULL, "%u ", qopt->prio_tc_map[i]); + close_json_array(PRINT_ANY, ""); + open_json_array(PRINT_ANY, is_json_context() ? "queues" : "\n queues:"); + for (i = 0; i < qopt->num_tc; i++) { + open_json_array(PRINT_JSON, NULL); + print_uint(PRINT_ANY, NULL, "(%u:", qopt->offset[i]); + print_uint(PRINT_ANY, NULL, "%u) ", qopt->offset[i] + qopt->count[i] - 1); + close_json_array(PRINT_JSON, NULL); + } + close_json_array(PRINT_ANY, ""); if (len > 0) { struct rtattr *tb[TCA_MQPRIO_MAX + 1]; @@ -262,18 +268,18 @@ static int mqprio_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) __u16 *mode = RTA_DATA(tb[TCA_MQPRIO_MODE]); if (*mode == TC_MQPRIO_MODE_CHANNEL) - fprintf(f, "\n mode:channel"); + print_string(PRINT_ANY, "mode", "\n mode:%s", "channel"); } else { - fprintf(f, "\n mode:dcb"); + print_string(PRINT_ANY, "mode", "\n mode:%s", "dcb"); } if (tb[TCA_MQPRIO_SHAPER]) { __u16 *shaper = RTA_DATA(tb[TCA_MQPRIO_SHAPER]); if (*shaper == TC_MQPRIO_SHAPER_BW_RATE) - fprintf(f, "\n shaper:bw_rlimit"); + print_string(PRINT_ANY, "shaper", "\n shaper:%s", "bw_rlimit"); } else { - fprintf(f, "\n shaper:dcb"); + print_string(PRINT_ANY, "shaper", "\n shaper:%s", "dcb"); } if (tb[TCA_MQPRIO_MIN_RATE64]) { @@ -287,9 +293,9 @@ static int mqprio_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) return -1; *(min++) = rta_getattr_u64(r); } - fprintf(f, " min_rate:"); + open_json_array(PRINT_ANY, is_json_context() ? "min_rate" : " min_rate:"); for (i = 0; i < qopt->num_tc; i++) - fprintf(f, "%s ", sprint_rate(min_rate64[i], b1)); + print_string(PRINT_ANY, NULL, "%s ", sprint_rate(min_rate64[i], b1)); } if (tb[TCA_MQPRIO_MAX_RATE64]) { @@ -303,9 +309,9 @@ static int mqprio_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) return -1; *(max++) = rta_getattr_u64(r); } - fprintf(f, " max_rate:"); + open_json_array(PRINT_ANY, is_json_context() ? "max_rate" : " max_rate:"); for (i = 0; i < qopt->num_tc; i++) - fprintf(f, "%s ", sprint_rate(max_rate64[i], b1)); + print_string(PRINT_ANY, NULL, "%s ", sprint_rate(max_rate64[i], b1)); } } return 0;