All of lore.kernel.org
 help / color / mirror / Atom feed
* [patch iproute2 00/11] tc: jsonify couple of qdics, filter and actions
@ 2017-11-25 14:48 Jiri Pirko
  2017-11-25 14:48 ` [patch iproute2 01/11] tc: jsonify qdisc core Jiri Pirko
                   ` (11 more replies)
  0 siblings, 12 replies; 14+ messages in thread
From: Jiri Pirko @ 2017-11-25 14:48 UTC (permalink / raw)
  To: netdev; +Cc: stephen, jhs, mlxsw

From: Jiri Pirko <jiri@mellanox.com>

An example json output:

$ tc -s -j filter show dev ens8 egress
[{
        "protocol": "ip",
        "pref": 6001,
        "kind": "flower",
        "chain": 0
    },{
        "protocol": "ip",
        "pref": 6001,
        "kind": "flower",
        "chain": 0,
        "options": {
            "handle": 1,
            "keys": {
                "eth_type": "ipv4",
                "dst_ip": "192.168.250.1"
            },
            "not_in_hw": true,
            "actions": [{
                    "order": 1,
                    "kind": "gact",
                    "control_action": {
                        "type": "drop"
                    },
                    "prob": {
                        "random_type": "none",
                        "control_action": {
                            "type": "pass"
                        },
                        "val": 0
                    },
                    "index": 1,
                    "ref": 1,
                    "bind": 1,
                    "installed": 1667830,
                    "last_used": 1667830,
                    "stats": {
                        "bytes": 0,
                        "packets": 0,
                        "drops": 0,
                        "overlimits": 0,
                        "requeues": 0,
                        "backlog": 0,
                        "qlen": 0,
                        "requeues": 0
                    },
                    "cookie": "a1b2c3d4aaaaaaaabb"
                }
            }
        }
    }
]
$ tc -s filter show dev ens8 egress
filter pref 6001 flower chain 0 
filter pref 6001 flower chain 0 handle 0x1 
  eth_type ipv4
  dst_ip 192.168.250.1
  not_in_hw
        action order 1: gact action drop
         random type none pass val 0
         index 1 ref 1 bind 1 installed 16689 sec used 16689 sec
        Action statistics:
        Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0) 
        backlog 0b 0p requeues 0
        cookie a1b2c3d4aaaaaaaabb

---
To be applied on top of my cookie fix patchset

Jiri Pirko (11):
  tc: jsonify qdisc core
  tc: jsonify stats2
  tc: jsonify fq_codel qdisc
  tc: jsonify htb qdisc
  tc: jsonify filter core
  tc: jsonify flower filter
  tc: jsonify matchall filter
  tc: jsonify actions core
  tc: jsonify gact action
  tc: jsonify mirred action
  tc: jsonify vlan action

 tc/f_flower.c   | 287 +++++++++++++++++++++++++++++++++-----------------------
 tc/f_matchall.c |  12 +--
 tc/m_action.c   |  22 +++--
 tc/m_gact.c     |  18 ++--
 tc/m_mirred.c   |  46 +++++++--
 tc/m_vlan.c     |  26 +++--
 tc/q_fq_codel.c |  25 +++--
 tc/q_htb.c      |  20 ++--
 tc/tc.c         |   5 +-
 tc/tc_filter.c  |  47 ++++++----
 tc/tc_qdisc.c   |  52 ++++++----
 tc/tc_util.c    |  66 +++++++++----
 tc/tc_util.h    |   1 +
 13 files changed, 396 insertions(+), 231 deletions(-)

-- 
2.9.5

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [patch iproute2 01/11] tc: jsonify qdisc core
  2017-11-25 14:48 [patch iproute2 00/11] tc: jsonify couple of qdics, filter and actions Jiri Pirko
@ 2017-11-25 14:48 ` Jiri Pirko
  2017-11-25 14:48 ` [patch iproute2 02/11] tc: jsonify stats2 Jiri Pirko
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Jiri Pirko @ 2017-11-25 14:48 UTC (permalink / raw)
  To: netdev; +Cc: stephen, jhs, mlxsw

From: Jiri Pirko <jiri@mellanox.com>

Add json output to qdisc core.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 tc/tc.c       |  5 ++++-
 tc/tc_qdisc.c | 52 ++++++++++++++++++++++++++++++++--------------------
 tc/tc_util.h  |  1 +
 3 files changed, 37 insertions(+), 21 deletions(-)

diff --git a/tc/tc.c b/tc/tc.c
index 793dca9..ad9f07e 100644
--- a/tc/tc.c
+++ b/tc/tc.c
@@ -41,6 +41,7 @@ int batch_mode;
 int use_iec;
 int force;
 bool use_names;
+int json;
 
 static char *conf_file;
 
@@ -189,7 +190,7 @@ static void usage(void)
 			"       tc [-force] -batch filename\n"
 			"where  OBJECT := { qdisc | class | filter | action | monitor | exec }\n"
 	                "       OPTIONS := { -s[tatistics] | -d[etails] | -r[aw] | -p[retty] | -b[atch] [filename] | -n[etns] name |\n"
-			"                    -nm | -nam[es] | { -cf | -conf } path }\n");
+			"                    -nm | -nam[es] | { -cf | -conf } path } | -j[son]\n");
 }
 
 static int do_cmd(int argc, char **argv)
@@ -312,6 +313,8 @@ int main(int argc, char **argv)
 		} else if (matches(argv[1], "-tshort") == 0) {
 			++timestamp;
 			++timestamp_short;
+		} else if (matches(argv[1], "-json") == 0) {
+			++json;
 		} else {
 			fprintf(stderr, "Option \"%s\" is unknown, try \"tc -help\".\n", argv[1]);
 			return -1;
diff --git a/tc/tc_qdisc.c b/tc/tc_qdisc.c
index 2f88f11..4431d5f 100644
--- a/tc/tc_qdisc.c
+++ b/tc/tc_qdisc.c
@@ -227,39 +227,44 @@ int print_qdisc(const struct sockaddr_nl *who,
 		return -1;
 	}
 
+	open_json_object(NULL);
+
 	if (n->nlmsg_type == RTM_DELQDISC)
-		fprintf(fp, "deleted ");
+		print_bool(PRINT_ANY, "deleted", "deleted ", true);
 
 	if (n->nlmsg_type == RTM_NEWQDISC &&
 			(n->nlmsg_flags & NLM_F_CREATE) &&
 			(n->nlmsg_flags & NLM_F_REPLACE))
-		fprintf(fp, "replaced ");
+		print_bool(PRINT_ANY, "replaced", "replaced ", true);
 
 	if (n->nlmsg_type == RTM_NEWQDISC &&
 			(n->nlmsg_flags & NLM_F_CREATE) &&
 			(n->nlmsg_flags & NLM_F_EXCL))
-		fprintf(fp, "added ");
-
-	if (show_raw)
-		fprintf(fp, "qdisc %s %x:[%08x]  ",
-			rta_getattr_str(tb[TCA_KIND]),
-			t->tcm_handle >> 16, t->tcm_handle);
-	else
-		fprintf(fp, "qdisc %s %x: ", rta_getattr_str(tb[TCA_KIND]),
-			t->tcm_handle >> 16);
+		print_bool(PRINT_ANY, "added", "added ", true);
+
+	print_string(PRINT_ANY, "kind", "qdisc %s",
+		     rta_getattr_str(tb[TCA_KIND]));
+	sprintf(abuf, "%x:", t->tcm_handle >> 16);
+	print_string(PRINT_ANY, "handle", " %s", abuf);
+	if (show_raw) {
+		sprintf(abuf, "[%08x]", t->tcm_handle);
+		print_string(PRINT_FP, NULL, "%s", abuf);
+	}
+	print_string(PRINT_FP, NULL, " ", NULL);
 
 	if (filter_ifindex == 0)
-		fprintf(fp, "dev %s ", ll_index_to_name(t->tcm_ifindex));
+		print_string(PRINT_ANY, "dev", "dev %s ",
+			     ll_index_to_name(t->tcm_ifindex));
 
 	if (t->tcm_parent == TC_H_ROOT)
-		fprintf(fp, "root ");
+		print_bool(PRINT_ANY, "root", "root ", true);
 	else if (t->tcm_parent) {
 		print_tc_classid(abuf, sizeof(abuf), t->tcm_parent);
-		fprintf(fp, "parent %s ", abuf);
+		print_string(PRINT_ANY, "parent", "parent %s ", abuf);
 	}
 
 	if (t->tcm_info != 1)
-		fprintf(fp, "refcnt %d ", t->tcm_info);
+		print_uint(PRINT_ANY, "refcnt", "refcnt %u ", t->tcm_info);
 
 	/* pfifo_fast is generic enough to warrant the hardcoding --JHS */
 	if (strcmp("pfifo_fast", RTA_DATA(tb[TCA_KIND])) == 0)
@@ -267,17 +272,21 @@ int print_qdisc(const struct sockaddr_nl *who,
 	else
 		q = get_qdisc_kind(RTA_DATA(tb[TCA_KIND]));
 
+	open_json_object("options");
 	if (tb[TCA_OPTIONS]) {
 		if (q)
 			q->print_qopt(q, fp, tb[TCA_OPTIONS]);
 		else
-			fprintf(fp, "[cannot parse qdisc parameters]");
+			print_string(PRINT_FP, NULL,
+				     "[cannot parse qdisc parameters]", NULL);
 	}
-	fprintf(fp, "\n");
+	close_json_object();
+
+	print_string(PRINT_FP, NULL, "\n", NULL);
 
 	if (show_details && tb[TCA_STAB]) {
 		print_size_table(fp, " ", tb[TCA_STAB]);
-		fprintf(fp, "\n");
+		print_string(PRINT_FP, NULL, "\n", NULL);
 	}
 
 	if (show_stats) {
@@ -285,14 +294,15 @@ int print_qdisc(const struct sockaddr_nl *who,
 
 		if (tb[TCA_STATS] || tb[TCA_STATS2] || tb[TCA_XSTATS]) {
 			print_tcstats_attr(fp, tb, " ", &xstats);
-			fprintf(fp, "\n");
+			print_string(PRINT_FP, NULL, "\n", NULL);
 		}
 
 		if (q && xstats && q->print_xstats) {
 			q->print_xstats(q, fp, xstats);
-			fprintf(fp, "\n");
+			print_string(PRINT_FP, NULL, "\n", NULL);
 		}
 	}
+	close_json_object();
 	fflush(fp);
 	return 0;
 }
@@ -360,10 +370,12 @@ static int tc_qdisc_list(int argc, char **argv)
 		return 1;
 	}
 
+	new_json_obj(json);
 	if (rtnl_dump_filter(&rth, print_qdisc, stdout) < 0) {
 		fprintf(stderr, "Dump terminated\n");
 		return 1;
 	}
+	delete_json_obj();
 
 	return 0;
 }
diff --git a/tc/tc_util.h b/tc/tc_util.h
index eae1091..b46b9c9 100644
--- a/tc/tc_util.h
+++ b/tc/tc_util.h
@@ -10,6 +10,7 @@
 #include <linux/gen_stats.h>
 
 #include "tc_core.h"
+#include "json_print.h"
 
 /* This is the deprecated multiqueue interface */
 #ifndef TCA_PRIO_MAX
