Esempio n. 1
0
// libxl internal in libxl__device_nic_add()
int hyperxl_nic_add(libxl_ctx* ctx, uint32_t domid, hyperxl_nic_config* config) {

    libxl_device_nic nic;
    libxl_mac mac;
    int i, ret = -1;

    libxl_device_nic_init(&nic);
    nic.backend_domid = 0;
    nic.mtu = 1492;
    nic.model = strdup("e1000");
    nic.ip = strdup(config->ip);
    nic.bridge = strdup(config->bridge);
    nic.nictype = LIBXL_NIC_TYPE_VIF_IOEMU;
    nic.ifname = strdup(config->ifname);
    nic.gatewaydev = strdup(config->gatewaydev);
    if (config->mac != NULL) {
        for (i=0; i<6; i++) {
            mac[i] = (uint8_t)(*(config->mac + i));
        }
        libxl_mac_copy(ctx, &nic.mac, &mac);
    }

    if( libxl_device_nic_add(ctx, domid, &nic, 0) ) {
        goto cleanup;
    }

    ret = 0;

cleanup:
    libxl_device_nic_dispose(&nic);
    return ret;
}
Esempio n. 2
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;
}
Esempio n. 3
0
int hyperxl_nic_remove(libxl_ctx* ctx, uint32_t domid, const char* mac) {
    libxl_device_nic nic;
    int ret = -1;

    libxl_device_nic_init(&nic);
    if(libxl_mac_to_device_nic(ctx, domid, mac, &nic)) {
        char* msg = "failed to get device from mac";
        hyperxl_log_cgo(msg, strlen(msg));
        goto cleanup;
    }

    if(libxl_device_nic_remove(ctx, domid, &nic, 0)) {
        char* msg = "failed to remove nic from domain";
        hyperxl_log_cgo(msg, strlen(msg));
        goto cleanup;
    }
    ret = 0;

cleanup:
    libxl_device_nic_dispose(&nic);
    return ret;
}
Esempio n. 4
0
int libxl_devid_to_device_nic(libxl_ctx *ctx, uint32_t domid,
                              int devid, libxl_device_nic *nic)
{
    GC_INIT(ctx);
    char *libxl_dom_path, *libxl_path;
    int rc = ERROR_FAIL;

    libxl_device_nic_init(nic);
    libxl_dom_path = libxl__xs_libxl_path(gc, domid);
    if (!libxl_dom_path)
        goto out;

    libxl_path = GCSPRINTF("%s/device/vif/%d", libxl_dom_path, devid);

    rc = libxl__device_nic_from_xenstore(gc, libxl_path, nic);
    if (rc) goto out;

    rc = 0;
out:
    GC_FREE;
    return rc;
}
Esempio n. 5
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;
}
Esempio n. 6
0
static int libxl__device_nic_from_xenstore(libxl__gc *gc,
                                           const char *libxl_path,
                                           libxl_device_nic *nic)
{
    const char *tmp;
    int rc;

    libxl_device_nic_init(nic);

    rc = libxl__xs_read_checked(gc, XBT_NULL,
                                GCSPRINTF("%s/handle", libxl_path), &tmp);
    if (rc) goto out;
    if (tmp)
        nic->devid = atoi(tmp);
    else
        nic->devid = 0;

    /* nic->mtu = */

    rc = libxl__xs_read_checked(gc, XBT_NULL,
                                GCSPRINTF("%s/mac", libxl_path), &tmp);
    if (rc) goto out;
    if (tmp) {
        rc = libxl__parse_mac(tmp, nic->mac);
        if (rc) goto out;
    } else {
        memset(nic->mac, 0, sizeof(nic->mac));
    }

    rc = libxl__xs_read_checked(NOGC, XBT_NULL,
                                GCSPRINTF("%s/ip", libxl_path),
                                (const char **)(&nic->ip));
    if (rc) goto out;
    rc = libxl__xs_read_checked(NOGC, XBT_NULL,
                                GCSPRINTF("%s/bridge", libxl_path),
                                (const char **)(&nic->bridge));
    if (rc) goto out;
    rc = libxl__xs_read_checked(NOGC, XBT_NULL,
                                GCSPRINTF("%s/script", libxl_path),
                                (const char **)(&nic->script));
    if (rc) goto out;
    rc = libxl__xs_read_checked(NOGC, XBT_NULL,
                                GCSPRINTF("%s/forwarddev", libxl_path),
                                (const char **)(&nic->coloft_forwarddev));
    if (rc) goto out;

    /* vif_ioemu nics use the same xenstore entries as vif interfaces */
    rc = libxl__xs_read_checked(gc, XBT_NULL,
                                GCSPRINTF("%s/type", libxl_path), &tmp);
    if (rc) goto out;
    if (tmp) {
        rc = libxl_nic_type_from_string(tmp, &nic->nictype);
        if (rc) goto out;
    } else {
        nic->nictype = LIBXL_NIC_TYPE_VIF;
    }
    nic->model = NULL; /* XXX Only for TYPE_IOEMU */
    nic->ifname = NULL; /* XXX Only for TYPE_IOEMU */

    rc = 0;
 out:
    return rc;
}
Esempio n. 7
0
static void libxl__device_nic_add(libxl__egc *egc, uint32_t domid,
                                  libxl_device_nic *nic,
                                  libxl__ao_device *aodev)
{
    STATE_AO_GC(aodev->ao);
    flexarray_t *front;
    flexarray_t *back;
    libxl__device *device;
    int rc;
    xs_transaction_t t = XBT_NULL;
    libxl_domain_config d_config;
    libxl_device_nic nic_saved;
    libxl__domain_userdata_lock *lock = NULL;

    libxl_domain_config_init(&d_config);
    libxl_device_nic_init(&nic_saved);
    libxl_device_nic_copy(CTX, &nic_saved, nic);

    rc = libxl__device_nic_setdefault(gc, nic, domid, aodev->update_json);
    if (rc) goto out;

    front = flexarray_make(gc, 16, 1);
    back = flexarray_make(gc, 18, 1);

    if (nic->devid == -1) {
        if ((nic->devid = libxl__device_nextid(gc, domid, "vif")) < 0) {
            rc = ERROR_FAIL;
            goto out;
        }
    }

    libxl__update_config_nic(gc, &nic_saved, nic);

    GCNEW(device);
    rc = libxl__device_from_nic(gc, domid, nic, device);
    if ( rc != 0 ) goto out;

    flexarray_append(back, "frontend-id");
    flexarray_append(back, GCSPRINTF("%d", domid));
    flexarray_append(back, "online");
    flexarray_append(back, "1");
    flexarray_append(back, "state");
    flexarray_append(back, GCSPRINTF("%d", XenbusStateInitialising));
    if (nic->script)
        flexarray_append_pair(back, "script",
                              libxl__abs_path(gc, nic->script,
                                              libxl__xen_script_dir_path()));

    if (nic->ifname) {
        flexarray_append(back, "vifname");
        flexarray_append(back, nic->ifname);
    }

    if (nic->coloft_forwarddev) {
        flexarray_append(back, "forwarddev");
        flexarray_append(back, nic->coloft_forwarddev);
    }

    flexarray_append(back, "mac");
    flexarray_append(back,GCSPRINTF(LIBXL_MAC_FMT, LIBXL_MAC_BYTES(nic->mac)));
    if (nic->ip) {
        flexarray_append(back, "ip");
        flexarray_append(back, libxl__strdup(gc, nic->ip));
    }
    if (nic->gatewaydev) {
        flexarray_append(back, "gatewaydev");
        flexarray_append(back, libxl__strdup(gc, nic->gatewaydev));
    }

    if (nic->rate_interval_usecs > 0) {
        flexarray_append(back, "rate");
        flexarray_append(back, GCSPRINTF("%"PRIu64",%"PRIu32"",
                            nic->rate_bytes_per_interval,
                            nic->rate_interval_usecs));
    }

    flexarray_append(back, "bridge");
    flexarray_append(back, libxl__strdup(gc, nic->bridge));
    flexarray_append(back, "handle");
    flexarray_append(back, GCSPRINTF("%d", nic->devid));
    flexarray_append(back, "type");
    flexarray_append(back, libxl__strdup(gc,
                                     libxl_nic_type_to_string(nic->nictype)));

    flexarray_append(front, "backend-id");
    flexarray_append(front, GCSPRINTF("%d", nic->backend_domid));
    flexarray_append(front, "state");
    flexarray_append(front, GCSPRINTF("%d", XenbusStateInitialising));
    flexarray_append(front, "handle");
    flexarray_append(front, GCSPRINTF("%d", nic->devid));
    flexarray_append(front, "mac");
    flexarray_append(front, GCSPRINTF(
                                    LIBXL_MAC_FMT, LIBXL_MAC_BYTES(nic->mac)));

    if (aodev->update_json) {
        lock = libxl__lock_domain_userdata(gc, domid);
        if (!lock) {
            rc = ERROR_LOCK_FAIL;
            goto out;
        }

        rc = libxl__get_domain_configuration(gc, domid, &d_config);
        if (rc) goto out;

        DEVICE_ADD(nic, nics, domid, &nic_saved, COMPARE_DEVID, &d_config);

        rc = libxl__dm_check_start(gc, &d_config, domid);
        if (rc) goto out;
    }

    for (;;) {
        rc = libxl__xs_transaction_start(gc, &t);
        if (rc) goto out;

        rc = libxl__device_exists(gc, t, device);
        if (rc < 0) goto out;
        if (rc == 1) {              /* already exists in xenstore */
            LOG(ERROR, "device already exists in xenstore");
            aodev->action = LIBXL__DEVICE_ACTION_ADD; /* for error message */
            rc = ERROR_DEVICE_EXISTS;
            goto out;
        }

        if (aodev->update_json) {
            rc = libxl__set_domain_configuration(gc, domid, &d_config);
            if (rc) goto out;
        }

        libxl__device_generic_add(gc, t, device,
                                  libxl__xs_kvs_of_flexarray(gc, back,
                                                             back->count),
                                  libxl__xs_kvs_of_flexarray(gc, front,
                                                             front->count),
                                  NULL);

        rc = libxl__xs_transaction_commit(gc, &t);
        if (!rc) break;
        if (rc < 0) goto out;
    }

    aodev->dev = device;
    aodev->action = LIBXL__DEVICE_ACTION_ADD;
    libxl__wait_device_connection(egc, aodev);

    rc = 0;
out:
    libxl__xs_transaction_abort(gc, &t);
    if (lock) libxl__unlock_domain_userdata(lock);
    libxl_device_nic_dispose(&nic_saved);
    libxl_domain_config_dispose(&d_config);
    aodev->rc = rc;
    if (rc) aodev->callback(egc, aodev);
    return;
}