summaryrefslogtreecommitdiff
path: root/node/EthernetTap.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'node/EthernetTap.cpp')
-rw-r--r--node/EthernetTap.cpp29
1 files changed, 18 insertions, 11 deletions
diff --git a/node/EthernetTap.cpp b/node/EthernetTap.cpp
index 01bd72cc..596cc5c2 100644
--- a/node/EthernetTap.cpp
+++ b/node/EthernetTap.cpp
@@ -478,7 +478,8 @@ EthernetTap::~EthernetTap()
delete [] _putBuf;
}
-static bool ___removeIp(const char *_dev,std::set<InetAddress> &_ips,const InetAddress &ip)
+// Helper function to actually remove IP from network device, execs ifconfig
+static bool ___removeIp(const char *_dev,const InetAddress &ip)
{
int cpid;
if ((cpid = (int)fork()) == 0) {
@@ -487,11 +488,9 @@ static bool ___removeIp(const char *_dev,std::set<InetAddress> &_ips,const InetA
} else {
int exitcode = -1;
waitpid(cpid,&exitcode,0);
- if (exitcode == 0) {
- _ips.erase(ip);
- return true;
- } else return false;
+ return (exitcode == 0);
}
+ return false; // never reached, make compiler shut up about return value
}
bool EthernetTap::addIP(const InetAddress &ip)
@@ -501,13 +500,17 @@ bool EthernetTap::addIP(const InetAddress &ip)
if (!ip)
return false;
if (_ips.count(ip) > 0)
- return true;
+ return true; // IP/netmask already assigned
// Remove and reconfigure if address is the same but netmask is different
for(std::set<InetAddress>::iterator i(_ips.begin());i!=_ips.end();++i) {
- if (i->ipsEqual(ip)) {
- ___removeIp(_dev,_ips,*i);
- break;
+ if ((i->ipsEqual(ip))&&(i->netmaskBits() != ip.netmaskBits())) {
+ if (___removeIp(_dev,*i)) {
+ _ips.erase(i);
+ break;
+ } else {
+ LOG("WARNING: failed to remove old IP/netmask %s to replace with %s",i->toString().c_str(),ip.toString().c_str());
+ }
}
}
@@ -530,8 +533,12 @@ bool EthernetTap::addIP(const InetAddress &ip)
bool EthernetTap::removeIP(const InetAddress &ip)
{
Mutex::Lock _l(_ips_m);
- if (_ips.count(ip) > 0)
- return ___removeIp(_dev,_ips,ip);
+ if (_ips.count(ip) > 0) {
+ if (___removeIp(_dev,ip)) {
+ _ips.erase(ip);
+ return true;
+ }
+ }
return false;
}