From 38566b8fbdec60b1601ed127fd759c85802909e9 Mon Sep 17 00:00:00 2001 From: jack9603301 Date: Sat, 9 Jan 2021 21:32:19 +0800 Subject: bridge: T3137: Let VLAN aware bridge approach the behavior of professional equipment According to the consensus, the specific behavior of a VLAN aware bridge should conform to the behavior of professional equipment. This commit makes a significant change to the behavior of VLAN aware bridge, and has the following behaviors: 1. Disable `vif 1` configuration 2. When the VLAN aware bridge is enabled, the parent interface is always VLAN 1 3. When `native-vlan` is not configured, the default behavior of the device is `native-vlan 1` 4. The VLAN ids forwarded by the bridge are determined by `vif` 5. It has an `enable-vlan` node to enable VLAN awareness 6. VLAN configuration is allowed only when VLAN aware bridge is activated --- python/vyos/ifconfig/bridge.py | 102 ++++++++++++++++------------------------- 1 file changed, 39 insertions(+), 63 deletions(-) (limited to 'python/vyos/ifconfig/bridge.py') diff --git a/python/vyos/ifconfig/bridge.py b/python/vyos/ifconfig/bridge.py index 76520f2ba..87af0c9df 100644 --- a/python/vyos/ifconfig/bridge.py +++ b/python/vyos/ifconfig/bridge.py @@ -274,20 +274,31 @@ class BridgeIf(Interface): for member in (tmp or []): if member in interfaces(): self.del_port(member) - vlan_filter = 0 - vlan_del = set() - vlan_add = set() + # enable/disable Vlan Filter + vlan_filter = 1 if 'enable_vlan' in config else 0 + self.set_vlan_filter(str(vlan_filter)) + + if vlan_filter: + del_ifname_vlan_ids = get_vlan_ids(ifname) + # Delete all VLAN IDS configured in the interface first + for vlan in del_ifname_vlan_ids: + cmd = f'bridge vlan del dev {ifname} vid {vlan} self' + self._cmd(cmd) + + tmp = dict_search('vif', config) + if tmp: + for vif, vif_config in tmp.items(): + cmd = f'bridge vlan add dev {ifname} vid {vif} self' + self._cmd(cmd) + + # VLAN of bridge parent interface is always 1 + # VLAN 1 is the default VLAN for all unlabeled packets + cmd = f'bridge vlan add dev {ifname} vid 1 pvid untagged self' + self._cmd(cmd) tmp = dict_search('member.interface', config) if tmp: - if self.get_vlan_filter(): - bridge_vlan_ids = get_vlan_ids(ifname) - # Delete VLAN ID for the bridge - if 1 in bridge_vlan_ids: - bridge_vlan_ids.remove(1) - for vlan in bridge_vlan_ids: - vlan_del.add(str(vlan)) for interface, interface_config in tmp.items(): # if interface does yet not exist bail out early and @@ -315,62 +326,27 @@ class BridgeIf(Interface): value = interface_config.get('priority') lower.set_path_priority(value) - tmp = dict_search('native_vlan_removed', interface_config) - - for vlan_id in (tmp or []): - cmd = f'bridge vlan del dev {interface} vid {vlan_id}' - self._cmd(cmd) - cmd = f'bridge vlan add dev {interface} vid 1 pvid untagged master' - self._cmd(cmd) - vlan_del.add(vlan_id) - vlan_add.add(1) - - tmp = dict_search('allowed_vlan_removed', interface_config) - - - for vlan_id in (tmp or []): - cmd = f'bridge vlan del dev {interface} vid {vlan_id}' - self._cmd(cmd) - vlan_del.add(vlan_id) - - if 'native_vlan' in interface_config: - vlan_filter = 1 - cmd = f'bridge vlan del dev {interface} vid 1' - self._cmd(cmd) - vlan_id = interface_config['native_vlan'] - if int(vlan_id) != 1: - if 1 in vlan_add: - vlan_add.remove(1) - vlan_del.add(1) - cmd = f'bridge vlan add dev {interface} vid {vlan_id} pvid untagged master' - self._cmd(cmd) - vlan_add.add(vlan_id) - if vlan_id in vlan_del: - vlan_del.remove(vlan_id) - - if 'allowed_vlan' in interface_config: - vlan_filter = 1 - if 'native_vlan' not in interface_config: - cmd = f'bridge vlan del dev {interface} vid 1' + if vlan_filter: + + del_member_vlan_ids = get_vlan_ids(interface) + # Delete all VLAN IDS configured in the interface first + for vlan in del_member_vlan_ids: + cmd = f'bridge vlan del dev {interface} vid {vlan} master' self._cmd(cmd) - vlan_del.add(1) - for vlan in interface_config['allowed_vlan']: - cmd = f'bridge vlan add dev {interface} vid {vlan} master' + + if 'native_vlan' in interface_config: + vlan_id = interface_config['native_vlan'] + cmd = f'bridge vlan add dev {interface} vid {vlan_id} pvid untagged master' + self._cmd(cmd) + else: + # VLAN 1 is the default VLAN for all unlabeled packets + cmd = f'bridge vlan add dev {interface} vid 1 pvid untagged master' self._cmd(cmd) - vlan_add.add(vlan) - if vlan in vlan_del: - vlan_del.remove(vlan) - - for vlan in vlan_del: - cmd = f'bridge vlan del dev {ifname} vid {vlan} self' - self._cmd(cmd) - - for vlan in vlan_add: - cmd = f'bridge vlan add dev {ifname} vid {vlan} self' - self._cmd(cmd) - # enable/disable Vlan Filter - self.set_vlan_filter(vlan_filter) + if 'allowed_vlan' in interface_config: + for vlan in interface_config['allowed_vlan']: + cmd = f'bridge vlan add dev {interface} vid {vlan} master' + self._cmd(cmd) # Enable/Disable of an interface must always be done at the end of the -- cgit v1.2.3