Sai, this patch is dependent on the recirculation patch, and, because it is 
ready, I have added it to the recirculation series instead of waiting for 
recirculation to be pushed to master then pushed it as a single patch.

-----Original Message-----
From: Sairam Venugopal [mailto:[email protected]] 
Sent: Friday, 26 February, 2016 22:01
To: Sorin Vinturis; [email protected]
Subject: Re: [ovs-dev] [PATCH v3 6/6] datapath-windows: Sample action support.

I think this should be a separate email/patch and not tied to Recirculation.


On 2/22/16, 6:07 AM, "Sorin Vinturis" <[email protected]>
wrote:

>This patch adds support for sampling to the OVS extension.
>
>Signed-off-by: Sorin Vinturis <[email protected]>
>---
>v3: No previous version.
>---
> datapath-windows/automake.mk           |   1 +
> datapath-windows/ovsext/Actions.c      | 183
>+++++++++++++++++++++++++++------
> datapath-windows/ovsext/Random.h       |  49 +++++++++
> datapath-windows/ovsext/ovsext.vcxproj |   1 +
> 4 files changed, 201 insertions(+), 33 deletions(-) create mode 100644 
> datapath-windows/ovsext/Random.h
>
>diff --git a/datapath-windows/automake.mk 
>b/datapath-windows/automake.mk index 04fc97f..1eb2be1 100644
>--- a/datapath-windows/automake.mk
>+++ b/datapath-windows/automake.mk
>@@ -46,6 +46,7 @@ EXTRA_DIST += \
>       datapath-windows/ovsext/PacketIO.h \
>       datapath-windows/ovsext/PacketParser.c \
>       datapath-windows/ovsext/PacketParser.h \
>+      datapath-windows/ovsext/Random.h \
>       datapath-windows/ovsext/Recirc.c \
>       datapath-windows/ovsext/Recirc.h \
>       datapath-windows/ovsext/Stt.c \
>diff --git a/datapath-windows/ovsext/Actions.c
>b/datapath-windows/ovsext/Actions.c
>index d3f9be4..f5b1410 100644
>--- a/datapath-windows/ovsext/Actions.c
>+++ b/datapath-windows/ovsext/Actions.c
>@@ -24,6 +24,7 @@
> #include "NetProto.h"
> #include "Offload.h"
> #include "PacketIO.h"
>+#include "Random.h"
> #include "Recirc.h"
> #include "Stt.h"
> #include "Switch.h"
>@@ -1585,6 +1586,132 @@ OvsActionExecuteHash(OvsFlowKey *key,
>         hash = 1;
> 
>     key->dpHash = hash;
>+}
>+
>+/*
>+ *
>-----------------------------------------------------------------------
>---
>+ * OvsOutputUserspaceAction --
>+ *      Executes a sample action.
>+ *
>-----------------------------------------------------------------------
>---
>+ */
>+static __inline NDIS_STATUS
>+OvsOutputUserspaceAction(OvsForwardingContext *ovsFwdCtx,
>+                         OvsFlowKey *key,
>+                         const PNL_ATTR attr) {
>+    NTSTATUS status = NDIS_STATUS_SUCCESS;
>+    PNL_ATTR userdataAttr;
>+    PNL_ATTR queueAttr;
>+    POVS_PACKET_QUEUE_ELEM elem;
>+    POVS_PACKET_HDR_INFO layers = &ovsFwdCtx->layers;
>+    BOOLEAN isRecv = FALSE;
>+
>+    POVS_VPORT_ENTRY vport =
>OvsFindVportByPortNo(ovsFwdCtx->switchContext,
>+                                                  
>+ ovsFwdCtx->srcVportNo);
>+
>+    if (vport) {
>+        if (vport->isExternal ||
>+            OvsIsTunnelVportType(vport->ovsType)) {
>+            isRecv = TRUE;
>+        }
>+    }
>+
>+    queueAttr = NlAttrFindNested(attr, OVS_USERSPACE_ATTR_PID);
>+    userdataAttr = NlAttrFindNested(attr, 
>+ OVS_USERSPACE_ATTR_USERDATA);
>+
>+    elem = OvsCreateQueueNlPacket(NlAttrData(userdataAttr),
>+                                  NlAttrGetSize(userdataAttr),
>+                                  OVS_PACKET_CMD_ACTION,
>+                                  vport, key, ovsFwdCtx->curNbl,
>+                 
>NET_BUFFER_LIST_FIRST_NB(ovsFwdCtx->curNbl),
>+                                  isRecv,
>+                                  layers);
>+    if (elem) {
>+        LIST_ENTRY missedPackets;
>+        InitializeListHead(&missedPackets);
>+        InsertTailList(&missedPackets, &elem->link);
>+        OvsQueuePackets(&missedPackets, 1);
>+    } else {
>+        status = NDIS_STATUS_FAILURE;
>+    }
>+
>+    return status;
>+}
>+
>+/*
>+ *
>-----------------------------------------------------------------------
>---
>+ * OvsExecuteSampleAction --
>+ *      Executes a sample action.
>+ *
>-----------------------------------------------------------------------
>---
>+ */
>+static __inline NDIS_STATUS
>+OvsExecuteSampleAction(OvsForwardingContext *ovsFwdCtx,
>+                       OvsFlowKey *key,
>+                       UINT64 *hashAction,
>+                       const PNL_ATTR attr) {
>+    PNET_BUFFER_LIST newNbl = NULL;
>+    PNL_ATTR actionsList = NULL;
>+    PNL_ATTR a = NULL;
>+    INT rem = 0;
>+    UINT64 hash = 0;
>+
>+    SRand();
>+    NL_ATTR_FOR_EACH_UNSAFE(a, rem, NlAttrData(attr),
>NlAttrGetSize(attr)) {
>+        switch (NlAttrType(a)) {
>+        case OVS_SAMPLE_ATTR_PROBABILITY:
>+        {
>+            UINT32 probability = NlAttrGetU32(a);
>+
>+            if (!probability || Rand() > probability) {
>+                return 0;
>+            }
>+            break;
>+        }
>+        case OVS_SAMPLE_ATTR_ACTIONS:
>+            actionsList = a;
>+            break;
>+        }
>+    }
>+
>+    if (actionsList) {
>+        rem = NlAttrGetSize(actionsList);
>+        a = (PNL_ATTR)NlAttrData(actionsList);
>+    }
>+
>+    if (!rem) {
>+        /* Actions list is empty, do nothing */
>+        return STATUS_SUCCESS;
>+    }
>+
>+    /*
>+     * The only known usage of sample action is having a single
>user-space
>+     * action. Treat this usage as a special case.
>+     */
>+    if (NlAttrType(a) == OVS_ACTION_ATTR_USERSPACE &&
>+        NlAttrIsLast(a, rem)) {
>+        return OvsOutputUserspaceAction(ovsFwdCtx, key, a);
>+    }
>+
>+    newNbl = OvsPartialCopyNBL(ovsFwdCtx->switchContext,
>ovsFwdCtx->curNbl,
>+                               0, 0, TRUE /*copy NBL info*/);
>+    if (newNbl == NULL) {
>+        /*
>+         * Skip the sample action when out of memory, but continue on
>with the
>+         * rest of the action list.
>+         */
>+        ovsActionStats.noCopiedNbl++;
>+        return STATUS_SUCCESS;
>+    }
>+
>+    hash = hashAction ? *hashAction : OvsHashFlow(key);
>+    if (!OvsAddDeferredActions(newNbl, key, hash, a)) {
>+        OVS_LOG_INFO(
>+            "Deferred actions limit reached, dropping sample action.");
>+        OvsCompleteNBL(ovsFwdCtx->switchContext, newNbl, TRUE);
>+    }
>+
>+    return STATUS_SUCCESS;
> }
> 
> /*
>@@ -1807,43 +1934,15 @@ OvsDoExecuteActions(POVS_SWITCH_CONTEXT
>switchContext,
> 
>         case OVS_ACTION_ATTR_USERSPACE:
>         {
>-            PNL_ATTR userdataAttr;
>-            PNL_ATTR queueAttr;
>-            POVS_PACKET_QUEUE_ELEM elem;
>-            BOOLEAN isRecv = FALSE;
>-
>-            POVS_VPORT_ENTRY vport = OvsFindVportByPortNo(switchContext,
>-                portNo);
>-
>-            if (vport) {
>-                if (vport->isExternal ||
>-                    OvsIsTunnelVportType(vport->ovsType)) {
>-                    isRecv = TRUE;
>-                }
>-            }
>-
>-            queueAttr = NlAttrFindNested(a, OVS_USERSPACE_ATTR_PID);
>-            userdataAttr = NlAttrFindNested(a,
>OVS_USERSPACE_ATTR_USERDATA);
>-
>-            elem = OvsCreateQueueNlPacket((PVOID)userdataAttr,
>-                                    userdataAttr->nlaLen,
>-                                    OVS_PACKET_CMD_ACTION,
>-                                    vport, key, ovsFwdCtx.curNbl,
>-                 
>NET_BUFFER_LIST_FIRST_NB(ovsFwdCtx.curNbl),
>-                                    isRecv,
>-                                    layers);
>-            if (elem) {
>-                LIST_ENTRY missedPackets;
>-                InitializeListHead(&missedPackets);
>-                InsertTailList(&missedPackets, &elem->link);
>-                OvsQueuePackets(&missedPackets, 1);
>-                dropReason = L"OVS-Completed since packet was copied to "
>-                             L"userspace";
>-            } else {
>+            status = OvsOutputUserspaceAction(&ovsFwdCtx, key,
>+                                              (const PNL_ATTR)a);
>+            if (status != NDIS_STATUS_SUCCESS) {
>                 dropReason = L"OVS-Dropped due to failure to queue to "
>                              L"userspace";
>                 goto dropit;
>             }
>+            dropReason = L"OVS-Completed since packet was copied to "
>+                         L"userspace";
>             break;
>         }
>         case OVS_ACTION_ATTR_SET:
>@@ -1867,6 +1966,24 @@ OvsDoExecuteActions(POVS_SWITCH_CONTEXT
>switchContext,
>             break;
>         }
>         case OVS_ACTION_ATTR_SAMPLE:
>+        {
>+            if (ovsFwdCtx.destPortsSizeOut > 0 || 
>+ ovsFwdCtx.tunnelTxNic
>!= NULL
>+                || ovsFwdCtx.tunnelRxNic != NULL) {
>+                status = OvsOutputBeforeSetAction(&ovsFwdCtx);
>+                if (status != NDIS_STATUS_SUCCESS) {
>+                    dropReason = L"OVS-adding destination failed";
>+                    goto dropit;
>+                }
>+            }
>+
>+            status = OvsExecuteSampleAction(&ovsFwdCtx, key, hash,
>+                                            (const PNL_ATTR)a);
>+            if (status != NDIS_STATUS_SUCCESS) {
>+                dropReason = L"OVS-sample action failed";
>+                goto dropit;
>+            }
>+            break;
>+        }
>         default:
>             status = NDIS_STATUS_NOT_SUPPORTED;
>             break;
>diff --git a/datapath-windows/ovsext/Random.h
>b/datapath-windows/ovsext/Random.h
>new file mode 100644
>index 0000000..d8cc3d5
>--- /dev/null
>+++ b/datapath-windows/ovsext/Random.h
>@@ -0,0 +1,49 @@
>+/*
>+ * Copyright (c) 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.
>+ * You may obtain a copy of the License at:
>+ *
>+ *     http://www.apache.org/licenses/LICENSE-2.0
>+ *
>+ * Unless required by applicable law or agreed to in writing, software
>+ * distributed under the License is distributed on an "AS IS" BASIS,
>+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
>implied.
>+ * See the License for the specific language governing permissions and
>+ * limitations under the License.
>+ */
>+
>+#ifndef __RANDOM_H_
>+#define __RANDOM_H_ 1
>+
>+#include "precomp.h"
>+
>+static LARGE_INTEGER seed;
>+
>+/*
>+ 
>*----------------------------------------------------------------------
>---
>---
>+ *  SRand --
>+ *    This function sets the starting seed value for the pseudorandom
>number
>+ *    generator.
>+ 
>*----------------------------------------------------------------------
>---
>---
>+ */
>+static __inline
>+VOID SRand()
>+{
>+    KeQuerySystemTime(&seed);
>+}
>+
>+/*
>+ 
>*----------------------------------------------------------------------
>---
>---
>+ *  Rand --
>+ *    This function generates a pseudorandom number between 0 to
>UINT_MAX.
>+ 
>*----------------------------------------------------------------------
>---
>---
>+ */
>+static __inline
>+UINT32 Rand()
>+{
>+    return seed.LowPart *= 0x8088405 + 1; }
>+
>+#endif /* __RANDOM_H_ */
>diff --git a/datapath-windows/ovsext/ovsext.vcxproj
>b/datapath-windows/ovsext/ovsext.vcxproj
>index 36187a6..2e697da 100644
>--- a/datapath-windows/ovsext/ovsext.vcxproj
>+++ b/datapath-windows/ovsext/ovsext.vcxproj
>@@ -94,6 +94,7 @@
>     <ClInclude Include="PacketIO.h" />
>     <ClInclude Include="PacketParser.h" />
>     <ClInclude Include="precomp.h" />
>+    <ClInclude Include="Random.h" />
>     <ClInclude Include="Recirc.h" />
>     <ClInclude Include="resource.h" />
>     <ClInclude Include="Stt.h" />
>--
>1.9.0.msysgit.0
>_______________________________________________
>dev mailing list
>[email protected]
>http://openvswitch.org/mailman/listinfo/dev

_______________________________________________
dev mailing list
[email protected]
http://openvswitch.org/mailman/listinfo/dev

Reply via email to