On Fri, Aug 2, 2019 at 5:49 PM Stephen Hemminger <step...@networkplumber.org> wrote: > > On Fri, 2 Aug 2019 13:14:15 +0200 > Andrea Claudi <acla...@redhat.com> wrote: > > > On Thu, Aug 1, 2019 at 5:16 PM Stephen Hemminger > > <step...@networkplumber.org> wrote: > > > > > > On Thu, 1 Aug 2019 12:12:58 +0200 > > > Andrea Claudi <acla...@redhat.com> wrote: > > > > > > > Add json support on iptunnel and ip6tunnel. > > > > The plain text output format should remain the same. > > > > > > > > Signed-off-by: Andrea Claudi <acla...@redhat.com> > > > > --- > > > > ip/ip6tunnel.c | 82 +++++++++++++++++++++++++++++++-------------- > > > > ip/iptunnel.c | 90 +++++++++++++++++++++++++++++++++----------------- > > > > ip/tunnel.c | 42 +++++++++++++++++------ > > > > 3 files changed, 148 insertions(+), 66 deletions(-) > > > > > > > > diff --git a/ip/ip6tunnel.c b/ip/ip6tunnel.c > > > > index d7684a673fdc4..f2b9710c1320f 100644 > > > > --- a/ip/ip6tunnel.c > > > > +++ b/ip/ip6tunnel.c > > > > @@ -71,57 +71,90 @@ static void usage(void) > > > > static void print_tunnel(const void *t) > > > > { > > > > const struct ip6_tnl_parm2 *p = t; > > > > - char s1[1024]; > > > > - char s2[1024]; > > > > + SPRINT_BUF(b1); > > > > > > > > /* Do not use format_host() for local addr, > > > > * symbolic name will not be useful. > > > > */ > > > > - printf("%s: %s/ipv6 remote %s local %s", > > > > - p->name, > > > > - tnl_strproto(p->proto), > > > > - format_host_r(AF_INET6, 16, &p->raddr, s1, sizeof(s1)), > > > > - rt_addr_n2a_r(AF_INET6, 16, &p->laddr, s2, sizeof(s2))); > > > > + open_json_object(NULL); > > > > + print_string(PRINT_ANY, "ifname", "%s: ", p->name); > > > > > > Print this using color for interface name? > > > > Thanks for the suggestion, I can do the same also for remote and local > > addresses? > > > > > > > > > > > > + snprintf(b1, sizeof(b1), "%s/ipv6", tnl_strproto(p->proto)); > > > > + print_string(PRINT_ANY, "mode", "%s ", b1); > > > > + print_string(PRINT_ANY, > > > > + "remote", > > > > + "remote %s ", > > > > + format_host_r(AF_INET6, 16, &p->raddr, b1, > > > > sizeof(b1))); > > > > + print_string(PRINT_ANY, > > > > + "local", > > > > + "local %s", > > > > + rt_addr_n2a_r(AF_INET6, 16, &p->laddr, b1, > > > > sizeof(b1))); > > > > + > > > > if (p->link) { > > > > const char *n = ll_index_to_name(p->link); > > > > > > > > if (n) > > > > - printf(" dev %s", n); > > > > + print_string(PRINT_ANY, "link", " dev %s", n); > > > > } > > > > > > > > if (p->flags & IP6_TNL_F_IGN_ENCAP_LIMIT) > > > > - printf(" encaplimit none"); > > > > + print_bool(PRINT_ANY, > > > > + "ip6_tnl_f_ign_encap_limit", > > > > + " encaplimit none", > > > > + true); > > > > > > For flags like this, print_null is more typical JSON than a boolean > > > value. Null is better for presence flag. Bool is better if both true and > > > false are printed. > > > > Using print_null json JSON output becomes: > > > > { > > "ifname": "gre2", > > "mode": "gre/ipv6", > > "remote": "fd::1", > > "local": "::", > > "ip6_tnl_f_ign_encap_limit": null, > > "hoplimit": 64, > > "tclass": "0x00", > > "flowlabel": "0x00000", > > "flowinfo": "0x00000000", > > "flags": [] > > } > > > > Which seems a bit confusing to me (what does the "null" value means?). > > Using print_null we also introduce an inconsistency with the JSON > > output of ip/link_gre6.c and ip/link_ip6tnl.c. > > I would prefer to use print_bool and print out > > ip6_tnl_f_ign_encap_limit both when true and false, patching both > > files above to do the same. WDYT? > > JSON has several ways to represent the same type of flag value. > Since JSON always has key/value. Null is used to indicate something is > present and > in that case the value is unnecessary, which is what the null field was meant > for. >
Thanks for the clarification, Stephen. I'll submit a v2 with print_null and I'll fix cases similar to the one you highlighted above in subsequent patches.