Skip to content

Commit a258aea

Browse files
Nikolay Aleksandrovdavem330
authored andcommitted
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>
1 parent 267c095 commit a258aea

File tree

5 files changed

+182
-0
lines changed

5 files changed

+182
-0
lines changed

drivers/net/bonding/bond_3ad.c

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include <net/net_namespace.h>
3232
#include <net/bonding.h>
3333
#include <net/bond_3ad.h>
34+
#include <net/netlink.h>
3435

3536
/* General definitions */
3637
#define AD_SHORT_TIMEOUT 1
@@ -2696,3 +2697,85 @@ void bond_3ad_update_lacp_rate(struct bonding *bond)
26962697
}
26972698
spin_unlock_bh(&bond->mode_lock);
26982699
}
2700+
2701+
void bond_3ad_stats_add(struct slave *slave, struct bond_3ad_stats *stats)
2702+
{
2703+
struct bond_3ad_stats *rstats = &SLAVE_AD_INFO(slave)->stats;
2704+
u64 stat;
2705+
2706+
atomic64_add(atomic64_read(&rstats->lacpdu_rx), &stats->lacpdu_rx);
2707+
atomic64_add(atomic64_read(&rstats->lacpdu_tx), &stats->lacpdu_tx);
2708+
2709+
stat = atomic64_read(&rstats->lacpdu_unknown_rx);
2710+
atomic64_add(stat, &stats->lacpdu_unknown_rx);
2711+
stat = atomic64_read(&rstats->lacpdu_illegal_rx);
2712+
atomic64_add(stat, &stats->lacpdu_illegal_rx);
2713+
2714+
atomic64_add(atomic64_read(&rstats->marker_rx), &stats->marker_rx);
2715+
atomic64_add(atomic64_read(&rstats->marker_tx), &stats->marker_tx);
2716+
2717+
stat = atomic64_read(&rstats->marker_resp_rx);
2718+
atomic64_add(stat, &stats->marker_resp_rx);
2719+
stat = atomic64_read(&rstats->marker_resp_tx);
2720+
atomic64_add(stat, &stats->marker_resp_tx);
2721+
stat = atomic64_read(&rstats->marker_unknown_rx);
2722+
atomic64_add(stat, &stats->marker_unknown_rx);
2723+
}
2724+
2725+
size_t bond_3ad_stats_size(void)
2726+
{
2727+
return nla_total_size_64bit(sizeof(u64)) + /* BOND_3AD_STAT_LACPDU_RX */
2728+
nla_total_size_64bit(sizeof(u64)) + /* BOND_3AD_STAT_LACPDU_TX */
2729+
nla_total_size_64bit(sizeof(u64)) + /* BOND_3AD_STAT_LACPDU_UNKNOWN_RX */
2730+
nla_total_size_64bit(sizeof(u64)) + /* BOND_3AD_STAT_LACPDU_ILLEGAL_RX */
2731+
nla_total_size_64bit(sizeof(u64)) + /* BOND_3AD_STAT_MARKER_RX */
2732+
nla_total_size_64bit(sizeof(u64)) + /* BOND_3AD_STAT_MARKER_TX */
2733+
nla_total_size_64bit(sizeof(u64)) + /* BOND_3AD_STAT_MARKER_RESP_RX */
2734+
nla_total_size_64bit(sizeof(u64)) + /* BOND_3AD_STAT_MARKER_RESP_TX */
2735+
nla_total_size_64bit(sizeof(u64)); /* BOND_3AD_STAT_MARKER_UNKNOWN_RX */
2736+
}
2737+
2738+
int bond_3ad_stats_fill(struct sk_buff *skb, struct bond_3ad_stats *stats)
2739+
{
2740+
u64 val;
2741+
2742+
val = atomic64_read(&stats->lacpdu_rx);
2743+
if (nla_put_u64_64bit(skb, BOND_3AD_STAT_LACPDU_RX, val,
2744+
BOND_3AD_STAT_PAD))
2745+
return -EMSGSIZE;
2746+
val = atomic64_read(&stats->lacpdu_tx);
2747+
if (nla_put_u64_64bit(skb, BOND_3AD_STAT_LACPDU_TX, val,
2748+
BOND_3AD_STAT_PAD))
2749+
return -EMSGSIZE;
2750+
val = atomic64_read(&stats->lacpdu_unknown_rx);
2751+
if (nla_put_u64_64bit(skb, BOND_3AD_STAT_LACPDU_UNKNOWN_RX, val,
2752+
BOND_3AD_STAT_PAD))
2753+
return -EMSGSIZE;
2754+
val = atomic64_read(&stats->lacpdu_illegal_rx);
2755+
if (nla_put_u64_64bit(skb, BOND_3AD_STAT_LACPDU_ILLEGAL_RX, val,
2756+
BOND_3AD_STAT_PAD))
2757+
return -EMSGSIZE;
2758+
2759+
val = atomic64_read(&stats->marker_rx);
2760+
if (nla_put_u64_64bit(skb, BOND_3AD_STAT_MARKER_RX, val,
2761+
BOND_3AD_STAT_PAD))
2762+
return -EMSGSIZE;
2763+
val = atomic64_read(&stats->marker_tx);
2764+
if (nla_put_u64_64bit(skb, BOND_3AD_STAT_MARKER_TX, val,
2765+
BOND_3AD_STAT_PAD))
2766+
return -EMSGSIZE;
2767+
val = atomic64_read(&stats->marker_resp_rx);
2768+
if (nla_put_u64_64bit(skb, BOND_3AD_STAT_MARKER_RESP_RX, val,
2769+
BOND_3AD_STAT_PAD))
2770+
return -EMSGSIZE;
2771+
val = atomic64_read(&stats->marker_resp_tx);
2772+
if (nla_put_u64_64bit(skb, BOND_3AD_STAT_MARKER_RESP_TX, val,
2773+
BOND_3AD_STAT_PAD))
2774+
return -EMSGSIZE;
2775+
val = atomic64_read(&stats->marker_unknown_rx);
2776+
if (nla_put_u64_64bit(skb, BOND_3AD_STAT_MARKER_UNKNOWN_RX, val,
2777+
BOND_3AD_STAT_PAD))
2778+
return -EMSGSIZE;
2779+
2780+
return 0;
2781+
}

