Acked-by: Sorin Vinturis <svintu...@cloudbasesolutions.com>

-----Original Message-----
From: dev [mailto:dev-boun...@openvswitch.org] On Behalf Of Alin Serdean
Sent: Thursday, 21 January, 2016 04:17
To: dev@openvswitch.org
Subject: [ovs-dev] [PATCH] datapath-windows: Refactor sofware offloads and mss

The purpose of this patch is to refactor the software offloads found in the 
VXLAN and GRE code and also to refactor how the maximmum segment size for a 
given NBL is obtained.

This patch introduces two functions OvsApplySWChecksumOnNB and OVSGetTcpMSS.

OVSGetTcpMSS - will return the mss found in a given NBL.

OvsApplySWChecksumOnNB - will compute and set software offloads for a given
                         NBL.

Signed-off-by: Alin Gabriel Serdean <aserd...@cloudbasesolutions.com>
---
 datapath-windows/ovsext/BufferMgmt.c | 106 +++++++++++++++++++++++++++++++++++
 datapath-windows/ovsext/BufferMgmt.h |  21 ++++++-
 datapath-windows/ovsext/Gre.c        |  79 ++------------------------
 datapath-windows/ovsext/Stt.c        |  15 +----
 datapath-windows/ovsext/Vxlan.c      |  79 ++------------------------
 5 files changed, 135 insertions(+), 165 deletions(-)

diff --git a/datapath-windows/ovsext/BufferMgmt.c 
b/datapath-windows/ovsext/BufferMgmt.c
index 7ec073b..e9d339c 100644
--- a/datapath-windows/ovsext/BufferMgmt.c
+++ b/datapath-windows/ovsext/BufferMgmt.c
@@ -1311,6 +1311,112 @@ nblcopy_error:
 }
 
 /*
+ * OvsApplySWChecksumOnNB --
+ *
+ * This function calculates and sets the required sofware offloads 
+given by
+ * csumInfo for a given NBL(nbl) with a single NB.
+ *
+ */
+NDIS_STATUS
+OvsApplySWChecksumOnNB(POVS_PACKET_HDR_INFO layers,
+                       PNET_BUFFER_LIST nbl,
+                       PNDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO 
+csumInfo) {
+    PNET_BUFFER curNb;
+    PMDL curMdl;
+    PUINT8 bufferStart;
+    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;
+    }
+
+    bufferStart += NET_BUFFER_CURRENT_MDL_OFFSET(curNb);
+
+    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 (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));
+        }
+    }
+
+    return NDIS_STATUS_SUCCESS;
+}
+
+/*
+ * OVSGetTcpMSS --
+ *
+ * This function returns the maximum segment size of the given NBL. It 
+takes
+ * into consideration both LSO v1 and v2.
+ */
+ULONG
+OVSGetTcpMSS(PNET_BUFFER_LIST nbl)
+{
+    NDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO lsoInfo;
+    ASSERT(nbl != NULL);
+
+    lsoInfo.Value = NET_BUFFER_LIST_INFO(nbl,
+                                         TcpLargeSendNetBufferListInfo);
+    switch (lsoInfo.Transmit.Type) {
+        case NDIS_TCP_LARGE_SEND_OFFLOAD_V1_TYPE:
+            return lsoInfo.LsoV1Transmit.MSS;
+            break;
+        case NDIS_TCP_LARGE_SEND_OFFLOAD_V2_TYPE:
+            return lsoInfo.LsoV2Transmit.MSS;
+            break;
+        default:
+            OVS_LOG_ERROR("Unknown LSO transmit type:%d",
+                          lsoInfo.Transmit.Type);
+            return 0;
+    }
+}
+
+/*
  * --------------------------------------------------------------------------
  * OvsAllocateNBLFromBuffer --
  *
diff --git a/datapath-windows/ovsext/BufferMgmt.h 
b/datapath-windows/ovsext/BufferMgmt.h
index 79abc3d..3f44b9b 100644
--- a/datapath-windows/ovsext/BufferMgmt.h
+++ b/datapath-windows/ovsext/BufferMgmt.h
@@ -63,7 +63,6 @@ typedef union _OVS_BUFFER_CONTEXT {
     UINT64 value[MEM_ALIGN_SIZE(16) >> 3];  } OVS_BUFFER_CONTEXT, 
*POVS_BUFFER_CONTEXT;
 
-
 typedef struct _OVS_NBL_POOL {
     NDIS_SWITCH_CONTEXT ndisContext;
     NDIS_HANDLE   ndisHandle;
@@ -83,11 +82,13 @@ typedef struct _OVS_NBL_POOL {
 
 
 NDIS_STATUS OvsInitBufferPool(PVOID context);
+
 VOID OvsCleanupBufferPool(PVOID context);
 
 PNET_BUFFER_LIST OvsAllocateFixSizeNBL(PVOID context,
                                        UINT32 size,
                                        UINT32 headRoom);
+
 PNET_BUFFER_LIST OvsAllocateVariableSizeNBL(PVOID context,
                                             UINT32 size,
                                             UINT32 headRoom); @@ -106,22 
+107,36 @@ PNET_BUFFER_LIST OvsPartialCopyToMultipleNBLs(PVOID context,
                                               UINT32 copySize,
                                               UINT32 headRoom,
                                               BOOLEAN copyNblInfo);
+
 PNET_BUFFER_LIST OvsFullCopyNBL(PVOID context, PNET_BUFFER_LIST nbl,
                                 UINT32 headRoom, BOOLEAN copyNblInfo);
+
 PNET_BUFFER_LIST OvsTcpSegmentNBL(PVOID context,
                                   PNET_BUFFER_LIST nbl,
                                   POVS_PACKET_HDR_INFO hdrInfo,
                                   UINT32 MSS,
                                   UINT32 headRoom);
+
 PNET_BUFFER_LIST OvsAllocateNBLFromBuffer(PVOID context,
                                           PVOID buffer,
                                           ULONG length); -PNET_BUFFER_LIST 
OvsFullCopyToMultipleNBLs(PVOID context,
-    PNET_BUFFER_LIST nbl, UINT32 headRoom, BOOLEAN copyNblInfo);
+
+PNET_BUFFER_LIST OvsFullCopyToMultipleNBLs(PVOID context, PNET_BUFFER_LIST nbl,
+                                           UINT32 headRoom,
+                                           BOOLEAN copyNblInfo);
+
 PNET_BUFFER_LIST OvsCompleteNBL(PVOID context, PNET_BUFFER_LIST nbl,
                                 BOOLEAN updateRef);
+
 NDIS_STATUS OvsSetCtxSourcePortNo(PNET_BUFFER_LIST nbl, UINT32 portNo);
 
 NDIS_STATUS OvsGetCtxSourcePortNo(PNET_BUFFER_LIST nbl, UINT32 *portNo);
 
+ULONG OVSGetTcpMSS(PNET_BUFFER_LIST nbl);
+
+NDIS_STATUS OvsApplySWChecksumOnNB(POVS_PACKET_HDR_INFO layers,
+                                   PNET_BUFFER_LIST nbl,
+                                   PNDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO
+                                                                     
+csumInfo);
+
 #endif /* __BUFFER_MGMT_H_ */
