summaryrefslogtreecommitdiff
path: root/drivers/net/bonding/bond_3ad.c
diff options
context:
space:
mode:
authorNikolay Aleksandrov <nikolay@cumulusnetworks.com>2019-01-18 14:30:23 +0200
committerDavid S. Miller <davem@davemloft.net>2019-01-22 12:04:14 -0800
commita258aeacd7f0dc10bb45caa7e92a3ea3ca1a76e9 (patch)
tree048540eec82f15a4ebd86c8511373b0be843a3f8 /drivers/net/bonding/bond_3ad.c
parent267c095aa2d9126059c1f5a65c660d5a71833e3f (diff)
downloadlwn-a258aeacd7f0dc10bb45caa7e92a3ea3ca1a76e9.tar.gz
lwn-a258aeacd7f0dc10bb45caa7e92a3ea3ca1a76e9.zip
bonding: add support for xstats and export 3ad stats
This patch adds support for extended statistics (xstats) call to the bonding. The first user would be the 3ad code which counts the following events: - LACPDU Rx/Tx - LACPDU unknown type Rx - LACPDU illegal Rx - Marker Rx/Tx - Marker response Rx/Tx - Marker unknown type Rx All of these are exported via netlink as separate attributes to be easily extensible as we plan to add more in the future. Similar to how the bridge and other xstats exports, the structure inside is: [ IFLA_STATS_LINK_XSTATS ] -> [ LINK_XSTATS_TYPE_BOND ] -> [ BOND_XSTATS_3AD ] -> [ 3ad stats attributes ] With this structure it's easy to add more stat types later. Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/bonding/bond_3ad.c')
-rw-r--r--drivers/net/bonding/bond_3ad.c83
1 files changed, 83 insertions, 0 deletions
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
index d1d8cb6b8cdc..d30c21b34858 100644
--- a/drivers/net/bonding/bond_3ad.c
+++ b/drivers/net/bonding/bond_3ad.c
@@ -31,6 +31,7 @@
#include <net/net_namespace.h>
#include <net/bonding.h>
#include <net/bond_3ad.h>
+#include <net/netlink.h>
/* General definitions */
#define AD_SHORT_TIMEOUT 1
@@ -2696,3 +2697,85 @@ void bond_3ad_update_lacp_rate(struct bonding *bond)
}
spin_unlock_bh(&bond->mode_lock);
}
+
+void bond_3ad_stats_add(struct slave *slave, struct bond_3ad_stats *stats)
+{
+ struct bond_3ad_stats *rstats = &SLAVE_AD_INFO(slave)->stats;
+ u64 stat;
+
+ atomic64_add(atomic64_read(&rstats->lacpdu_rx), &stats->lacpdu_rx);
+ atomic64_add(atomic64_read(&rstats->lacpdu_tx), &stats->lacpdu_tx);
+
+ stat = atomic64_read(&rstats->lacpdu_unknown_rx);
+ atomic64_add(stat, &stats->lacpdu_unknown_rx);
+ stat = atomic64_read(&rstats->lacpdu_illegal_rx);
+ atomic64_add(stat, &stats->lacpdu_illegal_rx);
+
+ atomic64_add(atomic64_read(&rstats->marker_rx), &stats->marker_rx);
+ atomic64_add(atomic64_read(&rstats->marker_tx), &stats->marker_tx);
+
+ stat = atomic64_read(&rstats->marker_resp_rx);
+ atomic64_add(stat, &stats->marker_resp_rx);
+ stat = atomic64_read(&rstats->marker_resp_tx);
+ atomic64_add(stat, &stats->marker_resp_tx);
+ stat = atomic64_read(&rstats->marker_unknown_rx);
+ atomic64_add(stat, &stats->marker_unknown_rx);
+}
+
+size_t bond_3ad_stats_size(void)
+{
+ return nla_total_size_64bit(sizeof(u64)) + /* BOND_3AD_STAT_LACPDU_RX */
+ nla_total_size_64bit(sizeof(u64)) + /* BOND_3AD_STAT_LACPDU_TX */
+ nla_total_size_64bit(sizeof(u64)) + /* BOND_3AD_STAT_LACPDU_UNKNOWN_RX */
+ nla_total_size_64bit(sizeof(u64)) + /* BOND_3AD_STAT_LACPDU_ILLEGAL_RX */
+ nla_total_size_64bit(sizeof(u64)) + /* BOND_3AD_STAT_MARKER_RX */
+ nla_total_size_64bit(sizeof(u64)) + /* BOND_3AD_STAT_MARKER_TX */
+ nla_total_size_64bit(sizeof(u64)) + /* BOND_3AD_STAT_MARKER_RESP_RX */
+ nla_total_size_64bit(sizeof(u64)) + /* BOND_3AD_STAT_MARKER_RESP_TX */
+ nla_total_size_64bit(sizeof(u64)); /* BOND_3AD_STAT_MARKER_UNKNOWN_RX */
+}
+
+int bond_3ad_stats_fill(struct sk_buff *skb, struct bond_3ad_stats *stats)
+{
+ u64 val;
+
+ val = atomic64_read(&stats->lacpdu_rx);
+ if (nla_put_u64_64bit(skb, BOND_3AD_STAT_LACPDU_RX, val,
+ BOND_3AD_STAT_PAD))
+ return -EMSGSIZE;
+ val = atomic64_read(&stats->lacpdu_tx);
+ if (nla_put_u64_64bit(skb, BOND_3AD_STAT_LACPDU_TX, val,
+ BOND_3AD_STAT_PAD))
+ return -EMSGSIZE;
+ val = atomic64_read(&stats->lacpdu_unknown_rx);
+ if (nla_put_u64_64bit(skb, BOND_3AD_STAT_LACPDU_UNKNOWN_RX, val,
+ BOND_3AD_STAT_PAD))
+ return -EMSGSIZE;
+ val = atomic64_read(&stats->lacpdu_illegal_rx);
+ if (nla_put_u64_64bit(skb, BOND_3AD_STAT_LACPDU_ILLEGAL_RX, val,
+ BOND_3AD_STAT_PAD))
+ return -EMSGSIZE;
+
+ val = atomic64_read(&stats->marker_rx);
+ if (nla_put_u64_64bit(skb, BOND_3AD_STAT_MARKER_RX, val,
+ BOND_3AD_STAT_PAD))
+ return -EMSGSIZE;
+ val = atomic64_read(&stats->marker_tx);
+ if (nla_put_u64_64bit(skb, BOND_3AD_STAT_MARKER_TX, val,
+ BOND_3AD_STAT_PAD))
+ return -EMSGSIZE;
+ val = atomic64_read(&stats->marker_resp_rx);
+ if (nla_put_u64_64bit(skb, BOND_3AD_STAT_MARKER_RESP_RX, val,
+ BOND_3AD_STAT_PAD))
+ return -EMSGSIZE;
+ val = atomic64_read(&stats->marker_resp_tx);
+ if (nla_put_u64_64bit(skb, BOND_3AD_STAT_MARKER_RESP_TX, val,
+ BOND_3AD_STAT_PAD))
+ return -EMSGSIZE;
+ val = atomic64_read(&stats->marker_unknown_rx);
+ if (nla_put_u64_64bit(skb, BOND_3AD_STAT_MARKER_UNKNOWN_RX, val,
+ BOND_3AD_STAT_PAD))
+ return -EMSGSIZE;
+
+ return 0;
+}