Merge "Add STP option for bridge interfaces"
This commit is contained in:
commit
d52b764a37
@ -359,6 +359,15 @@ The following attributes are supported:
|
||||
``bridge_ports``
|
||||
For bridge interfaces, a list of names of network interfaces to add to the
|
||||
bridge.
|
||||
``bridge_stp``
|
||||
.. note::
|
||||
|
||||
For Rocky Linux 9, the ``bridge_stp`` attribute is set to false to preserve
|
||||
backwards compatibility with network scripts. This is because the Network
|
||||
Manager sets STP to true by default on bridges.
|
||||
|
||||
Enable or disable the Spanning Tree Protocol (STP) on this bridge. Should be
|
||||
set to a boolean value. The default is not set on Ubuntu systems.
|
||||
``bond_mode``
|
||||
For bond interfaces, the bond's mode, e.g. 802.3ad.
|
||||
``bond_ad_select``
|
||||
|
@ -117,6 +117,7 @@ def _bridge_netdev(context, name, inventory_hostname):
|
||||
"""
|
||||
device = networks.net_interface(context, name, inventory_hostname)
|
||||
mtu = networks.net_mtu(context, name, inventory_hostname)
|
||||
stp = networks.net_bridge_stp(context, name, inventory_hostname)
|
||||
config = [
|
||||
{
|
||||
'NetDev': [
|
||||
@ -126,6 +127,8 @@ def _bridge_netdev(context, name, inventory_hostname):
|
||||
]
|
||||
}
|
||||
]
|
||||
if stp is not None:
|
||||
config[0]['Bridge'] = [{'STP': stp}]
|
||||
return _filter_options(config)
|
||||
|
||||
|
||||
|
@ -274,6 +274,30 @@ def net_mtu(context, name, inventory_hostname=None):
|
||||
return mtu
|
||||
|
||||
|
||||
@jinja2.pass_context
|
||||
def net_bridge_stp(context, name, inventory_hostname=None):
|
||||
"""Return the Spanning Tree Protocol (STP) state for a bridge.
|
||||
|
||||
On RL9 if STP is not defined, default it to 'false' to preserve
|
||||
compatibility with network scripts. STP is 'true' in NetworkManager
|
||||
by default, so we set it to 'false' here.
|
||||
|
||||
:param context: Jinja2 Context object.
|
||||
:param name: The name of the network.
|
||||
:param inventory_hostname: Ansible inventory hostname.
|
||||
:returns: A string "true" or "false" representing the STP state.
|
||||
"""
|
||||
bridge_stp = net_attr(context, name, 'bridge_stp', inventory_hostname)
|
||||
os_family = context['ansible_facts']['os_family']
|
||||
if bridge_stp is None:
|
||||
if os_family == 'RedHat':
|
||||
return 'false'
|
||||
else:
|
||||
return None
|
||||
bridge_stp = str(utils.call_bool_filter(context, bridge_stp)).lower()
|
||||
return bridge_stp
|
||||
|
||||
|
||||
net_routes = _make_attr_filter('routes')
|
||||
net_rules = _make_attr_filter('rules')
|
||||
net_physical_network = _make_attr_filter('physical_network')
|
||||
@ -431,6 +455,7 @@ def net_bridge_obj(context, name, inventory_hostname=None):
|
||||
defroute = net_defroute(context, name, inventory_hostname)
|
||||
ethtool_opts = net_ethtool_opts(context, name, inventory_hostname)
|
||||
zone = net_zone(context, name, inventory_hostname)
|
||||
stp = net_bridge_stp(context, name, inventory_hostname)
|
||||
vip_address = net_vip_address(context, name, inventory_hostname)
|
||||
allowed_addresses = [vip_address] if vip_address else None
|
||||
_validate_rules(rules)
|
||||
@ -450,6 +475,7 @@ def net_bridge_obj(context, name, inventory_hostname=None):
|
||||
'zone': zone,
|
||||
'allowed_addresses': allowed_addresses,
|
||||
'onboot': 'yes',
|
||||
'stp': stp,
|
||||
}
|
||||
interface = {k: v for k, v in interface.items() if v is not None}
|
||||
return interface
|
||||
@ -734,6 +760,7 @@ def get_filters():
|
||||
'net_defroute': net_defroute,
|
||||
'net_ethtool_opts': net_ethtool_opts,
|
||||
'net_zone': net_zone,
|
||||
'net_bridge_stp': net_bridge_stp,
|
||||
'net_interface_obj': net_interface_obj,
|
||||
'net_bridge_obj': net_bridge_obj,
|
||||
'net_bond_obj': net_bond_obj,
|
||||
|
@ -65,6 +65,7 @@ class BaseNetworkdTest(unittest.TestCase):
|
||||
# Bandit complains about Jinja2 autoescaping without nosec.
|
||||
self.env = jinja2.Environment() # nosec
|
||||
self.env.filters['bool'] = to_bool
|
||||
self.variables.update({'ansible_facts': {'os_family': 'Debian'}})
|
||||
self.context = self._make_context(self.variables)
|
||||
|
||||
def _make_context(self, parent):
|
||||
@ -202,7 +203,7 @@ class TestNetworkdNetDevs(BaseNetworkdTest):
|
||||
self.assertEqual(expected, devs)
|
||||
|
||||
def test_bridge_all_options(self):
|
||||
self._update_context({"net3_mtu": 1400})
|
||||
self._update_context({"net3_mtu": 1400, "net3_bridge_stp": True})
|
||||
devs = networkd.networkd_netdevs(self.context, ["net3"])
|
||||
expected = {
|
||||
"50-kayobe-br0": [
|
||||
@ -211,6 +212,9 @@ class TestNetworkdNetDevs(BaseNetworkdTest):
|
||||
{"Name": "br0"},
|
||||
{"Kind": "bridge"},
|
||||
{"MTUBytes": 1400},
|
||||
],
|
||||
"Bridge": [
|
||||
{"STP": "true"},
|
||||
]
|
||||
},
|
||||
]
|
||||
|
@ -56,6 +56,7 @@ test_net_eth_vlan_zone: test-zone1
|
||||
test_net_bridge_cidr: 192.168.36.0/24
|
||||
test_net_bridge_interface: br0
|
||||
test_net_bridge_bridge_ports: [dummy3, dummy4]
|
||||
test_net_bridge_bridge_stp: false
|
||||
test_net_bridge_zone: test-zone2
|
||||
|
||||
# br0.43: VLAN subinterface of br0.
|
||||
@ -80,6 +81,7 @@ test_net_bond_vlan_zone: public
|
||||
test_net_bridge_noip_cidr: 192.168.40.0/24
|
||||
test_net_bridge_noip_interface: br1
|
||||
test_net_bridge_noip_bridge_ports: [dummy7]
|
||||
test_net_bridge_noip_bridge_stp: true
|
||||
test_net_bridge_noip_no_ip: true
|
||||
|
||||
{% if ansible_os_family == "Debian" %}
|
||||
|
@ -56,6 +56,8 @@ def test_network_bridge(host):
|
||||
interface = host.interface('br0')
|
||||
assert interface.exists
|
||||
assert '192.168.36.1' in interface.addresses
|
||||
stp_status = host.file('/sys/class/net/br0/bridge/stp_state').content_string.strip()
|
||||
assert '0' == stp_status
|
||||
ports = ['dummy3', 'dummy4']
|
||||
sys_ports = host.check_output('ls -1 /sys/class/net/br0/brif')
|
||||
assert sys_ports == "\n".join(ports)
|
||||
@ -100,6 +102,8 @@ def test_network_bridge_no_ip(host):
|
||||
interface = host.interface('br1')
|
||||
assert interface.exists
|
||||
assert not '192.168.40.1' in interface.addresses
|
||||
stp_status = host.file('/sys/class/net/br1/bridge/stp_state').content_string.strip()
|
||||
assert '1' == stp_status
|
||||
|
||||
|
||||
@pytest.mark.skipif(not _is_apt(),
|
||||
|
@ -0,0 +1,12 @@
|
||||
features:
|
||||
- |
|
||||
The Spanning Tree Protocol (STP) can now be configured on bridge interfaces.
|
||||
Enable or disable STP by setting the ``bridge_stp`` attribute for a network.
|
||||
Note that STP is not set by default on Ubuntu, but it is disabled on Rocky
|
||||
Linux 9 for compatibility with network scripts, as NetworkManager enables
|
||||
STP on all bridges by default.
|
||||
upgrade:
|
||||
- |
|
||||
For Rocky Linux 9, Kayobe now disables STP on a bridge by default. This
|
||||
action will cause the bridge interface to restart during the host
|
||||
configuration process.
|
Loading…
x
Reference in New Issue
Block a user