1
The following changes since commit 6632f6ff96f0537fc34cdc00c760656fc62e23c5:
1
The following changes since commit 2a95551e8b1456aa53ce54fac573df18809340a6:
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 remote-tracking branch 'remotes/rth/tags/pull-tcg-20200330' into staging (2020-03-31 11:20:21 +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 1153cf9f5b67fad41ca6f8571e9a26e2c7c70759:
10
10
11
virtio-net: fix offload ctrl endian (2017-07-17 20:13:56 +0800)
11
qtest: add tulip test case (2020-03-31 21:14:35 +0800)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
14
15
- fix virtio-net ctrl offload endian
15
Changes from V1:
16
- vnet header support for variou COLO netfilters and compare thread
16
17
- fix the compiling error
18
- include qtest for tulip OOB
17
19
18
----------------------------------------------------------------
20
----------------------------------------------------------------
19
Jason Wang (1):
21
Andrew Melnychenko (1):
20
virtio-net: fix offload ctrl endian
22
Fixed integer overflow in e1000e
21
23
22
Michal Privoznik (1):
24
Li Qiang (1):
23
virtion-net: Prefer is_power_of_2()
25
qtest: add tulip test case
24
26
25
Zhang Chen (12):
27
Peter Maydell (2):
26
net: Add vnet_hdr_len arguments in NetClientState
28
hw/net/i82596.c: Avoid reading off end of buffer in i82596_receive()
27
net/net.c: Add vnet_hdr support in SocketReadState
29
hw/net/allwinner-sun8i-emac.c: Fix REG_ADDR_HIGH/LOW reads
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
30
39
docs/colo-proxy.txt | 26 ++++++++++++++++
31
Philippe Mathieu-Daudé (7):
40
hw/net/virtio-net.c | 4 ++-
32
hw/net/i82596: Correct command bitmask (CID 1419392)
41
include/net/net.h | 10 ++++--
33
hw/net/e1000e_core: Let e1000e_can_receive() return a boolean
42
net/colo-compare.c | 84 ++++++++++++++++++++++++++++++++++++++++++---------
34
hw/net/smc91c111: Let smc91c111_can_receive() return a boolean
43
net/colo.c | 9 +++---
35
hw/net/rtl8139: Simplify if/else statement
44
net/colo.h | 4 ++-
36
hw/net/rtl8139: Update coding style to make checkpatch.pl happy
45
net/filter-mirror.c | 75 +++++++++++++++++++++++++++++++++++++++++----
37
hw/net: Make NetCanReceive() return a boolean
46
net/filter-rewriter.c | 37 ++++++++++++++++++++++-
38
hw/net/can: Make CanBusClientInfo::can_receive() return a boolean
47
net/net.c | 37 ++++++++++++++++++++---
39
48
net/socket.c | 8 ++---
40
Prasad J Pandit (1):
49
qemu-options.hx | 19 ++++++------
41
net: tulip: check frame size and r/w data length
50
11 files changed, 265 insertions(+), 48 deletions(-)
42
43
Zhang Chen (2):
44
net/colo-compare.c: Expose "compare_timeout" to users
45
net/colo-compare.c: Expose "expired_scan_cycle" to users
46
47
hw/net/allwinner-sun8i-emac.c | 14 +++----
48
hw/net/allwinner_emac.c | 2 +-
49
hw/net/cadence_gem.c | 8 ++--
50
hw/net/can/can_sja1000.c | 8 ++--
51
hw/net/can/can_sja1000.h | 2 +-
52
hw/net/dp8393x.c | 8 ++--
53
hw/net/e1000.c | 2 +-
54
hw/net/e1000e.c | 4 +-
55
hw/net/e1000e_core.c | 2 +-
56
hw/net/e1000e_core.h | 2 +-
57
hw/net/ftgmac100.c | 6 +--
58
hw/net/i82596.c | 66 ++++++++++++++++++++----------
59
hw/net/i82596.h | 2 +-
60
hw/net/imx_fec.c | 2 +-
61
hw/net/opencores_eth.c | 5 +--
62
hw/net/rtl8139.c | 22 +++++-----
63
hw/net/smc91c111.c | 10 ++---
64
hw/net/spapr_llan.c | 4 +-
65
hw/net/sungem.c | 6 +--
66
hw/net/sunhme.c | 4 +-
67
hw/net/tulip.c | 36 ++++++++++++----
68
hw/net/virtio-net.c | 10 ++---
69
hw/net/xilinx_ethlite.c | 2 +-
70
include/net/can_emu.h | 2 +-
71
include/net/net.h | 2 +-
72
net/can/can_socketcan.c | 4 +-
73
net/colo-compare.c | 95 ++++++++++++++++++++++++++++++++++++++++---
74
net/filter-buffer.c | 2 +-
75
net/hub.c | 6 +--
76
qemu-options.hx | 10 +++--
77
tests/qtest/Makefile.include | 1 +
78
tests/qtest/tulip-test.c | 91 +++++++++++++++++++++++++++++++++++++++++
79
32 files changed, 328 insertions(+), 112 deletions(-)
80
create mode 100644 tests/qtest/tulip-test.c
51
81
52
82
diff view generated by jsdifflib
1
From: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
3
The command is 32-bit, but we are loading the 16 upper bits with
4
the 'get_uint16(s->scb + 2)' call.
5
6
Once shifted by 16, the command bits match the status bits:
7
8
- Command
9
Bit 31 ACK-CX Acknowledges that the CU completed an Action Command.
10
Bit 30 ACK-FR Acknowledges that the RU received a frame.
11
Bit 29 ACK-CNA Acknowledges that the Command Unit became not active.
12
Bit 28 ACK-RNR Acknowledges that the Receive Unit became not ready.
13
14
- Status
15
Bit 15 CX The CU finished executing a command with its I(interrupt) bit set.
16
Bit 14 FR The RU finished receiving a frame.
17
Bit 13 CNA The Command Unit left the Active state.
18
Bit 12 RNR The Receive Unit left the Ready state.
19
20
Add the SCB_COMMAND_ACK_MASK definition to simplify the code.
21
22
This fixes Coverity 1419392 (CONSTANT_EXPRESSION_RESULT):
23
24
/hw/net/i82596.c: 352 in examine_scb()
25
346 cuc = (command >> 8) & 0x7;
26
347 ruc = (command >> 4) & 0x7;
27
348 DBG(printf("MAIN COMMAND %04x cuc %02x ruc %02x\n", command, cuc, ruc));
28
349 /* and clear the scb command word */
29
350 set_uint16(s->scb + 2, 0);
30
351
31
>>> CID 1419392: (CONSTANT_EXPRESSION_RESULT)
32
>>> "command & (2147483648UL /* 1UL << 31 */)" is always 0 regardless of the values of its operands. This occurs as the logical operand of "if".
33
352 if (command & BIT(31)) /* ACK-CX */
34
353 s->scb_status &= ~SCB_STATUS_CX;
35
>>> CID 1419392: (CONSTANT_EXPRESSION_RESULT)
36
>>> "command & (1073741824UL /* 1UL << 30 */)" is always 0 regardless of the values of its operands. This occurs as the logical operand of "if".
37
354 if (command & BIT(30)) /*ACK-FR */
38
355 s->scb_status &= ~SCB_STATUS_FR;
39
>>> CID 1419392: (CONSTANT_EXPRESSION_RESULT)
40
>>> "command & (536870912UL /* 1UL << 29 */)" is always 0 regardless of the values of its operands. This occurs as the logical operand of "if".
41
356 if (command & BIT(29)) /*ACK-CNA */
42
357 s->scb_status &= ~SCB_STATUS_CNA;
43
>>> CID 1419392: (CONSTANT_EXPRESSION_RESULT)
44
>>> "command & (268435456UL /* 1UL << 28 */)" is always 0 regardless of the values of its operands. This occurs as the logical operand of "if".
45
358 if (command & BIT(28)) /*ACK-RNR */
46
359 s->scb_status &= ~SCB_STATUS_RNR;
47
48
Fixes: Covertiy CID 1419392 (commit 376b851909)
49
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
50
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Jason Wang <jasowang@redhat.com>
51
Signed-off-by: Jason Wang <jasowang@redhat.com>
5
---
52
---
6
docs/colo-proxy.txt | 26 ++++++++++++++++++++++++++
53
hw/net/i82596.c | 12 ++++--------
7
1 file changed, 26 insertions(+)
54
1 file changed, 4 insertions(+), 8 deletions(-)
8
55
9
diff --git a/docs/colo-proxy.txt b/docs/colo-proxy.txt
56
diff --git a/hw/net/i82596.c b/hw/net/i82596.c
10
index XXXXXXX..XXXXXXX 100644
57
index XXXXXXX..XXXXXXX 100644
11
--- a/docs/colo-proxy.txt
58
--- a/hw/net/i82596.c
12
+++ b/docs/colo-proxy.txt
59
+++ b/hw/net/i82596.c
13
@@ -XXX,XX +XXX,XX @@ Secondary(ip:3.3.3.8):
60
@@ -XXX,XX +XXX,XX @@
14
-chardev socket,id=red1,host=3.3.3.3,port=9004
61
#define SCB_STATUS_CNA 0x2000 /* CU left active state */
15
-object filter-redirector,id=f1,netdev=hn0,queue=tx,indev=red0
62
#define SCB_STATUS_RNR 0x1000 /* RU left active state */
16
-object filter-redirector,id=f2,netdev=hn0,queue=rx,outdev=red1
63
17
+-object filter-rewriter,id=f3,netdev=hn0,queue=all
64
+#define SCB_COMMAND_ACK_MASK \
65
+ (SCB_STATUS_CX | SCB_STATUS_FR | SCB_STATUS_CNA | SCB_STATUS_RNR)
18
+
66
+
19
+If you want to use virtio-net-pci or other driver with vnet_header:
67
#define CU_IDLE 0
20
+
68
#define CU_SUSPENDED 1
21
+Primary(ip:3.3.3.3):
69
#define CU_ACTIVE 2
22
+-netdev tap,id=hn0,vhost=off,script=/etc/qemu-ifup,downscript=/etc/qemu-ifdown
70
@@ -XXX,XX +XXX,XX @@ static void examine_scb(I82596State *s)
23
+-device e1000,id=e0,netdev=hn0,mac=52:a4:00:12:78:66
71
/* and clear the scb command word */
24
+-chardev socket,id=mirror0,host=3.3.3.3,port=9003,server,nowait
72
set_uint16(s->scb + 2, 0);
25
+-chardev socket,id=compare1,host=3.3.3.3,port=9004,server,nowait
73
26
+-chardev socket,id=compare0,host=3.3.3.3,port=9001,server,nowait
74
- if (command & BIT(31)) /* ACK-CX */
27
+-chardev socket,id=compare0-0,host=3.3.3.3,port=9001
75
- s->scb_status &= ~SCB_STATUS_CX;
28
+-chardev socket,id=compare_out,host=3.3.3.3,port=9005,server,nowait
76
- if (command & BIT(30)) /*ACK-FR */
29
+-chardev socket,id=compare_out0,host=3.3.3.3,port=9005
77
- s->scb_status &= ~SCB_STATUS_FR;
30
+-object filter-mirror,id=m0,netdev=hn0,queue=tx,outdev=mirror0,vnet_hdr_support
78
- if (command & BIT(29)) /*ACK-CNA */
31
+-object filter-redirector,netdev=hn0,id=redire0,queue=rx,indev=compare_out,vnet_hdr_support
79
- s->scb_status &= ~SCB_STATUS_CNA;
32
+-object filter-redirector,netdev=hn0,id=redire1,queue=rx,outdev=compare0,vnet_hdr_support
80
- if (command & BIT(28)) /*ACK-RNR */
33
+-object colo-compare,id=comp0,primary_in=compare0-0,secondary_in=compare1,outdev=compare_out0,vnet_hdr_support
81
- s->scb_status &= ~SCB_STATUS_RNR;
34
+
82
+ s->scb_status &= ~(command & SCB_COMMAND_ACK_MASK);
35
+Secondary(ip:3.3.3.8):
83
36
+-netdev tap,id=hn0,vhost=off,script=/etc/qemu-ifup,down script=/etc/qemu-ifdown
84
switch (cuc) {
37
+-device e1000,netdev=hn0,mac=52:a4:00:12:78:66
85
case 0: /* no change */
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
--
86
--
47
2.7.4
87
2.5.0
48
88
49
89
diff view generated by jsdifflib
1
From: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
1
From: Peter Maydell <peter.maydell@linaro.org>
2
2
3
COLO-Proxy just focus on packet payload, so we skip vnet header.
3
The i82596_receive() function attempts to pass the guest a buffer
4
which is effectively the concatenation of the data it is passed and a
5
4 byte CRC value. However, rather than implementing this as "write
6
the data; then write the CRC" it instead bumps the length value of
7
the data by 4, and writes 4 extra bytes from beyond the end of the
8
buffer, which it then overwrites with the CRC. It also assumed that
9
we could always fit all four bytes of the CRC into the final receive
10
buffer, which might not be true if the CRC needs to be split over two
11
receive buffers.
4
12
5
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
13
Calculate separately how many bytes we need to transfer into the
14
guest's receive buffer from the source buffer, and how many we need
15
to transfer from the CRC work.
16
17
We add a count 'bufsz' of the number of bytes left in the source
18
buffer, which we use purely to assert() that we don't overrun.
19
20
Spotted by Coverity (CID 1419396) for the specific case when we end
21
up using a local array as the source buffer.
22
23
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Jason Wang <jasowang@redhat.com>
24
Signed-off-by: Jason Wang <jasowang@redhat.com>
7
---
25
---
8
net/colo-compare.c | 8 ++++++--
26
hw/net/i82596.c | 44 +++++++++++++++++++++++++++++++++++---------
9
1 file changed, 6 insertions(+), 2 deletions(-)
27
1 file changed, 35 insertions(+), 9 deletions(-)
10
28
11
diff --git a/net/colo-compare.c b/net/colo-compare.c
29
diff --git a/hw/net/i82596.c b/hw/net/i82596.c
12
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
13
--- a/net/colo-compare.c
31
--- a/hw/net/i82596.c
14
+++ b/net/colo-compare.c
32
+++ b/hw/net/i82596.c
15
@@ -XXX,XX +XXX,XX @@ static int colo_packet_compare_common(Packet *ppkt, Packet *spkt, int offset)
33
@@ -XXX,XX +XXX,XX @@ ssize_t i82596_receive(NetClientState *nc, const uint8_t *buf, size_t sz)
16
sec_ip_src, sec_ip_dst);
34
uint32_t rfd_p;
35
uint32_t rbd;
36
uint16_t is_broadcast = 0;
37
- size_t len = sz;
38
+ size_t len = sz; /* length of data for guest (including CRC) */
39
+ size_t bufsz = sz; /* length of data in buf */
40
uint32_t crc;
41
uint8_t *crc_ptr;
42
uint8_t buf1[MIN_BUF_SIZE + VLAN_HLEN];
43
@@ -XXX,XX +XXX,XX @@ ssize_t i82596_receive(NetClientState *nc, const uint8_t *buf, size_t sz)
44
if (len < MIN_BUF_SIZE) {
45
len = MIN_BUF_SIZE;
46
}
47
+ bufsz = len;
17
}
48
}
18
49
19
+ offset = ppkt->vnet_hdr_len + offset;
50
/* Calculate the ethernet checksum (4 bytes) */
51
@@ -XXX,XX +XXX,XX @@ ssize_t i82596_receive(NetClientState *nc, const uint8_t *buf, size_t sz)
52
while (len) {
53
uint16_t buffer_size, num;
54
uint32_t rba;
55
+ size_t bufcount, crccount;
56
57
/* printf("Receive: rbd is %08x\n", rbd); */
58
buffer_size = get_uint16(rbd + 12);
59
@@ -XXX,XX +XXX,XX @@ ssize_t i82596_receive(NetClientState *nc, const uint8_t *buf, size_t sz)
60
}
61
rba = get_uint32(rbd + 8);
62
/* printf("rba is 0x%x\n", rba); */
63
- address_space_write(&address_space_memory, rba,
64
- MEMTXATTRS_UNSPECIFIED, buf, num);
65
- rba += num;
66
- buf += num;
67
- len -= num;
68
- if (len == 0) { /* copy crc */
69
- address_space_write(&address_space_memory, rba - 4,
70
- MEMTXATTRS_UNSPECIFIED, crc_ptr, 4);
71
+ /*
72
+ * Calculate how many bytes we want from buf[] and how many
73
+ * from the CRC.
74
+ */
75
+ if ((len - num) >= 4) {
76
+ /* The whole guest buffer, we haven't hit the CRC yet */
77
+ bufcount = num;
78
+ } else {
79
+ /* All that's left of buf[] */
80
+ bufcount = len - 4;
81
+ }
82
+ crccount = num - bufcount;
20
+
83
+
21
if (ppkt->size == spkt->size) {
84
+ if (bufcount > 0) {
22
- return memcmp(ppkt->data + offset, spkt->data + offset,
85
+ /* Still some of the actual data buffer to transfer */
23
+ return memcmp(ppkt->data + offset,
86
+ assert(bufsz >= bufcount);
24
+ spkt->data + offset,
87
+ bufsz -= bufcount;
25
spkt->size - offset);
88
+ address_space_write(&address_space_memory, rba,
26
} else {
89
+ MEMTXATTRS_UNSPECIFIED, buf, bufcount);
27
trace_colo_compare_main("Net packet size are not the same");
90
+ rba += bufcount;
28
@@ -XXX,XX +XXX,XX @@ static int colo_packet_compare_tcp(Packet *spkt, Packet *ppkt)
91
+ buf += bufcount;
29
*/
92
+ len -= bufcount;
30
if (ptcp->th_off > 5) {
93
+ }
31
ptrdiff_t tcp_offset;
32
+
94
+
33
tcp_offset = ppkt->transport_header - (uint8_t *)ppkt->data
95
+ /* Write as much of the CRC as fits */
34
- + (ptcp->th_off * 4);
96
+ if (crccount > 0) {
35
+ + (ptcp->th_off * 4) - ppkt->vnet_hdr_len;
97
+ address_space_write(&address_space_memory, rba,
36
res = colo_packet_compare_common(ppkt, spkt, tcp_offset);
98
+ MEMTXATTRS_UNSPECIFIED, crc_ptr, crccount);
37
} else if (ptcp->th_sum == stcp->th_sum) {
99
+ rba += crccount;
38
res = colo_packet_compare_common(ppkt, spkt, ETH_HLEN);
100
+ crc_ptr += crccount;
101
+ len -= crccount;
102
}
103
104
num |= 0x4000; /* set F BIT */
39
--
105
--
40
2.7.4
106
2.5.0
41
107
42
108
diff view generated by jsdifflib
1
From: Michal Privoznik <mprivozn@redhat.com>
1
From: Andrew Melnychenko <andrew@daynix.com>
2
2
3
We have a function that checks if given number is power of two.
3
Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=1737400
4
We should prefer it instead of expanding the check on our own.
4
Fixed setting max_queue_num if there are no peers in
5
NICConf. qemu_new_nic() creates NICState with 1 NetClientState(index
6
0) without peers, set max_queue_num to 0 - It prevents undefined
7
behavior and possible crashes, especially during pcie hotplug.
5
8
6
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
9
Fixes: 6f3fbe4ed06 ("net: Introduce e1000e device emulation")
10
Signed-off-by: Andrew Melnychenko <andrew@daynix.com>
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
12
Reviewed-by: Dmitry Fleytman <dmitry.fleytman@gmail.com>
7
Signed-off-by: Jason Wang <jasowang@redhat.com>
13
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
---
14
---
9
hw/net/virtio-net.c | 2 +-
15
hw/net/e1000e.c | 2 +-
10
1 file changed, 1 insertion(+), 1 deletion(-)
16
1 file changed, 1 insertion(+), 1 deletion(-)
11
17
12
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
18
diff --git a/hw/net/e1000e.c b/hw/net/e1000e.c
13
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/net/virtio-net.c
20
--- a/hw/net/e1000e.c
15
+++ b/hw/net/virtio-net.c
21
+++ b/hw/net/e1000e.c
16
@@ -XXX,XX +XXX,XX @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp)
22
@@ -XXX,XX +XXX,XX @@ e1000e_init_net_peer(E1000EState *s, PCIDevice *pci_dev, uint8_t *macaddr)
17
*/
23
s->nic = qemu_new_nic(&net_e1000e_info, &s->conf,
18
if (n->net_conf.rx_queue_size < VIRTIO_NET_RX_QUEUE_MIN_SIZE ||
24
object_get_typename(OBJECT(s)), dev->id, s);
19
n->net_conf.rx_queue_size > VIRTQUEUE_MAX_SIZE ||
25
20
- (n->net_conf.rx_queue_size & (n->net_conf.rx_queue_size - 1))) {
26
- s->core.max_queue_num = s->conf.peers.queues - 1;
21
+ !is_power_of_2(n->net_conf.rx_queue_size)) {
27
+ s->core.max_queue_num = s->conf.peers.queues ? s->conf.peers.queues - 1 : 0;
22
error_setg(errp, "Invalid rx_queue_size (= %" PRIu16 "), "
28
23
"must be a power of 2 between %d and %d.",
29
trace_e1000e_mac_set_permanent(MAC_ARG(macaddr));
24
n->net_conf.rx_queue_size, VIRTIO_NET_RX_QUEUE_MIN_SIZE,
30
memcpy(s->core.permanent_mac, macaddr, sizeof(s->core.permanent_mac));
25
--
31
--
26
2.7.4
32
2.5.0
27
33
28
34
diff view generated by jsdifflib
1
From: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
This patch change the compare_chr_send() parameter from CharBackend to CompareState,
3
The e1000e_can_receive() function simply returns a boolean value.
4
we can get more information like vnet_hdr(We use it to support packet with vnet_header).
5
4
6
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
5
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
7
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
---
9
---
9
net/colo-compare.c | 14 +++++++-------
10
hw/net/e1000e_core.c | 2 +-
10
1 file changed, 7 insertions(+), 7 deletions(-)
11
hw/net/e1000e_core.h | 2 +-
12
2 files changed, 2 insertions(+), 2 deletions(-)
11
13
12
diff --git a/net/colo-compare.c b/net/colo-compare.c
14
diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c
13
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
14
--- a/net/colo-compare.c
16
--- a/hw/net/e1000e_core.c
15
+++ b/net/colo-compare.c
17
+++ b/hw/net/e1000e_core.c
16
@@ -XXX,XX +XXX,XX @@ enum {
18
@@ -XXX,XX +XXX,XX @@ e1000e_start_recv(E1000ECore *core)
17
SECONDARY_IN,
18
};
19
20
-static int compare_chr_send(CharBackend *out,
21
+static int compare_chr_send(CompareState *s,
22
const uint8_t *buf,
23
uint32_t size);
24
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
}
19
}
36
}
20
}
37
21
38
-static int compare_chr_send(CharBackend *out,
22
-int
39
+static int compare_chr_send(CompareState *s,
23
+bool
40
const uint8_t *buf,
24
e1000e_can_receive(E1000ECore *core)
41
uint32_t size)
42
{
25
{
43
@@ -XXX,XX +XXX,XX @@ static int compare_chr_send(CharBackend *out,
26
int i;
44
return 0;
27
diff --git a/hw/net/e1000e_core.h b/hw/net/e1000e_core.h
45
}
28
index XXXXXXX..XXXXXXX 100644
46
29
--- a/hw/net/e1000e_core.h
47
- ret = qemu_chr_fe_write_all(out, (uint8_t *)&len, sizeof(len));
30
+++ b/hw/net/e1000e_core.h
48
+ ret = qemu_chr_fe_write_all(&s->chr_out, (uint8_t *)&len, sizeof(len));
31
@@ -XXX,XX +XXX,XX @@ e1000e_core_set_link_status(E1000ECore *core);
49
if (ret != sizeof(len)) {
32
void
50
goto err;
33
e1000e_core_pci_uninit(E1000ECore *core);
51
}
34
52
35
-int
53
- ret = qemu_chr_fe_write_all(out, (uint8_t *)buf, size);
36
+bool
54
+ ret = qemu_chr_fe_write_all(&s->chr_out, (uint8_t *)buf, size);
37
e1000e_can_receive(E1000ECore *core);
55
if (ret != size) {
38
56
goto err;
39
ssize_t
57
}
58
@@ -XXX,XX +XXX,XX @@ static void compare_pri_rs_finalize(SocketReadState *pri_rs)
59
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
--
40
--
77
2.7.4
41
2.5.0
78
42
79
43
diff view generated by jsdifflib
1
From: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
We can use this property flush and send packet with vnet_hdr_len.
3
The smc91c111_can_receive() function simply returns a boolean value.
4
4
5
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
5
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Cédric Le Goater <clg@kaod.org>
6
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
Signed-off-by: Jason Wang <jasowang@redhat.com>
7
---
9
---
8
net/colo-compare.c | 8 ++++++--
10
hw/net/smc91c111.c | 8 ++++----
9
net/colo.c | 3 ++-
11
1 file changed, 4 insertions(+), 4 deletions(-)
10
net/colo.h | 4 +++-
11
net/filter-rewriter.c | 2 +-
12
4 files changed, 12 insertions(+), 5 deletions(-)
13
12
14
diff --git a/net/colo-compare.c b/net/colo-compare.c
13
diff --git a/hw/net/smc91c111.c b/hw/net/smc91c111.c
15
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
16
--- a/net/colo-compare.c
15
--- a/hw/net/smc91c111.c
17
+++ b/net/colo-compare.c
16
+++ b/hw/net/smc91c111.c
18
@@ -XXX,XX +XXX,XX @@ static int packet_enqueue(CompareState *s, int mode)
17
@@ -XXX,XX +XXX,XX @@ static void smc91c111_update(smc91c111_state *s)
19
Connection *conn;
18
qemu_set_irq(s->irq, level);
20
19
}
21
if (mode == PRIMARY_IN) {
20
22
- pkt = packet_new(s->pri_rs.buf, s->pri_rs.packet_len);
21
-static int smc91c111_can_receive(smc91c111_state *s)
23
+ pkt = packet_new(s->pri_rs.buf,
22
+static bool smc91c111_can_receive(smc91c111_state *s)
24
+ s->pri_rs.packet_len,
23
{
25
+ s->pri_rs.vnet_hdr_len);
24
if ((s->rcr & RCR_RXEN) == 0 || (s->rcr & RCR_SOFT_RST)) {
26
} else {
25
- return 1;
27
- pkt = packet_new(s->sec_rs.buf, s->sec_rs.packet_len);
26
+ return true;
28
+ pkt = packet_new(s->sec_rs.buf,
29
+ s->sec_rs.packet_len,
30
+ s->sec_rs.vnet_hdr_len);
31
}
27
}
32
28
if (s->allocated == (1 << NUM_PACKETS) - 1 ||
33
if (parse_packet_early(pkt)) {
29
s->rx_fifo_len == NUM_PACKETS) {
34
diff --git a/net/colo.c b/net/colo.c
30
- return 0;
35
index XXXXXXX..XXXXXXX 100644
31
+ return false;
36
--- a/net/colo.c
32
}
37
+++ b/net/colo.c
33
- return 1;
38
@@ -XXX,XX +XXX,XX @@ void connection_destroy(void *opaque)
34
+ return true;
39
g_slice_free(Connection, conn);
40
}
35
}
41
36
42
-Packet *packet_new(const void *data, int size)
37
static inline void smc91c111_flush_queued_packets(smc91c111_state *s)
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
--
38
--
90
2.7.4
39
2.5.0
91
40
92
41
diff view generated by jsdifflib
1
From: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
Add vnet_hdr_len arguments in NetClientState
3
Rewrite:
4
that make other module get real vnet_hdr_len easily.
5
4
6
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
5
if (E) {
6
return A;
7
} else {
8
return B;
9
}
10
/* EOF */
11
}
12
13
as:
14
15
if (E) {
16
return A;
17
}
18
return B;
19
}
20
21
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
22
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
23
Reviewed-by: Cédric Le Goater <clg@kaod.org>
7
Signed-off-by: Jason Wang <jasowang@redhat.com>
24
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
---
25
---
9
include/net/net.h | 1 +
26
hw/net/rtl8139.c | 8 ++++----
10
net/net.c | 1 +
27
1 file changed, 4 insertions(+), 4 deletions(-)
11
2 files changed, 2 insertions(+)
12
28
13
diff --git a/include/net/net.h b/include/net/net.h
29
diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c
14
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
15
--- a/include/net/net.h
31
--- a/hw/net/rtl8139.c
16
+++ b/include/net/net.h
32
+++ b/hw/net/rtl8139.c
17
@@ -XXX,XX +XXX,XX @@ struct NetClientState {
33
@@ -XXX,XX +XXX,XX @@ static int rtl8139_can_receive(NetClientState *nc)
18
unsigned int queue_index;
34
/* ??? Flow control not implemented in c+ mode.
19
unsigned rxfilter_notify_enabled:1;
35
This is a hack to work around slirp deficiencies anyway. */
20
int vring_enable;
36
return 1;
21
+ int vnet_hdr_len;
37
- } else {
22
QTAILQ_HEAD(NetFilterHead, NetFilterState) filters;
38
- avail = MOD2(s->RxBufferSize + s->RxBufPtr - s->RxBufAddr,
23
};
39
- s->RxBufferSize);
24
40
- return (avail == 0 || avail >= 1514 || (s->IntrMask & RxOverflow));
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
}
41
}
32
42
+
33
+ nc->vnet_hdr_len = len;
43
+ avail = MOD2(s->RxBufferSize + s->RxBufPtr - s->RxBufAddr,
34
nc->info->set_vnet_hdr_len(nc, len);
44
+ s->RxBufferSize);
45
+ return avail == 0 || avail >= 1514 || (s->IntrMask & RxOverflow);
35
}
46
}
36
47
48
static ssize_t rtl8139_do_receive(NetClientState *nc, const uint8_t *buf, size_t size_, int do_interrupt)
37
--
49
--
38
2.7.4
50
2.5.0
39
51
40
52
diff view generated by jsdifflib
1
From: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
Make colo-compare and filter-rewriter can parse vnet packet.
3
We will modify this code in the next commit. Clean it up
4
first to avoid checkpatch.pl errors.
4
5
5
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Cédric Le Goater <clg@kaod.org>
6
Signed-off-by: Jason Wang <jasowang@redhat.com>
9
Signed-off-by: Jason Wang <jasowang@redhat.com>
7
---
10
---
8
net/colo.c | 6 +++---
11
hw/net/rtl8139.c | 10 ++++++----
9
1 file changed, 3 insertions(+), 3 deletions(-)
12
1 file changed, 6 insertions(+), 4 deletions(-)
10
13
11
diff --git a/net/colo.c b/net/colo.c
14
diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c
12
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
13
--- a/net/colo.c
16
--- a/hw/net/rtl8139.c
14
+++ b/net/colo.c
17
+++ b/hw/net/rtl8139.c
15
@@ -XXX,XX +XXX,XX @@ int parse_packet_early(Packet *pkt)
18
@@ -XXX,XX +XXX,XX @@ static int rtl8139_can_receive(NetClientState *nc)
16
{
19
int avail;
17
int network_length;
20
18
static const uint8_t vlan[] = {0x81, 0x00};
21
/* Receive (drop) packets if card is disabled. */
19
- uint8_t *data = pkt->data;
22
- if (!s->clock_enabled)
20
+ uint8_t *data = pkt->data + pkt->vnet_hdr_len;
23
- return 1;
21
uint16_t l3_proto;
24
- if (!rtl8139_receiver_enabled(s))
22
ssize_t l2hdr_len = eth_get_l2_hdr_length(data);
25
- return 1;
23
26
+ if (!s->clock_enabled) {
24
- if (pkt->size < ETH_HLEN) {
27
+ return 1;
25
+ if (pkt->size < ETH_HLEN + pkt->vnet_hdr_len) {
28
+ }
26
trace_colo_proxy_main("pkt->size < ETH_HLEN");
29
+ if (!rtl8139_receiver_enabled(s)) {
27
return 1;
30
+ return 1;
28
}
31
+ }
29
@@ -XXX,XX +XXX,XX @@ int parse_packet_early(Packet *pkt)
32
30
}
33
if (rtl8139_cp_receiver_enabled(s) && rtl8139_cp_rx_valid(s)) {
31
34
/* ??? Flow control not implemented in c+ mode.
32
network_length = pkt->ip->ip_hl * 4;
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
}
38
--
35
--
39
2.7.4
36
2.5.0
40
37
41
38
diff view generated by jsdifflib
1
Spec said offloads should be le64, so use virtio_ldq_p() to guarantee
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
valid endian.
3
2
4
Fixes: 644c98587d4c ("virtio-net: dynamic network offloads configuration")
3
The NetCanReceive handler return whether the device can or
5
Cc: qemu-stable@nongnu.org
4
can not receive new packets. Make it obvious by returning
6
Cc: Dmitry Fleytman <dfleytma@redhat.com>
5
a boolean type.
6
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Acked-by: David Gibson <david@gibson.dropbear.id.au>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Reviewed-by: Cédric Le Goater <clg@kaod.org>
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
hw/net/allwinner_emac.c | 2 +-
10
1 file changed, 2 insertions(+)
14
hw/net/cadence_gem.c | 8 ++++----
15
hw/net/dp8393x.c | 8 +++-----
16
hw/net/e1000.c | 2 +-
17
hw/net/e1000e.c | 2 +-
18
hw/net/ftgmac100.c | 6 +++---
19
hw/net/i82596.c | 10 +++++-----
20
hw/net/i82596.h | 2 +-
21
hw/net/imx_fec.c | 2 +-
22
hw/net/opencores_eth.c | 5 ++---
23
hw/net/rtl8139.c | 8 ++++----
24
hw/net/smc91c111.c | 2 +-
25
hw/net/spapr_llan.c | 4 ++--
26
hw/net/sungem.c | 6 +++---
27
hw/net/sunhme.c | 4 ++--
28
hw/net/virtio-net.c | 10 +++++-----
29
hw/net/xilinx_ethlite.c | 2 +-
30
include/net/net.h | 2 +-
31
net/filter-buffer.c | 2 +-
32
net/hub.c | 6 +++---
33
20 files changed, 45 insertions(+), 48 deletions(-)
11
34
35
diff --git a/hw/net/allwinner_emac.c b/hw/net/allwinner_emac.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/hw/net/allwinner_emac.c
38
+++ b/hw/net/allwinner_emac.c
39
@@ -XXX,XX +XXX,XX @@ static uint32_t fifo8_pop_word(Fifo8 *fifo)
40
return ret;
41
}
42
43
-static int aw_emac_can_receive(NetClientState *nc)
44
+static bool aw_emac_can_receive(NetClientState *nc)
45
{
46
AwEmacState *s = qemu_get_nic_opaque(nc);
47
48
diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
49
index XXXXXXX..XXXXXXX 100644
50
--- a/hw/net/cadence_gem.c
51
+++ b/hw/net/cadence_gem.c
52
@@ -XXX,XX +XXX,XX @@ static void phy_update_link(CadenceGEMState *s)
53
}
54
}
55
56
-static int gem_can_receive(NetClientState *nc)
57
+static bool gem_can_receive(NetClientState *nc)
58
{
59
CadenceGEMState *s;
60
int i;
61
@@ -XXX,XX +XXX,XX @@ static int gem_can_receive(NetClientState *nc)
62
s->can_rx_state = 1;
63
DB_PRINT("can't receive - no enable\n");
64
}
65
- return 0;
66
+ return false;
67
}
68
69
for (i = 0; i < s->num_priority_queues; i++) {
70
@@ -XXX,XX +XXX,XX @@ static int gem_can_receive(NetClientState *nc)
71
s->can_rx_state = 2;
72
DB_PRINT("can't receive - all the buffer descriptors are busy\n");
73
}
74
- return 0;
75
+ return false;
76
}
77
78
if (s->can_rx_state != 0) {
79
s->can_rx_state = 0;
80
DB_PRINT("can receive\n");
81
}
82
- return 1;
83
+ return true;
84
}
85
86
/*
87
diff --git a/hw/net/dp8393x.c b/hw/net/dp8393x.c
88
index XXXXXXX..XXXXXXX 100644
89
--- a/hw/net/dp8393x.c
90
+++ b/hw/net/dp8393x.c
91
@@ -XXX,XX +XXX,XX @@ static void dp8393x_do_stop_timer(dp8393xState *s)
92
dp8393x_update_wt_regs(s);
93
}
94
95
-static int dp8393x_can_receive(NetClientState *nc);
96
+static bool dp8393x_can_receive(NetClientState *nc);
97
98
static void dp8393x_do_receiver_enable(dp8393xState *s)
99
{
100
@@ -XXX,XX +XXX,XX @@ static void dp8393x_watchdog(void *opaque)
101
dp8393x_update_irq(s);
102
}
103
104
-static int dp8393x_can_receive(NetClientState *nc)
105
+static bool dp8393x_can_receive(NetClientState *nc)
106
{
107
dp8393xState *s = qemu_get_nic_opaque(nc);
108
109
- if (!(s->regs[SONIC_CR] & SONIC_CR_RXEN))
110
- return 0;
111
- return 1;
112
+ return !!(s->regs[SONIC_CR] & SONIC_CR_RXEN);
113
}
114
115
static int dp8393x_receive_filter(dp8393xState *s, const uint8_t * buf,
116
diff --git a/hw/net/e1000.c b/hw/net/e1000.c
117
index XXXXXXX..XXXXXXX 100644
118
--- a/hw/net/e1000.c
119
+++ b/hw/net/e1000.c
120
@@ -XXX,XX +XXX,XX @@ static bool e1000_has_rxbufs(E1000State *s, size_t total_size)
121
return total_size <= bufs * s->rxbuf_size;
122
}
123
124
-static int
125
+static bool
126
e1000_can_receive(NetClientState *nc)
127
{
128
E1000State *s = qemu_get_nic_opaque(nc);
129
diff --git a/hw/net/e1000e.c b/hw/net/e1000e.c
130
index XXXXXXX..XXXXXXX 100644
131
--- a/hw/net/e1000e.c
132
+++ b/hw/net/e1000e.c
133
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps io_ops = {
134
},
135
};
136
137
-static int
138
+static bool
139
e1000e_nc_can_receive(NetClientState *nc)
140
{
141
E1000EState *s = qemu_get_nic_opaque(nc);
142
diff --git a/hw/net/ftgmac100.c b/hw/net/ftgmac100.c
143
index XXXXXXX..XXXXXXX 100644
144
--- a/hw/net/ftgmac100.c
145
+++ b/hw/net/ftgmac100.c
146
@@ -XXX,XX +XXX,XX @@ static void ftgmac100_do_tx(FTGMAC100State *s, uint32_t tx_ring,
147
ftgmac100_update_irq(s);
148
}
149
150
-static int ftgmac100_can_receive(NetClientState *nc)
151
+static bool ftgmac100_can_receive(NetClientState *nc)
152
{
153
FTGMAC100State *s = FTGMAC100(qemu_get_nic_opaque(nc));
154
FTGMAC100Desc bd;
155
156
if ((s->maccr & (FTGMAC100_MACCR_RXDMA_EN | FTGMAC100_MACCR_RXMAC_EN))
157
!= (FTGMAC100_MACCR_RXDMA_EN | FTGMAC100_MACCR_RXMAC_EN)) {
158
- return 0;
159
+ return false;
160
}
161
162
if (ftgmac100_read_bd(&bd, s->rx_descriptor)) {
163
- return 0;
164
+ return false;
165
}
166
return !(bd.des0 & FTGMAC100_RXDES0_RXPKT_RDY);
167
}
168
diff --git a/hw/net/i82596.c b/hw/net/i82596.c
169
index XXXXXXX..XXXXXXX 100644
170
--- a/hw/net/i82596.c
171
+++ b/hw/net/i82596.c
172
@@ -XXX,XX +XXX,XX @@ void i82596_h_reset(void *opaque)
173
i82596_s_reset(s);
174
}
175
176
-int i82596_can_receive(NetClientState *nc)
177
+bool i82596_can_receive(NetClientState *nc)
178
{
179
I82596State *s = qemu_get_nic_opaque(nc);
180
181
if (s->rx_status == RX_SUSPENDED) {
182
- return 0;
183
+ return false;
184
}
185
186
if (!s->lnkst) {
187
- return 0;
188
+ return false;
189
}
190
191
if (USE_TIMER && !timer_pending(s->flush_queue_timer)) {
192
- return 1;
193
+ return true;
194
}
195
196
- return 1;
197
+ return true;
198
}
199
200
#define MIN_BUF_SIZE 60
201
diff --git a/hw/net/i82596.h b/hw/net/i82596.h
202
index XXXXXXX..XXXXXXX 100644
203
--- a/hw/net/i82596.h
204
+++ b/hw/net/i82596.h
205
@@ -XXX,XX +XXX,XX @@ void i82596_ioport_writel(void *opaque, uint32_t addr, uint32_t val);
206
uint32_t i82596_ioport_readl(void *opaque, uint32_t addr);
207
uint32_t i82596_bcr_readw(I82596State *s, uint32_t rap);
208
ssize_t i82596_receive(NetClientState *nc, const uint8_t *buf, size_t size_);
209
-int i82596_can_receive(NetClientState *nc);
210
+bool i82596_can_receive(NetClientState *nc);
211
void i82596_set_link_status(NetClientState *nc);
212
void i82596_common_init(DeviceState *dev, I82596State *s, NetClientInfo *info);
213
extern const VMStateDescription vmstate_i82596;
214
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
215
index XXXXXXX..XXXXXXX 100644
216
--- a/hw/net/imx_fec.c
217
+++ b/hw/net/imx_fec.c
218
@@ -XXX,XX +XXX,XX @@ static void imx_eth_write(void *opaque, hwaddr offset, uint64_t value,
219
imx_eth_update(s);
220
}
221
222
-static int imx_eth_can_receive(NetClientState *nc)
223
+static bool imx_eth_can_receive(NetClientState *nc)
224
{
225
IMXFECState *s = IMX_FEC(qemu_get_nic_opaque(nc));
226
227
diff --git a/hw/net/opencores_eth.c b/hw/net/opencores_eth.c
228
index XXXXXXX..XXXXXXX 100644
229
--- a/hw/net/opencores_eth.c
230
+++ b/hw/net/opencores_eth.c
231
@@ -XXX,XX +XXX,XX @@ static void open_eth_reset(void *opaque)
232
open_eth_set_link_status(qemu_get_queue(s->nic));
233
}
234
235
-static int open_eth_can_receive(NetClientState *nc)
236
+static bool open_eth_can_receive(NetClientState *nc)
237
{
238
OpenEthState *s = qemu_get_nic_opaque(nc);
239
240
- return GET_REGBIT(s, MODER, RXEN) &&
241
- (s->regs[TX_BD_NUM] < 0x80);
242
+ return GET_REGBIT(s, MODER, RXEN) && (s->regs[TX_BD_NUM] < 0x80);
243
}
244
245
static ssize_t open_eth_receive(NetClientState *nc,
246
diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c
247
index XXXXXXX..XXXXXXX 100644
248
--- a/hw/net/rtl8139.c
249
+++ b/hw/net/rtl8139.c
250
@@ -XXX,XX +XXX,XX @@ static bool rtl8139_cp_rx_valid(RTL8139State *s)
251
return !(s->RxRingAddrLO == 0 && s->RxRingAddrHI == 0);
252
}
253
254
-static int rtl8139_can_receive(NetClientState *nc)
255
+static bool rtl8139_can_receive(NetClientState *nc)
256
{
257
RTL8139State *s = qemu_get_nic_opaque(nc);
258
int avail;
259
260
/* Receive (drop) packets if card is disabled. */
261
if (!s->clock_enabled) {
262
- return 1;
263
+ return true;
264
}
265
if (!rtl8139_receiver_enabled(s)) {
266
- return 1;
267
+ return true;
268
}
269
270
if (rtl8139_cp_receiver_enabled(s) && rtl8139_cp_rx_valid(s)) {
271
/* ??? Flow control not implemented in c+ mode.
272
This is a hack to work around slirp deficiencies anyway. */
273
- return 1;
274
+ return true;
275
}
276
277
avail = MOD2(s->RxBufferSize + s->RxBufPtr - s->RxBufAddr,
278
diff --git a/hw/net/smc91c111.c b/hw/net/smc91c111.c
279
index XXXXXXX..XXXXXXX 100644
280
--- a/hw/net/smc91c111.c
281
+++ b/hw/net/smc91c111.c
282
@@ -XXX,XX +XXX,XX @@ static void smc91c111_writefn(void *opaque, hwaddr addr,
283
}
284
}
285
286
-static int smc91c111_can_receive_nc(NetClientState *nc)
287
+static bool smc91c111_can_receive_nc(NetClientState *nc)
288
{
289
smc91c111_state *s = qemu_get_nic_opaque(nc);
290
291
diff --git a/hw/net/spapr_llan.c b/hw/net/spapr_llan.c
292
index XXXXXXX..XXXXXXX 100644
293
--- a/hw/net/spapr_llan.c
294
+++ b/hw/net/spapr_llan.c
295
@@ -XXX,XX +XXX,XX @@ typedef struct SpaprVioVlan {
296
RxBufPool *rx_pool[RX_MAX_POOLS]; /* Receive buffer descriptor pools */
297
} SpaprVioVlan;
298
299
-static int spapr_vlan_can_receive(NetClientState *nc)
300
+static bool spapr_vlan_can_receive(NetClientState *nc)
301
{
302
SpaprVioVlan *dev = qemu_get_nic_opaque(nc);
303
304
- return (dev->isopen && dev->rx_bufs > 0);
305
+ return dev->isopen && dev->rx_bufs > 0;
306
}
307
308
/**
309
diff --git a/hw/net/sungem.c b/hw/net/sungem.c
310
index XXXXXXX..XXXXXXX 100644
311
--- a/hw/net/sungem.c
312
+++ b/hw/net/sungem.c
313
@@ -XXX,XX +XXX,XX @@ static bool sungem_rx_full(SunGEMState *s, uint32_t kick, uint32_t done)
314
return kick == ((done + 1) & s->rx_mask);
315
}
316
317
-static int sungem_can_receive(NetClientState *nc)
318
+static bool sungem_can_receive(NetClientState *nc)
319
{
320
SunGEMState *s = qemu_get_nic_opaque(nc);
321
uint32_t kick, done, rxdma_cfg, rxmac_cfg;
322
@@ -XXX,XX +XXX,XX @@ static int sungem_can_receive(NetClientState *nc)
323
/* If MAC disabled, can't receive */
324
if ((rxmac_cfg & MAC_RXCFG_ENAB) == 0) {
325
trace_sungem_rx_mac_disabled();
326
- return 0;
327
+ return false;
328
}
329
if ((rxdma_cfg & RXDMA_CFG_ENABLE) == 0) {
330
trace_sungem_rx_txdma_disabled();
331
- return 0;
332
+ return false;
333
}
334
335
/* Check RX availability */
336
diff --git a/hw/net/sunhme.c b/hw/net/sunhme.c
337
index XXXXXXX..XXXXXXX 100644
338
--- a/hw/net/sunhme.c
339
+++ b/hw/net/sunhme.c
340
@@ -XXX,XX +XXX,XX @@ static void sunhme_transmit(SunHMEState *s)
341
sunhme_update_irq(s);
342
}
343
344
-static int sunhme_can_receive(NetClientState *nc)
345
+static bool sunhme_can_receive(NetClientState *nc)
346
{
347
SunHMEState *s = qemu_get_nic_opaque(nc);
348
349
- return s->macregs[HME_MACI_RXCFG >> 2] & HME_MAC_RXCFG_ENABLE;
350
+ return !!(s->macregs[HME_MACI_RXCFG >> 2] & HME_MAC_RXCFG_ENABLE);
351
}
352
353
static void sunhme_link_status_changed(NetClientState *nc)
12
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
354
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
13
index XXXXXXX..XXXXXXX 100644
355
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/net/virtio-net.c
356
--- a/hw/net/virtio-net.c
15
+++ b/hw/net/virtio-net.c
357
+++ b/hw/net/virtio-net.c
16
@@ -XXX,XX +XXX,XX @@ static int virtio_net_handle_offloads(VirtIONet *n, uint8_t cmd,
358
@@ -XXX,XX +XXX,XX @@ static void virtio_net_handle_rx(VirtIODevice *vdev, VirtQueue *vq)
17
if (cmd == VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET) {
359
qemu_flush_queued_packets(qemu_get_subqueue(n->nic, queue_index));
18
uint64_t supported_offloads;
360
}
19
361
20
+ offloads = virtio_ldq_p(vdev, &offloads);
362
-static int virtio_net_can_receive(NetClientState *nc)
21
+
363
+static bool virtio_net_can_receive(NetClientState *nc)
22
if (!n->has_vnet_hdr) {
364
{
23
return VIRTIO_NET_ERR;
365
VirtIONet *n = qemu_get_nic_opaque(nc);
366
VirtIODevice *vdev = VIRTIO_DEVICE(n);
367
VirtIONetQueue *q = virtio_net_get_subqueue(nc);
368
369
if (!vdev->vm_running) {
370
- return 0;
371
+ return false;
372
}
373
374
if (nc->queue_index >= n->curr_queues) {
375
- return 0;
376
+ return false;
377
}
378
379
if (!virtio_queue_ready(q->rx_vq) ||
380
!(vdev->status & VIRTIO_CONFIG_S_DRIVER_OK)) {
381
- return 0;
382
+ return false;
383
}
384
385
- return 1;
386
+ return true;
387
}
388
389
static int virtio_net_has_buffers(VirtIONetQueue *q, int bufsize)
390
diff --git a/hw/net/xilinx_ethlite.c b/hw/net/xilinx_ethlite.c
391
index XXXXXXX..XXXXXXX 100644
392
--- a/hw/net/xilinx_ethlite.c
393
+++ b/hw/net/xilinx_ethlite.c
394
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps eth_ops = {
395
}
396
};
397
398
-static int eth_can_rx(NetClientState *nc)
399
+static bool eth_can_rx(NetClientState *nc)
400
{
401
struct xlx_ethlite *s = qemu_get_nic_opaque(nc);
402
unsigned int rxbase = s->rxbuf * (0x800 / 4);
403
diff --git a/include/net/net.h b/include/net/net.h
404
index XXXXXXX..XXXXXXX 100644
405
--- a/include/net/net.h
406
+++ b/include/net/net.h
407
@@ -XXX,XX +XXX,XX @@ typedef struct NICConf {
408
/* Net clients */
409
410
typedef void (NetPoll)(NetClientState *, bool enable);
411
-typedef int (NetCanReceive)(NetClientState *);
412
+typedef bool (NetCanReceive)(NetClientState *);
413
typedef ssize_t (NetReceive)(NetClientState *, const uint8_t *, size_t);
414
typedef ssize_t (NetReceiveIOV)(NetClientState *, const struct iovec *, int);
415
typedef void (NetCleanup) (NetClientState *);
416
diff --git a/net/filter-buffer.c b/net/filter-buffer.c
417
index XXXXXXX..XXXXXXX 100644
418
--- a/net/filter-buffer.c
419
+++ b/net/filter-buffer.c
420
@@ -XXX,XX +XXX,XX @@ static ssize_t filter_buffer_receive_iov(NetFilterState *nf,
421
* the filter can still accept packets until its internal queue is full.
422
* For example:
423
* For some reason, receiver could not receive more packets
424
- * (.can_receive() returns zero). Without a filter, at most one packet
425
+ * (.can_receive() returns false). Without a filter, at most one packet
426
* will be queued in incoming queue and sender's poll will be disabled
427
* unit its sent_cb() was called. With a filter, it will keep receiving
428
* the packets without caring about the receiver. This is suboptimal.
429
diff --git a/net/hub.c b/net/hub.c
430
index XXXXXXX..XXXXXXX 100644
431
--- a/net/hub.c
432
+++ b/net/hub.c
433
@@ -XXX,XX +XXX,XX @@ static NetHub *net_hub_new(int id)
434
return hub;
435
}
436
437
-static int net_hub_port_can_receive(NetClientState *nc)
438
+static bool net_hub_port_can_receive(NetClientState *nc)
439
{
440
NetHubPort *port;
441
NetHubPort *src_port = DO_UPCAST(NetHubPort, nc, nc);
442
@@ -XXX,XX +XXX,XX @@ static int net_hub_port_can_receive(NetClientState *nc)
24
}
443
}
444
445
if (qemu_can_send_packet(&port->nc)) {
446
- return 1;
447
+ return true;
448
}
449
}
450
451
- return 0;
452
+ return false;
453
}
454
455
static ssize_t net_hub_port_receive(NetClientState *nc,
25
--
456
--
26
2.7.4
457
2.5.0
27
458
28
459
diff view generated by jsdifflib
1
From: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
We add the vnet_hdr_support option for filter-mirror, default is disabled.
3
The CanBusClientInfo::can_receive handler return whether the
4
If you use virtio-net-pci or other driver needs vnet_hdr, please enable it.
4
device can or can not receive new frames. Make it obvious by
5
You can use it for example:
5
returning a boolean type.
6
-object filter-mirror,id=m0,netdev=hn0,queue=tx,outdev=mirror0,vnet_hdr_support
7
6
8
If it has vnet_hdr_support flag, we will change the sending packet format from
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
struct {int size; const uint8_t buf[];} to {int size; int vnet_hdr_len; const uint8_t buf[];}.
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
make other module(like colo-compare) know how to parse net packet correctly.
9
Reviewed-by: Cédric Le Goater <clg@kaod.org>
11
12
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
13
Signed-off-by: Jason Wang <jasowang@redhat.com>
10
Signed-off-by: Jason Wang <jasowang@redhat.com>
14
---
11
---
15
net/filter-mirror.c | 42 +++++++++++++++++++++++++++++++++++++++++-
12
hw/net/allwinner-sun8i-emac.c | 2 +-
16
qemu-options.hx | 5 ++---
13
hw/net/can/can_sja1000.c | 8 ++++----
17
2 files changed, 43 insertions(+), 4 deletions(-)
14
hw/net/can/can_sja1000.h | 2 +-
15
include/net/can_emu.h | 2 +-
16
net/can/can_socketcan.c | 4 ++--
17
5 files changed, 9 insertions(+), 9 deletions(-)
18
18
19
diff --git a/net/filter-mirror.c b/net/filter-mirror.c
19
diff --git a/hw/net/allwinner-sun8i-emac.c b/hw/net/allwinner-sun8i-emac.c
20
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
21
--- a/net/filter-mirror.c
21
--- a/hw/net/allwinner-sun8i-emac.c
22
+++ b/net/filter-mirror.c
22
+++ b/hw/net/allwinner-sun8i-emac.c
23
@@ -XXX,XX +XXX,XX @@ typedef struct MirrorState {
23
@@ -XXX,XX +XXX,XX @@ static void allwinner_sun8i_emac_flush_desc(FrameDescriptor *desc,
24
CharBackend chr_in;
24
cpu_physical_memory_write(phys_addr, desc, sizeof(*desc));
25
CharBackend chr_out;
25
}
26
SocketReadState rs;
26
27
+ bool vnet_hdr;
27
-static int allwinner_sun8i_emac_can_receive(NetClientState *nc)
28
} MirrorState;
28
+static bool allwinner_sun8i_emac_can_receive(NetClientState *nc)
29
30
static int filter_send(MirrorState *s,
31
const struct iovec *iov,
32
int iovcnt)
33
{
29
{
34
+ NetFilterState *nf = NETFILTER(s);
30
AwSun8iEmacState *s = qemu_get_nic_opaque(nc);
35
int ret = 0;
31
FrameDescriptor desc;
36
ssize_t size = 0;
32
diff --git a/hw/net/can/can_sja1000.c b/hw/net/can/can_sja1000.c
37
uint32_t len = 0;
33
index XXXXXXX..XXXXXXX 100644
38
@@ -XXX,XX +XXX,XX @@ static int filter_send(MirrorState *s,
34
--- a/hw/net/can/can_sja1000.c
39
goto err;
35
+++ b/hw/net/can/can_sja1000.c
40
}
36
@@ -XXX,XX +XXX,XX @@ uint64_t can_sja_mem_read(CanSJA1000State *s, hwaddr addr, unsigned size)
41
37
return temp;
42
+ if (s->vnet_hdr) {
38
}
43
+ /*
39
44
+ * If vnet_hdr = on, we send vnet header len to make other
40
-int can_sja_can_receive(CanBusClientState *client)
45
+ * module(like colo-compare) know how to parse net
41
+bool can_sja_can_receive(CanBusClientState *client)
46
+ * packet correctly.
42
{
47
+ */
43
CanSJA1000State *s = container_of(client, CanSJA1000State, bus_client);
48
+ ssize_t vnet_hdr_len;
44
49
+
45
if (s->clock & 0x80) { /* PeliCAN Mode */
50
+ vnet_hdr_len = nf->netdev->vnet_hdr_len;
46
if (s->mode & 0x01) { /* reset mode. */
51
+
47
- return 0;
52
+ len = htonl(vnet_hdr_len);
48
+ return false;
53
+ ret = qemu_chr_fe_write_all(&s->chr_out, (uint8_t *)&len, sizeof(len));
49
}
54
+ if (ret != sizeof(len)) {
50
} else { /* BasicCAN mode */
55
+ goto err;
51
if (s->control & 0x01) {
56
+ }
52
- return 0;
57
+ }
53
+ return false;
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
}
54
}
64
}
55
}
65
56
66
- net_socket_rs_init(&s->rs, redirector_rs_finalize, false);
57
- return 1; /* always return 1, when operation mode */
67
+ net_socket_rs_init(&s->rs, redirector_rs_finalize, s->vnet_hdr);
58
+ return true; /* always return true, when operation mode */
68
59
}
69
if (s->indev) {
60
70
chr = qemu_chr_find(s->indev);
61
ssize_t can_sja_receive(CanBusClientState *client, const qemu_can_frame *frames,
71
@@ -XXX,XX +XXX,XX @@ static void filter_mirror_set_outdev(Object *obj,
62
diff --git a/hw/net/can/can_sja1000.h b/hw/net/can/can_sja1000.h
63
index XXXXXXX..XXXXXXX 100644
64
--- a/hw/net/can/can_sja1000.h
65
+++ b/hw/net/can/can_sja1000.h
66
@@ -XXX,XX +XXX,XX @@ void can_sja_disconnect(CanSJA1000State *s);
67
68
int can_sja_init(CanSJA1000State *s, qemu_irq irq);
69
70
-int can_sja_can_receive(CanBusClientState *client);
71
+bool can_sja_can_receive(CanBusClientState *client);
72
73
ssize_t can_sja_receive(CanBusClientState *client,
74
const qemu_can_frame *frames, size_t frames_cnt);
75
diff --git a/include/net/can_emu.h b/include/net/can_emu.h
76
index XXXXXXX..XXXXXXX 100644
77
--- a/include/net/can_emu.h
78
+++ b/include/net/can_emu.h
79
@@ -XXX,XX +XXX,XX @@ typedef struct CanBusClientState CanBusClientState;
80
typedef struct CanBusState CanBusState;
81
82
typedef struct CanBusClientInfo {
83
- int (*can_receive)(CanBusClientState *);
84
+ bool (*can_receive)(CanBusClientState *);
85
ssize_t (*receive)(CanBusClientState *,
86
const struct qemu_can_frame *frames, size_t frames_cnt);
87
} CanBusClientInfo;
88
diff --git a/net/can/can_socketcan.c b/net/can/can_socketcan.c
89
index XXXXXXX..XXXXXXX 100644
90
--- a/net/can/can_socketcan.c
91
+++ b/net/can/can_socketcan.c
92
@@ -XXX,XX +XXX,XX @@ static void can_host_socketcan_read(void *opaque)
72
}
93
}
73
}
94
}
74
95
75
+static bool filter_mirror_get_vnet_hdr(Object *obj, Error **errp)
96
-static int can_host_socketcan_can_receive(CanBusClientState *client)
76
+{
97
+static bool can_host_socketcan_can_receive(CanBusClientState *client)
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
{
98
{
91
MirrorState *s = FILTER_REDIRECTOR(obj);
99
- return 1;
92
@@ -XXX,XX +XXX,XX @@ static void filter_redirector_set_outdev(Object *obj,
100
+ return true;
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
}
101
}
106
102
107
static void filter_redirector_init(Object *obj)
103
static ssize_t can_host_socketcan_receive(CanBusClientState *client,
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
--
104
--
126
2.7.4
105
2.5.0
127
106
128
107
diff view generated by jsdifflib
1
From: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
1
From: Zhang Chen <chen.zhang@intel.com>
2
2
3
We add the vnet_hdr_support option for colo-compare, default is disabled.
3
The "compare_timeout" determines the maximum time to hold the primary net packet.
4
If you use virtio-net-pci or other driver needs vnet_hdr, please enable it.
4
This patch expose the "compare_timeout", make user have ability to
5
You can use it for example:
5
adjest the value according to application scenarios.
6
-object colo-compare,id=comp0,primary_in=compare0-0,secondary_in=compare1,outdev=compare_out0,vnet_hdr_support
7
6
8
COLO-compare can get vnet header length from filter,
7
QMP command demo:
9
Add vnet_hdr_len to struct packet and output packet with
8
{ "execute": "qom-get",
10
the vnet_hdr_len.
9
"arguments": { "path": "/objects/comp0",
10
"property": "compare_timeout" } }
11
11
12
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
12
{ "execute": "qom-set",
13
"arguments": { "path": "/objects/comp0",
14
"property": "compare_timeout",
15
"value": 5000} }
16
17
Signed-off-by: Zhang Chen <chen.zhang@intel.com>
13
Signed-off-by: Jason Wang <jasowang@redhat.com>
18
Signed-off-by: Jason Wang <jasowang@redhat.com>
14
---
19
---
15
net/colo-compare.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++-------
20
net/colo-compare.c | 47 +++++++++++++++++++++++++++++++++++++++++++++--
16
qemu-options.hx | 4 ++--
21
qemu-options.hx | 8 +++++---
17
2 files changed, 55 insertions(+), 9 deletions(-)
22
2 files changed, 50 insertions(+), 5 deletions(-)
18
23
19
diff --git a/net/colo-compare.c b/net/colo-compare.c
24
diff --git a/net/colo-compare.c b/net/colo-compare.c
20
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
21
--- a/net/colo-compare.c
26
--- a/net/colo-compare.c
22
+++ b/net/colo-compare.c
27
+++ b/net/colo-compare.c
28
@@ -XXX,XX +XXX,XX @@ static NotifierList colo_compare_notifiers =
29
30
/* TODO: Should be configurable */
31
#define REGULAR_PACKET_CHECK_MS 3000
32
+#define DEFAULT_TIME_OUT_MS 3000
33
34
static QemuMutex event_mtx;
35
static QemuCond event_complete_cond;
23
@@ -XXX,XX +XXX,XX @@ typedef struct CompareState {
36
@@ -XXX,XX +XXX,XX @@ typedef struct CompareState {
24
CharBackend chr_out;
25
SocketReadState pri_rs;
26
SocketReadState sec_rs;
37
SocketReadState sec_rs;
27
+ bool vnet_hdr;
38
SocketReadState notify_rs;
28
39
bool vnet_hdr;
29
/* connection list: the connections belonged to this NIC could be found
40
+ uint32_t compare_timeout;
30
* in this list.
41
31
@@ -XXX,XX +XXX,XX @@ enum {
42
/*
32
43
* Record the connection that through the NIC
33
static int compare_chr_send(CompareState *s,
44
@@ -XXX,XX +XXX,XX @@ static int colo_old_packet_check_one_conn(Connection *conn,
34
const uint8_t *buf,
45
CompareState *s)
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
{
46
{
41
@@ -XXX,XX +XXX,XX @@ static void colo_compare_connection(void *opaque, void *user_data)
47
GList *result = NULL;
42
}
48
- int64_t check_time = REGULAR_PACKET_CHECK_MS;
43
49
44
if (result) {
50
result = g_queue_find_custom(&conn->primary_list,
45
- ret = compare_chr_send(s, pkt->data, pkt->size);
51
- &check_time,
46
+ ret = compare_chr_send(s,
52
+ &s->compare_timeout,
47
+ pkt->data,
53
(GCompareFunc)colo_old_packet_check_one);
48
+ pkt->size,
54
49
+ pkt->vnet_hdr_len);
55
if (result) {
50
if (ret < 0) {
56
@@ -XXX,XX +XXX,XX @@ static void compare_set_notify_dev(Object *obj, const char *value, Error **errp)
51
error_report("colo_send_primary_packet failed");
57
s->notify_dev = g_strdup(value);
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
}
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
}
58
}
85
59
86
+static bool compare_get_vnet_hdr(Object *obj, Error **errp)
60
+static void compare_get_timeout(Object *obj, Visitor *v,
61
+ const char *name, void *opaque,
62
+ Error **errp)
87
+{
63
+{
88
+ CompareState *s = COLO_COMPARE(obj);
64
+ CompareState *s = COLO_COMPARE(obj);
65
+ uint32_t value = s->compare_timeout;
89
+
66
+
90
+ return s->vnet_hdr;
67
+ visit_type_uint32(v, name, &value, errp);
91
+}
68
+}
92
+
69
+
93
+static void compare_set_vnet_hdr(Object *obj,
70
+static void compare_set_timeout(Object *obj, Visitor *v,
94
+ bool value,
71
+ const char *name, void *opaque,
95
+ Error **errp)
72
+ Error **errp)
96
+{
73
+{
97
+ CompareState *s = COLO_COMPARE(obj);
74
+ CompareState *s = COLO_COMPARE(obj);
75
+ Error *local_err = NULL;
76
+ uint32_t value;
98
+
77
+
99
+ s->vnet_hdr = value;
78
+ visit_type_uint32(v, name, &value, &local_err);
79
+ if (local_err) {
80
+ goto out;
81
+ }
82
+ if (!value) {
83
+ error_setg(&local_err, "Property '%s.%s' requires a positive value",
84
+ object_get_typename(obj), name);
85
+ goto out;
86
+ }
87
+ s->compare_timeout = value;
88
+
89
+out:
90
+ error_propagate(errp, local_err);
100
+}
91
+}
101
+
92
+
102
static void compare_pri_rs_finalize(SocketReadState *pri_rs)
93
static void compare_pri_rs_finalize(SocketReadState *pri_rs)
103
{
94
{
104
CompareState *s = container_of(pri_rs, CompareState, pri_rs);
95
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)
96
@@ -XXX,XX +XXX,XX @@ static void colo_compare_complete(UserCreatable *uc, Error **errp)
117
return;
97
return;
118
}
98
}
119
99
120
- net_socket_rs_init(&s->pri_rs, compare_pri_rs_finalize, false);
100
+ if (!s->compare_timeout) {
121
- net_socket_rs_init(&s->sec_rs, compare_sec_rs_finalize, false);
101
+ /* Set default value to 3000 MS */
122
+ net_socket_rs_init(&s->pri_rs, compare_pri_rs_finalize, s->vnet_hdr);
102
+ s->compare_timeout = DEFAULT_TIME_OUT_MS;
123
+ net_socket_rs_init(&s->sec_rs, compare_sec_rs_finalize, s->vnet_hdr);
103
+ }
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
+
104
+
145
object_property_add_str(obj, "primary_in",
105
if (find_and_check_chardev(&chr, s->pri_indev, errp) ||
146
compare_get_pri_indev, compare_set_pri_indev,
106
!qemu_chr_fe_init(&s->chr_pri_in, chr, errp)) {
107
return;
108
@@ -XXX,XX +XXX,XX @@ static void colo_compare_init(Object *obj)
109
compare_get_notify_dev, compare_set_notify_dev,
147
NULL);
110
NULL);
148
@@ -XXX,XX +XXX,XX @@ static void colo_compare_init(Object *obj)
111
149
object_property_add_str(obj, "outdev",
112
+ object_property_add(obj, "compare_timeout", "uint32",
150
compare_get_outdev, compare_set_outdev,
113
+ compare_get_timeout,
151
NULL);
114
+ compare_set_timeout, NULL, NULL, NULL);
152
+
115
+
153
+ s->vnet_hdr = false;
116
s->vnet_hdr = false;
154
+ object_property_add_bool(obj, "vnet_hdr_support", compare_get_vnet_hdr,
117
object_property_add_bool(obj, "vnet_hdr_support", compare_get_vnet_hdr,
155
+ compare_set_vnet_hdr, NULL);
118
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
119
diff --git a/qemu-options.hx b/qemu-options.hx
160
index XXXXXXX..XXXXXXX 100644
120
index XXXXXXX..XXXXXXX 100644
161
--- a/qemu-options.hx
121
--- a/qemu-options.hx
162
+++ b/qemu-options.hx
122
+++ b/qemu-options.hx
163
@@ -XXX,XX +XXX,XX @@ Dump the network traffic on netdev @var{dev} to the file specified by
123
@@ -XXX,XX +XXX,XX @@ SRST
164
The file format is libpcap, so it can be analyzed with tools such as tcpdump
124
stored. The file format is libpcap, so it can be analyzed with
165
or Wireshark.
125
tools such as tcpdump or Wireshark.
166
126
167
-@item -object colo-compare,id=@var{id},primary_in=@var{chardevid},secondary_in=@var{chardevid},
127
- ``-object colo-compare,id=id,primary_in=chardevid,secondary_in=chardevid,outdev=chardevid,iothread=id[,vnet_hdr_support][,notify_dev=id]``
168
-outdev=@var{chardevid}
128
+ ``-object colo-compare,id=id,primary_in=chardevid,secondary_in=chardevid,outdev=chardevid,iothread=id[,vnet_hdr_support][,notify_dev=id][,compare_timeout=@var{ms}]``
169
+@item -object colo-compare,id=@var{id},primary_in=@var{chardevid},secondary_in=@var{chardevid},outdev=@var{chardevid}[,vnet_hdr_support]
129
Colo-compare gets packet from primary\_inchardevid and
170
130
secondary\_inchardevid, than compare primary packet with
171
Colo-compare gets packet from primary_in@var{chardevid} and secondary_in@var{chardevid}, than compare primary packet with
131
secondary packet. If the packets are same, we will output
172
secondary packet. If the packets are same, we will output primary
132
@@ -XXX,XX +XXX,XX @@ SRST
173
packet to outdev@var{chardevid}, else we will notify colo-frame
133
outdevchardevid. In order to improve efficiency, we need to put
174
do checkpoint and send primary packet to outdev@var{chardevid}.
134
the task of comparison in another thread. If it has the
175
+if it has the vnet_hdr_support flag, colo compare will send/recv packet with vnet_hdr_len.
135
vnet\_hdr\_support flag, colo compare will send/recv packet with
176
136
- vnet\_hdr\_len. If you want to use Xen COLO, will need the
177
we must use it with the help of filter-mirror and filter-redirector.
137
- notify\_dev to notify Xen colo-frame to do checkpoint.
178
138
+ vnet\_hdr\_len. Then compare\_timeout=@var{ms} determines the
139
+ maximum delay colo-compare wait for the packet.
140
+ If you want to use Xen COLO, will need the notify\_dev to
141
+ notify Xen colo-frame to do checkpoint.
142
143
we must use it with the help of filter-mirror and
144
filter-redirector.
179
--
145
--
180
2.7.4
146
2.5.0
181
147
182
148
diff view generated by jsdifflib
1
From: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
1
From: Zhang Chen <chen.zhang@intel.com>
2
2
3
We add the vnet_hdr_support option for filter-redirector, default is disabled.
3
The "expired_scan_cycle" determines period of scanning expired
4
If you use virtio-net-pci net driver or other driver needs vnet_hdr, please enable it.
4
primary node net packets.
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
5
10
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
6
Signed-off-by: Zhang Chen <chen.zhang@intel.com>
11
Signed-off-by: Jason Wang <jasowang@redhat.com>
7
Signed-off-by: Jason Wang <jasowang@redhat.com>
12
---
8
---
13
net/filter-mirror.c | 23 +++++++++++++++++++++++
9
net/colo-compare.c | 48 +++++++++++++++++++++++++++++++++++++++++++++---
14
qemu-options.hx | 6 +++---
10
qemu-options.hx | 4 +++-
15
2 files changed, 26 insertions(+), 3 deletions(-)
11
2 files changed, 48 insertions(+), 4 deletions(-)
16
12
17
diff --git a/net/filter-mirror.c b/net/filter-mirror.c
13
diff --git a/net/colo-compare.c b/net/colo-compare.c
18
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
19
--- a/net/filter-mirror.c
15
--- a/net/colo-compare.c
20
+++ b/net/filter-mirror.c
16
+++ b/net/colo-compare.c
21
@@ -XXX,XX +XXX,XX @@ static void filter_redirector_set_outdev(Object *obj,
17
@@ -XXX,XX +XXX,XX @@ static NotifierList colo_compare_notifiers =
22
s->outdev = g_strdup(value);
18
#define COLO_COMPARE_FREE_PRIMARY 0x01
19
#define COLO_COMPARE_FREE_SECONDARY 0x02
20
21
-/* TODO: Should be configurable */
22
#define REGULAR_PACKET_CHECK_MS 3000
23
#define DEFAULT_TIME_OUT_MS 3000
24
25
@@ -XXX,XX +XXX,XX @@ typedef struct CompareState {
26
SocketReadState notify_rs;
27
bool vnet_hdr;
28
uint32_t compare_timeout;
29
+ uint32_t expired_scan_cycle;
30
31
/*
32
* Record the connection that through the NIC
33
@@ -XXX,XX +XXX,XX @@ static void check_old_packet_regular(void *opaque)
34
/* if have old packet we will notify checkpoint */
35
colo_old_packet_check(s);
36
timer_mod(s->packet_check_timer, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) +
37
- REGULAR_PACKET_CHECK_MS);
38
+ s->expired_scan_cycle);
23
}
39
}
24
40
25
+static bool filter_redirector_get_vnet_hdr(Object *obj, Error **errp)
41
/* Public API, Used for COLO frame to notify compare event */
42
@@ -XXX,XX +XXX,XX @@ static void colo_compare_timer_init(CompareState *s)
43
SCALE_MS, check_old_packet_regular,
44
s);
45
timer_mod(s->packet_check_timer, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) +
46
- REGULAR_PACKET_CHECK_MS);
47
+ s->expired_scan_cycle);
48
}
49
50
static void colo_compare_timer_del(CompareState *s)
51
@@ -XXX,XX +XXX,XX @@ out:
52
error_propagate(errp, local_err);
53
}
54
55
+static void compare_get_expired_scan_cycle(Object *obj, Visitor *v,
56
+ const char *name, void *opaque,
57
+ Error **errp)
26
+{
58
+{
27
+ MirrorState *s = FILTER_REDIRECTOR(obj);
59
+ CompareState *s = COLO_COMPARE(obj);
60
+ uint32_t value = s->expired_scan_cycle;
28
+
61
+
29
+ return s->vnet_hdr;
62
+ visit_type_uint32(v, name, &value, errp);
30
+}
63
+}
31
+
64
+
32
+static void filter_redirector_set_vnet_hdr(Object *obj,
65
+static void compare_set_expired_scan_cycle(Object *obj, Visitor *v,
33
+ bool value,
66
+ const char *name, void *opaque,
34
+ Error **errp)
67
+ Error **errp)
35
+{
68
+{
36
+ MirrorState *s = FILTER_REDIRECTOR(obj);
69
+ CompareState *s = COLO_COMPARE(obj);
70
+ Error *local_err = NULL;
71
+ uint32_t value;
37
+
72
+
38
+ s->vnet_hdr = value;
73
+ visit_type_uint32(v, name, &value, &local_err);
74
+ if (local_err) {
75
+ goto out;
76
+ }
77
+ if (!value) {
78
+ error_setg(&local_err, "Property '%s.%s' requires a positive value",
79
+ object_get_typename(obj), name);
80
+ goto out;
81
+ }
82
+ s->expired_scan_cycle = value;
83
+
84
+out:
85
+ error_propagate(errp, local_err);
39
+}
86
+}
40
+
87
+
41
static void filter_mirror_init(Object *obj)
88
static void compare_pri_rs_finalize(SocketReadState *pri_rs)
42
{
89
{
43
MirrorState *s = FILTER_MIRROR(obj);
90
CompareState *s = container_of(pri_rs, CompareState, pri_rs);
44
@@ -XXX,XX +XXX,XX @@ static void filter_mirror_init(Object *obj)
91
@@ -XXX,XX +XXX,XX @@ static void colo_compare_complete(UserCreatable *uc, Error **errp)
45
92
s->compare_timeout = DEFAULT_TIME_OUT_MS;
46
static void filter_redirector_init(Object *obj)
93
}
47
{
94
48
+ MirrorState *s = FILTER_REDIRECTOR(obj);
95
+ if (!s->expired_scan_cycle) {
96
+ /* Set default value to 3000 MS */
97
+ s->expired_scan_cycle = REGULAR_PACKET_CHECK_MS;
98
+ }
49
+
99
+
50
object_property_add_str(obj, "indev", filter_redirector_get_indev,
100
if (find_and_check_chardev(&chr, s->pri_indev, errp) ||
51
filter_redirector_set_indev, NULL);
101
!qemu_chr_fe_init(&s->chr_pri_in, chr, errp)) {
52
object_property_add_str(obj, "outdev", filter_redirector_get_outdev,
102
return;
53
filter_redirector_set_outdev, NULL);
103
@@ -XXX,XX +XXX,XX @@ static void colo_compare_init(Object *obj)
104
compare_get_timeout,
105
compare_set_timeout, NULL, NULL, NULL);
106
107
+ object_property_add(obj, "expired_scan_cycle", "uint32",
108
+ compare_get_expired_scan_cycle,
109
+ compare_set_expired_scan_cycle, NULL, NULL, NULL);
54
+
110
+
55
+ s->vnet_hdr = false;
111
s->vnet_hdr = false;
56
+ object_property_add_bool(obj, "vnet_hdr_support",
112
object_property_add_bool(obj, "vnet_hdr_support", compare_get_vnet_hdr,
57
+ filter_redirector_get_vnet_hdr,
113
compare_set_vnet_hdr, NULL);
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
114
diff --git a/qemu-options.hx b/qemu-options.hx
63
index XXXXXXX..XXXXXXX 100644
115
index XXXXXXX..XXXXXXX 100644
64
--- a/qemu-options.hx
116
--- a/qemu-options.hx
65
+++ b/qemu-options.hx
117
+++ b/qemu-options.hx
66
@@ -XXX,XX +XXX,XX @@ queue @var{all|rx|tx} is an option that can be applied to any netfilter.
118
@@ -XXX,XX +XXX,XX @@ SRST
67
119
stored. The file format is libpcap, so it can be analyzed with
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.
120
tools such as tcpdump or Wireshark.
69
121
70
-@item -object filter-redirector,id=@var{id},netdev=@var{netdevid},indev=@var{chardevid},
122
- ``-object colo-compare,id=id,primary_in=chardevid,secondary_in=chardevid,outdev=chardevid,iothread=id[,vnet_hdr_support][,notify_dev=id][,compare_timeout=@var{ms}]``
71
-outdev=@var{chardevid}[,queue=@var{all|rx|tx}]
123
+ ``-object colo-compare,id=id,primary_in=chardevid,secondary_in=chardevid,outdev=chardevid,iothread=id[,vnet_hdr_support][,notify_dev=id][,compare_timeout=@var{ms}][,expired_scan_cycle=@var{ms}``
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]
124
Colo-compare gets packet from primary\_inchardevid and
73
125
secondary\_inchardevid, than compare primary packet with
74
filter-redirector on netdev @var{netdevid},redirect filter's net packet to chardev
126
secondary packet. If the packets are same, we will output
75
-@var{chardevid},and redirect indev's packet to filter.
127
@@ -XXX,XX +XXX,XX @@ SRST
76
+@var{chardevid},and redirect indev's packet to filter.if it has the vnet_hdr_support flag,
128
vnet\_hdr\_support flag, colo compare will send/recv packet with
77
+filter-redirector will redirect packet with vnet_hdr_len.
129
vnet\_hdr\_len. Then compare\_timeout=@var{ms} determines the
78
Create a filter-redirector we need to differ outdev id from indev id, id can not
130
maximum delay colo-compare wait for the packet.
79
be the same. we can just use indev or outdev, but at least one of indev or outdev
131
+ The expired\_scan\_cycle=@var{ms} to set the period of scanning
80
need to be specified.
132
+ expired primary node network packets.
133
If you want to use Xen COLO, will need the notify\_dev to
134
notify Xen colo-frame to do checkpoint.
135
81
--
136
--
82
2.7.4
137
2.5.0
83
138
84
139
diff view generated by jsdifflib
1
From: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
1
From: Prasad J Pandit <pjp@fedoraproject.org>
2
2
3
We add a flag to decide whether net_fill_rstate() need read
3
Tulip network driver while copying tx/rx buffers does not check
4
the vnet_hdr_len or not.
4
frame size against r/w data length. This may lead to OOB buffer
5
access. Add check to avoid it.
5
6
6
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
7
Limit iterations over descriptors to avoid potential infinite
7
Suggested-by: Jason Wang <jasowang@redhat.com>
8
loop issue in tulip_xmit_list_update.
9
10
Reported-by: Li Qiang <pangpei.lq@antfin.com>
11
Reported-by: Ziming Zhang <ezrakiez@gmail.com>
12
Reported-by: Jason Wang <jasowang@redhat.com>
13
Tested-by: Li Qiang <liq3ea@gmail.com>
14
Reviewed-by: Li Qiang <liq3ea@gmail.com>
15
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
8
Signed-off-by: Jason Wang <jasowang@redhat.com>
16
Signed-off-by: Jason Wang <jasowang@redhat.com>
9
---
17
---
10
include/net/net.h | 9 +++++++--
18
hw/net/tulip.c | 36 +++++++++++++++++++++++++++---------
11
net/colo-compare.c | 4 ++--
19
1 file changed, 27 insertions(+), 9 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
20
17
diff --git a/include/net/net.h b/include/net/net.h
21
diff --git a/hw/net/tulip.c b/hw/net/tulip.c
18
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
19
--- a/include/net/net.h
23
--- a/hw/net/tulip.c
20
+++ b/include/net/net.h
24
+++ b/hw/net/tulip.c
21
@@ -XXX,XX +XXX,XX @@ typedef struct NICState {
25
@@ -XXX,XX +XXX,XX @@ static void tulip_copy_rx_bytes(TULIPState *s, struct tulip_descriptor *desc)
22
} NICState;
26
} else {
23
27
len = s->rx_frame_len;
24
struct SocketReadState {
28
}
25
- int state; /* 0 = getting length, 1 = getting data */
29
+
26
+ /* 0 = getting length, 1 = getting vnet header length, 2 = getting data */
30
+ if (s->rx_frame_len + len > sizeof(s->rx_frame)) {
27
+ int state;
31
+ return;
28
+ /* This flag decide whether to read the vnet_hdr_len field */
32
+ }
29
+ bool vnet_hdr;
33
pci_dma_write(&s->dev, desc->buf_addr1, s->rx_frame +
30
uint32_t index;
34
(s->rx_frame_size - s->rx_frame_len), len);
31
uint32_t packet_len;
35
s->rx_frame_len -= len;
32
+ uint32_t vnet_hdr_len;
36
@@ -XXX,XX +XXX,XX @@ static void tulip_copy_rx_bytes(TULIPState *s, struct tulip_descriptor *desc)
33
uint8_t buf[NET_BUFSIZE];
37
} else {
34
SocketReadStateFinalize *finalize;
38
len = s->rx_frame_len;
35
};
39
}
36
@@ -XXX,XX +XXX,XX @@ ssize_t qemu_deliver_packet_iov(NetClientState *sender,
40
+
37
void print_net_client(Monitor *mon, NetClientState *nc);
41
+ if (s->rx_frame_len + len > sizeof(s->rx_frame)) {
38
void hmp_info_network(Monitor *mon, const QDict *qdict);
42
+ return;
39
void net_socket_rs_init(SocketReadState *rs,
43
+ }
40
- SocketReadStateFinalize *finalize);
44
pci_dma_write(&s->dev, desc->buf_addr2, s->rx_frame +
41
+ SocketReadStateFinalize *finalize,
45
(s->rx_frame_size - s->rx_frame_len), len);
42
+ bool vnet_hdr);
46
s->rx_frame_len -= len;
43
47
@@ -XXX,XX +XXX,XX @@ static ssize_t tulip_receive(TULIPState *s, const uint8_t *buf, size_t size)
44
/* NIC info */
48
45
49
trace_tulip_receive(buf, size);
46
diff --git a/net/colo-compare.c b/net/colo-compare.c
50
47
index XXXXXXX..XXXXXXX 100644
51
- if (size < 14 || size > 2048 || s->rx_frame_len || tulip_rx_stopped(s)) {
48
--- a/net/colo-compare.c
52
+ if (size < 14 || size > sizeof(s->rx_frame) - 4
49
+++ b/net/colo-compare.c
53
+ || s->rx_frame_len || tulip_rx_stopped(s)) {
50
@@ -XXX,XX +XXX,XX @@ static void colo_compare_complete(UserCreatable *uc, Error **errp)
54
return 0;
55
}
56
57
@@ -XXX,XX +XXX,XX @@ static ssize_t tulip_receive_nc(NetClientState *nc,
58
return tulip_receive(qemu_get_nic_opaque(nc), buf, size);
59
}
60
61
-
62
static NetClientInfo net_tulip_info = {
63
.type = NET_CLIENT_DRIVER_NIC,
64
.size = sizeof(NICState),
65
@@ -XXX,XX +XXX,XX @@ static void tulip_tx(TULIPState *s, struct tulip_descriptor *desc)
66
if ((s->csr[6] >> CSR6_OM_SHIFT) & CSR6_OM_MASK) {
67
/* Internal or external Loopback */
68
tulip_receive(s, s->tx_frame, s->tx_frame_len);
69
- } else {
70
+ } else if (s->tx_frame_len <= sizeof(s->tx_frame)) {
71
qemu_send_packet(qemu_get_queue(s->nic),
72
s->tx_frame, s->tx_frame_len);
73
}
74
@@ -XXX,XX +XXX,XX @@ static void tulip_tx(TULIPState *s, struct tulip_descriptor *desc)
75
}
76
}
77
78
-static void tulip_copy_tx_buffers(TULIPState *s, struct tulip_descriptor *desc)
79
+static int tulip_copy_tx_buffers(TULIPState *s, struct tulip_descriptor *desc)
80
{
81
int len1 = (desc->control >> TDES1_BUF1_SIZE_SHIFT) & TDES1_BUF1_SIZE_MASK;
82
int len2 = (desc->control >> TDES1_BUF2_SIZE_SHIFT) & TDES1_BUF2_SIZE_MASK;
83
84
+ if (s->tx_frame_len + len1 > sizeof(s->tx_frame)) {
85
+ return -1;
86
+ }
87
if (len1) {
88
pci_dma_read(&s->dev, desc->buf_addr1,
89
s->tx_frame + s->tx_frame_len, len1);
90
s->tx_frame_len += len1;
91
}
92
93
+ if (s->tx_frame_len + len2 > sizeof(s->tx_frame)) {
94
+ return -1;
95
+ }
96
if (len2) {
97
pci_dma_read(&s->dev, desc->buf_addr2,
98
s->tx_frame + s->tx_frame_len, len2);
99
s->tx_frame_len += len2;
100
}
101
desc->status = (len1 + len2) ? 0 : 0x7fffffff;
102
+
103
+ return 0;
104
}
105
106
static void tulip_setup_filter_addr(TULIPState *s, uint8_t *buf, int n)
107
@@ -XXX,XX +XXX,XX @@ static uint32_t tulip_ts(TULIPState *s)
108
109
static void tulip_xmit_list_update(TULIPState *s)
110
{
111
+#define TULIP_DESC_MAX 128
112
+ uint8_t i = 0;
113
struct tulip_descriptor desc;
114
115
if (tulip_ts(s) != CSR5_TS_SUSPENDED) {
51
return;
116
return;
52
}
117
}
53
118
54
- net_socket_rs_init(&s->pri_rs, compare_pri_rs_finalize);
119
- for (;;) {
55
- net_socket_rs_init(&s->sec_rs, compare_sec_rs_finalize);
120
+ for (i = 0; i < TULIP_DESC_MAX; i++) {
56
+ net_socket_rs_init(&s->pri_rs, compare_pri_rs_finalize, false);
121
tulip_desc_read(s, s->current_tx_desc, &desc);
57
+ net_socket_rs_init(&s->sec_rs, compare_sec_rs_finalize, false);
122
tulip_dump_tx_descriptor(s, &desc);
58
123
59
g_queue_init(&s->conn_list);
124
@@ -XXX,XX +XXX,XX @@ static void tulip_xmit_list_update(TULIPState *s)
60
125
s->tx_frame_len = 0;
61
diff --git a/net/filter-mirror.c b/net/filter-mirror.c
126
}
62
index XXXXXXX..XXXXXXX 100644
127
63
--- a/net/filter-mirror.c
128
- tulip_copy_tx_buffers(s, &desc);
64
+++ b/net/filter-mirror.c
129
-
65
@@ -XXX,XX +XXX,XX @@ static void filter_redirector_setup(NetFilterState *nf, Error **errp)
130
- if (desc.control & TDES1_LS) {
66
}
131
- tulip_tx(s, &desc);
67
}
132
+ if (!tulip_copy_tx_buffers(s, &desc)) {
68
133
+ if (desc.control & TDES1_LS) {
69
- net_socket_rs_init(&s->rs, redirector_rs_finalize);
134
+ tulip_tx(s, &desc);
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
+ }
135
+ }
120
}
136
}
121
break;
137
}
122
case 1:
138
tulip_desc_write(s, s->current_tx_desc, &desc);
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
--
139
--
183
2.7.4
140
2.5.0
184
141
185
142
diff view generated by jsdifflib
1
From: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
1
From: Peter Maydell <peter.maydell@linaro.org>
2
2
3
This patch change the filter_send() parameter from CharBackend to MirrorState,
3
Coverity points out (CID 1421926) that the read code for
4
we can get more information like vnet_hdr(We use it to support packet with vnet_header).
4
REG_ADDR_HIGH reads off the end of the buffer, because it does a
5
32-bit read from byte 4 of a 6-byte buffer.
5
6
6
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
7
The code also has an endianness issue for both REG_ADDR_HIGH and
8
REG_ADDR_LOW, because it will do the wrong thing on a big-endian
9
host.
10
11
Rewrite the read code to use ldl_le_p() and lduw_le_p() to fix this;
12
the write code is not incorrect, but for consistency we make it use
13
stl_le_p() and stw_le_p().
14
15
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
16
Tested-by: Niek Linnenbank <nieklinnenbank@gmail.com>
17
Reviewed-by: Niek Linnenbank <nieklinnenbank@gmail.com>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Jason Wang <jasowang@redhat.com>
19
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
---
20
---
9
net/filter-mirror.c | 10 +++++-----
21
hw/net/allwinner-sun8i-emac.c | 12 ++++--------
10
1 file changed, 5 insertions(+), 5 deletions(-)
22
1 file changed, 4 insertions(+), 8 deletions(-)
11
23
12
diff --git a/net/filter-mirror.c b/net/filter-mirror.c
24
diff --git a/hw/net/allwinner-sun8i-emac.c b/hw/net/allwinner-sun8i-emac.c
13
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
14
--- a/net/filter-mirror.c
26
--- a/hw/net/allwinner-sun8i-emac.c
15
+++ b/net/filter-mirror.c
27
+++ b/hw/net/allwinner-sun8i-emac.c
16
@@ -XXX,XX +XXX,XX @@ typedef struct MirrorState {
28
@@ -XXX,XX +XXX,XX @@ static uint64_t allwinner_sun8i_emac_read(void *opaque, hwaddr offset,
17
SocketReadState rs;
29
value = s->mii_data;
18
} MirrorState;
30
break;
19
31
case REG_ADDR_HIGH: /* MAC Address High */
20
-static int filter_send(CharBackend *chr_out,
32
- value = *(((uint32_t *) (s->conf.macaddr.a)) + 1);
21
+static int filter_send(MirrorState *s,
33
+ value = lduw_le_p(s->conf.macaddr.a + 4);
22
const struct iovec *iov,
34
break;
23
int iovcnt)
35
case REG_ADDR_LOW: /* MAC Address Low */
24
{
36
- value = *(uint32_t *) (s->conf.macaddr.a);
25
@@ -XXX,XX +XXX,XX @@ static int filter_send(CharBackend *chr_out,
37
+ value = ldl_le_p(s->conf.macaddr.a);
26
}
38
break;
27
39
case REG_TX_DMA_STA: /* Transmit DMA Status */
28
len = htonl(size);
40
break;
29
- ret = qemu_chr_fe_write_all(chr_out, (uint8_t *)&len, sizeof(len));
41
@@ -XXX,XX +XXX,XX @@ static void allwinner_sun8i_emac_write(void *opaque, hwaddr offset,
30
+ ret = qemu_chr_fe_write_all(&s->chr_out, (uint8_t *)&len, sizeof(len));
42
s->mii_data = value;
31
if (ret != sizeof(len)) {
43
break;
32
goto err;
44
case REG_ADDR_HIGH: /* MAC Address High */
33
}
45
- s->conf.macaddr.a[4] = (value & 0xff);
34
46
- s->conf.macaddr.a[5] = (value & 0xff00) >> 8;
35
buf = g_malloc(size);
47
+ stw_le_p(s->conf.macaddr.a + 4, value);
36
iov_to_buf(iov, iovcnt, 0, buf, size);
48
break;
37
- ret = qemu_chr_fe_write_all(chr_out, (uint8_t *)buf, size);
49
case REG_ADDR_LOW: /* MAC Address Low */
38
+ ret = qemu_chr_fe_write_all(&s->chr_out, (uint8_t *)buf, size);
50
- s->conf.macaddr.a[0] = (value & 0xff);
39
g_free(buf);
51
- s->conf.macaddr.a[1] = (value & 0xff00) >> 8;
40
if (ret != size) {
52
- s->conf.macaddr.a[2] = (value & 0xff0000) >> 16;
41
goto err;
53
- s->conf.macaddr.a[3] = (value & 0xff000000) >> 24;
42
@@ -XXX,XX +XXX,XX @@ static ssize_t filter_mirror_receive_iov(NetFilterState *nf,
54
+ stl_le_p(s->conf.macaddr.a, value);
43
MirrorState *s = FILTER_MIRROR(nf);
55
break;
44
int ret;
56
case REG_TX_DMA_STA: /* Transmit DMA Status */
45
57
case REG_TX_CUR_DESC: /* Transmit Current Descriptor */
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
--
58
--
61
2.7.4
59
2.5.0
62
60
63
61
diff view generated by jsdifflib
1
From: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
1
From: Li Qiang <liq3ea@163.com>
2
2
3
We add the vnet_hdr_support option for filter-rewriter, default is disabled.
3
The tulip networking card emulation has an OOB issue in
4
If you use virtio-net-pci or other driver needs vnet_hdr, please enable it.
4
'tulip_copy_tx_buffers' when the guest provide malformed descriptor.
5
You can use it for example:
5
This test will trigger a ASAN heap overflow crash. To trigger this
6
-object filter-rewriter,id=rew0,netdev=hn0,queue=all,vnet_hdr_support
6
issue we can construct the data as following:
7
7
8
We get the vnet_hdr_len from NetClientState that make us
8
1. construct a 'tulip_descriptor'. Its control is set to
9
parse net packet correctly.
9
'0x7ff | 0x7ff << 11', this will make the 'tulip_copy_tx_buffers's
10
'len1' and 'len2' to 0x7ff(2047). So 'len1+len2' will overflow
11
'TULIPState's 'tx_frame' field. This descriptor's 'buf_addr1' and
12
'buf_addr2' should set to a guest address.
10
13
11
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
14
2. write this descriptor to tulip device's CSR4 register. This will
15
set the 'TULIPState's 'current_tx_desc' field.
16
17
3. write 'CSR6_ST' to tulip device's CSR6 register. This will trigger
18
'tulip_xmit_list_update' and finally calls 'tulip_copy_tx_buffers'.
19
20
Following shows the backtrack of crash:
21
22
==31781==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x628000007cd0 at pc 0x7fe03c5a077a bp 0x7fff05b46770 sp 0x7fff05b45f18
23
WRITE of size 2047 at 0x628000007cd0 thread T0
24
#0 0x7fe03c5a0779 (/usr/lib/x86_64-linux-gnu/libasan.so.4+0x79779)
25
#1 0x5575fb6daa6a in flatview_read_continue /home/test/qemu/exec.c:3194
26
#2 0x5575fb6daccb in flatview_read /home/test/qemu/exec.c:3227
27
#3 0x5575fb6dae66 in address_space_read_full /home/test/qemu/exec.c:3240
28
#4 0x5575fb6db0cb in address_space_rw /home/test/qemu/exec.c:3268
29
#5 0x5575fbdfd460 in dma_memory_rw_relaxed /home/test/qemu/include/sysemu/dma.h:87
30
#6 0x5575fbdfd4b5 in dma_memory_rw /home/test/qemu/include/sysemu/dma.h:110
31
#7 0x5575fbdfd866 in pci_dma_rw /home/test/qemu/include/hw/pci/pci.h:787
32
#8 0x5575fbdfd8a3 in pci_dma_read /home/test/qemu/include/hw/pci/pci.h:794
33
#9 0x5575fbe02761 in tulip_copy_tx_buffers hw/net/tulip.c:585
34
#10 0x5575fbe0366b in tulip_xmit_list_update hw/net/tulip.c:678
35
#11 0x5575fbe04073 in tulip_write hw/net/tulip.c:783
36
37
Signed-off-by: Li Qiang <liq3ea@163.com>
12
Signed-off-by: Jason Wang <jasowang@redhat.com>
38
Signed-off-by: Jason Wang <jasowang@redhat.com>
13
---
39
---
14
net/filter-rewriter.c | 37 ++++++++++++++++++++++++++++++++++++-
40
tests/qtest/Makefile.include | 1 +
15
qemu-options.hx | 4 ++--
41
tests/qtest/tulip-test.c | 91 ++++++++++++++++++++++++++++++++++++++++++++
16
2 files changed, 38 insertions(+), 3 deletions(-)
42
2 files changed, 92 insertions(+)
43
create mode 100644 tests/qtest/tulip-test.c
17
44
18
diff --git a/net/filter-rewriter.c b/net/filter-rewriter.c
45
diff --git a/tests/qtest/Makefile.include b/tests/qtest/Makefile.include
19
index XXXXXXX..XXXXXXX 100644
46
index XXXXXXX..XXXXXXX 100644
20
--- a/net/filter-rewriter.c
47
--- a/tests/qtest/Makefile.include
21
+++ b/net/filter-rewriter.c
48
+++ b/tests/qtest/Makefile.include
49
@@ -XXX,XX +XXX,XX @@ qos-test-obj-y += tests/qtest/es1370-test.o
50
qos-test-obj-y += tests/qtest/ipoctal232-test.o
51
qos-test-obj-y += tests/qtest/megasas-test.o
52
qos-test-obj-y += tests/qtest/ne2000-test.o
53
+qos-test-obj-y += tests/qtest/tulip-test.o
54
qos-test-obj-y += tests/qtest/nvme-test.o
55
qos-test-obj-y += tests/qtest/pca9552-test.o
56
qos-test-obj-y += tests/qtest/pci-test.o
57
diff --git a/tests/qtest/tulip-test.c b/tests/qtest/tulip-test.c
58
new file mode 100644
59
index XXXXXXX..XXXXXXX
60
--- /dev/null
61
+++ b/tests/qtest/tulip-test.c
22
@@ -XXX,XX +XXX,XX @@
62
@@ -XXX,XX +XXX,XX @@
23
#include "qemu-common.h"
63
+/*
24
#include "qapi/error.h"
64
+ * QTest testcase for DEC/Intel Tulip 21143
25
#include "qapi/qmp/qerror.h"
65
+ *
26
+#include "qemu/error-report.h"
66
+ * Copyright (c) 2020 Li Qiang <liq3ea@gmail.com>
27
#include "qapi-visit.h"
67
+ *
28
#include "qom/object.h"
68
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
29
#include "qemu/main-loop.h"
69
+ * See the COPYING file in the top-level directory.
30
@@ -XXX,XX +XXX,XX @@ typedef struct RewriterState {
70
+ */
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
+
71
+
48
+ if (s->vnet_hdr) {
72
+#include "qemu/osdep.h"
49
+ vnet_hdr_len = nf->netdev->vnet_hdr_len;
73
+#include "libqtest.h"
74
+#include "qemu/module.h"
75
+#include "libqos/qgraph.h"
76
+#include "libqos/pci.h"
77
+#include "qemu/bitops.h"
78
+#include "hw/net/tulip.h"
79
+
80
+typedef struct QTulip_pci QTulip_pci;
81
+
82
+struct QTulip_pci {
83
+ QOSGraphObject obj;
84
+ QPCIDevice dev;
85
+};
86
+
87
+static void *tulip_pci_get_driver(void *obj, const char *interface)
88
+{
89
+ QTulip_pci *tulip_pci = obj;
90
+
91
+ if (!g_strcmp0(interface, "pci-device")) {
92
+ return &tulip_pci->dev;
50
+ }
93
+ }
51
+
94
+
52
+ pkt = packet_new(buf, size, vnet_hdr_len);
95
+ fprintf(stderr, "%s not present in tulip_pci\n", interface);
53
g_free(buf);
96
+ g_assert_not_reached();
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
}
59
60
+static bool filter_rewriter_get_vnet_hdr(Object *obj, Error **errp)
61
+{
62
+ RewriterState *s = FILTER_COLO_REWRITER(obj);
63
+
64
+ return s->vnet_hdr;
65
+}
97
+}
66
+
98
+
67
+static void filter_rewriter_set_vnet_hdr(Object *obj,
99
+static void *tulip_pci_create(void *pci_bus, QGuestAllocator *alloc, void *addr)
68
+ bool value,
69
+ Error **errp)
70
+{
100
+{
71
+ RewriterState *s = FILTER_COLO_REWRITER(obj);
101
+ QTulip_pci *tulip_pci = g_new0(QTulip_pci, 1);
102
+ QPCIBus *bus = pci_bus;
72
+
103
+
73
+ s->vnet_hdr = value;
104
+ qpci_device_init(&tulip_pci->dev, bus, addr);
105
+ tulip_pci->obj.get_driver = tulip_pci_get_driver;
106
+
107
+ return &tulip_pci->obj;
74
+}
108
+}
75
+
109
+
76
+static void filter_rewriter_init(Object *obj)
110
+static void tulip_large_tx(void *obj, void *data, QGuestAllocator *alloc)
77
+{
111
+{
78
+ RewriterState *s = FILTER_COLO_REWRITER(obj);
112
+ QTulip_pci *tulip_pci = obj;
113
+ QPCIDevice *dev = &tulip_pci->dev;
114
+ QPCIBar bar;
115
+ struct tulip_descriptor context;
116
+ char guest_data[4096];
117
+ uint64_t context_pa;
118
+ uint64_t guest_pa;
79
+
119
+
80
+ s->vnet_hdr = false;
120
+ qpci_device_enable(dev);
81
+ object_property_add_bool(obj, "vnet_hdr_support",
121
+ bar = qpci_iomap(dev, 0, NULL);
82
+ filter_rewriter_get_vnet_hdr,
122
+ context_pa = guest_alloc(alloc, sizeof(context));
83
+ filter_rewriter_set_vnet_hdr, NULL);
123
+ guest_pa = guest_alloc(alloc, 4096);
124
+ memset(guest_data, 'A', sizeof(guest_data));
125
+ context.status = TDES0_OWN;
126
+ context.control = TDES1_BUF2_SIZE_MASK << TDES1_BUF2_SIZE_SHIFT |
127
+ TDES1_BUF1_SIZE_MASK << TDES1_BUF1_SIZE_SHIFT;
128
+ context.buf_addr2 = guest_pa;
129
+ context.buf_addr1 = guest_pa;
130
+
131
+ qtest_memwrite(dev->bus->qts, context_pa, &context, sizeof(context));
132
+ qtest_memwrite(dev->bus->qts, guest_pa, guest_data, sizeof(guest_data));
133
+ qpci_io_writel(dev, bar, 0x20, context_pa);
134
+ qpci_io_writel(dev, bar, 0x30, CSR6_ST);
135
+ guest_free(alloc, context_pa);
136
+ guest_free(alloc, guest_pa);
84
+}
137
+}
85
+
138
+
86
static void colo_rewriter_class_init(ObjectClass *oc, void *data)
139
+static void tulip_register_nodes(void)
87
{
140
+{
88
NetFilterClass *nfc = NETFILTER_CLASS(oc);
141
+ QOSGraphEdgeOptions opts = {
89
@@ -XXX,XX +XXX,XX @@ static const TypeInfo colo_rewriter_info = {
142
+ .extra_device_opts = "addr=04.0",
90
.name = TYPE_FILTER_REWRITER,
143
+ };
91
.parent = TYPE_NETFILTER,
144
+ add_qpci_address(&opts, &(QPCIAddress) { .devfn = QPCI_DEVFN(4, 0) });
92
.class_init = colo_rewriter_class_init,
145
+
93
+ .instance_init = filter_rewriter_init,
146
+ qos_node_create_driver("tulip", tulip_pci_create);
94
.instance_size = sizeof(RewriterState),
147
+ qos_node_consumes("tulip", "pci-bus", &opts);
95
};
148
+ qos_node_produces("tulip", "pci-device");
96
149
+
97
diff --git a/qemu-options.hx b/qemu-options.hx
150
+ qos_add_test("tulip_large_tx", "tulip", tulip_large_tx, NULL);
98
index XXXXXXX..XXXXXXX 100644
151
+}
99
--- a/qemu-options.hx
152
+
100
+++ b/qemu-options.hx
153
+libqos_init(tulip_register_nodes);
101
@@ -XXX,XX +XXX,XX @@ Create a filter-redirector we need to differ outdev id from indev id, id can not
102
be the same. we can just use indev or outdev, but at least one of indev or outdev
103
need to be specified.
104
105
-@item -object filter-rewriter,id=@var{id},netdev=@var{netdevid}[,queue=@var{all|rx|tx}]
106
+@item -object filter-rewriter,id=@var{id},netdev=@var{netdevid},queue=@var{all|rx|tx},[vnet_hdr_support]
107
108
Filter-rewriter is a part of COLO project.It will rewrite tcp packet to
109
secondary from primary to keep secondary tcp connection,and rewrite
110
tcp packet to primary from secondary make tcp packet can be handled by
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
--
154
--
117
2.7.4
155
2.5.0
118
156
119
157
diff view generated by jsdifflib