diff --git a/datapath-windows/ovsext/Gre.c b/datapath-windows/ovsext/Gre.c 
index 5abd4a4..fbba930 100644
--- a/datapath-windows/ovsext/Gre.c
+++ b/datapath-windows/ovsext/Gre.c
@@ -147,21 +147,8 @@ OvsDoEncapGre(POVS_VPORT_ENTRY vport,
     packetLength = NET_BUFFER_DATA_LENGTH(curNb);
 
     if (layers->isTcp) {
-        NDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO tsoInfo;
-
-        tsoInfo.Value = NET_BUFFER_LIST_INFO(curNbl,
-                                             TcpLargeSendNetBufferListInfo);
-        switch (tsoInfo.Transmit.Type) {
-            case NDIS_TCP_LARGE_SEND_OFFLOAD_V1_TYPE:
-                mss = tsoInfo.LsoV1Transmit.MSS;
-                break;
-            case NDIS_TCP_LARGE_SEND_OFFLOAD_V2_TYPE:
-                mss = tsoInfo.LsoV2Transmit.MSS;
-                break;
-            default:
-                OVS_LOG_ERROR("Unknown LSO transmit type:%d",
-                              tsoInfo.Transmit.Type);
-        }
+        mss = OVSGetTcpMSS(curNbl);
+
         OVS_LOG_TRACE("MSS %u packet len %u", mss,
                       packetLength);
         if (mss) {
@@ -188,71 +175,15 @@ OvsDoEncapGre(POVS_VPORT_ENTRY vport,
             OVS_LOG_ERROR("Unable to copy NBL");
             return NDIS_STATUS_FAILURE;
         }
-        /*
-         * To this point we do not have GRE hardware offloading.
-         * Apply defined checksums
-         */
-        curNb = NET_BUFFER_LIST_FIRST_NB(*newNbl);
-        curMdl = NET_BUFFER_CURRENT_MDL(curNb);
-        bufferStart = (PUINT8)MmGetSystemAddressForMdlSafe(curMdl,
-                                                           LowPagePriority);
-        if (!bufferStart) {
-            status = NDIS_STATUS_RESOURCES;
-            goto ret_error;
-        }
 
         NDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO csumInfo;
         csumInfo.Value = NET_BUFFER_LIST_INFO(curNbl,
                                               TcpIpChecksumNetBufferListInfo);
 
-        bufferStart += NET_BUFFER_CURRENT_MDL_OFFSET(curNb);
-
-        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 (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));
-            }
+        status = OvsApplySWChecksumOnNB(layers, *newNbl, &csumInfo);
+        if (status != NDIS_STATUS_SUCCESS) {
+            goto ret_error;
         }
-        /* Clear out TcpIpChecksumNetBufferListInfo flag */
-        NET_BUFFER_LIST_INFO(*newNbl, TcpIpChecksumNetBufferListInfo) = 0;
     }
 
     curNbl = *newNbl;
