From 3907233b51e721ea894f383b51e42118a2012d78 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Sun, 10 Jul 2022 22:27:29 +0200 Subject: smoketest: bond: add testcase for source-interface re-use A bond member is not allowed to also be used as a source interface for e.g. PPPoE or MACsec. (cherry picked from commit 6fca4854aa2e950795ff0411abe4601f86bdeac0) --- smoketest/scripts/cli/test_interfaces_bonding.py | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) (limited to 'smoketest/scripts/cli') diff --git a/smoketest/scripts/cli/test_interfaces_bonding.py b/smoketest/scripts/cli/test_interfaces_bonding.py index 9bb561275..a6e5ea59c 100755 --- a/smoketest/scripts/cli/test_interfaces_bonding.py +++ b/smoketest/scripts/cli/test_interfaces_bonding.py @@ -49,7 +49,7 @@ class BondingInterfaceTest(BasicInterfaceTest.TestCase): if not '.' in tmp: cls._members.append(tmp) - cls._options['bond0'] = [] + cls._options = {'bond0' : []} for member in cls._members: cls._options['bond0'].append(f'member interface {member}') cls._interfaces = list(cls._options) @@ -165,6 +165,26 @@ class BondingInterfaceTest(BasicInterfaceTest.TestCase): self.cli_commit() + def test_bonding_source_interface(self): + # Re-use member interface that is already a source-interface + bond = 'bond99' + pppoe = 'pppoe98756' + member = next(iter(self._members)) + + self.cli_set(self._base_path + [bond, 'member', 'interface', member]) + self.cli_set(['interfaces', 'pppoe', pppoe, 'source-interface', member]) + + # check validate() - can not add interface to bond, it is the source-interface of ... + with self.assertRaises(ConfigSessionError): + self.cli_commit() + + self.cli_delete(['interfaces', 'pppoe', pppoe]) + self.cli_commit() + + # verify config + slaves = read_file(f'/sys/class/net/{bond}/bonding/slaves').split() + self.assertIn(member, slaves) + def test_bonding_uniq_member_description(self): ethernet_path = ['interfaces', 'ethernet'] for interface in self._interfaces: -- cgit v1.2.3 From d88912616a7d1fe221069773a1102e17880739ed Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Sun, 10 Jul 2022 22:28:12 +0200 Subject: smoketest: bond: add testcase for conflicting bridge member A bond member can not also be used as a member of a bridge interface. (cherry picked from commit 19bfed0abd75adacb61f170606fff8b4d2e7713f) --- smoketest/scripts/cli/test_interfaces_bonding.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'smoketest/scripts/cli') diff --git a/smoketest/scripts/cli/test_interfaces_bonding.py b/smoketest/scripts/cli/test_interfaces_bonding.py index a6e5ea59c..af70c004b 100755 --- a/smoketest/scripts/cli/test_interfaces_bonding.py +++ b/smoketest/scripts/cli/test_interfaces_bonding.py @@ -185,6 +185,26 @@ class BondingInterfaceTest(BasicInterfaceTest.TestCase): slaves = read_file(f'/sys/class/net/{bond}/bonding/slaves').split() self.assertIn(member, slaves) + def test_bonding_source_bridge_interface(self): + # Re-use member interface that is already a source-interface + bond = 'bond1097' + bridge = 'br6327' + member = next(iter(self._members)) + + self.cli_set(self._base_path + [bond, 'member', 'interface', member]) + self.cli_set(['interfaces', 'bridge', bridge, 'member', 'interface', member]) + + # check validate() - can not add interface to bond, it is a member of bridge ... + with self.assertRaises(ConfigSessionError): + self.cli_commit() + + self.cli_delete(['interfaces', 'bridge', bridge]) + self.cli_commit() + + # verify config + slaves = read_file(f'/sys/class/net/{bond}/bonding/slaves').split() + self.assertIn(member, slaves) + def test_bonding_uniq_member_description(self): ethernet_path = ['interfaces', 'ethernet'] for interface in self._interfaces: -- cgit v1.2.3 From d5ed752207bbb016df40fb0fe18c27bb428c446c Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Sun, 10 Jul 2022 23:09:52 +0200 Subject: smoketest: bond: remove second instance of layer2+3 hash-policy test (cherry picked from commit 8d1bb953b784d03e02ba26e78da5488a79aaf20d) --- smoketest/scripts/cli/test_interfaces_bonding.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'smoketest/scripts/cli') diff --git a/smoketest/scripts/cli/test_interfaces_bonding.py b/smoketest/scripts/cli/test_interfaces_bonding.py index af70c004b..c0ed916f3 100755 --- a/smoketest/scripts/cli/test_interfaces_bonding.py +++ b/smoketest/scripts/cli/test_interfaces_bonding.py @@ -136,7 +136,7 @@ class BondingInterfaceTest(BasicInterfaceTest.TestCase): def test_bonding_hash_policy(self): # Define available bonding hash policies - hash_policies = ['layer2', 'layer2+3', 'layer2+3', 'encap2+3', 'encap3+4'] + hash_policies = ['layer2', 'layer2+3', 'encap2+3', 'encap3+4'] for hash_policy in hash_policies: for interface in self._interfaces: for option in self._options.get(interface, []): -- cgit v1.2.3 From 57d54b249ff04f70177b31fae0c10ac6677148ee Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Sun, 10 Jul 2022 23:01:09 +0200 Subject: bond: T4522: add ability to specify mii monitor interval via CLI Linux Kernel supports to specify the MII link monitoring frequency in milliseconds. This determines how often the link state of each slave is inspected for link failures. A value of zero disables MII link monitoring. A value of 100 is a good starting point. The default value is 100. set interfaces bonding bond0 mii-mon-interval (cherry picked from commit 4315c8fa5bb090e2b7edd6bda205041623e2511d) --- interface-definitions/interfaces-bonding.xml.in | 17 +++++++++++++++++ python/vyos/ifconfig/bond.py | 3 ++- smoketest/scripts/cli/test_interfaces_bonding.py | 23 +++++++++++++++++++++++ 3 files changed, 42 insertions(+), 1 deletion(-) (limited to 'smoketest/scripts/cli') diff --git a/interface-definitions/interfaces-bonding.xml.in b/interface-definitions/interfaces-bonding.xml.in index 5a4f08bef..307dd7558 100644 --- a/interface-definitions/interfaces-bonding.xml.in +++ b/interface-definitions/interfaces-bonding.xml.in @@ -92,6 +92,23 @@ #include #include #include + + + Specifies the MII link monitoring frequency in milliseconds + + u32:0 + Disable MII link monitoring + + + u32:50-1000 + MII link monitoring frequency in milliseconds + + + + + + 100 + Minimum number of member interfaces required up before enabling bond diff --git a/python/vyos/ifconfig/bond.py b/python/vyos/ifconfig/bond.py index 54e47f18a..47e0598ab 100644 --- a/python/vyos/ifconfig/bond.py +++ b/python/vyos/ifconfig/bond.py @@ -372,7 +372,8 @@ class BondIf(Interface): self.set_admin_state('down') # Specifies the MII link monitoring frequency in milliseconds - self.set_miimon_interval('250') + value = config.get('mii_mon_interval') + self.set_miimon_interval(value) # Bonding transmit hash policy value = config.get('hash_policy') diff --git a/smoketest/scripts/cli/test_interfaces_bonding.py b/smoketest/scripts/cli/test_interfaces_bonding.py index c0ed916f3..ab75cdcc9 100755 --- a/smoketest/scripts/cli/test_interfaces_bonding.py +++ b/smoketest/scripts/cli/test_interfaces_bonding.py @@ -151,6 +151,29 @@ class BondingInterfaceTest(BasicInterfaceTest.TestCase): defined_policy = read_file(f'/sys/class/net/{interface}/bonding/xmit_hash_policy').split() self.assertEqual(defined_policy[0], hash_policy) + def test_bonding_mii_monitoring_interval(self): + for interface in self._interfaces: + for option in self._options.get(interface, []): + self.cli_set(self._base_path + [interface] + option.split()) + + self.cli_commit() + + # verify default + for interface in self._interfaces: + tmp = read_file(f'/sys/class/net/{interface}/bonding/miimon').split() + self.assertIn('100', tmp) + + mii_mon = '250' + for interface in self._interfaces: + self.cli_set(self._base_path + [interface, 'mii-mon-interval', mii_mon]) + + self.cli_commit() + + # verify new CLI value + for interface in self._interfaces: + tmp = read_file(f'/sys/class/net/{interface}/bonding/miimon').split() + self.assertIn(mii_mon, tmp) + def test_bonding_multi_use_member(self): # Define available bonding hash policies for interface in ['bond10', 'bond20']: -- cgit v1.2.3 From 51455fc033cd41e1a105800b2a901e4a32df6058 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Mon, 11 Jul 2022 08:13:02 +0200 Subject: smoketest: bridge: also test QinQ bridge member interfaces (cherry picked from commit 74d6a7e4fc9e2e929c5f899070e6fc3e3e3b5ceb) --- smoketest/scripts/cli/test_interfaces_bridge.py | 31 ++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) (limited to 'smoketest/scripts/cli') diff --git a/smoketest/scripts/cli/test_interfaces_bridge.py b/smoketest/scripts/cli/test_interfaces_bridge.py index 09441326a..b4b91f226 100755 --- a/smoketest/scripts/cli/test_interfaces_bridge.py +++ b/smoketest/scripts/cli/test_interfaces_bridge.py @@ -224,7 +224,7 @@ class BridgeInterfaceTest(BasicInterfaceTest.TestCase): self.cli_delete(self._base_path + [interface, 'member']) - def test_bridge_vlan_members(self): + def test_bridge_vif_members(self): # T2945: ensure that VIFs are not dropped from bridge vifs = ['300', '400'] for interface in self._interfaces: @@ -249,5 +249,34 @@ class BridgeInterfaceTest(BasicInterfaceTest.TestCase): self.cli_delete(['interfaces', 'ethernet', member, 'vif', vif]) self.cli_delete(['interfaces', 'bridge', interface, 'member', 'interface', f'{member}.{vif}']) + def test_bridge_vif_s_vif_c_members(self): + # T2945: ensure that VIFs are not dropped from bridge + vifs = ['300', '400'] + vifc = ['301', '401'] + for interface in self._interfaces: + for member in self._members: + for vif_s in vifs: + for vif_c in vifc: + self.cli_set(['interfaces', 'ethernet', member, 'vif-s', vif_s, 'vif-c', vif_c]) + self.cli_set(['interfaces', 'bridge', interface, 'member', 'interface', f'{member}.{vif_s}.{vif_c}']) + + self.cli_commit() + + # Verify config + for interface in self._interfaces: + for member in self._members: + for vif_s in vifs: + for vif_c in vifc: + # member interface must be assigned to the bridge + self.assertTrue(os.path.exists(f'/sys/class/net/{interface}/lower_{member}.{vif_s}.{vif_c}')) + + # delete all members + for interface in self._interfaces: + for member in self._members: + for vif_s in vifs: + self.cli_delete(['interfaces', 'ethernet', member, 'vif-s', vif_s]) + for vif_c in vifc: + self.cli_delete(['interfaces', 'bridge', interface, 'member', 'interface', f'{member}.{vif_s}.{vif_c}']) + if __name__ == '__main__': unittest.main(verbosity=2) -- cgit v1.2.3