Example #1
0
    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,
        }
Example #2
0
    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
Example #3
0
    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())
Example #5
0
    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}
Example #6
0
    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
Example #7
0
    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
Example #8
0
    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())
Example #9
0
    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())