Statistics
| Branch: | Revision:

root / hw / vhost_net.c @ 1de7afc9

History | View | Annotate | Download (6 kB)

1 d5970055 Michael S. Tsirkin
/*
2 d5970055 Michael S. Tsirkin
 * vhost-net support
3 d5970055 Michael S. Tsirkin
 *
4 d5970055 Michael S. Tsirkin
 * Copyright Red Hat, Inc. 2010
5 d5970055 Michael S. Tsirkin
 *
6 d5970055 Michael S. Tsirkin
 * Authors:
7 d5970055 Michael S. Tsirkin
 *  Michael S. Tsirkin <mst@redhat.com>
8 d5970055 Michael S. Tsirkin
 *
9 d5970055 Michael S. Tsirkin
 * This work is licensed under the terms of the GNU GPL, version 2.  See
10 d5970055 Michael S. Tsirkin
 * the COPYING file in the top-level directory.
11 6b620ca3 Paolo Bonzini
 *
12 6b620ca3 Paolo Bonzini
 * Contributions after 2012-01-13 are licensed under the terms of the
13 6b620ca3 Paolo Bonzini
 * GNU GPL, version 2 or (at your option) any later version.
14 d5970055 Michael S. Tsirkin
 */
15 d5970055 Michael S. Tsirkin
16 1422e32d Paolo Bonzini
#include "net/net.h"
17 d5970055 Michael S. Tsirkin
#include "net/tap.h"
18 d5970055 Michael S. Tsirkin
19 d5970055 Michael S. Tsirkin
#include "virtio-net.h"
20 d5970055 Michael S. Tsirkin
#include "vhost_net.h"
21 1de7afc9 Paolo Bonzini
#include "qemu/error-report.h"
22 d5970055 Michael S. Tsirkin
23 d5970055 Michael S. Tsirkin
#include "config.h"
24 d5970055 Michael S. Tsirkin
25 d5970055 Michael S. Tsirkin
#ifdef CONFIG_VHOST_NET
26 d5970055 Michael S. Tsirkin
#include <linux/vhost.h>
27 d5970055 Michael S. Tsirkin
#include <sys/socket.h>
28 d5970055 Michael S. Tsirkin
#include <linux/kvm.h>
29 d5970055 Michael S. Tsirkin
#include <fcntl.h>
30 d5970055 Michael S. Tsirkin
#include <sys/ioctl.h>
31 d5970055 Michael S. Tsirkin
#include <linux/virtio_ring.h>
32 d5970055 Michael S. Tsirkin
#include <netpacket/packet.h>
33 d5970055 Michael S. Tsirkin
#include <net/ethernet.h>
34 d5970055 Michael S. Tsirkin
#include <net/if.h>
35 d5970055 Michael S. Tsirkin
#include <netinet/in.h>
36 d5970055 Michael S. Tsirkin
37 d5970055 Michael S. Tsirkin
#include <stdio.h>
38 d5970055 Michael S. Tsirkin
39 d5970055 Michael S. Tsirkin
#include "vhost.h"
40 d5970055 Michael S. Tsirkin
41 d5970055 Michael S. Tsirkin
struct vhost_net {
42 d5970055 Michael S. Tsirkin
    struct vhost_dev dev;
43 d5970055 Michael S. Tsirkin
    struct vhost_virtqueue vqs[2];
44 d5970055 Michael S. Tsirkin
    int backend;
45 35277d14 Stefan Hajnoczi
    NetClientState *nc;
46 d5970055 Michael S. Tsirkin
};
47 d5970055 Michael S. Tsirkin
48 d5970055 Michael S. Tsirkin
unsigned vhost_net_get_features(struct vhost_net *net, unsigned features)
49 d5970055 Michael S. Tsirkin
{
50 d5970055 Michael S. Tsirkin
    /* Clear features not supported by host kernel. */
51 d5970055 Michael S. Tsirkin
    if (!(net->dev.features & (1 << VIRTIO_F_NOTIFY_ON_EMPTY))) {
52 d5970055 Michael S. Tsirkin
        features &= ~(1 << VIRTIO_F_NOTIFY_ON_EMPTY);
53 d5970055 Michael S. Tsirkin
    }
54 d5970055 Michael S. Tsirkin
    if (!(net->dev.features & (1 << VIRTIO_RING_F_INDIRECT_DESC))) {
55 d5970055 Michael S. Tsirkin
        features &= ~(1 << VIRTIO_RING_F_INDIRECT_DESC);
56 d5970055 Michael S. Tsirkin
    }
57 bcbabae8 Michael S. Tsirkin
    if (!(net->dev.features & (1 << VIRTIO_RING_F_EVENT_IDX))) {
58 bcbabae8 Michael S. Tsirkin
        features &= ~(1 << VIRTIO_RING_F_EVENT_IDX);
59 bcbabae8 Michael S. Tsirkin
    }
60 ca736c8e Michael S. Tsirkin
    if (!(net->dev.features & (1 << VIRTIO_NET_F_MRG_RXBUF))) {
61 ca736c8e Michael S. Tsirkin
        features &= ~(1 << VIRTIO_NET_F_MRG_RXBUF);
62 ca736c8e Michael S. Tsirkin
    }
63 d5970055 Michael S. Tsirkin
    return features;
64 d5970055 Michael S. Tsirkin
}
65 d5970055 Michael S. Tsirkin
66 d5970055 Michael S. Tsirkin
void vhost_net_ack_features(struct vhost_net *net, unsigned features)
67 d5970055 Michael S. Tsirkin
{
68 d5970055 Michael S. Tsirkin
    net->dev.acked_features = net->dev.backend_features;
69 d5970055 Michael S. Tsirkin
    if (features & (1 << VIRTIO_F_NOTIFY_ON_EMPTY)) {
70 d5970055 Michael S. Tsirkin
        net->dev.acked_features |= (1 << VIRTIO_F_NOTIFY_ON_EMPTY);
71 d5970055 Michael S. Tsirkin
    }
72 d5970055 Michael S. Tsirkin
    if (features & (1 << VIRTIO_RING_F_INDIRECT_DESC)) {
73 d5970055 Michael S. Tsirkin
        net->dev.acked_features |= (1 << VIRTIO_RING_F_INDIRECT_DESC);
74 d5970055 Michael S. Tsirkin
    }
75 bcbabae8 Michael S. Tsirkin
    if (features & (1 << VIRTIO_RING_F_EVENT_IDX)) {
76 bcbabae8 Michael S. Tsirkin
        net->dev.acked_features |= (1 << VIRTIO_RING_F_EVENT_IDX);
77 bcbabae8 Michael S. Tsirkin
    }
78 ca736c8e Michael S. Tsirkin
    if (features & (1 << VIRTIO_NET_F_MRG_RXBUF)) {
79 ca736c8e Michael S. Tsirkin
        net->dev.acked_features |= (1 << VIRTIO_NET_F_MRG_RXBUF);
80 ca736c8e Michael S. Tsirkin
    }
81 d5970055 Michael S. Tsirkin
}
82 d5970055 Michael S. Tsirkin
83 4e68f7a0 Stefan Hajnoczi
static int vhost_net_get_fd(NetClientState *backend)
84 d5970055 Michael S. Tsirkin
{
85 d5970055 Michael S. Tsirkin
    switch (backend->info->type) {
86 2be64a68 Laszlo Ersek
    case NET_CLIENT_OPTIONS_KIND_TAP:
87 d5970055 Michael S. Tsirkin
        return tap_get_fd(backend);
88 d5970055 Michael S. Tsirkin
    default:
89 d5970055 Michael S. Tsirkin
        fprintf(stderr, "vhost-net requires tap backend\n");
90 d5970055 Michael S. Tsirkin
        return -EBADFD;
91 d5970055 Michael S. Tsirkin
    }
92 d5970055 Michael S. Tsirkin
}
93 d5970055 Michael S. Tsirkin
94 4e68f7a0 Stefan Hajnoczi
struct vhost_net *vhost_net_init(NetClientState *backend, int devfd,
95 5430a28f mst@redhat.com
                                 bool force)
