Example #1
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;
}
Example #2
0
static int
testVirNetDevBandwidthSet(const void *data)
{
    int ret = -1;
    const struct testSetStruct *info = data;
    const char *iface = info->iface;
    virNetDevBandwidthPtr band = NULL;
    virBuffer buf = VIR_BUFFER_INITIALIZER;
    char *actual_cmd = NULL;

    PARSE(info->band, band);

    if (!iface)
        iface = "eth0";

    virCommandSetDryRun(&buf, NULL, NULL);

    if (virNetDevBandwidthSet(iface, band, info->hierarchical_class) < 0)
        goto cleanup;

    if (!(actual_cmd = virBufferContentAndReset(&buf))) {
        int err = virBufferError(&buf);
        if (err) {
            fprintf(stderr, "buffer's in error state: %d", err);
            goto cleanup;
        }
        /* This is interesting, no command has been executed.
         * Maybe that's expected, actually. */
    }

    if (STRNEQ_NULLABLE(info->exp_cmd, actual_cmd)) {
        virTestDifference(stderr,
                          NULLSTR(info->exp_cmd),
                          NULLSTR(actual_cmd));
        goto cleanup;
    }

    ret = 0;
cleanup:
    virCommandSetDryRun(NULL, NULL, NULL);
    virNetDevBandwidthFree(band);
    virBufferFreeAndReset(&buf);
    VIR_FREE(actual_cmd);
    return ret;
}
Example #3
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;
}