qemu/replay/replay-net.c
<<
>>
Prefs
   1/*
   2 * replay-net.c
   3 *
   4 * Copyright (c) 2010-2016 Institute for System Programming
   5 *                         of the Russian Academy of Sciences.
   6 *
   7 * This work is licensed under the terms of the GNU GPL, version 2 or later.
   8 * See the COPYING file in the top-level directory.
   9 *
  10 */
  11
  12#include "qemu/osdep.h"
  13#include "qemu/error-report.h"
  14#include "sysemu/replay.h"
  15#include "replay-internal.h"
  16#include "sysemu/sysemu.h"
  17#include "net/net.h"
  18#include "net/filter.h"
  19#include "qemu/iov.h"
  20
  21struct ReplayNetState {
  22    NetFilterState *nfs;
  23    int id;
  24};
  25
  26typedef struct NetEvent {
  27    uint8_t id;
  28    uint32_t flags;
  29    uint8_t *data;
  30    size_t size;
  31} NetEvent;
  32
  33static NetFilterState **network_filters;
  34static int network_filters_count;
  35
  36ReplayNetState *replay_register_net(NetFilterState *nfs)
  37{
  38    ReplayNetState *rns = g_new0(ReplayNetState, 1);
  39    rns->nfs = nfs;
  40    rns->id = network_filters_count++;
  41    network_filters = g_realloc(network_filters,
  42                                network_filters_count
  43                                    * sizeof(*network_filters));
  44    network_filters[network_filters_count - 1] = nfs;
  45    return rns;
  46}
  47
  48void replay_unregister_net(ReplayNetState *rns)
  49{
  50    network_filters[rns->id] = NULL;
  51    g_free(rns);
  52}
  53
  54void replay_net_packet_event(ReplayNetState *rns, unsigned flags,
  55                             const struct iovec *iov, int iovcnt)
  56{
  57    NetEvent *event = g_new(NetEvent, 1);
  58    event->flags = flags;
  59    event->data = g_malloc(iov_size(iov, iovcnt));
  60    event->size = iov_size(iov, iovcnt);
  61    event->id = rns->id;
  62    iov_to_buf(iov, iovcnt, 0, event->data, event->size);
  63
  64    replay_add_event(REPLAY_ASYNC_EVENT_NET, event, NULL, 0);
  65}
  66
  67void replay_event_net_run(void *opaque)
  68{
  69    NetEvent *event = opaque;
  70    struct iovec iov = {
  71        .iov_base = (void *)event->data,
  72        .iov_len = event->size
  73    };
  74
  75    assert(event->id < network_filters_count);
  76
  77    qemu_netfilter_pass_to_next(network_filters[event->id]->netdev,
  78        event->flags, &iov, 1, network_filters[event->id]);
  79
  80    g_free(event->data);
  81    g_free(event);
  82}
  83
  84void replay_event_net_save(void *opaque)
  85{
  86    NetEvent *event = opaque;
  87
  88    replay_put_byte(event->id);
  89    replay_put_dword(event->flags);
  90    replay_put_array(event->data, event->size);
  91}
  92
  93void *replay_event_net_load(void)
  94{
  95    NetEvent *event = g_new(NetEvent, 1);
  96
  97    event->id = replay_get_byte();
  98    event->flags = replay_get_dword();
  99    replay_get_array_alloc(&event->data, &event->size);
 100
 101    return event;
 102}
 103