Skip to content

Commit 08ff1c9

Browse files
sreevani-ship-itanakryiko
authored andcommitted
bpf, docs: Libbpf overview documentation
This patch documents overview of libbpf, including its features for developing BPF programs. Signed-off-by: Sreevani Sreejith <[email protected]> Signed-off-by: Andrii Nakryiko <[email protected]> Acked-by: David Vernet <[email protected]> Link: https://lore.kernel.org/bpf/[email protected]
1 parent 2be7aa7 commit 08ff1c9

File tree

2 files changed

+245
-8
lines changed

2 files changed

+245
-8
lines changed

Documentation/bpf/libbpf/index.rst

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,32 @@
22
33
.. _libbpf:
44

5+
======
56
libbpf
67
======
78

9+
If you are looking to develop BPF applications using the libbpf library, this
10+
directory contains important documentation that you should read.
11+
12+
To get started, it is recommended to begin with the :doc:`libbpf Overview
13+
<libbpf_overview>` document, which provides a high-level understanding of the
14+
libbpf APIs and their usage. This will give you a solid foundation to start
15+
exploring and utilizing the various features of libbpf to develop your BPF
16+
applications.
17+
818
.. toctree::
919
:maxdepth: 1
1020

21+
libbpf_overview
1122
API Documentation <https://libbpf.readthedocs.io/en/latest/api.html>
1223
program_types
1324
libbpf_naming_convention
1425
libbpf_build
1526

16-
This is documentation for libbpf, a userspace library for loading and
17-
interacting with bpf programs.
1827

