C Temelleri
BPF C Ozellikleri
BPF’e özgü C özellikleri ve tuzaklar - __attribute__ syntax, const/volatile kısıtlamaları, offsetof ve BPF C tuzaklarının özeti.
1.13 __attribute__ Syntax (GCC/Clang Extension’ları)
BPF kodunda yaygın olarak kullanılan compiler attribute’ları:
// Zorunlu inlining (BPF'te gerekli)
static __always_inline int foo(void) { }
// Kullanılmasa bile compile et (SEC macro'sunun parçası)
__attribute__((section("xdp"), used))
// Struct padding'i kaldır
__attribute__((packed))
// Alignment'ı zorla
__attribute__((aligned(8)))
SEC() macro nasıl çalışır:
#define SEC(NAME) __attribute__((section(NAME), used))
SEC("xdp")
int xdp_prog(struct xdp_md *ctx) { ... }
eBPFHub’da kullanılan SEC() örnekleri:
SEC("tp/sched/sched_process_exec")-> tracepointSEC("tracepoint/syscalls/sys_enter_read")-> syscall entrySEC("kprobe/tcp_finish_connect")-> kprobe
1.14 const, volatile ve restrict
const-> değişmezvolatile-> optimizer’a “bu değişebilir” derrestrict-> pointer aliasing ipucu
BPF’teki kısıtlamalar:
constBPF’te sorunlara yol açabilir (verifier)volatilebazen map erişimi için gereklidir- Global const string/array YASAKLANMIŞTIR (relocation sorunu)
// YANLIŞ (BPF'te çalışmaz)
const char *msg = "hello";
// DOĞRU
char msg[] = "hello"; // stack üzerinde
1.15 offsetof Macro
Bir struct member’ın offset’ini compile time’da hesaplayın:
#include <stddef.h>
struct iphdr {
// ...
__be32 saddr; // offset: 12
__be32 daddr; // offset: 16
};
size_t off = offsetof(struct iphdr, saddr); // = 12
BPF’te kullanımı:
bpf_skb_store_bytes(skb,
l3_off + offsetof(struct iphdr, saddr),
&new_saddr, 4, 0);
1.16 BPF C Tuzakları Özeti
| Kural | Neden |
|---|---|
Her fonksiyon static __always_inline olmalı | BPF’te normal call yapılmaz (kernel 4.16+ bpf-to-bpf hariç) |
| Global variable KULLANMAYIN | Relocation sorunu |
| const string KULLANMAYIN | Relocation sorunu |
| Unbounded loop KULLANMAYIN | Verifier reddeder |
memset/memcpy için __builtin_* kullanın | Standart kütüphane yok |
| Struct padding’e dikkat edin | Verifier stack kontrolü |
| Pointer bounds check ZORUNLUDUR | if (ptr + 1 > data_end) |
eBPFHub: Tüm alıştırmalarda bu kurallar pratikte karşımıza çıkar, özellikle NULL check’ler, bounded loop’lar ve stack buffer boyutları.
Alıştırma: Basit bir BPF programı yazın, bu kuralları uygulayın ve verifier’dan geçirin.