Beispiel #1
0
static TAPState *net_tap_fd_init(NetClientState *peer,
                                 const char *model,
                                 const char *name,
                                 int fd,
                                 int vnet_hdr)
{
    NetClientState *nc;
    TAPState *s;

    nc = qemu_new_net_client(&net_tap_info, peer, model, name);

    s = DO_UPCAST(TAPState, nc, nc);

    s->fd = fd;
    s->host_vnet_hdr_len = vnet_hdr ? sizeof(struct virtio_net_hdr) : 0;
    s->using_vnet_hdr = false;
    s->has_ufo = tap_probe_has_ufo(s->fd);
    s->enabled = true;
    tap_set_offload(&s->nc, 0, 0, 0, 0, 0);
    /*
     * Make sure host header length is set correctly in tap:
     * it might have been modified by another instance of qemu.
     */
    if (tap_probe_vnet_hdr_len(s->fd, s->host_vnet_hdr_len)) {
        tap_fd_set_vnet_hdr_len(s->fd, s->host_vnet_hdr_len);
    }
    tap_read_poll(s, true);
    s->vhost_net = NULL;
    return s;
}
Beispiel #2
0
static int tap_win32_init(VLANState *vlan, const char *model,
                          const char *name, const char *ifname)
{
    VLANClientState *nc;
    TAPState *s;
    tap_win32_overlapped_t *handle;

    if (tap_win32_open(&handle, ifname) < 0) {
        printf("tap: Could not open '%s'\n", ifname);
        return -1;
    }

    nc = qemu_new_net_client(&net_tap_win32_info, vlan, NULL, model, name);

    s = DO_UPCAST(TAPState, nc, nc);

    snprintf(s->nc.info_str, sizeof(s->nc.info_str),
             "tap: ifname=%s", ifname);

    s->handle = handle;

    qemu_add_wait_object(s->handle->tap_semaphore, tap_win32_send, s);

    return 0;
}
Beispiel #3
0
/* The exported init function
 *
 * ... -net netmap,ifname="..."
 */
int net_init_netmap(const Netdev *netdev,
                    const char *name, NetClientState *peer, Error **errp)
{
    const NetdevNetmapOptions *netmap_opts = &netdev->u.netmap;
    struct nm_desc *nmd;
    NetClientState *nc;
    Error *err = NULL;
    NetmapState *s;

    nmd = netmap_open(netmap_opts, &err);
    if (err) {
        error_propagate(errp, err);
        return -1;
    }
    /* Create the object. */
    nc = qemu_new_net_client(&net_netmap_info, peer, "netmap", name);
    s = DO_UPCAST(NetmapState, nc, nc);
    s->nmd = nmd;
    s->tx = NETMAP_TXRING(nmd->nifp, 0);
    s->rx = NETMAP_RXRING(nmd->nifp, 0);
    s->vnet_hdr_len = 0;
    pstrcpy(s->ifname, sizeof(s->ifname), netmap_opts->ifname);
    netmap_read_poll(s, true); /* Initially only poll for reads. */

    return 0;
}
Beispiel #4
0
static int net_vhost_user_init(NetClientState *peer, const char *device,
                               const char *name, CharDriverState *chr,
                               int queues)
{
    NetClientState *nc;
    VhostUserState *s;
    int i;

    assert(name);
    assert(queues > 0);

    for (i = 0; i < queues; i++) {
        nc = qemu_new_net_client(&net_vhost_user_info, peer, device, name);

        snprintf(nc->info_str, sizeof(nc->info_str), "vhost-user%d to %s",
                 i, chr->label);

        nc->queue_index = i;

        s = DO_UPCAST(VhostUserState, nc, nc);
        s->chr = chr;
    }

    qemu_chr_add_handlers(chr, NULL, NULL, net_vhost_user_event, nc[0].name);

    return 0;
}
Beispiel #5
0
static int net_vde_init(NetClientState *peer, const char *model,
                        const char *name, const char *sock,
                        int port, const char *group, int mode)
{
    NetClientState *nc;
    VDEState *s;
    VDECONN *vde;
    char *init_group = (char *)group;
    char *init_sock = (char *)sock;

    struct vde_open_args args = {
        .port = port,
        .group = init_group,
        .mode = mode,
    };

    vde = vde_open(init_sock, (char *)"QEMU", &args);
    if (!vde){
        return -1;
    }

    nc = qemu_new_net_client(&net_vde_info, peer, model, name);

    snprintf(nc->info_str, sizeof(nc->info_str), "sock=%s,fd=%d",
             sock, vde_datafd(vde));

    s = DO_UPCAST(VDEState, nc, nc);

    s->vde = vde;

    qemu_set_fd_handler(vde_datafd(s->vde), vde_to_qemu, NULL, s);

    return 0;
}
Beispiel #6
0
static int net_socket_listen_init(NetClientState *peer,
                                  const char *model,
                                  const char *name,
                                  const char *host_str)
{
    NetClientState *nc;
    NetSocketState *s;
    struct sockaddr_in saddr;
    int fd, val, ret;

    if (parse_host_port(&saddr, host_str) < 0)
        return -1;

    fd = qemu_socket(PF_INET, SOCK_STREAM, 0);
    if (fd < 0) {
        perror("socket");
        return -1;
    }
    socket_set_nonblock(fd);

    /* allow fast reuse */
    val = 1;
    setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char *)&val, sizeof(val));

    ret = bind(fd, (struct sockaddr *)&saddr, sizeof(saddr));
    if (ret < 0) {
        perror("bind");
        closesocket(fd);
        return -1;
    }
    ret = listen(fd, 0);
    if (ret < 0) {
        perror("listen");
        closesocket(fd);
        return -1;
    }

    nc = qemu_new_net_client(&net_socket_info, peer, model, name);
    s = DO_UPCAST(NetSocketState, nc, nc);
    s->fd = -1;
    s->listen_fd = fd;
    s->nc.link_down = true;

    qemu_set_fd_handler(s->listen_fd, net_socket_accept, NULL, s);
    return 0;
}
Beispiel #7
0
static int net_dump_init(NetClientState *peer, const char *device,
                         const char *name, const char *filename, int len,
                         Error **errp)
{
    struct pcap_file_hdr hdr;
    NetClientState *nc;
    DumpState *s;
    struct tm tm;
    int fd;

    fd = open(filename, O_CREAT | O_TRUNC | O_WRONLY | O_BINARY, 0644);
    if (fd < 0) {
        error_setg_errno(errp, errno, "-net dump: can't open %s", filename);
        return -1;
    }

    hdr.magic = PCAP_MAGIC;
    hdr.version_major = 2;
    hdr.version_minor = 4;
    hdr.thiszone = 0;
    hdr.sigfigs = 0;
    hdr.snaplen = len;
    hdr.linktype = 1;

    if (write(fd, &hdr, sizeof(hdr)) < sizeof(hdr)) {
        error_setg_errno(errp, errno, "-net dump write error");
        close(fd);
        return -1;
    }

    nc = qemu_new_net_client(&net_dump_info, peer, device, name);

    snprintf(nc->info_str, sizeof(nc->info_str),
             "dump to %s (len=%d)", filename, len);

    s = DO_UPCAST(DumpState, nc, nc);

    s->fd = fd;
    s->pcap_caplen = len;

    qemu_get_timedate(&tm, 0);
    s->start_ts = mktime(&tm);

    return 0;
}
Beispiel #8
0
static int net_vhost_user_init(NetClientState *peer, const char *device,
                               const char *name, Chardev *chr,
                               int queues)
{
    Error *err = NULL;
    NetClientState *nc, *nc0 = NULL;
    VhostUserState *s;
    int i;

    assert(name);
    assert(queues > 0);

    for (i = 0; i < queues; i++) {
        nc = qemu_new_net_client(&net_vhost_user_info, peer, device, name);
        snprintf(nc->info_str, sizeof(nc->info_str), "vhost-user%d to %s",
                 i, chr->label);
        nc->queue_index = i;
        if (!nc0) {
            nc0 = nc;
            s = DO_UPCAST(VhostUserState, nc, nc);
            if (!qemu_chr_fe_init(&s->chr, chr, &err)) {
                error_report_err(err);
                return -1;
            }
        }

    }

    s = DO_UPCAST(VhostUserState, nc, nc0);
    do {
        if (qemu_chr_fe_wait_connected(&s->chr, &err) < 0) {
            error_report_err(err);
            return -1;
        }
        qemu_chr_fe_set_handlers(&s->chr, NULL, NULL,
                                 net_vhost_user_event, NULL, nc0->name, NULL,
                                 true);
    } while (!s->started);

    assert(s->vhost_net);

    return 0;
}
Beispiel #9
0
static TAPState *net_tap_fd_init(VLANState *vlan,
                                 const char *model,
                                 const char *name,
                                 int fd,
                                 int vnet_hdr)
{
    VLANClientState *nc;
    TAPState *s;

    nc = qemu_new_net_client(&net_tap_info, vlan, NULL, model, name);

    s = DO_UPCAST(TAPState, nc, nc);

    s->fd = fd;
    s->has_vnet_hdr = vnet_hdr != 0;
    s->using_vnet_hdr = 0;
    s->has_ufo = tap_probe_has_ufo(s->fd);
    tap_set_offload(&s->nc, 0, 0, 0, 0, 0);
    tap_read_poll(s, 1);
    return s;
}
Beispiel #10
0
static int net_vhost_user_init(NetClientState *peer, const char *device,
                               const char *name, CharDriverState *chr)
{
    NetClientState *nc;
    VhostUserState *s;

    nc = qemu_new_net_client(&net_vhost_user_info, peer, device, name);

    snprintf(nc->info_str, sizeof(nc->info_str), "vhost-user to %s",
             chr->label);

    s = DO_UPCAST(VhostUserState, nc, nc);

    /* We don't provide a receive callback */
    s->nc.receive_disabled = 1;
    s->chr = chr;

    qemu_chr_add_handlers(s->chr, NULL, NULL, net_vhost_user_event, s);

    return 0;
}
Beispiel #11
0
static TAPState *net_tap_fd_init(NetClientState *peer,
                                 const char *model,
                                 const char *name,
                                 int fd,
                                 int vnet_hdr)
{
    NetClientState *nc;
    TAPState *s;

    nc = qemu_new_net_client(&net_tap_info, peer, model, name);

    s = DO_UPCAST(TAPState, nc, nc);

    s->fd = fd;
    s->host_vnet_hdr_len = vnet_hdr ? sizeof(struct virtio_net_hdr) : 0;
    s->using_vnet_hdr = 0;
    s->has_ufo = tap_probe_has_ufo(s->fd);
    tap_set_offload(&s->nc, 0, 0, 0, 0, 0);
    tap_read_poll(s, 1);
    s->vhost_net = NULL;
    return s;
}
Beispiel #12
0
static NetSocketState *net_socket_fd_init_stream(VLANState *vlan,
                                                 const char *model,
                                                 const char *name,
                                                 int fd, int is_connected)
{
    VLANClientState *nc;
    NetSocketState *s;

    nc = qemu_new_net_client(&net_socket_info, vlan, NULL, model, name);

    snprintf(nc->info_str, sizeof(nc->info_str), "socket: fd=%d", fd);

    s = DO_UPCAST(NetSocketState, nc, nc);

    s->fd = fd;

    if (is_connected) {
        net_socket_connect(s);
    } else {
        qemu_set_fd_handler(s->fd, NULL, net_socket_connect, s);
    }
    return s;
}
Beispiel #13
0
static NetSocketState *net_socket_fd_init_dgram(NetClientState *peer,
                                                const char *model,
                                                const char *name,
                                                int fd, int is_connected)
{
    struct sockaddr_in saddr;
    int newfd;
    socklen_t saddr_len;
    NetClientState *nc;
    NetSocketState *s;

    /* fd passed: multicast: "learn" dgram_dst address from bound address and save it
     * Because this may be "shared" socket from a "master" process, datagrams would be recv()
     * by ONLY ONE process: we must "clone" this dgram socket --jjo
     */

    if (is_connected) {
        if (getsockname(fd, (struct sockaddr *) &saddr, &saddr_len) == 0) {
            /* must be bound */
            if (saddr.sin_addr.s_addr == 0) {
                fprintf(stderr, "qemu: error: init_dgram: fd=%d unbound, "
                        "cannot setup multicast dst addr\n", fd);
                goto err;
            }
            /* clone dgram socket */
            newfd = net_socket_mcast_create(&saddr, NULL);
            if (newfd < 0) {
                /* error already reported by net_socket_mcast_create() */
                goto err;
            }
            /* clone newfd to fd, close newfd */
            dup2(newfd, fd);
            close(newfd);

        } else {
            fprintf(stderr,
                    "qemu: error: init_dgram: fd=%d failed getsockname(): %s\n",
                    fd, strerror(errno));
            goto err;
        }
    }

    nc = qemu_new_net_client(&net_dgram_socket_info, peer, model, name);

    snprintf(nc->info_str, sizeof(nc->info_str),
            "socket: fd=%d (%s mcast=%s:%d)",
            fd, is_connected ? "cloned" : "",
            inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));

    s = DO_UPCAST(NetSocketState, nc, nc);

    s->fd = fd;
    s->listen_fd = -1;

    qemu_set_fd_handler(s->fd, net_socket_send_dgram, NULL, s);

    /* mcast: save bound address as dst */
    if (is_connected) {
        s->dgram_dst = saddr;
    }

    return s;

