1
The following changes since commit e81eb5e6d108008445821e4f891fb9563016c71b:
1
The following changes since commit f8d75e10d3e0033a0a29a7a7e4777a4fbc17a016:
2
2
3
Merge remote-tracking branch 'remotes/bonzini-gitlab/tags/for-upstream' into staging (2021-01-23 22:34:21 +0000)
3
Merge remote-tracking branch 'remotes/legoater/tags/pull-ppc-20220112' into staging (2022-01-13 11:18:24 +0000)
4
4
5
are available in the git repository at:
5
are available in the git repository at:
6
6
7
https://github.com/jasowang/qemu.git tags/net-pull-request
7
https://github.com/jasowang/qemu.git tags/net-pull-request
8
8
9
for you to fetch changes up to f574633529926697ced51b6865e5c50bbb78bf1b:
9
for you to fetch changes up to 818692f0a01587d02220916b31d5bb8e7dced611:
10
10
11
net: checksum: Introduce fine control over checksum type (2021-01-25 17:04:56 +0800)
11
net/vmnet: update MAINTAINERS list (2022-01-14 12:58:19 +0800)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
14
15
Changes since V2:
16
17
- Try to make vmnet work on some old mac version
18
15
----------------------------------------------------------------
19
----------------------------------------------------------------
16
Bin Meng (1):
20
Peter Foley (2):
17
net: checksum: Introduce fine control over checksum type
21
net/tap: Set return code on failure
22
net: Fix uninitialized data usage
18
23
19
Guishan Qin (1):
24
Philippe Mathieu-Daudé (1):
20
net: checksum: Add IP header checksum calculation
25
hw/net/vmxnet3: Log guest-triggerable errors using LOG_GUEST_ERROR
21
26
22
Markus Armbruster (1):
27
Rao Lei (1):
23
net: Fix handling of id in netdev_add and netdev_del
28
net/filter: Optimize filter_send to coroutine
24
29
25
Markus Carlstedt (1):
30
Vladislav Yaroshchuk (7):
26
net: checksum: Skip fragmented IP packets
31
net/vmnet: add vmnet dependency and customizable option
32
net/vmnet: add vmnet backends to qapi/net
33
net/vmnet: implement shared mode (vmnet-shared)
34
net/vmnet: implement host mode (vmnet-host)
35
net/vmnet: implement bridged mode (vmnet-bridged)
36
net/vmnet: update qemu-options.hx
37
net/vmnet: update MAINTAINERS list
27
38
28
hw/net/allwinner-sun8i-emac.c | 2 +-
39
Zhang Chen (2):
29
hw/net/cadence_gem.c | 2 +-
40
net/colo-compare.c: Optimize compare order for performance
30
hw/net/fsl_etsec/rings.c | 18 +++++++++---------
41
net/colo-compare.c: Update the default value comments
31
hw/net/ftgmac100.c | 13 ++++++++++++-
42
32
hw/net/imx_fec.c | 20 ++++++++------------
43
MAINTAINERS | 5 +
33
hw/net/virtio-net.c | 2 +-
44
hw/net/vmxnet3.c | 4 +-
34
hw/net/xen_nic.c | 2 +-
45
meson.build | 16 +-
35
include/net/checksum.h | 7 ++++++-
46
meson_options.txt | 2 +
36
net/checksum.c | 24 +++++++++++++++++++++---
47
net/clients.h | 11 ++
37
net/filter-rewriter.c | 4 ++--
48
net/colo-compare.c | 28 ++--
38
net/net.c | 20 ++++++++++++++++++--
49
net/filter-mirror.c | 66 +++++++--
39
11 files changed, 80 insertions(+), 34 deletions(-)
50
net/meson.build | 7 +
51
net/net.c | 10 ++
52
net/tap-linux.c | 1 +
53
net/tap.c | 1 +
54
net/vmnet-bridged.m | 120 +++++++++++++++
55
net/vmnet-common.m | 333 ++++++++++++++++++++++++++++++++++++++++++
56
net/vmnet-host.c | 122 ++++++++++++++++
57
net/vmnet-shared.c | 100 +++++++++++++
58
net/vmnet_int.h | 48 ++++++
59
qapi/net.json | 133 ++++++++++++++++-
60
qemu-options.hx | 25 ++++
61
scripts/meson-buildoptions.sh | 3 +
62
19 files changed, 1004 insertions(+), 31 deletions(-)
63
create mode 100644 net/vmnet-bridged.m
64
create mode 100644 net/vmnet-common.m
65
create mode 100644 net/vmnet-host.c
66
create mode 100644 net/vmnet-shared.c
67
create mode 100644 net/vmnet_int.h
40
68
41
69
diff view generated by jsdifflib
New patch
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
2
3
The "Interrupt Cause" register (VMXNET3_REG_ICR) is read-only.
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>
30
Signed-off-by: Jason Wang <jasowang@redhat.com>
31
---
32
hw/net/vmxnet3.c | 4 +++-
33
1 file changed, 3 insertions(+), 1 deletion(-)
34
35
diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/hw/net/vmxnet3.c
38
+++ b/hw/net/vmxnet3.c
39
@@ -XXX,XX +XXX,XX @@ vmxnet3_io_bar1_write(void *opaque,
40
case VMXNET3_REG_ICR:
41
VMW_CBPRN("Write BAR1 [VMXNET3_REG_ICR] = %" PRIx64 ", size %d",
42
val, size);
43
- g_assert_not_reached();
44
+ qemu_log_mask(LOG_GUEST_ERROR,
45
+ "%s: write to read-only register VMXNET3_REG_ICR\n",
46
+ TYPE_VMXNET3);
47
break;
48
49
/* Event Cause Register */
50
--
51
2.7.4
52
53
diff view generated by jsdifflib
New patch
1
From: Peter Foley <pefoley@google.com>
1
2
3
Match the other error handling in this function.
4
5
Fixes: e7b347d0bf6 ("net: detect errors from probing vnet hdr flag for TAP devices")
6
7
Reviewed-by: Patrick Venture <venture@google.com>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Signed-off-by: Peter Foley <pefoley@google.com>
10
Signed-off-by: Jason Wang <jasowang@redhat.com>
11
---
12
net/tap.c | 1 +
13
1 file changed, 1 insertion(+)
14
15
diff --git a/net/tap.c b/net/tap.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/net/tap.c
18
+++ b/net/tap.c
19
@@ -XXX,XX +XXX,XX @@ int net_init_tap(const Netdev *netdev, const char *name,
20
if (i == 0) {
21
vnet_hdr = tap_probe_vnet_hdr(fd, errp);
22
if (vnet_hdr < 0) {
23
+ ret = -1;
24
goto free_fail;
25
}
26
} else if (vnet_hdr != tap_probe_vnet_hdr(fd, NULL)) {
27
--
28
2.7.4
29
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
1
From: Bin Meng <bin.meng@windriver.com>
1
From: Zhang Chen <chen.zhang@intel.com>
2
2
3
At present net_checksum_calculate() blindly calculates all types of
3
COLO-compare use the glib function g_queue_find_custom to dump
4
checksums (IP, TCP, UDP). Some NICs may have a per type setting in
4
another VM's networking packet to compare. But this function always
5
their BDs to control what checksum should be offloaded. To support
5
start find from the queue->head(here is the newest packet), It will
6
such hardware behavior, introduce a 'csum_flag' parameter to the
6
reduce the success rate of comparison. So this patch reversed
7
net_checksum_calculate() API to allow fine control over what type
7
the order of the queues for performance.
8
checksum is calculated.
9
8
10
Existing users of this API are updated accordingly.
9
Signed-off-by: Zhang Chen <chen.zhang@intel.com>
11
10
Reported-by: leirao <lei.rao@intel.com>
12
Signed-off-by: Bin Meng <bin.meng@windriver.com>
13
Signed-off-by: Jason Wang <jasowang@redhat.com>
11
Signed-off-by: Jason Wang <jasowang@redhat.com>
14
---
12
---
15
hw/net/allwinner-sun8i-emac.c | 2 +-
13
net/colo-compare.c | 26 +++++++++++++-------------
16
hw/net/cadence_gem.c | 2 +-
14
1 file changed, 13 insertions(+), 13 deletions(-)
17
hw/net/fsl_etsec/rings.c | 18 +++++++++---------
18
hw/net/ftgmac100.c | 13 ++++++++++++-
19
hw/net/imx_fec.c | 20 ++++++++------------
20
hw/net/virtio-net.c | 2 +-
21
hw/net/xen_nic.c | 2 +-
22
include/net/checksum.h | 7 ++++++-
23
net/checksum.c | 18 ++++++++++++++----
24
net/filter-rewriter.c | 4 ++--
25
10 files changed, 55 insertions(+), 33 deletions(-)
26
15
27
diff --git a/hw/net/allwinner-sun8i-emac.c b/hw/net/allwinner-sun8i-emac.c
16
diff --git a/net/colo-compare.c b/net/colo-compare.c
28
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
29
--- a/hw/net/allwinner-sun8i-emac.c
18
--- a/net/colo-compare.c
30
+++ b/hw/net/allwinner-sun8i-emac.c
19
+++ b/net/colo-compare.c
31
@@ -XXX,XX +XXX,XX @@ static void allwinner_sun8i_emac_transmit(AwSun8iEmacState *s)
20
@@ -XXX,XX +XXX,XX @@ static void colo_compare_inconsistency_notify(CompareState *s)
32
/* After the last descriptor, send the packet */
21
/* Use restricted to colo_insert_packet() */
33
if (desc.status2 & TX_DESC_STATUS2_LAST_DESC) {
22
static gint seq_sorter(Packet *a, Packet *b, gpointer data)
34
if (desc.status2 & TX_DESC_STATUS2_CHECKSUM_MASK) {
23
{
35
- net_checksum_calculate(packet_buf, packet_bytes);
24
- return a->tcp_seq - b->tcp_seq;
36
+ net_checksum_calculate(packet_buf, packet_bytes, CSUM_ALL);
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:
37
}
47
}
38
48
}
39
qemu_send_packet(nc, packet_buf, packet_bytes);
49
if (!ppkt) {
40
diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
50
- g_queue_push_head(&conn->secondary_list, spkt);
41
index XXXXXXX..XXXXXXX 100644
51
+ g_queue_push_tail(&conn->secondary_list, spkt);
42
--- a/hw/net/cadence_gem.c
52
goto pri;
43
+++ b/hw/net/cadence_gem.c
44
@@ -XXX,XX +XXX,XX @@ static void gem_transmit(CadenceGEMState *s)
45
46
/* Is checksum offload enabled? */
47
if (s->regs[GEM_DMACFG] & GEM_DMACFG_TXCSUM_OFFL) {
48
- net_checksum_calculate(s->tx_packet, total_bytes);
49
+ net_checksum_calculate(s->tx_packet, total_bytes, CSUM_ALL);
50
}
51
52
/* Update MAC statistics */
53
diff --git a/hw/net/fsl_etsec/rings.c b/hw/net/fsl_etsec/rings.c
54
index XXXXXXX..XXXXXXX 100644
55
--- a/hw/net/fsl_etsec/rings.c
56
+++ b/hw/net/fsl_etsec/rings.c
57
@@ -XXX,XX +XXX,XX @@ static void process_tx_fcb(eTSEC *etsec)
58
uint8_t *l3_header = etsec->tx_buffer + 8 + l3_header_offset;
59
/* L4 header */
60
uint8_t *l4_header = l3_header + l4_header_offset;
61
+ int csum = 0;
62
63
/* if packet is IP4 and IP checksum is requested */
64
if (flags & FCB_TX_IP && flags & FCB_TX_CIP) {
65
- /* do IP4 checksum (TODO This function does TCP/UDP checksum
66
- * but not sure if it also does IP4 checksum.) */
67
- net_checksum_calculate(etsec->tx_buffer + 8,
68
- etsec->tx_buffer_len - 8);
69
+ csum |= CSUM_IP;
70
}
71
/* TODO Check the correct usage of the PHCS field of the FCB in case the NPH
72
* flag is on */
73
@@ -XXX,XX +XXX,XX @@ static void process_tx_fcb(eTSEC *etsec)
74
/* if checksum is requested */
75
if (flags & FCB_TX_CTU) {
76
/* do UDP checksum */
77
-
78
- net_checksum_calculate(etsec->tx_buffer + 8,
79
- etsec->tx_buffer_len - 8);
80
+ csum |= CSUM_UDP;
81
} else {
82
/* set checksum field to 0 */
83
l4_header[6] = 0;
84
@@ -XXX,XX +XXX,XX @@ static void process_tx_fcb(eTSEC *etsec)
85
}
86
} else if (flags & FCB_TX_CTU) { /* if TCP and checksum is requested */
87
/* do TCP checksum */
88
- net_checksum_calculate(etsec->tx_buffer + 8,
89
- etsec->tx_buffer_len - 8);
90
+ csum |= CSUM_TCP;
91
}
53
}
92
}
54
}
93
+
55
@@ -XXX,XX +XXX,XX @@ sec:
94
+ if (csum) {
56
if (mark == COLO_COMPARE_FREE_PRIMARY) {
95
+ net_checksum_calculate(etsec->tx_buffer + 8,
57
conn->compare_seq = ppkt->seq_end;
96
+ etsec->tx_buffer_len - 8, csum);
58
colo_release_primary_pkt(s, ppkt);
97
+ }
59
- g_queue_push_head(&conn->secondary_list, spkt);
98
}
60
+ g_queue_push_tail(&conn->secondary_list, spkt);
99
61
goto pri;
100
static void process_tx_bd(eTSEC *etsec,
62
} else if (mark == COLO_COMPARE_FREE_SECONDARY) {
101
diff --git a/hw/net/ftgmac100.c b/hw/net/ftgmac100.c
63
conn->compare_seq = spkt->seq_end;
102
index XXXXXXX..XXXXXXX 100644
64
@@ -XXX,XX +XXX,XX @@ sec:
103
--- a/hw/net/ftgmac100.c
65
goto pri;
104
+++ b/hw/net/ftgmac100.c
66
}
105
@@ -XXX,XX +XXX,XX @@ static void ftgmac100_do_tx(FTGMAC100State *s, uint32_t tx_ring,
67
} else {
106
ptr += len;
68
- g_queue_push_head(&conn->primary_list, ppkt);
107
frame_size += len;
69
- g_queue_push_head(&conn->secondary_list, spkt);
108
if (bd.des0 & FTGMAC100_TXDES0_LTS) {
70
+ g_queue_push_tail(&conn->primary_list, ppkt);
109
+ int csum = 0;
71
+ g_queue_push_tail(&conn->secondary_list, spkt);
110
72
111
/* Check for VLAN */
73
#ifdef DEBUG_COLO_PACKETS
112
if (flags & FTGMAC100_TXDES1_INS_VLANTAG &&
74
qemu_hexdump(stderr, "colo-compare ppkt", ppkt->data, ppkt->size);
113
@@ -XXX,XX +XXX,XX @@ static void ftgmac100_do_tx(FTGMAC100State *s, uint32_t tx_ring,
75
@@ -XXX,XX +XXX,XX @@ static void colo_compare_packet(CompareState *s, Connection *conn,
114
}
76
115
77
while (!g_queue_is_empty(&conn->primary_list) &&
116
if (flags & FTGMAC100_TXDES1_IP_CHKSUM) {
78
!g_queue_is_empty(&conn->secondary_list)) {
117
- net_checksum_calculate(s->frame, frame_size);
79
- pkt = g_queue_pop_head(&conn->primary_list);
118
+ csum |= CSUM_IP;
80
+ pkt = g_queue_pop_tail(&conn->primary_list);
119
}
81
result = g_queue_find_custom(&conn->secondary_list,
120
+ if (flags & FTGMAC100_TXDES1_TCP_CHKSUM) {
82
pkt, (GCompareFunc)HandlePacket);
121
+ csum |= CSUM_TCP;
83
122
+ }
84
@@ -XXX,XX +XXX,XX @@ static void colo_compare_packet(CompareState *s, Connection *conn,
123
+ if (flags & FTGMAC100_TXDES1_UDP_CHKSUM) {
85
* timeout, it will trigger a checkpoint request.
124
+ csum |= CSUM_UDP;
86
*/
125
+ }
87
trace_colo_compare_main("packet different");
126
+ if (csum) {
88
- g_queue_push_head(&conn->primary_list, pkt);
127
+ net_checksum_calculate(s->frame, frame_size, csum);
89
+ g_queue_push_tail(&conn->primary_list, pkt);
128
+ }
90
129
+
91
colo_compare_inconsistency_notify(s);
130
/* Last buffer in frame. */
92
break;
131
qemu_send_packet(qemu_get_queue(s->nic), s->frame, frame_size);
93
@@ -XXX,XX +XXX,XX @@ static int compare_chr_send(CompareState *s,
132
ptr = s->frame;
94
entry->buf = g_malloc(size);
133
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
95
memcpy(entry->buf, buf, size);
134
index XXXXXXX..XXXXXXX 100644
96
}
135
--- a/hw/net/imx_fec.c
97
- g_queue_push_head(&sendco->send_list, entry);
136
+++ b/hw/net/imx_fec.c
98
+ g_queue_push_tail(&sendco->send_list, entry);
137
@@ -XXX,XX +XXX,XX @@ static void imx_enet_do_tx(IMXFECState *s, uint32_t index)
99
138
ptr += len;
100
if (sendco->done) {
139
frame_size += len;
101
sendco->co = qemu_coroutine_create(_compare_chr_send, sendco);
140
if (bd.flags & ENET_BD_L) {
102
@@ -XXX,XX +XXX,XX @@ static void colo_flush_packets(void *opaque, void *user_data)
141
+ int csum = 0;
103
Packet *pkt = NULL;
142
+
104
143
if (bd.option & ENET_BD_PINS) {
105
while (!g_queue_is_empty(&conn->primary_list)) {
144
- struct ip_header *ip_hd = PKT_GET_IP_HDR(s->frame);
106
- pkt = g_queue_pop_head(&conn->primary_list);
145
- if (IP_HEADER_VERSION(ip_hd) == 4) {
107
+ pkt = g_queue_pop_tail(&conn->primary_list);
146
- net_checksum_calculate(s->frame, frame_size);
108
compare_chr_send(s,
147
- }
109
pkt->data,
148
+ csum |= (CSUM_TCP | CSUM_UDP);
110
pkt->size,
149
}
111
@@ -XXX,XX +XXX,XX @@ static void colo_flush_packets(void *opaque, void *user_data)
150
if (bd.option & ENET_BD_IINS) {
112
packet_destroy_partial(pkt, NULL);
151
- struct ip_header *ip_hd = PKT_GET_IP_HDR(s->frame);
113
}
152
- /* We compute checksum only for IPv4 frames */
114
while (!g_queue_is_empty(&conn->secondary_list)) {
153
- if (IP_HEADER_VERSION(ip_hd) == 4) {
115
- pkt = g_queue_pop_head(&conn->secondary_list);
154
- uint16_t csum;
116
+ pkt = g_queue_pop_tail(&conn->secondary_list);
155
- ip_hd->ip_sum = 0;
117
packet_destroy(pkt, NULL);
156
- csum = net_raw_checksum((uint8_t *)ip_hd, sizeof(*ip_hd));
157
- ip_hd->ip_sum = cpu_to_be16(csum);
158
- }
159
+ csum |= CSUM_IP;
160
+ }
161
+ if (csum) {
162
+ net_checksum_calculate(s->frame, frame_size, csum);
163
}
164
+
165
/* Last buffer in frame. */
166
167
qemu_send_packet(qemu_get_queue(s->nic), s->frame, frame_size);
168
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
169
index XXXXXXX..XXXXXXX 100644
170
--- a/hw/net/virtio-net.c
171
+++ b/hw/net/virtio-net.c
172
@@ -XXX,XX +XXX,XX @@ static void work_around_broken_dhclient(struct virtio_net_hdr *hdr,
173
(buf[12] == 0x08 && buf[13] == 0x00) && /* ethertype == IPv4 */
174
(buf[23] == 17) && /* ip.protocol == UDP */
175
(buf[34] == 0 && buf[35] == 67)) { /* udp.srcport == bootps */
176
- net_checksum_calculate(buf, size);
177
+ net_checksum_calculate(buf, size, CSUM_UDP);
178
hdr->flags &= ~VIRTIO_NET_HDR_F_NEEDS_CSUM;
179
}
118
}
180
}
119
}
181
diff --git a/hw/net/xen_nic.c b/hw/net/xen_nic.c
182
index XXXXXXX..XXXXXXX 100644
183
--- a/hw/net/xen_nic.c
184
+++ b/hw/net/xen_nic.c
185
@@ -XXX,XX +XXX,XX @@ static void net_tx_packets(struct XenNetDev *netdev)
186
tmpbuf = g_malloc(XC_PAGE_SIZE);
187
}
188
memcpy(tmpbuf, page + txreq.offset, txreq.size);
189
- net_checksum_calculate(tmpbuf, txreq.size);
190
+ net_checksum_calculate(tmpbuf, txreq.size, CSUM_ALL);
191
qemu_send_packet(qemu_get_queue(netdev->nic), tmpbuf,
192
txreq.size);
193
} else {
194
diff --git a/include/net/checksum.h b/include/net/checksum.h
195
index XXXXXXX..XXXXXXX 100644
196
--- a/include/net/checksum.h
197
+++ b/include/net/checksum.h
198
@@ -XXX,XX +XXX,XX @@
199
#include "qemu/bswap.h"
200
struct iovec;
201
202
+#define CSUM_IP 0x01
203
+#define CSUM_TCP 0x02
204
+#define CSUM_UDP 0x04
205
+#define CSUM_ALL (CSUM_IP | CSUM_TCP | CSUM_UDP)
206
+
207
uint32_t net_checksum_add_cont(int len, uint8_t *buf, int seq);
208
uint16_t net_checksum_finish(uint32_t sum);
209
uint16_t net_checksum_tcpudp(uint16_t length, uint16_t proto,
210
uint8_t *addrs, uint8_t *buf);
211
-void net_checksum_calculate(uint8_t *data, int length);
212
+void net_checksum_calculate(uint8_t *data, int length, int csum_flag);
213
214
static inline uint32_t
215
net_checksum_add(int len, uint8_t *buf)
216
diff --git a/net/checksum.c b/net/checksum.c
217
index XXXXXXX..XXXXXXX 100644
218
--- a/net/checksum.c
219
+++ b/net/checksum.c
220
@@ -XXX,XX +XXX,XX @@ uint16_t net_checksum_tcpudp(uint16_t length, uint16_t proto,
221
return net_checksum_finish(sum);
222
}
223
224
-void net_checksum_calculate(uint8_t *data, int length)
225
+void net_checksum_calculate(uint8_t *data, int length, int csum_flag)
226
{
227
int mac_hdr_len, ip_len;
228
struct ip_header *ip;
229
@@ -XXX,XX +XXX,XX @@ void net_checksum_calculate(uint8_t *data, int length)
230
}
231
232
/* Calculate IP checksum */
233
- stw_he_p(&ip->ip_sum, 0);
234
- csum = net_raw_checksum((uint8_t *)ip, IP_HDR_GET_LEN(ip));
235
- stw_be_p(&ip->ip_sum, csum);
236
+ if (csum_flag & CSUM_IP) {
237
+ stw_he_p(&ip->ip_sum, 0);
238
+ csum = net_raw_checksum((uint8_t *)ip, IP_HDR_GET_LEN(ip));
239
+ stw_be_p(&ip->ip_sum, csum);
240
+ }
241
242
if (IP4_IS_FRAGMENT(ip)) {
243
return; /* a fragmented IP packet */
244
@@ -XXX,XX +XXX,XX @@ void net_checksum_calculate(uint8_t *data, int length)
245
switch (ip->ip_p) {
246
case IP_PROTO_TCP:
247
{
248
+ if (!(csum_flag & CSUM_TCP)) {
249
+ return;
250
+ }
251
+
252
tcp_header *tcp = (tcp_header *)(ip + 1);
253
254
if (ip_len < sizeof(tcp_header)) {
255
@@ -XXX,XX +XXX,XX @@ void net_checksum_calculate(uint8_t *data, int length)
256
}
257
case IP_PROTO_UDP:
258
{
259
+ if (!(csum_flag & CSUM_UDP)) {
260
+ return;
261
+ }
262
+
263
udp_header *udp = (udp_header *)(ip + 1);
264
265
if (ip_len < sizeof(udp_header)) {
266
diff --git a/net/filter-rewriter.c b/net/filter-rewriter.c
267
index XXXXXXX..XXXXXXX 100644
268
--- a/net/filter-rewriter.c
269
+++ b/net/filter-rewriter.c
270
@@ -XXX,XX +XXX,XX @@ static int handle_primary_tcp_pkt(RewriterState *rf,
271
tcp_pkt->th_ack = htonl(ntohl(tcp_pkt->th_ack) + conn->offset);
272
273
net_checksum_calculate((uint8_t *)pkt->data + pkt->vnet_hdr_len,
274
- pkt->size - pkt->vnet_hdr_len);
275
+ pkt->size - pkt->vnet_hdr_len, CSUM_TCP);
276
}
277
278
/*
279
@@ -XXX,XX +XXX,XX @@ static int handle_secondary_tcp_pkt(RewriterState *rf,
280
tcp_pkt->th_seq = htonl(ntohl(tcp_pkt->th_seq) - conn->offset);
281
282
net_checksum_calculate((uint8_t *)pkt->data + pkt->vnet_hdr_len,
283
- pkt->size - pkt->vnet_hdr_len);
284
+ pkt->size - pkt->vnet_hdr_len, CSUM_TCP);
285
}
286
}
287
288
--
120
--
289
2.7.4
121
2.7.4
290
122
291
123
diff view generated by jsdifflib
1
From: Guishan Qin <guishan.qin@windriver.com>
1
From: Zhang Chen <chen.zhang@intel.com>
2
2
3
At present net_checksum_calculate() only calculates TCP/UDP checksum
3
Make the comments consistent with the REGULAR_PACKET_CHECK_MS.
4
in an IP packet, but assumes the IP header checksum to be provided
5
by the software, e.g.: Linux kernel always calculates the IP header
6
checksum. However this might not always be the case, e.g.: for an IP
7
checksum offload enabled stack like VxWorks, the IP header checksum
8
can be zero.
9
4
10
This adds the checksum calculation of the IP header.
5
Signed-off-by: Zhang Chen <chen.zhang@intel.com>
11
12
Signed-off-by: Guishan Qin <guishan.qin@windriver.com>
13
Signed-off-by: Yabing Liu <yabing.liu@windriver.com>
14
Signed-off-by: Bin Meng <bin.meng@windriver.com>
15
Reviewed-by: Cédric Le Goater <clg@kaod.org>
16
Signed-off-by: Jason Wang <jasowang@redhat.com>
6
Signed-off-by: Jason Wang <jasowang@redhat.com>
17
---
7
---
18
net/checksum.c | 8 ++++++--
8
net/colo-compare.c | 2 +-
19
1 file changed, 6 insertions(+), 2 deletions(-)
9
1 file changed, 1 insertion(+), 1 deletion(-)
20
10
21
diff --git a/net/checksum.c b/net/checksum.c
11
diff --git a/net/colo-compare.c b/net/colo-compare.c
22
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
23
--- a/net/checksum.c
13
--- a/net/colo-compare.c
24
+++ b/net/checksum.c
14
+++ b/net/colo-compare.c
25
@@ -XXX,XX +XXX,XX @@ void net_checksum_calculate(uint8_t *data, int length)
15
@@ -XXX,XX +XXX,XX @@ static void colo_compare_complete(UserCreatable *uc, Error **errp)
26
{
27
int mac_hdr_len, ip_len;
28
struct ip_header *ip;
29
+ uint16_t csum;
30
31
/*
32
* Note: We cannot assume "data" is aligned, so the all code uses
33
@@ -XXX,XX +XXX,XX @@ void net_checksum_calculate(uint8_t *data, int length)
34
return; /* not IPv4 */
35
}
16
}
36
17
37
+ /* Calculate IP checksum */
18
if (!s->expired_scan_cycle) {
38
+ stw_he_p(&ip->ip_sum, 0);
19
- /* Set default value to 3000 MS */
39
+ csum = net_raw_checksum((uint8_t *)ip, IP_HDR_GET_LEN(ip));
20
+ /* Set default value to 1000 MS */
40
+ stw_be_p(&ip->ip_sum, csum);
21
s->expired_scan_cycle = REGULAR_PACKET_CHECK_MS;
41
+
42
if (IP4_IS_FRAGMENT(ip)) {
43
return; /* a fragmented IP packet */
44
}
22
}
45
@@ -XXX,XX +XXX,XX @@ void net_checksum_calculate(uint8_t *data, int length)
23
46
switch (ip->ip_p) {
47
case IP_PROTO_TCP:
48
{
49
- uint16_t csum;
50
tcp_header *tcp = (tcp_header *)(ip + 1);
51
52
if (ip_len < sizeof(tcp_header)) {
53
@@ -XXX,XX +XXX,XX @@ void net_checksum_calculate(uint8_t *data, int length)
54
}
55
case IP_PROTO_UDP:
56
{
57
- uint16_t csum;
58
udp_header *udp = (udp_header *)(ip + 1);
59
60
if (ip_len < sizeof(udp_header)) {
61
--
24
--
62
2.7.4
25
2.7.4
63
26
64
27
diff view generated by jsdifflib
1
From: Markus Carlstedt <markus.carlstedt@windriver.com>
1
From: Rao Lei <lei.rao@intel.com>
2
2
3
To calculate the TCP/UDP checksum we need the whole datagram. Unless
3
This patch is to improve the logic of QEMU main thread sleep code in
4
the hardware has some logic to collect all fragments before sending
4
qemu_chr_write_buffer() where it can be blocked and can't run other
5
the whole datagram first, it can only be done by the network stack,
5
coroutines during COLO IO stress test.
6
which is normally the case for the NICs we have seen so far.
7
6
8
Skip these fragmented IP packets to avoid checksum corruption.
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.
9
11
10
Signed-off-by: Markus Carlstedt <markus.carlstedt@windriver.com>
12
Signed-off-by: Lei Rao <lei.rao@intel.com>
11
Signed-off-by: Bin Meng <bin.meng@windriver.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>
12
Signed-off-by: Jason Wang <jasowang@redhat.com>
16
Signed-off-by: Jason Wang <jasowang@redhat.com>
13
---
17
---
14
net/checksum.c | 4 ++++
18
net/filter-mirror.c | 66 ++++++++++++++++++++++++++++++++++++++++++-----------
15
1 file changed, 4 insertions(+)
19
1 file changed, 53 insertions(+), 13 deletions(-)
16
20
17
diff --git a/net/checksum.c b/net/checksum.c
21
diff --git a/net/filter-mirror.c b/net/filter-mirror.c
18
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
19
--- a/net/checksum.c
23
--- a/net/filter-mirror.c
20
+++ b/net/checksum.c
24
+++ b/net/filter-mirror.c
21
@@ -XXX,XX +XXX,XX @@ void net_checksum_calculate(uint8_t *data, int length)
25
@@ -XXX,XX +XXX,XX @@
22
return; /* not IPv4 */
26
#include "chardev/char-fe.h"
27
#include "qemu/iov.h"
28
#include "qemu/sockets.h"
29
+#include "block/aio-wait.h"
30
31
#define TYPE_FILTER_MIRROR "filter-mirror"
32
typedef struct MirrorState MirrorState;
33
@@ -XXX,XX +XXX,XX @@ struct MirrorState {
34
bool vnet_hdr;
35
};
36
37
-static int filter_send(MirrorState *s,
38
- const struct iovec *iov,
39
- int iovcnt)
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,
66
}
23
}
67
}
24
68
25
+ if (IP4_IS_FRAGMENT(ip)) {
69
- buf = g_malloc(size);
26
+ return; /* a fragmented IP packet */
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;
27
+ }
99
+ }
28
+
100
+
29
ip_len = lduw_be_p(&ip->ip_len);
101
+ buf = g_malloc(size);
30
102
+ iov_to_buf(iov, iovcnt, 0, buf, size);
31
/* Last, check that we have enough data for the all IP frame */
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)
32
--
124
--
33
2.7.4
125
2.7.4
34
126
35
127
diff view generated by jsdifflib
New patch
1
From: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
1
2
3
vmnet.framework dependency is added with 'vmnet' option
4
to enable or disable it. Default value is 'auto'.
5
6
vmnet features to be used are available since macOS 11.0,
7
corresponding probe is created into meson.build.
8
9
Signed-off-by: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
10
Signed-off-by: Jason Wang <jasowang@redhat.com>
11
---
12
meson.build | 16 +++++++++++++++-
13
meson_options.txt | 2 ++
14
scripts/meson-buildoptions.sh | 3 +++
15
3 files changed, 20 insertions(+), 1 deletion(-)
16
17
diff --git a/meson.build b/meson.build
18
index XXXXXXX..XXXXXXX 100644
19
--- a/meson.build
20
+++ b/meson.build
21
@@ -XXX,XX +XXX,XX @@ if cocoa.found() and get_option('gtk').enabled()
22
error('Cocoa and GTK+ cannot be enabled at the same time')
23
endif
24
25
+vmnet = dependency('appleframeworks', modules: 'vmnet', required: get_option('vmnet'))
26
+if vmnet.found() and not cc.has_header_symbol('vmnet/vmnet.h',
27
+ 'VMNET_BRIDGED_MODE',
28
+ dependencies: vmnet)
29
+ vmnet = not_found
30
+ if get_option('vmnet').enabled()
31
+ error('vmnet.framework API is outdated')
32
+ else
33
+ warning('vmnet.framework API is outdated, disabling')
34
+ endif
35
+endif
36
+
37
seccomp = not_found
38
if not get_option('seccomp').auto() or have_system or have_tools
39
seccomp = dependency('libseccomp', version: '>=2.3.0',
40
@@ -XXX,XX +XXX,XX @@ config_host_data.set('CONFIG_SECCOMP', seccomp.found())
41
config_host_data.set('CONFIG_SNAPPY', snappy.found())
42
config_host_data.set('CONFIG_USB_LIBUSB', libusb.found())
43
config_host_data.set('CONFIG_VDE', vde.found())
44
+config_host_data.set('CONFIG_VMNET', vmnet.found())
45
config_host_data.set('CONFIG_VHOST_USER_BLK_SERVER', have_vhost_user_blk_server)
46
config_host_data.set('CONFIG_VNC', vnc.found())
47
config_host_data.set('CONFIG_VNC_JPEG', jpeg.found())
48
@@ -XXX,XX +XXX,XX @@ summary(summary_info, bool_yn: true, section: 'Crypto')
49
# Libraries
50
summary_info = {}
51
if targetos == 'darwin'
52
- summary_info += {'Cocoa support': cocoa}
53
+ summary_info += {'Cocoa support': cocoa}
54
+ summary_info += {'vmnet.framework support': vmnet}
55
endif
56
summary_info += {'SDL support': sdl}
57
summary_info += {'SDL image support': sdl_image}
58
diff --git a/meson_options.txt b/meson_options.txt
59
index XXXXXXX..XXXXXXX 100644
60
--- a/meson_options.txt
61
+++ b/meson_options.txt
62
@@ -XXX,XX +XXX,XX @@ option('netmap', type : 'feature', value : 'auto',
63
description: 'netmap network backend support')
64
option('vde', type : 'feature', value : 'auto',
65
description: 'vde network backend support')
66
+option('vmnet', type : 'feature', value : 'auto',
67
+ description: 'vmnet.framework network backend support')
68
option('virglrenderer', type : 'feature', value : 'auto',
69
description: 'virgl rendering support')
70
option('vnc', type : 'feature', value : 'auto',
71
diff --git a/scripts/meson-buildoptions.sh b/scripts/meson-buildoptions.sh
72
index XXXXXXX..XXXXXXX 100644
73
--- a/scripts/meson-buildoptions.sh
74
+++ b/scripts/meson-buildoptions.sh
75
@@ -XXX,XX +XXX,XX @@ meson_options_help() {
76
printf "%s\n" ' u2f U2F emulation support'
77
printf "%s\n" ' usb-redir libusbredir support'
78
printf "%s\n" ' vde vde network backend support'
79
+ printf "%s\n" ' vmnet vmnet.framework network backend support'
80
printf "%s\n" ' vhost-user-blk-server'
81
printf "%s\n" ' build vhost-user-blk server'
82
printf "%s\n" ' virglrenderer virgl rendering support'
83
@@ -XXX,XX +XXX,XX @@ _meson_option_parse() {
84
--disable-usb-redir) printf "%s" -Dusb_redir=disabled ;;
85
--enable-vde) printf "%s" -Dvde=enabled ;;
86
--disable-vde) printf "%s" -Dvde=disabled ;;
87
+ --enable-vmnet) printf "%s" -Dvmnet=enabled ;;
88
+ --disable-vmnet) printf "%s" -Dvmnet=disabled ;;
89
--enable-vhost-user-blk-server) printf "%s" -Dvhost_user_blk_server=enabled ;;
90
--disable-vhost-user-blk-server) printf "%s" -Dvhost_user_blk_server=disabled ;;
91
--enable-virglrenderer) printf "%s" -Dvirglrenderer=enabled ;;
92
--
93
2.7.4
94
95
diff view generated by jsdifflib
1
From: Markus Armbruster <armbru@redhat.com>
1
From: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
2
2
3
CLI -netdev accumulates in option group "netdev".
3
Create separate netdevs for each vmnet operating mode:
4
- vmnet-host
5
- vmnet-shared
6
- vmnet-bridged
4
7
5
Before commit 08712fcb85 "net: Track netdevs in NetClientState rather
8
Signed-off-by: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
6
than QemuOpt", netdev_add added to the option group, and netdev_del
7
removed from it, both HMP and QMP. Thus, every netdev had a
8
corresponding QemuOpts in this option group.
9
10
Commit 08712fcb85 dropped this for QMP netdev_add and both netdev_del.
11
Now a netdev has a corresponding QemuOpts only when it was created
12
with CLI or HMP. Two issues:
13
14
* QMP and HMP netdev_del can leave QemuOpts behind, breaking HMP
15
netdev_add. Reproducer:
16
17
$ qemu-system-x86_64 -S -display none -nodefaults -monitor stdio
18
QEMU 5.1.92 monitor - type 'help' for more information
19
(qemu) netdev_add user,id=net0
20
(qemu) info network
21
net0: index=0,type=user,net=10.0.2.0,restrict=off
22
(qemu) netdev_del net0
23
(qemu) info network
24
(qemu) netdev_add user,id=net0
25
upstream-qemu: Duplicate ID 'net0' for netdev
26
Try "help netdev_add" for more information
27
28
Fix by restoring the QemuOpts deletion in qmp_netdev_del(), but with
29
a guard, because the QemuOpts need not exist.
30
31
* QMP netdev_add loses its "no duplicate ID" check. Reproducer:
32
33
$ qemu-system-x86_64 -S -display none -qmp stdio
34
{"QMP": {"version": {"qemu": {"micro": 92, "minor": 1, "major": 5}, "package": "v5.2.0-rc2-1-g02c1f0142c"}, "capabilities": ["oob"]}}
35
{"execute": "qmp_capabilities"}
36
{"return": {}}
37
{"execute": "netdev_add", "arguments": {"type": "user", "id":"net0"}}
38
{"return": {}}
39
{"execute": "netdev_add", "arguments": {"type": "user", "id":"net0"}}
40
{"return": {}}
41
42
Fix by adding a duplicate ID check to net_client_init1() to replace
43
the lost one. The check is redundant for callers where QemuOpts
44
still checks, i.e. for CLI and HMP.
45
46
Reported-by: Andrew Melnichenko <andrew@daynix.com>
47
Fixes: 08712fcb851034228b61f75bd922863a984a4f60
48
Cc: qemu-stable@nongnu.org
49
Signed-off-by: Markus Armbruster <armbru@redhat.com>
50
Reviewed-by: Eric Blake <eblake@redhat.com>
51
Signed-off-by: Jason Wang <jasowang@redhat.com>
9
Signed-off-by: Jason Wang <jasowang@redhat.com>
52
---
10
---
53
net/net.c | 20 ++++++++++++++++++--
11
net/clients.h | 11 +++++
54
1 file changed, 18 insertions(+), 2 deletions(-)
12
net/meson.build | 7 +++
13
net/net.c | 10 ++++
14
net/vmnet-bridged.m | 25 ++++++++++
15
net/vmnet-common.m | 19 ++++++++
16
net/vmnet-host.c | 24 ++++++++++
17
net/vmnet-shared.c | 25 ++++++++++
18
net/vmnet_int.h | 25 ++++++++++
19
qapi/net.json | 133 +++++++++++++++++++++++++++++++++++++++++++++++++++-
20
9 files changed, 277 insertions(+), 2 deletions(-)
21
create mode 100644 net/vmnet-bridged.m
22
create mode 100644 net/vmnet-common.m
23
create mode 100644 net/vmnet-host.c
24
create mode 100644 net/vmnet-shared.c
25
create mode 100644 net/vmnet_int.h
55
26
27
diff --git a/net/clients.h b/net/clients.h
28
index XXXXXXX..XXXXXXX 100644
29
--- a/net/clients.h
30
+++ b/net/clients.h
31
@@ -XXX,XX +XXX,XX @@ int net_init_vhost_user(const Netdev *netdev, const char *name,
32
33
int net_init_vhost_vdpa(const Netdev *netdev, const char *name,
34
NetClientState *peer, Error **errp);
35
+#ifdef CONFIG_VMNET
36
+int net_init_vmnet_host(const Netdev *netdev, const char *name,
37
+ NetClientState *peer, Error **errp);
38
+
39
+int net_init_vmnet_shared(const Netdev *netdev, const char *name,
40
+ NetClientState *peer, Error **errp);
41
+
42
+int net_init_vmnet_bridged(const Netdev *netdev, const char *name,
43
+ NetClientState *peer, Error **errp);
44
+#endif /* CONFIG_VMNET */
45
+
46
#endif /* QEMU_NET_CLIENTS_H */
47
diff --git a/net/meson.build b/net/meson.build
48
index XXXXXXX..XXXXXXX 100644
49
--- a/net/meson.build
50
+++ b/net/meson.build
51
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_POSIX', if_true: files(tap_posix))
52
softmmu_ss.add(when: 'CONFIG_WIN32', if_true: files('tap-win32.c'))
53
softmmu_ss.add(when: 'CONFIG_VHOST_NET_VDPA', if_true: files('vhost-vdpa.c'))
54
55
+vmnet_files = files(
56
+ 'vmnet-common.m',
57
+ 'vmnet-bridged.m',
58
+ 'vmnet-host.c',
59
+ 'vmnet-shared.c'
60
+)
61
+softmmu_ss.add(when: vmnet, if_true: vmnet_files)
62
subdir('can')
56
diff --git a/net/net.c b/net/net.c
63
diff --git a/net/net.c b/net/net.c
57
index XXXXXXX..XXXXXXX 100644
64
index XXXXXXX..XXXXXXX 100644
58
--- a/net/net.c
65
--- a/net/net.c
59
+++ b/net/net.c
66
+++ b/net/net.c
60
@@ -XXX,XX +XXX,XX @@ static int (* const net_client_init_fun[NET_CLIENT_DRIVER__MAX])(
67
@@ -XXX,XX +XXX,XX @@ static int (* const net_client_init_fun[NET_CLIENT_DRIVER__MAX])(
61
static int net_client_init1(const Netdev *netdev, bool is_netdev, Error **errp)
68
#ifdef CONFIG_L2TPV3
62
{
69
[NET_CLIENT_DRIVER_L2TPV3] = net_init_l2tpv3,
63
NetClientState *peer = NULL;
70
#endif
64
+ NetClientState *nc;
71
+#ifdef CONFIG_VMNET
65
72
+ [NET_CLIENT_DRIVER_VMNET_HOST] = net_init_vmnet_host,
66
if (is_netdev) {
73
+ [NET_CLIENT_DRIVER_VMNET_SHARED] = net_init_vmnet_shared,
67
if (netdev->type == NET_CLIENT_DRIVER_NIC ||
74
+ [NET_CLIENT_DRIVER_VMNET_BRIDGED] = net_init_vmnet_bridged,
68
@@ -XXX,XX +XXX,XX @@ static int net_client_init1(const Netdev *netdev, bool is_netdev, Error **errp)
75
+#endif /* CONFIG_VMNET */
69
}
76
};
70
}
77
71
78
72
+ nc = qemu_find_netdev(netdev->id);
79
@@ -XXX,XX +XXX,XX @@ void show_netdevs(void)
73
+ if (nc) {
80
#ifdef CONFIG_VHOST_VDPA
74
+ error_setg(errp, "Duplicate ID '%s'", netdev->id);
81
"vhost-vdpa",
75
+ return -1;
82
#endif
76
+ }
83
+#ifdef CONFIG_VMNET
77
+
84
+ "vmnet-host",
78
if (net_client_init_fun[netdev->type](netdev, netdev->id, peer, errp) < 0) {
85
+ "vmnet-shared",
79
/* FIXME drop when all init functions store an Error */
86
+ "vmnet-bridged",
80
if (errp && !*errp) {
87
+#endif
81
@@ -XXX,XX +XXX,XX @@ static int net_client_init1(const Netdev *netdev, bool is_netdev, Error **errp)
88
};
82
}
89
83
90
qemu_printf("Available netdev backend types:\n");
84
if (is_netdev) {
91
diff --git a/net/vmnet-bridged.m b/net/vmnet-bridged.m
85
- NetClientState *nc;
92
new file mode 100644
86
-
93
index XXXXXXX..XXXXXXX
87
nc = qemu_find_netdev(netdev->id);
94
--- /dev/null
88
assert(nc);
95
+++ b/net/vmnet-bridged.m
89
nc->is_netdev = true;
96
@@ -XXX,XX +XXX,XX @@
90
@@ -XXX,XX +XXX,XX @@ void qmp_netdev_add(Netdev *netdev, Error **errp)
97
+/*
91
void qmp_netdev_del(const char *id, Error **errp)
98
+ * vmnet-bridged.m
92
{
99
+ *
93
NetClientState *nc;
100
+ * Copyright(c) 2021 Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
94
+ QemuOpts *opts;
101
+ *
95
102
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
96
nc = qemu_find_netdev(id);
103
+ * See the COPYING file in the top-level directory.
97
if (!nc) {
104
+ *
98
@@ -XXX,XX +XXX,XX @@ void qmp_netdev_del(const char *id, Error **errp)
105
+ */
99
}
106
+
100
107
+#include "qemu/osdep.h"
101
qemu_del_net_client(nc);
108
+#include "qapi/qapi-types-net.h"
102
+
109
+#include "vmnet_int.h"
103
+ /*
110
+#include "clients.h"
104
+ * Wart: we need to delete the QemuOpts associated with netdevs
111
+#include "qemu/error-report.h"
105
+ * created via CLI or HMP, to avoid bogus "Duplicate ID" errors in
112
+#include "qapi/error.h"
106
+ * HMP netdev_add.
113
+
107
+ */
114
+#include <vmnet/vmnet.h>
108
+ opts = qemu_opts_find(qemu_find_opts("netdev"), id);
115
+
109
+ if (opts) {
116
+int net_init_vmnet_bridged(const Netdev *netdev, const char *name,
110
+ qemu_opts_del(opts);
117
+ NetClientState *peer, Error **errp)
111
+ }
118
+{
112
}
119
+ error_setg(errp, "vmnet-bridged is not implemented yet");
113
120
+ return -1;
114
static void netfilter_print_info(Monitor *mon, NetFilterState *nf)
121
+}
122
diff --git a/net/vmnet-common.m b/net/vmnet-common.m
123
new file mode 100644
124
index XXXXXXX..XXXXXXX
125
--- /dev/null
126
+++ b/net/vmnet-common.m
127
@@ -XXX,XX +XXX,XX @@
128
+/*
129
+ * vmnet-common.m - network client wrapper for Apple vmnet.framework
130
+ *
131
+ * Copyright(c) 2021 Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
132
+ * Copyright(c) 2021 Phillip Tennen <phillip@axleos.com>
133
+ *
134
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
135
+ * See the COPYING file in the top-level directory.
136
+ *
137
+ */
138
+
139
+#include "qemu/osdep.h"
140
+#include "qapi/qapi-types-net.h"
141
+#include "vmnet_int.h"
142
+#include "clients.h"
143
+#include "qemu/error-report.h"
144
+#include "qapi/error.h"
145
+
146
+#include <vmnet/vmnet.h>
147
diff --git a/net/vmnet-host.c b/net/vmnet-host.c
148
new file mode 100644
149
index XXXXXXX..XXXXXXX
150
--- /dev/null
151
+++ b/net/vmnet-host.c
152
@@ -XXX,XX +XXX,XX @@
153
+/*
154
+ * vmnet-host.c
155
+ *
156
+ * Copyright(c) 2021 Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
157
+ *
158
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
159
+ * See the COPYING file in the top-level directory.
160
+ *
161
+ */
162
+
163
+#include "qemu/osdep.h"
164
+#include "qapi/qapi-types-net.h"
165
+#include "vmnet_int.h"
166
+#include "clients.h"
167
+#include "qemu/error-report.h"
168
+#include "qapi/error.h"
169
+
170
+#include <vmnet/vmnet.h>
171
+
172
+int net_init_vmnet_host(const Netdev *netdev, const char *name,
173
+ NetClientState *peer, Error **errp) {
174
+ error_setg(errp, "vmnet-host is not implemented yet");
175
+ return -1;
176
+}
177
diff --git a/net/vmnet-shared.c b/net/vmnet-shared.c
178
new file mode 100644
179
index XXXXXXX..XXXXXXX
180
--- /dev/null
181
+++ b/net/vmnet-shared.c
182
@@ -XXX,XX +XXX,XX @@
183
+/*
184
+ * vmnet-shared.c
185
+ *
186
+ * Copyright(c) 2021 Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
187
+ *
188
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
189
+ * See the COPYING file in the top-level directory.
190
+ *
191
+ */
192
+
193
+#include "qemu/osdep.h"
194
+#include "qapi/qapi-types-net.h"
195
+#include "vmnet_int.h"
196
+#include "clients.h"
197
+#include "qemu/error-report.h"
198
+#include "qapi/error.h"
199
+
200
+#include <vmnet/vmnet.h>
201
+
202
+int net_init_vmnet_shared(const Netdev *netdev, const char *name,
203
+ NetClientState *peer, Error **errp)
204
+{
205
+ error_setg(errp, "vmnet-shared is not implemented yet");
206
+ return -1;
207
+}
208
diff --git a/net/vmnet_int.h b/net/vmnet_int.h
209
new file mode 100644
210
index XXXXXXX..XXXXXXX
211
--- /dev/null
212
+++ b/net/vmnet_int.h
213
@@ -XXX,XX +XXX,XX @@
214
+/*
215
+ * vmnet_int.h
216
+ *
217
+ * Copyright(c) 2021 Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
218
+ *
219
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
220
+ * See the COPYING file in the top-level directory.
221
+ *
222
+ */
223
+#ifndef VMNET_INT_H
224
+#define VMNET_INT_H
225
+
226
+#include "qemu/osdep.h"
227
+#include "vmnet_int.h"
228
+#include "clients.h"
229
+
230
+#include <vmnet/vmnet.h>
231
+
232
+typedef struct VmnetCommonState {
233
+ NetClientState nc;
234
+
235
+} VmnetCommonState;
236
+
237
+
238
+#endif /* VMNET_INT_H */
239
diff --git a/qapi/net.json b/qapi/net.json
240
index XXXXXXX..XXXXXXX 100644
241
--- a/qapi/net.json
242
+++ b/qapi/net.json
243
@@ -XXX,XX +XXX,XX @@
244
'*queues': 'int' } }
245
246
##
247
+# @NetdevVmnetHostOptions:
248
+#
249
+# vmnet (host mode) network backend.
250
+#
251
+# Allows the vmnet interface to communicate with other vmnet
252
+# interfaces that are in host mode and also with the host.
253
+#
254
+# @start-address: The starting IPv4 address to use for the interface.
255
+# Must be in the private IP range (RFC 1918). Must be
256
+# specified along with @end-address and @subnet-mask.
257
+# This address is used as the gateway address. The
258
+# subsequent address up to and including end-address are
259
+# placed in the DHCP pool.
260
+#
261
+# @end-address: The DHCP IPv4 range end address to use for the
262
+# interface. Must be in the private IP range (RFC 1918).
263
+# Must be specified along with @start-address and
264
+# @subnet-mask.
265
+#
266
+# @subnet-mask: The IPv4 subnet mask to use on the interface. Must
267
+# be specified along with @start-address and @subnet-mask.
268
+#
269
+# @isolated: Enable isolation for this interface. Interface isolation
270
+# ensures that vmnet interface is not able to communicate
271
+# with any other vmnet interfaces. Only communication with
272
+# host is allowed. Available since macOS Big Sur 11.0.
273
+#
274
+# @net-uuid: The identifier (UUID) to uniquely identify the isolated
275
+# network vmnet interface should be added to. If
276
+# set, no DHCP service is provided for this interface and
277
+# network communication is allowed only with other interfaces
278
+# added to this network identified by the UUID. Available
279
+# since macOS Big Sur 11.0.
280
+#
281
+# Since: 7.0
282
+##
283
+{ 'struct': 'NetdevVmnetHostOptions',
284
+ 'data': {
285
+ '*start-address': 'str',
286
+ '*end-address': 'str',
287
+ '*subnet-mask': 'str',
288
+ '*isolated': 'bool',
289
+ '*net-uuid': 'str' },
290
+ 'if': 'CONFIG_VMNET' }
291
+
292
+##
293
+# @NetdevVmnetSharedOptions:
294
+#
295
+# vmnet (shared mode) network backend.
296
+#
297
+# Allows traffic originating from the vmnet interface to reach the
298
+# Internet through a network address translator (NAT).
299
+# The vmnet interface can communicate with the host and with
300
+# other shared mode interfaces on the same subnet. If no DHCP
301
+# settings, subnet mask and IPv6 prefix specified, the interface can
302
+# communicate with any of other interfaces in shared mode.
303
+#
304
+# @start-address: The starting IPv4 address to use for the interface.
305
+# Must be in the private IP range (RFC 1918). Must be
306
+# specified along with @end-address and @subnet-mask.
307
+# This address is used as the gateway address. The
308
+# subsequent address up to and including end-address are
309
+# placed in the DHCP pool.
310
+#
311
+# @end-address: The DHCP IPv4 range end address to use for the
312
+# interface. Must be in the private IP range (RFC 1918).
313
+# Must be specified along with @start-address and @subnet-mask.
314
+#
315
+# @subnet-mask: The IPv4 subnet mask to use on the interface. Must
316
+# be specified along with @start-address and @subnet-mask.
317
+#
318
+# @isolated: Enable isolation for this interface. Interface isolation
319
+# ensures that vmnet interface is not able to communicate
320
+# with any other vmnet interfaces. Only communication with
321
+# host is allowed. Available since macOS Big Sur 11.0.
322
+#
323
+# @nat66-prefix: The IPv6 prefix to use into guest network. Must be a
324
+# unique local address i.e. start with fd00::/8 and have
325
+# length of 64.
326
+#
327
+# Since: 7.0
328
+##
329
+{ 'struct': 'NetdevVmnetSharedOptions',
330
+ 'data': {
331
+ '*start-address': 'str',
332
+ '*end-address': 'str',
333
+ '*subnet-mask': 'str',
334
+ '*isolated': 'bool',
335
+ '*nat66-prefix': 'str' },
336
+ 'if': 'CONFIG_VMNET' }
337
+
338
+##
339
+# @NetdevVmnetBridgedOptions:
340
+#
341
+# vmnet (bridged mode) network backend.
342
+#
343
+# Bridges the vmnet interface with a physical network interface.
344
+#
345
+# @ifname: The name of the physical interface to be bridged.
346
+#
347
+# @isolated: Enable isolation for this interface. Interface isolation
348
+# ensures that vmnet interface is not able to communicate
349
+# with any other vmnet interfaces. Only communication with
350
+# host is allowed. Available since macOS Big Sur 11.0.
351
+#
352
+# Since: 7.0
353
+##
354
+{ 'struct': 'NetdevVmnetBridgedOptions',
355
+ 'data': {
356
+ 'ifname': 'str',
357
+ '*isolated': 'bool' },
358
+ 'if': 'CONFIG_VMNET' }
359
+
360
+##
361
# @NetClientDriver:
362
#
363
# Available netdev drivers.
364
@@ -XXX,XX +XXX,XX @@
365
# Since: 2.7
366
#
367
# @vhost-vdpa since 5.1
368
+# @vmnet-host since 7.0
369
+# @vmnet-shared since 7.0
370
+# @vmnet-bridged since 7.0
371
##
372
{ 'enum': 'NetClientDriver',
373
'data': [ 'none', 'nic', 'user', 'tap', 'l2tpv3', 'socket', 'vde',
374
- 'bridge', 'hubport', 'netmap', 'vhost-user', 'vhost-vdpa' ] }
375
+ 'bridge', 'hubport', 'netmap', 'vhost-user', 'vhost-vdpa',
376
+ { 'name': 'vmnet-host', 'if': 'CONFIG_VMNET' },
377
+ { 'name': 'vmnet-shared', 'if': 'CONFIG_VMNET' },
378
+ { 'name': 'vmnet-bridged', 'if': 'CONFIG_VMNET' }] }
379
380
##
381
# @Netdev:
382
@@ -XXX,XX +XXX,XX @@
383
# Since: 1.2
384
#
385
# 'l2tpv3' - since 2.1
386
+# 'vmnet-host' - since 7.0
387
+# 'vmnet-shared' - since 7.0
388
+# 'vmnet-bridged' - since 7.0
389
##
390
{ 'union': 'Netdev',
391
'base': { 'id': 'str', 'type': 'NetClientDriver' },
392
@@ -XXX,XX +XXX,XX @@
393
'hubport': 'NetdevHubPortOptions',
394
'netmap': 'NetdevNetmapOptions',
395
'vhost-user': 'NetdevVhostUserOptions',
396
- 'vhost-vdpa': 'NetdevVhostVDPAOptions' } }
397
+ 'vhost-vdpa': 'NetdevVhostVDPAOptions',
398
+ 'vmnet-host': { 'type': 'NetdevVmnetHostOptions',
399
+ 'if': 'CONFIG_VMNET' },
400
+ 'vmnet-shared': { 'type': 'NetdevVmnetSharedOptions',
401
+ 'if': 'CONFIG_VMNET' },
402
+ 'vmnet-bridged': { 'type': 'NetdevVmnetBridgedOptions',
403
+ 'if': 'CONFIG_VMNET' } } }
404
405
##
406
# @RxState:
115
--
407
--
116
2.7.4
408
2.7.4
117
409
118
410
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 | 314 +++++++++++++++++++++++++++++++++++++++++++++++++++++
26
net/vmnet-shared.c | 83 +++++++++++++-
27
net/vmnet_int.h | 23 ++++
28
3 files changed, 416 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
+#if defined(MAC_OS_VERSION_11_0) && \
191
+ MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_VERSION_11_0
192
+ case VMNET_SHARING_SERVICE_BUSY:
193
+ return "conflict, sharing service is in use";
194
+#endif
195
+ default:
196
+ return "unknown vmnet error";
197
+ }
198
+}
199
+
200
+
201
+int vmnet_if_create(NetClientState *nc,
202
+ xpc_object_t if_desc,
203
+ Error **errp,
204
+ void (*completion_callback)(xpc_object_t interface_param))
205
+{
206
+ VmnetCommonState *s;
207
+
208
+ dispatch_queue_t if_create_q;
209
+ dispatch_semaphore_t if_created_sem;
210
+
211
+ __block vmnet_return_t if_status;
212
+
213
+ if_create_q = dispatch_queue_create("org.qemu.vmnet.create",
214
+ DISPATCH_QUEUE_SERIAL);
215
+ if_created_sem = dispatch_semaphore_create(0);
216
+
217
+ xpc_dictionary_set_bool(
218
+ if_desc,
219
+ vmnet_allocate_mac_address_key,
220
+ false
221
+ );
222
+
223
+ D(D_LOG("vmnet.start.interface_desc:\n");
224
+ xpc_dictionary_apply(if_desc,
225
+ ^bool(const char *k, xpc_object_t v) {
226
+ char *desc = xpc_copy_description(v);
227
+ D_LOG(" %s=%s\n", k, desc);
228
+ free(desc);
229
+ return true;
230
+ }));
231
+
232
+ s = DO_UPCAST(VmnetCommonState, nc, nc);
233
+ s->vmnet_if = vmnet_start_interface(
234
+ if_desc,
235
+ if_create_q,
236
+ ^(vmnet_return_t status, xpc_object_t interface_param) {
237
+ if_status = status;
238
+ if (status != VMNET_SUCCESS || !interface_param) {
239
+ dispatch_semaphore_signal(if_created_sem);
240
+ return;
241
+ }
242
+
243
+ D(D_LOG("vmnet.start.interface_param:\n");
244
+ xpc_dictionary_apply(interface_param,
245
+ ^bool(const char *k, xpc_object_t v) {
246
+ char *desc = xpc_copy_description(v);
247
+ D_LOG(" %s=%s\n", k, desc);
248
+ free(desc);
249
+ return true;
250
+ }));
251
+
252
+ s->mtu = xpc_dictionary_get_uint64(
253
+ interface_param,
254
+ vmnet_mtu_key);
255
+ s->max_packet_size = xpc_dictionary_get_uint64(
256
+ interface_param,
257
+ vmnet_max_packet_size_key);
258
+
259
+ if (completion_callback) {
260
+ completion_callback(interface_param);
261
+ }
262
+ dispatch_semaphore_signal(if_created_sem);
263
+ });
264
+
265
+ if (s->vmnet_if == NULL) {
266
+ error_setg(errp, "unable to create interface with requested params");
267
+ return -1;
268
+ }
269
+
270
+ dispatch_semaphore_wait(if_created_sem, DISPATCH_TIME_FOREVER);
271
+ dispatch_release(if_create_q);
272
+
273
+ if (if_status != VMNET_SUCCESS) {
274
+ error_setg(errp,
275
+ "cannot create vmnet interface: %s",
276
+ vmnet_status_map_str(if_status));
277
+ return -1;
278
+ }
279
+
280
+ vmnet_register_event_callback(s);
281
+ vmnet_bufs_init(s);
282
+ vmnet_set_send_enabled(s, true);
283
+
284
+ return 0;
285
+}
286
+
287
+
288
+ssize_t vmnet_receive_common(NetClientState *nc,
289
+ const uint8_t *buf,
290
+ size_t size)
291
+{
292
+ VmnetCommonState *s;
293
+ vmpktdesc_t packet;
294
+ iovec_t iov;
295
+ int pkt_cnt;
296
+ vmnet_return_t if_status;
297
+
298
+ s = DO_UPCAST(VmnetCommonState, nc, nc);
299
+
300
+ if (size > s->max_packet_size) {
301
+ warn_report("vmnet: packet is too big, %zu > %llu\n",
302
+ packet.vm_pkt_size,
303
+ s->max_packet_size);
304
+ return -1;
305
+ }
306
+
307
+ iov.iov_base = (char *) buf;
308
+ iov.iov_len = size;
309
+
310
+ packet.vm_pkt_iovcnt = 1;
311
+ packet.vm_flags = 0;
312
+ packet.vm_pkt_size = size;
313
+ packet.vm_pkt_iov = &iov;
314
+
315
+ pkt_cnt = 1;
316
+ if_status = vmnet_write(s->vmnet_if, &packet, &pkt_cnt);
317
+
318
+ if (if_status != VMNET_SUCCESS) {
319
+ error_report("vmnet: write error: %s\n",
320
+ vmnet_status_map_str(if_status));
321
+ }
322
+
323
+ if (if_status == VMNET_SUCCESS && pkt_cnt) {
324
+ return size;
325
+ }
326
+ return 0;
327
+}
328
+
329
+
330
+void vmnet_cleanup_common(NetClientState *nc)
331
+{
332
+ VmnetCommonState *s;
333
+ dispatch_queue_t if_destroy_q;
334
+
335
+ s = DO_UPCAST(VmnetCommonState, nc, nc);
336
+
337
+ qemu_purge_queued_packets(nc);
338
+ vmnet_set_send_enabled(s, false);
339
+
340
+ if (s->vmnet_if == NULL) {
341
+ return;
342
+ }
343
+
344
+ if_destroy_q = dispatch_queue_create(
345
+ "org.qemu.vmnet.destroy",
346
+ DISPATCH_QUEUE_SERIAL
347
+ );
348
+
349
+ vmnet_stop_interface(
350
+ s->vmnet_if,
351
+ if_destroy_q,
352
+ ^(vmnet_return_t status) {
353
+ });
354
+
355
+ for (int i = 0; i < VMNET_PACKETS_LIMIT; ++i) {
356
+ g_free(s->iov_buf[i].iov_base);
357
+ }
358
+}
359
diff --git a/net/vmnet-shared.c b/net/vmnet-shared.c
360
index XXXXXXX..XXXXXXX 100644
361
--- a/net/vmnet-shared.c
362
+++ b/net/vmnet-shared.c
363
@@ -XXX,XX +XXX,XX @@
364
365
#include "qemu/osdep.h"
366
#include "qapi/qapi-types-net.h"
367
+#include "qapi/error.h"
368
#include "vmnet_int.h"
369
#include "clients.h"
370
-#include "qemu/error-report.h"
371
-#include "qapi/error.h"
372
373
#include <vmnet/vmnet.h>
374
375
+typedef struct VmnetSharedState {
376
+ VmnetCommonState cs;
377
+} VmnetSharedState;
378
+
379
+
380
+static xpc_object_t create_if_desc(const Netdev *netdev, Error **errp)
381
+{
382
+ const NetdevVmnetSharedOptions *options = &(netdev->u.vmnet_shared);
383
+ xpc_object_t if_desc = xpc_dictionary_create(NULL, NULL, 0);
384
+
385
+ xpc_dictionary_set_uint64(
386
+ if_desc,
387
+ vmnet_operation_mode_key,
388
+ VMNET_SHARED_MODE
389
+ );
390
+
391
+#if defined(MAC_OS_VERSION_11_0) && \
392
+ MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_VERSION_11_0
393
+ xpc_dictionary_set_bool(
394
+ if_desc,
395
+ vmnet_enable_isolation_key,
396
+ options->isolated
397
+ );
398
+#else
399
+ if (options->has_isolated) {
400
+ error_setg(errp,
401
+ "vmnet-shared.isolated feature is "
402
+ "unavailable: outdated vmnet.framework API");
403
+ }
404
+#endif
405
+
406
+ if (options->has_nat66_prefix) {
407
+ xpc_dictionary_set_string(if_desc,
408
+ vmnet_nat66_prefix_key,
409
+ options->nat66_prefix);
410
+ }
411
+
412
+ if (options->has_start_address ||
413
+ options->has_end_address ||
414
+ options->has_subnet_mask) {
415
+
416
+ if (options->has_start_address &&
417
+ options->has_end_address &&
418
+ options->has_subnet_mask) {
419
+
420
+ xpc_dictionary_set_string(if_desc,
421
+ vmnet_start_address_key,
422
+ options->start_address);
423
+ xpc_dictionary_set_string(if_desc,
424
+ vmnet_end_address_key,
425
+ options->end_address);
426
+ xpc_dictionary_set_string(if_desc,
427
+ vmnet_subnet_mask_key,
428
+ options->subnet_mask);
429
+ } else {
430
+ error_setg(
431
+ errp,
432
+ "'start-address', 'end-address', 'subnet-mask' "
433
+ "should be provided together"
434
+ );
435
+ }
436
+ }
437
+
438
+ return if_desc;
439
+}
440
+
441
+static NetClientInfo net_vmnet_shared_info = {
442
+ .type = NET_CLIENT_DRIVER_VMNET_SHARED,
443
+ .size = sizeof(VmnetSharedState),
444
+ .receive = vmnet_receive_common,
445
+ .cleanup = vmnet_cleanup_common,
446
+};
447
+
448
int net_init_vmnet_shared(const Netdev *netdev, const char *name,
449
NetClientState *peer, Error **errp)
450
{
451
- error_setg(errp, "vmnet-shared is not implemented yet");
452
- return -1;
453
+ NetClientState *nc = qemu_new_net_client(&net_vmnet_shared_info,
454
+ peer, "vmnet-shared", name);
455
+ xpc_object_t if_desc = create_if_desc(netdev, errp);
456
+
457
+ return vmnet_if_create(nc, if_desc, errp, NULL);
458
}
459
diff --git a/net/vmnet_int.h b/net/vmnet_int.h
460
index XXXXXXX..XXXXXXX 100644
461
--- a/net/vmnet_int.h
462
+++ b/net/vmnet_int.h
463
@@ -XXX,XX +XXX,XX @@
464
465
#include <vmnet/vmnet.h>
466
467
+#define VMNET_PACKETS_LIMIT 50
468
+
469
typedef struct VmnetCommonState {
470
NetClientState nc;
471
+ interface_ref vmnet_if;
472
+
473
+ bool send_enabled;
474
+
475
+ uint64_t mtu;
476
+ uint64_t max_packet_size;
477
+
478
+ struct vmpktdesc packets_buf[VMNET_PACKETS_LIMIT];
479
+ struct iovec iov_buf[VMNET_PACKETS_LIMIT];
480
481
} VmnetCommonState;
482
483
+const char *vmnet_status_map_str(vmnet_return_t status);
484
+
485
+int vmnet_if_create(NetClientState *nc,
486
+ xpc_object_t if_desc,
487
+ Error **errp,
488
+ void (*completion_callback)(xpc_object_t interface_param));
489
+
490
+ssize_t vmnet_receive_common(NetClientState *nc,
491
+ const uint8_t *buf,
492
+ size_t size);
493
+
494
+void vmnet_cleanup_common(NetClientState *nc);
495
496
#endif /* VMNET_INT_H */
497
--
498
2.7.4
499
500
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 | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++++---
7
1 file changed, 104 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
+
39
+ xpc_object_t if_desc = xpc_dictionary_create(NULL, NULL, 0);
40
+
41
+ xpc_dictionary_set_uint64(
42
+ if_desc,
43
+ vmnet_operation_mode_key,
44
+ VMNET_HOST_MODE
45
+ );
46
+
47
+#if defined(MAC_OS_VERSION_11_0) && \
48
+ MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_VERSION_11_0
49
+
50
+ VmnetCommonState *cs = DO_UPCAST(VmnetCommonState, nc, nc);
51
+ VmnetHostState *hs = DO_UPCAST(VmnetHostState, cs, cs);
52
+
53
+ xpc_dictionary_set_bool(
54
+ if_desc,
55
+ vmnet_enable_isolation_key,
56
+ options->isolated
57
+ );
58
+
59
+ if (options->has_net_uuid) {
60
+ if (qemu_uuid_parse(options->net_uuid, &hs->network_uuid) < 0) {
61
+ error_setg(errp, "Invalid UUID provided in 'net-uuid'");
62
+ }
63
+
64
+ xpc_dictionary_set_uuid(
65
+ if_desc,
66
+ vmnet_network_identifier_key,
67
+ hs->network_uuid.data
68
+ );
69
+ }
70
+#else
71
+ if (options->has_isolated) {
72
+ error_setg(errp,
73
+ "vmnet-host.isolated feature is "
74
+ "unavailable: outdated vmnet.framework API");
75
+ }
76
+
77
+ if (options->has_net_uuid) {
78
+ error_setg(errp,
79
+ "vmnet-host.net-uuid feature is "
80
+ "unavailable: outdated vmnet.framework API");
81
+ }
82
+#endif
83
+
84
+ if (options->has_start_address ||
85
+ options->has_end_address ||
86
+ options->has_subnet_mask) {
87
+
88
+ if (options->has_start_address &&
89
+ options->has_end_address &&
90
+ options->has_subnet_mask) {
91
+
92
+ xpc_dictionary_set_string(if_desc,
93
+ vmnet_start_address_key,
94
+ options->start_address);
95
+ xpc_dictionary_set_string(if_desc,
96
+ vmnet_end_address_key,
97
+ options->end_address);
98
+ xpc_dictionary_set_string(if_desc,
99
+ vmnet_subnet_mask_key,
100
+ options->subnet_mask);
101
+ } else {
102
+ error_setg(
103
+ errp,
104
+ "'start-address', 'end-address', 'subnet-mask' "
105
+ "should be provided together"
106
+ );
107
+ }
108
+ }
109
+
110
+ return if_desc;
111
+}
112
+
113
+static NetClientInfo net_vmnet_host_info = {
114
+ .type = NET_CLIENT_DRIVER_VMNET_HOST,
115
+ .size = sizeof(VmnetHostState),
116
+ .receive = vmnet_receive_common,
117
+ .cleanup = vmnet_cleanup_common,
118
+};
119
+
120
int net_init_vmnet_host(const Netdev *netdev, const char *name,
121
- NetClientState *peer, Error **errp) {
122
- error_setg(errp, "vmnet-host is not implemented yet");
123
- return -1;
124
+ NetClientState *peer, Error **errp)
125
+{
126
+ NetClientState *nc;
127
+ xpc_object_t if_desc;
128
+
129
+ nc = qemu_new_net_client(&net_vmnet_host_info,
130
+ peer, "vmnet-host", name);
131
+ if_desc = create_if_desc(netdev, nc, errp);
132
+ return vmnet_if_create(nc, if_desc, errp, NULL);
133
}
134
--
135
2.7.4
136
137
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 | 105 +++++++++++++++++++++++++++++++++++++++++++++++++---
7
1 file changed, 100 insertions(+), 5 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
+#if defined(MAC_OS_VERSION_11_0) && \
81
+ MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_VERSION_11_0
82
+ xpc_dictionary_set_bool(
83
+ if_desc,
84
+ vmnet_enable_isolation_key,
85
+ options->isolated
86
+ );
87
+#else
88
+ if (options->has_isolated) {
89
+ error_setg(errp,
90
+ "vmnet-bridged.isolated feature is "
91
+ "unavailable: outdated vmnet.framework API");
92
+ }
93
+#endif
94
+
95
+ if (validate_ifname(options->ifname)) {
96
+ xpc_dictionary_set_string(if_desc,
97
+ vmnet_shared_interface_name_key,
98
+ options->ifname);
99
+ } else {
100
+ return NULL;
101
+ }
102
+ return if_desc;
103
+}
104
+
105
+static NetClientInfo net_vmnet_bridged_info = {
106
+ .type = NET_CLIENT_DRIVER_VMNET_BRIDGED,
107
+ .size = sizeof(VmnetBridgedState),
108
+ .receive = vmnet_receive_common,
109
+ .cleanup = vmnet_cleanup_common,
110
+};
111
+
112
int net_init_vmnet_bridged(const Netdev *netdev, const char *name,
113
NetClientState *peer, Error **errp)
114
{
115
- error_setg(errp, "vmnet-bridged is not implemented yet");
116
- return -1;
117
+ NetClientState *nc = qemu_new_net_client(&net_vmnet_bridged_info,
118
+ peer, "vmnet-bridged", name);
119
+ xpc_object_t if_desc = create_if_desc(netdev, errp);;
120
+
121
+ if (!if_desc) {
122
+ error_setg(errp,
123
+ "unsupported ifname, should be one of: %s",
124
+ get_valid_ifnames());
125
+ return -1;
126
+ }
127
+
128
+ return vmnet_if_create(nc, if_desc, errp, NULL);
129
}
130
--
131
2.7.4
132
133
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
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
MAINTAINERS | 5 +++++
7
1 file changed, 5 insertions(+)
8
9
diff --git a/MAINTAINERS b/MAINTAINERS
10
index XXXXXXX..XXXXXXX 100644
11
--- a/MAINTAINERS
12
+++ b/MAINTAINERS
13
@@ -XXX,XX +XXX,XX @@ W: http://info.iet.unipi.it/~luigi/netmap/
14
S: Maintained
15
F: net/netmap.c
16
17
+Apple vmnet network backends
18
+M: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
19
+S: Maintained
20
+F: net/vmnet*
21
+
22
Host Memory Backends
23
M: David Hildenbrand <david@redhat.com>
24
M: Igor Mammedov <imammedo@redhat.com>
25
--
26
2.7.4
27
28
diff view generated by jsdifflib