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 | 60 +++++++++++++++++++++++++------------------
src/util/virnetdev.c | 25 ++++++++---------
src/util/virnetdev.h | 4 ++-
3 files changed, 50 insertions(+), 39 deletions(-)
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index ddd66e5..38f6d12 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -59,6 +59,7 @@
#include "dnsmasq.h"
#include "configmake.h"
#include "virnetdev.h"
+#include "pci.h"
#include "virnetdevbridge.h"
#include "virnetdevtap.h"
#include "virnetdevvportprofile.h"
@@ -2780,10 +2781,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) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Could not get Virtual functions on %s"),
netdef->forwardPfs->dev);
@@ -2805,18 +2807,34 @@ 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_BRIDGE) ||
+ (netdef->forwardType == VIR_NETWORK_FORWARD_PRIVATE) ||
+ (netdef->forwardType == VIR_NETWORK_FORWARD_VEPA) ||
+ (netdef->forwardType == VIR_NETWORK_FORWARD_PASSTHROUGH)) {
+ netdef->forwardIfs[ii].type = VIR_NETWORK_FORWARD_HOSTDEV_DEVICE_NETDEV;
+ if(vfname[ii]) {
+ netdef->forwardIfs[ii].device.dev = strdup(vfname[ii]);
+ if (!netdef->forwardIfs[ii].device.dev) {
+ virReportOOMError();
+ goto finish;
+ }
+ }
+ else {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Direct mode types requires interface
names"));
+ goto finish;
+ }
}
}
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;
}
@@ -3008,31 +3026,23 @@ networkAllocateActualDevice(virDomainNetDefPtr iface)
} else {
/* pick an interface from the pool */
+ if ((netdef->nForwardPfs > 0) && (netdef->nForwardIfs <=
0)) {
+ if ((networkCreateInterfacePool(netdef)) < 0) {
+ goto error;
+ }
+ }
+
/* PASSTHROUGH mode, and PRIVATE Mode + 802.1Qbh both
* require exclusive access to a device, so current
* connections count must be 0. Other modes can share, so
* just search for the one with the lowest number of
* connections.
*/
- if (netdef->forwardType == VIR_NETWORK_FORWARD_PASSTHROUGH) {
- if ((netdef->nForwardPfs > 0) && (netdef->nForwardIfs
<= 0)) {
- if ((networkCreateInterfacePool(netdef)) < 0) {
- goto error;
- }
- }
-
- /* pick first dev with 0 connections */
-
- for (ii = 0; ii < netdef->nForwardIfs; ii++) {
- if (netdef->forwardIfs[ii].connections == 0) {
- dev = &netdef->forwardIfs[ii];
- break;
- }
- }
- } else if ((netdef->forwardType == VIR_NETWORK_FORWARD_PRIVATE)
&&
- iface->data.network.actual->virtPortProfile &&
-
(iface->data.network.actual->virtPortProfile->virtPortType
- == VIR_NETDEV_VPORT_PROFILE_8021QBH)) {
+ if ((netdef->forwardType == VIR_NETWORK_FORWARD_PASSTHROUGH) ||
+ ((netdef->forwardType == VIR_NETWORK_FORWARD_PRIVATE) &&
+ iface->data.network.actual->virtPortProfile &&
+ (iface->data.network.actual->virtPortProfile->virtPortType
+ == VIR_NETDEV_VPORT_PROFILE_8021QBH))) {
/* pick first dev with 0 connections */
for (ii = 0; ii < netdef->nForwardIfs; ii++) {
diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c
index 25bdf01..f9eba1a 100644
--- a/src/util/virnetdev.c
+++ b/src/util/virnetdev.c
@@ -29,6 +29,7 @@
#include "command.h"
#include "memory.h"
#include "pci.h"
+#include "logging.h"
#include <sys/ioctl.h>
#ifdef HAVE_NET_IF_H
@@ -981,18 +982,18 @@ 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;
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;
@@ -1003,10 +1004,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"));
@@ -1019,20 +1020,17 @@ 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;
+ VIR_INFO("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);
+ }
VIR_FREE(pf_sysfs_device_link);
VIR_FREE(pci_sysfs_device_link);
VIR_FREE(pciConfigAddr);
@@ -1169,6 +1167,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 c663e49..705ad9c 100644
--- a/src/util/virnetdev.h
+++ b/src/util/virnetdev.h
@@ -26,6 +26,7 @@
# include "virsocketaddr.h"
# include "virnetlink.h"
# include "virmacaddr.h"
+# include "pci.h"
int virNetDevExists(const char *brname)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK;
@@ -103,9 +104,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