netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH iproute2 net-next v4 0/5] bridge: json support for fdb and vlan show
@ 2016-06-22 13:45 Roopa Prabhu
  2016-06-22 13:45 ` [PATCH iproute2 net-next v4 1/5] json_writer: Removed automatic json-object type from the constructor Roopa Prabhu
                   ` (5 more replies)
  0 siblings, 6 replies; 13+ messages in thread
From: Roopa Prabhu @ 2016-06-22 13:45 UTC (permalink / raw)
  To: stephen, netdev; +Cc: anuradhak, nikolay, julien

From: Roopa Prabhu <roopa@cumulusnetworks.com>

This patch series adds json support for a few bridge show commands.
We plan to follow up with json support for additional commands soon.

Anuradha Karuppiah (3):
  json_writer: Removed automatic json-object type from the constructor
  bridge: add json support for bridge fdb show
  bridge: add json schema for bridge fdb show

Roopa Prabhu (2):
  bridge: add json support for bridge vlan show
  bridge: update man page

v2 - change vlan flags to an array as suggested by toshiaki

v3 - no change. resubmitting as requested by stephen

v4 - removed json type from constructor as recommended by stephen

 bridge/br_common.h            |   1 +
 bridge/bridge.c               |   5 +-
 bridge/fdb.c                  | 210 +++++++++++++++++++++++++++++++++---------
 bridge/vlan.c                 | 109 +++++++++++++++++++---
 lib/json_writer.c             |   6 +-
 man/man8/bridge.8             |   9 +-
 misc/ifstat.c                 |   7 ++
 misc/nstat.c                  |   6 ++
 schema/bridge_fdb_schema.json |  62 +++++++++++++
 9 files changed, 352 insertions(+), 63 deletions(-)
 create mode 100644 schema/bridge_fdb_schema.json

-- 
1.9.1

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

* [PATCH iproute2 net-next v4 1/5] json_writer: Removed automatic json-object type from the constructor
  2016-06-22 13:45 [PATCH iproute2 net-next v4 0/5] bridge: json support for fdb and vlan show Roopa Prabhu
@ 2016-06-22 13:45 ` Roopa Prabhu
  2016-06-22 13:45 ` [PATCH iproute2 net-next v4 2/5] bridge: add json support for bridge vlan show Roopa Prabhu
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 13+ messages in thread
From: Roopa Prabhu @ 2016-06-22 13:45 UTC (permalink / raw)
  To: stephen, netdev; +Cc: anuradhak, nikolay, julien

From: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>

Top level can be any json type and can be created using
jsonw_start_object/jsonw_end_object etc.

Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
---
 lib/json_writer.c | 8 ++++----
 misc/ifstat.c     | 7 +++++++
 misc/nstat.c      | 6 ++++++
 3 files changed, 17 insertions(+), 4 deletions(-)

diff --git a/lib/json_writer.c b/lib/json_writer.c
index 2af16e1..9fc05e9 100644
--- a/lib/json_writer.c
+++ b/lib/json_writer.c
@@ -33,7 +33,7 @@ struct json_writer {
 static void jsonw_indent(json_writer_t *self)
 {
 	unsigned i;
-	for (i = 0; i <= self->depth; ++i)
+	for (i = 0; i < self->depth; ++i)
 		fputs("    ", self->out);
 }
 
@@ -102,7 +102,6 @@ json_writer_t *jsonw_new(FILE *f)
 		self->depth = 0;
 		self->pretty = false;
 		self->sep = '\0';
-		putc('{', self->out);
 	}
 	return self;
 }
@@ -113,8 +112,7 @@ void jsonw_destroy(json_writer_t **self_p)
 	json_writer_t *self = *self_p;
 
 	assert(self->depth == 0);
-	jsonw_eol(self);
-	fputs("}\n", self->out);
+	fputs("\n", self->out);
 	fflush(self->out);
 	free(self);
 	*self_p = NULL;
@@ -269,6 +267,7 @@ int main(int argc, char **argv)
 {
 	json_writer_t *wr = jsonw_new(stdout);
 
+	jsonw_start_object(wr);
 	jsonw_pretty(wr, true);
 	jsonw_name(wr, "Vyatta");
 	jsonw_start_object(wr);
@@ -305,6 +304,7 @@ int main(int argc, char **argv)
 
 	jsonw_end_object(wr);
 
+	jsonw_end_object(wr);
 	jsonw_destroy(&wr);
 	return 0;
 }
diff --git a/misc/ifstat.c b/misc/ifstat.c
index abbb4e7..d551973 100644
--- a/misc/ifstat.c
+++ b/misc/ifstat.c
@@ -245,6 +245,7 @@ static void dump_raw_db(FILE *fp, int to_hist)
 
 	h = hist_db;
 	if (jw) {
+		jsonw_start_object(jw);
 		jsonw_pretty(jw, pretty);
 		jsonw_name(jw, info_source);
 		jsonw_start_object(jw);
@@ -288,6 +289,8 @@ static void dump_raw_db(FILE *fp, int to_hist)
 	}
 	if (jw) {
 		jsonw_end_object(jw);
+
+		jsonw_end_object(jw);
 		jsonw_destroy(&jw);
 	}
 }
