1
The following changes since commit 5dae13cd71f0755a1395b5a4cde635b8a6ee3f58:
1
The following changes since commit eec398119fc6911d99412c37af06a6bc27871f85:
2
2
3
Merge remote-tracking branch 'remotes/rth/tags/pull-or-20170214' into staging (2017-02-14 09:55:48 +0000)
3
Merge tag 'for_upstream' of git://git.kernel.org/pub/scm/virt/kvm/mst/qemu into staging (2022-05-16 16:31:01 -0700)
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 4154c7e03fa55b4cf52509a83d50d6c09d743b77:
9
for you to fetch changes up to 052c2579b89b0d87debe8b05594b5180f0fde87d:
10
10
11
net: e1000e: fix an infinite loop issue (2017-02-15 11:18:57 +0800)
11
tulip: Assign default MAC address if not specified (2022-05-17 16:48:23 +0800)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
14
15
----------------------------------------------------------------
15
----------------------------------------------------------------
16
Li Qiang (1):
16
Helge Deller (1):
17
net: e1000e: fix an infinite loop issue
17
tulip: Assign default MAC address if not specified
18
18
19
Paolo Bonzini (1):
19
Vladislav Yaroshchuk (7):
20
net: e1000e: fix dead code in e1000e_write_packet_to_guest
20
net/vmnet: add vmnet dependency and customizable option
21
net/vmnet: add vmnet backends to qapi/net
22
net/vmnet: implement shared mode (vmnet-shared)
23
net/vmnet: implement host mode (vmnet-host)
24
net/vmnet: implement bridged mode (vmnet-bridged)
25
net/vmnet: update qemu-options.hx
26
net/vmnet: update hmp-commands.hx
21
27
22
Prasad J Pandit (1):
28
hmp-commands.hx | 6 +-
23
net: imx: limit buffer descriptor count
29
hw/net/tulip.c | 4 +-
24
30
meson.build | 16 +-
25
Thomas Huth (1):
31
meson_options.txt | 2 +
26
net: Mark 'vlan' parameter as deprecated
32
net/clients.h | 11 ++
27
33
net/meson.build | 7 +
28
Zhang Chen (1):
34
net/net.c | 10 ++
29
colo-compare: sort TCP packet queue by sequence number
35
net/vmnet-bridged.m | 152 +++++++++++++++++
30
36
net/vmnet-common.m | 378 ++++++++++++++++++++++++++++++++++++++++++
31
hw/net/e1000e_core.c | 9 +++++++--
37
net/vmnet-host.c | 128 ++++++++++++++
32
hw/net/imx_fec.c | 10 ++++++----
38
net/vmnet-shared.c | 114 +++++++++++++
33
net/colo-compare.c | 19 +++++++++++++++++++
39
net/vmnet_int.h | 63 +++++++
34
net/net.c | 6 ++++++
40
qapi/net.json | 133 ++++++++++++++-
35
4 files changed, 38 insertions(+), 6 deletions(-)
41
qemu-options.hx | 25 +++
36
42
scripts/meson-buildoptions.sh | 1 +
37
43
15 files changed, 1044 insertions(+), 6 deletions(-)
44
create mode 100644 net/vmnet-bridged.m
45
create mode 100644 net/vmnet-common.m
46
create mode 100644 net/vmnet-host.c
47
create mode 100644 net/vmnet-shared.c
48
create mode 100644 net/vmnet_int.h
diff view generated by jsdifflib
New patch
1
From: Vladislav Yaroshchuk <vladislav.yaroshchuk@jetbrains.com>
1
2
3
vmnet.framework dependency is added with 'vmnet' option
4
to enable or disable it. Default value is 'auto'.
5
6
used vmnet features are available since macOS 11.0,
7
but new backend can be built and work properly with
8
subset of them on 10.15 too.
9
10
Reviewed-by: Akihiko Odaki <akihiko.odaki@gmail.com>
11
Tested-by: Akihiko Odaki <akihiko.odaki@gmail.com>
12
Signed-off-by: Vladislav Yaroshchuk <Vladislav.Yaroshchuk@jetbrains.com>
13
Signed-off-by: Jason Wang <jasowang@redhat.com>
14
---
15
meson.build | 16 +++++++++++++++-
16
meson_options.txt | 2 ++
17
scripts/meson-buildoptions.sh | 1 +
18
3 files changed, 18 insertions(+), 1 deletion(-)
19
20
diff --git a/meson.build b/meson.build
21
index XXXXXXX..XXXXXXX 100644
22
--- a/meson.build
23
+++ b/meson.build
24
@@ -XXX,XX +XXX,XX @@ if cocoa.found() and get_option('gtk').enabled()
25
error('Cocoa and GTK+ cannot be enabled at the same time')
26
endif
27
28
+vmnet = dependency('appleframeworks', modules: 'vmnet', required: get_option('vmnet'))
29
+if vmnet.found() and not cc.has_header_symbol('vmnet/vmnet.h',
30
+ 'VMNET_BRIDGED_MODE',
31
+ dependencies: vmnet)
32
+ vmnet = not_found
33
+ if get_option('vmnet').enabled()
34
+ error('vmnet.framework API is outdated')
35
+ else
36
+ warning('vmnet.framework API is outdated, disabling')
37
+ endif
38
+endif
39
+
40
seccomp = not_found
41
if not get_option('seccomp').auto() or have_system or have_tools
42
seccomp = dependency('libseccomp', version: '>=2.3.0',
43
@@ -XXX,XX +XXX,XX @@ config_host_data.set('CONFIG_VHOST_KERNEL', have_vhost_kernel)
44
config_host_data.set('CONFIG_VHOST_USER', have_vhost_user)
45
config_host_data.set('CONFIG_VHOST_CRYPTO', have_vhost_user_crypto)
46
config_host_data.set('CONFIG_VHOST_VDPA', have_vhost_vdpa)
47
+config_host_data.set('CONFIG_VMNET', vmnet.found())
48
config_host_data.set('CONFIG_VHOST_USER_BLK_SERVER', have_vhost_user_blk_server)
49
config_host_data.set('CONFIG_PNG', png.found())
50
config_host_data.set('CONFIG_VNC', vnc.found())
51
@@ -XXX,XX +XXX,XX @@ summary(summary_info, bool_yn: true, section: 'Crypto')
52
# Libraries
53
summary_info = {}
54
if targetos == 'darwin'
55
- summary_info += {'Cocoa support': cocoa}
56
+ summary_info += {'Cocoa support': cocoa}
57
+ summary_info += {'vmnet.framework support': vmnet}
58
endif
59
summary_info += {'SDL support': sdl}
60
summary_info += {'SDL image support': sdl_image}
61
diff --git a/meson_options.txt b/meson_options.txt
62
index XXXXXXX..XXXXXXX 100644
63
--- a/meson_options.txt
64
+++ b/meson_options.txt
65
@@ -XXX,XX +XXX,XX @@ option('netmap', type : 'feature', value : 'auto',
66
description: 'netmap network backend support')
67
option('vde', type : 'feature', value : 'auto',
68
description: 'vde network backend support')
69
+option('vmnet', type : 'feature', value : 'auto',
70
+ description: 'vmnet.framework network backend support')
71
option('virglrenderer', type : 'feature', value : 'auto',
72
description: 'virgl rendering support')
73
option('png', type : 'feature', value : 'auto',
74
diff --git a/scripts/meson-buildoptions.sh b/scripts/meson-buildoptions.sh
75
index XXXXXXX..XXXXXXX 100644
76
--- a/scripts/meson-buildoptions.sh
77
+++ b/scripts/meson-buildoptions.sh
78
@@ -XXX,XX +XXX,XX @@ meson_options_help() {
79
printf "%s\n" ' vhost-kernel vhost kernel backend support'
80
printf "%s\n" ' vhost-net vhost-net kernel acceleration support'
81
printf "%s\n" ' vhost-user vhost-user backend support'
82
+ printf "%s\n" ' vmnet vmnet.framework network backend support'
83
printf "%s\n" ' vhost-user-blk-server'
84
printf "%s\n" ' build vhost-user-blk server'
85
printf "%s\n" ' vhost-vdpa vhost-vdpa kernel backend support'
86
--
87
2.25.1
diff view generated by jsdifflib
1
From: Thomas Huth <thuth@redhat.com>
1
From: Vladislav Yaroshchuk <vladislav.yaroshchuk@jetbrains.com>
2
2
3
The 'vlan' parameter is a continuous source of confusion for the users,
3
Create separate netdevs for each vmnet operating mode:
4
many people mix it up with the more common term VLAN (the link layer
4
- vmnet-host
5
packet encapsulation), and even if they realize that the QEMU 'vlan' is
5
- vmnet-shared
6
rather some kind of network hub emulation, there is still a high risk
6
- vmnet-bridged
7
that they configure their QEMU networking in a wrong way with this
8
parameter (e.g. by hooking NICs together, so they get a 'loopback'
9
between one and the other NIC).
10
Thus at one point in time, we should finally get rid of the 'vlan'
11
feature in QEMU. Let's do a first step in this direction by declaring
12
the 'vlan' parameter as deprecated and informing the users to use the
13
'netdev' parameter instead.
14
7
15
Signed-off-by: Thomas Huth <thuth@redhat.com>
8
Reviewed-by: Akihiko Odaki <akihiko.odaki@gmail.com>
9
Tested-by: Akihiko Odaki <akihiko.odaki@gmail.com>
10
Acked-by: Markus Armbruster <armbru@redhat.com>
11
Signed-off-by: Vladislav Yaroshchuk <Vladislav.Yaroshchuk@jetbrains.com>
16
Signed-off-by: Jason Wang <jasowang@redhat.com>
12
Signed-off-by: Jason Wang <jasowang@redhat.com>
17
---
13
---
18
net/net.c | 6 ++++++
14
net/clients.h | 11 ++++
19
1 file changed, 6 insertions(+)
15
net/meson.build | 7 +++
16
net/net.c | 10 ++++
17
net/vmnet-bridged.m | 25 +++++++++
18
net/vmnet-common.m | 19 +++++++
19
net/vmnet-host.c | 24 ++++++++
20
net/vmnet-shared.c | 25 +++++++++
21
net/vmnet_int.h | 25 +++++++++
22
qapi/net.json | 133 +++++++++++++++++++++++++++++++++++++++++++-
23
9 files changed, 277 insertions(+), 2 deletions(-)
24
create mode 100644 net/vmnet-bridged.m
25
create mode 100644 net/vmnet-common.m
26
create mode 100644 net/vmnet-host.c
27
create mode 100644 net/vmnet-shared.c
28
create mode 100644 net/vmnet_int.h
20
29
30
diff --git a/net/clients.h b/net/clients.h
31
index XXXXXXX..XXXXXXX 100644
32
--- a/net/clients.h
33
+++ b/net/clients.h
34
@@ -XXX,XX +XXX,XX @@ int net_init_vhost_user(const Netdev *netdev, const char *name,
35
36
int net_init_vhost_vdpa(const Netdev *netdev, const char *name,
37
NetClientState *peer, Error **errp);
38
+#ifdef CONFIG_VMNET
39
+int net_init_vmnet_host(const Netdev *netdev, const char *name,
40
+ NetClientState *peer, Error **errp);
41
+
42
+int net_init_vmnet_shared(const Netdev *netdev, const char *name,
43
+ NetClientState *peer, Error **errp);
44
+
45
+int net_init_vmnet_bridged(const Netdev *netdev, const char *name,
46
+ NetClientState *peer, Error **errp);
47
+#endif /* CONFIG_VMNET */
48
+
49
#endif /* QEMU_NET_CLIENTS_H */
50
diff --git a/net/meson.build b/net/meson.build
51
index XXXXXXX..XXXXXXX 100644
52
--- a/net/meson.build
53
+++ b/net/meson.build
54
@@ -XXX,XX +XXX,XX @@ if have_vhost_net_vdpa
55
softmmu_ss.add(files('vhost-vdpa.c'))
56
endif
57
58
+vmnet_files = files(
59
+ 'vmnet-common.m',
60
+ 'vmnet-bridged.m',
61
+ 'vmnet-host.c',
62
+ 'vmnet-shared.c'
63
+)
64
+softmmu_ss.add(when: vmnet, if_true: vmnet_files)
65
subdir('can')
21
diff --git a/net/net.c b/net/net.c
66
diff --git a/net/net.c b/net/net.c
22
index XXXXXXX..XXXXXXX 100644
67
index XXXXXXX..XXXXXXX 100644
23
--- a/net/net.c
68
--- a/net/net.c
24
+++ b/net/net.c
69
+++ b/net/net.c
25
@@ -XXX,XX +XXX,XX @@ static int net_client_init1(const void *object, bool is_netdev, Error **errp)
70
@@ -XXX,XX +XXX,XX @@ static int (* const net_client_init_fun[NET_CLIENT_DRIVER__MAX])(
26
const Netdev *netdev;
71
#ifdef CONFIG_L2TPV3
27
const char *name;
72
[NET_CLIENT_DRIVER_L2TPV3] = net_init_l2tpv3,
28
NetClientState *peer = NULL;
73
#endif
29
+ static bool vlan_warned;
74
+#ifdef CONFIG_VMNET
30
75
+ [NET_CLIENT_DRIVER_VMNET_HOST] = net_init_vmnet_host,
31
if (is_netdev) {
76
+ [NET_CLIENT_DRIVER_VMNET_SHARED] = net_init_vmnet_shared,
32
netdev = object;
77
+ [NET_CLIENT_DRIVER_VMNET_BRIDGED] = net_init_vmnet_bridged,
33
@@ -XXX,XX +XXX,XX @@ static int net_client_init1(const void *object, bool is_netdev, Error **errp)
78
+#endif /* CONFIG_VMNET */
34
!opts->u.nic.data->has_netdev) {
79
};
35
peer = net_hub_add_port(net->has_vlan ? net->vlan : 0, NULL);
80
36
}
81
37
+
82
@@ -XXX,XX +XXX,XX @@ void show_netdevs(void)
38
+ if (net->has_vlan && !vlan_warned) {
83
#endif
39
+ error_report("'vlan' is deprecated. Please use 'netdev' instead.");
84
#ifdef CONFIG_VHOST_VDPA
40
+ vlan_warned = true;
85
"vhost-vdpa",
41
+ }
86
+#endif
42
}
87
+#ifdef CONFIG_VMNET
43
88
+ "vmnet-host",
44
if (net_client_init_fun[netdev->type](netdev, name, peer, errp) < 0) {
89
+ "vmnet-shared",
90
+ "vmnet-bridged",
91
#endif
92
};
93
94
diff --git a/net/vmnet-bridged.m b/net/vmnet-bridged.m
95
new file mode 100644
96
index XXXXXXX..XXXXXXX
97
--- /dev/null
98
+++ b/net/vmnet-bridged.m
99
@@ -XXX,XX +XXX,XX @@
100
+/*
101
+ * vmnet-bridged.m
102
+ *
103
+ * Copyright(c) 2022 Vladislav Yaroshchuk <vladislav.yaroshchuk@jetbrains.com>
104
+ *
105
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
106
+ * See the COPYING file in the top-level directory.
107
+ *
108
+ */
109
+
110
+#include "qemu/osdep.h"
111
+#include "qapi/qapi-types-net.h"
112
+#include "vmnet_int.h"
113
+#include "clients.h"
114
+#include "qemu/error-report.h"
115
+#include "qapi/error.h"
116
+
117
+#include <vmnet/vmnet.h>
118
+
119
+int net_init_vmnet_bridged(const Netdev *netdev, const char *name,
120
+ NetClientState *peer, Error **errp)
121
+{
122
+ error_setg(errp, "vmnet-bridged is not implemented yet");
123
+ return -1;
124
+}
125
diff --git a/net/vmnet-common.m b/net/vmnet-common.m
126
new file mode 100644
127
index XXXXXXX..XXXXXXX
128
--- /dev/null
129
+++ b/net/vmnet-common.m
130
@@ -XXX,XX +XXX,XX @@
131
+/*
132
+ * vmnet-common.m - network client wrapper for Apple vmnet.framework
133
+ *
134
+ * Copyright(c) 2022 Vladislav Yaroshchuk <vladislav.yaroshchuk@jetbrains.com>
135
+ * Copyright(c) 2021 Phillip Tennen <phillip@axleos.com>
136
+ *
137
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
138
+ * See the COPYING file in the top-level directory.
139
+ *
140
+ */
141
+
142
+#include "qemu/osdep.h"
143
+#include "qapi/qapi-types-net.h"
144
+#include "vmnet_int.h"
145
+#include "clients.h"
146
+#include "qemu/error-report.h"
147
+#include "qapi/error.h"
148
+
149
+#include <vmnet/vmnet.h>
150
diff --git a/net/vmnet-host.c b/net/vmnet-host.c
151
new file mode 100644
152
index XXXXXXX..XXXXXXX
153
--- /dev/null
154
+++ b/net/vmnet-host.c
155
@@ -XXX,XX +XXX,XX @@
156
+/*
157
+ * vmnet-host.c
158
+ *
159
+ * Copyright(c) 2022 Vladislav Yaroshchuk <vladislav.yaroshchuk@jetbrains.com>
160
+ *
161
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
162
+ * See the COPYING file in the top-level directory.
163
+ *
164
+ */
165
+
166
+#include "qemu/osdep.h"
167
+#include "qapi/qapi-types-net.h"
168
+#include "vmnet_int.h"
169
+#include "clients.h"
170
+#include "qemu/error-report.h"
171
+#include "qapi/error.h"
172
+
173
+#include <vmnet/vmnet.h>
174
+
175
+int net_init_vmnet_host(const Netdev *netdev, const char *name,
176
+ NetClientState *peer, Error **errp) {
177
+ error_setg(errp, "vmnet-host is not implemented yet");
178
+ return -1;
179
+}
180
diff --git a/net/vmnet-shared.c b/net/vmnet-shared.c
181
new file mode 100644
182
index XXXXXXX..XXXXXXX
183
--- /dev/null
184
+++ b/net/vmnet-shared.c
185
@@ -XXX,XX +XXX,XX @@
186
+/*
187
+ * vmnet-shared.c
188
+ *
189
+ * Copyright(c) 2022 Vladislav Yaroshchuk <vladislav.yaroshchuk@jetbrains.com>
190
+ *
191
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
192
+ * See the COPYING file in the top-level directory.
193
+ *
194
+ */
195
+
196
+#include "qemu/osdep.h"
197
+#include "qapi/qapi-types-net.h"
198
+#include "vmnet_int.h"
199
+#include "clients.h"
200
+#include "qemu/error-report.h"
201
+#include "qapi/error.h"
202
+
203
+#include <vmnet/vmnet.h>
204
+
205
+int net_init_vmnet_shared(const Netdev *netdev, const char *name,
206
+ NetClientState *peer, Error **errp)
207
+{
208
+ error_setg(errp, "vmnet-shared is not implemented yet");
209
+ return -1;
210
+}
211
diff --git a/net/vmnet_int.h b/net/vmnet_int.h
212
new file mode 100644
213
index XXXXXXX..XXXXXXX
214
--- /dev/null
215
+++ b/net/vmnet_int.h
216
@@ -XXX,XX +XXX,XX @@
217
+/*
218
+ * vmnet_int.h
219
+ *
220
+ * Copyright(c) 2022 Vladislav Yaroshchuk <vladislav.yaroshchuk@jetbrains.com>
221
+ *
222
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
223
+ * See the COPYING file in the top-level directory.
224
+ *
225
+ */
226
+#ifndef VMNET_INT_H
227
+#define VMNET_INT_H
228
+
229
+#include "qemu/osdep.h"
230
+#include "vmnet_int.h"
231
+#include "clients.h"
232
+
233
+#include <vmnet/vmnet.h>
234
+
235
+typedef struct VmnetState {
236
+ NetClientState nc;
237
+
238
+} VmnetState;
239
+
240
+
241
+#endif /* VMNET_INT_H */
242
diff --git a/qapi/net.json b/qapi/net.json
243
index XXXXXXX..XXXXXXX 100644
244
--- a/qapi/net.json
245
+++ b/qapi/net.json
246
@@ -XXX,XX +XXX,XX @@
247
'*vhostdev': 'str',
248
'*queues': 'int' } }
249
250
+##
251
+# @NetdevVmnetHostOptions:
252
+#
253
+# vmnet (host mode) network backend.
254
+#
255
+# Allows the vmnet interface to communicate with other vmnet
256
+# interfaces that are in host mode and also with the host.
257
+#
258
+# @start-address: The starting IPv4 address to use for the interface.
259
+# Must be in the private IP range (RFC 1918). Must be
260
+# specified along with @end-address and @subnet-mask.
261
+# This address is used as the gateway address. The
262
+# subsequent address up to and including end-address are
263
+# placed in the DHCP pool.
264
+#
265
+# @end-address: The DHCP IPv4 range end address to use for the
266
+# interface. Must be in the private IP range (RFC 1918).
267
+# Must be specified along with @start-address and
268
+# @subnet-mask.
269
+#
270
+# @subnet-mask: The IPv4 subnet mask to use on the interface. Must
271
+# be specified along with @start-address and @subnet-mask.
272
+#
273
+# @isolated: Enable isolation for this interface. Interface isolation
274
+# ensures that vmnet interface is not able to communicate
275
+# with any other vmnet interfaces. Only communication with
276
+# host is allowed. Requires at least macOS Big Sur 11.0.
277
+#
278
+# @net-uuid: The identifier (UUID) to uniquely identify the isolated
279
+# network vmnet interface should be added to. If
280
+# set, no DHCP service is provided for this interface and
281
+# network communication is allowed only with other interfaces
282
+# added to this network identified by the UUID. Requires
283
+# at least macOS Big Sur 11.0.
284
+#
285
+# Since: 7.1
286
+##
287
+{ 'struct': 'NetdevVmnetHostOptions',
288
+ 'data': {
289
+ '*start-address': 'str',
290
+ '*end-address': 'str',
291
+ '*subnet-mask': 'str',
292
+ '*isolated': 'bool',
293
+ '*net-uuid': 'str' },
294
+ 'if': 'CONFIG_VMNET' }
295
+
296
+##
297
+# @NetdevVmnetSharedOptions:
298
+#
299
+# vmnet (shared mode) network backend.
300
+#
301
+# Allows traffic originating from the vmnet interface to reach the
302
+# Internet through a network address translator (NAT).
303
+# The vmnet interface can communicate with the host and with
304
+# other shared mode interfaces on the same subnet. If no DHCP
305
+# settings, subnet mask and IPv6 prefix specified, the interface can
306
+# communicate with any of other interfaces in shared mode.
307
+#
308
+# @start-address: The starting IPv4 address to use for the interface.
309
+# Must be in the private IP range (RFC 1918). Must be
310
+# specified along with @end-address and @subnet-mask.
311
+# This address is used as the gateway address. The
312
+# subsequent address up to and including end-address are
313
+# placed in the DHCP pool.
314
+#
315
+# @end-address: The DHCP IPv4 range end address to use for the
316
+# interface. Must be in the private IP range (RFC 1918).
317
+# Must be specified along with @start-address and @subnet-mask.
318
+#
319
+# @subnet-mask: The IPv4 subnet mask to use on the interface. Must
320
+# be specified along with @start-address and @subnet-mask.
321
+#
322
+# @isolated: Enable isolation for this interface. Interface isolation
323
+# ensures that vmnet interface is not able to communicate
324
+# with any other vmnet interfaces. Only communication with
325
+# host is allowed. Requires at least macOS Big Sur 11.0.
326
+#
327
+# @nat66-prefix: The IPv6 prefix to use into guest network. Must be a
328
+# unique local address i.e. start with fd00::/8 and have
329
+# length of 64.
330
+#
331
+# Since: 7.1
332
+##
333
+{ 'struct': 'NetdevVmnetSharedOptions',
334
+ 'data': {
335
+ '*start-address': 'str',
336
+ '*end-address': 'str',
337
+ '*subnet-mask': 'str',
338
+ '*isolated': 'bool',
339
+ '*nat66-prefix': 'str' },
340
+ 'if': 'CONFIG_VMNET' }
341
+
342
+##
343
+# @NetdevVmnetBridgedOptions:
344
+#
345
+# vmnet (bridged mode) network backend.
346
+#
347
+# Bridges the vmnet interface with a physical network interface.
348
+#
349
+# @ifname: The name of the physical interface to be bridged.
350
+#
351
+# @isolated: Enable isolation for this interface. Interface isolation
352
+# ensures that vmnet interface is not able to communicate
353
+# with any other vmnet interfaces. Only communication with
354
+# host is allowed. Requires at least macOS Big Sur 11.0.
355
+#
356
+# Since: 7.1
357
+##
358
+{ 'struct': 'NetdevVmnetBridgedOptions',
359
+ 'data': {
360
+ 'ifname': 'str',
361
+ '*isolated': 'bool' },
362
+ 'if': 'CONFIG_VMNET' }
363
+
364
##
365
# @NetClientDriver:
366
#
367
@@ -XXX,XX +XXX,XX @@
368
# Since: 2.7
369
#
370
# @vhost-vdpa since 5.1
371
+# @vmnet-host since 7.1
372
+# @vmnet-shared since 7.1
373
+# @vmnet-bridged since 7.1
374
##
375
{ 'enum': 'NetClientDriver',
376
'data': [ 'none', 'nic', 'user', 'tap', 'l2tpv3', 'socket', 'vde',
377
- 'bridge', 'hubport', 'netmap', 'vhost-user', 'vhost-vdpa' ] }
378
+ 'bridge', 'hubport', 'netmap', 'vhost-user', 'vhost-vdpa',
379
+ { 'name': 'vmnet-host', 'if': 'CONFIG_VMNET' },
380
+ { 'name': 'vmnet-shared', 'if': 'CONFIG_VMNET' },
381
+ { 'name': 'vmnet-bridged', 'if': 'CONFIG_VMNET' }] }
382
383
##
384
# @Netdev:
385
@@ -XXX,XX +XXX,XX @@
386
# Since: 1.2
387
#
388
# 'l2tpv3' - since 2.1
389
+# 'vmnet-host' - since 7.1
390
+# 'vmnet-shared' - since 7.1
391
+# 'vmnet-bridged' - since 7.1
392
##
393
{ 'union': 'Netdev',
394
'base': { 'id': 'str', 'type': 'NetClientDriver' },
395
@@ -XXX,XX +XXX,XX @@
396
'hubport': 'NetdevHubPortOptions',
397
'netmap': 'NetdevNetmapOptions',
398
'vhost-user': 'NetdevVhostUserOptions',
399
- 'vhost-vdpa': 'NetdevVhostVDPAOptions' } }
400
+ 'vhost-vdpa': 'NetdevVhostVDPAOptions',
401
+ 'vmnet-host': { 'type': 'NetdevVmnetHostOptions',
402
+ 'if': 'CONFIG_VMNET' },
403
+ 'vmnet-shared': { 'type': 'NetdevVmnetSharedOptions',
404
+ 'if': 'CONFIG_VMNET' },
405
+ 'vmnet-bridged': { 'type': 'NetdevVmnetBridgedOptions',
406
+ 'if': 'CONFIG_VMNET' } } }
407
408
##
409
# @RxState:
45
--
410
--
46
2.7.4
411
2.25.1
47
48
diff view generated by jsdifflib
1
From: Li Qiang <liq3ea@gmail.com>
1
From: Vladislav Yaroshchuk <vladislav.yaroshchuk@jetbrains.com>
2
2
3
This issue is like the issue in e1000 network card addressed in
3
Interaction with vmnet.framework in different modes
4
this commit:
4
differs only on configuration stage, so we can create
5
e1000: eliminate infinite loops on out-of-bounds transfer start.
5
common `send`, `receive`, etc. procedures and reuse them.
6
6
7
Signed-off-by: Li Qiang <liqiang6-s@360.cn>
7
Reviewed-by: Akihiko Odaki <akihiko.odaki@gmail.com>
8
Reviewed-by: Dmitry Fleytman <dmitry@daynix.com>
8
Tested-by: Akihiko Odaki <akihiko.odaki@gmail.com>
9
Signed-off-by: Phillip Tennen <phillip@axleos.com>
10
Signed-off-by: Vladislav Yaroshchuk <Vladislav.Yaroshchuk@jetbrains.com>
9
Signed-off-by: Jason Wang <jasowang@redhat.com>
11
Signed-off-by: Jason Wang <jasowang@redhat.com>
10
---
12
---
11
hw/net/e1000e_core.c | 7 ++++++-
13
net/vmnet-common.m | 359 +++++++++++++++++++++++++++++++++++++++++++++
12
1 file changed, 6 insertions(+), 1 deletion(-)
14
net/vmnet-shared.c | 97 +++++++++++-
15
net/vmnet_int.h | 40 ++++-
16
3 files changed, 491 insertions(+), 5 deletions(-)
13
17
14
diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c
18
diff --git a/net/vmnet-common.m b/net/vmnet-common.m
15
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/net/e1000e_core.c
20
--- a/net/vmnet-common.m
17
+++ b/hw/net/e1000e_core.c
21
+++ b/net/vmnet-common.m
18
@@ -XXX,XX +XXX,XX @@ typedef struct E1000E_RingInfo_st {
22
@@ -XXX,XX +XXX,XX @@
19
static inline bool
23
*/
20
e1000e_ring_empty(E1000ECore *core, const E1000E_RingInfo *r)
24
21
{
25
#include "qemu/osdep.h"
22
- return core->mac[r->dh] == core->mac[r->dt];
26
+#include "qemu/main-loop.h"
23
+ return core->mac[r->dh] == core->mac[r->dt] ||
27
+#include "qemu/log.h"
24
+ core->mac[r->dt] >= core->mac[r->dlen] / E1000_RING_DESC_LEN;
28
#include "qapi/qapi-types-net.h"
25
}
29
#include "vmnet_int.h"
26
30
#include "clients.h"
27
static inline uint64_t
31
@@ -XXX,XX +XXX,XX @@
28
@@ -XXX,XX +XXX,XX @@ e1000e_write_packet_to_guest(E1000ECore *core, struct NetRxPkt *pkt,
32
#include "qapi/error.h"
29
desc_size = core->rx_desc_buf_size;
33
30
}
34
#include <vmnet/vmnet.h>
31
35
+#include <dispatch/dispatch.h>
32
+ if (e1000e_ring_empty(core, rxi)) {
36
+
37
+
38
+static void vmnet_send_completed(NetClientState *nc, ssize_t len);
39
+
40
+
41
+const char *vmnet_status_map_str(vmnet_return_t status)
42
+{
43
+ switch (status) {
44
+ case VMNET_SUCCESS:
45
+ return "success";
46
+ case VMNET_FAILURE:
47
+ return "general failure (possibly not enough privileges)";
48
+ case VMNET_MEM_FAILURE:
49
+ return "memory allocation failure";
50
+ case VMNET_INVALID_ARGUMENT:
51
+ return "invalid argument specified";
52
+ case VMNET_SETUP_INCOMPLETE:
53
+ return "interface setup is not complete";
54
+ case VMNET_INVALID_ACCESS:
55
+ return "invalid access, permission denied";
56
+ case VMNET_PACKET_TOO_BIG:
57
+ return "packet size is larger than MTU";
58
+ case VMNET_BUFFER_EXHAUSTED:
59
+ return "buffers exhausted in kernel";
60
+ case VMNET_TOO_MANY_PACKETS:
61
+ return "packet count exceeds limit";
62
+#if defined(MAC_OS_VERSION_11_0) && \
63
+ MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_VERSION_11_0
64
+ case VMNET_SHARING_SERVICE_BUSY:
65
+ return "conflict, sharing service is in use";
66
+#endif
67
+ default:
68
+ return "unknown vmnet error";
69
+ }
70
+}
71
+
72
+
73
+/**
74
+ * Write packets from QEMU to vmnet interface.
75
+ *
76
+ * vmnet.framework supports iov, but writing more than
77
+ * one iov into vmnet interface fails with
78
+ * 'VMNET_INVALID_ARGUMENT'. Collecting provided iovs into
79
+ * one and passing it to vmnet works fine. That's the
80
+ * reason why receive_iov() left unimplemented. But it still
81
+ * works with good performance having .receive() only.
82
+ */
83
+ssize_t vmnet_receive_common(NetClientState *nc,
84
+ const uint8_t *buf,
85
+ size_t size)
86
+{
87
+ VmnetState *s = DO_UPCAST(VmnetState, nc, nc);
88
+ struct vmpktdesc packet;
89
+ struct iovec iov;
90
+ int pkt_cnt;
91
+ vmnet_return_t if_status;
92
+
93
+ if (size > s->max_packet_size) {
94
+ warn_report("vmnet: packet is too big, %zu > %" PRIu64,
95
+ packet.vm_pkt_size,
96
+ s->max_packet_size);
97
+ return -1;
98
+ }
99
+
100
+ iov.iov_base = (char *) buf;
101
+ iov.iov_len = size;
102
+
103
+ packet.vm_pkt_iovcnt = 1;
104
+ packet.vm_flags = 0;
105
+ packet.vm_pkt_size = size;
106
+ packet.vm_pkt_iov = &iov;
107
+ pkt_cnt = 1;
108
+
109
+ if_status = vmnet_write(s->vmnet_if, &packet, &pkt_cnt);
110
+ if (if_status != VMNET_SUCCESS) {
111
+ error_report("vmnet: write error: %s\n",
112
+ vmnet_status_map_str(if_status));
113
+ return -1;
114
+ }
115
+
116
+ if (pkt_cnt) {
117
+ return size;
118
+ }
119
+ return 0;
120
+}
121
+
122
+
123
+/**
124
+ * Read packets from vmnet interface and write them
125
+ * to temporary buffers in VmnetState.
126
+ *
127
+ * Returns read packets number (may be 0) on success,
128
+ * -1 on error
129
+ */
130
+static int vmnet_read_packets(VmnetState *s)
131
+{
132
+ assert(s->packets_send_current_pos == s->packets_send_end_pos);
133
+
134
+ struct vmpktdesc *packets = s->packets_buf;
135
+ vmnet_return_t status;
136
+ int i;
137
+
138
+ /* Read as many packets as present */
139
+ s->packets_send_current_pos = 0;
140
+ s->packets_send_end_pos = VMNET_PACKETS_LIMIT;
141
+ for (i = 0; i < s->packets_send_end_pos; ++i) {
142
+ packets[i].vm_pkt_size = s->max_packet_size;
143
+ packets[i].vm_pkt_iovcnt = 1;
144
+ packets[i].vm_flags = 0;
145
+ }
146
+
147
+ status = vmnet_read(s->vmnet_if, packets, &s->packets_send_end_pos);
148
+ if (status != VMNET_SUCCESS) {
149
+ error_printf("vmnet: read failed: %s\n",
150
+ vmnet_status_map_str(status));
151
+ s->packets_send_current_pos = 0;
152
+ s->packets_send_end_pos = 0;
153
+ return -1;
154
+ }
155
+ return s->packets_send_end_pos;
156
+}
157
+
158
+
159
+/**
160
+ * Write packets from temporary buffers in VmnetState
161
+ * to QEMU.
162
+ */
163
+static void vmnet_write_packets_to_qemu(VmnetState *s)
164
+{
165
+ while (s->packets_send_current_pos < s->packets_send_end_pos) {
166
+ ssize_t size = qemu_send_packet_async(&s->nc,
167
+ s->iov_buf[s->packets_send_current_pos].iov_base,
168
+ s->packets_buf[s->packets_send_current_pos].vm_pkt_size,
169
+ vmnet_send_completed);
170
+
171
+ if (size == 0) {
172
+ /* QEMU is not ready to consume more packets -
173
+ * stop and wait for completion callback call */
33
+ return;
174
+ return;
34
+ }
175
+ }
35
+
176
+ ++s->packets_send_current_pos;
36
base = e1000e_ring_head_descr(core, rxi);
177
+ }
37
178
+}
38
pci_dma_read(d, base, &desc, core->rx_desc_len);
179
+
180
+
181
+/**
182
+ * Bottom half callback that transfers packets from vmnet interface
183
+ * to QEMU.
184
+ *
185
+ * The process of transferring packets is three-staged:
186
+ * 1. Handle vmnet event;
187
+ * 2. Read packets from vmnet interface into temporary buffer;
188
+ * 3. Write packets from temporary buffer to QEMU.
189
+ *
190
+ * QEMU may suspend this process on the last stage, returning 0 from
191
+ * qemu_send_packet_async function. If this happens, we should
192
+ * respectfully wait until it is ready to consume more packets,
193
+ * write left ones in temporary buffer and only after this
194
+ * continue reading more packets from vmnet interface.
195
+ *
196
+ * Packets to be transferred are stored into packets_buf,
197
+ * in the window [packets_send_current_pos..packets_send_end_pos)
198
+ * including current_pos, excluding end_pos.
199
+ *
200
+ * Thus, if QEMU is not ready, buffer is not read and
201
+ * packets_send_current_pos < packets_send_end_pos.
202
+ */
203
+static void vmnet_send_bh(void *opaque)
204
+{
205
+ NetClientState *nc = (NetClientState *) opaque;
206
+ VmnetState *s = DO_UPCAST(VmnetState, nc, nc);
207
+
208
+ /*
209
+ * Do nothing if QEMU is not ready - wait
210
+ * for completion callback invocation
211
+ */
212
+ if (s->packets_send_current_pos < s->packets_send_end_pos) {
213
+ return;
214
+ }
215
+
216
+ /* Read packets from vmnet interface */
217
+ if (vmnet_read_packets(s) > 0) {
218
+ /* Send them to QEMU */
219
+ vmnet_write_packets_to_qemu(s);
220
+ }
221
+}
222
+
223
+
224
+/**
225
+ * Completion callback to be invoked by QEMU when it becomes
226
+ * ready to consume more packets.
227
+ */
228
+static void vmnet_send_completed(NetClientState *nc, ssize_t len)
229
+{
230
+ VmnetState *s = DO_UPCAST(VmnetState, nc, nc);
231
+
232
+ /* Callback is invoked eq queued packet is sent */
233
+ ++s->packets_send_current_pos;
234
+
235
+ /* Complete sending packets left in VmnetState buffers */
236
+ vmnet_write_packets_to_qemu(s);
237
+
238
+ /* And read new ones from vmnet if VmnetState buffer is ready */
239
+ if (s->packets_send_current_pos < s->packets_send_end_pos) {
240
+ qemu_bh_schedule(s->send_bh);
241
+ }
242
+}
243
+
244
+
245
+static void vmnet_bufs_init(VmnetState *s)
246
+{
247
+ struct vmpktdesc *packets = s->packets_buf;
248
+ struct iovec *iov = s->iov_buf;
249
+ int i;
250
+
251
+ for (i = 0; i < VMNET_PACKETS_LIMIT; ++i) {
252
+ iov[i].iov_len = s->max_packet_size;
253
+ iov[i].iov_base = g_malloc0(iov[i].iov_len);
254
+ packets[i].vm_pkt_iov = iov + i;
255
+ }
256
+}
257
+
258
+
259
+int vmnet_if_create(NetClientState *nc,
260
+ xpc_object_t if_desc,
261
+ Error **errp)
262
+{
263
+ VmnetState *s = DO_UPCAST(VmnetState, nc, nc);
264
+ dispatch_semaphore_t if_created_sem = dispatch_semaphore_create(0);
265
+ __block vmnet_return_t if_status;
266
+
267
+ s->if_queue = dispatch_queue_create(
268
+ "org.qemu.vmnet.if_queue",
269
+ DISPATCH_QUEUE_SERIAL
270
+ );
271
+
272
+ xpc_dictionary_set_bool(
273
+ if_desc,
274
+ vmnet_allocate_mac_address_key,
275
+ false
276
+ );
277
+
278
+#ifdef DEBUG
279
+ qemu_log("vmnet.start.interface_desc:\n");
280
+ xpc_dictionary_apply(if_desc,
281
+ ^bool(const char *k, xpc_object_t v) {
282
+ char *desc = xpc_copy_description(v);
283
+ qemu_log(" %s=%s\n", k, desc);
284
+ free(desc);
285
+ return true;
286
+ });
287
+#endif /* DEBUG */
288
+
289
+ s->vmnet_if = vmnet_start_interface(
290
+ if_desc,
291
+ s->if_queue,
292
+ ^(vmnet_return_t status, xpc_object_t interface_param) {
293
+ if_status = status;
294
+ if (status != VMNET_SUCCESS || !interface_param) {
295
+ dispatch_semaphore_signal(if_created_sem);
296
+ return;
297
+ }
298
+
299
+#ifdef DEBUG
300
+ qemu_log("vmnet.start.interface_param:\n");
301
+ xpc_dictionary_apply(interface_param,
302
+ ^bool(const char *k, xpc_object_t v) {
303
+ char *desc = xpc_copy_description(v);
304
+ qemu_log(" %s=%s\n", k, desc);
305
+ free(desc);
306
+ return true;
307
+ });
308
+#endif /* DEBUG */
309
+
310
+ s->mtu = xpc_dictionary_get_uint64(
311
+ interface_param,
312
+ vmnet_mtu_key);
313
+ s->max_packet_size = xpc_dictionary_get_uint64(
314
+ interface_param,
315
+ vmnet_max_packet_size_key);
316
+
317
+ dispatch_semaphore_signal(if_created_sem);
318
+ });
319
+
320
+ if (s->vmnet_if == NULL) {
321
+ dispatch_release(s->if_queue);
322
+ dispatch_release(if_created_sem);
323
+ error_setg(errp,
324
+ "unable to create interface with requested params");
325
+ return -1;
326
+ }
327
+
328
+ dispatch_semaphore_wait(if_created_sem, DISPATCH_TIME_FOREVER);
329
+ dispatch_release(if_created_sem);
330
+
331
+ if (if_status != VMNET_SUCCESS) {
332
+ dispatch_release(s->if_queue);
333
+ error_setg(errp,
334
+ "cannot create vmnet interface: %s",
335
+ vmnet_status_map_str(if_status));
336
+ return -1;
337
+ }
338
+
339
+ s->send_bh = aio_bh_new(qemu_get_aio_context(), vmnet_send_bh, nc);
340
+ vmnet_bufs_init(s);
341
+
342
+ s->packets_send_current_pos = 0;
343
+ s->packets_send_end_pos = 0;
344
+
345
+ vmnet_interface_set_event_callback(
346
+ s->vmnet_if,
347
+ VMNET_INTERFACE_PACKETS_AVAILABLE,
348
+ s->if_queue,
349
+ ^(interface_event_t event_id, xpc_object_t event) {
350
+ assert(event_id == VMNET_INTERFACE_PACKETS_AVAILABLE);
351
+ /*
352
+ * This function is being called from a non qemu thread, so
353
+ * we only schedule a BH, and do the rest of the io completion
354
+ * handling from vmnet_send_bh() which runs in a qemu context.
355
+ */
356
+ qemu_bh_schedule(s->send_bh);
357
+ });
358
+
359
+ return 0;
360
+}
361
+
362
+
363
+void vmnet_cleanup_common(NetClientState *nc)
364
+{
365
+ VmnetState *s = DO_UPCAST(VmnetState, nc, nc);
366
+ dispatch_semaphore_t if_stopped_sem;
367
+
368
+ if (s->vmnet_if == NULL) {
369
+ return;
370
+ }
371
+
372
+ if_stopped_sem = dispatch_semaphore_create(0);
373
+ vmnet_stop_interface(
374
+ s->vmnet_if,
375
+ s->if_queue,
376
+ ^(vmnet_return_t status) {
377
+ assert(status == VMNET_SUCCESS);
378
+ dispatch_semaphore_signal(if_stopped_sem);
379
+ });
380
+ dispatch_semaphore_wait(if_stopped_sem, DISPATCH_TIME_FOREVER);
381
+
382
+ qemu_purge_queued_packets(nc);
383
+
384
+ qemu_bh_delete(s->send_bh);
385
+ dispatch_release(if_stopped_sem);
386
+ dispatch_release(s->if_queue);
387
+
388
+ for (int i = 0; i < VMNET_PACKETS_LIMIT; ++i) {
389
+ g_free(s->iov_buf[i].iov_base);
390
+ }
391
+}
392
diff --git a/net/vmnet-shared.c b/net/vmnet-shared.c
393
index XXXXXXX..XXXXXXX 100644
394
--- a/net/vmnet-shared.c
395
+++ b/net/vmnet-shared.c
396
@@ -XXX,XX +XXX,XX @@
397
398
#include "qemu/osdep.h"
399
#include "qapi/qapi-types-net.h"
400
+#include "qapi/error.h"
401
#include "vmnet_int.h"
402
#include "clients.h"
403
-#include "qemu/error-report.h"
404
-#include "qapi/error.h"
405
406
#include <vmnet/vmnet.h>
407
408
+
409
+static bool validate_options(const Netdev *netdev, Error **errp)
410
+{
411
+ const NetdevVmnetSharedOptions *options = &(netdev->u.vmnet_shared);
412
+
413
+#if !defined(MAC_OS_VERSION_11_0) || \
414
+ MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_VERSION_11_0
415
+ if (options->has_isolated) {
416
+ error_setg(errp,
417
+ "vmnet-shared.isolated feature is "
418
+ "unavailable: outdated vmnet.framework API");
419
+ return false;
420
+ }
421
+#endif
422
+
423
+ if ((options->has_start_address ||
424
+ options->has_end_address ||
425
+ options->has_subnet_mask) &&
426
+ !(options->has_start_address &&
427
+ options->has_end_address &&
428
+ options->has_subnet_mask)) {
429
+ error_setg(errp,
430
+ "'start-address', 'end-address', 'subnet-mask' "
431
+ "should be provided together"
432
+ );
433
+ return false;
434
+ }
435
+
436
+ return true;
437
+}
438
+
439
+static xpc_object_t build_if_desc(const Netdev *netdev)
440
+{
441
+ const NetdevVmnetSharedOptions *options = &(netdev->u.vmnet_shared);
442
+ xpc_object_t if_desc = xpc_dictionary_create(NULL, NULL, 0);
443
+
444
+ xpc_dictionary_set_uint64(
445
+ if_desc,
446
+ vmnet_operation_mode_key,
447
+ VMNET_SHARED_MODE
448
+ );
449
+
450
+ if (options->has_nat66_prefix) {
451
+ xpc_dictionary_set_string(if_desc,
452
+ vmnet_nat66_prefix_key,
453
+ options->nat66_prefix);
454
+ }
455
+
456
+ if (options->has_start_address) {
457
+ xpc_dictionary_set_string(if_desc,
458
+ vmnet_start_address_key,
459
+ options->start_address);
460
+ xpc_dictionary_set_string(if_desc,
461
+ vmnet_end_address_key,
462
+ options->end_address);
463
+ xpc_dictionary_set_string(if_desc,
464
+ vmnet_subnet_mask_key,
465
+ options->subnet_mask);
466
+ }
467
+
468
+#if defined(MAC_OS_VERSION_11_0) && \
469
+ MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_VERSION_11_0
470
+ xpc_dictionary_set_bool(
471
+ if_desc,
472
+ vmnet_enable_isolation_key,
473
+ options->isolated
474
+ );
475
+#endif
476
+
477
+ return if_desc;
478
+}
479
+
480
+static NetClientInfo net_vmnet_shared_info = {
481
+ .type = NET_CLIENT_DRIVER_VMNET_SHARED,
482
+ .size = sizeof(VmnetState),
483
+ .receive = vmnet_receive_common,
484
+ .cleanup = vmnet_cleanup_common,
485
+};
486
+
487
int net_init_vmnet_shared(const Netdev *netdev, const char *name,
488
NetClientState *peer, Error **errp)
489
{
490
- error_setg(errp, "vmnet-shared is not implemented yet");
491
- return -1;
492
+ NetClientState *nc = qemu_new_net_client(&net_vmnet_shared_info,
493
+ peer, "vmnet-shared", name);
494
+ xpc_object_t if_desc;
495
+ int result = -1;
496
+
497
+ if (!validate_options(netdev, errp)) {
498
+ return result;
499
+ }
500
+
501
+ if_desc = build_if_desc(netdev);
502
+ result = vmnet_if_create(nc, if_desc, errp);
503
+ xpc_release(if_desc);
504
+ return result;
505
}
506
diff --git a/net/vmnet_int.h b/net/vmnet_int.h
507
index XXXXXXX..XXXXXXX 100644
508
--- a/net/vmnet_int.h
509
+++ b/net/vmnet_int.h
510
@@ -XXX,XX +XXX,XX @@
511
#include "clients.h"
512
513
#include <vmnet/vmnet.h>
514
+#include <dispatch/dispatch.h>
515
+
516
+/**
517
+ * From vmnet.framework documentation
518
+ *
519
+ * Each read/write call allows up to 200 packets to be
520
+ * read or written for a maximum of 256KB.
521
+ *
522
+ * Each packet written should be a complete
523
+ * ethernet frame.
524
+ *
525
+ * https://developer.apple.com/documentation/vmnet
526
+ */
527
+#define VMNET_PACKETS_LIMIT 200
528
529
typedef struct VmnetState {
530
- NetClientState nc;
531
+ NetClientState nc;
532
+ interface_ref vmnet_if;
533
+
534
+ uint64_t mtu;
535
+ uint64_t max_packet_size;
536
537
+ dispatch_queue_t if_queue;
538
+
539
+ QEMUBH *send_bh;
540
+
541
+ struct vmpktdesc packets_buf[VMNET_PACKETS_LIMIT];
542
+ int packets_send_current_pos;
543
+ int packets_send_end_pos;
544
+
545
+ struct iovec iov_buf[VMNET_PACKETS_LIMIT];
546
} VmnetState;
547
548
+const char *vmnet_status_map_str(vmnet_return_t status);
549
+
550
+int vmnet_if_create(NetClientState *nc,
551
+ xpc_object_t if_desc,
552
+ Error **errp);
553
+
554
+ssize_t vmnet_receive_common(NetClientState *nc,
555
+ const uint8_t *buf,
556
+ size_t size);
557
+
558
+void vmnet_cleanup_common(NetClientState *nc);
559
560
#endif /* VMNET_INT_H */
39
--
561
--
40
2.7.4
562
2.25.1
41
42
diff view generated by jsdifflib
New patch
1
From: Vladislav Yaroshchuk <vladislav.yaroshchuk@jetbrains.com>
1
2
3
Reviewed-by: Akihiko Odaki <akihiko.odaki@gmail.com>
4
Tested-by: Akihiko Odaki <akihiko.odaki@gmail.com>
5
Signed-off-by: Vladislav Yaroshchuk <Vladislav.Yaroshchuk@jetbrains.com>
6
Signed-off-by: Jason Wang <jasowang@redhat.com>
7
---
8
net/vmnet-host.c | 116 ++++++++++++++++++++++++++++++++++++++++++++---
9
1 file changed, 110 insertions(+), 6 deletions(-)
10
11
diff --git a/net/vmnet-host.c b/net/vmnet-host.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/net/vmnet-host.c
14
+++ b/net/vmnet-host.c
15
@@ -XXX,XX +XXX,XX @@
16
*/
17
18
#include "qemu/osdep.h"
19
+#include "qemu/uuid.h"
20
#include "qapi/qapi-types-net.h"
21
-#include "vmnet_int.h"
22
-#include "clients.h"
23
-#include "qemu/error-report.h"
24
#include "qapi/error.h"
25
+#include "clients.h"
26
+#include "vmnet_int.h"
27
28
#include <vmnet/vmnet.h>
29
30
+
31
+static bool validate_options(const Netdev *netdev, Error **errp)
32
+{
33
+ const NetdevVmnetHostOptions *options = &(netdev->u.vmnet_host);
34
+
35
+#if defined(MAC_OS_VERSION_11_0) && \
36
+ MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_VERSION_11_0
37
+
38
+ QemuUUID net_uuid;
39
+ if (options->has_net_uuid &&
40
+ qemu_uuid_parse(options->net_uuid, &net_uuid) < 0) {
41
+ error_setg(errp, "Invalid UUID provided in 'net-uuid'");
42
+ return false;
43
+ }
44
+#else
45
+ if (options->has_isolated) {
46
+ error_setg(errp,
47
+ "vmnet-host.isolated feature is "
48
+ "unavailable: outdated vmnet.framework API");
49
+ return false;
50
+ }
51
+
52
+ if (options->has_net_uuid) {
53
+ error_setg(errp,
54
+ "vmnet-host.net-uuid feature is "
55
+ "unavailable: outdated vmnet.framework API");
56
+ return false;
57
+ }
58
+#endif
59
+
60
+ if ((options->has_start_address ||
61
+ options->has_end_address ||
62
+ options->has_subnet_mask) &&
63
+ !(options->has_start_address &&
64
+ options->has_end_address &&
65
+ options->has_subnet_mask)) {
66
+ error_setg(errp,
67
+ "'start-address', 'end-address', 'subnet-mask' "
68
+ "should be provided together");
69
+ return false;
70
+ }
71
+
72
+ return true;
73
+}
74
+
75
+static xpc_object_t build_if_desc(const Netdev *netdev)
76
+{
77
+ const NetdevVmnetHostOptions *options = &(netdev->u.vmnet_host);
78
+ xpc_object_t if_desc = xpc_dictionary_create(NULL, NULL, 0);
79
+
80
+ xpc_dictionary_set_uint64(if_desc,
81
+ vmnet_operation_mode_key,
82
+ VMNET_HOST_MODE);
83
+
84
+#if defined(MAC_OS_VERSION_11_0) && \
85
+ MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_VERSION_11_0
86
+
87
+ xpc_dictionary_set_bool(if_desc,
88
+ vmnet_enable_isolation_key,
89
+ options->isolated);
90
+
91
+ QemuUUID net_uuid;
92
+ if (options->has_net_uuid) {
93
+ qemu_uuid_parse(options->net_uuid, &net_uuid);
94
+ xpc_dictionary_set_uuid(if_desc,
95
+ vmnet_network_identifier_key,
96
+ net_uuid.data);
97
+ }
98
+#endif
99
+
100
+ if (options->has_start_address) {
101
+ xpc_dictionary_set_string(if_desc,
102
+ vmnet_start_address_key,
103
+ options->start_address);
104
+ xpc_dictionary_set_string(if_desc,
105
+ vmnet_end_address_key,
106
+ options->end_address);
107
+ xpc_dictionary_set_string(if_desc,
108
+ vmnet_subnet_mask_key,
109
+ options->subnet_mask);
110
+ }
111
+
112
+ return if_desc;
113
+}
114
+
115
+static NetClientInfo net_vmnet_host_info = {
116
+ .type = NET_CLIENT_DRIVER_VMNET_HOST,
117
+ .size = sizeof(VmnetState),
118
+ .receive = vmnet_receive_common,
119
+ .cleanup = vmnet_cleanup_common,
120
+};
121
+
122
int net_init_vmnet_host(const Netdev *netdev, const char *name,
123
- NetClientState *peer, Error **errp) {
124
- error_setg(errp, "vmnet-host is not implemented yet");
125
- return -1;
126
+ NetClientState *peer, Error **errp)
127
+{
128
+ NetClientState *nc = qemu_new_net_client(&net_vmnet_host_info,
129
+ peer, "vmnet-host", name);
130
+ xpc_object_t if_desc;
131
+ int result = -1;
132
+
133
+ if (!validate_options(netdev, errp)) {
134
+ return result;
135
+ }
136
+
137
+ if_desc = build_if_desc(netdev);
138
+ result = vmnet_if_create(nc, if_desc, errp);
139
+ xpc_release(if_desc);
140
+ return result;
141
}
142
--
143
2.25.1
diff view generated by jsdifflib
1
From: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
1
From: Vladislav Yaroshchuk <vladislav.yaroshchuk@jetbrains.com>
2
2
3
Improve efficiency of TCP packet comparison.
3
Reviewed-by: Akihiko Odaki <akihiko.odaki@gmail.com>
4
4
Tested-by: Akihiko Odaki <akihiko.odaki@gmail.com>
5
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
5
Signed-off-by: Vladislav Yaroshchuk <Vladislav.Yaroshchuk@jetbrains.com>
6
Signed-off-by: Li Zhijian <lizhijian@cn.fujitsu.com>
7
Signed-off-by: Jason Wang <jasowang@redhat.com>
6
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
---
7
---
9
net/colo-compare.c | 19 +++++++++++++++++++
8
net/vmnet-bridged.m | 137 ++++++++++++++++++++++++++++++++++++++++++--
10
1 file changed, 19 insertions(+)
9
1 file changed, 132 insertions(+), 5 deletions(-)
11
10
12
diff --git a/net/colo-compare.c b/net/colo-compare.c
11
diff --git a/net/vmnet-bridged.m b/net/vmnet-bridged.m
13
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
14
--- a/net/colo-compare.c
13
--- a/net/vmnet-bridged.m
15
+++ b/net/colo-compare.c
14
+++ b/net/vmnet-bridged.m
16
@@ -XXX,XX +XXX,XX @@ static int compare_chr_send(CharBackend *out,
15
@@ -XXX,XX +XXX,XX @@
17
const uint8_t *buf,
16
18
uint32_t size);
17
#include "qemu/osdep.h"
19
18
#include "qapi/qapi-types-net.h"
20
+static gint seq_sorter(Packet *a, Packet *b, gpointer data)
19
-#include "vmnet_int.h"
20
-#include "clients.h"
21
-#include "qemu/error-report.h"
22
#include "qapi/error.h"
23
+#include "clients.h"
24
+#include "vmnet_int.h"
25
26
#include <vmnet/vmnet.h>
27
28
+
29
+static bool validate_ifname(const char *ifname)
21
+{
30
+{
22
+ struct tcphdr *atcp, *btcp;
31
+ xpc_object_t shared_if_list = vmnet_copy_shared_interface_list();
32
+ bool match = false;
33
+ if (!xpc_array_get_count(shared_if_list)) {
34
+ goto done;
35
+ }
23
+
36
+
24
+ atcp = (struct tcphdr *)(a->transport_header);
37
+ match = !xpc_array_apply(
25
+ btcp = (struct tcphdr *)(b->transport_header);
38
+ shared_if_list,
26
+ return ntohl(atcp->th_seq) - ntohl(btcp->th_seq);
39
+ ^bool(size_t index, xpc_object_t value) {
40
+ return strcmp(xpc_string_get_string_ptr(value), ifname) != 0;
41
+ });
42
+
43
+done:
44
+ xpc_release(shared_if_list);
45
+ return match;
27
+}
46
+}
28
+
47
+
29
/*
48
+
30
* Return 0 on success, if return -1 means the pkt
49
+static char* get_valid_ifnames()
31
* is unsupported(arp and ipv6) and will be sent later
50
+{
32
@@ -XXX,XX +XXX,XX @@ static int packet_enqueue(CompareState *s, int mode)
51
+ xpc_object_t shared_if_list = vmnet_copy_shared_interface_list();
33
if (g_queue_get_length(&conn->primary_list) <=
52
+ __block char *if_list = NULL;
34
MAX_QUEUE_SIZE) {
53
+ __block char *if_list_prev = NULL;
35
g_queue_push_tail(&conn->primary_list, pkt);
54
+
36
+ if (conn->ip_proto == IPPROTO_TCP) {
55
+ if (!xpc_array_get_count(shared_if_list)) {
37
+ g_queue_sort(&conn->primary_list,
56
+ goto done;
38
+ (GCompareDataFunc)seq_sorter,
57
+ }
39
+ NULL);
58
+
40
+ }
59
+ xpc_array_apply(
41
} else {
60
+ shared_if_list,
42
error_report("colo compare primary queue size too big,"
61
+ ^bool(size_t index, xpc_object_t value) {
43
"drop packet");
62
+ /* build list of strings like "en0 en1 en2 " */
44
@@ -XXX,XX +XXX,XX @@ static int packet_enqueue(CompareState *s, int mode)
63
+ if_list = g_strconcat(xpc_string_get_string_ptr(value),
45
if (g_queue_get_length(&conn->secondary_list) <=
64
+ " ",
46
MAX_QUEUE_SIZE) {
65
+ if_list_prev,
47
g_queue_push_tail(&conn->secondary_list, pkt);
66
+ NULL);
48
+ if (conn->ip_proto == IPPROTO_TCP) {
67
+ g_free(if_list_prev);
49
+ g_queue_sort(&conn->secondary_list,
68
+ if_list_prev = if_list;
50
+ (GCompareDataFunc)seq_sorter,
69
+ return true;
51
+ NULL);
70
+ });
52
+ }
71
+
53
} else {
72
+done:
54
error_report("colo compare secondary queue size too big,"
73
+ xpc_release(shared_if_list);
55
"drop packet");
74
+ return if_list;
75
+}
76
+
77
+
78
+static bool validate_options(const Netdev *netdev, Error **errp)
79
+{
80
+ const NetdevVmnetBridgedOptions *options = &(netdev->u.vmnet_bridged);
81
+ char* if_list;
82
+
83
+ if (!validate_ifname(options->ifname)) {
84
+ if_list = get_valid_ifnames();
85
+ if (if_list) {
86
+ error_setg(errp,
87
+ "unsupported ifname '%s', expected one of [ %s]",
88
+ options->ifname,
89
+ if_list);
90
+ g_free(if_list);
91
+ } else {
92
+ error_setg(errp,
93
+ "unsupported ifname '%s', no supported "
94
+ "interfaces available",
95
+ options->ifname);
96
+ }
97
+ return false;
98
+ }
99
+
100
+#if !defined(MAC_OS_VERSION_11_0) || \
101
+ MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_VERSION_11_0
102
+ if (options->has_isolated) {
103
+ error_setg(errp,
104
+ "vmnet-bridged.isolated feature is "
105
+ "unavailable: outdated vmnet.framework API");
106
+ return false;
107
+ }
108
+#endif
109
+ return true;
110
+}
111
+
112
+
113
+static xpc_object_t build_if_desc(const Netdev *netdev)
114
+{
115
+ const NetdevVmnetBridgedOptions *options = &(netdev->u.vmnet_bridged);
116
+ xpc_object_t if_desc = xpc_dictionary_create(NULL, NULL, 0);
117
+
118
+ xpc_dictionary_set_uint64(if_desc,
119
+ vmnet_operation_mode_key,
120
+ VMNET_BRIDGED_MODE
121
+ );
122
+
123
+ xpc_dictionary_set_string(if_desc,
124
+ vmnet_shared_interface_name_key,
125
+ options->ifname);
126
+
127
+#if defined(MAC_OS_VERSION_11_0) && \
128
+ MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_VERSION_11_0
129
+ xpc_dictionary_set_bool(if_desc,
130
+ vmnet_enable_isolation_key,
131
+ options->isolated);
132
+#endif
133
+ return if_desc;
134
+}
135
+
136
+
137
+static NetClientInfo net_vmnet_bridged_info = {
138
+ .type = NET_CLIENT_DRIVER_VMNET_BRIDGED,
139
+ .size = sizeof(VmnetState),
140
+ .receive = vmnet_receive_common,
141
+ .cleanup = vmnet_cleanup_common,
142
+};
143
+
144
+
145
int net_init_vmnet_bridged(const Netdev *netdev, const char *name,
146
NetClientState *peer, Error **errp)
147
{
148
- error_setg(errp, "vmnet-bridged is not implemented yet");
149
- return -1;
150
+ NetClientState *nc = qemu_new_net_client(&net_vmnet_bridged_info,
151
+ peer, "vmnet-bridged", name);
152
+ xpc_object_t if_desc;
153
+ int result = -1;
154
+
155
+ if (!validate_options(netdev, errp)) {
156
+ return result;
157
+ }
158
+
159
+ if_desc = build_if_desc(netdev);
160
+ result = vmnet_if_create(nc, if_desc, errp);
161
+ xpc_release(if_desc);
162
+ return result;
163
}
56
--
164
--
57
2.7.4
165
2.25.1
58
59
diff view generated by jsdifflib
New patch
1
From: Vladislav Yaroshchuk <vladislav.yaroshchuk@jetbrains.com>
1
2
3
Update qemu-options.hx to support vmnet networking backend.
4
5
Reviewed-by: Akihiko Odaki <akihiko.odaki@gmail.com>
6
Tested-by: Akihiko Odaki <akihiko.odaki@gmail.com>
7
Signed-off-by: Vladislav Yaroshchuk <Vladislav.Yaroshchuk@jetbrains.com>
8
Signed-off-by: Jason Wang <jasowang@redhat.com>
9
---
10
qemu-options.hx | 25 +++++++++++++++++++++++++
11
1 file changed, 25 insertions(+)
12
13
diff --git a/qemu-options.hx b/qemu-options.hx
14
index XXXXXXX..XXXXXXX 100644
15
--- a/qemu-options.hx
16
+++ b/qemu-options.hx
17
@@ -XXX,XX +XXX,XX @@ DEF("netdev", HAS_ARG, QEMU_OPTION_netdev,
18
#ifdef __linux__
19
"-netdev vhost-vdpa,id=str,vhostdev=/path/to/dev\n"
20
" configure a vhost-vdpa network,Establish a vhost-vdpa netdev\n"
21
+#endif
22
+#ifdef CONFIG_VMNET
23
+ "-netdev vmnet-host,id=str[,isolated=on|off][,net-uuid=uuid]\n"
24
+ " [,start-address=addr,end-address=addr,subnet-mask=mask]\n"
25
+ " configure a vmnet network backend in host mode with ID 'str',\n"
26
+ " isolate this interface from others with 'isolated',\n"
27
+ " configure the address range and choose a subnet mask,\n"
28
+ " specify network UUID 'uuid' to disable DHCP and interact with\n"
29
+ " vmnet-host interfaces within this isolated network\n"
30
+ "-netdev vmnet-shared,id=str[,isolated=on|off][,nat66-prefix=addr]\n"
31
+ " [,start-address=addr,end-address=addr,subnet-mask=mask]\n"
32
+ " configure a vmnet network backend in shared mode with ID 'str',\n"
33
+ " configure the address range and choose a subnet mask,\n"
34
+ " set IPv6 ULA prefix (of length 64) to use for internal network,\n"
35
+ " isolate this interface from others with 'isolated'\n"
36
+ "-netdev vmnet-bridged,id=str,ifname=name[,isolated=on|off]\n"
37
+ " configure a vmnet network backend in bridged mode with ID 'str',\n"
38
+ " use 'ifname=name' to select a physical network interface to be bridged,\n"
39
+ " isolate this interface from others with 'isolated'\n"
40
#endif
41
"-netdev hubport,id=str,hubid=n[,netdev=nd]\n"
42
" configure a hub port on the hub with ID 'n'\n", QEMU_ARCH_ALL)
43
@@ -XXX,XX +XXX,XX @@ DEF("nic", HAS_ARG, QEMU_OPTION_nic,
44
#endif
45
#ifdef CONFIG_POSIX
46
"vhost-user|"
47
+#endif
48
+#ifdef CONFIG_VMNET
49
+ "vmnet-host|vmnet-shared|vmnet-bridged|"
50
#endif
51
"socket][,option][,...][mac=macaddr]\n"
52
" initialize an on-board / default host NIC (using MAC address\n"
53
@@ -XXX,XX +XXX,XX @@ DEF("net", HAS_ARG, QEMU_OPTION_net,
54
#endif
55
#ifdef CONFIG_NETMAP
56
"netmap|"
57
+#endif
58
+#ifdef CONFIG_VMNET
59
+ "vmnet-host|vmnet-shared|vmnet-bridged|"
60
#endif
61
"socket][,option][,option][,...]\n"
62
" old way to initialize a host network interface\n"
63
--
64
2.25.1
diff view generated by jsdifflib
1
From: Prasad J Pandit <pjp@fedoraproject.org>
1
From: Vladislav Yaroshchuk <vladislav.yaroshchuk@jetbrains.com>
2
2
3
i.MX Fast Ethernet Controller uses buffer descriptors to manage
3
Update HMP for supporting vmnet.
4
data flow to/fro receive & transmit queues. While transmitting
5
packets, it could continue to read buffer descriptors if a buffer
6
descriptor has length of zero and has crafted values in bd.flags.
7
Set an upper limit to number of buffer descriptors.
8
4
9
Reported-by: Li Qiang <liqiang6-s@360.cn>
5
Reviewed-by: Akihiko Odaki <akihiko.odaki@gmail.com>
10
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
6
Tested-by: Akihiko Odaki <akihiko.odaki@gmail.com>
7
Signed-off-by: Vladislav Yaroshchuk <Vladislav.Yaroshchuk@jetbrains.com>
11
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
Signed-off-by: Jason Wang <jasowang@redhat.com>
12
---
9
---
13
hw/net/imx_fec.c | 10 ++++++----
10
hmp-commands.hx | 6 +++++-
14
1 file changed, 6 insertions(+), 4 deletions(-)
11
1 file changed, 5 insertions(+), 1 deletion(-)
15
12
16
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
13
diff --git a/hmp-commands.hx b/hmp-commands.hx
17
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/net/imx_fec.c
15
--- a/hmp-commands.hx
19
+++ b/hw/net/imx_fec.c
16
+++ b/hmp-commands.hx
20
@@ -XXX,XX +XXX,XX @@
17
@@ -XXX,XX +XXX,XX @@ ERST
21
} \
18
{
22
} while (0)
19
.name = "netdev_add",
23
20
.args_type = "netdev:O",
24
+#define IMX_MAX_DESC 1024
21
- .params = "[user|tap|socket|vde|bridge|hubport|netmap|vhost-user],id=str[,prop=value][,...]",
25
+
22
+ .params = "[user|tap|socket|vde|bridge|hubport|netmap|vhost-user"
26
static const char *imx_default_reg_name(IMXFECState *s, uint32_t index)
23
+#ifdef CONFIG_VMNET
27
{
24
+ "|vmnet-host|vmnet-shared|vmnet-bridged"
28
static char tmp[20];
25
+#endif
29
@@ -XXX,XX +XXX,XX @@ static void imx_eth_update(IMXFECState *s)
26
+ "],id=str[,prop=value][,...]",
30
27
.help = "add host network device",
31
static void imx_fec_do_tx(IMXFECState *s)
28
.cmd = hmp_netdev_add,
32
{
29
.command_completion = netdev_add_completion,
33
- int frame_size = 0;
34
+ int frame_size = 0, descnt = 0;
35
uint8_t frame[ENET_MAX_FRAME_SIZE];
36
uint8_t *ptr = frame;
37
uint32_t addr = s->tx_descriptor;
38
39
- while (1) {
40
+ while (descnt++ < IMX_MAX_DESC) {
41
IMXFECBufDesc bd;
42
int len;
43
44
@@ -XXX,XX +XXX,XX @@ static void imx_fec_do_tx(IMXFECState *s)
45
46
static void imx_enet_do_tx(IMXFECState *s)
47
{
48
- int frame_size = 0;
49
+ int frame_size = 0, descnt = 0;
50
uint8_t frame[ENET_MAX_FRAME_SIZE];
51
uint8_t *ptr = frame;
52
uint32_t addr = s->tx_descriptor;
53
54
- while (1) {
55
+ while (descnt++ < IMX_MAX_DESC) {
56
IMXENETBufDesc bd;
57
int len;
58
59
--
30
--
60
2.7.4
31
2.25.1
61
62
diff view generated by jsdifflib
1
From: Paolo Bonzini <pbonzini@redhat.com>
1
From: Helge Deller <deller@gmx.de>
2
2
3
Because is_first is declared inside a loop, it is always true. The store
3
The MAC of the tulip card is stored in the EEPROM and at startup
4
is dead, and so is the "else" branch of "if (is_first)". is_last is
4
tulip_fill_eeprom() is called to initialize the EEPROM with the MAC
5
okay though.
5
address given on the command line, e.g.:
6
-device tulip,mac=00:11:22:33:44:55
6
7
7
Reported by Coverity.
8
In case the mac address was not given on the command line,
9
tulip_fill_eeprom() initializes the MAC in EEPROM with 00:00:00:00:00:00
10
which breaks e.g. a HP-UX guest.
8
11
9
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
12
Fix this problem by moving qemu_macaddr_default_if_unset() a few lines
10
Reviewed-by: Dmitry Fleytman <dmitry@daynix.com>
13
up, so that a default mac address is assigned before tulip_fill_eeprom()
14
initializes the EEPROM.
15
16
Signed-off-by: Helge Deller <deller@gmx.de>
17
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Signed-off-by: Jason Wang <jasowang@redhat.com>
18
Signed-off-by: Jason Wang <jasowang@redhat.com>
12
---
19
---
13
hw/net/e1000e_core.c | 2 +-
20
hw/net/tulip.c | 4 ++--
14
1 file changed, 1 insertion(+), 1 deletion(-)
21
1 file changed, 2 insertions(+), 2 deletions(-)
15
22
16
diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c
23
diff --git a/hw/net/tulip.c b/hw/net/tulip.c
17
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/net/e1000e_core.c
25
--- a/hw/net/tulip.c
19
+++ b/hw/net/e1000e_core.c
26
+++ b/hw/net/tulip.c
20
@@ -XXX,XX +XXX,XX @@ e1000e_write_packet_to_guest(E1000ECore *core, struct NetRxPkt *pkt,
27
@@ -XXX,XX +XXX,XX @@ static void pci_tulip_realize(PCIDevice *pci_dev, Error **errp)
21
const E1000E_RingInfo *rxi;
28
pci_conf = s->dev.config;
22
size_t ps_hdr_len = 0;
29
pci_conf[PCI_INTERRUPT_PIN] = 1; /* interrupt pin A */
23
bool do_ps = e1000e_do_ps(core, pkt, &ps_hdr_len);
30
24
+ bool is_first = true;
31
+ qemu_macaddr_default_if_unset(&s->c.macaddr);
25
32
+
26
rxi = rxr->i;
33
s->eeprom = eeprom93xx_new(&pci_dev->qdev, 64);
27
34
tulip_fill_eeprom(s);
28
@@ -XXX,XX +XXX,XX @@ e1000e_write_packet_to_guest(E1000ECore *core, struct NetRxPkt *pkt,
35
29
hwaddr ba[MAX_PS_BUFFERS];
36
@@ -XXX,XX +XXX,XX @@ static void pci_tulip_realize(PCIDevice *pci_dev, Error **errp)
30
e1000e_ba_state bastate = { { 0 } };
37
31
bool is_last = false;
38
s->irq = pci_allocate_irq(&s->dev);
32
- bool is_first = true;
39
33
40
- qemu_macaddr_default_if_unset(&s->c.macaddr);
34
desc_size = total_size - desc_offset;
41
-
35
42
s->nic = qemu_new_nic(&net_tulip_info, &s->c,
43
object_get_typename(OBJECT(pci_dev)),
44
pci_dev->qdev.id, s);
36
--
45
--
37
2.7.4
46
2.25.1
38
47
39
48
diff view generated by jsdifflib