libbpf_overview.rst 11 KB

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