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

Signed-off-by: Fabian Pfitzner <f.pfitz...@pengutronix.de>
---

v1->v2
        - refactor code
        - link to v1: 
https://lore.kernel.org/netdev/20250604105322.1185872-1-f.pfitz...@pengutronix.de/

 bridge/vlan.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 55 insertions(+)

diff --git a/bridge/vlan.c b/bridge/vlan.c
index ea4aff93..2afdc7c7 100644
--- a/bridge/vlan.c
+++ b/bridge/vlan.c
@@ -892,6 +892,61 @@ 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 *bqtb[BRIDGE_QUERIER_MAX + 1];
+               const char *querier_ip;
+               SPRINT_BUF(other_time);
+               __u64 tval;
+
+               parse_rtattr_nested(bqtb, BRIDGE_QUERIER_MAX,
+                                   
vtb[BRIDGE_VLANDB_GOPTS_MCAST_QUERIER_STATE]);
+               memset(other_time, 0, sizeof(other_time));
+
+               open_json_object("mcast_querier_state_ipv4");
+               if (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]) {
+                       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(tval, other_time));
+               }
+               close_json_object();
+               open_json_object("mcast_querier_state_ipv6");
+               if (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]) {
+                       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(tval, other_time));
+               }
+               close_json_object();
+       }
        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


Reply via email to