xref: /openbmc/qemu/net/vde.c (revision 53b85d95)
15c361cc3SMark McLoughlin /*
25c361cc3SMark McLoughlin  * QEMU System Emulator
35c361cc3SMark McLoughlin  *
45c361cc3SMark McLoughlin  * Copyright (c) 2003-2008 Fabrice Bellard
55c361cc3SMark McLoughlin  *
65c361cc3SMark McLoughlin  * Permission is hereby granted, free of charge, to any person obtaining a copy
75c361cc3SMark McLoughlin  * of this software and associated documentation files (the "Software"), to deal
85c361cc3SMark McLoughlin  * in the Software without restriction, including without limitation the rights
95c361cc3SMark McLoughlin  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
105c361cc3SMark McLoughlin  * copies of the Software, and to permit persons to whom the Software is
115c361cc3SMark McLoughlin  * furnished to do so, subject to the following conditions:
125c361cc3SMark McLoughlin  *
135c361cc3SMark McLoughlin  * The above copyright notice and this permission notice shall be included in
145c361cc3SMark McLoughlin  * all copies or substantial portions of the Software.
155c361cc3SMark McLoughlin  *
165c361cc3SMark McLoughlin  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
175c361cc3SMark McLoughlin  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
185c361cc3SMark McLoughlin  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
195c361cc3SMark McLoughlin  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
205c361cc3SMark McLoughlin  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
215c361cc3SMark McLoughlin  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
225c361cc3SMark McLoughlin  * THE SOFTWARE.
235c361cc3SMark McLoughlin  */
242744d920SPeter Maydell #include "qemu/osdep.h"
255c361cc3SMark McLoughlin 
265c361cc3SMark McLoughlin #include <libvdeplug.h>
275c361cc3SMark McLoughlin 
281422e32dSPaolo Bonzini #include "net/net.h"
29a245fc18SPaolo Bonzini #include "clients.h"
301de7afc9SPaolo Bonzini #include "qemu/option.h"
313f124b68SLiming Wang #include "qemu/main-loop.h"
327587855cSJulia Suvorova via Qemu-devel #include "qapi/error.h"
335c361cc3SMark McLoughlin 
345c361cc3SMark McLoughlin typedef struct VDEState {
354e68f7a0SStefan Hajnoczi     NetClientState nc;
365c361cc3SMark McLoughlin     VDECONN *vde;
375c361cc3SMark McLoughlin } VDEState;
385c361cc3SMark McLoughlin 
vde_to_qemu(void * opaque)395c361cc3SMark McLoughlin static void vde_to_qemu(void *opaque)
405c361cc3SMark McLoughlin {
415c361cc3SMark McLoughlin     VDEState *s = opaque;
42d32fcad3SScott Feldman     uint8_t buf[NET_BUFSIZE];
435c361cc3SMark McLoughlin     int size;
445c361cc3SMark McLoughlin 
455c361cc3SMark McLoughlin     size = vde_recv(s->vde, (char *)buf, sizeof(buf), 0);
465c361cc3SMark McLoughlin     if (size > 0) {
47b4e859c6SMark McLoughlin         qemu_send_packet(&s->nc, buf, size);
485c361cc3SMark McLoughlin     }
495c361cc3SMark McLoughlin }
505c361cc3SMark McLoughlin 
vde_receive(NetClientState * nc,const uint8_t * buf,size_t size)514e68f7a0SStefan Hajnoczi static ssize_t vde_receive(NetClientState *nc, const uint8_t *buf, size_t size)
525c361cc3SMark McLoughlin {
53b4e859c6SMark McLoughlin     VDEState *s = DO_UPCAST(VDEState, nc, nc);
545c361cc3SMark McLoughlin     ssize_t ret;
555c361cc3SMark McLoughlin 
565c361cc3SMark McLoughlin     do {
575c361cc3SMark McLoughlin       ret = vde_send(s->vde, (const char *)buf, size, 0);
585c361cc3SMark McLoughlin     } while (ret < 0 && errno == EINTR);
595c361cc3SMark McLoughlin 
605c361cc3SMark McLoughlin     return ret;
615c361cc3SMark McLoughlin }
625c361cc3SMark McLoughlin 
vde_cleanup(NetClientState * nc)634e68f7a0SStefan Hajnoczi static void vde_cleanup(NetClientState *nc)
645c361cc3SMark McLoughlin {
65b4e859c6SMark McLoughlin     VDEState *s = DO_UPCAST(VDEState, nc, nc);
665c361cc3SMark McLoughlin     qemu_set_fd_handler(vde_datafd(s->vde), NULL, NULL, NULL);
675c361cc3SMark McLoughlin     vde_close(s->vde);
685c361cc3SMark McLoughlin }
695c361cc3SMark McLoughlin 
70b4e859c6SMark McLoughlin static NetClientInfo net_vde_info = {
71f394b2e2SEric Blake     .type = NET_CLIENT_DRIVER_VDE,
72b4e859c6SMark McLoughlin     .size = sizeof(VDEState),
73b4e859c6SMark McLoughlin     .receive = vde_receive,
74b4e859c6SMark McLoughlin     .cleanup = vde_cleanup,
75b4e859c6SMark McLoughlin };
76b4e859c6SMark McLoughlin 
net_vde_init(NetClientState * peer,const char * model,const char * name,const char * sock,int port,const char * group,int mode,Error ** errp)774e68f7a0SStefan Hajnoczi static int net_vde_init(NetClientState *peer, const char *model,
785c361cc3SMark McLoughlin                         const char *name, const char *sock,
797587855cSJulia Suvorova via Qemu-devel                         int port, const char *group, int mode, Error **errp)
805c361cc3SMark McLoughlin {
814e68f7a0SStefan Hajnoczi     NetClientState *nc;
825c361cc3SMark McLoughlin     VDEState *s;
83b4e859c6SMark McLoughlin     VDECONN *vde;
845c361cc3SMark McLoughlin     char *init_group = (char *)group;
855c361cc3SMark McLoughlin     char *init_sock = (char *)sock;
865c361cc3SMark McLoughlin 
875c361cc3SMark McLoughlin     struct vde_open_args args = {
885c361cc3SMark McLoughlin         .port = port,
895c361cc3SMark McLoughlin         .group = init_group,
905c361cc3SMark McLoughlin         .mode = mode,
915c361cc3SMark McLoughlin     };
925c361cc3SMark McLoughlin 
93b4e859c6SMark McLoughlin     vde = vde_open(init_sock, (char *)"QEMU", &args);
94b4e859c6SMark McLoughlin     if (!vde){
957587855cSJulia Suvorova via Qemu-devel         error_setg_errno(errp, errno, "Could not open vde");
965c361cc3SMark McLoughlin         return -1;
975c361cc3SMark McLoughlin     }
98b4e859c6SMark McLoughlin 
99ab5f3f84SStefan Hajnoczi     nc = qemu_new_net_client(&net_vde_info, peer, model, name);
100b4e859c6SMark McLoughlin 
101*53b85d95SLaurent Vivier     qemu_set_info_str(nc, "sock=%s,fd=%d", sock, vde_datafd(vde));
102d89b4f83SJason Wang 
103b4e859c6SMark McLoughlin     s = DO_UPCAST(VDEState, nc, nc);
104b4e859c6SMark McLoughlin 
105b4e859c6SMark McLoughlin     s->vde = vde;
106b4e859c6SMark McLoughlin 
1075c361cc3SMark McLoughlin     qemu_set_fd_handler(vde_datafd(s->vde), vde_to_qemu, NULL, s);
108b4e859c6SMark McLoughlin 
1095c361cc3SMark McLoughlin     return 0;
1105c361cc3SMark McLoughlin }
1115c361cc3SMark McLoughlin 
net_init_vde(const Netdev * netdev,const char * name,NetClientState * peer,Error ** errp)112cebea510SKővágó, Zoltán int net_init_vde(const Netdev *netdev, const char *name,
113a30ecde6SMarkus Armbruster                  NetClientState *peer, Error **errp)
1145c361cc3SMark McLoughlin {
1154a917c39SLaszlo Ersek     const NetdevVdeOptions *vde;
1165c361cc3SMark McLoughlin 
117f394b2e2SEric Blake     assert(netdev->type == NET_CLIENT_DRIVER_VDE);
118f394b2e2SEric Blake     vde = &netdev->u.vde;
1195c361cc3SMark McLoughlin 
1204a917c39SLaszlo Ersek     /* missing optional values have been initialized to "all bits zero" */
121d33d93b2SStefan Hajnoczi     if (net_vde_init(peer, "vde", name, vde->sock, vde->port, vde->group,
1227587855cSJulia Suvorova via Qemu-devel                      vde->has_mode ? vde->mode : 0700, errp) == -1) {
1235c361cc3SMark McLoughlin         return -1;
1245c361cc3SMark McLoughlin     }
1255c361cc3SMark McLoughlin 
1265c361cc3SMark McLoughlin     return 0;
1275c361cc3SMark McLoughlin }
128