If the name of an internal or external NIC changes, we need to disconnect the NIC from OVS since the name is the key. In this change, we generate a link down event. It is as though we got a call to HvDisconnectNic() for the old name and got a HvConnectNic() for the new name.
Also, HvCreateNic() has been cleaned up to remove the code to look for existing vport. We won't have a vport now since we'd have deleted the vport in HvDeleteNic(). Signed-off-by: Nithin Raju <nit...@vmware.com> --- datapath-windows/ovsext/Vport.c | 100 ++++++++++++++++++++-------------------- datapath-windows/ovsext/Vport.h | 34 ++++++++++++-- 2 files changed, 80 insertions(+), 54 deletions(-) diff --git a/datapath-windows/ovsext/Vport.c b/datapath-windows/ovsext/Vport.c index ef21fca..a7576d3 100644 --- a/datapath-windows/ovsext/Vport.c +++ b/datapath-windows/ovsext/Vport.c @@ -327,9 +327,8 @@ HvCreateNic(POVS_SWITCH_CONTEXT switchContext, goto done; } - if (nicParam->NicType == NdisSwitchNicTypeInternal || - (nicParam->NicType == NdisSwitchNicTypeExternal && - nicParam->NicIndex != 0)) { + if (OvsIsInternalNIC(nicParam->NicType) || + OvsIsRealExternalNIC(nicParam->NicType, nicParam->NicIndex)) { GetNICAlias(&nicParam->NetCfgInstanceId, &portFriendlyName); } @@ -339,44 +338,22 @@ HvCreateNic(POVS_SWITCH_CONTEXT switchContext, * structure for each such NIC, and each NIC inherits a lot of properties * from the parent external port. */ - if (nicParam->NicType == NdisSwitchNicTypeExternal && - nicParam->NicIndex != 0) { + if (OvsIsRealExternalNIC(nicParam->NicType, nicParam->NicIndex)) { + NDIS_SWITCH_PORT_PARAMETERS portParam; POVS_VPORT_ENTRY virtExtVport = (POVS_VPORT_ENTRY)switchContext->virtualExternalVport; - vport = OvsFindVportByPortIdAndNicIndex(switchContext, - nicParam->PortId, - nicParam->NicIndex); - if (vport == NULL) { - NDIS_SWITCH_PORT_PARAMETERS portParam; - /* Find by interface name */ - WCHAR interfaceName[IF_MAX_STRING_SIZE] = { 0 }; - NET_LUID interfaceLuid = { 0 }; - size_t len = 0; - status = ConvertInterfaceGuidToLuid(&nicParam->NetCfgInstanceId, - &interfaceLuid); - if (status == STATUS_SUCCESS) { - status = ConvertInterfaceLuidToAlias(&interfaceLuid, - interfaceName, - IF_MAX_STRING_SIZE + 1); - if (status == STATUS_SUCCESS) { - RtlStringCbLengthW(interfaceName, - IF_MAX_STRING_SIZE, - &len); - vport = OvsFindVportByHvNameW(switchContext, - interfaceName, - len); - } - } - - OvsCopyPortParamsFromVport(virtExtVport, &portParam); - NdisReleaseRWLock(switchContext->dispatchLock, &lockState); - status = HvCreatePort(switchContext, &portParam, - nicParam->NicIndex); - NdisAcquireRWLockWrite(switchContext->dispatchLock, &lockState, 0); - if (status != NDIS_STATUS_SUCCESS) { - goto add_nic_done; - } + ASSERT(virtExtVport); + ASSERT(OvsFindVportByPortIdAndNicIndex(switchContext, + nicParam->PortId, + nicParam->NicIndex) == NULL); + OvsCopyPortParamsFromVport(virtExtVport, &portParam); + NdisReleaseRWLock(switchContext->dispatchLock, &lockState); + status = HvCreatePort(switchContext, &portParam, + nicParam->NicIndex); + NdisAcquireRWLockWrite(switchContext->dispatchLock, &lockState, 0); + if (status != NDIS_STATUS_SUCCESS) { + goto add_nic_done; } } @@ -390,9 +367,8 @@ HvCreateNic(POVS_SWITCH_CONTEXT switchContext, goto add_nic_done; } OvsInitVportWithNicParam(switchContext, vport, nicParam); - if (nicParam->NicType == NdisSwitchNicTypeInternal || - (nicParam->NicType == NdisSwitchNicTypeExternal && - nicParam->NicIndex != 0)) { + if (OvsIsInternalNIC(nicParam->NicType) || + OvsIsRealExternalNIC(nicParam->NicType, nicParam->NicIndex)) { RtlCopyMemory(&vport->portFriendlyName, &portFriendlyName, sizeof portFriendlyName); } @@ -470,6 +446,8 @@ HvUpdateNic(POVS_SWITCH_CONTEXT switchContext, LOCK_STATE_EX lockState; UINT32 event = 0; IF_COUNTED_STRING portFriendlyName = {0}; + BOOLEAN nameChanged = FALSE; + BOOLEAN aliasLookup = FALSE; VPORT_NIC_ENTER(nicParam); @@ -483,9 +461,9 @@ HvUpdateNic(POVS_SWITCH_CONTEXT switchContext, /* GetNICAlias() must be called outside of a lock. */ if (nicParam->NicType == NdisSwitchNicTypeInternal || - (nicParam->NicType == NdisSwitchNicTypeExternal && - nicParam->NicIndex != 0)) { + OvsIsRealExternalNIC(nicParam->NicType, nicParam->NicIndex)) { GetNICAlias(&nicParam->NetCfgInstanceId, &portFriendlyName); + aliasLookup = TRUE; } NdisAcquireRWLockWrite(switchContext->dispatchLock, &lockState, 0); @@ -502,8 +480,15 @@ HvUpdateNic(POVS_SWITCH_CONTEXT switchContext, case NdisSwitchNicTypeInternal: RtlCopyMemory(&vport->netCfgInstanceId, &nicParam->NetCfgInstanceId, sizeof (GUID)); - RtlCopyMemory(&vport->portFriendlyName, &portFriendlyName, - sizeof portFriendlyName); + if (aliasLookup) { + if (RtlCompareMemory(&vport->portFriendlyName, + &portFriendlyName, vport->portFriendlyName.Length) != + vport->portFriendlyName.Length) { + RtlCopyMemory(&vport->portFriendlyName, &portFriendlyName, + sizeof portFriendlyName); + nameChanged = TRUE; + } + } break; case NdisSwitchNicTypeSynthetic: case NdisSwitchNicTypeEmulated: @@ -536,6 +521,17 @@ HvUpdateNic(POVS_SWITCH_CONTEXT switchContext, } vport->numaNodeId = nicParam->NumaNodeId; + if (nameChanged) { + OVS_EVENT_ENTRY event; + event.portNo = vport->portNo; + event.ovsType = vport->ovsType; + event.upcallPid = vport->upcallPid; + RtlCopyMemory(&event.ovsName, &vport->ovsName, sizeof event.ovsName); + event.type = OVS_EVENT_LINK_DOWN; + OvsRemoveAndDeleteVport(NULL, switchContext, vport, FALSE, TRUE); + OvsPostEvent(&event); + } + NdisReleaseRWLock(switchContext->dispatchLock, &lockState); /* @@ -598,14 +594,15 @@ HvDisconnectNic(POVS_SWITCH_CONTEXT switchContext, RtlCopyMemory(&event.ovsName, &vport->ovsName, sizeof event.ovsName); event.type = OVS_EVENT_LINK_DOWN; - NdisReleaseRWLock(switchContext->dispatchLock, &lockState); - /* * Delete the port from the hash tables accessible to userspace. After this * point, userspace should not be able to access this port. */ - OvsRemoveAndDeleteVport(NULL, switchContext, vport, FALSE, TRUE); - OvsPostEvent(&event); + if (OvsIsRealExternalVport(vport)) { + OvsRemoveAndDeleteVport(NULL, switchContext, vport, FALSE, TRUE); + OvsPostEvent(&event); + } + NdisReleaseRWLock(switchContext->dispatchLock, &lockState); if (isInternalPort) { OvsInternalAdapterDown(); @@ -650,8 +647,8 @@ HvDeleteNic(POVS_SWITCH_CONTEXT switchContext, vport->nicState = NdisSwitchNicStateUnknown; vport->ovsState = OVS_STATE_PORT_CREATED; - if (vport->portType == NdisSwitchPortTypeExternal && - vport->nicIndex != 0) { + if (OvsIsRealExternalVport(vport)) { + /* This vport was created in HvCreateNic(). */ OvsRemoveAndDeleteVport(NULL, switchContext, vport, TRUE, FALSE); } @@ -926,6 +923,7 @@ OvsInitVportWithNicParam(POVS_SWITCH_CONTEXT switchContext, vport->mtu = nicParam->MTU; vport->nicState = nicParam->NicState; vport->nicIndex = nicParam->NicIndex; + vport->nicType = nicParam->NicType; vport->numaNodeId = nicParam->NumaNodeId; switch (vport->nicState) { diff --git a/datapath-windows/ovsext/Vport.h b/datapath-windows/ovsext/Vport.h index 0d56484..75ad898 100644 --- a/datapath-windows/ovsext/Vport.h +++ b/datapath-windows/ovsext/Vport.h @@ -95,6 +95,7 @@ typedef struct _OVS_VPORT_ENTRY { PVOID priv; NDIS_SWITCH_PORT_ID portId; NDIS_SWITCH_NIC_INDEX nicIndex; + NDIS_SWITCH_NIC_TYPE nicType; UINT16 numaNodeId; NDIS_SWITCH_PORT_STATE portState; NDIS_SWITCH_NIC_STATE nicState; @@ -194,14 +195,41 @@ OvsIsInternalVportType(OVS_VPORT_TYPE ovsType) } static __inline BOOLEAN +OvsIsVirtualExternalVport(POVS_VPORT_ENTRY vport) +{ + return vport->nicType == NdisSwitchNicTypeExternal && + vport->nicIndex == 0; +} + +static __inline BOOLEAN +OvsIsRealExternalVport(POVS_VPORT_ENTRY vport) +{ + return vport->nicType == NdisSwitchNicTypeExternal && + vport->nicIndex == 0; +} + +static __inline BOOLEAN OvsIsBridgeInternalVport(POVS_VPORT_ENTRY vport) { - if (vport->isBridgeInternal) { - ASSERT(vport->ovsType == OVS_VPORT_TYPE_INTERNAL); - } + ASSERT(vport->isBridgeInternal != TRUE || + vport->ovsType == OVS_VPORT_TYPE_INTERNAL); return vport->isBridgeInternal == TRUE; } +static __inline BOOLEAN +OvsIsInternalNIC(NDIS_SWITCH_NIC_TYPE nicType) +{ + return nicType == NdisSwitchNicTypeInternal; +} + +static __inline BOOLEAN +OvsIsRealExternalNIC(NDIS_SWITCH_NIC_TYPE nicType, + NDIS_SWITCH_NIC_INDEX nicIndex) +{ + return nicType == NdisSwitchNicTypeExternal && + nicIndex != 0; +} + NTSTATUS OvsRemoveAndDeleteVport(PVOID usrParamsCtx, POVS_SWITCH_CONTEXT switchContext, POVS_VPORT_ENTRY vport, -- 1.8.5.6 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev