1
The following changes since commit e607bbee553cfe73072870cef458cfa4e78133e2:
1
The following changes since commit c74e62ee3e2dc2955e07d004c71badecb68a84eb:
2
2
3
Merge remote-tracking branch 'remotes/edgar/tags/edgar/xilinx-next-2018-01-26.for-upstream' into staging (2018-01-26 14:24:25 +0000)
3
Merge remote-tracking branch 'remotes/rth/tags/cota-target-pull-request' into staging (2018-05-11 15:41:29 +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 bf4835a4d5338bb7424827715df22570a8adc67c:
9
for you to fetch changes up to 0e0266c2e475b82b39a757c875fa03e64272fbe7:
10
10
11
MAINTAINERS: update Dmitry Fleytman email (2018-01-29 16:05:38 +0800)
11
net: Get rid of 'vlan' terminology and use 'hub' instead in the doc files (2018-05-14 15:47:14 +0800)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
14
15
----------------------------------------------------------------
15
----------------------------------------------------------------
16
Mao Zhongyi (2):
16
Thomas Huth (4):
17
colo: modified the payload compare function
17
net: Fix memory leak in net_param_nic()
18
colo: compare the packet based on the tcp sequence number
18
net: Remove the deprecated "vlan" parameter
19
net: Get rid of 'vlan' terminology and use 'hub' instead in the source files
20
net: Get rid of 'vlan' terminology and use 'hub' instead in the doc files
19
21
20
Philippe Mathieu-Daudé (1):
22
docs/qdev-device-use.txt | 3 --
21
MAINTAINERS: update Dmitry Fleytman email
23
hw/core/qdev-properties-system.c | 80 ----------------------------------------
22
24
include/hw/qdev-properties.h | 3 --
23
Thomas Huth (3):
25
include/net/net.h | 1 -
24
net: Allow hubports to connect to other netdevs
26
net/hub.c | 7 ++--
25
net: Allow netdevs to be used with 'hostfwd_add' and 'hostfwd_remove'
27
net/net.c | 18 ++++-----
26
qemu-doc: Get rid of "vlan=X" example in the documentation
28
net/slirp.c | 8 ++--
27
29
net/tap.c | 4 +-
28
MAINTAINERS | 8 +-
30
qapi/net.json | 15 ++++----
29
hmp-commands.hx | 4 +-
31
qemu-doc.texi | 51 ++++++++++++-------------
30
net/colo-compare.c | 411 +++++++++++++++++++++++++++++++++--------------------
32
qemu-options.hx | 29 ++++++---------
31
net/colo.c | 9 ++
33
11 files changed, 58 insertions(+), 161 deletions(-)
32
net/colo.h | 15 ++
33
net/hub.c | 27 +++-
34
net/hub.h | 3 +-
35
net/net.c | 2 +-
36
net/slirp.c | 33 +++--
37
net/trace-events | 2 +-
38
qapi/net.json | 4 +-
39
qemu-options.hx | 12 +-
40
12 files changed, 347 insertions(+), 183 deletions(-)
41
34
42
35
diff view generated by jsdifflib
Deleted patch
1
From: Mao Zhongyi <maozy.fnst@cn.fujitsu.com>
2
1
3
Modified the function colo_packet_compare_common to prepare for the
4
tcp packet comparison in the next patch.
5
6
Cc: Zhang Chen <zhangckid@gmail.com>
7
Cc: Li Zhijian <lizhijian@cn.fujitsu.com>
8
Cc: Jason Wang <jasowang@redhat.com>
9
10
Signed-off-by: Mao Zhongyi <maozy.fnst@cn.fujitsu.com>
11
Signed-off-by: Li Zhijian <lizhijian@cn.fujitsu.com>
12
Signed-off-by: Zhang Chen <zhangckid@gmail.com>
13
Reviewed-by: Zhang Chen <zhangckid@gmail.com>
14
Signed-off-by: Jason Wang <jasowang@redhat.com>
15
---
16
net/colo-compare.c | 88 +++++++++++++++++++++++++++---------------------------
17
1 file changed, 44 insertions(+), 44 deletions(-)
18
19
diff --git a/net/colo-compare.c b/net/colo-compare.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/net/colo-compare.c
22
+++ b/net/colo-compare.c
23
@@ -XXX,XX +XXX,XX @@ static int packet_enqueue(CompareState *s, int mode, Connection **con)
24
* return: 0 means packet same
25
* > 0 || < 0 means packet different
26
*/
27
-static int colo_packet_compare_common(Packet *ppkt,
28
- Packet *spkt,
29
- int poffset,
30
- int soffset)
31
+static int colo_compare_packet_payload(Packet *ppkt,
32
+ Packet *spkt,
33
+ uint16_t poffset,
34
+ uint16_t soffset,
35
+ uint16_t len)
36
+
37
{
38
if (trace_event_get_state_backends(TRACE_COLO_COMPARE_MISCOMPARE)) {
39
char pri_ip_src[20], pri_ip_dst[20], sec_ip_src[20], sec_ip_dst[20];
40
@@ -XXX,XX +XXX,XX @@ static int colo_packet_compare_common(Packet *ppkt,
41
sec_ip_src, sec_ip_dst);
42
}
43
44
- poffset = ppkt->vnet_hdr_len + poffset;
45
- soffset = ppkt->vnet_hdr_len + soffset;
46
-
47
- if (ppkt->size - poffset == spkt->size - soffset) {
48
- return memcmp(ppkt->data + poffset,
49
- spkt->data + soffset,
50
- spkt->size - soffset);
51
- } else {
52
- trace_colo_compare_main("Net packet size are not the same");
53
- return -1;
54
- }
55
+ return memcmp(ppkt->data + poffset, spkt->data + soffset, len);
56
}
57
58
/*
59
@@ -XXX,XX +XXX,XX @@ static int colo_packet_compare_tcp(Packet *spkt, Packet *ppkt)
60
* the secondary guest's timestamp. COLO just focus on payload,
61
* so we just need skip this field.
62
*/
63
- if (ptcp->th_off > 5) {
64
- ptrdiff_t ptcp_offset, stcp_offset;
65
66
- ptcp_offset = ppkt->transport_header - (uint8_t *)ppkt->data
67
- + (ptcp->th_off * 4) - ppkt->vnet_hdr_len;
68
- stcp_offset = spkt->transport_header - (uint8_t *)spkt->data
69
- + (stcp->th_off * 4) - spkt->vnet_hdr_len;
70
+ ptrdiff_t ptcp_offset, stcp_offset;
71
72
- /*
73
- * When network is busy, some tcp options(like sack) will unpredictable
74
- * occur in primary side or secondary side. it will make packet size
75
- * not same, but the two packet's payload is identical. colo just
76
- * care about packet payload, so we skip the option field.
77
- */
78
- res = colo_packet_compare_common(ppkt, spkt, ptcp_offset, stcp_offset);
79
- } else if (ptcp->th_sum == stcp->th_sum) {
80
- res = colo_packet_compare_common(ppkt, spkt, ETH_HLEN, ETH_HLEN);
81
+ ptcp_offset = ppkt->transport_header - (uint8_t *)ppkt->data
82
+ + (ptcp->th_off << 2) - ppkt->vnet_hdr_len;
83
+ stcp_offset = spkt->transport_header - (uint8_t *)spkt->data
84
+ + (stcp->th_off << 2) - spkt->vnet_hdr_len;
85
+ if (ppkt->size - ptcp_offset == spkt->size - stcp_offset) {
86
+ res = colo_compare_packet_payload(ppkt, spkt,
87
+ ptcp_offset, stcp_offset,
88
+ ppkt->size - ptcp_offset);
89
} else {
90
+ trace_colo_compare_main("TCP: payload size of packets are different");
91
res = -1;
92
}
93
94
@@ -XXX,XX +XXX,XX @@ static int colo_packet_compare_tcp(Packet *spkt, Packet *ppkt)
95
*/
96
static int colo_packet_compare_udp(Packet *spkt, Packet *ppkt)
97
{
98
- int ret;
99
- int network_header_length = ppkt->ip->ip_hl * 4;
100
+ uint16_t network_header_length = ppkt->ip->ip_hl << 2;
101
+ uint16_t offset = network_header_length + ETH_HLEN + ppkt->vnet_hdr_len;
102
103
trace_colo_compare_main("compare udp");
104
105
@@ -XXX,XX +XXX,XX @@ static int colo_packet_compare_udp(Packet *spkt, Packet *ppkt)
106
* other field like TOS,TTL,IP Checksum. we only need to compare
107
* the ip payload here.
108
*/
109
- ret = colo_packet_compare_common(ppkt, spkt,
110
- network_header_length + ETH_HLEN,
111
- network_header_length + ETH_HLEN);
112
-
113
- if (ret) {
114
+ if (ppkt->size != spkt->size) {
115
+ trace_colo_compare_main("UDP: payload size of packets are different");
116
+ return -1;
117
+ }
118
+ if (colo_compare_packet_payload(ppkt, spkt, offset, offset,
119
+ ppkt->size - offset)) {
120
trace_colo_compare_udp_miscompare("primary pkt size", ppkt->size);
121
trace_colo_compare_udp_miscompare("Secondary pkt size", spkt->size);
122
if (trace_event_get_state_backends(TRACE_COLO_COMPARE_MISCOMPARE)) {
123
@@ -XXX,XX +XXX,XX @@ static int colo_packet_compare_udp(Packet *spkt, Packet *ppkt)
124
qemu_hexdump((char *)spkt->data, stderr, "colo-compare sec pkt",
125
spkt->size);
126
}
127
+ return -1;
128
+ } else {
129
+ return 0;
130
}
131
-
132
- return ret;
133
}
134
135
/*
136
@@ -XXX,XX +XXX,XX @@ static int colo_packet_compare_udp(Packet *spkt, Packet *ppkt)
137
*/
138
static int colo_packet_compare_icmp(Packet *spkt, Packet *ppkt)
139
{
140
- int network_header_length = ppkt->ip->ip_hl * 4;
141
+ uint16_t network_header_length = ppkt->ip->ip_hl << 2;
142
+ uint16_t offset = network_header_length + ETH_HLEN + ppkt->vnet_hdr_len;
143
144
trace_colo_compare_main("compare icmp");
145
146
@@ -XXX,XX +XXX,XX @@ static int colo_packet_compare_icmp(Packet *spkt, Packet *ppkt)
147
* other field like TOS,TTL,IP Checksum. we only need to compare
148
* the ip payload here.
149
*/
150
- if (colo_packet_compare_common(ppkt, spkt,
151
- network_header_length + ETH_HLEN,
152
- network_header_length + ETH_HLEN)) {
153
+ if (ppkt->size != spkt->size) {
154
+ trace_colo_compare_main("ICMP: payload size of packets are different");
155
+ return -1;
156
+ }
157
+ if (colo_compare_packet_payload(ppkt, spkt, offset, offset,
158
+ ppkt->size - offset)) {
159
trace_colo_compare_icmp_miscompare("primary pkt size",
160
ppkt->size);
161
trace_colo_compare_icmp_miscompare("Secondary pkt size",
162
@@ -XXX,XX +XXX,XX @@ static int colo_packet_compare_icmp(Packet *spkt, Packet *ppkt)
163
*/
164
static int colo_packet_compare_other(Packet *spkt, Packet *ppkt)
165
{
166
+ uint16_t offset = ppkt->vnet_hdr_len;
167
+
168
trace_colo_compare_main("compare other");
169
if (trace_event_get_state_backends(TRACE_COLO_COMPARE_MISCOMPARE)) {
170
char pri_ip_src[20], pri_ip_dst[20], sec_ip_src[20], sec_ip_dst[20];
171
@@ -XXX,XX +XXX,XX @@ static int colo_packet_compare_other(Packet *spkt, Packet *ppkt)
172
sec_ip_src, sec_ip_dst);
173
}
174
175
- return colo_packet_compare_common(ppkt, spkt, 0, 0);
176
+ if (ppkt->size != spkt->size) {
177
+ trace_colo_compare_main("Other: payload size of packets are different");
178
+ return -1;
179
+ }
180
+ return colo_compare_packet_payload(ppkt, spkt, offset, offset,
181
+ ppkt->size - offset);
182
}
183
184
static int colo_old_packet_check_one(Packet *pkt, int64_t *check_time)
185
--
186
2.7.4
187
188
diff view generated by jsdifflib
Deleted patch
1
From: Mao Zhongyi <maozy.fnst@cn.fujitsu.com>
2
1
3
Packet size some time different or when network is busy.
4
Based on same payload size, but TCP protocol can not
5
guarantee send the same one packet in the same way,
6
7
like that:
8
We send this payload:
9
------------------------------
10
| header |1|2|3|4|5|6|7|8|9|0|
11
------------------------------
12
13
primary:
14
ppkt1:
15
----------------
16
| header |1|2|3|
17
----------------
18
ppkt2:
19
------------------------
20
| header |4|5|6|7|8|9|0|
21
------------------------
22
23
secondary:
24
spkt1:
25
------------------------------
26
| header |1|2|3|4|5|6|7|8|9|0|
27
------------------------------
28
29
In the original method, ppkt1 and ppkt2 are different in size and
30
spkt1, so they can't compare and trigger the checkpoint.
31
32
I have tested FTP get 200M and 1G file many times, I found that
33
the performance was less than 1% of the native.
34
35
Now I reconstructed the comparison of TCP packets based on the
36
TCP sequence number. first of all, ppkt1 and spkt1 have the same
37
starting sequence number, so they can compare, even though their
38
length is different. And then ppkt1 with a smaller payload length
39
is used as the comparison length, if the payload is same, send
40
out the ppkt1 and record the offset(the length of ppkt1 payload)
41
in spkt1. The next comparison, ppkt2 and spkt1 can be compared
42
from the recorded position of spkt1.
43
44
like that:
45
----------------
46
| header |1|2|3| ppkt1
47
---------|-----|
48
| |
49
---------v-----v--------------
50
| header |1|2|3|4|5|6|7|8|9|0| spkt1
51
---------------|\------------|
52
| \offset |
53
---------v-------------v
54
| header |4|5|6|7|8|9|0| ppkt2
55
------------------------
56
57
In this way, the performance can reach native 20% in my multiple
58
tests.
59
60
Cc: Zhang Chen <zhangckid@gmail.com>
61
Cc: Li Zhijian <lizhijian@cn.fujitsu.com>
62
Cc: Jason Wang <jasowang@redhat.com>
63
64
Signed-off-by: Mao Zhongyi <maozy.fnst@cn.fujitsu.com>
65
Signed-off-by: Li Zhijian <lizhijian@cn.fujitsu.com>
66
Signed-off-by: Zhang Chen <zhangckid@gmail.com>
67
Reviewed-by: Zhang Chen <zhangckid@gmail.com>
68
Tested-by: Zhang Chen <zhangckid@gmail.com>
69
Signed-off-by: Jason Wang <jasowang@redhat.com>
70
---
71
net/colo-compare.c | 343 +++++++++++++++++++++++++++++++++++------------------
72
net/colo.c | 9 ++
73
net/colo.h | 15 +++
74
net/trace-events | 2 +-
75
4 files changed, 250 insertions(+), 119 deletions(-)
76
77
diff --git a/net/colo-compare.c b/net/colo-compare.c
78
index XXXXXXX..XXXXXXX 100644
79
--- a/net/colo-compare.c
80
+++ b/net/colo-compare.c
81
@@ -XXX,XX +XXX,XX @@
82
#define COMPARE_READ_LEN_MAX NET_BUFSIZE
83
#define MAX_QUEUE_SIZE 1024
84
85
+#define COLO_COMPARE_FREE_PRIMARY 0x01
86
+#define COLO_COMPARE_FREE_SECONDARY 0x02
87
+
88
/* TODO: Should be configurable */
89
#define REGULAR_PACKET_CHECK_MS 3000
90
91
@@ -XXX,XX +XXX,XX @@ static gint seq_sorter(Packet *a, Packet *b, gpointer data)
92
return ntohl(atcp->th_seq) - ntohl(btcp->th_seq);
93
}
94
95
+static void fill_pkt_tcp_info(void *data, uint32_t *max_ack)
96
+{
97
+ Packet *pkt = data;
98
+ struct tcphdr *tcphd;
99
+
100
+ tcphd = (struct tcphdr *)pkt->transport_header;
101
+
102
+ pkt->tcp_seq = ntohl(tcphd->th_seq);
103
+ pkt->tcp_ack = ntohl(tcphd->th_ack);
104
+ *max_ack = *max_ack > pkt->tcp_ack ? *max_ack : pkt->tcp_ack;
105
+ pkt->header_size = pkt->transport_header - (uint8_t *)pkt->data
106
+ + (tcphd->th_off << 2) - pkt->vnet_hdr_len;
107
+ pkt->payload_size = pkt->size - pkt->header_size;
108
+ pkt->seq_end = pkt->tcp_seq + pkt->payload_size;
109
+ pkt->flags = tcphd->th_flags;
110
+}
111
+
112
/*
113
* Return 1 on success, if return 0 means the
114
* packet will be dropped
115
*/
116
-static int colo_insert_packet(GQueue *queue, Packet *pkt)
117
+static int colo_insert_packet(GQueue *queue, Packet *pkt, uint32_t *max_ack)
118
{
119
if (g_queue_get_length(queue) <= MAX_QUEUE_SIZE) {
120
if (pkt->ip->ip_p == IPPROTO_TCP) {
121
+ fill_pkt_tcp_info(pkt, max_ack);
122
g_queue_insert_sorted(queue,
123
pkt,
124
(GCompareDataFunc)seq_sorter,
125
@@ -XXX,XX +XXX,XX @@ static int packet_enqueue(CompareState *s, int mode, Connection **con)
126
}
127
128
if (mode == PRIMARY_IN) {
129
- if (!colo_insert_packet(&conn->primary_list, pkt)) {
130
+ if (!colo_insert_packet(&conn->primary_list, pkt, &conn->pack)) {
131
error_report("colo compare primary queue size too big,"
132
"drop packet");
133
}
134
} else {
135
- if (!colo_insert_packet(&conn->secondary_list, pkt)) {
136
+ if (!colo_insert_packet(&conn->secondary_list, pkt, &conn->sack)) {
137
error_report("colo compare secondary queue size too big,"
138
"drop packet");
139
}
140
@@ -XXX,XX +XXX,XX @@ static int packet_enqueue(CompareState *s, int mode, Connection **con)
141
return 0;
142
}
143
144
+static inline bool after(uint32_t seq1, uint32_t seq2)
145
+{
146
+ return (int32_t)(seq1 - seq2) > 0;
147
+}
148
+
149
+static void colo_release_primary_pkt(CompareState *s, Packet *pkt)
150
+{
151
+ int ret;
152
+ ret = compare_chr_send(s,
153
+ pkt->data,
154
+ pkt->size,
155
+ pkt->vnet_hdr_len);
156
+ if (ret < 0) {
157
+ error_report("colo send primary packet failed");
158
+ }
159
+ trace_colo_compare_main("packet same and release packet");
160
+ packet_destroy(pkt, NULL);
161
+}
162
+
163
/*
164
* The IP packets sent by primary and secondary
165
* will be compared in here
166
@@ -XXX,XX +XXX,XX @@ static int colo_compare_packet_payload(Packet *ppkt,
167
}
168
169
/*
170
- * Called from the compare thread on the primary
171
- * for compare tcp packet
172
- * compare_tcp copied from Dr. David Alan Gilbert's branch
173
- */
174
-static int colo_packet_compare_tcp(Packet *spkt, Packet *ppkt)
175
+ * return true means that the payload is consist and
176
+ * need to make the next comparison, false means do
177
+ * the checkpoint
178
+*/
179
+static bool colo_mark_tcp_pkt(Packet *ppkt, Packet *spkt,
180
+ int8_t *mark, uint32_t max_ack)
181
{
182
- struct tcphdr *ptcp, *stcp;
183
- int res;
184
+ *mark = 0;
185
+
186
+ if (ppkt->tcp_seq == spkt->tcp_seq && ppkt->seq_end == spkt->seq_end) {
187
+ if (colo_compare_packet_payload(ppkt, spkt,
188
+ ppkt->header_size, spkt->header_size,
189
+ ppkt->payload_size)) {
190
+ *mark = COLO_COMPARE_FREE_SECONDARY | COLO_COMPARE_FREE_PRIMARY;
191
+ return true;
192
+ }
193
+ }
194
+ if (ppkt->tcp_seq == spkt->tcp_seq && ppkt->seq_end == spkt->seq_end) {
195
+ if (colo_compare_packet_payload(ppkt, spkt,
196
+ ppkt->header_size, spkt->header_size,
197
+ ppkt->payload_size)) {
198
+ *mark = COLO_COMPARE_FREE_SECONDARY | COLO_COMPARE_FREE_PRIMARY;
199
+ return true;
200
+ }
201
+ }
202
+
203
+ /* one part of secondary packet payload still need to be compared */
204
+ if (!after(ppkt->seq_end, spkt->seq_end)) {
205
+ if (colo_compare_packet_payload(ppkt, spkt,
206
+ ppkt->header_size + ppkt->offset,
207
+ spkt->header_size + spkt->offset,
208
+ ppkt->payload_size - ppkt->offset)) {
209
+ if (!after(ppkt->tcp_ack, max_ack)) {
210
+ *mark = COLO_COMPARE_FREE_PRIMARY;
211
+ spkt->offset += ppkt->payload_size - ppkt->offset;
212
+ return true;
213
+ } else {
214
+ /* secondary guest hasn't ack the data, don't send
215
+ * out this packet
216
+ */
217
+ return false;
218
+ }
219
+ }
220
+ } else {
221
+ /* primary packet is longer than secondary packet, compare
222
+ * the same part and mark the primary packet offset
223
+ */
224
+ if (colo_compare_packet_payload(ppkt, spkt,
225
+ ppkt->header_size + ppkt->offset,
226
+ spkt->header_size + spkt->offset,
227
+ spkt->payload_size - spkt->offset)) {
228
+ *mark = COLO_COMPARE_FREE_SECONDARY;
229
+ ppkt->offset += spkt->payload_size - spkt->offset;
230
+ return true;
231
+ }
232
+ }
233
234
- trace_colo_compare_main("compare tcp");
235
+ return false;
236
+}
237
238
- ptcp = (struct tcphdr *)ppkt->transport_header;
239
- stcp = (struct tcphdr *)spkt->transport_header;
240
+static void colo_compare_tcp(CompareState *s, Connection *conn)
241
+{
242
+ Packet *ppkt = NULL, *spkt = NULL;
243
+ int8_t mark;
244
245
/*
246
- * The 'identification' field in the IP header is *very* random
247
- * it almost never matches. Fudge this by ignoring differences in
248
- * unfragmented packets; they'll normally sort themselves out if different
249
- * anyway, and it should recover at the TCP level.
250
- * An alternative would be to get both the primary and secondary to rewrite
251
- * somehow; but that would need some sync traffic to sync the state
252
- */
253
- if (ntohs(ppkt->ip->ip_off) & IP_DF) {
254
- spkt->ip->ip_id = ppkt->ip->ip_id;
255
- /* and the sum will be different if the IDs were different */
256
- spkt->ip->ip_sum = ppkt->ip->ip_sum;
257
+ * If ppkt and spkt have the same payload, but ppkt's ACK
258
+ * is greater than spkt's ACK, in this case we can not
259
+ * send the ppkt because it will cause the secondary guest
260
+ * to miss sending some data in the next. Therefore, we
261
+ * record the maximum ACK in the current queue at both
262
+ * primary side and secondary side. Only when the ack is
263
+ * less than the smaller of the two maximum ack, then we
264
+ * can ensure that the packet's payload is acknowledged by
265
+ * primary and secondary.
266
+ */
267
+ uint32_t min_ack = conn->pack > conn->sack ? conn->sack : conn->pack;
268
+
269
+pri:
270
+ if (g_queue_is_empty(&conn->primary_list)) {
271
+ return;
272
}
273
+ ppkt = g_queue_pop_head(&conn->primary_list);
274
+sec:
275
+ if (g_queue_is_empty(&conn->secondary_list)) {
276
+ g_queue_push_head(&conn->primary_list, ppkt);
277
+ return;
278
+ }
279
+ spkt = g_queue_pop_head(&conn->secondary_list);
280
281
- /*
282
- * Check tcp header length for tcp option field.
283
- * th_off > 5 means this tcp packet have options field.
284
- * The tcp options maybe always different.
285
- * for example:
286
- * From RFC 7323.
287
- * TCP Timestamps option (TSopt):
288
- * Kind: 8
289
- *
290
- * Length: 10 bytes
291
- *
292
- * +-------+-------+---------------------+---------------------+
293
- * |Kind=8 | 10 | TS Value (TSval) |TS Echo Reply (TSecr)|
294
- * +-------+-------+---------------------+---------------------+
295
- * 1 1 4 4
296
- *
297
- * In this case the primary guest's timestamp always different with
298
- * the secondary guest's timestamp. COLO just focus on payload,
299
- * so we just need skip this field.
300
- */
301
+ if (ppkt->tcp_seq == ppkt->seq_end) {
302
+ colo_release_primary_pkt(s, ppkt);
303
+ ppkt = NULL;
304
+ }
305
306
- ptrdiff_t ptcp_offset, stcp_offset;
307
+ if (ppkt && conn->compare_seq && !after(ppkt->seq_end, conn->compare_seq)) {
308
+ trace_colo_compare_main("pri: this packet has compared");
309
+ colo_release_primary_pkt(s, ppkt);
310
+ ppkt = NULL;
311
+ }
312
313
- ptcp_offset = ppkt->transport_header - (uint8_t *)ppkt->data
314
- + (ptcp->th_off << 2) - ppkt->vnet_hdr_len;
315
- stcp_offset = spkt->transport_header - (uint8_t *)spkt->data
316
- + (stcp->th_off << 2) - spkt->vnet_hdr_len;
317
- if (ppkt->size - ptcp_offset == spkt->size - stcp_offset) {
318
- res = colo_compare_packet_payload(ppkt, spkt,
319
- ptcp_offset, stcp_offset,
320
- ppkt->size - ptcp_offset);
321
+ if (spkt->tcp_seq == spkt->seq_end) {
322
+ packet_destroy(spkt, NULL);
323
+ if (!ppkt) {
324
+ goto pri;
325
+ } else {
326
+ goto sec;
327
+ }
328
} else {
329
- trace_colo_compare_main("TCP: payload size of packets are different");
330
- res = -1;
331
+ if (conn->compare_seq && !after(spkt->seq_end, conn->compare_seq)) {
332
+ trace_colo_compare_main("sec: this packet has compared");
333
+ packet_destroy(spkt, NULL);
334
+ if (!ppkt) {
335
+ goto pri;
336
+ } else {
337
+ goto sec;
338
+ }
339
+ }
340
+ if (!ppkt) {
341
+ g_queue_push_head(&conn->secondary_list, spkt);
342
+ goto pri;
343
+ }
344
}
345
346
- if (res != 0 &&
347
- trace_event_get_state_backends(TRACE_COLO_COMPARE_MISCOMPARE)) {
348
- char pri_ip_src[20], pri_ip_dst[20], sec_ip_src[20], sec_ip_dst[20];
349
-
350
- strcpy(pri_ip_src, inet_ntoa(ppkt->ip->ip_src));
351
- strcpy(pri_ip_dst, inet_ntoa(ppkt->ip->ip_dst));
352
- strcpy(sec_ip_src, inet_ntoa(spkt->ip->ip_src));
353
- strcpy(sec_ip_dst, inet_ntoa(spkt->ip->ip_dst));
354
-
355
- trace_colo_compare_ip_info(ppkt->size, pri_ip_src,
356
- pri_ip_dst, spkt->size,
357
- sec_ip_src, sec_ip_dst);
358
-
359
- trace_colo_compare_tcp_info("pri tcp packet",
360
- ntohl(ptcp->th_seq),
361
- ntohl(ptcp->th_ack),
362
- res, ptcp->th_flags,
363
- ppkt->size);
364
-
365
- trace_colo_compare_tcp_info("sec tcp packet",
366
- ntohl(stcp->th_seq),
367
- ntohl(stcp->th_ack),
368
- res, stcp->th_flags,
369
- spkt->size);
370
+ if (colo_mark_tcp_pkt(ppkt, spkt, &mark, min_ack)) {
371
+ trace_colo_compare_tcp_info("pri",
372
+ ppkt->tcp_seq, ppkt->tcp_ack,
373
+ ppkt->header_size, ppkt->payload_size,
374
+ ppkt->offset, ppkt->flags);
375
+
376
+ trace_colo_compare_tcp_info("sec",
377
+ spkt->tcp_seq, spkt->tcp_ack,
378
+ spkt->header_size, spkt->payload_size,
379
+ spkt->offset, spkt->flags);
380
+
381
+ if (mark == COLO_COMPARE_FREE_PRIMARY) {
382
+ conn->compare_seq = ppkt->seq_end;
383
+ colo_release_primary_pkt(s, ppkt);
384
+ g_queue_push_head(&conn->secondary_list, spkt);
385
+ goto pri;
386
+ }
387
+ if (mark == COLO_COMPARE_FREE_SECONDARY) {
388
+ conn->compare_seq = spkt->seq_end;
389
+ packet_destroy(spkt, NULL);
390
+ goto sec;
391
+ }
392
+ if (mark == (COLO_COMPARE_FREE_PRIMARY | COLO_COMPARE_FREE_SECONDARY)) {
393
+ conn->compare_seq = ppkt->seq_end;
394
+ colo_release_primary_pkt(s, ppkt);
395
+ packet_destroy(spkt, NULL);
396
+ goto pri;
397
+ }
398
+ } else {
399
+ g_queue_push_head(&conn->primary_list, ppkt);
400
+ g_queue_push_head(&conn->secondary_list, spkt);
401
402
qemu_hexdump((char *)ppkt->data, stderr,
403
"colo-compare ppkt", ppkt->size);
404
qemu_hexdump((char *)spkt->data, stderr,
405
"colo-compare spkt", spkt->size);
406
- }
407
408
- return res;
409
+ /*
410
+ * colo_compare_inconsistent_notify();
411
+ * TODO: notice to checkpoint();
412
+ */
413
+ }
414
}
415
416
+
417
/*
418
* Called from the compare thread on the primary
419
* for compare udp packet
420
@@ -XXX,XX +XXX,XX @@ static void colo_old_packet_check(void *opaque)
421
(GCompareFunc)colo_old_packet_check_one_conn);
422
}
423
424
-/*
425
- * Called from the compare thread on the primary
426
- * for compare packet with secondary list of the
427
- * specified connection when a new packet was
428
- * queued to it.
429
- */
430
-static void colo_compare_connection(void *opaque, void *user_data)
431
+static void colo_compare_packet(CompareState *s, Connection *conn,
432
+ int (*HandlePacket)(Packet *spkt,
433
+ Packet *ppkt))
434
{
435
- CompareState *s = user_data;
436
- Connection *conn = opaque;
437
Packet *pkt = NULL;
438
GList *result = NULL;
439
- int ret;
440
441
while (!g_queue_is_empty(&conn->primary_list) &&
442
!g_queue_is_empty(&conn->secondary_list)) {
443
pkt = g_queue_pop_head(&conn->primary_list);
444
- switch (conn->ip_proto) {
445
- case IPPROTO_TCP:
446
- result = g_queue_find_custom(&conn->secondary_list,
447
- pkt, (GCompareFunc)colo_packet_compare_tcp);
448
- break;
449
- case IPPROTO_UDP:
450
- result = g_queue_find_custom(&conn->secondary_list,
451
- pkt, (GCompareFunc)colo_packet_compare_udp);
452
- break;
453
- case IPPROTO_ICMP:
454
- result = g_queue_find_custom(&conn->secondary_list,
455
- pkt, (GCompareFunc)colo_packet_compare_icmp);
456
- break;
457
- default:
458
- result = g_queue_find_custom(&conn->secondary_list,
459
- pkt, (GCompareFunc)colo_packet_compare_other);
460
- break;
461
- }
462
+ result = g_queue_find_custom(&conn->secondary_list,
463
+ pkt, (GCompareFunc)HandlePacket);
464
465
if (result) {
466
- ret = compare_chr_send(s,
467
- pkt->data,
468
- pkt->size,
469
- pkt->vnet_hdr_len);
470
- if (ret < 0) {
471
- error_report("colo_send_primary_packet failed");
472
- }
473
- trace_colo_compare_main("packet same and release packet");
474
+ colo_release_primary_pkt(s, pkt);
475
g_queue_remove(&conn->secondary_list, result->data);
476
- packet_destroy(pkt, NULL);
477
} else {
478
/*
479
* If one packet arrive late, the secondary_list or
480
@@ -XXX,XX +XXX,XX @@ static void colo_compare_connection(void *opaque, void *user_data)
481
}
482
}
483
484
+/*
485
+ * Called from the compare thread on the primary
486
+ * for compare packet with secondary list of the
487
+ * specified connection when a new packet was
488
+ * queued to it.
489
+ */
490
+static void colo_compare_connection(void *opaque, void *user_data)
491
+{
492
+ CompareState *s = user_data;
493
+ Connection *conn = opaque;
494
+
495
+ switch (conn->ip_proto) {
496
+ case IPPROTO_TCP:
497
+ colo_compare_tcp(s, conn);
498
+ break;
499
+ case IPPROTO_UDP:
500
+ colo_compare_packet(s, conn, colo_packet_compare_udp);
501
+ break;
502
+ case IPPROTO_ICMP:
503
+ colo_compare_packet(s, conn, colo_packet_compare_icmp);
504
+ break;
505
+ default:
506
+ colo_compare_packet(s, conn, colo_packet_compare_other);
507
+ break;
508
+ }
509
+}
510
+
511
static int compare_chr_send(CompareState *s,
512
const uint8_t *buf,
513
uint32_t size,
514
diff --git a/net/colo.c b/net/colo.c
515
index XXXXXXX..XXXXXXX 100644
516
--- a/net/colo.c
517
+++ b/net/colo.c
518
@@ -XXX,XX +XXX,XX @@ Connection *connection_new(ConnectionKey *key)
519
conn->processing = false;
520
conn->offset = 0;
521
conn->syn_flag = 0;
522
+ conn->pack = 0;
523
+ conn->sack = 0;
524
g_queue_init(&conn->primary_list);
525
g_queue_init(&conn->secondary_list);
526
527
@@ -XXX,XX +XXX,XX @@ Packet *packet_new(const void *data, int size, int vnet_hdr_len)
528
pkt->size = size;
529
pkt->creation_ms = qemu_clock_get_ms(QEMU_CLOCK_HOST);
530
pkt->vnet_hdr_len = vnet_hdr_len;
531
+ pkt->tcp_seq = 0;
532
+ pkt->tcp_ack = 0;
533
+ pkt->seq_end = 0;
534
+ pkt->header_size = 0;
535
+ pkt->payload_size = 0;
536
+ pkt->offset = 0;
537
+ pkt->flags = 0;
538
539
return pkt;
540
}
541
diff --git a/net/colo.h b/net/colo.h
542
index XXXXXXX..XXXXXXX 100644
543
--- a/net/colo.h
544
+++ b/net/colo.h
545
@@ -XXX,XX +XXX,XX @@ typedef struct Packet {
546
int64_t creation_ms;
547
/* Get vnet_hdr_len from filter */
548
uint32_t vnet_hdr_len;
549
+ uint32_t tcp_seq; /* sequence number */
550
+ uint32_t tcp_ack; /* acknowledgement number */
551
+ /* the sequence number of the last byte of the packet */
552
+ uint32_t seq_end;
553
+ uint8_t header_size; /* the header length */
554
+ uint16_t payload_size; /* the payload length */
555
+ /* record the payload offset(the length that has been compared) */
556
+ uint16_t offset;
557
+ uint8_t flags; /* Flags(aka Control bits) */
558
} Packet;
559
560
typedef struct ConnectionKey {
561
@@ -XXX,XX +XXX,XX @@ typedef struct Connection {
562
/* flag to enqueue unprocessed_connections */
563
bool processing;
564
uint8_t ip_proto;
565
+ /* record the sequence number that has been compared */
566
+ uint32_t compare_seq;
567
+ /* the maximum of acknowledgement number in primary_list queue */
568
+ uint32_t pack;
569
+ /* the maximum of acknowledgement number in secondary_list queue */
570
+ uint32_t sack;
571
/* offset = secondary_seq - primary_seq */
572
tcp_seq offset;
573
/*
574
diff --git a/net/trace-events b/net/trace-events
575
index XXXXXXX..XXXXXXX 100644
576
--- a/net/trace-events
577
+++ b/net/trace-events
578
@@ -XXX,XX +XXX,XX @@ colo_compare_icmp_miscompare(const char *sta, int size) ": %s = %d"
579
colo_compare_ip_info(int psize, const char *sta, const char *stb, int ssize, const char *stc, const char *std) "ppkt size = %d, ip_src = %s, ip_dst = %s, spkt size = %d, ip_src = %s, ip_dst = %s"
580
colo_old_packet_check_found(int64_t old_time) "%" PRId64
581
colo_compare_miscompare(void) ""
582
-colo_compare_tcp_info(const char *pkt, uint32_t seq, uint32_t ack, int res, uint32_t flag, int size) "side: %s seq/ack= %u/%u res= %d flags= 0x%x pkt_size: %d\n"
583
+colo_compare_tcp_info(const char *pkt, uint32_t seq, uint32_t ack, int hdlen, int pdlen, int offset, int flags) "%s: seq/ack= %u/%u hdlen= %d pdlen= %d offset= %d flags=%d\n"
584
585
# net/filter-rewriter.c
586
colo_filter_rewriter_debug(void) ""
587
--
588
2.7.4
589
590
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Thomas Huth <thuth@redhat.com>
2
2
3
gently asked by his automatic reply :)
3
The early exits in case of errors leak the memory allocated for nd_id.
4
Fix it by using a "goto out" to the cleanup at the end of the function
5
instead.
4
6
5
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Signed-off-by: Thomas Huth <thuth@redhat.com>
6
Signed-off-by: Jason Wang <jasowang@redhat.com>
10
Signed-off-by: Jason Wang <jasowang@redhat.com>
7
---
11
---
8
MAINTAINERS | 8 ++++----
12
net/net.c | 6 ++++--
9
1 file changed, 4 insertions(+), 4 deletions(-)
13
1 file changed, 4 insertions(+), 2 deletions(-)
10
14
11
diff --git a/MAINTAINERS b/MAINTAINERS
15
diff --git a/net/net.c b/net/net.c
12
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
13
--- a/MAINTAINERS
17
--- a/net/net.c
14
+++ b/MAINTAINERS
18
+++ b/net/net.c
15
@@ -XXX,XX +XXX,XX @@ F: hw/scsi/mfi.h
19
@@ -XXX,XX +XXX,XX @@ static int net_param_nic(void *dummy, QemuOpts *opts, Error **errp)
16
F: tests/megasas-test.c
20
g_free(mac);
17
21
if (ret) {
18
Network packet abstractions
22
error_setg(errp, "invalid syntax for ethernet address");
19
-M: Dmitry Fleytman <dmitry@daynix.com>
23
- return -1;
20
+M: Dmitry Fleytman <dmitry.fleytman@gmail.com>
24
+ goto out;
21
S: Maintained
25
}
22
F: include/net/eth.h
26
if (is_multicast_ether_addr(ni->macaddr.a)) {
23
F: net/eth.c
27
error_setg(errp, "NIC cannot have multicast MAC address");
24
@@ -XXX,XX +XXX,XX @@ F: hw/net/net_rx_pkt*
28
- return -1;
25
F: hw/net/net_tx_pkt*
29
+ ret = -1;
26
30
+ goto out;
27
Vmware
31
}
28
-M: Dmitry Fleytman <dmitry@daynix.com>
32
}
29
+M: Dmitry Fleytman <dmitry.fleytman@gmail.com>
33
qemu_macaddr_default_if_unset(&ni->macaddr);
30
S: Maintained
34
@@ -XXX,XX +XXX,XX @@ static int net_param_nic(void *dummy, QemuOpts *opts, Error **errp)
31
F: hw/net/vmxnet*
35
nb_nics++;
32
F: hw/scsi/vmw_pvscsi*
36
}
33
@@ -XXX,XX +XXX,XX @@ F: hw/mem/nvdimm.c
37
34
F: include/hw/mem/nvdimm.h
38
+out:
35
39
g_free(nd_id);
36
e1000x
40
return ret;
37
-M: Dmitry Fleytman <dmitry@daynix.com>
41
}
38
+M: Dmitry Fleytman <dmitry.fleytman@gmail.com>
39
S: Maintained
40
F: hw/net/e1000x*
41
42
e1000e
43
-M: Dmitry Fleytman <dmitry@daynix.com>
44
+M: Dmitry Fleytman <dmitry.fleytman@gmail.com>
45
S: Maintained
46
F: hw/net/e1000e*
47
48
--
42
--
49
2.7.4
43
2.7.4
50
44
51
45
diff view generated by jsdifflib
1
From: Thomas Huth <thuth@redhat.com>
1
From: Thomas Huth <thuth@redhat.com>
2
2
3
QEMU can emulate hubs to connect NICs and netdevs. This is currently
3
It's been marked as deprecated since QEMU v2.9.0, so that should have
4
primarily used for the mis-named 'vlan' feature of the networking
4
been enough time for everybody to either just drop unnecessary "vlan=0"
5
subsystem. Now the 'vlan' feature has been marked as deprecated, since
5
parameters, to switch to the modern -device + -netdev syntax for connecting
6
its name is rather confusing and the users often rather mis-configure
6
guest NICs with host network backends, or to switch to the "hubport" netdev
7
their network when trying to use it. But while the 'vlan' parameter
7
in case hubs are really wanted instead.
8
should be removed at one point in time, the basic idea of emulating
8
9
a hub in QEMU is still good: It's useful for bundling up the output of
9
Buglink: https://bugs.launchpad.net/qemu/+bug/658904
10
multiple NICs into one single l2tp netdev for example.
11
12
Now to be able to use the hubport feature without 'vlan's, there is one
13
missing piece: The possibility to connect a hubport to a netdev, too.
14
This patch adds this possibility by introducing a new "netdev=..."
15
parameter to the hubports.
16
17
To bundle up the output of multiple NICs into one socket netdev, you can
18
now run QEMU with these parameters for example:
19
20
qemu-system-ppc64 ... -netdev socket,id=s1,connect=:11122 \
21
-netdev hubport,hubid=1,id=h1,netdev=s1 \
22
-netdev hubport,hubid=1,id=h2 -device e1000,netdev=h2 \
23
-netdev hubport,hubid=1,id=h3 -device virtio-net-pci,netdev=h3
24
25
For using the socket netdev, you have got to start another QEMU as the
26
receiving side first, for example with network dumping enabled:
27
28
qemu-system-x86_64 -M isapc -netdev socket,id=s0,listen=:11122 \
29
-device ne2k_isa,netdev=s0 \
30
-object filter-dump,id=f1,netdev=s0,file=/tmp/dump.dat
31
32
After the ppc64 guest tried to boot from both NICs, you can see in the
33
dump file (using Wireshark, for example), that the output of both NICs
34
(the e1000 and the virtio-net-pci) has been successfully transfered
35
via the socket netdev in this case.
36
37
Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
38
Signed-off-by: Thomas Huth <thuth@redhat.com>
10
Signed-off-by: Thomas Huth <thuth@redhat.com>
11
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
39
Signed-off-by: Jason Wang <jasowang@redhat.com>
12
Signed-off-by: Jason Wang <jasowang@redhat.com>
40
---
13
---
41
net/hub.c | 27 +++++++++++++++++++++------
14
docs/qdev-device-use.txt | 3 --
42
net/hub.h | 3 ++-
15
hw/core/qdev-properties-system.c | 80 ----------------------------------------
43
net/net.c | 2 +-
16
include/hw/qdev-properties.h | 3 --
44
qapi/net.json | 4 +++-
17
include/net/net.h | 1 -
45
qemu-options.hx | 8 +++++---
18
net/net.c | 12 ++----
46
5 files changed, 32 insertions(+), 12 deletions(-)
19
qapi/net.json | 15 ++++----
47
20
qemu-doc.texi | 9 -----
48
diff --git a/net/hub.c b/net/hub.c
21
qemu-options.hx | 29 ++++++---------
49
index XXXXXXX..XXXXXXX 100644
22
8 files changed, 22 insertions(+), 130 deletions(-)
50
--- a/net/hub.c
23
51
+++ b/net/hub.c
24
diff --git a/docs/qdev-device-use.txt b/docs/qdev-device-use.txt
52
@@ -XXX,XX +XXX,XX @@
25
index XXXXXXX..XXXXXXX 100644
53
*/
26
--- a/docs/qdev-device-use.txt
54
27
+++ b/docs/qdev-device-use.txt
55
#include "qemu/osdep.h"
28
@@ -XXX,XX +XXX,XX @@ devices and ne2k_isa are.
56
+#include "qapi/error.h"
29
57
#include "monitor/monitor.h"
30
Some PCI devices aren't available with -net nic, e.g. i82558a.
58
#include "net/net.h"
31
59
#include "clients.h"
32
-To connect to a VLAN instead of an ordinary host part, replace
60
@@ -XXX,XX +XXX,XX @@ static NetClientInfo net_hub_port_info = {
33
-netdev=NET-ID by vlan=VLAN.
61
.cleanup = net_hub_port_cleanup,
34
-
35
=== Graphics Devices ===
36
37
Host and guest part of graphics devices have always been separate.
38
diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
39
index XXXXXXX..XXXXXXX 100644
40
--- a/hw/core/qdev-properties-system.c
41
+++ b/hw/core/qdev-properties-system.c
42
@@ -XXX,XX +XXX,XX @@ const PropertyInfo qdev_prop_netdev = {
43
.set = set_netdev,
62
};
44
};
63
45
64
-static NetHubPort *net_hub_port_new(NetHub *hub, const char *name)
46
-/* --- vlan --- */
65
+static NetHubPort *net_hub_port_new(NetHub *hub, const char *name,
47
-
66
+ NetClientState *hubpeer)
48
-static int print_vlan(DeviceState *dev, Property *prop, char *dest, size_t len)
67
{
49
-{
68
NetClientState *nc;
50
- NetClientState **ptr = qdev_get_prop_ptr(dev, prop);
69
NetHubPort *port;
51
-
70
@@ -XXX,XX +XXX,XX @@ static NetHubPort *net_hub_port_new(NetHub *hub, const char *name)
52
- if (*ptr) {
71
name = default_name;
53
- int id;
72
}
54
- if (!net_hub_id_for_client(*ptr, &id)) {
73
55
- return snprintf(dest, len, "%d", id);
74
- nc = qemu_new_net_client(&net_hub_port_info, NULL, "hub", name);
56
- }
75
+ nc = qemu_new_net_client(&net_hub_port_info, hubpeer, "hub", name);
57
- }
76
port = DO_UPCAST(NetHubPort, nc, nc);
58
-
77
port->id = id;
59
- return snprintf(dest, len, "<null>");
78
port->hub = hub;
60
-}
79
@@ -XXX,XX +XXX,XX @@ static NetHubPort *net_hub_port_new(NetHub *hub, const char *name)
61
-
80
62
-static void get_vlan(Object *obj, Visitor *v, const char *name, void *opaque,
81
/**
63
- Error **errp)
82
* Create a port on a given hub
64
-{
83
+ * @hub_id: Number of the hub
65
- DeviceState *dev = DEVICE(obj);
84
* @name: Net client name or NULL for default name.
66
- Property *prop = opaque;
85
+ * @hubpeer: Peer to use (if "netdev=id" has been specified)
67
- NetClientState **ptr = qdev_get_prop_ptr(dev, prop);
86
*
68
- int32_t id = -1;
87
* If there is no existing hub with the given id then a new hub is created.
69
-
88
*/
70
- if (*ptr) {
89
-NetClientState *net_hub_add_port(int hub_id, const char *name)
71
- int hub_id;
90
+NetClientState *net_hub_add_port(int hub_id, const char *name,
72
- if (!net_hub_id_for_client(*ptr, &hub_id)) {
91
+ NetClientState *hubpeer)
73
- id = hub_id;
92
{
74
- }
93
NetHub *hub;
75
- }
94
NetHubPort *port;
76
-
95
@@ -XXX,XX +XXX,XX @@ NetClientState *net_hub_add_port(int hub_id, const char *name)
77
- visit_type_int32(v, name, &id, errp);
96
hub = net_hub_new(hub_id);
78
-}
97
}
79
-
98
80
-static void set_vlan(Object *obj, Visitor *v, const char *name, void *opaque,
99
- port = net_hub_port_new(hub, name);
81
- Error **errp)
100
+ port = net_hub_port_new(hub, name, hubpeer);
82
-{
101
return &port->nc;
83
- DeviceState *dev = DEVICE(obj);
102
}
84
- Property *prop = opaque;
103
85
- NICPeers *peers_ptr = qdev_get_prop_ptr(dev, prop);
104
@@ -XXX,XX +XXX,XX @@ NetClientState *net_hub_port_find(int hub_id)
86
- NetClientState **ptr = &peers_ptr->ncs[0];
105
}
87
- Error *local_err = NULL;
106
}
88
- int32_t id;
107
89
- NetClientState *hubport;
108
- nc = net_hub_add_port(hub_id, NULL);
90
-
109
+ nc = net_hub_add_port(hub_id, NULL, NULL);
91
- if (dev->realized) {
110
return nc;
92
- qdev_prop_set_after_realize(dev, name, errp);
111
}
93
- return;
112
94
- }
113
@@ -XXX,XX +XXX,XX @@ int net_init_hubport(const Netdev *netdev, const char *name,
95
-
114
NetClientState *peer, Error **errp)
96
- visit_type_int32(v, name, &id, &local_err);
115
{
97
- if (local_err) {
116
const NetdevHubPortOptions *hubport;
98
- error_propagate(errp, local_err);
117
+ NetClientState *hubpeer = NULL;
99
- return;
118
100
- }
119
assert(netdev->type == NET_CLIENT_DRIVER_HUBPORT);
101
- if (id == -1) {
120
assert(!peer);
102
- *ptr = NULL;
121
hubport = &netdev->u.hubport;
103
- return;
122
104
- }
123
- net_hub_add_port(hubport->hubid, name);
105
- if (*ptr) {
124
+ if (hubport->has_netdev) {
106
- error_set_from_qdev_prop_error(errp, -EINVAL, dev, prop, name);
125
+ hubpeer = qemu_find_netdev(hubport->netdev);
107
- return;
126
+ if (!hubpeer) {
108
- }
127
+ error_setg(errp, "netdev '%s' not found", hubport->netdev);
109
-
128
+ return -1;
110
- hubport = net_hub_port_find(id);
129
+ }
111
- if (!hubport) {
130
+ }
112
- error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
131
+
113
- name, prop->info->name);
132
+ net_hub_add_port(hubport->hubid, name, hubpeer);
114
- return;
133
+
115
- }
134
return 0;
116
- *ptr = hubport;
135
}
117
-}
136
118
-
137
diff --git a/net/hub.h b/net/hub.h
119
-const PropertyInfo qdev_prop_vlan = {
138
index XXXXXXX..XXXXXXX 100644
120
- .name = "int32",
139
--- a/net/hub.h
121
- .description = "Integer VLAN id to connect to",
140
+++ b/net/hub.h
122
- .print = print_vlan,
141
@@ -XXX,XX +XXX,XX @@
123
- .get = get_vlan,
142
124
- .set = set_vlan,
143
#include "qemu-common.h"
125
-};
144
126
145
-NetClientState *net_hub_add_port(int hub_id, const char *name);
127
void qdev_prop_set_drive(DeviceState *dev, const char *name,
146
+NetClientState *net_hub_add_port(int hub_id, const char *name,
128
BlockBackend *value, Error **errp)
147
+ NetClientState *hubpeer);
129
diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
148
NetClientState *net_hub_find_client_by_name(int hub_id, const char *name);
130
index XXXXXXX..XXXXXXX 100644
149
void net_hub_info(Monitor *mon);
131
--- a/include/hw/qdev-properties.h
150
void net_hub_check_clients(void);
132
+++ b/include/hw/qdev-properties.h
133
@@ -XXX,XX +XXX,XX @@ extern const PropertyInfo qdev_prop_bios_chs_trans;
134
extern const PropertyInfo qdev_prop_fdc_drive_type;
135
extern const PropertyInfo qdev_prop_drive;
136
extern const PropertyInfo qdev_prop_netdev;
137
-extern const PropertyInfo qdev_prop_vlan;
138
extern const PropertyInfo qdev_prop_pci_devfn;
139
extern const PropertyInfo qdev_prop_blocksize;
140
extern const PropertyInfo qdev_prop_pci_host_devaddr;
141
@@ -XXX,XX +XXX,XX @@ extern const PropertyInfo qdev_prop_off_auto_pcibar;
142
DEFINE_PROP(_n, _s, _f, qdev_prop_string, char*)
143
#define DEFINE_PROP_NETDEV(_n, _s, _f) \
144
DEFINE_PROP(_n, _s, _f, qdev_prop_netdev, NICPeers)
145
-#define DEFINE_PROP_VLAN(_n, _s, _f) \
146
- DEFINE_PROP(_n, _s, _f, qdev_prop_vlan, NICPeers)
147
#define DEFINE_PROP_DRIVE(_n, _s, _f) \
148
DEFINE_PROP(_n, _s, _f, qdev_prop_drive, BlockBackend *)
149
#define DEFINE_PROP_MACADDR(_n, _s, _f) \
150
diff --git a/include/net/net.h b/include/net/net.h
151
index XXXXXXX..XXXXXXX 100644
152
--- a/include/net/net.h
153
+++ b/include/net/net.h
154
@@ -XXX,XX +XXX,XX @@ typedef struct NICConf {
155
156
#define DEFINE_NIC_PROPERTIES(_state, _conf) \
157
DEFINE_PROP_MACADDR("mac", _state, _conf.macaddr), \
158
- DEFINE_PROP_VLAN("vlan", _state, _conf.peers), \
159
DEFINE_PROP_NETDEV("netdev", _state, _conf.peers)
160
161
151
diff --git a/net/net.c b/net/net.c
162
diff --git a/net/net.c b/net/net.c
152
index XXXXXXX..XXXXXXX 100644
163
index XXXXXXX..XXXXXXX 100644
153
--- a/net/net.c
164
--- a/net/net.c
154
+++ b/net/net.c
165
+++ b/net/net.c
155
@@ -XXX,XX +XXX,XX @@ static int net_client_init1(const void *object, bool is_netdev, Error **errp)
166
@@ -XXX,XX +XXX,XX @@ static int net_client_init1(const void *object, bool is_netdev, Error **errp)
156
/* Do not add to a vlan if it's a nic with a netdev= parameter. */
167
const Netdev *netdev;
168
const char *name;
169
NetClientState *peer = NULL;
170
- static bool vlan_warned;
171
172
if (is_netdev) {
173
netdev = object;
174
@@ -XXX,XX +XXX,XX @@ static int net_client_init1(const void *object, bool is_netdev, Error **errp)
175
return -1;
176
}
177
178
- /* Do not add to a vlan if it's a nic with a netdev= parameter. */
179
+ /* Do not add to a hub if it's a nic with a netdev= parameter. */
157
if (netdev->type != NET_CLIENT_DRIVER_NIC ||
180
if (netdev->type != NET_CLIENT_DRIVER_NIC ||
158
!opts->u.nic.has_netdev) {
181
!opts->u.nic.has_netdev) {
159
- peer = net_hub_add_port(net->has_vlan ? net->vlan : 0, NULL);
182
- peer = net_hub_add_port(net->has_vlan ? net->vlan : 0, NULL, NULL);
160
+ peer = net_hub_add_port(net->has_vlan ? net->vlan : 0, NULL, NULL);
183
- }
184
-
185
- if (net->has_vlan && !vlan_warned) {
186
- error_report("'vlan' is deprecated. Please use 'netdev' instead.");
187
- vlan_warned = true;
188
+ peer = net_hub_add_port(0, NULL, NULL);
161
}
189
}
162
190
}
163
if (net->has_vlan && !vlan_warned) {
191
192
@@ -XXX,XX +XXX,XX @@ void qmp_set_link(const char *name, bool up, Error **errp)
193
* If the peer is a HUBPORT or a backend, we do not change the
194
* link status.
195
*
196
- * This behavior is compatible with qemu vlans where there could be
197
+ * This behavior is compatible with qemu hubs where there could be
198
* multiple clients that can still communicate with each other in
199
* disconnected mode. For now maintain this compatibility.
200
*/
164
diff --git a/qapi/net.json b/qapi/net.json
201
diff --git a/qapi/net.json b/qapi/net.json
165
index XXXXXXX..XXXXXXX 100644
202
index XXXXXXX..XXXXXXX 100644
166
--- a/qapi/net.json
203
--- a/qapi/net.json
167
+++ b/qapi/net.json
204
+++ b/qapi/net.json
168
@@ -XXX,XX +XXX,XX @@
205
@@ -XXX,XX +XXX,XX @@
169
# Connect two or more net clients through a software hub.
206
##
170
#
207
# @NetdevTapOptions:
171
# @hubid: hub identifier number
208
#
172
+# @netdev: used to connect hub to a netdev instead of a device (since 2.12)
209
-# Connect the host TAP network interface name to the VLAN.
210
+# Used to configure a host TAP network interface backend.
211
#
212
# @ifname: interface name
213
#
214
@@ -XXX,XX +XXX,XX @@
215
##
216
# @NetdevSocketOptions:
217
#
218
-# Connect the VLAN to a remote VLAN in another QEMU virtual machine using a TCP
219
-# socket connection.
220
+# Socket netdevs are used to establish a network connection to another
221
+# QEMU virtual machine via a TCP socket.
222
#
223
# @fd: file descriptor of an already opened socket
224
#
225
@@ -XXX,XX +XXX,XX @@
226
##
227
# @NetdevL2TPv3Options:
228
#
229
-# Connect the VLAN to Ethernet over L2TPv3 Static tunnel
230
+# Configure an Ethernet over L2TPv3 tunnel.
231
#
232
# @src: source address
233
#
234
@@ -XXX,XX +XXX,XX @@
235
##
236
# @NetdevVdeOptions:
237
#
238
-# Connect the VLAN to a vde switch running on the host.
239
+# Connect to a vde switch running on the host.
240
#
241
# @sock: socket path
242
#
243
@@ -XXX,XX +XXX,XX @@
244
#
245
# Captures the configuration of a network device; legacy.
246
#
247
-# @vlan: vlan number
248
-#
249
# @id: identifier for monitor commands
250
#
251
# @name: identifier for monitor commands, ignored if @id is present
252
@@ -XXX,XX +XXX,XX @@
253
# @opts: device type specific properties (legacy)
173
#
254
#
174
# Since: 1.2
255
# Since: 1.2
175
##
256
+#
176
{ 'struct': 'NetdevHubPortOptions',
257
+# 'vlan' - removed with 2.12
258
##
259
{ 'struct': 'NetLegacy',
177
'data': {
260
'data': {
178
- 'hubid': 'int32' } }
261
- '*vlan': 'int32',
179
+ 'hubid': 'int32',
262
'*id': 'str',
180
+ '*netdev': 'str' } }
263
'*name': 'str',
181
264
'opts': 'NetLegacyOptions' } }
182
##
265
diff --git a/qemu-doc.texi b/qemu-doc.texi
183
# @NetdevNetmapOptions:
266
index XXXXXXX..XXXXXXX 100644
267
--- a/qemu-doc.texi
268
+++ b/qemu-doc.texi
269
@@ -XXX,XX +XXX,XX @@ with ``-device ...,netdev=x''), or ``-nic user,smb=/some/dir''
270
(for embedded NICs). The new syntax allows different settings to be
271
provided per NIC.
272
273
-@subsection -net vlan (since 2.9.0)
274
-
275
-The ``-net vlan=NN'' argument was mostly used to attach separate
276
-network backends to different virtual NICs. This is the default
277
-behavior for ``-netdev'' and ``-nic''. You can connect multiple
278
-``-netdev'' and ``-nic'' devices to the same network using the
279
-"hubport" network backend, created with ``-netdev hubport,hubid=NN,...''
280
-and ``-nic hubport,hubid=NN''.
281
-
282
@subsection -drive cyls=...,heads=...,secs=...,trans=... (since 2.10.0)
283
284
The drive geometry arguments are replaced by the the geometry arguments
184
diff --git a/qemu-options.hx b/qemu-options.hx
285
diff --git a/qemu-options.hx b/qemu-options.hx
185
index XXXXXXX..XXXXXXX 100644
286
index XXXXXXX..XXXXXXX 100644
186
--- a/qemu-options.hx
287
--- a/qemu-options.hx
187
+++ b/qemu-options.hx
288
+++ b/qemu-options.hx
188
@@ -XXX,XX +XXX,XX @@ DEF("netdev", HAS_ARG, QEMU_OPTION_netdev,
289
@@ -XXX,XX +XXX,XX @@ DEF("netdev", HAS_ARG, QEMU_OPTION_netdev,
290
" configure a vhost-user network, backed by a chardev 'dev'\n"
189
#endif
291
#endif
190
"-netdev vhost-user,id=str,chardev=dev[,vhostforce=on|off]\n"
292
"-netdev hubport,id=str,hubid=n[,netdev=nd]\n"
191
" configure a vhost-user network, backed by a chardev 'dev'\n"
293
- " configure a hub port on QEMU VLAN 'n'\n", QEMU_ARCH_ALL)
192
- "-netdev hubport,id=str,hubid=n\n"
294
+ " configure a hub port on the hub with ID 'n'\n", QEMU_ARCH_ALL)
193
+ "-netdev hubport,id=str,hubid=n[,netdev=nd]\n"
295
DEF("nic", HAS_ARG, QEMU_OPTION_nic,
194
" configure a hub port on QEMU VLAN 'n'\n", QEMU_ARCH_ALL)
296
"--nic [tap|bridge|"
297
#ifdef CONFIG_SLIRP
298
@@ -XXX,XX +XXX,XX @@ DEF("nic", HAS_ARG, QEMU_OPTION_nic,
299
" provided a 'user' network connection)\n",
300
QEMU_ARCH_ALL)
195
DEF("net", HAS_ARG, QEMU_OPTION_net,
301
DEF("net", HAS_ARG, QEMU_OPTION_net,
196
"-net nic[,vlan=n][,netdev=nd][,macaddr=mac][,model=type][,name=str][,addr=str][,vectors=v]\n"
302
- "-net nic[,vlan=n][,netdev=nd][,macaddr=mac][,model=type][,name=str][,addr=str][,vectors=v]\n"
197
@@ -XXX,XX +XXX,XX @@ vde_switch -F -sock /tmp/myswitch
303
+ "-net nic[,macaddr=mac][,model=type][,name=str][,addr=str][,vectors=v]\n"
198
qemu-system-i386 linux.img -net nic -net vde,sock=/tmp/myswitch
304
" configure or create an on-board (or machine default) NIC and\n"
199
@end example
305
- " connect it either to VLAN 'n' or the netdev 'nd' (for pluggable\n"
200
306
- " NICs please use '-device devtype,netdev=nd' instead)\n"
201
-@item -netdev hubport,id=@var{id},hubid=@var{hubid}
307
+ " connect it to hub 0 (please use -nic unless you need a hub)\n"
202
+@item -netdev hubport,id=@var{id},hubid=@var{hubid}[,netdev=@var{nd}]
308
"-net ["
203
309
#ifdef CONFIG_SLIRP
204
Create a hub port on QEMU "vlan" @var{hubid}.
310
"user|"
205
311
@@ -XXX,XX +XXX,XX @@ DEF("net", HAS_ARG, QEMU_OPTION_net,
206
The hubport netdev lets you connect a NIC to a QEMU "vlan" instead of a single
312
#ifdef CONFIG_NETMAP
207
netdev. @code{-net} and @code{-device} with parameter @option{vlan} create the
313
"netmap|"
208
-required hub automatically.
314
#endif
209
+required hub automatically. Alternatively, you can also connect the hubport
315
- "socket][,vlan=n][,option][,option][,...]\n"
210
+to another netdev with ID @var{nd} by using the @option{netdev=@var{nd}}
316
+ "socket][,option][,option][,...]\n"
211
+option.
317
" old way to initialize a host network interface\n"
212
318
" (use the -netdev option if possible instead)\n", QEMU_ARCH_ALL)
213
@item -netdev vhost-user,chardev=@var{id}[,vhostforce=on|off][,queues=n]
319
STEXI
214
320
@@ -XXX,XX +XXX,XX @@ qemu -m 512 -object memory-backend-file,id=mem,size=512M,mem-path=/hugetlbfs,sha
321
Create a hub port on the emulated hub with ID @var{hubid}.
322
323
The hubport netdev lets you connect a NIC to a QEMU emulated hub instead of a
324
-single netdev. @code{-net} and @code{-device} with the parameter @option{vlan}
325
-(deprecated), or @code{-nic hubport} can also be used to connect a
326
-network device or a NIC to a hub. Alternatively, you can also connect the
327
-hubport to another netdev with ID @var{nd} by using the @option{netdev=@var{nd}}
328
-option.
329
+single netdev. Alternatively, you can also connect the hubport to another
330
+netdev with ID @var{nd} by using the @option{netdev=@var{nd}} option.
331
332
-@item -net nic[,vlan=@var{n}][,netdev=@var{nd}][,macaddr=@var{mac}][,model=@var{type}] [,name=@var{name}][,addr=@var{addr}][,vectors=@var{v}]
333
+@item -net nic[,netdev=@var{nd}][,macaddr=@var{mac}][,model=@var{type}] [,name=@var{name}][,addr=@var{addr}][,vectors=@var{v}]
334
@findex -net
335
Legacy option to configure or create an on-board (or machine default) Network
336
-Interface Card(NIC) and connect it either to the emulated hub port ("vlan")
337
-with number @var{n} (@var{n} = 0 is the default), or to the netdev @var{nd}.
338
+Interface Card(NIC) and connect it either to the emulated hub with ID 0 (i.e.
339
+the default hub), or to the netdev @var{nd}.
340
The NIC is an e1000 by default on the PC target. Optionally, the MAC address
341
can be changed to @var{mac}, the device address set to @var{addr} (PCI cards
342
only), and a @var{name} can be assigned for use in monitor commands.
343
@@ -XXX,XX +XXX,XX @@ that the card should have; this option currently only affects virtio cards; set
344
NIC is created. QEMU can emulate several different models of network card.
345
Use @code{-net nic,model=help} for a list of available devices for your target.
346
347
-@item -net user|tap|bridge|socket|l2tpv3|vde[,...][,vlan=@var{n}][,name=@var{name}]
348
+@item -net user|tap|bridge|socket|l2tpv3|vde[,...][,name=@var{name}]
349
Configure a host network backend (with the options corresponding to the same
350
-@option{-netdev} option) and connect it to the emulated hub ("vlan") with the
351
-number @var{n} (default is number 0). Use @var{name} to specify the name of the
352
-hub port.
353
+@option{-netdev} option) and connect it to the emulated hub 0 (the default
354
+hub). Use @var{name} to specify the name of the hub port.
355
ETEXI
356
357
STEXI
215
--
358
--
216
2.7.4
359
2.7.4
217
360
218
361
diff view generated by jsdifflib
1
From: Thomas Huth <thuth@redhat.com>
1
From: Thomas Huth <thuth@redhat.com>
2
2
3
It does not make much sense to limit these commands to the legacy 'vlan'
3
'vlan' is very confusing since it does not mean something like IEEE
4
concept only, they should work with the modern netdevs, too. So now
4
802.1Q, but rather emulated hubs, so let's switch to that terminology
5
it is possible to use this command with one, two or three parameters.
5
instead.
6
6
7
With one parameter, the command installs a hostfwd rule on the default
7
Buglink: https://bugs.launchpad.net/qemu/+bug/658904
8
"user" network:
8
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
9
hostfwd_add tcp:...
10
11
With two parameters, the command installs a hostfwd rule on a netdev
12
(that's the new way of using this command):
13
hostfwd_add netdev_id tcp:...
14
15
With three parameters, the command installs a rule on a 'vlan' (aka hub):
16
hostfwd_add hub_id name tcp:...
17
18
Same applies to the hostfwd_remove command now.
19
20
Signed-off-by: Thomas Huth <thuth@redhat.com>
9
Signed-off-by: Thomas Huth <thuth@redhat.com>
21
Signed-off-by: Jason Wang <jasowang@redhat.com>
10
Signed-off-by: Jason Wang <jasowang@redhat.com>
22
---
11
---
23
hmp-commands.hx | 4 ++--
12
net/hub.c | 7 +++----
24
net/slirp.c | 33 +++++++++++++++++++++++----------
13
net/slirp.c | 8 ++++----
25
2 files changed, 25 insertions(+), 12 deletions(-)
14
net/tap.c | 4 ++--
15
3 files changed, 9 insertions(+), 10 deletions(-)
26
16
27
diff --git a/hmp-commands.hx b/hmp-commands.hx
17
diff --git a/net/hub.c b/net/hub.c
28
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
29
--- a/hmp-commands.hx
19
--- a/net/hub.c
30
+++ b/hmp-commands.hx
20
+++ b/net/hub.c
31
@@ -XXX,XX +XXX,XX @@ ETEXI
21
@@ -XXX,XX +XXX,XX @@
32
{
22
33
.name = "hostfwd_add",
23
/*
34
.args_type = "arg1:s,arg2:s?,arg3:s?",
24
* A hub broadcasts incoming packets to all its ports except the source port.
35
- .params = "[vlan_id name] [tcp|udp]:[hostaddr]:hostport-[guestaddr]:guestport",
25
- * Hubs can be used to provide independent network segments, also confusingly
36
+ .params = "[hub_id name]|[netdev_id] [tcp|udp]:[hostaddr]:hostport-[guestaddr]:guestport",
26
- * named the QEMU 'vlan' feature.
37
.help = "redirect TCP or UDP connections from host to guest (requires -net user)",
27
+ * Hubs can be used to provide independent emulated network segments.
38
.cmd = hmp_hostfwd_add,
28
*/
39
},
29
40
@@ -XXX,XX +XXX,XX @@ ETEXI
30
typedef struct NetHub NetHub;
41
{
31
@@ -XXX,XX +XXX,XX @@ void net_hub_check_clients(void)
42
.name = "hostfwd_remove",
32
}
43
.args_type = "arg1:s,arg2:s?,arg3:s?",
33
}
44
- .params = "[vlan_id name] [tcp|udp]:[hostaddr]:hostport",
34
if (has_host_dev && !has_nic) {
45
+ .params = "[hub_id name]|[netdev_id] [tcp|udp]:[hostaddr]:hostport",
35
- warn_report("vlan %d with no nics", hub->id);
46
.help = "remove host-to-guest TCP or UDP redirection",
36
+ warn_report("hub %d with no nics", hub->id);
47
.cmd = hmp_hostfwd_remove,
37
}
48
},
38
if (has_nic && !has_host_dev) {
39
- warn_report("vlan %d is not connected to host network", hub->id);
40
+ warn_report("hub %d is not connected to host network", hub->id);
41
}
42
}
43
}
49
diff --git a/net/slirp.c b/net/slirp.c
44
diff --git a/net/slirp.c b/net/slirp.c
50
index XXXXXXX..XXXXXXX 100644
45
index XXXXXXX..XXXXXXX 100644
51
--- a/net/slirp.c
46
--- a/net/slirp.c
52
+++ b/net/slirp.c
47
+++ b/net/slirp.c
53
@@ -XXX,XX +XXX,XX @@ error:
48
@@ -XXX,XX +XXX,XX @@ static SlirpState *slirp_lookup(Monitor *mon, const char *hub_id,
54
return -1;
49
if (hub_id) {
55
}
50
nc = net_hub_find_client_by_name(strtol(hub_id, NULL, 0), name);
56
51
if (!nc) {
57
-static SlirpState *slirp_lookup(Monitor *mon, const char *vlan,
52
- monitor_printf(mon, "unrecognized (vlan-id, stackname) pair\n");
58
- const char *stack)
53
+ monitor_printf(mon, "unrecognized (hub-id, stackname) pair\n");
59
+static SlirpState *slirp_lookup(Monitor *mon, const char *hub_id,
54
return NULL;
60
+ const char *name)
55
}
61
{
56
} else {
62
-
57
@@ -XXX,XX +XXX,XX @@ void hmp_info_usernet(Monitor *mon, const QDict *qdict)
63
- if (vlan) {
58
64
+ if (name) {
59
QTAILQ_FOREACH(s, &slirp_stacks, entry) {
65
NetClientState *nc;
60
int id;
66
- nc = net_hub_find_client_by_name(strtol(vlan, NULL, 0), stack);
61
- bool got_vlan_id = net_hub_id_for_client(&s->nc, &id) == 0;
67
- if (!nc) {
62
- monitor_printf(mon, "VLAN %d (%s):\n",
68
- monitor_printf(mon, "unrecognized (vlan-id, stackname) pair\n");
63
- got_vlan_id ? id : -1,
69
- return NULL;
64
+ bool got_hub_id = net_hub_id_for_client(&s->nc, &id) == 0;
70
+ if (hub_id) {
65
+ monitor_printf(mon, "Hub %d (%s):\n",
71
+ nc = net_hub_find_client_by_name(strtol(hub_id, NULL, 0), name);
66
+ got_hub_id ? id : -1,
72
+ if (!nc) {
67
s->nc.name);
73
+ monitor_printf(mon, "unrecognized (vlan-id, stackname) pair\n");
68
slirp_connection_info(s->slirp, mon);
74
+ return NULL;
69
}
75
+ }
70
diff --git a/net/tap.c b/net/tap.c
76
+ } else {
71
index XXXXXXX..XXXXXXX 100644
77
+ nc = qemu_find_netdev(name);
72
--- a/net/tap.c
78
+ if (!nc) {
73
+++ b/net/tap.c
79
+ monitor_printf(mon, "unrecognized netdev id '%s'\n", name);
74
@@ -XXX,XX +XXX,XX @@ int net_init_tap(const Netdev *netdev, const char *name,
80
+ return NULL;
75
queues = tap->has_queues ? tap->queues : 1;
81
+ }
76
vhostfdname = tap->has_vhostfd ? tap->vhostfd : NULL;
82
}
77
83
if (strcmp(nc->model, "user")) {
78
- /* QEMU vlans does not support multiqueue tap, in this case peer is set.
84
monitor_printf(mon, "invalid device specified\n");
79
+ /* QEMU hubs do not support multiqueue tap, in this case peer is set.
85
@@ -XXX,XX +XXX,XX @@ void hmp_hostfwd_remove(Monitor *mon, const QDict *qdict)
80
* For -netdev, peer is always NULL. */
86
const char *arg2 = qdict_get_try_str(qdict, "arg2");
81
if (peer && (tap->has_queues || tap->has_fds || tap->has_vhostfds)) {
87
const char *arg3 = qdict_get_try_str(qdict, "arg3");
82
- error_setg(errp, "Multiqueue tap cannot be used with QEMU vlans");
88
83
+ error_setg(errp, "Multiqueue tap cannot be used with hubs");
89
- if (arg2) {
84
return -1;
90
+ if (arg3) {
85
}
91
s = slirp_lookup(mon, arg1, arg2);
86
92
src_str = arg3;
93
+ } else if (arg2) {
94
+ s = slirp_lookup(mon, NULL, arg1);
95
+ src_str = arg2;
96
} else {
97
s = slirp_lookup(mon, NULL, NULL);
98
src_str = arg1;
99
@@ -XXX,XX +XXX,XX @@ void hmp_hostfwd_add(Monitor *mon, const QDict *qdict)
100
const char *arg2 = qdict_get_try_str(qdict, "arg2");
101
const char *arg3 = qdict_get_try_str(qdict, "arg3");
102
103
- if (arg2) {
104
+ if (arg3) {
105
s = slirp_lookup(mon, arg1, arg2);
106
redir_str = arg3;
107
+ } else if (arg2) {
108
+ s = slirp_lookup(mon, NULL, arg1);
109
+ redir_str = arg2;
110
} else {
111
s = slirp_lookup(mon, NULL, NULL);
112
redir_str = arg1;
113
--
87
--
114
2.7.4
88
2.7.4
115
89
116
90
diff view generated by jsdifflib
1
From: Thomas Huth <thuth@redhat.com>
1
From: Thomas Huth <thuth@redhat.com>
2
2
3
The vlan concept is marked as deprecated, so we should not use
3
'vlan' is very confusing since it does not mean something like IEEE
4
this for examples in the documentation anymore.
4
802.1Q, but rather emulated hubs, so let's switch to that terminology
5
instead. While we're at it, move the subsection about hub a little bit
6
downward in the documentation (it's not as important anymore as it was
7
before the invention of the -netdev parameter), and extend it a little
8
bit.
5
9
10
Buglink: https://bugs.launchpad.net/qemu/+bug/658904
11
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
6
Signed-off-by: Thomas Huth <thuth@redhat.com>
12
Signed-off-by: Thomas Huth <thuth@redhat.com>
7
Signed-off-by: Jason Wang <jasowang@redhat.com>
13
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
---
14
---
9
qemu-options.hx | 4 ++--
15
qemu-doc.texi | 42 +++++++++++++++++++++++-------------------
10
1 file changed, 2 insertions(+), 2 deletions(-)
16
1 file changed, 23 insertions(+), 19 deletions(-)
11
17
12
diff --git a/qemu-options.hx b/qemu-options.hx
18
diff --git a/qemu-doc.texi b/qemu-doc.texi
13
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
14
--- a/qemu-options.hx
20
--- a/qemu-doc.texi
15
+++ b/qemu-options.hx
21
+++ b/qemu-doc.texi
16
@@ -XXX,XX +XXX,XX @@ qemu-system-i386 linux.img -net nic -net tap
22
@@ -XXX,XX +XXX,XX @@ state is not saved or restored properly (in particular USB).
17
#launch a QEMU instance with two NICs, each one connected
23
@node pcsys_network
18
#to a TAP device
24
@section Network emulation
19
qemu-system-i386 linux.img \
25
20
- -net nic,vlan=0 -net tap,vlan=0,ifname=tap0 \
26
-QEMU can simulate several network cards (PCI or ISA cards on the PC
21
- -net nic,vlan=1 -net tap,vlan=1,ifname=tap1
27
-target) and can connect them to an arbitrary number of Virtual Local
22
+ -netdev tap,id=nd0,ifname=tap0 -device e1000,netdev=nd0 \
28
-Area Networks (VLANs). Host TAP devices can be connected to any QEMU
23
+ -netdev tap,id=nd1,ifname=tap1 -device rtl8139,netdev=nd1
29
-VLAN. VLAN can be connected between separate instances of QEMU to
24
@end example
30
-simulate large networks. For simpler usage, a non privileged user mode
31
-network stack can replace the TAP device to have a basic network
32
-connection.
33
-
34
-@subsection VLANs
35
-
36
-QEMU simulates several VLANs. A VLAN can be symbolised as a virtual
37
-connection between several network devices. These devices can be for
38
-example QEMU virtual Ethernet cards or virtual Host ethernet devices
39
-(TAP devices).
40
+QEMU can simulate several network cards (e.g. PCI or ISA cards on the PC
41
+target) and can connect them to a network backend on the host or an emulated
42
+hub. The various host network backends can either be used to connect the NIC of
43
+the guest to a real network (e.g. by using a TAP devices or the non-privileged
44
+user mode network stack), or to other guest instances running in another QEMU
45
+process (e.g. by using the socket host network backend).
46
47
@subsection Using TAP network interfaces
48
49
@@ -XXX,XX +XXX,XX @@ network). The virtual network configuration is the following:
25
50
26
@example
51
@example
52
53
- QEMU VLAN <------> Firewall/DHCP server <-----> Internet
54
+ guest (10.0.2.15) <------> Firewall/DHCP server <-----> Internet
55
| (10.0.2.2)
56
|
57
----> DNS server (10.0.2.3)
58
@@ -XXX,XX +XXX,XX @@ When using the @option{'-netdev user,hostfwd=...'} option, TCP or UDP
59
connections can be redirected from the host to the guest. It allows for
60
example to redirect X11, telnet or SSH connections.
61
62
-@subsection Connecting VLANs between QEMU instances
63
+@subsection Hubs
64
+
65
+QEMU can simulate several hubs. A hub can be thought of as a virtual connection
66
+between several network devices. These devices can be for example QEMU virtual
67
+ethernet cards or virtual Host ethernet devices (TAP devices). You can connect
68
+guest NICs or host network backends to such a hub using the @option{-netdev
69
+hubport} or @option{-nic hubport} options. The legacy @option{-net} option
70
+also connects the given device to the emulated hub with ID 0 (i.e. the default
71
+hub) unless you specify a netdev with @option{-net nic,netdev=xxx} here.
72
+
73
+@subsection Connecting emulated networks between QEMU instances
74
75
-Using the @option{-net socket} option, it is possible to make VLANs
76
-that span several QEMU instances. See @ref{sec_invocation} to have a
77
-basic example.
78
+Using the @option{-netdev socket} (or @option{-nic socket} or
79
+@option{-net socket}) option, it is possible to create emulated
80
+networks that span several QEMU instances.
81
+See the description of the @option{-netdev socket} option in the
82
+@ref{sec_invocation,,Invocation chapter} to have a basic example.
83
84
@node pcsys_other_devs
85
@section Other Devices
27
--
86
--
28
2.7.4
87
2.7.4
29
88
30
89
diff view generated by jsdifflib