The old method of finding vports based on the
ovs port numbers is removed. Now, the lookup of a vport
by ovs port number is done the same way as the lookup by
hyper-v switch port id.

This is done so that the kernel is able to interact with
the userspace correctly when using vport channels.
The problem manifested in lib/dpif-netlink.c, at the function
vport_add_channels.

The field vportArray of OVS_SWITCH_CONTEXT is replaced by portNoHashArray.
The field portHashArray of OVS_SWITCH_CONTEXT is replaced by portIdHashArray,
so as to distinguish it from the new portNoHashArray.
The field portLink of OVS_VPORT_ENTRY is renamed by portIdLink, so as to
distinguish it from the new portNoLink.

Signed-off-by: Samuel Ghinet <sghi...@cloudbasesolutions.com>
---
 datapath-windows/include/OvsPub.h  |   2 -
 datapath-windows/ovsext/Actions.c  |  27 +++--
 datapath-windows/ovsext/Datapath.c |   6 +-
 datapath-windows/ovsext/Oid.c      |   4 +-
 datapath-windows/ovsext/Switch.c   |  40 +++----
 datapath-windows/ovsext/Switch.h   |  26 +++--
 datapath-windows/ovsext/Tunnel.c   |   2 +-
 datapath-windows/ovsext/Vport.c    | 223 ++++++++++++-------------------------
 datapath-windows/ovsext/Vport.h    |  44 +-------
 9 files changed, 132 insertions(+), 242 deletions(-)

diff --git a/datapath-windows/include/OvsPub.h 
b/datapath-windows/include/OvsPub.h
index ff0e8ce..823f646 100644
--- a/datapath-windows/include/OvsPub.h
+++ b/datapath-windows/include/OvsPub.h
@@ -132,8 +132,6 @@ typedef struct _OVS_VERSION {
     uint8_t mnrDrvVer;
 } OVS_VERSION, *POVS_VERSION;
 
-
-
 #define OVS_MAX_PORT_NAME_LENGTH 32
 
 typedef struct _OVS_VPORT_GET {
diff --git a/datapath-windows/ovsext/Actions.c 
b/datapath-windows/ovsext/Actions.c
index 180b6b8..002e1e4 100644
--- a/datapath-windows/ovsext/Actions.c
+++ b/datapath-windows/ovsext/Actions.c
@@ -205,7 +205,7 @@ OvsDetectTunnelRxPkt(OvsForwardingContext *ovsFwdCtx,
     if (!flowKey->ipKey.nwFrag &&
         flowKey->ipKey.nwProto == IPPROTO_UDP &&
         flowKey->ipKey.l4.tpDst == VXLAN_UDP_PORT_NBO) {
-        tunnelVport = OvsGetTunnelVport(OVS_VPORT_TYPE_VXLAN);
+        tunnelVport = ovsFwdCtx->switchContext->vxlanVport;
         ovsActionStats.rxVxlan++;
     }
 
@@ -271,9 +271,14 @@ OvsDetectTunnelPkt(OvsForwardingContext *ovsFwdCtx,
          * If the packet will not be encapsulated, consume the tunnel context
          * by clearing it.
          */
-        if (ovsFwdCtx->srcVportNo != OVS_DEFAULT_PORT_NO &&
-            !OvsIsVifVportNo(ovsFwdCtx->srcVportNo)) {
-            ovsFwdCtx->tunKey.dst = 0;
+        if (ovsFwdCtx->srcVportNo != OVS_DEFAULT_PORT_NO) {
+
+            POVS_VPORT_ENTRY vport = OvsFindVportByPortNo(
+                ovsFwdCtx->switchContext, ovsFwdCtx->srcVportNo);
+
+            if (!vport || vport->ovsType != OVS_VPORT_TYPE_NETDEV) {
+                ovsFwdCtx->tunKey.dst = 0;
+            }
         }
 
         /* Tunnel the packet only if tunnel context is set. */
@@ -1468,9 +1473,17 @@ OvsActionsExecute(POVS_SWITCH_CONTEXT switchContext,
             PNL_ATTR queueAttr;
             POVS_PACKET_QUEUE_ELEM elem;
             UINT32 queueId = OVS_DEFAULT_PACKET_QUEUE;
-            //XXX confusing that portNo is actually portId for external port.
-            BOOLEAN isRecv = (portNo == switchContext->externalPortId)
-                            || OvsIsTunnelVportNo(portNo);
+            BOOLEAN isRecv = FALSE;
+
+            POVS_VPORT_ENTRY vport = OvsFindVportByPortNo(switchContext,
+                                                          portNo);
+
+            if (vport) {
+                if (vport->isExternal ||
+                    OvsIsTunnelVportType(vport->ovsType)) {
+                    isRecv = TRUE;
+                }
+            }
 
             queueAttr = NlAttrFindNested(a, OVS_USERSPACE_ATTR_PID);
             userdataAttr = NlAttrFindNested(a, OVS_USERSPACE_ATTR_USERDATA);
diff --git a/datapath-windows/ovsext/Datapath.c 
b/datapath-windows/ovsext/Datapath.c
index 8a8c542..b688386 100644
--- a/datapath-windows/ovsext/Datapath.c
+++ b/datapath-windows/ovsext/Datapath.c
@@ -1357,7 +1357,7 @@ OvsGetVportDumpNext(POVS_USER_PARAMS_CONTEXT usrParamsCtx,
 
         for (i = inBucket; i < OVS_MAX_VPORT_ARRAY_SIZE; i++) {
             PLIST_ENTRY head, link;
-            head = &(gOvsSwitchContext->portHashArray[i]);
+            head = &(gOvsSwitchContext->portIdHashArray[i]);
             POVS_VPORT_ENTRY vport = NULL;
 
             outIndex = 0;
@@ -1369,9 +1369,9 @@ OvsGetVportDumpNext(POVS_USER_PARAMS_CONTEXT usrParamsCtx,
                  * inIndex + 1 vport from the bucket.
                 */
                 if (outIndex >= inIndex) {
-                    vport = CONTAINING_RECORD(link, OVS_VPORT_ENTRY, portLink);
+                    vport = CONTAINING_RECORD(link, OVS_VPORT_ENTRY, 
portIdLink);
 
-                    if (vport->portNo != 0) {
+                    if (vport->portNo != OVS_VPORT_NO_INVALID) {
                         OvsCreateMsgFromVport(vport, msgIn,
                                               usrParamsCtx->outputBuffer,
                                               usrParamsCtx->outputLength,
diff --git a/datapath-windows/ovsext/Oid.c b/datapath-windows/ovsext/Oid.c
index a675347..f180a21 100644
--- a/datapath-windows/ovsext/Oid.c
+++ b/datapath-windows/ovsext/Oid.c
@@ -167,7 +167,7 @@ OvsProcessSetOidPort(POVS_SWITCH_CONTEXT switchObject,
         OvsTeardownPort(switchObject, portParam);
         break;
     case OID_SWITCH_PORT_DELETE:
-        OvsDeletePort(switchObject, portParam);
+        OvsDeletePort(switchObject, portParam->PortId);
         break;
     default:
         break;
@@ -519,7 +519,7 @@ OvsOidRequestCompleteSetInfo(POVS_SWITCH_CONTEXT 
switchObject,
         switch(setInfo->Oid) {
         case OID_SWITCH_PORT_CREATE:
             OvsDeletePort(switchObject,
-                         (PNDIS_SWITCH_PORT_PARAMETERS)origHeader);
+                         ((PNDIS_SWITCH_PORT_PARAMETERS)origHeader)->PortId);
             break;
 
         case OID_SWITCH_NIC_CREATE:
diff --git a/datapath-windows/ovsext/Switch.c b/datapath-windows/ovsext/Switch.c
index 9578680..9ad9d71 100644
--- a/datapath-windows/ovsext/Switch.c
+++ b/datapath-windows/ovsext/Switch.c
@@ -354,11 +354,11 @@ OvsInitSwitchContext(POVS_SWITCH_CONTEXT switchContext)
     switchContext->dispatchLock =
         NdisAllocateRWLock(switchContext->NdisFilterHandle);
 
-    switchContext->vportArray =
-        (PVOID *)OvsAllocateMemory(sizeof (PVOID) * OVS_MAX_VPORT_ARRAY_SIZE);
+    switchContext->portNoHashArray = (PLIST_ENTRY)
+        OvsAllocateMemory(sizeof(LIST_ENTRY) * OVS_MAX_VPORT_ARRAY_SIZE);
     switchContext->nameHashArray = (PLIST_ENTRY)
          OvsAllocateMemory(sizeof (LIST_ENTRY) * OVS_MAX_VPORT_ARRAY_SIZE);
-    switchContext->portHashArray = (PLIST_ENTRY)
+    switchContext->portIdHashArray = (PLIST_ENTRY)
        OvsAllocateMemory(sizeof (LIST_ENTRY) * OVS_MAX_VPORT_ARRAY_SIZE);
     status = OvsAllocateFlowTable(&switchContext->datapath, switchContext);
 
@@ -367,20 +367,20 @@ OvsInitSwitchContext(POVS_SWITCH_CONTEXT switchContext)
     }
     if (status != NDIS_STATUS_SUCCESS ||
         switchContext->dispatchLock == NULL ||
-        switchContext->vportArray == NULL ||
+        switchContext->portNoHashArray == NULL ||
         switchContext->nameHashArray == NULL ||
-        switchContext->portHashArray == NULL) {
+        switchContext->portIdHashArray == NULL) {
         if (switchContext->dispatchLock) {
             NdisFreeRWLock(switchContext->dispatchLock);
         }
-        if (switchContext->vportArray) {
-            OvsFreeMemory(switchContext->vportArray);
+        if (switchContext->portNoHashArray) {
+            OvsFreeMemory(switchContext->portNoHashArray);
         }
         if (switchContext->nameHashArray) {
             OvsFreeMemory(switchContext->nameHashArray);
         }
-        if (switchContext->portHashArray) {
-            OvsFreeMemory(switchContext->portHashArray);
+        if (switchContext->portIdHashArray) {
+            OvsFreeMemory(switchContext->portIdHashArray);
         }
         OvsDeleteFlowTable(&switchContext->datapath);
         OvsCleanupBufferPool(switchContext);
@@ -393,15 +393,15 @@ OvsInitSwitchContext(POVS_SWITCH_CONTEXT switchContext)
         InitializeListHead(&switchContext->nameHashArray[i]);
     }
     for (i = 0; i < OVS_MAX_VPORT_ARRAY_SIZE; i++) {
-        InitializeListHead(&switchContext->portHashArray[i]);
+        InitializeListHead(&switchContext->portIdHashArray[i]);
+    }
+    for (i = 0; i < OVS_MAX_VPORT_ARRAY_SIZE; i++) {
+        InitializeListHead(&switchContext->portNoHashArray[i]);
     }
-    RtlZeroMemory(switchContext->vportArray,
-                  sizeof (PVOID) * OVS_MAX_VPORT_ARRAY_SIZE);
 
     switchContext->isActivated = FALSE;
     switchContext->isActivateFailed = FALSE;
     switchContext->dpNo = OVS_DP_NUMBER;
-    switchContext->lastPortIndex = OVS_MAX_VPORT_ARRAY_SIZE -1;
     ovsTimeIncrementPerTick = KeQueryTimeIncrement() / 10000;
     OVS_LOG_TRACE("Exit: Succesfully initialized switchContext: %p",
                   switchContext);
@@ -418,8 +418,8 @@ OvsCleanupSwitchContext(POVS_SWITCH_CONTEXT switchContext)
 
     NdisFreeRWLock(switchContext->dispatchLock);
     OvsFreeMemory(switchContext->nameHashArray);
-    OvsFreeMemory(switchContext->portHashArray);
-    OvsFreeMemory(switchContext->vportArray);
+    OvsFreeMemory(switchContext->portIdHashArray);
+    OvsFreeMemory(switchContext->portNoHashArray);
     OvsDeleteFlowTable(&switchContext->datapath);
     OvsCleanupBufferPool(switchContext);
     OVS_LOG_TRACE("Exit: Delete switchContext: %p", switchContext);
@@ -469,16 +469,6 @@ cleanup:
 }
 
 PVOID
-OvsGetVportFromIndex(UINT16 index)
-{
-    if (index < OVS_MAX_VPORT_ARRAY_SIZE &&
-            !OVS_IS_VPORT_ENTRY_NULL(gOvsSwitchContext, index)) {
-        return gOvsSwitchContext->vportArray[index];
-    }
-    return NULL;
-}
-
-PVOID
 OvsGetExternalVport()
 {
     return gOvsSwitchContext->externalVport;
diff --git a/datapath-windows/ovsext/Switch.h b/datapath-windows/ovsext/Switch.h
index 5199268..15f39b8 100644
--- a/datapath-windows/ovsext/Switch.h
+++ b/datapath-windows/ovsext/Switch.h
@@ -24,6 +24,8 @@
 #include "NetProto.h"
 #include "BufferMgmt.h"
 #define OVS_MAX_VPORT_ARRAY_SIZE 1024
+#define OVS_MAX_VPORTS          MAXUINT16
+#define OVS_VPORT_NO_INVALID    OVS_MAX_VPORTS
 
 #define OVS_VPORT_MASK (OVS_MAX_VPORT_ARRAY_SIZE - 1)
 
@@ -43,16 +45,14 @@
 #define OVS_INTERNAL_VPOR_END    72
 #define OVS_VM_VPORT_START       72
 #define OVS_VM_VPORT_MAX         0xffff
-#define OVS_VPORT_INDEX(_portNo)    ((_portNo) & 0xffffff)
-#define OVS_VPORT_PORT_NO(_index, _gen) \
-          (((_index) & 0xffffff) | ((UINT32)(_gen) << 24))
-#define OVS_VPORT_GEN(portNo) (portNo >> 24)
 
 #define OVS_MAX_PHYS_ADAPTERS    32
 #define OVS_MAX_IP_VPOR          32
 
 #define OVS_HASH_BASIS   0x13578642
 
+typedef struct _OVS_VPORT_ENTRY *POVS_VPORT_ENTRY;
+
 typedef struct _OVS_DATAPATH
 {
    PLIST_ENTRY             flowTable;       // Contains OvsFlows.
@@ -104,16 +104,21 @@ typedef struct _OVS_SWITCH_CONTEXT
 
     NDIS_SWITCH_PORT_ID     externalPortId;
     NDIS_SWITCH_PORT_ID     internalPortId;
-    PVOID                   externalVport;  // the virtual adapter vport
-    PVOID                   internalVport;
+    POVS_VPORT_ENTRY        externalVport;  // the virtual adapter vport
+    POVS_VPORT_ENTRY        internalVport;
+
+    /*
+     * XXX when we support multiple VXLAN ports, we will need a list entry
+     * instead
+    */
+    POVS_VPORT_ENTRY        vxlanVport;
 
-    PVOID                  *vportArray;
-    PLIST_ENTRY             nameHashArray;  // based on ovsName
-    PLIST_ENTRY             portHashArray;  // based on portId
+    PLIST_ENTRY             nameHashArray;    // based on ovsName
+    PLIST_ENTRY             portIdHashArray;  // based on portId
+    PLIST_ENTRY             portNoHashArray;  // based on ovs port number
 
     UINT32                  numPhysicalNics;
     UINT32                  numVports;     // include validation port
-    UINT32                  lastPortIndex;
 
     /* Lock taken over the switch. This protects the ports on the switch. */
     PNDIS_RW_LOCK_EX        dispatchLock;
@@ -163,7 +168,6 @@ OvsReleaseDatapath(OVS_DATAPATH *datapath,
 }
 
 
-PVOID OvsGetVportFromIndex(UINT16 index);
 PVOID OvsGetExternalVport();
 
 #endif /* __SWITCH_H_ */
diff --git a/datapath-windows/ovsext/Tunnel.c b/datapath-windows/ovsext/Tunnel.c
index 304ab59..64e279c 100644
--- a/datapath-windows/ovsext/Tunnel.c
+++ b/datapath-windows/ovsext/Tunnel.c
@@ -284,7 +284,7 @@ OvsInjectPacketThroughActions(PNET_BUFFER_LIST pNbl,
 
         SendFlags |= NDIS_SEND_FLAGS_DISPATCH_LEVEL;
 
-        vport = OvsGetTunnelVport(OVS_VPORT_TYPE_VXLAN);
+        vport = gOvsSwitchContext->vxlanVport;
 
         if (vport == NULL){
             status = STATUS_UNSUCCESSFUL;
diff --git a/datapath-windows/ovsext/Vport.c b/datapath-windows/ovsext/Vport.c
index 14b68d9..292eb2e 100644
--- a/datapath-windows/ovsext/Vport.c
+++ b/datapath-windows/ovsext/Vport.c
@@ -38,20 +38,17 @@
     OVS_LOG_TRACE("Exit: PortId: %x, NicIndex: %d", _nic->PortId, \
                                                     _nic->NicIndex)
 
-#define VPORT_PORT_ENTER(_port) \
-    OVS_LOG_TRACE("Enter: PortId: %x", _port->PortId)
+#define VPORT_PORT_ENTER(_portId) \
+    OVS_LOG_TRACE("Enter: PortId: %x", _portId)
 
-#define VPORT_PORT_EXIT(_port) \
-    OVS_LOG_TRACE("Exit: PortId: %x", _port->PortId)
+#define VPORT_PORT_EXIT(_portId) \
+    OVS_LOG_TRACE("Exit: PortId: %x", _portId)
 
 #define OVS_VPORT_DEFAULT_WAIT_TIME_MICROSEC    100
 
 extern POVS_SWITCH_CONTEXT gOvsSwitchContext;
 extern PNDIS_SPIN_LOCK gOvsCtrlLock;
 
-static UINT32 OvsGetVportNo(POVS_SWITCH_CONTEXT switchContext, UINT32 nicIndex,
-                            OVS_VPORT_TYPE ovsType,
-                            BOOLEAN isExternal);
 static POVS_VPORT_ENTRY OvsAllocateVport(VOID);
 static VOID OvsInitVportWithPortParam(POVS_VPORT_ENTRY vport,
                 PNDIS_SWITCH_PORT_PARAMETERS portParam);
@@ -131,16 +128,16 @@ OvsTeardownPort(POVS_SWITCH_CONTEXT switchContext,
 
 VOID
 OvsDeletePort(POVS_SWITCH_CONTEXT switchContext,
-              PNDIS_SWITCH_PORT_PARAMETERS portParam)
+              NDIS_SWITCH_PORT_ID portId)
 {
     POVS_VPORT_ENTRY vport;
     LOCK_STATE_EX lockState;
 
-    VPORT_PORT_ENTER(portParam);
+    VPORT_PORT_ENTER(portId);
 
     NdisAcquireRWLockWrite(switchContext->dispatchLock, &lockState, 0);
     vport = OvsFindVportByPortIdAndNicIndex(switchContext,
-                                            portParam->PortId, 0);
+                                            portId, 0);
     if (vport) {
         OvsRemoveAndDeleteVport(switchContext, vport);
     } else {
@@ -148,7 +145,7 @@ OvsDeletePort(POVS_SWITCH_CONTEXT switchContext,
     }
     NdisReleaseRWLock(switchContext->dispatchLock, &lockState);
 
-    VPORT_PORT_EXIT(portParam);
+    VPORT_PORT_EXIT(portId);
 }
 
 
@@ -214,7 +211,7 @@ OvsCreateNic(POVS_SWITCH_CONTEXT switchContext,
 
 add_nic_done:
     NdisReleaseRWLock(switchContext->dispatchLock, &lockState);
-    if (portNo && event) {
+    if (portNo != OVS_VPORT_NO_INVALID && event) {
         OvsPostEvent(portNo, event);
     }
 
@@ -263,6 +260,7 @@ OvsConnectNic(POVS_SWITCH_CONTEXT switchContext,
 
     NdisReleaseRWLock(switchContext->dispatchLock, &lockState);
 
+    /* XXX only if portNo != INVALID or always? */
     OvsPostEvent(portNo, OVS_EVENT_LINK_UP);
 
     if (nicParam->NicType == NdisSwitchNicTypeInternal) {
@@ -387,6 +385,7 @@ OvsDisconnectNic(POVS_SWITCH_CONTEXT switchContext,
 
     NdisReleaseRWLock(switchContext->dispatchLock, &lockState);
 
+    /* XXX if portNo != INVALID or always? */
     OvsPostEvent(portNo, OVS_EVENT_LINK_DOWN);
 
     if (isInternalPort) {
@@ -435,6 +434,7 @@ OvsDeleteNic(POVS_SWITCH_CONTEXT switchContext,
     vport->ovsState = OVS_STATE_PORT_CREATED;
 
     NdisReleaseRWLock(switchContext->dispatchLock, &lockState);
+    /* XXX if portNo != INVALID or always? */
     OvsPostEvent(portNo, OVS_EVENT_DISCONNECT);
 
 done:
@@ -449,14 +449,15 @@ POVS_VPORT_ENTRY
 OvsFindVportByPortNo(POVS_SWITCH_CONTEXT switchContext,
                      UINT32 portNo)
 {
-    if (OVS_VPORT_INDEX(portNo) < OVS_MAX_VPORT_ARRAY_SIZE) {
-        if (OVS_IS_VPORT_ENTRY_NULL(switchContext, OVS_VPORT_INDEX(portNo))) {
-            return NULL;
-        } else {
-            POVS_VPORT_ENTRY vport;
-            vport = (POVS_VPORT_ENTRY)
-                     switchContext->vportArray[OVS_VPORT_INDEX(portNo)];
-            return vport->portNo == portNo ? vport : NULL;
+    POVS_VPORT_ENTRY vport;
+    PLIST_ENTRY head, link;
+    UINT32 hash = OvsJhashBytes((const VOID *)&portNo, sizeof(portNo),
+                                OVS_HASH_BASIS);
+    head = &(switchContext->portNoHashArray[hash & OVS_VPORT_MASK]);
+    LIST_FORALL(head, link) {
+        vport = CONTAINING_RECORD(link, OVS_VPORT_ENTRY, portNoLink);
+        if (vport->portNo == portNo) {
+            return vport;
         }
     }
     return NULL;
@@ -488,18 +489,7 @@ OvsFindVportByPortIdAndNicIndex(POVS_SWITCH_CONTEXT 
switchContext,
                                 NDIS_SWITCH_NIC_INDEX index)
 {
     if (portId == switchContext->externalPortId) {
-        if (index == 0) {
-            return (POVS_VPORT_ENTRY)switchContext->externalVport;
-        } else if (index > OVS_MAX_PHYS_ADAPTERS) {
-            return NULL;
-        }
-        if (OVS_IS_VPORT_ENTRY_NULL(switchContext,
-                                    index + OVS_EXTERNAL_VPORT_START)) {
-           return NULL;
-        } else {
-           return (POVS_VPORT_ENTRY)switchContext->vportArray[
-                            index + OVS_EXTERNAL_VPORT_START];
-        }
+        return (POVS_VPORT_ENTRY)switchContext->externalVport;
     } else if (switchContext->internalPortId == portId) {
         return (POVS_VPORT_ENTRY)switchContext->internalVport;
     } else {
@@ -507,9 +497,9 @@ OvsFindVportByPortIdAndNicIndex(POVS_SWITCH_CONTEXT 
switchContext,
         POVS_VPORT_ENTRY vport;
         UINT32 hash;
         hash = OvsJhashWords((UINT32 *)&portId, 1, OVS_HASH_BASIS);
-        head = &(switchContext->portHashArray[hash & OVS_VPORT_MASK]);
+        head = &(switchContext->portIdHashArray[hash & OVS_VPORT_MASK]);
         LIST_FORALL(head, link) {
-            vport = CONTAINING_RECORD(link, OVS_VPORT_ENTRY, portLink);
+            vport = CONTAINING_RECORD(link, OVS_VPORT_ENTRY, portIdLink);
             if (portId == vport->portId && index == vport->nicIndex) {
                 return vport;
             }
@@ -518,71 +508,6 @@ OvsFindVportByPortIdAndNicIndex(POVS_SWITCH_CONTEXT 
switchContext,
     }
 }
 
-static UINT32
-OvsGetVportNo(POVS_SWITCH_CONTEXT switchContext,
-              UINT32 nicIndex,
-              OVS_VPORT_TYPE ovsType,
-              BOOLEAN isExternal)
-{
-    UINT32 index = 0xffffff, i = 0;
-    UINT64 gen;
-
-    if (isExternal) {
-        if (nicIndex == 0) {
-            return 0;  // not a valid portNo
-        } else if (nicIndex > OVS_MAX_PHYS_ADAPTERS) {
-            return 0;
-        } else {
-            index = nicIndex + OVS_EXTERNAL_VPORT_START;
-        }
-    }
-
-    switch (ovsType) {
-    case OVS_VPORT_TYPE_INTERNAL:
-        index = OVS_INTERNAL_VPORT_DEFAULT_INDEX;
-        break;
-    case OVS_VPORT_TYPE_NETDEV:
-        index = switchContext->lastPortIndex + 1;
-        if (index == OVS_MAX_VPORT_ARRAY_SIZE) {
-            index = OVS_VM_VPORT_START;
-        }
-        while (!OVS_IS_VPORT_ENTRY_NULL(switchContext, index) &&
-               i < (OVS_MAX_VPORT_ARRAY_SIZE - OVS_VM_VPORT_START)) {
-            index++;
-            i++;
-            if (index == OVS_MAX_VPORT_ARRAY_SIZE) {
-                index = OVS_VM_VPORT_START;
-            }
-        }
-        if (i == (OVS_MAX_VPORT_ARRAY_SIZE - OVS_VM_VPORT_START)) {
-            return 0; // not available
-        }
-        switchContext->lastPortIndex = index;
-        break;
-    case OVS_VPORT_TYPE_GRE:
-        index = OVS_GRE_VPORT_INDEX;
-        break;
-    case OVS_VPORT_TYPE_GRE64:
-        index = OVS_GRE64_VPORT_INDEX;
-        break;
-    case OVS_VPORT_TYPE_VXLAN:
-        index = OVS_VXLAN_VPORT_INDEX;
-        break;
-    default:
-        ASSERT(isExternal);
-    }
-    if (index > OVS_MAX_VPORT_ARRAY_SIZE) {
-        return 0;
-    }
-    gen = (UINT64)switchContext->vportArray[index];
-    if (gen > 0xff) {
-        return 0;
-    } else if (gen == 0) {
-        gen++;
-    }
-    return OVS_VPORT_PORT_NO(index, (UINT32)gen);
-}
-
 
 static POVS_VPORT_ENTRY
 OvsAllocateVport(VOID)
@@ -704,21 +629,13 @@ OvsInitPhysNicVport(POVS_VPORT_ENTRY vport,
 }
 static NDIS_STATUS
 OvsInitVportCommon(POVS_SWITCH_CONTEXT switchContext,
-POVS_VPORT_ENTRY vport)
+                   POVS_VPORT_ENTRY vport)
 {
     UINT32 hash;
     size_t len;
     if (vport->portType != NdisSwitchPortTypeExternal ||
         vport->nicIndex != 0) {
-        vport->portNo = OvsGetVportNo(switchContext, vport->nicIndex,
-            vport->ovsType, vport->portType == NdisSwitchPortTypeExternal);
-        if (vport->portNo == 0) {
-            return NDIS_STATUS_RESOURCES;
-        }
-        ASSERT(OVS_IS_VPORT_ENTRY_NULL(switchContext,
-            OVS_VPORT_INDEX(vport->portNo)));
-
-        switchContext->vportArray[OVS_VPORT_INDEX(vport->portNo)] = vport;
+        vport->portNo = OVS_VPORT_NO_INVALID;
     }
     switch (vport->portType) {
     case NdisSwitchPortTypeExternal:
@@ -758,9 +675,15 @@ POVS_VPORT_ENTRY vport)
     hash = OvsJhashBytes(vport->ovsName, vport->ovsNameLen, OVS_HASH_BASIS);
     InsertHeadList(&switchContext->nameHashArray[hash & OVS_VPORT_MASK],
         &vport->nameLink);
+
     hash = OvsJhashWords(&vport->portId, 1, OVS_HASH_BASIS);
-    InsertHeadList(&switchContext->portHashArray[hash & OVS_VPORT_MASK],
-        &vport->portLink);
+    InsertHeadList(&switchContext->portIdHashArray[hash & OVS_VPORT_MASK],
+        &vport->portIdLink);
+
+    hash = OvsJhashWords(&vport->portNo, 1, OVS_HASH_BASIS);
+    InsertHeadList(&switchContext->portNoHashArray[hash & OVS_VPORT_MASK],
+        &vport->portNoLink);
+
     switchContext->numVports++;
     return NDIS_STATUS_SUCCESS;
 }
@@ -770,8 +693,6 @@ static VOID
 OvsRemoveAndDeleteVport(POVS_SWITCH_CONTEXT switchContext,
                         POVS_VPORT_ENTRY vport)
 {
-    UINT64 gen = vport->portNo >> 24;
-
     if (vport->isExternal) {
         if (vport->nicIndex == 0) {
             ASSERT(switchContext->numPhysicalNics == 0);
@@ -803,10 +724,8 @@ OvsRemoveAndDeleteVport(POVS_SWITCH_CONTEXT switchContext,
     }
 
     RemoveEntryList(&vport->nameLink);
-    RemoveEntryList(&vport->portLink);
-    gen = (gen + 1) & 0xff;
-    switchContext->vportArray[OVS_VPORT_INDEX(vport->portNo)] =
-                     (PVOID)(UINT64)gen;
+    RemoveEntryList(&vport->portIdLink);
+    RemoveEntryList(&vport->portNoLink);
     switchContext->numVports--;
     OvsFreeMemory(vport);
 }
@@ -925,20 +844,25 @@ cleanup:
 VOID
 OvsClearAllSwitchVports(POVS_SWITCH_CONTEXT switchContext)
 {
-    UINT32 i;
+    for (UINT hash = 0; hash < OVS_MAX_VPORT_ARRAY_SIZE; ++hash) {
+        PLIST_ENTRY head, link;
+
+        head = &(switchContext->portNoHashArray[hash & OVS_VPORT_MASK]);
+        LIST_FORALL(head, link) {
+            POVS_VPORT_ENTRY vport;
 
-    for (i = 0; i < OVS_MAX_VPORT_ARRAY_SIZE; i++) {
-        if (!OVS_IS_VPORT_ENTRY_NULL(switchContext, i)) {
-            OvsRemoveAndDeleteVport(switchContext,
-                       (POVS_VPORT_ENTRY)switchContext->vportArray[i]);
+            vport = CONTAINING_RECORD(link, OVS_VPORT_ENTRY, portNoLink);
+            OvsRemoveAndDeleteVport(switchContext, vport);
         }
     }
+
     if (switchContext->externalVport) {
         OvsRemoveAndDeleteVport(switchContext,
                         (POVS_VPORT_ENTRY)switchContext->externalVport);
     }
 }
 
+#if !OVS_USE_NL_INTERFACE
 NTSTATUS
 OvsDumpVportIoctl(PVOID inputBuffer,
                   UINT32 inputLength,
@@ -947,9 +871,8 @@ OvsDumpVportIoctl(PVOID inputBuffer,
                   UINT32 *replyLen)
 {
     UINT32 numVports, count;
-    UINT32 dpNo, i;
+    UINT32 dpNo;
     UINT32 *outPtr;
-    POVS_VPORT_ENTRY vport;
     LOCK_STATE_EX lockState;
 
     if (inputLength < sizeof (UINT32)) {
@@ -972,19 +895,27 @@ OvsDumpVportIoctl(PVOID inputBuffer,
     numVports = outputLength/sizeof (UINT32);
     numVports = MIN(gOvsSwitchContext->numVports, numVports);
     outPtr = (UINT32 *)outputBuffer;
-    for (i = 0, count = 0;
-         i < OVS_MAX_VPORT_ARRAY_SIZE && count < numVports; i++) {
-        vport = (POVS_VPORT_ENTRY)gOvsSwitchContext->vportArray[i];
-        if (OVS_IS_VPORT_ENTRY_NULL(gOvsSwitchContext, i)) {
-            continue;
-        }
-        if (vport->ovsState == OVS_STATE_CONNECTED ||
-            vport->ovsState == OVS_STATE_NIC_CREATED) {
-            *outPtr = vport->portNo;
-            outPtr++;
-            count++;
+
+    count = 0;
+
+    for (UINT hash = 0; hash < OVS_MAX_VPORT_ARRAY_SIZE; ++hash) {
+        PLIST_ENTRY head, link;
+
+        head = &(gOvsSwitchContext->portNoHashArray[hash & OVS_VPORT_MASK]);
+        LIST_FORALL(head, link) {
+            POVS_VPORT_ENTRY vport;
+
+            vport = CONTAINING_RECORD(link, OVS_VPORT_ENTRY, portNoLink);
+
+            if (vport->ovsState == OVS_STATE_CONNECTED ||
+                vport->ovsState == OVS_STATE_NIC_CREATED) {
+                *outPtr = vport->portNo;
+                outPtr++;
+                count++;
+            }
         }
     }
+
     NdisReleaseRWLock(gOvsSwitchContext->dispatchLock, &lockState);
     NdisReleaseSpinLock(gOvsCtrlLock);
     *replyLen = count * sizeof (UINT32);
@@ -1060,6 +991,7 @@ OvsGetVportIoctl(PVOID inputBuffer,
     *replyLen = sizeof (OVS_VPORT_INFO);
     return STATUS_SUCCESS;
 }
+#endif
 
 
 NTSTATUS
@@ -1090,6 +1022,7 @@ OvsInitTunnelVport(POVS_VPORT_ENTRY vport,
     return status;
 }
 
+#if !OVS_USE_NL_INTERFACE
 NTSTATUS
 OvsAddVportIoctl(PVOID inputBuffer,
                  UINT32 inputLength,
@@ -1102,7 +1035,6 @@ OvsAddVportIoctl(PVOID inputBuffer,
     POVS_VPORT_ADD_REQUEST addReq;
     POVS_VPORT_ENTRY vport;
     LOCK_STATE_EX lockState;
-    UINT32 index;
     UINT32 portNo;
 
     OVS_LOG_TRACE("Enter: inputLength: %u, outputLength: %u",
@@ -1115,21 +1047,6 @@ OvsAddVportIoctl(PVOID inputBuffer,
     addReq = (POVS_VPORT_ADD_REQUEST)inputBuffer;
     addReq->name[OVS_MAX_PORT_NAME_LENGTH - 1] = 0;
 
-    switch (addReq->type) {
-    case OVS_VPORT_TYPE_GRE:
-        index = OVS_GRE_VPORT_INDEX;
-        break;
-    case OVS_VPORT_TYPE_GRE64:
-        index = OVS_GRE64_VPORT_INDEX;
-        break;
-    case OVS_VPORT_TYPE_VXLAN:
-        index = OVS_VXLAN_VPORT_INDEX;
-        break;
-    default:
-        status = STATUS_NOT_SUPPORTED;
-        goto vport_add_done;
-    }
-
     vport = (POVS_VPORT_ENTRY)OvsAllocateVport();
     if (vport == NULL) {
         status = STATUS_INSUFFICIENT_RESOURCES;
@@ -1146,7 +1063,7 @@ OvsAddVportIoctl(PVOID inputBuffer,
     }
     NdisAcquireRWLockRead(gOvsSwitchContext->dispatchLock, &lockState,
                           NDIS_RWL_AT_DISPATCH_LEVEL);
-    if (!OVS_IS_VPORT_ENTRY_NULL(gOvsSwitchContext, index)) {
+    if (OvsFindVportByPortNo(gOvsSwitchContext, addReq->dstPort)) {
         status = STATUS_DEVICE_BUSY;
         NdisReleaseRWLock(gOvsSwitchContext->dispatchLock, &lockState);
         NdisReleaseSpinLock(gOvsCtrlLock);
@@ -1243,6 +1160,8 @@ vport_del_done:
     return status;
 }
 
+#endif //OVS_USE_NL_INTERFACE
+
 NTSTATUS
 OvsConvertIfCountedStrToAnsiStr(PIF_COUNTED_STRING wStr,
                                 CHAR *str,
diff --git a/datapath-windows/ovsext/Vport.h b/datapath-windows/ovsext/Vport.h
index 5450fca..5516ee2 100644
--- a/datapath-windows/ovsext/Vport.h
+++ b/datapath-windows/ovsext/Vport.h
@@ -64,7 +64,8 @@ typedef struct _OVS_VPORT_FULL_STATS {
  */
 typedef struct _OVS_VPORT_ENTRY {
     LIST_ENTRY             nameLink;
-    LIST_ENTRY             portLink;
+    LIST_ENTRY             portIdLink;
+    LIST_ENTRY             portNoLink;
 
     OVS_VPORT_STATE        ovsState;
     OVS_VPORT_TYPE         ovsType;
@@ -98,9 +99,6 @@ typedef struct _OVS_VPORT_ENTRY {
 
 struct _OVS_SWITCH_CONTEXT;
 
-#define OVS_IS_VPORT_ENTRY_NULL(_SwitchContext, _i) \
-   ((UINT64)(_SwitchContext)->vportArray[_i] <= 0xff)
-
 POVS_VPORT_ENTRY
 OvsFindVportByPortNo(struct _OVS_SWITCH_CONTEXT *switchContext,
                      UINT32 portNo);
@@ -117,6 +115,7 @@ NDIS_STATUS OvsInitConfiguredSwitchNics(struct 
_OVS_SWITCH_CONTEXT *switchContex
 
 VOID OvsClearAllSwitchVports(struct _OVS_SWITCH_CONTEXT *switchContext);
 
+#if !OVS_USE_NL_INTERFACE
 NTSTATUS OvsDumpVportIoctl(PVOID inputBuffer, UINT32 inputLength,
                            PVOID outputBuffer, UINT32 outputLength,
                            UINT32 *replyLen);
@@ -128,6 +127,7 @@ NTSTATUS OvsAddVportIoctl(PVOID inputBuffer, UINT32 
inputLength,
                           UINT32 *replyLen);
 NTSTATUS OvsDelVportIoctl(PVOID inputBuffer, UINT32 inputLength,
                           UINT32 *replyLen);
+#endif
 NTSTATUS OvsGetExtInfoIoctl(PVOID inputBuffer, UINT32 inputLength,
                             PVOID outputBuffer, UINT32 outputLength,
                             UINT32 *replyLen);
@@ -138,7 +138,7 @@ NDIS_STATUS OvsCreatePort(POVS_SWITCH_CONTEXT switchContext,
 VOID OvsTeardownPort(POVS_SWITCH_CONTEXT switchContext,
                      PNDIS_SWITCH_PORT_PARAMETERS portParam);
 VOID OvsDeletePort(POVS_SWITCH_CONTEXT switchContext,
-                   PNDIS_SWITCH_PORT_PARAMETERS portParam);
+                   NDIS_SWITCH_PORT_ID portId);
 VOID OvsConnectNic(POVS_SWITCH_CONTEXT switchContext,
                    PNDIS_SWITCH_NIC_PARAMETERS nicParam);
 VOID OvsUpdateNic(POVS_SWITCH_CONTEXT switchContext,
@@ -162,40 +162,6 @@ OvsIsInternalVportType(OVS_VPORT_TYPE ovsType)
     return ovsType == OVS_VPORT_TYPE_INTERNAL;
 }
 
-static __inline BOOLEAN
-OvsIsTunnelVportNo(UINT32 portNo)
-{
-    UINT32 idx = OVS_VPORT_INDEX(portNo);
-    return (idx >= OVS_TUNNEL_INDEX_START && idx <= OVS_TUNNEL_INDEX_END);
-}
-
-static __inline BOOLEAN
-OvsIsVifVportNo(UINT32 portNo)
-{
-    UINT32 idx = OVS_VPORT_INDEX(portNo);
-    return (idx >= OVS_VM_VPORT_START && idx <= OVS_VM_VPORT_MAX);
-}
-
-static __inline POVS_VPORT_ENTRY
-OvsGetTunnelVport(OVS_VPORT_TYPE type)
-{
-    ASSERT(OvsIsTunnelVportType(type));
-    switch(type) {
-    case OVS_VPORT_TYPE_VXLAN:
-        return (POVS_VPORT_ENTRY) OvsGetVportFromIndex(OVS_VXLAN_VPORT_INDEX);
-    default:
-        ASSERT(! "OvsGetTunnelVport not implemented for this tunnel.");
-    }
-
-    return NULL;
-}
-
-static __inline PVOID
-OvsGetVportPriv(OVS_VPORT_TYPE type)
-{
-    return OvsGetTunnelVport(type)->priv;
-}
-
 static __inline UINT32
 OvsGetExternalMtu()
 {
-- 
1.8.3.msysgit.0

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to