From: Petr Machata Date: Tue, 10 Jun 2025 15:51:27 +0000 (+0200) Subject: ip: iplink_bridge: Support bridge VLAN stats in `ip stats' X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fba1f9c77b16402ab014a24bb19f124a6ae1d9b7;p=thirdparty%2Fiproute2.git ip: iplink_bridge: Support bridge VLAN stats in `ip stats' Add support for displaying bridge VLAN statistics in `ip stats'. Reuse the existing `bridge vlan' display and JSON format: # ip stats show dev v2 group xstats_slave subgroup bridge suite vlan 2: v2: group xstats_slave subgroup bridge suite vlan 10 RX: 3376 bytes 50 packets TX: 2824 bytes 44 packets 20 RX: 684 bytes 7 packets TX: 0 bytes 0 packets # ip -j -p stats show dev v2 group xstats_slave subgroup bridge suite vlan [ { "ifindex": 2, "ifname": "v2", "group": "xstats_slave", "subgroup": "bridge", "suite": "vlan", "vlans": [ { "vid": 10, "rx_bytes": 3376, "rx_packets": 50, "tx_bytes": 2824, "tx_packets": 44 },{ "vid": 20, "rx_bytes": 684, "rx_packets": 7, "tx_bytes": 0, "tx_packets": 0 } ] } ] Similarly for the master stats: # ip stats show dev br1 group xstats subgroup bridge suite vlan 211: br1: group xstats subgroup bridge suite vlan 10 RX: 3376 bytes 50 packets TX: 2824 bytes 44 packets 20 RX: 684 bytes 7 packets TX: 0 bytes 0 packets # ip -j -p stats show dev br1 group xstats subgroup bridge suite vlan [ { "ifindex": 211, "ifname": "br1", "group": "xstats", "subgroup": "bridge", "suite": "vlan", "vlans": [ { "vid": 10, "flags": [ ], "rx_bytes": 3376, "rx_packets": 50, "tx_bytes": 2824, "tx_packets": 44 },{ "vid": 20, "flags": [ ], "rx_bytes": 684, "rx_packets": 7, "tx_bytes": 0, "tx_packets": 0 } ] } ] Signed-off-by: Petr Machata Acked-by: Nikolay Aleksandrov Reviewed-by: Ido Schimmel Signed-off-by: David Ahern --- diff --git a/ip/iplink_bridge.c b/ip/iplink_bridge.c index 3d54e203..31e7cb5e 100644 --- a/ip/iplink_bridge.c +++ b/ip/iplink_bridge.c @@ -14,6 +14,7 @@ #include #include +#include "bridge.h" #include "rt_names.h" #include "utils.h" #include "ip_common.h" @@ -978,6 +979,26 @@ static void bridge_print_stats_stp(const struct rtattr *attr) close_json_object(); } +static void bridge_print_stats_vlan(const struct rtattr *attr) +{ + const struct bridge_vlan_xstats *vstats = RTA_DATA(attr); + + print_string(PRINT_FP, NULL, "%-" textify(IFNAMSIZ) "s ", ""); + bridge_print_vlan_stats(vstats); +} + +static int bridge_stat_desc_show_xstats(struct ipstats_stat_show_attrs *attrs, + const struct ipstats_stat_desc *desc) +{ + int ret; + + open_json_array(PRINT_JSON, "vlans"); + ret = ipstats_stat_desc_show_xstats(attrs, desc); + close_json_array(PRINT_JSON, "vlans"); + + return ret; +} + static void bridge_print_stats_attr(struct rtattr *attr, int ifindex) { struct rtattr *brtb[LINK_XSTATS_TYPE_MAX+1]; @@ -1088,10 +1109,27 @@ ipstats_stat_desc_xstats_bridge_mcast = { .show_cb = &bridge_print_stats_mcast, }; +#define IPSTATS_STAT_DESC_BRIDGE_VLAN { \ + .name = "vlan", \ + .kind = IPSTATS_STAT_DESC_KIND_LEAF, \ + .show = &bridge_stat_desc_show_xstats, \ + .pack = &ipstats_stat_desc_pack_xstats, \ + } + +static const struct ipstats_stat_desc_xstats +ipstats_stat_desc_xstats_bridge_vlan = { + .desc = IPSTATS_STAT_DESC_BRIDGE_VLAN, + .xstats_at = IFLA_STATS_LINK_XSTATS, + .link_type_at = LINK_XSTATS_TYPE_BRIDGE, + .inner_at = BRIDGE_XSTATS_VLAN, + .show_cb = &bridge_print_stats_vlan, +}; + static const struct ipstats_stat_desc * ipstats_stat_desc_xstats_bridge_subs[] = { &ipstats_stat_desc_xstats_bridge_stp.desc, &ipstats_stat_desc_xstats_bridge_mcast.desc, + &ipstats_stat_desc_xstats_bridge_vlan.desc, }; const struct ipstats_stat_desc ipstats_stat_desc_xstats_bridge_group = { @@ -1119,10 +1157,20 @@ ipstats_stat_desc_xstats_slave_bridge_mcast = { .show_cb = &bridge_print_stats_mcast, }; +static const struct ipstats_stat_desc_xstats +ipstats_stat_desc_xstats_slave_bridge_vlan = { + .desc = IPSTATS_STAT_DESC_BRIDGE_VLAN, + .xstats_at = IFLA_STATS_LINK_XSTATS_SLAVE, + .link_type_at = LINK_XSTATS_TYPE_BRIDGE, + .inner_at = BRIDGE_XSTATS_VLAN, + .show_cb = &bridge_print_stats_vlan, +}; + static const struct ipstats_stat_desc * ipstats_stat_desc_xstats_slave_bridge_subs[] = { &ipstats_stat_desc_xstats_slave_bridge_stp.desc, &ipstats_stat_desc_xstats_slave_bridge_mcast.desc, + &ipstats_stat_desc_xstats_slave_bridge_vlan.desc, }; const struct ipstats_stat_desc ipstats_stat_desc_xstats_slave_bridge_group = { diff --git a/man/man8/ip-stats.8 b/man/man8/ip-stats.8 index 26336454..e9ff49d5 100644 --- a/man/man8/ip-stats.8 +++ b/man/man8/ip-stats.8 @@ -152,9 +152,15 @@ Note how the l3_stats_info for the selected group is also part of the dump. .in 21 .ti 14 -.B subgroup bridge \fR[\fB suite stp \fR] [\fB suite mcast \fR] -- Statistics for STP and, respectively, IGMP / MLD (under the keyword -\fBmcast\fR) traffic on bridges and their slaves. +.B subgroup bridge\fR - Various statistics on bridges and their slaves. + +.ti 21 +.BR "suite stp " "- STP statistics" +.br +.BR "suite mcast " "- IGMP / MLD statistics" +.br +.BR "suite vlan " "- per-VLAN traffic statistics" +.br .ti 14 .B subgroup bond \fR[\fB suite 802.3ad \fR]