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 "net/net.h"
  17#include "net/filter.h"
  18#include "qemu/iov.h"
  19
  20struct ReplayNetState {
  21    NetFilterState *nfs;
  22    int id;
  23};
  24
  25typedef struct NetEvent {
  26    uint8_t id;
  27    uint32_t flags;
  28    uint8_t *data;
  29    size_t size;
  30} NetEvent;
  31
  32static NetFilterState **network_filters;
  33static int network_filters_count;
  34
  35ReplayNetState *replay_register_net(NetFilterState *nfs)
  36{
  37    ReplayNetState *rns = g_new0(ReplayNetState, 1);
  38    rns->nfs = nfs;
  39    rns->id = network_filters_count++;
  40    network_filters = g_realloc(network_filters,
  41                                network_filters_count
  42                                    * sizeof(*network_filters));
  43    network_filters[network_filters_count - 1] = nfs;
  44    return rns;
  45}
  46
  47void replay_unregister_net(ReplayNetState *rns)
  48{
  49    network_filters[rns->id] = NULL;
  50    g_free(rns);
  51}
  52
  53void replay_net_packet_event(ReplayNetState *rns, unsigned flags,
  54                             const struct iovec *iov, int iovcnt)
  55{
  56    NetEvent *event = g_new(NetEvent, 1);
  57    event->flags = flags;
  58    event->data = g_malloc(iov_size(iov, iovcnt));
  59    event->size = iov_size(iov, iovcnt);
  60    event->id = rns->id;
  61    iov_to_buf(iov, iovcnt, 0, event->data, event->size);
  62
  63    replay_add_event(REPLAY_ASYNC_EVENT_NET, event, NULL, 0);
  64}
  65
  66void replay_event_net_run(void *opaque)
  67{
  68    NetEvent *event = opaque;
  69    struct iovec iov = {
  70        .iov_base = (void *)event->data,
  71        .iov_len = event->size
  72    };
  73
  74    assert(event->id < network_filters_count);
  75
  76    qemu_netfilter_pass_to_next(network_filters[event->id]->netdev,
  77        event->flags, &iov, 1, network_filters[event->id]);
  78
  79    g_free(event->data);
  80    g_free(event);
  81}
  82
  83void replay_event_net_save(void *opaque)
  84{
  85    NetEvent *event = opaque;
  86
  87    replay_put_byte(event->id);
  88    replay_put_dword(event->flags);
  89    replay_put_array(event->data, event->size);
  90}
  91
  92void *replay_event_net_load(void)
  93{
  94    NetEvent *event = g_new(NetEvent, 1);
  95
  96    event->id = replay_get_byte();
  97    event->flags = replay_get_dword();
  98    replay_get_array_alloc(&event->data, &event->size);
  99
 100    return event;
 101}
 102