Re: [PATCH iproute2-next 1/7] ip: add color and json support to neigh

2018-03-06 Thread David Ahern
On 3/5/18 8:04 PM, Stephen Hemminger wrote:
> From: Stephen Hemminger 
> 
> Use json_print to provide json (and color) support to
> ip neigh command.
> 
> Signed-off-by: Stephen Hemminger 
> ---
>  ip/ipneigh.c | 143 
> ---
>  1 file changed, 97 insertions(+), 46 deletions(-)
> 
> diff --git a/ip/ipneigh.c b/ip/ipneigh.c
> index 0735424900f6..1f550e98e003 100644
> --- a/ip/ipneigh.c
> +++ b/ip/ipneigh.c
> @@ -23,6 +23,7 @@
>  #include "rt_names.h"
>  #include "utils.h"
>  #include "ip_common.h"
> +#include "json_print.h"
>  
>  #define NUD_VALID
> (NUD_PERMANENT|NUD_NOARP|NUD_REACHABLE|NUD_PROBE|NUD_STALE|NUD_DELAY)
>  #define MAX_ROUNDS   10
> @@ -189,6 +190,48 @@ static int ipneigh_modify(int cmd, int flags, int argc, 
> char **argv)
>   return 0;
>  }
>  
> +static void print_cacheinfo(const struct nda_cacheinfo *ci)
> +{
> + static int hz;
> +
> + if (!hz)
> + hz = get_user_hz();
> +
> + if (ci->ndm_refcnt)
> + print_uint(PRINT_ANY, "refcnt",
> + " ref %u", ci->ndm_refcnt);
> +
> + print_uint(PRINT_ANY,
> +  "used", " used %u", ci->ndm_used / hz);
> + print_uint(PRINT_ANY,
> +  "confirmed", "/%u", ci->ndm_confirmed / hz);
> + print_uint(PRINT_ANY,
> +  "updated", "/u", ci->ndm_updated / hz);

alignment is off in the above and it looks like all of them can be on 1
line and not exceed 80 col.


> +}
> +
> +static void print_neigh_state(unsigned int nud)
> +{
> +
> + open_json_array(PRINT_JSON,
> + is_json_context() ?  "state" : "");
> +
> +#define PRINT_FLAG(f)\
> + if (nud & NUD_##f) {\
> + nud &= ~NUD_##f;\
> + print_string(PRINT_ANY, NULL, " %s", #f);   \
> + }
> +
> + PRINT_FLAG(INCOMPLETE);
> + PRINT_FLAG(REACHABLE);
> + PRINT_FLAG(STALE);
> + PRINT_FLAG(DELAY);
> + PRINT_FLAG(PROBE);
> + PRINT_FLAG(FAILED);
> + PRINT_FLAG(NOARP);
> + PRINT_FLAG(PERMANENT);
> +#undef PRINT_FLAG
> + close_json_array(PRINT_JSON, NULL);
> +}
>  
>  int print_neigh(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
>  {
> @@ -262,65 +305,71 @@ int print_neigh(const struct sockaddr_nl *who, struct 
> nlmsghdr *n, void *arg)
>   return 0;
>   }
>  
> + open_json_object(NULL);
>   if (n->nlmsg_type == RTM_DELNEIGH)
> - fprintf(fp, "Deleted ");
> + print_bool(PRINT_ANY, "deleted", "Deleted ", true);
>   else if (n->nlmsg_type == RTM_GETNEIGH)
> - fprintf(fp, "miss ");
> + print_null(PRINT_ANY, "miss", "%s ", "miss");
> +
>   if (tb[NDA_DST]) {
> - fprintf(fp, "%s ",
> - format_host_rta(r->ndm_family, tb[NDA_DST]));
> + const char *dst;
> +
> + dst = format_host_rta(r->ndm_family, tb[NDA_DST]);
> + print_color_string(PRINT_ANY,
> +ifa_family_color(r->ndm_family),
> +"dst", "%s ", dst);
>   }
> - if (!filter.index && r->ndm_ifindex)
> - fprintf(fp, "dev %s ", ll_index_to_name(r->ndm_ifindex));
> +
> + if (!filter.index && r->ndm_ifindex) {
> + if (!is_json_context())
> + fprintf(fp, "dev ");
> +
> + print_color_string(PRINT_ANY, COLOR_IFNAME,
> +"dev", "%s ",
> +ll_index_to_name(r->ndm_ifindex));
> + }
> +
>   if (tb[NDA_LLADDR]) {
> + const char *lladdr;
>   SPRINT_BUF(b1);
> - fprintf(fp, "lladdr %s", ll_addr_n2a(RTA_DATA(tb[NDA_LLADDR]),
> -   RTA_PAYLOAD(tb[NDA_LLADDR]),
> -   ll_index_to_type(r->ndm_ifindex),
> -   b1, sizeof(b1)));
> - }
> - if (r->ndm_flags & NTF_ROUTER) {
> - fprintf(fp, " router");
> - }
> - if (r->ndm_flags & NTF_PROXY) {
> - fprintf(fp, " proxy");
> - }
> - if (tb[NDA_CACHEINFO] && show_stats) {
> - struct nda_cacheinfo *ci = RTA_DATA(tb[NDA_CACHEINFO]);
> - int hz = get_user_hz();
>  
> - if (ci->ndm_refcnt)
> - printf(" ref %d", ci->ndm_refcnt);
> - fprintf(fp, " used %d/%d/%d", ci->ndm_used/hz,
> -ci->ndm_confirmed/hz, ci->ndm_updated/hz);
> - }
> + lladdr = ll_addr_n2a(RTA_DATA(tb[NDA_LLADDR]),
> +  RTA_PAYLOAD(tb[NDA_LLADDR]),
> +  ll_index_to_type(r->ndm_ifindex),
> +  b1, 

[PATCH iproute2-next 1/7] ip: add color and json support to neigh

2018-03-05 Thread Stephen Hemminger
From: Stephen Hemminger 

Use json_print to provide json (and color) support to
ip neigh command.

Signed-off-by: Stephen Hemminger 
---
 ip/ipneigh.c | 143 ---
 1 file changed, 97 insertions(+), 46 deletions(-)

diff --git a/ip/ipneigh.c b/ip/ipneigh.c
index 0735424900f6..1f550e98e003 100644
--- a/ip/ipneigh.c
+++ b/ip/ipneigh.c
@@ -23,6 +23,7 @@
 #include "rt_names.h"
 #include "utils.h"
 #include "ip_common.h"
+#include "json_print.h"
 
 #define NUD_VALID  
(NUD_PERMANENT|NUD_NOARP|NUD_REACHABLE|NUD_PROBE|NUD_STALE|NUD_DELAY)
 #define MAX_ROUNDS 10
@@ -189,6 +190,48 @@ static int ipneigh_modify(int cmd, int flags, int argc, 
char **argv)
return 0;
 }
 
+static void print_cacheinfo(const struct nda_cacheinfo *ci)
+{
+   static int hz;
+
+   if (!hz)
+   hz = get_user_hz();
+
+   if (ci->ndm_refcnt)
+   print_uint(PRINT_ANY, "refcnt",
+   " ref %u", ci->ndm_refcnt);
+
+   print_uint(PRINT_ANY,
+"used", " used %u", ci->ndm_used / hz);
+   print_uint(PRINT_ANY,
+"confirmed", "/%u", ci->ndm_confirmed / hz);
+   print_uint(PRINT_ANY,
+"updated", "/u", ci->ndm_updated / hz);
+}
+
+static void print_neigh_state(unsigned int nud)
+{
+
+   open_json_array(PRINT_JSON,
+   is_json_context() ?  "state" : "");
+
+#define PRINT_FLAG(f)  \
+   if (nud & NUD_##f) {\
+   nud &= ~NUD_##f;\
+   print_string(PRINT_ANY, NULL, " %s", #f);   \
+   }
+
+   PRINT_FLAG(INCOMPLETE);
+   PRINT_FLAG(REACHABLE);
+   PRINT_FLAG(STALE);
+   PRINT_FLAG(DELAY);
+   PRINT_FLAG(PROBE);
+   PRINT_FLAG(FAILED);
+   PRINT_FLAG(NOARP);
+   PRINT_FLAG(PERMANENT);
+#undef PRINT_FLAG
+   close_json_array(PRINT_JSON, NULL);
+}
 
 int print_neigh(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
 {
@@ -262,65 +305,71 @@ int print_neigh(const struct sockaddr_nl *who, struct 
nlmsghdr *n, void *arg)
return 0;
}
 
+   open_json_object(NULL);
if (n->nlmsg_type == RTM_DELNEIGH)
-   fprintf(fp, "Deleted ");
+   print_bool(PRINT_ANY, "deleted", "Deleted ", true);
else if (n->nlmsg_type == RTM_GETNEIGH)
-   fprintf(fp, "miss ");
+   print_null(PRINT_ANY, "miss", "%s ", "miss");
+
if (tb[NDA_DST]) {
-   fprintf(fp, "%s ",
-   format_host_rta(r->ndm_family, tb[NDA_DST]));
+   const char *dst;
+
+   dst = format_host_rta(r->ndm_family, tb[NDA_DST]);
+   print_color_string(PRINT_ANY,
+  ifa_family_color(r->ndm_family),
+  "dst", "%s ", dst);
}
-   if (!filter.index && r->ndm_ifindex)
-   fprintf(fp, "dev %s ", ll_index_to_name(r->ndm_ifindex));
+
+   if (!filter.index && r->ndm_ifindex) {
+   if (!is_json_context())
+   fprintf(fp, "dev ");
+
+   print_color_string(PRINT_ANY, COLOR_IFNAME,
+  "dev", "%s ",
+  ll_index_to_name(r->ndm_ifindex));
+   }
+
if (tb[NDA_LLADDR]) {
+   const char *lladdr;
SPRINT_BUF(b1);
-   fprintf(fp, "lladdr %s", ll_addr_n2a(RTA_DATA(tb[NDA_LLADDR]),
- RTA_PAYLOAD(tb[NDA_LLADDR]),
- ll_index_to_type(r->ndm_ifindex),
- b1, sizeof(b1)));
-   }
-   if (r->ndm_flags & NTF_ROUTER) {
-   fprintf(fp, " router");
-   }
-   if (r->ndm_flags & NTF_PROXY) {
-   fprintf(fp, " proxy");
-   }
-   if (tb[NDA_CACHEINFO] && show_stats) {
-   struct nda_cacheinfo *ci = RTA_DATA(tb[NDA_CACHEINFO]);
-   int hz = get_user_hz();
 
-   if (ci->ndm_refcnt)
-   printf(" ref %d", ci->ndm_refcnt);
-   fprintf(fp, " used %d/%d/%d", ci->ndm_used/hz,
-  ci->ndm_confirmed/hz, ci->ndm_updated/hz);
-   }
+   lladdr = ll_addr_n2a(RTA_DATA(tb[NDA_LLADDR]),
+RTA_PAYLOAD(tb[NDA_LLADDR]),
+ll_index_to_type(r->ndm_ifindex),
+b1, sizeof(b1));
 
-   if (tb[NDA_PROBES] && show_stats) {
-   __u32 p = rta_getattr_u32(tb[NDA_PROBES]);
+   if (!is_json_context())
+   fprintf(fp, "lladdr ");
 
-   fprintf(fp, " probes %u", p);
+