diff mbox

[ovs-dev] datapath-windows: Fix HvUpdateNic() to handle name changes

Message ID 1447373526-10482-1-git-send-email-nithin@vmware.com
State Not Applicable
Headers show

Commit Message

Nithin Raju Nov. 13, 2015, 12:12 a.m. UTC
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 <nithin@vmware.com>
---
 datapath-windows/ovsext/Vport.c | 83 +++++++++++++++++++++--------------------
 1 file changed, 42 insertions(+), 41 deletions(-)
diff mbox

Patch

diff --git a/datapath-windows/ovsext/Vport.c b/datapath-windows/ovsext/Vport.c
index 37d5e59..a80ab00 100644
--- a/datapath-windows/ovsext/Vport.c
+++ b/datapath-windows/ovsext/Vport.c
@@ -341,42 +341,21 @@  HvCreateNic(POVS_SWITCH_CONTEXT switchContext,
      */
     if (nicParam->NicType == NdisSwitchNicTypeExternal &&
         nicParam->NicIndex != 0) {
+        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;
         }
     }
 
@@ -470,6 +449,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);
 
@@ -486,6 +467,7 @@  HvUpdateNic(POVS_SWITCH_CONTEXT switchContext,
         (nicParam->NicType == NdisSwitchNicTypeExternal &&
          nicParam->NicIndex != 0)) {
         GetNICAlias(&nicParam->NetCfgInstanceId, &portFriendlyName);
+        aliasLookup = TRUE;
     }
 
     NdisAcquireRWLockWrite(switchContext->dispatchLock, &lockState, 0);
@@ -498,14 +480,20 @@  HvUpdateNic(POVS_SWITCH_CONTEXT switchContext,
         goto update_nic_done;
     }
     switch (nicParam->NicType) {
+    case NdisSwitchNicTypeExternal:
     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:
         if (!RtlEqualMemory(vport->vmMacAddress, nicParam->VMMacAddress,
@@ -537,6 +525,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);
 
     /*
@@ -599,14 +598,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 (vport != switchContext->virtualExternalVport) {
+        OvsRemoveAndDeleteVport(NULL, switchContext, vport, FALSE, TRUE);
+        OvsPostEvent(&event);
+    }
+    NdisReleaseRWLock(switchContext->dispatchLock, &lockState);
 
     if (isInternalPort) {
         OvsInternalAdapterDown();
@@ -653,6 +653,7 @@  HvDeleteNic(POVS_SWITCH_CONTEXT switchContext,
 
     if (vport->portType == NdisSwitchPortTypeExternal &&
         vport->nicIndex != 0) {
+        /* This vport was created in HvCreateNic(). */
         OvsRemoveAndDeleteVport(NULL, switchContext, vport, TRUE, FALSE);
     }