xref: /qemu/net/filter-replay.c (revision 646c5478)
1*646c5478SPavel Dovgalyuk /*
2*646c5478SPavel Dovgalyuk  * filter-replay.c
3*646c5478SPavel Dovgalyuk  *
4*646c5478SPavel Dovgalyuk  * Copyright (c) 2010-2016 Institute for System Programming
5*646c5478SPavel Dovgalyuk  *                         of the Russian Academy of Sciences.
6*646c5478SPavel Dovgalyuk  *
7*646c5478SPavel Dovgalyuk  * This work is licensed under the terms of the GNU GPL, version 2 or later.
8*646c5478SPavel Dovgalyuk  * See the COPYING file in the top-level directory.
9*646c5478SPavel Dovgalyuk  *
10*646c5478SPavel Dovgalyuk  */
11*646c5478SPavel Dovgalyuk 
12*646c5478SPavel Dovgalyuk #include "qemu/osdep.h"
13*646c5478SPavel Dovgalyuk #include "clients.h"
14*646c5478SPavel Dovgalyuk #include "qapi/error.h"
15*646c5478SPavel Dovgalyuk #include "qemu-common.h"
16*646c5478SPavel Dovgalyuk #include "qemu/error-report.h"
17*646c5478SPavel Dovgalyuk #include "qemu/iov.h"
18*646c5478SPavel Dovgalyuk #include "qemu/log.h"
19*646c5478SPavel Dovgalyuk #include "qemu/timer.h"
20*646c5478SPavel Dovgalyuk #include "qapi/visitor.h"
21*646c5478SPavel Dovgalyuk #include "net/filter.h"
22*646c5478SPavel Dovgalyuk #include "sysemu/replay.h"
23*646c5478SPavel Dovgalyuk 
24*646c5478SPavel Dovgalyuk #define TYPE_FILTER_REPLAY "filter-replay"
25*646c5478SPavel Dovgalyuk 
26*646c5478SPavel Dovgalyuk #define FILTER_REPLAY(obj) \
27*646c5478SPavel Dovgalyuk     OBJECT_CHECK(NetFilterReplayState, (obj), TYPE_FILTER_REPLAY)
28*646c5478SPavel Dovgalyuk 
29*646c5478SPavel Dovgalyuk struct NetFilterReplayState {
30*646c5478SPavel Dovgalyuk     NetFilterState nfs;
31*646c5478SPavel Dovgalyuk     ReplayNetState *rns;
32*646c5478SPavel Dovgalyuk };
33*646c5478SPavel Dovgalyuk typedef struct NetFilterReplayState NetFilterReplayState;
34*646c5478SPavel Dovgalyuk 
35*646c5478SPavel Dovgalyuk static ssize_t filter_replay_receive_iov(NetFilterState *nf,
36*646c5478SPavel Dovgalyuk                                          NetClientState *sndr,
37*646c5478SPavel Dovgalyuk                                          unsigned flags,
38*646c5478SPavel Dovgalyuk                                          const struct iovec *iov,
39*646c5478SPavel Dovgalyuk                                          int iovcnt, NetPacketSent *sent_cb)
40*646c5478SPavel Dovgalyuk {
41*646c5478SPavel Dovgalyuk     NetFilterReplayState *nfrs = FILTER_REPLAY(nf);
42*646c5478SPavel Dovgalyuk     switch (replay_mode) {
43*646c5478SPavel Dovgalyuk     case REPLAY_MODE_RECORD:
44*646c5478SPavel Dovgalyuk         if (nf->netdev == sndr) {
45*646c5478SPavel Dovgalyuk             replay_net_packet_event(nfrs->rns, flags, iov, iovcnt);
46*646c5478SPavel Dovgalyuk             return iov_size(iov, iovcnt);
47*646c5478SPavel Dovgalyuk         }
48*646c5478SPavel Dovgalyuk         return 0;
49*646c5478SPavel Dovgalyuk     case REPLAY_MODE_PLAY:
50*646c5478SPavel Dovgalyuk         /* Drop all packets in replay mode.
51*646c5478SPavel Dovgalyuk            Packets from the log will be injected by the replay module. */
52*646c5478SPavel Dovgalyuk         return iov_size(iov, iovcnt);
53*646c5478SPavel Dovgalyuk     default:
54*646c5478SPavel Dovgalyuk         /* Pass all the packets. */
55*646c5478SPavel Dovgalyuk         return 0;
56*646c5478SPavel Dovgalyuk     }
57*646c5478SPavel Dovgalyuk }
58*646c5478SPavel Dovgalyuk 
59*646c5478SPavel Dovgalyuk static void filter_replay_instance_init(Object *obj)
60*646c5478SPavel Dovgalyuk {
61*646c5478SPavel Dovgalyuk     NetFilterReplayState *nfrs = FILTER_REPLAY(obj);
62*646c5478SPavel Dovgalyuk     nfrs->rns = replay_register_net(&nfrs->nfs);
63*646c5478SPavel Dovgalyuk }
64*646c5478SPavel Dovgalyuk 
65*646c5478SPavel Dovgalyuk static void filter_replay_instance_finalize(Object *obj)
66*646c5478SPavel Dovgalyuk {
67*646c5478SPavel Dovgalyuk     NetFilterReplayState *nfrs = FILTER_REPLAY(obj);
68*646c5478SPavel Dovgalyuk     replay_unregister_net(nfrs->rns);
69*646c5478SPavel Dovgalyuk }
70*646c5478SPavel Dovgalyuk 
71*646c5478SPavel Dovgalyuk static void filter_replay_class_init(ObjectClass *oc, void *data)
72*646c5478SPavel Dovgalyuk {
73*646c5478SPavel Dovgalyuk     NetFilterClass *nfc = NETFILTER_CLASS(oc);
74*646c5478SPavel Dovgalyuk 
75*646c5478SPavel Dovgalyuk     nfc->receive_iov = filter_replay_receive_iov;
76*646c5478SPavel Dovgalyuk }
77*646c5478SPavel Dovgalyuk 
78*646c5478SPavel Dovgalyuk static const TypeInfo filter_replay_info = {
79*646c5478SPavel Dovgalyuk     .name = TYPE_FILTER_REPLAY,
80*646c5478SPavel Dovgalyuk     .parent = TYPE_NETFILTER,
81*646c5478SPavel Dovgalyuk     .class_init = filter_replay_class_init,
82*646c5478SPavel Dovgalyuk     .instance_init = filter_replay_instance_init,
83*646c5478SPavel Dovgalyuk     .instance_finalize = filter_replay_instance_finalize,
84*646c5478SPavel Dovgalyuk     .instance_size = sizeof(NetFilterReplayState),
85*646c5478SPavel Dovgalyuk };
86*646c5478SPavel Dovgalyuk 
87*646c5478SPavel Dovgalyuk static void filter_replay_register_types(void)
88*646c5478SPavel Dovgalyuk {
89*646c5478SPavel Dovgalyuk     type_register_static(&filter_replay_info);
90*646c5478SPavel Dovgalyuk }
91*646c5478SPavel Dovgalyuk 
92*646c5478SPavel Dovgalyuk type_init(filter_replay_register_types);
93