123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101 |
- /*
- * replay-net.c
- *
- * Copyright (c) 2010-2016 Institute for System Programming
- * of the Russian Academy of Sciences.
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- *
- */
- #include "qemu/osdep.h"
- #include "qemu/error-report.h"
- #include "sysemu/replay.h"
- #include "replay-internal.h"
- #include "net/net.h"
- #include "net/filter.h"
- #include "qemu/iov.h"
- struct ReplayNetState {
- NetFilterState *nfs;
- int id;
- };
- typedef struct NetEvent {
- uint8_t id;
- uint32_t flags;
- uint8_t *data;
- size_t size;
- } NetEvent;
- static NetFilterState **network_filters;
- static int network_filters_count;
- ReplayNetState *replay_register_net(NetFilterState *nfs)
- {
- ReplayNetState *rns = g_new0(ReplayNetState, 1);
- rns->nfs = nfs;
- rns->id = network_filters_count++;
- network_filters = g_realloc(network_filters,
- network_filters_count
- * sizeof(*network_filters));
- network_filters[network_filters_count - 1] = nfs;
- return rns;
- }
- void replay_unregister_net(ReplayNetState *rns)
- {
- network_filters[rns->id] = NULL;
- g_free(rns);
- }
- void replay_net_packet_event(ReplayNetState *rns, unsigned flags,
- const struct iovec *iov, int iovcnt)
- {
- NetEvent *event = g_new(NetEvent, 1);
- event->flags = flags;
- event->data = g_malloc(iov_size(iov, iovcnt));
- event->size = iov_size(iov, iovcnt);
- event->id = rns->id;
- iov_to_buf(iov, iovcnt, 0, event->data, event->size);
- replay_add_event(REPLAY_ASYNC_EVENT_NET, event, NULL, 0);
- }
- void replay_event_net_run(void *opaque)
- {
- NetEvent *event = opaque;
- struct iovec iov = {
- .iov_base = (void *)event->data,
- .iov_len = event->size
- };
- assert(event->id < network_filters_count);
- qemu_netfilter_pass_to_next(network_filters[event->id]->netdev,
- event->flags, &iov, 1, network_filters[event->id]);
- g_free(event->data);
- g_free(event);
- }
- void replay_event_net_save(void *opaque)
- {
- NetEvent *event = opaque;
- replay_put_byte(event->id);
- replay_put_dword(event->flags);
- replay_put_array(event->data, event->size);
- }
- void *replay_event_net_load(void)
- {
- NetEvent *event = g_new(NetEvent, 1);
- event->id = replay_get_byte();
- event->flags = replay_get_dword();
- replay_get_array_alloc(&event->data, &event->size);
- return event;
- }
|