[ovs-dev] [PATCH 5/5 v1] datapath-windows: add OVS_DP_CMD_SET and OVS_DP_CMD_GET transaction support
Nithin Raju
nithin at vmware.com
Wed Sep 17 02:06:11 UTC 2014
In this patch, we add support for two commands, both of them are issued
as part of transactions semantics from userspace:
1. OVS_DP_CMD_SET is used to get the properties of a DP as well as set
some properties. The set operations does not seem to make much sense for
the Windows datpath right now.
2. There's already support for OVS_DP_CMD_GET command issued via the
dump semantics from userspace. Turns out that userspace can issue
OVS_DP_CMD_GET as a transaction.
There's lot of common code between these two commands. Hence combining
the implementation and the review.
Also refactories some of the code in the implementation of dump-based
OVS_DP_CMD_GET, and updated some of the comments.
Validation:
- With these series of patches, I was able to run the following command:
> .\utilities\ovs-dpctl.exe show
system at ovs-system:
lookups: hit:0 missed:22 lost:0
flows: 0
- I got so far as to hit the PORT_DUMP command which is currently not
implemented.
Signed-off-by: Nithin Raju <nithin at vmware.com>
Tested-by: Nithin Raju <nithin at vmware.com>
Reported-at: https://github.com/openvswitch/ovs-issues/issues/38
---
datapath-windows/ovsext/Datapath.c | 151 ++++++++++++++++++++++++++++++++++--
1 files changed, 143 insertions(+), 8 deletions(-)
diff --git a/datapath-windows/ovsext/Datapath.c b/datapath-windows/ovsext/Datapath.c
index 2d1836c..25a1ea0 100644
--- a/datapath-windows/ovsext/Datapath.c
+++ b/datapath-windows/ovsext/Datapath.c
@@ -101,6 +101,16 @@ static NTSTATUS OvsGetPidCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx,
static NTSTATUS OvsGetDpCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx,
UINT32 *replyLen);
+static NTSTATUS OvsSetDpCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx,
+ UINT32 *replyLen);
+
+static NTSTATUS HandleGetDpTransaction(POVS_USER_PARAMS_CONTEXT usrParamsCtx,
+ UINT32 *replyLen);
+static NTSTATUS HandleGetDpDump(POVS_USER_PARAMS_CONTEXT usrParamsCtx,
+ UINT32 *replyLen);
+static NTSTATUS HandleDpTransaction(POVS_USER_PARAMS_CONTEXT usrParamsCtx,
+ UINT32 *replyLen);
+
/*
* The various netlink families, along with the supported commands. Most of
* these families and commands are part of the openvswitch specification for a
@@ -130,8 +140,15 @@ NETLINK_FAMILY nlControlFamilyOps = {
NETLINK_CMD nlDatapathFamilyCmdOps[] = {
{ .cmd = OVS_DP_CMD_GET,
.handler = OvsGetDpCmdHandler,
- .supportedDevOp = OVS_WRITE_DEV_OP | OVS_READ_DEV_OP,
+ .supportedDevOp = OVS_WRITE_DEV_OP | OVS_READ_DEV_OP |
+ OVS_TRANSACTION_DEV_OP,
.validateDpIndex = FALSE
+ },
+ { .cmd = OVS_DP_CMD_SET,
+ .handler = OvsSetDpCmdHandler,
+ .supportedDevOp = OVS_WRITE_DEV_OP | OVS_READ_DEV_OP |
+ OVS_TRANSACTION_DEV_OP,
+ .validateDpIndex = TRUE
}
};
@@ -705,8 +722,6 @@ done:
* --------------------------------------------------------------------------
* Function to validate a netlink command. Only certain combinations of
* (device operation, netlink family, command) are valid.
- *
- * XXX: Take policy into consideration.
* --------------------------------------------------------------------------
*/
static NTSTATUS
@@ -784,9 +799,10 @@ InvokeNetlinkCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx,
return status;
}
-
/*
* --------------------------------------------------------------------------
+ * Command Handler for 'OVS_CTRL_CMD_WIN_GET_PID'.
+ *
* Each handle on the device is assigned a unique PID when the handle is
* created. On platforms that support netlink natively, the PID is available
* to userspace when the netlink socket is created. However, without native
@@ -837,7 +853,7 @@ OvsDpFillInfo(POVS_SWITCH_CONTEXT ovsSwitchContext,
PNL_MSG_HDR nlMsg;
/* XXX: Add API for nlBuf->bufRemLen. */
- ASSERT(NlBufAt(nlBuf, 0, 0) != 0 && nlBuf->bufRemLen >= sizeof msgOutTmp);
+ ASSERT(NlBufAt(nlBuf, 0, 0) != 0 && nlBuf->bufRemLen >= sizeof *msgIn);
msgOutTmp.nlMsg.nlmsgType = OVS_WIN_NL_DATAPATH_FAMILY_ID;
msgOutTmp.nlMsg.nlmsgFlags = 0; /* XXX: ? */
@@ -871,17 +887,49 @@ OvsDpFillInfo(POVS_SWITCH_CONTEXT ovsSwitchContext,
return writeOk ? STATUS_SUCCESS : STATUS_INVALID_BUFFER_SIZE;
}
-
/*
* --------------------------------------------------------------------------
- * Handler for the get dp command. The function handles the initial call to
- * setup the dump state, as well as subsequent calls to continue dumping data.
+ * Command Handler for 'OVS_DP_CMD_GET'.
+ *
+ * The function handles both the dump based as well as the transaction based
+ * 'OVS_DP_CMD_GET' command. In the dump command, it handles the initial
+ * call to setup dump state, as well as subsequent calls to continue dumping
+ * data.
* --------------------------------------------------------------------------
*/
static NTSTATUS
OvsGetDpCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx,
UINT32 *replyLen)
{
+ if (usrParamsCtx->devOp == OVS_TRANSACTION_DEV_OP) {
+ return HandleGetDpTransaction(usrParamsCtx, replyLen);
+ } else {
+ return HandleGetDpDump(usrParamsCtx, replyLen);
+ }
+}
+
+/*
+ * --------------------------------------------------------------------------
+ * Function for handling the transaction based 'OVS_DP_CMD_GET' command.
+ * --------------------------------------------------------------------------
+ */
+static NTSTATUS
+HandleGetDpTransaction(POVS_USER_PARAMS_CONTEXT usrParamsCtx,
+ UINT32 *replyLen)
+{
+ return HandleDpTransaction(usrParamsCtx, replyLen);
+}
+
+
+/*
+ * --------------------------------------------------------------------------
+ * Function for handling the dump-based 'OVS_DP_CMD_GET' command.
+ * --------------------------------------------------------------------------
+ */
+static NTSTATUS
+HandleGetDpDump(POVS_USER_PARAMS_CONTEXT usrParamsCtx,
+ UINT32 *replyLen)
+{
POVS_MESSAGE msgOut = (POVS_MESSAGE)usrParamsCtx->outputBuffer;
POVS_OPEN_INSTANCE instance =
(POVS_OPEN_INSTANCE)usrParamsCtx->ovsInstance;
@@ -937,6 +985,93 @@ OvsGetDpCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx,
return STATUS_SUCCESS;
}
+
+/*
+ * --------------------------------------------------------------------------
+ * Command Handler for 'OVS_DP_CMD_SET'.
+ * --------------------------------------------------------------------------
+ */
+static NTSTATUS
+OvsSetDpCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx,
+ UINT32 *replyLen)
+{
+ return HandleDpTransaction(usrParamsCtx, replyLen);
+}
+
+/*
+ * --------------------------------------------------------------------------
+ * Function for handling transaction based 'OVS_DP_CMD_GET' and
+ * 'OVS_DP_CMD_SET' commands.
+ * --------------------------------------------------------------------------
+ */
+static NTSTATUS
+HandleDpTransaction(POVS_USER_PARAMS_CONTEXT usrParamsCtx,
+ UINT32 *replyLen)
+{
+ POVS_MESSAGE msgIn = (POVS_MESSAGE)usrParamsCtx->inputBuffer;
+ POVS_MESSAGE msgOut = (POVS_MESSAGE)usrParamsCtx->outputBuffer;
+ NTSTATUS status = STATUS_SUCCESS;
+ NL_BUFFER nlBuf;
+ static const NL_POLICY ovsDatapathSetPolicy[] = {
+ [OVS_DP_ATTR_NAME] = { .type = NL_A_STRING, .maxLen = IFNAMSIZ },
+ [OVS_DP_ATTR_UPCALL_PID] = { .type = NL_A_U32 },
+ [OVS_DP_ATTR_USER_FEATURES] = { .type = NL_A_U32 },
+ };
+ PNL_ATTR dpAttrs[ARRAY_SIZE(ovsDatapathSetPolicy)];
+
+ /* input buffer has been validated while validating write dev op. */
+ ASSERT(msgIn != NULL && usrParamsCtx->inputLength >= sizeof *msgIn);
+
+ /* Parse any attributes in the request. */
+ if (usrParamsCtx->ovsMsg->genlMsg.cmd == OVS_DP_CMD_SET) {
+ if (!NlAttrParse((PNL_MSG_HDR)msgIn,
+ NLMSG_HDRLEN + GENL_HDRLEN + OVS_HDRLEN,
+ ovsDatapathSetPolicy, dpAttrs, ARRAY_SIZE(dpAttrs))) {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ /*
+ * XXX: Not clear at this stage if there's any role for the
+ * OVS_DP_ATTR_UPCALL_PID and OVS_DP_ATTR_USER_FEATURES attributes passed
+ * from userspace.
+ */
+
+ } else {
+ RtlZeroMemory(dpAttrs, sizeof dpAttrs);
+ }
+
+ /* Output buffer is optional for OVS_TRANSACTION_DEV_OP. */
+ if (msgOut == NULL || usrParamsCtx->outputLength < sizeof *msgOut) {
+ return STATUS_NDIS_INVALID_LENGTH;
+ }
+ NlBufInit(&nlBuf, usrParamsCtx->outputBuffer, usrParamsCtx->outputLength);
+
+ OvsAcquireCtrlLock();
+ if (dpAttrs[OVS_DP_ATTR_NAME] != NULL) {
+ if (!gOvsSwitchContext &&
+ !OvsCompareString(NlAttrGet(dpAttrs[OVS_DP_ATTR_NAME]),
+ NlAttrGetSize(dpAttrs[OVS_DP_ATTR_NAME]),
+ OVS_SYSTEM_DP_NAME, sizeof OVS_SYSTEM_DP_NAME)) {
+ OvsReleaseCtrlLock();
+ status = STATUS_NOT_FOUND;
+ goto cleanup;
+ }
+ } else if ((UINT32)msgIn->ovsHdr.dp_ifindex != gOvsSwitchContext->dpNo) {
+ OvsReleaseCtrlLock();
+ status = STATUS_NOT_FOUND;
+ goto cleanup;
+ }
+
+ status = OvsDpFillInfo(gOvsSwitchContext, msgIn, &nlBuf);
+ OvsReleaseCtrlLock();
+
+ *replyLen = NlBufSize(&nlBuf);
+
+cleanup:
+ return status;
+}
+
+
static NTSTATUS
OvsSetupDumpStart(POVS_USER_PARAMS_CONTEXT usrParamsCtx)
{
--
1.7.4.1
More information about the dev
mailing list