@@ -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
Signed-off-by: Sorin Vinturis <svinturis@cloudbasesolutions.com> --- datapath-windows/ovsext/Switch.c | 144 +++++++++++++++++++++------------------ 1 file changed, 76 insertions(+), 68 deletions(-)