コード例 #1
0
ファイル: uml_conf.c プロジェクト: Antique/libvirt
static int
umlConnectTapDevice(virDomainDefPtr vm,
                    virDomainNetDefPtr net,
                    const char *bridge)
{
    bool template_ifname = false;
    int tapfd = -1;

    if (!net->ifname ||
        STRPREFIX(net->ifname, VIR_NET_GENERATED_TAP_PREFIX) ||
        strchr(net->ifname, '%')) {
        VIR_FREE(net->ifname);
        if (VIR_STRDUP(net->ifname, VIR_NET_GENERATED_TAP_PREFIX "%d") < 0)
            goto error;
        /* avoid exposing vnet%d in getXMLDesc or error outputs */
        template_ifname = true;
    }

    if (virNetDevTapCreateInBridgePort(bridge, &net->ifname, &net->mac,
                                       vm->uuid, net->backend.tap, &tapfd, 1,
                                       virDomainNetGetActualVirtPortProfile(net),
                                       virDomainNetGetActualVlan(net),
                                       NULL, 0, NULL,
                                       VIR_NETDEV_TAP_CREATE_IFUP |
                                       VIR_NETDEV_TAP_CREATE_PERSIST) < 0) {
        if (template_ifname)
            VIR_FREE(net->ifname);
        goto error;
    }

    if (net->filter) {
        if (virDomainConfNWFilterInstantiate(vm->name, vm->uuid, net, false) < 0) {
            if (template_ifname)
                VIR_FREE(net->ifname);
            goto error;
        }
    }

    VIR_FORCE_CLOSE(tapfd);
    return 0;

 error:
    VIR_FORCE_CLOSE(tapfd);
    return -1;
}
コード例 #2
0
ファイル: uml_conf.c プロジェクト: pawitp/libvirt
static int
umlConnectTapDevice(virConnectPtr conn,
                    virDomainDefPtr vm,
                    virDomainNetDefPtr net,
                    const char *bridge)
{
    bool template_ifname = false;

    if (!net->ifname ||
            STRPREFIX(net->ifname, VIR_NET_GENERATED_PREFIX) ||
            strchr(net->ifname, '%')) {
        VIR_FREE(net->ifname);
        if (!(net->ifname = strdup(VIR_NET_GENERATED_PREFIX "%d")))
            goto no_memory;
        /* avoid exposing vnet%d in getXMLDesc or error outputs */
        template_ifname = true;
    }

    if (virNetDevTapCreateInBridgePort(bridge, &net->ifname, &net->mac,
                                       vm->uuid, NULL,
                                       virDomainNetGetActualVirtPortProfile(net),
                                       virDomainNetGetActualVlan(net),
                                       VIR_NETDEV_TAP_CREATE_IFUP |
                                       VIR_NETDEV_TAP_CREATE_PERSIST) < 0) {
        if (template_ifname)
            VIR_FREE(net->ifname);
        goto error;
    }

    if (net->filter) {
        if (virDomainConfNWFilterInstantiate(conn, vm->uuid, net) < 0) {
            if (template_ifname)
                VIR_FREE(net->ifname);
            goto error;
        }
    }

    return 0;

no_memory:
    virReportOOMError();
error:
    return -1;
}
コード例 #3
0
ファイル: qemu_interface.c プロジェクト: MountainWei/libvirt
/* qemuInterfaceBridgeConnect:
 * @def: the definition of the VM
 * @driver: qemu driver data
 * @net: pointer to the VM's interface description
 * @tapfd: array of file descriptor return value for the new device
 * @tapfdsize: number of file descriptors in @tapfd
 *
 * Called *only* called if actualType is VIR_DOMAIN_NET_TYPE_NETWORK or
 * VIR_DOMAIN_NET_TYPE_BRIDGE (i.e. if the connection is made with a tap
 * device connecting to a bridge device)
 */
int
qemuInterfaceBridgeConnect(virDomainDefPtr def,
                           virQEMUDriverPtr driver,
                           virDomainNetDefPtr net,
                           int *tapfd,
                           size_t *tapfdSize)
{
    const char *brname;
    int ret = -1;
    unsigned int tap_create_flags = VIR_NETDEV_TAP_CREATE_IFUP;
    bool template_ifname = false;
    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
    const char *tunpath = "/dev/net/tun";

    if (net->backend.tap) {
        tunpath = net->backend.tap;
        if (!(virQEMUDriverIsPrivileged(driver))) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("cannot use custom tap device in session mode"));
            goto cleanup;
        }
    }

    if (!(brname = virDomainNetGetActualBridgeName(net))) {
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Missing bridge name"));
        goto cleanup;
    }

    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)
            goto cleanup;
        /* avoid exposing vnet%d in getXMLDesc or error outputs */
        template_ifname = true;
    }

    if (net->model && STREQ(net->model, "virtio"))
        tap_create_flags |= VIR_NETDEV_TAP_CREATE_VNET_HDR;

    if (virQEMUDriverIsPrivileged(driver)) {
        if (virNetDevTapCreateInBridgePort(brname, &net->ifname, &net->mac,
                                           def->uuid, tunpath, tapfd, *tapfdSize,
                                           virDomainNetGetActualVirtPortProfile(net),
                                           virDomainNetGetActualVlan(net),
                                           tap_create_flags) < 0) {
            virDomainAuditNetDevice(def, net, tunpath, false);
            goto cleanup;
        }
        if (virDomainNetGetActualBridgeMACTableManager(net)
            == VIR_NETWORK_BRIDGE_MAC_TABLE_MANAGER_LIBVIRT) {
            /* libvirt is managing the FDB of the bridge this device
             * is attaching to, so we need to turn off learning and
             * unicast_flood on the device to prevent the kernel from
             * adding any FDB entries for it. We will add add an fdb
             * entry ourselves (during qemuInterfaceStartDevices(),
             * using the MAC address from the interface config.
             */
            if (virNetDevBridgePortSetLearning(brname, net->ifname, false) < 0)
                goto cleanup;
            if (virNetDevBridgePortSetUnicastFlood(brname, net->ifname, false) < 0)
                goto cleanup;
        }
    } else {
        if (qemuCreateInBridgePortWithHelper(cfg, brname,
                                             &net->ifname,
                                             tapfd, tap_create_flags) < 0) {
            virDomainAuditNetDevice(def, net, tunpath, false);
            goto cleanup;
        }
        /* qemuCreateInBridgePortWithHelper can only create a single FD */
        if (*tapfdSize > 1) {
            VIR_WARN("Ignoring multiqueue network request");
            *tapfdSize = 1;
        }
    }

    virDomainAuditNetDevice(def, net, tunpath, true);

    if (cfg->macFilter &&
        ebtablesAddForwardAllowIn(driver->ebtables,
                                  net->ifname,
                                  &net->mac) < 0)
        goto cleanup;

    if (net->filter &&
        virDomainConfNWFilterInstantiate(def->uuid, net) < 0) {
        goto cleanup;
    }

    ret = 0;

 cleanup:
    if (ret < 0) {
        size_t i;
        for (i = 0; i < *tapfdSize && tapfd[i] >= 0; i++)
            VIR_FORCE_CLOSE(tapfd[i]);
        if (template_ifname)
            VIR_FREE(net->ifname);
    }
    virObjectUnref(cfg);

    return ret;
}
コード例 #4
0
ファイル: bhyve_command.c プロジェクト: candhare/libvirt
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;
}
コード例 #5
0
ファイル: bhyve_command.c プロジェクト: TelekomCloud/libvirt
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;
}