loader: Reuse compiled BPF objects across agent restarts
The Issue & Context
Before this change, the Cilium agent recompiles all BPF programs from scratch on every restart, causing long delays (up to 553 seconds for endpoint templates) and missed regeneration deadlines in CI environments.
Root Cause Analysis
The recompilation happened because the agent had no mechanism to detect unchanged BPF inputs and reuse previously compiled objects. The compilation was triggered unconditionally without hashing or caching the BPF sources, clang configuration, Go build ID, or generated headers, leading to redundant expensive clang invocations.
Solution Strategy & Architectural Pattern
This PR introduces a hashing mechanism that combines all relevant inputs—BPF sources, clang config and environment, Go build ID, and generated headers—to produce a unique key. On agent restart, it loads cached compiled BPF objects from disk if the hash matches, skipping recompilation. Any input change triggers a fresh compile as before. This caching logic is implemented primarily in pkg/datapath/loader/cache.go and verified with new tests in cache_test.go and hash_test.go.
Key Takeaway for Contributors
When build artifacts depend on multiple inputs, hashing those inputs to cache and reuse compiled objects can drastically reduce restart latency and resource consumption, especially in environments where full rebuilds are costly and inputs rarely change.