eBPF Integration Guide

July 28, 2026 ยท View on GitHub

Overview

XDP for Windows supports eBPF-based packet processing through integration with the eBPF for Windows project. eBPF programs offer fully programmable packet inspection, filtering, and redirection -- replacing the limited built-in rules engine with arbitrary logic that runs safely inside the Windows kernel.

Note: The built-in rules-based program API (XDP_RULE, XDP_MATCH_TYPE, XdpCreateProgram) is deprecated and planned for removal. All users should migrate to eBPF programs. See Migrating from Built-in Rules.

How the Two Projects Fit Together

ProjectRole
XDP for WindowsProvides the high-performance data path: NIC hook points, AF_XDP sockets, shared-memory rings, and the XDP driver (xdp.sys). Registers an XDP program type and helper functions with the eBPF runtime.
eBPF for WindowsProvides the eBPF runtime: program verification (PREVAIL verifier), map infrastructure, and the NMR-based extension model that XDP plugs into.

An eBPF program is compiled offline into a native Windows kernel driver (.sys), loaded and verified by the eBPF for Windows runtime, and then attached to an XDP hook point. The XDP driver invokes the program on every received packet at wire speed.

graph TD
    subgraph User Mode
        A["AF_XDP App<br/>(XSK socket)"] -- UMEM rings --> X[xdp.sys]
        B["bpf_object__open/load<br/>(eBPF loader / libbpf)"] -- IOCTL --> E["eBPF runtime<br/>(ebpfcore.sys)<br/>verifier"]
    end

    subgraph Kernel Mode
        E -- NMR attach --> X
        X --> NIC
    end

Prerequisites

  1. eBPF for Windows must be installed first. Follow the eBPF for Windows installation guide.

  2. XDP for Windows with eBPF support enabled (see Installation).

  3. Clang/LLVM 18.1.8+ for compiling eBPF C programs to BPF bytecode. See the eBPF for Windows development prerequisites.

Installation

Runtime NuGet Package (v1.3+)

After installing eBPF for Windows:

xdp-setup.ps1 -Install xdp
xdp-setup.ps1 -Install xdpebpf

Developer Setup

Install the eBPF export tool so the eBPF verifier and compiler know about XDP's program type and helper functions:

xdp-setup.ps1 -Install xdpebpfexport

Then run the export tool before verifying or compiling XDP eBPF programs:

xdpbpfexport.exe

This populates registry keys (HKCU and/or HKLM) that eBPF for Windows reads to discover the XDP program type, attach type, context descriptor, and helper function prototypes.

Registry Configuration

Key (under HKLM\...\Services\xdp)TypeDefaultDescription
XdpEbpfEnabledDWORD0Set to 1 to enable eBPF program attachment.
XdpEbpfModeDWORDN/A0 = force generic mode; 1 = force native mode. If unset, XDP chooses automatically.

XDP Program Type

XDP registers a single eBPF program type with the following identifiers:

PropertyValue
Program type GUIDf1832a85-85d5-45b0-98a0-7069d63013b0
Attach type GUID85e0d8ef-579e-4931-b072-8ee226bb2e9d
bpf_prog_typeBPF_PROG_TYPE_XDP
ELF section prefixxdp

Context: xdp_md_t

Every XDP eBPF program receives a pointer to xdp_md_t describing the current 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;

Return Values: xdp_action_t

The program returns one of the following actions:

typedef enum _xdp_action {
    XDP_PASS     = 1, // Allow the packet to continue up the stack.
    XDP_DROP     = 2, // Drop the packet silently.
    XDP_TX       = 3, // Bounce the packet back out the same NIC.
    XDP_REDIRECT = 4, // Redirect to another target (set by bpf_redirect_map).
} xdp_action_t;

Program Signature

typedef xdp_action_t xdp_hook_t(xdp_md_t *context);

Helper Functions

XDP exposes program-specific helper functions in addition to the general eBPF helpers (e.g., bpf_map_lookup_elem, bpf_map_update_elem, bpf_printk).

bpf_redirect_map

Redirects the current packet to an AF_XDP socket looked up from an XSKMAP.

intptr_t bpf_redirect_map(void *map, uint64_t key, uint64_t flags);
ParameterDescription
mapPointer to a BPF_MAP_TYPE_XSKMAP map.
keyLookup key (typically ctx->rx_queue_index).
flagsThe lower 2 bits specify a fallback xdp_action_t to return if the lookup or redirect fails (e.g., XDP_PASS or XDP_DROP).

Returns: XDP_REDIRECT on success, or the fallback action on failure.

See eBPF Redirect Map (XSKMAP) for a comprehensive guide.

Writing an XDP eBPF Program

Minimal Example: Pass All Packets

#include "bpf_helpers.h"
#include "xdp/ebpfhook.h"

SEC("xdp/pass")
int pass(xdp_md_t *ctx) {
    return XDP_PASS;
}

Packet Inspection: Allow Only IPv6

#include "bpf_endian.h"
#include "bpf_helpers.h"
#include "net/if_ether.h"
#include "net/ip.h"
#include "xdp/ebpfhook.h"

SEC("xdp/allow_ipv6")
int allow_ipv6(xdp_md_t *ctx) {
    ETHERNET_HEADER *eth;
    IPV6_HEADER *ipv6;
    const int hdr_size = sizeof(*eth) + sizeof(*ipv6);

    if ((char *)ctx->data + hdr_size > (char *)ctx->data_end) {
        return XDP_DROP;
    }

    eth = (ETHERNET_HEADER *)ctx->data;
    if (eth->Type != htons(ETHERNET_TYPE_IPV6)) {
        return XDP_DROP;
    }

    ipv6 = (IPV6_HEADER *)(eth + 1);
    if (ipv6->Version != 6) {
        return XDP_DROP;
    }

    return XDP_PASS;
}

