aya_friday/maps/array/cgroup_array.rs
1//! An array of cgroups.
2
3use std::{
4 borrow::{Borrow, BorrowMut},
5 os::fd::{AsRawFd, RawFd},
6};
7
8use crate::maps::{MapData, MapError, check_bounds, check_kv_size, hash_map};
9
10/// An array of cgroups.
11///
12/// eBPF programs can test whether a packet or the current task belongs to a
13/// cgroup by calling `bpf_skb_under_cgroup` or `bpf_current_task_under_cgroup`
14/// against this map. You populate it from userspace with the file descriptors
15/// of cgroup directories.
16///
17/// # Minimum kernel version
18///
19/// The minimum kernel version required to use this feature is 4.8.
20///
21/// # Examples
22/// ```no_run
23/// # let mut bpf = aya::Ebpf::load(&[])?;
24/// # let cgroup_fd = 1;
25/// use aya::maps::CgroupArray;
26///
27/// let mut array = CgroupArray::try_from(bpf.map_mut("CGROUPS").unwrap())?;
28/// // cgroup_fd is the RawFd of an open cgroup directory.
29/// array.set(0, cgroup_fd, 0);
30/// # Ok::<(), aya::EbpfError>(())
31/// ```
32#[doc(alias = "BPF_MAP_TYPE_CGROUP_ARRAY")]
33pub struct CgroupArray<T> {
34 pub(crate) inner: T,
35}
36
37impl<T: Borrow<MapData>> CgroupArray<T> {
38 pub(crate) fn new(map: T) -> Result<Self, MapError> {
39 let data = map.borrow();
40 check_kv_size::<u32, RawFd>(data)?;
41
42 Ok(Self { inner: map })
43 }
44
45 /// Returns the number of elements in the array.
46 ///
47 /// This corresponds to the value of `bpf_map_def::max_entries` on the eBPF side.
48 pub fn len(&self) -> u32 {
49 self.inner.borrow().obj.max_entries()
50 }
51}
52
53impl<T: BorrowMut<MapData>> CgroupArray<T> {
54 /// Stores a cgroup file descriptor at the given index.
55 ///
56 /// # Errors
57 ///
58 /// Returns [`MapError::OutOfBounds`] if `index` is out of bounds,
59 /// [`MapError::SyscallError`] if `bpf_map_update_elem` fails.
60 pub fn set(&mut self, index: u32, cgroup_fd: impl AsRawFd, flags: u64) -> Result<(), MapError> {
61 let data = self.inner.borrow_mut();
62 check_bounds(data, index)?;
63 hash_map::insert(data, &index, &cgroup_fd.as_raw_fd(), flags)
64 }
65
66 /// Un-sets the cgroup at the given index.
67 ///
68 /// # Errors
69 ///
70 /// Returns [`MapError::OutOfBounds`] if `index` is out of bounds,
71 /// [`MapError::SyscallError`] if `bpf_map_delete_elem` fails.
72 pub fn unset(&mut self, index: u32) -> Result<(), MapError> {
73 let data = self.inner.borrow_mut();
74 check_bounds(data, index)?;
75 hash_map::remove(data, &index)
76 }
77}