The network pool should be able to keep track of both, network device
names nad PCI addresses, and return the appropriate one in the actualDevice
when networkAllocateActualDevice is called.
Signed-off-by: Shradha Shah <sshah(a)solarflare.com>
---
src/network/bridge_driver.c | 33 +++++++++++++++++++++++++++------
src/util/virnetdev.c | 29 ++++++++++++++++-------------
src/util/virnetdev.h | 4 +++-
3 files changed, 46 insertions(+), 20 deletions(-)
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index 630a655..6ce41b5 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -60,6 +60,7 @@
#include "configmake.h"
#include "ignore-value.h"
#include "virnetdev.h"
+#include "pci.h"
#include "virnetdevbridge.h"
#include "virnetdevtap.h"
@@ -2740,10 +2741,11 @@ static int
networkCreateInterfacePool(virNetworkDefPtr netdef) {
unsigned int num_virt_fns = 0;
char **vfname = NULL;
+ struct pci_config_address **virt_fns;
int ret = -1, ii = 0;
if ((virNetDevGetVirtualFunctions(netdef->forwardPfs->dev,
- &vfname, &num_virt_fns)) < 0) {
+ &vfname, &virt_fns, &num_virt_fns))
< 0) {
networkReportError(VIR_ERR_INTERNAL_ERROR,
_("Could not get Virtual functions on %s"),
netdef->forwardPfs->dev);
@@ -2765,19 +2767,38 @@ networkCreateInterfacePool(virNetworkDefPtr netdef) {
netdef->nForwardIfs = num_virt_fns;
for (ii = 0; ii < netdef->nForwardIfs; ii++) {
- netdef->forwardIfs[ii].device.dev = strdup(vfname[ii]);
- if (!netdef->forwardIfs[ii].device.dev) {
- virReportOOMError();
- goto finish;
+ if (netdef->forwardType == VIR_NETWORK_FORWARD_PASSTHROUGH) {
+ if(vfname[ii]) {
+ netdef->forwardIfs[ii].device.dev = strdup(vfname[ii]);
+ if (!netdef->forwardIfs[ii].device.dev) {
+ virReportOOMError();
+ goto finish;
+ }
+ }
+ else {
+ networkReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Passthrough mode requires interface
names"));
+ goto finish;
+ }
+ }
+ else if (netdef->forwardType == VIR_NETWORK_FORWARD_HOSTDEV) {
+ netdef->forwardIfs[ii].type = VIR_NETWORK_FORWARD_HOSTDEV_DEVICE_PCI;
/*Assuming PCI as VF's are PCI devices */
+ netdef->forwardIfs[ii].device.pci.domain = virt_fns[ii]->domain;
+ netdef->forwardIfs[ii].device.pci.bus = virt_fns[ii]->bus;
+ netdef->forwardIfs[ii].device.pci.slot = virt_fns[ii]->slot;
+ netdef->forwardIfs[ii].device.pci.function = virt_fns[ii]->function;
}
netdef->forwardIfs[ii].usageCount = 0;
}
ret = 0;
finish:
- for (ii = 0; ii < num_virt_fns; ii++)
+ for (ii = 0; ii < num_virt_fns; ii++) {
VIR_FREE(vfname[ii]);
+ VIR_FREE(virt_fns[ii]);
+ }
VIR_FREE(vfname);
+ VIR_FREE(virt_fns);
return ret;
}
diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c
index d53352f..a59012f 100644
--- a/src/util/virnetdev.c
+++ b/src/util/virnetdev.c
@@ -983,18 +983,19 @@ virNetDevSysfsDeviceFile(char **pf_sysfs_device_link, const char
*ifname,
int
virNetDevGetVirtualFunctions(const char *pfname,
char ***vfname,
+ struct pci_config_address ***virt_fns,
unsigned int *n_vfname)
{
int ret = -1, i;
char *pf_sysfs_device_link = NULL;
char *pci_sysfs_device_link = NULL;
- struct pci_config_address **virt_fns;
+// struct pci_config_address **virt_fns;
char *pciConfigAddr;
if (virNetDevSysfsFile(&pf_sysfs_device_link, pfname, "device") <
0)
return ret;
- if (pciGetVirtualFunctions(pf_sysfs_device_link, &virt_fns,
+ if (pciGetVirtualFunctions(pf_sysfs_device_link, virt_fns,
n_vfname) < 0)
goto cleanup;
@@ -1005,10 +1006,10 @@ virNetDevGetVirtualFunctions(const char *pfname,
for (i = 0; i < *n_vfname; i++)
{
- if (pciGetDeviceAddrString(virt_fns[i]->domain,
- virt_fns[i]->bus,
- virt_fns[i]->slot,
- virt_fns[i]->function,
+ if (pciGetDeviceAddrString((*virt_fns)[i]->domain,
+ (*virt_fns)[i]->bus,
+ (*virt_fns)[i]->slot,
+ (*virt_fns)[i]->function,
&pciConfigAddr) < 0) {
virReportSystemError(ENOSYS, "%s",
_("Failed to get PCI Config Address
String"));
@@ -1021,20 +1022,21 @@ virNetDevGetVirtualFunctions(const char *pfname,
}
if (pciDeviceNetName(pci_sysfs_device_link, &((*vfname)[i])) < 0) {
- virReportSystemError(ENOSYS, "%s",
- _("Failed to get interface name of the VF"));
- goto cleanup;
+ virReportSystemError(ENODATA, "%s",
+ _("VF does not have an interface name"));
}
}
ret = 0;
cleanup:
- if (ret < 0)
+ if (ret < 0) {
VIR_FREE(*vfname);
- for (i = 0; i < *n_vfname; i++)
- VIR_FREE(virt_fns[i]);
- VIR_FREE(virt_fns);
+ VIR_FREE(*virt_fns);
+ }
+ //for (i = 0; i < *n_vfname; i++)
+ // VIR_FREE(virt_fns[i]);
+ //VIR_FREE(virt_fns);
VIR_FREE(pf_sysfs_device_link);
VIR_FREE(pci_sysfs_device_link);
VIR_FREE(pciConfigAddr);
@@ -1171,6 +1173,7 @@ cleanup:
int
virNetDevGetVirtualFunctions(const char *pfname ATTRIBUTE_UNUSED,
char ***vfname ATTRIBUTE_UNUSED,
+ struct pci_config_address ***virt_fns ATTRIBUTE_UNUSED,
unsigned int *n_vfname ATTRIBUTE_UNUSED)
{
virReportSystemError(ENOSYS, "%s",
diff --git a/src/util/virnetdev.h b/src/util/virnetdev.h
index 660d2db..9be367c 100644
--- a/src/util/virnetdev.h
+++ b/src/util/virnetdev.h
@@ -25,6 +25,7 @@
# include "virsocketaddr.h"
# include "virnetlink.h"
+# include "pci.h"
int virNetDevExists(const char *brname)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK;
@@ -102,9 +103,10 @@ int virNetDevGetPhysicalFunction(const char *ifname, char **pfname)
int virNetDevGetVirtualFunctions(const char *pfname,
char ***vfname,
+ struct pci_config_address ***virt_fns,
unsigned int *n_vfname)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3)
- ATTRIBUTE_RETURN_CHECK;
+ ATTRIBUTE_NONNULL(4) ATTRIBUTE_RETURN_CHECK;
int virNetDevLinkDump(const char *ifname, int ifindex,
struct nlattr **tb,
--
1.7.4.4