From patchwork Tue Mar 12 16:41:28 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nikolay Aleksandrov X-Patchwork-Id: 1055545 X-Patchwork-Delegate: dsahern@gmail.com Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=cumulusnetworks.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=cumulusnetworks.com header.i=@cumulusnetworks.com header.b="RjYNr4fu"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 44Jgn02Bp2z9s5c for ; Wed, 13 Mar 2019 03:44:52 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726832AbfCLQov (ORCPT ); Tue, 12 Mar 2019 12:44:51 -0400 Received: from mail-wr1-f68.google.com ([209.85.221.68]:46128 "EHLO mail-wr1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726512AbfCLQot (ORCPT ); Tue, 12 Mar 2019 12:44:49 -0400 Received: by mail-wr1-f68.google.com with SMTP id 33so957376wrb.13 for ; Tue, 12 Mar 2019 09:44:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cumulusnetworks.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=4b08YIs5Xng5lqaGlS7OJKfvE3bnZL3WoMo4VtBH+JA=; b=RjYNr4fu/vuTbfeT2tsDxNQtSj0aWBd9eoh3ERdgyWLk4Fwg4Y9qiMhJHtezMp8K3y JXkyLCwSrswQXfTe0+gR1Q1voUdvvwPJNmxju6HR5t4eccnp4zRHsCww3A+GaL+OfMKa Qo5+lxNFEOixkqF1cL+P2DCepkqUoVEM5tIIM= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=4b08YIs5Xng5lqaGlS7OJKfvE3bnZL3WoMo4VtBH+JA=; b=sIIWlQk9waxn6zGvfxzvkV/c5YoiO+jf3o1ex5dsOJq0w+VucNzfzTXVCUk5zpIQL6 9pGPTdv29xCHmDmLkTYojBOPnoApEm5/7fHxVvxXFjGcVlOYRHJ3WLk2jN+gv3HBj8RZ KseBtJfx9Y3iV/kPxTXTa2/dcoNwEw39/70VBJD298b51ysJIhV/ML/pyn2ihZPiV45f hHHKdUQNFWkEBfacSHS7CJKx35zcd86PH2U8tSWGvqqonEmxRReJ+dIcGC18PtCu8BbX 65viCU7OC/RPzHdn23zCvfCYOs5MIp9R8y7yg9EQfLI63GyKT0i+4h7QkRF43NnXtcmA cwyA== X-Gm-Message-State: APjAAAWeM32x1qpfngsZQI5wm0YaDwFFMHNgVvCqlNxQ/9SWDEINp6W6 PvnhIfc7USAreac5rDqSb0VMKNj6p9Q= X-Google-Smtp-Source: APXvYqzWy4fjpjwlMWyz7eu6QtgjayyEAHc24Bn0CkZ3kOMONJ1rLnqXVMKtDWNnn5Ivy5X1nkxq2w== X-Received: by 2002:adf:a749:: with SMTP id e9mr23369801wrd.210.1552409086438; Tue, 12 Mar 2019 09:44:46 -0700 (PDT) Received: from localhost.localdomain ([93.152.141.58]) by smtp.gmail.com with ESMTPSA id b195sm5634864wmg.36.2019.03.12.09.44.45 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 12 Mar 2019 09:44:45 -0700 (PDT) From: Nikolay Aleksandrov To: netdev@vger.kernel.org Cc: roopa@cumulusnetworks.com, dsa@cumulusnetworks.com, stephen@networkplumber.org, Nikolay Aleksandrov Subject: [PATCH iproute2-next 3/3] ip: bond: add xstats support Date: Tue, 12 Mar 2019 18:41:28 +0200 Message-Id: <20190312164128.22536-4-nikolay@cumulusnetworks.com> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20190312164128.22536-1-nikolay@cumulusnetworks.com> References: <20190312164128.22536-1-nikolay@cumulusnetworks.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org 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 --- 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 #include #include -#include -#include -#include +#include #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, };