@@ -451,6 +454,7 @@ static void dump_kern_db(FILE *fp)
 	struct ifstat_ent *n;
 
 	if (jw) {
+		jsonw_start_object(jw);
 		jsonw_pretty(jw, pretty);
 		jsonw_name(jw, info_source);
 		jsonw_start_object(jw);
@@ -477,6 +481,7 @@ static void dump_incr_db(FILE *fp)
 
 	h = hist_db;
 	if (jw) {
+		jsonw_start_object(jw);
 		jsonw_pretty(jw, pretty);
 		jsonw_name(jw, info_source);
 		jsonw_start_object(jw);
@@ -509,6 +514,8 @@ static void dump_incr_db(FILE *fp)
 
 	if (jw) {
 		jsonw_end_object(jw);
+
+		jsonw_end_object(jw);
 		jsonw_destroy(&jw);
 	}
 }
diff --git a/misc/nstat.c b/misc/nstat.c
index a9e0f20..8bd3a1a 100644
--- a/misc/nstat.c
+++ b/misc/nstat.c
@@ -284,6 +284,7 @@ static void dump_kern_db(FILE *fp, int to_hist)
 
 	h = hist_db;
 	if (jw) {
+		jsonw_start_object(jw);
 		jsonw_pretty(jw, pretty);
 		jsonw_name(jw, info_source);
 		jsonw_start_object(jw);
@@ -317,6 +318,8 @@ static void dump_kern_db(FILE *fp, int to_hist)
 
 	if (jw) {
 		jsonw_end_object(jw);
+
+		jsonw_end_object(jw);
 		jsonw_destroy(&jw);
 	}
 }
@@ -328,6 +331,7 @@ static void dump_incr_db(FILE *fp)
 
 	h = hist_db;
 	if (jw) {
+		jsonw_start_object(jw);
 		jsonw_pretty(jw, pretty);
 		jsonw_name(jw, info_source);
 		jsonw_start_object(jw);
@@ -364,6 +368,8 @@ static void dump_incr_db(FILE *fp)
 
 	if (jw) {
 		jsonw_end_object(jw);
+
+		jsonw_end_object(jw);
 		jsonw_destroy(&jw);
 	}
 }
-- 
1.9.1

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

* [PATCH iproute2 net-next v4 2/5] bridge: add json support for bridge vlan show
  2016-06-22 13:45 [PATCH iproute2 net-next v4 0/5] bridge: json support for fdb and vlan show Roopa Prabhu
  2016-06-22 13:45 ` [PATCH iproute2 net-next v4 1/5] json_writer: Removed automatic json-object type from the constructor Roopa Prabhu
@ 2016-06-22 13:45 ` Roopa Prabhu
  2016-06-22 13:45 ` [PATCH iproute2 net-next v4 3/5] bridge: add json support for bridge fdb show Roopa Prabhu
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 13+ messages in thread
From: Roopa Prabhu @ 2016-06-22 13:45 UTC (permalink / raw)
  To: stephen, netdev; +Cc: anuradhak, nikolay, julien

From: Roopa Prabhu <roopa@cumulusnetworks.com>

$bridge -c vlan show
port	vlan ids
swp1	 1 PVID Egress Untagged
	 10-13

swp2	 1 PVID Egress Untagged
	 10-13

br0	 1 PVID Egress Untagged

$bridge  -json vlan show
{
    "swp1": [{
            "vlan": 1,
            "flags": ["PVID","Egress Untagged"
            ]
        },{
            "vlan": 10
        },{
            "vlan": 11
        },{
            "vlan": 12
        },{
            "vlan": 13
        }
    ],
    "swp2": [{
            "vlan": 1,
            "flags": ["PVID","Egress Untagged"
            ]
        },{
            "vlan": 10
        },{
            "vlan": 11
        },{
            "vlan": 12
        },{
            "vlan": 13
        }
    ],
    "br0": [{
            "vlan": 1,
            "flags": ["PVID","Egress Untagged"
            ]
        }
    ]
}

$bridge -c -json vlan show
{
    "swp1": [{
            "vlan": 1,
            "flags": ["PVID","Egress Untagged"
            ]
        },{
            "vlan": 10,
            "vlanEnd": 13
        }
    ],
    "swp2": [{
            "vlan": 1,
            "flags": ["PVID","Egress Untagged"
            ]
        },{
            "vlan": 10,
            "vlanEnd": 13
        }
    ],
    "br0": [{
            "vlan": 1,
            "flags": ["PVID","Egress Untagged"
            ]
        }
    ]
}

Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
---
 bridge/br_common.h |   1 +
 bridge/bridge.c    |   5 ++-
 bridge/vlan.c      | 109 ++++++++++++++++++++++++++++++++++++++++++++++-------
 3 files changed, 100 insertions(+), 15 deletions(-)

diff --git a/bridge/br_common.h b/bridge/br_common.h
index 5ea45c9..c649e7d 100644
--- a/bridge/br_common.h
+++ b/bridge/br_common.h
@@ -23,4 +23,5 @@ extern int show_stats;
 extern int show_details;
 extern int timestamp;
 extern int compress_vlans;
+extern int json_output;
 extern struct rtnl_handle rth;
diff --git a/bridge/bridge.c b/bridge/bridge.c
index 72f153f..5ff038d 100644
--- a/bridge/bridge.c
+++ b/bridge/bridge.c
@@ -23,6 +23,7 @@ int oneline;
 int show_stats;
 int show_details;
 int compress_vlans;
+int json_output;
 int timestamp;
 char *batch_file;
 int force;
@@ -38,7 +39,7 @@ static void usage(void)
 "where	OBJECT := { link | fdb | mdb | vlan | monitor }\n"
 "	OPTIONS := { -V[ersion] | -s[tatistics] | -d[etails] |\n"
 "		     -o[neline] | -t[imestamp] | -n[etns] name |\n"
-"		     -c[ompressvlans] }\n");
+"		     -c[ompressvlans] -j{son} }\n");
 	exit(-1);
 }
 
@@ -173,6 +174,8 @@ main(int argc, char **argv)
 			++compress_vlans;
 		} else if (matches(opt, "-force") == 0) {
 			++force;
+		} else if (matches(opt, "-json") == 0) {
+			++json_output;
 		} else if (matches(opt, "-batch") == 0) {
 			argc--;
 			argv++;
diff --git a/bridge/vlan.c b/bridge/vlan.c
index 717025a..ba4dfbc 100644
--- a/bridge/vlan.c
+++ b/bridge/vlan.c
@@ -7,6 +7,7 @@
 #include <netinet/in.h>
 #include <linux/if_bridge.h>
 #include <linux/if_ether.h>
+#include <json_writer.h>
 #include <string.h>
 
 #include "libnetlink.h"
@@ -15,6 +16,8 @@
 
 static unsigned int filter_index, filter_vlan;
 
+json_writer_t *jw_global = NULL;
+
 static void usage(void)
 {
 	fprintf(stderr, "Usage: bridge vlan { add | del } vid VLAN_ID dev DEV [ pvid] [ untagged ]\n");
@@ -158,6 +161,28 @@ static int filter_vlan_check(struct bridge_vlan_info *vinfo)
 	return 1;
 }
 
+static void print_vlan_port(FILE *fp, int ifi_index)
+{
+	if (jw_global) {
+		jsonw_pretty(jw_global, 1);
+		jsonw_name(jw_global,
+			   ll_index_to_name(ifi_index));
+		jsonw_start_array(jw_global);
+	} else {
+		fprintf(fp, "%s",
+			ll_index_to_name(ifi_index));
+	}
+}
+
+static void start_json_vlan_flags_array(bool *vlan_flags)
+{
+	if (*vlan_flags)
+		return;
+	jsonw_name(jw_global, "flags");
+	jsonw_start_array(jw_global);
+	*vlan_flags = true;
+}
+
 static int print_vlan(const struct sockaddr_nl *who,
 		      struct nlmsghdr *n,
 		      void *arg)
@@ -166,6 +191,8 @@ static int print_vlan(const struct sockaddr_nl *who,
 	struct ifinfomsg *ifm = NLMSG_DATA(n);
 	int len = n->nlmsg_len;
 	struct rtattr *tb[IFLA_MAX+1];
+	bool vlan_flags;
+	char flags[80];
 
 	if (n->nlmsg_type != RTM_NEWLINK) {
 		fprintf(stderr, "Not RTM_NEWLINK: %08x %08x %08x\n",
@@ -199,7 +226,8 @@ static int print_vlan(const struct sockaddr_nl *who,
 		__u16 last_vid_start = 0;
 
 		if (!filter_vlan)
-			fprintf(fp, "%s", ll_index_to_name(ifm->ifi_index));
+			print_vlan_port(fp, ifm->ifi_index);
+
 		for (i = RTA_DATA(list); RTA_OK(i, rem); i = RTA_NEXT(i, rem)) {
 			struct bridge_vlan_info *vinfo;
 			int vcheck_ret;
@@ -218,20 +246,58 @@ static int print_vlan(const struct sockaddr_nl *who,
 				continue;
 
 			if (filter_vlan)
-				fprintf(fp, "%s",
-					ll_index_to_name(ifm->ifi_index));
-			fprintf(fp, "\t %hu", last_vid_start);
-			if (last_vid_start != vinfo->vid)
-				fprintf(fp, "-%hu", vinfo->vid);
-			if (vinfo->flags & BRIDGE_VLAN_INFO_PVID)
-				fprintf(fp, " PVID");
-			if (vinfo->flags & BRIDGE_VLAN_INFO_UNTAGGED)
-				fprintf(fp, " Egress Untagged");
-			fprintf(fp, "\n");
+				print_vlan_port(fp, ifm->ifi_index);
+			if (jw_global) {
+				jsonw_start_object(jw_global);
+				jsonw_uint_field(jw_global, "vlan",
+						 last_vid_start);
+				if (vinfo->flags & BRIDGE_VLAN_INFO_RANGE_BEGIN)
+					continue;
+			} else {
+				fprintf(fp, "\t %hu", last_vid_start);
+			}
+			if (last_vid_start != vinfo->vid) {
+				if (jw_global)
+					jsonw_uint_field(jw_global, "vlanEnd",
+							 vinfo->vid);
+				else
+					fprintf(fp, "-%hu", vinfo->vid);
+			}
+			if (vinfo->flags & BRIDGE_VLAN_INFO_PVID) {
+				if (jw_global) {
+					start_json_vlan_flags_array(&vlan_flags);
+					jsonw_string(jw_global, "PVID");
+				} else {
+					fprintf(fp, " PVID");
+				}
+			}
+			if (vinfo->flags & BRIDGE_VLAN_INFO_UNTAGGED) {
+				if (jw_global) {
+					start_json_vlan_flags_array(&vlan_flags);
+					jsonw_string(jw_global,
+						     "Egress Untagged");
+				} else {
+					fprintf(fp, " Egress Untagged");
+				}
+			}
+			if (vlan_flags) {
+				jsonw_end_array(jw_global);
+				vlan_flags = false;
+			}
+
+			if (jw_global)
+				jsonw_end_object(jw_global);
+			else
+				fprintf(fp, "\n");
 		}
 	}
-	if (!filter_vlan)
-		fprintf(fp, "\n");
+	if (!filter_vlan) {
+		if (jw_global)
+			jsonw_end_array(jw_global);
+		else
+			fprintf(fp, "\n");
+
+	}
 	fflush(fp);
 	return 0;
 }
@@ -271,12 +337,27 @@ static int vlan_show(int argc, char **argv)
 		exit(1);
 	}
 
-	printf("port\tvlan ids\n");
+	if (json_output) {
+		jw_global = jsonw_new(stdout);
+		if (!jw_global) {
+			fprintf(stderr, "Error allocation json object\n");
+			exit(1);
+		}
+		jsonw_start_object(jw_global);
+	} else {
+		printf("port\tvlan ids\n");
+	}
+
 	if (rtnl_dump_filter(&rth, print_vlan, stdout) < 0) {
 		fprintf(stderr, "Dump ternminated\n");
 		exit(1);
 	}
 
+	if (jw_global) {
+		jsonw_end_object(jw_global);
+		jsonw_destroy(&jw_global);
+	}
+
 	return 0;
 }
 
-- 
1.9.1

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

* [PATCH iproute2 net-next v4 3/5] bridge: add json support for bridge fdb show
  2016-06-22 13:45 [PATCH iproute2 net-next v4 0/5] bridge: json support for fdb and vlan show Roopa Prabhu
  2016-06-22 13:45 ` [PATCH iproute2 net-next v4 1/5] json_writer: Removed automatic json-object type from the constructor Roopa Prabhu
  2016-06-22 13:45 ` [PATCH iproute2 net-next v4 2/5] bridge: add json support for bridge vlan show Roopa Prabhu
@ 2016-06-22 13:45 ` Roopa Prabhu
  2016-06-22 13:45 ` [PATCH iproute2 net-next v4 4/5] bridge: add json schema " Roopa Prabhu
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 13+ messages in thread
From: Roopa Prabhu @ 2016-06-22 13:45 UTC (permalink / raw)
  To: stephen, netdev; +Cc: anuradhak, nikolay, julien

From: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>

Sample output:
$bridge -j fdb show
[{
        "mac": "44:38:39:00:69:88",
        "dev": "swp2s0",
        "vlan": 2,
        "master": "br0",
        "state": "permanent"
    },{
        "mac": "00:02:00:00:00:01",
        "dev": "swp2s0",
        "vlan": 2,
        "master": "br0"
    },{
        "mac": "00:02:00:00:00:02",
        "dev": "swp2s1",
        "vlan": 2,
        "master": "br0"
    },{
        "mac": "44:38:39:00:69:89",
        "dev": "swp2s1",
        "master": "br0",
        "state": "permanent"
    },{
        "mac": "44:38:39:00:69:89",
        "dev": "swp2s1",
        "vlan": 2,
        "master": "br0",
        "state": "permanent"
    },{
        "mac": "44:38:39:00:69:88",
        "dev": "br0",
        "master": "br0",
        "state": "permanent"
    }
]

Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
---
 bridge/fdb.c | 210 +++++++++++++++++++++++++++++++++++++++++++++++------------
 1 file changed, 167 insertions(+), 43 deletions(-)

diff --git a/bridge/fdb.c b/bridge/fdb.c
index be849f9..3d1ef6c 100644
--- a/bridge/fdb.c
+++ b/bridge/fdb.c
@@ -21,6 +21,8 @@
 #include <linux/neighbour.h>
 #include <string.h>
 #include <limits.h>
+#include <json_writer.h>
+#include <stdbool.h>
 
 #include "libnetlink.h"
 #include "br_common.h"
@@ -29,6 +31,8 @@
 
 static unsigned int filter_index, filter_vlan;
 
+json_writer_t *jw_global;
+
 static void usage(void)
 {
 	fprintf(stderr, "Usage: bridge fdb { add | append | del | replace } ADDR dev DEV\n"
@@ -59,6 +63,15 @@ static const char *state_n2a(unsigned int s)
 	return buf;
 }
 
+static void start_json_fdb_flags_array(bool *fdb_flags)
+{
+	if (*fdb_flags)
+		return;
+	jsonw_name(jw_global, "flags");
+	jsonw_start_array(jw_global);
+	*fdb_flags = true;
+}
+
 int print_fdb(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
 {
 	FILE *fp = arg;
@@ -66,11 +79,12 @@ int print_fdb(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
 	int len = n->nlmsg_len;
 	struct rtattr *tb[NDA_MAX+1];
 	__u16 vid = 0;
+	bool fdb_flags = false;
+	const char *state_s;
 
 	if (n->nlmsg_type != RTM_NEWNEIGH && n->nlmsg_type != RTM_DELNEIGH) {
 		fprintf(stderr, "Not RTM_NEWNEIGH: %08x %08x %08x\n",
 			n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags);
-
 		return 0;
 	}
 
@@ -86,6 +100,11 @@ int print_fdb(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
 	if (filter_index && filter_index != r->ndm_ifindex)
 		return 0;
 
+	if (jw_global) {
+		jsonw_pretty(jw_global, 1);
+		jsonw_start_object(jw_global);
+	}
+
 	parse_rtattr(tb, NDA_MAX, NDA_RTA(r),
 		     n->nlmsg_len - NLMSG_LENGTH(sizeof(*r)));
 
@@ -95,40 +114,75 @@ int print_fdb(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
 	if (filter_vlan && filter_vlan != vid)
 		return 0;
 
-	if (n->nlmsg_type == RTM_DELNEIGH)
-		fprintf(fp, "Deleted ");
+	if (n->nlmsg_type == RTM_DELNEIGH) {
+		if (jw_global)
+			jsonw_string_field(jw_global, "opCode", "deleted");
+		else
+			fprintf(fp, "Deleted ");
+	}
 
 	if (tb[NDA_LLADDR]) {
 		SPRINT_BUF(b1);
-		fprintf(fp, "%s ",
-			ll_addr_n2a(RTA_DATA(tb[NDA_LLADDR]),
-				    RTA_PAYLOAD(tb[NDA_LLADDR]),
-				    ll_index_to_type(r->ndm_ifindex),
-				    b1, sizeof(b1)));
+		ll_addr_n2a(RTA_DATA(tb[NDA_LLADDR]),
+			    RTA_PAYLOAD(tb[NDA_LLADDR]),
+			    ll_index_to_type(r->ndm_ifindex),
+			    b1, sizeof(b1));
+		if (jw_global)
+			jsonw_string_field(jw_global, "mac", b1);
+		else
+			fprintf(fp, "%s ", b1);
 	}
 
-	if (!filter_index && r->ndm_ifindex)
-		fprintf(fp, "dev %s ", ll_index_to_name(r->ndm_ifindex));
+	if (!filter_index && r->ndm_ifindex) {
+		if (jw_global)
+			jsonw_string_field(jw_global, "dev",
+					   ll_index_to_name(r->ndm_ifindex));
+		else
+			fprintf(fp, "dev %s ",
+				ll_index_to_name(r->ndm_ifindex));
+	}
 
 	if (tb[NDA_DST]) {
 		int family = AF_INET;
+		const char *abuf_s;
 
 		if (RTA_PAYLOAD(tb[NDA_DST]) == sizeof(struct in6_addr))
 			family = AF_INET6;
 
-		fprintf(fp, "dst %s ",
-			format_host(family,
-				    RTA_PAYLOAD(tb[NDA_DST]),
-				    RTA_DATA(tb[NDA_DST])));
+		abuf_s = format_host(family,
+				     RTA_PAYLOAD(tb[NDA_DST]),
+				     RTA_DATA(tb[NDA_DST]));
+		if (jw_global)
+			jsonw_string_field(jw_global, "dst", abuf_s);
+		else
+			fprintf(fp, "dst %s ", abuf_s);
+	}
+
+	if (vid) {
+		if (jw_global)
+			jsonw_uint_field(jw_global, "vlan", vid);
+		else
+			fprintf(fp, "vlan %hu ", vid);
+	}
+
+	if (tb[NDA_PORT]) {
+		if (jw_global)
+			jsonw_uint_field(jw_global, "port",
+					 ntohs(rta_getattr_u16(tb[NDA_PORT])));
+		else
+			fprintf(fp, "port %d ",
+				ntohs(rta_getattr_u16(tb[NDA_PORT])));
 	}
 
-	if (vid)
-		fprintf(fp, "vlan %hu ", vid);
+	if (tb[NDA_VNI]) {
+		if (jw_global)
+			jsonw_uint_field(jw_global, "vni",
+					 rta_getattr_u32(tb[NDA_VNI]));
+		else
+			fprintf(fp, "vni %d ",
+				rta_getattr_u32(tb[NDA_VNI]));
+	}
 
-	if (tb[NDA_PORT])
-		fprintf(fp, "port %d ", ntohs(rta_getattr_u16(tb[NDA_PORT])));
-	if (tb[NDA_VNI])
-		fprintf(fp, "vni %d ", rta_getattr_u32(tb[NDA_VNI]));
 	if (tb[NDA_IFINDEX]) {
 		unsigned int ifindex = rta_getattr_u32(tb[NDA_IFINDEX]);
 
@@ -136,37 +190,95 @@ int print_fdb(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
 			char ifname[IF_NAMESIZE];
 
 			if (!tb[NDA_LINK_NETNSID] &&
-			    if_indextoname(ifindex, ifname))
-				fprintf(fp, "via %s ", ifname);
-			else
-				fprintf(fp, "via ifindex %u ", ifindex);
+			    if_indextoname(ifindex, ifname)) {
+				if (jw_global)
+					jsonw_string_field(jw_global, "viaIf",
+							   ifname);
+				else
+					fprintf(fp, "via %s ", ifname);
+			} else {
+				if (jw_global)
+					jsonw_uint_field(jw_global, "viaIfIndex",
+							 ifindex);
+				else
+					fprintf(fp, "via ifindex %u ", ifindex);
+			}
 		}
 	}
-	if (tb[NDA_LINK_NETNSID])
-		fprintf(fp, "link-netnsid %d ",
-			rta_getattr_u32(tb[NDA_LINK_NETNSID]));
+
+	if (tb[NDA_LINK_NETNSID]) {
+		if (jw_global)
+			jsonw_uint_field(jw_global, "linkNetNsId",
+					 rta_getattr_u32(tb[NDA_LINK_NETNSID]));
+		else
+			fprintf(fp, "link-netnsid %d ",
+				rta_getattr_u32(tb[NDA_LINK_NETNSID]));
+	}
 
 	if (show_stats && tb[NDA_CACHEINFO]) {
 		struct nda_cacheinfo *ci = RTA_DATA(tb[NDA_CACHEINFO]);
 		int hz = get_user_hz();
 
-		fprintf(fp, "used %d/%d ", ci->ndm_used/hz,
-		       ci->ndm_updated/hz);
+		if (jw_global) {
+			jsonw_uint_field(jw_global, "used",
+				ci->ndm_used/hz);
+			jsonw_uint_field(jw_global, "updated",
+				ci->ndm_updated/hz);
+		} else {
+			fprintf(fp, "used %d/%d ", ci->ndm_used/hz,
+					ci->ndm_updated/hz);
+		}
+	}
+
+	if (jw_global) {
+		if (r->ndm_flags & NTF_SELF) {
+			start_json_fdb_flags_array(&fdb_flags);
+			jsonw_string(jw_global, "self");
+		}
+		if (r->ndm_flags & NTF_ROUTER) {
+			start_json_fdb_flags_array(&fdb_flags);
+			jsonw_string(jw_global, "router");
+		}
+		if (r->ndm_flags & NTF_EXT_LEARNED) {
+			start_json_fdb_flags_array(&fdb_flags);
+			jsonw_string(jw_global, "offload");
+		}
+		if (r->ndm_flags & NTF_MASTER)
+			jsonw_string(jw_global, "master");
+		if (fdb_flags)
+			jsonw_end_array(jw_global);
+
+		if (tb[NDA_MASTER])
+			jsonw_string_field(jw_global,
+					   "master",
+					   ll_index_to_name(rta_getattr_u32(tb[NDA_MASTER])));
+
+	} else {
+		if (r->ndm_flags & NTF_SELF)
+			fprintf(fp, "self ");
+		if (r->ndm_flags & NTF_ROUTER)
+			fprintf(fp, "router ");
+		if (r->ndm_flags & NTF_EXT_LEARNED)
+			fprintf(fp, "offload ");
+		if (tb[NDA_MASTER]) {
+			fprintf(fp, "master %s ",
+				ll_index_to_name(rta_getattr_u32(tb[NDA_MASTER])));
+		} else if (r->ndm_flags & NTF_MASTER) {
+			fprintf(fp, "master ");
+		}
+	}
+
+	state_s = state_n2a(r->ndm_state);
+	if (jw_global) {
+		if (state_s[0])
+			jsonw_string_field(jw_global, "state", state_s);
+
+		jsonw_end_object(jw_global);
+	} else {
+		fprintf(fp, "%s\n", state_s);
+
+		fflush(fp);
 	}
-	if (r->ndm_flags & NTF_SELF)
-		fprintf(fp, "self ");
-	if (tb[NDA_MASTER])
-		fprintf(fp, "master %s ",
-			ll_index_to_name(rta_getattr_u32(tb[NDA_MASTER])));
-	else if (r->ndm_flags & NTF_MASTER)
-		fprintf(fp, "master ");
-	if (r->ndm_flags & NTF_ROUTER)
-		fprintf(fp, "router ");
-	if (r->ndm_flags & NTF_EXT_LEARNED)
-		fprintf(fp, "offload ");
-
-	fprintf(fp, "%s\n", state_n2a(r->ndm_state));
-	fflush(fp);
 
 	return 0;
 }
@@ -233,10 +345,22 @@ static int fdb_show(int argc, char **argv)
 		exit(1);
 	}
 
+	if (json_output) {
+		jw_global = jsonw_new(stdout);
+		if (!jw_global) {
+			fprintf(stderr, "Error allocation json object\n");
+			exit(1);
+		}
+		jsonw_start_array(jw_global);
+	}
 	if (rtnl_dump_filter(&rth, print_fdb, stdout) < 0) {
 		fprintf(stderr, "Dump terminated\n");
 		exit(1);
 	}
+	if (jw_global) {
+		jsonw_end_array(jw_global);
+		jsonw_destroy(&jw_global);
+	}
 
 	return 0;
 }
-- 
1.9.1

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

* [PATCH iproute2 net-next v4 4/5] bridge: add json schema for bridge fdb show
  2016-06-22 13:45 [PATCH iproute2 net-next v4 0/5] bridge: json support for fdb and vlan show Roopa Prabhu
                   ` (2 preceding siblings ...)
  2016-06-22 13:45 ` [PATCH iproute2 net-next v4 3/5] bridge: add json support for bridge fdb show Roopa Prabhu
@ 2016-06-22 13:45 ` Roopa Prabhu
  2016-06-22 13:45 ` [PATCH iproute2 net-next v4 5/5] bridge: update man page Roopa Prabhu
  2016-06-22 14:53 ` [PATCH iproute2 net-next v4 0/5] bridge: json support for fdb and vlan show Jiri Pirko
  5 siblings, 0 replies; 13+ messages in thread
From: Roopa Prabhu @ 2016-06-22 13:45 UTC (permalink / raw)
  To: stephen, netdev; +Cc: anuradhak, nikolay, julien

From: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>

Storing the schema file for the json format will be useful for doc
purposes as optional paramaters are typically suppressed in the json
sample outputs.

Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
---
 schema/bridge_fdb_schema.json | 62 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 62 insertions(+)
 create mode 100644 schema/bridge_fdb_schema.json

diff --git a/schema/bridge_fdb_schema.json b/schema/bridge_fdb_schema.json
new file mode 100644
index 0000000..3e5be8d
--- /dev/null
+++ b/schema/bridge_fdb_schema.json
@@ -0,0 +1,62 @@
+{
+    "$schema": "http://json-schema.org/draft-04/schema#",
+    "description": "bridge fdb show",
+    "type": "array",
+    "items": {
+        "type": "object",
+        "properties": {
+            "dev": {
+                "type": "string"
+            },
+            "dst": {
+                "description" : "host name or ip address",
+                "type": "string"
+            },
+            "flags": {
+                "type": "array",
+                "items": {
+                    "enum": ["self", "master", "router", "offload"]
+                },
+                "uniqueItems": true
+            },
+            "linkNetNsId": {
+                "type": "integer"
+            },
+            "mac": {
+                "type": "string"
+            },
+            "master": {
+                "type": "string"
+            },
+            "opCode": {
+                "description" : "used to indicate fdb entry del",
+                "enum": ["deleted"]
+            },
+            "port": {
+                "type": "integer"
+            },
+            "state": {
+                "description" : "permanent, static, stale, state=#x",
+                "type": "string"
+            },
+            "updated": {
+                "type": "integer"
+            },
+            "used": {
+                "type": "integer"
+            },
+            "viaIf": {
+                "type": "string"
+            },
+            "viaIfIndex": {
+                "type": "integer"
+            },
+            "vlan": {
+                "type": "integer"
+            },
+            "vni": {
+                "type": "integer"
+            }
+        }
+    }
+}
-- 
1.9.1

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

* [PATCH iproute2 net-next v4 5/5] bridge: update man page
  2016-06-22 13:45 [PATCH iproute2 net-next v4 0/5] bridge: json support for fdb and vlan show Roopa Prabhu
                   ` (3 preceding siblings ...)
  2016-06-22 13:45 ` [PATCH iproute2 net-next v4 4/5] bridge: add json schema " Roopa Prabhu
@ 2016-06-22 13:45 ` Roopa Prabhu
  2016-06-22 14:53 ` [PATCH iproute2 net-next v4 0/5] bridge: json support for fdb and vlan show Jiri Pirko
  5 siblings, 0 replies; 13+ messages in thread
From: Roopa Prabhu @ 2016-06-22 13:45 UTC (permalink / raw)
  To: stephen, netdev; +Cc: anuradhak, nikolay, julien

From: Roopa Prabhu <roopa@cumulusnetworks.com>

Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
---
 man/man8/bridge.8 | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/man/man8/bridge.8 b/man/man8/bridge.8
index 08e8a5b..abaee63 100644
--- a/man/man8/bridge.8
+++ b/man/man8/bridge.8
@@ -20,8 +20,9 @@ bridge \- show / manipulate bridge addresses and devices
 .IR OPTIONS " := { "
 \fB\-V\fR[\fIersion\fR] |
 \fB\-s\fR[\fItatistics\fR] |
-\fB\-n\fR[\fIetns\fR] name }
-\fB\-b\fR[\fIatch\fR] filename }
+\fB\-n\fR[\fIetns\fR] name |
+\fB\-b\fR[\fIatch\fR] filename |
+\fB\-j\fR[\fIson\fR] }
 
 .ti -8
 .BR "bridge link set"
