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