Windows System Software -- Consulting, Training, Development -- Unique Expertise, Guaranteed Results

Home NTDEV

More Info on Driver Writing and Debugging


The free OSR Learning Library has more than 50 articles on a wide variety of topics about writing and debugging device drivers and Minifilters. From introductory level to advanced. All the articles have been recently reviewed and updated, and are written using the clear and definitive style you've come to expect from OSR over the years.


Check out The OSR Learning Library at: https://www.osr.com/osr-learning-library/


Before Posting...

Please check out the Community Guidelines in the Announcements and Administration Category.

LWF driver - reusing NET_BUFFER_LIST structures for sending

Daniel_BujnikDaniel_Bujnik Member Posts: 4
Hello,

I have LWF driver, which is creating and sending down its own packets using preallocated NET_BUFFER_LIST structures. My implementation is working fine on Windows 7,
however on Windows 10 I am observing increase in non-paged pool size. Poolmon points to netio.sys, so probably there must be something wrong in the way I do preallocate and reuse NBLs.

Could you please have a look below and point out what I am doing wrong?

Here is the way I allocate the pool:

NdisZeroMemory(&PoolParameters, sizeof(NET_BUFFER_LIST_POOL_PARAMETERS));

PoolParameters.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
PoolParameters.Header.Revision = NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1;
PoolParameters.Header.Size = sizeof(PoolParameters);
PoolParameters.ProtocolId = NDIS_PROTOCOL_ID_DEFAULT ;
PoolParameters.ContextSize = CONTEXT_BUFFER_SIZE(sizeof(NBL_MYFILTER_CONTEXT));
PoolParameters.fAllocateNetBuffer = TRUE;
PoolParameters.PoolTag = 'ooPF';


pFilter->SendNetBufferListPool = NdisAllocateNetBufferListPool(pFilter->FilterHandle, &PoolParameters);


Here is how I allocate single NBL:

NdisAllocateMemoryWithTag(&pDataBuffer, 1530, NBL_DATA_TAG);

pMdl = NdisAllocateMdl(pFilter->FilterHandle, pDataBuffer, DataLength);

pNetBufList = NdisAllocateNetBufferAndNetBufferList(
pFilter->SendNetBufferListPool,
CONTEXT_BUFFER_SIZE(sizeof(NBL_MYFILTER_CONTEXT)), // ContextSize
0, // ContextBackfill
pMdl, // MdlChain
0, // DataOffset
1530); // DataLength

CircularQueuePush (pFilter->sendPrealocatedNBLqueue, pNetBufList)


Here is the way I send the packet:

pNetBufList = (PNET_BUFFER_LIST) CircularQueuePop (pFilter->sendPrealocatedNBLqueue);

NET_BUFFER_DATA_LENGTH(NET_BUFFER_LIST_FIRST_NB(pNetBufList)) = uPacketSize;

pMdl = NET_BUFFER_FIRST_MDL(NET_BUFFER_LIST_FIRST_NB(pNetBufList));

NdisQueryMdl(pMdl, &pCopyBuf, &CurrLength, NormalPagePriority);

pNetBufList->SourceHandle = pFilter->FilterHandle;

NdisMoveMemory(pCopyBuf, pHeaderBuffer, uHeaderBufferSize );
NdisMoveMemory(pCopyBuf+uHeaderBufferSize, pLookaheadBuffer, uLookaheadBufferSize);

NET_BUFFER_LIST_NEXT_NBL (pNetBufList) = NULL; // last element of the list
NET_BUFFER_LIST_INFO(pNetBufList, NetBufferListFrameType) = (PVOID)NDIS_PROTOCOL_ID_TCP_IP;

if ( KeGetCurrentIrql() == DISPATCH_LEVEL )
uSendFlags = NDIS_SEND_FLAGS_DISPATCH_LEVEL;
else uSendFlags = 0;

NdisFSendNetBufferLists(pFilter->FilterHandle, pNetBufList, NDIS_DEFAULT_PORT_NUMBER, uSendFlags);

Finally in send-complete callback I simply return my NBL into the queue:

CurrNbl = NetBufferLists;
while (CurrNbl)
{
tempNbl = CurrNbl;

CurrNbl = NET_BUFFER_LIST_NEXT_NBL(CurrNbl);

// unchain this nbl
NET_BUFFER_LIST_NEXT_NBL(tempNbl) = NULL;

result = CircularQueuePush (pFilter->sendPrealocatedNBLqueue, tempNbl);
}


Many thanks in advance.

Kind regards,
Daniel

Comments

  • Daniel_BujnikDaniel_Bujnik Member Posts: 4
    Update:

    I have checked my NBL received in send-complete callback and it looks that memory, which is leaking comes from NET_BUFFER_LIST_INFO.WfpNetBufferListInfo. Have a look below:

    NonPaged Paged
    Tag Allocs Frees Diff Used Allocs Frees Diff Used

    Wfpn 13169 0 13169 8426432 0 0 0 0 WFP NBL info container , Binary: netio.sys

    1: kd> !ndiskd.nbl ffffcf819bd0a910 -info

    NET_BUFFER_LIST_INFO

    TcpIpChecksumNetBufferListInfo 0
    TcpOffloadBytesTransferred 0
    IPsecOffloadV1NetBufferListInfo 0
    IPsecOffloadV2NetBufferListInfo 0
    TcpLargeSendNetBufferListInfo 0
    TcpReceiveNoPush 0
    ClassificationHandleNetBufferListInfo NULL
    Ieee8021QNetBufferListInfo 0
    NetBufferListCancelId NULL
    MediaSpecificInformation 0
    NetBufferListFrameType NDIS_PROTOCOL_ID_TCP_IP
    NetBufferListHashValue 0
    NetBufferListHashInfo 0
    WfpNetBufferListInfo ffffe00019128d90
    IPsecOffloadV2TunnelNetBufferListInfo 0
    IPsecOffloadV2HeaderNetBufferListInfo 0
    NetBufferListCorrelationId NULL
    NetBufferListFilteringInfo 0
    MediaSpecificInformationEx NULL
    NblOriginalInterfaceIfIndex 0
    NblReAuthWfpFlowContext NULL
    TcpReceiveBytesTransferred 0
    TcpRecvSegCoalesceInfo 0
    RscTcpTimestampDelta 0
    TcpSendOffloadsSupplementalNetBufferListInfo 0
    IMReserved NULL
    SwitchForwardingReserved NULL
    SwitchForwardingDetail NULL
    VirtualSubnetInfo 0
    NblCurrentOwner 00000018


    Is there any way I could release WfpNetBufferListInfo without calling NdisFreeNetBufferList on my NBL?

    Many thanks,
    Daniel
  • Larry_ClawsonLarry_Clawson Member Posts: 191
    What version of Win 10? The early versions of Win 10 have NDIS problems.

    Larry C
  • Daniel_BujnikDaniel_Bujnik Member Posts: 4
    I am running Windows 10 version 1511 (OS Build 10586.164).
  • Daniel_BujnikDaniel_Bujnik Member Posts: 4
    Ideas anyone?
Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. Sign in or register to get started.

Upcoming OSR Seminars
OSR has suspended in-person seminars due to the Covid-19 outbreak. But, don't miss your training! Attend via the internet instead!
Writing WDF Drivers 24 January 2022 Live, Online
Internals & Software Drivers 7 February 2022 Live, Online
Kernel Debugging 21 March 2022 Live, Online
Developing Minifilters 23 May 2022 Live, Online