summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNataliia Solomko <natalirs1985@gmail.com>2026-02-27 12:40:38 +0200
committerNataliia Solomko <natalirs1985@gmail.com>2026-03-02 16:15:30 +0200
commit61d607295fa826e707b82432c46668a2fb94ab22 (patch)
tree225df4b68614c5918f02b81ec4c661e24de19364 /src
parent0c7a2b861abd4c897a2cbe4a5564effca8f9cc01 (diff)
downloadvyos-1x-61d607295fa826e707b82432c46668a2fb94ab22.tar.gz
vyos-1x-61d607295fa826e707b82432c46668a2fb94ab22.zip
vpp: T8324: Migrate loopback interface to 'interfaces vpp loopback'
Diffstat (limited to 'src')
-rw-r--r--src/conf_mode/vpp_interfaces_bridge.py12
-rw-r--r--src/conf_mode/vpp_interfaces_loopback.py98
-rw-r--r--src/migration-scripts/vpp/5-to-627
3 files changed, 51 insertions, 86 deletions
diff --git a/src/conf_mode/vpp_interfaces_bridge.py b/src/conf_mode/vpp_interfaces_bridge.py
index 8d25cba00..d53173f04 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', 'vppvxlan')
+ allowed_prefixes = ('vppbond', 'gre', 'geneve', 'vpplo', 'vppvxlan')
if 'member' in config:
bvi_exists = False
@@ -116,7 +116,7 @@ def verify(config):
if 'bvi' in member_config:
if bvi_exists:
raise ConfigError("Only one BVI per bridge domain is allowed")
- if not member.startswith('lo'):
+ if not member.startswith('vpplo'):
raise ConfigError("BVI can only be defined on loopback interface")
bvi_exists = True
@@ -138,9 +138,9 @@ def apply(config):
for member in config.get('members_removed'):
if member.startswith(interface_transform_filter):
member = iftunnel_transform(member)
- if member.startswith('lo'):
+ if member.startswith('vpplo'):
# interface name in VPP is loopX
- member = member.replace('lo', 'loop')
+ member = member.replace('vpplo', 'loop')
elif member.startswith('vppbond'):
# interface name in VPP is BondEthernetX
member = member.replace('vppbond', 'BondEthernet')
@@ -166,9 +166,9 @@ def apply(config):
for member, member_config in members.items():
if member.startswith(interface_transform_filter):
member = iftunnel_transform(member)
- if member.startswith('lo'):
+ if member.startswith('vpplo'):
# interface name in VPP is loopX
- member = member.replace('lo', 'loop')
+ member = member.replace('vpplo', 'loop')
if 'bvi' in member_config:
port_type = 1
elif member.startswith('vppbond'):
diff --git a/src/conf_mode/vpp_interfaces_loopback.py b/src/conf_mode/vpp_interfaces_loopback.py
index d08557959..2f7b59354 100644
--- a/src/conf_mode/vpp_interfaces_loopback.py
+++ b/src/conf_mode/vpp_interfaces_loopback.py
@@ -16,22 +16,14 @@
# 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 LoopbackInterface
-from vyos.vpp.config_verify import (
- verify_vpp_remove_kernel_interface,
- verify_vpp_change_kernel_interface,
- verify_vpp_exists_kernel_interface,
-)
-from vyos.vpp.utils import cli_ifaces_lcp_kernel_list
+from vyos.ifconfig.vpp import VPPLoopbackInterface
def get_config(config=None) -> dict:
@@ -47,62 +39,22 @@ def get_config(config=None) -> dict:
else:
conf = Config()
- base = ['vpp', 'interfaces', 'loopback']
- base_kernel_interfaces = ['vpp', 'kernel-interfaces']
-
- ifname = os.environ['VYOS_TAGNODE_VALUE']
+ base = ['interfaces', 'vpp', 'loopback']
- # 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],
+ # Get 'vpp settings' config
+ config['vpp_settings'] = conf.get_config_dict(
+ ['vpp', 'settings'],
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
- 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)
-
# NAT dependency
if conf.exists(['vpp', 'nat', 'nat44']):
set_dependents('vpp_nat_nat44', conf)
@@ -113,7 +65,6 @@ def get_config(config=None) -> dict:
if conf.exists(['vpp', 'acl']):
set_dependents('vpp_acl', conf)
- config['ifname'] = ifname
return config
@@ -122,13 +73,10 @@ def verify(config):
if 'remove_vpp' in config:
return None
- verify_vpp_remove_kernel_interface(config)
-
- if 'remove' in config:
- return None
-
- verify_vpp_change_kernel_interface(config)
- verify_vpp_exists_kernel_interface(config)
+ if not is_systemd_service_active('vpp.service'):
+ raise ConfigError(
+ 'Cannot configure VPP loopback interface: vpp.service is not running'
+ )
def generate(config):
@@ -140,23 +88,13 @@ def apply(config):
return None
ifname = config.get('ifname')
- # Delete interface
- if 'effective' in config:
- i = LoopbackInterface(ifname)
- i.delete()
-
- if 'remove' in config:
- return None
+ loopback = VPPLoopbackInterface(ifname, config)
+ loopback.remove()
- # Add interface
- kernel_interface = config.get('kernel_interface', '')
- state = 'up' if 'disable' not in config else 'down'
- i = LoopbackInterface(ifname, kernel_interface, state)
- i.add()
+ if 'deleted' in config:
+ return
- # Add kernel-interface (LCP) if interface is not exist
- if 'kernel_interface' in config and not is_interface(kernel_interface):
- i.kernel_add()
+ loopback.update(config)
call_dependents()
diff --git a/src/migration-scripts/vpp/5-to-6 b/src/migration-scripts/vpp/5-to-6
index 18f0f70d2..23b2d4eaa 100644
--- a/src/migration-scripts/vpp/5-to-6
+++ b/src/migration-scripts/vpp/5-to-6
@@ -43,6 +43,8 @@
#
# Move ipip interface from vpp section to 'interfaces vpp ipip' (T8314)
#
+# Migrate loopback interface from vpp section to 'interfaces vpp loopback' (T8324)
+#
from vyos.configtree import ConfigTree
@@ -437,6 +439,30 @@ def _migrate_vpp_ipip_interface(config: ConfigTree) -> None:
config.delete(['vpp', 'interfaces'])
+def _migrate_vpp_loopback_interface(config: ConfigTree) -> None:
+ base = ['vpp', 'interfaces', 'loopback']
+ new_base = ['interfaces', 'vpp', 'loopback']
+ 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, 'loopback', ifname)
+
+ _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(config: ConfigTree) -> None:
if not config.exists(['vpp']):
# Nothing to do
@@ -455,3 +481,4 @@ def migrate(config: ConfigTree) -> None:
_migrate_vpp_bonding_interface(config)
_migrate_vpp_vxlan_interface(config)
_migrate_vpp_ipip_interface(config)
+ _migrate_vpp_loopback_interface(config)