netutils: Use ethtool ioctl to get permanent mac address
Fetching the permanent MAC address of the interface instead of the
default one allows to get the right one in case it got changed during
setup (likely with a bonding setup).
In order to fetch the permanent MAC address of a given interface, one
can either use Netlink (either rtnetlink or ethtool), or use ethtool
ioctl.
The use of ioctl feels simpler and requires no additional dependency.
The implementation falls back to older behavior should an error occur.
Closes-Bug: #2103450
Change-Id: I54151990e396ddcf775128ca24d3db08e45c256d
Signed-off-by: Nicolas Belouin <nicolas.belouin@suse.com>
(cherry picked from commit 48422a532f)
This commit is contained in:
@@ -34,6 +34,13 @@ LLDP_ETHERTYPE = 0x88cc
|
|||||||
IFF_PROMISC = 0x100
|
IFF_PROMISC = 0x100
|
||||||
SIOCGIFFLAGS = 0x8913
|
SIOCGIFFLAGS = 0x8913
|
||||||
SIOCSIFFLAGS = 0x8914
|
SIOCSIFFLAGS = 0x8914
|
||||||
|
# SIOCETHTOOL from linux/sockios.h
|
||||||
|
SIOCETHTOOL = 0x8946
|
||||||
|
# ETHTOOL_GPERMADDR from linux/ethtool.h
|
||||||
|
ETHTOOL_GPERMADDR = 0x00000020
|
||||||
|
# MAX_ADDR_LEN from linux/netdevice.h
|
||||||
|
MAX_ADDR_LEN = 32
|
||||||
|
|
||||||
INFINIBAND_ADDR_LEN = 59
|
INFINIBAND_ADDR_LEN = 59
|
||||||
|
|
||||||
# LLDP definitions needed to extract vlan information
|
# LLDP definitions needed to extract vlan information
|
||||||
@@ -45,10 +52,25 @@ dot1_VLAN_NAME = "03"
|
|||||||
VLAN_ID_LEN = len(LLDP_802dot1_OUI + dot1_VLAN_NAME)
|
VLAN_ID_LEN = len(LLDP_802dot1_OUI + dot1_VLAN_NAME)
|
||||||
|
|
||||||
|
|
||||||
|
class ethtoolPermAddr(ctypes.Structure):
|
||||||
|
"""Class for getting interface permanent MAC address"""
|
||||||
|
_fields_ = [("cmd", ctypes.c_uint32),
|
||||||
|
("size", ctypes.c_uint32),
|
||||||
|
("data", ctypes.c_uint8 * MAX_ADDR_LEN)]
|
||||||
|
|
||||||
|
|
||||||
|
class ifreq_data(ctypes.Union):
|
||||||
|
_fields_ = [("ifr_flags", ctypes.c_short),
|
||||||
|
(
|
||||||
|
"ifr_data_ethtool_perm_addr",
|
||||||
|
ctypes.POINTER(ethtoolPermAddr))]
|
||||||
|
|
||||||
|
|
||||||
class ifreq(ctypes.Structure):
|
class ifreq(ctypes.Structure):
|
||||||
"""Class for setting flags on a socket."""
|
"""Class for ioctl on socket."""
|
||||||
|
_anonymous_ = ("ifr_data",)
|
||||||
_fields_ = [("ifr_ifrn", ctypes.c_char * 16),
|
_fields_ = [("ifr_ifrn", ctypes.c_char * 16),
|
||||||
("ifr_flags", ctypes.c_short)]
|
("ifr_data", ifreq_data)]
|
||||||
|
|
||||||
|
|
||||||
class RawPromiscuousSockets(object):
|
class RawPromiscuousSockets(object):
|
||||||
@@ -236,6 +258,23 @@ def get_ipv6_addr(interface_id):
|
|||||||
|
|
||||||
|
|
||||||
def get_mac_addr(interface_id):
|
def get_mac_addr(interface_id):
|
||||||
|
"""Retrieve permanent mac address, if unable to fallback to default one"""
|
||||||
|
try:
|
||||||
|
data = ethtoolPermAddr(cmd=ETHTOOL_GPERMADDR, size=MAX_ADDR_LEN)
|
||||||
|
ifr = ifreq(ifr_ifrn=interface_id.encode())
|
||||||
|
ifr.ifr_data_ethtool_perm_addr = ctypes.pointer(data)
|
||||||
|
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, 0)
|
||||||
|
fcntl.ioctl(sock.fileno(), SIOCETHTOOL, ifr)
|
||||||
|
# if not full of zeros
|
||||||
|
if any(data.data[:data.size]):
|
||||||
|
# kernel updates size to actual address size during ioctl call
|
||||||
|
permaddr = [f'{b:02x}' for b in data.data[:data.size]]
|
||||||
|
return ':'.join(permaddr)
|
||||||
|
except OSError:
|
||||||
|
pass
|
||||||
|
LOG.warning("Failed to get permanent mac address for interface %s, "
|
||||||
|
"falling back to default mac address",
|
||||||
|
interface_id)
|
||||||
return get_default_ip_addr(socket.AF_PACKET, interface_id)
|
return get_default_ip_addr(socket.AF_PACKET, interface_id)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -6279,6 +6279,7 @@ class TestCollectSystemLogs(base.IronicAgentTest):
|
|||||||
FakeAddr = namedtuple('FakeAddr', ('family', 'address'))
|
FakeAddr = namedtuple('FakeAddr', ('family', 'address'))
|
||||||
|
|
||||||
|
|
||||||
|
@mock.patch.object(netutils, 'get_mac_addr', autospec=True)
|
||||||
@mock.patch.object(hardware.GenericHardwareManager, '_get_system_lshw_dict',
|
@mock.patch.object(hardware.GenericHardwareManager, '_get_system_lshw_dict',
|
||||||
autospec=True, return_value={'id': 'host'})
|
autospec=True, return_value={'id': 'host'})
|
||||||
@mock.patch.object(hardware, 'get_managers', autospec=True,
|
@mock.patch.object(hardware, 'get_managers', autospec=True,
|
||||||
@@ -6303,7 +6304,8 @@ class TestListNetworkInterfaces(base.IronicAgentTest):
|
|||||||
mocked_listdir,
|
mocked_listdir,
|
||||||
mocked_net_if_addrs,
|
mocked_net_if_addrs,
|
||||||
mockedget_managers,
|
mockedget_managers,
|
||||||
mocked_lshw):
|
mocked_lshw,
|
||||||
|
mocked_get_mac_addr):
|
||||||
mocked_lshw.return_value = json.loads(hws.LSHW_JSON_OUTPUT_V2[0])
|
mocked_lshw.return_value = json.loads(hws.LSHW_JSON_OUTPUT_V2[0])
|
||||||
mocked_listdir.return_value = ['lo', 'eth0', 'foobar']
|
mocked_listdir.return_value = ['lo', 'eth0', 'foobar']
|
||||||
mocked_exists.side_effect = [False, False, True, True]
|
mocked_exists.side_effect = [False, False, True, True]
|
||||||
@@ -6327,6 +6329,10 @@ class TestListNetworkInterfaces(base.IronicAgentTest):
|
|||||||
FakeAddr(socket.AF_INET6, 'fd00:1000::101')
|
FakeAddr(socket.AF_INET6, 'fd00:1000::101')
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
mocked_get_mac_addr.side_effect = lambda iface: {
|
||||||
|
'lo': '00:00:00:00:00:00',
|
||||||
|
'eth0': '00:0c:29:8c:11:b1',
|
||||||
|
}.get(iface)
|
||||||
mocked_execute.return_value = ('em0\n', '')
|
mocked_execute.return_value = ('em0\n', '')
|
||||||
mock_has_carrier.return_value = True
|
mock_has_carrier.return_value = True
|
||||||
interfaces = self.hardware.list_network_interfaces()
|
interfaces = self.hardware.list_network_interfaces()
|
||||||
@@ -6348,7 +6354,8 @@ class TestListNetworkInterfaces(base.IronicAgentTest):
|
|||||||
mocked_listdir,
|
mocked_listdir,
|
||||||
mocked_net_if_addrs,
|
mocked_net_if_addrs,
|
||||||
mockedget_managers,
|
mockedget_managers,
|
||||||
mocked_lshw):
|
mocked_lshw,
|
||||||
|
mocked_get_mac_addr):
|
||||||
mocked_listdir.return_value = ['lo', 'eth0']
|
mocked_listdir.return_value = ['lo', 'eth0']
|
||||||
mocked_exists.side_effect = [False, False, True]
|
mocked_exists.side_effect = [False, False, True]
|
||||||
mocked_open.return_value.__enter__ = lambda s: s
|
mocked_open.return_value.__enter__ = lambda s: s
|
||||||
@@ -6367,6 +6374,10 @@ class TestListNetworkInterfaces(base.IronicAgentTest):
|
|||||||
FakeAddr(socket.AF_PACKET, '00:0c:29:8c:11:b1')
|
FakeAddr(socket.AF_PACKET, '00:0c:29:8c:11:b1')
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
mocked_get_mac_addr.side_effect = lambda iface: {
|
||||||
|
'lo': '00:00:00:00:00:00',
|
||||||
|
'eth0': '00:0c:29:8c:11:b1',
|
||||||
|
}.get(iface)
|
||||||
mocked_execute.return_value = ('em0\n', '')
|
mocked_execute.return_value = ('em0\n', '')
|
||||||
mock_has_carrier.return_value = True
|
mock_has_carrier.return_value = True
|
||||||
interfaces = self.hardware.list_network_interfaces()
|
interfaces = self.hardware.list_network_interfaces()
|
||||||
@@ -6390,7 +6401,8 @@ class TestListNetworkInterfaces(base.IronicAgentTest):
|
|||||||
mocked_listdir,
|
mocked_listdir,
|
||||||
mocked_net_if_addrs,
|
mocked_net_if_addrs,
|
||||||
mockedget_managers,
|
mockedget_managers,
|
||||||
mocked_lshw):
|
mocked_lshw,
|
||||||
|
mocked_get_mac_addr):
|
||||||
CONF.set_override('collect_lldp', True)
|
CONF.set_override('collect_lldp', True)
|
||||||
mocked_listdir.return_value = ['lo', 'eth0']
|
mocked_listdir.return_value = ['lo', 'eth0']
|
||||||
mocked_exists.side_effect = [False, False, True]
|
mocked_exists.side_effect = [False, False, True]
|
||||||
@@ -6410,6 +6422,10 @@ class TestListNetworkInterfaces(base.IronicAgentTest):
|
|||||||
FakeAddr(socket.AF_PACKET, '00:0c:29:8c:11:b1')
|
FakeAddr(socket.AF_PACKET, '00:0c:29:8c:11:b1')
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
mocked_get_mac_addr.side_effect = lambda iface: {
|
||||||
|
'lo': '00:00:00:00:00:00',
|
||||||
|
'eth0': '00:0c:29:8c:11:b1',
|
||||||
|
}.get(iface)
|
||||||
mocked_lldp_info.return_value = {'eth0': [
|
mocked_lldp_info.return_value = {'eth0': [
|
||||||
(0, b''),
|
(0, b''),
|
||||||
(1, b'\x04\x88Z\x92\xecTY'),
|
(1, b'\x04\x88Z\x92\xecTY'),
|
||||||
@@ -6444,7 +6460,8 @@ class TestListNetworkInterfaces(base.IronicAgentTest):
|
|||||||
mocked_listdir,
|
mocked_listdir,
|
||||||
mocked_net_if_addrs,
|
mocked_net_if_addrs,
|
||||||
mockedget_managers,
|
mockedget_managers,
|
||||||
mocked_lshw):
|
mocked_lshw,
|
||||||
|
mocked_get_mac_addr):
|
||||||
CONF.set_override('collect_lldp', True)
|
CONF.set_override('collect_lldp', True)
|
||||||
mocked_listdir.return_value = ['lo', 'eth0']
|
mocked_listdir.return_value = ['lo', 'eth0']
|
||||||
mocked_exists.side_effect = [False, False, True]
|
mocked_exists.side_effect = [False, False, True]
|
||||||
@@ -6464,6 +6481,10 @@ class TestListNetworkInterfaces(base.IronicAgentTest):
|
|||||||
FakeAddr(socket.AF_PACKET, '00:0c:29:8c:11:b1')
|
FakeAddr(socket.AF_PACKET, '00:0c:29:8c:11:b1')
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
mocked_get_mac_addr.side_effect = lambda iface: {
|
||||||
|
'lo': '00:00:00:00:00:00',
|
||||||
|
'eth0': '00:0c:29:8c:11:b1',
|
||||||
|
}.get(iface)
|
||||||
mocked_lldp_info.side_effect = Exception('Boom!')
|
mocked_lldp_info.side_effect = Exception('Boom!')
|
||||||
mocked_execute.return_value = ('em0\n', '')
|
mocked_execute.return_value = ('em0\n', '')
|
||||||
mock_has_carrier.return_value = True
|
mock_has_carrier.return_value = True
|
||||||
@@ -6485,7 +6506,8 @@ class TestListNetworkInterfaces(base.IronicAgentTest):
|
|||||||
mocked_listdir,
|
mocked_listdir,
|
||||||
mocked_net_if_addrs,
|
mocked_net_if_addrs,
|
||||||
mockedget_managers,
|
mockedget_managers,
|
||||||
mocked_lshw):
|
mocked_lshw,
|
||||||
|
mocked_get_mac_addr):
|
||||||
|
|
||||||
mockedget_managers.return_value = [hardware.GenericHardwareManager()]
|
mockedget_managers.return_value = [hardware.GenericHardwareManager()]
|
||||||
mocked_listdir.return_value = ['lo', 'eth0']
|
mocked_listdir.return_value = ['lo', 'eth0']
|
||||||
@@ -6506,6 +6528,10 @@ class TestListNetworkInterfaces(base.IronicAgentTest):
|
|||||||
FakeAddr(socket.AF_PACKET, '00:0c:29:8c:11:b1')
|
FakeAddr(socket.AF_PACKET, '00:0c:29:8c:11:b1')
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
mocked_get_mac_addr.side_effect = lambda iface: {
|
||||||
|
'lo': '00:00:00:00:00:00',
|
||||||
|
'eth0': '00:0c:29:8c:11:b1',
|
||||||
|
}.get(iface)
|
||||||
mocked_execute.return_value = ('em0\n', '')
|
mocked_execute.return_value = ('em0\n', '')
|
||||||
mock_has_carrier.return_value = False
|
mock_has_carrier.return_value = False
|
||||||
interfaces = self.hardware.list_network_interfaces()
|
interfaces = self.hardware.list_network_interfaces()
|
||||||
@@ -6526,7 +6552,8 @@ class TestListNetworkInterfaces(base.IronicAgentTest):
|
|||||||
mocked_listdir,
|
mocked_listdir,
|
||||||
mocked_net_if_addrs,
|
mocked_net_if_addrs,
|
||||||
mockedget_managers,
|
mockedget_managers,
|
||||||
mocked_lshw):
|
mocked_lshw,
|
||||||
|
mocked_get_mac_addr):
|
||||||
mocked_listdir.return_value = ['lo', 'eth0']
|
mocked_listdir.return_value = ['lo', 'eth0']
|
||||||
mocked_exists.side_effect = [False, False, True]
|
mocked_exists.side_effect = [False, False, True]
|
||||||
mocked_open.return_value.__enter__ = lambda s: s
|
mocked_open.return_value.__enter__ = lambda s: s
|
||||||
@@ -6546,6 +6573,10 @@ class TestListNetworkInterfaces(base.IronicAgentTest):
|
|||||||
FakeAddr(socket.AF_PACKET, '00:0c:29:8c:11:b1')
|
FakeAddr(socket.AF_PACKET, '00:0c:29:8c:11:b1')
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
mocked_get_mac_addr.side_effect = lambda iface: {
|
||||||
|
'lo': '00:00:00:00:00:00',
|
||||||
|
'eth0': '00:0c:29:8c:11:b1',
|
||||||
|
}.get(iface)
|
||||||
mocked_execute.return_value = ('em0\n', '')
|
mocked_execute.return_value = ('em0\n', '')
|
||||||
mock_has_carrier.return_value = True
|
mock_has_carrier.return_value = True
|
||||||
interfaces = self.hardware.list_network_interfaces()
|
interfaces = self.hardware.list_network_interfaces()
|
||||||
@@ -6567,7 +6598,8 @@ class TestListNetworkInterfaces(base.IronicAgentTest):
|
|||||||
mocked_listdir,
|
mocked_listdir,
|
||||||
mocked_net_if_addrs,
|
mocked_net_if_addrs,
|
||||||
mockedget_managers,
|
mockedget_managers,
|
||||||
mocked_lshw):
|
mocked_lshw,
|
||||||
|
mocked_get_mac_addr):
|
||||||
mocked_listdir.return_value = ['lo', 'bond0']
|
mocked_listdir.return_value = ['lo', 'bond0']
|
||||||
mocked_exists.side_effect = [False, False, True]
|
mocked_exists.side_effect = [False, False, True]
|
||||||
mocked_open.return_value.__enter__ = lambda s: s
|
mocked_open.return_value.__enter__ = lambda s: s
|
||||||
@@ -6586,6 +6618,10 @@ class TestListNetworkInterfaces(base.IronicAgentTest):
|
|||||||
FakeAddr(socket.AF_PACKET, '00:0c:29:8c:11:b1')
|
FakeAddr(socket.AF_PACKET, '00:0c:29:8c:11:b1')
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
mocked_get_mac_addr.side_effect = lambda iface: {
|
||||||
|
'lo': '00:00:00:00:00:00',
|
||||||
|
'bond0': '00:0c:29:8c:11:b1',
|
||||||
|
}.get(iface)
|
||||||
mocked_execute.return_value = ('\n', '')
|
mocked_execute.return_value = ('\n', '')
|
||||||
mock_has_carrier.return_value = True
|
mock_has_carrier.return_value = True
|
||||||
interfaces = self.hardware.list_network_interfaces()
|
interfaces = self.hardware.list_network_interfaces()
|
||||||
@@ -6610,7 +6646,8 @@ class TestListNetworkInterfaces(base.IronicAgentTest):
|
|||||||
mocked_listdir,
|
mocked_listdir,
|
||||||
mocked_net_if_addrs,
|
mocked_net_if_addrs,
|
||||||
mockedget_managers,
|
mockedget_managers,
|
||||||
mocked_lshw):
|
mocked_lshw,
|
||||||
|
mocked_get_mac_addr):
|
||||||
mocked_listdir.return_value = ['lo', 'eth0']
|
mocked_listdir.return_value = ['lo', 'eth0']
|
||||||
mocked_exists.side_effect = [False, False, True]
|
mocked_exists.side_effect = [False, False, True]
|
||||||
mocked_open.return_value.__enter__ = lambda s: s
|
mocked_open.return_value.__enter__ = lambda s: s
|
||||||
@@ -6629,6 +6666,10 @@ class TestListNetworkInterfaces(base.IronicAgentTest):
|
|||||||
FakeAddr(socket.AF_PACKET, '00:0c:29:8c:11:b1')
|
FakeAddr(socket.AF_PACKET, '00:0c:29:8c:11:b1')
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
mocked_get_mac_addr.side_effect = lambda iface: {
|
||||||
|
'lo': '00:00:00:00:00:00',
|
||||||
|
'eth0': '00:0c:29:8c:11:b1',
|
||||||
|
}.get(iface)
|
||||||
mocked_execute.return_value = ('em0\n', '')
|
mocked_execute.return_value = ('em0\n', '')
|
||||||
mock_has_carrier.return_value = True
|
mock_has_carrier.return_value = True
|
||||||
mock_get_pci.return_value = '0000:02:00.0'
|
mock_get_pci.return_value = '0000:02:00.0'
|
||||||
@@ -6654,7 +6695,8 @@ class TestListNetworkInterfaces(base.IronicAgentTest):
|
|||||||
mocked_listdir,
|
mocked_listdir,
|
||||||
mocked_net_if_addrs,
|
mocked_net_if_addrs,
|
||||||
mockedget_managers,
|
mockedget_managers,
|
||||||
mocked_lshw):
|
mocked_lshw,
|
||||||
|
mocked_get_mac_addr):
|
||||||
CONF.set_override('enable_vlan_interfaces', 'eth0.100')
|
CONF.set_override('enable_vlan_interfaces', 'eth0.100')
|
||||||
mocked_listdir.return_value = ['lo', 'eth0']
|
mocked_listdir.return_value = ['lo', 'eth0']
|
||||||
mocked_exists.side_effect = [False, False, True]
|
mocked_exists.side_effect = [False, False, True]
|
||||||
@@ -6679,6 +6721,11 @@ class TestListNetworkInterfaces(base.IronicAgentTest):
|
|||||||
FakeAddr(socket.AF_PACKET, '00:0c:29:8c:11:b1')
|
FakeAddr(socket.AF_PACKET, '00:0c:29:8c:11:b1')
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
mocked_get_mac_addr.side_effect = lambda iface: {
|
||||||
|
'lo': '00:00:00:00:00:00',
|
||||||
|
'eth0': '00:0c:29:8c:11:b1',
|
||||||
|
'eth0.100': '00:0c:29:8c:11:b1',
|
||||||
|
}.get(iface)
|
||||||
mocked_execute.return_value = ('em0\n', '')
|
mocked_execute.return_value = ('em0\n', '')
|
||||||
mock_has_carrier.return_value = True
|
mock_has_carrier.return_value = True
|
||||||
interfaces = self.hardware.list_network_interfaces()
|
interfaces = self.hardware.list_network_interfaces()
|
||||||
@@ -6702,7 +6749,8 @@ class TestListNetworkInterfaces(base.IronicAgentTest):
|
|||||||
mocked_listdir,
|
mocked_listdir,
|
||||||
mocked_net_if_addrs,
|
mocked_net_if_addrs,
|
||||||
mockedget_managers,
|
mockedget_managers,
|
||||||
mocked_lshw):
|
mocked_lshw,
|
||||||
|
mocked_get_mac_addr):
|
||||||
CONF.set_override('collect_lldp', True)
|
CONF.set_override('collect_lldp', True)
|
||||||
CONF.set_override('enable_vlan_interfaces', 'eth0')
|
CONF.set_override('enable_vlan_interfaces', 'eth0')
|
||||||
mocked_listdir.return_value = ['lo', 'eth0']
|
mocked_listdir.return_value = ['lo', 'eth0']
|
||||||
@@ -6734,6 +6782,12 @@ class TestListNetworkInterfaces(base.IronicAgentTest):
|
|||||||
FakeAddr(socket.AF_PACKET, '00:0c:29:8c:11:c2')
|
FakeAddr(socket.AF_PACKET, '00:0c:29:8c:11:c2')
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
mocked_get_mac_addr.side_effect = lambda iface: {
|
||||||
|
'lo': '00:00:00:00:00:00',
|
||||||
|
'eth0': '00:0c:29:8c:11:b1',
|
||||||
|
'eth0.100': '00:0c:29:8c:11:c1',
|
||||||
|
'eth0.101': '00:0c:29:8c:11:c2',
|
||||||
|
}.get(iface)
|
||||||
mocked_lldp_info.return_value = {'eth0': [
|
mocked_lldp_info.return_value = {'eth0': [
|
||||||
(0, b''),
|
(0, b''),
|
||||||
(127, b'\x00\x80\xc2\x03\x00d\x08vlan-100'),
|
(127, b'\x00\x80\xc2\x03\x00d\x08vlan-100'),
|
||||||
@@ -6767,7 +6821,8 @@ class TestListNetworkInterfaces(base.IronicAgentTest):
|
|||||||
mocked_listdir,
|
mocked_listdir,
|
||||||
mocked_net_if_addrs,
|
mocked_net_if_addrs,
|
||||||
mockedget_managers,
|
mockedget_managers,
|
||||||
mocked_lshw):
|
mocked_lshw,
|
||||||
|
mocked_get_mac_addr):
|
||||||
CONF.set_override('collect_lldp', True)
|
CONF.set_override('collect_lldp', True)
|
||||||
CONF.set_override('enable_vlan_interfaces', 'enp0s1')
|
CONF.set_override('enable_vlan_interfaces', 'enp0s1')
|
||||||
mocked_listdir.return_value = ['lo', 'eth0']
|
mocked_listdir.return_value = ['lo', 'eth0']
|
||||||
@@ -6805,7 +6860,8 @@ class TestListNetworkInterfaces(base.IronicAgentTest):
|
|||||||
mocked_listdir,
|
mocked_listdir,
|
||||||
mocked_net_if_addrs,
|
mocked_net_if_addrs,
|
||||||
mockedget_managers,
|
mockedget_managers,
|
||||||
mocked_lshw):
|
mocked_lshw,
|
||||||
|
mocked_get_mac_addr):
|
||||||
CONF.set_override('collect_lldp', True)
|
CONF.set_override('collect_lldp', True)
|
||||||
CONF.set_override('enable_vlan_interfaces', 'all')
|
CONF.set_override('enable_vlan_interfaces', 'all')
|
||||||
mocked_listdir.return_value = ['lo', 'eth0', 'eth1']
|
mocked_listdir.return_value = ['lo', 'eth0', 'eth1']
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
---
|
||||||
|
fixes:
|
||||||
|
- |
|
||||||
|
Fixes IPA collecting the effective MAC address of NICs instead of the
|
||||||
|
pesistent MAC address. In case it fails to fetch the persistent address
|
||||||
|
falls back to effective MAC address.
|
||||||
|
See https://bugs.launchpad.net/ironic-python-agent/+bug/2103450 for
|
||||||
|
details.
|
||||||
|
|
||||||
Reference in New Issue
Block a user