TAPState *s = opaque;
int size;
- do {
+ while (qemu_can_send_packet(&s->nc)) {
uint8_t *buf = s->buf;
size = tap_read_packet(s->fd, s->buf, sizeof(s->buf));
size = qemu_send_packet_async(&s->nc, buf, size, tap_send_completed);
if (size == 0) {
tap_read_poll(s, false);
+ break;
+ } else if (size < 0) {
+ break;
}
- } while (size > 0 && qemu_can_send_packet(&s->nc));
+ }
}
-bool tap_has_ufo(NetClientState *nc)
+static bool tap_has_ufo(NetClientState *nc)
{
TAPState *s = DO_UPCAST(TAPState, nc, nc);
return s->has_ufo;
}
-int tap_has_vnet_hdr(NetClientState *nc)
+static bool tap_has_vnet_hdr(NetClientState *nc)
{
TAPState *s = DO_UPCAST(TAPState, nc, nc);
return !!s->host_vnet_hdr_len;
}
-int tap_has_vnet_hdr_len(NetClientState *nc, int len)
+static bool tap_has_vnet_hdr_len(NetClientState *nc, int len)
{
TAPState *s = DO_UPCAST(TAPState, nc, nc);
assert(nc->info->type == NET_CLIENT_OPTIONS_KIND_TAP);
- return tap_probe_vnet_hdr_len(s->fd, len);
+ return !!tap_probe_vnet_hdr_len(s->fd, len);
}
-void tap_set_vnet_hdr_len(NetClientState *nc, int len)
+static void tap_set_vnet_hdr_len(NetClientState *nc, int len)
{
TAPState *s = DO_UPCAST(TAPState, nc, nc);
s->host_vnet_hdr_len = len;
}
-void tap_using_vnet_hdr(NetClientState *nc, bool using_vnet_hdr)
+static void tap_using_vnet_hdr(NetClientState *nc, bool using_vnet_hdr)
{
TAPState *s = DO_UPCAST(TAPState, nc, nc);
s->using_vnet_hdr = using_vnet_hdr;
}
-void tap_set_offload(NetClientState *nc, int csum, int tso4,
+static void tap_set_offload(NetClientState *nc, int csum, int tso4,
int tso6, int ecn, int ufo)
{
TAPState *s = DO_UPCAST(TAPState, nc, nc);
.receive_iov = tap_receive_iov,
.poll = tap_poll,
.cleanup = tap_cleanup,
+ .has_ufo = tap_has_ufo,
+ .has_vnet_hdr = tap_has_vnet_hdr,
+ .has_vnet_hdr_len = tap_has_vnet_hdr_len,
+ .using_vnet_hdr = tap_using_vnet_hdr,
+ .set_offload = tap_set_offload,
+ .set_vnet_hdr_len = tap_set_vnet_hdr_len,
};
static TAPState *net_tap_fd_init(NetClientState *peer,
if (pid == 0) {
int open_max = sysconf(_SC_OPEN_MAX), i;
- for (i = 0; i < open_max; i++) {
- if (i != STDIN_FILENO &&
- i != STDOUT_FILENO &&
- i != STDERR_FILENO &&
- i != fd) {
+ for (i = 3; i < open_max; i++) {
+ if (i != fd) {
close(i);
}
}
char br_buf[6+IFNAMSIZ] = {0};
char helper_cmd[PATH_MAX + sizeof(fd_buf) + sizeof(br_buf) + 15];
- for (i = 0; i < open_max; i++) {
- if (i != STDIN_FILENO &&
- i != STDOUT_FILENO &&
- i != STDERR_FILENO &&
- i != sv[1]) {
+ for (i = 3; i < open_max; i++) {
+ if (i != sv[1]) {
close(i);
}
}
int vnet_hdr, int fd)
{
TAPState *s;
+ int vhostfd;
s = net_tap_fd_init(peer, model, name, fd, vnet_hdr);
if (!s) {
if (tap->has_vhost ? tap->vhost :
vhostfdname || (tap->has_vhostforce && tap->vhostforce)) {
- int vhostfd;
+ VhostNetOptions options;
+
+ options.backend_type = VHOST_BACKEND_TYPE_KERNEL;
+ options.net_backend = &s->nc;
+ options.force = tap->has_vhostforce && tap->vhostforce;
if (tap->has_vhostfd || tap->has_vhostfds) {
vhostfd = monitor_handle_fd_param(cur_mon, vhostfdname);
return -1;
}
} else {
- vhostfd = -1;
+ vhostfd = open("/dev/vhost-net", O_RDWR);
+ if (vhostfd < 0) {
+ error_report("tap: open vhost char device failed: %s",
+ strerror(errno));
+ return -1;
+ }
}
+ options.opaque = (void *)(uintptr_t)vhostfd;
- s->vhost_net = vhost_net_init(&s->nc, vhostfd,
- tap->has_vhostforce && tap->vhostforce);
+ s->vhost_net = vhost_net_init(&options);
if (!s->vhost_net) {
error_report("vhost-net requested but could not be initialized");
return -1;
if (tap->has_fd) {
if (tap->has_ifname || tap->has_script || tap->has_downscript ||
tap->has_vnet_hdr || tap->has_helper || tap->has_queues ||
- tap->has_fds) {
+ tap->has_fds || tap->has_vhostfds) {
error_report("ifname=, script=, downscript=, vnet_hdr=, "
- "helper=, queues=, and fds= are invalid with fd=");
+ "helper=, queues=, fds=, and vhostfds= "
+ "are invalid with fd=");
return -1;
}
if (tap->has_ifname || tap->has_script || tap->has_downscript ||
tap->has_vnet_hdr || tap->has_helper || tap->has_queues ||
- tap->has_fd) {
+ tap->has_vhostfd) {
error_report("ifname=, script=, downscript=, vnet_hdr=, "
- "helper=, queues=, and fd= are invalid with fds=");
+ "helper=, queues=, and vhostfd= "
+ "are invalid with fds=");
return -1;
}
}
} else if (tap->has_helper) {
if (tap->has_ifname || tap->has_script || tap->has_downscript ||
- tap->has_vnet_hdr || tap->has_queues || tap->has_fds) {
+ tap->has_vnet_hdr || tap->has_queues || tap->has_vhostfds) {
error_report("ifname=, script=, downscript=, and vnet_hdr= "
- "queues=, and fds= are invalid with helper=");
+ "queues=, and vhostfds= are invalid with helper=");
return -1;
}
return -1;
}
} else {
+ if (tap->has_vhostfds) {
+ error_report("vhostfds= is invalid if fds= wasn't specified");
+ return -1;
+ }
script = tap->has_script ? tap->script : DEFAULT_NETWORK_SCRIPT;
downscript = tap->has_downscript ? tap->downscript :
DEFAULT_NETWORK_DOWN_SCRIPT;