-- 
2.9.5

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [patch iproute2 02/11] tc: jsonify stats2
  2017-11-25 14:48 [patch iproute2 00/11] tc: jsonify couple of qdics, filter and actions Jiri Pirko
  2017-11-25 14:48 ` [patch iproute2 01/11] tc: jsonify qdisc core Jiri Pirko
@ 2017-11-25 14:48 ` Jiri Pirko
  2017-11-25 14:48 ` [patch iproute2 03/11] tc: jsonify fq_codel qdisc Jiri Pirko
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Jiri Pirko @ 2017-11-25 14:48 UTC (permalink / raw)
  To: netdev; +Cc: stephen, jhs, mlxsw

From: Jiri Pirko <jiri@mellanox.com>

Add json output to stats2.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 tc/tc_util.c | 32 +++++++++++++++++++++++---------
 1 file changed, 23 insertions(+), 9 deletions(-)

diff --git a/tc/tc_util.c b/tc/tc_util.c
index 5532d40..d276987 100644
--- a/tc/tc_util.c
+++ b/tc/tc_util.c
@@ -781,16 +781,19 @@ void print_tcstats2_attr(FILE *fp, struct rtattr *rta, char *prefix, struct rtat
 		struct gnet_stats_basic bs = {0};
 
 		memcpy(&bs, RTA_DATA(tbs[TCA_STATS_BASIC]), MIN(RTA_PAYLOAD(tbs[TCA_STATS_BASIC]), sizeof(bs)));
-		fprintf(fp, "%sSent %llu bytes %u pkt",
-			prefix, (unsigned long long) bs.bytes, bs.packets);
+		print_string(PRINT_FP, NULL, "%s", prefix);
+		print_lluint(PRINT_ANY, "bytes", "Sent %llu bytes", bs.bytes);
+		print_uint(PRINT_ANY, "packets", " %u pkt", bs.packets);
 	}
 
 	if (tbs[TCA_STATS_QUEUE]) {
 		struct gnet_stats_queue q = {0};
 
 		memcpy(&q, RTA_DATA(tbs[TCA_STATS_QUEUE]), MIN(RTA_PAYLOAD(tbs[TCA_STATS_QUEUE]), sizeof(q)));
-		fprintf(fp, " (dropped %u, overlimits %u requeues %u) ",
-			q.drops, q.overlimits, q.requeues);
+		print_uint(PRINT_ANY, "drops", " (dropped %u", q.drops);
+		print_uint(PRINT_ANY, "overlimits", ", overlimits %u",
+			   q.overlimits);
+		print_uint(PRINT_ANY, "requeues", " requeues %u) ", q.requeues);
 	}
 
 	if (tbs[TCA_STATS_RATE_EST64]) {
@@ -799,8 +802,11 @@ void print_tcstats2_attr(FILE *fp, struct rtattr *rta, char *prefix, struct rtat
 		memcpy(&re, RTA_DATA(tbs[TCA_STATS_RATE_EST64]),
 		       MIN(RTA_PAYLOAD(tbs[TCA_STATS_RATE_EST64]),
 			   sizeof(re)));
-		fprintf(fp, "\n%srate %s %llupps ",
-			prefix, sprint_rate(re.bps, b1), re.pps);
+		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));
+		print_lluint(PRINT_ANY, "pps", " %llupps", re.pps);
 	} else if (tbs[TCA_STATS_RATE_EST]) {
 		struct gnet_stats_rate_est re = {0};
 
@@ -808,6 +814,11 @@ void print_tcstats2_attr(FILE *fp, struct rtattr *rta, char *prefix, struct rtat
 		       MIN(RTA_PAYLOAD(tbs[TCA_STATS_RATE_EST]), sizeof(re)));
 		fprintf(fp, "\n%srate %s %upps ",
 			prefix, sprint_rate(re.bps, b1), re.pps);
+		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));
+		print_uint(PRINT_ANY, "pps", " %upps", re.pps);
 	}
 
 	if (tbs[TCA_STATS_QUEUE]) {
@@ -815,9 +826,12 @@ void print_tcstats2_attr(FILE *fp, struct rtattr *rta, char *prefix, struct rtat
 
 		memcpy(&q, RTA_DATA(tbs[TCA_STATS_QUEUE]), MIN(RTA_PAYLOAD(tbs[TCA_STATS_QUEUE]), sizeof(q)));
 		if (!tbs[TCA_STATS_RATE_EST])
-			fprintf(fp, "\n%s", prefix);
-		fprintf(fp, "backlog %s %up requeues %u ",
-			sprint_size(q.backlog, b1), q.qlen, q.requeues);
+			print_string(PRINT_FP, NULL, "\n%s", prefix);
+		print_uint(PRINT_JSON, "backlog", NULL, q.backlog);
+		print_string(PRINT_FP, NULL, "backlog %s",
+			     sprint_size(q.backlog, b1));
+		print_uint(PRINT_ANY, "qlen", " %up", q.qlen);
+		print_uint(PRINT_ANY, "requeues", " requeues %u", q.qlen);
 	}
 
 	if (xstats)
-- 
2.9.5

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [patch iproute2 03/11] tc: jsonify fq_codel qdisc
  2017-11-25 14:48 [patch iproute2 00/11] tc: jsonify couple of qdics, filter and actions Jiri Pirko
  2017-11-25 14:48 ` [patch iproute2 01/11] tc: jsonify qdisc core Jiri Pirko
  2017-11-25 14:48 ` [patch iproute2 02/11] tc: jsonify stats2 Jiri Pirko
@ 2017-11-25 14:48 ` Jiri Pirko
  2017-11-25 14:48 ` [patch iproute2 04/11] tc: jsonify htb qdisc Jiri Pirko
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Jiri Pirko @ 2017-11-25 14:48 UTC (permalink / raw)
  To: netdev; +Cc: stephen, jhs, mlxsw

From: Jiri Pirko <jiri@mellanox.com>

Add json output to fq_codel qdisc.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 tc/q_fq_codel.c | 25 ++++++++++++++++---------
 1 file changed, 16 insertions(+), 9 deletions(-)

diff --git a/tc/q_fq_codel.c b/tc/q_fq_codel.c
index 86c6fb2..fd1f59c 100644
--- a/tc/q_fq_codel.c
+++ b/tc/q_fq_codel.c
@@ -173,44 +173,51 @@ static int fq_codel_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt
 	if (tb[TCA_FQ_CODEL_LIMIT] &&
 	    RTA_PAYLOAD(tb[TCA_FQ_CODEL_LIMIT]) >= sizeof(__u32)) {
 		limit = rta_getattr_u32(tb[TCA_FQ_CODEL_LIMIT]);
-		fprintf(f, "limit %up ", limit);
+		print_uint(PRINT_ANY, "limit", "limit %up ", limit);
 	}
 	if (tb[TCA_FQ_CODEL_FLOWS] &&
 	    RTA_PAYLOAD(tb[TCA_FQ_CODEL_FLOWS]) >= sizeof(__u32)) {
 		flows = rta_getattr_u32(tb[TCA_FQ_CODEL_FLOWS]);
-		fprintf(f, "flows %u ", flows);
+		print_uint(PRINT_ANY, "flows", "flows %u ", flows);
 	}
 	if (tb[TCA_FQ_CODEL_QUANTUM] &&
 	    RTA_PAYLOAD(tb[TCA_FQ_CODEL_QUANTUM]) >= sizeof(__u32)) {
 		quantum = rta_getattr_u32(tb[TCA_FQ_CODEL_QUANTUM]);
-		fprintf(f, "quantum %u ", quantum);
+		print_uint(PRINT_ANY, "quantum", "quantum %u ", quantum);
 	}
 	if (tb[TCA_FQ_CODEL_TARGET] &&
 	    RTA_PAYLOAD(tb[TCA_FQ_CODEL_TARGET]) >= sizeof(__u32)) {
 		target = rta_getattr_u32(tb[TCA_FQ_CODEL_TARGET]);
-		fprintf(f, "target %s ", sprint_time(target, b1));
+		print_uint(PRINT_JSON, "target", NULL, target);
+		print_string(PRINT_FP, NULL, "target %s ",
+			     sprint_time(target, b1));
 	}
 	if (tb[TCA_FQ_CODEL_CE_THRESHOLD] &&
 	    RTA_PAYLOAD(tb[TCA_FQ_CODEL_CE_THRESHOLD]) >= sizeof(__u32)) {
 		ce_threshold = rta_getattr_u32(tb[TCA_FQ_CODEL_CE_THRESHOLD]);
-		fprintf(f, "ce_threshold %s ", sprint_time(ce_threshold, b1));
+		print_uint(PRINT_JSON, "ce_threshold", NULL, ce_threshold);
+		print_string(PRINT_FP, NULL, "ce_threshold %s ",
+			     sprint_time(ce_threshold, b1));
 	}
 	if (tb[TCA_FQ_CODEL_INTERVAL] &&
 	    RTA_PAYLOAD(tb[TCA_FQ_CODEL_INTERVAL]) >= sizeof(__u32)) {
 		interval = rta_getattr_u32(tb[TCA_FQ_CODEL_INTERVAL]);
-		fprintf(f, "interval %s ", sprint_time(interval, b1));
+		print_uint(PRINT_JSON, "interval", NULL, interval);
+		print_string(PRINT_FP, NULL, "interval %s ",
+			     sprint_time(interval, b1));
 	}
 	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]);
-
-		fprintf(f, "memory_limit %s ", sprint_size(memory_limit, b1));
+		print_uint(PRINT_JSON, "memory_limit", NULL, memory_limit);
+		print_string(PRINT_FP, NULL, "memory_limit %s ",
+			     sprint_size(memory_limit, b1));
 	}
 	if (tb[TCA_FQ_CODEL_ECN] &&
 	    RTA_PAYLOAD(tb[TCA_FQ_CODEL_ECN]) >= sizeof(__u32)) {
 		ecn = rta_getattr_u32(tb[TCA_FQ_CODEL_ECN]);
 		if (ecn)
-			fprintf(f, "ecn ");
+			print_bool(PRINT_ANY, "ecn", "ecn ", true);
 	}
 
 	return 0;
-- 
2.9.5

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [patch iproute2 04/11] tc: jsonify htb qdisc
  2017-11-25 14:48 [patch iproute2 00/11] tc: jsonify couple of qdics, filter and actions Jiri Pirko
                   ` (2 preceding siblings ...)
  2017-11-25 14:48 ` [patch iproute2 03/11] tc: jsonify fq_codel qdisc Jiri Pirko
@ 2017-11-25 14:48 ` Jiri Pirko
  2017-11-25 14:48 ` [patch iproute2 05/11] tc: jsonify filter core Jiri Pirko
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Jiri Pirko @ 2017-11-25 14:48 UTC (permalink / raw)
  To: netdev; +Cc: stephen, jhs, mlxsw

From: Jiri Pirko <jiri@mellanox.com>

Add json output to htb qdisc.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 tc/q_htb.c | 20 +++++++++++++-------
 1 file changed, 13 insertions(+), 7 deletions(-)

diff --git a/tc/q_htb.c b/tc/q_htb.c
index ffb43aa..3fc2acb 100644
--- a/tc/q_htb.c
+++ b/tc/q_htb.c
@@ -293,9 +293,10 @@ static int htb_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
 		if (RTA_PAYLOAD(tb[TCA_HTB_PARMS])  < sizeof(*hopt)) return -1;
 
 		if (!hopt->level) {
-			fprintf(f, "prio %d ", (int)hopt->prio);
+			print_int(PRINT_ANY, "prio", "prio ", (int)hopt->prio);
 			if (show_details)
-				fprintf(f, "quantum %d ", (int)hopt->quantum);
+				print_int(PRINT_ANY, "quantum", "quantum ",
+					  (int)hopt->quantum);
 		}
 
 		rate64 = hopt->rate.rate;
@@ -341,16 +342,21 @@ static int htb_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
 		gopt = RTA_DATA(tb[TCA_HTB_INIT]);
 		if (RTA_PAYLOAD(tb[TCA_HTB_INIT])  < sizeof(*gopt)) return -1;
 
-		fprintf(f, "r2q %d default %x direct_packets_stat %u",
-			gopt->rate2quantum, gopt->defcls, gopt->direct_pkts);
-		if (show_details)
-			fprintf(f, " ver %d.%d", gopt->version >> 16, gopt->version & 0xffff);
+		print_int(PRINT_ANY, "r2q", "r2q %d", gopt->rate2quantum);
+		print_uint(PRINT_ANY, "default", " default %u", gopt->defcls);
+		print_uint(PRINT_ANY, "direct_packets_stat",
+			   " direct_packets_stat %u", gopt->direct_pkts);
+		if (show_details) {
+			sprintf(b1, "%d.%d", gopt->version >> 16, gopt->version & 0xffff);
+			print_string(PRINT_ANY, "ver", " ver %s", b1);
+		}
 	}
 	if (tb[TCA_HTB_DIRECT_QLEN] &&
 	    RTA_PAYLOAD(tb[TCA_HTB_DIRECT_QLEN]) >= sizeof(__u32)) {
 		__u32 direct_qlen = rta_getattr_u32(tb[TCA_HTB_DIRECT_QLEN]);
 
-		fprintf(f, " direct_qlen %u", direct_qlen);
+		print_uint(PRINT_ANY, "direct_qlen", " direct_qlen %u",
+			   direct_qlen);
 	}
 	return 0;
 }
-- 
2.9.5

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [patch iproute2 05/11] tc: jsonify filter core
  2017-11-25 14:48 [patch iproute2 00/11] tc: jsonify couple of qdics, filter and actions Jiri Pirko
                   ` (3 preceding siblings ...)
  2017-11-25 14:48 ` [patch iproute2 04/11] tc: jsonify htb qdisc Jiri Pirko
@ 2017-11-25 14:48 ` Jiri Pirko
  2017-11-25 14:48 ` [patch iproute2 06/11] tc: jsonify flower filter Jiri Pirko
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Jiri Pirko @ 2017-11-25 14:48 UTC (permalink / raw)
  To: netdev; +Cc: stephen, jhs, mlxsw

From: Jiri Pirko <jiri@mellanox.com>

Add json output to filter core.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 tc/tc_filter.c | 47 ++++++++++++++++++++++++++++++-----------------
 1 file changed, 30 insertions(+), 17 deletions(-)

diff --git a/tc/tc_filter.c b/tc/tc_filter.c
index 276a66c..3d9b889 100644
--- a/tc/tc_filter.c
+++ b/tc/tc_filter.c
@@ -237,33 +237,36 @@ int print_filter(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
 		return -1;
 	}
 
+	open_json_object(NULL);
+
 	if (n->nlmsg_type == RTM_DELTFILTER)
-		fprintf(fp, "deleted ");
+		print_bool(PRINT_ANY, "deleted", "deleted ", true);
 
 	if (n->nlmsg_type == RTM_NEWTFILTER &&
 			(n->nlmsg_flags & NLM_F_CREATE) &&
 			!(n->nlmsg_flags & NLM_F_EXCL))
-		fprintf(fp, "replaced ");
+		print_bool(PRINT_ANY, "replaced", "replaced ", true);
 
 	if (n->nlmsg_type == RTM_NEWTFILTER &&
 			(n->nlmsg_flags & NLM_F_CREATE) &&
 			(n->nlmsg_flags & NLM_F_EXCL))
-		fprintf(fp, "added ");
+		print_bool(PRINT_ANY, "added", "added ", true);
 
-	fprintf(fp, "filter ");
+	print_string(PRINT_FP, NULL, "filter ", NULL);
 	if (!filter_ifindex || filter_ifindex != t->tcm_ifindex)
-		fprintf(fp, "dev %s ", ll_index_to_name(t->tcm_ifindex));
+		print_string(PRINT_ANY, "dev", "dev %s ",
+			     ll_index_to_name(t->tcm_ifindex));
 
 	if (!filter_parent || filter_parent != t->tcm_parent) {
 		if (t->tcm_parent == TC_H_ROOT)
-			fprintf(fp, "root ");
+			print_bool(PRINT_ANY, "root", "root ", true);
 		else if (t->tcm_parent == TC_H_MAKE(TC_H_CLSACT, TC_H_MIN_INGRESS))
-			fprintf(fp, "ingress ");
+			print_bool(PRINT_ANY, "ingress", "ingress ", true);
 		else if (t->tcm_parent == TC_H_MAKE(TC_H_CLSACT, TC_H_MIN_EGRESS))
-			fprintf(fp, "egress ");
+			print_bool(PRINT_ANY, "egress", "egress ", true);
 		else {
 			print_tc_classid(abuf, sizeof(abuf), t->tcm_parent);
-			fprintf(fp, "parent %s ", abuf);
+			print_string(PRINT_ANY, "parent", "parent %s ", abuf);
 		}
 	}
 
@@ -274,39 +277,45 @@ int print_filter(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
 		if (!filter_protocol || filter_protocol != f_proto) {
 			if (f_proto) {
 				SPRINT_BUF(b1);
-				fprintf(fp, "protocol %s ",
-					ll_proto_n2a(f_proto, b1, sizeof(b1)));
+				print_string(PRINT_JSON, "protocol",
+					     "protocol %s ",
+					     ll_proto_n2a(f_proto, b1, sizeof(b1)));
 			}
 		}
 		if (!filter_prio || filter_prio != prio) {
 			if (prio)
-				fprintf(fp, "pref %u ", prio);
+				print_uint(PRINT_ANY, "pref", "pref %u ", prio);
 		}
 	}
-	fprintf(fp, "%s ", rta_getattr_str(tb[TCA_KIND]));
+	print_string(PRINT_ANY, "kind", "%s ", rta_getattr_str(tb[TCA_KIND]));
 
 	if (tb[TCA_CHAIN]) {
 		__u32 chain_index = rta_getattr_u32(tb[TCA_CHAIN]);
 
 		if (!filter_chain_index_set ||
 		    filter_chain_index != chain_index)
-			fprintf(fp, "chain %u ", chain_index);
+			print_uint(PRINT_ANY, "chain", "chain %u ",
+				   chain_index);
 	}
 
 	q = get_filter_kind(RTA_DATA(tb[TCA_KIND]));
 	if (tb[TCA_OPTIONS]) {
+		open_json_object("options");
 		if (q)
 			q->print_fopt(q, fp, tb[TCA_OPTIONS], t->tcm_handle);
 		else
-			fprintf(fp, "[cannot parse parameters]");
+			print_string(PRINT_FP, NULL,
+				     "[cannot parse parameters]", NULL);
+		close_json_object();
 	}
-	fprintf(fp, "\n");
+	print_string(PRINT_FP, NULL, "\n", NULL);
 
 	if (show_stats && (tb[TCA_STATS] || tb[TCA_STATS2])) {
 		print_tcstats_attr(fp, tb, " ", NULL);
-		fprintf(fp, "\n");
+		print_string(PRINT_FP, NULL, "\n", NULL);
 	}
 
+	close_json_object();
 	fflush(fp);
 	return 0;
 }
@@ -489,7 +498,9 @@ static int tc_filter_get(int cmd, unsigned int flags, int argc, char **argv)
 		return 2;
 	}
 
+	new_json_obj(json);
 	print_filter(NULL, answer, (void *)stdout);
+	delete_json_obj();
 
 	free(answer);
 	return 0;
@@ -617,10 +628,12 @@ static int tc_filter_list(int argc, char **argv)
 		return 1;
 	}
 
+	new_json_obj(json);
 	if (rtnl_dump_filter(&rth, print_filter, stdout) < 0) {
 		fprintf(stderr, "Dump terminated\n");
 		return 1;
 	}
+	delete_json_obj();
 
 	return 0;
 }
-- 
2.9.5

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [patch iproute2 06/11] tc: jsonify flower filter
  2017-11-25 14:48 [patch iproute2 00/11] tc: jsonify couple of qdics, filter and actions Jiri Pirko
                   ` (4 preceding siblings ...)
  2017-11-25 14:48 ` [patch iproute2 05/11] tc: jsonify filter core Jiri Pirko
@ 2017-11-25 14:48 ` Jiri Pirko
  2017-11-25 14:48 ` [patch iproute2 07/11] tc: jsonify matchall filter Jiri Pirko
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Jiri Pirko @ 2017-11-25 14:48 UTC (permalink / raw)
  To: netdev; +Cc: stephen, jhs, mlxsw

From: Jiri Pirko <jiri@mellanox.com>

Add json output to flower filter.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 tc/f_flower.c | 287 ++++++++++++++++++++++++++++++++++------------------------
 1 file changed, 169 insertions(+), 118 deletions(-)

diff --git a/tc/f_flower.c b/tc/f_flower.c
index 9cad6c8..5a4ec83 100644
--- a/tc/f_flower.c
+++ b/tc/f_flower.c
@@ -1037,89 +1037,105 @@ static int __mask_bits(char *addr, size_t len)
 	return bits;
 }
 
-static void flower_print_eth_addr(FILE *f, char *name,
-				  struct rtattr *addr_attr,
+static void flower_print_eth_addr(char *name, struct rtattr *addr_attr,
 				  struct rtattr *mask_attr)
 {
+	SPRINT_BUF(namefrm);
+	SPRINT_BUF(out);
 	SPRINT_BUF(b1);
+	size_t done;
 	int bits;
 
 	if (!addr_attr || RTA_PAYLOAD(addr_attr) != ETH_ALEN)
 		return;
-	fprintf(f, "\n  %s %s", name, ll_addr_n2a(RTA_DATA(addr_attr), ETH_ALEN,
-						  0, b1, sizeof(b1)));
-	if (!mask_attr || RTA_PAYLOAD(mask_attr) != ETH_ALEN)
-		return;
-	bits = __mask_bits(RTA_DATA(mask_attr), ETH_ALEN);
-	if (bits < 0)
-		fprintf(f, "/%s", ll_addr_n2a(RTA_DATA(mask_attr), ETH_ALEN,
-					      0, b1, sizeof(b1)));
-	else if (bits < ETH_ALEN * 8)
-		fprintf(f, "/%d", bits);
+	done = sprintf(out, "%s",
+		       ll_addr_n2a(RTA_DATA(addr_attr), ETH_ALEN,
+				   0, b1, sizeof(b1)));
+	if (mask_attr && RTA_PAYLOAD(mask_attr) == ETH_ALEN) {
+		bits = __mask_bits(RTA_DATA(mask_attr), ETH_ALEN);
+		if (bits < 0)
+			sprintf(out + done, "/%s",
+				ll_addr_n2a(RTA_DATA(mask_attr), ETH_ALEN,
+					    0, b1, sizeof(b1)));
+		else if (bits < ETH_ALEN * 8)
+			sprintf(out + done, "/%d", bits);
+	}
+
+	sprintf(namefrm, "\n  %s %%s", name);
+	print_string(PRINT_ANY, name, namefrm, out);
 }
 
-static void flower_print_eth_type(FILE *f, __be16 *p_eth_type,
+static void flower_print_eth_type(__be16 *p_eth_type,
 				  struct rtattr *eth_type_attr)
 {
+	SPRINT_BUF(out);
 	__be16 eth_type;
 
 	if (!eth_type_attr)
 		return;
 
 	eth_type = rta_getattr_u16(eth_type_attr);
-	fprintf(f, "\n  eth_type ");
 	if (eth_type == htons(ETH_P_IP))
-		fprintf(f, "ipv4");
+		sprintf(out, "ipv4");
 	else if (eth_type == htons(ETH_P_IPV6))
-		fprintf(f, "ipv6");
+		sprintf(out, "ipv6");
 	else if (eth_type == htons(ETH_P_ARP))
-		fprintf(f, "arp");
+		sprintf(out, "arp");
 	else if (eth_type == htons(ETH_P_RARP))
-		fprintf(f, "rarp");
+		sprintf(out, "rarp");
 	else
-		fprintf(f, "%04x", ntohs(eth_type));
+		sprintf(out, "%04x", ntohs(eth_type));
+
+	print_string(PRINT_ANY, "eth_type", "\n  eth_type %s", out);
 	*p_eth_type = eth_type;
 }
 
-static void flower_print_ip_proto(FILE *f, __u8 *p_ip_proto,
+static void flower_print_ip_proto(__u8 *p_ip_proto,
 				  struct rtattr *ip_proto_attr)
 {
+	SPRINT_BUF(out);
 	__u8 ip_proto;
 
 	if (!ip_proto_attr)
 		return;
 
 	ip_proto = rta_getattr_u8(ip_proto_attr);
-	fprintf(f, "\n  ip_proto ");
 	if (ip_proto == IPPROTO_TCP)
-		fprintf(f, "tcp");
+		sprintf(out, "tcp");
 	else if (ip_proto == IPPROTO_UDP)
-		fprintf(f, "udp");
+		sprintf(out, "udp");
 	else if (ip_proto == IPPROTO_SCTP)
-		fprintf(f, "sctp");
+		sprintf(out, "sctp");
 	else if (ip_proto == IPPROTO_ICMP)
-		fprintf(f, "icmp");
+		sprintf(out, "icmp");
 	else if (ip_proto == IPPROTO_ICMPV6)
-		fprintf(f, "icmpv6");
+		sprintf(out, "icmpv6");
 	else
-		fprintf(f, "%02x", ip_proto);
+		sprintf(out, "%02x", ip_proto);
+
+	print_string(PRINT_ANY, "ip_proto", "\n  ip_proto %s", out);
 	*p_ip_proto = ip_proto;
 }
 
-static void flower_print_ip_attr(FILE *f, char *name,
-				 struct rtattr *key_attr,
+static void flower_print_ip_attr(char *name, struct rtattr *key_attr,
 				 struct rtattr *mask_attr)
 {
+	SPRINT_BUF(namefrm);
+	SPRINT_BUF(out);
+	size_t done;
+
 	if (!key_attr)
 		return;
 
-	fprintf(f, "\n  %s %x", name, rta_getattr_u8(key_attr));
-	if (!mask_attr)
-		return;
-	fprintf(f, "/%x", rta_getattr_u8(mask_attr));
+	done = sprintf(out, "%x", rta_getattr_u8(key_attr));
+	if (mask_attr)
+		sprintf(out + done, "/%x", rta_getattr_u8(mask_attr));
+
+	sprintf(namefrm, "\n  %s %%x", name);
+	print_string(PRINT_ANY, name, namefrm, out);
 }
 
-static void flower_print_matching_flags(FILE *f, char *name,
+static void flower_print_matching_flags(char *name,
 					enum flower_matching_flags type,
 					struct rtattr *attr,
 					struct rtattr *mask_attr)
@@ -1139,20 +1155,28 @@ static void flower_print_matching_flags(FILE *f, char *name,
 		if (type != flags_str[i].type)
 			continue;
 		if (mtf_mask & flags_str[i].flag) {
-			if (++count == 1)
-				fprintf(f, "\n  %s ", name);
-			else
-				fprintf(f, "/");
+			if (++count == 1) {
+				print_string(PRINT_FP, NULL, "\n  %s ", name);
+				open_json_object(name);
+			} else {
+				print_string(PRINT_FP, NULL, "/", NULL);
+			}
 
+			print_bool(PRINT_JSON, flags_str[i].string, NULL,
+				   mtf & flags_str[i].flag);
 			if (mtf & flags_str[i].flag)
-				fprintf(f, "%s", flags_str[i].string);
+				print_string(PRINT_FP, NULL, "%s",
+					     flags_str[i].string);
 			else
-				fprintf(f, "no%s", flags_str[i].string);
+				print_string(PRINT_FP, NULL, "no%s",
+					     flags_str[i].string);
 		}
 	}
+	if (count)
+		close_json_object();
 }
 
-static void flower_print_ip_addr(FILE *f, char *name, __be16 eth_type,
+static void flower_print_ip_addr(char *name, __be16 eth_type,
 				 struct rtattr *addr4_attr,
 				 struct rtattr *mask4_attr,
 				 struct rtattr *addr6_attr,
@@ -1160,6 +1184,9 @@ static void flower_print_ip_addr(FILE *f, char *name, __be16 eth_type,
 {
 	struct rtattr *addr_attr;
 	struct rtattr *mask_attr;
+	SPRINT_BUF(namefrm);
+	SPRINT_BUF(out);
+	size_t done;
 	int family;
 	size_t len;
 	int bits;
@@ -1179,56 +1206,75 @@ static void flower_print_ip_addr(FILE *f, char *name, __be16 eth_type,
 	}
 	if (!addr_attr || RTA_PAYLOAD(addr_attr) != len)
 		return;
-	fprintf(f, "\n  %s %s", name, rt_addr_n2a_rta(family, addr_attr));
 	if (!mask_attr || RTA_PAYLOAD(mask_attr) != len)
 		return;
+	done = sprintf(out, "%s", rt_addr_n2a_rta(family, addr_attr));
 	bits = __mask_bits(RTA_DATA(mask_attr), len);
 	if (bits < 0)
-		fprintf(f, "/%s", rt_addr_n2a_rta(family, mask_attr));
+		sprintf(out + done, "/%s", rt_addr_n2a_rta(family, mask_attr));
 	else if (bits < len * 8)
-		fprintf(f, "/%d", bits);
+		sprintf(out + done, "/%d", bits);
+
+	sprintf(namefrm, "\n  %s %%s", name);
+	print_string(PRINT_ANY, name, namefrm, out);
 }
-static void flower_print_ip4_addr(FILE *f, char *name,
-				  struct rtattr *addr_attr,
+static void flower_print_ip4_addr(char *name, struct rtattr *addr_attr,
 				  struct rtattr *mask_attr)
 {
-	return flower_print_ip_addr(f, name, htons(ETH_P_IP),
+	return flower_print_ip_addr(name, htons(ETH_P_IP),
 				    addr_attr, mask_attr, 0, 0);
 }
 
-static void flower_print_port(FILE *f, char *name, struct rtattr *attr)
+static void flower_print_port(char *name, struct rtattr *attr)
 {
-	if (attr)
-		fprintf(f, "\n  %s %d", name, rta_getattr_be16(attr));
+	SPRINT_BUF(namefrm);
+
+	if (!attr)
+		return;
+
+	sprintf(namefrm,"\n  %s %%u", name);
+	print_uint(PRINT_ANY, name, namefrm, rta_getattr_be16(attr));
 }
 
-static void flower_print_tcp_flags(FILE *f, char *name,
-				  struct rtattr *flags_attr,
-				  struct rtattr *mask_attr)
+static void flower_print_tcp_flags(char *name, struct rtattr *flags_attr,
+				   struct rtattr *mask_attr)
 {
+	SPRINT_BUF(namefrm);
+	SPRINT_BUF(out);
+	size_t done;
+
 	if (!flags_attr)
 		return;
-	fprintf(f, "\n  %s %x", name, rta_getattr_be16(flags_attr));
-	if (!mask_attr)
-		return;
-	fprintf(f, "/%x", rta_getattr_be16(mask_attr));
+
+	done = sprintf(out, "%x", rta_getattr_be16(flags_attr));
+	if (mask_attr)
+		sprintf(out + done, "%x", rta_getattr_be16(flags_attr));
+
+	sprintf(namefrm, "\n  %s %%s", name);
+	print_string(PRINT_ANY, name, namefrm, out);
 }
 
 
-static void flower_print_key_id(FILE *f, const char *name,
-				struct rtattr *attr)
+static void flower_print_key_id(const char *name, struct rtattr *attr)
 {
-	if (attr)
-		fprintf(f, "\n  %s %d", name, rta_getattr_be32(attr));
+	SPRINT_BUF(namefrm);
+
+	if (!attr)
+		return;
+
+	sprintf(namefrm,"\n  %s %%u", name);
+	print_uint(PRINT_ANY, name, namefrm, rta_getattr_be32(attr));
 }
 
-static void flower_print_masked_u8(FILE *f, const char *name,
-				   struct rtattr *attr,
+static void flower_print_masked_u8(const char *name, struct rtattr *attr,
 				   struct rtattr *mask_attr,
 				   const char *(*value_to_str)(__u8 value))
 {
 	const char *value_str = NULL;
 	__u8 value, mask;
+	SPRINT_BUF(namefrm);
+	SPRINT_BUF(out);
+	size_t done;
 
 	if (!attr)
 		return;
@@ -1238,39 +1284,39 @@ static void flower_print_masked_u8(FILE *f, const char *name,
 	if (mask == UINT8_MAX && value_to_str)
 		value_str = value_to_str(value);
 
-	fprintf(f, "\n  %s ", name);
-
 	if (value_str)
-		fputs(value_str, f);
+		done = sprintf(out, "%s", value_str);
 	else
-		fprintf(f, "%d", value);
+		done = sprintf(out, "%d", value);
 
 	if (mask != UINT8_MAX)
-		fprintf(f, "/%d", mask);
+		sprintf(out + done, "/%d", mask);
+
+	sprintf(namefrm,"\n  %s %%s", name);
+	print_string(PRINT_ANY, name, namefrm, out);
 }
 
-static void flower_print_u8(FILE *f, const char *name, struct rtattr *attr)
+static void flower_print_u8(const char *name, struct rtattr *attr)
 {
-	flower_print_masked_u8(f, name, attr, NULL, NULL);
+	flower_print_masked_u8(name, attr, NULL, NULL);
 }
 
-static void flower_print_u32(FILE *f, const char *name, struct rtattr *attr)
+static void flower_print_u32(const char *name, struct rtattr *attr)
 {
-	__u32 value;
+	SPRINT_BUF(namefrm);
 
 	if (!attr)
 		return;
 
-	value = rta_getattr_u32(attr);
-
-	fprintf(f, "\n  %s %d", name, value);
+	sprintf(namefrm,"\n  %s %%u", name);
+	print_uint(PRINT_ANY, name, namefrm, rta_getattr_u32(attr));
 }
 
-static void flower_print_arp_op(FILE *f, const char *name,
+static void flower_print_arp_op(const char *name,
 				struct rtattr *op_attr,
 				struct rtattr *mask_attr)
 {
-	flower_print_masked_u8(f, name, op_attr, mask_attr,
+	flower_print_masked_u8(name, op_attr, mask_attr,
 			       flower_print_arp_op_to_name);
 }
 
@@ -1288,7 +1334,7 @@ static int flower_print_opt(struct filter_util *qu, FILE *f,
 	parse_rtattr_nested(tb, TCA_FLOWER_MAX, opt);
 
 	if (handle)
-		fprintf(f, "handle 0x%x ", handle);
+		print_uint(PRINT_ANY, "handle", "handle 0x%x ", handle);
 
 	if (tb[TCA_FLOWER_CLASSID]) {
 		__u32 h = rta_getattr_u32(tb[TCA_FLOWER_CLASSID]);
@@ -1296,56 +1342,62 @@ static int flower_print_opt(struct filter_util *qu, FILE *f,
 		if (TC_H_MIN(h) < TC_H_MIN_PRIORITY ||
 		    TC_H_MIN(h) > (TC_H_MIN_PRIORITY + TC_QOPT_MAX_QUEUE - 1)) {
 			SPRINT_BUF(b1);
-			fprintf(f, "classid %s ", sprint_tc_classid(h, b1));
+			print_string(PRINT_ANY, "classid", "classid %s ",
+				     sprint_tc_classid(h, b1));
 		} else {
-			fprintf(f, "hw_tc %u ",
-				TC_H_MIN(h) - TC_H_MIN_PRIORITY);
+			print_uint(PRINT_ANY, "hw_tc", "hw_tc %u ",
+				   TC_H_MIN(h) - TC_H_MIN_PRIORITY);
 		}
 	}
 
 	if (tb[TCA_FLOWER_INDEV]) {
 		struct rtattr *attr = tb[TCA_FLOWER_INDEV];
 
-		fprintf(f, "\n  indev %s", rta_getattr_str(attr));
+		print_string(PRINT_ANY, "indev", "\n  indev %s",
+			     rta_getattr_str(attr));
 	}
 
+	open_json_object("keys");
+
 	if (tb[TCA_FLOWER_KEY_VLAN_ID]) {
 		struct rtattr *attr = tb[TCA_FLOWER_KEY_VLAN_ID];
 
-		fprintf(f, "\n  vlan_id %d", rta_getattr_u16(attr));
+		print_uint(PRINT_ANY, "vlan_id", "\n  vlan_id %u",
+			   rta_getattr_u16(attr));
 	}
 
 	if (tb[TCA_FLOWER_KEY_VLAN_PRIO]) {
 		struct rtattr *attr = tb[TCA_FLOWER_KEY_VLAN_PRIO];
 
-		fprintf(f, "\n  vlan_prio %d", rta_getattr_u8(attr));
+		print_uint(PRINT_ANY, "vlan_prio", "\n  vlan_prio %d",
+			   rta_getattr_u8(attr));
 	}
 
-	flower_print_eth_addr(f, "dst_mac", tb[TCA_FLOWER_KEY_ETH_DST],
+	flower_print_eth_addr("dst_mac", tb[TCA_FLOWER_KEY_ETH_DST],
 			      tb[TCA_FLOWER_KEY_ETH_DST_MASK]);
-	flower_print_eth_addr(f, "src_mac", tb[TCA_FLOWER_KEY_ETH_SRC],
+	flower_print_eth_addr("src_mac", tb[TCA_FLOWER_KEY_ETH_SRC],
 			      tb[TCA_FLOWER_KEY_ETH_SRC_MASK]);
 
-	flower_print_eth_type(f, &eth_type, tb[TCA_FLOWER_KEY_ETH_TYPE]);
-	flower_print_ip_proto(f, &ip_proto, tb[TCA_FLOWER_KEY_IP_PROTO]);
+	flower_print_eth_type(&eth_type, tb[TCA_FLOWER_KEY_ETH_TYPE]);
+	flower_print_ip_proto(&ip_proto, tb[TCA_FLOWER_KEY_IP_PROTO]);
 
-	flower_print_ip_attr(f, "ip_tos", tb[TCA_FLOWER_KEY_IP_TOS],
+	flower_print_ip_attr("ip_tos", tb[TCA_FLOWER_KEY_IP_TOS],
 			    tb[TCA_FLOWER_KEY_IP_TOS_MASK]);
-	flower_print_ip_attr(f, "ip_ttl", tb[TCA_FLOWER_KEY_IP_TTL],
+	flower_print_ip_attr("ip_ttl", tb[TCA_FLOWER_KEY_IP_TTL],
 			    tb[TCA_FLOWER_KEY_IP_TTL_MASK]);
 
-	flower_print_u32(f, "mpls_label", tb[TCA_FLOWER_KEY_MPLS_LABEL]);
-	flower_print_u8(f, "mpls_tc", tb[TCA_FLOWER_KEY_MPLS_TC]);
-	flower_print_u8(f, "mpls_bos", tb[TCA_FLOWER_KEY_MPLS_BOS]);
-	flower_print_u8(f, "mpls_ttl", tb[TCA_FLOWER_KEY_MPLS_TTL]);
+	flower_print_u32("mpls_label", tb[TCA_FLOWER_KEY_MPLS_LABEL]);
+	flower_print_u8("mpls_tc", tb[TCA_FLOWER_KEY_MPLS_TC]);
+	flower_print_u8("mpls_bos", tb[TCA_FLOWER_KEY_MPLS_BOS]);
+	flower_print_u8("mpls_ttl", tb[TCA_FLOWER_KEY_MPLS_TTL]);
 
-	flower_print_ip_addr(f, "dst_ip", eth_type,
+	flower_print_ip_addr("dst_ip", eth_type,
 			     tb[TCA_FLOWER_KEY_IPV4_DST],
 			     tb[TCA_FLOWER_KEY_IPV4_DST_MASK],
 			     tb[TCA_FLOWER_KEY_IPV6_DST],
 			     tb[TCA_FLOWER_KEY_IPV6_DST_MASK]);
 
-	flower_print_ip_addr(f, "src_ip", eth_type,
+	flower_print_ip_addr("src_ip", eth_type,
 			     tb[TCA_FLOWER_KEY_IPV4_SRC],
 			     tb[TCA_FLOWER_KEY_IPV4_SRC_MASK],
 			     tb[TCA_FLOWER_KEY_IPV6_SRC],
@@ -1353,12 +1405,12 @@ static int flower_print_opt(struct filter_util *qu, FILE *f,
 
 	nl_type = flower_port_attr_type(ip_proto, FLOWER_ENDPOINT_DST);
 	if (nl_type >= 0)
-		flower_print_port(f, "dst_port", tb[nl_type]);
+		flower_print_port("dst_port", tb[nl_type]);
 	nl_type = flower_port_attr_type(ip_proto, FLOWER_ENDPOINT_SRC);
 	if (nl_type >= 0)
-		flower_print_port(f, "src_port", tb[nl_type]);
+		flower_print_port("src_port", tb[nl_type]);
 
-	flower_print_tcp_flags(f, "tcp_flags", tb[TCA_FLOWER_KEY_TCP_FLAGS],
+	flower_print_tcp_flags("tcp_flags", tb[TCA_FLOWER_KEY_TCP_FLAGS],
 			       tb[TCA_FLOWER_KEY_TCP_FLAGS_MASK]);
 
 	nl_type = flower_icmp_attr_type(eth_type, ip_proto,
@@ -1366,7 +1418,7 @@ static int flower_print_opt(struct filter_util *qu, FILE *f,
 	nl_mask_type = flower_icmp_attr_mask_type(eth_type, ip_proto,
 						  FLOWER_ICMP_FIELD_TYPE);
 	if (nl_type >= 0 && nl_mask_type >= 0)
-		flower_print_masked_u8(f, "icmp_type", tb[nl_type],
+		flower_print_masked_u8("icmp_type", tb[nl_type],
 				       tb[nl_mask_type], NULL);
 
 	nl_type = flower_icmp_attr_type(eth_type, ip_proto,
@@ -1374,21 +1426,21 @@ static int flower_print_opt(struct filter_util *qu, FILE *f,
 	nl_mask_type = flower_icmp_attr_mask_type(eth_type, ip_proto,
 						  FLOWER_ICMP_FIELD_CODE);
 	if (nl_type >= 0 && nl_mask_type >= 0)
-		flower_print_masked_u8(f, "icmp_code", tb[nl_type],
+		flower_print_masked_u8("icmp_code", tb[nl_type],
 				       tb[nl_mask_type], NULL);
 
-	flower_print_ip4_addr(f, "arp_sip", tb[TCA_FLOWER_KEY_ARP_SIP],
+	flower_print_ip4_addr("arp_sip", tb[TCA_FLOWER_KEY_ARP_SIP],
 			     tb[TCA_FLOWER_KEY_ARP_SIP_MASK]);
-	flower_print_ip4_addr(f, "arp_tip", tb[TCA_FLOWER_KEY_ARP_TIP],
+	flower_print_ip4_addr("arp_tip", tb[TCA_FLOWER_KEY_ARP_TIP],
 			     tb[TCA_FLOWER_KEY_ARP_TIP_MASK]);
-	flower_print_arp_op(f, "arp_op", tb[TCA_FLOWER_KEY_ARP_OP],
+	flower_print_arp_op("arp_op", tb[TCA_FLOWER_KEY_ARP_OP],
 			    tb[TCA_FLOWER_KEY_ARP_OP_MASK]);
-	flower_print_eth_addr(f, "arp_sha", tb[TCA_FLOWER_KEY_ARP_SHA],
+	flower_print_eth_addr("arp_sha", tb[TCA_FLOWER_KEY_ARP_SHA],
 			      tb[TCA_FLOWER_KEY_ARP_SHA_MASK]);
-	flower_print_eth_addr(f, "arp_tha", tb[TCA_FLOWER_KEY_ARP_THA],
+	flower_print_eth_addr("arp_tha", tb[TCA_FLOWER_KEY_ARP_THA],
 			      tb[TCA_FLOWER_KEY_ARP_THA_MASK]);
 
-	flower_print_ip_addr(f, "enc_dst_ip",
+	flower_print_ip_addr("enc_dst_ip",
 			     tb[TCA_FLOWER_KEY_ENC_IPV4_DST_MASK] ?
 			     htons(ETH_P_IP) : htons(ETH_P_IPV6),
 			     tb[TCA_FLOWER_KEY_ENC_IPV4_DST],
@@ -1396,7 +1448,7 @@ static int flower_print_opt(struct filter_util *qu, FILE *f,
 			     tb[TCA_FLOWER_KEY_ENC_IPV6_DST],
 			     tb[TCA_FLOWER_KEY_ENC_IPV6_DST_MASK]);
 
-	flower_print_ip_addr(f, "enc_src_ip",
+	flower_print_ip_addr("enc_src_ip",
 			     tb[TCA_FLOWER_KEY_ENC_IPV4_SRC_MASK] ?
 			     htons(ETH_P_IP) : htons(ETH_P_IPV6),
 			     tb[TCA_FLOWER_KEY_ENC_IPV4_SRC],
@@ -1404,29 +1456,28 @@ static int flower_print_opt(struct filter_util *qu, FILE *f,
 			     tb[TCA_FLOWER_KEY_ENC_IPV6_SRC],
 			     tb[TCA_FLOWER_KEY_ENC_IPV6_SRC_MASK]);
 
-	flower_print_key_id(f, "enc_key_id",
-			    tb[TCA_FLOWER_KEY_ENC_KEY_ID]);
+	flower_print_key_id("enc_key_id", tb[TCA_FLOWER_KEY_ENC_KEY_ID]);
 
-	flower_print_port(f, "enc_dst_port",
-			  tb[TCA_FLOWER_KEY_ENC_UDP_DST_PORT]);
+	flower_print_port("enc_dst_port", tb[TCA_FLOWER_KEY_ENC_UDP_DST_PORT]);
 
-	flower_print_matching_flags(f, "ip_flags",
-				    FLOWER_IP_FLAGS,
+	flower_print_matching_flags("ip_flags", FLOWER_IP_FLAGS,
 				    tb[TCA_FLOWER_KEY_FLAGS],
 				    tb[TCA_FLOWER_KEY_FLAGS_MASK]);
 
+	close_json_object();
+
 	if (tb[TCA_FLOWER_FLAGS]) {
 		__u32 flags = rta_getattr_u32(tb[TCA_FLOWER_FLAGS]);
 
 		if (flags & TCA_CLS_FLAGS_SKIP_HW)
-			fprintf(f, "\n  skip_hw");
+			print_bool(PRINT_ANY, "skip_hw", "\n  skip_hw", true);
 		if (flags & TCA_CLS_FLAGS_SKIP_SW)
-			fprintf(f, "\n  skip_sw");
+			print_bool(PRINT_ANY, "skip_sw", "\n  skip_sw", true);
 
 		if (flags & TCA_CLS_FLAGS_IN_HW)
-			fprintf(f, "\n  in_hw");
+			print_bool(PRINT_ANY, "in_hw", "\n  in_hw", true);
 		else if (flags & TCA_CLS_FLAGS_NOT_IN_HW)
-			fprintf(f, "\n  not_in_hw");
+			print_bool(PRINT_ANY, "not_in_hw", "\n  not_in_hw", true);
 	}
 
 	if (tb[TCA_FLOWER_ACT])
-- 
2.9.5

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [patch iproute2 07/11] tc: jsonify matchall filter
  2017-11-25 14:48 [patch iproute2 00/11] tc: jsonify couple of qdics, filter and actions Jiri Pirko
                   ` (5 preceding siblings ...)
  2017-11-25 14:48 ` [patch iproute2 06/11] tc: jsonify flower filter Jiri Pirko
@ 2017-11-25 14:48 ` Jiri Pirko
  2017-11-25 14:48 ` [patch iproute2 08/11] tc: jsonify actions core Jiri Pirko
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Jiri Pirko @ 2017-11-25 14:48 UTC (permalink / raw)
  To: netdev; +Cc: stephen, jhs, mlxsw

From: Jiri Pirko <jiri@mellanox.com>

Add json output to matchall filter.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 tc/f_matchall.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/tc/f_matchall.c b/tc/f_matchall.c
index 183f261..5ebd041 100644
--- a/tc/f_matchall.c
+++ b/tc/f_matchall.c
@@ -121,11 +121,11 @@ static int matchall_print_opt(struct filter_util *qu, FILE *f,
 	parse_rtattr_nested(tb, TCA_MATCHALL_MAX, opt);
 
 	if (handle)
-		fprintf(f, "handle 0x%x ", handle);
+		print_uint(PRINT_ANY, "handle", "handle 0x%x ", handle);
 
 	if (tb[TCA_MATCHALL_CLASSID]) {
 		SPRINT_BUF(b1);
-		fprintf(f, "flowid %s ",
+		print_string(PRINT_ANY, "flowid", "flowid %s ",
 			sprint_tc_classid(rta_getattr_u32(tb[TCA_MATCHALL_CLASSID]), b1));
 	}
 
@@ -133,14 +133,14 @@ static int matchall_print_opt(struct filter_util *qu, FILE *f,
 		__u32 flags = rta_getattr_u32(tb[TCA_MATCHALL_FLAGS]);
 
 		if (flags & TCA_CLS_FLAGS_SKIP_HW)
-			fprintf(f, "\n  skip_hw");
+			print_bool(PRINT_ANY, "skip_hw", "\n  skip_hw", true);
 		if (flags & TCA_CLS_FLAGS_SKIP_SW)
-			fprintf(f, "\n  skip_sw");
+			print_bool(PRINT_ANY, "skip_sw", "\n  skip_sw", true);
 
 		if (flags & TCA_CLS_FLAGS_IN_HW)
-			fprintf(f, "\n  in_hw");
+			print_bool(PRINT_ANY, "in_hw", "\n  in_hw", true);
 		else if (flags & TCA_CLS_FLAGS_NOT_IN_HW)
-			fprintf(f, "\n  not_in_hw");
+			print_bool(PRINT_ANY, "not_in_hw", "\n  not_in_hw", true);
 	}
 
 	if (tb[TCA_MATCHALL_ACT])
-- 
2.9.5

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [patch iproute2 08/11] tc: jsonify actions core
  2017-11-25 14:48 [patch iproute2 00/11] tc: jsonify couple of qdics, filter and actions Jiri Pirko
                   ` (6 preceding siblings ...)
  2017-11-25 14:48 ` [patch iproute2 07/11] tc: jsonify matchall filter Jiri Pirko
@ 2017-11-25 14:48 ` Jiri Pirko
  2017-11-25 14:48 ` [patch iproute2 09/11] tc: jsonify gact action Jiri Pirko
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Jiri Pirko @ 2017-11-25 14:48 UTC (permalink / raw)
  To: netdev; +Cc: stephen, jhs, mlxsw

From: Jiri Pirko <jiri@mellanox.com>

Add json output to actions core.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 tc/m_action.c | 22 +++++++++++++++-------
 tc/tc_util.c  | 34 ++++++++++++++++++++++++----------
 2 files changed, 39 insertions(+), 17 deletions(-)

diff --git a/tc/m_action.c b/tc/m_action.c
index e6d9149..0940a39 100644
--- a/tc/m_action.c
+++ b/tc/m_action.c
@@ -301,17 +301,19 @@ static int tc_print_one_action(FILE *f, struct rtattr *arg)
 		return err;
 
 	if (show_stats && tb[TCA_ACT_STATS]) {
-		fprintf(f, "\tAction statistics:\n");
+		print_string(PRINT_FP, NULL, "\tAction statistics:\n", NULL);
+		open_json_object("stats");
 		print_tcstats2_attr(f, tb[TCA_ACT_STATS], "\t", NULL);
-		fprintf(f, "\n");
+		close_json_object();
+		print_string(PRINT_FP, NULL, "\n", NULL);
 	}
 	if (tb[TCA_ACT_COOKIE]) {
 		int strsz = RTA_PAYLOAD(tb[TCA_ACT_COOKIE]);
 		char b1[strsz * 2 + 1];
 
-		fprintf(f, "\tcookie %s\n",
-			hexstring_n2a(RTA_DATA(tb[TCA_ACT_COOKIE]),
-				      strsz, b1, sizeof(b1)));
+		print_string(PRINT_ANY, "cookie", "\tcookie %s\n",
+			     hexstring_n2a(RTA_DATA(tb[TCA_ACT_COOKIE]),
+					   strsz, b1, sizeof(b1)));
 	}
 
 	return 0;
@@ -362,15 +364,21 @@ tc_print_action(FILE *f, const struct rtattr *arg, unsigned short tot_acts)
 	if (tab_flush && NULL != tb[0]  && NULL == tb[1])
 		return tc_print_action_flush(f, tb[0]);
 
+	open_json_array(PRINT_JSON, "actions");
 	for (i = 0; i < tot_acts; i++) {
 		if (tb[i]) {
-			fprintf(f, "\n\taction order %d: ", i);
+			open_json_object(NULL);
+			print_uint(PRINT_ANY, "order",
+				   "\n\taction order %u: ", i);
 			if (tc_print_one_action(f, tb[i]) < 0) {
-				fprintf(f, "Error printing action\n");
+				print_string(PRINT_FP, NULL,
+					     "Error printing action\n", NULL);
 			}
+			close_json_object();
 		}
 
 	}
+	close_json_object();
 
 	return 0;
 }
diff --git a/tc/tc_util.c b/tc/tc_util.c
index d276987..1887905 100644
--- a/tc/tc_util.c
+++ b/tc/tc_util.c
@@ -709,12 +709,17 @@ int parse_action_control_slash(int *argc_p, char ***argv_p,
 void print_action_control(FILE *f, const char *prefix,
 			  int action, const char *suffix)
 {
-	fprintf(f, "%s%s", prefix, action_n2a(action));
+	print_string(PRINT_FP, NULL, "%s", prefix);
+	open_json_object("control_action");
+	print_string(PRINT_ANY, "type", "%s", action_n2a(action));
 	if (TC_ACT_EXT_CMP(action, TC_ACT_GOTO_CHAIN))
-		fprintf(f, " chain %u", action & TC_ACT_EXT_VAL_MASK);
+		print_uint(PRINT_ANY, "chain", " chain %u",
+			   action & TC_ACT_EXT_VAL_MASK);
 	if (TC_ACT_EXT_CMP(action, TC_ACT_JUMP))
-		fprintf(f, " %u", action & TC_ACT_EXT_VAL_MASK);
-	fprintf(f, "%s", suffix);
+		print_uint(PRINT_ANY, "jump", " %u",
+			   action & TC_ACT_EXT_VAL_MASK);
+	close_json_object();
+	print_string(PRINT_FP, NULL, "%s", suffix);
 }
 
 int get_linklayer(unsigned int *val, const char *arg)
@@ -762,12 +767,21 @@ void print_tm(FILE *f, const struct tcf_t *tm)
 {
 	int hz = get_user_hz();
 
-	if (tm->install != 0)
-		fprintf(f, " installed %u sec", (unsigned int)(tm->install/hz));
-	if (tm->lastuse != 0)
-		fprintf(f, " used %u sec", (unsigned int)(tm->lastuse/hz));
-	if (tm->expires != 0)
-		fprintf(f, " expires %u sec", (unsigned int)(tm->expires/hz));
+	if (tm->install != 0) {
+		print_uint(PRINT_JSON, "installed", NULL, tm->install);
+		print_uint(PRINT_FP, NULL, " installed %u sec",
+			   (unsigned int)(tm->install/hz));
+	}
+	if (tm->lastuse != 0) {
+		print_uint(PRINT_JSON, "last_used", NULL, tm->lastuse);
+		print_uint(PRINT_FP, NULL, " used %u sec",
+			   (unsigned int)(tm->lastuse/hz));
+	}
+	if (tm->expires != 0) {
+		print_uint(PRINT_JSON, "expires", NULL, tm->expires);
+		print_uint(PRINT_FP, NULL, " expires %u sec",
+			   (unsigned int)(tm->expires/hz));
+	}
 }
 
 void print_tcstats2_attr(FILE *fp, struct rtattr *rta, char *prefix, struct rtattr **xstats)
-- 
2.9.5

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [patch iproute2 09/11] tc: jsonify gact action
  2017-11-25 14:48 [patch iproute2 00/11] tc: jsonify couple of qdics, filter and actions Jiri Pirko
                   ` (7 preceding siblings ...)
  2017-11-25 14:48 ` [patch iproute2 08/11] tc: jsonify actions core Jiri Pirko
@ 2017-11-25 14:48 ` Jiri Pirko
  2017-11-25 14:48 ` [patch iproute2 10/11] tc: jsonify mirred action Jiri Pirko
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Jiri Pirko @ 2017-11-25 14:48 UTC (permalink / raw)
  To: netdev; +Cc: stephen, jhs, mlxsw

From: Jiri Pirko <jiri@mellanox.com>

Add json output to gact action.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 tc/m_gact.c | 18 +++++++++++-------
 1 file changed, 11 insertions(+), 7 deletions(-)

diff --git a/tc/m_gact.c b/tc/m_gact.c
index efe992f..905aa51 100644
--- a/tc/m_gact.c
+++ b/tc/m_gact.c
@@ -175,12 +175,12 @@ print_gact(struct action_util *au, FILE * f, struct rtattr *arg)
 	parse_rtattr_nested(tb, TCA_GACT_MAX, arg);
 
 	if (tb[TCA_GACT_PARMS] == NULL) {
-		fprintf(f, "[NULL gact parameters]");
+		print_string(PRINT_FP, NULL, "%s", "[NULL gact parameters]");
 		return -1;
 	}
 	p = RTA_DATA(tb[TCA_GACT_PARMS]);
 
-	fprintf(f, "gact ");
+	print_string(PRINT_ANY, "kind", "%s ", "gact");
 	print_action_control(f, "action ", p->action, "");
 #ifdef CONFIG_GACT_PROB
 	if (tb[TCA_GACT_PROB] != NULL) {
@@ -190,12 +190,16 @@ print_gact(struct action_util *au, FILE * f, struct rtattr *arg)
 		memset(&pp_dummy, 0, sizeof(pp_dummy));
 		pp = &pp_dummy;
 	}
-	fprintf(f, "\n\t random type %s", prob_n2a(pp->ptype));
+	open_json_object("prob");
+	print_string(PRINT_ANY, "random_type", "\n\t random type %s",
+		     prob_n2a(pp->ptype));
 	print_action_control(f, " ", pp->paction, " ");
-	fprintf(f, "val %d", pp->pval);
+	print_int(PRINT_ANY, "val", "val %d", pp->pval);
+	close_json_object();
 #endif
-	fprintf(f, "\n\t index %u ref %d bind %d", p->index, p->refcnt,
-		p->bindcnt);
+	print_uint(PRINT_ANY, "index", "\n\t index %u", p->index);
+	print_int(PRINT_ANY, "ref", " ref %d", p->refcnt);
+	print_int(PRINT_ANY, "bind", " bind %d", p->bindcnt);
 	if (show_stats) {
 		if (tb[TCA_GACT_TM]) {
 			struct tcf_t *tm = RTA_DATA(tb[TCA_GACT_TM]);
@@ -203,7 +207,7 @@ print_gact(struct action_util *au, FILE * f, struct rtattr *arg)
 			print_tm(f, tm);
 		}
 	}
-	fprintf(f, "\n ");
+	print_string(PRINT_FP, NULL, "%s", "\n");
 	return 0;
 }
 
-- 
2.9.5

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [patch iproute2 10/11] tc: jsonify mirred action
  2017-11-25 14:48 [patch iproute2 00/11] tc: jsonify couple of qdics, filter and actions Jiri Pirko
                   ` (8 preceding siblings ...)
  2017-11-25 14:48 ` [patch iproute2 09/11] tc: jsonify gact action Jiri Pirko
@ 2017-11-25 14:48 ` Jiri Pirko
  2017-11-25 14:48 ` [patch iproute2 11/11] tc: jsonify vlan action Jiri Pirko
  2017-11-26 20:44 ` [patch iproute2 00/11] tc: jsonify couple of qdics, filter and actions Stephen Hemminger
  11 siblings, 0 replies; 14+ messages in thread
