From 9e89d5b94d749f37525cd8778311e1c9f28f172a Mon Sep 17 00:00:00 2001 From: Petr Machata Date: Tue, 10 Jun 2025 17:51:26 +0200 Subject: [PATCH] lib: bridge: Add a module for bridge-related helpers `ip 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. Signed-off-by: Petr Machata Reviewed-by: Ido Schimmel Acked-by: Nikolay Aleksandrov Signed-off-by: David Ahern --- 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 diff --git a/MAINTAINERS b/MAINTAINERS index c9ea3ea5a..82043c1ba 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -31,6 +31,8 @@ M: Nikolay Aleksandrov L: bridge@lists.linux-foundation.org (moderated for non-subscribers) F: bridge/* F: ip/iplink_bridge* +F: lib/bridge* +F: include/bridge* Data Center Bridging - dcb M: Petr Machata diff --git a/bridge/vlan.c b/bridge/vlan.c index ea4aff931..14b8475d9 100644 --- a/bridge/vlan.c +++ b/bridge/vlan.c @@ -15,6 +15,7 @@ #include "json_print.h" #include "libnetlink.h" #include "br_common.h" +#include "bridge.h" #include "utils.h" static unsigned int filter_index, filter_vlan; @@ -705,47 +706,6 @@ static int print_vlan(struct nlmsghdr *n, void *arg) return 0; } -static void print_vlan_flags(__u16 flags) -{ - if (flags == 0) - return; - - open_json_array(PRINT_JSON, "flags"); - if (flags & BRIDGE_VLAN_INFO_PVID) - print_string(PRINT_ANY, NULL, " %s", "PVID"); - - if (flags & BRIDGE_VLAN_INFO_UNTAGGED) - print_string(PRINT_ANY, NULL, " %s", "Egress Untagged"); - close_json_array(PRINT_JSON, NULL); -} - -static void __print_one_vlan_stats(const struct bridge_vlan_xstats *vstats) -{ - print_string(PRINT_FP, NULL, "%-" textify(IFNAMSIZ) "s ", ""); - print_lluint(PRINT_ANY, "rx_bytes", "RX: %llu bytes", - vstats->rx_bytes); - print_lluint(PRINT_ANY, "rx_packets", " %llu packets\n", - vstats->rx_packets); - - print_string(PRINT_FP, NULL, "%-" textify(IFNAMSIZ) "s ", ""); - print_lluint(PRINT_ANY, "tx_bytes", "TX: %llu bytes", - vstats->tx_bytes); - print_lluint(PRINT_ANY, "tx_packets", " %llu packets\n", - vstats->tx_packets); -} - -static void print_one_vlan_stats(const struct bridge_vlan_xstats *vstats) -{ - open_json_object(NULL); - - print_hu(PRINT_ANY, "vid", "%hu", vstats->vid); - print_vlan_flags(vstats->flags); - print_nl(); - __print_one_vlan_stats(vstats); - - close_json_object(); -} - static void print_vlan_stats_attr(struct rtattr *attr, int ifindex) { struct rtattr *brtb[LINK_XSTATS_TYPE_MAX+1]; @@ -783,7 +743,7 @@ static void print_vlan_stats_attr(struct rtattr *attr, int ifindex) print_string(PRINT_FP, NULL, "%-" textify(IFNAMSIZ) "s ", ""); } - print_one_vlan_stats(vstats); + bridge_print_vlan_stats(vstats); } /* vlan_port is opened only if there are any vlan stats */ @@ -1025,7 +985,7 @@ static void print_vlan_opts(struct rtattr *a, int ifindex) print_string(PRINT_FP, NULL, "%-" textify(IFNAMSIZ) "s ", ""); } print_range("vlan", vinfo->vid, vrange); - print_vlan_flags(vinfo->flags); + bridge_print_vlan_flags(vinfo->flags); print_nl(); print_string(PRINT_FP, NULL, "%-" textify(IFNAMSIZ) "s ", ""); print_stp_state(state); @@ -1051,7 +1011,7 @@ static void print_vlan_opts(struct rtattr *a, int ifindex) } print_nl(); if (show_stats) - __print_one_vlan_stats(&vstats); + bridge_print_vlan_stats_only(&vstats); close_json_object(); } @@ -1334,7 +1294,7 @@ static void print_vlan_info(struct rtattr *tb, int ifindex) open_json_object(NULL); print_range("vlan", last_vid_start, vinfo->vid); - print_vlan_flags(vinfo->flags); + bridge_print_vlan_flags(vinfo->flags); close_json_object(); print_nl(); } diff --git a/include/bridge.h b/include/bridge.h new file mode 100644 index 000000000..8bcd1e386 --- /dev/null +++ b/include/bridge.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __BRIDGE_H__ +#define __BRIDGE_H__ 1 + +#include + +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__ */ diff --git a/lib/Makefile b/lib/Makefile index aa7bbd2ec..0ba629427 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -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) diff --git a/lib/bridge.c b/lib/bridge.c new file mode 100644 index 000000000..a888a20e2 --- /dev/null +++ b/lib/bridge.c @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include + +#include "bridge.h" +#include "utils.h" + +void bridge_print_vlan_flags(__u16 flags) +{ + if (flags == 0) + return; + + open_json_array(PRINT_JSON, "flags"); + if (flags & BRIDGE_VLAN_INFO_PVID) + print_string(PRINT_ANY, NULL, " %s", "PVID"); + + if (flags & BRIDGE_VLAN_INFO_UNTAGGED) + print_string(PRINT_ANY, NULL, " %s", "Egress Untagged"); + close_json_array(PRINT_JSON, NULL); +} + +void bridge_print_vlan_stats_only(const struct bridge_vlan_xstats *vstats) +{ + print_string(PRINT_FP, NULL, "%-" textify(IFNAMSIZ) "s ", ""); + print_lluint(PRINT_ANY, "rx_bytes", "RX: %llu bytes", + vstats->rx_bytes); + print_lluint(PRINT_ANY, "rx_packets", " %llu packets\n", + vstats->rx_packets); + + print_string(PRINT_FP, NULL, "%-" textify(IFNAMSIZ) "s ", ""); + print_lluint(PRINT_ANY, "tx_bytes", "TX: %llu bytes", + vstats->tx_bytes); + print_lluint(PRINT_ANY, "tx_packets", " %llu packets\n", + vstats->tx_packets); +} + +void bridge_print_vlan_stats(const struct bridge_vlan_xstats *vstats) +{ + open_json_object(NULL); + + print_hu(PRINT_ANY, "vid", "%hu", vstats->vid); + bridge_print_vlan_flags(vstats->flags); + print_nl(); + bridge_print_vlan_stats_only(vstats); + + close_json_object(); +} -- 2.47.2