Skip to content

Commit

Permalink
Merge pull request #3158 from c-po/bridge-T6125
Browse files Browse the repository at this point in the history
bridge: T6125: support 802.1ad (ethertype 0x88a8) VLAN filtering
  • Loading branch information
dmbaturin committed Mar 21, 2024
2 parents 33dfe6e + 9c9b1fe commit d03916b
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 25 deletions.
22 changes: 1 addition & 21 deletions interface-definitions/include/interface/vif-s.xml.i
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
23 changes: 23 additions & 0 deletions interface-definitions/include/interface/vlan-protocol.xml.i
Original file line number Diff line number Diff line change
@@ -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 -->
4 changes: 4 additions & 0 deletions interface-definitions/interfaces_bridge.xml.in
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
34 changes: 30 additions & 4 deletions python/vyos/ifconfig/bridge.py
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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',
Expand Down Expand Up @@ -248,6 +251,26 @@ def del_port(self, 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
Expand Down Expand Up @@ -294,10 +317,13 @@ def update(self, config):
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', {}):
Expand Down
18 changes: 18 additions & 0 deletions smoketest/scripts/cli/test_interfaces_bridge.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,10 @@ def test_add_remove_bridge_member(self):
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'])
Expand Down Expand Up @@ -442,5 +446,19 @@ def test_bridge_tunnel_vxlan_multicast(self):
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)

0 comments on commit d03916b

Please sign in to comment.