diff --git a/libbpf-rs/CHANGELOG.md b/libbpf-rs/CHANGELOG.md index 3cbfeb539..da9b6e00c 100644 --- a/libbpf-rs/CHANGELOG.md +++ b/libbpf-rs/CHANGELOG.md @@ -7,6 +7,8 @@ Unreleased - Adjusted `opts` to return a reference to `libbpf_sys::bpf_object_open_opts` - Removed object name argument from `open_memory` constructor - Added `pin_root_path` setter +- Added `AsLibbpfObject` trait as a unified way to retrieve `libbpf` equivalents + for `libbpf-rs` objects - Implemented `Send` for `Link` - Updated `bitflags` dependency to `2.0` diff --git a/libbpf-rs/src/btf/mod.rs b/libbpf-rs/src/btf/mod.rs index 8eb2a68e8..a0dbf5cab 100644 --- a/libbpf-rs/src/btf/mod.rs +++ b/libbpf-rs/src/btf/mod.rs @@ -31,14 +31,16 @@ use std::os::unix::prelude::OwnedFd; use std::path::Path; use std::ptr::NonNull; +use num_enum::IntoPrimitive; +use num_enum::TryFromPrimitive; + use crate::libbpf_sys; use crate::util::create_bpf_entity_checked; use crate::util::create_bpf_entity_checked_opt; use crate::util::parse_ret_i32; +use crate::AsLibbpfObject; use crate::Error; use crate::Result; -use num_enum::IntoPrimitive; -use num_enum::TryFromPrimitive; use self::types::Composite; @@ -339,6 +341,15 @@ impl<'btf> Btf<'btf> { } } +impl AsLibbpfObject for Btf<'_> { + type LibbpfType = libbpf_sys::btf; + + /// Retrieve the underlying [`libbpf_sys::btf`] object. + fn as_libbpf_object(&self) -> NonNull { + self.ptr + } +} + impl Drop for Btf<'_> { fn drop(&mut self) { match self.drop_policy { diff --git a/libbpf-rs/src/lib.rs b/libbpf-rs/src/lib.rs index 4912c2143..4decf1052 100644 --- a/libbpf-rs/src/lib.rs +++ b/libbpf-rs/src/lib.rs @@ -109,6 +109,7 @@ pub use crate::map::MapHandle; pub use crate::map::MapInfo; pub use crate::map::MapType; pub use crate::map::OpenMap; +pub use crate::object::AsLibbpfObject; pub use crate::object::Object; pub use crate::object::ObjectBuilder; pub use crate::object::OpenObject; diff --git a/libbpf-rs/src/link.rs b/libbpf-rs/src/link.rs index ffa057b34..2f3ef1433 100644 --- a/libbpf-rs/src/link.rs +++ b/libbpf-rs/src/link.rs @@ -7,6 +7,7 @@ use std::ptr::NonNull; use crate::libbpf_sys; use crate::util; +use crate::AsLibbpfObject; use crate::Program; use crate::Result; @@ -105,6 +106,15 @@ impl Link { } } +impl AsLibbpfObject for Link { + type LibbpfType = libbpf_sys::bpf_link; + + /// Retrieve the underlying [`libbpf_sys::bpf_link`]. + fn as_libbpf_object(&self) -> NonNull { + self.ptr + } +} + // SAFETY: `bpf_link` objects can safely be sent to a different thread. unsafe impl Send for Link {} diff --git a/libbpf-rs/src/linker.rs b/libbpf-rs/src/linker.rs index b141d6ff4..4113077e2 100644 --- a/libbpf-rs/src/linker.rs +++ b/libbpf-rs/src/linker.rs @@ -2,8 +2,9 @@ use std::path::Path; use std::ptr::null_mut; use std::ptr::NonNull; +use crate::util; use crate::util::path_to_cstring; -use crate::util::{self}; +use crate::AsLibbpfObject; use crate::Error; use crate::Result; @@ -62,6 +63,15 @@ impl Linker { } } +impl AsLibbpfObject for Linker { + type LibbpfType = libbpf_sys::bpf_linker; + + /// Retrieve the underlying [`libbpf_sys::bpf_linker`]. + fn as_libbpf_object(&self) -> NonNull { + self.linker + } +} + // SAFETY: `bpf_linker` can be sent to a different thread. unsafe impl Send for Linker {} diff --git a/libbpf-rs/src/map.rs b/libbpf-rs/src/map.rs index d1a45fd24..7ece1775f 100644 --- a/libbpf-rs/src/map.rs +++ b/libbpf-rs/src/map.rs @@ -31,6 +31,7 @@ use strum_macros::Display; use crate::util; use crate::util::parse_ret_i32; +use crate::AsLibbpfObject; use crate::Error; use crate::Link; use crate::Result; @@ -170,6 +171,15 @@ impl OpenMap { } } +impl AsLibbpfObject for OpenMap { + type LibbpfType = libbpf_sys::bpf_map; + + /// Retrieve the underlying [`libbpf_sys::bpf_map`]. + fn as_libbpf_object(&self) -> NonNull { + self.ptr + } +} + #[derive(Debug)] enum MapFd { Owned(OwnedFd), @@ -302,9 +312,13 @@ impl Map { Link::new(ptr) }) } +} + +impl AsLibbpfObject for Map { + type LibbpfType = libbpf_sys::bpf_map; /// Retrieve the underlying [`libbpf_sys::bpf_map`]. - pub fn as_libbpf_bpf_map_ptr(&self) -> NonNull { + fn as_libbpf_object(&self) -> NonNull { self.ptr } } diff --git a/libbpf-rs/src/object.rs b/libbpf-rs/src/object.rs index 2d235fa1e..cd0f56597 100644 --- a/libbpf-rs/src/object.rs +++ b/libbpf-rs/src/object.rs @@ -4,8 +4,8 @@ use std::ffi::CStr; use std::ffi::CString; use std::mem; use std::path::Path; +use std::ptr; use std::ptr::NonNull; -use std::ptr::{self}; use crate::libbpf_sys; use crate::set_print; @@ -19,6 +19,26 @@ use crate::PrintLevel; use crate::Program; use crate::Result; +/// A trait implemented for types that are thin wrappers around `libbpf` types. +/// +/// The trait provides access to the underlying `libbpf` (or `libbpf-sys`) +/// object. In many cases, this enables direct usage of `libbpf-sys` +/// functionality when higher-level bindings are not yet provided by this crate. +pub trait AsLibbpfObject { + /// The underlying `libbpf` type. + type LibbpfType; + + /// Retrieve the underlying `libbpf` object. + /// + /// # Warning + /// By virtue of working with a mutable raw pointer this method effectively + /// circumvents mutability and liveness checks. While by-design, usage is + /// meant as an escape-hatch more than anything else. If you find yourself + /// making use of it, please consider discussing your workflow with crate + /// maintainers to see if it would make sense to provide safer wrappers. + fn as_libbpf_object(&self) -> NonNull; +} + /// Builder for creating an [`OpenObject`]. Typically the entry point into libbpf-rs. #[derive(Debug)] pub struct ObjectBuilder { @@ -430,9 +450,13 @@ impl Object { pub fn progs_iter_mut(&mut self) -> impl Iterator { self.progs.values_mut() } +} + +impl AsLibbpfObject for Object { + type LibbpfType = libbpf_sys::bpf_object; /// Retrieve the underlying [`libbpf_sys::bpf_object`]. - pub fn as_libbpf_bpf_object_ptr(&self) -> NonNull { + fn as_libbpf_object(&self) -> NonNull { self.ptr } } diff --git a/libbpf-rs/src/perf_buffer.rs b/libbpf-rs/src/perf_buffer.rs index 79d0b8a36..e7449f022 100644 --- a/libbpf-rs/src/perf_buffer.rs +++ b/libbpf-rs/src/perf_buffer.rs @@ -11,6 +11,7 @@ use std::time::Duration; use crate::libbpf_sys; use crate::util; +use crate::AsLibbpfObject; use crate::Error; use crate::Map; use crate::MapType; @@ -227,9 +228,13 @@ impl PerfBuffer<'_> { }; util::parse_ret_i32(ret) } +} + +impl AsLibbpfObject for PerfBuffer<'_> { + type LibbpfType = libbpf_sys::perf_buffer; /// Retrieve the underlying [`libbpf_sys::perf_buffer`]. - pub fn as_libbpf_perf_buffer_ptr(&self) -> NonNull { + fn as_libbpf_object(&self) -> NonNull { self.ptr } } diff --git a/libbpf-rs/src/print.rs b/libbpf-rs/src/print.rs index 3ddd417a8..81f4c305d 100644 --- a/libbpf-rs/src/print.rs +++ b/libbpf-rs/src/print.rs @@ -1,7 +1,7 @@ use crate::libbpf_sys; use lazy_static::lazy_static; +use std::io; use std::io::Write; -use std::io::{self}; use std::os::raw::c_char; use std::sync::Mutex; diff --git a/libbpf-rs/src/program.rs b/libbpf-rs/src/program.rs index 45f095dd0..bd20f50b7 100644 --- a/libbpf-rs/src/program.rs +++ b/libbpf-rs/src/program.rs @@ -17,6 +17,7 @@ use strum_macros::Display; use crate::libbpf_sys; use crate::util; +use crate::AsLibbpfObject; use crate::Error; use crate::Link; use crate::Result; @@ -231,6 +232,15 @@ impl OpenProgram { } } +impl AsLibbpfObject for Program { + type LibbpfType = libbpf_sys::bpf_program; + + /// Retrieve the underlying [`libbpf_sys::bpf_program`]. + fn as_libbpf_object(&self) -> NonNull { + self.ptr + } +} + /// Type of a [`Program`]. Maps to `enum bpf_prog_type` in kernel uapi. #[non_exhaustive] #[repr(u32)] diff --git a/libbpf-rs/src/ringbuf.rs b/libbpf-rs/src/ringbuf.rs index f70b1bbd6..6b33fd44d 100644 --- a/libbpf-rs/src/ringbuf.rs +++ b/libbpf-rs/src/ringbuf.rs @@ -14,6 +14,7 @@ use std::time::Duration; use crate::libbpf_sys; use crate::util; +use crate::AsLibbpfObject; use crate::Error; use crate::MapHandle; use crate::MapType; @@ -182,6 +183,15 @@ impl RingBuffer<'_> { } } +impl AsLibbpfObject for RingBuffer<'_> { + type LibbpfType = libbpf_sys::ring_buffer; + + /// Retrieve the underlying [`libbpf_sys::ring_buffer`]. + fn as_libbpf_object(&self) -> NonNull { + self.ptr + } +} + // SAFETY: `ring_buffer` objects can safely be polled from any thread. unsafe impl Send for RingBuffer<'_> {} diff --git a/libbpf-rs/src/skeleton.rs b/libbpf-rs/src/skeleton.rs index e821277fe..985ba48b9 100644 --- a/libbpf-rs/src/skeleton.rs +++ b/libbpf-rs/src/skeleton.rs @@ -7,8 +7,8 @@ use std::ffi::CString; use std::mem::size_of; use std::os::raw::c_char; use std::os::raw::c_ulong; +use std::ptr; use std::ptr::NonNull; -use std::ptr::{self}; use libbpf_sys::bpf_link; use libbpf_sys::bpf_map; diff --git a/libbpf-rs/tests/test.rs b/libbpf-rs/tests/test.rs index 198aa27d1..d15e60207 100644 --- a/libbpf-rs/tests/test.rs +++ b/libbpf-rs/tests/test.rs @@ -23,6 +23,7 @@ use std::ptr; use tempfile::NamedTempFile; use libbpf_rs::num_possible_cpus; +use libbpf_rs::AsLibbpfObject; use libbpf_rs::Iter; use libbpf_rs::Linker; use libbpf_rs::Map; @@ -1430,7 +1431,7 @@ fn test_object_link_files() { /// Get access to the underlying per-cpu ring buffer data. fn buffer<'a>(perf: &'a libbpf_rs::PerfBuffer, buf_idx: usize) -> &'a [u8] { - let perf_buff_ptr = perf.as_libbpf_perf_buffer_ptr(); + let perf_buff_ptr = perf.as_libbpf_object(); let mut buffer_data_ptr: *mut c_void = ptr::null_mut(); let mut buffer_size: usize = 0; let ret = unsafe {