test: Fix bridge MAC address issue on Fedora 31.
With systemd version 242, Fedora 31 will use persistent MAC address for all virtual network interface (including linux bridges). Therefore the bridge will not use the MAC address of the first added port anymore. If you want to let kernel handle the MAC address selection system wide, please change `/usr/lib/systemd/network/99-default.link` to: ``` [Link] NamePolicy=kernel database onboard slot path MACAddressPolicy=none ``` This cause these test cases fail on Fedora 31: * test_linux_bridge_uses_the_port_mac * test_dhcp_on_bridge0 For `test_dhcp_on_bridge0` test, we explicitly set bridge to use the MAC address of the dhcpcli NIC. For `test_linux_bridge_uses_the_port_mac`, we change it into two test cases: * test_linux_bridge_uses_specified_mac_address Explicitly set MAC address and expected to pass on all systems. * test_linux_bridge_uses_the_port_mac_implicitly Do not specify the MAC address of the bridge. Expected to pass on CentOS/RHEL 8 but xfail on Fedora 31+. From nmstate point of view, explicitly setting MAC address in desired state is the preferred way when MAC address of virtual interface matters. Signed-off-by: Gris Ge <fge@redhat.com>
This commit is contained in:
parent
ca6d291218
commit
8cdaaa71c8
@ -39,6 +39,7 @@ from .testlib import cmd as libcmd
|
||||
from .testlib import bondlib
|
||||
from .testlib import ifacelib
|
||||
from .testlib import statelib
|
||||
from .testlib.ifacelib import get_mac_address
|
||||
from .testlib.bridgelib import add_port_to_bridge
|
||||
from .testlib.bridgelib import create_bridge_subtree_state
|
||||
from .testlib.bridgelib import linux_bridge
|
||||
@ -496,6 +497,7 @@ def test_dhcp_on_bridge0(dhcpcli_up_with_dynamic_ip):
|
||||
Interface.IPV6: create_ipv6_state(
|
||||
enabled=True, dhcp=True, autoconf=True
|
||||
),
|
||||
Interface.MAC: get_mac_address(DHCP_CLI_NIC),
|
||||
}
|
||||
bridge_name = TEST_BRIDGE_NIC
|
||||
with linux_bridge(bridge_name, bridge_state, bridge_iface_state) as state:
|
||||
|
@ -16,6 +16,7 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
from contextlib import contextmanager
|
||||
from copy import deepcopy
|
||||
|
||||
import time
|
||||
@ -34,10 +35,12 @@ from .testlib import assertlib
|
||||
from .testlib.bondlib import bond_interface
|
||||
from .testlib.bridgelib import add_port_to_bridge
|
||||
from .testlib.bridgelib import linux_bridge
|
||||
from .testlib.ifacelib import get_mac_address
|
||||
from .testlib.iproutelib import ip_monitor_assert_stable_link_up
|
||||
from .testlib.statelib import show_only
|
||||
from .testlib.assertlib import assert_mac_address
|
||||
from .testlib.vlan import vlan_interface
|
||||
from .testlib.env import is_fedora
|
||||
|
||||
TEST_BRIDGE0 = 'linux-br0'
|
||||
|
||||
@ -64,6 +67,18 @@ stp-priority: 32
|
||||
|
||||
@pytest.fixture
|
||||
def bridge0_with_port0(port0_up):
|
||||
with _bridge0_with_port0(port0_up) as state:
|
||||
yield state
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def bridge0_with_port0_with_explicit_port_mac(port0_up):
|
||||
with _bridge0_with_port0(port0_up, use_port_mac=True) as state:
|
||||
yield state
|
||||
|
||||
|
||||
@contextmanager
|
||||
def _bridge0_with_port0(port0_up, use_port_mac=False):
|
||||
bridge_name = TEST_BRIDGE0
|
||||
port_name = port0_up[Interface.KEY][0][Interface.NAME]
|
||||
bridge_state = _create_bridge_subtree_config((port_name,))
|
||||
@ -71,7 +86,14 @@ def bridge0_with_port0(port0_up):
|
||||
options_subtree = bridge_state[LinuxBridge.OPTIONS_SUBTREE]
|
||||
options_subtree[LinuxBridge.STP_SUBTREE][LinuxBridge.STP_ENABLED] = False
|
||||
|
||||
with linux_bridge(bridge_name, bridge_state) as desired_state:
|
||||
extra_iface_state = None
|
||||
|
||||
if use_port_mac:
|
||||
extra_iface_state = {Interface.MAC: get_mac_address(port_name)}
|
||||
|
||||
with linux_bridge(
|
||||
bridge_name, bridge_state, extra_iface_state
|
||||
) as desired_state:
|
||||
# Need to set twice so the wired setting will be explicitly set,
|
||||
# allowing reapply to succeed.
|
||||
# https://bugzilla.redhat.com/1703960
|
||||
@ -189,7 +211,29 @@ def test_add_port_to_existing_bridge(bridge0_with_port0, port1_up):
|
||||
assertlib.assert_state(desired_state)
|
||||
|
||||
|
||||
def test_linux_bridge_uses_the_port_mac(port0_up, bridge0_with_port0):
|
||||
@pytest.mark.xfail(
|
||||
is_fedora(),
|
||||
reason=(
|
||||
'On Fedora 31+, users need to explicitly configure the port MAC '
|
||||
'due to changes to the default systemd config.'
|
||||
),
|
||||
raises=AssertionError,
|
||||
strict=True,
|
||||
)
|
||||
def test_linux_bridge_uses_the_port_mac_implicitly(
|
||||
port0_up, bridge0_with_port0
|
||||
):
|
||||
print(bridge0_with_port0)
|
||||
port0_name = port0_up[Interface.KEY][0][Interface.NAME]
|
||||
current_state = show_only((TEST_BRIDGE0, port0_name))
|
||||
assert_mac_address(
|
||||
current_state, port0_up[Interface.KEY][0][Interface.MAC]
|
||||
)
|
||||
|
||||
|
||||
def test_linux_bridge_uses_specified_mac_address(
|
||||
port0_up, bridge0_with_port0_with_explicit_port_mac
|
||||
):
|
||||
port0_name = port0_up[Interface.KEY][0][Interface.NAME]
|
||||
current_state = show_only((TEST_BRIDGE0, port0_name))
|
||||
assert_mac_address(
|
||||
|
24
tests/integration/testlib/env.py
Normal file
24
tests/integration/testlib/env.py
Normal file
@ -0,0 +1,24 @@
|
||||
#
|
||||
# Copyright (c) 2019 Red Hat, Inc.
|
||||
#
|
||||
# This file is part of nmstate
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 2.1 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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 Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
import os
|
||||
|
||||
|
||||
def is_fedora():
|
||||
return os.path.exists('/etc/fedora-release')
|
@ -54,3 +54,8 @@ def _set_eth_admin_state(ifname, state):
|
||||
]
|
||||
}
|
||||
libnmstate.apply(desired_state)
|
||||
|
||||
|
||||
def get_mac_address(ifname):
|
||||
state = statelib.show_only((ifname,))
|
||||
return state[schema.Interface.KEY][0].get(schema.Interface.MAC)
|
||||
|
Loading…
x
Reference in New Issue
Block a user