]> git.proxmox.com Git - mirror_iproute2.git/blobdiff - ip/iplink_bridge.c
ip: bridge: add xstats json support
[mirror_iproute2.git] / ip / iplink_bridge.c
index fbf8a79bfbbb6ec7009db1d9cb26e6059091acb3..e9b77fdfe3775ad732c10849a24767e9362417a9 100644 (file)
@@ -670,7 +670,7 @@ static void bridge_print_xstats_help(struct link_util *lu, FILE *f)
        fprintf(f, "Usage: ... %s [ igmp ] [ dev DEVICE ]\n", lu->id);
 }
 
-static void bridge_print_stats_attr(FILE *f, struct rtattr *attr, int ifindex)
+static void bridge_print_stats_attr(struct rtattr *attr, int ifindex)
 {
        struct rtattr *brtb[LINK_XSTATS_TYPE_MAX+1];
        struct br_mcast_stats *mstats;
@@ -685,76 +685,116 @@ static void bridge_print_stats_attr(FILE *f, struct rtattr *attr, int ifindex)
 
        list = brtb[LINK_XSTATS_TYPE_BRIDGE];
        rem = RTA_PAYLOAD(list);
+       open_json_object(NULL);
+       ifname = ll_index_to_name(ifindex);
+       print_string(PRINT_ANY, "ifname", "%-16s\n", ifname);
        for (i = RTA_DATA(list); RTA_OK(i, rem); i = RTA_NEXT(i, rem)) {
                if (xstats_print_attr && i->rta_type != xstats_print_attr)
                        continue;
                switch (i->rta_type) {
                case BRIDGE_XSTATS_MCAST:
                        mstats = RTA_DATA(i);
-                       ifname = ll_index_to_name(ifindex);
-                       fprintf(f, "%-16s\n", ifname);
-                       fprintf(f, "%-16s    IGMP queries:\n", "");
-                       fprintf(f, "%-16s      RX: v1 %llu v2 %llu v3 %llu\n",
-                               "",
-                               mstats->igmp_v1queries[BR_MCAST_DIR_RX],
-                               mstats->igmp_v2queries[BR_MCAST_DIR_RX],
-                               mstats->igmp_v3queries[BR_MCAST_DIR_RX]);
-                       fprintf(f, "%-16s      TX: v1 %llu v2 %llu v3 %llu\n",
-                               "",
-                               mstats->igmp_v1queries[BR_MCAST_DIR_TX],
-                               mstats->igmp_v2queries[BR_MCAST_DIR_TX],
-                               mstats->igmp_v3queries[BR_MCAST_DIR_TX]);
-
-                       fprintf(f, "%-16s    IGMP reports:\n", "");
-                       fprintf(f, "%-16s      RX: v1 %llu v2 %llu v3 %llu\n",
-                               "",
-                               mstats->igmp_v1reports[BR_MCAST_DIR_RX],
-                               mstats->igmp_v2reports[BR_MCAST_DIR_RX],
-                               mstats->igmp_v3reports[BR_MCAST_DIR_RX]);
-                       fprintf(f, "%-16s      TX: v1 %llu v2 %llu v3 %llu\n",
-                               "",
-                               mstats->igmp_v1reports[BR_MCAST_DIR_TX],
-                               mstats->igmp_v2reports[BR_MCAST_DIR_TX],
-                               mstats->igmp_v3reports[BR_MCAST_DIR_TX]);
-
-                       fprintf(f, "%-16s    IGMP leaves: RX: %llu TX: %llu\n",
-                               "",
-                               mstats->igmp_leaves[BR_MCAST_DIR_RX],
-                               mstats->igmp_leaves[BR_MCAST_DIR_TX]);
-
-                       fprintf(f, "%-16s    IGMP parse errors: %llu\n",
-                               "", mstats->igmp_parse_errors);
-
-                       fprintf(f, "%-16s    MLD queries:\n", "");
-                       fprintf(f, "%-16s      RX: v1 %llu v2 %llu\n",
-                               "",
-                               mstats->mld_v1queries[BR_MCAST_DIR_RX],
-                               mstats->mld_v2queries[BR_MCAST_DIR_RX]);
-                       fprintf(f, "%-16s      TX: v1 %llu v2 %llu\n",
-                               "",
-                               mstats->mld_v1queries[BR_MCAST_DIR_TX],
-                               mstats->mld_v2queries[BR_MCAST_DIR_TX]);
-
-                       fprintf(f, "%-16s    MLD reports:\n", "");
-                       fprintf(f, "%-16s      RX: v1 %llu v2 %llu\n",
-                               "",
-                               mstats->mld_v1reports[BR_MCAST_DIR_RX],
-                               mstats->mld_v2reports[BR_MCAST_DIR_RX]);
-                       fprintf(f, "%-16s      TX: v1 %llu v2 %llu\n",
-                               "",
-                               mstats->mld_v1reports[BR_MCAST_DIR_TX],
-                               mstats->mld_v2reports[BR_MCAST_DIR_TX]);
-
-                       fprintf(f, "%-16s    MLD leaves: RX: %llu TX: %llu\n",
-                               "",
-                               mstats->mld_leaves[BR_MCAST_DIR_RX],
-                               mstats->mld_leaves[BR_MCAST_DIR_TX]);
-
-                       fprintf(f, "%-16s    MLD parse errors: %llu\n",
-                               "", mstats->mld_parse_errors);
+                       open_json_object("multicast");
+                       open_json_object("igmp_queries");
+                       print_string(PRINT_FP, NULL,
+                                    "%-16s    IGMP queries:\n", "");
+                       print_string(PRINT_FP, NULL, "%-16s      ", "");
+                       print_u64(PRINT_ANY, "rx_v1", "RX: v1 %llu ",
+                                 mstats->igmp_v1queries[BR_MCAST_DIR_RX]);
+                       print_u64(PRINT_ANY, "rx_v2", "v2 %llu ",
+                                 mstats->igmp_v2queries[BR_MCAST_DIR_RX]);
+                       print_u64(PRINT_ANY, "rx_v3", "v3 %llu\n",
+                                 mstats->igmp_v3queries[BR_MCAST_DIR_RX]);
+                       print_string(PRINT_FP, NULL, "%-16s      ", "");
+                       print_u64(PRINT_ANY, "tx_v1", "TX: v1 %llu ",
+                                 mstats->igmp_v1queries[BR_MCAST_DIR_TX]);
+                       print_u64(PRINT_ANY, "tx_v2", "v2 %llu ",
+                                 mstats->igmp_v2queries[BR_MCAST_DIR_TX]);
+                       print_u64(PRINT_ANY, "tx_v3", "v3 %llu\n",
+                                 mstats->igmp_v3queries[BR_MCAST_DIR_TX]);
+                       close_json_object();
+
+                       open_json_object("igmp_reports");
+                       print_string(PRINT_FP, NULL,
+                                    "%-16s    IGMP reports:\n", "");
+                       print_string(PRINT_FP, NULL, "%-16s      ", "");
+                       print_u64(PRINT_ANY, "rx_v1", "RX: v1 %llu ",
+                                 mstats->igmp_v1reports[BR_MCAST_DIR_RX]);
+                       print_u64(PRINT_ANY, "rx_v2", "v2 %llu ",
+                                 mstats->igmp_v2reports[BR_MCAST_DIR_RX]);
+                       print_u64(PRINT_ANY, "rx_v3", "v3 %llu\n",
+                                 mstats->igmp_v3reports[BR_MCAST_DIR_RX]);
+                       print_string(PRINT_FP, NULL, "%-16s      ", "");
+                       print_u64(PRINT_ANY, "tx_v1", "TX: v1 %llu ",
+                                 mstats->igmp_v1reports[BR_MCAST_DIR_TX]);
+                       print_u64(PRINT_ANY, "tx_v2", "v2 %llu",
+                                 mstats->igmp_v2reports[BR_MCAST_DIR_TX]);
+                       print_u64(PRINT_ANY, "tx_v3", "v3 %llu\n",
+                                 mstats->igmp_v3reports[BR_MCAST_DIR_TX]);
+                       close_json_object();
+
+                       open_json_object("igmp_leaves");
+                       print_string(PRINT_FP, NULL,
+                                    "%-16s    IGMP leaves: ", "");
+                       print_u64(PRINT_ANY, "rx", "RX: %llu ",
+                                 mstats->igmp_leaves[BR_MCAST_DIR_RX]);
+                       print_u64(PRINT_ANY, "tx", "TX: %llu\n",
+                                 mstats->igmp_leaves[BR_MCAST_DIR_TX]);
+                       close_json_object();
+
+                       print_string(PRINT_FP, NULL,
+                                    "%-16s    IGMP parse errors: ", "");
+                       print_u64(PRINT_ANY, "igmp_parse_errors", "%llu\n",
+                                 mstats->igmp_parse_errors);
+
+                       open_json_object("mld_queries");
+                       print_string(PRINT_FP, NULL,
+                                    "%-16s    MLD queries:\n", "");
+                       print_string(PRINT_FP, NULL, "%-16s      ", "");
+                       print_u64(PRINT_ANY, "rx_v1", "RX: v1 %llu ",
+                                 mstats->mld_v1queries[BR_MCAST_DIR_RX]);
+                       print_u64(PRINT_ANY, "rx_v2", "v2 %llu\n",
+                                 mstats->mld_v2queries[BR_MCAST_DIR_RX]);
+                       print_string(PRINT_FP, NULL, "%-16s      ", "");
+                       print_u64(PRINT_ANY, "tx_v1", "TX: v1 %llu ",
+                                 mstats->mld_v1queries[BR_MCAST_DIR_TX]);
+                       print_u64(PRINT_ANY, "tx_v2", "v2 %llu\n",
+                                 mstats->mld_v2queries[BR_MCAST_DIR_TX]);
+                       close_json_object();
+
+                       open_json_object("mld_reports");
+                       print_string(PRINT_FP, NULL,
+                                    "%-16s    MLD reports:\n", "");
+                       print_string(PRINT_FP, NULL, "%-16s      ", "");
+                       print_u64(PRINT_ANY, "rx_v1", "RX: v1 %llu ",
+                                 mstats->mld_v1reports[BR_MCAST_DIR_RX]);
+                       print_u64(PRINT_ANY, "rx_v2", "v2 %llu\n",
+                                 mstats->mld_v2reports[BR_MCAST_DIR_RX]);
+                       print_string(PRINT_FP, NULL, "%-16s      ", "");
+                       print_u64(PRINT_ANY, "tx_v1", "TX: v1 %llu ",
+                                 mstats->mld_v1reports[BR_MCAST_DIR_TX]);
+                       print_u64(PRINT_ANY, "tx_v2", "v2 %llu\n",
+                                 mstats->mld_v2reports[BR_MCAST_DIR_TX]);
+                       close_json_object();
+
+                       open_json_object("mld_leaves");
+                       print_string(PRINT_FP, NULL,
+                                    "%-16s    MLD leaves: ", "");
+                       print_u64(PRINT_ANY, "rx", "RX: %llu ",
+                                 mstats->mld_leaves[BR_MCAST_DIR_RX]);
+                       print_u64(PRINT_ANY, "tx", "TX: %llu\n",
+                                 mstats->mld_leaves[BR_MCAST_DIR_TX]);
+                       close_json_object();
+
+                       print_string(PRINT_FP, NULL,
+                                    "%-16s    MLD parse errors: ", "");
+                       print_u64(PRINT_ANY, "mld_parse_errors", "%llu\n",
+                                 mstats->mld_parse_errors);
+                       close_json_object();
                        break;
                }
        }
+       close_json_object();
 }
 
 int bridge_print_xstats(struct nlmsghdr *n, void *arg)
