In this patch we added the code to handle transactional errors in flow commands.
Signed-off-by: Ankur Sharma <ankursha...@vmware.com> --- datapath-windows/ovsext/Flow.c | 54 +++++++++++++++++++------- datapath-windows/ovsext/Netlink/NetlinkError.h | 32 ++++++++++++++- 2 files changed, 70 insertions(+), 16 deletions(-) diff --git a/datapath-windows/ovsext/Flow.c b/datapath-windows/ovsext/Flow.c index 50fa954..5ed5c18 100644 --- a/datapath-windows/ovsext/Flow.c +++ b/datapath-windows/ovsext/Flow.c @@ -261,6 +261,7 @@ OvsFlowNlCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx, OvsFlowPut mappedFlow; OvsFlowStats stats; struct ovs_flow_stats replyStats; + NL_ERROR nlError = NL_ERROR_SUCCESS; NL_BUFFER nlBuf; @@ -276,7 +277,7 @@ OvsFlowNlCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx, != TRUE) { OVS_LOG_ERROR("Attr Parsing failed for msg: %p", nlMsgHdr); - rc = STATUS_UNSUCCESSFUL; + rc = STATUS_INVALID_PARAMETER; goto done; } @@ -287,7 +288,7 @@ OvsFlowNlCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx, goto done; } - if ((_MapNlToFlowPut(msgIn, nlAttrs[OVS_FLOW_ATTR_KEY], + if ((rc = _MapNlToFlowPut(msgIn, nlAttrs[OVS_FLOW_ATTR_KEY], nlAttrs[OVS_FLOW_ATTR_ACTIONS], nlAttrs[OVS_FLOW_ATTR_CLEAR], &mappedFlow)) != STATUS_SUCCESS) { @@ -326,7 +327,7 @@ OvsFlowNlCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx, if (!NlMsgPutTailUnspec(&nlBuf, OVS_FLOW_ATTR_STATS, (PCHAR)(&replyStats), sizeof(replyStats))) { OVS_LOG_ERROR("Adding OVS_FLOW_ATTR_STATS attribute failed."); - rc = STATUS_UNSUCCESSFUL; + rc = STATUS_INVALID_BUFFER_SIZE; goto done; } @@ -334,7 +335,17 @@ OvsFlowNlCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx, *replyLen = msgOut->nlMsg.nlmsgLen; done: - return rc; + nlError = NlErrMapStatus(rc); + + if ((nlError != NL_ERROR_SUCCESS) && + (usrParamsCtx->outputBuffer)) { + POVS_MESSAGE_ERROR msgError = (POVS_MESSAGE_ERROR) + usrParamsCtx->outputBuffer; + BuildErrorMsg(msgIn, msgError, nlError); + *replyLen = msgError->nlMsg.nlmsgLen; + } + + return STATUS_SUCCESS; } /* @@ -348,6 +359,9 @@ OvsFlowNlGetCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx, UINT32 *replyLen) { NTSTATUS rc = STATUS_SUCCESS; + NL_ERROR nlError = NL_ERROR_SUCCESS; + POVS_MESSAGE msgIn = (POVS_MESSAGE)usrParamsCtx->inputBuffer; + *replyLen = 0; if (usrParamsCtx->devOp == OVS_TRANSACTION_DEV_OP) { @@ -356,7 +370,17 @@ OvsFlowNlGetCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx, rc = _FlowNlDumpCmdHandler(usrParamsCtx, replyLen); } - return rc; + nlError = NlErrMapStatus(rc); + + if ((nlError != NL_ERROR_SUCCESS) && + (usrParamsCtx->outputBuffer)) { + POVS_MESSAGE_ERROR msgError = (POVS_MESSAGE_ERROR) + usrParamsCtx->outputBuffer; + BuildErrorMsg(msgIn, msgError, nlError); + *replyLen = msgError->nlMsg.nlmsgLen; + } + + return STATUS_SUCCESS; } /* @@ -410,7 +434,7 @@ _FlowNlGetCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx, != TRUE) { OVS_LOG_ERROR("Attr Parsing failed for msg: %p", nlMsgHdr); - rc = STATUS_UNSUCCESSFUL; + rc = STATUS_INVALID_PARAMETER; goto done; } @@ -424,7 +448,7 @@ _FlowNlGetCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx, != TRUE) { OVS_LOG_ERROR("Key Attr Parsing failed for msg: %p", nlMsgHdr); - rc = STATUS_UNSUCCESSFUL; + rc = STATUS_INVALID_PARAMETER; goto done; } @@ -441,7 +465,7 @@ _FlowNlGetCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx, != TRUE) { OVS_LOG_ERROR("Tunnel key Attr Parsing failed for msg: %p", nlMsgHdr); - rc = STATUS_UNSUCCESSFUL; + rc = STATUS_INVALID_PARAMETER; goto done; } } @@ -657,19 +681,19 @@ _MapFlowStatsToNlStats(PNL_BUFFER nlBuf, OvsFlowStats *flowStats) replyStats.n_bytes = flowStats->byteCount; if (!NlMsgPutTailU64(nlBuf, OVS_FLOW_ATTR_USED, flowStats->used)) { - rc = STATUS_UNSUCCESSFUL; + rc = STATUS_INVALID_BUFFER_SIZE; goto done; } if (!NlMsgPutTailUnspec(nlBuf, OVS_FLOW_ATTR_STATS, (PCHAR)(&replyStats), sizeof(struct ovs_flow_stats))) { - rc = STATUS_UNSUCCESSFUL; + rc = STATUS_INVALID_BUFFER_SIZE; goto done; } if (!NlMsgPutTailU8(nlBuf, OVS_FLOW_ATTR_TCP_FLAGS, flowStats->tcpFlags)) { - rc = STATUS_UNSUCCESSFUL; + rc = STATUS_INVALID_BUFFER_SIZE; goto done; } @@ -693,13 +717,13 @@ _MapFlowActionToNlAction(PNL_BUFFER nlBuf, uint32_t actionsLen, offset = NlMsgStartNested(nlBuf, OVS_FLOW_ATTR_ACTIONS); if (!offset) { /* Starting the nested attribute failed. */ - rc = STATUS_UNSUCCESSFUL; + rc = STATUS_INVALID_BUFFER_SIZE; goto error_nested_start; } if (!NlBufCopyAtTail(nlBuf, (PCHAR)actions, actionsLen)) { /* Adding a nested attribute failed. */ - rc = STATUS_UNSUCCESSFUL; + rc = STATUS_INVALID_BUFFER_SIZE; goto done; } @@ -1118,7 +1142,7 @@ _MapNlToFlowPut(POVS_MESSAGE msgIn, PNL_ATTR keyAttr, != TRUE) { OVS_LOG_ERROR("Key Attr Parsing failed for msg: %p", nlMsgHdr); - rc = STATUS_UNSUCCESSFUL; + rc = STATUS_INVALID_PARAMETER; goto done; } @@ -1137,7 +1161,7 @@ _MapNlToFlowPut(POVS_MESSAGE msgIn, PNL_ATTR keyAttr, != TRUE) { OVS_LOG_ERROR("Tunnel key Attr Parsing failed for msg: %p", nlMsgHdr); - rc = STATUS_UNSUCCESSFUL; + rc = STATUS_INVALID_PARAMETER; goto done; } } diff --git a/datapath-windows/ovsext/Netlink/NetlinkError.h b/datapath-windows/ovsext/Netlink/NetlinkError.h index 6947b7c..3289184 100644 --- a/datapath-windows/ovsext/Netlink/NetlinkError.h +++ b/datapath-windows/ovsext/Netlink/NetlinkError.h @@ -5,7 +5,7 @@ * 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 +* 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, @@ -197,4 +197,34 @@ typedef enum _NL_ERROR_ NL_ERROR_TXTBSY = ((ULONG)-139), /*the operation would block */ NL_ERROR_WOULDBLOCK = ((ULONG)-140), + /* parsing failed */ + NL_ERROR_PARSEFAIL = ((ULONG)-141) } NL_ERROR; + +static __inline NL_ERROR +NlErrMapStatus(NTSTATUS input) +{ + NL_ERROR ret = NL_ERROR_SUCCESS; + + switch (input) { + + case STATUS_SUCCESS: + ret = NL_ERROR_SUCCESS; + break; + case STATUS_INVALID_PARAMETER: + case STATUS_INFO_LENGTH_MISMATCH: + ret = NL_ERROR_INVAL; + break; + case STATUS_INVALID_BUFFER_SIZE: + ret = NL_ERROR_NOBUFS; + break; + /* We want to make sure that an error case + * is not treated as success. Hence default + * is NL_ERROR_PARSEFAIL rather then NL_ERROR_SUCCESS. */ + default: + ret = NL_ERROR_PARSEFAIL; + break; + } + + return ret; +} -- 1.9.1 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev