NDIS 6.x LWF NetBufferList(s) question

I have a Light Weight Filter (LWF) that inspects packets on both the send and recv side. The driver has been around for quite a while, essentially problem free.

Recently while running performance tests on a broadcom netextreme card on a 1GB lan segment I came across an issue, I’m not sure if the issue is with the way I manipulate NET_BUFFER_LIST(s) or if it’s a problem with the broadcom nic/driver.

// The following works, obviously, its not doing anything except passing everything through.

FilterRecvNetBufferLists( NDIS_HANDLE Context, PNET_BUFFER_LIST NetBufferLists, NDIS_PORT_NUMBER Port, ULONG nBufferLists, ULONG Flags )
{
ptb_filter_t pFilter = (ptb_filter_t) Context;

NdisFIndicateReceiveNetBufferLists( pFilter->FilterHandle, NetBufferLists, Port, nBufferLists, Flags );
}

// The following doesn’t work, note I am splitting up multiple NetBufferLists into singletons so I can do inspection, etc…
// - so far this only seems reproducible of the broadcom nic
// – I do notice that the broadcomm is actually passing in NetBufferLists where nBufferLists > 1
// - System doesn’t crash, but nic goes offline,

FilterRecvNetBufferLists( NDIS_HANDLE Context, PNET_BUFFER_LIST NetBufferLists, NDIS_PORT_NUMBER Port, ULONG nBufferLists, ULONG Flags )
{
ptb_filter_t pFilter = (ptb_filter_t) Context;
PNET_BUFFER_LIST currNbl = NULL;
PNET_BUFFER_LIST nextNbl = NULL;

for( currNbl=NetBufferLists; currNbl; currNbl=nextNbl ) {
nextNbl = NET_BUFFER_LIST_NEXT_NBL( currNbl );
NET_BUFFER_LIST_NEXT_NBL( currNbl ) = NULL;

NdisFIndicateReceiveNetBufferLists( pFilter->FilterHandle, currNbl, Port, 1, Flags );
}
}

Can anybody answer if the method of breaking up NetBufferLists with multiple members into Singletons is valid, especially on the Recv side.

Thanks in Advance

On 14-Dec-2011 21:21, xxxxx@gmail.com wrote:

NET_BUFFER_LIST_NEXT_NBL( currNbl ) = NULL;

Here you modify the NBL passed to you. Instead, create your own NBL with
one NB and use it for indication, and leave the data passed to you intact.
– pa

The problem occurs when a receive indication has the NDIS_RECEIVE_FLAGS_RESOURCES flag. Although you can unlink an NBL chain, you need to restore the chain to its original arrangement if the NDIS_RECEIVE_FLAGS_RESOURCES flag is set.

(If the flag is not set, then you are free to return the NBLs in any order, in any number of chains, and optionally combined with NBLs from other receive indications too.)

This particular rule is documented on http://msdn.microsoft.com/library/ff570448(v=vs.85).aspx :

"
Note If the NDIS_RECEIVE_FLAGS_RESOURCES flag is set, the filter driver must retain the original set of NET_BUFFER_LIST structures in the linked list. For example, when this flag is set, the driver might process the structures and indicate them up the stack one at a time but before the function returns, it must restore the original linked list.
"

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@gmail.com
Sent: Wednesday, December 14, 2011 11:21 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] NDIS 6.x LWF NetBufferList(s) question

I have a Light Weight Filter (LWF) that inspects packets on both the send and recv side. The driver has been around for quite a while, essentially problem free.

Recently while running performance tests on a broadcom netextreme card on a 1GB lan segment I came across an issue, I’m not sure if the issue is with the way I manipulate NET_BUFFER_LIST(s) or if it’s a problem with the broadcom nic/driver.

// The following works, obviously, its not doing anything except passing everything through.

FilterRecvNetBufferLists( NDIS_HANDLE Context, PNET_BUFFER_LIST NetBufferLists, NDIS_PORT_NUMBER Port, ULONG nBufferLists, ULONG Flags ) {
ptb_filter_t pFilter = (ptb_filter_t) Context;

NdisFIndicateReceiveNetBufferLists( pFilter->FilterHandle, NetBufferLists, Port, nBufferLists, Flags ); }

// The following doesn’t work, note I am splitting up multiple NetBufferLists into singletons so I can do inspection, etc…
// - so far this only seems reproducible of the broadcom nic // – I do notice that the broadcomm is actually passing in NetBufferLists where nBufferLists > 1 // - System doesn’t crash, but nic goes offline,

FilterRecvNetBufferLists( NDIS_HANDLE Context, PNET_BUFFER_LIST NetBufferLists, NDIS_PORT_NUMBER Port, ULONG nBufferLists, ULONG Flags ) {
ptb_filter_t pFilter = (ptb_filter_t) Context;
PNET_BUFFER_LIST currNbl = NULL;
PNET_BUFFER_LIST nextNbl = NULL;

for( currNbl=NetBufferLists; currNbl; currNbl=nextNbl ) {
nextNbl = NET_BUFFER_LIST_NEXT_NBL( currNbl );
NET_BUFFER_LIST_NEXT_NBL( currNbl ) = NULL;

NdisFIndicateReceiveNetBufferLists( pFilter->FilterHandle, currNbl, Port, 1, Flags );
}
}

Can anybody answer if the method of breaking up NetBufferLists with multiple members into Singletons is valid, especially on the Recv side.

Thanks in Advance


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer