diff options
| author | Christian Breunig <christian@breunig.cc> | 2025-08-11 20:25:24 +0200 |
|---|---|---|
| committer | Christian Breunig <christian@breunig.cc> | 2025-08-11 20:25:24 +0200 |
| commit | 6ebb8cd26962b9840a912d5fb0ab2d891f7b00e2 (patch) | |
| tree | f7a6c03ad5e2172c2aa514213d172685b04bd418 /smoketest/scripts/cli | |
| parent | 6fa4978e8bd57b3e50357a87eee4d884aba431ef (diff) | |
| download | vyos-1x-6ebb8cd26962b9840a912d5fb0ab2d891f7b00e2.tar.gz vyos-1x-6ebb8cd26962b9840a912d5fb0ab2d891f7b00e2.zip | |
bond: T7571: fix inconsistent MAC address behaviour
After upgrading from VyOS 1.3 to 1.4, there is an inconsistent behavior with
MAC address assignment on bonded interfaces. In VyOS 1.3, bond interfaces used
a hardware MAC address from one of the member interfaces. In 1.4, a synthetic
MAC is used by default - generated by the Linux Kernel.
Oddly, setting mode 802.3ad (which is also the default) temporarily causes the
hardware MAC to be used again - until a reboot, after which the synthetic MAC
returns.
Deleting the mode config again causes the hardware MAC to be used. This
inconsistent behavior has caused issues with MAC-based filtering in networks.
The fix is to retrive the hardware MAC address from the first bond member
interface and use set it explicitly for the bond interface.
Diffstat (limited to 'smoketest/scripts/cli')
| -rwxr-xr-x | smoketest/scripts/cli/test_interfaces_bonding.py | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/smoketest/scripts/cli/test_interfaces_bonding.py b/smoketest/scripts/cli/test_interfaces_bonding.py index 2473bc732..57d245ae6 100755 --- a/smoketest/scripts/cli/test_interfaces_bonding.py +++ b/smoketest/scripts/cli/test_interfaces_bonding.py @@ -62,6 +62,23 @@ class BondingInterfaceTest(BasicInterfaceTest.TestCase): slaves = read_file(f'/sys/class/net/{interface}/bonding/slaves').split() self.assertListEqual(slaves, self._members) + def test_bonding_keep_mac(self): + # T7571: A bond interface should always run from the physical interfaces + # MAC address and not a synthetic one. + base_mac = Interface(self._members[0]).get_mac() + + # configure member interfaces + 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 bond interface MAC address matches the address of it's first member + for interface in self._interfaces: + mac = Interface(interface).get_mac() + self.assertEqual(mac, base_mac) + 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 |
