aboutsummaryrefslogtreecommitdiff
path: root/hw/e1000.c
diff options
context:
space:
mode:
authorAlex Williamson <alex.williamson@redhat.com>2010-11-05 14:52:08 -0600
committerAnthony Liguori <aliguori@us.ibm.com>2010-11-16 08:40:08 -0600
commit1f892feb37dabedbb2492c6b499b0c1b22631a1f (patch)
treeb907d279ad4e9c7f99c30d0f71979cd65b519101 /hw/e1000.c
parent27a6375de3edece2e5d115847d54c01e52331f7e (diff)
downloadqemu-1f892feb37dabedbb2492c6b499b0c1b22631a1f.zip
qemu-1f892feb37dabedbb2492c6b499b0c1b22631a1f.tar.gz
qemu-1f892feb37dabedbb2492c6b499b0c1b22631a1f.tar.bz2
e1000: Fix TCP checksum overflow with TSO
When adding the length to the pseudo header, we're not properly accounting for overflow. From: Mark Wu <dwu@redhat.com> Signed-off-by: Alex Williamson <alex.williamson@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Diffstat (limited to 'hw/e1000.c')
-rw-r--r--hw/e1000.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/hw/e1000.c b/hw/e1000.c
index 532efdc..677165f 100644
--- a/hw/e1000.c
+++ b/hw/e1000.c
@@ -384,9 +384,12 @@ xmit_seg(E1000State *s)
} else // UDP
cpu_to_be16wu((uint16_t *)(tp->data+css+4), len);
if (tp->sum_needed & E1000_TXD_POPTS_TXSM) {
+ unsigned int phsum;
// add pseudo-header length before checksum calculation
sp = (uint16_t *)(tp->data + tp->tucso);
- cpu_to_be16wu(sp, be16_to_cpup(sp) + len);
+ phsum = be16_to_cpup(sp) + len;
+ phsum = (phsum >> 16) + (phsum & 0xffff);
+ cpu_to_be16wu(sp, phsum);
}
tp->tso_frames++;
}