[ovs-dev] [PATCH 09/14] datapath-wuindows: Make VPORT ovs number values smaller than MAXUINT16

Samuel Ghinet sghinet at cloudbasesolutions.com
Tue Sep 30 14:54:35 UTC 2014


For this, 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.

This patch removes the field vportArray from OVS_SWITCH_CONTEXT.
In its place, portNoHashArray is set. In the OVS_VPORT_ENTRY
struct, we also add portNoLink. This new method will do lookup
and insertions of vports by ovs (datapath) port numbers the same
way it is done for hyper-v switch port ids.

This patch implicitly removes the indexes, which were previously
used in insertions and lookups on ovs port numbers. The removal
of the index also means that the vxlan vport can no longer be
looked up the same way as it was done before: now we hold a pointer
to it, vxlanVport in OVS_SWITCH_CONTEXT. For the moment, we can
have only one vxlan vport. When more will be allowed, this field
will turn into a list of vxlan ports.

The invalid port number value (held in OVS_DPPORT_NUMBER_INVALID)
is now changed from 0 to MAXUINT16, the same as it is on linux.

The function OvsComputeVportNo has also been removed, since the
computation of a vport port number can no longer be done like this.
When vport add will be added, a new, updated OvsComputeVportNo
function will be added.

Also, in OvsInitVportCommon, we no longer need to (and no longer can)
initialize vport->ovsName, nor vport->ovsNameLen, because they will
be initialized by the netlink command vport add. Since the netlink
command vport add will generate numbers for the datapath (ovs) port
numbers and set the port names, we cannot insert the vport into the
hash array of port numbers here, nor into the hash array of port names.

Signed-off-by: Samuel Ghinet <sghinet at cloudbasesolutions.com>
---
 datapath-windows/ovsext/Actions.c |  27 ++++--
 datapath-windows/ovsext/Switch.c  |  28 ++-----
 datapath-windows/ovsext/Switch.h  |  18 ++--
 datapath-windows/ovsext/Tunnel.c  |   2 +-
 datapath-windows/ovsext/Vport.c   | 169 ++++++++++----------------------------
 datapath-windows/ovsext/Vport.h   |  56 +++----------
 6 files changed, 94 insertions(+), 206 deletions(-)

diff --git a/datapath-windows/ovsext/Actions.c b/datapath-windows/ovsext/Actions.c
index 180b6b8..cf44140 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/Switch.c b/datapath-windows/ovsext/Switch.c
index ca95bdd..fbf5e80 100644
--- a/datapath-windows/ovsext/Switch.c
+++ b/datapath-windows/ovsext/Switch.c
@@ -354,8 +354,8 @@ 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->ovsPortNameHashArray = (PLIST_ENTRY)
          OvsAllocateMemory(sizeof (LIST_ENTRY) * OVS_MAX_VPORT_ARRAY_SIZE);
     switchContext->portIdHashArray = (PLIST_ENTRY)
