replay-net.c (2502B)
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}