I made NDIS 6 network filter driver and am reading the packet. When I use Intel I350 NIC, 'MmGetMdlByteCount' returns '9014'bytes. This value is the same as the MTU size, so I can read the data at once. However, when using the x540 NIC, 'MmGetMdlByteCount' is returned to '2048'bytes. So I have to read the MDL over and over again. Why is this happening? Is there a way to read data at once on the X540 NIC? I want to reduce repetition because I think the consumption time will be longer if I bring the data several times.
What you're seeing is a result of how the NIC hardware physically works. Different hardware will use different buffer layout strategies. NDIS does not attempt to force every NIC to use the same strategy, since that would reduce performance on some NICs. Unfortunately for you, that means the complexity of dealing with different buffers gets pushed upwards into NDIS filter & protocol drivers.
You can use
NdisGetDataBufferto do some of this work for you. Internally,NdisGetDataBufferworks like this:So you can use
NdisGetDataBufferto obtain a contiguous view of the payload. The simplest way to use it is this:But this can have a double-copy in some cases. (Exercise to test your understanding: when would there be a double-copy?) For slightly better performance, you can avoid the double-copy with this trick:
You haven't included a complete code sample, but I suspect there may be some bugs in your code. I don't see any attempt to handle NetBuffer->CurrentMdlOffset. While this is usually zero, it's not always zero, so your code would not always be correct.
Similarly, it looks like the copy isn't correctly constrained by ulDataLength. You would need a
ulDataLength -= ulBytesToCopyin there somewhere to fix this.I'm very sympathetic to how tricky it is to navigate NBLs, NBs, and MDLs -- my first NIC driver included a nasty bug in calculating MDL offsets. I have some MDL-handling code internally -- I will try to clean it up a bit and publish it at https://github.com/microsoft/ndis-driver-library/ in the next few days. I'll update this post if I get it published. I think there's clearly a need for some nice, reusable and well-documented sample code to just copy (subsets of) an MDL chain into a flat buffer, or vice-versa.
Update: Refer to
MdlCopyMdlChainAtOffsetToFlatBufferin mdl.h