From dd40ed58b9e50d40cd395e67be3e9bccfb89e1f6 Mon Sep 17 00:00:00 2001 From: Christian Breunig Date: Thu, 2 May 2024 21:04:30 +0200 Subject: netns: T6295: disable incomplete support in VyOS 1.4 sagitta The netns support currently available on the VyOS CLI is only a proof-of-technology, we have no real support for any service behind it. In order to not confuse anyone on the LTS branch we decided to remove the netns option for interfaces until there is a proper usecase and implementation available. --- data/configd-include.json | 1 - .../include/interface/netns.xml.i | 14 --- interface-definitions/interfaces_dummy.xml.in | 1 - interface-definitions/netns.xml.in | 23 ----- op-mode-definitions/force-netns.xml.in | 16 --- op-mode-definitions/show-netns.xml.in | 13 --- python/vyos/ifconfig/interface.py | 43 -------- python/vyos/utils/network.py | 26 ----- smoketest/scripts/cli/test_netns.py | 74 ------------- src/conf_mode/netns.py | 115 --------------------- 10 files changed, 326 deletions(-) delete mode 100644 interface-definitions/include/interface/netns.xml.i delete mode 100644 interface-definitions/netns.xml.in delete mode 100644 op-mode-definitions/force-netns.xml.in delete mode 100644 op-mode-definitions/show-netns.xml.in delete mode 100755 smoketest/scripts/cli/test_netns.py delete mode 100755 src/conf_mode/netns.py diff --git a/data/configd-include.json b/data/configd-include.json index 212b260e1..6edf350ec 100644 --- a/data/configd-include.json +++ b/data/configd-include.json @@ -27,7 +27,6 @@ "nat.py", "nat64.py", "nat66.py", -"netns.py", "pki.py", "policy.py", "policy_route.py", diff --git a/interface-definitions/include/interface/netns.xml.i b/interface-definitions/include/interface/netns.xml.i deleted file mode 100644 index fd6da8f37..000000000 --- a/interface-definitions/include/interface/netns.xml.i +++ /dev/null @@ -1,14 +0,0 @@ - - - - Network namespace name - - txt - Network namespace name - - - netns name - - - - diff --git a/interface-definitions/interfaces_dummy.xml.in b/interface-definitions/interfaces_dummy.xml.in index 36b4e41f2..4b63967ba 100644 --- a/interface-definitions/interfaces_dummy.xml.in +++ b/interface-definitions/interfaces_dummy.xml.in @@ -50,7 +50,6 @@ 1500 #include - #include #include #include diff --git a/interface-definitions/netns.xml.in b/interface-definitions/netns.xml.in deleted file mode 100644 index d5026bfae..000000000 --- a/interface-definitions/netns.xml.in +++ /dev/null @@ -1,23 +0,0 @@ - - - - - Network namespace - 10 - - - - - Network namespace name - - [a-zA-Z0-9-_]{1,100} - - Netns name must be alphanumeric and can contain hyphens and underscores. - - - #include - - - - - diff --git a/op-mode-definitions/force-netns.xml.in b/op-mode-definitions/force-netns.xml.in deleted file mode 100644 index b9dc2c1e8..000000000 --- a/op-mode-definitions/force-netns.xml.in +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - Execute shell in given Network Namespace - - netns name - - - sudo ip netns exec $3 su - $(whoami) - - - - diff --git a/op-mode-definitions/show-netns.xml.in b/op-mode-definitions/show-netns.xml.in deleted file mode 100644 index 8d5072d4e..000000000 --- a/op-mode-definitions/show-netns.xml.in +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - Show network namespace information - - ip netns ls - - - - diff --git a/python/vyos/ifconfig/interface.py b/python/vyos/ifconfig/interface.py index f295c1066..fbbc04532 100644 --- a/python/vyos/ifconfig/interface.py +++ b/python/vyos/ifconfig/interface.py @@ -36,7 +36,6 @@ from vyos.template import render from vyos.utils.network import mac2eui64 from vyos.utils.dict import dict_search from vyos.utils.network import get_interface_config -from vyos.utils.network import get_interface_namespace from vyos.utils.process import is_systemd_service_active from vyos.template import is_ipv4 from vyos.template import is_ipv6 @@ -137,9 +136,6 @@ 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}', @@ -538,35 +534,6 @@ 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 get_vrf(self): """ Get VRF from interface @@ -1489,16 +1456,6 @@ 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/utils/network.py b/python/vyos/utils/network.py index 63c9e263d..a3bd5c58f 100644 --- a/python/vyos/utils/network.py +++ b/python/vyos/utils/network.py @@ -40,13 +40,6 @@ def interface_exists(interface) -> bool: import os return os.path.exists(f'/sys/class/net/{interface}') -def interface_exists_in_netns(interface_name, netns): - from vyos.utils.process import rc_cmd - rc, out = rc_cmd(f'ip netns exec {netns} ip link show dev {interface_name}') - if rc == 0: - return True - return False - def get_vrf_members(vrf: str) -> list: """ Get list of interface VRF members @@ -101,25 +94,6 @@ def get_interface_address(interface): tmp = loads(cmd(f'ip --detail --json addr show dev {interface}'))[0] return tmp -def get_interface_namespace(iface): - """ - Returns wich netns the interface belongs to - """ - from json import loads - from vyos.utils.process import cmd - # Check if netns exist - tmp = loads(cmd(f'ip --json netns ls')) - if len(tmp) == 0: - return None - - for ns in tmp: - netns = f'{ns["name"]}' - # Search interface in each netns - data = loads(cmd(f'ip netns exec {netns} ip --json link show')) - for tmp in data: - if iface == tmp["ifname"]: - return netns - def is_ipv6_tentative(iface: str, ipv6_address: str) -> bool: """Check if IPv6 address is in tentative state. diff --git a/smoketest/scripts/cli/test_netns.py b/smoketest/scripts/cli/test_netns.py deleted file mode 100755 index d11a5d8f1..000000000 --- a/smoketest/scripts/cli/test_netns.py +++ /dev/null @@ -1,74 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (C) 2021-2024 VyOS maintainers and contributors -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License version 2 or later as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -import unittest - -from base_vyostest_shim import VyOSUnitTestSHIM - -from vyos.utils.process import cmd - -base_path = ['netns'] -namespaces = ['mgmt', 'front', 'back', 'ams-ix'] - -class NETNSTest(VyOSUnitTestSHIM.TestCase): - def setUp(self): - self._interfaces = ['dum10', 'dum12', 'dum50'] - - def test_create_netns(self): - for netns in namespaces: - base = base_path + ['name', netns] - self.cli_set(base) - - # commit changes - self.cli_commit() - - netns_list = cmd('ip netns ls') - - # Verify NETNS configuration - for netns in namespaces: - self.assertTrue(netns in netns_list) - - - def test_netns_assign_interface(self): - netns = 'foo' - self.cli_set(['netns', 'name', netns]) - - # Set - for iface in self._interfaces: - self.cli_set(['interfaces', 'dummy', iface, 'netns', netns]) - - # commit changes - self.cli_commit() - - netns_iface_list = cmd(f'sudo ip netns exec {netns} ip link show') - - for iface in self._interfaces: - self.assertTrue(iface in netns_iface_list) - - # Delete - for iface in self._interfaces: - self.cli_delete(['interfaces', 'dummy', iface, 'netns', netns]) - - # commit changes - self.cli_commit() - - netns_iface_list = cmd(f'sudo ip netns exec {netns} ip link show') - - for iface in self._interfaces: - self.assertNotIn(iface, netns_iface_list) - -if __name__ == '__main__': - unittest.main(verbosity=2) diff --git a/src/conf_mode/netns.py b/src/conf_mode/netns.py deleted file mode 100755 index b57e46a0d..000000000 --- a/src/conf_mode/netns.py +++ /dev/null @@ -1,115 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (C) 2021-2024 VyOS maintainers and contributors -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License version 2 or later as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -import os - -from sys import exit - -from vyos.config import Config -from vyos.configdict import node_changed -from vyos.utils.process import call -from vyos.utils.dict import dict_search -from vyos import ConfigError -from vyos import airbag -airbag.enable() - - -def netns_interfaces(c, match): - """ - get NETNS bound interfaces - """ - matched = [] - old_level = c.get_level() - c.set_level(['interfaces']) - section = c.get_config_dict([], get_first_key=True) - for type in section: - interfaces = section[type] - for name in interfaces: - interface = interfaces[name] - if 'netns' in interface: - v = interface.get('netns', '') - if v == match: - matched.append(name) - - c.set_level(old_level) - return matched - -def get_config(config=None): - if config: - conf = config - else: - conf = Config() - - base = ['netns'] - netns = conf.get_config_dict(base, get_first_key=True, - no_tag_node_value_mangle=True) - - # determine which NETNS has been removed - for name in node_changed(conf, base + ['name']): - if 'netns_remove' not in netns: - netns.update({'netns_remove' : {}}) - - netns['netns_remove'][name] = {} - # get NETNS bound interfaces - interfaces = netns_interfaces(conf, name) - if interfaces: netns['netns_remove'][name]['interface'] = interfaces - - return netns - -def verify(netns): - # ensure NETNS is not assigned to any interface - if 'netns_remove' in netns: - for name, config in netns['netns_remove'].items(): - if 'interface' in config: - raise ConfigError(f'Can not remove network namespace "{name}", it '\ - f'still has member interfaces!') - - if 'name' in netns: - for name, config in netns['name'].items(): - # no tests (yet) - pass - - return None - -def generate(netns): - if not netns: - return None - - return None - - -def apply(netns): - - for tmp in (dict_search('netns_remove', netns) or []): - if os.path.isfile(f'/run/netns/{tmp}'): - call(f'ip netns del {tmp}') - - if 'name' in netns: - for name, config in netns['name'].items(): - if not os.path.isfile(f'/run/netns/{name}'): - call(f'ip netns add {name}') - - return None - -if __name__ == '__main__': - try: - c = get_config() - verify(c) - generate(c) - apply(c) - except ConfigError as e: - print(e) - exit(1) -- cgit v1.2.3