C Temelleri

Struct, Memory Layout ve Byte Order

Struct, memory layout ve byte order - BPF verifier hataları ve network programming için kritik konular.

1.10 Struct, Union, Enum

Ön koşul: Önce Pointer’lar ve String’ler’i tamamlayın.

  • struct tanımlama ve erişim (. ve ->)
  • Nested struct’lar
  • union (aynı memory, farklı type)
  • enum (sabit kümesi)
  • typedef aliasing

BPF’te her yerde kullanılır: Packet header’lar, map tanımları, context struct’ları.

// BPF Map tanımlama - struct syntax
struct {
    __uint(type, BPF_MAP_TYPE_HASH);
    __uint(max_entries, 1024);
    __type(key, u64);
    __type(value, u64);
} my_map SEC(".maps");

İlgili eBPFHub alıştırmaları:

  • “Maps and multiple programs” - BPF map struct syntax
  • “Introduction (kprobes)” - struct sock, struct sock_common ile nested struct erişimi
  • “DNS packet parsing” - struct dns_header tanımlama

xdp-tutorial’da bakın:

  • common/parsing_helpers.h - struct hdr_cursor, struct vlan_hdr
  • basic03-map-counter/xdp_prog_kern.c:11-16 - BPF map tanımlama

Alıştırma: struct ethhdr’ı elle yazın: h_dest[6], h_source[6], h_proto.


1.11 Memory Layout, Padding ve Alignment (BPF İÇİN KRİTİK)

Ön koşul: Önce struct’ları tamamlayın.

Bu konu BPF verifier hataları için çok önemlidir!

  • Struct padding (compiler otomatik olarak padding ekler)
  • sizeof vs gerçek veri boyutu
  • #pragma pack(n) ile padding’i kaldırma
  • __attribute__((packed)) kullanımı
  • Explicit padding (bir pad member ekleme)
  • Memory alignment kuralları

BPF’te neden kritik:

struct called_info {
    u64 start;  // 8-byte
    u64 end;    // 8-byte
    u32 sector; // 4-byte
}; // sizeof = 24 (20 değil!)
// Verifier: "invalid indirect read from stack off -80+20 size 24"

Çözüm - explicit padding ekleyin:

struct called_info {
    u64 start;
    u64 end;
    u32 sector;
    u32 pad;    // explicit padding
}; // sizeof = 24, tüm byte'lar initialize edilmiş

eBPFHub: “Cross-syscall state tracking” alıştırmasında composite map key struct kullanacaksınız:

struct pid_fd_key {
    u64 pid;    // 8-byte aligned
    u32 fd;     // 4-byte -> dikkat: padding oluşabilir
};

Alıştırma: Farklı type’larla struct’lar yazın, sizeof ile kontrol edin ve padding’i gözlemleyin.


1.12 Byte Order (Endianness) - Network Programming İçin Temel

Ön koşul: Önce bitwise işlemleri tamamlayın.

  • Big-endian vs Little-endian
  • Network byte order (big-endian)
  • Host byte order (CPU’ya bağlıdır)
  • Dönüşüm fonksiyonları: htons, ntohs, htonl, ntohl

BPF’te:

  • bpf_ntohs() -> network to host (16-bit) - port numaraları
  • bpf_htons() -> host to network (16-bit) - protocol karşılaştırma
  • bpf_ntohl() -> network to host (32-bit) - IP adresleri
  • bpf_htonl() -> host to network (32-bit)
// Ethernet type field'ı network byte order'dadır
if (eth->h_proto == bpf_htons(ETH_P_IP)) {
    // IPv4 paketi
}

İlgili eBPFHub alıştırmaları:

  • “Tracking network connections” - bpf_ntohs(addr.sin_port) ile port dönüşümü
  • “DNS packet parsing” - bpf_ntohl(ip) ile IPv4 adres dönüşümü

Okuma: Computer Networking Fundamentals - byte order dahil networking temelleri.

Alıştırma:

  1. 0x1234’ü hem big-endian hem little-endian olarak byte’lara ayırın
  2. 192.168.1.1 IP adresini network byte order’a dönüştürün