summaryrefslogtreecommitdiff
path: root/datapath-windows/ovsext/Datapath.c
diff options
context:
space:
mode:
authorEitan Eliahu <eliahue@vmware.com>2014-09-17 23:12:05 -0700
committerBen Pfaff <blp@nicira.com>2014-09-18 15:58:11 -0700
commit7f9381db10823b995e57e5c8da57ece8c8e8cf99 (patch)
treec25b65dc992119799e39a52dec07fdeec6072a27 /datapath-windows/ovsext/Datapath.c
parent93451a0a81b40c480115abd8739c1582e6b49a9c (diff)
downloadopenvswitch-7f9381db10823b995e57e5c8da57ece8c8e8cf99.tar.gz
datapath-windows: NetLink kernel side, Event subscription and notification
This code handles an event notification subscription for a user mode thread which joins an MC group. The event wait handler queues an IRP which is completed upon change in a port state. Signed-off-by: Eitan Eliahu <eliahue@vmware.com> Signed-off-by: Ben Pfaff <blp@nicira.com> Acked-by: Nithin Raju <nithin@vmware.com> Acked-by: Samuel Ghinet <sghinet@cloudbasesolutions.com>
Diffstat (limited to 'datapath-windows/ovsext/Datapath.c')
-rw-r--r--datapath-windows/ovsext/Datapath.c103
1 files changed, 93 insertions, 10 deletions
diff --git a/datapath-windows/ovsext/Datapath.c b/datapath-windows/ovsext/Datapath.c
index 2d1836c09..f033860b2 100644
--- a/datapath-windows/ovsext/Datapath.c
+++ b/datapath-windows/ovsext/Datapath.c
@@ -64,12 +64,12 @@
* Handler for a given netlink command. Not all the parameters are used by all
* the handlers.
*/
-typedef NTSTATUS (*NetlinkCmdHandler)(POVS_USER_PARAMS_CONTEXT usrParamsCtx,
- UINT32 *replyLen);
+typedef NTSTATUS(NetlinkCmdHandler)(POVS_USER_PARAMS_CONTEXT usrParamsCtx,
+ UINT32 *replyLen);
typedef struct _NETLINK_CMD {
UINT16 cmd;
- NetlinkCmdHandler handler;
+ NetlinkCmdHandler *handler;
UINT32 supportedDevOp; /* Supported device operations. */
BOOLEAN validateDpIndex; /* Does command require a valid DP argument. */
} NETLINK_CMD, *PNETLINK_CMD;
@@ -95,11 +95,10 @@ typedef struct _NETLINK_FAMILY {
#define OVS_TRANSACTION_DEV_OP (1 << 2)
/* Handlers for the various netlink commands. */
-static NTSTATUS OvsGetPidCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx,
- UINT32 *replyLen);
-
-static NTSTATUS OvsGetDpCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx,
- UINT32 *replyLen);
+static NetlinkCmdHandler OvsGetPidCmdHandler,
+ OvsGetDpCmdHandler,
+ OvsPendEventCmdHandler,
+ OvsSubscribeEventCmdHandler;
/*
* The various netlink families, along with the supported commands. Most of
@@ -113,7 +112,17 @@ NETLINK_CMD nlControlFamilyCmdOps[] = {
{ .cmd = OVS_CTRL_CMD_WIN_GET_PID,
.handler = OvsGetPidCmdHandler,
.supportedDevOp = OVS_TRANSACTION_DEV_OP,
- .validateDpIndex = FALSE
+ .validateDpIndex = FALSE,
+ },
+ { .cmd = OVS_CTRL_CMD_WIN_PEND_REQ,
+ .handler = OvsPendEventCmdHandler,
+ .supportedDevOp = OVS_WRITE_DEV_OP,
+ .validateDpIndex = TRUE,
+ },
+ { .cmd = OVS_CTRL_CMD_MC_SUBSCRIBE_REQ,
+ .handler = OvsSubscribeEventCmdHandler,
+ .supportedDevOp = OVS_WRITE_DEV_OP,
+ .validateDpIndex = TRUE,
}
};
@@ -776,7 +785,11 @@ InvokeNetlinkCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx,
for (i = 0; i < nlFamilyOps->opsCount; i++) {
if (nlFamilyOps->cmds[i].cmd == usrParamsCtx->ovsMsg->genlMsg.cmd) {
- status = nlFamilyOps->cmds[i].handler(usrParamsCtx, replyLen);
+ NetlinkCmdHandler *handler = nlFamilyOps->cmds[i].handler;
+ ASSERT(handler);
+ if (handler) {
+ status = handler(usrParamsCtx, replyLen);
+ }
break;
}
}
@@ -874,6 +887,76 @@ OvsDpFillInfo(POVS_SWITCH_CONTEXT ovsSwitchContext,
/*
* --------------------------------------------------------------------------
+ * Handler for queueing an IRP used for event notification. The IRP is
+ * completed when a port state changes. STATUS_PENDING is returned on
+ * success. User mode keep a pending IRP at all times.
+ * --------------------------------------------------------------------------
+ */
+static NTSTATUS
+OvsPendEventCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx,
+ UINT32 *replyLen)
+{
+ NDIS_STATUS status;
+
+ UNREFERENCED_PARAMETER(replyLen);
+
+ POVS_OPEN_INSTANCE instance =
+ (POVS_OPEN_INSTANCE)usrParamsCtx->ovsInstance;
+ POVS_MESSAGE msgIn = (POVS_MESSAGE)usrParamsCtx->inputBuffer;
+ OVS_EVENT_POLL poll;
+
+ poll.dpNo = msgIn->ovsHdr.dp_ifindex;
+ status = OvsWaitEventIoctl(usrParamsCtx->irp, instance->fileObject,
+ &poll, sizeof poll);
+ return status;
+}
+
+/*
+ * --------------------------------------------------------------------------
+ * Handler for the subscription for the event queue
+ * --------------------------------------------------------------------------
+ */
+static NTSTATUS
+OvsSubscribeEventCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx,
+ UINT32 *replyLen)
+{
+ NDIS_STATUS status;
+ OVS_EVENT_SUBSCRIBE request;
+ BOOLEAN rc;
+ UINT8 join;
+ PNL_ATTR attrs[2];
+ const NL_POLICY policy[] = {
+ [OVS_NL_ATTR_MCAST_GRP] = {.type = NL_A_U32 },
+ [OVS_NL_ATTR_MCAST_JOIN] = {.type = NL_A_U8 },
+ };
+
+ UNREFERENCED_PARAMETER(replyLen);
+
+ POVS_OPEN_INSTANCE instance =
+ (POVS_OPEN_INSTANCE)usrParamsCtx->ovsInstance;
+ POVS_MESSAGE msgIn = (POVS_MESSAGE)usrParamsCtx->inputBuffer;
+
+ rc = NlAttrParse(&msgIn->nlMsg, sizeof (*msgIn),policy, attrs, 2);
+ if (!rc) {
+ status = STATUS_INVALID_PARAMETER;
+ goto done;
+ }
+
+ /* XXX Ignore the MC group for now */
+ join = NlAttrGetU8(attrs[OVS_NL_ATTR_MCAST_JOIN]);
+ request.dpNo = msgIn->ovsHdr.dp_ifindex;
+ request.subscribe = join;
+ request.mask = OVS_EVENT_MASK_ALL;
+
+ status = OvsSubscribeEventIoctl(instance->fileObject, &request,
+ sizeof request);
+done:
+ return status;
+}
+
+
+/*
+ * --------------------------------------------------------------------------
* 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.
* --------------------------------------------------------------------------