Exemplo n.º 1
0
/*
 * --------------------------------------------------------------------------
 * Creates the communication device between user and kernel, and also
 * initializes the data associated data structures.
 * --------------------------------------------------------------------------
 */
NDIS_STATUS
OvsCreateDeviceObject(NDIS_HANDLE ovsExtDriverHandle)
{
    NDIS_STATUS status = NDIS_STATUS_SUCCESS;
    UNICODE_STRING deviceName;
    UNICODE_STRING symbolicDeviceName;
    PDRIVER_DISPATCH dispatchTable[IRP_MJ_MAXIMUM_FUNCTION+1];
    NDIS_DEVICE_OBJECT_ATTRIBUTES deviceAttributes;
    OVS_LOG_TRACE("ovsExtDriverHandle: %p", ovsExtDriverHandle);

    RtlZeroMemory(dispatchTable,
                  (IRP_MJ_MAXIMUM_FUNCTION + 1) * sizeof (PDRIVER_DISPATCH));
    dispatchTable[IRP_MJ_CREATE] = OvsOpenCloseDevice;
    dispatchTable[IRP_MJ_CLOSE] = OvsOpenCloseDevice;
    dispatchTable[IRP_MJ_CLEANUP] = OvsCleanupDevice;
    dispatchTable[IRP_MJ_DEVICE_CONTROL] = OvsDeviceControl;

    NdisInitUnicodeString(&deviceName, OVS_DEVICE_NAME_NT);
    NdisInitUnicodeString(&symbolicDeviceName, OVS_DEVICE_NAME_DOS);

    RtlZeroMemory(&deviceAttributes, sizeof (NDIS_DEVICE_OBJECT_ATTRIBUTES));

    OVS_INIT_OBJECT_HEADER(&deviceAttributes.Header,
                           NDIS_OBJECT_TYPE_DEVICE_OBJECT_ATTRIBUTES,
                           NDIS_DEVICE_OBJECT_ATTRIBUTES_REVISION_1,
                           sizeof (NDIS_DEVICE_OBJECT_ATTRIBUTES));

    deviceAttributes.DeviceName = &deviceName;
    deviceAttributes.SymbolicName = &symbolicDeviceName;
    deviceAttributes.MajorFunctions = dispatchTable;
    deviceAttributes.ExtensionSize = sizeof (OVS_DEVICE_EXTENSION);

    status = NdisRegisterDeviceEx(ovsExtDriverHandle,
                                  &deviceAttributes,
                                  &gOvsDeviceObject,
                                  &gOvsDeviceHandle);
    if (status != NDIS_STATUS_SUCCESS) {
        POVS_DEVICE_EXTENSION ovsExt =
            (POVS_DEVICE_EXTENSION)NdisGetDeviceReservedExtension(gOvsDeviceObject);
        ASSERT(gOvsDeviceObject != NULL);
        ASSERT(gOvsDeviceHandle != NULL);

        if (ovsExt) {
            ovsExt->numberOpenInstance = 0;
        }
    } else {
        /* Initialize the associated data structures. */
        OvsInit();
    }
    OVS_LOG_TRACE("DeviceObject: %p", gOvsDeviceObject);
    return status;
}
Exemplo n.º 2
0
/*
 * --------------------------------------------------------------------------
 * OvsInitBufferPool --
 *
 *    Allocate NBL and NB pool
 *
 * XXX: more optimization may be done for buffer management include local cache
 * of NBL, NB, data, context, MDL.
 * --------------------------------------------------------------------------
 */
