[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |