add ringbuf map type

This commit is contained in:
2025-10-01 23:51:18 +05:30
parent 8ceb1d1ac3
commit da9df2e6bf
3 changed files with 114 additions and 28 deletions

View File

@ -1,11 +1,12 @@
import ast import ast
from logging import Logger
from llvmlite import ir from llvmlite import ir
from enum import Enum from enum import Enum
from .maps_utils import MapProcessorRegistry from .maps_utils import MapProcessorRegistry
from ..debuginfo import DebugInfoGenerator from ..debuginfo import DebugInfoGenerator
import logging import logging
logger = logging.getLogger(__name__) logger: Logger = logging.getLogger(__name__)
def maps_proc(tree, module, chunks): def maps_proc(tree, module, chunks):
@ -13,7 +14,7 @@ def maps_proc(tree, module, chunks):
map_sym_tab = {} map_sym_tab = {}
for func_node in chunks: for func_node in chunks:
if is_map(func_node): if is_map(func_node):
print(f"Found BPF map: {func_node.name}") logger.info(f"Found BPF map: {func_node.name}")
map_sym_tab[func_node.name] = process_bpf_map(func_node, module) map_sym_tab[func_node.name] = process_bpf_map(func_node, module)
return map_sym_tab return map_sym_tab
@ -145,6 +146,60 @@ def create_map_debug_info(module, map_global, map_name, map_params):
return global_var return global_var
def create_ringbuf_debug_info(module, map_global, map_name, map_params):
"""Generate debug information metadata for BPF RINGBUF map"""
generator = DebugInfoGenerator(module)
int_type = generator.get_int32_type()
type_array = generator.create_array_type(
int_type, map_params.get("type", BPFMapType.RINGBUF).value
)
type_ptr = generator.create_pointer_type(type_array, 64)
type_member = generator.create_struct_member("type", type_ptr, 0)
max_entries_array = generator.create_array_type(int_type, map_params["max_entries"])
max_entries_ptr = generator.create_pointer_type(max_entries_array, 64)
max_entries_member = generator.create_struct_member(
"max_entries", max_entries_ptr, 64
)
elements_arr = [type_member, max_entries_member]
struct_type = generator.create_struct_type(elements_arr, 128, is_distinct=True)
global_var = generator.create_global_var_debug_info(
map_name, struct_type, is_local=False
)
map_global.set_metadata("dbg", global_var)
return global_var
@MapProcessorRegistry.register("RingBuf")
def process_ringbuf_map(map_name, rval, module):
"""Process a BPF_RINGBUF map declaration"""
logger.info(f"Processing Ringbuf: {map_name}")
map_params = {"type": BPFMapType.RINGBUF}
# Parse max_entries if present
if len(rval.args) >= 1 and isinstance(rval.args[0], ast.Constant):
const_val = rval.args[0].value
if isinstance(const_val, int):
map_params["max_entries"] = const_val
for keyword in rval.keywords:
if keyword.arg == "max_entries" and isinstance(keyword.value, ast.Constant):
const_val = keyword.value.value
if isinstance(const_val, int):
map_params["max_entries"] = const_val
logger.info(f"Ringbuf map parameters: {map_params}")
map_global = create_bpf_map(module, map_name, map_params)
create_ringbuf_debug_info(module, map_global, map_name, map_params)
return map_global
@MapProcessorRegistry.register("HashMap") @MapProcessorRegistry.register("HashMap")
def process_hash_map(map_name, rval, module): def process_hash_map(map_name, rval, module):
"""Process a BPF_HASH map declaration""" """Process a BPF_HASH map declaration"""

View File

@ -1,30 +1,51 @@
#include "vmlinux.h" // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
#include <linux/bpf.h>
#include <bpf/bpf_helpers.h> #include <bpf/bpf_helpers.h>
#include <bpf/bpf_tracing.h> #include <bpf/bpf_tracing.h>
#include <bpf/bpf_core_read.h> #include <linux/types.h>
// Define the structure to be sent via ringbuf
struct event {
__u32 pid;
__u32 uid;
__u64 timestamp;
char comm[16]; // Process name
};
// Define the ringbuffer map
struct { struct {
__uint(type, BPF_MAP_TYPE_RINGBUF); __uint(type, BPF_MAP_TYPE_RINGBUF);
__uint(max_entries, 1 << 24); // 16 MB __uint(max_entries, 256 * 1024); // 256 KB
} rb SEC(".maps"); } events SEC(".maps");
//struct msg { // Tracepoint for execve system calls
// u32 pid; SEC("tracepoint/syscalls/sys_enter_execve")
// char comm[16]; int trace_execve(void *ctx)
//}; {
struct event *e;
__u64 pid_tgid;
__u64 uid_gid;
//SEC("tracepoint/syscalls/sys_enter_execve") // Reserve space in the ringbuffer
//int handle_execve(struct trace_event_raw_sys_enter *ctx) e = bpf_ringbuf_reserve(&events, sizeof(*e), 0);
//{ if (!e)
// struct msg *m; return 0;
// 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"; // Fill the struct with data
pid_tgid = bpf_get_current_pid_tgid();
e->pid = pid_tgid >> 32;
uid_gid = bpf_get_current_uid_gid();
e->uid = uid_gid & 0xFFFFFFFF;
e->timestamp = bpf_ktime_get_ns();
bpf_get_current_comm(&e->comm, sizeof(e->comm));
// Submit the event to ringbuffer
bpf_ringbuf_submit(e, 0);
return 0;
}
char LICENSE[] SEC("license") = "GPL";

View File

@ -1,5 +1,5 @@
from pythonbpf import bpf, map, bpfglobal, section from pythonbpf import bpf, BPF, map, bpfglobal, section, compile, compile_to_ir
from pythonbpf.maps import RingBuf from pythonbpf.maps import RingBuf, HashMap
from ctypes import c_int32, c_void_p from ctypes import c_int32, c_void_p
@ -7,12 +7,19 @@ from ctypes import c_int32, c_void_p
@bpf @bpf
@map @map
def mymap() -> RingBuf: def mymap() -> RingBuf:
return RingBuf(max_entries=(1 << 24)) return RingBuf(max_entries=(1024))
@bpf
@map
def mymap2() -> HashMap:
return HashMap(key=c_int32, value=c_int32, max_entries=1024)
@bpf @bpf
@section("tracepoint/syscalls/sys_enter_clone") @section("tracepoint/syscalls/sys_enter_clone")
def testing(ctx: c_void_p) -> c_int32: def random_section(ctx: c_void_p) -> c_int32:
print("Hello")
return c_int32(0) return c_int32(0)
@ -22,4 +29,7 @@ def LICENSE() -> str:
return "GPL" return "GPL"
compile_to_ir("ringbuf.py", "ringbuf.ll")
compile() compile()
b = BPF()
b.load_and_attach()