€•×°Œsphinx.addnodes”Œdocument”“”)�”}”(Œ rawsource”Œ”Œchildren”]”(Œ translations”Œ LanguagesNode”“”)�”}”(hhh]”(hŒ pending_xref”“”)�”}”(hhh]”Œdocutils.nodes”ŒText”“”ŒChinese (Simplified)”…”�”}”Œparent”hsbaŒ attributes”}”(Œids”]”Œclasses”]”Œnames”]”Œdupnames”]”Œbackrefs”]”Œ refdomain”Œstd”Œreftype”Œdoc”Œ reftarget”Œ./translations/zh_CN/bpf/libbpf/libbpf_overview”Œmodname”NŒ classname”NŒ refexplicit”ˆuŒtagname”hhh ubh)�”}”(hhh]”hŒChinese (Traditional)”…”�”}”hh2sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ./translations/zh_TW/bpf/libbpf/libbpf_overview”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒItalian”…”�”}”hhFsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ./translations/it_IT/bpf/libbpf/libbpf_overview”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒJapanese”…”�”}”hhZsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ./translations/ja_JP/bpf/libbpf/libbpf_overview”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒKorean”…”�”}”hhnsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ./translations/ko_KR/bpf/libbpf/libbpf_overview”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒPortuguese (Brazilian)”…”�”}”hh‚sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ./translations/pt_BR/bpf/libbpf/libbpf_overview”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒSpanish”…”�”}”hh–sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ./translations/sp_SP/bpf/libbpf/libbpf_overview”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubeh}”(h]”h ]”h"]”h$]”h&]”Œcurrent_language”ŒEnglish”uh1h hhŒ _document”hŒsource”NŒline”NubhŒcomment”“”)�”}”(hŒ SPDX-License-Identifier: GPL-2.0”h]”hŒ SPDX-License-Identifier: GPL-2.0”…”�”}”hh·sbah}”(h]”h ]”h"]”h$]”h&]”Œ xml:space”Œpreserve”uh1hµhhh²hh³ŒH/var/lib/git/docbuild/linux/Documentation/bpf/libbpf/libbpf_overview.rst”h´KubhŒsection”“”)�”}”(hhh]”(hŒtitle”“”)�”}”(hŒlibbpf Overview”h]”hŒlibbpf Overview”…”�”}”(hhÏh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhhÊh²hh³hÇh´KubhŒ paragraph”“”)�”}”(hXSlibbpf is a C-based library containing a BPF loader that takes compiled BPF object files and prepares and loads them into the Linux kernel. libbpf takes the heavy lifting of loading, verifying, and attaching BPF programs to various kernel hooks, allowing BPF application developers to focus only on BPF program correctness and performance.”h]”hXSlibbpf is a C-based library containing a BPF loader that takes compiled BPF object files and prepares and loads them into the Linux kernel. libbpf takes the heavy lifting of loading, verifying, and attaching BPF programs to various kernel hooks, allowing BPF application developers to focus only on BPF program correctness and performance.”…”�”}”(hhßh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KhhÊh²hubhÞ)�”}”(hŒ>The following are the high-level features supported by libbpf:”h]”hŒ>The following are the high-level features supported by libbpf:”…”�”}”(hhíh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K hhÊh²hubhŒ bullet_list”“”)�”}”(hhh]”(hŒ list_item”“”)�”}”(hXProvides high-level and low-level APIs for user space programs to interact with BPF programs. The low-level APIs wrap all the bpf system call functionality, which is useful when users need more fine-grained control over the interactions between user space and BPF programs.”h]”hÞ)�”}”(hXProvides high-level and low-level APIs for user space programs to interact with BPF programs. The low-level APIs wrap all the bpf system call functionality, which is useful when users need more fine-grained control over the interactions between user space and BPF programs.”h]”hXProvides high-level and low-level APIs for user space programs to interact with BPF programs. The low-level APIs wrap all the bpf system call functionality, which is useful when users need more fine-grained control over the interactions between user space and BPF programs.”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Khjubah}”(h]”h ]”h"]”h$]”h&]”uh1jhhýh²hh³hÇh´Nubj)�”}”(hŒÆProvides overall support for the BPF object skeleton generated by bpftool. The skeleton file simplifies the process for the user space programs to access global variables and work with BPF programs.”h]”hÞ)�”}”(hŒÆProvides overall support for the BPF object skeleton generated by bpftool. The skeleton file simplifies the process for the user space programs to access global variables and work with BPF programs.”h]”hŒÆProvides overall support for the BPF object skeleton generated by bpftool. The skeleton file simplifies the process for the user space programs to access global variables and work with BPF programs.”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Khjubah}”(h]”h ]”h"]”h$]”h&]”uh1jhhýh²hh³hÇh´Nubj)�”}”(hŒ’Provides BPF-side APIS, including BPF helper definitions, BPF maps support, and tracing helpers, allowing developers to simplify BPF code writing.”h]”hÞ)�”}”(hŒ’Provides BPF-side APIS, including BPF helper definitions, BPF maps support, and tracing helpers, allowing developers to simplify BPF code writing.”h]”hŒ’Provides BPF-side APIS, including BPF helper definitions, BPF maps support, and tracing helpers, allowing developers to simplify BPF code writing.”…”�”}”(hj6h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Khj2ubah}”(h]”h ]”h"]”h$]”h&]”uh1jhhýh²hh³hÇh´Nubj)�”}”(hŒ™Supports BPF CO-RE mechanism, enabling BPF developers to write portable BPF programs that can be compiled once and run across different kernel versions. ”h]”hÞ)�”}”(hŒ˜Supports BPF CO-RE mechanism, enabling BPF developers to write portable BPF programs that can be compiled once and run across different kernel versions.”h]”hŒ˜Supports BPF CO-RE mechanism, enabling BPF developers to write portable BPF programs that can be compiled once and run across different kernel versions.”…”�”}”(hjNh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KhjJubah}”(h]”h ]”h"]”h$]”h&]”uh1jhhýh²hh³hÇh´Nubeh}”(h]”h ]”h"]”h$]”h&]”Œbullet”Œ*”uh1hûh³hÇh´KhhÊh²hubhÞ)�”}”(hŒÇThis document will delve into the above concepts in detail, providing a deeper understanding of the capabilities and advantages of libbpf and how it can help you develop BPF applications efficiently.”h]”hŒÇThis document will delve into the above concepts in detail, providing a deeper understanding of the capabilities and advantages of libbpf and how it can help you develop BPF applications efficiently.”…”�”}”(hjjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KhhÊh²hubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒ!BPF App Lifecycle and libbpf APIs”h]”hŒ!BPF App Lifecycle and libbpf APIs”…”�”}”(hj{h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhjxh²hh³hÇh´K!ubhÞ)�”}”(hXŒA BPF application consists of one or more BPF programs (either cooperating or completely independent), BPF maps, and global variables. The global variables are shared between all BPF programs, which allows them to cooperate on a common set of data. libbpf provides APIs that user space programs can use to manipulate the BPF programs by triggering different phases of a BPF application lifecycle.”h]”hXŒA BPF application consists of one or more BPF programs (either cooperating or completely independent), BPF maps, and global variables. The global variables are shared between all BPF programs, which allows them to cooperate on a common set of data. libbpf provides APIs that user space programs can use to manipulate the BPF programs by triggering different phases of a BPF application lifecycle.”…”�”}”(hj‰h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K#hjxh²hubhÞ)�”}”(hŒTThe following section provides a brief overview of each phase in the BPF life cycle:”h]”hŒTThe following section provides a brief overview of each phase in the BPF life cycle:”…”�”}”(hj—h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K*hjxh²hubhü)�”}”(hhh]”(j)�”}”(hXY**Open phase**: In this phase, libbpf parses the BPF object file and discovers BPF maps, BPF programs, and global variables. After a BPF app is opened, user space apps can make additional adjustments (setting BPF program types, if necessary; pre-setting initial values for global variables, etc.) before all the entities are created and loaded. ”h]”hÞ)�”}”(hXX**Open phase**: In this phase, libbpf parses the BPF object file and discovers BPF maps, BPF programs, and global variables. After a BPF app is opened, user space apps can make additional adjustments (setting BPF program types, if necessary; pre-setting initial values for global variables, etc.) before all the entities are created and loaded.”h]”(hŒstrong”“”)�”}”(hŒ**Open phase**”h]”hŒ Open phase”…”�”}”(hj²h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j°hj¬ubhXJ: In this phase, libbpf parses the BPF object file and discovers BPF maps, BPF programs, and global variables. After a BPF app is opened, user space apps can make additional adjustments (setting BPF program types, if necessary; pre-setting initial values for global variables, etc.) before all the entities are created and loaded.”…”�”}”(hj¬h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K-hj¨ubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj¥h²hh³hÇh´Nubj)�”}”(hX¥**Load phase**: In the load phase, libbpf creates BPF maps, resolves various relocations, and verifies and loads BPF programs into the kernel. At this point, libbpf validates all the parts of a BPF application and loads the BPF program into the kernel, but no BPF program has yet been executed. After the load phase, it’s possible to set up the initial BPF map state without racing with the BPF program code execution. ”h]”hÞ)�”}”(hX¤**Load phase**: In the load phase, libbpf creates BPF maps, resolves various relocations, and verifies and loads BPF programs into the kernel. At this point, libbpf validates all the parts of a BPF application and loads the BPF program into the kernel, but no BPF program has yet been executed. After the load phase, it’s possible to set up the initial BPF map state without racing with the BPF program code execution.”h]”(j±)�”}”(hŒ**Load phase**”h]”hŒ Load phase”…”�”}”(hjØh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j°hjÔubhX–: In the load phase, libbpf creates BPF maps, resolves various relocations, and verifies and loads BPF programs into the kernel. At this point, libbpf validates all the parts of a BPF application and loads the BPF program into the kernel, but no BPF program has yet been executed. After the load phase, it’s possible to set up the initial BPF map state without racing with the BPF program code execution.”…”�”}”(hjÔh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K3hjÐubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj¥h²hh³hÇh´Nubj)�”}”(hXO**Attachment phase**: In this phase, libbpf attaches BPF programs to various BPF hook points (e.g., tracepoints, kprobes, cgroup hooks, network packet processing pipeline, etc.). During this phase, BPF programs perform useful work such as processing packets, or updating BPF maps and global variables that can be read from user space. ”h]”hÞ)�”}”(hXN**Attachment phase**: In this phase, libbpf attaches BPF programs to various BPF hook points (e.g., tracepoints, kprobes, cgroup hooks, network packet processing pipeline, etc.). During this phase, BPF programs perform useful work such as processing packets, or updating BPF maps and global variables that can be read from user space.”h]”(j±)�”}”(hŒ**Attachment phase**”h]”hŒAttachment phase”…”�”}”(hjþh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j°hjúubhX:: In this phase, libbpf attaches BPF programs to various BPF hook points (e.g., tracepoints, kprobes, cgroup hooks, network packet processing pipeline, etc.). During this phase, BPF programs perform useful work such as processing packets, or updating BPF maps and global variables that can be read from user space.”…”�”}”(hjúh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K:hjöubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj¥h²hh³hÇh´Nubj)�”}”(hŒ¹**Tear down phase**: In the tear down phase, libbpf detaches BPF programs and unloads them from the kernel. BPF maps are destroyed, and all the resources used by the BPF app are freed. ”h]”hÞ)�”}”(hŒ¸**Tear down phase**: In the tear down phase, libbpf detaches BPF programs and unloads them from the kernel. BPF maps are destroyed, and all the resources used by the BPF app are freed.”h]”(j±)�”}”(hŒ**Tear down phase**”h]”hŒTear down phase”…”�”}”(hj$h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j°hj ubhŒ¥: In the tear down phase, libbpf detaches BPF programs and unloads them from the kernel. BPF maps are destroyed, and all the resources used by the BPF app are freed.”…”�”}”(hj h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KAhjubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj¥h²hh³hÇh´Nubeh}”(h]”h ]”h"]”h$]”h&]”jhjiuh1hûh³hÇh´K-hjxh²hubeh}”(h]”Œ!bpf-app-lifecycle-and-libbpf-apis”ah ]”h"]”Œ!bpf app lifecycle and libbpf apis”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´K!ubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒBPF Object Skeleton File”h]”hŒBPF Object Skeleton File”…”�”}”(hjSh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhjPh²hh³hÇh´KFubhÞ)�”}”(hX¶BPF skeleton is an alternative interface to libbpf APIs for working with BPF objects. Skeleton code abstract away generic libbpf APIs to significantly simplify code for manipulating BPF programs from user space. Skeleton code includes a bytecode representation of the BPF object file, simplifying the process of distributing your BPF code. With BPF bytecode embedded, there are no extra files to deploy along with your application binary.”h]”hX¶BPF skeleton is an alternative interface to libbpf APIs for working with BPF objects. Skeleton code abstract away generic libbpf APIs to significantly simplify code for manipulating BPF programs from user space. Skeleton code includes a bytecode representation of the BPF object file, simplifying the process of distributing your BPF code. With BPF bytecode embedded, there are no extra files to deploy along with your application binary.”…”�”}”(hjah²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KHhjPh²hubhÞ)�”}”(hXYou can generate the skeleton header file ``(.skel.h)`` for a specific object file by passing the BPF object to the bpftool. The generated BPF skeleton provides the following custom functions that correspond to the BPF lifecycle, each of them prefixed with the specific object name:”h]”(hŒ*You can generate the skeleton header file ”…”�”}”(hjoh²hh³Nh´NubhŒliteral”“”)�”}”(hŒ ``(.skel.h)``”h]”hŒ (.skel.h)”…”�”}”(hjyh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jwhjoubhŒã for a specific object file by passing the BPF object to the bpftool. The generated BPF skeleton provides the following custom functions that correspond to the BPF lifecycle, each of them prefixed with the specific object name:”…”�”}”(hjoh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KOhjPh²hubhü)�”}”(hhh]”(j)�”}”(hŒm``__open()`` – creates and opens BPF application (```` stands for the specific bpf object name)”h]”hÞ)�”}”(hŒm``__open()`` – creates and opens BPF application (```` stands for the specific bpf object name)”h]”(jx)�”}”(hŒ``__open()``”h]”hŒ__open()”…”�”}”(hjœh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jwhj˜ubhŒ( – creates and opens BPF application (”…”�”}”(hj˜h²hh³Nh´Nubjx)�”}”(hŒ ````”h]”hŒ”…”�”}”(hj®h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jwhj˜ubhŒ) stands for the specific bpf object name)”…”�”}”(hj˜h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KThj”ubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj‘h²hh³hÇh´Nubj)�”}”(hŒM``__load()`` – instantiates, loads,and verifies BPF application parts”h]”hÞ)�”}”(hjÎh]”(jx)�”}”(hŒ``__load()``”h]”hŒ__load()”…”�”}”(hjÓh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jwhjÐubhŒ; – instantiates, loads,and verifies BPF application parts”…”�”}”(hjÐh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KVhjÌubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj‘h²hh³hÇh´Nubj)�”}”(hŒ�``__attach()`` – attaches all auto-attachable BPF programs (it’s optional, you can have more control by using libbpf APIs directly)”h]”hÞ)�”}”(hŒ�``__attach()`` – attaches all auto-attachable BPF programs (it’s optional, you can have more control by using libbpf APIs directly)”h]”(jx)�”}”(hŒ``__attach()``”h]”hŒ__attach()”…”�”}”(hjùh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jwhjõubhŒy – attaches all auto-attachable BPF programs (it’s optional, you can have more control by using libbpf APIs directly)”…”�”}”(hjõh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KWhjñubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj‘h²hh³hÇh´Nubj)�”}”(hŒT``__destroy()`` – detaches all BPF programs and frees up all used resources ”h]”hÞ)�”}”(hŒS``__destroy()`` – detaches all BPF programs and frees up all used resources”h]”(jx)�”}”(hŒ``__destroy()``”h]”hŒ__destroy()”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jwhjubhŒ> – detaches all BPF programs and frees up all used resources”…”�”}”(hjh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KYhjubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj‘h²hh³hÇh´Nubeh}”(h]”h ]”h"]”h$]”h&]”jhjiuh1hûh³hÇh´KThjPh²hubhÞ)�”}”(hXPUsing the skeleton code is the recommended way to work with bpf programs. Keep in mind, BPF skeleton provides access to the underlying BPF object, so whatever was possible to do with generic libbpf APIs is still possible even when the BPF skeleton is used. It's an additive convenience feature, with no syscalls, and no cumbersome code.”h]”hXRUsing the skeleton code is the recommended way to work with bpf programs. Keep in mind, BPF skeleton provides access to the underlying BPF object, so whatever was possible to do with generic libbpf APIs is still possible even when the BPF skeleton is used. It’s an additive convenience feature, with no syscalls, and no cumbersome code.”…”�”}”(hjCh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K\hjPh²hubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒ'Other Advantages of Using Skeleton File”h]”hŒ'Other Advantages of Using Skeleton File”…”�”}”(hjTh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhjQh²hh³hÇh´Kcubhü)�”}”(hhh]”(j)�”}”(hXDBPF skeleton provides an interface for user space programs to work with BPF global variables. The skeleton code memory maps global variables as a struct into user space. The struct interface allows user space programs to initialize BPF programs before the BPF load phase and fetch and update data from user space afterward. ”h]”hÞ)�”}”(hXCBPF skeleton provides an interface for user space programs to work with BPF global variables. The skeleton code memory maps global variables as a struct into user space. The struct interface allows user space programs to initialize BPF programs before the BPF load phase and fetch and update data from user space afterward.”h]”hXCBPF skeleton provides an interface for user space programs to work with BPF global variables. The skeleton code memory maps global variables as a struct into user space. The struct interface allows user space programs to initialize BPF programs before the BPF load phase and fetch and update data from user space afterward.”…”�”}”(hjih²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Kehjeubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjbh²hh³hÇh´Nubj)�”}”(hX�The ``skel.h`` file reflects the object file structure by listing out the available maps, programs, etc. BPF skeleton provides direct access to all the BPF maps and BPF programs as struct fields. This eliminates the need for string-based lookups with ``bpf_object_find_map_by_name()`` and ``bpf_object_find_program_by_name()`` APIs, reducing errors due to BPF source code and user-space code getting out of sync. ”h]”hÞ)�”}”(hXœThe ``skel.h`` file reflects the object file structure by listing out the available maps, programs, etc. BPF skeleton provides direct access to all the BPF maps and BPF programs as struct fields. This eliminates the need for string-based lookups with ``bpf_object_find_map_by_name()`` and ``bpf_object_find_program_by_name()`` APIs, reducing errors due to BPF source code and user-space code getting out of sync.”h]”(hŒThe ”…”�”}”(hj�h²hh³Nh´Nubjx)�”}”(hŒ ``skel.h``”h]”hŒskel.h”…”�”}”(hj‰h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jwhj�ubhŒí file reflects the object file structure by listing out the available maps, programs, etc. BPF skeleton provides direct access to all the BPF maps and BPF programs as struct fields. This eliminates the need for string-based lookups with ”…”�”}”(hj�h²hh³Nh´Nubjx)�”}”(hŒ!``bpf_object_find_map_by_name()``”h]”hŒbpf_object_find_map_by_name()”…”�”}”(hj›h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jwhj�ubhŒ and ”…”�”}”(hj�h²hh³Nh´Nubjx)�”}”(hŒ%``bpf_object_find_program_by_name()``”h]”hŒ!bpf_object_find_program_by_name()”…”�”}”(hj­h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jwhj�ubhŒV APIs, reducing errors due to BPF source code and user-space code getting out of sync.”…”�”}”(hj�h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Kkhj}ubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjbh²hh³hÇh´Nubj)�”}”(hŒ~The embedded bytecode representation of the object file ensures that the skeleton and the BPF object file are always in sync. ”h]”hÞ)�”}”(hŒ}The embedded bytecode representation of the object file ensures that the skeleton and the BPF object file are always in sync.”h]”hŒ}The embedded bytecode representation of the object file ensures that the skeleton and the BPF object file are always in sync.”…”�”}”(hjÏh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KrhjËubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjbh²hh³hÇh´Nubeh}”(h]”h ]”h"]”h$]”h&]”jhjiuh1hûh³hÇh´KehjQh²hubeh}”(h]”Œ'other-advantages-of-using-skeleton-file”ah ]”h"]”Œ'other advantages of using skeleton file”ah$]”h&]”uh1hÈhjPh²hh³hÇh´Kcubeh}”(h]”Œbpf-object-skeleton-file”ah ]”h"]”Œbpf object skeleton file”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´KFubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒ BPF Helpers”h]”hŒ BPF Helpers”…”�”}”(hjüh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhjùh²hh³hÇh´KvubhÞ)�”}”(hX`libbpf provides BPF-side APIs that BPF programs can use to interact with the system. The BPF helpers definition allows developers to use them in BPF code as any other plain C function. For example, there are helper functions to print debugging messages, get the time since the system was booted, interact with BPF maps, manipulate network packets, etc.”h]”hX`libbpf provides BPF-side APIs that BPF programs can use to interact with the system. The BPF helpers definition allows developers to use them in BPF code as any other plain C function. For example, there are helper functions to print debugging messages, get the time since the system was booted, interact with BPF maps, manipulate network packets, etc.”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Kxhjùh²hubhÞ)�”}”(hŒ½For a complete description of what the helpers do, the arguments they take, and the return value, see the `bpf-helpers `_ man page.”h]”(hŒjFor a complete description of what the helpers do, the arguments they take, and the return value, see the ”…”�”}”(hjh²hh³Nh´NubhŒ reference”“”)�”}”(hŒI`bpf-helpers `_”h]”hŒ bpf-helpers”…”�”}”(hj"h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”Œname”Œ bpf-helpers”Œrefuri”Œ8https://man7.org/linux/man-pages/man7/bpf-helpers.7.html”uh1j hjubhŒtarget”“”)�”}”(hŒ; ”h]”h}”(h]”Œid1”ah ]”h"]”Œ bpf-helpers”ah$]”h&]”Œrefuri”j3uh1j4Œ referenced”KhjubhŒ man page.”…”�”}”(hjh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K~hjùh²hubeh}”(h]”Œ bpf-helpers”ah ]”h"]”Œ bpf helpers”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´KvubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒ+BPF CO-RE (Compile Once – Run Everywhere)”h]”hŒ+BPF CO-RE (Compile Once – Run Everywhere)”…”�”}”(hjYh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhjVh²hh³hÇh´KƒubhÞ)�”}”(hX¤BPF programs work in the kernel space and have access to kernel memory and data structures. One limitation that BPF applications come across is the lack of portability across different kernel versions and configurations. `BCC `_ is one of the solutions for BPF portability. However, it comes with runtime overhead and a large binary size from embedding the compiler with the application.”h]”(hŒÝBPF programs work in the kernel space and have access to kernel memory and data structures. One limitation that BPF applications come across is the lack of portability across different kernel versions and configurations. ”…”�”}”(hjgh²hh³Nh´Nubj!)�”}”(hŒ(`BCC `_”h]”hŒBCC”…”�”}”(hjoh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”Œname”ŒBCC”j2Œhttps://github.com/iovisor/bcc/”uh1j hjgubj5)�”}”(hŒ" ”h]”h}”(h]”Œbcc”ah ]”h"]”Œbcc”ah$]”h&]”Œrefuri”juh1j4jCKhjgubhŒŸ is one of the solutions for BPF portability. However, it comes with runtime overhead and a large binary size from embedding the compiler with the application.”…”�”}”(hjgh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K…hjVh²hubhÞ)�”}”(hXlibbpf steps up the BPF program portability by supporting the BPF CO-RE concept. BPF CO-RE brings together BTF type information, libbpf, and the compiler to produce a single executable binary that you can run on multiple kernel versions and configurations.”h]”hXlibbpf steps up the BPF program portability by supporting the BPF CO-RE concept. BPF CO-RE brings together BTF type information, libbpf, and the compiler to produce a single executable binary that you can run on multiple kernel versions and configurations.”…”�”}”(hj—h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KŒhjVh²hubhÞ)�”}”(hŒ×To make BPF programs portable libbpf relies on the BTF type information of the running kernel. Kernel also exposes this self-describing authoritative BTF information through ``sysfs`` at ``/sys/kernel/btf/vmlinux``.”h]”(hŒ®To make BPF programs portable libbpf relies on the BTF type information of the running kernel. Kernel also exposes this self-describing authoritative BTF information through ”…”�”}”(hj¥h²hh³Nh´Nubjx)�”}”(hŒ ``sysfs``”h]”hŒsysfs”…”�”}”(hj­h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jwhj¥ubhŒ at ”…”�”}”(hj¥h²hh³Nh´Nubjx)�”}”(hŒ``/sys/kernel/btf/vmlinux``”h]”hŒ/sys/kernel/btf/vmlinux”…”�”}”(hj¿h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jwhj¥ubhŒ.”…”�”}”(hj¥h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K‘hjVh²hubhÞ)�”}”(hŒWYou can generate the BTF information for the running kernel with the following command:”h]”hŒWYou can generate the BTF information for the running kernel with the following command:”…”�”}”(hj×h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K•hjVh²hubhŒ literal_block”“”)�”}”(hŒD$ bpftool btf dump file /sys/kernel/btf/vmlinux format c > vmlinux.h”h]”hŒD$ bpftool btf dump file /sys/kernel/btf/vmlinux format c > vmlinux.h”…”�”}”hjçsbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1jåh³hÇh´KšhjVh²hubhÞ)�”}”(hŒâThe command generates a ``vmlinux.h`` header file with all kernel types (:doc:`BTF types <../btf>`) that the running kernel uses. Including ``vmlinux.h`` in your BPF program eliminates dependency on system-wide kernel headers.”h]”(hŒThe command generates a ”…”�”}”(hjõh²hh³Nh´Nubjx)�”}”(hŒ ``vmlinux.h``”h]”hŒ vmlinux.h”…”�”}”(hjýh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jwhjõubhŒ$ header file with all kernel types (”…”�”}”(hjõh²hh³Nh´Nubh)�”}”(hŒ:doc:`BTF types <../btf>`”h]”hŒinline”“”)�”}”(hjh]”hŒ BTF types”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”(Œxref”Œstd”Œstd-doc”eh"]”h$]”h&]”uh1jhjubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”Œbpf/libbpf/libbpf_overview”Œ refdomain”j Œreftype”Œdoc”Œ refexplicit”ˆŒrefwarn”ˆŒ reftarget”Œ../btf”uh1hh³hÇh´KœhjõubhŒ*) that the running kernel uses. Including ”…”�”}”(hjõh²hh³Nh´Nubjx)�”}”(hŒ ``vmlinux.h``”h]”hŒ vmlinux.h”…”�”}”(hj8h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jwhjõubhŒI in your BPF program eliminates dependency on system-wide kernel headers.”…”�”}”(hjõh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KœhjVh²hubhÞ)�”}”(hXmlibbpf enables portability of BPF programs by looking at the BPF program’s recorded BTF type and relocation information and matching them to BTF information (vmlinux) provided by the running kernel. libbpf then resolves and matches all the types and fields, and updates necessary offsets and other relocatable data to ensure that BPF program’s logic functions correctly for a specific kernel on the host. BPF CO-RE concept thus eliminates overhead associated with BPF development and allows developers to write portable BPF applications without modifications and runtime source code compilation on the target machine.”h]”hXmlibbpf enables portability of BPF programs by looking at the BPF program’s recorded BTF type and relocation information and matching them to BTF information (vmlinux) provided by the running kernel. libbpf then resolves and matches all the types and fields, and updates necessary offsets and other relocatable data to ensure that BPF program’s logic functions correctly for a specific kernel on the host. BPF CO-RE concept thus eliminates overhead associated with BPF development and allows developers to write portable BPF applications without modifications and runtime source code compilation on the target machine.”…”�”}”(hjPh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K¡hjVh²hubhÞ)�”}”(hX@The following code snippet shows how to read the parent field of a kernel ``task_struct`` using BPF CO-RE and libbf. The basic helper to read a field in a CO-RE relocatable manner is ``bpf_core_read(dst, sz, src)``, which will read ``sz`` bytes from the field referenced by ``src`` into the memory pointed to by ``dst``.”h]”(hŒJThe following code snippet shows how to read the parent field of a kernel ”…”�”}”(hj^h²hh³Nh´Nubjx)�”}”(hŒ``task_struct``”h]”hŒ task_struct”…”�”}”(hjfh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jwhj^ubhŒ^ using BPF CO-RE and libbf. The basic helper to read a field in a CO-RE relocatable manner is ”…”�”}”(hj^h²hh³Nh´Nubjx)�”}”(hŒ``bpf_core_read(dst, sz, src)``”h]”hŒbpf_core_read(dst, sz, src)”…”�”}”(hjxh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jwhj^ubhŒ, which will read ”…”�”}”(hj^h²hh³Nh´Nubjx)�”}”(hŒ``sz``”h]”hŒsz”…”�”}”(hjŠh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jwhj^ubhŒ$ bytes from the field referenced by ”…”�”}”(hj^h²hh³Nh´Nubjx)�”}”(hŒ``src``”h]”hŒsrc”…”�”}”(hjœh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jwhj^ubhŒ into the memory pointed to by ”…”�”}”(hj^h²hh³Nh´Nubjx)�”}”(hŒ``dst``”h]”hŒdst”…”�”}”(hj®h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jwhj^ubhŒ.”…”�”}”(hj^h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K«hjVh²hubjæ)�”}”(hX //... struct task_struct *task = (void *)bpf_get_current_task(); struct task_struct *parent_task; int err; err = bpf_core_read(&parent_task, sizeof(void *), &task->parent); if (err) { /* handle error */ } /* parent_task contains the value of task->parent pointer */”h]”hX //... struct task_struct *task = (void *)bpf_get_current_task(); struct task_struct *parent_task; int err; err = bpf_core_read(&parent_task, sizeof(void *), &task->parent); if (err) { /* handle error */ } /* parent_task contains the value of task->parent pointer */”…”�”}”hjÆsbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆŒforce”‰Œlanguage”ŒC”Œhighlight_args”}”Œhl_lines”]”Kasuh1jåh³hÇh´K±hjVh²hubhÞ)�”}”(hXPIn the code snippet, we first get a pointer to the current ``task_struct`` using ``bpf_get_current_task()``. We then use ``bpf_core_read()`` to read the parent field of task struct into the ``parent_task`` variable. ``bpf_core_read()`` is just like ``bpf_probe_read_kernel()`` BPF helper, except it records information about the field that should be relocated on the target kernel. i.e, if the ``parent`` field gets shifted to a different offset within ``struct task_struct`` due to some new field added in front of it, libbpf will automatically adjust the actual offset to the proper value.”h]”(hŒ;In the code snippet, we first get a pointer to the current ”…”�”}”(hjÛh²hh³Nh´Nubjx)�”}”(hŒ``task_struct``”h]”hŒ task_struct”…”�”}”(hjãh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jwhjÛubhŒ using ”…”�”}”(hjÛh²hh³Nh´Nubjx)�”}”(hŒ``bpf_get_current_task()``”h]”hŒbpf_get_current_task()”…”�”}”(hjõh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jwhjÛubhŒ. We then use ”…”�”}”(hjÛh²hh³Nh´Nubjx)�”}”(hŒ``bpf_core_read()``”h]”hŒbpf_core_read()”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jwhjÛubhŒ2 to read the parent field of task struct into the ”…”�”}”(hjÛh²hh³Nh´Nubjx)�”}”(hŒ``parent_task``”h]”hŒ parent_task”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jwhjÛubhŒ variable. ”…”�”}”(hjÛh²hh³Nh´Nubjx)�”}”(hŒ``bpf_core_read()``”h]”hŒbpf_core_read()”…”�”}”(hj+h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jwhjÛubhŒ is just like ”…”�”}”(hjÛh²hh³Nh´Nubjx)�”}”(hŒ``bpf_probe_read_kernel()``”h]”hŒbpf_probe_read_kernel()”…”�”}”(hj=h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jwhjÛubhŒv BPF helper, except it records information about the field that should be relocated on the target kernel. i.e, if the ”…”�”}”(hjÛh²hh³Nh´Nubjx)�”}”(hŒ ``parent``”h]”hŒparent”…”�”}”(hjOh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jwhjÛubhŒ1 field gets shifted to a different offset within ”…”�”}”(hjÛh²hh³Nh´Nubjx)�”}”(hŒ``struct task_struct``”h]”hŒstruct task_struct”…”�”}”(hjah²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jwhjÛubhŒt due to some new field added in front of it, libbpf will automatically adjust the actual offset to the proper value.”…”�”}”(hjÛh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KÀhjVh²hubeh}”(h]”Œ%bpf-co-re-compile-once-run-everywhere”ah ]”h"]”Œ+bpf co-re (compile once – run everywhere)”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´KƒubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒGetting Started with libbpf”h]”hŒGetting Started with libbpf”…”�”}”(hj„h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhj�h²hh³hÇh´KÊubhÞ)�”}”(hŒ¡Check out the `libbpf-bootstrap `_ repository with simple examples of using libbpf to build various BPF applications.”h]”(hŒCheck out the ”…”�”}”(hj’h²hh³Nh´Nubj!)�”}”(hŒ@`libbpf-bootstrap `_”h]”hŒlibbpf-bootstrap”…”�”}”(hjšh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”Œname”Œlibbpf-bootstrap”j2Œ*https://github.com/libbpf/libbpf-bootstrap”uh1j hj’ubj5)�”}”(hŒ- ”h]”h}”(h]”Œlibbpf-bootstrap”ah ]”h"]”Œlibbpf-bootstrap”ah$]”h&]”Œrefuri”jªuh1j4jCKhj’ubhŒS repository with simple examples of using libbpf to build various BPF applications.”…”�”}”(hj’h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KÌhj�h²hubhÞ)�”}”(hŒXSee also `libbpf API documentation `_.”h]”(hŒ See also ”…”�”}”(hjÂh²hh³Nh´Nubj!)�”}”(hŒN`libbpf API documentation `_”h]”hŒlibbpf API documentation”…”�”}”(hjÊh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”Œname”Œlibbpf API documentation”j2Œ0https://libbpf.readthedocs.io/en/latest/api.html”uh1j hjÂubj5)�”}”(hŒ3 ”h]”h}”(h]”Œlibbpf-api-documentation”ah ]”h"]”Œlibbpf api documentation”ah$]”h&]”Œrefuri”jÚuh1j4jCKhjÂubhŒ.”…”�”}”(hjÂh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KÐhj�h²hubeh}”(h]”Œgetting-started-with-libbpf”ah ]”h"]”Œgetting started with libbpf”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´KÊubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒlibbpf and Rust”h]”hŒlibbpf and Rust”…”�”}”(hjýh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhjúh²hh³hÇh´KÔubhÞ)�”}”(hXéIf you are building BPF applications in Rust, it is recommended to use the `Libbpf-rs `_ library instead of bindgen bindings directly to libbpf. Libbpf-rs wraps libbpf functionality in Rust-idiomatic interfaces and provides libbpf-cargo plugin to handle BPF code compilation and skeleton generation. Using Libbpf-rs will make building user space part of the BPF application easier. Note that the BPF program themselves must still be written in plain C.”h]”(hŒKIf you are building BPF applications in Rust, it is recommended to use the ”…”�”}”(hj h²hh³Nh´Nubj!)�”}”(hŒ2`Libbpf-rs `_”h]”hŒ Libbpf-rs”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”Œname”Œ Libbpf-rs”j2Œ#https://github.com/libbpf/libbpf-rs”uh1j hj ubj5)�”}”(hŒ& ”h]”h}”(h]”Œ libbpf-rs”ah ]”h"]”Œ libbpf-rs”ah$]”h&]”Œrefuri”j#uh1j4jCKhj ubhXl library instead of bindgen bindings directly to libbpf. Libbpf-rs wraps libbpf functionality in Rust-idiomatic interfaces and provides libbpf-cargo plugin to handle BPF code compilation and skeleton generation. Using Libbpf-rs will make building user space part of the BPF application easier. Note that the BPF program themselves must still be written in plain C.”…”�”}”(hj h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KÖhjúh²hubeh}”(h]”Œlibbpf-and-rust”ah ]”h"]”Œlibbpf and rust”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´KÔubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒlibbpf logging”h]”hŒlibbpf logging”…”�”}”(hjFh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhjCh²hh³hÇh´KßubhÞ)�”}”(hX By default, libbpf logs informational and warning messages to stderr. The verbosity of these messages can be controlled by setting the environment variable LIBBPF_LOG_LEVEL to either warn, info, or debug. A custom log callback can be set using ``libbpf_set_print()``.”h]”(hŒôBy default, libbpf logs informational and warning messages to stderr. The verbosity of these messages can be controlled by setting the environment variable LIBBPF_LOG_LEVEL to either warn, info, or debug. A custom log callback can be set using ”…”�”}”(hjTh²hh³Nh´Nubjx)�”}”(hŒ``libbpf_set_print()``”h]”hŒlibbpf_set_print()”…”�”}”(hj\h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jwhjTubhŒ.”…”�”}”(hjTh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KáhjCh²hubeh}”(h]”Œlibbpf-logging”ah ]”h"]”Œlibbpf logging”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´KßubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒAdditional Documentation”h]”hŒAdditional Documentation”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhj|h²hh³hÇh´Kçubhü)�”}”(hhh]”(j)�”}”(hŒ^`Program types and ELF Sections `_”h]”hÞ)�”}”(hj’h]”(j!)�”}”(hj’h]”hŒProgram types and ELF Sections”…”�”}”(hj—h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”Œname”ŒProgram types and ELF Sections”j2Œ:https://libbpf.readthedocs.io/en/latest/program_types.html”uh1j hj”ubj5)�”}”(hŒ= ”h]”h}”(h]”Œprogram-types-and-elf-sections”ah ]”h"]”Œprogram types and elf sections”ah$]”h&]”Œrefuri”j¦uh1j4jCKhj”ubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Kéhj�ubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj�h²hh³hÇh´Nubj)�”}”(hŒ``API naming convention `_”h]”hÞ)�”}”(hjÂh]”(j!)�”}”(hjÂh]”hŒAPI naming convention”…”�”}”(hjÇh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”Œname”ŒAPI naming convention”j2ŒEhttps://libbpf.readthedocs.io/en/latest/libbpf_naming_convention.html”uh1j hjÄubj5)�”}”(hŒH ”h]”h}”(h]”Œapi-naming-convention”ah ]”h"]”Œapi naming convention”ah$]”h&]”Œrefuri”jÖuh1j4jCKhjÄubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KêhjÀubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj�h²hh³hÇh´Nubj)�”}”(hŒN`Building libbpf `_”h]”hÞ)�”}”(hjòh]”(j!)�”}”(hjòh]”hŒBuilding libbpf”…”�”}”(hj÷h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”Œname”ŒBuilding libbpf”j2Œ9https://libbpf.readthedocs.io/en/latest/libbpf_build.html”uh1j hjôubj5)�”}”(hŒ< ”h]”h}”(h]”Œbuilding-libbpf”ah ]”h"]”Œbuilding libbpf”ah$]”h&]”Œrefuri”juh1j4jCKhjôubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Këhjðubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj�h²hh³hÇh´Nubj)�”}”(hŒ„`API documentation Convention `_”h]”hÞ)�”}”(hj"h]”(j!)�”}”(hj"h]”hŒAPI documentation Convention”…”�”}”(hj'h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”Œname”ŒAPI documentation Convention”j2Œbhttps://libbpf.readthedocs.io/en/latest/libbpf_naming_convention.html#api-documentation-convention”uh1j hj$ubj5)�”}”(hŒe ”h]”h}”(h]”Œapi-documentation-convention”ah ]”h"]”Œapi documentation convention”ah$]”h&]”Œrefuri”j6uh1j4jCKhj$ubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Kìhj ubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj�h²hh³hÇh´Nubeh}”(h]”h ]”h"]”h$]”h&]”jhjiuh1hûh³hÇh´Kéhj|h²hubeh}”(h]”Œadditional-documentation”ah ]”h"]”Œadditional documentation”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´Kçubeh}”(h]”Œlibbpf-overview”ah ]”h"]”Œlibbpf overview”ah$]”h&]”uh1hÈhhh²hh³hÇh´Kubeh}”(h]”h ]”h"]”h$]”h&]”Œsource”hÇuh1hŒcurrent_source”NŒ current_line”NŒsettings”Œdocutils.frontend”ŒValues”“”)�”}”(hÍNŒ generator”NŒ datestamp”NŒ source_link”NŒ source_url”NŒ toc_backlinks”Œentry”Œfootnote_backlinks”KŒ sectnum_xform”KŒstrip_comments”NŒstrip_elements_with_classes”NŒ strip_classes”NŒ report_level”KŒ halt_level”KŒexit_status_level”KŒdebug”NŒwarning_stream”NŒ traceback”ˆŒinput_encoding”Œ utf-8-sig”Œinput_encoding_error_handler”Œstrict”Œoutput_encoding”Œutf-8”Œoutput_encoding_error_handler”j‰Œerror_encoding”Œutf-8”Œerror_encoding_error_handler”Œbackslashreplace”Œ language_code”Œen”Œrecord_dependencies”NŒconfig”NŒ id_prefix”hŒauto_id_prefix”Œid”Œ dump_settings”NŒdump_internals”NŒdump_transforms”NŒdump_pseudo_xml”NŒexpose_internals”NŒstrict_visitor”NŒ_disable_config”NŒ_source”hÇŒ _destination”NŒ _config_files”]”Œ7/var/lib/git/docbuild/linux/Documentation/docutils.conf”aŒfile_insertion_enabled”ˆŒ raw_enabled”KŒline_length_limit”M'Œpep_references”NŒ pep_base_url”Œhttps://peps.python.org/”Œpep_file_url_template”Œpep-%04d”Œrfc_references”NŒ rfc_base_url”Œ&https://datatracker.ietf.org/doc/html/”Œ tab_width”KŒtrim_footnote_reference_space”‰Œsyntax_highlight”Œlong”Œ smart_quotes”ˆŒsmartquotes_locales”]”Œcharacter_level_inline_markup”‰Œdoctitle_xform”‰Œ docinfo_xform”KŒsectsubtitle_xform”‰Œ image_loading”Œlink”Œembed_stylesheet”‰Œcloak_email_addresses”ˆŒsection_self_link”‰Œenv”NubŒreporter”NŒindirect_targets”]”Œsubstitution_defs”}”Œsubstitution_names”}”Œrefnames”}”Œrefids”}”Œnameids”}”(jcj`jMjJjöjójîjëjSjPj?j<j~j{j‰j†j÷jôj´j±jäjáj@j=j-j*jyjvj[jXj°j­jàjÝjj j@j=uŒ nametypes”}”(jc‰jM‰jö‰jî‰jS‰j?ˆj~‰j‰ˆj÷‰j´ˆjäˆj@‰j-ˆjy‰j[‰j°ˆjàˆjˆj@ˆuh}”(j`hÊjJjxjójPjëjQjPjùj<j6j{jVj†j€jôj�j±j«jájÛj=júj*j$jvjCjXj|j­j§jÝj×j jj=j7uŒ footnote_refs”}”Œ citation_refs”}”Œ autofootnotes”]”Œautofootnote_refs”]”Œsymbol_footnotes”]”Œsymbol_footnote_refs”]”Œ footnotes”]”Œ citations”]”Œautofootnote_start”KŒsymbol_footnote_start”KŒ id_counter”Œ collections”ŒCounter”“”}”j—Ks…”R”Œparse_messages”]”Œtransform_messages”]”Œ transformer”NŒ include_log”]”Œ decoration”Nh²hub.