summaryrefslogtreecommitdiff
path: root/cloudinit
diff options
context:
space:
mode:
authorAnh Vo <anhvo@microsoft.com>2020-10-13 15:42:54 -0400
committerGitHub <noreply@github.com>2020-10-13 15:42:54 -0400
commit8ec8c3fc63a59b85888a0b52356b784314a1d4cc (patch)
tree51006af28392ee2f1cad61e2887e1d6851d8f8d5 /cloudinit
parent5bf287f430b97860bf746e61b83ff53b834592d0 (diff)
downloadcloud-init-git-8ec8c3fc63a59b85888a0b52356b784314a1d4cc.tar.gz
net: add the ability to blacklist network interfaces based on driver during enumeration of physical network devices (#591)
Diffstat (limited to 'cloudinit')
-rw-r--r--cloudinit/distros/networking.py6
-rw-r--r--cloudinit/net/__init__.py35
-rwxr-xr-xcloudinit/sources/DataSourceAzure.py36
3 files changed, 51 insertions, 26 deletions
diff --git a/cloudinit/distros/networking.py b/cloudinit/distros/networking.py
index 10ed249d..e407fa29 100644
--- a/cloudinit/distros/networking.py
+++ b/cloudinit/distros/networking.py
@@ -22,6 +22,9 @@ class Networking(metaclass=abc.ABCMeta):
Hierarchy" in HACKING.rst for full details.
"""
+ def __init__(self):
+ self.blacklist_drivers = None
+
def _get_current_rename_info(self) -> dict:
return net._get_current_rename_info()
@@ -68,7 +71,8 @@ class Networking(metaclass=abc.ABCMeta):
return net.get_interfaces()
def get_interfaces_by_mac(self) -> dict:
- return net.get_interfaces_by_mac()
+ return net.get_interfaces_by_mac(
+ blacklist_drivers=self.blacklist_drivers)
def get_master(self, devname: DeviceName):
return net.get_master(devname)
diff --git a/cloudinit/net/__init__.py b/cloudinit/net/__init__.py
index e233149a..75e79ca8 100644
--- a/cloudinit/net/__init__.py
+++ b/cloudinit/net/__init__.py
@@ -746,18 +746,22 @@ def get_ib_interface_hwaddr(ifname, ethernet_format):
return mac
-def get_interfaces_by_mac():
+def get_interfaces_by_mac(blacklist_drivers=None) -> dict:
if util.is_FreeBSD():
- return get_interfaces_by_mac_on_freebsd()
+ return get_interfaces_by_mac_on_freebsd(
+ blacklist_drivers=blacklist_drivers)
elif util.is_NetBSD():
- return get_interfaces_by_mac_on_netbsd()
+ return get_interfaces_by_mac_on_netbsd(
+ blacklist_drivers=blacklist_drivers)
elif util.is_OpenBSD():
- return get_interfaces_by_mac_on_openbsd()
+ return get_interfaces_by_mac_on_openbsd(
+ blacklist_drivers=blacklist_drivers)
else:
- return get_interfaces_by_mac_on_linux()
+ return get_interfaces_by_mac_on_linux(
+ blacklist_drivers=blacklist_drivers)
-def get_interfaces_by_mac_on_freebsd():
+def get_interfaces_by_mac_on_freebsd(blacklist_drivers=None) -> dict():
(out, _) = subp.subp(['ifconfig', '-a', 'ether'])
# flatten each interface block in a single line
@@ -784,7 +788,7 @@ def get_interfaces_by_mac_on_freebsd():
return results
-def get_interfaces_by_mac_on_netbsd():
+def get_interfaces_by_mac_on_netbsd(blacklist_drivers=None) -> dict():
ret = {}
re_field_match = (
r"(?P<ifname>\w+).*address:\s"
@@ -800,7 +804,7 @@ def get_interfaces_by_mac_on_netbsd():
return ret
-def get_interfaces_by_mac_on_openbsd():
+def get_interfaces_by_mac_on_openbsd(blacklist_drivers=None) -> dict():
ret = {}
re_field_match = (
r"(?P<ifname>\w+).*lladdr\s"
@@ -815,12 +819,13 @@ def get_interfaces_by_mac_on_openbsd():
return ret
-def get_interfaces_by_mac_on_linux():
+def get_interfaces_by_mac_on_linux(blacklist_drivers=None) -> dict:
"""Build a dictionary of tuples {mac: name}.
Bridges and any devices that have a 'stolen' mac are excluded."""
ret = {}
- for name, mac, _driver, _devid in get_interfaces():
+ for name, mac, _driver, _devid in get_interfaces(
+ blacklist_drivers=blacklist_drivers):
if mac in ret:
raise RuntimeError(
"duplicate mac found! both '%s' and '%s' have mac '%s'" %
@@ -838,11 +843,13 @@ def get_interfaces_by_mac_on_linux():
return ret
-def get_interfaces():
+def get_interfaces(blacklist_drivers=None) -> list:
"""Return list of interface tuples (name, mac, driver, device_id)
Bridges and any devices that have a 'stolen' mac are excluded."""
ret = []
+ if blacklist_drivers is None:
+ blacklist_drivers = []
devs = get_devicelist()
# 16 somewhat arbitrarily chosen. Normally a mac is 6 '00:' tokens.
zero_mac = ':'.join(('00',) * 16)
@@ -866,7 +873,11 @@ def get_interfaces():
# skip nics that have no mac (00:00....)
if name != 'lo' and mac == zero_mac[:len(mac)]:
continue
- ret.append((name, mac, device_driver(name), device_devid(name)))
+ # skip nics that have drivers blacklisted
+ driver = device_driver(name)
+ if driver in blacklist_drivers:
+ continue
+ ret.append((name, mac, driver, device_devid(name)))
return ret
diff --git a/cloudinit/sources/DataSourceAzure.py b/cloudinit/sources/DataSourceAzure.py
index 773c60d7..fc32f8b1 100755
--- a/cloudinit/sources/DataSourceAzure.py
+++ b/cloudinit/sources/DataSourceAzure.py
@@ -83,6 +83,25 @@ UBUNTU_EXTENDED_NETWORK_SCRIPTS = [
'/run/network/interfaces.ephemeral.d',
]
+# This list is used to blacklist devices that will be considered
+# for renaming or fallback interfaces.
+#
+# On Azure network devices using these drivers are automatically
+# configured by the platform and should not be configured by
+# cloud-init's network configuration.
+#
+# Note:
+# Azure Dv4 and Ev4 series VMs always have mlx5 hardware.
+# https://docs.microsoft.com/en-us/azure/virtual-machines/dv4-dsv4-series
+# https://docs.microsoft.com/en-us/azure/virtual-machines/ev4-esv4-series
+# Earlier D and E series VMs (such as Dv2, Dv3, and Ev3 series VMs)
+# can have either mlx4 or mlx5 hardware, with the older series VMs
+# having a higher chance of coming with mlx4 hardware.
+# https://docs.microsoft.com/en-us/azure/virtual-machines/dv2-dsv2-series
+# https://docs.microsoft.com/en-us/azure/virtual-machines/dv3-dsv3-series
+# https://docs.microsoft.com/en-us/azure/virtual-machines/ev3-esv3-series
+BLACKLIST_DRIVERS = ['mlx4_core', 'mlx5_core']
+
def find_storvscid_from_sysctl_pnpinfo(sysctl_out, deviceid):
# extract the 'X' from dev.storvsc.X. if deviceid matches
@@ -529,6 +548,8 @@ class DataSourceAzure(sources.DataSource):
except Exception as e:
LOG.warning("Failed to get system information: %s", e)
+ self.distro.networking.blacklist_drivers = BLACKLIST_DRIVERS
+
try:
crawled_data = util.log_time(
logfunc=LOG.debug, msg='Crawl of metadata service',
@@ -1468,23 +1489,12 @@ def _generate_network_config_from_imds_metadata(imds_metadata) -> dict:
@azure_ds_telemetry_reporter
def _generate_network_config_from_fallback_config() -> dict:
- """Generate fallback network config excluding mlx4_core & mlx5_core devices.
+ """Generate fallback network config excluding blacklisted devices.
@return: Dictionary containing network version 2 standard configuration.
"""
- # Azure Dv4 and Ev4 series VMs always have mlx5 hardware.
- # https://docs.microsoft.com/en-us/azure/virtual-machines/dv4-dsv4-series
- # https://docs.microsoft.com/en-us/azure/virtual-machines/ev4-esv4-series
- # Earlier D and E series VMs (such as Dv2, Dv3, and Ev3 series VMs)
- # can have either mlx4 or mlx5 hardware, with the older series VMs
- # having a higher chance of coming with mlx4 hardware.
- # https://docs.microsoft.com/en-us/azure/virtual-machines/dv2-dsv2-series
- # https://docs.microsoft.com/en-us/azure/virtual-machines/dv3-dsv3-series
- # https://docs.microsoft.com/en-us/azure/virtual-machines/ev3-esv3-series
- blacklist = ['mlx4_core', 'mlx5_core']
- # generate a network config, blacklist picking mlx4_core and mlx5_core devs
return net.generate_fallback_config(
- blacklist_drivers=blacklist, config_driver=True)
+ blacklist_drivers=BLACKLIST_DRIVERS, config_driver=True)
@azure_ds_telemetry_reporter