[ovs-dev] [PATCH v3 2/4] datapath-windows: Add function to get continuous buffer from context

Alin Serdean aserdean at cloudbasesolutions.com
Thu Jan 26 23:45:16 UTC 2017


From: Alin Serdean <aserdean at cloudbasesolutions.com>

This patch extracts the code that tries to get a continuous IPv4 header
buffer from the function 'OvsUpdateIPv4Header' and moves it to a new
function 'OvsGetHeaderBySize'.

The new function can be used later when trying to change the UDP/TCP/MPLS
etc., headers.

Signed-off-by: Alin Gabriel Serdean <aserdean at cloudbasesolutions.com>
Acked-by: Sairam Venugopal <vsairam at vmware.com>
---
v3: add acked
v2: no change
---
 datapath-windows/ovsext/Actions.c | 100 +++++++++++++++++++++++---------------
 1 file changed, 62 insertions(+), 38 deletions(-)

diff --git a/datapath-windows/ovsext/Actions.c b/datapath-windows/ovsext/Actions.c
index 760888e..467bfbc 100644
--- a/datapath-windows/ovsext/Actions.c
+++ b/datapath-windows/ovsext/Actions.c
@@ -1306,64 +1306,51 @@ OvsUpdateEthHeader(OvsForwardingContext *ovsFwdCtx,
     return NDIS_STATUS_SUCCESS;
 }
 
+
 /*
  *----------------------------------------------------------------------------
- * OvsUpdateIPv4Header --
- *      Updates the IPv4 header in ovsFwdCtx.curNbl inline based on the
- *      specified key.
+ * OvsGetHeaderBySize --
+ *      Tries to retrieve a continuous buffer from 'ovsFwdCtx->curnbl' of size
+ *      'size'.
+ *      If the original buffer is insufficient it will, try to clone the net
+ *      buffer list and force the size.
+ *      Returns 'NULL' on failure or a pointer to the first byte of the data
+ *      in the first net buffer of the net buffer list 'nbl'.
  *----------------------------------------------------------------------------
  */
