Browse Source

Enable ff:ff:ff:ff:ff:ff w/no ADI a.k.a. broadcast. YOLO.

Adam Ierymenko 12 years ago
parent
commit
2eaac3891e
3 changed files with 16 additions and 3 deletions
  1. 8 0
      node/EthernetTap.cpp
  2. 3 0
      node/EthernetTap.hpp
  3. 5 3
      node/Switch.cpp

+ 8 - 0
node/EthernetTap.cpp

@@ -31,6 +31,10 @@
 #include "Logger.hpp"
 #include "Logger.hpp"
 #include "RuntimeEnvironment.hpp"
 #include "RuntimeEnvironment.hpp"
 #include "Mutex.hpp"
 #include "Mutex.hpp"
+#include "MulticastGroup.hpp"
+
+// ff:ff:ff:ff:ff:ff with no ADI
+static const ZeroTier::MulticastGroup _blindWildcardMulticastGroup(ZeroTier::MAC(0xff),0);
 
 
 /* ======================================================================== */
 /* ======================================================================== */
 #if defined(__linux__) || defined(linux) || defined(__LINUX__) || defined(__linux)
 #if defined(__linux__) || defined(linux) || defined(__LINUX__) || defined(__linux)
@@ -337,6 +341,8 @@ bool EthernetTap::updateMulticastGroups(std::set<MulticastGroup> &groups)
 
 
 	bool changed = false;
 	bool changed = false;
 
 
+	newGroups.insert(_blindWildcardMulticastGroup); // always join this
+
 	for(std::set<MulticastGroup>::iterator mg(newGroups.begin());mg!=newGroups.end();++mg) {
 	for(std::set<MulticastGroup>::iterator mg(newGroups.begin());mg!=newGroups.end();++mg) {
 		if (!groups.count(*mg)) {
 		if (!groups.count(*mg)) {
 			groups.insert(*mg);
 			groups.insert(*mg);
@@ -658,6 +664,8 @@ bool EthernetTap::updateMulticastGroups(std::set<MulticastGroup> &groups)
 
 
 	bool changed = false;
 	bool changed = false;
 
 
+	newGroups.insert(_blindWildcardMulticastGroup); // always join this
+
 	for(std::set<MulticastGroup>::iterator mg(newGroups.begin());mg!=newGroups.end();++mg) {
 	for(std::set<MulticastGroup>::iterator mg(newGroups.begin());mg!=newGroups.end();++mg) {
 		if (!groups.count(*mg)) {
 		if (!groups.count(*mg)) {
 			groups.insert(*mg);
 			groups.insert(*mg);

+ 3 - 0
node/EthernetTap.hpp

@@ -164,6 +164,9 @@ public:
 	 * This populates a set or, if already populated, modifies it to contain
 	 * This populates a set or, if already populated, modifies it to contain
 	 * only multicast groups in which this device is interested.
 	 * only multicast groups in which this device is interested.
 	 *
 	 *
+	 * This should always include the blind wildcard MulticastGroup (MAC of
+	 * ff:ff:ff:ff:ff:ff and 0 ADI field).
+	 *
 	 * @param groups Set to modify in place
 	 * @param groups Set to modify in place
 	 * @return True if set was changed since last call
 	 * @return True if set was changed since last call
 	 */
 	 */

+ 5 - 3
node/Switch.cpp

@@ -252,9 +252,11 @@ void Switch::onLocalEthernet(const SharedPtr<Network> &network,const MAC &from,c
 	if (to.isMulticast()) {
 	if (to.isMulticast()) {
 		MulticastGroup mg(to,0);
 		MulticastGroup mg(to,0);
 
 
-		// Handle special cases: IPv4 ARP
-		if ((etherType == ZT_ETHERTYPE_ARP)&&(data.size() == 28)&&(data[2] == 0x08)&&(data[3] == 0x00)&&(data[4] == 6)&&(data[5] == 4)&&(data[7] == 0x01))
-			mg = MulticastGroup::deriveMulticastGroupForAddressResolution(InetAddress(data.field(24,4),4,0));
+		if (to.isBroadcast()) {
+			// Cram IPv4 IP into ADI field to make IPv4 ARP broadcast channel specific and scalable
+			if ((etherType == ZT_ETHERTYPE_ARP)&&(data.size() == 28)&&(data[2] == 0x08)&&(data[3] == 0x00)&&(data[4] == 6)&&(data[5] == 4)&&(data[7] == 0x01))
+				mg = MulticastGroup::deriveMulticastGroupForAddressResolution(InetAddress(data.field(24,4),4,0));
+		}
 
 
 		// Remember this message's CRC, but don't drop if we've already seen it
 		// Remember this message's CRC, but don't drop if we've already seen it
 		// since it's our own.
 		// since it's our own.