XDP Packet Processing
XDP Temelleri ve Packet Parsing
XDP (eXpress Data Path) - driver seviyesinde, kernel stack’e girmeden önce packet processing. En hızlı eBPF hook noktası.
XDP Temelleri ve Packet Parsing
Bu lab’da öğrenecekleriniz:
- XDP mode’ları: Generic (test), Native (production), Offload (NIC)
- XDP action’ları:
XDP_PASS- paketi kernel stack’e iletXDP_DROP- paketi düşür (en hızlı)XDP_TX- paketi aynı interface’den geri gönderXDP_REDIRECT- başka bir interface’e yönlendirXDP_ABORTED- hata, paketi düşür + trace
struct xdp_mdcontext (data,data_end,data_meta)- Ethernet header parsing (
struct ethhdr) - IPv4/IPv6 header parsing
- TCP/UDP header parsing
- ICMP parsing
- Byte order:
bpf_ntohs(),bpf_htons()
Packet Parsing Pattern
SEC("xdp")
int xdp_parser(struct xdp_md *ctx) {
void *data = (void *)(long)ctx->data;
void *data_end = (void *)(long)ctx->data_end;
struct ethhdr *eth = data;
if (data + sizeof(*eth) > data_end)
return XDP_PASS;
if (eth->h_proto == bpf_htons(ETH_P_IP)) {
struct iphdr *ip = data + sizeof(*eth);
if ((void *)(ip + 1) > data_end)
return XDP_PASS;
// IPv4 packet processing...
}
return XDP_PASS;
}
Tam parse chain: Ethernet → IP → TCP/UDP
Yukarıdaki temel pattern’i tam bir L3/L4 parser’a genişletme:
SEC("xdp")
int xdp_full_parse(struct xdp_md *ctx) {
void *data = (void *)(long)ctx->data;
void *data_end = (void *)(long)ctx->data_end;
// L2: Ethernet
struct ethhdr *eth = data;
if (data + sizeof(*eth) > data_end)
return XDP_PASS;
if (eth->h_proto != bpf_htons(ETH_P_IP))
return XDP_PASS; // IPv4 değil, atla
// L3: IPv4
struct iphdr *ip = data + sizeof(*eth);
if ((void *)(ip + 1) > data_end)
return XDP_PASS;
// L4: TCP veya UDP
void *l4 = (void *)ip + (ip->ihl * 4); // IP header değişken uzunlukta olabilir
if (ip->protocol == IPPROTO_TCP) {
struct tcphdr *tcp = l4;
if ((void *)(tcp + 1) > data_end)
return XDP_PASS;
// tcp->dest hedef portu içerir (network byte order)
if (tcp->dest == bpf_htons(80))
return XDP_DROP; // HTTP trafiğini düşür
} else if (ip->protocol == IPPROTO_UDP) {
struct udphdr *udp = l4;
if ((void *)(udp + 1) > data_end)
return XDP_PASS;
// udp->dest hedef portu içerir
if (udp->dest == bpf_htons(53))
return XDP_DROP; // DNS trafiğini düşür
}
return XDP_PASS;
}
Pattern’e dikkat edin: her pointer dereference, data_end’e karşı sınır kontrolü gerektirir. Verifier bunu zorlar — herhangi bir kontrolü atlarsanız programınız yüklenmez.
xdp-tutorial: packet01-parsing/ - kendiniz yapın!
xdp-tutorial nasıl çalışılır:
- Önce
README.orgdosyasını okuyun (ödevleri anlayın) xdp_prog_kern.cdosyasını okuyun,parsing_helpers.hinceleyin- Ödevleri kendiniz yapın
- Takılırsanız
packet-solutions/klasörüne bakın
Ön okuma: XDP Paper (~15 sayfa)
xdp-tutorial’da inceleyin: setup_dependencies.org - bağımlılıklar (clang, llvm, libelf, kernel header’ları, bpftool, libxdp, libbpf).