From 3c1e087b05ebd2ade25bb4804549387fbd14f67a Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 6 Mar 2018 13:07:12 -0800 Subject: [PATCH] ipntable: add json support Add JSON (and limited color) to ip neighbor table parameter output. Signed-off-by: Stephen Hemminger Signed-off-by: David Ahern --- ip/ipntable.c | 404 ++++++++++++++++++++++++++------------------------ 1 file changed, 214 insertions(+), 190 deletions(-) diff --git a/ip/ipntable.c b/ip/ipntable.c index 2f72c989..92024864 100644 --- a/ip/ipntable.c +++ b/ip/ipntable.c @@ -31,6 +31,7 @@ #include "utils.h" #include "ip_common.h" +#include "json_print.h" static struct { @@ -338,7 +339,191 @@ static const char *ntable_strtime_delta(__u32 msec) return str; } -static int print_ntable(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) +static void print_ndtconfig(const struct ndt_config *ndtc) +{ + + print_uint(PRINT_ANY, "key_length", + " config key_len %u ", ndtc->ndtc_key_len); + print_uint(PRINT_ANY, "entry_size", + "entry_size %u ", ndtc->ndtc_entry_size); + print_uint(PRINT_ANY, "entries", "entries %u ", ndtc->ndtc_entries); + + print_string(PRINT_FP, NULL, "%s", _SL_); + + print_string(PRINT_ANY, "last_flush", + " last_flush %s ", + ntable_strtime_delta(ndtc->ndtc_last_flush)); + print_string(PRINT_ANY, "last_rand", + "last_rand %s ", + ntable_strtime_delta(ndtc->ndtc_last_rand)); + + print_string(PRINT_FP, NULL, "%s", _SL_); + + print_uint(PRINT_ANY, "hash_rnd", + " hash_rnd %u ", ndtc->ndtc_hash_rnd); + print_0xhex(PRINT_ANY, "hash_mask", + "hash_mask %08x ", ndtc->ndtc_hash_mask); + + print_uint(PRINT_ANY, "hash_chain_gc", + "hash_chain_gc %u ", ndtc->ndtc_hash_chain_gc); + print_uint(PRINT_ANY, "proxy_qlen", + "proxy_qlen %u ", ndtc->ndtc_proxy_qlen); + + print_string(PRINT_FP, NULL, "%s", _SL_); +} + +static void print_ndtparams(struct rtattr *tpb[]) +{ + + if (tpb[NDTPA_IFINDEX]) { + __u32 ifindex = rta_getattr_u32(tpb[NDTPA_IFINDEX]); + + print_string(PRINT_FP, NULL, " dev ", NULL); + print_color_string(PRINT_ANY, COLOR_IFNAME, + "dev", "%s ", ll_index_to_name(ifindex)); + print_string(PRINT_FP, NULL, "%s", _SL_); + } + + print_string(PRINT_FP, NULL, " ", NULL); + if (tpb[NDTPA_REFCNT]) { + __u32 refcnt = rta_getattr_u32(tpb[NDTPA_REFCNT]); + + print_uint(PRINT_ANY, "refcnt", "refcnt %u ", refcnt); + } + + if (tpb[NDTPA_REACHABLE_TIME]) { + __u64 reachable = rta_getattr_u64(tpb[NDTPA_REACHABLE_TIME]); + + print_uint(PRINT_ANY, "reachable", + "reachable %llu ", reachable); + } + + if (tpb[NDTPA_BASE_REACHABLE_TIME]) { + __u64 breachable + = rta_getattr_u64(tpb[NDTPA_BASE_REACHABLE_TIME]); + + print_uint(PRINT_ANY, "base_reachable", + "base_reachable %llu ", breachable); + } + + if (tpb[NDTPA_RETRANS_TIME]) { + __u64 retrans = rta_getattr_u64(tpb[NDTPA_RETRANS_TIME]); + + print_uint(PRINT_ANY, "retrans", "retrans %llu ", retrans); + } + + print_string(PRINT_FP, NULL, "%s ", _SL_); + + if (tpb[NDTPA_GC_STALETIME]) { + __u64 gc_stale = rta_getattr_u64(tpb[NDTPA_GC_STALETIME]); + + print_uint(PRINT_ANY, "gc_stale", "gc_stale %llu ", gc_stale); + } + + if (tpb[NDTPA_DELAY_PROBE_TIME]) { + __u64 delay_probe + = rta_getattr_u64(tpb[NDTPA_DELAY_PROBE_TIME]); + + print_uint(PRINT_ANY, "delay_probe", + "delay_probe %llu ", delay_probe); + } + + if (tpb[NDTPA_QUEUE_LEN]) { + __u32 queue = rta_getattr_u32(tpb[NDTPA_QUEUE_LEN]); + + print_uint(PRINT_ANY, "queue", "queue %u ", queue); + } + + print_string(PRINT_FP, NULL, "%s ", _SL_); + + if (tpb[NDTPA_APP_PROBES]) { + __u32 aprobe = rta_getattr_u32(tpb[NDTPA_APP_PROBES]); + + print_uint(PRINT_ANY, "app_probes", "app_probes %u ", aprobe); + } + + if (tpb[NDTPA_UCAST_PROBES]) { + __u32 uprobe = rta_getattr_u32(tpb[NDTPA_UCAST_PROBES]); + + print_uint(PRINT_ANY, "ucast_probes", + "ucast_probes %u ", uprobe); + } + + if (tpb[NDTPA_MCAST_PROBES]) { + __u32 mprobe = rta_getattr_u32(tpb[NDTPA_MCAST_PROBES]); + + print_uint(PRINT_ANY, "mcast_probes", + "mcast_probes %u ", mprobe); + } + + print_string(PRINT_FP, NULL, "%s ", _SL_); + + if (tpb[NDTPA_ANYCAST_DELAY]) { + __u64 anycast_delay = rta_getattr_u64(tpb[NDTPA_ANYCAST_DELAY]); + + print_uint(PRINT_ANY, "anycast_delay", + "anycast_delay %llu ", anycast_delay); + } + + if (tpb[NDTPA_PROXY_DELAY]) { + __u64 proxy_delay = rta_getattr_u64(tpb[NDTPA_PROXY_DELAY]); + + print_uint(PRINT_ANY, "proxy_delay", + "proxy_delay %llu ", proxy_delay); + } + + if (tpb[NDTPA_PROXY_QLEN]) { + __u32 pqueue = rta_getattr_u32(tpb[NDTPA_PROXY_QLEN]); + + print_uint(PRINT_ANY, "proxy_queue", "proxy_queue %u ", pqueue); + } + + if (tpb[NDTPA_LOCKTIME]) { + __u64 locktime = rta_getattr_u64(tpb[NDTPA_LOCKTIME]); + + print_uint(PRINT_ANY, "locktime", "locktime %llu ", locktime); + } + + print_string(PRINT_FP, NULL, "%s", _SL_); +} + +static void print_ndtstats(const struct ndt_stats *ndts) +{ + + print_string(PRINT_FP, NULL, " stats ", NULL); + + print_uint(PRINT_ANY, "allocs", "allocs %llu ", ndts->ndts_allocs); + print_uint(PRINT_ANY, "destroys", "destroys %llu ", + ndts->ndts_destroys); + print_uint(PRINT_ANY, "hash_grows", "hash_grows %llu ", + ndts->ndts_hash_grows); + + print_string(PRINT_FP, NULL, "%s ", _SL_); + + print_uint(PRINT_ANY, "res_failed", "res_failed %llu ", + ndts->ndts_res_failed); + print_uint(PRINT_ANY, "lookups", "lookups %llu ", ndts->ndts_lookups); + print_uint(PRINT_ANY, "hits", "hits %llu ", ndts->ndts_hits); + + print_string(PRINT_FP, NULL, "%s ", _SL_); + + print_uint(PRINT_ANY, "rcv_probes_mcast", "rcv_probes_mcast %llu ", + ndts->ndts_rcv_probes_mcast); + print_uint(PRINT_ANY, "rcv_probes_ucast", "rcv_probes_ucast %llu ", + ndts->ndts_rcv_probes_ucast); + + print_string(PRINT_FP, NULL, "%s ", _SL_); + + print_uint(PRINT_ANY, "periodic_gc_runs", "periodic_gc_runs %llu ", + ndts->ndts_periodic_gc_runs); + print_uint(PRINT_ANY, "forced_gc_runs", "forced_gc_runs %llu ", + ndts->ndts_forced_gc_runs); + + print_string(PRINT_FP, NULL, "%s", _SL_); +} + +static int print_ntable(const struct sockaddr_nl *who, + struct nlmsghdr *n, void *arg) { FILE *fp = (FILE *)arg; struct ndtmsg *ndtm = NLMSG_DATA(n); @@ -370,6 +555,7 @@ static int print_ntable(const struct sockaddr_nl *who, struct nlmsghdr *n, void if (filter.name && strcmp(filter.name, name)) return 0; } + if (tb[NDTA_PARMS]) { parse_rtattr(tpb, NDTPA_MAX, RTA_DATA(tb[NDTA_PARMS]), RTA_PAYLOAD(tb[NDTA_PARMS])); @@ -385,227 +571,63 @@ static int print_ntable(const struct sockaddr_nl *who, struct nlmsghdr *n, void } } - if (ndtm->ndtm_family == AF_INET) - fprintf(fp, "inet "); - else if (ndtm->ndtm_family == AF_INET6) - fprintf(fp, "inet6 "); - else if (ndtm->ndtm_family == AF_DECnet) - fprintf(fp, "dnet "); - else - fprintf(fp, "(%d) ", ndtm->ndtm_family); + open_json_object(NULL); + print_string(PRINT_ANY, "family", + "%s ", family_name(ndtm->ndtm_family)); if (tb[NDTA_NAME]) { const char *name = rta_getattr_str(tb[NDTA_NAME]); - fprintf(fp, "%s ", name); + print_string(PRINT_ANY, "name", "%s ", name); } - fprintf(fp, "%s", _SL_); + print_string(PRINT_FP, NULL, "%s", _SL_); ret = (tb[NDTA_THRESH1] || tb[NDTA_THRESH2] || tb[NDTA_THRESH3] || tb[NDTA_GC_INTERVAL]); if (ret) - fprintf(fp, " "); + print_string(PRINT_FP, NULL, " ", NULL); if (tb[NDTA_THRESH1]) { __u32 thresh1 = rta_getattr_u32(tb[NDTA_THRESH1]); - fprintf(fp, "thresh1 %u ", thresh1); + print_uint(PRINT_ANY, "thresh1", "thresh1 %u ", thresh1); } + if (tb[NDTA_THRESH2]) { __u32 thresh2 = rta_getattr_u32(tb[NDTA_THRESH2]); - fprintf(fp, "thresh2 %u ", thresh2); + print_uint(PRINT_ANY, "thresh2", "thresh2 %u ", thresh2); } + if (tb[NDTA_THRESH3]) { __u32 thresh3 = rta_getattr_u32(tb[NDTA_THRESH3]); - fprintf(fp, "thresh3 %u ", thresh3); + print_uint(PRINT_ANY, "thresh3", "thresh3 %u ", thresh3); } - if (tb[NDTA_GC_INTERVAL]) { - unsigned long long gc_int = rta_getattr_u64(tb[NDTA_GC_INTERVAL]); - fprintf(fp, "gc_int %llu ", gc_int); + if (tb[NDTA_GC_INTERVAL]) { + __u64 gc_int = rta_getattr_u64(tb[NDTA_GC_INTERVAL]); + + print_uint(PRINT_ANY, "gc_interval", "gc_int %llu ", gc_int); } if (ret) - fprintf(fp, "%s", _SL_); + print_string(PRINT_FP, NULL, "%s", _SL_); - if (tb[NDTA_CONFIG] && show_stats) { - struct ndt_config *ndtc = RTA_DATA(tb[NDTA_CONFIG]); + if (tb[NDTA_CONFIG] && show_stats) + print_ndtconfig(RTA_DATA(tb[NDTA_CONFIG])); - fprintf(fp, " "); - fprintf(fp, "config "); + if (tb[NDTA_PARMS]) + print_ndtparams(tpb); - fprintf(fp, "key_len %u ", ndtc->ndtc_key_len); - fprintf(fp, "entry_size %u ", ndtc->ndtc_entry_size); - fprintf(fp, "entries %u ", ndtc->ndtc_entries); - - fprintf(fp, "%s", _SL_); - fprintf(fp, " "); - - fprintf(fp, "last_flush %s ", - ntable_strtime_delta(ndtc->ndtc_last_flush)); - fprintf(fp, "last_rand %s ", - ntable_strtime_delta(ndtc->ndtc_last_rand)); - - fprintf(fp, "%s", _SL_); - fprintf(fp, " "); - - fprintf(fp, "hash_rnd %u ", ndtc->ndtc_hash_rnd); - fprintf(fp, "hash_mask %08x ", ndtc->ndtc_hash_mask); - - fprintf(fp, "hash_chain_gc %u ", ndtc->ndtc_hash_chain_gc); - fprintf(fp, "proxy_qlen %u ", ndtc->ndtc_proxy_qlen); - - fprintf(fp, "%s", _SL_); - } - - if (tb[NDTA_PARMS]) { - if (tpb[NDTPA_IFINDEX]) { - __u32 ifindex = rta_getattr_u32(tpb[NDTPA_IFINDEX]); - - fprintf(fp, " "); - fprintf(fp, "dev %s ", ll_index_to_name(ifindex)); - fprintf(fp, "%s", _SL_); - } - - fprintf(fp, " "); - - if (tpb[NDTPA_REFCNT]) { - __u32 refcnt = rta_getattr_u32(tpb[NDTPA_REFCNT]); - - fprintf(fp, "refcnt %u ", refcnt); - } - if (tpb[NDTPA_REACHABLE_TIME]) { - unsigned long long reachable = rta_getattr_u64(tpb[NDTPA_REACHABLE_TIME]); - - fprintf(fp, "reachable %llu ", reachable); - } - if (tpb[NDTPA_BASE_REACHABLE_TIME]) { - unsigned long long breachable = rta_getattr_u64(tpb[NDTPA_BASE_REACHABLE_TIME]); - - fprintf(fp, "base_reachable %llu ", breachable); - } - if (tpb[NDTPA_RETRANS_TIME]) { - unsigned long long retrans = rta_getattr_u64(tpb[NDTPA_RETRANS_TIME]); - - fprintf(fp, "retrans %llu ", retrans); - } - - fprintf(fp, "%s", _SL_); - - fprintf(fp, " "); - - if (tpb[NDTPA_GC_STALETIME]) { - unsigned long long gc_stale = rta_getattr_u64(tpb[NDTPA_GC_STALETIME]); - - fprintf(fp, "gc_stale %llu ", gc_stale); - } - if (tpb[NDTPA_DELAY_PROBE_TIME]) { - unsigned long long delay_probe = rta_getattr_u64(tpb[NDTPA_DELAY_PROBE_TIME]); - - fprintf(fp, "delay_probe %llu ", delay_probe); - } - if (tpb[NDTPA_QUEUE_LEN]) { - __u32 queue = rta_getattr_u32(tpb[NDTPA_QUEUE_LEN]); - - fprintf(fp, "queue %u ", queue); - } - - fprintf(fp, "%s", _SL_); - - fprintf(fp, " "); - - if (tpb[NDTPA_APP_PROBES]) { - __u32 aprobe = rta_getattr_u32(tpb[NDTPA_APP_PROBES]); - - fprintf(fp, "app_probes %u ", aprobe); - } - if (tpb[NDTPA_UCAST_PROBES]) { - __u32 uprobe = rta_getattr_u32(tpb[NDTPA_UCAST_PROBES]); - - fprintf(fp, "ucast_probes %u ", uprobe); - } - if (tpb[NDTPA_MCAST_PROBES]) { - __u32 mprobe = rta_getattr_u32(tpb[NDTPA_MCAST_PROBES]); - - fprintf(fp, "mcast_probes %u ", mprobe); - } - - fprintf(fp, "%s", _SL_); - - fprintf(fp, " "); - - if (tpb[NDTPA_ANYCAST_DELAY]) { - unsigned long long anycast_delay = rta_getattr_u64(tpb[NDTPA_ANYCAST_DELAY]); - - fprintf(fp, "anycast_delay %llu ", anycast_delay); - } - if (tpb[NDTPA_PROXY_DELAY]) { - unsigned long long proxy_delay = rta_getattr_u64(tpb[NDTPA_PROXY_DELAY]); - - fprintf(fp, "proxy_delay %llu ", proxy_delay); - } - if (tpb[NDTPA_PROXY_QLEN]) { - __u32 pqueue = rta_getattr_u32(tpb[NDTPA_PROXY_QLEN]); - - fprintf(fp, "proxy_queue %u ", pqueue); - } - if (tpb[NDTPA_LOCKTIME]) { - unsigned long long locktime = rta_getattr_u64(tpb[NDTPA_LOCKTIME]); - - fprintf(fp, "locktime %llu ", locktime); - } - - fprintf(fp, "%s", _SL_); - } - - if (tb[NDTA_STATS] && show_stats) { - struct ndt_stats *ndts = RTA_DATA(tb[NDTA_STATS]); - - fprintf(fp, " "); - fprintf(fp, "stats "); - - fprintf(fp, "allocs %llu ", - (unsigned long long) ndts->ndts_allocs); - fprintf(fp, "destroys %llu ", - (unsigned long long) ndts->ndts_destroys); - fprintf(fp, "hash_grows %llu ", - (unsigned long long) ndts->ndts_hash_grows); - - fprintf(fp, "%s", _SL_); - fprintf(fp, " "); - - fprintf(fp, "res_failed %llu ", - (unsigned long long) ndts->ndts_res_failed); - fprintf(fp, "lookups %llu ", - (unsigned long long) ndts->ndts_lookups); - fprintf(fp, "hits %llu ", - (unsigned long long) ndts->ndts_hits); - - fprintf(fp, "%s", _SL_); - fprintf(fp, " "); - - fprintf(fp, "rcv_probes_mcast %llu ", - (unsigned long long) ndts->ndts_rcv_probes_mcast); - fprintf(fp, "rcv_probes_ucast %llu ", - (unsigned long long) ndts->ndts_rcv_probes_ucast); - - fprintf(fp, "%s", _SL_); - fprintf(fp, " "); - - fprintf(fp, "periodic_gc_runs %llu ", - (unsigned long long) ndts->ndts_periodic_gc_runs); - fprintf(fp, "forced_gc_runs %llu ", - (unsigned long long) ndts->ndts_forced_gc_runs); - - fprintf(fp, "%s", _SL_); - } - - fprintf(fp, "\n"); + if (tb[NDTA_STATS] && show_stats) + print_ndtstats(RTA_DATA(tb[NDTA_STATS])); + print_string(PRINT_FP, NULL, "\n", ""); + close_json_object(); fflush(fp); + return 0; } @@ -643,10 +665,12 @@ static int ipntable_show(int argc, char **argv) exit(1); } + new_json_obj(json); if (rtnl_dump_filter(&rth, print_ntable, stdout) < 0) { fprintf(stderr, "Dump terminated\n"); exit(1); } + delete_json_obj(); return 0; }