Ubuntu systemd-networkd: VLAN ifname heuristics
Add a regular expression match to verify that VLAN interfaces are named like VLAN interfaces, enabling non-VLAN interfaces to exist on a network where the VLAN ID is defined. Co-Authored-By: Mark Goddard <mark@stackhpc.com> Story: 2009270 Task: 43511 Change-Id: If09c4840bbe51168a8b94be0db85e6610c21aa82
This commit is contained in:
parent
b8abf706d4
commit
1b647acaf6
@ -488,8 +488,9 @@ def _add_to_result(result, prefix, device, config):
|
||||
# This should not happen.
|
||||
if key in result:
|
||||
raise errors.AnsibleFilterError(
|
||||
"Programming error: duplicate interface configuration for %s"
|
||||
% device)
|
||||
"Programming error: duplicate interface configuration for %s: "
|
||||
"have %s"
|
||||
% (device, result))
|
||||
result[key] = config
|
||||
|
||||
|
||||
@ -511,7 +512,8 @@ def networkd_netdevs(context, names, inventory_hostname=None):
|
||||
result = {}
|
||||
|
||||
# VLANs.
|
||||
for name in networks.net_select_vlans(context, names, inventory_hostname):
|
||||
for name in networks.net_select_vlan_interfaces(context, names,
|
||||
inventory_hostname):
|
||||
device = networks.get_and_validate_interface(context, name,
|
||||
inventory_hostname)
|
||||
netdev = _vlan_netdev(context, name, inventory_hostname)
|
||||
|
@ -535,6 +535,14 @@ def net_is_vlan(context, name, inventory_hostname=None):
|
||||
return net_vlan(context, name) is not None
|
||||
|
||||
|
||||
@jinja2.contextfilter
|
||||
def net_is_vlan_interface(context, name, inventory_hostname=None):
|
||||
device = get_and_validate_interface(context, name, inventory_hostname)
|
||||
# Use a heuristic to match conventional VLAN names, ending with a
|
||||
# period and a numerical extension to an interface name
|
||||
return re.match(r"^[a-zA-Z0-9_\-]+\.[1-9][\d]{0,3}$", device)
|
||||
|
||||
|
||||
@jinja2.contextfilter
|
||||
def net_select_ethers(context, names, inventory_hostname=None):
|
||||
return [name for name in names
|
||||
@ -559,6 +567,12 @@ def net_select_vlans(context, names, inventory_hostname=None):
|
||||
if net_is_vlan(context, name, inventory_hostname)]
|
||||
|
||||
|
||||
@jinja2.contextfilter
|
||||
def net_select_vlan_interfaces(context, names, inventory_hostname=None):
|
||||
return [name for name in names
|
||||
if net_is_vlan_interface(context, name, inventory_hostname)]
|
||||
|
||||
|
||||
@jinja2.contextfilter
|
||||
def net_reject_vlans(context, names, inventory_hostname=None):
|
||||
return [name for name in names
|
||||
|
@ -74,6 +74,19 @@ class TestNetworkdNetDevs(BaseNetworkdTest):
|
||||
devs = networkd.networkd_netdevs(self.context, [])
|
||||
self.assertEqual({}, devs)
|
||||
|
||||
def test_eth(self):
|
||||
devs = networkd.networkd_netdevs(self.context, ["net1"])
|
||||
expected = {}
|
||||
self.assertEqual(expected, devs)
|
||||
|
||||
def test_eth_untagged_vlan(self):
|
||||
# An untagged interface on a network with a VLAN defined should not
|
||||
# create a VLAN subinterface.
|
||||
self._update_context({"net1_vlan": 42})
|
||||
devs = networkd.networkd_netdevs(self.context, ["net1"])
|
||||
expected = {}
|
||||
self.assertEqual(expected, devs)
|
||||
|
||||
def test_vlan(self):
|
||||
devs = networkd.networkd_netdevs(self.context, ["net2"])
|
||||
expected = {
|
||||
@ -154,6 +167,23 @@ class TestNetworkdNetDevs(BaseNetworkdTest):
|
||||
self.assertRaises(errors.AnsibleFilterError,
|
||||
networkd.networkd_netdevs, self.context, ["net3"])
|
||||
|
||||
def test_bridge_untagged_vlan(self):
|
||||
# A bridge on a network with a VLAN defined should not create a VLAN
|
||||
# subinterface.
|
||||
self._update_context({"net3_vlan": 42})
|
||||
devs = networkd.networkd_netdevs(self.context, ["net3"])
|
||||
expected = {
|
||||
"50-kayobe-br0": [
|
||||
{
|
||||
"NetDev": [
|
||||
{"Name": "br0"},
|
||||
{"Kind": "bridge"},
|
||||
]
|
||||
},
|
||||
]
|
||||
}
|
||||
self.assertEqual(expected, devs)
|
||||
|
||||
def test_bond(self):
|
||||
devs = networkd.networkd_netdevs(self.context, ["net4"])
|
||||
expected = {
|
||||
@ -207,6 +237,23 @@ class TestNetworkdNetDevs(BaseNetworkdTest):
|
||||
self.assertRaises(errors.AnsibleFilterError,
|
||||
networkd.networkd_netdevs, self.context, ["net4"])
|
||||
|
||||
def test_bond_untagged_vlan(self):
|
||||
# A bridge on a network with a VLAN defined should not create a VLAN
|
||||
# subinterface.
|
||||
self._update_context({"net4_vlan": 42})
|
||||
devs = networkd.networkd_netdevs(self.context, ["net4"])
|
||||
expected = {
|
||||
"50-kayobe-bond0": [
|
||||
{
|
||||
"NetDev": [
|
||||
{"Name": "bond0"},
|
||||
{"Kind": "bond"},
|
||||
]
|
||||
},
|
||||
]
|
||||
}
|
||||
self.assertEqual(expected, devs)
|
||||
|
||||
def test_veth(self):
|
||||
self._update_context({"external_net_names": ["net3"]})
|
||||
devs = networkd.networkd_netdevs(self.context, ["net3"])
|
||||
|
@ -0,0 +1,5 @@
|
||||
---
|
||||
fixes:
|
||||
- |
|
||||
Fixes an issue with ``systemd-networkd`` configuration for VLAN interfaces
|
||||
when the interface is untagged.
|
Loading…
x
Reference in New Issue
Block a user