1
The following changes since commit 23895cbd82be95428e90168b12e925d0d3ca2f06:
1
The following changes since commit df722e33d5da26ea8604500ca8f509245a0ea524:
2
2
3
Merge remote-tracking branch 'remotes/awilliam/tags/vfio-update-20201123.0' into staging (2020-11-23 18:51:13 +0000)
3
Merge tag 'bsd-user-arm-pull-request' of gitlab.com:bsdimp/qemu into staging (2022-01-08 09:37:59 -0800)
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 9925990d01a92564af55f6f69d0f5f59b47609b1:
9
for you to fetch changes up to 5136cc6d3b8b74f4fa572f0874656947a401330e:
10
10
11
net: Use correct default-path macro for downscript (2020-11-24 10:40:17 +0800)
11
net/vmnet: update MAINTAINERS list (2022-01-10 11:30:55 +0800)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
14
15
----------------------------------------------------------------
15
----------------------------------------------------------------
16
Keqian Zhu (1):
16
Peter Foley (2):
17
net: Use correct default-path macro for downscript
17
net/tap: Set return code on failure
18
net: Fix uninitialized data usage
18
19
19
Paolo Bonzini (1):
20
Philippe Mathieu-Daudé (1):
20
net: do not exit on "netdev_add help" monitor command
21
hw/net/vmxnet3: Log guest-triggerable errors using LOG_GUEST_ERROR
21
22
22
Prasad J Pandit (1):
23
Rao Lei (1):
23
hw/net/e1000e: advance desc_offset in case of null descriptor
24
net/filter: Optimize filter_send to coroutine
24
25
25
Yuri Benditovich (1):
26
Vladislav Yaroshchuk (7):
26
net: purge queued rx packets on queue deletion
27
net/vmnet: add vmnet dependency and customizable option
28
net/vmnet: add vmnet backends to qapi/net
29
net/vmnet: implement shared mode (vmnet-shared)
30
net/vmnet: implement host mode (vmnet-host)
31
net/vmnet: implement bridged mode (vmnet-bridged)
32
net/vmnet: update qemu-options.hx
33
net/vmnet: update MAINTAINERS list
27
34
28
yuanjungong (1):
35
Zhang Chen (2):
29
tap: fix a memory leak
36
net/colo-compare.c: Optimize compare order for performance
37
net/colo-compare.c: Update the default value comments
30
38
31
hw/net/e1000e_core.c | 8 +++---
39
MAINTAINERS | 5 +
32
include/net/net.h | 1 +
40
hw/net/vmxnet3.c | 4 +-
33
monitor/hmp-cmds.c | 6 ++++
41
meson.build | 4 +
34
net/net.c | 80 +++++++++++++++++++++++++++-------------------------
42
meson_options.txt | 2 +
35
net/tap.c | 5 +++-
43
net/clients.h | 11 ++
36
5 files changed, 57 insertions(+), 43 deletions(-)
44
net/colo-compare.c | 28 ++--
45
net/filter-mirror.c | 66 +++++++--
46
net/meson.build | 7 +
47
net/net.c | 10 ++
48
net/tap-linux.c | 1 +
49
net/tap.c | 1 +
50
net/vmnet-bridged.m | 111 ++++++++++++++
51
net/vmnet-common.m | 330 ++++++++++++++++++++++++++++++++++++++++++
52
net/vmnet-host.c | 105 ++++++++++++++
53
net/vmnet-shared.c | 91 ++++++++++++
54
net/vmnet_int.h | 48 ++++++
55
qapi/net.json | 132 ++++++++++++++++-
56
qemu-options.hx | 25 ++++
57
scripts/meson-buildoptions.sh | 3 +
58
19 files changed, 954 insertions(+), 30 deletions(-)
59
create mode 100644 net/vmnet-bridged.m
60
create mode 100644 net/vmnet-common.m
61
create mode 100644 net/vmnet-host.c
62
create mode 100644 net/vmnet-shared.c
63
create mode 100644 net/vmnet_int.h
37
64
38
65
66
diff view generated by jsdifflib
1
From: Keqian Zhu <zhukeqian1@huawei.com>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
Fixes: 63c4db4c2e6d (net: relocate paths to helpers and scripts)
3
The "Interrupt Cause" register (VMXNET3_REG_ICR) is read-only.
4
Signed-off-by: Keqian Zhu <zhukeqian1@huawei.com>
4
Write accesses are ignored. Log them with as LOG_GUEST_ERROR
5
instead of aborting:
6
7
[R +0.239743] writeq 0xe0002031 0x46291a5a55460800
8
ERROR:hw/net/vmxnet3.c:1819:vmxnet3_io_bar1_write: code should not be reached
9
Thread 1 "qemu-system-i38" received signal SIGABRT, Aborted.
10
(gdb) bt
11
#3 0x74c397d3 in __GI_abort () at abort.c:79
12
#4 0x76d3cd4c in g_assertion_message (domain=<optimized out>, file=<optimized out>, line=<optimized out>, func=<optimized out>, message=<optimized out>) at ../glib/gtestutils.c:3223
13
#5 0x76d9d45f in g_assertion_message_expr
14
(domain=0x0, file=0x59fc2e53 "hw/net/vmxnet3.c", line=1819, func=0x59fc11e0 <__func__.vmxnet3_io_bar1_write> "vmxnet3_io_bar1_write", expr=<optimized out>)
15
at ../glib/gtestutils.c:3249
16
#6 0x57e80a3a in vmxnet3_io_bar1_write (opaque=0x62814100, addr=56, val=70, size=4) at hw/net/vmxnet3.c:1819
17
#7 0x58c2d894 in memory_region_write_accessor (mr=0x62816b90, addr=56, value=0x7fff9450, size=4, shift=0, mask=4294967295, attrs=...) at softmmu/memory.c:492
18
#8 0x58c2d1d2 in access_with_adjusted_size (addr=56, value=0x7fff9450, size=1, access_size_min=4, access_size_max=4, access_fn=
19
0x58c2d290 <memory_region_write_accessor>, mr=0x62816b90, attrs=...) at softmmu/memory.c:554
20
#9 0x58c2bae7 in memory_region_dispatch_write (mr=0x62816b90, addr=56, data=70, op=MO_8, attrs=...) at softmmu/memory.c:1504
21
#10 0x58bfd034 in flatview_write_continue (fv=0x606000181700, addr=0xe0002038, attrs=..., ptr=0x7fffb9e0, len=1, addr1=56, l=1, mr=0x62816b90)
22
at softmmu/physmem.c:2782
23
#11 0x58beba00 in flatview_write (fv=0x606000181700, addr=0xe0002031, attrs=..., buf=0x7fffb9e0, len=8) at softmmu/physmem.c:2822
24
#12 0x58beb589 in address_space_write (as=0x608000015f20, addr=0xe0002031, attrs=..., buf=0x7fffb9e0, len=8) at softmmu/physmem.c:2914
25
26
Reported-by: Dike <dike199774@qq.com>
27
Reported-by: Duhao <504224090@qq.com>
28
BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=2032932
29
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
Signed-off-by: Jason Wang <jasowang@redhat.com>
30
Signed-off-by: Jason Wang <jasowang@redhat.com>
6
---
31
---
7
net/tap.c | 3 ++-
32
hw/net/vmxnet3.c | 4 +++-
8
1 file changed, 2 insertions(+), 1 deletion(-)
33
1 file changed, 3 insertions(+), 1 deletion(-)
9
34
10
diff --git a/net/tap.c b/net/tap.c
35
diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c
11
index XXXXXXX..XXXXXXX 100644
36
index XXXXXXX..XXXXXXX 100644
12
--- a/net/tap.c
37
--- a/hw/net/vmxnet3.c
13
+++ b/net/tap.c
38
+++ b/hw/net/vmxnet3.c
14
@@ -XXX,XX +XXX,XX @@ free_fail:
39
@@ -XXX,XX +XXX,XX @@ vmxnet3_io_bar1_write(void *opaque,
15
script = default_script = get_relocated_path(DEFAULT_NETWORK_SCRIPT);
40
case VMXNET3_REG_ICR:
16
}
41
VMW_CBPRN("Write BAR1 [VMXNET3_REG_ICR] = %" PRIx64 ", size %d",
17
if (!downscript) {
42
val, size);
18
- downscript = default_downscript = get_relocated_path(DEFAULT_NETWORK_SCRIPT);
43
- g_assert_not_reached();
19
+ downscript = default_downscript =
44
+ qemu_log_mask(LOG_GUEST_ERROR,
20
+ get_relocated_path(DEFAULT_NETWORK_DOWN_SCRIPT);
45
+ "%s: write to read-only register VMXNET3_REG_ICR\n",
21
}
46
+ TYPE_VMXNET3);
22
47
break;
23
if (tap->has_ifname) {
48
49
/* Event Cause Register */
24
--
50
--
25
2.7.4
51
2.7.4
26
52
27
53
diff view generated by jsdifflib
1
From: yuanjungong <ruc_gongyuanjun@163.com>
1
From: Peter Foley <pefoley@google.com>
2
2
3
Close fd before returning.
3
Match the other error handling in this function.
4
4
5
Buglink: https://bugs.launchpad.net/qemu/+bug/1904486
5
Fixes: e7b347d0bf6 ("net: detect errors from probing vnet hdr flag for TAP devices")
6
6
7
Signed-off-by: yuanjungong <ruc_gongyuanjun@163.com>
7
Reviewed-by: Patrick Venture <venture@google.com>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Signed-off-by: Peter Foley <pefoley@google.com>
9
Signed-off-by: Jason Wang <jasowang@redhat.com>
10
Signed-off-by: Jason Wang <jasowang@redhat.com>
10
---
11
---
11
net/tap.c | 2 ++
12
net/tap.c | 1 +
12
1 file changed, 2 insertions(+)
13
1 file changed, 1 insertion(+)
13
14
14
diff --git a/net/tap.c b/net/tap.c
15
diff --git a/net/tap.c b/net/tap.c
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/net/tap.c
17
--- a/net/tap.c
17
+++ b/net/tap.c
18
+++ b/net/tap.c
18
@@ -XXX,XX +XXX,XX @@ int net_init_tap(const Netdev *netdev, const char *name,
19
@@ -XXX,XX +XXX,XX @@ int net_init_tap(const Netdev *netdev, const char *name,
19
if (ret < 0) {
20
if (i == 0) {
20
error_setg_errno(errp, -ret, "%s: Can't use file descriptor %d",
21
vnet_hdr = tap_probe_vnet_hdr(fd, errp);
21
name, fd);
22
if (vnet_hdr < 0) {
22
+ close(fd);
23
+ ret = -1;
23
return -1;
24
goto free_fail;
24
}
25
}
25
26
} else if (vnet_hdr != tap_probe_vnet_hdr(fd, NULL)) {
26
@@ -XXX,XX +XXX,XX @@ int net_init_tap(const Netdev *netdev, const char *name,
27
vhostfdname, vnet_hdr, fd, &err);
28
if (err) {
29
error_propagate(errp, err);
30
+ close(fd);
31
return -1;
32
}
33
} else if (tap->has_fds) {
34
--
27
--
35
2.7.4
28
2.7.4
36
29
37
30
diff view generated by jsdifflib
New patch
1
From: Peter Foley <pefoley@google.com>
1
2
3
e.g.
4
1109 15:16:20.151506 Uninitialized bytes in ioctl_common_pre at offset 0 inside [0x7ffc516af9b8, 4)
5
1109 15:16:20.151659 ==588974==WARNING: MemorySanitizer: use-of-uninitialized-value
6
1109 15:16:20.312923 #0 0x5639b88acb21 in tap_probe_vnet_hdr_len third_party/qemu/net/tap-linux.c:183:9
7
1109 15:16:20.312952 #1 0x5639b88afd66 in net_tap_fd_init third_party/qemu/net/tap.c:409:9
8
1109 15:16:20.312954 #2 0x5639b88b2d1b in net_init_tap_one third_party/qemu/net/tap.c:681:19
9
1109 15:16:20.312956 #3 0x5639b88b16a8 in net_init_tap third_party/qemu/net/tap.c:912:13
10
1109 15:16:20.312957 #4 0x5639b8890175 in net_client_init1 third_party/qemu/net/net.c:1110:9
11
1109 15:16:20.312958 #5 0x5639b888f912 in net_client_init third_party/qemu/net/net.c:1208:15
12
1109 15:16:20.312960 #6 0x5639b8894aa5 in net_param_nic third_party/qemu/net/net.c:1588:11
13
1109 15:16:20.312961 #7 0x5639b900cd18 in qemu_opts_foreach third_party/qemu/util/qemu-option.c:1135:14
14
1109 15:16:20.312962 #8 0x5639b889393c in net_init_clients third_party/qemu/net/net.c:1612:9
15
1109 15:16:20.312964 #9 0x5639b717aaf3 in qemu_create_late_backends third_party/qemu/softmmu/vl.c:1962:5
16
1109 15:16:20.312965 #10 0x5639b717aaf3 in qemu_init third_party/qemu/softmmu/vl.c:3694:5
17
1109 15:16:20.312967 #11 0x5639b71083b8 in main third_party/qemu/softmmu/main.c:49:5
18
1109 15:16:20.312968 #12 0x7f464de1d8d2 in __libc_start_main (/usr/grte/v5/lib64/libc.so.6+0x628d2)
19
1109 15:16:20.312969 #13 0x5639b6bbd389 in _start /usr/grte/v5/debug-src/src/csu/../sysdeps/x86_64/start.S:120
20
1109 15:16:20.312970
21
1109 15:16:20.312975 Uninitialized value was stored to memory at
22
1109 15:16:20.313393 #0 0x5639b88acbee in tap_probe_vnet_hdr_len third_party/qemu/net/tap-linux.c
23
1109 15:16:20.313396 #1 0x5639b88afd66 in net_tap_fd_init third_party/qemu/net/tap.c:409:9
24
1109 15:16:20.313398 #2 0x5639b88b2d1b in net_init_tap_one third_party/qemu/net/tap.c:681:19
25
1109 15:16:20.313399 #3 0x5639b88b16a8 in net_init_tap third_party/qemu/net/tap.c:912:13
26
1109 15:16:20.313400 #4 0x5639b8890175 in net_client_init1 third_party/qemu/net/net.c:1110:9
27
1109 15:16:20.313401 #5 0x5639b888f912 in net_client_init third_party/qemu/net/net.c:1208:15
28
1109 15:16:20.313403 #6 0x5639b8894aa5 in net_param_nic third_party/qemu/net/net.c:1588:11
29
1109 15:16:20.313404 #7 0x5639b900cd18 in qemu_opts_foreach third_party/qemu/util/qemu-option.c:1135:14
30
1109 15:16:20.313405 #8 0x5639b889393c in net_init_clients third_party/qemu/net/net.c:1612:9
31
1109 15:16:20.313407 #9 0x5639b717aaf3 in qemu_create_late_backends third_party/qemu/softmmu/vl.c:1962:5
32
1109 15:16:20.313408 #10 0x5639b717aaf3 in qemu_init third_party/qemu/softmmu/vl.c:3694:5
33
1109 15:16:20.313409 #11 0x5639b71083b8 in main third_party/qemu/softmmu/main.c:49:5
34
1109 15:16:20.313410 #12 0x7f464de1d8d2 in __libc_start_main (/usr/grte/v5/lib64/libc.so.6+0x628d2)
35
1109 15:16:20.313412 #13 0x5639b6bbd389 in _start /usr/grte/v5/debug-src/src/csu/../sysdeps/x86_64/start.S:120
36
1109 15:16:20.313413
37
1109 15:16:20.313417 Uninitialized value was stored to memory at
38
1109 15:16:20.313791 #0 0x5639b88affbd in net_tap_fd_init third_party/qemu/net/tap.c:400:26
39
1109 15:16:20.313826 #1 0x5639b88b2d1b in net_init_tap_one third_party/qemu/net/tap.c:681:19
40
1109 15:16:20.313829 #2 0x5639b88b16a8 in net_init_tap third_party/qemu/net/tap.c:912:13
41
1109 15:16:20.313831 #3 0x5639b8890175 in net_client_init1 third_party/qemu/net/net.c:1110:9
42
1109 15:16:20.313836 #4 0x5639b888f912 in net_client_init third_party/qemu/net/net.c:1208:15
43
1109 15:16:20.313838 #5 0x5639b8894aa5 in net_param_nic third_party/qemu/net/net.c:1588:11
44
1109 15:16:20.313839 #6 0x5639b900cd18 in qemu_opts_foreach third_party/qemu/util/qemu-option.c:1135:14
45
1109 15:16:20.313841 #7 0x5639b889393c in net_init_clients third_party/qemu/net/net.c:1612:9
46
1109 15:16:20.313843 #8 0x5639b717aaf3 in qemu_create_late_backends third_party/qemu/softmmu/vl.c:1962:5
47
1109 15:16:20.313844 #9 0x5639b717aaf3 in qemu_init third_party/qemu/softmmu/vl.c:3694:5
48
1109 15:16:20.313845 #10 0x5639b71083b8 in main third_party/qemu/softmmu/main.c:49:5
49
1109 15:16:20.313846 #11 0x7f464de1d8d2 in __libc_start_main (/usr/grte/v5/lib64/libc.so.6+0x628d2)
50
1109 15:16:20.313847 #12 0x5639b6bbd389 in _start /usr/grte/v5/debug-src/src/csu/../sysdeps/x86_64/start.S:120
51
1109 15:16:20.313849
52
1109 15:16:20.313851 Uninitialized value was created by an allocation of 'ifr' in the stack frame of function 'tap_probe_vnet_hdr'
53
1109 15:16:20.313855 #0 0x5639b88ac680 in tap_probe_vnet_hdr third_party/qemu/net/tap-linux.c:151
54
1109 15:16:20.313856
55
1109 15:16:20.313878 SUMMARY: MemorySanitizer: use-of-uninitialized-value third_party/qemu/net/tap-linux.c:183:9 in tap_probe_vnet_hdr_len
56
57
Fixes: dc69004c7d8 ("net: move tap_probe_vnet_hdr() to tap-linux.c")
58
Reviewed-by: Hao Wu <wuhaotsh@google.com>
59
Reviewed-by: Patrick Venture <venture@google.com>
60
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
61
Signed-off-by: Peter Foley <pefoley@google.com>
62
Signed-off-by: Jason Wang <jasowang@redhat.com>
63
---
64
net/tap-linux.c | 1 +
65
1 file changed, 1 insertion(+)
66
67
diff --git a/net/tap-linux.c b/net/tap-linux.c
68
index XXXXXXX..XXXXXXX 100644
69
--- a/net/tap-linux.c
70
+++ b/net/tap-linux.c
71
@@ -XXX,XX +XXX,XX @@ void tap_set_sndbuf(int fd, const NetdevTapOptions *tap, Error **errp)
72
int tap_probe_vnet_hdr(int fd, Error **errp)
73
{
74
struct ifreq ifr;
75
+ memset(&ifr, 0, sizeof(ifr));
76
77
if (ioctl(fd, TUNGETIFF, &ifr) != 0) {
78
/* TUNGETIFF is available since kernel v2.6.27 */
79
--
80
2.7.4
81
82
diff view generated by jsdifflib
New patch
1
From: Zhang Chen <chen.zhang@intel.com>
1
2
3
COLO-compare use the glib function g_queue_find_custom to dump
4
another VM's networking packet to compare. But this function always
5
start find from the queue->head(here is the newest packet), It will
6
reduce the success rate of comparison. So this patch reversed
7
the order of the queues for performance.
8
9
Signed-off-by: Zhang Chen <chen.zhang@intel.com>
10
Reported-by: leirao <lei.rao@intel.com>
11
Signed-off-by: Jason Wang <jasowang@redhat.com>
12
---
13
net/colo-compare.c | 26 +++++++++++++-------------
14
1 file changed, 13 insertions(+), 13 deletions(-)
15
16
diff --git a/net/colo-compare.c b/net/colo-compare.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/net/colo-compare.c
19
+++ b/net/colo-compare.c
20
@@ -XXX,XX +XXX,XX @@ static void colo_compare_inconsistency_notify(CompareState *s)
21
/* Use restricted to colo_insert_packet() */
22
static gint seq_sorter(Packet *a, Packet *b, gpointer data)
23
{
24
- return a->tcp_seq - b->tcp_seq;
25
+ return b->tcp_seq - a->tcp_seq;
26
}
27
28
static void fill_pkt_tcp_info(void *data, uint32_t *max_ack)
29
@@ -XXX,XX +XXX,XX @@ pri:
30
if (g_queue_is_empty(&conn->primary_list)) {
31
return;
32
}
33
- ppkt = g_queue_pop_head(&conn->primary_list);
34
+ ppkt = g_queue_pop_tail(&conn->primary_list);
35
sec:
36
if (g_queue_is_empty(&conn->secondary_list)) {
37
- g_queue_push_head(&conn->primary_list, ppkt);
38
+ g_queue_push_tail(&conn->primary_list, ppkt);
39
return;
40
}
41
- spkt = g_queue_pop_head(&conn->secondary_list);
42
+ spkt = g_queue_pop_tail(&conn->secondary_list);
43
44
if (ppkt->tcp_seq == ppkt->seq_end) {
45
colo_release_primary_pkt(s, ppkt);
46
@@ -XXX,XX +XXX,XX @@ sec:
47
}
48
}
49
if (!ppkt) {
50
- g_queue_push_head(&conn->secondary_list, spkt);
51
+ g_queue_push_tail(&conn->secondary_list, spkt);
52
goto pri;
53
}
54
}
55
@@ -XXX,XX +XXX,XX @@ sec:
56
if (mark == COLO_COMPARE_FREE_PRIMARY) {
57
conn->compare_seq = ppkt->seq_end;
58
colo_release_primary_pkt(s, ppkt);
59
- g_queue_push_head(&conn->secondary_list, spkt);
60
+ g_queue_push_tail(&conn->secondary_list, spkt);
61
goto pri;
62
} else if (mark == COLO_COMPARE_FREE_SECONDARY) {
63
conn->compare_seq = spkt->seq_end;
64
@@ -XXX,XX +XXX,XX @@ sec:
65
goto pri;
66
}
67
} else {
68
- g_queue_push_head(&conn->primary_list, ppkt);
69
- g_queue_push_head(&conn->secondary_list, spkt);
70
+ g_queue_push_tail(&conn->primary_list, ppkt);
71
+ g_queue_push_tail(&conn->secondary_list, spkt);
72
73
#ifdef DEBUG_COLO_PACKETS
74
qemu_hexdump(stderr, "colo-compare ppkt", ppkt->data, ppkt->size);
75
@@ -XXX,XX +XXX,XX @@ static void colo_compare_packet(CompareState *s, Connection *conn,
76
77
while (!g_queue_is_empty(&conn->primary_list) &&
78
!g_queue_is_empty(&conn->secondary_list)) {
79
- pkt = g_queue_pop_head(&conn->primary_list);
80
+ pkt = g_queue_pop_tail(&conn->primary_list);
81
result = g_queue_find_custom(&conn->secondary_list,
82
pkt, (GCompareFunc)HandlePacket);
83
84
@@ -XXX,XX +XXX,XX @@ static void colo_compare_packet(CompareState *s, Connection *conn,
85
* timeout, it will trigger a checkpoint request.
86
*/
87
trace_colo_compare_main("packet different");
88
- g_queue_push_head(&conn->primary_list, pkt);
89
+ g_queue_push_tail(&conn->primary_list, pkt);
90
91
colo_compare_inconsistency_notify(s);
92
break;
93
@@ -XXX,XX +XXX,XX @@ static int compare_chr_send(CompareState *s,
94
entry->buf = g_malloc(size);
95
memcpy(entry->buf, buf, size);
96
}
97
- g_queue_push_head(&sendco->send_list, entry);
98
+ g_queue_push_tail(&sendco->send_list, entry);
99
100
if (sendco->done) {
101
sendco->co = qemu_coroutine_create(_compare_chr_send, sendco);
102
@@ -XXX,XX +XXX,XX @@ static void colo_flush_packets(void *opaque, void *user_data)
103
Packet *pkt = NULL;
104
105
while (!g_queue_is_empty(&conn->primary_list)) {
106
- pkt = g_queue_pop_head(&conn->primary_list);
107
+ pkt = g_queue_pop_tail(&conn->primary_list);
108
compare_chr_send(s,
109
pkt->data,
110
pkt->size,
111
@@ -XXX,XX +XXX,XX @@ static void colo_flush_packets(void *opaque, void *user_data)
112
packet_destroy_partial(pkt, NULL);
113
}
114
while (!g_queue_is_empty(&conn->secondary_list)) {
115
- pkt = g_queue_pop_head(&conn->secondary_list);
116
+ pkt = g_queue_pop_tail(&conn->secondary_list);
117
packet_destroy(pkt, NULL);
118
}
119
}
120
--
121
2.7.4
122
123
diff view generated by jsdifflib
New patch
1
From: Zhang Chen <chen.zhang@intel.com>
1
2
3
Make the comments consistent with the REGULAR_PACKET_CHECK_MS.
4
5
Signed-off-by: Zhang Chen <chen.zhang@intel.com>
6
Signed-off-by: Jason Wang <jasowang@redhat.com>
7
---
8
net/colo-compare.c | 2 +-
9
1 file changed, 1 insertion(+), 1 deletion(-)
10
11
diff --git a/net/colo-compare.c b/net/colo-compare.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/net/colo-compare.c
14
+++ b/net/colo-compare.c
15
@@ -XXX,XX +XXX,XX @@ static void colo_compare_complete(UserCreatable *uc, Error **errp)
16
}
17
18
if (!s->expired_scan_cycle) {
19
- /* Set default value to 3000 MS */
20
+ /* Set default value to 1000 MS */
21
s->expired_scan_cycle = REGULAR_PACKET_CHECK_MS;
22
}
23
24
--
25
2.7.4
26
27
diff view generated by jsdifflib
1
From: Yuri Benditovich <yuri.benditovich@daynix.com>
1
From: Rao Lei <lei.rao@intel.com>
2
2
3
https://bugzilla.redhat.com/show_bug.cgi?id=1829272
3
This patch is to improve the logic of QEMU main thread sleep code in
4
When deleting queue pair, purge pending RX packets if any.
4
qemu_chr_write_buffer() where it can be blocked and can't run other
5
Example of problematic flow:
5
coroutines during COLO IO stress test.
6
1. Bring up q35 VM with tap (vhost off) and virtio-net or e1000e
7
2. Run ping flood to the VM NIC ( 1 ms interval)
8
3. Hot unplug the NIC device (device_del)
9
During unplug process one or more packets come, the NIC
10
can't receive, tap disables read_poll
11
4. Hot plug the device (device_add) with the same netdev
12
The tap stays with read_poll disabled and does not receive
13
any packets anymore (tap_send never triggered)
14
6
15
Signed-off-by: Yuri Benditovich <yuri.benditovich@daynix.com>
7
Our approach is to put filter_send() in a coroutine. In this way,
8
filter_send() will call qemu_coroutine_yield() in qemu_co_sleep_ns(),
9
so that it can be scheduled out and QEMU main thread has opportunity to
10
run other tasks.
11
12
Signed-off-by: Lei Rao <lei.rao@intel.com>
13
Signed-off-by: Zhang Chen <chen.zhang@intel.com>
14
Reviewed-by: Li Zhijian <lizhijian@fujitsu.com>
15
Reviewed-by: Zhang Chen <chen.zhang@intel.com>
16
Signed-off-by: Jason Wang <jasowang@redhat.com>
16
Signed-off-by: Jason Wang <jasowang@redhat.com>
17
---
17
---
18
net/net.c | 12 ++++++++----
18
net/filter-mirror.c | 66 ++++++++++++++++++++++++++++++++++++++++++-----------
19
1 file changed, 8 insertions(+), 4 deletions(-)
19
1 file changed, 53 insertions(+), 13 deletions(-)
20
20
21
diff --git a/net/net.c b/net/net.c
21
diff --git a/net/filter-mirror.c b/net/filter-mirror.c
22
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
23
--- a/net/net.c
23
--- a/net/filter-mirror.c
24
+++ b/net/net.c
24
+++ b/net/filter-mirror.c
25
@@ -XXX,XX +XXX,XX @@ void qemu_del_nic(NICState *nic)
25
@@ -XXX,XX +XXX,XX @@
26
26
#include "chardev/char-fe.h"
27
qemu_macaddr_set_free(&nic->conf->macaddr);
27
#include "qemu/iov.h"
28
28
#include "qemu/sockets.h"
29
- /* If this is a peer NIC and peer has already been deleted, free it now. */
29
+#include "block/aio-wait.h"
30
- if (nic->peer_deleted) {
30
31
- for (i = 0; i < queues; i++) {
31
#define TYPE_FILTER_MIRROR "filter-mirror"
32
- qemu_free_net_client(qemu_get_subqueue(nic, i)->peer);
32
typedef struct MirrorState MirrorState;
33
+ for (i = 0; i < queues; i++) {
33
@@ -XXX,XX +XXX,XX @@ struct MirrorState {
34
+ NetClientState *nc = qemu_get_subqueue(nic, i);
34
bool vnet_hdr;
35
+ /* If this is a peer NIC and peer has already been deleted, free it now. */
35
};
36
+ if (nic->peer_deleted) {
36
37
+ qemu_free_net_client(nc->peer);
37
-static int filter_send(MirrorState *s,
38
+ } else if (nc->peer) {
38
- const struct iovec *iov,
39
+ /* if there are RX packets pending, complete them */
39
- int iovcnt)
40
+ qemu_purge_queued_packets(nc->peer);
40
+typedef struct FilterSendCo {
41
+ MirrorState *s;
42
+ char *buf;
43
+ ssize_t size;
44
+ bool done;
45
+ int ret;
46
+} FilterSendCo;
47
+
48
+static int _filter_send(MirrorState *s,
49
+ char *buf,
50
+ ssize_t size)
51
{
52
NetFilterState *nf = NETFILTER(s);
53
int ret = 0;
54
- ssize_t size = 0;
55
uint32_t len = 0;
56
- char *buf;
57
-
58
- size = iov_size(iov, iovcnt);
59
- if (!size) {
60
- return 0;
61
- }
62
63
len = htonl(size);
64
ret = qemu_chr_fe_write_all(&s->chr_out, (uint8_t *)&len, sizeof(len));
65
@@ -XXX,XX +XXX,XX @@ static int filter_send(MirrorState *s,
41
}
66
}
42
}
67
}
43
68
69
- buf = g_malloc(size);
70
- iov_to_buf(iov, iovcnt, 0, buf, size);
71
ret = qemu_chr_fe_write_all(&s->chr_out, (uint8_t *)buf, size);
72
- g_free(buf);
73
if (ret != size) {
74
goto err;
75
}
76
@@ -XXX,XX +XXX,XX @@ err:
77
return ret < 0 ? ret : -EIO;
78
}
79
80
+static void coroutine_fn filter_send_co(void *opaque)
81
+{
82
+ FilterSendCo *data = opaque;
83
+
84
+ data->ret = _filter_send(data->s, data->buf, data->size);
85
+ data->done = true;
86
+ g_free(data->buf);
87
+ aio_wait_kick();
88
+}
89
+
90
+static int filter_send(MirrorState *s,
91
+ const struct iovec *iov,
92
+ int iovcnt)
93
+{
94
+ ssize_t size = iov_size(iov, iovcnt);
95
+ char *buf = NULL;
96
+
97
+ if (!size) {
98
+ return 0;
99
+ }
100
+
101
+ buf = g_malloc(size);
102
+ iov_to_buf(iov, iovcnt, 0, buf, size);
103
+
104
+ FilterSendCo data = {
105
+ .s = s,
106
+ .size = size,
107
+ .buf = buf,
108
+ .ret = 0,
109
+ };
110
+
111
+ Coroutine *co = qemu_coroutine_create(filter_send_co, &data);
112
+ qemu_coroutine_enter(co);
113
+
114
+ while (!data.done) {
115
+ aio_poll(qemu_get_aio_context(), true);
116
+ }
117
+
118
+ return data.ret;
119
+}
120
+
121
static void redirector_to_filter(NetFilterState *nf,
122
const uint8_t *buf,
123
int len)
44
--
124
--
45
2.7.4
125
2.7.4
46
126
47
127
diff view generated by jsdifflib
New patch
1
From: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
1
2
3
Signed-off-by: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
4
Signed-off-by: Jason Wang <jasowang@redhat.com>
5
---
6
meson.build | 4 ++++
7
meson_options.txt | 2 ++
8
scripts/meson-buildoptions.sh | 3 +++
9
3 files changed, 9 insertions(+)
10
11
diff --git a/meson.build b/meson.build
12
index XXXXXXX..XXXXXXX 100644
13
--- a/meson.build
14
+++ b/meson.build
15
@@ -XXX,XX +XXX,XX @@ if cocoa.found() and get_option('gtk').enabled()
16
error('Cocoa and GTK+ cannot be enabled at the same time')
17
endif
18
19
+vmnet = dependency('appleframeworks', modules: 'vmnet', required: get_option('vmnet'))
20
+
21
seccomp = not_found
22
if not get_option('seccomp').auto() or have_system or have_tools
23
seccomp = dependency('libseccomp', version: '>=2.3.0',
24
@@ -XXX,XX +XXX,XX @@ config_host_data.set('CONFIG_SECCOMP', seccomp.found())
25
config_host_data.set('CONFIG_SNAPPY', snappy.found())
26
config_host_data.set('CONFIG_USB_LIBUSB', libusb.found())
27
config_host_data.set('CONFIG_VDE', vde.found())
28
+config_host_data.set('CONFIG_VMNET', vmnet.found())
29
config_host_data.set('CONFIG_VHOST_USER_BLK_SERVER', have_vhost_user_blk_server)
30
config_host_data.set('CONFIG_VNC', vnc.found())
31
config_host_data.set('CONFIG_VNC_JPEG', jpeg.found())
32
@@ -XXX,XX +XXX,XX @@ endif
33
summary_info += {'JACK support': jack}
34
summary_info += {'brlapi support': brlapi}
35
summary_info += {'vde support': vde}
36
+summary_info += {'vmnet.framework support': vmnet}
37
summary_info += {'netmap support': have_netmap}
38
summary_info += {'l2tpv3 support': have_l2tpv3}
39
summary_info += {'Linux AIO support': libaio}
40
diff --git a/meson_options.txt b/meson_options.txt
41
index XXXXXXX..XXXXXXX 100644
42
--- a/meson_options.txt
43
+++ b/meson_options.txt
44
@@ -XXX,XX +XXX,XX @@ option('netmap', type : 'feature', value : 'auto',
45
description: 'netmap network backend support')
46
option('vde', type : 'feature', value : 'auto',
47
description: 'vde network backend support')
48
+option('vmnet', type : 'feature', value : 'auto',
49
+ description: 'vmnet.framework network backend support')
50
option('virglrenderer', type : 'feature', value : 'auto',
51
description: 'virgl rendering support')
52
option('vnc', type : 'feature', value : 'auto',
53
diff --git a/scripts/meson-buildoptions.sh b/scripts/meson-buildoptions.sh
54
index XXXXXXX..XXXXXXX 100644
55
--- a/scripts/meson-buildoptions.sh
56
+++ b/scripts/meson-buildoptions.sh
57
@@ -XXX,XX +XXX,XX @@ meson_options_help() {
58
printf "%s\n" ' u2f U2F emulation support'
59
printf "%s\n" ' usb-redir libusbredir support'
60
printf "%s\n" ' vde vde network backend support'
61
+ printf "%s\n" ' vmnet vmnet.framework network backend support'
62
printf "%s\n" ' vhost-user-blk-server'
63
printf "%s\n" ' build vhost-user-blk server'
64
printf "%s\n" ' virglrenderer virgl rendering support'
65
@@ -XXX,XX +XXX,XX @@ _meson_option_parse() {
66
--disable-usb-redir) printf "%s" -Dusb_redir=disabled ;;
67
--enable-vde) printf "%s" -Dvde=enabled ;;
68
--disable-vde) printf "%s" -Dvde=disabled ;;
69
+ --enable-vmnet) printf "%s" -Dvmnet=enabled ;;
70
+ --disable-vmnet) printf "%s" -Dvmnet=disabled ;;
71
--enable-vhost-user-blk-server) printf "%s" -Dvhost_user_blk_server=enabled ;;
72
--disable-vhost-user-blk-server) printf "%s" -Dvhost_user_blk_server=disabled ;;
73
--enable-virglrenderer) printf "%s" -Dvirglrenderer=enabled ;;
74
--
75
2.7.4
76
77
diff view generated by jsdifflib
1
From: Paolo Bonzini <pbonzini@redhat.com>
1
From: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
2
2
3
"netdev_add help" is causing QEMU to exit because the code that
3
The vmnet framework is an API for virtual machines to read and write
4
invokes show_netdevs is shared between CLI and HMP processing.
4
packets.
5
Move the check to the callers so that exit(0) remains only
5
6
in the CLI flow.
6
The API allows a Guest OS interface to be in host mode or shared
7
7
mode. Interfaces in host mode can communicate with the native host
8
"netdev_add help" is not fixed by this patch; that is left for
8
system and other interfaces running in host mode. In shared mode, the
9
later work.
9
network interface can send and receive packets to the Internet, the
10
10
native host, and other interfaces running in sharing mode.
11
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
11
12
Create separate netdevs for each vmnet operating mode:
13
14
- vmnet-host
15
- vmnet-shared
16
- vmnet-bridged
17
18
Signed-off-by: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
12
Signed-off-by: Jason Wang <jasowang@redhat.com>
19
Signed-off-by: Jason Wang <jasowang@redhat.com>
13
---
20
---
14
include/net/net.h | 1 +
21
net/clients.h | 11 +++++
15
monitor/hmp-cmds.c | 6 +++++
22
net/meson.build | 7 +++
16
net/net.c | 68 +++++++++++++++++++++++++++---------------------------
23
net/net.c | 10 ++++
17
3 files changed, 41 insertions(+), 34 deletions(-)
24
net/vmnet-bridged.m | 25 ++++++++++
18
25
net/vmnet-common.m | 19 ++++++++
19
diff --git a/include/net/net.h b/include/net/net.h
26
net/vmnet-host.c | 24 ++++++++++
27
net/vmnet-shared.c | 25 ++++++++++
28
net/vmnet_int.h | 25 ++++++++++
29
qapi/net.json | 132 +++++++++++++++++++++++++++++++++++++++++++++++++++-
30
9 files changed, 276 insertions(+), 2 deletions(-)
31
create mode 100644 net/vmnet-bridged.m
32
create mode 100644 net/vmnet-common.m
33
create mode 100644 net/vmnet-host.c
34
create mode 100644 net/vmnet-shared.c
35
create mode 100644 net/vmnet_int.h
36
37
diff --git a/net/clients.h b/net/clients.h
20
index XXXXXXX..XXXXXXX 100644
38
index XXXXXXX..XXXXXXX 100644
21
--- a/include/net/net.h
39
--- a/net/clients.h
22
+++ b/include/net/net.h
40
+++ b/net/clients.h
23
@@ -XXX,XX +XXX,XX @@ extern const char *host_net_devices[];
41
@@ -XXX,XX +XXX,XX @@ int net_init_vhost_user(const Netdev *netdev, const char *name,
24
42
25
/* from net.c */
43
int net_init_vhost_vdpa(const Netdev *netdev, const char *name,
26
int net_client_parse(QemuOptsList *opts_list, const char *str);
44
NetClientState *peer, Error **errp);
27
+void show_netdevs(void);
45
+#ifdef CONFIG_VMNET
28
int net_init_clients(Error **errp);
46
+int net_init_vmnet_host(const Netdev *netdev, const char *name,
29
void net_check_clients(void);
47
+ NetClientState *peer, Error **errp);
30
void net_cleanup(void);
48
+
31
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
49
+int net_init_vmnet_shared(const Netdev *netdev, const char *name,
50
+ NetClientState *peer, Error **errp);
51
+
52
+int net_init_vmnet_bridged(const Netdev *netdev, const char *name,
53
+ NetClientState *peer, Error **errp);
54
+#endif /* CONFIG_VMNET */
55
+
56
#endif /* QEMU_NET_CLIENTS_H */
57
diff --git a/net/meson.build b/net/meson.build
32
index XXXXXXX..XXXXXXX 100644
58
index XXXXXXX..XXXXXXX 100644
33
--- a/monitor/hmp-cmds.c
59
--- a/net/meson.build
34
+++ b/monitor/hmp-cmds.c
60
+++ b/net/meson.build
35
@@ -XXX,XX +XXX,XX @@
61
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_POSIX', if_true: files(tap_posix))
36
#include "qemu/option.h"
62
softmmu_ss.add(when: 'CONFIG_WIN32', if_true: files('tap-win32.c'))
37
#include "qemu/timer.h"
63
softmmu_ss.add(when: 'CONFIG_VHOST_NET_VDPA', if_true: files('vhost-vdpa.c'))
38
#include "qemu/sockets.h"
64
39
+#include "qemu/help_option.h"
65
+vmnet_files = files(
40
#include "monitor/monitor-internal.h"
66
+ 'vmnet-common.m',
41
#include "qapi/error.h"
67
+ 'vmnet-bridged.m',
42
#include "qapi/clone-visitor.h"
68
+ 'vmnet-host.c',
43
@@ -XXX,XX +XXX,XX @@ void hmp_netdev_add(Monitor *mon, const QDict *qdict)
69
+ 'vmnet-shared.c'
44
{
70
+)
45
Error *err = NULL;
71
+softmmu_ss.add(when: vmnet, if_true: vmnet_files)
46
QemuOpts *opts;
72
subdir('can')
47
+ const char *type = qdict_get_try_str(qdict, "type");
48
49
+ if (type && is_help_option(type)) {
50
+ show_netdevs();
51
+ return;
52
+ }
53
opts = qemu_opts_from_qdict(qemu_find_opts("netdev"), qdict, &err);
54
if (err) {
55
goto out;
56
diff --git a/net/net.c b/net/net.c
73
diff --git a/net/net.c b/net/net.c
57
index XXXXXXX..XXXXXXX 100644
74
index XXXXXXX..XXXXXXX 100644
58
--- a/net/net.c
75
--- a/net/net.c
59
+++ b/net/net.c
76
+++ b/net/net.c
60
@@ -XXX,XX +XXX,XX @@
77
@@ -XXX,XX +XXX,XX @@ static int (* const net_client_init_fun[NET_CLIENT_DRIVER__MAX])(
61
#include "qemu/config-file.h"
78
#ifdef CONFIG_L2TPV3
62
#include "qemu/ctype.h"
79
[NET_CLIENT_DRIVER_L2TPV3] = net_init_l2tpv3,
63
#include "qemu/iov.h"
64
+#include "qemu/qemu-print.h"
65
#include "qemu/main-loop.h"
66
#include "qemu/option.h"
67
#include "qapi/error.h"
68
@@ -XXX,XX +XXX,XX @@ static int net_client_init1(const Netdev *netdev, bool is_netdev, Error **errp)
69
return 0;
70
}
71
72
-static void show_netdevs(void)
73
+void show_netdevs(void)
74
{
75
int idx;
76
const char *available_netdevs[] = {
77
@@ -XXX,XX +XXX,XX @@ static void show_netdevs(void)
78
#endif
80
#endif
81
+#ifdef CONFIG_VMNET
82
+ [NET_CLIENT_DRIVER_VMNET_HOST] = net_init_vmnet_host,
83
+ [NET_CLIENT_DRIVER_VMNET_SHARED] = net_init_vmnet_shared,
84
+ [NET_CLIENT_DRIVER_VMNET_BRIDGED] = net_init_vmnet_bridged,
85
+#endif /* CONFIG_VMNET */
86
};
87
88
89
@@ -XXX,XX +XXX,XX @@ void show_netdevs(void)
90
#ifdef CONFIG_VHOST_VDPA
91
"vhost-vdpa",
92
#endif
93
+#ifdef CONFIG_VMNET
94
+ "vmnet-host",
95
+ "vmnet-shared",
96
+ "vmnet-bridged",
97
+#endif
79
};
98
};
80
99
81
- printf("Available netdev backend types:\n");
100
qemu_printf("Available netdev backend types:\n");
82
+ qemu_printf("Available netdev backend types:\n");
101
diff --git a/net/vmnet-bridged.m b/net/vmnet-bridged.m
83
for (idx = 0; idx < ARRAY_SIZE(available_netdevs); idx++) {
102
new file mode 100644
84
- puts(available_netdevs[idx]);
103
index XXXXXXX..XXXXXXX
85
+ qemu_printf("%s\n", available_netdevs[idx]);
104
--- /dev/null
86
}
105
+++ b/net/vmnet-bridged.m
87
}
106
@@ -XXX,XX +XXX,XX @@
88
107
+/*
89
@@ -XXX,XX +XXX,XX @@ static int net_client_init(QemuOpts *opts, bool is_netdev, Error **errp)
108
+ * vmnet-bridged.m
90
int ret = -1;
109
+ *
91
Visitor *v = opts_visitor_new(opts);
110
+ * Copyright(c) 2021 Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
92
111
+ *
93
- const char *type = qemu_opt_get(opts, "type");
112
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
94
-
113
+ * See the COPYING file in the top-level directory.
95
- if (is_netdev && type && is_help_option(type)) {
114
+ *
96
- show_netdevs();
115
+ */
97
- exit(0);
116
+
98
- } else {
117
+#include "qemu/osdep.h"
99
- /* Parse convenience option format ip6-net=fec0::0[/64] */
118
+#include "qapi/qapi-types-net.h"
100
- const char *ip6_net = qemu_opt_get(opts, "ipv6-net");
119
+#include "vmnet_int.h"
101
+ /* Parse convenience option format ip6-net=fec0::0[/64] */
120
+#include "clients.h"
102
+ const char *ip6_net = qemu_opt_get(opts, "ipv6-net");
121
+#include "qemu/error-report.h"
103
122
+#include "qapi/error.h"
104
- if (ip6_net) {
123
+
105
- char *prefix_addr;
124
+#include <vmnet/vmnet.h>
106
- unsigned long prefix_len = 64; /* Default 64bit prefix length. */
125
+
107
+ if (ip6_net) {
126
+int net_init_vmnet_bridged(const Netdev *netdev, const char *name,
108
+ char *prefix_addr;
127
+ NetClientState *peer, Error **errp)
109
+ unsigned long prefix_len = 64; /* Default 64bit prefix length. */
128
+{
110
129
+ error_setg(errp, "vmnet-bridged is not implemented yet");
111
- substrings = g_strsplit(ip6_net, "/", 2);
130
+ return -1;
112
- if (!substrings || !substrings[0]) {
131
+}
113
- error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "ipv6-net",
132
diff --git a/net/vmnet-common.m b/net/vmnet-common.m
114
- "a valid IPv6 prefix");
133
new file mode 100644
115
- goto out;
134
index XXXXXXX..XXXXXXX
116
- }
135
--- /dev/null
117
+ substrings = g_strsplit(ip6_net, "/", 2);
136
+++ b/net/vmnet-common.m
118
+ if (!substrings || !substrings[0]) {
137
@@ -XXX,XX +XXX,XX @@
119
+ error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "ipv6-net",
138
+/*
120
+ "a valid IPv6 prefix");
139
+ * vmnet-common.m - network client wrapper for Apple vmnet.framework
121
+ goto out;
140
+ *
122
+ }
141
+ * Copyright(c) 2021 Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
123
142
+ * Copyright(c) 2021 Phillip Tennen <phillip@axleos.com>
124
- prefix_addr = substrings[0];
143
+ *
125
+ prefix_addr = substrings[0];
144
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
126
145
+ * See the COPYING file in the top-level directory.
127
- /* Handle user-specified prefix length. */
146
+ *
128
- if (substrings[1] &&
147
+ */
129
- qemu_strtoul(substrings[1], NULL, 10, &prefix_len))
148
+
130
- {
149
+#include "qemu/osdep.h"
131
- error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
150
+#include "qapi/qapi-types-net.h"
132
- "ipv6-prefixlen", "a number");
151
+#include "vmnet_int.h"
133
- goto out;
152
+#include "clients.h"
134
- }
153
+#include "qemu/error-report.h"
135
-
154
+#include "qapi/error.h"
136
- qemu_opt_set(opts, "ipv6-prefix", prefix_addr, &error_abort);
155
+
137
- qemu_opt_set_number(opts, "ipv6-prefixlen", prefix_len,
156
+#include <vmnet/vmnet.h>
138
- &error_abort);
157
diff --git a/net/vmnet-host.c b/net/vmnet-host.c
139
- qemu_opt_unset(opts, "ipv6-net");
158
new file mode 100644
140
+ /* Handle user-specified prefix length. */
159
index XXXXXXX..XXXXXXX
141
+ if (substrings[1] &&
160
--- /dev/null
142
+ qemu_strtoul(substrings[1], NULL, 10, &prefix_len))
161
+++ b/net/vmnet-host.c
143
+ {
162
@@ -XXX,XX +XXX,XX @@
144
+ error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
163
+/*
145
+ "ipv6-prefixlen", "a number");
164
+ * vmnet-host.c
146
+ goto out;
165
+ *
147
}
166
+ * Copyright(c) 2021 Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
148
+
167
+ *
149
+ qemu_opt_set(opts, "ipv6-prefix", prefix_addr, &error_abort);
168
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
150
+ qemu_opt_set_number(opts, "ipv6-prefixlen", prefix_len,
169
+ * See the COPYING file in the top-level directory.
151
+ &error_abort);
170
+ *
152
+ qemu_opt_unset(opts, "ipv6-net");
171
+ */
153
}
172
+
154
173
+#include "qemu/osdep.h"
155
/* Create an ID for -net if the user did not specify one */
174
+#include "qapi/qapi-types-net.h"
156
@@ -XXX,XX +XXX,XX @@ static int net_init_client(void *dummy, QemuOpts *opts, Error **errp)
175
+#include "vmnet_int.h"
157
176
+#include "clients.h"
158
static int net_init_netdev(void *dummy, QemuOpts *opts, Error **errp)
177
+#include "qemu/error-report.h"
159
{
178
+#include "qapi/error.h"
160
+ const char *type = qemu_opt_get(opts, "type");
179
+
161
+
180
+#include <vmnet/vmnet.h>
162
+ if (type && is_help_option(type)) {
181
+
163
+ show_netdevs();
182
+int net_init_vmnet_host(const Netdev *netdev, const char *name,
164
+ exit(0);
183
+ NetClientState *peer, Error **errp) {
165
+ }
184
+ error_setg(errp, "vmnet-host is not implemented yet");
166
return net_client_init(opts, true, errp);
185
+ return -1;
167
}
186
+}
168
187
diff --git a/net/vmnet-shared.c b/net/vmnet-shared.c
188
new file mode 100644
189
index XXXXXXX..XXXXXXX
190
--- /dev/null
191
+++ b/net/vmnet-shared.c
192
@@ -XXX,XX +XXX,XX @@
193
+/*
194
+ * vmnet-shared.c
195
+ *
196
+ * Copyright(c) 2021 Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
197
+ *
198
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
199
+ * See the COPYING file in the top-level directory.
200
+ *
201
+ */
202
+
203
+#include "qemu/osdep.h"
204
+#include "qapi/qapi-types-net.h"
205
+#include "vmnet_int.h"
206
+#include "clients.h"
207
+#include "qemu/error-report.h"
208
+#include "qapi/error.h"
209
+
210
+#include <vmnet/vmnet.h>
211
+
212
+int net_init_vmnet_shared(const Netdev *netdev, const char *name,
213
+ NetClientState *peer, Error **errp)
214
+{
215
+ error_setg(errp, "vmnet-shared is not implemented yet");
216
+ return -1;
217
+}
218
diff --git a/net/vmnet_int.h b/net/vmnet_int.h
219
new file mode 100644
220
index XXXXXXX..XXXXXXX
221
--- /dev/null
222
+++ b/net/vmnet_int.h
223
@@ -XXX,XX +XXX,XX @@
224
+/*
225
+ * vmnet_int.h
226
+ *
227
+ * Copyright(c) 2021 Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
228
+ *
229
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
230
+ * See the COPYING file in the top-level directory.
231
+ *
232
+ */
233
+#ifndef VMNET_INT_H
234
+#define VMNET_INT_H
235
+
236
+#include "qemu/osdep.h"
237
+#include "vmnet_int.h"
238
+#include "clients.h"
239
+
240
+#include <vmnet/vmnet.h>
241
+
242
+typedef struct VmnetCommonState {
243
+ NetClientState nc;
244
+
245
+} VmnetCommonState;
246
+
247
+
248
+#endif /* VMNET_INT_H */
249
diff --git a/qapi/net.json b/qapi/net.json
250
index XXXXXXX..XXXXXXX 100644
251
--- a/qapi/net.json
252
+++ b/qapi/net.json
253
@@ -XXX,XX +XXX,XX @@
254
'*queues': 'int' } }
255
256
##
257
+# @NetdevVmnetHostOptions:
258
+#
259
+# vmnet (host mode) network backend.
260
+#
261
+# Allows the vmnet interface to communicate with other vmnet
262
+# interfaces that are in host mode and also with the host.
263
+#
264
+# @start-address: The starting IPv4 address to use for the interface.
265
+# Must be in the private IP range (RFC 1918). Must be
266
+# specified along with @end-address and @subnet-mask.
267
+# This address is used as the gateway address. The
268
+# subsequent address up to and including end-address are
269
+# placed in the DHCP pool.
270
+#
271
+# @end-address: The DHCP IPv4 range end address to use for the
272
+# interface. Must be in the private IP range (RFC 1918).
273
+# Must be specified along with @start-address and
274
+# @subnet-mask.
275
+#
276
+# @subnet-mask: The IPv4 subnet mask to use on the interface. Must
277
+# be specified along with @start-address and @subnet-mask.
278
+#
279
+# @isolated: Enable isolation for this interface. Interface isolation
280
+# ensures that vmnet interface is not able to communicate
281
+# with any other vmnet interfaces. Only communication with
282
+# host is allowed.
283
+#
284
+# @net-uuid: The identifier (UUID) to uniquely identify the isolated
285
+# network vmnet interface should be added to. If
286
+# set, no DHCP service is provided for this interface and
287
+# network communication is allowed only with other interfaces
288
+# added to this network identified by the UUID.
289
+#
290
+# Since: 7.0
291
+##
292
+{ 'struct': 'NetdevVmnetHostOptions',
293
+ 'data': {
294
+ '*start-address': 'str',
295
+ '*end-address': 'str',
296
+ '*subnet-mask': 'str',
297
+ '*isolated': 'bool',
298
+ '*net-uuid': 'str' },
299
+ 'if': 'CONFIG_VMNET' }
300
+
301
+##
302
+# @NetdevVmnetSharedOptions:
303
+#
304
+# vmnet (shared mode) network backend.
305
+#
306
+# Allows traffic originating from the vmnet interface to reach the
307
+# Internet through a network address translator (NAT).
308
+# The vmnet interface can communicate with the host and with
309
+# other shared mode interfaces on the same subnet. If no DHCP
310
+# settings, subnet mask and IPv6 prefix specified, the interface can
311
+# communicate with any of other interfaces in shared mode.
312
+#
313
+# @start-address: The starting IPv4 address to use for the interface.
314
+# Must be in the private IP range (RFC 1918). Must be
315
+# specified along with @end-address and @subnet-mask.
316
+# This address is used as the gateway address. The
317
+# subsequent address up to and including end-address are
318
+# placed in the DHCP pool.
319
+#
320
+# @end-address: The DHCP IPv4 range end address to use for the
321
+# interface. Must be in the private IP range (RFC 1918).
322
+# Must be specified along with @start-address and @subnet-mask.
323
+#
324
+# @subnet-mask: The IPv4 subnet mask to use on the interface. Must
325
+# be specified along with @start-address and @subnet-mask.
326
+#
327
+# @isolated: Enable isolation for this interface. Interface isolation
328
+# ensures that vmnet interface is not able to communicate
329
+# with any other vmnet interfaces. Only communication with
330
+# host is allowed.
331
+#
332
+# @nat66-prefix: The IPv6 prefix to use into guest network. Must be a
333
+# unique local address i.e. start with fd00::/8 and have
334
+# length of 64.
335
+#
336
+# Since: 7.0
337
+##
338
+{ 'struct': 'NetdevVmnetSharedOptions',
339
+ 'data': {
340
+ '*start-address': 'str',
341
+ '*end-address': 'str',
342
+ '*subnet-mask': 'str',
343
+ '*isolated': 'bool',
344
+ '*nat66-prefix': 'str' },
345
+ 'if': 'CONFIG_VMNET' }
346
+
347
+##
348
+# @NetdevVmnetBridgedOptions:
349
+#
350
+# vmnet (bridged mode) network backend.
351
+#
352
+# Bridges the vmnet interface with a physical network interface.
353
+#
354
+# @ifname: The name of the physical interface to be bridged.
355
+#
356
+# @isolated: Enable isolation for this interface. Interface isolation
357
+# ensures that vmnet interface is not able to communicate
358
+# with any other vmnet interfaces. Only communication with
359
+# host is allowed.
360
+#
361
+# Since: 7.0
362
+##
363
+{ 'struct': 'NetdevVmnetBridgedOptions',
364
+ 'data': {
365
+ 'ifname': 'str',
366
+ '*isolated': 'str' },
367
+ 'if': 'CONFIG_VMNET' }
368
+
369
+##
370
# @NetClientDriver:
371
#
372
# Available netdev drivers.
373
@@ -XXX,XX +XXX,XX @@
374
# Since: 2.7
375
#
376
# @vhost-vdpa since 5.1
377
+# @vmnet-host since 7.0
378
+# @vmnet-shared since 7.0
379
+# @vmnet-bridged since 7.0
380
##
381
{ 'enum': 'NetClientDriver',
382
'data': [ 'none', 'nic', 'user', 'tap', 'l2tpv3', 'socket', 'vde',
383
- 'bridge', 'hubport', 'netmap', 'vhost-user', 'vhost-vdpa' ] }
384
+ 'bridge', 'hubport', 'netmap', 'vhost-user', 'vhost-vdpa',
385
+ { 'name': 'vmnet-host', 'if': 'CONFIG_VMNET' },
386
+ { 'name': 'vmnet-shared', 'if': 'CONFIG_VMNET' },
387
+ { 'name': 'vmnet-bridged', 'if': 'CONFIG_VMNET' }] }
388
389
##
390
# @Netdev:
391
@@ -XXX,XX +XXX,XX @@
392
# Since: 1.2
393
#
394
# 'l2tpv3' - since 2.1
395
+# 'vmnet-host' - since 7.0
396
+# 'vmnet-shared' - since 7.0
397
+# 'vmnet-bridged' - since 7.0
398
##
399
{ 'union': 'Netdev',
400
'base': { 'id': 'str', 'type': 'NetClientDriver' },
401
@@ -XXX,XX +XXX,XX @@
402
'hubport': 'NetdevHubPortOptions',
403
'netmap': 'NetdevNetmapOptions',
404
'vhost-user': 'NetdevVhostUserOptions',
405
- 'vhost-vdpa': 'NetdevVhostVDPAOptions' } }
406
+ 'vhost-vdpa': 'NetdevVhostVDPAOptions',
407
+ 'vmnet-host': { 'type': 'NetdevVmnetHostOptions',
408
+ 'if': 'CONFIG_VMNET' },
409
+ 'vmnet-shared': { 'type': 'NetdevVmnetSharedOptions',
410
+ 'if': 'CONFIG_VMNET' },
411
+ 'vmnet-bridged': { 'type': 'NetdevVmnetBridgedOptions',
412
+ 'if': 'CONFIG_VMNET' } } }
413
414
##
415
# @RxState:
169
--
416
--
170
2.7.4
417
2.7.4
171
418
172
419
diff view generated by jsdifflib
New patch
1
1
From: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
2
3
Interaction with vmnet.framework in different modes
4
differs only on configuration stage, so we can create
5
common `send`, `receive`, etc. procedures and reuse them.
6
7
vmnet.framework supports iov, but writing more than
8
one iov into vmnet interface fails with
9
'VMNET_INVALID_ARGUMENT'. Collecting provided iovs into
10
one and passing it to vmnet works fine. That's the
11
reason why receive_iov() left unimplemented. But it still
12
works with good enough performance having .receive()
13
implemented only.
14
15
Also, there is no way to unsubscribe from vmnet packages
16
receiving except registering and unregistering event
17
callback or simply drop packages just ignoring and
18
not processing them when related flag is set. Here we do
19
using the second way.
20
21
Signed-off-by: Phillip Tennen <phillip@axleos.com>
22
Signed-off-by: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
23
Signed-off-by: Jason Wang <jasowang@redhat.com>
24
---
25
net/vmnet-common.m | 311 +++++++++++++++++++++++++++++++++++++++++++++++++++++
26
net/vmnet-shared.c | 74 ++++++++++++-
27
net/vmnet_int.h | 23 ++++
28
3 files changed, 404 insertions(+), 4 deletions(-)
29
30
diff --git a/net/vmnet-common.m b/net/vmnet-common.m
31
index XXXXXXX..XXXXXXX 100644
32
--- a/net/vmnet-common.m
33
+++ b/net/vmnet-common.m
34
@@ -XXX,XX +XXX,XX @@
35
*/
36
37
#include "qemu/osdep.h"
38
+#include "qemu/main-loop.h"
39
+#include "qemu/log.h"
40
#include "qapi/qapi-types-net.h"
41
#include "vmnet_int.h"
42
#include "clients.h"
43
@@ -XXX,XX +XXX,XX @@
44
#include "qapi/error.h"
45
46
#include <vmnet/vmnet.h>
47
+#include <dispatch/dispatch.h>
48
+
49
+#ifdef DEBUG
50
+#define D(x) x
51
+#define D_LOG(...) qemu_log(__VA_ARGS__)
52
+#else
53
+#define D(x) do { } while (0)
54
+#define D_LOG(...) do { } while (0)
55
+#endif
56
+
57
+typedef struct vmpktdesc vmpktdesc_t;
58
+typedef struct iovec iovec_t;
59
+
60
+static void vmnet_set_send_enabled(VmnetCommonState *s, bool enable)
61
+{
62
+ s->send_enabled = enable;
63
+}
64
+
65
+
66
+static void vmnet_send_completed(NetClientState *nc, ssize_t len)
67
+{
68
+ VmnetCommonState *s = DO_UPCAST(VmnetCommonState, nc, nc);
69
+ vmnet_set_send_enabled(s, true);
70
+}
71
+
72
+
73
+static void vmnet_send(NetClientState *nc,
74
+ interface_event_t event_id,
75
+ xpc_object_t event)
76
+{
77
+ assert(event_id == VMNET_INTERFACE_PACKETS_AVAILABLE);
78
+
79
+ VmnetCommonState *s;
80
+ uint64_t packets_available;
81
+
82
+ struct iovec *iov;
83
+ struct vmpktdesc *packets;
84
+ int pkt_cnt;
85
+ int i;
86
+
87
+ vmnet_return_t if_status;
88
+ ssize_t size;
89
+
90
+ s = DO_UPCAST(VmnetCommonState, nc, nc);
91
+
92
+ packets_available = xpc_dictionary_get_uint64(
93
+ event,
94
+ vmnet_estimated_packets_available_key
95
+ );
96
+
97
+ pkt_cnt = (packets_available < VMNET_PACKETS_LIMIT) ?
98
+ packets_available :
99
+ VMNET_PACKETS_LIMIT;
100
+
101
+
102
+ iov = s->iov_buf;
103
+ packets = s->packets_buf;
104
+
105
+ for (i = 0; i < pkt_cnt; ++i) {
106
+ packets[i].vm_pkt_size = s->max_packet_size;
107
+ packets[i].vm_pkt_iovcnt = 1;
108
+ packets[i].vm_flags = 0;
109
+ }
110
+
111
+ if_status = vmnet_read(s->vmnet_if, packets, &pkt_cnt);
112
+ if (if_status != VMNET_SUCCESS) {
113
+ error_printf("vmnet: read failed: %s\n",
114
+ vmnet_status_map_str(if_status));
115
+ }
116
+ qemu_mutex_lock_iothread();
117
+ for (i = 0; i < pkt_cnt; ++i) {
118
+ size = qemu_send_packet_async(nc,
119
+ iov[i].iov_base,
120
+ packets[i].vm_pkt_size,
121
+ vmnet_send_completed);
122
+ if (size == 0) {
123
+ vmnet_set_send_enabled(s, false);
124
+ } else if (size < 0) {
125
+ break;
126
+ }
127
+ }
128
+ qemu_mutex_unlock_iothread();
129
+
130
+}
131
+
132
+
133
+static void vmnet_register_event_callback(VmnetCommonState *s)
134
+{
135
+ dispatch_queue_t avail_pkt_q = dispatch_queue_create(
136
+ "org.qemu.vmnet.if_queue",
137
+ DISPATCH_QUEUE_SERIAL
138
+ );
139
+
140
+ vmnet_interface_set_event_callback(
141
+ s->vmnet_if,
142
+ VMNET_INTERFACE_PACKETS_AVAILABLE,
143
+ avail_pkt_q,
144
+ ^(interface_event_t event_id, xpc_object_t event) {
145
+ if (s->send_enabled) {
146
+ vmnet_send(&s->nc, event_id, event);
147
+ }
148
+ });
149
+}
150
+
151
+
152
+static void vmnet_bufs_init(VmnetCommonState *s)
153
+{
154
+ int i;
155
+ struct vmpktdesc *packets;
156
+ struct iovec *iov;
157
+
158
+ packets = s->packets_buf;
159
+ iov = s->iov_buf;
160
+
161
+ for (i = 0; i < VMNET_PACKETS_LIMIT; ++i) {
162
+ iov[i].iov_len = s->max_packet_size;
163
+ iov[i].iov_base = g_malloc0(iov[i].iov_len);
164
+ packets[i].vm_pkt_iov = iov + i;
165
+ }
166
+}
167
+
168
+
169
+const char *vmnet_status_map_str(vmnet_return_t status)
170
+{
171
+ switch (status) {
172
+ case VMNET_SUCCESS:
173
+ return "success";
174
+ case VMNET_FAILURE:
175
+ return "general failure";
176
+ case VMNET_MEM_FAILURE:
177
+ return "memory allocation failure";
178
+ case VMNET_INVALID_ARGUMENT:
179
+ return "invalid argument specified";
180
+ case VMNET_SETUP_INCOMPLETE:
181
+ return "interface setup is not complete";
182
+ case VMNET_INVALID_ACCESS:
183
+ return "invalid access, permission denied";
184
+ case VMNET_PACKET_TOO_BIG:
185
+ return "packet size is larger than MTU";
186
+ case VMNET_BUFFER_EXHAUSTED:
187
+ return "buffers exhausted in kernel";
188
+ case VMNET_TOO_MANY_PACKETS:
189
+ return "packet count exceeds limit";
190
+ case VMNET_SHARING_SERVICE_BUSY:
191
+ return "conflict, sharing service is in use";
192
+ default:
193
+ return "unknown vmnet error";
194
+ }
195
+}
196
+
197
+
198
+int vmnet_if_create(NetClientState *nc,
199
+ xpc_object_t if_desc,
200
+ Error **errp,
201
+ void (*completion_callback)(xpc_object_t interface_param))
202
+{
203
+ VmnetCommonState *s;
204
+
205
+ dispatch_queue_t if_create_q;
206
+ dispatch_semaphore_t if_created_sem;
207
+
208
+ __block vmnet_return_t if_status;
209
+
210
+ if_create_q = dispatch_queue_create("org.qemu.vmnet.create",
211
+ DISPATCH_QUEUE_SERIAL);
212
+ if_created_sem = dispatch_semaphore_create(0);
213
+
214
+ xpc_dictionary_set_bool(
215
+ if_desc,
216
+ vmnet_allocate_mac_address_key,
217
+ false
218
+ );
219
+
220
+ D(D_LOG("vmnet.start.interface_desc:\n");
221
+ xpc_dictionary_apply(if_desc,
222
+ ^bool(const char *k, xpc_object_t v) {
223
+ char *desc = xpc_copy_description(v);
224
+ D_LOG(" %s=%s\n", k, desc);
225
+ free(desc);
226
+ return true;
227
+ }));
228
+
229
+ s = DO_UPCAST(VmnetCommonState, nc, nc);
230
+ s->vmnet_if = vmnet_start_interface(
231
+ if_desc,
232
+ if_create_q,
233
+ ^(vmnet_return_t status, xpc_object_t interface_param) {
234
+ if_status = status;
235
+ if (status != VMNET_SUCCESS || !interface_param) {
236
+ dispatch_semaphore_signal(if_created_sem);
237
+ return;
238
+ }
239
+
240
+ D(D_LOG("vmnet.start.interface_param:\n");
241
+ xpc_dictionary_apply(interface_param,
242
+ ^bool(const char *k, xpc_object_t v) {
243
+ char *desc = xpc_copy_description(v);
244
+ D_LOG(" %s=%s\n", k, desc);
245
+ free(desc);
246
+ return true;
247
+ }));
248
+
249
+ s->mtu = xpc_dictionary_get_uint64(
250
+ interface_param,
251
+ vmnet_mtu_key);
252
+ s->max_packet_size = xpc_dictionary_get_uint64(
253
+ interface_param,
254
+ vmnet_max_packet_size_key);
255
+
256
+ if (completion_callback) {
257
+ completion_callback(interface_param);
258
+ }
259
+ dispatch_semaphore_signal(if_created_sem);
260
+ });
261
+
262
+ if (s->vmnet_if == NULL) {
263
+ error_setg(errp, "unable to create interface with requested params");
264
+ return -1;
265
+ }
266
+
267
+ dispatch_semaphore_wait(if_created_sem, DISPATCH_TIME_FOREVER);
268
+ dispatch_release(if_create_q);
269
+
270
+ if (if_status != VMNET_SUCCESS) {
271
+ error_setg(errp,
272
+ "cannot create vmnet interface: %s",
273
+ vmnet_status_map_str(if_status));
274
+ return -1;
275
+ }
276
+
277
+ vmnet_register_event_callback(s);
278
+ vmnet_bufs_init(s);
279
+ vmnet_set_send_enabled(s, true);
280
+
281
+ return 0;
282
+}
283
+
284
+
285
+ssize_t vmnet_receive_common(NetClientState *nc,
286
+ const uint8_t *buf,
287
+ size_t size)
288
+{
289
+ VmnetCommonState *s;
290
+ vmpktdesc_t packet;
291
+ iovec_t iov;
292
+ int pkt_cnt;
293
+ vmnet_return_t if_status;
294
+
295
+ s = DO_UPCAST(VmnetCommonState, nc, nc);
296
+
297
+ if (size > s->max_packet_size) {
298
+ warn_report("vmnet: packet is too big, %zu > %llu\n",
299
+ packet.vm_pkt_size,
300
+ s->max_packet_size);
301
+ return -1;
302
+ }
303
+
304
+ iov.iov_base = (char *) buf;
305
+ iov.iov_len = size;
306
+
307
+ packet.vm_pkt_iovcnt = 1;
308
+ packet.vm_flags = 0;
309
+ packet.vm_pkt_size = size;
310
+ packet.vm_pkt_iov = &iov;
311
+
312
+ pkt_cnt = 1;
313
+ if_status = vmnet_write(s->vmnet_if, &packet, &pkt_cnt);
314
+
315
+ if (if_status != VMNET_SUCCESS) {
316
+ error_report("vmnet: write error: %s\n",
317
+ vmnet_status_map_str(if_status));
318
+ }
319
+
320
+ if (if_status == VMNET_SUCCESS && pkt_cnt) {
321
+ return size;
322
+ }
323
+ return 0;
324
+}
325
+
326
+
327
+void vmnet_cleanup_common(NetClientState *nc)
328
+{
329
+ VmnetCommonState *s;
330
+ dispatch_queue_t if_destroy_q;
331
+
332
+ s = DO_UPCAST(VmnetCommonState, nc, nc);
333
+
334
+ qemu_purge_queued_packets(nc);
335
+ vmnet_set_send_enabled(s, false);
336
+
337
+ if (s->vmnet_if == NULL) {
338
+ return;
339
+ }
340
+
341
+ if_destroy_q = dispatch_queue_create(
342
+ "org.qemu.vmnet.destroy",
343
+ DISPATCH_QUEUE_SERIAL
344
+ );
345
+
346
+ vmnet_stop_interface(
347
+ s->vmnet_if,
348
+ if_destroy_q,
349
+ ^(vmnet_return_t status) {
350
+ });
351
+
352
+ for (int i = 0; i < VMNET_PACKETS_LIMIT; ++i) {
353
+ g_free(s->iov_buf[i].iov_base);
354
+ }
355
+}
356
diff --git a/net/vmnet-shared.c b/net/vmnet-shared.c
357
index XXXXXXX..XXXXXXX 100644
358
--- a/net/vmnet-shared.c
359
+++ b/net/vmnet-shared.c
360
@@ -XXX,XX +XXX,XX @@
361
362
#include "qemu/osdep.h"
363
#include "qapi/qapi-types-net.h"
364
+#include "qapi/error.h"
365
#include "vmnet_int.h"
366
#include "clients.h"
367
-#include "qemu/error-report.h"
368
-#include "qapi/error.h"
369
370
#include <vmnet/vmnet.h>
371
372
+typedef struct VmnetSharedState {
373
+ VmnetCommonState cs;
374
+} VmnetSharedState;
375
+
376
+
377
+static xpc_object_t create_if_desc(const Netdev *netdev, Error **errp)
378
+{
379
+ const NetdevVmnetSharedOptions *options = &(netdev->u.vmnet_shared);
380
+ xpc_object_t if_desc = xpc_dictionary_create(NULL, NULL, 0);
381
+
382
+ xpc_dictionary_set_uint64(
383
+ if_desc,
384
+ vmnet_operation_mode_key,
385
+ VMNET_SHARED_MODE
386
+ );
387
+
388
+ xpc_dictionary_set_bool(
389
+ if_desc,
390
+ vmnet_enable_isolation_key,
391
+ options->isolated
392
+ );
393
+
394
+ if (options->has_nat66_prefix) {
395
+ xpc_dictionary_set_string(if_desc,
396
+ vmnet_nat66_prefix_key,
397
+ options->nat66_prefix);
398
+ }
399
+
400
+ if (options->has_start_address ||
401
+ options->has_end_address ||
402
+ options->has_subnet_mask) {
403
+
404
+ if (options->has_start_address &&
405
+ options->has_end_address &&
406
+ options->has_subnet_mask) {
407
+
408
+ xpc_dictionary_set_string(if_desc,
409
+ vmnet_start_address_key,
410
+ options->start_address);
411
+ xpc_dictionary_set_string(if_desc,
412
+ vmnet_end_address_key,
413
+ options->end_address);
414
+ xpc_dictionary_set_string(if_desc,
415
+ vmnet_subnet_mask_key,
416
+ options->subnet_mask);
417
+ } else {
418
+ error_setg(
419
+ errp,
420
+ "'start-address', 'end-address', 'subnet_mask' "
421
+ "should be provided together"
422
+ );
423
+ }
424
+ }
425
+
426
+ return if_desc;
427
+}
428
+
429
+static NetClientInfo net_vmnet_shared_info = {
430
+ .type = NET_CLIENT_DRIVER_VMNET_SHARED,
431
+ .size = sizeof(VmnetSharedState),
432
+ .receive = vmnet_receive_common,
433
+ .cleanup = vmnet_cleanup_common,
434
+};
435
+
436
int net_init_vmnet_shared(const Netdev *netdev, const char *name,
437
NetClientState *peer, Error **errp)
438
{
439
- error_setg(errp, "vmnet-shared is not implemented yet");
440
- return -1;
441
+ NetClientState *nc = qemu_new_net_client(&net_vmnet_shared_info,
442
+ peer, "vmnet-shared", name);
443
+ xpc_object_t if_desc = create_if_desc(netdev, errp);
444
+
445
+ return vmnet_if_create(nc, if_desc, errp, NULL);
446
}
447
diff --git a/net/vmnet_int.h b/net/vmnet_int.h
448
index XXXXXXX..XXXXXXX 100644
449
--- a/net/vmnet_int.h
450
+++ b/net/vmnet_int.h
451
@@ -XXX,XX +XXX,XX @@
452
453
#include <vmnet/vmnet.h>
454
455
+#define VMNET_PACKETS_LIMIT 50
456
+
457
typedef struct VmnetCommonState {
458
NetClientState nc;
459
+ interface_ref vmnet_if;
460
+
461
+ bool send_enabled;
462
+
463
+ uint64_t mtu;
464
+ uint64_t max_packet_size;
465
+
466
+ struct vmpktdesc packets_buf[VMNET_PACKETS_LIMIT];
467
+ struct iovec iov_buf[VMNET_PACKETS_LIMIT];
468
469
} VmnetCommonState;
470
471
+const char *vmnet_status_map_str(vmnet_return_t status);
472
+
473
+int vmnet_if_create(NetClientState *nc,
474
+ xpc_object_t if_desc,
475
+ Error **errp,
476
+ void (*completion_callback)(xpc_object_t interface_param));
477
+
478
+ssize_t vmnet_receive_common(NetClientState *nc,
479
+ const uint8_t *buf,
480
+ size_t size);
481
+
482
+void vmnet_cleanup_common(NetClientState *nc);
483
484
#endif /* VMNET_INT_H */
485
--
486
2.7.4
487
488
diff view generated by jsdifflib
New patch
1
From: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
1
2
3
Signed-off-by: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
4
Signed-off-by: Jason Wang <jasowang@redhat.com>
5
---
6
net/vmnet-host.c | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++++----
7
1 file changed, 87 insertions(+), 6 deletions(-)
8
9
diff --git a/net/vmnet-host.c b/net/vmnet-host.c
10
index XXXXXXX..XXXXXXX 100644
11
--- a/net/vmnet-host.c
12
+++ b/net/vmnet-host.c
13
@@ -XXX,XX +XXX,XX @@
14
*/
15
16
#include "qemu/osdep.h"
17
+#include "qemu/uuid.h"
18
#include "qapi/qapi-types-net.h"
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
+typedef struct VmnetHostState {
29
+ VmnetCommonState cs;
30
+ QemuUUID network_uuid;
31
+} VmnetHostState;
32
+
33
+static xpc_object_t create_if_desc(const Netdev *netdev,
34
+ NetClientState *nc,
35
+ Error **errp)
36
+{
37
+ const NetdevVmnetHostOptions *options = &(netdev->u.vmnet_host);
38
+ VmnetCommonState *cs = DO_UPCAST(VmnetCommonState, nc, nc);
39
+ VmnetHostState *hs = DO_UPCAST(VmnetHostState, cs, cs);
40
+
41
+ xpc_object_t if_desc = xpc_dictionary_create(NULL, NULL, 0);
42
+
43
+ xpc_dictionary_set_uint64(
44
+ if_desc,
45
+ vmnet_operation_mode_key,
46
+ VMNET_HOST_MODE
47
+ );
48
+
49
+ xpc_dictionary_set_bool(
50
+ if_desc,
51
+ vmnet_enable_isolation_key,
52
+ options->isolated
53
+ );
54
+
55
+ if (options->has_net_uuid) {
56
+ if (qemu_uuid_parse(options->net_uuid, &hs->network_uuid) < 0) {
57
+ error_setg(errp, "Invalid UUID provided in 'net-uuid'");
58
+ }
59
+
60
+ xpc_dictionary_set_uuid(
61
+ if_desc,
62
+ vmnet_network_identifier_key,
63
+ hs->network_uuid.data
64
+ );
65
+ }
66
+
67
+ if (options->has_start_address ||
68
+ options->has_end_address ||
69
+ options->has_subnet_mask) {
70
+
71
+ if (options->has_start_address &&
72
+ options->has_end_address &&
73
+ options->has_subnet_mask) {
74
+
75
+ xpc_dictionary_set_string(if_desc,
76
+ vmnet_start_address_key,
77
+ options->start_address);
78
+ xpc_dictionary_set_string(if_desc,
79
+ vmnet_end_address_key,
80
+ options->end_address);
81
+ xpc_dictionary_set_string(if_desc,
82
+ vmnet_subnet_mask_key,
83
+ options->subnet_mask);
84
+ } else {
85
+ error_setg(
86
+ errp,
87
+ "'start-address', 'end-address', 'subnet_mask' "
88
+ "should be provided together"
89
+ );
90
+ }
91
+ }
92
+
93
+ return if_desc;
94
+}
95
+
96
+static NetClientInfo net_vmnet_host_info = {
97
+ .type = NET_CLIENT_DRIVER_VMNET_HOST,
98
+ .size = sizeof(VmnetHostState),
99
+ .receive = vmnet_receive_common,
100
+ .cleanup = vmnet_cleanup_common,
101
+};
102
+
103
int net_init_vmnet_host(const Netdev *netdev, const char *name,
104
- NetClientState *peer, Error **errp) {
105
- error_setg(errp, "vmnet-host is not implemented yet");
106
- return -1;
107
+ NetClientState *peer, Error **errp)
108
+{
109
+ NetClientState *nc;
110
+ xpc_object_t if_desc;
111
+
112
+ nc = qemu_new_net_client(&net_vmnet_host_info,
113
+ peer, "vmnet-host", name);
114
+ if_desc = create_if_desc(netdev, nc, errp);
115
+ return vmnet_if_create(nc, if_desc, errp, NULL);
116
}
117
--
118
2.7.4
119
120
diff view generated by jsdifflib
New patch
1
From: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
1
2
3
Signed-off-by: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
4
Signed-off-by: Jason Wang <jasowang@redhat.com>
5
---
6
net/vmnet-bridged.m | 98 +++++++++++++++++++++++++++++++++++++++++++++++++----
7
1 file changed, 92 insertions(+), 6 deletions(-)
8
9
diff --git a/net/vmnet-bridged.m b/net/vmnet-bridged.m
10
index XXXXXXX..XXXXXXX 100644
11
--- a/net/vmnet-bridged.m
12
+++ b/net/vmnet-bridged.m
13
@@ -XXX,XX +XXX,XX @@
14
15
#include "qemu/osdep.h"
16
#include "qapi/qapi-types-net.h"
17
-#include "vmnet_int.h"
18
-#include "clients.h"
19
-#include "qemu/error-report.h"
20
#include "qapi/error.h"
21
+#include "clients.h"
22
+#include "vmnet_int.h"
23
24
#include <vmnet/vmnet.h>
25
26
+typedef struct VmnetBridgedState {
27
+ VmnetCommonState cs;
28
+} VmnetBridgedState;
29
+
30
+static bool validate_ifname(const char *ifname)
31
+{
32
+ xpc_object_t shared_if_list = vmnet_copy_shared_interface_list();
33
+ __block bool match = false;
34
+
35
+ xpc_array_apply(
36
+ shared_if_list,
37
+ ^bool(size_t index, xpc_object_t value) {
38
+ if (strcmp(xpc_string_get_string_ptr(value), ifname) == 0) {
39
+ match = true;
40
+ return false;
41
+ }
42
+ return true;
43
+ });
44
+
45
+ return match;
46
+}
47
+
48
+static const char *get_valid_ifnames(void)
49
+{
50
+ xpc_object_t shared_if_list = vmnet_copy_shared_interface_list();
51
+ __block char *if_list = NULL;
52
+
53
+ xpc_array_apply(
54
+ shared_if_list,
55
+ ^bool(size_t index, xpc_object_t value) {
56
+ if_list = g_strconcat(xpc_string_get_string_ptr(value),
57
+ " ",
58
+ if_list,
59
+ NULL);
60
+ return true;
61
+ });
62
+
63
+ if (if_list) {
64
+ return if_list;
65
+ }
66
+ return "[no interfaces]";
67
+}
68
+
69
+static xpc_object_t create_if_desc(const Netdev *netdev, Error **errp)
70
+{
71
+ const NetdevVmnetBridgedOptions *options = &(netdev->u.vmnet_bridged);
72
+ xpc_object_t if_desc = xpc_dictionary_create(NULL, NULL, 0);
73
+
74
+ xpc_dictionary_set_uint64(
75
+ if_desc,
76
+ vmnet_operation_mode_key,
77
+ VMNET_BRIDGED_MODE
78
+ );
79
+
80
+ xpc_dictionary_set_bool(
81
+ if_desc,
82
+ vmnet_enable_isolation_key,
83
+ options->isolated
84
+ );
85
+
86
+ if (validate_ifname(options->ifname)) {
87
+ xpc_dictionary_set_string(if_desc,
88
+ vmnet_shared_interface_name_key,
89
+ options->ifname);
90
+ } else {
91
+ return NULL;
92
+ }
93
+ return if_desc;
94
+}
95
+
96
+static NetClientInfo net_vmnet_bridged_info = {
97
+ .type = NET_CLIENT_DRIVER_VMNET_BRIDGED,
98
+ .size = sizeof(VmnetBridgedState),
99
+ .receive = vmnet_receive_common,
100
+ .cleanup = vmnet_cleanup_common,
101
+};
102
+
103
int net_init_vmnet_bridged(const Netdev *netdev, const char *name,
104
NetClientState *peer, Error **errp)
105
{
106
- error_setg(errp, "vmnet-bridged is not implemented yet");
107
- return -1;
108
-}
109
+ NetClientState *nc = qemu_new_net_client(&net_vmnet_bridged_info,
110
+ peer, "vmnet-bridged", name);
111
+ xpc_object_t if_desc = create_if_desc(netdev, errp);;
112
+
113
+ if (!if_desc) {
114
+ error_setg(errp,
115
+ "unsupported ifname, should be one of: %s",
116
+ get_valid_ifnames());
117
+ return -1;
118
+ }
119
+
120
+ return vmnet_if_create(nc, if_desc, errp, NULL);
121
+}
122
\ No newline at end of file
123
--
124
2.7.4
125
126
diff view generated by jsdifflib
New patch
1
From: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
1
2
3
Signed-off-by: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
4
Signed-off-by: Jason Wang <jasowang@redhat.com>
5
---
6
qemu-options.hx | 25 +++++++++++++++++++++++++
7
1 file changed, 25 insertions(+)
8
9
diff --git a/qemu-options.hx b/qemu-options.hx
10
index XXXXXXX..XXXXXXX 100644
11
--- a/qemu-options.hx
12
+++ b/qemu-options.hx
13
@@ -XXX,XX +XXX,XX @@ DEF("netdev", HAS_ARG, QEMU_OPTION_netdev,
14
"-netdev vhost-vdpa,id=str,vhostdev=/path/to/dev\n"
15
" configure a vhost-vdpa network,Establish a vhost-vdpa netdev\n"
16
#endif
17
+#ifdef CONFIG_VMNET
18
+ "-netdev vmnet-host,id=str[,isolated=on|off][,net-uuid=uuid]\n"
19
+ " [,start-address=addr,end-address=addr,subnet-mask=mask]\n"
20
+ " configure a vmnet network backend in host mode with ID 'str',\n"
21
+ " isolate this interface from others with 'isolated',\n"
22
+ " configure the address range and choose a subnet mask,\n"
23
+ " specify network UUID 'uuid' to disable DHCP and interact with\n"
24
+ " vmnet-host interfaces within this isolated network\n"
25
+ "-netdev vmnet-shared,id=str[,isolated=on|off][,nat66-prefix=addr]\n"
26
+ " [,start-address=addr,end-address=addr,subnet-mask=mask]\n"
27
+ " configure a vmnet network backend in shared mode with ID 'str',\n"
28
+ " configure the address range and choose a subnet mask,\n"
29
+ " set IPv6 ULA prefix (of length 64) to use for internal network,\n"
30
+ " isolate this interface from others with 'isolated'\n"
31
+ "-netdev vmnet-bridged,id=str,ifname=name[,isolated=on|off]\n"
32
+ " configure a vmnet network backend in bridged mode with ID 'str',\n"
33
+ " use 'ifname=name' to select a physical network interface to be bridged,\n"
34
+ " isolate this interface from others with 'isolated'\n"
35
+#endif
36
"-netdev hubport,id=str,hubid=n[,netdev=nd]\n"
37
" configure a hub port on the hub with ID 'n'\n", QEMU_ARCH_ALL)
38
DEF("nic", HAS_ARG, QEMU_OPTION_nic,
39
@@ -XXX,XX +XXX,XX @@ DEF("nic", HAS_ARG, QEMU_OPTION_nic,
40
#ifdef CONFIG_POSIX
41
"vhost-user|"
42
#endif
43
+#ifdef CONFIG_VMNET
44
+ "vmnet-host|vmnet-shared|vmnet-bridged|"
45
+#endif
46
"socket][,option][,...][mac=macaddr]\n"
47
" initialize an on-board / default host NIC (using MAC address\n"
48
" macaddr) and connect it to the given host network backend\n"
49
@@ -XXX,XX +XXX,XX @@ DEF("net", HAS_ARG, QEMU_OPTION_net,
50
#ifdef CONFIG_NETMAP
51
"netmap|"
52
#endif
53
+#ifdef CONFIG_VMNET
54
+ "vmnet-host|vmnet-shared|vmnet-bridged|"
55
+#endif
56
"socket][,option][,option][,...]\n"
57
" old way to initialize a host network interface\n"
58
" (use the -netdev option if possible instead)\n", QEMU_ARCH_ALL)
59
--
60
2.7.4
61
62
diff view generated by jsdifflib
1
From: Prasad J Pandit <pjp@fedoraproject.org>
1
From: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
2
2
3
While receiving packets via e1000e_write_packet_to_guest() routine,
3
Signed-off-by: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
4
'desc_offset' is advanced only when RX descriptor is processed. And
5
RX descriptor is not processed if it has NULL buffer address.
6
This may lead to an infinite loop condition. Increament 'desc_offset'
7
to process next descriptor in the ring to avoid infinite loop.
8
9
Reported-by: Cheol-woo Myung <330cjfdn@gmail.com>
10
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
11
Signed-off-by: Jason Wang <jasowang@redhat.com>
4
Signed-off-by: Jason Wang <jasowang@redhat.com>
12
---
5
---
13
hw/net/e1000e_core.c | 8 ++++----
6
MAINTAINERS | 5 +++++
14
1 file changed, 4 insertions(+), 4 deletions(-)
7
1 file changed, 5 insertions(+)
15
8
16
diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c
9
diff --git a/MAINTAINERS b/MAINTAINERS
17
index XXXXXXX..XXXXXXX 100644
10
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/net/e1000e_core.c
11
--- a/MAINTAINERS
19
+++ b/hw/net/e1000e_core.c
12
+++ b/MAINTAINERS
20
@@ -XXX,XX +XXX,XX @@ e1000e_write_packet_to_guest(E1000ECore *core, struct NetRxPkt *pkt,
13
@@ -XXX,XX +XXX,XX @@ W: http://info.iet.unipi.it/~luigi/netmap/
21
(const char *) &fcs_pad, e1000x_fcs_len(core->mac));
14
S: Maintained
22
}
15
F: net/netmap.c
23
}
16
24
- desc_offset += desc_size;
17
+Apple vmnet network backends
25
- if (desc_offset >= total_size) {
18
+M: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
26
- is_last = true;
19
+S: Maintained
27
- }
20
+F: net/vmnet*
28
} else { /* as per intel docs; skip descriptors with null buf addr */
21
+
29
trace_e1000e_rx_null_descriptor();
22
Host Memory Backends
30
}
23
M: David Hildenbrand <david@redhat.com>
31
+ desc_offset += desc_size;
24
M: Igor Mammedov <imammedo@redhat.com>
32
+ if (desc_offset >= total_size) {
33
+ is_last = true;
34
+ }
35
36
e1000e_write_rx_descr(core, desc, is_last ? core->rx_pkt : NULL,
37
rss_info, do_ps ? ps_hdr_len : 0, &bastate.written);
38
--
25
--
39
2.7.4
26
2.7.4
40
27
41
28
diff view generated by jsdifflib