mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2024-12-19 04:57:53 +00:00
Another possible workaround for what seems to be a Linux bug in some newer kernels.
This commit is contained in:
parent
d735a1d04c
commit
2d489a8679
@ -166,31 +166,39 @@ LinuxEthernetTap::LinuxEthernetTap(
|
||||
throw std::runtime_error("unable to configure TUN/TAP device for TAP operation");
|
||||
}
|
||||
|
||||
_dev = ifr.ifr_name;
|
||||
|
||||
::ioctl(_fd,TUNSETPERSIST,0); // valgrind may generate a false alarm here
|
||||
|
||||
int sock = socket(AF_INET,SOCK_DGRAM,0);
|
||||
const int sock = socket(AF_INET,SOCK_DGRAM,0);
|
||||
if (sock <= 0) {
|
||||
::close(_fd);
|
||||
throw std::runtime_error("unable to open netlink socket");
|
||||
}
|
||||
|
||||
if (fcntl(_fd,F_SETFL,fcntl(_fd,F_GETFL) & ~O_NONBLOCK) == -1) {
|
||||
::close(_fd);
|
||||
throw std::runtime_error("unable to set flags on file descriptor for TAP device");
|
||||
}
|
||||
_dev = ifr.ifr_name;
|
||||
|
||||
if (ioctl(sock,SIOCGIFFLAGS,(void *)&ifr) < 0) {
|
||||
::close(_fd);
|
||||
::close(sock);
|
||||
throw std::runtime_error("unable to get TAP interface flags");
|
||||
}
|
||||
ifr.ifr_flags |= IFF_UP;
|
||||
if (ioctl(sock,SIOCSIFFLAGS,(void *)&ifr) < 0) {
|
||||
::close(_fd);
|
||||
::close(sock);
|
||||
throw std::runtime_error("unable to set TAP interface flags");
|
||||
// Set/check loop is a workaround for a weird likely kernel bug in which
|
||||
// the interface doesn't come up right away when set to up. This causes
|
||||
// settings like the MAC address to not "take."
|
||||
for(;;) {
|
||||
if (ioctl(sock,SIOCGIFFLAGS,(void *)&ifr) < 0) {
|
||||
::close(_fd);
|
||||
::close(sock);
|
||||
throw std::runtime_error("unable to get TAP interface flags");
|
||||
}
|
||||
ifr.ifr_flags |= IFF_UP;
|
||||
if (ioctl(sock,SIOCSIFFLAGS,(void *)&ifr) < 0) {
|
||||
::close(_fd);
|
||||
::close(sock);
|
||||
throw std::runtime_error("unable to bring up TAP interface");
|
||||
}
|
||||
if (ioctl(sock,SIOCGIFFLAGS,(void *)&ifr) < 0) {
|
||||
::close(_fd);
|
||||
::close(sock);
|
||||
throw std::runtime_error("unable to get TAP interface flags");
|
||||
}
|
||||
usleep(1000);
|
||||
if ((ifr.ifr_flags & IFF_UP) != 0)
|
||||
break;
|
||||
}
|
||||
|
||||
ifr.ifr_ifru.ifru_hwaddr.sa_family = ARPHRD_ETHER;
|
||||
@ -201,6 +209,7 @@ LinuxEthernetTap::LinuxEthernetTap(
|
||||
throw std::runtime_error("unable to configure TAP hardware (MAC) address");
|
||||
return;
|
||||
}
|
||||
|
||||
ifr.ifr_ifru.ifru_mtu = (int)mtu;
|
||||
if (ioctl(sock,SIOCSIFMTU,(void *)&ifr) < 0) {
|
||||
::close(_fd);
|
||||
@ -208,6 +217,11 @@ LinuxEthernetTap::LinuxEthernetTap(
|
||||
throw std::runtime_error("unable to configure TAP MTU");
|
||||
}
|
||||
|
||||
if (fcntl(_fd,F_SETFL,fcntl(_fd,F_GETFL) & ~O_NONBLOCK) == -1) {
|
||||
::close(_fd);
|
||||
throw std::runtime_error("unable to set flags on file descriptor for TAP device");
|
||||
}
|
||||
|
||||
::close(sock);
|
||||
|
||||
// Set close-on-exec so that devices cannot persist if we fork/exec for update
|
||||
@ -215,19 +229,6 @@ LinuxEthernetTap::LinuxEthernetTap(
|
||||
|
||||
(void)::pipe(_shutdownSignalPipe);
|
||||
|
||||
/*
|
||||
globalDeviceMap[nwids] = _dev;
|
||||
devmapf = fopen((_homePath + ZT_PATH_SEPARATOR_S + "devicemap").c_str(),"w");
|
||||
if (devmapf) {
|
||||
gdmEntry = globalDeviceMap.begin();
|
||||
while (gdmEntry != globalDeviceMap.end()) {
|
||||
fprintf(devmapf,"%s=%s\n",gdmEntry->first.c_str(),gdmEntry->second.c_str());
|
||||
++gdmEntry;
|
||||
}
|
||||
fclose(devmapf);
|
||||
}
|
||||
*/
|
||||
|
||||
_thread = Thread::start(this);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user