summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Breunig <christian@breunig.cc>2026-02-28 19:48:51 +0100
committerGitHub <noreply@github.com>2026-02-28 19:48:51 +0100
commit3e448bd51685688bdae6ec698a3923cfdeb83689 (patch)
treefe2d66479b80af79153154c8890065fa37aa974f /src
parent440e116cebac31cb51507b23add9d5c5cb414513 (diff)
parent3755dfa7612ffa7edc94537220340a00c9db13ad (diff)
downloadvyos-1x-3e448bd51685688bdae6ec698a3923cfdeb83689.tar.gz
vyos-1x-3e448bd51685688bdae6ec698a3923cfdeb83689.zip
Merge pull request #5014 from natali-rs1985/T8296
vpp: T8296: Move vxlan interface from vpp section to 'interfaces vpp vxlan'
Diffstat (limited to 'src')
-rw-r--r--src/conf_mode/vpp_interfaces_bridge.py6
-rw-r--r--src/conf_mode/vpp_interfaces_vxlan.py118
-rw-r--r--src/migration-scripts/vpp/5-to-6106
3 files changed, 108 insertions, 122 deletions
diff --git a/src/conf_mode/vpp_interfaces_bridge.py b/src/conf_mode/vpp_interfaces_bridge.py
index e86381cc3..8d25cba00 100644
--- a/src/conf_mode/vpp_interfaces_bridge.py
+++ b/src/conf_mode/vpp_interfaces_bridge.py
@@ -96,7 +96,7 @@ def verify(config):
# Check if interface exists in vpp before adding to bridge-domain
- allowed_prefixes = ('vppbond', 'gre', 'geneve', 'lo', 'vxlan')
+ allowed_prefixes = ('vppbond', 'gre', 'geneve', 'lo', 'vppvxlan')
if 'member' in config:
bvi_exists = False
@@ -130,8 +130,8 @@ def apply(config):
return None
ifname = config.get('ifname')
- # vxlan10 in the vpp is vxlan_tunnel10
- interface_transform_filter = ('geneve', 'vxlan')
+ # vppvxlan10 in the vpp is vxlan_tunnel10
+ interface_transform_filter = ('geneve', 'vppvxlan')
# update members
if 'members_removed' in config:
i = BridgeInterface(ifname)
diff --git a/src/conf_mode/vpp_interfaces_vxlan.py b/src/conf_mode/vpp_interfaces_vxlan.py
index 4a0b157e5..9c24b6a01 100644
--- a/src/conf_mode/vpp_interfaces_vxlan.py
+++ b/src/conf_mode/vpp_interfaces_vxlan.py
@@ -16,26 +16,21 @@
# 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.configdict import get_interface_dict
from vyos.configdep import set_dependents, call_dependents
-from vyos.template import is_interface
+from vyos.utils.process import is_systemd_service_active
-from vyos.vpp.interface import VXLANInterface
+from vyos.ifconfig.vpp import VPPVXLANInterface
from vyos.vpp.config_deps import deps_bridge_dict
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,
verify_vpp_tunnel_source_address,
)
-from vyos.vpp.utils import cli_ifaces_lcp_kernel_list, cli_ethernet_with_vifs_ifaces
+from vyos.vpp.utils import cli_ethernet_with_vifs_ifaces
def get_config(config=None) -> dict:
@@ -51,55 +46,14 @@ def get_config(config=None) -> dict:
else:
conf = Config()
- base = ['vpp', 'interfaces', 'vxlan']
- base_kernel_interfaces = ['vpp', 'kernel-interfaces']
-
- ifname = os.environ['VYOS_TAGNODE_VALUE']
+ base = ['interfaces', 'vpp', 'vxlan']
- # 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,
- )
+ ifname, config = get_interface_dict(conf, base)
- if not conf.exists(['vpp']):
+ if not conf.exists(['vpp']) and not conf.exists(base):
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)
-
# list of all Ethernet interfaces with vifs
config['vpp_ether_vif_ifaces'] = cli_ethernet_with_vifs_ifaces(conf)
@@ -114,11 +68,14 @@ def get_config(config=None) -> dict:
for bridge_iface in config['bridge_members'][ifname]:
set_dependents('vpp_interfaces_bridge', conf, bridge_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)
+ # Get 'vpp settings' config with default values
+ config['vpp_settings'] = conf.get_config_dict(
+ ['vpp', 'settings'],
+ key_mangling=('-', '_'),
+ get_first_key=True,
+ no_tag_node_value_mangle=True,
+ with_defaults=True,
+ )
# NAT dependency
if conf.exists(['vpp', 'nat', 'nat44']):
@@ -130,7 +87,6 @@ def get_config(config=None) -> dict:
if conf.exists(['vpp', 'acl']):
set_dependents('vpp_acl', conf)
- config['ifname'] = ifname
return config
@@ -139,16 +95,16 @@ def verify(config):
if 'remove_vpp' in config:
return None
- # Verify that removed kernel interface is not used in 'vpp kernel-interfaces'.
- # vpp interfaces vxlan vxlanX 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:
+ if 'deleted' in config:
return None
+ if not is_systemd_service_active('vpp.service'):
+ raise ConfigError(
+ 'Cannot configure VPP vxlan interface: vpp.service is not running'
+ )
+
required_keys = {'source_address', 'remote', 'vni'}
if not all(key in config for key in required_keys):
missing_keys = required_keys - set(config.keys())
@@ -161,12 +117,6 @@ def verify(config):
if config.get('source_address') == config.get('remote'):
raise ConfigError('Remote address must not be the same as source address')
- # Change 'vpp interfaces vxlan greX kernel-interface vpp-tunX'
- # => 'vpp interfaces gre vxlanX 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
@@ -178,29 +128,13 @@ def apply(config):
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 = VXLANInterface(ifname, src_addr, dst_addr, vni)
- i.delete()
-
- if 'remove' in config:
+ vxlan = VPPVXLANInterface(ifname, config)
+ vxlan.remove()
+
+ if 'deleted' 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', '')
- state = 'up' if 'disable' not in config else 'down'
- i = VXLANInterface(ifname, src_addr, dst_addr, vni, kernel_interface, state)
- 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()
+ vxlan.update(config)
call_dependents()
diff --git a/src/migration-scripts/vpp/5-to-6 b/src/migration-scripts/vpp/5-to-6
index 84b91ce40..25529cf36 100644
--- a/src/migration-scripts/vpp/5-to-6
+++ b/src/migration-scripts/vpp/5-to-6
@@ -39,6 +39,8 @@
#
# Move bonding interface from vpp section to 'interfaces vpp bonding' (T8283)
#
+# Move vxlan interface from vpp section to 'interfaces vpp vxlan' (T8296)
+#
from vyos.configtree import ConfigTree
@@ -290,6 +292,55 @@ def _migrate_vpp_resources(config: ConfigTree) -> None:
config.delete(new_base)
+def _migrate_interface(config, type, ifname):
+ base = ['vpp', 'interfaces', type]
+ new_base = ['interfaces', 'vpp', type]
+ kernel_interface_base = ['vpp', 'kernel-interfaces']
+
+ kernel_interface_path = base + [ifname, 'kernel-interface']
+ kernel_iface = None
+ if config.exists(kernel_interface_path):
+ kernel_iface = config.return_value(kernel_interface_path)
+ config.delete(kernel_interface_path)
+ new_ifname = f'vpp{ifname}'
+ iface_base = new_base + [new_ifname]
+ config.copy(base + [ifname], iface_base)
+ config.set_tag(new_base)
+
+ if kernel_iface and config.exists(kernel_interface_base + [kernel_iface]):
+ if config.exists(kernel_interface_base + [kernel_iface, 'vif']):
+ config.copy(kernel_interface_base + [kernel_iface, 'vif'], iface_base + ['vif'])
+ if config.exists(kernel_interface_base + [kernel_iface, 'mtu']):
+ config.copy(kernel_interface_base + [kernel_iface, 'mtu'], iface_base + ['mtu'])
+ if config.exists(kernel_interface_base + [kernel_iface, 'address']):
+ config.copy(kernel_interface_base + [kernel_iface, 'address'], iface_base + ['address'])
+ config.delete(kernel_interface_base + [kernel_iface])
+
+
+def _migrate_members_bridge(config, ifname):
+ bridge_path = ['vpp', 'interfaces', 'bridge']
+ if config.exists(bridge_path):
+ for iface in config.list_nodes(bridge_path):
+ tmp = bridge_path + [iface, 'member', 'interface']
+ if config.exists(tmp):
+ for name in config.list_nodes(tmp):
+ if name == ifname:
+ new_name = f'vpp{name}'
+ config.rename(tmp + [name], new_name)
+
+
+def _migrate_members_xconnect(config, ifname):
+ xconnect_path = ['vpp', 'interfaces', 'xconnect']
+ if config.exists(xconnect_path):
+ for iface in config.list_nodes(xconnect_path):
+ tmp = xconnect_path + [iface, 'member', 'interface']
+ if config.exists(tmp):
+ for name in config.return_values(tmp):
+ if name == ifname:
+ new_name = f'vpp{name}'
+ config.delete_value(tmp, name)
+ config.set(tmp, value=new_name, replace=False)
+
def _migrate_vpp_bonding_interface(config: ConfigTree) -> None:
base = ['vpp', 'interfaces', 'bonding']
new_base = ['interfaces', 'vpp', 'bonding']
@@ -301,24 +352,7 @@ def _migrate_vpp_bonding_interface(config: ConfigTree) -> None:
config.set(new_base)
for ifname in config.list_nodes(base):
- bond_kernel_interface_path = base + [ifname, 'kernel-interface']
- kernel_iface = None
- if config.exists(bond_kernel_interface_path):
- kernel_iface = config.return_value(bond_kernel_interface_path)
- config.delete(bond_kernel_interface_path)
- new_ifname = f'vpp{ifname}'
- iface_base = new_base + [new_ifname]
- config.copy(base + [ifname], iface_base)
- config.set_tag(new_base)
-
- if kernel_iface and config.exists(kernel_interface_base + [kernel_iface]):
- if config.exists(kernel_interface_base + [kernel_iface, 'vif']):
- config.copy(kernel_interface_base + [kernel_iface, 'vif'], iface_base + ['vif'])
- if config.exists(kernel_interface_base + [kernel_iface, 'mtu']):
- config.copy(kernel_interface_base + [kernel_iface, 'mtu'], iface_base + ['mtu'])
- if config.exists(kernel_interface_base + [kernel_iface, 'address']):
- config.copy(kernel_interface_base + [kernel_iface, 'address'], iface_base + ['address'])
- config.delete(kernel_interface_base + [kernel_iface])
+ _migrate_interface(config, 'bonding', ifname)
for feature in ['nat44', 'cgnat']:
for direction in ['inside', 'outside']:
@@ -341,15 +375,32 @@ def _migrate_vpp_bonding_interface(config: ConfigTree) -> None:
new_name = f'vpp{name}'
config.rename(ipfix_path + [name], new_name)
- bridge_path = ['vpp', 'interfaces', 'bridge']
- if config.exists(bridge_path):
- for iface in config.list_nodes(bridge_path):
- tmp = bridge_path + [iface, 'member', 'interface']
- if config.exists(tmp):
- for name in config.list_nodes(tmp):
- if name == ifname:
- new_name = f'vpp{name}'
- config.rename(tmp + [name], new_name)
+ _migrate_members_bridge(config, ifname)
+
+ config.delete(base)
+
+ if config.exists(kernel_interface_base) and len(config.list_nodes(kernel_interface_base)) == 0:
+ config.delete(['vpp', 'kernel-interfaces'])
+
+ if len(config.list_nodes(['vpp', 'interfaces'])) == 0:
+ config.delete(['vpp', 'interfaces'])
+
+
+def _migrate_vpp_vxlan_interface(config: ConfigTree) -> None:
+ base = ['vpp', 'interfaces', 'vxlan']
+ new_base = ['interfaces', 'vpp', 'vxlan']
+ kernel_interface_base = ['vpp', 'kernel-interfaces']
+
+ if not config.exists(base):
+ return
+
+ config.set(new_base)
+
+ for ifname in config.list_nodes(base):
+ _migrate_interface(config, 'vxlan', ifname)
+
+ _migrate_members_bridge(config, ifname)
+ _migrate_members_xconnect(config, ifname)
config.delete(base)
@@ -376,3 +427,4 @@ def migrate(config: ConfigTree) -> None:
_migrate_vpp_dpdk_options(config)
_migrate_vpp_resources(config)
_migrate_vpp_bonding_interface(config)
+ _migrate_vpp_vxlan_interface(config)