96 d5970055 Michael S. Tsirkin
{
97 d5970055 Michael S. Tsirkin
    int r;
98 7267c094 Anthony Liguori
    struct vhost_net *net = g_malloc(sizeof *net);
99 d5970055 Michael S. Tsirkin
    if (!backend) {
100 d5970055 Michael S. Tsirkin
        fprintf(stderr, "vhost-net requires backend to be setup\n");
101 d5970055 Michael S. Tsirkin
        goto fail;
102 d5970055 Michael S. Tsirkin
    }
103 d5970055 Michael S. Tsirkin
    r = vhost_net_get_fd(backend);
104 d5970055 Michael S. Tsirkin
    if (r < 0) {
105 d5970055 Michael S. Tsirkin
        goto fail;
106 d5970055 Michael S. Tsirkin
    }
107 35277d14 Stefan Hajnoczi
    net->nc = backend;
108 d5970055 Michael S. Tsirkin
    net->dev.backend_features = tap_has_vnet_hdr(backend) ? 0 :
109 d5970055 Michael S. Tsirkin
        (1 << VHOST_NET_F_VIRTIO_NET_HDR);
110 d5970055 Michael S. Tsirkin
    net->backend = r;
111 d5970055 Michael S. Tsirkin
112 1241ed94 Stefan Hajnoczi
    r = vhost_dev_init(&net->dev, devfd, "/dev/vhost-net", force);
113 d5970055 Michael S. Tsirkin
    if (r < 0) {
114 d5970055 Michael S. Tsirkin
        goto fail;
115 d5970055 Michael S. Tsirkin
    }
116 ca736c8e Michael S. Tsirkin
    if (!tap_has_vnet_hdr_len(backend,
117 ca736c8e Michael S. Tsirkin
                              sizeof(struct virtio_net_hdr_mrg_rxbuf))) {
118 ca736c8e Michael S. Tsirkin
        net->dev.features &= ~(1 << VIRTIO_NET_F_MRG_RXBUF);
119 ca736c8e Michael S. Tsirkin
    }
120 d5970055 Michael S. Tsirkin
    if (~net->dev.features & net->dev.backend_features) {
121 0bfcd599 Blue Swirl
        fprintf(stderr, "vhost lacks feature mask %" PRIu64 " for backend\n",
122 29f91781 Jes Sorensen
                (uint64_t)(~net->dev.features & net->dev.backend_features));
123 d5970055 Michael S. Tsirkin
        vhost_dev_cleanup(&net->dev);
124 d5970055 Michael S. Tsirkin
        goto fail;
125 d5970055 Michael S. Tsirkin
    }
126 d5970055 Michael S. Tsirkin
127 d5970055 Michael S. Tsirkin
    /* Set sane init value. Override when guest acks. */
128 d5970055 Michael S. Tsirkin
    vhost_net_ack_features(net, 0);
129 d5970055 Michael S. Tsirkin
    return net;
130 d5970055 Michael S. Tsirkin
fail:
131 7267c094 Anthony Liguori
    g_free(net);
132 d5970055 Michael S. Tsirkin
    return NULL;
133 d5970055 Michael S. Tsirkin
}
134 d5970055 Michael S. Tsirkin
135 5430a28f mst@redhat.com
bool vhost_net_query(VHostNetState *net, VirtIODevice *dev)
136 5430a28f mst@redhat.com
{
137 5430a28f mst@redhat.com
    return vhost_dev_query(&net->dev, dev);
138 5430a28f mst@redhat.com
}
139 5430a28f mst@redhat.com
140 d5970055 Michael S. Tsirkin
int vhost_net_start(struct vhost_net *net,
141 d5970055 Michael S. Tsirkin
                    VirtIODevice *dev)
142 d5970055 Michael S. Tsirkin
{
143 d5970055 Michael S. Tsirkin
    struct vhost_vring_file file = { };
144 d5970055 Michael S. Tsirkin
    int r;
145 b0b3db79 Michael S. Tsirkin
146 b0b3db79 Michael S. Tsirkin
    net->dev.nvqs = 2;
147 b0b3db79 Michael S. Tsirkin
    net->dev.vqs = net->vqs;
148 b0b3db79 Michael S. Tsirkin
149 b0b3db79 Michael S. Tsirkin
    r = vhost_dev_enable_notifiers(&net->dev, dev);
150 b0b3db79 Michael S. Tsirkin
    if (r < 0) {
151 b0b3db79 Michael S. Tsirkin
        goto fail_notifiers;
152 b0b3db79 Michael S. Tsirkin
    }
153 d5970055 Michael S. Tsirkin
154 d5970055 Michael S. Tsirkin
    r = vhost_dev_start(&net->dev, dev);
155 d5970055 Michael S. Tsirkin
    if (r < 0) {
156 b0b3db79 Michael S. Tsirkin
        goto fail_start;
157 d5970055 Michael S. Tsirkin
    }
158 d5970055 Michael S. Tsirkin
159 35277d14 Stefan Hajnoczi
    net->nc->info->poll(net->nc, false);
160 d5970055 Michael S. Tsirkin
    qemu_set_fd_handler(net->backend, NULL, NULL, NULL);
161 d5970055 Michael S. Tsirkin
    file.fd = net->backend;
162 d5970055 Michael S. Tsirkin
    for (file.index = 0; file.index < net->dev.nvqs; ++file.index) {
163 d5970055 Michael S. Tsirkin
        r = ioctl(net->dev.control, VHOST_NET_SET_BACKEND, &file);
164 d5970055 Michael S. Tsirkin
        if (r < 0) {
165 d5970055 Michael S. Tsirkin
            r = -errno;
166 d5970055 Michael S. Tsirkin
            goto fail;
167 d5970055 Michael S. Tsirkin
        }
168 d5970055 Michael S. Tsirkin
    }
169 d5970055 Michael S. Tsirkin
    return 0;
170 d5970055 Michael S. Tsirkin
fail:
171 d5970055 Michael S. Tsirkin
    file.fd = -1;
172 6b37c87c Michael S. Tsirkin
    while (file.index-- > 0) {
173 d5970055 Michael S. Tsirkin
        int r = ioctl(net->dev.control, VHOST_NET_SET_BACKEND, &file);
174 d5970055 Michael S. Tsirkin
        assert(r >= 0);
175 d5970055 Michael S. Tsirkin
    }
176 35277d14 Stefan Hajnoczi
    net->nc->info->poll(net->nc, true);
177 d5970055 Michael S. Tsirkin
    vhost_dev_stop(&net->dev, dev);
178 b0b3db79 Michael S. Tsirkin
fail_start:
179 b0b3db79 Michael S. Tsirkin
    vhost_dev_disable_notifiers(&net->dev, dev);
180 b0b3db79 Michael S. Tsirkin
fail_notifiers:
181 d5970055 Michael S. Tsirkin
    return r;
182 d5970055 Michael S. Tsirkin
}
183 d5970055 Michael S. Tsirkin
184 d5970055 Michael S. Tsirkin
void vhost_net_stop(struct vhost_net *net,
185 d5970055 Michael S. Tsirkin
                    VirtIODevice *dev)