19-
All general BPF questions, including kernel functionality, libbpf APIs and
20-
their application, should be sent to [email protected] mailing list.
21-
You can `subscribe <http://vger.kernel.org/vger-lists.html#bpf>`_ to the
22-
mailing list search its `archive <https://lore.kernel.org/bpf/>`_.
23-
Please search the archive before asking new questions. It very well might
24-
be that this was already addressed or answered before.
28+
All general BPF questions, including kernel functionality, libbpf APIs and their
29+
application, should be sent to [email protected] mailing list. You can
30+
`subscribe <http://vger.kernel.org/vger-lists.html#bpf>`_ to the mailing list
31+
search its `archive <https://lore.kernel.org/bpf/>`_. Please search the archive
32+
before asking new questions. It may be that this was already addressed or
33+
answered before.
Lines changed: 228 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,228 @@
1+
.. SPDX-License-Identifier: GPL-2.0
2+
3+
===============
4+
libbpf Overview
5+
===============
6+
7+
libbpf is a C-based library containing a BPF loader that takes compiled BPF
8+
object files and prepares and loads them into the Linux kernel. libbpf takes the
9+
heavy lifting of loading, verifying, and attaching BPF programs to various
10+
kernel hooks, allowing BPF application developers to focus only on BPF program
11+
correctness and performance.
12+
13+
The following are the high-level features supported by libbpf:
14+
15+
* Provides high-level and low-level APIs for user space programs to interact
16+
with BPF programs. The low-level APIs wrap all the bpf system call
17+
functionality, which is useful when users need more fine-grained control
18+
over the interactions between user space and BPF programs.
19+
* Provides overall support for the BPF object skeleton generated by bpftool.
20+
The skeleton file simplifies the process for the user space programs to access
21+
global variables and work with BPF programs.
22+
* Provides BPF-side APIS, including BPF helper definitions, BPF maps support,
23+
and tracing helpers, allowing developers to simplify BPF code writing.
24+
* Supports BPF CO-RE mechanism, enabling BPF developers to write portable
25+
BPF programs that can be compiled once and run across different kernel
26+
versions.
27+
28+
This document will delve into the above concepts in detail, providing a deeper
29+
understanding of the capabilities and advantages of libbpf and how it can help
30+
you develop BPF applications efficiently.
31+
32+
BPF App Lifecycle and libbpf APIs
33+
==================================
34+
35+
A BPF application consists of one or more BPF programs (either cooperating or
36+
completely independent), BPF maps, and global variables. The global
37+
variables are shared between all BPF programs, which allows them to cooperate on
38+
a common set of data. libbpf provides APIs that user space programs can use to
39+
manipulate the BPF programs by triggering different phases of a BPF application
40+
lifecycle.
41+
42+
The following section provides a brief overview of each phase in the BPF life
43+
cycle:
44+
45+
* **Open phase**: In this phase, libbpf parses the BPF
46+
object file and discovers BPF maps, BPF programs, and global variables. After
47+
a BPF app is opened, user space apps can make additional adjustments
48+
(setting BPF program types, if necessary; pre-setting initial values for
49+
global variables, etc.) before all the entities are created and loaded.
50+
51+
* **Load phase**: In the load phase, libbpf creates BPF
52+
maps, resolves various relocations, and verifies and loads BPF programs into
53+
the kernel. At this point, libbpf validates all the parts of a BPF application
54+
and loads the BPF program into the kernel, but no BPF program has yet been
55+
executed. After the load phase, it’s possible to set up the initial BPF map
56+
state without racing with the BPF program code execution.
57+
58+
* **Attachment phase**: In this phase, libbpf
59+
attaches BPF programs to various BPF hook points (e.g., tracepoints, kprobes,
60+
cgroup hooks, network packet processing pipeline, etc.). During this
61+
phase, BPF programs perform useful work such as processing
62+
packets, or updating BPF maps and global variables that can be read from user
63+
space.
64+
65+
* **Tear down phase**: In the tear down phase,
66+
libbpf detaches BPF programs and unloads them from the kernel. BPF maps are
67+
destroyed, and all the resources used by the BPF app are freed.
68+
69+
BPF Object Skeleton File
70+
========================
71+
72+
BPF skeleton is an alternative interface to libbpf APIs for working with BPF
73+
objects. Skeleton code abstract away generic libbpf APIs to significantly
74+
simplify code for manipulating BPF programs from user space. Skeleton code
75+
includes a bytecode representation of the BPF object file, simplifying the
76+
process of distributing your BPF code. With BPF bytecode embedded, there are no
77+
extra files to deploy along with your application binary.
78+
79+
You can generate the skeleton header file ``(.skel.h)`` for a specific object
80+
file by passing the BPF object to the bpftool. The generated BPF skeleton
81+
provides the following custom functions that correspond to the BPF lifecycle,
82+
each of them prefixed with the specific object name:
83+
84+
* ``<name>__open()`` – creates and opens BPF application (``<name>`` stands for
85+
the specific bpf object name)
86+
* ``<name>__load()`` – instantiates, loads,and verifies BPF application parts
87+
* ``<name>__attach()`` – attaches all auto-attachable BPF programs (it’s
88+
optional, you can have more control by using libbpf APIs directly)
89+
* ``<name>__destroy()`` – detaches all BPF programs and
90+
frees up all used resources
91+
92+
Using the skeleton code is the recommended way to work with bpf programs. Keep
93+
in mind, BPF skeleton provides access to the underlying BPF object, so whatever
94+
was possible to do with generic libbpf APIs is still possible even when the BPF
95+
skeleton is used. It's an additive convenience feature, with no syscalls, and no
96+
cumbersome code.
97+
98+
Other Advantages of Using Skeleton File
99+
---------------------------------------
100+
101+
* BPF skeleton provides an interface for user space programs to work with BPF
102+
global variables. The skeleton code memory maps global variables as a struct
103+
into user space. The struct interface allows user space programs to initialize
104+
BPF programs before the BPF load phase and fetch and update data from user
105+
space afterward.
106+
107+
* The ``skel.h`` file reflects the object file structure by listing out the
108+
available maps, programs, etc. BPF skeleton provides direct access to all the
109+
BPF maps and BPF programs as struct fields. This eliminates the need for
110+
string-based lookups with ``bpf_object_find_map_by_name()`` and
111+
``bpf_object_find_program_by_name()`` APIs, reducing errors due to BPF source
112+
code and user-space code getting out of sync.
113+
114+
* The embedded bytecode representation of the object file ensures that the
115+
skeleton and the BPF object file are always in sync.
116+
117+
BPF Helpers
118+
===========
119+
120+
libbpf provides BPF-side APIs that BPF programs can use to interact with the
121+
system. The BPF helpers definition allows developers to use them in BPF code as
122+
any other plain C function. For example, there are helper functions to print
123+
debugging messages, get the time since the system was booted, interact with BPF
124+
maps, manipulate network packets, etc.
125+
126+
For a complete description of what the helpers do, the arguments they take, and
127+
the return value, see the `bpf-helpers
128+
<https://man7.org/linux/man-pages/man7/bpf-helpers.7.html>`_ man page.
129+
130+
BPF CO-RE (Compile Once – Run Everywhere)
131+
=========================================
132+
133+
BPF programs work in the kernel space and have access to kernel memory and data
134+
structures. One limitation that BPF applications come across is the lack of
135+
portability across different kernel versions and configurations. `BCC
136+
<https://github.com/iovisor/bcc/>`_ is one of the solutions for BPF
137+
portability. However, it comes with runtime overhead and a large binary size
138+
from embedding the compiler with the application.
139+
140+
libbpf steps up the BPF program portability by supporting the BPF CO-RE concept.
141+
BPF CO-RE brings together BTF type information, libbpf, and the compiler to
142+
produce a single executable binary that you can run on multiple kernel versions
143+
and configurations.
144+
145+
To make BPF programs portable libbpf relies on the BTF type information of the
146+
running kernel. Kernel also exposes this self-describing authoritative BTF
147+
information through ``sysfs`` at ``/sys/kernel/btf/vmlinux``.
148+
149+
You can generate the BTF information for the running kernel with the following
150+
command:
151+
152+
::
153+
154+
$ bpftool btf dump file /sys/kernel/btf/vmlinux format c > vmlinux.h
155+
156+
The command generates a ``vmlinux.h`` header file with all kernel types
157+
(:doc:`BTF types <../btf>`) that the running kernel uses. Including
158+
``vmlinux.h`` in your BPF program eliminates dependency on system-wide kernel
159+
headers.
160+
161+
libbpf enables portability of BPF programs by looking at the BPF program’s
162+
recorded BTF type and relocation information and matching them to BTF
163+
information (vmlinux) provided by the running kernel. libbpf then resolves and
164+
matches all the types and fields, and updates necessary offsets and other
165+
relocatable data to ensure that BPF program’s logic functions correctly for a
166+
specific kernel on the host. BPF CO-RE concept thus eliminates overhead
167+
associated with BPF development and allows developers to write portable BPF
168+
applications without modifications and runtime source code compilation on the
169+
target machine.
170+
171+
The following code snippet shows how to read the parent field of a kernel
172+
``task_struct`` using BPF CO-RE and libbf. The basic helper to read a field in a
173+
CO-RE relocatable manner is ``bpf_core_read(dst, sz, src)``, which will read
174+
``sz`` bytes from the field referenced by ``src`` into the memory pointed to by
175+
``dst``.
176+
177+
.. code-block:: C
178+
:emphasize-lines: 6
179+
180+
//...
181+
struct task_struct *task = (void *)bpf_get_current_task();
182+
struct task_struct *parent_task;
183+
int err;
184+
185+
err = bpf_core_read(&parent_task, sizeof(void *), &task->parent);
186+
if (err) {
187+
/* handle error */
188+
}
189+
190+
/* parent_task contains the value of task->parent pointer */
191+
192+
In the code snippet, we first get a pointer to the current ``task_struct`` using
193+
``bpf_get_current_task()``. We then use ``bpf_core_read()`` to read the parent
194+
field of task struct into the ``parent_task`` variable. ``bpf_core_read()`` is
195+
just like ``bpf_probe_read_kernel()`` BPF helper, except it records information
196+
about the field that should be relocated on the target kernel. i.e, if the
197+
``parent`` field gets shifted to a different offset within
198+
``struct task_struct`` due to some new field added in front of it, libbpf will
199+
automatically adjust the actual offset to the proper value.
200+
201+
Getting Started with libbpf
202+
===========================
203+
204+
Check out the `libbpf-bootstrap <https://github.com/libbpf/libbpf-bootstrap>`_
205+
repository with simple examples of using libbpf to build various BPF
206+
applications.
207+
208+
See also `libbpf API documentation
209+
<https://libbpf.readthedocs.io/en/latest/api.html>`_.
210+
211+
libbpf and Rust
212+
===============
213+
214+
If you are building BPF applications in Rust, it is recommended to use the
215+
`Libbpf-rs <https://github.com/libbpf/libbpf-rs>`_ library instead of bindgen
216+
bindings directly to libbpf. Libbpf-rs wraps libbpf functionality in
217+
Rust-idiomatic interfaces and provides libbpf-cargo plugin to handle BPF code
218+
compilation and skeleton generation. Using Libbpf-rs will make building user
219+
space part of the BPF application easier. Note that the BPF program themselves
220+
must still be written in plain C.
221+
222+
Additional Documentation
223+
========================
224+
225+
* `Program types and ELF Sections <https://libbpf.readthedocs.io/en/latest/program_types.html>`_
226+
* `API naming convention <https://libbpf.readthedocs.io/en/latest/libbpf_naming_convention.html>`_
227+
* `Building libbpf <https://libbpf.readthedocs.io/en/latest/libbpf_build.html>`_
228+
* `API documentation Convention <https://libbpf.readthedocs.io/en/latest/libbpf_naming_convention.html#api-documentation-convention>`_

0 commit comments

Comments
 (0)