From: Jiri Pirko @ 2017-11-25 14:48 UTC (permalink / raw)
  To: netdev; +Cc: stephen, jhs, mlxsw

From: Jiri Pirko <jiri@mellanox.com>

Add json output to mirred action.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 tc/m_mirred.c | 46 ++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 40 insertions(+), 6 deletions(-)

diff --git a/tc/m_mirred.c b/tc/m_mirred.c
index 33c915d..c771632 100644
--- a/tc/m_mirred.c
+++ b/tc/m_mirred.c
@@ -60,6 +60,34 @@ static const char *mirred_n2a(int action)
 	}
 }
 
+static const char *mirred_direction(int action)
+{
+	switch (action) {
+	case TCA_EGRESS_REDIR:
+	case TCA_EGRESS_MIRROR:
+		return "egress";
+	case TCA_INGRESS_REDIR:
+	case TCA_INGRESS_MIRROR:
+		return "ingress";
+	default:
+		return "unknown";
+	}
+}
+
+static const char *mirred_action(int action)
+{
+	switch (action) {
+	case TCA_EGRESS_REDIR:
+	case TCA_INGRESS_REDIR:
+		return "redirect";
+	case TCA_EGRESS_MIRROR:
+	case TCA_INGRESS_MIRROR:
+		return "mirror";
+	default:
+		return "unknown";
+	}
+}
+
 static int
 parse_direction(struct action_util *a, int *argc_p, char ***argv_p,
 		int tca_id, struct nlmsghdr *n)
