ebpf_kern/
ring_buffer.rs

1use core::{ptr, ffi::{c_void, c_int}};
2
3use super::helpers;
4
5#[allow(dead_code)]
6pub struct RingBuffer<const MAX_ENTRIES: usize> {
7    ty__: *mut [u32; 27],
8    max_entries: *mut [u32; MAX_ENTRIES],
9}
10
11impl<const MAX_ENTRIES: usize> RingBuffer<MAX_ENTRIES> {
12    pub const fn new() -> Self {
13        RingBuffer {
14            ty__: ptr::null_mut(),
15            max_entries: ptr::null_mut(),
16        }
17    }
18}
19
20pub struct RingBufferRef {
21    inner: usize,
22}
23
24pub struct RingBufferData {
25    inner: &'static mut [u8],
26}
27
28impl AsMut<[u8]> for RingBufferData {
29    #[inline(always)]
30    fn as_mut(&mut self) -> &mut [u8] {
31        self.inner
32    }
33}
34
35impl AsRef<[u8]> for RingBufferData {
36    #[inline(always)]
37    fn as_ref(&self) -> &[u8] {
38        self.inner
39    }
40}
41
42impl RingBufferRef {
43    pub fn new<const MAX_ENTRIES: usize>(inner: &mut RingBuffer<MAX_ENTRIES>) -> Self {
44        RingBufferRef {
45            inner: inner as *mut _ as usize,
46        }
47    }
48
49    #[inline(always)]
50    fn inner(&mut self) -> *mut c_void {
51        self.inner as *mut _
52    }
53
54    #[inline(always)]
55    pub fn output(&mut self, data: &[u8]) -> Result<(), i32> {
56        let code = unsafe {
57            helpers::ringbuf_output(self.inner(), data.as_ptr() as *mut _, data.len() as _, 0)
58        };
59        if code == 0 {
60            Ok(())
61        } else {
62            Err(code as _)
63        }
64    }
65
66    #[inline(always)]
67    pub fn reserve(&mut self, size: usize) -> Result<RingBufferData, c_int> {
68        use core::mem;
69
70        let data_ptr = unsafe { helpers::ringbuf_reserve(self.inner(), size as _, 0) };
71        if data_ptr.is_null() {
72            Err(-90)
73        } else {
74            Ok(RingBufferData {
75                inner: //unsafe { slice::from_raw_parts_mut(data_ptr as *mut _, size) },
76                // it is really unsafe, the code become invalid if compiler change
77                // the metadata format
78                unsafe { mem::transmute((data_ptr, size)) },
79            })
80        }
81    }
82}
83
84impl RingBufferData {
85    #[inline(always)]
86    pub fn submit(self) {
87        unsafe { helpers::ringbuf_submit(self.inner.as_mut_ptr() as *mut _, 0) };
88    }
89
90    #[inline(always)]
91    pub fn discard(self) {
92        unsafe { helpers::ringbuf_discard(self.inner.as_mut_ptr() as *mut _, 0) };
93    }
94}