drivers/net/bonding/bond_netlink.c

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -675,6 +675,75 @@ static int bond_fill_info(struct sk_buff *skb,
675675
return -EMSGSIZE;
676676
}
677677

678+
static size_t bond_get_linkxstats_size(const struct net_device *dev, int attr)
679+
{
680+
switch (attr) {
681+
case IFLA_STATS_LINK_XSTATS:
682+
case IFLA_STATS_LINK_XSTATS_SLAVE:
683+
break;
684+
default:
685+
return 0;
686+
}
687+
688+
return bond_3ad_stats_size() + nla_total_size(0);
689+
}
690+
691+
static int bond_fill_linkxstats(struct sk_buff *skb,
692+
const struct net_device *dev,
693+
int *prividx, int attr)
694+
{
695+
struct nlattr *nla __maybe_unused;
696+
struct slave *slave = NULL;
697+
struct nlattr *nest, *nest2;
698+
struct bonding *bond;
699+
700+
switch (attr) {
701+
case IFLA_STATS_LINK_XSTATS:
702+
bond = netdev_priv(dev);
703+
break;
704+
case IFLA_STATS_LINK_XSTATS_SLAVE:
705+
slave = bond_slave_get_rtnl(dev);
706+
if (!slave)
707+
return 0;
708+
bond = slave->bond;
709+
break;
710+
default:
711+
return -EINVAL;
712+
}
713+
714+
nest = nla_nest_start(skb, LINK_XSTATS_TYPE_BOND);
715+
if (!nest)
716+
return -EMSGSIZE;
717+
if (BOND_MODE(bond) == BOND_MODE_8023AD) {
718+
struct bond_3ad_stats stats;
719+
struct list_head *iter;
720+
721+
memset(&stats, 0, sizeof(stats));
722+
if (slave) {
723+
bond_3ad_stats_add(slave, &stats);
724+
} else {
725+
bond_for_each_slave(bond, slave, iter)
726+
bond_3ad_stats_add(slave, &stats);
727+
}
728+
729+
nest2 = nla_nest_start(skb, BOND_XSTATS_3AD);
730+
if (!nest2) {
731+
nla_nest_end(skb, nest);
732+
return -EMSGSIZE;
733+
}
734+
735+
if (bond_3ad_stats_fill(skb, &stats)) {
736+
nla_nest_cancel(skb, nest2);
737+
nla_nest_end(skb, nest);
738+
return -EMSGSIZE;
739+
}
740+
nla_nest_end(skb, nest2);
741+
}
742+
nla_nest_end(skb, nest);
743+
744+
return 0;
745+
}
746+
678747
struct rtnl_link_ops bond_link_ops __read_mostly = {
679748
.kind = "bond",
680749
.priv_size = sizeof(struct bonding),
@@ -689,6 +758,8 @@ struct rtnl_link_ops bond_link_ops __read_mostly = {
689758
.get_num_tx_queues = bond_get_num_tx_queues,
690759
.get_num_rx_queues = bond_get_num_tx_queues, /* Use the same number
691760
as for TX queues */
761+
.fill_linkxstats = bond_fill_linkxstats,
762+
.get_linkxstats_size = bond_get_linkxstats_size,
692763
.slave_maxtype = IFLA_BOND_SLAVE_MAX,
693764
.slave_policy = bond_slave_policy,
694765
.slave_changelink = bond_slave_changelink,

include/net/bond_3ad.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,5 +321,8 @@ int bond_3ad_lacpdu_recv(const struct sk_buff *skb, struct bonding *bond,
321321
int bond_3ad_set_carrier(struct bonding *bond);
322322
void bond_3ad_update_lacp_rate(struct bonding *bond);
323323
void bond_3ad_update_ad_actor_settings(struct bonding *bond);
324+
void bond_3ad_stats_add(struct slave *slave, struct bond_3ad_stats *stats);
325+
int bond_3ad_stats_fill(struct sk_buff *skb, struct bond_3ad_stats *stats);
326+
size_t bond_3ad_stats_size(void);
324327
#endif /* _NET_BOND_3AD_H */
325328

include/uapi/linux/if_bonding.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,30 @@ struct ad_info {
117117
__u8 partner_system[ETH_ALEN];
118118
};
119119

120+
/* Embedded inside LINK_XSTATS_TYPE_BOND */
121+
enum {
122+
BOND_XSTATS_UNSPEC,
123+
BOND_XSTATS_3AD,
124+
__BOND_XSTATS_MAX
125+
};
126+
#define BOND_XSTATS_MAX (__BOND_XSTATS_MAX - 1)
127+
128+
/* Embedded inside BOND_XSTATS_3AD */
129+
enum {
130+
BOND_3AD_STAT_LACPDU_RX,
131+
BOND_3AD_STAT_LACPDU_TX,
132+
BOND_3AD_STAT_LACPDU_UNKNOWN_RX,
133+
BOND_3AD_STAT_LACPDU_ILLEGAL_RX,
134+
BOND_3AD_STAT_MARKER_RX,
135+
BOND_3AD_STAT_MARKER_TX,
136+
BOND_3AD_STAT_MARKER_RESP_RX,
137+
BOND_3AD_STAT_MARKER_RESP_TX,
138+
BOND_3AD_STAT_MARKER_UNKNOWN_RX,
139+
BOND_3AD_STAT_PAD,
140+
__BOND_3AD_STAT_MAX
141+
};
142+
#define BOND_3AD_STAT_MAX (__BOND_3AD_STAT_MAX - 1)
143+
120144
#endif /* _LINUX_IF_BONDING_H */
121145

122146
/*

include/uapi/linux/if_link.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -925,6 +925,7 @@ enum {
925925
enum {
926926
LINK_XSTATS_TYPE_UNSPEC,
927927
LINK_XSTATS_TYPE_BRIDGE,
928+
LINK_XSTATS_TYPE_BOND,
928929
__LINK_XSTATS_TYPE_MAX
929930
};
930931
#define LINK_XSTATS_TYPE_MAX (__LINK_XSTATS_TYPE_MAX - 1)

0 commit comments

Comments
 (0)