#pragma warning( push )
#pragma warning( disable:4127 )
-extern PNDIS_SPIN_LOCK gOvsCtrlLock;
extern POVS_SWITCH_CONTEXT gOvsSwitchContext;
extern UINT64 ovsTimeIncrementPerTick;
.maxLen = sizeof(struct ovs_flow_stats),
.optional = TRUE},
[OVS_FLOW_ATTR_TCP_FLAGS] = {NL_A_U8, .optional = TRUE},
- [OVS_FLOW_ATTR_USED] = {NL_A_U64, .optional = TRUE}
+ [OVS_FLOW_ATTR_USED] = {NL_A_U64, .optional = TRUE},
+ [OVS_FLOW_ATTR_PROBE] = {.type = NL_A_FLAG, .optional = TRUE}
};
/* For Parsing nested OVS_FLOW_ATTR_KEY attributes.
.maxLen = 4, .optional = TRUE},
[OVS_KEY_ATTR_MPLS] = {.type = NL_A_VAR_LEN, .optional = TRUE}
};
+const UINT32 nlFlowKeyPolicyLen = ARRAY_SIZE(nlFlowKeyPolicy);
/* For Parsing nested OVS_KEY_ATTR_TUNNEL attributes */
const NL_POLICY nlFlowTunnelKeyPolicy[] = {
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);
OvsFlowStats stats;
struct ovs_flow_stats replyStats;
NL_ERROR nlError = NL_ERROR_SUCCESS;
-
NL_BUFFER nlBuf;
RtlZeroMemory(&mappedFlow, sizeof(OvsFlowPut));
/* Get all the top level Flow attributes */
if ((NlAttrParse(nlMsgHdr, attrOffset, NlMsgAttrsLen(nlMsgHdr),
- nlFlowPolicy, nlAttrs, ARRAY_SIZE(nlAttrs)))
+ nlFlowPolicy, ARRAY_SIZE(nlFlowPolicy),
+ nlAttrs, ARRAY_SIZE(nlAttrs)))
!= TRUE) {
OVS_LOG_ERROR("Attr Parsing failed for msg: %p",
nlMsgHdr);
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;
}
}
goto done;
}
+ if (flowAttrs[OVS_FLOW_ATTR_PROBE]) {
+ OVS_LOG_ERROR("Attribute OVS_FLOW_ATTR_PROBE not supported");
+ nlError = NL_ERROR_NOENT;
+ goto done;
+ }
+
if ((rc = _MapNlToFlowPut(msgIn, nlAttrs[OVS_FLOW_ATTR_KEY],
nlAttrs[OVS_FLOW_ATTR_ACTIONS], nlAttrs[OVS_FLOW_ATTR_CLEAR],
&mappedFlow))
rc = OvsPutFlowIoctl(&mappedFlow, sizeof (struct OvsFlowPut),
&stats);
if (rc != STATUS_SUCCESS) {
- OVS_LOG_ERROR("OvsFlowPut failed.");
+ OVS_LOG_ERROR("OvsPutFlowIoctl failed.");
goto done;
}
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 */
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;
}
(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;
UINT32 *replyLen)
{
NTSTATUS rc = STATUS_SUCCESS;
- POVS_OPEN_INSTANCE instance = (POVS_OPEN_INSTANCE)
- (usrParamsCtx->ovsInstance);
- POVS_MESSAGE msgIn = instance->dumpState.ovsMsg;
+ POVS_MESSAGE msgIn = (POVS_MESSAGE)usrParamsCtx->inputBuffer;
PNL_MSG_HDR nlMsgHdr = &(msgIn->nlMsg);
POVS_HDR ovsHdr = &(msgIn->ovsHdr);
PNL_MSG_HDR nlMsgOutHdr = NULL;
RtlZeroMemory(&getOutput, sizeof(OvsFlowGetOutput));
UINT32 keyAttrOffset = 0;
UINT32 tunnelKeyAttrOffset = 0;
+ BOOLEAN ok;
if (usrParamsCtx->inputLength > usrParamsCtx->outputLength) {
/* Should not be the case.
/* Get all the top level Flow attributes */
if ((NlAttrParse(nlMsgHdr, attrOffset, NlMsgAttrsLen(nlMsgHdr),
- nlFlowPolicy, nlAttrs, ARRAY_SIZE(nlAttrs)))
+ nlFlowPolicy, ARRAY_SIZE(nlFlowPolicy),
+ nlAttrs, ARRAY_SIZE(nlAttrs)))
!= TRUE) {
OVS_LOG_ERROR("Attr Parsing failed for msg: %p",
nlMsgHdr);
/* Get flow keys attributes */
if ((NlAttrParseNested(nlMsgHdr, keyAttrOffset,
NlAttrLen(nlAttrs[OVS_FLOW_ATTR_KEY]),
- nlFlowKeyPolicy, keyAttrs, ARRAY_SIZE(keyAttrs)))
+ nlFlowKeyPolicy, ARRAY_SIZE(nlFlowKeyPolicy),
+ keyAttrs, ARRAY_SIZE(keyAttrs)))
!= TRUE) {
OVS_LOG_ERROR("Key Attr Parsing failed for msg: %p",
nlMsgHdr);
/* Get tunnel keys attributes */
if ((NlAttrParseNested(nlMsgHdr, tunnelKeyAttrOffset,
NlAttrLen(keyAttrs[OVS_KEY_ATTR_TUNNEL]),
- nlFlowTunnelKeyPolicy,
+ nlFlowTunnelKeyPolicy,
+ ARRAY_SIZE(nlFlowTunnelKeyPolicy),
tunnelAttrs, ARRAY_SIZE(tunnelAttrs)))
!= TRUE) {
OVS_LOG_ERROR("Tunnel key Attr Parsing failed for msg: %p",
/* 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) {
/*
*----------------------------------------------------------------------------
* _FlowNlDumpCmdHandler --
- * Handler for OVS_FLOW_CMD_GET command.
+ * Handler for OVS_FLOW_CMD_DUMP command.
*----------------------------------------------------------------------------
*/
NTSTATUS
/* 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);
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;
/* Get flow keys attributes */
if ((NlAttrParseNested(nlMsgHdr, keyAttrOffset, NlAttrLen(keyAttr),
- nlFlowKeyPolicy, keyAttrs, ARRAY_SIZE(keyAttrs)))
+ nlFlowKeyPolicy, ARRAY_SIZE(nlFlowKeyPolicy),
+ keyAttrs, ARRAY_SIZE(keyAttrs)))
!= TRUE) {
OVS_LOG_ERROR("Key Attr Parsing failed for msg: %p",
nlMsgHdr);
(keyAttrs[OVS_KEY_ATTR_TUNNEL])
- (PCHAR)nlMsgHdr);
- OVS_LOG_ERROR("Parse Flow Tunnel Key Policy");
-
/* Get tunnel keys attributes */
if ((NlAttrParseNested(nlMsgHdr, tunnelKeyAttrOffset,
NlAttrLen(keyAttrs[OVS_KEY_ATTR_TUNNEL]),
nlFlowTunnelKeyPolicy,
+ ARRAY_SIZE(nlFlowTunnelKeyPolicy),
tunnelAttrs, ARRAY_SIZE(tunnelAttrs)))
!= TRUE) {
OVS_LOG_ERROR("Tunnel key Attr Parsing failed for msg: %p",
}
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;
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;
}
}
datapath->lock = NdisAllocateRWLock(switchContext->NdisFilterHandle);
+ if (!datapath->lock) {
+ return NDIS_STATUS_RESOURCES;
+ }
+
return NDIS_STATUS_SUCCESS;
}
{
OvsFlow *f = *flow;
*flow = NULL;
- UNREFERENCED_PARAMETER(datapath);
ASSERT(datapath->nFlows);
datapath->nFlows--;
FreeFlow(OvsFlow *flow)
{
ASSERT(flow);
- OvsFreeMemory(flow);
+ OvsFreeMemoryWithTag(flow, OVS_FLOW_POOL_TAG);
}
NTSTATUS
BOOLEAN findNextNonEmpty = FALSE;
dpNo = dumpInput->dpNo;
- NdisAcquireSpinLock(gOvsCtrlLock);
- if (gOvsSwitchContext == NULL ||
- gOvsSwitchContext->dpNo != dpNo) {
+ 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;
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,
}
dpNo = put->dpNo;
- NdisAcquireSpinLock(gOvsCtrlLock);
- if (gOvsSwitchContext == NULL ||
- gOvsSwitchContext->dpNo != dpNo) {
+ 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;
}
status = OvsPrepareFlow(&KernelFlow, put, hash);
if (status != STATUS_SUCCESS) {
- FreeFlow(KernelFlow);
return STATUS_UNSUCCESSFUL;
}
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;
}
dpNo = getInput->dpNo;
- NdisAcquireSpinLock(gOvsCtrlLock);
- if (gOvsSwitchContext == NULL ||
- gOvsSwitchContext->dpNo != dpNo) {
+ 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;
dp_unlock:
OvsReleaseDatapath(datapath, &dpLockState);
-unlock:
- NdisReleaseSpinLock(gOvsCtrlLock);
+exit:
return status;
}
OVS_DATAPATH *datapath = NULL;
LOCK_STATE_EX dpLockState;
- NdisAcquireSpinLock(gOvsCtrlLock);
- if (gOvsSwitchContext == NULL ||
- gOvsSwitchContext->dpNo != dpNo) {
+ 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;
}