@@ -254,7 +282,7 @@ print_mirred(struct action_util *au, FILE * f, struct rtattr *arg)
 	parse_rtattr_nested(tb, TCA_MIRRED_MAX, arg);
 
 	if (tb[TCA_MIRRED_PARMS] == NULL) {
-		fprintf(f, "[NULL mirred parameters]");
+		print_string(PRINT_FP, NULL, "%s", "[NULL mirred parameters]");
 		return -1;
 	}
 	p = RTA_DATA(tb[TCA_MIRRED_PARMS]);
@@ -269,12 +297,18 @@ print_mirred(struct action_util *au, FILE * f, struct rtattr *arg)
 		return -1;
 	}
 
-	fprintf(f, "mirred (%s to device %s)", mirred_n2a(p->eaction), dev);
+	print_string(PRINT_ANY, "kind", "%s ", "mirred");
+	print_string(PRINT_FP, NULL, "(%s", mirred_n2a(p->eaction));
+	print_string(PRINT_JSON, "mirred_action", NULL,
+		     mirred_action(p->eaction));
+	print_string(PRINT_JSON, "direction", NULL,
+		     mirred_direction(p->eaction));
+	print_string(PRINT_ANY, "to_dev", " to device %s)", dev);
 	print_action_control(f, " ", p->action, "");
 
