This commit is contained in:
yunwei37
2023-08-14 12:54:25 +00:00
parent a11dbe5999
commit e6c9607bdc
9 changed files with 3192 additions and 3350 deletions

View File

@@ -166,137 +166,148 @@
<div id="content" class="content">
<main>
<h1 id="bpf-features-by-linux-kernel-version"><a class="header" href="#bpf-features-by-linux-kernel-version">BPF Features by Linux Kernel Version</a></h1>
<h2 id="ebpf-support"><a class="header" href="#ebpf-support">eBPF support</a></h2>
<div class="table-wrapper"><table><thead><tr><th>Kernel version</th><th>Commit</th></tr></thead><tbody>
<h1 id="linux-内核版本的-bpf-功能"><a class="header" href="#linux-内核版本的-bpf-功能">Linux 内核版本的 BPF 功能</a></h1>
<h2 id="ebpf支持"><a class="header" href="#ebpf支持">eBPF支持</a></h2>
<div class="table-wrapper"><table><thead><tr><th>内核版本</th><th>提交</th></tr></thead><tbody>
<tr><td>3.15</td><td><a href="https://github.com/torvalds/linux/commit/bd4cf0ed331a275e9bf5a49e6d0fd55dffc551b8"><code>bd4cf0ed331a</code></a></td></tr>
</tbody></table>
</div>
<h2 id="jit-compiling"><a class="header" href="#jit-compiling">JIT compiling</a></h2>
<p>The list of supported architectures for your kernel can be retrieved with:</p>
<h2 id="jit编译"><a class="header" href="#jit编译">JIT编译</a></h2>
<p>可以使用以下命令获取内核支持的体系结构列表:</p>
<pre><code class="language-sh">git grep HAVE_EBPF_JIT arch/
</code></pre>
<div class="table-wrapper"><table><thead><tr><th>Feature / Architecture</th><th>Kernel version</th><th>Commit</th></tr></thead><tbody>
<div class="table-wrapper"><table><thead><tr><th>功能 / 体系结构</th><th>内核版本</th><th>提交</th></tr></thead><tbody>
<tr><td>x86_64</td><td>3.16</td><td><a href="https://github.com/torvalds/linux/commit/622582786c9e041d0bd52bde201787adeab249f8"><code>622582786c9e</code></a></td></tr>
<tr><td>ARM64</td><td>3.18</td><td><a href="https://github.com/torvalds/linux/commit/e54bcde3d69d40023ae77727213d14f920eb264a"><code>e54bcde3d69d</code></a></td></tr>
<tr><td>s390</td><td>4.1</td><td><a href="https://github.com/torvalds/linux/commit/054623105728b06852f077299e2bf1bf3d5f2b0b"><code>054623105728</code></a></td></tr>
<tr><td>Constant blinding for JIT machines</td><td>4.7</td><td><a href="https://github.com/torvalds/linux/commit/4f3446bb809f20ad56cadf712e6006815ae7a8f9"><code>4f3446bb809f</code></a></td></tr>
<tr><td>JIT机器的常量混淆</td><td>4.7</td><td><a href="https://github.com/torvalds/linux/commit/4f3446bb809f20ad56cadf712e6006815ae7a8f9"><code>4f3446bb809f</code></a></td></tr>
<tr><td>PowerPC64</td><td>4.8</td><td><a href="https://github.com/torvalds/linux/commit/156d0e290e969caba25f1851c52417c14d141b24"><code>156d0e290e96</code></a></td></tr>
<tr><td>Constant blinding - PowerPC64</td><td>4.9</td><td><a href="https://github.com/torvalds/linux/commit/b7b7013cac55d794940bd9cb7b7c55c9dececac4"><code>b7b7013cac55</code></a></td></tr>
<tr><td>常量混淆 - PowerPC64</td><td>4.9</td><td><a href="https://github.com/torvalds/linux/commit/b7b7013cac55d794940bd9cb7b7c55c9dececac4"><code>b7b7013cac55</code></a></td></tr>
<tr><td>Sparc64</td><td>4.12</td><td><a href="https://github.com/torvalds/linux/commit/7a12b5031c6b947cc13918237ae652b536243b76"><code>7a12b5031c6b</code></a></td></tr>
<tr><td>MIPS</td><td>4.13</td><td><a href="https://github.com/torvalds/linux/commit/f381bf6d82f032b7410185b35d000ea370ac706b"><code>f381bf6d82f0</code></a></td></tr>
<tr><td>ARM32</td><td>4.14</td><td><a href="https://github.com/torvalds/linux/commit/39c13c204bb1150d401e27d41a9d8b332be47c49"><code>39c13c204bb1</code></a></td></tr>
<tr><td>x86_32</td><td>4.18</td><td><a href="https://github.com/torvalds/linux/commit/03f5781be2c7b7e728d724ac70ba10799cc710d7"><code>03f5781be2c7</code></a></td></tr>
<tr><td>RISC-V RV64G</td><td>5.1</td><td><a href="https://github.com/torvalds/linux/commit/2353ecc6f91fd15b893fa01bf85a1c7a823ee4f2"><code>2353ecc6f91f</code></a></td></tr>
<tr><td>RISC-V RV32G</td><td>5.7</td><td><a href="https://github.com/torvalds/linux/commit/5f316b65e99f109942c556dc8790abd4c75bcb34"><code>5f316b65e99f</code></a></td></tr>
<tr><td>RISC-V RV64G</td><td>5.1</td><td><a href="https://github.com/torvalds/linux/commit/2353ecc6f91fd15b893fa01bf85a1c7a823ee4f2"><code>2353ecc6f91f</code></a>RISC-V RV32G</td></tr>
<tr><td>PowerPC32</td><td>5.13</td><td><a href="https://github.com/torvalds/linux/commit/51c66ad849a703d9bbfd7704c941827aed0fd9fd"><code>51c66ad849a7</code></a></td></tr>
<tr><td>LoongArch</td><td>6.1</td><td><a href="https://github.com/torvalds/linux/commit/5dc615520c4dfb358245680f1904bad61116648e"><code>5dc615520c4d</code></a></td></tr>
</tbody></table>
</div>
<h2 id="main-features"><a class="header" href="#main-features">Main features</a></h2>
<p>Several (but not all) of these <em>main features</em> translate to an eBPF program type.
The list of such program types supported in your kernel can be found in file
<a href="https://github.com/torvalds/linux/blob/master/include/uapi/linux/bpf.h"><code>include/uapi/linux/bpf.h</code></a>:</p>
<h2 id="主要特性"><a class="header" href="#主要特性">主要特性</a></h2>
<p>其中几个(但不是全部)<em>主要特性</em> 可以转换为 eBPF 程序类型。
您的内核支持的此类程序类型的列表可以在文件 <a href="https://github.com/torvalds/linux/blob/master/include/uapi/linux/bpf.h"><code>include/uapi/linux/bpf.h</code></a> 中找到:</p>
<pre><code class="language-sh">git grep -W 'bpf_prog_type {' include/uapi/linux/bpf.h
</code></pre>
<div class="table-wrapper"><table><thead><tr><th>Feature</th><th>Kernel version</th><th>Commit</th></tr></thead><tbody>
<tr><td><code>AF_PACKET</code> (libpcap/tcpdump, <code>cls_bpf</code> classifier, netfilter's <code>xt_bpf</code>, team driver's load-balancing mode…)</td><td>3.15</td><td><a href="https://github.com/torvalds/linux/commit/bd4cf0ed331a275e9bf5a49e6d0fd55dffc551b8"><code>bd4cf0ed331a</code></a></td></tr>
<tr><td>Kernel helpers</td><td>3.15</td><td><a href="https://github.com/torvalds/linux/commit/bd4cf0ed331a275e9bf5a49e6d0fd55dffc551b8"><code>bd4cf0ed331a</code></a></td></tr>
<tr><td><code>bpf()</code> syscall</td><td>3.18</td><td><a href="https://github.com/torvalds/linux/commit/99c55f7d47c0dc6fc64729f37bf435abf43f4c60"><code>99c55f7d47c0</code></a></td></tr>
<tr><td>Maps (<em>a.k.a.</em> Tables; details below)</td><td>3.18</td><td><a href="https://github.com/torvalds/linux/commit/99c55f7d47c0dc6fc64729f37bf435abf43f4c60"><code>99c55f7d47c0</code></a></td></tr>
<tr><td>BPF attached to sockets</td><td>3.19</td><td><a href="https://github.com/torvalds/linux/commit/89aa075832b0da4402acebd698d0411dcc82d03e"><code>89aa075832b0</code></a></td></tr>
<tr><td>BPF attached to <code>kprobes</code></td><td>4.1</td><td><a href="https://github.com/torvalds/linux/commit/2541517c32be2531e0da59dfd7efc1ce844644f5"><code>2541517c32be</code></a></td></tr>
<tr><td><code>cls_bpf</code> / <code>act_bpf</code> for <code>tc</code></td><td>4.1</td><td><a href="https://github.com/torvalds/linux/commit/e2e9b6541dd4b31848079da80fe2253daaafb549"><code>e2e9b6541dd4</code></a></td></tr>
<tr><td>Tail calls</td><td>4.2</td><td><a href="https://github.com/torvalds/linux/commit/04fd61ab36ec065e194ab5e74ae34a5240d992bb"><code>04fd61ab36ec</code></a></td></tr>
<tr><td>Non-root programs on sockets</td><td>4.4</td><td><a href="https://github.com/torvalds/linux/commit/1be7f75d1668d6296b80bf35dcf6762393530afc"><code>1be7f75d1668</code></a></td></tr>
<tr><td>Persistent maps and programs (virtual FS)</td><td>4.4</td><td><a href="https://github.com/torvalds/linux/commit/b2197755b2633e164a439682fb05a9b5ea48f706"><code>b2197755b263</code></a></td></tr>
<tr><td><code>tc</code>'s <code>direct-action</code> (<code>da</code>) mode</td><td>4.4</td><td><a href="https://github.com/torvalds/linux/commit/045efa82ff563cd4e656ca1c2e354fa5bf6bbda4"><code>045efa82ff56</code></a></td></tr>
<tr><td><code>tc</code>'s <code>clsact</code> qdisc</td><td>4.5</td><td><a href="https://github.com/torvalds/linux/commit/1f211a1b929c804100e138c5d3d656992cfd5622"><code>1f211a1b929c</code></a></td></tr>
<tr><td>BPF attached to tracepoints</td><td>4.7</td><td><a href="https://github.com/torvalds/linux/commit/98b5c2c65c2951772a8fc661f50d675e450e8bce"><code>98b5c2c65c29</code></a></td></tr>
<tr><td>Direct packet access</td><td>4.7</td><td><a href="https://github.com/torvalds/linux/commit/969bf05eb3cedd5a8d4b7c346a85c2ede87a6d6d"><code>969bf05eb3ce</code></a></td></tr>
<tr><td>XDP (see below)</td><td>4.8</td><td><a href="https://github.com/torvalds/linux/commit/6a773a15a1e8874e5eccd2f29190c31085912c95"><code>6a773a15a1e8</code></a></td></tr>
<tr><td>BPF attached to perf events</td><td>4.9</td><td><a href="https://github.com/torvalds/linux/commit/0515e5999a466dfe6e1924f460da599bb6821487"><code>0515e5999a46</code></a></td></tr>
<tr><td>Hardware offload for <code>tc</code>'s <code>cls_bpf</code></td><td>4.9</td><td><a href="https://github.com/torvalds/linux/commit/332ae8e2f6ecda5e50c5c62ed62894963e3a83f5"><code>332ae8e2f6ec</code></a></td></tr>
<tr><td>Verifier exposure and internal hooks</td><td>4.9</td><td><a href="https://github.com/torvalds/linux/commit/13a27dfc669724564aafa2699976ee756029fed2"><code>13a27dfc6697</code></a></td></tr>
<tr><td>BPF attached to cgroups for socket filtering</td><td>4.10</td><td><a href="https://github.com/torvalds/linux/commit/0e33661de493db325435d565a4a722120ae4cbf3"><code>0e33661de493</code></a></td></tr>
<tr><td>Lightweight tunnel encapsulation</td><td>4.10</td><td><a href="https://github.com/torvalds/linux/commit/3a0af8fd61f90920f6fa04e4f1e9a6a73c1b4fd2"><code>3a0af8fd61f9</code></a></td></tr>
<tr><td><strong>e</strong>BPF support for <code>xt_bpf</code> module (iptables)</td><td>4.10</td><td><a href="https://github.com/torvalds/linux/commit/2c16d60332643e90d4fa244f4a706c454b8c7569"><code>2c16d6033264</code></a></td></tr>
<tr><td>BPF program tag</td><td>4.10</td><td><a href="https://github.com/torvalds/linux/commit/7bd509e311f408f7a5132fcdde2069af65fa05ae"><code>7bd509e311f4</code></a></td></tr>
<tr><td>Tracepoints to debug BPF</td><td>4.11 (removed in 4.18)</td><td><a href="https://github.com/torvalds/linux/commit/a67edbf4fb6deadcfe57a04a134abed4a5ba3bb5"><code>a67edbf4fb6d</code></a> <a href="https://github.com/torvalds/linux/commit/4d220ed0f8140c478ab7b0a14d96821da639b646"><code>4d220ed0f814</code></a></td></tr>
<tr><td>Testing / benchmarking BPF programs</td><td>4.12</td><td><a href="https://github.com/torvalds/linux/commit/1cf1cae963c2e6032aebe1637e995bc2f5d330f4"><code>1cf1cae963c2</code></a></td></tr>
<tr><td>BPF programs and maps IDs</td><td>4.13</td><td><a href="https://github.com/torvalds/linux/commit/dc4bb0e2356149aee4cdae061936f3bbdd45595c"><code>dc4bb0e23561</code></a></td></tr>
<tr><td>BPF support for <code>sock_ops</code></td><td>4.13</td><td><a href="https://github.com/torvalds/linux/commit/40304b2a1567fecc321f640ee4239556dd0f3ee0"><code>40304b2a1567</code></a></td></tr>
<tr><td>BPF support for skbs on sockets</td><td>4.14</td><td><a href="https://github.com/torvalds/linux/commit/b005fd189cec9407b700599e1e80e0552446ee79"><code>b005fd189cec</code></a></td></tr>
<tr><td>bpftool utility in kernel sources</td><td>4.15</td><td><a href="https://github.com/torvalds/linux/commit/71bb428fe2c19512ac671d5ee16ef3e73e1b49a8"><code>71bb428fe2c1</code></a></td></tr>
<tr><td>BPF attached to cgroups as device controller</td><td>4.15</td><td><a href="https://github.com/torvalds/linux/commit/ebc614f687369f9df99828572b1d85a7c2de3d92"><code>ebc614f68736</code></a></td></tr>
<tr><td>bpf2bpf function calls</td><td>4.16</td><td><a href="https://github.com/torvalds/linux/commit/cc8b0b92a1699bc32f7fec71daa2bfc90de43a4d"><code>cc8b0b92a169</code></a></td></tr>
<tr><td>BPF used for monitoring socket RX/TX data</td><td>4.17</td><td><a href="https://github.com/torvalds/linux/commit/4f738adba30a7cfc006f605707e7aee847ffefa0"><code>4f738adba30a</code></a></td></tr>
<tr><td>BPF attached to raw tracepoints</td><td>4.17</td><td><a href="https://github.com/torvalds/linux/commit/c4f6699dfcb8558d138fe838f741b2c10f416cf9"><code>c4f6699dfcb8</code></a></td></tr>
<tr><td>BPF attached to <code>bind()</code> system call</td><td>4.17</td><td><a href="https://github.com/torvalds/linux/commit/4fbac77d2d092b475dda9eea66da674369665427"><code>4fbac77d2d09</code></a> <a href="https://github.com/torvalds/linux/commit/aac3fc320d9404f2665a8b1249dc3170d5fa3caf"><code>aac3fc320d94</code></a></td></tr>
<tr><td>BPF attached to <code>connect()</code> system call</td><td>4.17</td><td><a href="https://github.com/torvalds/linux/commit/d74bad4e74ee373787a9ae24197c17b7cdc428d5"><code>d74bad4e74ee</code></a></td></tr>
<tr><td>BPF Type Format (BTF)</td><td>4.18</td><td><a href="https://github.com/torvalds/linux/commit/69b693f0aefa0ed521e8bd02260523b5ae446ad7"><code>69b693f0aefa</code></a></td></tr>
<div class="table-wrapper"><table><thead><tr><th>特性</th><th>内核版本</th><th>提交</th></tr></thead><tbody>
<tr><td><code>AF_PACKET</code> (libpcap/tcpdump, <code>cls_bpf</code> 分类器, netfilter <code>xt_bpf</code>, team 驱动程序的负载均衡模式…)</td><td>3.15</td><td><a href="https://github.com/torvalds/linux/commit/bd4cf0ed331a275e9bf5a49e6d0fd55dffc551b8"><code>bd4cf0ed331a</code></a></td></tr>
<tr><td>内核助手</td><td>3.15</td><td><a href="https://github.com/torvalds/linux/commit/bd4cf0ed331a275e9bf5a49e6d0fd55dffc551b8"><code>bd4cf0ed331a</code></a></td></tr>
<tr><td><code>bpf()</code> 系统调用</td><td>3.18</td><td><a href="https://github.com/torvalds/linux/commit/99c55f7d47c0dc6fc64729f37bf435abf43f4c60"><code>99c55f7d47c0</code></a></td></tr>
<tr><td>Maps (<em>又名</em> 表; 详见下文)</td><td>3.18</td><td><a href="https://github.com/torvalds/linux/commit/99c55f7d47c0dc6fc64729f37bf435abf43f4c60"><code>99c55f7d47c0</code></a></td></tr>
<tr><td>BPF 附加到套接字</td><td>3.19</td><td><a href="https://github.com/torvalds/linux/commit/89aa075832b0da4402acebd698d0411dcc82d03e"><code>89aa075832b0</code></a></td></tr>
<tr><td>BPF 附加到 <code>kprobes</code></td><td>4.1</td><td><a href="https://github.com/torvalds/linux/commit/2541517c32be2531e0da59dfd7efc1ce844644f5"><code>2541517c32be</code></a></td></tr>
<tr><td><code>cls_bpf</code> / <code>act_bpf</code> 用于 <code>tc</code></td><td>4.1</td><td><a href="https://github.com/torvalds/linux/commit/e2e9b6541dd4b31848079da80fe2253daaafb549"><code>e2e9b6541dd4</code></a></td></tr>
<tr><td>尾调用</td><td>4.2</td><td><a href="https://github.com/torvalds/linux/commit/04fd61ab36ec065e194ab5e74ae34a5240d992bb"><code>04fd61ab36ec</code></a>非根程序上的套接字</td></tr>
<tr><td>持久映射和程序(虚拟文件系统)</td><td>4.4</td><td><a href="https://github.com/torvalds/linux/commit/b2197755b2633e164a439682fb05a9b5ea48f706"><code>b2197755b263</code></a></td></tr>
<tr><td><code>tc</code><code>direct-action</code>(<code>da</code>)模式</td><td>4.4</td><td><a href="https://github.com/torvalds/linux/commit/045efa82ff563cd4e656ca1c2e354fa5bf6bbda4"><code>045efa82ff56</code></a></td></tr>
<tr><td><code>tc</code><code>clsact</code>qdisc</td><td>4.5</td><td><a href="https://github.com/torvalds/linux/commit/1f211a1b929c804100e138c5d3d656992cfd5622"><code>1f211a1b929c</code></a></td></tr>
<tr><td>BPF连接到跟踪点</td><td>4.7</td><td><a href="https://github.com/torvalds/linux/commit/98b5c2c65c2951772a8fc661f50d675e450e8bce"><code>98b5c2c65c29</code></a></td></tr>
<tr><td>直接数据包访问</td><td>4.7</td><td><a href="https://github.com/torvalds/linux/commit/969bf05eb3cedd5a8d4b7c346a85c2ede87a6d6d"><code>969bf05eb3ce</code></a></td></tr>
<tr><td>XDP参见下文</td><td>4.8</td><td><a href="https://github.com/torvalds/linux/commit/6a773a15a1e8874e5eccd2f29190c31085912c95"><code>6a773a15a1e8</code></a></td></tr>
<tr><td>BPF连接到性能事件</td><td>4.9</td><td><a href="https://github.com/torvalds/linux/commit/0515e5999a466dfe6e1924f460da599bb6821487"><code>0515e5999a46</code></a></td></tr>
<tr><td><code>tc</code><code>cls_bpf</code>的硬件卸载</td><td>4.9</td><td><a href="https://github.com/torvalds/linux/commit/332ae8e2f6ecda5e50c5c62ed62894963e3a83f5"><code>332ae8e2f6ec</code></a></td></tr>
<tr><td>验证器暴露和内部钩子</td><td>4.9</td><td><a href="https://github.com/torvalds/linux/commit/13a27dfc669724564aafa2699976ee756029fed2"><code>13a27dfc6697</code></a></td></tr>
<tr><td>BPF连接到 cgroups 用于套接字过滤</td><td>4.10</td><td><a href="https://github.com/torvalds/linux/commit/0e33661de493db325435d565a4a722120ae4cbf3"><code>0e33661de493</code></a></td></tr>
<tr><td>轻量级隧道封装</td><td>4.10</td><td><a href="https://github.com/torvalds/linux/commit/3a0af8fd61f90920f6fa04e4f1e9a6a73c1b4fd2"><code>3a0af8fd61f9</code></a></td></tr>
<tr><td><strong>e</strong>BPF对<code>xt_bpf</code>模块iptables的支持</td><td>4.10</td><td><a href="https://github.com/torvalds/linux/commit/2c16d60332643e90d4fa244f4a706c454b8c7569"><code>2c16d6033264</code></a></td></tr>
<tr><td>BPF程序标签</td><td>4.10</td><td><a href="https://github.com/torvalds/linux/commit/7bd509e311f408f7a5132fcdde2069af65fa05ae"><code>7bd509e311f4</code></a>跟踪点以调试BPF</td></tr>
<tr><td>测试/基准测试BPF程序</td><td>4.12</td><td><a href="https://github.com/torvalds/linux/commit/1cf1cae963c2e6032aebe1637e995bc2f5d330f4"><code>1cf1cae963c2</code></a></td></tr>
<tr><td>BPF程序和映射ID</td><td>4.13</td><td><a href="https://github.com/torvalds/linux/commit/dc4bb0e2356149aee4cdae061936f3bbdd45595c"><code>dc4bb0e23561</code></a></td></tr>
<tr><td>BPF对<code>sock_ops</code>的支持</td><td>4.13</td><td><a href="https://github.com/torvalds/linux/commit/40304b2a1567fecc321f640ee4239556dd0f3ee0"><code>40304b2a1567</code></a></td></tr>
<tr><td>BPF对套接字上的skb的支持</td><td>4.14</td><td><a href="https://github.com/torvalds/linux/commit/b005fd189cec9407b700599e1e80e0552446ee79"><code>b005fd189cec</code></a></td></tr>
<tr><td>内核源码中的bpftool实用程序</td><td>4.15</td><td><a href="https://github.com/torvalds/linux/commit/71bb428fe2c19512ac671d5ee16ef3e73e1b49a8"><code>71bb428fe2c1</code></a></td></tr>
<tr><td>BPF附加到cgroups作为设备控制器</td><td>4.15</td><td><a href="https://github.com/torvalds/linux/commit/ebc614f687369f9df99828572b1d85a7c2de3d92"><code>ebc614f68736</code></a></td></tr>
<tr><td>bpf2bpf函数调用</td><td>4.16</td><td><a href="https://github.com/torvalds/linux/commit/cc8b0b92a1699bc32f7fec71daa2bfc90de43a4d"><code>cc8b0b92a169</code></a></td></tr>
<tr><td>BPF用于监视套接字RX/TX数据</td><td>4.17</td><td><a href="https://github.com/torvalds/linux/commit/4f738adba30a7cfc006f605707e7aee847ffefa0"><code>4f738adba30a</code></a></td></tr>
<tr><td>BPF附加到原始跟踪点</td><td>4.17</td><td><a href="https://github.com/torvalds/linux/commit/c4f6699dfcb8558d138fe838f741b2c10f416cf9"><code>c4f6699dfcb8</code></a></td></tr>
<tr><td>BPF附加到<code>bind()</code>系统调用</td><td>4.17</td><td><a href="https://github.com/torvalds/linux/commit/4fbac77d2d092b475dda9eea66da674369665427"><code>4fbac77d2d09</code></a> <a href="https://github.com/torvalds/linux/commit/aac3fc320d9404f2665a8b1249dc3170d5fa3caf"><code>aac3fc320d94</code></a></td></tr>
<tr><td>BPF附加到<code>connect()</code>系统调用</td><td>4.17</td><td><a href="https://github.com/torvalds/linux/commit/d74bad4e74ee373787a9ae24197c17b7cdc428d5"><code>d74bad4e74ee</code></a>BPF 类型格式BTF</td></tr>
<tr><td>AF_XDP</td><td>4.18</td><td><a href="https://github.com/torvalds/linux/commit/fbfc504a24f53f7ebe128ab55cb5dba634f4ece8"><code>fbfc504a24f5</code></a></td></tr>
<tr><td>bpfilter</td><td>4.18</td><td><a href="https://github.com/torvalds/linux/commit/d2ba09c17a0647f899d6c20a11bab9e6d3382f07"><code>d2ba09c17a06</code></a></td></tr>
<tr><td>End.BPF action for seg6local LWT</td><td>4.18</td><td><a href="https://github.com/torvalds/linux/commit/004d4b274e2a1a895a0e5dc66158b90a7d463d44"><code>004d4b274e2a</code></a></td></tr>
<tr><td>BPF attached to LIRC devices</td><td>4.18</td><td><a href="https://github.com/torvalds/linux/commit/f4364dcfc86df7c1ca47b256eaf6b6d0cdd0d936"><code>f4364dcfc86d</code></a></td></tr>
<tr><td>Pass map values to map helpers</td><td>4.18</td><td><a href="https://github.com/torvalds/linux/commit/d71962f3e627b5941804036755c844fabfb65ff5"><code>d71962f3e627</code></a></td></tr>
<tr><td>BPF socket reuseport</td><td>4.19</td><td><a href="https://github.com/torvalds/linux/commit/2dbb9b9e6df67d444fbe425c7f6014858d337adf"><code>2dbb9b9e6df6</code></a></td></tr>
<tr><td>BPF flow dissector</td><td>4.20</td><td><a href="https://github.com/torvalds/linux/commit/d58e468b1112dcd1d5193c0a89ff9f98b5a3e8b9"><code>d58e468b1112</code></a></td></tr>
<tr><td>BPF 1M insn limit</td><td>5.2</td><td><a href="https://github.com/torvalds/linux/commit/c04c0d2b968ac45d6ef020316808ef6c82325a82"><code>c04c0d2b968a</code></a></td></tr>
<tr><td>BPF cgroup sysctl</td><td>5.2</td><td><a href="https://github.com/torvalds/linux/commit/7b146cebe30cb481b0f70d85779da938da818637"><code>7b146cebe30c</code></a></td></tr>
<tr><td>BPF raw tracepoint writable</td><td>5.2</td><td><a href="https://github.com/torvalds/linux/commit/9df1c28bb75217b244257152ab7d788bb2a386d0"><code>9df1c28bb752</code></a></td></tr>
<tr><td>BPF bounded loop</td><td>5.3</td><td><a href="https://github.com/torvalds/linux/commit/2589726d12a1b12eaaa93c7f1ea64287e383c7a5"><code>2589726d12a1</code></a></td></tr>
<tr><td>BPF trampoline</td><td>5.5</td><td><a href="https://github.com/torvalds/linux/commit/fec56f5890d93fc2ed74166c397dc186b1c25951"><code>fec56f5890d9</code></a></td></tr>
<tr><td>BPF LSM hook</td><td>5.7</td><td><a href="https://github.com/torvalds/linux/commit/fc611f47f2188ade2b48ff6902d5cce8baac0c58"><code>fc611f47f218</code></a> <a href="https://github.com/torvalds/linux/commit/641cd7b06c911c5935c34f24850ea18690649917"><code>641cd7b06c91</code></a></td></tr>
<tr><td>BPF iterator</td><td>5.8</td><td><a href="https://github.com/torvalds/linux/commit/180139dca8b38c858027b8360ee10064fdb2fbf7"><code>180139dca8b3</code></a></td></tr>
<tr><td>BPF socket lookup hook</td><td>5.9</td><td><a href="https://github.com/torvalds/linux/commit/e9ddbb7707ff5891616240026062b8c1e29864ca"><code>e9ddbb7707ff</code></a></td></tr>
<tr><td>Sleepable BPF programs</td><td>5.10</td><td><a href="https://github.com/torvalds/linux/commit/1e6c62a8821557720a9b2ea9617359b264f2f67c"><code>1e6c62a88215</code></a></td></tr>
<tr><td>seg6local LWT 的 End.BPF 操作</td><td>4.18</td><td><a href="https://github.com/torvalds/linux/commit/004d4b274e2a1a895a0e5dc66158b90a7d463d44"><code>004d4b274e2a</code></a></td></tr>
<tr><td>BPF 附加到 LIRC 设备</td><td>4.18</td><td><a href="https://github.com/torvalds/linux/commit/f4364dcfc86df7c1ca47b256eaf6b6d0cdd0d936"><code>f4364dcfc86d</code></a></td></tr>
<tr><td>将映射值传递给映射助手</td><td>4.18</td><td><a href="https://github.com/torvalds/linux/commit/d71962f3e627b5941804036755c844fabfb65ff5"><code>d71962f3e627</code></a></td></tr>
<tr><td>BPF 套接字复用端口</td><td>4.19</td><td><a href="https://github.com/torvalds/linux/commit/2dbb9b9e6df67d444fbe425c7f6014858d337adf"><code>2dbb9b9e6df6</code></a></td></tr>
<tr><td>BPF 流解剖器</td><td>4.20</td><td><a href="https://github.com/torvalds/linux/commit/d58e468b1112dcd1d5193c0a89ff9f98b5a3e8b9"><code>d58e468b1112</code></a></td></tr>
<tr><td>BPF 1M 指令限制</td><td>5.2</td><td><a href="https://github.com/torvalds/linux/commit/c04c0d2b968ac45d6ef020316808ef6c82325a82"><code>c04c0d2b968a</code></a></td></tr>
<tr><td>BPF 控制组 sysctl</td><td>5.2</td><td><a href="https://github.com/torvalds/linux/commit/7b146cebe30cb481b0f70d85779da938da818637"><code>7b146cebe30c</code></a></td></tr>
<tr><td>BPF 原始跟踪点可写</td><td>5.2</td><td><a href="https://github.com/torvalds/linux/commit/9df1c28bb75217b244257152ab7d788bb2a386d0"><code>9df1c28bb752</code></a></td></tr>
<tr><td>BPF 有界循环</td><td>5.3</td><td><a href="https://github.com/torvalds/linux/commit/2589726d12a1b12eaaa93c7f1ea64287e383c7a5"><code>2589726d12a1</code></a></td></tr>
<tr><td>BPF 跳板</td><td>5.5</td><td><a href="https://github.com/torvalds/linux/commit/fec56f5890d93fc2ed74166c397dc186b1c25951"><code>fec56f5890d9</code></a></td></tr>
<tr><td>BPF LSM 钩子</td><td>5.7</td><td><a href="https://github.com/torvalds/linux/commit/fc611f47f2188ade2b48ff6902d5cce8baac0c58"><code>fc611f47f218</code></a> <a href="https://github.com/torvalds/linux/commit/641cd7b06c911c5935c34f24850ea18690649917"><code>641cd7b06c91</code></a></td></tr>
<tr><td>BPF 迭代器</td><td>5.8</td><td><a href="https://github.com/torvalds/linux/commit/180139dca8b38c858027b8360ee10064fdb2fbf7"><code>180139dca8b3</code></a>BPF套接字查找挂钩</td></tr>
<tr><td>可睡眠的BPF程序</td><td>5.10</td><td><a href="https://github.com/torvalds/linux/commit/1e6c62a8821557720a9b2ea9617359b264f2f67c"><code>1e6c62a88215</code></a></td></tr>
</tbody></table>
</div>
<h3 id="program-types"><a class="header" href="#program-types">Program types</a></h3>
<div class="table-wrapper"><table><thead><tr><th>Program type</th><th>Kernel version</th><th>Commit</th><th>Enum</th></tr></thead><tbody>
<tr><td>Socket filter</td><td>3.19</td><td><a href="https://github.com/torvalds/linux/commit/ddd872bc3098f9d9abe1680a6b2013e59e3337f7"><code>ddd872bc3098</code></a></td><td>BPF_PROG_TYPE_SOCKET_FILTER</td></tr>
<h3 id="程序类型"><a class="header" href="#程序类型">程序类型</a></h3>
<div class="table-wrapper"><table><thead><tr><th>程序类型</th><th>内核版本</th><th>提交</th><th>枚举</th></tr></thead><tbody>
<tr><td>套接字过滤器</td><td>3.19</td><td><a href="https://github.com/torvalds/linux/commit/ddd872bc3098f9d9abe1680a6b2013e59e3337f7"><code>ddd872bc3098</code></a></td><td>BPF_PROG_TYPE_SOCKET_FILTER</td></tr>
<tr><td>Kprobe</td><td>4.1</td><td><a href="https://github.com/torvalds/linux/commit/2541517c32be2531e0da59dfd7efc1ce844644f5"><code>2541517c32be</code></a></td><td>BPF_PROG_TYPE_KPROBE</td></tr>
<tr><td>traffic control (TC)</td><td>4.1</td><td><a href="https://github.com/torvalds/linux/commit/96be4325f443dbbfeb37d2a157675ac0736531a1"><code>96be4325f443</code></a></td><td>BPF_PROG_TYPE_SCHED_CLS</td></tr>
<tr><td>traffic control (TC)</td><td>4.1</td><td><a href="https://github.com/torvalds/linux/commit/94caee8c312d96522bcdae88791aaa9ebcd5f22c"><code>94caee8c312d</code></a></td><td>BPF_PROG_TYPE_SCHED_ACT</td></tr>
<tr><td>Tracepoint</td><td>4.7</td><td><a href="https://github.com/torvalds/linux/commit/98b5c2c65c2951772a8fc661f50d675e450e8bce"><code>98b5c2c65c29</code></a></td><td>BPF_PROG_TYPE_TRACEPOINT</td></tr>
<tr><td>流量控制(TC)</td><td>4.1</td><td><a href="https://github.com/torvalds/linux/commit/96be4325f443dbbfeb37d2a157675ac0736531a1"><code>96be4325f443</code></a></td><td>BPF_PROG_TYPE_SCHED_CLS</td></tr>
<tr><td>流量控制(TC)</td><td>4.1</td><td><a href="https://github.com/torvalds/linux/commit/94caee8c312d96522bcdae88791aaa9ebcd5f22c"><code>94caee8c312d</code></a></td><td>BPF_PROG_TYPE_SCHED_ACT</td></tr>
<tr><td>跟踪点</td><td>4.7</td><td><a href="https://github.com/torvalds/linux/commit/98b5c2c65c2951772a8fc661f50d675e450e8bce"><code>98b5c2c65c29</code></a></td><td>BPF_PROG_TYPE_TRACEPOINT</td></tr>
<tr><td>XDP</td><td>4.8</td><td><a href="https://github.com/torvalds/linux/commit/6a773a15a1e8874e5eccd2f29190c31085912c95"><code>6a773a15a1e8</code></a></td><td>BPF_PROG_TYPE_XDP</td></tr>
<tr><td>Perf event</td><td>4.9</td><td><a href="https://github.com/torvalds/linux/commit/0515e5999a466dfe6e1924f460da599bb6821487"><code>0515e5999a46</code></a></td><td>BPF_PROG_TYPE_PERF_EVENT</td></tr>
<tr><td>cgroup socket filtering</td><td>4.10</td><td><a href="https://github.com/torvalds/linux/commit/0e33661de493db325435d565a4a722120ae4cbf3"><code>0e33661de493</code></a></td><td>BPF_PROG_TYPE_CGROUP_SKB</td></tr>
<tr><td>cgroup sock modification</td><td>4.10</td><td><a href="https://github.com/torvalds/linux/commit/61023658760032e97869b07d54be9681d2529e77"><code>610236587600</code></a></td><td>BPF_PROG_TYPE_CGROUP_SOCK</td></tr>
<tr><td>lightweight tunnel (IN)</td><td>4.10</td><td><a href="https://github.com/torvalds/linux/commit/3a0af8fd61f90920f6fa04e4f1e9a6a73c1b4fd2"><code>3a0af8fd61f9</code></a></td><td>BPF_PROG_TYPE_LWT_IN</td></tr>
<tr><td>lightweight tunnel (OUT)</td><td>4.10</td><td><a href="https://github.com/torvalds/linux/commit/3a0af8fd61f90920f6fa04e4f1e9a6a73c1b4fd2"><code>3a0af8fd61f9</code></a></td><td>BPF_PROG_TYPE_LWT_OUT</td></tr>
<tr><td>lightweight tunnel (XMIT)</td><td>4.10</td><td><a href="https://github.com/torvalds/linux/commit/3a0af8fd61f90920f6fa04e4f1e9a6a73c1b4fd2"><code>3a0af8fd61f9</code></a></td><td>BPF_PROG_TYPE_LWT_XMIT</td></tr>
<tr><td>cgroup sock ops (per conn)</td><td>4.13</td><td><a href="https://github.com/torvalds/linux/commit/40304b2a1567fecc321f640ee4239556dd0f3ee0"><code>40304b2a1567</code></a></td><td>BPF_PROG_TYPE_SOCK_OPS</td></tr>
<tr><td>stream parser / stream verdict</td><td>4.14</td><td><a href="https://github.com/torvalds/linux/commit/b005fd189cec9407b700599e1e80e0552446ee79"><code>b005fd189cec</code></a></td><td>BPF_PROG_TYPE_SK_SKB</td></tr>
<tr><td>cgroup device manager</td><td>4.15</td><td><a href="https://github.com/torvalds/linux/commit/ebc614f687369f9df99828572b1d85a7c2de3d92"><code>ebc614f68736</code></a></td><td>BPF_PROG_TYPE_CGROUP_DEVICE</td></tr>
<tr><td>socket msg verdict</td><td>4.17</td><td><a href="https://github.com/torvalds/linux/commit/4f738adba30a7cfc006f605707e7aee847ffefa0"><code>4f738adba30a</code></a></td><td>BPF_PROG_TYPE_SK_MSG</td></tr>
<tr><td>Raw tracepoint</td><td>4.17</td><td><a href="https://github.com/torvalds/linux/commit/c4f6699dfcb8558d138fe838f741b2c10f416cf9"><code>c4f6699dfcb8</code></a></td><td>BPF_PROG_TYPE_RAW_TRACEPOINT</td></tr>
<tr><td>socket binding</td><td>4.17</td><td><a href="https://github.com/torvalds/linux/commit/4fbac77d2d092b475dda9eea66da674369665427"><code>4fbac77d2d09</code></a></td><td>BPF_PROG_TYPE_CGROUP_SOCK_ADDR</td></tr>
<tr><td>LWT seg6local</td><td>4.18</td><td><a href="https://github.com/torvalds/linux/commit/004d4b274e2a1a895a0e5dc66158b90a7d463d44"><code>004d4b274e2a</code></a></td><td>BPF_PROG_TYPE_LWT_SEG6LOCAL</td></tr>
<tr><td>lirc devices</td><td>4.18</td><td><a href="https://github.com/torvalds/linux/commit/f4364dcfc86df7c1ca47b256eaf6b6d0cdd0d936"><code>f4364dcfc86d</code></a></td><td>BPF_PROG_TYPE_LIRC_MODE2</td></tr>
<tr><td>lookup SO_REUSEPORT socket</td><td>4.19</td><td><a href="https://github.com/torvalds/linux/commit/2dbb9b9e6df67d444fbe425c7f6014858d337adf"><code>2dbb9b9e6df6</code></a></td><td>BPF_PROG_TYPE_SK_REUSEPORT</td></tr>
<tr><td>flow dissector</td><td>4.20</td><td><a href="https://github.com/torvalds/linux/commit/d58e468b1112dcd1d5193c0a89ff9f98b5a3e8b9"><code>d58e468b1112</code></a></td><td>BPF_PROG_TYPE_FLOW_DISSECTOR</td></tr>
<tr><td>cgroup sysctl</td><td>5.2</td><td><a href="https://github.com/torvalds/linux/commit/7b146cebe30cb481b0f70d85779da938da818637"><code>7b146cebe30c</code></a></td><td>BPF_PROG_TYPE_CGROUP_SYSCTL</td></tr>
<tr><td>writable raw tracepoints</td><td>5.2</td><td><a href="https://github.com/torvalds/linux/commit/9df1c28bb75217b244257152ab7d788bb2a386d0"><code>9df1c28bb752</code></a></td><td>BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE</td></tr>
<tr><td>cgroup getsockopt/setsockopt</td><td>5.3</td><td><a href="https://github.com/torvalds/linux/commit/0d01da6afc5402f60325c5da31b22f7d56689b49"><code>0d01da6afc54</code></a></td><td>BPF_PROG_TYPE_CGROUP_SOCKOPT</td></tr>
<tr><td>Tracing (BTF/BPF trampoline)</td><td>5.5</td><td><a href="https://github.com/torvalds/linux/commit/f1b9509c2fb0ef4db8d22dac9aef8e856a5d81f6"><code>f1b9509c2fb0</code></a></td><td>BPF_PROG_TYPE_TRACING</td></tr>
<tr><td>struct ops</td><td>5.6</td><td><a href="https://github.com/torvalds/linux/commit/27ae7997a66174cb8afd6a75b3989f5e0c1b9e5a"><code>27ae7997a661</code></a></td><td>BPF_PROG_TYPE_STRUCT_OPS</td></tr>
<tr><td>extensions</td><td>5.6</td><td><a href="https://github.com/torvalds/linux/commit/be8704ff07d2374bcc5c675526f95e70c6459683"><code>be8704ff07d2</code></a></td><td>BPF_PROG_TYPE_EXT</td></tr>
<tr><td>LSM</td><td>5.7</td><td><a href="https://github.com/torvalds/linux/commit/fc611f47f2188ade2b48ff6902d5cce8baac0c58"><code>fc611f47f218</code></a></td><td>BPF_PROG_TYPE_LSM</td></tr>
<tr><td>lookup listening socket</td><td>5.9</td><td><a href="https://github.com/torvalds/linux/commit/e9ddbb7707ff5891616240026062b8c1e29864ca"><code>e9ddbb7707ff</code></a></td><td>BPF_PROG_TYPE_SK_LOOKUP</td></tr>
<tr><td>Allow executing syscalls</td><td>5.15</td><td><a href="https://github.com/torvalds/linux/commit/79a7f8bdb159d9914b58740f3d31d602a6e4aca8"><code>79a7f8bdb159</code></a></td><td>BPF_PROG_TYPE_SYSCALL</td></tr>
<tr><td>性能事件</td><td>4.9</td><td><a href="https://github.com/torvalds/linux/commit/0515e5999a466dfe6e1924f460da599bb6821487"><code>0515e5999a46</code></a></td><td>BPF_PROG_TYPE_PERF_EVENT</td></tr>
<tr><td>cgroup套接字过滤</td><td>4.10</td><td><a href="https://github.com/torvalds/linux/commit/0e33661de493db325435d565a4a722120ae4cbf3"><code>0e33661de493</code></a></td><td>BPF_PROG_TYPE_CGROUP_SKB</td></tr>
<tr><td>cgroup套接字修改</td><td>4.10</td><td><a href="https://github.com/torvalds/linux/commit/61023658760032e97869b07d54be9681d2529e77"><code>610236587600</code></a></td><td>BPF_PROG_TYPE_CGROUP_SOCK</td></tr>
<tr><td>轻量级隧道(IN)</td><td>4.10</td><td><a href="https://github.com/torvalds/linux/commit/3a0af8fd61f90920f6fa04e4f1e9a6a73c1b4fd2"><code>3a0af8fd61f9</code></a></td><td>BPF_PROG_TYPE_LWT_IN&quot;.lightweight tunnel (OUT)</td></tr>
<tr><td>轻量级隧道 (OUT)</td><td>4.10</td><td><a href="https://github.com/torvalds/linux/commit/3a0af8fd61f90920f6fa04e4f1e9a6a73c1b4fd2"><code>3a0af8fd61f9</code></a></td><td>BPF_PROG_TYPE_LWT_OUT</td></tr>
</tbody></table>
</div>
<h2 id="maps-aka-tables-in-bcc-lingo"><a class="header" href="#maps-aka-tables-in-bcc-lingo">Maps (<em>a.k.a.</em> Tables, in BCC lingo)</a></h2>
<h3 id="map-types"><a class="header" href="#map-types">Map types</a></h3>
<p>The list of map types supported in your kernel can be found in file
<a href="https://github.com/torvalds/linux/blob/master/include/uapi/linux/bpf.h"><code>include/uapi/linux/bpf.h</code></a>:</p>
<p>lightweight tunnel (XMIT) | 4.10 | <a href="https://github.com/torvalds/linux/commit/3a0af8fd61f90920f6fa04e4f1e9a6a73c1b4fd2"><code>3a0af8fd61f9</code></a> | BPF_PROG_TYPE_LWT_XMIT
轻量级隧道 (XMIT) | 4.10 | <a href="https://github.com/torvalds/linux/commit/3a0af8fd61f90920f6fa04e4f1e9a6a73c1b4fd2"><code>3a0af8fd61f9</code></a> | BPF_PROG_TYPE_LWT_XMIT</p>
<p>cgroup sock ops (per conn) | 4.13 | <a href="https://github.com/torvalds/linux/commit/40304b2a1567fecc321f640ee4239556dd0f3ee0"><code>40304b2a1567</code></a> | BPF_PROG_TYPE_SOCK_OPS
cgroup sock操作 (每个连接) | 4.13 | <a href="https://github.com/torvalds/linux/commit/40304b2a1567fecc321f640ee4239556dd0f3ee0"><code>40304b2a1567</code></a> | BPF_PROG_TYPE_SOCK_OPS</p>
<p>stream parser / stream verdict | 4.14 | <a href="https://github.com/torvalds/linux/commit/b005fd189cec9407b700599e1e80e0552446ee79"><code>b005fd189cec</code></a> | BPF_PROG_TYPE_SK_SKB
流分析器 / 流判定 | 4.14 | <a href="https://github.com/torvalds/linux/commit/b005fd189cec9407b700599e1e80e0552446ee79"><code>b005fd189cec</code></a> | BPF_PROG_TYPE_SK_SKB</p>
<p>cgroup device manager | 4.15 | <a href="https://github.com/torvalds/linux/commit/ebc614f687369f9df99828572b1d85a7c2de3d92"><code>ebc614f68736</code></a> | BPF_PROG_TYPE_CGROUP_DEVICE
cgroup设备管理器 | 4.15 | <a href="https://github.com/torvalds/linux/commit/ebc614f687369f9df99828572b1d85a7c2de3d92"><code>ebc614f68736</code></a> | BPF_PROG_TYPE_CGROUP_DEVICE</p>
<p>socket msg verdict | 4.17 | <a href="https://github.com/torvalds/linux/commit/4f738adba30a7cfc006f605707e7aee847ffefa0"><code>4f738adba30a</code></a> | BPF_PROG_TYPE_SK_MSG
套接字消息判定 | 4.17 | <a href="https://github.com/torvalds/linux/commit/4f738adba30a7cfc006f605707e7aee847ffefa0"><code>4f738adba30a</code></a> | BPF_PROG_TYPE_SK_MSG</p>
<p>Raw tracepoint | 4.17 | <a href="https://github.com/torvalds/linux/commit/c4f6699dfcb8558d138fe838f741b2c10f416cf9"><code>c4f6699dfcb8</code></a> | BPF_PROG_TYPE_RAW_TRACEPOINT
裸跟踪点 | 4.17 | <a href="https://github.com/torvalds/linux/commit/c4f6699dfcb8558d138fe838f741b2c10f416cf9"><code>c4f6699dfcb8</code></a> | BPF_PROG_TYPE_RAW_TRACEPOINT</p>
<p>socket binding | 4.17 | <a href="https://github.com/torvalds/linux/commit/4fbac77d2d092b475dda9eea66da674369665427"><code>4fbac77d2d09</code></a> | BPF_PROG_TYPE_CGROUP_SOCK_ADDR
套接字绑定 | 4.17 | <a href="https://github.com/torvalds/linux/commit/4fbac77d2d092b475dda9eea66da674369665427"><code>4fbac77d2d09</code></a> | BPF_PROG_TYPE_CGROUP_SOCK_ADDR</p>
<p>LWT seg6local | 4.18 | <a href="https://github.com/torvalds/linux/commit/004d4b274e2a1a895a0e5dc66158b90a7d463d44"><code>004d4b274e2a</code></a> | BPF_PROG_TYPE_LWT_SEG6LOCAL
轻量级隧道seg6local | 4.18 | <a href="https://github.com/torvalds/linux/commit/004d4b274e2a1a895a0e5dc66158b90a7d463d44"><code>004d4b274e2a</code></a> | BPF_PROG_TYPE_LWT_SEG6LOCAL</p>
<p>lirc devices | 4.18 | <a href="https://github.com/torvalds/linux/commit/f4364dcfc86df7c1ca47b256eaf6b6d0cdd0d936"><code>f4364dcfc86d</code></a> | BPF_PROG_TYPE_LIRC_MODE2
lirc设备 | 4.18 | <a href="https://github.com/torvalds/linux/commit/f4364dcfc86df7c1ca47b256eaf6b6d0cdd0d936"><code>f4364dcfc86d</code></a> | BPF_PROG_TYPE_LIRC_MODE2</p>
<p>lookup SO_REUSEPORT socket | 4.19 | <a href="https://github.com/torvalds/linux/commit/2dbb9b9e6df67d444fbe425c7f6014858d337adf"><code>2dbb9b9e6df6</code></a> | BPF_PROG_TYPE_SK_REUSEPORT
查找SO_REUSEPORT套接字 | 4.19 | <a href="https://github.com/torvalds/linux/commit/2dbb9b9e6df67d444fbe425c7f6014858d337adf"><code>2dbb9b9e6df6</code></a> | BPF_PROG_TYPE_SK_REUSEPORT</p>
<p>flow dissector | 4.20 | <a href="https://github.com/torvalds/linux/commit/d58e468b1112dcd1d5193c0a89ff9f98b5a3e8b9"><code>d58e468b1112</code></a> | BPF_PROG_TYPE_FLOW_DISSECTOR
流解析器 | 4.20 | <a href="https://github.com/torvalds/linux/commit/d58e468b1112dcd1d5193c0a89ff9f98b5a3e8b9"><code>d58e468b1112</code></a> | BPF_PROG_TYPE_FLOW_DISSECTORcgroup sysctl | 5.2 | <a href="https://github.com/torvalds/linux/commit/7b146cebe30cb481b0f70d85779da938da818637"><code>7b146cebe30c</code></a> | BPF_PROG_TYPE_CGROUP_SYSCTL
可控 cgroup | 5.2 | <a href="https://github.com/torvalds/linux/commit/7b146cebe30cb481b0f70d85779da938da818637"><code>7b146cebe30c</code></a> | BPF_PROG_TYPE_CGROUP_SYSCTL</p>
<p>writable raw tracepoints | 5.2 | <a href="https://github.com/torvalds/linux/commit/9df1c28bb75217b244257152ab7d788bb2a386d0"><code>9df1c28bb752</code></a> | BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE
可写原始跟踪点 | 5.2 | <a href="https://github.com/torvalds/linux/commit/9df1c28bb75217b244257152ab7d788bb2a386d0"><code>9df1c28bb752</code></a> | BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE</p>
<p>cgroup getsockopt/setsockopt | 5.3 | <a href="https://github.com/torvalds/linux/commit/0d01da6afc5402f60325c5da31b22f7d56689b49"><code>0d01da6afc54</code></a> | BPF_PROG_TYPE_CGROUP_SOCKOPT
cgroup getsockopt/setsockopt | 5.3 | <a href="https://github.com/torvalds/linux/commit/0d01da6afc5402f60325c5da31b22f7d56689b49"><code>0d01da6afc54</code></a> | BPF_PROG_TYPE_CGROUP_SOCKOPT</p>
<p>Tracing (BTF/BPF trampoline) | 5.5 | <a href="https://github.com/torvalds/linux/commit/f1b9509c2fb0ef4db8d22dac9aef8e856a5d81f6"><code>f1b9509c2fb0</code></a> | BPF_PROG_TYPE_TRACING
追踪 (BTF/BPF 弹跳) | 5.5 | <a href="https://github.com/torvalds/linux/commit/f1b9509c2fb0ef4db8d22dac9aef8e856a5d81f6"><code>f1b9509c2fb0</code></a> | BPF_PROG_TYPE_TRACING</p>
<p>struct ops | 5.6 | <a href="https://github.com/torvalds/linux/commit/27ae7997a66174cb8afd6a75b3989f5e0c1b9e5a"><code>27ae7997a661</code></a> | BPF_PROG_TYPE_STRUCT_OPS
结构操作 | 5.6 | <a href="https://github.com/torvalds/linux/commit/27ae7997a66174cb8afd6a75b3989f5e0c1b9e5a"><code>27ae7997a661</code></a> | BPF_PROG_TYPE_STRUCT_OPS</p>
<p>extensions | 5.6 | <a href="https://github.com/torvalds/linux/commit/be8704ff07d2374bcc5c675526f95e70c6459683"><code>be8704ff07d2</code></a> | BPF_PROG_TYPE_EXT
扩展 | 5.6 | <a href="https://github.com/torvalds/linux/commit/be8704ff07d2374bcc5c675526f95e70c6459683"><code>be8704ff07d2</code></a> | BPF_PROG_TYPE_EXT</p>
<p>LSM | 5.7 | <a href="https://github.com/torvalds/linux/commit/fc611f47f2188ade2b48ff6902d5cce8baac0c58"><code>fc611f47f218</code></a> | BPF_PROG_TYPE_LSM
LSM (Linux安全模块) | 5.7 | <a href="https://github.com/torvalds/linux/commit/fc611f47f2188ade2b48ff6902d5cce8baac0c58"><code>fc611f47f218</code></a> | BPF_PROG_TYPE_LSM</p>
<p>lookup listening socket | 5.9 | <a href="https://github.com/torvalds/linux/commit/e9ddbb7707ff5891616240026062b8c1e29864ca"><code>e9ddbb7707ff</code></a> | BPF_PROG_TYPE_SK_LOOKUP
查询监听套接字 | 5.9 | <a href="https://github.com/torvalds/linux/commit/e9ddbb7707ff5891616240026062b8c1e29864ca"><code>e9ddbb7707ff</code></a> | BPF_PROG_TYPE_SK_LOOKUP</p>
<p>Allow executing syscalls | 5.15 | <a href="https://github.com/torvalds/linux/commit/79a7f8bdb159d9914b58740f3d31d602a6e4aca8"><code>79a7f8bdb159</code></a> | BPF_PROG_TYPE_SYSCALL
允许执行系统调用 | 5.15 | <a href="https://github.com/torvalds/linux/commit/79a7f8bdb159d9914b58740f3d31d602a6e4aca8"><code>79a7f8bdb159</code></a> | BPF_PROG_TYPE_SYSCALL</p>
<h2 id="map-types-aka-表格-在-bcc-术语中"><a class="header" href="#map-types-aka-表格-在-bcc-术语中">Map types (<em>a.k.a.</em> 表格, 在 BCC 术语中)</a></h2>
<h3 id="map-类型"><a class="header" href="#map-类型">Map 类型</a></h3>
<p>您内核支持的 Map 类型列表可以在文件 <a href="https://github.com/torvalds/linux/blob/master/include/uapi/linux/bpf.h"><code>include/uapi/linux/bpf.h</code></a> 中找到:</p>
<pre><code class="language-sh">git grep -W 'bpf_map_type {' include/uapi/linux/bpf.h
</code></pre>
<div class="table-wrapper"><table><thead><tr><th>Map type</th><th>Kernel version</th><th>Commit</th><th>Enum</th></tr></thead><tbody>
<tr><td>Hash</td><td>3.19</td><td><a href="https://github.com/torvalds/linux/commit/0f8e4bd8a1fc8c4185f1630061d0a1f2d197a475"><code>0f8e4bd8a1fc</code></a></td><td>BPF_MAP_TYPE_HASH</td></tr>
<tr><td>Array</td><td>3.19</td><td><a href="https://github.com/torvalds/linux/commit/28fbcfa08d8ed7c5a50d41a0433aad222835e8e3"><code>28fbcfa08d8e</code></a></td><td>BPF_MAP_TYPE_ARRAY</td></tr>
<div class="table-wrapper"><table><thead><tr><th>Map 类型</th><th>内核版本</th><th>提交</th><th>枚举</th></tr></thead><tbody>
<tr><td>哈希</td><td>3.19</td><td><a href="https://github.com/torvalds/linux/commit/0f8e4bd8a1fc8c4185f1630061d0a1f2d197a475"><code>0f8e4bd8a1fc</code></a></td><td>BPF_MAP_TYPE_HASH&quot;.Array</td></tr>
<tr><td>Prog array</td><td>4.2</td><td><a href="https://github.com/torvalds/linux/commit/04fd61ab36ec065e194ab5e74ae34a5240d992bb"><code>04fd61ab36ec</code></a></td><td>BPF_MAP_TYPE_PROG_ARRAY</td></tr>
<tr><td>Perf events</td><td>4.3</td><td><a href="https://github.com/torvalds/linux/commit/ea317b267e9d03a8241893aa176fba7661d07579"><code>ea317b267e9d</code></a></td><td>BPF_MAP_TYPE_PERF_EVENT_ARRAY</td></tr>
<tr><td>Per-CPU hash</td><td>4.6</td><td><a href="https://github.com/torvalds/linux/commit/824bd0ce6c7c43a9e1e210abf124958e54d88342"><code>824bd0ce6c7c</code></a></td><td>BPF_MAP_TYPE_PERCPU_HASH</td></tr>
@@ -306,8 +317,7 @@ The list of such program types supported in your kernel can be found in file
<tr><td>LRU hash</td><td>4.10</td><td><a href="https://github.com/torvalds/linux/commit/29ba732acbeece1e34c68483d1ec1f3720fa1bb3"><code>29ba732acbee</code></a> <a href="https://github.com/torvalds/linux/commit/3a08c2fd763450a927d1130de078d6f9e74944fb"><code>3a08c2fd7634</code></a></td><td>BPF_MAP_TYPE_LRU_HASH</td></tr>
<tr><td>LRU per-CPU hash</td><td>4.10</td><td><a href="https://github.com/torvalds/linux/commit/8f8449384ec364ba2a654f11f94e754e4ff719e0"><code>8f8449384ec3</code></a> <a href="https://github.com/torvalds/linux/commit/961578b63474d13ad0e2f615fcc2901c5197dda6"><code>961578b63474</code></a></td><td>BPF_MAP_TYPE_LRU_PERCPU_HASH</td></tr>
<tr><td>LPM trie (longest-prefix match)</td><td>4.11</td><td><a href="https://github.com/torvalds/linux/commit/b95a5c4db09bc7c253636cb84dc9b12c577fd5a0"><code>b95a5c4db09b</code></a></td><td>BPF_MAP_TYPE_LPM_TRIE</td></tr>
<tr><td>Array of maps</td><td>4.12</td><td><a href="https://github.com/torvalds/linux/commit/56f668dfe00dcf086734f1c42ea999398fad6572"><code>56f668dfe00d</code></a></td><td>BPF_MAP_TYPE_ARRAY_OF_MAPS</td></tr>
<tr><td>Hash of maps</td><td>4.12</td><td><a href="https://github.com/torvalds/linux/commit/bcc6b1b7ebf857a9fe56202e2be3361131588c15"><code>bcc6b1b7ebf8</code></a></td><td>BPF_MAP_TYPE_HASH_OF_MAPS</td></tr>
<tr><td>Array of maps</td><td>4.12</td><td><a href="https://github.com/torvalds/linux/commit/56f668dfe00dcf086734f1c42ea999398fad6572"><code>56f668dfe00d</code></a></td><td>BPF_MAP_TYPE_ARRAY_OF_MAPSHash of maps</td></tr>
<tr><td>Netdevice references (array)</td><td>4.14</td><td><a href="https://github.com/torvalds/linux/commit/546ac1ffb70d25b56c1126940e5ec639c4dd7413"><code>546ac1ffb70d</code></a></td><td>BPF_MAP_TYPE_DEVMAP</td></tr>
<tr><td>Socket references (array)</td><td>4.14</td><td><a href="https://github.com/torvalds/linux/commit/174a79ff9515f400b9a6115643dafd62a635b7e6"><code>174a79ff9515</code></a></td><td>BPF_MAP_TYPE_SOCKMAP</td></tr>
<tr><td>CPU references</td><td>4.15</td><td><a href="https://github.com/torvalds/linux/commit/6710e1126934d8b4372b4d2f9ae1646cd3f151bf"><code>6710e1126934</code></a></td><td>BPF_MAP_TYPE_CPUMAP</td></tr>
@@ -318,86 +328,82 @@ The list of such program types supported in your kernel can be found in file
<tr><td>precpu cgroup storage</td><td>4.20</td><td><a href="https://github.com/torvalds/linux/commit/b741f1630346defcbc8cc60f1a2bdae8b3b0036f"><code>b741f1630346</code></a></td><td>BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE</td></tr>
<tr><td>queue</td><td>4.20</td><td><a href="https://github.com/torvalds/linux/commit/f1a2e44a3aeccb3ff18d3ccc0b0203e70b95bd92"><code>f1a2e44a3aec</code></a></td><td>BPF_MAP_TYPE_QUEUE</td></tr>
<tr><td>stack</td><td>4.20</td><td><a href="https://github.com/torvalds/linux/commit/f1a2e44a3aeccb3ff18d3ccc0b0203e70b95bd92"><code>f1a2e44a3aec</code></a></td><td>BPF_MAP_TYPE_STACK</td></tr>
<tr><td>socket local storage</td><td>5.2</td><td><a href="https://github.com/torvalds/linux/commit/6ac99e8f23d4b10258406ca0dd7bffca5f31da9d"><code>6ac99e8f23d4</code></a></td><td>BPF_MAP_TYPE_SK_STORAGE</td></tr>
<tr><td>Netdevice references (hashmap)</td><td>5.4</td><td><a href="https://github.com/torvalds/linux/commit/6f9d451ab1a33728adb72d7ff66a7b374d665176"><code>6f9d451ab1a3</code></a></td><td>BPF_MAP_TYPE_DEVMAP_HASH</td></tr>
<tr><td>struct ops</td><td>5.6</td><td><a href="https://github.com/torvalds/linux/commit/85d33df357b634649ddbe0a20fd2d0fc5732c3cb"><code>85d33df357b6</code></a></td><td>BPF_MAP_TYPE_STRUCT_OPS</td></tr>
<tr><td>ring buffer</td><td>5.8</td><td><a href="https://github.com/torvalds/linux/commit/457f44363a8894135c85b7a9afd2bd8196db24ab"><code>457f44363a88</code></a></td><td>BPF_MAP_TYPE_RINGBUF</td></tr>
<tr><td>inode storage</td><td>5.10</td><td><a href="https://github.com/torvalds/linux/commit/8ea636848aca35b9f97c5b5dee30225cf2dd0fe6"><code>8ea636848aca</code></a></td><td>BPF_MAP_TYPE_INODE_STORAGE</td></tr>
<tr><td>task storage</td><td>5.11</td><td><a href="https://github.com/torvalds/linux/commit/4cf1bc1f10452065a29d576fc5693fc4fab5b919"><code>4cf1bc1f1045</code></a></td><td>BPF_MAP_TYPE_TASK_STORAGE</td></tr>
<tr><td>Bloom filter</td><td>5.16</td><td><a href="https://github.com/torvalds/linux/commit/9330986c03006ab1d33d243b7cfe598a7a3c1baa"><code>9330986c0300</code></a></td><td>BPF_MAP_TYPE_BLOOM_FILTER</td></tr>
<tr><td>user ringbuf</td><td>6.1</td><td><a href="https://github.com/torvalds/linux/commit/583c1f420173f7d84413a1a1fbf5109d798b4faa"><code>583c1f420173</code></a></td><td>BPF_MAP_TYPE_USER_RINGBUF</td></tr>
<tr><td>socket local storage</td><td>5.2</td><td><a href="https://github.com/torvalds/linux/commit/6ac99e8f23d4b10258406ca0dd7bffca5f31da9d"><code>6ac99e8f23d4</code></a></td><td>BPF_MAP_TYPE_SK_STORAGENetdevice references (hashmap)</td></tr>
<tr><td>struct ops</td><td>5.6</td><td><a href="https://github.com/torvalds/linux/commit/85d33df357b634649ddbe0a20fd2d0fc5732c3cb">85d33df357b6</a></td><td>BPF_MAP_TYPE_STRUCT_OPS</td></tr>
<tr><td>ring buffer</td><td>5.8</td><td><a href="https://github.com/torvalds/linux/commit/457f44363a8894135c85b7a9afd2bd8196db24ab">457f44363a88</a></td><td>BPF_MAP_TYPE_RINGBUF</td></tr>
<tr><td>inode storage</td><td>5.10</td><td><a href="https://github.com/torvalds/linux/commit/8ea636848aca35b9f97c5b5dee30225cf2dd0fe6">8ea636848aca</a></td><td>BPF_MAP_TYPE_INODE_STORAGE</td></tr>
<tr><td>task storage</td><td>5.11</td><td><a href="https://github.com/torvalds/linux/commit/4cf1bc1f10452065a29d576fc5693fc4fab5b919">4cf1bc1f1045</a></td><td>BPF_MAP_TYPE_TASK_STORAGE</td></tr>
<tr><td>Bloom filter</td><td>5.16</td><td><a href="https://github.com/torvalds/linux/commit/9330986c03006ab1d33d243b7cfe598a7a3c1baa">9330986c0300</a></td><td>BPF_MAP_TYPE_BLOOM_FILTER</td></tr>
<tr><td>user ringbuf</td><td>6.1</td><td><a href="https://github.com/torvalds/linux/commit/583c1f420173f7d84413a1a1fbf5109d798b4faa">583c1f420173</a></td><td>BPF_MAP_TYPE_USER_RINGBUF</td></tr>
</tbody></table>
</div>
<h3 id="map-userspace-api"><a class="header" href="#map-userspace-api">Map userspace API</a></h3>
<p>Some (but not all) of these <em>API features</em> translate to a subcommand beginning with <code>BPF_MAP_</code>.
The list of subcommands supported in your kernel can be found in file
<a href="https://github.com/torvalds/linux/blob/master/include/uapi/linux/bpf.h"><code>include/uapi/linux/bpf.h</code></a>:</p>
<a href="https://github.com/torvalds/linux/blob/master/include/uapi/linux/bpf.h">include/uapi/linux/bpf.h</a>:</p>
<pre><code class="language-sh">git grep -W 'bpf_cmd {' include/uapi/linux/bpf.h
</code></pre>
<div class="table-wrapper"><table><thead><tr><th>Feature</th><th>Kernel version</th><th>Commit</th></tr></thead><tbody>
<tr><td>Basic operations (lookup, update, delete, <code>GET_NEXT_KEY</code>)</td><td>3.18</td><td><a href="https://github.com/torvalds/linux/commit/db20fd2b01087bdfbe30bce314a198eefedcc42e"><code>db20fd2b0108</code></a></td></tr>
<tr><td>Pass flags to <code>UPDATE_ELEM</code></td><td>3.19</td><td><a href="https://github.com/torvalds/linux/commit/3274f52073d88b62f3c5ace82ae9d48546232e72"><code>3274f52073d8</code></a></td></tr>
<tr><td>Pre-alloc map memory by default</td><td>4.6</td><td><a href="https://github.com/torvalds/linux/commit/6c90598174322b8888029e40dd84a4eb01f56afe"><code>6c9059817432</code></a></td></tr>
<tr><td>Pass <code>NULL</code> to <code>GET_NEXT_KEY</code></td><td>4.12</td><td><a href="https://github.com/torvalds/linux/commit/8fe45924387be6b5c1be59a7eb330790c61d5d10"><code>8fe45924387b</code></a></td></tr>
<tr><td>Creation: select NUMA node</td><td>4.14</td><td><a href="https://github.com/torvalds/linux/commit/96eabe7a40aa17e613cf3db2c742ee8b1fc764d0"><code>96eabe7a40aa</code></a></td></tr>
<tr><td>Restrict access from syscall side</td><td>4.15</td><td><a href="https://github.com/torvalds/linux/commit/6e71b04a82248ccf13a94b85cbc674a9fefe53f5"><code>6e71b04a8224</code></a></td></tr>
<tr><td>Creation: specify map name</td><td>4.15</td><td><a href="https://github.com/torvalds/linux/commit/ad5b177bd73f5107d97c36f56395c4281fb6f089"><code>ad5b177bd73f</code></a></td></tr>
<tr><td>Basic operations (lookup, update, delete, <code>GET_NEXT_KEY</code>)</td><td>3.18</td><td><a href="https://github.com/torvalds/linux/commit/db20fd2b01087bdfbe30bce314a198eefedcc42e">db20fd2b0108</a></td></tr>
<tr><td>Pass flags to <code>UPDATE_ELEM</code></td><td>3.19</td><td><a href="https://github.com/torvalds/linux/commit/3274f52073d88b62f3c5ace82ae9d48546232e72">3274f52073d8</a></td></tr>
<tr><td>Pre-alloc map memory by default</td><td>4.6</td><td><a href="https://github.com/torvalds/linux/commit/6c90598174322b8888029e40dd84a4eb01f56afe">6c9059817432</a>传递<code>NULL</code><code>GET_NEXT_KEY</code></td></tr>
<tr><td>创建: 选择NUMA节点</td><td>4.14</td><td><a href="https://github.com/torvalds/linux/commit/96eabe7a40aa17e613cf3db2c742ee8b1fc764d0"><code>96eabe7a40aa</code></a></td></tr>
<tr><td>限制从系统调用方面的访问</td><td>4.15</td><td><a href="https://github.com/torvalds/linux/commit/6e71b04a82248ccf13a94b85cbc674a9fefe53f5"><code>6e71b04a8224</code></a></td></tr>
<tr><td>创建: 指定映射名称</td><td>4.15</td><td><a href="https://github.com/torvalds/linux/commit/ad5b177bd73f5107d97c36f56395c4281fb6f089"><code>ad5b177bd73f</code></a></td></tr>
<tr><td><code>LOOKUP_AND_DELETE_ELEM</code></td><td>4.20</td><td><a href="https://github.com/torvalds/linux/commit/bd513cd08f10cbe28856f99ae951e86e86803861"><code>bd513cd08f10</code></a></td></tr>
<tr><td>Creation: <code>BPF_F_ZERO_SEED</code></td><td>5.0</td><td><a href="https://github.com/torvalds/linux/commit/96b3b6c9091d23289721350e32c63cc8749686be"><code>96b3b6c9091d</code></a></td></tr>
<tr><td><code>BPF_F_LOCK</code> flag for lookup / update</td><td>5.1</td><td><a href="https://github.com/torvalds/linux/commit/96049f3afd50fe8db69fa0068cdca822e747b1e4"><code>96049f3afd50</code></a></td></tr>
<tr><td>Restrict access from BPF side</td><td>5.2</td><td><a href="https://github.com/torvalds/linux/commit/591fe9888d7809d9ee5c828020b6c6ae27c37229"><code>591fe9888d78</code></a></td></tr>
<tr><td>创建: <code>BPF_F_ZERO_SEED</code></td><td>5.0</td><td><a href="https://github.com/torvalds/linux/commit/96b3b6c9091d23289721350e32c63cc8749686be"><code>96b3b6c9091d</code></a></td></tr>
<tr><td>查找/更新的<code>BPF_F_LOCK</code>标志</td><td>5.1</td><td><a href="https://github.com/torvalds/linux/commit/96049f3afd50fe8db69fa0068cdca822e747b1e4"><code>96049f3afd50</code></a></td></tr>
<tr><td>限制从BPF方面的访问</td><td>5.2</td><td><a href="https://github.com/torvalds/linux/commit/591fe9888d7809d9ee5c828020b6c6ae27c37229"><code>591fe9888d78</code></a></td></tr>
<tr><td><code>FREEZE</code></td><td>5.2</td><td><a href="https://github.com/torvalds/linux/commit/87df15de441bd4add7876ef584da8cabdd9a042a"><code>87df15de441b</code></a></td></tr>
<tr><td>mmap() support for array maps</td><td>5.5</td><td><a href="https://github.com/torvalds/linux/commit/fc9702273e2edb90400a34b3be76f7b08fa3344b"><code>fc9702273e2e</code></a></td></tr>
<tr><td>数组映射的mmap()支持</td><td>5.5</td><td><a href="https://github.com/torvalds/linux/commit/fc9702273e2edb90400a34b3be76f7b08fa3344b"><code>fc9702273e2e</code></a></td></tr>
<tr><td><code>LOOKUP_BATCH</code></td><td>5.6</td><td><a href="https://github.com/torvalds/linux/commit/cb4d03ab499d4c040f4ab6fd4389d2b49f42b5a5"><code>cb4d03ab499d</code></a></td></tr>
<tr><td><code>UPDATE_BATCH</code>, <code>DELETE_BATCH</code></td><td>5.6</td><td><a href="https://github.com/torvalds/linux/commit/aa2e93b8e58e18442edfb2427446732415bc215e"><code>aa2e93b8e58e</code></a></td></tr>
<tr><td><code>LOOKUP_AND_DELETE_BATCH</code></td><td>5.6</td><td><a href="https://github.com/torvalds/linux/commit/057996380a42bb64ccc04383cfa9c0ace4ea11f0"><code>057996380a42</code></a></td></tr>
<tr><td><code>LOOKUP_AND_DELETE_ELEM</code> support for hash maps</td><td>5.14</td><td><a href="https://github.com/torvalds/linux/commit/3e87f192b405960c0fe83e0925bd0dadf4f8cf43"><code>3e87f192b405</code></a></td></tr>
<tr><td><code>LOOKUP_AND_DELETE_ELEM</code>哈希映射的支持</td><td>5.14</td><td><a href="https://github.com/torvalds/linux/commit/3e87f192b405960c0fe83e0925bd0dadf4f8cf43"><code>3e87f192b405</code></a></td></tr>
</tbody></table>
</div>
<h2 id="xdp"><a class="header" href="#xdp">XDP</a></h2>
<p>An approximate list of drivers or components supporting XDP programs for your
kernel can be retrieved with:</p>
<pre><code class="language-sh">git grep -l XDP_SETUP_PROG drivers/
</code></pre>
<div class="table-wrapper"><table><thead><tr><th>Feature / Driver</th><th>Kernel version</th><th>Commit</th></tr></thead><tbody>
<tr><td>XDP core architecture</td><td>4.8</td><td><a href="https://github.com/torvalds/linux/commit/6a773a15a1e8874e5eccd2f29190c31085912c95"><code>6a773a15a1e8</code></a></td></tr>
<tr><td>Action: drop</td><td>4.8</td><td><a href="https://github.com/torvalds/linux/commit/6a773a15a1e8874e5eccd2f29190c31085912c95"><code>6a773a15a1e8</code></a></td></tr>
<tr><td>Action: pass on to stack</td><td>4.8</td><td><a href="https://github.com/torvalds/linux/commit/6a773a15a1e8874e5eccd2f29190c31085912c95"><code>6a773a15a1e8</code></a></td></tr>
<tr><td>Action: direct forwarding (on same port)</td><td>4.8</td><td><a href="https://github.com/torvalds/linux/commit/6ce96ca348a9e949f8c43f4d3e98db367d93cffd"><code>6ce96ca348a9</code></a></td></tr>
<tr><td>Direct packet data write</td><td>4.8</td><td><a href="https://github.com/torvalds/linux/commit/4acf6c0b84c91243c705303cd9ff16421914150d"><code>4acf6c0b84c9</code></a></td></tr>
<tr><td>Mellanox <code>mlx4</code> driver</td><td>4.8</td><td><a href="https://github.com/torvalds/linux/commit/47a38e155037f417c5740e24ccae6482aedf4b68"><code>47a38e155037</code></a></td></tr>
<tr><td>Mellanox <code>mlx5</code> driver</td><td>4.9</td><td><a href="https://github.com/torvalds/linux/commit/86994156c736978d113e7927455d4eeeb2128b9f"><code>86994156c736</code></a></td></tr>
<tr><td>Netronome <code>nfp</code> driver</td><td>4.10</td><td><a href="https://github.com/torvalds/linux/commit/ecd63a0217d5f1e8a92f7516f5586d1177b95de2"><code>ecd63a0217d5</code></a></td></tr>
<tr><td>QLogic (Cavium) <code>qed*</code> drivers</td><td>4.10</td><td><a href="https://github.com/torvalds/linux/commit/496e051709588f832d7a6a420f44f8642b308a87"><code>496e05170958</code></a></td></tr>
<tr><td><code>virtio_net</code> driver</td><td>4.10</td><td><a href="https://github.com/torvalds/linux/commit/f600b690501550b94e83e07295d9c8b9c4c39f4e"><code>f600b6905015</code></a></td></tr>
<tr><td>Broadcom <code>bnxt_en</code> driver</td><td>4.11</td><td><a href="https://github.com/torvalds/linux/commit/c6d30e8391b85e00eb544e6cf047ee0160ee9938"><code>c6d30e8391b8</code></a></td></tr>
<tr><td>Intel <code>ixgbe*</code> drivers</td><td>4.12</td><td><a href="https://github.com/torvalds/linux/commit/9247080816297de4e31abb684939c0e53e3a8a67"><code>924708081629</code></a></td></tr>
<tr><td>Cavium <code>thunderx</code> driver</td><td>4.12</td><td><a href="https://github.com/torvalds/linux/commit/05c773f52b96ef3fbc7d9bfa21caadc6247ef7a8"><code>05c773f52b96</code></a></td></tr>
<tr><td>Generic XDP</td><td>4.12</td><td><a href="https://github.com/torvalds/linux/commit/b5cdae3291f7be7a34e75affe4c0ec1f7f328b64"><code>b5cdae3291f7</code></a></td></tr>
<tr><td>Intel <code>i40e</code> driver</td><td>4.13</td><td><a href="https://github.com/torvalds/linux/commit/0c8493d90b6bb0f5c4fe9217db8f7203f24c0f28"><code>0c8493d90b6b</code></a></td></tr>
<tr><td>Action: redirect</td><td>4.14</td><td><a href="https://github.com/torvalds/linux/commit/6453073987ba392510ab6c8b657844a9312c67f7"><code>6453073987ba</code></a></td></tr>
<tr><td>Support for tap</td><td>4.14</td><td><a href="https://github.com/torvalds/linux/commit/761876c857cb2ef8489fbee01907151da902af91"><code>761876c857cb</code></a></td></tr>
<tr><td>Support for veth</td><td>4.14</td><td><a href="https://github.com/torvalds/linux/commit/d445516966dcb2924741b13b27738b54df2af01a"><code>d445516966dc</code></a></td></tr>
<tr><td>Intel <code>ixgbevf</code> driver</td><td>4.17</td><td><a href="https://github.com/torvalds/linux/commit/c7aec59657b60f3a29fc7d3274ebefd698879301"><code>c7aec59657b6</code></a></td></tr>
<tr><td>Freescale <code>dpaa2</code> driver</td><td>5.0</td><td><a href="https://github.com/torvalds/linux/commit/7e273a8ebdd3b83f94eb8b49fc8ee61464f47cc2"><code>7e273a8ebdd3</code></a></td></tr>
<tr><td>Socionext <code>netsec</code> driver</td><td>5.3</td><td><a href="https://github.com/torvalds/linux/commit/ba2b232108d3c2951bab02930a00f23b0cffd5af"><code>ba2b232108d3</code></a></td></tr>
<tr><td>TI <code>cpsw</code> driver</td><td>5.3</td><td><a href="https://github.com/torvalds/linux/commit/9ed4050c0d75768066a07cf66eef4f8dc9d79b52"><code>9ed4050c0d75</code></a></td></tr>
<tr><td>Intel <code>ice</code> driver</td><td>5.5</td><td><a href="https://github.com/torvalds/linux/commit/efc2214b6047b6f5b4ca53151eba62521b9452d6"><code>efc2214b6047</code></a></td></tr>
<tr><td>Solarflare <code>sfc</code> driver</td><td>5.5</td><td><a href="https://github.com/torvalds/linux/commit/eb9a36be7f3ec414700af9a616f035eda1f1e63e"><code>eb9a36be7f3e</code></a></td></tr>
<tr><td>Marvell <code>mvneta</code> driver</td><td>5.5</td><td><a href="https://github.com/torvalds/linux/commit/0db51da7a8e99f0803ec3a8e25c1a66234a219cb"><code>0db51da7a8e9</code></a></td></tr>
<tr><td>Microsoft <code>hv_netvsc</code> driver</td><td>5.6</td><td><a href="https://github.com/torvalds/linux/commit/351e1581395fcc7fb952bbd7dda01238f69968fd"><code>351e1581395f</code></a></td></tr>
<tr><td>Amazon <code>ena</code> driver</td><td>5.6</td><td><a href="https://github.com/torvalds/linux/commit/838c93dc5449e5d6378bae117b0a65a122cf7361"><code>838c93dc5449</code></a></td></tr>
<tr><td><code>xen-netfront</code> driver</td><td>5.9</td><td><a href="https://github.com/torvalds/linux/commit/6c5aa6fc4defc2a0977a2c59e4710d50fa1e834c"><code>6c5aa6fc4def</code></a></td></tr>
<tr><td>Intel <code>igb</code> driver</td><td>5.10</td><td><a href="https://github.com/torvalds/linux/commit/9cbc948b5a20c9c054d9631099c0426c16da546b"><code>9cbc948b5a20</code></a></td></tr>
<p>您的内核支持XDP程序的驱动程序或组件的近似列表可以用以下命令检索:
```sh````git grep -l XDP_SETUP_PROG drivers/</p>
<div class="table-wrapper"><table><thead><tr><th>功能/驱动</th><th>内核版本</th><th>提交</th></tr></thead><tbody>
<tr><td>XDP核心架构</td><td>4.8</td><td><a href="https://github.com/torvalds/linux/commit/6a773a15a1e8874e5eccd2f29190c31085912c95"><code>6a773a15a1e8</code></a></td></tr>
<tr><td>操作:丢弃</td><td>4.8</td><td><a href="https://github.com/torvalds/linux/commit/6a773a15a1e8874e5eccd2f29190c31085912c95"><code>6a773a15a1e8</code></a></td></tr>
<tr><td>操作:传递到堆栈</td><td>4.8</td><td><a href="https://github.com/torvalds/linux/commit/6a773a15a1e8874e5eccd2f29190c31085912c95"><code>6a773a15a1e8</code></a></td></tr>
<tr><td>直接转发(同一端口)</td><td>4.8</td><td><a href="https://github.com/torvalds/linux/commit/6ce96ca348a9e949f8c43f4d3e98db367d93cffd"><code>6ce96ca348a9</code></a></td></tr>
<tr><td>直接数据包数据写入</td><td>4.8</td><td><a href="https://github.com/torvalds/linux/commit/4acf6c0b84c91243c705303cd9ff16421914150d"><code>4acf6c0b84c9</code></a></td></tr>
<tr><td>Mellanox <code>mlx4</code>驱动</td><td>4.8</td><td><a href="https://github.com/torvalds/linux/commit/47a38e155037f417c5740e24ccae6482aedf4b68"><code>47a38e155037</code></a></td></tr>
<tr><td>Mellanox <code>mlx5</code>驱动</td><td>4.9</td><td><a href="https://github.com/torvalds/linux/commit/86994156c736978d113e7927455d4eeeb2128b9f"><code>86994156c736</code></a></td></tr>
<tr><td>Netronome <code>nfp</code>驱动</td><td>4.10</td><td><a href="https://github.com/torvalds/linux/commit/ecd63a0217d5f1e8a92f7516f5586d1177b95de2"><code>ecd63a0217d5</code></a></td></tr>
<tr><td>QLogicCavium<code>qed*</code>驱动</td><td>4.10</td><td><a href="https://github.com/torvalds/linux/commit/496e051709588f832d7a6a420f44f8642b308a87"><code>496e05170958</code></a></td></tr>
<tr><td><code>virtio_net</code>驱动</td><td>4.10</td><td><a href="https://github.com/torvalds/linux/commit/f600b690501550b94e83e07295d9c8b9c4c39f4e"><code>f600b6905015</code></a></td></tr>
<tr><td>Broadcom <code>bnxt_en</code>驱动</td><td>4.11</td><td><a href="https://github.com/torvalds/linux/commit/c6d30e8391b85e00eb544e6cf047ee0160ee9938"><code>c6d30e8391b8</code></a></td></tr>
<tr><td>Intel <code>ixgbe*</code>驱动</td><td>4.12</td><td><a href="https://github.com/torvalds/linux/commit/9247080816297de4e31abb684939c0e53e3a8a67"><code>924708081629</code></a></td></tr>
<tr><td>Cavium <code>thunderx</code>驱动</td><td>4.12</td><td><a href="https://github.com/torvalds/linux/commit/05c773f52b96ef3fbc7d9bfa21caadc6247ef7a8"><code>05c773f52b96</code></a></td></tr>
<tr><td>通用XDP</td><td>4.12</td><td><a href="https://github.com/torvalds/linux/commit/b5cdae3291f7be7a34e75affe4c0ec1f7f328b64"><code>b5cdae3291f7</code></a>`</td></tr>
</tbody></table>
</div>
<h2 id="helpers"><a class="header" href="#helpers">Helpers</a></h2>
<p>The list of helpers supported in your kernel can be found in file
<a href="https://github.com/torvalds/linux/blob/master/include/uapi/linux/bpf.h"><code>include/uapi/linux/bpf.h</code></a>:</p>
<pre><code class="language-sh">git grep ' FN(' include/uapi/linux/bpf.h
<p><strong>注意:</strong>
本次翻译仅包括翻译部分,不包括原始文本。## 帮助者</p>
<p>您的内核支持的辅助者列表可在文件中找到。</p>
<p>Intel <code>i40e</code> 驱动程序 | 4.13 | <a href="https://github.com/torvalds/linux/commit/0c8493d90b6bb0f5c4fe9217db8f7203f24c0f28"><code>0c8493d90b6b</code></a></p>
<p>操作:重定向 | 4.14 | <a href="https://github.com/torvalds/linux/commit/6453073987ba392510ab6c8b657844a9312c67f7"><code>6453073987ba</code></a></p>
<p>支持 tap | 4.14 | <a href="https://github.com/torvalds/linux/commit/761876c857cb2ef8489fbee01907151da902af91"><code>761876c857cb</code></a></p>
<p>支持 veth | 4.14 | <a href="https://github.com/torvalds/linux/commit/d445516966dcb2924741b13b27738b54df2af01a"><code>d445516966dc</code></a></p>
<p>Intel <code>ixgbevf</code> 驱动程序 | 4.17 | <a href="https://github.com/torvalds/linux/commit/c7aec59657b60f3a29fc7d3274ebefd698879301"><code>c7aec59657b6</code></a></p>
<p>Freescale <code>dpaa2</code> 驱动程序 | 5.0 | <a href="https://github.com/torvalds/linux/commit/7e273a8ebdd3b83f94eb8b49fc8ee61464f47cc2"><code>7e273a8ebdd3</code></a></p>
<p>Socionext <code>netsec</code> 驱动程序 | 5.3 | <a href="https://github.com/torvalds/linux/commit/ba2b232108d3c2951bab02930a00f23b0cffd5af"><code>ba2b232108d3</code></a></p>
<p>TI <code>cpsw</code> 驱动程序 | 5.3 | <a href="https://github.com/torvalds/linux/commit/9ed4050c0d75768066a07cf66eef4f8dc9d79b52"><code>9ed4050c0d75</code></a></p>
<p>Intel <code>ice</code> 驱动程序 |5.5| <a href="https://github.com/torvalds/linux/commit/efc2214b6047b6f5b4ca53151eba62521b9452d6"><code>efc2214b6047</code></a></p>
<p>Solarflare <code>sfc</code> 驱动程序 | 5.5 | <a href="https://github.com/torvalds/linux/commit/eb9a36be7f3ec414700af9a616f035eda1f1e63e"><code>eb9a36be7f3e</code></a></p>
<p>Marvell <code>mvneta</code> 驱动程序 | 5.5 | <a href="https://github.com/torvalds/linux/commit/0db51da7a8e99f0803ec3a8e25c1a66234a219cb"><code>0db51da7a8e9</code></a></p>
<p>Microsoft <code>hv_netvsc</code> 驱动程序 | 5.6 | <a href="https://github.com/torvalds/linux/commit/351e1581395fcc7fb952bbd7dda01238f69968fd"><code>351e1581395f</code></a></p>
<p>Amazon <code>ena</code> 驱动程序 | 5.6 | <a href="https://github.com/torvalds/linux/commit/838c93dc5449e5d6378bae117b0a65a122cf7361"><code>838c93dc5449</code></a></p>
<p><code>xen-netfront</code> 驱动程序 | 5.9 | <a href="https://github.com/torvalds/linux/commit/6c5aa6fc4defc2a0977a2c59e4710d50fa1e834c"><code>6c5aa6fc4def</code></a></p>
<p>Intel <code>gi</code> 驱动程序 | 5.10 | <a href="https://github.com/torvalds/linux/commit/9cbc948b5a20c9c054d9631099c0426c16da546b"><code>9cbc948b5a20</code></a><code>include/uapi/linux/bpf.h</code>: <a href="https://github.com/torvalds/linux/blob/master/include/uapi/linux/bpf.h"><code>include/uapi/linux/bpf.h</code></a>:</p>
<pre><code class="language-sh">git grep ' FN(' include/uapi/linux/bpf.h
</code></pre>
<p>Alphabetical order</p>
<div class="table-wrapper"><table><thead><tr><th>Helper</th><th>Kernel version</th><th>License</th><th>Commit</th></tr></thead><tbody>
<p>按字母顺序排列</p>
<div class="table-wrapper"><table><thead><tr><th>Helper</th><th>内核版本</th><th>授权许可</th><th>提交记录</th></tr></thead><tbody>
<tr><td><code>BPF_FUNC_bind()</code></td><td>4.17</td><td></td><td><a href="https://github.com/torvalds/linux/commit/d74bad4e74ee373787a9ae24197c17b7cdc428d5"><code>d74bad4e74ee</code></a></td></tr>
<tr><td><code>BPF_FUNC_bprm_opts_set()</code></td><td>5.11</td><td></td><td><a href="https://github.com/torvalds/linux/commit/3f6719c7b62f0327c9091e26d0da10e65668229e"><code>3f6719c7b62f</code></a></td></tr>
<tr><td><code>BPF_FUNC_btf_find_by_name_kind()</code></td><td>5.14</td><td></td><td><a href="https://github.com/torvalds/linux/commit/3d78417b60fba249cc555468cb72d96f5cde2964"><code>3d78417b60fb</code></a></td></tr>
@@ -409,8 +415,7 @@ kernel can be retrieved with:</p>
<tr><td><code>BPF_FUNC_copy_from_user_task()</code></td><td>5.18</td><td>GPL</td><td><a href="https://github.com/torvalds/linux/commit/376040e47334c6dc6a939a32197acceb00fe4acf"><code>376040e47334</code></a></td></tr>
<tr><td><code>BPF_FUNC_csum_diff()</code></td><td>4.6</td><td></td><td><a href="https://github.com/torvalds/linux/commit/7d672345ed295b1356a5d9f7111da1d1d7d65867"><code>7d672345ed29</code></a></td></tr>
<tr><td><code>BPF_FUNC_csum_level()</code></td><td>5.7</td><td></td><td><a href="https://github.com/torvalds/linux/commit/7cdec54f9713256bb170873a1fc5c75c9127c9d2"><code>7cdec54f9713</code></a></td></tr>
<tr><td><code>BPF_FUNC_csum_update()</code></td><td>4.9</td><td></td><td><a href="https://github.com/torvalds/linux/commit/36bbef52c7eb646ed6247055a2acd3851e317857"><code>36bbef52c7eb</code></a></td></tr>
<tr><td><code>BPF_FUNC_current_task_under_cgroup()</code></td><td>4.9</td><td></td><td><a href="https://github.com/torvalds/linux/commit/60d20f9195b260bdf0ac10c275ae9f6016f9c069"><code>60d20f9195b2</code></a></td></tr>
<tr><td><code>BPF_FUNC_csum_update()</code></td><td>4.9</td><td></td><td><a href="https://github.com/torvalds/linux/commit/36bbef52c7eb646ed6247055a2acd3851e317857"><code>36bbef52c7eb</code></a>&quot;<code>BPF_FUNC_current_task_under_cgroup()</code></td></tr>
<tr><td><code>BPF_FUNC_d_path()</code></td><td>5.10</td><td></td><td><a href="https://github.com/torvalds/linux/commit/6e22ab9da79343532cd3cde39df25e5a5478c692"><code>6e22ab9da793</code></a></td></tr>
<tr><td><code>BPF_FUNC_dynptr_data()</code></td><td>5.19</td><td></td><td><a href="https://github.com/torvalds/linux/commit/34d4ef5775f776ec4b0d53a02d588bf3195cada6"><code>34d4ef5775f7</code></a></td></tr>
<tr><td><code>BPF_FUNC_dynptr_from_mem()</code></td><td>5.19</td><td></td><td><a href="https://github.com/torvalds/linux/commit/263ae152e96253f40c2c276faad8629e096b3bad"><code>263ae152e962</code></a></td></tr>
@@ -424,7 +429,20 @@ kernel can be retrieved with:</p>
<tr><td><code>BPF_FUNC_get_current_ancestor_cgroup_id()</code></td><td>5.6</td><td></td><td><a href="https://github.com/torvalds/linux/commit/b4490c5c4e023f09b7d27c9a9d3e7ad7d09ea6bf"><code>b4490c5c4e02</code></a></td></tr>
<tr><td><code>BPF_FUNC_get_cgroup_classid()</code></td><td>4.3</td><td></td><td><a href="https://github.com/torvalds/linux/commit/8d20aabe1c76cccac544d9fcc3ad7823d9e98a2d"><code>8d20aabe1c76</code></a></td></tr>
<tr><td><code>BPF_FUNC_get_current_cgroup_id()</code></td><td>4.18</td><td></td><td><a href="https://github.com/torvalds/linux/commit/bf6fa2c893c5237b48569a13fa3c673041430b6c"><code>bf6fa2c893c5</code></a></td></tr>
<tr><td><code>BPF_FUNC_get_current_comm()</code></td><td>4.2</td><td></td><td><a href="https://github.com/torvalds/linux/commit/ffeedafbf0236f03aeb2e8db273b3e5ae5f5bc89"><code>ffeedafbf023</code></a></td></tr>
<tr><td><code>BPF_FUNC_current_task_under_cgroup()</code></td><td>4.9</td><td></td><td><a href="https://github.com/torvalds/linux/commit/60d20f9195b260bdf0ac10c275ae9f6016f9c069"><code>60d20f9195b2</code></a></td></tr>
<tr><td><code>BPF_FUNC_d_path()</code></td><td>5.10</td><td></td><td><a href="https://github.com/torvalds/linux/commit/6e22ab9da79343532cd3cde39df25e5a5478c692"><code>6e22ab9da793</code></a></td></tr>
<tr><td><code>BPF_FUNC_dynptr_data()</code></td><td>5.19</td><td></td><td><a href="https://github.com/torvalds/linux/commit/34d4ef5775f776ec4b0d53a02d588bf3195cada6"><code>34d4ef5775f7</code></a></td></tr>
<tr><td><code>BPF_FUNC_dynptr_from_mem()</code></td><td>5.19</td><td></td><td><a href="https://github.com/torvalds/linux/commit/263ae152e96253f40c2c276faad8629e096b3bad"><code>263ae152e962</code></a></td></tr>
<tr><td><code>BPF_FUNC_dynptr_read()</code></td><td>5.19</td><td></td><td><a href="https://github.com/torvalds/linux/commit/13bbbfbea7598ea9f8d9c3d73bf053bb57f9c4b2"><code>13bbbfbea759</code></a></td></tr>
<tr><td><code>BPF_FUNC_dynptr_write()</code></td><td>5.19</td><td></td><td><a href="https://github.com/torvalds/linux/commit/13bbbfbea7598ea9f8d9c3d73bf053bb57f9c4b2"><code>13bbbfbea759</code></a></td></tr>
<tr><td><code>BPF_FUNC_fib_lookup()</code></td><td>4.18</td><td>GPL</td><td><a href="https://github.com/torvalds/linux/commit/87f5fc7e48dd3175b30dd03b41564e1a8e136323"><code>87f5fc7e48dd</code></a></td></tr>
<tr><td><code>BPF_FUNC_find_vma()</code></td><td>5.17</td><td></td><td><a href="https://github.com/torvalds/linux/commit/7c7e3d31e7856a8260a254f8c71db416f7f9f5a1"><code>7c7e3d31e785</code></a></td></tr>
<tr><td><code>BPF_FUNC_for_each_map_elem()</code></td><td>5.13</td><td></td><td><a href="https://github.com/torvalds/linux/commit/69c087ba6225b574afb6e505b72cb75242a3d844"><code>69c087ba6225</code></a></td></tr>
<tr><td><code>BPF_FUNC_get_attach_cookie()</code></td><td>5.15</td><td></td><td><a href="https://github.com/torvalds/linux/commit/7adfc6c9b315e174cf8743b21b7b691c8766791b"><code>7adfc6c9b315</code></a></td></tr>
<tr><td><code>BPF_FUNC_get_branch_snapshot()</code></td><td>5.16</td><td>GPL</td><td><a href="https://github.com/torvalds/linux/commit/856c02dbce4f8d6a5644083db22c11750aa11481"><code>856c02dbce4f</code></a></td></tr>
<tr><td><code>BPF_FUNC_get_current_ancestor_cgroup_id()</code></td><td>5.6</td><td></td><td><a href="https://github.com/torvalds/linux/commit/b4490c5c4e023f09b7d27c9a9d3e7ad7d09ea6bf"><code>b4490c5c4e02</code></a></td></tr>
<tr><td><code>BPF_FUNC_get_cgroup_classid()</code></td><td>4.3</td><td></td><td><a href="https://github.com/torvalds/linux/commit/8d20aabe1c76cccac544d9fcc3ad7823d9e98a2d"><code>8d20aabe1c76</code></a></td></tr>
<tr><td><code>BPF_FUNC_get_current_cgroup_id()</code></td><td>4.18</td><td></td><td><a href="https://github.com/torvalds/linux/commit/bf6fa2c893c5237b48569a13fa3c673041430b6c"><code>bf6fa2c893c5</code></a>&quot;.&quot;<code>BPF_FUNC_get_current_comm()</code></td></tr>
<tr><td><code>BPF_FUNC_get_current_pid_tgid()</code></td><td>4.2</td><td></td><td><a href="https://github.com/torvalds/linux/commit/ffeedafbf0236f03aeb2e8db273b3e5ae5f5bc89"><code>ffeedafbf023</code></a></td></tr>
<tr><td><code>BPF_FUNC_get_current_task()</code></td><td>4.8</td><td>GPL</td><td><a href="https://github.com/torvalds/linux/commit/606274c5abd8e245add01bc7145a8cbb92b69ba8"><code>606274c5abd8</code></a></td></tr>
<tr><td><code>BPF_FUNC_get_current_task_btf()</code></td><td>5.11</td><td>GPL</td><td><a href="https://github.com/torvalds/linux/commit/3ca1032ab7ab010eccb107aa515598788f7d93bb"><code>3ca1032ab7ab</code></a></td></tr>
@@ -437,8 +455,7 @@ kernel can be retrieved with:</p>
<tr><td><code>BPF_FUNC_get_hash_recalc()</code></td><td>4.8</td><td></td><td><a href="https://github.com/torvalds/linux/commit/13c5c240f789bbd2bcacb14a23771491485ae61f"><code>13c5c240f789</code></a></td></tr>
<tr><td><code>BPF_FUNC_get_listener_sock()</code></td><td>5.1</td><td></td><td><a href="https://github.com/torvalds/linux/commit/dbafd7ddd62369b2f3926ab847cbf8fc40e800b7"><code>dbafd7ddd623</code></a></td></tr>
<tr><td><code>BPF_FUNC_get_local_storage()</code></td><td>4.19</td><td></td><td><a href="https://github.com/torvalds/linux/commit/cd3394317653837e2eb5c5d0904a8996102af9fc"><code>cd3394317653</code></a></td></tr>
<tr><td><code>BPF_FUNC_get_netns_cookie()</code></td><td>5.7</td><td></td><td><a href="https://github.com/torvalds/linux/commit/f318903c0bf42448b4c884732df2bbb0ef7a2284"><code>f318903c0bf4</code></a></td></tr>
<tr><td><code>BPF_FUNC_get_ns_current_pid_tgid()</code></td><td>5.7</td><td></td><td><a href="https://github.com/torvalds/linux/commit/b4490c5c4e023f09b7d27c9a9d3e7ad7d09ea6bf"><code>b4490c5c4e02</code></a></td></tr>
<tr><td><code>BPF_FUNC_get_netns_cookie()</code></td><td>5.7</td><td></td><td><a href="https://github.com/torvalds/linux/commit/f318903c0bf42448b4c884732df2bbb0ef7a2284"><code>f318903c0bf4</code></a><code>BPF_FUNC_get_ns_current_pid_tgid()</code></td></tr>
<tr><td><code>BPF_FUNC_get_numa_node_id()</code></td><td>4.10</td><td></td><td><a href="https://github.com/torvalds/linux/commit/2d0e30c30f84d08dc16f0f2af41f1b8a85f0755e"><code>2d0e30c30f84</code></a></td></tr>
<tr><td><code>BPF_FUNC_get_prandom_u32()</code></td><td>4.1</td><td></td><td><a href="https://github.com/torvalds/linux/commit/03e69b508b6f7c51743055c9f61d1dfeadf4b635"><code>03e69b508b6f</code></a></td></tr>
<tr><td><code>BPF_FUNC_get_route_realm()</code></td><td>4.4</td><td></td><td><a href="https://github.com/torvalds/linux/commit/c46646d0484f5d08e2bede9b45034ba5b8b489cc"><code>c46646d0484f</code></a></td></tr>
@@ -452,7 +469,20 @@ kernel can be retrieved with:</p>
<tr><td><code>BPF_FUNC_ima_file_hash()</code></td><td>5.18</td><td></td><td><a href="https://github.com/torvalds/linux/commit/174b16946e39ebd369097e0f773536c91a8c1a4c"><code>174b16946e39</code></a></td></tr>
<tr><td><code>BPF_FUNC_ima_inode_hash()</code></td><td>5.11</td><td></td><td><a href="https://github.com/torvalds/linux/commit/27672f0d280a3f286a410a8db2004f46ace72a17"><code>27672f0d280a</code></a></td></tr>
<tr><td><code>BPF_FUNC_inode_storage_delete()</code></td><td>5.10</td><td></td><td><a href="https://github.com/torvalds/linux/commit/8ea636848aca35b9f97c5b5dee30225cf2dd0fe6"><code>8ea636848aca</code></a></td></tr>
<tr><td><code>BPF_FUNC_inode_storage_get()</code></td><td>5.10</td><td></td><td><a href="https://github.com/torvalds/linux/commit/8ea636848aca35b9f97c5b5dee30225cf2dd0fe6"><code>8ea636848aca</code></a></td></tr>
<tr><td>RPC_FUNC_get_ns_current_pid_tgid()</td><td>5.7</td><td></td><td><a href="https://github.com/torvalds/linux/commit/b4490c5c4e023f09b7d27c9a9d3e7ad7d09ea6bf">b4490c5c4e02</a></td></tr>
<tr><td>RPC_FUNC_get_numa_node_id()</td><td>4.10</td><td></td><td><a href="https://github.com/torvalds/linux/commit/2d0e30c30f84d08dc16f0f2af41f1b8a85f0755e">2d0e30c30f84</a></td></tr>
<tr><td>RPC_FUNC_get_prandom_u32()</td><td>4.1</td><td></td><td><a href="https://github.com/torvalds/linux/commit/03e69b508b6f7c51743055c9f61d1dfeadf4b635">03e69b508b6f</a></td></tr>
<tr><td>RPC_FUNC_get_route_realm()</td><td>4.4</td><td></td><td><a href="https://github.com/torvalds/linux/commit/c46646d0484f5d08e2bede9b45034ba5b8b489cc">c46646d0484f</a></td></tr>
<tr><td>RPC_FUNC_get_smp_processor_id()</td><td>4.1</td><td></td><td><a href="https://github.com/torvalds/linux/commit/c04167ce2ca0ecaeaafef006cb0d65cf01b68e42">c04167ce2ca0</a></td></tr>
<tr><td>RPC_FUNC_get_socket_cookie()</td><td>4.12</td><td></td><td><a href="https://github.com/torvalds/linux/commit/91b8270f2a4d1d9b268de90451cdca63a70052d6">91b8270f2a4d</a></td></tr>
<tr><td>RPC_FUNC_get_socket_uid()</td><td>4.12</td><td></td><td><a href="https://github.com/torvalds/linux/commit/6acc5c2910689fc6ee181bf63085c5efff6a42bd">6acc5c291068</a></td></tr>
<tr><td>RPC_FUNC_get_stack()</td><td>4.18</td><td>GPL</td><td><a href="https://github.com/torvalds/linux/commit/de2ff05f48afcde816ff4edb217417f62f624ab5">de2ff05f48af</a></td></tr>
<tr><td>RPC_FUNC_get_stackid()</td><td>4.6</td><td>GPL</td><td><a href="https://github.com/torvalds/linux/commit/d5a3b1f691865be576c2bffa708549b8cdccda19">d5a3b1f69186</a></td></tr>
<tr><td>RPC_FUNC_get_task_stack()</td><td>5.9</td><td></td><td><a href="https://github.com/torvalds/linux/commit/fa28dcb82a38f8e3993b0fae9106b1a80b59e4f0">fa28dcb82a38</a></td></tr>
<tr><td>RPC_FUNC_getsockopt()</td><td>4.15</td><td></td><td><a href="https://github.com/torvalds/linux/commit/cd86d1fd21025fdd6daf23d1288da405e7ad0ec6">cd86d1fd2102</a></td></tr>
<tr><td>RPC_FUNC_ima_file_hash()</td><td>5.18</td><td></td><td><a href="https://github.com/torvalds/linux/commit/174b16946e39ebd369097e0f773536c91a8c1a4c">174b16946e39</a></td></tr>
<tr><td>RPC_FUNC_ima_inode_hash()</td><td>5.11</td><td></td><td><a href="https://github.com/torvalds/linux/commit/27672f0d280a3f286a410a8db2004f46ace72a17">27672f0d280a</a></td></tr>
<tr><td>RPC_FUNC_inode_storage_delete()</td><td>5.10</td><td></td><td><a href="https://github.com/torvalds/linux/commit/8ea636848aca35b9f97c5b5dee30225cf2dd0fe6">8ea636848aca</a>&quot;.&quot;<code>BPF_FUNC_inode_storage_get()</code></td></tr>
<tr><td><code>BPF_FUNC_jiffies64()</code></td><td>5.5</td><td></td><td><a href="https://github.com/torvalds/linux/commit/5576b991e9c1a11d2cc21c4b94fc75ec27603896"><code>5576b991e9c1</code></a></td></tr>
<tr><td><code>BPF_FUNC_kallsyms_lookup_name()</code></td><td>5.16</td><td></td><td><a href="https://github.com/torvalds/linux/commit/d6aef08a872b9e23eecc92d0e92393473b13c497"><code>d6aef08a872b</code></a></td></tr>
<tr><td><code>BPF_FUNC_kptr_xchg()</code></td><td>5.19</td><td></td><td><a href="https://github.com/torvalds/linux/commit/c0a5a21c25f37c9fd7b36072f9968cdff1e4aa13"><code>c0a5a21c25f3</code></a></td></tr>
@@ -465,22 +495,20 @@ kernel can be retrieved with:</p>
<tr><td><code>BPF_FUNC_load_hdr_opt()</code></td><td>5.10</td><td></td><td><a href="https://github.com/torvalds/linux/commit/0813a841566f0962a5551be7749b43c45f0022a0"><code>0813a841566f</code></a></td></tr>
<tr><td><code>BPF_FUNC_loop()</code></td><td>5.17</td><td></td><td><a href="https://github.com/torvalds/linux/commit/e6f2dd0f80674e9d5960337b3e9c2a242441b326"><code>e6f2dd0f8067</code></a></td></tr>
<tr><td><code>BPF_FUNC_lwt_push_encap()</code></td><td>4.18</td><td></td><td><a href="https://github.com/torvalds/linux/commit/fe94cc290f535709d3c5ebd1e472dfd0aec7ee79"><code>fe94cc290f53</code></a></td></tr>
<tr><td><code>BPF_FUNC_lwt_seg6_action()</code></td><td>4.18</td><td></td><td><a href="https://github.com/torvalds/linux/commit/fe94cc290f535709d3c5ebd1e472dfd0aec7ee79"><code>fe94cc290f53</code></a></td></tr>
<tr><td><code>BPF_FUNC_lwt_seg6_adjust_srh()</code></td><td>4.18</td><td></td><td><a href="https://github.com/torvalds/linux/commit/fe94cc290f535709d3c5ebd1e472dfd0aec7ee79"><code>fe94cc290f53</code></a></td></tr>
<tr><td><code>BPF_FUNC_lwt_seg6_store_bytes()</code></td><td>4.18</td><td></td><td><a href="https://github.com/torvalds/linux/commit/fe94cc290f535709d3c5ebd1e472dfd0aec7ee79"><code>fe94cc290f53</code></a></td></tr>
<tr><td><code>BPF_FUNC_map_delete_elem()</code></td><td>3.19</td><td></td><td><a href="https://github.com/torvalds/linux/commit/d0003ec01c667b731c139e23de3306a8b328ccf5"><code>d0003ec01c66</code></a></td></tr>
<tr><td><code>BPF_FUNC_map_lookup_elem()</code></td><td>3.19</td><td></td><td><a href="https://github.com/torvalds/linux/commit/d0003ec01c667b731c139e23de3306a8b328ccf5"><code>d0003ec01c66</code></a></td></tr>
<tr><td><code>BPF_FUNC_map_lookup_percpu_elem()</code></td><td>5.19</td><td></td><td><a href="https://github.com/torvalds/linux/commit/07343110b293456d30393e89b86c4dee1ac051c8"><code>07343110b293</code></a></td></tr>
<tr><td><code>BPF_FUNC_map_peek_elem()</code></td><td>4.20</td><td></td><td><a href="https://github.com/torvalds/linux/commit/f1a2e44a3aeccb3ff18d3ccc0b0203e70b95bd92"><code>f1a2e44a3aec</code></a></td></tr>
<tr><td><code>BPF_FUNC_map_pop_elem()</code></td><td>4.20</td><td></td><td><a href="https://github.com/torvalds/linux/commit/f1a2e44a3aeccb3ff18d3ccc0b0203e70b95bd92"><code>f1a2e44a3aec</code></a></td></tr>
<tr><td><code>BPF_FUNC_map_push_elem()</code></td><td>4.20</td><td></td><td><a href="https://github.com/torvalds/linux/commit/f1a2e44a3aeccb3ff18d3ccc0b0203e70b95bd92"><code>f1a2e44a3aec</code></a></td></tr>
<tr><td><code>BPF_FUNC_map_update_elem()</code></td><td>3.19</td><td></td><td><a href="https://github.com/torvalds/linux/commit/d0003ec01c667b731c139e23de3306a8b328ccf5"><code>d0003ec01c66</code></a></td></tr>
<tr><td><code>BPF_FUNC_msg_apply_bytes()</code></td><td>4.17</td><td></td><td><a href="https://github.com/torvalds/linux/commit/2a100317c9ebc204a166f16294884fbf9da074ce"><code>2a100317c9eb</code></a></td></tr>
<tr><td><code>BPF_FUNC_msg_cork_bytes()</code></td><td>4.17</td><td></td><td><a href="https://github.com/torvalds/linux/commit/91843d540a139eb8070bcff8aa10089164436deb"><code>91843d540a13</code></a></td></tr>
<tr><td><code>BPF_FUNC_msg_pop_data()</code></td><td>5.0</td><td></td><td><a href="https://github.com/torvalds/linux/commit/7246d8ed4dcce23f7509949a77be15fa9f0e3d28"><code>7246d8ed4dcc</code></a></td></tr>
<tr><td><code>BPF_FUNC_msg_pull_data()</code></td><td>4.17</td><td></td><td><a href="https://github.com/torvalds/linux/commit/015632bb30daaaee64e1bcac07570860e0bf3092"><code>015632bb30da</code></a></td></tr>
<tr><td><code>BPF_FUNC_msg_push_data()</code></td><td>4.20</td><td></td><td><a href="https://github.com/torvalds/linux/commit/6fff607e2f14bd7c63c06c464a6f93b8efbabe28"><code>6fff607e2f14</code></a></td></tr>
<tr><td><code>BPF_FUNC_msg_redirect_hash()</code></td><td>4.18</td><td></td><td><a href="https://github.com/torvalds/linux/commit/81110384441a59cff47430f20f049e69b98c17f4"><code>81110384441a</code></a></td></tr>
<tr><td><code>BPF_FUNC_lwt_seg6_action()</code></td><td>4.18</td><td></td><td><a href="https://github.com/torvalds/linux/commit/fe94cc290f535709d3c5ebd1e472dfd0aec7ee79"><code>fe94cc290f53</code></a>`BPF_FUNC_lwt_seg6_adjust_srh()`</td></tr>
<tr><td>`BPF_FUNC_lwt_seg6_store_bytes()`</td><td>4.18</td><td></td><td><a href="https://github.com/torvalds/linux/commit/fe94cc290f535709d3c5ebd1e472dfd0aec7ee79"><code>fe94cc290f53</code></a></td></tr>
<tr><td>`BPF_FUNC_map_delete_elem()`</td><td>3.19</td><td></td><td><a href="https://github.com/torvalds/linux/commit/d0003ec01c667b731c139e23de3306a8b328ccf5"><code>d0003ec01c66</code></a></td></tr>
<tr><td>`BPF_FUNC_map_lookup_elem()`</td><td>3.19</td><td></td><td><a href="https://github.com/torvalds/linux/commit/d0003ec01c667b731c139e23de3306a8b328ccf5"><code>d0003ec01c66</code></a></td></tr>
<tr><td>`BPF_FUNC_map_lookup_percpu_elem()`</td><td>5.19</td><td></td><td><a href="https://github.com/torvalds/linux/commit/07343110b293456d30393e89b86c4dee1ac051c8"><code>07343110b293</code></a></td></tr>
<tr><td>`BPF_FUNC_map_peek_elem()`</td><td>4.20</td><td></td><td><a href="https://github.com/torvalds/linux/commit/f1a2e44a3aeccb3ff18d3ccc0b0203e70b95bd92"><code>f1a2e44a3aec</code></a></td></tr>
<tr><td>`BPF_FUNC_map_pop_elem()`</td><td>4.20</td><td></td><td><a href="https://github.com/torvalds/linux/commit/f1a2e44a3aeccb3ff18d3ccc0b0203e70b95bd92"><code>f1a2e44a3aec</code></a></td></tr>
<tr><td>`BPF_FUNC_map_push_elem()`</td><td>4.20</td><td></td><td><a href="https://github.com/torvalds/linux/commit/f1a2e44a3aeccb3ff18d3ccc0b0203e70b95bd92"><code>f1a2e44a3aec</code></a></td></tr>
<tr><td>`BPF_FUNC_map_update_elem()`</td><td>3.19</td><td></td><td><a href="https://github.com/torvalds/linux/commit/d0003ec01c667b731c139e23de3306a8b328ccf5"><code>d0003ec01c66</code></a></td></tr>
<tr><td>`BPF_FUNC_msg_apply_bytes()`</td><td>4.17</td><td></td><td><a href="https://github.com/torvalds/linux/commit/2a100317c9ebc204a166f16294884fbf9da074ce"><code>2a100317c9eb</code></a></td></tr>
<tr><td>`BPF_FUNC_msg_cork_bytes()`</td><td>4.17</td><td></td><td><a href="https://github.com/torvalds/linux/commit/91843d540a139eb8070bcff8aa10089164436deb"><code>91843d540a13</code></a></td></tr>
<tr><td>`BPF_FUNC_msg_pop_data()`</td><td>5.0</td><td></td><td><a href="https://github.com/torvalds/linux/commit/7246d8ed4dcce23f7509949a77be15fa9f0e3d28"><code>7246d8ed4dcc</code></a></td></tr>
<tr><td>`BPF_FUNC_msg_pull_data()`</td><td>4.17</td><td></td><td><a href="https://github.com/torvalds/linux/commit/015632bb30daaaee64e1bcac07570860e0bf3092"><code>015632bb30da</code></a></td></tr>
<tr><td>`BPF_FUNC_msg_push_data()`</td><td>4.20</td><td></td><td><a href="https://github.com/torvalds/linux/commit/6fff607e2f14bd7c63c06c464a6f93b8efbabe28"><code>6fff607e2f14</code></a>&quot;.<code>BPF_FUNC_msg_redirect_hash()</code></td></tr>
<tr><td><code>BPF_FUNC_msg_redirect_map()</code></td><td>4.17</td><td></td><td><a href="https://github.com/torvalds/linux/commit/4f738adba30a7cfc006f605707e7aee847ffefa0"><code>4f738adba30a</code></a></td></tr>
<tr><td><code>BPF_FUNC_per_cpu_ptr()</code></td><td>5.10</td><td></td><td><a href="https://github.com/torvalds/linux/commit/eaa6bcb71ef6ed3dc18fc525ee7e293b06b4882b"><code>eaa6bcb71ef6</code></a></td></tr>
<tr><td><code>BPF_FUNC_perf_event_output()</code></td><td>4.4</td><td>GPL</td><td><a href="https://github.com/torvalds/linux/commit/a43eec304259a6c637f4014a6d4767159b6a3aa3"><code>a43eec304259</code></a></td></tr>
@@ -493,8 +521,7 @@ kernel can be retrieved with:</p>
<tr><td><code>BPF_FUNC_probe_read_user()</code></td><td>5.5</td><td>GPL</td><td><a href="https://github.com/torvalds/linux/commit/6ae08ae3dea2cfa03dd3665a3c8475c2d429ef47"><code>6ae08ae3dea2</code></a></td></tr>
<tr><td><code>BPF_FUNC_probe_read_user_str()</code></td><td>5.5</td><td>GPL</td><td><a href="https://github.com/torvalds/linux/commit/6ae08ae3dea2cfa03dd3665a3c8475c2d429ef47"><code>6ae08ae3dea2</code></a></td></tr>
<tr><td><code>BPF_FUNC_probe_read_str()</code></td><td>4.11</td><td>GPL</td><td><a href="https://github.com/torvalds/linux/commit/a5e8c07059d0f0b31737408711d44794928ac218"><code>a5e8c07059d0</code></a></td></tr>
<tr><td><code>BPF_FUNC_probe_write_user()</code></td><td>4.8</td><td>GPL</td><td><a href="https://github.com/torvalds/linux/commit/96ae52279594470622ff0585621a13e96b700600"><code>96ae52279594</code></a></td></tr>
<tr><td><code>BPF_FUNC_rc_keydown()</code></td><td>4.18</td><td>GPL</td><td><a href="https://github.com/torvalds/linux/commit/f4364dcfc86df7c1ca47b256eaf6b6d0cdd0d936"><code>f4364dcfc86d</code></a></td></tr>
<tr><td><code>BPF_FUNC_probe_write_user()</code></td><td>4.8</td><td>GPL</td><td><a href="https://github.com/torvalds/linux/commit/96ae52279594470622ff0585621a13e96b700600"><code>96ae52279594</code></a>&quot;<code>BPF_FUNC_rc_keydown()</code></td></tr>
<tr><td><code>BPF_FUNC_rc_pointer_rel()</code></td><td>5.0</td><td>GPL</td><td><a href="https://github.com/torvalds/linux/commit/01d3240a04f4c09392e13c77b54d4423ebce2d72"><code>01d3240a04f4</code></a></td></tr>
<tr><td><code>BPF_FUNC_rc_repeat()</code></td><td>4.18</td><td>GPL</td><td><a href="https://github.com/torvalds/linux/commit/f4364dcfc86df7c1ca47b256eaf6b6d0cdd0d936"><code>f4364dcfc86d</code></a></td></tr>
<tr><td><code>BPF_FUNC_read_branch_records()</code></td><td>5.6</td><td>GPL</td><td><a href="https://github.com/torvalds/linux/commit/fff7b64355eac6e29b50229ad1512315bc04b44e"><code>fff7b64355ea</code></a></td></tr>
@@ -521,8 +548,34 @@ kernel can be retrieved with:</p>
<tr><td><code>BPF_FUNC_set_retval()</code></td><td>5.18</td><td></td><td><a href="https://github.com/torvalds/linux/commit/b44123b4a3dcad4664d3a0f72c011ffd4c9c4d93"><code>b44123b4a3dc</code></a></td></tr>
<tr><td><code>BPF_FUNC_setsockopt()</code></td><td>4.13</td><td></td><td><a href="https://github.com/torvalds/linux/commit/8c4b4c7e9ff0447995750d9329949fa082520269"><code>8c4b4c7e9ff0</code></a></td></tr>
<tr><td><code>BPF_FUNC_sk_ancestor_cgroup_id()</code></td><td>5.7</td><td></td><td><a href="https://github.com/torvalds/linux/commit/f307fa2cb4c935f7f1ff0aeb880c7b44fb9a642b"><code>f307fa2cb4c9</code></a></td></tr>
<tr><td><code>BPF_FUNC_sk_assign()</code></td><td>5.6</td><td></td><td><a href="https://github.com/torvalds/linux/commit/cf7fbe660f2dbd738ab58aea8e9b0ca6ad232449"><code>cf7fbe660f2d</code></a><code>BPF_FUNC_ringbuf_reserve_dynptr()</code></td></tr>
<tr><td><code>BPF_FUNC_ringbuf_submit()</code></td><td>5.8</td><td></td><td><a href="https://github.com/torvalds/linux/commit/457f44363a8894135c85b7a9afd2bd8196db24ab"><code>457f44363a88</code></a></td></tr>
<tr><td><code>BPF_FUNC_ringbuf_submit_dynptr()</code></td><td>5.19</td><td></td><td><a href="https://github.com/torvalds/linux/commit/bc34dee65a65e9c920c420005b8a43f2a721a458"><code>bc34dee65a65</code></a></td></tr>
<tr><td><code>BPF_FUNC_send_signal()</code></td><td>5.3</td><td></td><td><a href="https://github.com/torvalds/linux/commit/8b401f9ed2441ad9e219953927a842d24ed051fc"><code>8b401f9ed244</code></a></td></tr>
<tr><td><code>BPF_FUNC_send_signal_thread()</code></td><td>5.5</td><td></td><td><a href="https://github.com/torvalds/linux/commit/8482941f09067da42f9c3362e15bfb3f3c19d610"><code>8482941f0906</code></a></td></tr>
<tr><td><code>BPF_FUNC_seq_printf()</code></td><td>5.7</td><td>GPL</td><td><a href="https://github.com/torvalds/linux/commit/492e639f0c222784e2e0f121966375f641c61b15"><code>492e639f0c22</code></a></td></tr>
<tr><td><code>BPF_FUNC_seq_printf_btf()</code></td><td>5.10</td><td></td><td><a href="https://github.com/torvalds/linux/commit/eb411377aed9e27835e77ee0710ee8f4649958f3"><code>eb411377aed9</code></a></td></tr>
<tr><td><code>BPF_FUNC_seq_write()</code></td><td>5.7</td><td>GPL</td><td><a href="https://github.com/torvalds/linux/commit/492e639f0c222784e2e0f121966375f641c61b15"><code>492e639f0c22</code></a></td></tr>
<tr><td><code>BPF_FUNC_set_hash()</code></td><td>4.13</td><td></td><td><a href="https://github.com/torvalds/linux/commit/ded092cd73c2c56a394b936f86897f29b2e131c0"><code>ded092cd73c2</code></a></td></tr>
<tr><td><code>BPF_FUNC_set_hash_invalid()</code></td><td>4.9</td><td></td><td><a href="https://github.com/torvalds/linux/commit/7a4b28c6cc9ffac50f791b99cc7e46106436e5d8"><code>7a4b28c6cc9f</code></a></td></tr>
<tr><td><code>BPF_FUNC_set_retval()</code></td><td>5.18</td><td></td><td><a href="https://github.com/torvalds/linux/commit/b44123b4a3dcad4664d3a0f72c011ffd4c9c4d93"><code>b44123b4a3dc</code></a></td></tr>
<tr><td><code>BPF_FUNC_setsockopt()</code></td><td>4.13</td><td></td><td><a href="https://github.com/torvalds/linux/commit/8c4b4c7e9ff0447995750d9329949fa082520269"><code>8c4b4c7e9ff0</code></a></td></tr>
<tr><td><code>BPF_FUNC_sk_ancestor_cgroup_id()</code></td><td>5.7</td><td></td><td><a href="https://github.com/torvalds/linux/commit/f307fa2cb4c935f7f1ff0aeb880c7b44fb9a642b"><code>f307fa2cb4c9</code></a></td></tr>
<tr><td><code>BPF_FUNC_sk_assign()</code></td><td>5.6</td><td></td><td><a href="https://github.com/torvalds/linux/commit/cf7fbe660f2dbd738ab58aea8e9b0ca6ad232449"><code>cf7fbe660f2d</code></a></td></tr>
<tr><td><code>BPF_FUNC_sk_cgroup_id()</code></td><td>5.7</td><td></td><td><a href="https://github.com/torvalds/linux/commit/f307fa2cb4c935f7f1ff0aeb880c7b44fb9a642b"><code>f307fa2cb4c9</code></a></td></tr>
<tr><td><code>BPF_FUNC_ringbuf_reserve_dynptr()</code></td><td>5.19</td><td></td><td><a href="https://github.com/torvalds/linux/commit/bc34dee65a65e9c920c420005b8a43f2a721a458"><code>bc34dee65a65</code></a></td></tr>
<tr><td><code>BPF_FUNC_ringbuf_submit()</code></td><td>5.8</td><td></td><td><a href="https://github.com/torvalds/linux/commit/457f44363a8894135c85b7a9afd2bd8196db24ab"><code>457f44363a88</code></a></td></tr>
<tr><td><code>BPF_FUNC_ringbuf_submit_dynptr()</code></td><td>5.19</td><td></td><td><a href="https://github.com/torvalds/linux/commit/bc34dee65a65e9c920c420005b8a43f2a721a458"><code>bc34dee65a65</code></a></td></tr>
<tr><td><code>BPF_FUNC_send_signal()</code></td><td>5.3</td><td></td><td><a href="https://github.com/torvalds/linux/commit/8b401f9ed2441ad9e219953927a842d24ed051fc"><code>8b401f9ed244</code></a></td></tr>
<tr><td><code>BPF_FUNC_send_signal_thread()</code></td><td>5.5</td><td></td><td><a href="https://github.com/torvalds/linux/commit/8482941f09067da42f9c3362e15bfb3f3c19d610"><code>8482941f0906</code></a></td></tr>
<tr><td><code>BPF_FUNC_seq_printf()</code></td><td>5.7</td><td>GPL</td><td><a href="https://github.com/torvalds/linux/commit/492e639f0c222784e2e0f121966375f641c61b15"><code>492e639f0c22</code></a></td></tr>
<tr><td><code>BPF_FUNC_seq_printf_btf()</code></td><td>5.10</td><td></td><td><a href="https://github.com/torvalds/linux/commit/eb411377aed9e27835e77ee0710ee8f4649958f3"><code>eb411377aed9</code></a></td></tr>
<tr><td><code>BPF_FUNC_seq_write()</code></td><td>5.7</td><td>GPL</td><td><a href="https://github.com/torvalds/linux/commit/492e639f0c222784e2e0f121966375f641c61b15"><code>492e639f0c22</code></a></td></tr>
<tr><td><code>BPF_FUNC_set_hash()</code></td><td>4.13</td><td></td><td><a href="https://github.com/torvalds/linux/commit/ded092cd73c2c56a394b936f86897f29b2e131c0"><code>ded092cd73c2</code></a></td></tr>
<tr><td><code>BPF_FUNC_set_hash_invalid()</code></td><td>4.9</td><td></td><td><a href="https://github.com/torvalds/linux/commit/7a4b28c6cc9ffac50f791b99cc7e46106436e5d8"><code>7a4b28c6cc9f</code></a></td></tr>
<tr><td><code>BPF_FUNC_set_retval()</code></td><td>5.18</td><td></td><td><a href="https://github.com/torvalds/linux/commit/b44123b4a3dcad4664d3a0f72c011ffd4c9c4d93"><code>b44123b4a3dc</code></a></td></tr>
<tr><td><code>BPF_FUNC_setsockopt()</code></td><td>4.13</td><td></td><td><a href="https://github.com/torvalds/linux/commit/8c4b4c7e9ff0447995750d9329949fa082520269"><code>8c4b4c7e9ff0</code></a></td></tr>
<tr><td><code>BPF_FUNC_sk_ancestor_cgroup_id()</code></td><td>5.7</td><td></td><td><a href="https://github.com/torvalds/linux/commit/f307fa2cb4c935f7f1ff0aeb880c7b44fb9a642b"><code>f307fa2cb4c9</code></a></td></tr>
<tr><td><code>BPF_FUNC_sk_assign()</code></td><td>5.6</td><td></td><td><a href="https://github.com/torvalds/linux/commit/cf7fbe660f2dbd738ab58aea8e9b0ca6ad232449"><code>cf7fbe660f2d</code></a>&quot;.&quot;<code>BPF_FUNC_sk_cgroup_id()</code></td></tr>
<tr><td><code>BPF_FUNC_sk_fullsock()</code></td><td>5.1</td><td></td><td><a href="https://github.com/torvalds/linux/commit/46f8bc92758c6259bcf945e9216098661c1587cd"><code>46f8bc92758c</code></a></td></tr>
<tr><td><code>BPF_FUNC_sk_lookup_tcp()</code></td><td>4.20</td><td></td><td><a href="https://github.com/torvalds/linux/commit/6acc9b432e6714d72d7d77ec7c27f6f8358d0c71"><code>6acc9b432e67</code></a></td></tr>
<tr><td><code>BPF_FUNC_sk_lookup_udp()</code></td><td>4.20</td><td></td><td><a href="https://github.com/torvalds/linux/commit/6acc9b432e6714d72d7d77ec7c27f6f8358d0c71"><code>6acc9b432e67</code></a></td></tr>
@@ -536,7 +589,20 @@ kernel can be retrieved with:</p>
<tr><td><code>BPF_FUNC_skb_ancestor_cgroup_id()</code></td><td>4.19</td><td></td><td><a href="https://github.com/torvalds/linux/commit/7723628101aaeb1d723786747529b4ea65c5b5c5"><code>7723628101aa</code></a></td></tr>
<tr><td><code>BPF_FUNC_skb_change_head()</code></td><td>4.10</td><td></td><td><a href="https://github.com/torvalds/linux/commit/3a0af8fd61f90920f6fa04e4f1e9a6a73c1b4fd2"><code>3a0af8fd61f9</code></a></td></tr>
<tr><td><code>BPF_FUNC_skb_change_proto()</code></td><td>4.8</td><td></td><td><a href="https://github.com/torvalds/linux/commit/6578171a7ff0c31dc73258f93da7407510abf085"><code>6578171a7ff0</code></a></td></tr>
<tr><td><code>BPF_FUNC_skb_change_tail()</code></td><td>4.9</td><td></td><td><a href="https://github.com/torvalds/linux/commit/5293efe62df81908f2e90c9820c7edcc8e61f5e9"><code>5293efe62df8</code></a></td></tr>
<tr><td><code>BPF_FUNC_sk_cgroup_id()</code></td><td>5.7</td><td></td><td><a href="https://github.com/torvalds/linux/commit/f307fa2cb4c935f7f1ff0aeb880c7b44fb9a642b"><code>f307fa2cb4c9</code></a></td></tr>
<tr><td><code>BPF_FUNC_sk_fullsock()</code></td><td>5.1</td><td></td><td><a href="https://github.com/torvalds/linux/commit/46f8bc92758c6259bcf945e9216098661c1587cd"><code>46f8bc92758c</code></a></td></tr>
<tr><td><code>BPF_FUNC_sk_lookup_tcp()</code></td><td>4.20</td><td></td><td><a href="https://github.com/torvalds/linux/commit/6acc9b432e6714d72d7d77ec7c27f6f8358d0c71"><code>6acc9b432e67</code></a></td></tr>
<tr><td><code>BPF_FUNC_sk_lookup_udp()</code></td><td>4.20</td><td></td><td><a href="https://github.com/torvalds/linux/commit/6acc9b432e6714d72d7d77ec7c27f6f8358d0c71"><code>6acc9b432e67</code></a></td></tr>
<tr><td><code>BPF_FUNC_sk_redirect_hash()</code></td><td>4.18</td><td></td><td><a href="https://github.com/torvalds/linux/commit/81110384441a59cff47430f20f049e69b98c17f4"><code>81110384441a</code></a></td></tr>
<tr><td><code>BPF_FUNC_sk_redirect_map()</code></td><td>4.14</td><td></td><td><a href="https://github.com/torvalds/linux/commit/174a79ff9515f400b9a6115643dafd62a635b7e6"><code>174a79ff9515</code></a></td></tr>
<tr><td><code>BPF_FUNC_sk_release()</code></td><td>4.20</td><td></td><td><a href="https://github.com/torvalds/linux/commit/6acc9b432e6714d72d7d77ec7c27f6f8358d0c71"><code>6acc9b432e67</code></a></td></tr>
<tr><td><code>BPF_FUNC_sk_select_reuseport()</code></td><td>4.19</td><td></td><td><a href="https://github.com/torvalds/linux/commit/2dbb9b9e6df67d444fbe425c7f6014858d337adf"><code>2dbb9b9e6df6</code></a></td></tr>
<tr><td><code>BPF_FUNC_sk_storage_delete()</code></td><td>5.2</td><td></td><td><a href="https://github.com/torvalds/linux/commit/6ac99e8f23d4b10258406ca0dd7bffca5f31da9d"><code>6ac99e8f23d4</code></a></td></tr>
<tr><td><code>BPF_FUNC_sk_storage_get()</code></td><td>5.2</td><td></td><td><a href="https://github.com/torvalds/linux/commit/6ac99e8f23d4b10258406ca0dd7bffca5f31da9d"><code>6ac99e8f23d4</code></a></td></tr>
<tr><td><code>BPF_FUNC_skb_adjust_room()</code></td><td>4.13</td><td></td><td><a href="https://github.com/torvalds/linux/commit/2be7e212d5419a400d051c84ca9fdd083e5aacac"><code>2be7e212d541</code></a></td></tr>
<tr><td><code>BPF_FUNC_skb_ancestor_cgroup_id()</code></td><td>4.19</td><td></td><td><a href="https://github.com/torvalds/linux/commit/7723628101aaeb1d723786747529b4ea65c5b5c5"><code>7723628101aa</code></a></td></tr>
<tr><td><code>BPF_FUNC_skb_change_head()</code></td><td>4.10</td><td></td><td><a href="https://github.com/torvalds/linux/commit/3a0af8fd61f90920f6fa04e4f1e9a6a73c1b4fd2"><code>3a0af8fd61f9</code></a></td></tr>
<tr><td><code>BPF_FUNC_skb_change_proto()</code></td><td>4.8</td><td></td><td><a href="https://github.com/torvalds/linux/commit/6578171a7ff0c31dc73258f93da7407510abf085"><code>6578171a7ff0</code></a><code>&quot;</code>BPF_FUNC_skb_change_tail()`</td></tr>
<tr><td><code>BPF_FUNC_skb_change_type()</code></td><td>4.8</td><td></td><td><a href="https://github.com/torvalds/linux/commit/d2485c4242a826fdf493fd3a27b8b792965b9b9e"><code>d2485c4242a8</code></a></td></tr>
<tr><td><code>BPF_FUNC_skb_cgroup_classid()</code></td><td>5.10</td><td></td><td><a href="https://github.com/torvalds/linux/commit/b426ce83baa7dff947fb354118d3133f2953aac8"><code>b426ce83baa7</code></a></td></tr>
<tr><td><code>BPF_FUNC_skb_cgroup_id()</code></td><td>4.18</td><td></td><td><a href="https://github.com/torvalds/linux/commit/cb20b08ead401fd17627a36f035c0bf5bfee5567"><code>cb20b08ead40</code></a></td></tr>
@@ -563,8 +629,7 @@ kernel can be retrieved with:</p>
<tr><td><code>BPF_FUNC_skc_to_tcp6_sock()</code></td><td>5.9</td><td></td><td><a href="https://github.com/torvalds/linux/commit/af7ec13833619e17f03aa73a785a2f871da6d66b"><code>af7ec1383361</code></a></td></tr>
<tr><td><code>BPF_FUNC_skc_to_udp6_sock()</code></td><td>5.9</td><td></td><td><a href="https://github.com/torvalds/linux/commit/0d4fad3e57df2bf61e8ffc8d12a34b1caf9b8835"><code>0d4fad3e57df</code></a></td></tr>
<tr><td><code>BPF_FUNC_skc_to_unix_sock()</code></td><td>5.16</td><td></td><td><a href="https://github.com/torvalds/linux/commit/9eeb3aa33ae005526f672b394c1791578463513f"><code>9eeb3aa33ae0</code></a></td></tr>
<tr><td><code>BPF_FUNC_snprintf()</code></td><td>5.13</td><td></td><td><a href="https://github.com/torvalds/linux/commit/7b15523a989b63927c2bb08e9b5b0bbc10b58bef"><code>7b15523a989b</code></a></td></tr>
<tr><td><code>BPF_FUNC_snprintf_btf()</code></td><td>5.10</td><td></td><td><a href="https://github.com/torvalds/linux/commit/c4d0bfb45068d853a478b9067a95969b1886a30f"><code>c4d0bfb45068</code></a></td></tr>
<tr><td><code>BPF_FUNC_snprintf()</code></td><td>5.13</td><td></td><td><a href="https://github.com/torvalds/linux/commit/7b15523a989b63927c2bb08e9b5b0bbc10b58bef"><code>7b15523a989b</code></a>&quot;.&quot;<code>BPF_FUNC_snprintf_btf()</code></td></tr>
<tr><td><code>BPF_FUNC_sock_from_file()</code></td><td>5.11</td><td></td><td><a href="https://github.com/torvalds/linux/commit/4f19cab76136e800a3f04d8c9aa4d8e770e3d3d8"><code>4f19cab76136</code></a></td></tr>
<tr><td><code>BPF_FUNC_sock_hash_update()</code></td><td>4.18</td><td></td><td><a href="https://github.com/torvalds/linux/commit/81110384441a59cff47430f20f049e69b98c17f4"><code>81110384441a</code></a></td></tr>
<tr><td><code>BPF_FUNC_sock_map_update()</code></td><td>4.14</td><td></td><td><a href="https://github.com/torvalds/linux/commit/174a79ff9515f400b9a6115643dafd62a635b7e6"><code>174a79ff9515</code></a></td></tr>
@@ -577,21 +642,20 @@ kernel can be retrieved with:</p>
<tr><td><code>BPF_FUNC_sys_bpf()</code></td><td>5.14</td><td></td><td><a href="https://github.com/torvalds/linux/commit/79a7f8bdb159d9914b58740f3d31d602a6e4aca8"><code>79a7f8bdb159</code></a></td></tr>
<tr><td><code>BPF_FUNC_sys_close()</code></td><td>5.14</td><td></td><td><a href="https://github.com/torvalds/linux/commit/3abea089246f76c1517b054ddb5946f3f1dbd2c0"><code>3abea089246f</code></a></td></tr>
<tr><td><code>BPF_FUNC_sysctl_get_current_value()</code></td><td>5.2</td><td></td><td><a href="https://github.com/torvalds/linux/commit/1d11b3016cec4ed9770b98e82a61708c8f4926e7"><code>1d11b3016cec</code></a></td></tr>
<tr><td><code>BPF_FUNC_sysctl_get_name()</code></td><td>5.2</td><td></td><td><a href="https://github.com/torvalds/linux/commit/808649fb787d918a48a360a668ee4ee9023f0c11"><code>808649fb787d</code></a></td></tr>
<tr><td><code>BPF_FUNC_sysctl_get_new_value()</code></td><td>5.2</td><td></td><td><a href="https://github.com/torvalds/linux/commit/4e63acdff864654cee0ac5aaeda3913798ee78f6"><code>4e63acdff864</code></a></td></tr>
<tr><td><code>BPF_FUNC_sysctl_set_new_value()</code></td><td>5.2</td><td></td><td><a href="https://github.com/torvalds/linux/commit/4e63acdff864654cee0ac5aaeda3913798ee78f6"><code>4e63acdff864</code></a></td></tr>
<tr><td><code>BPF_FUNC_tail_call()</code></td><td>4.2</td><td></td><td><a href="https://github.com/torvalds/linux/commit/04fd61ab36ec065e194ab5e74ae34a5240d992bb"><code>04fd61ab36ec</code></a></td></tr>
<tr><td><code>BPF_FUNC_task_pt_regs()</code></td><td>5.15</td><td>GPL</td><td><a href="https://github.com/torvalds/linux/commit/dd6e10fbd9fb86a571d925602c8a24bb4d09a2a7"><code>dd6e10fbd9f</code></a></td></tr>
<tr><td><code>BPF_FUNC_task_storage_delete()</code></td><td>5.11</td><td></td><td><a href="https://github.com/torvalds/linux/commit/4cf1bc1f10452065a29d576fc5693fc4fab5b919"><code>4cf1bc1f1045</code></a></td></tr>
<tr><td><code>BPF_FUNC_task_storage_get()</code></td><td>5.11</td><td></td><td><a href="https://github.com/torvalds/linux/commit/4cf1bc1f10452065a29d576fc5693fc4fab5b919"><code>4cf1bc1f1045</code></a></td></tr>
<tr><td><code>BPF_FUNC_tcp_check_syncookie()</code></td><td>5.2</td><td></td><td><a href="https://github.com/torvalds/linux/commit/399040847084a69f345e0a52fd62f04654e0fce3"><code>399040847084</code></a></td></tr>
<tr><td><code>BPF_FUNC_tcp_gen_syncookie()</code></td><td>5.3</td><td></td><td><a href="https://github.com/torvalds/linux/commit/70d66244317e958092e9c971b08dd5b7fd29d9cb#diff-05da4bf36c7fbcd176254e1615d98b28"><code>70d66244317e</code></a></td></tr>
<tr><td><code>BPF_FUNC_tcp_raw_check_syncookie_ipv4()</code></td><td>6.0</td><td></td><td><a href="https://github.com/torvalds/linux/commit/33bf9885040c399cf6a95bd33216644126728e14"><code>33bf9885040c</code></a></td></tr>
<tr><td><code>BPF_FUNC_tcp_raw_check_syncookie_ipv6()</code></td><td>6.0</td><td></td><td><a href="https://github.com/torvalds/linux/commit/33bf9885040c399cf6a95bd33216644126728e14"><code>33bf9885040c</code></a></td></tr>
<tr><td><code>BPF_FUNC_tcp_raw_gen_syncookie_ipv4()</code></td><td>6.0</td><td></td><td><a href="https://github.com/torvalds/linux/commit/33bf9885040c399cf6a95bd33216644126728e14"><code>33bf9885040c</code></a></td></tr>
<tr><td><code>BPF_FUNC_tcp_raw_gen_syncookie_ipv6()</code></td><td>6.0</td><td></td><td><a href="https://github.com/torvalds/linux/commit/33bf9885040c399cf6a95bd33216644126728e14"><code>33bf9885040c</code></a></td></tr>
<tr><td><code>BPF_FUNC_tcp_send_ack()</code></td><td>5.5</td><td></td><td><a href="https://github.com/torvalds/linux/commit/206057fe020ac5c037d5e2dd6562a9bd216ec765"><code>206057fe020a</code></a></td></tr>
<tr><td><code>BPF_FUNC_tcp_sock()</code></td><td>5.1</td><td></td><td><a href="https://github.com/torvalds/linux/commit/655a51e536c09d15ffa3603b1b6fce2b45b85a1f"><code>655a51e536c0</code></a></td></tr>
<tr><td><code>BPF_FUNC_sysctl_get_name()</code></td><td>5.2</td><td></td><td><a href="https://github.com/torvalds/linux/commit/808649fb787d918a48a360a668ee4ee9023f0c11"><code>808649fb787d</code></a>&quot;.</td></tr>
<tr><td>格式:只返回翻译后的内容,不包括原文。<code>BPF_FUNC_sysctl_get_new_value()</code>| 5.2| | <a href="https://github.com/torvalds/linux/commit/4e63acdff864654cee0ac5aaeda3913798ee78f6"><code>4e63acdff864</code></a></td><td></td><td></td><td></td></tr>
<tr><td><code>BPF_FUNC_sysctl_set_new_value()</code>|5.2| | <a href="https://github.com/torvalds/linux/commit/4e63acdff864654cee0ac5aaeda3913798ee78f6"><code>4e63acdff864</code></a></td><td></td><td></td><td></td></tr>
<tr><td><code>BPF_FUNC_tail_call()</code>|4.2| | <a href="https://github.com/torvalds/linux/commit/04fd61ab36ec065e194ab5e74ae34a5240d992bb"><code>04fd61ab36ec</code></a></td><td></td><td></td><td></td></tr>
<tr><td><code>BPF_FUNC_task_pt_regs()</code>|5.15| GPL | <a href="https://github.com/torvalds/linux/commit/dd6e10fbd9fb86a571d925602c8a24bb4d09a2a7"><code>dd6e10fbd9f</code></a></td><td></td><td></td><td></td></tr>
<tr><td><code>BPF_FUNC_task_storage_delete()</code>|5.11| | <a href="https://github.com/torvalds/linux/commit/4cf1bc1f10452065a29d576fc5693fc4fab5b919"><code>4cf1bc1f1045</code></a></td><td></td><td></td><td></td></tr>
<tr><td><code>BPF_FUNC_task_storage_get()</code>|5.11| | <a href="https://github.com/torvalds/linux/commit/4cf1bc1f10452065a29d576fc5693fc4fab5b919"><code>4cf1bc1f1045</code></a></td><td></td><td></td><td></td></tr>
<tr><td><code>BPF_FUNC_tcp_check_syncookie()</code>|5.2| | <a href="https://github.com/torvalds/linux/commit/399040847084a69f345e0a52fd62f04654e0fce3"><code>399040847084</code></a></td><td></td><td></td><td></td></tr>
<tr><td><code>BPF_FUNC_tcp_gen_syncookie()</code>|5.3| | <a href="https://github.com/torvalds/linux/commit/70d66244317e958092e9c971b08dd5b7fd29d9cb#diff-05da4bf36c7fbcd176254e1615d98b28"><code>70d66244317e</code></a></td><td></td><td></td><td></td></tr>
<tr><td><code>BPF_FUNC_tcp_raw_check_syncookie_ipv4()</code>|6.0| | <a href="https://github.com/torvalds/linux/commit/33bf9885040c399cf6a95bd33216644126728e14"><code>33bf9885040c</code></a></td><td></td><td></td><td></td></tr>
<tr><td><code>BPF_FUNC_tcp_raw_check_syncookie_ipv6()</code>|6.0| | <a href="https://github.com/torvalds/linux/commit/33bf9885040c399cf6a95bd33216644126728e14"><code>33bf9885040c</code></a></td><td></td><td></td><td></td></tr>
<tr><td><code>BPF_FUNC_tcp_raw_gen_syncookie_ipv4()</code>|6.0| | <a href="https://github.com/torvalds/linux/commit/33bf9885040c399cf6a95bd33216644126728e14"><code>33bf9885040c</code></a></td><td></td><td></td><td></td></tr>
<tr><td><code>BPF_FUNC_tcp_raw_gen_syncookie_ipv6()</code>|6.0| | <a href="https://github.com/torvalds/linux/commit/33bf9885040c399cf6a95bd33216644126728e14"><code>33bf9885040c</code></a></td><td></td><td></td><td></td></tr>
<tr><td><code>BPF_FUNC_tcp_send_ack()</code>|5.5 | | <a href="https://github.com/torvalds/linux/commit/206057fe020ac5c037d5e2dd6562a9bd216ec765"><code>206057fe020a</code></a><code>BPF_FUNC_tcp_sock()</code></td><td>5.1</td><td></td><td><a href="https://github.com/torvalds/linux/commit/655a51e536c09d15ffa3603b1b6fce2b45b85a1f"><code>655a51e536c0</code></a></td></tr>
<tr><td><code>BPF_FUNC_this_cpu_ptr()</code></td><td>5.10</td><td></td><td><a href="https://github.com/torvalds/linux/commit/63d9b80dcf2c67bc5ade61cbbaa09d7af21f43f1"><code>63d9b80dcf2c</code></a></td></tr>
<tr><td><code>BPF_FUNC_timer_init()</code></td><td>5.15</td><td></td><td><a href="https://github.com/torvalds/linux/commit/b00628b1c7d595ae5b544e059c27b1f5828314b4"><code>b00628b1c7d5</code></a></td></tr>
<tr><td><code>BPF_FUNC_timer_set_callback()</code></td><td>5.15</td><td></td><td><a href="https://github.com/torvalds/linux/commit/b00628b1c7d595ae5b544e059c27b1f5828314b4"><code>b00628b1c7d5</code></a></td></tr>
@@ -604,54 +668,49 @@ kernel can be retrieved with:</p>
<tr><td><code>BPF_FUNC_xdp_adjust_meta()</code></td><td>4.15</td><td></td><td><a href="https://github.com/torvalds/linux/commit/de8f3a83b0a0fddb2cf56e7a718127e9619ea3da"><code>de8f3a83b0a0</code></a></td></tr>
<tr><td><code>BPF_FUNC_xdp_adjust_tail()</code></td><td>4.18</td><td></td><td><a href="https://github.com/torvalds/linux/commit/b32cc5b9a346319c171e3ad905e0cddda032b5eb"><code>b32cc5b9a346</code></a></td></tr>
<tr><td><code>BPF_FUNC_xdp_get_buff_len()</code></td><td>5.18</td><td></td><td><a href="https://github.com/torvalds/linux/commit/0165cc817075cf701e4289838f1d925ff1911b3e"><code>0165cc817075</code></a></td></tr>
<tr><td><code>BPF_FUNC_xdp_load_bytes()</code></td><td>5.18</td><td></td><td><a href="https://github.com/torvalds/linux/commit/3f364222d032eea6b245780e845ad213dab28cdd"><code>3f364222d032</code></a></td></tr>
<tr><td><code>BPF_FUNC_xdp_store_bytes()</code></td><td>5.18</td><td></td><td><a href="https://github.com/torvalds/linux/commit/3f364222d032eea6b245780e845ad213dab28cdd"><code>3f364222d032</code></a></td></tr>
<tr><td><code>BPF_FUNC_xdp_load_bytes()</code></td><td>5.18</td><td></td><td><a href="https://github.com/torvalds/linux/commit/3f364222d032eea6b245780e845ad213dab28cdd"><code>3f364222d032</code></a>&quot;<code>BPF_FUNC_xdp_store_bytes()</code></td></tr>
<tr><td><code>BPF_FUNC_xdp_output()</code></td><td>5.6</td><td>GPL</td><td><a href="https://github.com/torvalds/linux/commit/d831ee84bfc9173eecf30dbbc2553ae81b996c60"><code>d831ee84bfc9</code></a></td></tr>
<tr><td><code>BPF_FUNC_override_return()</code></td><td>4.16</td><td>GPL</td><td><a href="https://github.com/torvalds/linux/commit/9802d86585db91655c7d1929a4f6bbe0952ea88e"><code>9802d86585db</code></a></td></tr>
<tr><td><code>BPF_FUNC_sock_ops_cb_flags_set()</code></td><td>4.16</td><td></td><td><a href="https://github.com/torvalds/linux/commit/b13d880721729384757f235166068c315326f4a1"><code>b13d88072172</code></a></td></tr>
</tbody></table>
</div>
<p>Note: GPL-only BPF helpers require a GPL-compatible license. The current licenses considered GPL-compatible by the kernel are:</p>
<p>仅GPL兼容的BPF助手需要GPL兼容的许可证。内核所认可的当前GPL兼容许可证有</p>
<ul>
<li>GPL</li>
<li>GPL v2</li>
<li>GPL and additional rights</li>
<li>Dual BSD/GPL</li>
<li>Dual MIT/GPL</li>
<li>Dual MPL/GPL</li>
<li>GPL和其他权利</li>
<li>BSD/GPL</li>
<li>MIT/GPL</li>
<li>MPL/GPL</li>
</ul>
<p>Check the list of GPL-compatible licenses in your <a href="https://github.com/torvalds/linux/blob/master/include/linux/license.h">kernel source code</a>.</p>
<h2 id="program-types-1"><a class="header" href="#program-types-1">Program Types</a></h2>
<p>The list of program types and supported helper functions can be retrieved with:</p>
<p>在您的<a href="https://github.com/torvalds/linux/blob/master/include/linux/license.h">内核源代码</a>中查看GPL兼容许可证的列表。</p>
<h2 id="程序类型-1"><a class="header" href="#程序类型-1">程序类型</a></h2>
<p>可以使用以下命令获取程序类型和支持的辅助函数列表:</p>
<pre><code class="language-sh">git grep -W 'func_proto(enum bpf_func_id func_id' kernel/ net/ drivers/
</code></pre>
<div class="table-wrapper"><table><thead><tr><th>Program Type</th><th>Helper Functions</th></tr></thead><tbody>
<tr><td><code>BPF_PROG_TYPE_SOCKET_FILTER</code></td><td><code>BPF_FUNC_skb_load_bytes()</code> <br> <code>BPF_FUNC_skb_load_bytes_relative()</code> <br> <code>BPF_FUNC_get_socket_cookie()</code> <br> <code>BPF_FUNC_get_socket_uid()</code> <br> <code>BPF_FUNC_perf_event_output()</code> <br> <code>Base functions</code></td></tr>
<tr><td><code>BPF_PROG_TYPE_KPROBE</code></td><td><code>BPF_FUNC_perf_event_output()</code> <br> <code>BPF_FUNC_get_stackid()</code> <br> <code>BPF_FUNC_get_stack()</code> <br> <code>BPF_FUNC_perf_event_read_value()</code> <br> <code>BPF_FUNC_override_return()</code> <br> <code>Tracing functions</code></td></tr>
<tr><td><code>BPF_PROG_TYPE_SCHED_CLS</code> <br> <code>BPF_PROG_TYPE_SCHED_ACT</code></td><td><code>BPF_FUNC_skb_store_bytes()</code> <br> <code>BPF_FUNC_skb_load_bytes()</code> <br> <code>BPF_FUNC_skb_load_bytes_relative()</code> <br> <code>BPF_FUNC_skb_pull_data()</code> <br> <code>BPF_FUNC_csum_diff()</code> <br> <code>BPF_FUNC_csum_update()</code> <br> <code>BPF_FUNC_l3_csum_replace()</code> <br> <code>BPF_FUNC_l4_csum_replace()</code> <br> <code>BPF_FUNC_clone_redirect()</code> <br> <code>BPF_FUNC_get_cgroup_classid()</code> <br> <code>BPF_FUNC_skb_vlan_push()</code> <br> <code>BPF_FUNC_skb_vlan_pop()</code> <br> <code>BPF_FUNC_skb_change_proto()</code> <br> <code>BPF_FUNC_skb_change_type()</code> <br> <code>BPF_FUNC_skb_adjust_room()</code> <br> <code>BPF_FUNC_skb_change_tail()</code> <br> <code>BPF_FUNC_skb_get_tunnel_key()</code> <br> <code>BPF_FUNC_skb_set_tunnel_key()</code> <br> <code>BPF_FUNC_skb_get_tunnel_opt()</code> <br> <code>BPF_FUNC_skb_set_tunnel_opt()</code> <br> <code>BPF_FUNC_redirect()</code> <br> <code>BPF_FUNC_get_route_realm()</code> <br> <code>BPF_FUNC_get_hash_recalc()</code> <br> <code>BPF_FUNC_set_hash_invalid()</code> <br> <code>BPF_FUNC_set_hash()</code> <br> <code>BPF_FUNC_perf_event_output()</code> <br> <code>BPF_FUNC_get_smp_processor_id()</code> <br> <code>BPF_FUNC_skb_under_cgroup()</code> <br> <code>BPF_FUNC_get_socket_cookie()</code> <br> <code>BPF_FUNC_get_socket_uid()</code> <br> <code>BPF_FUNC_fib_lookup()</code> <br> <code>BPF_FUNC_skb_get_xfrm_state()</code> <br> <code>BPF_FUNC_skb_cgroup_id()</code> <br> <code>Base functions</code></td></tr>
<tr><td><code>BPF_PROG_TYPE_TRACEPOINT</code></td><td><code>BPF_FUNC_perf_event_output()</code> <br> <code>BPF_FUNC_get_stackid()</code> <br> <code>BPF_FUNC_get_stack()</code> <br> <code>BPF_FUNC_d_path()</code> <br> <code>Tracing functions</code></td></tr>
<tr><td><code>BPF_PROG_TYPE_XDP</code></td><td><code>BPF_FUNC_perf_event_output()</code> <br> <code>BPF_FUNC_get_smp_processor_id()</code> <br> <code>BPF_FUNC_csum_diff()</code> <br> <code>BPF_FUNC_xdp_adjust_head()</code> <br> <code>BPF_FUNC_xdp_adjust_meta()</code> <br> <code>BPF_FUNC_redirect()</code> <br> <code>BPF_FUNC_redirect_map()</code> <br> <code>BPF_FUNC_xdp_adjust_tail()</code> <br> <code>BPF_FUNC_fib_lookup()</code> <br> <code>Base functions</code></td></tr>
<tr><td><code>BPF_PROG_TYPE_PERF_EVENT</code></td><td><code>BPF_FUNC_perf_event_output()</code> <br> <code>BPF_FUNC_get_stackid()</code> <br> <code>BPF_FUNC_get_stack()</code> <br> <code>BPF_FUNC_perf_prog_read_value()</code> <br> <code>Tracing functions</code></td></tr>
<tr><td><code>BPF_PROG_TYPE_CGROUP_SKB</code></td><td><code>BPF_FUNC_skb_load_bytes()</code> <br> <code>BPF_FUNC_skb_load_bytes_relative()</code> <br> <code>BPF_FUNC_get_socket_cookie()</code> <br> <code>BPF_FUNC_get_socket_uid()</code> <br> <code>Base functions</code></td></tr>
<tr><td><code>BPF_PROG_TYPE_CGROUP_SOCK</code></td><td><code>BPF_FUNC_get_current_uid_gid()</code> <br> <code>Base functions</code></td></tr>
<tr><td><code>BPF_PROG_TYPE_LWT_IN</code></td><td><code>BPF_FUNC_lwt_push_encap()</code> <br> <code>LWT functions</code> <br> <code>Base functions</code></td></tr>
<tr><td><code>BPF_PROG_TYPE_LWT_OUT</code></td><td><code>LWT functions</code> <br> <code>Base functions</code></td></tr>
<tr><td><code>BPF_PROG_TYPE_LWT_XMIT</code></td><td><code>BPF_FUNC_skb_get_tunnel_key()</code> <br> <code>BPF_FUNC_skb_set_tunnel_key()</code> <br> <code>BPF_FUNC_skb_get_tunnel_opt()</code> <br> <code>BPF_FUNC_skb_set_tunnel_opt()</code> <br> <code>BPF_FUNC_redirect()</code> <br> <code>BPF_FUNC_clone_redirect()</code> <br> <code>BPF_FUNC_skb_change_tail()</code> <br> <code>BPF_FUNC_skb_change_head()</code> <br> <code>BPF_FUNC_skb_store_bytes()</code> <br> <code>BPF_FUNC_csum_update()</code> <br> <code>BPF_FUNC_l3_csum_replace()</code> <br> <code>BPF_FUNC_l4_csum_replace()</code> <br> <code>BPF_FUNC_set_hash_invalid()</code> <br> <code>LWT functions</code></td></tr>
<tr><td><code>BPF_PROG_TYPE_SOCK_OPS</code></td><td><code>BPF_FUNC_setsockopt()</code> <br> <code>BPF_FUNC_getsockopt()</code> <br> <code>BPF_FUNC_sock_ops_cb_flags_set()</code> <br> <code>BPF_FUNC_sock_map_update()</code> <br> <code>BPF_FUNC_sock_hash_update()</code> <br> <code>BPF_FUNC_get_socket_cookie()</code> <br> <code>Base functions</code></td></tr>
<tr><td><code>BPF_PROG_TYPE_SK_SKB</code></td><td><code>BPF_FUNC_skb_store_bytes()</code> <br> <code>BPF_FUNC_skb_load_bytes()</code> <br> <code>BPF_FUNC_skb_pull_data()</code> <br> <code>BPF_FUNC_skb_change_tail()</code> <br> <code>BPF_FUNC_skb_change_head()</code> <br> <code>BPF_FUNC_get_socket_cookie()</code> <br> <code>BPF_FUNC_get_socket_uid()</code> <br> <code>BPF_FUNC_sk_redirect_map()</code> <br> <code>BPF_FUNC_sk_redirect_hash()</code> <br> <code>BPF_FUNC_sk_lookup_tcp()</code> <br> <code>BPF_FUNC_sk_lookup_udp()</code> <br> <code>BPF_FUNC_sk_release()</code> <br> <code>Base functions</code></td></tr>
<tr><td><code>BPF_PROG_TYPE_CGROUP_DEVICE</code></td><td><code>BPF_FUNC_map_lookup_elem()</code> <br> <code>BPF_FUNC_map_update_elem()</code> <br> <code>BPF_FUNC_map_delete_elem()</code> <br> <code>BPF_FUNC_get_current_uid_gid()</code> <br> <code>BPF_FUNC_trace_printk()</code></td></tr>
<tr><td><code>BPF_PROG_TYPE_SK_MSG</code></td><td><code>BPF_FUNC_msg_redirect_map()</code> <br> <code>BPF_FUNC_msg_redirect_hash()</code> <br> <code>BPF_FUNC_msg_apply_bytes()</code> <br> <code>BPF_FUNC_msg_cork_bytes()</code> <br> <code>BPF_FUNC_msg_pull_data()</code> <br> <code>BPF_FUNC_msg_push_data()</code> <br> <code>BPF_FUNC_msg_pop_data()</code> <br> <code>Base functions</code></td></tr>
<tr><td><code>BPF_PROG_TYPE_RAW_TRACEPOINT</code></td><td><code>BPF_FUNC_perf_event_output()</code> <br> <code>BPF_FUNC_get_stackid()</code> <br> <code>BPF_FUNC_get_stack()</code> <br> <code>BPF_FUNC_skb_output()</code> <br> <code>Tracing functions</code></td></tr>
<tr><td><code>BPF_PROG_TYPE_CGROUP_SOCK_ADDR</code></td><td><code>BPF_FUNC_get_current_uid_gid()</code> <br> <code>BPF_FUNC_bind()</code> <br> <code>BPF_FUNC_get_socket_cookie()</code> <br> <code>Base functions</code></td></tr>
<tr><td><code>BPF_PROG_TYPE_LWT_SEG6LOCAL</code></td><td><code>BPF_FUNC_lwt_seg6_store_bytes()</code> <br> <code>BPF_FUNC_lwt_seg6_action()</code> <br> <code>BPF_FUNC_lwt_seg6_adjust_srh()</code> <br> <code>LWT functions</code></td></tr>
<div class="table-wrapper"><table><thead><tr><th>程序类型</th><th>辅助函数</th></tr></thead><tbody>
<tr><td><code>BPF_PROG_TYPE_SOCKET_FILTER</code></td><td><code>BPF_FUNC_skb_load_bytes()</code> <br> <code>BPF_FUNC_skb_load_bytes_relative()</code> <br> <code>BPF_FUNC_get_socket_cookie()</code> <br> <code>BPF_FUNC_get_socket_uid()</code> <br> <code>BPF_FUNC_perf_event_output()</code> <br> <code>基础函数</code></td></tr>
<tr><td><code>BPF_PROG_TYPE_KPROBE</code></td><td><code>BPF_FUNC_perf_event_output()</code> <br> <code>BPF_FUNC_get_stackid()</code> <br> <code>BPF_FUNC_get_stack()</code> <br> <code>BPF_FUNC_perf_event_read_value()</code> <br> <code>BPF_FUNC_override_return()</code> <br> <code>跟踪函数</code></td></tr>
<tr><td><code>BPF_PROG_TYPE_TRACEPOINT</code></td><td><code>BPF_FUNC_perf_event_output()</code> <br> <code>BPF_FUNC_get_stackid()</code> <br> <code>BPF_FUNC_get_stack()</code> <br> <code>BPF_FUNC_d_path()</code> <br> <code>跟踪函数</code></td></tr>
<tr><td><code>BPF_PROG_TYPE_XDP</code></td><td><code>BPF_FUNC_perf_event_output()</code> <br> <code>BPF_FUNC_get_smp_processor_id()</code> <br> <code>BPF_FUNC_csum_diff()</code> <br> <code>BPF_FUNC_xdp_adjust_head()</code> <br> <code>BPF_FUNC_xdp_adjust_meta()</code> <br> <code>BPF_FUNC_redirect()</code> <br> <code>BPF_FUNC_redirect_map()</code> <br> <code>BPF_FUNC_xdp_adjust_tail()</code> <br> <code>BPF_FUNC_fib_lookup()</code> <br> <code>基础函数</code></td></tr>
<tr><td><code>BPF_PROG_TYPE_PERF_EVENT</code></td><td><code>BPF_FUNC_perf_event_output()</code> <br> <code>BPF_FUNC_get_stackid()</code> <br> <code>BPF_FUNC_get_stack()</code> <br> <code>BPF_FUNC_perf_prog_read_value()</code> <br> <code>跟踪函数</code></td></tr>
<tr><td><code>BPF_PROG_TYPE_CGROUP_SOCK</code></td><td>|<a href=""><code>BPF_FUNC_get_current_uid_gid()</code></a> <br> <code>基本功能</code></td></tr>
<tr><td><code>BPF_PROG_TYPE_LWT_IN</code></td><td>|<a href=""><code>BPF_FUNC_lwt_push_encap()</code></a> <br> <code>LWT功能</code> <br> <code>基本功能</code></td></tr>
<tr><td><code>BPF_PROG_TYPE_LWT_OUT</code></td><td><code>LWT功能</code> <br> <code>基本功能</code></td></tr>
<tr><td><code>BPF_PROG_TYPE_LWT_XMIT</code></td><td>|<a href=""><code>BPF_FUNC_skb_get_tunnel_key()</code></a> <br> <a href=""><code>BPF_FUNC_skb_set_tunnel_key()</code></a> <br> <a href=""><code>BPF_FUNC_skb_get_tunnel_opt()</code></a> <br> <a href=""><code>BPF_FUNC_skb_set_tunnel_opt()</code></a> <br> <a href=""><code>BPF_FUNC_redirect()</code></a> <br> <a href=""><code>BPF_FUNC_clone_redirect()</code></a> <br> <a href=""><code>BPF_FUNC_skb_change_tail()</code></a> <br> <a href=""><code>BPF_FUNC_skb_change_head()</code></a> <br> <a href=""><code>BPF_FUNC_skb_store_bytes()</code></a> <br> <a href=""><code>BPF_FUNC_csum_update()</code></a> <br> <a href=""><code>BPF_FUNC_l3_csum_replace()</code></a> <br> <a href=""><code>BPF_FUNC_l4_csum_replace()</code></a> <br> <a href=""><code>BPF_FUNC_set_hash_invalid()</code></a> <br> <code>LWT功能</code></td></tr>
<tr><td><code>BPF_PROG_TYPE_SOCK_OPS</code></td><td>|<a href=""><code>BPF_FUNC_setsockopt()</code></a> <br> <a href=""><code>BPF_FUNC_getsockopt()</code></a> <br> <a href=""><code>BPF_FUNC_sock_ops_cb_flags_set()</code></a> <br> <a href=""><code>BPF_FUNC_sock_map_update()</code></a> <br> <a href=""><code>BPF_FUNC_sock_hash_update()</code></a> <br> <a href=""><code>BPF_FUNC_get_socket_cookie()</code></a> <br> <code>基本功能</code></td></tr>
<tr><td><code>BPF_PROG_TYPE_SK_SKB</code></td><td>|<a href=""><code>BPF_FUNC_skb_store_bytes()</code></a> <br> <a href=""><code>BPF_FUNC_skb_load_bytes()</code></a> <br> <a href=""><code>BPF_FUNC_skb_pull_data()</code></a> <br> <a href=""><code>BPF_FUNC_skb_change_tail()</code></a> <br> <a href=""><code>BPF_FUNC_skb_change_head()</code></a> <br> <a href=""><code>BPF_FUNC_get_socket_cookie()</code></a> <br> <a href=""><code>BPF_FUNC_get_socket_uid()</code></a> <br> <a href=""><code>BPF_FUNC_sk_redirect_map()</code></a> <br> <a href=""><code>BPF_FUNC_sk_redirect_hash()</code></a> <br> <a href=""><code>BPF_FUNC_sk_lookup_tcp()</code></a> <br> <a href=""><code>BPF_FUNC_sk_lookup_udp()</code></a> <br> <a href=""><code>BPF_FUNC_sk_release()</code></a> <br> <code>基本功能</code></td></tr>
<tr><td><code>BPF_PROG_TYPE_CGROUP_DEVICE</code></td><td>|<a href=""><code>BPF_FUNC_map_lookup_elem()</code></a> <br> <a href=""><code>BPF_FUNC_map_update_elem()</code></a> <br> <a href=""><code>BPF_FUNC_map_delete_elem()</code></a> <br> <a href=""><code>BPF_FUNC_get_current_uid_gid()</code></a> <br> <a href=""><code>BPF_FUNC_trace_printk()</code></a></td></tr>
<tr><td><code>BPF_PROG_TYPE_RAW_TRACEPOINT</code></td><td><code>BPF_FUNC_perf_event_output()</code> <br> <code>BPF_FUNC_get_stackid()</code> <br> <code>BPF_FUNC_get_stack()</code> <br> <code>BPF_FUNC_skb_output()</code> <br> <code>跟踪功能</code></td></tr>
<tr><td><code>BPF_PROG_TYPE_CGROUP_SOCK_ADDR</code></td><td><code>BPF_FUNC_get_current_uid_gid()</code> <br> <code>BPF_FUNC_bind()</code> <br> <code>BPF_FUNC_get_socket_cookie()</code> <br> <code>基本功能</code></td></tr>
<tr><td><code>BPF_PROG_TYPE_LWT_SEG6LOCAL</code></td><td><code>BPF_FUNC_lwt_seg6_store_bytes()</code> <br> <code>BPF_FUNC_lwt_seg6_action()</code> <br> <code>BPF_FUNC_lwt_seg6_adjust_srh()</code> <br> <code>LWT功能</code></td></tr>
<tr><td><code>BPF_PROG_TYPE_LIRC_MODE2</code></td><td><code>BPF_FUNC_rc_repeat()</code> <br> <code>BPF_FUNC_rc_keydown()</code> <br> <code>BPF_FUNC_rc_pointer_rel()</code> <br> <code>BPF_FUNC_map_lookup_elem()</code> <br> <code>BPF_FUNC_map_update_elem()</code> <br> <code>BPF_FUNC_map_delete_elem()</code> <br> <code>BPF_FUNC_ktime_get_ns()</code> <br> <code>BPF_FUNC_tail_call()</code> <br> <code>BPF_FUNC_get_prandom_u32()</code> <br> <code>BPF_FUNC_trace_printk()</code></td></tr>
<tr><td><code>BPF_PROG_TYPE_SK_REUSEPORT</code></td><td><code>BPF_FUNC_sk_select_reuseport()</code> <br> <code>BPF_FUNC_skb_load_bytes()</code> <br> <code>BPF_FUNC_load_bytes_relative()</code> <br> <code>Base functions</code></td></tr>
<tr><td><code>BPF_PROG_TYPE_FLOW_DISSECTOR</code></td><td><code>BPF_FUNC_skb_load_bytes()</code> <br> <code>Base functions</code></td></tr>
<tr><td><code>BPF_PROG_TYPE_SK_REUSEPORT</code></td><td><code>BPF_FUNC_sk_select_reuseport()</code> <br> <code>BPF_FUNC_skb_load_bytes()</code> <br> <code>BPF_FUNC_load_bytes_relative()</code> <br> <code>基本功能</code></td></tr>
<tr><td><code>BPF_PROG_TYPE_FLOW_DISSECTOR</code></td><td><code>BPF_FUNC_skb_load_bytes()</code> <br> <code>基本功能</code></td></tr>
</tbody></table>
</div><div class="table-wrapper"><table><thead><tr><th>Function Group</th><th>Functions</th></tr></thead><tbody>
<tr><td><code>Base functions</code></td><td><code>BPF_FUNC_map_lookup_elem()</code> <br> <code>BPF_FUNC_map_update_elem()</code> <br> <code>BPF_FUNC_map_delete_elem()</code> <br> <code>BPF_FUNC_map_peek_elem()</code> <br> <code>BPF_FUNC_map_pop_elem()</code> <br> <code>BPF_FUNC_map_push_elem()</code> <br> <code>BPF_FUNC_get_prandom_u32()</code> <br> <code>BPF_FUNC_get_smp_processor_id()</code> <br> <code>BPF_FUNC_get_numa_node_id()</code> <br> <code>BPF_FUNC_tail_call()</code> <br> <code>BPF_FUNC_ktime_get_boot_ns()</code> <br> <code>BPF_FUNC_ktime_get_ns()</code> <br> <code>BPF_FUNC_trace_printk()</code> <br> <code>BPF_FUNC_spin_lock()</code> <br> <code>BPF_FUNC_spin_unlock()</code></td></tr>
<tr><td><code>Tracing functions</code></td><td><code>BPF_FUNC_map_lookup_elem()</code> <br> <code>BPF_FUNC_map_update_elem()</code> <br> <code>BPF_FUNC_map_delete_elem()</code> <br> <code>BPF_FUNC_probe_read()</code> <br> <code>BPF_FUNC_ktime_get_boot_ns()</code> <br> <code>BPF_FUNC_ktime_get_ns()</code> <br> <code>BPF_FUNC_tail_call()</code> <br> <code>BPF_FUNC_get_current_pid_tgid()</code> <br> <code>BPF_FUNC_get_current_task()</code> <br> <code>BPF_FUNC_get_current_uid_gid()</code> <br> <code>BPF_FUNC_get_current_comm()</code> <br> <code>BPF_FUNC_trace_printk()</code> <br> <code>BPF_FUNC_get_smp_processor_id()</code> <br> <code>BPF_FUNC_get_numa_node_id()</code> <br> <code>BPF_FUNC_perf_event_read()</code> <br> <code>BPF_FUNC_probe_write_user()</code> <br> <code>BPF_FUNC_current_task_under_cgroup()</code> <br> <code>BPF_FUNC_get_prandom_u32()</code> <br> <code>BPF_FUNC_probe_read_str()</code> <br> <code>BPF_FUNC_get_current_cgroup_id()</code> <br> <code>BPF_FUNC_send_signal()</code> <br> <code>BPF_FUNC_probe_read_kernel()</code> <br> <code>BPF_FUNC_probe_read_kernel_str()</code> <br> <code>BPF_FUNC_probe_read_user()</code> <br> <code>BPF_FUNC_probe_read_user_str()</code> <br> <code>BPF_FUNC_send_signal_thread()</code> <br> <code>BPF_FUNC_get_ns_current_pid_tgid()</code> <br> <code>BPF_FUNC_xdp_output()</code> <br> <code>BPF_FUNC_get_task_stack()</code></td></tr>
<tr><td><code>LWT functions</code></td><td><code>BPF_FUNC_skb_load_bytes()</code> <br> <code>BPF_FUNC_skb_pull_data()</code> <br> <code>BPF_FUNC_csum_diff()</code> <br> <code>BPF_FUNC_get_cgroup_classid()</code> <br> <code>BPF_FUNC_get_route_realm()</code> <br> <code>BPF_FUNC_get_hash_recalc()</code> <br> <code>BPF_FUNC_perf_event_output()</code> <br> <code>BPF_FUNC_get_smp_processor_id()</code> <br> <code>BPF_FUNC_skb_under_cgroup()</code></td></tr>
</div><div class="table-wrapper"><table><thead><tr><th>功能组</th><th>功能</th></tr></thead><tbody>
<tr><td><code>基本功能</code></td><td><code>BPF_FUNC_map_lookup_elem()</code> <br> <code>BPF_FUNC_map_update_elem()</code> <br> <code>BPF_FUNC_map_delete_elem()</code> <br> <code>BPF_FUNC_map_peek_elem()</code> <br> <code>BPF_FUNC_map_pop_elem()</code> <br> <code>BPF_FUNC_map_push_elem()</code> <br> <code>BPF_FUNC_get_prandom_u32()</code> <br> <code>BPF_FUNC_get_smp_processor_id()</code> <br> <code>BPF_FUNC_get_numa_node_id()</code> <br> <code>BPF_FUNC_tail_call()</code> <br> <code>BPF_FUNC_ktime_get_boot_ns()</code> <br> <code>BPF_FUNC_ktime_get_ns()</code> <br> <code>BPF_FUNC_trace_printk()</code> <br> <code>BPF_FUNC_spin_lock()</code> <br> <code>BPF_FUNC_spin_unlock()</code></td></tr>
<tr><td><code>LWT函数</code></td><td><code>BPF_FUNC_skb_load_bytes()</code> <br> <code>BPF_FUNC_skb_pull_data()</code> <br> <code>BPF_FUNC_csum_diff()</code> <br> <code>BPF_FUNC_get_cgroup_classid()</code> <br> <code>BPF_FUNC_get_route_realm()</code> <br> <code>BPF_FUNC_get_hash_recalc()</code> <br> <code>BPF_FUNC_perf_event_output()</code> <br> <code>BPF_FUNC_get_smp_processor_id()</code> <br> <code>BPF_FUNC_skb_under_cgroup()</code></td></tr>
</tbody></table>
</div>
</main>

View File

@@ -166,50 +166,48 @@
<div id="content" class="content">
<main>
<h1 id="kernel-configuration-for-bpf-features"><a class="header" href="#kernel-configuration-for-bpf-features">Kernel Configuration for BPF Features</a></h1>
<h2 id="bpf-related-kernel-configurations"><a class="header" href="#bpf-related-kernel-configurations">BPF Related Kernel Configurations</a></h2>
<div class="table-wrapper"><table><thead><tr><th style="text-align: left">Functionalities</th><th style="text-align: left">Kernel Configuration</th><th style="text-align: left">Description</th></tr></thead><tbody>
<tr><td style="text-align: left"><strong>Basic</strong></td><td style="text-align: left">CONFIG_BPF_SYSCALL</td><td style="text-align: left">Enable the bpf() system call</td></tr>
<tr><td style="text-align: left"></td><td style="text-align: left">CONFIG_BPF_JIT</td><td style="text-align: left">BPF programs are normally handled by a BPF interpreter. This option allows the kernel to generate native code when a program is loaded into the kernel. This will significantly speed-up processing of BPF programs</td></tr>
<tr><td style="text-align: left"></td><td style="text-align: left">CONFIG_HAVE_BPF_JIT</td><td style="text-align: left">Enable BPF Just In Time compiler</td></tr>
<tr><td style="text-align: left"></td><td style="text-align: left">CONFIG_HAVE_EBPF_JIT</td><td style="text-align: left">Extended BPF JIT (eBPF)</td></tr>
<tr><td style="text-align: left"></td><td style="text-align: left">CONFIG_HAVE_CBPF_JIT</td><td style="text-align: left">Classic BPF JIT (cBPF)</td></tr>
<tr><td style="text-align: left"></td><td style="text-align: left">CONFIG_MODULES</td><td style="text-align: left">Enable to build loadable kernel modules</td></tr>
<tr><td style="text-align: left"></td><td style="text-align: left">CONFIG_BPF</td><td style="text-align: left">BPF VM interpreter</td></tr>
<tr><td style="text-align: left"></td><td style="text-align: left">CONFIG_BPF_EVENTS</td><td style="text-align: left">Allow the user to attach BPF programs to kprobe, uprobe, and tracepoint events</td></tr>
<tr><td style="text-align: left"></td><td style="text-align: left">CONFIG_PERF_EVENTS</td><td style="text-align: left">Kernel performance events and counters</td></tr>
<tr><td style="text-align: left"></td><td style="text-align: left">CONFIG_HAVE_PERF_EVENTS</td><td style="text-align: left">Enable perf events</td></tr>
<tr><td style="text-align: left"></td><td style="text-align: left">CONFIG_PROFILING</td><td style="text-align: left">Enable the extended profiling support mechanisms used by profilers</td></tr>
<tr><td style="text-align: left"><strong>BTF</strong></td><td style="text-align: left">CONFIG_DEBUG_INFO_BTF</td><td style="text-align: left">Generate deduplicated BTF type information from DWARF debug info</td></tr>
<tr><td style="text-align: left"></td><td style="text-align: left">CONFIG_PAHOLE_HAS_SPLIT_BTF</td><td style="text-align: left">Generate BTF for each selected kernel module</td></tr>
<tr><td style="text-align: left"></td><td style="text-align: left">CONFIG_DEBUG_INFO_BTF_MODULES</td><td style="text-align: left">Generate compact split BTF type information for kernel modules</td></tr>
<tr><td style="text-align: left"><strong>Security</strong></td><td style="text-align: left">CONFIG_BPF_JIT_ALWAYS_ON</td><td style="text-align: left">Enable BPF JIT and removes BPF interpreter to avoid speculative execution</td></tr>
<tr><td style="text-align: left"></td><td style="text-align: left">CONFIG_BPF_UNPRIV_DEFAULT_OFF</td><td style="text-align: left">Disable unprivileged BPF by default by setting</td></tr>
<tr><td style="text-align: left"><strong>Cgroup</strong></td><td style="text-align: left">CONFIG_CGROUP_BPF</td><td style="text-align: left">Support for BPF programs attached to cgroups</td></tr>
<tr><td style="text-align: left"><strong>Network</strong></td><td style="text-align: left">CONFIG_BPFILTER</td><td style="text-align: left">BPF based packet filtering framework (BPFILTER)</td></tr>
<tr><td style="text-align: left"></td><td style="text-align: left">CONFIG_BPFILTER_UMH</td><td style="text-align: left">This builds bpfilter kernel module with embedded user mode helper</td></tr>
<tr><td style="text-align: left"></td><td style="text-align: left">CONFIG_NET_CLS_BPF</td><td style="text-align: left">BPF-based classifier - to classify packets based on programmable BPF (JIT'ed) filters as an alternative to ematches</td></tr>
<tr><td style="text-align: left"></td><td style="text-align: left">CONFIG_NET_ACT_BPF</td><td style="text-align: left">Execute BPF code on packets. The BPF code will decide if the packet should be dropped or not</td></tr>
<tr><td style="text-align: left"></td><td style="text-align: left">CONFIG_BPF_STREAM_PARSER</td><td style="text-align: left">Enable this to allow a TCP stream parser to be used with BPF_MAP_TYPE_SOCKMAP</td></tr>
<tr><td style="text-align: left"></td><td style="text-align: left">CONFIG_LWTUNNEL_BPF</td><td style="text-align: left">Allow to run BPF programs as a nexthop action following a route lookup for incoming and outgoing packets</td></tr>
<tr><td style="text-align: left"></td><td style="text-align: left">CONFIG_NETFILTER_XT_MATCH_BPF</td><td style="text-align: left">BPF matching applies a linux socket filter to each packet and accepts those for which the filter returns non-zero</td></tr>
<tr><td style="text-align: left"></td><td style="text-align: left">CONFIG_IPV6_SEG6_BPF</td><td style="text-align: left">To support BPF seg6local hook. bpf: Add IPv6 Segment Routing helpersy. <a href="https://github.com/torvalds/linux/commit/fe94cc290f535709d3c5ebd1e472dfd0aec7ee7">Reference</a></td></tr>
<tr><td style="text-align: left"><strong>kprobes</strong></td><td style="text-align: left">CONFIG_KPROBE_EVENTS</td><td style="text-align: left">This allows the user to add tracing events (similar to tracepoints) on the fly via the ftrace interface</td></tr>
<tr><td style="text-align: left"></td><td style="text-align: left">CONFIG_KPROBES</td><td style="text-align: left">Enable kprobes-based dynamic events</td></tr>
<tr><td style="text-align: left"></td><td style="text-align: left">CONFIG_HAVE_KPROBES</td><td style="text-align: left">Check if krpobes enabled</td></tr>
<tr><td style="text-align: left"></td><td style="text-align: left">CONFIG_HAVE_REGS_AND_STACK_ACCESS_API</td><td style="text-align: left">This symbol should be selected by an architecture if it supports the API needed to access registers and stack entries from pt_regs. For example the kprobes-based event tracer needs this API.</td></tr>
<tr><td style="text-align: left"></td><td style="text-align: left">CONFIG_KPROBES_ON_FTRACE</td><td style="text-align: left">Have kprobes on function tracer if arch supports full passing of pt_regs to function tracing</td></tr>
<tr><td style="text-align: left"><strong>kprobe multi</strong></td><td style="text-align: left">CONFIG_FPROBE</td><td style="text-align: left">Enable fprobe to attach the probe on multiple functions at once</td></tr>
<tr><td style="text-align: left"><strong>kprobe override</strong></td><td style="text-align: left">CONFIG_BPF_KPROBE_OVERRIDE</td><td style="text-align: left">Enable BPF programs to override a kprobed function</td></tr>
<tr><td style="text-align: left"><strong>uprobes</strong></td><td style="text-align: left">CONFIG_UPROBE_EVENTS</td><td style="text-align: left">Enable uprobes-based dynamic events</td></tr>
<tr><td style="text-align: left"></td><td style="text-align: left">CONFIG_ARCH_SUPPORTS_UPROBES</td><td style="text-align: left">Arch specific uprobes support</td></tr>
<tr><td style="text-align: left"></td><td style="text-align: left">CONFIG_UPROBES</td><td style="text-align: left">Uprobes is the user-space counterpart to kprobes: they enable instrumentation applications (such as 'perf probe') to establish unintrusive probes in user-space binaries and libraries, by executing handler functions when the probes are hit by user-space applications.</td></tr>
<tr><td style="text-align: left"></td><td style="text-align: left">CONFIG_MMU</td><td style="text-align: left">MMU-based virtualised addressing space support by paged memory management</td></tr>
<tr><td style="text-align: left"><strong>Tracepoints</strong></td><td style="text-align: left">CONFIG_TRACEPOINTS</td><td style="text-align: left">Enable inserting tracepoints in the kernel and connect to proble functions</td></tr>
<tr><td style="text-align: left"></td><td style="text-align: left">CONFIG_HAVE_SYSCALL_TRACEPOINTS</td><td style="text-align: left">Enable syscall enter/exit tracing</td></tr>
<h1 id="bpf-特性的内核配置"><a class="header" href="#bpf-特性的内核配置">BPF 特性的内核配置</a></h1>
<h2 id="与-bpf-相关的内核配置"><a class="header" href="#与-bpf-相关的内核配置">BPF 相关的内核配置</a></h2>
<div class="table-wrapper"><table><thead><tr><th style="text-align: left">功能</th><th style="text-align: left">内核配置</th><th style="text-align: left">描述</th></tr></thead><tbody>
<tr><td style="text-align: left"><strong>基础</strong></td><td style="text-align: left">CONFIG_BPF_SYSCALL</td><td style="text-align: left">启用 bpf() 系统调用</td></tr>
<tr><td style="text-align: left"></td><td style="text-align: left">CONFIG_BPF_JIT</td><td style="text-align: left">BPF 程序通常由 BPF 解释器处理。此选项允许内核在加载程序时生成本地代码。这将显著加速 BPF 程序的处理</td></tr>
<tr><td style="text-align: left"></td><td style="text-align: left">CONFIG_HAVE_BPF_JIT</td><td style="text-align: left">启用 BPF 即时编译器</td></tr>
<tr><td style="text-align: left"></td><td style="text-align: left">CONFIG_HAVE_EBPF_JIT</td><td style="text-align: left">扩展 BPF JIT (eBPF)</td></tr>
<tr><td style="text-align: left"></td><td style="text-align: left">CONFIG_HAVE_CBPF_JIT</td><td style="text-align: left">经典 BPF JIT (cBPF)</td></tr>
<tr><td style="text-align: left"></td><td style="text-align: left">CONFIG_MODULES</td><td style="text-align: left">启用可加载内核模块的构建</td></tr>
<tr><td style="text-align: left"></td><td style="text-align: left">CONFIG_BPF</td><td style="text-align: left">BPF VM 解释器</td></tr>
<tr><td style="text-align: left"></td><td style="text-align: left">CONFIG_BPF_EVENTS</td><td style="text-align: left">允许用户将 BPF 程序附加到 kprobeuprobe tracepoint 事件上</td></tr>
<tr><td style="text-align: left"></td><td style="text-align: left">CONFIG_PERF_EVENTS</td><td style="text-align: left">内核性能事件和计数器</td></tr>
<tr><td style="text-align: left"></td><td style="text-align: left">CONFIG_HAVE_PERF_EVENTS</td><td style="text-align: left">启用性能事件</td></tr>
<tr><td style="text-align: left"></td><td style="text-align: left">CONFIG_PROFILING</td><td style="text-align: left">启用分析器使用的扩展分析支持机制</td></tr>
<tr><td style="text-align: left"><strong>BTF</strong></td><td style="text-align: left">CONFIG_DEBUG_INFO_BTF</td><td style="text-align: left">从 DWARF 调试信息生成去重的 BTF 类型信息</td></tr>
<tr><td style="text-align: left"></td><td style="text-align: left">CONFIG_PAHOLE_HAS_SPLIT_BTF</td><td style="text-align: left">为每个选定的内核模块生成 BTF</td></tr>
<tr><td style="text-align: left"></td><td style="text-align: left">CONFIG_DEBUG_INFO_BTF_MODULES</td><td style="text-align: left">为内核模块生成紧凑的分割 BTF 类型信息</td></tr>
<tr><td style="text-align: left"><strong>安全</strong></td><td style="text-align: left">CONFIG_BPF_JIT_ALWAYS_ON</td><td style="text-align: left">启用 BPF JIT 并删除 BPF 解释器以避免猜测执行</td></tr>
<tr><td style="text-align: left"></td><td style="text-align: left">CONFIG_BPF_UNPRIV_DEFAULT_OFF</td><td style="text-align: left">通过设置默认禁用非特权 BPF</td></tr>
<tr><td style="text-align: left"><strong>Cgroup</strong></td><td style="text-align: left">CONFIG_CGROUP_BPF</td><td style="text-align: left">支持将 BPF 程序附加到 cgroup</td></tr>
<tr><td style="text-align: left"><strong>网络</strong></td><td style="text-align: left">CONFIG_BPFILTER</td><td style="text-align: left">基于 BPF 的数据包过滤框架 (BPFILTER)</td></tr>
<tr><td style="text-align: left"></td><td style="text-align: left">CONFIG_BPFILTER_UMH</td><td style="text-align: left">使用内嵌的用户模式助手构建 bpfilter 内核模块</td></tr>
<tr><td style="text-align: left"></td><td style="text-align: left">CONFIG_NET_CLS_BPF</td><td style="text-align: left">基于可编程 BPF (JIT'ed) 过滤器进行数据包分类的基于 BPF 的分类器的替代方法</td></tr>
<tr><td style="text-align: left"></td><td style="text-align: left">CONFIG_BPF_STREAM_PARSER</td><td style="text-align: left">启用此功能允许使用BPF_MAP_TYPE_SOCKMAP与TCP流解析器配合使用</td></tr>
<tr><td style="text-align: left"></td><td style="text-align: left">CONFIG_LWTUNNEL_BPF</td><td style="text-align: left">在路由查找入站和出站数据包后允许作为下一跳操作运行BPF程序</td></tr>
<tr><td style="text-align: left"></td><td style="text-align: left">CONFIG_NETFILTER_XT_MATCH_BPF</td><td style="text-align: left">BPF匹配将对每个数据包应用Linux套接字过滤器并接受过滤器返回非零值的数据包</td></tr>
<tr><td style="text-align: left"></td><td style="text-align: left">CONFIG_IPV6_SEG6_BPF</td><td style="text-align: left">为支持BPF seg6local挂钩添加IPv6 Segement Routing助手 <a href="https://github.com/torvalds/linux/commit/fe94cc290f535709d3c5ebd1e472dfd0aec7ee7">参考</a></td></tr>
<tr><td style="text-align: left"><strong>kprobes</strong></td><td style="text-align: left">CONFIG_KPROBE_EVENTS</td><td style="text-align: left">允许用户通过ftrace接口动态添加跟踪事件类似于tracepoints</td></tr>
<tr><td style="text-align: left"></td><td style="text-align: left">CONFIG_KPROBES</td><td style="text-align: left">启用基于kprobes的动态事件</td></tr>
<tr><td style="text-align: left"></td><td style="text-align: left">CONFIG_HAVE_KPROBES</td><td style="text-align: left">检查是否启用了kprobes</td></tr>
<tr><td style="text-align: left"></td><td style="text-align: left">CONFIG_HAVE_REGS_AND_STACK_ACCESS_API</td><td style="text-align: left">如果架构支持从pt_regs访问寄存器和堆栈条目所需的API则应该选择此符号。例如基于kprobes的事件跟踪器需要此API</td></tr>
<tr><td style="text-align: left"></td><td style="text-align: left">CONFIG_KPROBES_ON_FTRACE</td><td style="text-align: left">如果架构支持将pt_regs完全传递给函数跟踪则在函数跟踪器上有kprobes</td></tr>
<tr><td style="text-align: left"><strong>kprobe multi</strong></td><td style="text-align: left">CONFIG_FPROBE</td><td style="text-align: left">启用fprobe以一次性在多个函数上附加探测点</td></tr>
<tr><td style="text-align: left"><strong>kprobe override</strong></td><td style="text-align: left">CONFIG_BPF_KPROBE_OVERRIDE</td><td style="text-align: left">启用BPF程序覆盖kprobed函数</td></tr>
<tr><td style="text-align: left"><strong>uprobes</strong></td><td style="text-align: left">CONFIG_UPROBE_EVENTS</td><td style="text-align: left">启用基于uprobes的动态事件</td></tr>
<tr><td style="text-align: left"></td><td style="text-align: left">CONFIG_ARCH_SUPPORTS_UPROBES</td><td style="text-align: left">架构特定的uprobes支持</td></tr>
<tr><td style="text-align: left"></td><td style="text-align: left">CONFIG_UPROBES</td><td style="text-align: left">Uprobes是kprobes的用户空间对应项它们允许仪器应用程序如'perf probe')在用户空间二进制文件和库中建立非侵入性探测点,并在用户空间应用程序触发探测点时执行处理函数。</td></tr>
<tr><td style="text-align: left"><strong>Tracepoints</strong></td><td style="text-align: left">CONFIG_TRACEPOINTS</td><td style="text-align: left">启用在内核中插入Tracepoints并与问题函数连接</td></tr>
<tr><td style="text-align: left"></td><td style="text-align: left">CONFIG_HAVE_SYSCALL_TRACEPOINTS</td><td style="text-align: left">启用系统调用进入/退出跟踪</td></tr>
<tr><td style="text-align: left"><strong>Raw Tracepoints</strong></td><td style="text-align: left">Same as Tracepoints</td><td style="text-align: left"></td></tr>
<tr><td style="text-align: left"><strong>LSM</strong></td><td style="text-align: left">CONFIG_BPF_LSM</td><td style="text-align: left">Enable instrumentation of the security hooks with BPF programs for implementing dynamic MAC and Audit Policies</td></tr>
<tr><td style="text-align: left"><strong>LIRC</strong></td><td style="text-align: left">CONFIG_BPF_LIRC_MODE2</td><td style="text-align: left">Allow attaching BPF programs to a lirc device</td></tr>
<tr><td style="text-align: left"><strong>LSM</strong></td><td style="text-align: left">CONFIG_BPF_LSM</td><td style="text-align: left">使用BPF程序对安全钩子进行仪器化实现动态MAC和审计策略</td></tr>
<tr><td style="text-align: left"><strong>LIRC</strong></td><td style="text-align: left">CONFIG_BPF_LIRC_MODE2</td><td style="text-align: left">允许将BPF程序附加到lirc设备</td></tr>
</tbody></table>
</div>
</main>

File diff suppressed because it is too large Load Diff

View File

@@ -166,68 +166,56 @@
<div id="content" class="content">
<main>
<h1 id="special-filtering"><a class="header" href="#special-filtering">Special Filtering</a></h1>
<p>Some tools have special filtering capabitilies, the main use case is to trace
processes running in containers, but those mechanisms are generic and could
be used in other cases as well.</p>
<h2 id="filtering-by-cgroups"><a class="header" href="#filtering-by-cgroups">Filtering by cgroups</a></h2>
<p>Some tools have an option to filter by cgroup by referencing a pinned BPF hash
map managed externally.</p>
<p>Examples of commands:</p>
<h1 id="特殊过滤"><a class="header" href="#特殊过滤">特殊过滤</a></h1>
<p>某些工具具有特殊的过滤能力,主要用例是跟踪运行在容器中的进程,但这些机制是通用的,也可以在其他情况下使用。</p>
<h2 id="按-cgroups过滤"><a class="header" href="#按-cgroups过滤">按 cgroups过滤</a></h2>
<p>某些工具有一个通过引用外部管理的固定的BPF哈希映射来按cgroup过滤的选项。</p>
<p>命令示例:</p>
<pre><code class="language-sh"># ./opensnoop --cgroupmap /sys/fs/bpf/test01
# ./execsnoop --cgroupmap /sys/fs/bpf/test01
# ./tcpconnect --cgroupmap /sys/fs/bpf/test01
# ./tcpaccept --cgroupmap /sys/fs/bpf/test01
# ./tcptracer --cgroupmap /sys/fs/bpf/test01
</code></pre>
<p>The commands above will only display results from processes that belong to one
of the cgroups whose id, returned by <code>bpf_get_current_cgroup_id()</code>, is in the
pinned BPF hash map.</p>
<p>The BPF hash map can be created by:</p>
<p>上述命令将仅显示属于一个或多个cgroup的进程的结果这些cgroup的ID由<code>bpf_get_current_cgroup_id()</code>返回并存在固定的BPF哈希映射中。</p>
<p>通过以下方式创建BPF哈希映射</p>
<pre><code class="language-sh"># bpftool map create /sys/fs/bpf/test01 type hash key 8 value 8 entries 128 \
name cgroupset flags 0
</code></pre>
<p>To get a shell in a new cgroup, you can use:</p>
<p>要在新cgroup中获取一个shell可以使用</p>
<pre><code class="language-sh"># systemd-run --pty --unit test bash
</code></pre>
<p>The shell will be running in the cgroup
<code>/sys/fs/cgroup/unified/system.slice/test.service</code>.</p>
<p>The cgroup id can be discovered using the <code>name_to_handle_at()</code> system call. In
the examples/cgroupid, you will find an example of program to get the cgroup
id.</p>
<p>shell将在cgroup<code>/sys/fs/cgroup/unified/system.slice/test.service</code>中运行。</p>
<p>可以使用<code>name_to_handle_at()</code>系统调用来发现cgroup ID。在examples/cgroupid中您可以找到一个获取cgroup ID的程序示例。</p>
<pre><code class="language-sh"># cd examples/cgroupid
# make
# ./cgroupid hex /sys/fs/cgroup/unified/system.slice/test.service
</code></pre>
<p>or, using Docker:</p>
<p>或者,使用Docker</p>
<pre><code class="language-sh"># cd examples/cgroupid
# docker build -t cgroupid .
# docker run --rm --privileged -v /sys/fs/cgroup:/sys/fs/cgroup \
cgroupid cgroupid hex /sys/fs/cgroup/unified/system.slice/test.service
cgroupid cgroupid hex /sys/fs/cgroup/unified/system.slice/test.service
</code></pre>
<p>This prints the cgroup id as a hexadecimal string in the host endianness such
as <code>77 16 00 00 01 00 00 00</code>.</p>
<p>这将以主机的字节序(hexadecimal string)打印出cgroup ID例如<code>77 16 00 00 01 00 00 00</code></p>
<pre><code class="language-sh"># FILE=/sys/fs/bpf/test01
# CGROUPID_HEX=&quot;77 16 00 00 01 00 00 00&quot;
# bpftool map update pinned $FILE key hex $CGROUPID_HEX value hex 00 00 00 00 00 00 00 00 any
</code></pre>
<p>Now that the shell started by systemd-run has its cgroup id in the BPF hash
map, bcc tools will display results from this shell. Cgroups can be added and
removed from the BPF hash map without restarting the bcc tool.</p>
<p>This feature is useful for integrating bcc tools in external projects.</p>
<h2 id="filtering-by-mount-by-namespace"><a class="header" href="#filtering-by-mount-by-namespace">Filtering by mount by namespace</a></h2>
<p>The BPF hash map can be created by:</p>
<p>现在通过systemd-run启动的shell的cgroup ID已经存在于BPF哈希映射中bcc工具将显示来自该shell的结果。可以添加和。从BPF哈希映射中删除而不重新启动bcc工具。</p>
<p>这个功能对于将bcc工具集成到外部项目中非常有用。</p>
<h2 id="按命名空间选择挂载点进行过滤"><a class="header" href="#按命名空间选择挂载点进行过滤">按命名空间选择挂载点进行过滤</a></h2>
<p>BPF哈希映射可以通过以下方式创建</p>
<pre><code class="language-sh"># bpftool map create /sys/fs/bpf/mnt_ns_set type hash key 8 value 4 entries 128 \
name mnt_ns_set flags 0
</code></pre>
<p>Execute the <code>execsnoop</code> tool filtering only the mount namespaces
in <code>/sys/fs/bpf/mnt_ns_set</code>:</p>
<p>仅执行<code>execsnoop</code>工具,过滤挂载命名空间在<code>/sys/fs/bpf/mnt_ns_set</code>中:</p>
<pre><code class="language-sh"># tools/execsnoop.py --mntnsmap /sys/fs/bpf/mnt_ns_set
</code></pre>
<p>Start a terminal in a new mount namespace:</p>
<p>在新的挂载命名空间中启动一个终端:</p>
<pre><code class="language-sh"># unshare -m bash
</code></pre>
<p>Update the hash map with the mount namespace ID of the terminal above:</p>
<p>使用上述终端的挂载命名空间ID更新哈希映射</p>
<pre><code class="language-sh">FILE=/sys/fs/bpf/mnt_ns_set
if [ $(printf '\1' | od -dAn) -eq 1 ]; then
HOST_ENDIAN_CMD=tac
@@ -238,14 +226,15 @@ fi
NS_ID_HEX=&quot;$(printf '%016x' $(stat -Lc '%i' /proc/self/ns/mnt) | sed 's/.\{2\}/&amp;\n/g' | $HOST_ENDIAN_CMD)&quot;
bpftool map update pinned $FILE key hex $NS_ID_HEX value hex 00 00 00 00 any
</code></pre>
<p>Execute a command in this terminal:</p>
<p>在这个终端中执行命令:</p>
<pre><code class="language-sh"># ping kinvolk.io
</code></pre>
<p>You'll see how on the <code>execsnoop</code> terminal you started above the call is logged:</p>
<p>你会看到在上述你启动的<code>execsnoop</code>终端中,这个调用被记录下来:</p>
<pre><code class="language-sh"># tools/execsnoop.py --mntnsmap /sys/fs/bpf/mnt_ns_set
[sudo] password for mvb:
PCOMM PID PPID RET ARGS
ping 8096 7970 0 /bin/ping kinvolk.io
```。
</code></pre>
</main>

