ip: multicast commands JSON
Subsystems (2)
cover ip: multicast commands JSON
From: Stephen Hemminger <[email protected]>
Some more JSON support and report better error if kernel is configured without multicast.
Stephen Hemminger (3):
ipmaddr: json and color support
ipmroute: convert to output JSON
ipmroute: better error message if no kernel mroute
ip/ipmaddr.c | 69 ++++++++++++++++++++++++-------------- ip/ipmroute.c | 106 +++++++++++++++++++++++++++++++++++++++------------------- 2 files changed, 114 insertions(+), 61 deletions(-)
Signature · 1 line
2.16.1
PATCH 1/3 ipmaddr: json and color support
From: Stephen Hemminger <[email protected]>
Support printing mulitcast addresses in json and color mode. Output format is unchanged for normal use.
--- ip/ipmaddr.c | 69 +++++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 43 insertions(+), 26 deletions(-)
ip/ipmaddr.c +43 -26
@@ -28,6 +28,7 @@#include "rt_names.h" #include "utils.h" #include "ip_common.h" +#include "json_print.h" static struct { char *dev;
@@ -193,50 +194,66 @@ static void read_igmp6(struct ma_info **result_p)static void print_maddr (FILE *fp,struct ma_info *list) { -fprintf (fp,"\t" ); +print_string (PRINT_FP ,NULL ,"\t" ,NULL ); +open_json_object (NULL );if (list->addr.family ==AF_PACKET ) {SPRINT_BUF (b1); -fprintf (fp,"link %s" ,ll_addr_n2a ((unsigned char *)list->addr.data, - list->addr.bytelen,0 , - b1,sizeof (b1))); + +print_string (PRINT_FP ,NULL ,"link " ,NULL ); +print_color_string (PRINT_ANY ,COLOR_MAC ,"link" ,"%s" , +ll_addr_n2a ((void *)list->addr.data, list->addr.bytelen, +0 , b1,sizeof (b1))); }else { -switch (list->addr.family) { -case AF_INET : -fprintf (fp,"inet " ); -break ; -case AF_INET6 : -fprintf (fp,"inet6 " ); -break ; -default : -fprintf (fp,"family %d " , list->addr.family); -break ; - } -fprintf (fp,"%s" , -format_host (list->addr.family, --1 , list->addr.data)); +print_string (PRINT_ANY ,"family" ,"%-5s " , +family_name (list->addr.family)); +print_color_string (PRINT_ANY ,ifa_family_color (list->addr.family), +"address" ,"%s" , +format_host (list->addr.family, +-1 , list->addr.data)); } +if (list->users !=1 ) -fprintf (fp," users %d" , list->users); +print_uint (PRINT_ANY ,"users" ," users %u" , list->users); +if (list->features) -fprintf (fp," %s" , list->features); -fprintf (fp,"\n" ); +print_string (PRINT_ANY ,"features" ," %s" , list->features); + +print_string (PRINT_FP ,NULL ,"\n" ,NULL ); +close_json_object (); }static void print_mlist (FILE *fp,struct ma_info *list) {int cur_index =0 ; +new_json_obj (json);for (; list; list = list->next) { -if (oneline) { - cur_index = list->index; -fprintf (fp,"%d:\t%s%s" , cur_index, list->name, _SL_); - }else if (cur_index != list->index) { + +if (list->index != cur_index || oneline) { +if (cur_index) { +close_json_array (PRINT_JSON ,NULL ); +close_json_object (); + } +open_json_object (NULL ); + +print_uint (PRINT_ANY ,"ifindex" ,"%d:" , list->index); +print_color_string (PRINT_ANY ,COLOR_IFNAME , +"ifname" ,"\t%s" , list->name); +print_string (PRINT_FP ,NULL ,"%s" , _SL_); cur_index = list->index; -fprintf (fp,"%d:\t%s\n" , cur_index, list->name); + +open_json_array (PRINT_JSON ,"maddr" ); } +print_maddr (fp, list); } +if (cur_index) { +close_json_array (PRINT_JSON ,NULL ); +close_json_object (); + } + +delete_json_obj (); }static int multiaddr_list (int argc,char **argv)
Signature · 1 line
2.16.1
PATCH 2/3 ipmroute: convert to output JSON
In reply to Stephen HemmingerFrom: Stephen Hemminger <[email protected]>
Should be no change for non-json case except putting color on address if desired.
--- ip/ipmroute.c | 99 ++++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 67 insertions(+), 32 deletions(-)
ip/ipmroute.c +67 -32
@@ -29,6 +29,7 @@#include <rt_names.h> #include "utils.h" #include "ip_common.h" +#include "json_print.h" static void usage (void ) __attribute__((noreturn));
@@ -53,13 +54,12 @@ struct rtfilter {int print_mroute (const struct sockaddr_nl *who,struct nlmsghdr *n,void *arg) { -FILE *fp = (FILE *)arg;struct rtmsg *r =NLMSG_DATA (n);int len = n->nlmsg_len;struct rtattr *tb[RTA_MAX +1 ]; -char obuf[256 ]; - +const char *src, *dst;SPRINT_BUF (b1); +SPRINT_BUF (b2);__u32 table;int iif =0 ;int family;
@@ -103,30 +103,44 @@ int print_mroute(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) family =get_real_family (r->rtm_type, r->rtm_family); +open_json_object (NULL );if (n->nlmsg_type ==RTM_DELROUTE ) -fprintf (fp,"Deleted " ); +print_bool (PRINT_ANY ,"deleted" ,"Deleted " , true);if (tb[RTA_SRC ]) - len =snprintf (obuf,sizeof (obuf), -"(%s, " ,rt_addr_n2a_rta (family, tb[RTA_SRC ])); + src =rt_addr_n2a_r (family,RTA_PAYLOAD (tb[RTA_SRC ]), +RTA_DATA (tb[RTA_SRC ]), b1,sizeof (b1));else - len =sprintf (obuf,"(unknown, " ); + src ="unknown" ; +if (tb[RTA_DST ]) -snprintf (obuf + len,sizeof (obuf) - len, -"%s)" ,rt_addr_n2a_rta (family, tb[RTA_DST ])); + dst =rt_addr_n2a_r (family,RTA_PAYLOAD (tb[RTA_DST ]), +RTA_DATA (tb[RTA_DST ]), b2,sizeof (b2));else -snprintf (obuf + len,sizeof (obuf) - len,"unknown) " ); + dst ="unknown" ; + +if (is_json_context ()) { +print_string (PRINT_JSON ,"src" ,NULL , src); +print_string (PRINT_JSON ,"dst" ,NULL , dst); + }else { +char obuf[256 ]; + +snprintf (obuf,sizeof (obuf),"(%s,%s)" , src, dst); +print_string (PRINT_FP ,NULL , +"%-32s Iif: " , obuf); + } -fprintf (fp,"%-32s Iif: " , obuf);if (iif) -fprintf (fp,"%-10s " ,ll_index_to_name (iif)); +print_color_string (PRINT_ANY ,COLOR_IFNAME , +"iif" ,"%-10s " ,ll_index_to_name (iif));else -fprintf (fp,"unresolved " ); +print_string (PRINT_ANY ,"iif" ,"%s " ,"unresolved" );if (tb[RTA_MULTIPATH ]) {struct rtnexthop *nh =RTA_DATA (tb[RTA_MULTIPATH ]);int first =1 ; +open_json_array (PRINT_JSON ,"multipath" ); len =RTA_PAYLOAD (tb[RTA_MULTIPATH ]);for (;;) {
@@ -135,47 +149,65 @@ int print_mroute(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)if (nh->rtnh_len > len)break ; +open_json_object (NULL );if (first) { -fprintf (fp,"Oifs: " ); +print_string (PRINT_FP ,NULL ,"Oifs: " ,NULL ); first =0 ; } -fprintf (fp,"%s" ,ll_index_to_name (nh->rtnh_ifindex)); + +print_color_string (PRINT_ANY ,COLOR_IFNAME , +"oif" ,"%s" ,ll_index_to_name (nh->rtnh_ifindex)); +if (nh->rtnh_hops >1 ) -fprintf (fp,"(ttl %d) " , nh->rtnh_hops); +print_uint (PRINT_ANY , +"ttl" ,"(ttl %u) " , nh->rtnh_hops);else -fprintf (fp," " ); +print_string (PRINT_FP ,NULL ," " ,NULL ); + +close_json_object (); len -=NLMSG_ALIGN (nh->rtnh_len); nh =RTNH_NEXT (nh); } +close_json_array (PRINT_JSON ,NULL ); } -fprintf (fp," State: %s" , - r->rtm_flags &RTNH_F_UNRESOLVED ?"unresolved" :"resolved" ); + +print_string (PRINT_ANY ,"state" ," State: %s" , + (r->rtm_flags &RTNH_F_UNRESOLVED ) ?"unresolved" :"resolved" ); +if (r->rtm_flags &RTNH_F_OFFLOAD ) -fprintf (fp," offload" ); +print_null (PRINT_ANY ,"offload" ," offload" ,NULL ); +if (show_stats && tb[RTA_MFC_STATS ]) {struct rta_mfc_stats *mfcs =RTA_DATA (tb[RTA_MFC_STATS ]); -fprintf (fp,"%s %" PRIu64" packets, %" PRIu64" bytes" , _SL_, - (uint64_t )mfcs->mfcs_packets, - (uint64_t )mfcs->mfcs_bytes); +print_string (PRINT_FP ,NULL ,"%s" , _SL_); +print_uint (PRINT_ANY ,"packets" ," %" PRIu64" packets," , + mfcs->mfcs_packets); +print_uint (PRINT_ANY ,"bytes" ," %" PRIu64" bytes" , mfcs->mfcs_bytes); +if (mfcs->mfcs_wrong_if) -fprintf (fp,", %" PRIu64" arrived on wrong iif." , - (uint64_t )mfcs->mfcs_wrong_if); +print_uint (PRINT_ANY ,"wrong_if" , +", %" PRIu64" arrived on wrong iif." , + mfcs->mfcs_wrong_if); } +if (show_stats && tb[RTA_EXPIRES ]) {struct timeval tv; +double age;__jiffies_to_tv (&tv,rta_getattr_u64 (tb[RTA_EXPIRES ])); -fprintf (fp,", Age %4i.%.2i" , (int )tv.tv_sec, - (int )tv.tv_usec/10000 ); + age = tv.tv_sec; + age += tv.tv_usec /1000000. ; +print_float (PRINT_ANY ,"expires" , +", Age %.2f" , age); }if (table && (table !=RT_TABLE_MAIN || show_details >0 ) && !filter.tb) -fprintf (fp," Table: %s" , -rtnl_rttable_n2a (table, b1,sizeof (b1))); +print_string (PRINT_ANY ,"table" ," Table: %s" , +rtnl_rttable_n2a (table, b1,sizeof (b1))); -fprintf (fp,"\n" ); -fflush (fp); +print_string (PRINT_FP ,NULL ,"\n" ,NULL ); +close_json_object ();return 0 ; }
@@ -256,12 +288,15 @@ static int mroute_list(int argc, char **argv)return 1 ; } +new_json_obj (json);if (rtnl_dump_filter (&rth, print_mroute, stdout) <0 ) { +delete_json_obj ();fprintf (stderr,"Dump terminated\n" );exit (1 ); } +delete_json_obj (); -exit (0 ); +return 0 ; }int do_multiroute (int argc,char **argv)
Signature · 1 line
2.16.1
PATCH 3/3 ipmroute: better error message if no kernel mroute
In reply to Stephen HemmingerFrom: Stephen Hemminger <[email protected]>
If kernel does not support the IP multicast address family, then it will report all routes (PF_UNSPEC).
Give the user a better error message and abort the command.
--- ip/ipmroute.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
ip/ipmroute.c +4 -3
@@ -75,10 +75,11 @@ int print_mroute(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)fprintf (stderr,"BUG: wrong nlmsg len %d\n" , len);return -1 ; } +if (r->rtm_type !=RTN_MULTICAST ) { -fprintf (stderr,"Not a multicast route (type: %s)\n" , -rtnl_rtntype_n2a (r->rtm_type, b1,sizeof (b1))); -return 0 ; +fprintf (stderr, +"Non multicast route received, kernel does support IP multicast?\n" ); +return -1 ; }parse_rtattr (tb,RTA_MAX ,RTM_RTA (r), len);
Signature · 1 line
2.16.1
David Ahern
AppliedQuoted 10 lines · Stephen Hemminger
From: Stephen Hemminger <[email protected]>
Some more JSON support and report better error if kernel is configured without multicast.
Stephen Hemminger (3):
ipmaddr: json and color support
ipmroute: convert to output JSON
ipmroute: better error message if no kernel mroute
applied to iproute2-next