def _get_ethernet_interface(self, host, iface, ifname): port = interface.get_interface_port(self.context, iface) if interface.is_a_mellanox_device(self.context, iface): # Mellanox devices use an ibverbs enumerated device name, therefore # use the MAC address to identify the device. device_name = "class=eth,mac=%s" % iface['imac'] else: device_name = str(port.pciaddr) rxq_count = len(self.context["_ovs_cpus"]) attributes = [ "options:dpdk-devargs=%s" % device_name, "options:n_rxq=%d" % rxq_count, "mtu_request=%d" % iface['imtu'] ] # TODO(mpeters): set other_config:pmd-rxq-affinity to pin receive # queues to specific PMD cores iftype = 'dpdk' return { 'name': ifname, 'type': iftype, 'attributes': attributes, }
def _get_lldp_port(self, iface, lldp_brname, ovs_ifname=None): interfaces = [] port = interface.get_interface_port(self.context, iface) # Limit port name length to the maximum supported by ovs-ofctl to # reference a port with a name rather than ofport number # when creating flows. port_name_len = constants.LLDP_OVS_PORT_NAME_LEN uuid_len = port_name_len - len(constants.LLDP_OVS_PORT_PREFIX) port_name = '{}{}'.format(constants.LLDP_OVS_PORT_PREFIX, port.uuid[:uuid_len]) if ovs_ifname: interfaces.append(self._get_lldp_interface(port_name, ovs_ifname)) else: interfaces.append( self._get_lldp_interface(port_name, iface['name'])) port = { 'name': port_name, 'bridge': lldp_brname, 'interfaces': interfaces, } return port
def _get_pci_pt_whitelist(self, host): # Process all configured PCI passthrough interfaces and add them to # the list of devices to whitelist devices = [] for iface in self.context['interfaces'].values(): if iface['ifclass'] in [constants.INTERFACE_CLASS_PCI_PASSTHROUGH]: port = interface.get_interface_port(self.context, iface) dnames = interface._get_datanetwork_names(self.context, iface) device = { 'address': port['pciaddr'], 'physical_network': dnames } LOG.debug("_get_pci_pt_whitelist device=%s" % device) devices.append(device) # Process all enabled PCI devices configured for PT and SRIOV and # add them to the list of devices to whitelist. # Since we are now properly initializing the qat driver and # restarting sysinv, we need to add VF devices to the regular # whitelist instead of the sriov whitelist pci_devices = self.dbapi.pci_device_get_by_host(host.id) for pci_device in pci_devices: if pci_device.enabled: device = { 'address': pci_device.pciaddr, 'class_id': pci_device.pclass_id } devices.append(device) return json.dumps(devices)
def _get_pcidp_network_resources_by_ifclass(self, ifclass): resources = {} interfaces = self._get_network_interfaces_by_class(ifclass) for iface in interfaces: port = interface.get_interface_port(self.context, iface) datanets = interface.get_interface_datanets(self.context, iface) for datanet in datanets: dn_name = datanet['name'].strip() resource = resources.get(dn_name, None) if resource: # Add to the list of pci addreses for this data network resource['rootDevices'].append(port['pciaddr']) else: device_type = iface.get('sriov_vf_driver', None) if not device_type: device_type = constants.SRIOV_DRIVER_TYPE_NETDEVICE # PCI addresses don't exist for this data network yet resource = { dn_name: { "resourceName": "{}_net_{}".format(ifclass, dn_name).replace("-", "_"), "deviceType": device_type, "rootDevices": [port['pciaddr']], "sriovMode": ifclass == constants.INTERFACE_CLASS_PCI_SRIOV } } resources.update(resource) return list(resources.values())
def _get_ethernet_device(self, iface): if interface.is_a_mellanox_device(self.context, iface): # Mellanox devices are not bound to the DPDK driver return None port = interface.get_interface_port(self.context, iface) pci_addr = self.quoted_str(port.pciaddr) return {'pci_addr': pci_addr}
def get_host_config(self, host): if (constants.CONTROLLER not in utils.get_personalities(host) and constants.WORKER not in utils.get_personalities(host)): return {} device_mappings = [] for iface in self.context['interfaces'].values(): if (iface['ifclass'] in [constants.INTERFACE_CLASS_PCI_SRIOV]): port = interface.get_interface_port(self.context, iface) datanets = interface.get_interface_datanets( self.context, iface) for dnet in datanets: device_mappings.append( "%s:%s" % (dnet['name'], port['name'])) LOG.debug("get_host_config device_mappings=%s" % device_mappings) config = { 'neutron::agents::ml2::sriov::physical_device_mappings': device_mappings, } if host.personality == constants.CONTROLLER: service_parameters = self._get_service_parameter_configs( constants.SERVICE_TYPE_NETWORK) if service_parameters is None: return config # check if neutron bgp speaker is configured if host.hostname == constants.CONTROLLER_0_HOSTNAME: bgp_router_id = self._service_parameter_lookup_one( service_parameters, constants.SERVICE_PARAM_SECTION_NETWORK_BGP, constants.SERVICE_PARAM_NAME_BGP_ROUTER_ID_C0, None) else: bgp_router_id = self._service_parameter_lookup_one( service_parameters, constants.SERVICE_PARAM_SECTION_NETWORK_BGP, constants.SERVICE_PARAM_NAME_BGP_ROUTER_ID_C1, None) if bgp_router_id is not None: config.update({ 'openstack::neutron::params::bgp_router_id': bgp_router_id}) return config
def _get_pci_sriov_whitelist(self, host): # Process all configured SRIOV passthrough interfaces and add them to # the list of devices to whitelist devices = [] for iface in self.context['interfaces'].values(): if iface['ifclass'] in [constants.INTERFACE_CLASS_PCI_SRIOV]: port = interface.get_interface_port(self.context, iface) dnames = interface._get_datanetwork_names(self.context, iface) device = { 'address': port['pciaddr'], 'physical_network': dnames, 'sriov_numvfs': iface['sriov_numvfs'] } LOG.debug("_get_pci_sriov_whitelist device=%s" % device) devices.append(device) return json.dumps(devices) if devices else None
def _get_pcidp_network_resources_by_ifclass(self, ifclass): resources = {} interfaces = self._get_network_interfaces_by_class(ifclass) for iface in interfaces: if ifclass == constants.INTERFACE_CLASS_PCI_SRIOV: port = interface.get_sriov_interface_port(self.context, iface) else: port = interface.get_interface_port(self.context, iface) if not port: continue datanets = interface.get_interface_datanets(self.context, iface) for datanet in datanets: dn_name = datanet['name'].strip() resource = resources.get(dn_name, None) if not resource: resource = { "resourceName": "{}_net_{}".format(ifclass, dn_name).replace("-", "_"), "selectors": { "vendors": [], "devices": [], "drivers": [], "pfNames": [] } } vendor = self._get_pcidp_vendor_id(port) if not vendor: LOG.error("Failed to get vendor id for pci device %s", port['pciaddr']) continue device = self._get_pcidp_device_id(port, ifclass) if not device: LOG.error("Failed to get device id for pci device %s", port['pciaddr']) continue driver = self._get_pcidp_driver(port, iface, ifclass) if not driver: LOG.error("Failed to get driver for pci device %s", port['pciaddr']) continue vendor_list = resource['selectors']['vendors'] if vendor not in vendor_list: vendor_list.append(vendor) device_list = resource['selectors']['devices'] if device not in device_list: device_list.append(device) driver_list = resource['selectors']['drivers'] if driver not in driver_list: driver_list.append(driver) pf_name_list = resource['selectors']['pfNames'] if port['name'] not in pf_name_list: pf_name_list.append(port['name']) if interface.is_a_mellanox_device(self.context, iface): resource['selectors']['isRdma'] = True resources[dn_name] = resource return list(resources.values())
def _get_pcidp_network_resources_by_ifclass(self, ifclass): resources = {} interfaces = self._get_network_interfaces_by_class(ifclass) for iface in interfaces: if ifclass == constants.INTERFACE_CLASS_PCI_SRIOV: port = interface.get_sriov_interface_port(self.context, iface) else: port = interface.get_interface_port(self.context, iface) if not port: continue datanets = interface.get_interface_datanets(self.context, iface) for datanet in datanets: dn_name = datanet['name'].strip() resource = resources.get(dn_name, None) if not resource: resource = { "resourceName": "{}_net_{}".format(ifclass, dn_name).replace("-", "_"), "selectors": { "vendors": [], "devices": [], "drivers": [], "pfNames": [] } } vendor = self._get_pcidp_vendor_id(port) if not vendor: LOG.error("Failed to get vendor id for pci device %s", port['pciaddr']) continue device = self._get_pcidp_device_id(port, ifclass) if not device: LOG.error("Failed to get device id for pci device %s", port['pciaddr']) continue driver = self._get_pcidp_driver(port, iface, ifclass) if not driver: LOG.error("Failed to get driver for pci device %s", port['pciaddr']) continue vendor_list = resource['selectors']['vendors'] if vendor not in vendor_list: vendor_list.append(vendor) device_list = resource['selectors']['devices'] if device not in device_list: device_list.append(device) driver_list = resource['selectors']['drivers'] if driver not in driver_list: driver_list.append(driver) pf_name_list = resource['selectors']['pfNames'] if ifclass == constants.INTERFACE_CLASS_PCI_SRIOV: # In sriov case, we need specify each VF for resource pool # Get VF addresses assigned to this logical VF interface vf_addr_list = [] all_vf_addr_list = [] vf_addrs = port.get('sriov_vfs_pci_address', None) if vf_addrs: all_vf_addr_list = vf_addrs.split(',') vf_addr_list = interface.get_sriov_interface_vf_addrs( self.context, iface, all_vf_addr_list) vfnolst = [ utils.get_sriov_vf_index(addr, all_vf_addr_list) for addr in vf_addr_list ] vfnolst = [str(vfno) for vfno in vfnolst] vfnolist_str = ",".join(vfnolst) if vfnolist_str: # concat into the form of 'ens785f0#0,2,7,9' pfname_with_vfs = "%s#%s" % (port['name'], vfnolist_str) pf_name_list.append(pfname_with_vfs) else: # error case, cannot find the vf numbers in sriov case LOG.error("Failed to get vf numbers for pci device %s", port['name']) continue else: if port['name'] not in pf_name_list: pf_name_list.append(port['name']) if interface.is_a_mellanox_device(self.context, iface): resource['selectors']['isRdma'] = True resources[dn_name] = resource return list(resources.values())