def test_ordered_active_nics(self): tmpdir = tempfile.mkdtemp() self.stubs.Set(utils, '_SYS_CLASS_NET', tmpdir) def test_is_active_nic(interface_name): return True self.stubs.Set(utils, '_is_active_nic', test_is_active_nic) for nic in [ 'a1', 'em1', 'em2', 'eth2', 'z1', 'enp8s0', 'enp10s0', 'enp1s0f0' ]: with open(os.path.join(tmpdir, nic), 'w') as f: f.write(nic) nics = utils.ordered_active_nics() self.assertEqual('em1', nics[0]) self.assertEqual('em2', nics[1]) self.assertEqual('eth2', nics[2]) self.assertEqual('a1', nics[3]) self.assertEqual('enp1s0f0', nics[4]) self.assertEqual('enp8s0', nics[5]) self.assertEqual('enp10s0', nics[6]) self.assertEqual('z1', nics[7]) shutil.rmtree(tmpdir)
def test_ordered_active_nics_with_dpdk_mapping(self): tmpdir = tempfile.mkdtemp() self.stub_out('os_net_config.utils._SYS_CLASS_NET', tmpdir) def test_is_available_nic(interface_name, check_active): return True self.stub_out('os_net_config.utils._is_available_nic', test_is_available_nic) for nic in ['a1', 'em1', 'em2', 'eth2', 'z1', 'enp8s0', 'enp10s0', 'enp1s0f0']: with open(os.path.join(tmpdir, nic), 'w') as f: f.write(nic) 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() self.assertEqual('em1', nics[0]) self.assertEqual('em2', nics[1]) self.assertEqual('eth1', nics[2]) # DPDK bound nic self.assertEqual('eth2', nics[3]) self.assertEqual('a1', nics[4]) self.assertEqual('enp1s0f0', nics[5]) self.assertEqual('enp8s0', nics[6]) self.assertEqual('enp10s0', nics[7]) self.assertEqual('p3p1', nics[8]) # DPDK bound nic self.assertEqual('z1', nics[9]) shutil.rmtree(tmpdir)
def test_ordered_active_nics(self): tmpdir = tempfile.mkdtemp() self.stubs.Set(utils, '_SYS_CLASS_NET', tmpdir) def test_is_active_nic(interface_name): return True self.stubs.Set(utils, '_is_active_nic', test_is_active_nic) for nic in ['a1', 'em1', 'em2', 'eth2', 'z1', 'enp8s0', 'enp10s0', 'enp1s0f0']: with open(os.path.join(tmpdir, nic), 'w') as f: f.write(nic) nics = utils.ordered_active_nics() self.assertEqual('em1', nics[0]) self.assertEqual('em2', nics[1]) self.assertEqual('eth2', nics[2]) self.assertEqual('a1', nics[3]) self.assertEqual('enp1s0f0', nics[4]) self.assertEqual('enp8s0', nics[5]) self.assertEqual('enp10s0', nics[6]) self.assertEqual('z1', nics[7]) shutil.rmtree(tmpdir)
def test_ordered_active_nics_with_dpdk_mapping(self): tmpdir = tempfile.mkdtemp() self.stubs.Set(utils, '_SYS_CLASS_NET', tmpdir) def test_is_active_nic(interface_name): return True self.stubs.Set(utils, '_is_active_nic', test_is_active_nic) for nic in ['a1', 'em1', 'em2', 'eth2', 'z1', 'enp8s0', 'enp10s0', 'enp1s0f0']: with open(os.path.join(tmpdir, nic), 'w') as f: f.write(nic) 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() self.assertEqual('em1', nics[0]) self.assertEqual('em2', nics[1]) self.assertEqual('eth1', nics[2]) # DPDK bound nic self.assertEqual('eth2', nics[3]) self.assertEqual('a1', nics[4]) self.assertEqual('enp1s0f0', nics[5]) self.assertEqual('enp8s0', nics[6]) self.assertEqual('enp10s0', nics[7]) self.assertEqual('p3p1', nics[8]) # DPDK bound nic self.assertEqual('z1', nics[9]) shutil.rmtree(tmpdir)
def _numbered_nics(): global _NUMBERED_NICS if _NUMBERED_NICS: return _NUMBERED_NICS _NUMBERED_NICS = {} count = 0 for nic in utils.ordered_active_nics(): count += 1 _NUMBERED_NICS["nic%i" % count] = nic logger.info("nic%i mapped to: %s" % (count, nic)) return _NUMBERED_NICS
def _mapped_nics(nic_mapping=None): mapping = nic_mapping or {} global _MAPPED_NICS if _MAPPED_NICS: return _MAPPED_NICS _MAPPED_NICS = {} active_nics = utils.ordered_active_nics() for nic_alias, nic_mapped in mapping.items(): if nic_mapped not in active_nics: # The mapping is either invalid, or specifies a mac is_mapping_valid = False for active in active_nics: try: active_mac = utils.interface_mac(active) except IOError: continue if nic_mapped == active_mac: logger.debug("%s matches device %s" % (nic_mapped, active)) nic_mapped = active is_mapping_valid = True break if not is_mapping_valid: # The mapping can't specify a non-active or non-existent nic logger.warning('interface %s is not an active nic (%s)' % (nic_mapped, ', '.join(active_nics))) continue # Duplicate mappings are not allowed if nic_mapped in _MAPPED_NICS.values(): msg = ('interface %s already mapped, ' 'check mapping file for duplicates' % nic_mapped) raise InvalidConfigException(msg) _MAPPED_NICS[nic_alias] = nic_mapped logger.info("%s mapped to: %s" % (nic_alias, nic_mapped)) # Add default numbered mappings, but do not overwrite existing entries for nic_mapped in set(active_nics).difference(set(_MAPPED_NICS.values())): nic_alias = "nic%i" % (active_nics.index(nic_mapped) + 1) if nic_alias in _MAPPED_NICS: logger.warning("no mapping for interface %s because " "%s is mapped to %s" % (nic_mapped, nic_alias, _MAPPED_NICS[nic_alias])) else: _MAPPED_NICS[nic_alias] = nic_mapped logger.info("%s mapped to: %s" % (nic_alias, nic_mapped)) if not _MAPPED_NICS: logger.warning('No active nics found.') return _MAPPED_NICS
def get_uplinks_and_chassisid(): """Get uplinks and chassis_id in RHOSP environment. :returns: a list of uplinks names and one chassis_id which is the first active nic's mac address. """ intf_indexes = [] while True: if not os.path.isfile(NET_CONF_PATH): time.sleep(1) continue try: json_data = open(NET_CONF_PATH).read() data = jsonutils.loads(json_data) except ValueError: time.sleep(1) continue network_config = data.get('network_config') for config in network_config: if config.get('type') != 'ovs_bridge': continue members = config.get('members') for member in members: if member.get('type') != 'ovs_bond': continue nics = member.get('members') for nic in nics: if nic.get('type') != 'interface': continue nic_name = nic.get('name') indexes = map(int, re.findall(r'\d+', nic_name)) if len(indexes) == 1: intf_indexes.append(indexes[0] - 1) break break break active_intfs = utils.ordered_active_nics() intf_len = len(active_intfs) chassis_id = "00:00:00:00:00:00" if len(active_intfs) != 0: chassis_id = get_mac_str(active_intfs[0]) intfs = [] for index in intf_indexes: if index < intf_len: intfs.append(active_intfs[index]) return intfs, chassis_id
def test_ordered_active_nics_with_dpdk_mapping(self): tmpdir = tempfile.mkdtemp() self.stub_out('os_net_config.common.SYS_CLASS_NET', tmpdir) tmp_pci_dir = tempfile.mkdtemp() self.stub_out('os_net_config.utils._SYS_BUS_PCI_DEV', tmp_pci_dir) physfn_path = utils._SYS_BUS_PCI_DEV + '/0000:05:01.1/physfn' os.makedirs(physfn_path) def test_is_available_nic(interface_name, check_active): return True self.stub_out('os_net_config.utils._is_available_nic', test_is_available_nic) for nic in [ 'a1', 'em1', 'em2', 'eth2', 'z1', 'enp8s0', 'enp10s0', 'enp1s0f0' ]: with open(os.path.join(tmpdir, nic), 'w') as f: f.write(nic) 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') utils._update_dpdk_map('p3p0_0', '0000:05:01.1', 'AA:02:03:04:05:FF', 'vfio-pci') nics = utils.ordered_active_nics() self.assertEqual('em1', nics[0]) self.assertEqual('em2', nics[1]) self.assertEqual('eth1', nics[2]) # DPDK bound nic self.assertEqual('eth2', nics[3]) self.assertEqual('a1', nics[4]) self.assertEqual('enp1s0f0', nics[5]) self.assertEqual('enp8s0', nics[6]) self.assertEqual('enp10s0', nics[7]) self.assertEqual('p3p1', nics[8]) # DPDK bound nic self.assertEqual('z1', nics[9]) shutil.rmtree(tmpdir) shutil.rmtree(tmp_pci_dir)
def _numbered_nics(nic_mapping=None): mapping = nic_mapping or {} global _NUMBERED_NICS if _NUMBERED_NICS: return _NUMBERED_NICS _NUMBERED_NICS = {} count = 0 active_nics = utils.ordered_active_nics() for nic in active_nics: count += 1 nic_alias = "nic%i" % count nic_mapped = mapping.get(nic_alias, nic) # The mapping is either invalid, or specifies a mac if nic_mapped not in active_nics: for active in active_nics: try: active_mac = utils.interface_mac(active) except IOError: continue if nic_mapped == active_mac: logger.debug("%s matches device %s" % (nic_mapped, active)) nic_mapped = active break else: # The mapping can't specify a non-active or non-existent nic logger.warning('interface %s is not in an active nic (%s)' % (nic_mapped, ', '.join(active_nics))) continue # Duplicate mappings are not allowed if nic_mapped in _NUMBERED_NICS.values(): msg = ('interface %s already mapped, ' 'check mapping file for duplicates' % nic_mapped) raise InvalidConfigException(msg) _NUMBERED_NICS[nic_alias] = nic_mapped logger.info("%s mapped to: %s" % (nic_alias, nic_mapped)) if not _NUMBERED_NICS: logger.warning('No active nics found.') return _NUMBERED_NICS
def test_ordered_active_nics_with_dpdk_mapping_of_vf(self): tmpdir = tempfile.mkdtemp() self.stub_out('os_net_config.common.SYS_CLASS_NET', tmpdir) tmp_pci_dir = tempfile.mkdtemp() self.stub_out('os_net_config.common._SYS_BUS_PCI_DEV', tmp_pci_dir) physfn_path = common._SYS_BUS_PCI_DEV + '/0000:05:01.1/physfn' os.makedirs(physfn_path) def test_is_available_nic(interface_name, check_active): return True self.stub_out('os_net_config.utils._is_available_nic', test_is_available_nic) utils._update_dpdk_map('eth2_0', '0000:06:01.1', 'AA:02:03:04:05:FE', 'vfio-pci') utils.update_sriov_vf_map('eth2', 0, 'eth2_0') nics = utils.ordered_active_nics() self.assertEqual(len(nics), 0) shutil.rmtree(tmpdir) shutil.rmtree(tmp_pci_dir)
def get_uplinks_and_chassisid(): """Get uplinks and chassis_id in RHOSP environment. :returns: a list of uplinks names and one chassis_id which is the first active nic's mac address. """ intf_indexes = [] while True: if not os.path.isfile(NET_CONF_PATH): time.sleep(1) continue try: json_data = open(NET_CONF_PATH).read() data = jsonutils.loads(json_data) except ValueError: time.sleep(1) continue network_config = data.get('network_config') for config in network_config: if config.get('type') != 'ovs_bridge': continue if config.get('name') != 'br-ex': continue members = config.get('members') for member in members: if member.get('type') not in SUPPORTED_BOND: continue nics = member.get('members') for nic in nics: if nic.get('type') != 'interface': continue nic_name = nic.get('name') indexes = map(int, re.findall(r'\d+', nic_name)) if len(indexes) == 1 and nic_name.startswith("nic"): intf_indexes.append(str(indexes[0] - 1)) else: intf_indexes.append(str(nic_name)) break break break intfs = [] chassis_id = "00:00:00:00:00:00" at_least_one_nic_ready = False while True: # get active interfaces from os_net_config active_intfs = utils.ordered_active_nics() intf_len = len(active_intfs) if intf_len != 0: chassis_id = get_mac_str(active_intfs[0]) intfs = [] for index in intf_indexes: try: idx = int(index) if idx < intf_len: intfs.append(active_intfs[idx]) at_least_one_nic_ready = True except ValueError: intfs.append(index) at_least_one_nic_ready = True if at_least_one_nic_ready: break # if no nics found active, retry in a sec LOG.syslog("LLDP has no active uplinks %s" % intfs) time.sleep(1) return intfs, chassis_id
def get_network_interface_map(): """Get interface map for bonds and bridges relevant on this RHOSP node :return: returns a mapping of network interfaces with its parent being a bridge or bond. syntax: { 'bridge_or_bond_name': { 'type': 'bond or bridge type', 'lacp': False (boolean, defaults to False), 'members': [ list of interfaces ] } } sample output of a mix of bonds and bridges: { u 'bond_api': { 'type': 'linux_bond',, 'lacp': True, 'members': ['p1p1'] }, u 'br-link': { 'type': 'ovs_bridge', 'lacp': False, 'members': ['p1p2'] }, u 'br-ex': { 'type': 'ovs_bridge', 'lacp': True, 'members': ['p1p1', 'p1p2'] } } """ intf_map = {} while True: if not os.path.isfile(NET_CONF_PATH): time.sleep(1) continue try: json_data = open(NET_CONF_PATH).read() data = jsonutils.loads(json_data) except ValueError: time.sleep(1) continue network_config = data.get('network_config') for config in network_config: config_type = config.get('type') if config_type == 'ovs_bridge': bridge_name = config.get('name').encode('ascii', 'ignore') members = config.get('members') for member in members: # member can be a bond or single interface in case of # ovs_bridge on DPDK controller member_type = member.get('type') if member_type == 'interface': intf_index = _get_intf_index( member.get('name').encode('ascii', 'ignore')) add_intf_to_map(intf_map=intf_map, bridge_or_bond=bridge_name, config_type='ovs_bridge', intf_index=intf_index) break elif member_type in SUPPORTED_BOND: nics = member.get('members') for nic in nics: if nic.get('type') != 'interface': continue intf_index = _get_intf_index( nic.get('name').encode('ascii', 'ignore')) add_intf_to_map(intf_map=intf_map, bridge_or_bond=bridge_name, config_type='ovs_bridge', intf_index=intf_index, lacp=True) break else: # either a vlan type interface or unsupported type continue elif config_type == 'linux_bond': bond_name = config.get('name').encode('ascii', 'ignore') members = config.get('members') for nic in members: if nic.get('type') != 'interface': continue intf_index = _get_intf_index( nic.get('name').encode('ascii', 'ignore')) add_intf_to_map(intf_map=intf_map, bridge_or_bond=bond_name, config_type='linux_bond', intf_index=intf_index) elif config_type == 'ovs_user_bridge': bridge_name = config.get('name').encode('ascii', 'ignore') members = config.get('members') for nic in members: nic_type = nic.get('type') if nic_type == 'ovs_dpdk_port': intf_name = nic.get('name').encode('ascii', 'ignore') add_intf_to_map(intf_map=intf_map, bridge_or_bond=bridge_name, config_type='ovs_user_bridge', intf_index=intf_name) break elif nic_type == 'ovs_dpdk_bond': bond_interfaces = nic.get('members') for bond_intf in bond_interfaces: if bond_intf.get('type') != 'ovs_dpdk_port': LOG.syslog("DPDK ovs_dpdk_bond has NON " "ovs_dpdk_port %s" % bond_intf.get('name')) continue intf_name = (bond_intf.get('name').encode( 'ascii', 'ignore')) add_intf_to_map(intf_map=intf_map, bridge_or_bond=bridge_name, config_type='ovs_user_bridge', intf_index=intf_name, lacp=True) else: continue break # get active interfaces from os_net_config active_intfs = utils.ordered_active_nics() intf_len = len(active_intfs) # use the intf_map and work out the chassisid for br_or_bond in intf_map: if intf_map[br_or_bond]['config_type'] == 'ovs_user_bridge': # do not try to map interface name with kernel entries # ovs_user_bridge is used for DPDK compute nodes, interfaces are # owned by DPDK driver and not kernel network driver continue if 'members' in intf_map[br_or_bond]: intfs = [] for index in intf_map[br_or_bond]['members']: try: idx = int(index) if idx < intf_len: intfs.append(active_intfs[idx]) except ValueError: intfs.append(index) intf_map[br_or_bond]['members'] = intfs LOG.syslog("Network interface map is %s" % intf_map) return intf_map