mirror of
https://github.com/varun-r-mallya/pylibbpf.git
synced 2026-02-12 16:11:00 +00:00
Compare commits
8 Commits
3335e0471b
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| ecd94057b7 | |||
| 68f2bc4b9b | |||
| ccce772b51 | |||
| 8ac2d67a76 | |||
| d4202cdc88 | |||
| 13554e9da9 | |||
| 9a54aedb37 | |||
| 270f4337d3 |
2
.github/workflows/format.yml
vendored
2
.github/workflows/format.yml
vendored
@ -15,7 +15,7 @@ jobs:
|
|||||||
name: Format
|
name: Format
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v6
|
||||||
- uses: actions/setup-python@v6
|
- uses: actions/setup-python@v6
|
||||||
with:
|
with:
|
||||||
python-version: "3.x"
|
python-version: "3.x"
|
||||||
|
|||||||
4
.github/workflows/pip.yml
vendored
4
.github/workflows/pip.yml
vendored
@ -18,7 +18,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v5
|
uses: actions/checkout@v6
|
||||||
with:
|
with:
|
||||||
submodules: recursive
|
submodules: recursive
|
||||||
|
|
||||||
@ -32,7 +32,7 @@ jobs:
|
|||||||
ls -la libbpf/src/ || echo "libbpf/src not found!"
|
ls -la libbpf/src/ || echo "libbpf/src not found!"
|
||||||
|
|
||||||
- name: Set up Python ${{ matrix.python-version }}
|
- name: Set up Python ${{ matrix.python-version }}
|
||||||
uses: actions/setup-python@v5
|
uses: actions/setup-python@v6
|
||||||
with:
|
with:
|
||||||
python-version: ${{ matrix.python-version }}
|
python-version: ${{ matrix.python-version }}
|
||||||
|
|
||||||
|
|||||||
12
.github/workflows/wheels.yml
vendored
12
.github/workflows/wheels.yml
vendored
@ -15,7 +15,7 @@ jobs:
|
|||||||
name: Build SDist
|
name: Build SDist
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v6
|
||||||
with:
|
with:
|
||||||
submodules: recursive
|
submodules: recursive
|
||||||
|
|
||||||
@ -25,7 +25,7 @@ jobs:
|
|||||||
- name: Check metadata
|
- name: Check metadata
|
||||||
run: pipx run twine check dist/*
|
run: pipx run twine check dist/*
|
||||||
|
|
||||||
- uses: actions/upload-artifact@v4
|
- uses: actions/upload-artifact@v5
|
||||||
with:
|
with:
|
||||||
name: cibw-sdist
|
name: cibw-sdist
|
||||||
path: dist/*.tar.gz
|
path: dist/*.tar.gz
|
||||||
@ -39,12 +39,12 @@ jobs:
|
|||||||
arch: [x86_64]
|
arch: [x86_64]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v6
|
||||||
with:
|
with:
|
||||||
submodules: recursive
|
submodules: recursive
|
||||||
|
|
||||||
- name: Build wheels
|
- name: Build wheels
|
||||||
uses: pypa/cibuildwheel@v3.2
|
uses: pypa/cibuildwheel@v3.3
|
||||||
env:
|
env:
|
||||||
CIBW_PLATFORM: linux
|
CIBW_PLATFORM: linux
|
||||||
CIBW_ARCHS_LINUX: ${{ matrix.arch }}
|
CIBW_ARCHS_LINUX: ${{ matrix.arch }}
|
||||||
@ -65,7 +65,7 @@ jobs:
|
|||||||
shell: bash
|
shell: bash
|
||||||
|
|
||||||
- name: Upload wheels
|
- name: Upload wheels
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v5
|
||||||
with:
|
with:
|
||||||
name: cibw-wheels-linux-${{ matrix.arch }}
|
name: cibw-wheels-linux-${{ matrix.arch }}
|
||||||
path: wheelhouse/*.whl
|
path: wheelhouse/*.whl
|
||||||
@ -82,7 +82,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Download all artifacts
|
- name: Download all artifacts
|
||||||
uses: actions/download-artifact@v5
|
uses: actions/download-artifact@v6
|
||||||
with:
|
with:
|
||||||
pattern: cibw-*
|
pattern: cibw-*
|
||||||
path: dist
|
path: dist
|
||||||
|
|||||||
@ -11,7 +11,7 @@
|
|||||||
</picture>
|
</picture>
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<!-- PyPI -->
|
<!-- PyPI -->
|
||||||
<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://www.python.org/downloads/release/python-3120/"><img src="https://img.shields.io/badge/python-3.12-blue.svg"></a>
|
||||||
<a href="https://pypi.org/project/pylibbpf"><img src="https://badge.fury.io/py/pylibbpf.svg"></a>
|
<a href="https://pypi.org/project/pylibbpf"><img src="https://badge.fury.io/py/pylibbpf.svg"></a>
|
||||||
<!-- <a href="https://pypi.org/project/pythonbpf/"><img src="https://img.shields.io/pypi/status/pythonbpf" alt="PyPI Status"></a> -->
|
<!-- <a href="https://pypi.org/project/pythonbpf/"><img src="https://img.shields.io/pypi/status/pythonbpf" alt="PyPI Status"></a> -->
|
||||||
<a href="https://pepy.tech/project/pylibbpf"><img src="https://pepy.tech/badge/pylibbpf" alt="Downloads"></a>
|
<a href="https://pepy.tech/project/pylibbpf"><img src="https://pepy.tech/badge/pylibbpf" alt="Downloads"></a>
|
||||||
|
|||||||
@ -43,4 +43,4 @@ __all__ = [
|
|||||||
"BpfException",
|
"BpfException",
|
||||||
]
|
]
|
||||||
|
|
||||||
__version__ = "0.0.6"
|
__version__ = "0.0.7"
|
||||||
|
|||||||
@ -10,7 +10,7 @@ build-backend = "setuptools.build_meta"
|
|||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "pylibbpf"
|
name = "pylibbpf"
|
||||||
version = "0.0.6"
|
version = "0.0.7"
|
||||||
description = "Python Bindings for Libbpf"
|
description = "Python Bindings for Libbpf"
|
||||||
authors = [
|
authors = [
|
||||||
{ name = "r41k0u", email = "pragyanshchaturvedi18@gmail.com" },
|
{ name = "r41k0u", email = "pragyanshchaturvedi18@gmail.com" },
|
||||||
|
|||||||
@ -65,6 +65,10 @@ PYBIND11_MODULE(pylibbpf, m) {
|
|||||||
.def("get_key_size", &BpfMap::get_key_size)
|
.def("get_key_size", &BpfMap::get_key_size)
|
||||||
.def("get_value_size", &BpfMap::get_value_size)
|
.def("get_value_size", &BpfMap::get_value_size)
|
||||||
.def("get_max_entries", &BpfMap::get_max_entries)
|
.def("get_max_entries", &BpfMap::get_max_entries)
|
||||||
|
.def("set_value_struct", &BpfMap::set_value_struct,
|
||||||
|
py::arg("struct_name"))
|
||||||
|
.def("get_value_struct_name", &BpfMap::get_value_struct_name)
|
||||||
|
.def("has_struct_value", &BpfMap::has_struct_value)
|
||||||
.def("__getitem__", &BpfMap::lookup, py::arg("key"))
|
.def("__getitem__", &BpfMap::lookup, py::arg("key"))
|
||||||
.def("__setitem__", &BpfMap::update, py::arg("key"), py::arg("value"))
|
.def("__setitem__", &BpfMap::update, py::arg("key"), py::arg("value"))
|
||||||
.def("__delitem__", &BpfMap::delete_elem, py::arg("key"));
|
.def("__delitem__", &BpfMap::delete_elem, py::arg("key"));
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
#include "core/bpf_map.h"
|
#include "core/bpf_map.h"
|
||||||
#include "core/bpf_exception.h"
|
#include "core/bpf_exception.h"
|
||||||
#include "core/bpf_object.h"
|
#include "core/bpf_object.h"
|
||||||
|
#include "utils/struct_parser.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cerrno>
|
#include <cerrno>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
@ -25,6 +26,24 @@ BpfMap::BpfMap(std::shared_ptr<BpfObject> parent, struct bpf_map *raw_map,
|
|||||||
value_size_ = bpf_map__value_size(map_);
|
value_size_ = bpf_map__value_size(map_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BpfMap::set_value_struct(const std::string &struct_name) {
|
||||||
|
auto parent = parent_obj_.lock();
|
||||||
|
if (!parent) {
|
||||||
|
throw BpfException("Parent BpfObject no longer exists");
|
||||||
|
}
|
||||||
|
|
||||||
|
struct_parser_ = parent->get_struct_parser();
|
||||||
|
if (!struct_parser_) {
|
||||||
|
throw BpfException("No struct definitions available in BpfObject");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!struct_parser_->has_struct(struct_name)) {
|
||||||
|
throw BpfException("Unknown struct: " + struct_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
value_struct_name_ = struct_name;
|
||||||
|
}
|
||||||
|
|
||||||
py::object BpfMap::lookup(const py::object &key) const {
|
py::object BpfMap::lookup(const py::object &key) const {
|
||||||
if (map_fd_ < 0)
|
if (map_fd_ < 0)
|
||||||
throw BpfException("Map '" + map_name_ + "' is not initialized properly");
|
throw BpfException("Map '" + map_name_ + "' is not initialized properly");
|
||||||
@ -215,7 +234,13 @@ void BpfMap::python_to_bytes_inplace(const py::object &obj,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
py::object BpfMap::bytes_to_python(std::span<const uint8_t> data) {
|
py::object BpfMap::bytes_to_python(std::span<const uint8_t> data) const {
|
||||||
|
// NOTE: Struct parsing for value type
|
||||||
|
if (struct_parser_ && !value_struct_name_.empty()) {
|
||||||
|
py::bytes py_data(reinterpret_cast<const char *>(data.data()), data.size());
|
||||||
|
return struct_parser_->parse(value_struct_name_, py_data);
|
||||||
|
}
|
||||||
|
|
||||||
if (data.size() == 4) {
|
if (data.size() == 4) {
|
||||||
uint32_t value;
|
uint32_t value;
|
||||||
std::memcpy(&value, data.data(), 4);
|
std::memcpy(&value, data.data(), 4);
|
||||||
|
|||||||
@ -9,6 +9,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
class BpfObject;
|
class BpfObject;
|
||||||
|
class StructParser;
|
||||||
|
|
||||||
namespace py = pybind11;
|
namespace py = pybind11;
|
||||||
|
|
||||||
@ -20,6 +21,11 @@ private:
|
|||||||
std::string map_name_;
|
std::string map_name_;
|
||||||
__u32 key_size_, value_size_;
|
__u32 key_size_, value_size_;
|
||||||
|
|
||||||
|
// TODO: For now, we'll only support struct parsing for value types
|
||||||
|
// later we can extend this to keys
|
||||||
|
std::shared_ptr<StructParser> struct_parser_;
|
||||||
|
std::string value_struct_name_;
|
||||||
|
|
||||||
template <size_t StackSize = 64> struct BufferManager {
|
template <size_t StackSize = 64> struct BufferManager {
|
||||||
std::array<uint8_t, StackSize> stack_buf;
|
std::array<uint8_t, StackSize> stack_buf;
|
||||||
std::vector<uint8_t> heap_buf;
|
std::vector<uint8_t> heap_buf;
|
||||||
@ -52,6 +58,7 @@ public:
|
|||||||
py::dict items() const;
|
py::dict items() const;
|
||||||
py::list keys() const;
|
py::list keys() const;
|
||||||
py::list values() const;
|
py::list values() const;
|
||||||
|
void set_value_struct(const std::string &struct_name);
|
||||||
|
|
||||||
[[nodiscard]] std::string get_name() const { return map_name_; }
|
[[nodiscard]] std::string get_name() const { return map_name_; }
|
||||||
[[nodiscard]] int get_fd() const { return map_fd_; }
|
[[nodiscard]] int get_fd() const { return map_fd_; }
|
||||||
@ -62,11 +69,17 @@ public:
|
|||||||
[[nodiscard]] std::shared_ptr<BpfObject> get_parent() const {
|
[[nodiscard]] std::shared_ptr<BpfObject> get_parent() const {
|
||||||
return parent_obj_.lock();
|
return parent_obj_.lock();
|
||||||
}
|
}
|
||||||
|
[[nodiscard]] std::string get_value_struct_name() const {
|
||||||
|
return value_struct_name_;
|
||||||
|
}
|
||||||
|
[[nodiscard]] bool has_struct_value() const {
|
||||||
|
return !value_struct_name_.empty();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void python_to_bytes_inplace(const py::object &obj,
|
static void python_to_bytes_inplace(const py::object &obj,
|
||||||
std::span<uint8_t> buffer);
|
std::span<uint8_t> buffer);
|
||||||
static py::object bytes_to_python(std::span<const uint8_t> data);
|
py::object bytes_to_python(std::span<const uint8_t> data) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // PYLIBBPF_BPF_MAP_H
|
#endif // PYLIBBPF_BPF_MAP_H
|
||||||
|
|||||||
@ -2,6 +2,6 @@ import pylibbpf as m
|
|||||||
|
|
||||||
|
|
||||||
def test_main():
|
def test_main():
|
||||||
assert m.__version__ == "0.0.6"
|
assert m.__version__ == "0.0.7"
|
||||||
prog = m.BpfObject("tests/execve2.o", structs={})
|
prog = m.BpfObject("tests/execve2.o", structs={})
|
||||||
print(prog)
|
print(prog)
|
||||||
|
|||||||
Reference in New Issue
Block a user