aya_obj/
maps.rs

1//! Map struct and type bindings.
2
3use alloc::vec::Vec;
4use core::mem;
5
6#[cfg(not(feature = "std"))]
7use crate::std;
8use crate::{EbpfSectionKind, InvalidTypeBinding};
9
10impl TryFrom<u32> for crate::generated::bpf_map_type {
11    type Error = InvalidTypeBinding<u32>;
12
13    fn try_from(map_type: u32) -> Result<Self, Self::Error> {
14        use crate::generated::bpf_map_type::*;
15        Ok(match map_type {
16            x if x == BPF_MAP_TYPE_UNSPEC as u32 => BPF_MAP_TYPE_UNSPEC,
17            x if x == BPF_MAP_TYPE_HASH as u32 => BPF_MAP_TYPE_HASH,
18            x if x == BPF_MAP_TYPE_ARRAY as u32 => BPF_MAP_TYPE_ARRAY,
19            x if x == BPF_MAP_TYPE_PROG_ARRAY as u32 => BPF_MAP_TYPE_PROG_ARRAY,
20            x if x == BPF_MAP_TYPE_PERF_EVENT_ARRAY as u32 => BPF_MAP_TYPE_PERF_EVENT_ARRAY,
21            x if x == BPF_MAP_TYPE_PERCPU_HASH as u32 => BPF_MAP_TYPE_PERCPU_HASH,
22            x if x == BPF_MAP_TYPE_PERCPU_ARRAY as u32 => BPF_MAP_TYPE_PERCPU_ARRAY,
23            x if x == BPF_MAP_TYPE_STACK_TRACE as u32 => BPF_MAP_TYPE_STACK_TRACE,
24            x if x == BPF_MAP_TYPE_CGROUP_ARRAY as u32 => BPF_MAP_TYPE_CGROUP_ARRAY,
25            x if x == BPF_MAP_TYPE_LRU_HASH as u32 => BPF_MAP_TYPE_LRU_HASH,
26            x if x == BPF_MAP_TYPE_LRU_PERCPU_HASH as u32 => BPF_MAP_TYPE_LRU_PERCPU_HASH,
27            x if x == BPF_MAP_TYPE_LPM_TRIE as u32 => BPF_MAP_TYPE_LPM_TRIE,
28            x if x == BPF_MAP_TYPE_ARRAY_OF_MAPS as u32 => BPF_MAP_TYPE_ARRAY_OF_MAPS,
29            x if x == BPF_MAP_TYPE_HASH_OF_MAPS as u32 => BPF_MAP_TYPE_HASH_OF_MAPS,
30            x if x == BPF_MAP_TYPE_DEVMAP as u32 => BPF_MAP_TYPE_DEVMAP,
31            x if x == BPF_MAP_TYPE_SOCKMAP as u32 => BPF_MAP_TYPE_SOCKMAP,
32            x if x == BPF_MAP_TYPE_CPUMAP as u32 => BPF_MAP_TYPE_CPUMAP,
33            x if x == BPF_MAP_TYPE_XSKMAP as u32 => BPF_MAP_TYPE_XSKMAP,
34            x if x == BPF_MAP_TYPE_SOCKHASH as u32 => BPF_MAP_TYPE_SOCKHASH,
35            x if x == BPF_MAP_TYPE_CGROUP_STORAGE_DEPRECATED as u32 => {
36                BPF_MAP_TYPE_CGROUP_STORAGE_DEPRECATED
37            }
38            x if x == BPF_MAP_TYPE_REUSEPORT_SOCKARRAY as u32 => BPF_MAP_TYPE_REUSEPORT_SOCKARRAY,
39            x if x == BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE_DEPRECATED as u32 => {
40                BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE_DEPRECATED
41            }
42            x if x == BPF_MAP_TYPE_QUEUE as u32 => BPF_MAP_TYPE_QUEUE,
43            x if x == BPF_MAP_TYPE_STACK as u32 => BPF_MAP_TYPE_STACK,
44            x if x == BPF_MAP_TYPE_SK_STORAGE as u32 => BPF_MAP_TYPE_SK_STORAGE,
45            x if x == BPF_MAP_TYPE_DEVMAP_HASH as u32 => BPF_MAP_TYPE_DEVMAP_HASH,
46            x if x == BPF_MAP_TYPE_STRUCT_OPS as u32 => BPF_MAP_TYPE_STRUCT_OPS,
47            x if x == BPF_MAP_TYPE_RINGBUF as u32 => BPF_MAP_TYPE_RINGBUF,
48            x if x == BPF_MAP_TYPE_INODE_STORAGE as u32 => BPF_MAP_TYPE_INODE_STORAGE,
49            x if x == BPF_MAP_TYPE_TASK_STORAGE as u32 => BPF_MAP_TYPE_TASK_STORAGE,
50            x if x == BPF_MAP_TYPE_BLOOM_FILTER as u32 => BPF_MAP_TYPE_BLOOM_FILTER,
51            x if x == BPF_MAP_TYPE_USER_RINGBUF as u32 => BPF_MAP_TYPE_USER_RINGBUF,
52            x if x == BPF_MAP_TYPE_CGRP_STORAGE as u32 => BPF_MAP_TYPE_CGRP_STORAGE,
53            x if x == BPF_MAP_TYPE_ARENA as u32 => BPF_MAP_TYPE_ARENA,
54            _ => return Err(InvalidTypeBinding { value: map_type }),
55        })
56    }
57}
58
59/// BTF definition of a map
60#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
61pub struct BtfMapDef {
62    pub(crate) map_type: u32,
63    pub(crate) key_size: u32,
64    pub(crate) value_size: u32,
65    pub(crate) max_entries: u32,
66    pub(crate) map_flags: u32,
67    pub(crate) pinning: PinningType,
68    /// BTF type id of the map key
69    pub btf_key_type_id: u32,
70    /// BTF type id of the map value
71    pub btf_value_type_id: u32,
72}
73
74/// The pinning type
75///
76/// Upon pinning a map, a file representation is created for the map,
77/// so that the map can be alive and retrievable across sessions.
78#[repr(u32)]
79#[derive(Copy, Clone, Debug, PartialEq, Eq, Default)]
80pub enum PinningType {
81    /// No pinning
82    #[default]
83    None = 0,
84    /// Pin by the name
85    ByName = 1,
86}
87
88/// The error type returned when failing to parse a [PinningType]
89#[derive(Debug, thiserror::Error)]
90pub enum PinningError {
91    /// Unsupported pinning type
92    #[error("unsupported pinning type `{pinning_type}`")]
93    Unsupported {
94        /// The unsupported pinning type
95        pinning_type: u32,
96    },
97}
98
99impl TryFrom<u32> for PinningType {
100    type Error = PinningError;
101
102    fn try_from(value: u32) -> Result<Self, Self::Error> {
103        match value {
104            0 => Ok(PinningType::None),
105            1 => Ok(PinningType::ByName),
106            pinning_type => Err(PinningError::Unsupported { pinning_type }),
107        }
108    }
109}
110
111/// Map definition in legacy BPF map declaration style
112#[allow(non_camel_case_types)]
113#[repr(C)]
114#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
115pub struct bpf_map_def {
116    // minimum features required by old BPF programs
117    /// The map type
118    pub map_type: u32,
119    /// The key_size
120    pub key_size: u32,
121    /// The value size
122    pub value_size: u32,
123    /// Max entry number
124    pub max_entries: u32,
125    /// Map flags
126    pub map_flags: u32,
127    // optional features
128    /// Id
129    pub id: u32,
130    /// Pinning type
131    pub pinning: PinningType,
132}
133
134/// The first five __u32 of `bpf_map_def` must be defined.
135pub(crate) const MINIMUM_MAP_SIZE: usize = mem::size_of::<u32>() * 5;
136
137/// Map data defined in `maps` or `.maps` sections
138#[derive(Debug, Clone)]
139pub enum Map {
140    /// A map defined in the `maps` section
141    Legacy(LegacyMap),
142    /// A map defined in the `.maps` section
143    Btf(BtfMap),
144}
145
146impl Map {
147    /// Returns the map type
148    pub fn map_type(&self) -> u32 {
149        match self {
150            Map::Legacy(m) => m.def.map_type,
151            Map::Btf(m) => m.def.map_type,
152        }
153    }
154
155    /// Returns the key size in bytes
156    pub fn key_size(&self) -> u32 {
157        match self {
158            Map::Legacy(m) => m.def.key_size,
159            Map::Btf(m) => m.def.key_size,
160        }
161    }
162
163    /// Returns the value size in bytes
164    pub fn value_size(&self) -> u32 {
165        match self {
166            Map::Legacy(m) => m.def.value_size,
167            Map::Btf(m) => m.def.value_size,
168        }
169    }
170
171    /// Set the value size in bytes
172    pub fn set_value_size(&mut self, size: u32) {
173        match self {
174            Map::Legacy(m) => m.def.value_size = size,
175            Map::Btf(m) => m.def.value_size = size,
176        }
177    }
178
179    /// Returns the max entry number
180    pub fn max_entries(&self) -> u32 {
181        match self {
182            Map::Legacy(m) => m.def.max_entries,
183            Map::Btf(m) => m.def.max_entries,
184        }
185    }
186
187    /// Sets the max entry number
188    pub fn set_max_entries(&mut self, v: u32) {
189        match self {
190            Map::Legacy(m) => m.def.max_entries = v,
191            Map::Btf(m) => m.def.max_entries = v,
192        }
193    }
194
195    /// Returns the map flags
196    pub fn map_flags(&self) -> u32 {
197        match self {
198            Map::Legacy(m) => m.def.map_flags,
199            Map::Btf(m) => m.def.map_flags,
200        }
201    }
202
203    /// Returns the pinning type of the map
204    pub fn pinning(&self) -> PinningType {
205        match self {
206            Map::Legacy(m) => m.def.pinning,
207            Map::Btf(m) => m.def.pinning,
208        }
209    }
210
211    /// Returns the map data
212    pub fn data(&self) -> &[u8] {
213        match self {
214            Map::Legacy(m) => &m.data,
215            Map::Btf(m) => &m.data,
216        }
217    }
218
219    /// Returns the map data as mutable
220    pub fn data_mut(&mut self) -> &mut Vec<u8> {
221        match self {
222            Map::Legacy(m) => m.data.as_mut(),
223            Map::Btf(m) => m.data.as_mut(),
224        }
225    }
226
227    /// Returns the section index
228    pub fn section_index(&self) -> usize {
229        match self {
230            Map::Legacy(m) => m.section_index,
231            Map::Btf(m) => m.section_index,
232        }
233    }
234
235    /// Returns the section kind.
236    pub fn section_kind(&self) -> EbpfSectionKind {
237        match self {
238            Map::Legacy(m) => m.section_kind,
239            Map::Btf(_) => EbpfSectionKind::BtfMaps,
240        }
241    }
242
243    /// Returns the symbol index.
244    ///
245    /// This is `None` for data maps (.bss, .data and .rodata) since those don't
246    /// need symbols in order to be relocated.
247    pub fn symbol_index(&self) -> Option<usize> {
248        match self {
249            Map::Legacy(m) => m.symbol_index,
250            Map::Btf(m) => Some(m.symbol_index),
251        }
252    }
253}
254
255/// A map declared with legacy BPF map declaration style, most likely from a `maps` section.
256///
257/// See [Drop support for legacy BPF map declaration syntax - Libbpf: the road to v1.0](https://github.com/libbpf/libbpf/wiki/Libbpf:-the-road-to-v1.0#drop-support-for-legacy-bpf-map-declaration-syntax)
258/// for more info.
259#[derive(Debug, Clone)]
260pub struct LegacyMap {
261    /// The definition of the map
262    pub def: bpf_map_def,
263    /// The section index
264    pub section_index: usize,
265    /// The section kind
266    pub section_kind: EbpfSectionKind,
267    /// The symbol index.
268    ///
269    /// This is None for data maps (.bss .data and .rodata).  We don't need
270    /// symbols to relocate those since they don't contain multiple maps, but
271    /// are just a flat array of bytes.
272    pub symbol_index: Option<usize>,
273    /// The map data
274    pub data: Vec<u8>,
275}
276
277/// A BTF-defined map, most likely from a `.maps` section.
278#[derive(Debug, Clone)]
279pub struct BtfMap {
280    /// The definition of the map
281    pub def: BtfMapDef,
282    pub(crate) section_index: usize,
283    pub(crate) symbol_index: usize,
284    pub(crate) data: Vec<u8>,
285}