This commit is contained in:
Adam Ierymenko 2017-02-22 15:34:49 -08:00
commit fb00f0f94c
4 changed files with 64 additions and 14 deletions

View File

@ -63,12 +63,8 @@
*
* OneService also does this on detected restarts.
*/
#ifdef __SYNOLOGY___
// Synology devices like to kill routes, check more often and re-add
#define ZT_BINDER_REFRESH_PERIOD 10000
#else
#define ZT_BINDER_REFRESH_PERIOD 30000
#endif
#define ZT_BINDER_REFRESH_PERIOD 30000
namespace ZeroTier {
/**

View File

@ -109,7 +109,12 @@ LinuxEthernetTap::LinuxEthernetTap(
if (!recalledDevice) {
int devno = 0;
do {
#ifdef __SYNOLOGY__
devno+=50; // Arbitrary number to prevent interface name conflicts
Utils::snprintf(ifr.ifr_name,sizeof(ifr.ifr_name),"eth%d",devno++);
#else
Utils::snprintf(ifr.ifr_name,sizeof(ifr.ifr_name),"zt%d",devno++);
#endif
Utils::snprintf(procpath,sizeof(procpath),"/proc/sys/net/ipv4/conf/%s",ifr.ifr_name);
} while (stat(procpath,&sbuf) == 0); // try zt#++ until we find one that does not exist
}
@ -215,16 +220,65 @@ static bool ___removeIp(const std::string &_dev,const InetAddress &ip)
}
}
bool LinuxEthernetTap::addIpSyn(std::vector<InetAddress> ips)
{
// Here we fill out interface config (ifcfg-dev) to prevent it from being killed
std::string filepath = "/etc/sysconfig/network-scripts/ifcfg-"+_dev;
std::string cfg_contents = "DEVICE="+_dev+"\nBOOTPROTO=static";
int ip4=0,ip6=0,ip4_tot=0,ip6_tot=0;
long cpid = (long)vfork();
if (cpid == 0) {
OSUtils::redirectUnixOutputs("/dev/null",(const char *)0);
setenv("PATH", "/sbin:/bin:/usr/sbin:/usr/bin", 1);
// We must know if there is at least (one) of each protocol version so we
// can properly enumerate address/netmask combinations in the ifcfg-dev file
for(int i=0; i<ips.size(); i++) {
if (ips[i].isV4())
ip4_tot++;
else
ip6_tot++;
}
// Assemble and write contents of ifcfg-dev file
for(int i=0; i<ips.size(); i++) {
if (ips[i].isV4()) {
std::string numstr4 = ip4_tot > 1 ? std::to_string(ip4) : "";
cfg_contents += "\nIPADDR"+numstr4+"="+ips[i].toIpString()
+ "\nNETMASK"+numstr4+"="+ips[i].netmask().toIpString()+"\n";
ip4++;
}
else {
std::string numstr6 = ip6_tot > 1 ? std::to_string(ip6) : "";
cfg_contents += "\nIPV6ADDR"+numstr6+"="+ips[i].toIpString()
+ "\nNETMASK"+numstr6+"="+ips[i].netmask().toIpString()+"\n";
ip6++;
}
}
OSUtils::writeFile(filepath.c_str(), cfg_contents.c_str(), cfg_contents.length());
// Finaly, add IPs
for(int i=0; i<ips.size(); i++){
if (ips[i].isV4())
::execlp("ip","ip","addr","add",ips[i].toString().c_str(),"broadcast",ips[i].broadcast().toIpString().c_str(),"dev",_dev.c_str(),(const char *)0);
else
::execlp("ip","ip","addr","add",ips[i].toString().c_str(),"dev",_dev.c_str(),(const char *)0);
}
::_exit(-1);
} else if (cpid > 0) {
int exitcode = -1;
::waitpid(cpid,&exitcode,0);
return (exitcode == 0);
}
return true;
}
bool LinuxEthernetTap::addIp(const InetAddress &ip)
{
if (!ip)
return false;
std::vector<InetAddress> allIps(ips());
#ifndef __SYNOLOGY__
if (std::binary_search(allIps.begin(),allIps.end(),ip))
return true;
#endif
// Remove and reconfigure if address is the same but netmask is different
for(std::vector<InetAddress>::iterator i(allIps.begin());i!=allIps.end();++i) {

View File

@ -52,6 +52,7 @@ public:
void setEnabled(bool en);
bool enabled() const;
bool addIp(const InetAddress &ip);
bool addIpSyn(std::vector<InetAddress> ips);
bool removeIp(const InetAddress &ip);
std::vector<InetAddress> ips() const;
void put(const MAC &from,const MAC &to,unsigned int etherType,const void *data,unsigned int len);

View File

@ -1087,18 +1087,17 @@ public:
fprintf(stderr,"ERROR: unable to remove ip address %s" ZT_EOL_S, ip->toString().c_str());
}
}
for(std::vector<InetAddress>::iterator ip(newManagedIps.begin());ip!=newManagedIps.end();++ip) {
#ifdef __SYNOLOGY__
if (!n.tap->addIp(*ip))
fprintf(stderr,"ERROR: unable to add ip address %s" ZT_EOL_S, ip->toString().c_str());
if (!n.tap->addIpSyn(newManagedIps))
fprintf(stderr,"ERROR: unable to add ip addresses to ifcfg" ZT_EOL_S);
#else
for(std::vector<InetAddress>::iterator ip(newManagedIps.begin());ip!=newManagedIps.end();++ip) {
if (std::find(n.managedIps.begin(),n.managedIps.end(),*ip) == n.managedIps.end()) {
if (!n.tap->addIp(*ip))
fprintf(stderr,"ERROR: unable to add ip address %s" ZT_EOL_S, ip->toString().c_str());
}
#endif
}
}
#endif
n.managedIps.swap(newManagedIps);
}