In this patch we have implemented the flow get. Signed-off-by: Ankur Sharma <ankursha...@vmware.com> Acked-by: Nithin Raju <nit...@vmware.com> --- datapath-windows/ovsext/Flow.c | 203 +++++++++++++++++++++++++++++++++++----- datapath-windows/ovsext/Flow.h | 4 +- datapath-windows/ovsext/Ioctl.c | 5 + 3 files changed, 186 insertions(+), 26 deletions(-)
diff --git a/datapath-windows/ovsext/Flow.c b/datapath-windows/ovsext/Flow.c index e1f1c1a..ebcf005 100644 --- a/datapath-windows/ovsext/Flow.c +++ b/datapath-windows/ovsext/Flow.c @@ -53,7 +53,7 @@ static NTSTATUS _MapNlToFlowPut(POVS_MESSAGE msgIn, PNL_ATTR keyAttr, OvsFlowPut *mappedFlow); static VOID _MapKeyAttrToFlowPut(PNL_ATTR *keyAttrs, PNL_ATTR *tunnelAttrs, - OvsFlowPut *mappedFlow); + OvsFlowKey *destKey); static VOID _MapTunAttrToFlowPut(PNL_ATTR *keyAttrs, PNL_ATTR *tunnelAttrs, @@ -359,19 +359,143 @@ OvsFlowNlGetCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx, return rc; } +/* + *---------------------------------------------------------------------------- + * _FlowNlGetCmdHandler -- + * Handler for OVS_FLOW_CMD_GET command. + *---------------------------------------------------------------------------- + */ NTSTATUS _FlowNlGetCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx, UINT32 *replyLen) { NTSTATUS rc = STATUS_SUCCESS; + POVS_OPEN_INSTANCE instance = (POVS_OPEN_INSTANCE) + (usrParamsCtx->ovsInstance); + POVS_MESSAGE msgIn = instance->dumpState.ovsMsg; + PNL_MSG_HDR nlMsgHdr = &(msgIn->nlMsg); + POVS_HDR ovsHdr = &(msgIn->ovsHdr); + PNL_MSG_HDR nlMsgOutHdr = NULL; + UINT32 attrOffset = NLMSG_HDRLEN + GENL_HDRLEN + OVS_HDRLEN; + PNL_ATTR nlAttrs[__OVS_FLOW_ATTR_MAX]; + + OvsFlowGetInput getInput; + OvsFlowGetOutput getOutput; + NL_BUFFER nlBuf; + PNL_ATTR keyAttrs[__OVS_KEY_ATTR_MAX]; + PNL_ATTR tunnelAttrs[__OVS_TUNNEL_KEY_ATTR_MAX]; - UNREFERENCED_PARAMETER(usrParamsCtx); + NlBufInit(&nlBuf, usrParamsCtx->outputBuffer, + usrParamsCtx->outputLength); + RtlZeroMemory(&getInput, sizeof(OvsFlowGetInput)); + RtlZeroMemory(&getOutput, sizeof(OvsFlowGetOutput)); + UINT32 keyAttrOffset = 0; + UINT32 tunnelKeyAttrOffset = 0; *replyLen = 0; + if (usrParamsCtx->inputLength > usrParamsCtx->outputLength) { + /* Should not be the case. + * We'll be copying the flow keys back from + * input buffer to output buffer. */ + rc = STATUS_INVALID_PARAMETER; + OVS_LOG_ERROR("inputLength: %d GREATER THEN outputLength: %d", + usrParamsCtx->inputLength, usrParamsCtx->outputLength); + goto done; + } + + /* Get all the top level Flow attributes */ + if ((NlAttrParse(nlMsgHdr, attrOffset, NlMsgAttrsLen(nlMsgHdr), + nlFlowPolicy, nlAttrs, ARRAY_SIZE(nlAttrs))) + != TRUE) { + OVS_LOG_ERROR("Attr Parsing failed for msg: %p", + nlMsgHdr); + rc = STATUS_UNSUCCESSFUL; + goto done; + } + + keyAttrOffset = (UINT32)((PCHAR) nlAttrs[OVS_FLOW_ATTR_KEY] - + (PCHAR)nlMsgHdr); + + /* Get flow keys attributes */ + if ((NlAttrParseNested(nlMsgHdr, keyAttrOffset, + NlAttrLen(nlAttrs[OVS_FLOW_ATTR_KEY]), + nlFlowKeyPolicy, keyAttrs, ARRAY_SIZE(keyAttrs))) + != TRUE) { + OVS_LOG_ERROR("Key Attr Parsing failed for msg: %p", + nlMsgHdr); + rc = STATUS_UNSUCCESSFUL; + goto done; + } + + if (keyAttrs[OVS_KEY_ATTR_TUNNEL]) { + tunnelKeyAttrOffset = (UINT32)((PCHAR) + (keyAttrs[OVS_KEY_ATTR_TUNNEL]) + - (PCHAR)nlMsgHdr); + + /* Get tunnel keys attributes */ + if ((NlAttrParseNested(nlMsgHdr, tunnelKeyAttrOffset, + NlAttrLen(keyAttrs[OVS_KEY_ATTR_TUNNEL]), + nlFlowTunnelKeyPolicy, + tunnelAttrs, ARRAY_SIZE(tunnelAttrs))) + != TRUE) { + OVS_LOG_ERROR("Tunnel key Attr Parsing failed for msg: %p", + nlMsgHdr); + rc = STATUS_UNSUCCESSFUL; + goto done; + } + } + + _MapKeyAttrToFlowPut(keyAttrs, tunnelAttrs, + &(getInput.key)); + + getInput.dpNo = ovsHdr->dp_ifindex; + getInput.getFlags = FLOW_GET_STATS | FLOW_GET_ACTIONS; + + /* 4th argument is a no op. + * We are keeping this argument to be compatible + * with our dpif-windows based interface. */ + rc = OvsGetFlowIoctl(&getInput, &getOutput); + if (rc != STATUS_SUCCESS) { + OVS_LOG_ERROR("OvsGetFlowIoctl failed."); + goto done; + } + + /* Lets prepare the reply. */ + nlMsgOutHdr = (PNL_MSG_HDR)(NlBufAt(&nlBuf, 0, 0)); + + /* Input already has all the attributes for the flow key. + * Lets copy the values back. */ + RtlCopyMemory(usrParamsCtx->outputBuffer, usrParamsCtx->inputBuffer, + usrParamsCtx->inputLength); + + rc = _MapFlowStatsToNlStats(&nlBuf, &((getOutput.info).stats)); + if (rc != STATUS_SUCCESS) { + OVS_LOG_ERROR("_OvsFlowMapFlowKeyToNlStats failed."); + goto done; + } + + rc = _MapFlowActionToNlAction(&nlBuf, ((getOutput.info).actionsLen), + getOutput.info.actions); + if (rc != STATUS_SUCCESS) { + OVS_LOG_ERROR("_MapFlowActionToNlAction failed."); + goto done; + } + + NlMsgSetSize(nlMsgOutHdr, NlBufSize(&nlBuf)); + NlMsgAlignSize(nlMsgOutHdr); + *replyLen += NlMsgSize(nlMsgOutHdr); + +done: return rc; } +/* + *---------------------------------------------------------------------------- + * _FlowNlDumpCmdHandler -- + * Handler for OVS_FLOW_CMD_GET command. + *---------------------------------------------------------------------------- + */ NTSTATUS _FlowNlDumpCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx, UINT32 *replyLen) @@ -486,6 +610,12 @@ done: return rc; } +/* + *---------------------------------------------------------------------------- + * _MapFlowInfoToNl -- + * Maps OvsFlowInfo to Netlink attributes. + *---------------------------------------------------------------------------- + */ static NTSTATUS _MapFlowInfoToNl(PNL_BUFFER nlBuf, OvsFlowInfo *flowInfo) { @@ -511,6 +641,12 @@ done: return rc; } +/* + *---------------------------------------------------------------------------- + * _MapFlowStatsToNlStats -- + * Maps OvsFlowStats to OVS_FLOW_ATTR_STATS attribute. + *---------------------------------------------------------------------------- + */ static NTSTATUS _MapFlowStatsToNlStats(PNL_BUFFER nlBuf, OvsFlowStats *flowStats) { @@ -541,6 +677,12 @@ done: return rc; } +/* + *---------------------------------------------------------------------------- + * _MapFlowActionToNlAction -- + * Maps flow actions to OVS_FLOW_ATTR_ACTION attribute. + *---------------------------------------------------------------------------- + */ static NTSTATUS _MapFlowActionToNlAction(PNL_BUFFER nlBuf, uint32_t actionsLen, PNL_ATTR actions) @@ -568,6 +710,12 @@ error_nested_start: } +/* + *---------------------------------------------------------------------------- + * _MapFlowKeyToNlKey -- + * Maps OvsFlowKey to OVS_FLOW_ATTR_KEY attribute. + *---------------------------------------------------------------------------- + */ static NTSTATUS _MapFlowKeyToNlKey(PNL_BUFFER nlBuf, OvsFlowKey *flowKey) { @@ -657,6 +805,12 @@ error_nested_start: return rc; } +/* + *---------------------------------------------------------------------------- + * _MapFlowTunKeyToNlKey -- + * Maps OvsIPv4TunnelKey to OVS_TUNNEL_KEY_ATTR_ID attribute. + *---------------------------------------------------------------------------- + */ static NTSTATUS _MapFlowTunKeyToNlKey(PNL_BUFFER nlBuf, OvsIPv4TunnelKey *tunKey) { @@ -706,6 +860,12 @@ error_nested_start: return rc; } +/* + *---------------------------------------------------------------------------- + * _MapFlowTunKeyToNlKey -- + * Maps OvsIPv4FlowPutKey to OVS_KEY_ATTR_IPV4 attribute. + *---------------------------------------------------------------------------- + */ static NTSTATUS _MapFlowIpv4KeyToNlKey(PNL_BUFFER nlBuf, IpKey *ipv4FlowPutKey) { @@ -789,6 +949,12 @@ done: return rc; } +/* + *---------------------------------------------------------------------------- + * _MapFlowIpv6KeyToNlKey -- + * Maps _MapFlowIpv6KeyToNlKey to OVS_KEY_ATTR_IPV6 attribute. + *---------------------------------------------------------------------------- + */ static NTSTATUS _MapFlowIpv6KeyToNlKey(PNL_BUFFER nlBuf, Ipv6Key *ipv6FlowPutKey, Icmp6Key *icmpv6FlowPutKey) @@ -893,6 +1059,12 @@ done: return rc; } +/* + *---------------------------------------------------------------------------- + * _MapFlowArpKeyToNlKey -- + * Maps _MapFlowArpKeyToNlKey to OVS_KEY_ATTR_ARP attribute. + *---------------------------------------------------------------------------- + */ static NTSTATUS _MapFlowArpKeyToNlKey(PNL_BUFFER nlBuf, ArpKey *arpFlowPutKey) { @@ -959,7 +1131,8 @@ _MapNlToFlowPut(POVS_MESSAGE msgIn, PNL_ATTR keyAttr, /* Get tunnel keys attributes */ if ((NlAttrParseNested(nlMsgHdr, tunnelKeyAttrOffset, - NlAttrLen(keyAttr), nlFlowTunnelKeyPolicy, + NlAttrLen(keyAttrs[OVS_KEY_ATTR_TUNNEL]), + nlFlowTunnelKeyPolicy, tunnelAttrs, ARRAY_SIZE(tunnelAttrs))) != TRUE) { OVS_LOG_ERROR("Tunnel key Attr Parsing failed for msg: %p", @@ -970,7 +1143,7 @@ _MapNlToFlowPut(POVS_MESSAGE msgIn, PNL_ATTR keyAttr, } _MapKeyAttrToFlowPut(keyAttrs, tunnelAttrs, - mappedFlow); + &(mappedFlow->key)); /* Map the action */ if (actionAttr) { @@ -1029,10 +1202,9 @@ _MapNlToFlowPutFlags(PGENL_MSG_HDR genlMsgHdr, static VOID _MapKeyAttrToFlowPut(PNL_ATTR *keyAttrs, PNL_ATTR *tunnelAttrs, - OvsFlowPut *mappedFlow) + OvsFlowKey *destKey) { const struct ovs_key_ethernet *eth_key; - OvsFlowKey *destKey = &(mappedFlow->key); _MapTunAttrToFlowPut(keyAttrs, tunnelAttrs, destKey); @@ -2054,10 +2226,7 @@ OvsPrepareFlow(OvsFlow **flow, NTSTATUS OvsGetFlowIoctl(PVOID inputBuffer, - UINT32 inputLength, - PVOID outputBuffer, - UINT32 outputLength, - UINT32 *replyLen) + PVOID outputBuffer) { NTSTATUS status = STATUS_SUCCESS; OVS_DATAPATH *datapath = NULL; @@ -2069,21 +2238,11 @@ OvsGetFlowIoctl(PVOID inputBuffer, UINT32 dpNo; LOCK_STATE_EX dpLockState; - if (inputLength != sizeof(OvsFlowGetInput) - || inputBuffer == NULL) { - return STATUS_INFO_LENGTH_MISMATCH; - } - getInput = (OvsFlowGetInput *) inputBuffer; getFlags = getInput->getFlags; getActionsLen = getInput->actionsLen; - if (getInput->getFlags & FLOW_GET_KEY) { - return STATUS_INVALID_PARAMETER; - } - if (outputBuffer == NULL - || outputLength != (sizeof *getOutput + - getInput->actionsLen)) { + if (outputBuffer == NULL) { return STATUS_INFO_LENGTH_MISMATCH; } @@ -2104,8 +2263,6 @@ OvsGetFlowIoctl(PVOID inputBuffer, goto dp_unlock; } - // XXX: can be optimized to return only how much is written out - *replyLen = outputLength; getOutput = (OvsFlowGetOutput *)outputBuffer; ReportFlowInfo(flow, getFlags, &getOutput->info); diff --git a/datapath-windows/ovsext/Flow.h b/datapath-windows/ovsext/Flow.h index 7835b8c..2b5b93c 100644 --- a/datapath-windows/ovsext/Flow.h +++ b/datapath-windows/ovsext/Flow.h @@ -65,9 +65,7 @@ NTSTATUS OvsDumpFlowIoctl(PVOID inputBuffer, UINT32 inputLength, UINT32 *replyLen); NTSTATUS OvsPutFlowIoctl(PVOID inputBuffer, UINT32 inputLength, struct OvsFlowStats *stats); -NTSTATUS OvsGetFlowIoctl(PVOID inputBuffer, UINT32 inputLength, - PVOID outputBuffer, UINT32 outputLength, - UINT32 *replyLen); +NTSTATUS OvsGetFlowIoctl(PVOID inputBuffer, PVOID outputBuffer); NTSTATUS OvsFlushFlowIoctl(UINT32 dpNo); NTSTATUS OvsFlowNlCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx, diff --git a/datapath-windows/ovsext/Ioctl.c b/datapath-windows/ovsext/Ioctl.c index 9b93200..32abcda 100644 --- a/datapath-windows/ovsext/Ioctl.c +++ b/datapath-windows/ovsext/Ioctl.c @@ -654,9 +654,14 @@ OvsDeviceControl(PDEVICE_OBJECT deviceObject, outputBuffer = MmGetSystemAddressForMdlSafe(irp->MdlAddress, NormalPagePriority); if (outputBuffer) { + /* Commenting out the call. + * Post netlink implementation, + * we'll get rid of this file itself. */ +#if 0 status = OvsGetFlowIoctl(inputBuffer, inputBufferLen, outputBuffer, outputBufferLen, &replyLen); +#endif } else { status = STATUS_INSUFFICIENT_RESOURCES; } -- 1.9.1 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev