Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions src/conf_mode/interfaces_ethernet.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.

import os
import re

from sys import exit

Expand Down Expand Up @@ -171,6 +172,13 @@ def get_config(config=None):

ethernet['flowtable_interfaces'] = get_flowtable_interfaces(conf)

ethernet['vpp'] = conf.get_config_dict(
['vpp'],
key_mangling=('-', '_'),
get_first_key=True,
no_tag_node_value_mangle=True,
)

return ethernet

def verify_speed_duplex(ethernet: dict, ethtool: Ethtool):
Expand Down Expand Up @@ -301,8 +309,51 @@ def verify_flowtable(ethernet: dict):
if vifcname in ethernet['flowtable_interfaces']:
raise ConfigError(f'Cannot delete interface "{vifcname}", still referenced on a flowtable')

def verify_vpp_remove_vif(ethernet: dict):
"""Ensure that VIF interfaces being removed are not used by VPP features"""
possible_vpp_paths = [
# Known paths that already use VLAN interfaces
r'nat.cgnat.interface.inside',
r'nat.cgnat.interface.outside',
r'nat44.interface.inside',
r'nat44.interface.outside',
# Potential paths for VLAN interfaces
r'nat44.address_pool.translation.interface',
r'nat44.address_pool.twice_nat.interface',
r'nat44.exclude.rule.(\d)+.external_interface',
r'interfaces.bonding.bond(\d)+.member.interface',
r'interfaces.bridge.br(\d)+.member.interface',
r'interfaces.xconnect.xcon(\d)+.member.interface',
r'acl.ip.interface',
r'acl.macip.interface',
]
ifname = ethernet['ifname']
vpp_flat = dict_to_paths_values(ethernet.get('vpp', {}))

for vif_group in ['vif_remove', 'vif_s_remove']:
for vif_id in ethernet.get(vif_group, []):
vif_name = f'{ifname}.{vif_id}'

# Find all VPP paths that reference this VIF
matching_paths = [
key
for pattern in possible_vpp_paths
for key, value in vpp_flat.items()
if re.fullmatch(pattern, key)
and (
value == vif_name or (isinstance(value, list) and vif_name in value)
)
]

if matching_paths:
raise ConfigError(
f'Cannot delete interface "{vif_name}", it is still in use by '
f'"vpp {matching_paths[0].replace(".", " ")}"'
)

def verify(ethernet):
verify_flowtable(ethernet)
verify_vpp_remove_vif(ethernet)

if 'deleted' in ethernet:
return None
Expand Down
Loading