NDIS LWF: is restoring the original NET_BUFFER_LIST chain mandatory when NDIS_RECEIVE_FLAGS_RESOURCES is set?

박승용 (Seungyong Park) 0 Reputation points
2026-09-21T08:40:17.68+00:00

We maintain an NDIS lightweight filter that inspects an image stream carried over

UDP. In FilterReceiveNetBufferLists the filter splits the indicated chain into two

lists: the NBLs it consumes itself, and the remaining NBLs, which it passes up with

NdisFIndicateReceiveNetBufferLists. On calls where NDIS_RECEIVE_FLAGS_RESOURCES was

set, the filter returned without restoring the original chain.

On one setup (Intel I350, MS switch team) the miniport sets the RESOURCES flag on a

large share of indications. In that case the miniport reclaimed only the NBLs it

could still reach from the head it had handed over; the NBLs on the detached branch

were never reclaimed. Unreclaimed receive buffers accumulated over hours until the

port stopped receiving, and only a reboot restored it. We have measured this: the

counter of unreachable NBLs stopped at 2,033 against a configured 2,048 receive

buffers, at exactly the moment the port went silent. Restoring the chain before

returning removes the problem.

Questions:

  1. Is the requirement to restore the original linked list before returning, when NDIS_RECEIVE_FLAGS_RESOURCES is set, normative for filter drivers? The statement appears in "Receiving Data in a Filter Driver", but the FILTER_RECEIVE_NET_BUFFER_LISTS reference page does not repeat it.
  2. If a filter must pass only part of the chain upward on a RESOURCES indication, what is the sanctioned pattern? Restore the original chain before returning, or copy the data out and indicate a locally allocated NBL instead?
  3. The ndislwf sample does not contain any chain-restore handling. Is that because the sample never modifies the chain, or is the obligation considered out of scope for the sample?
  4. Is there a recommended way for a filter to self-check this at runtime or under Driver Verifier? NdisTimedDataHang covers the send path, and we found no receive-path rule that flags unreclaimed NBLs.

Environment: Windows 11 24H2, NDIS 6.8x filter, Intel I350 and X550 adapters.

Windows development | Windows Driver Kit (WDK)
0 comments No comments

1 answer

Sort by: Newest
  1. AI answer

    2026-09-21T08:40:40.5066667+00:00
    1. Yes. For filter drivers, when NDIS_RECEIVE_FLAGS_RESOURCES is set on FilterReceiveNetBufferLists, restoring the original NET_BUFFER_LIST linked list before returning is a documented requirement.

    The filter-driver documentation states that when this flag is set, the filter driver cannot keep the NET_BUFFER_LIST structures and underlying driver-allocated resources, should return as quickly as possible, and must retain the original set of NET_BUFFER_LIST structures in the linked list. It explicitly gives the case where a driver processes or indicates them one at a time, but before the function returns, it must restore the original linked list.

    1. The sanctioned patterns supported by the documentation are:
    • If NDIS_RECEIVE_FLAGS_RESOURCES is set and only part of the traffic is to be passed upward, process or indicate as needed, but restore the original linked list before returning.
    • If the filter needs to keep data for later processing, copy the data into filter-driver-allocated storage before returning.
    • The filter can also copy the buffer and originate a receive indication with the copy; in that case, the original buffer must be returned to the underlying driver.

    So for a partial-chain scenario on a RESOURCES indication, the documented safe approaches are:

    • temporarily split/process/indicate, then restore the original chain before return, or
    • copy the data and use filter-owned storage / a filter-originated indication.
    1. The available documentation supports only this conclusion: the sample would not need chain-restore handling if it does not alter the original linked list. The documentation makes the restore requirement conditional on the case where the driver has processed or indicated the structures in a way that changes the original list shape. No context states that the obligation is waived for samples.
    2. No documented runtime self-check or Driver Verifier receive-path rule for this specific condition is present in the provided material.

    What is documented is the ownership model:

    • If NDIS_RECEIVE_FLAGS_RESOURCES is not set, the filter retains ownership until it calls NdisFReturnNetBufferLists.
    • If NDIS_RECEIVE_FLAGS_RESOURCES is set, returning from FilterReceiveNetBufferLists returns the buffer; the filter cannot keep the original NET_BUFFER_LIST and associated resources.
    • If a filter calls NdisFIndicateReceiveNetBufferLists with the resources flag set, NDIS returns the NET_BUFFER_LIST structures to the filter immediately on return from NdisFIndicateReceiveNetBufferLists, and NDIS does not call FilterReturnNetBufferLists for them.

    That matches the failure mode described: detaching a branch and returning on a RESOURCES indication breaks the underlying owner’s ability to reclaim all originally indicated NBLs.

    On the reference-page question: the FILTER_RECEIVE_NET_BUFFER_LISTS callback remarks do repeat the requirement. They state that if NDIS_RECEIVE_FLAGS_RESOURCES is set, the filter cannot keep the NET_BUFFER_LIST and associated resources, and the note says the driver must retain the original set of NET_BUFFER_LIST structures in the linked list and restore the original linked list before returning.


    References:

    AI-generated content may be incorrect. Read our transparency notes for more information.

    Was this answer helpful?

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.