@@ -153,6 +154,10 @@ Don't terminate bridge command on errors in batch mode.
 If there were any errors during execution of the commands, the application
 return code will be non zero.
 
+.TP
+.BR "\-json"
+Display results in JSON format. Currently available for vlan and fdb.
+
 .SH BRIDGE - COMMAND SYNTAX
 
 .SS
-- 
1.9.1

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

* Re: [PATCH iproute2 net-next v4 0/5] bridge: json support for fdb and vlan show
  2016-06-22 13:45 [PATCH iproute2 net-next v4 0/5] bridge: json support for fdb and vlan show Roopa Prabhu
                   ` (4 preceding siblings ...)
  2016-06-22 13:45 ` [PATCH iproute2 net-next v4 5/5] bridge: update man page Roopa Prabhu
@ 2016-06-22 14:53 ` Jiri Pirko
  2016-06-22 17:41   ` Roopa Prabhu
  2016-06-22 18:10   ` Stephen Hemminger
  5 siblings, 2 replies; 13+ messages in thread
From: Jiri Pirko @ 2016-06-22 14:53 UTC (permalink / raw)
  To: Roopa Prabhu; +Cc: stephen, netdev, anuradhak, nikolay, julien

Wed, Jun 22, 2016 at 03:45:50PM CEST, roopa@cumulusnetworks.com wrote:
>From: Roopa Prabhu <roopa@cumulusnetworks.com>
>
>This patch series adds json support for a few bridge show commands.
>We plan to follow up with json support for additional commands soon.

I'm just curious, what is you use case for this? Apps can use rtnetlink
socket directly.


>
>Anuradha Karuppiah (3):
>  json_writer: Removed automatic json-object type from the constructor
>  bridge: add json support for bridge fdb show
>  bridge: add json schema for bridge fdb show
>
>Roopa Prabhu (2):
>  bridge: add json support for bridge vlan show
>  bridge: update man page
>
>v2 - change vlan flags to an array as suggested by toshiaki
>
>v3 - no change. resubmitting as requested by stephen
>
>v4 - removed json type from constructor as recommended by stephen
>
> bridge/br_common.h            |   1 +
> bridge/bridge.c               |   5 +-
> bridge/fdb.c                  | 210 +++++++++++++++++++++++++++++++++---------
> bridge/vlan.c                 | 109 +++++++++++++++++++---
> lib/json_writer.c             |   6 +-
> man/man8/bridge.8             |   9 +-
> misc/ifstat.c                 |   7 ++
> misc/nstat.c                  |   6 ++
> schema/bridge_fdb_schema.json |  62 +++++++++++++
> 9 files changed, 352 insertions(+), 63 deletions(-)
> create mode 100644 schema/bridge_fdb_schema.json
>
>-- 
>1.9.1
>

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

* Re: [PATCH iproute2 net-next v4 0/5] bridge: json support for fdb and vlan show
  2016-06-22 14:53 ` [PATCH iproute2 net-next v4 0/5] bridge: json support for fdb and vlan show Jiri Pirko
