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