diff options
author | jack9603301 <jack9603301@163.com> | 2020-11-10 12:24:31 +0800 |
---|---|---|
committer | jack9603301 <jack9603301@163.com> | 2020-11-10 12:24:49 +0800 |
commit | 3466941316a70ac840ebdcc7576230158be8a0fb (patch) | |
tree | 73a00197f3a37d729e17e5446db0e5ebbc14ac31 /src | |
parent | ad856600ca29ba463de2b288189d3f40b9e91846 (diff) | |
download | vyos-1x-3466941316a70ac840ebdcc7576230158be8a0fb.tar.gz vyos-1x-3466941316a70ac840ebdcc7576230158be8a0fb.zip |
bridge: T3042: Support VLAN filter and VLAN sub-interface on the bridge
Diffstat (limited to 'src')
-rwxr-xr-x | src/conf_mode/interfaces-bridge.py | 60 |
1 files changed, 59 insertions, 1 deletions
diff --git a/src/conf_mode/interfaces-bridge.py b/src/conf_mode/interfaces-bridge.py index 258f9ec79..076bdb63e 100755 --- a/src/conf_mode/interfaces-bridge.py +++ b/src/conf_mode/interfaces-bridge.py @@ -18,12 +18,15 @@ import os from sys import exit from netifaces import interfaces +import re from vyos.config import Config from vyos.configdict import get_interface_dict from vyos.configdict import node_changed +from vyos.configdict import leaf_node_changed from vyos.configdict import is_member from vyos.configdict import is_source_interface +from vyos.configdict import has_vlan_subinterface_configured from vyos.configdict import dict_merge from vyos.configverify import verify_dhcpv6 from vyos.configverify import verify_vrf @@ -38,6 +41,26 @@ from vyos import ConfigError from vyos import airbag airbag.enable() +def helper_check_removed_vlan(conf,bridge,key,key_mangling): + key_update = re.sub(key_mangling[0], key_mangling[1], key) + if dict_search('member.interface', bridge): + for interface in bridge['member']['interface']: + tmp = leaf_node_changed(conf, ['member', 'interface',interface,key]) + if tmp: + if 'member' in bridge: + if 'interface' in bridge['member']: + if interface in bridge['member']['interface']: + bridge['member']['interface'][interface].update({f'{key_update}_removed': tmp }) + else: + bridge['member']['interface'].update({interface: {f'{key_update}_removed': tmp }}) + else: + bridge['member'].update({ 'interface': {interface: {f'{key_update}_removed': tmp }}}) + else: + bridge.update({'member': { 'interface': {interface: {f'{key_update}_removed': tmp }}}}) + + return bridge + + def get_config(config=None): """ Retrive CLI config as dictionary. Dictionary can never be empty, as at least the @@ -57,6 +80,12 @@ def get_config(config=None): bridge['member'].update({'interface_remove': tmp }) else: bridge.update({'member': {'interface_remove': tmp }}) + + + # determine which members vlan have been removed + + bridge = helper_check_removed_vlan(conf,bridge,'native-vlan',('-', '_')) + bridge = helper_check_removed_vlan(conf,bridge,'allowed-vlan',('-', '_')) if dict_search('member.interface', bridge): # XXX: T2665: we need a copy of the dict keys for iteration, else we will get: @@ -70,7 +99,8 @@ def get_config(config=None): # the default dictionary is not properly paged into the dict (see T2665) # thus we will ammend it ourself default_member_values = defaults(base + ['member', 'interface']) - for interface in bridge['member']['interface']: + vlan_aware = False + for interface,interface_config in bridge['member']['interface'].items(): bridge['member']['interface'][interface] = dict_merge( default_member_values, bridge['member']['interface'][interface]) @@ -90,6 +120,19 @@ def get_config(config=None): # Bridge members must not have an assigned address tmp = has_address_configured(conf, interface) if tmp: bridge['member']['interface'][interface].update({'has_address' : ''}) + + # VLAN-aware bridge members must not have VLAN interface configuration + if 'native_vlan' in interface_config: + if 'disable' not in interface_config['native_vlan']: + vlan_aware = True + + if 'allowed_vlan' in interface_config: + vlan_aware = True + + if vlan_aware: + tmp = has_vlan_subinterface_configured(conf,interface) + if tmp: + if tmp: bridge['member']['interface'][interface].update({'has_vlan' : ''}) return bridge @@ -121,6 +164,21 @@ def verify(bridge): if 'has_address' in interface_config: raise ConfigError(error_msg + 'it has an address assigned!') + + if 'has_vlan' in interface_config: + raise ConfigError(error_msg + 'it has an VLAN subinterface assigned!') + + if 'allowed_vlan' in interface_config: + for vlan in interface_config['allowed_vlan']: + if re.search('[0-9]{1,4}-[0-9]{1,4}', vlan): + vlan_range = vlan.split('-') + if int(vlan_range[0]) <1 and int(vlan_range[0])>4094: + raise ConfigError('VLAN ID must be between 1 and 4094') + if int(vlan_range[1]) <1 and int(vlan_range[1])>4094: + raise ConfigError('VLAN ID must be between 1 and 4094') + else: + if int(vlan) <1 and int(vlan)>4094: + raise ConfigError('VLAN ID must be between 1 and 4094') return None |