X-Git-Url: http://git.cascardo.eti.br/?a=blobdiff_plain;f=datapath-windows%2Fovsext%2FFlow.c;h=69b546a587cee662d2844cc614fec300109dfa82;hb=706c0c0c17adcb3feb0e51e48c4e4a362f0e7ae9;hp=1257377765a50d34242cc8c2d5738ad6a87fc9e5;hpb=f8cb1dbb2484d42a232060cdd7091455a8806adc;p=cascardo%2Fovs.git diff --git a/datapath-windows/ovsext/Flow.c b/datapath-windows/ovsext/Flow.c index 125737776..69b546a58 100644 --- a/datapath-windows/ovsext/Flow.c +++ b/datapath-windows/ovsext/Flow.c @@ -31,7 +31,6 @@ #pragma warning( push ) #pragma warning( disable:4127 ) -extern PNDIS_SPIN_LOCK gOvsCtrlLock; extern POVS_SWITCH_CONTEXT gOvsSwitchContext; extern UINT64 ovsTimeIncrementPerTick; @@ -247,6 +246,7 @@ OvsFlowNlCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx, UINT32 *replyLen) { NTSTATUS rc = STATUS_SUCCESS; + BOOLEAN ok; POVS_MESSAGE msgIn = (POVS_MESSAGE)usrParamsCtx->inputBuffer; POVS_MESSAGE msgOut = (POVS_MESSAGE)usrParamsCtx->outputBuffer; PNL_MSG_HDR nlMsgHdr = &(msgIn->nlMsg); @@ -258,7 +258,6 @@ OvsFlowNlCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx, OvsFlowStats stats; struct ovs_flow_stats replyStats; NL_ERROR nlError = NL_ERROR_SUCCESS; - NL_BUFFER nlBuf; RtlZeroMemory(&mappedFlow, sizeof(OvsFlowPut)); @@ -294,13 +293,14 @@ OvsFlowNlCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx, usrParamsCtx->outputLength); /* Prepare nl Msg headers */ - rc = NlFillOvsMsg(&nlBuf, nlMsgHdr->nlmsgType, 0, + ok = NlFillOvsMsg(&nlBuf, nlMsgHdr->nlmsgType, 0, nlMsgHdr->nlmsgSeq, nlMsgHdr->nlmsgPid, genlMsgHdr->cmd, OVS_FLOW_VERSION, ovsHdr->dp_ifindex); - - if (rc == STATUS_SUCCESS) { + if (ok) { *replyLen = msgOut->nlMsg.nlmsgLen; + } else { + rc = STATUS_INVALID_BUFFER_SIZE; } } @@ -318,7 +318,7 @@ OvsFlowNlCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx, rc = OvsPutFlowIoctl(&mappedFlow, sizeof (struct OvsFlowPut), &stats); if (rc != STATUS_SUCCESS) { - OVS_LOG_ERROR("OvsFlowPut failed."); + OVS_LOG_ERROR("OvsPutFlowIoctl failed."); goto done; } @@ -330,13 +330,15 @@ OvsFlowNlCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx, usrParamsCtx->outputLength); /* Prepare nl Msg headers */ - rc = NlFillOvsMsg(&nlBuf, nlMsgHdr->nlmsgType, 0, + ok = NlFillOvsMsg(&nlBuf, nlMsgHdr->nlmsgType, 0, nlMsgHdr->nlmsgSeq, nlMsgHdr->nlmsgPid, genlMsgHdr->cmd, OVS_FLOW_VERSION, ovsHdr->dp_ifindex); - - if (rc != STATUS_SUCCESS) { + if (!ok) { + rc = STATUS_INVALID_BUFFER_SIZE; goto done; + } else { + rc = STATUS_SUCCESS; } /* Append OVS_FLOW_ATTR_STATS attribute */ @@ -355,7 +357,7 @@ done: if (nlError != NL_ERROR_SUCCESS) { POVS_MESSAGE_ERROR msgError = (POVS_MESSAGE_ERROR) usrParamsCtx->outputBuffer; - BuildErrorMsg(msgIn, msgError, nlError); + NlBuildErrorMsg(msgIn, msgError, nlError); *replyLen = msgError->nlMsg.nlmsgLen; rc = STATUS_SUCCESS; } @@ -387,7 +389,7 @@ OvsFlowNlGetCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx, (usrParamsCtx->outputBuffer)) { POVS_MESSAGE_ERROR msgError = (POVS_MESSAGE_ERROR) usrParamsCtx->outputBuffer; - BuildErrorMsg(msgIn, msgError, nlError); + NlBuildErrorMsg(msgIn, msgError, nlError); *replyLen = msgError->nlMsg.nlmsgLen; status = STATUS_SUCCESS; goto done; @@ -430,6 +432,7 @@ _FlowNlGetCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx, RtlZeroMemory(&getOutput, sizeof(OvsFlowGetOutput)); UINT32 keyAttrOffset = 0; UINT32 tunnelKeyAttrOffset = 0; + BOOLEAN ok; if (usrParamsCtx->inputLength > usrParamsCtx->outputLength) { /* Should not be the case. @@ -503,8 +506,12 @@ _FlowNlGetCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx, /* Input already has all the attributes for the flow key. * Lets copy the values back. */ - RtlCopyMemory(usrParamsCtx->outputBuffer, usrParamsCtx->inputBuffer, - usrParamsCtx->inputLength); + ok = NlMsgPutTail(&nlBuf, (PCHAR)(usrParamsCtx->inputBuffer), + usrParamsCtx->inputLength); + if (!ok) { + OVS_LOG_ERROR("Could not copy the data to the buffer tail"); + goto done; + } rc = _MapFlowStatsToNlStats(&nlBuf, &((getOutput.info).stats)); if (rc != STATUS_SUCCESS) { @@ -586,15 +593,20 @@ _FlowNlDumpCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx, /* Done with Dump, send NLMSG_DONE */ if (!(dumpOutput.n)) { + BOOLEAN ok; + OVS_LOG_INFO("Dump Done"); nlMsgOutHdr = (PNL_MSG_HDR)(NlBufAt(&nlBuf, NlBufSize(&nlBuf), 0)); - rc = NlFillNlHdr(&nlBuf, NLMSG_DONE, NLM_F_MULTI, + ok = NlFillNlHdr(&nlBuf, NLMSG_DONE, NLM_F_MULTI, nlMsgHdr->nlmsgSeq, nlMsgHdr->nlmsgPid); - if (rc != STATUS_SUCCESS) { + if (!ok) { + rc = STATUS_INVALID_BUFFER_SIZE; OVS_LOG_ERROR("Unable to prepare DUMP_DONE reply."); break; + } else { + rc = STATUS_SUCCESS; } NlMsgAlignSize(nlMsgOutHdr); @@ -603,17 +615,18 @@ _FlowNlDumpCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx, FreeUserDumpState(instance); break; } else { + BOOLEAN ok; hdrOffset = NlBufSize(&nlBuf); nlMsgOutHdr = (PNL_MSG_HDR)(NlBufAt(&nlBuf, hdrOffset, 0)); /* Netlink header */ - rc = NlFillOvsMsg(&nlBuf, nlMsgHdr->nlmsgType, NLM_F_MULTI, + ok = NlFillOvsMsg(&nlBuf, nlMsgHdr->nlmsgType, NLM_F_MULTI, nlMsgHdr->nlmsgSeq, nlMsgHdr->nlmsgPid, genlMsgHdr->cmd, genlMsgHdr->version, ovsHdr->dp_ifindex); - if (rc != STATUS_SUCCESS) { + if (!ok) { /* Reset rc to success so that we can * send already added messages to user space. */ rc = STATUS_SUCCESS; @@ -1498,8 +1511,13 @@ OvsDeleteFlowTable(OVS_DATAPATH *datapath) } DeleteAllFlows(datapath); - OvsFreeMemory(datapath->flowTable); + OvsFreeMemoryWithTag(datapath->flowTable, OVS_FLOW_POOL_TAG); datapath->flowTable = NULL; + + if (datapath->lock == NULL) { + return NDIS_STATUS_SUCCESS; + } + NdisFreeRWLock(datapath->lock); return NDIS_STATUS_SUCCESS; @@ -1520,8 +1538,8 @@ OvsAllocateFlowTable(OVS_DATAPATH *datapath, PLIST_ENTRY bucket; int i; - datapath->flowTable = OvsAllocateMemory(OVS_FLOW_TABLE_SIZE * - sizeof (LIST_ENTRY)); + datapath->flowTable = OvsAllocateMemoryWithTag( + OVS_FLOW_TABLE_SIZE * sizeof(LIST_ENTRY), OVS_FLOW_POOL_TAG); if (!datapath->flowTable) { return NDIS_STATUS_RESOURCES; } @@ -1531,6 +1549,10 @@ OvsAllocateFlowTable(OVS_DATAPATH *datapath, } datapath->lock = NdisAllocateRWLock(switchContext->NdisFilterHandle); + if (!datapath->lock) { + return NDIS_STATUS_RESOURCES; + } + return NDIS_STATUS_SUCCESS; } @@ -1873,7 +1895,6 @@ RemoveFlow(OVS_DATAPATH *datapath, { OvsFlow *f = *flow; *flow = NULL; - UNREFERENCED_PARAMETER(datapath); ASSERT(datapath->nFlows); datapath->nFlows--; @@ -1963,7 +1984,7 @@ VOID FreeFlow(OvsFlow *flow) { ASSERT(flow); - OvsFreeMemory(flow); + OvsFreeMemoryWithTag(flow, OVS_FLOW_POOL_TAG); } NTSTATUS @@ -1982,25 +2003,23 @@ OvsDoDumpFlows(OvsFlowDumpInput *dumpInput, BOOLEAN findNextNonEmpty = FALSE; dpNo = dumpInput->dpNo; - NdisAcquireSpinLock(gOvsCtrlLock); if (gOvsSwitchContext->dpNo != dpNo) { status = STATUS_INVALID_PARAMETER; - goto unlock; + goto exit; } rowIndex = dumpInput->position[0]; if (rowIndex >= OVS_FLOW_TABLE_SIZE) { dumpOutput->n = 0; *replyLen = sizeof(*dumpOutput); - goto unlock; + goto exit; } columnIndex = dumpInput->position[1]; datapath = &gOvsSwitchContext->datapath; ASSERT(datapath); - ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL); - OvsAcquireDatapathRead(datapath, &dpLockState, TRUE); + OvsAcquireDatapathRead(datapath, &dpLockState, FALSE); head = &datapath->flowTable[rowIndex]; node = head->Flink; @@ -2049,33 +2068,10 @@ OvsDoDumpFlows(OvsFlowDumpInput *dumpInput, dp_unlock: OvsReleaseDatapath(datapath, &dpLockState); -unlock: - NdisReleaseSpinLock(gOvsCtrlLock); +exit: return status; } -NTSTATUS -OvsDumpFlowIoctl(PVOID inputBuffer, - UINT32 inputLength, - PVOID outputBuffer, - UINT32 outputLength, - UINT32 *replyLen) -{ - OvsFlowDumpOutput *dumpOutput = (OvsFlowDumpOutput *)outputBuffer; - OvsFlowDumpInput *dumpInput = (OvsFlowDumpInput *)inputBuffer; - - if (inputBuffer == NULL || outputBuffer == NULL) { - return STATUS_INVALID_PARAMETER; - } - - if ((inputLength != sizeof(OvsFlowDumpInput)) - || (outputLength != sizeof *dumpOutput + dumpInput->actionsLen)) { - return STATUS_INFO_LENGTH_MISMATCH; - } - - return OvsDoDumpFlows(dumpInput, dumpOutput, replyLen); -} - static NTSTATUS ReportFlowInfo(OvsFlow *flow, UINT32 getFlags, @@ -2133,21 +2129,18 @@ OvsPutFlowIoctl(PVOID inputBuffer, } dpNo = put->dpNo; - NdisAcquireSpinLock(gOvsCtrlLock); if (gOvsSwitchContext->dpNo != dpNo) { status = STATUS_INVALID_PARAMETER; - goto unlock; + goto exit; } datapath = &gOvsSwitchContext->datapath; ASSERT(datapath); - ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL); - OvsAcquireDatapathWrite(datapath, &dpLockState, TRUE); + OvsAcquireDatapathWrite(datapath, &dpLockState, FALSE); status = HandleFlowPut(put, datapath, stats); OvsReleaseDatapath(datapath, &dpLockState); -unlock: - NdisReleaseSpinLock(gOvsCtrlLock); +exit: return status; } @@ -2179,7 +2172,6 @@ HandleFlowPut(OvsFlowPut *put, status = OvsPrepareFlow(&KernelFlow, put, hash); if (status != STATUS_SUCCESS) { - FreeFlow(KernelFlow); return STATUS_UNSUCCESSFUL; } @@ -2268,7 +2260,8 @@ OvsPrepareFlow(OvsFlow **flow, do { *flow = localFlow = - OvsAllocateMemory(sizeof(OvsFlow) + put->actionsLen); + OvsAllocateMemoryWithTag(sizeof(OvsFlow) + put->actionsLen, + OVS_FLOW_POOL_TAG); if (localFlow == NULL) { status = STATUS_NO_MEMORY; break; @@ -2314,16 +2307,14 @@ OvsGetFlowIoctl(PVOID inputBuffer, } dpNo = getInput->dpNo; - NdisAcquireSpinLock(gOvsCtrlLock); if (gOvsSwitchContext->dpNo != dpNo) { status = STATUS_INVALID_PARAMETER; - goto unlock; + goto exit; } datapath = &gOvsSwitchContext->datapath; ASSERT(datapath); - ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL); - OvsAcquireDatapathRead(datapath, &dpLockState, TRUE); + OvsAcquireDatapathRead(datapath, &dpLockState, FALSE); flow = OvsLookupFlow(datapath, &getInput->key, &hash, FALSE); if (!flow) { status = STATUS_INVALID_PARAMETER; @@ -2335,8 +2326,7 @@ OvsGetFlowIoctl(PVOID inputBuffer, dp_unlock: OvsReleaseDatapath(datapath, &dpLockState); -unlock: - NdisReleaseSpinLock(gOvsCtrlLock); +exit: return status; } @@ -2347,21 +2337,18 @@ OvsFlushFlowIoctl(UINT32 dpNo) OVS_DATAPATH *datapath = NULL; LOCK_STATE_EX dpLockState; - NdisAcquireSpinLock(gOvsCtrlLock); if (gOvsSwitchContext->dpNo != dpNo) { status = STATUS_INVALID_PARAMETER; - goto unlock; + goto exit; } datapath = &gOvsSwitchContext->datapath; ASSERT(datapath); - ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL); - OvsAcquireDatapathWrite(datapath, &dpLockState, TRUE); + OvsAcquireDatapathWrite(datapath, &dpLockState, FALSE); DeleteAllFlows(datapath); OvsReleaseDatapath(datapath, &dpLockState); -unlock: - NdisReleaseSpinLock(gOvsCtrlLock); +exit: return status; }