[ovs-dev] [PATCH 2/3] datapath-windows: Add Netlink vport command get
Samuel Ghinet
sghinet at cloudbasesolutions.com
Wed Sep 24 15:42:20 UTC 2014
The transactional get vport command.
This command uses the netlink transactional errors.
Signed-off-by: Samuel Ghinet <sghinet at cloudbasesolutions.com>
---
datapath-windows/ovsext/Datapath.c | 83 ++++++++++++++++++++++++++++++++++++++
1 file changed, 83 insertions(+)
diff --git a/datapath-windows/ovsext/Datapath.c b/datapath-windows/ovsext/Datapath.c
index 05c06b6..8a8c542 100644
--- a/datapath-windows/ovsext/Datapath.c
+++ b/datapath-windows/ovsext/Datapath.c
@@ -1425,6 +1425,86 @@ OvsGetVportDumpNext(POVS_USER_PARAMS_CONTEXT usrParamsCtx,
return STATUS_SUCCESS;
}
+static NTSTATUS
+OvsGetVport(POVS_USER_PARAMS_CONTEXT usrParamsCtx,
+ UINT32 *replyLen)
+{
+ NDIS_STATUS status = STATUS_SUCCESS;
+ LOCK_STATE_EX lockState;
+
+ POVS_MESSAGE msgIn = (POVS_MESSAGE)usrParamsCtx->inputBuffer;
+ POVS_MESSAGE msgOut = (POVS_MESSAGE)usrParamsCtx->outputBuffer;
+ POVS_VPORT_ENTRY vport = NULL;
+ NL_ERROR nlError = NL_ERROR_SUCCESS;
+
+ static const NL_POLICY ovsVportPolicy[] = {
+ [OVS_VPORT_ATTR_PORT_NO] = { .type = NL_A_U32 },
+ [OVS_VPORT_ATTR_TYPE] = { .type = NL_A_U32 },
+ [OVS_VPORT_ATTR_NAME] = { .type = NL_A_STRING, .maxLen = IFNAMSIZ },
+ [OVS_VPORT_ATTR_UPCALL_PID] = { .type = NL_A_UNSPEC },
+ [OVS_VPORT_ATTR_STATS] = { .type = NL_A_UNSPEC,
+ .minLen = sizeof(OVS_VPORT_FULL_STATS),
+ .maxLen = sizeof(OVS_VPORT_FULL_STATS)
+ },
+ [OVS_VPORT_ATTR_OPTIONS] = { .type = NL_A_NESTED, .optional = TRUE },
+ };
+ PNL_ATTR vportAttrs[ARRAY_SIZE(ovsVportPolicy)];
+
+ /* input buffer has been validated while validating write dev op. */
+ ASSERT(usrParamsCtx->inputBuffer != NULL);
+
+ if (!NlAttrParse((PNL_MSG_HDR)msgIn,
+ NLMSG_HDRLEN + GENL_HDRLEN + OVS_HDRLEN,
+ ovsVportPolicy, vportAttrs, ARRAY_SIZE(vportAttrs))) {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ if (msgOut == NULL || usrParamsCtx->outputLength < sizeof *msgOut) {
+ return STATUS_NDIS_INVALID_LENGTH;
+ }
+
+ OvsAcquireCtrlLock();
+ if (!gOvsSwitchContext) {
+ OvsReleaseCtrlLock();
+ *replyLen = 0;
+ return STATUS_DATA_NOT_ACCEPTED;
+ }
+ OvsReleaseCtrlLock();
+
+ if (vportAttrs[OVS_VPORT_ATTR_NAME] != NULL) {
+ vport = OvsFindVportByOvsName(gOvsSwitchContext,
+ NlAttrGet(vportAttrs[OVS_VPORT_ATTR_NAME]),
+ NlAttrGetSize(vportAttrs[OVS_VPORT_ATTR_NAME]));
+ } else if (vportAttrs[OVS_VPORT_ATTR_PORT_NO] != NULL) {
+ vport = OvsFindVportByPortNo(gOvsSwitchContext,
+ NlAttrGetU32(vportAttrs[OVS_VPORT_ATTR_PORT_NO]));
+ }
+
+ if (!vport) {
+ nlError = NL_ERROR_NODEV;
+ goto Cleanup;
+ }
+
+ NdisAcquireRWLockRead(gOvsSwitchContext->dispatchLock, &lockState, 0);
+ status = OvsCreateMsgFromVport(vport, msgIn, usrParamsCtx->outputBuffer,
+ usrParamsCtx->outputLength,
+ gOvsSwitchContext->dpNo);
+ NdisReleaseRWLock(gOvsSwitchContext->dispatchLock, &lockState);
+
+ *replyLen = msgOut->nlMsg.nlmsgLen;
+
+Cleanup:
+ if (nlError != NL_ERROR_NODEV) {
+ POVS_MESSAGE_ERROR msgError = (POVS_MESSAGE_ERROR)
+ usrParamsCtx->outputBuffer;
+
+ BuildErrorMsg(msgIn, msgError, nlError);
+ *replyLen = msgError->nlMsg.nlmsgLen;
+ }
+
+ return STATUS_SUCCESS;
+}
+
/*
* --------------------------------------------------------------------------
* Handler for the get vport command. The function handles the initial call to
@@ -1444,6 +1524,9 @@ OvsGetVportCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx,
case OVS_READ_DEV_OP:
return OvsGetVportDumpNext(usrParamsCtx, replyLen);
+ case OVS_TRANSACTION_DEV_OP:
+ return OvsGetVport(usrParamsCtx, replyLen);
+
default:
return STATUS_INVALID_DEVICE_REQUEST;
}
--
1.8.3.msysgit.0
More information about the dev
mailing list