Skip to main content

aya_friday/maps/
info.rs

1//! Metadata information about an eBPF map.
2
3use 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/// Provides Provides metadata information about a loaded eBPF map.
21///
22/// Introduced in kernel v4.13.
23#[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    /// Loads map info from a map ID.
34    ///
35    /// Uses kernel v4.13 features.
36    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    /// The type of map.
42    ///
43    /// Introduced in kernel v4.13.
44    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    /// The unique ID for this map.
51    ///
52    /// Introduced in kernel v4.13.
53    pub const fn id(&self) -> u32 {
54        self.0.id
55    }
56
57    /// The key size for this map in bytes.
58    ///
59    /// Introduced in kernel v4.13.
60    pub const fn key_size(&self) -> u32 {
61        self.0.key_size
62    }
63
64    /// The value size for this map in bytes.
65    ///
66    /// Introduced in kernel v4.13.
67    pub const fn value_size(&self) -> u32 {
68        self.0.value_size
69    }
70
71    /// The maximum number of entries in this map.
72    ///
73    /// Introduced in kernel v4.13.
74    pub const fn max_entries(&self) -> u32 {
75        self.0.max_entries
76    }
77
78    /// The flags used in loading this map.
79    ///
80    /// Introduced in kernel v4.13.
81    pub const fn map_flags(&self) -> u32 {
82        self.0.map_flags
83    }
84
85    /// The name of the map, limited to 16 bytes.
86    ///
87    /// Introduced in kernel v4.15.
88    pub fn name(&self) -> &[u8] {
89        bytes_of_bpf_name(&self.0.name)
90    }
91
92    /// The name of the map as a &str.
93    ///
94    /// `None` is returned if the name was not valid unicode or if field is not available.
95    ///
96    /// Introduced in kernel v4.15.
97    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    /// Returns a file descriptor referencing the map.
103    ///
104    /// The returned file descriptor can be closed at any time and doing so does
105    /// not influence the life cycle of the map.
106    ///
107    /// Uses kernel v4.13 features.
108    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    /// Loads a map from a pinned path in bpffs.
115    ///
116    /// Uses kernel v4.4 and v4.13 features.
117    pub fn from_pin<P: AsRef<Path>>(path: P) -> Result<Self, MapError> {
118        use std::os::unix::ffi::OsStrExt as _;
119
120        // TODO: avoid this unwrap by adding a new error variant.
121        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
131/// Returns an iterator of [`MapInfo`] over all eBPF maps on the host.
132///
133/// Unlike [`Ebpf::maps`](crate::Ebpf::maps), this includes all maps on the host system, not
134/// just those tied to a specific [`crate::Ebpf`] instance.
135///
136/// Uses kernel v4.13 features.
137///
138/// # Example
139/// ```
140/// # use aya::maps::loaded_maps;
141/// #
142/// for m in loaded_maps() {
143///     match m {
144///         Ok(map) => println!("{:?}", map.name_as_str()),
145///         Err(e) => println!("error iterating maps: {:?}", e),
146///     }
147/// }
148/// ```
149///
150/// # Errors
151///
152/// Returns [`MapError::SyscallError`] if any of the syscalls required to either get
153/// next map id, get the map fd, or the [`MapInfo`] fail.
154///
155/// In cases where iteration can't be performed, for example the caller does not have the necessary
156/// privileges, a single item will be yielded containing the error that occurred.
157pub 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/// The type of eBPF map.
165#[non_exhaustive]
166#[doc(alias = "bpf_map_type")]
167#[derive(Copy, Clone, Debug, PartialEq)]
168pub enum MapType {
169    /// An unspecified program type.
170    Unspecified = bpf_map_type::BPF_MAP_TYPE_UNSPEC as isize,
171    /// A Hash map type. See [`HashMap`](super::hash_map::HashMap) for the map implementation.
172    ///
173    /// Introduced in kernel v3.19.
174    #[doc(alias = "BPF_MAP_TYPE_HASH")]
175    Hash = bpf_map_type::BPF_MAP_TYPE_HASH as isize,
176    /// An Array map type. See [`Array`](super::array::Array) for the map implementation.
177    ///
178    /// Introduced in kernel v3.19.
179    #[doc(alias = "BPF_MAP_TYPE_ARRAY")]
180    Array = bpf_map_type::BPF_MAP_TYPE_ARRAY as isize,
181    /// A Program Array map type. See [`ProgramArray`](super::array::ProgramArray) for the map
182    /// implementation.
183    ///
184    /// Introduced in kernel v4.2.
185    #[doc(alias = "BPF_MAP_TYPE_PROG_ARRAY")]
186    ProgramArray = bpf_map_type::BPF_MAP_TYPE_PROG_ARRAY as isize,
187    /// A Perf Event Array map type. See [`PerfEventArray`](super::perf::PerfEventArray) for the map
188    /// implementation.
189    ///
190    /// Introduced in kernel v4.3.
191    #[doc(alias = "BPF_MAP_TYPE_PERF_EVENT_ARRAY")]
192    PerfEventArray = bpf_map_type::BPF_MAP_TYPE_PERF_EVENT_ARRAY as isize,
193    /// A per-CPU Hash map type. See [`PerCpuHashMap`](super::hash_map::PerCpuHashMap) for the map
194    /// implementation.
195    ///
196    /// Introduced in kernel v4.6.
197    #[doc(alias = "BPF_MAP_TYPE_PERCPU_HASH")]
198    PerCpuHash = bpf_map_type::BPF_MAP_TYPE_PERCPU_HASH as isize,
199    /// A per-CPU Array map type. See [`PerCpuArray`](super::array::PerCpuArray) for the map
200    /// implementation.
201    ///
202    /// Introduced in kernel v4.6.
203    #[doc(alias = "BPF_MAP_TYPE_PERCPU_ARRAY")]
204    PerCpuArray = bpf_map_type::BPF_MAP_TYPE_PERCPU_ARRAY as isize,
205    /// A Stack Trace map type. See [`StackTraceMap`](super::stack_trace::StackTraceMap) for the map
206    /// implementation.
207    ///
208    /// Introduced in kernel v4.6.
209    #[doc(alias = "BPF_MAP_TYPE_STACK_TRACE")]
210    StackTrace = bpf_map_type::BPF_MAP_TYPE_STACK_TRACE as isize,
211    /// A cGroup Array map type.
212    ///
213    /// Introduced in kernel v4.8.
214    #[doc(alias = "BPF_MAP_TYPE_CGROUP_ARRAY")]
215    CgroupArray = bpf_map_type::BPF_MAP_TYPE_CGROUP_ARRAY as isize,
216    /// A Least Recently Used (LRU) Hash map type. See [`HashMap`](super::hash_map::HashMap) for
217    /// the map implementation.
218    ///
219    /// Introduced in kernel v4.10.
220    #[doc(alias = "BPF_MAP_TYPE_LRU_HASH")]
221    LruHash = bpf_map_type::BPF_MAP_TYPE_LRU_HASH as isize,
222    /// A Least Recently Used (LRU) per-CPU Hash map type. See
223    /// [`PerCpuHashMap`](super::hash_map::PerCpuHashMap) for the map implementation.
224    ///
225    /// Introduced in kernel v4.10.
226    #[doc(alias = "BPF_MAP_TYPE_LRU_PERCPU_HASH")]
227    LruPerCpuHash = bpf_map_type::BPF_MAP_TYPE_LRU_PERCPU_HASH as isize,
228    /// A Longest Prefix Match (LPM) Trie map type. See [`LpmTrie`](super::lpm_trie::LpmTrie) for
229    /// the map implementation.
230    ///
231    /// Introduced in kernel v4.11.
232    #[doc(alias = "BPF_MAP_TYPE_LPM_TRIE")]
233    LpmTrie = bpf_map_type::BPF_MAP_TYPE_LPM_TRIE as isize,
234    /// An Array of Maps map type.
235    ///
236    /// Introduced in kernel v4.12.
237    #[doc(alias = "BPF_MAP_TYPE_ARRAY_OF_MAPS")]
238    ArrayOfMaps = bpf_map_type::BPF_MAP_TYPE_ARRAY_OF_MAPS as isize,
239    /// A Hash of Maps map type.
240    ///
241    /// Introduced in kernel v4.12.
242    #[doc(alias = "BPF_MAP_TYPE_HASH_OF_MAPS")]
243    HashOfMaps = bpf_map_type::BPF_MAP_TYPE_HASH_OF_MAPS as isize,
244    /// A Device Map type. See [`DevMap`](super::xdp::DevMap) for the map implementation.
245    ///
246    /// Introduced in kernel v4.14.
247    #[doc(alias = "BPF_MAP_TYPE_DEVMAP")]
248    DevMap = bpf_map_type::BPF_MAP_TYPE_DEVMAP as isize,
249    /// A Socket Map type. See [`SockMap`](super::sock::SockMap) for the map implementation.
250    ///
251    /// Introduced in kernel v4.14.
252    #[doc(alias = "BPF_MAP_TYPE_SOCKMAP")]
253    SockMap = bpf_map_type::BPF_MAP_TYPE_SOCKMAP as isize,
254    /// A CPU Map type. See [`CpuMap`](super::xdp::CpuMap) for the map implementation.
255    ///
256    /// Introduced in kernel v4.15.
257    #[doc(alias = "BPF_MAP_TYPE_CPUMAP")]
258    CpuMap = bpf_map_type::BPF_MAP_TYPE_CPUMAP as isize,
259    /// An XDP Socket Map type. See [`XskMap`](super::xdp::XskMap) for the map implementation.
260    ///
261    /// Introduced in kernel v4.18.
262    #[doc(alias = "BPF_MAP_TYPE_XSKMAP")]
263    XskMap = bpf_map_type::BPF_MAP_TYPE_XSKMAP as isize,
264    /// A Socket Hash map type. See [`SockHash`](super::sock::SockHash) for the map implementation.
265    ///
266    /// Introduced in kernel v4.18.
267    #[doc(alias = "BPF_MAP_TYPE_SOCKHASH")]
268    SockHash = bpf_map_type::BPF_MAP_TYPE_SOCKHASH as isize,
269    /// A cGroup Storage map type.
270    ///
271    /// Introduced in kernel v4.19.
272    // #[deprecated]
273    #[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    /// A Reuseport Socket Array map type.
277    ///
278    /// Introduced in kernel v4.19.
279    #[doc(alias = "BPF_MAP_TYPE_REUSEPORT_SOCKARRAY")]
280    ReuseportSockArray = bpf_map_type::BPF_MAP_TYPE_REUSEPORT_SOCKARRAY as isize,
281    /// A per-CPU cGroup Storage map type.
282    ///
283    /// Introduced in kernel v4.20.
284    #[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    /// A Queue map type. See [`Queue`](super::queue::Queue) for the map implementation.
288    ///
289    /// Introduced in kernel v4.20.
290    #[doc(alias = "BPF_MAP_TYPE_QUEUE")]
291    Queue = bpf_map_type::BPF_MAP_TYPE_QUEUE as isize,
292    /// A Stack map type. See [`Stack`](super::stack::Stack) for the map implementation.
293    ///
294    /// Introduced in kernel v4.20.
295    #[doc(alias = "BPF_MAP_TYPE_STACK")]
296    Stack = bpf_map_type::BPF_MAP_TYPE_STACK as isize,
297    /// A Socket-local Storage map type.
298    ///
299    /// Introduced in kernel v5.2.
300    #[doc(alias = "BPF_MAP_TYPE_SK_STORAGE")]
301    SkStorage = bpf_map_type::BPF_MAP_TYPE_SK_STORAGE as isize,
302    /// A Device Hash Map type. See [`DevMapHash`](super::xdp::DevMapHash) for the map
303    /// implementation.
304    ///
305    /// Introduced in kernel v5.4.
306    #[doc(alias = "BPF_MAP_TYPE_DEVMAP_HASH")]
307    DevMapHash = bpf_map_type::BPF_MAP_TYPE_DEVMAP_HASH as isize,
308    /// A Struct Ops map type.
309    ///
310    /// Introduced in kernel v5.6.
311    #[doc(alias = "BPF_MAP_TYPE_STRUCT_OPS")]
312    StructOps = bpf_map_type::BPF_MAP_TYPE_STRUCT_OPS as isize,
313    /// A Ring Buffer map type. See [`RingBuf`](super::ring_buf::RingBuf) for the map
314    /// implementation.
315    ///
316    /// Introduced in kernel v5.8.
317    #[doc(alias = "BPF_MAP_TYPE_RINGBUF")]
318    RingBuf = bpf_map_type::BPF_MAP_TYPE_RINGBUF as isize,
319    /// An Inode Storage map type.
320    ///
321    /// Introduced in kernel v5.10.
322    #[doc(alias = "BPF_MAP_TYPE_INODE_STORAGE")]
323    InodeStorage = bpf_map_type::BPF_MAP_TYPE_INODE_STORAGE as isize,
324    /// A Task Storage map type.
325    ///
326    /// Introduced in kernel v5.11.
327    #[doc(alias = "BPF_MAP_TYPE_TASK_STORAGE")]
328    TaskStorage = bpf_map_type::BPF_MAP_TYPE_TASK_STORAGE as isize,
329    /// A Bloom Filter map type. See [`BloomFilter`](super::bloom_filter::BloomFilter) for the map
330    /// implementation.
331    ///
332    /// Introduced in kernel v5.16.
333    #[doc(alias = "BPF_MAP_TYPE_BLOOM_FILTER")]
334    BloomFilter = bpf_map_type::BPF_MAP_TYPE_BLOOM_FILTER as isize,
335    /// A User Ring Buffer map type.
336    ///
337    /// Introduced in kernel v6.1.
338    #[doc(alias = "BPF_MAP_TYPE_USER_RINGBUF")]
339    UserRingBuf = bpf_map_type::BPF_MAP_TYPE_USER_RINGBUF as isize,
340    /// A cGroup Storage map type.
341    ///
342    /// Introduced in kernel v6.2.
343    #[doc(alias = "BPF_MAP_TYPE_CGRP_STORAGE")]
344    CgrpStorage = bpf_map_type::BPF_MAP_TYPE_CGRP_STORAGE as isize,
345    /// An Arena map type.
346    ///
347    /// Introduced in kernel v6.9.
348    #[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}