1
The following changes since commit e607bbee553cfe73072870cef458cfa4e78133e2:
1
The following changes since commit c6f28ed5075df79fef39c500362a3f4089256c9c:
2
2
3
Merge remote-tracking branch 'remotes/edgar/tags/edgar/xilinx-next-2018-01-26.for-upstream' into staging (2018-01-26 14:24:25 +0000)
3
Update version for v5.2.0-rc1 release (2020-11-10 22:29:57 +0000)
4
4
5
are available in the git repository at:
5
are available in the git repository at:
6
6
7
https://github.com/jasowang/qemu.git tags/net-pull-request
7
https://github.com/jasowang/qemu.git tags/net-pull-request
8
8
9
for you to fetch changes up to bf4835a4d5338bb7424827715df22570a8adc67c:
9
for you to fetch changes up to 71182187ddae5d5b17bd48464f719798321484ed:
10
10
11
MAINTAINERS: update Dmitry Fleytman email (2018-01-29 16:05:38 +0800)
11
hw/net/can/ctucan_core: Use stl_le_p to write to tx_buffers (2020-11-11 20:34:36 +0800)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
14
15
----------------------------------------------------------------
15
----------------------------------------------------------------
16
Mao Zhongyi (2):
16
AlexChen (1):
17
colo: modified the payload compare function
17
net/l2tpv3: Remove redundant check in net_init_l2tpv3()
18
colo: compare the packet based on the tcp sequence number
19
18
20
Philippe Mathieu-Daudé (1):
19
Cindy Lu (1):
21
MAINTAINERS: update Dmitry Fleytman email
20
virtio-net: Set mac address to hardware if the peer is vdpa
22
21
23
Thomas Huth (3):
22
Li Zhijian (2):
24
net: Allow hubports to connect to other netdevs
23
colo-compare: fix missing compare_seq initialization
25
net: Allow netdevs to be used with 'hostfwd_add' and 'hostfwd_remove'
24
colo-compare: check mark in mutual exclusion
26
qemu-doc: Get rid of "vlan=X" example in the documentation
27
25
28
MAINTAINERS | 8 +-
26
Pan Nengyuan (1):
29
hmp-commands.hx | 4 +-
27
net/filter-rewriter: destroy g_hash_table in colo_rewriter_cleanup
30
net/colo-compare.c | 411 +++++++++++++++++++++++++++++++++--------------------
28
31
net/colo.c | 9 ++
29
Peter Maydell (4):
32
net/colo.h | 15 ++
30
hw/net/can/ctucan: Don't allow guest to write off end of tx_buffer
33
net/hub.c | 27 +++-
31
hw/net/can/ctucan: Avoid unused value in ctucan_send_ready_buffers()
34
net/hub.h | 3 +-
32
hw/net/can/ctucan_core: Handle big-endian hosts
35
net/net.c | 2 +-
33
hw/net/can/ctucan_core: Use stl_le_p to write to tx_buffers
36
net/slirp.c | 33 +++--
34
37
net/trace-events | 2 +-
35
Prasad J Pandit (1):
38
qapi/net.json | 4 +-
36
net: remove an assert call in eth_get_gso_type
39
qemu-options.hx | 12 +-
37
40
12 files changed, 347 insertions(+), 183 deletions(-)
38
Rao, Lei (3):
39
Optimize seq_sorter function for colo-compare
40
Reduce the time of checkpoint for COLO
41
Fix the qemu crash when guest shutdown in COLO mode
42
43
Zhang Chen (4):
44
net/colo-compare.c: Fix compare_timeout format issue
45
net/colo-compare.c: Change the timer clock type
46
net/colo-compare.c: Add secondary old packet detection
47
net/colo-compare.c: Increase default queued packet scan frequency
48
49
hw/net/can/ctucan_core.c | 23 ++++++-------------
50
hw/net/can/ctucan_core.h | 3 +--
51
hw/net/virtio-net.c | 6 +++++
52
migration/ram.c | 14 +++++++++++-
53
net/colo-compare.c | 58 +++++++++++++++++++++++++-----------------------
54
net/colo.c | 5 +----
55
net/eth.c | 6 ++---
56
net/filter-rewriter.c | 2 ++
57
net/l2tpv3.c | 9 +++-----
58
softmmu/vl.c | 1 +
59
10 files changed, 67 insertions(+), 60 deletions(-)
41
60
42
61
62
diff view generated by jsdifflib
New patch
1
From: Cindy Lu <lulu@redhat.com>
1
2
3
If the peer's type is vdpa, we need to set the mac address to hardware
4
in virtio_net_device_realize,
5
6
Signed-off-by: Cindy Lu <lulu@redhat.com>
7
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
---
9
hw/net/virtio-net.c | 6 ++++++
10
1 file changed, 6 insertions(+)
11
12
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/net/virtio-net.c
15
+++ b/hw/net/virtio-net.c
16
@@ -XXX,XX +XXX,XX @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp)
17
nc = qemu_get_queue(n->nic);
18
nc->rxfilter_notify_enabled = 1;
19
20
+ if (nc->peer && nc->peer->info->type == NET_CLIENT_DRIVER_VHOST_VDPA) {
21
+ struct virtio_net_config netcfg = {};
22
+ memcpy(&netcfg.mac, &n->nic_conf.macaddr, ETH_ALEN);
23
+ vhost_net_set_config(get_vhost_net(nc->peer),
24
+ (uint8_t *)&netcfg, 0, ETH_ALEN, VHOST_SET_CONFIG_TYPE_MASTER);
25
+ }
26
QTAILQ_INIT(&n->rsc_chains);
27
n->qdev = dev;
28
29
--
30
2.7.4
31
32
diff view generated by jsdifflib
New patch
1
From: Pan Nengyuan <pannengyuan@huawei.com>
1
2
3
s->connection_track_table forgot to destroy in colo_rewriter_cleanup. Fix it.
4
5
Reported-by: Euler Robot <euler.robot@huawei.com>
6
Signed-off-by: Pan Nengyuan <pannengyuan@huawei.com>
7
Signed-off-by: Zhang Chen <chen.zhang@intel.com>
8
Reviewed-by: Zhang Chen <chen.zhang@intel.com>
9
Reviewed-by: Li Qiang <liq3ea@gmail.com>
10
Signed-off-by: Jason Wang <jasowang@redhat.com>
11
---
12
net/filter-rewriter.c | 2 ++
13
1 file changed, 2 insertions(+)
14
15
diff --git a/net/filter-rewriter.c b/net/filter-rewriter.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/net/filter-rewriter.c
18
+++ b/net/filter-rewriter.c
19
@@ -XXX,XX +XXX,XX @@ static void colo_rewriter_cleanup(NetFilterState *nf)
20
filter_rewriter_flush(nf);
21
g_free(s->incoming_queue);
22
}
23
+
24
+ g_hash_table_destroy(s->connection_track_table);
25
}
26
27
static void colo_rewriter_setup(NetFilterState *nf, Error **errp)
28
--
29
2.7.4
30
31
diff view generated by jsdifflib
New patch
1
From: "Rao, Lei" <lei.rao@intel.com>
1
2
3
The seq of tcp has been filled in fill_pkt_tcp_info, it
4
can be used directly here.
5
6
Signed-off-by: Lei Rao <lei.rao@intel.com>
7
Signed-off-by: Zhang Chen <chen.zhang@intel.com>
8
Reviewed-by: Li Zhijian <lizhijian@cn.fujitsu.com>
9
Reviewed-by: Zhang Chen <chen.zhang@intel.com>
10
Signed-off-by: Jason Wang <jasowang@redhat.com>
11
---
12
net/colo-compare.c | 7 ++-----
13
1 file changed, 2 insertions(+), 5 deletions(-)
14
15
diff --git a/net/colo-compare.c b/net/colo-compare.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/net/colo-compare.c
18
+++ b/net/colo-compare.c
19
@@ -XXX,XX +XXX,XX @@ static void colo_compare_inconsistency_notify(CompareState *s)
20
}
21
}
22
23
+/* Use restricted to colo_insert_packet() */
24
static gint seq_sorter(Packet *a, Packet *b, gpointer data)
25
{
26
- struct tcp_hdr *atcp, *btcp;
27
-
28
- atcp = (struct tcp_hdr *)(a->transport_header);
29
- btcp = (struct tcp_hdr *)(b->transport_header);
30
- return ntohl(atcp->th_seq) - ntohl(btcp->th_seq);
31
+ return a->tcp_seq - b->tcp_seq;
32
}
33
34
static void fill_pkt_tcp_info(void *data, uint32_t *max_ack)
35
--
36
2.7.4
37
38
diff view generated by jsdifflib
1
From: Thomas Huth <thuth@redhat.com>
1
From: "Rao, Lei" <lei.rao@intel.com>
2
2
3
QEMU can emulate hubs to connect NICs and netdevs. This is currently
3
we should set ram_bulk_stage to false after ram_state_init,
4
primarily used for the mis-named 'vlan' feature of the networking
4
otherwise the bitmap will be unused in migration_bitmap_find_dirty.
5
subsystem. Now the 'vlan' feature has been marked as deprecated, since
5
all pages in ram cache will be flushed to the ram of secondary guest
6
its name is rather confusing and the users often rather mis-configure
6
for each checkpoint.
7
their network when trying to use it. But while the 'vlan' parameter
8
should be removed at one point in time, the basic idea of emulating
9
a hub in QEMU is still good: It's useful for bundling up the output of
10
multiple NICs into one single l2tp netdev for example.
11
7
12
Now to be able to use the hubport feature without 'vlan's, there is one
8
Signed-off-by: Lei Rao <lei.rao@intel.com>
13
missing piece: The possibility to connect a hubport to a netdev, too.
9
Signed-off-by: Derek Su <dereksu@qnap.com>
14
This patch adds this possibility by introducing a new "netdev=..."
10
Signed-off-by: Zhang Chen <chen.zhang@intel.com>
15
parameter to the hubports.
11
Reviewed-by: Li Zhijian <lizhijian@cn.fujitsu.com>
16
12
Reviewed-by: Zhang Chen <chen.zhang@intel.com>
17
To bundle up the output of multiple NICs into one socket netdev, you can
18
now run QEMU with these parameters for example:
19
20
qemu-system-ppc64 ... -netdev socket,id=s1,connect=:11122 \
21
-netdev hubport,hubid=1,id=h1,netdev=s1 \
22
-netdev hubport,hubid=1,id=h2 -device e1000,netdev=h2 \
23
-netdev hubport,hubid=1,id=h3 -device virtio-net-pci,netdev=h3
24
25
For using the socket netdev, you have got to start another QEMU as the
26
receiving side first, for example with network dumping enabled:
27
28
qemu-system-x86_64 -M isapc -netdev socket,id=s0,listen=:11122 \
29
-device ne2k_isa,netdev=s0 \
30
-object filter-dump,id=f1,netdev=s0,file=/tmp/dump.dat
31
32
After the ppc64 guest tried to boot from both NICs, you can see in the
33
dump file (using Wireshark, for example), that the output of both NICs
34
(the e1000 and the virtio-net-pci) has been successfully transfered
35
via the socket netdev in this case.
36
37
Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
38
Signed-off-by: Thomas Huth <thuth@redhat.com>
39
Signed-off-by: Jason Wang <jasowang@redhat.com>
13
Signed-off-by: Jason Wang <jasowang@redhat.com>
40
---
14
---
41
net/hub.c | 27 +++++++++++++++++++++------
15
migration/ram.c | 14 +++++++++++++-
42
net/hub.h | 3 ++-
16
1 file changed, 13 insertions(+), 1 deletion(-)
43
net/net.c | 2 +-
44
qapi/net.json | 4 +++-
45
qemu-options.hx | 8 +++++---
46
5 files changed, 32 insertions(+), 12 deletions(-)
47
17
48
diff --git a/net/hub.c b/net/hub.c
18
diff --git a/migration/ram.c b/migration/ram.c
49
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
50
--- a/net/hub.c
20
--- a/migration/ram.c
51
+++ b/net/hub.c
21
+++ b/migration/ram.c
52
@@ -XXX,XX +XXX,XX @@
22
@@ -XXX,XX +XXX,XX @@ static void decompress_data_with_multi_threads(QEMUFile *f,
53
*/
23
qemu_mutex_unlock(&decomp_done_lock);
54
55
#include "qemu/osdep.h"
56
+#include "qapi/error.h"
57
#include "monitor/monitor.h"
58
#include "net/net.h"
59
#include "clients.h"
60
@@ -XXX,XX +XXX,XX @@ static NetClientInfo net_hub_port_info = {
61
.cleanup = net_hub_port_cleanup,
62
};
63
64
-static NetHubPort *net_hub_port_new(NetHub *hub, const char *name)
65
+static NetHubPort *net_hub_port_new(NetHub *hub, const char *name,
66
+ NetClientState *hubpeer)
67
{
68
NetClientState *nc;
69
NetHubPort *port;
70
@@ -XXX,XX +XXX,XX @@ static NetHubPort *net_hub_port_new(NetHub *hub, const char *name)
71
name = default_name;
72
}
73
74
- nc = qemu_new_net_client(&net_hub_port_info, NULL, "hub", name);
75
+ nc = qemu_new_net_client(&net_hub_port_info, hubpeer, "hub", name);
76
port = DO_UPCAST(NetHubPort, nc, nc);
77
port->id = id;
78
port->hub = hub;
79
@@ -XXX,XX +XXX,XX @@ static NetHubPort *net_hub_port_new(NetHub *hub, const char *name)
80
81
/**
82
* Create a port on a given hub
83
+ * @hub_id: Number of the hub
84
* @name: Net client name or NULL for default name.
85
+ * @hubpeer: Peer to use (if "netdev=id" has been specified)
86
*
87
* If there is no existing hub with the given id then a new hub is created.
88
*/
89
-NetClientState *net_hub_add_port(int hub_id, const char *name)
90
+NetClientState *net_hub_add_port(int hub_id, const char *name,
91
+ NetClientState *hubpeer)
92
{
93
NetHub *hub;
94
NetHubPort *port;
95
@@ -XXX,XX +XXX,XX @@ NetClientState *net_hub_add_port(int hub_id, const char *name)
96
hub = net_hub_new(hub_id);
97
}
98
99
- port = net_hub_port_new(hub, name);
100
+ port = net_hub_port_new(hub, name, hubpeer);
101
return &port->nc;
102
}
24
}
103
25
104
@@ -XXX,XX +XXX,XX @@ NetClientState *net_hub_port_find(int hub_id)
26
+ /*
27
+ * we must set ram_bulk_stage to false, otherwise in
28
+ * migation_bitmap_find_dirty the bitmap will be unused and
29
+ * all the pages in ram cache wil be flushed to the ram of
30
+ * secondary VM.
31
+ */
32
+static void colo_init_ram_state(void)
33
+{
34
+ ram_state_init(&ram_state);
35
+ ram_state->ram_bulk_stage = false;
36
+}
37
+
38
/*
39
* colo cache: this is for secondary VM, we cache the whole
40
* memory of the secondary VM, it is need to hold the global lock
41
@@ -XXX,XX +XXX,XX @@ int colo_init_ram_cache(void)
105
}
42
}
106
}
43
}
107
44
108
- nc = net_hub_add_port(hub_id, NULL);
45
- ram_state_init(&ram_state);
109
+ nc = net_hub_add_port(hub_id, NULL, NULL);
46
+ colo_init_ram_state();
110
return nc;
111
}
112
113
@@ -XXX,XX +XXX,XX @@ int net_init_hubport(const Netdev *netdev, const char *name,
114
NetClientState *peer, Error **errp)
115
{
116
const NetdevHubPortOptions *hubport;
117
+ NetClientState *hubpeer = NULL;
118
119
assert(netdev->type == NET_CLIENT_DRIVER_HUBPORT);
120
assert(!peer);
121
hubport = &netdev->u.hubport;
122
123
- net_hub_add_port(hubport->hubid, name);
124
+ if (hubport->has_netdev) {
125
+ hubpeer = qemu_find_netdev(hubport->netdev);
126
+ if (!hubpeer) {
127
+ error_setg(errp, "netdev '%s' not found", hubport->netdev);
128
+ return -1;
129
+ }
130
+ }
131
+
132
+ net_hub_add_port(hubport->hubid, name, hubpeer);
133
+
134
return 0;
47
return 0;
135
}
48
}
136
137
diff --git a/net/hub.h b/net/hub.h
138
index XXXXXXX..XXXXXXX 100644
139
--- a/net/hub.h
140
+++ b/net/hub.h
141
@@ -XXX,XX +XXX,XX @@
142
143
#include "qemu-common.h"
144
145
-NetClientState *net_hub_add_port(int hub_id, const char *name);
146
+NetClientState *net_hub_add_port(int hub_id, const char *name,
147
+ NetClientState *hubpeer);
148
NetClientState *net_hub_find_client_by_name(int hub_id, const char *name);
149
void net_hub_info(Monitor *mon);
150
void net_hub_check_clients(void);
151
diff --git a/net/net.c b/net/net.c
152
index XXXXXXX..XXXXXXX 100644
153
--- a/net/net.c
154
+++ b/net/net.c
155
@@ -XXX,XX +XXX,XX @@ static int net_client_init1(const void *object, bool is_netdev, Error **errp)
156
/* Do not add to a vlan if it's a nic with a netdev= parameter. */
157
if (netdev->type != NET_CLIENT_DRIVER_NIC ||
158
!opts->u.nic.has_netdev) {
159
- peer = net_hub_add_port(net->has_vlan ? net->vlan : 0, NULL);
160
+ peer = net_hub_add_port(net->has_vlan ? net->vlan : 0, NULL, NULL);
161
}
162
163
if (net->has_vlan && !vlan_warned) {
164
diff --git a/qapi/net.json b/qapi/net.json
165
index XXXXXXX..XXXXXXX 100644
166
--- a/qapi/net.json
167
+++ b/qapi/net.json
168
@@ -XXX,XX +XXX,XX @@
169
# Connect two or more net clients through a software hub.
170
#
171
# @hubid: hub identifier number
172
+# @netdev: used to connect hub to a netdev instead of a device (since 2.12)
173
#
174
# Since: 1.2
175
##
176
{ 'struct': 'NetdevHubPortOptions',
177
'data': {
178
- 'hubid': 'int32' } }
179
+ 'hubid': 'int32',
180
+ '*netdev': 'str' } }
181
182
##
183
# @NetdevNetmapOptions:
184
diff --git a/qemu-options.hx b/qemu-options.hx
185
index XXXXXXX..XXXXXXX 100644
186
--- a/qemu-options.hx
187
+++ b/qemu-options.hx
188
@@ -XXX,XX +XXX,XX @@ DEF("netdev", HAS_ARG, QEMU_OPTION_netdev,
189
#endif
190
"-netdev vhost-user,id=str,chardev=dev[,vhostforce=on|off]\n"
191
" configure a vhost-user network, backed by a chardev 'dev'\n"
192
- "-netdev hubport,id=str,hubid=n\n"
193
+ "-netdev hubport,id=str,hubid=n[,netdev=nd]\n"
194
" configure a hub port on QEMU VLAN 'n'\n", QEMU_ARCH_ALL)
195
DEF("net", HAS_ARG, QEMU_OPTION_net,
196
"-net nic[,vlan=n][,netdev=nd][,macaddr=mac][,model=type][,name=str][,addr=str][,vectors=v]\n"
197
@@ -XXX,XX +XXX,XX @@ vde_switch -F -sock /tmp/myswitch
198
qemu-system-i386 linux.img -net nic -net vde,sock=/tmp/myswitch
199
@end example
200
201
-@item -netdev hubport,id=@var{id},hubid=@var{hubid}
202
+@item -netdev hubport,id=@var{id},hubid=@var{hubid}[,netdev=@var{nd}]
203
204
Create a hub port on QEMU "vlan" @var{hubid}.
205
206
The hubport netdev lets you connect a NIC to a QEMU "vlan" instead of a single
207
netdev. @code{-net} and @code{-device} with parameter @option{vlan} create the
208
-required hub automatically.
209
+required hub automatically. Alternatively, you can also connect the hubport
210
+to another netdev with ID @var{nd} by using the @option{netdev=@var{nd}}
211
+option.
212
213
@item -netdev vhost-user,chardev=@var{id}[,vhostforce=on|off][,queues=n]
214
49
215
--
50
--
216
2.7.4
51
2.7.4
217
52
218
53
diff view generated by jsdifflib
New patch
1
From: "Rao, Lei" <lei.rao@intel.com>
1
2
3
In COLO mode, if the startup parameters of QEMU include "no-shutdown",
4
QEMU will crash when the guest shutdown. The root cause is when the
5
guest shutdown, the state of VM will switch COLO to SHUTDOWN. When do
6
checkpoint again, the state will be changed to COLO. But the state
7
switch is undefined in runstate_transitions_def, we should add it.
8
This patch fixes the following:
9
qemu-system-x86_64: invalid runstate transition: 'shutdown' -> 'colo'
10
Aborted
11
12
Signed-off-by: Lei Rao <lei.rao@intel.com>
13
Signed-off-by: Zhang Chen <chen.zhang@intel.com>
14
Reviewed-by: Zhang Chen <chen.zhang@intel.com>
15
Signed-off-by: Jason Wang <jasowang@redhat.com>
16
---
17
softmmu/vl.c | 1 +
18
1 file changed, 1 insertion(+)
19
20
diff --git a/softmmu/vl.c b/softmmu/vl.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/softmmu/vl.c
23
+++ b/softmmu/vl.c
24
@@ -XXX,XX +XXX,XX @@ static const RunStateTransition runstate_transitions_def[] = {
25
{ RUN_STATE_SHUTDOWN, RUN_STATE_PAUSED },
26
{ RUN_STATE_SHUTDOWN, RUN_STATE_FINISH_MIGRATE },
27
{ RUN_STATE_SHUTDOWN, RUN_STATE_PRELAUNCH },
28
+ { RUN_STATE_SHUTDOWN, RUN_STATE_COLO },
29
30
{ RUN_STATE_DEBUG, RUN_STATE_SUSPENDED },
31
{ RUN_STATE_RUNNING, RUN_STATE_SUSPENDED },
32
--
33
2.7.4
34
35
diff view generated by jsdifflib
New patch
1
From: Li Zhijian <lizhijian@cn.fujitsu.com>
1
2
3
Fixes: f449c9e549c ("colo: compare the packet based on the tcp sequence
4
number")
5
6
Signed-off-by: Li Zhijian <lizhijian@cn.fujitsu.com>
7
Signed-off-by: Zhang Chen <chen.zhang@intel.com>
8
Reviewed-by: Zhang Chen <chen.zhang@intel.com>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
10
Signed-off-by: Jason Wang <jasowang@redhat.com>
11
---
12
net/colo.c | 5 +----
13
1 file changed, 1 insertion(+), 4 deletions(-)
14
15
diff --git a/net/colo.c b/net/colo.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/net/colo.c
18
+++ b/net/colo.c
19
@@ -XXX,XX +XXX,XX @@ void reverse_connection_key(ConnectionKey *key)
20
21
Connection *connection_new(ConnectionKey *key)
22
{
23
- Connection *conn = g_slice_new(Connection);
24
+ Connection *conn = g_slice_new0(Connection);
25
26
conn->ip_proto = key->ip_proto;
27
conn->processing = false;
28
- conn->offset = 0;
29
conn->tcp_state = TCPS_CLOSED;
30
- conn->pack = 0;
31
- conn->sack = 0;
32
g_queue_init(&conn->primary_list);
33
g_queue_init(&conn->secondary_list);
34
35
--
36
2.7.4
37
38
diff view generated by jsdifflib
New patch
1
From: Li Zhijian <lizhijian@cn.fujitsu.com>
1
2
3
Signed-off-by: Li Zhijian <lizhijian@cn.fujitsu.com>
4
Signed-off-by: Zhang Chen <chen.zhang@intel.com>
5
Reviewed-by: Zhang Chen <chen.zhang@intel.com>
6
Signed-off-by: Jason Wang <jasowang@redhat.com>
7
---
8
net/colo-compare.c | 6 ++----
9
1 file changed, 2 insertions(+), 4 deletions(-)
10
11
diff --git a/net/colo-compare.c b/net/colo-compare.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/net/colo-compare.c
14
+++ b/net/colo-compare.c
15
@@ -XXX,XX +XXX,XX @@ sec:
16
colo_release_primary_pkt(s, ppkt);
17
g_queue_push_head(&conn->secondary_list, spkt);
18
goto pri;
19
- }
20
- if (mark == COLO_COMPARE_FREE_SECONDARY) {
21
+ } else if (mark == COLO_COMPARE_FREE_SECONDARY) {
22
conn->compare_seq = spkt->seq_end;
23
packet_destroy(spkt, NULL);
24
goto sec;
25
- }
26
- if (mark == (COLO_COMPARE_FREE_PRIMARY | COLO_COMPARE_FREE_SECONDARY)) {
27
+ } else if (mark == (COLO_COMPARE_FREE_PRIMARY | COLO_COMPARE_FREE_SECONDARY)) {
28
conn->compare_seq = ppkt->seq_end;
29
colo_release_primary_pkt(s, ppkt);
30
packet_destroy(spkt, NULL);
31
--
32
2.7.4
33
34
diff view generated by jsdifflib
New patch
1
From: Zhang Chen <chen.zhang@intel.com>
1
2
3
This parameter need compare with the return of qemu_clock_get_ms(),
4
it is uint64_t. So we need fix this issue here.
5
6
Fixes: 9cc43c94b31 ("net/colo-compare.c: Expose "compare_timeout" to users")
7
8
Reported-by: Derek Su <dereksu@qnap.com>
9
Signed-off-by: Zhang Chen <chen.zhang@intel.com>
10
Reviewed-by: Li Zhijian <lizhijian@cn.fujitsu.com>
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
12
Signed-off-by: Jason Wang <jasowang@redhat.com>
13
---
14
net/colo-compare.c | 12 ++++++------
15
1 file changed, 6 insertions(+), 6 deletions(-)
16
17
diff --git a/net/colo-compare.c b/net/colo-compare.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/net/colo-compare.c
20
+++ b/net/colo-compare.c
21
@@ -XXX,XX +XXX,XX @@ struct CompareState {
22
SendCo out_sendco;
23
SendCo notify_sendco;
24
bool vnet_hdr;
25
- uint32_t compare_timeout;
26
+ uint64_t compare_timeout;
27
uint32_t expired_scan_cycle;
28
29
/*
30
@@ -XXX,XX +XXX,XX @@ static void compare_get_timeout(Object *obj, Visitor *v,
31
Error **errp)
32
{
33
CompareState *s = COLO_COMPARE(obj);
34
- uint32_t value = s->compare_timeout;
35
+ uint64_t value = s->compare_timeout;
36
37
- visit_type_uint32(v, name, &value, errp);
38
+ visit_type_uint64(v, name, &value, errp);
39
}
40
41
static void compare_set_timeout(Object *obj, Visitor *v,
42
@@ -XXX,XX +XXX,XX @@ static void set_max_queue_size(Object *obj, Visitor *v,
43
Error **errp)
44
{
45
Error *local_err = NULL;
46
- uint32_t value;
47
+ uint64_t value;
48
49
- visit_type_uint32(v, name, &value, &local_err);
50
+ visit_type_uint64(v, name, &value, &local_err);
51
if (local_err) {
52
goto out;
53
}
54
@@ -XXX,XX +XXX,XX @@ static void colo_compare_init(Object *obj)
55
object_property_add_str(obj, "notify_dev",
56
compare_get_notify_dev, compare_set_notify_dev);
57
58
- object_property_add(obj, "compare_timeout", "uint32",
59
+ object_property_add(obj, "compare_timeout", "uint64",
60
compare_get_timeout,
61
compare_set_timeout, NULL, NULL);
62
63
--
64
2.7.4
65
66
diff view generated by jsdifflib
1
From: Mao Zhongyi <maozy.fnst@cn.fujitsu.com>
1
From: Zhang Chen <chen.zhang@intel.com>
2
2
3
Packet size some time different or when network is busy.
3
The virtual clock only runs during the emulation. It stops
4
Based on same payload size, but TCP protocol can not
4
when the virtual machine is stopped.
5
guarantee send the same one packet in the same way,
5
The host clock should be used for device models that emulate accurate
6
real time sources. It will continue to run when the virtual machine
7
is suspended. COLO need to know the host time here.
6
8
7
like that:
9
Fixes: dd321ecfc2e ("colo-compare: Use IOThread to Check old packet
8
We send this payload:
10
regularly and Process packets of the primary")
9
------------------------------
10
| header |1|2|3|4|5|6|7|8|9|0|
11
------------------------------
12
11
13
primary:
12
Reported-by: Derek Su <dereksu@qnap.com>
14
ppkt1:
13
Signed-off-by: Zhang Chen <chen.zhang@intel.com>
15
----------------
14
Reviewed-by: Li Zhijian <lizhijian@cn.fujitsu.com>
16
| header |1|2|3|
15
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
17
----------------
18
ppkt2:
19
------------------------
20
| header |4|5|6|7|8|9|0|
21
------------------------
22
23
secondary:
24
spkt1:
25
------------------------------
26
| header |1|2|3|4|5|6|7|8|9|0|
27
------------------------------
28
29
In the original method, ppkt1 and ppkt2 are different in size and
30
spkt1, so they can't compare and trigger the checkpoint.
31
32
I have tested FTP get 200M and 1G file many times, I found that
33
the performance was less than 1% of the native.
34
35
Now I reconstructed the comparison of TCP packets based on the
36
TCP sequence number. first of all, ppkt1 and spkt1 have the same
37
starting sequence number, so they can compare, even though their
38
length is different. And then ppkt1 with a smaller payload length
39
is used as the comparison length, if the payload is same, send
40
out the ppkt1 and record the offset(the length of ppkt1 payload)
41
in spkt1. The next comparison, ppkt2 and spkt1 can be compared
42
from the recorded position of spkt1.
43
44
like that:
45
----------------
46
| header |1|2|3| ppkt1
47
---------|-----|
48
| |
49
---------v-----v--------------
50
| header |1|2|3|4|5|6|7|8|9|0| spkt1
51
---------------|\------------|
52
| \offset |
53
---------v-------------v
54
| header |4|5|6|7|8|9|0| ppkt2
55
------------------------
56
57
In this way, the performance can reach native 20% in my multiple
58
tests.
59
60
Cc: Zhang Chen <zhangckid@gmail.com>
61
Cc: Li Zhijian <lizhijian@cn.fujitsu.com>
62
Cc: Jason Wang <jasowang@redhat.com>
63
64
Signed-off-by: Mao Zhongyi <maozy.fnst@cn.fujitsu.com>
65
Signed-off-by: Li Zhijian <lizhijian@cn.fujitsu.com>
66
Signed-off-by: Zhang Chen <zhangckid@gmail.com>
67
Reviewed-by: Zhang Chen <zhangckid@gmail.com>
68
Tested-by: Zhang Chen <zhangckid@gmail.com>
69
Signed-off-by: Jason Wang <jasowang@redhat.com>
16
Signed-off-by: Jason Wang <jasowang@redhat.com>
70
---
17
---
71
net/colo-compare.c | 343 +++++++++++++++++++++++++++++++++++------------------
18
net/colo-compare.c | 6 +++---
72
net/colo.c | 9 ++
19
1 file changed, 3 insertions(+), 3 deletions(-)
73
net/colo.h | 15 +++
74
net/trace-events | 2 +-
75
4 files changed, 250 insertions(+), 119 deletions(-)
76
20
77
diff --git a/net/colo-compare.c b/net/colo-compare.c
21
diff --git a/net/colo-compare.c b/net/colo-compare.c
78
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
79
--- a/net/colo-compare.c
23
--- a/net/colo-compare.c
80
+++ b/net/colo-compare.c
24
+++ b/net/colo-compare.c
81
@@ -XXX,XX +XXX,XX @@
25
@@ -XXX,XX +XXX,XX @@ static void check_old_packet_regular(void *opaque)
82
#define COMPARE_READ_LEN_MAX NET_BUFSIZE
26
83
#define MAX_QUEUE_SIZE 1024
27
/* if have old packet we will notify checkpoint */
84
28
colo_old_packet_check(s);
85
+#define COLO_COMPARE_FREE_PRIMARY 0x01
29
- timer_mod(s->packet_check_timer, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) +
86
+#define COLO_COMPARE_FREE_SECONDARY 0x02
30
+ timer_mod(s->packet_check_timer, qemu_clock_get_ms(QEMU_CLOCK_HOST) +
87
+
31
s->expired_scan_cycle);
88
/* TODO: Should be configurable */
89
#define REGULAR_PACKET_CHECK_MS 3000
90
91
@@ -XXX,XX +XXX,XX @@ static gint seq_sorter(Packet *a, Packet *b, gpointer data)
92
return ntohl(atcp->th_seq) - ntohl(btcp->th_seq);
93
}
32
}
94
33
95
+static void fill_pkt_tcp_info(void *data, uint32_t *max_ack)
34
@@ -XXX,XX +XXX,XX @@ static void colo_compare_timer_init(CompareState *s)
96
+{
97
+ Packet *pkt = data;
98
+ struct tcphdr *tcphd;
99
+
100
+ tcphd = (struct tcphdr *)pkt->transport_header;
101
+
102
+ pkt->tcp_seq = ntohl(tcphd->th_seq);
103
+ pkt->tcp_ack = ntohl(tcphd->th_ack);
104
+ *max_ack = *max_ack > pkt->tcp_ack ? *max_ack : pkt->tcp_ack;
105
+ pkt->header_size = pkt->transport_header - (uint8_t *)pkt->data
106
+ + (tcphd->th_off << 2) - pkt->vnet_hdr_len;
107
+ pkt->payload_size = pkt->size - pkt->header_size;
108
+ pkt->seq_end = pkt->tcp_seq + pkt->payload_size;
109
+ pkt->flags = tcphd->th_flags;
110
+}
111
+
112
/*
113
* Return 1 on success, if return 0 means the
114
* packet will be dropped
115
*/
116
-static int colo_insert_packet(GQueue *queue, Packet *pkt)
117
+static int colo_insert_packet(GQueue *queue, Packet *pkt, uint32_t *max_ack)
118
{
35
{
119
if (g_queue_get_length(queue) <= MAX_QUEUE_SIZE) {
36
AioContext *ctx = iothread_get_aio_context(s->iothread);
120
if (pkt->ip->ip_p == IPPROTO_TCP) {
37
121
+ fill_pkt_tcp_info(pkt, max_ack);
38
- s->packet_check_timer = aio_timer_new(ctx, QEMU_CLOCK_VIRTUAL,
122
g_queue_insert_sorted(queue,
39
+ s->packet_check_timer = aio_timer_new(ctx, QEMU_CLOCK_HOST,
123
pkt,
40
SCALE_MS, check_old_packet_regular,
124
(GCompareDataFunc)seq_sorter,
41
s);
125
@@ -XXX,XX +XXX,XX @@ static int packet_enqueue(CompareState *s, int mode, Connection **con)
42
- timer_mod(s->packet_check_timer, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) +
126
}
43
+ timer_mod(s->packet_check_timer, qemu_clock_get_ms(QEMU_CLOCK_HOST) +
127
44
s->expired_scan_cycle);
128
if (mode == PRIMARY_IN) {
129
- if (!colo_insert_packet(&conn->primary_list, pkt)) {
130
+ if (!colo_insert_packet(&conn->primary_list, pkt, &conn->pack)) {
131
error_report("colo compare primary queue size too big,"
132
"drop packet");
133
}
134
} else {
135
- if (!colo_insert_packet(&conn->secondary_list, pkt)) {
136
+ if (!colo_insert_packet(&conn->secondary_list, pkt, &conn->sack)) {
137
error_report("colo compare secondary queue size too big,"
138
"drop packet");
139
}
140
@@ -XXX,XX +XXX,XX @@ static int packet_enqueue(CompareState *s, int mode, Connection **con)
141
return 0;
142
}
45
}
143
46
144
+static inline bool after(uint32_t seq1, uint32_t seq2)
145
+{
146
+ return (int32_t)(seq1 - seq2) > 0;
147
+}
148
+
149
+static void colo_release_primary_pkt(CompareState *s, Packet *pkt)
150
+{
151
+ int ret;
152
+ ret = compare_chr_send(s,
153
+ pkt->data,
154
+ pkt->size,
155
+ pkt->vnet_hdr_len);
156
+ if (ret < 0) {
157
+ error_report("colo send primary packet failed");
158
+ }
159
+ trace_colo_compare_main("packet same and release packet");
160
+ packet_destroy(pkt, NULL);
161
+}
162
+
163
/*
164
* The IP packets sent by primary and secondary
165
* will be compared in here
166
@@ -XXX,XX +XXX,XX @@ static int colo_compare_packet_payload(Packet *ppkt,
167
}
168
169
/*
170
- * Called from the compare thread on the primary
171
- * for compare tcp packet
172
- * compare_tcp copied from Dr. David Alan Gilbert's branch
173
- */
174
-static int colo_packet_compare_tcp(Packet *spkt, Packet *ppkt)
175
+ * return true means that the payload is consist and
176
+ * need to make the next comparison, false means do
177
+ * the checkpoint
178
+*/
179
+static bool colo_mark_tcp_pkt(Packet *ppkt, Packet *spkt,
180
+ int8_t *mark, uint32_t max_ack)
181
{
182
- struct tcphdr *ptcp, *stcp;
183
- int res;
184
+ *mark = 0;
185
+
186
+ if (ppkt->tcp_seq == spkt->tcp_seq && ppkt->seq_end == spkt->seq_end) {
187
+ if (colo_compare_packet_payload(ppkt, spkt,
188
+ ppkt->header_size, spkt->header_size,
189
+ ppkt->payload_size)) {
190
+ *mark = COLO_COMPARE_FREE_SECONDARY | COLO_COMPARE_FREE_PRIMARY;
191
+ return true;
192
+ }
193
+ }
194
+ if (ppkt->tcp_seq == spkt->tcp_seq && ppkt->seq_end == spkt->seq_end) {
195
+ if (colo_compare_packet_payload(ppkt, spkt,
196
+ ppkt->header_size, spkt->header_size,
197
+ ppkt->payload_size)) {
198
+ *mark = COLO_COMPARE_FREE_SECONDARY | COLO_COMPARE_FREE_PRIMARY;
199
+ return true;
200
+ }
201
+ }
202
+
203
+ /* one part of secondary packet payload still need to be compared */
204
+ if (!after(ppkt->seq_end, spkt->seq_end)) {
205
+ if (colo_compare_packet_payload(ppkt, spkt,
206
+ ppkt->header_size + ppkt->offset,
207
+ spkt->header_size + spkt->offset,
208
+ ppkt->payload_size - ppkt->offset)) {
209
+ if (!after(ppkt->tcp_ack, max_ack)) {
210
+ *mark = COLO_COMPARE_FREE_PRIMARY;
211
+ spkt->offset += ppkt->payload_size - ppkt->offset;
212
+ return true;
213
+ } else {
214
+ /* secondary guest hasn't ack the data, don't send
215
+ * out this packet
216
+ */
217
+ return false;
218
+ }
219
+ }
220
+ } else {
221
+ /* primary packet is longer than secondary packet, compare
222
+ * the same part and mark the primary packet offset
223
+ */
224
+ if (colo_compare_packet_payload(ppkt, spkt,
225
+ ppkt->header_size + ppkt->offset,
226
+ spkt->header_size + spkt->offset,
227
+ spkt->payload_size - spkt->offset)) {
228
+ *mark = COLO_COMPARE_FREE_SECONDARY;
229
+ ppkt->offset += spkt->payload_size - spkt->offset;
230
+ return true;
231
+ }
232
+ }
233
234
- trace_colo_compare_main("compare tcp");
235
+ return false;
236
+}
237
238
- ptcp = (struct tcphdr *)ppkt->transport_header;
239
- stcp = (struct tcphdr *)spkt->transport_header;
240
+static void colo_compare_tcp(CompareState *s, Connection *conn)
241
+{
242
+ Packet *ppkt = NULL, *spkt = NULL;
243
+ int8_t mark;
244
245
/*
246
- * The 'identification' field in the IP header is *very* random
247
- * it almost never matches. Fudge this by ignoring differences in
248
- * unfragmented packets; they'll normally sort themselves out if different
249
- * anyway, and it should recover at the TCP level.
250
- * An alternative would be to get both the primary and secondary to rewrite
251
- * somehow; but that would need some sync traffic to sync the state
252
- */
253
- if (ntohs(ppkt->ip->ip_off) & IP_DF) {
254
- spkt->ip->ip_id = ppkt->ip->ip_id;
255
- /* and the sum will be different if the IDs were different */
256
- spkt->ip->ip_sum = ppkt->ip->ip_sum;
257
+ * If ppkt and spkt have the same payload, but ppkt's ACK
258
+ * is greater than spkt's ACK, in this case we can not
259
+ * send the ppkt because it will cause the secondary guest
260
+ * to miss sending some data in the next. Therefore, we
261
+ * record the maximum ACK in the current queue at both
262
+ * primary side and secondary side. Only when the ack is
263
+ * less than the smaller of the two maximum ack, then we
264
+ * can ensure that the packet's payload is acknowledged by
265
+ * primary and secondary.
266
+ */
267
+ uint32_t min_ack = conn->pack > conn->sack ? conn->sack : conn->pack;
268
+
269
+pri:
270
+ if (g_queue_is_empty(&conn->primary_list)) {
271
+ return;
272
}
273
+ ppkt = g_queue_pop_head(&conn->primary_list);
274
+sec:
275
+ if (g_queue_is_empty(&conn->secondary_list)) {
276
+ g_queue_push_head(&conn->primary_list, ppkt);
277
+ return;
278
+ }
279
+ spkt = g_queue_pop_head(&conn->secondary_list);
280
281
- /*
282
- * Check tcp header length for tcp option field.
283
- * th_off > 5 means this tcp packet have options field.
284
- * The tcp options maybe always different.
285
- * for example:
286
- * From RFC 7323.
287
- * TCP Timestamps option (TSopt):
288
- * Kind: 8
289
- *
290
- * Length: 10 bytes
291
- *
292
- * +-------+-------+---------------------+---------------------+
293
- * |Kind=8 | 10 | TS Value (TSval) |TS Echo Reply (TSecr)|
294
- * +-------+-------+---------------------+---------------------+
295
- * 1 1 4 4
296
- *
297
- * In this case the primary guest's timestamp always different with
298
- * the secondary guest's timestamp. COLO just focus on payload,
299
- * so we just need skip this field.
300
- */
301
+ if (ppkt->tcp_seq == ppkt->seq_end) {
302
+ colo_release_primary_pkt(s, ppkt);
303
+ ppkt = NULL;
304
+ }
305
306
- ptrdiff_t ptcp_offset, stcp_offset;
307
+ if (ppkt && conn->compare_seq && !after(ppkt->seq_end, conn->compare_seq)) {
308
+ trace_colo_compare_main("pri: this packet has compared");
309
+ colo_release_primary_pkt(s, ppkt);
310
+ ppkt = NULL;
311
+ }
312
313
- ptcp_offset = ppkt->transport_header - (uint8_t *)ppkt->data
314
- + (ptcp->th_off << 2) - ppkt->vnet_hdr_len;
315
- stcp_offset = spkt->transport_header - (uint8_t *)spkt->data
316
- + (stcp->th_off << 2) - spkt->vnet_hdr_len;
317
- if (ppkt->size - ptcp_offset == spkt->size - stcp_offset) {
318
- res = colo_compare_packet_payload(ppkt, spkt,
319
- ptcp_offset, stcp_offset,
320
- ppkt->size - ptcp_offset);
321
+ if (spkt->tcp_seq == spkt->seq_end) {
322
+ packet_destroy(spkt, NULL);
323
+ if (!ppkt) {
324
+ goto pri;
325
+ } else {
326
+ goto sec;
327
+ }
328
} else {
329
- trace_colo_compare_main("TCP: payload size of packets are different");
330
- res = -1;
331
+ if (conn->compare_seq && !after(spkt->seq_end, conn->compare_seq)) {
332
+ trace_colo_compare_main("sec: this packet has compared");
333
+ packet_destroy(spkt, NULL);
334
+ if (!ppkt) {
335
+ goto pri;
336
+ } else {
337
+ goto sec;
338
+ }
339
+ }
340
+ if (!ppkt) {
341
+ g_queue_push_head(&conn->secondary_list, spkt);
342
+ goto pri;
343
+ }
344
}
345
346
- if (res != 0 &&
347
- trace_event_get_state_backends(TRACE_COLO_COMPARE_MISCOMPARE)) {
348
- char pri_ip_src[20], pri_ip_dst[20], sec_ip_src[20], sec_ip_dst[20];
349
-
350
- strcpy(pri_ip_src, inet_ntoa(ppkt->ip->ip_src));
351
- strcpy(pri_ip_dst, inet_ntoa(ppkt->ip->ip_dst));
352
- strcpy(sec_ip_src, inet_ntoa(spkt->ip->ip_src));
353
- strcpy(sec_ip_dst, inet_ntoa(spkt->ip->ip_dst));
354
-
355
- trace_colo_compare_ip_info(ppkt->size, pri_ip_src,
356
- pri_ip_dst, spkt->size,
357
- sec_ip_src, sec_ip_dst);
358
-
359
- trace_colo_compare_tcp_info("pri tcp packet",
360
- ntohl(ptcp->th_seq),
361
- ntohl(ptcp->th_ack),
362
- res, ptcp->th_flags,
363
- ppkt->size);
364
-
365
- trace_colo_compare_tcp_info("sec tcp packet",
366
- ntohl(stcp->th_seq),
367
- ntohl(stcp->th_ack),
368
- res, stcp->th_flags,
369
- spkt->size);
370
+ if (colo_mark_tcp_pkt(ppkt, spkt, &mark, min_ack)) {
371
+ trace_colo_compare_tcp_info("pri",
372
+ ppkt->tcp_seq, ppkt->tcp_ack,
373
+ ppkt->header_size, ppkt->payload_size,
374
+ ppkt->offset, ppkt->flags);
375
+
376
+ trace_colo_compare_tcp_info("sec",
377
+ spkt->tcp_seq, spkt->tcp_ack,
378
+ spkt->header_size, spkt->payload_size,
379
+ spkt->offset, spkt->flags);
380
+
381
+ if (mark == COLO_COMPARE_FREE_PRIMARY) {
382
+ conn->compare_seq = ppkt->seq_end;
383
+ colo_release_primary_pkt(s, ppkt);
384
+ g_queue_push_head(&conn->secondary_list, spkt);
385
+ goto pri;
386
+ }
387
+ if (mark == COLO_COMPARE_FREE_SECONDARY) {
388
+ conn->compare_seq = spkt->seq_end;
389
+ packet_destroy(spkt, NULL);
390
+ goto sec;
391
+ }
392
+ if (mark == (COLO_COMPARE_FREE_PRIMARY | COLO_COMPARE_FREE_SECONDARY)) {
393
+ conn->compare_seq = ppkt->seq_end;
394
+ colo_release_primary_pkt(s, ppkt);
395
+ packet_destroy(spkt, NULL);
396
+ goto pri;
397
+ }
398
+ } else {
399
+ g_queue_push_head(&conn->primary_list, ppkt);
400
+ g_queue_push_head(&conn->secondary_list, spkt);
401
402
qemu_hexdump((char *)ppkt->data, stderr,
403
"colo-compare ppkt", ppkt->size);
404
qemu_hexdump((char *)spkt->data, stderr,
405
"colo-compare spkt", spkt->size);
406
- }
407
408
- return res;
409
+ /*
410
+ * colo_compare_inconsistent_notify();
411
+ * TODO: notice to checkpoint();
412
+ */
413
+ }
414
}
415
416
+
417
/*
418
* Called from the compare thread on the primary
419
* for compare udp packet
420
@@ -XXX,XX +XXX,XX @@ static void colo_old_packet_check(void *opaque)
421
(GCompareFunc)colo_old_packet_check_one_conn);
422
}
423
424
-/*
425
- * Called from the compare thread on the primary
426
- * for compare packet with secondary list of the
427
- * specified connection when a new packet was
428
- * queued to it.
429
- */
430
-static void colo_compare_connection(void *opaque, void *user_data)
431
+static void colo_compare_packet(CompareState *s, Connection *conn,
432
+ int (*HandlePacket)(Packet *spkt,
433
+ Packet *ppkt))
434
{
435
- CompareState *s = user_data;
436
- Connection *conn = opaque;
437
Packet *pkt = NULL;
438
GList *result = NULL;
439
- int ret;
440
441
while (!g_queue_is_empty(&conn->primary_list) &&
442
!g_queue_is_empty(&conn->secondary_list)) {
443
pkt = g_queue_pop_head(&conn->primary_list);
444
- switch (conn->ip_proto) {
445
- case IPPROTO_TCP:
446
- result = g_queue_find_custom(&conn->secondary_list,
447
- pkt, (GCompareFunc)colo_packet_compare_tcp);
448
- break;
449
- case IPPROTO_UDP:
450
- result = g_queue_find_custom(&conn->secondary_list,
451
- pkt, (GCompareFunc)colo_packet_compare_udp);
452
- break;
453
- case IPPROTO_ICMP:
454
- result = g_queue_find_custom(&conn->secondary_list,
455
- pkt, (GCompareFunc)colo_packet_compare_icmp);
456
- break;
457
- default:
458
- result = g_queue_find_custom(&conn->secondary_list,
459
- pkt, (GCompareFunc)colo_packet_compare_other);
460
- break;
461
- }
462
+ result = g_queue_find_custom(&conn->secondary_list,
463
+ pkt, (GCompareFunc)HandlePacket);
464
465
if (result) {
466
- ret = compare_chr_send(s,
467
- pkt->data,
468
- pkt->size,
469
- pkt->vnet_hdr_len);
470
- if (ret < 0) {
471
- error_report("colo_send_primary_packet failed");
472
- }
473
- trace_colo_compare_main("packet same and release packet");
474
+ colo_release_primary_pkt(s, pkt);
475
g_queue_remove(&conn->secondary_list, result->data);
476
- packet_destroy(pkt, NULL);
477
} else {
478
/*
479
* If one packet arrive late, the secondary_list or
480
@@ -XXX,XX +XXX,XX @@ static void colo_compare_connection(void *opaque, void *user_data)
481
}
482
}
483
484
+/*
485
+ * Called from the compare thread on the primary
486
+ * for compare packet with secondary list of the
487
+ * specified connection when a new packet was
488
+ * queued to it.
489
+ */
490
+static void colo_compare_connection(void *opaque, void *user_data)
491
+{
492
+ CompareState *s = user_data;
493
+ Connection *conn = opaque;
494
+
495
+ switch (conn->ip_proto) {
496
+ case IPPROTO_TCP:
497
+ colo_compare_tcp(s, conn);
498
+ break;
499
+ case IPPROTO_UDP:
500
+ colo_compare_packet(s, conn, colo_packet_compare_udp);
501
+ break;
502
+ case IPPROTO_ICMP:
503
+ colo_compare_packet(s, conn, colo_packet_compare_icmp);
504
+ break;
505
+ default:
506
+ colo_compare_packet(s, conn, colo_packet_compare_other);
507
+ break;
508
+ }
509
+}
510
+
511
static int compare_chr_send(CompareState *s,
512
const uint8_t *buf,
513
uint32_t size,
514
diff --git a/net/colo.c b/net/colo.c
515
index XXXXXXX..XXXXXXX 100644
516
--- a/net/colo.c
517
+++ b/net/colo.c
518
@@ -XXX,XX +XXX,XX @@ Connection *connection_new(ConnectionKey *key)
519
conn->processing = false;
520
conn->offset = 0;
521
conn->syn_flag = 0;
522
+ conn->pack = 0;
523
+ conn->sack = 0;
524
g_queue_init(&conn->primary_list);
525
g_queue_init(&conn->secondary_list);
526
527
@@ -XXX,XX +XXX,XX @@ Packet *packet_new(const void *data, int size, int vnet_hdr_len)
528
pkt->size = size;
529
pkt->creation_ms = qemu_clock_get_ms(QEMU_CLOCK_HOST);
530
pkt->vnet_hdr_len = vnet_hdr_len;
531
+ pkt->tcp_seq = 0;
532
+ pkt->tcp_ack = 0;
533
+ pkt->seq_end = 0;
534
+ pkt->header_size = 0;
535
+ pkt->payload_size = 0;
536
+ pkt->offset = 0;
537
+ pkt->flags = 0;
538
539
return pkt;
540
}
541
diff --git a/net/colo.h b/net/colo.h
542
index XXXXXXX..XXXXXXX 100644
543
--- a/net/colo.h
544
+++ b/net/colo.h
545
@@ -XXX,XX +XXX,XX @@ typedef struct Packet {
546
int64_t creation_ms;
547
/* Get vnet_hdr_len from filter */
548
uint32_t vnet_hdr_len;
549
+ uint32_t tcp_seq; /* sequence number */
550
+ uint32_t tcp_ack; /* acknowledgement number */
551
+ /* the sequence number of the last byte of the packet */
552
+ uint32_t seq_end;
553
+ uint8_t header_size; /* the header length */
554
+ uint16_t payload_size; /* the payload length */
555
+ /* record the payload offset(the length that has been compared) */
556
+ uint16_t offset;
557
+ uint8_t flags; /* Flags(aka Control bits) */
558
} Packet;
559
560
typedef struct ConnectionKey {
561
@@ -XXX,XX +XXX,XX @@ typedef struct Connection {
562
/* flag to enqueue unprocessed_connections */
563
bool processing;
564
uint8_t ip_proto;
565
+ /* record the sequence number that has been compared */
566
+ uint32_t compare_seq;
567
+ /* the maximum of acknowledgement number in primary_list queue */
568
+ uint32_t pack;
569
+ /* the maximum of acknowledgement number in secondary_list queue */
570
+ uint32_t sack;
571
/* offset = secondary_seq - primary_seq */
572
tcp_seq offset;
573
/*
574
diff --git a/net/trace-events b/net/trace-events
575
index XXXXXXX..XXXXXXX 100644
576
--- a/net/trace-events
577
+++ b/net/trace-events
578
@@ -XXX,XX +XXX,XX @@ colo_compare_icmp_miscompare(const char *sta, int size) ": %s = %d"
579
colo_compare_ip_info(int psize, const char *sta, const char *stb, int ssize, const char *stc, const char *std) "ppkt size = %d, ip_src = %s, ip_dst = %s, spkt size = %d, ip_src = %s, ip_dst = %s"
580
colo_old_packet_check_found(int64_t old_time) "%" PRId64
581
colo_compare_miscompare(void) ""
582
-colo_compare_tcp_info(const char *pkt, uint32_t seq, uint32_t ack, int res, uint32_t flag, int size) "side: %s seq/ack= %u/%u res= %d flags= 0x%x pkt_size: %d\n"
583
+colo_compare_tcp_info(const char *pkt, uint32_t seq, uint32_t ack, int hdlen, int pdlen, int offset, int flags) "%s: seq/ack= %u/%u hdlen= %d pdlen= %d offset= %d flags=%d\n"
584
585
# net/filter-rewriter.c
586
colo_filter_rewriter_debug(void) ""
587
--
47
--
588
2.7.4
48
2.7.4
589
49
590
50
diff view generated by jsdifflib
1
From: Mao Zhongyi <maozy.fnst@cn.fujitsu.com>
1
From: Zhang Chen <chen.zhang@intel.com>
2
2
3
Modified the function colo_packet_compare_common to prepare for the
3
Detect queued secondary packet to sync VM state in time.
4
tcp packet comparison in the next patch.
5
4
6
Cc: Zhang Chen <zhangckid@gmail.com>
5
Signed-off-by: Zhang Chen <chen.zhang@intel.com>
7
Cc: Li Zhijian <lizhijian@cn.fujitsu.com>
6
Reviewed-by: Li Zhijian <lizhijian@cn.fujitsu.com>
8
Cc: Jason Wang <jasowang@redhat.com>
9
10
Signed-off-by: Mao Zhongyi <maozy.fnst@cn.fujitsu.com>
11
Signed-off-by: Li Zhijian <lizhijian@cn.fujitsu.com>
12
Signed-off-by: Zhang Chen <zhangckid@gmail.com>
13
Reviewed-by: Zhang Chen <zhangckid@gmail.com>
14
Signed-off-by: Jason Wang <jasowang@redhat.com>
7
Signed-off-by: Jason Wang <jasowang@redhat.com>
15
---
8
---
16
net/colo-compare.c | 88 +++++++++++++++++++++++++++---------------------------
9
net/colo-compare.c | 25 ++++++++++++++++---------
17
1 file changed, 44 insertions(+), 44 deletions(-)
10
1 file changed, 16 insertions(+), 9 deletions(-)
18
11
19
diff --git a/net/colo-compare.c b/net/colo-compare.c
12
diff --git a/net/colo-compare.c b/net/colo-compare.c
20
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
21
--- a/net/colo-compare.c
14
--- a/net/colo-compare.c
22
+++ b/net/colo-compare.c
15
+++ b/net/colo-compare.c
23
@@ -XXX,XX +XXX,XX @@ static int packet_enqueue(CompareState *s, int mode, Connection **con)
16
@@ -XXX,XX +XXX,XX @@ void colo_compare_unregister_notifier(Notifier *notify)
24
* return: 0 means packet same
17
static int colo_old_packet_check_one_conn(Connection *conn,
25
* > 0 || < 0 means packet different
18
CompareState *s)
26
*/
19
{
27
-static int colo_packet_compare_common(Packet *ppkt,
20
- GList *result = NULL;
28
- Packet *spkt,
21
-
29
- int poffset,
22
- result = g_queue_find_custom(&conn->primary_list,
30
- int soffset)
23
- &s->compare_timeout,
31
+static int colo_compare_packet_payload(Packet *ppkt,
24
- (GCompareFunc)colo_old_packet_check_one);
32
+ Packet *spkt,
25
+ if (!g_queue_is_empty(&conn->primary_list)) {
33
+ uint16_t poffset,
26
+ if (g_queue_find_custom(&conn->primary_list,
34
+ uint16_t soffset,
27
+ &s->compare_timeout,
35
+ uint16_t len)
28
+ (GCompareFunc)colo_old_packet_check_one))
29
+ goto out;
30
+ }
31
32
- if (result) {
33
- /* Do checkpoint will flush old packet */
34
- colo_compare_inconsistency_notify(s);
35
- return 0;
36
+ if (!g_queue_is_empty(&conn->secondary_list)) {
37
+ if (g_queue_find_custom(&conn->secondary_list,
38
+ &s->compare_timeout,
39
+ (GCompareFunc)colo_old_packet_check_one))
40
+ goto out;
41
}
42
43
return 1;
36
+
44
+
37
{
45
+out:
38
if (trace_event_get_state_backends(TRACE_COLO_COMPARE_MISCOMPARE)) {
46
+ /* Do checkpoint will flush old packet */
39
char pri_ip_src[20], pri_ip_dst[20], sec_ip_src[20], sec_ip_dst[20];
47
+ colo_compare_inconsistency_notify(s);
40
@@ -XXX,XX +XXX,XX @@ static int colo_packet_compare_common(Packet *ppkt,
48
+ return 0;
41
sec_ip_src, sec_ip_dst);
42
}
43
44
- poffset = ppkt->vnet_hdr_len + poffset;
45
- soffset = ppkt->vnet_hdr_len + soffset;
46
-
47
- if (ppkt->size - poffset == spkt->size - soffset) {
48
- return memcmp(ppkt->data + poffset,
49
- spkt->data + soffset,
50
- spkt->size - soffset);
51
- } else {
52
- trace_colo_compare_main("Net packet size are not the same");
53
- return -1;
54
- }
55
+ return memcmp(ppkt->data + poffset, spkt->data + soffset, len);
56
}
49
}
57
50
58
/*
51
/*
59
@@ -XXX,XX +XXX,XX @@ static int colo_packet_compare_tcp(Packet *spkt, Packet *ppkt)
60
* the secondary guest's timestamp. COLO just focus on payload,
61
* so we just need skip this field.
62
*/
63
- if (ptcp->th_off > 5) {
64
- ptrdiff_t ptcp_offset, stcp_offset;
65
66
- ptcp_offset = ppkt->transport_header - (uint8_t *)ppkt->data
67
- + (ptcp->th_off * 4) - ppkt->vnet_hdr_len;
68
- stcp_offset = spkt->transport_header - (uint8_t *)spkt->data
69
- + (stcp->th_off * 4) - spkt->vnet_hdr_len;
70
+ ptrdiff_t ptcp_offset, stcp_offset;
71
72
- /*
73
- * When network is busy, some tcp options(like sack) will unpredictable
74
- * occur in primary side or secondary side. it will make packet size
75
- * not same, but the two packet's payload is identical. colo just
76
- * care about packet payload, so we skip the option field.
77
- */
78
- res = colo_packet_compare_common(ppkt, spkt, ptcp_offset, stcp_offset);
79
- } else if (ptcp->th_sum == stcp->th_sum) {
80
- res = colo_packet_compare_common(ppkt, spkt, ETH_HLEN, ETH_HLEN);
81
+ ptcp_offset = ppkt->transport_header - (uint8_t *)ppkt->data
82
+ + (ptcp->th_off << 2) - ppkt->vnet_hdr_len;
83
+ stcp_offset = spkt->transport_header - (uint8_t *)spkt->data
84
+ + (stcp->th_off << 2) - spkt->vnet_hdr_len;
85
+ if (ppkt->size - ptcp_offset == spkt->size - stcp_offset) {
86
+ res = colo_compare_packet_payload(ppkt, spkt,
87
+ ptcp_offset, stcp_offset,
88
+ ppkt->size - ptcp_offset);
89
} else {
90
+ trace_colo_compare_main("TCP: payload size of packets are different");
91
res = -1;
92
}
93
94
@@ -XXX,XX +XXX,XX @@ static int colo_packet_compare_tcp(Packet *spkt, Packet *ppkt)
95
*/
96
static int colo_packet_compare_udp(Packet *spkt, Packet *ppkt)
97
{
98
- int ret;
99
- int network_header_length = ppkt->ip->ip_hl * 4;
100
+ uint16_t network_header_length = ppkt->ip->ip_hl << 2;
101
+ uint16_t offset = network_header_length + ETH_HLEN + ppkt->vnet_hdr_len;
102
103
trace_colo_compare_main("compare udp");
104
105
@@ -XXX,XX +XXX,XX @@ static int colo_packet_compare_udp(Packet *spkt, Packet *ppkt)
106
* other field like TOS,TTL,IP Checksum. we only need to compare
107
* the ip payload here.
108
*/
109
- ret = colo_packet_compare_common(ppkt, spkt,
110
- network_header_length + ETH_HLEN,
111
- network_header_length + ETH_HLEN);
112
-
113
- if (ret) {
114
+ if (ppkt->size != spkt->size) {
115
+ trace_colo_compare_main("UDP: payload size of packets are different");
116
+ return -1;
117
+ }
118
+ if (colo_compare_packet_payload(ppkt, spkt, offset, offset,
119
+ ppkt->size - offset)) {
120
trace_colo_compare_udp_miscompare("primary pkt size", ppkt->size);
121
trace_colo_compare_udp_miscompare("Secondary pkt size", spkt->size);
122
if (trace_event_get_state_backends(TRACE_COLO_COMPARE_MISCOMPARE)) {
123
@@ -XXX,XX +XXX,XX @@ static int colo_packet_compare_udp(Packet *spkt, Packet *ppkt)
124
qemu_hexdump((char *)spkt->data, stderr, "colo-compare sec pkt",
125
spkt->size);
126
}
127
+ return -1;
128
+ } else {
129
+ return 0;
130
}
131
-
132
- return ret;
133
}
134
135
/*
136
@@ -XXX,XX +XXX,XX @@ static int colo_packet_compare_udp(Packet *spkt, Packet *ppkt)
137
*/
138
static int colo_packet_compare_icmp(Packet *spkt, Packet *ppkt)
139
{
140
- int network_header_length = ppkt->ip->ip_hl * 4;
141
+ uint16_t network_header_length = ppkt->ip->ip_hl << 2;
142
+ uint16_t offset = network_header_length + ETH_HLEN + ppkt->vnet_hdr_len;
143
144
trace_colo_compare_main("compare icmp");
145
146
@@ -XXX,XX +XXX,XX @@ static int colo_packet_compare_icmp(Packet *spkt, Packet *ppkt)
147
* other field like TOS,TTL,IP Checksum. we only need to compare
148
* the ip payload here.
149
*/
150
- if (colo_packet_compare_common(ppkt, spkt,
151
- network_header_length + ETH_HLEN,
152
- network_header_length + ETH_HLEN)) {
153
+ if (ppkt->size != spkt->size) {
154
+ trace_colo_compare_main("ICMP: payload size of packets are different");
155
+ return -1;
156
+ }
157
+ if (colo_compare_packet_payload(ppkt, spkt, offset, offset,
158
+ ppkt->size - offset)) {
159
trace_colo_compare_icmp_miscompare("primary pkt size",
160
ppkt->size);
161
trace_colo_compare_icmp_miscompare("Secondary pkt size",
162
@@ -XXX,XX +XXX,XX @@ static int colo_packet_compare_icmp(Packet *spkt, Packet *ppkt)
163
*/
164
static int colo_packet_compare_other(Packet *spkt, Packet *ppkt)
165
{
166
+ uint16_t offset = ppkt->vnet_hdr_len;
167
+
168
trace_colo_compare_main("compare other");
169
if (trace_event_get_state_backends(TRACE_COLO_COMPARE_MISCOMPARE)) {
170
char pri_ip_src[20], pri_ip_dst[20], sec_ip_src[20], sec_ip_dst[20];
171
@@ -XXX,XX +XXX,XX @@ static int colo_packet_compare_other(Packet *spkt, Packet *ppkt)
172
sec_ip_src, sec_ip_dst);
173
}
174
175
- return colo_packet_compare_common(ppkt, spkt, 0, 0);
176
+ if (ppkt->size != spkt->size) {
177
+ trace_colo_compare_main("Other: payload size of packets are different");
178
+ return -1;
179
+ }
180
+ return colo_compare_packet_payload(ppkt, spkt, offset, offset,
181
+ ppkt->size - offset);
182
}
183
184
static int colo_old_packet_check_one(Packet *pkt, int64_t *check_time)
185
--
52
--
186
2.7.4
53
2.7.4
187
54
188
55
diff view generated by jsdifflib
New patch
1
From: Zhang Chen <chen.zhang@intel.com>
1
2
3
In my test, use this default parameter looks better.
4
5
Signed-off-by: Zhang Chen <chen.zhang@intel.com>
6
Signed-off-by: Jason Wang <jasowang@redhat.com>
7
---
8
net/colo-compare.c | 2 +-
9
1 file changed, 1 insertion(+), 1 deletion(-)
10
11
diff --git a/net/colo-compare.c b/net/colo-compare.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/net/colo-compare.c
14
+++ b/net/colo-compare.c
15
@@ -XXX,XX +XXX,XX @@ static NotifierList colo_compare_notifiers =
16
#define COLO_COMPARE_FREE_PRIMARY 0x01
17
#define COLO_COMPARE_FREE_SECONDARY 0x02
18
19
-#define REGULAR_PACKET_CHECK_MS 3000
20
+#define REGULAR_PACKET_CHECK_MS 1000
21
#define DEFAULT_TIME_OUT_MS 3000
22
23
/* #define DEBUG_COLO_PACKETS */
24
--
25
2.7.4
26
27
diff view generated by jsdifflib
New patch
1
From: Prasad J Pandit <pjp@fedoraproject.org>
1
2
3
eth_get_gso_type() routine returns segmentation offload type based on
4
L3 protocol type. It calls g_assert_not_reached if L3 protocol is
5
unknown, making the following return statement unreachable. Remove the
6
g_assert call, it maybe triggered by a guest user.
7
8
Reported-by: Gaoning Pan <pgn@zju.edu.cn>
9
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
10
Signed-off-by: Jason Wang <jasowang@redhat.com>
11
---
12
net/eth.c | 6 +++---
13
1 file changed, 3 insertions(+), 3 deletions(-)
14
15
diff --git a/net/eth.c b/net/eth.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/net/eth.c
18
+++ b/net/eth.c
19
@@ -XXX,XX +XXX,XX @@
20
*/
21
22
#include "qemu/osdep.h"
23
+#include "qemu/log.h"
24
#include "net/eth.h"
25
#include "net/checksum.h"
26
#include "net/tap.h"
27
@@ -XXX,XX +XXX,XX @@ eth_get_gso_type(uint16_t l3_proto, uint8_t *l3_hdr, uint8_t l4proto)
28
return VIRTIO_NET_HDR_GSO_TCPV6 | ecn_state;
29
}
30
}
31
-
32
- /* Unsupported offload */
33
- g_assert_not_reached();
34
+ qemu_log_mask(LOG_UNIMP, "%s: probably not GSO frame, "
35
+ "unknown L3 protocol: 0x%04"PRIx16"\n", __func__, l3_proto);
36
37
return VIRTIO_NET_HDR_GSO_NONE | ecn_state;
38
}
39
--
40
2.7.4
41
42
diff view generated by jsdifflib
New patch
1
From: AlexChen <alex.chen@huawei.com>
1
2
3
The result has been checked to be NULL before, it cannot be NULL here,
4
so the check is redundant. Remove it.
5
6
Reported-by: Euler Robot <euler.robot@huawei.com>
7
Signed-off-by: AlexChen <alex.chen@huawei.com>
8
Signed-off-by: Jason Wang <jasowang@redhat.com>
9
---
10
net/l2tpv3.c | 9 +++------
11
1 file changed, 3 insertions(+), 6 deletions(-)
12
13
diff --git a/net/l2tpv3.c b/net/l2tpv3.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/net/l2tpv3.c
16
+++ b/net/l2tpv3.c
17
@@ -XXX,XX +XXX,XX @@ int net_init_l2tpv3(const Netdev *netdev,
18
error_setg(errp, "could not bind socket err=%i", errno);
19
goto outerr;
20
}
21
- if (result) {
22
- freeaddrinfo(result);
23
- }
24
+
25
+ freeaddrinfo(result);
26
27
memset(&hints, 0, sizeof(hints));
28
29
@@ -XXX,XX +XXX,XX @@ int net_init_l2tpv3(const Netdev *netdev,
30
memcpy(s->dgram_dst, result->ai_addr, result->ai_addrlen);
31
s->dst_size = result->ai_addrlen;
32
33
- if (result) {
34
- freeaddrinfo(result);
35
- }
36
+ freeaddrinfo(result);
37
38
if (l2tpv3->has_counter && l2tpv3->counter) {
39
s->has_counter = true;
40
--
41
2.7.4
42
43
diff view generated by jsdifflib
New patch
1
From: Peter Maydell <peter.maydell@linaro.org>
1
2
3
The ctucan device has 4 CAN bus cores, each of which has a set of 20
4
32-bit registers for writing the transmitted data. The registers are
5
however not contiguous; each core's buffers is 0x100 bytes after
6
the last.
7
8
We got the checks on the address wrong in the ctucan_mem_write()
9
function:
10
* the first "is addr in range at all" check allowed
11
addr == CTUCAN_CORE_MEM_SIZE, which is actually the first
12
byte off the end of the range
13
* the decode of addresses into core-number plus offset in the
14
tx buffer for that core failed to check that the offset was
15
in range, so the guest could write off the end of the
16
tx_buffer[] array
17
18
NB: currently the values of CTUCAN_CORE_MEM_SIZE, CTUCAN_CORE_TXBUF_NUM,
19
etc, make "buff_num >= CTUCAN_CORE_TXBUF_NUM" impossible, but we
20
retain this as a runtime check rather than an assertion to permit
21
those values to be changed in future (in hardware they are
22
configurable synthesis parameters).
23
24
Fix the top level check, and check the offset is within the buffer.
25
26
Fixes: Coverity CID 1432874
27
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
28
Signed-off-by: Pavel Pisa <pisa@cmp.felk.cvut.cz>
29
Tested-by: Pavel Pisa <pisa@cmp.felk.cvut.cz>
30
Signed-off-by: Jason Wang <jasowang@redhat.com>
31
---
32
hw/net/can/ctucan_core.c | 6 ++++--
33
1 file changed, 4 insertions(+), 2 deletions(-)
34
35
diff --git a/hw/net/can/ctucan_core.c b/hw/net/can/ctucan_core.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/hw/net/can/ctucan_core.c
38
+++ b/hw/net/can/ctucan_core.c
39
@@ -XXX,XX +XXX,XX @@ void ctucan_mem_write(CtuCanCoreState *s, hwaddr addr, uint64_t val,
40
DPRINTF("write 0x%02llx addr 0x%02x\n",
41
(unsigned long long)val, (unsigned int)addr);
42
43
- if (addr > CTUCAN_CORE_MEM_SIZE) {
44
+ if (addr >= CTUCAN_CORE_MEM_SIZE) {
45
return;
46
}
47
48
@@ -XXX,XX +XXX,XX @@ void ctucan_mem_write(CtuCanCoreState *s, hwaddr addr, uint64_t val,
49
addr -= CTU_CAN_FD_TXTB1_DATA_1;
50
buff_num = addr / CTUCAN_CORE_TXBUFF_SPAN;
51
addr %= CTUCAN_CORE_TXBUFF_SPAN;
52
- if (buff_num < CTUCAN_CORE_TXBUF_NUM) {
53
+ addr &= ~3;
54
+ if ((buff_num < CTUCAN_CORE_TXBUF_NUM) &&
55
+ (addr < sizeof(s->tx_buffer[buff_num].data))) {
56
uint32_t *bufp = (uint32_t *)(s->tx_buffer[buff_num].data + addr);
57
*bufp = cpu_to_le32(val);
58
}
59
--
60
2.7.4
61
62
diff view generated by jsdifflib
1
From: Thomas Huth <thuth@redhat.com>
1
From: Peter Maydell <peter.maydell@linaro.org>
2
2
3
It does not make much sense to limit these commands to the legacy 'vlan'
3
Coverity points out that in ctucan_send_ready_buffers() we
4
concept only, they should work with the modern netdevs, too. So now
4
set buff_st_mask = 0xf << (i * 4) inside the loop, but then
5
it is possible to use this command with one, two or three parameters.
5
we never use it before overwriting it later.
6
6
7
With one parameter, the command installs a hostfwd rule on the default
7
The only thing we use the mask for is as part of the code that is
8
"user" network:
8
inserting the new buff_st field into tx_status. That is more
9
hostfwd_add tcp:...
9
comprehensibly written using deposit32(), so do that and drop the
10
mask variable entirely.
10
11
11
With two parameters, the command installs a hostfwd rule on a netdev
12
We also update the buff_st local variable at multiple points
12
(that's the new way of using this command):
13
during this function, but nothing can ever see these
13
hostfwd_add netdev_id tcp:...
14
intermediate values, so just drop those, write the final
15
TXT_TOK as a fixed constant value, and collapse the only
16
remaining set/use of buff_st down into an extract32().
14
17
15
With three parameters, the command installs a rule on a 'vlan' (aka hub):
18
Fixes: Coverity CID 1432869
16
hostfwd_add hub_id name tcp:...
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
20
Acked-by: Pavel Pisa <pisa@cmp.felk.cvut.cz>
18
Same applies to the hostfwd_remove command now.
21
Tested-by: Pavel Pisa <pisa@cmp.felk.cvut.cz>
19
20
Signed-off-by: Thomas Huth <thuth@redhat.com>
21
Signed-off-by: Jason Wang <jasowang@redhat.com>
22
Signed-off-by: Jason Wang <jasowang@redhat.com>
22
---
23
---
23
hmp-commands.hx | 4 ++--
24
hw/net/can/ctucan_core.c | 15 +++------------
24
net/slirp.c | 33 +++++++++++++++++++++++----------
25
1 file changed, 3 insertions(+), 12 deletions(-)
25
2 files changed, 25 insertions(+), 12 deletions(-)
26
26
27
diff --git a/hmp-commands.hx b/hmp-commands.hx
27
diff --git a/hw/net/can/ctucan_core.c b/hw/net/can/ctucan_core.c
28
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
29
--- a/hmp-commands.hx
29
--- a/hw/net/can/ctucan_core.c
30
+++ b/hmp-commands.hx
30
+++ b/hw/net/can/ctucan_core.c
31
@@ -XXX,XX +XXX,XX @@ ETEXI
31
@@ -XXX,XX +XXX,XX @@ static void ctucan_send_ready_buffers(CtuCanCoreState *s)
32
{
32
uint8_t *pf;
33
.name = "hostfwd_add",
33
int buff2tx_idx;
34
.args_type = "arg1:s,arg2:s?,arg3:s?",
34
uint32_t tx_prio_max;
35
- .params = "[vlan_id name] [tcp|udp]:[hostaddr]:hostport-[guestaddr]:guestport",
35
- unsigned int buff_st;
36
+ .params = "[hub_id name]|[netdev_id] [tcp|udp]:[hostaddr]:hostport-[guestaddr]:guestport",
36
- uint32_t buff_st_mask;
37
.help = "redirect TCP or UDP connections from host to guest (requires -net user)",
37
38
.cmd = hmp_hostfwd_add,
38
if (!s->mode_settings.s.ena) {
39
},
39
return;
40
@@ -XXX,XX +XXX,XX @@ ETEXI
40
@@ -XXX,XX +XXX,XX @@ static void ctucan_send_ready_buffers(CtuCanCoreState *s)
41
{
41
for (i = 0; i < CTUCAN_CORE_TXBUF_NUM; i++) {
42
.name = "hostfwd_remove",
42
uint32_t prio;
43
.args_type = "arg1:s,arg2:s?,arg3:s?",
43
44
- .params = "[vlan_id name] [tcp|udp]:[hostaddr]:hostport",
44
- buff_st_mask = 0xf << (i * 4);
45
+ .params = "[hub_id name]|[netdev_id] [tcp|udp]:[hostaddr]:hostport",
45
- buff_st = (s->tx_status.u32 >> (i * 4)) & 0xf;
46
.help = "remove host-to-guest TCP or UDP redirection",
46
-
47
.cmd = hmp_hostfwd_remove,
47
- if (buff_st != TXT_RDY) {
48
},
48
+ if (extract32(s->tx_status.u32, i * 4, 4) != TXT_RDY) {
49
diff --git a/net/slirp.c b/net/slirp.c
49
continue;
50
index XXXXXXX..XXXXXXX 100644
50
}
51
--- a/net/slirp.c
51
prio = (s->tx_priority.u32 >> (i * 4)) & 0x7;
52
+++ b/net/slirp.c
52
@@ -XXX,XX +XXX,XX @@ static void ctucan_send_ready_buffers(CtuCanCoreState *s)
53
@@ -XXX,XX +XXX,XX @@ error:
53
if (buff2tx_idx == -1) {
54
return -1;
54
break;
55
}
56
- buff_st_mask = 0xf << (buff2tx_idx * 4);
57
- buff_st = (s->tx_status.u32 >> (buff2tx_idx * 4)) & 0xf;
58
int_stat.u32 = 0;
59
- buff_st = TXT_RDY;
60
pf = s->tx_buffer[buff2tx_idx].data;
61
ctucan_buff2frame(pf, &frame);
62
s->status.s.idle = 0;
63
@@ -XXX,XX +XXX,XX @@ static void ctucan_send_ready_buffers(CtuCanCoreState *s)
64
s->status.s.idle = 1;
65
s->status.s.txs = 0;
66
s->tx_fr_ctr.s.tx_fr_ctr_val++;
67
- buff_st = TXT_TOK;
68
int_stat.s.txi = 1;
69
int_stat.s.txbhci = 1;
70
s->int_stat.u32 |= int_stat.u32 & ~s->int_mask.u32;
71
- s->tx_status.u32 = (s->tx_status.u32 & ~buff_st_mask) |
72
- (buff_st << (buff2tx_idx * 4));
73
+ s->tx_status.u32 = deposit32(s->tx_status.u32,
74
+ buff2tx_idx * 4, 4, TXT_TOK);
75
} while (1);
55
}
76
}
56
77
57
-static SlirpState *slirp_lookup(Monitor *mon, const char *vlan,
58
- const char *stack)
59
+static SlirpState *slirp_lookup(Monitor *mon, const char *hub_id,
60
+ const char *name)
61
{
62
-
63
- if (vlan) {
64
+ if (name) {
65
NetClientState *nc;
66
- nc = net_hub_find_client_by_name(strtol(vlan, NULL, 0), stack);
67
- if (!nc) {
68
- monitor_printf(mon, "unrecognized (vlan-id, stackname) pair\n");
69
- return NULL;
70
+ if (hub_id) {
71
+ nc = net_hub_find_client_by_name(strtol(hub_id, NULL, 0), name);
72
+ if (!nc) {
73
+ monitor_printf(mon, "unrecognized (vlan-id, stackname) pair\n");
74
+ return NULL;
75
+ }
76
+ } else {
77
+ nc = qemu_find_netdev(name);
78
+ if (!nc) {
79
+ monitor_printf(mon, "unrecognized netdev id '%s'\n", name);
80
+ return NULL;
81
+ }
82
}
83
if (strcmp(nc->model, "user")) {
84
monitor_printf(mon, "invalid device specified\n");
85
@@ -XXX,XX +XXX,XX @@ void hmp_hostfwd_remove(Monitor *mon, const QDict *qdict)
86
const char *arg2 = qdict_get_try_str(qdict, "arg2");
87
const char *arg3 = qdict_get_try_str(qdict, "arg3");
88
89
- if (arg2) {
90
+ if (arg3) {
91
s = slirp_lookup(mon, arg1, arg2);
92
src_str = arg3;
93
+ } else if (arg2) {
94
+ s = slirp_lookup(mon, NULL, arg1);
95
+ src_str = arg2;
96
} else {
97
s = slirp_lookup(mon, NULL, NULL);
98
src_str = arg1;
99
@@ -XXX,XX +XXX,XX @@ void hmp_hostfwd_add(Monitor *mon, const QDict *qdict)
100
const char *arg2 = qdict_get_try_str(qdict, "arg2");
101
const char *arg3 = qdict_get_try_str(qdict, "arg3");
102
103
- if (arg2) {
104
+ if (arg3) {
105
s = slirp_lookup(mon, arg1, arg2);
106
redir_str = arg3;
107
+ } else if (arg2) {
108
+ s = slirp_lookup(mon, NULL, arg1);
109
+ redir_str = arg2;
110
} else {
111
s = slirp_lookup(mon, NULL, NULL);
112
redir_str = arg1;
113
--
78
--
114
2.7.4
79
2.7.4
115
80
116
81
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Peter Maydell <peter.maydell@linaro.org>
2
2
3
gently asked by his automatic reply :)
3
The ctucan driver defines types for its registers which are a union
4
of a uint32_t with a struct with bitfields for the individual
5
fields within that register. This is a bad idea, because bitfields
6
aren't portable. The ctu_can_fd_regs.h header works around the
7
most glaring of the portability issues by defining the
8
fields in two different orders depending on the setting of the
9
__LITTLE_ENDIAN_BITFIELD define. However, in ctucan_core.h this
10
is unconditionally set to 1, which is wrong for big-endian hosts.
4
11
5
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
Set it only if HOST_WORDS_BIGENDIAN is not set. There is no need
13
for a "have we defined it already" guard, because the only place
14
that should set it is ctucan_core.h, which has the usual
15
double-inclusion guard.
16
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
19
Acked-by: Pavel Pisa <pisa@cmp.felk.cvut.cz>
20
Tested-by: Pavel Pisa <pisa@cmp.felk.cvut.cz>
6
Signed-off-by: Jason Wang <jasowang@redhat.com>
21
Signed-off-by: Jason Wang <jasowang@redhat.com>
7
---
22
---
8
MAINTAINERS | 8 ++++----
23
hw/net/can/ctucan_core.h | 3 +--
9
1 file changed, 4 insertions(+), 4 deletions(-)
24
1 file changed, 1 insertion(+), 2 deletions(-)
10
25
11
diff --git a/MAINTAINERS b/MAINTAINERS
26
diff --git a/hw/net/can/ctucan_core.h b/hw/net/can/ctucan_core.h
12
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
13
--- a/MAINTAINERS
28
--- a/hw/net/can/ctucan_core.h
14
+++ b/MAINTAINERS
29
+++ b/hw/net/can/ctucan_core.h
15
@@ -XXX,XX +XXX,XX @@ F: hw/scsi/mfi.h
30
@@ -XXX,XX +XXX,XX @@
16
F: tests/megasas-test.c
31
#include "exec/hwaddr.h"
17
32
#include "net/can_emu.h"
18
Network packet abstractions
33
19
-M: Dmitry Fleytman <dmitry@daynix.com>
34
-
20
+M: Dmitry Fleytman <dmitry.fleytman@gmail.com>
35
-#ifndef __LITTLE_ENDIAN_BITFIELD
21
S: Maintained
36
+#ifndef HOST_WORDS_BIGENDIAN
22
F: include/net/eth.h
37
#define __LITTLE_ENDIAN_BITFIELD 1
23
F: net/eth.c
38
#endif
24
@@ -XXX,XX +XXX,XX @@ F: hw/net/net_rx_pkt*
25
F: hw/net/net_tx_pkt*
26
27
Vmware
28
-M: Dmitry Fleytman <dmitry@daynix.com>
29
+M: Dmitry Fleytman <dmitry.fleytman@gmail.com>
30
S: Maintained
31
F: hw/net/vmxnet*
32
F: hw/scsi/vmw_pvscsi*
33
@@ -XXX,XX +XXX,XX @@ F: hw/mem/nvdimm.c
34
F: include/hw/mem/nvdimm.h
35
36
e1000x
37
-M: Dmitry Fleytman <dmitry@daynix.com>
38
+M: Dmitry Fleytman <dmitry.fleytman@gmail.com>
39
S: Maintained
40
F: hw/net/e1000x*
41
42
e1000e
43
-M: Dmitry Fleytman <dmitry@daynix.com>
44
+M: Dmitry Fleytman <dmitry.fleytman@gmail.com>
45
S: Maintained
46
F: hw/net/e1000e*
47
39
48
--
40
--
49
2.7.4
41
2.7.4
50
42
51
43
diff view generated by jsdifflib
1
From: Thomas Huth <thuth@redhat.com>
1
From: Peter Maydell <peter.maydell@linaro.org>
2
2
3
The vlan concept is marked as deprecated, so we should not use
3
Instead of casting an address within a uint8_t array to a
4
this for examples in the documentation anymore.
4
uint32_t*, use stl_le_p(). This handles possibly misaligned
5
addresses which would otherwise crash on some hosts.
5
6
6
Signed-off-by: Thomas Huth <thuth@redhat.com>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Signed-off-by: Pavel Pisa <pisa@cmp.felk.cvut.cz>
10
Tested-by: Pavel Pisa <pisa@cmp.felk.cvut.cz>
7
Signed-off-by: Jason Wang <jasowang@redhat.com>
11
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
---
12
---
9
qemu-options.hx | 4 ++--
13
hw/net/can/ctucan_core.c | 6 ++----
10
1 file changed, 2 insertions(+), 2 deletions(-)
14
1 file changed, 2 insertions(+), 4 deletions(-)
11
15
12
diff --git a/qemu-options.hx b/qemu-options.hx
16
diff --git a/hw/net/can/ctucan_core.c b/hw/net/can/ctucan_core.c
13
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
14
--- a/qemu-options.hx
18
--- a/hw/net/can/ctucan_core.c
15
+++ b/qemu-options.hx
19
+++ b/hw/net/can/ctucan_core.c
16
@@ -XXX,XX +XXX,XX @@ qemu-system-i386 linux.img -net nic -net tap
20
@@ -XXX,XX +XXX,XX @@ void ctucan_mem_write(CtuCanCoreState *s, hwaddr addr, uint64_t val,
17
#launch a QEMU instance with two NICs, each one connected
21
addr -= CTU_CAN_FD_TXTB1_DATA_1;
18
#to a TAP device
22
buff_num = addr / CTUCAN_CORE_TXBUFF_SPAN;
19
qemu-system-i386 linux.img \
23
addr %= CTUCAN_CORE_TXBUFF_SPAN;
20
- -net nic,vlan=0 -net tap,vlan=0,ifname=tap0 \
24
- addr &= ~3;
21
- -net nic,vlan=1 -net tap,vlan=1,ifname=tap1
25
if ((buff_num < CTUCAN_CORE_TXBUF_NUM) &&
22
+ -netdev tap,id=nd0,ifname=tap0 -device e1000,netdev=nd0 \
26
- (addr < sizeof(s->tx_buffer[buff_num].data))) {
23
+ -netdev tap,id=nd1,ifname=tap1 -device rtl8139,netdev=nd1
27
- uint32_t *bufp = (uint32_t *)(s->tx_buffer[buff_num].data + addr);
24
@end example
28
- *bufp = cpu_to_le32(val);
25
29
+ ((addr + size) <= sizeof(s->tx_buffer[buff_num].data))) {
26
@example
30
+ stn_le_p(s->tx_buffer[buff_num].data + addr, size, val);
31
}
32
} else {
33
switch (addr & ~3) {
27
--
34
--
28
2.7.4
35
2.7.4
29
36
30
37
diff view generated by jsdifflib