[ovs-dev] [PATCH 5/5] datapath-windows: Multiple NBLs support for VXLAN packets

Sorin Vinturis svinturis at cloudbasesolutions.com
Thu Apr 23 21:05:15 UTC 2015


Added support for handling multiple NBLs with only one NB when
encapsulating VXLAN packets.

Signed-off-by: Sorin Vinturis <svinturis at cloudbasesolutions.com>
Reported-by: Alessandro Pilotti <apilotti at cloudbasesolutions.com>
Reported-at: https://github.com/openvswitch/ovs-issues/issues/2

---
 datapath-windows/ovsext/Actions.c | 21 ++++++++++++++++-----
 datapath-windows/ovsext/Vxlan.c   | 28 +++++++++++++++++++++-------
 2 files changed, 37 insertions(+), 12 deletions(-)

diff --git a/datapath-windows/ovsext/Actions.c b/datapath-windows/ovsext/Actions.c
index a93fe03..dbd5b5f 100644
--- a/datapath-windows/ovsext/Actions.c
+++ b/datapath-windows/ovsext/Actions.c
@@ -511,9 +511,9 @@ OvsCompleteNBLForwardingCtx(OvsForwardingContext *ovsFwdCtx,
  * OvsDoFlowLookupOutput --
  *     Function to be used for the second stage of a tunneling workflow, ie.:
  *     - On the encapsulated packet on Tx path, to do a flow extract, flow
- *       lookup and excuting the actions.
+ *       lookup and executing the actions.
  *     - On the decapsulated packet on Rx path, to do a flow extract, flow
- *       lookup and excuting the actions.
+ *       lookup and executing the actions.
  *
  *     XXX: It is assumed that the NBL in 'ovsFwdCtx' is owned by OVS. This is
  *     until the new buffer management framework is adopted.
@@ -607,6 +607,7 @@ OvsTunnelPortTx(OvsForwardingContext *ovsFwdCtx)
 {
     NDIS_STATUS status = NDIS_STATUS_FAILURE;
     PNET_BUFFER_LIST newNbl = NULL;
+    PNET_BUFFER_LIST nextNbl = NULL;
 
     /*
      * Setup the source port to be the internal port to as to facilitate the
@@ -644,9 +645,19 @@ OvsTunnelPortTx(OvsForwardingContext *ovsFwdCtx)
         ASSERT(newNbl);
         OvsCompleteNBLForwardingCtx(ovsFwdCtx,
                                     L"Complete after cloning NBL for encapsulation");
-        ovsFwdCtx->curNbl = newNbl;
-        status = OvsDoFlowLookupOutput(ovsFwdCtx);
-        ASSERT(ovsFwdCtx->curNbl == NULL);
+
+        while (newNbl) {
+            nextNbl = NET_BUFFER_LIST_NEXT_NBL(newNbl);
+            NET_BUFFER_LIST_NEXT_NBL(newNbl) = NULL;
+
+            ovsFwdCtx->curNbl = newNbl;
+            status = OvsDoFlowLookupOutput(ovsFwdCtx);
+            if (!NT_SUCCESS(status)) {
+                OVS_LOG_ERROR("Tx: OvsDoFlowLookupOutput failed, status: %x\n",
+                              status);
+            }
+            newNbl = nextNbl;
+        }
     } else {
         /*
         * XXX: Temporary freeing of the packet until we register a
diff --git a/datapath-windows/ovsext/Vxlan.c b/datapath-windows/ovsext/Vxlan.c
index 8c57185..2c6e698 100644
--- a/datapath-windows/ovsext/Vxlan.c
+++ b/datapath-windows/ovsext/Vxlan.c
@@ -116,6 +116,8 @@ OvsDoEncapVxlan(PNET_BUFFER_LIST curNbl,
     VXLANHdr *vxlanHdr;
     UINT32 headRoom = OvsGetVxlanTunHdrSize();
     UINT32 packetLength;
+    PNET_BUFFER_LIST nextNbl = NULL;
+    PNET_BUFFER_LIST prevNbl = NULL;
 
     /*
      * XXX: the assumption currently is that the NBL is owned by OVS, and
@@ -142,17 +144,18 @@ OvsDoEncapVxlan(PNET_BUFFER_LIST curNbl,
     }
     /* If we didn't split the packet above, make a copy now */
     if (*newNbl == NULL) {
-        *newNbl = OvsPartialCopyNBL(switchContext, curNbl, 0, headRoom,
-                                    FALSE /*NBL info*/);
+        *newNbl = OvsPartialCopyToMultipleNBLs(switchContext, curNbl, 0,
+                                               headRoom, FALSE /*NBL info*/);
         if (*newNbl == NULL) {
             OVS_LOG_ERROR("Unable to copy NBL");
             return NDIS_STATUS_FAILURE;
         }
     }
 
-    curNbl = *newNbl;
-    for (curNb = NET_BUFFER_LIST_FIRST_NB(curNbl); curNb != NULL;
-            curNb = curNb->Next) {
+    for (curNbl = *newNbl; curNbl != NULL; prevNbl = curNbl, curNbl = nextNbl) {
+        nextNbl = NET_BUFFER_LIST_NEXT_NBL(curNbl);
+
+        curNb = NET_BUFFER_LIST_FIRST_NB(curNbl);
         status = NdisRetreatNetBufferDataStart(curNb, headRoom, 0, NULL);
         if (status != NDIS_STATUS_SUCCESS) {
             goto ret_error;
@@ -223,8 +226,19 @@ OvsDoEncapVxlan(PNET_BUFFER_LIST curNbl,
     return STATUS_SUCCESS;
 
 ret_error:
-    OvsCompleteNBL(switchContext, *newNbl, TRUE);
-    *newNbl = NULL;
+    /* Complete erroneous curNbl and all the rest NBLs that follow. */
+    while (curNbl) {
+        nextNbl = NET_BUFFER_LIST_NEXT_NBL(curNbl);
+        NET_BUFFER_LIST_NEXT_NBL(curNbl) = NULL;
+        OvsCompleteNBL(switchContext, curNbl, TRUE);
+        if (prevNbl) {
+            /* Remove the link to the erroneous NBLs from newNbl list. */
+            NET_BUFFER_LIST_NEXT_NBL(prevNbl) = NULL;
+            prevNbl = NULL;
+        }
+        curNbl = nextNbl;
+    }
+
     return status;
 }
 
-- 
1.9.0.msysgit.0



More information about the dev mailing list