Separate network port allocation code from the domain driver network
callback implementation.
Reviewed-by: Laine Stump <laine(a)laine.org>
Signed-off-by: Daniel P. Berrangé <berrange(a)redhat.com>
---
src/network/bridge_driver.c | 143 +++++++++++++++++++-----------------
1 file changed, 77 insertions(+), 66 deletions(-)
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index ec2f5e92ee..0954b5515b 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -4366,60 +4366,38 @@ networkLogAllocation(virNetworkDefPtr netdef,
* "backend" function table.
*/
-/* networkAllocateActualDevice:
- * @dom: domain definition that @iface belongs to
- * @iface: the original NetDef from the domain
+/* networkAllocatePort:
+ * @obj: the network to allocate from
+ * @port: the port definition to allocate
*
- * Looks up the network reference by iface, allocates a physical
+ * Looks up the network reference by port, allocates a physical
* device from that network (if appropriate), and returns with the
- * virDomainActualNetDef filled in accordingly. If there are no
- * changes to be made in the netdef, then just leave the actualdef
- * empty.
+ * port configuration filled in accordingly.
*
* Returns 0 on success, -1 on failure.
*/
static int
-networkAllocateActualDevice(virNetworkPtr net,
- virDomainDefPtr dom,
- virDomainNetDefPtr iface)
+networkAllocatePort(virNetworkObjPtr obj,
+ virNetworkPortDefPtr port)
{
virNetworkDriverStatePtr driver = networkGetDriver();
- virNetworkObjPtr obj = NULL;
virNetworkDefPtr netdef = NULL;
virPortGroupDefPtr portgroup = NULL;
virNetworkForwardIfDefPtr dev = NULL;
size_t i;
int ret = -1;
virNetDevVPortProfilePtr portprofile = NULL;
- virNetworkPortDefPtr port = NULL;
-
- VIR_DEBUG("Allocating port from net %s", net->name);
- obj = virNetworkObjFindByName(driver->networks, net->name);
- if (!obj) {
- virReportError(VIR_ERR_NO_NETWORK,
- _("no network with matching name '%s'"),
- net->name);
- goto error;
- }
-
- if (iface->type != VIR_DOMAIN_NET_TYPE_NETWORK) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("Expected an interface for a virtual network"));
- goto error;
- }
netdef = virNetworkObjGetDef(obj);
+ VIR_DEBUG("Allocating port from net %s", netdef->name);
if (!virNetworkObjIsActive(obj)) {
virReportError(VIR_ERR_OPERATION_INVALID,
_("network '%s' is not active"),
netdef->name);
- goto error;
+ goto cleanup;
}
- if (!(port = virDomainNetDefToNetworkPort(dom, iface)))
- goto error;
-
VIR_DEBUG("Interface port group %s", port->group);
/* portgroup can be present for any type of network, in particular
* for bandwidth information, so we need to check for that and
@@ -4431,7 +4409,7 @@ networkAllocateActualDevice(virNetworkPtr net,
if (portgroup && portgroup->bandwidth &&
virNetDevBandwidthCopy(&port->bandwidth,
portgroup->bandwidth) < 0)
- goto error;
+ goto cleanup;
}
if (port->vlan.nTags == 0) {
@@ -4442,7 +4420,7 @@ networkAllocateActualDevice(virNetworkPtr net,
vlan = &netdef->vlan;
if (vlan && virNetDevVlanCopy(&port->vlan, vlan) < 0)
- goto error;
+ goto cleanup;
}
if (!port->trustGuestRxFilters) {
@@ -4460,7 +4438,7 @@ networkAllocateActualDevice(virNetworkPtr net,
netdef->virtPortProfile,
portgroup
? portgroup->virtPortProfile : NULL) < 0) {
- goto error;
+ goto cleanup;
}
if (portprofile) {
VIR_FREE(port->virtPortProfile);
@@ -4480,7 +4458,7 @@ networkAllocateActualDevice(virNetworkPtr net,
port->plugtype = VIR_NETWORK_PORT_PLUG_TYPE_NETWORK;
if (VIR_STRDUP(port->plug.bridge.brname, netdef->bridge) < 0)
- goto error;
+ goto cleanup;
port->plug.bridge.macTableManager = netdef->macTableManager;
if (port->virtPortProfile) {
@@ -4489,18 +4467,18 @@ networkAllocateActualDevice(virNetworkPtr net,
"'%s' which uses IP forwarding"),
virNetDevVPortTypeToString(port->virtPortProfile->virtPortType),
netdef->name);
- goto error;
+ goto cleanup;
}
if (networkPlugBandwidth(obj, &port->mac, port->bandwidth,
&port->class_id) < 0)
- goto error;
+ goto cleanup;
break;
case VIR_NETWORK_FORWARD_HOSTDEV: {
port->plugtype = VIR_NETWORK_PORT_PLUG_TYPE_HOSTDEV_PCI;
if (networkCreateInterfacePool(netdef) < 0)
- goto error;
+ goto cleanup;
/* pick first dev with 0 connections */
for (i = 0; i < netdef->forward.nifs; i++) {
@@ -4514,7 +4492,7 @@ networkAllocateActualDevice(virNetworkPtr net,
_("network '%s' requires exclusive access "
"to interfaces, but none are available"),
netdef->name);
- goto error;
+ goto cleanup;
}
port->plug.hostdevpci.addr = dev->device.pci;
port->plug.hostdevpci.driver = netdef->forward.driverName;
@@ -4530,7 +4508,7 @@ networkAllocateActualDevice(virNetworkPtr net,
"via PCI passthrough"),
virNetDevVPortTypeToString(port->virtPortProfile->virtPortType),
netdef->name);
- goto error;
+ goto cleanup;
}
}
break;
@@ -4544,7 +4522,7 @@ networkAllocateActualDevice(virNetworkPtr net,
port->plugtype = VIR_NETWORK_PORT_PLUG_TYPE_BRIDGE;
if (VIR_STRDUP(port->plug.bridge.brname, netdef->bridge) < 0)
- goto error;
+ goto cleanup;
port->plug.bridge.macTableManager = netdef->macTableManager;
if (port->virtPortProfile) {
@@ -4555,12 +4533,12 @@ networkAllocateActualDevice(virNetworkPtr net,
"'%s' which uses a bridge
device"),
virNetDevVPortTypeToString(port->virtPortProfile->virtPortType),
netdef->name);
- goto error;
+ goto cleanup;
}
}
if (networkPlugBandwidth(obj, &port->mac, port->bandwidth,
&port->class_id) < 0)
- goto error;
+ goto cleanup;
break;
}
@@ -4594,7 +4572,7 @@ networkAllocateActualDevice(virNetworkPtr net,
"'%s' which uses a macvtap device"),
virNetDevVPortTypeToString(port->virtPortProfile->virtPortType),
netdef->name);
- goto error;
+ goto cleanup;
}
}
@@ -4606,12 +4584,12 @@ networkAllocateActualDevice(virNetworkPtr net,
_("network '%s' uses a direct mode, but "
"has no forward dev and no interface pool"),
netdef->name);
- goto error;
+ goto cleanup;
} else {
/* pick an interface from the pool */
if (networkCreateInterfacePool(netdef) < 0)
- goto error;
+ goto cleanup;
/* PASSTHROUGH mode, and PRIVATE Mode + 802.1Qbh both
* require exclusive access to a device, so current
@@ -4646,26 +4624,26 @@ networkAllocateActualDevice(virNetworkPtr net,
_("network '%s' requires exclusive access
"
"to interfaces, but none are available"),
netdef->name);
- goto error;
+ goto cleanup;
}
if (VIR_STRDUP(port->plug.direct.linkdev,
dev->device.dev) < 0)
- goto error;
+ goto cleanup;
}
break;
case VIR_NETWORK_FORWARD_LAST:
default:
virReportEnumRangeError(virNetworkForwardType, netdef->forward.type);
- goto error;
+ goto cleanup;
}
if (virNetworkObjMacMgrAdd(obj, driver->dnsmasqStateDir,
- dom->name, &port->mac) < 0)
- goto error;
+ port->ownername, &port->mac) < 0)
+ goto cleanup;
if (virNetDevVPortProfileCheckComplete(port->virtPortProfile, true) < 0)
- goto error;
+ goto cleanup;
/* make sure that everything now specified for the device is
* actually supported on this type of network. NB: network,
@@ -4690,7 +4668,7 @@ networkAllocateActualDevice(virNetworkPtr net,
"is requesting a vlan tag, but that is not "
"supported for this type of network"),
netdef->name);
- goto error;
+ goto cleanup;
}
}
@@ -4701,7 +4679,7 @@ networkAllocateActualDevice(virNetworkPtr net,
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("bandwidth settings are not supported "
"for hostdev interfaces"));
- goto error;
+ goto cleanup;
}
netdef->connections++;
@@ -4715,28 +4693,61 @@ networkAllocateActualDevice(virNetworkPtr net,
netdef->connections--;
if (dev)
dev->connections--;
- goto error;
+ goto cleanup;
}
- networkLogAllocation(netdef, dev, &iface->mac, true);
-
- VIR_DEBUG("Populating net def");
- if (virDomainNetDefActualFromNetworkPort(iface, port) < 0)
- goto error;
+ networkLogAllocation(netdef, dev, &port->mac, true);
VIR_DEBUG("Port allocated");
- ret = 0;
+ ret = 0;
cleanup:
- virNetworkPortDefFree(port);
- virNetworkObjEndAPI(&obj);
return ret;
+}
- error:
- if (iface->type == VIR_DOMAIN_NET_TYPE_NETWORK) {
+
+static int
+networkAllocateActualDevice(virNetworkPtr net,
+ virDomainDefPtr dom,
+ virDomainNetDefPtr iface)
+{
+ virNetworkDriverStatePtr driver = networkGetDriver();
+ virNetworkPortDefPtr port = NULL;
+ virNetworkObjPtr obj;
+ int ret = -1;
+
+ obj = virNetworkObjFindByName(driver->networks, net->name);
+ if (!obj) {
+ virReportError(VIR_ERR_NO_NETWORK,
+ _("no network with matching name '%s'"),
+ net->name);
+ return -1;
+ }
+
+ if (iface->type != VIR_DOMAIN_NET_TYPE_NETWORK) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Expected an interface for a virtual network"));
+ goto cleanup;
+ }
+
+ if (!(port = virDomainNetDefToNetworkPort(dom, iface)))
+ goto cleanup;
+
+ if (networkAllocatePort(obj, port) < 0)
+ goto cleanup;
+
+ VIR_DEBUG("Populating net def");
+ if (virDomainNetDefActualFromNetworkPort(iface, port) < 0)
+ goto cleanup;
+
+ ret = 0;
+ cleanup:
+ if (ret < 0) {
virDomainActualNetDefFree(iface->data.network.actual);
iface->data.network.actual = NULL;
}
- goto cleanup;
+ virNetworkPortDefFree(port);
+ virNetworkObjEndAPI(&obj);
+ return ret;
}
--
2.21.0