diff options
author | aapostoliuk <a.apostoliuk@vyos.io> | 2024-12-17 13:39:49 +0200 |
---|---|---|
committer | Christian Breunig <christian@breunig.cc> | 2025-01-06 12:05:22 +0100 |
commit | 4a194b32509ffcd9574bb7571a5a6347f7dc4e42 (patch) | |
tree | f12c3bba738fe1bcbdab8deb7dba56e8adb7d0f4 /src/conf_mode | |
parent | df176d9b9b4cc67ae509ae2ff17a02f2520cc881 (diff) | |
download | vyos-1x-4a194b32509ffcd9574bb7571a5a6347f7dc4e42.tar.gz vyos-1x-4a194b32509ffcd9574bb7571a5a6347f7dc4e42.zip |
T6841: firewall: Fixed issues in ZBF when using VRFs
Improve config parsing for ZBF when using VRFs and interfaces attached to VRFs
Diffstat (limited to 'src/conf_mode')
-rwxr-xr-x | src/conf_mode/firewall.py | 69 |
1 files changed, 36 insertions, 33 deletions
diff --git a/src/conf_mode/firewall.py b/src/conf_mode/firewall.py index c09f934aa..768bb127d 100755 --- a/src/conf_mode/firewall.py +++ b/src/conf_mode/firewall.py @@ -18,7 +18,6 @@ import os import re from sys import exit - from vyos.base import Warning from vyos.config import Config from vyos.configdict import is_node_changed @@ -135,6 +134,27 @@ def get_config(config=None): fqdn_config_parse(firewall, 'firewall') + if not os.path.exists(nftables_conf): + firewall['first_install'] = True + + if 'zone' in firewall: + for local_zone, local_zone_conf in firewall['zone'].items(): + if 'local_zone' not in local_zone_conf: + # Get physical interfaces assigned to the zone if vrf is used: + if 'vrf' in local_zone_conf['member']: + local_zone_conf['vrf_interfaces'] = {} + for vrf_name in local_zone_conf['member']['vrf']: + local_zone_conf['vrf_interfaces'][vrf_name] = ','.join(get_vrf_members(vrf_name)) + continue + + local_zone_conf['from_local'] = {} + + for zone, zone_conf in firewall['zone'].items(): + if zone == local_zone or 'from' not in zone_conf: + continue + if local_zone in zone_conf['from']: + local_zone_conf['from_local'][zone] = zone_conf['from'][local_zone] + set_dependents('conntrack', conf) return firewall @@ -447,22 +467,21 @@ def verify(firewall): if 'zone' in firewall: for zone, zone_conf in firewall['zone'].items(): - if 'local_zone' not in zone_conf and 'interface' not in zone_conf: + if 'local_zone' not in zone_conf and 'member' not in zone_conf: raise ConfigError(f'Zone "{zone}" has no interfaces and is not the local zone') if 'local_zone' in zone_conf: if local_zone: raise ConfigError('There cannot be multiple local zones') - if 'interface' in zone_conf: + if 'member' in zone_conf: raise ConfigError('Local zone cannot have interfaces assigned') if 'intra_zone_filtering' in zone_conf: raise ConfigError('Local zone cannot use intra-zone-filtering') local_zone = True - if 'interface' in zone_conf: - if 'name'in zone_conf['interface']: - - for iface in zone_conf['interface']['name']: + if 'member' in zone_conf: + if 'interface' in zone_conf['member']: + for iface in zone_conf['member']['interface']: if iface in zone_interfaces: raise ConfigError(f'Interfaces cannot be assigned to multiple zones') @@ -470,13 +489,19 @@ def verify(firewall): iface_vrf = get_interface_vrf(iface) if iface_vrf != 'default': Warning(f"Interface {iface} assigned to zone {zone} is in VRF {iface_vrf}. This might not work as expected.") - zone_interfaces += iface + zone_interfaces.append(iface) - if 'vrf' in zone_conf['interface']: - for vrf in zone_conf['interface']['vrf']: + if 'vrf' in zone_conf['member']: + for vrf in zone_conf['member']['vrf']: if vrf in zone_vrf: raise ConfigError(f'VRF cannot be assigned to multiple zones') - zone_vrf += vrf + zone_vrf.append(vrf) + + if 'vrf_interfaces' in zone_conf: + for vrf_name, vrf_interfaces in zone_conf['vrf_interfaces'].items(): + if not vrf_interfaces: + raise ConfigError( + f'VRF "{vrf_name}" cannot be a member of any zone. It does not contain any interfaces.') if 'intra_zone_filtering' in zone_conf: intra_zone = zone_conf['intra_zone_filtering'] @@ -512,28 +537,6 @@ def verify(firewall): return None def generate(firewall): - if not os.path.exists(nftables_conf): - firewall['first_install'] = True - - if 'zone' in firewall: - for local_zone, local_zone_conf in firewall['zone'].items(): - if 'local_zone' not in local_zone_conf: - # Get physical interfaces assigned to the zone if vrf is used: - if 'vrf' in local_zone_conf['interface']: - local_zone_conf['vrf_interfaces'] = {} - for vrf_name in local_zone_conf['interface']['vrf']: - local_zone_conf['vrf_interfaces'][vrf_name] = ','.join(get_vrf_members(vrf_name)) - #local_zone_conf['interface']['vrf'][vrf_name] = ''.join(get_vrf_members(vrf_name)) - continue - - local_zone_conf['from_local'] = {} - - for zone, zone_conf in firewall['zone'].items(): - if zone == local_zone or 'from' not in zone_conf: - continue - if local_zone in zone_conf['from']: - local_zone_conf['from_local'][zone] = zone_conf['from'][local_zone] - render(nftables_conf, 'firewall/nftables.j2', firewall) render(sysctl_file, 'firewall/sysctl-firewall.conf.j2', firewall) return None |