@@ -30,6 +30,7 @@
#include <linux/sockios.h>
#include <linux/net_namespace.h>
+#include "utils.h"
#include "rt_names.h"
#include "utils.h"
#include "ll_map.h"
@@ -84,13 +85,14 @@ static void usage(void)
static void print_link_flags(FILE *fp, unsigned int flags, unsigned int mdown)
{
- fprintf(fp, "<");
+ open_json_array(PRINT_ANY, is_json_context() ? "flags" : "<");
if (flags & IFF_UP && !(flags & IFF_RUNNING))
- fprintf(fp, "NO-CARRIER%s", flags ? "," : "");
+ print_string(PRINT_ANY, NULL,
+ flags ? "%s," : "%s", "NO-CARRIER");
flags &= ~IFF_RUNNING;
-#define _PF(f) if (flags&IFF_##f) { \
- flags &= ~IFF_##f ; \
- fprintf(fp, #f "%s", flags ? "," : ""); }
+#define _PF(f) if (flags&IFF_##f) { \
+ flags &= ~IFF_##f ; \
+ print_string(PRINT_ANY, NULL, flags ? "%s," : "%s", #f); }
_PF(LOOPBACK);
_PF(BROADCAST);
_PF(POINTOPOINT);
@@ -111,10 +113,10 @@ static void print_link_flags(FILE *fp, unsigned int flags, unsigned int mdown)
_PF(ECHO);
#undef _PF
if (flags)
- fprintf(fp, "%x", flags);
+ print_hex(PRINT_ANY, NULL, "%x", flags);
if (mdown)
- fprintf(fp, ",M-DOWN");
- fprintf(fp, "> ");
+ print_string(PRINT_ANY, NULL, ",%s", "M-DOWN");
+ close_json_array(PRINT_ANY, "> ");
}
static const char *oper_states[] = {
@@ -125,14 +127,26 @@ static const char *oper_states[] = {
static void print_operstate(FILE *f, __u8 state)
{
if (state >= ARRAY_SIZE(oper_states)) {
- fprintf(f, "state %#x ", state);
+ if (is_json_context())
+ print_uint(PRINT_JSON, "operstate_index", NULL, state);
+ else
+ print_0xhex(PRINT_FP, NULL, "state %#x", state);
} else if (brief) {
- color_fprintf(f, oper_state_color(state),
- "%-14s ", oper_states[state]);
+ print_color_string(PRINT_ANY,
+ oper_state_color(state),
+ "operstate",
+ "%-14s ",
+ oper_states[state]);
} else {
- fprintf(f, "state ");
- color_fprintf(f, oper_state_color(state),
- "%s ", oper_states[state]);
+ if (is_json_context())
+ print_string(PRINT_JSON,
+ "operstate",
+ NULL, oper_states[state]);
+ else {
+ fprintf(f, "state ");
+ color_fprintf(f, oper_state_color(state),
+ "%s ", oper_states[state]);
+ }
}
}
@@ -169,7 +183,7 @@ static void print_queuelen(FILE *f, struct rtattr *tb[IFLA_MAX + 1])
qlen = ifr.ifr_qlen;
}
if (qlen)
- fprintf(f, "qlen %d", qlen);
+ print_int(PRINT_ANY, "txqlen", "qlen %d", qlen);
}
static const char *link_modes[] = {
@@ -181,9 +195,15 @@ static void print_linkmode(FILE *f, struct rtattr *tb)
unsigned int mode = rta_getattr_u8(tb);
if (mode >= ARRAY_SIZE(link_modes))
- fprintf(f, "mode %d ", mode);
+ print_int(PRINT_ANY,
+ "linkmode_index",
+ "mode %d ",
+ mode);
else
- fprintf(f, "mode %s ", link_modes[mode]);
+ print_string(PRINT_ANY,
+ "linkmode",
+ "mode %s "
+ , link_modes[mode]);
}
static char *parse_link_kind(struct rtattr *tb, bool slave)
@@ -215,13 +235,14 @@ static void print_linktype(FILE *fp, struct rtattr *tb)
char slave[32];
parse_rtattr_nested(linkinfo, IFLA_INFO_MAX, tb);
+ open_json_object("linkinfo");
if (linkinfo[IFLA_INFO_KIND]) {
const char *kind
= rta_getattr_str(linkinfo[IFLA_INFO_KIND]);
- fprintf(fp, "%s", _SL_);
- fprintf(fp, " %s ", kind);
+ print_string(PRINT_FP, NULL, "%s", _SL_);
+ print_string(PRINT_ANY, "info_kind", " %s ", kind);
lu = get_link_kind(kind);
if (lu && lu->print_opt) {
@@ -232,11 +253,16 @@ static void print_linktype(FILE *fp, struct rtattr *tb)
linkinfo[IFLA_INFO_DATA]);
data = attr;
}
+ open_json_object("info_data");
lu->print_opt(lu, fp, data);
+ close_json_object();
if (linkinfo[IFLA_INFO_XSTATS] && show_stats &&
- lu->print_xstats)
+ lu->print_xstats) {
+ open_json_object("info_xstats");
lu->print_xstats(lu, fp, linkinfo[IFLA_INFO_XSTATS]);
+ close_json_object();
+ }
}
}
@@ -244,8 +270,12 @@ static void print_linktype(FILE *fp, struct rtattr *tb)
const char *slave_kind
= rta_getattr_str(linkinfo[IFLA_INFO_SLAVE_KIND]);
- fprintf(fp, "%s", _SL_);
- fprintf(fp, " %s_slave ", slave_kind);
+ print_string(PRINT_FP, NULL, "%s", _SL_);
+ print_string(PRINT_ANY,
+ "info_slave_kind",
+ " %s_slave ",
+ slave_kind);
+
snprintf(slave, sizeof(slave), "%s_slave", slave_kind);
slave_lu = get_link_kind(slave);
@@ -257,9 +287,12 @@ static void print_linktype(FILE *fp, struct rtattr *tb)
linkinfo[IFLA_INFO_SLAVE_DATA]);
data = attr;
}
+ open_json_object("info_slave_data");
slave_lu->print_opt(slave_lu, fp, data);
+ close_json_object();
}
}
+ close_json_object();
}
static void print_af_spec(FILE *fp, struct rtattr *af_spec_attr)
@@ -275,22 +308,39 @@ static void print_af_spec(FILE *fp, struct rtattr *af_spec_attr)
if (tb[IFLA_INET6_ADDR_GEN_MODE]) {
__u8 mode = rta_getattr_u8(tb[IFLA_INET6_ADDR_GEN_MODE]);
+ SPRINT_BUF(b1);
switch (mode) {
case IN6_ADDR_GEN_MODE_EUI64:
- fprintf(fp, "addrgenmode eui64 ");
+ print_string(PRINT_ANY,
+ "inet6_addr_gen_mode",
+ "addrgenmode %s ",
+ "eui64");
break;
case IN6_ADDR_GEN_MODE_NONE:
- fprintf(fp, "addrgenmode none ");
+ print_string(PRINT_ANY,
+ "inet6_addr_gen_mode",
+ "addrgenmode %s ",
+ "none");
break;
case IN6_ADDR_GEN_MODE_STABLE_PRIVACY:
- fprintf(fp, "addrgenmode stable_secret ");
+ print_string(PRINT_ANY,
+ "inet6_addr_gen_mode",
+ "addrgenmode %s ",
+ "stable_secret");
break;
case IN6_ADDR_GEN_MODE_RANDOM:
- fprintf(fp, "addrgenmode random ");
+ print_string(PRINT_ANY,
+ "inet6_addr_gen_mode",
+ "addrgenmode %s ",
+ "random");
break;
default:
- fprintf(fp, "addrgenmode %#.2hhx ", mode);
+ snprintf(b1, sizeof(b1), "%#.2hhx", mode);
+ print_string(PRINT_ANY,
+ "inet6_addr_gen_mode",
+ "addrgenmode %s ",
+ b1);
break;
}
}
@@ -316,83 +366,135 @@ static void print_vfinfo(FILE *fp, struct rtattr *vfinfo)
vf_mac = RTA_DATA(vf[IFLA_VF_MAC]);
vf_tx_rate = RTA_DATA(vf[IFLA_VF_TX_RATE]);
- fprintf(fp, "%s vf %d MAC %s", _SL_, vf_mac->vf,
- ll_addr_n2a((unsigned char *)&vf_mac->mac,
- ETH_ALEN, 0, b1, sizeof(b1)));
+ print_string(PRINT_FP, NULL, "%s ", _SL_);
+ print_int(PRINT_ANY, "vf", "vf %d ", vf_mac->vf);
+ print_string(PRINT_ANY, "mac", "MAC %s",
+ ll_addr_n2a((unsigned char *) &vf_mac->mac,
+ ETH_ALEN, 0, b1, sizeof(b1)));
+
if (vf[IFLA_VF_VLAN_LIST]) {
struct rtattr *i, *vfvlanlist = vf[IFLA_VF_VLAN_LIST];
int rem = RTA_PAYLOAD(vfvlanlist);
+ open_json_array(PRINT_JSON, "vlan_list");
for (i = RTA_DATA(vfvlanlist);
- RTA_OK(i, rem); i = RTA_NEXT(i, rem)) {
- struct ifla_vf_vlan_info *vf_vlan_info =
- RTA_DATA(i);
+ RTA_OK(i, rem); i = RTA_NEXT(i, rem)) {
+ struct ifla_vf_vlan_info *vf_vlan_info = RTA_DATA(i);
SPRINT_BUF(b2);
+ open_json_object(NULL);
if (vf_vlan_info->vlan)
- fprintf(fp, ", vlan %d", vf_vlan_info->vlan);
+ print_int(PRINT_ANY,
+ "vlan",
+ ", vlan %d",
+ vf_vlan_info->vlan);
if (vf_vlan_info->qos)
- fprintf(fp, ", qos %d", vf_vlan_info->qos);
+ print_int(PRINT_ANY,
+ "qos",
+ ", qos %d",
+ vf_vlan_info->qos);
if (vf_vlan_info->vlan_proto &&
vf_vlan_info->vlan_proto != htons(ETH_P_8021Q))
- fprintf(fp, ", vlan protocol %s",
- ll_proto_n2a(vf_vlan_info->vlan_proto,
+ print_string(PRINT_ANY,
+ "protocol",
+ ", vlan protocol %s",
+ ll_proto_n2a(
+ vf_vlan_info->vlan_proto,
b2, sizeof(b2)));
-
+ close_json_object();
}
+ close_json_array(PRINT_JSON, NULL);
} else {
struct ifla_vf_vlan *vf_vlan = RTA_DATA(vf[IFLA_VF_VLAN]);
if (vf_vlan->vlan)
- fprintf(fp, ", vlan %d", vf_vlan->vlan);
+ print_int(PRINT_ANY,
+ "vlan",
+ ", vlan %d",
+ vf_vlan->vlan);
if (vf_vlan->qos)
- fprintf(fp, ", qos %d", vf_vlan->qos);
+ print_int(PRINT_ANY, "qos", ", qos %d", vf_vlan->qos);
}
+
if (vf_tx_rate->rate)
- fprintf(fp, ", tx rate %d (Mbps)", vf_tx_rate->rate);
+ print_int(PRINT_ANY,
+ "tx_rate",
+ ", tx rate %d (Mbps)",
+ vf_tx_rate->rate);
if (vf[IFLA_VF_RATE]) {
struct ifla_vf_rate *vf_rate = RTA_DATA(vf[IFLA_VF_RATE]);
-
- if (vf_rate->max_tx_rate)
- fprintf(fp, ", max_tx_rate %dMbps", vf_rate->max_tx_rate);
- if (vf_rate->min_tx_rate)
- fprintf(fp, ", min_tx_rate %dMbps", vf_rate->min_tx_rate);
+ int max_tx = vf_rate->max_tx_rate;
+ int min_tx = vf_rate->min_tx_rate;
+
+ if (is_json_context()) {
+ open_json_object("rate");
+ print_int(PRINT_JSON, "max_tx", NULL, max_tx);
+ print_int(PRINT_ANY, "min_tx", NULL, min_tx);
+ close_json_object();
+ } else {
+ if (max_tx)
+ fprintf(fp, ", max_tx_rate %dMbps", max_tx);
+ if (min_tx)
+ fprintf(fp, ", min_tx_rate %dMbps", min_tx);
+ }
}
+
if (vf[IFLA_VF_SPOOFCHK]) {
struct ifla_vf_spoofchk *vf_spoofchk =
RTA_DATA(vf[IFLA_VF_SPOOFCHK]);
if (vf_spoofchk->setting != -1)
- fprintf(fp, ", spoof checking %s",
- vf_spoofchk->setting ? "on" : "off");
+ print_bool(PRINT_ANY,
+ "spoofchk",
+ vf_spoofchk->setting ?
+ ", spoof checking on" : ", spoof checking off",
+ vf_spoofchk->setting);
}
+
if (vf[IFLA_VF_LINK_STATE]) {
struct ifla_vf_link_state *vf_linkstate =
RTA_DATA(vf[IFLA_VF_LINK_STATE]);
if (vf_linkstate->link_state == IFLA_VF_LINK_STATE_AUTO)
- fprintf(fp, ", link-state auto");
+ print_string(PRINT_ANY,
+ "link_state",
+ ", link-state %s",
+ "auto");
else if (vf_linkstate->link_state == IFLA_VF_LINK_STATE_ENABLE)
- fprintf(fp, ", link-state enable");
+ print_string(PRINT_ANY,
+ "link_state",
+ ", link-state %s",
+ "enable");
else
- fprintf(fp, ", link-state disable");
+ print_string(PRINT_ANY,
+ "link_state",
+ ", link-state %s",
+ "disable");
}
+
if (vf[IFLA_VF_TRUST]) {
struct ifla_vf_trust *vf_trust = RTA_DATA(vf[IFLA_VF_TRUST]);
if (vf_trust->setting != -1)
- fprintf(fp, ", trust %s",
- vf_trust->setting ? "on" : "off");
+ print_bool(PRINT_ANY,
+ "trust",
+ vf_trust->setting ? ", trust on" : ", trust off",
+ vf_trust->setting);
}
+
if (vf[IFLA_VF_RSS_QUERY_EN]) {
struct ifla_vf_rss_query_en *rss_query =
RTA_DATA(vf[IFLA_VF_RSS_QUERY_EN]);
if (rss_query->setting != -1)
- fprintf(fp, ", query_rss %s",
- rss_query->setting ? "on" : "off");
+ print_bool(PRINT_ANY,
+ "query_rss_en",
+ rss_query->setting ? ", query_rss on"
+ : ", query_rss off",
+ rss_query->setting);
}
+
if (vf[IFLA_VF_STATS] && show_stats)
print_vf_stats64(fp, vf[IFLA_VF_STATS]);
}
@@ -432,7 +534,7 @@ void print_num(FILE *fp, unsigned int width, uint64_t count)
}
snprintf(buf, sizeof(buf), "%.*f%c%s", precision,
- (double) count / powi, *prefix, use_iec ? "i" : "");
+ (double) count / powi, *prefix, use_iec ? "i" : "");
fprintf(fp, "%-*s ", width, buf);
}
@@ -448,155 +550,339 @@ static void print_vf_stats64(FILE *fp, struct rtattr *vfstats)
parse_rtattr_nested(vf, IFLA_VF_MAX, vfstats);
- /* RX stats */
- fprintf(fp, "%s", _SL_);
- fprintf(fp, " RX: bytes packets mcast bcast %s", _SL_);
- fprintf(fp, " ");
+ if (is_json_context()) {
+ open_json_object("stats");
+
+ /* RX stats */
+ open_json_object("rx");
+ print_uint(PRINT_JSON, "bytes", NULL,
+ rta_getattr_u64(vf[IFLA_VF_STATS_RX_BYTES]));
+ print_uint(PRINT_JSON, "packets", NULL,
+ rta_getattr_u64(vf[IFLA_VF_STATS_RX_PACKETS]));
+ print_uint(PRINT_JSON, "multicast", NULL,
+ rta_getattr_u64(vf[IFLA_VF_STATS_MULTICAST]));
+ print_uint(PRINT_JSON, "broadcast", NULL,
+ rta_getattr_u64(vf[IFLA_VF_STATS_BROADCAST]));
+ close_json_object();
+
+ /* TX stats */
+ open_json_object("tx");
+ print_uint(PRINT_JSON, "tx_bytes", NULL,
+ rta_getattr_u64(vf[IFLA_VF_STATS_TX_BYTES]));
+ print_uint(PRINT_JSON, "tx_packets", NULL,
+ rta_getattr_u64(vf[IFLA_VF_STATS_TX_PACKETS]));
+ close_json_object();
+ close_json_object();
+ } else {
+ /* RX stats */
+ fprintf(fp, "%s", _SL_);
+ fprintf(fp, " RX: bytes packets mcast bcast %s", _SL_);
+ fprintf(fp, " ");
- print_num(fp, 10, rta_getattr_u64(vf[IFLA_VF_STATS_RX_BYTES]));
- print_num(fp, 8, rta_getattr_u64(vf[IFLA_VF_STATS_RX_PACKETS]));
- print_num(fp, 7, rta_getattr_u64(vf[IFLA_VF_STATS_MULTICAST]));
- print_num(fp, 7, rta_getattr_u64(vf[IFLA_VF_STATS_BROADCAST]));
+ print_num(fp, 10, rta_getattr_u64(vf[IFLA_VF_STATS_RX_BYTES]));
+ print_num(fp, 8, rta_getattr_u64(vf[IFLA_VF_STATS_RX_PACKETS]));
+ print_num(fp, 7, rta_getattr_u64(vf[IFLA_VF_STATS_MULTICAST]));
+ print_num(fp, 7, rta_getattr_u64(vf[IFLA_VF_STATS_BROADCAST]));
- /* TX stats */
- fprintf(fp, "%s", _SL_);
- fprintf(fp, " TX: bytes packets %s", _SL_);
- fprintf(fp, " ");
+ /* TX stats */
+ fprintf(fp, "%s", _SL_);
+ fprintf(fp, " TX: bytes packets %s", _SL_);
+ fprintf(fp, " ");
- print_num(fp, 10, rta_getattr_u64(vf[IFLA_VF_STATS_TX_BYTES]));
- print_num(fp, 8, rta_getattr_u64(vf[IFLA_VF_STATS_TX_PACKETS]));
+ print_num(fp, 10, rta_getattr_u64(vf[IFLA_VF_STATS_TX_BYTES]));
+ print_num(fp, 8, rta_getattr_u64(vf[IFLA_VF_STATS_TX_PACKETS]));
+ }
}
static void print_link_stats64(FILE *fp, const struct rtnl_link_stats64 *s,
const struct rtattr *carrier_changes)
{
- /* RX stats */
- fprintf(fp, " RX: bytes packets errors dropped overrun mcast %s%s",
- s->rx_compressed ? "compressed" : "", _SL_);
-
- fprintf(fp, " ");
- print_num(fp, 10, s->rx_bytes);
- print_num(fp, 8, s->rx_packets);
- print_num(fp, 7, s->rx_errors);
- print_num(fp, 7, s->rx_dropped);
- print_num(fp, 7, s->rx_over_errors);
- print_num(fp, 7, s->multicast);
- if (s->rx_compressed)
- print_num(fp, 7, s->rx_compressed);
-
- /* RX error stats */
- if (show_stats > 1) {
- fprintf(fp, "%s", _SL_);
- fprintf(fp, " RX errors: length crc frame fifo missed%s%s",
- s->rx_nohandler ? " nohandler" : "", _SL_);
-
- fprintf(fp, " ");
- print_num(fp, 8, s->rx_length_errors);
- print_num(fp, 7, s->rx_crc_errors);
- print_num(fp, 7, s->rx_frame_errors);
- print_num(fp, 7, s->rx_fifo_errors);
- print_num(fp, 7, s->rx_missed_errors);
- if (s->rx_nohandler)
- print_num(fp, 7, s->rx_nohandler);
+ if (is_json_context()) {
+ open_json_object("stats644");
+
+ /* RX stats */
+ open_json_object("rx");
+ print_uint(PRINT_JSON, "bytes", NULL, s->rx_bytes);
+ print_uint(PRINT_JSON, "packets", NULL, s->rx_packets);
+ print_uint(PRINT_JSON, "errors", NULL, s->rx_errors);
+ print_uint(PRINT_JSON, "dropped", NULL, s->rx_dropped);
+ print_uint(PRINT_JSON, "over_errors", NULL, s->rx_over_errors);
+ print_uint(PRINT_JSON, "multicast", NULL, s->multicast);
+ if (s->rx_compressed)
+ print_uint(PRINT_JSON,
+ "compressed",
+ NULL, s->rx_compressed);
+
+ /* RX error stats */
+ if (show_stats > 1) {
+ print_uint(PRINT_JSON,
+ "length_errors",
+ NULL, s->rx_length_errors);
+ print_uint(PRINT_JSON,
+ "crc_errors",
+ NULL, s->rx_crc_errors);
+ print_uint(PRINT_JSON,
+ "frame_errors",
+ NULL, s->rx_frame_errors);
+ print_uint(PRINT_JSON,
+ "fifo_errors",
+ NULL, s->rx_fifo_errors);
+ print_uint(PRINT_JSON,
+ "missed_errors",
+ NULL, s->rx_missed_errors);
+ if (s->rx_nohandler)
+ print_uint(PRINT_JSON,
+ "nohandler", NULL, s->rx_nohandler);
+ }
+ close_json_object();
+
+ /* TX stats */
+ open_json_object("tx");
+ print_uint(PRINT_JSON, "bytes", NULL, s->tx_bytes);
+ print_uint(PRINT_JSON, "packets", NULL, s->tx_packets);
+ print_uint(PRINT_JSON, "errors", NULL, s->tx_errors);
+ print_uint(PRINT_JSON, "dropped", NULL, s->tx_dropped);
+ print_uint(PRINT_JSON,
+ "carrier_errors",
+ NULL, s->tx_carrier_errors);
+ print_uint(PRINT_JSON, "collisions", NULL, s->collisions);
+ if (s->tx_compressed)
+ print_uint(PRINT_JSON,
+ "compressed",
+ NULL, s->tx_compressed);
+
+ /* TX error stats */
+ if (show_stats > 1) {
+ print_uint(PRINT_JSON,
+ "aborted_errors",
+ NULL, s->tx_aborted_errors);
+ print_uint(PRINT_JSON,
+ "fifo_errors",
+ NULL, s->tx_fifo_errors);
+ print_uint(PRINT_JSON,
+ "window_errors",
+ NULL, s->tx_window_errors);
+ print_uint(PRINT_JSON,
+ "heartbeat_errors",
+ NULL, s->tx_heartbeat_errors);
+ if (carrier_changes)
+ print_uint(PRINT_JSON, "carrier_changes", NULL,
+ rta_getattr_u32(carrier_changes));
+ }
+ close_json_object();
+ close_json_object();
- }
- fprintf(fp, "%s", _SL_);
+ } else {
+ /* RX stats */
+ fprintf(fp, " RX: bytes packets errors dropped overrun mcast %s%s",
+ s->rx_compressed ? "compressed" : "", _SL_);
+
+ fprintf(fp, " ");
+ print_num(fp, 10, s->rx_bytes);
+ print_num(fp, 8, s->rx_packets);
+ print_num(fp, 7, s->rx_errors);
+ print_num(fp, 7, s->rx_dropped);
+ print_num(fp, 7, s->rx_over_errors);
+ print_num(fp, 7, s->multicast);
+ if (s->rx_compressed)
+ print_num(fp, 7, s->rx_compressed);
+
+ /* RX error stats */
+ if (show_stats > 1) {
+ fprintf(fp, "%s", _SL_);
+ fprintf(fp, " RX errors: length crc frame fifo missed%s%s",
+ s->rx_nohandler ? " nohandler" : "", _SL_);
+
+ fprintf(fp, " ");
+ print_num(fp, 8, s->rx_length_errors);
+ print_num(fp, 7, s->rx_crc_errors);
+ print_num(fp, 7, s->rx_frame_errors);
+ print_num(fp, 7, s->rx_fifo_errors);
+ print_num(fp, 7, s->rx_missed_errors);
+ if (s->rx_nohandler)
+ print_num(fp, 7, s->rx_nohandler);
- /* TX stats */
- fprintf(fp, " TX: bytes packets errors dropped carrier collsns %s%s",
- s->tx_compressed ? "compressed" : "", _SL_);
-
- fprintf(fp, " ");
- print_num(fp, 10, s->tx_bytes);
- print_num(fp, 8, s->tx_packets);
- print_num(fp, 7, s->tx_errors);
- print_num(fp, 7, s->tx_dropped);
- print_num(fp, 7, s->tx_carrier_errors);
- print_num(fp, 7, s->collisions);
- if (s->tx_compressed)
- print_num(fp, 7, s->tx_compressed);
-
- /* TX error stats */
- if (show_stats > 1) {
- fprintf(fp, "%s", _SL_);
- fprintf(fp, " TX errors: aborted fifo window heartbeat");
- if (carrier_changes)
- fprintf(fp, " transns");
+ }
fprintf(fp, "%s", _SL_);
- fprintf(fp, " ");
- print_num(fp, 8, s->tx_aborted_errors);
- print_num(fp, 7, s->tx_fifo_errors);
- print_num(fp, 7, s->tx_window_errors);
- print_num(fp, 7, s->tx_heartbeat_errors);
- if (carrier_changes)
- print_num(fp, 7, rta_getattr_u32(carrier_changes));
+ /* TX stats */
+ fprintf(fp, " TX: bytes packets errors dropped carrier collsns %s%s",
+ s->tx_compressed ? "compressed" : "", _SL_);
+
+ fprintf(fp, " ");
+ print_num(fp, 10, s->tx_bytes);
+ print_num(fp, 8, s->tx_packets);
+ print_num(fp, 7, s->tx_errors);
+ print_num(fp, 7, s->tx_dropped);
+ print_num(fp, 7, s->tx_carrier_errors);
+ print_num(fp, 7, s->collisions);
+ if (s->tx_compressed)
+ print_num(fp, 7, s->tx_compressed);
+
+ /* TX error stats */
+ if (show_stats > 1) {
+ fprintf(fp, "%s", _SL_);
+ fprintf(fp, " TX errors: aborted fifo window heartbeat");
+ if (carrier_changes)
+ fprintf(fp, " transns");
+ fprintf(fp, "%s", _SL_);
+
+ fprintf(fp, " ");
+ print_num(fp, 8, s->tx_aborted_errors);
+ print_num(fp, 7, s->tx_fifo_errors);
+ print_num(fp, 7, s->tx_window_errors);
+ print_num(fp, 7, s->tx_heartbeat_errors);
+ if (carrier_changes)
+ print_num(fp, 7,
+ rta_getattr_u32(carrier_changes));
+ }
}
}
static void print_link_stats32(FILE *fp, const struct rtnl_link_stats *s,
const struct rtattr *carrier_changes)
{
- /* RX stats */
- fprintf(fp, " RX: bytes packets errors dropped overrun mcast %s%s",
- s->rx_compressed ? "compressed" : "", _SL_);
-
-
- fprintf(fp, " ");
- print_num(fp, 10, s->rx_bytes);
- print_num(fp, 8, s->rx_packets);
- print_num(fp, 7, s->rx_errors);
- print_num(fp, 7, s->rx_dropped);
- print_num(fp, 7, s->rx_over_errors);
- print_num(fp, 7, s->multicast);
- if (s->rx_compressed)
- print_num(fp, 7, s->rx_compressed);
-
- /* RX error stats */
- if (show_stats > 1) {
- fprintf(fp, "%s", _SL_);
- fprintf(fp, " RX errors: length crc frame fifo missed%s%s",
- s->rx_nohandler ? " nohandler" : "", _SL_);
- fprintf(fp, " ");
- print_num(fp, 8, s->rx_length_errors);
- print_num(fp, 7, s->rx_crc_errors);
- print_num(fp, 7, s->rx_frame_errors);
- print_num(fp, 7, s->rx_fifo_errors);
- print_num(fp, 7, s->rx_missed_errors);
- if (s->rx_nohandler)
- print_num(fp, 7, s->rx_nohandler);
- }
- fprintf(fp, "%s", _SL_);
+ if (is_json_context()) {
+ open_json_object("stats");
+
+ /* RX stats */
+ open_json_object("rx");
+ print_uint(PRINT_JSON, "bytes", NULL, s->rx_bytes);
+ print_uint(PRINT_JSON, "packets", NULL, s->rx_packets);
+ print_uint(PRINT_JSON, "errors", NULL, s->rx_errors);
+ print_uint(PRINT_JSON, "dropped", NULL, s->rx_dropped);
+ print_uint(PRINT_JSON, "over_errors", NULL, s->rx_over_errors);
+ print_uint(PRINT_JSON, "multicast", NULL, s->multicast);
+ if (s->rx_compressed)
+ print_int(PRINT_JSON,
+ "compressed",
+ NULL, s->rx_compressed);
+
+ /* RX error stats */
+ if (show_stats > 1) {
+ print_uint(PRINT_JSON,
+ "length_errors",
+ NULL, s->rx_length_errors);
+ print_uint(PRINT_JSON,
+ "crc_errors",
+ NULL, s->rx_crc_errors);
+ print_uint(PRINT_JSON,
+ "frame_errors",
+ NULL, s->rx_frame_errors);
+ print_uint(PRINT_JSON,
+ "fifo_errors",
+ NULL, s->rx_fifo_errors);
+ print_uint(PRINT_JSON,
+ "missed_errors",
+ NULL, s->rx_missed_errors);
+ if (s->rx_nohandler)
+ print_int(PRINT_JSON,
+ "nohandler",
+ NULL, s->rx_nohandler);
+ }
+ close_json_object();
+
+ /* TX stats */
+ open_json_object("tx");
+ print_uint(PRINT_JSON, "bytes", NULL, s->tx_bytes);
+ print_uint(PRINT_JSON, "packets", NULL, s->tx_packets);
+ print_uint(PRINT_JSON, "errors", NULL, s->tx_errors);
+ print_uint(PRINT_JSON, "dropped", NULL, s->tx_dropped);
+ print_uint(PRINT_JSON,
+ "carrier_errors",
+ NULL, s->tx_carrier_errors);
+ print_uint(PRINT_JSON, "collisions", NULL, s->collisions);
+ if (s->tx_compressed)
+ print_int(PRINT_JSON,
+ "compressed",
+ NULL, s->tx_compressed);
+
+ /* TX error stats */
+ if (show_stats > 1) {
+ print_uint(PRINT_JSON,
+ "aborted_errors",
+ NULL, s->tx_aborted_errors);
+ print_uint(PRINT_JSON,
+ "fifo_errors",
+ NULL, s->tx_fifo_errors);
+ print_uint(PRINT_JSON,
+ "window_errors",
+ NULL, s->tx_window_errors);
+ print_uint(PRINT_JSON,
+ "heartbeat_errors",
+ NULL, s->tx_heartbeat_errors);
+ if (carrier_changes)
+ print_uint(PRINT_JSON,
+ "carrier_changes",
+ NULL,
+ rta_getattr_u32(carrier_changes));
+ }
- /* TX stats */
- fprintf(fp, " TX: bytes packets errors dropped carrier collsns %s%s",
- s->tx_compressed ? "compressed" : "", _SL_);
-
- fprintf(fp, " ");
- print_num(fp, 10, s->tx_bytes);
- print_num(fp, 8, s->tx_packets);
- print_num(fp, 7, s->tx_errors);
- print_num(fp, 7, s->tx_dropped);
- print_num(fp, 7, s->tx_carrier_errors);
- print_num(fp, 7, s->collisions);
- if (s->tx_compressed)
- print_num(fp, 7, s->tx_compressed);
-
- /* TX error stats */
- if (show_stats > 1) {
- fprintf(fp, "%s", _SL_);
- fprintf(fp, " TX errors: aborted fifo window heartbeat");
- if (carrier_changes)
- fprintf(fp, " transns");
+ close_json_object();
+ close_json_object();
+ } else {
+ /* RX stats */
+ fprintf(fp, " RX: bytes packets errors dropped overrun mcast %s%s",
+ s->rx_compressed ? "compressed" : "", _SL_);
+
+
+ fprintf(fp, " ");
+ print_num(fp, 10, s->rx_bytes);
+ print_num(fp, 8, s->rx_packets);
+ print_num(fp, 7, s->rx_errors);
+ print_num(fp, 7, s->rx_dropped);
+ print_num(fp, 7, s->rx_over_errors);
+ print_num(fp, 7, s->multicast);
+ if (s->rx_compressed)
+ print_num(fp, 7, s->rx_compressed);
+
+ /* RX error stats */
+ if (show_stats > 1) {
+ fprintf(fp, "%s", _SL_);
+ fprintf(fp, " RX errors: length crc frame fifo missed%s%s",
+ s->rx_nohandler ? " nohandler" : "", _SL_);
+ fprintf(fp, " ");
+ print_num(fp, 8, s->rx_length_errors);
+ print_num(fp, 7, s->rx_crc_errors);
+ print_num(fp, 7, s->rx_frame_errors);
+ print_num(fp, 7, s->rx_fifo_errors);
+ print_num(fp, 7, s->rx_missed_errors);
+ if (s->rx_nohandler)
+ print_num(fp, 7, s->rx_nohandler);
+ }
fprintf(fp, "%s", _SL_);
- fprintf(fp, " ");
- print_num(fp, 8, s->tx_aborted_errors);
- print_num(fp, 7, s->tx_fifo_errors);
- print_num(fp, 7, s->tx_window_errors);
- print_num(fp, 7, s->tx_heartbeat_errors);
- if (carrier_changes)
- print_num(fp, 7, rta_getattr_u32(carrier_changes));
+ /* TX stats */
+ fprintf(fp, " TX: bytes packets errors dropped carrier collsns %s%s",
+ s->tx_compressed ? "compressed" : "", _SL_);
+
+ fprintf(fp, " ");
+ print_num(fp, 10, s->tx_bytes);
+ print_num(fp, 8, s->tx_packets);
+ print_num(fp, 7, s->tx_errors);
+ print_num(fp, 7, s->tx_dropped);
+ print_num(fp, 7, s->tx_carrier_errors);
+ print_num(fp, 7, s->collisions);
+ if (s->tx_compressed)
+ print_num(fp, 7, s->tx_compressed);
+
+ /* TX error stats */
+ if (show_stats > 1) {
+ fprintf(fp, "%s", _SL_);
+ fprintf(fp, " TX errors: aborted fifo window heartbeat");
+ if (carrier_changes)
+ fprintf(fp, " transns");
+ fprintf(fp, "%s", _SL_);
+
+ fprintf(fp, " ");
+ print_num(fp, 8, s->tx_aborted_errors);
+ print_num(fp, 7, s->tx_fifo_errors);
+ print_num(fp, 7, s->tx_window_errors);
+ print_num(fp, 7, s->tx_heartbeat_errors);
+ if (carrier_changes)
+ print_num(fp, 7,
+ rta_getattr_u32(carrier_changes));
+ }
}
}
@@ -694,44 +980,50 @@ int print_linkinfo_brief(const struct sockaddr_nl *who,
return -1;
if (n->nlmsg_type == RTM_DELLINK)
- fprintf(fp, "Deleted ");
+ print_bool(PRINT_ANY, "deleted", "Deleted ", true);
if (tb[IFLA_LINK]) {
SPRINT_BUF(b1);
int iflink = rta_getattr_u32(tb[IFLA_LINK]);
- if (iflink == 0)
+ if (iflink == 0) {
snprintf(buf, sizeof(buf), "%s@NONE", name);
- else {
- snprintf(buf, sizeof(buf),
- "%s@%s", name, ll_idx_n2a(iflink, b1));
+ print_null(PRINT_JSON, "link", NULL, NULL);
+ } else {
+ const char *link = ll_idx_n2a(iflink, b1);
+
+ print_string(PRINT_JSON, "link", NULL, link);
+ snprintf(buf, sizeof(buf), "%s@%s", name, link);
m_flag = ll_index_to_flags(iflink);
m_flag = !(m_flag & IFF_UP);
}
} else
snprintf(buf, sizeof(buf), "%s", name);
- fprintf(fp, "%-16s ", buf);
+ print_string(PRINT_FP, NULL, "%-16s ", buf);
+ print_string(PRINT_JSON, "ifname", NULL, name);
if (tb[IFLA_OPERSTATE])
print_operstate(fp, rta_getattr_u8(tb[IFLA_OPERSTATE]));
if (pfilter->family == AF_PACKET) {
SPRINT_BUF(b1);
+
if (tb[IFLA_ADDRESS]) {
- color_fprintf(fp, COLOR_MAC, "%s ",
- ll_addr_n2a(RTA_DATA(tb[IFLA_ADDRESS]),
- RTA_PAYLOAD(tb[IFLA_ADDRESS]),
- ifi->ifi_type,
- b1, sizeof(b1)));
+ print_color_string(PRINT_ANY, COLOR_MAC,
+ "address", "%s ",
+ ll_addr_n2a(
+ RTA_DATA(tb[IFLA_ADDRESS]),
+ RTA_PAYLOAD(tb[IFLA_ADDRESS]),
+ ifi->ifi_type,
+ b1, sizeof(b1)));
}
}
- if (pfilter->family == AF_PACKET)
+ if (pfilter->family == AF_PACKET) {
print_link_flags(fp, ifi->ifi_flags, m_flag);
-
- if (pfilter->family == AF_PACKET)
- fprintf(fp, "\n");
+ print_string(PRINT_FP, NULL, "%s", "\n");
+ }
fflush(fp);
return 0;
}
@@ -749,10 +1041,12 @@ static const char *link_events[] = {
static void print_link_event(FILE *f, __u32 event)
{
if (event >= ARRAY_SIZE(link_events))
- fprintf(f, "event %d ", event);
+ print_int(PRINT_ANY, "event", "event %d ", event);
else {
if (event)
- fprintf(f, "event %s ", link_events[event]);
+ print_string(PRINT_ANY,
+ "event", "event %s ",
+ link_events[event]);
}
}
@@ -808,41 +1102,63 @@ int print_linkinfo(const struct sockaddr_nl *who,
return -1;
if (n->nlmsg_type == RTM_DELLINK)
- fprintf(fp, "Deleted ");
-
- fprintf(fp, "%d: ", ifi->ifi_index);
- color_fprintf(fp, COLOR_IFNAME, "%s",
- tb[IFLA_IFNAME] ? rta_getattr_str(tb[IFLA_IFNAME]) : "<nil>");
+ print_bool(PRINT_ANY, "deleted", "Deleted ", true);
+
+ print_int(PRINT_ANY, "ifindex", "%d: ", ifi->ifi_index);
+ if (tb[IFLA_IFNAME]) {
+ print_color_string(PRINT_ANY,
+ COLOR_IFNAME,
+ "ifname", "%s",
+ rta_getattr_str(tb[IFLA_IFNAME]));
+ } else {
+ print_null(PRINT_JSON, "ifname", NULL, NULL);
+ print_color_null(PRINT_FP, COLOR_IFNAME,
+ "ifname", "%s", "<nil>");
+ }
if (tb[IFLA_LINK]) {
- SPRINT_BUF(b1);
int iflink = rta_getattr_u32(tb[IFLA_LINK]);
if (iflink == 0)
- fprintf(fp, "@NONE: ");
+ print_null(PRINT_ANY, "link", "@%s: ", "NONE");
else {
if (tb[IFLA_LINK_NETNSID])
- fprintf(fp, "@if%d: ", iflink);
+ print_int(PRINT_ANY,
+ "link_index", "@if%d: ", iflink);
else {
- fprintf(fp, "@%s: ", ll_idx_n2a(iflink, b1));
+ SPRINT_BUF(b1);
+
+ print_string(PRINT_ANY,
+ "link",
+ "@%s: ",
+ ll_idx_n2a(iflink, b1));
m_flag = ll_index_to_flags(iflink);
m_flag = !(m_flag & IFF_UP);
}
}
} else {
- fprintf(fp, ": ");
+ print_string(PRINT_FP, NULL, ": ", NULL);
}
print_link_flags(fp, ifi->ifi_flags, m_flag);
if (tb[IFLA_MTU])
- fprintf(fp, "mtu %u ", rta_getattr_u32(tb[IFLA_MTU]));
+ print_int(PRINT_ANY,
+ "mtu", "mtu %u ",
+ rta_getattr_u32(tb[IFLA_MTU]));
if (tb[IFLA_XDP])
xdp_dump(fp, tb[IFLA_XDP]);
if (tb[IFLA_QDISC])
- fprintf(fp, "qdisc %s ", rta_getattr_str(tb[IFLA_QDISC]));
+ print_string(PRINT_ANY,
+ "qdisc",
+ "qdisc %s ",
+ rta_getattr_str(tb[IFLA_QDISC]));
if (tb[IFLA_MASTER]) {
SPRINT_BUF(b1);
- fprintf(fp, "master %s ", ll_idx_n2a(rta_getattr_u32(tb[IFLA_MASTER]), b1));
+
+ print_string(PRINT_ANY,
+ "master",
+ "master %s ",
+ ll_idx_n2a(rta_getattr_u32(tb[IFLA_MASTER]), b1));
}
if (tb[IFLA_OPERSTATE])
@@ -855,7 +1171,10 @@ int print_linkinfo(const struct sockaddr_nl *who,
SPRINT_BUF(b1);
int group = rta_getattr_u32(tb[IFLA_GROUP]);
- fprintf(fp, "group %s ", rtnl_group_n2a(group, b1, sizeof(b1)));
+ print_string(PRINT_ANY,
+ "group",
+ "group %s ",
+ rtnl_group_n2a(group, b1, sizeof(b1)));
}
if (filter.showqueue)
@@ -866,47 +1185,68 @@ int print_linkinfo(const struct sockaddr_nl *who,
if (!filter.family || filter.family == AF_PACKET || show_details) {
SPRINT_BUF(b1);
- fprintf(fp, "%s", _SL_);
- fprintf(fp, " link/%s ", ll_type_n2a(ifi->ifi_type, b1, sizeof(b1)));
+ print_string(PRINT_FP, NULL, "%s", _SL_);
+ print_string(PRINT_ANY,
+ "link_type",
+ " link/%s ",
+ ll_type_n2a(ifi->ifi_type, b1, sizeof(b1)));
if (tb[IFLA_ADDRESS]) {
- color_fprintf(fp, COLOR_MAC, "%s",
- ll_addr_n2a(RTA_DATA(tb[IFLA_ADDRESS]),
- RTA_PAYLOAD(tb[IFLA_ADDRESS]),
- ifi->ifi_type,
- b1, sizeof(b1)));
+ print_color_string(PRINT_ANY,
+ COLOR_MAC,
+ "address",
+ "%s",
+ ll_addr_n2a(RTA_DATA(tb[IFLA_ADDRESS]),
+ RTA_PAYLOAD(tb[IFLA_ADDRESS]),
+ ifi->ifi_type,
+ b1, sizeof(b1)));
}
if (tb[IFLA_BROADCAST]) {
- if (ifi->ifi_flags&IFF_POINTOPOINT)
- fprintf(fp, " peer ");
- else
- fprintf(fp, " brd ");
- color_fprintf(fp, COLOR_MAC, "%s",
- ll_addr_n2a(RTA_DATA(tb[IFLA_BROADCAST]),
- RTA_PAYLOAD(tb[IFLA_BROADCAST]),
- ifi->ifi_type,
- b1, sizeof(b1)));
+ if (ifi->ifi_flags&IFF_POINTOPOINT) {
+ print_string(PRINT_FP, NULL, " peer ", NULL);
+ print_bool(PRINT_JSON,
+ "link_pointtopoint", NULL, true);
+ } else {
+ print_string(PRINT_FP, NULL, " brd ", NULL);
+ }
+ print_color_string(PRINT_ANY,
+ COLOR_MAC,
+ "broadcast",
+ "%s",
+ ll_addr_n2a(RTA_DATA(tb[IFLA_BROADCAST]),
+ RTA_PAYLOAD(tb[IFLA_BROADCAST]),
+ ifi->ifi_type,
+ b1, sizeof(b1)));
}
}
if (tb[IFLA_LINK_NETNSID]) {
int id = rta_getattr_u32(tb[IFLA_LINK_NETNSID]);
- if (id >= 0)
- fprintf(fp, " link-netnsid %d", id);
- else
- fprintf(fp, " link-netnsid unknown");
+ if (is_json_context()) {
+ print_int(PRINT_JSON, "link_netnsid", NULL, id);
+ } else {
+ if (id >= 0)
+ print_int(PRINT_FP, NULL,
+ " link-netnsid %d", id);
+ else
+ print_string(PRINT_FP, NULL,
+ " link-netnsid %s", "unknown");
+ }
}
if (tb[IFLA_PROTO_DOWN]) {
if (rta_getattr_u8(tb[IFLA_PROTO_DOWN]))
- fprintf(fp, " protodown on ");
+ print_bool(PRINT_ANY,
+ "proto_down", " protodown on ", true);
}
if (show_details) {
if (tb[IFLA_PROMISCUITY])
- fprintf(fp, " promiscuity %u ",
- rta_getattr_u32(tb[IFLA_PROMISCUITY]));
+ print_uint(PRINT_ANY,
+ "promiscuity",
+ " promiscuity %u ",
+ rta_getattr_u32(tb[IFLA_PROMISCUITY]));
if (tb[IFLA_LINKINFO])
print_linktype(fp, tb[IFLA_LINKINFO]);
@@ -915,50 +1255,68 @@ int print_linkinfo(const struct sockaddr_nl *who,
print_af_spec(fp, tb[IFLA_AF_SPEC]);
if (tb[IFLA_NUM_TX_QUEUES])
- fprintf(fp, "numtxqueues %u ",
- rta_getattr_u32(tb[IFLA_NUM_TX_QUEUES]));
+ print_uint(PRINT_ANY,
+ "num_tx_queues",
+ "numtxqueues %u ",
+ rta_getattr_u32(tb[IFLA_NUM_TX_QUEUES]));
if (tb[IFLA_NUM_RX_QUEUES])
- fprintf(fp, "numrxqueues %u ",
- rta_getattr_u32(tb[IFLA_NUM_RX_QUEUES]));
+ print_uint(PRINT_ANY,
+ "num_rx_queues",
+ "numrxqueues %u ",
+ rta_getattr_u32(tb[IFLA_NUM_RX_QUEUES]));
if (tb[IFLA_GSO_MAX_SIZE])
- fprintf(fp, "gso_max_size %u ",
- rta_getattr_u32(tb[IFLA_GSO_MAX_SIZE]));
+ print_uint(PRINT_ANY,
+ "gso_max_size",
+ "gso_max_size %u ",
+ rta_getattr_u32(tb[IFLA_GSO_MAX_SIZE]));
if (tb[IFLA_GSO_MAX_SEGS])
- fprintf(fp, "gso_max_segs %u ",
- rta_getattr_u32(tb[IFLA_GSO_MAX_SEGS]));
+ print_uint(PRINT_ANY,
+ "gso_max_segs",
+ "gso_max_segs %u ",
+ rta_getattr_u32(tb[IFLA_GSO_MAX_SEGS]));
if (tb[IFLA_PHYS_PORT_NAME])
- fprintf(fp, "portname %s ",
- rta_getattr_str(tb[IFLA_PHYS_PORT_NAME]));
+ print_string(PRINT_ANY,
+ "phys_port_name",
+ "portname %s ",
+ rta_getattr_str(tb[IFLA_PHYS_PORT_NAME]));
if (tb[IFLA_PHYS_PORT_ID]) {
SPRINT_BUF(b1);
- fprintf(fp, "portid %s ",
- hexstring_n2a(RTA_DATA(tb[IFLA_PHYS_PORT_ID]),
- RTA_PAYLOAD(tb[IFLA_PHYS_PORT_ID]),
- b1, sizeof(b1)));
+ print_string(PRINT_ANY,
+ "phys_port_id",
+ "portid %s ",
+ hexstring_n2a(
+ RTA_DATA(tb[IFLA_PHYS_PORT_ID]),
+ RTA_PAYLOAD(tb[IFLA_PHYS_PORT_ID]),
+ b1, sizeof(b1)));
}
if (tb[IFLA_PHYS_SWITCH_ID]) {
SPRINT_BUF(b1);
- fprintf(fp, "switchid %s ",
- hexstring_n2a(RTA_DATA(tb[IFLA_PHYS_SWITCH_ID]),
- RTA_PAYLOAD(tb[IFLA_PHYS_SWITCH_ID]),
- b1, sizeof(b1)));
+ print_string(PRINT_ANY,
+ "phys_switch_id",
+ "switchid %s ",
+ hexstring_n2a(RTA_DATA(tb[IFLA_PHYS_SWITCH_ID]),
+ RTA_PAYLOAD(tb[IFLA_PHYS_SWITCH_ID]),
+ b1, sizeof(b1)));
}
}
if ((do_link || show_details) && tb[IFLA_IFALIAS]) {
- fprintf(fp, "%s alias %s", _SL_,
- rta_getattr_str(tb[IFLA_IFALIAS]));
+ print_string(PRINT_FP, NULL, "%s ", _SL_);
+ print_string(PRINT_ANY,
+ "ifalias",
+ "alias %s",
+ rta_getattr_str(tb[IFLA_IFALIAS]));
}
if (do_link && show_stats) {
- fprintf(fp, "%s", _SL_);
+ print_string(PRINT_FP, NULL, "%s", _SL_);
__print_link_stats(fp, tb);
}
@@ -966,11 +1324,16 @@ int print_linkinfo(const struct sockaddr_nl *who,
struct rtattr *i, *vflist = tb[IFLA_VFINFO_LIST];
int rem = RTA_PAYLOAD(vflist);
- for (i = RTA_DATA(vflist); RTA_OK(i, rem); i = RTA_NEXT(i, rem))
+ open_json_array(PRINT_JSON, "vfinfo_list");
+ for (i = RTA_DATA(vflist); RTA_OK(i, rem); i = RTA_NEXT(i, rem)) {
+ open_json_object(NULL);
print_vfinfo(fp, i);
+ close_json_object();
+ }
+ close_json_array(PRINT_JSON, NULL);
}
- fprintf(fp, "\n");
+ print_string(PRINT_FP, NULL, "\n", NULL);
fflush(fp);
return 1;
}
@@ -1009,7 +1372,7 @@ static unsigned int get_ifa_flags(struct ifaddrmsg *ifa,
struct rtattr *ifa_flags_attr)
{
return ifa_flags_attr ? rta_getattr_u32(ifa_flags_attr) :
- ifa->ifa_flags;
+ ifa->ifa_flags;
}
/* Mapping from argument to address flag mask */
@@ -1042,20 +1405,34 @@ static void print_ifa_flags(FILE *fp, const struct ifaddrmsg *ifa,
if (mask == IFA_F_PERMANENT) {
if (!(flags & mask))
- fprintf(fp, "dynamic ");
+ print_bool(PRINT_ANY,
+ "dynamic", "dynamic ", true);
} else if (flags & mask) {
if (mask == IFA_F_SECONDARY &&
- ifa->ifa_family == AF_INET6)
- fprintf(fp, "temporary ");
- else
- fprintf(fp, "%s ", ifa_flag_names[i].name);
+ ifa->ifa_family == AF_INET6) {
+ print_bool(PRINT_ANY,
+ "temporary", "temporary ", true);
+ } else {
+ print_string(PRINT_FP, NULL,
+ "%s ", ifa_flag_names[i].name);
+ print_bool(PRINT_JSON,
+ ifa_flag_names[i].name, NULL, true);
+ }
}
flags &= ~mask;
}
- if (flags)
- fprintf(fp, "flags %02x ", flags);
+ if (flags) {
+ if (is_json_context()) {
+ SPRINT_BUF(b1);
+
+ snprintf(b1, sizeof(b1), "%02x", flags);
+ print_string(PRINT_JSON, "ifa_flags", NULL, b1);
+ } else {
+ fprintf(fp, "flags %02x ", flags);
+ }
+ }
}
@@ -1176,80 +1553,130 @@ int print_addrinfo(const struct sockaddr_nl *who, struct nlmsghdr *n,
}
if (n->nlmsg_type == RTM_DELADDR)
- fprintf(fp, "Deleted ");
+ print_bool(PRINT_ANY, "deleted", "Deleted ", true);
if (!brief) {
- if (filter.oneline || filter.flushb)
- fprintf(fp, "%u: %s", ifa->ifa_index, ll_index_to_name(ifa->ifa_index));
+ if (filter.oneline || filter.flushb) {
+ const char *dev = ll_index_to_name(ifa->ifa_index);
+
+ if (is_json_context()) {
+ print_int(PRINT_JSON,
+ "index", NULL, ifa->ifa_index);
+ print_string(PRINT_JSON, "dev", NULL, dev);
+ } else {
+ fprintf(fp, "%u: %s", ifa->ifa_index, dev);
+ }
+ }
+
+ int family = ifa->ifa_family;
+
if (ifa->ifa_family == AF_INET)
- fprintf(fp, " inet ");
+ print_string(PRINT_ANY, "family", " %s ", "inet");
else if (ifa->ifa_family == AF_INET6)
- fprintf(fp, " inet6 ");
+ print_string(PRINT_ANY, "family", " %s ", "inet6");
else if (ifa->ifa_family == AF_DECnet)
- fprintf(fp, " dnet ");
+ print_string(PRINT_ANY, "family", " %s ", "dnet");
else if (ifa->ifa_family == AF_IPX)
- fprintf(fp, " ipx ");
+ print_string(PRINT_ANY, "family", " %s ", "ipx");
else
- fprintf(fp, " family %d ", ifa->ifa_family);
+ print_int(PRINT_ANY,
+ "family_index",
+ " family %d ", family);
}
if (rta_tb[IFA_LOCAL]) {
- color_fprintf(fp, ifa_family_color(ifa->ifa_family), "%s",
- format_host_rta(ifa->ifa_family,
- rta_tb[IFA_LOCAL]));
+ print_color_string(PRINT_ANY,
+ ifa_family_color(ifa->ifa_family),
+ "local", "%s",
+ format_host_rta(ifa->ifa_family,
+ rta_tb[IFA_LOCAL]));
if (rta_tb[IFA_ADDRESS] &&
memcmp(RTA_DATA(rta_tb[IFA_ADDRESS]),
RTA_DATA(rta_tb[IFA_LOCAL]),
ifa->ifa_family == AF_INET ? 4 : 16)) {
- fprintf(fp, " peer ");
- color_fprintf(fp, ifa_family_color(ifa->ifa_family),
- "%s", format_host_rta(ifa->ifa_family,
- rta_tb[IFA_ADDRESS]));
+ print_string(PRINT_FP, NULL, " %s ", "peer");
+ print_color_string(PRINT_ANY,
+ ifa_family_color(ifa->ifa_family),
+ "address",
+ "%s",
+ format_host_rta(ifa->ifa_family,
+ rta_tb[IFA_ADDRESS]));
}
- fprintf(fp, "/%d ", ifa->ifa_prefixlen);
+ print_int(PRINT_ANY, "prefixlen", "/%d", ifa->ifa_prefixlen);
}
if (brief)
goto brief_exit;
if (rta_tb[IFA_BROADCAST]) {
- fprintf(fp, "brd ");
- color_fprintf(fp, ifa_family_color(ifa->ifa_family), "%s ",
- format_host_rta(ifa->ifa_family,
- rta_tb[IFA_BROADCAST]));
+ print_string(PRINT_FP, NULL, "%s ", "brd");
+ print_color_string(PRINT_ANY,
+ ifa_family_color(ifa->ifa_family),
+ "broadcast",
+ "%s ",
+ format_host_rta(ifa->ifa_family,
+ rta_tb[IFA_BROADCAST]));
}
+
if (rta_tb[IFA_ANYCAST]) {
- fprintf(fp, "any ");
- color_fprintf(fp, ifa_family_color(ifa->ifa_family), "%s ",
- format_host_rta(ifa->ifa_family,
- rta_tb[IFA_ANYCAST]));
+ print_string(PRINT_FP, NULL, "%s ", "any");
+ print_color_string(PRINT_ANY,
+ ifa_family_color(ifa->ifa_family),
+ "anycast",
+ "%s ",
+ format_host_rta(ifa->ifa_family,
+ rta_tb[IFA_ANYCAST]));
}
- fprintf(fp, "scope %s ", rtnl_rtscope_n2a(ifa->ifa_scope, b1, sizeof(b1)));
+
+ print_string(PRINT_ANY,
+ "scope",
+ "scope %s ",
+ rtnl_rtscope_n2a(ifa->ifa_scope, b1, sizeof(b1)));
print_ifa_flags(fp, ifa, ifa_flags);
if (rta_tb[IFA_LABEL])
- fprintf(fp, "%s", rta_getattr_str(rta_tb[IFA_LABEL]));
+ print_string(PRINT_ANY,
+ "label",
+ "%s",
+ rta_getattr_str(rta_tb[IFA_LABEL]));
+
if (rta_tb[IFA_CACHEINFO]) {
struct ifa_cacheinfo *ci = RTA_DATA(rta_tb[IFA_CACHEINFO]);
- fprintf(fp, "%s", _SL_);
- fprintf(fp, " valid_lft ");
- if (ci->ifa_valid == INFINITY_LIFE_TIME)
- fprintf(fp, "forever");
- else
- fprintf(fp, "%usec", ci->ifa_valid);
- fprintf(fp, " preferred_lft ");
- if (ci->ifa_prefered == INFINITY_LIFE_TIME)
- fprintf(fp, "forever");
- else {
+ print_string(PRINT_FP, NULL, "%s", _SL_);
+ print_string(PRINT_FP, NULL, " valid_lft ", NULL);
+
+ if (ci->ifa_valid == INFINITY_LIFE_TIME) {
+ print_uint(PRINT_JSON,
+ "valid_life_time",
+ NULL, INFINITY_LIFE_TIME);
+ print_string(PRINT_FP, NULL, "%s", "forever");
+ } else {
+ print_uint(PRINT_ANY,
+ "valid_life_time", "%usec", ci->ifa_valid);
+ }
+
+ print_string(PRINT_FP, NULL, " preferred_lft ", NULL);
+ if (ci->ifa_prefered == INFINITY_LIFE_TIME) {
+ print_uint(PRINT_JSON,
+ "preferred_life_time",
+ NULL, INFINITY_LIFE_TIME);
+ print_string(PRINT_FP, NULL, "%s", "forever");
+ } else {
if (ifa_flags & IFA_F_DEPRECATED)
- fprintf(fp, "%dsec", ci->ifa_prefered);
+ print_int(PRINT_ANY,
+ "preferred_life_time",
+ "%dsec",
+ ci->ifa_prefered);
else
- fprintf(fp, "%usec", ci->ifa_prefered);
+ print_uint(PRINT_ANY,
+ "preferred_life_time",
+ "%usec",
+ ci->ifa_prefered);
}
}
- fprintf(fp, "\n");
+ print_string(PRINT_FP, NULL, "%s", "\n");
brief_exit:
fflush(fp);
return 0;
@@ -1258,6 +1685,7 @@ brief_exit:
static int print_selected_addrinfo(struct ifinfomsg *ifi,
struct nlmsg_list *ainfo, FILE *fp)
{
+ open_json_array(PRINT_JSON, "addr_info");
for ( ; ainfo ; ainfo = ainfo->next) {
struct nlmsghdr *n = &ainfo->h;
struct ifaddrmsg *ifa = NLMSG_DATA(n);
@@ -1275,10 +1703,14 @@ static int print_selected_addrinfo(struct ifinfomsg *ifi,
if (filter.up && !(ifi->ifi_flags&IFF_UP))
continue;
+ open_json_object(NULL);
print_addrinfo(NULL, n, fp);
+ close_json_object();
}
+ close_json_array(PRINT_JSON, NULL);
+
if (brief) {
- fprintf(fp, "\n");
+ print_string(PRINT_FP, NULL, "%s", "\n");
fflush(fp);
}
return 0;
@@ -1724,6 +2156,12 @@ static int ipaddr_list_flush_or_save(int argc, char **argv, int action)
exit(0);
}
+ /*
+ * Initialize a json_writer and open an array object
+ * if -json was specified.
+ */
+ new_json_obj(json, stdout);
+
/*
* If only filter_dev present and none of the other
* link filters are present, use RTM_GETLINK to get
@@ -1732,8 +2170,10 @@ static int ipaddr_list_flush_or_save(int argc, char **argv, int action)
if (filter_dev && filter.group == -1 && do_link == 1) {
if (iplink_get(0, filter_dev, RTEXT_FILTER_VF) < 0) {
perror("Cannot send link get request");
+ delete_json_obj();
exit(1);
}
+ delete_json_obj();
exit(0);
}
@@ -1755,6 +2195,7 @@ static int ipaddr_list_flush_or_save(int argc, char **argv, int action)
int res = 0;
struct ifinfomsg *ifi = NLMSG_DATA(&l->h);
+ open_json_object(NULL);
if (brief) {
if (print_linkinfo_brief(NULL, &l->h,
stdout, NULL) == 0)
@@ -1763,13 +2204,14 @@ static int ipaddr_list_flush_or_save(int argc, char **argv, int action)
ainfo->head,
stdout);
} else if (no_link ||
- (res = print_linkinfo(NULL, &l->h, stdout)) >= 0) {
+ (res = print_linkinfo(NULL, &l->h, stdout)) >= 0) {
if (filter.family != AF_PACKET)
print_selected_addrinfo(ifi,
ainfo->head, stdout);
if (res > 0 && !do_link && show_stats)
print_link_stats(stdout, &l->h);
}
+ close_json_object();
}
fflush(stdout);
@@ -1777,7 +2219,7 @@ out:
if (ainfo)
free_nlmsg_chain(ainfo);
free_nlmsg_chain(&linfo);
-
+ delete_json_obj();
return 0;
}