Ugrás a főtartalomra

Linux eBPF & XDP Networking Primer

Linux eBPF & XDP Networking Primer

A gyakorlati útmutató a BPF programok, XDP kampók, és kernel- bypass csomagfeldolgozás hálózati mérnökök.

1. Milyen típusú gyógyszer az eBPF?

Az eBPF (kibővített Berkeley Packet Filter) egy Linux kernel alrendszer, amely lehetővé teszi, hogy a kernel belsejében szandoxizált programokat futtass anélkül, hogy módosítanád a kernel forráskódját vagy a rendszermag moduljait. A programokat egy kernel bytecode hitelesítő ellenőrzi a végrehajtás előtt, biztosítva a biztonságot.

Hálózatépítéshez az eBPF programok a kernel hálózati stack, és meg tudja vizsgálni, módosítani, átirányítani, vagy csepp csomagok. A legfontosabb előny vagy kernel modulok teljesítmény és programozhatóság: eBPF programok JIT- konfigurált anyanyelvi kód, és megoszthatja az állam keresztül (a kernel és a userspace között megosztott kulcsértékboltok).

Hook Hely Láthatóság Az eset használata
XDP NIC driver, a sk _ buff hozzárendelés előtt Legkisebb DDOS leesés, terheléskiegyenlítés
tc be- és kilépés A sk _ buff hozzárendelés után Alacsony Forgalmi alakítás, jelölés, átirányítás
aljzatszűrő Socket kap útvonal Közepes tcpdump- style szűrés
kszonda / jelpont Kernel funkció be- és kilépése Változások Megfigyelhetőség, nyomon követés

2. XDP hook pontok

XDP (eXpress Data Path) programok fut a lehető legkorábbi ponton a hálózati stack - belül a NIC meghajtó, mielőtt a kernel hozzárendeli a . Ez azt jelenti:

  • Native XDP
  • Általános XDPsk_buff
  • Offlocked XDP

Az XDP program az öt ítélet egyikét adja vissza:

Visszatérési kód Intézkedés
XDP_DROP Drop csomag azonnal - a legalacsonyabb késleltetés eldobása
XDP_PASS Áttérés a normál hálózati készletre
XDP_TX Visszaküldeni ugyanazt az interfészt (pattogó)
XDP_REDIRECT Átirányítani egy másik interfész vagy AF _ XDP aljzat
XDP_ABORTED Hibaút - csepp nyomkövetővel

3. XDP csomag csepp példa

A következő program leejti az összes UDP csomagot az eBPF térképen tárolt IP-forrásból, így a felhasználói tér vezérlősíkja futáskor frissítheti a bloklistát.

// xdp_drop_udp.c — Drop UDP from IPs in a BPF map
#include 
#include 
#include 
#include 
#include 

// BPF map: src IP → drop flag (1 = drop)
struct {
    __uint(type, BPF_MAP_TYPE_HASH);
    __uint(max_entries, 1024);
    __type(key, __u32);    // source IPv4 address
    __type(value, __u32);  // 1 = block
} blocklist SEC(".maps");

SEC("xdp")
int xdp_drop_udp(struct xdp_md *ctx) {
    void *data     = (void *)(long)ctx->data;
    void *data_end = (void *)(long)ctx->data_end;

    // Parse Ethernet header
    struct ethhdr *eth = data;
    if ((void *)(eth + 1) > data_end) return XDP_PASS;
    if (eth->h_proto != __constant_htons(ETH_P_IP)) return XDP_PASS;

    // Parse IPv4 header
    struct iphdr *ip = (void *)(eth + 1);
    if ((void *)(ip + 1) > data_end) return XDP_PASS;
    if (ip->protocol != IPPROTO_UDP) return XDP_PASS;

    // Check blocklist map
    __u32 src = ip->saddr;
    __u32 *val = bpf_map_lookup_elem(&blocklist, &src);
    if (val && *val == 1) return XDP_DROP;

    return XDP_PASS;
}

char _license[] SEC("license") = "GPL";
A kutyák ellenőrzése kötelező.data_end

Töltés és csatlakoztatás :

# Compile
clang -O2 -target bpf -c xdp_drop_udp.c -o xdp_drop_udp.o

# Attach to interface (native XDP)
ip link set eth0 xdp obj xdp_drop_udp.o sec xdp

# Add an IP to the blocklist via bpftool
bpftool map update name blocklist key 0x01 0x02 0x03 0x04 value 0x01 0x00 0x00 0x00

# Remove XDP program
ip link set eth0 xdp off

4. AF _ XDP: Kernel- Bypass

AF_XDPXDP_REDIRECT

Főbb alkotóelemek:

  • UMEM
  • Gyűrűk
  • Zero- másolási mód

AF _ XDP ideális egyedi csomag feldolgozása vonali sebességgel anélkül, hogy a működési komplexitás DPDK (nincs ölelés, nincs CPU rögzítés szükséges alapvető használat).

