datapath-windows: Add packet miss read Netlink command.
authorEitan Eliahu <eliahue@vmware.com>
Fri, 17 Oct 2014 00:53:27 +0000 (17:53 -0700)
committerBen Pfaff <blp@nicira.com>
Thu, 16 Oct 2014 22:35:16 +0000 (15:35 -0700)
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 <eliahue@vmware.com>
Co-authored-by: Nithin Raju <nithin@vmware.com>
Signed-off-by: Nithin Raju <nithin@vmware.com>
Signed-off-by: Ben Pfaff <blp@nicira.com>
datapath-windows/include/OvsDpInterfaceExt.h
datapath-windows/ovsext/Datapath.c
datapath-windows/ovsext/Datapath.h
datapath-windows/ovsext/User.c

index e9faecc..d357a16 100644 (file)
@@ -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 */
index 4e8be02..6cb9398 100644 (file)
@@ -91,6 +91,7 @@ static NetlinkCmdHandler OvsGetPidCmdHandler,
                          OvsPendEventCmdHandler,
                          OvsSubscribeEventCmdHandler,
                          OvsReadEventCmdHandler,
+                         OvsReadPacketCmdHandler,
                          OvsNewDpCmdHandler,
                          OvsGetDpCmdHandler,
                          OvsSetDpCmdHandler,
@@ -136,6 +137,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,
     }
 };
 
@@ -704,6 +710,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,
@@ -722,7 +729,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;
 
@@ -2292,4 +2301,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 */
index b9c7417..399baee 100644 (file)
@@ -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;
index f24c4e3..a8128bc 100644 (file)
@@ -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 ?