1*4882a593Smuzhiyun================ 2*4882a593Smuzhiyunbpftool-gen 3*4882a593Smuzhiyun================ 4*4882a593Smuzhiyun------------------------------------------------------------------------------- 5*4882a593Smuzhiyuntool for BPF code-generation 6*4882a593Smuzhiyun------------------------------------------------------------------------------- 7*4882a593Smuzhiyun 8*4882a593Smuzhiyun:Manual section: 8 9*4882a593Smuzhiyun 10*4882a593SmuzhiyunSYNOPSIS 11*4882a593Smuzhiyun======== 12*4882a593Smuzhiyun 13*4882a593Smuzhiyun **bpftool** [*OPTIONS*] **gen** *COMMAND* 14*4882a593Smuzhiyun 15*4882a593Smuzhiyun *OPTIONS* := { { **-j** | **--json** } [{ **-p** | **--pretty** }] } 16*4882a593Smuzhiyun 17*4882a593Smuzhiyun *COMMAND* := { **skeleton** | **help** } 18*4882a593Smuzhiyun 19*4882a593SmuzhiyunGEN COMMANDS 20*4882a593Smuzhiyun============= 21*4882a593Smuzhiyun 22*4882a593Smuzhiyun| **bpftool** **gen skeleton** *FILE* 23*4882a593Smuzhiyun| **bpftool** **gen help** 24*4882a593Smuzhiyun 25*4882a593SmuzhiyunDESCRIPTION 26*4882a593Smuzhiyun=========== 27*4882a593Smuzhiyun **bpftool gen skeleton** *FILE* 28*4882a593Smuzhiyun Generate BPF skeleton C header file for a given *FILE*. 29*4882a593Smuzhiyun 30*4882a593Smuzhiyun BPF skeleton is an alternative interface to existing libbpf 31*4882a593Smuzhiyun APIs for working with BPF objects. Skeleton code is intended 32*4882a593Smuzhiyun to significantly shorten and simplify code to load and work 33*4882a593Smuzhiyun with BPF programs from userspace side. Generated code is 34*4882a593Smuzhiyun tailored to specific input BPF object *FILE*, reflecting its 35*4882a593Smuzhiyun structure by listing out available maps, program, variables, 36*4882a593Smuzhiyun etc. Skeleton eliminates the need to lookup mentioned 37*4882a593Smuzhiyun components by name. Instead, if skeleton instantiation 38*4882a593Smuzhiyun succeeds, they are populated in skeleton structure as valid 39*4882a593Smuzhiyun libbpf types (e.g., **struct bpf_map** pointer) and can be 40*4882a593Smuzhiyun passed to existing generic libbpf APIs. 41*4882a593Smuzhiyun 42*4882a593Smuzhiyun In addition to simple and reliable access to maps and 43*4882a593Smuzhiyun programs, skeleton provides a storage for BPF links (**struct 44*4882a593Smuzhiyun bpf_link**) for each BPF program within BPF object. When 45*4882a593Smuzhiyun requested, supported BPF programs will be automatically 46*4882a593Smuzhiyun attached and resulting BPF links stored for further use by 47*4882a593Smuzhiyun user in pre-allocated fields in skeleton struct. For BPF 48*4882a593Smuzhiyun programs that can't be automatically attached by libbpf, 49*4882a593Smuzhiyun user can attach them manually, but store resulting BPF link 50*4882a593Smuzhiyun in per-program link field. All such set up links will be 51*4882a593Smuzhiyun automatically destroyed on BPF skeleton destruction. This 52*4882a593Smuzhiyun eliminates the need for users to manage links manually and 53*4882a593Smuzhiyun rely on libbpf support to detach programs and free up 54*4882a593Smuzhiyun resources. 55*4882a593Smuzhiyun 56*4882a593Smuzhiyun Another facility provided by BPF skeleton is an interface to 57*4882a593Smuzhiyun global variables of all supported kinds: mutable, read-only, 58*4882a593Smuzhiyun as well as extern ones. This interface allows to pre-setup 59*4882a593Smuzhiyun initial values of variables before BPF object is loaded and 60*4882a593Smuzhiyun verified by kernel. For non-read-only variables, the same 61*4882a593Smuzhiyun interface can be used to fetch values of global variables on 62*4882a593Smuzhiyun userspace side, even if they are modified by BPF code. 63*4882a593Smuzhiyun 64*4882a593Smuzhiyun During skeleton generation, contents of source BPF object 65*4882a593Smuzhiyun *FILE* is embedded within generated code and is thus not 66*4882a593Smuzhiyun necessary to keep around. This ensures skeleton and BPF 67*4882a593Smuzhiyun object file are matching 1-to-1 and always stay in sync. 68*4882a593Smuzhiyun Generated code is dual-licensed under LGPL-2.1 and 69*4882a593Smuzhiyun BSD-2-Clause licenses. 70*4882a593Smuzhiyun 71*4882a593Smuzhiyun It is a design goal and guarantee that skeleton interfaces 72*4882a593Smuzhiyun are interoperable with generic libbpf APIs. User should 73*4882a593Smuzhiyun always be able to use skeleton API to create and load BPF 74*4882a593Smuzhiyun object, and later use libbpf APIs to keep working with 75*4882a593Smuzhiyun specific maps, programs, etc. 76*4882a593Smuzhiyun 77*4882a593Smuzhiyun As part of skeleton, few custom functions are generated. 78*4882a593Smuzhiyun Each of them is prefixed with object name, derived from 79*4882a593Smuzhiyun object file name. I.e., if BPF object file name is 80*4882a593Smuzhiyun **example.o**, BPF object name will be **example**. The 81*4882a593Smuzhiyun following custom functions are provided in such case: 82*4882a593Smuzhiyun 83*4882a593Smuzhiyun - **example__open** and **example__open_opts**. 84*4882a593Smuzhiyun These functions are used to instantiate skeleton. It 85*4882a593Smuzhiyun corresponds to libbpf's **bpf_object__open**\ () API. 86*4882a593Smuzhiyun **_opts** variants accepts extra **bpf_object_open_opts** 87*4882a593Smuzhiyun options. 88*4882a593Smuzhiyun 89*4882a593Smuzhiyun - **example__load**. 90*4882a593Smuzhiyun This function creates maps, loads and verifies BPF 91*4882a593Smuzhiyun programs, initializes global data maps. It corresponds to 92*4882a593Smuzhiyun libppf's **bpf_object__load**\ () API. 93*4882a593Smuzhiyun 94*4882a593Smuzhiyun - **example__open_and_load** combines **example__open** and 95*4882a593Smuzhiyun **example__load** invocations in one commonly used 96*4882a593Smuzhiyun operation. 97*4882a593Smuzhiyun 98*4882a593Smuzhiyun - **example__attach** and **example__detach** 99*4882a593Smuzhiyun This pair of functions allow to attach and detach, 100*4882a593Smuzhiyun correspondingly, already loaded BPF object. Only BPF 101*4882a593Smuzhiyun programs of types supported by libbpf for auto-attachment 102*4882a593Smuzhiyun will be auto-attached and their corresponding BPF links 103*4882a593Smuzhiyun instantiated. For other BPF programs, user can manually 104*4882a593Smuzhiyun create a BPF link and assign it to corresponding fields in 105*4882a593Smuzhiyun skeleton struct. **example__detach** will detach both 106*4882a593Smuzhiyun links created automatically, as well as those populated by 107*4882a593Smuzhiyun user manually. 108*4882a593Smuzhiyun 109*4882a593Smuzhiyun - **example__destroy** 110*4882a593Smuzhiyun Detach and unload BPF programs, free up all the resources 111*4882a593Smuzhiyun used by skeleton and BPF object. 112*4882a593Smuzhiyun 113*4882a593Smuzhiyun If BPF object has global variables, corresponding structs 114*4882a593Smuzhiyun with memory layout corresponding to global data data section 115*4882a593Smuzhiyun layout will be created. Currently supported ones are: *.data*, 116*4882a593Smuzhiyun *.bss*, *.rodata*, and *.kconfig* structs/data sections. 117*4882a593Smuzhiyun These data sections/structs can be used to set up initial 118*4882a593Smuzhiyun values of variables, if set before **example__load**. 119*4882a593Smuzhiyun Afterwards, if target kernel supports memory-mapped BPF 120*4882a593Smuzhiyun arrays, same structs can be used to fetch and update 121*4882a593Smuzhiyun (non-read-only) data from userspace, with same simplicity 122*4882a593Smuzhiyun as for BPF side. 123*4882a593Smuzhiyun 124*4882a593Smuzhiyun **bpftool gen help** 125*4882a593Smuzhiyun Print short help message. 126*4882a593Smuzhiyun 127*4882a593SmuzhiyunOPTIONS 128*4882a593Smuzhiyun======= 129*4882a593Smuzhiyun .. include:: common_options.rst 130*4882a593Smuzhiyun 131*4882a593SmuzhiyunEXAMPLES 132*4882a593Smuzhiyun======== 133*4882a593Smuzhiyun**$ cat example.c** 134*4882a593Smuzhiyun 135*4882a593Smuzhiyun:: 136*4882a593Smuzhiyun 137*4882a593Smuzhiyun #include <stdbool.h> 138*4882a593Smuzhiyun #include <linux/ptrace.h> 139*4882a593Smuzhiyun #include <linux/bpf.h> 140*4882a593Smuzhiyun #include "bpf_helpers.h" 141*4882a593Smuzhiyun 142*4882a593Smuzhiyun const volatile int param1 = 42; 143*4882a593Smuzhiyun bool global_flag = true; 144*4882a593Smuzhiyun struct { int x; } data = {}; 145*4882a593Smuzhiyun 146*4882a593Smuzhiyun struct { 147*4882a593Smuzhiyun __uint(type, BPF_MAP_TYPE_HASH); 148*4882a593Smuzhiyun __uint(max_entries, 128); 149*4882a593Smuzhiyun __type(key, int); 150*4882a593Smuzhiyun __type(value, long); 151*4882a593Smuzhiyun } my_map SEC(".maps"); 152*4882a593Smuzhiyun 153*4882a593Smuzhiyun SEC("raw_tp/sys_enter") 154*4882a593Smuzhiyun int handle_sys_enter(struct pt_regs *ctx) 155*4882a593Smuzhiyun { 156*4882a593Smuzhiyun static long my_static_var; 157*4882a593Smuzhiyun if (global_flag) 158*4882a593Smuzhiyun my_static_var++; 159*4882a593Smuzhiyun else 160*4882a593Smuzhiyun data.x += param1; 161*4882a593Smuzhiyun return 0; 162*4882a593Smuzhiyun } 163*4882a593Smuzhiyun 164*4882a593Smuzhiyun SEC("raw_tp/sys_exit") 165*4882a593Smuzhiyun int handle_sys_exit(struct pt_regs *ctx) 166*4882a593Smuzhiyun { 167*4882a593Smuzhiyun int zero = 0; 168*4882a593Smuzhiyun bpf_map_lookup_elem(&my_map, &zero); 169*4882a593Smuzhiyun return 0; 170*4882a593Smuzhiyun } 171*4882a593Smuzhiyun 172*4882a593SmuzhiyunThis is example BPF application with two BPF programs and a mix of BPF maps 173*4882a593Smuzhiyunand global variables. 174*4882a593Smuzhiyun 175*4882a593Smuzhiyun**$ bpftool gen skeleton example.o** 176*4882a593Smuzhiyun 177*4882a593Smuzhiyun:: 178*4882a593Smuzhiyun 179*4882a593Smuzhiyun /* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */ 180*4882a593Smuzhiyun 181*4882a593Smuzhiyun /* THIS FILE IS AUTOGENERATED! */ 182*4882a593Smuzhiyun #ifndef __EXAMPLE_SKEL_H__ 183*4882a593Smuzhiyun #define __EXAMPLE_SKEL_H__ 184*4882a593Smuzhiyun 185*4882a593Smuzhiyun #include <stdlib.h> 186*4882a593Smuzhiyun #include <bpf/libbpf.h> 187*4882a593Smuzhiyun 188*4882a593Smuzhiyun struct example { 189*4882a593Smuzhiyun struct bpf_object_skeleton *skeleton; 190*4882a593Smuzhiyun struct bpf_object *obj; 191*4882a593Smuzhiyun struct { 192*4882a593Smuzhiyun struct bpf_map *rodata; 193*4882a593Smuzhiyun struct bpf_map *data; 194*4882a593Smuzhiyun struct bpf_map *bss; 195*4882a593Smuzhiyun struct bpf_map *my_map; 196*4882a593Smuzhiyun } maps; 197*4882a593Smuzhiyun struct { 198*4882a593Smuzhiyun struct bpf_program *handle_sys_enter; 199*4882a593Smuzhiyun struct bpf_program *handle_sys_exit; 200*4882a593Smuzhiyun } progs; 201*4882a593Smuzhiyun struct { 202*4882a593Smuzhiyun struct bpf_link *handle_sys_enter; 203*4882a593Smuzhiyun struct bpf_link *handle_sys_exit; 204*4882a593Smuzhiyun } links; 205*4882a593Smuzhiyun struct example__bss { 206*4882a593Smuzhiyun struct { 207*4882a593Smuzhiyun int x; 208*4882a593Smuzhiyun } data; 209*4882a593Smuzhiyun } *bss; 210*4882a593Smuzhiyun struct example__data { 211*4882a593Smuzhiyun _Bool global_flag; 212*4882a593Smuzhiyun long int handle_sys_enter_my_static_var; 213*4882a593Smuzhiyun } *data; 214*4882a593Smuzhiyun struct example__rodata { 215*4882a593Smuzhiyun int param1; 216*4882a593Smuzhiyun } *rodata; 217*4882a593Smuzhiyun }; 218*4882a593Smuzhiyun 219*4882a593Smuzhiyun static void example__destroy(struct example *obj); 220*4882a593Smuzhiyun static inline struct example *example__open_opts( 221*4882a593Smuzhiyun const struct bpf_object_open_opts *opts); 222*4882a593Smuzhiyun static inline struct example *example__open(); 223*4882a593Smuzhiyun static inline int example__load(struct example *obj); 224*4882a593Smuzhiyun static inline struct example *example__open_and_load(); 225*4882a593Smuzhiyun static inline int example__attach(struct example *obj); 226*4882a593Smuzhiyun static inline void example__detach(struct example *obj); 227*4882a593Smuzhiyun 228*4882a593Smuzhiyun #endif /* __EXAMPLE_SKEL_H__ */ 229*4882a593Smuzhiyun 230*4882a593Smuzhiyun**$ cat example_user.c** 231*4882a593Smuzhiyun 232*4882a593Smuzhiyun:: 233*4882a593Smuzhiyun 234*4882a593Smuzhiyun #include "example.skel.h" 235*4882a593Smuzhiyun 236*4882a593Smuzhiyun int main() 237*4882a593Smuzhiyun { 238*4882a593Smuzhiyun struct example *skel; 239*4882a593Smuzhiyun int err = 0; 240*4882a593Smuzhiyun 241*4882a593Smuzhiyun skel = example__open(); 242*4882a593Smuzhiyun if (!skel) 243*4882a593Smuzhiyun goto cleanup; 244*4882a593Smuzhiyun 245*4882a593Smuzhiyun skel->rodata->param1 = 128; 246*4882a593Smuzhiyun 247*4882a593Smuzhiyun err = example__load(skel); 248*4882a593Smuzhiyun if (err) 249*4882a593Smuzhiyun goto cleanup; 250*4882a593Smuzhiyun 251*4882a593Smuzhiyun err = example__attach(skel); 252*4882a593Smuzhiyun if (err) 253*4882a593Smuzhiyun goto cleanup; 254*4882a593Smuzhiyun 255*4882a593Smuzhiyun /* all libbpf APIs are usable */ 256*4882a593Smuzhiyun printf("my_map name: %s\n", bpf_map__name(skel->maps.my_map)); 257*4882a593Smuzhiyun printf("sys_enter prog FD: %d\n", 258*4882a593Smuzhiyun bpf_program__fd(skel->progs.handle_sys_enter)); 259*4882a593Smuzhiyun 260*4882a593Smuzhiyun /* detach and re-attach sys_exit program */ 261*4882a593Smuzhiyun bpf_link__destroy(skel->links.handle_sys_exit); 262*4882a593Smuzhiyun skel->links.handle_sys_exit = 263*4882a593Smuzhiyun bpf_program__attach(skel->progs.handle_sys_exit); 264*4882a593Smuzhiyun 265*4882a593Smuzhiyun printf("my_static_var: %ld\n", 266*4882a593Smuzhiyun skel->bss->handle_sys_enter_my_static_var); 267*4882a593Smuzhiyun 268*4882a593Smuzhiyun cleanup: 269*4882a593Smuzhiyun example__destroy(skel); 270*4882a593Smuzhiyun return err; 271*4882a593Smuzhiyun } 272*4882a593Smuzhiyun 273*4882a593Smuzhiyun**# ./example_user** 274*4882a593Smuzhiyun 275*4882a593Smuzhiyun:: 276*4882a593Smuzhiyun 277*4882a593Smuzhiyun my_map name: my_map 278*4882a593Smuzhiyun sys_enter prog FD: 8 279*4882a593Smuzhiyun my_static_var: 7 280*4882a593Smuzhiyun 281*4882a593SmuzhiyunThis is a stripped-out version of skeleton generated for above example code. 282