static int parallelsGetBridgedNetInfo(virNetworkDefPtr def, virJSONValuePtr jobj) { const char *ifname; char *bridgeLink = NULL; char *bridgePath = NULL; char *bridgeAddressPath = NULL; char *bridgeAddress = NULL; int len = 0; int ret = -1; if (!(ifname = virJSONValueObjectGetString(jobj, "Bound To"))) { parallelsParseError(); goto cleanup; } if (virAsprintf(&bridgeLink, SYSFS_NET_DIR "%s/brport/bridge", ifname) < 0) goto cleanup; if (virFileResolveLink(bridgeLink, &bridgePath) < 0) { virReportSystemError(errno, _("cannot read link '%s'"), bridgeLink); goto cleanup; } if (VIR_STRDUP(def->bridge, last_component(bridgePath)) < 0) goto cleanup; if (virAsprintf(&bridgeAddressPath, SYSFS_NET_DIR "%s/brport/bridge/address", ifname) < 0) goto cleanup; if ((len = virFileReadAll(bridgeAddressPath, 18, &bridgeAddress)) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Error reading file '%s'"), bridgeAddressPath); goto cleanup; } if (len < VIR_MAC_STRING_BUFLEN) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Error reading MAC from '%s'"), bridgeAddressPath); } bridgeAddress[VIR_MAC_STRING_BUFLEN - 1] = '\0'; if (virMacAddrParse(bridgeAddress, &def->mac) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Can't parse MAC '%s'"), bridgeAddress); goto cleanup; } def->mac_specified = 1; ret = 0; cleanup: VIR_FREE(bridgeLink); VIR_FREE(bridgePath); VIR_FREE(bridgeAddress); VIR_FREE(bridgeAddressPath); return ret; }
static virDomainNetDefPtr lxcCreateNetDef(const char *type, const char *linkdev, const char *mac, const char *flag, const char *macvlanmode, const char *name) { virDomainNetDefPtr net = NULL; virMacAddr macAddr; if (VIR_ALLOC(net) < 0) goto error; if (STREQ_NULLABLE(flag, "up")) net->linkstate = VIR_DOMAIN_NET_INTERFACE_LINK_STATE_UP; else net->linkstate = VIR_DOMAIN_NET_INTERFACE_LINK_STATE_DOWN; if (VIR_STRDUP(net->ifname_guest, name) < 0) goto error; if (mac && virMacAddrParse(mac, &macAddr) == 0) net->mac = macAddr; if (STREQ(type, "veth")) { if (!linkdev) goto error; net->type = VIR_DOMAIN_NET_TYPE_BRIDGE; if (VIR_STRDUP(net->data.bridge.brname, linkdev) < 0) goto error; } else if (STREQ(type, "macvlan")) { net->type = VIR_DOMAIN_NET_TYPE_DIRECT; if (!linkdev || VIR_STRDUP(net->data.direct.linkdev, linkdev) < 0) goto error; if (!macvlanmode || STREQ(macvlanmode, "private")) net->data.direct.mode = VIR_NETDEV_MACVLAN_MODE_PRIVATE; else if (STREQ(macvlanmode, "vepa")) net->data.direct.mode = VIR_NETDEV_MACVLAN_MODE_VEPA; else if (STREQ(macvlanmode, "bridge")) net->data.direct.mode = VIR_NETDEV_MACVLAN_MODE_BRIDGE; else VIR_WARN("Unknown macvlan type: %s", macvlanmode); } return net; error: virDomainNetDefFree(net); return NULL; }
virInterfacePtr vshCommandOptInterfaceBy(vshControl *ctl, const vshCmd *cmd, const char *optname, const char **name, unsigned int flags) { virInterfacePtr iface = NULL; const char *n = NULL; bool is_mac = false; virMacAddr dummy; virCheckFlags(VSH_BYNAME | VSH_BYMAC, NULL); if (!optname) optname = "interface"; if (!vshCmdHasOption(ctl, cmd, optname)) return NULL; if (vshCommandOptStringReq(ctl, cmd, optname, &n) < 0) return NULL; vshDebug(ctl, VSH_ERR_INFO, "%s: found option <%s>: %s\n", cmd->def->name, optname, n); if (name) *name = n; if (virMacAddrParse(n, &dummy) == 0) is_mac = true; /* try it by NAME */ if (!is_mac && (flags & VSH_BYNAME)) { vshDebug(ctl, VSH_ERR_DEBUG, "%s: <%s> trying as interface NAME\n", cmd->def->name, optname); iface = virInterfaceLookupByName(ctl->conn, n); /* try it by MAC */ } else if (is_mac && (flags & VSH_BYMAC)) { vshDebug(ctl, VSH_ERR_DEBUG, "%s: <%s> trying as interface MAC\n", cmd->def->name, optname); iface = virInterfaceLookupByMACString(ctl->conn, n); } if (!iface) vshError(ctl, _("failed to get interface '%s'"), n); return iface; }
int openvzReadNetworkConf(virDomainDefPtr def, int veid) { int ret; virDomainNetDefPtr net = NULL; char *temp = NULL; char *token, *saveptr = NULL; /*parse routing network configuration* * Sample from config: * IP_ADDRESS="1.1.1.1 1.1.1.2" * IPs split by space */ ret = openvzReadVPSConfigParam(veid, "IP_ADDRESS", &temp); if (ret < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Could not read 'IP_ADDRESS' from config for container %d"), veid); goto error; } else if (ret > 0) { token = strtok_r(temp, " ", &saveptr); while (token != NULL) { if (VIR_ALLOC(net) < 0) goto error; net->type = VIR_DOMAIN_NET_TYPE_ETHERNET; if (virDomainNetAppendIpAddress(net, token, AF_UNSPEC, 0) < 0) goto error; if (VIR_APPEND_ELEMENT_COPY(def->nets, def->nnets, net) < 0) goto error; token = strtok_r(NULL, " ", &saveptr); } } /*parse bridge devices*/ /*Sample from config: * NETIF="ifname=eth10,mac=00:18:51:C1:05:EE,host_ifname=veth105.10,host_mac=00:18:51:8F:D9:F3" *devices split by ';' */ ret = openvzReadVPSConfigParam(veid, "NETIF", &temp); if (ret < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Could not read 'NETIF' from config for container %d"), veid); goto error; } else if (ret > 0) { token = strtok_r(temp, ";", &saveptr); while (token != NULL) { /*add new device to list*/ if (VIR_ALLOC(net) < 0) goto error; net->type = VIR_DOMAIN_NET_TYPE_BRIDGE; char *p = token; char cpy_temp[32]; int len; /*parse string*/ do { char *next = strchrnul(p, ','); if (STRPREFIX(p, "ifname=")) { /* skip in libvirt */ } else if (STRPREFIX(p, "host_ifname=")) { p += 12; len = next - p; if (len > 16) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Too long network device name")); goto error; } if (VIR_ALLOC_N(net->ifname, len+1) < 0) goto error; if (virStrncpy(net->ifname, p, len, len+1) == NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Network ifname %s too long for destination"), p); goto error; } } else if (STRPREFIX(p, "bridge=")) { p += 7; len = next - p; if (len > 16) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Too long bridge device name")); goto error; } if (VIR_ALLOC_N(net->data.bridge.brname, len+1) < 0) goto error; if (virStrncpy(net->data.bridge.brname, p, len, len+1) == NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Bridge name %s too long for destination"), p); goto error; } } else if (STRPREFIX(p, "mac=")) { p += 4; len = next - p; if (len != 17) { /* should be 17 */ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Wrong length MAC address")); goto error; } if (virStrncpy(cpy_temp, p, len, sizeof(cpy_temp)) == NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, _("MAC address %s too long for destination"), p); goto error; } if (virMacAddrParse(cpy_temp, &net->mac) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Wrong MAC address")); goto error; } } p = ++next; } while (p < token + strlen(token)); if (VIR_APPEND_ELEMENT_COPY(def->nets, def->nnets, net) < 0) goto error; token = strtok_r(NULL, ";", &saveptr); } } VIR_FREE(temp); return 0; error: VIR_FREE(temp); virDomainNetDefFree(net); return -1; }
/* * - lxc.net.x or lxc.network.x? * - lxc.net or lxc.network? * TODO: legacy keys */ static int lxctoolsReadNetConfig(struct lxc_container* cont, virDomainDefPtr def) { virDomainNetDefPtr net = NULL; char* item_str = NULL; int ret = -1; char* config_str = NULL; char *key = NULL; VIR_DEBUG("Reading net config..."); // TODO: Check if legacy config and throw error for (int i = 0;; ++i) { // Check if net dev with index i exists. VIR_DEBUG("Checking for net dev %d.", i); if (virAsprintf(&key, "lxc.net.%d", i) < 0) { VIR_DEBUG("Failed to print key in string."); goto cleanup; } if (lxctoolsGetKeys(cont, key, NULL) < 0) { break; } // Allocate network definition structure if (VIR_ALLOC(net) < 0) { VIR_DEBUG("Failed to alloc virDomainNetDef."); goto cleanup; } // Check network type if (virAsprintf(&config_str, "%s.type", key) < 0) { goto cleanup; } if (lxctoolsReadConfigItem(cont, config_str, &item_str) < 0) { goto cleanup; } VIR_FREE(config_str); config_str=NULL; if (item_str != NULL) { VIR_DEBUG("%s", item_str); if (strcmp(item_str, "veth") == 0) { net->type = VIR_DOMAIN_NET_TYPE_BRIDGE; } else { VIR_DEBUG("Only network type veth is supported."); goto cleanup; } } else { VIR_DEBUG("No type for network device found."); goto cleanup; } VIR_FREE(item_str); item_str=NULL; // Check network hwaddr if (virAsprintf(&config_str, "%s.hwaddr", key) < 0) { goto cleanup; } if (lxctoolsReadConfigItem(cont, config_str, &item_str) < 0) { goto cleanup; } VIR_FREE(config_str); config_str=NULL; if (item_str != NULL && item_str[0] != '\0') { if (virMacAddrParse(item_str, &net->mac) < 0) { goto cleanup; } } else { VIR_DEBUG("No hwaddr for network device found."); goto cleanup; } VIR_FREE(item_str); item_str=NULL; // Check for network link if (virAsprintf(&config_str, "%s.link", key) < 0) { goto cleanup; } if (lxctoolsReadConfigItem(cont, config_str, &item_str) < 0) { goto cleanup; } VIR_FREE(config_str); config_str=NULL; if (item_str != NULL && item_str[0] != '\0') { if (VIR_STRDUP(net->data.bridge.brname, item_str) < 0) { goto cleanup; } } VIR_FREE(item_str); item_str=NULL; // Check for network flags if (virAsprintf(&config_str, "%s.flags", key) < 0) { goto cleanup; } if (lxctoolsReadConfigItem(cont, config_str, &item_str) < 0) { goto cleanup; } VIR_FREE(config_str); config_str=NULL; if (item_str != NULL && item_str[0] != '\0') { if (strcmp(item_str, "up") == 0) { net->linkstate = VIR_DOMAIN_NET_INTERFACE_LINK_STATE_UP; } else { net->linkstate = VIR_DOMAIN_NET_INTERFACE_LINK_STATE_DOWN; } } else { net->linkstate = VIR_DOMAIN_NET_INTERFACE_LINK_STATE_DOWN; } VIR_FREE(item_str); item_str=NULL; // Insert network definition into domain config. if (virDomainNetInsert(def, net) < 0) { goto cleanup; } } ret = 0; cleanup: if (ret==-1) VIR_FREE(net); VIR_FREE(item_str); return ret; }
static int bhyveParsePCINet(virDomainDefPtr def, virDomainXMLOptionPtr xmlopt, unsigned caps ATTRIBUTE_UNUSED, unsigned pcislot, unsigned pcibus, unsigned function, const char *config) { /* -s slot,virtio-net,tapN[,mac=xx:xx:xx:xx:xx:xx] */ virDomainNetDefPtr net = NULL; const char *separator = NULL; const char *mac = NULL; if (VIR_ALLOC(net) < 0) goto cleanup; /* Let's just assume it is VIR_DOMAIN_NET_TYPE_ETHERNET, it could also be * a bridge, but this is the most generic option. */ net->type = VIR_DOMAIN_NET_TYPE_ETHERNET; net->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI; net->info.addr.pci.slot = pcislot; net->info.addr.pci.bus = pcibus; net->info.addr.pci.function = function; if (!config) goto error; if (!STRPREFIX(config, "tap")) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("Only tap devices supported")); goto error; } separator = strchr(config, ','); if (VIR_STRNDUP(net->ifname, config, separator? separator - config : -1) < 0) goto error; if (!separator) goto cleanup; if (!STRPREFIX(++separator, "mac=")) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("Only mac option can be specified for virt-net")); goto error; } mac = separator + 4; if (virMacAddrParse(mac, &net->mac) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("unable to parse mac address '%s'"), mac); goto cleanup; } cleanup: if (!mac) virDomainNetGenerateMAC(xmlopt, &net->mac); if (VIR_APPEND_ELEMENT(def->nets, def->nnets, net) < 0) goto error; return 0; error: virDomainNetDefFree(net); return -1; }