diff options
author | Dmitrii Shcherbakov <dmitrii.shcherbakov@canonical.com> | 2022-01-16 21:53:49 +0300 |
---|---|---|
committer | Dmitrii Shcherbakov <dmitrii.shcherbakov@canonical.com> | 2022-02-07 23:38:41 +0300 |
commit | 1f71696ecc2cd1abfc30f2f03f3c4857e51b9fbf (patch) | |
tree | bbe6691ccc6e023cb6fb3a200096dfc51243b13c /nova/network | |
parent | b6fe7521afa8d42febc68f5f79782f7bcc3b568f (diff) | |
download | nova-1f71696ecc2cd1abfc30f2f03f3c4857e51b9fbf.tar.gz |
[yoga] Include pf mac and vf num in port updates
Retrieve PF mac and VF logical number at runtime for
a given VF PCI address and include them in port updates to Neutron.
Implements: blueprint integration-with-off-path-network-backends
Change-Id: I83a128a260acdd8bf78fede566af6881b8b82a9c
Diffstat (limited to 'nova/network')
-rw-r--r-- | nova/network/neutron.py | 54 |
1 files changed, 48 insertions, 6 deletions
diff --git a/nova/network/neutron.py b/nova/network/neutron.py index 294ccaebbe..cd8450ef71 100644 --- a/nova/network/neutron.py +++ b/nova/network/neutron.py @@ -668,7 +668,8 @@ class API: # information in the binding profile. for profile_key in ('pci_vendor_info', 'pci_slot', constants.ALLOCATION, 'arq_uuid', - 'physical_network', 'card_serial_number'): + 'physical_network', 'card_serial_number', + 'vf_num', 'pf_mac_address'): if profile_key in port_profile: del port_profile[profile_key] port_req_body['port'][constants.BINDING_PROFILE] = port_profile @@ -1504,6 +1505,50 @@ class API: raise exception.PortBindingDeletionFailed( port_id=port_id, host=host) + def _get_vf_pci_device_profile(self, pci_dev): + """Get VF-specific fields to add to the PCI device profile. + + This data can be useful, e.g. for off-path networking backends that + need to do the necessary plumbing in order to set a VF up for packet + forwarding. + """ + vf_profile: ty.Dict[str, ty.Union[str, int]] = {} + try: + pf_mac = pci_utils.get_mac_by_pci_address(pci_dev.parent_addr) + except (exception.PciDeviceNotFoundById) as e: + LOG.debug( + "Could not determine PF MAC address for a VF with" + " addr %(addr)s, error: %(e)s", + {"addr": pci_dev.address, "e": e}) + # NOTE(dmitriis): we do not raise here since not all PFs will + # have netdevs even when VFs are netdevs (see LP: #1915255). The + # rest of the fields (VF number and card serial) are not enough + # to fully identify the VF so they are not populated either. + return vf_profile + try: + vf_num = pci_utils.get_vf_num_by_pci_address( + pci_dev.address) + except exception.PciDeviceNotFoundById as e: + # This is unlikely to happen because the kernel has a common SR-IOV + # code that creates physfn symlinks, however, it would be better + # to avoid raising an exception here and simply warn an operator + # that things did not go as planned. + LOG.warning( + "Could not determine a VF logical number for a VF" + " with addr %(addr)s, error: %(e)s", { + "addr": pci_dev.address, "e": e}) + return vf_profile + card_serial_number = pci_dev.card_serial_number + if card_serial_number: + vf_profile.update({ + 'card_serial_number': card_serial_number + }) + vf_profile.update({ + 'pf_mac_address': pf_mac, + 'vf_num': vf_num, + }) + return vf_profile + def _get_pci_device_profile(self, pci_dev): dev_spec = self.pci_whitelist.get_devspec(pci_dev) if dev_spec: @@ -1516,11 +1561,8 @@ class API: ), } if pci_dev.dev_type == obj_fields.PciDeviceType.SRIOV_VF: - card_serial_number = pci_dev.card_serial_number - if card_serial_number: - dev_profile.update({ - 'card_serial_number': card_serial_number - }) + dev_profile.update( + self._get_vf_pci_device_profile(pci_dev)) return dev_profile raise exception.PciDeviceNotFound(node_id=pci_dev.compute_node_id, |