summaryrefslogtreecommitdiff
path: root/datapath-windows/ovsext/User.c
diff options
context:
space:
mode:
authorAnkur Sharma <ankursharma@vmware.com>2014-10-15 15:54:53 -0700
committerBen Pfaff <blp@nicira.com>2014-10-15 17:00:26 -0700
commitefa753a8ee4d14c426df4367edbe801fe2ec6859 (patch)
tree4c76037f680b69a629419213cf288078648262c6 /datapath-windows/ovsext/User.c
parenta74933bc9f3935c50900fcb16c6f61bf6056ca5f (diff)
downloadopenvswitch-efa753a8ee4d14c426df4367edbe801fe2ec6859.tar.gz
datapath-windows: OVS_PACKET_CMD_EXECUTE handler.
In this patch we have implemented the handler for OVS_PACKET_CMD_EXECUTE command. Signed-off-by: Ankur Sharma <ankursharma@vmware.com> Acked-by: Eitan Eliahu <eliahue@vmware.com> Acked-by: Nithin Raju <nithin@vmware.com> Signed-off-by: Ben Pfaff <blp@nicira.com>
Diffstat (limited to 'datapath-windows/ovsext/User.c')
-rw-r--r--datapath-windows/ovsext/User.c111
1 files changed, 107 insertions, 4 deletions
diff --git a/datapath-windows/ovsext/User.c b/datapath-windows/ovsext/User.c
index 31c579cc9..8400b83bc 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()
@@ -310,12 +313,112 @@ NTSTATUS
OvsNlExecuteCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx,
UINT32 *replyLen)
{
- NTSTATUS rc = STATUS_SUCCESS;
+ NTSTATUS status = 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;
+
+ 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);
+ status = 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);
+ status = STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ execute.dpNo = ovsHdr->dp_ifindex;
+
+ _MapNlAttrToOvsPktExec(nlAttrs, keyAttrs, &execute);
+
+ status = OvsExecuteDpIoctl(&execute);
+
+ if (status == STATUS_SUCCESS) {
+ NlBufInit(&nlBuf, usrParamsCtx->outputBuffer,
+ usrParamsCtx->outputLength);
+
+ /* Prepare nl Msg headers */
+ status = NlFillOvsMsg(&nlBuf, nlMsgHdr->nlmsgType, 0,
+ nlMsgHdr->nlmsgSeq, nlMsgHdr->nlmsgPid,
+ genlMsgHdr->cmd, OVS_PACKET_VERSION,
+ ovsHdr->dp_ifindex);
+
+ if (status == STATUS_SUCCESS) {
+ *replyLen = msgOut->nlMsg.nlmsgLen;
+ }
+ }
+
+ /* As of now there are no transactional errors in the implementation.
+ * Once we have them then we need to map status to correct
+ * nlError value, so that below mentioned code gets hit. */
+ if ((nlError != NL_ERROR_SUCCESS) &&
+ (usrParamsCtx->outputBuffer)) {
+
+ POVS_MESSAGE_ERROR msgError = (POVS_MESSAGE_ERROR)
+ usrParamsCtx->outputBuffer;
+ BuildErrorMsg(msgIn, msgError, nlError);
+ *replyLen = msgError->nlMsg.nlmsgLen;
+ status = STATUS_SUCCESS;
+ goto done;
+ }
+
+done:
+ return status;
+}
+
+/*
+ *----------------------------------------------------------------------------
+ * _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]);
- UNREFERENCED_PARAMETER(usrParamsCtx);
- UNREFERENCED_PARAMETER(replyLen);
+ execute->actions = NlAttrGet(nlAttrs[OVS_PACKET_ATTR_ACTIONS]);
+ execute->actionsLen = NlAttrGetSize(nlAttrs[OVS_PACKET_ATTR_ACTIONS]);
- return rc;
+ execute->inPort = NlAttrGetU32(keyAttrs[OVS_KEY_ATTR_IN_PORT]);
}
NTSTATUS