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/conf/network_conf.c | 55 ++++++++++++++++++++++++++++++++++++++++++-
src/conf/network_conf.h | 10 +++++++-
src/network/bridge_driver.c | 47 ++++++++++++++++++++++++++++++++++++
src/util/pci.c | 5 +++-
src/util/virnetdev.c | 6 +---
5 files changed, 116 insertions(+), 7 deletions(-)
diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c
index 6515efe..8fcba16 100644
--- a/src/conf/network_conf.c
+++ b/src/conf/network_conf.c
@@ -98,6 +98,12 @@ virPortGroupDefClear(virPortGroupDefPtr def)
}
static void
+virNetworkForwardPfDefClear(virNetworkForwardPfDefPtr def)
+{
+ VIR_FREE(def->dev);
+}
+
+static void
virNetworkForwardIfDefClear(virNetworkForwardIfDefPtr def)
{
VIR_FREE(def->dev);
@@ -163,7 +169,7 @@ void virNetworkDefFree(virNetworkDefPtr def)
VIR_FREE(def->domain);
for (ii = 0 ; ii < def->nForwardPfs && def->forwardPfs ; ii++) {
- virNetworkForwardIfDefClear(&def->forwardPfs[ii]);
+ virNetworkForwardPfDefClear(&def->forwardPfs[ii]);
}
VIR_FREE(def->forwardPfs);
@@ -925,6 +931,44 @@ error:
return result;
}
+/* Function to compare strings with wildcard strings*/
+/* When editing this function also edit the one in src/network/bridge_driver.c*/
+static int
+wildcmp(const char *wild, const char *string)
+{
+/* Written by Jack Handy - <A
href="mailto:jakkhandy@hotmail.com">jakkhandy@hotmail.com</A>*/
+ const char *cp = NULL, *mp = NULL;
+
+ while ((*string) && (*wild != '*')) {
+ if ((*wild != *string) && (*wild != '?')) {
+ return 0;
+ }
+ wild++;
+ string++;
+ }
+
+ while (*string) {
+ if (*wild == '*') {
+ if (!*++wild) {
+ return 1;
+ }
+ mp = wild;
+ cp = string+1;
+ } else if ((*wild == *string) || (*wild == '?')) {
+ wild++;
+ string++;
+ } else {
+ wild = mp;
+ string = cp++;
+ }
+ }
+
+ while (*wild == '*') {
+ wild++;
+ }
+ return !*wild;
+}
+
static virNetworkDefPtr
virNetworkDefParseXML(xmlXPathContextPtr ctxt)
{
@@ -1170,6 +1214,15 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt)
def->nForwardIfs++;
}
}
+ int i;
+ for (i = 0; i < nForwardIfs; i++) {
+ if (wildcmp("????:??:??.?", def->forwardIfs[i].dev)) {
+ def->forwardIfs[i].isPciAddr = true;
+ } else {
+ def->forwardIfs[i].isPciAddr = false;
+ }
+ }
+
VIR_FREE(forwardDev);
VIR_FREE(forwardPfNodes);
VIR_FREE(forwardIfNodes);
diff --git a/src/conf/network_conf.h b/src/conf/network_conf.h
index 4339a69..b205cb0 100644
--- a/src/conf/network_conf.h
+++ b/src/conf/network_conf.h
@@ -133,6 +133,14 @@ typedef virNetworkForwardIfDef *virNetworkForwardIfDefPtr;
struct _virNetworkForwardIfDef {
char *dev; /* name of device */
int usageCount; /* how many guest interfaces are bound to this device? */
+ bool isPciAddr; /* Differentiate a VF based on interface name or pci addr*/
+};
+
+typedef struct _virNetworkForwardPfDef virNetworkForwardPfDef;
+typedef virNetworkForwardPfDef *virNetworkForwardPfDefPtr;
+struct _virNetworkForwardPfDef {
+ char *dev; /* name of device */
+ int usageCount; /* how many guest interfaces are bound to this device? */
};
typedef struct _virPortGroupDef virPortGroupDef;
@@ -163,7 +171,7 @@ struct _virNetworkDef {
* interfaces), they will be listed here.
*/
size_t nForwardPfs;
- virNetworkForwardIfDefPtr forwardPfs;
+ virNetworkForwardPfDefPtr forwardPfs;
size_t nForwardIfs;
virNetworkForwardIfDefPtr forwardIfs;
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index d82212f..41e3a49 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -87,6 +87,43 @@ struct network_driver {
char *logDir;
};
+/* Function to compare strings with wildcard strings*/
+/* When editing this function also edit the one in src/conf/network_conf.c*/
+static int
+wildcmp(const char *wild, const char *string)
+{
+ // Written by Jack Handy - <A
href="mailto:jakkhandy@hotmail.com">jakkhandy@otmail.com</A>
+ const char *cp = NULL, *mp = NULL;
+
+ while ((*string) && (*wild != '*')) {
+ if ((*wild != *string) && (*wild != '?')) {
+ return 0;
+ }
+ wild++;
+ string++;
+ }
+
+ while (*string) {
+ if (*wild == '*') {
+ if (!*++wild) {
+ return 1;
+ }
+ mp = wild;
+ cp = string+1;
+ } else if ((*wild == *string) || (*wild == '?')) {
+ wild++;
+ string++;
+ } else {
+ wild = mp;
+ string = cp++;
+ }
+ }
+
+ while (*wild == '*') {
+ wild++;
+ }
+ return !*wild;
+}
static void networkDriverLock(struct network_driver *driver)
{
@@ -2918,6 +2955,16 @@ networkAllocateActualDevice(virDomainNetDefPtr iface)
goto cleanup;
}
netdef->forwardIfs[ii].usageCount = 0;
+ if
(wildcmp("????:??:??.?",netdef->forwardIfs[ii].dev))
+ netdef->forwardIfs[ii].isPciAddr = true;
+ else
+ netdef->forwardIfs[ii].isPciAddr = false;
+
+ if (netdef->forwardIfs[ii].isPciAddr == true) {
+ networkReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Passthrough mode does not work
with PCI addresses and needs Interface names"));
+ goto cleanup;
+ }
}
}
diff --git a/src/util/pci.c b/src/util/pci.c
index b3be405..88e4ac5 100644
--- a/src/util/pci.c
+++ b/src/util/pci.c
@@ -2113,8 +2113,11 @@ pciDeviceNetName(char *device_link_sysfs_path, char **netname)
}
dir = opendir(pcidev_sysfs_net_path);
- if (dir == NULL)
+ if (dir == NULL) {
+ VIR_DEBUG("No interface name");
+ ret = 1;
goto out;
+ }
while ((entry = readdir(dir))) {
if (STREQ(entry->d_name, ".") ||
diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c
index d53352f..a328294 100644
--- a/src/util/virnetdev.c
+++ b/src/util/virnetdev.c
@@ -989,7 +989,6 @@ virNetDevGetVirtualFunctions(const char *pfname,
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;
@@ -1009,12 +1008,12 @@ virNetDevGetVirtualFunctions(const char *pfname,
virt_fns[i]->bus,
virt_fns[i]->slot,
virt_fns[i]->function,
- &pciConfigAddr) < 0) {
+ &((*vfname)[i])) < 0) {
virReportSystemError(ENOSYS, "%s",
_("Failed to get PCI Config Address
String"));
goto cleanup;
}
- if (pciSysfsFile(pciConfigAddr, &pci_sysfs_device_link) < 0) {
+ if (pciSysfsFile((*vfname)[i], &pci_sysfs_device_link) < 0) {
virReportSystemError(ENOSYS, "%s",
_("Failed to get PCI SYSFS file"));
goto cleanup;
@@ -1037,7 +1036,6 @@ cleanup:
VIR_FREE(virt_fns);
VIR_FREE(pf_sysfs_device_link);
VIR_FREE(pci_sysfs_device_link);
- VIR_FREE(pciConfigAddr);
return ret;
}
--
1.7.4.4