On 5/14/19 11:48 AM, Daniel P. Berrangé wrote:
Helper APIs are needed to
- Populate basic virNetworkPortDef from virDomainNetDef
- Set a virDomainActualNetDef from virNetworkPortDef
- Populate a full virNetworkPortDef from virDomainActualNetDef
Signed-off-by: Daniel P. Berrangé <berrange(a)redhat.com>
Reviewed-by: Laine Stump <laine(a)laine.org>
---
src/conf/domain_conf.c | 290 +++++++++++++++++++++++++++++++++++++++
src/conf/domain_conf.h | 17 +++
src/libvirt_private.syms | 3 +
3 files changed, 310 insertions(+)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 011d789feb..7569b1b580 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -39,6 +39,7 @@
#include "virbuffer.h"
#include "virlog.h"
#include "nwfilter_conf.h"
+#include "virnetworkportdef.h"
#include "storage_conf.h"
#include "virstoragefile.h"
#include "virfile.h"
@@ -30367,6 +30368,295 @@ virDomainNetTypeSharesHostView(const virDomainNetDef *net)
return false;
}
+virNetworkPortDefPtr
+virDomainNetDefToNetworkPort(virDomainDefPtr dom,
+ virDomainNetDefPtr iface)
+{
+ virNetworkPortDefPtr port;
+
+ if (iface->type != VIR_DOMAIN_NET_TYPE_NETWORK) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Expected an interface of type 'network' not
'%s'"),
+ virDomainNetTypeToString(iface->type));
+ return NULL;
+ }
+
+ if (VIR_ALLOC(port) < 0)
+ return NULL;
+
+ virUUIDGenerate(port->uuid);
+
+ memcpy(port->owneruuid, dom->uuid, VIR_UUID_BUFLEN);
+ if (VIR_STRDUP(port->ownername, dom->name) < 0)
+ goto error;
+
+ if (VIR_STRDUP(port->group, iface->data.network.portgroup) < 0)
+ goto error;
+
+ memcpy(&port->mac, &iface->mac, VIR_MAC_BUFLEN);
+
+ if (virNetDevVPortProfileCopy(&port->virtPortProfile,
iface->virtPortProfile) < 0)
+ goto error;
+
+ if (virNetDevBandwidthCopy(&port->bandwidth, iface->bandwidth) < 0)
+ goto error;
+
+ if (virNetDevVlanCopy(&port->vlan, &iface->vlan) < 0)
+ goto error;
+
+ port->trustGuestRxFilters = iface->trustGuestRxFilters;
+
+ return port;
+
+ error:
+ virNetworkPortDefFree(port);
+ return NULL;
+}
+
+int
+virDomainNetDefActualFromNetworkPort(virDomainNetDefPtr iface,
+ virNetworkPortDefPtr port)
+{
+ virDomainActualNetDefPtr actual = NULL;
+
+ if (iface->type != VIR_DOMAIN_NET_TYPE_NETWORK) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Expected an interface of type 'network' not
'%s'"),
+ virDomainNetTypeToString(iface->type));
+ return -1;
+ }
+
+ if (VIR_ALLOC(actual) < 0)
+ return -1;
+
+ switch ((virNetworkPortPlugType)port->plugtype) {
+ case VIR_NETWORK_PORT_PLUG_TYPE_NONE:
+ break;
+
+ case VIR_NETWORK_PORT_PLUG_TYPE_NETWORK:
+ actual->type = VIR_DOMAIN_NET_TYPE_NETWORK;
+ if (VIR_STRDUP(actual->data.bridge.brname,
+ port->plug.bridge.brname) < 0)
+ goto error;
+ actual->data.bridge.macTableManager = port->plug.bridge.macTableManager;
+ break;
+
+ case VIR_NETWORK_PORT_PLUG_TYPE_BRIDGE:
+ actual->type = VIR_DOMAIN_NET_TYPE_BRIDGE;
+ if (VIR_STRDUP(actual->data.bridge.brname,
+ port->plug.bridge.brname) < 0)
+ goto error;
+ actual->data.bridge.macTableManager = port->plug.bridge.macTableManager;
+ break;
+
+ case VIR_NETWORK_PORT_PLUG_TYPE_DIRECT:
+ actual->type = VIR_DOMAIN_NET_TYPE_DIRECT;
+ if (VIR_STRDUP(actual->data.direct.linkdev,
+ port->plug.direct.linkdev) < 0)
+ goto error;
+ actual->data.direct.mode = port->plug.direct.mode;
+ break;
+
+ case VIR_NETWORK_PORT_PLUG_TYPE_HOSTDEV_PCI:
+ actual->type = VIR_DOMAIN_NET_TYPE_HOSTDEV;
+ actual->data.hostdev.def.parentnet = iface;
+ actual->data.hostdev.def.info = &iface->info;
+ actual->data.hostdev.def.mode = VIR_DOMAIN_HOSTDEV_MODE_SUBSYS;
+ actual->data.hostdev.def.managed = port->plug.hostdevpci.managed;
+ actual->data.hostdev.def.source.subsys.type =
VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI;
+ actual->data.hostdev.def.source.subsys.u.pci.addr =
port->plug.hostdevpci.addr;
+ switch ((virNetworkForwardDriverNameType)port->plug.hostdevpci.driver) {
+ case VIR_NETWORK_FORWARD_DRIVER_NAME_DEFAULT:
+ actual->data.hostdev.def.source.subsys.u.pci.backend =
+ VIR_DOMAIN_HOSTDEV_PCI_BACKEND_DEFAULT;
+ break;
+
+ case VIR_NETWORK_FORWARD_DRIVER_NAME_KVM:
+ actual->data.hostdev.def.source.subsys.u.pci.backend =
+ VIR_DOMAIN_HOSTDEV_PCI_BACKEND_KVM;
+ break;
+
+ case VIR_NETWORK_FORWARD_DRIVER_NAME_VFIO:
+ actual->data.hostdev.def.source.subsys.u.pci.backend =
+ VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO;
+ break;
+
+ case VIR_NETWORK_FORWARD_DRIVER_NAME_LAST:
+ default:
+ virReportEnumRangeError(virNetworkForwardDriverNameType,
+ port->plug.hostdevpci.driver);
+ goto error;
+ }
+
+ break;
+
+ case VIR_NETWORK_PORT_PLUG_TYPE_LAST:
+ default:
+ virReportEnumRangeError(virNetworkPortPlugType, port->plugtype);
+ goto error;
+ }
+
+ if (virNetDevVPortProfileCopy(&actual->virtPortProfile,
port->virtPortProfile) < 0)
+ goto error;
+
+ if (virNetDevBandwidthCopy(&actual->bandwidth, port->bandwidth) < 0)
+ goto error;
+
+ if (virNetDevVlanCopy(&actual->vlan, &port->vlan) < 0)
+ goto error;
+
+ actual->class_id = port->class_id;
+ actual->trustGuestRxFilters = port->trustGuestRxFilters;
+
+ virDomainActualNetDefFree(iface->data.network.actual);
+ iface->data.network.actual = actual;
+
+ return 0;
+
+ error:
+ virDomainActualNetDefFree(actual);
+ return -1;
+}
+
+virNetworkPortDefPtr
+virDomainNetDefActualToNetworkPort(virDomainDefPtr dom,
+ virDomainNetDefPtr iface)
+{
+ virDomainActualNetDefPtr actual;
+ virNetworkPortDefPtr port;
+
+ if (!iface->data.network.actual) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Missing actual data for interface '%s'"),
+ iface->ifname);
+ return NULL;
+ }
+
+ actual = iface->data.network.actual;
+
+ if (iface->type != VIR_DOMAIN_NET_TYPE_NETWORK) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Expected an interface of type 'network' not
'%s'"),
+ virDomainNetTypeToString(iface->type));
+ return NULL;
+ }
+
+ if (VIR_ALLOC(port) < 0)
+ return NULL;
+
+ /* Bad - we need to preserve original port uuid */
+ virUUIDGenerate(port->uuid);
+
+ memcpy(port->owneruuid, dom->uuid, VIR_UUID_BUFLEN);
+ if (VIR_STRDUP(port->ownername, dom->name) < 0)
+ goto error;
+
+ if (VIR_STRDUP(port->group, iface->data.network.portgroup) < 0)
+ goto error;
+
+ memcpy(&port->mac, &iface->mac, VIR_MAC_BUFLEN);
+
+ switch (virDomainNetGetActualType(iface)) {
+ case VIR_DOMAIN_NET_TYPE_NETWORK:
+ port->plugtype = VIR_NETWORK_PORT_PLUG_TYPE_NETWORK;
+ if (VIR_STRDUP(port->plug.bridge.brname,
+ actual->data.bridge.brname) < 0)
+ goto error;
+ port->plug.bridge.macTableManager = actual->data.bridge.macTableManager;
+ break;
+
+ case VIR_DOMAIN_NET_TYPE_BRIDGE:
+ port->plugtype = VIR_NETWORK_PORT_PLUG_TYPE_BRIDGE;
+ if (VIR_STRDUP(port->plug.bridge.brname,
+ actual->data.bridge.brname) < 0)
+ goto error;
+ port->plug.bridge.macTableManager = actual->data.bridge.macTableManager;
+ break;
+
+ case VIR_DOMAIN_NET_TYPE_DIRECT:
+ port->plugtype = VIR_NETWORK_PORT_PLUG_TYPE_DIRECT;
+ if (VIR_STRDUP(port->plug.direct.linkdev,
+ actual->data.direct.linkdev) < 0)
+ goto error;
+ port->plug.direct.mode = actual->data.direct.mode;
+ break;
+
+ case VIR_DOMAIN_NET_TYPE_HOSTDEV:
+ port->plugtype = VIR_NETWORK_PORT_PLUG_TYPE_HOSTDEV_PCI;
+ if (actual->data.hostdev.def.mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS ||
+ actual->data.hostdev.def.source.subsys.type !=
VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Actual interface '%s' hostdev was not a PCI
device"),
+ iface->ifname);
+ goto error;
+ }
+ port->plug.hostdevpci.managed = actual->data.hostdev.def.managed;
+ port->plug.hostdevpci.addr =
actual->data.hostdev.def.source.subsys.u.pci.addr;
+ switch
((virDomainHostdevSubsysPCIBackendType)actual->data.hostdev.def.source.subsys.u.pci.backend)
{
+ case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_DEFAULT:
+ port->plug.hostdevpci.driver = VIR_NETWORK_FORWARD_DRIVER_NAME_DEFAULT;
+ break;
+
+ case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_KVM:
+ port->plug.hostdevpci.driver = VIR_NETWORK_FORWARD_DRIVER_NAME_KVM;
+ break;
+
+ case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO:
+ port->plug.hostdevpci.driver = VIR_NETWORK_FORWARD_DRIVER_NAME_VFIO;
+ break;
+
+ case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_XEN:
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("Unexpected PCI backend 'xen'"));
+ break;
+
+ case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_TYPE_LAST:
+ default:
+ virReportEnumRangeError(virDomainHostdevSubsysPCIBackendType,
+
actual->data.hostdev.def.source.subsys.u.pci.backend);
+ goto error;
+ }
+
+ break;
+
+ case VIR_DOMAIN_NET_TYPE_CLIENT:
+ case VIR_DOMAIN_NET_TYPE_ETHERNET:
+ case VIR_DOMAIN_NET_TYPE_INTERNAL:
+ case VIR_DOMAIN_NET_TYPE_MCAST:
+ case VIR_DOMAIN_NET_TYPE_SERVER:
+ case VIR_DOMAIN_NET_TYPE_UDP:
+ case VIR_DOMAIN_NET_TYPE_USER:
+ case VIR_DOMAIN_NET_TYPE_VHOSTUSER:
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("Unexpected network port type %s"),
+ virDomainNetTypeToString(virDomainNetGetActualType(iface)));
+ goto error;
+
+ case VIR_DOMAIN_NET_TYPE_LAST:
+ default:
+ virReportEnumRangeError(virNetworkPortPlugType, port->plugtype);
+ goto error;
+ }
+
+ if (virNetDevVPortProfileCopy(&port->virtPortProfile,
actual->virtPortProfile) < 0)
+ goto error;
+
+ if (virNetDevBandwidthCopy(&port->bandwidth, actual->bandwidth) < 0)
+ goto error;
+
+ if (virNetDevVlanCopy(&port->vlan, &actual->vlan) < 0)
+ goto error;
+
+ port->class_id = actual->class_id;
+ port->trustGuestRxFilters = actual->trustGuestRxFilters;
+
+ return port;
+
+ error:
+ virNetworkPortDefFree(port);
+ return NULL;
+}
+
static virDomainNetAllocateActualDeviceImpl netAllocate;
static virDomainNetNotifyActualDeviceImpl netNotify;
static virDomainNetReleaseActualDeviceImpl netRelease;
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index fa0756b634..c0a94e3b5a 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -3552,6 +3552,23 @@ bool
virDomainDefLifecycleActionAllowed(virDomainLifecycle type,
virDomainLifecycleAction action);
+// Forward decl to avoid pulling in virnetworkportdef.h because
+// that pulls in virhostdev.h which pulls in domain_conf.h (evil)
+typedef struct _virNetworkPortDef virNetworkPortDef;
+typedef virNetworkPortDef *virNetworkPortDefPtr;
+
+virNetworkPortDefPtr
+virDomainNetDefToNetworkPort(virDomainDefPtr dom,
+ virDomainNetDefPtr iface);
+
+int
+virDomainNetDefActualFromNetworkPort(virDomainNetDefPtr iface,
+ virNetworkPortDefPtr port);
+
+virNetworkPortDefPtr
+virDomainNetDefActualToNetworkPort(virDomainDefPtr dom,
+ virDomainNetDefPtr iface);
+
typedef int
(*virDomainNetAllocateActualDeviceImpl)(virNetworkPtr net,
virDomainDefPtr dom,
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 62a07c094e..6646fc5039 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -458,9 +458,12 @@ virDomainNetAllocateActualDevice;
virDomainNetAppendIPAddress;
virDomainNetBandwidthChangeAllowed;
virDomainNetBandwidthUpdate;
+virDomainNetDefActualFromNetworkPort;
+virDomainNetDefActualToNetworkPort;
virDomainNetDefClear;
virDomainNetDefFormat;
virDomainNetDefFree;
+virDomainNetDefToNetworkPort;
virDomainNetFind;
virDomainNetFindByName;
virDomainNetFindIdx;