diff options
author | Eitan Eliahu <eliahue@vmware.com> | 2014-09-17 23:12:05 -0700 |
---|---|---|
committer | Ben Pfaff <blp@nicira.com> | 2014-09-18 15:58:11 -0700 |
commit | 7f9381db10823b995e57e5c8da57ece8c8e8cf99 (patch) | |
tree | c25b65dc992119799e39a52dec07fdeec6072a27 /datapath-windows/ovsext/Datapath.c | |
parent | 93451a0a81b40c480115abd8739c1582e6b49a9c (diff) | |
download | openvswitch-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.c | 103 |
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. * -------------------------------------------------------------------------- |