// 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; }
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; }
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; }
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; }
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; }
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; }
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; }