diff options
| author | Nataliia Solomko <natalirs1985@gmail.com> | 2025-10-07 18:21:06 +0300 |
|---|---|---|
| committer | Nataliia Solomko <natalirs1985@gmail.com> | 2025-10-14 15:41:37 +0300 |
| commit | 888eec975ff765216e4c65ba15ed9176d7dee7ea (patch) | |
| tree | 650d0f2ed8edd656e00bb8c8c4d583b5c9e90213 /src | |
| parent | fc178aaf00f7a9dc4589567ae3e17cb9718d9ad3 (diff) | |
| download | vyos-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-x | src/conf_mode/vpp.py | 5 | ||||
| -rw-r--r-- | src/conf_mode/vpp_kernel-interfaces.py | 6 | ||||
| -rw-r--r-- | src/conf_mode/vpp_nat_cgnat.py | 43 |
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', {}): |