View File

@@ -166,13 +166,13 @@
<div id="content" class="content">
<main>
<h1 id="bcc-tutorial"><a class="header" href="#bcc-tutorial">bcc Tutorial</a></h1>
<p>This tutorial covers how to use <a href="https://github.com/iovisor/bcc">bcc</a> tools to quickly solve performance, troubleshooting, and networking issues. If you want to develop new bcc tools, see <a href="tutorial_bcc_python_developer.html">tutorial_bcc_python_developer.md</a> for that tutorial.</p>
<p>It is assumed for this tutorial that bcc is already installed, and you can run tools like execsnoop successfully. See <a href="https://github.com/iovisor/bcc/tree/master/INSTALL.md">INSTALL.md</a>. This uses enhancements added to the Linux 4.x series.</p>
<h2 id="observability"><a class="header" href="#observability">Observability</a></h2>
<p>Some quick wins.</p>
<h3 id="0-before-bcc"><a class="header" href="#0-before-bcc">0. Before bcc</a></h3>
<p>Before using bcc, you should start with the Linux basics. One reference is the <a href="https://netflixtechblog.com/linux-performance-analysis-in-60-000-milliseconds-accc10403c55">Linux Performance Analysis in 60,000 Milliseconds</a> post, which covers these commands:</p>
<h1 id="bcc-教程"><a class="header" href="#bcc-教程">bcc 教程</a></h1>
<p>本教程介绍如何使用<a href="https://github.com/iovisor/bcc">bcc</a>工具快速解决性能、故障排除和网络问题。如果你想开发新的bcc工具请参考<a href="tutorial_bcc_python_developer.html">tutorial_bcc_python_developer.md</a>教程。</p>
<p>本教程假设bcc已经安装好并且你可以成功运行像execsnoop这样的工具。参见<a href="https://github.com/iovisor/bcc/tree/master/INSTALL.md">INSTALL.md</a>。这些功能是在Linux 4.x系列中增加的。</p>
<h2 id="可观察性"><a class="header" href="#可观察性">可观察性</a></h2>
<p>一些快速的收获。</p>
<h3 id="0-使用bcc之前"><a class="header" href="#0-使用bcc之前">0. 使用bcc之前</a></h3>
<p>在使用bcc之前你应该从Linux基础知识开始。可以参考<a href="https://netflixtechblog.com/linux-performance-analysis-in-60-000-milliseconds-accc10403c55">Linux Performance Analysis in 60,000 Milliseconds</a>文章,其中介绍了以下命令:</p>
<ol>
<li>uptime</li>
<li>dmesg | tail</li>
@@ -185,12 +185,12 @@
<li>sar -n TCP,ETCP 1</li>
<li>top</li>
</ol>
<h3 id="1-general-performance"><a class="header" href="#1-general-performance">1. General Performance</a></h3>
<p>Here is a generic checklist for performance investigations with bcc, first as a list, then in detail:</p>
<h3 id="1-性能分析"><a class="header" href="#1-性能分析">1. 性能分析</a></h3>
<p>这是一个用于性能调查的通用检查清单,首先有一个列表,然后详细描述:</p>
<ol>
<li>execsnoop</li>
<li>opensnoop</li>
<li>ext4slower (or btrfs*, xfs*, zfs*)</li>
<li>ext4slower(或btrfs*xfs*zfs*</li>
<li>biolatency</li>
<li>biosnoop</li>
<li>cachestat</li>
@@ -200,7 +200,7 @@
<li>runqlat</li>
<li>profile</li>
</ol>
<p>These tools may be installed on your system under /usr/share/bcc/tools, or you can run them from the bcc github repo under /tools where they have a .py extension. Browse the 50+ tools available for more analysis options.</p>
<p>这些工具可能已经安装在你的系统的/usr/share/bcc/tools目录下或者你可以从bcc github仓库的/tools目录中运行它们这些工具使用.py扩展名。浏览50多个可用的工具获得更多的分析选项。</p>
<h4 id="11-execsnoop"><a class="header" href="#11-execsnoop">1.1 execsnoop</a></h4>
<pre><code class="language-sh"># ./execsnoop
PCOMM PID RET ARGS
@@ -210,9 +210,8 @@ mkdir 9662 0 /bin/mkdir -p ./main
run 9663 0 ./run
[...]
</code></pre>
<p>execsnoop prints one line of output for each new process. Check for short-lived processes. These can consume CPU resources, but not show up in most monitoring tools that periodically take snapshots of which processes are running.</p>
<p>It works by tracing exec(), not the fork(), so it will catch many types of new processes but not all (eg, it won't see an application launching working processes, that doesn't exec() anything else).</p>
<p>More <a href="https://github.com/iovisor/bcc/tree/master/tools/execsnoop_example.txt">examples</a>.</p>
<p>execsnoop对于每个新进程打印一行输出。检查短生命周期的进程。这些进程可能会消耗CPU资源但不会在大多数周期性运行的进程监控工具中显示出来。它通过跟踪<code>exec()</code>来工作,而不是<code>fork()</code>,所以它可以捕获许多类型的新进程,但不是所有类型(例如,它不会看到启动工作进程的应用程序,该应用程序没有<code>exec()</code>其他任何内容)。</p>
<p>更多<a href="https://github.com/iovisor/bcc/tree/master/tools/execsnoop_example.txt">例子</a></p>
<h4 id="12-opensnoop"><a class="header" href="#12-opensnoop">1.2. opensnoop</a></h4>
<pre><code class="language-sh"># ./opensnoop
PID COMM FD ERR PATH
@@ -227,28 +226,27 @@ PID COMM FD ERR PATH
1603 snmpd 11 0 /proc/sys/net/ipv6/conf/eth0/forwarding
[...]
</code></pre>
<p>opensnoop prints one line of output for each open() syscall, including details.</p>
<p>Files that are opened can tell you a lot about how applications work: identifying their data files, config files, and log files. Sometimes applications can misbehave, and perform poorly, when they are constantly attempting to read files that do not exist. opensnoop gives you a quick look.</p>
<p>More <a href="https://github.com/iovisor/bcc/tree/master/tools/opensnoop_example.txt">examples</a>.</p>
<h4 id="13-ext4slower-or-btrfs-xfs-zfs"><a class="header" href="#13-ext4slower-or-btrfs-xfs-zfs">1.3. ext4slower (or btrfs*, xfs*, zfs*)</a></h4>
<p>opensnoop每次open() syscall执行时打印一行输出包括详细信息。</p>
<p>打开的文件可以告诉你很多关于应用程序的工作方式的信息它们的数据文件、配置文件和日志文件。有时候应用程序可能会表现不正常当它们不断尝试读取不存在的文件时则会表现得很差。opensnoop能够快速帮助你查看。</p>
<p>更多<a href="https://github.com/iovisor/bcc/tree/master/tools/opensnoop_example.txt">例子</a></p>
<h4 id="13-ext4slowerbtrfsxfszfs"><a class="header" href="#13-ext4slowerbtrfsxfszfs">1.3. ext4slower(或btrfs*xfs*zfs*</a></h4>
<pre><code class="language-sh"># ./ext4slower
Tracing ext4 operations slower than 10 ms
TIME COMM PID T BYTES OFF_KB LAT(ms) FILENAME
追踪超过10毫秒的ext4操作
时间 进程 进程ID T 字节数 偏移KB 延迟(ms) 文件名
06:35:01 cron 16464 R 1249 0 16.05 common-auth
06:35:01 cron 16463 R 1249 0 16.04 common-auth
06:35:01 cron 16465 R 1249 0 16.03 common-auth
06:35:01 cron 16465 R 4096 0 10.62 login.defs
06:35:01 cron 16464 R 4096 0 10.61 login.defs
</code></pre>
<p>ext4slower traces the ext4 file system and times common operations, and then only prints those that exceed a threshold.</p>
<p>This is great for identifying or exonerating one type of performance issue: show individually slow disk i/O via the file system. Disks process I/O asynchronously, and it can be difficult to associate latency at that layer with the latency applications experience. Tracing higher up in the kernel stack, at the VFS -&gt; file system interface, will more closely match what an application suffers. Use this tool to identify if file system latency exceeds a given threshold.</p>
<p>Similar tools exist in bcc for other file systems: btrfsslower, xfsslower, and zfsslower. There is also fileslower, which works at the VFS layer and traces everything (although at some higher overhead).</p>
<p>More <a href="https://github.com/iovisor/bcc/tree/master/tools/ext4slower_example.txt">examples</a>.</p>
<p>ext4slower跟踪ext4文件系统并计时常见操作然后只打印超过阈值的操作。这对于识别或证明一种性能问题非常方便通过文件系统单独显示较慢的磁盘 I/O。磁盘以异步方式处理 I/O很难将该层的延迟与应用程序所经历的延迟关联起来。在内核堆栈中更高层的追踪即在 VFS -&gt; 文件系统接口中,会更接近应用程序遭受的延迟。使用此工具来判断文件系统的延迟是否超过了给定的阈值。</p>
<p>在 bcc 中存在其他文件系统的类似工具btrfsslower、xfsslower 和 zfsslower。还有一个名为 fileslower 的工具,它在 VFS 层工作并跟踪所有内容(尽管会有更高的开销)。</p>
<p>更多<a href="https://github.com/iovisor/bcc/tree/master/tools/ext4slower_example.txt">示例</a></p>
<h4 id="14-biolatency"><a class="header" href="#14-biolatency">1.4. biolatency</a></h4>
<pre><code class="language-sh"># ./biolatency
Tracing block device I/O... Hit Ctrl-C to end.
跟踪块设备的 I/O... Ctrl-C 结束。
^C
usecs : count distribution
微秒 : 数量 分布
0 -&gt; 1 : 0 | |
2 -&gt; 3 : 0 | |
4 -&gt; 7 : 0 | |
@@ -263,13 +261,12 @@ Tracing block device I/O... Hit Ctrl-C to end.
2048 -&gt; 4095 : 47 |********************************** |
4096 -&gt; 8191 : 52 |**************************************|
8192 -&gt; 16383 : 36 |************************** |
16384 -&gt; 32767 : 15 |********** |
32768 -&gt; 65535 : 2 |* |
16384 -&gt; 32767 : 15 |********** |。32768 -&gt; 65535 : 2 |* |
65536 -&gt; 131071 : 2 |* |
</code></pre>
<p>biolatency traces disk I/O latency (time from device issue to completion), and when the tool ends (Ctrl-C, or a given interval), it prints a histogram summary of the latency.</p>
<p>This is great for understanding disk I/O latency beyond the average times given by tools like iostat. I/O latency outliers will be visible at the end of the distribution, as well as multi-mode distributions.</p>
<p>More <a href="https://github.com/iovisor/bcc/tree/master/tools/biolatency_example.txt">examples</a>.</p>
<p>biolatency跟踪磁盘I/O延迟从设备执行到完成的时间当工具结束Ctrl-C或给定的间隔它会打印延迟的直方图摘要。</p>
<p>这对于了解超出iostat等工具提供的平均时间的磁盘I/O延迟非常有用。在分布的末尾将可见I/O延迟的异常值以及多种模式的分布。</p>
<p>更多<a href="https://github.com/iovisor/bcc/tree/master/tools/biolatency_example.txt">示例</a></p>
<h4 id="15-biosnoop"><a class="header" href="#15-biosnoop">1.5. biosnoop</a></h4>
<pre><code class="language-sh"># ./biosnoop
TIME(s) COMM PID DISK T SECTOR BYTES LAT(ms)
@@ -281,23 +278,24 @@ TIME(s) COMM PID DISK T SECTOR BYTES LAT(ms)
1.022568002 supervise 1950 xvda1 W 13188496 4096 0.93
[...]
</code></pre>
<p>biosnoop prints a line of output for each disk I/O, with details including latency (time from device issue to completion).</p>
<p>This allows you to examine disk I/O in more detail, and look for time-ordered patterns (eg, reads queueing behind writes). Note that the output will be verbose if your system performs disk I/O at a high rate.</p>
<p>More <a href="https://github.com/iovisor/bcc/tree/master/tools/biosnoop_example.txt">examples</a>.</p>
<p>biosnoop为每个磁盘I/O打印一行输出其中包括延迟从设备执行到完成的时间等详细信息。</p>
<p>这让您可以更详细地研究磁盘I/O并寻找按时间排序的模式例如读取在写入后排队。请注意如果您的系统以高速率执行磁盘I/O则输出将冗长。</p>
<p>更多<a href="https://github.com/iovisor/bcc/tree/master/tools/biosnoop_example.txt">示例</a></p>
<h4 id="16-cachestat"><a class="header" href="#16-cachestat">1.6. cachestat</a></h4>
<pre><code class="language-sh"># ./cachestat
HITS MISSES DIRTIES READ_HIT% WRITE_HIT% BUFFERS_MB CACHED_MB
1074 44 13 94.9% 2.9% 1 223
2195 170 8 92.5% 6.8% 1 143
182 53 56 53.6% 1.3% 1 143
62480 40960 20480 40.6% 19.8% 1 223
7 2 5 22.2% 22.2% 1 223
62480 40960 20480 40.6% 19.8% 1 223&quot;
格式:仅返回翻译后的内容,不包括原始文本。```
7 2 5 22.2% 22.2% 1 223
348 0 0 100.0% 0.0% 1 223
[...]
</code></pre>
<p>cachestat prints a one line summary every second (or every custom interval) showing statistics from the file system cache.</p>
<p>Use this to identify a low cache hit ratio, and a high rate of misses: which gives one lead for performance tuning.</p>
<p>More <a href="https://github.com/iovisor/bcc/tree/master/tools/cachestat_example.txt">examples</a>.</p>
<p>cachestat 每秒(或每个自定义时间间隔)打印一行摘要,显示文件系统缓存的统计信息。</p>
<p>可以用它来识别低缓存命中率和高缺失率,这是性能调优的线索之一。</p>
<p>更多 <a href="https://github.com/iovisor/bcc/tree/master/tools/cachestat_example.txt">示例</a></p>
<h4 id="17-tcpconnect"><a class="header" href="#17-tcpconnect">1.7. tcpconnect</a></h4>
<pre><code class="language-sh"># ./tcpconnect
PID COMM IP SADDR DADDR DPORT
@@ -308,9 +306,9 @@ PID COMM IP SADDR DADDR DPORT
2015 ssh 6 fe80::2000:bff:fe82:3ac fe80::2000:bff:fe82:3ac 22
[...]
</code></pre>
<p>tcpconnect prints one line of output for every active TCP connection (eg, via connect()), with details including source and destination addresses.</p>
<p>Look for unexpected connections that may point to inefficiencies in application configuration, or an intruder.</p>
<p>More <a href="https://github.com/iovisor/bcc/tree/master/tools/tcpconnect_example.txt">examples</a>.</p>
<p>tcpconnect 每个活动的 TCP 连接(例如通过 connect())打印一行输出,包括源地址和目标地址的详细信息。</p>
<p>寻找可能指向应用程序配置问题或入侵者的意外连接。</p>
<p>更多 <a href="https://github.com/iovisor/bcc/tree/master/tools/tcpconnect_example.txt">示例</a></p>
<h4 id="18-tcpaccept"><a class="header" href="#18-tcpaccept">1.8. tcpaccept</a></h4>
<pre><code class="language-sh"># ./tcpaccept
PID COMM IP RADDR LADDR LPORT
@@ -319,25 +317,25 @@ PID COMM IP RADDR LADDR LPORT
5389 perl 6 1234:ab12:2040:5020:2299:0:5:0 1234:ab12:2040:5020:2299:0:5:0 7001
[...]
</code></pre>
<p>tcpaccept prints one line of output for every passive TCP connection (eg, via accept()), with details including source and destination addresses.</p>
<p>Look for unexpected connections that may point to inefficiencies in application configuration, or an intruder.</p>
<p>More <a href="https://github.com/iovisor/bcc/tree/master/tools/tcpaccept_example.txt">examples</a>.</p>
<p>tcpaccept 每个被动的 TCP 连接(例如通过 accept())打印一行输出,包括源地址和目标地址的详细信息。</p>
<p>寻找可能指向应用程序配置问题或入侵者的意外连接。</p>
<p>更多 <a href="https://github.com/iovisor/bcc/tree/master/tools/tcpaccept_example.txt">示例</a></p>
<h4 id="19-tcpretrans"><a class="header" href="#19-tcpretrans">1.9. tcpretrans</a></h4>
<pre><code class="language-sh"># ./tcpretrans
TIME PID IP LADDR:LPORT T&gt; RADDR:RPORT STATE
01:55:05 0 4 10.153.223.157:22 R&gt; 69.53.245.40:34619 ESTABLISHED
01:55:05 0 4 10.153.223.157:22 R&gt; 69.53.245.40:34619 ESTABLISHED
01:55:17 0 4 10.153.223.157:22 R&gt; 69.53.245.40:22957 ESTABLISHED
<pre><code class="language-sh"># ./tcpretrans&quot;.
```时间 PID IP LADDR:LPORT T&gt; RADDR:RPORT 状态
01:55:05 0 4 10.153.223.157:22 R&gt; 69.53.245.40:34619 已建立
01:55:05 0 4 10.153.223.157:22 R&gt; 69.53.245.40:34619 已建立
01:55:17 0 4 10.153.223.157:22 R&gt; 69.53.245.40:22957 已建立
[...]
</code></pre>
<p>tcprerans prints one line of output for every TCP retransmit packet, with details including source and destination addresses, and kernel state of the TCP connection.</p>
<p>TCP retransmissions cause latency and throughput issues. For ESTABLISHED retransmits, look for patterns with networks. For SYN_SENT, this may point to target kernel CPU saturation and kernel packet drops.</p>
<p>More <a href="https://github.com/iovisor/bcc/tree/master/tools/tcpretrans_example.txt">examples</a>.</p>
<p>tcpretrans为每个TCP重传数据包打印一行输出其中包括源地址、目的地址以及TCP连接的内核状态。</p>
<p>TCP重传会导致延迟和吞吐量问题。对于已建立的重传可以查找与网络有关的模式。对于SYN_SENT可能指向目标内核CPU饱和和内核数据包丢失。</p>
<p>更多<a href="https://github.com/iovisor/bcc/tree/master/tools/tcpretrans_example.txt">示例</a></p>
<h4 id="110-runqlat"><a class="header" href="#110-runqlat">1.10. runqlat</a></h4>
<pre><code class="language-sh"># ./runqlat
Tracing run queue latency... Hit Ctrl-C to end.
跟踪运行队列延迟... 按Ctrl-C结束。
^C
usecs : count distribution
微秒数 : 计数 分布
0 -&gt; 1 : 233 |*********** |
2 -&gt; 3 : 742 |************************************ |
4 -&gt; 7 : 203 |********** |
@@ -351,19 +349,17 @@ Tracing run queue latency... Hit Ctrl-C to end.
1024 -&gt; 2047 : 27 |* |
2048 -&gt; 4095 : 30 |* |
4096 -&gt; 8191 : 20 | |
8192 -&gt; 16383 : 29 |* |
16384 -&gt; 32767 : 809 |****************************************|
32768 -&gt; 65535 : 64 |*** |
8192 -&gt; 16383 : 29 |* |&quot;.16384 -&gt; 32767 : 809 |****************************************|
32768 -&gt; 65535 : 64 |*** |
</code></pre>
<p>runqlat times how long threads were waiting on the CPU run queues, and prints this as a histogram.</p>
<p>This can help quantify time lost waiting for a turn on CPU, during periods of CPU saturation.</p>
<p>More <a href="https://github.com/iovisor/bcc/tree/master/tools/runqlat_example.txt">examples</a>.</p>
<h4 id="111-profile"><a class="header" href="#111-profile">1.11. profile</a></h4>
<p>这可以帮助量化在CPU饱和期间等待获取CPU的时间损失。</p>
<p>更多<a href="https://github.com/iovisor/bcc/tree/master/tools/runqlat_example.txt">示例</a></p>
<h4 id="111-分析"><a class="header" href="#111-分析">1.11. 分析</a></h4>
<pre><code class="language-sh"># ./profile
Sampling at 49 Hertz of all threads by user + kernel stack... Hit Ctrl-C to end.
以每秒49次的频率对所有线程进行采样包括用户和内核栈...按Ctrl-C结束。
^C
00007f31d76c3251 [unknown]
47a2c1e752bf47f7 [unknown]
00007f31d76c3251 [未知]
47a2c1e752bf47f7 [未知]
- sign-file (8877)
1
@@ -381,7 +377,7 @@ Sampling at 49 Hertz of all threads by user + kernel stack... Hit Ctrl-C to end.
0000000000400542 func_a
0000000000400598 main
00007f12a133e830 __libc_start_main
083e258d4c544155 [unknown]
083e258d4c544155 [未知]
- func_ab (13549)
5
@@ -396,20 +392,19 @@ Sampling at 49 Hertz of all threads by user + kernel stack... Hit Ctrl-C to end.
- swapper/1 (0)
75
</code></pre>
<p>profile is a CPU profiler, which takes samples of stack traces at timed intervals, and prints a summary of unique stack traces and a count of their occurrence.</p>
<p>Use this tool to understand the code paths that are consuming CPU resources.</p>
<p>More <a href="https://github.com/iovisor/bcc/tree/master/tools/profile_example.txt">examples</a>.</p>
<h3 id="2-observability-with-generic-tools"><a class="header" href="#2-observability-with-generic-tools">2. Observability with Generic Tools</a></h3>
<p>In addition to the above tools for performance tuning, below is a checklist for bcc generic tools, first as a list, and in detail:</p>
<p>profile是一个CPU分析工具它在定时间隔内采样堆栈跟踪并打印唯一堆栈跟踪的摘要及其出现次数。</p>
<p>使用此工具来了解消耗CPU资源的代码路径。</p>
<p>更多<a href="https://github.com/iovisor/bcc/tree/master/tools/profile_example.txt">示例</a></p>
<h3 id="2-使用通用工具进行可观察性"><a class="header" href="#2-使用通用工具进行可观察性">2. 使用通用工具进行可观察性</a></h3>
<p>除了上述用于性能调整的工具外下面是一个bcc通用工具的清单首先是一个列表然后详细说明</p>
<ol>
<li>trace</li>
<li>argdist</li>
<li>funccount</li>
<li>funccount这些通用工具可能有助于解决您特定问题的可视化。</li>
</ol>
<p>These generic tools may be useful to provide visibility to solve your specific problems.</p>
<h4 id="21-trace"><a class="header" href="#21-trace">2.1. trace</a></h4>
<h5 id="example-1"><a class="header" href="#example-1">Example 1</a></h5>
<p>Suppose you want to track file ownership change. There are three syscalls, <code>chown</code>, <code>fchown</code> and <code>lchown</code> which users can use to change file ownership. The corresponding syscall entry is <code>SyS_[f|l]chown</code>. The following command can be used to print out syscall parameters and the calling process user id. You can use <code>id</code> command to find the uid of a particular user.</p>
<h4 id="21-跟踪"><a class="header" href="#21-跟踪">2.1. 跟踪</a></h4>
<h5 id="示例-1"><a class="header" href="#示例-1">示例 1</a></h5>
<p>假设您想要跟踪文件所有权更改。有三个系统调用,<code>chown</code><code>fchown</code><code>lchown</code>,用户可以使用它们来更改文件所有权。相应的系统调用入口是<code>SyS_[f|l]chown</code>。可以使用以下命令打印系统调用参数和调用进程的用户ID。您可以使用<code>id</code>命令查找特定用户的UID。</p>
<pre><code class="language-sh">$ trace.py \
'p::SyS_chown &quot;file = %s, to_uid = %d, to_gid = %d, from_uid = %d&quot;, arg1, arg2, arg3, $uid' \
'p::SyS_fchown &quot;fd = %d, to_uid = %d, to_gid = %d, from_uid = %d&quot;, arg1, arg2, arg3, $uid' \
@@ -421,14 +416,14 @@ PID TID COMM FUNC -
1269442 1269442 zstd SyS_chown file = /tmp/dotsync-gzp413o_/dotsync-package.zst, to_uid = 128203, to_gid = 100, from_uid = 128203
1269255 1269255 python3.6 SyS_lchown file = /tmp/dotsync-whx4fivm/tmp/.bash_profile, to_uid = 128203, to_gid = 100, from_uid = 128203
</code></pre>
<h5 id="example-2"><a class="header" href="#example-2">Example 2</a></h5>
<p>Suppose you want to count nonvoluntary context switches (<code>nvcsw</code>) in your bpf based performance monitoring tools and you do not know what is the proper method. <code>/proc/&lt;pid&gt;/status</code> already tells you the number (<code>nonvoluntary_ctxt_switches</code>) for a pid and you can use <code>trace.py</code> to do a quick experiment to verify your method. With kernel source code, the <code>nvcsw</code> is counted at file <code>linux/kernel/sched/core.c</code> function <code>__schedule</code> and under condition</p>
<pre><code class="language-c">!(!preempt &amp;&amp; prev-&gt;state) // i.e., preempt || !prev-&gt;state
<h5 id="示例-2"><a class="header" href="#示例-2">示例 2</a></h5>
<p>假设您想要统计基于bpf的性能监控工具中的非自愿上下文切换<code>nvcsw</code>),而您不知道正确的方法是什么。<code>/proc/&lt;pid&gt;/status</code>已经告诉您进程的非自愿上下文切换(<code>nonvoluntary_ctxt_switches</code>)的数量,并且您可以使用<code>trace.py</code>进行快速实验以验证您的方法。根据内核源代码,<code>nvcsw</code>在文件<code>linux/kernel/sched/core.c</code><code>__schedule</code>函数中计数,并满足以下条件:</p>
<pre><code class="language-c">.!(!preempt &amp;&amp; prev-&gt;state) // preempt || !prev-&gt;state
</code></pre>
<p>The <code>__schedule</code> function is marked as <code>notrace</code>, and the best place to evaluate the above condition seems in <code>sched/sched_switch</code> tracepoint called inside function <code>__schedule</code> and defined in <code>linux/include/trace/events/sched.h</code>. <code>trace.py</code> already has <code>args</code> being the pointer to the tracepoint <code>TP_STRUCT__entry</code>. The above condition in function <code>__schedule</code> can be represented as</p>
<p><code>__schedule</code> 函数被标记为 <code>notrace</code> ,评估上述条件的最佳位置似乎在函数 <code>__schedule</code> 内部的 <code>sched/sched_switch</code> 跟踪点中,并且在 <code>linux/include/trace/events/sched.h</code> 中定义。<code>trace.py</code> 已经将 <code>args</code> 设置为跟踪点 <code>TP_STRUCT__entry</code> 的指针。函数 <code>__schedule</code> 中的上述条件可以表示为</p>
<pre><code class="language-c">args-&gt;prev_state == TASK_STATE_MAX || args-&gt;prev_state == 0
</code></pre>
<p>The below command can be used to count the involuntary context switches (per process or per pid) and compare to <code>/proc/&lt;pid&gt;/status</code> or <code>/proc/&lt;pid&gt;/task/&lt;task_id&gt;/status</code> for correctness, as in typical cases, involuntary context switches are not very common.</p>
<p>可以使用以下命令来计算非自愿上下文切换每个进程或每个进程ID并与 <code>/proc/&lt;pid&gt;/status</code> <code>/proc/&lt;pid&gt;/task/&lt;task_id&gt;/status</code> 进行比较,以确保正确性,因为在典型情况下,非自愿上下文切换并不常见。</p>
<pre><code class="language-sh">$ trace.py -p 1134138 't:sched:sched_switch (args-&gt;prev_state == TASK_STATE_MAX || args-&gt;prev_state == 0)'
PID TID COMM FUNC
1134138 1134140 contention_test sched_switch
@@ -440,45 +435,44 @@ PID TID COMM FUNC
1134138 1134140 contention_test sched_switch
...
</code></pre>
<h5 id="example-3"><a class="header" href="#example-3">Example 3</a></h5>
<p>This example is related to issue <a href="https://github.com/iovisor/bcc/issues/1231">1231</a> and <a href="https://github.com/iovisor/bcc/issues/1516">1516</a> where uprobe does not work at all in certain cases. First, you can do a <code>strace</code> as below</p>
<h5 id="示例-3"><a class="header" href="#示例-3">示例 3</a></h5>
<p>此示例与问题 <a href="https://github.com/iovisor/bcc/issues/1231">1231</a> <a href="https://github.com/iovisor/bcc/issues/1516">1516</a> 相关其中在某些情况下uprobes 完全无法工作。首先,你可以执行以下 <code>strace</code></p>
<pre><code class="language-sh">$ strace trace.py 'r:bash:readline &quot;%s&quot;, retval'
...
perf_event_open(0x7ffd968212f0, -1, 0, -1, 0x8 /* PERF_FLAG_??? */) = -1 EIO (Input/output error)
...
</code></pre>
<p>The <code>perf_event_open</code> syscall returns <code>-EIO</code>. Digging into kernel uprobe related codes in <code>/kernel/trace</code> and <code>/kernel/events</code> directories to search <code>EIO</code>, the function <code>uprobe_register</code> is the most suspicious. Let us find whether this function is called or not and what is the return value if it is called. In one terminal using the following command to print out the return value of uprobe_register,</p>
<pre><code class="language-sh">$ trace.py 'r::uprobe_register &quot;ret = %d&quot;, retval'
<p><code>perf_event_open</code>系统调用返回<code>-EIO</code>。在<code>/kernel/trace</code><code>/kernel/events</code>目录中查找与<code>EIO</code>相关的内核uprobe代码函数<code>uprobe_register</code>最可疑。让我们找出是否调用了这个函数,如果调用了,返回值是什么。在一个终端中使用以下命令打印出<code>uprobe_register</code>的返回值:</p>
<pre><code class="language-sh">trace.py 'r::uprobe_register &quot;ret = %d&quot;, retval'
</code></pre>
<p>In another terminal run the same bash uretprobe tracing example, and you should get</p>
<p>在另一个终端中运行相同的bash uretprobe跟踪示例您应该得到</p>
<pre><code class="language-sh">$ trace.py 'r::uprobe_register &quot;ret = %d&quot;, retval'
PID TID COMM FUNC -
1041401 1041401 python2.7 uprobe_register ret = -5
</code></pre>
<p>The <code>-5</code> error code is EIO. This confirms that the following code in function <code>uprobe_register</code> is the most suspicious culprit.</p>
<p>错误代码<code>-5</code>是EIO。这证实了函数<code>uprobe_register</code>中的以下代码是最可疑的罪魁祸首。</p>
<pre><code class="language-c"> if (!inode-&gt;i_mapping-&gt;a_ops-&gt;readpage &amp;&amp; !shmem_mapping(inode-&gt;i_mapping))
return -EIO;
</code></pre>
<p>The <code>shmem_mapping</code> function is defined as</p>
<p><code>shmem_mapping</code>函数定义如下:</p>
<pre><code class="language-c">bool shmem_mapping(struct address_space *mapping)
{
return mapping-&gt;a_ops == &amp;shmem_aops;
}
</code></pre>
<p>To confirm the theory, find what is <code>inode-&gt;i_mapping-&gt;a_ops</code> with the following command</p>
<p>为了确认这个理论,使用以下命令找出<code>inode-&gt;i_mapping-&gt;a_ops</code>的值:</p>
<pre><code class="language-sh">$ trace.py -I 'linux/fs.h' 'p::uprobe_register(struct inode *inode) &quot;a_ops = %llx&quot;, inode-&gt;i_mapping-&gt;a_ops'
PID TID COMM FUNC -
814288 814288 python2.7 uprobe_register a_ops = ffffffff81a2adc0
^C$ grep ffffffff81a2adc0 /proc/kallsyms
ffffffff81a2adc0 R empty_aops
</code></pre>
<p>The kernel symbol <code>empty_aops</code> does not have <code>readpage</code> defined and hence the above suspicious condition is true. Further examining the kernel source code shows that <code>overlayfs</code> does not provide its own <code>a_ops</code> while some other file systems (e.g., ext4) define their own <code>a_ops</code> (e.g., <code>ext4_da_aops</code>), and <code>ext4_da_aops</code> defines <code>readpage</code>. Hence, uprobe works fine on ext4 while not on overlayfs.</p>
<p>More <a href="https://github.com/iovisor/bcc/tree/master/tools/trace_example.txt">examples</a>.</p>
<h4 id="22-argdist"><a class="header" href="#22-argdist">2.2. argdist</a></h4>
<p>More <a href="https://github.com/iovisor/bcc/tree/master/tools/argdist_example.txt">examples</a>.</p>
<p>内核符号<code>empty_aops</code>没有定义<code>readpage</code>,因此上述可疑条件为真。进一步检查内核源代码显示,<code>overlayfs</code>没有提供自己的<code>a_ops</code>而其他一些文件系统例如ext4定义了自己的<code>a_ops</code>(例如<code>ext4_da_aops</code>),并且<code>ext4_da_aops</code>定义了<code>readpage</code>。因此uprobe对于ext4正常工作但在overlayfs上不正常工作。</p>
<p>更多<a href="https://github.com/iovisor/bcc/tree/master/tools/trace_example.txt">示例</a></p>
<h4 id="22-argdist更多示例"><a class="header" href="#22-argdist更多示例">2.2. argdist&quot;。更多<a href="https://github.com/iovisor/bcc/tree/master/tools/argdist_example.txt">示例</a></a></h4>
<h4 id="23-funccount"><a class="header" href="#23-funccount">2.3. funccount</a></h4>
<p>More <a href="https://github.com/iovisor/bcc/tree/master/tools/funccount_example.txt">examples</a>.</p>
<h2 id="networking"><a class="header" href="#networking">Networking</a></h2>
<p>更多<a href="https://github.com/iovisor/bcc/tree/master/tools/funccount_example.txt">示例</a>.</p>
<h2 id="网络"><a class="header" href="#网络">网络</a></h2>
<p>To do.</p>
</main>

View File

@@ -166,74 +166,74 @@
<div id="content" class="content">
<main>
<h1 id="bcc-python-developer-tutorial"><a class="header" href="#bcc-python-developer-tutorial">bcc Python Developer Tutorial</a></h1>
<p>This tutorial is about developing <a href="https://github.com/iovisor/bcc">bcc</a> tools and programs using the Python interface. There are two parts: observability then networking. Snippets are taken from various programs in bcc: see their files for licences.</p>
<p>Also see the bcc developer's <a href="reference_guide.html">reference_guide.md</a>, and a tutorial for end-users of tools: <a href="tutorial.html">tutorial.md</a>. There is also a lua interface for bcc.</p>
<h2 id="observability"><a class="header" href="#observability">Observability</a></h2>
<p>This observability tutorial contains 17 lessons, and 46 enumerated things to learn.</p>
<h3 id="lesson-1-hello-world"><a class="header" href="#lesson-1-hello-world">Lesson 1. Hello World</a></h3>
<p>Start by running <a href="https://github.com/iovisor/bcc/tree/master/examples/hello_world.py">examples/hello_world.py</a>, while running some commands (eg, &quot;ls&quot;) in another session. It should print &quot;Hello, World!&quot; for new processes. If not, start by fixing bcc: see <a href="https://github.com/iovisor/bcc/tree/master/INSTALL.md">INSTALL.md</a>.</p>
<h1 id="bcc-python-开发者教程"><a class="header" href="#bcc-python-开发者教程">bcc Python 开发者教程</a></h1>
<p>本教程介绍使用 Python 接口开发 <a href="https://github.com/iovisor/bcc">bcc</a> 工具和程序。分为两个部分:可观测性和网络。代码片段取自 bcc 的各个程序,请查阅其文件以了解许可证情况。</p>
<p>还请参阅 bcc 开发者的<a href="reference_guide.html">参考指南</a>,以及针对工具的用户的教程:<a href="tutorial.html">教程</a>。还有适用于 bcc 的 lua 接口。</p>
<h2 id="可观测性"><a class="header" href="#可观测性">可观测性</a></h2>
<p>这个可观测性教程包含17个课程和46个要学习的枚举事项。</p>
<h3 id="第1课-你好世界"><a class="header" href="#第1课-你好世界">第1课. 你好,世界</a></h3>
<p>首先运行 <a href="https://github.com/iovisor/bcc/tree/master/examples/hello_world.py">examples/hello_world.py</a>同时在另一个会话中运行一些命令例如“ls”。它应该会为新进程打印“Hello, World!”。如果没有打印请先修复bcc请参阅 <a href="https://github.com/iovisor/bcc/tree/master/INSTALL.md">INSTALL.md</a></p>
<pre><code class="language-sh"># ./examples/hello_world.py
bash-13364 [002] d... 24573433.052937: : Hello, World!
bash-13364 [003] d... 24573436.642808: : Hello, World!
[...]
</code></pre>
<p>Here's the code for hello_world.py:</p>
<p>以下是 hello_world.py 的代码示例:</p>
<pre><code class="language-Python">from bcc import BPF
BPF(text='int kprobe__sys_clone(void *ctx) { bpf_trace_printk(&quot;Hello, World!\\n&quot;); return 0; }').trace_print()
</code></pre>
<p>There are six things to learn from this:</p>
<p>从中可以学到六件事情:</p>
<ol>
<li>
<p><code>text='...'</code>: This defines a BPF program inline. The program is written in C.</p>
<p><code>text='...'</code>:这定义了内联的 BPF 程序。该程序是用 C 编写的。</p>
</li>
<li>
<p><code>kprobe__sys_clone()</code>: This is a short-cut for kernel dynamic tracing via kprobes. If the C function begins with <code>kprobe__</code>, the rest is treated as a kernel function name to instrument, in this case, <code>sys_clone()</code>.</p>
<p><code>kprobe__sys_clone()</code>:这是通过 kprobes 动态跟踪内核的一种快捷方式。如果 C 函数以 <code>kprobe__</code> 开头,其余部分将被视为要定位的内核函数名称,本例中为 <code>sys_clone()</code></p>
</li>
<li>
<p><code>void *ctx</code>: ctx has arguments, but since we aren't using them here, we'll just cast it to <code>void *</code>.</p>
<p><code>void *ctx</code>ctx 是参数,但由于我们在此处未使用它们,所以我们将其转换为 <code>void*</code> 类型。</p>
</li>
<li>
<p><code>bpf_trace_printk()</code>: A simple kernel facility for printf() to the common trace_pipe (/sys/kernel/debug/tracing/trace_pipe). This is ok for some quick examples, but has limitations: 3 args max, 1 %s only, and trace_pipe is globally shared, so concurrent programs will have clashing output. A better interface is via BPF_PERF_OUTPUT(), covered later.</p>
<p><code>bpf_trace_printk()</code>: 用于将 printf() 打印到通用 trace_pipe (/sys/kernel/debug/tracing/trace_pipe) 的简单内核工具。 这对于一些快速示例是可以的,但有一些限制:最多只有 3 个参数,只能有一个 %s并且 trace_pipe 是全局共享的,所以并发程序会有冲突的输出。更好的接口是通过 BPF_PERF_OUTPUT() 实现的,稍后会介绍。</p>
</li>
<li>
<p><code>return 0;</code>: Necessary formality (if you want to know why, see <a href="https://github.com/iovisor/bcc/issues/139">#139</a>).</p>
<p><code>return 0;</code>: 必要的规范性代码(如果想知道原因,请参见 <a href="https://github.com/iovisor/bcc/issues/139">#139</a>)。</p>
</li>
<li>
<p><code>.trace_print()</code>: A bcc routine that reads trace_pipe and prints the output.</p>
<p><code>.trace_print()</code>: 一个读取 trace_pipe 并打印输出的 bcc 程序。</p>
</li>
</ol>
<h3 id="lesson-2-sys_sync"><a class="header" href="#lesson-2-sys_sync">Lesson 2. sys_sync()</a></h3>
<p>Write a program that traces the sys_sync() kernel function. Print &quot;sys_sync() called&quot; when it runs. Test by running <code>sync</code> in another session while tracing. The hello_world.py program has everything you need for this.</p>
<p>Improve it by printing &quot;Tracing sys_sync()... Ctrl-C to end.&quot; when the program first starts. Hint: it's just Python.</p>
<h3 id="lesson-3-hello_fieldspy"><a class="header" href="#lesson-3-hello_fieldspy">Lesson 3. hello_fields.py</a></h3>
<p>This program is in <a href="https://github.com/iovisor/bcc/tree/master/examples/tracing/hello_fields.py">examples/tracing/hello_fields.py</a>. Sample output (run commands in another session):</p>
<h3 id="第二课-sys_sync"><a class="header" href="#第二课-sys_sync">第二课 sys_sync()</a></h3>
<p>编写一个跟踪 sys_sync() 内核函数的程序。运行时打印 &quot;sys_sync() called&quot;。在跟踪时,在另一个会话中运行 <code>sync</code> 进行测试。hello_world.py 程序中包含了这一切所需的内容。</p>
<p>通过在程序刚启动时打印 &quot;Tracing sys_sync()... Ctrl-C to end.&quot; 来改进它。提示:它只是 Python 代码。</p>
<h3 id="第三课-hello_fieldspy"><a class="header" href="#第三课-hello_fieldspy">第三课 hello_fields.py</a></h3>
<p>该程序位于 <a href="https://github.com/iovisor/bcc/tree/master/examples/tracing/hello_fields.py">examples/tracing/hello_fields.py</a>。样本输出(在另一个会话中运行命令):</p>
<pre><code class="language-sh"># examples/tracing/hello_fields.py
TIME(s) COMM PID MESSAGE
24585001.174885999 sshd 1432 Hello, World!
24585001.195710000 sshd 15780 Hello, World!
24585001.991976000 systemd-udevd 484 Hello, World!
24585002.276147000 bash 15787 Hello, World!
时间(s) 进程名 进程 ID 消息
24585001.174885999 sshd 1432 你好,世界!
24585001.195710000 sshd 15780 你好,世界!
24585001.991976000 systemd-udevd 484 你好,世界!
24585002.276147000 bash 15787 你好,世界!
</code></pre>
<p>Code:</p>
<p>代码:</p>
<pre><code class="language-Python">from bcc import BPF
# define BPF program
# 定义 BPF 程序
prog = &quot;&quot;&quot;
int hello(void *ctx) {
bpf_trace_printk(&quot;Hello, World!\\n&quot;);
bpf_trace_printk(&quot;你好,世界!\\n&quot;);
return 0;
}
&quot;&quot;&quot;
# load BPF program
# 加载 BPF 程序
b = BPF(text=prog)
b.attach_kprobe(event=b.get_syscall_fnname(&quot;clone&quot;), fn_name=&quot;hello&quot;)
# header
print(&quot;%-18s %-16s %-6s %s&quot; % (&quot;TIME(s)&quot;, &quot;COMM&quot;, &quot;PID&quot;, &quot;MESSAGE&quot;))
# 头部
print(&quot;%-18s %-16s %-6s %s&quot; % (&quot;时间(s)&quot;, &quot;进程名&quot;, &quot;进程 ID&quot;, &quot;消息&quot;))
# format output
# 格式化输出
while 1:
try:
(task, pid, cpu, flags, ts, msg) = b.trace_fields()
@@ -241,34 +241,34 @@ while 1:
continue
print(&quot;%-18.9f %-16s %-6d %s&quot; % (ts, task, pid, msg))
</code></pre>
<p>This is similar to hello_world.py, and traces new processes via sys_clone() again, but has a few more things to learn:</p>
<p>这与hello_world.py类似并通过sys_clone()再次跟踪新进程,但是还有一些要学习的内容:</p>
<ol>
<li>
<p><code>prog =</code>: This time we declare the C program as a variable, and later refer to it. This is useful if you want to add some string substitutions based on command line arguments.</p>
<p><code>prog =</code>这次我们将C程序声明为变量然后引用它。如果您想根据命令行参数添加一些字符串替换这将非常有用。</p>
</li>
<li>
<p><code>hello()</code>: Now we're just declaring a C function, instead of the <code>kprobe__</code> shortcut. We'll refer to this later. All C functions declared in the BPF program are expected to be executed on a probe, hence they all need to take a <code>pt_reg* ctx</code> as first argument. If you need to define some helper function that will not be executed on a probe, they need to be defined as <code>static inline</code> in order to be inlined by the compiler. Sometimes you would also need to add <code>_always_inline</code> function attribute to it.</p>
<p><code>hello()</code>现在我们只是声明了一个C函数而不是使用<code>kprobe__</code>的快捷方式。我们稍后会引用它。在BPF程序中声明的所有C函数都希望在探测器上执行因此它们都需要以<code>pt_reg* ctx</code>作为第一个参数。如果您需要定义一些不会在探测器上执行的辅助函数,则需要将其定义为<code>static inline</code>,以便由编译器内联。有时您还需要为其添加<code>_always_inline</code>函数属性。</p>
</li>
<li>
<p><code>b.attach_kprobe(event=b.get_syscall_fnname(&quot;clone&quot;), fn_name=&quot;hello&quot;)</code>: Creates a kprobe for the kernel clone system call function, which will execute our defined hello() function. You can call attach_kprobe() more than once, and attach your C function to multiple kernel functions.</p>
<p><code>b.attach_kprobe(event=b.get_syscall_fnname(&quot;clone&quot;), fn_name=&quot;hello&quot;)</code>为内核clone系统调用函数创建一个kprobe该函数将执行我们定义的hello()函数。您可以多次调用attach_kprobe()并将您的C函数附加到多个内核函数上。</p>
</li>
<li>
<p><code>b.trace_fields()</code>: Returns a fixed set of fields from trace_pipe. Similar to trace_print(), this is handy for hacking, but for real tooling we should switch to BPF_PERF_OUTPUT().</p>
<p><code>b.trace_fields()</code>从trace_pipe中返回一组固定的字段。与trace_print()类似,它对于编写脚本很方便,但是对于实际的工具化需求,我们应该切换到BPF_PERF_OUTPUT()</p>
</li>
</ol>
<h3 id="lesson-4-sync_timingpy"><a class="header" href="#lesson-4-sync_timingpy">Lesson 4. sync_timing.py</a></h3>
<p>Remember the days of sysadmins typing <code>sync</code> three times on a slow console before <code>reboot</code>, to give the first asynchronous sync time to complete? Then someone thought <code>sync;sync;sync</code> was clever, to run them all on one line, which became industry practice despite defeating the original purpose! And then sync became synchronous, so more reasons it was silly. Anyway.</p>
<p>The following example times how quickly the <code>do_sync</code> function is called, and prints output if it has been called more recently than one second ago. A <code>sync;sync;sync</code> will print output for the 2nd and 3rd sync's:</p>
<p>还记得以前系统管理员在缓慢的控制台上输入<code>sync</code>三次然后才重启吗?后来有人认为<code>sync;sync;sync</code>很聪明将它们都写在一行上运行尽管这违背了最初的目的然后sync变成了同步操作所以更加愚蠢。无论如何。</p>
<p>以下示例计算了<code>do_sync</code>函数被调用的速度,并且如果它在一秒钟之内被调用,则输出信息。<code>sync;sync;sync</code>将为第2个和第3个sync打印输出</p>
<pre><code class="language-sh"># examples/tracing/sync_timing.py
Tracing for quick sync's... Ctrl-C to end
At time 0.00 s: multiple syncs detected, last 95 ms ago
At time 0.10 s: multiple syncs detected, last 96 ms ago
追踪快速sync... Ctrl-C结束&quot;
</code></pre>
<p>This program is <a href="https://github.com/iovisor/bcc/tree/master/examples/tracing/sync_timing.py">examples/tracing/sync_timing.py</a>:</p>
<p>在时间0.00秒时检测到多个同步上次发生在95毫秒前
在时间0.10秒时检测到多个同步上次发生在96毫秒前</p>
<p>此程序是<a href="https://github.com/iovisor/bcc/tree/master/examples/tracing/sync_timing.py">examples/tracing/sync_timing.py</a></p>
<pre><code class="language-Python">from __future__ import print_function
from bcc import BPF
# load BPF program
# 加载BPF程序
b = BPF(text=&quot;&quot;&quot;
#include &lt;uapi/linux/ptrace.h&gt;
@@ -277,18 +277,18 @@ BPF_HASH(last);
int do_trace(struct pt_regs *ctx) {
u64 ts, *tsp, delta, key = 0;
// attempt to read stored timestamp
// 尝试读取存储的时间戳
tsp = last.lookup(&amp;key);
if (tsp != NULL) {
delta = bpf_ktime_get_ns() - *tsp;
if (delta &lt; 1000000000) {
// output if time is less than 1 second
// 时间小于1秒则输出
bpf_trace_printk(&quot;%d\\n&quot;, delta / 1000000);
}
last.delete(&amp;key);
}
// update stored timestamp
// 更新存储的时间戳
ts = bpf_ktime_get_ns();
last.update(&amp;key, &amp;ts);
return 0;
@@ -296,44 +296,43 @@ int do_trace(struct pt_regs *ctx) {
&quot;&quot;&quot;)
b.attach_kprobe(event=b.get_syscall_fnname(&quot;sync&quot;), fn_name=&quot;do_trace&quot;)
print(&quot;Tracing for quick sync's... Ctrl-C to end&quot;)
print(&quot;跟踪快速同步... Ctrl-C结束&quot;)
# format output
# 格式化输出
start = 0
while 1:
(task, pid, cpu, flags, ts, ms) = b.trace_fields()
if start == 0:
start = ts
ts = ts - start
print(&quot;At time %.2f s: multiple syncs detected, last %s ms ago&quot; % (ts, ms))
print(&quot;在时间%.2f秒处:检测到多个同步,上次发生在%s毫秒前&quot; % (ts, ms))
</code></pre>
<p>Things to learn:</p>
<p>学习内容:</p>
<ol>
<li><code>bpf_ktime_get_ns()</code>: Returns the time as nanoseconds.</li>
<li><code>BPF_HASH(last)</code>: Creates a BPF map object that is a hash (associative array), called &quot;last&quot;. We didn't specify any further arguments, so it defaults to key and value types of u64.</li>
<li><code>key = 0</code>: We'll only store one key/value pair in this hash, where the key is hardwired to zero.</li>
<li><code>last.lookup(&amp;key)</code>: Lookup the key in the hash, and return a pointer to its value if it exists, else NULL. We pass the key in as an address to a pointer.</li>
<li><code>if (tsp != NULL) {</code>: The verifier requires that pointer values derived from a map lookup must be checked for a null value before they can be dereferenced and used.</li>
<li><code>last.delete(&amp;key)</code>: Delete the key from the hash. This is currently required because of <a href="https://git.kernel.org/cgit/linux/kernel/git/davem/net.git/commit/?id=a6ed3ea65d9868fdf9eff84e6fe4f666b8d14b02">a kernel bug in <code>.update()</code></a> (fixed in 4.8.10).</li>
<li><code>last.update(&amp;key, &amp;ts)</code>: Associate the value in the 2nd argument to the key, overwriting any previous value. This records the timestamp.</li>
<li><code>bpf_ktime_get_ns()</code>: 返回时间,单位为纳秒。</li>
<li><code>BPF_HASH(last)</code>: 创建一个BPF映射对象类型为哈希关联数组名为&quot;last&quot;。我们没有指定其他参数,因此默认的键和值类型为u64</li>
<li><code>key = 0</code>: 我们只会在哈希中存储一个键值对,其中键被硬编码为零。</li>
<li><code>last.lookup(&amp;key)</code>: 在哈希中查找键并如果存在则返回其值的指针否则返回NULL。我们将键作为指针的地址传递给该函数。</li>
<li><code>if (tsp != NULL) {</code>: 验证器要求在将从映射查找得到的指针值解引用使用之前必须先检查其是否为null。1. <code>last.delete(&amp;key)</code>: 从哈希表中删除key。目前需要这样做是因为<a href="https://git.kernel.org/cgit/linux/kernel/git/davem/net.git/commit/?id=a6ed3ea65d9868fdf9eff84e6fe4f666b8d14b02"><code>.update()</code>中存在一个内核错误</a>在4.8.10中已经修复)。</li>
<li><code>last.update(&amp;key, &amp;ts)</code>: 将第二个参数的值与key关联起来覆盖之前的任何值。这会记录时间戳。</li>
</ol>
<h3 id="lesson-5-sync_countpy"><a class="header" href="#lesson-5-sync_countpy">Lesson 5. sync_count.py</a></h3>
<p>Modify the sync_timing.py program (prior lesson) to store the count of all kernel sync system calls (both fast and slow), and print it with the output. This count can be recorded in the BPF program by adding a new key index to the existing hash.</p>
<h3 id="lesson-6-disksnooppy"><a class="header" href="#lesson-6-disksnooppy">Lesson 6. disksnoop.py</a></h3>
<p>Browse the <a href="https://github.com/iovisor/bcc/tree/master/examples/tracing/disksnoop.py">examples/tracing/disksnoop.py</a> program to see what is new. Here is some sample output:</p>
<h3 id="第5课-sync_countpy"><a class="header" href="#第5课-sync_countpy">第5课. sync_count.py</a></h3>
<p>修改sync_timing.py程序前一课以存储所有内核同步系统调用包括快速和慢速的计数并将其与输出一起打印出来。可以通过向现有哈希表添加一个新的键索引来在BPF程序中记录此计数。</p>
<h3 id="第6课-disksnooppy"><a class="header" href="#第6课-disksnooppy">第6课. disksnoop.py</a></h3>
<p>浏览<a href="https://github.com/iovisor/bcc/tree/master/examples/tracing/disksnoop.py">examples/tracing/disksnoop.py</a>程序以了解新内容。以下是一些示例输出:</p>
<pre><code class="language-sh"># disksnoop.py
TIME(s) T BYTES LAT(ms)
时间(s) T 字节 延迟(ms)
16458043.436012 W 4096 3.13
16458043.437326 W 4096 4.44
16458044.126545 R 4096 42.82
16458044.129872 R 4096 3.24
[...]
</code></pre>
<p>And a code snippet:</p>
<p>以及代码片段:</p>
<pre><code class="language-Python">[...]
REQ_WRITE = 1 # from include/linux/blk_types.h
REQ_WRITE = 1 # 来自include/linux/blk_types.h
# load BPF program
# 加载BPF程序
b = BPF(text=&quot;&quot;&quot;
#include &lt;uapi/linux/ptrace.h&gt;
#include &lt;linux/blk-mq.h&gt;
@@ -341,59 +340,57 @@ b = BPF(text=&quot;&quot;&quot;
BPF_HASH(start, struct request *);
void trace_start(struct pt_regs *ctx, struct request *req) {
// stash start timestamp by request ptr
u64 ts = bpf_ktime_get_ns();
// 使用请求指针存储开始时间戳
u64 ts = bpf_ktime_get_ns();
start.update(&amp;req, &amp;ts);
start.update(&amp;req, &amp;ts);
}
void trace_completion(struct pt_regs *ctx, struct request *req) {
u64 *tsp, delta;
u64 *tsp, delta;
tsp = start.lookup(&amp;req);
if (tsp != 0) {
delta = bpf_ktime_get_ns() - *tsp;
bpf_trace_printk(&quot;%d %x %d\\n&quot;, req-&gt;__data_len,
req-&gt;cmd_flags, delta / 1000);
start.delete(&amp;req);
}
tsp = start.lookup(&amp;req);
if (tsp != 0) {
delta = bpf_ktime_get_ns() - *tsp;
bpf_trace_printk(&quot;%d %x %d\\n&quot;, req-&gt;__data_len,
req-&gt;cmd_flags, delta / 1000);
start.delete(&amp;req);
}
}
&quot;&quot;&quot;)
if BPF.get_kprobe_functions(b'blk_start_request'):
b.attach_kprobe(event=&quot;blk_start_request&quot;, fn_name=&quot;trace_start&quot;)
b.attach_kprobe(event=&quot;blk_mq_start_request&quot;, fn_name=&quot;trace_start&quot;)
if BPF.get_kprobe_functions(b'__blk_account_io_done'):
b.attach_kprobe(event=&quot;__blk_account_io_done&quot;, fn_name=&quot;trace_completion&quot;)
else:
b.attach_kprobe(event=&quot;blk_account_io_done&quot;, fn_name=&quot;trace_completion&quot;)
[...]
b.attach_kprobe(event=&quot;__blk_account_io_done&quot;, fn_name=&quot;trace_completion&quot;) else: b.attach_kprobe(event=&quot;blk_account_io_done&quot;, fn_name=&quot;trace_completion&quot;)
[...]
</code></pre>
<p>Things to learn:</p>
<p>学习内容:</p>
<ol>
<li><code>REQ_WRITE</code>: We're defining a kernel constant in the Python program because we'll use it there later. If we were using REQ_WRITE in the BPF program, it should just work (without needing to be defined) with the appropriate #includes.</li>
<li><code>trace_start(struct pt_regs *ctx, struct request *req)</code>: This function will later be attached to kprobes. The arguments to kprobe functions are <code>struct pt_regs *ctx</code>, for registers and BPF context, and then the actual arguments to the function. We'll attach this to blk_start_request(), where the first argument is <code>struct request *</code>.</li>
<li><code>start.update(&amp;req, &amp;ts)</code>: We're using the pointer to the request struct as a key in our hash. What? This is commonplace in tracing. Pointers to structs turn out to be great keys, as they are unique: two structs can't have the same pointer address. (Just be careful about when it gets free'd and reused.) So what we're really doing is tagging the request struct, which describes the disk I/O, with our own timestamp, so that we can time it. There's two common keys used for storing timestamps: pointers to structs, and, thread IDs (for timing function entry to return).</li>
<li><code>req-&gt;__data_len</code>: We're dereferencing members of <code>struct request</code>. See its definition in the kernel source for what members are there. bcc actually rewrites these expressions to be a series of <code>bpf_probe_read_kernel()</code> calls. Sometimes bcc can't handle a complex dereference, and you need to call <code>bpf_probe_read_kernel()</code> directly.</li>
<li><code>REQ_WRITE</code>: 我们在Python程序中定义了一个内核常量因为我们后面会在Python程序中使用它。如果我们在BPF程序中使用REQ_WRITE它应该可以正常工作无需定义只需使用适当的<code>#includes</code></li>
<li><code>trace_start(struct pt_regs *ctx, struct request*req)</code>: 这个函数将在后面附加到kprobe上。kprobe函数的参数是<code>struct pt_regs *ctx</code>用于寄存器和BPF上下文然后是函数的实际参数。我们将把它附加到blk_start_request()上,其中第一个参数是<code>struct request*</code></li>
<li><code>start.update(&amp;req, &amp;ts)</code>: 我们使用请求结构的指针作为哈希中的键。这在跟踪中很常见。结构体指针是非常好的键因为它们是唯一的两个结构体不能具有相同的指针地址。只需小心何时释放和重用指针。所以我们实际上是给描述磁盘I/O的请求结构体打上我们自己的时间戳以便我们可以计时。存储时间戳常用的两个键是结构体指针和线程ID用于记录函数入口到返回的时间</li>
<li><code>req-&gt;__data_len</code>: 我们在解引用<code>struct request</code>的成员。请参阅内核源代码中对其定义的部分以获得有关哪些成员可用的信息。bcc实际上会将这些表达式重写为一系列<code>bpf_probe_read_kernel()</code>调用。有时bcc无法处理复杂的解引用此时您需要直接调用<code>bpf_probe_read_kernel()</code></li>
</ol>
<p>This is a pretty interesting program, and if you can understand all the code, you'll understand many important basics. We're still using the bpf_trace_printk() hack, so let's fix that next.</p>
<p>这是一个非常有趣的程序,如果您能理解所有的代码,您就会理解很多重要的基础知识。我们仍然在使用<code>bpf_trace_printk()</code>的技巧,我们下一步要解决这个问题。</p>
<h3 id="lesson-7-hello_perf_outputpy"><a class="header" href="#lesson-7-hello_perf_outputpy">Lesson 7. hello_perf_output.py</a></h3>
<p>Let's finally stop using bpf_trace_printk() and use the proper BPF_PERF_OUTPUT() interface. This will also mean we stop getting the free trace_field() members like PID and timestamp, and will need to fetch them directly. Sample output while commands are run in another session:</p>
<p>让我们最终停止使用bpf_trace_printk()并使用适当的BPF_PERF_OUTPUT()接口。这也意味着我们将停止获取免费的trace_field()成员如PID和时间戳并且需要直接获取它们。在另一个会话中运行命令时的示例输出</p>
<pre><code class="language-sh"># hello_perf_output.py
TIME(s) COMM PID MESSAGE
0.000000000 bash 22986 Hello, perf_output!
0.021080275 systemd-udevd 484 Hello, perf_output!
0.021359520 systemd-udevd 484 Hello, perf_output!
0.021590610 systemd-udevd 484 Hello, perf_output!
0.000000000 bash 22986 你好,perf_output
0.021080275 systemd-udevd 484 你好,perf_output
0.021359520 systemd-udevd 484 你好,perf_output
0.021590610 systemd-udevd 484 你好,perf_output
[...]
</code></pre>
<p>Code is <a href="https://github.com/iovisor/bcc/tree/master/examples/tracing/hello_perf_output.py">examples/tracing/hello_perf_output.py</a>:</p>
<p>代码位于<a href="https://github.com/iovisor/bcc/tree/master/examples/tracing/hello_perf_output.py">examples/tracing/hello_perf_output.py</a></p>
<pre><code class="language-Python">from bcc import BPF
# define BPF program
// 定义BPF程序
prog = &quot;&quot;&quot;
#include &lt;linux/sched.h&gt;
// define output data structure in C
// 在C中定义输出数据结构
struct data_t {
u32 pid;
u64 ts;
@@ -414,14 +411,14 @@ int hello(struct pt_regs *ctx) {
}
&quot;&quot;&quot;
# load BPF program
// 加载BPF程序
b = BPF(text=prog)
b.attach_kprobe(event=b.get_syscall_fnname(&quot;clone&quot;), fn_name=&quot;hello&quot;)
# header
//标题
print(&quot;%-18s %-16s %-6s %s&quot; % (&quot;TIME(s)&quot;, &quot;COMM&quot;, &quot;PID&quot;, &quot;MESSAGE&quot;))
# process event
//处理事件
start = 0
def print_event(cpu, data, size):
global start
@@ -429,50 +426,47 @@ def print_event(cpu, data, size):
if start == 0:
start = event.ts
time_s = (float(event.ts - start)) / 1000000000
print(&quot;%-18.9f %-16s %-6d %s&quot; % (time_s, event.comm, event.pid,
&quot;Hello, perf_output!&quot;))
print(&quot;%-18.9f %-16s %-6d %s&quot; % (time_s, event.comm, event.pid, &quot;你好perf_output&quot;))
# loop with callback to print_event
//循环并回调print_event
b[&quot;events&quot;].open_perf_buffer(print_event)
while 1:
b.perf_buffer_poll()
</code></pre>
<p>Things to learn:</p>
<p>学习的内容:</p>
<ol>
<li><code>struct data_t</code>: This defines the C struct we'll use to pass data from kernel to user space.</li>
<li><code>BPF_PERF_OUTPUT(events)</code>: This names our output channel &quot;events&quot;.</li>
<li><code>struct data_t data = {};</code>: Create an empty data_t struct that we'll then populate.</li>
<li><code>bpf_get_current_pid_tgid()</code>: Returns the process ID in the lower 32 bits (kernel's view of the PID, which in user space is usually presented as the thread ID), and the thread group ID in the upper 32 bits (what user space often thinks of as the PID). By directly setting this to a u32, we discard the upper 32 bits. Should you be presenting the PID or the TGID? For a multi-threaded app, the TGID will be the same, so you need the PID to differentiate them, if that's what you want. It's also a question of expectations for the end user.</li>
<li><code>bpf_get_current_comm()</code>: Populates the first argument address with the current process name.</li>
<li><code>events.perf_submit()</code>: Submit the event for user space to read via a perf ring buffer.</li>
<li><code>def print_event()</code>: Define a Python function that will handle reading events from the <code>events</code> stream.</li>
<li><code>b[&quot;events&quot;].event(data)</code>: Now get the event as a Python object, auto-generated from the C declaration.</li>
<li><code>b[&quot;events&quot;].open_perf_buffer(print_event)</code>: Associate the Python <code>print_event</code> function with the <code>events</code> stream.</li>
<li><code>while 1: b.perf_buffer_poll()</code>: Block waiting for events.</li>
<li><code>struct data_t</code>: 这定义了一个C结构体我们将用它来从内核传递数据到用户空间。1. <code>BPF_PERF_OUTPUT(events)</code>: 这里给我们的输出通道命名为&quot;events&quot;</li>
<li><code>struct data_t data = {};</code>: 创建一个空的<code>data_t</code>结构体,我们将在之后填充它。</li>
<li><code>bpf_get_current_pid_tgid()</code>: 返回低32位的进程ID内核视图中的PID用户空间中通常被表示为线程ID以及高32位的线程组ID用户空间通常认为是PID。通过直接将其设置为<code>u32</code>我们丢弃了高32位。应该显示PID还是TGID对于多线程应用程序TGID将是相同的所以如果你想要区分它们你需要PID。这也是对最终用户期望的一个问题。</li>
<li><code>bpf_get_current_comm()</code>: 将当前进程的名称填充到第一个参数的地址中。</li>
<li><code>events.perf_submit()</code>: 通过perf环形缓冲区将事件提交给用户空间以供读取。</li>
<li><code>def print_event()</code>: 定义一个Python函数来处理从<code>events</code>流中读取的事件。</li>
<li><code>b[&quot;events&quot;].event(data)</code>: 现在将事件作为一个Python对象获取该对象是根据C声明自动生成的。</li>
<li><code>b[&quot;events&quot;].open_perf_buffer(print_event)</code>: 将Python的<code>print_event</code>函数与<code>events</code>流关联起来。</li>
<li><code>while 1: b.perf_buffer_poll()</code>: 阻塞等待事件。</li>
</ol>
<h3 id="lesson-8-sync_perf_outputpy"><a class="header" href="#lesson-8-sync_perf_outputpy">Lesson 8. sync_perf_output.py</a></h3>
<p>Rewrite sync_timing.py, from a prior lesson, to use <code>BPF_PERF_OUTPUT</code>.</p>
<h3 id="lesson-9-bitehistpy"><a class="header" href="#lesson-9-bitehistpy">Lesson 9. bitehist.py</a></h3>
<p>The following tool records a histogram of disk I/O sizes. Sample output:</p>
<h3 id="第八课-sync_perf_outputpy"><a class="header" href="#第八课-sync_perf_outputpy">第八课。 sync_perf_output.py</a></h3>
<p>重写之前的课程中的sync_timing.py,使用<code>BPF_PERF_OUTPUT</code></p>
<h3 id="第九课-bitehistpy"><a class="header" href="#第九课-bitehistpy">第九课。 bitehist.py</a></h3>
<p>以下工具记录了磁盘I/O大小的直方图。样本输出</p>
<pre><code class="language-sh"># bitehist.py
Tracing... Hit Ctrl-C to end.
跟踪中... 按Ctrl-C结束。
^C
kbytes : count distribution
0 -&gt; 1 : 3 | |
2 -&gt; 3 : 0 | |
4 -&gt; 7 : 211 |********** |
8 -&gt; 15 : 0 | |
16 -&gt; 31 : 0 | |
32 -&gt; 63 : 0 | |
16 -&gt; 31 : 0 | |&quot;.32 -&gt; 63 : 0 | |
64 -&gt; 127 : 1 | |
128 -&gt; 255 : 800 |**************************************|
</code></pre>
<p>Code is <a href="https://github.com/iovisor/bcc/tree/master/examples/tracing/bitehist.py">examples/tracing/bitehist.py</a>:</p>
<p>代码在<a href="https://github.com/iovisor/bcc/tree/master/examples/tracing/bitehist.py">examples/tracing/bitehist.py</a>:</p>
<pre><code class="language-Python">from __future__ import print_function
from bcc import BPF
from time import sleep
# load BPF program
# 加载BPF程序
b = BPF(text=&quot;&quot;&quot;
#include &lt;uapi/linux/ptrace.h&gt;
#include &lt;linux/blkdev.h&gt;
@@ -481,49 +475,47 @@ BPF_HISTOGRAM(dist);
int kprobe__blk_account_io_done(struct pt_regs *ctx, struct request *req)
{
dist.increment(bpf_log2l(req-&gt;__data_len / 1024));
return 0;
dist.increment(bpf_log2l(req-&gt;__data_len / 1024));
return 0;
}
&quot;&quot;&quot;)
# header
print(&quot;Tracing... Hit Ctrl-C to end.&quot;)
# 头部
print(&quot;跟踪中... 按Ctrl-C结束.&quot;)
# trace until Ctrl-C
# 跟踪直到按下Ctrl-C
try:
sleep(99999999)
sleep(99999999)
except KeyboardInterrupt:
print()
print()
# output
# 输出
b[&quot;dist&quot;].print_log2_hist(&quot;kbytes&quot;)
</code></pre>
<p>A recap from earlier lessons:</p>
<p>之前课程的总结:</p>
<ul>
<li><code>kprobe__</code>: This prefix means the rest will be treated as a kernel function name that will be instrumented using kprobe.</li>
<li><code>struct pt_regs *ctx, struct request *req</code>: Arguments to kprobe. The <code>ctx</code> is registers and BPF context, the <code>req</code> is the first argument to the instrumented function: <code>blk_account_io_done()</code>.</li>
<li><code>req-&gt;__data_len</code>: Dereferencing that member.</li>
<li><code>kprobe__</code>: 这个前缀意味着其余部分将被视为一个将使用kprobe进行插桩的内核函数名。</li>
<li><code>struct pt_regs *ctx, struct request*req</code>: kprobe的参数。<code>ctx</code> 是寄存器和BPF上下文<code>req</code> 是被插桩函数 <code>blk_account_io_done()</code> 的第一个参数。</li>
<li><code>req-&gt;__data_len</code>: 解引用该成员。</li>
</ul>
<p>New things to learn:</p>
<p>新知识:</p>
<ol>
<li><code>BPF_HISTOGRAM(dist)</code>: Defines a BPF map object that is a histogram, and names it &quot;dist&quot;.</li>
<li><code>dist.increment()</code>: Increments the histogram bucket index provided as first argument by one by default. Optionally, custom increments can be passed as the second argument.</li>
<li><code>bpf_log2l()</code>: Returns the log-2 of the provided value. This becomes the index of our histogram, so that we're constructing a power-of-2 histogram.</li>
<li><code>b[&quot;dist&quot;].print_log2_hist(&quot;kbytes&quot;)</code>: Prints the &quot;dist&quot; histogram as power-of-2, with a column header of &quot;kbytes&quot;. The only data transferred from kernel to user space is the bucket counts, making this efficient.</li>
<li><code>BPF_HISTOGRAM(dist)</code>: 定义了一个名为 &quot;dist&quot; 的BPF映射对象它是一个直方图。</li>
<li><code>dist.increment()</code>: 默认情况下将第一个参数提供的直方图桶索引加1。也可以作为第二个参数传递自定义的增量。</li>
<li><code>bpf_log2l()</code>: 返回所提供值的对数值。这将成为我们直方图的索引这样我们构建了一个以2为底的幂直方图。</li>
<li><code>b[&quot;dist&quot;].print_log2_hist(&quot;kbytes&quot;)</code>: 以2为底的幂形式打印 &quot;dist&quot; 直方图,列标题为 &quot;kbytes&quot;。这样只有桶计数从内核传输到用户空间,因此效率高。</li>
</ol>
<h3 id="lesson-10-disklatencypy"><a class="header" href="#lesson-10-disklatencypy">Lesson 10. disklatency.py</a></h3>
<p>Write a program that times disk I/O, and prints a histogram of their latency. Disk I/O instrumentation and timing can be found in the disksnoop.py program from a prior lesson, and histogram code can be found in bitehist.py from a prior lesson.</p>
<h3 id="lesson-11-vfsreadlatpy"><a class="header" href="#lesson-11-vfsreadlatpy">Lesson 11. vfsreadlat.py</a></h3>
<p>This example is split into separate Python and C files. Example output:</p>
<h3 id="lesson-10-disklatencypy-lesson-11-vfsreadlatpy"><a class="header" href="#lesson-10-disklatencypy-lesson-11-vfsreadlatpy">Lesson 10. disklatency.py”。#### Lesson 11. vfsreadlat.py</a></h3>
<p>这个例子分为独立的Python和C文件。示例输出</p>
<pre><code class="language-sh"># vfsreadlat.py 1
Tracing... Hit Ctrl-C to end.
usecs : count distribution
跟踪中... 按Ctrl-C停止。
微秒 : 数量 分布
0 -&gt; 1 : 0 | |
2 -&gt; 3 : 2 |*********** |
4 -&gt; 7 : 7 |****************************************|
8 -&gt; 15 : 4 |********************** |
usecs : count distribution
微秒 : 数量 分布
0 -&gt; 1 : 29 |****************************************|
2 -&gt; 3 : 28 |************************************** |
4 -&gt; 7 : 4 |***** |
@@ -538,8 +530,7 @@ Tracing... Hit Ctrl-C to end.
2048 -&gt; 4095 : 0 | |
4096 -&gt; 8191 : 4 |***** |
8192 -&gt; 16383 : 6 |******** |
16384 -&gt; 32767 : 9 |************ |
32768 -&gt; 65535 : 6 |******** |
16384 -&gt; 32767 : 9 |************ |```.32768 -&gt; 65535 : 6 |******** |
65536 -&gt; 131071 : 2 |** |
usecs : count distribution
@@ -551,14 +542,15 @@ Tracing... Hit Ctrl-C to end.
32 -&gt; 63 : 2 |******* |
[...]
</code></pre>
<p>Browse the code in <a href="https://github.com/iovisor/bcc/tree/master/examples/tracing/vfsreadlat.py">examples/tracing/vfsreadlat.py</a> and <a href="https://github.com/iovisor/bcc/tree/master/examples/tracing/vfsreadlat.c">examples/tracing/vfsreadlat.c</a>. Things to learn:</p>
<p>浏览 <a href="https://github.com/iovisor/bcc/tree/master/examples/tracing/vfsreadlat.py">examples/tracing/vfsreadlat.py</a> <a href="https://github.com/iovisor/bcc/tree/master/examples/tracing/vfsreadlat.c">examples/tracing/vfsreadlat.c</a> 中的代码。</p>
<p>学习的内容:</p>
<ol>
<li><code>b = BPF(src_file = &quot;vfsreadlat.c&quot;)</code>: Read the BPF C program from a separate source file.</li>
<li><code>b.attach_kretprobe(event=&quot;vfs_read&quot;, fn_name=&quot;do_return&quot;)</code>: Attaches the BPF C function <code>do_return()</code> to the return of the kernel function <code>vfs_read()</code>. This is a kretprobe: instrumenting the return from a function, rather than its entry.</li>
<li><code>b[&quot;dist&quot;].clear()</code>: Clears the histogram.</li>
<li><code>b = BPF(src_file = &quot;vfsreadlat.c&quot;)</code>: 从单独的源代码文件中读取 BPF C 程序。</li>
<li><code>b.attach_kretprobe(event=&quot;vfs_read&quot;, fn_name=&quot;do_return&quot;)</code>: 将 BPF C 函数 <code>do_return()</code> 链接到内核函数 <code>vfs_read()</code> 的返回值上。这是一个 kretprobe用于检测函数返回值而不是函数的入口。</li>
<li><code>b[&quot;dist&quot;].clear()</code>: 清除直方图。</li>
</ol>
<h3 id="lesson-12-urandomreadpy"><a class="header" href="#lesson-12-urandomreadpy">Lesson 12. urandomread.py</a></h3>
<p>Tracing while a <code>dd if=/dev/urandom of=/dev/null bs=8k count=5</code> is run:</p>
<p>当运行 <code>dd if=/dev/urandom of=/dev/null bs=8k count=5</code> 时进行跟踪:</p>
<pre><code class="language-sh"># urandomread.py
TIME(s) COMM PID GOTBITS
24652832.956994001 smtp 24690 384
@@ -568,11 +560,11 @@ TIME(s) COMM PID GOTBITS
24652837.728294998 dd 24692 65536
24652837.728888001 dd 24692 65536
</code></pre>
<p>Hah! I caught smtp by accident. Code is <a href="https://github.com/iovisor/bcc/tree/master/examples/tracing/urandomread.py">examples/tracing/urandomread.py</a>:</p>
<pre><code class="language-Python">from __future__ import print_function
<p>哈!我意外地捕捉到了 smtp。代码在 <a href="https://github.com/iovisor/bcc/tree/master/examples/tracing/urandomread.py">examples/tracing/urandomread.py</a> 中:</p>
<pre><code class="language-Python">from __future__ import print_function&quot;.```python
from bcc import BPF
# load BPF program
# 加载BPF程序
b = BPF(text=&quot;&quot;&quot;
TRACEPOINT_PROBE(random, urandom_read) {
// args is from /sys/kernel/debug/tracing/events/random/urandom_read/format
@@ -592,34 +584,34 @@ while 1:
continue
print(&quot;%-18.9f %-16s %-6d %s&quot; % (ts, task, pid, msg))
</code></pre>
<p>Things to learn:</p>
<p>要学到的东西:</p>
<ol>
<li><code>TRACEPOINT_PROBE(random, urandom_read)</code>: Instrument the kernel tracepoint <code>random:urandom_read</code>. These have a stable API, and thus are recommend to use instead of kprobes, wherever possible. You can run <code>perf list</code> for a list of tracepoints. Linux &gt;= 4.7 is required to attach BPF programs to tracepoints.</li>
<li><code>args-&gt;got_bits</code>: <code>args</code> is auto-populated to be a structure of the tracepoint arguments. The comment above says where you can see that structure. Eg:</li>
<li><code>TRACEPOINT_PROBE(random, urandom_read)</code>: 对内核跟踪点 <code>random:urandom_read</code> 进行注入。这些具有稳定的API因此在可能的情况下建议使用它们来代替kprobe。您可以运行 <code>perf list</code> 来获取跟踪点列表。至少需要 Linux 版本 4.7 来将 BPF 程序附加到跟踪点上。</li>
<li><code>args-&gt;got_bits</code>: <code>args</code> 是自动填充的跟踪点参数结构。上面的注释指出了可以查看这个结构的位置。例如:</li>
</ol>
<pre><code class="language-sh"># cat /sys/kernel/debug/tracing/events/random/urandom_read/format
name: urandom_read
ID: 972
format:
field:unsigned short common_type; offset:0; size:2; signed:0;
field:unsigned char common_flags; offset:2; size:1; signed:0;
field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
field:int common_pid; offset:4; size:4; signed:1;
field:unsigned short common_type; offset:0; size:2; signed:0;
field:unsigned char common_flags; offset:2; size:1; signed:0;
field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
field:int common_pid; offset:4; size:4; signed:1;
field:int got_bits; offset:8; size:4; signed:1;
field:int pool_left; offset:12; size:4; signed:1;
field:int input_left; offset:16; size:4; signed:1;
field:int got_bits; offset:8; size:4; signed:1;
field:int pool_left; offset:12; size:4; signed:1;
field:int input_left; offset:16; size:4; signed:1;
print fmt: &quot;got_bits %d nonblocking_pool_entropy_left %d input_entropy_left %d&quot;, REC-&gt;got_bits, REC-&gt;pool_left, REC-&gt;input_left
</code></pre>
<p>In this case, we were printing the <code>got_bits</code> member.</p>
<h3 id="lesson-13-disksnooppy-fixed"><a class="header" href="#lesson-13-disksnooppy-fixed">Lesson 13. disksnoop.py fixed</a></h3>
<p>Convert disksnoop.py from a previous lesson to use the <code>block:block_rq_issue</code> and <code>block:block_rq_complete</code> tracepoints.</p>
<h3 id="lesson-14-strlen_countpy"><a class="header" href="#lesson-14-strlen_countpy">Lesson 14. strlen_count.py</a></h3>
<p>This program instruments a user-level function, the <code>strlen()</code> library function, and frequency counts its string argument. Example output:</p>
<p>在这种情况下,我们正在打印 <code>got_bits</code> 成员。</p>
<h3 id="13-disksnooppy已修复"><a class="header" href="#13-disksnooppy已修复">13. disksnoop.py已修复</a></h3>
<p>将上一课的 disksnoop.py 修改为使用 <code>block:block_rq_issue</code> <code>block:block_rq_complete</code> 跟踪点。</p>
<h3 id="14-strlen_countpy"><a class="header" href="#14-strlen_countpy">14. strlen_count.py.</a></h3>
<p>这个程序对用户级函数进行插桩,其中包括 <code>strlen()</code> 库函数,并对其字符串参数进行频率统计。例如输出</p>
<pre><code class="language-sh"># strlen_count.py
Tracing strlen()... Hit Ctrl-C to end.
^C COUNT STRING
跟踪 strlen()... Ctrl-C 结束。
^C 数量 字符串
1 &quot; &quot;
1 &quot;/bin/ls&quot;
1 &quot;.&quot;
@@ -637,13 +629,13 @@ Tracing strlen()... Hit Ctrl-C to end.
70 &quot;#%^,~:-=?+/}&quot;
340 &quot;\x01\x1b]0;root@bgregg-test: ~\x07\x02root@bgregg-test:~# &quot;
</code></pre>
<p>These are various strings that are being processed by this library function while tracing, along with their frequency counts. <code>strlen()</code> was called on &quot;LC_ALL&quot; 12 times, for example.</p>
<p>Code is <a href="https://github.com/iovisor/bcc/tree/master/examples/tracing/strlen_count.py">examples/tracing/strlen_count.py</a>:</p>
<p>这些是在跟踪时由此库函数处理的各种字符串以及它们的频率计数。例如,&quot;LC_ALL&quot; 被调用了12次。</p>
<p>代码在 <a href="https://github.com/iovisor/bcc/tree/master/examples/tracing/strlen_count.py">examples/tracing/strlen_count.py</a> 中:</p>
<pre><code class="language-Python">from __future__ import print_function
from bcc import BPF
from time import sleep
# load BPF program
# 载入 BPF 程序
b = BPF(text=&quot;&quot;&quot;
#include &lt;uapi/linux/ptrace.h&gt;
@@ -660,7 +652,7 @@ int count(struct pt_regs *ctx) {
u64 zero = 0, *val;
bpf_probe_read_user(&amp;key.c, sizeof(key.c), (void *)PT_REGS_PARM1(ctx));
// could also use `counts.increment(key)`
// 也可以使用 `counts.increment(key)`
val = counts.lookup_or_try_init(&amp;key, &amp;zero);
if (val) {
(*val)++;
@@ -670,35 +662,34 @@ int count(struct pt_regs *ctx) {
&quot;&quot;&quot;)
b.attach_uprobe(name=&quot;c&quot;, sym=&quot;strlen&quot;, fn_name=&quot;count&quot;)
# header
print(&quot;Tracing strlen()... Hit Ctrl-C to end.&quot;)
# 头部
print(&quot;跟踪 strlen()... Ctrl-C 结束。&quot;)
# sleep until Ctrl-C
# 睡眠直到按下 Ctrl-C
try:
sleep(99999999)
except KeyboardInterrupt:
pass
# print output
print(&quot;%10s %s&quot; % (&quot;COUNT&quot;, &quot;STRING&quot;))
# 打印输出
print(&quot;%10s %s&quot; % (&quot;数量&quot;, &quot;字符串&quot;))
counts = b.get_table(&quot;counts&quot;)
for k, v in sorted(counts.items(), key=lambda counts: counts[1].value):
print(&quot;%10d \&quot;%s\&quot;&quot; % (v.value, k.c.encode('string-escape')))
</code></pre>
<p>Things to learn:</p>
<p>要学习的内容1. <code>PT_REGS_PARM1(ctx)</code>: 这个参数会获取传递给 <code>strlen()</code> 的第一个参数,也就是字符串。</p>
<ol>
<li><code>PT_REGS_PARM1(ctx)</code>: This fetches the first argument to <code>strlen()</code>, which is the string.</li>
<li><code>b.attach_uprobe(name=&quot;c&quot;, sym=&quot;strlen&quot;, fn_name=&quot;count&quot;)</code>: Attach to library &quot;c&quot; (if this is the main program, use its pathname), instrument the user-level function <code>strlen()</code>, and on execution call our C function <code>count()</code>.</li>
<li><code>b.attach_uprobe(name=&quot;c&quot;, sym=&quot;strlen&quot;, fn_name=&quot;count&quot;)</code>: 附加到库 &quot;c&quot;(如果这是主程序,则使用其路径名),对用户级函数 <code>strlen()</code> 进行插装,并在执行时调用我们的 C 函数 <code>count()</code></li>
</ol>
<h3 id="lesson-15-nodejs_http_serverpy"><a class="header" href="#lesson-15-nodejs_http_serverpy">Lesson 15. nodejs_http_server.py</a></h3>
<p>This program instruments a user statically-defined tracing (USDT) probe, which is the user-level version of a kernel tracepoint. Sample output:</p>
<h3 id="15nodejs_http_serverpy"><a class="header" href="#15nodejs_http_serverpy">第15课。nodejs_http_server.py</a></h3>
<p>本程序会对用户静态定义的跟踪 (USDT) 探测点进行插装,这是内核跟踪点的用户级版本。示例输出:</p>
<pre><code class="language-sh"># nodejs_http_server.py 24728
TIME(s) COMM PID ARGS
24653324.561322998 node 24728 path:/index.html
24653335.343401998 node 24728 path:/images/welcome.png
24653340.510164998 node 24728 path:/images/favicon.png
</code></pre>
<p>Relevant code from <a href="https://github.com/iovisor/bcc/tree/master/examples/tracing/nodejs_http_server.py">examples/tracing/nodejs_http_server.py</a>:</p>
<p>来自 <a href="https://github.com/iovisor/bcc/tree/master/examples/tracing/nodejs_http_server.py">examples/tracing/nodejs_http_server.py</a> 的相关代码:</p>
<pre><code class="language-Python">from __future__ import print_function
from bcc import BPF, USDT
import sys
@@ -732,26 +723,17 @@ if debug:
# initialize BPF
b = BPF(text=bpf_text, usdt_contexts=[u])
</code></pre>
<p>Things to learn:</p>
<p>学习内容:</p>
<ol>
<li><code>bpf_usdt_readarg(6, ctx, &amp;addr)</code>: Read the address of argument 6 from the USDT probe into <code>addr</code>.</li>
<li><code>bpf_probe_read_user(&amp;path, sizeof(path), (void *)addr)</code>: Now the string <code>addr</code> points to into our <code>path</code> variable.</li>
<li><code>u = USDT(pid=int(pid))</code>: Initialize USDT tracing for the given PID.</li>
<li><code>u.enable_probe(probe=&quot;http__server__request&quot;, fn_name=&quot;do_trace&quot;)</code>: Attach our <code>do_trace()</code> BPF C function to the Node.js <code>http__server__request</code> USDT probe.</li>
<li><code>b = BPF(text=bpf_text, usdt_contexts=[u])</code>: Need to pass in our USDT object, <code>u</code>, to BPF object creation.</li>
<li><code>bpf_usdt_readarg(6, ctx, &amp;addr)</code>: 从 USDT 探测点中读取参数 6 的地址到 <code>addr</code></li>
<li><code>bpf_probe_read_user(&amp;path, sizeof(path), (void *)addr)</code>: 现在字符串 <code>addr</code> 指向我们的 <code>path</code> 变量。</li>
<li><code>u = USDT(pid=int(pid))</code>: 为给定的 PID 初始化 USDT 跟踪。1. <code>u.enable_probe(probe=&quot;http__server__request&quot;, fn_name=&quot;do_trace&quot;)</code>: 将我们的 <code>do_trace()</code> BPF C 函数附加到 Node.js 的 <code>http__server__request</code> USDT 探针。</li>
<li><code>b = BPF(text=bpf_text, usdt_contexts=[u])</code>: 需要将我们的 USDT 对象 <code>u</code> 传递给 BPF 对象的创建。</li>
</ol>
<h3 id="lesson-16-task_switchc"><a class="header" href="#lesson-16-task_switchc">Lesson 16. task_switch.c</a></h3>
<p>This is an older tutorial included as a bonus lesson. Use this for recap and to reinforce what you've already learned.</p>
<p>This is a slightly more complex tracing example than Hello World. This program
will be invoked for every task change in the kernel, and record in a BPF map
the new and old pids.</p>
<p>The C program below introduces a new concept: the prev argument. This
argument is treated specially by the BCC frontend, such that accesses
to this variable are read from the saved context that is passed by the
kprobe infrastructure. The prototype of the args starting from
position 1 should match the prototype of the kernel function being
kprobed. If done so, the program will have seamless access to the
function parameters.</p>
<h3 id="16-task_switchc"><a class="header" href="#16-task_switchc">16. task_switch.c</a></h3>
<p>这是一个早期的教程,作为额外的课程包含其中。用它来复习和加深你已经学到的内容。</p>
<p>这是一个比 Hello World 更复杂的示例程序。该程序将在内核中每次任务切换时被调用,并在一个 BPF 映射中记录新旧进程的 pid。</p>
<p>下面的 C 程序引入了一个新的概念prev 参数。BCC 前端会特殊处理这个参数,从而使得对这个变量的访问从由 kprobe 基础设施传递的保存上下文中进行读取。从位置1开始的参数的原型应该与被 kprobed 的内核函数的原型匹配。如果这样做,程序就可以无缝访问函数参数。</p>
<pre><code class="language-c">#include &lt;uapi/linux/ptrace.h&gt;
#include &lt;linux/sched.h&gt;
@@ -776,30 +758,27 @@ int count_sched(struct pt_regs *ctx, struct task_struct *prev) {
return 0;
}
</code></pre>
<p>The userspace component loads the file shown above, and attaches it to the
<code>finish_task_switch</code> kernel function.
The <code>[]</code> operator of the BPF object gives access to each BPF_HASH in the
program, allowing pass-through access to the values residing in the kernel. Use
the object as you would any other python dict object: read, update, and deletes
are all allowed.</p>
<p>用户空间组件加载上面显示的文件,并将其附加到 <code>finish_task_switch</code> 内核函数上。
BPF 对象的 <code>[]</code> 运算符允许访问程序中的每个 BPF_HASH允许对内核中的值进行通行访问。可以像使用任何其他 python dict 对象一样使用该对象:读取、更新和删除操作都是允许的。</p>
<pre><code class="language-python">from bcc import BPF
from time import sleep
b = BPF(src_file=&quot;task_switch.c&quot;)
b = BPF(src_file=&quot;task_switch.c&quot;)&quot;.```markdown
```Chinese
b.attach_kprobe(event=&quot;finish_task_switch&quot;, fn_name=&quot;count_sched&quot;)
# generate many schedule events
# 生成多个调度事件
for i in range(0, 100): sleep(0.01)
for k, v in b[&quot;stats&quot;].items():
print(&quot;task_switch[%5d-&gt;%5d]=%u&quot; % (k.prev_pid, k.curr_pid, v.value))
</code></pre>
<p>These programs can be found in the files <a href="https://github.com/iovisor/bcc/tree/master/examples/tracing/task_switch.c">examples/tracing/task_switch.c</a> and <a href="https://github.com/iovisor/bcc/tree/master/examples/tracing/task_switch.py">examples/tracing/task_switch.py</a> respectively.</p>
<h3 id="lesson-17-further-study"><a class="header" href="#lesson-17-further-study">Lesson 17. Further Study</a></h3>
<p>For further study, see Sasha Goldshtein's <a href="https://github.com/goldshtn/linux-tracing-workshop">linux-tracing-workshop</a>, which contains additional labs. There are also many tools in bcc /tools to study.</p>
<p>Please read <a href="https://github.com/iovisor/bcc/tree/master/CONTRIBUTING-SCRIPTS.md">CONTRIBUTING-SCRIPTS.md</a> if you wish to contribute tools to bcc. At the bottom of the main <a href="https://github.com/iovisor/bcc/tree/master/README.md">README.md</a>, you'll also find methods for contacting us. Good luck, and happy tracing!</p>
<h2 id="networking"><a class="header" href="#networking">Networking</a></h2>
<p>To do.</p>
<p>这些程序可以在文件 <a href="https://github.com/iovisor/bcc/tree/master/examples/tracing/task_switch.c">examples/tracing/task_switch.c</a> <a href="https://github.com/iovisor/bcc/tree/master/examples/tracing/task_switch.py">examples/tracing/task_switch.py</a> 中找到。</p>
<h3 id="第17课-进一步研究"><a class="header" href="#第17课-进一步研究">17. 进一步研究</a></h3>
<p>要进行进一步研究,请参阅 Sasha Goldshtein <a href="https://github.com/goldshtn/linux-tracing-workshop">linux-tracing-workshop</a>,其中包含了额外的实验。bcc/tools 中还有许多工具可供研究。</p>
<p>如果您希望为 bcc 贡献工具,请阅读 <a href="https://github.com/iovisor/bcc/tree/master/CONTRIBUTING-SCRIPTS.md">CONTRIBUTING-SCRIPTS.md</a>。在主要的 <a href="https://github.com/iovisor/bcc/tree/master/README.md">README.md</a> 的底部,您还会找到与我们联系的方法。祝您好运,祝您成功追踪!</p>
<h2 id="网络"><a class="header" href="#网络">网络</a></h2>
<p>TODO</p>
</main>