Commit 266ec5b4 authored by Yohann D'Anello's avatar Yohann D'Anello

New monitoring, add one IP address per interface and add rules to don't contact them directly

Signed-off-by: Yohann D'Anello's avatarYohann D'ANELLO <ynerant@crans.org>
parent ba573ab7
...@@ -70,6 +70,7 @@ class Connection(object): ...@@ -70,6 +70,7 @@ class Connection(object):
self.address_list = address_list self.address_list = address_list
self.iface = iface self.iface = iface
self._prefix = prefix self._prefix = prefix
self._monitoring_address = None
def __iter__(self): def __iter__(self):
if not hasattr(self, '_remote_ip_set'): if not hasattr(self, '_remote_ip_set'):
...@@ -99,6 +100,22 @@ class Connection(object): ...@@ -99,6 +100,22 @@ class Connection(object):
self._retry += 1 self._retry += 1
def connected(self, serial): def connected(self, serial):
# Generate random IP address in the prefix
# FIXME Run DAD
# TODO Check if there are enough IP addresses. If not, we have to find a rule.
prefix = self.tunnel_manager.ctl.network + self.tunnel_manager._prefix
suffix = bin(random.randint(2, 2 ** (128 - len(prefix))))[2:]
self._monitoring_address = utils.ipFromBin(prefix, suffix)
# Add IP address on Re6stnet interface
subprocess.check_call(('ip', '-6', 'address', 'add', self._monitoring_address, 'dev', self.iface))
subprocess.check_call(('ip', '-6', 'route', 'del', self._monitoring_address))
# Add IP rule to indicate to search main route first instead of local route
# FIXME Get main interface instead of hardcoding 'lo'
subprocess.check_call(('ip', '-6', 'rule', 'add', 'from', utils.ipFromBin(prefix, '1'),
'to', self._monitoring_address, 'iif', 'lo', 'priority', '0'))
subprocess.check_call(('ip', '-6', 'rule', 'del', 'from', 'all', 'lookup', 'local', 'priority', '0'))
subprocess.check_call(('ip', '-6', 'rule', 'add', 'from', 'all', 'lookup', 'local', 'priority', '1'))
cache = self.tunnel_manager.cache cache = self.tunnel_manager.cache
if serial in cache.crl: if serial in cache.crl:
self.tunnel_manager._kill(self._prefix) self.tunnel_manager._kill(self._prefix)
...@@ -112,6 +129,11 @@ class Connection(object): ...@@ -112,6 +129,11 @@ class Connection(object):
cache.connecting(self._prefix, 0) cache.connecting(self._prefix, 0)
def close(self): def close(self):
if self._monitoring_address:
# Remove address and reset IP rule
subprocess.check_call(('ip', '-6', 'address', 'del', self._monitoring_address, 'dev', self.iface))
subprocess.check_call(('ip', '-6', 'rule', 'del', 'to', self._monitoring_address, 'priority', '0'))
try: try:
self.process.stop() self.process.stop()
except AttributeError: except AttributeError:
...@@ -666,6 +688,30 @@ class BaseTunnelManager(object): ...@@ -666,6 +688,30 @@ class BaseTunnelManager(object):
'\7%s (%s)' % (msg, os.uname()[2])) '\7%s (%s)' % (msg, os.uname()[2]))
break break
def updateMonitoringLinks(self):
"""
Refresh routes that are used for link monitoring.
"""
# Cleanup old routes
for connection in self._connection_dict.values():
if connection._monitoring_address:
subprocess.check_call(('ip', '-6', 'route', 'del', connection._monitoring_address,
'dev', connection.iface))
# Get nexthop for each prefix, and draw a route for monitoring addresses
for prefix in self.ctl.neighbours.keys():
if prefix is None or prefix not in self._connection_dict:
continue
neighbour = self.ctl.neighbours[prefix][0]
nexthop = neighbour.address
nexthop = utils.ipFromBin("".join(bin(ord(c))[2:].zfill(8) for c in nexthop))
connection = self._connection_dict[prefix]
address = connection._monitoring_address
# Add route in kernel
subprocess.check_call(('ip', '-6', 'route', 'add', address, 'via', nexthop, 'dev', connection.iface))
def _updateCountry(self, address): def _updateCountry(self, address):
def update(): def update():
for a in address: for a in address:
...@@ -740,6 +786,7 @@ class TunnelManager(BaseTunnelManager): ...@@ -740,6 +786,7 @@ class TunnelManager(BaseTunnelManager):
'--dev', iface, '--dev-type', 'tap') '--dev', iface, '--dev-type', 'tap')
logging.debug('%r', args) logging.debug('%r', args)
subprocess.check_call(args) subprocess.check_call(args)
return iface return iface
def delInterfaces(self): def delInterfaces(self):
...@@ -776,6 +823,7 @@ class TunnelManager(BaseTunnelManager): ...@@ -776,6 +823,7 @@ class TunnelManager(BaseTunnelManager):
else: else:
self._next_refresh = time.time() + 5 self._next_refresh = time.time() + 5
self.checkRoutingCache() self.checkRoutingCache()
self.updateMonitoringLinks()
def babel_dump(self): def babel_dump(self):
t = time.time() t = time.time()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment