diff options
author | Petr Machata <petrm@nvidia.com> | 2022-04-22 10:30:55 +0200 |
---|---|---|
committer | David Ahern <dsahern@kernel.org> | 2022-04-27 20:12:42 -0600 |
commit | 0517a2fd66ae30bd037ddc9ac2358146e6a7bfb7 (patch) | |
tree | e24a0f3daf43fe2884067ac4df3498f1a75e96b2 | |
parent | df0b2c6d0098bfcc8be1c74238d43a0e38681090 (diff) | |
download | iproute2-0517a2fd66ae30bd037ddc9ac2358146e6a7bfb7.tar.gz |
ipstats: Add a group "link"
Add the "link" top-level group for showing IFLA_STATS_LINK_64 statistics.
For example:
# ip stats show dev swp1 group link
4178: swp1: group link
RX: bytes packets errors dropped missed mcast
47048 354 0 0 0 64
TX: bytes packets errors dropped carrier collsns
47474 355 0 0 0 0
# ip -j stats show dev swp1 group link | jq
[
{
"ifindex": 4178,
"ifname": "swp1",
"group": "link",
"stats64": {
"rx": {
"bytes": 47048,
"packets": 354,
"errors": 0,
"dropped": 0,
"over_errors": 0,
"multicast": 64
},
"tx": {
"bytes": 47474,
"packets": 355,
"errors": 0,
"dropped": 0,
"carrier_errors": 0,
"collisions": 0
}
}
}
]
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/ipstats.c | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/ip/ipstats.c b/ip/ipstats.c index 79f7b1ffa..e4f97dddd 100644 --- a/ip/ipstats.c +++ b/ip/ipstats.c @@ -12,6 +12,15 @@ struct ipstats_stat_dump_filters { __u32 mask[IFLA_STATS_MAX + 1]; }; +static void +ipstats_stat_desc_enable_bit(struct ipstats_stat_dump_filters *filters, + unsigned int group, unsigned int subgroup) +{ + filters->mask[0] |= IFLA_STATS_FILTER_BIT(group); + if (subgroup) + filters->mask[group] |= IFLA_STATS_FILTER_BIT(subgroup); +} + struct ipstats_stat_show_attrs { struct if_stats_msg *ifsm; int len; @@ -89,6 +98,29 @@ ipstats_stat_show_attrs_alloc_tb(struct ipstats_stat_show_attrs *attrs, return err; } +static const struct rtattr * +ipstats_stat_show_get_attr(struct ipstats_stat_show_attrs *attrs, + int group, int subgroup, int *err) +{ + int tmp_err; + + if (err == NULL) + err = &tmp_err; + + *err = 0; + if (subgroup == 0) + return attrs->tbs[0][group]; + + if (attrs->tbs[0][group] == NULL) + return NULL; + + *err = ipstats_stat_show_attrs_alloc_tb(attrs, group); + if (*err != 0) + return NULL; + + return attrs->tbs[group][subgroup]; +} + static void ipstats_stat_show_attrs_free(struct ipstats_stat_show_attrs *attrs) { @@ -98,7 +130,65 @@ ipstats_stat_show_attrs_free(struct ipstats_stat_show_attrs *attrs) free(attrs->tbs[i]); } +#define IPSTATS_RTA_PAYLOAD(TYPE, AT) \ + ({ \ + const struct rtattr *__at = (AT); \ + TYPE *__ret = NULL; \ + \ + if (__at != NULL && \ + __at->rta_len - RTA_LENGTH(0) >= sizeof(TYPE)) \ + __ret = RTA_DATA(__at); \ + __ret; \ + }) + +static int ipstats_show_64(struct ipstats_stat_show_attrs *attrs, + unsigned int group, unsigned int subgroup) +{ + struct rtnl_link_stats64 *stats; + const struct rtattr *at; + int err; + + at = ipstats_stat_show_get_attr(attrs, group, subgroup, &err); + if (at == NULL) + return err; + + stats = IPSTATS_RTA_PAYLOAD(struct rtnl_link_stats64, at); + if (stats == NULL) { + fprintf(stderr, "Error: attribute payload too short"); + return -EINVAL; + } + + open_json_object("stats64"); + print_stats64(stdout, stats, NULL, NULL); + close_json_object(); + return 0; +} + +static void +ipstats_stat_desc_pack_link(struct ipstats_stat_dump_filters *filters, + const struct ipstats_stat_desc *desc) +{ + ipstats_stat_desc_enable_bit(filters, + IFLA_STATS_LINK_64, 0); +} + +static int +ipstats_stat_desc_show_link(struct ipstats_stat_show_attrs *attrs, + const struct ipstats_stat_desc *desc) +{ + print_nl(); + return ipstats_show_64(attrs, IFLA_STATS_LINK_64, 0); +} + +static const struct ipstats_stat_desc ipstats_stat_desc_toplev_link = { + .name = "link", + .kind = IPSTATS_STAT_DESC_KIND_LEAF, + .pack = &ipstats_stat_desc_pack_link, + .show = &ipstats_stat_desc_show_link, +}; + static const struct ipstats_stat_desc *ipstats_stat_desc_toplev_subs[] = { + &ipstats_stat_desc_toplev_link, }; static const struct ipstats_stat_desc ipstats_stat_desc_toplev_group = { |