Re: [PATCH iproute2-next 3/7] ip: add json support to ip rule
On Tue, 6 Mar 2018 09:51:29 -0700 David Ahernwrote: > NULL for detached value seems weird. > [ { > "priority": 998, > "src": "all", > "iif": "dummy2", > "iif_detached": null, > "table": "1" > }, > > Is that normal for json for fields that only exist when a value is true? null is the best way to indicate a value with presence having a meaning.
Re: [PATCH iproute2-next 3/7] ip: add json support to ip rule
On 3/5/18 8:04 PM, Stephen Hemminger wrote: > @@ -202,50 +202,66 @@ int print_rule(const struct sockaddr_nl *who, struct > nlmsghdr *n, void *arg) > if (!filter_nlmsg(n, tb, host_len)) > return 0; > > + open_json_object(NULL); > if (n->nlmsg_type == RTM_DELRULE) > - fprintf(fp, "Deleted "); > + print_bool(PRINT_ANY, "deleted", "Deleted ", true); > > if (tb[FRA_PRIORITY]) > - fprintf(fp, "%u:\t", > - rta_getattr_u32(tb[FRA_PRIORITY])); > - else > - fprintf(fp, "0:\t"); > + prio = rta_getattr_u32(tb[FRA_PRIORITY]); > + > + print_uint(PRINT_ANY, "priority", > +"%u:\t", prio); This one has a lot of instances where the print_* can be put on one line. > > if (frh->flags & FIB_RULE_INVERT) > - fprintf(fp, "not "); > + print_null(PRINT_ANY, "not", "not ", NULL); > + > + if (!is_json_context()) > + fprintf(fp, "from "); > > if (tb[FRA_SRC]) { > - if (frh->src_len != host_len) { > - fprintf(fp, "from %s/%u ", > - rt_addr_n2a_rta(frh->family, tb[FRA_SRC]), > - frh->src_len); > - } else { > - fprintf(fp, "from %s ", > - format_host_rta(frh->family, tb[FRA_SRC])); > - } > + const char *src > + = rt_addr_n2a_rta(frh->family, tb[FRA_SRC]); > + > + print_color_string(PRINT_ANY, > +ifa_family_color(frh->family), > +"src", "%s", src); > + if (frh->src_len != host_len) > + print_uint(PRINT_ANY, "srclen", > +"/%u", frh->src_len); > } else if (frh->src_len) { > - fprintf(fp, "from 0/%d ", frh->src_len); > + print_string(PRINT_ANY, > + "src", "%s", "0"); > + print_uint(PRINT_ANY, > +"srclen", "/%u", frh->src_len); > } else { > - fprintf(fp, "from all "); > + print_string(PRINT_ANY, > + "src", "%s", "all"); > } > > + if (!is_json_context()) > + fprintf(fp, " to "); > + > if (tb[FRA_DST]) { > - if (frh->dst_len != host_len) { > - fprintf(fp, "to %s/%u ", > - rt_addr_n2a_rta(frh->family, tb[FRA_DST]), > - frh->dst_len); > - } else { > - fprintf(fp, "to %s ", > - format_host_rta(frh->family, tb[FRA_DST])); > - } > + const char *dst > + = rt_addr_n2a_rta(frh->family, tb[FRA_DST]); > + > + print_color_string(PRINT_ANY, > +ifa_family_color(frh->family), > +"dst", "%s", dst); > + if (frh->dst_len != host_len) > + print_uint(PRINT_ANY, "dstlen", > +"/%u ", frh->dst_len); > } else if (frh->dst_len) { > - fprintf(fp, "to 0/%d ", frh->dst_len); > + print_string(PRINT_ANY, > + "dst", "%s", "0"); > + print_uint(PRINT_ANY, > +"dstlen", "/%u ", frh->dst_len); > } > > if (frh->tos) { > - SPRINT_BUF(b1); > - fprintf(fp, "tos %s ", > - rtnl_dsfield_n2a(frh->tos, b1, sizeof(b1))); > + print_string(PRINT_ANY, "tos", > + "tos %s ", > + rtnl_dsfield_n2a(frh->tos, b1, sizeof(b1))); > } > > if (tb[FRA_FWMARK] || tb[FRA_FWMASK]) { > @@ -255,53 +271,82 @@ int print_rule(const struct sockaddr_nl *who, struct > nlmsghdr *n, void *arg) > mark = rta_getattr_u32(tb[FRA_FWMARK]); > > if (tb[FRA_FWMASK] && > - (mask = rta_getattr_u32(tb[FRA_FWMASK])) != 0x) > - fprintf(fp, "fwmark 0x%x/0x%x ", mark, mask); > - else > - fprintf(fp, "fwmark 0x%x ", mark); > + (mask = rta_getattr_u32(tb[FRA_FWMASK])) != 0x) { > + print_0xhex(PRINT_ANY, "fwmark", > + "fwmark 0x%x", mark); > + print_0xhex(PRINT_ANY, "fwmask", > + "/0x%x ", mask); > + } else { > + print_0xhex(PRINT_ANY, "fwmark", > + "fwmark 0x%x ", mark); > + } > } > > if (tb[FRA_IFNAME]) { > - fprintf(fp, "iif %s ", rta_getattr_str(tb[FRA_IFNAME])); > + if (!is_json_context()) > + fprintf(fp, "iif
[PATCH iproute2-next 3/7] ip: add json support to ip rule
From: Stephen HemmingerMore JSON and colorizing. Signed-off-by: Stephen Hemminger --- ip/iprule.c | 203 ++-- 1 file changed, 130 insertions(+), 73 deletions(-) diff --git a/ip/iprule.c b/ip/iprule.c index 6fdc9b5efa00..ab1e0c15f877 100644 --- a/ip/iprule.c +++ b/ip/iprule.c @@ -26,6 +26,7 @@ #include "rt_names.h" #include "utils.h" #include "ip_common.h" +#include "json_print.h" enum list_action { IPRULE_LIST, @@ -179,13 +180,12 @@ static bool filter_nlmsg(struct nlmsghdr *n, struct rtattr **tb, int host_len) int print_rule(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) { - FILE *fp = (FILE *)arg; + FILE *fp = arg; struct fib_rule_hdr *frh = NLMSG_DATA(n); int len = n->nlmsg_len; int host_len = -1; - __u32 table; + __u32 table, prio = 0; struct rtattr *tb[FRA_MAX+1]; - SPRINT_BUF(b1); if (n->nlmsg_type != RTM_NEWRULE && n->nlmsg_type != RTM_DELRULE) @@ -202,50 +202,66 @@ int print_rule(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) if (!filter_nlmsg(n, tb, host_len)) return 0; + open_json_object(NULL); if (n->nlmsg_type == RTM_DELRULE) - fprintf(fp, "Deleted "); + print_bool(PRINT_ANY, "deleted", "Deleted ", true); if (tb[FRA_PRIORITY]) - fprintf(fp, "%u:\t", - rta_getattr_u32(tb[FRA_PRIORITY])); - else - fprintf(fp, "0:\t"); + prio = rta_getattr_u32(tb[FRA_PRIORITY]); + + print_uint(PRINT_ANY, "priority", + "%u:\t", prio); if (frh->flags & FIB_RULE_INVERT) - fprintf(fp, "not "); + print_null(PRINT_ANY, "not", "not ", NULL); + + if (!is_json_context()) + fprintf(fp, "from "); if (tb[FRA_SRC]) { - if (frh->src_len != host_len) { - fprintf(fp, "from %s/%u ", - rt_addr_n2a_rta(frh->family, tb[FRA_SRC]), - frh->src_len); - } else { - fprintf(fp, "from %s ", - format_host_rta(frh->family, tb[FRA_SRC])); - } + const char *src + = rt_addr_n2a_rta(frh->family, tb[FRA_SRC]); + + print_color_string(PRINT_ANY, + ifa_family_color(frh->family), + "src", "%s", src); + if (frh->src_len != host_len) + print_uint(PRINT_ANY, "srclen", + "/%u", frh->src_len); } else if (frh->src_len) { - fprintf(fp, "from 0/%d ", frh->src_len); + print_string(PRINT_ANY, +"src", "%s", "0"); + print_uint(PRINT_ANY, + "srclen", "/%u", frh->src_len); } else { - fprintf(fp, "from all "); + print_string(PRINT_ANY, +"src", "%s", "all"); } + if (!is_json_context()) + fprintf(fp, " to "); + if (tb[FRA_DST]) { - if (frh->dst_len != host_len) { - fprintf(fp, "to %s/%u ", - rt_addr_n2a_rta(frh->family, tb[FRA_DST]), - frh->dst_len); - } else { - fprintf(fp, "to %s ", - format_host_rta(frh->family, tb[FRA_DST])); - } + const char *dst + = rt_addr_n2a_rta(frh->family, tb[FRA_DST]); + + print_color_string(PRINT_ANY, + ifa_family_color(frh->family), + "dst", "%s", dst); + if (frh->dst_len != host_len) + print_uint(PRINT_ANY, "dstlen", + "/%u ", frh->dst_len); } else if (frh->dst_len) { - fprintf(fp, "to 0/%d ", frh->dst_len); + print_string(PRINT_ANY, +"dst", "%s", "0"); + print_uint(PRINT_ANY, + "dstlen", "/%u ", frh->dst_len); } if (frh->tos) { - SPRINT_BUF(b1); - fprintf(fp, "tos %s ", - rtnl_dsfield_n2a(frh->tos, b1, sizeof(b1))); + print_string(PRINT_ANY, "tos", +"tos %s ", +rtnl_dsfield_n2a(frh->tos, b1, sizeof(b1))); } if (tb[FRA_FWMARK] || tb[FRA_FWMASK]) { @@ -255,53 +271,82 @@ int print_rule(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) mark =