Skip to content

Commit 3b6f7ea

Browse files
committed
T7949: VPP add the ability to configure bond subinterfaces for NAT
1 parent d272b25 commit 3b6f7ea

File tree

5 files changed

+42
-26
lines changed

5 files changed

+42
-26
lines changed

data/config-mode-dependencies/vyos-vpp.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,8 @@
6767
"vpp_kernel_interface": ["vpp_kernel-interfaces"]
6868
},
6969
"vpp_kernel_interfaces": {
70-
"vpp_nat_cgnat": ["vpp_nat_cgnat"]
70+
"vpp_nat_cgnat": ["vpp_nat_cgnat"],
71+
"vpp_nat": ["vpp_nat"]
7172
}
7273
}
7374

python/vyos/vpp/utils.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,22 @@ def iftunnel_transform(iface: str) -> str:
4848
return f'{iface_type}_tunnel{iface_num}'
4949

5050

51+
def vpp_iface_name_transform(iface: str) -> str:
52+
"""Convert a CLI interface name to its corresponding VPP interface name format
53+
54+
Args:
55+
iface (str): Interface name as used in VyOS configuration (e.g., "bond0").
56+
57+
Returns:
58+
str: Interface name formatted as recognized by VPP (e.g., "BondEthernet0").
59+
"""
60+
vpp_iface_name = iface
61+
if vpp_iface_name.startswith('bond'):
62+
# interface name in VPP is BondEthernetX
63+
vpp_iface_name = vpp_iface_name.replace('bond', 'BondEthernet')
64+
return vpp_iface_name
65+
66+
5167
def cli_ifaces_list(config_instance, mode: str = 'candidate') -> list[str]:
5268
"""List of all VPP interfaces (CLI names)
5369

src/conf_mode/vpp_kernel-interfaces.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ def get_config(config=None) -> dict:
8282

8383
if conf.exists(['vpp', 'nat', 'cgnat']):
8484
set_dependents('vpp_nat_cgnat', conf)
85+
if conf.exists(['vpp', 'nat44']):
86+
set_dependents('vpp_nat', conf)
8587

8688
config['ifname'] = ifname
8789

src/conf_mode/vpp_nat.py

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@
2626
from vyos.utils.network import get_interface_address
2727

2828
from vyos.vpp.utils import cli_ifaces_list
29+
from vyos.vpp.utils import vpp_iface_name_transform
2930
from vyos.vpp.nat.nat44 import Nat44
31+
from vyos.vpp.control_vpp import VPPControl
3032

3133

3234
protocol_map = {
@@ -155,16 +157,14 @@ def verify(config):
155157
f'Both inside and outside interfaces must be configured. Please add: {", ".join(missing_keys)}'
156158
)
157159

158-
for interface in config['interface']['inside']:
159-
if interface not in config['vpp_ifaces']:
160-
raise ConfigError(
161-
f'{interface} must be a VPP interface for inside NAT interface'
162-
)
163-
for interface in config['interface']['outside']:
164-
if interface not in config['vpp_ifaces']:
165-
raise ConfigError(
166-
f'{interface} must be a VPP interface for outside NAT interface'
167-
)
160+
vpp = VPPControl()
161+
for direction in ['inside', 'outside']:
162+
for interface in config['interface'][direction]:
163+
vpp_iface_name = vpp_iface_name_transform(interface)
164+
if vpp.get_sw_if_index(vpp_iface_name) is None:
165+
raise ConfigError(
166+
f'{interface} must be a VPP interface for {direction} NAT interface'
167+
)
168168

169169
if not config.get('address_pool', {}).get('translation') and not config.get(
170170
'static', {}
@@ -371,11 +371,13 @@ def apply(config):
371371
# Delete inside interfaces
372372
for interface in remove_config['interface']['inside']:
373373
if interface not in config.get('interface', {}).get('inside', []):
374-
n.delete_nat44_interface_inside(interface)
374+
vpp_iface_name = vpp_iface_name_transform(interface)
375+
n.delete_nat44_interface_inside(vpp_iface_name)
375376
# Delete outside interfaces
376377
for interface in remove_config['interface']['outside']:
377378
if interface not in config.get('interface', {}).get('outside', []):
378-
n.delete_nat44_interface_outside(interface)
379+
vpp_iface_name = vpp_iface_name_transform(interface)
380+
n.delete_nat44_interface_outside(vpp_iface_name)
379381
# Delete address pool
380382
address_pool = config.get('address_pool', {})
381383
for address in (
@@ -445,10 +447,12 @@ def apply(config):
445447

446448
# Add inside interfaces
447449
for interface in config['interface']['inside']:
448-
n.add_nat44_interface_inside(interface)
450+
vpp_iface_name = vpp_iface_name_transform(interface)
451+
n.add_nat44_interface_inside(vpp_iface_name)
449452
# Add outside interfaces
450453
for interface in config['interface']['outside']:
451-
n.add_nat44_interface_outside(interface)
454+
vpp_iface_name = vpp_iface_name_transform(interface)
455+
n.add_nat44_interface_outside(vpp_iface_name)
452456
# Add translation pool
453457
for address in (
454458
config.get('address_pool', {}).get('translation', {}).get('address', [])

src/conf_mode/vpp_nat_cgnat.py

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,12 @@
2121
from vyos.configdict import node_changed
2222
from vyos.configdiff import Diff
2323
from vyos.vpp.utils import cli_ifaces_list
24+
from vyos.vpp.utils import vpp_iface_name_transform
2425

2526
from vyos.vpp.nat.det44 import Det44
2627
from vyos.vpp.control_vpp import VPPControl
2728

2829

29-
def _vpp_iface_name_transform(iface_name):
30-
vpp_iface_name = iface_name
31-
if vpp_iface_name.startswith('bond'):
32-
# interface name in VPP is BondEthernetX
33-
vpp_iface_name = vpp_iface_name.replace('bond', 'BondEthernet')
34-
return vpp_iface_name
35-
36-
3730
def get_config(config=None) -> dict:
3831
if config:
3932
conf = config
@@ -132,7 +125,7 @@ def verify(config):
132125
vpp = VPPControl()
133126
for direction in ['inside', 'outside']:
134127
for interface in config['interface'][direction]:
135-
vpp_iface_name = _vpp_iface_name_transform(interface)
128+
vpp_iface_name = vpp_iface_name_transform(interface)
136129
if vpp.get_sw_if_index(vpp_iface_name) is None:
137130
raise ConfigError(
138131
f'{interface} must be a VPP interface for {direction} CGNAT interface'
@@ -187,11 +180,11 @@ def apply(config):
187180
cgnat.enable_det44_plugin()
188181
# Add inside interfaces
189182
for interface in config['interface']['inside']:
190-
vpp_iface_name = _vpp_iface_name_transform(interface)
183+
vpp_iface_name = vpp_iface_name_transform(interface)
191184
cgnat.add_det44_interface_inside(vpp_iface_name)
192185
# Add outside interfaces
193186
for interface in config['interface']['outside']:
194-
vpp_iface_name = _vpp_iface_name_transform(interface)
187+
vpp_iface_name = vpp_iface_name_transform(interface)
195188
cgnat.add_det44_interface_outside(vpp_iface_name)
196189
# Add CGNAT rules
197190
for rule in config['changed_rules']:

0 commit comments

Comments
 (0)