1
The following changes since commit 23895cbd82be95428e90168b12e925d0d3ca2f06:
1
The following changes since commit f670b3eec7f5d1ed8c4573ef244e7b8c6b32001b:
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 'migration-20230213-pull-request' of https://gitlab.com/juan.quintela/qemu into staging (2023-02-13 11:54:05 +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 9925990d01a92564af55f6f69d0f5f59b47609b1:
9
for you to fetch changes up to e4b953a26da11d214f91516cb9b0542eab5afaa0:
10
10
11
net: Use correct default-path macro for downscript (2020-11-24 10:40:17 +0800)
11
vdpa: fix VHOST_BACKEND_F_IOTLB_ASID flag check (2023-02-14 14:00:30 +0800)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
14
15
----------------------------------------------------------------
15
----------------------------------------------------------------
16
Keqian Zhu (1):
16
Christian Svensson (1):
17
net: Use correct default-path macro for downscript
17
net: Increase L2TPv3 buffer to fit jumboframes
18
18
19
Paolo Bonzini (1):
19
Eugenio Pérez (1):
20
net: do not exit on "netdev_add help" monitor command
20
vdpa: fix VHOST_BACKEND_F_IOTLB_ASID flag check
21
21
22
Prasad J Pandit (1):
22
Fiona Ebner (1):
23
hw/net/e1000e: advance desc_offset in case of null descriptor
23
hw/net/vmxnet3: allow VMXNET3_MAX_MTU itself as a value
24
24
25
Yuri Benditovich (1):
25
Joelle van Dyne (1):
26
net: purge queued rx packets on queue deletion
26
vmnet: stop recieving events when VM is stopped
27
27
28
yuanjungong (1):
28
Laurent Vivier (1):
29
tap: fix a memory leak
29
net: stream: add a new option to automatically reconnect
30
30
31
hw/net/e1000e_core.c | 8 +++---
31
Qiang Liu (2):
32
include/net/net.h | 1 +
32
hw/net/lan9118: log [read|write]b when mode_16bit is enabled rather than abort
33
monitor/hmp-cmds.c | 6 ++++
33
hw/net/can/xlnx-zynqmp-can: fix assertion failures in transfer_fifo()
34
net/net.c | 80 +++++++++++++++++++++++++++-------------------------
34
35
net/tap.c | 5 +++-
35
Thomas Huth (3):
36
5 files changed, 57 insertions(+), 43 deletions(-)
36
net: Move the code to collect available NIC models to a separate function
37
net: Restore printing of the help text with "-nic help"
38
net: Replace "Supported NIC models" with "Available NIC models"
39
40
hw/net/can/xlnx-zynqmp-can.c | 9 +++-
41
hw/net/lan9118.c | 17 ++++----
42
hw/net/vmxnet3.c | 2 +-
43
hw/pci/pci.c | 29 +------------
44
include/net/net.h | 14 ++++++
45
net/l2tpv3.c | 2 +-
46
net/net.c | 50 +++++++++++++++++++--
47
net/stream.c | 53 ++++++++++++++++++++++-
48
net/vhost-vdpa.c | 2 +-
49
net/vmnet-common.m | 48 ++++++++++++++------
50
net/vmnet_int.h | 2 +
51
qapi/net.json | 7 ++-
52
qemu-options.hx | 6 +--
53
tests/qtest/netdev-socket.c | 101 +++++++++++++++++++++++++++++++++++++++++++
54
14 files changed, 280 insertions(+), 62 deletions(-)
37
55
38
56
diff view generated by jsdifflib
1
From: Paolo Bonzini <pbonzini@redhat.com>
1
From: Thomas Huth <thuth@redhat.com>
2
2
3
"netdev_add help" is causing QEMU to exit because the code that
3
The code that collects the available NIC models is not really specific
4
invokes show_netdevs is shared between CLI and HMP processing.
4
to PCI anymore and will be required in the next patch, too, so let's
5
Move the check to the callers so that exit(0) remains only
5
move this into a new separate function in net.c instead.
6
in the CLI flow.
7
6
8
"netdev_add help" is not fixed by this patch; that is left for
7
Signed-off-by: Thomas Huth <thuth@redhat.com>
9
later work.
10
11
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
12
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
Signed-off-by: Jason Wang <jasowang@redhat.com>
13
---
9
---
14
include/net/net.h | 1 +
10
hw/pci/pci.c | 29 +----------------------------
15
monitor/hmp-cmds.c | 6 +++++
11
include/net/net.h | 14 ++++++++++++++
16
net/net.c | 68 +++++++++++++++++++++++++++---------------------------
12
net/net.c | 34 ++++++++++++++++++++++++++++++++++
17
3 files changed, 41 insertions(+), 34 deletions(-)
13
3 files changed, 49 insertions(+), 28 deletions(-)
18
14
15
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/pci/pci.c
18
+++ b/hw/pci/pci.c
19
@@ -XXX,XX +XXX,XX @@ PCIDevice *pci_nic_init_nofail(NICInfo *nd, PCIBus *rootbus,
20
const char *default_devaddr)
21
{
22
const char *devaddr = nd->devaddr ? nd->devaddr : default_devaddr;
23
- GSList *list;
24
GPtrArray *pci_nic_models;
25
PCIBus *bus;
26
PCIDevice *pci_dev;
27
@@ -XXX,XX +XXX,XX @@ PCIDevice *pci_nic_init_nofail(NICInfo *nd, PCIBus *rootbus,
28
nd->model = g_strdup("virtio-net-pci");
29
}
30
31
- list = object_class_get_list_sorted(TYPE_PCI_DEVICE, false);
32
- pci_nic_models = g_ptr_array_new();
33
- while (list) {
34
- DeviceClass *dc = OBJECT_CLASS_CHECK(DeviceClass, list->data,
35
- TYPE_DEVICE);
36
- GSList *next;
37
- if (test_bit(DEVICE_CATEGORY_NETWORK, dc->categories) &&
38
- dc->user_creatable) {
39
- const char *name = object_class_get_name(list->data);
40
- /*
41
- * A network device might also be something else than a NIC, see
42
- * e.g. the "rocker" device. Thus we have to look for the "netdev"
43
- * property, too. Unfortunately, some devices like virtio-net only
44
- * create this property during instance_init, so we have to create
45
- * a temporary instance here to be able to check it.
46
- */
47
- Object *obj = object_new_with_class(OBJECT_CLASS(dc));
48
- if (object_property_find(obj, "netdev")) {
49
- g_ptr_array_add(pci_nic_models, (gpointer)name);
50
- }
51
- object_unref(obj);
52
- }
53
- next = list->next;
54
- g_slist_free_1(list);
55
- list = next;
56
- }
57
- g_ptr_array_add(pci_nic_models, NULL);
58
+ pci_nic_models = qemu_get_nic_models(TYPE_PCI_DEVICE);
59
60
if (qemu_show_nic_models(nd->model, (const char **)pci_nic_models->pdata)) {
61
exit(0);
19
diff --git a/include/net/net.h b/include/net/net.h
62
diff --git a/include/net/net.h b/include/net/net.h
20
index XXXXXXX..XXXXXXX 100644
63
index XXXXXXX..XXXXXXX 100644
21
--- a/include/net/net.h
64
--- a/include/net/net.h
22
+++ b/include/net/net.h
65
+++ b/include/net/net.h
23
@@ -XXX,XX +XXX,XX @@ extern const char *host_net_devices[];
66
@@ -XXX,XX +XXX,XX @@ void net_socket_rs_init(SocketReadState *rs,
24
67
bool vnet_hdr);
25
/* from net.c */
68
NetClientState *qemu_get_peer(NetClientState *nc, int queue_index);
26
int net_client_parse(QemuOptsList *opts_list, const char *str);
69
27
+void show_netdevs(void);
70
+/**
28
int net_init_clients(Error **errp);
71
+ * qemu_get_nic_models:
29
void net_check_clients(void);
72
+ * @device_type: Defines which devices should be taken into consideration
30
void net_cleanup(void);
73
+ * (e.g. TYPE_DEVICE for all devices, or TYPE_PCI_DEVICE for PCI)
31
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
74
+ *
32
index XXXXXXX..XXXXXXX 100644
75
+ * Get an array of pointers to names of NIC devices that are available in
33
--- a/monitor/hmp-cmds.c
76
+ * the QEMU binary. The array is terminated with a NULL pointer entry.
34
+++ b/monitor/hmp-cmds.c
77
+ * The caller is responsible for freeing the memory when it is not required
35
@@ -XXX,XX +XXX,XX @@
78
+ * anymore, e.g. with g_ptr_array_free(..., true).
36
#include "qemu/option.h"
79
+ *
37
#include "qemu/timer.h"
80
+ * Returns: Pointer to the array that contains the pointers to the names.
38
#include "qemu/sockets.h"
81
+ */
39
+#include "qemu/help_option.h"
82
+GPtrArray *qemu_get_nic_models(const char *device_type);
40
#include "monitor/monitor-internal.h"
83
+
41
#include "qapi/error.h"
84
/* NIC info */
42
#include "qapi/clone-visitor.h"
85
43
@@ -XXX,XX +XXX,XX @@ void hmp_netdev_add(Monitor *mon, const QDict *qdict)
86
#define MAX_NICS 8
44
{
45
Error *err = NULL;
46
QemuOpts *opts;
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
87
diff --git a/net/net.c b/net/net.c
57
index XXXXXXX..XXXXXXX 100644
88
index XXXXXXX..XXXXXXX 100644
58
--- a/net/net.c
89
--- a/net/net.c
59
+++ b/net/net.c
90
+++ b/net/net.c
60
@@ -XXX,XX +XXX,XX @@
91
@@ -XXX,XX +XXX,XX @@ static int nic_get_free_idx(void)
61
#include "qemu/config-file.h"
92
return -1;
62
#include "qemu/ctype.h"
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
}
93
}
71
94
72
-static void show_netdevs(void)
95
+GPtrArray *qemu_get_nic_models(const char *device_type)
73
+void show_netdevs(void)
96
+{
97
+ GPtrArray *nic_models = g_ptr_array_new();
98
+ GSList *list = object_class_get_list_sorted(device_type, false);
99
+
100
+ while (list) {
101
+ DeviceClass *dc = OBJECT_CLASS_CHECK(DeviceClass, list->data,
102
+ TYPE_DEVICE);
103
+ GSList *next;
104
+ if (test_bit(DEVICE_CATEGORY_NETWORK, dc->categories) &&
105
+ dc->user_creatable) {
106
+ const char *name = object_class_get_name(list->data);
107
+ /*
108
+ * A network device might also be something else than a NIC, see
109
+ * e.g. the "rocker" device. Thus we have to look for the "netdev"
110
+ * property, too. Unfortunately, some devices like virtio-net only
111
+ * create this property during instance_init, so we have to create
112
+ * a temporary instance here to be able to check it.
113
+ */
114
+ Object *obj = object_new_with_class(OBJECT_CLASS(dc));
115
+ if (object_property_find(obj, "netdev")) {
116
+ g_ptr_array_add(nic_models, (gpointer)name);
117
+ }
118
+ object_unref(obj);
119
+ }
120
+ next = list->next;
121
+ g_slist_free_1(list);
122
+ list = next;
123
+ }
124
+ g_ptr_array_add(nic_models, NULL);
125
+
126
+ return nic_models;
127
+}
128
+
129
int qemu_show_nic_models(const char *arg, const char *const *models)
74
{
130
{
75
int idx;
131
int i;
76
const char *available_netdevs[] = {
77
@@ -XXX,XX +XXX,XX @@ static void show_netdevs(void)
78
#endif
79
};
80
81
- printf("Available netdev backend types:\n");
82
+ qemu_printf("Available netdev backend types:\n");
83
for (idx = 0; idx < ARRAY_SIZE(available_netdevs); idx++) {
84
- puts(available_netdevs[idx]);
85
+ qemu_printf("%s\n", available_netdevs[idx]);
86
}
87
}
88
89
@@ -XXX,XX +XXX,XX @@ static int net_client_init(QemuOpts *opts, bool is_netdev, Error **errp)
90
int ret = -1;
91
Visitor *v = opts_visitor_new(opts);
92
93
- const char *type = qemu_opt_get(opts, "type");
94
-
95
- if (is_netdev && type && is_help_option(type)) {
96
- show_netdevs();
97
- exit(0);
98
- } else {
99
- /* Parse convenience option format ip6-net=fec0::0[/64] */
100
- const char *ip6_net = qemu_opt_get(opts, "ipv6-net");
101
+ /* Parse convenience option format ip6-net=fec0::0[/64] */
102
+ const char *ip6_net = qemu_opt_get(opts, "ipv6-net");
103
104
- if (ip6_net) {
105
- char *prefix_addr;
106
- unsigned long prefix_len = 64; /* Default 64bit prefix length. */
107
+ if (ip6_net) {
108
+ char *prefix_addr;
109
+ unsigned long prefix_len = 64; /* Default 64bit prefix length. */
110
111
- substrings = g_strsplit(ip6_net, "/", 2);
112
- if (!substrings || !substrings[0]) {
113
- error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "ipv6-net",
114
- "a valid IPv6 prefix");
115
- goto out;
116
- }
117
+ substrings = g_strsplit(ip6_net, "/", 2);
118
+ if (!substrings || !substrings[0]) {
119
+ error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "ipv6-net",
120
+ "a valid IPv6 prefix");
121
+ goto out;
122
+ }
123
124
- prefix_addr = substrings[0];
125
+ prefix_addr = substrings[0];
126
127
- /* Handle user-specified prefix length. */
128
- if (substrings[1] &&
129
- qemu_strtoul(substrings[1], NULL, 10, &prefix_len))
130
- {
131
- error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
132
- "ipv6-prefixlen", "a number");
133
- goto out;
134
- }
135
-
136
- qemu_opt_set(opts, "ipv6-prefix", prefix_addr, &error_abort);
137
- qemu_opt_set_number(opts, "ipv6-prefixlen", prefix_len,
138
- &error_abort);
139
- qemu_opt_unset(opts, "ipv6-net");
140
+ /* Handle user-specified prefix length. */
141
+ if (substrings[1] &&
142
+ qemu_strtoul(substrings[1], NULL, 10, &prefix_len))
143
+ {
144
+ error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
145
+ "ipv6-prefixlen", "a number");
146
+ goto out;
147
}
148
+
149
+ qemu_opt_set(opts, "ipv6-prefix", prefix_addr, &error_abort);
150
+ qemu_opt_set_number(opts, "ipv6-prefixlen", prefix_len,
151
+ &error_abort);
152
+ qemu_opt_unset(opts, "ipv6-net");
153
}
154
155
/* Create an ID for -net if the user did not specify one */
156
@@ -XXX,XX +XXX,XX @@ static int net_init_client(void *dummy, QemuOpts *opts, Error **errp)
157
158
static int net_init_netdev(void *dummy, QemuOpts *opts, Error **errp)
159
{
160
+ const char *type = qemu_opt_get(opts, "type");
161
+
162
+ if (type && is_help_option(type)) {
163
+ show_netdevs();
164
+ exit(0);
165
+ }
166
return net_client_init(opts, true, errp);
167
}
168
169
--
132
--
170
2.7.4
133
2.7.4
171
172
diff view generated by jsdifflib
1
From: Keqian Zhu <zhukeqian1@huawei.com>
1
From: Thomas Huth <thuth@redhat.com>
2
2
3
Fixes: 63c4db4c2e6d (net: relocate paths to helpers and scripts)
3
Running QEMU with "-nic help" used to work in QEMU 5.2 and earlier versions
4
Signed-off-by: Keqian Zhu <zhukeqian1@huawei.com>
4
(it showed the available netdev backends), but this feature got broken during
5
some refactoring in version 6.0. Let's restore the old behavior, and while
6
we're at it, let's also print the available NIC models here now since this
7
option can be used to configure both, netdev backend and model in one go.
8
9
Fixes: ad6f932fe8 ("net: do not exit on "netdev_add help" monitor command")
10
Signed-off-by: Thomas Huth <thuth@redhat.com>
5
Signed-off-by: Jason Wang <jasowang@redhat.com>
11
Signed-off-by: Jason Wang <jasowang@redhat.com>
6
---
12
---
7
net/tap.c | 3 ++-
13
net/net.c | 14 ++++++++++++--
8
1 file changed, 2 insertions(+), 1 deletion(-)
14
1 file changed, 12 insertions(+), 2 deletions(-)
9
15
10
diff --git a/net/tap.c b/net/tap.c
16
diff --git a/net/net.c b/net/net.c
11
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
12
--- a/net/tap.c
18
--- a/net/net.c
13
+++ b/net/tap.c
19
+++ b/net/net.c
14
@@ -XXX,XX +XXX,XX @@ free_fail:
20
@@ -XXX,XX +XXX,XX @@ static int net_param_nic(void *dummy, QemuOpts *opts, Error **errp)
15
script = default_script = get_relocated_path(DEFAULT_NETWORK_SCRIPT);
21
const char *type;
16
}
22
17
if (!downscript) {
23
type = qemu_opt_get(opts, "type");
18
- downscript = default_downscript = get_relocated_path(DEFAULT_NETWORK_SCRIPT);
24
- if (type && g_str_equal(type, "none")) {
19
+ downscript = default_downscript =
25
- return 0; /* Nothing to do, default_net is cleared in vl.c */
20
+ get_relocated_path(DEFAULT_NETWORK_DOWN_SCRIPT);
26
+ if (type) {
21
}
27
+ if (g_str_equal(type, "none")) {
22
28
+ return 0; /* Nothing to do, default_net is cleared in vl.c */
23
if (tap->has_ifname) {
29
+ }
30
+ if (is_help_option(type)) {
31
+ GPtrArray *nic_models = qemu_get_nic_models(TYPE_DEVICE);
32
+ show_netdevs();
33
+ printf("\n");
34
+ qemu_show_nic_models(type, (const char **)nic_models->pdata);
35
+ g_ptr_array_free(nic_models, true);
36
+ exit(0);
37
+ }
38
}
39
40
idx = nic_get_free_idx();
24
--
41
--
25
2.7.4
42
2.7.4
26
27
diff view generated by jsdifflib
1
From: Yuri Benditovich <yuri.benditovich@daynix.com>
1
From: Thomas Huth <thuth@redhat.com>
2
2
3
https://bugzilla.redhat.com/show_bug.cgi?id=1829272
3
Just because a NIC model is compiled into the QEMU binary does not
4
When deleting queue pair, purge pending RX packets if any.
4
necessary mean that it can be used with each and every machine.
5
Example of problematic flow:
5
So let's rather talk about "available" models instead of "supported"
6
1. Bring up q35 VM with tap (vhost off) and virtio-net or e1000e
6
models, just to avoid confusion.
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
7
15
Signed-off-by: Yuri Benditovich <yuri.benditovich@daynix.com>
8
Reviewed-by: Claudio Fontana <cfontana@suse.de>
9
Signed-off-by: Thomas Huth <thuth@redhat.com>
16
Signed-off-by: Jason Wang <jasowang@redhat.com>
10
Signed-off-by: Jason Wang <jasowang@redhat.com>
17
---
11
---
18
net/net.c | 12 ++++++++----
12
net/net.c | 2 +-
19
1 file changed, 8 insertions(+), 4 deletions(-)
13
1 file changed, 1 insertion(+), 1 deletion(-)
20
14
21
diff --git a/net/net.c b/net/net.c
15
diff --git a/net/net.c b/net/net.c
22
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
23
--- a/net/net.c
17
--- a/net/net.c
24
+++ b/net/net.c
18
+++ b/net/net.c
25
@@ -XXX,XX +XXX,XX @@ void qemu_del_nic(NICState *nic)
19
@@ -XXX,XX +XXX,XX @@ int qemu_show_nic_models(const char *arg, const char *const *models)
26
20
return 0;
27
qemu_macaddr_set_free(&nic->conf->macaddr);
28
29
- /* If this is a peer NIC and peer has already been deleted, free it now. */
30
- if (nic->peer_deleted) {
31
- for (i = 0; i < queues; i++) {
32
- qemu_free_net_client(qemu_get_subqueue(nic, i)->peer);
33
+ for (i = 0; i < queues; i++) {
34
+ NetClientState *nc = qemu_get_subqueue(nic, i);
35
+ /* If this is a peer NIC and peer has already been deleted, free it now. */
36
+ if (nic->peer_deleted) {
37
+ qemu_free_net_client(nc->peer);
38
+ } else if (nc->peer) {
39
+ /* if there are RX packets pending, complete them */
40
+ qemu_purge_queued_packets(nc->peer);
41
}
42
}
21
}
43
22
23
- printf("Supported NIC models:\n");
24
+ printf("Available NIC models:\n");
25
for (i = 0 ; models[i]; i++) {
26
printf("%s\n", models[i]);
27
}
44
--
28
--
45
2.7.4
29
2.7.4
46
47
diff view generated by jsdifflib
1
From: yuanjungong <ruc_gongyuanjun@163.com>
1
From: Qiang Liu <cyruscyliu@gmail.com>
2
2
3
Close fd before returning.
3
This patch replaces hw_error to guest error log for [read|write]b
4
accesses when mode_16bit is enabled. This avoids aborting qemu.
4
5
5
Buglink: https://bugs.launchpad.net/qemu/+bug/1904486
6
Fixes: 1248f8d4cbc3 ("hw/lan9118: Add basic 16-bit mode support.")
6
7
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1433
7
Signed-off-by: yuanjungong <ruc_gongyuanjun@163.com>
8
Reported-by: Qiang Liu <cyruscyliu@gmail.com>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Signed-off-by: Qiang Liu <cyruscyliu@gmail.com>
11
Suggested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Signed-off-by: Jason Wang <jasowang@redhat.com>
12
Signed-off-by: Jason Wang <jasowang@redhat.com>
10
---
13
---
11
net/tap.c | 2 ++
14
hw/net/lan9118.c | 17 ++++++++---------
12
1 file changed, 2 insertions(+)
15
1 file changed, 8 insertions(+), 9 deletions(-)
13
16
14
diff --git a/net/tap.c b/net/tap.c
17
diff --git a/hw/net/lan9118.c b/hw/net/lan9118.c
15
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
16
--- a/net/tap.c
19
--- a/hw/net/lan9118.c
17
+++ b/net/tap.c
20
+++ b/hw/net/lan9118.c
18
@@ -XXX,XX +XXX,XX @@ int net_init_tap(const Netdev *netdev, const char *name,
21
@@ -XXX,XX +XXX,XX @@
19
if (ret < 0) {
22
#include "migration/vmstate.h"
20
error_setg_errno(errp, -ret, "%s: Can't use file descriptor %d",
23
#include "net/net.h"
21
name, fd);
24
#include "net/eth.h"
22
+ close(fd);
25
-#include "hw/hw.h"
23
return -1;
26
#include "hw/irq.h"
24
}
27
#include "hw/net/lan9118.h"
25
28
#include "hw/ptimer.h"
26
@@ -XXX,XX +XXX,XX @@ int net_init_tap(const Netdev *netdev, const char *name,
29
@@ -XXX,XX +XXX,XX @@
27
vhostfdname, vnet_hdr, fd, &err);
30
#ifdef DEBUG_LAN9118
28
if (err) {
31
#define DPRINTF(fmt, ...) \
29
error_propagate(errp, err);
32
do { printf("lan9118: " fmt , ## __VA_ARGS__); } while (0)
30
+ close(fd);
33
-#define BADF(fmt, ...) \
31
return -1;
34
-do { hw_error("lan9118: error: " fmt , ## __VA_ARGS__);} while (0)
32
}
35
#else
33
} else if (tap->has_fds) {
36
#define DPRINTF(fmt, ...) do {} while(0)
37
-#define BADF(fmt, ...) \
38
-do { fprintf(stderr, "lan9118: error: " fmt , ## __VA_ARGS__);} while (0)
39
#endif
40
41
/* The tx and rx fifo ports are a range of aliased 32-bit registers */
42
@@ -XXX,XX +XXX,XX @@ static uint32_t do_phy_read(lan9118_state *s, int reg)
43
case 30: /* Interrupt mask */
44
return s->phy_int_mask;
45
default:
46
- BADF("PHY read reg %d\n", reg);
47
+ qemu_log_mask(LOG_GUEST_ERROR,
48
+ "do_phy_read: PHY read reg %d\n", reg);
49
return 0;
50
}
51
}
52
@@ -XXX,XX +XXX,XX @@ static void do_phy_write(lan9118_state *s, int reg, uint32_t val)
53
phy_update_irq(s);
54
break;
55
default:
56
- BADF("PHY write reg %d = 0x%04x\n", reg, val);
57
+ qemu_log_mask(LOG_GUEST_ERROR,
58
+ "do_phy_write: PHY write reg %d = 0x%04x\n", reg, val);
59
}
60
}
61
62
@@ -XXX,XX +XXX,XX @@ static void lan9118_16bit_mode_write(void *opaque, hwaddr offset,
63
return;
64
}
65
66
- hw_error("lan9118_write: Bad size 0x%x\n", size);
67
+ qemu_log_mask(LOG_GUEST_ERROR,
68
+ "lan9118_16bit_mode_write: Bad size 0x%x\n", size);
69
}
70
71
static uint64_t lan9118_readl(void *opaque, hwaddr offset,
72
@@ -XXX,XX +XXX,XX @@ static uint64_t lan9118_16bit_mode_read(void *opaque, hwaddr offset,
73
return lan9118_readl(opaque, offset, size);
74
}
75
76
- hw_error("lan9118_read: Bad size 0x%x\n", size);
77
+ qemu_log_mask(LOG_GUEST_ERROR,
78
+ "lan9118_16bit_mode_read: Bad size 0x%x\n", size);
79
return 0;
80
}
81
34
--
82
--
35
2.7.4
83
2.7.4
36
84
37
85
diff view generated by jsdifflib
New patch
1
From: Fiona Ebner <f.ebner@proxmox.com>
1
2
3
Currently, VMXNET3_MAX_MTU itself (being 9000) is not considered a
4
valid value for the MTU, but a guest running ESXi 7.0 might try to
5
set it and fail the assert [0].
6
7
In the Linux kernel, dev->max_mtu itself is a valid value for the MTU
8
and for the vmxnet3 driver it's 9000, so a guest running Linux will
9
also fail the assert when trying to set an MTU of 9000.
10
11
VMXNET3_MAX_MTU and s->mtu don't seem to be used in relation to buffer
12
allocations/accesses, so allowing the upper limit itself as a value
13
should be fine.
14
15
[0]: https://forum.proxmox.com/threads/114011/
16
17
Fixes: d05dcd94ae ("net: vmxnet3: validate configuration values during activate (CVE-2021-20203)")
18
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
19
Signed-off-by: Jason Wang <jasowang@redhat.com>
20
---
21
hw/net/vmxnet3.c | 2 +-
22
1 file changed, 1 insertion(+), 1 deletion(-)
23
24
diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c
25
index XXXXXXX..XXXXXXX 100644
26
--- a/hw/net/vmxnet3.c
27
+++ b/hw/net/vmxnet3.c
28
@@ -XXX,XX +XXX,XX @@ static void vmxnet3_activate_device(VMXNET3State *s)
29
vmxnet3_setup_rx_filtering(s);
30
/* Cache fields from shared memory */
31
s->mtu = VMXNET3_READ_DRV_SHARED32(d, s->drv_shmem, devRead.misc.mtu);
32
- assert(VMXNET3_MIN_MTU <= s->mtu && s->mtu < VMXNET3_MAX_MTU);
33
+ assert(VMXNET3_MIN_MTU <= s->mtu && s->mtu <= VMXNET3_MAX_MTU);
34
VMW_CFPRN("MTU is %u", s->mtu);
35
36
s->max_rx_frags =
37
--
38
2.7.4
diff view generated by jsdifflib
New patch
1
From: Christian Svensson <blue@cmd.nu>
1
2
3
Increase the allocated buffer size to fit larger packets.
4
Given that jumboframes can commonly be up to 9000 bytes the closest suitable
5
value seems to be 16 KiB.
6
7
Tested by running qemu towards a Linux L2TPv3 endpoint and pushing
8
jumboframe traffic through the interfaces.
9
10
Signed-off-by: Christian Svensson <blue@cmd.nu>
11
Signed-off-by: Jason Wang <jasowang@redhat.com>
12
---
13
net/l2tpv3.c | 2 +-
14
1 file changed, 1 insertion(+), 1 deletion(-)
15
16
diff --git a/net/l2tpv3.c b/net/l2tpv3.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/net/l2tpv3.c
19
+++ b/net/l2tpv3.c
20
@@ -XXX,XX +XXX,XX @@
21
*/
22
23
#define BUFFER_ALIGN sysconf(_SC_PAGESIZE)
24
-#define BUFFER_SIZE 2048
25
+#define BUFFER_SIZE 16384
26
#define IOVSIZE 2
27
#define MAX_L2TPV3_MSGCNT 64
28
#define MAX_L2TPV3_IOVCNT (MAX_L2TPV3_MSGCNT * IOVSIZE)
29
--
30
2.7.4
diff view generated by jsdifflib
New patch
1
From: Joelle van Dyne <j@getutm.app>
1
2
3
When the VM is stopped using the HMP command "stop", soon the handler will
4
stop reading from the vmnet interface. This causes a flood of
5
`VMNET_INTERFACE_PACKETS_AVAILABLE` events to arrive and puts the host CPU
6
at 100%. We fix this by removing the event handler from vmnet when the VM
7
is no longer in a running state and restore it when we return to a running
8
state.
9
10
Signed-off-by: Joelle van Dyne <j@getutm.app>
11
Signed-off-by: Jason Wang <jasowang@redhat.com>
12
---
13
net/vmnet-common.m | 48 +++++++++++++++++++++++++++++++++++-------------
14
net/vmnet_int.h | 2 ++
15
2 files changed, 37 insertions(+), 13 deletions(-)
16
17
diff --git a/net/vmnet-common.m b/net/vmnet-common.m
18
index XXXXXXX..XXXXXXX 100644
19
--- a/net/vmnet-common.m
20
+++ b/net/vmnet-common.m
21
@@ -XXX,XX +XXX,XX @@
22
#include "clients.h"
23
#include "qemu/error-report.h"
24
#include "qapi/error.h"
25
+#include "sysemu/runstate.h"
26
27
#include <vmnet/vmnet.h>
28
#include <dispatch/dispatch.h>
29
@@ -XXX,XX +XXX,XX @@ static void vmnet_bufs_init(VmnetState *s)
30
}
31
}
32
33
+/**
34
+ * Called on state change to un-register/re-register handlers
35
+ */
36
+static void vmnet_vm_state_change_cb(void *opaque, bool running, RunState state)
37
+{
38
+ VmnetState *s = opaque;
39
+
40
+ if (running) {
41
+ vmnet_interface_set_event_callback(
42
+ s->vmnet_if,
43
+ VMNET_INTERFACE_PACKETS_AVAILABLE,
44
+ s->if_queue,
45
+ ^(interface_event_t event_id, xpc_object_t event) {
46
+ assert(event_id == VMNET_INTERFACE_PACKETS_AVAILABLE);
47
+ /*
48
+ * This function is being called from a non qemu thread, so
49
+ * we only schedule a BH, and do the rest of the io completion
50
+ * handling from vmnet_send_bh() which runs in a qemu context.
51
+ */
52
+ qemu_bh_schedule(s->send_bh);
53
+ });
54
+ } else {
55
+ vmnet_interface_set_event_callback(
56
+ s->vmnet_if,
57
+ VMNET_INTERFACE_PACKETS_AVAILABLE,
58
+ NULL,
59
+ NULL);
60
+ }
61
+}
62
63
int vmnet_if_create(NetClientState *nc,
64
xpc_object_t if_desc,
65
@@ -XXX,XX +XXX,XX @@ int vmnet_if_create(NetClientState *nc,
66
s->packets_send_current_pos = 0;
67
s->packets_send_end_pos = 0;
68
69
- vmnet_interface_set_event_callback(
70
- s->vmnet_if,
71
- VMNET_INTERFACE_PACKETS_AVAILABLE,
72
- s->if_queue,
73
- ^(interface_event_t event_id, xpc_object_t event) {
74
- assert(event_id == VMNET_INTERFACE_PACKETS_AVAILABLE);
75
- /*
76
- * This function is being called from a non qemu thread, so
77
- * we only schedule a BH, and do the rest of the io completion
78
- * handling from vmnet_send_bh() which runs in a qemu context.
79
- */
80
- qemu_bh_schedule(s->send_bh);
81
- });
82
+ vmnet_vm_state_change_cb(s, 1, RUN_STATE_RUNNING);
83
+
84
+ s->change = qemu_add_vm_change_state_handler(vmnet_vm_state_change_cb, s);
85
86
return 0;
87
}
88
@@ -XXX,XX +XXX,XX @@ void vmnet_cleanup_common(NetClientState *nc)
89
return;
90
}
91
92
+ vmnet_vm_state_change_cb(s, 0, RUN_STATE_SHUTDOWN);
93
+ qemu_del_vm_change_state_handler(s->change);
94
if_stopped_sem = dispatch_semaphore_create(0);
95
vmnet_stop_interface(
96
s->vmnet_if,
97
diff --git a/net/vmnet_int.h b/net/vmnet_int.h
98
index XXXXXXX..XXXXXXX 100644
99
--- a/net/vmnet_int.h
100
+++ b/net/vmnet_int.h
101
@@ -XXX,XX +XXX,XX @@ typedef struct VmnetState {
102
int packets_send_end_pos;
103
104
struct iovec iov_buf[VMNET_PACKETS_LIMIT];
105
+
106
+ VMChangeStateEntry *change;
107
} VmnetState;
108
109
const char *vmnet_status_map_str(vmnet_return_t status);
110
--
111
2.7.4
diff view generated by jsdifflib
New patch
1
From: Qiang Liu <cyruscyliu@gmail.com>
1
2
3
Check fifos before poping data from and pushing data into it.
4
5
Fixes: 98e5d7a2b726 ("hw/net/can: Introduce Xilinx ZynqMP CAN controller")
6
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1425
7
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1427
8
Reported-by: Qiang Liu <cyruscyliu@gmail.com>
9
Signed-off-by: Qiang Liu <cyruscyliu@gmail.com>
10
Signed-off-by: Jason Wang <jasowang@redhat.com>
11
---
12
hw/net/can/xlnx-zynqmp-can.c | 9 ++++++++-
13
1 file changed, 8 insertions(+), 1 deletion(-)
14
15
diff --git a/hw/net/can/xlnx-zynqmp-can.c b/hw/net/can/xlnx-zynqmp-can.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/net/can/xlnx-zynqmp-can.c
18
+++ b/hw/net/can/xlnx-zynqmp-can.c
19
@@ -XXX,XX +XXX,XX @@ static void transfer_fifo(XlnxZynqMPCANState *s, Fifo32 *fifo)
20
}
21
22
while (!fifo32_is_empty(fifo)) {
23
+ if (fifo32_num_used(fifo) < (4 * CAN_FRAME_SIZE)) {
24
+ g_autofree char *path = object_get_canonical_path(OBJECT(s));
25
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: data left in the fifo is not"
26
+ " enough for transfer.\n", path);
27
+ break;
28
+ }
29
for (i = 0; i < CAN_FRAME_SIZE; i++) {
30
data[i] = fifo32_pop(fifo);
31
}
32
@@ -XXX,XX +XXX,XX @@ static void transfer_fifo(XlnxZynqMPCANState *s, Fifo32 *fifo)
33
* acknowledged. The XlnxZynqMPCAN core receives any message
34
* that it transmits.
35
*/
36
- if (fifo32_is_full(&s->rx_fifo)) {
37
+ if (fifo32_is_full(&s->rx_fifo) ||
38
+ (fifo32_num_free(&s->rx_fifo) < (4 * CAN_FRAME_SIZE))) {
39
ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, RXOFLW, 1);
40
} else {
41
for (i = 0; i < CAN_FRAME_SIZE; i++) {
42
--
43
2.7.4
diff view generated by jsdifflib
New patch
1
1
From: Laurent Vivier <lvivier@redhat.com>
2
3
In stream mode, if the server shuts down there is currently
4
no way to reconnect the client to a new server without removing
5
the NIC device and the netdev backend (or to reboot).
6
7
This patch introduces a reconnect option that specifies a delay
8
to try to reconnect with the same parameters.
9
10
Add a new test in qtest to test the reconnect option and the
11
connect/disconnect events.
12
13
Signed-off-by: Laurent Vivier <lvivier@redhat.com>
14
Signed-off-by: Jason Wang <jasowang@redhat.com>
15
---
16
net/stream.c | 53 ++++++++++++++++++++++-
17
qapi/net.json | 7 ++-
18
qemu-options.hx | 6 +--
19
tests/qtest/netdev-socket.c | 101 ++++++++++++++++++++++++++++++++++++++++++++
20
4 files changed, 162 insertions(+), 5 deletions(-)
21
22
diff --git a/net/stream.c b/net/stream.c
23
index XXXXXXX..XXXXXXX 100644
24
--- a/net/stream.c
25
+++ b/net/stream.c
26
@@ -XXX,XX +XXX,XX @@
27
#include "io/channel-socket.h"
28
#include "io/net-listener.h"
29
#include "qapi/qapi-events-net.h"
30
+#include "qapi/qapi-visit-sockets.h"
31
+#include "qapi/clone-visitor.h"
32
33
typedef struct NetStreamState {
34
NetClientState nc;
35
@@ -XXX,XX +XXX,XX @@ typedef struct NetStreamState {
36
guint ioc_write_tag;
37
SocketReadState rs;
38
unsigned int send_index; /* number of bytes sent*/
39
+ uint32_t reconnect;
40
+ guint timer_tag;
41
+ SocketAddress *addr;
42
} NetStreamState;
43
44
static void net_stream_listen(QIONetListener *listener,
45
QIOChannelSocket *cioc,
46
void *opaque);
47
+static void net_stream_arm_reconnect(NetStreamState *s);
48
49
static gboolean net_stream_writable(QIOChannel *ioc,
50
GIOCondition condition,
51
@@ -XXX,XX +XXX,XX @@ static gboolean net_stream_send(QIOChannel *ioc,
52
qemu_set_info_str(&s->nc, "%s", "");
53
54
qapi_event_send_netdev_stream_disconnected(s->nc.name);
55
+ net_stream_arm_reconnect(s);
56
57
return G_SOURCE_REMOVE;
58
}
59
@@ -XXX,XX +XXX,XX @@ static gboolean net_stream_send(QIOChannel *ioc,
60
static void net_stream_cleanup(NetClientState *nc)
61
{
62
NetStreamState *s = DO_UPCAST(NetStreamState, nc, nc);
63
+ if (s->timer_tag) {
64
+ g_source_remove(s->timer_tag);
65
+ s->timer_tag = 0;
66
+ }
67
+ if (s->addr) {
68
+ qapi_free_SocketAddress(s->addr);
69
+ s->addr = NULL;
70
+ }
71
if (s->ioc) {
72
if (QIO_CHANNEL_SOCKET(s->ioc)->fd != -1) {
73
if (s->ioc_read_tag) {
74
@@ -XXX,XX +XXX,XX @@ static void net_stream_client_connected(QIOTask *task, gpointer opaque)
75
error:
76
object_unref(OBJECT(s->ioc));
77
s->ioc = NULL;
78
+ net_stream_arm_reconnect(s);
79
+}
80
+
81
+static gboolean net_stream_reconnect(gpointer data)
82
+{
83
+ NetStreamState *s = data;
84
+ QIOChannelSocket *sioc;
85
+
86
+ s->timer_tag = 0;
87
+
88
+ sioc = qio_channel_socket_new();
89
+ s->ioc = QIO_CHANNEL(sioc);
90
+ qio_channel_socket_connect_async(sioc, s->addr,
91
+ net_stream_client_connected, s,
92
+ NULL, NULL);
93
+ return G_SOURCE_REMOVE;
94
+}
95
+
96
+static void net_stream_arm_reconnect(NetStreamState *s)
97
+{
98
+ if (s->reconnect && s->timer_tag == 0) {
99
+ s->timer_tag = g_timeout_add_seconds(s->reconnect,
100
+ net_stream_reconnect, s);
101
+ }
102
}
103
104
static int net_stream_client_init(NetClientState *peer,
105
const char *model,
106
const char *name,
107
SocketAddress *addr,
108
+ uint32_t reconnect,
109
Error **errp)
110
{
111
NetStreamState *s;
112
@@ -XXX,XX +XXX,XX @@ static int net_stream_client_init(NetClientState *peer,
113
s->ioc = QIO_CHANNEL(sioc);
114
s->nc.link_down = true;
115
116
+ s->reconnect = reconnect;
117
+ if (reconnect) {
118
+ s->addr = QAPI_CLONE(SocketAddress, addr);
119
+ }
120
qio_channel_socket_connect_async(sioc, addr,
121
net_stream_client_connected, s,
122
NULL, NULL);
123
@@ -XXX,XX +XXX,XX @@ int net_init_stream(const Netdev *netdev, const char *name,
124
sock = &netdev->u.stream;
125
126
if (!sock->has_server || !sock->server) {
127
- return net_stream_client_init(peer, "stream", name, sock->addr, errp);
128
+ return net_stream_client_init(peer, "stream", name, sock->addr,
129
+ sock->has_reconnect ? sock->reconnect : 0,
130
+ errp);
131
+ }
132
+ if (sock->has_reconnect) {
133
+ error_setg(errp, "'reconnect' option is incompatible with "
134
+ "socket in server mode");
135
+ return -1;
136
}
137
return net_stream_server_init(peer, "stream", name, sock->addr, errp);
138
}
139
diff --git a/qapi/net.json b/qapi/net.json
140
index XXXXXXX..XXXXXXX 100644
141
--- a/qapi/net.json
142
+++ b/qapi/net.json
143
@@ -XXX,XX +XXX,XX @@
144
# @addr: socket address to listen on (server=true)
145
# or connect to (server=false)
146
# @server: create server socket (default: false)
147
+# @reconnect: For a client socket, if a socket is disconnected,
148
+# then attempt a reconnect after the given number of seconds.
149
+# Setting this to zero disables this function. (default: 0)
150
+# (since 8.0)
151
#
152
# Only SocketAddress types 'unix', 'inet' and 'fd' are supported.
153
#
154
@@ -XXX,XX +XXX,XX @@
155
{ 'struct': 'NetdevStreamOptions',
156
'data': {
157
'addr': 'SocketAddress',
158
- '*server': 'bool' } }
159
+ '*server': 'bool',
160
+ '*reconnect': 'uint32' } }
161
162
##
163
# @NetdevDgramOptions:
164
diff --git a/qemu-options.hx b/qemu-options.hx
165
index XXXXXXX..XXXXXXX 100644
166
--- a/qemu-options.hx
167
+++ b/qemu-options.hx
168
@@ -XXX,XX +XXX,XX @@ DEF("netdev", HAS_ARG, QEMU_OPTION_netdev,
169
"-netdev socket,id=str[,fd=h][,udp=host:port][,localaddr=host:port]\n"
170
" configure a network backend to connect to another network\n"
171
" using an UDP tunnel\n"
172
- "-netdev stream,id=str[,server=on|off],addr.type=inet,addr.host=host,addr.port=port[,to=maxport][,numeric=on|off][,keep-alive=on|off][,mptcp=on|off][,addr.ipv4=on|off][,addr.ipv6=on|off]\n"
173
- "-netdev stream,id=str[,server=on|off],addr.type=unix,addr.path=path[,abstract=on|off][,tight=on|off]\n"
174
- "-netdev stream,id=str[,server=on|off],addr.type=fd,addr.str=file-descriptor\n"
175
+ "-netdev stream,id=str[,server=on|off],addr.type=inet,addr.host=host,addr.port=port[,to=maxport][,numeric=on|off][,keep-alive=on|off][,mptcp=on|off][,addr.ipv4=on|off][,addr.ipv6=on|off][,reconnect=seconds]\n"
176
+ "-netdev stream,id=str[,server=on|off],addr.type=unix,addr.path=path[,abstract=on|off][,tight=on|off][,reconnect=seconds]\n"
177
+ "-netdev stream,id=str[,server=on|off],addr.type=fd,addr.str=file-descriptor[,reconnect=seconds]\n"
178
" configure a network backend to connect to another network\n"
179
" using a socket connection in stream mode.\n"
180
"-netdev dgram,id=str,remote.type=inet,remote.host=maddr,remote.port=port[,local.type=inet,local.host=addr]\n"
181
diff --git a/tests/qtest/netdev-socket.c b/tests/qtest/netdev-socket.c
182
index XXXXXXX..XXXXXXX 100644
183
--- a/tests/qtest/netdev-socket.c
184
+++ b/tests/qtest/netdev-socket.c
185
@@ -XXX,XX +XXX,XX @@
186
#include <glib/gstdio.h>
187
#include "../unit/socket-helpers.h"
188
#include "libqtest.h"
189
+#include "qapi/qmp/qstring.h"
190
+#include "qemu/sockets.h"
191
+#include "qapi/qobject-input-visitor.h"
192
+#include "qapi/qapi-visit-sockets.h"
193
194
#define CONNECTION_TIMEOUT 60
195
196
@@ -XXX,XX +XXX,XX @@ static void test_stream_inet_ipv4(void)
197
qtest_quit(qts0);
198
}
199
200
+static void wait_stream_connected(QTestState *qts, const char *id,
201
+ SocketAddress **addr)
202
+{
203
+ QDict *resp, *data;
204
+ QString *qstr;
205
+ QObject *obj;
206
+ Visitor *v = NULL;
207
+
208
+ resp = qtest_qmp_eventwait_ref(qts, "NETDEV_STREAM_CONNECTED");
209
+ g_assert_nonnull(resp);
210
+ data = qdict_get_qdict(resp, "data");
211
+ g_assert_nonnull(data);
212
+
213
+ qstr = qobject_to(QString, qdict_get(data, "netdev-id"));
214
+ g_assert_nonnull(data);
215
+
216
+ g_assert(!strcmp(qstring_get_str(qstr), id));
217
+
218
+ obj = qdict_get(data, "addr");
219
+
220
+ v = qobject_input_visitor_new(obj);
221
+ visit_type_SocketAddress(v, NULL, addr, NULL);
222
+ visit_free(v);
223
+ qobject_unref(resp);
224
+}
225
+
226
+static void wait_stream_disconnected(QTestState *qts, const char *id)
227
+{
228
+ QDict *resp, *data;
229
+ QString *qstr;
230
+
231
+ resp = qtest_qmp_eventwait_ref(qts, "NETDEV_STREAM_DISCONNECTED");
232
+ g_assert_nonnull(resp);
233
+ data = qdict_get_qdict(resp, "data");
234
+ g_assert_nonnull(data);
235
+
236
+ qstr = qobject_to(QString, qdict_get(data, "netdev-id"));
237
+ g_assert_nonnull(data);
238
+
239
+ g_assert(!strcmp(qstring_get_str(qstr), id));
240
+ qobject_unref(resp);
241
+}
242
+
243
+static void test_stream_inet_reconnect(void)
244
+{
245
+ QTestState *qts0, *qts1;
246
+ int port;
247
+ SocketAddress *addr;
248
+
249
+ port = inet_get_free_port(false);
250
+ qts0 = qtest_initf("-nodefaults -M none "
251
+ "-netdev stream,id=st0,server=true,addr.type=inet,"
252
+ "addr.ipv4=on,addr.ipv6=off,"
253
+ "addr.host=127.0.0.1,addr.port=%d", port);
254
+
255
+ EXPECT_STATE(qts0, "st0: index=0,type=stream,\r\n", 0);
256
+
257
+ qts1 = qtest_initf("-nodefaults -M none "
258
+ "-netdev stream,server=false,id=st0,addr.type=inet,"
259
+ "addr.ipv4=on,addr.ipv6=off,reconnect=1,"
260
+ "addr.host=127.0.0.1,addr.port=%d", port);
261
+
262
+ wait_stream_connected(qts0, "st0", &addr);
263
+ g_assert_cmpint(addr->type, ==, SOCKET_ADDRESS_TYPE_INET);
264
+ g_assert_cmpstr(addr->u.inet.host, ==, "127.0.0.1");
265
+ qapi_free_SocketAddress(addr);
266
+
267
+ /* kill server */
268
+ qtest_quit(qts0);
269
+
270
+ /* check client has been disconnected */
271
+ wait_stream_disconnected(qts1, "st0");
272
+
273
+ /* restart server */
274
+ qts0 = qtest_initf("-nodefaults -M none "
275
+ "-netdev stream,id=st0,server=true,addr.type=inet,"
276
+ "addr.ipv4=on,addr.ipv6=off,"
277
+ "addr.host=127.0.0.1,addr.port=%d", port);
278
+
279
+ /* wait connection events*/
280
+ wait_stream_connected(qts0, "st0", &addr);
281
+ g_assert_cmpint(addr->type, ==, SOCKET_ADDRESS_TYPE_INET);
282
+ g_assert_cmpstr(addr->u.inet.host, ==, "127.0.0.1");
283
+ qapi_free_SocketAddress(addr);
284
+
285
+ wait_stream_connected(qts1, "st0", &addr);
286
+ g_assert_cmpint(addr->type, ==, SOCKET_ADDRESS_TYPE_INET);
287
+ g_assert_cmpstr(addr->u.inet.host, ==, "127.0.0.1");
288
+ g_assert_cmpint(atoi(addr->u.inet.port), ==, port);
289
+ qapi_free_SocketAddress(addr);
290
+
291
+ qtest_quit(qts1);
292
+ qtest_quit(qts0);
293
+}
294
+
295
static void test_stream_inet_ipv6(void)
296
{
297
QTestState *qts0, *qts1;
298
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
299
#ifndef _WIN32
300
qtest_add_func("/netdev/dgram/mcast", test_dgram_mcast);
301
#endif
302
+ qtest_add_func("/netdev/stream/inet/reconnect",
303
+ test_stream_inet_reconnect);
304
}
305
if (has_ipv6) {
306
qtest_add_func("/netdev/stream/inet/ipv6", test_stream_inet_ipv6);
307
--
308
2.7.4
diff view generated by jsdifflib
1
From: Prasad J Pandit <pjp@fedoraproject.org>
1
From: Eugenio Pérez <eperezma@redhat.com>
2
2
3
While receiving packets via e1000e_write_packet_to_guest() routine,
3
VHOST_BACKEND_F_IOTLB_ASID is the feature bit, not the bitmask. Since
4
'desc_offset' is advanced only when RX descriptor is processed. And
4
the device under test also provided VHOST_BACKEND_F_IOTLB_MSG_V2 and
5
RX descriptor is not processed if it has NULL buffer address.
5
VHOST_BACKEND_F_IOTLB_BATCH, this went unnoticed.
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
6
9
Reported-by: Cheol-woo Myung <330cjfdn@gmail.com>
7
Fixes: c1a1008685 ("vdpa: always start CVQ in SVQ mode if possible")
10
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
8
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
9
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
10
Acked-by: Jason Wang <jasowang@redhat.com>
11
Signed-off-by: Jason Wang <jasowang@redhat.com>
11
Signed-off-by: Jason Wang <jasowang@redhat.com>
12
---
12
---
13
hw/net/e1000e_core.c | 8 ++++----
13
net/vhost-vdpa.c | 2 +-
14
1 file changed, 4 insertions(+), 4 deletions(-)
14
1 file changed, 1 insertion(+), 1 deletion(-)
15
15
16
diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c
16
diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
17
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/net/e1000e_core.c
18
--- a/net/vhost-vdpa.c
19
+++ b/hw/net/e1000e_core.c
19
+++ b/net/vhost-vdpa.c
20
@@ -XXX,XX +XXX,XX @@ e1000e_write_packet_to_guest(E1000ECore *core, struct NetRxPkt *pkt,
20
@@ -XXX,XX +XXX,XX @@ static int vhost_vdpa_net_cvq_start(NetClientState *nc)
21
(const char *) &fcs_pad, e1000x_fcs_len(core->mac));
21
g_strerror(errno), errno);
22
}
22
return -1;
23
}
23
}
24
- desc_offset += desc_size;
24
- if (!(backend_features & VHOST_BACKEND_F_IOTLB_ASID) ||
25
- if (desc_offset >= total_size) {
25
+ if (!(backend_features & BIT_ULL(VHOST_BACKEND_F_IOTLB_ASID)) ||
26
- is_last = true;
26
!vhost_vdpa_net_valid_svq_features(v->dev->features, NULL)) {
27
- }
27
return 0;
28
} else { /* as per intel docs; skip descriptors with null buf addr */
28
}
29
trace_e1000e_rx_null_descriptor();
30
}
31
+ desc_offset += desc_size;
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
--
29
--
39
2.7.4
30
2.7.4
40
31
41
32
diff view generated by jsdifflib