Page Menu
Home
VyOS Platform
Search
Configure Global Search
Log In
Files
F117520869
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
15 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/interface-definitions/interfaces-bonding.xml.in b/interface-definitions/interfaces-bonding.xml.in
index cf9fb73eb..6c5e2abcc 100644
--- a/interface-definitions/interfaces-bonding.xml.in
+++ b/interface-definitions/interfaces-bonding.xml.in
@@ -1,192 +1,200 @@
<?xml version="1.0"?>
<interfaceDefinition>
<node name="interfaces">
<children>
<tagNode name="bonding" owner="${vyos_conf_scripts_dir}/interfaces-bonding.py">
<properties>
<help>Bonding Interface/Link Aggregation</help>
<priority>320</priority>
<constraint>
<regex>^bond[0-9]+$</regex>
</constraint>
<constraintErrorMessage>Bonding interface must be named bondN</constraintErrorMessage>
<valueHelp>
<format>bondN</format>
<description>Bonding interface name</description>
</valueHelp>
</properties>
<children>
#include <include/interface/address-ipv4-ipv6-dhcp.xml.i>
<node name="arp-monitor">
<properties>
<help>ARP link monitoring parameters</help>
</properties>
<children>
<leafNode name="interval">
<properties>
<help>ARP link monitoring interval</help>
<valueHelp>
<format>u32</format>
<description>Specifies the ARP link monitoring frequency in milliseconds</description>
</valueHelp>
<constraint>
<validator name="numeric" argument="--range 0-4294967295"/>
</constraint>
</properties>
</leafNode>
<leafNode name="target">
<properties>
<help>IP address used for ARP monitoring</help>
<valueHelp>
<format>ipv4</format>
<description>Specify IPv4 address of ARP requests when interval is enabled</description>
</valueHelp>
<constraint>
<validator name="ipv4-address"/>
</constraint>
<multi/>
</properties>
</leafNode>
</children>
</node>
#include <include/interface/interface-description.xml.i>
#include <include/interface/dhcp-options.xml.i>
#include <include/interface/dhcpv6-options.xml.i>
#include <include/interface/interface-disable-link-detect.xml.i>
#include <include/interface/interface-disable.xml.i>
#include <include/interface/interface-vrf.xml.i>
#include <include/interface/interface-mirror.xml.i>
<leafNode name="hash-policy">
<properties>
<help>Bonding transmit hash policy</help>
<completionHelp>
- <list>layer2 layer2+3 layer3+4</list>
+ <list>layer2 layer2+3 layer3+4 encap2+3 encap3+4</list>
</completionHelp>
<valueHelp>
<format>layer2</format>
<description>use MAC addresses to generate the hash (802.3ad, default)</description>
</valueHelp>
<valueHelp>
<format>layer2+3</format>
<description>combine MAC address and IP address to make hash</description>
</valueHelp>
<valueHelp>
<format>layer3+4</format>
<description>combine IP address and port to make hash</description>
</valueHelp>
+ <valueHelp>
+ <format>encap2+3</format>
+ <description>combine encapsulated MAC address and IP address to make hash</description>
+ </valueHelp>
+ <valueHelp>
+ <format>encap3+4</format>
+ <description>combine encapsulated IP address and port to make hash</description>
+ </valueHelp>
<constraint>
- <regex>^(layer2\+3|layer3\+4|layer2)$</regex>
+ <regex>^(layer2\+3|layer3\+4|layer2|encap2\+3|encap3\+4)$</regex>
</constraint>
- <constraintErrorMessage>hash-policy must be layer2 layer2+3 or layer3+4</constraintErrorMessage>
+ <constraintErrorMessage>hash-policy must be layer2 layer2+3 layer3+4 encap2+3 or encap3+4</constraintErrorMessage>
</properties>
<defaultValue>layer2</defaultValue>
</leafNode>
#include <include/interface/interface-ipv4-options.xml.i>
#include <include/interface/interface-ipv6-options.xml.i>
#include <include/interface/interface-mac.xml.i>
<leafNode name="min-links">
<properties>
<help>Minimum number of member interfaces required up before enabling bond</help>
<valueHelp>
<format>u32:0-16</format>
<description>Minimum number of member interfaces required up before enabling bond</description>
</valueHelp>
<constraint>
<validator name="numeric" argument="--range 0-16"/>
</constraint>
</properties>
<defaultValue>0</defaultValue>
</leafNode>
<leafNode name="lacp-rate">
<properties>
<help>Rate in which we will ask our link partner to transmit LACPDU packets</help>
<completionHelp>
<list>slow fast</list>
</completionHelp>
<valueHelp>
<format>slow</format>
<description>Request partner to transmit LACPDUs every 30 seconds (default)</description>
</valueHelp>
<valueHelp>
<format>fast</format>
<description>Request partner to transmit LACPDUs every 1 second</description>
</valueHelp>
<constraint>
<regex>^(slow|fast)$</regex>
</constraint>
</properties>
<defaultValue>slow</defaultValue>
</leafNode>
<leafNode name="mode">
<properties>
<help>Bonding mode</help>
<completionHelp>
<list>802.3ad active-backup broadcast round-robin transmit-load-balance adaptive-load-balance xor-hash</list>
</completionHelp>
<valueHelp>
<format>802.3ad</format>
<description>IEEE 802.3ad Dynamic link aggregation (Default)</description>
</valueHelp>
<valueHelp>
<format>active-backup</format>
<description>Fault tolerant: only one slave in the bond is active</description>
</valueHelp>
<valueHelp>
<format>broadcast</format>
<description>Fault tolerant: transmits everything on all slave interfaces</description>
</valueHelp>
<valueHelp>
<format>round-robin</format>
<description>Load balance: transmit packets in sequential order</description>
</valueHelp>
<valueHelp>
<format>transmit-load-balance</format>
<description>Load balance: adapts based on transmit load and speed</description>
</valueHelp>
<valueHelp>
<format>adaptive-load-balance</format>
<description>Load balance: adapts based on transmit and receive plus ARP</description>
</valueHelp>
<valueHelp>
<format>xor-hash</format>
<description>Distribute based on MAC address</description>
</valueHelp>
<constraint>
<regex>^(802.3ad|active-backup|broadcast|round-robin|transmit-load-balance|adaptive-load-balance|xor-hash)$</regex>
</constraint>
<constraintErrorMessage>mode must be 802.3ad, active-backup, broadcast, round-robin, transmit-load-balance, adaptive-load-balance, or xor</constraintErrorMessage>
</properties>
<defaultValue>802.3ad</defaultValue>
</leafNode>
<node name="member">
<properties>
<help>Bridge member interfaces</help>
</properties>
<children>
<leafNode name="interface">
<properties>
<help>Member interface name</help>
<completionHelp>
<script>${vyos_completion_dir}/list_interfaces.py --bondable</script>
</completionHelp>
<multi/>
</properties>
</leafNode>
</children>
</node>
#include <include/interface/interface-mtu-68-16000.xml.i>
<leafNode name="primary">
<properties>
<help>Primary device interface</help>
<completionHelp>
<script>${vyos_completion_dir}/list_interfaces.py --bondable</script>
</completionHelp>
</properties>
</leafNode>
#include <include/interface/vif-s.xml.i>
#include <include/interface/vif.xml.i>
</children>
</tagNode>
</children>
</node>
</interfaceDefinition>
diff --git a/smoketest/scripts/cli/test_interfaces_bonding.py b/smoketest/scripts/cli/test_interfaces_bonding.py
index 4771eb6b6..880a822a7 100755
--- a/smoketest/scripts/cli/test_interfaces_bonding.py
+++ b/smoketest/scripts/cli/test_interfaces_bonding.py
@@ -1,134 +1,151 @@
#!/usr/bin/env python3
#
# Copyright (C) 2020 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os
import unittest
from base_interfaces_test import BasicInterfaceTest
from vyos.ifconfig import Section
from vyos.ifconfig.interface import Interface
from vyos.configsession import ConfigSessionError
from vyos.util import get_interface_config
from vyos.util import read_file
class BondingInterfaceTest(BasicInterfaceTest.BaseTest):
@classmethod
def setUpClass(cls):
cls._test_ip = True
cls._test_ipv6 = True
cls._test_ipv6_pd = True
cls._test_ipv6_dhcpc6 = True
cls._test_mtu = True
cls._test_vlan = True
cls._test_qinq = True
cls._base_path = ['interfaces', 'bonding']
cls._interfaces = ['bond0']
cls._mirror_interfaces = ['dum21354']
cls._members = []
# we need to filter out VLAN interfaces identified by a dot (.)
# in their name - just in case!
if 'TEST_ETH' in os.environ:
cls._members = os.environ['TEST_ETH'].split()
else:
for tmp in Section.interfaces('ethernet'):
if not '.' in tmp:
cls._members.append(tmp)
cls._options['bond0'] = []
for member in cls._members:
cls._options['bond0'].append(f'member interface {member}')
def test_add_single_ip_address(self):
super().test_add_single_ip_address()
for interface in self._interfaces:
slaves = read_file(f'/sys/class/net/{interface}/bonding/slaves').split()
self.assertListEqual(slaves, self._members)
def test_vif_8021q_interfaces(self):
super().test_vif_8021q_interfaces()
for interface in self._interfaces:
slaves = read_file(f'/sys/class/net/{interface}/bonding/slaves').split()
self.assertListEqual(slaves, self._members)
def test_bonding_remove_member(self):
# T2515: when removing a bond member the previously enslaved/member
# interface must be in its former admin-up/down state. Here we ensure
# that it is admin-up as it was admin-up before.
# configure member interfaces
for interface in self._interfaces:
for option in self._options.get(interface, []):
self.session.set(self._base_path + [interface] + option.split())
self.session.commit()
# remove single bond member port
for interface in self._interfaces:
remove_member = self._members[0]
self.session.delete(self._base_path + [interface, 'member', 'interface', remove_member])
self.session.commit()
# removed member port must be admin-up
for interface in self._interfaces:
remove_member = self._members[0]
state = Interface(remove_member).get_admin_state()
self.assertEqual('up', state)
def test_bonding_min_links(self):
# configure member interfaces
min_links = len(self._interfaces)
for interface in self._interfaces:
for option in self._options.get(interface, []):
self.session.set(self._base_path + [interface] + option.split())
self.session.set(self._base_path + [interface, 'min-links', str(min_links)])
self.session.commit()
# verify config
for interface in self._interfaces:
tmp = get_interface_config(interface)
self.assertEqual(min_links, tmp['linkinfo']['info_data']['min_links'])
# check LACP default rate
self.assertEqual('slow', tmp['linkinfo']['info_data']['ad_lacp_rate'])
def test_bonding_lacp_rate(self):
# configure member interfaces
lacp_rate = 'fast'
for interface in self._interfaces:
for option in self._options.get(interface, []):
self.session.set(self._base_path + [interface] + option.split())
self.session.set(self._base_path + [interface, 'lacp-rate', lacp_rate])
self.session.commit()
# verify config
for interface in self._interfaces:
tmp = get_interface_config(interface)
# check LACP minimum links (default value)
self.assertEqual(0, tmp['linkinfo']['info_data']['min_links'])
self.assertEqual(lacp_rate, tmp['linkinfo']['info_data']['ad_lacp_rate'])
+ def test_bonding_hash_policy(self):
+ # Define available bonding hash policies
+ hash_policies = ['layer2', 'layer2+3', 'layer2+3', 'encap2+3', 'encap3+4']
+ for hash_policy in hash_policies:
+ for interface in self._interfaces:
+ for option in self._options.get(interface, []):
+ self.session.set(self._base_path + [interface] + option.split())
+
+ self.session.set(self._base_path + [interface, 'hash-policy', hash_policy])
+
+ self.session.commit()
+
+ # verify config
+ for interface in self._interfaces:
+ defined_policy = read_file(f'/sys/class/net/{interface}/bonding/xmit_hash_policy').split()
+ self.assertEqual(defined_policy[0], hash_policy)
+
if __name__ == '__main__':
unittest.main(verbosity=2)
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sat, Sep 26, 12:36 PM (1 d, 16 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
4285165
Default Alt Text
(15 KB)
Attached To
Mode
rVYOSONEX vyos-1x
Attached
Detach File
Event Timeline
Log In to Comment