lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Sat, 14 Jul 2018 18:41:03 -0700
From:   Roopa Prabhu <roopa@...ulusnetworks.com>
To:     Stephen Hemminger <stephen@...workplumber.org>
Cc:     netdev <netdev@...r.kernel.org>,
        Stephen Hemminger <sthemmin@...rosoft.com>,
        Julien Fortin <julien@...ulusnetworks.com>,
        David Ahern <dsahern@...il.com>
Subject: Re: [PATCH v2 iproute2-next 2/5] bridge: colorize output and use JSON
 print library

On Tue, Feb 20, 2018 at 11:24 AM, Stephen Hemminger
<stephen@...workplumber.org> wrote:
> From: Stephen Hemminger <sthemmin@...rosoft.com>
>
> Use new functions from json_print to simplify code.
> Provide standard flag for colorizing output.
>
> The shortened -c flag is ambiguous it could mean color or
> compressvlan; it is now changed to mean color for consistency
> with other iproute2 commands.
>
> Signed-off-by: Stephen Hemminger <stephen@...workplumber.org>
> ---
>  bridge/br_common.h |   2 +-
>  bridge/bridge.c    |  10 +-
>  bridge/fdb.c       | 281 +++++++++++++++--------------------------
>  bridge/mdb.c       | 362 ++++++++++++++++++++++-------------------------------
>  bridge/vlan.c      | 276 +++++++++++++++-------------------------
>  5 files changed, 363 insertions(+), 568 deletions(-)
>
> diff --git a/bridge/br_common.h b/bridge/br_common.h
> index b25f61e50e05..2f1cb8fd9f3d 100644
> --- a/bridge/br_common.h
> +++ b/bridge/br_common.h
> @@ -6,7 +6,7 @@
>  #define MDB_RTR_RTA(r) \
>                 ((struct rtattr *)(((char *)(r)) + RTA_ALIGN(sizeof(__u32))))
>
> -extern void print_vlan_info(FILE *fp, struct rtattr *tb, int ifindex);
> +extern void print_vlan_info(FILE *fp, struct rtattr *tb);
>  extern int print_linkinfo(const struct sockaddr_nl *who,
>                           struct nlmsghdr *n,
>                           void *arg);
> diff --git a/bridge/bridge.c b/bridge/bridge.c
> index 4b112e3b8da9..e5b4c3c2198f 100644
> --- a/bridge/bridge.c
> +++ b/bridge/bridge.c
> @@ -16,12 +16,15 @@
>  #include "utils.h"
>  #include "br_common.h"
>  #include "namespace.h"
> +#include "color.h"
>
>  struct rtnl_handle rth = { .fd = -1 };
>  int preferred_family = AF_UNSPEC;
>  int oneline;
>  int show_stats;
>  int show_details;
> +int show_pretty;
> +int color;
>  int compress_vlans;
>  int json;
>  int timestamp;
> @@ -39,7 +42,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] -p[retty] -j{son} }\n");
> +"                   -c[ompressvlans] -color -p[retty] -j{son} }\n");
>         exit(-1);
>  }
>
> @@ -170,6 +173,8 @@ main(int argc, char **argv)
>                         NEXT_ARG();
>                         if (netns_switch(argv[1]))
>                                 exit(-1);
> +               } else if (matches(opt, "-color") == 0) {
> +                       enable_color();
>                 } else if (matches(opt, "-compressvlans") == 0) {
>                         ++compress_vlans;
>                 } else if (matches(opt, "-force") == 0) {
> @@ -195,6 +200,9 @@ main(int argc, char **argv)
>
>         _SL_ = oneline ? "\\" : "\n";
>
> +       if (json)
> +               check_if_color_enabled();
> +
>         if (batch_file)
>                 return batch(batch_file);
>
> diff --git a/bridge/fdb.c b/bridge/fdb.c
> index 93b5b2e694e3..b4f6e8b3a01b 100644
> --- a/bridge/fdb.c
> +++ b/bridge/fdb.c
> @@ -22,9 +22,9 @@
>  #include <linux/neighbour.h>
>  #include <string.h>
>  #include <limits.h>
> -#include <json_writer.h>
>  #include <stdbool.h>
>
> +#include "json_print.h"
>  #include "libnetlink.h"
>  #include "br_common.h"
>  #include "rt_names.h"
> @@ -32,8 +32,6 @@
>
>  static unsigned int filter_index, filter_vlan, filter_state;
>
> -json_writer_t *jw_global;
> -
>  static void usage(void)
>  {
>         fprintf(stderr,
> @@ -83,13 +81,46 @@ static int state_a2n(unsigned int *s, const char *arg)
>         return 0;
>  }
>
> -static void start_json_fdb_flags_array(bool *fdb_flags)
> +static void fdb_print_flags(FILE *fp, unsigned int flags)
> +{
> +       open_json_array(PRINT_JSON,
> +                       is_json_context() ?  "flags" : "");
> +
> +       if (flags & NTF_SELF)
> +               print_string(PRINT_ANY, NULL, "%s ", "self");
> +
> +       if (flags & NTF_ROUTER)
> +               print_string(PRINT_ANY, NULL, "%s ", "router");
> +
> +       if (flags & NTF_EXT_LEARNED)
> +               print_string(PRINT_ANY, NULL, "%s ", "extern_learn");
> +
> +       if (flags & NTF_OFFLOADED)
> +               print_string(PRINT_ANY, NULL, "%s ", "offload");
> +
> +       if (flags & NTF_MASTER)
> +               print_string(PRINT_ANY, NULL, "%s ", "master");
> +
> +       close_json_array(PRINT_JSON, NULL);
> +}
> +
> +static void fdb_print_stats(FILE *fp, const struct nda_cacheinfo *ci)
>  {
> -       if (*fdb_flags)
> -               return;
> -       jsonw_name(jw_global, "flags");
> -       jsonw_start_array(jw_global);
> -       *fdb_flags = true;
> +       static int hz;
> +
> +       if (!hz)
> +               hz = get_user_hz();
> +
> +       if (is_json_context()) {
> +               print_uint(PRINT_JSON, "used", NULL,
> +                                ci->ndm_used / hz);
> +               print_uint(PRINT_JSON, "updated", NULL,
> +                               ci->ndm_updated / hz);
> +       } else {
> +               fprintf(fp, "used %d/%d ", ci->ndm_used / hz,
> +                                       ci->ndm_updated / hz);
> +
> +       }
>  }
>
>  int print_fdb(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
> @@ -99,8 +130,6 @@ 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",
> @@ -132,189 +161,98 @@ int print_fdb(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
>         if (filter_vlan && filter_vlan != vid)
>                 return 0;
>
> -       if (jw_global)
> -               jsonw_start_object(jw_global);
> -
> -       if (n->nlmsg_type == RTM_DELNEIGH) {
> -               if (jw_global)
> -                       jsonw_string_field(jw_global, "opCode", "deleted");
> -               else
> -                       fprintf(fp, "Deleted ");
> -       }
> +       open_json_object(NULL);
> +       if (n->nlmsg_type == RTM_DELNEIGH)
> +               print_bool(PRINT_ANY, "deleted", "Deleted ", true);
>
>         if (tb[NDA_LLADDR]) {
> +               const char *lladdr;
>                 SPRINT_BUF(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);
> +
> +               lladdr = ll_addr_n2a(RTA_DATA(tb[NDA_LLADDR]),
> +                                    RTA_PAYLOAD(tb[NDA_LLADDR]),
> +                                    ll_index_to_type(r->ndm_ifindex),
> +                                    b1, sizeof(b1));
> +
> +               print_color_string(PRINT_ANY, COLOR_MAC,
> +                                  "mac", "%s ", lladdr);
>         }
>
>         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 (!is_json_context())
> +                       fprintf(fp, "dev ");
> +               print_color_string(PRINT_ANY, COLOR_IFNAME,
> +                                  "ifname", "%s ",
> +                                  ll_index_to_name(r->ndm_ifindex));
>         }
>
>         if (tb[NDA_DST]) {
>                 int family = AF_INET;
> -               const char *abuf_s;
> +               const char *dst;
>
>                 if (RTA_PAYLOAD(tb[NDA_DST]) == sizeof(struct in6_addr))
>                         family = AF_INET6;
>
> -               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);
> -       }
> +               dst = format_host(family,
> +                                 RTA_PAYLOAD(tb[NDA_DST]),
> +                                 RTA_DATA(tb[NDA_DST]));
>
> -       if (vid) {
> -               if (jw_global)
> -                       jsonw_uint_field(jw_global, "vlan", vid);
> -               else
> -                       fprintf(fp, "vlan %hu ", vid);
> +               print_color_string(PRINT_ANY,
> +                                  ifa_family_color(family),
> +                                   "dst", "%s ", dst);
>         }
>
> -       if (tb[NDA_PORT]) {
> -               if (jw_global)
> -                       jsonw_uint_field(jw_global, "port",
> -                                        rta_getattr_be16(tb[NDA_PORT]));
> -               else
> -                       fprintf(fp, "port %d ",
> -                               rta_getattr_be16(tb[NDA_PORT]));
> -       }
> +       if (vid)
> +               print_uint(PRINT_ANY,
> +                                "vlan", "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])
> +               print_uint(PRINT_ANY,
> +                                "port", "port %u ",
> +                                rta_getattr_be16(tb[NDA_PORT]));
>
> -       if (tb[NDA_SRC_VNI]) {
> -               if (jw_global)
> -                       jsonw_uint_field(jw_global, "src_vni",
> -                                        rta_getattr_u32(tb[NDA_SRC_VNI]));
> -               else
> -                       fprintf(fp, "src_vni %d ",
> +       if (tb[NDA_VNI])
> +               print_uint(PRINT_ANY,
> +                                "vni", "vni %u ",
> +                                rta_getattr_u32(tb[NDA_VNI]));
> +
> +       if (tb[NDA_SRC_VNI])
> +               print_uint(PRINT_ANY,
> +                                "src_vni", "src_vni %u ",
>                                 rta_getattr_u32(tb[NDA_SRC_VNI]));
> -       }
>
>         if (tb[NDA_IFINDEX]) {
>                 unsigned int ifindex = rta_getattr_u32(tb[NDA_IFINDEX]);
>
> -               if (ifindex) {
> -                       if (!tb[NDA_LINK_NETNSID]) {
> -                               const char *ifname = ll_index_to_name(ifindex);
> -
> -                               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]) {
> -               if (jw_global)
> -                       jsonw_uint_field(jw_global, "linkNetNsId",
> -                                        rta_getattr_u32(tb[NDA_LINK_NETNSID]));
> +               if (tb[NDA_LINK_NETNSID])
> +                       print_uint(PRINT_ANY,
> +                                        "viaIfIndex", "via ifindex %u ",
> +                                        ifindex);
>                 else
> -                       fprintf(fp, "link-netnsid %d ",
> -                               rta_getattr_u32(tb[NDA_LINK_NETNSID]));
> +                       print_string(PRINT_ANY,
> +                                          "viaIf", "via %s ",
> +                                          ll_index_to_name(ifindex));
>         }
>
> -       if (show_stats && tb[NDA_CACHEINFO]) {
> -               struct nda_cacheinfo *ci = RTA_DATA(tb[NDA_CACHEINFO]);
> -               int hz = get_user_hz();
> +       if (tb[NDA_LINK_NETNSID])
> +               print_uint(PRINT_ANY,
> +                                "linkNetNsId", "link-netnsid %d ",
> +                                rta_getattr_u32(tb[NDA_LINK_NETNSID]));
>
> -               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 (show_stats && tb[NDA_CACHEINFO])
> +               fdb_print_stats(fp, RTA_DATA(tb[NDA_CACHEINFO]));
>
> -       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, "extern_learn");
> -               }
> -               if (r->ndm_flags & NTF_OFFLOADED) {
> -                       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);
> +       fdb_print_flags(fp, r->ndm_flags);
>
> -               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, "extern_learn ");
> -               if (r->ndm_flags & NTF_OFFLOADED)
> -                       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 (tb[NDA_MASTER])
> +               print_string(PRINT_ANY, "master", "%s ",
> +                            ll_index_to_name(rta_getattr_u32(tb[NDA_MASTER])));
>
> +       print_string(PRINT_ANY, "state", "%s\n",
> +                          state_n2a(r->ndm_state));
> +       close_json_object();
> +       fflush(fp);
>         return 0;
>  }
>
> @@ -386,26 +324,13 @@ static int fdb_show(int argc, char **argv)
>                 exit(1);
>         }
>
> -       if (json) {
> -               jw_global = jsonw_new(stdout);
> -               if (!jw_global) {
> -                       fprintf(stderr, "Error allocation json object\n");
> -                       exit(1);
> -               }
> -               if (pretty)
> -                       jsonw_pretty(jw_global, 1);
> -
> -               jsonw_start_array(jw_global);
> -       }
> -
> +       new_json_obj(json);
>         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);
> -       }
> +       delete_json_obj();
> +       fflush(stdout);
>
>         return 0;
>  }
> diff --git a/bridge/mdb.c b/bridge/mdb.c
> index da0282fdc91c..8c08baf570ec 100644
> --- a/bridge/mdb.c
> +++ b/bridge/mdb.c
> @@ -14,12 +14,12 @@
>  #include <linux/if_ether.h>
>  #include <string.h>
>  #include <arpa/inet.h>
> -#include <json_writer.h>
>
>  #include "libnetlink.h"
>  #include "br_common.h"
>  #include "rt_names.h"
>  #include "utils.h"
> +#include "json_print.h"
>
>  #ifndef MDBA_RTA
>  #define MDBA_RTA(r) \
> @@ -27,9 +27,6 @@
>  #endif
>
>  static unsigned int filter_index, filter_vlan;
> -json_writer_t *jw_global;
> -static bool print_mdb_entries = true;
> -static bool print_mdb_router = true;
>
>  static void usage(void)
>  {
> @@ -43,162 +40,131 @@ static bool is_temp_mcast_rtr(__u8 type)
>         return type == MDB_RTR_TYPE_TEMP_QUERY || type == MDB_RTR_TYPE_TEMP;
>  }
>
> +static const char *format_timer(__u32 ticks)
> +{
> +       struct timeval tv;
> +       static char tbuf[32];
> +
> +       __jiffies_to_tv(&tv, ticks);
> +       snprintf(tbuf, sizeof(tbuf), "%4lu.%.2lu",
> +                (unsigned long)tv.tv_sec,
> +                (unsigned long)tv.tv_usec / 10000);
> +
> +       return tbuf;
> +}
> +
>  static void __print_router_port_stats(FILE *f, struct rtattr *pattr)
>  {
>         struct rtattr *tb[MDBA_ROUTER_PATTR_MAX + 1];
> -       struct timeval tv;
> -       __u8 type;
>
>         parse_rtattr(tb, MDBA_ROUTER_PATTR_MAX, MDB_RTR_RTA(RTA_DATA(pattr)),
>                      RTA_PAYLOAD(pattr) - RTA_ALIGN(sizeof(uint32_t)));
> +
>         if (tb[MDBA_ROUTER_PATTR_TIMER]) {
> -               __jiffies_to_tv(&tv,
> -                               rta_getattr_u32(tb[MDBA_ROUTER_PATTR_TIMER]));
> -               if (jw_global) {
> -                       char formatted_time[9];
> -
> -                       snprintf(formatted_time, sizeof(formatted_time),
> -                                "%4i.%.2i", (int)tv.tv_sec,
> -                                (int)tv.tv_usec/10000);
> -                       jsonw_string_field(jw_global, "timer", formatted_time);
> -               } else {
> -                       fprintf(f, " %4i.%.2i",
> -                               (int)tv.tv_sec, (int)tv.tv_usec/10000);
> -               }
> +               __u32 timer = rta_getattr_u32(tb[MDBA_ROUTER_PATTR_TIMER]);
> +
> +               print_string(PRINT_ANY, "timer", " %s",
> +                            format_timer(timer));
>         }
> +
>         if (tb[MDBA_ROUTER_PATTR_TYPE]) {
> -               type = rta_getattr_u8(tb[MDBA_ROUTER_PATTR_TYPE]);
> -               if (jw_global)
> -                       jsonw_string_field(jw_global, "type",
> -                               is_temp_mcast_rtr(type) ? "temp" : "permanent");
> -               else
> -                       fprintf(f, " %s",
> -                               is_temp_mcast_rtr(type) ? "temp" : "permanent");
> +               __u8 type = rta_getattr_u8(tb[MDBA_ROUTER_PATTR_TYPE]);
> +
> +               print_string(PRINT_ANY, "type", " %s",
> +                            is_temp_mcast_rtr(type) ? "temp" : "permanent");
>         }
>  }
>
> -static void br_print_router_ports(FILE *f, struct rtattr *attr, __u32 brifidx)
> +static void br_print_router_ports(FILE *f, struct rtattr *attr,
> +                                 const char *brifname)
>  {
> -       uint32_t *port_ifindex;
> +       int rem = RTA_PAYLOAD(attr);
>         struct rtattr *i;
> -       int rem;
>
> -       rem = RTA_PAYLOAD(attr);
> -       if (jw_global) {
> -               jsonw_name(jw_global, ll_index_to_name(brifidx));
> -               jsonw_start_array(jw_global);
> -               for (i = RTA_DATA(attr); RTA_OK(i, rem); i = RTA_NEXT(i, rem)) {
> -                       port_ifindex = RTA_DATA(i);
> -                       jsonw_start_object(jw_global);
> -                       jsonw_string_field(jw_global,
> -                                          "port",
> -                                          ll_index_to_name(*port_ifindex));
> +       if (is_json_context())
> +               open_json_array(PRINT_JSON, brifname);
> +       else if (!show_stats)
> +               fprintf(f, "router ports on %s: ", brifname);
> +
> +       for (i = RTA_DATA(attr); RTA_OK(i, rem); i = RTA_NEXT(i, rem)) {
> +               uint32_t *port_ifindex = RTA_DATA(i);
> +               const char *port_ifname = ll_index_to_name(*port_ifindex);
> +
> +               if (is_json_context()) {
> +                       open_json_object(NULL);
> +                       print_string(PRINT_JSON, "port", NULL, port_ifname);
> +
>                         if (show_stats)
>                                 __print_router_port_stats(f, i);
> -                       jsonw_end_object(jw_global);
> -               }
> -               jsonw_end_array(jw_global);
> -       } else {
> -               if (!show_stats)
> -                       fprintf(f, "router ports on %s: ",
> -                               ll_index_to_name(brifidx));
> -               for (i = RTA_DATA(attr); RTA_OK(i, rem); i = RTA_NEXT(i, rem)) {
> -                       port_ifindex = RTA_DATA(i);
> -                       if (show_stats) {
> -                               fprintf(f, "router ports on %s: %s",
> -                                       ll_index_to_name(brifidx),
> -                                       ll_index_to_name(*port_ifindex));
> -                               __print_router_port_stats(f, i);
> -                               fprintf(f, "\n");
> -                       } else{
> -                               fprintf(f, "%s ",
> -                                       ll_index_to_name(*port_ifindex));
> -                       }
> -               }
> -               if (!show_stats)
> +                       close_json_object();
> +               } else if (show_stats) {
> +                       fprintf(f, "router ports on %s: %s",
> +                               brifname, port_ifname);
> +
> +                       __print_router_port_stats(f, i);
>                         fprintf(f, "\n");
> +               } else {
> +                       fprintf(f, "%s ", port_ifname);
> +               }
>         }
> +       close_json_array(PRINT_JSON, NULL);
>  }
>
> -static void start_json_mdb_flags_array(bool *mdb_flags)
> -{
> -       if (*mdb_flags)
> -               return;
> -       jsonw_name(jw_global, "flags");
> -       jsonw_start_array(jw_global);
> -       *mdb_flags = true;
> -}
> -
> -static void print_mdb_entry(FILE *f, int ifindex, struct br_mdb_entry *e,
> +static void print_mdb_entry(FILE *f, int ifindex, const struct br_mdb_entry *e,
>                             struct nlmsghdr *n, struct rtattr **tb)
>  {
>         SPRINT_BUF(abuf);
> +       const char *dev;
>         const void *src;
>         int af;
> -       bool mdb_flags = false;
>
>         if (filter_vlan && e->vid != filter_vlan)
>                 return;
> +
>         af = e->addr.proto == htons(ETH_P_IP) ? AF_INET : AF_INET6;
>         src = af == AF_INET ? (const void *)&e->addr.u.ip4 :
>                               (const void *)&e->addr.u.ip6;
> -       if (jw_global)
> -               jsonw_start_object(jw_global);
> -       if (n->nlmsg_type == RTM_DELMDB) {
> -               if (jw_global)
> -                       jsonw_string_field(jw_global, "opCode", "deleted");
> -               else
> -                       fprintf(f, "Deleted ");
> -       }
> -       if (jw_global) {
> -               jsonw_string_field(jw_global, "dev", ll_index_to_name(ifindex));
> -               jsonw_string_field(jw_global,
> -                                  "port",
> -                                  ll_index_to_name(e->ifindex));
> -               jsonw_string_field(jw_global, "grp", inet_ntop(af, src,
> -                       abuf, sizeof(abuf)));
> -               jsonw_string_field(jw_global, "state",
> -                       (e->state & MDB_PERMANENT) ? "permanent" : "temp");
> -               if (e->flags & MDB_FLAGS_OFFLOAD) {
> -                       start_json_mdb_flags_array(&mdb_flags);
> -                       jsonw_string(jw_global, "offload");
> -               }
> -               if (mdb_flags)
> -                       jsonw_end_array(jw_global);
> -       } else{
> -               fprintf(f, "dev %s port %s grp %s %s %s",
> -                       ll_index_to_name(ifindex),
> -                       ll_index_to_name(e->ifindex),
> -                       inet_ntop(af, src, abuf, sizeof(abuf)),
> -                       (e->state & MDB_PERMANENT) ? "permanent" : "temp",
> -                       (e->flags & MDB_FLAGS_OFFLOAD) ? "offload" : "");
> -       }
> -       if (e->vid) {
> -               if (jw_global)
> -                       jsonw_uint_field(jw_global, "vid", e->vid);
> -               else
> -                       fprintf(f, " vid %hu", e->vid);
> +       dev = ll_index_to_name(ifindex);
> +
> +       open_json_object(NULL);
> +
> +       if (n->nlmsg_type == RTM_DELMDB)
> +               print_bool(PRINT_ANY, "deleted", "Deleted ", true);
> +
> +
> +       if (is_json_context()) {
> +               print_int(PRINT_JSON, "index", NULL, ifindex);
> +               print_string(PRINT_JSON, "dev", NULL, dev);
> +       } else {
> +               fprintf(f, "%u: ", ifindex);
> +               color_fprintf(f, COLOR_IFNAME, "%s ", dev);
>         }
> -       if (show_stats && tb && tb[MDBA_MDB_EATTR_TIMER]) {
> -               struct timeval tv;
>
> -               __jiffies_to_tv(&tv, rta_getattr_u32(tb[MDBA_MDB_EATTR_TIMER]));
> -               if (jw_global) {
> -                       char formatted_time[9];
> +       print_string(PRINT_ANY, "port", " %s ",
> +                    ll_index_to_name(e->ifindex));
>
> -                       snprintf(formatted_time, sizeof(formatted_time),
> -                                "%4i.%.2i", (int)tv.tv_sec,
> -                                (int)tv.tv_usec/10000);
> -                       jsonw_string_field(jw_global, "timer", formatted_time);
> -               } else {
> -                       fprintf(f, "%4i.%.2i", (int)tv.tv_sec,
> -                               (int)tv.tv_usec/10000);
> -               }
> +       print_color_string(PRINT_ANY, ifa_family_color(af),
> +                           "grp", " %s ",
> +                           inet_ntop(af, src, abuf, sizeof(abuf)));
> +
> +       print_string(PRINT_ANY, "state", " %s ",
> +                          (e->state & MDB_PERMANENT) ? "permanent" : "temp");
> +
> +       open_json_array(PRINT_JSON, "flags");
> +       if (e->flags & MDB_FLAGS_OFFLOAD)
> +               print_string(PRINT_ANY, NULL, "%s ", "offload");
> +       close_json_array(PRINT_JSON, NULL);
> +
> +       if (e->vid)
> +               print_uint(PRINT_ANY, "vid", " vid %u", e->vid);
> +
> +       if (show_stats && tb && tb[MDBA_MDB_EATTR_TIMER]) {
> +               __u32 timer = rta_getattr_u32(tb[MDBA_MDB_EATTR_TIMER]);
> +
> +               print_string(PRINT_ANY, "timer", " %s",
> +                            format_timer(timer));
>         }
> -       if (jw_global)
> -               jsonw_end_object(jw_global);
> -       else
> -               fprintf(f, "\n");
> +       close_json_object();
>  }
>
>  static void br_print_mdb_entry(FILE *f, int ifindex, struct rtattr *attr,
> @@ -218,15 +184,60 @@ static void br_print_mdb_entry(FILE *f, int ifindex, struct rtattr *attr,
>         }
>  }
>
> +static void print_mdb_entries(FILE *fp, struct nlmsghdr *n,
> +                             int ifindex,  struct rtattr *mdb)
> +{
> +       int rem = RTA_PAYLOAD(mdb);
> +       struct rtattr *i;
> +
> +       open_json_array(PRINT_JSON, "mdb");
> +       for (i = RTA_DATA(mdb); RTA_OK(i, rem); i = RTA_NEXT(i, rem))
> +               br_print_mdb_entry(fp, ifindex, i, n);
> +       close_json_array(PRINT_JSON, NULL);
> +}
> +
> +static void print_router_entries(FILE *fp, struct nlmsghdr *n,
> +                                int ifindex, struct rtattr *router)
> +{
> +       const char *brifname = ll_index_to_name(ifindex);
> +
> +       open_json_array(PRINT_JSON, "router");
> +       if (n->nlmsg_type == RTM_GETMDB) {
> +               if (show_details)
> +                       br_print_router_ports(fp, router, brifname);
> +       } else {
> +               struct rtattr *i = RTA_DATA(router);
> +               uint32_t *port_ifindex = RTA_DATA(i);
> +
> +               if (is_json_context()) {
> +                       open_json_array(PRINT_JSON, brifname);
> +                       open_json_object(NULL);
> +
> +                       print_string(PRINT_JSON, "port", NULL,
> +                                    ll_index_to_name(*port_ifindex));
> +                       close_json_object();
> +                       close_json_array(PRINT_JSON, NULL);
> +               } else {
> +                       fprintf(fp, "router port dev %s master %s\n",
> +                               ll_index_to_name(*port_ifindex),
> +                               brifname);
> +               }
> +       }
> +       close_json_array(PRINT_JSON, NULL);
> +}
> +
>  int print_mdb(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
>  {
>         FILE *fp = arg;
>         struct br_port_msg *r = NLMSG_DATA(n);
>         int len = n->nlmsg_len;
> -       struct rtattr *tb[MDBA_MAX+1], *i;
> +       struct rtattr *tb[MDBA_MAX+1];
>
> -       if (n->nlmsg_type != RTM_GETMDB && n->nlmsg_type != RTM_NEWMDB && n->nlmsg_type != RTM_DELMDB) {
> -               fprintf(stderr, "Not RTM_GETMDB, RTM_NEWMDB or RTM_DELMDB: %08x %08x %08x\n",
> +       if (n->nlmsg_type != RTM_GETMDB &&
> +           n->nlmsg_type != RTM_NEWMDB &&
> +           n->nlmsg_type != RTM_DELMDB) {
> +               fprintf(stderr,
> +                       "Not RTM_GETMDB, RTM_NEWMDB or RTM_DELMDB: %08x %08x %08x\n",
>                         n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags);
>
>                 return 0;
> @@ -243,50 +254,14 @@ int print_mdb(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
>
>         parse_rtattr(tb, MDBA_MAX, MDBA_RTA(r), n->nlmsg_len - NLMSG_LENGTH(sizeof(*r)));
>
> -       if (tb[MDBA_MDB] && print_mdb_entries) {
> -               int rem = RTA_PAYLOAD(tb[MDBA_MDB]);
> +       if (n->nlmsg_type == RTM_DELMDB)
> +               print_bool(PRINT_ANY, "deleted", "Deleted ", true);
>
> -               for (i = RTA_DATA(tb[MDBA_MDB]); RTA_OK(i, rem); i = RTA_NEXT(i, rem))
> -                       br_print_mdb_entry(fp, r->ifindex, i, n);
> -       }
> +       if (tb[MDBA_MDB])
> +               print_mdb_entries(fp, n, r->ifindex, tb[MDBA_MDB]);
>
> -       if (tb[MDBA_ROUTER] && print_mdb_router) {
> -               if (n->nlmsg_type == RTM_GETMDB) {
> -                       if (show_details)
> -                               br_print_router_ports(fp, tb[MDBA_ROUTER],
> -                                                     r->ifindex);
> -               } else {
> -                       uint32_t *port_ifindex;
> -
> -                       i = RTA_DATA(tb[MDBA_ROUTER]);
> -                       port_ifindex = RTA_DATA(i);
> -                       if (n->nlmsg_type == RTM_DELMDB) {
> -                               if (jw_global)
> -                                       jsonw_string_field(jw_global,
> -                                                          "opCode",
> -                                                          "deleted");
> -                               else
> -                                       fprintf(fp, "Deleted ");
> -                       }
> -                       if (jw_global) {
> -                               jsonw_name(jw_global,
> -                                          ll_index_to_name(r->ifindex));
> -                               jsonw_start_array(jw_global);
> -                               jsonw_start_object(jw_global);
> -                               jsonw_string_field(jw_global, "port",
> -                                       ll_index_to_name(*port_ifindex));
> -                               jsonw_end_object(jw_global);
> -                               jsonw_end_array(jw_global);
> -                       } else {
> -                               fprintf(fp, "router port dev %s master %s\n",
> -                                       ll_index_to_name(*port_ifindex),
> -                                       ll_index_to_name(r->ifindex));
> -                       }
> -               }
> -       }
> -
> -       if (!jw_global)
> -               fflush(fp);
> +       if (tb[MDBA_ROUTER])
> +               print_router_entries(fp, n, r->ifindex, tb[MDBA_ROUTER]);
>
>         return 0;
>  }
> @@ -319,62 +294,21 @@ static int mdb_show(int argc, char **argv)
>                 }
>         }
>
> +       new_json_obj(json);
> +
>         /* get mdb entries*/
>         if (rtnl_wilddump_request(&rth, PF_BRIDGE, RTM_GETMDB) < 0) {
>                 perror("Cannot send dump request");
>                 return -1;
>         }
>
> -       if (!json) {
> -               /* Normal output */
> -               if (rtnl_dump_filter(&rth, print_mdb, stdout) < 0) {
> -                       fprintf(stderr, "Dump terminated\n");
> -                       return -1;
> -               }
> -               return 0;
> -       }
> -
> -       /* Json output */
> -       jw_global = jsonw_new(stdout);
> -       if (!jw_global) {
> -               fprintf(stderr, "Error allocation json object\n");
> -               exit(1);
> -       }
> -
> -       if (pretty)
> -               jsonw_pretty(jw_global, 1);
> -
> -       jsonw_start_object(jw_global);
> -       jsonw_name(jw_global, "mdb");
> -       jsonw_start_array(jw_global);
> -
> -       /* print mdb entries */
> -       print_mdb_entries = true;
> -       print_mdb_router = false;
>         if (rtnl_dump_filter(&rth, print_mdb, stdout) < 0) {
>                 fprintf(stderr, "Dump terminated\n");
>                 return -1;
>         }
> -       jsonw_end_array(jw_global);
> -
> -       /* get router ports */
> -       if (rtnl_wilddump_request(&rth, PF_BRIDGE, RTM_GETMDB) < 0) {
> -               perror("Cannot send dump request");
> -               return -1;
> -       }
> -       jsonw_name(jw_global, "router");
> -       jsonw_start_object(jw_global);
>
> -       /* print router ports */
> -       print_mdb_entries = false;
> -       print_mdb_router = true;
> -       if (rtnl_dump_filter(&rth, print_mdb, stdout) < 0) {
> -               fprintf(stderr, "Dump terminated\n");
> -               return -1;
> -       }
> -       jsonw_end_object(jw_global);
> -       jsonw_end_object(jw_global);
> -       jsonw_destroy(&jw_global);
> +       delete_json_obj();
> +       fflush(stdout);
>
>         return 0;
>  }
> diff --git a/bridge/vlan.c b/bridge/vlan.c
> index 7c8b3ad54857..9f4a7a2be55c 100644
> --- a/bridge/vlan.c
> +++ b/bridge/vlan.c
> @@ -8,19 +8,16 @@
>  #include <netinet/in.h>
>  #include <linux/if_bridge.h>
>  #include <linux/if_ether.h>
> -#include <json_writer.h>
>  #include <string.h>
>
> +#include "json_print.h"
>  #include "libnetlink.h"
>  #include "br_common.h"
>  #include "utils.h"
>
>  static unsigned int filter_index, filter_vlan;
> -static int last_ifidx = -1;
>  static int show_vlan_tunnel_info = 0;
>
> -json_writer_t *jw_global;
> -
>  static void usage(void)
>  {
>         fprintf(stderr,
> @@ -257,38 +254,33 @@ static int filter_vlan_check(__u16 vid, __u16 flags)
>
>  static void print_vlan_port(FILE *fp, int ifi_index)
>  {
> -       if (jw_global) {
> -               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));
> -       }
> +       print_string(PRINT_ANY, NULL, "%s",
> +                    ll_index_to_name(ifi_index));
>  }
>

Stephen, this seems to have broken both json and non-json output.

Here is some output before and after the patch (same thing for tunnelshow):

before:
$bridge vlan show
port    vlan ids
hostbond4        1000
         1001 PVID Egress Untagged
         1002
         1003
         1004

hostbond3        1000 PVID Egress Untagged
         1001
         1002
         1003
         1004

bridge   1 PVID Egress Untagged
         1000
         1001
         1002
         1003
         1004

vxlan0   1 PVID Egress Untagged
         1000
         1001
         1002
         1003
         1004


$ bridge -j -c vlan show
{
    "hostbond4": [{
            "vlan": 1000
        },{
            "vlan": 1001,
            "flags": ["PVID","Egress Untagged"
            ]
        },{
            "vlan": 1002,
            "vlanEnd": 1004
        }
    ],
    "hostbond3": [{
            "vlan": 1000,
            "flags": ["PVID","Egress Untagged"
            ]
        },{
            "vlan": 1001,
            "vlanEnd": 1004
        }
    ],
    "bridge": [{
            "vlan": 1,
            "flags": ["PVID","Egress Untagged"
            ]
        },{
            "vlan": 1000,
            "vlanEnd": 1004
        }
    ],
        "vxlan0": [{
            "vlan": 1,
            "flags": ["PVID","Egress Untagged"
            ]
        },{
            "vlan": 1000,
            "vlanEnd": 1004
        }
    ]
}


after:
====

$bridge vlan show
port    vlan ids
hostbond4
         1000    1001 PVID untagged      1002    1003    1004
hostbond3
         1000 PVID untagged      1001    1002    1003    1004
bridge
         1 PVID untagged         1000    1001    1002    1003    1004
vxlan0
         1 PVID untagged         1000    1001    1002    1003    1004

$bridge -j -c vlan show
["hostbond4","vlan":[{"vlan":1000},{"vlan":1001,"pvid":null,"untagged":null},{"vlan":1002},{"vlan":1003},{"vlan":1004}],"hostbond3","vlan":[{"vlan":1000,"pvid":null,"untagged":null},{"vlan":1001},{"vlan":1002},{"vlan":1003},{"vlan":1004}],"bridge","vlan":[{"vlan":1,"pvid":null,"untagged":null},{"vlan":1000},{"vlan":1001},{"vlan":1002},{"vlan":1003},{"vlan":1004}],"vxlan0","vlan":[{"vlan":1,"pvid":null,"untagged":null},{"vlan":1000},{"vlan":1001},{"vlan":1002},{"vlan":1003},{"vlan":1004}]]

Powered by blists - more mailing lists