From 2e8095b70b7a41abce7b609e788ddb1d2030367d Mon Sep 17 00:00:00 2001 From: Paul Durrant Date: Tue, 4 Mar 2014 17:00:43 +0000 Subject: [PATCH] Implement checksum verification as recommended in RFC1071. Signed-off-by: Paul Durrant --- src/xenvif/checksum.c | 14 ++++++++++++++ src/xenvif/checksum.h | 6 ++++++ src/xenvif/receiver.c | 36 +++++------------------------------- 3 files changed, 25 insertions(+), 31 deletions(-) diff --git a/src/xenvif/checksum.c b/src/xenvif/checksum.c index 3ae9d57..5f9c800 100644 --- a/src/xenvif/checksum.c +++ b/src/xenvif/checksum.c @@ -79,6 +79,20 @@ AccumulateChecksum( __AccumulateChecksum(Accumulator, MappedSystemVa, ByteCount); } +BOOLEAN +ChecksumVerify( + IN USHORT Calculated, + IN USHORT Embedded + ) +{ + ULONG Accumulator = ~Calculated; + + // See RFC 1624, section 5 + __AccumulateChecksum(&Accumulator, (PUCHAR)&Embedded, sizeof (USHORT)); + + return (Accumulator == 0xFFFF) ? TRUE : FALSE; +} + static FORCEINLINE USHORT __ChecksumIpVersion4PseudoHeader( IN PIPV4_ADDRESS SourceAddress, diff --git a/src/xenvif/checksum.h b/src/xenvif/checksum.h index 6c6c417..67ed895 100644 --- a/src/xenvif/checksum.h +++ b/src/xenvif/checksum.h @@ -85,4 +85,10 @@ ChecksumUdpPacket( IN PXENVIF_PACKET_PAYLOAD Payload ); +extern BOOLEAN +ChecksumVerify( + IN USHORT Calculated, + IN USHORT Embedded + ); + #endif // _XENVIF_CHECKSUM_H diff --git a/src/xenvif/receiver.c b/src/xenvif/receiver.c index f163f3f..6cd35a5 100644 --- a/src/xenvif/receiver.c +++ b/src/xenvif/receiver.c @@ -426,7 +426,7 @@ RingProcessChecksum( Calculated = ChecksumIpVersion4Header(StartVa, Info); Ring->OffloadStatistics.IpVersion4HeaderChecksumCalculated++; - if (Embedded == Calculated) { + if (ChecksumVerify(Calculated, Embedded)) { Packet->Flags.IpChecksumSucceeded = 1; Ring->OffloadStatistics.IpVersion4HeaderChecksumSucceeded++; } else { @@ -478,16 +478,10 @@ RingProcessChecksum( Calculated = ChecksumPseudoHeader(StartVa, Info); Calculated = ChecksumTcpPacket(StartVa, Info, Calculated, &Payload); - // Windows seems to take RFC 2460 a bit too far and replace zero - // TCP checksum with 0xFFFF even though there was never a provision - // for in 'no checksum' option for TCP. - if (Embedded == 0xFFFF) - Embedded = 0; - if (IpHeader->Version == 4) { Ring->OffloadStatistics.IpVersion4TcpChecksumCalculated++; - if (Embedded == Calculated) { + if (ChecksumVerify(Calculated, Embedded)) { Packet->Flags.TcpChecksumSucceeded = 1; Ring->OffloadStatistics.IpVersion4TcpChecksumSucceeded++; @@ -499,7 +493,7 @@ RingProcessChecksum( } else { Ring->OffloadStatistics.IpVersion6TcpChecksumCalculated++; - if (Embedded == Calculated) { + if (ChecksumVerify(Calculated, Embedded)) { Packet->Flags.TcpChecksumSucceeded = 1; Ring->OffloadStatistics.IpVersion6TcpChecksumSucceeded++; @@ -526,11 +520,6 @@ RingProcessChecksum( else Ring->OffloadStatistics.IpVersion6TcpChecksumCalculated++; - // RFC 2460 should not be applicable to TCP, but Microsoft seems - // to think it is. - if (Calculated == 0) - Calculated = 0xFFFF; - TcpHeader->Checksum = Calculated; } @@ -582,13 +571,7 @@ RingProcessChecksum( Ring->OffloadStatistics.IpVersion4UdpChecksumSucceeded++; } else { - // RFC 2460 should not be applicable to IPv4 but it looks - // like Microsoft screwed things up in its stack so we have - // to cope. - if (Embedded == 0xFFFF) - Embedded = 0; - - if ( Embedded == Calculated) { + if (ChecksumVerify(Calculated, Embedded)) { Packet->Flags.UdpChecksumSucceeded = 1; Ring->OffloadStatistics.IpVersion4UdpChecksumSucceeded++; @@ -601,11 +584,7 @@ RingProcessChecksum( } else { Ring->OffloadStatistics.IpVersion6UdpChecksumCalculated++; - // See RFC 2460 - if (Embedded == 0xFFFF) - Embedded = 0; - - if (Embedded == Calculated) { + if (ChecksumVerify(Calculated, Embedded)) { Packet->Flags.UdpChecksumSucceeded = 1; Ring->OffloadStatistics.IpVersion6UdpChecksumSucceeded++; @@ -632,11 +611,6 @@ RingProcessChecksum( else Ring->OffloadStatistics.IpVersion6UdpChecksumCalculated++; - // RFC 2460 should only be applicable to IPv6 but Microsoft seems - // to think it applies to the IPv4 too. - if (Calculated == 0) - Calculated = 0xFFFF; - UdpHeader->Checksum = Calculated; } -- 2.39.5