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
