Browse Source

Set MAC address twice, once before and once after bringing interface up, since different kernels behave differently (Linux).

Adam Ierymenko 3 years ago
parent
commit
c16b03c8b8
1 changed files with 11 additions and 5 deletions
  1. 11 5
      osdep/LinuxEthernetTap.cpp

+ 11 - 5
osdep/LinuxEthernetTap.cpp

@@ -205,6 +205,16 @@ LinuxEthernetTap::LinuxEthernetTap(
 			return;
 			return;
 		}
 		}
 
 
+		ifr.ifr_ifru.ifru_hwaddr.sa_family = ARPHRD_ETHER;
+		_mac.copyTo(ifr.ifr_ifru.ifru_hwaddr.sa_data,6);
+		if (ioctl(sock,SIOCSIFHWADDR,(void *)&ifr) < 0) {
+			::close(sock);
+			printf("WARNING: ioctl() failed setting up Linux tap device (set MAC)\n");
+			return;
+		}
+
+		usleep(100000);
+
 		ifr.ifr_flags |= IFF_MULTICAST;
 		ifr.ifr_flags |= IFF_MULTICAST;
 		ifr.ifr_flags |= IFF_UP;
 		ifr.ifr_flags |= IFF_UP;
 		if (ioctl(sock,SIOCSIFFLAGS,(void *)&ifr) < 0) {
 		if (ioctl(sock,SIOCSIFFLAGS,(void *)&ifr) < 0) {
@@ -213,11 +223,7 @@ LinuxEthernetTap::LinuxEthernetTap(
 			return;
 			return;
 		}
 		}
 
 
-		// Some kernel versions seem to require you to yield while the device comes up
-		// before they will accept MTU and MAC. For others it doesn't matter, but is
-		// harmless. This was moved to the worker thread though so as not to block the
-		// main ZeroTier loop.
-		usleep(200000);
+		usleep(100000);
 
 
 		ifr.ifr_ifru.ifru_hwaddr.sa_family = ARPHRD_ETHER;
 		ifr.ifr_ifru.ifru_hwaddr.sa_family = ARPHRD_ETHER;
 		_mac.copyTo(ifr.ifr_ifru.ifru_hwaddr.sa_data,6);
 		_mac.copyTo(ifr.ifr_ifru.ifru_hwaddr.sa_data,6);