/* * -------------------------------------------------------------------------- * Implements filter driver's FilterDetach function. * -------------------------------------------------------------------------- */ _Use_decl_annotations_ VOID OvsExtDetach(NDIS_HANDLE filterModuleContext) { POVS_SWITCH_CONTEXT switchContext = (POVS_SWITCH_CONTEXT)filterModuleContext; OVS_LOG_TRACE("Enter: filterModuleContext %p", filterModuleContext); ASSERT(switchContext->dataFlowState == OvsSwitchPaused); switchContext->controlFlowState = OvsSwitchDetached; KeMemoryBarrier(); while(switchContext->pendingOidCount > 0) { NdisMSleep(1000); } OvsDeleteSwitch(switchContext); OvsCleanupIpHelper(); /* This completes the cleanup, and a new attach can be handled now. */ OVS_LOG_TRACE("Exit: OvsDetach Successfully"); }
/* * -------------------------------------------------------------------------- * Implements filter driver's FilterAttach function. * * This function allocates the switch context, and initializes its necessary * members. * -------------------------------------------------------------------------- */ NDIS_STATUS OvsExtAttach(NDIS_HANDLE ndisFilterHandle, NDIS_HANDLE filterDriverContext, PNDIS_FILTER_ATTACH_PARAMETERS attachParameters) { NDIS_STATUS status = NDIS_STATUS_FAILURE; NDIS_FILTER_ATTRIBUTES ovsExtAttributes; POVS_SWITCH_CONTEXT switchContext = NULL; UNREFERENCED_PARAMETER(filterDriverContext); OVS_LOG_TRACE("Enter: ndisFilterHandle %p", ndisFilterHandle); ASSERT(filterDriverContext == (NDIS_HANDLE)gOvsExtDriverObject); if (attachParameters->MiniportMediaType != NdisMedium802_3) { status = NDIS_STATUS_INVALID_PARAMETER; goto cleanup; } if (gOvsExtDriverHandle == NULL) { OVS_LOG_TRACE("Exit: OVSEXT driver is not loaded."); ASSERT(FALSE); goto cleanup; } NdisAcquireSpinLock(gOvsCtrlLock); if (gOvsSwitchContext) { NdisReleaseSpinLock(gOvsCtrlLock); OVS_LOG_TRACE("Exit: Failed to create OVS Switch, only one datapath is" "supported, %p.", gOvsSwitchContext); goto cleanup; } if (gOvsInAttach) { NdisReleaseSpinLock(gOvsCtrlLock); /* Just fail the request. */ OVS_LOG_TRACE("Exit: Failed to create OVS Switch, since another attach" "instance is in attach process."); goto cleanup; } gOvsInAttach = TRUE; NdisReleaseSpinLock(gOvsCtrlLock); status = OvsInitIpHelper(ndisFilterHandle); if (status != STATUS_SUCCESS) { OVS_LOG_ERROR("Exit: Failed to initialize IP helper."); goto cleanup; } status = OvsCreateSwitch(ndisFilterHandle, &switchContext); if (status != NDIS_STATUS_SUCCESS) { OvsCleanupIpHelper(); goto cleanup; } ASSERT(switchContext); /* * Register the switch context with NDIS so NDIS can pass it back to the * Filterxxx callback functions as the 'FilterModuleContext' parameter. */ RtlZeroMemory(&ovsExtAttributes, sizeof(NDIS_FILTER_ATTRIBUTES)); ovsExtAttributes.Header.Revision = NDIS_FILTER_ATTRIBUTES_REVISION_1; ovsExtAttributes.Header.Size = sizeof(NDIS_FILTER_ATTRIBUTES); ovsExtAttributes.Header.Type = NDIS_OBJECT_TYPE_FILTER_ATTRIBUTES; ovsExtAttributes.Flags = 0; NDIS_DECLARE_FILTER_MODULE_CONTEXT(OVS_SWITCH_CONTEXT); status = NdisFSetAttributes(ndisFilterHandle, switchContext, &ovsExtAttributes); if (status != NDIS_STATUS_SUCCESS) { OVS_LOG_ERROR("Failed to set attributes."); OvsCleanupIpHelper(); goto cleanup; } /* Setup the state machine. */ switchContext->controlFlowState = OvsSwitchAttached; switchContext->dataFlowState = OvsSwitchPaused; gOvsSwitchContext = switchContext; KeMemoryBarrier(); cleanup: gOvsInAttach = FALSE; if (status != NDIS_STATUS_SUCCESS) { if (switchContext != NULL) { OvsDeleteSwitch(switchContext); } } OVS_LOG_TRACE("Exit: status %x", status); return status; }