@ 2016-06-22 17:41   ` Roopa Prabhu
  2016-06-22 18:10   ` Stephen Hemminger
  1 sibling, 0 replies; 13+ messages in thread
From: Roopa Prabhu @ 2016-06-22 17:41 UTC (permalink / raw)
  To: Jiri Pirko
  Cc: stephen@networkplumber.org, netdev@vger.kernel.org,
	Anuradha Karuppiah, Nikolay Aleksandrov, Julien Fortin

On Wed, Jun 22, 2016 at 7:53 AM, Jiri Pirko <jiri@resnulli.us> wrote:
> Wed, Jun 22, 2016 at 03:45:50PM CEST, roopa@cumulusnetworks.com wrote:
>>From: Roopa Prabhu <roopa@cumulusnetworks.com>
>>
>>This patch series adds json support for a few bridge show commands.
>>We plan to follow up with json support for additional commands soon.
>
> I'm just curious, what is you use case for this? Apps can use rtnetlink
> socket directly.

most important use case is for automation/orchestration tools.
They use existing linux tools to query and configure. Iproute2 output
is not machine
readable today ...and json is industry standard.

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

* Re: [PATCH iproute2 net-next v4 0/5] bridge: json support for fdb and vlan show
  2016-06-22 14:53 ` [PATCH iproute2 net-next v4 0/5] bridge: json support for fdb and vlan show Jiri Pirko
  2016-06-22 17:41   ` Roopa Prabhu
