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; }
/** * 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; for (i = 0; i < def->nnets; i++) { char *veth = NULL; /* 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. */ if (networkAllocateActualDevice(def, def->nets[i]) < 0) goto cleanup; if (VIR_EXPAND_N(*veths, *nveths, 1) < 0) goto cleanup; switch (virDomainNetGetActualType(def->nets[i])) { case VIR_DOMAIN_NET_TYPE_NETWORK: { virNetworkPtr network; char *brname = NULL; bool fail = false; int active; virErrorPtr errobj; if (!(network = virNetworkLookupByName(conn, def->nets[i]->data.network.name))) goto cleanup; active = virNetworkIsActive(network); if (active != 1) { fail = true; if (active == 0) virReportError(VIR_ERR_INTERNAL_ERROR, _("Network '%s' is not active."), def->nets[i]->data.network.name); } if (!fail) { brname = virNetworkGetBridgeName(network); if (brname == NULL) fail = true; } /* Make sure any above failure is preserved */ errobj = virSaveLastError(); virNetworkFree(network); virSetError(errobj); virFreeError(errobj); if (fail) goto cleanup; if (!(veth = virLXCProcessSetupInterfaceBridged(conn, def, def->nets[i], brname))) { VIR_FREE(brname); goto cleanup; } VIR_FREE(brname); break; } case VIR_DOMAIN_NET_TYPE_BRIDGE: { const char *brname = virDomainNetGetActualBridgeName(def->nets[i]); if (!brname) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("No bridge name specified")); goto cleanup; } if (!(veth = virLXCProcessSetupInterfaceBridged(conn, def, def->nets[i], brname))) goto cleanup; } break; case VIR_DOMAIN_NET_TYPE_DIRECT: if (!(veth = virLXCProcessSetupInterfaceDirect(conn, def, def->nets[i]))) goto cleanup; break; case VIR_DOMAIN_NET_TYPE_USER: case VIR_DOMAIN_NET_TYPE_ETHERNET: 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: virReportError(VIR_ERR_INTERNAL_ERROR, _("Unsupported network type %s"), virDomainNetTypeToString( virDomainNetGetActualType(def->nets[i]) )); goto cleanup; } (*veths)[(*nveths)-1] = veth; } 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; }
static int bhyveBuildNetArgStr(const virDomainDef *def, virDomainNetDefPtr net, virCommandPtr cmd, bool dryRun) { char macaddr[VIR_MAC_STRING_BUFLEN]; char *realifname = NULL; char *brname = NULL; int actualType = virDomainNetGetActualType(net); if (actualType == VIR_DOMAIN_NET_TYPE_BRIDGE) { if (VIR_STRDUP(brname, virDomainNetGetActualBridgeName(net)) < 0) return -1; } else { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Network type %d is not supported"), virDomainNetGetActualType(net)); return -1; } if (!net->ifname || STRPREFIX(net->ifname, VIR_NET_GENERATED_PREFIX) || strchr(net->ifname, '%')) { VIR_FREE(net->ifname); if (VIR_STRDUP(net->ifname, VIR_NET_GENERATED_PREFIX "%d") < 0) { VIR_FREE(brname); return -1; } } if (!dryRun) { if (virNetDevTapCreateInBridgePort(brname, &net->ifname, &net->mac, def->uuid, NULL, NULL, 0, virDomainNetGetActualVirtPortProfile(net), virDomainNetGetActualVlan(net), VIR_NETDEV_TAP_CREATE_IFUP | VIR_NETDEV_TAP_CREATE_PERSIST) < 0) { VIR_FREE(net->ifname); VIR_FREE(brname); return -1; } realifname = virNetDevTapGetRealDeviceName(net->ifname); if (realifname == NULL) { VIR_FREE(net->ifname); VIR_FREE(brname); return -1; } VIR_DEBUG("%s -> %s", net->ifname, realifname); /* hack on top of other hack: we need to set * interface to 'UP' again after re-opening to find its * name */ if (virNetDevSetOnline(net->ifname, true) != 0) { VIR_FREE(realifname); VIR_FREE(net->ifname); VIR_FREE(brname); return -1; } } else { if (VIR_STRDUP(realifname, "tap0") < 0) return -1; } virCommandAddArg(cmd, "-s"); virCommandAddArgFormat(cmd, "%d:0,virtio-net,%s,mac=%s", net->info.addr.pci.slot, realifname, virMacAddrFormat(&net->mac, macaddr)); VIR_FREE(realifname); return 0; }
static int bhyveBuildNetArgStr(const virDomainDef *def, virCommandPtr cmd) { virDomainNetDefPtr net = NULL; char *brname = NULL; char *realifname = NULL; int *tapfd = NULL; if (def->nnets != 1) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("domain should have one and only one net defined")); return -1; } net = def->nets[0]; if (net) { int actualType = virDomainNetGetActualType(net); if (actualType == VIR_DOMAIN_NET_TYPE_BRIDGE) { if (VIR_STRDUP(brname, virDomainNetGetActualBridgeName(net)) < 0) return -1; } else { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Network type %d is not supported"), virDomainNetGetActualType(net)); return -1; } if (!net->ifname || STRPREFIX(net->ifname, VIR_NET_GENERATED_PREFIX) || strchr(net->ifname, '%')) { VIR_FREE(net->ifname); if (VIR_STRDUP(net->ifname, VIR_NET_GENERATED_PREFIX "%d") < 0) { VIR_FREE(brname); return -1; } } if (virNetDevTapCreateInBridgePort(brname, &net->ifname, &net->mac, def->uuid, tapfd, 1, virDomainNetGetActualVirtPortProfile(net), virDomainNetGetActualVlan(net), VIR_NETDEV_TAP_CREATE_IFUP | VIR_NETDEV_TAP_CREATE_PERSIST) < 0) { VIR_FREE(net->ifname); VIR_FREE(brname); return -1; } } realifname = virBhyveTapGetRealDeviceName(net->ifname); if (realifname == NULL) { VIR_FREE(net->ifname); VIR_FREE(brname); return -1; } VIR_DEBUG("%s -> %s", net->ifname, realifname); /* hack on top of other hack: we need to set * interface to 'UP' again after re-opening to find its * name */ if (virNetDevSetOnline(net->ifname, true) != 0) { VIR_FREE(net->ifname); VIR_FREE(brname); return -1; } virCommandAddArgList(cmd, "-s", "0:0,hostbridge", NULL); virCommandAddArg(cmd, "-s"); virCommandAddArgFormat(cmd, "1:0,virtio-net,%s", realifname); return 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; }
int qemuAssignDeviceAliases(virDomainDefPtr def, virQEMUCapsPtr qemuCaps) { size_t i; for (i = 0; i < def->ndisks; i++) { if (qemuAssignDeviceDiskAlias(def, def->disks[i], qemuCaps) < 0) return -1; } for (i = 0; i < def->nnets; i++) { /* type='hostdev' interfaces are also on the hostdevs list, * and will have their alias assigned with other hostdevs. */ if (virDomainNetGetActualType(def->nets[i]) != VIR_DOMAIN_NET_TYPE_HOSTDEV && qemuAssignDeviceNetAlias(def, def->nets[i], i) < 0) { return -1; } } if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) return 0; for (i = 0; i < def->nfss; i++) { if (virAsprintf(&def->fss[i]->info.alias, "fs%zu", i) < 0) return -1; } for (i = 0; i < def->nsounds; i++) { if (virAsprintf(&def->sounds[i]->info.alias, "sound%zu", i) < 0) return -1; } for (i = 0; i < def->nhostdevs; i++) { if (qemuAssignDeviceHostdevAlias(def, def->hostdevs[i], i) < 0) return -1; } for (i = 0; i < def->nredirdevs; i++) { if (qemuAssignDeviceRedirdevAlias(def, def->redirdevs[i], i) < 0) return -1; } for (i = 0; i < def->nvideos; i++) { if (virAsprintf(&def->videos[i]->info.alias, "video%zu", i) < 0) return -1; } for (i = 0; i < def->ncontrollers; i++) { if (qemuAssignDeviceControllerAlias(def, qemuCaps, def->controllers[i]) < 0) return -1; } for (i = 0; i < def->ninputs; i++) { if (virAsprintf(&def->inputs[i]->info.alias, "input%zu", i) < 0) return -1; } for (i = 0; i < def->nparallels; i++) { if (qemuAssignDeviceChrAlias(def, def->parallels[i], i) < 0) return -1; } for (i = 0; i < def->nserials; i++) { if (qemuAssignDeviceChrAlias(def, def->serials[i], i) < 0) return -1; } for (i = 0; i < def->nchannels; i++) { if (qemuAssignDeviceChrAlias(def, def->channels[i], i) < 0) return -1; } for (i = 0; i < def->nconsoles; i++) { if (qemuAssignDeviceChrAlias(def, def->consoles[i], i) < 0) return -1; } for (i = 0; i < def->nhubs; i++) { if (virAsprintf(&def->hubs[i]->info.alias, "hub%zu", i) < 0) return -1; } for (i = 0; i < def->nshmems; i++) { if (virAsprintf(&def->shmems[i]->info.alias, "shmem%zu", i) < 0) return -1; } for (i = 0; i < def->nsmartcards; i++) { if (virAsprintf(&def->smartcards[i]->info.alias, "smartcard%zu", i) < 0) return -1; } if (def->watchdog) { if (virAsprintf(&def->watchdog->info.alias, "watchdog%d", 0) < 0) return -1; } if (def->memballoon) { if (virAsprintf(&def->memballoon->info.alias, "balloon%d", 0) < 0) return -1; } for (i = 0; i < def->nrngs; i++) { if (qemuAssignDeviceRNGAlias(def->rngs[i], i) < 0) return -1; } if (def->tpm) { if (virAsprintf(&def->tpm->info.alias, "tpm%d", 0) < 0) return -1; } for (i = 0; i < def->nmems; i++) { if (virAsprintf(&def->mems[i]->info.alias, "dimm%zu", i) < 0) return -1; } return 0; }