1
The following changes since commit 6632f6ff96f0537fc34cdc00c760656fc62e23c5:
1
The following changes since commit cda4a338c4243fa3bff4498b935340ac7121cc76:
2
2
3
Merge remote-tracking branch 'remotes/famz/tags/block-and-testing-pull-request' into staging (2017-07-17 11:46:36 +0100)
3
tcg/tci: Add TCG_TARGET_DEFAULT_MO (2017-09-07 18:57:34 +0100)
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 189ae6bb5ce1f5a322f8691d00fe942ba43dd601:
9
for you to fetch changes up to 861d51e62bb197b43606f888dbefbabebaf0d854:
10
10
11
virtio-net: fix offload ctrl endian (2017-07-17 20:13:56 +0800)
11
colo-compare: Update the COLO document to add the IOThread configuration (2017-09-08 09:34:40 +0800)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
14
15
- fix virtio-net ctrl offload endian
15
----------------------------------------------------------------
16
- vnet header support for variou COLO netfilters and compare thread
16
Kamil Rytarowski (1):
17
e1000: Rename the SEC symbol to SEQEC
17
18
18
----------------------------------------------------------------
19
Mao Zhongyi (8):
19
Jason Wang (1):
20
net/rocker: Remove the dead error handling
20
virtio-net: fix offload ctrl endian
21
net/rocker: Plug memory leak in pci_rocker_init()
22
net/rocker: Convert to realize()
23
net/rocker: Fix the unusual macro name
24
net/socket: Don't treat odd socket type as SOCK_STREAM
25
net/socket: Convert several helper functions to Error
26
net/net: Convert parse_host_port() to Error
27
net/socket: Improve -net socket error reporting
21
28
22
Michal Privoznik (1):
29
Matt Parker (1):
23
virtion-net: Prefer is_power_of_2()
30
net: rtl8139: do not use old_mmio accesses
24
31
25
Zhang Chen (12):
32
Wang Yong (3):
26
net: Add vnet_hdr_len arguments in NetClientState
33
qemu-iothread: IOThread supports the GMainContext event loop
27
net/net.c: Add vnet_hdr support in SocketReadState
34
colo-compare: Use IOThread to Check old packet regularly and Process pactkets of the primary
28
net/filter-mirror.c: Introduce parameter for filter_send()
35
colo-compare: Update the COLO document to add the IOThread configuration
29
net/filter-mirror.c: Make filter mirror support vnet support.
30
net/filter-mirror.c: Add new option to enable vnet support for filter-redirector
31
net/colo.c: Make vnet_hdr_len as packet property
32
net/colo-compare.c: Introduce parameter for compare_chr_send()
33
net/colo-compare.c: Make colo-compare support vnet_hdr_len
34
net/colo.c: Add vnet packet parse feature in colo-proxy
35
net/colo-compare.c: Add vnet packet's tcp/udp/icmp compare
36
net/filter-rewriter.c: Make filter-rewriter support vnet_hdr_len
37
docs/colo-proxy.txt: Update colo-proxy usage of net driver with vnet_header
38
36
39
docs/colo-proxy.txt | 26 ++++++++++++++++
37
Zhang Chen (5):
40
hw/net/virtio-net.c | 4 ++-
38
net/filter-rewriter.c: Fix rewirter checksum bug when use virtio-net
41
include/net/net.h | 10 ++++--
39
MAINTAINERS: Update mail address for COLO Proxy
42
net/colo-compare.c | 84 ++++++++++++++++++++++++++++++++++++++++++---------
40
net/colo-compare.c: Optimize unpredictable tcp options comparison
43
net/colo.c | 9 +++---
41
net/colo-compare.c: Adjust net queue pop order for performance
44
net/colo.h | 4 ++-
42
net/colo-compare.c: Fix comments and scheme
45
net/filter-mirror.c | 75 +++++++++++++++++++++++++++++++++++++++++----
43
46
net/filter-rewriter.c | 37 ++++++++++++++++++++++-
44
MAINTAINERS | 2 +-
47
net/net.c | 37 ++++++++++++++++++++---
45
docs/colo-proxy.txt | 3 +-
48
net/socket.c | 8 ++---
46
hw/net/e1000.c | 4 +-
49
qemu-options.hx | 19 ++++++------
47
hw/net/e1000_regs.h | 2 +-
50
11 files changed, 265 insertions(+), 48 deletions(-)
48
hw/net/e1000e_core.c | 2 +-
49
hw/net/e1000x_common.h | 2 +-
50
hw/net/rocker/rocker.c | 94 ++++++----------------
51
hw/net/rocker/rocker_desc.c | 10 ---
52
hw/net/rocker/rocker_fp.c | 4 -
53
hw/net/rocker/rocker_of_dpa.c | 20 -----
54
hw/net/rocker/rocker_world.c | 12 ++-
55
hw/net/rtl8139.c | 53 +-----------
56
include/qemu/sockets.h | 3 +-
57
include/sysemu/iothread.h | 4 +
58
iothread.c | 45 +++++++++++
59
net/colo-compare.c | 183 ++++++++++++++++++++++++------------------
60
net/filter-rewriter.c | 6 +-
61
net/net.c | 22 +++--
62
net/socket.c | 156 +++++++++++++++++++----------------
63
19 files changed, 304 insertions(+), 323 deletions(-)
51
64
52
65
diff view generated by jsdifflib
1
From: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
1
From: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
2
2
3
We add the vnet_hdr_support option for filter-rewriter, default is disabled.
3
Because vnet_hdr have a offset to net packet, we must add it when use
4
If you use virtio-net-pci or other driver needs vnet_hdr, please enable it.
4
virtio-net.
5
You can use it for example:
6
-object filter-rewriter,id=rew0,netdev=hn0,queue=all,vnet_hdr_support
7
8
We get the vnet_hdr_len from NetClientState that make us
9
parse net packet correctly.
10
5
11
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
6
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
12
Signed-off-by: Jason Wang <jasowang@redhat.com>
7
Signed-off-by: Jason Wang <jasowang@redhat.com>
13
---
8
---
14
net/filter-rewriter.c | 37 ++++++++++++++++++++++++++++++++++++-
9
net/filter-rewriter.c | 6 ++++--
15
qemu-options.hx | 4 ++--
10
1 file changed, 4 insertions(+), 2 deletions(-)
16
2 files changed, 38 insertions(+), 3 deletions(-)
17
11
18
diff --git a/net/filter-rewriter.c b/net/filter-rewriter.c
12
diff --git a/net/filter-rewriter.c b/net/filter-rewriter.c
19
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
20
--- a/net/filter-rewriter.c
14
--- a/net/filter-rewriter.c
21
+++ b/net/filter-rewriter.c
15
+++ b/net/filter-rewriter.c
22
@@ -XXX,XX +XXX,XX @@
16
@@ -XXX,XX +XXX,XX @@ static int handle_primary_tcp_pkt(NetFilterState *nf,
23
#include "qemu-common.h"
17
/* handle packets to the secondary from the primary */
24
#include "qapi/error.h"
18
tcp_pkt->th_ack = htonl(ntohl(tcp_pkt->th_ack) + conn->offset);
25
#include "qapi/qmp/qerror.h"
19
26
+#include "qemu/error-report.h"
20
- net_checksum_calculate((uint8_t *)pkt->data, pkt->size);
27
#include "qapi-visit.h"
21
+ net_checksum_calculate((uint8_t *)pkt->data + pkt->vnet_hdr_len,
28
#include "qom/object.h"
22
+ pkt->size - pkt->vnet_hdr_len);
29
#include "qemu/main-loop.h"
23
}
30
@@ -XXX,XX +XXX,XX @@ typedef struct RewriterState {
24
}
31
NetQueue *incoming_queue;
25
32
/* hashtable to save connection */
26
@@ -XXX,XX +XXX,XX @@ static int handle_secondary_tcp_pkt(NetFilterState *nf,
33
GHashTable *connection_track_table;
27
/* handle packets to the primary from the secondary*/
34
+ bool vnet_hdr;
28
tcp_pkt->th_seq = htonl(ntohl(tcp_pkt->th_seq) - conn->offset);
35
} RewriterState;
29
36
30
- net_checksum_calculate((uint8_t *)pkt->data, pkt->size);
37
static void filter_rewriter_flush(NetFilterState *nf)
31
+ net_checksum_calculate((uint8_t *)pkt->data + pkt->vnet_hdr_len,
38
@@ -XXX,XX +XXX,XX @@ static ssize_t colo_rewriter_receive_iov(NetFilterState *nf,
32
+ pkt->size - pkt->vnet_hdr_len);
39
ConnectionKey key;
33
}
40
Packet *pkt;
34
}
41
ssize_t size = iov_size(iov, iovcnt);
35
42
+ ssize_t vnet_hdr_len = 0;
43
char *buf = g_malloc0(size);
44
45
iov_to_buf(iov, iovcnt, 0, buf, size);
46
- pkt = packet_new(buf, size, 0);
47
+
48
+ if (s->vnet_hdr) {
49
+ vnet_hdr_len = nf->netdev->vnet_hdr_len;
50
+ }
51
+
52
+ pkt = packet_new(buf, size, vnet_hdr_len);
53
g_free(buf);
54
55
/*
56
@@ -XXX,XX +XXX,XX @@ static void colo_rewriter_setup(NetFilterState *nf, Error **errp)
57
s->incoming_queue = qemu_new_net_queue(qemu_netfilter_pass_to_next, nf);
58
}
59
60
+static bool filter_rewriter_get_vnet_hdr(Object *obj, Error **errp)
61
+{
62
+ RewriterState *s = FILTER_COLO_REWRITER(obj);
63
+
64
+ return s->vnet_hdr;
65
+}
66
+
67
+static void filter_rewriter_set_vnet_hdr(Object *obj,
68
+ bool value,
69
+ Error **errp)
70
+{
71
+ RewriterState *s = FILTER_COLO_REWRITER(obj);
72
+
73
+ s->vnet_hdr = value;
74
+}
75
+
76
+static void filter_rewriter_init(Object *obj)
77
+{
78
+ RewriterState *s = FILTER_COLO_REWRITER(obj);
79
+
80
+ s->vnet_hdr = false;
81
+ object_property_add_bool(obj, "vnet_hdr_support",
82
+ filter_rewriter_get_vnet_hdr,
83
+ filter_rewriter_set_vnet_hdr, NULL);
84
+}
85
+
86
static void colo_rewriter_class_init(ObjectClass *oc, void *data)
87
{
88
NetFilterClass *nfc = NETFILTER_CLASS(oc);
89
@@ -XXX,XX +XXX,XX @@ static const TypeInfo colo_rewriter_info = {
90
.name = TYPE_FILTER_REWRITER,
91
.parent = TYPE_NETFILTER,
92
.class_init = colo_rewriter_class_init,
93
+ .instance_init = filter_rewriter_init,
94
.instance_size = sizeof(RewriterState),
95
};
96
97
diff --git a/qemu-options.hx b/qemu-options.hx
98
index XXXXXXX..XXXXXXX 100644
99
--- a/qemu-options.hx
100
+++ b/qemu-options.hx
101
@@ -XXX,XX +XXX,XX @@ Create a filter-redirector we need to differ outdev id from indev id, id can not
102
be the same. we can just use indev or outdev, but at least one of indev or outdev
103
need to be specified.
104
105
-@item -object filter-rewriter,id=@var{id},netdev=@var{netdevid}[,queue=@var{all|rx|tx}]
106
+@item -object filter-rewriter,id=@var{id},netdev=@var{netdevid},queue=@var{all|rx|tx},[vnet_hdr_support]
107
108
Filter-rewriter is a part of COLO project.It will rewrite tcp packet to
109
secondary from primary to keep secondary tcp connection,and rewrite
110
tcp packet to primary from secondary make tcp packet can be handled by
111
-client.
112
+client.if it has the vnet_hdr_support flag, we can parse packet with vnet header.
113
114
usage:
115
colo secondary:
116
--
36
--
117
2.7.4
37
2.7.4
118
38
119
39
diff view generated by jsdifflib
1
Spec said offloads should be le64, so use virtio_ldq_p() to guarantee
1
From: Mao Zhongyi <maozy.fnst@cn.fujitsu.com>
2
valid endian.
2
3
3
Memory allocation functions like world_alloc, desc_ring_alloc etc,
4
Fixes: 644c98587d4c ("virtio-net: dynamic network offloads configuration")
4
they are all wrappers around g_malloc, g_new etc. But g_malloc and
5
Cc: qemu-stable@nongnu.org
5
similar functions doesn't return null. Because they ignore the fact
6
Cc: Dmitry Fleytman <dfleytma@redhat.com>
6
that g_malloc() of 0 bytes returns null. So error checks for these
7
allocation failure are superfluous. Now, remove them entirely.
8
9
Cc: jasowang@redhat.com
10
Cc: jiri@resnulli.us
11
Cc: armbru@redhat.com
12
Cc: f4bug@amsat.org
13
Signed-off-by: Mao Zhongyi <maozy.fnst@cn.fujitsu.com>
14
Reviewed-by: Markus Armbruster <armbru@redhat.com>
7
Signed-off-by: Jason Wang <jasowang@redhat.com>
15
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
---
16
---
9
hw/net/virtio-net.c | 2 ++
17
hw/net/rocker/rocker.c | 47 +------------------------------------------
10
1 file changed, 2 insertions(+)
18
hw/net/rocker/rocker_desc.c | 10 ---------
11
19
hw/net/rocker/rocker_fp.c | 4 ----
12
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
20
hw/net/rocker/rocker_of_dpa.c | 20 ------------------
13
index XXXXXXX..XXXXXXX 100644
21
hw/net/rocker/rocker_world.c | 12 +++++------
14
--- a/hw/net/virtio-net.c
22
5 files changed, 6 insertions(+), 87 deletions(-)
15
+++ b/hw/net/virtio-net.c
23
16
@@ -XXX,XX +XXX,XX @@ static int virtio_net_handle_offloads(VirtIONet *n, uint8_t cmd,
24
diff --git a/hw/net/rocker/rocker.c b/hw/net/rocker/rocker.c
17
if (cmd == VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET) {
25
index XXXXXXX..XXXXXXX 100644
18
uint64_t supported_offloads;
26
--- a/hw/net/rocker/rocker.c
19
27
+++ b/hw/net/rocker/rocker.c
20
+ offloads = virtio_ldq_p(vdev, &offloads);
28
@@ -XXX,XX +XXX,XX @@ static int tx_consume(Rocker *r, DescInfo *info)
29
}
30
iov[iovcnt].iov_len = frag_len;
31
iov[iovcnt].iov_base = g_malloc(frag_len);
32
- if (!iov[iovcnt].iov_base) {
33
- err = -ROCKER_ENOMEM;
34
- goto err_no_mem;
35
- }
36
37
pci_dma_read(dev, frag_addr, iov[iovcnt].iov_base,
38
iov[iovcnt].iov_len);
39
@@ -XXX,XX +XXX,XX @@ static int tx_consume(Rocker *r, DescInfo *info)
40
err = fp_port_eg(r->fp_port[port], iov, iovcnt);
41
42
err_too_many_frags:
43
-err_no_mem:
44
err_bad_attr:
45
for (i = 0; i < ROCKER_TX_FRAGS_MAX; i++) {
46
g_free(iov[i].iov_base);
47
@@ -XXX,XX +XXX,XX @@ int rx_produce(World *world, uint32_t pport,
48
*/
49
50
data = g_malloc(data_size);
51
- if (!data) {
52
- err = -ROCKER_ENOMEM;
53
- goto out;
54
- }
21
+
55
+
22
if (!n->has_vnet_hdr) {
56
iov_to_buf(iov, iovcnt, 0, data, data_size);
23
return VIRTIO_NET_ERR;
57
pci_dma_write(dev, frag_addr, data, data_size);
24
}
58
g_free(data);
59
@@ -XXX,XX +XXX,XX @@ static void rocker_test_dma_ctrl(Rocker *r, uint32_t val)
60
61
buf = g_malloc(r->test_dma_size);
62
63
- if (!buf) {
64
- DPRINTF("test dma buffer alloc failed");
65
- return;
66
- }
67
-
68
switch (val) {
69
case ROCKER_TEST_DMA_CTRL_CLEAR:
70
memset(buf, 0, r->test_dma_size);
71
@@ -XXX,XX +XXX,XX @@ static int pci_rocker_init(PCIDevice *dev)
72
73
r->worlds[ROCKER_WORLD_TYPE_OF_DPA] = of_dpa_world_alloc(r);
74
75
- for (i = 0; i < ROCKER_WORLD_TYPE_MAX; i++) {
76
- if (!r->worlds[i]) {
77
- err = -ENOMEM;
78
- goto err_world_alloc;
79
- }
80
- }
81
-
82
if (!r->world_name) {
83
r->world_name = g_strdup(world_name(r->worlds[ROCKER_WORLD_TYPE_OF_DPA]));
84
}
85
@@ -XXX,XX +XXX,XX @@ static int pci_rocker_init(PCIDevice *dev)
86
}
87
88
r->rings = g_new(DescRing *, rocker_pci_ring_count(r));
89
- if (!r->rings) {
90
- goto err_rings_alloc;
91
- }
92
93
/* Rings are ordered like this:
94
* - command ring
95
@@ -XXX,XX +XXX,XX @@ static int pci_rocker_init(PCIDevice *dev)
96
* .....
97
*/
98
99
- err = -ENOMEM;
100
for (i = 0; i < rocker_pci_ring_count(r); i++) {
101
DescRing *ring = desc_ring_alloc(r, i);
102
103
- if (!ring) {
104
- goto err_ring_alloc;
105
- }
106
-
107
if (i == ROCKER_RING_CMD) {
108
desc_ring_set_consume(ring, cmd_consume, ROCKER_MSIX_VEC_CMD);
109
} else if (i == ROCKER_RING_EVENT) {
110
@@ -XXX,XX +XXX,XX @@ static int pci_rocker_init(PCIDevice *dev)
111
fp_port_alloc(r, r->name, &r->fp_start_macaddr,
112
i, &r->fp_ports_peers[i]);
113
114
- if (!port) {
115
- goto err_port_alloc;
116
- }
117
-
118
r->fp_port[i] = port;
119
fp_port_set_world(port, r->world_dflt);
120
}
121
@@ -XXX,XX +XXX,XX @@ static int pci_rocker_init(PCIDevice *dev)
122
123
return 0;
124
125
-err_port_alloc:
126
- for (--i; i >= 0; i--) {
127
- FpPort *port = r->fp_port[i];
128
- fp_port_free(port);
129
- }
130
- i = rocker_pci_ring_count(r);
131
-err_ring_alloc:
132
- for (--i; i >= 0; i--) {
133
- desc_ring_free(r->rings[i]);
134
- }
135
- g_free(r->rings);
136
-err_rings_alloc:
137
err_duplicate:
138
rocker_msix_uninit(r);
139
err_msix_init:
140
object_unparent(OBJECT(&r->msix_bar));
141
object_unparent(OBJECT(&r->mmio));
142
err_world_type_by_name:
143
-err_world_alloc:
144
for (i = 0; i < ROCKER_WORLD_TYPE_MAX; i++) {
145
if (r->worlds[i]) {
146
world_free(r->worlds[i]);
147
diff --git a/hw/net/rocker/rocker_desc.c b/hw/net/rocker/rocker_desc.c
148
index XXXXXXX..XXXXXXX 100644
149
--- a/hw/net/rocker/rocker_desc.c
150
+++ b/hw/net/rocker/rocker_desc.c
151
@@ -XXX,XX +XXX,XX @@ char *desc_get_buf(DescInfo *info, bool read_only)
152
info->buf_size = size;
153
}
154
155
- if (!info->buf) {
156
- return NULL;
157
- }
158
-
159
pci_dma_read(dev, le64_to_cpu(info->desc.buf_addr), info->buf, size);
160
161
return info->buf;
162
@@ -XXX,XX +XXX,XX @@ bool desc_ring_set_size(DescRing *ring, uint32_t size)
163
ring->head = ring->tail = 0;
164
165
ring->info = g_renew(DescInfo, ring->info, size);
166
- if (!ring->info) {
167
- return false;
168
- }
169
170
memset(ring->info, 0, size * sizeof(DescInfo));
171
172
@@ -XXX,XX +XXX,XX @@ DescRing *desc_ring_alloc(Rocker *r, int index)
173
DescRing *ring;
174
175
ring = g_new0(DescRing, 1);
176
- if (!ring) {
177
- return NULL;
178
- }
179
180
ring->r = r;
181
ring->index = index;
182
diff --git a/hw/net/rocker/rocker_fp.c b/hw/net/rocker/rocker_fp.c
183
index XXXXXXX..XXXXXXX 100644
184
--- a/hw/net/rocker/rocker_fp.c
185
+++ b/hw/net/rocker/rocker_fp.c
186
@@ -XXX,XX +XXX,XX @@ FpPort *fp_port_alloc(Rocker *r, char *sw_name,
187
{
188
FpPort *port = g_new0(FpPort, 1);
189
190
- if (!port) {
191
- return NULL;
192
- }
193
-
194
port->r = r;
195
port->index = index;
196
port->pport = index + 1;
197
diff --git a/hw/net/rocker/rocker_of_dpa.c b/hw/net/rocker/rocker_of_dpa.c
198
index XXXXXXX..XXXXXXX 100644
199
--- a/hw/net/rocker/rocker_of_dpa.c
200
+++ b/hw/net/rocker/rocker_of_dpa.c
201
@@ -XXX,XX +XXX,XX @@ static OfDpaFlow *of_dpa_flow_alloc(uint64_t cookie)
202
int64_t now = qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) / 1000;
203
204
flow = g_new0(OfDpaFlow, 1);
205
- if (!flow) {
206
- return NULL;
207
- }
208
209
flow->cookie = cookie;
210
flow->mask.tbl_id = 0xffffffff;
211
@@ -XXX,XX +XXX,XX @@ static OfDpaGroup *of_dpa_group_alloc(uint32_t id)
212
{
213
OfDpaGroup *group = g_new0(OfDpaGroup, 1);
214
215
- if (!group) {
216
- return NULL;
217
- }
218
-
219
group->id = id;
220
221
return group;
222
@@ -XXX,XX +XXX,XX @@ static int of_dpa_cmd_flow_add(OfDpa *of_dpa, uint64_t cookie,
223
}
224
225
flow = of_dpa_flow_alloc(cookie);
226
- if (!flow) {
227
- return -ROCKER_ENOMEM;
228
- }
229
230
err = of_dpa_cmd_flow_add_mod(of_dpa, flow, flow_tlvs);
231
if (err) {
232
@@ -XXX,XX +XXX,XX @@ static int of_dpa_cmd_add_l2_flood(OfDpa *of_dpa, OfDpaGroup *group,
233
rocker_tlv_get_le16(group_tlvs[ROCKER_TLV_OF_DPA_GROUP_COUNT]);
234
235
tlvs = g_new0(RockerTlv *, group->l2_flood.group_count + 1);
236
- if (!tlvs) {
237
- return -ROCKER_ENOMEM;
238
- }
239
240
g_free(group->l2_flood.group_ids);
241
group->l2_flood.group_ids =
242
g_new0(uint32_t, group->l2_flood.group_count);
243
- if (!group->l2_flood.group_ids) {
244
- err = -ROCKER_ENOMEM;
245
- goto err_out;
246
- }
247
248
rocker_tlv_parse_nested(tlvs, group->l2_flood.group_count,
249
group_tlvs[ROCKER_TLV_OF_DPA_GROUP_IDS]);
250
@@ -XXX,XX +XXX,XX @@ static int of_dpa_cmd_group_add(OfDpa *of_dpa, uint32_t group_id,
251
}
252
253
group = of_dpa_group_alloc(group_id);
254
- if (!group) {
255
- return -ROCKER_ENOMEM;
256
- }
257
258
err = of_dpa_cmd_group_do(of_dpa, group_id, group, group_tlvs);
259
if (err) {
260
diff --git a/hw/net/rocker/rocker_world.c b/hw/net/rocker/rocker_world.c
261
index XXXXXXX..XXXXXXX 100644
262
--- a/hw/net/rocker/rocker_world.c
263
+++ b/hw/net/rocker/rocker_world.c
264
@@ -XXX,XX +XXX,XX @@ World *world_alloc(Rocker *r, size_t sizeof_private,
265
{
266
World *w = g_malloc0(sizeof(World) + sizeof_private);
267
268
- if (w) {
269
- w->r = r;
270
- w->type = type;
271
- w->ops = ops;
272
- if (w->ops->init) {
273
- w->ops->init(w);
274
- }
275
+ w->r = r;
276
+ w->type = type;
277
+ w->ops = ops;
278
+ if (w->ops->init) {
279
+ w->ops->init(w);
280
}
281
282
return w;
25
--
283
--
26
2.7.4
284
2.7.4
27
285
28
286
diff view generated by jsdifflib
New patch
1
From: Mao Zhongyi <maozy.fnst@cn.fujitsu.com>
1
2
3
pci_rocker_init() leaks a World when the name more than 9 chars,
4
then return a negative value directly, doesn't make a correct
5
cleanup. So add a new goto label to fix it.
6
7
Cc: jasowang@redhat.com
8
Cc: jiri@resnulli.us
9
Cc: armbru@redhat.com
10
Cc: f4bug@amsat.org
11
Signed-off-by: Mao Zhongyi <maozy.fnst@cn.fujitsu.com>
12
Reviewed-by: Markus Armbruster <armbru@redhat.com>
13
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
Signed-off-by: Jason Wang <jasowang@redhat.com>
15
---
16
hw/net/rocker/rocker.c | 4 +++-
17
1 file changed, 3 insertions(+), 1 deletion(-)
18
19
diff --git a/hw/net/rocker/rocker.c b/hw/net/rocker/rocker.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/net/rocker/rocker.c
22
+++ b/hw/net/rocker/rocker.c
23
@@ -XXX,XX +XXX,XX @@ static int pci_rocker_init(PCIDevice *dev)
24
fprintf(stderr,
25
"rocker: name too long; please shorten to at most %d chars\n",
26
MAX_ROCKER_NAME_LEN);
27
- return -EINVAL;
28
+ err = -EINVAL;
29
+ goto err_name_too_long;
30
}
31
32
if (memcmp(&r->fp_start_macaddr, &zero, sizeof(zero)) == 0) {
33
@@ -XXX,XX +XXX,XX @@ static int pci_rocker_init(PCIDevice *dev)
34
35
return 0;
36
37
+err_name_too_long:
38
err_duplicate:
39
rocker_msix_uninit(r);
40
err_msix_init:
41
--
42
2.7.4
43
44
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
This patch change the filter_send() parameter from CharBackend to MirrorState,
3
The rocker device still implements the old PCIDeviceClass .init()
4
we can get more information like vnet_hdr(We use it to support packet with vnet_header).
4
instead of the new .realize(). All devices need to be converted to
5
.realize().
5
6
6
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
7
.init() reports errors with fprintf() and return 0 on success, negative
8
number on failure. Meanwhile, when -device rocker fails, it first report
9
a specific error, then a generic one, like this:
10
11
$ x86_64-softmmu/qemu-system-x86_64 -device rocker,name=qemu-rocker
12
rocker: name too long; please shorten to at most 9 chars
13
qemu-system-x86_64: -device rocker,name=qemu-rocker: Device initialization failed
14
15
Now, convert it to .realize() that passes errors to its callers via its
16
errp argument. Also avoid the superfluous second error message. After
17
the patch, effect like this:
18
19
$ x86_64-softmmu/qemu-system-x86_64 -device rocker,name=qemu-rocker
20
qemu-system-x86_64: -device rocker,name=qemu-rocker: name too long; please shorten to at most 9 chars
21
22
Cc: jasowang@redhat.com
23
Cc: jiri@resnulli.us
24
Cc: armbru@redhat.com
25
Cc: f4bug@amsat.org
26
Signed-off-by: Mao Zhongyi <maozy.fnst@cn.fujitsu.com>
27
Reviewed-by: Markus Armbruster <armbru@redhat.com>
28
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Signed-off-by: Jason Wang <jasowang@redhat.com>
29
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
---
30
---
9
net/filter-mirror.c | 10 +++++-----
31
hw/net/rocker/rocker.c | 27 +++++++++++----------------
10
1 file changed, 5 insertions(+), 5 deletions(-)
32
1 file changed, 11 insertions(+), 16 deletions(-)
11
33
12
diff --git a/net/filter-mirror.c b/net/filter-mirror.c
34
diff --git a/hw/net/rocker/rocker.c b/hw/net/rocker/rocker.c
13
index XXXXXXX..XXXXXXX 100644
35
index XXXXXXX..XXXXXXX 100644
14
--- a/net/filter-mirror.c
36
--- a/hw/net/rocker/rocker.c
15
+++ b/net/filter-mirror.c
37
+++ b/hw/net/rocker/rocker.c
16
@@ -XXX,XX +XXX,XX @@ typedef struct MirrorState {
38
@@ -XXX,XX +XXX,XX @@ rollback:
17
SocketReadState rs;
39
return err;
18
} MirrorState;
40
}
19
41
20
-static int filter_send(CharBackend *chr_out,
42
-static int rocker_msix_init(Rocker *r)
21
+static int filter_send(MirrorState *s,
43
+static int rocker_msix_init(Rocker *r, Error **errp)
22
const struct iovec *iov,
23
int iovcnt)
24
{
44
{
25
@@ -XXX,XX +XXX,XX @@ static int filter_send(CharBackend *chr_out,
45
PCIDevice *dev = PCI_DEVICE(r);
46
int err;
47
- Error *local_err = NULL;
48
49
err = msix_init(dev, ROCKER_MSIX_VEC_COUNT(r->fp_ports),
50
&r->msix_bar,
51
ROCKER_PCI_MSIX_BAR_IDX, ROCKER_PCI_MSIX_TABLE_OFFSET,
52
&r->msix_bar,
53
ROCKER_PCI_MSIX_BAR_IDX, ROCKER_PCI_MSIX_PBA_OFFSET,
54
- 0, &local_err);
55
+ 0, errp);
56
if (err) {
57
- error_report_err(local_err);
58
return err;
26
}
59
}
27
60
28
len = htonl(size);
61
@@ -XXX,XX +XXX,XX @@ static World *rocker_world_type_by_name(Rocker *r, const char *name)
29
- ret = qemu_chr_fe_write_all(chr_out, (uint8_t *)&len, sizeof(len));
62
return NULL;
30
+ ret = qemu_chr_fe_write_all(&s->chr_out, (uint8_t *)&len, sizeof(len));
63
}
31
if (ret != sizeof(len)) {
64
32
goto err;
65
-static int pci_rocker_init(PCIDevice *dev)
66
+static void pci_rocker_realize(PCIDevice *dev, Error **errp)
67
{
68
Rocker *r = to_rocker(dev);
69
const MACAddr zero = { .a = { 0, 0, 0, 0, 0, 0 } };
70
@@ -XXX,XX +XXX,XX @@ static int pci_rocker_init(PCIDevice *dev)
71
72
r->world_dflt = rocker_world_type_by_name(r, r->world_name);
73
if (!r->world_dflt) {
74
- fprintf(stderr,
75
- "rocker: requested world \"%s\" does not exist\n",
76
+ error_setg(errp,
77
+ "invalid argument requested world %s does not exist",
78
r->world_name);
79
- err = -EINVAL;
80
goto err_world_type_by_name;
33
}
81
}
34
82
35
buf = g_malloc(size);
83
@@ -XXX,XX +XXX,XX @@ static int pci_rocker_init(PCIDevice *dev)
36
iov_to_buf(iov, iovcnt, 0, buf, size);
84
37
- ret = qemu_chr_fe_write_all(chr_out, (uint8_t *)buf, size);
85
/* MSI-X init */
38
+ ret = qemu_chr_fe_write_all(&s->chr_out, (uint8_t *)buf, size);
86
39
g_free(buf);
87
- err = rocker_msix_init(r);
40
if (ret != size) {
88
+ err = rocker_msix_init(r, errp);
41
goto err;
89
if (err) {
42
@@ -XXX,XX +XXX,XX @@ static ssize_t filter_mirror_receive_iov(NetFilterState *nf,
90
goto err_msix_init;
43
MirrorState *s = FILTER_MIRROR(nf);
44
int ret;
45
46
- ret = filter_send(&s->chr_out, iov, iovcnt);
47
+ ret = filter_send(s, iov, iovcnt);
48
if (ret) {
49
error_report("filter mirror send failed(%s)", strerror(-ret));
50
}
91
}
51
@@ -XXX,XX +XXX,XX @@ static ssize_t filter_redirector_receive_iov(NetFilterState *nf,
92
@@ -XXX,XX +XXX,XX @@ static int pci_rocker_init(PCIDevice *dev)
52
int ret;
93
}
53
94
54
if (qemu_chr_fe_backend_connected(&s->chr_out)) {
95
if (rocker_find(r->name)) {
55
- ret = filter_send(&s->chr_out, iov, iovcnt);
96
- err = -EEXIST;
56
+ ret = filter_send(s, iov, iovcnt);
97
+ error_setg(errp, "%s already exists", r->name);
57
if (ret) {
98
goto err_duplicate;
58
error_report("filter redirector send failed(%s)", strerror(-ret));
99
}
100
101
@@ -XXX,XX +XXX,XX @@ static int pci_rocker_init(PCIDevice *dev)
102
#define ROCKER_IFNAMSIZ 16
103
#define MAX_ROCKER_NAME_LEN (ROCKER_IFNAMSIZ - 1 - 3 - 3)
104
if (strlen(r->name) > MAX_ROCKER_NAME_LEN) {
105
- fprintf(stderr,
106
- "rocker: name too long; please shorten to at most %d chars\n",
107
+ error_setg(errp,
108
+ "name too long; please shorten to at most %d chars",
109
MAX_ROCKER_NAME_LEN);
110
- err = -EINVAL;
111
goto err_name_too_long;
112
}
113
114
@@ -XXX,XX +XXX,XX @@ static int pci_rocker_init(PCIDevice *dev)
115
116
QLIST_INSERT_HEAD(&rockers, r, next);
117
118
- return 0;
119
+ return;
120
121
err_name_too_long:
122
err_duplicate:
123
@@ -XXX,XX +XXX,XX @@ err_world_type_by_name:
124
world_free(r->worlds[i]);
59
}
125
}
126
}
127
- return err;
128
}
129
130
static void pci_rocker_uninit(PCIDevice *dev)
131
@@ -XXX,XX +XXX,XX @@ static void rocker_class_init(ObjectClass *klass, void *data)
132
DeviceClass *dc = DEVICE_CLASS(klass);
133
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
134
135
- k->init = pci_rocker_init;
136
+ k->realize = pci_rocker_realize;
137
k->exit = pci_rocker_uninit;
138
k->vendor_id = PCI_VENDOR_ID_REDHAT;
139
k->device_id = PCI_DEVICE_ID_REDHAT_ROCKER;
60
--
140
--
61
2.7.4
141
2.7.4
62
142
63
143
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
Add vnet_hdr_len arguments in NetClientState
3
Cc: jasowang@redhat.com
4
that make other module get real vnet_hdr_len easily.
4
Cc: jiri@resnulli.us
5
5
Cc: armbru@redhat.com
6
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
6
Cc: f4bug@amsat.org
7
Suggested-by: Markus Armbruster <armbru@redhat.com>
8
Signed-off-by: Mao Zhongyi <maozy.fnst@cn.fujitsu.com>
9
Reviewed-by: Markus Armbruster <armbru@redhat.com>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Signed-off-by: Jason Wang <jasowang@redhat.com>
11
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
---
12
---
9
include/net/net.h | 1 +
13
hw/net/rocker/rocker.c | 18 +++++++++---------
10
net/net.c | 1 +
14
1 file changed, 9 insertions(+), 9 deletions(-)
11
2 files changed, 2 insertions(+)
12
15
13
diff --git a/include/net/net.h b/include/net/net.h
16
diff --git a/hw/net/rocker/rocker.c b/hw/net/rocker/rocker.c
14
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
15
--- a/include/net/net.h
18
--- a/hw/net/rocker/rocker.c
16
+++ b/include/net/net.h
19
+++ b/hw/net/rocker/rocker.c
17
@@ -XXX,XX +XXX,XX @@ struct NetClientState {
20
@@ -XXX,XX +XXX,XX @@ struct rocker {
18
unsigned int queue_index;
21
QLIST_ENTRY(rocker) next;
19
unsigned rxfilter_notify_enabled:1;
20
int vring_enable;
21
+ int vnet_hdr_len;
22
QTAILQ_HEAD(NetFilterHead, NetFilterState) filters;
23
};
22
};
24
23
25
diff --git a/net/net.c b/net/net.c
24
-#define ROCKER "rocker"
26
index XXXXXXX..XXXXXXX 100644
25
+#define TYPE_ROCKER "rocker"
27
--- a/net/net.c
26
28
+++ b/net/net.c
27
-#define to_rocker(obj) \
29
@@ -XXX,XX +XXX,XX @@ void qemu_set_vnet_hdr_len(NetClientState *nc, int len)
28
- OBJECT_CHECK(Rocker, (obj), ROCKER)
30
return;
29
+#define ROCKER(obj) \
30
+ OBJECT_CHECK(Rocker, (obj), TYPE_ROCKER)
31
32
static QLIST_HEAD(, rocker) rockers;
33
34
@@ -XXX,XX +XXX,XX @@ static World *rocker_world_type_by_name(Rocker *r, const char *name)
35
36
static void pci_rocker_realize(PCIDevice *dev, Error **errp)
37
{
38
- Rocker *r = to_rocker(dev);
39
+ Rocker *r = ROCKER(dev);
40
const MACAddr zero = { .a = { 0, 0, 0, 0, 0, 0 } };
41
const MACAddr dflt = { .a = { 0x52, 0x54, 0x00, 0x12, 0x35, 0x01 } };
42
static int sw_index;
43
@@ -XXX,XX +XXX,XX @@ static void pci_rocker_realize(PCIDevice *dev, Error **errp)
44
/* validate switch properties */
45
46
if (!r->name) {
47
- r->name = g_strdup(ROCKER);
48
+ r->name = g_strdup(TYPE_ROCKER);
31
}
49
}
32
50
33
+ nc->vnet_hdr_len = len;
51
if (rocker_find(r->name)) {
34
nc->info->set_vnet_hdr_len(nc, len);
52
@@ -XXX,XX +XXX,XX @@ err_world_type_by_name:
53
54
static void pci_rocker_uninit(PCIDevice *dev)
55
{
56
- Rocker *r = to_rocker(dev);
57
+ Rocker *r = ROCKER(dev);
58
int i;
59
60
QLIST_REMOVE(r, next);
61
@@ -XXX,XX +XXX,XX @@ static void pci_rocker_uninit(PCIDevice *dev)
62
63
static void rocker_reset(DeviceState *dev)
64
{
65
- Rocker *r = to_rocker(dev);
66
+ Rocker *r = ROCKER(dev);
67
int i;
68
69
for (i = 0; i < ROCKER_WORLD_TYPE_MAX; i++) {
70
@@ -XXX,XX +XXX,XX @@ static Property rocker_properties[] = {
71
};
72
73
static const VMStateDescription rocker_vmsd = {
74
- .name = ROCKER,
75
+ .name = TYPE_ROCKER,
76
.unmigratable = 1,
77
};
78
79
@@ -XXX,XX +XXX,XX @@ static void rocker_class_init(ObjectClass *klass, void *data)
35
}
80
}
36
81
82
static const TypeInfo rocker_info = {
83
- .name = ROCKER,
84
+ .name = TYPE_ROCKER,
85
.parent = TYPE_PCI_DEVICE,
86
.instance_size = sizeof(Rocker),
87
.class_init = rocker_class_init,
37
--
88
--
38
2.7.4
89
2.7.4
39
90
40
91
diff view generated by jsdifflib
New patch
1
From: Matt Parker <mtparkr@gmail.com>
1
2
3
Both io and memory use the same mmio functions in the rtl8139 device.
4
This patch removes the separate MemoryRegionOps and old_mmio accessors
5
for memory, and replaces it with an alias to the io memory region.
6
7
Signed-off-by: Matt Parker <mtparkr@gmail.com>
8
Signed-off-by: Jason Wang <jasowang@redhat.com>
9
---
10
hw/net/rtl8139.c | 53 +++--------------------------------------------------
11
1 file changed, 3 insertions(+), 50 deletions(-)
12
13
diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/net/rtl8139.c
16
+++ b/hw/net/rtl8139.c
17
@@ -XXX,XX +XXX,XX @@ static uint32_t rtl8139_io_readl(void *opaque, uint8_t addr)
18
19
/* */
20
21
-static void rtl8139_mmio_writeb(void *opaque, hwaddr addr, uint32_t val)
22
-{
23
- rtl8139_io_writeb(opaque, addr & 0xFF, val);
24
-}
25
-
26
-static void rtl8139_mmio_writew(void *opaque, hwaddr addr, uint32_t val)
27
-{
28
- rtl8139_io_writew(opaque, addr & 0xFF, val);
29
-}
30
-
31
-static void rtl8139_mmio_writel(void *opaque, hwaddr addr, uint32_t val)
32
-{
33
- rtl8139_io_writel(opaque, addr & 0xFF, val);
34
-}
35
-
36
-static uint32_t rtl8139_mmio_readb(void *opaque, hwaddr addr)
37
-{
38
- return rtl8139_io_readb(opaque, addr & 0xFF);
39
-}
40
-
41
-static uint32_t rtl8139_mmio_readw(void *opaque, hwaddr addr)
42
-{
43
- uint32_t val = rtl8139_io_readw(opaque, addr & 0xFF);
44
- return val;
45
-}
46
-
47
-static uint32_t rtl8139_mmio_readl(void *opaque, hwaddr addr)
48
-{
49
- uint32_t val = rtl8139_io_readl(opaque, addr & 0xFF);
50
- return val;
51
-}
52
-
53
static int rtl8139_post_load(void *opaque, int version_id)
54
{
55
RTL8139State* s = opaque;
56
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps rtl8139_io_ops = {
57
.endianness = DEVICE_LITTLE_ENDIAN,
58
};
59
60
-static const MemoryRegionOps rtl8139_mmio_ops = {
61
- .old_mmio = {
62
- .read = {
63
- rtl8139_mmio_readb,
64
- rtl8139_mmio_readw,
65
- rtl8139_mmio_readl,
66
- },
67
- .write = {
68
- rtl8139_mmio_writeb,
69
- rtl8139_mmio_writew,
70
- rtl8139_mmio_writel,
71
- },
72
- },
73
- .endianness = DEVICE_LITTLE_ENDIAN,
74
-};
75
-
76
static void rtl8139_timer(void *opaque)
77
{
78
RTL8139State *s = opaque;
79
@@ -XXX,XX +XXX,XX @@ static void pci_rtl8139_realize(PCIDevice *dev, Error **errp)
80
81
memory_region_init_io(&s->bar_io, OBJECT(s), &rtl8139_io_ops, s,
82
"rtl8139", 0x100);
83
- memory_region_init_io(&s->bar_mem, OBJECT(s), &rtl8139_mmio_ops, s,
84
- "rtl8139", 0x100);
85
+ memory_region_init_alias(&s->bar_mem, OBJECT(s), "rtl8139-mem", &s->bar_io,
86
+ 0, 0x100);
87
+
88
pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->bar_io);
89
pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->bar_mem);
90
91
--
92
2.7.4
93
94
diff view generated by jsdifflib
1
From: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
1
From: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
2
2
3
Make colo-compare and filter-rewriter can parse vnet packet.
3
My Fujitsu mail account will be disabled soon, update the mail info
4
to my private mail.
4
5
5
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
6
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
6
Signed-off-by: Jason Wang <jasowang@redhat.com>
7
Signed-off-by: Jason Wang <jasowang@redhat.com>
7
---
8
---
8
net/colo.c | 6 +++---
9
MAINTAINERS | 2 +-
9
1 file changed, 3 insertions(+), 3 deletions(-)
10
1 file changed, 1 insertion(+), 1 deletion(-)
10
11
11
diff --git a/net/colo.c b/net/colo.c
12
diff --git a/MAINTAINERS b/MAINTAINERS
12
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
13
--- a/net/colo.c
14
--- a/MAINTAINERS
14
+++ b/net/colo.c
15
+++ b/MAINTAINERS
15
@@ -XXX,XX +XXX,XX @@ int parse_packet_early(Packet *pkt)
16
@@ -XXX,XX +XXX,XX @@ F: include/migration/failover.h
16
{
17
F: docs/COLO-FT.txt
17
int network_length;
18
18
static const uint8_t vlan[] = {0x81, 0x00};
19
COLO Proxy
19
- uint8_t *data = pkt->data;
20
-M: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
20
+ uint8_t *data = pkt->data + pkt->vnet_hdr_len;
21
+M: Zhang Chen <zhangckid@gmail.com>
21
uint16_t l3_proto;
22
M: Li Zhijian <lizhijian@cn.fujitsu.com>
22
ssize_t l2hdr_len = eth_get_l2_hdr_length(data);
23
S: Supported
23
24
F: docs/colo-proxy.txt
24
- if (pkt->size < ETH_HLEN) {
25
+ if (pkt->size < ETH_HLEN + pkt->vnet_hdr_len) {
26
trace_colo_proxy_main("pkt->size < ETH_HLEN");
27
return 1;
28
}
29
@@ -XXX,XX +XXX,XX @@ int parse_packet_early(Packet *pkt)
30
}
31
32
network_length = pkt->ip->ip_hl * 4;
33
- if (pkt->size < l2hdr_len + network_length) {
34
+ if (pkt->size < l2hdr_len + network_length + pkt->vnet_hdr_len) {
35
trace_colo_proxy_main("pkt->size < network_header + network_length");
36
return 1;
37
}
38
--
25
--
39
2.7.4
26
2.7.4
40
27
41
28
diff view generated by jsdifflib
New patch
1
From: Mao Zhongyi <maozy.fnst@cn.fujitsu.com>
1
2
3
In net_socket_fd_init(), the 'default' case is odd: it warns,
4
then continues as if the socket type was SOCK_STREAM. The
5
comment explains "this could be a eg. a pty", but that makes
6
no sense. If @fd really was a pty, getsockopt() would fail
7
with ENOTSOCK. If @fd was a socket, but neither SOCK_DGRAM nor
8
SOCK_STREAM. It should not be treated as if it was SOCK_STREAM.
9
10
Turn this case into an Error. If there is a genuine reason to
11
support something like SOCK_RAW, it should be explicitly
12
handled.
13
14
Cc: jasowang@redhat.com
15
Cc: armbru@redhat.com
16
Cc: berrange@redhat.com
17
Cc: armbru@redhat.com
18
Cc: eblake@redhat.com
19
Suggested-by: Markus Armbruster <armbru@redhat.com>
20
Suggested-by: Daniel P. Berrange <berrange@redhat.com>
21
Signed-off-by: Mao Zhongyi <maozy.fnst@cn.fujitsu.com>
22
Reviewed-by: Markus Armbruster <armbru@redhat.com>
23
Signed-off-by: Jason Wang <jasowang@redhat.com>
24
---
25
net/socket.c | 6 +++---
26
1 file changed, 3 insertions(+), 3 deletions(-)
27
28
diff --git a/net/socket.c b/net/socket.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/net/socket.c
31
+++ b/net/socket.c
32
@@ -XXX,XX +XXX,XX @@ static NetSocketState *net_socket_fd_init(NetClientState *peer,
33
case SOCK_STREAM:
34
return net_socket_fd_init_stream(peer, model, name, fd, is_connected);
35
default:
36
- /* who knows ... this could be a eg. a pty, do warn and continue as stream */
37
- fprintf(stderr, "qemu: warning: socket type=%d for fd=%d is not SOCK_DGRAM or SOCK_STREAM\n", so_type, fd);
38
- return net_socket_fd_init_stream(peer, model, name, fd, is_connected);
39
+ error_report("socket type=%d for fd=%d must be either"
40
+ " SOCK_DGRAM or SOCK_STREAM", so_type, fd);
41
+ closesocket(fd);
42
}
43
return NULL;
44
}
45
--
46
2.7.4
47
48
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
We add the vnet_hdr_support option for filter-redirector, default is disabled.
3
Currently, net_socket_mcast_create(), net_socket_fd_init_dgram() and
4
If you use virtio-net-pci net driver or other driver needs vnet_hdr, please enable it.
4
net_socket_fd_init() use the function such as fprintf(), perror() to
5
Because colo-compare or other modules needs the vnet_hdr_len to parse
5
report an error message.
6
packet, we add this new option send the len to others.
6
7
You can use it for example:
7
Now, convert these functions to Error.
8
-object filter-redirector,id=r0,netdev=hn0,queue=tx,outdev=red0,vnet_hdr_support
8
9
9
Cc: jasowang@redhat.com
10
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
10
Cc: armbru@redhat.com
11
Cc: berrange@redhat.com
12
Signed-off-by: Mao Zhongyi <maozy.fnst@cn.fujitsu.com>
13
Reviewed-by: Daniel P. Berrange <berrange@redhat.com>
14
Reviewed-by: Markus Armbruster <armbru@redhat.com>
11
Signed-off-by: Jason Wang <jasowang@redhat.com>
15
Signed-off-by: Jason Wang <jasowang@redhat.com>
12
---
16
---
13
net/filter-mirror.c | 23 +++++++++++++++++++++++
17
net/socket.c | 82 ++++++++++++++++++++++++++++++++++++------------------------
14
qemu-options.hx | 6 +++---
18
1 file changed, 50 insertions(+), 32 deletions(-)
15
2 files changed, 26 insertions(+), 3 deletions(-)
19
16
20
diff --git a/net/socket.c b/net/socket.c
17
diff --git a/net/filter-mirror.c b/net/filter-mirror.c
18
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
19
--- a/net/filter-mirror.c
22
--- a/net/socket.c
20
+++ b/net/filter-mirror.c
23
+++ b/net/socket.c
21
@@ -XXX,XX +XXX,XX @@ static void filter_redirector_set_outdev(Object *obj,
24
@@ -XXX,XX +XXX,XX @@ static void net_socket_send_dgram(void *opaque)
22
s->outdev = g_strdup(value);
25
}
23
}
26
}
24
27
25
+static bool filter_redirector_get_vnet_hdr(Object *obj, Error **errp)
28
-static int net_socket_mcast_create(struct sockaddr_in *mcastaddr, struct in_addr *localaddr)
26
+{
29
+static int net_socket_mcast_create(struct sockaddr_in *mcastaddr,
27
+ MirrorState *s = FILTER_REDIRECTOR(obj);
30
+ struct in_addr *localaddr,
31
+ Error **errp)
32
{
33
struct ip_mreq imr;
34
int fd;
35
@@ -XXX,XX +XXX,XX @@ static int net_socket_mcast_create(struct sockaddr_in *mcastaddr, struct in_addr
36
#endif
37
38
if (!IN_MULTICAST(ntohl(mcastaddr->sin_addr.s_addr))) {
39
- fprintf(stderr, "qemu: error: specified mcastaddr \"%s\" (0x%08x) "
40
- "does not contain a multicast address\n",
41
- inet_ntoa(mcastaddr->sin_addr),
42
- (int)ntohl(mcastaddr->sin_addr.s_addr));
43
+ error_setg(errp, "specified mcastaddr %s (0x%08x) "
44
+ "does not contain a multicast address",
45
+ inet_ntoa(mcastaddr->sin_addr),
46
+ (int)ntohl(mcastaddr->sin_addr.s_addr));
47
return -1;
48
-
49
}
28
+
50
+
29
+ return s->vnet_hdr;
51
fd = qemu_socket(PF_INET, SOCK_DGRAM, 0);
30
+}
52
if (fd < 0) {
53
- perror("socket(PF_INET, SOCK_DGRAM)");
54
+ error_setg_errno(errp, errno, "can't create datagram socket");
55
return -1;
56
}
57
58
@@ -XXX,XX +XXX,XX @@ static int net_socket_mcast_create(struct sockaddr_in *mcastaddr, struct in_addr
59
val = 1;
60
ret = qemu_setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
61
if (ret < 0) {
62
- perror("setsockopt(SOL_SOCKET, SO_REUSEADDR)");
63
+ error_setg_errno(errp, errno,
64
+ "can't set socket option SO_REUSEADDR");
65
goto fail;
66
}
67
68
ret = bind(fd, (struct sockaddr *)mcastaddr, sizeof(*mcastaddr));
69
if (ret < 0) {
70
- perror("bind");
71
+ error_setg_errno(errp, errno, "can't bind ip=%s to socket",
72
+ inet_ntoa(mcastaddr->sin_addr));
73
goto fail;
74
}
75
76
@@ -XXX,XX +XXX,XX @@ static int net_socket_mcast_create(struct sockaddr_in *mcastaddr, struct in_addr
77
ret = qemu_setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
78
&imr, sizeof(struct ip_mreq));
79
if (ret < 0) {
80
- perror("setsockopt(IP_ADD_MEMBERSHIP)");
81
+ error_setg_errno(errp, errno,
82
+ "can't add socket to multicast group %s",
83
+ inet_ntoa(imr.imr_multiaddr));
84
goto fail;
85
}
86
87
@@ -XXX,XX +XXX,XX @@ static int net_socket_mcast_create(struct sockaddr_in *mcastaddr, struct in_addr
88
ret = qemu_setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP,
89
&loop, sizeof(loop));
90
if (ret < 0) {
91
- perror("setsockopt(SOL_IP, IP_MULTICAST_LOOP)");
92
+ error_setg_errno(errp, errno,
93
+ "can't force multicast message to loopback");
94
goto fail;
95
}
96
97
@@ -XXX,XX +XXX,XX @@ static int net_socket_mcast_create(struct sockaddr_in *mcastaddr, struct in_addr
98
ret = qemu_setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF,
99
localaddr, sizeof(*localaddr));
100
if (ret < 0) {
101
- perror("setsockopt(IP_MULTICAST_IF)");
102
+ error_setg_errno(errp, errno,
103
+ "can't set the default network send interface");
104
goto fail;
105
}
106
}
107
@@ -XXX,XX +XXX,XX @@ static NetSocketState *net_socket_fd_init_dgram(NetClientState *peer,
108
const char *model,
109
const char *name,
110
int fd, int is_connected,
111
- const char *mcast)
112
+ const char *mcast,
113
+ Error **errp)
114
{
115
struct sockaddr_in saddr;
116
int newfd;
117
@@ -XXX,XX +XXX,XX @@ static NetSocketState *net_socket_fd_init_dgram(NetClientState *peer,
118
119
if (is_connected && mcast != NULL) {
120
if (parse_host_port(&saddr, mcast) < 0) {
121
- fprintf(stderr,
122
- "qemu: error: init_dgram: fd=%d failed parse_host_port()\n",
123
- fd);
124
+ error_setg(errp, "fd=%d failed parse_host_port()", fd);
125
goto err;
126
}
127
/* must be bound */
128
if (saddr.sin_addr.s_addr == 0) {
129
- fprintf(stderr, "qemu: error: init_dgram: fd=%d unbound, "
130
- "cannot setup multicast dst addr\n", fd);
131
+ error_setg(errp, "can't setup multicast destination address");
132
goto err;
133
}
134
/* clone dgram socket */
135
- newfd = net_socket_mcast_create(&saddr, NULL);
136
+ newfd = net_socket_mcast_create(&saddr, NULL, errp);
137
if (newfd < 0) {
138
- /* error already reported by net_socket_mcast_create() */
139
goto err;
140
}
141
/* clone newfd to fd, close newfd */
142
@@ -XXX,XX +XXX,XX @@ static NetSocketState *net_socket_fd_init_stream(NetClientState *peer,
143
144
static NetSocketState *net_socket_fd_init(NetClientState *peer,
145
const char *model, const char *name,
146
- int fd, int is_connected, const char *mc)
147
+ int fd, int is_connected,
148
+ const char *mc, Error **errp)
149
{
150
int so_type = -1, optlen=sizeof(so_type);
151
152
if(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&so_type,
153
(socklen_t *)&optlen)< 0) {
154
- fprintf(stderr, "qemu: error: getsockopt(SO_TYPE) for fd=%d failed\n",
155
- fd);
156
+ error_setg(errp, "can't get socket option SO_TYPE");
157
closesocket(fd);
158
return NULL;
159
}
160
switch(so_type) {
161
case SOCK_DGRAM:
162
- return net_socket_fd_init_dgram(peer, model, name, fd, is_connected, mc);
163
+ return net_socket_fd_init_dgram(peer, model, name, fd, is_connected,
164
+ mc, errp);
165
case SOCK_STREAM:
166
return net_socket_fd_init_stream(peer, model, name, fd, is_connected);
167
default:
168
@@ -XXX,XX +XXX,XX @@ static int net_socket_connect_init(NetClientState *peer,
169
NetSocketState *s;
170
int fd, connected, ret;
171
struct sockaddr_in saddr;
172
+ Error *err = NULL;
173
174
if (parse_host_port(&saddr, host_str) < 0)
175
return -1;
176
@@ -XXX,XX +XXX,XX @@ static int net_socket_connect_init(NetClientState *peer,
177
break;
178
}
179
}
180
- s = net_socket_fd_init(peer, model, name, fd, connected, NULL);
181
- if (!s)
182
+ s = net_socket_fd_init(peer, model, name, fd, connected, NULL, &err);
183
+ if (!s) {
184
+ error_report_err(err);
185
return -1;
186
+ }
31
+
187
+
32
+static void filter_redirector_set_vnet_hdr(Object *obj,
188
snprintf(s->nc.info_str, sizeof(s->nc.info_str),
33
+ bool value,
189
"socket: connect to %s:%d",
34
+ Error **errp)
190
inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
35
+{
191
@@ -XXX,XX +XXX,XX @@ static int net_socket_mcast_init(NetClientState *peer,
36
+ MirrorState *s = FILTER_REDIRECTOR(obj);
192
int fd;
37
+
193
struct sockaddr_in saddr;
38
+ s->vnet_hdr = value;
194
struct in_addr localaddr, *param_localaddr;
39
+}
195
+ Error *err = NULL;
40
+
196
41
static void filter_mirror_init(Object *obj)
197
if (parse_host_port(&saddr, host_str) < 0)
42
{
198
return -1;
43
MirrorState *s = FILTER_MIRROR(obj);
199
@@ -XXX,XX +XXX,XX @@ static int net_socket_mcast_init(NetClientState *peer,
44
@@ -XXX,XX +XXX,XX @@ static void filter_mirror_init(Object *obj)
200
param_localaddr = NULL;
45
201
}
46
static void filter_redirector_init(Object *obj)
202
47
{
203
- fd = net_socket_mcast_create(&saddr, param_localaddr);
48
+ MirrorState *s = FILTER_REDIRECTOR(obj);
204
- if (fd < 0)
49
+
205
+ fd = net_socket_mcast_create(&saddr, param_localaddr, &err);
50
object_property_add_str(obj, "indev", filter_redirector_get_indev,
206
+ if (fd < 0) {
51
filter_redirector_set_indev, NULL);
207
+ error_report_err(err);
52
object_property_add_str(obj, "outdev", filter_redirector_get_outdev,
208
return -1;
53
filter_redirector_set_outdev, NULL);
209
+ }
54
+
210
55
+ s->vnet_hdr = false;
211
- s = net_socket_fd_init(peer, model, name, fd, 0, NULL);
56
+ object_property_add_bool(obj, "vnet_hdr_support",
212
- if (!s)
57
+ filter_redirector_get_vnet_hdr,
213
+ s = net_socket_fd_init(peer, model, name, fd, 0, NULL, &err);
58
+ filter_redirector_set_vnet_hdr, NULL);
214
+ if (!s) {
59
}
215
+ error_report_err(err);
60
216
return -1;
61
static void filter_mirror_fini(Object *obj)
217
+ }
62
diff --git a/qemu-options.hx b/qemu-options.hx
218
63
index XXXXXXX..XXXXXXX 100644
219
s->dgram_dst = saddr;
64
--- a/qemu-options.hx
220
65
+++ b/qemu-options.hx
221
@@ -XXX,XX +XXX,XX @@ static int net_socket_udp_init(NetClientState *peer,
66
@@ -XXX,XX +XXX,XX @@ queue @var{all|rx|tx} is an option that can be applied to any netfilter.
222
NetSocketState *s;
67
223
int fd, ret;
68
filter-mirror on netdev @var{netdevid},mirror net packet to chardev@var{chardevid}, if it has the vnet_hdr_support flag, filter-mirror will mirror packet with vnet_hdr_len.
224
struct sockaddr_in laddr, raddr;
69
225
+ Error *err = NULL;
70
-@item -object filter-redirector,id=@var{id},netdev=@var{netdevid},indev=@var{chardevid},
226
71
-outdev=@var{chardevid}[,queue=@var{all|rx|tx}]
227
if (parse_host_port(&laddr, lhost) < 0) {
72
+@item -object filter-redirector,id=@var{id},netdev=@var{netdevid},indev=@var{chardevid},outdev=@var{chardevid},queue=@var{all|rx|tx}[,vnet_hdr_support]
228
return -1;
73
229
@@ -XXX,XX +XXX,XX @@ static int net_socket_udp_init(NetClientState *peer,
74
filter-redirector on netdev @var{netdevid},redirect filter's net packet to chardev
230
}
75
-@var{chardevid},and redirect indev's packet to filter.
231
qemu_set_nonblock(fd);
76
+@var{chardevid},and redirect indev's packet to filter.if it has the vnet_hdr_support flag,
232
77
+filter-redirector will redirect packet with vnet_hdr_len.
233
- s = net_socket_fd_init(peer, model, name, fd, 0, NULL);
78
Create a filter-redirector we need to differ outdev id from indev id, id can not
234
+ s = net_socket_fd_init(peer, model, name, fd, 0, NULL, &err);
79
be the same. we can just use indev or outdev, but at least one of indev or outdev
235
if (!s) {
80
need to be specified.
236
+ error_report_err(err);
237
return -1;
238
}
239
240
@@ -XXX,XX +XXX,XX @@ int net_init_socket(const Netdev *netdev, const char *name,
241
return -1;
242
}
243
qemu_set_nonblock(fd);
244
- if (!net_socket_fd_init(peer, "socket", name, fd, 1, sock->mcast)) {
245
+ if (!net_socket_fd_init(peer, "socket", name, fd, 1, sock->mcast,
246
+ errp)) {
247
return -1;
248
}
249
return 0;
81
--
250
--
82
2.7.4
251
2.7.4
83
252
84
253
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
We add a flag to decide whether net_fill_rstate() need read
3
Cc: berrange@redhat.com
4
the vnet_hdr_len or not.
4
Cc: kraxel@redhat.com
5
5
Cc: pbonzini@redhat.com
6
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
6
Cc: jasowang@redhat.com
7
Suggested-by: Jason Wang <jasowang@redhat.com>
7
Cc: armbru@redhat.com
8
Cc: eblake@redhat.com
9
Signed-off-by: Mao Zhongyi <maozy.fnst@cn.fujitsu.com>
10
Reviewed-by: Markus Armbruster <armbru@redhat.com>
8
Signed-off-by: Jason Wang <jasowang@redhat.com>
11
Signed-off-by: Jason Wang <jasowang@redhat.com>
9
---
12
---
10
include/net/net.h | 9 +++++++--
13
include/qemu/sockets.h | 3 ++-
11
net/colo-compare.c | 4 ++--
14
net/net.c | 22 +++++++++++++++++-----
12
net/filter-mirror.c | 2 +-
15
net/socket.c | 22 +++++++++++++++-------
13
net/net.c | 36 ++++++++++++++++++++++++++++++++----
16
3 files changed, 34 insertions(+), 13 deletions(-)
14
net/socket.c | 8 ++++----
15
5 files changed, 46 insertions(+), 13 deletions(-)
16
17
17
diff --git a/include/net/net.h b/include/net/net.h
18
diff --git a/include/qemu/sockets.h b/include/qemu/sockets.h
18
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
19
--- a/include/net/net.h
20
--- a/include/qemu/sockets.h
20
+++ b/include/net/net.h
21
+++ b/include/qemu/sockets.h
21
@@ -XXX,XX +XXX,XX @@ typedef struct NICState {
22
@@ -XXX,XX +XXX,XX @@ void socket_listen_cleanup(int fd, Error **errp);
22
} NICState;
23
int socket_dgram(SocketAddress *remote, SocketAddress *local, Error **errp);
23
24
24
struct SocketReadState {
25
/* Old, ipv4 only bits. Don't use for new code. */
25
- int state; /* 0 = getting length, 1 = getting data */
26
-int parse_host_port(struct sockaddr_in *saddr, const char *str);
26
+ /* 0 = getting length, 1 = getting vnet header length, 2 = getting data */
27
+int parse_host_port(struct sockaddr_in *saddr, const char *str,
27
+ int state;
28
+ Error **errp);
28
+ /* This flag decide whether to read the vnet_hdr_len field */
29
int socket_init(void);
29
+ bool vnet_hdr;
30
30
uint32_t index;
31
/**
31
uint32_t packet_len;
32
+ uint32_t vnet_hdr_len;
33
uint8_t buf[NET_BUFSIZE];
34
SocketReadStateFinalize *finalize;
35
};
36
@@ -XXX,XX +XXX,XX @@ ssize_t qemu_deliver_packet_iov(NetClientState *sender,
37
void print_net_client(Monitor *mon, NetClientState *nc);
38
void hmp_info_network(Monitor *mon, const QDict *qdict);
39
void net_socket_rs_init(SocketReadState *rs,
40
- SocketReadStateFinalize *finalize);
41
+ SocketReadStateFinalize *finalize,
42
+ bool vnet_hdr);
43
44
/* NIC info */
45
46
diff --git a/net/colo-compare.c b/net/colo-compare.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/net/colo-compare.c
49
+++ b/net/colo-compare.c
50
@@ -XXX,XX +XXX,XX @@ static void colo_compare_complete(UserCreatable *uc, Error **errp)
51
return;
52
}
53
54
- net_socket_rs_init(&s->pri_rs, compare_pri_rs_finalize);
55
- net_socket_rs_init(&s->sec_rs, compare_sec_rs_finalize);
56
+ net_socket_rs_init(&s->pri_rs, compare_pri_rs_finalize, false);
57
+ net_socket_rs_init(&s->sec_rs, compare_sec_rs_finalize, false);
58
59
g_queue_init(&s->conn_list);
60
61
diff --git a/net/filter-mirror.c b/net/filter-mirror.c
62
index XXXXXXX..XXXXXXX 100644
63
--- a/net/filter-mirror.c
64
+++ b/net/filter-mirror.c
65
@@ -XXX,XX +XXX,XX @@ static void filter_redirector_setup(NetFilterState *nf, Error **errp)
66
}
67
}
68
69
- net_socket_rs_init(&s->rs, redirector_rs_finalize);
70
+ net_socket_rs_init(&s->rs, redirector_rs_finalize, false);
71
72
if (s->indev) {
73
chr = qemu_chr_find(s->indev);
74
diff --git a/net/net.c b/net/net.c
32
diff --git a/net/net.c b/net/net.c
75
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
76
--- a/net/net.c
34
--- a/net/net.c
77
+++ b/net/net.c
35
+++ b/net/net.c
78
@@ -XXX,XX +XXX,XX @@ QemuOptsList qemu_net_opts = {
36
@@ -XXX,XX +XXX,XX @@ static int get_str_sep(char *buf, int buf_size, const char **pp, int sep)
79
};
37
return 0;
80
38
}
81
void net_socket_rs_init(SocketReadState *rs,
39
82
- SocketReadStateFinalize *finalize)
40
-int parse_host_port(struct sockaddr_in *saddr, const char *str)
83
+ SocketReadStateFinalize *finalize,
41
+int parse_host_port(struct sockaddr_in *saddr, const char *str,
84
+ bool vnet_hdr)
42
+ Error **errp)
85
{
43
{
86
rs->state = 0;
44
char buf[512];
87
+ rs->vnet_hdr = vnet_hdr;
45
struct hostent *he;
88
rs->index = 0;
46
@@ -XXX,XX +XXX,XX @@ int parse_host_port(struct sockaddr_in *saddr, const char *str)
89
rs->packet_len = 0;
47
int port;
90
+ rs->vnet_hdr_len = 0;
48
91
memset(rs->buf, 0, sizeof(rs->buf));
49
p = str;
92
rs->finalize = finalize;
50
- if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
51
+ if (get_str_sep(buf, sizeof(buf), &p, ':') < 0) {
52
+ error_setg(errp, "host address '%s' doesn't contain ':' "
53
+ "separating host from port", str);
54
return -1;
55
+ }
56
saddr->sin_family = AF_INET;
57
if (buf[0] == '\0') {
58
saddr->sin_addr.s_addr = 0;
59
} else {
60
if (qemu_isdigit(buf[0])) {
61
- if (!inet_aton(buf, &saddr->sin_addr))
62
+ if (!inet_aton(buf, &saddr->sin_addr)) {
63
+ error_setg(errp, "host address '%s' is not a valid "
64
+ "IPv4 address", buf);
65
return -1;
66
+ }
67
} else {
68
- if ((he = gethostbyname(buf)) == NULL)
69
+ he = gethostbyname(buf);
70
+ if (he == NULL) {
71
+ error_setg(errp, "can't resolve host address '%s'", buf);
72
return - 1;
73
+ }
74
saddr->sin_addr = *(struct in_addr *)he->h_addr;
75
}
76
}
77
port = strtol(p, (char **)&r, 0);
78
- if (r == p)
79
+ if (r == p) {
80
+ error_setg(errp, "port number '%s' is invalid", p);
81
return -1;
82
+ }
83
saddr->sin_port = htons(port);
84
return 0;
93
}
85
}
94
@@ -XXX,XX +XXX,XX @@ int net_fill_rstate(SocketReadState *rs, const uint8_t *buf, int size)
95
unsigned int l;
96
97
while (size > 0) {
98
- /* reassemble a packet from the network */
99
- switch (rs->state) { /* 0 = getting length, 1 = getting data */
100
+ /* Reassemble a packet from the network.
101
+ * 0 = getting length.
102
+ * 1 = getting vnet header length.
103
+ * 2 = getting data.
104
+ */
105
+ switch (rs->state) {
106
case 0:
107
l = 4 - rs->index;
108
if (l > size) {
109
@@ -XXX,XX +XXX,XX @@ int net_fill_rstate(SocketReadState *rs, const uint8_t *buf, int size)
110
/* got length */
111
rs->packet_len = ntohl(*(uint32_t *)rs->buf);
112
rs->index = 0;
113
- rs->state = 1;
114
+ if (rs->vnet_hdr) {
115
+ rs->state = 1;
116
+ } else {
117
+ rs->state = 2;
118
+ rs->vnet_hdr_len = 0;
119
+ }
120
}
121
break;
122
case 1:
123
+ l = 4 - rs->index;
124
+ if (l > size) {
125
+ l = size;
126
+ }
127
+ memcpy(rs->buf + rs->index, buf, l);
128
+ buf += l;
129
+ size -= l;
130
+ rs->index += l;
131
+ if (rs->index == 4) {
132
+ /* got vnet header length */
133
+ rs->vnet_hdr_len = ntohl(*(uint32_t *)rs->buf);
134
+ rs->index = 0;
135
+ rs->state = 2;
136
+ }
137
+ break;
138
+ case 2:
139
l = rs->packet_len - rs->index;
140
if (l > size) {
141
l = size;
142
diff --git a/net/socket.c b/net/socket.c
86
diff --git a/net/socket.c b/net/socket.c
143
index XXXXXXX..XXXXXXX 100644
87
index XXXXXXX..XXXXXXX 100644
144
--- a/net/socket.c
88
--- a/net/socket.c
145
+++ b/net/socket.c
89
+++ b/net/socket.c
146
@@ -XXX,XX +XXX,XX @@ static void net_socket_send(void *opaque)
147
closesocket(s->fd);
148
149
s->fd = -1;
150
- net_socket_rs_init(&s->rs, net_socket_rs_finalize);
151
+ net_socket_rs_init(&s->rs, net_socket_rs_finalize, false);
152
s->nc.link_down = true;
153
memset(s->nc.info_str, 0, sizeof(s->nc.info_str));
154
155
@@ -XXX,XX +XXX,XX @@ static NetSocketState *net_socket_fd_init_dgram(NetClientState *peer,
90
@@ -XXX,XX +XXX,XX @@ static NetSocketState *net_socket_fd_init_dgram(NetClientState *peer,
156
s->fd = fd;
91
*/
157
s->listen_fd = -1;
92
158
s->send_fn = net_socket_send_dgram;
93
if (is_connected && mcast != NULL) {
159
- net_socket_rs_init(&s->rs, net_socket_rs_finalize);
94
- if (parse_host_port(&saddr, mcast) < 0) {
160
+ net_socket_rs_init(&s->rs, net_socket_rs_finalize, false);
95
- error_setg(errp, "fd=%d failed parse_host_port()", fd);
161
net_socket_read_poll(s, true);
96
+ if (parse_host_port(&saddr, mcast, errp) < 0) {
162
97
goto err;
163
/* mcast: save bound address as dst */
98
}
164
@@ -XXX,XX +XXX,XX @@ static NetSocketState *net_socket_fd_init_stream(NetClientState *peer,
99
/* must be bound */
165
166
s->fd = fd;
167
s->listen_fd = -1;
168
- net_socket_rs_init(&s->rs, net_socket_rs_finalize);
169
+ net_socket_rs_init(&s->rs, net_socket_rs_finalize, false);
170
171
/* Disable Nagle algorithm on TCP sockets to reduce latency */
172
socket_set_nodelay(fd);
173
@@ -XXX,XX +XXX,XX @@ static int net_socket_listen_init(NetClientState *peer,
100
@@ -XXX,XX +XXX,XX @@ static int net_socket_listen_init(NetClientState *peer,
174
s->fd = -1;
101
NetSocketState *s;
175
s->listen_fd = fd;
102
struct sockaddr_in saddr;
176
s->nc.link_down = true;
103
int fd, ret;
177
- net_socket_rs_init(&s->rs, net_socket_rs_finalize);
104
+ Error *err = NULL;
178
+ net_socket_rs_init(&s->rs, net_socket_rs_finalize, false);
105
179
106
- if (parse_host_port(&saddr, host_str) < 0)
180
qemu_set_fd_handler(s->listen_fd, net_socket_accept, NULL, s);
107
+ if (parse_host_port(&saddr, host_str, &err) < 0) {
181
return 0;
108
+ error_report_err(err);
109
return -1;
110
+ }
111
112
fd = qemu_socket(PF_INET, SOCK_STREAM, 0);
113
if (fd < 0) {
114
@@ -XXX,XX +XXX,XX @@ static int net_socket_connect_init(NetClientState *peer,
115
struct sockaddr_in saddr;
116
Error *err = NULL;
117
118
- if (parse_host_port(&saddr, host_str) < 0)
119
+ if (parse_host_port(&saddr, host_str, &err) < 0) {
120
+ error_report_err(err);
121
return -1;
122
+ }
123
124
fd = qemu_socket(PF_INET, SOCK_STREAM, 0);
125
if (fd < 0) {
126
@@ -XXX,XX +XXX,XX @@ static int net_socket_mcast_init(NetClientState *peer,
127
struct in_addr localaddr, *param_localaddr;
128
Error *err = NULL;
129
130
- if (parse_host_port(&saddr, host_str) < 0)
131
+ if (parse_host_port(&saddr, host_str, &err) < 0) {
132
+ error_report_err(err);
133
return -1;
134
+ }
135
136
if (localaddr_str != NULL) {
137
if (inet_aton(localaddr_str, &localaddr) == 0)
138
@@ -XXX,XX +XXX,XX @@ static int net_socket_udp_init(NetClientState *peer,
139
struct sockaddr_in laddr, raddr;
140
Error *err = NULL;
141
142
- if (parse_host_port(&laddr, lhost) < 0) {
143
+ if (parse_host_port(&laddr, lhost, &err) < 0) {
144
+ error_report_err(err);
145
return -1;
146
}
147
148
- if (parse_host_port(&raddr, rhost) < 0) {
149
+ if (parse_host_port(&raddr, rhost, &err) < 0) {
150
+ error_report_err(err);
151
return -1;
152
}
153
182
--
154
--
183
2.7.4
155
2.7.4
184
156
185
157
diff view generated by jsdifflib
1
From: Michal Privoznik <mprivozn@redhat.com>
1
From: Mao Zhongyi <maozy.fnst@cn.fujitsu.com>
2
2
3
We have a function that checks if given number is power of two.
3
When -net socket fails, it first reports a specific error, then
4
We should prefer it instead of expanding the check on our own.
4
a generic one, like this:
5
5
6
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
6
$ ./x86_64-softmmu/qemu-system-x86_64 -net socket,mcast=230.0.0.1:1234,listen
7
qemu-system-x86_64: -net socket,mcast=230.0.0.1:1234,listen: exactly one of listen=, connect=, mcast= or udp= is required
8
qemu-system-x86_64: -net socket,mcast=230.0.0.1:1234,listen: Device 'socket' could not be initialized
9
10
Convert net_socket_*_init() to Error to get rid of the superfluous second
11
error message. After the patch, the effect like this:
12
13
$ ./x86_64-softmmu/qemu-system-x86_64 -net socket,mcast=230.0.0.1:1234,listen
14
qemu-system-x86_64: -net socket,mcast=230.0.0.1:1234,listen: exactly one of listen=, connect=, mcast= or udp= is requireda
15
16
This also fixes a few silent failures to report an error.
17
18
Cc: jasowang@redhat.com
19
Cc: armbru@redhat.com
20
Cc: berrange@redhat.com
21
Signed-off-by: Mao Zhongyi <maozy.fnst@cn.fujitsu.com>
22
Reviewed-by: Markus Armbruster <armbru@redhat.com>
7
Signed-off-by: Jason Wang <jasowang@redhat.com>
23
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
---
24
---
9
hw/net/virtio-net.c | 2 +-
25
net/socket.c | 92 +++++++++++++++++++++++++++++-------------------------------
10
1 file changed, 1 insertion(+), 1 deletion(-)
26
1 file changed, 44 insertions(+), 48 deletions(-)
11
27
12
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
28
diff --git a/net/socket.c b/net/socket.c
13
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/net/virtio-net.c
30
--- a/net/socket.c
15
+++ b/hw/net/virtio-net.c
31
+++ b/net/socket.c
16
@@ -XXX,XX +XXX,XX @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp)
32
@@ -XXX,XX +XXX,XX @@ static void net_socket_accept(void *opaque)
17
*/
33
static int net_socket_listen_init(NetClientState *peer,
18
if (n->net_conf.rx_queue_size < VIRTIO_NET_RX_QUEUE_MIN_SIZE ||
34
const char *model,
19
n->net_conf.rx_queue_size > VIRTQUEUE_MAX_SIZE ||
35
const char *name,
20
- (n->net_conf.rx_queue_size & (n->net_conf.rx_queue_size - 1))) {
36
- const char *host_str)
21
+ !is_power_of_2(n->net_conf.rx_queue_size)) {
37
+ const char *host_str,
22
error_setg(errp, "Invalid rx_queue_size (= %" PRIu16 "), "
38
+ Error **errp)
23
"must be a power of 2 between %d and %d.",
39
{
24
n->net_conf.rx_queue_size, VIRTIO_NET_RX_QUEUE_MIN_SIZE,
40
NetClientState *nc;
41
NetSocketState *s;
42
struct sockaddr_in saddr;
43
int fd, ret;
44
- Error *err = NULL;
45
46
- if (parse_host_port(&saddr, host_str, &err) < 0) {
47
- error_report_err(err);
48
+ if (parse_host_port(&saddr, host_str, errp) < 0) {
49
return -1;
50
}
51
52
fd = qemu_socket(PF_INET, SOCK_STREAM, 0);
53
if (fd < 0) {
54
- perror("socket");
55
+ error_setg_errno(errp, errno, "can't create stream socket");
56
return -1;
57
}
58
qemu_set_nonblock(fd);
59
@@ -XXX,XX +XXX,XX @@ static int net_socket_listen_init(NetClientState *peer,
60
61
ret = bind(fd, (struct sockaddr *)&saddr, sizeof(saddr));
62
if (ret < 0) {
63
- perror("bind");
64
+ error_setg_errno(errp, errno, "can't bind ip=%s to socket",
65
+ inet_ntoa(saddr.sin_addr));
66
closesocket(fd);
67
return -1;
68
}
69
ret = listen(fd, 0);
70
if (ret < 0) {
71
- perror("listen");
72
+ error_setg_errno(errp, errno, "can't listen on socket");
73
closesocket(fd);
74
return -1;
75
}
76
@@ -XXX,XX +XXX,XX @@ static int net_socket_listen_init(NetClientState *peer,
77
static int net_socket_connect_init(NetClientState *peer,
78
const char *model,
79
const char *name,
80
- const char *host_str)
81
+ const char *host_str,
82
+ Error **errp)
83
{
84
NetSocketState *s;
85
int fd, connected, ret;
86
struct sockaddr_in saddr;
87
- Error *err = NULL;
88
89
- if (parse_host_port(&saddr, host_str, &err) < 0) {
90
- error_report_err(err);
91
+ if (parse_host_port(&saddr, host_str, errp) < 0) {
92
return -1;
93
}
94
95
fd = qemu_socket(PF_INET, SOCK_STREAM, 0);
96
if (fd < 0) {
97
- perror("socket");
98
+ error_setg_errno(errp, errno, "can't create stream socket");
99
return -1;
100
}
101
qemu_set_nonblock(fd);
102
@@ -XXX,XX +XXX,XX @@ static int net_socket_connect_init(NetClientState *peer,
103
errno == EINVAL) {
104
break;
105
} else {
106
- perror("connect");
107
+ error_setg_errno(errp, errno, "can't connect socket");
108
closesocket(fd);
109
return -1;
110
}
111
@@ -XXX,XX +XXX,XX @@ static int net_socket_connect_init(NetClientState *peer,
112
break;
113
}
114
}
115
- s = net_socket_fd_init(peer, model, name, fd, connected, NULL, &err);
116
+ s = net_socket_fd_init(peer, model, name, fd, connected, NULL, errp);
117
if (!s) {
118
- error_report_err(err);
119
return -1;
120
}
121
122
@@ -XXX,XX +XXX,XX @@ static int net_socket_mcast_init(NetClientState *peer,
123
const char *model,
124
const char *name,
125
const char *host_str,
126
- const char *localaddr_str)
127
+ const char *localaddr_str,
128
+ Error **errp)
129
{
130
NetSocketState *s;
131
int fd;
132
struct sockaddr_in saddr;
133
struct in_addr localaddr, *param_localaddr;
134
- Error *err = NULL;
135
136
- if (parse_host_port(&saddr, host_str, &err) < 0) {
137
- error_report_err(err);
138
+ if (parse_host_port(&saddr, host_str, errp) < 0) {
139
return -1;
140
}
141
142
if (localaddr_str != NULL) {
143
- if (inet_aton(localaddr_str, &localaddr) == 0)
144
+ if (inet_aton(localaddr_str, &localaddr) == 0) {
145
+ error_setg(errp, "localaddr '%s' is not a valid IPv4 address",
146
+ localaddr_str);
147
return -1;
148
+ }
149
param_localaddr = &localaddr;
150
} else {
151
param_localaddr = NULL;
152
}
153
154
- fd = net_socket_mcast_create(&saddr, param_localaddr, &err);
155
+ fd = net_socket_mcast_create(&saddr, param_localaddr, errp);
156
if (fd < 0) {
157
- error_report_err(err);
158
return -1;
159
}
160
161
- s = net_socket_fd_init(peer, model, name, fd, 0, NULL, &err);
162
+ s = net_socket_fd_init(peer, model, name, fd, 0, NULL, errp);
163
if (!s) {
164
- error_report_err(err);
165
return -1;
166
}
167
168
@@ -XXX,XX +XXX,XX @@ static int net_socket_udp_init(NetClientState *peer,
169
const char *model,
170
const char *name,
171
const char *rhost,
172
- const char *lhost)
173
+ const char *lhost,
174
+ Error **errp)
175
{
176
NetSocketState *s;
177
int fd, ret;
178
struct sockaddr_in laddr, raddr;
179
- Error *err = NULL;
180
181
- if (parse_host_port(&laddr, lhost, &err) < 0) {
182
- error_report_err(err);
183
+ if (parse_host_port(&laddr, lhost, errp) < 0) {
184
return -1;
185
}
186
187
- if (parse_host_port(&raddr, rhost, &err) < 0) {
188
- error_report_err(err);
189
+ if (parse_host_port(&raddr, rhost, errp) < 0) {
190
return -1;
191
}
192
193
fd = qemu_socket(PF_INET, SOCK_DGRAM, 0);
194
if (fd < 0) {
195
- perror("socket(PF_INET, SOCK_DGRAM)");
196
+ error_setg_errno(errp, errno, "can't create datagram socket");
197
return -1;
198
}
199
200
ret = socket_set_fast_reuse(fd);
201
if (ret < 0) {
202
+ error_setg_errno(errp, errno,
203
+ "can't set socket option SO_REUSEADDR");
204
closesocket(fd);
205
return -1;
206
}
207
ret = bind(fd, (struct sockaddr *)&laddr, sizeof(laddr));
208
if (ret < 0) {
209
- perror("bind");
210
+ error_setg_errno(errp, errno, "can't bind ip=%s to socket",
211
+ inet_ntoa(laddr.sin_addr));
212
closesocket(fd);
213
return -1;
214
}
215
qemu_set_nonblock(fd);
216
217
- s = net_socket_fd_init(peer, model, name, fd, 0, NULL, &err);
218
+ s = net_socket_fd_init(peer, model, name, fd, 0, NULL, errp);
219
if (!s) {
220
- error_report_err(err);
221
return -1;
222
}
223
224
@@ -XXX,XX +XXX,XX @@ static int net_socket_udp_init(NetClientState *peer,
225
int net_init_socket(const Netdev *netdev, const char *name,
226
NetClientState *peer, Error **errp)
227
{
228
- /* FIXME error_setg(errp, ...) on failure */
229
- Error *err = NULL;
230
const NetdevSocketOptions *sock;
231
232
assert(netdev->type == NET_CLIENT_DRIVER_SOCKET);
233
@@ -XXX,XX +XXX,XX @@ int net_init_socket(const Netdev *netdev, const char *name,
234
235
if (sock->has_listen + sock->has_connect + sock->has_mcast +
236
sock->has_udp > 1) {
237
- error_report("exactly one of listen=, connect=, mcast= or udp="
238
- " is required");
239
+ error_setg(errp, "exactly one of listen=, connect=, mcast= or udp="
240
+ " is required");
241
return -1;
242
}
243
244
if (sock->has_localaddr && !sock->has_mcast && !sock->has_udp) {
245
- error_report("localaddr= is only valid with mcast= or udp=");
246
+ error_setg(errp, "localaddr= is only valid with mcast= or udp=");
247
return -1;
248
}
249
250
if (sock->has_fd) {
251
int fd;
252
253
- fd = monitor_fd_param(cur_mon, sock->fd, &err);
254
+ fd = monitor_fd_param(cur_mon, sock->fd, errp);
255
if (fd == -1) {
256
- error_report_err(err);
257
return -1;
258
}
259
qemu_set_nonblock(fd);
260
@@ -XXX,XX +XXX,XX @@ int net_init_socket(const Netdev *netdev, const char *name,
261
}
262
263
if (sock->has_listen) {
264
- if (net_socket_listen_init(peer, "socket", name, sock->listen) == -1) {
265
+ if (net_socket_listen_init(peer, "socket", name, sock->listen, errp)
266
+ < 0) {
267
return -1;
268
}
269
return 0;
270
}
271
272
if (sock->has_connect) {
273
- if (net_socket_connect_init(peer, "socket", name, sock->connect) ==
274
- -1) {
275
+ if (net_socket_connect_init(peer, "socket", name, sock->connect, errp)
276
+ < 0) {
277
return -1;
278
}
279
return 0;
280
@@ -XXX,XX +XXX,XX @@ int net_init_socket(const Netdev *netdev, const char *name,
281
/* if sock->localaddr is missing, it has been initialized to "all bits
282
* zero" */
283
if (net_socket_mcast_init(peer, "socket", name, sock->mcast,
284
- sock->localaddr) == -1) {
285
+ sock->localaddr, errp) < 0) {
286
return -1;
287
}
288
return 0;
289
@@ -XXX,XX +XXX,XX @@ int net_init_socket(const Netdev *netdev, const char *name,
290
291
assert(sock->has_udp);
292
if (!sock->has_localaddr) {
293
- error_report("localaddr= is mandatory with udp=");
294
+ error_setg(errp, "localaddr= is mandatory with udp=");
295
return -1;
296
}
297
- if (net_socket_udp_init(peer, "socket", name, sock->udp, sock->localaddr) ==
298
- -1) {
299
+ if (net_socket_udp_init(peer, "socket", name, sock->udp, sock->localaddr,
300
+ errp) < 0) {
301
return -1;
302
}
303
return 0;
25
--
304
--
26
2.7.4
305
2.7.4
27
306
28
307
diff view generated by jsdifflib
New patch
1
From: Kamil Rytarowski <n54@gmx.com>
1
2
3
SunOS defines SEC in <sys/time.h> as 1 (commonly used time symbols).
4
5
This fixes build on SmartOS (Joyent).
6
7
Patch cherry-picked from pkgsrc by jperkin (Joyent).
8
9
Signed-off-by: Kamil Rytarowski <n54@gmx.com>
10
Reviewed-by: Dmitry Fleytman <dmitry@daynix.com>
11
Signed-off-by: Jason Wang <jasowang@redhat.com>
12
---
13
hw/net/e1000.c | 4 ++--
14
hw/net/e1000_regs.h | 2 +-
15
hw/net/e1000e_core.c | 2 +-
16
hw/net/e1000x_common.h | 2 +-
17
4 files changed, 5 insertions(+), 5 deletions(-)
18
19
diff --git a/hw/net/e1000.c b/hw/net/e1000.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/net/e1000.c
22
+++ b/hw/net/e1000.c
23
@@ -XXX,XX +XXX,XX @@ static uint32_t (*macreg_readops[])(E1000State *, int) = {
24
getreg(TADV), getreg(ITR), getreg(FCRUC), getreg(IPAV),
25
getreg(WUC), getreg(WUS), getreg(SCC), getreg(ECOL),
26
getreg(MCC), getreg(LATECOL), getreg(COLC), getreg(DC),
27
- getreg(TNCRS), getreg(SEC), getreg(CEXTERR), getreg(RLEC),
28
+ getreg(TNCRS), getreg(SEQEC), getreg(CEXTERR), getreg(RLEC),
29
getreg(XONRXC), getreg(XONTXC), getreg(XOFFRXC), getreg(XOFFTXC),
30
getreg(RFC), getreg(RJC), getreg(RNBC), getreg(TSCTFC),
31
getreg(MGTPRC), getreg(MGTPDC), getreg(MGTPTC), getreg(GORCL),
32
@@ -XXX,XX +XXX,XX @@ static const uint8_t mac_reg_access[0x8000] = {
33
[FFLT] = markflag(MAC), [FFMT] = markflag(MAC),
34
[SCC] = markflag(MAC), [FCRUC] = markflag(MAC),
35
[LATECOL] = markflag(MAC), [COLC] = markflag(MAC),
36
- [SEC] = markflag(MAC), [CEXTERR] = markflag(MAC),
37
+ [SEQEC] = markflag(MAC), [CEXTERR] = markflag(MAC),
38
[XONTXC] = markflag(MAC), [XOFFRXC] = markflag(MAC),
39
[RJC] = markflag(MAC), [RNBC] = markflag(MAC),
40
[MGTPDC] = markflag(MAC), [MGTPTC] = markflag(MAC),
41
diff --git a/hw/net/e1000_regs.h b/hw/net/e1000_regs.h
42
index XXXXXXX..XXXXXXX 100644
43
--- a/hw/net/e1000_regs.h
44
+++ b/hw/net/e1000_regs.h
45
@@ -XXX,XX +XXX,XX @@
46
#define E1000_COLC 0x04028 /* Collision Count - R/clr */
47
#define E1000_DC 0x04030 /* Defer Count - R/clr */
48
#define E1000_TNCRS 0x04034 /* TX-No CRS - R/clr */
49
-#define E1000_SEC 0x04038 /* Sequence Error Count - R/clr */
50
+#define E1000_SEQEC 0x04038 /* Sequence Error Count - R/clr */
51
#define E1000_CEXTERR 0x0403C /* Carrier Extension Error Count - R/clr */
52
#define E1000_RLEC 0x04040 /* Receive Length Error Count - R/clr */
53
#define E1000_XONRXC 0x04048 /* XON RX Count - R/clr */
54
diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c
55
index XXXXXXX..XXXXXXX 100644
56
--- a/hw/net/e1000e_core.c
57
+++ b/hw/net/e1000e_core.c
58
@@ -XXX,XX +XXX,XX @@ static uint32_t (*e1000e_macreg_readops[])(E1000ECore *, int) = {
59
e1000e_getreg(RDLEN0),
60
e1000e_getreg(RDH1),
61
e1000e_getreg(LATECOL),
62
- e1000e_getreg(SEC),
63
+ e1000e_getreg(SEQEC),
64
e1000e_getreg(XONTXC),
65
e1000e_getreg(WUS),
66
e1000e_getreg(GORCL),
67
diff --git a/hw/net/e1000x_common.h b/hw/net/e1000x_common.h
68
index XXXXXXX..XXXXXXX 100644
69
--- a/hw/net/e1000x_common.h
70
+++ b/hw/net/e1000x_common.h
71
@@ -XXX,XX +XXX,XX @@ enum {
72
defreg(VFTA), defreg(VET), defreg(RDTR), defreg(RADV),
73
defreg(TADV), defreg(ITR), defreg(SCC), defreg(ECOL),
74
defreg(MCC), defreg(LATECOL), defreg(COLC), defreg(DC),
75
- defreg(TNCRS), defreg(SEC), defreg(CEXTERR), defreg(RLEC),
76
+ defreg(TNCRS), defreg(SEQEC), defreg(CEXTERR), defreg(RLEC),
77
defreg(XONRXC), defreg(XONTXC), defreg(XOFFRXC), defreg(XOFFTXC),
78
defreg(FCRUC), defreg(AIT), defreg(TDFH), defreg(TDFT),
79
defreg(TDFHS), defreg(TDFTS), defreg(TDFPC), defreg(WUC),
80
--
81
2.7.4
82
83
diff view generated by jsdifflib
1
From: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
1
From: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
2
2
3
COLO-Proxy just focus on packet payload, so we skip vnet header.
3
When network is busy, some tcp options(like sack) will unpredictable
4
occur in primary side or secondary side. it will make packet size
5
not same, but the two packet's payload is identical. colo just
6
care about packet payload, so we skip the option field.
4
7
5
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
8
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
6
Signed-off-by: Jason Wang <jasowang@redhat.com>
9
Signed-off-by: Jason Wang <jasowang@redhat.com>
7
---
10
---
8
net/colo-compare.c | 8 ++++++--
11
net/colo-compare.c | 39 +++++++++++++++++++++++++++------------
9
1 file changed, 6 insertions(+), 2 deletions(-)
12
1 file changed, 27 insertions(+), 12 deletions(-)
10
13
11
diff --git a/net/colo-compare.c b/net/colo-compare.c
14
diff --git a/net/colo-compare.c b/net/colo-compare.c
12
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
13
--- a/net/colo-compare.c
16
--- a/net/colo-compare.c
14
+++ b/net/colo-compare.c
17
+++ b/net/colo-compare.c
18
@@ -XXX,XX +XXX,XX @@ static int packet_enqueue(CompareState *s, int mode)
19
* return: 0 means packet same
20
* > 0 || < 0 means packet different
21
*/
22
-static int colo_packet_compare_common(Packet *ppkt, Packet *spkt, int offset)
23
+static int colo_packet_compare_common(Packet *ppkt,
24
+ Packet *spkt,
25
+ int poffset,
26
+ int soffset)
27
{
28
if (trace_event_get_state_backends(TRACE_COLO_COMPARE_MISCOMPARE)) {
29
char pri_ip_src[20], pri_ip_dst[20], sec_ip_src[20], sec_ip_dst[20];
15
@@ -XXX,XX +XXX,XX @@ static int colo_packet_compare_common(Packet *ppkt, Packet *spkt, int offset)
30
@@ -XXX,XX +XXX,XX @@ static int colo_packet_compare_common(Packet *ppkt, Packet *spkt, int offset)
16
sec_ip_src, sec_ip_dst);
31
sec_ip_src, sec_ip_dst);
17
}
32
}
18
33
19
+ offset = ppkt->vnet_hdr_len + offset;
34
- offset = ppkt->vnet_hdr_len + offset;
20
+
35
+ poffset = ppkt->vnet_hdr_len + poffset;
21
if (ppkt->size == spkt->size) {
36
+ soffset = ppkt->vnet_hdr_len + soffset;
22
- return memcmp(ppkt->data + offset, spkt->data + offset,
37
23
+ return memcmp(ppkt->data + offset,
38
- if (ppkt->size == spkt->size) {
24
+ spkt->data + offset,
39
- return memcmp(ppkt->data + offset,
25
spkt->size - offset);
40
- spkt->data + offset,
41
- spkt->size - offset);
42
+ if (ppkt->size - poffset == spkt->size - soffset) {
43
+ return memcmp(ppkt->data + poffset,
44
+ spkt->data + soffset,
45
+ spkt->size - soffset);
26
} else {
46
} else {
27
trace_colo_compare_main("Net packet size are not the same");
47
trace_colo_compare_main("Net packet size are not the same");
48
return -1;
28
@@ -XXX,XX +XXX,XX @@ static int colo_packet_compare_tcp(Packet *spkt, Packet *ppkt)
49
@@ -XXX,XX +XXX,XX @@ static int colo_packet_compare_tcp(Packet *spkt, Packet *ppkt)
50
* so we just need skip this field.
29
*/
51
*/
30
if (ptcp->th_off > 5) {
52
if (ptcp->th_off > 5) {
31
ptrdiff_t tcp_offset;
53
- ptrdiff_t tcp_offset;
54
+ ptrdiff_t ptcp_offset, stcp_offset;
55
56
- tcp_offset = ppkt->transport_header - (uint8_t *)ppkt->data
57
- + (ptcp->th_off * 4) - ppkt->vnet_hdr_len;
58
- res = colo_packet_compare_common(ppkt, spkt, tcp_offset);
59
+ ptcp_offset = ppkt->transport_header - (uint8_t *)ppkt->data
60
+ + (ptcp->th_off * 4) - ppkt->vnet_hdr_len;
61
+ stcp_offset = spkt->transport_header - (uint8_t *)spkt->data
62
+ + (stcp->th_off * 4) - spkt->vnet_hdr_len;
32
+
63
+
33
tcp_offset = ppkt->transport_header - (uint8_t *)ppkt->data
64
+ /*
34
- + (ptcp->th_off * 4);
65
+ * When network is busy, some tcp options(like sack) will unpredictable
35
+ + (ptcp->th_off * 4) - ppkt->vnet_hdr_len;
66
+ * occur in primary side or secondary side. it will make packet size
36
res = colo_packet_compare_common(ppkt, spkt, tcp_offset);
67
+ * not same, but the two packet's payload is identical. colo just
68
+ * care about packet payload, so we skip the option field.
69
+ */
70
+ res = colo_packet_compare_common(ppkt, spkt, ptcp_offset, stcp_offset);
37
} else if (ptcp->th_sum == stcp->th_sum) {
71
} else if (ptcp->th_sum == stcp->th_sum) {
38
res = colo_packet_compare_common(ppkt, spkt, ETH_HLEN);
72
- res = colo_packet_compare_common(ppkt, spkt, ETH_HLEN);
73
+ res = colo_packet_compare_common(ppkt, spkt, ETH_HLEN, ETH_HLEN);
74
} else {
75
res = -1;
76
}
77
@@ -XXX,XX +XXX,XX @@ static int colo_packet_compare_udp(Packet *spkt, Packet *ppkt)
78
* the ip payload here.
79
*/
80
ret = colo_packet_compare_common(ppkt, spkt,
81
+ network_header_length + ETH_HLEN,
82
network_header_length + ETH_HLEN);
83
84
if (ret) {
85
@@ -XXX,XX +XXX,XX @@ static int colo_packet_compare_icmp(Packet *spkt, Packet *ppkt)
86
* the ip payload here.
87
*/
88
if (colo_packet_compare_common(ppkt, spkt,
89
+ network_header_length + ETH_HLEN,
90
network_header_length + ETH_HLEN)) {
91
trace_colo_compare_icmp_miscompare("primary pkt size",
92
ppkt->size);
93
@@ -XXX,XX +XXX,XX @@ static int colo_packet_compare_other(Packet *spkt, Packet *ppkt)
94
sec_ip_src, sec_ip_dst);
95
}
96
97
- return colo_packet_compare_common(ppkt, spkt, 0);
98
+ return colo_packet_compare_common(ppkt, spkt, 0, 0);
99
}
100
101
static int colo_old_packet_check_one(Packet *pkt, int64_t *check_time)
39
--
102
--
40
2.7.4
103
2.7.4
41
104
42
105
diff view generated by jsdifflib
1
From: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
1
From: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
2
2
3
We can use this property flush and send packet with vnet_hdr_len.
3
The packet_enqueue() use g_queue_push_tail() to
4
enqueue net packet, so it is more efficent way use
5
g_queue_pop_head() to get packet for compare.
6
That will improve the success rate of comparison.
7
In my test the performance of ftp put 1000M file
8
will increase 10%
4
9
5
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
10
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
6
Signed-off-by: Jason Wang <jasowang@redhat.com>
11
Signed-off-by: Jason Wang <jasowang@redhat.com>
7
---
12
---
8
net/colo-compare.c | 8 ++++++--
13
net/colo-compare.c | 4 ++--
9
net/colo.c | 3 ++-
14
1 file changed, 2 insertions(+), 2 deletions(-)
10
net/colo.h | 4 +++-
11
net/filter-rewriter.c | 2 +-
12
4 files changed, 12 insertions(+), 5 deletions(-)
13
15
14
diff --git a/net/colo-compare.c b/net/colo-compare.c
16
diff --git a/net/colo-compare.c b/net/colo-compare.c
15
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
16
--- a/net/colo-compare.c
18
--- a/net/colo-compare.c
17
+++ b/net/colo-compare.c
19
+++ b/net/colo-compare.c
18
@@ -XXX,XX +XXX,XX @@ static int packet_enqueue(CompareState *s, int mode)
20
@@ -XXX,XX +XXX,XX @@ static void colo_compare_connection(void *opaque, void *user_data)
19
Connection *conn;
21
20
22
while (!g_queue_is_empty(&conn->primary_list) &&
21
if (mode == PRIMARY_IN) {
23
!g_queue_is_empty(&conn->secondary_list)) {
22
- pkt = packet_new(s->pri_rs.buf, s->pri_rs.packet_len);
24
- pkt = g_queue_pop_tail(&conn->primary_list);
23
+ pkt = packet_new(s->pri_rs.buf,
25
+ pkt = g_queue_pop_head(&conn->primary_list);
24
+ s->pri_rs.packet_len,
26
switch (conn->ip_proto) {
25
+ s->pri_rs.vnet_hdr_len);
27
case IPPROTO_TCP:
26
} else {
28
result = g_queue_find_custom(&conn->secondary_list,
27
- pkt = packet_new(s->sec_rs.buf, s->sec_rs.packet_len);
29
@@ -XXX,XX +XXX,XX @@ static void colo_compare_connection(void *opaque, void *user_data)
28
+ pkt = packet_new(s->sec_rs.buf,
30
* until next comparison.
29
+ s->sec_rs.packet_len,
31
*/
30
+ s->sec_rs.vnet_hdr_len);
32
trace_colo_compare_main("packet different");
31
}
33
- g_queue_push_tail(&conn->primary_list, pkt);
32
34
+ g_queue_push_head(&conn->primary_list, pkt);
33
if (parse_packet_early(pkt)) {
35
/* TODO: colo_notify_checkpoint();*/
34
diff --git a/net/colo.c b/net/colo.c
36
break;
35
index XXXXXXX..XXXXXXX 100644
37
}
36
--- a/net/colo.c
37
+++ b/net/colo.c
38
@@ -XXX,XX +XXX,XX @@ void connection_destroy(void *opaque)
39
g_slice_free(Connection, conn);
40
}
41
42
-Packet *packet_new(const void *data, int size)
43
+Packet *packet_new(const void *data, int size, int vnet_hdr_len)
44
{
45
Packet *pkt = g_slice_new(Packet);
46
47
pkt->data = g_memdup(data, size);
48
pkt->size = size;
49
pkt->creation_ms = qemu_clock_get_ms(QEMU_CLOCK_HOST);
50
+ pkt->vnet_hdr_len = vnet_hdr_len;
51
52
return pkt;
53
}
54
diff --git a/net/colo.h b/net/colo.h
55
index XXXXXXX..XXXXXXX 100644
56
--- a/net/colo.h
57
+++ b/net/colo.h
58
@@ -XXX,XX +XXX,XX @@ typedef struct Packet {
59
int size;
60
/* Time of packet creation, in wall clock ms */
61
int64_t creation_ms;
62
+ /* Get vnet_hdr_len from filter */
63
+ uint32_t vnet_hdr_len;
64
} Packet;
65
66
typedef struct ConnectionKey {
67
@@ -XXX,XX +XXX,XX @@ Connection *connection_get(GHashTable *connection_track_table,
68
ConnectionKey *key,
69
GQueue *conn_list);
70
void connection_hashtable_reset(GHashTable *connection_track_table);
71
-Packet *packet_new(const void *data, int size);
72
+Packet *packet_new(const void *data, int size, int vnet_hdr_len);
73
void packet_destroy(void *opaque, void *user_data);
74
75
#endif /* QEMU_COLO_PROXY_H */
76
diff --git a/net/filter-rewriter.c b/net/filter-rewriter.c
77
index XXXXXXX..XXXXXXX 100644
78
--- a/net/filter-rewriter.c
79
+++ b/net/filter-rewriter.c
80
@@ -XXX,XX +XXX,XX @@ static ssize_t colo_rewriter_receive_iov(NetFilterState *nf,
81
char *buf = g_malloc0(size);
82
83
iov_to_buf(iov, iovcnt, 0, buf, size);
84
- pkt = packet_new(buf, size);
85
+ pkt = packet_new(buf, size, 0);
86
g_free(buf);
87
88
/*
89
--
38
--
90
2.7.4
39
2.7.4
91
40
92
41
diff view generated by jsdifflib
1
From: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
1
From: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
2
3
This patch change the compare_chr_send() parameter from CharBackend to CompareState,
4
we can get more information like vnet_hdr(We use it to support packet with vnet_header).
5
2
6
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
3
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
7
Signed-off-by: Jason Wang <jasowang@redhat.com>
4
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
---
5
---
9
net/colo-compare.c | 14 +++++++-------
6
net/colo-compare.c | 59 ++++++++++++++++++++++++++++--------------------------
10
1 file changed, 7 insertions(+), 7 deletions(-)
7
1 file changed, 31 insertions(+), 28 deletions(-)
11
8
12
diff --git a/net/colo-compare.c b/net/colo-compare.c
9
diff --git a/net/colo-compare.c b/net/colo-compare.c
13
index XXXXXXX..XXXXXXX 100644
10
index XXXXXXX..XXXXXXX 100644
14
--- a/net/colo-compare.c
11
--- a/net/colo-compare.c
15
+++ b/net/colo-compare.c
12
+++ b/net/colo-compare.c
16
@@ -XXX,XX +XXX,XX @@ enum {
13
@@ -XXX,XX +XXX,XX @@
17
SECONDARY_IN,
14
#define REGULAR_PACKET_CHECK_MS 3000
18
};
15
19
16
/*
20
-static int compare_chr_send(CharBackend *out,
17
- + CompareState ++
21
+static int compare_chr_send(CompareState *s,
18
- | |
22
const uint8_t *buf,
19
- +---------------+ +---------------+ +---------------+
23
uint32_t size);
20
- |conn list +--->conn +--------->conn |
24
21
- +---------------+ +---------------+ +---------------+
25
@@ -XXX,XX +XXX,XX @@ static void colo_compare_connection(void *opaque, void *user_data)
22
- | | | | | |
26
}
23
- +---------------+ +---v----+ +---v----+ +---v----+ +---v----+
27
24
- |primary | |secondary |primary | |secondary
28
if (result) {
25
- |packet | |packet + |packet | |packet +
29
- ret = compare_chr_send(&s->chr_out, pkt->data, pkt->size);
26
- +--------+ +--------+ +--------+ +--------+
30
+ ret = compare_chr_send(s, pkt->data, pkt->size);
27
- | | | |
31
if (ret < 0) {
28
- +---v----+ +---v----+ +---v----+ +---v----+
32
error_report("colo_send_primary_packet failed");
29
- |primary | |secondary |primary | |secondary
33
}
30
- |packet | |packet + |packet | |packet +
34
@@ -XXX,XX +XXX,XX @@ static void colo_compare_connection(void *opaque, void *user_data)
31
- +--------+ +--------+ +--------+ +--------+
35
}
32
- | | | |
36
}
33
- +---v----+ +---v----+ +---v----+ +---v----+
37
34
- |primary | |secondary |primary | |secondary
38
-static int compare_chr_send(CharBackend *out,
35
- |packet | |packet + |packet | |packet +
39
+static int compare_chr_send(CompareState *s,
36
- +--------+ +--------+ +--------+ +--------+
40
const uint8_t *buf,
37
-*/
41
uint32_t size)
38
+ * + CompareState ++
42
{
39
+ * | |
43
@@ -XXX,XX +XXX,XX @@ static int compare_chr_send(CharBackend *out,
40
+ * +---------------+ +---------------+ +---------------+
41
+ * | conn list + - > conn + ------- > conn + -- > ......
42
+ * +---------------+ +---------------+ +---------------+
43
+ * | | | | | |
44
+ * +---------------+ +---v----+ +---v----+ +---v----+ +---v----+
45
+ * |primary | |secondary |primary | |secondary
46
+ * |packet | |packet + |packet | |packet +
47
+ * +--------+ +--------+ +--------+ +--------+
48
+ * | | | |
49
+ * +---v----+ +---v----+ +---v----+ +---v----+
50
+ * |primary | |secondary |primary | |secondary
51
+ * |packet | |packet + |packet | |packet +
52
+ * +--------+ +--------+ +--------+ +--------+
53
+ * | | | |
54
+ * +---v----+ +---v----+ +---v----+ +---v----+
55
+ * |primary | |secondary |primary | |secondary
56
+ * |packet | |packet + |packet | |packet +
57
+ * +--------+ +--------+ +--------+ +--------+
58
+ */
59
typedef struct CompareState {
60
Object parent;
61
62
@@ -XXX,XX +XXX,XX @@ typedef struct CompareState {
63
SocketReadState sec_rs;
64
bool vnet_hdr;
65
66
- /* connection list: the connections belonged to this NIC could be found
67
- * in this list.
68
- * element type: Connection
69
+ /*
70
+ * Record the connection that through the NIC
71
+ * Element type: Connection
72
*/
73
GQueue conn_list;
74
- /* hashtable to save connection */
75
+ /* Record the connection without repetition */
76
GHashTable *connection_track_table;
77
- /* compare thread, a thread for each NIC */
78
+ /* This thread just do packet compare job */
79
QemuThread thread;
80
81
GMainContext *worker_context;
82
@@ -XXX,XX +XXX,XX @@ static int colo_old_packet_check_one_conn(Connection *conn,
83
(GCompareFunc)colo_old_packet_check_one);
84
85
if (result) {
86
- /* do checkpoint will flush old packet */
87
- /* TODO: colo_notify_checkpoint();*/
88
+ /* Do checkpoint will flush old packet */
89
+ /*
90
+ * TODO: Notify colo frame to do checkpoint.
91
+ * colo_compare_inconsistent_notify();
92
+ */
44
return 0;
93
return 0;
45
}
94
}
46
95
47
- ret = qemu_chr_fe_write_all(out, (uint8_t *)&len, sizeof(len));
48
+ ret = qemu_chr_fe_write_all(&s->chr_out, (uint8_t *)&len, sizeof(len));
49
if (ret != sizeof(len)) {
50
goto err;
51
}
52
53
- ret = qemu_chr_fe_write_all(out, (uint8_t *)buf, size);
54
+ ret = qemu_chr_fe_write_all(&s->chr_out, (uint8_t *)buf, size);
55
if (ret != size) {
56
goto err;
57
}
58
@@ -XXX,XX +XXX,XX @@ static void compare_pri_rs_finalize(SocketReadState *pri_rs)
59
60
if (packet_enqueue(s, PRIMARY_IN)) {
61
trace_colo_compare_main("primary: unsupported packet in");
62
- compare_chr_send(&s->chr_out, pri_rs->buf, pri_rs->packet_len);
63
+ compare_chr_send(s, pri_rs->buf, pri_rs->packet_len);
64
} else {
65
/* compare connection */
66
g_queue_foreach(&s->conn_list, colo_compare_connection, s);
67
@@ -XXX,XX +XXX,XX @@ static void colo_flush_packets(void *opaque, void *user_data)
68
69
while (!g_queue_is_empty(&conn->primary_list)) {
70
pkt = g_queue_pop_head(&conn->primary_list);
71
- compare_chr_send(&s->chr_out, pkt->data, pkt->size);
72
+ compare_chr_send(s, pkt->data, pkt->size);
73
packet_destroy(pkt, NULL);
74
}
75
while (!g_queue_is_empty(&conn->secondary_list)) {
76
--
96
--
77
2.7.4
97
2.7.4
78
98
79
99
diff view generated by jsdifflib
1
From: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
1
From: Wang Yong <wang.yong155@zte.com.cn>
2
2
3
We add the vnet_hdr_support option for filter-mirror, default is disabled.
3
IOThread uses AioContext event loop and does not run a GMainContext.
4
If you use virtio-net-pci or other driver needs vnet_hdr, please enable it.
4
Therefore,chardev cannot work in IOThread,such as the chardev is
5
You can use it for example:
5
used for colo-compare packets reception.
6
-object filter-mirror,id=m0,netdev=hn0,queue=tx,outdev=mirror0,vnet_hdr_support
7
6
8
If it has vnet_hdr_support flag, we will change the sending packet format from
7
This patch makes the IOThread run the GMainContext event loop,
9
struct {int size; const uint8_t buf[];} to {int size; int vnet_hdr_len; const uint8_t buf[];}.
8
chardev and IOThread can work together.
10
make other module(like colo-compare) know how to parse net packet correctly.
11
9
12
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
10
Reviewed-by: Fam Zheng <famz@redhat.com>
11
Signed-off-by: Wang Yong <wang.yong155@zte.com.cn>
12
Signed-off-by: Wang Guang <wang.guang55@zte.com.cn>
13
Signed-off-by: Jason Wang <jasowang@redhat.com>
13
Signed-off-by: Jason Wang <jasowang@redhat.com>
14
---
14
---
15
net/filter-mirror.c | 42 +++++++++++++++++++++++++++++++++++++++++-
15
include/sysemu/iothread.h | 4 ++++
16
qemu-options.hx | 5 ++---
16
iothread.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
17
2 files changed, 43 insertions(+), 4 deletions(-)
17
2 files changed, 49 insertions(+)
18
18
19
diff --git a/net/filter-mirror.c b/net/filter-mirror.c
19
diff --git a/include/sysemu/iothread.h b/include/sysemu/iothread.h
20
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
21
--- a/net/filter-mirror.c
21
--- a/include/sysemu/iothread.h
22
+++ b/net/filter-mirror.c
22
+++ b/include/sysemu/iothread.h
23
@@ -XXX,XX +XXX,XX @@ typedef struct MirrorState {
23
@@ -XXX,XX +XXX,XX @@ typedef struct {
24
CharBackend chr_in;
24
25
CharBackend chr_out;
25
QemuThread thread;
26
SocketReadState rs;
26
AioContext *ctx;
27
+ bool vnet_hdr;
27
+ GMainContext *worker_context;
28
} MirrorState;
28
+ GMainLoop *main_loop;
29
29
+ GOnce once;
30
static int filter_send(MirrorState *s,
30
QemuMutex init_done_lock;
31
const struct iovec *iov,
31
QemuCond init_done_cond; /* is thread initialization done? */
32
int iovcnt)
32
bool stopping;
33
{
33
@@ -XXX,XX +XXX,XX @@ typedef struct {
34
+ NetFilterState *nf = NETFILTER(s);
34
char *iothread_get_id(IOThread *iothread);
35
int ret = 0;
35
AioContext *iothread_get_aio_context(IOThread *iothread);
36
ssize_t size = 0;
36
void iothread_stop_all(void);
37
uint32_t len = 0;
37
+GMainContext *iothread_get_g_main_context(IOThread *iothread);
38
@@ -XXX,XX +XXX,XX @@ static int filter_send(MirrorState *s,
38
39
goto err;
39
#endif /* IOTHREAD_H */
40
diff --git a/iothread.c b/iothread.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/iothread.c
43
+++ b/iothread.c
44
@@ -XXX,XX +XXX,XX @@ static void *iothread_run(void *opaque)
45
46
while (!atomic_read(&iothread->stopping)) {
47
aio_poll(iothread->ctx, true);
48
+
49
+ if (atomic_read(&iothread->worker_context)) {
50
+ GMainLoop *loop;
51
+
52
+ g_main_context_push_thread_default(iothread->worker_context);
53
+ iothread->main_loop =
54
+ g_main_loop_new(iothread->worker_context, TRUE);
55
+ loop = iothread->main_loop;
56
+
57
+ g_main_loop_run(iothread->main_loop);
58
+ iothread->main_loop = NULL;
59
+ g_main_loop_unref(loop);
60
+
61
+ g_main_context_pop_thread_default(iothread->worker_context);
62
+ g_main_context_unref(iothread->worker_context);
63
+ iothread->worker_context = NULL;
64
+ }
40
}
65
}
41
66
42
+ if (s->vnet_hdr) {
67
rcu_unregister_thread();
43
+ /*
68
@@ -XXX,XX +XXX,XX @@ static int iothread_stop(Object *object, void *opaque)
44
+ * If vnet_hdr = on, we send vnet header len to make other
69
}
45
+ * module(like colo-compare) know how to parse net
70
iothread->stopping = true;
46
+ * packet correctly.
71
aio_notify(iothread->ctx);
47
+ */
72
+ if (atomic_read(&iothread->main_loop)) {
48
+ ssize_t vnet_hdr_len;
73
+ g_main_loop_quit(iothread->main_loop);
74
+ }
75
qemu_thread_join(&iothread->thread);
76
return 0;
77
}
78
@@ -XXX,XX +XXX,XX @@ static void iothread_complete(UserCreatable *obj, Error **errp)
79
80
qemu_mutex_init(&iothread->init_done_lock);
81
qemu_cond_init(&iothread->init_done_cond);
82
+ iothread->once = (GOnce) G_ONCE_INIT;
83
84
/* This assumes we are called from a thread with useful CPU affinity for us
85
* to inherit.
86
@@ -XXX,XX +XXX,XX @@ void iothread_stop_all(void)
87
88
object_child_foreach(container, iothread_stop, NULL);
89
}
49
+
90
+
50
+ vnet_hdr_len = nf->netdev->vnet_hdr_len;
91
+static gpointer iothread_g_main_context_init(gpointer opaque)
92
+{
93
+ AioContext *ctx;
94
+ IOThread *iothread = opaque;
95
+ GSource *source;
51
+
96
+
52
+ len = htonl(vnet_hdr_len);
97
+ iothread->worker_context = g_main_context_new();
53
+ ret = qemu_chr_fe_write_all(&s->chr_out, (uint8_t *)&len, sizeof(len));
54
+ if (ret != sizeof(len)) {
55
+ goto err;
56
+ }
57
+ }
58
+
98
+
59
buf = g_malloc(size);
99
+ ctx = iothread_get_aio_context(iothread);
60
iov_to_buf(iov, iovcnt, 0, buf, size);
100
+ source = aio_get_g_source(ctx);
61
ret = qemu_chr_fe_write_all(&s->chr_out, (uint8_t *)buf, size);
101
+ g_source_attach(source, iothread->worker_context);
62
@@ -XXX,XX +XXX,XX @@ static void filter_redirector_setup(NetFilterState *nf, Error **errp)
102
+ g_source_unref(source);
63
}
64
}
65
66
- net_socket_rs_init(&s->rs, redirector_rs_finalize, false);
67
+ net_socket_rs_init(&s->rs, redirector_rs_finalize, s->vnet_hdr);
68
69
if (s->indev) {
70
chr = qemu_chr_find(s->indev);
71
@@ -XXX,XX +XXX,XX @@ static void filter_mirror_set_outdev(Object *obj,
72
}
73
}
74
75
+static bool filter_mirror_get_vnet_hdr(Object *obj, Error **errp)
76
+{
77
+ MirrorState *s = FILTER_MIRROR(obj);
78
+
103
+
79
+ return s->vnet_hdr;
104
+ aio_notify(iothread->ctx);
105
+ return NULL;
80
+}
106
+}
81
+
107
+
82
+static void filter_mirror_set_vnet_hdr(Object *obj, bool value, Error **errp)
108
+GMainContext *iothread_get_g_main_context(IOThread *iothread)
83
+{
109
+{
84
+ MirrorState *s = FILTER_MIRROR(obj);
110
+ g_once(&iothread->once, iothread_g_main_context_init, iothread);
85
+
111
+
86
+ s->vnet_hdr = value;
112
+ return iothread->worker_context;
87
+}
113
+}
88
+
89
static char *filter_redirector_get_outdev(Object *obj, Error **errp)
90
{
91
MirrorState *s = FILTER_REDIRECTOR(obj);
92
@@ -XXX,XX +XXX,XX @@ static void filter_redirector_set_outdev(Object *obj,
93
94
static void filter_mirror_init(Object *obj)
95
{
96
+ MirrorState *s = FILTER_MIRROR(obj);
97
+
98
object_property_add_str(obj, "outdev", filter_mirror_get_outdev,
99
filter_mirror_set_outdev, NULL);
100
+
101
+ s->vnet_hdr = false;
102
+ object_property_add_bool(obj, "vnet_hdr_support",
103
+ filter_mirror_get_vnet_hdr,
104
+ filter_mirror_set_vnet_hdr, NULL);
105
}
106
107
static void filter_redirector_init(Object *obj)
108
diff --git a/qemu-options.hx b/qemu-options.hx
109
index XXXXXXX..XXXXXXX 100644
110
--- a/qemu-options.hx
111
+++ b/qemu-options.hx
112
@@ -XXX,XX +XXX,XX @@ queue @var{all|rx|tx} is an option that can be applied to any netfilter.
113
@option{tx}: the filter is attached to the transmit queue of the netdev,
114
where it will receive packets sent by the netdev.
115
116
-@item -object filter-mirror,id=@var{id},netdev=@var{netdevid},outdev=@var{chardevid}[,queue=@var{all|rx|tx}]
117
+@item -object filter-mirror,id=@var{id},netdev=@var{netdevid},outdev=@var{chardevid},queue=@var{all|rx|tx}[,vnet_hdr_support]
118
119
-filter-mirror on netdev @var{netdevid},mirror net packet to chardev
120
-@var{chardevid}
121
+filter-mirror on netdev @var{netdevid},mirror net packet to chardev@var{chardevid}, if it has the vnet_hdr_support flag, filter-mirror will mirror packet with vnet_hdr_len.
122
123
@item -object filter-redirector,id=@var{id},netdev=@var{netdevid},indev=@var{chardevid},
124
outdev=@var{chardevid}[,queue=@var{all|rx|tx}]
125
--
114
--
126
2.7.4
115
2.7.4
127
116
128
117
diff view generated by jsdifflib
1
From: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
1
From: Wang Yong <wang.yong155@zte.com.cn>
2
2
3
We add the vnet_hdr_support option for colo-compare, default is disabled.
3
Remove the task which check old packet in the comparing thread,
4
If you use virtio-net-pci or other driver needs vnet_hdr, please enable it.
4
then use IOthread context timer to handle it.
5
You can use it for example:
6
-object colo-compare,id=comp0,primary_in=compare0-0,secondary_in=compare1,outdev=compare_out0,vnet_hdr_support
7
5
8
COLO-compare can get vnet header length from filter,
6
Process pactkets in the IOThread which arrived over the socket.
9
Add vnet_hdr_len to struct packet and output packet with
7
we use iothread_get_g_main_context to create a new g_main_loop in
10
the vnet_hdr_len.
8
the IOThread.then the packets from the primary and the secondary
9
are processed in the IOThread.
11
10
12
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
11
Finally remove the colo-compare thread using the IOThread instead.
12
13
Reviewed-by: Zhang Chen<zhangchen.fnst@cn.fujitsu.com>
14
Signed-off-by: Wang Yong <wang.yong155@zte.com.cn>
15
Signed-off-by: Wang Guang <wang.guang55@zte.com.cn>
13
Signed-off-by: Jason Wang <jasowang@redhat.com>
16
Signed-off-by: Jason Wang <jasowang@redhat.com>
14
---
17
---
15
net/colo-compare.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++-------
18
net/colo-compare.c | 83 +++++++++++++++++++++++++++++-------------------------
16
qemu-options.hx | 4 ++--
19
1 file changed, 45 insertions(+), 38 deletions(-)
17
2 files changed, 55 insertions(+), 9 deletions(-)
18
20
19
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
20
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
21
--- a/net/colo-compare.c
23
--- a/net/colo-compare.c
22
+++ b/net/colo-compare.c
24
+++ b/net/colo-compare.c
25
@@ -XXX,XX +XXX,XX @@
26
#include "qemu/sockets.h"
27
#include "qapi-visit.h"
28
#include "net/colo.h"
29
+#include "sysemu/iothread.h"
30
31
#define TYPE_COLO_COMPARE "colo-compare"
32
#define COLO_COMPARE(obj) \
23
@@ -XXX,XX +XXX,XX @@ typedef struct CompareState {
33
@@ -XXX,XX +XXX,XX @@ typedef struct CompareState {
24
CharBackend chr_out;
34
GQueue conn_list;
25
SocketReadState pri_rs;
35
/* Record the connection without repetition */
26
SocketReadState sec_rs;
36
GHashTable *connection_track_table;
27
+ bool vnet_hdr;
37
- /* This thread just do packet compare job */
28
38
- QemuThread thread;
29
/* connection list: the connections belonged to this NIC could be found
39
30
* in this list.
40
+ IOThread *iothread;
31
@@ -XXX,XX +XXX,XX @@ enum {
41
GMainContext *worker_context;
32
42
- GMainLoop *compare_loop;
33
static int compare_chr_send(CompareState *s,
43
+ QEMUTimer *packet_check_timer;
34
const uint8_t *buf,
44
} CompareState;
35
- uint32_t size);
45
36
+ uint32_t size,
46
typedef struct CompareClass {
37
+ uint32_t vnet_hdr_len);
47
@@ -XXX,XX +XXX,XX @@ static void compare_sec_chr_in(void *opaque, const uint8_t *buf, int size)
38
48
* Check old packet regularly so it can watch for any packets
39
static gint seq_sorter(Packet *a, Packet *b, gpointer data)
49
* that the secondary hasn't produced equivalents of.
50
*/
51
-static gboolean check_old_packet_regular(void *opaque)
52
+static void check_old_packet_regular(void *opaque)
40
{
53
{
41
@@ -XXX,XX +XXX,XX @@ static void colo_compare_connection(void *opaque, void *user_data)
54
CompareState *s = opaque;
42
}
55
43
56
/* if have old packet we will notify checkpoint */
44
if (result) {
57
colo_old_packet_check(s);
45
- ret = compare_chr_send(s, pkt->data, pkt->size);
58
+ timer_mod(s->packet_check_timer, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) +
46
+ ret = compare_chr_send(s,
59
+ REGULAR_PACKET_CHECK_MS);
47
+ pkt->data,
48
+ pkt->size,
49
+ pkt->vnet_hdr_len);
50
if (ret < 0) {
51
error_report("colo_send_primary_packet failed");
52
}
53
@@ -XXX,XX +XXX,XX @@ static void colo_compare_connection(void *opaque, void *user_data)
54
55
static int compare_chr_send(CompareState *s,
56
const uint8_t *buf,
57
- uint32_t size)
58
+ uint32_t size,
59
+ uint32_t vnet_hdr_len)
60
{
61
int ret = 0;
62
uint32_t len = htonl(size);
63
@@ -XXX,XX +XXX,XX @@ static int compare_chr_send(CompareState *s,
64
goto err;
65
}
66
67
+ if (s->vnet_hdr) {
68
+ /*
69
+ * We send vnet header len make other module(like filter-redirector)
70
+ * know how to parse net packet correctly.
71
+ */
72
+ len = htonl(vnet_hdr_len);
73
+ ret = qemu_chr_fe_write_all(&s->chr_out, (uint8_t *)&len, sizeof(len));
74
+ if (ret != sizeof(len)) {
75
+ goto err;
76
+ }
77
+ }
78
+
79
ret = qemu_chr_fe_write_all(&s->chr_out, (uint8_t *)buf, size);
80
if (ret != size) {
81
goto err;
82
@@ -XXX,XX +XXX,XX @@ static void compare_set_outdev(Object *obj, const char *value, Error **errp)
83
s->outdev = g_strdup(value);
84
}
85
86
+static bool compare_get_vnet_hdr(Object *obj, Error **errp)
87
+{
88
+ CompareState *s = COLO_COMPARE(obj);
89
+
90
+ return s->vnet_hdr;
91
+}
60
+}
92
+
61
+
93
+static void compare_set_vnet_hdr(Object *obj,
62
+static void colo_compare_timer_init(CompareState *s)
94
+ bool value,
95
+ Error **errp)
96
+{
63
+{
97
+ CompareState *s = COLO_COMPARE(obj);
64
+ AioContext *ctx = iothread_get_aio_context(s->iothread);
98
+
65
99
+ s->vnet_hdr = value;
66
- return TRUE;
100
+}
67
+ s->packet_check_timer = aio_timer_new(ctx, QEMU_CLOCK_VIRTUAL,
101
+
68
+ SCALE_MS, check_old_packet_regular,
102
static void compare_pri_rs_finalize(SocketReadState *pri_rs)
69
+ s);
70
+ timer_mod(s->packet_check_timer, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) +
71
+ REGULAR_PACKET_CHECK_MS);
72
}
73
74
-static void *colo_compare_thread(void *opaque)
75
+static void colo_compare_timer_del(CompareState *s)
103
{
76
{
104
CompareState *s = container_of(pri_rs, CompareState, pri_rs);
77
- CompareState *s = opaque;
105
78
- GSource *timeout_source;
106
if (packet_enqueue(s, PRIMARY_IN)) {
79
+ if (s->packet_check_timer) {
107
trace_colo_compare_main("primary: unsupported packet in");
80
+ timer_del(s->packet_check_timer);
108
- compare_chr_send(s, pri_rs->buf, pri_rs->packet_len);
81
+ timer_free(s->packet_check_timer);
109
+ compare_chr_send(s,
82
+ s->packet_check_timer = NULL;
110
+ pri_rs->buf,
83
+ }
111
+ pri_rs->packet_len,
84
+ }
112
+ pri_rs->vnet_hdr_len);
85
113
} else {
86
- s->worker_context = g_main_context_new();
114
/* compare connection */
87
+static void colo_compare_iothread(CompareState *s)
115
g_queue_foreach(&s->conn_list, colo_compare_connection, s);
88
+{
89
+ object_ref(OBJECT(s->iothread));
90
+ s->worker_context = iothread_get_g_main_context(s->iothread);
91
92
qemu_chr_fe_set_handlers(&s->chr_pri_in, compare_chr_can_read,
93
compare_pri_chr_in, NULL, NULL,
94
@@ -XXX,XX +XXX,XX @@ static void *colo_compare_thread(void *opaque)
95
compare_sec_chr_in, NULL, NULL,
96
s, s->worker_context, true);
97
98
- s->compare_loop = g_main_loop_new(s->worker_context, FALSE);
99
-
100
- /* To kick any packets that the secondary doesn't match */
101
- timeout_source = g_timeout_source_new(REGULAR_PACKET_CHECK_MS);
102
- g_source_set_callback(timeout_source,
103
- (GSourceFunc)check_old_packet_regular, s, NULL);
104
- g_source_attach(timeout_source, s->worker_context);
105
-
106
- g_main_loop_run(s->compare_loop);
107
-
108
- g_source_unref(timeout_source);
109
- g_main_loop_unref(s->compare_loop);
110
- g_main_context_unref(s->worker_context);
111
- return NULL;
112
+ colo_compare_timer_init(s);
113
}
114
115
static char *compare_get_pri_indev(Object *obj, Error **errp)
116
@@ -XXX,XX +XXX,XX @@ static void colo_compare_complete(UserCreatable *uc, Error **errp)
116
@@ -XXX,XX +XXX,XX @@ static void colo_compare_complete(UserCreatable *uc, Error **errp)
117
{
118
CompareState *s = COLO_COMPARE(uc);
119
Chardev *chr;
120
- char thread_name[64];
121
- static int compare_id;
122
123
- if (!s->pri_indev || !s->sec_indev || !s->outdev) {
124
+ if (!s->pri_indev || !s->sec_indev || !s->outdev || !s->iothread) {
125
error_setg(errp, "colo compare needs 'primary_in' ,"
126
- "'secondary_in','outdev' property set");
127
+ "'secondary_in','outdev','iothread' property set");
117
return;
128
return;
118
}
129
} else if (!strcmp(s->pri_indev, s->outdev) ||
119
130
!strcmp(s->sec_indev, s->outdev) ||
120
- net_socket_rs_init(&s->pri_rs, compare_pri_rs_finalize, false);
131
@@ -XXX,XX +XXX,XX @@ static void colo_compare_complete(UserCreatable *uc, Error **errp)
121
- net_socket_rs_init(&s->sec_rs, compare_sec_rs_finalize, false);
132
g_free,
122
+ net_socket_rs_init(&s->pri_rs, compare_pri_rs_finalize, s->vnet_hdr);
133
connection_destroy);
123
+ net_socket_rs_init(&s->sec_rs, compare_sec_rs_finalize, s->vnet_hdr);
134
124
135
- sprintf(thread_name, "colo-compare %d", compare_id);
125
g_queue_init(&s->conn_list);
136
- qemu_thread_create(&s->thread, thread_name,
126
137
- colo_compare_thread, s,
127
@@ -XXX,XX +XXX,XX @@ static void colo_flush_packets(void *opaque, void *user_data)
138
- QEMU_THREAD_JOINABLE);
128
139
- compare_id++;
129
while (!g_queue_is_empty(&conn->primary_list)) {
140
-
130
pkt = g_queue_pop_head(&conn->primary_list);
141
+ colo_compare_iothread(s);
131
- compare_chr_send(s, pkt->data, pkt->size);
142
return;
132
+ compare_chr_send(s,
143
}
133
+ pkt->data,
144
134
+ pkt->size,
135
+ pkt->vnet_hdr_len);
136
packet_destroy(pkt, NULL);
137
}
138
while (!g_queue_is_empty(&conn->secondary_list)) {
139
@@ -XXX,XX +XXX,XX @@ static void colo_compare_class_init(ObjectClass *oc, void *data)
140
141
static void colo_compare_init(Object *obj)
142
{
143
+ CompareState *s = COLO_COMPARE(obj);
144
+
145
object_property_add_str(obj, "primary_in",
146
compare_get_pri_indev, compare_set_pri_indev,
147
NULL);
148
@@ -XXX,XX +XXX,XX @@ static void colo_compare_init(Object *obj)
145
@@ -XXX,XX +XXX,XX @@ static void colo_compare_init(Object *obj)
149
object_property_add_str(obj, "outdev",
146
object_property_add_str(obj, "outdev",
150
compare_get_outdev, compare_set_outdev,
147
compare_get_outdev, compare_set_outdev,
151
NULL);
148
NULL);
149
+ object_property_add_link(obj, "iothread", TYPE_IOTHREAD,
150
+ (Object **)&s->iothread,
151
+ object_property_allow_set_link,
152
+ OBJ_PROP_LINK_UNREF_ON_RELEASE, NULL);
153
154
s->vnet_hdr = false;
155
object_property_add_bool(obj, "vnet_hdr_support", compare_get_vnet_hdr,
156
@@ -XXX,XX +XXX,XX @@ static void colo_compare_finalize(Object *obj)
157
qemu_chr_fe_deinit(&s->chr_pri_in, false);
158
qemu_chr_fe_deinit(&s->chr_sec_in, false);
159
qemu_chr_fe_deinit(&s->chr_out, false);
160
-
161
- g_main_loop_quit(s->compare_loop);
162
- qemu_thread_join(&s->thread);
163
-
164
+ if (s->iothread) {
165
+ colo_compare_timer_del(s);
166
+ }
167
/* Release all unhandled packets after compare thead exited */
168
g_queue_foreach(&s->conn_list, colo_flush_packets, s);
169
170
g_queue_clear(&s->conn_list);
171
172
- g_hash_table_destroy(s->connection_track_table);
173
+ if (s->connection_track_table) {
174
+ g_hash_table_destroy(s->connection_track_table);
175
+ }
152
+
176
+
153
+ s->vnet_hdr = false;
177
+ if (s->iothread) {
154
+ object_property_add_bool(obj, "vnet_hdr_support", compare_get_vnet_hdr,
178
+ object_unref(OBJECT(s->iothread));
155
+ compare_set_vnet_hdr, NULL);
179
+ }
156
}
180
g_free(s->pri_indev);
157
181
g_free(s->sec_indev);
158
static void colo_compare_finalize(Object *obj)
182
g_free(s->outdev);
159
diff --git a/qemu-options.hx b/qemu-options.hx
160
index XXXXXXX..XXXXXXX 100644
161
--- a/qemu-options.hx
162
+++ b/qemu-options.hx
163
@@ -XXX,XX +XXX,XX @@ Dump the network traffic on netdev @var{dev} to the file specified by
164
The file format is libpcap, so it can be analyzed with tools such as tcpdump
165
or Wireshark.
166
167
-@item -object colo-compare,id=@var{id},primary_in=@var{chardevid},secondary_in=@var{chardevid},
168
-outdev=@var{chardevid}
169
+@item -object colo-compare,id=@var{id},primary_in=@var{chardevid},secondary_in=@var{chardevid},outdev=@var{chardevid}[,vnet_hdr_support]
170
171
Colo-compare gets packet from primary_in@var{chardevid} and secondary_in@var{chardevid}, than compare primary packet with
172
secondary packet. If the packets are same, we will output primary
173
packet to outdev@var{chardevid}, else we will notify colo-frame
174
do checkpoint and send primary packet to outdev@var{chardevid}.
175
+if it has the vnet_hdr_support flag, colo compare will send/recv packet with vnet_hdr_len.
176
177
we must use it with the help of filter-mirror and filter-redirector.
178
179
--
183
--
180
2.7.4
184
2.7.4
181
185
182
186
diff view generated by jsdifflib
1
From: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
1
From: Wang Yong <wang.yong155@zte.com.cn>
2
2
3
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
3
Update colo-proxy.txt,add IOThread configuration.
4
Later we have to configure IOThread,if not COLO can not work.
5
6
Reviewed-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
7
Signed-off-by: Wang Yong <wang.yong155@zte.com.cn>
8
Signed-off-by: Wang Guang <wang.guang55@zte.com.cn>
4
Signed-off-by: Jason Wang <jasowang@redhat.com>
9
Signed-off-by: Jason Wang <jasowang@redhat.com>
5
---
10
---
6
docs/colo-proxy.txt | 26 ++++++++++++++++++++++++++
11
docs/colo-proxy.txt | 3 ++-
7
1 file changed, 26 insertions(+)
12
1 file changed, 2 insertions(+), 1 deletion(-)
8
13
9
diff --git a/docs/colo-proxy.txt b/docs/colo-proxy.txt
14
diff --git a/docs/colo-proxy.txt b/docs/colo-proxy.txt
10
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
11
--- a/docs/colo-proxy.txt
16
--- a/docs/colo-proxy.txt
12
+++ b/docs/colo-proxy.txt
17
+++ b/docs/colo-proxy.txt
13
@@ -XXX,XX +XXX,XX @@ Secondary(ip:3.3.3.8):
18
@@ -XXX,XX +XXX,XX @@ Primary(ip:3.3.3.3):
14
-chardev socket,id=red1,host=3.3.3.3,port=9004
19
-chardev socket,id=compare0-0,host=3.3.3.3,port=9001
15
-object filter-redirector,id=f1,netdev=hn0,queue=tx,indev=red0
20
-chardev socket,id=compare_out,host=3.3.3.3,port=9005,server,nowait
16
-object filter-redirector,id=f2,netdev=hn0,queue=rx,outdev=red1
21
-chardev socket,id=compare_out0,host=3.3.3.3,port=9005
17
+-object filter-rewriter,id=f3,netdev=hn0,queue=all
22
+-object iothread,id=iothread1
18
+
23
-object filter-mirror,id=m0,netdev=hn0,queue=tx,outdev=mirror0
19
+If you want to use virtio-net-pci or other driver with vnet_header:
24
-object filter-redirector,netdev=hn0,id=redire0,queue=rx,indev=compare_out
20
+
25
-object filter-redirector,netdev=hn0,id=redire1,queue=rx,outdev=compare0
21
+Primary(ip:3.3.3.3):
26
--object colo-compare,id=comp0,primary_in=compare0-0,secondary_in=compare1,outdev=compare_out0
22
+-netdev tap,id=hn0,vhost=off,script=/etc/qemu-ifup,downscript=/etc/qemu-ifdown
27
+-object colo-compare,id=comp0,primary_in=compare0-0,secondary_in=compare1,outdev=compare_out0,iothread=iothread1
23
+-device e1000,id=e0,netdev=hn0,mac=52:a4:00:12:78:66
28
24
+-chardev socket,id=mirror0,host=3.3.3.3,port=9003,server,nowait
29
Secondary(ip:3.3.3.8):
25
+-chardev socket,id=compare1,host=3.3.3.3,port=9004,server,nowait
30
-netdev tap,id=hn0,vhost=off,script=/etc/qemu-ifup,down script=/etc/qemu-ifdown
26
+-chardev socket,id=compare0,host=3.3.3.3,port=9001,server,nowait
27
+-chardev socket,id=compare0-0,host=3.3.3.3,port=9001
28
+-chardev socket,id=compare_out,host=3.3.3.3,port=9005,server,nowait
29
+-chardev socket,id=compare_out0,host=3.3.3.3,port=9005
30
+-object filter-mirror,id=m0,netdev=hn0,queue=tx,outdev=mirror0,vnet_hdr_support
31
+-object filter-redirector,netdev=hn0,id=redire0,queue=rx,indev=compare_out,vnet_hdr_support
32
+-object filter-redirector,netdev=hn0,id=redire1,queue=rx,outdev=compare0,vnet_hdr_support
33
+-object colo-compare,id=comp0,primary_in=compare0-0,secondary_in=compare1,outdev=compare_out0,vnet_hdr_support
34
+
35
+Secondary(ip:3.3.3.8):
36
+-netdev tap,id=hn0,vhost=off,script=/etc/qemu-ifup,down script=/etc/qemu-ifdown
37
+-device e1000,netdev=hn0,mac=52:a4:00:12:78:66
38
+-chardev socket,id=red0,host=3.3.3.3,port=9003
39
+-chardev socket,id=red1,host=3.3.3.3,port=9004
40
+-object filter-redirector,id=f1,netdev=hn0,queue=tx,indev=red0,vnet_hdr_support
41
+-object filter-redirector,id=f2,netdev=hn0,queue=rx,outdev=red1,vnet_hdr_support
42
+-object filter-rewriter,id=f3,netdev=hn0,queue=all,vnet_hdr_support
43
44
Note:
45
a.COLO-proxy must work with COLO-frame and Block-replication.
46
--
31
--
47
2.7.4
32
2.7.4
48
33
49
34
diff view generated by jsdifflib