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