From 53004f71947c52aab8e6e3fabc3fd5d78a3c643f Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Thu, 4 Apr 2024 16:36:30 +0200
Subject: [PATCH 08/33] net: bridge: drop delay for applying strict multicast
 filtering
Organization: Wires

This *local* patch drops the initial delay before applying strict multicast
filtering, introduced in [1] and recently updated in [2].

The main reason for this patch is RFC conformance and customer expectations.
At power on we assume the querier role by default and are expected to stop
unknown flooding as soon as we have a membership report in place, not after
10 seconds.

A proper fix for upstreaming could be to add a knob to disable the delay.

[1]: https://lore.kernel.org/netdev/1375311980-25575-1-git-send-email-linus.luessing@web.de/
[2]: https://lore.kernel.org/netdev/20240127175033.9640-1-linus.luessing@c0d3.blue/

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
 net/bridge/br_multicast.c | 42 +++++++--------------------------------
 net/bridge/br_private.h   |  4 +---
 2 files changed, 8 insertions(+), 38 deletions(-)

diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
index 06641afb99a8..bacff6c2e968 100644
--- a/net/bridge/br_multicast.c
+++ b/net/bridge/br_multicast.c
@@ -1760,10 +1760,6 @@ static void br_ip6_multicast_querier_expired(struct timer_list *t)
 }
 #endif
 
-static void br_multicast_query_delay_expired(struct timer_list *t)
-{
-}
-
 static void br_multicast_select_own_querier(struct net_bridge_mcast *brmctx,
 					    struct br_ip *ip,
 					    struct sk_buff *skb)
@@ -3258,12 +3254,8 @@ int br_multicast_dump_querier_state(struct sk_buff *skb,
 
 static void
 br_multicast_update_query_timer(struct net_bridge_mcast *brmctx,
-				struct bridge_mcast_other_query *query,
-				unsigned long max_delay)
+				struct bridge_mcast_other_query *query)
 {
-	if (!timer_pending(&query->timer))
-		mod_timer(&query->delay_timer, jiffies + max_delay);
-
 	mod_timer(&query->timer, jiffies + brmctx->multicast_querier_interval);
 }
 
@@ -3454,13 +3446,12 @@ static void
 br_ip4_multicast_query_received(struct net_bridge_mcast *brmctx,
 				struct net_bridge_mcast_port *pmctx,
 				struct bridge_mcast_other_query *query,
-				struct br_ip *saddr,
-				unsigned long max_delay)
+				struct br_ip *saddr)
 {
 	if (!br_multicast_select_querier(brmctx, pmctx, saddr))
 		return;
 
-	br_multicast_update_query_timer(brmctx, query, max_delay);
+	br_multicast_update_query_timer(brmctx, query);
 	br_ip4_multicast_mark_router(brmctx, pmctx);
 }
 
@@ -3469,13 +3460,12 @@ static void
 br_ip6_multicast_query_received(struct net_bridge_mcast *brmctx,
 				struct net_bridge_mcast_port *pmctx,
 				struct bridge_mcast_other_query *query,
-				struct br_ip *saddr,
-				unsigned long max_delay)
+				struct br_ip *saddr)
 {
 	if (!br_multicast_select_querier(brmctx, pmctx, saddr))
 		return;
 
-	br_multicast_update_query_timer(brmctx, query, max_delay);
+	br_multicast_update_query_timer(brmctx, query);
 	br_ip6_multicast_mark_router(brmctx, pmctx);
 }
 #endif
@@ -3529,7 +3519,7 @@ static void br_ip4_multicast_query(struct net_bridge_mcast *brmctx,
 
 		br_ip4_multicast_query_received(brmctx, pmctx,
 						&brmctx->ip4_other_query,
-						&saddr, max_delay);
+						&saddr);
 		goto out;
 	}
 
@@ -3617,7 +3607,7 @@ static int br_ip6_multicast_query(struct net_bridge_mcast *brmctx,
 
 		br_ip6_multicast_query_received(brmctx, pmctx,
 						&brmctx->ip6_other_query,
-						&saddr, max_delay);
+						&saddr);
 		goto out;
 	} else if (!group) {
 		goto out;
@@ -4122,8 +4112,6 @@ void br_multicast_ctx_init(struct net_bridge *br,
 		    br_ip4_multicast_local_router_expired, 0);
 	timer_setup(&brmctx->ip4_other_query.timer,
 		    br_ip4_multicast_querier_expired, 0);
-	timer_setup(&brmctx->ip4_other_query.delay_timer,
-		    br_multicast_query_delay_expired, 0);
 	timer_setup(&brmctx->ip4_own_query.timer,
 		    br_ip4_multicast_query_expired, 0);
 #if IS_ENABLED(CONFIG_IPV6)
@@ -4131,8 +4119,6 @@ void br_multicast_ctx_init(struct net_bridge *br,
 		    br_ip6_multicast_local_router_expired, 0);
 	timer_setup(&brmctx->ip6_other_query.timer,
 		    br_ip6_multicast_querier_expired, 0);
-	timer_setup(&brmctx->ip6_other_query.delay_timer,
-		    br_multicast_query_delay_expired, 0);
 	timer_setup(&brmctx->ip6_own_query.timer,
 		    br_ip6_multicast_query_expired, 0);
 #endif
@@ -4267,12 +4253,10 @@ static void __br_multicast_stop(struct net_bridge_mcast *brmctx)
 {
 	timer_delete_sync(&brmctx->ip4_mc_router_timer);
 	timer_delete_sync(&brmctx->ip4_other_query.timer);
-	timer_delete_sync(&brmctx->ip4_other_query.delay_timer);
 	timer_delete_sync(&brmctx->ip4_own_query.timer);
 #if IS_ENABLED(CONFIG_IPV6)
 	timer_delete_sync(&brmctx->ip6_mc_router_timer);
 	timer_delete_sync(&brmctx->ip6_other_query.timer);
-	timer_delete_sync(&brmctx->ip6_other_query.delay_timer);
 	timer_delete_sync(&brmctx->ip6_own_query.timer);
 #endif
 }
@@ -4726,8 +4710,6 @@ EXPORT_SYMBOL_GPL(br_multicast_router);
 
 int br_multicast_set_querier(struct net_bridge_mcast *brmctx, unsigned long val)
 {
-	unsigned long max_delay;
-
 	val = !!val;
 
 	spin_lock_bh(&brmctx->br->multicast_lock);
@@ -4738,19 +4720,9 @@ int br_multicast_set_querier(struct net_bridge_mcast *brmctx, unsigned long val)
 	if (!val)
 		goto unlock;
 
-	max_delay = brmctx->multicast_query_response_interval;
-
-	if (!timer_pending(&brmctx->ip4_other_query.timer))
-		mod_timer(&brmctx->ip4_other_query.delay_timer,
-			  jiffies + max_delay);
-
 	br_multicast_start_querier(brmctx, &brmctx->ip4_own_query);
 
 #if IS_ENABLED(CONFIG_IPV6)
-	if (!timer_pending(&brmctx->ip6_other_query.timer))
-		mod_timer(&brmctx->ip6_other_query.delay_timer,
-			  jiffies + max_delay);
-
 	br_multicast_start_querier(brmctx, &brmctx->ip6_own_query);
 #endif
 
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index d7187bead496..83dc15fdcefd 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -80,7 +80,6 @@ struct bridge_mcast_own_query {
 /* other querier */
 struct bridge_mcast_other_query {
 	struct timer_list		timer;
-	struct timer_list		delay_timer;
 };
 
 /* selected querier */
@@ -1175,8 +1174,7 @@ __br_multicast_querier_exists(struct net_bridge_mcast *brmctx,
 		own_querier_enabled = false;
 	}
 
-	return !timer_pending(&querier->delay_timer) &&
-	       (own_querier_enabled || timer_pending(&querier->timer));
+	return own_querier_enabled || timer_pending(&querier->timer);
 }
 
 static inline bool br_multicast_querier_exists(struct net_bridge_mcast *brmctx,
