From: Hoang Le Date: Tue, 12 Jun 2018 02:32:29 +0000 (+0700) Subject: tipc: JSON support for tipc link printouts X-Git-Tag: v4.19.0~111 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a56e0db7e892e600278fab58b917032e8c3bba5c;p=thirdparty%2Fiproute2.git tipc: JSON support for tipc link printouts Add json output support for tipc link command Example output: $tipc -j -p link list [ { "broadcast-link": "up", "1.1.1:bridge-1.1.104:eth0": "up", "1.1.1:bridge-1.1.105:eth0": "up", "1.1.1:bridge-1.1.106:eth0": "up" } ] -------------------- $tipc -j -p link stat show link broadcast-link [ { "link": "broadcast-link", "window": 50, "rx packets": { "rx packets": 0, "fragments": 0, "fragmented": 0, "bundles": 0, "bundled": 0 }, "tx packets": { "tx packets": 0, "fragments": 0, "fragmented": 0, "bundles": 0, "bundled": 0 }, "rx naks": { "rx naks": 0, "defs": 0, "dups": 0 }, "tx naks": { "tx naks": 0, "acks": 0, "retrans": 0 }, "congestion link": 0, "send queue max": 0, "avg": 0 } ] v2: Replace variable 'json_flag' by 'json' declared in include/utils.h v3: Update manual page Acked-by: Jon Maloy Signed-off-by: Hoang Le Signed-off-by: David Ahern --- diff --git a/man/man8/tipc-link.8 b/man/man8/tipc-link.8 index fee283e5c..01afa1c3a 100644 --- a/man/man8/tipc-link.8 +++ b/man/man8/tipc-link.8 @@ -71,6 +71,16 @@ Show help about last valid command. For example will show link help and .B tipc --help will show general help. The position of the option in the string is irrelevant. + +.TP +.BR "\-j", " \-json" +Output results in JavaScript Object Notation (JSON). + +.TP +.BR "\-p", " \-pretty" +The default JSON format is compact and more efficient to parse but hard for most users to read. +This flag adds indentation for readability. + .SH DESCRIPTION .SS Link statistics diff --git a/tipc/link.c b/tipc/link.c index a2d7c0016..afd3e68d8 100644 --- a/tipc/link.c +++ b/tipc/link.c @@ -23,6 +23,11 @@ #include "msg.h" #include "link.h" #include "bearer.h" +#include "utils.h" + +#define PRIORITY_STR "priority" +#define TOLERANCE_STR "tolerance" +#define WINDOW_STR "window" static int link_list_cb(const struct nlmsghdr *nlh, void *data) { @@ -38,13 +43,14 @@ static int link_list_cb(const struct nlmsghdr *nlh, void *data) if (!attrs[TIPC_NLA_LINK_NAME]) return MNL_CB_ERROR; - printf("%s: ", mnl_attr_get_str(attrs[TIPC_NLA_LINK_NAME])); - + print_string(PRINT_FP, NULL, "%s: ", + mnl_attr_get_str(attrs[TIPC_NLA_LINK_NAME])); if (attrs[TIPC_NLA_LINK_UP]) - printf("up\n"); + print_string(PRINT_ANY, + mnl_attr_get_str(attrs[TIPC_NLA_LINK_NAME]),"%s\n", "up"); else - printf("down\n"); - + print_string(PRINT_ANY, + mnl_attr_get_str(attrs[TIPC_NLA_LINK_NAME]), "%s\n", "down"); return MNL_CB_OK; } @@ -52,6 +58,7 @@ static int cmd_link_list(struct nlmsghdr *nlh, const struct cmd *cmd, struct cmdl *cmdl, void *data) { char buf[MNL_SOCKET_BUFFER_SIZE]; + int err = 0; if (help_flag) { fprintf(stderr, "Usage: %s link list\n", cmdl->argv[0]); @@ -64,7 +71,12 @@ static int cmd_link_list(struct nlmsghdr *nlh, const struct cmd *cmd, return -1; } - return msg_dumpit(nlh, link_list_cb, NULL); + new_json_obj(json); + open_json_object(NULL); + err = msg_dumpit(nlh, link_list_cb, NULL); + close_json_object(); + delete_json_obj(); + return err; } static int link_get_cb(const struct nlmsghdr *nlh, void *data) @@ -87,8 +99,23 @@ static int link_get_cb(const struct nlmsghdr *nlh, void *data) if (!props[*prop]) return MNL_CB_ERROR; - printf("%u\n", mnl_attr_get_u32(props[*prop])); - + new_json_obj(json); + open_json_object(NULL); + switch (*prop) { + case TIPC_NLA_PROP_PRIO: + print_uint(PRINT_ANY, PRIORITY_STR, "%u\n", mnl_attr_get_u32(props[*prop])); + break; + case TIPC_NLA_PROP_TOL: + print_uint(PRINT_ANY, TOLERANCE_STR, "%u\n", mnl_attr_get_u32(props[*prop])); + break; + case TIPC_NLA_PROP_WIN: + print_uint(PRINT_ANY, WINDOW_STR, "%u\n", mnl_attr_get_u32(props[*prop])); + break; + default: + break; + } + close_json_object(); + delete_json_obj(); return MNL_CB_OK; } @@ -104,11 +131,11 @@ static int cmd_link_get_prop(struct nlmsghdr *nlh, const struct cmd *cmd, { NULL } }; - if (strcmp(cmd->cmd, "priority") == 0) + if (strcmp(cmd->cmd, PRIORITY_STR) == 0) prop = TIPC_NLA_PROP_PRIO; - else if ((strcmp(cmd->cmd, "tolerance") == 0)) + else if ((strcmp(cmd->cmd, TOLERANCE_STR) == 0)) prop = TIPC_NLA_PROP_TOL; - else if ((strcmp(cmd->cmd, "window") == 0)) + else if ((strcmp(cmd->cmd, WINDOW_STR) == 0)) prop = TIPC_NLA_PROP_WIN; else return -EINVAL; @@ -153,9 +180,9 @@ static int cmd_link_get(struct nlmsghdr *nlh, const struct cmd *cmd, struct cmdl *cmdl, void *data) { const struct cmd cmds[] = { - { "priority", cmd_link_get_prop, cmd_link_get_help }, - { "tolerance", cmd_link_get_prop, cmd_link_get_help }, - { "window", cmd_link_get_prop, cmd_link_get_help }, + { PRIORITY_STR, cmd_link_get_prop, cmd_link_get_help }, + { TOLERANCE_STR, cmd_link_get_prop, cmd_link_get_help }, + { WINDOW_STR, cmd_link_get_prop, cmd_link_get_help }, { NULL } }; @@ -214,109 +241,178 @@ static uint32_t perc(uint32_t count, uint32_t total) return (count * 100 + (total / 2)) / total; } -static int _show_link_stat(struct nlattr *attrs[], struct nlattr *prop[], - struct nlattr *stats[]) +static int _show_link_stat(const char *name, struct nlattr *attrs[], + struct nlattr *prop[], struct nlattr *stats[]) { uint32_t proft; + open_json_object(NULL); + + print_string(PRINT_ANY, "link", "\nLink <%s>\n", name); + print_string(PRINT_JSON, "state", "", NULL); + open_json_array(PRINT_JSON, NULL); if (attrs[TIPC_NLA_LINK_ACTIVE]) - printf(" ACTIVE"); + print_string(PRINT_ANY, NULL, " %s", "ACTIVE"); else if (attrs[TIPC_NLA_LINK_UP]) - printf(" STANDBY"); + print_string(PRINT_ANY, NULL, " %s", "STANDBY"); else - printf(" DEFUNCT"); - - printf(" MTU:%u Priority:%u Tolerance:%u ms Window:%u packets\n", - mnl_attr_get_u32(attrs[TIPC_NLA_LINK_MTU]), - mnl_attr_get_u32(prop[TIPC_NLA_PROP_PRIO]), - mnl_attr_get_u32(prop[TIPC_NLA_PROP_TOL]), - mnl_attr_get_u32(prop[TIPC_NLA_PROP_WIN])); - - printf(" RX packets:%u fragments:%u/%u bundles:%u/%u\n", - mnl_attr_get_u32(attrs[TIPC_NLA_LINK_RX]) - - mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_INFO]), - mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_FRAGMENTS]), - mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_FRAGMENTED]), - mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_BUNDLES]), - mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_BUNDLED])); - - printf(" TX packets:%u fragments:%u/%u bundles:%u/%u\n", - mnl_attr_get_u32(attrs[TIPC_NLA_LINK_TX]) - - mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_INFO]), - mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_FRAGMENTS]), - mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_FRAGMENTED]), - mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_BUNDLES]), - mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_BUNDLED])); + print_string(PRINT_ANY, NULL, " %s", "DEFUNCT"); + close_json_array(PRINT_JSON, NULL); + + print_uint(PRINT_ANY, "mtu", " MTU:%u", + mnl_attr_get_u32(attrs[TIPC_NLA_LINK_MTU])); + print_uint(PRINT_ANY, PRIORITY_STR, " Priority:%u", + mnl_attr_get_u32(prop[TIPC_NLA_PROP_PRIO])); + print_uint(PRINT_ANY, TOLERANCE_STR, " Tolerance:%u ms", + mnl_attr_get_u32(prop[TIPC_NLA_PROP_TOL])); + print_uint(PRINT_ANY, WINDOW_STR, " Window:%u packets\n", + mnl_attr_get_u32(prop[TIPC_NLA_PROP_WIN])); + + open_json_object("rx packets"); + print_uint(PRINT_ANY, "rx packets", " RX packets:%u", + mnl_attr_get_u32(attrs[TIPC_NLA_LINK_RX]) - + mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_INFO])); + print_uint(PRINT_ANY, "fragments", " fragments:%u", + mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_FRAGMENTS])); + print_uint(PRINT_ANY, "fragmented", "/%u", + mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_FRAGMENTED])); + print_uint(PRINT_ANY, "bundles", " bundles:%u", + mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_BUNDLES])); + print_uint(PRINT_ANY, "bundled", "/%u\n", + mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_BUNDLED])); + close_json_object(); + + open_json_object("tx packets"); + print_uint(PRINT_ANY, "tx packets", " TX packets:%u", + mnl_attr_get_u32(attrs[TIPC_NLA_LINK_TX]) - + mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_INFO])); + print_uint(PRINT_ANY, "fragments", " fragments:%u", + mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_FRAGMENTS])); + print_uint(PRINT_ANY, "fragmented", "/%u", + mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_FRAGMENTED])); + print_uint(PRINT_ANY, "bundles", " bundles:%u", + mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_BUNDLES])); + print_uint(PRINT_ANY, "bundled", "/%u\n", + mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_BUNDLED])); + close_json_object(); proft = mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_PROF_TOT]); - printf(" TX profile sample:%u packets average:%u octets\n", - mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_CNT]), - mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_TOT]) / proft); - - printf(" 0-64:%u%% -256:%u%% -1024:%u%% -4096:%u%% -16384:%u%% -32768:%u%% -66000:%u%%\n", - perc(mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P0]), proft), - perc(mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P1]), proft), - perc(mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P2]), proft), - perc(mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P3]), proft), - perc(mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P4]), proft), - perc(mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P5]), proft), - perc(mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P6]), proft)); - - printf(" RX states:%u probes:%u naks:%u defs:%u dups:%u\n", - mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_STATES]), - mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_PROBES]), - mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_NACKS]), - mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_DEFERRED]), - mnl_attr_get_u32(stats[TIPC_NLA_STATS_DUPLICATES])); - - printf(" TX states:%u probes:%u naks:%u acks:%u dups:%u\n", - mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_STATES]), - mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_PROBES]), - mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_NACKS]), - mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_ACKS]), - mnl_attr_get_u32(stats[TIPC_NLA_STATS_RETRANSMITTED])); - - printf(" Congestion link:%u Send queue max:%u avg:%u\n", - mnl_attr_get_u32(stats[TIPC_NLA_STATS_LINK_CONGS]), - mnl_attr_get_u32(stats[TIPC_NLA_STATS_MAX_QUEUE]), - mnl_attr_get_u32(stats[TIPC_NLA_STATS_AVG_QUEUE])); - + print_uint(PRINT_ANY, "tx profile sample", " TX profile sample:%u", + mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_CNT])); + print_uint(PRINT_ANY, "packets average", " packets average:%u octets\n", + mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_TOT]) / proft); + + print_uint(PRINT_ANY, "0-64", " 0-64:%u%%", + perc(mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P0]), proft)); + print_uint(PRINT_ANY, "-256", " -256:%u%%", + perc(mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P1]), proft)); + print_uint(PRINT_ANY, "-1024", " -1024:%u%%", + perc(mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P2]), proft)); + print_uint(PRINT_ANY, "-4096", " -4096:%u%%", + perc(mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P3]), proft)); + print_uint(PRINT_ANY, "-16384", " -16384:%u%%", + perc(mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P4]), proft)); + print_uint(PRINT_ANY, "-32768", " -32768:%u%%", + perc(mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P5]), proft)); + print_uint(PRINT_ANY, "-66000", " -66000:%u%%\n", + perc(mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P6]), proft)); + + open_json_object("rx states"); + print_uint(PRINT_ANY, "rx states", " RX states:%u", + mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_STATES])); + print_uint(PRINT_ANY, "probes", " probes:%u", + mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_PROBES])); + print_uint(PRINT_ANY, "naks", " naks:%u", + mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_NACKS])); + print_uint(PRINT_ANY, "defs", " defs:%u", + mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_DEFERRED])); + print_uint(PRINT_ANY, "dups", " dups:%u\n", + mnl_attr_get_u32(stats[TIPC_NLA_STATS_DUPLICATES])); + close_json_object(); + + open_json_object("tx states"); + print_uint(PRINT_ANY, "tx states", " TX states:%u", + mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_STATES])); + print_uint(PRINT_ANY, "probes", " probes:%u", + mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_PROBES])); + print_uint(PRINT_ANY, "naks", " naks:%u", + mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_NACKS])); + print_uint(PRINT_ANY, "acks", " acks:%u", + mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_ACKS])); + print_uint(PRINT_ANY, "retrans", " retrans:%u\n", + mnl_attr_get_u32(stats[TIPC_NLA_STATS_RETRANSMITTED])); + close_json_object(); + + print_uint(PRINT_ANY, "congestion link", " Congestion link:%u", + mnl_attr_get_u32(stats[TIPC_NLA_STATS_LINK_CONGS])); + print_uint(PRINT_ANY, "send queue max", " Send queue max:%u", + mnl_attr_get_u32(stats[TIPC_NLA_STATS_MAX_QUEUE])); + print_uint(PRINT_ANY, "avg", " avg:%u\n", + mnl_attr_get_u32(stats[TIPC_NLA_STATS_AVG_QUEUE])); + + close_json_object(); return MNL_CB_OK; } -static int _show_bc_link_stat(struct nlattr *prop[], struct nlattr *stats[]) +static int _show_bc_link_stat(const char *name, struct nlattr *prop[], + struct nlattr *stats[]) { - printf(" Window:%u packets\n", - mnl_attr_get_u32(prop[TIPC_NLA_PROP_WIN])); - - printf(" RX packets:%u fragments:%u/%u bundles:%u/%u\n", - mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_INFO]), - mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_FRAGMENTS]), - mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_FRAGMENTED]), - mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_BUNDLES]), - mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_BUNDLED])); - - printf(" TX packets:%u fragments:%u/%u bundles:%u/%u\n", - mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_INFO]), - mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_FRAGMENTS]), - mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_FRAGMENTED]), - mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_BUNDLES]), - mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_BUNDLED])); - - printf(" RX naks:%u defs:%u dups:%u\n", - mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_NACKS]), - mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_DEFERRED]), - mnl_attr_get_u32(stats[TIPC_NLA_STATS_DUPLICATES])); - - printf(" TX naks:%u acks:%u dups:%u\n", - mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_NACKS]), - mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_ACKS]), - mnl_attr_get_u32(stats[TIPC_NLA_STATS_RETRANSMITTED])); - - printf(" Congestion link:%u Send queue max:%u avg:%u\n", - mnl_attr_get_u32(stats[TIPC_NLA_STATS_LINK_CONGS]), - mnl_attr_get_u32(stats[TIPC_NLA_STATS_MAX_QUEUE]), - mnl_attr_get_u32(stats[TIPC_NLA_STATS_AVG_QUEUE])); + open_json_object(NULL); + print_string(PRINT_ANY, "link", "Link <%s>\n", name); + print_uint(PRINT_ANY, WINDOW_STR, " Window:%u packets\n", + mnl_attr_get_u32(prop[TIPC_NLA_PROP_WIN])); + + open_json_object("rx packets"); + print_uint(PRINT_ANY, "rx packets", " RX packets:%u", + mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_INFO])); + print_uint(PRINT_ANY, "fragments", " fragments:%u", + mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_FRAGMENTS])); + print_uint(PRINT_ANY, "fragmented", "/%u", + mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_FRAGMENTED])); + print_uint(PRINT_ANY, "bundles", " bundles:%u", + mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_BUNDLES])); + print_uint(PRINT_ANY, "bundled", "/%u\n", + mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_BUNDLED])); + close_json_object(); + + open_json_object("tx packets"); + print_uint(PRINT_ANY, "tx packets", " TX packets:%u", + mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_INFO])); + print_uint(PRINT_ANY, "fragments", " fragments:%u", + mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_FRAGMENTS])); + print_uint(PRINT_ANY, "fragmented", "/%u", + mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_FRAGMENTED])); + print_uint(PRINT_ANY, "bundles", " bundles:%u", + mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_BUNDLES])); + print_uint(PRINT_ANY, "bundled", "/%u\n", + mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_BUNDLED])); + close_json_object(); + + open_json_object("rx naks"); + print_uint(PRINT_ANY, "rx naks", " RX naks:%u", + mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_NACKS])); + print_uint(PRINT_ANY, "defs", " defs:%u", + mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_DEFERRED])); + print_uint(PRINT_ANY, "dups", " dups:%u\n", + mnl_attr_get_u32(stats[TIPC_NLA_STATS_DUPLICATES])); + close_json_object(); + + open_json_object("tx naks"); + print_uint(PRINT_ANY, "tx naks", " TX naks:%u", + mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_NACKS])); + print_uint(PRINT_ANY, "acks", " acks:%u", + mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_ACKS])); + print_uint(PRINT_ANY, "retrans", " retrans:%u\n", + mnl_attr_get_u32(stats[TIPC_NLA_STATS_RETRANSMITTED])); + close_json_object(); + + print_uint(PRINT_ANY, "congestion link", " Congestion link:%u", + mnl_attr_get_u32(stats[TIPC_NLA_STATS_LINK_CONGS])); + print_uint(PRINT_ANY, "send queue max", " Send queue max:%u", + mnl_attr_get_u32(stats[TIPC_NLA_STATS_MAX_QUEUE])); + print_uint(PRINT_ANY, "avg", " avg:%u\n", + mnl_attr_get_u32(stats[TIPC_NLA_STATS_AVG_QUEUE])); + close_json_object(); return MNL_CB_OK; } @@ -350,13 +446,10 @@ static int link_stat_show_cb(const struct nlmsghdr *nlh, void *data) return MNL_CB_OK; if (attrs[TIPC_NLA_LINK_BROADCAST]) { - printf("Link <%s>\n", name); - return _show_bc_link_stat(prop, stats); + return _show_bc_link_stat(name, prop, stats); } - printf("\nLink <%s>\n", name); - - return _show_link_stat(attrs, prop, stats); + return _show_link_stat(name, attrs, prop, stats); } static void cmd_link_stat_show_help(struct cmdl *cmdl) @@ -375,6 +468,7 @@ static int cmd_link_stat_show(struct nlmsghdr *nlh, const struct cmd *cmd, { "link", OPT_KEYVAL, NULL }, { NULL } }; + int err = 0; if (help_flag) { (cmd->help)(cmdl); @@ -394,7 +488,10 @@ static int cmd_link_stat_show(struct nlmsghdr *nlh, const struct cmd *cmd, if (opt) link = opt->val; - return msg_dumpit(nlh, link_stat_show_cb, link); + new_json_obj(json); + err = msg_dumpit(nlh, link_stat_show_cb, link); + delete_json_obj(); + return err; } static void cmd_link_stat_help(struct cmdl *cmdl) @@ -442,11 +539,11 @@ static int cmd_link_set_prop(struct nlmsghdr *nlh, const struct cmd *cmd, { NULL } }; - if (strcmp(cmd->cmd, "priority") == 0) + if (strcmp(cmd->cmd, PRIORITY_STR) == 0) prop = TIPC_NLA_PROP_PRIO; - else if ((strcmp(cmd->cmd, "tolerance") == 0)) + else if ((strcmp(cmd->cmd, TOLERANCE_STR) == 0)) prop = TIPC_NLA_PROP_TOL; - else if ((strcmp(cmd->cmd, "window") == 0)) + else if ((strcmp(cmd->cmd, WINDOW_STR) == 0)) prop = TIPC_NLA_PROP_WIN; else return -EINVAL; @@ -492,9 +589,9 @@ static int cmd_link_set(struct nlmsghdr *nlh, const struct cmd *cmd, struct cmdl *cmdl, void *data) { const struct cmd cmds[] = { - { "priority", cmd_link_set_prop, cmd_link_set_help }, - { "tolerance", cmd_link_set_prop, cmd_link_set_help }, - { "window", cmd_link_set_prop, cmd_link_set_help }, + { PRIORITY_STR, cmd_link_set_prop, cmd_link_set_help }, + { TOLERANCE_STR, cmd_link_set_prop, cmd_link_set_help }, + { WINDOW_STR, cmd_link_set_prop, cmd_link_set_help }, { NULL } }; @@ -540,15 +637,17 @@ static int link_mon_summary_cb(const struct nlmsghdr *nlh, void *data) mnl_attr_parse_nested(info[TIPC_NLA_MON], parse_attrs, attrs); - printf("\nbearer %s\n", + open_json_object(NULL); + print_string(PRINT_ANY, "bearer", "\nbearer %s\n", mnl_attr_get_str(attrs[TIPC_NLA_MON_BEARER_NAME])); - printf(" table_generation %u\n", + print_uint(PRINT_ANY, "table_generation", " table_generation %u\n", mnl_attr_get_u32(attrs[TIPC_NLA_MON_LISTGEN])); - printf(" cluster_size %u\n", + print_uint(PRINT_ANY, "cluster_size", " cluster_size %u\n", mnl_attr_get_u32(attrs[TIPC_NLA_MON_PEERCNT])); - printf(" algorithm %s\n", + print_string(PRINT_ANY, "algorithm", " algorithm %s\n", attrs[TIPC_NLA_MON_ACTIVE] ? "overlapping-ring" : "full-mesh"); + close_json_object(); return MNL_CB_OK; } @@ -557,6 +656,7 @@ static int cmd_link_mon_summary(struct nlmsghdr *nlh, const struct cmd *cmd, struct cmdl *cmdl, void *data) { char buf[MNL_SOCKET_BUFFER_SIZE]; + int err = 0; if (help_flag) { fprintf(stderr, "Usage: %s monitor summary\n", cmdl->argv[0]); @@ -569,7 +669,11 @@ static int cmd_link_mon_summary(struct nlmsghdr *nlh, const struct cmd *cmd, return -1; } - return msg_dumpit(nlh, link_mon_summary_cb, NULL); + new_json_obj(json); + err = msg_dumpit(nlh, link_mon_summary_cb, NULL); + delete_json_obj(); + + return err; } #define STATUS_WIDTH 7 @@ -590,16 +694,19 @@ static int map_get(uint64_t up_map, int i) static void link_mon_print_applied(uint16_t applied, uint64_t up_map) { int i; - char state; + open_json_array(PRINT_JSON, "applied_node_status"); for (i = 0; i < applied; i++) { + char state_str[2] = {0}; + /* print the delimiter for every -n- entry */ if (i && !(i % APPL_NODE_STATUS_WIDTH)) - printf(","); + print_string(PRINT_FP, NULL, "%s", ","); - state = map_get(up_map, i) ? 'U' : 'D'; - printf("%c", state); + sprintf(state_str, "%c", map_get(up_map, i) ? 'U' : 'D'); + print_string(PRINT_ANY, NULL, "%s", state_str); } + close_json_array(PRINT_JSON, "applied_node_status"); } /* print the non applied members, since we dont know @@ -611,19 +718,23 @@ static void link_mon_print_non_applied(uint16_t applied, uint16_t member_cnt, int i; char state; - printf(" ["); + open_json_array(PRINT_JSON, "[non_applied_node:status]"); + print_string(PRINT_FP, NULL, " %s", "["); for (i = applied; i < member_cnt; i++) { char addr_str[16]; + char full_state[17] = {0}; /* print the delimiter for every entry */ if (i != applied) - printf(","); + print_string(PRINT_FP, NULL, "%s", ","); sprintf(addr_str, "%x:", members[i]); state = map_get(up_map, i) ? 'U' : 'D'; - printf("%s%c", addr_str, state); + sprintf(full_state, "%s%c", addr_str, state); + print_string(PRINT_ANY, NULL, "%s", full_state); } - printf("]"); + print_string(PRINT_FP, NULL, "%s", "]"); + close_json_array(PRINT_JSON, "[non_applied_node:status]"); } static void link_mon_print_peer_state(const uint32_t addr, const char *status, @@ -634,11 +745,17 @@ static void link_mon_print_peer_state(const uint32_t addr, const char *status, sprintf(addr_str, "%u.%u.%u", tipc_zone(addr), tipc_cluster(addr), tipc_node(addr)); - - printf("%-*s", MAX_NODE_WIDTH, addr_str); - printf("%-*s", STATUS_WIDTH, status); - printf("%-*s", DIRECTLY_MON_WIDTH, monitored); - printf("%-*u", MAX_DOM_GEN_WIDTH, dom_gen); + if (is_json_context()) { + print_string(PRINT_JSON, "node", NULL, addr_str); + print_string(PRINT_JSON, "status", NULL, status); + print_string(PRINT_JSON, "monitored", NULL, monitored); + print_uint(PRINT_JSON, "generation", NULL, dom_gen); + } else { + printf("%-*s", MAX_NODE_WIDTH, addr_str); + printf("%-*s", STATUS_WIDTH, status); + printf("%-*s", DIRECTLY_MON_WIDTH, monitored); + printf("%-*u", MAX_DOM_GEN_WIDTH, dom_gen); + } } static int link_mon_peer_list_cb(const struct nlmsghdr *nlh, void *data) @@ -657,6 +774,7 @@ static int link_mon_peer_list_cb(const struct nlmsghdr *nlh, void *data) if (!info[TIPC_NLA_MON_PEER]) return MNL_CB_ERROR; + open_json_object(NULL); mnl_attr_parse_nested(info[TIPC_NLA_MON_PEER], parse_attrs, attrs); (attrs[TIPC_NLA_MON_PEER_LOCAL] || attrs[TIPC_NLA_MON_PEER_HEAD]) ? @@ -691,8 +809,9 @@ static int link_mon_peer_list_cb(const struct nlmsghdr *nlh, void *data) mnl_attr_get_payload(attrs[TIPC_NLA_MON_PEER_MEMBERS])); exit: - printf("\n"); + print_string(PRINT_FP, NULL, "\n", ""); + close_json_object(); return MNL_CB_OK; } @@ -701,6 +820,7 @@ static int link_mon_peer_list(uint32_t mon_ref) struct nlmsghdr *nlh; char buf[MNL_SOCKET_BUFFER_SIZE]; struct nlattr *nest; + int err = 0; nlh = msg_init(buf, TIPC_NL_MON_PEER_GET); if (!nlh) { @@ -712,7 +832,8 @@ static int link_mon_peer_list(uint32_t mon_ref) mnl_attr_put_u32(nlh, TIPC_NLA_MON_REF, mon_ref); mnl_attr_nest_end(nlh, nest); - return msg_dumpit(nlh, link_mon_peer_list_cb, NULL); + err = msg_dumpit(nlh, link_mon_peer_list_cb, NULL); + return err; } static int link_mon_list_cb(const struct nlmsghdr *nlh, void *data) @@ -736,12 +857,16 @@ static int link_mon_list_cb(const struct nlmsghdr *nlh, void *data) if (*req_bearer && (strcmp(req_bearer, bname) != 0)) return MNL_CB_OK; - printf("\nbearer %s\n", bname); - printf("%s\n", title); + open_json_object(NULL); + print_string(PRINT_ANY, "bearer", "\nbearer %s\n", bname); + print_string(PRINT_FP, NULL, "%s\n", title); + open_json_array(PRINT_JSON, bname); if (mnl_attr_get_u32(attrs[TIPC_NLA_MON_PEERCNT])) link_mon_peer_list(mnl_attr_get_u32(attrs[TIPC_NLA_MON_REF])); + close_json_array(PRINT_JSON, bname); + close_json_object(); return MNL_CB_OK; } @@ -807,7 +932,10 @@ static int cmd_link_mon_list(struct nlmsghdr *nlh, const struct cmd *cmd, return -1; } - return msg_dumpit(nlh, link_mon_list_cb, bname); + new_json_obj(json); + err = msg_dumpit(nlh, link_mon_list_cb, bname); + delete_json_obj(); + return err; } static void cmd_link_mon_set_help(struct cmdl *cmdl) @@ -851,8 +979,10 @@ static int link_mon_get_cb(const struct nlmsghdr *nlh, void *data) if (!attrs[TIPC_NLA_MON_ACTIVATION_THRESHOLD]) return MNL_CB_ERROR; - printf("%u\n", - mnl_attr_get_u32(attrs[TIPC_NLA_MON_ACTIVATION_THRESHOLD])); + new_json_obj(json); + print_uint(PRINT_ANY, "threshold", "%u\n", + mnl_attr_get_u32(attrs[TIPC_NLA_MON_ACTIVATION_THRESHOLD])); + delete_json_obj(); return MNL_CB_OK; }