ip: Support bridge VLAN stats in `ip stats'
Subsystems (4)
v3 cover ip: Support bridge VLAN stats in `ip stats'
ip stats displays bridge-related multicast and STP stats, but not VLAN stats. There is code for requesting, decoding and formatting these stats accessible through bridge -s vlan', but the ip stats' suite lacks it. In this patchset, extract the bridge vlan' code to a generally accessible place and extend ip stats' to use it.
This reuses the existing display and JSON format, and plugs it into the existing `ip stats' hierarchy:
# 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
} ]
} ]v3:
- Patch #4:
- Add man page coverage.
- Order the VLAN suite at the end in both master and slave subgroups.
- Retain Nik's Acked-by for these.
v2:
- Patch #1:
- Use rtattr_for_each_nested
- Drop #include <alloca.h>, it's not used anymore
- Patch #3:
- Add MAINTAINERS entry for the module
- Patch #4:
- Add the master stats as well.
Petr Machata (4):
ip: ipstats: Iterate all xstats attributes
ip: ip_common: Drop ipstats_stat_desc_xstats::inner_max
lib: bridge: Add a module for bridge-related helpers
ip: iplink_bridge: Support bridge VLAN stats in `ip stats'
MAINTAINERS | 2 ++ bridge/vlan.c | 50 +++++-------------------------------------- include/bridge.h | 11 ++++++++++ ip/ip_common.h | 1 - ip/iplink_bond.c | 2 -- ip/iplink_bridge.c | 52 +++++++++++++++++++++++++++++++++++++++++---- ip/ipstats.c | 17 ++++++--------- lib/Makefile | 3 ++- lib/bridge.c | 47 ++++++++++++++++++++++++++++++++++++++++ man/man8/ip-stats.8 | 12 ++++++++--- 10 files changed, 131 insertions(+), 66 deletions(-) create mode 100644 include/bridge.h create mode 100644 lib/bridge.c
Signature · 1 line
2.49.0
PATCH v3 1/4 ip: ipstats: Iterate all xstats attributes
ipstats_stat_desc_show_xstats() operates by first parsing the attribute stream into a type-indexed table, and then accessing the right attribute. But bridge VLAN stats are given as several BRIDGE_XSTATS_VLAN attributes, one per VLAN. With the above approach to parsing, only one of these attributes would be shown. Instead, iterate the stream of attributes and call the show_cb for each one with a matching type.
---
Notes:
v2:
- Use rtattr_for_each_nested
- Drop #include <alloca.h>, it's not used anymore
ip/ipstats.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-)
ip/ipstats.c +7 -10
@@ -1,5 +1,4 @@// SPDX-License-Identifier: GPL-2.0+ -#include <alloca.h> #include <assert.h> #include <errno.h> #include <stdio.h>
@@ -590,7 +589,7 @@ int ipstats_stat_desc_show_xstats(struct ipstats_stat_show_attrs *attrs, {struct ipstats_stat_desc_xstats *xdesc;const struct rtattr *at; -struct rtattr **tb; +const struct rtattr *i;int err; xdesc = container_of(desc, struct ipstats_stat_desc_xstats, desc);
@@ -600,15 +599,13 @@ int ipstats_stat_desc_show_xstats(struct ipstats_stat_show_attrs *attrs,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]); +rtattr_for_each_nested (i, at) { +if (i->rta_type == xdesc->inner_at) { +print_nl (); + xdesc->show_cb (i); + } } +return 0 ; }
Signature · 1 line
2.49.0
PATCH v3 2/4 ip: ip_common: Drop ipstats_stat_desc_xstats::inner_max
In reply to Petr MachataAfter the previous patch, this field is not read anymore. Drop it.
--- ip/ip_common.h | 1 - ip/iplink_bond.c | 2 -- ip/iplink_bridge.c | 4 ---- 3 files changed, 7 deletions(-)
ip/ip_common.h +0 -1
@@ -195,7 +195,6 @@ 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); };
ip/iplink_bond.c +0 -2
@@ -940,7 +940,6 @@ ipstats_stat_desc_xstats_bond_lacp = { .desc = IPSTATS_STAT_DESC_XSTATS_LEAF("802.3ad"), .xstats_at = IFLA_STATS_LINK_XSTATS, .link_type_at = LINK_XSTATS_TYPE_BOND, - .inner_max = BOND_XSTATS_MAX, .inner_at = BOND_XSTATS_3AD, .show_cb = &bond_print_3ad_stats, };
@@ -962,7 +961,6 @@ ipstats_stat_desc_xstats_slave_bond_lacp = { .desc = IPSTATS_STAT_DESC_XSTATS_LEAF("802.3ad"), .xstats_at = IFLA_STATS_LINK_XSTATS_SLAVE, .link_type_at = LINK_XSTATS_TYPE_BOND, - .inner_max = BOND_XSTATS_MAX, .inner_at = BOND_XSTATS_3AD, .show_cb = &bond_print_3ad_stats, };
ip/iplink_bridge.c +0 -4
@@ -1075,7 +1075,6 @@ ipstats_stat_desc_xstats_bridge_stp = { .desc = IPSTATS_STAT_DESC_XSTATS_LEAF("stp"), .xstats_at = IFLA_STATS_LINK_XSTATS, .link_type_at = LINK_XSTATS_TYPE_BRIDGE, - .inner_max = BRIDGE_XSTATS_MAX, .inner_at = BRIDGE_XSTATS_STP, .show_cb = &bridge_print_stats_stp, };
@@ -1085,7 +1084,6 @@ ipstats_stat_desc_xstats_bridge_mcast = { .desc = IPSTATS_STAT_DESC_XSTATS_LEAF("mcast"), .xstats_at = IFLA_STATS_LINK_XSTATS, .link_type_at = LINK_XSTATS_TYPE_BRIDGE, - .inner_max = BRIDGE_XSTATS_MAX, .inner_at = BRIDGE_XSTATS_MCAST, .show_cb = &bridge_print_stats_mcast, };
@@ -1108,7 +1106,6 @@ ipstats_stat_desc_xstats_slave_bridge_stp = { .desc = IPSTATS_STAT_DESC_XSTATS_LEAF("stp"), .xstats_at = IFLA_STATS_LINK_XSTATS_SLAVE, .link_type_at = LINK_XSTATS_TYPE_BRIDGE, - .inner_max = BRIDGE_XSTATS_MAX, .inner_at = BRIDGE_XSTATS_STP, .show_cb = &bridge_print_stats_stp, };
@@ -1118,7 +1115,6 @@ ipstats_stat_desc_xstats_slave_bridge_mcast = { .desc = IPSTATS_STAT_DESC_XSTATS_LEAF("mcast"), .xstats_at = IFLA_STATS_LINK_XSTATS_SLAVE, .link_type_at = LINK_XSTATS_TYPE_BRIDGE, - .inner_max = BRIDGE_XSTATS_MAX, .inner_at = BRIDGE_XSTATS_MCAST, .show_cb = &bridge_print_stats_mcast, };
Signature · 1 line
2.49.0
PATCH v3 3/4 lib: bridge: Add a module for bridge-related helpers
In reply to Petr Machataip stats' displays a range of bridge_slave-related statistics, but not the VLAN stats. bridge vlan' actually has code to show these. Extract the code to libutil so that it can be reused between the bridge and ip stats tools.
Rename them reasonably so as not to litter the global namespace.
---
Notes:
v2:
- Add MAINTAINERS entry for the module
MAINTAINERS | 2 ++ bridge/vlan.c | 50 +++++------------------------------------------- include/bridge.h | 11 +++++++++++ lib/Makefile | 3 ++- lib/bridge.c | 47 +++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 67 insertions(+), 46 deletions(-) create mode 100644 include/bridge.h create mode 100644 lib/bridge.c
MAINTAINERS +2 -0
@@ -31,6 +31,8 @@ M: Nikolay Aleksandrov <[email protected]> L: [email protected] (moderated for non-subscribers) F: bridge/* F: ip/iplink_bridge* +F: lib/bridge* +F: include/bridge* Data Center Bridging - dcb M: Petr Machata <[email protected]>
bridge/vlan.c +5 -45
86 lines not on this page · raw message
include/bridge.h new file +11 -0
@@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __BRIDGE_H__ +#define __BRIDGE_H__ 1 + +#include <linux/if_bridge.h> + +void bridge_print_vlan_flags (__u16 flags); +void bridge_print_vlan_stats_only (const struct bridge_vlan_xstats *vstats); +void bridge_print_vlan_stats (const struct bridge_vlan_xstats *vstats); + +#endif /* __BRIDGE_H__ */
lib/Makefile +2 -1
@@ -5,7 +5,8 @@ CFLAGS += -fPIC UTILOBJ = utils.o utils_math.o rt_names.o ll_map.o ll_types.o ll_proto.o ll_addr.o \ inet_proto.o namespace.o json_writer.o json_print.o json_print_math.o \ - names.o color.o bpf_legacy.o bpf_glue.o exec.o fs.o cg_map.o ppp_proto.o + names.o color.o bpf_legacy.o bpf_glue.o exec.o fs.o cg_map.o \ + ppp_proto.o bridge.o ifeq ($(HAVE_ELF),y) ifeq ($(HAVE_LIBBPF),y)
lib/bridge.c new file +47 -0
47 lines not on this page · raw message
Signature · 1 line
2.49.0
PATCH v3 4/4 ip: iplink_bridge: Support bridge VLAN stats in `ip stats'
In reply to Petr MachataAdd 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
} ]
} ]---
Notes:
v3:
- Add man page coverage.
- Order the VLAN suite at the end in both master and slave subgroups.
- Retain Nik's Acked-by for these.
v2:
- Add the master stats as well.
ip/iplink_bridge.c | 48 +++++++++++++++++++++++++++++++++++++++++++++ man/man8/ip-stats.8 | 12 +++++++++--- 2 files changed, 57 insertions(+), 3 deletions(-)
ip/iplink_bridge.c +48 -0
@@ -14,6 +14,7 @@#include <linux/if_bridge.h> #include <net/if.h> +#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 = {
man/man8/ip-stats.8 +9 -3
@@ -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]
Signature · 1 line
2.49.0
Re: [PATCH iproute2-next v3 4/4] ip: iplink_bridge: Support bridge VLAN stats in `ip stats'
Quoted 2 lines · Petr Machata
Add support for displaying bridge VLAN statistics in
ip stats'. Reuse the existingbridge vlan' display and JSON format:
[...]
Quoted 2 lines
Signed-off-by Petr Machata <[email protected]>
David Ahern
AppliedQuoted 6 lines · Petr Machata
ip stats displays bridge-related multicast and STP stats, but not VLAN stats. There is code for requesting, decoding and formatting these stats accessible through
bridge -s vlan', but theip stats' suite lacks it. In this patchset, extract thebridge vlan' code to a generally accessible place and extendip stats' to use it.
applied to iproute2-next. Thanks