XDP for Windows
repository·main·Indexed 19 days ago
https://github.com/microsoft/xdp-for-windowsA high-performance networking interface for Windows that allows applications to bypass the standard networking stack to achieve high packet processing rates. It provides the AF_XDP interface for user-mode applications to receive, inspect, drop, or send network traffic via XDP hook points using shared memory rings. The project includes driver-level APIs for registering XDP interfaces, managing RX/TX queues, and handling data path operations via XDP_RING, XDP_BUFFER, and XDP_FRAME structures.
What's inside XDP for Windows
- XDP for Windows is a high-performance Windows interface designed to send and receive network packets at high rates. It achieves this by bypassing most of the standard Windows OS networking stack, similar to the eXpress Data Path (XDP) concept used in Linux. Developers use this project to implement high-throughput, low-latency networking applications on Windows.
eBPF Integration Guide Overview
mainThis guide explains how to integrate XDP for Windows with theebpf-for-windowsproject. XDP for Windows provides the high-performance packet processing framework, whileebpf-for-windowsprovides the eBPF runtime and ecosystem. Together, they allow developers to run eBPF programs on Windows to process network traffic at the XDP layer.How extension negotiation works for drivers and AF_XDP applications
mainThe XDP platform negotiates extensions between sockets/programs and drivers using the following workflows:
For XDP Drivers
- Declaration: Drivers declare supported extensions during queue initialization using
XDP_EXTENSION_INFO. - Enablement: The XDP platform enables the intersection of the requested extensions and the extensions supported by the driver.
- Retrieval: Drivers retrieve
XDP_EXTENSIONhandles to access the enabled extensions.
For AF_XDP Applications
- Implicit Enablement: All V1 extensions are implicitly enabled by the AF_XDP subsystem.
- Direct Access: Applications do not need to explicitly declare version information; they can directly access extension data using extension getter functions.
- Driver Dependency: Extension availability is ultimately dependent on whether the underlying driver supports them.
- Declaration: Drivers declare supported extensions during queue initialization using
Use XDP_API_VERSION_3 or later instead of XDP_API_TABLE
mainThe
XDP_API_TABLEstructure is deprecated. It was used to hold function pointers from thexdpapi.dlllibrary for older versions of the API (XDP_API_VERSION_1andXDP_API_VERSION_2).Recommendation for new applications: Do not use
XDP_API_TABLE. Instead, useXDP_API_VERSION_3or later. These newer versions provide header-only API implementations, which eliminates the need to loadxdpapi.dllor manage a function pointer table manually.XDP eBPF Program Type and Context
mainXDP registers a specific eBPF program type. When writing programs, use the following identifiers and the
xdp_md_tcontext structure.Identifiers:
- Program type GUID:
f1832a85-85d5-45b0-98a0-7069d63013b0 - Attach type GUID:
85e0d8ef-579e-4931-b072-8ee226bb2e9d bpf_prog_type:BPF_PROG_TYPE_XDP- ELF section prefix:
xdp
Context Structure (
xdp_md_t): Every program receives a pointer to this structure describing the packet:typedef struct xdp_md { void *data; // Pointer to start of packet data (L2 frame). void *data_end; // Pointer to end of packet data. uint64_t data_meta; // Packet metadata (reserved). uint32_t ingress_ifindex; // Ingress network interface index. uint32_t rx_queue_index; // RX queue index on the ingress interface. } xdp_md_t;typedef struct xdp_md { void *data; void *data_end; uint64_t data_meta; uint32_t ingress_ifindex; uint32_t rx_queue_index; } xdp_md_t;- Program type GUID:
Usage constraints for XdpUnloadApi
mainWhen using
XdpUnloadApi, observe the following constraints:- Lifecycle Management: Every call to
XdpLoadApimust be paired with a corresponding call toXdpUnloadApiwhen the API is no longer required. - Thread Safety/Context: This routine cannot be called from
DllMain.
- Lifecycle Management: Every call to
Manage XDP receive queues (RX)
mainXDP interfaces manage receive queues through a lifecycle of creation, activation, and deletion:
- Create: Call
XDP_CREATE_RX_QUEUEto request a queue. The platform ensures at most one XDP queue exists per hardware queue. This returns anInterfaceRxQueuecontext and anInterfaceRxQueueDispatchtable. - Activate: Use
XDP_ACTIVATE_RX_QUEUEto insert the queue into the data path. This step is required because the queue is not ready for use immediately after creation. - Delete: Call
XDP_DELETE_RX_QUEUEto remove the queue. After this, the interface must not access descriptor rings or XDP buffers associated with that queue.
Note: The
XDP_INTERFACE_RX_QUEUE_DISPATCHstructure contains theInterfaceNotifyQueuecallback used by the platform to request data path operations.typedef NTSTATUS XDP_CREATE_RX_QUEUE( _In_ XDP_INTERFACE_HANDLE InterfaceContext, _Inout_ XDP_RX_QUEUE_CONFIG_CREATE Config, _Out_ XDP_INTERFACE_HANDLE *InterfaceRxQueue, _Out_ const XDP_INTERFACE_RX_QUEUE_DISPATCH **InterfaceRxQueueDispatch ); typedef NTSTATUS XDP_ACTIVATE_RX_QUEUE( _In_ XDP_INTERFACE_HANDLE InterfaceRxQueue, _In_ XDP_RX_QUEUE_HANDLE XdpRxQueue, _In_ XDP_RX_QUEUE_CONFIG_ACTIVATE Config ); typedef VOID XDP_DELETE_RX_QUEUE( _In_ XDP_INTERFACE_HANDLE InterfaceRxQueue );- Create: Call
How the User-Mode API handles Per-Type Device Fallback
mainThe XDP API (specifically
_XdpOpenObjectType()inxdp/details/xdpapi.handxdp/details/afxdp.h) implements a fallback mechanism to ensure compatibility with older versions of XDP.Fallback Logic:
- The API attempts to open the specific per-type device (e.g.,
\Device\xdpapi\program). - If the per-type device does not exist, the API checks the application's version requirements.
- If the application defines
XDP_MINIMUM_MAJOR_VERandXDP_MINIMUM_MINOR_VERsuch that the minimum version is <= 1.3, the API falls back to the common\Device\xdpdevice. - Applications targeting a version > 1.3 will not perform this fallback, as per-type devices were introduced after version 1.3.
- The API attempts to open the specific per-type device (e.g.,
Lifecycle management for XdpOpenApi
mainEvery successful call toXdpOpenApimust be paired with a corresponding call toXdpCloseApiwhen the API is no longer required to ensure proper resource cleanup.Understand XDP Per-Object-Type Security
mainXDP provides fine-grained access control by exposing separate device objects for different XDP object types. Instead of a single monolithic device, administrators can assign independent SDDL (Security Descriptor Definition Language) security descriptors to specific object types. This allows granting a user access to XDP maps without necessarily granting them access to XDP programs or interface configurations.
Key Concepts:
- Per-type devices: Located under the
\Device\xdpapidirectory. - Common device: The legacy
\Device\xdpdevice allows any object type and is used for backward compatibility. - Security Enforcement: To effectively restrict access via per-type devices, the common device's SDDL must be configured to be at least as restrictive as the per-type SDDLs. If a user has access to the common device, they can bypass per-type restrictions by accessing objects through it.
- Per-type devices: Located under the
Extend XDP with eBPF
mainXDP for Windows is extensible via eBPF programs through integration with eBPF for Windows.
Migration Warning: The built-in rules-based program engine is deprecated and planned for removal. Developers should migrate to eBPF-based processing. See the eBPF Integration Guide for details.
What are XDP Descriptor Extensions?
mainDescriptor extensions are optional, variable-sized metadata structures stored contiguously after base descriptors (frames, buffers, or TX completions) in memory. They allow the XDP data path to pass additional information—such as timestamps, checksum offload data, or memory mapping details—without modifying the base descriptor structures, ensuring backward compatibility and memory efficiency.