[ovs-dev] [PATCH v2 3/3] datapath-windows: Add GRE checksum

Paul Boca pboca at cloudbasesolutions.com
Mon May 30 08:50:48 UTC 2016


Looks good to me.

Acked-by: Paul-Daniel Boca <pboca at cloudbasesolutions.com>

> -----Original Message-----
> From: dev [mailto:dev-bounces at openvswitch.org] On Behalf Of Alin Serdean
> Sent: Tuesday, May 24, 2016 7:15 PM
> To: dev at openvswitch.org
> Subject: [ovs-dev] [PATCH v2 3/3] datapath-windows: Add GRE checksum
> 
> This patch introduces GRE checksum computation if the userspace requires
> it on Tx. On Rx we verify the GRE checksum if the checksum bit was
> specified and also inform the userspace about it.
> 
> Also fix the GRE header length as specified by the GRE flags not the
> tunnel flags.
> 
> Signed-off-by: Alin Gabriel Serdean <aserdean at cloudbasesolutions.com>
> ---
>  datapath-windows/ovsext/Gre.c | 68 ++++++++++++++++++++++++++++++------
> -------
>  datapath-windows/ovsext/Gre.h | 14 ++++-----
>  2 files changed, 55 insertions(+), 27 deletions(-)
> 
> diff --git a/datapath-windows/ovsext/Gre.c b/datapath-windows/ovsext/Gre.c
> index cb41593..5fa10c3 100644
> --- a/datapath-windows/ovsext/Gre.c
> +++ b/datapath-windows/ovsext/Gre.c
> @@ -135,7 +135,8 @@ OvsDoEncapGre(POVS_VPORT_ENTRY vport,
>      IPHdr *ipHdr;
>      PGREHdr greHdr;
>      POVS_GRE_VPORT vportGre;
> -    UINT32 headRoom = GreTunHdrSize(tunKey->flags);
> +    PCHAR pChk = NULL;
> +    UINT32 headRoom = GreTunHdrSize(OvsTunnelFlagsToGreFlags(tunKey-
> >flags));
>  #if DBG
>      UINT32 counterHeadRoom;
>  #endif
> @@ -259,6 +260,7 @@ OvsDoEncapGre(POVS_VPORT_ENTRY vport,
> 
>          if (tunKey->flags & OVS_TNL_F_CSUM) {
>              RtlZeroMemory(currentOffset, 4);
> +            pChk = currentOffset;
>              currentOffset += 4;
>  #if DBG
>              counterHeadRoom -= 4;
> @@ -275,6 +277,17 @@ OvsDoEncapGre(POVS_VPORT_ENTRY vport,
>  #endif
>          }
> 
> +        /* Checksum needs to be done after the GRE header has been set */
> +        if (tunKey->flags & OVS_TNL_F_CSUM) {
> +            ASSERT(pChk);
> +            UINT16 chksum =
> +                CalculateChecksumNB(curNb,
> +                                    (UINT16)(NET_BUFFER_DATA_LENGTH(curNb) -
> +                                             sizeof *ipHdr - sizeof *ethHdr),
> +                                    sizeof *ipHdr + sizeof *ethHdr);
> +            RtlCopyMemory(pChk, &chksum, 2);
> +        }
> +
>  #if DBG
>          ASSERT(counterHeadRoom == 0);
>  #endif
> @@ -306,25 +319,12 @@ OvsDecapGre(POVS_SWITCH_CONTEXT
> switchContext,
> 
>      curNb = NET_BUFFER_LIST_FIRST_NB(curNbl);
>      packetLength = NET_BUFFER_DATA_LENGTH(curNb);
> -    tunnelSize = GreTunHdrSize(tunKey->flags);
> +    curMdl = NET_BUFFER_CURRENT_MDL(curNb);
> +    tunnelSize = GreTunHdrSize(0);
>      if (packetLength <= tunnelSize) {
>          return NDIS_STATUS_INVALID_LENGTH;
>      }
> 
> -    /*
> -     * Create a copy of the NBL so that we have all the headers in one MDL.
> -     */
> -    *newNbl = OvsPartialCopyNBL(switchContext, curNbl,
> -                                tunnelSize + OVS_DEFAULT_COPY_SIZE, 0,
> -                                TRUE /*copy NBL info */);
> -
> -    if (*newNbl == NULL) {
> -        return NDIS_STATUS_RESOURCES;
> -    }
> -
> -    curNbl = *newNbl;
> -    curNb = NET_BUFFER_LIST_FIRST_NB(curNbl);
> -    curMdl = NET_BUFFER_CURRENT_MDL(curNb);
>      bufferStart = (PUINT8)MmGetSystemAddressForMdlSafe(curMdl,
> LowPagePriority) +
>                    NET_BUFFER_CURRENT_MDL_OFFSET(curNb);
>      if (!bufferStart) {
> @@ -346,16 +346,30 @@ OvsDecapGre(POVS_SWITCH_CONTEXT
> switchContext,
>      greHdr = (GREHdr *)((PCHAR)ipHdr + sizeof *ipHdr);
>      headRoom += sizeof *greHdr;
> 
> +    tunnelSize = GreTunHdrSize(greHdr->flags);
> +
>      /* Validate if GRE header protocol type. */
>      if (greHdr->protocolType != GRE_NET_TEB) {
> -        status = STATUS_NDIS_INVALID_PACKET;
> -        goto dropNbl;
> +        *newNbl = NULL;
> +        return STATUS_NDIS_INVALID_PACKET;
>      }
> 
>      PCHAR currentOffset = (PCHAR)greHdr + sizeof *greHdr;
> 
>      if (greHdr->flags & GRE_CSUM) {
>          tunKey->flags |= OVS_TNL_F_CSUM;
> +        UINT16 prevChksum = *((UINT16 *)currentOffset);
> +        RtlZeroMemory(currentOffset, 2);
> +        UINT16 chksum =
> +            CalculateChecksumNB(curNb,
> +                                (UINT16)(NET_BUFFER_DATA_LENGTH(curNb) -
> +                                (ipHdr->ihl * 4 + sizeof *ethHdr)),
> +                                ipHdr->ihl * 4 + sizeof *ethHdr);
> +        if (prevChksum != chksum) {
> +            *newNbl = NULL;
> +            return STATUS_NDIS_INVALID_PACKET;
> +        }
> +        RtlCopyMemory(currentOffset, &prevChksum, 2);
>          currentOffset += 4;
>          headRoom += 4;
>      }
> @@ -369,11 +383,25 @@ OvsDecapGre(POVS_SWITCH_CONTEXT
> switchContext,
>          headRoom += 4;
>      }
> 
> +    /*
> +     * Create a copy of the NBL so that we have all the headers in one MDL.
> +     */
> +    *newNbl = OvsPartialCopyNBL(switchContext, curNbl,
> +                                tunnelSize, 0,
> +                                TRUE /*copy NBL info */);
> +
> +    if (*newNbl == NULL) {
> +        return NDIS_STATUS_RESOURCES;
> +    }
> +
> +    curNbl = *newNbl;
> +    curNb = NET_BUFFER_LIST_FIRST_NB(curNbl);
> +
>      /* Clear out the receive flag for the inner packet. */
>      NET_BUFFER_LIST_INFO(curNbl, TcpIpChecksumNetBufferListInfo) = 0;
> -    NdisAdvanceNetBufferDataStart(curNb, GreTunHdrSize(tunKey->flags),
> FALSE,
> +    NdisAdvanceNetBufferDataStart(curNb, GreTunHdrSize(greHdr->flags),
> FALSE,
>                                    NULL);
> -    ASSERT(headRoom == GreTunHdrSize(tunKey->flags));
> +    ASSERT(headRoom == GreTunHdrSize(greHdr->flags));
>      return NDIS_STATUS_SUCCESS;
> 
>  dropNbl:
> diff --git a/datapath-windows/ovsext/Gre.h b/datapath-windows/ovsext/Gre.h
> index d2472d9..beee86c 100644
> --- a/datapath-windows/ovsext/Gre.h
> +++ b/datapath-windows/ovsext/Gre.h
> @@ -1,5 +1,5 @@
>  /*
> - * Copyright (c) 2015 Cloudbase Solutions Srl
> + * Copyright (c) 2015, 2016 Cloudbase Solutions Srl
>   *
>   * Licensed under the Apache License, Version 2.0 (the "License");
>   * you may not use this file except in compliance with the License.
> @@ -76,11 +76,13 @@ OvsTunnelFlagsToGreFlags(UINT16 tunnelflags)
>  {
>      UINT16 flags = 0;
> 
> -    if (tunnelflags & OVS_TNL_F_CSUM)
> +    if (tunnelflags & OVS_TNL_F_CSUM) {
>          flags |= GRE_CSUM;
> +    }
> 
> -    if (tunnelflags & OVS_TNL_F_KEY)
> +    if (tunnelflags & OVS_TNL_F_KEY) {
>          flags |= GRE_KEY;
> +    }
> 
>      return flags;
>  }
> @@ -89,10 +91,8 @@ static __inline UINT32
>  GreTunHdrSize(UINT16 flags)
>  {
>      UINT32 sum = sizeof(EthHdr) + sizeof(IPHdr) + sizeof(GREHdr);
> -    sum += (flags & OVS_TNL_F_CSUM) ?
> -           4 : 0;
> -    sum += (flags & OVS_TNL_F_KEY) ?
> -           4 : 0;
> +    sum += (flags & GRE_CSUM) ? 4 : 0;
> +    sum += (flags & GRE_KEY) ? 4 : 0;
> 
>      return sum;
>  }
> --
> 1.9.5.msysgit.0
> _______________________________________________
> dev mailing list
> dev at openvswitch.org
> http://openvswitch.org/mailman/listinfo/dev


More information about the dev mailing list