]> xenbits.xensource.com Git - pvdrivers/win/xenvif.git/commitdiff
Implement checksum verification as recommended in RFC1071.
authorPaul Durrant <paul.durrant@citrix.com>
Tue, 4 Mar 2014 17:00:43 +0000 (17:00 +0000)
committerPaul Durrant <paul.durrant@citrix.com>
Tue, 4 Mar 2014 17:00:43 +0000 (17:00 +0000)
Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
src/xenvif/checksum.c
src/xenvif/checksum.h
src/xenvif/receiver.c

index 3ae9d57b476ad09d9061cf9e4d9feda260a27eca..5f9c800384eb355e053c69c0e34effd1dbc74e9c 100644 (file)
@@ -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,
index 6c6c417800abe6b5feb0f8dcc638202bf6f50068..67ed89558e1e56c685c7c8beaf175dd269bcef97 100644 (file)
@@ -85,4 +85,10 @@ ChecksumUdpPacket(
     IN  PXENVIF_PACKET_PAYLOAD  Payload
     );
 
+extern BOOLEAN
+ChecksumVerify(
+    IN  USHORT  Calculated,
+    IN  USHORT  Embedded
+    );
+
 #endif  // _XENVIF_CHECKSUM_H
index f163f3f7a86558d4c8397707f5bafd5a7aa3de79..6cd35a50fde5cccbd7f802012bc83aeaec798db3 100644 (file)
@@ -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;
             }