@ 2016-06-22 18:10   ` Stephen Hemminger
  2016-06-22 18:23     ` Roopa Prabhu
  2016-06-22 20:00     ` Jiri Pirko
  1 sibling, 2 replies; 13+ messages in thread
From: Stephen Hemminger @ 2016-06-22 18:10 UTC (permalink / raw)
  To: Jiri Pirko; +Cc: Roopa Prabhu, netdev, anuradhak, nikolay, julien

On Wed, 22 Jun 2016 16:53:44 +0200
Jiri Pirko <jiri@resnulli.us> wrote:

> Wed, Jun 22, 2016 at 03:45:50PM CEST, roopa@cumulusnetworks.com wrote:
> >From: Roopa Prabhu <roopa@cumulusnetworks.com>
> >
> >This patch series adds json support for a few bridge show commands.
> >We plan to follow up with json support for additional commands soon.  
> 
> I'm just curious, what is you use case for this? Apps can use rtnetlink
> socket directly.

Try using netlink in perl or python, it is quite difficult.

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

* Re: [PATCH iproute2 net-next v4 0/5] bridge: json support for fdb and vlan show
  2016-06-22 18:10   ` Stephen Hemminger
@ 2016-06-22 18:23     ` Roopa Prabhu
  2016-06-22 20:00     ` Jiri Pirko
  1 sibling, 0 replies; 13+ messages in thread
