2
0
mirror of https://github.com/openvswitch/ovs synced 2025-10-27 15:18:06 +00:00

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>
This commit is contained in:
Eitan Eliahu
2014-09-17 23:12:05 -07:00
committed by Ben Pfaff
parent 93451a0a81
commit 7f9381db10

View File

@@ -64,12 +64,12 @@
* Handler for a given netlink command. Not all the parameters are used by all * Handler for a given netlink command. Not all the parameters are used by all
* the handlers. * the handlers.
*/ */
typedef NTSTATUS (*NetlinkCmdHandler)(POVS_USER_PARAMS_CONTEXT usrParamsCtx, typedef NTSTATUS(NetlinkCmdHandler)(POVS_USER_PARAMS_CONTEXT usrParamsCtx,
UINT32 *replyLen); UINT32 *replyLen);
typedef struct _NETLINK_CMD { typedef struct _NETLINK_CMD {
UINT16 cmd; UINT16 cmd;
NetlinkCmdHandler handler; NetlinkCmdHandler *handler;
UINT32 supportedDevOp; /* Supported device operations. */ UINT32 supportedDevOp; /* Supported device operations. */
BOOLEAN validateDpIndex; /* Does command require a valid DP argument. */ BOOLEAN validateDpIndex; /* Does command require a valid DP argument. */
} NETLINK_CMD, *PNETLINK_CMD; } NETLINK_CMD, *PNETLINK_CMD;
@@ -95,11 +95,10 @@ typedef struct _NETLINK_FAMILY {
#define OVS_TRANSACTION_DEV_OP (1 << 2) #define OVS_TRANSACTION_DEV_OP (1 << 2)
/* Handlers for the various netlink commands. */ /* Handlers for the various netlink commands. */
static NTSTATUS OvsGetPidCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx, static NetlinkCmdHandler OvsGetPidCmdHandler,
UINT32 *replyLen); OvsGetDpCmdHandler,
OvsPendEventCmdHandler,
static NTSTATUS OvsGetDpCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx, OvsSubscribeEventCmdHandler;
UINT32 *replyLen);
/* /*
* The various netlink families, along with the supported commands. Most of * 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, { .cmd = OVS_CTRL_CMD_WIN_GET_PID,
.handler = OvsGetPidCmdHandler, .handler = OvsGetPidCmdHandler,
.supportedDevOp = OVS_TRANSACTION_DEV_OP, .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++) { for (i = 0; i < nlFamilyOps->opsCount; i++) {
if (nlFamilyOps->cmds[i].cmd == usrParamsCtx->ovsMsg->genlMsg.cmd) { 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; break;
} }
} }
@@ -872,6 +885,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 * Handler for the get dp command. The function handles the initial call to