[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20190312164128.22536-4-nikolay@cumulusnetworks.com>
Date: Tue, 12 Mar 2019 18:41:28 +0200
From: Nikolay Aleksandrov <nikolay@...ulusnetworks.com>
To: netdev@...r.kernel.org
Cc: roopa@...ulusnetworks.com, dsa@...ulusnetworks.com,
stephen@...workplumber.org,
Nikolay Aleksandrov <nikolay@...ulusnetworks.com>
Subject: [PATCH iproute2-next 3/3] ip: bond: add xstats support
Add bond and bond_slave xstats support with optional json output.
Example:
- Plain text:
$ ip link xstats type bond 802.3ad
bond0
LACPDU Rx 2017
LACPDU Tx 2038
LACPDU Unknown type Rx 0
LACPDU Illegal Rx 0
Marker Rx 0
Marker Tx 0
Marker response Rx 0
Marker response Tx 0
Marker unknown type Rx 0
- JSON:
$ ip -j -p link xstats type bond 802.3ad
[ {
"ifname": "bond0",
"802.3ad": {
"lacpdu_rx": 219,
"lacpdu_tx": 241,
"lacpdu_unknown_rx": 0,
"lacpdu_illegal_rx": 0,
"marker_rx": 0,
"marker_tx": 0,
"marker_response_rx": 0,
"marker_response_tx": 0,
"marker_unknown_rx": 0
}
} ]
Signed-off-by: Nikolay Aleksandrov <nikolay@...ulusnetworks.com>
---
ip/ip_common.h | 3 +
ip/iplink_bond.c | 167 ++++++++++++++++++++++++++++++++++++++++-
ip/iplink_bond_slave.c | 2 +
3 files changed, 169 insertions(+), 3 deletions(-)
diff --git a/ip/ip_common.h b/ip/ip_common.h
index d67575c63c24..b4aa34a70c92 100644
--- a/ip/ip_common.h
+++ b/ip/ip_common.h
@@ -130,6 +130,9 @@ void br_dump_bridge_id(const struct ifla_bridge_id *id, char *buf, size_t len);
int bridge_parse_xstats(struct link_util *lu, int argc, char **argv);
int bridge_print_xstats(struct nlmsghdr *n, void *arg);
+int bond_parse_xstats(struct link_util *lu, int argc, char **argv);
+int bond_print_xstats(struct nlmsghdr *n, void *arg);
+
/* iproute_lwtunnel.c */
int lwt_parse_encap(struct rtattr *rta, size_t len, int *argcp, char ***argvp);
void lwt_print_encap(FILE *fp, struct rtattr *encap_type, struct rtattr *encap);
diff --git a/ip/iplink_bond.c b/ip/iplink_bond.c
index f906e7f1b323..c60f0e8ad0a0 100644
--- a/ip/iplink_bond.c
+++ b/ip/iplink_bond.c
@@ -13,16 +13,18 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <linux/if_link.h>
-#include <linux/if_ether.h>
-#include <net/if.h>
+#include <linux/if_bonding.h>
#include "rt_names.h"
#include "utils.h"
#include "ip_common.h"
+#include "json_print.h"
#define BOND_MAX_ARP_TARGETS 16
+static unsigned int xstats_print_attr;
+static int filter_index;
+
static const char *mode_tbl[] = {
"balance-rr",
"active-backup",
@@ -649,10 +651,169 @@ static void bond_print_help(struct link_util *lu, int argc, char **argv,
print_explain(f);
}
+static void bond_print_xstats_help(struct link_util *lu, FILE *f)
+{
+ fprintf(f, "Usage: ... %s [ 802.3ad ] [ dev DEVICE ]\n", lu->id);
+}
+
+static void bond_print_3ad_stats(struct rtattr *lacpattr)
+{
+ struct rtattr *lacptb[BOND_3AD_STAT_MAX+1];
+ __u64 val;
+
+ parse_rtattr(lacptb, BOND_3AD_STAT_MAX, RTA_DATA(lacpattr),
+ RTA_PAYLOAD(lacpattr));
+ open_json_object("802.3ad");
+ if (lacptb[BOND_3AD_STAT_LACPDU_RX]) {
+ print_string(PRINT_FP, NULL, "%-16s ", "");
+ print_u64(PRINT_ANY, "lacpdu_rx", "LACPDU Rx %llu\n",
+ rta_getattr_u64(lacptb[BOND_3AD_STAT_LACPDU_RX]));
+ }
+ if (lacptb[BOND_3AD_STAT_LACPDU_TX]) {
+ print_string(PRINT_FP, NULL, "%-16s ", "");
+ print_u64(PRINT_ANY, "lacpdu_tx", "LACPDU Tx %llu\n",
+ rta_getattr_u64(lacptb[BOND_3AD_STAT_LACPDU_TX]));
+ }
+ if (lacptb[BOND_3AD_STAT_LACPDU_UNKNOWN_RX]) {
+ print_string(PRINT_FP, NULL, "%-16s ", "");
+ val = rta_getattr_u64(lacptb[BOND_3AD_STAT_LACPDU_UNKNOWN_RX]);
+ print_u64(PRINT_ANY,
+ "lacpdu_unknown_rx",
+ "LACPDU Unknown type Rx %llu\n",
+ val);
+ }
+ if (lacptb[BOND_3AD_STAT_LACPDU_ILLEGAL_RX]) {
+ print_string(PRINT_FP, NULL, "%-16s ", "");
+ val = rta_getattr_u64(lacptb[BOND_3AD_STAT_LACPDU_ILLEGAL_RX]);
+ print_u64(PRINT_ANY,
+ "lacpdu_illegal_rx",
+ "LACPDU Illegal Rx %llu\n",
+ val);
+ }
+ if (lacptb[BOND_3AD_STAT_MARKER_RX]) {
+ print_string(PRINT_FP, NULL, "%-16s ", "");
+ print_u64(PRINT_ANY, "marker_rx", "Marker Rx %llu\n",
+ rta_getattr_u64(lacptb[BOND_3AD_STAT_MARKER_RX]));
+ }
+ if (lacptb[BOND_3AD_STAT_MARKER_TX]) {
+ print_string(PRINT_FP, NULL, "%-16s ", "");
+ print_u64(PRINT_ANY, "marker_tx", "Marker Tx %llu\n",
+ rta_getattr_u64(lacptb[BOND_3AD_STAT_MARKER_TX]));
+ }
+ if (lacptb[BOND_3AD_STAT_MARKER_RESP_RX]) {
+ print_string(PRINT_FP, NULL, "%-16s ", "");
+ val = rta_getattr_u64(lacptb[BOND_3AD_STAT_MARKER_RESP_RX]);
+ print_u64(PRINT_ANY,
+ "marker_response_rx",
+ "Marker response Rx %llu\n",
+ val);
+ }
+ if (lacptb[BOND_3AD_STAT_MARKER_RESP_TX]) {
+ print_string(PRINT_FP, NULL, "%-16s ", "");
+ val = rta_getattr_u64(lacptb[BOND_3AD_STAT_MARKER_RESP_TX]);
+ print_u64(PRINT_ANY,
+ "marker_response_tx",
+ "Marker response Tx %llu\n",
+ val);
+ }
+ if (lacptb[BOND_3AD_STAT_MARKER_UNKNOWN_RX]) {
+ print_string(PRINT_FP, NULL, "%-16s ", "");
+ val = rta_getattr_u64(lacptb[BOND_3AD_STAT_MARKER_UNKNOWN_RX]);
+ print_u64(PRINT_ANY,
+ "marker_unknown_rx",
+ "Marker unknown type Rx %llu\n",
+ val);
+ }
+ close_json_object();
+}
+
+static void bond_print_stats_attr(struct rtattr *attr, int ifindex)
+{
+ struct rtattr *bondtb[LINK_XSTATS_TYPE_MAX+1];
+ struct rtattr *i, *list;
+ const char *ifname = "";
+ int rem;
+
+ parse_rtattr(bondtb, LINK_XSTATS_TYPE_MAX+1, RTA_DATA(attr),
+ RTA_PAYLOAD(attr));
+ if (!bondtb[LINK_XSTATS_TYPE_BOND])
+ return;
+
+ list = bondtb[LINK_XSTATS_TYPE_BOND];
+ 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 BOND_XSTATS_3AD:
+ bond_print_3ad_stats(i);
+ break;
+ }
+ break;
+ }
+ close_json_object();
+}
+
+int bond_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;
+
+ len -= NLMSG_LENGTH(sizeof(*ifsm));
+ if (len < 0) {
+ fprintf(stderr, "BUG: wrong nlmsg len %d\n", len);
+ return -1;
+ }
+ if (filter_index && filter_index != ifsm->ifindex)
+ return 0;
+
+ parse_rtattr(tb, IFLA_STATS_MAX, IFLA_STATS_RTA(ifsm), len);
+ if (tb[IFLA_STATS_LINK_XSTATS])
+ bond_print_stats_attr(tb[IFLA_STATS_LINK_XSTATS],
+ ifsm->ifindex);
+
+ if (tb[IFLA_STATS_LINK_XSTATS_SLAVE])
+ bond_print_stats_attr(tb[IFLA_STATS_LINK_XSTATS_SLAVE],
+ ifsm->ifindex);
+
+ return 0;
+}
+
+int bond_parse_xstats(struct link_util *lu, int argc, char **argv)
+{
+ while (argc > 0) {
+ if (strcmp(*argv, "lacp") == 0 ||
+ strcmp(*argv, "802.3ad") == 0) {
+ xstats_print_attr = BOND_XSTATS_3AD;
+ } else if (strcmp(*argv, "dev") == 0) {
+ NEXT_ARG();
+ filter_index = ll_name_to_index(*argv);
+ if (!filter_index)
+ return nodev(*argv);
+ } else if (strcmp(*argv, "help") == 0) {
+ bond_print_xstats_help(lu, stdout);
+ exit(0);
+ } else {
+ invarg("unknown attribute", *argv);
+ }
+ argc--; argv++;
+ }
+
+ return 0;
+}
+
+
struct link_util bond_link_util = {
.id = "bond",
.maxattr = IFLA_BOND_MAX,
.parse_opt = bond_parse_opt,
.print_opt = bond_print_opt,
.print_help = bond_print_help,
+ .parse_ifla_xstats = bond_parse_xstats,
+ .print_ifla_xstats = bond_print_xstats,
};
diff --git a/ip/iplink_bond_slave.c b/ip/iplink_bond_slave.c
index 67219c67241b..4eaf72b86f59 100644
--- a/ip/iplink_bond_slave.c
+++ b/ip/iplink_bond_slave.c
@@ -156,4 +156,6 @@ struct link_util bond_slave_link_util = {
.print_opt = bond_slave_print_opt,
.parse_opt = bond_slave_parse_opt,
.print_help = bond_slave_print_help,
+ .parse_ifla_xstats = bond_parse_xstats,
+ .print_ifla_xstats = bond_print_xstats,
};
--
2.17.2
Powered by blists - more mailing lists