Skip to main content

profile_bee_aya/
lib.rs

1//! [![](https://aya-rs.dev/assets/images/aya_logo_docs.svg)](https://aya-rs.dev)
2//!
3//! A library to work with eBPF programs.
4//!
5//! eBPF is a technology that allows running user-supplied programs inside the
6//! Linux kernel. For more info see
7//! [https://ebpf.io/what-is-ebpf](https://ebpf.io/what-is-ebpf).
8//!
9//! Aya is an eBPF library built with a focus on operability and developer experience. It does not
10//! rely on [libbpf](https://github.com/libbpf/libbpf) nor [bcc](https://github.com/iovisor/bcc) -
11//! it's built from the ground up purely in Rust, using only the [libc](https://crates.io/libc)
12//! crate to execute syscalls. With BTF support and when linked with musl, it offers a true
13//! [compile once, run everywhere
14//! solution](https://facebookmicrosites.github.io/bpf/blog/2020/02/19/bpf-portability-and-co-re.html),
15//! where a single self-contained binary can be deployed on many linux distributions
16//! and kernel versions.
17//!
18//! Some of the major features provided include:
19//!
20//! * Support for the **BPF Type Format** (BTF), which is transparently enabled when
21//!   supported by the target kernel. This allows eBPF programs compiled against
22//!   one kernel version to run on different kernel versions without the need to
23//!   recompile.
24//! * Support for function call relocation and global data maps, which
25//!   allows eBPF programs to make **function calls** and use **global variables
26//!   and initializers**.
27//! * **Async support** with both [tokio] and [async-std].
28//! * Easy to deploy and fast to build: aya doesn't require a kernel build or
29//!   compiled headers, and not even a C toolchain; a release build completes in a matter
30//!   of seconds.
31//!
32//! [tokio]: https://docs.rs/tokio
33//! [async-std]: https://docs.rs/async-std
34
35#![doc(
36    html_logo_url = "https://aya-rs.dev/assets/images/crabby.svg",
37    html_favicon_url = "https://aya-rs.dev/assets/images/crabby.svg"
38)]
39#![cfg_attr(docsrs, feature(doc_cfg))]
40#![deny(missing_docs)]
41
42mod bpf;
43pub mod maps;
44pub mod pin;
45pub mod programs;
46pub mod sys;
47pub mod util;
48
49use std::os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, OwnedFd, RawFd};
50
51pub use aya_obj::btf::{Btf, BtfError};
52pub use bpf::*;
53pub use object::Endianness;
54#[doc(hidden)]
55pub use sys::netlink_set_link_up;
56
57// See https://github.com/rust-lang/rust/pull/124210; this structure exists to avoid crashing the
58// process when we try to close a fake file descriptor.
59#[derive(Debug)]
60struct MockableFd {
61    #[cfg(not(test))]
62    fd: OwnedFd,
63    #[cfg(test)]
64    fd: Option<OwnedFd>,
65}
66
67impl MockableFd {
68    #[cfg(test)]
69    const fn mock_signed_fd() -> i32 {
70        1337
71    }
72
73    #[cfg(test)]
74    const fn mock_unsigned_fd() -> u32 {
75        1337
76    }
77
78    #[cfg(not(test))]
79    const fn from_fd(fd: OwnedFd) -> Self {
80        Self { fd }
81    }
82
83    #[cfg(test)]
84    const fn from_fd(fd: OwnedFd) -> Self {
85        let fd = Some(fd);
86        Self { fd }
87    }
88
89    #[cfg(not(test))]
90    const fn inner(&self) -> &OwnedFd {
91        let Self { fd } = self;
92        fd
93    }
94
95    #[cfg(test)]
96    const fn inner(&self) -> &OwnedFd {
97        let Self { fd } = self;
98        fd.as_ref().unwrap()
99    }
100
101    #[cfg(not(test))]
102    fn into_inner(self) -> OwnedFd {
103        self.fd
104    }
105
106    #[cfg(test)]
107    fn into_inner(mut self) -> OwnedFd {
108        self.fd.take().unwrap()
109    }
110
111    fn try_clone(&self) -> std::io::Result<Self> {
112        let fd = self.inner();
113        let fd = fd.try_clone()?;
114        Ok(Self::from_fd(fd))
115    }
116}
117
118impl<T> From<T> for MockableFd
119where
120    OwnedFd: From<T>,
121{
122    fn from(value: T) -> Self {
123        let fd = OwnedFd::from(value);
124        Self::from_fd(fd)
125    }
126}
127
128impl AsFd for MockableFd {
129    fn as_fd(&self) -> BorrowedFd<'_> {
130        self.inner().as_fd()
131    }
132}
133
134impl AsRawFd for MockableFd {
135    fn as_raw_fd(&self) -> RawFd {
136        self.inner().as_raw_fd()
137    }
138}
139
140impl FromRawFd for MockableFd {
141    unsafe fn from_raw_fd(fd: RawFd) -> Self {
142        let fd = unsafe { OwnedFd::from_raw_fd(fd) };
143        Self::from_fd(fd)
144    }
145}
146
147#[cfg(test)]
148impl Drop for MockableFd {
149    fn drop(&mut self) {
150        use std::os::fd::{AsRawFd as _, IntoRawFd as _};
151
152        let Self { fd } = self;
153        let fd = fd.take().unwrap();
154        if fd.as_raw_fd() < Self::mock_signed_fd() {
155            drop(fd)
156        } else {
157            let _raw_fd = fd.into_raw_fd();
158        }
159    }
160}