1use alloc::vec::Vec;
4use core::mem;
5
6use crate::{EbpfSectionKind, InvalidTypeBinding};
7
8impl TryFrom<u32> for crate::generated::bpf_map_type {
9 type Error = InvalidTypeBinding<u32>;
10
11 fn try_from(map_type: u32) -> Result<Self, Self::Error> {
12 use crate::generated::bpf_map_type::*;
13 Ok(match map_type {
14 x if x == BPF_MAP_TYPE_UNSPEC as u32 => BPF_MAP_TYPE_UNSPEC,
15 x if x == BPF_MAP_TYPE_HASH as u32 => BPF_MAP_TYPE_HASH,
16 x if x == BPF_MAP_TYPE_ARRAY as u32 => BPF_MAP_TYPE_ARRAY,
17 x if x == BPF_MAP_TYPE_PROG_ARRAY as u32 => BPF_MAP_TYPE_PROG_ARRAY,
18 x if x == BPF_MAP_TYPE_PERF_EVENT_ARRAY as u32 => BPF_MAP_TYPE_PERF_EVENT_ARRAY,
19 x if x == BPF_MAP_TYPE_PERCPU_HASH as u32 => BPF_MAP_TYPE_PERCPU_HASH,
20 x if x == BPF_MAP_TYPE_PERCPU_ARRAY as u32 => BPF_MAP_TYPE_PERCPU_ARRAY,
21 x if x == BPF_MAP_TYPE_STACK_TRACE as u32 => BPF_MAP_TYPE_STACK_TRACE,
22 x if x == BPF_MAP_TYPE_CGROUP_ARRAY as u32 => BPF_MAP_TYPE_CGROUP_ARRAY,
23 x if x == BPF_MAP_TYPE_LRU_HASH as u32 => BPF_MAP_TYPE_LRU_HASH,
24 x if x == BPF_MAP_TYPE_LRU_PERCPU_HASH as u32 => BPF_MAP_TYPE_LRU_PERCPU_HASH,
25 x if x == BPF_MAP_TYPE_LPM_TRIE as u32 => BPF_MAP_TYPE_LPM_TRIE,
26 x if x == BPF_MAP_TYPE_ARRAY_OF_MAPS as u32 => BPF_MAP_TYPE_ARRAY_OF_MAPS,
27 x if x == BPF_MAP_TYPE_HASH_OF_MAPS as u32 => BPF_MAP_TYPE_HASH_OF_MAPS,
28 x if x == BPF_MAP_TYPE_DEVMAP as u32 => BPF_MAP_TYPE_DEVMAP,
29 x if x == BPF_MAP_TYPE_SOCKMAP as u32 => BPF_MAP_TYPE_SOCKMAP,
30 x if x == BPF_MAP_TYPE_CPUMAP as u32 => BPF_MAP_TYPE_CPUMAP,
31 x if x == BPF_MAP_TYPE_XSKMAP as u32 => BPF_MAP_TYPE_XSKMAP,
32 x if x == BPF_MAP_TYPE_SOCKHASH as u32 => BPF_MAP_TYPE_SOCKHASH,
33 x if x == BPF_MAP_TYPE_CGROUP_STORAGE_DEPRECATED as u32 => {
34 BPF_MAP_TYPE_CGROUP_STORAGE_DEPRECATED
35 }
36 x if x == BPF_MAP_TYPE_REUSEPORT_SOCKARRAY as u32 => BPF_MAP_TYPE_REUSEPORT_SOCKARRAY,
37 x if x == BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE_DEPRECATED as u32 => {
38 BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE_DEPRECATED
39 }
40 x if x == BPF_MAP_TYPE_QUEUE as u32 => BPF_MAP_TYPE_QUEUE,
41 x if x == BPF_MAP_TYPE_STACK as u32 => BPF_MAP_TYPE_STACK,
42 x if x == BPF_MAP_TYPE_SK_STORAGE as u32 => BPF_MAP_TYPE_SK_STORAGE,
43 x if x == BPF_MAP_TYPE_DEVMAP_HASH as u32 => BPF_MAP_TYPE_DEVMAP_HASH,
44 x if x == BPF_MAP_TYPE_STRUCT_OPS as u32 => BPF_MAP_TYPE_STRUCT_OPS,
45 x if x == BPF_MAP_TYPE_RINGBUF as u32 => BPF_MAP_TYPE_RINGBUF,
46 x if x == BPF_MAP_TYPE_INODE_STORAGE as u32 => BPF_MAP_TYPE_INODE_STORAGE,
47 x if x == BPF_MAP_TYPE_TASK_STORAGE as u32 => BPF_MAP_TYPE_TASK_STORAGE,
48 x if x == BPF_MAP_TYPE_BLOOM_FILTER as u32 => BPF_MAP_TYPE_BLOOM_FILTER,
49 x if x == BPF_MAP_TYPE_USER_RINGBUF as u32 => BPF_MAP_TYPE_USER_RINGBUF,
50 x if x == BPF_MAP_TYPE_CGRP_STORAGE as u32 => BPF_MAP_TYPE_CGRP_STORAGE,
51 x if x == BPF_MAP_TYPE_ARENA as u32 => BPF_MAP_TYPE_ARENA,
52 _ => return Err(InvalidTypeBinding { value: map_type }),
53 })
54 }
55}
56
57#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
59pub struct BtfMapDef {
60 pub(crate) map_type: u32,
61 pub(crate) key_size: u32,
62 pub(crate) value_size: u32,
63 pub(crate) max_entries: u32,
64 pub(crate) map_flags: u32,
65 pub(crate) pinning: PinningType,
66 pub btf_key_type_id: u32,
68 pub btf_value_type_id: u32,
70}
71
72#[repr(u32)]
77#[derive(Copy, Clone, Debug, PartialEq, Eq, Default)]
78pub enum PinningType {
79 #[default]
81 None = 0,
82 ByName = 1,
84}
85
86#[derive(Debug, thiserror::Error)]
88pub enum PinningError {
89 #[error("unsupported pinning type `{pinning_type}`")]
91 Unsupported {
92 pinning_type: u32,
94 },
95}
96
97impl TryFrom<u32> for PinningType {
98 type Error = PinningError;
99
100 fn try_from(value: u32) -> Result<Self, Self::Error> {
101 match value {
102 0 => Ok(Self::None),
103 1 => Ok(Self::ByName),
104 pinning_type => Err(PinningError::Unsupported { pinning_type }),
105 }
106 }
107}
108
109#[repr(C)]
111#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
112pub struct bpf_map_def {
113 pub map_type: u32,
116 pub key_size: u32,
118 pub value_size: u32,
120 pub max_entries: u32,
122 pub map_flags: u32,
124 pub id: u32,
127 pub pinning: PinningType,
129}
130
131pub(crate) const MINIMUM_MAP_SIZE: usize = mem::size_of::<u32>() * 5;
133
134#[derive(Debug, Clone)]
136pub enum Map {
137 Legacy(LegacyMap),
139 Btf(BtfMap),
141}
142
143impl Map {
144 pub fn map_type(&self) -> u32 {
146 match self {
147 Self::Legacy(m) => m.def.map_type,
148 Self::Btf(m) => m.def.map_type,
149 }
150 }
151
152 pub fn key_size(&self) -> u32 {
154 match self {
155 Self::Legacy(m) => m.def.key_size,
156 Self::Btf(m) => m.def.key_size,
157 }
158 }
159
160 pub fn value_size(&self) -> u32 {
162 match self {
163 Self::Legacy(m) => m.def.value_size,
164 Self::Btf(m) => m.def.value_size,
165 }
166 }
167
168 pub fn set_value_size(&mut self, size: u32) {
170 match self {
171 Self::Legacy(m) => m.def.value_size = size,
172 Self::Btf(m) => m.def.value_size = size,
173 }
174 }
175
176 pub fn max_entries(&self) -> u32 {
178 match self {
179 Self::Legacy(m) => m.def.max_entries,
180 Self::Btf(m) => m.def.max_entries,
181 }
182 }
183
184 pub fn set_max_entries(&mut self, v: u32) {
186 match self {
187 Self::Legacy(m) => m.def.max_entries = v,
188 Self::Btf(m) => m.def.max_entries = v,
189 }
190 }
191
192 pub fn map_flags(&self) -> u32 {
194 match self {
195 Self::Legacy(m) => m.def.map_flags,
196 Self::Btf(m) => m.def.map_flags,
197 }
198 }
199
200 pub fn pinning(&self) -> PinningType {
202 match self {
203 Self::Legacy(m) => m.def.pinning,
204 Self::Btf(m) => m.def.pinning,
205 }
206 }
207
208 pub fn data(&self) -> &[u8] {
210 match self {
211 Self::Legacy(m) => &m.data,
212 Self::Btf(m) => &m.data,
213 }
214 }
215
216 pub fn data_mut(&mut self) -> &mut Vec<u8> {
218 match self {
219 Self::Legacy(m) => m.data.as_mut(),
220 Self::Btf(m) => m.data.as_mut(),
221 }
222 }
223
224 pub fn section_index(&self) -> usize {
226 match self {
227 Self::Legacy(m) => m.section_index,
228 Self::Btf(m) => m.section_index,
229 }
230 }
231
232 pub fn section_kind(&self) -> EbpfSectionKind {
234 match self {
235 Self::Legacy(m) => m.section_kind,
236 Self::Btf(_) => EbpfSectionKind::BtfMaps,
237 }
238 }
239
240 pub fn symbol_index(&self) -> Option<usize> {
245 match self {
246 Self::Legacy(m) => m.symbol_index,
247 Self::Btf(m) => Some(m.symbol_index),
248 }
249 }
250}
251
252#[derive(Debug, Clone)]
257pub struct LegacyMap {
258 pub def: bpf_map_def,
260 pub section_index: usize,
262 pub section_kind: EbpfSectionKind,
264 pub symbol_index: Option<usize>,
270 pub data: Vec<u8>,
272}
273
274#[derive(Debug, Clone)]
276pub struct BtfMap {
277 pub def: BtfMapDef,
279 pub(crate) section_index: usize,
280 pub(crate) symbol_index: usize,
281 pub(crate) data: Vec<u8>,
282}