summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--python/vyos/configdict.py15
-rwxr-xr-xsmoketest/scripts/cli/test_firewall.py6
-rwxr-xr-xsrc/conf_mode/interfaces_ethernet.py34
3 files changed, 55 insertions, 0 deletions
diff --git a/python/vyos/configdict.py b/python/vyos/configdict.py
index a34b0176a..040eb49ba 100644
--- a/python/vyos/configdict.py
+++ b/python/vyos/configdict.py
@@ -703,3 +703,18 @@ def get_accel_dict(config, base, chap_secrets, with_pki=False):
dict['authentication']['radius']['server'][server]['acct_port'] = '0'
return dict
+
+def get_flowtable_interfaces(config):
+ """
+ Return all interfaces used in flowtables
+ """
+ ft_base = ['firewall', 'flowtable']
+
+ if not config.exists(ft_base):
+ return []
+
+ ifaces = []
+ for ft_name in config.list_nodes(ft_base):
+ ifaces += config.return_values(ft_base + [ft_name, 'interface'])
+
+ return ifaces
diff --git a/smoketest/scripts/cli/test_firewall.py b/smoketest/scripts/cli/test_firewall.py
index 851a15f16..bbe4de9df 100755
--- a/smoketest/scripts/cli/test_firewall.py
+++ b/smoketest/scripts/cli/test_firewall.py
@@ -1113,6 +1113,12 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase):
self.verify_nftables_chain([['accept']], 'ip vyos_conntrack', 'FW_CONNTRACK')
self.verify_nftables_chain([['accept']], 'ip6 vyos_conntrack', 'FW_CONNTRACK')
+ # Test interface deletion
+ self.cli_delete(['interfaces', 'ethernet', 'eth0', 'vif', '10'])
+
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+
def test_zone_flow_offload(self):
self.cli_set(['firewall', 'flowtable', 'smoketest', 'interface', 'eth0'])
self.cli_set(['firewall', 'flowtable', 'smoketest', 'offload', 'hardware'])
diff --git a/src/conf_mode/interfaces_ethernet.py b/src/conf_mode/interfaces_ethernet.py
index 41c89fdf8..13d3e82e9 100755
--- a/src/conf_mode/interfaces_ethernet.py
+++ b/src/conf_mode/interfaces_ethernet.py
@@ -22,6 +22,7 @@ from vyos.base import Warning
from vyos.config import Config
from vyos.configdict import get_interface_dict
from vyos.configdict import is_node_changed
+from vyos.configdict import get_flowtable_interfaces
from vyos.configverify import verify_address
from vyos.configverify import verify_dhcpv6
from vyos.configverify import verify_interface_exists
@@ -168,6 +169,8 @@ def get_config(config=None):
tmp = is_node_changed(conf, base + [ifname, 'evpn'])
if tmp: ethernet.update({'frr_dict' : get_frrender_dict(conf)})
+ ethernet['flowtable_interfaces'] = get_flowtable_interfaces(conf)
+
return ethernet
def verify_speed_duplex(ethernet: dict, ethtool: Ethtool):
@@ -269,7 +272,38 @@ def verify_allowedbond_changes(ethernet: dict):
f' on interface "{ethernet["ifname"]}".' \
f' Interface is a bond member')
+def verify_flowtable(ethernet: dict):
+ ifname = ethernet['ifname']
+
+ if 'deleted' in ethernet and ifname in ethernet['flowtable_interfaces']:
+ raise ConfigError(f'Cannot delete interface "{ifname}", still referenced on a flowtable')
+
+ if 'vif_remove' in ethernet:
+ for vif in ethernet['vif_remove']:
+ vifname = f'{ifname}.{vif}'
+
+ if vifname in ethernet['flowtable_interfaces']:
+ raise ConfigError(f'Cannot delete interface "{vifname}", still referenced on a flowtable')
+
+ if 'vif_s_remove' in ethernet:
+ for vifs in ethernet['vif_s_remove']:
+ vifsname = f'{ifname}.{vifs}'
+
+ if vifsname in ethernet['flowtable_interfaces']:
+ raise ConfigError(f'Cannot delete interface "{vifsname}", still referenced on a flowtable')
+
+ if 'vif_s' in ethernet:
+ for vifs, vifs_conf in ethernet['vif_s'].items():
+ if 'vif_c_delete' in vifs_conf:
+ for vifc in vifs_conf['vif_c_delete']:
+ vifcname = f'{ifname}.{vifs}.{vifc}'
+
+ if vifcname in ethernet['flowtable_interfaces']:
+ raise ConfigError(f'Cannot delete interface "{vifcname}", still referenced on a flowtable')
+
def verify(ethernet):
+ verify_flowtable(ethernet)
+
if 'deleted' in ethernet:
return None
if 'is_bond_member' in ethernet: