summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Breunig <christian@breunig.cc>2026-03-04 20:30:20 +0100
committerGitHub <noreply@github.com>2026-03-04 20:30:20 +0100
commit53488d0ef8ded005e75f853b6ca05342c3c8725d (patch)
treecaef839f6bb5f49ad6607a438755ca7585f6267c /src
parentddaae274187916b3a7932372ee8944ddce8c5423 (diff)
parentd340acd74270728743807b1db4124b0fddcceec4 (diff)
downloadvyos-1x-53488d0ef8ded005e75f853b6ca05342c3c8725d.tar.gz
vyos-1x-53488d0ef8ded005e75f853b6ca05342c3c8725d.zip
Merge pull request #5026 from natali-rs1985/T8339
vpp: T8339: Cleanup vpp interfaces and kernel-interfaces after migration
Diffstat (limited to 'src')
-rwxr-xr-xsrc/conf_mode/vpp.py18
-rw-r--r--src/conf_mode/vpp_interfaces_ethernet.py134
-rw-r--r--src/conf_mode/vpp_interfaces_geneve.py193
-rw-r--r--src/conf_mode/vpp_kernel-interfaces.py218
-rwxr-xr-xsrc/op_mode/show_vpp_interfaces.py9
5 files changed, 6 insertions, 566 deletions
diff --git a/src/conf_mode/vpp.py b/src/conf_mode/vpp.py
index 396cce548..2ae079c30 100755
--- a/src/conf_mode/vpp.py
+++ b/src/conf_mode/vpp.py
@@ -78,8 +78,6 @@ vpp_log = getLogger(
dependency_interface_type_map = {
'vpp_interfaces_bonding': 'bonding',
'vpp_interfaces_bridge': 'bridge',
- 'vpp_interfaces_ethernet': 'ethernet',
- 'vpp_interfaces_geneve': 'geneve',
'vpp_interfaces_gre': 'gre',
'vpp_interfaces_ipip': 'ipip',
'vpp_interfaces_loopback': 'loopback',
@@ -442,17 +440,6 @@ def get_config(config=None):
# Dependencies
for dependency, interface_type in dependency_interface_type_map.items():
- # if conf.exists(base + ['interfaces', interface_type]):
- if effective_config.get('interfaces', {}).get(interface_type):
- for iface, iface_config in (
- config.get('interfaces', {}).get(interface_type, {}).items()
- ):
- # filter unsupported config nodes
- if interface_type == 'ethernet':
- iface_filter_eth(conf, iface)
- set_dependents(dependency, conf, iface)
-
- for dependency, interface_type in dependency_interface_type_map.items():
if conf.exists(['interfaces', 'vpp', interface_type]):
for iface, iface_config in interfaces_config.get(
interface_type, {}
@@ -466,11 +453,6 @@ def get_config(config=None):
no_tag_node_value_mangle=True,
)
- # kernel-interfaces dependency
- if effective_config.get('kernel_interfaces'):
- for iface in config.get('kernel_interfaces', {}):
- set_dependents('vpp_kernel_interface', conf, iface)
-
# NAT dependency
if conf.exists(['vpp', 'nat', 'nat44']):
set_dependents('vpp_nat_nat44', conf)
diff --git a/src/conf_mode/vpp_interfaces_ethernet.py b/src/conf_mode/vpp_interfaces_ethernet.py
deleted file mode 100644
index 81050444e..000000000
--- a/src/conf_mode/vpp_interfaces_ethernet.py
+++ /dev/null
@@ -1,134 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright (C) VyOS Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-import os
-
-from vyos.config import Config
-from vyos.configdep import set_dependents
-from vyos import ConfigError
-from vyos.vpp.config_verify import verify_vpp_remove_xconnect_interface
-
-
-def get_config(config=None) -> dict:
- """Get Ethernet interface configuration
-
- Args:
- config (vyos.config.Config, optional): The VyOS configuration dictionary
- Returns:
- dict: Ethernet interface configuration
- """
- if config:
- conf = config
- else:
- conf = Config()
-
- base = ['vpp', 'interfaces', 'ethernet']
- base_interfaces_xconnect = ['vpp', 'interfaces', 'xconnect']
-
- ifname = os.environ['VYOS_TAGNODE_VALUE']
-
- # Get effective config as we need full dicitonary per interface delete
- effective_config = conf.get_config_dict(
- base + [ifname],
- key_mangling=('-', '_'),
- effective=True,
- get_first_key=True,
- no_tag_node_value_mangle=True,
- )
-
- if not conf.exists(base + [ifname]):
- config = conf.get_config_dict(
- base + [ifname],
- key_mangling=('-', '_'),
- get_first_key=True,
- no_tag_node_value_mangle=True,
- )
- config.update({'remove': effective_config})
- else:
- # Get config_dict with default values
- config = conf.get_config_dict(
- base + [ifname],
- key_mangling=('-', '_'),
- get_first_key=True,
- no_tag_node_value_mangle=True,
- with_defaults=True,
- with_recursive_defaults=True,
- )
-
- # Get global 'vpp interfaces xconnect'
- config['vpp_interfaces_xconnect'] = conf.get_config_dict(
- base_interfaces_xconnect,
- key_mangling=('-', '_'),
- get_first_key=True,
- no_tag_node_value_mangle=True,
- )
-
- # Dependency
- for xcon_name, xcon_config in config.get('vpp_interfaces_xconnect').items():
- for member_name in xcon_config.get('member', {}).get('interface', []):
- if member_name == ifname:
- set_dependents('vpp_interfaces_xconnect', conf, xcon_name)
-
- if conf.exists(base + [ifname, 'kernel-interface']):
- iface = config.get('kernel_interface')
- if conf.exists(['vpp', 'kernel-interfaces', iface]):
- set_dependents('vpp_kernel_interface', conf, iface)
-
- config['ifname'] = ifname
- return config
-
-
-def verify(config):
- verify_vpp_remove_xconnect_interface(config)
- if 'remove' in config:
- return None
-
-
-def generate(config):
- pass
-
-
-def apply(config):
- # Delete interface
- if 'remove' in config:
- pass
- # remove_config = config.get('remove')
- # ifname = config.get('ifname')
- # src_addr = remove_config.get('source_address')
- # dst_addr = remove_config.get('remote')
- # vni = int(remove_config.get('vni'))
- # v = VXLANInterface(ifname, src_addr, dst_addr, vni)
- # v.delete()
- else:
- pass
- # ifname = config.get('ifname')
- # kernel_interface = config.get('kernel_interface', '')
- # v = VXLANInterface(ifname, src_addr, dst_addr, vni, kernel_interface)
- # v.add()
- return None
-
-
-if __name__ == '__main__':
- try:
- c = get_config()
- verify(c)
- generate(c)
- apply(c)
- except ConfigError as e:
- print(e)
- exit(1)
diff --git a/src/conf_mode/vpp_interfaces_geneve.py b/src/conf_mode/vpp_interfaces_geneve.py
deleted file mode 100644
index efac4e65a..000000000
--- a/src/conf_mode/vpp_interfaces_geneve.py
+++ /dev/null
@@ -1,193 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright (C) VyOS Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-import os
-
-from vyos import ConfigError
-
-from vyos.config import Config
-from vyos.configdict import leaf_node_changed
-from vyos.configdep import set_dependents, call_dependents
-from vyos.template import is_interface
-
-from vyos.vpp.interface import GeneveInterface
-from vyos.vpp.config_deps import deps_xconnect_dict
-from vyos.vpp.config_verify import (
- verify_vpp_remove_kernel_interface,
- verify_vpp_change_kernel_interface,
- verify_vpp_remove_xconnect_interface,
- verify_vpp_exists_kernel_interface,
-)
-from vyos.vpp.utils import cli_ifaces_lcp_kernel_list
-
-
-def get_config(config=None) -> dict:
- """Get Geneve interface configuration
-
- Args:
- config (vyos.config.Config, optional): The VyOS configuration dictionary
- recursive_defaults (bool, optional): Include recursive defaults
- Returns:
- dict: Geneve interface configuration
- """
- if config:
- conf = config
- else:
- conf = Config()
-
- base = ['vpp', 'interfaces', 'geneve']
- base_kernel_interfaces = ['vpp', 'kernel-interfaces']
-
- ifname = os.environ['VYOS_TAGNODE_VALUE']
-
- # Get config_dict with default values
- config = conf.get_config_dict(
- base + [ifname],
- key_mangling=('-', '_'),
- get_first_key=True,
- no_tag_node_value_mangle=True,
- with_defaults=True,
- with_recursive_defaults=True,
- )
-
- if not conf.exists(['vpp']):
- config['remove_vpp'] = True
- return config
-
- # Get effective config as we need full dicitonary per interface delete
- effective_config = conf.get_config_dict(
- base + [ifname],
- key_mangling=('-', '_'),
- effective=True,
- get_first_key=True,
- no_tag_node_value_mangle=True,
- )
-
- if effective_config:
- config.update({'effective': effective_config})
-
- if not conf.exists(base + [ifname]):
- config['remove'] = True
-
- # Get global 'vpp kernel-interfaces' for verify
- config['vpp_kernel_interfaces'] = conf.get_config_dict(
- base_kernel_interfaces,
- key_mangling=('-', '_'),
- get_first_key=True,
- no_tag_node_value_mangle=True,
- )
-
- tmp = leaf_node_changed(conf, base + [ifname, 'kernel-interface'])
- if tmp:
- config['kernel_interface_removed'] = tmp
-
- # list of all kernel interfaces `vpp interface xxx kernel-interface xxx`
- config['candidate_kernel_interfaces'] = cli_ifaces_lcp_kernel_list(conf)
-
- # Dependency
- config['xconn_members'] = deps_xconnect_dict(conf)
- if ifname in config['xconn_members']:
- for xconn_iface in config['xconn_members'][ifname]:
- set_dependents('vpp_interfaces_xconnect', conf, xconn_iface)
-
- if effective_config.get('kernel_interface'):
- if conf.exists(base + [ifname, 'kernel-interface']):
- iface = config.get('kernel_interface')
- if conf.exists(['vpp', 'kernel-interfaces', iface]):
- set_dependents('vpp_kernel_interface', conf, iface)
-
- config['ifname'] = ifname
- return config
-
-
-def verify(config):
- # No need to verify anything if vpp is removed
- if 'remove_vpp' in config:
- return None
-
- # Verify that removed kernel interface is not used in 'vpp kernel-interfaces'.
- # vpp interfaces geneve geneveX kernel-interface vpp-tunX
- # vpp kernel-interface vpp-tunX
- verify_vpp_remove_kernel_interface(config)
-
- verify_vpp_remove_xconnect_interface(config)
-
- if 'remove' in config:
- return None
-
- required_keys = {'source_address', 'remote', 'vni'}
- if not all(key in config for key in required_keys):
- missing_keys = required_keys - set(config.keys())
- raise ConfigError(
- f"Required options are missing: {', '.join(missing_keys).replace('_', '-')}"
- )
-
- # Change 'vpp interfaces geneve geneveX kernel-interface vpp-tunX'
- # => 'vpp interfaces geneve geneveX kernel-interface vpp-tunY'
- # check if we have kernel interface config 'vpp kernel-interface vpp-tunX'
- verify_vpp_change_kernel_interface(config)
- verify_vpp_exists_kernel_interface(config)
-
-
-def generate(config):
- pass
-
-
-def apply(config):
- if 'remove_vpp' in config:
- return None
-
- ifname = config.get('ifname')
- # Delete interface
- if 'effective' in config:
- remove_config = config.get('effective')
- src_addr = remove_config.get('source_address')
- dst_addr = remove_config.get('remote')
- vni = int(remove_config.get('vni'))
- i = GeneveInterface(ifname, src_addr, dst_addr, vni)
- i.delete()
-
- if 'remove' in config:
- return None
-
- # Add interface
- src_addr = config.get('source_address')
- dst_addr = config.get('remote')
- vni = int(config.get('vni'))
- kernel_interface = config.get('kernel_interface', '')
- i = GeneveInterface(ifname, src_addr, dst_addr, vni, kernel_interface)
- i.add()
-
- # Add kernel-interface (LCP) if interface is not exist
- if 'kernel_interface' in config and not is_interface(kernel_interface):
- i.kernel_add()
-
- call_dependents()
-
- return None
-
-
-if __name__ == '__main__':
- try:
- c = get_config()
- verify(c)
- generate(c)
- apply(c)
- except ConfigError as e:
- print(e)
- exit(1)
diff --git a/src/conf_mode/vpp_kernel-interfaces.py b/src/conf_mode/vpp_kernel-interfaces.py
deleted file mode 100644
index d18a5d3e5..000000000
--- a/src/conf_mode/vpp_kernel-interfaces.py
+++ /dev/null
@@ -1,218 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright (C) VyOS Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-import os
-
-from vyos.config import Config
-from vyos.configdep import set_dependents, call_dependents
-from vyos.configdict import leaf_node_changed
-from vyos.configdict import node_changed
-from vyos import ConfigError
-from vyos.ifconfig import Interface
-from vyos.utils.network import interface_exists
-from vyos.utils.process import call
-from vyos.vpp import VPPControl
-
-
-def get_config(config=None) -> dict:
- if config:
- conf = config
- else:
- conf = Config()
-
- base = ['vpp', 'kernel-interfaces']
- base_settings = ['vpp', 'settings']
-
- ifname = os.environ['VYOS_TAGNODE_VALUE']
-
- # Get config_dict with default values
- config = conf.get_config_dict(
- base + [ifname],
- key_mangling=('-', '_'),
- get_first_key=True,
- no_tag_node_value_mangle=True,
- with_defaults=True,
- )
-
- if not conf.exists(['vpp']):
- config['remove_vpp'] = True
- return config
-
- # Get 'vpp settings' config with default values
- config_settings = conf.get_config_dict(
- base_settings,
- key_mangling=('-', '_'),
- get_first_key=True,
- no_tag_node_value_mangle=True,
- with_defaults=True,
- )
- config['vpp_settings'] = config_settings
-
- # Get effective config as we need full dicitonary per interface delete
- if __name__ == '__main__':
- effective_config = conf.get_config_dict(
- base + [ifname],
- key_mangling=('-', '_'),
- effective=True,
- get_first_key=True,
- no_tag_node_value_mangle=True,
- )
- # if a file was started as dependency, we are starting from empty config
- else:
- effective_config = {}
-
- if effective_config:
- config.update({'effective': effective_config})
-
- address_removed = leaf_node_changed(conf, base + [ifname, 'address'])
- if address_removed:
- config['address_removed'] = address_removed
-
- description_removed = leaf_node_changed(conf, base + [ifname, 'description'])
- if description_removed:
- config['description_removed'] = {}
-
- vlans_removed = node_changed(conf, base + [ifname, 'vif'])
- if vlans_removed:
- config['vlans_removed'] = vlans_removed
-
- if conf.exists(['vpp', 'nat', 'cgnat']):
- set_dependents('vpp_nat_cgnat', conf)
- if conf.exists(['vpp', 'nat', 'nat44']):
- set_dependents('vpp_nat_nat44', conf)
-
- config['ifname'] = ifname
-
- return config
-
-
-def verify(config):
- if 'remove' in config or 'remove_vpp' in config:
- return None
-
- # Interface must exists before it is configured
- if not interface_exists(config['ifname']):
- raise ConfigError(
- f'Interface {config["ifname"]} must be created before using in configuration'
- )
-
-
-def generate(config):
- pass
-
-
-def apply(config):
- if 'remove_vpp' in config:
- return None
-
- ifname = config.get('ifname')
- i = Interface(ifname)
- # update/remove addresses
- if 'address_removed' in config:
- for address in config['address_removed']:
- i.del_addr(address)
- # remove description
- if 'description_removed' in config:
- i.set_alias('')
-
- # remove VLANs
- if 'vlans_removed' in config:
- for vlan in config['vlans_removed']:
- call(f'ip link del dev {ifname}.{vlan}')
-
- # Delete
- if 'remove' in config:
- pass
- else:
- # Add address
- if 'address' in config:
- for address in config['address']:
- i.add_addr(address)
- # Set MTU
- if 'mtu' in config:
- i.set_mtu(config.get('mtu'))
- # Set description
- if 'description' in config:
- i.set_alias(config.get('description'))
- # Admin state down
- if 'disable' in config:
- i.set_admin_state('down')
- else:
- i.set_admin_state('up')
-
- for vlan, vlan_config in config.get('vif', {}).items():
- if vlan not in config.get('effective', {}).get('vif', {}).keys():
- call(
- f'ip link add link {ifname} name {ifname}.{vlan} type vlan id {vlan}'
- )
- call(f'ip link set dev {ifname}.{vlan} up')
- v = Interface(f'{ifname}.{vlan}')
-
- # VLAN address
- addresses_effective = (
- config.get('effective', {})
- .get('vif', {})
- .get(vlan, {})
- .get('address', [])
- )
- addresses_candidate = vlan_config.get('address', [])
-
- for ipaddr in addresses_effective:
- if ipaddr not in addresses_candidate:
- v.del_addr(ipaddr)
- for ipaddr in addresses_candidate:
- if ipaddr not in addresses_effective:
- v.add_addr(ipaddr)
-
- # VLAN description
- description_effective = (
- config.get('effective', {})
- .get('vif', {})
- .get(vlan, {})
- .get('description', '')
- )
- description_candidate = vlan_config.get('description', '')
-
- if description_candidate:
- v.set_alias(description_candidate)
- elif description_effective and not description_candidate:
- v.set_alias('')
-
- v.set_admin_state('up')
-
- # Set rx-mode
- rx_mode = config['vpp_settings'].get('interface_rx_mode')
- if rx_mode:
- vpp_control = VPPControl()
- lcp_name = vpp_control.lcp_pair_find(kernel_name=ifname).get('vpp_name_kernel')
- vpp_control.iface_rxmode(lcp_name, rx_mode)
-
- call_dependents()
-
- return None
-
-
-if __name__ == '__main__':
- try:
- c = get_config()
- verify(c)
- generate(c)
- apply(c)
- except ConfigError as e:
- print(e)
- exit(1)
diff --git a/src/op_mode/show_vpp_interfaces.py b/src/op_mode/show_vpp_interfaces.py
index c159ad0aa..d5dd08247 100755
--- a/src/op_mode/show_vpp_interfaces.py
+++ b/src/op_mode/show_vpp_interfaces.py
@@ -248,9 +248,12 @@ if __name__ == '__main__':
vpp_interfaces = []
vpp_ethernet = config.list_nodes('vpp settings interface')
vpp_interfaces.extend(vpp_ethernet)
- if config.exists('vpp kernel-interfaces'):
- vpp_kernel_interfaces = config.list_nodes('vpp kernel-interfaces')
- vpp_interfaces.extend(vpp_kernel_interfaces)
+ if config.exists('interfaces vpp'):
+ for iface_type in config.list_nodes('interfaces vpp'):
+ vpp_kernel_interfaces = config.list_nodes(
+ f'interfaces vpp {iface_type}'
+ )
+ vpp_interfaces.extend(vpp_kernel_interfaces)
print(show_interfaces(interfaces_list=vpp_interfaces))
if args.hardware: