1 use crate::include::bindings::linux_bpf::{bpf_attr, bpf_map_type};
2 use alloc::string::{String, ToString};
3 use core::ffi::CStr;
4 use num_traits::FromPrimitive;
5 use system_error::SystemError;
6
7 #[derive(Debug, Clone)]
8 pub struct BpfMapMeta {
9 pub map_type: bpf_map_type,
10 pub key_size: u32,
11 pub value_size: u32,
12 pub max_entries: u32,
13 pub _map_flags: u32,
14 pub _map_name: String,
15 }
16
17 impl TryFrom<&bpf_attr> for BpfMapMeta {
18 type Error = SystemError;
try_from(value: &bpf_attr) -> Result<Self, Self::Error>19 fn try_from(value: &bpf_attr) -> Result<Self, Self::Error> {
20 let u = unsafe { &value.__bindgen_anon_1 };
21 let map_name_slice = unsafe {
22 core::slice::from_raw_parts(u.map_name.as_ptr() as *const u8, u.map_name.len())
23 };
24 let map_name = CStr::from_bytes_until_nul(map_name_slice)
25 .map_err(|_| SystemError::EINVAL)?
26 .to_str()
27 .map_err(|_| SystemError::EINVAL)?
28 .to_string();
29 let map_type = bpf_map_type::from_u32(u.map_type).ok_or(SystemError::EINVAL)?;
30 Ok(BpfMapMeta {
31 map_type,
32 key_size: u.key_size,
33 value_size: u.value_size,
34 max_entries: u.max_entries,
35 _map_flags: u.map_flags,
36 _map_name: map_name,
37 })
38 }
39 }
40
41 #[derive(Debug)]
42 pub struct BpfMapUpdateArg {
43 pub map_fd: u32,
44 pub key: u64,
45 pub value: u64,
46 pub flags: u64,
47 }
48
49 impl From<&bpf_attr> for BpfMapUpdateArg {
from(value: &bpf_attr) -> Self50 fn from(value: &bpf_attr) -> Self {
51 unsafe {
52 let u = &value.__bindgen_anon_2;
53 BpfMapUpdateArg {
54 map_fd: u.map_fd,
55 key: u.key,
56 value: u.__bindgen_anon_1.value,
57 flags: u.flags,
58 }
59 }
60 }
61 }
62 #[derive(Debug)]
63 pub struct BpfMapGetNextKeyArg {
64 pub map_fd: u32,
65 pub key: Option<u64>,
66 pub next_key: u64,
67 }
68
69 impl From<&bpf_attr> for BpfMapGetNextKeyArg {
from(value: &bpf_attr) -> Self70 fn from(value: &bpf_attr) -> Self {
71 unsafe {
72 let u = &value.__bindgen_anon_2;
73 BpfMapGetNextKeyArg {
74 map_fd: u.map_fd,
75 key: if u.key != 0 { Some(u.key) } else { None },
76 next_key: u.__bindgen_anon_1.next_key,
77 }
78 }
79 }
80 }
81
82 #[inline]
83 /// Round up `x` to the nearest multiple of `align`.
round_up(x: usize, align: usize) -> usize84 pub fn round_up(x: usize, align: usize) -> usize {
85 (x + align - 1) & !(align - 1)
86 }
87
88 bitflags! {
89 /// flags for BPF_MAP_UPDATE_ELEM command
90 pub struct BpfMapUpdateElemFlags: u64 {
91 /// create new element or update existing
92 const BPF_ANY = 0;
93 /// create new element if it didn't exist
94 const BPF_NOEXIST = 1;
95 /// update existing element
96 const BPF_EXIST = 2;
97 /// spin_lock-ed map_lookup/map_update
98 const BPF_F_LOCK = 4;
99 }
100 }
101