In this patch we have implemented the handler for OVS_PACKET_CMD_EXECUTE command.
Signed-off-by: Ankur Sharma <ankursha...@vmware.com> --- datapath-windows/ovsext/User.c | 104 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 103 insertions(+), 1 deletion(-) diff --git a/datapath-windows/ovsext/User.c b/datapath-windows/ovsext/User.c index 184608a..5df41b1 100644 --- a/datapath-windows/ovsext/User.c +++ b/datapath-windows/ovsext/User.c @@ -46,6 +46,9 @@ extern PNDIS_SPIN_LOCK gOvsCtrlLock; extern POVS_SWITCH_CONTEXT gOvsSwitchContext; OVS_USER_STATS ovsUserStats; +static VOID _MapNlAttrToOvsPktExec(PNL_ATTR *nlAttrs, PNL_ATTR *keyAttrs, + OvsPacketExecute *execute); +extern NL_POLICY nlFlowKeyPolicy[]; NTSTATUS OvsUserInit() @@ -311,13 +314,112 @@ OvsNlExecuteCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx, UINT32 *replyLen) { NTSTATUS rc = STATUS_SUCCESS; + POVS_MESSAGE msgIn = (POVS_MESSAGE)usrParamsCtx->inputBuffer; + POVS_MESSAGE msgOut = (POVS_MESSAGE)usrParamsCtx->outputBuffer; + PNL_MSG_HDR nlMsgHdr = &(msgIn->nlMsg); + PGENL_MSG_HDR genlMsgHdr = &(msgIn->genlMsg); + POVS_HDR ovsHdr = &(msgIn->ovsHdr); + + PNL_ATTR nlAttrs[__OVS_PACKET_ATTR_MAX]; + PNL_ATTR keyAttrs[__OVS_KEY_ATTR_MAX] = {NULL}; + + UINT32 attrOffset = NLMSG_HDRLEN + GENL_HDRLEN + OVS_HDRLEN; + UINT32 keyAttrOffset = 0; + OvsPacketExecute execute; + NL_ERROR nlError = NL_ERROR_SUCCESS; + NL_BUFFER nlBuf; - UNREFERENCED_PARAMETER(usrParamsCtx); UNREFERENCED_PARAMETER(replyLen); + static const NL_POLICY nlPktExecPolicy[] = { + [OVS_PACKET_ATTR_PACKET] = {.type = NL_A_UNSPEC, .optional = FALSE}, + [OVS_PACKET_ATTR_KEY] = {.type = NL_A_UNSPEC, .optional = FALSE}, + [OVS_PACKET_ATTR_ACTIONS] = {.type = NL_A_UNSPEC, .optional = FALSE}, + [OVS_PACKET_ATTR_USERDATA] = {.type = NL_A_UNSPEC, .optional = TRUE}, + [OVS_PACKET_ATTR_EGRESS_TUN_KEY] = {.type = NL_A_UNSPEC, + .optional = TRUE} + }; + + RtlZeroMemory(&execute, sizeof(OvsPacketExecute)); + + /* Get all the top level Flow attributes */ + if ((NlAttrParse(nlMsgHdr, attrOffset, NlMsgAttrsLen(nlMsgHdr), + nlPktExecPolicy, 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_PACKET_ATTR_KEY] - + (PCHAR)nlMsgHdr); + + /* Get flow keys attributes */ + if ((NlAttrParseNested(nlMsgHdr, keyAttrOffset, + NlAttrLen(nlAttrs[OVS_PACKET_ATTR_KEY]), + nlFlowKeyPolicy, keyAttrs, + ARRAY_SIZE(keyAttrs))) != TRUE) { + OVS_LOG_ERROR("Key Attr Parsing failed for msg: %p", nlMsgHdr); + rc = STATUS_UNSUCCESSFUL; + goto done; + } + + execute.dpNo = ovsHdr->dp_ifindex; + + _MapNlAttrToOvsPktExec(nlAttrs, keyAttrs, &execute); + + rc = OvsExecuteDpIoctl(&execute); + + if (rc == STATUS_SUCCESS) { + NlBufInit(&nlBuf, usrParamsCtx->outputBuffer, + usrParamsCtx->outputLength); + + /* Prepare nl Msg headers */ + rc = NlFillOvsMsg(&nlBuf, nlMsgHdr->nlmsgType, 0, + nlMsgHdr->nlmsgSeq, nlMsgHdr->nlmsgPid, + genlMsgHdr->cmd, OVS_FLOW_VERSION, + ovsHdr->dp_ifindex); + + if (rc == STATUS_SUCCESS) { + *replyLen = msgOut->nlMsg.nlmsgLen; + } + } + + if ((nlError != NL_ERROR_SUCCESS) && + (usrParamsCtx->outputBuffer)) { + + POVS_MESSAGE_ERROR msgError = (POVS_MESSAGE_ERROR) + usrParamsCtx->outputBuffer; + BuildErrorMsg(msgIn, msgError, nlError); + *replyLen = msgError->nlMsg.nlmsgLen; + rc = STATUS_SUCCESS; + goto done; + } + +done: return rc; } +/* + *---------------------------------------------------------------------------- + * _MapNlAttrToOvsPktExec -- + * Maps input Netlink attributes to OvsPacketExecute. + *---------------------------------------------------------------------------- + */ +static VOID +_MapNlAttrToOvsPktExec(PNL_ATTR *nlAttrs, PNL_ATTR *keyAttrs, + OvsPacketExecute *execute) +{ + execute->packetBuf = NlAttrGet(nlAttrs[OVS_PACKET_ATTR_PACKET]); + execute->packetLen = NlAttrGetSize(nlAttrs[OVS_PACKET_ATTR_PACKET]); + + execute->actions = NlAttrGet(nlAttrs[OVS_PACKET_ATTR_ACTIONS]); + execute->actionsLen = NlAttrGetSize(nlAttrs[OVS_PACKET_ATTR_ACTIONS]); + + execute->inPort = NlAttrGetU32(keyAttrs[OVS_KEY_ATTR_IN_PORT]); +} + NTSTATUS OvsExecuteDpIoctl(PVOID inputBuffer) { -- 1.9.1 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev