libbpf_rs/
lib.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
//! # libbpf-rs
//!
//! `libbpf-rs` is a safe, idiomatic, and opinionated wrapper around
//! [libbpf](https://github.com/libbpf/libbpf/).
//!
//! libbpf-rs, together with `libbpf-cargo` (libbpf cargo plugin) allow you
//! to write Compile-Once-Run-Everywhere (CO-RE) eBPF programs. Note this document
//! uses "eBPF" and "BPF" interchangeably.
//!
//! More information about CO-RE is [available
//! here](https://facebookmicrosites.github.io/bpf/blog/2020/02/19/bpf-portability-and-co-re.html).
//!
//! ## High level workflow
//!
//! 1. Create new rust project (via `cargo new` or similar) at path `$PROJ_PATH`
//! 2. Create directory `$PROJ_PATH/src/bpf`
//! 3. Write CO-RE bpf code in `$PROJ_PATH/src/bpf/${MYFILE}.bpf.c`, where `$MYFILE` may be any
//!    valid filename. Note the `.bpf.c` extension is required.
//! 4. Create a [build script](https://doc.rust-lang.org/cargo/reference/build-scripts.html) that
//!    builds and generates a skeleton module using `libbpf_cargo::SkeletonBuilder`
//! 5. Write your userspace code by importing and using the generated module. Import the
//!    module by using the [path
//!    attribute](https://doc.rust-lang.org/reference/items/modules.html#the-path-attribute).
//!    Your userspace code goes in `$PROJ_PATH/src/` as it would in a normal rust project.
//! 6. Continue regular rust workflow (ie `cargo build`, `cargo run`, etc)
//!
//! ## Alternate workflow
//!
//! While using the skeleton is recommended, it is also possible to directly use libbpf-rs.
//!
//! 1. Follow steps 1-3 of "High level workflow"
//! 2. Generate a BPF object file. Options include manually invoking `clang`, creating a build
//!    script to invoke `clang`, or using `libbpf-cargo` cargo plugins.
//! 3. Write your userspace code in `$PROJ_PATH/src/` as you would a normal rust project and point
//!    libbpf-rs at your BPF object file
//! 4. Continue regular rust workflow (ie `cargo build`, `cargo run`, etc)
//!
//! ## Design
//!
//! libbpf-rs models various "phases":
//! ```text
//!                from_*()        load()
//!                  |               |
//!                  v               v
//!    ObjectBuilder ->  OpenObject  -> Object
//!                          ^            ^
//!                          |            |
//!              <pre-load modifications> |
//!                                       |
//!                            <post-load interactions>
//! ```
//!
//! The entry point into libbpf-rs is [`ObjectBuilder`]. `ObjectBuilder` helps open the BPF object
//! file. After the object file is opened, you are returned an [`OpenObject`] where you can
//! perform all your pre-load operations. Pre-load means before any BPF maps are created or BPF
//! programs are loaded and verified by the kernel. Finally, after the BPF object is loaded, you
//! are returned an [`Object`] instance where you can read/write to BPF maps, attach BPF programs
//! to hooks, etc.
//!
//! You _must_ keep the [`Object`] alive the entire duration you interact with anything inside the
//! BPF object it represents. This is further documented in [`Object`] documentation.
//!
//! ## Example
//!
//! This is probably the best way to understand how libbpf-rs and libbpf-cargo work together.
//!
//! [See example here](https://github.com/libbpf/libbpf-rs/tree/master/examples/runqslower).

#![allow(clippy::let_and_return, clippy::let_unit_value)]
#![warn(
    elided_lifetimes_in_paths,
    missing_debug_implementations,
    missing_docs,
    single_use_lifetimes,
    clippy::absolute_paths,
    clippy::wildcard_imports,
    rustdoc::broken_intra_doc_links
)]
#![deny(unsafe_op_in_unsafe_fn)]

pub mod btf;
mod error;
mod iter;
mod link;
mod linker;
mod map;
mod netfilter;
mod object;
mod perf_buffer;
mod print;
mod program;
pub mod query;
mod ringbuf;
mod skeleton;
mod tc;
mod user_ringbuf;
mod util;
mod xdp;

pub use libbpf_sys;

pub use crate::btf::Btf;
pub use crate::btf::HasSize;
pub use crate::btf::ReferencesType;
pub use crate::error::Error;
pub use crate::error::ErrorExt;
pub use crate::error::ErrorKind;
pub use crate::error::Result;
pub use crate::iter::Iter;
pub use crate::link::Link;
pub use crate::linker::Linker;
pub use crate::map::Map;
pub use crate::map::MapCore;
pub use crate::map::MapFlags;
pub use crate::map::MapHandle;
pub use crate::map::MapImpl;
pub use crate::map::MapInfo;
pub use crate::map::MapKeyIter;
pub use crate::map::MapMut;
pub use crate::map::MapType;
pub use crate::map::OpenMap;
pub use crate::map::OpenMapImpl;
pub use crate::map::OpenMapMut;
pub use crate::netfilter::NetfilterOpts;
pub use crate::netfilter::NFPROTO_IPV4;
pub use crate::netfilter::NFPROTO_IPV6;
pub use crate::netfilter::NF_INET_FORWARD;
pub use crate::netfilter::NF_INET_LOCAL_IN;
pub use crate::netfilter::NF_INET_LOCAL_OUT;
pub use crate::netfilter::NF_INET_POST_ROUTING;
pub use crate::netfilter::NF_INET_PRE_ROUTING;
pub use crate::object::AsRawLibbpf;
pub use crate::object::MapIter;
pub use crate::object::Object;
pub use crate::object::ObjectBuilder;
pub use crate::object::OpenObject;
pub use crate::object::ProgIter;
pub use crate::perf_buffer::PerfBuffer;
pub use crate::perf_buffer::PerfBufferBuilder;
pub use crate::print::get_print;
pub use crate::print::set_print;
pub use crate::print::PrintCallback;
pub use crate::print::PrintLevel;
pub use crate::program::Input as ProgramInput;
pub use crate::program::OpenProgram;
pub use crate::program::OpenProgramImpl;
pub use crate::program::OpenProgramMut;
pub use crate::program::Output as ProgramOutput;
pub use crate::program::Program;
pub use crate::program::ProgramAttachType;
pub use crate::program::ProgramImpl;
pub use crate::program::ProgramMut;
pub use crate::program::ProgramType;
pub use crate::program::TracepointOpts;
pub use crate::program::UprobeOpts;
pub use crate::program::UsdtOpts;
pub use crate::ringbuf::RingBuffer;
pub use crate::ringbuf::RingBufferBuilder;
pub use crate::tc::TcAttachPoint;
pub use crate::tc::TcHook;
pub use crate::tc::TcHookBuilder;
pub use crate::tc::TC_CUSTOM;
pub use crate::tc::TC_EGRESS;
pub use crate::tc::TC_H_CLSACT;
pub use crate::tc::TC_H_INGRESS;
pub use crate::tc::TC_H_MIN_EGRESS;
pub use crate::tc::TC_H_MIN_INGRESS;
pub use crate::tc::TC_INGRESS;
pub use crate::user_ringbuf::UserRingBuffer;
pub use crate::user_ringbuf::UserRingBufferSample;
pub use crate::util::num_possible_cpus;
pub use crate::xdp::Xdp;
pub use crate::xdp::XdpFlags;

/// An unconstructible dummy type used for tagging mutable type
/// variants.
#[doc(hidden)]
#[derive(Copy, Clone, Debug)]
pub enum Mut {}


/// Used for skeleton -- an end user may not consider this API stable
#[doc(hidden)]
pub mod __internal_skel {
    pub use super::skeleton::*;
}

/// Skeleton related definitions.
pub mod skel {
    pub use super::skeleton::OpenSkel;
    pub use super::skeleton::Skel;
    pub use super::skeleton::SkelBuilder;
}