-static __inline NDIS_STATUS
-OvsUpdateIPv4Header(OvsForwardingContext *ovsFwdCtx,
-                    const struct ovs_key_ipv4 *ipAttr)
+PUINT8 OvsGetHeaderBySize(OvsForwardingContext *ovsFwdCtx,
+                          UINT32 size)
 {
     PNET_BUFFER curNb;
+    UINT32 mdlLen, packetLen;
     PMDL curMdl;
     ULONG curMdlOffset;
-    PUINT8 bufferStart;
-    UINT32 mdlLen, hdrSize, packetLen;
-    OVS_PACKET_HDR_INFO *layers = &ovsFwdCtx->layers;
-    NDIS_STATUS status;
-    IPHdr *ipHdr;
-    TCPHdr *tcpHdr = NULL;
-    UDPHdr *udpHdr = NULL;
-
-    ASSERT(layers->value != 0);
+    PUINT8 start;
 
-    /*
-     * Peek into the MDL to get a handle to the IP header and if required
-     * the TCP/UDP header as well. We check if the required headers are in one
-     * contiguous MDL, and if not, we copy them over to one MDL.
-     */
     curNb = NET_BUFFER_LIST_FIRST_NB(ovsFwdCtx->curNbl);
     ASSERT(curNb->Next == NULL);
     packetLen = NET_BUFFER_DATA_LENGTH(curNb);
     curMdl = NET_BUFFER_CURRENT_MDL(curNb);
-    NdisQueryMdl(curMdl, &bufferStart, &mdlLen, LowPagePriority);
-    if (!bufferStart) {
+    NdisQueryMdl(curMdl, &start, &mdlLen, LowPagePriority);
+    if (!start) {
         ovsActionStats.noResource++;
-        return NDIS_STATUS_RESOURCES;
+        return NULL;
     }
+
     curMdlOffset = NET_BUFFER_CURRENT_MDL_OFFSET(curNb);
     mdlLen -= curMdlOffset;
     ASSERT((INT)mdlLen >= 0);
 
-    if (layers->isTcp || layers->isUdp) {
-        hdrSize = layers->l4Offset +
-                  layers->isTcp ? sizeof (*tcpHdr) : sizeof (*udpHdr);
-    } else {
-        hdrSize = layers->l3Offset + sizeof (*ipHdr);
-    }
-
     /* Count of number of bytes of valid data there are in the first MDL. */
     mdlLen = MIN(packetLen, mdlLen);
-    if (mdlLen < hdrSize) {
+    if (mdlLen < size) {
         PNET_BUFFER_LIST newNbl;
+        NDIS_STATUS status;
         newNbl = OvsPartialCopyNBL(ovsFwdCtx->switchContext, ovsFwdCtx->curNbl,
-                                   hdrSize, 0, TRUE /*copy NBL info*/);
+                                   size, 0, TRUE /*copy NBL info*/);
         if (!newNbl) {
             ovsActionStats.noCopiedNbl++;
-            return NDIS_STATUS_RESOURCES;
+            return NULL;
         }
         OvsCompleteNBLForwardingCtx(ovsFwdCtx,
                                     L"Complete after partial copy.");
@@ -1372,25 +1359,62 @@ OvsUpdateIPv4Header(OvsForwardingContext *ovsFwdCtx,
                                       newNbl, ovsFwdCtx->srcVportNo, 0,
                                       NET_BUFFER_LIST_SWITCH_FORWARDING_DETAIL(newNbl),
                                       NULL, &ovsFwdCtx->layers, FALSE);
+
         if (status != NDIS_STATUS_SUCCESS) {
             OvsCompleteNBLForwardingCtx(ovsFwdCtx,
                                         L"OVS-Dropped due to resources");
-            return NDIS_STATUS_RESOURCES;
+            return NULL;
         }
 
         curNb = NET_BUFFER_LIST_FIRST_NB(ovsFwdCtx->curNbl);
         ASSERT(curNb->Next == NULL);
         curMdl = NET_BUFFER_CURRENT_MDL(curNb);
-        NdisQueryMdl(curMdl, &bufferStart, &mdlLen, LowPagePriority);
+        NdisQueryMdl(curMdl, &start, &mdlLen, LowPagePriority);
         if (!curMdl) {
             ovsActionStats.noResource++;
-            return NDIS_STATUS_RESOURCES;
+            return NULL;
         }
         curMdlOffset = NET_BUFFER_CURRENT_MDL_OFFSET(curNb);
         mdlLen -= curMdlOffset;
-        ASSERT(mdlLen >= hdrSize);
+        ASSERT(mdlLen >= size);
     }
-    bufferStart += curMdlOffset;
+
+    return start + curMdlOffset;
+}
+
+
+/*
+ *----------------------------------------------------------------------------
+ * OvsUpdateIPv4Header --
+ *      Updates the IPv4 header in ovsFwdCtx.curNbl inline based on the
+ *      specified key.
+ *----------------------------------------------------------------------------
+ */
+static __inline NDIS_STATUS
+OvsUpdateIPv4Header(OvsForwardingContext *ovsFwdCtx,
+                    const struct ovs_key_ipv4 *ipAttr)
+{
+    PUINT8 bufferStart;
+    UINT32 hdrSize;
+    OVS_PACKET_HDR_INFO *layers = &ovsFwdCtx->layers;
+    IPHdr *ipHdr;
+    TCPHdr *tcpHdr = NULL;
+    UDPHdr *udpHdr = NULL;
+
+    ASSERT(layers->value != 0);
+
+    if (layers->isTcp || layers->isUdp) {
+        hdrSize = layers->l4Offset +
+                  layers->isTcp ? sizeof (*tcpHdr) : sizeof (*udpHdr);
+    } else {
+        hdrSize = layers->l3Offset + sizeof (*ipHdr);
+    }
+
+    bufferStart = OvsGetHeaderBySize(ovsFwdCtx, hdrSize);
+    if (!bufferStart) {
+        return NDIS_STATUS_RESOURCES;
+    }
+
     ipHdr = (IPHdr *)(bufferStart + layers->l3Offset);
 
     if (layers->isTcp) {
-- 
2.10.2.windows.1


More information about the dev mailing list