Module 01 — Config Parser
What you learn
How to write a config file parser in C and use it to drive all subsystem initialization in a dataplane application.
In a real DPDK app nothing can start without a config file. The config tells the application which CPU cores to hand to DPDK, how many NIC queues to open, where Kafka is running, where the Hyperscan pattern files live, and which lcore plays which role (RX / TX / worker). Every piece of the system reads from this one parsed structure.
Where this fits in the real application
main()
│
├─► config_load() ← THIS MODULE
│ parse dp_app.conf
│ populate config_t
│
├─► build eal_argv[] (Module 11 — EAL Init)
│ from config: cores, socket_mem, hugepage_sz
│
├─► rte_eal_init() (Module 11)
│
├─► port_init() (Module 13)
│ from config: num_rx_queues, rx_desc, tx_desc
│
├─► kafka_init() (Module 25/26)
│ from config: broker, topic_policy, topic_cdr
│
├─► hs_init_global_scratch() (Module 19/21)
│ from config: pattern_file, pattern_file2
│
└─► launch worker lcores (Module 15)
from config: rx_lcore, tx_lcore, worker_lcores
In the production dataplane project this logic lives in app_main.c.
Files
| File | Purpose |
|---|---|
config_parser.c |
Parser implementation + demo main() |
sample.conf |
Example config with all sections a real DP app uses |
Makefile |
Build rules |
Build and run
make
./config_parser # reads sample.conf
./config_parser my.conf # reads a custom config file
Expected output:
=== Module 01: Config Parser ===
[config] Loaded 23 entries:
[eal ] cores = 0-7
[eal ] socket_mem = 2048
...
--- Values a real dataplane app reads at startup ---
[EAL]
cores = 0-7
socket_mem = 2048 MB
...
Key concepts in the code
1. Parse once, read many times
config_load() is called once. The resulting config_t is a global (or
passed by pointer). Every subsystem calls config_get_*() to read its
values — no one re-parses the file.
2. Section + key lookup
Values are identified by [section] + key, not just key. This prevents
name collisions across subsystems (eal.log_level vs logging.level).
3. Default values everywhere
config_get_int(&cfg, "port", "num_rx_queues", 1) — the third argument is
the default. Code never crashes on a missing key; it falls back gracefully.
This is critical in production where operators may omit optional settings.
4. Inline comments stripped
broker.example.com:9092 # primary broker is parsed as broker.example.com:9092.
Without this, the # would end up in the Kafka broker string and cause a
connection failure.
5. Type coercion at read time
The file stores everything as strings. config_get_int() and
config_get_bool() convert at read time with proper error handling —
same pattern used with every C config library.
Config format reference
# Full-line comment (ignored)
; Also a comment
[section_name]
key = value
key = value # inline comment (stripped)
Supported value types:
| Function | Accepts |
|---|---|
config_get_string() |
any string |
config_get_int() |
decimal integer |
config_get_bool() |
true/false, yes/no, 1/0 |
Next module
Module 02 — Logger: Once config is parsed the first real subsystem to initialize is the logger. Every subsequent module (EAL, ports, Kafka, policy engine) uses it to report startup progress and errors.
Source files
| File | Download |
|---|---|
config_parser.c |
config_parser.c |
sample.conf |
sample.conf |
Makefile |
Makefile |