summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNataliia Solomko <natalirs1985@gmail.com>2025-10-07 18:21:06 +0300
committerNataliia Solomko <natalirs1985@gmail.com>2025-10-14 15:41:37 +0300
commit888eec975ff765216e4c65ba15ed9176d7dee7ea (patch)
tree650d0f2ed8edd656e00bb8c8c4d583b5c9e90213 /src
parentfc178aaf00f7a9dc4589567ae3e17cb9718d9ad3 (diff)
downloadvyos-1x-888eec975ff765216e4c65ba15ed9176d7dee7ea.tar.gz
vyos-1x-888eec975ff765216e4c65ba15ed9176d7dee7ea.zip
T7750: VPP: CGNAT commit failure with vpptunX interface
Allow using bond interfaces in CGNAT. Improve interface cleanup to rely on VPP API queries, as VPP config changes may modify interface indexes
Diffstat (limited to 'src')
-rwxr-xr-xsrc/conf_mode/vpp.py5
-rw-r--r--src/conf_mode/vpp_kernel-interfaces.py6
-rw-r--r--src/conf_mode/vpp_nat_cgnat.py43
3 files changed, 36 insertions, 18 deletions
diff --git a/src/conf_mode/vpp.py b/src/conf_mode/vpp.py
index 81502c0b4..2d8c17e4f 100755
--- a/src/conf_mode/vpp.py
+++ b/src/conf_mode/vpp.py
@@ -373,6 +373,11 @@ def get_config(config=None):
eth_ifaces_persist[iface]['bus_id'] = control_host.get_bus_name(iface)
eth_ifaces_persist[iface]['dev_id'] = control_host.get_dev_id(iface)
+ # 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', 'nat44']):
set_dependents('vpp_nat', conf)
diff --git a/src/conf_mode/vpp_kernel-interfaces.py b/src/conf_mode/vpp_kernel-interfaces.py
index 85706094e..d10449eec 100644
--- a/src/conf_mode/vpp_kernel-interfaces.py
+++ b/src/conf_mode/vpp_kernel-interfaces.py
@@ -19,6 +19,7 @@
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
@@ -79,6 +80,9 @@ def get_config(config=None) -> dict:
if vlans_removed:
config['vlans_removed'] = vlans_removed
+ if conf.exists(['vpp', 'nat', 'cgnat']):
+ set_dependents('vpp_nat_cgnat', conf)
+
config['ifname'] = ifname
return config
@@ -185,6 +189,8 @@ def apply(config):
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
diff --git a/src/conf_mode/vpp_nat_cgnat.py b/src/conf_mode/vpp_nat_cgnat.py
index be2386ba2..56d11b5a1 100644
--- a/src/conf_mode/vpp_nat_cgnat.py
+++ b/src/conf_mode/vpp_nat_cgnat.py
@@ -23,6 +23,15 @@ from vyos.configdiff import Diff
from vyos.vpp.utils import cli_ifaces_list
from vyos.vpp.nat.det44 import Det44
+from vyos.vpp.control_vpp import VPPControl
+
+
+def _vpp_iface_name_transform(iface_name):
+ vpp_iface_name = iface_name
+ if vpp_iface_name.startswith('bond'):
+ # interface name in VPP is BondEthernetX
+ vpp_iface_name = vpp_iface_name.replace('bond', 'BondEthernet')
+ return vpp_iface_name
def get_config(config=None) -> dict:
@@ -120,16 +129,14 @@ def verify(config):
f'Please choose a side for: {", ".join(conflict_ifaces)} '
)
- for interface in config['interface']['inside']:
- if interface not in config['vpp_ifaces']:
- raise ConfigError(
- f'{interface} must be a VPP interface for inside CGNAT interface'
- )
- for interface in config['interface']['outside']:
- if interface not in config['vpp_ifaces']:
- raise ConfigError(
- f'{interface} must be a VPP interface for outside CGNAT interface'
- )
+ vpp = VPPControl()
+ for direction in ['inside', 'outside']:
+ for interface in config['interface'][direction]:
+ vpp_iface_name = _vpp_iface_name_transform(interface)
+ if vpp.get_sw_if_index(vpp_iface_name) is None:
+ raise ConfigError(
+ f'{interface} must be a VPP interface for {direction} CGNAT interface'
+ )
required_keys = {'outside_prefix', 'inside_prefix'}
for rule in config['rule']:
@@ -158,13 +165,11 @@ def apply(config):
if 'effective' in config:
remove_config = config.get('effective')
# Delete inside interfaces
- for interface in remove_config['interface']['inside']:
- if interface not in config.get('interface', {}).get('inside', []):
- cgnat.delete_det44_interface_inside(interface)
+ for interface in cgnat.get_det44_interfaces_inside():
+ cgnat.delete_det44_interface_inside(interface)
# Delete outside interfaces
- for interface in remove_config['interface']['outside']:
- if interface not in config.get('interface', {}).get('outside', []):
- cgnat.delete_det44_interface_outside(interface)
+ for interface in cgnat.get_det44_interfaces_outside():
+ cgnat.delete_det44_interface_outside(interface)
# Delete CGNAT rules
for rule in config['changed_rules']:
if rule in remove_config.get('rule', {}):
@@ -182,10 +187,12 @@ def apply(config):
cgnat.enable_det44_plugin()
# Add inside interfaces
for interface in config['interface']['inside']:
- cgnat.add_det44_interface_inside(interface)
+ vpp_iface_name = _vpp_iface_name_transform(interface)
+ cgnat.add_det44_interface_inside(vpp_iface_name)
# Add outside interfaces
for interface in config['interface']['outside']:
- cgnat.add_det44_interface_outside(interface)
+ vpp_iface_name = _vpp_iface_name_transform(interface)
+ cgnat.add_det44_interface_outside(vpp_iface_name)
# Add CGNAT rules
for rule in config['changed_rules']:
if rule in config.get('rule', {}):