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

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



> -----Original Message-----
> From: Owen Smith [mailto:owen.smith@xxxxxxxxxx]
> Sent: 12 November 2014 16:39
> To: win-pv-devel@xxxxxxxxxxxxxxxxxxxx
> Cc: Paul Durrant; Owen Smith
> Subject: [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;
> +}

Why such an expensive hash? You don't need to use Toeplitz.

  Paul

> +
> +#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®.