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

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

    case VIR_NETWORK_PORT_PLUG_TYPE_DIRECT:
        actual->type = VIR_DOMAIN_NET_TYPE_DIRECT;
        actual->data.direct.linkdev = g_strdup(port->plug.direct.linkdev);
        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;
        switch (port->plug.hostdevpci.managed) {
        case VIR_TRISTATE_BOOL_YES:
            actual->data.hostdev.def.managed = true;
            break;
        case VIR_TRISTATE_BOOL_ABSENT:
        case VIR_TRISTATE_BOOL_NO:
            actual->data.hostdev.def.managed = false;
            break;
        }
        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->isolatedPort = port->isolatedPort;
    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;
}