1
The following changes since commit 56821559f0ba682fe6b367815572e6f974d329ab:
1
The following changes since commit e607bbee553cfe73072870cef458cfa4e78133e2:
2
2
3
Merge remote-tracking branch 'dgilbert/tags/pull-hmp-20170517' into staging (2017-05-18 13:36:15 +0100)
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)
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 82342e91b60a4a078811df4e1a545e57abffa11d:
9
for you to fetch changes up to bf4835a4d5338bb7424827715df22570a8adc67c:
10
10
11
e1000e: Fix ICR "Other" causes clear logic (2017-05-23 10:10:38 +0800)
11
MAINTAINERS: update Dmitry Fleytman email (2018-01-29 16:05:38 +0800)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
14
15
----------------------------------------------------------------
15
----------------------------------------------------------------
16
Sameeh Jubran (1):
16
Mao Zhongyi (2):
17
e1000e: Fix ICR "Other" causes clear logic
17
colo: modified the payload compare function
18
colo: compare the packet based on the tcp sequence number
19
20
Philippe Mathieu-Daudé (1):
21
MAINTAINERS: update Dmitry Fleytman email
18
22
19
Thomas Huth (3):
23
Thomas Huth (3):
20
net/tap: Replace tap-haiku.c and tap-aix.c by a generic tap-stub.c
24
net: Allow hubports to connect to other netdevs
21
net/dump: Issue a warning for the deprecated "-net dump"
25
net: Allow netdevs to be used with 'hostfwd_add' and 'hostfwd_remove'
22
hmp / net: Mark host_net_add/remove as deprecated
26
qemu-doc: Get rid of "vlan=X" example in the documentation
23
27
24
Yunjian Wang (1):
28
MAINTAINERS | 8 +-
25
virtio-net: fix wild pointer when remove virtio-net queues
29
hmp-commands.hx | 4 +-
26
30
net/colo-compare.c | 411 +++++++++++++++++++++++++++++++++--------------------
27
Zhang Chen (4):
31
net/colo.c | 9 ++
28
COLO-compare: Improve tcp compare trace event readability
32
net/colo.h | 15 ++
29
net/filter-mirror.c: Remove duplicate check code.
33
net/hub.c | 27 +++-
30
net/filter-mirror.c: Rename filter_mirror_send() and fix codestyle
34
net/hub.h | 3 +-
31
net/filter-rewriter: Remove unused option in filter-rewriter
35
net/net.c | 2 +-
32
36
net/slirp.c | 33 +++--
33
hmp-commands.hx | 8 ++--
37
net/trace-events | 2 +-
34
hw/net/e1000e_core.c | 10 ++++-
38
qapi/net.json | 4 +-
35
hw/net/virtio-net.c | 3 ++
39
qemu-options.hx | 12 +-
36
net/Makefile.objs | 15 ++++----
40
12 files changed, 347 insertions(+), 183 deletions(-)
37
net/colo-compare.c | 33 ++++++++++------
38
net/dump.c | 3 ++
39
net/filter-mirror.c | 35 ++++++++---------
40
net/net.c | 13 +++++++
41
net/tap-haiku.c | 87 -------------------------------------------
42
net/{tap-aix.c => tap-stub.c} | 3 +-
43
net/trace-events | 3 +-
44
qemu-options.hx | 2 +-
45
12 files changed, 80 insertions(+), 135 deletions(-)
46
delete mode 100644 net/tap-haiku.c
47
rename net/{tap-aix.c => tap-stub.c} (97%)
48
41
49
42
diff view generated by jsdifflib
Deleted patch
1
From: Thomas Huth <thuth@redhat.com>
2
1
3
The files tap-haiku.c and tap-aix.c are identical (except one line
4
of error message). We should avoid such code duplication, so replace
5
these by a generic tap-stub.c file instead.
6
7
Signed-off-by: Thomas Huth <thuth@redhat.com>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Signed-off-by: Jason Wang <jasowang@redhat.com>
10
---
11
net/Makefile.objs | 15 +++++-----
12
net/tap-aix.c | 88 -------------------------------------------------------
13
net/tap-haiku.c | 87 ------------------------------------------------------
14
net/tap-stub.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
15
4 files changed, 95 insertions(+), 182 deletions(-)
16
delete mode 100644 net/tap-aix.c
17
delete mode 100644 net/tap-haiku.c
18
create mode 100644 net/tap-stub.c
19
20
diff --git a/net/Makefile.objs b/net/Makefile.objs
21
index XXXXXXX..XXXXXXX 100644
22
--- a/net/Makefile.objs
23
+++ b/net/Makefile.objs
24
@@ -XXX,XX +XXX,XX @@ common-obj-y += socket.o
25
common-obj-y += dump.o
26
common-obj-y += eth.o
27
common-obj-$(CONFIG_L2TPV3) += l2tpv3.o
28
-common-obj-$(CONFIG_POSIX) += tap.o vhost-user.o
29
-common-obj-$(CONFIG_LINUX) += tap-linux.o
30
-common-obj-$(CONFIG_WIN32) += tap-win32.o
31
-common-obj-$(CONFIG_BSD) += tap-bsd.o
32
-common-obj-$(CONFIG_SOLARIS) += tap-solaris.o
33
-common-obj-$(CONFIG_AIX) += tap-aix.o
34
-common-obj-$(CONFIG_HAIKU) += tap-haiku.o
35
+common-obj-$(CONFIG_POSIX) += vhost-user.o
36
common-obj-$(CONFIG_SLIRP) += slirp.o
37
common-obj-$(CONFIG_VDE) += vde.o
38
common-obj-$(CONFIG_NETMAP) += netmap.o
39
@@ -XXX,XX +XXX,XX @@ common-obj-y += colo-compare.o
40
common-obj-y += colo.o
41
common-obj-y += filter-rewriter.o
42
common-obj-y += filter-replay.o
43
+
44
+tap-obj-$(CONFIG_LINUX) = tap-linux.o
45
+tap-obj-$(CONFIG_BSD) = tap-bsd.o
46
+tap-obj-$(CONFIG_SOLARIS) = tap-solaris.o
47
+tap-obj-y ?= tap-stub.o
48
+common-obj-$(CONFIG_POSIX) += tap.o $(tap-obj-y)
49
+common-obj-$(CONFIG_WIN32) += tap-win32.o
50
diff --git a/net/tap-aix.c b/net/tap-aix.c
51
deleted file mode 100644
52
index XXXXXXX..XXXXXXX
53
--- a/net/tap-aix.c
54
+++ /dev/null
55
@@ -XXX,XX +XXX,XX @@
56
-/*
57
- * QEMU System Emulator
58
- *
59
- * Copyright (c) 2003-2008 Fabrice Bellard
60
- *
61
- * Permission is hereby granted, free of charge, to any person obtaining a copy
62
- * of this software and associated documentation files (the "Software"), to deal
63
- * in the Software without restriction, including without limitation the rights
64
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
65
- * copies of the Software, and to permit persons to whom the Software is
66
- * furnished to do so, subject to the following conditions:
67
- *
68
- * The above copyright notice and this permission notice shall be included in
69
- * all copies or substantial portions of the Software.
70
- *
71
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
72
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
73
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
74
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
75
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
76
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
77
- * THE SOFTWARE.
78
- */
79
-
80
-#include "qemu/osdep.h"
81
-#include "qapi/error.h"
82
-#include "tap_int.h"
83
-
84
-int tap_open(char *ifname, int ifname_size, int *vnet_hdr,
85
- int vnet_hdr_required, int mq_required, Error **errp)
86
-{
87
- error_setg(errp, "no tap on AIX");
88
- return -1;
89
-}
90
-
91
-void tap_set_sndbuf(int fd, const NetdevTapOptions *tap, Error **errp)
92
-{
93
-}
94
-
95
-int tap_probe_vnet_hdr(int fd)
96
-{
97
- return 0;
98
-}
99
-
100
-int tap_probe_has_ufo(int fd)
101
-{
102
- return 0;
103
-}
104
-
105
-int tap_probe_vnet_hdr_len(int fd, int len)
106
-{
107
- return 0;
108
-}
109
-
110
-void tap_fd_set_vnet_hdr_len(int fd, int len)
111
-{
112
-}
113
-
114
-int tap_fd_set_vnet_le(int fd, int is_le)
115
-{
116
- return -EINVAL;
117
-}
118
-
119
-int tap_fd_set_vnet_be(int fd, int is_be)
120
-{
121
- return -EINVAL;
122
-}
123
-
124
-void tap_fd_set_offload(int fd, int csum, int tso4,
125
- int tso6, int ecn, int ufo)
126
-{
127
-}
128
-
129
-int tap_fd_enable(int fd)
130
-{
131
- return -1;
132
-}
133
-
134
-int tap_fd_disable(int fd)
135
-{
136
- return -1;
137
-}
138
-
139
-int tap_fd_get_ifname(int fd, char *ifname)
140
-{
141
- return -1;
142
-}
143
-
144
diff --git a/net/tap-haiku.c b/net/tap-haiku.c
145
deleted file mode 100644
146
index XXXXXXX..XXXXXXX
147
--- a/net/tap-haiku.c
148
+++ /dev/null
149
@@ -XXX,XX +XXX,XX @@
150
-/*
151
- * QEMU System Emulator
152
- *
153
- * Copyright (c) 2003-2008 Fabrice Bellard
154
- *
155
- * Permission is hereby granted, free of charge, to any person obtaining a copy
156
- * of this software and associated documentation files (the "Software"), to deal
157
- * in the Software without restriction, including without limitation the rights
158
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
159
- * copies of the Software, and to permit persons to whom the Software is
160
- * furnished to do so, subject to the following conditions:
161
- *
162
- * The above copyright notice and this permission notice shall be included in
163
- * all copies or substantial portions of the Software.
164
- *
165
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
166
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
167
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
168
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
169
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
170
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
171
- * THE SOFTWARE.
172
- */
173
-
174
-#include "qemu/osdep.h"
175
-#include "qapi/error.h"
176
-#include "tap_int.h"
177
-
178
-int tap_open(char *ifname, int ifname_size, int *vnet_hdr,
179
- int vnet_hdr_required, int mq_required, Error **errp)
180
-{
181
- error_setg(errp, "no tap on Haiku");
182
- return -1;
183
-}
184
-
185
-void tap_set_sndbuf(int fd, const NetdevTapOptions *tap, Error **errp)
186
-{
187
-}
188
-
189
-int tap_probe_vnet_hdr(int fd)
190
-{
191
- return 0;
192
-}
193
-
194
-int tap_probe_has_ufo(int fd)
195
-{
196
- return 0;
197
-}
198
-
199
-int tap_probe_vnet_hdr_len(int fd, int len)
200
-{
201
- return 0;
202
-}
203
-
204
-void tap_fd_set_vnet_hdr_len(int fd, int len)
205
-{
206
-}
207
-
208
-int tap_fd_set_vnet_le(int fd, int is_le)
209
-{
210
- return -EINVAL;
211
-}
212
-
213
-int tap_fd_set_vnet_be(int fd, int is_be)
214
-{
215
- return -EINVAL;
216
-}
217
-
218
-void tap_fd_set_offload(int fd, int csum, int tso4,
219
- int tso6, int ecn, int ufo)
220
-{
221
-}
222
-
223
-int tap_fd_enable(int fd)
224
-{
225
- return -1;
226
-}
227
-
228
-int tap_fd_disable(int fd)
229
-{
230
- return -1;
231
-}
232
-
233
-int tap_fd_get_ifname(int fd, char *ifname)
234
-{
235
- return -1;
236
-}
237
diff --git a/net/tap-stub.c b/net/tap-stub.c
238
new file mode 100644
239
index XXXXXXX..XXXXXXX
240
--- /dev/null
241
+++ b/net/tap-stub.c
242
@@ -XXX,XX +XXX,XX @@
243
+/*
244
+ * QEMU System Emulator
245
+ *
246
+ * Copyright (c) 2003-2008 Fabrice Bellard
247
+ *
248
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
249
+ * of this software and associated documentation files (the "Software"), to deal
250
+ * in the Software without restriction, including without limitation the rights
251
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
252
+ * copies of the Software, and to permit persons to whom the Software is
253
+ * furnished to do so, subject to the following conditions:
254
+ *
255
+ * The above copyright notice and this permission notice shall be included in
256
+ * all copies or substantial portions of the Software.
257
+ *
258
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
259
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
260
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
261
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
262
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
263
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
264
+ * THE SOFTWARE.
265
+ */
266
+
267
+#include "qemu/osdep.h"
268
+#include "qapi/error.h"
269
+#include "tap_int.h"
270
+
271
+int tap_open(char *ifname, int ifname_size, int *vnet_hdr,
272
+ int vnet_hdr_required, int mq_required, Error **errp)
273
+{
274
+ error_setg(errp, "tap is not supported in this build");
275
+ return -1;
276
+}
277
+
278
+void tap_set_sndbuf(int fd, const NetdevTapOptions *tap, Error **errp)
279
+{
280
+}
281
+
282
+int tap_probe_vnet_hdr(int fd)
283
+{
284
+ return 0;
285
+}
286
+
287
+int tap_probe_has_ufo(int fd)
288
+{
289
+ return 0;
290
+}
291
+
292
+int tap_probe_vnet_hdr_len(int fd, int len)
293
+{
294
+ return 0;
295
+}
296
+
297
+void tap_fd_set_vnet_hdr_len(int fd, int len)
298
+{
299
+}
300
+
301
+int tap_fd_set_vnet_le(int fd, int is_le)
302
+{
303
+ return -EINVAL;
304
+}
305
+
306
+int tap_fd_set_vnet_be(int fd, int is_be)
307
+{
308
+ return -EINVAL;
309
+}
310
+
311
+void tap_fd_set_offload(int fd, int csum, int tso4,
312
+ int tso6, int ecn, int ufo)
313
+{
314
+}
315
+
316
+int tap_fd_enable(int fd)
317
+{
318
+ return -1;
319
+}
320
+
321
+int tap_fd_disable(int fd)
322
+{
323
+ return -1;
324
+}
325
+
326
+int tap_fd_get_ifname(int fd, char *ifname)
327
+{
328
+ return -1;
329
+}
330
--
331
2.7.4
332
333
diff view generated by jsdifflib
Deleted patch
1
From: Thomas Huth <thuth@redhat.com>
2
1
3
Network dumping should be done with "-object filter-dump" nowadays.
4
Using "-net dump" via the VLAN mechanism is considered as deprecated
5
and might be removed in a future release. So warn the users now
6
to inform them to user the filter-dump method instead.
7
8
Signed-off-by: Thomas Huth <thuth@redhat.com>
9
Signed-off-by: Jason Wang <jasowang@redhat.com>
10
---
11
net/dump.c | 3 +++
12
1 file changed, 3 insertions(+)
13
14
diff --git a/net/dump.c b/net/dump.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/net/dump.c
17
+++ b/net/dump.c
18
@@ -XXX,XX +XXX,XX @@ int net_init_dump(const Netdev *netdev, const char *name,
19
20
assert(peer);
21
22
+ error_report("'-net dump' is deprecated. "
23
+ "Please use '-object filter-dump' instead.");
24
+
25
if (dump->has_file) {
26
file = dump->file;
27
} else {
28
--
29
2.7.4
30
31
diff view generated by jsdifflib
1
From: Sameeh Jubran <sameeh@daynix.com>
1
From: Mao Zhongyi <maozy.fnst@cn.fujitsu.com>
2
2
3
This commit fixes a bug which causes the guest to hang. The bug was
3
Modified the function colo_packet_compare_common to prepare for the
4
observed upon a "receive overrun" (bit #6 of the ICR register)
4
tcp packet comparison in the next patch.
5
interrupt which could be triggered post migration in a heavy traffic
6
environment. Even though the "receive overrun" bit (#6) is masked out
7
by the IMS register (refer to the log below) the driver still receives
8
an interrupt as the "receive overrun" bit (#6) causes the "Other" -
9
bit #24 of the ICR register - bit to be set as documented below. The
10
driver handles the interrupt and clears the "Other" bit (#24) but
11
doesn't clear the "receive overrun" bit (#6) which leads to an
12
infinite loop. Apparently the Windows driver expects that the "receive
13
overrun" bit and other ones - documented below - to be cleared when
14
the "Other" bit (#24) is cleared.
15
5
16
So to sum that up:
6
Cc: Zhang Chen <zhangckid@gmail.com>
17
1. Bit #6 of the ICR register is set by heavy traffic
7
Cc: Li Zhijian <lizhijian@cn.fujitsu.com>
18
2. As a results of setting bit #6, bit #24 is set
8
Cc: Jason Wang <jasowang@redhat.com>
19
3. The driver receives an interrupt for bit 24 (it doesn't receieve an
20
interrupt for bit #6 as it is masked out by IMS)
21
4. The driver handles and clears the interrupt of bit #24
22
5. Bit #6 is still set.
23
6. 2 happens all over again
24
9
25
The Interrupt Cause Read - ICR register:
10
Signed-off-by: Mao Zhongyi <maozy.fnst@cn.fujitsu.com>
26
11
Signed-off-by: Li Zhijian <lizhijian@cn.fujitsu.com>
27
The ICR has the "Other" bit - bit #24 - that is set when one or more
12
Signed-off-by: Zhang Chen <zhangckid@gmail.com>
28
of the following ICR register's bits are set:
13
Reviewed-by: Zhang Chen <zhangckid@gmail.com>
29
30
LSC - bit #2, RXO - bit #6, MDAC - bit #9, SRPD - bit #16, ACK - bit
31
#17, MNG - bit #18
32
33
This bug can occur with any of these bits depending on the driver's
34
behaviour and the way it configures the device. However, trying to
35
reproduce it with any bit other than RX0 is challenging and came to
36
failure as the drivers don't implement most of these bits, trying to
37
reproduce it with LSC (Link Status Change - bit #2) bit didn't succeed
38
too as it seems that Windows handles this bit differently.
39
40
Log sample of the storm:
41
42
27563@1494850819.411877:e1000e_irq_pending_interrupts ICR PENDING: 0x1000000 (ICR: 0x815000c2, IMS: 0x1a00004)
43
27563@1494850819.411900:e1000e_irq_pending_interrupts ICR PENDING: 0x0 (ICR: 0x815000c2, IMS: 0xa00004)
44
27563@1494850819.411915:e1000e_irq_pending_interrupts ICR PENDING: 0x0 (ICR: 0x815000c2, IMS: 0xa00004)
45
27563@1494850819.412380:e1000e_irq_pending_interrupts ICR PENDING: 0x0 (ICR: 0x815000c2, IMS: 0xa00004)
46
27563@1494850819.412395:e1000e_irq_pending_interrupts ICR PENDING: 0x0 (ICR: 0x815000c2, IMS: 0xa00004)
47
27563@1494850819.412436:e1000e_irq_pending_interrupts ICR PENDING: 0x0 (ICR: 0x815000c2, IMS: 0xa00004)
48
27563@1494850819.412441:e1000e_irq_pending_interrupts ICR PENDING: 0x0 (ICR: 0x815000c2, IMS: 0xa00004)
49
27563@1494850819.412998:e1000e_irq_pending_interrupts ICR PENDING: 0x1000000 (ICR: 0x815000c2, IMS: 0x1a00004)
50
51
* This bug behaviour wasn't observed with the Linux driver.
52
53
This commit solves:
54
https://bugzilla.redhat.com/show_bug.cgi?id=1447935
55
https://bugzilla.redhat.com/show_bug.cgi?id=1449490
56
57
Cc: qemu-stable@nongnu.org
58
Signed-off-by: Sameeh Jubran <sjubran@redhat.com>
59
Signed-off-by: Jason Wang <jasowang@redhat.com>
14
Signed-off-by: Jason Wang <jasowang@redhat.com>
60
---
15
---
61
hw/net/e1000e_core.c | 10 ++++++++--
16
net/colo-compare.c | 88 +++++++++++++++++++++++++++---------------------------
62
1 file changed, 8 insertions(+), 2 deletions(-)
17
1 file changed, 44 insertions(+), 44 deletions(-)
63
18
64
diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c
19
diff --git a/net/colo-compare.c b/net/colo-compare.c
65
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
66
--- a/hw/net/e1000e_core.c
21
--- a/net/colo-compare.c
67
+++ b/hw/net/e1000e_core.c
22
+++ b/net/colo-compare.c
68
@@ -XXX,XX +XXX,XX @@ e1000e_set_ics(E1000ECore *core, int index, uint32_t val)
23
@@ -XXX,XX +XXX,XX @@ static int packet_enqueue(CompareState *s, int mode, Connection **con)
69
static void
24
* return: 0 means packet same
70
e1000e_set_icr(E1000ECore *core, int index, uint32_t val)
25
* > 0 || < 0 means packet different
26
*/
27
-static int colo_packet_compare_common(Packet *ppkt,
28
- Packet *spkt,
29
- int poffset,
30
- int soffset)
31
+static int colo_compare_packet_payload(Packet *ppkt,
32
+ Packet *spkt,
33
+ uint16_t poffset,
34
+ uint16_t soffset,
35
+ uint16_t len)
36
+
71
{
37
{
72
+ uint32_t icr = 0;
38
if (trace_event_get_state_backends(TRACE_COLO_COMPARE_MISCOMPARE)) {
73
if ((core->mac[ICR] & E1000_ICR_ASSERTED) &&
39
char pri_ip_src[20], pri_ip_dst[20], sec_ip_src[20], sec_ip_dst[20];
74
(core->mac[CTRL_EXT] & E1000_CTRL_EXT_IAME)) {
40
@@ -XXX,XX +XXX,XX @@ static int colo_packet_compare_common(Packet *ppkt,
75
trace_e1000e_irq_icr_process_iame();
41
sec_ip_src, sec_ip_dst);
76
e1000e_clear_ims_bits(core, core->mac[IAM]);
77
}
42
}
78
43
79
- trace_e1000e_irq_icr_write(val, core->mac[ICR], core->mac[ICR] & ~val);
44
- poffset = ppkt->vnet_hdr_len + poffset;
80
- core->mac[ICR] &= ~val;
45
- soffset = ppkt->vnet_hdr_len + soffset;
81
+ icr = core->mac[ICR] & ~val;
46
-
82
+ /* Windows driver expects that the "receive overrun" bit and other
47
- if (ppkt->size - poffset == spkt->size - soffset) {
83
+ * ones to be cleared when the "Other" bit (#24) is cleared.
48
- return memcmp(ppkt->data + poffset,
84
+ */
49
- spkt->data + soffset,
85
+ icr = (val & E1000_ICR_OTHER) ? (icr & ~E1000_ICR_OTHER_CAUSES) : icr;
50
- spkt->size - soffset);
86
+ trace_e1000e_irq_icr_write(val, core->mac[ICR], icr);
51
- } else {
87
+ core->mac[ICR] = icr;
52
- trace_colo_compare_main("Net packet size are not the same");
88
e1000e_update_interrupt_state(core);
53
- return -1;
54
- }
55
+ return memcmp(ppkt->data + poffset, spkt->data + soffset, len);
89
}
56
}
90
57
58
/*
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)
91
--
185
--
92
2.7.4
186
2.7.4
93
187
94
188
diff view generated by jsdifflib
1
From: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
1
From: Mao Zhongyi <maozy.fnst@cn.fujitsu.com>
2
2
3
Because of previous patch's trace arguments over the limit
3
Packet size some time different or when network is busy.
4
of UST backend, so I rewrite the patch.
4
Based on same payload size, but TCP protocol can not
5
5
guarantee send the same one packet in the same way,
6
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
6
7
like that:
8
We send this payload:
9
------------------------------
10
| header |1|2|3|4|5|6|7|8|9|0|
11
------------------------------
12
13
primary:
14
ppkt1:
15
----------------
16
| header |1|2|3|
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>
7
Signed-off-by: Jason Wang <jasowang@redhat.com>
69
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
---
70
---
9
net/colo-compare.c | 33 ++++++++++++++++++++++-----------
71
net/colo-compare.c | 343 +++++++++++++++++++++++++++++++++++------------------
10
net/trace-events | 3 +--
72
net/colo.c | 9 ++
11
2 files changed, 23 insertions(+), 13 deletions(-)
73
net/colo.h | 15 +++
74
net/trace-events | 2 +-
75
4 files changed, 250 insertions(+), 119 deletions(-)
12
76
13
diff --git a/net/colo-compare.c b/net/colo-compare.c
77
diff --git a/net/colo-compare.c b/net/colo-compare.c
14
index XXXXXXX..XXXXXXX 100644
78
index XXXXXXX..XXXXXXX 100644
15
--- a/net/colo-compare.c
79
--- a/net/colo-compare.c
16
+++ b/net/colo-compare.c
80
+++ b/net/colo-compare.c
17
@@ -XXX,XX +XXX,XX @@ static int colo_packet_compare_tcp(Packet *spkt, Packet *ppkt)
81
@@ -XXX,XX +XXX,XX @@
82
#define COMPARE_READ_LEN_MAX NET_BUFSIZE
83
#define MAX_QUEUE_SIZE 1024
84
85
+#define COLO_COMPARE_FREE_PRIMARY 0x01
86
+#define COLO_COMPARE_FREE_SECONDARY 0x02
87
+
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
}
94
95
+static void fill_pkt_tcp_info(void *data, uint32_t *max_ack)
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
{
119
if (g_queue_get_length(queue) <= MAX_QUEUE_SIZE) {
120
if (pkt->ip->ip_p == IPPROTO_TCP) {
121
+ fill_pkt_tcp_info(pkt, max_ack);
122
g_queue_insert_sorted(queue,
123
pkt,
124
(GCompareDataFunc)seq_sorter,
125
@@ -XXX,XX +XXX,XX @@ static int packet_enqueue(CompareState *s, int mode, Connection **con)
18
}
126
}
19
127
20
if (res != 0 && trace_event_get_state(TRACE_COLO_COMPARE_MISCOMPARE)) {
128
if (mode == PRIMARY_IN) {
21
- trace_colo_compare_pkt_info_src(inet_ntoa(ppkt->ip->ip_src),
129
- if (!colo_insert_packet(&conn->primary_list, pkt)) {
22
- ntohl(stcp->th_seq),
130
+ if (!colo_insert_packet(&conn->primary_list, pkt, &conn->pack)) {
23
- ntohl(stcp->th_ack),
131
error_report("colo compare primary queue size too big,"
24
- res, stcp->th_flags,
132
"drop packet");
25
- spkt->size);
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
}
143
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];
26
-
349
-
27
- trace_colo_compare_pkt_info_dst(inet_ntoa(ppkt->ip->ip_dst),
350
- strcpy(pri_ip_src, inet_ntoa(ppkt->ip->ip_src));
28
- ntohl(ptcp->th_seq),
351
- strcpy(pri_ip_dst, inet_ntoa(ppkt->ip->ip_dst));
29
- ntohl(ptcp->th_ack),
352
- strcpy(sec_ip_src, inet_ntoa(spkt->ip->ip_src));
30
- res, ptcp->th_flags,
353
- strcpy(sec_ip_dst, inet_ntoa(spkt->ip->ip_dst));
31
- ppkt->size);
354
-
32
+ char pri_ip_src[20], pri_ip_dst[20], sec_ip_src[20], sec_ip_dst[20];
355
- trace_colo_compare_ip_info(ppkt->size, pri_ip_src,
33
+
356
- pri_ip_dst, spkt->size,
34
+ strcpy(pri_ip_src, inet_ntoa(ppkt->ip->ip_src));
357
- sec_ip_src, sec_ip_dst);
35
+ strcpy(pri_ip_dst, inet_ntoa(ppkt->ip->ip_dst));
358
-
36
+ strcpy(sec_ip_src, inet_ntoa(spkt->ip->ip_src));
359
- trace_colo_compare_tcp_info("pri tcp packet",
37
+ strcpy(sec_ip_dst, inet_ntoa(spkt->ip->ip_dst));
360
- ntohl(ptcp->th_seq),
38
+
361
- ntohl(ptcp->th_ack),
39
+ trace_colo_compare_ip_info(ppkt->size, pri_ip_src,
362
- res, ptcp->th_flags,
40
+ pri_ip_dst, spkt->size,
363
- ppkt->size);
41
+ sec_ip_src, sec_ip_dst);
364
-
42
+
365
- trace_colo_compare_tcp_info("sec tcp packet",
43
+ trace_colo_compare_tcp_info("pri tcp packet",
366
- ntohl(stcp->th_seq),
44
+ ntohl(ptcp->th_seq),
367
- ntohl(stcp->th_ack),
45
+ ntohl(ptcp->th_ack),
368
- res, stcp->th_flags,
46
+ res, ptcp->th_flags,
369
- spkt->size);
47
+ ppkt->size);
370
+ if (colo_mark_tcp_pkt(ppkt, spkt, &mark, min_ack)) {
48
+
371
+ trace_colo_compare_tcp_info("pri",
49
+ trace_colo_compare_tcp_info("sec tcp packet",
372
+ ppkt->tcp_seq, ppkt->tcp_ack,
50
+ ntohl(stcp->th_seq),
373
+ ppkt->header_size, ppkt->payload_size,
51
+ ntohl(stcp->th_ack),
374
+ ppkt->offset, ppkt->flags);
52
+ res, stcp->th_flags,
375
+
53
+ spkt->size);
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);
54
401
55
qemu_hexdump((char *)ppkt->data, stderr,
402
qemu_hexdump((char *)ppkt->data, stderr,
56
"colo-compare ppkt", ppkt->size);
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
/*
57
diff --git a/net/trace-events b/net/trace-events
574
diff --git a/net/trace-events b/net/trace-events
58
index XXXXXXX..XXXXXXX 100644
575
index XXXXXXX..XXXXXXX 100644
59
--- a/net/trace-events
576
--- a/net/trace-events
60
+++ b/net/trace-events
577
+++ b/net/trace-events
61
@@ -XXX,XX +XXX,XX @@ colo_compare_icmp_miscompare(const char *sta, int size) ": %s = %d"
578
@@ -XXX,XX +XXX,XX @@ colo_compare_icmp_miscompare(const char *sta, int size) ": %s = %d"
62
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"
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"
63
colo_old_packet_check_found(int64_t old_time) "%" PRId64
580
colo_old_packet_check_found(int64_t old_time) "%" PRId64
64
colo_compare_miscompare(void) ""
581
colo_compare_miscompare(void) ""
65
-colo_compare_pkt_info_src(const char *src, uint32_t sseq, uint32_t sack, int res, uint32_t sflag, int ssize) "src/dst: %s s: seq/ack=%u/%u res=%d flags=%x spkt_size: %d\n"
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"
66
-colo_compare_pkt_info_dst(const char *dst, uint32_t dseq, uint32_t dack, int res, uint32_t dflag, int dsize) "src/dst: %s d: seq/ack=%u/%u res=%d flags=%x dpkt_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"
67
+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= %x pkt_size: %d\n"
68
584
69
# net/filter-rewriter.c
585
# net/filter-rewriter.c
70
colo_filter_rewriter_debug(void) ""
586
colo_filter_rewriter_debug(void) ""
71
--
587
--
72
2.7.4
588
2.7.4
73
589
74
590
diff view generated by jsdifflib
1
From: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
1
From: Thomas Huth <thuth@redhat.com>
2
2
3
Because filter_mirror_receive_iov() and filter_redirector_receive_iov()
3
QEMU can emulate hubs to connect NICs and netdevs. This is currently
4
both use the filter_mirror_send() to send packet, so I change
4
primarily used for the mis-named 'vlan' feature of the networking
5
filter_mirror_send() to filter_send() that looks more common.
5
subsystem. Now the 'vlan' feature has been marked as deprecated, since
6
And fix some codestyle.
6
its name is rather confusing and the users often rather mis-configure
7
7
their network when trying to use it. But while the 'vlan' parameter
8
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
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
12
Now to be able to use the hubport feature without 'vlan's, there is one
13
missing piece: The possibility to connect a hubport to a netdev, too.
14
This patch adds this possibility by introducing a new "netdev=..."
15
parameter to the hubports.
16
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>
9
Signed-off-by: Jason Wang <jasowang@redhat.com>
39
Signed-off-by: Jason Wang <jasowang@redhat.com>
10
---
40
---
11
net/filter-mirror.c | 29 ++++++++++++++++-------------
41
net/hub.c | 27 +++++++++++++++++++++------
12
1 file changed, 16 insertions(+), 13 deletions(-)
42
net/hub.h | 3 ++-
13
43
net/net.c | 2 +-
14
diff --git a/net/filter-mirror.c b/net/filter-mirror.c
44
qapi/net.json | 4 +++-
15
index XXXXXXX..XXXXXXX 100644
45
qemu-options.hx | 8 +++++---
16
--- a/net/filter-mirror.c
46
5 files changed, 32 insertions(+), 12 deletions(-)
17
+++ b/net/filter-mirror.c
47
18
@@ -XXX,XX +XXX,XX @@ typedef struct MirrorState {
48
diff --git a/net/hub.c b/net/hub.c
19
SocketReadState rs;
49
index XXXXXXX..XXXXXXX 100644
20
} MirrorState;
50
--- a/net/hub.c
21
51
+++ b/net/hub.c
22
-static int filter_mirror_send(CharBackend *chr_out,
52
@@ -XXX,XX +XXX,XX @@
23
- const struct iovec *iov,
53
*/
24
- int iovcnt)
54
25
+static int filter_send(CharBackend *chr_out,
55
#include "qemu/osdep.h"
26
+ const struct iovec *iov,
56
+#include "qapi/error.h"
27
+ int iovcnt)
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)
28
{
67
{
29
int ret = 0;
68
NetClientState *nc;
30
ssize_t size = 0;
69
NetHubPort *port;
31
@@ -XXX,XX +XXX,XX @@ static ssize_t filter_mirror_receive_iov(NetFilterState *nf,
70
@@ -XXX,XX +XXX,XX @@ static NetHubPort *net_hub_port_new(NetHub *hub, const char *name)
32
MirrorState *s = FILTER_MIRROR(nf);
71
name = default_name;
33
int ret;
34
35
- ret = filter_mirror_send(&s->chr_out, iov, iovcnt);
36
+ ret = filter_send(&s->chr_out, iov, iovcnt);
37
if (ret) {
38
- error_report("filter_mirror_send failed(%s)", strerror(-ret));
39
+ error_report("filter mirror send failed(%s)", strerror(-ret));
40
}
72
}
41
73
42
/*
74
- nc = qemu_new_net_client(&net_hub_port_info, NULL, "hub", name);
43
@@ -XXX,XX +XXX,XX @@ static ssize_t filter_redirector_receive_iov(NetFilterState *nf,
75
+ nc = qemu_new_net_client(&net_hub_port_info, hubpeer, "hub", name);
44
int ret;
76
port = DO_UPCAST(NetHubPort, nc, nc);
45
77
port->id = id;
46
if (qemu_chr_fe_get_driver(&s->chr_out)) {
78
port->hub = hub;
47
- ret = filter_mirror_send(&s->chr_out, iov, iovcnt);
79
@@ -XXX,XX +XXX,XX @@ static NetHubPort *net_hub_port_new(NetHub *hub, const char *name)
48
+ ret = filter_send(&s->chr_out, iov, iovcnt);
80
49
if (ret) {
81
/**
50
- error_report("filter_mirror_send failed(%s)", strerror(-ret));
82
* Create a port on a given hub
51
+ error_report("filter redirector send failed(%s)", strerror(-ret));
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
}
103
104
@@ -XXX,XX +XXX,XX @@ NetClientState *net_hub_port_find(int hub_id)
52
}
105
}
53
return iov_size(iov, iovcnt);
106
}
54
} else {
107
55
@@ -XXX,XX +XXX,XX @@ static char *filter_redirector_get_indev(Object *obj, Error **errp)
108
- nc = net_hub_add_port(hub_id, NULL);
56
return g_strdup(s->indev);
109
+ nc = net_hub_add_port(hub_id, NULL, NULL);
110
return nc;
57
}
111
}
58
112
59
-static void
113
@@ -XXX,XX +XXX,XX @@ int net_init_hubport(const Netdev *netdev, const char *name,
60
-filter_redirector_set_indev(Object *obj, const char *value, Error **errp)
114
NetClientState *peer, Error **errp)
61
+static void filter_redirector_set_indev(Object *obj,
62
+ const char *value,
63
+ Error **errp)
64
{
115
{
65
MirrorState *s = FILTER_REDIRECTOR(obj);
116
const NetdevHubPortOptions *hubport;
66
117
+ NetClientState *hubpeer = NULL;
67
@@ -XXX,XX +XXX,XX @@ static char *filter_mirror_get_outdev(Object *obj, Error **errp)
118
68
return g_strdup(s->outdev);
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;
69
}
135
}
70
136
71
-static void
137
diff --git a/net/hub.h b/net/hub.h
72
-filter_mirror_set_outdev(Object *obj, const char *value, Error **errp)
138
index XXXXXXX..XXXXXXX 100644
73
+static void filter_mirror_set_outdev(Object *obj,
139
--- a/net/hub.h
74
+ const char *value,
140
+++ b/net/hub.h
75
+ Error **errp)
141
@@ -XXX,XX +XXX,XX @@
76
{
142
77
MirrorState *s = FILTER_MIRROR(obj);
143
#include "qemu-common.h"
78
144
79
@@ -XXX,XX +XXX,XX @@ static char *filter_redirector_get_outdev(Object *obj, Error **errp)
145
-NetClientState *net_hub_add_port(int hub_id, const char *name);
80
return g_strdup(s->outdev);
146
+NetClientState *net_hub_add_port(int hub_id, const char *name,
81
}
147
+ NetClientState *hubpeer);
82
148
NetClientState *net_hub_find_client_by_name(int hub_id, const char *name);
83
-static void
149
void net_hub_info(Monitor *mon);
84
-filter_redirector_set_outdev(Object *obj, const char *value, Error **errp)
150
void net_hub_check_clients(void);
85
+static void filter_redirector_set_outdev(Object *obj,
151
diff --git a/net/net.c b/net/net.c
86
+ const char *value,
152
index XXXXXXX..XXXXXXX 100644
87
+ Error **errp)
153
--- a/net/net.c
88
{
154
+++ b/net/net.c
89
MirrorState *s = FILTER_REDIRECTOR(obj);
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]
90
214
91
--
215
--
92
2.7.4
216
2.7.4
93
217
94
218
diff view generated by jsdifflib
1
From: Thomas Huth <thuth@redhat.com>
1
From: Thomas Huth <thuth@redhat.com>
2
2
3
The netdev_add and netdev_del commands should be used nowadays instead.
3
It does not make much sense to limit these commands to the legacy 'vlan'
4
concept only, they should work with the modern netdevs, too. So now
5
it is possible to use this command with one, two or three parameters.
6
7
With one parameter, the command installs a hostfwd rule on the default
8
"user" network:
9
hostfwd_add tcp:...
10
11
With two parameters, the command installs a hostfwd rule on a netdev
12
(that's the new way of using this command):
13
hostfwd_add netdev_id tcp:...
14
15
With three parameters, the command installs a rule on a 'vlan' (aka hub):
16
hostfwd_add hub_id name tcp:...
17
18
Same applies to the hostfwd_remove command now.
4
19
5
Signed-off-by: Thomas Huth <thuth@redhat.com>
20
Signed-off-by: Thomas Huth <thuth@redhat.com>
6
Signed-off-by: Jason Wang <jasowang@redhat.com>
21
Signed-off-by: Jason Wang <jasowang@redhat.com>
7
---
22
---
8
hmp-commands.hx | 8 ++++----
23
hmp-commands.hx | 4 ++--
9
net/net.c | 13 +++++++++++++
24
net/slirp.c | 33 +++++++++++++++++++++++----------
10
2 files changed, 17 insertions(+), 4 deletions(-)
25
2 files changed, 25 insertions(+), 12 deletions(-)
11
26
12
diff --git a/hmp-commands.hx b/hmp-commands.hx
27
diff --git a/hmp-commands.hx b/hmp-commands.hx
13
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
14
--- a/hmp-commands.hx
29
--- a/hmp-commands.hx
15
+++ b/hmp-commands.hx
30
+++ b/hmp-commands.hx
16
@@ -XXX,XX +XXX,XX @@ ETEXI
31
@@ -XXX,XX +XXX,XX @@ ETEXI
17
.name = "host_net_add",
32
{
18
.args_type = "device:s,opts:s?",
33
.name = "hostfwd_add",
19
.params = "tap|user|socket|vde|netmap|bridge|vhost-user|dump [options]",
34
.args_type = "arg1:s,arg2:s?,arg3:s?",
20
- .help = "add host VLAN client",
35
- .params = "[vlan_id name] [tcp|udp]:[hostaddr]:hostport-[guestaddr]:guestport",
21
+ .help = "add host VLAN client (deprecated, use netdev_add instead)",
36
+ .params = "[hub_id name]|[netdev_id] [tcp|udp]:[hostaddr]:hostport-[guestaddr]:guestport",
22
.cmd = hmp_host_net_add,
37
.help = "redirect TCP or UDP connections from host to guest (requires -net user)",
23
.command_completion = host_net_add_completion,
38
.cmd = hmp_hostfwd_add,
24
},
39
},
25
@@ -XXX,XX +XXX,XX @@ ETEXI
40
@@ -XXX,XX +XXX,XX @@ ETEXI
26
STEXI
27
@item host_net_add
28
@findex host_net_add
29
-Add host VLAN client.
30
+Add host VLAN client. Deprecated, please use @code{netdev_add} instead.
31
ETEXI
32
33
{
41
{
34
.name = "host_net_remove",
42
.name = "hostfwd_remove",
35
.args_type = "vlan_id:i,device:s",
43
.args_type = "arg1:s,arg2:s?,arg3:s?",
36
.params = "vlan_id name",
44
- .params = "[vlan_id name] [tcp|udp]:[hostaddr]:hostport",
37
- .help = "remove host VLAN client",
45
+ .params = "[hub_id name]|[netdev_id] [tcp|udp]:[hostaddr]:hostport",
38
+ .help = "remove host VLAN client (deprecated, use netdev_del instead)",
46
.help = "remove host-to-guest TCP or UDP redirection",
39
.cmd = hmp_host_net_remove,
47
.cmd = hmp_hostfwd_remove,
40
.command_completion = host_net_remove_completion,
41
},
48
},
42
@@ -XXX,XX +XXX,XX @@ ETEXI
49
diff --git a/net/slirp.c b/net/slirp.c
43
STEXI
44
@item host_net_remove
45
@findex host_net_remove
46
-Remove host VLAN client.
47
+Remove host VLAN client. Deprecated, please use @code{netdev_del} instead.
48
ETEXI
49
50
{
51
diff --git a/net/net.c b/net/net.c
52
index XXXXXXX..XXXXXXX 100644
50
index XXXXXXX..XXXXXXX 100644
53
--- a/net/net.c
51
--- a/net/slirp.c
54
+++ b/net/net.c
52
+++ b/net/slirp.c
55
@@ -XXX,XX +XXX,XX @@
53
@@ -XXX,XX +XXX,XX @@ error:
56
#include "qapi-visit.h"
54
return -1;
57
#include "qapi/opts-visitor.h"
55
}
58
#include "sysemu/sysemu.h"
56
59
+#include "sysemu/qtest.h"
57
-static SlirpState *slirp_lookup(Monitor *mon, const char *vlan,
60
#include "net/filter.h"
58
- const char *stack)
61
#include "qapi/string-output-visitor.h"
59
+static SlirpState *slirp_lookup(Monitor *mon, const char *hub_id,
62
60
+ const char *name)
63
@@ -XXX,XX +XXX,XX @@ void hmp_host_net_add(Monitor *mon, const QDict *qdict)
61
{
64
const char *opts_str = qdict_get_try_str(qdict, "opts");
62
-
65
Error *local_err = NULL;
63
- if (vlan) {
66
QemuOpts *opts;
64
+ if (name) {
67
+ static bool warned;
65
NetClientState *nc;
68
+
66
- nc = net_hub_find_client_by_name(strtol(vlan, NULL, 0), stack);
69
+ if (!warned && !qtest_enabled()) {
67
- if (!nc) {
70
+ error_report("host_net_add is deprecated, use netdev_add instead");
68
- monitor_printf(mon, "unrecognized (vlan-id, stackname) pair\n");
71
+ warned = true;
69
- return NULL;
72
+ }
70
+ if (hub_id) {
73
71
+ nc = net_hub_find_client_by_name(strtol(hub_id, NULL, 0), name);
74
if (!net_host_check_device(device)) {
72
+ if (!nc) {
75
monitor_printf(mon, "invalid host network device %s\n", device);
73
+ monitor_printf(mon, "unrecognized (vlan-id, stackname) pair\n");
76
@@ -XXX,XX +XXX,XX @@ void hmp_host_net_remove(Monitor *mon, const QDict *qdict)
74
+ return NULL;
77
NetClientState *nc;
75
+ }
78
int vlan_id = qdict_get_int(qdict, "vlan_id");
76
+ } else {
79
const char *device = qdict_get_str(qdict, "device");
77
+ nc = qemu_find_netdev(name);
80
+ static bool warned;
78
+ if (!nc) {
81
+
79
+ monitor_printf(mon, "unrecognized netdev id '%s'\n", name);
82
+ if (!warned && !qtest_enabled()) {
80
+ return NULL;
83
+ error_report("host_net_remove is deprecated, use netdev_del instead");
81
+ }
84
+ warned = true;
82
}
85
+ }
83
if (strcmp(nc->model, "user")) {
86
84
monitor_printf(mon, "invalid device specified\n");
87
nc = net_hub_find_client_by_name(vlan_id, device);
85
@@ -XXX,XX +XXX,XX @@ void hmp_hostfwd_remove(Monitor *mon, const QDict *qdict)
88
if (!nc) {
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;
89
--
113
--
90
2.7.4
114
2.7.4
91
115
92
116
diff view generated by jsdifflib
1
From: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
1
From: Thomas Huth <thuth@redhat.com>
2
2
3
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
3
The vlan concept is marked as deprecated, so we should not use
4
this for examples in the documentation anymore.
5
6
Signed-off-by: Thomas Huth <thuth@redhat.com>
4
Signed-off-by: Jason Wang <jasowang@redhat.com>
7
Signed-off-by: Jason Wang <jasowang@redhat.com>
5
---
8
---
6
qemu-options.hx | 2 +-
9
qemu-options.hx | 4 ++--
7
1 file changed, 1 insertion(+), 1 deletion(-)
10
1 file changed, 2 insertions(+), 2 deletions(-)
8
11
9
diff --git a/qemu-options.hx b/qemu-options.hx
12
diff --git a/qemu-options.hx b/qemu-options.hx
10
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
11
--- a/qemu-options.hx
14
--- a/qemu-options.hx
12
+++ b/qemu-options.hx
15
+++ b/qemu-options.hx
13
@@ -XXX,XX +XXX,XX @@ Create a filter-redirector we need to differ outdev id from indev id, id can not
16
@@ -XXX,XX +XXX,XX @@ qemu-system-i386 linux.img -net nic -net tap
14
be the same. we can just use indev or outdev, but at least one of indev or outdev
17
#launch a QEMU instance with two NICs, each one connected
15
need to be specified.
18
#to a TAP device
16
19
qemu-system-i386 linux.img \
17
-@item -object filter-rewriter,id=@var{id},netdev=@var{netdevid},rewriter-mode=@var{mode}[,queue=@var{all|rx|tx}]
20
- -net nic,vlan=0 -net tap,vlan=0,ifname=tap0 \
18
+@item -object filter-rewriter,id=@var{id},netdev=@var{netdevid}[,queue=@var{all|rx|tx}]
21
- -net nic,vlan=1 -net tap,vlan=1,ifname=tap1
19
22
+ -netdev tap,id=nd0,ifname=tap0 -device e1000,netdev=nd0 \
20
Filter-rewriter is a part of COLO project.It will rewrite tcp packet to
23
+ -netdev tap,id=nd1,ifname=tap1 -device rtl8139,netdev=nd1
21
secondary from primary to keep secondary tcp connection,and rewrite
24
@end example
25
26
@example
22
--
27
--
23
2.7.4
28
2.7.4
24
29
25
30
diff view generated by jsdifflib
1
From: Yunjian Wang <wangyunjian@huawei.com>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
The tx_bh or tx_timer will free in virtio_net_del_queue() function, when
3
gently asked by his automatic reply :)
4
removing virtio-net queues if the guest doesn't support multiqueue. But
5
it might be still referenced by virtio_net_set_status(), which needs to
6
be set NULL. And also the tx_waiting needs to be set zero to prevent
7
virtio_net_set_status() accessing tx_bh or tx_timer.
8
4
9
Cc: qemu-stable@nongnu.org
5
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Signed-off-by: Yunjian Wang <wangyunjian@huawei.com>
11
Signed-off-by: Jason Wang <jasowang@redhat.com>
6
Signed-off-by: Jason Wang <jasowang@redhat.com>
12
---
7
---
13
hw/net/virtio-net.c | 3 +++
8
MAINTAINERS | 8 ++++----
14
1 file changed, 3 insertions(+)
9
1 file changed, 4 insertions(+), 4 deletions(-)
15
10
16
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
11
diff --git a/MAINTAINERS b/MAINTAINERS
17
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/net/virtio-net.c
13
--- a/MAINTAINERS
19
+++ b/hw/net/virtio-net.c
14
+++ b/MAINTAINERS
20
@@ -XXX,XX +XXX,XX @@ static void virtio_net_del_queue(VirtIONet *n, int index)
15
@@ -XXX,XX +XXX,XX @@ F: hw/scsi/mfi.h
21
if (q->tx_timer) {
16
F: tests/megasas-test.c
22
timer_del(q->tx_timer);
17
23
timer_free(q->tx_timer);
18
Network packet abstractions
24
+ q->tx_timer = NULL;
19
-M: Dmitry Fleytman <dmitry@daynix.com>
25
} else {
20
+M: Dmitry Fleytman <dmitry.fleytman@gmail.com>
26
qemu_bh_delete(q->tx_bh);
21
S: Maintained
27
+ q->tx_bh = NULL;
22
F: include/net/eth.h
28
}
23
F: net/eth.c
29
+ q->tx_waiting = 0;
24
@@ -XXX,XX +XXX,XX @@ F: hw/net/net_rx_pkt*
30
virtio_del_queue(vdev, index * 2 + 1);
25
F: hw/net/net_tx_pkt*
31
}
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*
32
47
33
--
48
--
34
2.7.4
49
2.7.4
35
50
36
51
diff view generated by jsdifflib
Deleted patch
1
From: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
2
1
3
The s->outdev have checked in filter_mirror_set_outdev().
4
5
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
6
Signed-off-by: Jason Wang <jasowang@redhat.com>
7
---
8
net/filter-mirror.c | 6 ------
9
1 file changed, 6 deletions(-)
10
11
diff --git a/net/filter-mirror.c b/net/filter-mirror.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/net/filter-mirror.c
14
+++ b/net/filter-mirror.c
15
@@ -XXX,XX +XXX,XX @@ static void filter_mirror_setup(NetFilterState *nf, Error **errp)
16
MirrorState *s = FILTER_MIRROR(nf);
17
Chardev *chr;
18
19
- if (!s->outdev) {
20
- error_setg(errp, "filter mirror needs 'outdev' "
21
- "property set");
22
- return;
23
- }
24
-
25
chr = qemu_chr_find(s->outdev);
26
if (chr == NULL) {
27
error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
28
--
29
2.7.4
30
31
diff view generated by jsdifflib