Commit 564e6000 authored by Martín Ferrari's avatar Martín Ferrari

Add support for migrating pre-existing interfaces into netns's. Fix destroy() issues.

parent 98faabfc
...@@ -4,7 +4,7 @@ import os ...@@ -4,7 +4,7 @@ import os
import netns.iproute import netns.iproute
__all__ = ['NodeInterface', 'P2PInterface', 'ForeignInterface', __all__ = ['NodeInterface', 'P2PInterface', 'ForeignInterface',
'ForeignNodeInterface', 'Link'] 'ForeignNodeInterface', 'ImportedNodeInterface', 'Link']
class Interface(object): class Interface(object):
"""Just a base class for the *Interface classes: assign names and handle """Just a base class for the *Interface classes: assign names and handle
...@@ -119,12 +119,10 @@ class NodeInterface(NSInterface): ...@@ -119,12 +119,10 @@ class NodeInterface(NSInterface):
return self._control return self._control
def destroy(self): def destroy(self):
try: if self._slave:
if self.index in self._slave.get_if_data():
self._slave.del_if(self.index) self._slave.del_if(self.index)
except: self._slave = None
# Maybe it already went away, or the slave died. Anyway, better
# ignore the error
pass
class P2PInterface(NSInterface): class P2PInterface(NSInterface):
"""Class to create and handle point-to-point interfaces between name """Class to create and handle point-to-point interfaces between name
...@@ -160,10 +158,10 @@ class P2PInterface(NSInterface): ...@@ -160,10 +158,10 @@ class P2PInterface(NSInterface):
raise RuntimeError(P2PInterface.__init__.__doc__) raise RuntimeError(P2PInterface.__init__.__doc__)
def destroy(self): def destroy(self):
try: if self._slave:
if self.index in self._slave.get_if_data():
self._slave.del_if(self.index) self._slave.del_if(self.index)
except: self._slave = None
pass
class ForeignNodeInterface(NSInterface): class ForeignNodeInterface(NSInterface):
"""Class to handle already existing interfaces inside a name space, usually """Class to handle already existing interfaces inside a name space, usually
...@@ -172,15 +170,39 @@ class ForeignNodeInterface(NSInterface): ...@@ -172,15 +170,39 @@ class ForeignNodeInterface(NSInterface):
in before being imported into netns.""" in before being imported into netns."""
def __init__(self, node, iface): def __init__(self, node, iface):
iface = node._slave.get_if_data(iface) iface = node._slave.get_if_data(iface)
self._original_state = iface self._original_state = iface.copy()
super(ForeignNodeInterface, self).__init__(node, iface.index) super(ForeignNodeInterface, self).__init__(node, iface.index)
# FIXME: register somewhere for destruction! # FIXME: register somewhere for destruction!
def destroy(self): # override: restore as much as possible def destroy(self): # override: restore as much as possible
try: if self._slave:
if self.index in self._slave.get_if_data():
self._slave.set_if(self._original_state) self._slave.set_if(self._original_state)
except: self._slave = None
pass
class ImportedNodeInterface(NSInterface):
"""Class to handle already existing interfaces that are migrated inside a
name space: real devices, tun devices, etc. On destruction, the interface
will be restored to the original name space and will try to restore the
original state."""
def __init__(self, node, iface):
iface = netns.iproute.get_if(iface)
self._original_state = iface.copy()
# Change the name to avoid clashes
iface.name = self._gen_if_name()
netns.iproute.set_if(iface)
netns.iproute.change_netns(iface, node.pid)
super(ImportedNodeInterface, self).__init__(node, iface.index)
def destroy(self): # override: restore as much as possible
if self._slave:
if self.index in self._slave.get_if_data():
self._slave.change_netns(self.index, os.getpid())
# else, assume it is in the main name space
netns.iproute.set_if(self._original_state)
self._slave = None
class ExternalInterface(Interface): class ExternalInterface(Interface):
"""Add user-facing methods for interfaces that run in the main namespace.""" """Add user-facing methods for interfaces that run in the main namespace."""
...@@ -248,15 +270,15 @@ class ForeignInterface(ExternalInterface): ...@@ -248,15 +270,15 @@ class ForeignInterface(ExternalInterface):
was in before being imported into netns.""" was in before being imported into netns."""
def __init__(self, iface): def __init__(self, iface):
iface = netns.iproute.get_if(iface) iface = netns.iproute.get_if(iface)
self._original_state = iface self._original_state = iface.copy()
super(ForeignInterface, self).__init__(iface.index) super(ForeignInterface, self).__init__(iface.index)
# FIXME: register somewhere for destruction! # FIXME: register somewhere for destruction!
def destroy(self): # override: restore as much as possible def destroy(self): # override: restore as much as possible
try: if self._slave:
if self.index in self._slave.get_if_data():
netns.iproute.set_if(self._original_state) netns.iproute.set_if(self._original_state)
except: self._slave = None
pass
# Link is just another interface type # Link is just another interface type
...@@ -267,6 +289,16 @@ class Link(ExternalInterface): ...@@ -267,6 +289,16 @@ class Link(ExternalInterface):
# Max 15 chars # Max 15 chars
return "NETNSbr-%.4x%.3x" % (os.getpid(), n) return "NETNSbr-%.4x%.3x" % (os.getpid(), n)
bandwidth = property(lambda s: getattr(s, '_bandwidth'))
delay = property(lambda s: getattr(s, '_delay'))
delay_jitter = property(lambda s: getattr(s, '_delay_jitter'))
delay_correlation = property(lambda s: getattr(s, '_delay_correlation'))
delay_distribution = property(lambda s: getattr(s, '_delay_distribution'))
loss = property(lambda s: getattr(s, '_loss'))
loss_correlation = property(lambda s: getattr(s, '_loss_correlation'))
dup = property(lambda s: getattr(s, '_dup'))
dup_correlation = property(lambda s: getattr(s, '_dup_correlation'))
def __init__(self, bandwidth = None, delay = None, delay_jitter = None, def __init__(self, bandwidth = None, delay = None, delay_jitter = None,
delay_correlation = None, delay_distribution = None, loss = None, delay_correlation = None, delay_distribution = None, loss = None,
loss_correlation = None, dup = None, dup_correlation = None, loss_correlation = None, dup = None, dup_correlation = None,
......
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