Creating a Filter Driver
A filter driver exports some functions that are called by the NL2. Such functions have an Rtndflt prefix. The filter driver can also call functions provided by the NL2. Those functions are called callbacks, and their address is provided by the NL2 in the RtndfltInitDriver function.
Note: Functions exported by filter drivers are always called in the context of the NL2 process.
Sections in this topic:
- Loading the Filter Driver
- Initializing the Filter Driver Globally
- Initializing a Filter Driver Instance
- Filtering a Batch of Received Frames
Load the Filter Driver
The NL2 calls LoadLibrary to dynamically load the filter driver RTDLL. The NL2 then calls GetProcAddress to get the addresses of all exported functions.
Initializing the Filter Driver Globally
Once the filter driver is loaded, the NL2 calls RtndfltInitDriver. This function allows the filter driver to perform some global initialization (independent of any specific Rx Queue), and also allows for an initial information exchange between the filter driver and the NL2:
- The NL2 provides the filter driver with the RTNDFLT_CALLBACKS structure, which contains function pointers to the callbacks exposed to filter drivers by the NL2.
- The filter driver provides the NL2 with the RTNDFLT_DRIVER_INFO structure, which contains information about the filter driver.
Initializing a Filter Driver Instance
Any filter driver should be capable of running simultaneously on several Receive Queues.
The NL2 calls the RtndfltManageRxQueue function for each Rx Queue the filter driver must run on. This allows the filter driver to allocate and initialize different resources for each Rx Queue. In this function, the filter driver is expected to allocate a dedicated context for the specified Rx Queue and return a number or a pointer (ULONG_PTR type) that the NL2 will use in subsequent function calls to identify the Rx Queue from which frames are incoming.
Filtering a Batch of Received Frames
Once the filter driver initializes an instance for a given Rx Queue, it must be ready to inspect all the incoming frames from that queue.
The NL2 calls RtndfltReceiveFrames whenever it extracts a batch of frames from the Rx Queue. This allows the filter driver to inspect the content of each frame and determine whether it should be dropped or passed to the application. The filter driver must set the Filtered field of the RTND Buffer Header structure to TRUE for every frame it wants to drop. It's not necessary to change the Filtered field for the frames it wants to pass to the application, as the NL2 sets the fields to FALSE before calling the filter driver.
Note: The filter driver is not allowed to modify the content of the frames.
For a given Rx Queue, the RtndfltReceiveFrames function is always called from the same thread (the queue's Rx Queue Management thread).