1
The following changes since commit e607bbee553cfe73072870cef458cfa4e78133e2:
1
The following changes since commit 136c67e07869227b21b3f627316e03679ce7b738:
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/bkoppelmann/tags/pull-tricore-2018-03-02' into staging (2018-03-02 16:56:20 +0000)
4
4
5
are available in the git repository at:
5
are available in the git repository at:
6
6
7
https://github.com/jasowang/qemu.git tags/net-pull-request
7
https://github.com/jasowang/qemu.git tags/net-pull-request
8
8
9
for you to fetch changes up to bf4835a4d5338bb7424827715df22570a8adc67c:
9
for you to fetch changes up to 46d4d36d0bf2b24b205f2f604f0905db80264eef:
10
10
11
MAINTAINERS: update Dmitry Fleytman email (2018-01-29 16:05:38 +0800)
11
tap: setting error appropriately when calling net_init_tap_one() (2018-03-05 10:30:16 +0800)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
14
15
----------------------------------------------------------------
15
----------------------------------------------------------------
16
Mao Zhongyi (2):
16
Jay Zhou (1):
17
colo: modified the payload compare function
17
tap: setting error appropriately when calling net_init_tap_one()
18
colo: compare the packet based on the tcp sequence number
19
18
20
Philippe Mathieu-Daudé (1):
19
Thomas Huth (8):
21
MAINTAINERS: update Dmitry Fleytman email
20
net: Move error reporting from net_init_client/netdev to the calling site
21
net: List available netdevs with "-netdev help"
22
net: Only show vhost-user in the help text if CONFIG_POSIX is defined
23
net: Make net_client_init() static
24
net: Remove the deprecated way of dumping network packets
25
net: Remove the deprecated 'host_net_add' and 'host_net_remove' HMP commands
26
net: Add a new convenience option "--nic" to configure default/on-board NICs
27
hw/net: Remove unnecessary header includes
22
28
23
Thomas Huth (3):
29
hmp-commands.hx | 30 ------
24
net: Allow hubports to connect to other netdevs
30
hmp.h | 3 -
25
net: Allow netdevs to be used with 'hostfwd_add' and 'hostfwd_remove'
31
hw/net/e1000.c | 1 -
26
qemu-doc: Get rid of "vlan=X" example in the documentation
32
hw/net/lance.c | 3 -
27
33
hw/net/ne2000.c | 2 -
28
MAINTAINERS | 8 +-
34
hw/net/pcnet-pci.c | 1 -
29
hmp-commands.hx | 4 +-
35
hw/net/pcnet.c | 1 -
30
net/colo-compare.c | 411 +++++++++++++++++++++++++++++++++--------------------
36
hw/net/rtl8139.c | 2 -
31
net/colo.c | 9 ++
37
hw/net/xgmac.c | 1 -
32
net/colo.h | 15 ++
38
include/net/net.h | 4 +-
33
net/hub.c | 27 +++-
39
include/net/vhost_net.h | 3 +
34
net/hub.h | 3 +-
40
include/sysemu/sysemu.h | 1 +
35
net/net.c | 2 +-
41
monitor.c | 61 ------------
36
net/slirp.c | 33 +++--
42
net/dump.c | 102 +--------------------
37
net/trace-events | 2 +-
43
net/net.c | 239 +++++++++++++++++++++++-------------------------
38
qapi/net.json | 4 +-
44
net/tap.c | 22 ++++-
39
qemu-options.hx | 12 +-
45
qapi/net.json | 29 ++----
40
12 files changed, 347 insertions(+), 183 deletions(-)
46
qemu-doc.texi | 16 ----
47
qemu-options.hx | 48 +++++++---
48
tests/test-hmp.c | 2 -
49
vl.c | 10 +-
50
21 files changed, 190 insertions(+), 391 deletions(-)
41
51
42
52
diff view generated by jsdifflib
1
From: Mao Zhongyi <maozy.fnst@cn.fujitsu.com>
1
From: Thomas Huth <thuth@redhat.com>
2
2
3
Modified the function colo_packet_compare_common to prepare for the
3
It looks strange that net_init_client() and net_init_netdev() both
4
tcp packet comparison in the next patch.
4
take an "Error **errp" parameter, but then do the error reporting
5
with "error_report_err(local_err)" on their own. Let's move the
6
error reporting to the calling site instead to simplify this code
7
a little bit.
5
8
6
Cc: Zhang Chen <zhangckid@gmail.com>
9
Reviewed-by: Eric Blake <eblake@redhat.com>
7
Cc: Li Zhijian <lizhijian@cn.fujitsu.com>
10
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
8
Cc: Jason Wang <jasowang@redhat.com>
11
Signed-off-by: Thomas Huth <thuth@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>
12
Signed-off-by: Jason Wang <jasowang@redhat.com>
15
---
13
---
16
net/colo-compare.c | 88 +++++++++++++++++++++++++++---------------------------
14
include/net/net.h | 2 +-
17
1 file changed, 44 insertions(+), 44 deletions(-)
15
net/net.c | 29 +++++------------------------
16
vl.c | 3 ++-
17
3 files changed, 8 insertions(+), 26 deletions(-)
18
18
19
diff --git a/net/colo-compare.c b/net/colo-compare.c
19
diff --git a/include/net/net.h b/include/net/net.h
20
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
21
--- a/net/colo-compare.c
21
--- a/include/net/net.h
22
+++ b/net/colo-compare.c
22
+++ b/include/net/net.h
23
@@ -XXX,XX +XXX,XX @@ static int packet_enqueue(CompareState *s, int mode, Connection **con)
23
@@ -XXX,XX +XXX,XX @@ extern const char *legacy_bootp_filename;
24
* return: 0 means packet same
24
25
* > 0 || < 0 means packet different
25
int net_client_init(QemuOpts *opts, bool is_netdev, Error **errp);
26
*/
26
int net_client_parse(QemuOptsList *opts_list, const char *str);
27
-static int colo_packet_compare_common(Packet *ppkt,
27
-int net_init_clients(void);
28
- Packet *spkt,
28
+int net_init_clients(Error **errp);
29
- int poffset,
29
void net_check_clients(void);
30
- int soffset)
30
void net_cleanup(void);
31
+static int colo_compare_packet_payload(Packet *ppkt,
31
void hmp_host_net_add(Monitor *mon, const QDict *qdict);
32
+ Packet *spkt,
32
diff --git a/net/net.c b/net/net.c
33
+ uint16_t poffset,
33
index XXXXXXX..XXXXXXX 100644
34
+ uint16_t soffset,
34
--- a/net/net.c
35
+ uint16_t len)
35
+++ b/net/net.c
36
+
36
@@ -XXX,XX +XXX,XX @@ void net_check_clients(void)
37
38
static int net_init_client(void *dummy, QemuOpts *opts, Error **errp)
37
{
39
{
38
if (trace_event_get_state_backends(TRACE_COLO_COMPARE_MISCOMPARE)) {
40
- Error *local_err = NULL;
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
-
41
-
47
- if (ppkt->size - poffset == spkt->size - soffset) {
42
- net_client_init(opts, false, &local_err);
48
- return memcmp(ppkt->data + poffset,
43
- if (local_err) {
49
- spkt->data + soffset,
44
- error_report_err(local_err);
50
- spkt->size - soffset);
51
- } else {
52
- trace_colo_compare_main("Net packet size are not the same");
53
- return -1;
45
- return -1;
54
- }
46
- }
55
+ return memcmp(ppkt->data + poffset, spkt->data + soffset, len);
47
-
48
- return 0;
49
+ return net_client_init(opts, false, errp);
56
}
50
}
57
51
58
/*
52
static int net_init_netdev(void *dummy, QemuOpts *opts, Error **errp)
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
{
53
{
54
- Error *local_err = NULL;
98
- int ret;
55
- 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
-
56
-
113
- if (ret) {
57
- ret = net_client_init(opts, true, &local_err);
114
+ if (ppkt->size != spkt->size) {
58
- if (local_err) {
115
+ trace_colo_compare_main("UDP: payload size of packets are different");
59
- error_report_err(local_err);
116
+ return -1;
60
- return -1;
117
+ }
61
- }
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
-
62
-
132
- return ret;
63
- return ret;
64
+ return net_client_init(opts, true, errp);
133
}
65
}
134
66
135
/*
67
-int net_init_clients(void)
136
@@ -XXX,XX +XXX,XX @@ static int colo_packet_compare_udp(Packet *spkt, Packet *ppkt)
68
+int net_init_clients(Error **errp)
137
*/
138
static int colo_packet_compare_icmp(Packet *spkt, Packet *ppkt)
139
{
69
{
140
- int network_header_length = ppkt->ip->ip_hl * 4;
70
- QemuOptsList *net = qemu_find_opts("net");
141
+ uint16_t network_header_length = ppkt->ip->ip_hl << 2;
71
-
142
+ uint16_t offset = network_header_length + ETH_HLEN + ppkt->vnet_hdr_len;
72
net_change_state_entry =
143
73
qemu_add_vm_change_state_handler(net_vm_change_state_handler, NULL);
144
trace_colo_compare_main("compare icmp");
74
145
75
QTAILQ_INIT(&net_clients);
146
@@ -XXX,XX +XXX,XX @@ static int colo_packet_compare_icmp(Packet *spkt, Packet *ppkt)
76
147
* other field like TOS,TTL,IP Checksum. we only need to compare
77
if (qemu_opts_foreach(qemu_find_opts("netdev"),
148
* the ip payload here.
78
- net_init_netdev, NULL, NULL)) {
149
*/
79
+ net_init_netdev, NULL, errp)) {
150
- if (colo_packet_compare_common(ppkt, spkt,
80
return -1;
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
}
81
}
174
82
175
- return colo_packet_compare_common(ppkt, spkt, 0, 0);
83
- if (qemu_opts_foreach(net, net_init_client, NULL, NULL)) {
176
+ if (ppkt->size != spkt->size) {
84
+ if (qemu_opts_foreach(qemu_find_opts("net"), net_init_client, NULL, errp)) {
177
+ trace_colo_compare_main("Other: payload size of packets are different");
85
return -1;
178
+ return -1;
86
}
179
+ }
87
180
+ return colo_compare_packet_payload(ppkt, spkt, offset, offset,
88
diff --git a/vl.c b/vl.c
181
+ ppkt->size - offset);
89
index XXXXXXX..XXXXXXX 100644
182
}
90
--- a/vl.c
183
91
+++ b/vl.c
184
static int colo_old_packet_check_one(Packet *pkt, int64_t *check_time)
92
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv, char **envp)
93
94
colo_info_init();
95
96
- if (net_init_clients() < 0) {
97
+ if (net_init_clients(&err) < 0) {
98
+ error_report_err(err);
99
exit(1);
100
}
101
185
--
102
--
186
2.7.4
103
2.7.4
187
104
188
105
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
Other options like "-chardev" or "-device" feature a nice help text
4
with the available devices when being called with "help" or "?".
5
Since it is quite useful, especially if you want to see which network
6
backends have been compiled into the QEMU binary, let's provide such
7
a help text for "-netdev", too.
4
8
5
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
10
Reviewed-by: Eric Blake <eblake@redhat.com>
11
Signed-off-by: Thomas Huth <thuth@redhat.com>
6
Signed-off-by: Jason Wang <jasowang@redhat.com>
12
Signed-off-by: Jason Wang <jasowang@redhat.com>
7
---
13
---
8
MAINTAINERS | 8 ++++----
14
net/net.c | 37 ++++++++++++++++++++++++++++++++++++-
9
1 file changed, 4 insertions(+), 4 deletions(-)
15
1 file changed, 36 insertions(+), 1 deletion(-)
10
16
11
diff --git a/MAINTAINERS b/MAINTAINERS
17
diff --git a/net/net.c b/net/net.c
12
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
13
--- a/MAINTAINERS
19
--- a/net/net.c
14
+++ b/MAINTAINERS
20
+++ b/net/net.c
15
@@ -XXX,XX +XXX,XX @@ F: hw/scsi/mfi.h
21
@@ -XXX,XX +XXX,XX @@ static int net_client_init1(const void *object, bool is_netdev, Error **errp)
16
F: tests/megasas-test.c
22
return 0;
17
23
}
18
Network packet abstractions
24
19
-M: Dmitry Fleytman <dmitry@daynix.com>
25
+static void show_netdevs(void)
20
+M: Dmitry Fleytman <dmitry.fleytman@gmail.com>
26
+{
21
S: Maintained
27
+ int idx;
22
F: include/net/eth.h
28
+ const char *available_netdevs[] = {
23
F: net/eth.c
29
+ "socket",
24
@@ -XXX,XX +XXX,XX @@ F: hw/net/net_rx_pkt*
30
+ "hubport",
25
F: hw/net/net_tx_pkt*
31
+ "tap",
26
32
+#ifdef CONFIG_SLIRP
27
Vmware
33
+ "user",
28
-M: Dmitry Fleytman <dmitry@daynix.com>
34
+#endif
29
+M: Dmitry Fleytman <dmitry.fleytman@gmail.com>
35
+#ifdef CONFIG_L2TPV3
30
S: Maintained
36
+ "l2tpv3",
31
F: hw/net/vmxnet*
37
+#endif
32
F: hw/scsi/vmw_pvscsi*
38
+#ifdef CONFIG_VDE
33
@@ -XXX,XX +XXX,XX @@ F: hw/mem/nvdimm.c
39
+ "vde",
34
F: include/hw/mem/nvdimm.h
40
+#endif
35
41
+#ifdef CONFIG_NET_BRIDGE
36
e1000x
42
+ "bridge",
37
-M: Dmitry Fleytman <dmitry@daynix.com>
43
+#endif
38
+M: Dmitry Fleytman <dmitry.fleytman@gmail.com>
44
+#ifdef CONFIG_NETMAP
39
S: Maintained
45
+ "netmap",
40
F: hw/net/e1000x*
46
+#endif
41
47
+#ifdef CONFIG_POSIX
42
e1000e
48
+ "vhost-user",
43
-M: Dmitry Fleytman <dmitry@daynix.com>
49
+#endif
44
+M: Dmitry Fleytman <dmitry.fleytman@gmail.com>
50
+ };
45
S: Maintained
51
+
46
F: hw/net/e1000e*
52
+ printf("Available netdev backend types:\n");
53
+ for (idx = 0; idx < ARRAY_SIZE(available_netdevs); idx++) {
54
+ puts(available_netdevs[idx]);
55
+ }
56
+}
57
58
int net_client_init(QemuOpts *opts, bool is_netdev, Error **errp)
59
{
60
@@ -XXX,XX +XXX,XX @@ int net_client_init(QemuOpts *opts, bool is_netdev, Error **errp)
61
int ret = -1;
62
Visitor *v = opts_visitor_new(opts);
63
64
- {
65
+ if (is_netdev && is_help_option(qemu_opt_get(opts, "type"))) {
66
+ show_netdevs();
67
+ exit(0);
68
+ } else {
69
/* Parse convenience option format ip6-net=fec0::0[/64] */
70
const char *ip6_net = qemu_opt_get(opts, "ipv6-net");
47
71
48
--
72
--
49
2.7.4
73
2.7.4
50
74
51
75
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
According to net/Makefile.objs we only link in the vhost-user code
4
this for examples in the documentation anymore.
4
if CONFIG_POSIX has been set. So the help screen should also only
5
show this information if CONFIG_POSIX has been defined.
5
6
7
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
6
Signed-off-by: Thomas Huth <thuth@redhat.com>
8
Signed-off-by: Thomas Huth <thuth@redhat.com>
7
Signed-off-by: Jason Wang <jasowang@redhat.com>
9
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
---
10
---
9
qemu-options.hx | 4 ++--
11
qemu-options.hx | 2 ++
10
1 file changed, 2 insertions(+), 2 deletions(-)
12
1 file changed, 2 insertions(+)
11
13
12
diff --git a/qemu-options.hx b/qemu-options.hx
14
diff --git a/qemu-options.hx b/qemu-options.hx
13
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
14
--- a/qemu-options.hx
16
--- a/qemu-options.hx
15
+++ b/qemu-options.hx
17
+++ b/qemu-options.hx
16
@@ -XXX,XX +XXX,XX @@ qemu-system-i386 linux.img -net nic -net tap
18
@@ -XXX,XX +XXX,XX @@ DEF("netdev", HAS_ARG, QEMU_OPTION_netdev,
17
#launch a QEMU instance with two NICs, each one connected
19
" VALE port (created on the fly) called 'name' ('nmname' is name of the \n"
18
#to a TAP device
20
" netmap device, defaults to '/dev/netmap')\n"
19
qemu-system-i386 linux.img \
21
#endif
20
- -net nic,vlan=0 -net tap,vlan=0,ifname=tap0 \
22
+#ifdef CONFIG_POSIX
21
- -net nic,vlan=1 -net tap,vlan=1,ifname=tap1
23
"-netdev vhost-user,id=str,chardev=dev[,vhostforce=on|off]\n"
22
+ -netdev tap,id=nd0,ifname=tap0 -device e1000,netdev=nd0 \
24
" configure a vhost-user network, backed by a chardev 'dev'\n"
23
+ -netdev tap,id=nd1,ifname=tap1 -device rtl8139,netdev=nd1
25
+#endif
24
@end example
26
"-netdev hubport,id=str,hubid=n[,netdev=nd]\n"
25
27
" configure a hub port on QEMU VLAN 'n'\n", QEMU_ARCH_ALL)
26
@example
28
DEF("net", HAS_ARG, QEMU_OPTION_net,
27
--
29
--
28
2.7.4
30
2.7.4
29
31
30
32
diff view generated by jsdifflib
New patch
1
From: Thomas Huth <thuth@redhat.com>
1
2
3
The function is only used within net.c, so there's no need that
4
this is a global function.
5
6
While we're at it, also remove the unused prototype compute_mcast_idx()
7
(the function has been removed in commit d9caeb09b107e91122d10ba4a08a).
8
9
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
10
Signed-off-by: Thomas Huth <thuth@redhat.com>
11
Signed-off-by: Jason Wang <jasowang@redhat.com>
12
---
13
include/net/net.h | 2 --
14
net/net.c | 2 +-
15
2 files changed, 1 insertion(+), 3 deletions(-)
16
17
diff --git a/include/net/net.h b/include/net/net.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/include/net/net.h
20
+++ b/include/net/net.h
21
@@ -XXX,XX +XXX,XX @@ extern const char *host_net_devices[];
22
extern const char *legacy_tftp_prefix;
23
extern const char *legacy_bootp_filename;
24
25
-int net_client_init(QemuOpts *opts, bool is_netdev, Error **errp);
26
int net_client_parse(QemuOptsList *opts_list, const char *str);
27
int net_init_clients(Error **errp);
28
void net_check_clients(void);
29
@@ -XXX,XX +XXX,XX @@ void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd);
30
#define POLYNOMIAL_LE 0xedb88320
31
uint32_t net_crc32(const uint8_t *p, int len);
32
uint32_t net_crc32_le(const uint8_t *p, int len);
33
-unsigned compute_mcast_idx(const uint8_t *ep);
34
35
#define vmstate_offset_macaddr(_state, _field) \
36
vmstate_offset_array(_state, _field.a, uint8_t, \
37
diff --git a/net/net.c b/net/net.c
38
index XXXXXXX..XXXXXXX 100644
39
--- a/net/net.c
40
+++ b/net/net.c
41
@@ -XXX,XX +XXX,XX @@ static void show_netdevs(void)
42
}
43
}
44
45
-int net_client_init(QemuOpts *opts, bool is_netdev, Error **errp)
46
+static int net_client_init(QemuOpts *opts, bool is_netdev, Error **errp)
47
{
48
void *object = NULL;
49
Error *err = NULL;
50
--
51
2.7.4
52
53
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
"-net dump" has been marked as deprecated since QEMU v2.10, since it
4
primarily used for the mis-named 'vlan' feature of the networking
4
only works with the deprecated 'vlan' parameter (or hubs). Network
5
subsystem. Now the 'vlan' feature has been marked as deprecated, since
5
dumping should be done with "-object filter-dump" nowadays instead.
6
its name is rather confusing and the users often rather mis-configure
6
Since nobody complained so far about the deprecation message, let's
7
their network when trying to use it. But while the 'vlan' parameter
7
finally get rid of "-net dump" now.
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
10
multiple NICs into one single l2tp netdev for example.
11
12
Now to be able to use the hubport feature without 'vlan's, there is one
13
missing piece: The possibility to connect a hubport to a netdev, too.
14
This patch adds this possibility by introducing a new "netdev=..."
15
parameter to the hubports.
16
17
To bundle up the output of multiple NICs into one socket netdev, you can
18
now run QEMU with these parameters for example:
19
20
qemu-system-ppc64 ... -netdev socket,id=s1,connect=:11122 \
21
-netdev hubport,hubid=1,id=h1,netdev=s1 \
22
-netdev hubport,hubid=1,id=h2 -device e1000,netdev=h2 \
23
-netdev hubport,hubid=1,id=h3 -device virtio-net-pci,netdev=h3
24
25
For using the socket netdev, you have got to start another QEMU as the
26
receiving side first, for example with network dumping enabled:
27
28
qemu-system-x86_64 -M isapc -netdev socket,id=s0,listen=:11122 \
29
-device ne2k_isa,netdev=s0 \
30
-object filter-dump,id=f1,netdev=s0,file=/tmp/dump.dat
31
32
After the ppc64 guest tried to boot from both NICs, you can see in the
33
dump file (using Wireshark, for example), that the output of both NICs
34
(the e1000 and the virtio-net-pci) has been successfully transfered
35
via the socket netdev in this case.
36
37
Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
38
Signed-off-by: Thomas Huth <thuth@redhat.com>
9
Signed-off-by: Thomas Huth <thuth@redhat.com>
39
Signed-off-by: Jason Wang <jasowang@redhat.com>
10
Signed-off-by: Jason Wang <jasowang@redhat.com>
40
---
11
---
41
net/hub.c | 27 +++++++++++++++++++++------
12
net/dump.c | 102 ++------------------------------------------------------
42
net/hub.h | 3 ++-
13
net/net.c | 9 +----
43
net/net.c | 2 +-
14
qapi/net.json | 29 ++++------------
44
qapi/net.json | 4 +++-
15
qemu-doc.texi | 6 ----
45
qemu-options.hx | 8 +++++---
16
qemu-options.hx | 8 -----
46
5 files changed, 32 insertions(+), 12 deletions(-)
17
5 files changed, 9 insertions(+), 145 deletions(-)
47
18
48
diff --git a/net/hub.c b/net/hub.c
19
diff --git a/net/dump.c b/net/dump.c
49
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
50
--- a/net/hub.c
21
--- a/net/dump.c
51
+++ b/net/hub.c
22
+++ b/net/dump.c
52
@@ -XXX,XX +XXX,XX @@
23
@@ -XXX,XX +XXX,XX @@ static int net_dump_state_init(DumpState *s, const char *filename,
53
*/
24
54
25
fd = open(filename, O_CREAT | O_TRUNC | O_WRONLY | O_BINARY, 0644);
55
#include "qemu/osdep.h"
26
if (fd < 0) {
56
+#include "qapi/error.h"
27
- error_setg_errno(errp, errno, "-net dump: can't open %s", filename);
57
#include "monitor/monitor.h"
28
+ error_setg_errno(errp, errno, "net dump: can't open %s", filename);
58
#include "net/net.h"
29
return -1;
59
#include "clients.h"
60
@@ -XXX,XX +XXX,XX @@ static NetClientInfo net_hub_port_info = {
61
.cleanup = net_hub_port_cleanup,
62
};
63
64
-static NetHubPort *net_hub_port_new(NetHub *hub, const char *name)
65
+static NetHubPort *net_hub_port_new(NetHub *hub, const char *name,
66
+ NetClientState *hubpeer)
67
{
68
NetClientState *nc;
69
NetHubPort *port;
70
@@ -XXX,XX +XXX,XX @@ static NetHubPort *net_hub_port_new(NetHub *hub, const char *name)
71
name = default_name;
72
}
30
}
73
31
74
- nc = qemu_new_net_client(&net_hub_port_info, NULL, "hub", name);
32
@@ -XXX,XX +XXX,XX @@ static int net_dump_state_init(DumpState *s, const char *filename,
75
+ nc = qemu_new_net_client(&net_hub_port_info, hubpeer, "hub", name);
33
hdr.linktype = 1;
76
port = DO_UPCAST(NetHubPort, nc, nc);
34
77
port->id = id;
35
if (write(fd, &hdr, sizeof(hdr)) < sizeof(hdr)) {
78
port->hub = hub;
36
- error_setg_errno(errp, errno, "-net dump write error");
79
@@ -XXX,XX +XXX,XX @@ static NetHubPort *net_hub_port_new(NetHub *hub, const char *name)
37
+ error_setg_errno(errp, errno, "net dump write error");
80
38
close(fd);
81
/**
39
return -1;
82
* Create a port on a given hub
83
+ * @hub_id: Number of the hub
84
* @name: Net client name or NULL for default name.
85
+ * @hubpeer: Peer to use (if "netdev=id" has been specified)
86
*
87
* If there is no existing hub with the given id then a new hub is created.
88
*/
89
-NetClientState *net_hub_add_port(int hub_id, const char *name)
90
+NetClientState *net_hub_add_port(int hub_id, const char *name,
91
+ NetClientState *hubpeer)
92
{
93
NetHub *hub;
94
NetHubPort *port;
95
@@ -XXX,XX +XXX,XX @@ NetClientState *net_hub_add_port(int hub_id, const char *name)
96
hub = net_hub_new(hub_id);
97
}
40
}
98
41
@@ -XXX,XX +XXX,XX @@ static int net_dump_state_init(DumpState *s, const char *filename,
99
- port = net_hub_port_new(hub, name);
100
+ port = net_hub_port_new(hub, name, hubpeer);
101
return &port->nc;
102
}
103
104
@@ -XXX,XX +XXX,XX @@ NetClientState *net_hub_port_find(int hub_id)
105
}
106
}
107
108
- nc = net_hub_add_port(hub_id, NULL);
109
+ nc = net_hub_add_port(hub_id, NULL, NULL);
110
return nc;
111
}
112
113
@@ -XXX,XX +XXX,XX @@ int net_init_hubport(const Netdev *netdev, const char *name,
114
NetClientState *peer, Error **errp)
115
{
116
const NetdevHubPortOptions *hubport;
117
+ NetClientState *hubpeer = NULL;
118
119
assert(netdev->type == NET_CLIENT_DRIVER_HUBPORT);
120
assert(!peer);
121
hubport = &netdev->u.hubport;
122
123
- net_hub_add_port(hubport->hubid, name);
124
+ if (hubport->has_netdev) {
125
+ hubpeer = qemu_find_netdev(hubport->netdev);
126
+ if (!hubpeer) {
127
+ error_setg(errp, "netdev '%s' not found", hubport->netdev);
128
+ return -1;
129
+ }
130
+ }
131
+
132
+ net_hub_add_port(hubport->hubid, name, hubpeer);
133
+
134
return 0;
42
return 0;
135
}
43
}
136
44
137
diff --git a/net/hub.h b/net/hub.h
45
-/* Dumping via VLAN netclient */
138
index XXXXXXX..XXXXXXX 100644
46
-
139
--- a/net/hub.h
47
-struct DumpNetClient {
140
+++ b/net/hub.h
48
- NetClientState nc;
141
@@ -XXX,XX +XXX,XX @@
49
- DumpState ds;
142
50
-};
143
#include "qemu-common.h"
51
-typedef struct DumpNetClient DumpNetClient;
144
52
-
145
-NetClientState *net_hub_add_port(int hub_id, const char *name);
53
-static ssize_t dumpclient_receive(NetClientState *nc, const uint8_t *buf,
146
+NetClientState *net_hub_add_port(int hub_id, const char *name,
54
- size_t size)
147
+ NetClientState *hubpeer);
55
-{
148
NetClientState *net_hub_find_client_by_name(int hub_id, const char *name);
56
- DumpNetClient *dc = DO_UPCAST(DumpNetClient, nc, nc);
149
void net_hub_info(Monitor *mon);
57
- struct iovec iov = {
150
void net_hub_check_clients(void);
58
- .iov_base = (void *)buf,
59
- .iov_len = size
60
- };
61
-
62
- return dump_receive_iov(&dc->ds, &iov, 1);
63
-}
64
-
65
-static ssize_t dumpclient_receive_iov(NetClientState *nc,
66
- const struct iovec *iov, int cnt)
67
-{
68
- DumpNetClient *dc = DO_UPCAST(DumpNetClient, nc, nc);
69
-
70
- return dump_receive_iov(&dc->ds, iov, cnt);
71
-}
72
-
73
-static void dumpclient_cleanup(NetClientState *nc)
74
-{
75
- DumpNetClient *dc = DO_UPCAST(DumpNetClient, nc, nc);
76
-
77
- dump_cleanup(&dc->ds);
78
-}
79
-
80
-static NetClientInfo net_dump_info = {
81
- .type = NET_CLIENT_DRIVER_DUMP,
82
- .size = sizeof(DumpNetClient),
83
- .receive = dumpclient_receive,
84
- .receive_iov = dumpclient_receive_iov,
85
- .cleanup = dumpclient_cleanup,
86
-};
87
-
88
-int net_init_dump(const Netdev *netdev, const char *name,
89
- NetClientState *peer, Error **errp)
90
-{
91
- int len, rc;
92
- const char *file;
93
- char def_file[128];
94
- const NetdevDumpOptions *dump;
95
- NetClientState *nc;
96
- DumpNetClient *dnc;
97
-
98
- assert(netdev->type == NET_CLIENT_DRIVER_DUMP);
99
- dump = &netdev->u.dump;
100
-
101
- assert(peer);
102
-
103
- error_report("'-net dump' is deprecated. "
104
- "Please use '-object filter-dump' instead.");
105
-
106
- if (dump->has_file) {
107
- file = dump->file;
108
- } else {
109
- int id;
110
- int ret;
111
-
112
- ret = net_hub_id_for_client(peer, &id);
113
- assert(ret == 0); /* peer must be on a hub */
114
-
115
- snprintf(def_file, sizeof(def_file), "qemu-vlan%d.pcap", id);
116
- file = def_file;
117
- }
118
-
119
- if (dump->has_len) {
120
- if (dump->len > INT_MAX) {
121
- error_setg(errp, "invalid length: %"PRIu64, dump->len);
122
- return -1;
123
- }
124
- len = dump->len;
125
- } else {
126
- len = 65536;
127
- }
128
-
129
- nc = qemu_new_net_client(&net_dump_info, peer, "dump", name);
130
- snprintf(nc->info_str, sizeof(nc->info_str),
131
- "dump to %s (len=%d)", file, len);
132
-
133
- dnc = DO_UPCAST(DumpNetClient, nc, nc);
134
- rc = net_dump_state_init(&dnc->ds, file, len, errp);
135
- if (rc) {
136
- qemu_del_net_client(nc);
137
- }
138
- return rc;
139
-}
140
-
141
-/* Dumping via filter */
142
-
143
#define TYPE_FILTER_DUMP "filter-dump"
144
145
#define FILTER_DUMP(obj) \
151
diff --git a/net/net.c b/net/net.c
146
diff --git a/net/net.c b/net/net.c
152
index XXXXXXX..XXXXXXX 100644
147
index XXXXXXX..XXXXXXX 100644
153
--- a/net/net.c
148
--- a/net/net.c
154
+++ b/net/net.c
149
+++ b/net/net.c
150
@@ -XXX,XX +XXX,XX @@ static QTAILQ_HEAD(, NetClientState) net_clients;
151
const char *host_net_devices[] = {
152
"tap",
153
"socket",
154
- "dump",
155
#ifdef CONFIG_NET_BRIDGE
156
"bridge",
157
#endif
158
@@ -XXX,XX +XXX,XX @@ static int (* const net_client_init_fun[NET_CLIENT_DRIVER__MAX])(
159
#ifdef CONFIG_NETMAP
160
[NET_CLIENT_DRIVER_NETMAP] = net_init_netmap,
161
#endif
162
- [NET_CLIENT_DRIVER_DUMP] = net_init_dump,
163
#ifdef CONFIG_NET_BRIDGE
164
[NET_CLIENT_DRIVER_BRIDGE] = net_init_bridge,
165
#endif
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
netdev = object;
157
if (netdev->type != NET_CLIENT_DRIVER_NIC ||
168
name = netdev->id;
158
!opts->u.nic.has_netdev) {
169
159
- peer = net_hub_add_port(net->has_vlan ? net->vlan : 0, NULL);
170
- if (netdev->type == NET_CLIENT_DRIVER_DUMP ||
160
+ peer = net_hub_add_port(net->has_vlan ? net->vlan : 0, NULL, NULL);
171
- netdev->type == NET_CLIENT_DRIVER_NIC ||
161
}
172
+ if (netdev->type == NET_CLIENT_DRIVER_NIC ||
162
173
!net_client_init_fun[netdev->type]) {
163
if (net->has_vlan && !vlan_warned) {
174
error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "type",
175
"a netdev backend type");
176
@@ -XXX,XX +XXX,XX @@ static int net_client_init1(const void *object, bool is_netdev, Error **errp)
177
legacy.type = NET_CLIENT_DRIVER_VDE;
178
legacy.u.vde = opts->u.vde;
179
break;
180
- case NET_LEGACY_OPTIONS_TYPE_DUMP:
181
- legacy.type = NET_CLIENT_DRIVER_DUMP;
182
- legacy.u.dump = opts->u.dump;
183
- break;
184
case NET_LEGACY_OPTIONS_TYPE_BRIDGE:
185
legacy.type = NET_CLIENT_DRIVER_BRIDGE;
186
legacy.u.bridge = opts->u.bridge;
164
diff --git a/qapi/net.json b/qapi/net.json
187
diff --git a/qapi/net.json b/qapi/net.json
165
index XXXXXXX..XXXXXXX 100644
188
index XXXXXXX..XXXXXXX 100644
166
--- a/qapi/net.json
189
--- a/qapi/net.json
167
+++ b/qapi/net.json
190
+++ b/qapi/net.json
168
@@ -XXX,XX +XXX,XX @@
191
@@ -XXX,XX +XXX,XX @@
169
# Connect two or more net clients through a software hub.
192
#
170
#
193
# Add a network backend.
171
# @hubid: hub identifier number
194
#
172
+# @netdev: used to connect hub to a netdev instead of a device (since 2.12)
195
-# @type: the type of network backend. Current valid values are 'user', 'tap',
173
#
196
-# 'vde', 'socket', 'dump' and 'bridge'
174
# Since: 1.2
197
+# @type: the type of network backend. Possible values are listed in
175
##
198
+# NetClientDriver (excluding 'none' and 'nic')
176
{ 'struct': 'NetdevHubPortOptions',
199
#
177
'data': {
200
# @id: the name of the new network backend
178
- 'hubid': 'int32' } }
201
#
179
+ 'hubid': 'int32',
202
@@ -XXX,XX +XXX,XX @@
180
+ '*netdev': 'str' } }
203
'*mode': 'uint16' } }
181
204
182
##
205
##
183
# @NetdevNetmapOptions:
206
-# @NetdevDumpOptions:
207
-#
208
-# Dump VLAN network traffic to a file.
209
-#
210
-# @len: per-packet size limit (64k default). Understands [TGMKkb]
211
-# suffixes.
212
-#
213
-# @file: dump file path (default is qemu-vlan0.pcap)
214
-#
215
-# Since: 1.2
216
-##
217
-{ 'struct': 'NetdevDumpOptions',
218
- 'data': {
219
- '*len': 'size',
220
- '*file': 'str' } }
221
-
222
-##
223
# @NetdevBridgeOptions:
224
#
225
# Connect a host TAP network interface to a host bridge device.
226
@@ -XXX,XX +XXX,XX @@
227
# Available netdev drivers.
228
#
229
# Since: 2.7
230
+#
231
+# 'dump' - removed with 2.12
232
##
233
{ 'enum': 'NetClientDriver',
234
- 'data': [ 'none', 'nic', 'user', 'tap', 'l2tpv3', 'socket', 'vde', 'dump',
235
+ 'data': [ 'none', 'nic', 'user', 'tap', 'l2tpv3', 'socket', 'vde',
236
'bridge', 'hubport', 'netmap', 'vhost-user' ] }
237
238
##
239
@@ -XXX,XX +XXX,XX @@
240
'l2tpv3': 'NetdevL2TPv3Options',
241
'socket': 'NetdevSocketOptions',
242
'vde': 'NetdevVdeOptions',
243
- 'dump': 'NetdevDumpOptions',
244
'bridge': 'NetdevBridgeOptions',
245
'hubport': 'NetdevHubPortOptions',
246
'netmap': 'NetdevNetmapOptions',
247
@@ -XXX,XX +XXX,XX @@
248
##
249
{ 'enum': 'NetLegacyOptionsType',
250
'data': ['none', 'nic', 'user', 'tap', 'l2tpv3', 'socket', 'vde',
251
- 'dump', 'bridge', 'netmap', 'vhost-user'] }
252
+ 'bridge', 'netmap', 'vhost-user'] }
253
254
##
255
# @NetLegacyOptions:
256
@@ -XXX,XX +XXX,XX @@
257
'l2tpv3': 'NetdevL2TPv3Options',
258
'socket': 'NetdevSocketOptions',
259
'vde': 'NetdevVdeOptions',
260
- 'dump': 'NetdevDumpOptions',
261
'bridge': 'NetdevBridgeOptions',
262
'netmap': 'NetdevNetmapOptions',
263
'vhost-user': 'NetdevVhostUserOptions' } }
264
diff --git a/qemu-doc.texi b/qemu-doc.texi
265
index XXXXXXX..XXXXXXX 100644
266
--- a/qemu-doc.texi
267
+++ b/qemu-doc.texi
268
@@ -XXX,XX +XXX,XX @@ that can be specified with the ``-device'' parameter.
269
The drive addr argument is replaced by the the addr argument
270
that can be specified with the ``-device'' parameter.
271
272
-@subsection -net dump (since 2.10.0)
273
-
274
-The ``--net dump'' argument is now replaced with the
275
-``-object filter-dump'' argument which works in combination
276
-with the modern ``-netdev`` backends instead.
277
-
278
@subsection -usbdevice (since 2.10.0)
279
280
The ``-usbdevice DEV'' argument is now a synonym for setting
184
diff --git a/qemu-options.hx b/qemu-options.hx
281
diff --git a/qemu-options.hx b/qemu-options.hx
185
index XXXXXXX..XXXXXXX 100644
282
index XXXXXXX..XXXXXXX 100644
186
--- a/qemu-options.hx
283
--- a/qemu-options.hx
187
+++ b/qemu-options.hx
284
+++ b/qemu-options.hx
188
@@ -XXX,XX +XXX,XX @@ DEF("netdev", HAS_ARG, QEMU_OPTION_netdev,
285
@@ -XXX,XX +XXX,XX @@ DEF("net", HAS_ARG, QEMU_OPTION_net,
189
#endif
286
" configure or create an on-board (or machine default) NIC and\n"
190
"-netdev vhost-user,id=str,chardev=dev[,vhostforce=on|off]\n"
287
" connect it either to VLAN 'n' or the netdev 'nd' (for pluggable\n"
191
" configure a vhost-user network, backed by a chardev 'dev'\n"
288
" NICs please use '-device devtype,netdev=nd' instead)\n"
192
- "-netdev hubport,id=str,hubid=n\n"
289
- "-net dump[,vlan=n][,file=f][,len=n]\n"
193
+ "-netdev hubport,id=str,hubid=n[,netdev=nd]\n"
290
- " dump traffic on vlan 'n' to file 'f' (max n bytes per packet)\n"
194
" configure a hub port on QEMU VLAN 'n'\n", QEMU_ARCH_ALL)
291
"-net none use it alone to have zero network devices. If no -net option\n"
195
DEF("net", HAS_ARG, QEMU_OPTION_net,
292
" is provided, the default is '-net nic -net user'\n"
196
"-net nic[,vlan=n][,netdev=nd][,macaddr=mac][,model=type][,name=str][,addr=str][,vectors=v]\n"
293
"-net ["
197
@@ -XXX,XX +XXX,XX @@ vde_switch -F -sock /tmp/myswitch
294
@@ -XXX,XX +XXX,XX @@ qemu -m 512 -object memory-backend-file,id=mem,size=512M,mem-path=/hugetlbfs,sha
198
qemu-system-i386 linux.img -net nic -net vde,sock=/tmp/myswitch
295
-device virtio-net-pci,netdev=net0
199
@end example
296
@end example
200
297
201
-@item -netdev hubport,id=@var{id},hubid=@var{hubid}
298
-@item -net dump[,vlan=@var{n}][,file=@var{file}][,len=@var{len}]
202
+@item -netdev hubport,id=@var{id},hubid=@var{hubid}[,netdev=@var{nd}]
299
-Dump network traffic on VLAN @var{n} to file @var{file} (@file{qemu-vlan0.pcap} by default).
203
300
-At most @var{len} bytes (64k by default) per packet are stored. The file format is
204
Create a hub port on QEMU "vlan" @var{hubid}.
301
-libpcap, so it can be analyzed with tools such as tcpdump or Wireshark.
205
302
-Note: For devices created with '-netdev', use '-object filter-dump,...' instead.
206
The hubport netdev lets you connect a NIC to a QEMU "vlan" instead of a single
303
-
207
netdev. @code{-net} and @code{-device} with parameter @option{vlan} create the
304
@item -net none
208
-required hub automatically.
305
Indicate that no network devices should be configured. It is used to
209
+required hub automatically. Alternatively, you can also connect the hubport
306
override the default configuration (@option{-net nic -net user}) which
210
+to another netdev with ID @var{nd} by using the @option{netdev=@var{nd}}
211
+option.
212
213
@item -netdev vhost-user,chardev=@var{id}[,vhostforce=on|off][,queues=n]
214
215
--
307
--
216
2.7.4
308
2.7.4
217
309
218
310
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
They are deprecated since QEMU v2.10, and so far nobody complained that
4
concept only, they should work with the modern netdevs, too. So now
4
these commands are still necessary for any reason - and since you can use
5
it is possible to use this command with one, two or three parameters.
5
'netdev_add' and 'netdev_remove' instead, there also should not be any
6
6
real reason. Since they are also standing in the way for the upcoming
7
With one parameter, the command installs a hostfwd rule on the default
7
'vlan' clean-up, it's now time to remove them.
8
"user" network:
8
9
hostfwd_add tcp:...
9
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
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>
10
Signed-off-by: Thomas Huth <thuth@redhat.com>
21
Signed-off-by: Jason Wang <jasowang@redhat.com>
11
Signed-off-by: Jason Wang <jasowang@redhat.com>
22
---
12
---
23
hmp-commands.hx | 4 ++--
13
hmp-commands.hx | 30 ------------------
24
net/slirp.c | 33 +++++++++++++++++++++++----------
14
hmp.h | 3 --
25
2 files changed, 25 insertions(+), 12 deletions(-)
15
monitor.c | 61 ------------------------------------
16
net/net.c | 94 --------------------------------------------------------
17
qemu-doc.texi | 10 ------
18
tests/test-hmp.c | 2 --
19
6 files changed, 200 deletions(-)
26
20
27
diff --git a/hmp-commands.hx b/hmp-commands.hx
21
diff --git a/hmp-commands.hx b/hmp-commands.hx
28
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
29
--- a/hmp-commands.hx
23
--- a/hmp-commands.hx
30
+++ b/hmp-commands.hx
24
+++ b/hmp-commands.hx
31
@@ -XXX,XX +XXX,XX @@ ETEXI
25
@@ -XXX,XX +XXX,XX @@ Inject PCIe AER error
26
ETEXI
27
32
{
28
{
33
.name = "hostfwd_add",
29
- .name = "host_net_add",
34
.args_type = "arg1:s,arg2:s?,arg3:s?",
30
- .args_type = "device:s,opts:s?",
35
- .params = "[vlan_id name] [tcp|udp]:[hostaddr]:hostport-[guestaddr]:guestport",
31
- .params = "tap|user|socket|vde|netmap|bridge|vhost-user|dump [options]",
36
+ .params = "[hub_id name]|[netdev_id] [tcp|udp]:[hostaddr]:hostport-[guestaddr]:guestport",
32
- .help = "add host VLAN client (deprecated, use netdev_add instead)",
37
.help = "redirect TCP or UDP connections from host to guest (requires -net user)",
33
- .cmd = hmp_host_net_add,
38
.cmd = hmp_hostfwd_add,
34
- .command_completion = host_net_add_completion,
39
},
35
- },
40
@@ -XXX,XX +XXX,XX @@ ETEXI
36
-
41
{
37
-STEXI
42
.name = "hostfwd_remove",
38
-@item host_net_add
43
.args_type = "arg1:s,arg2:s?,arg3:s?",
39
-@findex host_net_add
44
- .params = "[vlan_id name] [tcp|udp]:[hostaddr]:hostport",
40
-Add host VLAN client. Deprecated, please use @code{netdev_add} instead.
45
+ .params = "[hub_id name]|[netdev_id] [tcp|udp]:[hostaddr]:hostport",
41
-ETEXI
46
.help = "remove host-to-guest TCP or UDP redirection",
42
-
47
.cmd = hmp_hostfwd_remove,
43
- {
48
},
44
- .name = "host_net_remove",
49
diff --git a/net/slirp.c b/net/slirp.c
45
- .args_type = "vlan_id:i,device:s",
50
index XXXXXXX..XXXXXXX 100644
46
- .params = "vlan_id name",
51
--- a/net/slirp.c
47
- .help = "remove host VLAN client (deprecated, use netdev_del instead)",
52
+++ b/net/slirp.c
48
- .cmd = hmp_host_net_remove,
53
@@ -XXX,XX +XXX,XX @@ error:
49
- .command_completion = host_net_remove_completion,
54
return -1;
50
- },
51
-
52
-STEXI
53
-@item host_net_remove
54
-@findex host_net_remove
55
-Remove host VLAN client. Deprecated, please use @code{netdev_del} instead.
56
-ETEXI
57
-
58
- {
59
.name = "netdev_add",
60
.args_type = "netdev:O",
61
.params = "[user|tap|socket|vde|bridge|hubport|netmap|vhost-user],id=str[,prop=value][,...]",
62
diff --git a/hmp.h b/hmp.h
63
index XXXXXXX..XXXXXXX 100644
64
--- a/hmp.h
65
+++ b/hmp.h
66
@@ -XXX,XX +XXX,XX @@ void migrate_set_capability_completion(ReadLineState *rs, int nb_args,
67
const char *str);
68
void migrate_set_parameter_completion(ReadLineState *rs, int nb_args,
69
const char *str);
70
-void host_net_add_completion(ReadLineState *rs, int nb_args, const char *str);
71
-void host_net_remove_completion(ReadLineState *rs, int nb_args,
72
- const char *str);
73
void delvm_completion(ReadLineState *rs, int nb_args, const char *str);
74
void loadvm_completion(ReadLineState *rs, int nb_args, const char *str);
75
void hmp_rocker(Monitor *mon, const QDict *qdict);
76
diff --git a/monitor.c b/monitor.c
77
index XXXXXXX..XXXXXXX 100644
78
--- a/monitor.c
79
+++ b/monitor.c
80
@@ -XXX,XX +XXX,XX @@ void migrate_set_parameter_completion(ReadLineState *rs, int nb_args,
81
}
55
}
82
}
56
83
57
-static SlirpState *slirp_lookup(Monitor *mon, const char *vlan,
84
-void host_net_add_completion(ReadLineState *rs, int nb_args, const char *str)
58
- const char *stack)
85
-{
59
+static SlirpState *slirp_lookup(Monitor *mon, const char *hub_id,
86
- int i;
60
+ const char *name)
87
- size_t len;
88
- if (nb_args != 2) {
89
- return;
90
- }
91
- len = strlen(str);
92
- readline_set_completion_index(rs, len);
93
- for (i = 0; host_net_devices[i]; i++) {
94
- if (!strncmp(host_net_devices[i], str, len)) {
95
- readline_add_completion(rs, host_net_devices[i]);
96
- }
97
- }
98
-}
99
-
100
-void host_net_remove_completion(ReadLineState *rs, int nb_args, const char *str)
101
-{
102
- NetClientState *ncs[MAX_QUEUE_NUM];
103
- int count, i, len;
104
-
105
- len = strlen(str);
106
- readline_set_completion_index(rs, len);
107
- if (nb_args == 2) {
108
- count = qemu_find_net_clients_except(NULL, ncs,
109
- NET_CLIENT_DRIVER_NONE,
110
- MAX_QUEUE_NUM);
111
- for (i = 0; i < MIN(count, MAX_QUEUE_NUM); i++) {
112
- int id;
113
- char name[16];
114
-
115
- if (net_hub_id_for_client(ncs[i], &id)) {
116
- continue;
117
- }
118
- snprintf(name, sizeof(name), "%d", id);
119
- if (!strncmp(str, name, len)) {
120
- readline_add_completion(rs, name);
121
- }
122
- }
123
- return;
124
- } else if (nb_args == 3) {
125
- count = qemu_find_net_clients_except(NULL, ncs,
126
- NET_CLIENT_DRIVER_NIC,
127
- MAX_QUEUE_NUM);
128
- for (i = 0; i < MIN(count, MAX_QUEUE_NUM); i++) {
129
- int id;
130
- const char *name;
131
-
132
- if (ncs[i]->info->type == NET_CLIENT_DRIVER_HUBPORT ||
133
- net_hub_id_for_client(ncs[i], &id)) {
134
- continue;
135
- }
136
- name = ncs[i]->name;
137
- if (!strncmp(str, name, len)) {
138
- readline_add_completion(rs, name);
139
- }
140
- }
141
- return;
142
- }
143
-}
144
-
145
static void vm_completion(ReadLineState *rs, const char *str)
61
{
146
{
62
-
147
size_t len;
63
- if (vlan) {
148
diff --git a/net/net.c b/net/net.c
64
+ if (name) {
149
index XXXXXXX..XXXXXXX 100644
65
NetClientState *nc;
150
--- a/net/net.c
66
- nc = net_hub_find_client_by_name(strtol(vlan, NULL, 0), stack);
151
+++ b/net/net.c
67
- if (!nc) {
152
@@ -XXX,XX +XXX,XX @@
68
- monitor_printf(mon, "unrecognized (vlan-id, stackname) pair\n");
153
static VMChangeStateEntry *net_change_state_entry;
69
- return NULL;
154
static QTAILQ_HEAD(, NetClientState) net_clients;
70
+ if (hub_id) {
155
71
+ nc = net_hub_find_client_by_name(strtol(hub_id, NULL, 0), name);
156
-const char *host_net_devices[] = {
72
+ if (!nc) {
157
- "tap",
73
+ monitor_printf(mon, "unrecognized (vlan-id, stackname) pair\n");
158
- "socket",
74
+ return NULL;
159
-#ifdef CONFIG_NET_BRIDGE
75
+ }
160
- "bridge",
76
+ } else {
161
-#endif
77
+ nc = qemu_find_netdev(name);
162
-#ifdef CONFIG_NETMAP
78
+ if (!nc) {
163
- "netmap",
79
+ monitor_printf(mon, "unrecognized netdev id '%s'\n", name);
164
-#endif
80
+ return NULL;
165
-#ifdef CONFIG_SLIRP
81
+ }
166
- "user",
82
}
167
-#endif
83
if (strcmp(nc->model, "user")) {
168
-#ifdef CONFIG_VDE
84
monitor_printf(mon, "invalid device specified\n");
169
- "vde",
85
@@ -XXX,XX +XXX,XX @@ void hmp_hostfwd_remove(Monitor *mon, const QDict *qdict)
170
-#endif
86
const char *arg2 = qdict_get_try_str(qdict, "arg2");
171
- "vhost-user",
87
const char *arg3 = qdict_get_try_str(qdict, "arg3");
172
- NULL,
88
173
-};
89
- if (arg2) {
174
-
90
+ if (arg3) {
175
/***********************************************************/
91
s = slirp_lookup(mon, arg1, arg2);
176
/* network device redirectors */
92
src_str = arg3;
177
93
+ } else if (arg2) {
178
@@ -XXX,XX +XXX,XX @@ static int net_client_init(QemuOpts *opts, bool is_netdev, Error **errp)
94
+ s = slirp_lookup(mon, NULL, arg1);
179
return ret;
95
+ src_str = arg2;
180
}
96
} else {
181
97
s = slirp_lookup(mon, NULL, NULL);
182
-
98
src_str = arg1;
183
-static int net_host_check_device(const char *device)
99
@@ -XXX,XX +XXX,XX @@ void hmp_hostfwd_add(Monitor *mon, const QDict *qdict)
184
-{
100
const char *arg2 = qdict_get_try_str(qdict, "arg2");
185
- int i;
101
const char *arg3 = qdict_get_try_str(qdict, "arg3");
186
- for (i = 0; host_net_devices[i]; i++) {
102
187
- if (!strncmp(host_net_devices[i], device,
103
- if (arg2) {
188
- strlen(host_net_devices[i]))) {
104
+ if (arg3) {
189
- return 1;
105
s = slirp_lookup(mon, arg1, arg2);
190
- }
106
redir_str = arg3;
191
- }
107
+ } else if (arg2) {
192
-
108
+ s = slirp_lookup(mon, NULL, arg1);
193
- return 0;
109
+ redir_str = arg2;
194
-}
110
} else {
195
-
111
s = slirp_lookup(mon, NULL, NULL);
196
-void hmp_host_net_add(Monitor *mon, const QDict *qdict)
112
redir_str = arg1;
197
-{
198
- const char *device = qdict_get_str(qdict, "device");
199
- const char *opts_str = qdict_get_try_str(qdict, "opts");
200
- Error *local_err = NULL;
201
- QemuOpts *opts;
202
- static bool warned;
203
-
204
- if (!warned && !qtest_enabled()) {
205
- error_report("host_net_add is deprecated, use netdev_add instead");
206
- warned = true;
207
- }
208
-
209
- if (!net_host_check_device(device)) {
210
- monitor_printf(mon, "invalid host network device %s\n", device);
211
- return;
212
- }
213
-
214
- opts = qemu_opts_parse_noisily(qemu_find_opts("net"),
215
- opts_str ? opts_str : "", false);
216
- if (!opts) {
217
- return;
218
- }
219
-
220
- qemu_opt_set(opts, "type", device, &error_abort);
221
-
222
- net_client_init(opts, false, &local_err);
223
- if (local_err) {
224
- error_report_err(local_err);
225
- monitor_printf(mon, "adding host network device %s failed\n", device);
226
- }
227
-}
228
-
229
-void hmp_host_net_remove(Monitor *mon, const QDict *qdict)
230
-{
231
- NetClientState *nc;
232
- int vlan_id = qdict_get_int(qdict, "vlan_id");
233
- const char *device = qdict_get_str(qdict, "device");
234
- static bool warned;
235
-
236
- if (!warned && !qtest_enabled()) {
237
- error_report("host_net_remove is deprecated, use netdev_del instead");
238
- warned = true;
239
- }
240
-
241
- nc = net_hub_find_client_by_name(vlan_id, device);
242
- if (!nc) {
243
- error_report("Host network device '%s' on hub '%d' not found",
244
- device, vlan_id);
245
- return;
246
- }
247
- if (nc->info->type == NET_CLIENT_DRIVER_NIC) {
248
- error_report("invalid host network device '%s'", device);
249
- return;
250
- }
251
-
252
- qemu_del_net_client(nc->peer);
253
- qemu_del_net_client(nc);
254
- qemu_opts_del(qemu_opts_find(qemu_find_opts("net"), device));
255
-}
256
-
257
void netdev_add(QemuOpts *opts, Error **errp)
258
{
259
net_client_init(opts, true, errp);
260
diff --git a/qemu-doc.texi b/qemu-doc.texi
261
index XXXXXXX..XXXXXXX 100644
262
--- a/qemu-doc.texi
263
+++ b/qemu-doc.texi
264
@@ -XXX,XX +XXX,XX @@ from qcow2 images.
265
266
The ``query-cpus'' command is replaced by the ``query-cpus-fast'' command.
267
268
-@section System emulator human monitor commands
269
-
270
-@subsection host_net_add (since 2.10.0)
271
-
272
-The ``host_net_add'' command is replaced by the ``netdev_add'' command.
273
-
274
-@subsection host_net_remove (since 2.10.0)
275
-
276
-The ``host_net_remove'' command is replaced by the ``netdev_del'' command.
277
-
278
@section System emulator devices
279
280
@subsection ivshmem (since 2.6.0)
281
diff --git a/tests/test-hmp.c b/tests/test-hmp.c
282
index XXXXXXX..XXXXXXX 100644
283
--- a/tests/test-hmp.c
284
+++ b/tests/test-hmp.c
285
@@ -XXX,XX +XXX,XX @@ static const char *hmp_cmds[] = {
286
"dump-guest-memory /dev/null 0 4096",
287
"dump-guest-memory /dev/null",
288
"gdbserver",
289
- "host_net_add user id=net0",
290
"hostfwd_add tcp::43210-:43210",
291
"hostfwd_remove tcp::43210-:43210",
292
- "host_net_remove 0 net0",
293
"i /w 0",
294
"log all",
295
"log none",
113
--
296
--
114
2.7.4
297
2.7.4
115
298
116
299
diff view generated by jsdifflib
1
From: Mao Zhongyi <maozy.fnst@cn.fujitsu.com>
1
From: Thomas Huth <thuth@redhat.com>
2
2
3
Packet size some time different or when network is busy.
3
The legacy "-net" option can be quite confusing for the users since most
4
Based on same payload size, but TCP protocol can not
4
people do not expect to get a "vlan" hub between their emulated guest
5
guarantee send the same one packet in the same way,
5
hardware and the host backend. But so far, we are also not able to get
6
6
rid of "-net" completely, since it is the only way to configure on-board
7
like that:
7
NICs that can not be instantiated via "-device" yet. It's also a little
8
We send this payload:
8
bit shorter to type "-net nic -net tap" instead of "-device xyz,netdev=n1
9
------------------------------
9
-netdev tap,id=n1".
10
| header |1|2|3|4|5|6|7|8|9|0|
10
11
------------------------------
11
So what we need is a new convenience option that is shorter to type than
12
12
the full -device + -netdev stuff, and which can be used to configure the
13
primary:
13
on-board NICs that can not be handled via -device yet. Thus this patch now
14
ppkt1:
14
provides such a new option "--nic": It adds an entry in the nd_table to
15
----------------
15
configure a on-board / default NIC, creates a host backend and connects
16
| header |1|2|3|
16
the two directly, without a confusing "vlan" hub inbetween.
17
----------------
17
18
ppkt2:
18
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
19
------------------------
19
Signed-off-by: Thomas Huth <thuth@redhat.com>
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>
20
Signed-off-by: Jason Wang <jasowang@redhat.com>
70
---
21
---
71
net/colo-compare.c | 343 +++++++++++++++++++++++++++++++++++------------------
22
include/sysemu/sysemu.h | 1 +
72
net/colo.c | 9 ++
23
net/net.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++++
73
net/colo.h | 15 +++
24
qemu-options.hx | 40 +++++++++++++++++++++----
74
net/trace-events | 2 +-
25
vl.c | 7 +++++
75
4 files changed, 250 insertions(+), 119 deletions(-)
26
4 files changed, 120 insertions(+), 6 deletions(-)
76
27
77
diff --git a/net/colo-compare.c b/net/colo-compare.c
28
diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
78
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
79
--- a/net/colo-compare.c
30
--- a/include/sysemu/sysemu.h
80
+++ b/net/colo-compare.c
31
+++ b/include/sysemu/sysemu.h
81
@@ -XXX,XX +XXX,XX @@
32
@@ -XXX,XX +XXX,XX @@ extern QemuOptsList bdrv_runtime_opts;
82
#define COMPARE_READ_LEN_MAX NET_BUFSIZE
33
extern QemuOptsList qemu_chardev_opts;
83
#define MAX_QUEUE_SIZE 1024
34
extern QemuOptsList qemu_device_opts;
84
35
extern QemuOptsList qemu_netdev_opts;
85
+#define COLO_COMPARE_FREE_PRIMARY 0x01
36
+extern QemuOptsList qemu_nic_opts;
86
+#define COLO_COMPARE_FREE_SECONDARY 0x02
37
extern QemuOptsList qemu_net_opts;
87
+
38
extern QemuOptsList qemu_global_opts;
88
/* TODO: Should be configurable */
39
extern QemuOptsList qemu_mon_opts;
89
#define REGULAR_PACKET_CHECK_MS 3000
40
diff --git a/net/net.c b/net/net.c
90
41
index XXXXXXX..XXXXXXX 100644
91
@@ -XXX,XX +XXX,XX @@ static gint seq_sorter(Packet *a, Packet *b, gpointer data)
42
--- a/net/net.c
92
return ntohl(atcp->th_seq) - ntohl(btcp->th_seq);
43
+++ b/net/net.c
44
@@ -XXX,XX +XXX,XX @@ static int net_init_netdev(void *dummy, QemuOpts *opts, Error **errp)
45
return net_client_init(opts, true, errp);
93
}
46
}
94
47
95
+static void fill_pkt_tcp_info(void *data, uint32_t *max_ack)
48
+/* For the convenience "--nic" parameter */
49
+static int net_param_nic(void *dummy, QemuOpts *opts, Error **errp)
96
+{
50
+{
97
+ Packet *pkt = data;
51
+ char *mac, *nd_id;
98
+ struct tcphdr *tcphd;
52
+ int idx, ret;
99
+
53
+ NICInfo *ni;
100
+ tcphd = (struct tcphdr *)pkt->transport_header;
54
+ const char *type;
101
+
55
+
102
+ pkt->tcp_seq = ntohl(tcphd->th_seq);
56
+ type = qemu_opt_get(opts, "type");
103
+ pkt->tcp_ack = ntohl(tcphd->th_ack);
57
+ if (type && g_str_equal(type, "none")) {
104
+ *max_ack = *max_ack > pkt->tcp_ack ? *max_ack : pkt->tcp_ack;
58
+ return 0; /* Nothing to do, default_net is cleared in vl.c */
105
+ pkt->header_size = pkt->transport_header - (uint8_t *)pkt->data
59
+ }
106
+ + (tcphd->th_off << 2) - pkt->vnet_hdr_len;
60
+
107
+ pkt->payload_size = pkt->size - pkt->header_size;
61
+ idx = nic_get_free_idx();
108
+ pkt->seq_end = pkt->tcp_seq + pkt->payload_size;
62
+ if (idx == -1 || nb_nics >= MAX_NICS) {
109
+ pkt->flags = tcphd->th_flags;
63
+ error_setg(errp, "no more on-board/default NIC slots available");
64
+ return -1;
65
+ }
66
+
67
+ if (!type) {
68
+ qemu_opt_set(opts, "type", "user", &error_abort);
69
+ }
70
+
71
+ ni = &nd_table[idx];
72
+ memset(ni, 0, sizeof(*ni));
73
+ ni->model = qemu_opt_get_del(opts, "model");
74
+
75
+ /* Create an ID if the user did not specify one */
76
+ nd_id = g_strdup(qemu_opts_id(opts));
77
+ if (!nd_id) {
78
+ nd_id = g_strdup_printf("__org.qemu.nic%i\n", idx);
79
+ qemu_opts_set_id(opts, nd_id);
80
+ }
81
+
82
+ /* Handle MAC address */
83
+ mac = qemu_opt_get_del(opts, "mac");
84
+ if (mac) {
85
+ ret = net_parse_macaddr(ni->macaddr.a, mac);
86
+ g_free(mac);
87
+ if (ret) {
88
+ error_setg(errp, "invalid syntax for ethernet address");
89
+ return -1;
90
+ }
91
+ if (is_multicast_ether_addr(ni->macaddr.a)) {
92
+ error_setg(errp, "NIC cannot have multicast MAC address");
93
+ return -1;
94
+ }
95
+ }
96
+ qemu_macaddr_default_if_unset(&ni->macaddr);
97
+
98
+ ret = net_client_init(opts, true, errp);
99
+ if (ret == 0) {
100
+ ni->netdev = qemu_find_netdev(nd_id);
101
+ ni->used = true;
102
+ nb_nics++;
103
+ }
104
+
105
+ g_free(nd_id);
106
+ return ret;
110
+}
107
+}
111
+
108
+
112
/*
109
int net_init_clients(Error **errp)
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
{
110
{
119
if (g_queue_get_length(queue) <= MAX_QUEUE_SIZE) {
111
net_change_state_entry =
120
if (pkt->ip->ip_p == IPPROTO_TCP) {
112
@@ -XXX,XX +XXX,XX @@ int net_init_clients(Error **errp)
121
+ fill_pkt_tcp_info(pkt, max_ack);
113
return -1;
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
}
114
}
127
115
128
if (mode == PRIMARY_IN) {
116
+ if (qemu_opts_foreach(qemu_find_opts("nic"), net_param_nic, NULL, errp)) {
129
- if (!colo_insert_packet(&conn->primary_list, pkt)) {
117
+ return -1;
130
+ if (!colo_insert_packet(&conn->primary_list, pkt, &conn->pack)) {
118
+ }
131
error_report("colo compare primary queue size too big,"
119
+
132
"drop packet");
120
if (qemu_opts_foreach(qemu_find_opts("net"), net_init_client, NULL, errp)) {
133
}
121
return -1;
134
} else {
122
}
135
- if (!colo_insert_packet(&conn->secondary_list, pkt)) {
123
@@ -XXX,XX +XXX,XX @@ QemuOptsList qemu_netdev_opts = {
136
+ if (!colo_insert_packet(&conn->secondary_list, pkt, &conn->sack)) {
124
},
137
error_report("colo compare secondary queue size too big,"
125
};
138
"drop packet");
126
139
}
127
+QemuOptsList qemu_nic_opts = {
140
@@ -XXX,XX +XXX,XX @@ static int packet_enqueue(CompareState *s, int mode, Connection **con)
128
+ .name = "nic",
141
return 0;
129
+ .implied_opt_name = "type",
142
}
130
+ .head = QTAILQ_HEAD_INITIALIZER(qemu_nic_opts.head),
143
131
+ .desc = {
144
+static inline bool after(uint32_t seq1, uint32_t seq2)
132
+ /*
145
+{
133
+ * no elements => accept any params
146
+ return (int32_t)(seq1 - seq2) > 0;
134
+ * validation will happen later
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
+ */
135
+ */
224
+ if (colo_compare_packet_payload(ppkt, spkt,
136
+ { /* end of list */ }
225
+ ppkt->header_size + ppkt->offset,
137
+ },
226
+ spkt->header_size + spkt->offset,
138
+};
227
+ spkt->payload_size - spkt->offset)) {
139
+
228
+ *mark = COLO_COMPARE_FREE_SECONDARY;
140
QemuOptsList qemu_net_opts = {
229
+ ppkt->offset += spkt->payload_size - spkt->offset;
141
.name = "net",
230
+ return true;
142
.implied_opt_name = "type",
231
+ }
143
diff --git a/qemu-options.hx b/qemu-options.hx
232
+ }
144
index XXXXXXX..XXXXXXX 100644
233
145
--- a/qemu-options.hx
234
- trace_colo_compare_main("compare tcp");
146
+++ b/qemu-options.hx
235
+ return false;
147
@@ -XXX,XX +XXX,XX @@ DEF("netdev", HAS_ARG, QEMU_OPTION_netdev,
236
+}
148
#endif
237
149
"-netdev hubport,id=str,hubid=n[,netdev=nd]\n"
238
- ptcp = (struct tcphdr *)ppkt->transport_header;
150
" configure a hub port on QEMU VLAN 'n'\n", QEMU_ARCH_ALL)
239
- stcp = (struct tcphdr *)spkt->transport_header;
151
+DEF("nic", HAS_ARG, QEMU_OPTION_nic,
240
+static void colo_compare_tcp(CompareState *s, Connection *conn)
152
+ "--nic [tap|bridge|"
241
+{
153
+#ifdef CONFIG_SLIRP
242
+ Packet *ppkt = NULL, *spkt = NULL;
154
+ "user|"
243
+ int8_t mark;
155
+#endif
244
156
+#ifdef __linux__
245
/*
157
+ "l2tpv3|"
246
- * The 'identification' field in the IP header is *very* random
158
+#endif
247
- * it almost never matches. Fudge this by ignoring differences in
159
+#ifdef CONFIG_VDE
248
- * unfragmented packets; they'll normally sort themselves out if different
160
+ "vde|"
249
- * anyway, and it should recover at the TCP level.
161
+#endif
250
- * An alternative would be to get both the primary and secondary to rewrite
162
+#ifdef CONFIG_NETMAP
251
- * somehow; but that would need some sync traffic to sync the state
163
+ "netmap|"
252
- */
164
+#endif
253
- if (ntohs(ppkt->ip->ip_off) & IP_DF) {
165
+#ifdef CONFIG_POSIX
254
- spkt->ip->ip_id = ppkt->ip->ip_id;
166
+ "vhost-user|"
255
- /* and the sum will be different if the IDs were different */
167
+#endif
256
- spkt->ip->ip_sum = ppkt->ip->ip_sum;
168
+ "socket][,option][,...][mac=macaddr]\n"
257
+ * If ppkt and spkt have the same payload, but ppkt's ACK
169
+ " initialize an on-board / default host NIC (using MAC address\n"
258
+ * is greater than spkt's ACK, in this case we can not
170
+ " macaddr) and connect it to the given host network backend\n"
259
+ * send the ppkt because it will cause the secondary guest
171
+ "--nic none use it alone to have zero network devices (the default is to\n"
260
+ * to miss sending some data in the next. Therefore, we
172
+ " provided a 'user' network connection)\n",
261
+ * record the maximum ACK in the current queue at both
173
+ QEMU_ARCH_ALL)
262
+ * primary side and secondary side. Only when the ack is
174
DEF("net", HAS_ARG, QEMU_OPTION_net,
263
+ * less than the smaller of the two maximum ack, then we
175
"-net nic[,vlan=n][,netdev=nd][,macaddr=mac][,model=type][,name=str][,addr=str][,vectors=v]\n"
264
+ * can ensure that the packet's payload is acknowledged by
176
" configure or create an on-board (or machine default) NIC and\n"
265
+ * primary and secondary.
177
" connect it either to VLAN 'n' or the netdev 'nd' (for pluggable\n"
266
+ */
178
" NICs please use '-device devtype,netdev=nd' instead)\n"
267
+ uint32_t min_ack = conn->pack > conn->sack ? conn->sack : conn->pack;
179
- "-net none use it alone to have zero network devices. If no -net option\n"
268
+
180
- " is provided, the default is '-net nic -net user'\n"
269
+pri:
181
"-net ["
270
+ if (g_queue_is_empty(&conn->primary_list)) {
182
#ifdef CONFIG_SLIRP
271
+ return;
183
"user|"
272
}
184
@@ -XXX,XX +XXX,XX @@ qemu -m 512 -object memory-backend-file,id=mem,size=512M,mem-path=/hugetlbfs,sha
273
+ ppkt = g_queue_pop_head(&conn->primary_list);
185
-device virtio-net-pci,netdev=net0
274
+sec:
186
@end example
275
+ if (g_queue_is_empty(&conn->secondary_list)) {
187
276
+ g_queue_push_head(&conn->primary_list, ppkt);
188
-@item -net none
277
+ return;
189
-Indicate that no network devices should be configured. It is used to
278
+ }
190
-override the default configuration (@option{-net nic -net user}) which
279
+ spkt = g_queue_pop_head(&conn->secondary_list);
191
-is activated if no @option{-net} options are provided.
280
192
+@item --nic [tap|bridge|user|l2tpv3|vde|netmap|vhost-user|socket][,...][,mac=macaddr]
281
- /*
193
+
282
- * Check tcp header length for tcp option field.
194
+This option is a shortcut for setting both, the on-board (default) guest NIC
283
- * th_off > 5 means this tcp packet have options field.
195
+hardware and the host network backend in one go. The host backend options are
284
- * The tcp options maybe always different.
196
+the same as with the corresponding @option{--netdev} option. The guest NIC
285
- * for example:
197
+hardware MAC address can be set with @option{mac=@var{macaddr}}.
286
- * From RFC 7323.
198
+
287
- * TCP Timestamps option (TSopt):
199
+@item --nic none
288
- * Kind: 8
200
+Indicate that no network devices should be configured. It is used to override
289
- *
201
+the default configuration (default NIC with @option{--net user} backend) which
290
- * Length: 10 bytes
202
+is activated if no other networking options are provided.
291
- *
203
ETEXI
292
- * +-------+-------+---------------------+---------------------+
204
293
- * |Kind=8 | 10 | TS Value (TSval) |TS Echo Reply (TSecr)|
205
STEXI
294
- * +-------+-------+---------------------+---------------------+
206
diff --git a/vl.c b/vl.c
295
- * 1 1 4 4
207
index XXXXXXX..XXXXXXX 100644
296
- *
208
--- a/vl.c
297
- * In this case the primary guest's timestamp always different with
209
+++ b/vl.c
298
- * the secondary guest's timestamp. COLO just focus on payload,
210
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv, char **envp)
299
- * so we just need skip this field.
211
qemu_add_opts(&qemu_chardev_opts);
300
- */
212
qemu_add_opts(&qemu_device_opts);
301
+ if (ppkt->tcp_seq == ppkt->seq_end) {
213
qemu_add_opts(&qemu_netdev_opts);
302
+ colo_release_primary_pkt(s, ppkt);
214
+ qemu_add_opts(&qemu_nic_opts);
303
+ ppkt = NULL;
215
qemu_add_opts(&qemu_net_opts);
304
+ }
216
qemu_add_opts(&qemu_rtc_opts);
305
217
qemu_add_opts(&qemu_global_opts);
306
- ptrdiff_t ptcp_offset, stcp_offset;
218
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv, char **envp)
307
+ if (ppkt && conn->compare_seq && !after(ppkt->seq_end, conn->compare_seq)) {
219
exit(1);
308
+ trace_colo_compare_main("pri: this packet has compared");
220
}
309
+ colo_release_primary_pkt(s, ppkt);
221
break;
310
+ ppkt = NULL;
222
+ case QEMU_OPTION_nic:
311
+ }
223
+ default_net = 0;
312
224
+ if (net_client_parse(qemu_find_opts("nic"), optarg) == -1) {
313
- ptcp_offset = ppkt->transport_header - (uint8_t *)ppkt->data
225
+ exit(1);
314
- + (ptcp->th_off << 2) - ppkt->vnet_hdr_len;
226
+ }
315
- stcp_offset = spkt->transport_header - (uint8_t *)spkt->data
227
+ break;
316
- + (stcp->th_off << 2) - spkt->vnet_hdr_len;
228
case QEMU_OPTION_net:
317
- if (ppkt->size - ptcp_offset == spkt->size - stcp_offset) {
229
default_net = 0;
318
- res = colo_compare_packet_payload(ppkt, spkt,
230
if (net_client_parse(qemu_find_opts("net"), optarg) == -1) {
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
--
231
--
588
2.7.4
232
2.7.4
589
233
590
234
diff view generated by jsdifflib
New patch
1
From: Thomas Huth <thuth@redhat.com>
1
2
3
Headers like "hw/loader.h" and "qemu/sockets.h" are not needed in
4
the hw/net/*.c files. And Some other headers are included via other
5
headers already, so we can drop them, too.
6
7
Signed-off-by: Thomas Huth <thuth@redhat.com>
8
Signed-off-by: Jason Wang <jasowang@redhat.com>
9
---
10
hw/net/e1000.c | 1 -
11
hw/net/lance.c | 3 ---
12
hw/net/ne2000.c | 2 --
13
hw/net/pcnet-pci.c | 1 -
14
hw/net/pcnet.c | 1 -
15
hw/net/rtl8139.c | 2 --
16
hw/net/xgmac.c | 1 -
17
7 files changed, 11 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 @@
24
#include "hw/pci/pci.h"
25
#include "net/net.h"
26
#include "net/checksum.h"
27
-#include "hw/loader.h"
28
#include "sysemu/sysemu.h"
29
#include "sysemu/dma.h"
30
#include "qemu/iov.h"
31
diff --git a/hw/net/lance.c b/hw/net/lance.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/hw/net/lance.c
34
+++ b/hw/net/lance.c
35
@@ -XXX,XX +XXX,XX @@
36
*/
37
38
#include "qemu/osdep.h"
39
-#include "hw/sysbus.h"
40
-#include "net/net.h"
41
#include "qemu/timer.h"
42
-#include "qemu/sockets.h"
43
#include "hw/sparc/sparc32_dma.h"
44
#include "hw/net/lance.h"
45
#include "trace.h"
46
diff --git a/hw/net/ne2000.c b/hw/net/ne2000.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/hw/net/ne2000.c
49
+++ b/hw/net/ne2000.c
50
@@ -XXX,XX +XXX,XX @@
51
*/
52
#include "qemu/osdep.h"
53
#include "hw/pci/pci.h"
54
-#include "net/net.h"
55
#include "net/eth.h"
56
#include "ne2000.h"
57
-#include "hw/loader.h"
58
#include "sysemu/sysemu.h"
59
60
/* debug NE2000 card */
61
diff --git a/hw/net/pcnet-pci.c b/hw/net/pcnet-pci.c
62
index XXXXXXX..XXXXXXX 100644
63
--- a/hw/net/pcnet-pci.c
64
+++ b/hw/net/pcnet-pci.c
65
@@ -XXX,XX +XXX,XX @@
66
#include "qemu/osdep.h"
67
#include "hw/pci/pci.h"
68
#include "net/net.h"
69
-#include "hw/loader.h"
70
#include "qemu/timer.h"
71
#include "sysemu/dma.h"
72
#include "sysemu/sysemu.h"
73
diff --git a/hw/net/pcnet.c b/hw/net/pcnet.c
74
index XXXXXXX..XXXXXXX 100644
75
--- a/hw/net/pcnet.c
76
+++ b/hw/net/pcnet.c
77
@@ -XXX,XX +XXX,XX @@
78
#include "net/net.h"
79
#include "net/eth.h"
80
#include "qemu/timer.h"
81
-#include "qemu/sockets.h"
82
#include "sysemu/sysemu.h"
83
#include "trace.h"
84
85
diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c
86
index XXXXXXX..XXXXXXX 100644
87
--- a/hw/net/rtl8139.c
88
+++ b/hw/net/rtl8139.c
89
@@ -XXX,XX +XXX,XX @@
90
#include "qemu/timer.h"
91
#include "net/net.h"
92
#include "net/eth.h"
93
-#include "hw/loader.h"
94
#include "sysemu/sysemu.h"
95
-#include "qemu/iov.h"
96
97
/* debug RTL8139 card */
98
//#define DEBUG_RTL8139 1
99
diff --git a/hw/net/xgmac.c b/hw/net/xgmac.c
100
index XXXXXXX..XXXXXXX 100644
101
--- a/hw/net/xgmac.c
102
+++ b/hw/net/xgmac.c
103
@@ -XXX,XX +XXX,XX @@
104
#include "hw/sysbus.h"
105
#include "qemu/log.h"
106
#include "net/net.h"
107
-#include "net/checksum.h"
108
109
#ifdef DEBUG_XGMAC
110
#define DEBUGF_BRK(message, args...) do { \
111
--
112
2.7.4
113
114
diff view generated by jsdifflib
New patch
1
From: Jay Zhou <jianjay.zhou@huawei.com>
1
2
3
If netdev_add tap,id=net0,...,vhost=on failed in net_init_tap_one(),
4
the followed up device_add virtio-net-pci,netdev=net0 will fail
5
too, prints:
6
7
TUNSETOFFLOAD ioctl() failed: Bad file descriptor TUNSETOFFLOAD
8
ioctl() failed: Bad file descriptor
9
10
The reason is that the fd of tap is closed when error occured after
11
calling net_init_tap_one().
12
13
The fd should be closed when calling net_init_tap_one failed:
14
- if tap_set_sndbuf() failed
15
- if tap_set_sndbuf() succeeded but vhost failed to open or
16
initialize with vhostforce flag on
17
- with wrong vhost command line parameter
18
The fd should not be closed just because vhost failed to open or
19
initialize but without vhostforce flag. So the followed up
20
device_add can fall back to userspace virtio successfully.
21
22
Suggested-by: Michael S. Tsirkin <mst@redhat.com>
23
Suggested-by: Igor Mammedov <imammedo@redhat.com>
24
Suggested-by: Jason Wang <jasowang@redhat.com>
25
Signed-off-by: Jay Zhou <jianjay.zhou@huawei.com>
26
Signed-off-by: Jason Wang <jasowang@redhat.com>
27
---
28
include/net/vhost_net.h | 3 +++
29
net/tap.c | 22 +++++++++++++++++-----
30
2 files changed, 20 insertions(+), 5 deletions(-)
31
32
diff --git a/include/net/vhost_net.h b/include/net/vhost_net.h
33
index XXXXXXX..XXXXXXX 100644
34
--- a/include/net/vhost_net.h
35
+++ b/include/net/vhost_net.h
36
@@ -XXX,XX +XXX,XX @@
37
#include "net/net.h"
38
#include "hw/virtio/vhost-backend.h"
39
40
+#define VHOST_NET_INIT_FAILED \
41
+ "vhost-net requested but could not be initialized"
42
+
43
struct vhost_net;
44
typedef struct vhost_net VHostNetState;
45
46
diff --git a/net/tap.c b/net/tap.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/net/tap.c
49
+++ b/net/tap.c
50
@@ -XXX,XX +XXX,XX @@ static void net_init_tap_one(const NetdevTapOptions *tap, NetClientState *peer,
51
if (vhostfdname) {
52
vhostfd = monitor_fd_param(cur_mon, vhostfdname, &err);
53
if (vhostfd == -1) {
54
- error_propagate(errp, err);
55
+ if (tap->has_vhostforce && tap->vhostforce) {
56
+ error_propagate(errp, err);
57
+ } else {
58
+ warn_report_err(err);
59
+ }
60
return;
61
}
62
} else {
63
vhostfd = open("/dev/vhost-net", O_RDWR);
64
if (vhostfd < 0) {
65
- error_setg_errno(errp, errno,
66
- "tap: open vhost char device failed");
67
+ if (tap->has_vhostforce && tap->vhostforce) {
68
+ error_setg_errno(errp, errno,
69
+ "tap: open vhost char device failed");
70
+ } else {
71
+ warn_report("tap: open vhost char device failed: %s",
72
+ strerror(errno));
73
+ }
74
return;
75
}
76
fcntl(vhostfd, F_SETFL, O_NONBLOCK);
77
@@ -XXX,XX +XXX,XX @@ static void net_init_tap_one(const NetdevTapOptions *tap, NetClientState *peer,
78
79
s->vhost_net = vhost_net_init(&options);
80
if (!s->vhost_net) {
81
- error_setg(errp,
82
- "vhost-net requested but could not be initialized");
83
+ if (tap->has_vhostforce && tap->vhostforce) {
84
+ error_setg(errp, VHOST_NET_INIT_FAILED);
85
+ } else {
86
+ warn_report(VHOST_NET_INIT_FAILED);
87
+ }
88
return;
89
}
90
} else if (vhostfdname) {
91
--
92
2.7.4
93
94
diff view generated by jsdifflib