@@ -367,14 +367,14 @@ OvsInitSwitchContext(POVS_SWITCH_CONTEXT switchContext)
     }
     if (status != NDIS_STATUS_SUCCESS ||
         switchContext->dispatchLock == NULL ||
-        switchContext->vportArray == NULL ||
+        switchContext->portNoHashArray == NULL ||
         switchContext->ovsPortNameHashArray == NULL ||
         switchContext->portIdHashArray == NULL) {
         if (switchContext->dispatchLock) {
             NdisFreeRWLock(switchContext->dispatchLock);
         }
-        if (switchContext->vportArray) {
-            OvsFreeMemory(switchContext->vportArray);
+        if (switchContext->portNoHashArray) {
+            OvsFreeMemory(switchContext->portNoHashArray);
         }
         if (switchContext->ovsPortNameHashArray) {
             OvsFreeMemory(switchContext->ovsPortNameHashArray);
@@ -395,13 +395,13 @@ OvsInitSwitchContext(POVS_SWITCH_CONTEXT switchContext)
     for (i = 0; i < OVS_MAX_VPORT_ARRAY_SIZE; i++) {
         InitializeListHead(&switchContext->portIdHashArray[i]);
     }
-    RtlZeroMemory(switchContext->vportArray,
-                  sizeof (PVOID) * OVS_MAX_VPORT_ARRAY_SIZE);
+    for (i = 0; i < OVS_MAX_VPORT_ARRAY_SIZE; i++) {
+        InitializeListHead(&switchContext->portNoHashArray[i]);
+    }
 
     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);
@@ -419,7 +419,7 @@ OvsCleanupSwitchContext(POVS_SWITCH_CONTEXT switchContext)
     NdisFreeRWLock(switchContext->dispatchLock);
     OvsFreeMemory(switchContext->ovsPortNameHashArray);
     OvsFreeMemory(switchContext->portIdHashArray);
-    OvsFreeMemory(switchContext->vportArray);
+    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 5cf65b9..83a725c 100644
--- a/datapath-windows/ovsext/Switch.h
+++ b/datapath-windows/ovsext/Switch.h
@@ -43,10 +43,6 @@
 #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
@@ -109,13 +105,18 @@ typedef struct _OVS_SWITCH_CONTEXT
     POVS_VPORT_ENTRY        externalVport;  // the virtual adapter vport
     POVS_VPORT_ENTRY        internalVport;
 
-    PVOID                  *vportArray;
-    PLIST_ENTRY             ovsPortNameHashArray;  // based on ovsName
-    PLIST_ENTRY             portIdHashArray;       // based on portId
+    /*
+     * XXX when we support multiple VXLAN ports, we will need a list entry
+     * instead
+    */
+    POVS_VPORT_ENTRY        vxlanVport;
+
+    PLIST_ENTRY             ovsPortNameHashArray;    // 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;
@@ -165,7 +166,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 28319a4..443e71e 100644
--- a/datapath-windows/ovsext/Vport.c
+++ b/datapath-windows/ovsext/Vport.c
@@ -211,7 +211,7 @@ HvOnCreateNic(POVS_SWITCH_CONTEXT switchContext,
 
 add_nic_done:
     NdisReleaseRWLock(switchContext->dispatchLock, &lockState);
-    if (portNo && event) {
+    if (portNo != OVS_DPPORT_NUMBER_INVALID && event) {
         OvsPostEvent(portNo, event);
     }
 
@@ -260,6 +260,7 @@ HvOnConnectNic(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) {
@@ -384,6 +385,7 @@ HvOnDisconnectNic(POVS_SWITCH_CONTEXT switchContext,
 
     NdisReleaseRWLock(switchContext->dispatchLock, &lockState);
 
+    /* XXX if portNo != INVALID or always? */
     OvsPostEvent(portNo, OVS_EVENT_LINK_DOWN);
 
     if (isInternalPort) {
@@ -432,6 +434,7 @@ HvOnDeleteNic(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:
@@ -446,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;
@@ -485,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 {
@@ -515,72 +508,6 @@ OvsFindVportByPortIdAndNicIndex(POVS_SWITCH_CONTEXT switchContext,
     }
 }
 
-UINT32
-OvsComputeVportNo(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)
 {
@@ -591,6 +518,12 @@ OvsAllocateVport(VOID)
     }
     RtlZeroMemory(vport, sizeof (OVS_VPORT_ENTRY));
     vport->ovsState = OVS_STATE_UNKNOWN;
+    vport->portNo = OVS_DPPORT_NUMBER_INVALID;
+
+    InitializeListHead(&vport->ovsNameLink);
+    InitializeListHead(&vport->portIdLink);
+    InitializeListHead(&vport->portNoLink);
+
     return vport;
 }
 
@@ -699,63 +632,45 @@ 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 = OvsComputeVportNo(switchContext, vport->nicIndex,
-            vport->ovsType, vport->portType == NdisSwitchPortTypeExternal);
-        if (vport->portNo == OVS_DPPORT_NUMBER_INVALID) {
-            return NDIS_STATUS_RESOURCES;
-        }
-        ASSERT(OVS_IS_VPORT_ENTRY_NULL(switchContext,
-            OVS_VPORT_INDEX(vport->portNo)));
 
-        switchContext->vportArray[OVS_VPORT_INDEX(vport->portNo)] = vport;
-    }
+    ASSERT(vport->portNo == OVS_DPPORT_NUMBER_INVALID);
+
     switch (vport->portType) {
     case NdisSwitchPortTypeExternal:
         if (vport->nicIndex == 0) {
             switchContext->externalPortId = vport->portId;
             switchContext->externalVport = vport;
-            RtlStringCbPrintfA(vport->ovsName, OVS_MAX_PORT_NAME_LENGTH - 1,
-                "external.virtualAdapter");
-        }
-        else {
+        } else {
             switchContext->numPhysicalNics++;
-            RtlStringCbPrintfA(vport->ovsName, OVS_MAX_PORT_NAME_LENGTH - 1,
-                "external.%lu", (UINT32)vport->nicIndex);
         }
         break;
     case NdisSwitchPortTypeInternal:
         switchContext->internalPortId = vport->portId;
         switchContext->internalVport = vport;
-        RtlStringCbPrintfA(vport->ovsName, OVS_MAX_PORT_NAME_LENGTH - 1,
-            "internal");
         break;
     case NdisSwitchPortTypeSynthetic:
-        RtlStringCbPrintfA(vport->ovsName, OVS_MAX_PORT_NAME_LENGTH - 1,
-            "vmNICSyn.%lx", vport->portNo);
         break;
     case NdisSwitchPortTypeEmulated:
-        RtlStringCbPrintfA(vport->ovsName, OVS_MAX_PORT_NAME_LENGTH - 1,
-            "vmNICEmu.%lx", vport->portNo);
         break;
     }
-    StringCbLengthA(vport->ovsName, OVS_MAX_PORT_NAME_LENGTH - 1, &len);
-    vport->ovsNameLen = (UINT32)len;
+
     if (vport->portType == NdisSwitchPortTypeExternal &&
         vport->nicIndex == 0) {
         return NDIS_STATUS_SUCCESS;
     }
-    hash = OvsJhashBytes(vport->ovsName, vport->ovsNameLen, OVS_HASH_BASIS);
-    InsertHeadList(&switchContext->ovsPortNameHashArray[hash & OVS_VPORT_MASK],
-        &vport->ovsNameLink);
+
+    /*
+     * NOTE: OvsJhashWords has portId as "1" word. This should be ok, even
+     * though sizeof(NDIS_SWITCH_PORT_ID) = 4, not 2, because the
+     * hyper-v switch seems to use only 2 bytes out of 4.
+    */
     hash = OvsJhashWords(&vport->portId, 1, OVS_HASH_BASIS);
     InsertHeadList(&switchContext->portIdHashArray[hash & OVS_VPORT_MASK],
         &vport->portIdLink);
+
     switchContext->numVports++;
     return NDIS_STATUS_SUCCESS;
 }
@@ -765,8 +680,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);
@@ -799,9 +712,7 @@ OvsRemoveAndDeleteVport(POVS_SWITCH_CONTEXT switchContext,
 
     RemoveEntryList(&vport->ovsNameLink);
     RemoveEntryList(&vport->portIdLink);
-    gen = (gen + 1) & 0xff;
-    switchContext->vportArray[OVS_VPORT_INDEX(vport->portNo)] =
-                     (PVOID)(UINT64)gen;
+    RemoveEntryList(&vport->portNoLink);
     switchContext->numVports--;
     OvsFreeMemory(vport);
 }
@@ -925,14 +836,18 @@ 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);
diff --git a/datapath-windows/ovsext/Vport.h b/datapath-windows/ovsext/Vport.h
index fce16e2..678c7c5 100644
--- a/datapath-windows/ovsext/Vport.h
+++ b/datapath-windows/ovsext/Vport.h
@@ -17,7 +17,18 @@
 #ifndef __VPORT_H_
 #define __VPORT_H_ 1
 
-#define OVS_DPPORT_NUMBER_INVALID 0
+#define OVS_MAX_DPPORTS             MAXUINT16
+#define OVS_DPPORT_NUMBER_INVALID   OVS_MAX_DPPORTS
+/*
+ * The local port (0) is a reserved port, that is not allowed to be be
+ * created by the netlink command vport add. On linux, this port is created
+ * at netlink command datapath new. However, on windows, we do not need to
+ * create it, and more, we shouldn't. The userspace attempts to create two
+ * internal vports, the LOCAL port (0) and the internal port (with any other
+ * port number). The non-LOCAL internal port is used in the userspace when it
+ * requests the internal port.
+*/
+#define OVS_DPPORT_LOCAL            0
 
 #include "Switch.h"
 
@@ -67,6 +78,7 @@ typedef struct _OVS_VPORT_FULL_STATS {
 typedef struct _OVS_VPORT_ENTRY {
     LIST_ENTRY             ovsNameLink;
     LIST_ENTRY             portIdLink;
+    LIST_ENTRY             portNoLink;
 
     OVS_VPORT_STATE        ovsState;
     OVS_VPORT_TYPE         ovsType;
@@ -99,9 +111,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);
@@ -148,49 +157,10 @@ 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()
 {
     return ((POVS_VPORT_ENTRY) OvsGetExternalVport())->mtu;
 }
 
-UINT32 OvsComputeVportNo(POVS_SWITCH_CONTEXT switchContext,
-                         UINT32 nicIndex,
-                         OVS_VPORT_TYPE ovsType,
-                         BOOLEAN isExternal);
-
 #endif /* __VPORT_H_ */
-- 
1.8.3.msysgit.0




More information about the dev mailing list