Selective Drop with Map-Based Configuration

#include "bpf_helpers.h"
#include "xdp/ebpfhook.h"

struct {
    __uint(type, BPF_MAP_TYPE_ARRAY);
    __type(key, uint32_t);
    __type(value, uint32_t);
    __uint(max_entries, 1);
} interface_map SEC(".maps");

struct {
    __uint(type, BPF_MAP_TYPE_ARRAY);
    __type(key, uint32_t);
    __type(value, uint64_t);
    __uint(max_entries, 1);
} dropped_packet_map SEC(".maps");

SEC("xdp/selective_drop")
int selective_drop(xdp_md_t *ctx) {
    uint32_t zero = 0;

    uint32_t *target_ifindex = bpf_map_lookup_elem(&interface_map, &zero);
    if (!target_ifindex) {
        return XDP_PASS;
    }

    if (*target_ifindex == ctx->ingress_ifindex) {
        uint64_t *count = bpf_map_lookup_elem(&dropped_packet_map, &zero);
        if (count) {
            *count += 1;
        }
        return XDP_DROP;
    }

    return XDP_PASS;
}

Redirect to AF_XDP Socket

See eBPF Redirect Map (XSKMAP) for complete examples.

#include "bpf_helpers.h"
#include "xdp/ebpfhook.h"

struct {
    __uint(type, BPF_MAP_TYPE_XSKMAP);
    __type(key, uint64_t);
    __type(value, void *);
    __uint(max_entries, 64);
} xsk_map SEC(".maps");

SEC("xdp/xsk_redirect")
int xsk_redirect(xdp_md_t *ctx) {
    return bpf_redirect_map(&xsk_map, ctx->rx_queue_index, XDP_PASS);
}

Compiling eBPF Programs

eBPF programs are compiled from C source to native Windows kernel drivers (.sys files) using a two-step process. The official eBPF for Windows runtime only supports loading native drivers -- JIT execution of BPF object files (.o) is not officially supported.

Step 1: Compile to BPF ELF Object

clang -g -target bpf -O2 -c my_program.c -o my_program.o

Step 2: Convert to Native Driver

Use the Convert-BpfToNative.ps1 script from the eBPF for Windows package to convert the BPF object file into a signed Windows kernel driver:

Convert-BpfToNative.ps1 -FileName my_program -IncludeDir <ebpf_include_path> -Platform x64 -Configuration Release -KernelMode $true

This produces a my_program.sys file that can be loaded by the eBPF runtime.

Ensure the include paths contain the XDP and eBPF headers:

  • xdp/ebpfhook.h (from the XDP development NuGet package)
  • bpf_helpers.h, bpf_endian.h (from eBPF for Windows)

The ELF section name must start with xdp (e.g., SEC("xdp/my_prog")).

Loading and Attaching Programs

Programs are loaded and attached using the eBPF for Windows user-mode APIs (libbpf-compatible or native Windows eBPF APIs). XDP does not provide its own program loading API for eBPF -- the eBPF for Windows runtime handles verification and attachment.

Important: The official eBPF for Windows runtime only supports loading native drivers (.sys files). JIT execution of BPF object files (.o) is not officially supported. See Compiling eBPF Programs for the compilation workflow.

// Load a native eBPF driver (.sys)
struct bpf_object *obj = bpf_object__open("my_program.sys");
bpf_object__load(obj);
int prog_fd = bpf_program__fd(
    bpf_object__find_program_by_name(obj, "xsk_redirect"));
bpf_xdp_attach(ifIndex, prog_fd, 0, NULL);

For AF_XDP redirection, user mode must also populate the XSKMAP with XSK socket handles after loading the program. See eBPF Redirect Map (XSKMAP) for the complete workflow.

Observability

Performance Counters

XDP exposes per-interface performance counters for eBPF program execution:

CounterDescription
EbpfXskMapLookupFailuresbpf_redirect_map calls where the XSKMAP key lookup failed.
EbpfXskMapRedirectFailuresbpf_redirect_map calls where the XSK was found but the socket was in an invalid state for redirect.

ETW Tracing

eBPF-specific ETW events are emitted for redirect map operations:

EventDescription
EbpfRedirectMapLookupFailureLogged when bpf_redirect_map fails to find a key in the XSKMAP. Includes the key and fallback action.
EbpfRedirectMapRedirectFailureLogged when the XSK handle was found but XskCanRedirect returned false. Includes the key, XSK handle, and fallback action.
EbpfRedirectMapSuccessLogged on successful redirect. Includes the key and XSK handle.

Use the existing XDP tracing infrastructure to capture these events at Logging.

Limitations

  • XSKMAP is read-only from eBPF programs -- user mode must populate the map; bpf_map_lookup_elem, bpf_map_update_elem, and bpf_map_delete_elem cannot be used on XSKMAPs from within a BPF program.
  • No mixing of eBPF and built-in rules -- a program is either eBPF or rules-based; they cannot be combined on the same queue.
  • Not source-compatible with Linux XDP -- while the programming model is similar, the APIs and headers differ.

Migrating from Built-in Rules

The built-in rules engine (XdpCreateProgram with XDP_RULE / XDP_MATCH_TYPE / XDP_RULE_ACTION) is deprecated and planned for removal. All users should migrate to eBPF programs.

References