NDIS_STATUS
OvsInitBufferPool(PVOID ovsContext)
{
    POVS_NBL_POOL ovsPool;
    POVS_SWITCH_CONTEXT context = (POVS_SWITCH_CONTEXT)ovsContext;
    NET_BUFFER_LIST_POOL_PARAMETERS  nblParam;
    NET_BUFFER_POOL_PARAMETERS nbParam;

    C_ASSERT(MEMORY_ALLOCATION_ALIGNMENT >= 8);

    OVS_LOG_TRACE("Enter: context: %p", context);

    ovsPool = &context->ovsPool;
    RtlZeroMemory(ovsPool, sizeof (OVS_NBL_POOL));
    ovsPool->ndisHandle = context->NdisFilterHandle;
    ovsPool->ndisContext = context->NdisSwitchContext;
    /*
     * fix size NBL pool includes
     *    NBL + NB + MDL + DATA + Context
     *    This is mainly used for Packet execute or slow path when copy is
     *    required and size is less than OVS_DEFAULT_DATA_SIZE. We expect
     *    Most of packet from user space will use this Pool. (This is
     *    true for all bfd and cfm packet.
     */
    RtlZeroMemory(&nblParam, sizeof (nblParam));
    OVS_INIT_OBJECT_HEADER(&nblParam.Header,
                           NDIS_OBJECT_TYPE_DEFAULT,
                           NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1,
                           NDIS_SIZEOF_NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1);
    nblParam.ContextSize = OVS_DEFAULT_NBL_CONTEXT_SIZE;
    nblParam.PoolTag = OVS_FIX_SIZE_NBL_POOL_TAG;
    nblParam.fAllocateNetBuffer = TRUE;
    nblParam.DataSize = OVS_DEFAULT_DATA_SIZE + OVS_DEFAULT_HEADROOM_SIZE;

    ovsPool->fixSizePool =
        NdisAllocateNetBufferListPool(context->NdisSwitchContext, &nblParam);
    if (ovsPool->fixSizePool == NULL) {
        goto pool_cleanup;
    }

    /*
     * Zero Size NBL Pool includes
     *    NBL + NB + Context
     *    This is mainly for packet with large data Size, in this case MDL and
     *    Data will be allocate separately.
     */
    RtlZeroMemory(&nblParam, sizeof (nblParam));
    OVS_INIT_OBJECT_HEADER(&nblParam.Header,
                           NDIS_OBJECT_TYPE_DEFAULT,
                           NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1,
                           NDIS_SIZEOF_NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1);

    nblParam.ContextSize = OVS_DEFAULT_NBL_CONTEXT_SIZE;
    nblParam.PoolTag = OVS_VARIABLE_SIZE_NBL_POOL_TAG;
    nblParam.fAllocateNetBuffer = TRUE;
    nblParam.DataSize = 0;

    ovsPool->zeroSizePool =
        NdisAllocateNetBufferListPool(context->NdisSwitchContext, &nblParam);
    if (ovsPool->zeroSizePool == NULL) {
        goto pool_cleanup;
    }

    /*
     * NBL only pool just includes
     *    NBL (+ context)
     *    This is mainly used for clone and partial copy
     */
    RtlZeroMemory(&nblParam, sizeof (nblParam));
    OVS_INIT_OBJECT_HEADER(&nblParam.Header,
                           NDIS_OBJECT_TYPE_DEFAULT,
                           NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1,
                           NDIS_SIZEOF_NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1);

    nblParam.ContextSize = OVS_DEFAULT_NBL_CONTEXT_SIZE;
    nblParam.PoolTag = OVS_NBL_ONLY_POOL_TAG;
    nblParam.fAllocateNetBuffer = FALSE;
    nblParam.DataSize = 0;

    ovsPool->nblOnlyPool =
        NdisAllocateNetBufferListPool(context->NdisSwitchContext, &nblParam);
    if (ovsPool->nblOnlyPool == NULL) {
        goto pool_cleanup;
    }

    /* nb Pool
     *    NB only pool, used for copy
     */

    OVS_INIT_OBJECT_HEADER(&nbParam.Header,
                           NDIS_OBJECT_TYPE_DEFAULT,
                           NET_BUFFER_POOL_PARAMETERS_REVISION_1,
                           NDIS_SIZEOF_NET_BUFFER_POOL_PARAMETERS_REVISION_1);
    nbParam.PoolTag = OVS_NET_BUFFER_POOL_TAG;
    nbParam.DataSize = 0;
    ovsPool->nbPool =
        NdisAllocateNetBufferPool(context->NdisSwitchContext, &nbParam);
    if (ovsPool->nbPool == NULL) {
        goto pool_cleanup;
    }
    OVS_LOG_TRACE("Exit: fixSizePool: %p zeroSizePool: %p nblOnlyPool: %p"
                  "nbPool: %p", ovsPool->fixSizePool, ovsPool->zeroSizePool,
                  ovsPool->nblOnlyPool, ovsPool->nbPool);
    return NDIS_STATUS_SUCCESS;

pool_cleanup:
    OvsCleanupBufferPool(context);
    OVS_LOG_TRACE("Exit: Fail to initialize ovs buffer pool");
    return NDIS_STATUS_RESOURCES;
}