diff options
Diffstat (limited to 'os_net_config')
-rw-r--r-- | os_net_config/tests/test_utils.py | 49 | ||||
-rw-r--r-- | os_net_config/utils.py | 29 |
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'] |