diff mbox

[ovs-dev] datapath-windows: Add software checksums for nbl which contain multiple nb

Message ID 20170421024259.17396-1-aserdean@cloudbasesolutions.com
State Accepted
Headers show

Commit Message

Alin Serdean April 21, 2017, 2:43 a.m. UTC
Until now we only needed to compute software checksums on net buffer lists
containing a single net buffer.

This patch allows the software checksums to be applied on a net buffer list
with multiple net buffers. The hard assumption for this, is the net buffers are
part of the same connection. The position of the offsets is pointed by the
layers parameter.

This will be useful for introducing support ip fragments in conntrack.

Signed-off-by: Alin Gabriel Serdean <aserdean@cloudbasesolutions.com>
---
 datapath-windows/ovsext/Offload.c | 105 ++++++++++++++++++++------------------
 1 file changed, 54 insertions(+), 51 deletions(-)

Comments

Anand Kumar April 21, 2017, 4:43 p.m. UTC | #1
Acked-by: Anand Kumar <kumaranand@vmware.com>

On 4/20/17, 7:43 PM, "ovs-dev-bounces@openvswitch.org on behalf of Alin Serdean" <ovs-dev-bounces@openvswitch.org on behalf of aserdean@cloudbasesolutions.com> wrote:

    Until now we only needed to compute software checksums on net buffer lists
    containing a single net buffer.
    
    This patch allows the software checksums to be applied on a net buffer list
    with multiple net buffers. The hard assumption for this, is the net buffers are
    part of the same connection. The position of the offsets is pointed by the
    layers parameter.
    
    This will be useful for introducing support ip fragments in conntrack.
    
    Signed-off-by: Alin Gabriel Serdean <aserdean@cloudbasesolutions.com>
    ---
     datapath-windows/ovsext/Offload.c | 105 ++++++++++++++++++++------------------
     1 file changed, 54 insertions(+), 51 deletions(-)
    
    diff --git a/datapath-windows/ovsext/Offload.c b/datapath-windows/ovsext/Offload.c
    index f3ab0e1..65d3b67 100644
    --- a/datapath-windows/ovsext/Offload.c
    +++ b/datapath-windows/ovsext/Offload.c
    @@ -647,7 +647,9 @@ OvsCalculateUDPChecksum(PNET_BUFFER_LIST curNbl,
      * OvsApplySWChecksumOnNB --
      *
      * This function calculates and sets the required software offloads given by
    - * csumInfo for a given NBL(nbl) with a single NB.
    + * csumInfo for a given NBL(nbl). If the given net buffer list 'nbl'
    + * has multiple net buffers, we assume that they are part of the same
    + * connection with the same offsets defined in 'layers'.
      *
      */
     NDIS_STATUS
    @@ -661,60 +663,61 @@ OvsApplySWChecksumOnNB(POVS_PACKET_HDR_INFO layers,
         UINT32 packetLength = 0;
         ASSERT(nbl != NULL);
     
    -    curNb = NET_BUFFER_LIST_FIRST_NB(nbl);
    -    ASSERT(curNb->Next == NULL);
    -    packetLength = NET_BUFFER_DATA_LENGTH(curNb);
    -    curMdl = NET_BUFFER_CURRENT_MDL(curNb);
    -    bufferStart = (PUINT8)MmGetSystemAddressForMdlSafe(curMdl,
    -                                                       LowPagePriority);
    -    if (!bufferStart) {
    -        return NDIS_STATUS_RESOURCES;
    -    }
    +    for (curNb = NET_BUFFER_LIST_FIRST_NB(nbl); curNb != NULL;
    +         curNb = curNb->Next) {
    +        packetLength = NET_BUFFER_DATA_LENGTH(curNb);
    +        curMdl = NET_BUFFER_CURRENT_MDL(curNb);
    +        bufferStart = (PUINT8)MmGetSystemAddressForMdlSafe(curMdl,
    +                                                           LowPagePriority);
    +        if (!bufferStart) {
    +            return NDIS_STATUS_RESOURCES;
    +        }
     
    -    bufferStart += NET_BUFFER_CURRENT_MDL_OFFSET(curNb);
    +        bufferStart += NET_BUFFER_CURRENT_MDL_OFFSET(curNb);
     
    -    if (layers->isIPv4) {
    -        IPHdr *ip = (IPHdr *)(bufferStart + layers->l3Offset);
    +        if (layers->isIPv4) {
    +            IPHdr *ip = (IPHdr *)(bufferStart + layers->l3Offset);
     
    -        if (csumInfo->Transmit.IpHeaderChecksum) {
    -            ip->check = 0;
    -            ip->check = IPChecksum((UINT8 *)ip, 4 * ip->ihl, 0);
    -        }
    +            if (csumInfo->Transmit.IpHeaderChecksum) {
    +                ip->check = 0;
    +                ip->check = IPChecksum((UINT8 *)ip, 4 * ip->ihl, 0);
    +            }
     
    -        if (layers->isTcp && csumInfo->Transmit.TcpChecksum) {
    -            UINT16 csumLength = (UINT16)(packetLength - layers->l4Offset);
    -            TCPHdr *tcp = (TCPHdr *)(bufferStart + layers->l4Offset);
    -            tcp->check = IPPseudoChecksum(&ip->saddr, &ip->daddr,
    -                                          IPPROTO_TCP, csumLength);
    -            tcp->check = CalculateChecksumNB(curNb, csumLength,
    -                                             (UINT32)(layers->l4Offset));
    -        } else if (layers->isUdp && csumInfo->Transmit.UdpChecksum) {
    -            UINT16 csumLength = (UINT16)(packetLength - layers->l4Offset);
    -            UDPHdr *udp = (UDPHdr *)((PCHAR)ip + sizeof *ip);
    -            udp->check = IPPseudoChecksum(&ip->saddr, &ip->daddr,
    -                                          IPPROTO_UDP, csumLength);
    -            udp->check = CalculateChecksumNB(curNb, csumLength,
    -                                             (UINT32)(layers->l4Offset));
    -        }
    -    } else if (layers->isIPv6) {
    -        IPv6Hdr *ip = (IPv6Hdr *)(bufferStart + layers->l3Offset);
    -
    -        if (layers->isTcp && csumInfo->Transmit.TcpChecksum) {
    -            UINT16 csumLength = (UINT16)(packetLength - layers->l4Offset);
    -            TCPHdr *tcp = (TCPHdr *)(bufferStart + layers->l4Offset);
    -            tcp->check = IPv6PseudoChecksum((UINT32 *) &ip->saddr,
    -                                            (UINT32 *) &ip->daddr,
    -                                            IPPROTO_TCP, csumLength);
    -            tcp->check = CalculateChecksumNB(curNb, csumLength,
    -                                             (UINT32)(layers->l4Offset));
    -        } else if (layers->isUdp && csumInfo->Transmit.UdpChecksum) {
    -            UINT16 csumLength = (UINT16)(packetLength - layers->l4Offset);
    -            UDPHdr *udp = (UDPHdr *)((PCHAR)ip + sizeof *ip);
    -            udp->check = IPv6PseudoChecksum((UINT32 *) &ip->saddr,
    -                                            (UINT32 *) &ip->daddr,
    -                                            IPPROTO_UDP, csumLength);
    -            udp->check = CalculateChecksumNB(curNb, csumLength,
    -                                             (UINT32)(layers->l4Offset));
    +            if (layers->isTcp && csumInfo->Transmit.TcpChecksum) {
    +                UINT16 csumLength = (UINT16)(packetLength - layers->l4Offset);
    +                TCPHdr *tcp = (TCPHdr *)(bufferStart + layers->l4Offset);
    +                tcp->check = IPPseudoChecksum(&ip->saddr, &ip->daddr,
    +                                              IPPROTO_TCP, csumLength);
    +                tcp->check = CalculateChecksumNB(curNb, csumLength,
    +                                                 (UINT32)(layers->l4Offset));
    +            } else if (layers->isUdp && csumInfo->Transmit.UdpChecksum) {
    +                UINT16 csumLength = (UINT16)(packetLength - layers->l4Offset);
    +                UDPHdr *udp = (UDPHdr *)((PCHAR)ip + sizeof *ip);
    +                udp->check = IPPseudoChecksum(&ip->saddr, &ip->daddr,
    +                                              IPPROTO_UDP, csumLength);
    +                udp->check = CalculateChecksumNB(curNb, csumLength,
    +                                                 (UINT32)(layers->l4Offset));
    +            }
    +        } else if (layers->isIPv6) {
    +            IPv6Hdr *ip = (IPv6Hdr *)(bufferStart + layers->l3Offset);
    +
    +            if (layers->isTcp && csumInfo->Transmit.TcpChecksum) {
    +                UINT16 csumLength = (UINT16)(packetLength - layers->l4Offset);
    +                TCPHdr *tcp = (TCPHdr *)(bufferStart + layers->l4Offset);
    +                tcp->check = IPv6PseudoChecksum((UINT32 *) &ip->saddr,
    +                                                (UINT32 *) &ip->daddr,
    +                                                IPPROTO_TCP, csumLength);
    +                tcp->check = CalculateChecksumNB(curNb, csumLength,
    +                                                 (UINT32)(layers->l4Offset));
    +            } else if (layers->isUdp && csumInfo->Transmit.UdpChecksum) {
    +                UINT16 csumLength = (UINT16)(packetLength - layers->l4Offset);
    +                UDPHdr *udp = (UDPHdr *)((PCHAR)ip + sizeof *ip);
    +                udp->check = IPv6PseudoChecksum((UINT32 *) &ip->saddr,
    +                                                (UINT32 *) &ip->daddr,
    +                                                IPPROTO_UDP, csumLength);
    +                udp->check = CalculateChecksumNB(curNb, csumLength,
    +                                                 (UINT32)(layers->l4Offset));
    +            }
             }
         }
     
    -- 
    2.10.2.windows.1
    _______________________________________________
    dev mailing list
    dev@openvswitch.org
    https://urldefense.proofpoint.com/v2/url?u=https-3A__mail.openvswitch.org_mailman_listinfo_ovs-2Ddev&d=DwICAg&c=uilaK90D4TOVoH58JNXRgQ&r=Q5z9tBe-nAOpE7LIHSPV8uy5-437agMXvkeHHMkR8Us&m=Jn6rbfIkYjn-gZXTTAD1vxxRs7ZxXWYdjfQF2AZJYPs&s=yxOSTorKcbP95c9XH21T2b6zUnY2VzUTxUgrqgXLiwg&e=
Gurucharan Shetty April 21, 2017, 5:08 p.m. UTC | #2
On 20 April 2017 at 19:43, Alin Serdean <aserdean@cloudbasesolutions.com>
wrote:

> Until now we only needed to compute software checksums on net buffer lists
> containing a single net buffer.
>
> This patch allows the software checksums to be applied on a net buffer list
> with multiple net buffers. The hard assumption for this, is the net
> buffers are
> part of the same connection. The position of the offsets is pointed by the
> layers parameter.
>
> This will be useful for introducing support ip fragments in conntrack.
>
> Signed-off-by: Alin Gabriel Serdean <aserdean@cloudbasesolutions.com>
>
Applied, thanks!


> ---
>  datapath-windows/ovsext/Offload.c | 105 ++++++++++++++++++++----------
> --------
>  1 file changed, 54 insertions(+), 51 deletions(-)
>
> diff --git a/datapath-windows/ovsext/Offload.c b/datapath-windows/ovsext/
> Offload.c
> index f3ab0e1..65d3b67 100644
> --- a/datapath-windows/ovsext/Offload.c
> +++ b/datapath-windows/ovsext/Offload.c
> @@ -647,7 +647,9 @@ OvsCalculateUDPChecksum(PNET_BUFFER_LIST curNbl,
>   * OvsApplySWChecksumOnNB --
>   *
>   * This function calculates and sets the required software offloads given
> by
> - * csumInfo for a given NBL(nbl) with a single NB.
> + * csumInfo for a given NBL(nbl). If the given net buffer list 'nbl'
> + * has multiple net buffers, we assume that they are part of the same
> + * connection with the same offsets defined in 'layers'.
>   *
>   */
>  NDIS_STATUS
> @@ -661,60 +663,61 @@ OvsApplySWChecksumOnNB(POVS_PACKET_HDR_INFO layers,
>      UINT32 packetLength = 0;
>      ASSERT(nbl != NULL);
>
> -    curNb = NET_BUFFER_LIST_FIRST_NB(nbl);
> -    ASSERT(curNb->Next == NULL);
> -    packetLength = NET_BUFFER_DATA_LENGTH(curNb);
> -    curMdl = NET_BUFFER_CURRENT_MDL(curNb);
> -    bufferStart = (PUINT8)MmGetSystemAddressForMdlSafe(curMdl,
> -                                                       LowPagePriority);
> -    if (!bufferStart) {
> -        return NDIS_STATUS_RESOURCES;
> -    }
> +    for (curNb = NET_BUFFER_LIST_FIRST_NB(nbl); curNb != NULL;
> +         curNb = curNb->Next) {
> +        packetLength = NET_BUFFER_DATA_LENGTH(curNb);
> +        curMdl = NET_BUFFER_CURRENT_MDL(curNb);
> +        bufferStart = (PUINT8)MmGetSystemAddressForMdlSafe(curMdl,
> +
>  LowPagePriority);
> +        if (!bufferStart) {
> +            return NDIS_STATUS_RESOURCES;
> +        }
>
> -    bufferStart += NET_BUFFER_CURRENT_MDL_OFFSET(curNb);
> +        bufferStart += NET_BUFFER_CURRENT_MDL_OFFSET(curNb);
>
> -    if (layers->isIPv4) {
> -        IPHdr *ip = (IPHdr *)(bufferStart + layers->l3Offset);
> +        if (layers->isIPv4) {
> +            IPHdr *ip = (IPHdr *)(bufferStart + layers->l3Offset);
>
> -        if (csumInfo->Transmit.IpHeaderChecksum) {
> -            ip->check = 0;
> -            ip->check = IPChecksum((UINT8 *)ip, 4 * ip->ihl, 0);
> -        }
> +            if (csumInfo->Transmit.IpHeaderChecksum) {
> +                ip->check = 0;
> +                ip->check = IPChecksum((UINT8 *)ip, 4 * ip->ihl, 0);
> +            }
>
> -        if (layers->isTcp && csumInfo->Transmit.TcpChecksum) {
> -            UINT16 csumLength = (UINT16)(packetLength - layers->l4Offset);
> -            TCPHdr *tcp = (TCPHdr *)(bufferStart + layers->l4Offset);
> -            tcp->check = IPPseudoChecksum(&ip->saddr, &ip->daddr,
> -                                          IPPROTO_TCP, csumLength);
> -            tcp->check = CalculateChecksumNB(curNb, csumLength,
> -                                             (UINT32)(layers->l4Offset));
> -        } else if (layers->isUdp && csumInfo->Transmit.UdpChecksum) {
> -            UINT16 csumLength = (UINT16)(packetLength - layers->l4Offset);
> -            UDPHdr *udp = (UDPHdr *)((PCHAR)ip + sizeof *ip);
> -            udp->check = IPPseudoChecksum(&ip->saddr, &ip->daddr,
> -                                          IPPROTO_UDP, csumLength);
> -            udp->check = CalculateChecksumNB(curNb, csumLength,
> -                                             (UINT32)(layers->l4Offset));
> -        }
> -    } else if (layers->isIPv6) {
> -        IPv6Hdr *ip = (IPv6Hdr *)(bufferStart + layers->l3Offset);
> -
> -        if (layers->isTcp && csumInfo->Transmit.TcpChecksum) {
> -            UINT16 csumLength = (UINT16)(packetLength - layers->l4Offset);
> -            TCPHdr *tcp = (TCPHdr *)(bufferStart + layers->l4Offset);
> -            tcp->check = IPv6PseudoChecksum((UINT32 *) &ip->saddr,
> -                                            (UINT32 *) &ip->daddr,
> -                                            IPPROTO_TCP, csumLength);
> -            tcp->check = CalculateChecksumNB(curNb, csumLength,
> -                                             (UINT32)(layers->l4Offset));
> -        } else if (layers->isUdp && csumInfo->Transmit.UdpChecksum) {
> -            UINT16 csumLength = (UINT16)(packetLength - layers->l4Offset);
> -            UDPHdr *udp = (UDPHdr *)((PCHAR)ip + sizeof *ip);
> -            udp->check = IPv6PseudoChecksum((UINT32 *) &ip->saddr,
> -                                            (UINT32 *) &ip->daddr,
> -                                            IPPROTO_UDP, csumLength);
> -            udp->check = CalculateChecksumNB(curNb, csumLength,
> -                                             (UINT32)(layers->l4Offset));
> +            if (layers->isTcp && csumInfo->Transmit.TcpChecksum) {
> +                UINT16 csumLength = (UINT16)(packetLength -
> layers->l4Offset);
> +                TCPHdr *tcp = (TCPHdr *)(bufferStart + layers->l4Offset);
> +                tcp->check = IPPseudoChecksum(&ip->saddr, &ip->daddr,
> +                                              IPPROTO_TCP, csumLength);
> +                tcp->check = CalculateChecksumNB(curNb, csumLength,
> +
>  (UINT32)(layers->l4Offset));
> +            } else if (layers->isUdp && csumInfo->Transmit.UdpChecksum) {
> +                UINT16 csumLength = (UINT16)(packetLength -
> layers->l4Offset);
> +                UDPHdr *udp = (UDPHdr *)((PCHAR)ip + sizeof *ip);
> +                udp->check = IPPseudoChecksum(&ip->saddr, &ip->daddr,
> +                                              IPPROTO_UDP, csumLength);
> +                udp->check = CalculateChecksumNB(curNb, csumLength,
> +
>  (UINT32)(layers->l4Offset));
> +            }
> +        } else if (layers->isIPv6) {
> +            IPv6Hdr *ip = (IPv6Hdr *)(bufferStart + layers->l3Offset);
> +
> +            if (layers->isTcp && csumInfo->Transmit.TcpChecksum) {
> +                UINT16 csumLength = (UINT16)(packetLength -
> layers->l4Offset);
> +                TCPHdr *tcp = (TCPHdr *)(bufferStart + layers->l4Offset);
> +                tcp->check = IPv6PseudoChecksum((UINT32 *) &ip->saddr,
> +                                                (UINT32 *) &ip->daddr,
> +                                                IPPROTO_TCP, csumLength);
> +                tcp->check = CalculateChecksumNB(curNb, csumLength,
> +
>  (UINT32)(layers->l4Offset));
> +            } else if (layers->isUdp && csumInfo->Transmit.UdpChecksum) {
> +                UINT16 csumLength = (UINT16)(packetLength -
> layers->l4Offset);
> +                UDPHdr *udp = (UDPHdr *)((PCHAR)ip + sizeof *ip);
> +                udp->check = IPv6PseudoChecksum((UINT32 *) &ip->saddr,
> +                                                (UINT32 *) &ip->daddr,
> +                                                IPPROTO_UDP, csumLength);
> +                udp->check = CalculateChecksumNB(curNb, csumLength,
> +
>  (UINT32)(layers->l4Offset));
> +            }
>          }
>      }
>
> --
> 2.10.2.windows.1
> _______________________________________________
> dev mailing list
> dev@openvswitch.org
> https://mail.openvswitch.org/mailman/listinfo/ovs-dev
>
diff mbox

Patch

diff --git a/datapath-windows/ovsext/Offload.c b/datapath-windows/ovsext/Offload.c
index f3ab0e1..65d3b67 100644
--- a/datapath-windows/ovsext/Offload.c
+++ b/datapath-windows/ovsext/Offload.c
@@ -647,7 +647,9 @@  OvsCalculateUDPChecksum(PNET_BUFFER_LIST curNbl,
  * OvsApplySWChecksumOnNB --
  *
  * This function calculates and sets the required software offloads given by
- * csumInfo for a given NBL(nbl) with a single NB.
+ * csumInfo for a given NBL(nbl). If the given net buffer list 'nbl'
+ * has multiple net buffers, we assume that they are part of the same
+ * connection with the same offsets defined in 'layers'.
  *
  */
 NDIS_STATUS
@@ -661,60 +663,61 @@  OvsApplySWChecksumOnNB(POVS_PACKET_HDR_INFO layers,
     UINT32 packetLength = 0;
     ASSERT(nbl != NULL);
 
-    curNb = NET_BUFFER_LIST_FIRST_NB(nbl);
-    ASSERT(curNb->Next == NULL);
-    packetLength = NET_BUFFER_DATA_LENGTH(curNb);
-    curMdl = NET_BUFFER_CURRENT_MDL(curNb);
-    bufferStart = (PUINT8)MmGetSystemAddressForMdlSafe(curMdl,
-                                                       LowPagePriority);
-    if (!bufferStart) {
-        return NDIS_STATUS_RESOURCES;
-    }
+    for (curNb = NET_BUFFER_LIST_FIRST_NB(nbl); curNb != NULL;
+         curNb = curNb->Next) {
+        packetLength = NET_BUFFER_DATA_LENGTH(curNb);
+        curMdl = NET_BUFFER_CURRENT_MDL(curNb);
+        bufferStart = (PUINT8)MmGetSystemAddressForMdlSafe(curMdl,
+                                                           LowPagePriority);
+        if (!bufferStart) {
+            return NDIS_STATUS_RESOURCES;
+        }
 
-    bufferStart += NET_BUFFER_CURRENT_MDL_OFFSET(curNb);
+        bufferStart += NET_BUFFER_CURRENT_MDL_OFFSET(curNb);
 
-    if (layers->isIPv4) {
-        IPHdr *ip = (IPHdr *)(bufferStart + layers->l3Offset);
+        if (layers->isIPv4) {
+            IPHdr *ip = (IPHdr *)(bufferStart + layers->l3Offset);
 
-        if (csumInfo->Transmit.IpHeaderChecksum) {
-            ip->check = 0;
-            ip->check = IPChecksum((UINT8 *)ip, 4 * ip->ihl, 0);
-        }
+            if (csumInfo->Transmit.IpHeaderChecksum) {
+                ip->check = 0;
+                ip->check = IPChecksum((UINT8 *)ip, 4 * ip->ihl, 0);
+            }
 
-        if (layers->isTcp && csumInfo->Transmit.TcpChecksum) {
-            UINT16 csumLength = (UINT16)(packetLength - layers->l4Offset);
-            TCPHdr *tcp = (TCPHdr *)(bufferStart + layers->l4Offset);
-            tcp->check = IPPseudoChecksum(&ip->saddr, &ip->daddr,
-                                          IPPROTO_TCP, csumLength);
-            tcp->check = CalculateChecksumNB(curNb, csumLength,
-                                             (UINT32)(layers->l4Offset));
-        } else if (layers->isUdp && csumInfo->Transmit.UdpChecksum) {
-            UINT16 csumLength = (UINT16)(packetLength - layers->l4Offset);
-            UDPHdr *udp = (UDPHdr *)((PCHAR)ip + sizeof *ip);
-            udp->check = IPPseudoChecksum(&ip->saddr, &ip->daddr,
-                                          IPPROTO_UDP, csumLength);
-            udp->check = CalculateChecksumNB(curNb, csumLength,
-                                             (UINT32)(layers->l4Offset));
-        }
-    } else if (layers->isIPv6) {
-        IPv6Hdr *ip = (IPv6Hdr *)(bufferStart + layers->l3Offset);
-
-        if (layers->isTcp && csumInfo->Transmit.TcpChecksum) {
-            UINT16 csumLength = (UINT16)(packetLength - layers->l4Offset);
-            TCPHdr *tcp = (TCPHdr *)(bufferStart + layers->l4Offset);
-            tcp->check = IPv6PseudoChecksum((UINT32 *) &ip->saddr,
-                                            (UINT32 *) &ip->daddr,
-                                            IPPROTO_TCP, csumLength);
-            tcp->check = CalculateChecksumNB(curNb, csumLength,
-                                             (UINT32)(layers->l4Offset));
-        } else if (layers->isUdp && csumInfo->Transmit.UdpChecksum) {
-            UINT16 csumLength = (UINT16)(packetLength - layers->l4Offset);
-            UDPHdr *udp = (UDPHdr *)((PCHAR)ip + sizeof *ip);
-            udp->check = IPv6PseudoChecksum((UINT32 *) &ip->saddr,
-                                            (UINT32 *) &ip->daddr,
-                                            IPPROTO_UDP, csumLength);
-            udp->check = CalculateChecksumNB(curNb, csumLength,
-                                             (UINT32)(layers->l4Offset));
+            if (layers->isTcp && csumInfo->Transmit.TcpChecksum) {
+                UINT16 csumLength = (UINT16)(packetLength - layers->l4Offset);
+                TCPHdr *tcp = (TCPHdr *)(bufferStart + layers->l4Offset);
+                tcp->check = IPPseudoChecksum(&ip->saddr, &ip->daddr,
+                                              IPPROTO_TCP, csumLength);
+                tcp->check = CalculateChecksumNB(curNb, csumLength,
+                                                 (UINT32)(layers->l4Offset));
+            } else if (layers->isUdp && csumInfo->Transmit.UdpChecksum) {
+                UINT16 csumLength = (UINT16)(packetLength - layers->l4Offset);
+                UDPHdr *udp = (UDPHdr *)((PCHAR)ip + sizeof *ip);
+                udp->check = IPPseudoChecksum(&ip->saddr, &ip->daddr,
+                                              IPPROTO_UDP, csumLength);
+                udp->check = CalculateChecksumNB(curNb, csumLength,
+                                                 (UINT32)(layers->l4Offset));
+            }
+        } else if (layers->isIPv6) {
+            IPv6Hdr *ip = (IPv6Hdr *)(bufferStart + layers->l3Offset);
+
+            if (layers->isTcp && csumInfo->Transmit.TcpChecksum) {
+                UINT16 csumLength = (UINT16)(packetLength - layers->l4Offset);
+                TCPHdr *tcp = (TCPHdr *)(bufferStart + layers->l4Offset);
+                tcp->check = IPv6PseudoChecksum((UINT32 *) &ip->saddr,
+                                                (UINT32 *) &ip->daddr,
+                                                IPPROTO_TCP, csumLength);
+                tcp->check = CalculateChecksumNB(curNb, csumLength,
+                                                 (UINT32)(layers->l4Offset));
+            } else if (layers->isUdp && csumInfo->Transmit.UdpChecksum) {
+                UINT16 csumLength = (UINT16)(packetLength - layers->l4Offset);
+                UDPHdr *udp = (UDPHdr *)((PCHAR)ip + sizeof *ip);
+                udp->check = IPv6PseudoChecksum((UINT32 *) &ip->saddr,
+                                                (UINT32 *) &ip->daddr,
+                                                IPPROTO_UDP, csumLength);
+                udp->check = CalculateChecksumNB(curNb, csumLength,
+                                                 (UINT32)(layers->l4Offset));
+            }
         }
     }