Example #1
0
int
libxlMakeNic(virDomainDefPtr def,
             virDomainNetDefPtr l_nic,
             libxl_device_nic *x_nic)
{
    bool ioemu_nic = STREQ(def->os.type, "hvm");

    /* TODO: Where is mtu stored?
     *
     * x_nics[i].mtu = 1492;
     */

    libxl_device_nic_init(x_nic);

    virMacAddrGetRaw(&l_nic->mac, x_nic->mac);

    if (ioemu_nic)
        x_nic->nictype = LIBXL_NIC_TYPE_VIF_IOEMU;
    else
        x_nic->nictype = LIBXL_NIC_TYPE_VIF;

    if (l_nic->model) {
        if (VIR_STRDUP(x_nic->model, l_nic->model) < 0)
            return -1;
        if (STREQ(l_nic->model, "netfront"))
            x_nic->nictype = LIBXL_NIC_TYPE_VIF;
    }

    if (VIR_STRDUP(x_nic->ifname, l_nic->ifname) < 0)
        return -1;

    switch (l_nic->type) {
        case VIR_DOMAIN_NET_TYPE_BRIDGE:
            if (VIR_STRDUP(x_nic->bridge, l_nic->data.bridge.brname) < 0)
                return -1;
            /* fallthrough */
        case VIR_DOMAIN_NET_TYPE_ETHERNET:
            if (VIR_STRDUP(x_nic->script, l_nic->script) < 0)
                return -1;
            break;
        default:
            virReportError(VIR_ERR_INTERNAL_ERROR,
                    _("libxenlight does not support network device type %s"),
                    virDomainNetTypeToString(l_nic->type));
            return -1;
    }

    return 0;
}
Example #2
0
int
libxlMakeNic(virDomainDefPtr def,
             virDomainNetDefPtr l_nic,
             libxl_device_nic *x_nic)
{
    bool ioemu_nic = STREQ(def->os.type, "hvm");
    virDomainNetType actual_type = virDomainNetGetActualType(l_nic);

    /* TODO: Where is mtu stored?
     *
     * x_nics[i].mtu = 1492;
     */

    if (l_nic->script && !(actual_type == VIR_DOMAIN_NET_TYPE_BRIDGE ||
                           actual_type == VIR_DOMAIN_NET_TYPE_ETHERNET)) {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("specifying a script is only supported with "
                         "interface types bridge and ethernet"));
        return -1;
    }

    libxl_device_nic_init(x_nic);

    virMacAddrGetRaw(&l_nic->mac, x_nic->mac);

    if (ioemu_nic)
        x_nic->nictype = LIBXL_NIC_TYPE_VIF_IOEMU;
    else
        x_nic->nictype = LIBXL_NIC_TYPE_VIF;

    if (l_nic->model) {
        if (VIR_STRDUP(x_nic->model, l_nic->model) < 0)
            return -1;
        if (STREQ(l_nic->model, "netfront"))
            x_nic->nictype = LIBXL_NIC_TYPE_VIF;
    }

    if (VIR_STRDUP(x_nic->ifname, l_nic->ifname) < 0)
        return -1;

    switch (actual_type) {
        case VIR_DOMAIN_NET_TYPE_BRIDGE:
            if (VIR_STRDUP(x_nic->bridge,
                           virDomainNetGetActualBridgeName(l_nic)) < 0)
                return -1;
            /* fallthrough */
        case VIR_DOMAIN_NET_TYPE_ETHERNET:
            if (VIR_STRDUP(x_nic->script, l_nic->script) < 0)
                return -1;
            break;
        case VIR_DOMAIN_NET_TYPE_NETWORK:
        {
            bool fail = false;
            char *brname = NULL;
            virNetworkPtr network;
            virConnectPtr conn;
            virErrorPtr errobj;

            if (!(conn = virConnectOpen("xen:///system")))
                return -1;

            if (!(network =
                  virNetworkLookupByName(conn, l_nic->data.network.name))) {
                virObjectUnref(conn);
                return -1;
            }

            if ((brname = virNetworkGetBridgeName(network))) {
                if (VIR_STRDUP(x_nic->bridge, brname) < 0)
                    fail = true;
            } else {
                fail = true;
            }

            VIR_FREE(brname);

            /* Preserve any previous failure */
            errobj = virSaveLastError();
            virNetworkFree(network);
            virSetError(errobj);
            virFreeError(errobj);
            virObjectUnref(conn);
            if (fail)
                return -1;
            break;
        }
        case VIR_DOMAIN_NET_TYPE_USER:
        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_DIRECT:
        case VIR_DOMAIN_NET_TYPE_HOSTDEV:
        case VIR_DOMAIN_NET_TYPE_LAST:
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                    _("unsupported interface type %s"),
                    virDomainNetTypeToString(l_nic->type));
            return -1;
    }

    return 0;
}
Example #3
0
/*
 * virNetDevBandwidthPlug:
 * @brname: name of the bridge
 * @net_bandwidth: QoS settings on @brname
 * @ifmac: MAC of interface
 * @bandwidth: QoS settings for interface
 * @id: unique ID (MUST be greater than 2)
 *
 * Set bridge part of interface QoS settings, e.g. guaranteed
 * bandwidth.  @id is an unique ID (among @brname) from which
 * other identifiers for class, qdisc and filter are derived.
 * However, two classes were already set up (by
 * virNetDevBandwidthSet). That's why this @id MUST be greater
 * than 2. You may want to keep passed @id, as it is used later
 * by virNetDevBandwidthUnplug.
 *
 * Returns:
 * 0 if QoS set successfully
 * -1 otherwise.
 */
int
virNetDevBandwidthPlug(const char *brname,
                       virNetDevBandwidthPtr net_bandwidth,
                       const virMacAddrPtr ifmac_ptr,
                       virNetDevBandwidthPtr bandwidth,
                       unsigned int id)
{
    int ret = -1;
    virCommandPtr cmd = NULL;
    char *class_id = NULL;
    char *qdisc_id = NULL;
    char *filter_id = NULL;
    char *floor = NULL;
    char *ceil = NULL;
    unsigned char ifmac[VIR_MAC_BUFLEN];
    char ifmacStr[VIR_MAC_STRING_BUFLEN];
    char *mac[2] = {NULL, NULL};

    if (id <= 2) {
        virReportError(VIR_ERR_INTERNAL_ERROR, _("Invalid class ID %d"), id);
        return -1;
    }

    virMacAddrGetRaw(ifmac_ptr, ifmac);
    virMacAddrFormat(ifmac_ptr, ifmacStr);

    if (!net_bandwidth || !net_bandwidth->in) {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("Bridge '%s' has no QoS set, therefore "
                         "unable to set 'floor' on '%s'"),
                       brname, ifmacStr);
        return -1;
    }

    if (virAsprintf(&class_id, "1:%x", id) < 0 ||
        virAsprintf(&qdisc_id, "%x:", id) < 0 ||
        virAsprintf(&filter_id, "%u", id) < 0 ||
        virAsprintf(&mac[0], "0x%02x%02x%02x%02x", ifmac[2],
                    ifmac[3], ifmac[4], ifmac[5]) < 0 ||
        virAsprintf(&mac[1], "0x%02x%02x", ifmac[0], ifmac[1]) < 0 ||
        virAsprintf(&floor, "%llukbps", bandwidth->in->floor) < 0 ||
        virAsprintf(&ceil, "%llukbps", net_bandwidth->in->peak ?
                    net_bandwidth->in->peak :
                    net_bandwidth->in->average) < 0) {
        virReportOOMError();
        goto cleanup;
    }

    cmd = virCommandNew(TC);
    virCommandAddArgList(cmd, "class", "add", "dev", brname, "parent", "1:1",
                         "classid", class_id, "htb", "rate", floor,
                         "ceil", ceil, NULL);

    if (virCommandRun(cmd, NULL) < 0)
        goto cleanup;

    virCommandFree(cmd);
    cmd = virCommandNew(TC);
    virCommandAddArgList(cmd, "qdisc", "add", "dev", brname, "parent",
                         class_id, "handle", qdisc_id, "sfq", "perturb",
                         "10", NULL);

    if (virCommandRun(cmd, NULL) < 0)
        goto cleanup;

    virCommandFree(cmd);
    cmd = virCommandNew(TC);
    /* Okay, this not nice. But since libvirt does not know anything about
     * interface IP address(es), and tc fw filter simply refuse to use ebtables
     * marks, we need to use u32 selector to match MAC address.
     * If libvirt will ever know something, remove this FIXME
     */
    virCommandAddArgList(cmd, "filter", "add", "dev", brname, "protocol", "ip",
                         "prio", filter_id, "u32",
                         "match", "u16", "0x0800", "0xffff", "at", "-2",
                         "match", "u32", mac[0], "0xffffffff", "at", "-12",
                         "match", "u16", mac[1], "0xffff", "at", "-14",
                         "flowid", class_id, NULL);

    if (virCommandRun(cmd, NULL) < 0)
        goto cleanup;

    ret = 0;

cleanup:
    VIR_FREE(mac[1]);
    VIR_FREE(mac[0]);
    VIR_FREE(ceil);
    VIR_FREE(floor);
    VIR_FREE(filter_id);
    VIR_FREE(qdisc_id);
    VIR_FREE(class_id);
    virCommandFree(cmd);
    return ret;
}