1 Commits

Author SHA1 Message Date
26f8f769c5 remove demos and add examples
Signed-off-by: varun-r-mallya <varunrmallya@gmail.com>
2025-09-29 23:44:49 +05:30
7 changed files with 1080 additions and 0 deletions

430
examples/IO-run.ipynb Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

35
examples/pybpf0.py Normal file
View File

@ -0,0 +1,35 @@
from pythonbpf import bpf, section, bpfglobal, BPF
import sys
from ctypes import c_void_p, c_int64
# Instructions to how to run this program
# 1. Install PythonBPF: pip install pythonbpf
# 2. `sudo /path/to/venv/bin/python ./python-bpf/demo/pybpf0.py`
@bpf
@section("tracepoint/syscalls/sys_enter_execve")
def hello_world(ctx: c_void_p) -> c_int64:
print("Hello, World!")
return c_int64(0)
@bpf
@bpfglobal
def LICENSE() -> str:
return "GPL"
b = BPF()
b.load_and_attach()
def main():
try:
with open("/sys/kernel/debug/tracing/trace_pipe", "r") as f:
for line in f:
sys.stdout.write(line)
sys.stdout.flush()
except KeyboardInterrupt:
pass
except PermissionError:
sys.stderr.write("Need root privileges to read trace_pipe\n")
if __name__ == "__main__":
main()

41
examples/pybpf1.py Normal file
View File

@ -0,0 +1,41 @@
from pythonbpf import bpf, map, section, bpfglobal, compile
from pythonbpf.helpers import XDP_PASS
from pythonbpf.maps import HashMap
from ctypes import c_void_p, c_int64
# Instructions to how to run this program
# 1. Install PythonBPF: pip install pythonbpf
# 2. Run the program: python demo/pybpf1.py
# 3. Run the program with sudo: sudo examples/check.sh run demo/pybpf1.o
# 4. Attach object file to any network device with something like ./check.sh xdp ../demo/pybpf1.o tailscale0
# 5. send traffic through the device and observe effects
@bpf
@map
def count() -> HashMap:
return HashMap(key=c_int64, value=c_int64, max_entries=1)
@bpf
@section("xdp")
def hello_world(ctx: c_void_p) -> c_int64:
key = 0
one = 1
prev = count().lookup(key)
if prev:
prevval = prev + 1
print(f"count: {prevval}")
count().update(key, prevval)
return XDP_PASS
else:
count().update(key, one)
return XDP_PASS
@bpf
@bpfglobal
def LICENSE() -> str:
return "GPL"
compile()

43
examples/pybpf2.py Normal file
View File

@ -0,0 +1,43 @@
from pythonbpf import bpf, map, section, bpfglobal, compile
from pythonbpf.helpers import ktime
from pythonbpf.maps import HashMap
from ctypes import c_void_p, c_int64, c_uint64
# Instructions to how to run this program
# 1. Install PythonBPF: pip install pythonbpf
# 2. Run the program: python demo/pybpf2.py
# 3. Run the program with sudo: sudo examples/check.sh run demo/pybpf2.o
# 4. Start a Python repl and `import os` and then keep entering `os.sync()` to see reponses.
@bpf
@map
def last() -> HashMap:
return HashMap(key=c_uint64, value=c_uint64, max_entries=3)
@bpf
@section("tracepoint/syscalls/sys_enter_sync")
def do_trace(ctx: c_void_p) -> c_int64:
key = 0
tsp = last().lookup(key)
if tsp:
kt = ktime()
delta = (kt - tsp)
if delta < 1000000000:
time_ms = (delta // 1000000)
print(f"sync called within last second, last {time_ms} ms ago")
last().delete(key)
else:
kt = ktime()
last().update(key, kt)
return c_int64(0)
@bpf
@bpfglobal
def LICENSE() -> str:
return "GPL"
compile()

49
examples/pybpf3.py Normal file
View File

@ -0,0 +1,49 @@
from pythonbpf import *
from pylibbpf import *
import sys
from ctypes import c_void_p, c_int64, c_uint64
@bpf
@map
def last() -> HashMap:
return HashMap(key=c_uint64, value=c_uint64, max_entries=3)
@bpf
@section("tracepoint/syscalls/sys_enter_clone")
def do_trace(ctx: c_void_p) -> c_int64:
key = 0
tsp = last().lookup(key)
if tsp:
kt = ktime()
delta = (kt - tsp)
if delta < 1000000000:
time_ms = (delta // 1000000)
print(f"Clone syscall entered within last second, last {time_ms} ms ago")
last().delete(key)
else:
kt = ktime()
last().update(key, kt)
return c_int64(0)
@bpf
@bpfglobal
def LICENSE() -> str:
return "GPL"
b = BPF()
# autoattaches tracepoints
b.load_and_attach()
def main():
try:
with open("/sys/kernel/debug/tracing/trace_pipe", "r") as f:
for line in f:
sys.stdout.write(line)
sys.stdout.flush()
except KeyboardInterrupt:
pass
except PermissionError:
sys.stderr.write("Need root privileges to read trace_pipe\n")
if __name__ == "__main__":
main()

62
examples/pybpf4.py Normal file
View File

@ -0,0 +1,62 @@
import time
from pythonbpf import bpf, map, section, bpfglobal, BPF
from pythonbpf.helpers import pid
from pythonbpf.maps import HashMap
from pylibbpf import BpfMap
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.
# Everything is done with Python only code and with the new pylibbpf library.
# Run `sudo /path/to/python/binary/ pybpf4.py`
@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()
one = 1
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 c_int64(0)
else:
hist().update(process_id, one)
return c_int64(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())
x = 0
for key in hist.keys():
if hist[key] > 40:
x += 1
print(f"PID {key} called clone() >40 times")
print(f"Total PIDs with clone() >40 times: {x}")
plt.hist(counts, bins=20)
plt.xlabel("Clone calls per PID")
plt.ylabel("Number of processes that called clone() x times in last 10 seconds")
plt.title("x")
plt.show()