ip stats: Support for xstats and afstats
Subsystems (2)
cover ip stats: Support for xstats and afstats
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. IFLA_STATS_AF_SPEC are similarly used to carry statistics specific to a certain address family.
In this patch set, add support for three new stats groups that cover the above attributes: xstats, xstats_slave and afstats. Add bridge and bond subgroups to the former two groups, and mpls subgroup to the latter one.
Now "group" is used for selecting the top-level attribute, and subgroup for the link-type or address-family nest below it (bridge, bond, mpls in this patchset). But xstats (both master and slave) are further subdivided. E.g. in the case of bridge statistics, the two subdivisions are called "stp" and "mcast". To make it possible to pick these sets, add to the two selector levels of group and subgroup a third level, suite, which is filtered in the userspace.
The patchset progresses as follows:
- Patches #1 and #2 fix up MPLS stats formatting and expose the helpers for reuse.
- Patch #3 adds ip stats group afstats and a subgroup mpls
- Patch #4 adds support for JSON formatting to MPLS
- Patch #5 adds support for the selector level "suite"
- Patch #6 adds groups "xstats" and "xstats_slave"
- Patches #7 and #8 first prepare helpers, then add support for the "bridge" subgroup of the xstats groups.
- Patch #9 adds the "bond" subgroup.
- Patch #10 adds manual page coverage.
Petr Machata (10):
iplink: Fix formatting of MPLS stats
iplink: Publish a function to format MPLS stats
ipstats: Add a group "afstats", subgroup "mpls"
iplink: Add JSON support to MPLS stats formatter
ipstats: Add a third level of stats hierarchy, a "suite"
ipstats: Add groups "xstats", "xstats_slave"
iplink_bridge: Split bridge_print_stats_attr()
ipstats: Expose bridge stats in ipstats
ipstats: Expose bond stats in ipstats
man: ip-stats.8: Describe groups xstats, xstats_slave and afstats
ip/ip_common.h | 22 +++ ip/iplink.c | 75 ++++++++-- ip/iplink_bond.c | 55 +++++++- ip/iplink_bridge.c | 334 ++++++++++++++++++++++++++++---------------- ip/ipstats.c | 126 ++++++++++++++++- man/man8/ip-stats.8 | 50 ++++++- 6 files changed, 522 insertions(+), 140 deletions(-)
Signature · 1 line
2.31.1
PATCH 1/10 iplink: Fix formatting of MPLS stats
Currently, MPLS stats are formatted this way:
# ip -n ns0-DBZpxj8I link afstats dev veth01
3: veth01
mpls:
RX: bytes packets errors dropped noroute
0 0 0 0 0
TX: bytes packets errors dropped
216 2 0 0Note how most numbers are not aligned properly under their column headers. Fix by converting the code to use size_columns() to dynamically determine the necessary width of individual columns, which also takes care of formatting the table properly in case the counter values are high. After the fix, the formatting looks as follows:
# ip -n ns0-Y1PyEc55 link afstats dev veth01
3: veth01
mpls:
RX: bytes packets errors dropped noroute
0 0 0 0 0
TX: bytes packets errors dropped
108 1 0 0--- ip/iplink.c | 44 ++++++++++++++++++++++++++++++++------------ 1 file changed, 32 insertions(+), 12 deletions(-)
ip/iplink.c +32 -12
@@ -1521,6 +1521,13 @@ static void print_mpls_stats(FILE *fp, struct rtattr *attr) {struct rtattr *mrtb[MPLS_STATS_MAX +1 ];struct mpls_link_stats *stats; +unsigned int cols[] = { +strlen ("*X: bytes" ), +strlen ("packets" ), +strlen ("errors" ), +strlen ("dropped" ), +strlen ("noroute" ), + };parse_rtattr (mrtb,MPLS_STATS_MAX ,RTA_DATA (attr),RTA_PAYLOAD (attr));
@@ -1528,22 +1535,35 @@ static void print_mpls_stats(FILE *fp, struct rtattr *attr)return ; stats =RTA_DATA (mrtb[MPLS_STATS_LINK ]); -fprintf (fp," mpls:\n" ); -fprintf (fp," RX: bytes packets errors dropped noroute\n" ); + +size_columns (cols,ARRAY_SIZE (cols), + stats->rx_bytes, stats->rx_packets, stats->rx_errors, + stats->rx_dropped, stats->rx_noroute); +size_columns (cols,ARRAY_SIZE (cols), + stats->tx_bytes, stats->tx_packets, stats->tx_errors, + stats->tx_dropped,0 ); + +fprintf (fp," RX: %*s %*s %*s %*s %*s%s" , + cols[0 ] -4 ,"bytes" , cols[1 ],"packets" , + cols[2 ],"errors" , cols[3 ],"dropped" , + cols[4 ],"noroute" , _SL_);fprintf (fp," " ); -print_num (fp,10 , stats->rx_bytes); -print_num (fp,8 , stats->rx_packets); -print_num (fp,7 , stats->rx_errors); -print_num (fp,8 , stats->rx_dropped); -print_num (fp,7 , stats->rx_noroute); +print_num (fp, cols[0 ], stats->rx_bytes); +print_num (fp, cols[1 ], stats->rx_packets); +print_num (fp, cols[2 ], stats->rx_errors); +print_num (fp, cols[3 ], stats->rx_dropped); +print_num (fp, cols[4 ], stats->rx_noroute);fprintf (fp,"\n" ); -fprintf (fp," TX: bytes packets errors dropped\n" ); + +fprintf (fp," TX: %*s %*s %*s %*s%s" , + cols[0 ] -4 ,"bytes" , cols[1 ],"packets" , + cols[2 ],"errors" , cols[3 ],"dropped" , _SL_);fprintf (fp," " ); -print_num (fp,10 , stats->tx_bytes); -print_num (fp,8 , stats->tx_packets); -print_num (fp,7 , stats->tx_errors); -print_num (fp,7 , stats->tx_dropped); +print_num (fp, cols[0 ], stats->tx_bytes); +print_num (fp, cols[1 ], stats->tx_packets); +print_num (fp, cols[2 ], stats->tx_errors); +print_num (fp, cols[3 ], stats->tx_dropped);fprintf (fp,"\n" ); }
Signature · 1 line
2.31.1
PATCH 2/10 iplink: Publish a function to format MPLS stats
In reply to Petr MachataExtract from print_mpls_stats() a new function, print_mpls_link_stats(), make it non-static and publish in the header file.
--- ip/ip_common.h | 3 +++ ip/iplink.c | 36 +++++++++++++++++++++--------------- 2 files changed, 24 insertions(+), 15 deletions(-)
ip/ip_common.h +3 -0
@@ -3,6 +3,7 @@#define _IP_COMMON_H_#include <stdbool.h> +#include <linux/mpls.h> #include "json_print.h"
@@ -202,4 +203,6 @@ void print_rta_gateway(FILE *fp, unsigned char family,void size_columns (unsigned int cols[],unsigned int n, ...);void print_stats64 (FILE *fp,struct rtnl_link_stats64 *s,const struct rtattr *carrier_changes,const char *what); +void print_mpls_link_stats (FILE *fp,const struct mpls_link_stats *stats, +const char *indent);#endif /* _IP_COMMON_H_ */
ip/iplink.c +21 -15
@@ -1517,10 +1517,9 @@ static int do_set(int argc, char **argv) }#endif /* IPLINK_IOCTL_COMPAT */ -static void print_mpls_stats (FILE *fp,struct rtattr *attr) +void print_mpls_link_stats (FILE *fp,const struct mpls_link_stats *stats, +const char *indent) { -struct rtattr *mrtb[MPLS_STATS_MAX +1 ]; -struct mpls_link_stats *stats;unsigned int cols[] = {strlen ("*X: bytes" ),strlen ("packets" ),
@@ -1529,14 +1528,6 @@ static void print_mpls_stats(FILE *fp, struct rtattr *attr) strlen("noroute"), }; -parse_rtattr (mrtb,MPLS_STATS_MAX ,RTA_DATA (attr), -RTA_PAYLOAD (attr)); -if (!mrtb[MPLS_STATS_LINK ]) -return ; - - stats =RTA_DATA (mrtb[MPLS_STATS_LINK ]); -fprintf (fp," mpls:\n" ); -size_columns (cols,ARRAY_SIZE (cols), stats->rx_bytes, stats->rx_packets, stats->rx_errors, stats->rx_dropped, stats->rx_noroute);
@@ -1544,11 +1535,11 @@ static void print_mpls_stats(FILE *fp, struct rtattr *attr) stats->tx_bytes, stats->tx_packets, stats->tx_errors, stats->tx_dropped, 0); -fprintf (fp," RX: %*s %*s %*s %*s %*s%s" , +fprintf (fp,"%sRX: %*s %*s %*s %*s %*s%s" , indent, cols[0 ] -4 ,"bytes" , cols[1 ],"packets" , cols[2 ],"errors" , cols[3 ],"dropped" , cols[4 ],"noroute" , _SL_); -fprintf (fp," " ); +fprintf (fp,"%s" , indent);print_num (fp, cols[0 ], stats->rx_bytes);print_num (fp, cols[1 ], stats->rx_packets);print_num (fp, cols[2 ], stats->rx_errors);
@@ -1556,10 +1547,10 @@ static void print_mpls_stats(FILE *fp, struct rtattr *attr)print_num (fp, cols[4 ], stats->rx_noroute);fprintf (fp,"\n" ); -fprintf (fp," TX: %*s %*s %*s %*s%s" , +fprintf (fp,"%sTX: %*s %*s %*s %*s%s" , indent, cols[0 ] -4 ,"bytes" , cols[1 ],"packets" , cols[2 ],"errors" , cols[3 ],"dropped" , _SL_); -fprintf (fp," " ); +fprintf (fp,"%s" , indent);print_num (fp, cols[0 ], stats->tx_bytes);print_num (fp, cols[1 ], stats->tx_packets);print_num (fp, cols[2 ], stats->tx_errors);
@@ -1567,6 +1558,21 @@ static void print_mpls_stats(FILE *fp, struct rtattr *attr)fprintf (fp,"\n" ); } +static void print_mpls_stats (FILE *fp,struct rtattr *attr) +{ +struct rtattr *mrtb[MPLS_STATS_MAX +1 ]; +struct mpls_link_stats *stats; + +parse_rtattr (mrtb,MPLS_STATS_MAX ,RTA_DATA (attr), +RTA_PAYLOAD (attr)); +if (!mrtb[MPLS_STATS_LINK ]) +return ; + + stats =RTA_DATA (mrtb[MPLS_STATS_LINK ]); +fprintf (fp," mpls:\n" ); +print_mpls_link_stats (fp, stats," " ); +} +static void print_af_stats_attr (FILE *fp,int ifindex,struct rtattr *attr) {bool if_printed = false;
Signature · 1 line
2.31.1
PATCH 3/10 ipstats: Add a group "afstats", subgroup "mpls"
In reply to Petr MachataAdd a new group, "afstats", for showing counters from the IFLA_STATS_AF_SPEC nest, and a subgroup "mpls" for the AF_MPLS specifically.
For example:
# ip -n ns0-NrdgY9sx stats show dev veth01 group afstats
3: veth01: group afstats subgroup mpls
RX: bytes packets errors dropped noroute
0 0 0 0 0
TX: bytes packets errors dropped
108 1 0 0--- ip/iplink.c | 2 +- ip/ipstats.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 1 deletion(-)
ip/iplink.c +1 -1
@@ -1555,7 +1555,6 @@ void print_mpls_link_stats(FILE *fp, const struct mpls_link_stats *stats,print_num (fp, cols[1 ], stats->tx_packets);print_num (fp, cols[2 ], stats->tx_errors);print_num (fp, cols[3 ], stats->tx_dropped); -fprintf (fp,"\n" ); }static void print_mpls_stats (FILE *fp,struct rtattr *attr)
@@ -1571,6 +1570,7 @@ static void print_mpls_stats(FILE *fp, struct rtattr *attr) stats =RTA_DATA (mrtb[MPLS_STATS_LINK ]);fprintf (fp," mpls:\n" );print_mpls_link_stats (fp, stats," " ); +fprintf (fp,"\n" ); }static void print_af_stats_attr (FILE *fp,int ifindex,struct rtattr *attr)
ip/ipstats.c +54 -0
63 lines not on this page · raw message
Signature · 1 line
2.31.1
PATCH 4/10 iplink: Add JSON support to MPLS stats formatter
In reply to Petr MachataMPLS stats currently do not support dumping in JSON format. Recognize when JSON is requested and dump in an obvious manner:
# ip -n ns0-2G8Ozd9z -j stats show dev veth01 group afstats | jq
[
{
"ifindex": 3,
"ifname": "veth01",
"group": "afstats",
"subgroup": "mpls",
"mpls_stats": {
"rx": {
"bytes": 0,
"packets": 0,
"errors": 0,
"dropped": 0,
"noroute": 0
},
"tx": {
"bytes": 216,
"packets": 2,
"errors": 0,
"dropped": 0
}
}
}
]--- ip/iplink.c | 69 ++++++++++++++++++++++++++++++++++------------------- 1 file changed, 44 insertions(+), 25 deletions(-)
ip/iplink.c +44 -25
@@ -1528,33 +1528,52 @@ void print_mpls_link_stats(FILE *fp, const struct mpls_link_stats *stats, strlen("noroute"), }; -size_columns (cols,ARRAY_SIZE (cols), - stats->rx_bytes, stats->rx_packets, stats->rx_errors, - stats->rx_dropped, stats->rx_noroute); -size_columns (cols,ARRAY_SIZE (cols), - stats->tx_bytes, stats->tx_packets, stats->tx_errors, - stats->tx_dropped,0 ); +if (is_json_context ()) { +/* RX stats */ +open_json_object ("rx" ); +print_u64 (PRINT_JSON ,"bytes" ,NULL , stats->rx_bytes); +print_u64 (PRINT_JSON ,"packets" ,NULL , stats->rx_packets); +print_u64 (PRINT_JSON ,"errors" ,NULL , stats->rx_errors); +print_u64 (PRINT_JSON ,"dropped" ,NULL , stats->rx_dropped); +print_u64 (PRINT_JSON ,"noroute" ,NULL , stats->rx_noroute); +close_json_object (); -fprintf (fp,"%sRX: %*s %*s %*s %*s %*s%s" , indent, - cols[0 ] -4 ,"bytes" , cols[1 ],"packets" , - cols[2 ],"errors" , cols[3 ],"dropped" , - cols[4 ],"noroute" , _SL_); -fprintf (fp,"%s" , indent); -print_num (fp, cols[0 ], stats->rx_bytes); -print_num (fp, cols[1 ], stats->rx_packets); -print_num (fp, cols[2 ], stats->rx_errors); -print_num (fp, cols[3 ], stats->rx_dropped); -print_num (fp, cols[4 ], stats->rx_noroute); -fprintf (fp,"\n" ); +/* TX stats */ +open_json_object ("tx" ); +print_u64 (PRINT_JSON ,"bytes" ,NULL , stats->tx_bytes); +print_u64 (PRINT_JSON ,"packets" ,NULL , stats->tx_packets); +print_u64 (PRINT_JSON ,"errors" ,NULL , stats->tx_errors); +print_u64 (PRINT_JSON ,"dropped" ,NULL , stats->tx_dropped); +close_json_object (); + }else { +size_columns (cols,ARRAY_SIZE (cols), stats->rx_bytes, + stats->rx_packets, stats->rx_errors, + stats->rx_dropped, stats->rx_noroute); +size_columns (cols,ARRAY_SIZE (cols), stats->tx_bytes, + stats->tx_packets, stats->tx_errors, + stats->tx_dropped,0 ); -fprintf (fp,"%sTX: %*s %*s %*s %*s%s" , indent, - cols[0 ] -4 ,"bytes" , cols[1 ],"packets" , - cols[2 ],"errors" , cols[3 ],"dropped" , _SL_); -fprintf (fp,"%s" , indent); -print_num (fp, cols[0 ], stats->tx_bytes); -print_num (fp, cols[1 ], stats->tx_packets); -print_num (fp, cols[2 ], stats->tx_errors); -print_num (fp, cols[3 ], stats->tx_dropped); +fprintf (fp,"%sRX: %*s %*s %*s %*s %*s%s" , indent, + cols[0 ] -4 ,"bytes" , cols[1 ],"packets" , + cols[2 ],"errors" , cols[3 ],"dropped" , + cols[4 ],"noroute" , _SL_); +fprintf (fp,"%s" , indent); +print_num (fp, cols[0 ], stats->rx_bytes); +print_num (fp, cols[1 ], stats->rx_packets); +print_num (fp, cols[2 ], stats->rx_errors); +print_num (fp, cols[3 ], stats->rx_dropped); +print_num (fp, cols[4 ], stats->rx_noroute); +fprintf (fp,"\n" ); + +fprintf (fp,"%sTX: %*s %*s %*s %*s%s" , indent, + cols[0 ] -4 ,"bytes" , cols[1 ],"packets" , + cols[2 ],"errors" , cols[3 ],"dropped" , _SL_); +fprintf (fp,"%s" , indent); +print_num (fp, cols[0 ], stats->tx_bytes); +print_num (fp, cols[1 ], stats->tx_packets); +print_num (fp, cols[2 ], stats->tx_errors); +print_num (fp, cols[3 ], stats->tx_dropped); + } }static void print_mpls_stats (FILE *fp,struct rtattr *attr)
Signature · 1 line
2.31.1
PATCH 5/10 ipstats: Add a third level of stats hierarchy, a "suite"
In reply to Petr MachataTo show statistics nested under IFLA_STATS_LINK_XSTATS_SLAVE or IFLA_STATS_LINK_XSTATS, one would use "group" to select the top-level attribute, then "subgroup" to select the link type, which is itself a nest, and then would lack a way to denote which attribute to select out of the link-type nest.
To that end, add the selector level "suite", which is filtered in the userspace.
--- ip/ipstats.c | 9 ++++++++- man/man8/ip-stats.8 | 3 ++- 2 files changed, 10 insertions(+), 2 deletions(-)
ip/ipstats.c +8 -1
@@ -34,6 +34,7 @@ struct ipstats_stat_show_attrs {static const char *const ipstats_levels[] = {"group" ,"subgroup" , +"suite" , };enum {
@@ -1024,7 +1025,7 @@ static int do_help(void)fprintf (stderr,"Usage: ip stats help\n" -" ip stats show [ dev DEV ] [ group GROUP [ subgroup SUBGROUP ] ... ] ...\n" +" ip stats show [ dev DEV ] [ group GROUP [ subgroup SUBGROUP [ suite SUITE ] ... ] ... ] ...\n" " ip stats set dev DEV l3_stats { on | off }\n" );
@@ -1048,6 +1049,8 @@ static int do_help(void)continue ;for (j =0 ; j < desc->nsubs; j++) { +size_t k; +if (j ==0 )fprintf (stderr,"%s SUBGROUP := {" , desc->name);else
@@ -1057,6 +1060,10 @@ static int do_help(void)if (desc->subs[j]->kind !=IPSTATS_STAT_DESC_KIND_GROUP )continue ; + +for (k =0 ; k < desc->subs[j]->nsubs; k++) +fprintf (stderr," [ suite %s ]" , + desc->subs[j]->subs[k]->name); }if (opened)fprintf (stderr," }\n" );
man/man8/ip-stats.8 +2 -1
@@ -19,7 +19,8 @@ ip-stats \- manage and show interface statistics .RB "[ " group .IR GROUP " [ " .BI subgroup " SUBGROUP" -.R " ] ... ] ..." +.RB " [ " suite +.IR " SUITE" " ] ... ] ... ] ..." .ti -8 .BR "ip stats set"
Signature · 1 line
2.31.1
PATCH 6/10 ipstats: Add groups "xstats", "xstats_slave"
In reply to Petr MachataThe 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.
--- ip/ip_common.h | 14 ++++++++++++ ip/ipstats.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+)
ip/ip_common.h +14 -0
@@ -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
ip/ipstats.c +59 -0
77 lines not on this page · raw message
Signature · 1 line
2.31.1
PATCH 7/10 iplink_bridge: Split bridge_print_stats_attr()
In reply to Petr MachataExtract from bridge_print_stats_attr() two helpers, one for dumping the multicast attribute, one for dumping the STP attribute.
--- ip/iplink_bridge.c | 254 ++++++++++++++++++++++++--------------------- 1 file changed, 133 insertions(+), 121 deletions(-)
ip/iplink_bridge.c +133 -121
@@ -714,11 +714,140 @@ static void bridge_print_xstats_help(struct link_util *lu, FILE *f)fprintf (f,"Usage: ... %s [ igmp ] [ dev DEVICE ]\n" , lu->id); } +static void bridge_print_stats_mcast (const struct rtattr *attr) +{ +struct br_mcast_stats *mstats; + + mstats =RTA_DATA (attr); +open_json_object ("multicast" ); +open_json_object ("igmp_queries" ); +print_string (PRINT_FP ,NULL , +"%-16s IGMP queries:\n" ,"" ); +print_string (PRINT_FP ,NULL ,"%-16s " ,"" ); +print_u64 (PRINT_ANY ,"rx_v1" ,"RX: v1 %llu " , + mstats->igmp_v1queries[BR_MCAST_DIR_RX ]); +print_u64 (PRINT_ANY ,"rx_v2" ,"v2 %llu " , + mstats->igmp_v2queries[BR_MCAST_DIR_RX ]); +print_u64 (PRINT_ANY ,"rx_v3" ,"v3 %llu\n" , + mstats->igmp_v3queries[BR_MCAST_DIR_RX ]); +print_string (PRINT_FP ,NULL ,"%-16s " ,"" ); +print_u64 (PRINT_ANY ,"tx_v1" ,"TX: v1 %llu " , + mstats->igmp_v1queries[BR_MCAST_DIR_TX ]); +print_u64 (PRINT_ANY ,"tx_v2" ,"v2 %llu " , + mstats->igmp_v2queries[BR_MCAST_DIR_TX ]); +print_u64 (PRINT_ANY ,"tx_v3" ,"v3 %llu\n" , + mstats->igmp_v3queries[BR_MCAST_DIR_TX ]); +close_json_object (); + +open_json_object ("igmp_reports" ); +print_string (PRINT_FP ,NULL , +"%-16s IGMP reports:\n" ,"" ); +print_string (PRINT_FP ,NULL ,"%-16s " ,"" ); +print_u64 (PRINT_ANY ,"rx_v1" ,"RX: v1 %llu " , + mstats->igmp_v1reports[BR_MCAST_DIR_RX ]); +print_u64 (PRINT_ANY ,"rx_v2" ,"v2 %llu " , + mstats->igmp_v2reports[BR_MCAST_DIR_RX ]); +print_u64 (PRINT_ANY ,"rx_v3" ,"v3 %llu\n" , + mstats->igmp_v3reports[BR_MCAST_DIR_RX ]); +print_string (PRINT_FP ,NULL ,"%-16s " ,"" ); +print_u64 (PRINT_ANY ,"tx_v1" ,"TX: v1 %llu " , + mstats->igmp_v1reports[BR_MCAST_DIR_TX ]); +print_u64 (PRINT_ANY ,"tx_v2" ,"v2 %llu " , + mstats->igmp_v2reports[BR_MCAST_DIR_TX ]); +print_u64 (PRINT_ANY ,"tx_v3" ,"v3 %llu\n" , + mstats->igmp_v3reports[BR_MCAST_DIR_TX ]); +close_json_object (); + +open_json_object ("igmp_leaves" ); +print_string (PRINT_FP ,NULL , +"%-16s IGMP leaves: " ,"" ); +print_u64 (PRINT_ANY ,"rx" ,"RX: %llu " , + mstats->igmp_leaves[BR_MCAST_DIR_RX ]); +print_u64 (PRINT_ANY ,"tx" ,"TX: %llu\n" , + mstats->igmp_leaves[BR_MCAST_DIR_TX ]); +close_json_object (); + +print_string (PRINT_FP ,NULL , +"%-16s IGMP parse errors: " ,"" ); +print_u64 (PRINT_ANY ,"igmp_parse_errors" ,"%llu\n" , + mstats->igmp_parse_errors); + +open_json_object ("mld_queries" ); +print_string (PRINT_FP ,NULL , +"%-16s MLD queries:\n" ,"" ); +print_string (PRINT_FP ,NULL ,"%-16s " ,"" ); +print_u64 (PRINT_ANY ,"rx_v1" ,"RX: v1 %llu " , + mstats->mld_v1queries[BR_MCAST_DIR_RX ]); +print_u64 (PRINT_ANY ,"rx_v2" ,"v2 %llu\n" , + mstats->mld_v2queries[BR_MCAST_DIR_RX ]); +print_string (PRINT_FP ,NULL ,"%-16s " ,"" ); +print_u64 (PRINT_ANY ,"tx_v1" ,"TX: v1 %llu " , + mstats->mld_v1queries[BR_MCAST_DIR_TX ]); +print_u64 (PRINT_ANY ,"tx_v2" ,"v2 %llu\n" , + mstats->mld_v2queries[BR_MCAST_DIR_TX ]); +close_json_object (); + +open_json_object ("mld_reports" ); +print_string (PRINT_FP ,NULL , +"%-16s MLD reports:\n" ,"" ); +print_string (PRINT_FP ,NULL ,"%-16s " ,"" ); +print_u64 (PRINT_ANY ,"rx_v1" ,"RX: v1 %llu " , + mstats->mld_v1reports[BR_MCAST_DIR_RX ]); +print_u64 (PRINT_ANY ,"rx_v2" ,"v2 %llu\n" , + mstats->mld_v2reports[BR_MCAST_DIR_RX ]); +print_string (PRINT_FP ,NULL ,"%-16s " ,"" ); +print_u64 (PRINT_ANY ,"tx_v1" ,"TX: v1 %llu " , + mstats->mld_v1reports[BR_MCAST_DIR_TX ]); +print_u64 (PRINT_ANY ,"tx_v2" ,"v2 %llu\n" , + mstats->mld_v2reports[BR_MCAST_DIR_TX ]); +close_json_object (); + +open_json_object ("mld_leaves" ); +print_string (PRINT_FP ,NULL , +"%-16s MLD leaves: " ,"" ); +print_u64 (PRINT_ANY ,"rx" ,"RX: %llu " , + mstats->mld_leaves[BR_MCAST_DIR_RX ]); +print_u64 (PRINT_ANY ,"tx" ,"TX: %llu\n" , + mstats->mld_leaves[BR_MCAST_DIR_TX ]); +close_json_object (); + +print_string (PRINT_FP ,NULL , +"%-16s MLD parse errors: " ,"" ); +print_u64 (PRINT_ANY ,"mld_parse_errors" ,"%llu\n" , + mstats->mld_parse_errors); +close_json_object (); +} + +static void bridge_print_stats_stp (const struct rtattr *attr) +{ +struct bridge_stp_xstats *sstats; + + sstats =RTA_DATA (attr); +open_json_object ("stp" ); +print_string (PRINT_FP ,NULL , +"%-16s STP BPDU: " ,"" ); +print_u64 (PRINT_ANY ,"rx_bpdu" ,"RX: %llu " , + sstats->rx_bpdu); +print_u64 (PRINT_ANY ,"tx_bpdu" ,"TX: %llu\n" , + sstats->tx_bpdu); +print_string (PRINT_FP ,NULL , +"%-16s STP TCN: " ,"" ); +print_u64 (PRINT_ANY ,"rx_tcn" ,"RX: %llu " , + sstats->rx_tcn); +print_u64 (PRINT_ANY ,"tx_tcn" ,"TX: %llu\n" , + sstats->tx_tcn); +print_string (PRINT_FP ,NULL , +"%-16s STP Transitions: " ,"" ); +print_u64 (PRINT_ANY ,"transition_blk" ,"Blocked: %llu " , + sstats->transition_blk); +print_u64 (PRINT_ANY ,"transition_fwd" ,"Forwarding: %llu\n" , + sstats->transition_fwd); +close_json_object (); +} +static void bridge_print_stats_attr (struct rtattr *attr,int ifindex) {struct rtattr *brtb[LINK_XSTATS_TYPE_MAX +1 ]; -struct bridge_stp_xstats *sstats; -struct br_mcast_stats *mstats;struct rtattr *i, *list;const char *ifname ="" ;int rem;
@@ -738,127 +867,10 @@ static void bridge_print_stats_attr(struct rtattr *attr, int ifindex)continue ;switch (i->rta_type) {case BRIDGE_XSTATS_MCAST : - mstats =RTA_DATA (i); -open_json_object ("multicast" ); -open_json_object ("igmp_queries" ); -print_string (PRINT_FP ,NULL , -"%-16s IGMP queries:\n" ,"" ); -print_string (PRINT_FP ,NULL ,"%-16s " ,"" ); -print_u64 (PRINT_ANY ,"rx_v1" ,"RX: v1 %llu " , - mstats->igmp_v1queries[BR_MCAST_DIR_RX ]); -print_u64 (PRINT_ANY ,"rx_v2" ,"v2 %llu " , - mstats->igmp_v2queries[BR_MCAST_DIR_RX ]); -print_u64 (PRINT_ANY ,"rx_v3" ,"v3 %llu\n" , - mstats->igmp_v3queries[BR_MCAST_DIR_RX ]); -print_string (PRINT_FP ,NULL ,"%-16s " ,"" ); -print_u64 (PRINT_ANY ,"tx_v1" ,"TX: v1 %llu " , - mstats->igmp_v1queries[BR_MCAST_DIR_TX ]); -print_u64 (PRINT_ANY ,"tx_v2" ,"v2 %llu " , - mstats->igmp_v2queries[BR_MCAST_DIR_TX ]); -print_u64 (PRINT_ANY ,"tx_v3" ,"v3 %llu\n" , - mstats->igmp_v3queries[BR_MCAST_DIR_TX ]); -close_json_object (); - -open_json_object ("igmp_reports" ); -print_string (PRINT_FP ,NULL , -"%-16s IGMP reports:\n" ,"" ); -print_string (PRINT_FP ,NULL ,"%-16s " ,"" ); -print_u64 (PRINT_ANY ,"rx_v1" ,"RX: v1 %llu " , - mstats->igmp_v1reports[BR_MCAST_DIR_RX ]); -print_u64 (PRINT_ANY ,"rx_v2" ,"v2 %llu " , - mstats->igmp_v2reports[BR_MCAST_DIR_RX ]); -print_u64 (PRINT_ANY ,"rx_v3" ,"v3 %llu\n" , - mstats->igmp_v3reports[BR_MCAST_DIR_RX ]); -print_string (PRINT_FP ,NULL ,"%-16s " ,"" ); -print_u64 (PRINT_ANY ,"tx_v1" ,"TX: v1 %llu " , - mstats->igmp_v1reports[BR_MCAST_DIR_TX ]); -print_u64 (PRINT_ANY ,"tx_v2" ,"v2 %llu " , - mstats->igmp_v2reports[BR_MCAST_DIR_TX ]); -print_u64 (PRINT_ANY ,"tx_v3" ,"v3 %llu\n" , - mstats->igmp_v3reports[BR_MCAST_DIR_TX ]); -close_json_object (); - -open_json_object ("igmp_leaves" ); -print_string (PRINT_FP ,NULL , -"%-16s IGMP leaves: " ,"" ); -print_u64 (PRINT_ANY ,"rx" ,"RX: %llu " , - mstats->igmp_leaves[BR_MCAST_DIR_RX ]); -print_u64 (PRINT_ANY ,"tx" ,"TX: %llu\n" , - mstats->igmp_leaves[BR_MCAST_DIR_TX ]); -close_json_object (); - -print_string (PRINT_FP ,NULL , -"%-16s IGMP parse errors: " ,"" ); -print_u64 (PRINT_ANY ,"igmp_parse_errors" ,"%llu\n" , - mstats->igmp_parse_errors); - -open_json_object ("mld_queries" ); -print_string (PRINT_FP ,NULL , -"%-16s MLD queries:\n" ,"" ); -print_string (PRINT_FP ,NULL ,"%-16s " ,"" ); -print_u64 (PRINT_ANY ,"rx_v1" ,"RX: v1 %llu " , - mstats->mld_v1queries[BR_MCAST_DIR_RX ]); -print_u64 (PRINT_ANY ,"rx_v2" ,"v2 %llu\n" , - mstats->mld_v2queries[BR_MCAST_DIR_RX ]); -print_string (PRINT_FP ,NULL ,"%-16s " ,"" ); -print_u64 (PRINT_ANY ,"tx_v1" ,"TX: v1 %llu " , - mstats->mld_v1queries[BR_MCAST_DIR_TX ]); -print_u64 (PRINT_ANY ,"tx_v2" ,"v2 %llu\n" , - mstats->mld_v2queries[BR_MCAST_DIR_TX ]); -close_json_object (); - -open_json_object ("mld_reports" ); -print_string (PRINT_FP ,NULL , -"%-16s MLD reports:\n" ,"" ); -print_string (PRINT_FP ,NULL ,"%-16s " ,"" ); -print_u64 (PRINT_ANY ,"rx_v1" ,"RX: v1 %llu " , - mstats->mld_v1reports[BR_MCAST_DIR_RX ]); -print_u64 (PRINT_ANY ,"rx_v2" ,"v2 %llu\n" , - mstats->mld_v2reports[BR_MCAST_DIR_RX ]); -print_string (PRINT_FP ,NULL ,"%-16s " ,"" ); -print_u64 (PRINT_ANY ,"tx_v1" ,"TX: v1 %llu " , - mstats->mld_v1reports[BR_MCAST_DIR_TX ]); -print_u64 (PRINT_ANY ,"tx_v2" ,"v2 %llu\n" , - mstats->mld_v2reports[BR_MCAST_DIR_TX ]); -close_json_object (); - -open_json_object ("mld_leaves" ); -print_string (PRINT_FP ,NULL , -"%-16s MLD leaves: " ,"" ); -print_u64 (PRINT_ANY ,"rx" ,"RX: %llu " , - mstats->mld_leaves[BR_MCAST_DIR_RX ]); -print_u64 (PRINT_ANY ,"tx" ,"TX: %llu\n" , - mstats->mld_leaves[BR_MCAST_DIR_TX ]); -close_json_object (); - -print_string (PRINT_FP ,NULL , -"%-16s MLD parse errors: " ,"" ); -print_u64 (PRINT_ANY ,"mld_parse_errors" ,"%llu\n" , - mstats->mld_parse_errors); -close_json_object (); +bridge_print_stats_mcast (i);break ;case BRIDGE_XSTATS_STP : - sstats =RTA_DATA (i); -open_json_object ("stp" ); -print_string (PRINT_FP ,NULL , -"%-16s STP BPDU: " ,"" ); -print_u64 (PRINT_ANY ,"rx_bpdu" ,"RX: %llu " , - sstats->rx_bpdu); -print_u64 (PRINT_ANY ,"tx_bpdu" ,"TX: %llu\n" , - sstats->tx_bpdu); -print_string (PRINT_FP ,NULL , -"%-16s STP TCN: " ,"" ); -print_u64 (PRINT_ANY ,"rx_tcn" ,"RX: %llu " , - sstats->rx_tcn); -print_u64 (PRINT_ANY ,"tx_tcn" ,"TX: %llu\n" , - sstats->tx_tcn); -print_string (PRINT_FP ,NULL , -"%-16s STP Transitions: " ,"" ); -print_u64 (PRINT_ANY ,"transition_blk" ,"Blocked: %llu " , - sstats->transition_blk); -print_u64 (PRINT_ANY ,"transition_fwd" ,"Forwarding: %llu\n" , - sstats->transition_fwd); -close_json_object (); +bridge_print_stats_stp (i);break ; } }
Signature · 1 line
2.31.1
PATCH 8/10 ipstats: Expose bridge stats in ipstats
In reply to Petr MachataBridge supports two suites, STP and IGMP, carried by attributes BRIDGE_XSTATS_STP and BRIDGE_XSTATS_MCAST. Expose them as suites "stp" and "mcast" (to correspond to the attribute name).
For example:
# ip stats show dev swp1 group xstats_slave subgroup bridge
56: swp1: group xstats_slave subgroup bridge suite mcast
IGMP queries:
RX: v1 0 v2 0 v3 0
TX: v1 0 v2 0 v3 0
IGMP reports:
RX: v1 0 v2 0 v3 0
TX: v1 0 v2 0 v3 0
IGMP leaves: RX: 0 TX: 0
IGMP parse errors: 0
MLD queries:
RX: v1 0 v2 0
TX: v1 0 v2 0
MLD reports:
RX: v1 0 v2 0
TX: v1 0 v2 0
MLD leaves: RX: 0 TX: 0
MLD parse errors: 0 56: swp1: group xstats_slave subgroup bridge suite stp
STP BPDU: RX: 0 TX: 0
STP TCN: RX: 0 TX: 0
STP Transitions: Blocked: 1 Forwarding: 0
# ip -j stats show dev swp1 group xstats_slave subgroup bridge | jq
[
{
"ifindex": 56,
"ifname": "swp1",
"group": "xstats_slave",
"subgroup": "bridge",
"suite": "mcast",
"multicast": {
"igmp_queries": {
"rx_v1": 0,
"rx_v2": 0,
"rx_v3": 0,
"tx_v1": 0,
"tx_v2": 0,
"tx_v3": 0
},
"igmp_reports": {
"rx_v1": 0,
"rx_v2": 0,
"rx_v3": 0,
"tx_v1": 0,
"tx_v2": 0,
"tx_v3": 0
},
"igmp_leaves": {
"rx": 0,
"tx": 0
},
"igmp_parse_errors": 0,
"mld_queries": {
"rx_v1": 0,
"rx_v2": 0,
"tx_v1": 0,
"tx_v2": 0
},
"mld_reports": {
"rx_v1": 0,
"rx_v2": 0,
"tx_v1": 0,
"tx_v2": 0
},
"mld_leaves": {
"rx": 0,
"tx": 0
},
"mld_parse_errors": 0
}
},
{
"ifindex": 56,
"ifname": "swp1",
"group": "xstats_slave",
"subgroup": "bridge",
"suite": "stp",
"stp": {
"rx_bpdu": 0,
"tx_bpdu": 0,
"rx_tcn": 0,
"tx_tcn": 0,
"transition_blk": 1,
"transition_fwd": 0
}
}
]--- ip/ip_common.h | 2 ++ ip/iplink_bridge.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++ ip/ipstats.c | 2 ++ 3 files changed, 84 insertions(+)
ip/ip_common.h +2 -0
@@ -142,6 +142,8 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req, char **type);void br_dump_bridge_id (const struct ifla_bridge_id *id,char *buf,size_t len);int bridge_parse_xstats (struct link_util *lu,int argc,char **argv);int bridge_print_xstats (struct nlmsghdr *n,void *arg); +extern const struct ipstats_stat_desc ipstats_stat_desc_xstats_bridge_group; +extern const struct ipstats_stat_desc ipstats_stat_desc_xstats_slave_bridge_group;int bond_parse_xstats (struct link_util *lu,int argc,char **argv);int bond_print_xstats (struct nlmsghdr *n,void *arg);
ip/iplink_bridge.c +80 -0
83 lines not on this page · raw message
ip/ipstats.c +2 -0
@@ -605,6 +605,7 @@ int ipstats_stat_desc_show_xstats(struct ipstats_stat_show_attrs *attrs, }static const struct ipstats_stat_desc *ipstats_stat_desc_xstats_subs[] = { + &ipstats_stat_desc_xstats_bridge_group, };static const struct ipstats_stat_desc ipstats_stat_desc_xstats_group = {
@@ -615,6 +616,7 @@ static const struct ipstats_stat_desc ipstats_stat_desc_xstats_group = { };static const struct ipstats_stat_desc *ipstats_stat_desc_xstats_slave_subs[] = { + &ipstats_stat_desc_xstats_slave_bridge_group, };static const struct ipstats_stat_desc ipstats_stat_desc_xstats_slave_group = {
Signature · 1 line
2.31.1
PATCH 9/10 ipstats: Expose bond stats in ipstats
In reply to Petr MachataDescribe xstats and xstats_slave subgroups for bond netdevices.
For example:
# ip stats show dev swp1 group xstats_slave subgroup bond
56: swp1: group xstats_slave subgroup bond suite 802.3ad
LACPDU Rx 0
LACPDU Tx 0
LACPDU Unknown type Rx 0
LACPDU Illegal Rx 0
Marker Rx 0
Marker Tx 0
Marker response Rx 0
Marker response Tx 0
Marker unknown type Rx 0 # ip -j stats show dev swp1 group xstats_slave subgroup bond | jq
[
{
"ifindex": 56,
"ifname": "swp1",
"group": "xstats_slave",
"subgroup": "bond",
"suite": "802.3ad",
"802.3ad": {
"lacpdu_rx": 0,
"lacpdu_tx": 0,
"lacpdu_unknown_rx": 0,
"lacpdu_illegal_rx": 0,
"marker_rx": 0,
"marker_tx": 0,
"marker_response_rx": 0,
"marker_response_tx": 0,
"marker_unknown_rx": 0
}
}
]--- ip/ip_common.h | 3 +++ ip/iplink_bond.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++-- ip/ipstats.c | 2 ++ 3 files changed, 58 insertions(+), 2 deletions(-)
ip/ip_common.h +3 -0
@@ -145,8 +145,11 @@ int bridge_print_xstats(struct nlmsghdr *n, void *arg);extern const struct ipstats_stat_desc ipstats_stat_desc_xstats_bridge_group;extern const struct ipstats_stat_desc ipstats_stat_desc_xstats_slave_bridge_group; +/* iplink_bond.c */ int bond_parse_xstats (struct link_util *lu,int argc,char **argv);int bond_print_xstats (struct nlmsghdr *n,void *arg); +extern const struct ipstats_stat_desc ipstats_stat_desc_xstats_bond_group; +extern const struct ipstats_stat_desc ipstats_stat_desc_xstats_slave_bond_group;/* iproute_lwtunnel.c */ int lwt_parse_encap(struct rtattr *rta, size_t len, int *argcp, char ***argvp,
ip/iplink_bond.c +53 -2
76 lines not on this page · raw message
ip/ipstats.c +2 -0
@@ -606,6 +606,7 @@ int ipstats_stat_desc_show_xstats(struct ipstats_stat_show_attrs *attrs,static const struct ipstats_stat_desc *ipstats_stat_desc_xstats_subs[] = { &ipstats_stat_desc_xstats_bridge_group, + &ipstats_stat_desc_xstats_bond_group, };static const struct ipstats_stat_desc ipstats_stat_desc_xstats_group = {
@@ -617,6 +618,7 @@ static const struct ipstats_stat_desc ipstats_stat_desc_xstats_group = {static const struct ipstats_stat_desc *ipstats_stat_desc_xstats_slave_subs[] = { &ipstats_stat_desc_xstats_slave_bridge_group, + &ipstats_stat_desc_xstats_slave_bond_group, };static const struct ipstats_stat_desc ipstats_stat_desc_xstats_slave_group = {
Signature · 1 line
2.31.1
Re: [PATCH iproute2-next 09/10] ipstats: Expose bond stats in ipstats
Quoted 38 lines · On Mon, 9 May 2022 16:00:02 +0200 Petr Machata <[email protected]> wrote:
Describe xstats and
xstats_slavesubgroups for bond netdevices.For example:
# ip stats show dev swp1 group xstats_slave subgroup bond 56: swp1: group xstats_slave subgroup bond suite 802.3ad LACPDU Rx 0 LACPDU Tx 0 LACPDU Unknown type Rx 0 LACPDU Illegal Rx 0 Marker Rx 0 Marker Tx 0 Marker response Rx 0 Marker response Tx 0 Marker unknown type Rx 0# ip -j stats show dev swp1 group xstats_slave subgroup bond | jq [ { "ifindex": 56, "ifname": "swp1", "group": "xstats_slave", "subgroup": "bond", "suite": "802.3ad", "802.3ad": { "lacpdu_rx": 0, "lacpdu_tx": 0, "lacpdu_unknown_rx": 0, "lacpdu_illegal_rx": 0, "marker_rx": 0, "marker_tx": 0, "marker_response_rx": 0, "marker_response_tx": 0, "marker_unknown_rx": 0 } } ]
Quoted 7 lines
Signed-off-by Petr Machata <[email protected]>Reviewed-by Ido Schimmel <[email protected]>--- ip/ip_common.h | 3 +++ ip/iplink_bond.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++-- ip/ipstats.c | 2 ++ 3 files changed, 58 insertions(+), 2 deletions(-)
This change won't build if clang is used to build iproute2. It has valid warning:
CC iplink_bond.o
iplink_bond.c:935:10: error: initializer element is not a compile-time constant
.desc = ipstats_stat_desc_bond_tmpl_lacp,
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
iplink_bond.c:957:10: error: initializer element is not a compile-time constant
.desc = ipstats_stat_desc_bond_tmpl_lacp,
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2 errors generated.
Since desc is a structure, you can't just assign an existing data structure to the new initializer. It needs to be a pointer or macro.
Re: [PATCH iproute2-next 09/10] ipstats: Expose bond stats in ipstats
Quoted 12 lines · Stephen Hemminger
This change won't build if clang is used to build iproute2. It has valid warning:
CC iplink_bond.o
iplink_bond.c:935:10: error: initializer element is not a compile-time constant
.desc =ipstats_stat_desc_bond_tmpl_lacp,
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
iplink_bond.c:957:10: error: initializer element is not a compile-time constant
.desc =ipstats_stat_desc_bond_tmpl_lacp,
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2 errors generated.
Quoted 2 lines
Since desc is a structure, you can't just assign an existing data structure to the new initializer. It needs to be a pointer or macro.
Yeah, it has to be a macro. I'll send a patch probably next week.
PATCH 10/10 man: ip-stats.8: Describe groups xstats, xstats_slave and afstats
In reply to Petr MachataAdd description of the newly-added statistics groups.
--- man/man8/ip-stats.8 | 47 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+)
man/man8/ip-stats.8 +47 -0
@@ -68,6 +68,20 @@ The following groups are recognized: - A group that contains a number of HW-oriented statistics. See below for individual subgroups within this group. +.ti 14 +.B group xstats +- Extended statistics. A subgroup identifies the type of netdevice to show the +statistics for. + +.ti 14 +.B group xstats_slave +- Extended statistics for the slave of a netdevice of a given type. A subgroup +identifies the type of master netdevice. + +.ti 14 +.B group afstats +- A group for address-family specific netdevice statistics. + .TQ .BR "group offload " subgroups: .in 21
@@ -133,6 +147,39 @@ For example: Note how the l3_stats_info for the selected group is also part of the dump. +.TQ +.BR "group xstats " and " group xstats_slave " subgroups: +.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. + +.ti 14 +.B subgroup bond \fR[\fB suite 802.3ad \fR] +- Statistics for LACP traffic on bond devices and their slaves. + +.TQ +.BR "group afstats " subgroups: +.in 21 + +.ti 14 +.B subgroup mpls +- Statistics for MPLS traffic seen on the netdevice. For example: + +# ip stats show dev veth01 group afstats subgroup mpls +.br +3: veth01: group afstats subgroup mpls +.br + RX: bytes packets errors dropped noroute +.br + 0 0 0 0 0 +.br + TX: bytes packets errors dropped +.br + 216 2 0 0 + .SH EXAMPLES .PP # ip stats set dev swp1 l3_stats on
Signature · 1 line
2.31.1
This series was applied to iproute2/iproute2-next.git (main) by David Ahern <[email protected]>:
Hello:
This series was applied to iproute2/iproute2-next.git (main) by David Ahern <[email protected]>:
Quoted 11 lines · On Mon, 9 May 2022 15:59:53 +0200 you wrote:
The
RTM_GETSTATSresponse attributesIFLA_STATS_LINK_XSTATSandIFLA_STATS_LINK_XSTATS_SLAVEare used to carry statistics related to, respectively, netdevices of a certain type, and netdevices enslaved to netdevices of a certain type.IFLA_STATS_AF_SPECare similarly used to carry statistics specific to a certain address family.In this patch set, add support for three new stats groups that cover the above attributes: xstats,
xstats_slaveand afstats. Add bridge and bond subgroups to the former two groups, and mpls subgroup to the latter one.[...]
Here is the summary with links:
- [iproute2-next,01/10] iplink: Fix formatting of MPLS stats
https://git.kernel.org/pub/scm/network/iproute2/iproute2-next.git/commit/?id=72623b73c4ea - [iproute2-next,02/10] iplink: Publish a function to format MPLS stats https://git.kernel.org/pub/scm/network/iproute2/iproute2-next.git/commit/?id=dff392fd86ee - [iproute2-next,03/10] ipstats: Add a group "afstats", subgroup "mpls" https://git.kernel.org/pub/scm/network/iproute2/iproute2-next.git/commit/?id=5ed8fd9d5144 - [iproute2-next,04/10] iplink: Add JSON support to MPLS stats formatter (no matching commit) - [iproute2-next,05/10] ipstats: Add a third level of stats hierarchy, a "suite" https://git.kernel.org/pub/scm/network/iproute2/iproute2-next.git/commit/?id=c6900b79b13d - [iproute2-next,06/10] ipstats: Add groups "xstats", "xstats_slave" https://git.kernel.org/pub/scm/network/iproute2/iproute2-next.git/commit/?id=1247ed51e924 - [iproute2-next,07/10] iplink_bridge: Split bridge_print_stats_attr() https://git.kernel.org/pub/scm/network/iproute2/iproute2-next.git/commit/?id=79f5ad95c17c - [iproute2-next,08/10] ipstats: Expose bridge stats in ipstats https://git.kernel.org/pub/scm/network/iproute2/iproute2-next.git/commit/?id=36e10429dafc - [iproute2-next,09/10] ipstats: Expose bond stats in ipstats https://git.kernel.org/pub/scm/network/iproute2/iproute2-next.git/commit/?id=d9976d671c37 - [iproute2-next,10/10] man: ip-stats.8: Describe groups xstats, xstats_slave and afstats https://git.kernel.org/pub/scm/network/iproute2/iproute2-next.git/commit/?id=5a1ad9f8c1e6
You are awesome, thank you!
Signature · 2 lines
Deet-doot-dot, I am a bot. https://korg.docs.kernel.org/patchwork/pwbot.html