aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--os_net_config/tests/test_utils.py49
-rw-r--r--os_net_config/utils.py29
2 files changed, 60 insertions, 18 deletions
diff --git a/os_net_config/tests/test_utils.py b/os_net_config/tests/test_utils.py
index a2d5cc4..b766384 100644
--- a/os_net_config/tests/test_utils.py
+++ b/os_net_config/tests/test_utils.py
@@ -109,7 +109,13 @@ class TestUtils(base.TestCase):
return out, None
if 'driverctl' in name:
return None, None
+
+ def test_get_dpdk_mac_address(name):
+ return '01:02:03:04:05:06'
self.stubs.Set(processutils, 'execute', test_execute)
+ self.stubs.Set(utils, '_get_dpdk_mac_address',
+ test_get_dpdk_mac_address)
+
utils.bind_dpdk_interfaces('nic2', 'vfio-pci', False)
def test_bind_dpdk_interfaces_fail(self):
@@ -119,34 +125,38 @@ class TestUtils(base.TestCase):
return out, None
if 'driverctl' in name:
return None, 'Error'
+
+ def test_get_dpdk_mac_address(name):
+ return '01:02:03:04:05:06'
self.stubs.Set(processutils, 'execute', test_execute)
+ self.stubs.Set(utils, '_get_dpdk_mac_address',
+ test_get_dpdk_mac_address)
+
self.assertRaises(utils.OvsDpdkBindException,
- utils.bind_dpdk_interfaces, 'nic2', 'vfio-pci',
+ utils.bind_dpdk_interfaces, 'eth1', 'vfio-pci',
False)
- def test_update_dpdk_map_new(self):
- utils._update_dpdk_map('eth1', '0000:03:00.0', 'vfio-pci')
- try:
- contents = utils.get_file_data(utils._DPDK_MAPPING_FILE)
- except IOError:
- pass
+ def test__update_dpdk_map_new(self):
+ utils._update_dpdk_map('eth1', '0000:03:00.0', '01:02:03:04:05:06',
+ 'vfio-pci')
+ contents = utils.get_file_data(utils._DPDK_MAPPING_FILE)
dpdk_map = yaml.load(contents) if contents else []
self.assertEqual(1, len(dpdk_map))
dpdk_test = [{'name': 'eth1', 'pci_address': '0000:03:00.0',
+ 'mac_address': '01:02:03:04:05:06',
'driver': 'vfio-pci'}]
self.assertListEqual(dpdk_test, dpdk_map)
def test_update_dpdk_map_exist(self):
dpdk_test = [{'name': 'eth1', 'pci_address': '0000:03:00.0',
+ 'mac_address': '01:02:03:04:05:06',
'driver': 'vfio-pci'}]
utils.write_yaml_config(utils._DPDK_MAPPING_FILE, dpdk_test)
- utils._update_dpdk_map('eth1', '0000:03:00.0', 'vfio-pci')
- try:
- contents = utils.get_file_data(utils._DPDK_MAPPING_FILE)
- except IOError:
- pass
+ utils._update_dpdk_map('eth1', '0000:03:00.0', '01:02:03:04:05:06',
+ 'vfio-pci')
+ contents = utils.get_file_data(utils._DPDK_MAPPING_FILE)
dpdk_map = yaml.load(contents) if contents else []
self.assertEqual(1, len(dpdk_map))
@@ -158,8 +168,10 @@ class TestUtils(base.TestCase):
utils.write_yaml_config(utils._DPDK_MAPPING_FILE, dpdk_test)
dpdk_test = [{'name': 'eth1', 'pci_address': '0000:03:00.0',
- 'driver': 'igb_uio'}]
- utils._update_dpdk_map('eth1', '0000:03:00.0', 'igb_uio')
+ 'mac_address': '01:02:03:04:05:06',
+ 'driver': 'vfio-pci'}]
+ utils._update_dpdk_map('eth1', '0000:03:00.0', '01:02:03:04:05:06',
+ 'vfio-pci')
try:
contents = utils.get_file_data(utils._DPDK_MAPPING_FILE)
except IOError:
@@ -183,8 +195,10 @@ class TestUtils(base.TestCase):
with open(os.path.join(tmpdir, nic), 'w') as f:
f.write(nic)
- utils._update_dpdk_map('eth1', '0000:03:00.0', 'igb_uio')
- utils._update_dpdk_map('p3p1', '0000:04:00.0', 'igb_uio')
+ utils._update_dpdk_map('eth1', '0000:03:00.0', '01:02:03:04:05:06',
+ 'vfio-pci')
+ utils._update_dpdk_map('p3p1', '0000:04:00.0', '01:02:03:04:05:07',
+ 'igb_uio')
nics = utils.ordered_active_nics()
@@ -200,3 +214,6 @@ class TestUtils(base.TestCase):
self.assertEqual('z1', nics[9])
shutil.rmtree(tmpdir)
+
+ def test_interface_mac_raises(self):
+ self.assertRaises(IOError, utils.interface_mac, 'ens20f2p3')
diff --git a/os_net_config/utils.py b/os_net_config/utils.py
index 95325a3..af359d5 100644
--- a/os_net_config/utils.py
+++ b/os_net_config/utils.py
@@ -25,6 +25,14 @@ from oslo_concurrency import processutils
logger = logging.getLogger(__name__)
_SYS_CLASS_NET = '/sys/class/net'
+# File to contain the DPDK mapped nics, as nic name will not be available after
+# binding driver, which is required for correct nic numbering.
+# Format of the file (list mapped nic's details):
+# -
+# name: eth1
+# pci_address: 0000:02:00.0
+# mac_address: 01:02:03:04:05:06
+# driver: vfio-pci
_DPDK_MAPPING_FILE = '/var/lib/os-net-config/dpdk_mapping.yaml'
@@ -73,6 +81,12 @@ def interface_mac(name):
with open('/sys/class/net/%s/address' % name, 'r') as f:
return f.read().rstrip()
except IOError:
+ # If the interface is bound to a DPDK driver, get the mac address from
+ # the dpdk mapping file as /sys files will be removed after binding.
+ dpdk_mac_address = _get_dpdk_mac_address(name)
+ if dpdk_mac_address:
+ return dpdk_mac_address
+
logger.error("Unable to read mac address: %s" % name)
raise
@@ -176,6 +190,7 @@ def bind_dpdk_interfaces(ifname, driver, noop):
msg = "Failed to modprobe vfio-pci module"
raise OvsDpdkBindException(msg)
+ mac_address = interface_mac(ifname)
try:
out, err = processutils.execute('driverctl', 'set-override',
pci_address, driver)
@@ -183,7 +198,7 @@ def bind_dpdk_interfaces(ifname, driver, noop):
msg = "Failed to bind dpdk interface err - %s" % err
raise OvsDpdkBindException(msg)
else:
- _update_dpdk_map(ifname, pci_address, driver)
+ _update_dpdk_map(ifname, pci_address, mac_address, driver)
except processutils.ProcessExecutionError:
msg = "Failed to bind interface %s with dpdk" % ifname
@@ -219,19 +234,29 @@ def _get_pci_address(ifname, noop):
# way to identify the nic name after it is bound. So, the DPDK bound nic info
# is stored persistently in a file and is used to for nic numbering on
# subsequent runs of os-net-config.
-def _update_dpdk_map(ifname, pci_address, driver):
+def _update_dpdk_map(ifname, pci_address, mac_address, driver):
contents = get_file_data(_DPDK_MAPPING_FILE)
dpdk_map = yaml.load(contents) if contents else []
for item in dpdk_map:
if item['pci_address'] == pci_address:
item['name'] = ifname
+ item['mac_address'] = mac_address
item['driver'] = driver
break
else:
new_item = {}
new_item['pci_address'] = pci_address
new_item['name'] = ifname
+ new_item['mac_address'] = mac_address
new_item['driver'] = driver
dpdk_map.append(new_item)
write_yaml_config(_DPDK_MAPPING_FILE, dpdk_map)
+
+
+def _get_dpdk_mac_address(name):
+ contents = get_file_data(_DPDK_MAPPING_FILE)
+ dpdk_map = yaml.load(contents) if contents else []
+ for item in dpdk_map:
+ if item['name'] == name:
+ return item['mac_address']