5. tc BPF: Forgalomalakítás és -szűrés

tcclsactsk_buff

// tc_mark.c — Mark packets with DSCP EF (46) for VoIP traffic on port 5060
#include 
#include 
#include 
#include 
#include 

SEC("classifier")
int tc_mark_voip(struct __sk_buff *skb) {
    void *data     = (void *)(long)skb->data;
    void *data_end = (void *)(long)skb->data_end;

    struct ethhdr *eth = data;
    if ((void *)(eth + 1) > data_end) return TC_ACT_OK;
    if (eth->h_proto != __constant_htons(ETH_P_IP)) return TC_ACT_OK;

    struct iphdr *ip = (void *)(eth + 1);
    if ((void *)(ip + 1) > data_end) return TC_ACT_OK;
    if (ip->protocol != IPPROTO_UDP) return TC_ACT_OK;

    struct udphdr *udp = (void *)(ip + 1);
    if ((void *)(udp + 1) > data_end) return TC_ACT_OK;

    // Mark SIP traffic (port 5060) with DSCP EF (46 = 0xB8 in TOS byte)
    if (udp->dest == __constant_htons(5060) || udp->source == __constant_htons(5060)) {
        // DSCP EF = 46, shifted left 2 bits in TOS field = 184 (0xB8)
        bpf_skb_store_bytes(skb, offsetof(struct iphdr, tos) + sizeof(struct ethhdr),
                            &((__u8){184}), 1, BPF_F_RECOMPUTE_CSUM);
    }
    return TC_ACT_OK;
}

char _license[] SEC("license") = "GPL";
# Attach tc BPF program
tc qdisc add dev eth0 clsact
tc filter add dev eth0 egress bpf da obj tc_mark.o sec classifier

6. Áránykorlátozás eBPF Térképek

Az eBPF térképek nagyvonalú feldolgozást tesznek lehetővé. A következő minta végrehajtja persource- IP sebesség korlátozó segítségével egy token vödör tárolt :

// Conceptual token bucket per source IP — checks tokens, drops if exceeded
struct ratelimit_entry {
    __u64 tokens;        // current token count
    __u64 last_update;   // nanoseconds timestamp
};

struct {
    __uint(type, BPF_MAP_TYPE_LRU_HASH);
    __uint(max_entries, 65536);
    __type(key, __u32);                     // source IP
    __type(value, struct ratelimit_entry);
} rate_map SEC(".maps");

// In XDP program:
// 1. bpf_ktime_get_ns() — get current time
// 2. Lookup entry for src IP
// 3. Refill tokens: tokens += (elapsed_ns / 1e9) * rate_pps
// 4. If tokens >= 1: decrement and XDP_PASS
// 5. Else: XDP_DROP

7. bpftool & bpftrace

Két alapvető eszköz az élő eBPF programokkal való munkához:

# bpftool — inspect loaded programs and maps
bpftool prog list                         # list all loaded eBPF programs
bpftool prog show id 42                   # details for program ID 42
bpftool prog dump xlated id 42            # disassemble to eBPF bytecode
bpftool prog dump jited id 42            # dump JIT-compiled native code
bpftool map list                          # list all BPF maps
bpftool map dump name blocklist           # dump all entries in map "blocklist"
bpftool map update name blocklist \
    key 192 168 1 100 value 1 0 0 0       # add entry (network byte order)
# bpftrace — DTrace-style one-liners for kernel tracing
# Count XDP drops per second
bpftrace -e 'tracepoint:xdp:xdp_exception { @drops[args->action] = count(); } interval:s:1 { print(@drops); clear(@drops); }'

# Trace tcp_retransmit_skb — show retransmit events with comm name
bpftrace -e 'kprobe:tcp_retransmit_skb { printf("%s retransmit\n", comm); }'

# Histogram of packet sizes on eth0
bpftrace -e 'tracepoint:net:netif_receive_skb /args->name == "eth0"/ { @size = hist(args->len); }'

8. Összehasonlítás: eBPF / XDP vs DPDK vs RDMA

Jellemzők eBPF / XDP DPDK RDMA
Kernel érintettség Minimális (XDP járművezetői) Nincs (teljes bypass) Nincs (RDMA NIC)
Memóriamodell Standard + AF _ XDP UMEM Kötelező felszakadások Regisztrált memóriarégiók
Max. áthaladás ~ 100 Gbps natív XDP > 100 Gbps 200 + Gbps (InfiniBand)
CPU-használat Alacsony (eseményvezérelt) Magas (busy- poll magok) Közel nulla (kirakodott)
Műveleti összetettség Alacsony - szabványos szerszámok Magas - dedikált magok, ölelések Magas - szövet kezelése
Használati eset DDoS mérséklés, LB, megfigyelhetőség Virtuális routerek, NFV, csomag gen Tárolás (NVMeoF), HPC MPI
Nyelv Korlátozott C / rozsda C / Rozs API (C) igék
A hüvelykujj szabálya: