xref: /qemu/hw/net/vhost_net.c (revision ed8b4afe5ff290ae119237e4fa2142e9f1832230)
1d5970055SMichael S. Tsirkin /*
2d5970055SMichael S. Tsirkin  * vhost-net support
3d5970055SMichael S. Tsirkin  *
4d5970055SMichael S. Tsirkin  * Copyright Red Hat, Inc. 2010
5d5970055SMichael S. Tsirkin  *
6d5970055SMichael S. Tsirkin  * Authors:
7d5970055SMichael S. Tsirkin  *  Michael S. Tsirkin <mst@redhat.com>
8d5970055SMichael S. Tsirkin  *
9d5970055SMichael S. Tsirkin  * This work is licensed under the terms of the GNU GPL, version 2.  See
10d5970055SMichael S. Tsirkin  * the COPYING file in the top-level directory.
116b620ca3SPaolo Bonzini  *
126b620ca3SPaolo Bonzini  * Contributions after 2012-01-13 are licensed under the terms of the
136b620ca3SPaolo Bonzini  * GNU GPL, version 2 or (at your option) any later version.
14d5970055SMichael S. Tsirkin  */
15d5970055SMichael S. Tsirkin 
161422e32dSPaolo Bonzini #include "net/net.h"
17d5970055SMichael S. Tsirkin #include "net/tap.h"
18d5970055SMichael S. Tsirkin 
190d09e41aSPaolo Bonzini #include "hw/virtio/virtio-net.h"
200d09e41aSPaolo Bonzini #include "net/vhost_net.h"
211de7afc9SPaolo Bonzini #include "qemu/error-report.h"
22d5970055SMichael S. Tsirkin 
23d5970055SMichael S. Tsirkin #include "config.h"
24d5970055SMichael S. Tsirkin 
25d5970055SMichael S. Tsirkin #ifdef CONFIG_VHOST_NET
26d5970055SMichael S. Tsirkin #include <linux/vhost.h>
27d5970055SMichael S. Tsirkin #include <sys/socket.h>
28d5970055SMichael S. Tsirkin #include <linux/kvm.h>
29d5970055SMichael S. Tsirkin #include <fcntl.h>
30d5970055SMichael S. Tsirkin #include <sys/ioctl.h>
31d5970055SMichael S. Tsirkin #include <linux/virtio_ring.h>
32d5970055SMichael S. Tsirkin #include <netpacket/packet.h>
33d5970055SMichael S. Tsirkin #include <net/ethernet.h>
34d5970055SMichael S. Tsirkin #include <net/if.h>
35d5970055SMichael S. Tsirkin #include <netinet/in.h>
36d5970055SMichael S. Tsirkin 
37d5970055SMichael S. Tsirkin #include <stdio.h>
38d5970055SMichael S. Tsirkin 
390d09e41aSPaolo Bonzini #include "hw/virtio/vhost.h"
401c819449SKONRAD Frederic #include "hw/virtio/virtio-bus.h"
41d5970055SMichael S. Tsirkin 
42d5970055SMichael S. Tsirkin struct vhost_net {
43d5970055SMichael S. Tsirkin     struct vhost_dev dev;
44d5970055SMichael S. Tsirkin     struct vhost_virtqueue vqs[2];
45d5970055SMichael S. Tsirkin     int backend;
4635277d14SStefan Hajnoczi     NetClientState *nc;
47d5970055SMichael S. Tsirkin };
48d5970055SMichael S. Tsirkin 
492e6d46d7SNikolay Nikolaev /* Features supported by host kernel. */
502e6d46d7SNikolay Nikolaev static const int kernel_feature_bits[] = {
512e6d46d7SNikolay Nikolaev     VIRTIO_F_NOTIFY_ON_EMPTY,
522e6d46d7SNikolay Nikolaev     VIRTIO_RING_F_INDIRECT_DESC,
532e6d46d7SNikolay Nikolaev     VIRTIO_RING_F_EVENT_IDX,
542e6d46d7SNikolay Nikolaev     VIRTIO_NET_F_MRG_RXBUF,
552e6d46d7SNikolay Nikolaev     VHOST_INVALID_FEATURE_BIT
562e6d46d7SNikolay Nikolaev };
572e6d46d7SNikolay Nikolaev 
582e6d46d7SNikolay Nikolaev static const int *vhost_net_get_feature_bits(struct vhost_net *net)
592e6d46d7SNikolay Nikolaev {
602e6d46d7SNikolay Nikolaev     const int *feature_bits = 0;
612e6d46d7SNikolay Nikolaev 
622e6d46d7SNikolay Nikolaev     switch (net->nc->info->type) {
632e6d46d7SNikolay Nikolaev     case NET_CLIENT_OPTIONS_KIND_TAP:
642e6d46d7SNikolay Nikolaev         feature_bits = kernel_feature_bits;
652e6d46d7SNikolay Nikolaev         break;
662e6d46d7SNikolay Nikolaev     default:
672e6d46d7SNikolay Nikolaev         error_report("Feature bits not defined for this type: %d",
682e6d46d7SNikolay Nikolaev                 net->nc->info->type);
692e6d46d7SNikolay Nikolaev         break;
702e6d46d7SNikolay Nikolaev     }
712e6d46d7SNikolay Nikolaev 
722e6d46d7SNikolay Nikolaev     return feature_bits;
732e6d46d7SNikolay Nikolaev }
742e6d46d7SNikolay Nikolaev 
75d5970055SMichael S. Tsirkin unsigned vhost_net_get_features(struct vhost_net *net, unsigned features)
76d5970055SMichael S. Tsirkin {
772e6d46d7SNikolay Nikolaev     return vhost_get_features(&net->dev, vhost_net_get_feature_bits(net),
782e6d46d7SNikolay Nikolaev             features);
79d5970055SMichael S. Tsirkin }
80d5970055SMichael S. Tsirkin 
81d5970055SMichael S. Tsirkin void vhost_net_ack_features(struct vhost_net *net, unsigned features)
82d5970055SMichael S. Tsirkin {
832e6d46d7SNikolay Nikolaev     vhost_ack_features(&net->dev, vhost_net_get_feature_bits(net), features);
84d5970055SMichael S. Tsirkin }
85d5970055SMichael S. Tsirkin 
864e68f7a0SStefan Hajnoczi static int vhost_net_get_fd(NetClientState *backend)
87d5970055SMichael S. Tsirkin {
88d5970055SMichael S. Tsirkin     switch (backend->info->type) {
892be64a68SLaszlo Ersek     case NET_CLIENT_OPTIONS_KIND_TAP:
90d5970055SMichael S. Tsirkin         return tap_get_fd(backend);
91d5970055SMichael S. Tsirkin     default:
92d5970055SMichael S. Tsirkin         fprintf(stderr, "vhost-net requires tap backend\n");
93d5970055SMichael S. Tsirkin         return -EBADFD;
94d5970055SMichael S. Tsirkin     }
95d5970055SMichael S. Tsirkin }
96d5970055SMichael S. Tsirkin 
974e68f7a0SStefan Hajnoczi struct vhost_net *vhost_net_init(NetClientState *backend, int devfd,
985430a28fSmst@redhat.com                                  bool force)
99d5970055SMichael S. Tsirkin {
100d5970055SMichael S. Tsirkin     int r;
1017267c094SAnthony Liguori     struct vhost_net *net = g_malloc(sizeof *net);
102d5970055SMichael S. Tsirkin     if (!backend) {
103d5970055SMichael S. Tsirkin         fprintf(stderr, "vhost-net requires backend to be setup\n");
104d5970055SMichael S. Tsirkin         goto fail;
105d5970055SMichael S. Tsirkin     }
106d5970055SMichael S. Tsirkin     r = vhost_net_get_fd(backend);
107d5970055SMichael S. Tsirkin     if (r < 0) {
108d5970055SMichael S. Tsirkin         goto fail;
109d5970055SMichael S. Tsirkin     }
11035277d14SStefan Hajnoczi     net->nc = backend;
111e3e48565SStefan Hajnoczi     net->dev.backend_features = qemu_has_vnet_hdr(backend) ? 0 :
112d5970055SMichael S. Tsirkin         (1 << VHOST_NET_F_VIRTIO_NET_HDR);
113d5970055SMichael S. Tsirkin     net->backend = r;
114d5970055SMichael S. Tsirkin 
115f56a1247SMichael S. Tsirkin     net->dev.nvqs = 2;
116f56a1247SMichael S. Tsirkin     net->dev.vqs = net->vqs;
117f56a1247SMichael S. Tsirkin 
1181241ed94SStefan Hajnoczi     r = vhost_dev_init(&net->dev, devfd, "/dev/vhost-net", force);
119d5970055SMichael S. Tsirkin     if (r < 0) {
120d5970055SMichael S. Tsirkin         goto fail;
121d5970055SMichael S. Tsirkin     }
122e3e48565SStefan Hajnoczi     if (!qemu_has_vnet_hdr_len(backend,
123ca736c8eSMichael S. Tsirkin                                sizeof(struct virtio_net_hdr_mrg_rxbuf))) {
124ca736c8eSMichael S. Tsirkin         net->dev.features &= ~(1 << VIRTIO_NET_F_MRG_RXBUF);
125ca736c8eSMichael S. Tsirkin     }
126d5970055SMichael S. Tsirkin     if (~net->dev.features & net->dev.backend_features) {
1270bfcd599SBlue Swirl         fprintf(stderr, "vhost lacks feature mask %" PRIu64 " for backend\n",
12829f91781SJes Sorensen                 (uint64_t)(~net->dev.features & net->dev.backend_features));
129d5970055SMichael S. Tsirkin         vhost_dev_cleanup(&net->dev);
130d5970055SMichael S. Tsirkin         goto fail;
131d5970055SMichael S. Tsirkin     }
132d5970055SMichael S. Tsirkin 
133d5970055SMichael S. Tsirkin     /* Set sane init value. Override when guest acks. */
134d5970055SMichael S. Tsirkin     vhost_net_ack_features(net, 0);
135d5970055SMichael S. Tsirkin     return net;
136d5970055SMichael S. Tsirkin fail:
1377267c094SAnthony Liguori     g_free(net);
138d5970055SMichael S. Tsirkin     return NULL;
139d5970055SMichael S. Tsirkin }
140d5970055SMichael S. Tsirkin 
1415430a28fSmst@redhat.com bool vhost_net_query(VHostNetState *net, VirtIODevice *dev)
1425430a28fSmst@redhat.com {
1435430a28fSmst@redhat.com     return vhost_dev_query(&net->dev, dev);
1445430a28fSmst@redhat.com }
1455430a28fSmst@redhat.com 
146a9f98bb5SJason Wang static int vhost_net_start_one(struct vhost_net *net,
147a9f98bb5SJason Wang                                VirtIODevice *dev,
148a9f98bb5SJason Wang                                int vq_index)
149d5970055SMichael S. Tsirkin {
150d5970055SMichael S. Tsirkin     struct vhost_vring_file file = { };
151d5970055SMichael S. Tsirkin     int r;
152b0b3db79SMichael S. Tsirkin 
153a9f98bb5SJason Wang     if (net->dev.started) {
154a9f98bb5SJason Wang         return 0;
155a9f98bb5SJason Wang     }
156a9f98bb5SJason Wang 
157a9f98bb5SJason Wang     net->dev.nvqs = 2;
158a9f98bb5SJason Wang     net->dev.vqs = net->vqs;
159a9f98bb5SJason Wang     net->dev.vq_index = vq_index;
160a9f98bb5SJason Wang 
161b0b3db79SMichael S. Tsirkin     r = vhost_dev_enable_notifiers(&net->dev, dev);
162b0b3db79SMichael S. Tsirkin     if (r < 0) {
163b0b3db79SMichael S. Tsirkin         goto fail_notifiers;
164b0b3db79SMichael S. Tsirkin     }
165d5970055SMichael S. Tsirkin 
166d5970055SMichael S. Tsirkin     r = vhost_dev_start(&net->dev, dev);
167d5970055SMichael S. Tsirkin     if (r < 0) {
168b0b3db79SMichael S. Tsirkin         goto fail_start;
169d5970055SMichael S. Tsirkin     }
170d5970055SMichael S. Tsirkin 
171212d69f2SNikolay Nikolaev     if (net->nc->info->poll) {
17235277d14SStefan Hajnoczi         net->nc->info->poll(net->nc, false);
173212d69f2SNikolay Nikolaev     }
174212d69f2SNikolay Nikolaev 
175d5970055SMichael S. Tsirkin     qemu_set_fd_handler(net->backend, NULL, NULL, NULL);
176d5970055SMichael S. Tsirkin     file.fd = net->backend;
177d5970055SMichael S. Tsirkin     for (file.index = 0; file.index < net->dev.nvqs; ++file.index) {
178d5970055SMichael S. Tsirkin         r = ioctl(net->dev.control, VHOST_NET_SET_BACKEND, &file);
179d5970055SMichael S. Tsirkin         if (r < 0) {
180d5970055SMichael S. Tsirkin             r = -errno;
181d5970055SMichael S. Tsirkin             goto fail;
182d5970055SMichael S. Tsirkin         }
183d5970055SMichael S. Tsirkin     }
184d5970055SMichael S. Tsirkin     return 0;
185d5970055SMichael S. Tsirkin fail:
186d5970055SMichael S. Tsirkin     file.fd = -1;
1876b37c87cSMichael S. Tsirkin     while (file.index-- > 0) {
188d5970055SMichael S. Tsirkin         int r = ioctl(net->dev.control, VHOST_NET_SET_BACKEND, &file);
189d5970055SMichael S. Tsirkin         assert(r >= 0);
190d5970055SMichael S. Tsirkin     }
191212d69f2SNikolay Nikolaev     if (net->nc->info->poll) {
19235277d14SStefan Hajnoczi         net->nc->info->poll(net->nc, true);
193212d69f2SNikolay Nikolaev     }
194d5970055SMichael S. Tsirkin     vhost_dev_stop(&net->dev, dev);
195b0b3db79SMichael S. Tsirkin fail_start:
196b0b3db79SMichael S. Tsirkin     vhost_dev_disable_notifiers(&net->dev, dev);
197b0b3db79SMichael S. Tsirkin fail_notifiers:
198d5970055SMichael S. Tsirkin     return r;
199d5970055SMichael S. Tsirkin }
200d5970055SMichael S. Tsirkin 
201a9f98bb5SJason Wang static void vhost_net_stop_one(struct vhost_net *net,
202d5970055SMichael S. Tsirkin                                VirtIODevice *dev)
203d5970055SMichael S. Tsirkin {
204d5970055SMichael S. Tsirkin     struct vhost_vring_file file = { .fd = -1 };
205d5970055SMichael S. Tsirkin 
206a9f98bb5SJason Wang     if (!net->dev.started) {
207a9f98bb5SJason Wang         return;
208a9f98bb5SJason Wang     }
209a9f98bb5SJason Wang 
210d5970055SMichael S. Tsirkin     for (file.index = 0; file.index < net->dev.nvqs; ++file.index) {
211d5970055SMichael S. Tsirkin         int r = ioctl(net->dev.control, VHOST_NET_SET_BACKEND, &file);
212d5970055SMichael S. Tsirkin         assert(r >= 0);
213d5970055SMichael S. Tsirkin     }
214212d69f2SNikolay Nikolaev     if (net->nc->info->poll) {
21535277d14SStefan Hajnoczi         net->nc->info->poll(net->nc, true);
216212d69f2SNikolay Nikolaev     }
217d5970055SMichael S. Tsirkin     vhost_dev_stop(&net->dev, dev);
218b0b3db79SMichael S. Tsirkin     vhost_dev_disable_notifiers(&net->dev, dev);
219d5970055SMichael S. Tsirkin }
220d5970055SMichael S. Tsirkin 
221a9f98bb5SJason Wang int vhost_net_start(VirtIODevice *dev, NetClientState *ncs,
222a9f98bb5SJason Wang                     int total_queues)
223a9f98bb5SJason Wang {
2241c819449SKONRAD Frederic     BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(dev)));
2251c819449SKONRAD Frederic     VirtioBusState *vbus = VIRTIO_BUS(qbus);
2261c819449SKONRAD Frederic     VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(vbus);
227a9f98bb5SJason Wang     int r, i = 0;
228a9f98bb5SJason Wang 
2291c819449SKONRAD Frederic     if (!k->set_guest_notifiers) {
230312fd5f2SMarkus Armbruster         error_report("binding does not support guest notifiers");
231a9f98bb5SJason Wang         r = -ENOSYS;
232a9f98bb5SJason Wang         goto err;
233a9f98bb5SJason Wang     }
234a9f98bb5SJason Wang 
235a9f98bb5SJason Wang     for (i = 0; i < total_queues; i++) {
236*ed8b4afeSNikolay Nikolaev         r = vhost_net_start_one(get_vhost_net(ncs[i].peer), dev, i * 2);
237a9f98bb5SJason Wang 
238a9f98bb5SJason Wang         if (r < 0) {
239a9f98bb5SJason Wang             goto err;
240a9f98bb5SJason Wang         }
241a9f98bb5SJason Wang     }
242a9f98bb5SJason Wang 
2431c819449SKONRAD Frederic     r = k->set_guest_notifiers(qbus->parent, total_queues * 2, true);
244a9f98bb5SJason Wang     if (r < 0) {
245312fd5f2SMarkus Armbruster         error_report("Error binding guest notifier: %d", -r);
246a9f98bb5SJason Wang         goto err;
247a9f98bb5SJason Wang     }
248a9f98bb5SJason Wang 
249a9f98bb5SJason Wang     return 0;
250a9f98bb5SJason Wang 
251a9f98bb5SJason Wang err:
252a9f98bb5SJason Wang     while (--i >= 0) {
253*ed8b4afeSNikolay Nikolaev         vhost_net_stop_one(get_vhost_net(ncs[i].peer), dev);
254a9f98bb5SJason Wang     }
255a9f98bb5SJason Wang     return r;
256a9f98bb5SJason Wang }
257a9f98bb5SJason Wang 
258a9f98bb5SJason Wang void vhost_net_stop(VirtIODevice *dev, NetClientState *ncs,
259a9f98bb5SJason Wang                     int total_queues)
260a9f98bb5SJason Wang {
2611c819449SKONRAD Frederic     BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(dev)));
2621c819449SKONRAD Frederic     VirtioBusState *vbus = VIRTIO_BUS(qbus);
2631c819449SKONRAD Frederic     VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(vbus);
264a9f98bb5SJason Wang     int i, r;
265a9f98bb5SJason Wang 
2661c819449SKONRAD Frederic     r = k->set_guest_notifiers(qbus->parent, total_queues * 2, false);
267a9f98bb5SJason Wang     if (r < 0) {
268a9f98bb5SJason Wang         fprintf(stderr, "vhost guest notifier cleanup failed: %d\n", r);
269a9f98bb5SJason Wang         fflush(stderr);
270a9f98bb5SJason Wang     }
271a9f98bb5SJason Wang     assert(r >= 0);
272a9f98bb5SJason Wang 
273a9f98bb5SJason Wang     for (i = 0; i < total_queues; i++) {
274*ed8b4afeSNikolay Nikolaev         vhost_net_stop_one(get_vhost_net(ncs[i].peer), dev);
275a9f98bb5SJason Wang     }
276a9f98bb5SJason Wang }
277a9f98bb5SJason Wang 
278d5970055SMichael S. Tsirkin void vhost_net_cleanup(struct vhost_net *net)
279d5970055SMichael S. Tsirkin {
280d5970055SMichael S. Tsirkin     vhost_dev_cleanup(&net->dev);
2817267c094SAnthony Liguori     g_free(net);
282d5970055SMichael S. Tsirkin }
283f56a1247SMichael S. Tsirkin 
284f56a1247SMichael S. Tsirkin bool vhost_net_virtqueue_pending(VHostNetState *net, int idx)
285f56a1247SMichael S. Tsirkin {
286f56a1247SMichael S. Tsirkin     return vhost_virtqueue_pending(&net->dev, idx);
287f56a1247SMichael S. Tsirkin }
288f56a1247SMichael S. Tsirkin 
289f56a1247SMichael S. Tsirkin void vhost_net_virtqueue_mask(VHostNetState *net, VirtIODevice *dev,
290f56a1247SMichael S. Tsirkin                               int idx, bool mask)
291f56a1247SMichael S. Tsirkin {
292f56a1247SMichael S. Tsirkin     vhost_virtqueue_mask(&net->dev, dev, idx, mask);
293f56a1247SMichael S. Tsirkin }
294*ed8b4afeSNikolay Nikolaev 
295*ed8b4afeSNikolay Nikolaev VHostNetState *get_vhost_net(NetClientState *nc)
296*ed8b4afeSNikolay Nikolaev {
297*ed8b4afeSNikolay Nikolaev     VHostNetState *vhost_net = 0;
298*ed8b4afeSNikolay Nikolaev 
299*ed8b4afeSNikolay Nikolaev     if (!nc) {
300*ed8b4afeSNikolay Nikolaev         return 0;
301*ed8b4afeSNikolay Nikolaev     }
302*ed8b4afeSNikolay Nikolaev 
303*ed8b4afeSNikolay Nikolaev     switch (nc->info->type) {
304*ed8b4afeSNikolay Nikolaev     case NET_CLIENT_OPTIONS_KIND_TAP:
305*ed8b4afeSNikolay Nikolaev         vhost_net = tap_get_vhost_net(nc);
306*ed8b4afeSNikolay Nikolaev         break;
307*ed8b4afeSNikolay Nikolaev     default:
308*ed8b4afeSNikolay Nikolaev         break;
309*ed8b4afeSNikolay Nikolaev     }
310*ed8b4afeSNikolay Nikolaev 
311*ed8b4afeSNikolay Nikolaev     return vhost_net;
312*ed8b4afeSNikolay Nikolaev }
313d5970055SMichael S. Tsirkin #else
3144e68f7a0SStefan Hajnoczi struct vhost_net *vhost_net_init(NetClientState *backend, int devfd,
3155430a28fSmst@redhat.com                                  bool force)
316d5970055SMichael S. Tsirkin {
31735f75462SMichael Tokarev     error_report("vhost-net support is not compiled in");
318d5970055SMichael S. Tsirkin     return NULL;
319d5970055SMichael S. Tsirkin }
320d5970055SMichael S. Tsirkin 
3215430a28fSmst@redhat.com bool vhost_net_query(VHostNetState *net, VirtIODevice *dev)
3225430a28fSmst@redhat.com {
3235430a28fSmst@redhat.com     return false;
3245430a28fSmst@redhat.com }
3255430a28fSmst@redhat.com 
326a9f98bb5SJason Wang int vhost_net_start(VirtIODevice *dev,
327a9f98bb5SJason Wang                     NetClientState *ncs,
328a9f98bb5SJason Wang                     int total_queues)
329d5970055SMichael S. Tsirkin {
330d5970055SMichael S. Tsirkin     return -ENOSYS;
331d5970055SMichael S. Tsirkin }
332a9f98bb5SJason Wang void vhost_net_stop(VirtIODevice *dev,
333a9f98bb5SJason Wang                     NetClientState *ncs,
334a9f98bb5SJason Wang                     int total_queues)
335d5970055SMichael S. Tsirkin {
336d5970055SMichael S. Tsirkin }
337d5970055SMichael S. Tsirkin 
338d5970055SMichael S. Tsirkin void vhost_net_cleanup(struct vhost_net *net)
339d5970055SMichael S. Tsirkin {
340d5970055SMichael S. Tsirkin }
341d5970055SMichael S. Tsirkin 
342d5970055SMichael S. Tsirkin unsigned vhost_net_get_features(struct vhost_net *net, unsigned features)
343d5970055SMichael S. Tsirkin {
344d5970055SMichael S. Tsirkin     return features;
345d5970055SMichael S. Tsirkin }
346d5970055SMichael S. Tsirkin void vhost_net_ack_features(struct vhost_net *net, unsigned features)
347d5970055SMichael S. Tsirkin {
348d5970055SMichael S. Tsirkin }
349f56a1247SMichael S. Tsirkin 
350f56a1247SMichael S. Tsirkin bool vhost_net_virtqueue_pending(VHostNetState *net, int idx)
351f56a1247SMichael S. Tsirkin {
3524dd72e04SStefan Weil     return false;
353f56a1247SMichael S. Tsirkin }
354f56a1247SMichael S. Tsirkin 
355f56a1247SMichael S. Tsirkin void vhost_net_virtqueue_mask(VHostNetState *net, VirtIODevice *dev,
356f56a1247SMichael S. Tsirkin                               int idx, bool mask)
357f56a1247SMichael S. Tsirkin {
358f56a1247SMichael S. Tsirkin }
359*ed8b4afeSNikolay Nikolaev 
360*ed8b4afeSNikolay Nikolaev VHostNetState *get_vhost_net(NetClientState *nc)
361*ed8b4afeSNikolay Nikolaev {
362*ed8b4afeSNikolay Nikolaev     return 0;
363*ed8b4afeSNikolay Nikolaev }
364d5970055SMichael S. Tsirkin #endif
365