Пример #1
0
char *virLXCProcessSetupInterfaceDirect(virConnectPtr conn,
                                        virDomainDefPtr def,
                                        virDomainNetDefPtr net)
{
    char *ret = NULL;
    char *res_ifname = NULL;
    virLXCDriverPtr driver = conn->privateData;
    virNetDevBandwidthPtr bw;
    virNetDevVPortProfilePtr prof;
    virLXCDriverConfigPtr cfg = virLXCDriverGetConfig(driver);

    /* XXX how todo bandwidth controls ?
     * Since the 'net-ifname' is about to be moved to a different
     * namespace & renamed, there will be no host side visible
     * interface for the container to attach rules to
     */
    bw = virDomainNetGetActualBandwidth(net);
    if (bw) {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("Unable to set network bandwidth on direct interfaces"));
        return NULL;
    }

    /* XXX how todo port profiles ?
     * Although we can do the association during container
     * startup, at shutdown we are unable to disassociate
     * because the macvlan device was moved to the container
     * and automagically dies when the container dies. So
     * we have no dev to perform disassociation with.
     */
    prof = virDomainNetGetActualVirtPortProfile(net);
    if (prof) {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("Unable to set port profile on direct interfaces"));
        return NULL;
    }

    if (virNetDevMacVLanCreateWithVPortProfile(
            net->ifname, &net->mac,
            virDomainNetGetActualDirectDev(net),
            virDomainNetGetActualDirectMode(net),
            false, false, def->uuid,
            virDomainNetGetActualVirtPortProfile(net),
            &res_ifname,
            VIR_NETDEV_VPORT_PROFILE_OP_CREATE,
            cfg->stateDir,
            virDomainNetGetActualBandwidth(net)) < 0)
        goto cleanup;

    ret = res_ifname;

 cleanup:
    virObjectUnref(cfg);
    return ret;
}
Пример #2
0
char *virLXCProcessSetupInterfaceBridged(virConnectPtr conn,
                                         virDomainDefPtr vm,
                                         virDomainNetDefPtr net,
                                         const char *brname)
{
    char *ret = NULL;
    char *parentVeth;
    char *containerVeth = NULL;
    virNetDevVPortProfilePtr vport = virDomainNetGetActualVirtPortProfile(net);

    VIR_DEBUG("calling vethCreate()");
    parentVeth = net->ifname;
    if (virNetDevVethCreate(&parentVeth, &containerVeth) < 0)
        goto cleanup;
    VIR_DEBUG("parentVeth: %s, containerVeth: %s", parentVeth, containerVeth);

    if (net->ifname == NULL)
        net->ifname = parentVeth;

    if (virNetDevSetMAC(containerVeth, &net->mac) < 0)
        goto cleanup;

    if (vport && vport->virtPortType == VIR_NETDEV_VPORT_PROFILE_OPENVSWITCH) {
        if (virNetDevOpenvswitchAddPort(brname, parentVeth, &net->mac,
                                        vm->uuid, vport, virDomainNetGetActualVlan(net)) < 0)
            goto cleanup;
    } else {
        if (virNetDevBridgeAddPort(brname, parentVeth) < 0)
            goto cleanup;
    }

    if (virNetDevSetOnline(parentVeth, true) < 0)
        goto cleanup;

    if (virNetDevBandwidthSet(net->ifname,
                              virDomainNetGetActualBandwidth(net),
                              false) < 0) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("cannot set bandwidth limits on %s"),
                       net->ifname);
        goto cleanup;
    }

    if (net->filter &&
        virDomainConfNWFilterInstantiate(conn, vm->uuid, net) < 0)
        goto cleanup;

    ret = containerVeth;

 cleanup:
    return ret;
}
Пример #3
0
void
virDomainClearNetBandwidth(virDomainObjPtr vm)
{
    size_t i;
    virDomainNetType type;

    for (i = 0; i < vm->def->nnets; i++) {
        type = virDomainNetGetActualType(vm->def->nets[i]);
        if (virDomainNetGetActualBandwidth(vm->def->nets[i]) &&
            virNetDevSupportBandwidth(type))
            virNetDevBandwidthClear(vm->def->nets[i]->ifname);
    }
}
Пример #4
0
/**
 * virLXCProcessSetupInterfaces:
 * @conn: pointer to connection
 * @def: pointer to virtual machine structure
 * @nveths: number of interfaces
 * @veths: interface names
 *
 * Sets up the container interfaces by creating the veth device pairs and
 * attaching the parent end to the appropriate bridge.  The container end
 * will moved into the container namespace later after clone has been called.
 *
 * Returns 0 on success or -1 in case of error
 */
