xref: /DragonOS/kernel/src/bpf/map/util.rs (revision a9e28e9ce9607ebd1953898dda370c22d4f1425d)
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;
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 {
50     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 {
70     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`.
84 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