In this mode the guest contains a Virtual network device along with a SRIOV VF passed through to the guest as a pci device. --- src/conf/domain_conf.c | 37 +++++++++++++++++++++++++++++++++++-- src/conf/domain_conf.h | 5 +++++ src/libvirt_private.syms | 1 + src/util/pci.c | 2 +- src/util/pci.h | 2 ++ src/util/virnetdev.c | 40 ++++++++++++++++++++++++++++++++++++++++ src/util/virnetdev.h | 6 ++++++ 7 files changed, 90 insertions(+), 3 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 39b5cdb..e73c07d 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -1025,6 +1025,7 @@ virDomainActualNetDefFree(virDomainActualNetDefPtr def) VIR_FREE(def->data.hostdev.virtPortProfile); break; case VIR_DOMAIN_NET_TYPE_HOSTDEV_HYBRID: + VIR_FREE(def->data.hostdev.linkdev); virDomainHostdevDefClear(&def->data.hostdev.def); VIR_FREE(def->data.hostdev.virtPortProfile); break; @@ -1084,6 +1085,7 @@ void virDomainNetDefFree(virDomainNetDefPtr def) break; case VIR_DOMAIN_NET_TYPE_HOSTDEV_HYBRID: + VIR_FREE(def->data.hostdev.linkdev); virDomainHostdevDefClear(&def->data.hostdev.def); VIR_FREE(def->data.hostdev.virtPortProfile); break; @@ -4475,6 +4477,7 @@ virDomainNetDefParseXML(virCapsPtr caps, char *mode = NULL; char *linkstate = NULL; char *addrtype = NULL; + char *pfname = NULL; virNWFilterHashTablePtr filterparams = NULL; virNetDevVPortProfilePtr virtPort = NULL; virDomainActualNetDefPtr actual = NULL; @@ -4795,6 +4798,26 @@ virDomainNetDefParseXML(virCapsPtr caps, hostdev, flags) < 0) { goto error; } + if (hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) { + if (virNetDevGetPhysicalFunctionFromVfPciAddr(hostdev->source.subsys.u.pci.domain, + hostdev->source.subsys.u.pci.bus, + hostdev->source.subsys.u.pci.slot, + hostdev->source.subsys.u.pci.function, + &pfname) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Could not get Physical Function of the hostdev")); + goto error; + } + } + if (pfname != NULL) + def->data.hostdev.linkdev = strdup(pfname); + else { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Linkdev is required in %s mode"), + virDomainNetTypeToString(def->type)); + goto error; + } + def->data.hostdev.mode = VIR_NETDEV_MACVLAN_MODE_BRIDGE; def->data.hostdev.virtPortProfile = virtPort; virtPort = NULL; break; @@ -15033,11 +15056,16 @@ virDomainNetGetActualDirectDev(virDomainNetDefPtr iface) { if (iface->type == VIR_DOMAIN_NET_TYPE_DIRECT) return iface->data.direct.linkdev; + if (iface->type == VIR_DOMAIN_NET_TYPE_HOSTDEV_HYBRID) + return iface->data.hostdev.linkdev; if (iface->type != VIR_DOMAIN_NET_TYPE_NETWORK) return NULL; if (!iface->data.network.actual) return NULL; - return iface->data.network.actual->data.direct.linkdev; + if (iface->data.network.actual->type == VIR_DOMAIN_NET_TYPE_HOSTDEV_HYBRID) + return iface->data.network.actual->data.hostdev.linkdev; + else + return iface->data.network.actual->data.direct.linkdev; } int @@ -15045,11 +15073,16 @@ virDomainNetGetActualDirectMode(virDomainNetDefPtr iface) { if (iface->type == VIR_DOMAIN_NET_TYPE_DIRECT) return iface->data.direct.mode; + if (iface->type == VIR_DOMAIN_NET_TYPE_HOSTDEV_HYBRID) + return iface->data.hostdev.mode; if (iface->type != VIR_DOMAIN_NET_TYPE_NETWORK) return 0; if (!iface->data.network.actual) return 0; - return iface->data.network.actual->data.direct.mode; + if (iface->data.network.actual->type == VIR_DOMAIN_NET_TYPE_HOSTDEV_HYBRID) + return iface->data.network.actual->data.hostdev.mode; + else + return iface->data.network.actual->data.direct.mode; } virDomainHostdevDefPtr diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 7bcaee4..053c71c 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -43,6 +43,7 @@ # include "virnetdevvportprofile.h" # include "virnetdevopenvswitch.h" # include "virnetdevbandwidth.h" +# include "virnetdev.h" # include "virobject.h" # include "device_conf.h" @@ -762,6 +763,8 @@ struct _virDomainActualNetDef { virNetDevVPortProfilePtr virtPortProfile; } direct; struct { + char *linkdev; + int mode; virDomainHostdevDef def; virNetDevVPortProfilePtr virtPortProfile; } hostdev; @@ -819,6 +822,8 @@ struct _virDomainNetDef { virNetDevVPortProfilePtr virtPortProfile; } direct; struct { + char *linkdev; + int mode; virDomainHostdevDef def; virNetDevVPortProfilePtr virtPortProfile; } hostdev; diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index f752f49..fae69ef 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1366,6 +1366,7 @@ virNetDevGetMTU; virNetDevGetPhysicalFunction; virNetDevGetVLanID; virNetDevGetVirtualFunctionIndex; +virNetDevGetPhysicalFunctionFromVfPciAddr; virNetDevGetVirtualFunctionInfo; virNetDevGetVirtualFunctions; virNetDevIsOnline; diff --git a/src/util/pci.c b/src/util/pci.c index 137521b..5bf1758 100644 --- a/src/util/pci.c +++ b/src/util/pci.c @@ -803,7 +803,7 @@ pciDriverFile(char **buffer, const char *driver, const char *file) return 0; } -static int +int pciDeviceFile(char **buffer, const char *device, const char *file) { VIR_FREE(*buffer); diff --git a/src/util/pci.h b/src/util/pci.h index 8bbab07..936fee4 100644 --- a/src/util/pci.h +++ b/src/util/pci.h @@ -116,6 +116,8 @@ int pciConfigAddressToSysfsFile(struct pci_config_address *dev, int pciDeviceNetName(char *device_link_sysfs_path, char **netname); +int pciDeviceFile(char **buffer, const char *device, const char *file); + int pciSysfsFile(char *pciDeviceName, char **pci_sysfs_device_link) ATTRIBUTE_RETURN_CHECK; diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c index 8103aff..46d0cda 100644 --- a/src/util/virnetdev.c +++ b/src/util/virnetdev.c @@ -1099,6 +1099,46 @@ virNetDevGetVirtualFunctionIndex(const char *pfname, const char *vfname, } /** + * virNetDevGetPhyscialFunctionFromVfPciAddr + * + * @domain : Domain part of VF PCI addr + * @bus : Bus part of VF PCI addr + * @slot : Slot part of VF PCI addr + * @function : Function part of VF PCI addr + * @pfname : Contains sriov physical function for Vf upon + * successful return + * + * Returns 0 on success, -1 on failure + * + */ +int +virNetDevGetPhysicalFunctionFromVfPciAddr(unsigned domain, + unsigned bus, + unsigned slot, + unsigned function, + char **pfname) +{ + char *pciConfigAddr; + char *physfn_sysfs_path = NULL; + int ret = -1; + + if (pciGetDeviceAddrString(domain, bus, slot, function, + &pciConfigAddr) < 0) { + goto cleanup; + } + if (pciDeviceFile(&physfn_sysfs_path, pciConfigAddr, "physfn") < 0) { + goto cleanup; + } + ret = pciDeviceNetName(physfn_sysfs_path, pfname); + +cleanup: + VIR_FREE(pciConfigAddr); + VIR_FREE(physfn_sysfs_path); + + return ret; +} + +/** * virNetDevGetPhysicalFunction * * @ifname : name of the physical function interface name diff --git a/src/util/virnetdev.h b/src/util/virnetdev.h index 705ad9c..66b57db 100644 --- a/src/util/virnetdev.h +++ b/src/util/virnetdev.h @@ -99,6 +99,12 @@ int virNetDevGetVirtualFunctionIndex(const char *pfname, const char *vfname, ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3) ATTRIBUTE_RETURN_CHECK; +int virNetDevGetPhysicalFunctionFromVfPciAddr(unsigned domain, unsigned bus, + unsigned slot, unsigned function, + char **pfname) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3) + ATTRIBUTE_NONNULL(4) ATTRIBUTE_RETURN_CHECK; + int virNetDevGetPhysicalFunction(const char *ifname, char **pfname) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; -- 1.7.4.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list