diff --git a/pythonbpf/maps/__init__.py b/pythonbpf/maps/__init__.py index 370bbf2..48fc9ff 100644 --- a/pythonbpf/maps/__init__.py +++ b/pythonbpf/maps/__init__.py @@ -1,4 +1,4 @@ -from .maps import HashMap, PerfEventArray +from .maps import HashMap, PerfEventArray, RingBuf from .maps_pass import maps_proc -__all__ = ["HashMap", "PerfEventArray", "maps_proc"] +__all__ = ["HashMap", "PerfEventArray", "maps_proc", "RingBuf"] diff --git a/pythonbpf/maps/maps.py b/pythonbpf/maps/maps.py index 24b421c..a2d7c21 100644 --- a/pythonbpf/maps/maps.py +++ b/pythonbpf/maps/maps.py @@ -1,3 +1,4 @@ +# This file provides type and function hints only and does not actually give any functionality. class HashMap: def __init__(self, key, value, max_entries): self.key = key @@ -33,3 +34,18 @@ class PerfEventArray: def output(self, data): pass # Placeholder for output method + + +class RingBuf: + def __init__(self, max_entries): + self.max_entries = max_entries + + def reserve(self, size: int, flags=0): + if size > self.max_entries: + raise ValueError("size cannot be greater than set maximum entries") + return 0 + + def submit(self, data, flags=0): + pass + + # add discard, output and also give names to flags and stuff diff --git a/pythonbpf/maps/maps_pass.py b/pythonbpf/maps/maps_pass.py index 2621617..51fd7c1 100644 --- a/pythonbpf/maps/maps_pass.py +++ b/pythonbpf/maps/maps_pass.py @@ -51,7 +51,7 @@ def create_bpf_map(module, map_name, map_params): def create_map_debug_info(module, map_global, map_name, map_params): - """Generate debug information metadata for BPF map""" + """Generate debug information metadata for BPF maps HASH and PERF_EVENT_ARRAY""" generator = DebugInfoGenerator(module) uint_type = generator.get_uint32_type() diff --git a/tests/c-form/ex8.bpf.c b/tests/c-form/ex8.bpf.c deleted file mode 100644 index b1861fd..0000000 --- a/tests/c-form/ex8.bpf.c +++ /dev/null @@ -1,47 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include -#include -#include -#include -#define __TARGET_ARCH_aarch64 -#define u64 unsigned long long - -struct { - __uint(type, BPF_MAP_TYPE_HASH); - __uint(max_entries, 10240); - __type(key, struct request *); - __type(value, u64); -} start SEC(".maps"); - -SEC("kprobe/blk_start_request") -int BPF_KPROBE(trace_start_req, struct request *req) -{ - u64 ts = bpf_ktime_get_ns(); - bpf_map_update_elem(&start, &req, &ts, BPF_ANY); - return 0; -} - -SEC("kprobe/blk_mq_start_request") -int BPF_KPROBE(trace_start_mq, struct request *req) -{ - u64 ts = bpf_ktime_get_ns(); - bpf_map_update_elem(&start, &req, &ts, BPF_ANY); - return 0; -} - -SEC("kprobe/blk_account_io_completion") -int BPF_KPROBE(trace_completion, struct request *req) -{ - u64 *tsp, delta; - - tsp = bpf_map_lookup_elem(&start, &req); - if (tsp) { - delta = bpf_ktime_get_ns() - *tsp; - bpf_printk("%d %x %d\n", req->__data_len, - req->cmd_flags, delta / 1000); - bpf_map_delete_elem(&start, &req); - } - return 0; -} - -char LICENSE[] SEC("license") = "GPL"; diff --git a/tests/c-form/ringbuf.bpf.c b/tests/c-form/ringbuf.bpf.c new file mode 100644 index 0000000..648de2c --- /dev/null +++ b/tests/c-form/ringbuf.bpf.c @@ -0,0 +1,30 @@ +#include "vmlinux.h" +#include +#include +#include + +struct { + __uint(type, BPF_MAP_TYPE_RINGBUF); + __uint(max_entries, 1 << 24); // 16 MB +} rb SEC(".maps"); + +//struct msg { +// u32 pid; +// char comm[16]; +//}; + +//SEC("tracepoint/syscalls/sys_enter_execve") +//int handle_execve(struct trace_event_raw_sys_enter *ctx) +//{ +// struct msg *m; +// m = bpf_ringbuf_reserve(&rb, sizeof(*m), 0); +// if (!m) +// return 0; +// +// m->pid = bpf_get_current_pid_tgid() >> 32; +// bpf_get_current_comm(&m->comm, sizeof(m->comm)); +// bpf_ringbuf_submit(m, 0); +// return 0; +//} + +//char LICENSE[] SEC("license") = "GPL"; diff --git a/tests/failing_tests/perf_buffer_map.py b/tests/failing_tests/perf_buffer_map.py new file mode 100644 index 0000000..1ec3874 --- /dev/null +++ b/tests/failing_tests/perf_buffer_map.py @@ -0,0 +1,45 @@ +from pythonbpf import bpf, map, struct, section, bpfglobal, compile +from pythonbpf.helpers import ktime, pid +from pythonbpf.maps import PerfEventArray + +from ctypes import c_void_p, c_int32, c_uint64 + + +# PLACEHOLDER EXAMPLE. THIS SHOULD TECHNICALLY STILL FAIL TESTS +@bpf +@struct +class data_t: + pid: c_uint64 + ts: c_uint64 + comm: str(16) + + +@bpf +@map +def events() -> PerfEventArray: + return PerfEventArray(key_size=c_int32, value_size=c_int32) + + +@bpf +@section("tracepoint/syscalls/sys_enter_clone") +def hello(ctx: c_void_p) -> c_int32: + dataobj = data_t() + ts = ktime() + strobj = "hellohellohello" + dataobj.pid = pid() + dataobj.ts = ktime() + # dataobj.comm = strobj + print( + f"clone called at {dataobj.ts} by pid {dataobj.pid}, comm {strobj} at time {ts}" + ) + events.output(dataobj) + return c_int32(0) + + +@bpf +@bpfglobal +def LICENSE() -> str: + return "GPL" + + +compile() diff --git a/tests/failing_tests/ringbuf.py b/tests/failing_tests/ringbuf.py new file mode 100644 index 0000000..a6c60c8 --- /dev/null +++ b/tests/failing_tests/ringbuf.py @@ -0,0 +1,25 @@ +from pythonbpf import bpf, map, bpfglobal, section +from pythonbpf.maps import RingBuf +from ctypes import c_int32, c_void_p + + +# Define a map +@bpf +@map +def mymap() -> RingBuf: + return RingBuf(max_entries=(1 << 24)) + + +@bpf +@section("tracepoint/syscalls/sys_enter_clone") +def testing(ctx: c_void_p) -> c_int32: + return c_int32(0) + + +@bpf +@bpfglobal +def LICENSE() -> str: + return "GPL" + + +compile()