diff options
-rw-r--r-- | python/vyos/configdict.py | 15 | ||||
-rwxr-xr-x | smoketest/scripts/cli/test_firewall.py | 6 | ||||
-rwxr-xr-x | src/conf_mode/interfaces_ethernet.py | 34 |
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: |