Skip to main content

What Comes After eBPF? Exploring the KernelScript Experiment

·1436 words·7 mins
Linux EBPF KernelScript Kernel Development Open Source Systems Programming Rust Networking Cloud Native Linux Foundation
Table of Contents

What Comes After eBPF? Exploring the KernelScript Experiment

For more than a decade, eBPF has transformed Linux from a static operating system into a programmable platform. It powers modern observability systems, cloud networking infrastructure, security frameworks, and Kubernetes networking stacks. Yet despite its success, eBPF development remains notoriously difficult.

KernelScript, a new project introduced by Linux kernel developer Cong Wang, attempts to address this challenge by rethinking how Linux kernel extensions are built. Rather than creating another wrapper around existing eBPF tooling, KernelScript proposes a unified programming model that spans eBPF programs, user-space applications, and kernel modules.

Whether it ultimately succeeds or fails, the project raises an important question: after years of innovation around eBPF, has Linux kernel extensibility become too complex for its own good?

๐Ÿš€ The Persistent Complexity of eBPF Development
#

eBPF has become one of the most influential Linux technologies of the past decade.

Today, organizations such as Cloudflare, Meta, and the Cilium project rely heavily on eBPF for:

  • High-performance packet processing
  • DDoS mitigation
  • Load balancing
  • Network observability
  • Kubernetes networking
  • Runtime security enforcement

However, building production-grade eBPF software remains challenging.

During his presentation at the Linux Foundation Open Source Summit, Cong Wang highlighted several recurring pain points faced by developers:

  • Understanding verifier constraints
  • Managing kernel-version-specific structure layouts
  • Handling tail call program arrays
  • Sharing maps across multiple programs
  • Coordinating user-space lifecycle management
  • Maintaining separate codebases for kernel and user-space components

These issues are not theoretical. They represent daily operational challenges for engineers deploying eBPF at scale.

Perhaps the strongest evidence of this complexity is that most production eBPF systems continue to be written directly in C, despite years of attempts to introduce higher-level abstractions.

๐Ÿ› ๏ธ Five Generations of eBPF Abstraction
#

KernelScript is not the first effort to simplify eBPF development. It follows a long history of abstraction layers that attempted to improve developer productivity.

BCC: The First Wave
#

The earliest widely adopted abstraction was BCC (BPF Compiler Collection).

BCC wrapped eBPF programs with Python tooling, enabling developers to create tracing utilities quickly without managing low-level details.

Its advantages included:

  • Rapid prototyping
  • Python integration
  • Rich tracing capabilities

Its disadvantages were equally significant:

  • Runtime LLVM dependency
  • Kernel header requirements
  • Large deployment footprint

BCC remains useful for development and diagnostics but is less attractive for production environments.

bpftrace: DTrace-Inspired Simplicity
#

The second major wave was bpftrace.

Inspired by DTrace, bpftrace introduced a concise scripting language that dramatically reduced the amount of code needed for tracing workloads.

A single command could often replace dozens of lines of C code.

However, its scope remained limited:

  • Excellent for observability
  • Poor fit for advanced networking
  • No support for XDP
  • No support for TC traffic control
  • No support for struct_ops

As a result, users frequently return to C when moving from experimentation to production.

libbpf and CO-RE
#

The third wave brought libbpf and CO-RE (Compile Once, Run Everywhere).

This approach solved one of eBPF’s most frustrating problems: kernel-version portability.

By leveraging BTF (BPF Type Format) metadata, CO-RE allows programs to adapt to structure layout differences across kernels without requiring recompilation.

Today, libbpf + CO-RE is widely considered the production standard.

The downside is that developers still write eBPF programs in C and must understand verifier behavior and low-level implementation details.

Rust-Based eBPF Frameworks
#

The fourth wave introduced Rust-based eBPF development.

Frameworks such as Aya offer:

  • Memory safety
  • Strong type systems
  • Improved developer ergonomics
  • Modern tooling

Yet Rust introduces its own challenges.

The eBPF verifier evaluates generated bytecode rather than source code. Certain Rust language constructs may generate code patterns that are difficult or impossible for the verifier to accept.

As a result, developers often find themselves debugging interactions between Rust, LLVM, and verifier constraints.

KernelScript: The Fifth Wave
#

KernelScript represents a fundamentally different approach.

Rather than wrapping existing eBPF development workflows, it introduces a new domain-specific language (DSL) and compiler infrastructure built in OCaml.

Its objective is not simply to simplify eBPF syntax but to unify multiple development domains under a single programming model.

๐Ÿ”„ One Source File, Three Execution Worlds
#

The most distinctive aspect of KernelScript is its multi-target compilation model.

Within a single .ks source file, developers can define components destined for different execution environments.

Examples include:

  • @xdp functions for XDP packet processing
  • @helper functions for eBPF helpers
  • @kfunc functions that generate kernel module code
  • Standard functions that become user-space applications

