From patchwork Mon Feb 22 14:07:18 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sorin Vinturis X-Patchwork-Id: 586182 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from archives.nicira.com (archives.nicira.com [96.126.127.54]) by ozlabs.org (Postfix) with ESMTP id 7854A140BA3 for ; Tue, 23 Feb 2016 01:09:26 +1100 (AEDT) Received: from archives.nicira.com (localhost [127.0.0.1]) by archives.nicira.com (Postfix) with ESMTP id BB02A106B0; Mon, 22 Feb 2016 06:09:25 -0800 (PST) X-Original-To: dev@openvswitch.org Delivered-To: dev@openvswitch.org Received: from mx1e3.cudamail.com (mx1.cudamail.com [69.90.118.67]) by archives.nicira.com (Postfix) with ESMTPS id 26CF5106C5 for ; Mon, 22 Feb 2016 06:09:24 -0800 (PST) Received: from bar5.cudamail.com (localhost [127.0.0.1]) by mx1e3.cudamail.com (Postfix) with ESMTPS id A76BD42030F for ; Mon, 22 Feb 2016 07:09:23 -0700 (MST) X-ASG-Debug-ID: 1456150163-09eadd66192c290001-byXFYA Received: from mx1-pf1.cudamail.com ([192.168.24.1]) by bar5.cudamail.com with ESMTP id VWYRekzDlO2q531S (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Mon, 22 Feb 2016 07:09:23 -0700 (MST) X-Barracuda-Envelope-From: svinturis@cloudbasesolutions.com X-Barracuda-RBL-Trusted-Forwarder: 192.168.24.1 Received: from unknown (HELO cbssmtp1.cloudbase.local) (91.232.152.5) by mx1-pf1.cudamail.com with SMTP; 22 Feb 2016 14:09:22 -0000 Received-SPF: pass (mx1-pf1.cudamail.com: SPF record at cloudbasesolutions.com designates 91.232.152.5 as permitted sender) X-Barracuda-Apparent-Source-IP: 91.232.152.5 X-Barracuda-RBL-IP: 91.232.152.5 Received: from localhost (localhost [127.0.0.1]) by cbssmtp1.cloudbase.local (Postfix) with ESMTP id 4A47F41777 for ; Mon, 22 Feb 2016 16:09:21 +0200 (EET) X-Virus-Scanned: amavisd-new at cloudbasesolutions.com Received: from cbssmtp1.cloudbase.local ([127.0.0.1]) by localhost (cbssmtp1.cloudbase.local [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id nF8tVYD_ApU6 for ; Mon, 22 Feb 2016 16:09:00 +0200 (EET) Received: from CBSEX1.cloudbase.local (unknown [10.77.78.3]) by cbssmtp1.cloudbase.local (Postfix) with ESMTP id D92604176E for ; Mon, 22 Feb 2016 16:07:19 +0200 (EET) Received: from CBSEX1.cloudbase.local ([10.77.78.3]) by CBSEX1.cloudbase.local ([10.77.78.3]) with mapi id 14.03.0224.002; Mon, 22 Feb 2016 15:07:19 +0100 X-CudaMail-Envelope-Sender: svinturis@cloudbasesolutions.com From: Sorin Vinturis To: "dev@openvswitch.org" X-CudaMail-MID: CM-E1-221018566 X-CudaMail-DTE: 022216 X-CudaMail-Originating-IP: 91.232.152.5 Thread-Topic: [PATCH v3 6/6] datapath-windows: Sample action support. X-ASG-Orig-Subj: [##CM-E1-221018566##][PATCH v3 6/6] datapath-windows: Sample action support. Thread-Index: AQHRbXpXPkXAILXtlU+zIY7aIDkVrg== Date: Mon, 22 Feb 2016 14:07:18 +0000 Message-ID: <1453469461-28267-7-git-send-email-svinturis@cloudbasesolutions.com> References: <1453469461-28267-1-git-send-email-svinturis@cloudbasesolutions.com> In-Reply-To: <1453469461-28267-1-git-send-email-svinturis@cloudbasesolutions.com> Accept-Language: en-US, it-IT Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [10.77.78.1] MIME-Version: 1.0 X-GBUdb-Analysis: 0, 91.232.152.5, Ugly c=0.247104 p=-0.454545 Source Normal X-MessageSniffer-Rules: 0-0-0-21340-c X-Barracuda-Connect: UNKNOWN[192.168.24.1] X-Barracuda-Start-Time: 1456150163 X-Barracuda-Encrypted: DHE-RSA-AES256-SHA X-Barracuda-URL: https://web.cudamail.com:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at cudamail.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.10 X-Barracuda-Spam-Status: No, SCORE=0.10 using per-user scores of TAG_LEVEL=3.5 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=4.0 tests=RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.27238 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS Subject: [ovs-dev] [PATCH v3 6/6] datapath-windows: Sample action support. X-BeenThere: dev@openvswitch.org X-Mailman-Version: 2.1.16 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@openvswitch.org Sender: "dev" This patch adds support for sampling to the OVS extension. Signed-off-by: Sorin Vinturis --- 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 @@ +