-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This patch adds support of recording and replaying network packets in irount rr mode. Record and replay for network interactions is performed with the network filter. Each backend must have its own instance of the replay filter as follows: -netdev user,id=net1 -device rtl8139,netdev=net1 -object filter-replay,id=replay,netdev=net1 Replay network filter is used to record and replay network packets. While recording the virtual machine this filter puts all packets coming from the outer world into the log. In replay mode packets from the log are injected into the network device. All interactions with network backend in replay mode are disabled. v5 changes: - using iov_to_buf function instead of loop Signed-off-by: Pavel Dovgalyuk <[email protected]> Signed-off-by: Jason Wang <[email protected]>
- Loading branch information
Showing
10 changed files
with
246 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
/* | ||
* filter-replay.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 "clients.h" | ||
#include "qapi/error.h" | ||
#include "qemu-common.h" | ||
#include "qemu/error-report.h" | ||
#include "qemu/iov.h" | ||
#include "qemu/log.h" | ||
#include "qemu/timer.h" | ||
#include "qapi/visitor.h" | ||
#include "net/filter.h" | ||
#include "sysemu/replay.h" | ||
|
||
#define TYPE_FILTER_REPLAY "filter-replay" | ||
|
||
#define FILTER_REPLAY(obj) \ | ||
OBJECT_CHECK(NetFilterReplayState, (obj), TYPE_FILTER_REPLAY) | ||
|
||
struct NetFilterReplayState { | ||
NetFilterState nfs; | ||
ReplayNetState *rns; | ||
}; | ||
typedef struct NetFilterReplayState NetFilterReplayState; | ||
|
||
static ssize_t filter_replay_receive_iov(NetFilterState *nf, | ||
NetClientState *sndr, | ||
unsigned flags, | ||
const struct iovec *iov, | ||
int iovcnt, NetPacketSent *sent_cb) | ||
{ | ||
NetFilterReplayState *nfrs = FILTER_REPLAY(nf); | ||
switch (replay_mode) { | ||
case REPLAY_MODE_RECORD: | ||
if (nf->netdev == sndr) { | ||
replay_net_packet_event(nfrs->rns, flags, iov, iovcnt); | ||
return iov_size(iov, iovcnt); | ||
} | ||
return 0; | ||
case REPLAY_MODE_PLAY: | ||
/* Drop all packets in replay mode. | ||
Packets from the log will be injected by the replay module. */ | ||
return iov_size(iov, iovcnt); | ||
default: | ||
/* Pass all the packets. */ | ||
return 0; | ||
} | ||
} | ||
|
||
static void filter_replay_instance_init(Object *obj) | ||
{ | ||
NetFilterReplayState *nfrs = FILTER_REPLAY(obj); | ||
nfrs->rns = replay_register_net(&nfrs->nfs); | ||
} | ||
|
||
static void filter_replay_instance_finalize(Object *obj) | ||
{ | ||
NetFilterReplayState *nfrs = FILTER_REPLAY(obj); | ||
replay_unregister_net(nfrs->rns); | ||
} | ||
|
||
static void filter_replay_class_init(ObjectClass *oc, void *data) | ||
{ | ||
NetFilterClass *nfc = NETFILTER_CLASS(oc); | ||
|
||
nfc->receive_iov = filter_replay_receive_iov; | ||
} | ||
|
||
static const TypeInfo filter_replay_info = { | ||
.name = TYPE_FILTER_REPLAY, | ||
.parent = TYPE_NETFILTER, | ||
.class_init = filter_replay_class_init, | ||
.instance_init = filter_replay_instance_init, | ||
.instance_finalize = filter_replay_instance_finalize, | ||
.instance_size = sizeof(NetFilterReplayState), | ||
}; | ||
|
||
static void filter_replay_register_types(void) | ||
{ | ||
type_register_static(&filter_replay_info); | ||
} | ||
|
||
type_init(filter_replay_register_types); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
/* | ||
* 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 "sysemu/sysemu.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; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters