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;
}
Example #2
0
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;
}
Example #3
0
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;
}
Example #4
0
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;
}
Example #5
0
/*
 * - 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;   
}
Example #6
0
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;
}