From: Roopa Prabhu @ 2016-06-22 18:23 UTC (permalink / raw)
  To: Stephen Hemminger
  Cc: Jiri Pirko, netdev@vger.kernel.org, Anuradha Karuppiah,
	Nikolay Aleksandrov, Julien Fortin

On Wed, Jun 22, 2016 at 11:10 AM, Stephen Hemminger
<stephen@networkplumber.org> wrote:
> On Wed, 22 Jun 2016 16:53:44 +0200
> Jiri Pirko <jiri@resnulli.us> wrote:
>
>> Wed, Jun 22, 2016 at 03:45:50PM CEST, roopa@cumulusnetworks.com wrote:
>> >From: Roopa Prabhu <roopa@cumulusnetworks.com>
>> >
>> >This patch series adds json support for a few bridge show commands.
>> >We plan to follow up with json support for additional commands soon.
>>
>> I'm just curious, what is you use case for this? Apps can use rtnetlink
>> socket directly.
>
> Try using netlink in perl or python, it is quite difficult.

yep, ++

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

* Re: [PATCH iproute2 net-next v4 0/5] bridge: json support for fdb and vlan show
  2016-06-22 18:10   ` Stephen Hemminger
  2016-06-22 18:23     ` Roopa Prabhu
@ 2016-06-22 20:00     ` Jiri Pirko
  2016-06-23 11:03       ` Roopa Prabhu
  1 sibling, 1 reply; 13+ messages in thread