static int virLXCProcessSetupInterfaces(virConnectPtr conn,
                                        virDomainDefPtr def,
                                        size_t *nveths,
                                        char ***veths)
{
    int ret = -1;
    size_t i;
    size_t niface = 0;
    virDomainNetDefPtr net;
    virDomainNetType type;

    for (i = 0; i < def->nnets; i++) {
        char *veth = NULL;
        virNetDevBandwidthPtr actualBandwidth;
        /* If appropriate, grab a physical device from the configured
         * network's pool of devices, or resolve bridge device name
         * to the one defined in the network definition.
         */
        net = def->nets[i];
        if (networkAllocateActualDevice(def, net) < 0)
            goto cleanup;

        if (VIR_EXPAND_N(*veths, *nveths, 1) < 0)
            goto cleanup;

        type = virDomainNetGetActualType(net);
        switch (type) {
        case VIR_DOMAIN_NET_TYPE_NETWORK:
        case VIR_DOMAIN_NET_TYPE_BRIDGE: {
            const char *brname = virDomainNetGetActualBridgeName(net);
            if (!brname) {
                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                               _("No bridge name specified"));
                goto cleanup;
            }
            if (!(veth = virLXCProcessSetupInterfaceBridged(def,
                                                            net,
                                                            brname)))
                goto cleanup;
        }   break;

        case VIR_DOMAIN_NET_TYPE_DIRECT:
            if (!(veth = virLXCProcessSetupInterfaceDirect(conn,
                                                           def,
                                                           net)))
                goto cleanup;
            break;

        case VIR_DOMAIN_NET_TYPE_ETHERNET:
            break;

        case VIR_DOMAIN_NET_TYPE_USER:
        case VIR_DOMAIN_NET_TYPE_VHOSTUSER:
        case VIR_DOMAIN_NET_TYPE_SERVER:
        case VIR_DOMAIN_NET_TYPE_CLIENT:
        case VIR_DOMAIN_NET_TYPE_MCAST:
        case VIR_DOMAIN_NET_TYPE_INTERNAL:
        case VIR_DOMAIN_NET_TYPE_LAST:
        case VIR_DOMAIN_NET_TYPE_HOSTDEV:
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("Unsupported network type %s"),
                           virDomainNetTypeToString(type));
            goto cleanup;

        }

        /* Set bandwidth or warn if requested and not supported. */
        actualBandwidth = virDomainNetGetActualBandwidth(net);
        if (actualBandwidth) {
            if (virNetDevSupportBandwidth(type)) {
                if (virNetDevBandwidthSet(net->ifname, actualBandwidth, false) < 0)
                    goto cleanup;
            } else {
                VIR_WARN("setting bandwidth on interfaces of "
                         "type '%s' is not implemented yet",
                         virDomainNetTypeToString(type));
            }
        }

        (*veths)[(*nveths)-1] = veth;

        if (VIR_STRDUP(def->nets[i]->ifname_guest_actual, veth) < 0)
            goto cleanup;

        /* Make sure all net definitions will have a name in the container */
        if (!net->ifname_guest) {
            if (virAsprintf(&net->ifname_guest, "eth%zu", niface) < 0)
                return -1;
            niface++;
        }
    }

    ret = 0;

 cleanup:
    if (ret < 0) {
        for (i = 0; i < def->nnets; i++) {
            virDomainNetDefPtr iface = def->nets[i];
            virNetDevVPortProfilePtr vport = virDomainNetGetActualVirtPortProfile(iface);
            if (vport && vport->virtPortType == VIR_NETDEV_VPORT_PROFILE_OPENVSWITCH)
                ignore_value(virNetDevOpenvswitchRemovePort(
                                virDomainNetGetActualBridgeName(iface),
                                iface->ifname));
            networkReleaseActualDevice(def, iface);
        }
    }
    return ret;
}