diff --git a/XDP.md b/XDP.md index 5d63837..38f9140 100644 --- a/XDP.md +++ b/XDP.md @@ -1,6 +1,59 @@ XDP stands for e**X**press **D**ata **P**ath, and provides a high performance data path in the Linux kernel for processing network packets as they hit the NIC. +### Simple XDP Sample + +main.py +```python +#!/usr/bin/env python3 + +from bcc import BPF +import time + +device = "lo" +b = BPF(src_file="filter.c") +fn = b.load_func("udpfilter", BPF.XDP) +b.attach_xdp(device, fn, 0) + +try: + b.trace_print() +except KeyboardInterrupt: + pass + +b.remove_xdp(device, 0) +``` + +filter.c +```c +#define KBUILD_MODNAME "filter" +#include +#include +#include +#include +#include + +int udpfilter(struct xdp_md *ctx) { + bpf_trace_printk("got a packet\n"); + void *data = (void *)(long)ctx->data; + void *data_end = (void *)(long)ctx->data_end; + struct ethhdr *eth = data; + if ((void*)eth + sizeof(*eth) <= data_end) { + struct iphdr *ip = data + sizeof(*eth); + if ((void*)ip + sizeof(*ip) <= data_end) { + if (ip->protocol == IPPROTO_UDP) { + struct udphdr *udp = (void*)ip + sizeof(*ip); + if ((void*)udp + sizeof(*udp) <= data_end) { + if (udp->dest == ntohs(7999)) { + bpf_trace_printk("udp port 7999\n"); + udp->dest = ntohs(7998); + } + } + } + } + } + return XDP_PASS; +} +```