mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-08-28 03:21:19 +00:00
network: introduce networkAllocatePort
Separate network port allocation code from the domain driver network callback implementation. Reviewed-by: Laine Stump <laine@laine.org> Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
This commit is contained in:
parent
f02e21cb33
commit
7475562d5b
@ -4359,60 +4359,38 @@ networkLogAllocation(virNetworkDefPtr netdef,
|
|||||||
* "backend" function table.
|
* "backend" function table.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* networkAllocateActualDevice:
|
/* networkAllocatePort:
|
||||||
* @dom: domain definition that @iface belongs to
|
* @obj: the network to allocate from
|
||||||
* @iface: the original NetDef from the domain
|
* @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
|
* device from that network (if appropriate), and returns with the
|
||||||
* virDomainActualNetDef filled in accordingly. If there are no
|
* port configuration filled in accordingly.
|
||||||
* changes to be made in the netdef, then just leave the actualdef
|
|
||||||
* empty.
|
|
||||||
*
|
*
|
||||||
* Returns 0 on success, -1 on failure.
|
* Returns 0 on success, -1 on failure.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
networkAllocateActualDevice(virNetworkPtr net,
|
networkAllocatePort(virNetworkObjPtr obj,
|
||||||
virDomainDefPtr dom,
|
virNetworkPortDefPtr port)
|
||||||
virDomainNetDefPtr iface)
|
|
||||||
{
|
{
|
||||||
virNetworkDriverStatePtr driver = networkGetDriver();
|
virNetworkDriverStatePtr driver = networkGetDriver();
|
||||||
virNetworkObjPtr obj = NULL;
|
|
||||||
virNetworkDefPtr netdef = NULL;
|
virNetworkDefPtr netdef = NULL;
|
||||||
virPortGroupDefPtr portgroup = NULL;
|
virPortGroupDefPtr portgroup = NULL;
|
||||||
virNetworkForwardIfDefPtr dev = NULL;
|
virNetworkForwardIfDefPtr dev = NULL;
|
||||||
size_t i;
|
size_t i;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
virNetDevVPortProfilePtr portprofile = NULL;
|
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);
|
netdef = virNetworkObjGetDef(obj);
|
||||||
|
VIR_DEBUG("Allocating port from net %s", netdef->name);
|
||||||
|
|
||||||
if (!virNetworkObjIsActive(obj)) {
|
if (!virNetworkObjIsActive(obj)) {
|
||||||
virReportError(VIR_ERR_OPERATION_INVALID,
|
virReportError(VIR_ERR_OPERATION_INVALID,
|
||||||
_("network '%s' is not active"),
|
_("network '%s' is not active"),
|
||||||
netdef->name);
|
netdef->name);
|
||||||
goto error;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(port = virDomainNetDefToNetworkPort(dom, iface)))
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
VIR_DEBUG("Interface port group %s", port->group);
|
VIR_DEBUG("Interface port group %s", port->group);
|
||||||
/* portgroup can be present for any type of network, in particular
|
/* portgroup can be present for any type of network, in particular
|
||||||
* for bandwidth information, so we need to check for that and
|
* for bandwidth information, so we need to check for that and
|
||||||
@ -4424,7 +4402,7 @@ networkAllocateActualDevice(virNetworkPtr net,
|
|||||||
if (portgroup && portgroup->bandwidth &&
|
if (portgroup && portgroup->bandwidth &&
|
||||||
virNetDevBandwidthCopy(&port->bandwidth,
|
virNetDevBandwidthCopy(&port->bandwidth,
|
||||||
portgroup->bandwidth) < 0)
|
portgroup->bandwidth) < 0)
|
||||||
goto error;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (port->vlan.nTags == 0) {
|
if (port->vlan.nTags == 0) {
|
||||||
@ -4435,7 +4413,7 @@ networkAllocateActualDevice(virNetworkPtr net,
|
|||||||
vlan = &netdef->vlan;
|
vlan = &netdef->vlan;
|
||||||
|
|
||||||
if (vlan && virNetDevVlanCopy(&port->vlan, vlan) < 0)
|
if (vlan && virNetDevVlanCopy(&port->vlan, vlan) < 0)
|
||||||
goto error;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!port->trustGuestRxFilters) {
|
if (!port->trustGuestRxFilters) {
|
||||||
@ -4453,7 +4431,7 @@ networkAllocateActualDevice(virNetworkPtr net,
|
|||||||
netdef->virtPortProfile,
|
netdef->virtPortProfile,
|
||||||
portgroup
|
portgroup
|
||||||
? portgroup->virtPortProfile : NULL) < 0) {
|
? portgroup->virtPortProfile : NULL) < 0) {
|
||||||
goto error;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
if (portprofile) {
|
if (portprofile) {
|
||||||
VIR_FREE(port->virtPortProfile);
|
VIR_FREE(port->virtPortProfile);
|
||||||
@ -4473,7 +4451,7 @@ networkAllocateActualDevice(virNetworkPtr net,
|
|||||||
port->plugtype = VIR_NETWORK_PORT_PLUG_TYPE_NETWORK;
|
port->plugtype = VIR_NETWORK_PORT_PLUG_TYPE_NETWORK;
|
||||||
|
|
||||||
if (VIR_STRDUP(port->plug.bridge.brname, netdef->bridge) < 0)
|
if (VIR_STRDUP(port->plug.bridge.brname, netdef->bridge) < 0)
|
||||||
goto error;
|
goto cleanup;
|
||||||
port->plug.bridge.macTableManager = netdef->macTableManager;
|
port->plug.bridge.macTableManager = netdef->macTableManager;
|
||||||
|
|
||||||
if (port->virtPortProfile) {
|
if (port->virtPortProfile) {
|
||||||
@ -4482,18 +4460,18 @@ networkAllocateActualDevice(virNetworkPtr net,
|
|||||||
"'%s' which uses IP forwarding"),
|
"'%s' which uses IP forwarding"),
|
||||||
virNetDevVPortTypeToString(port->virtPortProfile->virtPortType),
|
virNetDevVPortTypeToString(port->virtPortProfile->virtPortType),
|
||||||
netdef->name);
|
netdef->name);
|
||||||
goto error;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (networkPlugBandwidth(obj, &port->mac, port->bandwidth, &port->class_id) < 0)
|
if (networkPlugBandwidth(obj, &port->mac, port->bandwidth, &port->class_id) < 0)
|
||||||
goto error;
|
goto cleanup;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VIR_NETWORK_FORWARD_HOSTDEV: {
|
case VIR_NETWORK_FORWARD_HOSTDEV: {
|
||||||
port->plugtype = VIR_NETWORK_PORT_PLUG_TYPE_HOSTDEV_PCI;
|
port->plugtype = VIR_NETWORK_PORT_PLUG_TYPE_HOSTDEV_PCI;
|
||||||
|
|
||||||
if (networkCreateInterfacePool(netdef) < 0)
|
if (networkCreateInterfacePool(netdef) < 0)
|
||||||
goto error;
|
goto cleanup;
|
||||||
|
|
||||||
/* pick first dev with 0 connections */
|
/* pick first dev with 0 connections */
|
||||||
for (i = 0; i < netdef->forward.nifs; i++) {
|
for (i = 0; i < netdef->forward.nifs; i++) {
|
||||||
@ -4507,7 +4485,7 @@ networkAllocateActualDevice(virNetworkPtr net,
|
|||||||
_("network '%s' requires exclusive access "
|
_("network '%s' requires exclusive access "
|
||||||
"to interfaces, but none are available"),
|
"to interfaces, but none are available"),
|
||||||
netdef->name);
|
netdef->name);
|
||||||
goto error;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
port->plug.hostdevpci.addr = dev->device.pci;
|
port->plug.hostdevpci.addr = dev->device.pci;
|
||||||
port->plug.hostdevpci.driver = netdef->forward.driverName;
|
port->plug.hostdevpci.driver = netdef->forward.driverName;
|
||||||
@ -4523,7 +4501,7 @@ networkAllocateActualDevice(virNetworkPtr net,
|
|||||||
"via PCI passthrough"),
|
"via PCI passthrough"),
|
||||||
virNetDevVPortTypeToString(port->virtPortProfile->virtPortType),
|
virNetDevVPortTypeToString(port->virtPortProfile->virtPortType),
|
||||||
netdef->name);
|
netdef->name);
|
||||||
goto error;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -4537,7 +4515,7 @@ networkAllocateActualDevice(virNetworkPtr net,
|
|||||||
|
|
||||||
port->plugtype = VIR_NETWORK_PORT_PLUG_TYPE_BRIDGE;
|
port->plugtype = VIR_NETWORK_PORT_PLUG_TYPE_BRIDGE;
|
||||||
if (VIR_STRDUP(port->plug.bridge.brname, netdef->bridge) < 0)
|
if (VIR_STRDUP(port->plug.bridge.brname, netdef->bridge) < 0)
|
||||||
goto error;
|
goto cleanup;
|
||||||
port->plug.bridge.macTableManager = netdef->macTableManager;
|
port->plug.bridge.macTableManager = netdef->macTableManager;
|
||||||
|
|
||||||
if (port->virtPortProfile) {
|
if (port->virtPortProfile) {
|
||||||
@ -4548,12 +4526,12 @@ networkAllocateActualDevice(virNetworkPtr net,
|
|||||||
"'%s' which uses a bridge device"),
|
"'%s' which uses a bridge device"),
|
||||||
virNetDevVPortTypeToString(port->virtPortProfile->virtPortType),
|
virNetDevVPortTypeToString(port->virtPortProfile->virtPortType),
|
||||||
netdef->name);
|
netdef->name);
|
||||||
goto error;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (networkPlugBandwidth(obj, &port->mac, port->bandwidth, &port->class_id) < 0)
|
if (networkPlugBandwidth(obj, &port->mac, port->bandwidth, &port->class_id) < 0)
|
||||||
goto error;
|
goto cleanup;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4587,7 +4565,7 @@ networkAllocateActualDevice(virNetworkPtr net,
|
|||||||
"'%s' which uses a macvtap device"),
|
"'%s' which uses a macvtap device"),
|
||||||
virNetDevVPortTypeToString(port->virtPortProfile->virtPortType),
|
virNetDevVPortTypeToString(port->virtPortProfile->virtPortType),
|
||||||
netdef->name);
|
netdef->name);
|
||||||
goto error;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4599,12 +4577,12 @@ networkAllocateActualDevice(virNetworkPtr net,
|
|||||||
_("network '%s' uses a direct mode, but "
|
_("network '%s' uses a direct mode, but "
|
||||||
"has no forward dev and no interface pool"),
|
"has no forward dev and no interface pool"),
|
||||||
netdef->name);
|
netdef->name);
|
||||||
goto error;
|
goto cleanup;
|
||||||
} else {
|
} else {
|
||||||
/* pick an interface from the pool */
|
/* pick an interface from the pool */
|
||||||
|
|
||||||
if (networkCreateInterfacePool(netdef) < 0)
|
if (networkCreateInterfacePool(netdef) < 0)
|
||||||
goto error;
|
goto cleanup;
|
||||||
|
|
||||||
/* PASSTHROUGH mode, and PRIVATE Mode + 802.1Qbh both
|
/* PASSTHROUGH mode, and PRIVATE Mode + 802.1Qbh both
|
||||||
* require exclusive access to a device, so current
|
* require exclusive access to a device, so current
|
||||||
@ -4639,26 +4617,26 @@ networkAllocateActualDevice(virNetworkPtr net,
|
|||||||
_("network '%s' requires exclusive access "
|
_("network '%s' requires exclusive access "
|
||||||
"to interfaces, but none are available"),
|
"to interfaces, but none are available"),
|
||||||
netdef->name);
|
netdef->name);
|
||||||
goto error;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
if (VIR_STRDUP(port->plug.direct.linkdev,
|
if (VIR_STRDUP(port->plug.direct.linkdev,
|
||||||
dev->device.dev) < 0)
|
dev->device.dev) < 0)
|
||||||
goto error;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VIR_NETWORK_FORWARD_LAST:
|
case VIR_NETWORK_FORWARD_LAST:
|
||||||
default:
|
default:
|
||||||
virReportEnumRangeError(virNetworkForwardType, netdef->forward.type);
|
virReportEnumRangeError(virNetworkForwardType, netdef->forward.type);
|
||||||
goto error;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (virNetworkObjMacMgrAdd(obj, driver->dnsmasqStateDir,
|
if (virNetworkObjMacMgrAdd(obj, driver->dnsmasqStateDir,
|
||||||
dom->name, &port->mac) < 0)
|
port->ownername, &port->mac) < 0)
|
||||||
goto error;
|
goto cleanup;
|
||||||
|
|
||||||
if (virNetDevVPortProfileCheckComplete(port->virtPortProfile, true) < 0)
|
if (virNetDevVPortProfileCheckComplete(port->virtPortProfile, true) < 0)
|
||||||
goto error;
|
goto cleanup;
|
||||||
|
|
||||||
/* make sure that everything now specified for the device is
|
/* make sure that everything now specified for the device is
|
||||||
* actually supported on this type of network. NB: network,
|
* actually supported on this type of network. NB: network,
|
||||||
@ -4683,7 +4661,7 @@ networkAllocateActualDevice(virNetworkPtr net,
|
|||||||
"is requesting a vlan tag, but that is not "
|
"is requesting a vlan tag, but that is not "
|
||||||
"supported for this type of network"),
|
"supported for this type of network"),
|
||||||
netdef->name);
|
netdef->name);
|
||||||
goto error;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4694,7 +4672,7 @@ networkAllocateActualDevice(virNetworkPtr net,
|
|||||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
||||||
_("bandwidth settings are not supported "
|
_("bandwidth settings are not supported "
|
||||||
"for hostdev interfaces"));
|
"for hostdev interfaces"));
|
||||||
goto error;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
netdef->connections++;
|
netdef->connections++;
|
||||||
@ -4708,28 +4686,61 @@ networkAllocateActualDevice(virNetworkPtr net,
|
|||||||
netdef->connections--;
|
netdef->connections--;
|
||||||
if (dev)
|
if (dev)
|
||||||
dev->connections--;
|
dev->connections--;
|
||||||
goto error;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
networkLogAllocation(netdef, dev, &iface->mac, true);
|
networkLogAllocation(netdef, dev, &port->mac, true);
|
||||||
|
|
||||||
|
VIR_DEBUG("Port allocated");
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
cleanup:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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");
|
VIR_DEBUG("Populating net def");
|
||||||
if (virDomainNetDefActualFromNetworkPort(iface, port) < 0)
|
if (virDomainNetDefActualFromNetworkPort(iface, port) < 0)
|
||||||
goto error;
|
goto cleanup;
|
||||||
|
|
||||||
VIR_DEBUG("Port allocated");
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
virNetworkPortDefFree(port);
|
if (ret < 0) {
|
||||||
virNetworkObjEndAPI(&obj);
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
error:
|
|
||||||
if (iface->type == VIR_DOMAIN_NET_TYPE_NETWORK) {
|
|
||||||
virDomainActualNetDefFree(iface->data.network.actual);
|
virDomainActualNetDefFree(iface->data.network.actual);
|
||||||
iface->data.network.actual = NULL;
|
iface->data.network.actual = NULL;
|
||||||
}
|
}
|
||||||
goto cleanup;
|
virNetworkPortDefFree(port);
|
||||||
|
virNetworkObjEndAPI(&obj);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user