aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPetr Machata <petrm@nvidia.com>2022-05-09 15:59:59 +0200
committerDavid Ahern <dsahern@kernel.org>2022-05-12 11:08:20 -0600
commit1247ed51e9242ca3d0a74dfaeedb5b7afea91c42 (patch)
treee5e198cc1b92553e147785d37034ff665fa553f4
parentc6900b79b13d7bc329955b4f9e8c7470d42ae2fa (diff)
downloadiproute2-1247ed51e9242ca3d0a74dfaeedb5b7afea91c42.tar.gz
ipstats: Add groups "xstats", "xstats_slave"
The RTM_GETSTATS response attributes IFLA_STATS_LINK_XSTATS and IFLA_STATS_LINK_XSTATS_SLAVE are used to carry statistics related to, respectively, netdevices of a certain type, and netdevices enslaved to netdevices of a certain type. Inside the nest is then link-type specific attribute (e.g. LINK_XSTATS_TYPE_BRIDGE), and inside that nest further attributes for individual type-specific statistical suites. Under the "ip stats" model, that corresponds to groups "xstats" and "xstats_slave", link-type specific subgroup, e.g. "bridge", and one or more link-type specific suites, such as "stp". Link-type specific stats are currently supported through struct link_util and in particular the callbacks parse_ifla_xstats and print_ifla_xstats. The role of parse_ifla_xstats is to establish which statistical suite to display, and on which device. "ip stats" has framework for both of these tasks, which obviates the need for custom parsing. Therefore the module should instead provide a subgroup descriptor, which "ip stats" will then use as any other. The second link_util callback, print_ifla_xstats, is for response dissection. In "ip stats" model, this belongs to leaf descriptors. Eventually, the link-specific leaf descriptors will be similar to each other: either master or slave top-level nest needs to be parsed, and link-type attribute underneath that, and suite attribute underneath that. To support this commonality, add struct ipstats_stat_desc_xstats to describe the xstats suites. Further, expose ipstats_stat_desc_pack_xstats() and ipstats_stat_desc_show_xstats(), which can be used at leaf descriptors and do the appropriate thing according to the configuration in ipstats_stat_desc_xstats. Signed-off-by: Petr Machata <petrm@nvidia.com> Reviewed-by: Ido Schimmel <idosch@nvidia.com> Signed-off-by: David Ahern <dsahern@kernel.org>
-rw-r--r--ip/ip_common.h14
-rw-r--r--ip/ipstats.c59
2 files changed, 73 insertions, 0 deletions
diff --git a/ip/ip_common.h b/ip/ip_common.h
index 63618f0fb..8b7ec6452 100644
--- a/ip/ip_common.h
+++ b/ip/ip_common.h
@@ -186,6 +186,20 @@ struct ipstats_stat_desc {
};
};
+struct ipstats_stat_desc_xstats {
+ const struct ipstats_stat_desc desc;
+ int xstats_at;
+ int link_type_at;
+ int inner_max;
+ int inner_at;
+ void (*show_cb)(const struct rtattr *at);
+};
+
+void ipstats_stat_desc_pack_xstats(struct ipstats_stat_dump_filters *filters,
+ const struct ipstats_stat_desc *desc);
+int ipstats_stat_desc_show_xstats(struct ipstats_stat_show_attrs *attrs,
+ const struct ipstats_stat_desc *desc);
+
#ifndef INFINITY_LIFE_TIME
#define INFINITY_LIFE_TIME 0xFFFFFFFFU
#endif
diff --git a/ip/ipstats.c b/ip/ipstats.c
index 0e7f2b3c9..0691a3f05 100644
--- a/ip/ipstats.c
+++ b/ip/ipstats.c
@@ -2,6 +2,7 @@
#include <assert.h>
#include <errno.h>
+#include "list.h"
#include "utils.h"
#include "ip_common.h"
@@ -567,6 +568,62 @@ static const struct ipstats_stat_desc ipstats_stat_desc_offload_group = {
.nsubs = ARRAY_SIZE(ipstats_stat_desc_offload_subs),
};
+void ipstats_stat_desc_pack_xstats(struct ipstats_stat_dump_filters *filters,
+ const struct ipstats_stat_desc *desc)
+{
+ struct ipstats_stat_desc_xstats *xdesc;
+
+ xdesc = container_of(desc, struct ipstats_stat_desc_xstats, desc);
+ ipstats_stat_desc_enable_bit(filters, xdesc->xstats_at, 0);
+}
+
+int ipstats_stat_desc_show_xstats(struct ipstats_stat_show_attrs *attrs,
+ const struct ipstats_stat_desc *desc)
+{
+ struct ipstats_stat_desc_xstats *xdesc;
+ const struct rtattr *at;
+ struct rtattr **tb;
+ int err;
+
+ xdesc = container_of(desc, struct ipstats_stat_desc_xstats, desc);
+ at = ipstats_stat_show_get_attr(attrs,
+ xdesc->xstats_at,
+ xdesc->link_type_at, &err);
+ if (at == NULL)
+ return err;
+
+ tb = alloca(sizeof(*tb) * (xdesc->inner_max + 1));
+ err = parse_rtattr_nested(tb, xdesc->inner_max, at);
+ if (err != 0)
+ return err;
+
+ if (tb[xdesc->inner_at] != NULL) {
+ print_nl();
+ xdesc->show_cb(tb[xdesc->inner_at]);
+ }
+ return 0;
+}
+
+static const struct ipstats_stat_desc *ipstats_stat_desc_xstats_subs[] = {
+};
+
+static const struct ipstats_stat_desc ipstats_stat_desc_xstats_group = {
+ .name = "xstats",
+ .kind = IPSTATS_STAT_DESC_KIND_GROUP,
+ .subs = ipstats_stat_desc_xstats_subs,
+ .nsubs = ARRAY_SIZE(ipstats_stat_desc_xstats_subs),
+};
+
+static const struct ipstats_stat_desc *ipstats_stat_desc_xstats_slave_subs[] = {
+};
+
+static const struct ipstats_stat_desc ipstats_stat_desc_xstats_slave_group = {
+ .name = "xstats_slave",
+ .kind = IPSTATS_STAT_DESC_KIND_GROUP,
+ .subs = ipstats_stat_desc_xstats_slave_subs,
+ .nsubs = ARRAY_SIZE(ipstats_stat_desc_xstats_slave_subs),
+};
+
static void
ipstats_stat_desc_pack_link(struct ipstats_stat_dump_filters *filters,
const struct ipstats_stat_desc *desc)
@@ -645,6 +702,8 @@ static const struct ipstats_stat_desc ipstats_stat_desc_afstats_group = {
};
static const struct ipstats_stat_desc *ipstats_stat_desc_toplev_subs[] = {
&ipstats_stat_desc_toplev_link,
+ &ipstats_stat_desc_xstats_group,
+ &ipstats_stat_desc_xstats_slave_group,
&ipstats_stat_desc_offload_group,
&ipstats_stat_desc_afstats_group,
};