-	fprintf(f, "\n ");
-	fprintf(f, "\tindex %u ref %d bind %d", p->index, p->refcnt,
-		p->bindcnt);
+	print_uint(PRINT_ANY, "index", "\n \tindex %u", p->index);
+	print_int(PRINT_ANY, "ref", " ref %d", p->refcnt);
+	print_int(PRINT_ANY, "bind", " bind %d", p->bindcnt);
 
 	if (show_stats) {
 		if (tb[TCA_MIRRED_TM]) {
@@ -283,7 +317,7 @@ print_mirred(struct action_util *au, FILE * f, struct rtattr *arg)
 			print_tm(f, tm);
 		}
 	}
-	fprintf(f, "\n ");
+	print_string(PRINT_FP, NULL, "%s", "\n ");
 	return 0;
 }
 
-- 
2.9.5

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [patch iproute2 11/11] tc: jsonify vlan action
  2017-11-25 14:48 [patch iproute2 00/11] tc: jsonify couple of qdics, filter and actions Jiri Pirko
                   ` (9 preceding siblings ...)
  2017-11-25 14:48 ` [patch iproute2 10/11] tc: jsonify mirred action Jiri Pirko
@ 2017-11-25 14:48 ` Jiri Pirko
  2017-11-26 20:44 ` [patch iproute2 00/11] tc: jsonify couple of qdics, filter and actions Stephen Hemminger
  11 siblings, 0 replies; 14+ messages in thread
