Exemplo n.º 1
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;
}
Exemplo n.º 2
0
static int
lxcAddNetworkDefinition(lxcNetworkParseData *data)
{
    virDomainNetDefPtr net = NULL;
    virDomainHostdevDefPtr hostdev = NULL;
    bool isPhys, isVlan = false;
    size_t i;

    if ((data->type == NULL) || STREQ(data->type, "empty") ||
         STREQ(data->type, "") ||  STREQ(data->type, "none"))
        return 0;

    isPhys = STREQ(data->type, "phys");
    isVlan = STREQ(data->type, "vlan");
    if (data->type != NULL && (isPhys || isVlan)) {
        if (!data->link) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("Missing 'link' attribute for NIC"));
            goto error;
        }
        if (!(hostdev = lxcCreateHostdevDef(VIR_DOMAIN_HOSTDEV_MODE_CAPABILITIES,
                                            VIR_DOMAIN_HOSTDEV_CAPS_TYPE_NET,
                                            data->link)))
            goto error;

        /* This still requires the user to manually setup the vlan interface
         * on the host */
        if (isVlan && data->vlanid) {
            VIR_FREE(hostdev->source.caps.u.net.iface);
            if (virAsprintf(&hostdev->source.caps.u.net.iface,
                            "%s.%s", data->link, data->vlanid) < 0)
                goto error;
        }

        hostdev->source.caps.u.net.ips = data->ips;
        hostdev->source.caps.u.net.nips = data->nips;

        if (data->gateway_ipv4 &&
            lxcAddNetworkRouteDefinition(data->gateway_ipv4, AF_INET,
                                         &hostdev->source.caps.u.net.routes,
                                         &hostdev->source.caps.u.net.nroutes) < 0)
                goto error;

        if (data->gateway_ipv6 &&
            lxcAddNetworkRouteDefinition(data->gateway_ipv6, AF_INET6,
                                         &hostdev->source.caps.u.net.routes,
                                         &hostdev->source.caps.u.net.nroutes) < 0)
                goto error;

        if (VIR_EXPAND_N(data->def->hostdevs, data->def->nhostdevs, 1) < 0)
            goto error;
        data->def->hostdevs[data->def->nhostdevs - 1] = hostdev;
    } else {
        if (!(net = lxcCreateNetDef(data->type, data->link, data->mac,
                                    data->flag, data->macvlanmode,
                                    data->name)))
            goto error;

        net->ips = data->ips;
        net->nips = data->nips;

        if (data->gateway_ipv4 &&
            lxcAddNetworkRouteDefinition(data->gateway_ipv4, AF_INET,
                                         &net->routes,
                                         &net->nroutes) < 0)
                goto error;

        if (data->gateway_ipv6 &&
            lxcAddNetworkRouteDefinition(data->gateway_ipv6, AF_INET6,
                                         &net->routes,
                                         &net->nroutes) < 0)
                goto error;

        if (VIR_EXPAND_N(data->def->nets, data->def->nnets, 1) < 0)
            goto error;
        data->def->nets[data->def->nnets - 1] = net;
    }

    return 1;

 error:
    for (i = 0; i < data->nips; i++)
        VIR_FREE(data->ips[i]);
    VIR_FREE(data->ips);
    virDomainNetDefFree(net);
    virDomainHostdevDefFree(hostdev);
    return -1;
}
Exemplo n.º 3
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;
}
Exemplo n.º 4
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;
}