* [PATCH iproute2-next v6 1/3] bridge: move mcast querier dumping code into a shared function
2025-06-25 8:39 [PATCH iproute2-next v6 0/3] bridge: dump mcast querier state per vlan Fabian Pfitzner
@ 2025-06-25 8:39 ` Fabian Pfitzner
2025-06-25 8:39 ` [PATCH iproute2-next v6 2/3] bridge: dump mcast querier per vlan Fabian Pfitzner
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Fabian Pfitzner @ 2025-06-25 8:39 UTC (permalink / raw)
To: netdev; +Cc: entwicklung, razor, bridge, dsahern, idosch, Fabian Pfitzner
Put mcast querier dumping code into a shared function. This function
will be called from the bridge utility in a later patch.
Adapt the code such that the vtb parameter is used
instead of tb[IFLA_BR_MCAST_QUERIER_STATE].
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Acked-by: Nikolay Aleksandrov <razor@blackwall.org>
Signed-off-by: Fabian Pfitzner <f.pfitzner@pengutronix.de>
---
include/bridge.h | 3 +++
ip/iplink_bridge.c | 59 +++-------------------------------------------------
lib/bridge.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 67 insertions(+), 56 deletions(-)
diff --git a/include/bridge.h b/include/bridge.h
index 8bcd1e38..8b0942b5 100644
--- a/include/bridge.h
+++ b/include/bridge.h
@@ -3,9 +3,12 @@
#define __BRIDGE_H__ 1
#include <linux/if_bridge.h>
+#include <linux/rtnetlink.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);
+void bridge_print_mcast_querier_state(const struct rtattr *vtb);
+
#endif /* __BRIDGE_H__ */
diff --git a/ip/iplink_bridge.c b/ip/iplink_bridge.c
index 31e7cb5e..76e69086 100644
--- a/ip/iplink_bridge.c
+++ b/ip/iplink_bridge.c
@@ -682,62 +682,9 @@ static void bridge_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
rta_getattr_u8(tb[IFLA_BR_MCAST_QUERIER]));
if (tb[IFLA_BR_MCAST_QUERIER_STATE]) {
- struct rtattr *bqtb[BRIDGE_QUERIER_MAX + 1];
- SPRINT_BUF(other_time);
-
- parse_rtattr_nested(bqtb, BRIDGE_QUERIER_MAX, tb[IFLA_BR_MCAST_QUERIER_STATE]);
- memset(other_time, 0, sizeof(other_time));
-
- open_json_object("mcast_querier_state_ipv4");
- if (bqtb[BRIDGE_QUERIER_IP_ADDRESS]) {
- print_string(PRINT_FP,
- NULL,
- "%s ",
- "mcast_querier_ipv4_addr");
- print_color_string(PRINT_ANY,
- COLOR_INET,
- "mcast_querier_ipv4_addr",
- "%s ",
- format_host_rta(AF_INET, bqtb[BRIDGE_QUERIER_IP_ADDRESS]));
- }
- if (bqtb[BRIDGE_QUERIER_IP_PORT])
- print_uint(PRINT_ANY,
- "mcast_querier_ipv4_port",
- "mcast_querier_ipv4_port %u ",
- rta_getattr_u32(bqtb[BRIDGE_QUERIER_IP_PORT]));
- if (bqtb[BRIDGE_QUERIER_IP_OTHER_TIMER])
- print_string(PRINT_ANY,
- "mcast_querier_ipv4_other_timer",
- "mcast_querier_ipv4_other_timer %s ",
- sprint_time64(
- rta_getattr_u64(bqtb[BRIDGE_QUERIER_IP_OTHER_TIMER]),
- other_time));
- close_json_object();
- open_json_object("mcast_querier_state_ipv6");
- if (bqtb[BRIDGE_QUERIER_IPV6_ADDRESS]) {
- print_string(PRINT_FP,
- NULL,
- "%s ",
- "mcast_querier_ipv6_addr");
- print_color_string(PRINT_ANY,
- COLOR_INET6,
- "mcast_querier_ipv6_addr",
- "%s ",
- format_host_rta(AF_INET6, bqtb[BRIDGE_QUERIER_IPV6_ADDRESS]));
- }
- if (bqtb[BRIDGE_QUERIER_IPV6_PORT])
- print_uint(PRINT_ANY,
- "mcast_querier_ipv6_port",
- "mcast_querier_ipv6_port %u ",
- rta_getattr_u32(bqtb[BRIDGE_QUERIER_IPV6_PORT]));
- if (bqtb[BRIDGE_QUERIER_IPV6_OTHER_TIMER])
- print_string(PRINT_ANY,
- "mcast_querier_ipv6_other_timer",
- "mcast_querier_ipv6_other_timer %s ",
- sprint_time64(
- rta_getattr_u64(bqtb[BRIDGE_QUERIER_IPV6_OTHER_TIMER]),
- other_time));
- close_json_object();
+ struct rtattr *vtb = tb[IFLA_BR_MCAST_QUERIER_STATE];
+
+ bridge_print_mcast_querier_state(vtb);
}
if (tb[IFLA_BR_MCAST_HASH_ELASTICITY])
diff --git a/lib/bridge.c b/lib/bridge.c
index a888a20e..480693c9 100644
--- a/lib/bridge.c
+++ b/lib/bridge.c
@@ -45,3 +45,64 @@ void bridge_print_vlan_stats(const struct bridge_vlan_xstats *vstats)
close_json_object();
}
+
+void bridge_print_mcast_querier_state(const struct rtattr *vtb)
+{
+ struct rtattr *bqtb[BRIDGE_QUERIER_MAX + 1];
+
+ SPRINT_BUF(other_time);
+
+ parse_rtattr_nested(bqtb, BRIDGE_QUERIER_MAX, vtb);
+ memset(other_time, 0, sizeof(other_time));
+
+ open_json_object("mcast_querier_state_ipv4");
+ if (bqtb[BRIDGE_QUERIER_IP_ADDRESS]) {
+ print_string(PRINT_FP,
+ NULL,
+ "%s ",
+ "mcast_querier_ipv4_addr");
+ print_color_string(PRINT_ANY,
+ COLOR_INET,
+ "mcast_querier_ipv4_addr",
+ "%s ",
+ format_host_rta(AF_INET, bqtb[BRIDGE_QUERIER_IP_ADDRESS]));
+ }
+ if (bqtb[BRIDGE_QUERIER_IP_PORT])
+ print_uint(PRINT_ANY,
+ "mcast_querier_ipv4_port",
+ "mcast_querier_ipv4_port %u ",
+ rta_getattr_u32(bqtb[BRIDGE_QUERIER_IP_PORT]));
+ if (bqtb[BRIDGE_QUERIER_IP_OTHER_TIMER])
+ print_string(PRINT_ANY,
+ "mcast_querier_ipv4_other_timer",
+ "mcast_querier_ipv4_other_timer %s ",
+ sprint_time64(
+ rta_getattr_u64(bqtb[BRIDGE_QUERIER_IP_OTHER_TIMER]),
+ other_time));
+ close_json_object();
+ open_json_object("mcast_querier_state_ipv6");
+ if (bqtb[BRIDGE_QUERIER_IPV6_ADDRESS]) {
+ print_string(PRINT_FP,
+ NULL,
+ "%s ",
+ "mcast_querier_ipv6_addr");
+ print_color_string(PRINT_ANY,
+ COLOR_INET6,
+ "mcast_querier_ipv6_addr",
+ "%s ",
+ format_host_rta(AF_INET6, bqtb[BRIDGE_QUERIER_IPV6_ADDRESS]));
+ }
+ if (bqtb[BRIDGE_QUERIER_IPV6_PORT])
+ print_uint(PRINT_ANY,
+ "mcast_querier_ipv6_port",
+ "mcast_querier_ipv6_port %u ",
+ rta_getattr_u32(bqtb[BRIDGE_QUERIER_IPV6_PORT]));
+ if (bqtb[BRIDGE_QUERIER_IPV6_OTHER_TIMER])
+ print_string(PRINT_ANY,
+ "mcast_querier_ipv6_other_timer",
+ "mcast_querier_ipv6_other_timer %s ",
+ sprint_time64(
+ rta_getattr_u64(bqtb[BRIDGE_QUERIER_IPV6_OTHER_TIMER]),
+ other_time));
+ close_json_object();
+}
--
2.39.5
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH iproute2-next v6 2/3] bridge: dump mcast querier per vlan
2025-06-25 8:39 [PATCH iproute2-next v6 0/3] bridge: dump mcast querier state per vlan Fabian Pfitzner
2025-06-25 8:39 ` [PATCH iproute2-next v6 1/3] bridge: move mcast querier dumping code into a shared function Fabian Pfitzner
@ 2025-06-25 8:39 ` Fabian Pfitzner
2025-06-25 8:39 ` [PATCH iproute2-next v6 3/3] bridge: refactor bridge mcast querier function Fabian Pfitzner
2025-07-02 14:40 ` [PATCH iproute2-next v6 0/3] bridge: dump mcast querier state per vlan patchwork-bot+netdevbpf
3 siblings, 0 replies; 5+ messages in thread
From: Fabian Pfitzner @ 2025-06-25 8:39 UTC (permalink / raw)
To: netdev; +Cc: entwicklung, razor, bridge, dsahern, idosch, Fabian Pfitzner
Dump the multicast querier state per vlan.
This commit is almost identical to [1].
The querier state can be seen with:
bridge -d vlan global
The options for vlan filtering and vlan mcast snooping have to be enabled
in order to see the output:
ip link set [dev] type bridge mcast_vlan_snooping 1 vlan_filtering 1
The querier state shows the following information for IPv4 and IPv6
respectively:
1) The ip address of the current querier in the network. This could be
ourselves or an external querier.
2) The port on which the querier was seen
3) Querier timeout in seconds
[1] https://git.kernel.org/pub/scm/network/iproute2/iproute2.git/commit/?id=16aa4494d7fc6543e5e92beb2ce01648b79f8fa2
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Acked-by: Nikolay Aleksandrov <razor@blackwall.org>
Signed-off-by: Fabian Pfitzner <f.pfitzner@pengutronix.de>
---
bridge/vlan.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/bridge/vlan.c b/bridge/vlan.c
index 14b8475d..3c240207 100644
--- a/bridge/vlan.c
+++ b/bridge/vlan.c
@@ -852,6 +852,11 @@ static void print_vlan_global_opts(struct rtattr *a, int ifindex)
print_uint(PRINT_ANY, "mcast_querier", "mcast_querier %u ",
rta_getattr_u8(vattr));
}
+ if (vtb[BRIDGE_VLANDB_GOPTS_MCAST_QUERIER_STATE]) {
+ struct rtattr *attr = vtb[BRIDGE_VLANDB_GOPTS_MCAST_QUERIER_STATE];
+
+ bridge_print_mcast_querier_state(attr);
+ }
if (vtb[BRIDGE_VLANDB_GOPTS_MCAST_IGMP_VERSION]) {
vattr = vtb[BRIDGE_VLANDB_GOPTS_MCAST_IGMP_VERSION];
print_uint(PRINT_ANY, "mcast_igmp_version",
--
2.39.5
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH iproute2-next v6 3/3] bridge: refactor bridge mcast querier function
2025-06-25 8:39 [PATCH iproute2-next v6 0/3] bridge: dump mcast querier state per vlan Fabian Pfitzner
2025-06-25 8:39 ` [PATCH iproute2-next v6 1/3] bridge: move mcast querier dumping code into a shared function Fabian Pfitzner
2025-06-25 8:39 ` [PATCH iproute2-next v6 2/3] bridge: dump mcast querier per vlan Fabian Pfitzner
@ 2025-06-25 8:39 ` Fabian Pfitzner
2025-07-02 14:40 ` [PATCH iproute2-next v6 0/3] bridge: dump mcast querier state per vlan patchwork-bot+netdevbpf
3 siblings, 0 replies; 5+ messages in thread
From: Fabian Pfitzner @ 2025-06-25 8:39 UTC (permalink / raw)
To: netdev; +Cc: entwicklung, razor, bridge, dsahern, idosch, Fabian Pfitzner
Make code more readable and consistent with other functions.
Acked-by: Nikolay Aleksandrov <razor@blackwall.org>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Signed-off-by: Fabian Pfitzner <f.pfitzner@pengutronix.de>
---
lib/bridge.c | 73 ++++++++++++++++++++++++++++--------------------------------
1 file changed, 34 insertions(+), 39 deletions(-)
diff --git a/lib/bridge.c b/lib/bridge.c
index 480693c9..5386aa01 100644
--- a/lib/bridge.c
+++ b/lib/bridge.c
@@ -49,60 +49,55 @@ void bridge_print_vlan_stats(const struct bridge_vlan_xstats *vstats)
void bridge_print_mcast_querier_state(const struct rtattr *vtb)
{
struct rtattr *bqtb[BRIDGE_QUERIER_MAX + 1];
-
+ const char *querier_ip;
SPRINT_BUF(other_time);
+ __u64 tval;
parse_rtattr_nested(bqtb, BRIDGE_QUERIER_MAX, vtb);
memset(other_time, 0, sizeof(other_time));
open_json_object("mcast_querier_state_ipv4");
if (bqtb[BRIDGE_QUERIER_IP_ADDRESS]) {
- print_string(PRINT_FP,
- NULL,
- "%s ",
- "mcast_querier_ipv4_addr");
- print_color_string(PRINT_ANY,
- COLOR_INET,
- "mcast_querier_ipv4_addr",
- "%s ",
- format_host_rta(AF_INET, bqtb[BRIDGE_QUERIER_IP_ADDRESS]));
+ querier_ip = format_host_rta(AF_INET,
+ bqtb[BRIDGE_QUERIER_IP_ADDRESS]);
+ print_string(PRINT_FP, NULL, "%s ",
+ "mcast_querier_ipv4_addr");
+ print_color_string(PRINT_ANY, COLOR_INET,
+ "mcast_querier_ipv4_addr", "%s ",
+ querier_ip);
}
if (bqtb[BRIDGE_QUERIER_IP_PORT])
- print_uint(PRINT_ANY,
- "mcast_querier_ipv4_port",
- "mcast_querier_ipv4_port %u ",
- rta_getattr_u32(bqtb[BRIDGE_QUERIER_IP_PORT]));
- if (bqtb[BRIDGE_QUERIER_IP_OTHER_TIMER])
+ print_uint(PRINT_ANY, "mcast_querier_ipv4_port",
+ "mcast_querier_ipv4_port %u ",
+ rta_getattr_u32(bqtb[BRIDGE_QUERIER_IP_PORT]));
+ if (bqtb[BRIDGE_QUERIER_IP_OTHER_TIMER]) {
+ tval = rta_getattr_u64(bqtb[BRIDGE_QUERIER_IP_OTHER_TIMER]);
print_string(PRINT_ANY,
- "mcast_querier_ipv4_other_timer",
- "mcast_querier_ipv4_other_timer %s ",
- sprint_time64(
- rta_getattr_u64(bqtb[BRIDGE_QUERIER_IP_OTHER_TIMER]),
- other_time));
+ "mcast_querier_ipv4_other_timer",
+ "mcast_querier_ipv4_other_timer %s ",
+ sprint_time64(tval, other_time));
+ }
close_json_object();
open_json_object("mcast_querier_state_ipv6");
if (bqtb[BRIDGE_QUERIER_IPV6_ADDRESS]) {
- print_string(PRINT_FP,
- NULL,
- "%s ",
- "mcast_querier_ipv6_addr");
- print_color_string(PRINT_ANY,
- COLOR_INET6,
- "mcast_querier_ipv6_addr",
- "%s ",
- format_host_rta(AF_INET6, bqtb[BRIDGE_QUERIER_IPV6_ADDRESS]));
+ querier_ip = format_host_rta(AF_INET6,
+ bqtb[BRIDGE_QUERIER_IPV6_ADDRESS]);
+ print_string(PRINT_FP, NULL, "%s ",
+ "mcast_querier_ipv6_addr");
+ print_color_string(PRINT_ANY, COLOR_INET6,
+ "mcast_querier_ipv6_addr", "%s ",
+ querier_ip);
}
if (bqtb[BRIDGE_QUERIER_IPV6_PORT])
- print_uint(PRINT_ANY,
- "mcast_querier_ipv6_port",
- "mcast_querier_ipv6_port %u ",
- rta_getattr_u32(bqtb[BRIDGE_QUERIER_IPV6_PORT]));
- if (bqtb[BRIDGE_QUERIER_IPV6_OTHER_TIMER])
+ print_uint(PRINT_ANY, "mcast_querier_ipv6_port",
+ "mcast_querier_ipv6_port %u ",
+ rta_getattr_u32(bqtb[BRIDGE_QUERIER_IPV6_PORT]));
+ if (bqtb[BRIDGE_QUERIER_IPV6_OTHER_TIMER]) {
+ tval = rta_getattr_u64(bqtb[BRIDGE_QUERIER_IPV6_OTHER_TIMER]);
print_string(PRINT_ANY,
- "mcast_querier_ipv6_other_timer",
- "mcast_querier_ipv6_other_timer %s ",
- sprint_time64(
- rta_getattr_u64(bqtb[BRIDGE_QUERIER_IPV6_OTHER_TIMER]),
- other_time));
+ "mcast_querier_ipv6_other_timer",
+ "mcast_querier_ipv6_other_timer %s ",
+ sprint_time64(tval, other_time));
+ }
close_json_object();
}
--
2.39.5
^ permalink raw reply related [flat|nested] 5+ messages in thread* Re: [PATCH iproute2-next v6 0/3] bridge: dump mcast querier state per vlan
2025-06-25 8:39 [PATCH iproute2-next v6 0/3] bridge: dump mcast querier state per vlan Fabian Pfitzner
` (2 preceding siblings ...)
2025-06-25 8:39 ` [PATCH iproute2-next v6 3/3] bridge: refactor bridge mcast querier function Fabian Pfitzner
@ 2025-07-02 14:40 ` patchwork-bot+netdevbpf
3 siblings, 0 replies; 5+ messages in thread
From: patchwork-bot+netdevbpf @ 2025-07-02 14:40 UTC (permalink / raw)
To: Fabian Pfitzner; +Cc: netdev, entwicklung, razor, bridge, dsahern, idosch
Hello:
This series was applied to iproute2/iproute2-next.git (main)
by David Ahern <dsahern@kernel.org>:
On Wed, 25 Jun 2025 10:39:12 +0200 you wrote:
> Dump the multicast querier state per vlan.
> This commit is almost identical to [1].
>
> The querier state can be seen with:
>
> bridge -d vlan global
>
> [...]
Here is the summary with links:
- [iproute2-next,v6,1/3] bridge: move mcast querier dumping code into a shared function
https://git.kernel.org/pub/scm/network/iproute2/iproute2-next.git/commit/?id=da6fbcf63c13
- [iproute2-next,v6,2/3] bridge: dump mcast querier per vlan
https://git.kernel.org/pub/scm/network/iproute2/iproute2-next.git/commit/?id=baeeb9a8e184
- [iproute2-next,v6,3/3] bridge: refactor bridge mcast querier function
https://git.kernel.org/pub/scm/network/iproute2/iproute2-next.git/commit/?id=cdc027cb7f47
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply [flat|nested] 5+ messages in thread