diff --git a/datapath-windows/ovsext/Stt.c b/datapath-windows/ovsext/Stt.c 
index 0ae2633..6da0ac9 100644
--- a/datapath-windows/ovsext/Stt.c
+++ b/datapath-windows/ovsext/Stt.c
@@ -163,20 +163,7 @@ OvsDoEncapStt(POVS_VPORT_ENTRY vport,
     BOOLEAN innerPartialChecksum = FALSE;
 
     if (layers->isTcp) {
-        lsoInfo.Value = NET_BUFFER_LIST_INFO(curNbl,
-                TcpLargeSendNetBufferListInfo);
-
-        switch (lsoInfo.Transmit.Type) {
-            case NDIS_TCP_LARGE_SEND_OFFLOAD_V1_TYPE:
-                mss = lsoInfo.LsoV1Transmit.MSS;
-                break;
-            case NDIS_TCP_LARGE_SEND_OFFLOAD_V2_TYPE:
-                mss = lsoInfo.LsoV2Transmit.MSS;
-                break;
-            default:
-                OVS_LOG_ERROR("Unknown LSO transmit type:%d",
-                              lsoInfo.Transmit.Type);
-        }
+        mss = OVSGetTcpMSS(curNbl);
     }
 
     vportStt = (POVS_STT_VPORT) GetOvsVportPriv(vport); diff --git 
a/datapath-windows/ovsext/Vxlan.c b/datapath-windows/ovsext/Vxlan.c index 
2516ece..813fe42 100644
--- a/datapath-windows/ovsext/Vxlan.c
+++ b/datapath-windows/ovsext/Vxlan.c
@@ -201,21 +201,8 @@ OvsDoEncapVxlan(POVS_VPORT_ENTRY vport,
     packetLength = NET_BUFFER_DATA_LENGTH(curNb);
 
     if (layers->isTcp) {
-        NDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO tsoInfo;
-
-        tsoInfo.Value = NET_BUFFER_LIST_INFO(curNbl,
-                                             TcpLargeSendNetBufferListInfo);
-        switch (tsoInfo.Transmit.Type) {
-            case NDIS_TCP_LARGE_SEND_OFFLOAD_V1_TYPE:
-                mss = tsoInfo.LsoV1Transmit.MSS;
-                break;
-            case NDIS_TCP_LARGE_SEND_OFFLOAD_V2_TYPE:
-                mss = tsoInfo.LsoV2Transmit.MSS;
-                break;
-            default:
-                OVS_LOG_ERROR("Unknown LSO transmit type:%d",
-                              tsoInfo.Transmit.Type);
-        }
+        mss = OVSGetTcpMSS(curNbl);
+
         OVS_LOG_TRACE("MSS %u packet len %u", mss,
                       packetLength);
         if (mss) {
@@ -242,70 +229,14 @@ OvsDoEncapVxlan(POVS_VPORT_ENTRY vport,
             OVS_LOG_ERROR("Unable to copy NBL");
             return NDIS_STATUS_FAILURE;
         }
-        /*
-         * To this point we do not have VXLAN offloading.
-         * Apply defined checksums
-         */
-        curNb = NET_BUFFER_LIST_FIRST_NB(*newNbl);
-        curMdl = NET_BUFFER_CURRENT_MDL(curNb);
-        bufferStart = (PUINT8)MmGetSystemAddressForMdlSafe(curMdl, 
LowPagePriority);
-        if (!bufferStart) {
-            status = NDIS_STATUS_RESOURCES;
-            goto ret_error;
-        }
-
         NDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO csumInfo;
         csumInfo.Value = NET_BUFFER_LIST_INFO(curNbl,
                                               TcpIpChecksumNetBufferListInfo);
+        status = OvsApplySWChecksumOnNB(layers, *newNbl, &csumInfo);
 
-        bufferStart += NET_BUFFER_CURRENT_MDL_OFFSET(curNb);
-
-        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 (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 (status != NDIS_STATUS_SUCCESS) {
+            goto ret_error;
         }
-        /* Clear out TcpIpChecksumNetBufferListInfo flag */
-        NET_BUFFER_LIST_INFO(*newNbl, TcpIpChecksumNetBufferListInfo) = 0;
     }
 
     curNbl = *newNbl;
--
1.9.5.msysgit.0
_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev
_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to