From 25e39a6047f19b84612bfa8bb28b573c7a3f02bc Mon Sep 17 00:00:00 2001 From: Nithin Raju Date: Thu, 23 Oct 2014 17:33:09 -0700 Subject: [PATCH] datapath-windows: Clarify externalVport. In this patch, we add some explanation about the usage of 'externalVport' in the switch context. Also, we rename 'externalVport' to 'virtualExternalVport' in alignment with the explanation. Also, we rename 'numVports' to 'numHvVports' since ports are added from 2 ends now. Signed-off-by: Nithin Raju Acked-by: Alin Gabriel Serdean Tested-by: Alin Gabriel Serdean Acked-by: Ankur Sharma Signed-off-by: Ben Pfaff --- datapath-windows/ovsext/Actions.c | 2 +- datapath-windows/ovsext/Datapath.c | 8 ++--- datapath-windows/ovsext/PacketIO.c | 4 +-- datapath-windows/ovsext/Switch.c | 4 +-- datapath-windows/ovsext/Switch.h | 52 ++++++++++++++++++++++++------ datapath-windows/ovsext/Vport.c | 24 +++++++------- 6 files changed, 64 insertions(+), 30 deletions(-) diff --git a/datapath-windows/ovsext/Actions.c b/datapath-windows/ovsext/Actions.c index f5ce12e90..3f8c35159 100644 --- a/datapath-windows/ovsext/Actions.c +++ b/datapath-windows/ovsext/Actions.c @@ -249,7 +249,7 @@ OvsDetectTunnelPkt(OvsForwardingContext *ovsFwdCtx, * default port. */ BOOLEAN validSrcPort = (ovsFwdCtx->fwdDetail->SourcePortId == - ovsFwdCtx->switchContext->externalPortId) || + ovsFwdCtx->switchContext->virtualExternalPortId) || (ovsFwdCtx->fwdDetail->SourcePortId == NDIS_SWITCH_DEFAULT_PORT_ID); diff --git a/datapath-windows/ovsext/Datapath.c b/datapath-windows/ovsext/Datapath.c index 17f2e3a13..55b19a089 100644 --- a/datapath-windows/ovsext/Datapath.c +++ b/datapath-windows/ovsext/Datapath.c @@ -1513,7 +1513,7 @@ OvsGetVportDumpNext(POVS_USER_PARAMS_CONTEXT usrParamsCtx, NdisAcquireRWLockRead(gOvsSwitchContext->dispatchLock, &lockState, NDIS_RWL_AT_DISPATCH_LEVEL); - if (gOvsSwitchContext->numVports > 0) { + if (gOvsSwitchContext->numHvVports > 0) { /* inBucket: the bucket, used for lookup */ UINT32 inBucket = instance->dumpState.index[0]; /* inIndex: index within the given bucket, used for lookup */ @@ -1802,7 +1802,7 @@ OvsNewVportCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx, vport = gOvsSwitchContext->internalVport; } else if (portType == OVS_VPORT_TYPE_NETDEV) { if (!strcmp(portName, "external")) { - vport = gOvsSwitchContext->externalVport; + vport = gOvsSwitchContext->virtualExternalVport; } else { vport = OvsFindVportByHvName(gOvsSwitchContext, portName); } @@ -1885,8 +1885,8 @@ OvsNewVportCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx, gOvsSwitchContext->internalPortId = vport->portId; } else if (vport->ovsType == OVS_VPORT_TYPE_NETDEV && vport->isExternal) { - gOvsSwitchContext->externalVport = vport; - gOvsSwitchContext->externalPortId = vport->portId; + gOvsSwitchContext->virtualExternalVport = vport; + gOvsSwitchContext->virtualExternalPortId = vport->portId; } /* diff --git a/datapath-windows/ovsext/PacketIO.c b/datapath-windows/ovsext/PacketIO.c index 7eb6ed837..027b42a06 100644 --- a/datapath-windows/ovsext/PacketIO.c +++ b/datapath-windows/ovsext/PacketIO.c @@ -236,7 +236,7 @@ OvsStartNBLIngress(POVS_SWITCH_CONTEXT switchContext, dispatch); ctx = OvsInitExternalNBLContext(switchContext, curNbl, - sourcePort == switchContext->externalPortId); + sourcePort == switchContext->virtualExternalPortId); if (ctx == NULL) { RtlInitUnicodeString(&filterReason, L"Cannot allocate external NBL context."); @@ -291,7 +291,7 @@ OvsStartNBLIngress(POVS_SWITCH_CONTEXT switchContext, portNo, &key, curNbl, sourcePort == - switchContext->externalPortId, + switchContext->virtualExternalPortId, &layers, switchContext, &missedPackets, &num); if (status == NDIS_STATUS_SUCCESS) { diff --git a/datapath-windows/ovsext/Switch.c b/datapath-windows/ovsext/Switch.c index 020300cb6..a540926e8 100644 --- a/datapath-windows/ovsext/Switch.c +++ b/datapath-windows/ovsext/Switch.c @@ -432,7 +432,7 @@ OvsUninitSwitchContext(POVS_SWITCH_CONTEXT switchContext) OVS_LOG_TRACE("Enter: Delete switchContext:%p", switchContext); /* We need to do cleanup for tunnel port here. */ - ASSERT(switchContext->numVports == 0); + ASSERT(switchContext->numHvVports == 0); NdisFreeRWLock(switchContext->dispatchLock); switchContext->dispatchLock = NULL; @@ -496,7 +496,7 @@ cleanup: PVOID OvsGetExternalVport() { - return gOvsSwitchContext->externalVport; + return gOvsSwitchContext->virtualExternalVport; } diff --git a/datapath-windows/ovsext/Switch.h b/datapath-windows/ovsext/Switch.h index b61462b43..11d9df623 100644 --- a/datapath-windows/ovsext/Switch.h +++ b/datapath-windows/ovsext/Switch.h @@ -95,26 +95,60 @@ typedef struct _OVS_SWITCH_CONTEXT UINT32 dpNo; - NDIS_SWITCH_PORT_ID externalPortId; + /* + * 'virtualExternalVport' represents default external interface. This is + * a virtual interface. The friendly name of such an interface has + * been observed to be: "Microsoft Default External Interface". This NIC + * has 'NicIndex' == 0. + * + * The "real" physical external NIC has 'NicIndex' > 0. For each + * external interface, virtual or physical, NDIS gives an NIC level + * OID callback. Note that, even though there are multile "NICs", + * there's only one underlying Hyper-V port. Thus, we get a single + * NDIS port-level callback, but multiple NDIS NIC-level callbacks. + * + * The virtual external NIC can be accessed at 'virtualExternalVport', and + * is assigned the name "external.defaultAdapter". The virtual external + * NIC is not inserted into the 'portIdHashArray' since the port must not + * be exposed to OVS userspace. + * + * The physical external NICs are assigned names "external.%INDEX%", + * where '%INDEX%' represents the 'NicIndex' of the NIC. + * + * While adding a physical external NIC in OvsInitConfiguredSwitchNics(), + * some required properties of the vport are available only at the + * NDIS port-level. So, these are copied from 'virtualExternalVport'. + * The vport created for the physical external NIC is inserted into the + * 'portIdHashArray'. + * + * When the virtual external NIC is torn down or deleted, the + * corresponding physical external ports are also torn down or + * deleted. The number of physical external NICs is tracked by + * 'numPhysicalNics'. + */ + NDIS_SWITCH_PORT_ID virtualExternalPortId; NDIS_SWITCH_PORT_ID internalPortId; - POVS_VPORT_ENTRY externalVport; // the virtual adapter vport + POVS_VPORT_ENTRY virtualExternalVport; // 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; PLIST_ENTRY ovsPortNameHashArray; // based on ovsName - PLIST_ENTRY portIdHashArray; // based on portId + PLIST_ENTRY portIdHashArray; // based on Hyper-V portId PLIST_ENTRY portNoHashArray; // based on ovs port number PLIST_ENTRY pidHashArray; // based on packet pids NDIS_SPIN_LOCK pidHashLock; // Lock for pidHash table + /* + * 'numPhysicalNics' is the number of physical external NICs. + * 'numHvVports' is the number of Hyper-V switch ports added to OVS + * via the NDIS callbacks. + * 'numNonHvVports' is the number of ports added from userspace that are + * not on the Hyper-V switch. Eg. tunnel ports. + */ UINT32 numPhysicalNics; - UINT32 numVports; // include validation port - UINT32 lastPortIndex; + UINT32 numHvVports; + UINT32 numNonHvVports; /* Lock taken over the switch. This protects the ports on the switch. */ PNDIS_RW_LOCK_EX dispatchLock; diff --git a/datapath-windows/ovsext/Vport.c b/datapath-windows/ovsext/Vport.c index 0522cfdbd..3fd40f71a 100644 --- a/datapath-windows/ovsext/Vport.c +++ b/datapath-windows/ovsext/Vport.c @@ -204,7 +204,7 @@ HvCreateNic(POVS_SWITCH_CONTEXT switchContext, if (nicParam->NicType == NdisSwitchNicTypeExternal && nicParam->NicIndex != 0) { POVS_VPORT_ENTRY virtVport = - (POVS_VPORT_ENTRY)switchContext->externalVport; + (POVS_VPORT_ENTRY)switchContext->virtualExternalVport; vport = (POVS_VPORT_ENTRY)OvsAllocateVport(); if (vport == NULL) { status = NDIS_STATUS_RESOURCES; @@ -553,8 +553,8 @@ OvsFindVportByPortIdAndNicIndex(POVS_SWITCH_CONTEXT switchContext, NDIS_SWITCH_PORT_ID portId, NDIS_SWITCH_NIC_INDEX index) { - if (portId == switchContext->externalPortId) { - return (POVS_VPORT_ENTRY)switchContext->externalVport; + if (portId == switchContext->virtualExternalPortId) { + return (POVS_VPORT_ENTRY)switchContext->virtualExternalVport; } else if (switchContext->internalPortId == portId) { return (POVS_VPORT_ENTRY)switchContext->internalVport; } else { @@ -716,8 +716,8 @@ OvsInitVportCommon(POVS_SWITCH_CONTEXT switchContext, switch (vport->portType) { case NdisSwitchPortTypeExternal: if (vport->nicIndex == 0) { - switchContext->externalPortId = vport->portId; - switchContext->externalVport = vport; + switchContext->virtualExternalPortId = vport->portId; + switchContext->virtualExternalVport = vport; RtlStringCbPrintfA(vport->ovsName, OVS_MAX_PORT_NAME_LENGTH - 1, "external.virtualAdapter"); } else { @@ -749,7 +749,7 @@ OvsInitVportCommon(POVS_SWITCH_CONTEXT switchContext, hash = OvsJhashWords(&vport->portId, 1, OVS_HASH_BASIS); InsertHeadList(&switchContext->portIdHashArray[hash & OVS_VPORT_MASK], &vport->portIdLink); - switchContext->numVports++; + switchContext->numHvVports++; return NDIS_STATUS_SUCCESS; } @@ -760,8 +760,8 @@ OvsRemoveAndDeleteVport(POVS_SWITCH_CONTEXT switchContext, if (vport->isExternal) { if (vport->nicIndex == 0) { ASSERT(switchContext->numPhysicalNics == 0); - switchContext->externalPortId = 0; - switchContext->externalVport = NULL; + switchContext->virtualExternalPortId = 0; + switchContext->virtualExternalVport = NULL; OvsFreeMemory(vport); return; } else { @@ -790,7 +790,7 @@ OvsRemoveAndDeleteVport(POVS_SWITCH_CONTEXT switchContext, RemoveEntryList(&vport->ovsNameLink); RemoveEntryList(&vport->portIdLink); RemoveEntryList(&vport->portNoLink); - switchContext->numVports--; + switchContext->numHvVports--; OvsFreeMemory(vport); } @@ -877,7 +877,7 @@ OvsInitConfiguredSwitchNics(POVS_SWITCH_CONTEXT switchContext) if (nicParam->NicType == NdisSwitchNicTypeExternal && nicParam->NicIndex != 0) { POVS_VPORT_ENTRY virtVport = - (POVS_VPORT_ENTRY)switchContext->externalVport; + (POVS_VPORT_ENTRY)switchContext->virtualExternalVport; vport = OvsAllocateVport(); if (vport) { OvsInitPhysNicVport(vport, virtVport, nicParam->NicIndex); @@ -924,9 +924,9 @@ OvsClearAllSwitchVports(POVS_SWITCH_CONTEXT switchContext) } } - if (switchContext->externalVport) { + if (switchContext->virtualExternalVport) { OvsRemoveAndDeleteVport(switchContext, - (POVS_VPORT_ENTRY)switchContext->externalVport); + (POVS_VPORT_ENTRY)switchContext->virtualExternalVport); } } -- 2.20.1