Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bridge: T6125: support 802.1ad (ethertype 0x88a8) VLAN filtering #3158

Merged
merged 1 commit into from
Mar 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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)