简体   繁体   中英

Copying the NetBufferListInfo array instead of calling NdisCopySendNetBufferListInfo?

I have a kernel driver that seperates every net buffer in every recv/send NBL, and allocates a local structure for every NB which contains the packet content and some other stuff and sends it to a user buffer, and completes/returns the original NBL. The user service then sends back the packets that are OK back to driver and i then finally send/indicate them, by creating an NBL for every packet, and then chaining them together.

This causes the loss of some metadata about the packet, that are seem to be inside NetBufferListInfo (specially WFP metadata).

My question is, can i just save the content of the NetBufferListInfo in the original NBL of the corresponding NB, and save it to my local structure that represents NBs, and the recopy it when i create a NBL that contains that NB?

I thought i should use NdisAllocateCloneNetBufferList + NetBufferListInfo and copy the pointer to the cloned NBL to my local structure as a new member, but the problem with this is that freeing these buffers using NdisFreeCloneNetBufferList will become very complicated, as i create a local structure for every net buffer and insert them in a list that is sent to user service, and each of them could point to a arbitrary NBL (and many of them could be pointing to the same NBL, as i clone the NBL once for multiple NBs inside an NBL), and when the user sends those that are OK to me to, i need to be careful not to free a cloned NBL twice after i indicate/send the NBLs (i assume it will cause double free BSOD). Therefore i need to then keep a reference count for every cloned NBL and make sure to free it when it hits 0, and also some other complications..

So what is the easiest solution for me? Can i just save the content of NetBufferListInfo array of the corresponding NBL in my local structure, and recopy it when i create the final NBL corresponding to a NB?

You're allowed to copy the NetBufferListInfo fields that are fully documented and that you understand semantically. For example, you can copy the TcpIpChecksumNetBufferListInfo , because it's fully documented, and semantically it makes sense to propagate it to another NBL that has the same payload.

But there are some fields that are private to the OS, and at least one of those is a refcounted pointer. So if you were to copy that field, then return the original NBL, the pointer would dangle. The only way to influence the refcount is to call NdisCopySendNetBufferListInfo or NdisCopyReceiveNetBufferListInfo , which handle this for you.

TL;DR: You can write code like this:

new_nbl->NetBufferListInfo[TcpIpChecksumNetBufferListInfo] = old_nbl->NetBufferListInfo[TcpIpChecksumNetBufferListInfo];
new_nbl->NetBufferListInfo[NetBufferListHashValue] = old_nbl->NetBufferListInfo[NetBufferListHashValue];
. . .

but you can't write code like this:

RtlCopyMemory(
    new_nbl->NetBufferListInfo,
    old_nbl->NetBufferListInfo,
    sizeof(old_nbl->NetBufferListInfo));

since not all the slots are blittable.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM