1
The following changes since commit 23895cbd82be95428e90168b12e925d0d3ca2f06:
1
The following changes since commit e81eb5e6d108008445821e4f891fb9563016c71b:
2
2
3
Merge remote-tracking branch 'remotes/awilliam/tags/vfio-update-20201123.0' into staging (2020-11-23 18:51:13 +0000)
3
Merge remote-tracking branch 'remotes/bonzini-gitlab/tags/for-upstream' into staging (2021-01-23 22:34:21 +0000)
4
4
5
are available in the git repository at:
5
are available in the git repository at:
6
6
7
https://github.com/jasowang/qemu.git tags/net-pull-request
7
https://github.com/jasowang/qemu.git tags/net-pull-request
8
8
9
for you to fetch changes up to 9925990d01a92564af55f6f69d0f5f59b47609b1:
9
for you to fetch changes up to f574633529926697ced51b6865e5c50bbb78bf1b:
10
10
11
net: Use correct default-path macro for downscript (2020-11-24 10:40:17 +0800)
11
net: checksum: Introduce fine control over checksum type (2021-01-25 17:04:56 +0800)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
14
15
----------------------------------------------------------------
15
----------------------------------------------------------------
16
Keqian Zhu (1):
16
Bin Meng (1):
17
net: Use correct default-path macro for downscript
17
net: checksum: Introduce fine control over checksum type
18
18
19
Paolo Bonzini (1):
19
Guishan Qin (1):
20
net: do not exit on "netdev_add help" monitor command
20
net: checksum: Add IP header checksum calculation
21
21
22
Prasad J Pandit (1):
22
Markus Armbruster (1):
23
hw/net/e1000e: advance desc_offset in case of null descriptor
23
net: Fix handling of id in netdev_add and netdev_del
24
24
25
Yuri Benditovich (1):
25
Markus Carlstedt (1):
26
net: purge queued rx packets on queue deletion
26
net: checksum: Skip fragmented IP packets
27
27
28
yuanjungong (1):
28
hw/net/allwinner-sun8i-emac.c | 2 +-
29
tap: fix a memory leak
29
hw/net/cadence_gem.c | 2 +-
30
30
hw/net/fsl_etsec/rings.c | 18 +++++++++---------
31
hw/net/e1000e_core.c | 8 +++---
31
hw/net/ftgmac100.c | 13 ++++++++++++-
32
include/net/net.h | 1 +
32
hw/net/imx_fec.c | 20 ++++++++------------
33
monitor/hmp-cmds.c | 6 ++++
33
hw/net/virtio-net.c | 2 +-
34
net/net.c | 80 +++++++++++++++++++++++++++-------------------------
34
hw/net/xen_nic.c | 2 +-
35
net/tap.c | 5 +++-
35
include/net/checksum.h | 7 ++++++-
36
5 files changed, 57 insertions(+), 43 deletions(-)
36
net/checksum.c | 24 +++++++++++++++++++++---
37
net/filter-rewriter.c | 4 ++--
38
net/net.c | 20 ++++++++++++++++++--
39
11 files changed, 80 insertions(+), 34 deletions(-)
37
40
38
41
diff view generated by jsdifflib
Deleted patch
1
From: Prasad J Pandit <pjp@fedoraproject.org>
2
1
3
While receiving packets via e1000e_write_packet_to_guest() routine,
4
'desc_offset' is advanced only when RX descriptor is processed. And
5
RX descriptor is not processed if it has NULL buffer address.
6
This may lead to an infinite loop condition. Increament 'desc_offset'
7
to process next descriptor in the ring to avoid infinite loop.
8
9
Reported-by: Cheol-woo Myung <330cjfdn@gmail.com>
10
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
11
Signed-off-by: Jason Wang <jasowang@redhat.com>
12
---
13
hw/net/e1000e_core.c | 8 ++++----
14
1 file changed, 4 insertions(+), 4 deletions(-)
15
16
diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/net/e1000e_core.c
19
+++ b/hw/net/e1000e_core.c
20
@@ -XXX,XX +XXX,XX @@ e1000e_write_packet_to_guest(E1000ECore *core, struct NetRxPkt *pkt,
21
(const char *) &fcs_pad, e1000x_fcs_len(core->mac));
22
}
23
}
24
- desc_offset += desc_size;
25
- if (desc_offset >= total_size) {
26
- is_last = true;
27
- }
28
} else { /* as per intel docs; skip descriptors with null buf addr */
29
trace_e1000e_rx_null_descriptor();
30
}
31
+ desc_offset += desc_size;
32
+ if (desc_offset >= total_size) {
33
+ is_last = true;
34
+ }
35
36
e1000e_write_rx_descr(core, desc, is_last ? core->rx_pkt : NULL,
37
rss_info, do_ps ? ps_hdr_len : 0, &bastate.written);
38
--
39
2.7.4
40
41
diff view generated by jsdifflib
1
From: Yuri Benditovich <yuri.benditovich@daynix.com>
1
From: Markus Armbruster <armbru@redhat.com>
2
2
3
https://bugzilla.redhat.com/show_bug.cgi?id=1829272
3
CLI -netdev accumulates in option group "netdev".
4
When deleting queue pair, purge pending RX packets if any.
5
Example of problematic flow:
6
1. Bring up q35 VM with tap (vhost off) and virtio-net or e1000e
7
2. Run ping flood to the VM NIC ( 1 ms interval)
8
3. Hot unplug the NIC device (device_del)
9
During unplug process one or more packets come, the NIC
10
can't receive, tap disables read_poll
11
4. Hot plug the device (device_add) with the same netdev
12
The tap stays with read_poll disabled and does not receive
13
any packets anymore (tap_send never triggered)
14
4
15
Signed-off-by: Yuri Benditovich <yuri.benditovich@daynix.com>
5
Before commit 08712fcb85 "net: Track netdevs in NetClientState rather
6
than QemuOpt", netdev_add added to the option group, and netdev_del
7
removed from it, both HMP and QMP. Thus, every netdev had a
8
corresponding QemuOpts in this option group.
9
10
Commit 08712fcb85 dropped this for QMP netdev_add and both netdev_del.
11
Now a netdev has a corresponding QemuOpts only when it was created
12
with CLI or HMP. Two issues:
13
14
* QMP and HMP netdev_del can leave QemuOpts behind, breaking HMP
15
netdev_add. Reproducer:
16
17
$ qemu-system-x86_64 -S -display none -nodefaults -monitor stdio
18
QEMU 5.1.92 monitor - type 'help' for more information
19
(qemu) netdev_add user,id=net0
20
(qemu) info network
21
net0: index=0,type=user,net=10.0.2.0,restrict=off
22
(qemu) netdev_del net0
23
(qemu) info network
24
(qemu) netdev_add user,id=net0
25
upstream-qemu: Duplicate ID 'net0' for netdev
26
Try "help netdev_add" for more information
27
28
Fix by restoring the QemuOpts deletion in qmp_netdev_del(), but with
29
a guard, because the QemuOpts need not exist.
30
31
* QMP netdev_add loses its "no duplicate ID" check. Reproducer:
32
33
$ qemu-system-x86_64 -S -display none -qmp stdio
34
{"QMP": {"version": {"qemu": {"micro": 92, "minor": 1, "major": 5}, "package": "v5.2.0-rc2-1-g02c1f0142c"}, "capabilities": ["oob"]}}
35
{"execute": "qmp_capabilities"}
36
{"return": {}}
37
{"execute": "netdev_add", "arguments": {"type": "user", "id":"net0"}}
38
{"return": {}}
39
{"execute": "netdev_add", "arguments": {"type": "user", "id":"net0"}}
40
{"return": {}}
41
42
Fix by adding a duplicate ID check to net_client_init1() to replace
43
the lost one. The check is redundant for callers where QemuOpts
44
still checks, i.e. for CLI and HMP.
45
46
Reported-by: Andrew Melnichenko <andrew@daynix.com>
47
Fixes: 08712fcb851034228b61f75bd922863a984a4f60
48
Cc: qemu-stable@nongnu.org
49
Signed-off-by: Markus Armbruster <armbru@redhat.com>
50
Reviewed-by: Eric Blake <eblake@redhat.com>
16
Signed-off-by: Jason Wang <jasowang@redhat.com>
51
Signed-off-by: Jason Wang <jasowang@redhat.com>
17
---
52
---
18
net/net.c | 12 ++++++++----
53
net/net.c | 20 ++++++++++++++++++--
19
1 file changed, 8 insertions(+), 4 deletions(-)
54
1 file changed, 18 insertions(+), 2 deletions(-)
20
55
21
diff --git a/net/net.c b/net/net.c
56
diff --git a/net/net.c b/net/net.c
22
index XXXXXXX..XXXXXXX 100644
57
index XXXXXXX..XXXXXXX 100644
23
--- a/net/net.c
58
--- a/net/net.c
24
+++ b/net/net.c
59
+++ b/net/net.c
25
@@ -XXX,XX +XXX,XX @@ void qemu_del_nic(NICState *nic)
60
@@ -XXX,XX +XXX,XX @@ static int (* const net_client_init_fun[NET_CLIENT_DRIVER__MAX])(
26
61
static int net_client_init1(const Netdev *netdev, bool is_netdev, Error **errp)
27
qemu_macaddr_set_free(&nic->conf->macaddr);
62
{
28
63
NetClientState *peer = NULL;
29
- /* If this is a peer NIC and peer has already been deleted, free it now. */
64
+ NetClientState *nc;
30
- if (nic->peer_deleted) {
65
31
- for (i = 0; i < queues; i++) {
66
if (is_netdev) {
32
- qemu_free_net_client(qemu_get_subqueue(nic, i)->peer);
67
if (netdev->type == NET_CLIENT_DRIVER_NIC ||
33
+ for (i = 0; i < queues; i++) {
68
@@ -XXX,XX +XXX,XX @@ static int net_client_init1(const Netdev *netdev, bool is_netdev, Error **errp)
34
+ NetClientState *nc = qemu_get_subqueue(nic, i);
35
+ /* If this is a peer NIC and peer has already been deleted, free it now. */
36
+ if (nic->peer_deleted) {
37
+ qemu_free_net_client(nc->peer);
38
+ } else if (nc->peer) {
39
+ /* if there are RX packets pending, complete them */
40
+ qemu_purge_queued_packets(nc->peer);
41
}
69
}
42
}
70
}
43
71
72
+ nc = qemu_find_netdev(netdev->id);
73
+ if (nc) {
74
+ error_setg(errp, "Duplicate ID '%s'", netdev->id);
75
+ return -1;
76
+ }
77
+
78
if (net_client_init_fun[netdev->type](netdev, netdev->id, peer, errp) < 0) {
79
/* FIXME drop when all init functions store an Error */
80
if (errp && !*errp) {
81
@@ -XXX,XX +XXX,XX @@ static int net_client_init1(const Netdev *netdev, bool is_netdev, Error **errp)
82
}
83
84
if (is_netdev) {
85
- NetClientState *nc;
86
-
87
nc = qemu_find_netdev(netdev->id);
88
assert(nc);
89
nc->is_netdev = true;
90
@@ -XXX,XX +XXX,XX @@ void qmp_netdev_add(Netdev *netdev, Error **errp)
91
void qmp_netdev_del(const char *id, Error **errp)
92
{
93
NetClientState *nc;
94
+ QemuOpts *opts;
95
96
nc = qemu_find_netdev(id);
97
if (!nc) {
98
@@ -XXX,XX +XXX,XX @@ void qmp_netdev_del(const char *id, Error **errp)
99
}
100
101
qemu_del_net_client(nc);
102
+
103
+ /*
104
+ * Wart: we need to delete the QemuOpts associated with netdevs
105
+ * created via CLI or HMP, to avoid bogus "Duplicate ID" errors in
106
+ * HMP netdev_add.
107
+ */
108
+ opts = qemu_opts_find(qemu_find_opts("netdev"), id);
109
+ if (opts) {
110
+ qemu_opts_del(opts);
111
+ }
112
}
113
114
static void netfilter_print_info(Monitor *mon, NetFilterState *nf)
44
--
115
--
45
2.7.4
116
2.7.4
46
117
47
118
diff view generated by jsdifflib
1
From: Keqian Zhu <zhukeqian1@huawei.com>
1
From: Markus Carlstedt <markus.carlstedt@windriver.com>
2
2
3
Fixes: 63c4db4c2e6d (net: relocate paths to helpers and scripts)
3
To calculate the TCP/UDP checksum we need the whole datagram. Unless
4
Signed-off-by: Keqian Zhu <zhukeqian1@huawei.com>
4
the hardware has some logic to collect all fragments before sending
5
the whole datagram first, it can only be done by the network stack,
6
which is normally the case for the NICs we have seen so far.
7
8
Skip these fragmented IP packets to avoid checksum corruption.
9
10
Signed-off-by: Markus Carlstedt <markus.carlstedt@windriver.com>
11
Signed-off-by: Bin Meng <bin.meng@windriver.com>
5
Signed-off-by: Jason Wang <jasowang@redhat.com>
12
Signed-off-by: Jason Wang <jasowang@redhat.com>
6
---
13
---
7
net/tap.c | 3 ++-
14
net/checksum.c | 4 ++++
8
1 file changed, 2 insertions(+), 1 deletion(-)
15
1 file changed, 4 insertions(+)
9
16
10
diff --git a/net/tap.c b/net/tap.c
17
diff --git a/net/checksum.c b/net/checksum.c
11
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
12
--- a/net/tap.c
19
--- a/net/checksum.c
13
+++ b/net/tap.c
20
+++ b/net/checksum.c
14
@@ -XXX,XX +XXX,XX @@ free_fail:
21
@@ -XXX,XX +XXX,XX @@ void net_checksum_calculate(uint8_t *data, int length)
15
script = default_script = get_relocated_path(DEFAULT_NETWORK_SCRIPT);
22
return; /* not IPv4 */
16
}
23
}
17
if (!downscript) {
24
18
- downscript = default_downscript = get_relocated_path(DEFAULT_NETWORK_SCRIPT);
25
+ if (IP4_IS_FRAGMENT(ip)) {
19
+ downscript = default_downscript =
26
+ return; /* a fragmented IP packet */
20
+ get_relocated_path(DEFAULT_NETWORK_DOWN_SCRIPT);
27
+ }
21
}
28
+
22
29
ip_len = lduw_be_p(&ip->ip_len);
23
if (tap->has_ifname) {
30
31
/* Last, check that we have enough data for the all IP frame */
24
--
32
--
25
2.7.4
33
2.7.4
26
34
27
35
diff view generated by jsdifflib
1
From: yuanjungong <ruc_gongyuanjun@163.com>
1
From: Guishan Qin <guishan.qin@windriver.com>
2
2
3
Close fd before returning.
3
At present net_checksum_calculate() only calculates TCP/UDP checksum
4
in an IP packet, but assumes the IP header checksum to be provided
5
by the software, e.g.: Linux kernel always calculates the IP header
6
checksum. However this might not always be the case, e.g.: for an IP
7
checksum offload enabled stack like VxWorks, the IP header checksum
8
can be zero.
4
9
5
Buglink: https://bugs.launchpad.net/qemu/+bug/1904486
10
This adds the checksum calculation of the IP header.
6
11
7
Signed-off-by: yuanjungong <ruc_gongyuanjun@163.com>
12
Signed-off-by: Guishan Qin <guishan.qin@windriver.com>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Yabing Liu <yabing.liu@windriver.com>
14
Signed-off-by: Bin Meng <bin.meng@windriver.com>
15
Reviewed-by: Cédric Le Goater <clg@kaod.org>
9
Signed-off-by: Jason Wang <jasowang@redhat.com>
16
Signed-off-by: Jason Wang <jasowang@redhat.com>
10
---
17
---
11
net/tap.c | 2 ++
18
net/checksum.c | 8 ++++++--
12
1 file changed, 2 insertions(+)
19
1 file changed, 6 insertions(+), 2 deletions(-)
13
20
14
diff --git a/net/tap.c b/net/tap.c
21
diff --git a/net/checksum.c b/net/checksum.c
15
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
16
--- a/net/tap.c
23
--- a/net/checksum.c
17
+++ b/net/tap.c
24
+++ b/net/checksum.c
18
@@ -XXX,XX +XXX,XX @@ int net_init_tap(const Netdev *netdev, const char *name,
25
@@ -XXX,XX +XXX,XX @@ void net_checksum_calculate(uint8_t *data, int length)
19
if (ret < 0) {
26
{
20
error_setg_errno(errp, -ret, "%s: Can't use file descriptor %d",
27
int mac_hdr_len, ip_len;
21
name, fd);
28
struct ip_header *ip;
22
+ close(fd);
29
+ uint16_t csum;
23
return -1;
30
24
}
31
/*
25
32
* Note: We cannot assume "data" is aligned, so the all code uses
26
@@ -XXX,XX +XXX,XX @@ int net_init_tap(const Netdev *netdev, const char *name,
33
@@ -XXX,XX +XXX,XX @@ void net_checksum_calculate(uint8_t *data, int length)
27
vhostfdname, vnet_hdr, fd, &err);
34
return; /* not IPv4 */
28
if (err) {
35
}
29
error_propagate(errp, err);
36
30
+ close(fd);
37
+ /* Calculate IP checksum */
31
return -1;
38
+ stw_he_p(&ip->ip_sum, 0);
32
}
39
+ csum = net_raw_checksum((uint8_t *)ip, IP_HDR_GET_LEN(ip));
33
} else if (tap->has_fds) {
40
+ stw_be_p(&ip->ip_sum, csum);
41
+
42
if (IP4_IS_FRAGMENT(ip)) {
43
return; /* a fragmented IP packet */
44
}
45
@@ -XXX,XX +XXX,XX @@ void net_checksum_calculate(uint8_t *data, int length)
46
switch (ip->ip_p) {
47
case IP_PROTO_TCP:
48
{
49
- uint16_t csum;
50
tcp_header *tcp = (tcp_header *)(ip + 1);
51
52
if (ip_len < sizeof(tcp_header)) {
53
@@ -XXX,XX +XXX,XX @@ void net_checksum_calculate(uint8_t *data, int length)
54
}
55
case IP_PROTO_UDP:
56
{
57
- uint16_t csum;
58
udp_header *udp = (udp_header *)(ip + 1);
59
60
if (ip_len < sizeof(udp_header)) {
34
--
61
--
35
2.7.4
62
2.7.4
36
63
37
64
diff view generated by jsdifflib
1
From: Paolo Bonzini <pbonzini@redhat.com>
1
From: Bin Meng <bin.meng@windriver.com>
2
2
3
"netdev_add help" is causing QEMU to exit because the code that
3
At present net_checksum_calculate() blindly calculates all types of
4
invokes show_netdevs is shared between CLI and HMP processing.
4
checksums (IP, TCP, UDP). Some NICs may have a per type setting in
5
Move the check to the callers so that exit(0) remains only
5
their BDs to control what checksum should be offloaded. To support
6
in the CLI flow.
6
such hardware behavior, introduce a 'csum_flag' parameter to the
7
7
net_checksum_calculate() API to allow fine control over what type
8
"netdev_add help" is not fixed by this patch; that is left for
8
checksum is calculated.
9
later work.
9
10
10
Existing users of this API are updated accordingly.
11
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
11
12
Signed-off-by: Bin Meng <bin.meng@windriver.com>
12
Signed-off-by: Jason Wang <jasowang@redhat.com>
13
Signed-off-by: Jason Wang <jasowang@redhat.com>
13
---
14
---
14
include/net/net.h | 1 +
15
hw/net/allwinner-sun8i-emac.c | 2 +-
15
monitor/hmp-cmds.c | 6 +++++
16
hw/net/cadence_gem.c | 2 +-
16
net/net.c | 68 +++++++++++++++++++++++++++---------------------------
17
hw/net/fsl_etsec/rings.c | 18 +++++++++---------
17
3 files changed, 41 insertions(+), 34 deletions(-)
18
hw/net/ftgmac100.c | 13 ++++++++++++-
18
19
hw/net/imx_fec.c | 20 ++++++++------------
19
diff --git a/include/net/net.h b/include/net/net.h
20
hw/net/virtio-net.c | 2 +-
20
index XXXXXXX..XXXXXXX 100644
21
hw/net/xen_nic.c | 2 +-
21
--- a/include/net/net.h
22
include/net/checksum.h | 7 ++++++-
22
+++ b/include/net/net.h
23
net/checksum.c | 18 ++++++++++++++----
23
@@ -XXX,XX +XXX,XX @@ extern const char *host_net_devices[];
24
net/filter-rewriter.c | 4 ++--
24
25
10 files changed, 55 insertions(+), 33 deletions(-)
25
/* from net.c */
26
26
int net_client_parse(QemuOptsList *opts_list, const char *str);
27
diff --git a/hw/net/allwinner-sun8i-emac.c b/hw/net/allwinner-sun8i-emac.c
27
+void show_netdevs(void);
28
index XXXXXXX..XXXXXXX 100644
28
int net_init_clients(Error **errp);
29
--- a/hw/net/allwinner-sun8i-emac.c
29
void net_check_clients(void);
30
+++ b/hw/net/allwinner-sun8i-emac.c
30
void net_cleanup(void);
31
@@ -XXX,XX +XXX,XX @@ static void allwinner_sun8i_emac_transmit(AwSun8iEmacState *s)
31
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
32
/* After the last descriptor, send the packet */
32
index XXXXXXX..XXXXXXX 100644
33
if (desc.status2 & TX_DESC_STATUS2_LAST_DESC) {
33
--- a/monitor/hmp-cmds.c
34
if (desc.status2 & TX_DESC_STATUS2_CHECKSUM_MASK) {
34
+++ b/monitor/hmp-cmds.c
35
- net_checksum_calculate(packet_buf, packet_bytes);
36
+ net_checksum_calculate(packet_buf, packet_bytes, CSUM_ALL);
37
}
38
39
qemu_send_packet(nc, packet_buf, packet_bytes);
40
diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/hw/net/cadence_gem.c
43
+++ b/hw/net/cadence_gem.c
44
@@ -XXX,XX +XXX,XX @@ static void gem_transmit(CadenceGEMState *s)
45
46
/* Is checksum offload enabled? */
47
if (s->regs[GEM_DMACFG] & GEM_DMACFG_TXCSUM_OFFL) {
48
- net_checksum_calculate(s->tx_packet, total_bytes);
49
+ net_checksum_calculate(s->tx_packet, total_bytes, CSUM_ALL);
50
}
51
52
/* Update MAC statistics */
53
diff --git a/hw/net/fsl_etsec/rings.c b/hw/net/fsl_etsec/rings.c
54
index XXXXXXX..XXXXXXX 100644
55
--- a/hw/net/fsl_etsec/rings.c
56
+++ b/hw/net/fsl_etsec/rings.c
57
@@ -XXX,XX +XXX,XX @@ static void process_tx_fcb(eTSEC *etsec)
58
uint8_t *l3_header = etsec->tx_buffer + 8 + l3_header_offset;
59
/* L4 header */
60
uint8_t *l4_header = l3_header + l4_header_offset;
61
+ int csum = 0;
62
63
/* if packet is IP4 and IP checksum is requested */
64
if (flags & FCB_TX_IP && flags & FCB_TX_CIP) {
65
- /* do IP4 checksum (TODO This function does TCP/UDP checksum
66
- * but not sure if it also does IP4 checksum.) */
67
- net_checksum_calculate(etsec->tx_buffer + 8,
68
- etsec->tx_buffer_len - 8);
69
+ csum |= CSUM_IP;
70
}
71
/* TODO Check the correct usage of the PHCS field of the FCB in case the NPH
72
* flag is on */
73
@@ -XXX,XX +XXX,XX @@ static void process_tx_fcb(eTSEC *etsec)
74
/* if checksum is requested */
75
if (flags & FCB_TX_CTU) {
76
/* do UDP checksum */
77
-
78
- net_checksum_calculate(etsec->tx_buffer + 8,
79
- etsec->tx_buffer_len - 8);
80
+ csum |= CSUM_UDP;
81
} else {
82
/* set checksum field to 0 */
83
l4_header[6] = 0;
84
@@ -XXX,XX +XXX,XX @@ static void process_tx_fcb(eTSEC *etsec)
85
}
86
} else if (flags & FCB_TX_CTU) { /* if TCP and checksum is requested */
87
/* do TCP checksum */
88
- net_checksum_calculate(etsec->tx_buffer + 8,
89
- etsec->tx_buffer_len - 8);
90
+ csum |= CSUM_TCP;
91
}
92
}
93
+
94
+ if (csum) {
95
+ net_checksum_calculate(etsec->tx_buffer + 8,
96
+ etsec->tx_buffer_len - 8, csum);
97
+ }
98
}
99
100
static void process_tx_bd(eTSEC *etsec,
101
diff --git a/hw/net/ftgmac100.c b/hw/net/ftgmac100.c
102
index XXXXXXX..XXXXXXX 100644
103
--- a/hw/net/ftgmac100.c
104
+++ b/hw/net/ftgmac100.c
105
@@ -XXX,XX +XXX,XX @@ static void ftgmac100_do_tx(FTGMAC100State *s, uint32_t tx_ring,
106
ptr += len;
107
frame_size += len;
108
if (bd.des0 & FTGMAC100_TXDES0_LTS) {
109
+ int csum = 0;
110
111
/* Check for VLAN */
112
if (flags & FTGMAC100_TXDES1_INS_VLANTAG &&
113
@@ -XXX,XX +XXX,XX @@ static void ftgmac100_do_tx(FTGMAC100State *s, uint32_t tx_ring,
114
}
115
116
if (flags & FTGMAC100_TXDES1_IP_CHKSUM) {
117
- net_checksum_calculate(s->frame, frame_size);
118
+ csum |= CSUM_IP;
119
}
120
+ if (flags & FTGMAC100_TXDES1_TCP_CHKSUM) {
121
+ csum |= CSUM_TCP;
122
+ }
123
+ if (flags & FTGMAC100_TXDES1_UDP_CHKSUM) {
124
+ csum |= CSUM_UDP;
125
+ }
126
+ if (csum) {
127
+ net_checksum_calculate(s->frame, frame_size, csum);
128
+ }
129
+
130
/* Last buffer in frame. */
131
qemu_send_packet(qemu_get_queue(s->nic), s->frame, frame_size);
132
ptr = s->frame;
133
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
134
index XXXXXXX..XXXXXXX 100644
135
--- a/hw/net/imx_fec.c
136
+++ b/hw/net/imx_fec.c
137
@@ -XXX,XX +XXX,XX @@ static void imx_enet_do_tx(IMXFECState *s, uint32_t index)
138
ptr += len;
139
frame_size += len;
140
if (bd.flags & ENET_BD_L) {
141
+ int csum = 0;
142
+
143
if (bd.option & ENET_BD_PINS) {
144
- struct ip_header *ip_hd = PKT_GET_IP_HDR(s->frame);
145
- if (IP_HEADER_VERSION(ip_hd) == 4) {
146
- net_checksum_calculate(s->frame, frame_size);
147
- }
148
+ csum |= (CSUM_TCP | CSUM_UDP);
149
}
150
if (bd.option & ENET_BD_IINS) {
151
- struct ip_header *ip_hd = PKT_GET_IP_HDR(s->frame);
152
- /* We compute checksum only for IPv4 frames */
153
- if (IP_HEADER_VERSION(ip_hd) == 4) {
154
- uint16_t csum;
155
- ip_hd->ip_sum = 0;
156
- csum = net_raw_checksum((uint8_t *)ip_hd, sizeof(*ip_hd));
157
- ip_hd->ip_sum = cpu_to_be16(csum);
158
- }
159
+ csum |= CSUM_IP;
160
+ }
161
+ if (csum) {
162
+ net_checksum_calculate(s->frame, frame_size, csum);
163
}
164
+
165
/* Last buffer in frame. */
166
167
qemu_send_packet(qemu_get_queue(s->nic), s->frame, frame_size);
168
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
169
index XXXXXXX..XXXXXXX 100644
170
--- a/hw/net/virtio-net.c
171
+++ b/hw/net/virtio-net.c
172
@@ -XXX,XX +XXX,XX @@ static void work_around_broken_dhclient(struct virtio_net_hdr *hdr,
173
(buf[12] == 0x08 && buf[13] == 0x00) && /* ethertype == IPv4 */
174
(buf[23] == 17) && /* ip.protocol == UDP */
175
(buf[34] == 0 && buf[35] == 67)) { /* udp.srcport == bootps */
176
- net_checksum_calculate(buf, size);
177
+ net_checksum_calculate(buf, size, CSUM_UDP);
178
hdr->flags &= ~VIRTIO_NET_HDR_F_NEEDS_CSUM;
179
}
180
}
181
diff --git a/hw/net/xen_nic.c b/hw/net/xen_nic.c
182
index XXXXXXX..XXXXXXX 100644
183
--- a/hw/net/xen_nic.c
184
+++ b/hw/net/xen_nic.c
185
@@ -XXX,XX +XXX,XX @@ static void net_tx_packets(struct XenNetDev *netdev)
186
tmpbuf = g_malloc(XC_PAGE_SIZE);
187
}
188
memcpy(tmpbuf, page + txreq.offset, txreq.size);
189
- net_checksum_calculate(tmpbuf, txreq.size);
190
+ net_checksum_calculate(tmpbuf, txreq.size, CSUM_ALL);
191
qemu_send_packet(qemu_get_queue(netdev->nic), tmpbuf,
192
txreq.size);
193
} else {
194
diff --git a/include/net/checksum.h b/include/net/checksum.h
195
index XXXXXXX..XXXXXXX 100644
196
--- a/include/net/checksum.h
197
+++ b/include/net/checksum.h
35
@@ -XXX,XX +XXX,XX @@
198
@@ -XXX,XX +XXX,XX @@
36
#include "qemu/option.h"
199
#include "qemu/bswap.h"
37
#include "qemu/timer.h"
200
struct iovec;
38
#include "qemu/sockets.h"
201
39
+#include "qemu/help_option.h"
202
+#define CSUM_IP 0x01
40
#include "monitor/monitor-internal.h"
203
+#define CSUM_TCP 0x02
41
#include "qapi/error.h"
204
+#define CSUM_UDP 0x04
42
#include "qapi/clone-visitor.h"
205
+#define CSUM_ALL (CSUM_IP | CSUM_TCP | CSUM_UDP)
43
@@ -XXX,XX +XXX,XX @@ void hmp_netdev_add(Monitor *mon, const QDict *qdict)
206
+
207
uint32_t net_checksum_add_cont(int len, uint8_t *buf, int seq);
208
uint16_t net_checksum_finish(uint32_t sum);
209
uint16_t net_checksum_tcpudp(uint16_t length, uint16_t proto,
210
uint8_t *addrs, uint8_t *buf);
211
-void net_checksum_calculate(uint8_t *data, int length);
212
+void net_checksum_calculate(uint8_t *data, int length, int csum_flag);
213
214
static inline uint32_t
215
net_checksum_add(int len, uint8_t *buf)
216
diff --git a/net/checksum.c b/net/checksum.c
217
index XXXXXXX..XXXXXXX 100644
218
--- a/net/checksum.c
219
+++ b/net/checksum.c
220
@@ -XXX,XX +XXX,XX @@ uint16_t net_checksum_tcpudp(uint16_t length, uint16_t proto,
221
return net_checksum_finish(sum);
222
}
223
224
-void net_checksum_calculate(uint8_t *data, int length)
225
+void net_checksum_calculate(uint8_t *data, int length, int csum_flag)
44
{
226
{
45
Error *err = NULL;
227
int mac_hdr_len, ip_len;
46
QemuOpts *opts;
228
struct ip_header *ip;
47
+ const char *type = qdict_get_try_str(qdict, "type");
229
@@ -XXX,XX +XXX,XX @@ void net_checksum_calculate(uint8_t *data, int length)
48
230
}
49
+ if (type && is_help_option(type)) {
231
50
+ show_netdevs();
232
/* Calculate IP checksum */
51
+ return;
233
- stw_he_p(&ip->ip_sum, 0);
234
- csum = net_raw_checksum((uint8_t *)ip, IP_HDR_GET_LEN(ip));
235
- stw_be_p(&ip->ip_sum, csum);
236
+ if (csum_flag & CSUM_IP) {
237
+ stw_he_p(&ip->ip_sum, 0);
238
+ csum = net_raw_checksum((uint8_t *)ip, IP_HDR_GET_LEN(ip));
239
+ stw_be_p(&ip->ip_sum, csum);
52
+ }
240
+ }
53
opts = qemu_opts_from_qdict(qemu_find_opts("netdev"), qdict, &err);
241
54
if (err) {
242
if (IP4_IS_FRAGMENT(ip)) {
55
goto out;
243
return; /* a fragmented IP packet */
56
diff --git a/net/net.c b/net/net.c
244
@@ -XXX,XX +XXX,XX @@ void net_checksum_calculate(uint8_t *data, int length)
57
index XXXXXXX..XXXXXXX 100644
245
switch (ip->ip_p) {
58
--- a/net/net.c
246
case IP_PROTO_TCP:
59
+++ b/net/net.c
247
{
60
@@ -XXX,XX +XXX,XX @@
248
+ if (!(csum_flag & CSUM_TCP)) {
61
#include "qemu/config-file.h"
249
+ return;
62
#include "qemu/ctype.h"
63
#include "qemu/iov.h"
64
+#include "qemu/qemu-print.h"
65
#include "qemu/main-loop.h"
66
#include "qemu/option.h"
67
#include "qapi/error.h"
68
@@ -XXX,XX +XXX,XX @@ static int net_client_init1(const Netdev *netdev, bool is_netdev, Error **errp)
69
return 0;
70
}
71
72
-static void show_netdevs(void)
73
+void show_netdevs(void)
74
{
75
int idx;
76
const char *available_netdevs[] = {
77
@@ -XXX,XX +XXX,XX @@ static void show_netdevs(void)
78
#endif
79
};
80
81
- printf("Available netdev backend types:\n");
82
+ qemu_printf("Available netdev backend types:\n");
83
for (idx = 0; idx < ARRAY_SIZE(available_netdevs); idx++) {
84
- puts(available_netdevs[idx]);
85
+ qemu_printf("%s\n", available_netdevs[idx]);
86
}
87
}
88
89
@@ -XXX,XX +XXX,XX @@ static int net_client_init(QemuOpts *opts, bool is_netdev, Error **errp)
90
int ret = -1;
91
Visitor *v = opts_visitor_new(opts);
92
93
- const char *type = qemu_opt_get(opts, "type");
94
-
95
- if (is_netdev && type && is_help_option(type)) {
96
- show_netdevs();
97
- exit(0);
98
- } else {
99
- /* Parse convenience option format ip6-net=fec0::0[/64] */
100
- const char *ip6_net = qemu_opt_get(opts, "ipv6-net");
101
+ /* Parse convenience option format ip6-net=fec0::0[/64] */
102
+ const char *ip6_net = qemu_opt_get(opts, "ipv6-net");
103
104
- if (ip6_net) {
105
- char *prefix_addr;
106
- unsigned long prefix_len = 64; /* Default 64bit prefix length. */
107
+ if (ip6_net) {
108
+ char *prefix_addr;
109
+ unsigned long prefix_len = 64; /* Default 64bit prefix length. */
110
111
- substrings = g_strsplit(ip6_net, "/", 2);
112
- if (!substrings || !substrings[0]) {
113
- error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "ipv6-net",
114
- "a valid IPv6 prefix");
115
- goto out;
116
- }
117
+ substrings = g_strsplit(ip6_net, "/", 2);
118
+ if (!substrings || !substrings[0]) {
119
+ error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "ipv6-net",
120
+ "a valid IPv6 prefix");
121
+ goto out;
122
+ }
250
+ }
123
251
+
124
- prefix_addr = substrings[0];
252
tcp_header *tcp = (tcp_header *)(ip + 1);
125
+ prefix_addr = substrings[0];
253
126
254
if (ip_len < sizeof(tcp_header)) {
127
- /* Handle user-specified prefix length. */
255
@@ -XXX,XX +XXX,XX @@ void net_checksum_calculate(uint8_t *data, int length)
128
- if (substrings[1] &&
256
}
129
- qemu_strtoul(substrings[1], NULL, 10, &prefix_len))
257
case IP_PROTO_UDP:
130
- {
258
{
131
- error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
259
+ if (!(csum_flag & CSUM_UDP)) {
132
- "ipv6-prefixlen", "a number");
260
+ return;
133
- goto out;
261
+ }
134
- }
262
+
135
-
263
udp_header *udp = (udp_header *)(ip + 1);
136
- qemu_opt_set(opts, "ipv6-prefix", prefix_addr, &error_abort);
264
137
- qemu_opt_set_number(opts, "ipv6-prefixlen", prefix_len,
265
if (ip_len < sizeof(udp_header)) {
138
- &error_abort);
266
diff --git a/net/filter-rewriter.c b/net/filter-rewriter.c
139
- qemu_opt_unset(opts, "ipv6-net");
267
index XXXXXXX..XXXXXXX 100644
140
+ /* Handle user-specified prefix length. */
268
--- a/net/filter-rewriter.c
141
+ if (substrings[1] &&
269
+++ b/net/filter-rewriter.c
142
+ qemu_strtoul(substrings[1], NULL, 10, &prefix_len))
270
@@ -XXX,XX +XXX,XX @@ static int handle_primary_tcp_pkt(RewriterState *rf,
143
+ {
271
tcp_pkt->th_ack = htonl(ntohl(tcp_pkt->th_ack) + conn->offset);
144
+ error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
272
145
+ "ipv6-prefixlen", "a number");
273
net_checksum_calculate((uint8_t *)pkt->data + pkt->vnet_hdr_len,
146
+ goto out;
274
- pkt->size - pkt->vnet_hdr_len);
275
+ pkt->size - pkt->vnet_hdr_len, CSUM_TCP);
147
}
276
}
148
+
277
149
+ qemu_opt_set(opts, "ipv6-prefix", prefix_addr, &error_abort);
278
/*
150
+ qemu_opt_set_number(opts, "ipv6-prefixlen", prefix_len,
279
@@ -XXX,XX +XXX,XX @@ static int handle_secondary_tcp_pkt(RewriterState *rf,
151
+ &error_abort);
280
tcp_pkt->th_seq = htonl(ntohl(tcp_pkt->th_seq) - conn->offset);
152
+ qemu_opt_unset(opts, "ipv6-net");
281
153
}
282
net_checksum_calculate((uint8_t *)pkt->data + pkt->vnet_hdr_len,
154
283
- pkt->size - pkt->vnet_hdr_len);
155
/* Create an ID for -net if the user did not specify one */
284
+ pkt->size - pkt->vnet_hdr_len, CSUM_TCP);
156
@@ -XXX,XX +XXX,XX @@ static int net_init_client(void *dummy, QemuOpts *opts, Error **errp)
285
}
157
286
}
158
static int net_init_netdev(void *dummy, QemuOpts *opts, Error **errp)
159
{
160
+ const char *type = qemu_opt_get(opts, "type");
161
+
162
+ if (type && is_help_option(type)) {
163
+ show_netdevs();
164
+ exit(0);
165
+ }
166
return net_client_init(opts, true, errp);
167
}
168
287
169
--
288
--
170
2.7.4
289
2.7.4
171
290
172
291
diff view generated by jsdifflib