diff --git a/osdep/LinuxNetLink.cpp b/osdep/LinuxNetLink.cpp index 4c6d21a87..8eff09229 100644 --- a/osdep/LinuxNetLink.cpp +++ b/osdep/LinuxNetLink.cpp @@ -13,6 +13,8 @@ #include "../node/Constants.hpp" +#define ZT_NETLINK_TRACE + #ifdef __LINUX__ #include "LinuxNetLink.hpp" @@ -85,7 +87,7 @@ void LinuxNetLink::_setSocketTimeout(int fd, int seconds) tv.tv_sec = seconds; tv.tv_usec = 0; if(setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tv, sizeof(tv)) != 0) { -#ifdef ZT_TRACE +#ifdef ZT_NETLINK_TRACE fprintf(stderr, "setsockopt failed: %s\n", strerror(errno)); #endif } @@ -119,8 +121,8 @@ int LinuxNetLink::_doRecv(int fd) if(nlp->nlmsg_type == NLMSG_ERROR && (nlp->nlmsg_flags & NLM_F_ACK) != NLM_F_ACK) { struct nlmsgerr *err = (struct nlmsgerr*)NLMSG_DATA(nlp); if (err->error != 0) { -#ifdef ZT_TRACE - //fprintf(stderr, "rtnetlink error: %s\n", strerror(-(err->error))); +#ifdef ZT_NETLINK_TRACE + fprintf(stderr, "rtnetlink error: %s\n", strerror(-(err->error))); #endif } p = buf; @@ -145,7 +147,7 @@ int LinuxNetLink::_doRecv(int fd) } if (nlp->nlmsg_type == NLMSG_OVERRUN) { -//#ifdef ZT_TRACE +//#ifdef ZT_NETLINK_TRACE fprintf(stderr, "NLMSG_OVERRUN: Data lost\n"); //#endif p = buf; @@ -242,8 +244,8 @@ void LinuxNetLink::_ipAddressAdded(struct nlmsghdr *nlp) } } -#ifdef ZT_TRACE - //fprintf(stderr,"Added IP Address %s local: %s label: %s broadcast: %s\n", addr, local, label, bcast); +#ifdef ZT_NETLINK_TRACE + fprintf(stderr,"Added IP Address %s local: %s label: %s broadcast: %s\n", addr, local, label, bcast); #endif } @@ -276,8 +278,8 @@ void LinuxNetLink::_ipAddressDeleted(struct nlmsghdr *nlp) } } -#ifdef ZT_TRACE - //fprintf(stderr, "Removed IP Address %s local: %s label: %s broadcast: %s\n", addr, local, label, bcast); +#ifdef ZT_NETLINK_TRACE + fprintf(stderr, "Removed IP Address %s local: %s label: %s broadcast: %s\n", addr, local, label, bcast); #endif } @@ -313,8 +315,8 @@ void LinuxNetLink::_routeAdded(struct nlmsghdr *nlp) } sprintf(ms, "%d", rtp->rtm_dst_len); -#ifdef ZT_TRACE - //fprintf(stderr, "Route Added: dst %s/%s gw %s src %s if %s\n", dsts, ms, gws, srcs, ifs); +#ifdef ZT_NETLINK_TRACE + fprintf(stderr, "Route Added: dst %s/%s gw %s src %s if %s\n", dsts, ms, gws, srcs, ifs); #endif } @@ -350,8 +352,8 @@ void LinuxNetLink::_routeDeleted(struct nlmsghdr *nlp) } sprintf(ms, "%d", rtp->rtm_dst_len); -#ifdef ZT_TRACE - //fprintf(stderr, "Route Deleted: dst %s/%s gw %s src %s if %s\n", dsts, ms, gws, srcs, ifs); +#ifdef ZT_NETLINK_TRACE + fprintf(stderr, "Route Deleted: dst %s/%s gw %s src %s if %s\n", dsts, ms, gws, srcs, ifs); #endif } @@ -605,11 +607,11 @@ void LinuxNetLink::addRoute(const InetAddress &target, const InetAddress &via, c return; } -#ifdef ZT_TRACE - //char tmp[64]; - //char tmp2[64]; - //char tmp3[64]; - //fprintf(stderr, "Adding Route. target: %s via: %s src: %s iface: %s\n", target.toString(tmp), via.toString(tmp2), src.toString(tmp3), ifaceName); +#ifdef ZT_NETLINK_TRACE + char tmp[64]; + char tmp2[64]; + char tmp3[64]; + fprintf(stderr, "Adding Route. target: %s via: %s src: %s iface: %s\n", target.toString(tmp), via.toString(tmp2), src.toString(tmp3), ifaceName); #endif int rtl = sizeof(struct rtmsg); @@ -720,11 +722,11 @@ void LinuxNetLink::delRoute(const InetAddress &target, const InetAddress &via, c return; } -#ifdef ZT_TRACE - //char tmp[64]; - //char tmp2[64]; - //char tmp3[64]; - //fprintf(stderr, "Removing Route. target: %s via: %s src: %s iface: %s\n", target.toString(tmp), via.toString(tmp2), src.toString(tmp3), ifaceName); +#ifdef ZT_NETLINK_TRACE + char tmp[64]; + char tmp2[64]; + char tmp3[64]; + fprintf(stderr, "Removing Route. target: %s via: %s src: %s iface: %s\n", target.toString(tmp), via.toString(tmp2), src.toString(tmp3), ifaceName); #endif int rtl = sizeof(struct rtmsg); @@ -839,9 +841,9 @@ void LinuxNetLink::addAddress(const InetAddress &addr, const char *iface) return; } -#ifdef ZT_TRACE - //char tmp[128]; - //fprintf(stderr, "Adding IP address %s to interface %s", addr.toString(tmp), iface); +#ifdef ZT_NETLINK_TRACE + char tmp[128]; + fprintf(stderr, "Adding IP address %s to interface %s\n", addr.toString(tmp), iface); #endif int interface_index = _indexForInterface(iface); @@ -955,9 +957,9 @@ void LinuxNetLink::removeAddress(const InetAddress &addr, const char *iface) return; } -#ifdef ZT_TRACE - //char tmp[128]; - //fprintf(stderr, "Removing IP address %s from interface %s", addr.toString(tmp), iface); +#ifdef ZT_NETLINK_TRACE + char tmp[128]; + fprintf(stderr, "Removing IP address %s from interface %s\n", addr.toString(tmp), iface); #endif int interface_index = _indexForInterface(iface); diff --git a/osdep/ManagedRoute.cpp b/osdep/ManagedRoute.cpp index 8bab2174c..d64f4279e 100644 --- a/osdep/ManagedRoute.cpp +++ b/osdep/ManagedRoute.cpp @@ -520,13 +520,13 @@ bool ManagedRoute::sync() if (!_applied.count(leftt)) { _applied[leftt] = false; // boolean unused - LinuxNetLink::getInstance().delRoute(leftt, _via, _src, (_via) ? (const char *)0 : _device); + //LinuxNetLink::getInstance().delRoute(leftt, _via, _src, (_via) ? (const char *)0 : _device); LinuxNetLink::getInstance().addRoute(leftt, _via, _src, (_via) ? (const char *)0 : _device); //_routeCmd("replace",leftt,_via,(_via) ? (const char *)0 : _device); } if ((rightt)&&(!_applied.count(rightt))) { _applied[rightt] = false; // boolean unused - LinuxNetLink::getInstance().delRoute(rightt, _via, _src, (_via) ? (const char *)0 : _device); + //LinuxNetLink::getInstance().delRoute(rightt, _via, _src, (_via) ? (const char *)0 : _device); LinuxNetLink::getInstance().addRoute(rightt, _via, _src, (_via) ? (const char *)0 : _device); //_routeCmd("replace",rightt,_via,(_via) ? (const char *)0 : _device); } diff --git a/service/OneService.cpp b/service/OneService.cpp index 3e899358c..4a6669c26 100644 --- a/service/OneService.cpp +++ b/service/OneService.cpp @@ -1989,7 +1989,6 @@ public: SharedPtr &mr = n.managedRoutes[*target]; if (!mr) mr.set(new ManagedRoute(*target, *via, *src, tapdev.c_str())); - mr->sync(); #endif } @@ -1998,6 +1997,18 @@ public: n.managedRoutes.erase(r++); else ++r; } + + // Sync device-local managed routes first, then indirect results. That way + // we don't get destination unreachable for routes that are via things + // that do not yet have routes in the system. + for(std::map< InetAddress, SharedPtr >::iterator r(n.managedRoutes.begin());r!=n.managedRoutes.end();++r) { + if (!r->second->via()) + r->second->sync(); + } + for(std::map< InetAddress, SharedPtr >::iterator r(n.managedRoutes.begin());r!=n.managedRoutes.end();++r) { + if (r->second->via()) + r->second->sync(); + } } if (syncDns) {