summaryrefslogtreecommitdiff
path: root/hw/e1000.c
diff options
context:
space:
mode:
authorAlex Williamson <alex.williamson@redhat.com>2010-11-05 14:52:08 -0600
committerMichael S. Tsirkin <mst@redhat.com>2010-11-13 23:22:08 +0200
commite685b4eb649cbddd26f203b611eabeb714648f4d (patch)
tree5fc3c1eba41adb02ec9dda482bf94985f371c9c7 /hw/e1000.c
parenta5fd2c345f7a616e48e7f2be8b3060d23252180c (diff)
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 532efdc27d..677165f830 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++;
}