virDomainNetDefActualToNetworkPort(virDomainDefPtr dom,
                                   virDomainNetDefPtr iface)
{
    virDomainActualNetDefPtr actual;
    g_autoptr(virNetworkPortDef) port = NULL;

    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;

    if (virUUIDIsValid(iface->data.network.portid)) {
        memcpy(port->uuid, iface->data.network.portid, VIR_UUID_BUFLEN);
    } else if (virUUIDGenerate(port->uuid) < 0) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       "%s", _("Failed to generate UUID"));
        return NULL;
    }

    memcpy(port->owneruuid, dom->uuid, VIR_UUID_BUFLEN);
    port->ownername = g_strdup(dom->name);

    port->group = g_strdup(iface->data.network.portgroup);

    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;
        port->plug.bridge.brname = g_strdup(actual->data.bridge.brname);
        port->plug.bridge.macTableManager = actual->data.bridge.macTableManager;
        break;

    case VIR_DOMAIN_NET_TYPE_BRIDGE:
        port->plugtype = VIR_NETWORK_PORT_PLUG_TYPE_BRIDGE;
        port->plug.bridge.brname = g_strdup(actual->data.bridge.brname);
        port->plug.bridge.macTableManager = actual->data.bridge.macTableManager;
        break;

    case VIR_DOMAIN_NET_TYPE_DIRECT:
        port->plugtype = VIR_NETWORK_PORT_PLUG_TYPE_DIRECT;
        port->plug.direct.linkdev = g_strdup(actual->data.direct.linkdev);
        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);
            return NULL;
        }
        port->plug.hostdevpci.managed = virTristateBoolFromBool(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);
            return NULL;
        }

        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)));
        return NULL;

    case VIR_DOMAIN_NET_TYPE_LAST:
    default:
        virReportEnumRangeError(virNetworkPortPlugType, port->plugtype);
        return NULL;
    }

    if (virNetDevVPortProfileCopy(&port->virtPortProfile, actual->virtPortProfile) < 0)
        return NULL;

    if (virNetDevBandwidthCopy(&port->bandwidth, actual->bandwidth) < 0)
        return NULL;

    if (virNetDevVlanCopy(&port->vlan, &actual->vlan) < 0)
        return NULL;

    port->isolatedPort = actual->isolatedPort;
    port->class_id = actual->class_id;
    port->trustGuestRxFilters = actual->trustGuestRxFilters;

    return g_steal_pointer(&port);
}