diff options
| author | Christian Poessinger <christian.poessinger@rohde-schwarz.com> | 2021-12-06 18:49:30 +0100 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-12-06 18:49:30 +0100 | 
| commit | 84455522574afb9286803f4e192a3d99c259618c (patch) | |
| tree | 01ab634d8e5a9c40061f2b8150245319c44746a4 /python | |
| parent | 5b3ff8574c8265cf308b225c1a39503712f0b21d (diff) | |
| parent | 47584e030f3341b265e826643951648982cb20d0 (diff) | |
| download | vyos-1x-84455522574afb9286803f4e192a3d99c259618c.tar.gz vyos-1x-84455522574afb9286803f4e192a3d99c259618c.zip  | |
Merge pull request #1077 from sever-sever/T3829
netns: T3829: Ability to configure network namespaces
Diffstat (limited to 'python')
| -rwxr-xr-x | python/vyos/ifconfig/interface.py | 43 | ||||
| -rw-r--r-- | python/vyos/util.py | 18 | 
2 files changed, 61 insertions, 0 deletions
diff --git a/python/vyos/ifconfig/interface.py b/python/vyos/ifconfig/interface.py index 58d130ef6..bcb692697 100755 --- a/python/vyos/ifconfig/interface.py +++ b/python/vyos/ifconfig/interface.py @@ -37,6 +37,7 @@ from vyos.util import mac2eui64  from vyos.util import dict_search  from vyos.util import read_file  from vyos.util import get_interface_config +from vyos.util import get_interface_namespace  from vyos.util import is_systemd_service_active  from vyos.template import is_ipv4  from vyos.template import is_ipv6 @@ -135,6 +136,9 @@ class Interface(Control):              'validate': assert_mtu,              'shellcmd': 'ip link set dev {ifname} mtu {value}',          }, +        'netns': { +            'shellcmd': 'ip link set dev {ifname} netns {value}', +        },          'vrf': {              'convert': lambda v: f'master {v}' if v else 'nomaster',              'shellcmd': 'ip link set dev {ifname} {value}', @@ -512,6 +516,35 @@ class Interface(Control):          if prev_state == 'up':              self.set_admin_state('up') +    def del_netns(self, netns): +        """ +        Remove interface from given NETNS. +        """ + +        # If NETNS does not exist then there is nothing to delete +        if not os.path.exists(f'/run/netns/{netns}'): +            return None + +        # As a PoC we only allow 'dummy' interfaces +        if 'dum' not in self.ifname: +            return None + +        # Check if interface realy exists in namespace +        if get_interface_namespace(self.ifname) != None: +            self._cmd(f'ip netns exec {get_interface_namespace(self.ifname)} ip link del dev {self.ifname}') +            return + +    def set_netns(self, netns): +        """ +        Add interface from given NETNS. + +        Example: +        >>> from vyos.ifconfig import Interface +        >>> Interface('dum0').set_netns('foo') +        """ + +        self.set_interface('netns', netns) +      def set_vrf(self, vrf):          """          Add/Remove interface from given VRF instance. @@ -1353,6 +1386,16 @@ class Interface(Control):              if mac:                  self.set_mac(mac) +        # If interface is connected to NETNS we don't have to check all other +        # settings like MTU/IPv6/sysctl values, etc. +        # Since the interface is pushed onto a separate logical stack +        # Configure NETNS +        if dict_search('netns', config) != None: +            self.set_netns(config.get('netns', '')) +            return +        else: +            self.del_netns(config.get('netns', '')) +          # Update interface description          self.set_alias(config.get('description', '')) diff --git a/python/vyos/util.py b/python/vyos/util.py index d8e83ab8d..157b26bf7 100644 --- a/python/vyos/util.py +++ b/python/vyos/util.py @@ -794,6 +794,24 @@ def get_interface_address(interface):      tmp = loads(cmd(f'ip -d -j addr show {interface}'))[0]      return tmp +def get_interface_namespace(iface): +    """ +       Returns wich netns the interface belongs to +    """ +    from json import loads +    # Check if netns exist +    tmp = loads(cmd(f'ip --json netns ls')) +    if len(tmp) == 0: +        return None + +    for ns in tmp: +        namespace = f'{ns["name"]}' +        # Search interface in each netns +        data = loads(cmd(f'ip netns exec {namespace} ip -j link show')) +        for compare in data: +            if iface == compare["ifname"]: +                return namespace +  def get_all_vrfs():      """ Return a dictionary of all system wide known VRF instances """      from json import loads  | 