@@ -762,7 +802,6 @@ int bridge_print_xstats(struct nlmsghdr *n, void *arg)
        struct if_stats_msg *ifsm = NLMSG_DATA(n);
        struct rtattr *tb[IFLA_STATS_MAX+1];
        int len = n->nlmsg_len;
-       FILE *fp = arg;
 
        len -= NLMSG_LENGTH(sizeof(*ifsm));
        if (len < 0) {
@@ -774,11 +813,11 @@ int bridge_print_xstats(struct nlmsghdr *n, void *arg)
 
        parse_rtattr(tb, IFLA_STATS_MAX, IFLA_STATS_RTA(ifsm), len);
        if (tb[IFLA_STATS_LINK_XSTATS])
-               bridge_print_stats_attr(fp, tb[IFLA_STATS_LINK_XSTATS],
+               bridge_print_stats_attr(tb[IFLA_STATS_LINK_XSTATS],
                                        ifsm->ifindex);
 
        if (tb[IFLA_STATS_LINK_XSTATS_SLAVE])
-               bridge_print_stats_attr(fp, tb[IFLA_STATS_LINK_XSTATS_SLAVE],
+               bridge_print_stats_attr(tb[IFLA_STATS_LINK_XSTATS_SLAVE],
                                        ifsm->ifindex);
 
        return 0;