[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[win-pv-devel] [PATCH 3/4] Pullup headers and calculate hash over IP addresses and Ports



Signed-off-by: Owen Smith <owen.smith@xxxxxxxxxx>
---
 include/vif_interface.h   |  2 ++
 src/xennet/toeplitzhash.h | 71 ++++++++++++++++++++++++++++++++++++++++++
 src/xennet/transmitter.c  | 79 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 152 insertions(+)
 create mode 100644 src/xennet/toeplitzhash.h

diff --git a/include/vif_interface.h b/include/vif_interface.h
index 4ce61c4..83e3846 100644
--- a/include/vif_interface.h
+++ b/include/vif_interface.h
@@ -280,6 +280,8 @@ struct _XENVIF_TRANSMITTER_PACKET_V2 {
     ULONG                                       Length;
     /*! Opaque cookie used to store context information for packet return */
     PVOID                                       Cookie;
+    /*! Hash value calculated from packet's headers */
+    ULONGLONG                                   HashValue;
     /*! Packet information passed down to subscriber */
     XENVIF_TRANSMITTER_PACKET_SEND_INFO         Send;
     /*! Information passed up from subscriber for packet completion */
diff --git a/src/xennet/toeplitzhash.h b/src/xennet/toeplitzhash.h
new file mode 100644
index 0000000..df9e924
--- /dev/null
+++ b/src/xennet/toeplitzhash.h
@@ -0,0 +1,71 @@
+/* Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, 
+ * with or without modification, are permitted provided 
+ * that the following conditions are met:
+ * 
+ * *   Redistributions of source code must retain the above 
+ *     copyright notice, this list of conditions and the 
+ *     following disclaimer.
+ * *   Redistributions in binary form must reproduce the above 
+ *     copyright notice, this list of conditions and the 
+ *     following disclaimer in the documentation and/or other 
+ *     materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE.
+ */
+
+#ifndef _XENVIF_TOEPLITZ_HASH_H
+#define _XENVIF_TOEPLITZ_HASH_H
+
+static const UCHAR ToeplitzKey[] = {
+    0x6d, 0x5a, 0x56, 0xda, 0x25, 0x5b, 0x0e, 0xc2,
+    0x41, 0x67, 0x25, 0x3d, 0x43, 0xa3, 0x8f, 0xb0,
+    0xd0, 0xca, 0x2b, 0xcb, 0xae, 0x7b, 0x30, 0xb4,
+    0x77, 0xcb, 0x2d, 0xa3, 0x80, 0x30, 0xf2, 0x0c,
+    0x6a, 0x42, 0xb7, 0x3b, 0xbe, 0xac, 0x01, 0xfa
+};
+
+static FORCEINLINE ULONG
+ToeplitzHash(
+    IN  PUCHAR              Input,
+    IN  ULONG               Length
+    )
+{
+    ULONG                   Bit, Byte;
+    ULONG                   Keyword;
+    ULONG                   HashValue;
+    const UCHAR*            Next;
+
+    Next = ToeplitzKey + sizeof(ULONG);
+    Keyword = RtlUlongByteSwap(*(PULONG)ToeplitzKey);
+    HashValue = 0;
+
+    for (Byte = 0; Byte < Length; ++Byte) {
+        for (Bit = 0; Bit < 8; ++Bit) {
+            if (Input[Byte] & (1 << (8 - Bit)))
+                HashValue ^= Keyword;
+            Keyword = (Keyword << 1) | ((*Next) >> (8 - Bit) & 1);
+        }
+        ++Next;
+    }
+
+    return HashValue;
+}
+
+#endif // _XENVIF_TOEPLITZ_HASH_H
+
diff --git a/src/xennet/transmitter.c b/src/xennet/transmitter.c
index 9bf730c..e408364 100644
--- a/src/xennet/transmitter.c
+++ b/src/xennet/transmitter.c
@@ -32,6 +32,8 @@
 #include <ndis.h>
 #include "transmitter.h"
 #include "adapter.h"
+#include "toeplitzhash.h"
+#include <tcpip.h>
 #include "dbg_print.h"
 #include "assert.h"
 
@@ -281,6 +283,82 @@ __OffloadOptions(
     }
 }
 
+static FORCEINLINE ULONGLONG
+__TransmitterCalculateHash(
+    IN  PXENNET_TRANSMITTER             Transmitter,
+    IN  PXENVIF_TRANSMITTER_PACKET_V2   Packet
+    )
+{
+    UCHAR               Buffer[1024];
+    UCHAR               HashOver[40]; // sizeof(IPV6_ADDRESS)*2 + 
sizeof(USHORT)*2
+    PUCHAR              Ptr;
+    XENVIF_PACKET_INFO  Info;
+    NTSTATUS            status;
+
+    RtlZeroMemory(&Info, sizeof(XENVIF_PACKET_INFO));
+
+    status = XENVIF_VIF(TransmitterGetPacketHeaders,
+                        Transmitter->VifInterface,
+                        Packet->Mdl,
+                        Packet->Offset,
+                        Packet->Length,
+                        Buffer,
+                        sizeof(Buffer),
+                        &Info);
+    if (!NT_SUCCESS(status))
+        goto fail1;
+
+    Ptr = HashOver;
+    if (Info.IpHeader.Length) {
+        PIP_HEADER  IpHeader;
+
+        IpHeader = (PIP_HEADER)(Buffer + Info.IpHeader.Offset);
+
+        if (IpHeader->Version == 4) {
+            RtlCopyMemory(Ptr, &IpHeader->Version4.SourceAddress, 
sizeof(IPV4_ADDRESS));
+            Ptr += sizeof(IPV4_ADDRESS);
+            RtlCopyMemory(Ptr, &IpHeader->Version4.DestinationAddress, 
sizeof(IPV4_ADDRESS));
+            Ptr += sizeof(IPV4_ADDRESS);
+        } else if (IpHeader->Version == 6) {
+            RtlCopyMemory(Ptr, &IpHeader->Version6.SourceAddress, 
sizeof(IPV6_ADDRESS));
+            Ptr += sizeof(IPV6_ADDRESS);
+            RtlCopyMemory(Ptr, &IpHeader->Version6.DestinationAddress, 
sizeof(IPV6_ADDRESS));
+            Ptr += sizeof(IPV6_ADDRESS);
+        }
+    }
+    if (Info.TcpHeader.Length) {
+        PTCP_HEADER TcpHeader;
+
+        TcpHeader = (PTCP_HEADER)(Buffer + Info.TcpHeader.Offset);
+
+        *(PUSHORT)Ptr = TcpHeader->SourcePort;
+        Ptr += sizeof(USHORT);
+        *(PUSHORT)Ptr = TcpHeader->DestinationPort;
+        Ptr += sizeof(USHORT);
+    } else if (Info.UdpHeader.Length) {
+        PUDP_HEADER UdpHeader;
+
+        UdpHeader = (PUDP_HEADER)(Buffer + Info.UdpHeader.Offset);
+
+        *(PUSHORT)Ptr = UdpHeader->SourcePort;
+        Ptr += sizeof(USHORT);
+        *(PUSHORT)Ptr = UdpHeader->DestinationPort;
+        Ptr += sizeof(USHORT);
+    }
+    if (Ptr - HashOver == 0)
+        goto done;
+
+    return ToeplitzHash(HashOver, (ULONG)(Ptr - HashOver));
+
+done:
+    return 0;
+
+fail1:
+    Error("fail1 (%08x)\n", status);
+
+    return 0;
+}
+
 static FORCEINLINE VOID
 __TransmitterSendNetBufferListsV1(
     IN  PXENNET_TRANSMITTER     Transmitter,
@@ -400,6 +478,7 @@ __TransmitterSendNetBufferListsV2(
             Packet->Mdl                         = 
NET_BUFFER_CURRENT_MDL(NetBuffer);
             Packet->Offset                      = 
NET_BUFFER_CURRENT_MDL_OFFSET(NetBuffer);
             Packet->Length                      = 
NET_BUFFER_DATA_LENGTH(NetBuffer);
+            Packet->HashValue                   = 
__TransmitterCalculateHash(Transmitter, Packet);
             RtlZeroMemory(&Packet->Completion, sizeof(Packet->Completion));
 
             InsertTailList(&List, &Packet->ListEntry);
-- 
1.9.4.msysgit.1


_______________________________________________
win-pv-devel mailing list
win-pv-devel@xxxxxxxxxxxxxxxxxxxx
http://lists.xenproject.org/cgi-bin/mailman/listinfo/win-pv-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.