diff options
author | Cong Wang <amwang@redhat.com> | 2013-05-21 21:52:56 +0000 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-05-22 14:54:37 -0700 |
commit | 6b7df111ece130fa979a0c4f58e53674c1e47d3e (patch) | |
tree | ecbed2edcc3b7378329d8932a3402fa3a481b43f /net/bridge | |
parent | 9f00b2e7cf241fa389733d41b615efdaa2cb0f5b (diff) | |
download | kernel_goldelico_gta04-6b7df111ece130fa979a0c4f58e53674c1e47d3e.zip kernel_goldelico_gta04-6b7df111ece130fa979a0c4f58e53674c1e47d3e.tar.gz kernel_goldelico_gta04-6b7df111ece130fa979a0c4f58e53674c1e47d3e.tar.bz2 |
bridge: send query as soon as leave is received
Continue sending queries when leave is received if the user marks
it as a querier.
Cc: Herbert Xu <herbert@gondor.apana.org.au>
Cc: Stephen Hemminger <stephen@networkplumber.org>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Adam Baker <linux@baker-net.org.uk>
Signed-off-by: Cong Wang <amwang@redhat.com>
Acked-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.c | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index 40bda80..37a4676 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c @@ -1250,6 +1250,32 @@ static void br_multicast_leave_group(struct net_bridge *br, if (!mp) goto out; + if (br->multicast_querier && + !timer_pending(&br->multicast_querier_timer)) { + __br_multicast_send_query(br, port, &mp->addr); + + time = jiffies + br->multicast_last_member_count * + br->multicast_last_member_interval; + mod_timer(port ? &port->multicast_query_timer : + &br->multicast_query_timer, time); + + for (p = mlock_dereference(mp->ports, br); + p != NULL; + p = mlock_dereference(p->next, br)) { + if (p->port != port) + continue; + + if (!hlist_unhashed(&p->mglist) && + (timer_pending(&p->timer) ? + time_after(p->timer.expires, time) : + try_to_del_timer_sync(&p->timer) >= 0)) { + mod_timer(&p->timer, time); + } + + break; + } + } + if (port && (port->flags & BR_MULTICAST_FAST_LEAVE)) { struct net_bridge_port_group __rcu **pp; |