summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Poessinger <christian@poessinger.com>2020-10-01 21:30:23 +0200
committerChristian Poessinger <christian@poessinger.com>2020-10-01 21:30:23 +0200
commit4cfb3515475d95313ad1840978ee09704bd6351a (patch)
tree418c2fddcef56583a66e993ed5efd64efe3e4c69
parenta91b9e6805c61c58cdca83ffa7a47182831d8652 (diff)
downloadvyos-1x-4cfb3515475d95313ad1840978ee09704bd6351a.tar.gz
vyos-1x-4cfb3515475d95313ad1840978ee09704bd6351a.zip
vlan: configdict: T2945: determine if vlan is part of bridge
Every interface knows if it is part of a bridge or not - except a VLAN (VIF) interface. Also VLANs should be aware of its master bridge. Add a testcase to ensure when VIFs on an interface change the bridge does not loos one of it's members.
-rw-r--r--python/vyos/configdict.py13
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_bridge.py37
2 files changed, 50 insertions, 0 deletions
diff --git a/python/vyos/configdict.py b/python/vyos/configdict.py
index 660d779d4..ce6d58693 100644
--- a/python/vyos/configdict.py
+++ b/python/vyos/configdict.py
@@ -360,6 +360,10 @@ def get_interface_dict(config, base, ifname=''):
# XXX: T2665: blend in proper DHCPv6-PD default values
dict['vif'][vif] = T2665_set_dhcpv6pd_defaults(dict['vif'][vif])
+ # Check if we are a member of a bridge device
+ bridge = is_member(config, f'{ifname}.{vif}', 'bridge')
+ if bridge: dict['vif'][vif].update({'is_bridge_member' : bridge})
+
for vif_s, vif_s_config in dict.get('vif_s', {}).items():
default_vif_s_values = defaults(base + ['vif-s'])
# XXX: T2665: we only wan't the vif-s defaults - do not care about vif-c
@@ -375,6 +379,10 @@ def get_interface_dict(config, base, ifname=''):
dict['vif_s'][vif_s] = T2665_set_dhcpv6pd_defaults(
dict['vif_s'][vif_s])
+ # Check if we are a member of a bridge device
+ bridge = is_member(config, f'{ifname}.{vif_s}', 'bridge')
+ if bridge: dict['vif_s'][vif_s].update({'is_bridge_member' : bridge})
+
for vif_c, vif_c_config in vif_s_config.get('vif_c', {}).items():
default_vif_c_values = defaults(base + ['vif-s', 'vif-c'])
@@ -389,6 +397,11 @@ def get_interface_dict(config, base, ifname=''):
dict['vif_s'][vif_s]['vif_c'][vif_c] = T2665_set_dhcpv6pd_defaults(
dict['vif_s'][vif_s]['vif_c'][vif_c])
+ # Check if we are a member of a bridge device
+ bridge = is_member(config, f'{ifname}.{vif_s}.{vif_c}', 'bridge')
+ if bridge: dict['vif_s'][vif_s]['vif_c'][vif_c].update(
+ {'is_bridge_member' : bridge})
+
# Check vif, vif-s/vif-c VLAN interfaces for removal
dict = get_removed_vlans(config, dict)
return dict
diff --git a/smoketest/scripts/cli/test_interfaces_bridge.py b/smoketest/scripts/cli/test_interfaces_bridge.py
index bc0bb69c6..a1359680b 100755
--- a/smoketest/scripts/cli/test_interfaces_bridge.py
+++ b/smoketest/scripts/cli/test_interfaces_bridge.py
@@ -18,6 +18,8 @@ import os
import unittest
from base_interfaces_test import BasicInterfaceTest
+from glob import glob
+from netifaces import interfaces
from vyos.ifconfig import Section
class BridgeInterfaceTest(BasicInterfaceTest.BaseTest):
@@ -44,6 +46,7 @@ class BridgeInterfaceTest(BasicInterfaceTest.BaseTest):
self._options['br0'].append(f'member interface {member}')
def test_add_remove_member(self):
+ """ Add member interfaces to bridge and set STP cost/priority """
for interface in self._interfaces:
base = self._base_path + [interface]
self.session.set(base + ['stp'])
@@ -59,12 +62,46 @@ class BridgeInterfaceTest(BasicInterfaceTest.BaseTest):
cost += 1
priority += 1
+ # commit config
self.session.commit()
+ # check member interfaces are added on the bridge
+ bridge_members = []
+ for tmp in glob(f'/sys/class/net/{interface}/lower_*'):
+ bridge_members.append(os.path.basename(tmp).replace('lower_', ''))
+
+ for member in self._members:
+ self.assertIn(member, bridge_members)
+
+ # delete all members
for interface in self._interfaces:
self.session.delete(self._base_path + [interface, 'member'])
self.session.commit()
+ def test_vlan_members(self):
+ """ T2945: ensure that VIFs are not dropped from bridge """
+
+ self.session.set(['interfaces', 'ethernet', 'eth0', 'vif', '300'])
+ self.session.set(['interfaces', 'bridge', 'br0', 'member', 'interface', 'eth0.300'])
+ self.session.commit()
+
+ # member interface must be assigned to the bridge
+ self.assertTrue(os.path.exists('/sys/class/net/br0/lower_eth0.300'))
+
+ # add second bridge member
+ self.session.set(['interfaces', 'ethernet', 'eth0', 'vif', '400'])
+ self.session.commit()
+
+ # member interface must still be assigned to the bridge
+ self.assertTrue(os.path.exists('/sys/class/net/br0/lower_eth0.300'))
+
+ # remove VLAN interfaces
+ self.session.delete(['interfaces', 'ethernet', 'eth0', 'vif', '300'])
+ self.session.delete(['interfaces', 'ethernet', 'eth0', 'vif', '400'])
+ self.session.commit()
+
+
if __name__ == '__main__':
unittest.main()
+