The compiler then generates the corresponding artifacts:

  • eBPF C code
  • User-space C code
  • Kernel module C code

These outputs are subsequently passed to existing toolchains for final compilation.

This architecture addresses a genuine fragmentation problem.

Today, a complete eBPF solution often consists of:

  1. eBPF programs running inside the kernel
  2. User-space management applications
  3. Optional kernel modules providing custom functionality

Each component typically lives in separate files, uses different APIs, and follows different lifecycle models.

KernelScript attempts to bring them together under a single language and type system.

Automatic Resource Coordination
#

The language also introduces higher-level management concepts.

Examples include:

  • Automatic map sharing
  • Unified resource visibility
  • Compile-time lifecycle validation
  • Cross-component type consistency

For instance, operations such as attach() can be validated statically to ensure they occur only after successful program loading.

This moves a class of runtime errors into compile-time verification.

โš ๏ธ The Hidden Cost of New Abstractions
#

The history of software engineering suggests that every abstraction removes one set of problems while introducing another.

The eBPF ecosystem provides numerous examples.

BCC’s Debugging Burden
#

While BCC simplified development, debugging often required understanding:

  • Python code
  • Generated eBPF code
  • Kernel verifier behavior

Developers effectively had to understand multiple layers simultaneously.

Rust’s Translation Gap
#

Rust-based eBPF frameworks improve safety but can complicate debugging.

Verifier failures may originate from generated LLVM output rather than the Rust source code that developers wrote.

This creates a translation gap between intent and execution.

KernelScript’s Longer Toolchain
#

KernelScript introduces an even longer compilation path:

KernelScript (.ks)
        โ†“
Generated C
        โ†“
Compiler
        โ†“
eBPF Bytecode
        โ†“
Kernel Verifier

When something fails, developers may need to inspect generated C code rather than the original KernelScript source.

Consequently, KernelScript’s success will depend heavily on two factors:

  1. The quality of generated code
  2. The clarity of diagnostic messages

Without exceptional tooling, a simplified language could merely relocate complexity instead of eliminating it.

๐ŸŒ The Multikernel Connection
#

KernelScript becomes even more interesting when viewed alongside another initiative being pursued by Cong Wang.

At the same time he is developing KernelScript, Wang is also advocating a multikernel architecture for Linux.

The concept proposes running multiple isolated kernel instances on the same machine, improving security and flexibility through stronger separation boundaries.

Patches related to this proposal have already appeared on Linux kernel mailing lists.

If such an architecture were eventually adopted, several new challenges would emerge:

  • Which kernel instance owns a given eBPF program?
  • How are maps shared across kernels?
  • How is communication coordinated?
  • How are resources isolated and managed?

Traditional eBPF development models may become increasingly difficult to manage in such an environment.

Viewed through this lens, KernelScript may be less about simplifying today’s eBPF workflows and more about preparing for a future where Linux extensibility becomes significantly more sophisticated.

๐Ÿ“Š Evaluating KernelScript Beyond eBPF
#

The significance of KernelScript depends largely on whether it is viewed as:

  • Another eBPF abstraction layer, or
  • A foundational programming model for future Linux architectures

If the multikernel vision never gains widespread adoption, KernelScript will need to justify itself solely through developer productivity improvements.

If multikernel Linux eventually becomes reality, however, a unified language spanning user space, eBPF programs, and kernel extensions could become an essential tool rather than a convenience.

This broader context changes how the project should be evaluated.

The goal is not merely to reduce boilerplate code. It is to create a coherent programming model for increasingly complex kernel extension environments.

๐Ÿ”ฎ Conclusion
#

KernelScript highlights a deeper issue within Linux development: despite 35 years of evolution, kernel extensibility remains fragmented across multiple programming models, toolchains, and execution contexts.

Its attempt to unify eBPF programs, user-space applications, and kernel modules under a single language addresses a legitimate pain point that many developers experience today.

Whether KernelScript becomes widely adopted remains uncertain. History suggests that new abstraction layers often trade one form of complexity for another, and the project’s long-term success will depend on tooling quality, debugging experience, and ecosystem adoption.

Nevertheless, it is worth remembering that eBPF itself was once dismissed as a niche technology. Today it underpins critical infrastructure across the cloud-native ecosystem.

KernelScript may ultimately become a footnote in Linux historyโ€”or it may represent the first step toward the next generation of kernel programmability. At this stage, both possibilities remain open.

Related

The Souls of Linux: The Visionaries Behind the Open-Source Revolution
·719 words·4 mins
Linux Open Source GNU Debian Ubuntu Kernel Development Free Software
Linux Copy Fail Vulnerability Exposes Millions of Systems to Root Attacks
·1356 words·7 mins
Linux Cybersecurity Kernel Security CVE-2026-31431 Kubernetes Cloud Security Privilege Escalation Open Source
Linux 7.1 NTFS Driver: A Major Performance Breakthrough
·579 words·3 mins
Linux NTFS Kernel File Systems WSL2 Performance Open Source Storage