From: Jiri Pirko @ 2017-11-25 14:48 UTC (permalink / raw)
  To: netdev; +Cc: stephen, jhs, mlxsw

From: Jiri Pirko <jiri@mellanox.com>

Add json output to vlan action.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 tc/m_vlan.c | 26 ++++++++++++--------------
 1 file changed, 12 insertions(+), 14 deletions(-)

diff --git a/tc/m_vlan.c b/tc/m_vlan.c
index cccb499..44254b6 100644
--- a/tc/m_vlan.c
+++ b/tc/m_vlan.c
@@ -195,39 +195,37 @@ static int print_vlan(struct action_util *au, FILE *f, struct rtattr *arg)
 	parse_rtattr_nested(tb, TCA_VLAN_MAX, arg);
 
 	if (!tb[TCA_VLAN_PARMS]) {
-		fprintf(f, "[NULL vlan parameters]");
+		print_string(PRINT_FP, NULL, "%s", "[NULL vlan parameters]");
 		return -1;
 	}
 	parm = RTA_DATA(tb[TCA_VLAN_PARMS]);
 
-	fprintf(f, " vlan");
+	print_string(PRINT_ANY, "kind", "%s ", "vlan");
+	print_string(PRINT_ANY, "vlan_action", " %s", action_names[parm->v_action]);
 
 	switch (parm->v_action) {
-	case TCA_VLAN_ACT_POP:
-		fprintf(f, " pop");
-		break;
 	case TCA_VLAN_ACT_PUSH:
 	case TCA_VLAN_ACT_MODIFY:
-		fprintf(f, " %s", action_names[parm->v_action]);
 		if (tb[TCA_VLAN_PUSH_VLAN_ID]) {
 			val = rta_getattr_u16(tb[TCA_VLAN_PUSH_VLAN_ID]);
-			fprintf(f, " id %u", val);
+			print_uint(PRINT_ANY, "id", " id %u", val);
 		}
 		if (tb[TCA_VLAN_PUSH_VLAN_PROTOCOL]) {
-			fprintf(f, " protocol %s",
-				ll_proto_n2a(rta_getattr_u16(tb[TCA_VLAN_PUSH_VLAN_PROTOCOL]),
-					     b1, sizeof(b1)));
+			print_string(PRINT_ANY, "protocol", " protocol %s",
+				     ll_proto_n2a(rta_getattr_u16(tb[TCA_VLAN_PUSH_VLAN_PROTOCOL]),
+						  b1, sizeof(b1)));
 		}
 		if (tb[TCA_VLAN_PUSH_VLAN_PRIORITY]) {
 			val = rta_getattr_u8(tb[TCA_VLAN_PUSH_VLAN_PRIORITY]);
-			fprintf(f, " priority %u", val);
+			print_uint(PRINT_ANY, "priority", " priority %u", val);
 		}
 		break;
 	}
 	print_action_control(f, " ", parm->action, "");
 
