mirror of
https://github.com/varun-r-mallya/pylibbpf.git
synced 2025-12-31 20:36:26 +00:00
addd example and support for load and attach
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@ -9,3 +9,4 @@ _generate/
|
||||
build/
|
||||
*venv/
|
||||
.idea/
|
||||
sudo-python.sh
|
||||
|
||||
14
README.md
14
README.md
@ -1,10 +1,13 @@
|
||||
# Py-libbpf
|
||||
<p align="center">
|
||||
<a href="https://www.python.org/downloads/release/python-3080/"><img src="https://img.shields.io/badge/python-3.8-blue.svg"></a>
|
||||
<a href="https://pypi.org/project/pylibbpf"><img src="https://badge.fury.io/py/pylibbpf.svg"></a>
|
||||
</p>
|
||||
This library provides Python bindings for libbpf on Linux to make loading of eBPF object files easier. This is meant to
|
||||
be used along with `pythonbpf`, the eBPF Python DSL compiler. This library makes it possible to attach these programs to
|
||||
events in the kernel right from inside Python.
|
||||
|
||||
# Warning
|
||||
IN DEVELOPMENT. DO NOT USE.
|
||||
# IN DEVELOPMENT. DO NOT USE.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
@ -19,6 +22,7 @@ Just clone this repository and pip install. Note the `--recursive` option which
|
||||
needed for the pybind11 submodule:
|
||||
|
||||
```bash
|
||||
sudo apt install libelf-dev
|
||||
git clone --recursive https://github.com/varun-r-mallya/pylibbpf.git
|
||||
pip install .
|
||||
```
|
||||
@ -26,5 +30,11 @@ pip install .
|
||||
With the `setup.py` file included in this example, the `pip install` command will
|
||||
invoke CMake and build the pybind11 module as specified in `CMakeLists.txt`.
|
||||
|
||||
## Development
|
||||
Do this before running to make sure Python can manipulate bpf programs without sudo
|
||||
```bash
|
||||
sudo setcap cap_bpf,cap_sys_admin+ep /usr/bin/python3.12
|
||||
```
|
||||
|
||||
## Building the documentation
|
||||
The documentation here is still boilerplate.
|
||||
|
||||
41
examples/execve.py
Normal file
41
examples/execve.py
Normal file
@ -0,0 +1,41 @@
|
||||
from pythonbpf import bpf, map, section, bpfglobal, BPF
|
||||
from ctypes import c_void_p, c_int64, c_int32, c_uint64
|
||||
from pythonbpf.helpers import ktime
|
||||
from pythonbpf.maps import HashMap
|
||||
import time
|
||||
|
||||
@bpf
|
||||
@map
|
||||
def last() -> HashMap:
|
||||
return HashMap(key=c_uint64, value=c_uint64, max_entries=1)
|
||||
|
||||
|
||||
@bpf
|
||||
@section("tracepoint/syscalls/sys_enter_execve")
|
||||
def hello(ctx: c_void_p) -> c_int32:
|
||||
print("entered")
|
||||
print("multi constant support")
|
||||
return c_int32(0)
|
||||
|
||||
|
||||
@bpf
|
||||
@section("tracepoint/syscalls/sys_exit_execve")
|
||||
def hello_again(ctx: c_void_p) -> c_int64:
|
||||
print("exited")
|
||||
key = 0
|
||||
tsp = last().lookup(key)
|
||||
print(tsp)
|
||||
ts = ktime()
|
||||
return c_int64(0)
|
||||
|
||||
|
||||
@bpf
|
||||
@bpfglobal
|
||||
def LICENSE() -> str:
|
||||
return "GPL"
|
||||
|
||||
b = BPF()
|
||||
b.load_and_attach()
|
||||
while True:
|
||||
print("running")
|
||||
time.sleep(1)
|
||||
@ -33,6 +33,7 @@ PYBIND11_MODULE(pylibbpf, m) {
|
||||
.def("load", &BpfProgram::load)
|
||||
.def("attach", &BpfProgram::attach)
|
||||
// .def("detach", &BpfProgram::detach)
|
||||
.def("load_and_attach", &BpfProgram::load_and_attach)
|
||||
.def("is_loaded", &BpfProgram::is_loaded)
|
||||
.def("is_attached", &BpfProgram::is_attached);
|
||||
|
||||
|
||||
@ -1,10 +1,11 @@
|
||||
#include "bpf_program.h"
|
||||
#include "bpf_exception.h"
|
||||
#include <filesystem>
|
||||
#include <utility>
|
||||
|
||||
BpfProgram::BpfProgram(const std::string& object_path, const std::string& program_name)
|
||||
BpfProgram::BpfProgram(std::string object_path, std::string program_name)
|
||||
: obj_(nullptr), prog_(nullptr), link_(nullptr),
|
||||
object_path_(object_path), program_name_(program_name) {
|
||||
object_path_(std::move(object_path)), program_name_(std::move(program_name)) {
|
||||
}
|
||||
|
||||
BpfProgram::~BpfProgram() {
|
||||
@ -28,9 +29,12 @@ bool BpfProgram::load() {
|
||||
throw BpfException("Program '" + program_name_ + "' not found in object");
|
||||
}
|
||||
} else {
|
||||
// Use the first program if no name specified
|
||||
prog_ = bpf_object__next_program(obj_, nullptr);
|
||||
if (!prog_) {
|
||||
while ((prog_ = bpf_object__next_program(obj_, prog_)) != nullptr) {
|
||||
programs.emplace_back(prog_, nullptr);
|
||||
}
|
||||
|
||||
// throw if no programs found
|
||||
if (programs.empty()) {
|
||||
throw BpfException("No programs found in object file");
|
||||
}
|
||||
}
|
||||
@ -44,15 +48,23 @@ bool BpfProgram::load() {
|
||||
}
|
||||
|
||||
bool BpfProgram::attach() {
|
||||
if (!prog_) {
|
||||
throw BpfException("Program not loaded");
|
||||
}
|
||||
for (auto [prog, link] : programs)
|
||||
{
|
||||
if (!prog) {
|
||||
throw BpfException("Program not loaded");
|
||||
}
|
||||
|
||||
link_ = bpf_program__attach(prog_);
|
||||
if (libbpf_get_error(link_)) {
|
||||
link_ = nullptr;
|
||||
throw BpfException("Failed to attach BPF program");
|
||||
link = bpf_program__attach(prog);
|
||||
if (libbpf_get_error(link)) {
|
||||
link = nullptr;
|
||||
throw BpfException("Failed to attach BPF program");
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void BpfProgram::load_and_attach() {
|
||||
load();
|
||||
attach();
|
||||
}
|
||||
|
||||
@ -14,16 +14,17 @@ private:
|
||||
struct bpf_link* link_;
|
||||
std::string object_path_;
|
||||
std::string program_name_;
|
||||
|
||||
std::vector<std::pair<bpf_program*, bpf_link*>> programs;
|
||||
public:
|
||||
explicit BpfProgram(const std::string& object_path, const std::string& program_name = "");
|
||||
explicit BpfProgram(std::string object_path, std::string program_name = "");
|
||||
~BpfProgram();
|
||||
|
||||
bool load();
|
||||
bool attach();
|
||||
void load_and_attach();
|
||||
|
||||
bool is_loaded() const { return obj_ != nullptr; }
|
||||
bool is_attached() const { return link_ != nullptr; }
|
||||
[[nodiscard]] bool is_loaded() const { return obj_ != nullptr; }
|
||||
[[nodiscard]] bool is_attached() const { return link_ != nullptr; }
|
||||
};
|
||||
|
||||
#endif //PYLIBBPF_BPF_PROGRAM_H
|
||||
|
||||
Reference in New Issue
Block a user