summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjack9603301 <jack9603301@163.com>2020-12-10 23:23:44 +0800
committerjack9603301 <jack9603301@163.com>2020-12-13 02:12:45 +0800
commitc4048b2047f693436b38196632cddf65beb67a86 (patch)
tree62a140416830d1c9f72636f3e72680f15279dbb3
parente6e87c839f8dc458dcf2962ea936329e972fbafc (diff)
downloadvyos-1x-c4048b2047f693436b38196632cddf65beb67a86.tar.gz
vyos-1x-c4048b2047f693436b38196632cddf65beb67a86.zip
interfaces: T3114: Fix VLAN-aware bridge setting failure
-rw-r--r--python/vyos/ifconfig/bridge.py37
-rw-r--r--python/vyos/ifconfig/interface.py59
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_bridge.py16
3 files changed, 106 insertions, 6 deletions
diff --git a/python/vyos/ifconfig/bridge.py b/python/vyos/ifconfig/bridge.py
index d0d5da881..959345f2f 100644
--- a/python/vyos/ifconfig/bridge.py
+++ b/python/vyos/ifconfig/bridge.py
@@ -14,6 +14,7 @@
# 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.validate import assert_boolean
@@ -208,6 +209,35 @@ class BridgeIf(Interface):
"""
return self.set_interface('del_port', interface)
+ def get_vlan_ids(self):
+ """
+ Get the VLAN ID of the interface bound to the bridge
+
+ is_trunk is 1 means to obtain the VLAN ID of Trunk mode, otherwise obtain the VLAN ID of Access mode
+
+ Example:
+ >>> from vyos.ifconfig import BridgeIf
+ >>> Interface('br0').get_vlan_id()
+ None
+ """
+ interface = self.config['ifname']
+
+ vlan_ids = []
+
+ bridge_status = cmd('bridge -j vlan show', shell=True)
+ vlan_filter_status = json.loads(bridge_status)
+
+ if vlan_filter_status is not None:
+ for interface_status in vlan_filter_status:
+ ifname = interface_status['ifname']
+ if interface == ifname:
+ vlans_status = interface_status['vlans']
+ for vlan_status in vlans_status:
+ vlan_id = vlan_status['vlan']
+ vlan_ids.append(vlan_id)
+
+ return vlan_ids
+
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
@@ -309,7 +339,7 @@ class BridgeIf(Interface):
cmd = f'bridge vlan del dev {interface} vid 1'
self._cmd(cmd)
vlan_id = interface_config['native_vlan']
- if vlan_id != 1:
+ if int(vlan_id) != 1:
vlan_del.add(1)
cmd = f'bridge vlan add dev {interface} vid {vlan_id} pvid untagged master'
self._cmd(cmd)
@@ -329,16 +359,11 @@ class BridgeIf(Interface):
self._cmd(cmd)
vlan_add.add(vlan)
-
-
-
for vlan in vlan_del:
if isinstance(vlan,str) and vlan.isnumeric():
if int(vlan) == 1:
cmd = f'bridge vlan del dev {ifname} vid {vlan} self'
self._cmd(cmd)
- cmd = f'bridge vlan add dev {ifname} vid {vlan} pvid untagged self'
- self._cmd(cmd)
else:
cmd = f'bridge vlan del dev {ifname} vid {vlan} self'
self._cmd(cmd)
diff --git a/python/vyos/ifconfig/interface.py b/python/vyos/ifconfig/interface.py
index 6e6a83f36..eda3fadd6 100644
--- a/python/vyos/ifconfig/interface.py
+++ b/python/vyos/ifconfig/interface.py
@@ -731,6 +731,7 @@ class Interface(Control):
>>> Interface('eth0').set_proxy_arp_pvlan(1)
"""
self.set_interface('proxy_arp_pvlan', enable)
+
def get_addr(self):
"""
@@ -898,6 +899,64 @@ class Interface(Control):
# set bridge port path priority
if 'priority' in bridge_config:
self.set_path_cost(bridge_config['priority'])
+
+ vlan_filter = 0
+
+ vlan_del = set()
+ vlan_add = set()
+
+ if 'native_vlan' in bridge_config:
+ vlan_filter = 1
+ cmd = f'bridge vlan del dev {self.ifname} vid 1'
+ self._cmd(cmd)
+ vlan_id = bridge_config['native_vlan']
+ if int(vlan_id) != 1:
+ vlan_del.add(1)
+ cmd = f'bridge vlan add dev {self.ifname} vid {vlan_id} pvid untagged master'
+ self._cmd(cmd)
+ vlan_add.add(vlan_id)
+
+ if 'allowed_vlan' in bridge_config:
+ vlan_filter = 1
+
+ if vlan_filter:
+ if 'native_vlan' not in bridge_config:
+ cmd = f'bridge vlan del dev {self.ifname} vid 1'
+ self._cmd(cmd)
+
+ if 'allowed_vlan' in bridge_config:
+ for vlan in bridge_config['allowed_vlan']:
+ cmd = f'bridge vlan add dev {self.ifname} vid {vlan} master'
+ self._cmd(cmd)
+ vlan_add.add(vlan)
+
+ vlan_bridge_ids = Section.klass(bridge)(bridge, create=True).get_vlan_ids()
+
+ # Delete VLAN ID for the bridge
+ for vlan in vlan_del:
+ if int(vlan) == 1:
+ cmd = f'bridge vlan del dev {bridge} vid {vlan} self'
+ self._cmd(cmd)
+
+ # Setting VLAN ID for the bridge
+ for vlan in vlan_add:
+ if isinstance(vlan,str) and vlan.isnumeric():
+ if int(vlan) not in vlan_bridge_ids:
+ cmd = f'bridge vlan add dev {bridge} vid {vlan} self'
+ self._cmd(cmd)
+ elif isinstance(vlan,str) and not vlan.isnumeric():
+ vlan_range = vlan.split('-')
+ for vlan_id in range(int(vlan_range[0]),int(vlan_range[1]) + 1):
+ if int(vlan_id) not in vlan_bridge_ids:
+ cmd = f'bridge vlan add dev {bridge} vid {vlan_id} self'
+ self._cmd(cmd)
+ else:
+ if vlan not in vlan_bridge_ids:
+ cmd = f'bridge vlan add dev {bridge} vid {vlan} self'
+ self._cmd(cmd)
+
+ # enable/disable Vlan Filter
+ Section.klass(bridge)(bridge, create=True).set_vlan_filter(vlan_filter)
def set_dhcp(self, enable):
"""
diff --git a/smoketest/scripts/cli/test_interfaces_bridge.py b/smoketest/scripts/cli/test_interfaces_bridge.py
index 9bddede31..0072a4d3b 100755
--- a/smoketest/scripts/cli/test_interfaces_bridge.py
+++ b/smoketest/scripts/cli/test_interfaces_bridge.py
@@ -45,10 +45,25 @@ class BridgeInterfaceTest(BasicInterfaceTest.BaseTest):
for tmp in Section.interfaces("ethernet"):
if not '.' in tmp:
self._members.append(tmp)
+
+ self.session.set(['interfaces','dummy','dum0'])
+ self.session.set(['interfaces','dummy','dum1'])
+ self.session.commit()
+ self.session.set(['interfaces','bonding','bond1','member','interface','dum0'])
+ self.session.set(['interfaces','bonding','bond1','member','interface','dum1'])
+ self.session.commit()
+ for tmp in Section.interfaces("bonding"):
+ if not '.' in tmp:
+ self._members.append(tmp)
self._options['br0'] = []
for member in self._members:
self._options['br0'].append(f'member interface {member}')
+
+ def tearDown(self):
+ self.session.delete(['interfaces','bonding'])
+ self.session.delete(['interfaces','dummy'])
+ super().tearDown()
def test_add_remove_member(self):
""" Add member interfaces to bridge and set STP cost/priority """
@@ -56,6 +71,7 @@ class BridgeInterfaceTest(BasicInterfaceTest.BaseTest):
base = self._base_path + [interface]
self.session.set(base + ['stp'])
self.session.set(base + ['address', '192.0.2.1/24'])
+ self.session.commit()
cost = 1000
priority = 10