This patch updates the network driver to properly utilize the new
attributes/elements that are now in virNetworkDef
---
src/network/bridge_driver.c | 123 ++++++++++++++++++++++++++++++++++++++-----
1 files changed, 110 insertions(+), 13 deletions(-)
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index 808c843..f94f81a 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -1993,9 +1993,9 @@ networkStartNetworkExternal(struct network_driver *driver
ATTRIBUTE_UNUSED,
virNetworkObjPtr network ATTRIBUTE_UNUSED)
{
/* put anything here that needs to be done each time a network of
- * type BRIDGE, PRIVATE, VEPA, HOSTDEV or PASSTHROUGH is started. On
- * failure, undo anything you've done, and return -1. On success
- * return 0.
+ * type BRIDGE, PRIVATE, VEPA, HOSTDEV, HOSTDEV-HYBRID or PASSTHROUGH
+ * is started. On failure, undo anything you've done, and return -1.
+ * On success return 0.
*/
return 0;
}
@@ -2004,9 +2004,9 @@ static int networkShutdownNetworkExternal(struct network_driver
*driver ATTRIBUT
virNetworkObjPtr network ATTRIBUTE_UNUSED)
{
/* put anything here that needs to be done each time a network of
- * type BRIDGE, PRIVATE, VEPA, HOSTDEV or PASSTHROUGH is shutdown. On
- * failure, undo anything you've done, and return -1. On success
- * return 0.
+ * type BRIDGE, PRIVATE, VEPA, HOSTDEV, HOSTDEV-HYBRID or PASSTHROUGH
+ * is shutdown. On failure, undo anything you've done, and return -1.
+ * On success return 0.
*/
return 0;
}
@@ -2036,6 +2036,7 @@ networkStartNetwork(struct network_driver *driver,
case VIR_NETWORK_FORWARD_VEPA:
case VIR_NETWORK_FORWARD_PASSTHROUGH:
case VIR_NETWORK_FORWARD_HOSTDEV:
+ case VIR_NETWORK_FORWARD_HOSTDEV_HYBRID:
ret = networkStartNetworkExternal(driver, network);
break;
}
@@ -2096,6 +2097,7 @@ static int networkShutdownNetwork(struct network_driver *driver,
case VIR_NETWORK_FORWARD_VEPA:
case VIR_NETWORK_FORWARD_PASSTHROUGH:
case VIR_NETWORK_FORWARD_HOSTDEV:
+ case VIR_NETWORK_FORWARD_HOSTDEV_HYBRID:
ret = networkShutdownNetworkExternal(driver, network);
break;
}
@@ -2885,7 +2887,8 @@ networkCreateInterfacePool(virNetworkDefPtr netdef) {
goto finish;
}
}
- else if (netdef->forwardType == VIR_NETWORK_FORWARD_HOSTDEV) {
+ else if (netdef->forwardType == VIR_NETWORK_FORWARD_HOSTDEV ||
+ netdef->forwardType == VIR_NETWORK_FORWARD_HOSTDEV_HYBRID) {
/* VF's are always PCI devices */
netdef->forwardIfs[ii].type = VIR_NETWORK_FORWARD_HOSTDEV_DEVICE_PCI;
netdef->forwardIfs[ii].device.pci.domain = virt_fns[ii]->domain;
@@ -3056,6 +3059,8 @@ networkAllocateActualDevice(virDomainNetDefPtr iface)
}
iface->data.network.actual->data.hostdev.def.parent.type =
VIR_DOMAIN_DEVICE_NET;
iface->data.network.actual->data.hostdev.def.parent.data.net = iface;
+ iface->data.network.actual->data.hostdev.def.actualParent.type =
VIR_DOMAIN_DEVICE_NET;
+
iface->data.network.actual->data.hostdev.def.actualParent.data.net =
iface;
iface->data.network.actual->data.hostdev.def.info = &iface->info;
iface->data.network.actual->data.hostdev.def.mode =
VIR_DOMAIN_HOSTDEV_MODE_SUBSYS;
iface->data.network.actual->data.hostdev.def.managed = netdef->managed;
@@ -3087,6 +3092,92 @@ networkAllocateActualDevice(virDomainNetDefPtr iface)
}
}
+ } else if (netdef->forwardType == VIR_NETWORK_FORWARD_HOSTDEV_HYBRID) {
+ char *pfname = NULL;
+ if (!iface->data.network.actual
+ && (VIR_ALLOC(iface->data.network.actual) < 0)) {
+ virReportOOMError();
+ goto error;
+ }
+ iface->data.network.actual->type = actualType =
VIR_DOMAIN_NET_TYPE_HOSTDEV_HYBRID;
+
+ if (netdef->nForwardPfs > 0 && netdef->nForwardIfs <= 0
&&
+ 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;
+ }
+ }
+ if (!dev) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("network '%s' requires exclusive access to
interfaces, but none are available"),
+ netdef->name);
+ goto error;
+ }
+ iface->data.network.actual->data.hostdev.def.parent.type =
VIR_DOMAIN_DEVICE_NONE;
+ iface->data.network.actual->data.hostdev.def.actualParent.type =
VIR_DOMAIN_DEVICE_NET;
+
iface->data.network.actual->data.hostdev.def.actualParent.data.net =
iface;
+
+ if (VIR_ALLOC(iface->data.network.actual->data.hostdev.def.info) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ iface->data.network.actual->data.hostdev.def.ephemeral = 1;
+
+ iface->data.network.actual->data.hostdev.def.mode =
VIR_DOMAIN_HOSTDEV_MODE_SUBSYS;
+ iface->data.network.actual->data.hostdev.def.managed = netdef->managed;
+ iface->data.network.actual->data.hostdev.def.source.subsys.type =
dev->type;
+ iface->data.network.actual->data.hostdev.def.source.subsys.u.pci =
dev->device.pci;
+
+ if (virNetDevGetPhysicalFunctionFromVfPciAddr(dev->device.pci.domain,
+ dev->device.pci.bus,
+ dev->device.pci.slot,
+ dev->device.pci.function,
+ &pfname) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Could not get Physical function of the selected
VF"));
+ goto cleanup;
+ }
+
+ if (pfname != NULL)
+ iface->data.network.actual->data.hostdev.linkdev = strdup(pfname);
+ else {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Linkdev is required in hostdev-hybrid mode"));
+ goto cleanup;
+ }
+ iface->data.network.actual->data.hostdev.mode =
VIR_NETDEV_MACVLAN_MODE_BRIDGE;
+
+ /* merge virtualports from interface, network, and portgroup to
+ * arrive at actual virtualport to use
+ */
+ if
(virNetDevVPortProfileMerge3(&iface->data.network.actual->virtPortProfile,
+ iface->virtPortProfile,
+ netdef->virtPortProfile,
+ portgroup
+ ? portgroup->virtPortProfile : NULL) < 0)
{
+ goto error;
+ }
+ virtport = iface->data.network.actual->virtPortProfile;
+ if (virtport) {
+ /* make sure type is supported for hostdev connections */
+ if (virtport->virtPortType != VIR_NETDEV_VPORT_PROFILE_8021QBG &&
+ virtport->virtPortType != VIR_NETDEV_VPORT_PROFILE_8021QBH) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("<virtualport type='%s'> not
supported for network "
+ "'%s' which uses an SR-IOV Virtual Function
"
+ "via PCI passthrough"),
+ virNetDevVPortTypeToString(virtport->virtPortType),
+ netdef->name);
+ goto error;
+ }
+ }
+
} else if ((netdef->forwardType == VIR_NETWORK_FORWARD_BRIDGE) ||
(netdef->forwardType == VIR_NETWORK_FORWARD_PRIVATE) ||
(netdef->forwardType == VIR_NETWORK_FORWARD_VEPA) ||
@@ -3252,7 +3343,8 @@ validate:
if (dev) {
/* we are now assured of success, so mark the allocation */
dev->connections++;
- if (actualType != VIR_DOMAIN_NET_TYPE_HOSTDEV) {
+ if (actualType != VIR_DOMAIN_NET_TYPE_HOSTDEV &&
+ actualType != VIR_DOMAIN_NET_TYPE_HOSTDEV_HYBRID) {
VIR_DEBUG("Using physical device %s, %d connections",
dev->device.dev, dev->connections);
} else {
@@ -3319,7 +3411,8 @@ networkNotifyActualDevice(virDomainNetDefPtr iface)
if (!iface->data.network.actual ||
(actualType != VIR_DOMAIN_NET_TYPE_DIRECT &&
- actualType != VIR_DOMAIN_NET_TYPE_HOSTDEV)) {
+ actualType != VIR_DOMAIN_NET_TYPE_HOSTDEV &&
+ actualType != VIR_DOMAIN_NET_TYPE_HOSTDEV_HYBRID)) {
VIR_DEBUG("Nothing to claim from network %s",
iface->data.network.name);
goto success;
}
@@ -3387,7 +3480,8 @@ networkNotifyActualDevice(virDomainNetDefPtr iface)
VIR_DEBUG("Using physical device %s, connections %d",
dev->device.dev, dev->connections);
- } else /* if (actualType == VIR_DOMAIN_NET_TYPE_HOSTDEV) */ {
+ } else if (actualType == VIR_DOMAIN_NET_TYPE_HOSTDEV ||
+ actualType == VIR_DOMAIN_NET_TYPE_HOSTDEV_HYBRID) {
virDomainHostdevDefPtr hostdev;
hostdev = virDomainNetGetActualHostdev(iface);
@@ -3426,7 +3520,8 @@ networkNotifyActualDevice(virDomainNetDefPtr iface)
* current connections count must be 0 in those cases.
*/
if ((dev->connections > 0) &&
- netdef->forwardType == VIR_NETWORK_FORWARD_HOSTDEV) {
+ (netdef->forwardType == VIR_NETWORK_FORWARD_HOSTDEV ||
+ netdef->forwardType == VIR_NETWORK_FORWARD_HOSTDEV_HYBRID)) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("network '%s' claims the PCI device at "
"domain=%d bus=%d slot=%d function=%d "
@@ -3496,7 +3591,8 @@ networkReleaseActualDevice(virDomainNetDefPtr iface)
if ((!iface->data.network.actual) ||
((actualType != VIR_DOMAIN_NET_TYPE_DIRECT) &&
- (actualType != VIR_DOMAIN_NET_TYPE_HOSTDEV))) {
+ (actualType != VIR_DOMAIN_NET_TYPE_HOSTDEV) &&
+ (actualType != VIR_DOMAIN_NET_TYPE_HOSTDEV_HYBRID))) {
VIR_DEBUG("Nothing to release to network %s",
iface->data.network.name);
goto success;
}
@@ -3541,7 +3637,8 @@ networkReleaseActualDevice(virDomainNetDefPtr iface)
VIR_DEBUG("Releasing physical device %s, connections %d",
dev->device.dev, dev->connections);
- } else /* if (actualType == VIR_DOMAIN_NET_TYPE_HOSTDEV) */ {
+ } else if (actualType == VIR_DOMAIN_NET_TYPE_HOSTDEV ||
+ actualType == VIR_DOMAIN_NET_TYPE_HOSTDEV_HYBRID) {
virDomainHostdevDefPtr hostdev;
hostdev = virDomainNetGetActualHostdev(iface);
--
1.7.4.4