ebpf_kern/
map.rs

1use core::{ptr, ffi::c_void};
2
3use super::helpers;
4
5#[allow(dead_code)]
6pub struct ArrayPerCpu<const VALUE_SIZE: usize, const MAX_ENTRIES: usize> {
7    ty__: *mut [u32; 6],
8    key_size: *mut [u32; 4],
9    value_size: *mut [u32; VALUE_SIZE],
10    max_entries: *mut [u32; MAX_ENTRIES],
11}
12
13impl<const V: usize, const M: usize> ArrayPerCpu<V, M> {
14    pub const fn new() -> Self {
15        ArrayPerCpu {
16            ty__: ptr::null_mut(),
17            key_size: ptr::null_mut(),
18            value_size: ptr::null_mut(),
19            max_entries: ptr::null_mut(),
20        }
21    }
22}
23
24pub struct ArrayPerCpuRef<const V: usize> {
25    inner: usize,
26}
27
28impl<const V: usize> ArrayPerCpuRef<V> {
29    #[inline(always)]
30    pub fn new<const M: usize>(inner: &mut ArrayPerCpu<V, M>) -> Self {
31        ArrayPerCpuRef {
32            inner: inner as *mut _ as usize,
33        }
34    }
35
36    #[inline(always)]
37    fn inner(&self) -> *mut c_void {
38        self.inner as *mut _
39    }
40
41    #[inline(always)]
42    pub fn get(&self, index: u32) -> Option<&[u8; V]> {
43        let key = index.to_ne_bytes();
44        unsafe {
45            let v = helpers::map_lookup_elem(self.inner(), key.as_ptr() as _);
46            if v.is_null() {
47                None
48            } else {
49                Some(&*(v as *const [u8; V]))
50            }
51        }
52    }
53
54    #[inline(always)]
55    pub fn get_mut(&mut self, index: u32) -> Option<&mut [u8; V]> {
56        let key = index.to_ne_bytes();
57        unsafe {
58            let v = helpers::map_lookup_elem(self.inner(), key.as_ptr() as _);
59            if v.is_null() {
60                None
61            } else {
62                Some(&mut *(v as *mut [u8; V]))
63            }
64        }
65    }
66}
67
68#[allow(dead_code)]
69pub struct HashMap<const KEY_SIZE: usize, const VALUE_SIZE: usize, const MAX_ENTRIES: usize> {
70    ty__: *mut [u32; 1],
71    key_size: *mut [u32; KEY_SIZE],
72    value_size: *mut [u32; VALUE_SIZE],
73    max_entries: *mut [u32; MAX_ENTRIES],
74}
75
76impl<const K: usize, const V: usize, const M: usize> HashMap<K, V, M> {
77    pub const fn new() -> Self {
78        HashMap {
79            ty__: ptr::null_mut(),
80            key_size: ptr::null_mut(),
81            value_size: ptr::null_mut(),
82            max_entries: ptr::null_mut(),
83        }
84    }
85}
86
87pub struct HashMapRef<const K: usize, const V: usize> {
88    inner: usize,
89}
90
91impl<const K: usize, const V: usize> HashMapRef<K, V> {
92    #[inline(always)]
93    pub fn new<const M: usize>(inner: &mut HashMap<K, V, M>) -> Self {
94        HashMapRef {
95            inner: inner as *mut _ as usize,
96        }
97    }
98
99    #[inline(always)]
100    fn inner(&self) -> *mut c_void {
101        self.inner as *mut _
102    }
103
104    #[inline(always)]
105    pub fn insert_unsafe<T>(&mut self, key: [u8; K], value: T) -> Result<(), i32> {
106        let value = &value as *const T as _;
107        let key = &key as *const [u8] as *const u8 as *const _;
108        let c = unsafe {
109            helpers::map_update_elem(self.inner(), key, value, 0)
110        };
111        if c >= 0 {
112            Ok(())
113        } else {
114            Err(c as _)
115        }
116    }
117
118    #[inline(always)]
119    pub fn get_unsafe<T>(&self, key: &[u8; K]) -> Option<&T> {
120        let key = key as *const [u8] as *const u8 as *const _;
121        unsafe {
122            let v = helpers::map_lookup_elem(self.inner(), key);
123            if v.is_null() {
124                None
125            } else {
126                Some(&*(v as *const T))
127            }
128        }
129    }
130
131    #[inline(always)]
132    pub fn get_mut_unsafe<T>(&self, key: &[u8; K]) -> Option<&mut T> {
133        let key = key as *const [u8] as *const u8 as *const _;
134        unsafe {
135            let v = helpers::map_lookup_elem(self.inner(), key);
136            if v.is_null() {
137                None
138            } else {
139                Some(&mut *(v as *mut T))
140            }
141        }
142    }
143
144    #[inline(always)]
145    pub fn insert(&mut self, key: [u8; K], value: [u8; V]) -> Result<(), i32> {
146        let c = unsafe {
147            helpers::map_update_elem(self.inner(), key.as_ptr() as _, value.as_ptr() as _, 0)
148        };
149        if c >= 0 {
150            Ok(())
151        } else {
152            Err(c as _)
153        }
154    }
155
156    #[inline(always)]
157    pub fn get(&self, key: &[u8; K]) -> Option<&[u8; V]> {
158        unsafe {
159            let v = helpers::map_lookup_elem(self.inner(), key.as_ptr() as _);
160            if v.is_null() {
161                None
162            } else {
163                Some(&*(v as *const [u8; V]))
164            }
165        }
166    }
167
168    #[inline(always)]
169    pub fn get_mut(&mut self, key: &[u8; K]) -> Option<&mut [u8; V]> {
170        unsafe {
171            let v = helpers::map_lookup_elem(self.inner(), key.as_ptr() as _);
172            if v.is_null() {
173                None
174            } else {
175                Some(&mut *(v as *mut [u8; V]))
176            }
177        }
178    }
179
180    #[inline(always)]
181    pub fn remove(&mut self, key: &[u8; K]) -> Result<Option<[u8; V]>, i32> {
182        match self.get(key) {
183            Some(v) => {
184                let c = unsafe { helpers::map_delete_elem(self.inner(), key.as_ptr() as _) };
185                if c >= 0 {
186                    Ok(Some(*v))
187                } else {
188                    Err(c as _)
189                }
190            },
191            None => Ok(None),
192        }
193    }
194
195    #[inline(always)]
196    pub fn remove_unsafe<T>(&mut self, key: &[u8; K]) -> Result<Option<T>, i32>
197    where
198        T: Copy,
199    {
200        match self.get_unsafe(key) {
201            Some(v) => {
202                let c = unsafe { helpers::map_delete_elem(self.inner(), key.as_ptr() as _) };
203                if c >= 0 {
204                    Ok(Some(*v))
205                } else {
206                    Err(c as _)
207                }
208            },
209            None => Ok(None),
210        }
211    }
212}