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