From: Jiri Pirko @ 2016-06-22 20:00 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: Roopa Prabhu, netdev, anuradhak, nikolay, julien

Wed, Jun 22, 2016 at 08:10:47PM CEST, stephen@networkplumber.org wrote:
>On Wed, 22 Jun 2016 16:53:44 +0200
>Jiri Pirko <jiri@resnulli.us> wrote:
>
>> Wed, Jun 22, 2016 at 03:45:50PM CEST, roopa@cumulusnetworks.com wrote:
>> >From: Roopa Prabhu <roopa@cumulusnetworks.com>
>> >
>> >This patch series adds json support for a few bridge show commands.
>> >We plan to follow up with json support for additional commands soon.  
>> 
>> I'm just curious, what is you use case for this? Apps can use rtnetlink
>> socket directly.
>
>Try using netlink in perl or python, it is quite difficult.

pyroute2? Quite easy...

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

* Re: [PATCH iproute2 net-next v4 0/5] bridge: json support for fdb and vlan show
  2016-06-22 20:00     ` Jiri Pirko
@ 2016-06-23 11:03       ` Roopa Prabhu
  2016-06-25  6:20         ` Rami Rosen
  0 siblings, 1 reply; 13+ messages in thread
From: Roopa Prabhu @ 2016-06-23 11:03 UTC (permalink / raw)
  To: Jiri Pirko
  Cc: Stephen Hemminger, netdev@vger.kernel.org, Anuradha Karuppiah,
	Nikolay Aleksandrov, Julien Fortin

On Wed, Jun 22, 2016 at 1:00 PM, Jiri Pirko <jiri@resnulli.us> wrote:
> Wed, Jun 22, 2016 at 08:10:47PM CEST, stephen@networkplumber.org wrote:
>>On Wed, 22 Jun 2016 16:53:44 +0200
>>Jiri Pirko <jiri@resnulli.us> wrote:
>>
>>> Wed, Jun 22, 2016 at 03:45:50PM CEST, roopa@cumulusnetworks.com wrote:
>>> >From: Roopa Prabhu <roopa@cumulusnetworks.com>
>>> >
>>> >This patch series adds json support for a few bridge show commands.
>>> >We plan to follow up with json support for additional commands soon.
>>>
>>> I'm just curious, what is you use case for this? Apps can use rtnetlink
>>> socket directly.
>>
>>Try using netlink in perl or python, it is quite difficult.
>
> pyroute2? Quite easy...

none of the implementations out there are complete nor can compete
with iproute2.
iproute2 is maintained by netdev community and always is up-todate
with the latest
networking api.

Nothing against pyroute2 but we wrote our own for other reasons and we
carry additional burden of maintaining it and keeping it up-todate for
every networking api..
that gets added to iproute2 (and the implementation of netlink
is often very easy in C).

Also, for external automation and orchestration tools (to whom this
patch-set is addressed),
there is no reason for them to write and maintain their own tools
using netlink when they
can use iproute2 directly to create a link or query its properties.

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

* Re: [PATCH iproute2 net-next v4 0/5] bridge: json support for fdb and vlan show
  2016-06-23 11:03       ` Roopa Prabhu