-	fprintf(f, "\n\t index %u ref %d bind %d", parm->index, parm->refcnt,
-		parm->bindcnt);
+	print_uint(PRINT_ANY, "index", "\n\t index %u", parm->index);
+	print_int(PRINT_ANY, "ref", " ref %d", parm->refcnt);
+	print_int(PRINT_ANY, "bind", " bind %d", parm->bindcnt);
 
 	if (show_stats) {
 		if (tb[TCA_VLAN_TM]) {
@@ -237,7 +235,7 @@ static int print_vlan(struct action_util *au, FILE *f, struct rtattr *arg)
 		}
 	}
 
-	fprintf(f, "\n ");
+	print_string(PRINT_FP, NULL, "%s", "\n");
 
 	return 0;
 }
-- 
2.9.5

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [patch iproute2 00/11] tc: jsonify couple of qdics, filter and actions
  2017-11-25 14:48 [patch iproute2 00/11] tc: jsonify couple of qdics, filter and actions Jiri Pirko
                   ` (10 preceding siblings ...)
  2017-11-25 14:48 ` [patch iproute2 11/11] tc: jsonify vlan action Jiri Pirko
@ 2017-11-26 20:44 ` Stephen Hemminger
  2017-11-26 21:26   ` Jiri Pirko
  11 siblings, 1 reply; 14+ messages in thread
