From 36e167013a8e8aca0223dddc3d177734c65c470e Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Wed, 11 Nov 2020 15:12:16 -0500 Subject: [PATCH] More Linux tap shotgun debugging. --- osdep/LinuxEthernetTap.cpp | 105 +++++++++++++++++-------------------- 1 file changed, 49 insertions(+), 56 deletions(-) diff --git a/osdep/LinuxEthernetTap.cpp b/osdep/LinuxEthernetTap.cpp index 859d0673b..360147eb1 100644 --- a/osdep/LinuxEthernetTap.cpp +++ b/osdep/LinuxEthernetTap.cpp @@ -167,63 +167,8 @@ LinuxEthernetTap::LinuxEthernetTap( } ::ioctl(_fd,TUNSETPERSIST,0); // valgrind may generate a false alarm here - - const int sock = socket(AF_INET,SOCK_DGRAM,0); - if (sock <= 0) { - ::close(_fd); - throw std::runtime_error("unable to open netlink socket"); - } - _dev = ifr.ifr_name; - // 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; - mac.copyTo(ifr.ifr_ifru.ifru_hwaddr.sa_data,6); - if (ioctl(sock,SIOCSIFHWADDR,(void *)&ifr) < 0) { - ::close(_fd); - ::close(sock); - 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); - ::close(sock); - 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 ::fcntl(_fd,F_SETFD,fcntl(_fd,F_GETFD) | FD_CLOEXEC); @@ -460,7 +405,55 @@ void LinuxEthernetTap::threadMain() int n,nfds,r; char getBuf[ZT_MAX_MTU + 64]; - Thread::sleep(500); + Thread::sleep(100); + + { + struct ifreq ifr; + memset(&ifr,0,sizeof(ifr)); + + strcpy(ifr.ifr_name,_dev.c_str()); + + const int sock = socket(AF_INET,SOCK_DGRAM,0); + if (sock <= 0) + return; + + if (ioctl(sock,SIOCGIFFLAGS,(void *)&ifr) < 0) { + ::close(sock); + printf("WARNING: ioctl() failed setting up Linux tap device (bring interface up)\n"); + return; + } + ifr.ifr_flags |= IFF_UP; + if (ioctl(sock,SIOCSIFFLAGS,(void *)&ifr) < 0) { + ::close(sock); + printf("WARNING: ioctl() failed setting up Linux tap device (bring interface up)\n"); + return; + } + + Thread::sleep(500); + + 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; + } + + ifr.ifr_ifru.ifru_mtu = (int)mtu; + if (ioctl(sock,SIOCSIFMTU,(void *)&ifr) < 0) { + ::close(sock); + printf("WARNING: ioctl() failed setting up Linux tap device (set MTU)\n"); + return; + } + + if (fcntl(_fd,F_SETFL,fcntl(_fd,F_GETFL) & ~O_NONBLOCK) == -1) { + ::close(sock); + printf("WARNING: ioctl() failed setting up Linux tap device (set non-blocking)\n"); + return; + } + + ::close(sock); + } FD_ZERO(&readfds); FD_ZERO(&nullfds);