err:
    closesocket(fd);
    return NULL;
}
Beispiel #14
0
int
net_init_vnic(QemuOpts *opts, Monitor *mon, const char *name, VLANState *vlan)
{
	int fd, len, vnderr, syserr;
	const char *ifname, *mac;
	uchar_t *macaddr;
	VLANClientState *ncp;
	VNICState *vsp;
	vnd_prop_buf_t vib;

	if ((ifname = qemu_opt_get(opts, "ifname")) == NULL) {
		error_report("missing ifname required for vnic\n");
		return (-1);
	}

	mac = qemu_opt_get(opts, "macaddr");

	if (mac != NULL) {
		macaddr = _link_aton(mac, &len);
		if (macaddr == NULL || len != ETHERADDRL) {
			error_report("invalid macaddr for vnic: %s\n", mac);
			return (-1);
		}
	}

	ncp = qemu_new_net_client(&net_vnic_info, vlan, NULL, "vnic", name);
	vsp = DO_UPCAST(VNICState, vns_nc, ncp);


	vsp->vns_hdl = vnd_open(NULL, ifname, &vnderr, &syserr);
	if (vsp->vns_hdl == NULL) {
		const char *err = vnderr != VND_E_SYS ?
		    vnd_strerror(vnderr) : vnd_strsyserror(syserr);
		error_report("vnic: failed to open interface %s - %s\n",
		    ifname, err);
		return (-1);
	}

	vib.vpb_size = 1024 * 1024 * 4; 	/* 4 MB */
	if (vnd_prop_set(vsp->vns_hdl, VND_PROP_RXBUF, &vib,
	    sizeof (vib)) != 0) {
		const char *err = vnderr != VND_E_SYS ?
		    vnd_strerror(vnderr) : vnd_strsyserror(syserr);
		error_report("failed to change rx buf size: %s\n", err);
		return (-1);
	}

	vib.vpb_size = 1024 * 1024 * 4; 	/* 4 MB */
	if (vnd_prop_set(vsp->vns_hdl, VND_PROP_TXBUF, &vib,
	    sizeof (vib)) != 0) {
		const char *err = vnderr != VND_E_SYS ?
		    vnd_strerror(vnderr) : vnd_strsyserror(syserr);
		error_report("failed to change tx buf size: %s\n", err);
		return (-1);
	}


	fd = vnd_pollfd(vsp->vns_hdl);
	if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) {
		error_report("vnic: failed to set fd on interface %s to "
		    "non-blocking: %s\n", ifname, strerror(errno));
		return (-1);
	}

	vsp->vns_fd = fd;

	snprintf(vsp->vns_nc.info_str, sizeof (vsp->vns_nc.info_str), "ifname=%s",
	    qemu_opt_get(opts, "ifname"));

	if (vnic_dhcp_init(&vsp->vns_ds, opts) == 0)
		return (-1);

	if (vnic_frameio_init(vsp) != 0) {
		error_report("vnic: failed initialize frameio: %s\n",
		    strerror(errno));
		return (-1);
	}

	/* We have to manually intialize the polling for read */
	vnic_read_poll(vsp, 1);

	return (0);
}