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