From 190cf5338956c53596f60b20fa7672ba052ee815 Mon Sep 17 00:00:00 2001 From: Sorin Vinturis Date: Thu, 2 Apr 2015 19:35:32 +0000 Subject: datapath-windows: Make GET_PID a separate IOCTL Added a new IOCTL in order to retrieve the PID from the kernel datapath. The new method uses a direct and cleaner way, as opposed to the old way of using a Netlink transaction, avoiding the unnecessary overhead. Signed-off-by: Sorin Vinturis Reported-by: Alin Gabriel Serdean Reported-at: https://github.com/openvswitch/ovs-issues/issues/31 Acked-by: Nithin Raju Acked-by: Alin Gabriel Serdean Tested-by: Alin Gabriel Serdean Signed-off-by: Ben Pfaff --- datapath-windows/include/OvsDpInterfaceExt.h | 18 ++++---- datapath-windows/ovsext/Datapath.c | 63 +++++++++++++++------------- datapath-windows/ovsext/Flow.c | 2 +- 3 files changed, 47 insertions(+), 36 deletions(-) (limited to 'datapath-windows') diff --git a/datapath-windows/include/OvsDpInterfaceExt.h b/datapath-windows/include/OvsDpInterfaceExt.h index 7e09caf77..e2353767d 100644 --- a/datapath-windows/include/OvsDpInterfaceExt.h +++ b/datapath-windows/include/OvsDpInterfaceExt.h @@ -29,22 +29,27 @@ #define OVS_IOCTL_DEVICE_TYPE 45000 -/* We used Direct I/O (zero copy) for the buffers. */ #define OVS_IOCTL_START 0x100 +/* We used Direct I/O (zero copy) for the buffers. */ +/* Non-Netlink-based IOCTLs. */ +#define OVS_IOCTL_GET_PID \ + CTL_CODE (OVS_IOCTL_DEVICE_TYPE, OVS_IOCTL_START + 0x0, METHOD_BUFFERED,\ + FILE_WRITE_ACCESS) +/* Netlink-based IOCTLs. */ #define OVS_IOCTL_READ \ - CTL_CODE (OVS_IOCTL_DEVICE_TYPE, OVS_IOCTL_START + 0x0, METHOD_OUT_DIRECT,\ + CTL_CODE (OVS_IOCTL_DEVICE_TYPE, OVS_IOCTL_START + 0x1, METHOD_OUT_DIRECT,\ FILE_READ_ACCESS) #define OVS_IOCTL_READ_EVENT \ - CTL_CODE (OVS_IOCTL_DEVICE_TYPE, OVS_IOCTL_START + 0x1, METHOD_OUT_DIRECT, \ + CTL_CODE (OVS_IOCTL_DEVICE_TYPE, OVS_IOCTL_START + 0x2, METHOD_OUT_DIRECT, \ FILE_READ_ACCESS) #define OVS_IOCTL_READ_PACKET \ - CTL_CODE (OVS_IOCTL_DEVICE_TYPE, OVS_IOCTL_START + 0x2, METHOD_OUT_DIRECT, \ + CTL_CODE (OVS_IOCTL_DEVICE_TYPE, OVS_IOCTL_START + 0x3, METHOD_OUT_DIRECT, \ FILE_READ_ACCESS) #define OVS_IOCTL_WRITE \ - CTL_CODE (OVS_IOCTL_DEVICE_TYPE, OVS_IOCTL_START + 0x3, METHOD_IN_DIRECT,\ + CTL_CODE (OVS_IOCTL_DEVICE_TYPE, OVS_IOCTL_START + 0x4, METHOD_IN_DIRECT,\ FILE_READ_ACCESS) #define OVS_IOCTL_TRANSACT \ - CTL_CODE (OVS_IOCTL_DEVICE_TYPE, OVS_IOCTL_START + 0x4, METHOD_OUT_DIRECT,\ + CTL_CODE (OVS_IOCTL_DEVICE_TYPE, OVS_IOCTL_START + 0x5, METHOD_OUT_DIRECT,\ FILE_WRITE_ACCESS) /* @@ -75,7 +80,6 @@ /* Commands available under the OVS_WIN_CONTROL_FAMILY. */ enum ovs_win_control_cmd { - OVS_CTRL_CMD_WIN_GET_PID, OVS_CTRL_CMD_WIN_PEND_REQ, OVS_CTRL_CMD_WIN_PEND_PACKET_REQ, OVS_CTRL_CMD_MC_SUBSCRIBE_REQ, diff --git a/datapath-windows/ovsext/Datapath.c b/datapath-windows/ovsext/Datapath.c index 888c6ef79..e566ea9d0 100644 --- a/datapath-windows/ovsext/Datapath.c +++ b/datapath-windows/ovsext/Datapath.c @@ -87,8 +87,7 @@ typedef struct _NETLINK_FAMILY { } NETLINK_FAMILY, *PNETLINK_FAMILY; /* Handlers for the various netlink commands. */ -static NetlinkCmdHandler OvsGetPidCmdHandler, - OvsPendEventCmdHandler, +static NetlinkCmdHandler OvsPendEventCmdHandler, OvsPendPacketCmdHandler, OvsSubscribeEventCmdHandler, OvsSubscribePacketCmdHandler, @@ -110,6 +109,8 @@ static NTSTATUS HandleGetDpDump(POVS_USER_PARAMS_CONTEXT usrParamsCtx, UINT32 *replyLen); static NTSTATUS HandleDpTransactionCommon( POVS_USER_PARAMS_CONTEXT usrParamsCtx, UINT32 *replyLen); +static NTSTATUS OvsGetPidHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx, + UINT32 *replyLen); /* * The various netlink families, along with the supported commands. Most of @@ -120,11 +121,6 @@ static NTSTATUS HandleDpTransactionCommon( /* Netlink control family: this is a Windows specific family. */ NETLINK_CMD nlControlFamilyCmdOps[] = { - { .cmd = OVS_CTRL_CMD_WIN_GET_PID, - .handler = OvsGetPidCmdHandler, - .supportedDevOp = OVS_TRANSACTION_DEV_OP, - .validateDpIndex = FALSE, - }, { .cmd = OVS_CTRL_CMD_WIN_PEND_REQ, .handler = OvsPendEventCmdHandler, .supportedDevOp = OVS_WRITE_DEV_OP, @@ -736,6 +732,24 @@ OvsDeviceControl(PDEVICE_OBJECT deviceObject, * operation. */ switch (code) { + case OVS_IOCTL_GET_PID: + /* Both input buffer and output buffer use the same location. */ + outputBuffer = irp->AssociatedIrp.SystemBuffer; + if (outputBufferLen != 0) { + InitUserParamsCtx(irp, instance, 0, NULL, + inputBuffer, inputBufferLen, + outputBuffer, outputBufferLen, + &usrParamsCtx); + + ASSERT(outputBuffer); + } else { + status = STATUS_NDIS_INVALID_LENGTH; + goto done; + } + + status = OvsGetPidHandler(&usrParamsCtx, &replyLen); + goto done; + case OVS_IOCTL_TRANSACT: /* Both input buffer and output buffer are mandatory. */ if (outputBufferLen != 0) { @@ -947,11 +961,9 @@ ValidateNetlinkCmd(UINT32 devOp, } /* Validate the PID. */ - if (ovsMsg->genlMsg.cmd != OVS_CTRL_CMD_WIN_GET_PID) { - if (ovsMsg->nlMsg.nlmsgPid != instance->pid) { - status = STATUS_INVALID_PARAMETER; - goto done; - } + if (ovsMsg->nlMsg.nlmsgPid != instance->pid) { + status = STATUS_INVALID_PARAMETER; + goto done; } status = STATUS_SUCCESS; @@ -992,38 +1004,33 @@ InvokeNetlinkCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx, /* * -------------------------------------------------------------------------- - * Command Handler for 'OVS_CTRL_CMD_WIN_GET_PID'. + * Handler for 'OVS_IOCTL_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 - * netlink support on Windows, OVS datapath generates the PID and lets the - * userspace query it. - * - * This function implements the query. + * created. This function passes the PID to userspace using METHOD_BUFFERED + * method. * -------------------------------------------------------------------------- */ static NTSTATUS -OvsGetPidCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx, - UINT32 *replyLen) +OvsGetPidHandler(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; + PUINT32 msgOut = (PUINT32)usrParamsCtx->outputBuffer; if (usrParamsCtx->outputLength >= sizeof *msgOut) { POVS_OPEN_INSTANCE instance = (POVS_OPEN_INSTANCE)usrParamsCtx->ovsInstance; RtlZeroMemory(msgOut, sizeof *msgOut); - msgOut->nlMsg.nlmsgSeq = msgIn->nlMsg.nlmsgSeq; - msgOut->nlMsg.nlmsgPid = instance->pid; + RtlCopyMemory(msgOut, &instance->pid, sizeof(*msgOut)); *replyLen = sizeof *msgOut; - /* XXX: We might need to return the DP index as well. */ } else { - return STATUS_NDIS_INVALID_LENGTH; + *replyLen = sizeof *msgOut; + status = STATUS_NDIS_INVALID_LENGTH; } - return STATUS_SUCCESS; + return status; } /* diff --git a/datapath-windows/ovsext/Flow.c b/datapath-windows/ovsext/Flow.c index 97220b468..f25fe9a4f 100644 --- a/datapath-windows/ovsext/Flow.c +++ b/datapath-windows/ovsext/Flow.c @@ -319,7 +319,7 @@ OvsFlowNlCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx, rc = OvsPutFlowIoctl(&mappedFlow, sizeof (struct OvsFlowPut), &stats); if (rc != STATUS_SUCCESS) { - OVS_LOG_ERROR("OvsFlowPut failed."); + OVS_LOG_ERROR("OvsPutFlowIoctl failed."); goto done; } -- cgit v1.2.1