mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-05-21 17:58:15 +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");
|
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
|
::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) {
|
if (sock <= 0) {
|
||||||
::close(_fd);
|
::close(_fd);
|
||||||
throw std::runtime_error("unable to open netlink socket");
|
throw std::runtime_error("unable to open netlink socket");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fcntl(_fd,F_SETFL,fcntl(_fd,F_GETFL) & ~O_NONBLOCK) == -1) {
|
_dev = ifr.ifr_name;
|
||||||
::close(_fd);
|
|
||||||
throw std::runtime_error("unable to set flags on file descriptor for TAP device");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ioctl(sock,SIOCGIFFLAGS,(void *)&ifr) < 0) {
|
// Set/check loop is a workaround for a weird likely kernel bug in which
|
||||||
::close(_fd);
|
// the interface doesn't come up right away when set to up. This causes
|
||||||
::close(sock);
|
// settings like the MAC address to not "take."
|
||||||
throw std::runtime_error("unable to get TAP interface flags");
|
for(;;) {
|
||||||
}
|
if (ioctl(sock,SIOCGIFFLAGS,(void *)&ifr) < 0) {
|
||||||
ifr.ifr_flags |= IFF_UP;
|
::close(_fd);
|
||||||
if (ioctl(sock,SIOCSIFFLAGS,(void *)&ifr) < 0) {
|
::close(sock);
|
||||||
::close(_fd);
|
throw std::runtime_error("unable to get TAP interface flags");
|
||||||
::close(sock);
|
}
|
||||||
throw std::runtime_error("unable to set 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;
|
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");
|
throw std::runtime_error("unable to configure TAP hardware (MAC) address");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ifr.ifr_ifru.ifru_mtu = (int)mtu;
|
ifr.ifr_ifru.ifru_mtu = (int)mtu;
|
||||||
if (ioctl(sock,SIOCSIFMTU,(void *)&ifr) < 0) {
|
if (ioctl(sock,SIOCSIFMTU,(void *)&ifr) < 0) {
|
||||||
::close(_fd);
|
::close(_fd);
|
||||||
@ -208,6 +217,11 @@ LinuxEthernetTap::LinuxEthernetTap(
|
|||||||
throw std::runtime_error("unable to configure TAP MTU");
|
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);
|
::close(sock);
|
||||||
|
|
||||||
// Set close-on-exec so that devices cannot persist if we fork/exec for update
|
// Set close-on-exec so that devices cannot persist if we fork/exec for update
|
||||||
@ -215,19 +229,6 @@ LinuxEthernetTap::LinuxEthernetTap(
|
|||||||
|
|
||||||
(void)::pipe(_shutdownSignalPipe);
|
(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);
|
_thread = Thread::start(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user