@ 2016-06-25  6:20         ` Rami Rosen
  0 siblings, 0 replies; 13+ messages in thread
From: Rami Rosen @ 2016-06-25  6:20 UTC (permalink / raw)
  To: Roopa Prabhu
  Cc: Jiri Pirko, Stephen Hemminger, netdev@vger.kernel.org,
	Anuradha Karuppiah, Nikolay Aleksandrov, Julien Fortin

Hi all,

>Also, for external automation and orchestration tools (to whom this
>patch-set is addressed),
>there is no reason for them to write and maintain their own tools
>using netlink when they
>can use iproute2 directly to create a link or query its properties.

+1 for this, seems very reasonable,

Just want to remind us all, in recent netdev 1.1 conference in Seville
(Feb 2016), Damascene Joachimpillai (DJ) from Verizon gave a talk
("Linux Networking and Data Center Operations Challenges"); IIRC, he
mentioned that he misses a REST API to the Linux Kernel networking
stack control plane. And it seems that Rest API and JSON (and maybe
other APIs, like python based APIs) are natural candidates for such an
interface nowadays.


Regards,
Rami Rosen
http://ramirose.wix.com/ramirosen

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

end of thread, other threads:[~2016-06-25  6:20 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-06-22 13:45 [PATCH iproute2 net-next v4 0/5] bridge: json support for fdb and vlan show Roopa Prabhu
2016-06-22 13:45 ` [PATCH iproute2 net-next v4 1/5] json_writer: Removed automatic json-object type from the constructor Roopa Prabhu
2016-06-22 13:45 ` [PATCH iproute2 net-next v4 2/5] bridge: add json support for bridge vlan show Roopa Prabhu
2016-06-22 13:45 ` [PATCH iproute2 net-next v4 3/5] bridge: add json support for bridge fdb show Roopa Prabhu
2016-06-22 13:45 ` [PATCH iproute2 net-next v4 4/5] bridge: add json schema " Roopa Prabhu
2016-06-22 13:45 ` [PATCH iproute2 net-next v4 5/5] bridge: update man page Roopa Prabhu
2016-06-22 14:53 ` [PATCH iproute2 net-next v4 0/5] bridge: json support for fdb and vlan show Jiri Pirko
2016-06-22 17:41   ` Roopa Prabhu
2016-06-22 18:10   ` Stephen Hemminger
2016-06-22 18:23     ` Roopa Prabhu
2016-06-22 20:00     ` Jiri Pirko
2016-06-23 11:03       ` Roopa Prabhu
2016-06-25  6:20         ` Rami Rosen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).