1use std::{
4 ffi::CString,
5 os::fd::{AsFd as _, BorrowedFd},
6 path::Path,
7};
8
9use aya_obj::generated::{bpf_map_info, bpf_map_type};
10
11use super::{MapError, MapFd};
12use crate::{
13 FEATURES,
14 sys::{
15 SyscallError, bpf_get_object, bpf_map_get_fd_by_id, bpf_map_get_info_by_fd, iter_map_ids,
16 },
17 util::bytes_of_bpf_name,
18};
19
20#[doc(alias = "bpf_map_info")]
24#[derive(Debug)]
25pub struct MapInfo(pub(crate) bpf_map_info);
26
27impl MapInfo {
28 pub(crate) fn new_from_fd(fd: BorrowedFd<'_>) -> Result<Self, MapError> {
29 let info = bpf_map_get_info_by_fd(fd.as_fd())?;
30 Ok(Self(info))
31 }
32
33 pub fn from_id(id: u32) -> Result<Self, MapError> {
37 let fd = bpf_map_get_fd_by_id(id).map_err(MapError::from)?;
38 Self::new_from_fd(fd.as_fd())
39 }
40
41 pub fn map_type(&self) -> Result<MapType, MapError> {
45 bpf_map_type::try_from(self.0.type_)
46 .unwrap_or(bpf_map_type::__MAX_BPF_MAP_TYPE)
47 .try_into()
48 }
49
50 pub const fn id(&self) -> u32 {
54 self.0.id
55 }
56
57 pub const fn key_size(&self) -> u32 {
61 self.0.key_size
62 }
63
64 pub const fn value_size(&self) -> u32 {
68 self.0.value_size
69 }
70
71 pub const fn max_entries(&self) -> u32 {
75 self.0.max_entries
76 }
77
78 pub const fn map_flags(&self) -> u32 {
82 self.0.map_flags
83 }
84
85 pub fn name(&self) -> &[u8] {
89 bytes_of_bpf_name(&self.0.name)
90 }
91
92 pub fn name_as_str(&self) -> Option<&str> {
98 let name = std::str::from_utf8(self.name()).ok()?;
99 (FEATURES.bpf_name() || !name.is_empty()).then_some(name)
100 }
101
102 pub fn fd(&self) -> Result<MapFd, MapError> {
109 let Self(info) = self;
110 let fd = bpf_map_get_fd_by_id(info.id)?;
111 Ok(MapFd::from_fd(fd))
112 }
113
114 pub fn from_pin<P: AsRef<Path>>(path: P) -> Result<Self, MapError> {
118 use std::os::unix::ffi::OsStrExt as _;
119
120 let path_string = CString::new(path.as_ref().as_os_str().as_bytes()).unwrap();
122 let fd = bpf_get_object(&path_string).map_err(|io_error| SyscallError {
123 call: "BPF_OBJ_GET",
124 io_error,
125 })?;
126
127 Self::new_from_fd(fd.as_fd())
128 }
129}
130
131pub fn loaded_maps() -> impl Iterator<Item = Result<MapInfo, MapError>> {
158 iter_map_ids().map(|id| {
159 let id = id?;
160 MapInfo::from_id(id)
161 })
162}
163
164#[non_exhaustive]
166#[doc(alias = "bpf_map_type")]
167#[derive(Copy, Clone, Debug, PartialEq)]
168pub enum MapType {
169 Unspecified = bpf_map_type::BPF_MAP_TYPE_UNSPEC as isize,
171 #[doc(alias = "BPF_MAP_TYPE_HASH")]
175 Hash = bpf_map_type::BPF_MAP_TYPE_HASH as isize,
176 #[doc(alias = "BPF_MAP_TYPE_ARRAY")]
180 Array = bpf_map_type::BPF_MAP_TYPE_ARRAY as isize,
181 #[doc(alias = "BPF_MAP_TYPE_PROG_ARRAY")]
186 ProgramArray = bpf_map_type::BPF_MAP_TYPE_PROG_ARRAY as isize,
187 #[doc(alias = "BPF_MAP_TYPE_PERF_EVENT_ARRAY")]
192 PerfEventArray = bpf_map_type::BPF_MAP_TYPE_PERF_EVENT_ARRAY as isize,
193 #[doc(alias = "BPF_MAP_TYPE_PERCPU_HASH")]
198 PerCpuHash = bpf_map_type::BPF_MAP_TYPE_PERCPU_HASH as isize,
199 #[doc(alias = "BPF_MAP_TYPE_PERCPU_ARRAY")]
204 PerCpuArray = bpf_map_type::BPF_MAP_TYPE_PERCPU_ARRAY as isize,
205 #[doc(alias = "BPF_MAP_TYPE_STACK_TRACE")]
210 StackTrace = bpf_map_type::BPF_MAP_TYPE_STACK_TRACE as isize,
211 #[doc(alias = "BPF_MAP_TYPE_CGROUP_ARRAY")]
215 CgroupArray = bpf_map_type::BPF_MAP_TYPE_CGROUP_ARRAY as isize,
216 #[doc(alias = "BPF_MAP_TYPE_LRU_HASH")]
221 LruHash = bpf_map_type::BPF_MAP_TYPE_LRU_HASH as isize,
222 #[doc(alias = "BPF_MAP_TYPE_LRU_PERCPU_HASH")]
227 LruPerCpuHash = bpf_map_type::BPF_MAP_TYPE_LRU_PERCPU_HASH as isize,
228 #[doc(alias = "BPF_MAP_TYPE_LPM_TRIE")]
233 LpmTrie = bpf_map_type::BPF_MAP_TYPE_LPM_TRIE as isize,
234 #[doc(alias = "BPF_MAP_TYPE_ARRAY_OF_MAPS")]
238 ArrayOfMaps = bpf_map_type::BPF_MAP_TYPE_ARRAY_OF_MAPS as isize,
239 #[doc(alias = "BPF_MAP_TYPE_HASH_OF_MAPS")]
243 HashOfMaps = bpf_map_type::BPF_MAP_TYPE_HASH_OF_MAPS as isize,
244 #[doc(alias = "BPF_MAP_TYPE_DEVMAP")]
248 DevMap = bpf_map_type::BPF_MAP_TYPE_DEVMAP as isize,
249 #[doc(alias = "BPF_MAP_TYPE_SOCKMAP")]
253 SockMap = bpf_map_type::BPF_MAP_TYPE_SOCKMAP as isize,
254 #[doc(alias = "BPF_MAP_TYPE_CPUMAP")]
258 CpuMap = bpf_map_type::BPF_MAP_TYPE_CPUMAP as isize,
259 #[doc(alias = "BPF_MAP_TYPE_XSKMAP")]
263 XskMap = bpf_map_type::BPF_MAP_TYPE_XSKMAP as isize,
264 #[doc(alias = "BPF_MAP_TYPE_SOCKHASH")]
268 SockHash = bpf_map_type::BPF_MAP_TYPE_SOCKHASH as isize,
269 #[doc(alias = "BPF_MAP_TYPE_CGROUP_STORAGE")]
274 #[doc(alias = "BPF_MAP_TYPE_CGROUP_STORAGE_DEPRECATED")]
275 CgroupStorage = bpf_map_type::BPF_MAP_TYPE_CGROUP_STORAGE as isize,
276 #[doc(alias = "BPF_MAP_TYPE_REUSEPORT_SOCKARRAY")]
280 ReuseportSockArray = bpf_map_type::BPF_MAP_TYPE_REUSEPORT_SOCKARRAY as isize,
281 #[doc(alias = "BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE")]
285 #[doc(alias = "BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE_DEPRECATED")]
286 PerCpuCgroupStorage = bpf_map_type::BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE as isize,
287 #[doc(alias = "BPF_MAP_TYPE_QUEUE")]
291 Queue = bpf_map_type::BPF_MAP_TYPE_QUEUE as isize,
292 #[doc(alias = "BPF_MAP_TYPE_STACK")]
296 Stack = bpf_map_type::BPF_MAP_TYPE_STACK as isize,
297 #[doc(alias = "BPF_MAP_TYPE_SK_STORAGE")]
301 SkStorage = bpf_map_type::BPF_MAP_TYPE_SK_STORAGE as isize,
302 #[doc(alias = "BPF_MAP_TYPE_DEVMAP_HASH")]
307 DevMapHash = bpf_map_type::BPF_MAP_TYPE_DEVMAP_HASH as isize,
308 #[doc(alias = "BPF_MAP_TYPE_STRUCT_OPS")]
312 StructOps = bpf_map_type::BPF_MAP_TYPE_STRUCT_OPS as isize,
313 #[doc(alias = "BPF_MAP_TYPE_RINGBUF")]
318 RingBuf = bpf_map_type::BPF_MAP_TYPE_RINGBUF as isize,
319 #[doc(alias = "BPF_MAP_TYPE_INODE_STORAGE")]
323 InodeStorage = bpf_map_type::BPF_MAP_TYPE_INODE_STORAGE as isize,
324 #[doc(alias = "BPF_MAP_TYPE_TASK_STORAGE")]
328 TaskStorage = bpf_map_type::BPF_MAP_TYPE_TASK_STORAGE as isize,
329 #[doc(alias = "BPF_MAP_TYPE_BLOOM_FILTER")]
334 BloomFilter = bpf_map_type::BPF_MAP_TYPE_BLOOM_FILTER as isize,
335 #[doc(alias = "BPF_MAP_TYPE_USER_RINGBUF")]
339 UserRingBuf = bpf_map_type::BPF_MAP_TYPE_USER_RINGBUF as isize,
340 #[doc(alias = "BPF_MAP_TYPE_CGRP_STORAGE")]
344 CgrpStorage = bpf_map_type::BPF_MAP_TYPE_CGRP_STORAGE as isize,
345 #[doc(alias = "BPF_MAP_TYPE_ARENA")]
349 Arena = bpf_map_type::BPF_MAP_TYPE_ARENA as isize,
350}
351
352impl TryFrom<bpf_map_type> for MapType {
353 type Error = MapError;
354
355 fn try_from(map_type: bpf_map_type) -> Result<Self, Self::Error> {
356 Ok(match map_type {
357 bpf_map_type::BPF_MAP_TYPE_UNSPEC => Self::Unspecified,
358 bpf_map_type::BPF_MAP_TYPE_HASH => Self::Hash,
359 bpf_map_type::BPF_MAP_TYPE_ARRAY => Self::Array,
360 bpf_map_type::BPF_MAP_TYPE_PROG_ARRAY => Self::ProgramArray,
361 bpf_map_type::BPF_MAP_TYPE_PERF_EVENT_ARRAY => Self::PerfEventArray,
362 bpf_map_type::BPF_MAP_TYPE_PERCPU_HASH => Self::PerCpuHash,
363 bpf_map_type::BPF_MAP_TYPE_PERCPU_ARRAY => Self::PerCpuArray,
364 bpf_map_type::BPF_MAP_TYPE_STACK_TRACE => Self::StackTrace,
365 bpf_map_type::BPF_MAP_TYPE_CGROUP_ARRAY => Self::CgroupArray,
366 bpf_map_type::BPF_MAP_TYPE_LRU_HASH => Self::LruHash,
367 bpf_map_type::BPF_MAP_TYPE_LRU_PERCPU_HASH => Self::LruPerCpuHash,
368 bpf_map_type::BPF_MAP_TYPE_LPM_TRIE => Self::LpmTrie,
369 bpf_map_type::BPF_MAP_TYPE_ARRAY_OF_MAPS => Self::ArrayOfMaps,
370 bpf_map_type::BPF_MAP_TYPE_HASH_OF_MAPS => Self::HashOfMaps,
371 bpf_map_type::BPF_MAP_TYPE_DEVMAP => Self::DevMap,
372 bpf_map_type::BPF_MAP_TYPE_SOCKMAP => Self::SockMap,
373 bpf_map_type::BPF_MAP_TYPE_CPUMAP => Self::CpuMap,
374 bpf_map_type::BPF_MAP_TYPE_XSKMAP => Self::XskMap,
375 bpf_map_type::BPF_MAP_TYPE_SOCKHASH => Self::SockHash,
376 bpf_map_type::BPF_MAP_TYPE_CGROUP_STORAGE_DEPRECATED => Self::CgroupStorage,
377 bpf_map_type::BPF_MAP_TYPE_REUSEPORT_SOCKARRAY => Self::ReuseportSockArray,
378 bpf_map_type::BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE_DEPRECATED => {
379 Self::PerCpuCgroupStorage
380 }
381 bpf_map_type::BPF_MAP_TYPE_QUEUE => Self::Queue,
382 bpf_map_type::BPF_MAP_TYPE_STACK => Self::Stack,
383 bpf_map_type::BPF_MAP_TYPE_SK_STORAGE => Self::SkStorage,
384 bpf_map_type::BPF_MAP_TYPE_DEVMAP_HASH => Self::DevMapHash,
385 bpf_map_type::BPF_MAP_TYPE_STRUCT_OPS => Self::StructOps,
386 bpf_map_type::BPF_MAP_TYPE_RINGBUF => Self::RingBuf,
387 bpf_map_type::BPF_MAP_TYPE_INODE_STORAGE => Self::InodeStorage,
388 bpf_map_type::BPF_MAP_TYPE_TASK_STORAGE => Self::TaskStorage,
389 bpf_map_type::BPF_MAP_TYPE_BLOOM_FILTER => Self::BloomFilter,
390 bpf_map_type::BPF_MAP_TYPE_USER_RINGBUF => Self::UserRingBuf,
391 bpf_map_type::BPF_MAP_TYPE_CGRP_STORAGE => Self::CgrpStorage,
392 bpf_map_type::BPF_MAP_TYPE_ARENA => Self::Arena,
393 bpf_map_type::__MAX_BPF_MAP_TYPE => {
394 return Err(MapError::InvalidMapType {
395 map_type: map_type as u32,
396 });
397 }
398 })
399 }
400}