C Fundamentals

Program Structure, Types and Operators

This chapter teaches C through the lens of BPF programming. The concepts are standard C, but every topic includes its BPF-specific restrictions and patterns. Topics not relevant to XDP/networking are explicitly marked.

The building blocks of C programs: preprocessors, data types, and operators. Since BPF programs are written in C, these fundamentals are critical.

What to Skip

This roadmap focuses on XDP/networking eBPF programs. The following C topics are not needed in this context. Verified against Facebook Katran, Cilium, and Cloudflare production BPF code.

TopicWhy It Is Not Needed
time.h / date-time functionsBPF programs use bpf_ktime_get_ns() instead of libc time functions
File I/O (fopen, fread, fwrite)BPF programs cannot access the filesystem; all state goes through maps
Dynamic memory (malloc, free)XDP/networking BPF programs use stack and map-based allocation only*
RecursionThe verifier rejects backward jumps; use bounded loops with #pragma unroll
Floating point arithmeticThe BPF ISA has no floating-point instructions; use integer math
Signal handling (signal.h)Only relevant in user-space loader code, not in BPF programs
Multi-threading (pthread)BPF programs are single-threaded per invocation; concurrency is handled by per-CPU maps
Standard I/O (printf, scanf)Use bpf_printk() for debug output; no standard I/O in kernel context
struct tm, strftimeNot available in BPF; timestamps are raw nanosecond values
Random number generationBPF has bpf_get_prandom_u32(); no need for libc random functions
Binary search treesUse BPF_MAP_TYPE_LPM_TRIE for prefix matching; BPF maps replace manual search
Linear/binary search algorithmsBPF maps provide O(1) hash lookup; no need to implement search manually
Complex data structures (linked lists, trees)BPF maps (hash, array, LRU, LPM trie) replace classic data structures*

* Kernel 6.1+ note: Modern kernels introduce bpf_obj_new() for heap allocation, bpf_list_head for linked lists (6.1+), and bpf_rbtree for red-black trees (6.3+). These are used in advanced BPF subsystems like sched_ext (custom CPU scheduling), not in typical XDP/networking programs. If you move beyond this roadmap into advanced BPF, revisit these topics.

Optional but useful for pointer practice: Linked lists and stack/queue implementations. You will not use these in XDP, but they provide good struct + pointer practice.


1.1 Program Structure and Preprocessors

  • #include - including header files
  • #define - defining macros
  • #ifndef / #endif - header guards (prevents double inclusion)
  • #pragma directives - special instructions for the compiler
  • Macro functions - compile-time code generation

Used in BPF:

  • SEC() macro -> __attribute__((section(NAME), used))
  • #include "ep_platform.h" - eBPFHub platform header
  • #pragma unroll - bounded loop optimization
#define SEC(NAME) __attribute__((section(NAME), used))

SEC("xdp")
int xdp_prog(struct xdp_md *ctx) { ... }
// -> places into the .xdp section, prevents the linker from discarding it

eBPFHub: In the Chapter 0 -> “Platform overview” exercise, you will see the SEC() macro, #include usage, and your first BPF program structure.

See in xdp-tutorial: basic01-xdp-pass/xdp_pass_kern.c - see how the SEC() macro is defined.

Exercise: Write your own header file, add a header guard, and define a macro.


1.2 Data Types and Format Specifiers

  • int, char, short, long, unsigned types
  • sizeof operator
  • Type casting
  • Format specifiers: %d, %u, %x, %s, %p, %llu

Types used in BPF: __u8, __u16, __u32, __u64, __s32, __be16

Format specifiers are critical for bpf_printk:

  • %d -> int
  • %u -> unsigned int
  • %x -> hex
  • %llu -> __u64
  • %s -> string (limited)

eBPFHub: In the “Process context” exercise, you will see char[16] buffer usage with bpf_get_current_comm(&buf, sizeof(buf)).

See in xdp-tutorial: common/xdp_stats_kern_user.h - struct datarec definition.

Exercise: Print the sizes of different types using sizeof, and format them with printf.


1.3 Operators and Bitwise Operations

  • Arithmetic: +, -, *, /, %
  • Bitwise: &, |, ^, ~, <<, >>
  • Comparison: ==, !=, <, >, <=, >=
  • Logical: &&, ||, !

Critical in BPF: Bit masking (extracting VLAN IDs, flag checks)

eBPFHub: In the “Reading event data” exercise, you will practice bitwise operations with __data_loc field decoding: lower 16 bits = offset, upper 16 bits = length.

offset = loc & 0xFFFF;
len = loc >> 16;

Exercise:

  1. Set/clear a specific bit of a number
  2. Split an IP address into 4 octets (using >> and &)