Only add active bridges to top of MC propagation list if they are alive. Otherwise a dead active bridge might kill multicast for us.

This commit is contained in:
Adam Ierymenko 2014-06-26 18:13:48 -07:00
parent 999e963533
commit 458f6ae7c3
2 changed files with 11 additions and 6 deletions

View file

@ -401,11 +401,12 @@ public:
* Learn a multicast group that is bridged to our tap device * Learn a multicast group that is bridged to our tap device
* *
* @param mg Multicast group * @param mg Multicast group
* @param now Current time
*/ */
inline void learnBridgedMulticastGroup(const MulticastGroup &mg) inline void learnBridgedMulticastGroup(const MulticastGroup &mg,uint64_t now)
{ {
Mutex::Lock _l(_lock); Mutex::Lock _l(_lock);
_bridgedMulticastGroups[mg] = Utils::now(); _bridgedMulticastGroups[mg] = now;
} }
/** /**

View file

@ -121,6 +121,7 @@ void Switch::onLocalEthernet(const SharedPtr<Network> &network,const MAC &from,c
if (to.isMulticast()) { if (to.isMulticast()) {
// Destination is a multicast address (including broadcast) // Destination is a multicast address (including broadcast)
uint64_t now = Utils::now();
MulticastGroup mg(to,0); MulticastGroup mg(to,0);
if (to.isBroadcast()) { if (to.isBroadcast()) {
@ -140,7 +141,7 @@ void Switch::onLocalEthernet(const SharedPtr<Network> &network,const MAC &from,c
* multicast addresses on bridge interfaces and subscribing each slave. * multicast addresses on bridge interfaces and subscribing each slave.
* But in that case this does no harm, as the sets are just merged. */ * But in that case this does no harm, as the sets are just merged. */
if (fromBridged) if (fromBridged)
network->learnBridgedMulticastGroup(mg); network->learnBridgedMulticastGroup(mg,now);
// Check multicast/broadcast bandwidth quotas and reject if quota exceeded // Check multicast/broadcast bandwidth quotas and reject if quota exceeded
if (!network->updateAndCheckMulticastBalance(_r->identity.address(),mg,data.size())) { if (!network->updateAndCheckMulticastBalance(_r->identity.address(),mg,data.size())) {
@ -166,9 +167,12 @@ void Switch::onLocalEthernet(const SharedPtr<Network> &network,const MAC &from,c
// All multicasts visit all active bridges first -- this is one of the two active/passive bridge differences // All multicasts visit all active bridges first -- this is one of the two active/passive bridge differences
for(std::set<Address>::const_iterator ab(nconf->activeBridges().begin());ab!=nconf->activeBridges().end();++ab) { for(std::set<Address>::const_iterator ab(nconf->activeBridges().begin());ab!=nconf->activeBridges().end();++ab) {
if ((*ab != _r->identity.address())&&(ab->withinMulticastPropagationPrefix(prefix,nconf->multicastPrefixBits()))) { if ((*ab != _r->identity.address())&&(ab->withinMulticastPropagationPrefix(prefix,nconf->multicastPrefixBits()))) {
ab->copyTo(fifoPtr,ZT_ADDRESS_LENGTH); SharedPtr<Peer> abPeer(_r->topology->getPeer(*ab));
if ((fifoPtr += ZT_ADDRESS_LENGTH) == fifoEnd) if ((abPeer)&&(abPeer->hasActiveDirectPath(now))) {
break; ab->copyTo(fifoPtr,ZT_ADDRESS_LENGTH);
if ((fifoPtr += ZT_ADDRESS_LENGTH) == fifoEnd)
break;
}
} }
} }