summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Estabrook <jestabro@vyos.io>2020-11-12 08:34:01 -0600
committerGitHub <noreply@github.com>2020-11-12 08:34:01 -0600
commitbf31936562e4e827373ac56661a9e1a48ee0a0a6 (patch)
tree1d9a2a72366fde7ec757264bbab08a483cb72596 /src
parent2e498164218851f1b958c43a7b903849a80b8304 (diff)
parent3466941316a70ac840ebdcc7576230158be8a0fb (diff)
downloadvyos-1x-bf31936562e4e827373ac56661a9e1a48ee0a0a6.tar.gz
vyos-1x-bf31936562e4e827373ac56661a9e1a48ee0a0a6.zip
Merge pull request #594 from jack9603301/T3042
bridge: T3042: Support VLAN filter and VLAN sub-interface on the bridge
Diffstat (limited to 'src')
-rwxr-xr-xsrc/conf_mode/interfaces-bridge.py60
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