summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Breunig <christian@breunig.cc>2024-03-20 21:25:43 +0100
committerMergify <37929162+mergify[bot]@users.noreply.github.com>2024-03-21 00:05:37 +0000
commit5a8f9d44b3c2e09a16fc0bf082ba30729c04e81a (patch)
treec4f0293a69073e13d3ab7649771a75966c20963c
parent197f48aa3286c52989739f72d52fe280877d8ed1 (diff)
downloadvyos-1x-5a8f9d44b3c2e09a16fc0bf082ba30729c04e81a.tar.gz
vyos-1x-5a8f9d44b3c2e09a16fc0bf082ba30729c04e81a.zip
bridge: T6125: support 802.1ad (ethertype 0x88a8) VLAN filtering
Linux bridge uses EtherType 0x8100 by default. In some scenarios, an EtherType value of 0x88A8 is required. Reusing CLI command from VIF-S (QinQ) interfaces: set interfaces bridge br0 protocol 802.1ad (cherry picked from commit 9c9b1febff6863ccd3632a04d9e307909b3efe7a)
-rw-r--r--interface-definitions/include/interface/vif-s.xml.i22
-rw-r--r--interface-definitions/include/interface/vlan-protocol.xml.i23
-rw-r--r--interface-definitions/interfaces_bridge.xml.in4
-rw-r--r--python/vyos/ifconfig/bridge.py34
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_bridge.py18
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)