1
The following changes since commit 6632f6ff96f0537fc34cdc00c760656fc62e23c5:
1
The following changes since commit 97c81ef4b8e203d9620fd46e7eb77004563e3675:
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 'pull-9p-20230706' of https://github.com/cschoenebeck/qemu into staging (2023-07-06 18:19:42 +0100)
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 da9f7f7769e8e65f6423095e978f9a375e33515c:
10
10
11
virtio-net: fix offload ctrl endian (2017-07-17 20:13:56 +0800)
11
igb: Remove obsolete workaround for Windows (2023-07-07 16:35:12 +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
Akihiko Odaki (2):
17
e1000e: Add ICR clearing by corresponding IMS bit
18
igb: Remove obsolete workaround for Windows
17
19
18
----------------------------------------------------------------
20
Bin Meng (9):
19
Jason Wang (1):
21
hw/net: e1000: Remove the logic of padding short frames in the receive path
20
virtio-net: fix offload ctrl endian
22
hw/net: vmxnet3: Remove the logic of padding short frames in the receive path
23
hw/net: i82596: Remove the logic of padding short frames in the receive path
24
hw/net: ne2000: Remove the logic of padding short frames in the receive path
25
hw/net: pcnet: Remove the logic of padding short frames in the receive path
26
hw/net: rtl8139: Remove the logic of padding short frames in the receive path
27
hw/net: sungem: Remove the logic of padding short frames in the receive path
28
hw/net: sunhme: Remove the logic of padding short frames in the receive path
29
hw/net: ftgmac100: Drop the small packet check in the receive path
21
30
22
Michal Privoznik (1):
31
Laurent Vivier (4):
23
virtion-net: Prefer is_power_of_2()
32
virtio-net: correctly report maximum tx_queue_size value
33
net: socket: prepare to cleanup net_init_socket()
34
net: socket: move fd type checking to its own function
35
net: socket: remove net_init_socket()
24
36
25
Zhang Chen (12):
37
hw/net/e1000.c | 11 +----------
26
net: Add vnet_hdr_len arguments in NetClientState
38
hw/net/e1000e_core.c | 38 +++++++++++++++++++++++++++++++------
27
net/net.c: Add vnet_hdr support in SocketReadState
39
hw/net/ftgmac100.c | 8 --------
28
net/filter-mirror.c: Introduce parameter for filter_send()
40
hw/net/i82596.c | 18 ------------------
29
net/filter-mirror.c: Make filter mirror support vnet support.
41
hw/net/igb_core.c | 7 +------
30
net/filter-mirror.c: Add new option to enable vnet support for filter-redirector
42
hw/net/ne2000.c | 12 ------------
31
net/colo.c: Make vnet_hdr_len as packet property
43
hw/net/pcnet.c | 9 ---------
32
net/colo-compare.c: Introduce parameter for compare_chr_send()
44
hw/net/rtl8139.c | 12 ------------
33
net/colo-compare.c: Make colo-compare support vnet_hdr_len
45
hw/net/sungem.c | 14 --------------
34
net/colo.c: Add vnet packet parse feature in colo-proxy
46
hw/net/sunhme.c | 11 -----------
35
net/colo-compare.c: Add vnet packet's tcp/udp/icmp compare
47
hw/net/trace-events | 1 +
36
net/filter-rewriter.c: Make filter-rewriter support vnet_hdr_len
48
hw/net/virtio-net.c | 4 ++--
37
docs/colo-proxy.txt: Update colo-proxy usage of net driver with vnet_header
49
hw/net/vmxnet3.c | 10 ----------
38
50
net/socket.c | 53 +++++++++++++++++++++++++++-------------------------
39
docs/colo-proxy.txt | 26 ++++++++++++++++
51
14 files changed, 65 insertions(+), 143 deletions(-)
40
hw/net/virtio-net.c | 4 ++-
41
include/net/net.h | 10 ++++--
42
net/colo-compare.c | 84 ++++++++++++++++++++++++++++++++++++++++++---------
43
net/colo.c | 9 +++---
44
net/colo.h | 4 ++-
45
net/filter-mirror.c | 75 +++++++++++++++++++++++++++++++++++++++++----
46
net/filter-rewriter.c | 37 ++++++++++++++++++++++-
47
net/net.c | 37 ++++++++++++++++++++---
48
net/socket.c | 8 ++---
49
qemu-options.hx | 19 ++++++------
50
11 files changed, 265 insertions(+), 48 deletions(-)
51
52
diff view generated by jsdifflib
1
From: Michal Privoznik <mprivozn@redhat.com>
1
From: Laurent Vivier <lvivier@redhat.com>
2
2
3
We have a function that checks if given number is power of two.
3
Maximum value for tx_queue_size depends on the backend type.
4
We should prefer it instead of expanding the check on our own.
4
1024 for vDPA/vhost-user, 256 for all the others.
5
5
6
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
6
The value is returned by virtio_net_max_tx_queue_size() to set the
7
parameter:
8
9
n->net_conf.tx_queue_size = MIN(virtio_net_max_tx_queue_size(n),
10
n->net_conf.tx_queue_size);
11
12
But the parameter checking uses VIRTQUEUE_MAX_SIZE (1024).
13
14
So the parameter is silently ignored and ethtool reports a different
15
value than the one provided by the user.
16
17
... -netdev tap,... -device virtio-net,tx_queue_size=1024
18
19
# ethtool -g enp0s2
20
Ring parameters for enp0s2:
21
Pre-set maximums:
22
RX:        256
23
RX Mini:    n/a
24
RX Jumbo:    n/a
25
TX:        256
26
Current hardware settings:
27
RX:        256
28
RX Mini:    n/a
29
RX Jumbo:    n/a
30
TX:        256
31
32
... -netdev vhost-user,... -device virtio-net,tx_queue_size=2048
33
34
Invalid tx_queue_size (= 2048), must be a power of 2 between 256 and 1024
35
36
With this patch the correct maximum value is checked and displayed.
37
38
For vDPA/vhost-user:
39
40
Invalid tx_queue_size (= 2048), must be a power of 2 between 256 and 1024
41
42
For all the others:
43
44
Invalid tx_queue_size (= 512), must be a power of 2 between 256 and 256
45
46
Fixes: 2eef278b9e63 ("virtio-net: fix tx queue size for !vhost-user")
47
Cc: mst@redhat.com
48
Cc: qemu-stable@nongnu.org
49
Signed-off-by: Laurent Vivier <lvivier@redhat.com>
7
Signed-off-by: Jason Wang <jasowang@redhat.com>
50
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
---
51
---
9
hw/net/virtio-net.c | 2 +-
52
hw/net/virtio-net.c | 4 ++--
10
1 file changed, 1 insertion(+), 1 deletion(-)
53
1 file changed, 2 insertions(+), 2 deletions(-)
11
54
12
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
55
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
13
index XXXXXXX..XXXXXXX 100644
56
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/net/virtio-net.c
57
--- a/hw/net/virtio-net.c
15
+++ b/hw/net/virtio-net.c
58
+++ b/hw/net/virtio-net.c
16
@@ -XXX,XX +XXX,XX @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp)
59
@@ -XXX,XX +XXX,XX @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp)
17
*/
60
}
18
if (n->net_conf.rx_queue_size < VIRTIO_NET_RX_QUEUE_MIN_SIZE ||
61
19
n->net_conf.rx_queue_size > VIRTQUEUE_MAX_SIZE ||
62
if (n->net_conf.tx_queue_size < VIRTIO_NET_TX_QUEUE_MIN_SIZE ||
20
- (n->net_conf.rx_queue_size & (n->net_conf.rx_queue_size - 1))) {
63
- n->net_conf.tx_queue_size > VIRTQUEUE_MAX_SIZE ||
21
+ !is_power_of_2(n->net_conf.rx_queue_size)) {
64
+ n->net_conf.tx_queue_size > virtio_net_max_tx_queue_size(n) ||
22
error_setg(errp, "Invalid rx_queue_size (= %" PRIu16 "), "
65
!is_power_of_2(n->net_conf.tx_queue_size)) {
23
"must be a power of 2 between %d and %d.",
66
error_setg(errp, "Invalid tx_queue_size (= %" PRIu16 "), "
24
n->net_conf.rx_queue_size, VIRTIO_NET_RX_QUEUE_MIN_SIZE,
67
"must be a power of 2 between %d and %d",
68
n->net_conf.tx_queue_size, VIRTIO_NET_TX_QUEUE_MIN_SIZE,
69
- VIRTQUEUE_MAX_SIZE);
70
+ virtio_net_max_tx_queue_size(n));
71
virtio_cleanup(vdev);
72
return;
73
}
25
--
74
--
26
2.7.4
75
2.7.4
27
28
diff view generated by jsdifflib
1
From: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
1
From: Bin Meng <bmeng@tinylab.org>
2
2
3
This patch change the compare_chr_send() parameter from CharBackend to CompareState,
3
Now that we have implemented unified short frames padding in the
4
we can get more information like vnet_hdr(We use it to support packet with vnet_header).
4
QEMU networking codes, remove the same logic in the NIC codes.
5
5
6
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
6
This actually reverts commit 78aeb23eded2d0b765bf9145c71f80025b568acd.
7
8
Signed-off-by: Bin Meng <bmeng@tinylab.org>
7
Signed-off-by: Jason Wang <jasowang@redhat.com>
9
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
---
10
---
9
net/colo-compare.c | 14 +++++++-------
11
hw/net/e1000.c | 11 +----------
10
1 file changed, 7 insertions(+), 7 deletions(-)
12
1 file changed, 1 insertion(+), 10 deletions(-)
11
13
12
diff --git a/net/colo-compare.c b/net/colo-compare.c
14
diff --git a/hw/net/e1000.c b/hw/net/e1000.c
13
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
14
--- a/net/colo-compare.c
16
--- a/hw/net/e1000.c
15
+++ b/net/colo-compare.c
17
+++ b/hw/net/e1000.c
16
@@ -XXX,XX +XXX,XX @@ enum {
18
@@ -XXX,XX +XXX,XX @@ e1000_receive_iov(NetClientState *nc, const struct iovec *iov, int iovcnt)
17
SECONDARY_IN,
19
uint16_t vlan_special = 0;
18
};
20
uint8_t vlan_status = 0;
19
21
uint8_t min_buf[ETH_ZLEN];
20
-static int compare_chr_send(CharBackend *out,
22
- struct iovec min_iov;
21
+static int compare_chr_send(CompareState *s,
23
uint8_t *filter_buf = iov->iov_base;
22
const uint8_t *buf,
24
size_t size = iov_size(iov, iovcnt);
23
uint32_t size);
25
size_t iov_ofs = 0;
24
26
@@ -XXX,XX +XXX,XX @@ e1000_receive_iov(NetClientState *nc, const struct iovec *iov, int iovcnt)
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
}
36
}
37
38
-static int compare_chr_send(CharBackend *out,
39
+static int compare_chr_send(CompareState *s,
40
const uint8_t *buf,
41
uint32_t size)
42
{
43
@@ -XXX,XX +XXX,XX @@ static int compare_chr_send(CharBackend *out,
44
return 0;
27
return 0;
45
}
28
}
46
29
47
- ret = qemu_chr_fe_write_all(out, (uint8_t *)&len, sizeof(len));
30
- /* Pad to minimum Ethernet frame length */
48
+ ret = qemu_chr_fe_write_all(&s->chr_out, (uint8_t *)&len, sizeof(len));
31
- if (size < sizeof(min_buf)) {
49
if (ret != sizeof(len)) {
32
- iov_to_buf(iov, iovcnt, 0, min_buf, size);
50
goto err;
33
- memset(&min_buf[size], 0, sizeof(min_buf) - size);
51
}
34
- min_iov.iov_base = filter_buf = min_buf;
52
35
- min_iov.iov_len = size = sizeof(min_buf);
53
- ret = qemu_chr_fe_write_all(out, (uint8_t *)buf, size);
36
- iovcnt = 1;
54
+ ret = qemu_chr_fe_write_all(&s->chr_out, (uint8_t *)buf, size);
37
- iov = &min_iov;
55
if (ret != size) {
38
- } else if (iov->iov_len < MAXIMUM_ETHERNET_HDR_LEN) {
56
goto err;
39
+ if (iov->iov_len < MAXIMUM_ETHERNET_HDR_LEN) {
57
}
40
/* This is very unlikely, but may happen. */
58
@@ -XXX,XX +XXX,XX @@ static void compare_pri_rs_finalize(SocketReadState *pri_rs)
41
iov_to_buf(iov, iovcnt, 0, min_buf, MAXIMUM_ETHERNET_HDR_LEN);
59
42
filter_buf = min_buf;
60
if (packet_enqueue(s, PRIMARY_IN)) {
61
trace_colo_compare_main("primary: unsupported packet in");
62
- compare_chr_send(&s->chr_out, pri_rs->buf, pri_rs->packet_len);
63
+ compare_chr_send(s, pri_rs->buf, pri_rs->packet_len);
64
} else {
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
--
43
--
77
2.7.4
44
2.7.4
78
79
diff view generated by jsdifflib
1
Spec said offloads should be le64, so use virtio_ldq_p() to guarantee
1
From: Bin Meng <bmeng@tinylab.org>
2
valid endian.
3
2
4
Fixes: 644c98587d4c ("virtio-net: dynamic network offloads configuration")
3
Now that we have implemented unified short frames padding in the
5
Cc: qemu-stable@nongnu.org
4
QEMU networking codes, remove the same logic in the NIC codes.
6
Cc: Dmitry Fleytman <dfleytma@redhat.com>
5
6
This actually reverts commit 40a87c6c9b11ef9c14e0301f76abf0eb2582f08e.
7
8
Signed-off-by: Bin Meng <bmeng@tinylab.org>
7
Signed-off-by: Jason Wang <jasowang@redhat.com>
9
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
---
10
---
9
hw/net/virtio-net.c | 2 ++
11
hw/net/vmxnet3.c | 10 ----------
10
1 file changed, 2 insertions(+)
12
1 file changed, 10 deletions(-)
11
13
12
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
14
diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c
13
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/net/virtio-net.c
16
--- a/hw/net/vmxnet3.c
15
+++ b/hw/net/virtio-net.c
17
+++ b/hw/net/vmxnet3.c
16
@@ -XXX,XX +XXX,XX @@ static int virtio_net_handle_offloads(VirtIONet *n, uint8_t cmd,
18
@@ -XXX,XX +XXX,XX @@
17
if (cmd == VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET) {
19
18
uint64_t supported_offloads;
20
#define PCI_DEVICE_ID_VMWARE_VMXNET3_REVISION 0x1
19
21
#define VMXNET3_MSIX_BAR_SIZE 0x2000
20
+ offloads = virtio_ldq_p(vdev, &offloads);
22
-#define MIN_BUF_SIZE 60
21
+
23
22
if (!n->has_vnet_hdr) {
24
/* Compatibility flags for migration */
23
return VIRTIO_NET_ERR;
25
#define VMXNET3_COMPAT_FLAG_OLD_MSI_OFFSETS_BIT 0
24
}
26
@@ -XXX,XX +XXX,XX @@ vmxnet3_receive(NetClientState *nc, const uint8_t *buf, size_t size)
27
{
28
VMXNET3State *s = qemu_get_nic_opaque(nc);
29
size_t bytes_indicated;
30
- uint8_t min_buf[MIN_BUF_SIZE];
31
32
if (!vmxnet3_can_receive(nc)) {
33
VMW_PKPRN("Cannot receive now");
34
@@ -XXX,XX +XXX,XX @@ vmxnet3_receive(NetClientState *nc, const uint8_t *buf, size_t size)
35
size -= sizeof(struct virtio_net_hdr);
36
}
37
38
- /* Pad to minimum Ethernet frame length */
39
- if (size < sizeof(min_buf)) {
40
- memcpy(min_buf, buf, size);
41
- memset(&min_buf[size], 0, sizeof(min_buf) - size);
42
- buf = min_buf;
43
- size = sizeof(min_buf);
44
- }
45
-
46
net_rx_pkt_set_packet_type(s->rx_pkt,
47
get_eth_packet_type(PKT_GET_ETH_HDR(buf)));
48
25
--
49
--
26
2.7.4
50
2.7.4
27
28
diff view generated by jsdifflib
1
From: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
1
From: Bin Meng <bmeng@tinylab.org>
2
2
3
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
3
Now that we have implemented unified short frames padding in the
4
QEMU networking codes, remove the same logic in the NIC codes.
5
6
Signed-off-by: Bin Meng <bmeng@tinylab.org>
4
Signed-off-by: Jason Wang <jasowang@redhat.com>
7
Signed-off-by: Jason Wang <jasowang@redhat.com>
5
---
8
---
6
docs/colo-proxy.txt | 26 ++++++++++++++++++++++++++
9
hw/net/i82596.c | 18 ------------------
7
1 file changed, 26 insertions(+)
10
1 file changed, 18 deletions(-)
8
11
9
diff --git a/docs/colo-proxy.txt b/docs/colo-proxy.txt
12
diff --git a/hw/net/i82596.c b/hw/net/i82596.c
10
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
11
--- a/docs/colo-proxy.txt
14
--- a/hw/net/i82596.c
12
+++ b/docs/colo-proxy.txt
15
+++ b/hw/net/i82596.c
13
@@ -XXX,XX +XXX,XX @@ Secondary(ip:3.3.3.8):
16
@@ -XXX,XX +XXX,XX @@ enum commands {
14
-chardev socket,id=red1,host=3.3.3.3,port=9004
17
#define I596_EOF 0x8000
15
-object filter-redirector,id=f1,netdev=hn0,queue=tx,indev=red0
18
#define SIZE_MASK 0x3fff
16
-object filter-redirector,id=f2,netdev=hn0,queue=rx,outdev=red1
19
17
+-object filter-rewriter,id=f3,netdev=hn0,queue=all
20
-#define ETHER_TYPE_LEN 2
18
+
21
-#define VLAN_TCI_LEN 2
19
+If you want to use virtio-net-pci or other driver with vnet_header:
22
-#define VLAN_HLEN (ETHER_TYPE_LEN + VLAN_TCI_LEN)
20
+
23
-
21
+Primary(ip:3.3.3.3):
24
/* various flags in the chip config registers */
22
+-netdev tap,id=hn0,vhost=off,script=/etc/qemu-ifup,downscript=/etc/qemu-ifdown
25
#define I596_PREFETCH (s->config[0] & 0x80)
23
+-device e1000,id=e0,netdev=hn0,mac=52:a4:00:12:78:66
26
#define I596_PROMISC (s->config[8] & 0x01)
24
+-chardev socket,id=mirror0,host=3.3.3.3,port=9003,server,nowait
27
@@ -XXX,XX +XXX,XX @@ bool i82596_can_receive(NetClientState *nc)
25
+-chardev socket,id=compare1,host=3.3.3.3,port=9004,server,nowait
28
return true;
26
+-chardev socket,id=compare0,host=3.3.3.3,port=9001,server,nowait
29
}
27
+-chardev socket,id=compare0-0,host=3.3.3.3,port=9001
30
28
+-chardev socket,id=compare_out,host=3.3.3.3,port=9005,server,nowait
31
-#define MIN_BUF_SIZE 60
29
+-chardev socket,id=compare_out0,host=3.3.3.3,port=9005
32
-
30
+-object filter-mirror,id=m0,netdev=hn0,queue=tx,outdev=mirror0,vnet_hdr_support
33
ssize_t i82596_receive(NetClientState *nc, const uint8_t *buf, size_t sz)
31
+-object filter-redirector,netdev=hn0,id=redire0,queue=rx,indev=compare_out,vnet_hdr_support
34
{
32
+-object filter-redirector,netdev=hn0,id=redire1,queue=rx,outdev=compare0,vnet_hdr_support
35
I82596State *s = qemu_get_nic_opaque(nc);
33
+-object colo-compare,id=comp0,primary_in=compare0-0,secondary_in=compare1,outdev=compare_out0,vnet_hdr_support
36
@@ -XXX,XX +XXX,XX @@ ssize_t i82596_receive(NetClientState *nc, const uint8_t *buf, size_t sz)
34
+
37
size_t bufsz = sz; /* length of data in buf */
35
+Secondary(ip:3.3.3.8):
38
uint32_t crc;
36
+-netdev tap,id=hn0,vhost=off,script=/etc/qemu-ifup,down script=/etc/qemu-ifdown
39
uint8_t *crc_ptr;
37
+-device e1000,netdev=hn0,mac=52:a4:00:12:78:66
40
- uint8_t buf1[MIN_BUF_SIZE + VLAN_HLEN];
38
+-chardev socket,id=red0,host=3.3.3.3,port=9003
41
static const uint8_t broadcast_macaddr[6] = {
39
+-chardev socket,id=red1,host=3.3.3.3,port=9004
42
0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
40
+-object filter-redirector,id=f1,netdev=hn0,queue=tx,indev=red0,vnet_hdr_support
43
41
+-object filter-redirector,id=f2,netdev=hn0,queue=rx,outdev=red1,vnet_hdr_support
44
@@ -XXX,XX +XXX,XX @@ ssize_t i82596_receive(NetClientState *nc, const uint8_t *buf, size_t sz)
42
+-object filter-rewriter,id=f3,netdev=hn0,queue=all,vnet_hdr_support
45
}
43
46
}
44
Note:
47
45
a.COLO-proxy must work with COLO-frame and Block-replication.
48
- /* if too small buffer, then expand it */
49
- if (len < MIN_BUF_SIZE + VLAN_HLEN) {
50
- memcpy(buf1, buf, len);
51
- memset(buf1 + len, 0, MIN_BUF_SIZE + VLAN_HLEN - len);
52
- buf = buf1;
53
- if (len < MIN_BUF_SIZE) {
54
- len = MIN_BUF_SIZE;
55
- }
56
- bufsz = len;
57
- }
58
-
59
/* Calculate the ethernet checksum (4 bytes) */
60
len += 4;
61
crc = cpu_to_be32(crc32(~0, buf, sz));
46
--
62
--
47
2.7.4
63
2.7.4
48
49
diff view generated by jsdifflib
1
From: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
1
From: Bin Meng <bmeng@tinylab.org>
2
2
3
COLO-Proxy just focus on packet payload, so we skip vnet header.
3
Now that we have implemented unified short frames padding in the
4
QEMU networking codes, remove the same logic in the NIC codes.
4
5
5
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
6
Signed-off-by: Bin Meng <bmeng@tinylab.org>
6
Signed-off-by: Jason Wang <jasowang@redhat.com>
7
Signed-off-by: Jason Wang <jasowang@redhat.com>
7
---
8
---
8
net/colo-compare.c | 8 ++++++--
9
hw/net/ne2000.c | 12 ------------
9
1 file changed, 6 insertions(+), 2 deletions(-)
10
1 file changed, 12 deletions(-)
10
11
11
diff --git a/net/colo-compare.c b/net/colo-compare.c
12
diff --git a/hw/net/ne2000.c b/hw/net/ne2000.c
12
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
13
--- a/net/colo-compare.c
14
--- a/hw/net/ne2000.c
14
+++ b/net/colo-compare.c
15
+++ b/hw/net/ne2000.c
15
@@ -XXX,XX +XXX,XX @@ static int colo_packet_compare_common(Packet *ppkt, Packet *spkt, int offset)
16
@@ -XXX,XX +XXX,XX @@ static int ne2000_buffer_full(NE2000State *s)
16
sec_ip_src, sec_ip_dst);
17
return 0;
18
}
19
20
-#define MIN_BUF_SIZE 60
21
-
22
ssize_t ne2000_receive(NetClientState *nc, const uint8_t *buf, size_t size_)
23
{
24
NE2000State *s = qemu_get_nic_opaque(nc);
25
size_t size = size_;
26
uint8_t *p;
27
unsigned int total_len, next, avail, len, index, mcast_idx;
28
- uint8_t buf1[60];
29
static const uint8_t broadcast_macaddr[6] =
30
{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
31
32
@@ -XXX,XX +XXX,XX @@ ssize_t ne2000_receive(NetClientState *nc, const uint8_t *buf, size_t size_)
33
}
17
}
34
}
18
35
19
+ offset = ppkt->vnet_hdr_len + offset;
36
-
20
+
37
- /* if too small buffer, then expand it */
21
if (ppkt->size == spkt->size) {
38
- if (size < MIN_BUF_SIZE) {
22
- return memcmp(ppkt->data + offset, spkt->data + offset,
39
- memcpy(buf1, buf, size);
23
+ return memcmp(ppkt->data + offset,
40
- memset(buf1 + size, 0, MIN_BUF_SIZE - size);
24
+ spkt->data + offset,
41
- buf = buf1;
25
spkt->size - offset);
42
- size = MIN_BUF_SIZE;
26
} else {
43
- }
27
trace_colo_compare_main("Net packet size are not the same");
44
-
28
@@ -XXX,XX +XXX,XX @@ static int colo_packet_compare_tcp(Packet *spkt, Packet *ppkt)
45
index = s->curpag << 8;
29
*/
46
if (index >= NE2000_PMEM_END) {
30
if (ptcp->th_off > 5) {
47
index = s->start;
31
ptrdiff_t tcp_offset;
32
+
33
tcp_offset = ppkt->transport_header - (uint8_t *)ppkt->data
34
- + (ptcp->th_off * 4);
35
+ + (ptcp->th_off * 4) - ppkt->vnet_hdr_len;
36
res = colo_packet_compare_common(ppkt, spkt, tcp_offset);
37
} else if (ptcp->th_sum == stcp->th_sum) {
38
res = colo_packet_compare_common(ppkt, spkt, ETH_HLEN);
39
--
48
--
40
2.7.4
49
2.7.4
41
42
diff view generated by jsdifflib
New patch
1
From: Bin Meng <bmeng@tinylab.org>
1
2
3
Now that we have implemented unified short frames padding in the
4
QEMU networking codes, remove the same logic in the NIC codes.
5
6
Signed-off-by: Bin Meng <bmeng@tinylab.org>
7
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
---
9
hw/net/pcnet.c | 9 ---------
10
1 file changed, 9 deletions(-)
11
12
diff --git a/hw/net/pcnet.c b/hw/net/pcnet.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/net/pcnet.c
15
+++ b/hw/net/pcnet.c
16
@@ -XXX,XX +XXX,XX @@ ssize_t pcnet_receive(NetClientState *nc, const uint8_t *buf, size_t size_)
17
{
18
PCNetState *s = qemu_get_nic_opaque(nc);
19
int is_padr = 0, is_bcast = 0, is_ladr = 0;
20
- uint8_t buf1[60];
21
int remaining;
22
int crc_err = 0;
23
size_t size = size_;
24
@@ -XXX,XX +XXX,XX @@ ssize_t pcnet_receive(NetClientState *nc, const uint8_t *buf, size_t size_)
25
printf("pcnet_receive size=%zu\n", size);
26
#endif
27
28
- /* if too small buffer, then expand it */
29
- if (size < MIN_BUF_SIZE) {
30
- memcpy(buf1, buf, size);
31
- memset(buf1 + size, 0, MIN_BUF_SIZE - size);
32
- buf = buf1;
33
- size = MIN_BUF_SIZE;
34
- }
35
-
36
if (CSR_PROM(s)
37
|| (is_padr=padr_match(s, buf, size))
38
|| (is_bcast=padr_bcast(s, buf, size))
39
--
40
2.7.4
diff view generated by jsdifflib
1
From: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
1
From: Bin Meng <bmeng@tinylab.org>
2
2
3
We add the vnet_hdr_support option for filter-mirror, default is disabled.
3
Now that we have implemented unified short frames padding in the
4
If you use virtio-net-pci or other driver needs vnet_hdr, please enable it.
4
QEMU networking codes, remove the same logic in the NIC codes.
5
You can use it for example:
6
-object filter-mirror,id=m0,netdev=hn0,queue=tx,outdev=mirror0,vnet_hdr_support
7
5
8
If it has vnet_hdr_support flag, we will change the sending packet format from
6
Signed-off-by: Bin Meng <bmeng@tinylab.org>
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>
7
Signed-off-by: Jason Wang <jasowang@redhat.com>
14
---
8
---
15
net/filter-mirror.c | 42 +++++++++++++++++++++++++++++++++++++++++-
9
hw/net/rtl8139.c | 12 ------------
16
qemu-options.hx | 5 ++---
10
1 file changed, 12 deletions(-)
17
2 files changed, 43 insertions(+), 4 deletions(-)
18
11
19
diff --git a/net/filter-mirror.c b/net/filter-mirror.c
12
diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c
20
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
21
--- a/net/filter-mirror.c
14
--- a/hw/net/rtl8139.c
22
+++ b/net/filter-mirror.c
15
+++ b/hw/net/rtl8139.c
23
@@ -XXX,XX +XXX,XX @@ typedef struct MirrorState {
16
@@ -XXX,XX +XXX,XX @@ static ssize_t rtl8139_do_receive(NetClientState *nc, const uint8_t *buf, size_t
24
CharBackend chr_in;
17
25
CharBackend chr_out;
18
uint32_t packet_header = 0;
26
SocketReadState rs;
19
27
+ bool vnet_hdr;
20
- uint8_t buf1[MIN_BUF_SIZE + VLAN_HLEN];
28
} MirrorState;
21
static const uint8_t broadcast_macaddr[6] =
29
22
{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
30
static int filter_send(MirrorState *s,
23
31
const struct iovec *iov,
24
@@ -XXX,XX +XXX,XX @@ static ssize_t rtl8139_do_receive(NetClientState *nc, const uint8_t *buf, size_t
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
}
25
}
64
}
26
}
65
27
66
- net_socket_rs_init(&s->rs, redirector_rs_finalize, false);
28
- /* if too small buffer, then expand it
67
+ net_socket_rs_init(&s->rs, redirector_rs_finalize, s->vnet_hdr);
29
- * Include some tailroom in case a vlan tag is later removed. */
68
30
- if (size < MIN_BUF_SIZE + VLAN_HLEN) {
69
if (s->indev) {
31
- memcpy(buf1, buf, size);
70
chr = qemu_chr_find(s->indev);
32
- memset(buf1 + size, 0, MIN_BUF_SIZE + VLAN_HLEN - size);
71
@@ -XXX,XX +XXX,XX @@ static void filter_mirror_set_outdev(Object *obj,
33
- buf = buf1;
72
}
34
- if (size < MIN_BUF_SIZE) {
73
}
35
- size = MIN_BUF_SIZE;
74
36
- }
75
+static bool filter_mirror_get_vnet_hdr(Object *obj, Error **errp)
37
- }
76
+{
38
-
77
+ MirrorState *s = FILTER_MIRROR(obj);
39
if (rtl8139_cp_receiver_enabled(s))
78
+
40
{
79
+ return s->vnet_hdr;
41
if (!rtl8139_cp_rx_valid(s)) {
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
--
42
--
126
2.7.4
43
2.7.4
127
128
diff view generated by jsdifflib
1
From: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
1
From: Bin Meng <bmeng@tinylab.org>
2
2
3
We add the vnet_hdr_support option for colo-compare, default is disabled.
3
Now that we have implemented unified short frames padding in the
4
If you use virtio-net-pci or other driver needs vnet_hdr, please enable it.
4
QEMU networking codes, remove the same logic in the NIC codes.
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
Signed-off-by: Bin Meng <bmeng@tinylab.org>
9
Add vnet_hdr_len to struct packet and output packet with
10
the vnet_hdr_len.
11
12
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
13
Signed-off-by: Jason Wang <jasowang@redhat.com>
7
Signed-off-by: Jason Wang <jasowang@redhat.com>
14
---
8
---
15
net/colo-compare.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++-------
9
hw/net/sungem.c | 14 --------------
16
qemu-options.hx | 4 ++--
10
1 file changed, 14 deletions(-)
17
2 files changed, 55 insertions(+), 9 deletions(-)
18
11
19
diff --git a/net/colo-compare.c b/net/colo-compare.c
12
diff --git a/hw/net/sungem.c b/hw/net/sungem.c
20
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
21
--- a/net/colo-compare.c
14
--- a/hw/net/sungem.c
22
+++ b/net/colo-compare.c
15
+++ b/hw/net/sungem.c
23
@@ -XXX,XX +XXX,XX @@ typedef struct CompareState {
16
@@ -XXX,XX +XXX,XX @@ static ssize_t sungem_receive(NetClientState *nc, const uint8_t *buf,
24
CharBackend chr_out;
17
PCIDevice *d = PCI_DEVICE(s);
25
SocketReadState pri_rs;
18
uint32_t mac_crc, done, kick, max_fsize;
26
SocketReadState sec_rs;
19
uint32_t fcs_size, ints, rxdma_cfg, rxmac_cfg, csum, coff;
27
+ bool vnet_hdr;
20
- uint8_t smallbuf[60];
28
21
struct gem_rxd desc;
29
/* connection list: the connections belonged to this NIC could be found
22
uint64_t dbase, baddr;
30
* in this list.
23
unsigned int rx_cond;
31
@@ -XXX,XX +XXX,XX @@ enum {
24
@@ -XXX,XX +XXX,XX @@ static ssize_t sungem_receive(NetClientState *nc, const uint8_t *buf,
32
25
return size;
33
static int compare_chr_send(CompareState *s,
34
const uint8_t *buf,
35
- uint32_t size);
36
+ uint32_t size,
37
+ uint32_t vnet_hdr_len);
38
39
static gint seq_sorter(Packet *a, Packet *b, gpointer data)
40
{
41
@@ -XXX,XX +XXX,XX @@ static void colo_compare_connection(void *opaque, void *user_data)
42
}
43
44
if (result) {
45
- ret = compare_chr_send(s, pkt->data, pkt->size);
46
+ ret = compare_chr_send(s,
47
+ pkt->data,
48
+ pkt->size,
49
+ pkt->vnet_hdr_len);
50
if (ret < 0) {
51
error_report("colo_send_primary_packet failed");
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
}
26
}
66
27
67
+ if (s->vnet_hdr) {
28
- /* We don't drop too small frames since we get them in qemu, we pad
68
+ /*
29
- * them instead. We should probably use the min frame size register
69
+ * We send vnet header len make other module(like filter-redirector)
30
- * but I don't want to use a variable size staging buffer and I
70
+ * know how to parse net packet correctly.
31
- * know both MacOS and Linux use the default 64 anyway. We use 60
71
+ */
32
- * here to account for the non-existent FCS.
72
+ len = htonl(vnet_hdr_len);
33
- */
73
+ ret = qemu_chr_fe_write_all(&s->chr_out, (uint8_t *)&len, sizeof(len));
34
- if (size < 60) {
74
+ if (ret != sizeof(len)) {
35
- memcpy(smallbuf, buf, size);
75
+ goto err;
36
- memset(&smallbuf[size], 0, 60 - size);
76
+ }
37
- buf = smallbuf;
77
+ }
38
- size = 60;
78
+
39
- }
79
ret = qemu_chr_fe_write_all(&s->chr_out, (uint8_t *)buf, size);
40
-
80
if (ret != size) {
41
/* Get MAC crc */
81
goto err;
42
mac_crc = net_crc32_le(buf, ETH_ALEN);
82
@@ -XXX,XX +XXX,XX @@ static void compare_set_outdev(Object *obj, const char *value, Error **errp)
83
s->outdev = g_strdup(value);
84
}
85
86
+static bool compare_get_vnet_hdr(Object *obj, Error **errp)
87
+{
88
+ CompareState *s = COLO_COMPARE(obj);
89
+
90
+ return s->vnet_hdr;
91
+}
92
+
93
+static void compare_set_vnet_hdr(Object *obj,
94
+ bool value,
95
+ Error **errp)
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;
118
}
119
120
- net_socket_rs_init(&s->pri_rs, compare_pri_rs_finalize, false);
121
- net_socket_rs_init(&s->sec_rs, compare_sec_rs_finalize, false);
122
+ net_socket_rs_init(&s->pri_rs, compare_pri_rs_finalize, s->vnet_hdr);
123
+ net_socket_rs_init(&s->sec_rs, compare_sec_rs_finalize, s->vnet_hdr);
124
125
g_queue_init(&s->conn_list);
126
127
@@ -XXX,XX +XXX,XX @@ static void colo_flush_packets(void *opaque, void *user_data)
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
}
138
while (!g_queue_is_empty(&conn->secondary_list)) {
139
@@ -XXX,XX +XXX,XX @@ static void colo_compare_class_init(ObjectClass *oc, void *data)
140
141
static void colo_compare_init(Object *obj)
142
{
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
}
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
43
179
--
44
--
180
2.7.4
45
2.7.4
181
182
diff view generated by jsdifflib
1
From: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
1
From: Bin Meng <bmeng@tinylab.org>
2
2
3
We add the vnet_hdr_support option for filter-rewriter, default is disabled.
3
Now that we have implemented unified short frames padding in the
4
If you use virtio-net-pci or other driver needs vnet_hdr, please enable it.
4
QEMU networking codes, remove the same logic in the NIC codes.
5
You can use it for example:
6
-object filter-rewriter,id=rew0,netdev=hn0,queue=all,vnet_hdr_support
7
5
8
We get the vnet_hdr_len from NetClientState that make us
6
Signed-off-by: Bin Meng <bmeng@tinylab.org>
9
parse net packet correctly.
10
11
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
12
Signed-off-by: Jason Wang <jasowang@redhat.com>
7
Signed-off-by: Jason Wang <jasowang@redhat.com>
13
---
8
---
14
net/filter-rewriter.c | 37 ++++++++++++++++++++++++++++++++++++-
9
hw/net/sunhme.c | 11 -----------
15
qemu-options.hx | 4 ++--
10
1 file changed, 11 deletions(-)
16
2 files changed, 38 insertions(+), 3 deletions(-)
17
11
18
diff --git a/net/filter-rewriter.c b/net/filter-rewriter.c
12
diff --git a/hw/net/sunhme.c b/hw/net/sunhme.c
19
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
20
--- a/net/filter-rewriter.c
14
--- a/hw/net/sunhme.c
21
+++ b/net/filter-rewriter.c
15
+++ b/hw/net/sunhme.c
22
@@ -XXX,XX +XXX,XX @@
16
@@ -XXX,XX +XXX,XX @@ static inline void sunhme_set_rx_ring_nr(SunHMEState *s, int i)
23
#include "qemu-common.h"
17
s->erxregs[HME_ERXI_RING >> 2] = ring;
24
#include "qapi/error.h"
25
#include "qapi/qmp/qerror.h"
26
+#include "qemu/error-report.h"
27
#include "qapi-visit.h"
28
#include "qom/object.h"
29
#include "qemu/main-loop.h"
30
@@ -XXX,XX +XXX,XX @@ typedef struct RewriterState {
31
NetQueue *incoming_queue;
32
/* hashtable to save connection */
33
GHashTable *connection_track_table;
34
+ bool vnet_hdr;
35
} RewriterState;
36
37
static void filter_rewriter_flush(NetFilterState *nf)
38
@@ -XXX,XX +XXX,XX @@ static ssize_t colo_rewriter_receive_iov(NetFilterState *nf,
39
ConnectionKey key;
40
Packet *pkt;
41
ssize_t size = iov_size(iov, iovcnt);
42
+ ssize_t vnet_hdr_len = 0;
43
char *buf = g_malloc0(size);
44
45
iov_to_buf(iov, iovcnt, 0, buf, size);
46
- pkt = packet_new(buf, size, 0);
47
+
48
+ if (s->vnet_hdr) {
49
+ vnet_hdr_len = nf->netdev->vnet_hdr_len;
50
+ }
51
+
52
+ pkt = packet_new(buf, size, vnet_hdr_len);
53
g_free(buf);
54
55
/*
56
@@ -XXX,XX +XXX,XX @@ static void colo_rewriter_setup(NetFilterState *nf, Error **errp)
57
s->incoming_queue = qemu_new_net_queue(qemu_netfilter_pass_to_next, nf);
58
}
18
}
59
19
60
+static bool filter_rewriter_get_vnet_hdr(Object *obj, Error **errp)
20
-#define MIN_BUF_SIZE 60
61
+{
21
-
62
+ RewriterState *s = FILTER_COLO_REWRITER(obj);
22
static ssize_t sunhme_receive(NetClientState *nc, const uint8_t *buf,
63
+
23
size_t size)
64
+ return s->vnet_hdr;
65
+}
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
{
24
{
88
NetFilterClass *nfc = NETFILTER_CLASS(oc);
25
@@ -XXX,XX +XXX,XX @@ static ssize_t sunhme_receive(NetClientState *nc, const uint8_t *buf,
89
@@ -XXX,XX +XXX,XX @@ static const TypeInfo colo_rewriter_info = {
26
dma_addr_t rb, addr;
90
.name = TYPE_FILTER_REWRITER,
27
uint32_t intstatus, status, buffer, buffersize, sum;
91
.parent = TYPE_NETFILTER,
28
uint16_t csum;
92
.class_init = colo_rewriter_class_init,
29
- uint8_t buf1[60];
93
+ .instance_init = filter_rewriter_init,
30
int nr, cr, len, rxoffset, csum_offset;
94
.instance_size = sizeof(RewriterState),
31
95
};
32
trace_sunhme_rx_incoming(size);
96
33
@@ -XXX,XX +XXX,XX @@ static ssize_t sunhme_receive(NetClientState *nc, const uint8_t *buf,
97
diff --git a/qemu-options.hx b/qemu-options.hx
34
98
index XXXXXXX..XXXXXXX 100644
35
trace_sunhme_rx_filter_accept();
99
--- a/qemu-options.hx
36
100
+++ b/qemu-options.hx
37
- /* If too small buffer, then expand it */
101
@@ -XXX,XX +XXX,XX @@ Create a filter-redirector we need to differ outdev id from indev id, id can not
38
- if (size < MIN_BUF_SIZE) {
102
be the same. we can just use indev or outdev, but at least one of indev or outdev
39
- memcpy(buf1, buf, size);
103
need to be specified.
40
- memset(buf1 + size, 0, MIN_BUF_SIZE - size);
104
41
- buf = buf1;
105
-@item -object filter-rewriter,id=@var{id},netdev=@var{netdevid}[,queue=@var{all|rx|tx}]
42
- size = MIN_BUF_SIZE;
106
+@item -object filter-rewriter,id=@var{id},netdev=@var{netdevid},queue=@var{all|rx|tx},[vnet_hdr_support]
43
- }
107
44
-
108
Filter-rewriter is a part of COLO project.It will rewrite tcp packet to
45
rb = s->erxregs[HME_ERXI_RING >> 2] & HME_ERXI_RING_ADDR;
109
secondary from primary to keep secondary tcp connection,and rewrite
46
nr = sunhme_get_rx_ring_count(s);
110
tcp packet to primary from secondary make tcp packet can be handled by
47
cr = sunhme_get_rx_ring_nr(s);
111
-client.
112
+client.if it has the vnet_hdr_support flag, we can parse packet with vnet header.
113
114
usage:
115
colo secondary:
116
--
48
--
117
2.7.4
49
2.7.4
118
119
diff view generated by jsdifflib
1
From: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
1
From: Bin Meng <bmeng@tinylab.org>
2
2
3
We can use this property flush and send packet with vnet_hdr_len.
3
Now that we have implemented unified short frames padding in the
4
QEMU networking codes, the small packet check logic in the receive
5
path is no longer needed.
4
6
5
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
7
Suggested-by: Cédric Le Goater <clg@kaod.org>
8
Reviewed-by: Cédric Le Goater <clg@kaod.org>
9
Signed-off-by: Bin Meng <bmeng@tinylab.org>
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/ftgmac100.c | 8 --------
9
net/colo.c | 3 ++-
13
1 file changed, 8 deletions(-)
10
net/colo.h | 4 +++-
11
net/filter-rewriter.c | 2 +-
12
4 files changed, 12 insertions(+), 5 deletions(-)
13
14
14
diff --git a/net/colo-compare.c b/net/colo-compare.c
15
diff --git a/hw/net/ftgmac100.c b/hw/net/ftgmac100.c
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/net/colo-compare.c
17
--- a/hw/net/ftgmac100.c
17
+++ b/net/colo-compare.c
18
+++ b/hw/net/ftgmac100.c
18
@@ -XXX,XX +XXX,XX @@ static int packet_enqueue(CompareState *s, int mode)
19
@@ -XXX,XX +XXX,XX @@ static ssize_t ftgmac100_receive(NetClientState *nc, const uint8_t *buf,
19
Connection *conn;
20
return -1;
20
21
if (mode == PRIMARY_IN) {
22
- pkt = packet_new(s->pri_rs.buf, s->pri_rs.packet_len);
23
+ pkt = packet_new(s->pri_rs.buf,
24
+ s->pri_rs.packet_len,
25
+ s->pri_rs.vnet_hdr_len);
26
} else {
27
- pkt = packet_new(s->sec_rs.buf, s->sec_rs.packet_len);
28
+ pkt = packet_new(s->sec_rs.buf,
29
+ s->sec_rs.packet_len,
30
+ s->sec_rs.vnet_hdr_len);
31
}
21
}
32
22
33
if (parse_packet_early(pkt)) {
23
- /* TODO : Pad to minimum Ethernet frame length */
34
diff --git a/net/colo.c b/net/colo.c
24
- /* handle small packets. */
35
index XXXXXXX..XXXXXXX 100644
25
- if (size < 10) {
36
--- a/net/colo.c
26
- qemu_log_mask(LOG_GUEST_ERROR, "%s: dropped frame of %zd bytes\n",
37
+++ b/net/colo.c
27
- __func__, size);
38
@@ -XXX,XX +XXX,XX @@ void connection_destroy(void *opaque)
28
- return size;
39
g_slice_free(Connection, conn);
29
- }
40
}
30
-
41
31
if (!ftgmac100_filter(s, buf, size)) {
42
-Packet *packet_new(const void *data, int size)
32
return size;
43
+Packet *packet_new(const void *data, int size, int vnet_hdr_len)
33
}
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
--
34
--
90
2.7.4
35
2.7.4
91
36
92
37
diff view generated by jsdifflib
1
From: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
1
From: Laurent Vivier <lvivier@redhat.com>
2
2
3
Make colo-compare and filter-rewriter can parse vnet packet.
3
Use directly net_socket_fd_init_stream() and net_socket_fd_init_dgram()
4
when the socket type is already known.
4
5
5
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
6
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
7
Signed-off-by: Laurent Vivier <lvivier@redhat.com>
6
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
Signed-off-by: Jason Wang <jasowang@redhat.com>
7
---
9
---
8
net/colo.c | 6 +++---
10
net/socket.c | 6 +++---
9
1 file changed, 3 insertions(+), 3 deletions(-)
11
1 file changed, 3 insertions(+), 3 deletions(-)
10
12
11
diff --git a/net/colo.c b/net/colo.c
13
diff --git a/net/socket.c b/net/socket.c
12
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
13
--- a/net/colo.c
15
--- a/net/socket.c
14
+++ b/net/colo.c
16
+++ b/net/socket.c
15
@@ -XXX,XX +XXX,XX @@ int parse_packet_early(Packet *pkt)
17
@@ -XXX,XX +XXX,XX @@ static int net_socket_connect_init(NetClientState *peer,
16
{
18
break;
17
int network_length;
19
}
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
}
20
}
29
@@ -XXX,XX +XXX,XX @@ int parse_packet_early(Packet *pkt)
21
- s = net_socket_fd_init(peer, model, name, fd, connected, NULL, errp);
22
+ s = net_socket_fd_init_stream(peer, model, name, fd, connected);
23
if (!s) {
24
return -1;
30
}
25
}
31
26
@@ -XXX,XX +XXX,XX @@ static int net_socket_mcast_init(NetClientState *peer,
32
network_length = pkt->ip->ip_hl * 4;
27
return -1;
33
- if (pkt->size < l2hdr_len + network_length) {
28
}
34
+ if (pkt->size < l2hdr_len + network_length + pkt->vnet_hdr_len) {
29
35
trace_colo_proxy_main("pkt->size < network_header + network_length");
30
- s = net_socket_fd_init(peer, model, name, fd, 0, NULL, errp);
36
return 1;
31
+ s = net_socket_fd_init_dgram(peer, model, name, fd, 0, NULL, errp);
32
if (!s) {
33
return -1;
34
}
35
@@ -XXX,XX +XXX,XX @@ static int net_socket_udp_init(NetClientState *peer,
36
}
37
qemu_socket_set_nonblock(fd);
38
39
- s = net_socket_fd_init(peer, model, name, fd, 0, NULL, errp);
40
+ s = net_socket_fd_init_dgram(peer, model, name, fd, 0, NULL, errp);
41
if (!s) {
42
return -1;
37
}
43
}
38
--
44
--
39
2.7.4
45
2.7.4
40
41
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-redirector, default is disabled.
3
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
4
If you use virtio-net-pci net driver or other driver needs vnet_hdr, please enable it.
4
Signed-off-by: Laurent Vivier <lvivier@redhat.com>
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>
5
Signed-off-by: Jason Wang <jasowang@redhat.com>
12
---
6
---
13
net/filter-mirror.c | 23 +++++++++++++++++++++++
7
net/socket.c | 28 ++++++++++++++++++++--------
14
qemu-options.hx | 6 +++---
8
1 file changed, 20 insertions(+), 8 deletions(-)
15
2 files changed, 26 insertions(+), 3 deletions(-)
16
9
17
diff --git a/net/filter-mirror.c b/net/filter-mirror.c
10
diff --git a/net/socket.c b/net/socket.c
18
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
19
--- a/net/filter-mirror.c
12
--- a/net/socket.c
20
+++ b/net/filter-mirror.c
13
+++ b/net/socket.c
21
@@ -XXX,XX +XXX,XX @@ static void filter_redirector_set_outdev(Object *obj,
14
@@ -XXX,XX +XXX,XX @@ static NetSocketState *net_socket_fd_init_stream(NetClientState *peer,
22
s->outdev = g_strdup(value);
15
return s;
23
}
16
}
24
17
25
+static bool filter_redirector_get_vnet_hdr(Object *obj, Error **errp)
18
+static int net_socket_fd_check(int fd, Error **errp)
26
+{
19
+{
27
+ MirrorState *s = FILTER_REDIRECTOR(obj);
20
+ int so_type, optlen = sizeof(so_type);
28
+
21
+
29
+ return s->vnet_hdr;
22
+ if (getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&so_type,
23
+ (socklen_t *)&optlen) < 0) {
24
+ error_setg(errp, "can't get socket option SO_TYPE");
25
+ return -1;
26
+ }
27
+ if (so_type != SOCK_DGRAM && so_type != SOCK_STREAM) {
28
+ error_setg(errp, "socket type=%d for fd=%d must be either"
29
+ " SOCK_DGRAM or SOCK_STREAM", so_type, fd);
30
+ return -1;
31
+ }
32
+ return so_type;
30
+}
33
+}
31
+
34
+
32
+static void filter_redirector_set_vnet_hdr(Object *obj,
35
static NetSocketState *net_socket_fd_init(NetClientState *peer,
33
+ bool value,
36
const char *model, const char *name,
34
+ Error **errp)
37
int fd, int is_connected,
35
+{
38
const char *mc, Error **errp)
36
+ MirrorState *s = FILTER_REDIRECTOR(obj);
37
+
38
+ s->vnet_hdr = value;
39
+}
40
+
41
static void filter_mirror_init(Object *obj)
42
{
39
{
43
MirrorState *s = FILTER_MIRROR(obj);
40
- int so_type = -1, optlen=sizeof(so_type);
44
@@ -XXX,XX +XXX,XX @@ static void filter_mirror_init(Object *obj)
41
+ int so_type;
45
42
46
static void filter_redirector_init(Object *obj)
43
- if(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&so_type,
47
{
44
- (socklen_t *)&optlen)< 0) {
48
+ MirrorState *s = FILTER_REDIRECTOR(obj);
45
- error_setg(errp, "can't get socket option SO_TYPE");
49
+
46
+ so_type = net_socket_fd_check(fd, errp);
50
object_property_add_str(obj, "indev", filter_redirector_get_indev,
47
+ if (so_type < 0) {
51
filter_redirector_set_indev, NULL);
48
close(fd);
52
object_property_add_str(obj, "outdev", filter_redirector_get_outdev,
49
return NULL;
53
filter_redirector_set_outdev, NULL);
50
}
54
+
51
@@ -XXX,XX +XXX,XX @@ static NetSocketState *net_socket_fd_init(NetClientState *peer,
55
+ s->vnet_hdr = false;
52
mc, errp);
56
+ object_property_add_bool(obj, "vnet_hdr_support",
53
case SOCK_STREAM:
57
+ filter_redirector_get_vnet_hdr,
54
return net_socket_fd_init_stream(peer, model, name, fd, is_connected);
58
+ filter_redirector_set_vnet_hdr, NULL);
55
- default:
56
- error_setg(errp, "socket type=%d for fd=%d must be either"
57
- " SOCK_DGRAM or SOCK_STREAM", so_type, fd);
58
- close(fd);
59
}
60
return NULL;
59
}
61
}
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
--
62
--
82
2.7.4
63
2.7.4
83
84
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 a flag to decide whether net_fill_rstate() need read
3
Move the file descriptor type checking before doing anything with it.
4
the vnet_hdr_len or not.
4
If it's not usable, don't close it as it could be in use by another
5
part of QEMU, only fail and report an error.
5
6
6
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
7
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
7
Suggested-by: Jason Wang <jasowang@redhat.com>
8
Signed-off-by: Laurent Vivier <lvivier@redhat.com>
8
Signed-off-by: Jason Wang <jasowang@redhat.com>
9
Signed-off-by: Jason Wang <jasowang@redhat.com>
9
---
10
---
10
include/net/net.h | 9 +++++++--
11
net/socket.c | 43 +++++++++++++++++--------------------------
11
net/colo-compare.c | 4 ++--
12
1 file changed, 17 insertions(+), 26 deletions(-)
12
net/filter-mirror.c | 2 +-
13
net/net.c | 36 ++++++++++++++++++++++++++++++++----
14
net/socket.c | 8 ++++----
15
5 files changed, 46 insertions(+), 13 deletions(-)
16
13
17
diff --git a/include/net/net.h b/include/net/net.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/include/net/net.h
20
+++ b/include/net/net.h
21
@@ -XXX,XX +XXX,XX @@ typedef struct NICState {
22
} NICState;
23
24
struct SocketReadState {
25
- int state; /* 0 = getting length, 1 = getting data */
26
+ /* 0 = getting length, 1 = getting vnet header length, 2 = getting data */
27
+ int state;
28
+ /* This flag decide whether to read the vnet_hdr_len field */
29
+ bool vnet_hdr;
30
uint32_t index;
31
uint32_t packet_len;
32
+ uint32_t vnet_hdr_len;
33
uint8_t buf[NET_BUFSIZE];
34
SocketReadStateFinalize *finalize;
35
};
36
@@ -XXX,XX +XXX,XX @@ ssize_t qemu_deliver_packet_iov(NetClientState *sender,
37
void print_net_client(Monitor *mon, NetClientState *nc);
38
void hmp_info_network(Monitor *mon, const QDict *qdict);
39
void net_socket_rs_init(SocketReadState *rs,
40
- SocketReadStateFinalize *finalize);
41
+ SocketReadStateFinalize *finalize,
42
+ bool vnet_hdr);
43
44
/* NIC info */
45
46
diff --git a/net/colo-compare.c b/net/colo-compare.c
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
75
index XXXXXXX..XXXXXXX 100644
76
--- a/net/net.c
77
+++ b/net/net.c
78
@@ -XXX,XX +XXX,XX @@ QemuOptsList qemu_net_opts = {
79
};
80
81
void net_socket_rs_init(SocketReadState *rs,
82
- SocketReadStateFinalize *finalize)
83
+ SocketReadStateFinalize *finalize,
84
+ bool vnet_hdr)
85
{
86
rs->state = 0;
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
14
diff --git a/net/socket.c b/net/socket.c
143
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
144
--- a/net/socket.c
16
--- a/net/socket.c
145
+++ b/net/socket.c
17
+++ b/net/socket.c
146
@@ -XXX,XX +XXX,XX @@ static void net_socket_send(void *opaque)
18
@@ -XXX,XX +XXX,XX @@ static int net_socket_fd_check(int fd, Error **errp)
147
closesocket(s->fd);
19
return so_type;
148
20
}
149
s->fd = -1;
21
150
- net_socket_rs_init(&s->rs, net_socket_rs_finalize);
22
-static NetSocketState *net_socket_fd_init(NetClientState *peer,
151
+ net_socket_rs_init(&s->rs, net_socket_rs_finalize, false);
23
- const char *model, const char *name,
152
s->nc.link_down = true;
24
- int fd, int is_connected,
153
memset(s->nc.info_str, 0, sizeof(s->nc.info_str));
25
- const char *mc, Error **errp)
154
26
-{
155
@@ -XXX,XX +XXX,XX @@ static NetSocketState *net_socket_fd_init_dgram(NetClientState *peer,
27
- int so_type;
156
s->fd = fd;
28
-
157
s->listen_fd = -1;
29
- so_type = net_socket_fd_check(fd, errp);
158
s->send_fn = net_socket_send_dgram;
30
- if (so_type < 0) {
159
- net_socket_rs_init(&s->rs, net_socket_rs_finalize);
31
- close(fd);
160
+ net_socket_rs_init(&s->rs, net_socket_rs_finalize, false);
32
- return NULL;
161
net_socket_read_poll(s, true);
33
- }
162
34
- switch(so_type) {
163
/* mcast: save bound address as dst */
35
- case SOCK_DGRAM:
164
@@ -XXX,XX +XXX,XX @@ static NetSocketState *net_socket_fd_init_stream(NetClientState *peer,
36
- return net_socket_fd_init_dgram(peer, model, name, fd, is_connected,
165
37
- mc, errp);
166
s->fd = fd;
38
- case SOCK_STREAM:
167
s->listen_fd = -1;
39
- return net_socket_fd_init_stream(peer, model, name, fd, is_connected);
168
- net_socket_rs_init(&s->rs, net_socket_rs_finalize);
40
- }
169
+ net_socket_rs_init(&s->rs, net_socket_rs_finalize, false);
41
- return NULL;
170
42
-}
171
/* Disable Nagle algorithm on TCP sockets to reduce latency */
43
-
172
socket_set_nodelay(fd);
44
static void net_socket_accept(void *opaque)
173
@@ -XXX,XX +XXX,XX @@ static int net_socket_listen_init(NetClientState *peer,
45
{
174
s->fd = -1;
46
NetSocketState *s = opaque;
175
s->listen_fd = fd;
47
@@ -XXX,XX +XXX,XX @@ int net_init_socket(const Netdev *netdev, const char *name,
176
s->nc.link_down = true;
48
}
177
- net_socket_rs_init(&s->rs, net_socket_rs_finalize);
49
178
+ net_socket_rs_init(&s->rs, net_socket_rs_finalize, false);
50
if (sock->fd) {
179
51
- int fd, ret;
180
qemu_set_fd_handler(s->listen_fd, net_socket_accept, NULL, s);
52
+ int fd, ret, so_type;
181
return 0;
53
54
fd = monitor_fd_param(monitor_cur(), sock->fd, errp);
55
if (fd == -1) {
56
return -1;
57
}
58
+ so_type = net_socket_fd_check(fd, errp);
59
+ if (so_type < 0) {
60
+ return -1;
61
+ }
62
ret = qemu_socket_try_set_nonblock(fd);
63
if (ret < 0) {
64
error_setg_errno(errp, -ret, "%s: Can't use file descriptor %d",
65
name, fd);
66
return -1;
67
}
68
- if (!net_socket_fd_init(peer, "socket", name, fd, 1, sock->mcast,
69
- errp)) {
70
- return -1;
71
+ switch (so_type) {
72
+ case SOCK_DGRAM:
73
+ if (!net_socket_fd_init_dgram(peer, "socket", name, fd, 1,
74
+ sock->mcast, errp)) {
75
+ return -1;
76
+ }
77
+ break;
78
+ case SOCK_STREAM:
79
+ if (!net_socket_fd_init_stream(peer, "socket", name, fd, 1)) {
80
+ return -1;
81
+ }
82
+ break;
83
}
84
return 0;
85
}
182
--
86
--
183
2.7.4
87
2.7.4
184
185
diff view generated by jsdifflib
1
From: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
2
2
3
This patch change the filter_send() parameter from CharBackend to MirrorState,
3
The datasheet does not say what happens when interrupt was asserted
4
we can get more information like vnet_hdr(We use it to support packet with vnet_header).
4
(ICR.INT_ASSERT=1) and auto mask is *not* active.
5
However, section of 13.3.27 the PCIe* GbE Controllers Open Source
6
Software Developer’s Manual, which were written for older devices,
7
namely 631xESB/632xESB, 82563EB/82564EB, 82571EB/82572EI &
8
82573E/82573V/82573L, does say:
9
> If IMS = 0b, then the ICR register is always clear-on-read. If IMS is
10
> not 0b, but some ICR bit is set where the corresponding IMS bit is not
11
> set, then a read does not clear the ICR register. For example, if
12
> IMS = 10101010b and ICR = 01010101b, then a read to the ICR register
13
> does not clear it. If IMS = 10101010b and ICR = 0101011b, then a read
14
> to the ICR register clears it entirely (ICR.INT_ASSERTED = 1b).
5
15
6
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
16
Linux does no longer activate auto mask since commit
17
0a8047ac68e50e4ccbadcfc6b6b070805b976885 and the real hardware clears
18
ICR even in such a case so we also should do so.
19
20
Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=1707441
21
Signed-off-by: Andrew Melnychenko <andrew@daynix.com>
22
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
7
Signed-off-by: Jason Wang <jasowang@redhat.com>
23
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
---
24
---
9
net/filter-mirror.c | 10 +++++-----
25
hw/net/e1000e_core.c | 38 ++++++++++++++++++++++++++++++++------
10
1 file changed, 5 insertions(+), 5 deletions(-)
26
hw/net/trace-events | 1 +
27
2 files changed, 33 insertions(+), 6 deletions(-)
11
28
12
diff --git a/net/filter-mirror.c b/net/filter-mirror.c
29
diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c
13
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
14
--- a/net/filter-mirror.c
31
--- a/hw/net/e1000e_core.c
15
+++ b/net/filter-mirror.c
32
+++ b/hw/net/e1000e_core.c
16
@@ -XXX,XX +XXX,XX @@ typedef struct MirrorState {
33
@@ -XXX,XX +XXX,XX @@ e1000e_mac_icr_read(E1000ECore *core, int index)
17
SocketReadState rs;
34
e1000e_lower_interrupts(core, ICR, 0xffffffff);
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
}
35
}
27
36
28
len = htonl(size);
37
- if ((core->mac[ICR] & E1000_ICR_ASSERTED) &&
29
- ret = qemu_chr_fe_write_all(chr_out, (uint8_t *)&len, sizeof(len));
38
- (core->mac[CTRL_EXT] & E1000_CTRL_EXT_IAME)) {
30
+ ret = qemu_chr_fe_write_all(&s->chr_out, (uint8_t *)&len, sizeof(len));
39
- trace_e1000e_irq_icr_clear_iame();
31
if (ret != sizeof(len)) {
40
- e1000e_lower_interrupts(core, ICR, 0xffffffff);
32
goto err;
41
- trace_e1000e_irq_icr_process_iame();
42
- e1000e_lower_interrupts(core, IMS, core->mac[IAM]);
43
+ if (core->mac[ICR] & E1000_ICR_ASSERTED) {
44
+ if (core->mac[CTRL_EXT] & E1000_CTRL_EXT_IAME) {
45
+ trace_e1000e_irq_icr_clear_iame();
46
+ e1000e_lower_interrupts(core, ICR, 0xffffffff);
47
+ trace_e1000e_irq_icr_process_iame();
48
+ e1000e_lower_interrupts(core, IMS, core->mac[IAM]);
49
+ }
50
+
51
+ /*
52
+ * The datasheet does not say what happens when interrupt was asserted
53
+ * (ICR.INT_ASSERT=1) and auto mask is *not* active.
54
+ * However, section of 13.3.27 the PCIe* GbE Controllers Open Source
55
+ * Software Developer’s Manual, which were written for older devices,
56
+ * namely 631xESB/632xESB, 82563EB/82564EB, 82571EB/82572EI &
57
+ * 82573E/82573V/82573L, does say:
58
+ * > If IMS = 0b, then the ICR register is always clear-on-read. If IMS
59
+ * > is not 0b, but some ICR bit is set where the corresponding IMS bit
60
+ * > is not set, then a read does not clear the ICR register. For
61
+ * > example, if IMS = 10101010b and ICR = 01010101b, then a read to the
62
+ * > ICR register does not clear it. If IMS = 10101010b and
63
+ * > ICR = 0101011b, then a read to the ICR register clears it entirely
64
+ * > (ICR.INT_ASSERTED = 1b).
65
+ *
66
+ * Linux does no longer activate auto mask since commit
67
+ * 0a8047ac68e50e4ccbadcfc6b6b070805b976885 and the real hardware
68
+ * clears ICR even in such a case so we also should do so.
69
+ */
70
+ if (core->mac[ICR] & core->mac[IMS]) {
71
+ trace_e1000e_irq_icr_clear_icr_bit_ims(core->mac[ICR],
72
+ core->mac[IMS]);
73
+ e1000e_lower_interrupts(core, ICR, 0xffffffff);
74
+ }
33
}
75
}
34
76
35
buf = g_malloc(size);
77
return ret;
36
iov_to_buf(iov, iovcnt, 0, buf, size);
78
diff --git a/hw/net/trace-events b/hw/net/trace-events
37
- ret = qemu_chr_fe_write_all(chr_out, (uint8_t *)buf, size);
79
index XXXXXXX..XXXXXXX 100644
38
+ ret = qemu_chr_fe_write_all(&s->chr_out, (uint8_t *)buf, size);
80
--- a/hw/net/trace-events
39
g_free(buf);
81
+++ b/hw/net/trace-events
40
if (ret != size) {
82
@@ -XXX,XX +XXX,XX @@ e1000e_irq_read_ims(uint32_t ims) "Current IMS: 0x%x"
41
goto err;
83
e1000e_irq_icr_clear_nonmsix_icr_read(void) "Clearing ICR on read due to non MSI-X int"
42
@@ -XXX,XX +XXX,XX @@ static ssize_t filter_mirror_receive_iov(NetFilterState *nf,
84
e1000e_irq_icr_clear_zero_ims(void) "Clearing ICR on read due to zero IMS"
43
MirrorState *s = FILTER_MIRROR(nf);
85
e1000e_irq_icr_clear_iame(void) "Clearing ICR on read due to IAME"
44
int ret;
86
+e1000e_irq_icr_clear_icr_bit_ims(uint32_t icr, uint32_t ims) "Clearing ICR on read due corresponding IMS bit: 0x%x & 0x%x"
45
87
e1000e_irq_iam_clear_eiame(uint32_t iam, uint32_t cause) "Clearing IMS due to EIAME, IAM: 0x%X, cause: 0x%X"
46
- ret = filter_send(&s->chr_out, iov, iovcnt);
88
e1000e_irq_icr_clear_eiac(uint32_t icr, uint32_t eiac) "Clearing ICR bits due to EIAC, ICR: 0x%X, EIAC: 0x%X"
47
+ ret = filter_send(s, iov, iovcnt);
89
e1000e_irq_ims_clear_set_imc(uint32_t val) "Clearing IMS bits due to IMC write 0x%x"
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
--
90
--
61
2.7.4
91
2.7.4
62
92
63
93
diff view generated by jsdifflib
1
From: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
2
2
3
Add vnet_hdr_len arguments in NetClientState
3
I confirmed it works with Windows even without this workaround. It is
4
that make other module get real vnet_hdr_len easily.
4
likely to be a mistake so remove it.
5
5
6
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
6
Fixes: 3a977deebe ("Intrdocue igb device emulation")
7
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
7
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
---
9
---
9
include/net/net.h | 1 +
10
hw/net/igb_core.c | 7 +------
10
net/net.c | 1 +
11
1 file changed, 1 insertion(+), 6 deletions(-)
11
2 files changed, 2 insertions(+)
12
12
13
diff --git a/include/net/net.h b/include/net/net.h
13
diff --git a/hw/net/igb_core.c b/hw/net/igb_core.c
14
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
15
--- a/include/net/net.h
15
--- a/hw/net/igb_core.c
16
+++ b/include/net/net.h
16
+++ b/hw/net/igb_core.c
17
@@ -XXX,XX +XXX,XX @@ struct NetClientState {
17
@@ -XXX,XX +XXX,XX @@ static uint32_t igb_get_status(IGBCore *core, int index)
18
unsigned int queue_index;
18
res |= E1000_STATUS_IOV_MODE;
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
26
index XXXXXXX..XXXXXXX 100644
27
--- a/net/net.c
28
+++ b/net/net.c
29
@@ -XXX,XX +XXX,XX @@ void qemu_set_vnet_hdr_len(NetClientState *nc, int len)
30
return;
31
}
19
}
32
20
33
+ nc->vnet_hdr_len = len;
21
- /*
34
nc->info->set_vnet_hdr_len(nc, len);
22
- * Windows driver 12.18.9.23 resets if E1000_STATUS_GIO_MASTER_ENABLE is
35
}
23
- * left set after E1000_CTRL_LRST is set.
24
- */
25
- if (!(core->mac[CTRL] & E1000_CTRL_GIO_MASTER_DISABLE) &&
26
- !(core->mac[CTRL] & E1000_CTRL_LRST)) {
27
+ if (!(core->mac[CTRL] & E1000_CTRL_GIO_MASTER_DISABLE)) {
28
res |= E1000_STATUS_GIO_MASTER_ENABLE;
29
}
36
30
37
--
31
--
38
2.7.4
32
2.7.4
39
40
diff view generated by jsdifflib