Signed-off-by: Sorin Vinturis <svintu...@cloudbasesolutions.com> --- datapath-windows/ovsext/Switch.c | 144 +++++++++++++++++++++------------------ 1 file changed, 76 insertions(+), 68 deletions(-)
diff --git a/datapath-windows/ovsext/Switch.c b/datapath-windows/ovsext/Switch.c index f176fa0..7ea8c68 100644 --- a/datapath-windows/ovsext/Switch.c +++ b/datapath-windows/ovsext/Switch.c @@ -35,7 +35,6 @@ #include "Debug.h" POVS_SWITCH_CONTEXT gOvsSwitchContext; -LONG volatile gOvsInAttach; UINT64 ovsTimeIncrementPerTick; extern NDIS_HANDLE gOvsExtDriverHandle; @@ -50,7 +49,8 @@ volatile LONG gOvsSwitchContextRefCount = 0; static NDIS_STATUS OvsCreateSwitch(NDIS_HANDLE ndisFilterHandle, POVS_SWITCH_CONTEXT *switchContextOut); -static NDIS_STATUS OvsInitSwitchContext(POVS_SWITCH_CONTEXT switchContext); +static NDIS_STATUS OvsInitSwitchContext(NDIS_HANDLE ndisFilterHandle); +static POVS_SWITCH_CONTEXT OvsAllocateSwitchContext(NDIS_HANDLE ndisFilterHandle); static VOID OvsDeleteSwitch(POVS_SWITCH_CONTEXT switchContext); static VOID OvsUninitSwitchContext(POVS_SWITCH_CONTEXT switchContext); static NDIS_STATUS OvsActivateSwitch(POVS_SWITCH_CONTEXT switchContext); @@ -71,7 +71,6 @@ OvsExtAttach(NDIS_HANDLE ndisFilterHandle, { NDIS_STATUS status = NDIS_STATUS_FAILURE; NDIS_FILTER_ATTRIBUTES ovsExtAttributes; - POVS_SWITCH_CONTEXT switchContext = NULL; UNREFERENCED_PARAMETER(filterDriverContext); @@ -89,31 +88,18 @@ OvsExtAttach(NDIS_HANDLE ndisFilterHandle, goto cleanup; } - if (gOvsSwitchContext) { - OVS_LOG_TRACE("Exit: Failed to create OVS Switch, only one datapath is" - "supported, %p.", gOvsSwitchContext); - goto cleanup; - } - - if (InterlockedCompareExchange(&gOvsInAttach, 1, 0)) { - /* Just fail the request. */ - OVS_LOG_TRACE("Exit: Failed to create OVS Switch, since another attach" - "instance is in attach process."); - goto cleanup; - } - - 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; + if (gOvsSwitchContext == NULL) { + status = OvsInitSwitchContext(ndisFilterHandle); + if (status != NDIS_STATUS_SUCCESS) { + OVS_LOG_ERROR("Exit: Failed to initialize switch context."); + goto cleanup; + } + } else { + if (!OvsAcquireSwitchContext()) { + status = STATUS_DEVICE_NOT_READY; + goto cleanup; + } } - ASSERT(switchContext); /* * Register the switch context with NDIS so NDIS can pass it back to the @@ -126,26 +112,17 @@ OvsExtAttach(NDIS_HANDLE ndisFilterHandle, ovsExtAttributes.Flags = 0; NDIS_DECLARE_FILTER_MODULE_CONTEXT(OVS_SWITCH_CONTEXT); - status = NdisFSetAttributes(ndisFilterHandle, switchContext, &ovsExtAttributes); + status = NdisFSetAttributes(ndisFilterHandle, gOvsSwitchContext, &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; - - gOvsSwitchContextRefCount = 1; - gOvsSwitchContext = switchContext; - KeMemoryBarrier(); - cleanup: - gOvsInAttach = FALSE; if (status != NDIS_STATUS_SUCCESS) { - if (switchContext != NULL) { - OvsDeleteSwitch(switchContext); + if (gOvsSwitchContext != NULL) { + OvsDeleteSwitch(gOvsSwitchContext); } } OVS_LOG_TRACE("Exit: status %x", status); @@ -154,6 +131,30 @@ cleanup: } +NDIS_STATUS +OvsInitSwitchContext(NDIS_HANDLE ndisFilterHandle) +{ + NDIS_STATUS status = STATUS_SUCCESS; + + OvsAcquireCtrlLock(TRUE); + if (gOvsSwitchContext == NULL) { + status = OvsCreateSwitch(ndisFilterHandle, &gOvsSwitchContext); + ASSERT(gOvsSwitchContext); + + if (gOvsSwitchContext) { + /* Setup the state machine. */ + gOvsSwitchContext->controlFlowState = OvsSwitchAttached; + gOvsSwitchContext->dataFlowState = OvsSwitchPaused; + } + + gOvsSwitchContextRefCount = 1; + } + OvsReleaseCtrlLock(); + + return status; +} + + /* * -------------------------------------------------------------------------- * This function allocated the switch context, and initializes its necessary @@ -171,13 +172,24 @@ OvsCreateSwitch(NDIS_HANDLE ndisFilterHandle, OVS_LOG_TRACE("Enter: Create switch object"); - switchContext = (POVS_SWITCH_CONTEXT) OvsAllocateMemoryWithTag( - sizeof(OVS_SWITCH_CONTEXT), OVS_SWITCH_POOL_TAG); + switchContext = OvsAllocateSwitchContext(ndisFilterHandle); if (switchContext == NULL) { - status = NDIS_STATUS_RESOURCES; + OVS_LOG_ERROR("Exit: Failed to allocate switch context."); + status = NDIS_STATUS_RESOURCES; + goto exit; + } + + status = OvsInitIpHelper(ndisFilterHandle); + if (status != NDIS_STATUS_SUCCESS) { + OVS_LOG_ERROR("Exit: Failed to initialize IP helper."); + goto create_switch_done; + } + + status = OvsInitTunnelFilter(gOvsExtDriverObject, gOvsDeviceObject); + if (status != NDIS_STATUS_SUCCESS) { + OVS_LOG_ERROR("Exit: Failed to initialize tunnel filter."); goto create_switch_done; } - RtlZeroMemory(switchContext, sizeof(OVS_SWITCH_CONTEXT)); /* Initialize the switch. */ hostSwitchHandler.Header.Type = NDIS_OBJECT_TYPE_SWITCH_OPTIONAL_HANDLERS; @@ -199,22 +211,14 @@ OvsCreateSwitch(NDIS_HANDLE ndisFilterHandle, RtlCopyMemory(&switchContext->NdisSwitchHandlers, &hostSwitchHandler, sizeof(NDIS_SWITCH_OPTIONAL_HANDLERS)); - status = OvsInitSwitchContext(switchContext); - if (status != NDIS_STATUS_SUCCESS) { - OvsFreeMemoryWithTag(switchContext, OVS_SWITCH_POOL_TAG); - switchContext = NULL; - goto create_switch_done; - } + *switchContextOut = switchContext; - status = OvsInitTunnelFilter(gOvsExtDriverObject, gOvsDeviceObject); +create_switch_done: if (status != NDIS_STATUS_SUCCESS) { - OvsUninitSwitchContext(switchContext); - goto create_switch_done; + OvsDeleteSwitch(switchContext); } - *switchContextOut = switchContext; - -create_switch_done: +exit: OVS_LOG_TRACE("Exit: switchContext: %p status: %#lx", switchContext, status); return status; @@ -349,16 +353,20 @@ OvsExtPause(NDIS_HANDLE filterModuleContext, return NDIS_STATUS_SUCCESS; } -static NDIS_STATUS -OvsInitSwitchContext(POVS_SWITCH_CONTEXT switchContext) +static POVS_SWITCH_CONTEXT +OvsAllocateSwitchContext(NDIS_HANDLE ndisFilterHandle) { - int i; + POVS_SWITCH_CONTEXT switchContext = NULL; NTSTATUS status; - OVS_LOG_TRACE("Enter: switchContext: %p", switchContext); + switchContext = (POVS_SWITCH_CONTEXT)OvsAllocateMemoryWithTag( + sizeof(OVS_SWITCH_CONTEXT), OVS_SWITCH_POOL_TAG); + if (switchContext == NULL) { + return switchContext; + } + RtlZeroMemory(switchContext, sizeof(OVS_SWITCH_CONTEXT)); - switchContext->dispatchLock = - NdisAllocateRWLock(switchContext->NdisFilterHandle); + switchContext->dispatchLock = NdisAllocateRWLock(ndisFilterHandle); switchContext->portNoHashArray = (PLIST_ENTRY)OvsAllocateMemoryWithTag( sizeof(LIST_ENTRY) * OVS_MAX_VPORT_ARRAY_SIZE, OVS_SWITCH_POOL_TAG); @@ -409,18 +417,20 @@ OvsInitSwitchContext(POVS_SWITCH_CONTEXT switchContext) OvsDeleteFlowTable(&switchContext->datapath); OvsCleanupBufferPool(switchContext); - OVS_LOG_TRACE("Exit: Failed to init switchContext"); - return NDIS_STATUS_RESOURCES; + OvsFreeMemoryWithTag(switchContext, OVS_SWITCH_POOL_TAG); + switchContext = NULL; + + return switchContext; } - for (i = 0; i < OVS_MAX_VPORT_ARRAY_SIZE; i++) { + for (int i = 0; i < OVS_MAX_VPORT_ARRAY_SIZE; i++) { InitializeListHead(&switchContext->ovsPortNameHashArray[i]); InitializeListHead(&switchContext->portIdHashArray[i]); InitializeListHead(&switchContext->portNoHashArray[i]); InitializeListHead(&switchContext->tunnelVportsArray[i]); } - for (i = 0; i < OVS_MAX_PID_ARRAY_SIZE; i++) { + for (int i = 0; i < OVS_MAX_PID_ARRAY_SIZE; i++) { InitializeListHead(&switchContext->pidHashArray[i]); } @@ -430,9 +440,7 @@ OvsInitSwitchContext(POVS_SWITCH_CONTEXT switchContext) switchContext->dpNo = OVS_DP_NUMBER; ovsTimeIncrementPerTick = KeQueryTimeIncrement() / 10000; - OVS_LOG_TRACE("Exit: Succesfully initialized switchContext: %p", - switchContext); - return NDIS_STATUS_SUCCESS; + return switchContext; } static VOID -- 1.9.0.msysgit.0 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev