aboutsummaryrefslogtreecommitdiffstats
path: root/net/bridge
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2012-04-12 22:37:42 -0400
committerDavid S. Miller <davem@davemloft.net>2012-04-15 12:51:34 -0400
commitc83b8fab06fc8c80d6440649f117bb7541df5fd0 (patch)
tree66a9b4782395aafb307f9a12728ac7e2c999f805 /net/bridge
parent748572162a2bc3ce6f0b215e25ad601c3ec33e77 (diff)
bridge: Restart queries when last querier expires
As it stands when we discover that a real querier (one that queries with a non-zero source address) we stop querying. However, even after said querier has fallen off the edge of the earth, we will never restart querying (unless the bridge itself is restarted). This patch fixes this by kicking our own querier into gear when the timer for other queriers expire. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/bridge')
-rw-r--r--net/bridge/br_multicast.c19
1 files changed, 18 insertions, 1 deletions
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
index ecabf210d0d2..b3647d090e1f 100644
--- a/net/bridge/br_multicast.c
+++ b/net/bridge/br_multicast.c
@@ -36,6 +36,8 @@
36#define mlock_dereference(X, br) \ 36#define mlock_dereference(X, br) \
37 rcu_dereference_protected(X, lockdep_is_held(&br->multicast_lock)) 37 rcu_dereference_protected(X, lockdep_is_held(&br->multicast_lock))
38 38
39static void br_multicast_start_querier(struct net_bridge *br);
40
39#if IS_ENABLED(CONFIG_IPV6) 41#if IS_ENABLED(CONFIG_IPV6)
40static inline int ipv6_is_transient_multicast(const struct in6_addr *addr) 42static inline int ipv6_is_transient_multicast(const struct in6_addr *addr)
41{ 43{
@@ -740,6 +742,21 @@ static void br_multicast_local_router_expired(unsigned long data)
740{ 742{
741} 743}
742 744
745static void br_multicast_querier_expired(unsigned long data)
746{
747 struct net_bridge_port *port = (void *)data;
748 struct net_bridge *br = port->br;
749
750 spin_lock(&br->multicast_lock);
751 if (!netif_running(br->dev) || br->multicast_disabled)
752 goto out;
753
754 br_multicast_start_querier(br);
755
756out:
757 spin_unlock(&br->multicast_lock);
758}
759
743static void __br_multicast_send_query(struct net_bridge *br, 760static void __br_multicast_send_query(struct net_bridge *br,
744 struct net_bridge_port *port, 761 struct net_bridge_port *port,
745 struct br_ip *ip) 762 struct br_ip *ip)
@@ -1562,7 +1579,7 @@ void br_multicast_init(struct net_bridge *br)
1562 setup_timer(&br->multicast_router_timer, 1579 setup_timer(&br->multicast_router_timer,
1563 br_multicast_local_router_expired, 0); 1580 br_multicast_local_router_expired, 0);
1564 setup_timer(&br->multicast_querier_timer, 1581 setup_timer(&br->multicast_querier_timer,
1565 br_multicast_local_router_expired, 0); 1582 br_multicast_querier_expired, 0);
1566 setup_timer(&br->multicast_query_timer, br_multicast_query_expired, 1583 setup_timer(&br->multicast_query_timer, br_multicast_query_expired,
1567 (unsigned long)br); 1584 (unsigned long)br);
1568} 1585}