From: Stephen Hemminger @ 2017-11-26 20:44 UTC (permalink / raw)
  To: Jiri Pirko; +Cc: netdev, jhs, mlxsw

On Sat, 25 Nov 2017 15:48:24 +0100
Jiri Pirko <jiri@resnulli.us> wrote:

> From: Jiri Pirko <jiri@mellanox.com>
> 
> An example json output:
> 
> $ tc -s -j filter show dev ens8 egress
> [{
>         "protocol": "ip",
>         "pref": 6001,
>         "kind": "flower",
>         "chain": 0
>     },{
>         "protocol": "ip",
>         "pref": 6001,
>         "kind": "flower",
>         "chain": 0,
>         "options": {
>             "handle": 1,
>             "keys": {
>                 "eth_type": "ipv4",
>                 "dst_ip": "192.168.250.1"
>             },
>             "not_in_hw": true,
>             "actions": [{
>                     "order": 1,
>                     "kind": "gact",
>                     "control_action": {
>                         "type": "drop"
>                     },
>                     "prob": {
>                         "random_type": "none",
>                         "control_action": {
>                             "type": "pass"
>                         },
>                         "val": 0
>                     },
>                     "index": 1,
>                     "ref": 1,
>                     "bind": 1,
>                     "installed": 1667830,
>                     "last_used": 1667830,
>                     "stats": {
>                         "bytes": 0,
>                         "packets": 0,
>                         "drops": 0,
>                         "overlimits": 0,
>                         "requeues": 0,
>                         "backlog": 0,
>                         "qlen": 0,
>                         "requeues": 0
>                     },
>                     "cookie": "a1b2c3d4aaaaaaaabb"
>                 }
>             }
>         }
>     }
> ]
> $ tc -s filter show dev ens8 egress
> filter pref 6001 flower chain 0 
> filter pref 6001 flower chain 0 handle 0x1 
>   eth_type ipv4
>   dst_ip 192.168.250.1
>   not_in_hw
>         action order 1: gact action drop
>          random type none pass val 0
>          index 1 ref 1 bind 1 installed 16689 sec used 16689 sec
>         Action statistics:
>         Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0) 
>         backlog 0b 0p requeues 0
>         cookie a1b2c3d4aaaaaaaabb
> 
> ---
> To be applied on top of my cookie fix patchset
> 
> Jiri Pirko (11):
>   tc: jsonify qdisc core
>   tc: jsonify stats2
>   tc: jsonify fq_codel qdisc
>   tc: jsonify htb qdisc
>   tc: jsonify filter core
>   tc: jsonify flower filter
>   tc: jsonify matchall filter
>   tc: jsonify actions core
>   tc: jsonify gact action
>   tc: jsonify mirred action
>   tc: jsonify vlan action
> 
>  tc/f_flower.c   | 287 +++++++++++++++++++++++++++++++++-----------------------
>  tc/f_matchall.c |  12 +--
>  tc/m_action.c   |  22 +++--
>  tc/m_gact.c     |  18 ++--
>  tc/m_mirred.c   |  46 +++++++--
>  tc/m_vlan.c     |  26 +++--
>  tc/q_fq_codel.c |  25 +++--
>  tc/q_htb.c      |  20 ++--
>  tc/tc.c         |   5 +-
>  tc/tc_filter.c  |  47 ++++++----
>  tc/tc_qdisc.c   |  52 ++++++----
>  tc/tc_util.c    |  66 +++++++++----
>  tc/tc_util.h    |   1 +
>  13 files changed, 396 insertions(+), 231 deletions(-)
> 


Applied, but other qdisc need some jsonification as well.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [patch iproute2 00/11] tc: jsonify couple of qdics, filter and actions
  2017-11-26 20:44 ` [patch iproute2 00/11] tc: jsonify couple of qdics, filter and actions Stephen Hemminger
@ 2017-11-26 21:26   ` Jiri Pirko
  0 siblings, 0 replies; 14+ messages in thread
From: Jiri Pirko @ 2017-11-26 21:26 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: netdev, jhs, mlxsw

Sun, Nov 26, 2017 at 09:44:17PM CET, stephen@networkplumber.org wrote:
>On Sat, 25 Nov 2017 15:48:24 +0100
>Jiri Pirko <jiri@resnulli.us> wrote:
>
>> From: Jiri Pirko <jiri@mellanox.com>
>> 
>> An example json output:
>> 
>> $ tc -s -j filter show dev ens8 egress
>> [{
>>         "protocol": "ip",
>>         "pref": 6001,
>>         "kind": "flower",
>>         "chain": 0
>>     },{
>>         "protocol": "ip",
>>         "pref": 6001,
>>         "kind": "flower",
>>         "chain": 0,
>>         "options": {
>>             "handle": 1,
>>             "keys": {
>>                 "eth_type": "ipv4",
>>                 "dst_ip": "192.168.250.1"
>>             },
>>             "not_in_hw": true,
>>             "actions": [{
>>                     "order": 1,
>>                     "kind": "gact",
>>                     "control_action": {
>>                         "type": "drop"
>>                     },
>>                     "prob": {
>>                         "random_type": "none",
>>                         "control_action": {
>>                             "type": "pass"
>>                         },
>>                         "val": 0
>>                     },
>>                     "index": 1,
>>                     "ref": 1,
>>                     "bind": 1,
>>                     "installed": 1667830,
>>                     "last_used": 1667830,
>>                     "stats": {
>>                         "bytes": 0,
>>                         "packets": 0,
>>                         "drops": 0,
>>                         "overlimits": 0,
>>                         "requeues": 0,
>>                         "backlog": 0,
>>                         "qlen": 0,
>>                         "requeues": 0
>>                     },
>>                     "cookie": "a1b2c3d4aaaaaaaabb"
>>                 }
>>             }
>>         }
>>     }
>> ]
>> $ tc -s filter show dev ens8 egress
>> filter pref 6001 flower chain 0 
>> filter pref 6001 flower chain 0 handle 0x1 
>>   eth_type ipv4
>>   dst_ip 192.168.250.1
>>   not_in_hw
>>         action order 1: gact action drop
>>          random type none pass val 0
>>          index 1 ref 1 bind 1 installed 16689 sec used 16689 sec
>>         Action statistics:
>>         Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0) 
>>         backlog 0b 0p requeues 0
>>         cookie a1b2c3d4aaaaaaaabb
>> 
>> ---
>> To be applied on top of my cookie fix patchset
>> 
>> Jiri Pirko (11):
>>   tc: jsonify qdisc core
>>   tc: jsonify stats2
>>   tc: jsonify fq_codel qdisc
>>   tc: jsonify htb qdisc
>>   tc: jsonify filter core
>>   tc: jsonify flower filter
>>   tc: jsonify matchall filter
>>   tc: jsonify actions core
>>   tc: jsonify gact action
>>   tc: jsonify mirred action
>>   tc: jsonify vlan action
>> 
>>  tc/f_flower.c   | 287 +++++++++++++++++++++++++++++++++-----------------------
>>  tc/f_matchall.c |  12 +--
>>  tc/m_action.c   |  22 +++--
>>  tc/m_gact.c     |  18 ++--
>>  tc/m_mirred.c   |  46 +++++++--
>>  tc/m_vlan.c     |  26 +++--
>>  tc/q_fq_codel.c |  25 +++--
>>  tc/q_htb.c      |  20 ++--
>>  tc/tc.c         |   5 +-
>>  tc/tc_filter.c  |  47 ++++++----
>>  tc/tc_qdisc.c   |  52 ++++++----
>>  tc/tc_util.c    |  66 +++++++++----
>>  tc/tc_util.h    |   1 +
>>  13 files changed, 396 insertions(+), 231 deletions(-)
>> 
>
>
>Applied, but other qdisc need some jsonification as well.

and classes/actions. I agree.

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2017-11-26 21:26 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-11-25 14:48 [patch iproute2 00/11] tc: jsonify couple of qdics, filter and actions Jiri Pirko
2017-11-25 14:48 ` [patch iproute2 01/11] tc: jsonify qdisc core Jiri Pirko
2017-11-25 14:48 ` [patch iproute2 02/11] tc: jsonify stats2 Jiri Pirko
2017-11-25 14:48 ` [patch iproute2 03/11] tc: jsonify fq_codel qdisc Jiri Pirko
2017-11-25 14:48 ` [patch iproute2 04/11] tc: jsonify htb qdisc Jiri Pirko
2017-11-25 14:48 ` [patch iproute2 05/11] tc: jsonify filter core Jiri Pirko
2017-11-25 14:48 ` [patch iproute2 06/11] tc: jsonify flower filter Jiri Pirko
2017-11-25 14:48 ` [patch iproute2 07/11] tc: jsonify matchall filter Jiri Pirko
2017-11-25 14:48 ` [patch iproute2 08/11] tc: jsonify actions core Jiri Pirko
2017-11-25 14:48 ` [patch iproute2 09/11] tc: jsonify gact action Jiri Pirko
2017-11-25 14:48 ` [patch iproute2 10/11] tc: jsonify mirred action Jiri Pirko
2017-11-25 14:48 ` [patch iproute2 11/11] tc: jsonify vlan action Jiri Pirko
2017-11-26 20:44 ` [patch iproute2 00/11] tc: jsonify couple of qdics, filter and actions Stephen Hemminger
2017-11-26 21:26   ` Jiri Pirko

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.