The change include the Packet Read handler. The current implementation reads once packet at a time. This should be updated once user mode code is in place.
signed-off-by: Eitan Eliahu <elia...@vmware.com> --- datapath-windows/include/OvsDpInterfaceExt.h | 3 +- datapath-windows/ovsext/Datapath.c | 53 +++++++++++++++++++++++++++- datapath-windows/ovsext/Datapath.h | 1 + datapath-windows/ovsext/User.c | 11 +++--- 4 files changed, 60 insertions(+), 8 deletions(-) diff --git a/datapath-windows/include/OvsDpInterfaceExt.h b/datapath-windows/include/OvsDpInterfaceExt.h index e9faecc..d357a16 100644 --- a/datapath-windows/include/OvsDpInterfaceExt.h +++ b/datapath-windows/include/OvsDpInterfaceExt.h @@ -80,7 +80,8 @@ enum ovs_win_control_cmd { OVS_CTRL_CMD_MC_SUBSCRIBE_REQ, /* This command is logically belong to the Vport family */ - OVS_CTRL_CMD_EVENT_NOTIFY + OVS_CTRL_CMD_EVENT_NOTIFY, + OVS_CTRL_CMD_READ_NOTIFY }; /* NL Attributes for joining/unjoining an MC group */ diff --git a/datapath-windows/ovsext/Datapath.c b/datapath-windows/ovsext/Datapath.c index 9a4827a..2c57ea0 100644 --- a/datapath-windows/ovsext/Datapath.c +++ b/datapath-windows/ovsext/Datapath.c @@ -91,6 +91,7 @@ static NetlinkCmdHandler OvsGetPidCmdHandler, OvsPendEventCmdHandler, OvsSubscribeEventCmdHandler, OvsReadEventCmdHandler, + OvsReadPacketCmdHandler, OvsNewDpCmdHandler, OvsGetDpCmdHandler, OvsSetDpCmdHandler, @@ -135,6 +136,11 @@ NETLINK_CMD nlControlFamilyCmdOps[] = { .handler = OvsReadEventCmdHandler, .supportedDevOp = OVS_READ_EVENT_DEV_OP, .validateDpIndex = FALSE, + }, + { .cmd = OVS_CTRL_CMD_READ_NOTIFY, + .handler = OvsReadPacketCmdHandler, + .supportedDevOp = OVS_READ_PACKET_DEV_OP, + .validateDpIndex = FALSE, } }; @@ -698,6 +704,7 @@ OvsDeviceControl(PDEVICE_OBJECT deviceObject, break; case OVS_IOCTL_READ_EVENT: + case OVS_IOCTL_READ_PACKET: /* This IOCTL is used to read events */ if (outputBufferLen != 0) { status = MapIrpOutputBuffer(irp, outputBufferLen, @@ -716,7 +723,9 @@ OvsDeviceControl(PDEVICE_OBJECT deviceObject, ovsMsg = &ovsMsgReadOp; ovsMsg->nlMsg.nlmsgType = OVS_WIN_NL_CTRL_FAMILY_ID; /* An "artificial" command so we can use NL family function table*/ - ovsMsg->genlMsg.cmd = OVS_CTRL_CMD_EVENT_NOTIFY; + ovsMsg->genlMsg.cmd = (code == OVS_IOCTL_READ_EVENT) ? + OVS_CTRL_CMD_EVENT_NOTIFY : + OVS_CTRL_CMD_READ_NOTIFY; devOp = OVS_READ_DEV_OP; break; @@ -2160,4 +2169,46 @@ cleanup: OvsReleaseCtrlLock(); return status; } + +/* + * -------------------------------------------------------------------------- + * Handler for reading missed pacckets from the driver event queue. This + * handler is executed when user modes issues a socket receive on a socket + * -------------------------------------------------------------------------- + */ +static NTSTATUS +OvsReadPacketCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx, + UINT32 *replyLen) +{ +#ifdef DBG + POVS_MESSAGE msgOut = (POVS_MESSAGE)usrParamsCtx->outputBuffer; +#endif + POVS_OPEN_INSTANCE instance = + (POVS_OPEN_INSTANCE)usrParamsCtx->ovsInstance; + NTSTATUS status; + + ASSERT(usrParamsCtx->devOp == OVS_READ_DEV_OP); + + /* Should never read events with a dump socket */ + ASSERT(instance->dumpState.ovsMsg == NULL); + + /* Must have an packet queue */ + ASSERT(instance->packetQueue != NULL); + + /* Output buffer has been validated while validating read dev op. */ + ASSERT(msgOut != NULL && usrParamsCtx->outputLength >= sizeof *msgOut); + + OvsAcquireCtrlLock(); + if (!gOvsSwitchContext) { + status = STATUS_SUCCESS; + OvsReleaseCtrlLock(); + return status; + } + OvsReleaseCtrlLock(); + + /* Read a packet from the instance queue */ + status = OvsReadDpIoctl(instance->fileObject, usrParamsCtx->outputBuffer, + usrParamsCtx->outputLength, replyLen); + return status; +} #endif /* OVS_USE_NL_INTERFACE */ diff --git a/datapath-windows/ovsext/Datapath.h b/datapath-windows/ovsext/Datapath.h index b9c7417..399baee 100644 --- a/datapath-windows/ovsext/Datapath.h +++ b/datapath-windows/ovsext/Datapath.h @@ -45,6 +45,7 @@ typedef struct _OVS_MESSAGE_ERROR { #define OVS_WRITE_DEV_OP (1 << 1) #define OVS_TRANSACTION_DEV_OP (1 << 2) #define OVS_READ_EVENT_DEV_OP (1 << 3) +#define OVS_READ_PACKET_DEV_OP (1 << 4) typedef struct _OVS_DEVICE_EXTENSION { INT numberOpenInstance; diff --git a/datapath-windows/ovsext/User.c b/datapath-windows/ovsext/User.c index f24c4e3..a8128bc 100644 --- a/datapath-windows/ovsext/User.c +++ b/datapath-windows/ovsext/User.c @@ -226,13 +226,12 @@ OvsReadDpIoctl(PFILE_OBJECT fileObject, if ((elem->hdrInfo.tcpCsumNeeded || elem->hdrInfo.udpCsumNeeded) && len == elem->packet.totalLen) { UINT16 sum, *ptr; - UINT16 size = (UINT16)(elem->packet.userDataLen + - elem->hdrInfo.l4Offset + - (UINT16)sizeof (OVS_PACKET_INFO)); - RtlCopyMemory(outputBuffer, &elem->packet, size); - ASSERT(len - size >= elem->hdrInfo.l4PayLoad); + UINT16 size = (UINT16)(elem->packet.payload - elem->packet.data + + elem->hdrInfo.l4Offset); + RtlCopyMemory(outputBuffer, &elem->packet.data, size); + ASSERT(len - size >= elem->hdrInfo.l4PayLoad); sum = CopyAndCalculateChecksum((UINT8 *)outputBuffer + size, - (UINT8 *)&elem->packet + size, + (UINT8 *)&elem->packet.data + size, elem->hdrInfo.l4PayLoad, 0); ptr =(UINT16 *)((UINT8 *)outputBuffer + size + (elem->hdrInfo.tcpCsumNeeded ? -- 1.9.4.msysgit.0 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev