void vhost_net_stop(struct vhost_net *net, VirtIODevice *dev) { struct vhost_vring_file file = { .fd = -1 }; for (file.index = 0; file.index < net->dev.nvqs; ++file.index) { int r = ioctl(net->dev.control, VHOST_NET_SET_BACKEND, &file); assert(r >= 0); } net->vc->info->poll(net->vc, true); vhost_dev_stop(&net->dev, dev); if (net->dev.acked_features & (1 << VIRTIO_NET_F_MRG_RXBUF)) { tap_set_vnet_hdr_len(net->vc, sizeof(struct virtio_net_hdr)); } vhost_dev_disable_notifiers(&net->dev, dev); } void vhost_net_cleanup(struct vhost_net *net) { vhost_dev_cleanup(&net->dev); if (net->dev.acked_features & (1 << VIRTIO_NET_F_MRG_RXBUF)) { tap_set_vnet_hdr_len(net->vc, sizeof(struct virtio_net_hdr)); } g_free(net); }
int vhost_net_start(struct vhost_net *net, VirtIODevice *dev) { struct vhost_vring_file file = { }; int r; net->dev.nvqs = 2; net->dev.vqs = net->vqs; r = vhost_dev_enable_notifiers(&net->dev, dev); if (r < 0) { goto fail_notifiers; } if (net->dev.acked_features & (1 << VIRTIO_NET_F_MRG_RXBUF)) { tap_set_vnet_hdr_len(net->vc, sizeof(struct virtio_net_hdr_mrg_rxbuf)); } r = vhost_dev_start(&net->dev, dev); if (r < 0) { goto fail_start; } net->vc->info->poll(net->vc, false); qemu_set_fd_handler(net->backend, NULL, NULL, NULL); file.fd = net->backend; for (file.index = 0; file.index < net->dev.nvqs; ++file.index) { r = ioctl(net->dev.control, VHOST_NET_SET_BACKEND, &file); if (r < 0) { r = -errno; goto fail; } } return 0; fail: file.fd = -1; while (file.index-- > 0) { int r = ioctl(net->dev.control, VHOST_NET_SET_BACKEND, &file); assert(r >= 0); } net->vc->info->poll(net->vc, true); vhost_dev_stop(&net->dev, dev); if (net->dev.acked_features & (1 << VIRTIO_NET_F_MRG_RXBUF)) { tap_set_vnet_hdr_len(net->vc, sizeof(struct virtio_net_hdr)); } fail_start: vhost_dev_disable_notifiers(&net->dev, dev); fail_notifiers: return r; }
static void virtio_net_set_mrg_rx_bufs(VirtIONet *n, int mergeable_rx_bufs) { n->mergeable_rx_bufs = mergeable_rx_bufs; n->guest_hdr_len = n->mergeable_rx_bufs ? sizeof(struct virtio_net_hdr_mrg_rxbuf) : sizeof(struct virtio_net_hdr); if (peer_has_vnet_hdr(n) && tap_has_vnet_hdr_len(n->nic->nc.peer, n->guest_hdr_len)) { tap_set_vnet_hdr_len(n->nic->nc.peer, n->guest_hdr_len); n->host_hdr_len = n->guest_hdr_len; } }