1*5c361cc3SMark McLoughlin /* 2*5c361cc3SMark McLoughlin * QEMU System Emulator 3*5c361cc3SMark McLoughlin * 4*5c361cc3SMark McLoughlin * Copyright (c) 2003-2008 Fabrice Bellard 5*5c361cc3SMark McLoughlin * 6*5c361cc3SMark McLoughlin * Permission is hereby granted, free of charge, to any person obtaining a copy 7*5c361cc3SMark McLoughlin * of this software and associated documentation files (the "Software"), to deal 8*5c361cc3SMark McLoughlin * in the Software without restriction, including without limitation the rights 9*5c361cc3SMark McLoughlin * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10*5c361cc3SMark McLoughlin * copies of the Software, and to permit persons to whom the Software is 11*5c361cc3SMark McLoughlin * furnished to do so, subject to the following conditions: 12*5c361cc3SMark McLoughlin * 13*5c361cc3SMark McLoughlin * The above copyright notice and this permission notice shall be included in 14*5c361cc3SMark McLoughlin * all copies or substantial portions of the Software. 15*5c361cc3SMark McLoughlin * 16*5c361cc3SMark McLoughlin * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17*5c361cc3SMark McLoughlin * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18*5c361cc3SMark McLoughlin * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19*5c361cc3SMark McLoughlin * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20*5c361cc3SMark McLoughlin * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21*5c361cc3SMark McLoughlin * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22*5c361cc3SMark McLoughlin * THE SOFTWARE. 23*5c361cc3SMark McLoughlin */ 24*5c361cc3SMark McLoughlin #include "net/vde.h" 25*5c361cc3SMark McLoughlin 26*5c361cc3SMark McLoughlin #include "config-host.h" 27*5c361cc3SMark McLoughlin 28*5c361cc3SMark McLoughlin #include <libvdeplug.h> 29*5c361cc3SMark McLoughlin 30*5c361cc3SMark McLoughlin #include "net.h" 31*5c361cc3SMark McLoughlin #include "qemu-char.h" 32*5c361cc3SMark McLoughlin #include "qemu-common.h" 33*5c361cc3SMark McLoughlin #include "qemu-option.h" 34*5c361cc3SMark McLoughlin #include "sysemu.h" 35*5c361cc3SMark McLoughlin 36*5c361cc3SMark McLoughlin typedef struct VDEState { 37*5c361cc3SMark McLoughlin VLANClientState *vc; 38*5c361cc3SMark McLoughlin VDECONN *vde; 39*5c361cc3SMark McLoughlin } VDEState; 40*5c361cc3SMark McLoughlin 41*5c361cc3SMark McLoughlin static void vde_to_qemu(void *opaque) 42*5c361cc3SMark McLoughlin { 43*5c361cc3SMark McLoughlin VDEState *s = opaque; 44*5c361cc3SMark McLoughlin uint8_t buf[4096]; 45*5c361cc3SMark McLoughlin int size; 46*5c361cc3SMark McLoughlin 47*5c361cc3SMark McLoughlin size = vde_recv(s->vde, (char *)buf, sizeof(buf), 0); 48*5c361cc3SMark McLoughlin if (size > 0) { 49*5c361cc3SMark McLoughlin qemu_send_packet(s->vc, buf, size); 50*5c361cc3SMark McLoughlin } 51*5c361cc3SMark McLoughlin } 52*5c361cc3SMark McLoughlin 53*5c361cc3SMark McLoughlin static ssize_t vde_receive(VLANClientState *vc, const uint8_t *buf, size_t size) 54*5c361cc3SMark McLoughlin { 55*5c361cc3SMark McLoughlin VDEState *s = vc->opaque; 56*5c361cc3SMark McLoughlin ssize_t ret; 57*5c361cc3SMark McLoughlin 58*5c361cc3SMark McLoughlin do { 59*5c361cc3SMark McLoughlin ret = vde_send(s->vde, (const char *)buf, size, 0); 60*5c361cc3SMark McLoughlin } while (ret < 0 && errno == EINTR); 61*5c361cc3SMark McLoughlin 62*5c361cc3SMark McLoughlin return ret; 63*5c361cc3SMark McLoughlin } 64*5c361cc3SMark McLoughlin 65*5c361cc3SMark McLoughlin static void vde_cleanup(VLANClientState *vc) 66*5c361cc3SMark McLoughlin { 67*5c361cc3SMark McLoughlin VDEState *s = vc->opaque; 68*5c361cc3SMark McLoughlin qemu_set_fd_handler(vde_datafd(s->vde), NULL, NULL, NULL); 69*5c361cc3SMark McLoughlin vde_close(s->vde); 70*5c361cc3SMark McLoughlin qemu_free(s); 71*5c361cc3SMark McLoughlin } 72*5c361cc3SMark McLoughlin 73*5c361cc3SMark McLoughlin static int net_vde_init(VLANState *vlan, const char *model, 74*5c361cc3SMark McLoughlin const char *name, const char *sock, 75*5c361cc3SMark McLoughlin int port, const char *group, int mode) 76*5c361cc3SMark McLoughlin { 77*5c361cc3SMark McLoughlin VDEState *s; 78*5c361cc3SMark McLoughlin char *init_group = (char *)group; 79*5c361cc3SMark McLoughlin char *init_sock = (char *)sock; 80*5c361cc3SMark McLoughlin 81*5c361cc3SMark McLoughlin struct vde_open_args args = { 82*5c361cc3SMark McLoughlin .port = port, 83*5c361cc3SMark McLoughlin .group = init_group, 84*5c361cc3SMark McLoughlin .mode = mode, 85*5c361cc3SMark McLoughlin }; 86*5c361cc3SMark McLoughlin 87*5c361cc3SMark McLoughlin s = qemu_mallocz(sizeof(VDEState)); 88*5c361cc3SMark McLoughlin s->vde = vde_open(init_sock, (char *)"QEMU", &args); 89*5c361cc3SMark McLoughlin if (!s->vde){ 90*5c361cc3SMark McLoughlin free(s); 91*5c361cc3SMark McLoughlin return -1; 92*5c361cc3SMark McLoughlin } 93*5c361cc3SMark McLoughlin s->vc = qemu_new_vlan_client(NET_CLIENT_TYPE_VDE, 94*5c361cc3SMark McLoughlin vlan, NULL, model, name, NULL, 95*5c361cc3SMark McLoughlin vde_receive, NULL, NULL, 96*5c361cc3SMark McLoughlin vde_cleanup, s); 97*5c361cc3SMark McLoughlin qemu_set_fd_handler(vde_datafd(s->vde), vde_to_qemu, NULL, s); 98*5c361cc3SMark McLoughlin snprintf(s->vc->info_str, sizeof(s->vc->info_str), "sock=%s,fd=%d", 99*5c361cc3SMark McLoughlin sock, vde_datafd(s->vde)); 100*5c361cc3SMark McLoughlin return 0; 101*5c361cc3SMark McLoughlin } 102*5c361cc3SMark McLoughlin 103*5c361cc3SMark McLoughlin int net_init_vde(QemuOpts *opts, Monitor *mon, const char *name, VLANState *vlan) 104*5c361cc3SMark McLoughlin { 105*5c361cc3SMark McLoughlin const char *sock; 106*5c361cc3SMark McLoughlin const char *group; 107*5c361cc3SMark McLoughlin int port, mode; 108*5c361cc3SMark McLoughlin 109*5c361cc3SMark McLoughlin sock = qemu_opt_get(opts, "sock"); 110*5c361cc3SMark McLoughlin group = qemu_opt_get(opts, "group"); 111*5c361cc3SMark McLoughlin 112*5c361cc3SMark McLoughlin port = qemu_opt_get_number(opts, "port", 0); 113*5c361cc3SMark McLoughlin mode = qemu_opt_get_number(opts, "mode", 0700); 114*5c361cc3SMark McLoughlin 115*5c361cc3SMark McLoughlin if (net_vde_init(vlan, "vde", name, sock, port, group, mode) == -1) { 116*5c361cc3SMark McLoughlin return -1; 117*5c361cc3SMark McLoughlin } 118*5c361cc3SMark McLoughlin 119*5c361cc3SMark McLoughlin if (vlan) { 120*5c361cc3SMark McLoughlin vlan->nb_host_devs++; 121*5c361cc3SMark McLoughlin } 122*5c361cc3SMark McLoughlin 123*5c361cc3SMark McLoughlin return 0; 124*5c361cc3SMark McLoughlin } 125