On 3/5/18 8:04 PM, Stephen Hemminger wrote:
> From: Stephen Hemminger <sthem...@microsoft.com>
> 
> Use json_print to provide json (and color) support to
> ip neigh command.
> 
> Signed-off-by: Stephen Hemminger <step...@networkplumber.org>
> ---
>  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, 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);
> +             print_color_string(PRINT_ANY, COLOR_MAC,
> +                                "lladdr", "%s", lladdr);
>       }
>  
> -     if (r->ndm_state) {
> -             int nud = r->ndm_state;
> -
> -             fprintf(fp, " ");
> -
> -#define PRINT_FLAG(f) if (nud & NUD_##f) { \
> -     nud &= ~NUD_##f; fprintf(fp, #f "%s", nud ? "," : ""); }
> -             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
> +     if (r->ndm_flags & NTF_ROUTER)
> +             print_null(PRINT_ANY, "router", " %s", "router");
> +
> +     if (r->ndm_flags & NTF_PROXY)
> +             print_null(PRINT_ANY, "proxy", " %s", "proxy");
> +
> +     if (show_stats) {
> +             if (tb[NDA_CACHEINFO])
> +                     print_cacheinfo(RTA_DATA(tb[NDA_CACHEINFO]));
> +
> +             if (tb[NDA_PROBES]) {
> +                     __u32 p = rta_getattr_u32(tb[NDA_PROBES]);
> +
> +                     print_uint(PRINT_ANY, "probes",
> +                                      " probes %u", p);

alignment on the above as well.

Reply via email to