mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-04-07 19:24:13 +00:00
Apply default route a different way - macOS
The original way we applied default route, by forking 0.0.0.0/0 into 0/1 and 128/1 works, but if mac os has any networking hiccups -if you change SSIDs or sleep/wake- macos erases the system default route. And then all networking on the computer is broken. to summarize the new way: allowDefault=1 ``` sudo route delete default 192.168.82.1 sudo route add default 10.2.0.2 sudo route add -ifscope en1 default 192.168.82.1 ``` gives us this routing table ``` Destination Gateway RT_IFA Flags Refs Use Mtu Netif Expire rtt(ms) rttvar(ms) default 10.2.0.2 10.2.0.18 UGScg 90 1 2800 feth4823 default 192.168.82.1 192.168.82.217 UGScIg ``` allowDefault=0 ``` sudo route delete default sudo route delete -ifscope en1 default sudo route add default 192.168.82.1 ``` Notice the I flag, for -ifscope, on the physical default route. route change does not seem to work reliably.
This commit is contained in:
parent
03841dcb81
commit
22ab673480
@ -12,6 +12,7 @@
|
||||
/****/
|
||||
|
||||
#include "../node/Constants.hpp"
|
||||
#include "../osdep/OSUtils.hpp"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
@ -94,6 +95,7 @@ struct _RTE
|
||||
char device[128];
|
||||
int metric;
|
||||
bool ifscope;
|
||||
bool isDefault;
|
||||
};
|
||||
|
||||
#ifdef __BSD__ // ------------------------------------------------------------
|
||||
@ -127,6 +129,7 @@ static std::vector<_RTE> _getRTEs(const InetAddress &target,bool contains)
|
||||
|
||||
InetAddress sa_t,sa_v;
|
||||
int deviceIndex = -9999;
|
||||
bool isDefault = false;
|
||||
|
||||
if (((rtm->rtm_flags & RTF_LLINFO) == 0)&&((rtm->rtm_flags & RTF_HOST) == 0)&&((rtm->rtm_flags & RTF_UP) != 0)&&((rtm->rtm_flags & RTF_MULTICAST) == 0)) {
|
||||
int which = 0;
|
||||
@ -160,6 +163,13 @@ static std::vector<_RTE> _getRTEs(const InetAddress &target,bool contains)
|
||||
if (!sin6->sin6_scope_id)
|
||||
sin6->sin6_scope_id = interfaceIndex;
|
||||
}
|
||||
|
||||
#ifdef __APPLE__
|
||||
isDefault = IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr) && !(rtm->rtm_flags & RTF_IFSCOPE);
|
||||
#endif
|
||||
} else {
|
||||
struct sockaddr_in *sin4 = (struct sockaddr_in *)sa;
|
||||
isDefault = sin4->sin_addr.s_addr == 0;
|
||||
}
|
||||
sa_t = *sa;
|
||||
break;
|
||||
@ -167,8 +177,7 @@ static std::vector<_RTE> _getRTEs(const InetAddress &target,bool contains)
|
||||
//printf("RTA_GATEWAY\n");
|
||||
switch(sa->sa_family) {
|
||||
case AF_LINK:
|
||||
deviceIndex = (int)((const struct sockaddr_dl *)sa)->sdl_index;
|
||||
break;
|
||||
// deviceIndex = (int)((const struct sockaddr_dl *)sa)->sdl_index;
|
||||
case AF_INET:
|
||||
case AF_INET6:
|
||||
sa_v = *sa;
|
||||
@ -211,10 +220,15 @@ static std::vector<_RTE> _getRTEs(const InetAddress &target,bool contains)
|
||||
saptr += salen;
|
||||
}
|
||||
|
||||
|
||||
deviceIndex = rtm->rtm_index;
|
||||
|
||||
|
||||
if (((contains)&&(sa_t.containsAddress(target)))||(sa_t == target)) {
|
||||
rtes.push_back(_RTE());
|
||||
rtes.back().target = sa_t;
|
||||
rtes.back().via = sa_v;
|
||||
rtes.back().isDefault = isDefault;
|
||||
if (deviceIndex >= 0) {
|
||||
if_indextoname(deviceIndex,rtes.back().device);
|
||||
} else {
|
||||
@ -457,70 +471,66 @@ bool ManagedRoute::sync()
|
||||
return false;
|
||||
}
|
||||
|
||||
// Find lowest metric system route that this route should override (if any)
|
||||
InetAddress newSystemVia;
|
||||
char newSystemDevice[128];
|
||||
newSystemDevice[0] = (char)0;
|
||||
int systemMetric = 9999999;
|
||||
std::vector<_RTE> rtes(_getRTEs(_target,false));
|
||||
|
||||
bool hasRoute = false;
|
||||
for(std::vector<_RTE>::iterator r(rtes.begin());r!=rtes.end();++r) {
|
||||
if (r->via) {
|
||||
if ( ((!newSystemVia)||(r->metric < systemMetric)) && (strcmp(r->device,_device) != 0) ) {
|
||||
newSystemVia = r->via;
|
||||
Utils::scopy(newSystemDevice,sizeof(newSystemDevice),r->device);
|
||||
systemMetric = r->metric;
|
||||
hasRoute = _target == r->target && _via.ipOnly() == r->via.ipOnly() && (strcmp(r->device,_device) == 0);
|
||||
if (hasRoute) { break; }
|
||||
}
|
||||
|
||||
|
||||
if (!hasRoute) {
|
||||
if (_target && _target.netmaskBits() == 0) {
|
||||
InetAddress newSystemVia;
|
||||
char newSystemDevice[128];
|
||||
newSystemDevice[0] = (char)0;
|
||||
|
||||
// Find system default route that this route should override
|
||||
// We need to put it back when default route is turned off
|
||||
for(std::vector<_RTE>::iterator r(rtes.begin());r!=rtes.end();++r) {
|
||||
if (r->via) {
|
||||
if ( !_systemVia && r->isDefault == 1 && (strcmp(r->device,_device) != 0) ) {
|
||||
|
||||
newSystemVia = r->via;
|
||||
Utils::scopy(newSystemDevice,sizeof(newSystemDevice),r->device);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get device corresponding to route if we don't have that already
|
||||
if ((newSystemVia)&&(!newSystemDevice[0])) {
|
||||
rtes = _getRTEs(newSystemVia,true);
|
||||
for(std::vector<_RTE>::iterator r(rtes.begin());r!=rtes.end();++r) {
|
||||
if ( (r->device[0]) && (strcmp(r->device,_device) != 0) && r->target.netmaskBits() != 0) {
|
||||
Utils::scopy(newSystemDevice,sizeof(newSystemDevice),r->device);
|
||||
break;
|
||||
if (!newSystemVia) { return false; }
|
||||
|
||||
// Get device corresponding to route if we don't have that already
|
||||
if ((newSystemVia)&&(!newSystemDevice[0])) {
|
||||
rtes = _getRTEs(newSystemVia,true);
|
||||
for(std::vector<_RTE>::iterator r(rtes.begin());r!=rtes.end();++r) {
|
||||
if ( (r->device[0]) && (strcmp(r->device,_device) != 0) && r->target.netmaskBits() != 0) {
|
||||
Utils::scopy(newSystemDevice,sizeof(newSystemDevice),r->device);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!newSystemDevice[0])
|
||||
newSystemVia.zero();
|
||||
if (!newSystemDevice[0]) { return false; }
|
||||
|
||||
// Shadow system route if it exists, also delete any obsolete shadows
|
||||
// and replace them with the new state. sync() is called periodically to
|
||||
// allow us to do that if underlying connectivity changes.
|
||||
if ((_systemVia != newSystemVia)||(strcmp(_systemDevice,newSystemDevice) != 0)) {
|
||||
if (_systemVia) {
|
||||
_routeCmd("delete",leftt,_systemVia,_systemDevice,(const char *)0);
|
||||
if (rightt)
|
||||
_routeCmd("delete",rightt,_systemVia,_systemDevice,(const char *)0);
|
||||
}
|
||||
|
||||
_systemVia = newSystemVia;
|
||||
Utils::scopy(_systemDevice,sizeof(_systemDevice),newSystemDevice);
|
||||
// update the system via in case it changed out from under us
|
||||
// while we were in default route mode
|
||||
|
||||
if (_systemVia) {
|
||||
_routeCmd("add",leftt,_systemVia,_systemDevice,(const char *)0);
|
||||
//_routeCmd("change",leftt,_systemVia,_systemDevice,(const char *)0);
|
||||
if (rightt) {
|
||||
_routeCmd("add",rightt,_systemVia,_systemDevice,(const char *)0);
|
||||
//_routeCmd("change",rightt,_systemVia,_systemDevice,(const char *)0);
|
||||
}
|
||||
_systemVia = newSystemVia;
|
||||
Utils::scopy(_systemDevice,sizeof(_systemDevice),newSystemDevice);
|
||||
|
||||
// Do the actual default route commands
|
||||
_routeCmd("delete",_target,_systemVia,(const char *)0,(const char *)0);
|
||||
_routeCmd("add",_target,_via,(const char *)0,(const char *)0);
|
||||
_routeCmd("add",_target,_systemVia,_systemDevice,(const char *)0);
|
||||
_applied[_target] = true;
|
||||
} else {
|
||||
// Do the actual route commands
|
||||
_applied[_target] = true;
|
||||
_routeCmd("add",leftt,_via,(const char *)0,(_via) ? (const char *)0 : _device);
|
||||
}
|
||||
}
|
||||
|
||||
if (leftt && !_applied.count(leftt)) {
|
||||
_applied[leftt] = !_via;
|
||||
//_routeCmd("delete",leftt,_via,(const char *)0,(_via) ? (const char *)0 : _device);
|
||||
_routeCmd("add",leftt,_via,(const char *)0,(_via) ? (const char *)0 : _device);
|
||||
//_routeCmd("change",leftt,_via,(const char *)0,(_via) ? (const char *)0 : _device);
|
||||
}
|
||||
if (rightt && !_applied.count(rightt)) {
|
||||
_applied[rightt] = !_via;
|
||||
//_routeCmd("delete",rightt,_via,(const char *)0,(_via) ? (const char *)0 : _device);
|
||||
_routeCmd("add",rightt,_via,(const char *)0,(_via) ? (const char *)0 : _device);
|
||||
//_routeCmd("change",rightt,_via,(const char *)0,(_via) ? (const char *)0 : _device);
|
||||
}
|
||||
|
||||
#endif // __BSD__ ------------------------------------------------------------
|
||||
|
||||
@ -565,18 +575,22 @@ void ManagedRoute::remove()
|
||||
#endif
|
||||
|
||||
#ifdef __BSD__
|
||||
if (_systemVia) {
|
||||
InetAddress leftt,rightt;
|
||||
_forkTarget(_target,leftt,rightt);
|
||||
_routeCmd("delete",leftt,_systemVia,_systemDevice,(const char *)0);
|
||||
if (rightt)
|
||||
_routeCmd("delete",rightt,_systemVia,_systemDevice,(const char *)0);
|
||||
}
|
||||
#endif // __BSD__ ------------------------------------------------------------
|
||||
|
||||
for(std::map<InetAddress,bool>::iterator r(_applied.begin());r!=_applied.end();++r) {
|
||||
#ifdef __BSD__ // ------------------------------------------------------------
|
||||
_routeCmd("delete",r->first,_via,r->second ? _device : (const char *)0,(_via) ? (const char *)0 : _device);
|
||||
if (_target && _target.netmaskBits() == 0) {
|
||||
if (_systemVia) {
|
||||
_routeCmd("delete",_target,_via,(const char *)0,(const char *)0);
|
||||
_routeCmd("delete",_target,_systemVia,_systemDevice,(const char *)0);
|
||||
|
||||
_routeCmd("add",_target,_systemVia,(const char *)0,(const char *)0);
|
||||
|
||||
}
|
||||
} else {
|
||||
_routeCmd("delete",_target,_via, (const char *)0, _via ? (const char *)0 : _device);
|
||||
}
|
||||
break;
|
||||
#endif // __BSD__ ------------------------------------------------------------
|
||||
|
||||
#ifdef __LINUX__ // ----------------------------------------------------------
|
||||
|
Loading…
x
Reference in New Issue
Block a user