Exemple #1
0
/*
 * --------------------------------------------------------------------------
 *  This function allocated the switch context, and initializes its necessary
 *  members.
 * --------------------------------------------------------------------------
 */
NDIS_STATUS
OvsCreateSwitch(NDIS_HANDLE ndisFilterHandle,
                POVS_SWITCH_CONTEXT *switchContextOut)
{
    NDIS_STATUS status;
    POVS_SWITCH_CONTEXT switchContext;
    NDIS_SWITCH_CONTEXT hostSwitchContext;
    NDIS_SWITCH_OPTIONAL_HANDLERS hostSwitchHandler;

    OVS_LOG_TRACE("Enter: Create switch object");

    switchContext = (POVS_SWITCH_CONTEXT) OvsAllocateMemoryWithTag(
        sizeof(OVS_SWITCH_CONTEXT), OVS_SWITCH_POOL_TAG);
    if (switchContext == NULL) {
        status = NDIS_STATUS_RESOURCES;
        goto create_switch_done;
    }
    RtlZeroMemory(switchContext, sizeof(OVS_SWITCH_CONTEXT));

    /* Initialize the switch. */
    hostSwitchHandler.Header.Type = NDIS_OBJECT_TYPE_SWITCH_OPTIONAL_HANDLERS;
    hostSwitchHandler.Header.Size = NDIS_SIZEOF_SWITCH_OPTIONAL_HANDLERS_REVISION_1;
    hostSwitchHandler.Header.Revision = NDIS_SWITCH_OPTIONAL_HANDLERS_REVISION_1;

    status = NdisFGetOptionalSwitchHandlers(ndisFilterHandle,
                                            &hostSwitchContext,
                                            &hostSwitchHandler);
    if (status != NDIS_STATUS_SUCCESS) {
        OVS_LOG_ERROR("OvsExtAttach: Extension is running in "
                      "non-switch environment.");
        OvsFreeMemoryWithTag(switchContext, OVS_SWITCH_POOL_TAG);
        goto create_switch_done;
    }

    switchContext->NdisFilterHandle = ndisFilterHandle;
    switchContext->NdisSwitchContext = hostSwitchContext;
    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;
    }

    status = OvsInitTunnelFilter(gOvsExtDriverObject, gOvsDeviceObject);
    if (status != NDIS_STATUS_SUCCESS) {
        OvsUninitSwitchContext(switchContext);
        goto create_switch_done;
    }

    *switchContextOut = switchContext;

create_switch_done:
    OVS_LOG_TRACE("Exit: switchContext: %p status: %#lx",
                  switchContext, status);
    return status;
}
//
// FilterAttach Function
// http://msdn.microsoft.com/en-us/library/ff549905(v=VS.85).aspx
//
_Use_decl_annotations_
NDIS_STATUS
SxNdisAttach(
    NDIS_HANDLE NdisFilterHandle,
    NDIS_HANDLE SxDriverContext,
    PNDIS_FILTER_ATTACH_PARAMETERS AttachParameters
    )
{
    NDIS_STATUS status;
    NDIS_FILTER_ATTRIBUTES sxAttributes;
    ULONG switchObjectSize;
    NDIS_SWITCH_CONTEXT switchContext;
    NDIS_SWITCH_OPTIONAL_HANDLERS switchHandler;
    PSX_SWITCH_OBJECT switchObject;
    
    UNREFERENCED_PARAMETER(SxDriverContext);

    DEBUGP(DL_TRACE, ("===>SxAttach: NdisFilterHandle %p\n", NdisFilterHandle));

    status = NDIS_STATUS_SUCCESS;
    switchObject = NULL;

    NT_ASSERT(SxDriverContext == (NDIS_HANDLE)SxDriverObject);

    if (AttachParameters->MiniportMediaType != NdisMedium802_3)
    {
        status = NDIS_STATUS_INVALID_PARAMETER;
        goto Cleanup;
    }

    switchHandler.Header.Type = NDIS_OBJECT_TYPE_SWITCH_OPTIONAL_HANDLERS;
    switchHandler.Header.Size = NDIS_SIZEOF_SWITCH_OPTIONAL_HANDLERS_REVISION_1;
    switchHandler.Header.Revision = NDIS_SWITCH_OPTIONAL_HANDLERS_REVISION_1;

    status = NdisFGetOptionalSwitchHandlers(NdisFilterHandle,
                                            &switchContext,
                                            &switchHandler);

    if (status != NDIS_STATUS_SUCCESS)
    {
        DEBUGP(DL_ERROR,
               ("SxAttach: Extension is running in non-switch environment.\n"));
        goto Cleanup;
    }

    switchObjectSize = sizeof(SX_SWITCH_OBJECT);
    switchObject = ExAllocatePoolWithTag(NonPagedPoolNx,
                                         switchObjectSize,
                                         SxExtAllocationTag);

    if (switchObject == NULL)
    {
        status = NDIS_STATUS_RESOURCES;
        goto Cleanup;
    }

    RtlZeroMemory(switchObject, switchObjectSize);

    //
    // Initialize NDIS related information.
    //
    switchObject->NdisFilterHandle = NdisFilterHandle;
    switchObject->NdisSwitchContext = switchContext;
    RtlCopyMemory(&switchObject->NdisSwitchHandlers,
                  &switchHandler,
                  sizeof(NDIS_SWITCH_OPTIONAL_HANDLERS));

    //
    // Let the extension create its own context.
    //
    status = SxExtCreateSwitch(switchObject,
                               &(switchObject->ExtensionContext));

    if (status != NDIS_STATUS_SUCCESS)
    {
        goto Cleanup;
    }

    //
    // Register the object with NDIS because NDIS passes this object when it
    // calls into the driver.
    //
    NdisZeroMemory(&sxAttributes, sizeof(NDIS_FILTER_ATTRIBUTES));
    sxAttributes.Header.Revision = NDIS_FILTER_ATTRIBUTES_REVISION_1;
    sxAttributes.Header.Size = sizeof(NDIS_FILTER_ATTRIBUTES);
    sxAttributes.Header.Type = NDIS_OBJECT_TYPE_FILTER_ATTRIBUTES;
    sxAttributes.Flags = 0;

    NDIS_DECLARE_FILTER_MODULE_CONTEXT(SX_SWITCH_OBJECT);
    status = NdisFSetAttributes(NdisFilterHandle, switchObject, &sxAttributes);

    if (status != NDIS_STATUS_SUCCESS)
    {
        DEBUGP(DL_ERROR, ("SxBase: Failed to set attributes.\n"));
        goto Cleanup;
    }

    switchObject->ControlFlowState = SxSwitchAttached;
    switchObject->DataFlowState = SxSwitchPaused;
    
    NdisAcquireSpinLock(&SxExtensionListLock);
    InsertHeadList(&SxExtensionList, &switchObject->Link);
    NdisReleaseSpinLock(&SxExtensionListLock);
    
Cleanup:

    if (status != NDIS_STATUS_SUCCESS)
    {
        if (switchObject != NULL)
        {
            ExFreePool(switchObject);
        }
    }

    DEBUGP(DL_TRACE, ("<===SxAttach: status %x\n", status));

    return status;
}