diff options
Diffstat (limited to 'python/vyos/configverify.py')
-rw-r--r-- | python/vyos/configverify.py | 56 |
1 files changed, 43 insertions, 13 deletions
diff --git a/python/vyos/configverify.py b/python/vyos/configverify.py index 365a28feb..1062d51ee 100644 --- a/python/vyos/configverify.py +++ b/python/vyos/configverify.py @@ -173,24 +173,43 @@ def verify_eapol(config): if ca_cert_name not in config['pki']['ca']: raise ConfigError('Invalid CA certificate specified for EAPoL') - ca_cert = config['pki']['ca'][cert_name] + ca_cert = config['pki']['ca'][ca_cert_name] if 'certificate' not in ca_cert: raise ConfigError('Invalid CA certificate specified for EAPoL') -def verify_mirror(config): +def verify_mirror_redirect(config): """ Common helper function used by interface implementations to perform - recurring validation of mirror interface configuration. + recurring validation of mirror and redirect interface configuration via tc(8) It makes no sense to mirror traffic back at yourself! """ + import os + if {'mirror', 'redirect'} <= set(config): + raise ConfigError('Mirror and redirect can not be enabled at the same time!') + if 'mirror' in config: for direction, mirror_interface in config['mirror'].items(): + if not os.path.exists(f'/sys/class/net/{mirror_interface}'): + raise ConfigError(f'Requested mirror interface "{mirror_interface}" '\ + 'does not exist!') + if mirror_interface == config['ifname']: - raise ConfigError(f'Can not mirror "{direction}" traffic back ' \ + raise ConfigError(f'Can not mirror "{direction}" traffic back '\ 'the originating interface!') + if 'redirect' in config: + redirect_ifname = config['redirect'] + if not os.path.exists(f'/sys/class/net/{redirect_ifname}'): + raise ConfigError(f'Requested redirect interface "{redirect_ifname}" '\ + 'does not exist!') + + if dict_search('traffic_policy.in', config) != None: + # XXX: support combination of limiting and redirect/mirror - this is an + # artificial limitation + raise ConfigError('Can not use ingress policy tigether with mirror or redirect!') + def verify_authentication(config): """ Common helper function used by interface implementations to perform @@ -224,9 +243,10 @@ def verify_bridge_delete(config): when interface also is part of a bridge. """ if 'is_bridge_member' in config: - raise ConfigError( - 'Interface "{ifname}" cannot be deleted as it is a ' - 'member of bridge "{is_bridge_member}"!'.format(**config)) + interface = config['ifname'] + for bridge in config['is_bridge_member']: + raise ConfigError(f'Interface "{interface}" cannot be deleted as it ' + f'is a member of bridge "{bridge}"!') def verify_interface_exists(ifname): """ @@ -308,27 +328,37 @@ def verify_vlan_config(config): if duplicate: raise ConfigError(f'Duplicate VLAN id "{duplicate[0]}" used for vif and vif-s interfaces!') + parent_ifname = config['ifname'] # 802.1q VLANs - for vlan in config.get('vif', {}): - vlan = config['vif'][vlan] + for vlan_id in config.get('vif', {}): + vlan = config['vif'][vlan_id] + vlan['ifname'] = f'{parent_ifname}.{vlan_id}' + verify_dhcpv6(vlan) verify_address(vlan) verify_vrf(vlan) + verify_mirror_redirect(vlan) verify_mtu_parent(vlan, config) # 802.1ad (Q-in-Q) VLANs - for s_vlan in config.get('vif_s', {}): - s_vlan = config['vif_s'][s_vlan] + for s_vlan_id in config.get('vif_s', {}): + s_vlan = config['vif_s'][s_vlan_id] + s_vlan['ifname'] = f'{parent_ifname}.{s_vlan_id}' + verify_dhcpv6(s_vlan) verify_address(s_vlan) verify_vrf(s_vlan) + verify_mirror_redirect(s_vlan) verify_mtu_parent(s_vlan, config) - for c_vlan in s_vlan.get('vif_c', {}): - c_vlan = s_vlan['vif_c'][c_vlan] + for c_vlan_id in s_vlan.get('vif_c', {}): + c_vlan = s_vlan['vif_c'][c_vlan_id] + c_vlan['ifname'] = f'{parent_ifname}.{s_vlan_id}.{c_vlan_id}' + verify_dhcpv6(c_vlan) verify_address(c_vlan) verify_vrf(c_vlan) + verify_mirror_redirect(c_vlan) verify_mtu_parent(c_vlan, config) verify_mtu_parent(c_vlan, s_vlan) |