diff options
| -rw-r--r-- | interface-definitions/include/interface/vif-s.xml.i | 22 | ||||
| -rw-r--r-- | interface-definitions/include/interface/vlan-protocol.xml.i | 23 | ||||
| -rw-r--r-- | interface-definitions/interfaces_bridge.xml.in | 4 | ||||
| -rw-r--r-- | python/vyos/ifconfig/bridge.py | 34 | ||||
| -rwxr-xr-x | smoketest/scripts/cli/test_interfaces_bridge.py | 18 | 
5 files changed, 76 insertions, 25 deletions
| diff --git a/interface-definitions/include/interface/vif-s.xml.i b/interface-definitions/include/interface/vif-s.xml.i index fdd62b63d..02e7ab057 100644 --- a/interface-definitions/include/interface/vif-s.xml.i +++ b/interface-definitions/include/interface/vif-s.xml.i @@ -18,27 +18,7 @@      #include <include/interface/dhcpv6-options.xml.i>      #include <include/interface/disable-link-detect.xml.i>      #include <include/interface/disable.xml.i> -    <leafNode name="protocol"> -      <properties> -        <help>Protocol used for service VLAN (default: 802.1ad)</help> -        <completionHelp> -          <list>802.1ad 802.1q</list> -        </completionHelp> -        <valueHelp> -          <format>802.1ad</format> -          <description>Provider Bridging (IEEE 802.1ad, Q-inQ), ethertype 0x88a8</description> -        </valueHelp> -        <valueHelp> -          <format>802.1q</format> -          <description>VLAN-tagged frame (IEEE 802.1q), ethertype 0x8100</description> -        </valueHelp> -        <constraint> -          <regex>(802.1q|802.1ad)</regex> -        </constraint> -        <constraintErrorMessage>Ethertype must be 802.1ad or 802.1q</constraintErrorMessage> -      </properties> -      <defaultValue>802.1ad</defaultValue> -    </leafNode> +    #include <include/interface/vlan-protocol.xml.i>      #include <include/interface/ipv4-options.xml.i>      #include <include/interface/ipv6-options.xml.i>      #include <include/interface/mac.xml.i> diff --git a/interface-definitions/include/interface/vlan-protocol.xml.i b/interface-definitions/include/interface/vlan-protocol.xml.i new file mode 100644 index 000000000..2fe8d65d7 --- /dev/null +++ b/interface-definitions/include/interface/vlan-protocol.xml.i @@ -0,0 +1,23 @@ +<!-- include start from interface/vif.xml.i --> +<leafNode name="protocol"> +  <properties> +    <help>Protocol used for service VLAN (default: 802.1ad)</help> +    <completionHelp> +      <list>802.1ad 802.1q</list> +    </completionHelp> +    <valueHelp> +      <format>802.1ad</format> +      <description>Provider Bridging (IEEE 802.1ad, Q-inQ), ethertype 0x88a8</description> +    </valueHelp> +    <valueHelp> +      <format>802.1q</format> +      <description>VLAN-tagged frame (IEEE 802.1q), ethertype 0x8100</description> +    </valueHelp> +    <constraint> +      <regex>(802.1q|802.1ad)</regex> +    </constraint> +    <constraintErrorMessage>Ethertype must be 802.1ad or 802.1q</constraintErrorMessage> +  </properties> +  <defaultValue>802.1ad</defaultValue> +</leafNode> +<!-- include end --> diff --git a/interface-definitions/interfaces_bridge.xml.in b/interface-definitions/interfaces_bridge.xml.in index d4d277cfc..7fb5f121a 100644 --- a/interface-definitions/interfaces_bridge.xml.in +++ b/interface-definitions/interfaces_bridge.xml.in @@ -98,6 +98,10 @@                <valueless/>              </properties>            </leafNode> +          #include <include/interface/vlan-protocol.xml.i> +          <leafNode name="protocol"> +            <defaultValue>802.1q</defaultValue> +          </leafNode>            <leafNode name="max-age">              <properties>                <help>Interval at which neighbor bridges are removed</help> diff --git a/python/vyos/ifconfig/bridge.py b/python/vyos/ifconfig/bridge.py index b29e71394..7936e3da5 100644 --- a/python/vyos/ifconfig/bridge.py +++ b/python/vyos/ifconfig/bridge.py @@ -1,4 +1,4 @@ -# Copyright 2019-2021 VyOS maintainers and contributors <maintainers@vyos.io> +# Copyright 2019-2024 VyOS maintainers and contributors <maintainers@vyos.io>  #  # This library is free software; you can redistribute it and/or  # modify it under the terms of the GNU Lesser General Public @@ -14,12 +14,11 @@  # License along with this library.  If not, see <http://www.gnu.org/licenses/>.  from netifaces import interfaces -import json  from vyos.ifconfig.interface import Interface  from vyos.utils.assertion import assert_boolean +from vyos.utils.assertion import assert_list  from vyos.utils.assertion import assert_positive -from vyos.utils.process import cmd  from vyos.utils.dict import dict_search  from vyos.configdict import get_vlan_ids  from vyos.configdict import list_diff @@ -86,6 +85,10 @@ class BridgeIf(Interface):              'validate': assert_boolean,              'location': '/sys/class/net/{ifname}/bridge/vlan_filtering',          }, +        'vlan_protocol': { +            'validate': lambda v: assert_list(v, ['0x88a8', '0x8100']), +            'location': '/sys/class/net/{ifname}/bridge/vlan_protocol', +        },          'multicast_querier': {              'validate': assert_boolean,              'location': '/sys/class/net/{ifname}/bridge/multicast_querier', @@ -248,6 +251,26 @@ class BridgeIf(Interface):          """          return self.set_interface('del_port', interface) +    def set_vlan_protocol(self, protocol): +        """ +        Set protocol used for VLAN filtering. +        The valid values are 0x8100(802.1q) or 0x88A8(802.1ad). + +        Example: +        >>> from vyos.ifconfig import Interface +        >>> BridgeIf('br0').del_port('eth1') +        """ + +        if protocol not in ['802.1q', '802.1ad']: +            raise ValueError() + +        map = { +            '802.1ad': '0x88a8', +            '802.1q' : '0x8100' +        } + +        return self.set_interface('vlan_protocol', map[protocol]) +      def update(self, config):          """ General helper function which works on a dictionary retrived by          get_config_dict(). It's main intention is to consolidate the scattered @@ -294,10 +317,13 @@ class BridgeIf(Interface):              if member in interfaces():                  self.del_port(member) -        # enable/disable Vlan Filter +        # enable/disable VLAN Filter          tmp = '1' if 'enable_vlan' in config else '0'          self.set_vlan_filter(tmp) +        tmp = config.get('protocol') +        self.set_vlan_protocol(tmp) +          # add VLAN interfaces to local 'parent' bridge to allow forwarding          if 'enable_vlan' in config:              for vlan in config.get('vif_remove', {}): diff --git a/smoketest/scripts/cli/test_interfaces_bridge.py b/smoketest/scripts/cli/test_interfaces_bridge.py index 3500e97d6..124c1fbcb 100755 --- a/smoketest/scripts/cli/test_interfaces_bridge.py +++ b/smoketest/scripts/cli/test_interfaces_bridge.py @@ -182,6 +182,10 @@ class BridgeInterfaceTest(BasicInterfaceTest.TestCase):          for interface in self._interfaces:              cost = 1000              priority = 10 + +            tmp = get_interface_config(interface) +            self.assertEqual('802.1Q',  tmp['linkinfo']['info_data']['vlan_protocol']) # default VLAN protocol +              for member in self._members:                  tmp = get_interface_config(member)                  self.assertEqual(interface, tmp['master']) @@ -442,5 +446,19 @@ class BridgeInterfaceTest(BasicInterfaceTest.TestCase):          self.cli_delete(['interfaces', 'tunnel', tunnel_if])          self.cli_delete(['interfaces', 'ethernet', 'eth0', 'address', eth0_addr]) +    def test_bridge_vlan_protocol(self): +        protocol = '802.1ad' + +        # Add member interface to bridge and set VLAN filter +        for interface in self._interfaces: +            self.cli_set(self._base_path + [interface, 'protocol', protocol]) + +        # commit config +        self.cli_commit() + +        for interface in self._interfaces: +            tmp = get_interface_config(interface) +            self.assertEqual(protocol, tmp['linkinfo']['info_data']['vlan_protocol']) +  if __name__ == '__main__':      unittest.main(verbosity=2) | 
