datapath-windows: Avoid BSOD when cleaning up a tunnel vport
[cascardo/ovs.git] / datapath-windows / ovsext / Vport.c
index a276212..59cf651 100644 (file)
@@ -129,7 +129,7 @@ HvCreatePort(POVS_SWITCH_CONTEXT switchContext,
     vport = OvsFindVportByHvNameW(gOvsSwitchContext,
                                   portParam->PortFriendlyName.String,
                                   portParam->PortFriendlyName.Length);
-    if (vport && vport->isPresentOnHv == FALSE) {
+    if (vport && vport->isAbsentOnHv == FALSE) {
         OVS_LOG_ERROR("Port add failed since a port already exists on "
                       "the specified port Id: %u, ovsName: %s",
                       portParam->PortId, vport->ovsName);
@@ -138,7 +138,7 @@ HvCreatePort(POVS_SWITCH_CONTEXT switchContext,
     }
 
     if (vport != NULL) {
-        ASSERT(vport->isPresentOnHv);
+        ASSERT(vport->isAbsentOnHv);
         ASSERT(vport->portNo != OVS_DPPORT_NUMBER_INVALID);
 
         /*
@@ -153,7 +153,7 @@ HvCreatePort(POVS_SWITCH_CONTEXT switchContext,
             status = STATUS_DATA_NOT_ACCEPTED;
             goto create_port_done;
         }
-        vport->isPresentOnHv = FALSE;
+        vport->isAbsentOnHv = FALSE;
     } else {
         vport = (POVS_VPORT_ENTRY)OvsAllocateVport();
         if (vport == NULL) {
@@ -759,7 +759,7 @@ OvsAllocateVport(VOID)
     }
     RtlZeroMemory(vport, sizeof (OVS_VPORT_ENTRY));
     vport->ovsState = OVS_STATE_UNKNOWN;
-    vport->isPresentOnHv = FALSE;
+    vport->isAbsentOnHv = FALSE;
     vport->portNo = OVS_DPPORT_NUMBER_INVALID;
 
     InitializeListHead(&vport->ovsNameLink);
@@ -920,7 +920,8 @@ OvsInitTunnelVport(PVOID userContext,
     {
         POVS_TUNFLT_INIT_CONTEXT tunnelContext = NULL;
 
-        tunnelContext = OvsAllocateMemory(sizeof(*tunnelContext));
+        tunnelContext = OvsAllocateMemoryWithTag(sizeof(*tunnelContext),
+                                                 OVS_VPORT_POOL_TAG);
         if (tunnelContext == NULL) {
             status = STATUS_INSUFFICIENT_RESOURCES;
             break;
@@ -935,6 +936,10 @@ OvsInitTunnelVport(PVOID userContext,
                                     dstPort,
                                     OvsTunnelVportPendingInit,
                                     (PVOID)tunnelContext);
+        if (status != STATUS_PENDING) {
+            OvsFreeMemoryWithTag(tunnelContext, OVS_VPORT_POOL_TAG);
+            tunnelContext = NULL;
+        }
         break;
     }
     case OVS_VPORT_TYPE_STT:
@@ -1152,7 +1157,7 @@ OvsRemoveAndDeleteVport(PVOID usrParamsContext,
     switch (vport->ovsType) {
     case OVS_VPORT_TYPE_INTERNAL:
         if (!vport->isBridgeInternal) {
-            if (hvDelete && vport->isPresentOnHv == FALSE) {
+            if (hvDelete && vport->isAbsentOnHv == FALSE) {
                 switchContext->internalPortId = 0;
                 switchContext->internalVport = NULL;
                 OvsInternalAdapterDown();
@@ -1200,7 +1205,7 @@ OvsRemoveAndDeleteVport(PVOID usrParamsContext,
      *
      * Both 'hvDelete' and 'ovsDelete' can be set to TRUE by the caller.
      */
-    if (vport->isPresentOnHv == TRUE) {
+    if (vport->isAbsentOnHv == TRUE) {
         deletedOnHv = TRUE;
     }
     if (vport->portNo == OVS_DPPORT_NUMBER_INVALID) {
@@ -1208,7 +1213,7 @@ OvsRemoveAndDeleteVport(PVOID usrParamsContext,
     }
 
     if (hvDelete && !deletedOnHv) {
-        vport->isPresentOnHv = TRUE;
+        vport->isAbsentOnHv = TRUE;
 
         if (vport->isExternal) {
             ASSERT(vport->nicIndex != 0);
@@ -1447,7 +1452,7 @@ OvsClearAllSwitchVports(POVS_SWITCH_CONTEXT switchContext)
             vport = CONTAINING_RECORD(link, OVS_VPORT_ENTRY, portNoLink);
             ASSERT(OvsIsTunnelVportType(vport->ovsType) ||
                    (vport->ovsType == OVS_VPORT_TYPE_INTERNAL &&
-                    vport->isBridgeInternal) || vport->isPresentOnHv == TRUE);
+                    vport->isBridgeInternal) || vport->isAbsentOnHv == TRUE);
             OvsRemoveAndDeleteVport(NULL, switchContext, vport, TRUE, TRUE);
         }
     }
@@ -2198,7 +2203,7 @@ OvsNewVportCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx,
              * Allow the vport to be deleted, because there is no
              * corresponding hyper-v switch part.
              */
-            vport->isPresentOnHv = TRUE;
+            vport->isAbsentOnHv = TRUE;
         } else {
             goto Cleanup;
         }
@@ -2523,7 +2528,7 @@ OvsTunnelVportPendingRemove(PVOID context,
         }
     }
 
-    ASSERT(vport->isPresentOnHv == TRUE);
+    ASSERT(vport->isAbsentOnHv == TRUE);
     ASSERT(vport->portNo != OVS_DPPORT_NUMBER_INVALID);
 
     /* Remove the port from the relevant lists. */
@@ -2531,6 +2536,12 @@ OvsTunnelVportPendingRemove(PVOID context,
     RemoveEntryList(&vport->ovsNameLink);
     RemoveEntryList(&vport->portNoLink);
     RemoveEntryList(&vport->tunnelVportLink);
+
+    if (vport->priv) {
+        OvsFreeMemoryWithTag(vport->priv, OVS_VXLAN_POOL_TAG);
+        vport->priv = NULL;
+    }
+
     OvsFreeMemoryWithTag(vport, OVS_VPORT_POOL_TAG);
 
     NdisReleaseRWLock(switchContext->dispatchLock, &lockState);
@@ -2600,7 +2611,7 @@ OvsTunnelVportPendingInit(PVOID context,
          * Allow the vport to be deleted, because there is no
          * corresponding hyper-v switch part.
          */
-        vport->isPresentOnHv = TRUE;
+        vport->isAbsentOnHv = TRUE;
 
         if (vportAttrs[OVS_VPORT_ATTR_PORT_NO] != NULL) {
             /*