Python-BPF is an LLVM IR generator for eBPF programs written in Python. It uses llvmlite to generate LLVM IR and then compiles to LLVM object files. These object files can be loaded into the kernel for execution. Python-BPF performs compilation without relying on BCC.
Note: This project is under active development and not ready for production use.
llvmlite for IR generation.Dependencies:
bpftoolclangInstall via pip:
pip install pythonbpf pylibbpf
sudo apt-get install bpftool clang
pip install pythonbpf pylibbpf ctypeslib2
vmlinux.py using:sudo tools/vmlinux-gen.py
BCC-Examples/pip install -r BCC-Examples/requirements.txt
curl -s https://raw.githubusercontent.com/pythonbpf/Python-BPF/refs/heads/master/tools/setup.sh | sudo bash
BCC-Examples/ folder.import time
from pythonbpf import bpf, map, section, bpfglobal, BPF
from pythonbpf.helper import pid
from pythonbpf.maps import HashMap
from pylibbpf import *
from ctypes import c_void_p, c_int64, c_uint64, c_int32
import matplotlib.pyplot as plt
# This program attaches an eBPF tracepoint to sys_enter_clone,
# counts per-PID clone syscalls, stores them in a hash map,
# and then plots the distribution as a histogram using matplotlib.
# It provides a quick view of process creation activity over 10 seconds.
@bpf
@map
def hist() -> HashMap:
return HashMap(key=c_int32, value=c_uint64, max_entries=4096)
@bpf
@section("tracepoint/syscalls/sys_enter_clone")
def hello(ctx: c_void_p) -> c_int64:
process_id = pid()
prev = hist.lookup(process_id)
if prev:
previous_value = prev + 1
print(f"count: {previous_value} with {process_id}")
hist.update(process_id, previous_value)
return 0
else:
hist.update(process_id, 1)
return 0
@bpf
@bpfglobal
def LICENSE() -> str:
return "GPL"
b = BPF()
b.load_and_attach()
hist = BpfMap(b, hist)
print("Recording")
time.sleep(10)
counts = list(hist.values())
plt.hist(counts, bins=20)
plt.xlabel("Clone calls per PID")
plt.ylabel("Frequency")
plt.title("Syscall clone counts")
plt.show()
Python-BPF provides a complete pipeline to write, compile, and load eBPF programs in Python:
Python Source Code
@bpf, @map, @section, and @bpfglobal.ktime, deref), and tracepoints are defined using Python constructs, preserving a syntax close to standard Python.AST Generation
ast module parses the source code into an Abstract Syntax Tree (AST).LLVM IR Emission
llvmlite.LLVM Object File Compilation
.ll) is compiled into a BPF target object file (.o) using llc -march=bpf -O2.libbpf Integration (via pylibbpf)
pylibbpf.Execution in Kernel
This architecture eliminates the need for embedding C code in Python, allowing full Python tooling support while generating true BPF object files ready for kernel execution.
Create a virtual environment and activate it:
python3 -m venv .venv
source .venv/bin/activate
Install dependencies:
make install
Then, run any example in examples
Verify an object file with the kernel verifier:
./tools/check.sh check execve2.o
Run an object file using bpftool:
./tools/check.sh run execve2.o
Explore LLVM IR output from clang in examples/c-form by running make.
Python
79.9%
Jupyter Notebook
13.5%
C
2.7%
Shell
1.9%
Rust
1.6%
Python-BPF is an LLVM IR generator for eBPF programs written in Python. It uses llvmlite to generate LLVM IR and then compiles to LLVM object files. These object files can be loaded into the kernel for execution. Python-BPF performs compilation without relying on BCC.
Note: This project is under active development and not ready for production use.
llvmlite for IR generation.Dependencies:
bpftoolclangInstall via pip:
pip install pythonbpf pylibbpf
sudo apt-get install bpftool clang
pip install pythonbpf pylibbpf ctypeslib2
vmlinux.py using:sudo tools/vmlinux-gen.py
BCC-Examples/pip install -r BCC-Examples/requirements.txt
curl -s https://raw.githubusercontent.com/pythonbpf/Python-BPF/refs/heads/master/tools/setup.sh | sudo bash
BCC-Examples/ folder.import time
from pythonbpf import bpf, map, section, bpfglobal, BPF
from pythonbpf.helper import pid
from pythonbpf.maps import HashMap
from pylibbpf import *
from ctypes import c_void_p, c_int64, c_uint64, c_int32
import matplotlib.pyplot as plt
# This program attaches an eBPF tracepoint to sys_enter_clone,
# counts per-PID clone syscalls, stores them in a hash map,
# and then plots the distribution as a histogram using matplotlib.
# It provides a quick view of process creation activity over 10 seconds.
@bpf
@map
def hist() -> HashMap:
return HashMap(key=c_int32, value=c_uint64, max_entries=4096)
@bpf
@section("tracepoint/syscalls/sys_enter_clone")
def hello(ctx: c_void_p) -> c_int64:
process_id = pid()
prev = hist.lookup(process_id)
if prev:
previous_value = prev + 1
print(f"count: {previous_value} with {process_id}")
hist.update(process_id, previous_value)
return 0
else:
hist.update(process_id, 1)
return 0
@bpf
@bpfglobal
def LICENSE() -> str:
return "GPL"
b = BPF()
b.load_and_attach()
hist = BpfMap(b, hist)
print("Recording")
time.sleep(10)
counts = list(hist.values())
plt.hist(counts, bins=20)
plt.xlabel("Clone calls per PID")
plt.ylabel("Frequency")
plt.title("Syscall clone counts")
plt.show()
Python-BPF provides a complete pipeline to write, compile, and load eBPF programs in Python:
Python Source Code
@bpf, @map, @section, and @bpfglobal.ktime, deref), and tracepoints are defined using Python constructs, preserving a syntax close to standard Python.AST Generation
ast module parses the source code into an Abstract Syntax Tree (AST).LLVM IR Emission
llvmlite.LLVM Object File Compilation
.ll) is compiled into a BPF target object file (.o) using llc -march=bpf -O2.libbpf Integration (via pylibbpf)
pylibbpf.Execution in Kernel
This architecture eliminates the need for embedding C code in Python, allowing full Python tooling support while generating true BPF object files ready for kernel execution.
Create a virtual environment and activate it:
python3 -m venv .venv
source .venv/bin/activate
Install dependencies:
make install
Then, run any example in examples
Verify an object file with the kernel verifier:
./tools/check.sh check execve2.o
Run an object file using bpftool:
./tools/check.sh run execve2.o
Explore LLVM IR output from clang in examples/c-form by running make.
Python
79.9%
Jupyter Notebook
13.5%
C
2.7%
Shell
1.9%
Rust
1.6%