1
The following changes since commit 6632f6ff96f0537fc34cdc00c760656fc62e23c5:
1
The following changes since commit f670b3eec7f5d1ed8c4573ef244e7b8c6b32001b:
2
2
3
Merge remote-tracking branch 'remotes/famz/tags/block-and-testing-pull-request' into staging (2017-07-17 11:46:36 +0100)
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 189ae6bb5ce1f5a322f8691d00fe942ba43dd601:
9
for you to fetch changes up to e4b953a26da11d214f91516cb9b0542eab5afaa0:
10
10
11
virtio-net: fix offload ctrl endian (2017-07-17 20:13:56 +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
- fix virtio-net ctrl offload endian
15
----------------------------------------------------------------
16
- vnet header support for variou COLO netfilters and compare thread
16
Christian Svensson (1):
17
net: Increase L2TPv3 buffer to fit jumboframes
17
18
18
----------------------------------------------------------------
19
Eugenio Pérez (1):
19
Jason Wang (1):
20
vdpa: fix VHOST_BACKEND_F_IOTLB_ASID flag check
20
virtio-net: fix offload ctrl endian
21
21
22
Michal Privoznik (1):
22
Fiona Ebner (1):
23
virtion-net: Prefer is_power_of_2()
23
hw/net/vmxnet3: allow VMXNET3_MAX_MTU itself as a value
24
24
25
Zhang Chen (12):
25
Joelle van Dyne (1):
26
net: Add vnet_hdr_len arguments in NetClientState
26
vmnet: stop recieving events when VM is stopped
27
net/net.c: Add vnet_hdr support in SocketReadState
28
net/filter-mirror.c: Introduce parameter for filter_send()
29
net/filter-mirror.c: Make filter mirror support vnet support.
30
net/filter-mirror.c: Add new option to enable vnet support for filter-redirector
31
net/colo.c: Make vnet_hdr_len as packet property
32
net/colo-compare.c: Introduce parameter for compare_chr_send()
33
net/colo-compare.c: Make colo-compare support vnet_hdr_len
34
net/colo.c: Add vnet packet parse feature in colo-proxy
35
net/colo-compare.c: Add vnet packet's tcp/udp/icmp compare
36
net/filter-rewriter.c: Make filter-rewriter support vnet_hdr_len
37
docs/colo-proxy.txt: Update colo-proxy usage of net driver with vnet_header
38
27
39
docs/colo-proxy.txt | 26 ++++++++++++++++
28
Laurent Vivier (1):
40
hw/net/virtio-net.c | 4 ++-
29
net: stream: add a new option to automatically reconnect
41
include/net/net.h | 10 ++++--
30
42
net/colo-compare.c | 84 ++++++++++++++++++++++++++++++++++++++++++---------
31
Qiang Liu (2):
43
net/colo.c | 9 +++---
32
hw/net/lan9118: log [read|write]b when mode_16bit is enabled rather than abort
44
net/colo.h | 4 ++-
33
hw/net/can/xlnx-zynqmp-can: fix assertion failures in transfer_fifo()
45
net/filter-mirror.c | 75 +++++++++++++++++++++++++++++++++++++++++----
34
46
net/filter-rewriter.c | 37 ++++++++++++++++++++++-
35
Thomas Huth (3):
47
net/net.c | 37 ++++++++++++++++++++---
36
net: Move the code to collect available NIC models to a separate function
48
net/socket.c | 8 ++---
37
net: Restore printing of the help text with "-nic help"
49
qemu-options.hx | 19 ++++++------
38
net: Replace "Supported NIC models" with "Available NIC models"
50
11 files changed, 265 insertions(+), 48 deletions(-)
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(-)
51
55
52
56
diff view generated by jsdifflib
1
From: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
1
From: Thomas Huth <thuth@redhat.com>
2
2
3
We add a flag to decide whether net_fill_rstate() need read
3
The code that collects the available NIC models is not really specific
4
the vnet_hdr_len or not.
4
to PCI anymore and will be required in the next patch, too, so let's
5
move this into a new separate function in net.c instead.
5
6
6
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
7
Signed-off-by: Thomas Huth <thuth@redhat.com>
7
Suggested-by: Jason Wang <jasowang@redhat.com>
8
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
Signed-off-by: Jason Wang <jasowang@redhat.com>
9
---
9
---
10
include/net/net.h | 9 +++++++--
10
hw/pci/pci.c | 29 +----------------------------
11
net/colo-compare.c | 4 ++--
11
include/net/net.h | 14 ++++++++++++++
12
net/filter-mirror.c | 2 +-
12
net/net.c | 34 ++++++++++++++++++++++++++++++++++
13
net/net.c | 36 ++++++++++++++++++++++++++++++++----
13
3 files changed, 49 insertions(+), 28 deletions(-)
14
net/socket.c | 8 ++++----
15
5 files changed, 46 insertions(+), 13 deletions(-)
16
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);
17
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
18
index XXXXXXX..XXXXXXX 100644
63
index XXXXXXX..XXXXXXX 100644
19
--- a/include/net/net.h
64
--- a/include/net/net.h
20
+++ b/include/net/net.h
65
+++ b/include/net/net.h
21
@@ -XXX,XX +XXX,XX @@ typedef struct NICState {
66
@@ -XXX,XX +XXX,XX @@ void net_socket_rs_init(SocketReadState *rs,
22
} NICState;
67
bool vnet_hdr);
23
68
NetClientState *qemu_get_peer(NetClientState *nc, int queue_index);
24
struct SocketReadState {
69
25
- int state; /* 0 = getting length, 1 = getting data */
70
+/**
26
+ /* 0 = getting length, 1 = getting vnet header length, 2 = getting data */
71
+ * qemu_get_nic_models:
27
+ int state;
72
+ * @device_type: Defines which devices should be taken into consideration
28
+ /* This flag decide whether to read the vnet_hdr_len field */
73
+ * (e.g. TYPE_DEVICE for all devices, or TYPE_PCI_DEVICE for PCI)
29
+ bool vnet_hdr;
74
+ *
30
uint32_t index;
75
+ * Get an array of pointers to names of NIC devices that are available in
31
uint32_t packet_len;
76
+ * the QEMU binary. The array is terminated with a NULL pointer entry.
32
+ uint32_t vnet_hdr_len;
77
+ * The caller is responsible for freeing the memory when it is not required
33
uint8_t buf[NET_BUFSIZE];
78
+ * anymore, e.g. with g_ptr_array_free(..., true).
34
SocketReadStateFinalize *finalize;
79
+ *
35
};
80
+ * Returns: Pointer to the array that contains the pointers to the names.
36
@@ -XXX,XX +XXX,XX @@ ssize_t qemu_deliver_packet_iov(NetClientState *sender,
81
+ */
37
void print_net_client(Monitor *mon, NetClientState *nc);
82
+GPtrArray *qemu_get_nic_models(const char *device_type);
38
void hmp_info_network(Monitor *mon, const QDict *qdict);
83
+
39
void net_socket_rs_init(SocketReadState *rs,
40
- SocketReadStateFinalize *finalize);
41
+ SocketReadStateFinalize *finalize,
42
+ bool vnet_hdr);
43
44
/* NIC info */
84
/* NIC info */
45
85
46
diff --git a/net/colo-compare.c b/net/colo-compare.c
86
#define MAX_NICS 8
47
index XXXXXXX..XXXXXXX 100644
48
--- a/net/colo-compare.c
49
+++ b/net/colo-compare.c
50
@@ -XXX,XX +XXX,XX @@ static void colo_compare_complete(UserCreatable *uc, Error **errp)
51
return;
52
}
53
54
- net_socket_rs_init(&s->pri_rs, compare_pri_rs_finalize);
55
- net_socket_rs_init(&s->sec_rs, compare_sec_rs_finalize);
56
+ net_socket_rs_init(&s->pri_rs, compare_pri_rs_finalize, false);
57
+ net_socket_rs_init(&s->sec_rs, compare_sec_rs_finalize, false);
58
59
g_queue_init(&s->conn_list);
60
61
diff --git a/net/filter-mirror.c b/net/filter-mirror.c
62
index XXXXXXX..XXXXXXX 100644
63
--- a/net/filter-mirror.c
64
+++ b/net/filter-mirror.c
65
@@ -XXX,XX +XXX,XX @@ static void filter_redirector_setup(NetFilterState *nf, Error **errp)
66
}
67
}
68
69
- net_socket_rs_init(&s->rs, redirector_rs_finalize);
70
+ net_socket_rs_init(&s->rs, redirector_rs_finalize, false);
71
72
if (s->indev) {
73
chr = qemu_chr_find(s->indev);
74
diff --git a/net/net.c b/net/net.c
87
diff --git a/net/net.c b/net/net.c
75
index XXXXXXX..XXXXXXX 100644
88
index XXXXXXX..XXXXXXX 100644
76
--- a/net/net.c
89
--- a/net/net.c
77
+++ b/net/net.c
90
+++ b/net/net.c
78
@@ -XXX,XX +XXX,XX @@ QemuOptsList qemu_net_opts = {
91
@@ -XXX,XX +XXX,XX @@ static int nic_get_free_idx(void)
79
};
92
return -1;
80
93
}
81
void net_socket_rs_init(SocketReadState *rs,
94
82
- SocketReadStateFinalize *finalize)
95
+GPtrArray *qemu_get_nic_models(const char *device_type)
83
+ SocketReadStateFinalize *finalize,
96
+{
84
+ bool vnet_hdr)
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)
85
{
130
{
86
rs->state = 0;
131
int i;
87
+ rs->vnet_hdr = vnet_hdr;
88
rs->index = 0;
89
rs->packet_len = 0;
90
+ rs->vnet_hdr_len = 0;
91
memset(rs->buf, 0, sizeof(rs->buf));
92
rs->finalize = finalize;
93
}
94
@@ -XXX,XX +XXX,XX @@ int net_fill_rstate(SocketReadState *rs, const uint8_t *buf, int size)
95
unsigned int l;
96
97
while (size > 0) {
98
- /* reassemble a packet from the network */
99
- switch (rs->state) { /* 0 = getting length, 1 = getting data */
100
+ /* Reassemble a packet from the network.
101
+ * 0 = getting length.
102
+ * 1 = getting vnet header length.
103
+ * 2 = getting data.
104
+ */
105
+ switch (rs->state) {
106
case 0:
107
l = 4 - rs->index;
108
if (l > size) {
109
@@ -XXX,XX +XXX,XX @@ int net_fill_rstate(SocketReadState *rs, const uint8_t *buf, int size)
110
/* got length */
111
rs->packet_len = ntohl(*(uint32_t *)rs->buf);
112
rs->index = 0;
113
- rs->state = 1;
114
+ if (rs->vnet_hdr) {
115
+ rs->state = 1;
116
+ } else {
117
+ rs->state = 2;
118
+ rs->vnet_hdr_len = 0;
119
+ }
120
}
121
break;
122
case 1:
123
+ l = 4 - rs->index;
124
+ if (l > size) {
125
+ l = size;
126
+ }
127
+ memcpy(rs->buf + rs->index, buf, l);
128
+ buf += l;
129
+ size -= l;
130
+ rs->index += l;
131
+ if (rs->index == 4) {
132
+ /* got vnet header length */
133
+ rs->vnet_hdr_len = ntohl(*(uint32_t *)rs->buf);
134
+ rs->index = 0;
135
+ rs->state = 2;
136
+ }
137
+ break;
138
+ case 2:
139
l = rs->packet_len - rs->index;
140
if (l > size) {
141
l = size;
142
diff --git a/net/socket.c b/net/socket.c
143
index XXXXXXX..XXXXXXX 100644
144
--- a/net/socket.c
145
+++ b/net/socket.c
146
@@ -XXX,XX +XXX,XX @@ static void net_socket_send(void *opaque)
147
closesocket(s->fd);
148
149
s->fd = -1;
150
- net_socket_rs_init(&s->rs, net_socket_rs_finalize);
151
+ net_socket_rs_init(&s->rs, net_socket_rs_finalize, false);
152
s->nc.link_down = true;
153
memset(s->nc.info_str, 0, sizeof(s->nc.info_str));
154
155
@@ -XXX,XX +XXX,XX @@ static NetSocketState *net_socket_fd_init_dgram(NetClientState *peer,
156
s->fd = fd;
157
s->listen_fd = -1;
158
s->send_fn = net_socket_send_dgram;
159
- net_socket_rs_init(&s->rs, net_socket_rs_finalize);
160
+ net_socket_rs_init(&s->rs, net_socket_rs_finalize, false);
161
net_socket_read_poll(s, true);
162
163
/* mcast: save bound address as dst */
164
@@ -XXX,XX +XXX,XX @@ static NetSocketState *net_socket_fd_init_stream(NetClientState *peer,
165
166
s->fd = fd;
167
s->listen_fd = -1;
168
- net_socket_rs_init(&s->rs, net_socket_rs_finalize);
169
+ net_socket_rs_init(&s->rs, net_socket_rs_finalize, false);
170
171
/* Disable Nagle algorithm on TCP sockets to reduce latency */
172
socket_set_nodelay(fd);
173
@@ -XXX,XX +XXX,XX @@ static int net_socket_listen_init(NetClientState *peer,
174
s->fd = -1;
175
s->listen_fd = fd;
176
s->nc.link_down = true;
177
- net_socket_rs_init(&s->rs, net_socket_rs_finalize);
178
+ net_socket_rs_init(&s->rs, net_socket_rs_finalize, false);
179
180
qemu_set_fd_handler(s->listen_fd, net_socket_accept, NULL, s);
181
return 0;
182
--
132
--
183
2.7.4
133
2.7.4
184
185
diff view generated by jsdifflib
1
From: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
1
From: Thomas Huth <thuth@redhat.com>
2
2
3
We can use this property flush and send packet with vnet_hdr_len.
3
Running QEMU with "-nic help" used to work in QEMU 5.2 and earlier versions
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.
4
8
5
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
9
Fixes: ad6f932fe8 ("net: do not exit on "netdev_add help" monitor command")
10
Signed-off-by: Thomas Huth <thuth@redhat.com>
6
Signed-off-by: Jason Wang <jasowang@redhat.com>
11
Signed-off-by: Jason Wang <jasowang@redhat.com>
7
---
12
---
8
net/colo-compare.c | 8 ++++++--
13
net/net.c | 14 ++++++++++++--
9
net/colo.c | 3 ++-
14
1 file changed, 12 insertions(+), 2 deletions(-)
10
net/colo.h | 4 +++-
11
net/filter-rewriter.c | 2 +-
12
4 files changed, 12 insertions(+), 5 deletions(-)
13
15
14
diff --git a/net/colo-compare.c b/net/colo-compare.c
16
diff --git a/net/net.c b/net/net.c
15
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
16
--- a/net/colo-compare.c
18
--- a/net/net.c
17
+++ b/net/colo-compare.c
19
+++ b/net/net.c
18
@@ -XXX,XX +XXX,XX @@ static int packet_enqueue(CompareState *s, int mode)
20
@@ -XXX,XX +XXX,XX @@ static int net_param_nic(void *dummy, QemuOpts *opts, Error **errp)
19
Connection *conn;
21
const char *type;
20
22
21
if (mode == PRIMARY_IN) {
23
type = qemu_opt_get(opts, "type");
22
- pkt = packet_new(s->pri_rs.buf, s->pri_rs.packet_len);
24
- if (type && g_str_equal(type, "none")) {
23
+ pkt = packet_new(s->pri_rs.buf,
25
- return 0; /* Nothing to do, default_net is cleared in vl.c */
24
+ s->pri_rs.packet_len,
26
+ if (type) {
25
+ s->pri_rs.vnet_hdr_len);
27
+ if (g_str_equal(type, "none")) {
26
} else {
28
+ return 0; /* Nothing to do, default_net is cleared in vl.c */
27
- pkt = packet_new(s->sec_rs.buf, s->sec_rs.packet_len);
29
+ }
28
+ pkt = packet_new(s->sec_rs.buf,
30
+ if (is_help_option(type)) {
29
+ s->sec_rs.packet_len,
31
+ GPtrArray *nic_models = qemu_get_nic_models(TYPE_DEVICE);
30
+ s->sec_rs.vnet_hdr_len);
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
+ }
31
}
38
}
32
39
33
if (parse_packet_early(pkt)) {
40
idx = nic_get_free_idx();
34
diff --git a/net/colo.c b/net/colo.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/net/colo.c
37
+++ b/net/colo.c
38
@@ -XXX,XX +XXX,XX @@ void connection_destroy(void *opaque)
39
g_slice_free(Connection, conn);
40
}
41
42
-Packet *packet_new(const void *data, int size)
43
+Packet *packet_new(const void *data, int size, int vnet_hdr_len)
44
{
45
Packet *pkt = g_slice_new(Packet);
46
47
pkt->data = g_memdup(data, size);
48
pkt->size = size;
49
pkt->creation_ms = qemu_clock_get_ms(QEMU_CLOCK_HOST);
50
+ pkt->vnet_hdr_len = vnet_hdr_len;
51
52
return pkt;
53
}
54
diff --git a/net/colo.h b/net/colo.h
55
index XXXXXXX..XXXXXXX 100644
56
--- a/net/colo.h
57
+++ b/net/colo.h
58
@@ -XXX,XX +XXX,XX @@ typedef struct Packet {
59
int size;
60
/* Time of packet creation, in wall clock ms */
61
int64_t creation_ms;
62
+ /* Get vnet_hdr_len from filter */
63
+ uint32_t vnet_hdr_len;
64
} Packet;
65
66
typedef struct ConnectionKey {
67
@@ -XXX,XX +XXX,XX @@ Connection *connection_get(GHashTable *connection_track_table,
68
ConnectionKey *key,
69
GQueue *conn_list);
70
void connection_hashtable_reset(GHashTable *connection_track_table);
71
-Packet *packet_new(const void *data, int size);
72
+Packet *packet_new(const void *data, int size, int vnet_hdr_len);
73
void packet_destroy(void *opaque, void *user_data);
74
75
#endif /* QEMU_COLO_PROXY_H */
76
diff --git a/net/filter-rewriter.c b/net/filter-rewriter.c
77
index XXXXXXX..XXXXXXX 100644
78
--- a/net/filter-rewriter.c
79
+++ b/net/filter-rewriter.c
80
@@ -XXX,XX +XXX,XX @@ static ssize_t colo_rewriter_receive_iov(NetFilterState *nf,
81
char *buf = g_malloc0(size);
82
83
iov_to_buf(iov, iovcnt, 0, buf, size);
84
- pkt = packet_new(buf, size);
85
+ pkt = packet_new(buf, size, 0);
86
g_free(buf);
87
88
/*
89
--
41
--
90
2.7.4
42
2.7.4
91
92
diff view generated by jsdifflib
1
From: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
1
From: Thomas Huth <thuth@redhat.com>
2
2
3
Add vnet_hdr_len arguments in NetClientState
3
Just because a NIC model is compiled into the QEMU binary does not
4
that make other module get real vnet_hdr_len easily.
4
necessary mean that it can be used with each and every machine.
5
So let's rather talk about "available" models instead of "supported"
6
models, just to avoid confusion.
5
7
6
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
8
Reviewed-by: Claudio Fontana <cfontana@suse.de>
9
Signed-off-by: Thomas Huth <thuth@redhat.com>
7
Signed-off-by: Jason Wang <jasowang@redhat.com>
10
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
---
11
---
9
include/net/net.h | 1 +
12
net/net.c | 2 +-
10
net/net.c | 1 +
13
1 file changed, 1 insertion(+), 1 deletion(-)
11
2 files changed, 2 insertions(+)
12
14
13
diff --git a/include/net/net.h b/include/net/net.h
14
index XXXXXXX..XXXXXXX 100644
15
--- a/include/net/net.h
16
+++ b/include/net/net.h
17
@@ -XXX,XX +XXX,XX @@ struct NetClientState {
18
unsigned int queue_index;
19
unsigned rxfilter_notify_enabled:1;
20
int vring_enable;
21
+ int vnet_hdr_len;
22
QTAILQ_HEAD(NetFilterHead, NetFilterState) filters;
23
};
24
25
diff --git a/net/net.c b/net/net.c
15
diff --git a/net/net.c b/net/net.c
26
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
27
--- a/net/net.c
17
--- a/net/net.c
28
+++ b/net/net.c
18
+++ b/net/net.c
29
@@ -XXX,XX +XXX,XX @@ void qemu_set_vnet_hdr_len(NetClientState *nc, int len)
19
@@ -XXX,XX +XXX,XX @@ int qemu_show_nic_models(const char *arg, const char *const *models)
30
return;
20
return 0;
31
}
21
}
32
22
33
+ nc->vnet_hdr_len = len;
23
- printf("Supported NIC models:\n");
34
nc->info->set_vnet_hdr_len(nc, len);
24
+ printf("Available NIC models:\n");
35
}
25
for (i = 0 ; models[i]; i++) {
36
26
printf("%s\n", models[i]);
27
}
37
--
28
--
38
2.7.4
29
2.7.4
39
40
diff view generated by jsdifflib
Deleted patch
1
From: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
2
1
3
This patch change the filter_send() parameter from CharBackend to MirrorState,
4
we can get more information like vnet_hdr(We use it to support packet with vnet_header).
5
6
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
7
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
---
9
net/filter-mirror.c | 10 +++++-----
10
1 file changed, 5 insertions(+), 5 deletions(-)
11
12
diff --git a/net/filter-mirror.c b/net/filter-mirror.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/net/filter-mirror.c
15
+++ b/net/filter-mirror.c
16
@@ -XXX,XX +XXX,XX @@ typedef struct MirrorState {
17
SocketReadState rs;
18
} MirrorState;
19
20
-static int filter_send(CharBackend *chr_out,
21
+static int filter_send(MirrorState *s,
22
const struct iovec *iov,
23
int iovcnt)
24
{
25
@@ -XXX,XX +XXX,XX @@ static int filter_send(CharBackend *chr_out,
26
}
27
28
len = htonl(size);
29
- ret = qemu_chr_fe_write_all(chr_out, (uint8_t *)&len, sizeof(len));
30
+ ret = qemu_chr_fe_write_all(&s->chr_out, (uint8_t *)&len, sizeof(len));
31
if (ret != sizeof(len)) {
32
goto err;
33
}
34
35
buf = g_malloc(size);
36
iov_to_buf(iov, iovcnt, 0, buf, size);
37
- ret = qemu_chr_fe_write_all(chr_out, (uint8_t *)buf, size);
38
+ ret = qemu_chr_fe_write_all(&s->chr_out, (uint8_t *)buf, size);
39
g_free(buf);
40
if (ret != size) {
41
goto err;
42
@@ -XXX,XX +XXX,XX @@ static ssize_t filter_mirror_receive_iov(NetFilterState *nf,
43
MirrorState *s = FILTER_MIRROR(nf);
44
int ret;
45
46
- ret = filter_send(&s->chr_out, iov, iovcnt);
47
+ ret = filter_send(s, iov, iovcnt);
48
if (ret) {
49
error_report("filter mirror send failed(%s)", strerror(-ret));
50
}
51
@@ -XXX,XX +XXX,XX @@ static ssize_t filter_redirector_receive_iov(NetFilterState *nf,
52
int ret;
53
54
if (qemu_chr_fe_backend_connected(&s->chr_out)) {
55
- ret = filter_send(&s->chr_out, iov, iovcnt);
56
+ ret = filter_send(s, iov, iovcnt);
57
if (ret) {
58
error_report("filter redirector send failed(%s)", strerror(-ret));
59
}
60
--
61
2.7.4
62
63
diff view generated by jsdifflib
Deleted patch
1
From: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
2
1
3
We add the vnet_hdr_support option for filter-mirror, default is disabled.
4
If you use virtio-net-pci or other driver needs vnet_hdr, please enable it.
5
You can use it for example:
6
-object filter-mirror,id=m0,netdev=hn0,queue=tx,outdev=mirror0,vnet_hdr_support
7
8
If it has vnet_hdr_support flag, we will change the sending packet format from
9
struct {int size; const uint8_t buf[];} to {int size; int vnet_hdr_len; const uint8_t buf[];}.
10
make other module(like colo-compare) know how to parse net packet correctly.
11
12
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
13
Signed-off-by: Jason Wang <jasowang@redhat.com>
14
---
15
net/filter-mirror.c | 42 +++++++++++++++++++++++++++++++++++++++++-
16
qemu-options.hx | 5 ++---
17
2 files changed, 43 insertions(+), 4 deletions(-)
18
19
diff --git a/net/filter-mirror.c b/net/filter-mirror.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/net/filter-mirror.c
22
+++ b/net/filter-mirror.c
23
@@ -XXX,XX +XXX,XX @@ typedef struct MirrorState {
24
CharBackend chr_in;
25
CharBackend chr_out;
26
SocketReadState rs;
27
+ bool vnet_hdr;
28
} MirrorState;
29
30
static int filter_send(MirrorState *s,
31
const struct iovec *iov,
32
int iovcnt)
33
{
34
+ NetFilterState *nf = NETFILTER(s);
35
int ret = 0;
36
ssize_t size = 0;
37
uint32_t len = 0;
38
@@ -XXX,XX +XXX,XX @@ static int filter_send(MirrorState *s,
39
goto err;
40
}
41
42
+ if (s->vnet_hdr) {
43
+ /*
44
+ * If vnet_hdr = on, we send vnet header len to make other
45
+ * module(like colo-compare) know how to parse net
46
+ * packet correctly.
47
+ */
48
+ ssize_t vnet_hdr_len;
49
+
50
+ vnet_hdr_len = nf->netdev->vnet_hdr_len;
51
+
52
+ len = htonl(vnet_hdr_len);
53
+ ret = qemu_chr_fe_write_all(&s->chr_out, (uint8_t *)&len, sizeof(len));
54
+ if (ret != sizeof(len)) {
55
+ goto err;
56
+ }
57
+ }
58
+
59
buf = g_malloc(size);
60
iov_to_buf(iov, iovcnt, 0, buf, size);
61
ret = qemu_chr_fe_write_all(&s->chr_out, (uint8_t *)buf, size);
62
@@ -XXX,XX +XXX,XX @@ static void filter_redirector_setup(NetFilterState *nf, Error **errp)
63
}
64
}
65
66
- net_socket_rs_init(&s->rs, redirector_rs_finalize, false);
67
+ net_socket_rs_init(&s->rs, redirector_rs_finalize, s->vnet_hdr);
68
69
if (s->indev) {
70
chr = qemu_chr_find(s->indev);
71
@@ -XXX,XX +XXX,XX @@ static void filter_mirror_set_outdev(Object *obj,
72
}
73
}
74
75
+static bool filter_mirror_get_vnet_hdr(Object *obj, Error **errp)
76
+{
77
+ MirrorState *s = FILTER_MIRROR(obj);
78
+
79
+ return s->vnet_hdr;
80
+}
81
+
82
+static void filter_mirror_set_vnet_hdr(Object *obj, bool value, Error **errp)
83
+{
84
+ MirrorState *s = FILTER_MIRROR(obj);
85
+
86
+ s->vnet_hdr = value;
87
+}
88
+
89
static char *filter_redirector_get_outdev(Object *obj, Error **errp)
90
{
91
MirrorState *s = FILTER_REDIRECTOR(obj);
92
@@ -XXX,XX +XXX,XX @@ static void filter_redirector_set_outdev(Object *obj,
93
94
static void filter_mirror_init(Object *obj)
95
{
96
+ MirrorState *s = FILTER_MIRROR(obj);
97
+
98
object_property_add_str(obj, "outdev", filter_mirror_get_outdev,
99
filter_mirror_set_outdev, NULL);
100
+
101
+ s->vnet_hdr = false;
102
+ object_property_add_bool(obj, "vnet_hdr_support",
103
+ filter_mirror_get_vnet_hdr,
104
+ filter_mirror_set_vnet_hdr, NULL);
105
}
106
107
static void filter_redirector_init(Object *obj)
108
diff --git a/qemu-options.hx b/qemu-options.hx
109
index XXXXXXX..XXXXXXX 100644
110
--- a/qemu-options.hx
111
+++ b/qemu-options.hx
112
@@ -XXX,XX +XXX,XX @@ queue @var{all|rx|tx} is an option that can be applied to any netfilter.
113
@option{tx}: the filter is attached to the transmit queue of the netdev,
114
where it will receive packets sent by the netdev.
115
116
-@item -object filter-mirror,id=@var{id},netdev=@var{netdevid},outdev=@var{chardevid}[,queue=@var{all|rx|tx}]
117
+@item -object filter-mirror,id=@var{id},netdev=@var{netdevid},outdev=@var{chardevid},queue=@var{all|rx|tx}[,vnet_hdr_support]
118
119
-filter-mirror on netdev @var{netdevid},mirror net packet to chardev
120
-@var{chardevid}
121
+filter-mirror on netdev @var{netdevid},mirror net packet to chardev@var{chardevid}, if it has the vnet_hdr_support flag, filter-mirror will mirror packet with vnet_hdr_len.
122
123
@item -object filter-redirector,id=@var{id},netdev=@var{netdevid},indev=@var{chardevid},
124
outdev=@var{chardevid}[,queue=@var{all|rx|tx}]
125
--
126
2.7.4
127
128
diff view generated by jsdifflib
Deleted patch
1
From: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
2
1
3
We add the vnet_hdr_support option for filter-redirector, default is disabled.
4
If you use virtio-net-pci net driver or other driver needs vnet_hdr, please enable it.
5
Because colo-compare or other modules needs the vnet_hdr_len to parse
6
packet, we add this new option send the len to others.
7
You can use it for example:
8
-object filter-redirector,id=r0,netdev=hn0,queue=tx,outdev=red0,vnet_hdr_support
9
10
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
11
Signed-off-by: Jason Wang <jasowang@redhat.com>
12
---
13
net/filter-mirror.c | 23 +++++++++++++++++++++++
14
qemu-options.hx | 6 +++---
15
2 files changed, 26 insertions(+), 3 deletions(-)
16
17
diff --git a/net/filter-mirror.c b/net/filter-mirror.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/net/filter-mirror.c
20
+++ b/net/filter-mirror.c
21
@@ -XXX,XX +XXX,XX @@ static void filter_redirector_set_outdev(Object *obj,
22
s->outdev = g_strdup(value);
23
}
24
25
+static bool filter_redirector_get_vnet_hdr(Object *obj, Error **errp)
26
+{
27
+ MirrorState *s = FILTER_REDIRECTOR(obj);
28
+
29
+ return s->vnet_hdr;
30
+}
31
+
32
+static void filter_redirector_set_vnet_hdr(Object *obj,
33
+ bool value,
34
+ Error **errp)
35
+{
36
+ MirrorState *s = FILTER_REDIRECTOR(obj);
37
+
38
+ s->vnet_hdr = value;
39
+}
40
+
41
static void filter_mirror_init(Object *obj)
42
{
43
MirrorState *s = FILTER_MIRROR(obj);
44
@@ -XXX,XX +XXX,XX @@ static void filter_mirror_init(Object *obj)
45
46
static void filter_redirector_init(Object *obj)
47
{
48
+ MirrorState *s = FILTER_REDIRECTOR(obj);
49
+
50
object_property_add_str(obj, "indev", filter_redirector_get_indev,
51
filter_redirector_set_indev, NULL);
52
object_property_add_str(obj, "outdev", filter_redirector_get_outdev,
53
filter_redirector_set_outdev, NULL);
54
+
55
+ s->vnet_hdr = false;
56
+ object_property_add_bool(obj, "vnet_hdr_support",
57
+ filter_redirector_get_vnet_hdr,
58
+ filter_redirector_set_vnet_hdr, NULL);
59
}
60
61
static void filter_mirror_fini(Object *obj)
62
diff --git a/qemu-options.hx b/qemu-options.hx
63
index XXXXXXX..XXXXXXX 100644
64
--- a/qemu-options.hx
65
+++ b/qemu-options.hx
66
@@ -XXX,XX +XXX,XX @@ queue @var{all|rx|tx} is an option that can be applied to any netfilter.
67
68
filter-mirror on netdev @var{netdevid},mirror net packet to chardev@var{chardevid}, if it has the vnet_hdr_support flag, filter-mirror will mirror packet with vnet_hdr_len.
69
70
-@item -object filter-redirector,id=@var{id},netdev=@var{netdevid},indev=@var{chardevid},
71
-outdev=@var{chardevid}[,queue=@var{all|rx|tx}]
72
+@item -object filter-redirector,id=@var{id},netdev=@var{netdevid},indev=@var{chardevid},outdev=@var{chardevid},queue=@var{all|rx|tx}[,vnet_hdr_support]
73
74
filter-redirector on netdev @var{netdevid},redirect filter's net packet to chardev
75
-@var{chardevid},and redirect indev's packet to filter.
76
+@var{chardevid},and redirect indev's packet to filter.if it has the vnet_hdr_support flag,
77
+filter-redirector will redirect packet with vnet_hdr_len.
78
Create a filter-redirector we need to differ outdev id from indev id, id can not
79
be the same. we can just use indev or outdev, but at least one of indev or outdev
80
need to be specified.
81
--
82
2.7.4
83
84
diff view generated by jsdifflib
1
From: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
1
From: Qiang Liu <cyruscyliu@gmail.com>
2
2
3
We add the vnet_hdr_support option for colo-compare, default is disabled.
3
This patch replaces hw_error to guest error log for [read|write]b
4
If you use virtio-net-pci or other driver needs vnet_hdr, please enable it.
4
accesses when mode_16bit is enabled. This avoids aborting qemu.
5
You can use it for example:
6
-object colo-compare,id=comp0,primary_in=compare0-0,secondary_in=compare1,outdev=compare_out0,vnet_hdr_support
7
5
8
COLO-compare can get vnet header length from filter,
6
Fixes: 1248f8d4cbc3 ("hw/lan9118: Add basic 16-bit mode support.")
9
Add vnet_hdr_len to struct packet and output packet with
7
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1433
10
the vnet_hdr_len.
8
Reported-by: Qiang Liu <cyruscyliu@gmail.com>
11
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
12
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
10
Signed-off-by: Qiang Liu <cyruscyliu@gmail.com>
11
Suggested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
13
Signed-off-by: Jason Wang <jasowang@redhat.com>
12
Signed-off-by: Jason Wang <jasowang@redhat.com>
14
---
13
---
15
net/colo-compare.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++-------
14
hw/net/lan9118.c | 17 ++++++++---------
16
qemu-options.hx | 4 ++--
15
1 file changed, 8 insertions(+), 9 deletions(-)
17
2 files changed, 55 insertions(+), 9 deletions(-)
18
16
19
diff --git a/net/colo-compare.c b/net/colo-compare.c
17
diff --git a/hw/net/lan9118.c b/hw/net/lan9118.c
20
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
21
--- a/net/colo-compare.c
19
--- a/hw/net/lan9118.c
22
+++ b/net/colo-compare.c
20
+++ b/hw/net/lan9118.c
23
@@ -XXX,XX +XXX,XX @@ typedef struct CompareState {
21
@@ -XXX,XX +XXX,XX @@
24
CharBackend chr_out;
22
#include "migration/vmstate.h"
25
SocketReadState pri_rs;
23
#include "net/net.h"
26
SocketReadState sec_rs;
24
#include "net/eth.h"
27
+ bool vnet_hdr;
25
-#include "hw/hw.h"
28
26
#include "hw/irq.h"
29
/* connection list: the connections belonged to this NIC could be found
27
#include "hw/net/lan9118.h"
30
* in this list.
28
#include "hw/ptimer.h"
31
@@ -XXX,XX +XXX,XX @@ enum {
29
@@ -XXX,XX +XXX,XX @@
32
30
#ifdef DEBUG_LAN9118
33
static int compare_chr_send(CompareState *s,
31
#define DPRINTF(fmt, ...) \
34
const uint8_t *buf,
32
do { printf("lan9118: " fmt , ## __VA_ARGS__); } while (0)
35
- uint32_t size);
33
-#define BADF(fmt, ...) \
36
+ uint32_t size,
34
-do { hw_error("lan9118: error: " fmt , ## __VA_ARGS__);} while (0)
37
+ uint32_t vnet_hdr_len);
35
#else
38
36
#define DPRINTF(fmt, ...) do {} while(0)
39
static gint seq_sorter(Packet *a, Packet *b, gpointer data)
37
-#define BADF(fmt, ...) \
40
{
38
-do { fprintf(stderr, "lan9118: error: " fmt , ## __VA_ARGS__);} while (0)
41
@@ -XXX,XX +XXX,XX @@ static void colo_compare_connection(void *opaque, void *user_data)
39
#endif
42
}
40
43
41
/* The tx and rx fifo ports are a range of aliased 32-bit registers */
44
if (result) {
42
@@ -XXX,XX +XXX,XX @@ static uint32_t do_phy_read(lan9118_state *s, int reg)
45
- ret = compare_chr_send(s, pkt->data, pkt->size);
43
case 30: /* Interrupt mask */
46
+ ret = compare_chr_send(s,
44
return s->phy_int_mask;
47
+ pkt->data,
45
default:
48
+ pkt->size,
46
- BADF("PHY read reg %d\n", reg);
49
+ pkt->vnet_hdr_len);
47
+ qemu_log_mask(LOG_GUEST_ERROR,
50
if (ret < 0) {
48
+ "do_phy_read: PHY read reg %d\n", reg);
51
error_report("colo_send_primary_packet failed");
49
return 0;
52
}
53
@@ -XXX,XX +XXX,XX @@ static void colo_compare_connection(void *opaque, void *user_data)
54
55
static int compare_chr_send(CompareState *s,
56
const uint8_t *buf,
57
- uint32_t size)
58
+ uint32_t size,
59
+ uint32_t vnet_hdr_len)
60
{
61
int ret = 0;
62
uint32_t len = htonl(size);
63
@@ -XXX,XX +XXX,XX @@ static int compare_chr_send(CompareState *s,
64
goto err;
65
}
50
}
66
67
+ if (s->vnet_hdr) {
68
+ /*
69
+ * We send vnet header len make other module(like filter-redirector)
70
+ * know how to parse net packet correctly.
71
+ */
72
+ len = htonl(vnet_hdr_len);
73
+ ret = qemu_chr_fe_write_all(&s->chr_out, (uint8_t *)&len, sizeof(len));
74
+ if (ret != sizeof(len)) {
75
+ goto err;
76
+ }
77
+ }
78
+
79
ret = qemu_chr_fe_write_all(&s->chr_out, (uint8_t *)buf, size);
80
if (ret != size) {
81
goto err;
82
@@ -XXX,XX +XXX,XX @@ static void compare_set_outdev(Object *obj, const char *value, Error **errp)
83
s->outdev = g_strdup(value);
84
}
51
}
85
52
@@ -XXX,XX +XXX,XX @@ static void do_phy_write(lan9118_state *s, int reg, uint32_t val)
86
+static bool compare_get_vnet_hdr(Object *obj, Error **errp)
53
phy_update_irq(s);
87
+{
54
break;
88
+ CompareState *s = COLO_COMPARE(obj);
55
default:
89
+
56
- BADF("PHY write reg %d = 0x%04x\n", reg, val);
90
+ return s->vnet_hdr;
57
+ qemu_log_mask(LOG_GUEST_ERROR,
91
+}
58
+ "do_phy_write: PHY write reg %d = 0x%04x\n", reg, val);
92
+
59
}
93
+static void compare_set_vnet_hdr(Object *obj,
60
}
94
+ bool value,
61
95
+ Error **errp)
62
@@ -XXX,XX +XXX,XX @@ static void lan9118_16bit_mode_write(void *opaque, hwaddr offset,
96
+{
97
+ CompareState *s = COLO_COMPARE(obj);
98
+
99
+ s->vnet_hdr = value;
100
+}
101
+
102
static void compare_pri_rs_finalize(SocketReadState *pri_rs)
103
{
104
CompareState *s = container_of(pri_rs, CompareState, pri_rs);
105
106
if (packet_enqueue(s, PRIMARY_IN)) {
107
trace_colo_compare_main("primary: unsupported packet in");
108
- compare_chr_send(s, pri_rs->buf, pri_rs->packet_len);
109
+ compare_chr_send(s,
110
+ pri_rs->buf,
111
+ pri_rs->packet_len,
112
+ pri_rs->vnet_hdr_len);
113
} else {
114
/* compare connection */
115
g_queue_foreach(&s->conn_list, colo_compare_connection, s);
116
@@ -XXX,XX +XXX,XX @@ static void colo_compare_complete(UserCreatable *uc, Error **errp)
117
return;
63
return;
118
}
64
}
119
65
120
- net_socket_rs_init(&s->pri_rs, compare_pri_rs_finalize, false);
66
- hw_error("lan9118_write: Bad size 0x%x\n", size);
121
- net_socket_rs_init(&s->sec_rs, compare_sec_rs_finalize, false);
67
+ qemu_log_mask(LOG_GUEST_ERROR,
122
+ net_socket_rs_init(&s->pri_rs, compare_pri_rs_finalize, s->vnet_hdr);
68
+ "lan9118_16bit_mode_write: Bad size 0x%x\n", size);
123
+ net_socket_rs_init(&s->sec_rs, compare_sec_rs_finalize, s->vnet_hdr);
69
}
124
70
125
g_queue_init(&s->conn_list);
71
static uint64_t lan9118_readl(void *opaque, hwaddr offset,
126
72
@@ -XXX,XX +XXX,XX @@ static uint64_t lan9118_16bit_mode_read(void *opaque, hwaddr offset,
127
@@ -XXX,XX +XXX,XX @@ static void colo_flush_packets(void *opaque, void *user_data)
73
return lan9118_readl(opaque, offset, size);
128
129
while (!g_queue_is_empty(&conn->primary_list)) {
130
pkt = g_queue_pop_head(&conn->primary_list);
131
- compare_chr_send(s, pkt->data, pkt->size);
132
+ compare_chr_send(s,
133
+ pkt->data,
134
+ pkt->size,
135
+ pkt->vnet_hdr_len);
136
packet_destroy(pkt, NULL);
137
}
74
}
138
while (!g_queue_is_empty(&conn->secondary_list)) {
75
139
@@ -XXX,XX +XXX,XX @@ static void colo_compare_class_init(ObjectClass *oc, void *data)
76
- hw_error("lan9118_read: Bad size 0x%x\n", size);
140
77
+ qemu_log_mask(LOG_GUEST_ERROR,
141
static void colo_compare_init(Object *obj)
78
+ "lan9118_16bit_mode_read: Bad size 0x%x\n", size);
142
{
79
return 0;
143
+ CompareState *s = COLO_COMPARE(obj);
144
+
145
object_property_add_str(obj, "primary_in",
146
compare_get_pri_indev, compare_set_pri_indev,
147
NULL);
148
@@ -XXX,XX +XXX,XX @@ static void colo_compare_init(Object *obj)
149
object_property_add_str(obj, "outdev",
150
compare_get_outdev, compare_set_outdev,
151
NULL);
152
+
153
+ s->vnet_hdr = false;
154
+ object_property_add_bool(obj, "vnet_hdr_support", compare_get_vnet_hdr,
155
+ compare_set_vnet_hdr, NULL);
156
}
80
}
157
158
static void colo_compare_finalize(Object *obj)
159
diff --git a/qemu-options.hx b/qemu-options.hx
160
index XXXXXXX..XXXXXXX 100644
161
--- a/qemu-options.hx
162
+++ b/qemu-options.hx
163
@@ -XXX,XX +XXX,XX @@ Dump the network traffic on netdev @var{dev} to the file specified by
164
The file format is libpcap, so it can be analyzed with tools such as tcpdump
165
or Wireshark.
166
167
-@item -object colo-compare,id=@var{id},primary_in=@var{chardevid},secondary_in=@var{chardevid},
168
-outdev=@var{chardevid}
169
+@item -object colo-compare,id=@var{id},primary_in=@var{chardevid},secondary_in=@var{chardevid},outdev=@var{chardevid}[,vnet_hdr_support]
170
171
Colo-compare gets packet from primary_in@var{chardevid} and secondary_in@var{chardevid}, than compare primary packet with
172
secondary packet. If the packets are same, we will output primary
173
packet to outdev@var{chardevid}, else we will notify colo-frame
174
do checkpoint and send primary packet to outdev@var{chardevid}.
175
+if it has the vnet_hdr_support flag, colo compare will send/recv packet with vnet_hdr_len.
176
177
we must use it with the help of filter-mirror and filter-redirector.
178
81
179
--
82
--
180
2.7.4
83
2.7.4
181
84
182
85
diff view generated by jsdifflib
1
Spec said offloads should be le64, so use virtio_ldq_p() to guarantee
1
From: Fiona Ebner <f.ebner@proxmox.com>
2
valid endian.
3
2
4
Fixes: 644c98587d4c ("virtio-net: dynamic network offloads configuration")
3
Currently, VMXNET3_MAX_MTU itself (being 9000) is not considered a
5
Cc: qemu-stable@nongnu.org
4
valid value for the MTU, but a guest running ESXi 7.0 might try to
6
Cc: Dmitry Fleytman <dfleytma@redhat.com>
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>
7
Signed-off-by: Jason Wang <jasowang@redhat.com>
19
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
---
20
---
9
hw/net/virtio-net.c | 2 ++
21
hw/net/vmxnet3.c | 2 +-
10
1 file changed, 2 insertions(+)
22
1 file changed, 1 insertion(+), 1 deletion(-)
11
23
12
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
24
diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c
13
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/net/virtio-net.c
26
--- a/hw/net/vmxnet3.c
15
+++ b/hw/net/virtio-net.c
27
+++ b/hw/net/vmxnet3.c
16
@@ -XXX,XX +XXX,XX @@ static int virtio_net_handle_offloads(VirtIONet *n, uint8_t cmd,
28
@@ -XXX,XX +XXX,XX @@ static void vmxnet3_activate_device(VMXNET3State *s)
17
if (cmd == VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET) {
29
vmxnet3_setup_rx_filtering(s);
18
uint64_t supported_offloads;
30
/* Cache fields from shared memory */
19
31
s->mtu = VMXNET3_READ_DRV_SHARED32(d, s->drv_shmem, devRead.misc.mtu);
20
+ offloads = virtio_ldq_p(vdev, &offloads);
32
- assert(VMXNET3_MIN_MTU <= s->mtu && s->mtu < VMXNET3_MAX_MTU);
21
+
33
+ assert(VMXNET3_MIN_MTU <= s->mtu && s->mtu <= VMXNET3_MAX_MTU);
22
if (!n->has_vnet_hdr) {
34
VMW_CFPRN("MTU is %u", s->mtu);
23
return VIRTIO_NET_ERR;
35
24
}
36
s->max_rx_frags =
25
--
37
--
26
2.7.4
38
2.7.4
27
28
diff view generated by jsdifflib
1
From: Michal Privoznik <mprivozn@redhat.com>
1
From: Christian Svensson <blue@cmd.nu>
2
2
3
We have a function that checks if given number is power of two.
3
Increase the allocated buffer size to fit larger packets.
4
We should prefer it instead of expanding the check on our own.
4
Given that jumboframes can commonly be up to 9000 bytes the closest suitable
5
value seems to be 16 KiB.
5
6
6
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
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>
7
Signed-off-by: Jason Wang <jasowang@redhat.com>
11
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
---
12
---
9
hw/net/virtio-net.c | 2 +-
13
net/l2tpv3.c | 2 +-
10
1 file changed, 1 insertion(+), 1 deletion(-)
14
1 file changed, 1 insertion(+), 1 deletion(-)
11
15
12
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
16
diff --git a/net/l2tpv3.c b/net/l2tpv3.c
13
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/net/virtio-net.c
18
--- a/net/l2tpv3.c
15
+++ b/hw/net/virtio-net.c
19
+++ b/net/l2tpv3.c
16
@@ -XXX,XX +XXX,XX @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp)
20
@@ -XXX,XX +XXX,XX @@
17
*/
21
*/
18
if (n->net_conf.rx_queue_size < VIRTIO_NET_RX_QUEUE_MIN_SIZE ||
22
19
n->net_conf.rx_queue_size > VIRTQUEUE_MAX_SIZE ||
23
#define BUFFER_ALIGN sysconf(_SC_PAGESIZE)
20
- (n->net_conf.rx_queue_size & (n->net_conf.rx_queue_size - 1))) {
24
-#define BUFFER_SIZE 2048
21
+ !is_power_of_2(n->net_conf.rx_queue_size)) {
25
+#define BUFFER_SIZE 16384
22
error_setg(errp, "Invalid rx_queue_size (= %" PRIu16 "), "
26
#define IOVSIZE 2
23
"must be a power of 2 between %d and %d.",
27
#define MAX_L2TPV3_MSGCNT 64
24
n->net_conf.rx_queue_size, VIRTIO_NET_RX_QUEUE_MIN_SIZE,
28
#define MAX_L2TPV3_IOVCNT (MAX_L2TPV3_MSGCNT * IOVSIZE)
25
--
29
--
26
2.7.4
30
2.7.4
27
28
diff view generated by jsdifflib
1
From: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
1
From: Joelle van Dyne <j@getutm.app>
2
2
3
This patch change the compare_chr_send() parameter from CharBackend to CompareState,
3
When the VM is stopped using the HMP command "stop", soon the handler will
4
we can get more information like vnet_hdr(We use it to support packet with vnet_header).
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.
5
9
6
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
10
Signed-off-by: Joelle van Dyne <j@getutm.app>
7
Signed-off-by: Jason Wang <jasowang@redhat.com>
11
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
---
12
---
9
net/colo-compare.c | 14 +++++++-------
13
net/vmnet-common.m | 48 +++++++++++++++++++++++++++++++++++-------------
10
1 file changed, 7 insertions(+), 7 deletions(-)
14
net/vmnet_int.h | 2 ++
15
2 files changed, 37 insertions(+), 13 deletions(-)
11
16
12
diff --git a/net/colo-compare.c b/net/colo-compare.c
17
diff --git a/net/vmnet-common.m b/net/vmnet-common.m
13
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
14
--- a/net/colo-compare.c
19
--- a/net/vmnet-common.m
15
+++ b/net/colo-compare.c
20
+++ b/net/vmnet-common.m
16
@@ -XXX,XX +XXX,XX @@ enum {
21
@@ -XXX,XX +XXX,XX @@
17
SECONDARY_IN,
22
#include "clients.h"
18
};
23
#include "qemu/error-report.h"
19
24
#include "qapi/error.h"
20
-static int compare_chr_send(CharBackend *out,
25
+#include "sysemu/runstate.h"
21
+static int compare_chr_send(CompareState *s,
26
22
const uint8_t *buf,
27
#include <vmnet/vmnet.h>
23
uint32_t size);
28
#include <dispatch/dispatch.h>
24
29
@@ -XXX,XX +XXX,XX @@ static void vmnet_bufs_init(VmnetState *s)
25
@@ -XXX,XX +XXX,XX @@ static void colo_compare_connection(void *opaque, void *user_data)
26
}
27
28
if (result) {
29
- ret = compare_chr_send(&s->chr_out, pkt->data, pkt->size);
30
+ ret = compare_chr_send(s, pkt->data, pkt->size);
31
if (ret < 0) {
32
error_report("colo_send_primary_packet failed");
33
}
34
@@ -XXX,XX +XXX,XX @@ static void colo_compare_connection(void *opaque, void *user_data)
35
}
30
}
36
}
31
}
37
32
38
-static int compare_chr_send(CharBackend *out,
33
+/**
39
+static int compare_chr_send(CompareState *s,
34
+ * Called on state change to un-register/re-register handlers
40
const uint8_t *buf,
35
+ */
41
uint32_t size)
36
+static void vmnet_vm_state_change_cb(void *opaque, bool running, RunState state)
42
{
37
+{
43
@@ -XXX,XX +XXX,XX @@ static int compare_chr_send(CharBackend *out,
38
+ VmnetState *s = opaque;
44
return 0;
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;
45
}
90
}
46
91
47
- ret = qemu_chr_fe_write_all(out, (uint8_t *)&len, sizeof(len));
92
+ vmnet_vm_state_change_cb(s, 0, RUN_STATE_SHUTDOWN);
48
+ ret = qemu_chr_fe_write_all(&s->chr_out, (uint8_t *)&len, sizeof(len));
93
+ qemu_del_vm_change_state_handler(s->change);
49
if (ret != sizeof(len)) {
94
if_stopped_sem = dispatch_semaphore_create(0);
50
goto err;
95
vmnet_stop_interface(
51
}
96
s->vmnet_if,
52
97
diff --git a/net/vmnet_int.h b/net/vmnet_int.h
53
- ret = qemu_chr_fe_write_all(out, (uint8_t *)buf, size);
98
index XXXXXXX..XXXXXXX 100644
54
+ ret = qemu_chr_fe_write_all(&s->chr_out, (uint8_t *)buf, size);
99
--- a/net/vmnet_int.h
55
if (ret != size) {
100
+++ b/net/vmnet_int.h
56
goto err;
101
@@ -XXX,XX +XXX,XX @@ typedef struct VmnetState {
57
}
102
int packets_send_end_pos;
58
@@ -XXX,XX +XXX,XX @@ static void compare_pri_rs_finalize(SocketReadState *pri_rs)
103
59
104
struct iovec iov_buf[VMNET_PACKETS_LIMIT];
60
if (packet_enqueue(s, PRIMARY_IN)) {
105
+
61
trace_colo_compare_main("primary: unsupported packet in");
106
+ VMChangeStateEntry *change;
62
- compare_chr_send(&s->chr_out, pri_rs->buf, pri_rs->packet_len);
107
} VmnetState;
63
+ compare_chr_send(s, pri_rs->buf, pri_rs->packet_len);
108
64
} else {
109
const char *vmnet_status_map_str(vmnet_return_t status);
65
/* compare connection */
66
g_queue_foreach(&s->conn_list, colo_compare_connection, s);
67
@@ -XXX,XX +XXX,XX @@ static void colo_flush_packets(void *opaque, void *user_data)
68
69
while (!g_queue_is_empty(&conn->primary_list)) {
70
pkt = g_queue_pop_head(&conn->primary_list);
71
- compare_chr_send(&s->chr_out, pkt->data, pkt->size);
72
+ compare_chr_send(s, pkt->data, pkt->size);
73
packet_destroy(pkt, NULL);
74
}
75
while (!g_queue_is_empty(&conn->secondary_list)) {
76
--
110
--
77
2.7.4
111
2.7.4
78
79
diff view generated by jsdifflib
1
From: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
1
From: Qiang Liu <cyruscyliu@gmail.com>
2
2
3
COLO-Proxy just focus on packet payload, so we skip vnet header.
3
Check fifos before poping data from and pushing data into it.
4
4
5
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
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>
6
Signed-off-by: Jason Wang <jasowang@redhat.com>
10
Signed-off-by: Jason Wang <jasowang@redhat.com>
7
---
11
---
8
net/colo-compare.c | 8 ++++++--
12
hw/net/can/xlnx-zynqmp-can.c | 9 ++++++++-
9
1 file changed, 6 insertions(+), 2 deletions(-)
13
1 file changed, 8 insertions(+), 1 deletion(-)
10
14
11
diff --git a/net/colo-compare.c b/net/colo-compare.c
15
diff --git a/hw/net/can/xlnx-zynqmp-can.c b/hw/net/can/xlnx-zynqmp-can.c
12
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
13
--- a/net/colo-compare.c
17
--- a/hw/net/can/xlnx-zynqmp-can.c
14
+++ b/net/colo-compare.c
18
+++ b/hw/net/can/xlnx-zynqmp-can.c
15
@@ -XXX,XX +XXX,XX @@ static int colo_packet_compare_common(Packet *ppkt, Packet *spkt, int offset)
19
@@ -XXX,XX +XXX,XX @@ static void transfer_fifo(XlnxZynqMPCANState *s, Fifo32 *fifo)
16
sec_ip_src, sec_ip_dst);
17
}
20
}
18
21
19
+ offset = ppkt->vnet_hdr_len + offset;
22
while (!fifo32_is_empty(fifo)) {
20
+
23
+ if (fifo32_num_used(fifo) < (4 * CAN_FRAME_SIZE)) {
21
if (ppkt->size == spkt->size) {
24
+ g_autofree char *path = object_get_canonical_path(OBJECT(s));
22
- return memcmp(ppkt->data + offset, spkt->data + offset,
25
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: data left in the fifo is not"
23
+ return memcmp(ppkt->data + offset,
26
+ " enough for transfer.\n", path);
24
+ spkt->data + offset,
27
+ break;
25
spkt->size - offset);
28
+ }
26
} else {
29
for (i = 0; i < CAN_FRAME_SIZE; i++) {
27
trace_colo_compare_main("Net packet size are not the same");
30
data[i] = fifo32_pop(fifo);
28
@@ -XXX,XX +XXX,XX @@ static int colo_packet_compare_tcp(Packet *spkt, Packet *ppkt)
31
}
29
*/
32
@@ -XXX,XX +XXX,XX @@ static void transfer_fifo(XlnxZynqMPCANState *s, Fifo32 *fifo)
30
if (ptcp->th_off > 5) {
33
* acknowledged. The XlnxZynqMPCAN core receives any message
31
ptrdiff_t tcp_offset;
34
* that it transmits.
32
+
35
*/
33
tcp_offset = ppkt->transport_header - (uint8_t *)ppkt->data
36
- if (fifo32_is_full(&s->rx_fifo)) {
34
- + (ptcp->th_off * 4);
37
+ if (fifo32_is_full(&s->rx_fifo) ||
35
+ + (ptcp->th_off * 4) - ppkt->vnet_hdr_len;
38
+ (fifo32_num_free(&s->rx_fifo) < (4 * CAN_FRAME_SIZE))) {
36
res = colo_packet_compare_common(ppkt, spkt, tcp_offset);
39
ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, RXOFLW, 1);
37
} else if (ptcp->th_sum == stcp->th_sum) {
40
} else {
38
res = colo_packet_compare_common(ppkt, spkt, ETH_HLEN);
41
for (i = 0; i < CAN_FRAME_SIZE; i++) {
39
--
42
--
40
2.7.4
43
2.7.4
41
42
diff view generated by jsdifflib
1
From: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
1
From: Laurent Vivier <lvivier@redhat.com>
2
2
3
We add the vnet_hdr_support option for filter-rewriter, default is disabled.
3
In stream mode, if the server shuts down there is currently
4
If you use virtio-net-pci or other driver needs vnet_hdr, please enable it.
4
no way to reconnect the client to a new server without removing
5
You can use it for example:
5
the NIC device and the netdev backend (or to reboot).
6
-object filter-rewriter,id=rew0,netdev=hn0,queue=all,vnet_hdr_support
6
7
7
This patch introduces a reconnect option that specifies a delay
8
We get the vnet_hdr_len from NetClientState that make us
8
to try to reconnect with the same parameters.
9
parse net packet correctly.
9
10
10
Add a new test in qtest to test the reconnect option and the
11
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
11
connect/disconnect events.
12
13
Signed-off-by: Laurent Vivier <lvivier@redhat.com>
12
Signed-off-by: Jason Wang <jasowang@redhat.com>
14
Signed-off-by: Jason Wang <jasowang@redhat.com>
13
---
15
---
14
net/filter-rewriter.c | 37 ++++++++++++++++++++++++++++++++++++-
16
net/stream.c | 53 ++++++++++++++++++++++-
15
qemu-options.hx | 4 ++--
17
qapi/net.json | 7 ++-
16
2 files changed, 38 insertions(+), 3 deletions(-)
18
qemu-options.hx | 6 +--
17
19
tests/qtest/netdev-socket.c | 101 ++++++++++++++++++++++++++++++++++++++++++++
18
diff --git a/net/filter-rewriter.c b/net/filter-rewriter.c
20
4 files changed, 162 insertions(+), 5 deletions(-)
21
22
diff --git a/net/stream.c b/net/stream.c
19
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
20
--- a/net/filter-rewriter.c
24
--- a/net/stream.c
21
+++ b/net/filter-rewriter.c
25
+++ b/net/stream.c
22
@@ -XXX,XX +XXX,XX @@
26
@@ -XXX,XX +XXX,XX @@
23
#include "qemu-common.h"
27
#include "io/channel-socket.h"
24
#include "qapi/error.h"
28
#include "io/net-listener.h"
25
#include "qapi/qmp/qerror.h"
29
#include "qapi/qapi-events-net.h"
26
+#include "qemu/error-report.h"
30
+#include "qapi/qapi-visit-sockets.h"
27
#include "qapi-visit.h"
31
+#include "qapi/clone-visitor.h"
28
#include "qom/object.h"
32
29
#include "qemu/main-loop.h"
33
typedef struct NetStreamState {
30
@@ -XXX,XX +XXX,XX @@ typedef struct RewriterState {
34
NetClientState nc;
31
NetQueue *incoming_queue;
35
@@ -XXX,XX +XXX,XX @@ typedef struct NetStreamState {
32
/* hashtable to save connection */
36
guint ioc_write_tag;
33
GHashTable *connection_track_table;
37
SocketReadState rs;
34
+ bool vnet_hdr;
38
unsigned int send_index; /* number of bytes sent*/
35
} RewriterState;
39
+ uint32_t reconnect;
36
40
+ guint timer_tag;
37
static void filter_rewriter_flush(NetFilterState *nf)
41
+ SocketAddress *addr;
38
@@ -XXX,XX +XXX,XX @@ static ssize_t colo_rewriter_receive_iov(NetFilterState *nf,
42
} NetStreamState;
39
ConnectionKey key;
43
40
Packet *pkt;
44
static void net_stream_listen(QIONetListener *listener,
41
ssize_t size = iov_size(iov, iovcnt);
45
QIOChannelSocket *cioc,
42
+ ssize_t vnet_hdr_len = 0;
46
void *opaque);
43
char *buf = g_malloc0(size);
47
+static void net_stream_arm_reconnect(NetStreamState *s);
44
48
45
iov_to_buf(iov, iovcnt, 0, buf, size);
49
static gboolean net_stream_writable(QIOChannel *ioc,
46
- pkt = packet_new(buf, size, 0);
50
GIOCondition condition,
47
+
51
@@ -XXX,XX +XXX,XX @@ static gboolean net_stream_send(QIOChannel *ioc,
48
+ if (s->vnet_hdr) {
52
qemu_set_info_str(&s->nc, "%s", "");
49
+ vnet_hdr_len = nf->netdev->vnet_hdr_len;
53
50
+ }
54
qapi_event_send_netdev_stream_disconnected(s->nc.name);
51
+
55
+ net_stream_arm_reconnect(s);
52
+ pkt = packet_new(buf, size, vnet_hdr_len);
56
53
g_free(buf);
57
return G_SOURCE_REMOVE;
54
58
}
55
/*
59
@@ -XXX,XX +XXX,XX @@ static gboolean net_stream_send(QIOChannel *ioc,
56
@@ -XXX,XX +XXX,XX @@ static void colo_rewriter_setup(NetFilterState *nf, Error **errp)
60
static void net_stream_cleanup(NetClientState *nc)
57
s->incoming_queue = qemu_new_net_queue(qemu_netfilter_pass_to_next, nf);
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
+ }
58
}
102
}
59
103
60
+static bool filter_rewriter_get_vnet_hdr(Object *obj, Error **errp)
104
static int net_stream_client_init(NetClientState *peer,
61
+{
105
const char *model,
62
+ RewriterState *s = FILTER_COLO_REWRITER(obj);
106
const char *name,
63
+
107
SocketAddress *addr,
64
+ return s->vnet_hdr;
108
+ uint32_t reconnect,
65
+}
109
Error **errp)
66
+
67
+static void filter_rewriter_set_vnet_hdr(Object *obj,
68
+ bool value,
69
+ Error **errp)
70
+{
71
+ RewriterState *s = FILTER_COLO_REWRITER(obj);
72
+
73
+ s->vnet_hdr = value;
74
+}
75
+
76
+static void filter_rewriter_init(Object *obj)
77
+{
78
+ RewriterState *s = FILTER_COLO_REWRITER(obj);
79
+
80
+ s->vnet_hdr = false;
81
+ object_property_add_bool(obj, "vnet_hdr_support",
82
+ filter_rewriter_get_vnet_hdr,
83
+ filter_rewriter_set_vnet_hdr, NULL);
84
+}
85
+
86
static void colo_rewriter_class_init(ObjectClass *oc, void *data)
87
{
110
{
88
NetFilterClass *nfc = NETFILTER_CLASS(oc);
111
NetStreamState *s;
89
@@ -XXX,XX +XXX,XX @@ static const TypeInfo colo_rewriter_info = {
112
@@ -XXX,XX +XXX,XX @@ static int net_stream_client_init(NetClientState *peer,
90
.name = TYPE_FILTER_REWRITER,
113
s->ioc = QIO_CHANNEL(sioc);
91
.parent = TYPE_NETFILTER,
114
s->nc.link_down = true;
92
.class_init = colo_rewriter_class_init,
115
93
+ .instance_init = filter_rewriter_init,
116
+ s->reconnect = reconnect;
94
.instance_size = sizeof(RewriterState),
117
+ if (reconnect) {
95
};
118
+ s->addr = QAPI_CLONE(SocketAddress, addr);
96
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:
97
diff --git a/qemu-options.hx b/qemu-options.hx
164
diff --git a/qemu-options.hx b/qemu-options.hx
98
index XXXXXXX..XXXXXXX 100644
165
index XXXXXXX..XXXXXXX 100644
99
--- a/qemu-options.hx
166
--- a/qemu-options.hx
100
+++ b/qemu-options.hx
167
+++ b/qemu-options.hx
101
@@ -XXX,XX +XXX,XX @@ Create a filter-redirector we need to differ outdev id from indev id, id can not
168
@@ -XXX,XX +XXX,XX @@ DEF("netdev", HAS_ARG, QEMU_OPTION_netdev,
102
be the same. we can just use indev or outdev, but at least one of indev or outdev
169
"-netdev socket,id=str[,fd=h][,udp=host:port][,localaddr=host:port]\n"
103
need to be specified.
170
" configure a network backend to connect to another network\n"
104
171
" using an UDP tunnel\n"
105
-@item -object filter-rewriter,id=@var{id},netdev=@var{netdevid}[,queue=@var{all|rx|tx}]
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"
106
+@item -object filter-rewriter,id=@var{id},netdev=@var{netdevid},queue=@var{all|rx|tx},[vnet_hdr_support]
173
- "-netdev stream,id=str[,server=on|off],addr.type=unix,addr.path=path[,abstract=on|off][,tight=on|off]\n"
107
174
- "-netdev stream,id=str[,server=on|off],addr.type=fd,addr.str=file-descriptor\n"
108
Filter-rewriter is a part of COLO project.It will rewrite tcp packet to
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"
109
secondary from primary to keep secondary tcp connection,and rewrite
176
+ "-netdev stream,id=str[,server=on|off],addr.type=unix,addr.path=path[,abstract=on|off][,tight=on|off][,reconnect=seconds]\n"
110
tcp packet to primary from secondary make tcp packet can be handled by
177
+ "-netdev stream,id=str[,server=on|off],addr.type=fd,addr.str=file-descriptor[,reconnect=seconds]\n"
111
-client.
178
" configure a network backend to connect to another network\n"
112
+client.if it has the vnet_hdr_support flag, we can parse packet with vnet header.
179
" using a socket connection in stream mode.\n"
113
180
"-netdev dgram,id=str,remote.type=inet,remote.host=maddr,remote.port=port[,local.type=inet,local.host=addr]\n"
114
usage:
181
diff --git a/tests/qtest/netdev-socket.c b/tests/qtest/netdev-socket.c
115
colo secondary:
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);
116
--
307
--
117
2.7.4
308
2.7.4
118
119
diff view generated by jsdifflib
1
From: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
1
From: Eugenio Pérez <eperezma@redhat.com>
2
2
3
Make colo-compare and filter-rewriter can parse vnet packet.
3
VHOST_BACKEND_F_IOTLB_ASID is the feature bit, not the bitmask. Since
4
the device under test also provided VHOST_BACKEND_F_IOTLB_MSG_V2 and
5
VHOST_BACKEND_F_IOTLB_BATCH, this went unnoticed.
4
6
5
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
7
Fixes: c1a1008685 ("vdpa: always start CVQ in SVQ mode if possible")
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>
6
Signed-off-by: Jason Wang <jasowang@redhat.com>
11
Signed-off-by: Jason Wang <jasowang@redhat.com>
7
---
12
---
8
net/colo.c | 6 +++---
13
net/vhost-vdpa.c | 2 +-
9
1 file changed, 3 insertions(+), 3 deletions(-)
14
1 file changed, 1 insertion(+), 1 deletion(-)
10
15
11
diff --git a/net/colo.c b/net/colo.c
16
diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
12
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
13
--- a/net/colo.c
18
--- a/net/vhost-vdpa.c
14
+++ b/net/colo.c
19
+++ b/net/vhost-vdpa.c
15
@@ -XXX,XX +XXX,XX @@ int parse_packet_early(Packet *pkt)
20
@@ -XXX,XX +XXX,XX @@ static int vhost_vdpa_net_cvq_start(NetClientState *nc)
16
{
21
g_strerror(errno), errno);
17
int network_length;
22
return -1;
18
static const uint8_t vlan[] = {0x81, 0x00};
19
- uint8_t *data = pkt->data;
20
+ uint8_t *data = pkt->data + pkt->vnet_hdr_len;
21
uint16_t l3_proto;
22
ssize_t l2hdr_len = eth_get_l2_hdr_length(data);
23
24
- if (pkt->size < ETH_HLEN) {
25
+ if (pkt->size < ETH_HLEN + pkt->vnet_hdr_len) {
26
trace_colo_proxy_main("pkt->size < ETH_HLEN");
27
return 1;
28
}
23
}
29
@@ -XXX,XX +XXX,XX @@ int parse_packet_early(Packet *pkt)
24
- if (!(backend_features & VHOST_BACKEND_F_IOTLB_ASID) ||
30
}
25
+ if (!(backend_features & BIT_ULL(VHOST_BACKEND_F_IOTLB_ASID)) ||
31
26
!vhost_vdpa_net_valid_svq_features(v->dev->features, NULL)) {
32
network_length = pkt->ip->ip_hl * 4;
27
return 0;
33
- if (pkt->size < l2hdr_len + network_length) {
34
+ if (pkt->size < l2hdr_len + network_length + pkt->vnet_hdr_len) {
35
trace_colo_proxy_main("pkt->size < network_header + network_length");
36
return 1;
37
}
28
}
38
--
29
--
39
2.7.4
30
2.7.4
40
31
41
32
diff view generated by jsdifflib
Deleted patch
1
From: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
2
1
3
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
4
Signed-off-by: Jason Wang <jasowang@redhat.com>
5
---
6
docs/colo-proxy.txt | 26 ++++++++++++++++++++++++++
7
1 file changed, 26 insertions(+)
8
9
diff --git a/docs/colo-proxy.txt b/docs/colo-proxy.txt
10
index XXXXXXX..XXXXXXX 100644
11
--- a/docs/colo-proxy.txt
12
+++ b/docs/colo-proxy.txt
13
@@ -XXX,XX +XXX,XX @@ Secondary(ip:3.3.3.8):
14
-chardev socket,id=red1,host=3.3.3.3,port=9004
15
-object filter-redirector,id=f1,netdev=hn0,queue=tx,indev=red0
16
-object filter-redirector,id=f2,netdev=hn0,queue=rx,outdev=red1
17
+-object filter-rewriter,id=f3,netdev=hn0,queue=all
18
+
19
+If you want to use virtio-net-pci or other driver with vnet_header:
20
+
21
+Primary(ip:3.3.3.3):
22
+-netdev tap,id=hn0,vhost=off,script=/etc/qemu-ifup,downscript=/etc/qemu-ifdown
23
+-device e1000,id=e0,netdev=hn0,mac=52:a4:00:12:78:66
24
+-chardev socket,id=mirror0,host=3.3.3.3,port=9003,server,nowait
25
+-chardev socket,id=compare1,host=3.3.3.3,port=9004,server,nowait
26
+-chardev socket,id=compare0,host=3.3.3.3,port=9001,server,nowait
27
+-chardev socket,id=compare0-0,host=3.3.3.3,port=9001
28
+-chardev socket,id=compare_out,host=3.3.3.3,port=9005,server,nowait
29
+-chardev socket,id=compare_out0,host=3.3.3.3,port=9005
30
+-object filter-mirror,id=m0,netdev=hn0,queue=tx,outdev=mirror0,vnet_hdr_support
31
+-object filter-redirector,netdev=hn0,id=redire0,queue=rx,indev=compare_out,vnet_hdr_support
32
+-object filter-redirector,netdev=hn0,id=redire1,queue=rx,outdev=compare0,vnet_hdr_support
33
+-object colo-compare,id=comp0,primary_in=compare0-0,secondary_in=compare1,outdev=compare_out0,vnet_hdr_support
34
+
35
+Secondary(ip:3.3.3.8):
36
+-netdev tap,id=hn0,vhost=off,script=/etc/qemu-ifup,down script=/etc/qemu-ifdown
37
+-device e1000,netdev=hn0,mac=52:a4:00:12:78:66
38
+-chardev socket,id=red0,host=3.3.3.3,port=9003
39
+-chardev socket,id=red1,host=3.3.3.3,port=9004
40
+-object filter-redirector,id=f1,netdev=hn0,queue=tx,indev=red0,vnet_hdr_support
41
+-object filter-redirector,id=f2,netdev=hn0,queue=rx,outdev=red1,vnet_hdr_support
42
+-object filter-rewriter,id=f3,netdev=hn0,queue=all,vnet_hdr_support
43
44
Note:
45
a.COLO-proxy must work with COLO-frame and Block-replication.
46
--
47
2.7.4
48
49
diff view generated by jsdifflib