1use 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#[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 pub btf_key_type_id: u32,
70 pub btf_value_type_id: u32,
72}
73
74#[repr(u32)]
79#[derive(Copy, Clone, Debug, PartialEq, Eq, Default)]
80pub enum PinningType {
81 #[default]
83 None = 0,
84 ByName = 1,
86}
87
88#[derive(Debug, thiserror::Error)]
90pub enum PinningError {
91 #[error("unsupported pinning type `{pinning_type}`")]
93 Unsupported {
94 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#[allow(non_camel_case_types)]
113#[repr(C)]
114#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
115pub struct bpf_map_def {
116 pub map_type: u32,
119 pub key_size: u32,
121 pub value_size: u32,
123 pub max_entries: u32,
125 pub map_flags: u32,
127 pub id: u32,
130 pub pinning: PinningType,
132}
133
134pub(crate) const MINIMUM_MAP_SIZE: usize = mem::size_of::<u32>() * 5;
136
137#[derive(Debug, Clone)]
139pub enum Map {
140 Legacy(LegacyMap),
142 Btf(BtfMap),
144}
145
146impl Map {
147 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 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 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 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 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 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 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 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 pub fn data(&self) -> &[u8] {
213 match self {
214 Map::Legacy(m) => &m.data,
215 Map::Btf(m) => &m.data,
216 }
217 }
218
219 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 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 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 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#[derive(Debug, Clone)]
260pub struct LegacyMap {
261 pub def: bpf_map_def,
263 pub section_index: usize,
265 pub section_kind: EbpfSectionKind,
267 pub symbol_index: Option<usize>,
273 pub data: Vec<u8>,
275}
276
277#[derive(Debug, Clone)]
279pub struct BtfMap {
280 pub def: BtfMapDef,
282 pub(crate) section_index: usize,
283 pub(crate) symbol_index: usize,
284 pub(crate) data: Vec<u8>,
285}