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.
| Topic | Why It Is Not Needed |
|---|---|
time.h / date-time functions | BPF 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* |
| Recursion | The verifier rejects backward jumps; use bounded loops with #pragma unroll |
| Floating point arithmetic | The 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, strftime | Not available in BPF; timestamps are raw nanosecond values |
| Random number generation | BPF has bpf_get_prandom_u32(); no need for libc random functions |
| Binary search trees | Use BPF_MAP_TYPE_LPM_TRIE for prefix matching; BPF maps replace manual search |
| Linear/binary search algorithms | BPF 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)#pragmadirectives - 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,unsignedtypessizeofoperator- 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:
- Set/clear a specific bit of a number
- Split an IP address into 4 octets (using
>>and&)