471 lines
16 KiB
ReStructuredText
471 lines
16 KiB
ReStructuredText
.. SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
|
|
|
================
|
|
bpftool-gen
|
|
================
|
|
-------------------------------------------------------------------------------
|
|
tool for BPF code-generation
|
|
-------------------------------------------------------------------------------
|
|
|
|
:Manual section: 8
|
|
|
|
.. include:: substitutions.rst
|
|
|
|
SYNOPSIS
|
|
========
|
|
|
|
**bpftool** [*OPTIONS*] **gen** *COMMAND*
|
|
|
|
*OPTIONS* := { |COMMON_OPTIONS| | { **-L** | **--use-loader** } }
|
|
|
|
*COMMAND* := { **object** | **skeleton** | **help** }
|
|
|
|
GEN COMMANDS
|
|
=============
|
|
|
|
| **bpftool** **gen object** *OUTPUT_FILE* *INPUT_FILE* [*INPUT_FILE*...]
|
|
| **bpftool** **gen skeleton** *FILE* [**name** *OBJECT_NAME*]
|
|
| **bpftool** **gen subskeleton** *FILE* [**name** *OBJECT_NAME*]
|
|
| **bpftool** **gen min_core_btf** *INPUT* *OUTPUT* *OBJECT* [*OBJECT*...]
|
|
| **bpftool** **gen help**
|
|
|
|
DESCRIPTION
|
|
===========
|
|
bpftool gen object *OUTPUT_FILE* *INPUT_FILE* [*INPUT_FILE*...]
|
|
Statically link (combine) together one or more *INPUT_FILE*'s into a single
|
|
resulting *OUTPUT_FILE*. All the files involved are BPF ELF object files.
|
|
|
|
The rules of BPF static linking are mostly the same as for user-space
|
|
object files, but in addition to combining data and instruction sections,
|
|
.BTF and .BTF.ext (if present in any of the input files) data are combined
|
|
together. .BTF data is deduplicated, so all the common types across
|
|
*INPUT_FILE*'s will only be represented once in the resulting BTF
|
|
information.
|
|
|
|
BPF static linking allows to partition BPF source code into individually
|
|
compiled files that are then linked into a single resulting BPF object
|
|
file, which can be used to generated BPF skeleton (with **gen skeleton**
|
|
command) or passed directly into **libbpf** (using **bpf_object__open()**
|
|
family of APIs).
|
|
|
|
bpftool gen skeleton *FILE*
|
|
Generate BPF skeleton C header file for a given *FILE*.
|
|
|
|
BPF skeleton is an alternative interface to existing libbpf APIs for
|
|
working with BPF objects. Skeleton code is intended to significantly
|
|
shorten and simplify code to load and work with BPF programs from userspace
|
|
side. Generated code is tailored to specific input BPF object *FILE*,
|
|
reflecting its structure by listing out available maps, program, variables,
|
|
etc. Skeleton eliminates the need to lookup mentioned components by name.
|
|
Instead, if skeleton instantiation succeeds, they are populated in skeleton
|
|
structure as valid libbpf types (e.g., **struct bpf_map** pointer) and can
|
|
be passed to existing generic libbpf APIs.
|
|
|
|
In addition to simple and reliable access to maps and programs, skeleton
|
|
provides a storage for BPF links (**struct bpf_link**) for each BPF program
|
|
within BPF object. When requested, supported BPF programs will be
|
|
automatically attached and resulting BPF links stored for further use by
|
|
user in pre-allocated fields in skeleton struct. For BPF programs that
|
|
can't be automatically attached by libbpf, user can attach them manually,
|
|
but store resulting BPF link in per-program link field. All such set up
|
|
links will be automatically destroyed on BPF skeleton destruction. This
|
|
eliminates the need for users to manage links manually and rely on libbpf
|
|
support to detach programs and free up resources.
|
|
|
|
Another facility provided by BPF skeleton is an interface to global
|
|
variables of all supported kinds: mutable, read-only, as well as extern
|
|
ones. This interface allows to pre-setup initial values of variables before
|
|
BPF object is loaded and verified by kernel. For non-read-only variables,
|
|
the same interface can be used to fetch values of global variables on
|
|
userspace side, even if they are modified by BPF code.
|
|
|
|
During skeleton generation, contents of source BPF object *FILE* is
|
|
embedded within generated code and is thus not necessary to keep around.
|
|
This ensures skeleton and BPF object file are matching 1-to-1 and always
|
|
stay in sync. Generated code is dual-licensed under LGPL-2.1 and
|
|
BSD-2-Clause licenses.
|
|
|
|
It is a design goal and guarantee that skeleton interfaces are
|
|
interoperable with generic libbpf APIs. User should always be able to use
|
|
skeleton API to create and load BPF object, and later use libbpf APIs to
|
|
keep working with specific maps, programs, etc.
|
|
|
|
As part of skeleton, few custom functions are generated. Each of them is
|
|
prefixed with object name. Object name can either be derived from object
|
|
file name, i.e., if BPF object file name is **example.o**, BPF object name
|
|
will be **example**. Object name can be also specified explicitly through
|
|
**name** *OBJECT_NAME* parameter. The following custom functions are
|
|
provided (assuming **example** as the object name):
|
|
|
|
- **example__open** and **example__open_opts**.
|
|
These functions are used to instantiate skeleton. It corresponds to
|
|
libbpf's **bpf_object__open**\ () API. **_opts** variants accepts extra
|
|
**bpf_object_open_opts** options.
|
|
|
|
- **example__load**.
|
|
This function creates maps, loads and verifies BPF programs, initializes
|
|
global data maps. It corresponds to libbpf's **bpf_object__load**\ ()
|
|
API.
|
|
|
|
- **example__open_and_load** combines **example__open** and
|
|
**example__load** invocations in one commonly used operation.
|
|
|
|
- **example__attach** and **example__detach**.
|
|
This pair of functions allow to attach and detach, correspondingly,
|
|
already loaded BPF object. Only BPF programs of types supported by libbpf
|
|
for auto-attachment will be auto-attached and their corresponding BPF
|
|
links instantiated. For other BPF programs, user can manually create a
|
|
BPF link and assign it to corresponding fields in skeleton struct.
|
|
**example__detach** will detach both links created automatically, as well
|
|
as those populated by user manually.
|
|
|
|
- **example__destroy**.
|
|
Detach and unload BPF programs, free up all the resources used by
|
|
skeleton and BPF object.
|
|
|
|
If BPF object has global variables, corresponding structs with memory
|
|
layout corresponding to global data data section layout will be created.
|
|
Currently supported ones are: *.data*, *.bss*, *.rodata*, and *.kconfig*
|
|
structs/data sections. These data sections/structs can be used to set up
|
|
initial values of variables, if set before **example__load**. Afterwards,
|
|
if target kernel supports memory-mapped BPF arrays, same structs can be
|
|
used to fetch and update (non-read-only) data from userspace, with same
|
|
simplicity as for BPF side.
|
|
|
|
bpftool gen subskeleton *FILE*
|
|
Generate BPF subskeleton C header file for a given *FILE*.
|
|
|
|
Subskeletons are similar to skeletons, except they do not own the
|
|
corresponding maps, programs, or global variables. They require that the
|
|
object file used to generate them is already loaded into a *bpf_object* by
|
|
some other means.
|
|
|
|
This functionality is useful when a library is included into a larger BPF
|
|
program. A subskeleton for the library would have access to all objects and
|
|
globals defined in it, without having to know about the larger program.
|
|
|
|
Consequently, there are only two functions defined for subskeletons:
|
|
|
|
- **example__open(bpf_object\*)**.
|
|
Instantiates a subskeleton from an already opened (but not necessarily
|
|
loaded) **bpf_object**.
|
|
|
|
- **example__destroy()**.
|
|
Frees the storage for the subskeleton but *does not* unload any BPF
|
|
programs or maps.
|
|
|
|
bpftool gen min_core_btf *INPUT* *OUTPUT* *OBJECT* [*OBJECT*...]
|
|
Generate a minimum BTF file as *OUTPUT*, derived from a given *INPUT* BTF
|
|
file, containing all needed BTF types so one, or more, given eBPF objects
|
|
CO-RE relocations may be satisfied.
|
|
|
|
When kernels aren't compiled with CONFIG_DEBUG_INFO_BTF, libbpf, when
|
|
loading an eBPF object, has to rely on external BTF files to be able to
|
|
calculate CO-RE relocations.
|
|
|
|
Usually, an external BTF file is built from existing kernel DWARF data
|
|
using pahole. It contains all the types used by its respective kernel image
|
|
and, because of that, is big.
|
|
|
|
The min_core_btf feature builds smaller BTF files, customized to one or
|
|
multiple eBPF objects, so they can be distributed together with an eBPF
|
|
CO-RE based application, turning the application portable to different
|
|
kernel versions.
|
|
|
|
Check examples below for more information on how to use it.
|
|
|
|
bpftool gen help
|
|
Print short help message.
|
|
|
|
OPTIONS
|
|
=======
|
|
.. include:: common_options.rst
|
|
|
|
-L, --use-loader
|
|
For skeletons, generate a "light" skeleton (also known as "loader"
|
|
skeleton). A light skeleton contains a loader eBPF program. It does not use
|
|
the majority of the libbpf infrastructure, and does not need libelf.
|
|
|
|
EXAMPLES
|
|
========
|
|
**$ cat example1.bpf.c**
|
|
|
|
::
|
|
|
|
#include <stdbool.h>
|
|
#include <linux/ptrace.h>
|
|
#include <linux/bpf.h>
|
|
#include <bpf/bpf_helpers.h>
|
|
|
|
const volatile int param1 = 42;
|
|
bool global_flag = true;
|
|
struct { int x; } data = {};
|
|
|
|
SEC("raw_tp/sys_enter")
|
|
int handle_sys_enter(struct pt_regs *ctx)
|
|
{
|
|
static long my_static_var;
|
|
if (global_flag)
|
|
my_static_var++;
|
|
else
|
|
data.x += param1;
|
|
return 0;
|
|
}
|
|
|
|
**$ cat example2.bpf.c**
|
|
|
|
::
|
|
|
|
#include <linux/ptrace.h>
|
|
#include <linux/bpf.h>
|
|
#include <bpf/bpf_helpers.h>
|
|
|
|
struct {
|
|
__uint(type, BPF_MAP_TYPE_HASH);
|
|
__uint(max_entries, 128);
|
|
__type(key, int);
|
|
__type(value, long);
|
|
} my_map SEC(".maps");
|
|
|
|
SEC("raw_tp/sys_exit")
|
|
int handle_sys_exit(struct pt_regs *ctx)
|
|
{
|
|
int zero = 0;
|
|
bpf_map_lookup_elem(&my_map, &zero);
|
|
return 0;
|
|
}
|
|
|
|
**$ cat example3.bpf.c**
|
|
|
|
::
|
|
|
|
#include <linux/ptrace.h>
|
|
#include <linux/bpf.h>
|
|
#include <bpf/bpf_helpers.h>
|
|
/* This header file is provided by the bpf_testmod module. */
|
|
#include "bpf_testmod.h"
|
|
|
|
int test_2_result = 0;
|
|
|
|
/* bpf_Testmod.ko calls this function, passing a "4"
|
|
* and testmod_map->data.
|
|
*/
|
|
SEC("struct_ops/test_2")
|
|
void BPF_PROG(test_2, int a, int b)
|
|
{
|
|
test_2_result = a + b;
|
|
}
|
|
|
|
SEC(".struct_ops")
|
|
struct bpf_testmod_ops testmod_map = {
|
|
.test_2 = (void *)test_2,
|
|
.data = 0x1,
|
|
};
|
|
|
|
This is example BPF application with three BPF programs and a mix of BPF
|
|
maps and global variables. Source code is split across three source code
|
|
files.
|
|
|
|
**$ clang --target=bpf -g example1.bpf.c -o example1.bpf.o**
|
|
|
|
**$ clang --target=bpf -g example2.bpf.c -o example2.bpf.o**
|
|
|
|
**$ clang --target=bpf -g example3.bpf.c -o example3.bpf.o**
|
|
|
|
**$ bpftool gen object example.bpf.o example1.bpf.o example2.bpf.o example3.bpf.o**
|
|
|
|
This set of commands compiles *example1.bpf.c*, *example2.bpf.c* and
|
|
*example3.bpf.c* individually and then statically links respective object
|
|
files into the final BPF ELF object file *example.bpf.o*.
|
|
|
|
**$ bpftool gen skeleton example.bpf.o name example | tee example.skel.h**
|
|
|
|
::
|
|
|
|
/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */
|
|
|
|
/* THIS FILE IS AUTOGENERATED! */
|
|
#ifndef __EXAMPLE_SKEL_H__
|
|
#define __EXAMPLE_SKEL_H__
|
|
|
|
#include <stdlib.h>
|
|
#include <bpf/libbpf.h>
|
|
|
|
struct example {
|
|
struct bpf_object_skeleton *skeleton;
|
|
struct bpf_object *obj;
|
|
struct {
|
|
struct bpf_map *rodata;
|
|
struct bpf_map *data;
|
|
struct bpf_map *bss;
|
|
struct bpf_map *my_map;
|
|
struct bpf_map *testmod_map;
|
|
} maps;
|
|
struct {
|
|
struct example__testmod_map__bpf_testmod_ops {
|
|
const struct bpf_program *test_1;
|
|
const struct bpf_program *test_2;
|
|
int data;
|
|
} *testmod_map;
|
|
} struct_ops;
|
|
struct {
|
|
struct bpf_program *handle_sys_enter;
|
|
struct bpf_program *handle_sys_exit;
|
|
} progs;
|
|
struct {
|
|
struct bpf_link *handle_sys_enter;
|
|
struct bpf_link *handle_sys_exit;
|
|
} links;
|
|
struct example__bss {
|
|
struct {
|
|
int x;
|
|
} data;
|
|
int test_2_result;
|
|
} *bss;
|
|
struct example__data {
|
|
_Bool global_flag;
|
|
long int handle_sys_enter_my_static_var;
|
|
} *data;
|
|
struct example__rodata {
|
|
int param1;
|
|
} *rodata;
|
|
};
|
|
|
|
static void example__destroy(struct example *obj);
|
|
static inline struct example *example__open_opts(
|
|
const struct bpf_object_open_opts *opts);
|
|
static inline struct example *example__open();
|
|
static inline int example__load(struct example *obj);
|
|
static inline struct example *example__open_and_load();
|
|
static inline int example__attach(struct example *obj);
|
|
static inline void example__detach(struct example *obj);
|
|
|
|
#endif /* __EXAMPLE_SKEL_H__ */
|
|
|
|
**$ cat example.c**
|
|
|
|
::
|
|
|
|
#include "example.skel.h"
|
|
|
|
int main()
|
|
{
|
|
struct example *skel;
|
|
int err = 0;
|
|
|
|
skel = example__open();
|
|
if (!skel)
|
|
goto cleanup;
|
|
|
|
skel->rodata->param1 = 128;
|
|
|
|
/* Change the value through the pointer of shadow type */
|
|
skel->struct_ops.testmod_map->data = 13;
|
|
|
|
err = example__load(skel);
|
|
if (err)
|
|
goto cleanup;
|
|
|
|
/* The result of the function test_2() */
|
|
printf("test_2_result: %d\n", skel->bss->test_2_result);
|
|
|
|
err = example__attach(skel);
|
|
if (err)
|
|
goto cleanup;
|
|
|
|
/* all libbpf APIs are usable */
|
|
printf("my_map name: %s\n", bpf_map__name(skel->maps.my_map));
|
|
printf("sys_enter prog FD: %d\n",
|
|
bpf_program__fd(skel->progs.handle_sys_enter));
|
|
|
|
/* detach and re-attach sys_exit program */
|
|
bpf_link__destroy(skel->links.handle_sys_exit);
|
|
skel->links.handle_sys_exit =
|
|
bpf_program__attach(skel->progs.handle_sys_exit);
|
|
|
|
printf("my_static_var: %ld\n",
|
|
skel->bss->handle_sys_enter_my_static_var);
|
|
|
|
cleanup:
|
|
example__destroy(skel);
|
|
return err;
|
|
}
|
|
|
|
**# ./example**
|
|
|
|
::
|
|
|
|
test_2_result: 17
|
|
my_map name: my_map
|
|
sys_enter prog FD: 8
|
|
my_static_var: 7
|
|
|
|
This is a stripped-out version of skeleton generated for above example code.
|
|
|
|
min_core_btf
|
|
------------
|
|
|
|
**$ bpftool btf dump file 5.4.0-example.btf format raw**
|
|
|
|
::
|
|
|
|
[1] INT 'long unsigned int' size=8 bits_offset=0 nr_bits=64 encoding=(none)
|
|
[2] CONST '(anon)' type_id=1
|
|
[3] VOLATILE '(anon)' type_id=1
|
|
[4] ARRAY '(anon)' type_id=1 index_type_id=21 nr_elems=2
|
|
[5] PTR '(anon)' type_id=8
|
|
[6] CONST '(anon)' type_id=5
|
|
[7] INT 'char' size=1 bits_offset=0 nr_bits=8 encoding=(none)
|
|
[8] CONST '(anon)' type_id=7
|
|
[9] INT 'unsigned int' size=4 bits_offset=0 nr_bits=32 encoding=(none)
|
|
<long output>
|
|
|
|
**$ bpftool btf dump file one.bpf.o format raw**
|
|
|
|
::
|
|
|
|
[1] PTR '(anon)' type_id=2
|
|
[2] STRUCT 'trace_event_raw_sys_enter' size=64 vlen=4
|
|
'ent' type_id=3 bits_offset=0
|
|
'id' type_id=7 bits_offset=64
|
|
'args' type_id=9 bits_offset=128
|
|
'__data' type_id=12 bits_offset=512
|
|
[3] STRUCT 'trace_entry' size=8 vlen=4
|
|
'type' type_id=4 bits_offset=0
|
|
'flags' type_id=5 bits_offset=16
|
|
'preempt_count' type_id=5 bits_offset=24
|
|
<long output>
|
|
|
|
**$ bpftool gen min_core_btf 5.4.0-example.btf 5.4.0-smaller.btf one.bpf.o**
|
|
|
|
**$ bpftool btf dump file 5.4.0-smaller.btf format raw**
|
|
|
|
::
|
|
|
|
[1] TYPEDEF 'pid_t' type_id=6
|
|
[2] STRUCT 'trace_event_raw_sys_enter' size=64 vlen=1
|
|
'args' type_id=4 bits_offset=128
|
|
[3] STRUCT 'task_struct' size=9216 vlen=2
|
|
'pid' type_id=1 bits_offset=17920
|
|
'real_parent' type_id=7 bits_offset=18048
|
|
[4] ARRAY '(anon)' type_id=5 index_type_id=8 nr_elems=6
|
|
[5] INT 'long unsigned int' size=8 bits_offset=0 nr_bits=64 encoding=(none)
|
|
[6] TYPEDEF '__kernel_pid_t' type_id=8
|
|
[7] PTR '(anon)' type_id=3
|
|
[8] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED
|
|
<end>
|
|
|
|
Now, the "5.4.0-smaller.btf" file may be used by libbpf as an external BTF file
|
|
when loading the "one.bpf.o" object into the "5.4.0-example" kernel. Note that
|
|
the generated BTF file won't allow other eBPF objects to be loaded, just the
|
|
ones given to min_core_btf.
|
|
|
|
::
|
|
|
|
LIBBPF_OPTS(bpf_object_open_opts, opts, .btf_custom_path = "5.4.0-smaller.btf");
|
|
struct bpf_object *obj;
|
|
|
|
obj = bpf_object__open_file("one.bpf.o", &opts);
|
|
|
|
...
|