186 d5970055 Michael S. Tsirkin
{
187 d5970055 Michael S. Tsirkin
    struct vhost_vring_file file = { .fd = -1 };
188 d5970055 Michael S. Tsirkin
189 d5970055 Michael S. Tsirkin
    for (file.index = 0; file.index < net->dev.nvqs; ++file.index) {
190 d5970055 Michael S. Tsirkin
        int r = ioctl(net->dev.control, VHOST_NET_SET_BACKEND, &file);
191 d5970055 Michael S. Tsirkin
        assert(r >= 0);
192 d5970055 Michael S. Tsirkin
    }
193 35277d14 Stefan Hajnoczi
    net->nc->info->poll(net->nc, true);
194 d5970055 Michael S. Tsirkin
    vhost_dev_stop(&net->dev, dev);
195 b0b3db79 Michael S. Tsirkin
    vhost_dev_disable_notifiers(&net->dev, dev);
196 d5970055 Michael S. Tsirkin
}
197 d5970055 Michael S. Tsirkin
198 d5970055 Michael S. Tsirkin
void vhost_net_cleanup(struct vhost_net *net)
199 d5970055 Michael S. Tsirkin
{
200 d5970055 Michael S. Tsirkin
    vhost_dev_cleanup(&net->dev);
201 7267c094 Anthony Liguori
    g_free(net);
202 d5970055 Michael S. Tsirkin
}
203 d5970055 Michael S. Tsirkin
#else
204 4e68f7a0 Stefan Hajnoczi
struct vhost_net *vhost_net_init(NetClientState *backend, int devfd,
205 5430a28f mst@redhat.com
                                 bool force)
206 5430a28f mst@redhat.com
{
207 35f75462 Michael Tokarev
    error_report("vhost-net support is not compiled in");
208 5430a28f mst@redhat.com
    return NULL;
209 5430a28f mst@redhat.com
}
210 5430a28f mst@redhat.com
211 5430a28f mst@redhat.com
bool vhost_net_query(VHostNetState *net, VirtIODevice *dev)
212 d5970055 Michael S. Tsirkin
{
213 5430a28f mst@redhat.com
    return false;
214 d5970055 Michael S. Tsirkin
}
215 d5970055 Michael S. Tsirkin
216 d5970055 Michael S. Tsirkin
int vhost_net_start(struct vhost_net *net,
217 d5970055 Michael S. Tsirkin
                    VirtIODevice *dev)
218 d5970055 Michael S. Tsirkin
{
219 5430a28f mst@redhat.com
    return -ENOSYS;
220 d5970055 Michael S. Tsirkin
}
221 d5970055 Michael S. Tsirkin
void vhost_net_stop(struct vhost_net *net,
222 d5970055 Michael S. Tsirkin
                    VirtIODevice *dev)
223 d5970055 Michael S. Tsirkin
{
224 d5970055 Michael S. Tsirkin
}
225 d5970055 Michael S. Tsirkin
226 d5970055 Michael S. Tsirkin
void vhost_net_cleanup(struct vhost_net *net)
227 d5970055 Michael S. Tsirkin
{
228 d5970055 Michael S. Tsirkin
}
229 d5970055 Michael S. Tsirkin
230 d5970055 Michael S. Tsirkin
unsigned vhost_net_get_features(struct vhost_net *net, unsigned features)
231 d5970055 Michael S. Tsirkin
{
232 5430a28f mst@redhat.com
    return features;
233 d5970055 Michael S. Tsirkin
}
234 d5970055 Michael S. Tsirkin
void vhost_net_ack_features(struct vhost_net *net, unsigned features)
235 d5970055 Michael S. Tsirkin
{
236 d5970055 Michael S. Tsirkin
}
237 d5970055 Michael S. Tsirkin
#endif