diff options
-rw-r--r-- | data/configd-include.json | 1 | ||||
-rw-r--r-- | interface-definitions/include/interface/netns.xml.i | 14 | ||||
-rw-r--r-- | interface-definitions/interfaces_dummy.xml.in | 1 | ||||
-rw-r--r-- | interface-definitions/netns.xml.in | 23 | ||||
-rw-r--r-- | op-mode-definitions/force-netns.xml.in | 16 | ||||
-rw-r--r-- | op-mode-definitions/show-netns.xml.in | 13 | ||||
-rw-r--r-- | python/vyos/ifconfig/interface.py | 43 | ||||
-rw-r--r-- | python/vyos/utils/network.py | 26 | ||||
-rwxr-xr-x | smoketest/scripts/cli/test_netns.py | 74 | ||||
-rwxr-xr-x | src/conf_mode/netns.py | 115 |
10 files changed, 0 insertions, 326 deletions
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 @@ -<!-- include start from interface/netns.xml.i --> -<leafNode name="netns"> - <properties> - <help>Network namespace name</help> - <valueHelp> - <format>txt</format> - <description>Network namespace name</description> - </valueHelp> - <completionHelp> - <path>netns name</path> - </completionHelp> - </properties> -</leafNode> -<!-- include end --> 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 @@ <defaultValue>1500</defaultValue> </leafNode> #include <include/interface/mirror.xml.i> - #include <include/interface/netns.xml.i> #include <include/interface/redirect.xml.i> #include <include/interface/vrf.xml.i> </children> 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 @@ -<?xml version="1.0"?> -<interfaceDefinition> - <node name="netns" owner="${vyos_conf_scripts_dir}/netns.py"> - <properties> - <help>Network namespace</help> - <priority>10</priority> - </properties> - <children> - <tagNode name="name"> - <properties> - <help>Network namespace name</help> - <constraint> - <regex>[a-zA-Z0-9-_]{1,100}</regex> - </constraint> - <constraintErrorMessage>Netns name must be alphanumeric and can contain hyphens and underscores.</constraintErrorMessage> - </properties> - <children> - #include <include/generic-description.xml.i> - </children> - </tagNode> - </children> - </node> -</interfaceDefinition> 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 @@ -<?xml version="1.0"?> -<interfaceDefinition> - <node name="force"> - <children> - <tagNode name="netns"> - <properties> - <help>Execute shell in given Network Namespace</help> - <completionHelp> - <path>netns name</path> - </completionHelp> - </properties> - <command>sudo ip netns exec $3 su - $(whoami)</command> - </tagNode> - </children> - </node> -</interfaceDefinition> 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 @@ -<?xml version="1.0"?> -<interfaceDefinition> - <node name="show"> - <children> - <node name="netns"> - <properties> - <help>Show network namespace information</help> - </properties> - <command>ip netns ls</command> - </node> - </children> - </node> -</interfaceDefinition> 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 <http://www.gnu.org/licenses/>. - -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 <http://www.gnu.org/licenses/>. - -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) |