lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Tue, 10 Jul 2018 14:05:37 -0700
From:   Stephen Hemminger <stephen@...workplumber.org>
To:     netdev@...r.kernel.org
Cc:     Stephen Hemminger <sthemmin@...rosoft.com>,
        Stephen Hemminger <stephen@...workplumber.org>
Subject: [PATCH v2 iproute2-next 10/31] tc/mqprio: implement JSON output

From: Stephen Hemminger <sthemmin@...rosoft.com>

Output queue options in JSON if requested.

Signed-off-by: Stephen Hemminger <stephen@...workplumber.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

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