英语

eBPF 系统调用

作者:

关于 bpf 系统调用的主要信息可在 man-pages 中的 bpf(2) 中找到。

bpf() 子命令参考

bpf() 系统调用执行的操作由 cmd 参数确定。 每个操作都接受一个随附的参数,该参数通过 attr 提供,attr 是指向类型为 bpf_attr 的联合的指针(如下所示)。 size 参数是由 attr 指向的联合的大小。

BPF_MAP_CREATE
描述

创建一个 map 并返回一个指向该 map 的文件描述符。 新文件描述符会自动启用 close-on-exec 文件描述符标志(请参阅 fcntl(2))。

BPF_MAP_CREATE 返回的文件描述符应用 close(2) 将删除该 map(但请参阅“注释”)。

返回值

一个新的文件描述符(一个非负整数),如果发生错误,则返回 -1(在这种情况下,会适当地设置 errno)。

BPF_MAP_LOOKUP_ELEM
描述

在由文件描述符 map_fd 引用的 map 中查找具有给定 key 的元素。

flags 参数可以指定为以下值之一:

BPF_F_LOCK

查找自旋锁 map 的值,而不返回锁。 如果元素包含自旋锁,则必须指定此项。

返回值

成功返回零。 如果发生错误,则返回 -1,并适当地设置 errno

BPF_MAP_UPDATE_ELEM
描述

在指定的 map 中创建或更新一个元素(键/值对)。

flags 参数应指定为以下值之一:

BPF_ANY

创建新元素或更新现有元素。

BPF_NOEXIST

仅当新元素不存在时才创建新元素。

BPF_EXIST

更新现有元素。

BPF_F_LOCK

更新自旋锁定的 map 元素。

返回值

成功返回零。 如果发生错误,则返回 -1,并适当地设置 errno

可能会将 errno 设置为 EINVALEPERMENOMEME2BIGEEXISTENOENT

E2BIG

map 中的元素数量达到了 map 创建时指定的 max_entries 限制。

EEXIST

如果 flags 指定了 BPF_NOEXIST,并且具有 key 的元素已存在于 map 中。

ENOENT

如果 flags 指定了 BPF_EXIST,并且具有 key 的元素不存在于 map 中。

BPF_MAP_DELETE_ELEM
描述

在指定的 map 中按键查找并删除元素。

返回值

成功返回零。 如果发生错误,则返回 -1,并适当地设置 errno

BPF_MAP_GET_NEXT_KEY
描述

在指定的 map 中按键查找元素,并返回下一个元素的键。 可用于迭代 map 中的所有元素。

返回值

成功返回零。 如果发生错误,则返回 -1,并适当地设置 errno

以下情况可用于迭代 map 的所有元素:

  • 如果未找到 key,则操作返回零,并将 next_key 指针设置为第一个元素的键。

  • 如果找到了 key,则操作返回零,并将 next_key 指针设置为下一个元素的键。

  • 如果 key 是最后一个元素,则返回 -1,并将 errno 设置为 ENOENT

如果发生错误,可能会将 errno 设置为 ENOMEMEFAULTEPERMEINVAL

BPF_PROG_LOAD
描述

验证并加载 eBPF 程序,返回与该程序关联的新文件描述符。

BPF_PROG_LOAD 返回的文件描述符应用 close(2) 将卸载 eBPF 程序(但请参阅“注释”)。

新文件描述符会自动启用 close-on-exec 文件描述符标志(请参阅 fcntl(2))。

返回值

一个新的文件描述符(一个非负整数),如果发生错误,则返回 -1(在这种情况下,会适当地设置 errno)。

BPF_OBJ_PIN
描述

将指定的 bpf_fd 引用的 eBPF 程序或 map 固定到文件系统上提供的 pathname

pathname 参数不能包含点(“.”)。

成功后,pathname 将保留对 eBPF 对象的引用,从而防止在关闭原始 bpf_fd 时释放该对象。 这允许 eBPF 对象在 close(bpf_fd) 之后存在,从而使其能够存活于父进程的生命周期之外。

pathname 应用 unlink(2) 或类似调用会从文件系统中取消固定该对象,从而删除该引用。 如果没有其他文件描述符或文件系统节点引用同一对象,则会释放该对象(请参阅“注释”)。

pathname 的父目录的文件系统类型必须为 BPF_FS_MAGIC

返回值

成功返回零。 如果发生错误,则返回 -1,并适当地设置 errno

BPF_OBJ_GET
描述

为固定到指定的 pathname 的 eBPF 对象打开一个文件描述符。

返回值

一个新的文件描述符(一个非负整数),如果发生错误,则返回 -1(在这种情况下,会适当地设置 errno)。

BPF_PROG_ATTACH
描述

在指定的 attach_type 钩子处将 eBPF 程序附加到 target_fd

attach_type 指定要将程序附加到的 eBPF 附加点,并且必须是 bpf_attach_type 之一(如下所示)。

attach_bpf_fd 必须是已加载的 cgroup、流分析器、LIRC、sockmap 或 sock_ops 类型的 eBPF 程序的有效文件描述符,该程序类型与指定的 attach_type 相对应。

target_fd 必须是内核对象的有效文件描述符,该内核对象依赖于 attach_bpf_fd 的附加类型

BPF_PROG_TYPE_CGROUP_DEVICEBPF_PROG_TYPE_CGROUP_SKBBPF_PROG_TYPE_CGROUP_SOCKBPF_PROG_TYPE_CGROUP_SOCK_ADDRBPF_PROG_TYPE_CGROUP_SOCKOPTBPF_PROG_TYPE_CGROUP_SYSCTLBPF_PROG_TYPE_SOCK_OPS

启用了 eBPF 控制器的 Control Group v2 层次结构。 要求内核使用 CONFIG_CGROUP_BPF 编译。

BPF_PROG_TYPE_FLOW_DISSECTOR

网络命名空间(例如 /proc/self/ns/net)。

BPF_PROG_TYPE_LIRC_MODE2

LIRC 设备路径(例如 /dev/lircN)。 要求内核使用 CONFIG_BPF_LIRC_MODE2 编译。

BPF_PROG_TYPE_SK_SKBBPF_PROG_TYPE_SK_MSG

socket 类型的 eBPF map(例如 BPF_MAP_TYPE_SOCKHASH)。

返回值

成功返回零。 如果发生错误,则返回 -1,并适当地设置 errno

BPF_PROG_DETACH
描述

在由 attach_type 指定的钩子处分离与 target_fd 关联的 eBPF 程序。 该程序必须之前使用 BPF_PROG_ATTACH 附加过。

返回值

成功返回零。 如果发生错误,则返回 -1,并适当地设置 errno

BPF_PROG_TEST_RUN
描述

针对提供的程序上下文 ctx_in 和数据 data_in 运行与 prog_fd 关联的 eBPF 程序 repeat 次,并返回修改后的程序上下文 ctx_outdata_out(例如,数据包数据)、执行结果 retval 和测试运行的 duration

作为输入和输出参数提供的缓冲区 ctx_inctx_outdata_indata_out 的大小必须在相应的变量 ctx_size_inctx_size_outdata_size_in 和/或 data_size_out 中提供。 如果未提供任何这些参数(即设置为 NULL),则相应的大小字段必须为零。

某些程序类型有特定的要求

BPF_PROG_TYPE_SK_LOOKUP

data_indata_out 必须为 NULL。

BPF_PROG_TYPE_RAW_TRACEPOINTBPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE

ctx_outdata_indata_out 必须为 NULL。 repeat 必须为零。

BPF_PROG_RUN 是 BPF_PROG_TEST_RUN 的别名。

返回值

成功返回零。 如果发生错误,则返回 -1,并适当地设置 errno

ENOSPC

data_size_outctx_size_out 太小。

ENOTSUPP

prog_fd 引用的程序的程序类型不支持此命令。

BPF_PROG_GET_NEXT_ID
描述

获取当前已加载到内核的下一个 eBPF 程序。

查找 id 大于 start_id 的 eBPF 程序,并在成功时更新 next_id。 如果没有剩余 id 大于 start_id 的其他 eBPF 程序,则返回 -1 并将 errno 设置为 ENOENT

返回值

成功返回零。 如果发生错误,或者没有剩余 id,则返回 -1,并适当地设置 errno

BPF_MAP_GET_NEXT_ID
描述

获取当前已加载到内核的下一个 eBPF map。

查找 id 大于 start_id 的 eBPF map,并在成功时更新 next_id。 如果没有剩余 id 大于 start_id 的其他 eBPF map,则返回 -1 并将 errno 设置为 ENOENT

返回值

成功返回零。 如果发生错误,或者没有剩余 id,则返回 -1,并适当地设置 errno

BPF_PROG_GET_FD_BY_ID
描述

为与 prog_id 相对应的 eBPF 程序打开一个文件描述符。

返回值

一个新的文件描述符(一个非负整数),如果发生错误,则返回 -1(在这种情况下,会适当地设置 errno)。

BPF_MAP_GET_FD_BY_ID
描述

为与 map_id 相对应的 eBPF map 打开一个文件描述符。

返回值

一个新的文件描述符(一个非负整数),如果发生错误,则返回 -1(在这种情况下,会适当地设置 errno)。

BPF_OBJ_GET_INFO_BY_FD
描述

获取有关与 bpf_fd 相对应的 eBPF 对象的信息。

最多填充 info_len 字节的 info,该信息将采用以下格式之一,具体取决于 bpf_fd 的 eBPF 对象类型:

  • struct bpf_prog_info

  • struct bpf_map_info

  • struct bpf_btf_info

  • struct bpf_link_info

返回值

成功返回零。 如果发生错误,则返回 -1,并适当地设置 errno

BPF_PROG_QUERY
描述

获取有关与指定的 attach_type 钩子关联的 eBPF 程序的信息。

target_fd 必须是内核对象的有效文件描述符,该内核对象依赖于 attach_bpf_fd 的附加类型

BPF_PROG_TYPE_CGROUP_DEVICEBPF_PROG_TYPE_CGROUP_SKBBPF_PROG_TYPE_CGROUP_SOCKBPF_PROG_TYPE_CGROUP_SOCK_ADDRBPF_PROG_TYPE_CGROUP_SOCKOPTBPF_PROG_TYPE_CGROUP_SYSCTLBPF_PROG_TYPE_SOCK_OPS

启用了 eBPF 控制器的 Control Group v2 层次结构。 要求内核使用 CONFIG_CGROUP_BPF 编译。

BPF_PROG_TYPE_FLOW_DISSECTOR

网络命名空间(例如 /proc/self/ns/net)。

BPF_PROG_TYPE_LIRC_MODE2

LIRC 设备路径(例如 /dev/lircN)。 要求内核使用 CONFIG_BPF_LIRC_MODE2 编译。

BPF_PROG_QUERY 始终获取附加的程序数量和用于附加这些程序的 attach_flags。 此外,如果 prog_ids 非零且附加的程序数量小于 prog_cnt,则会使用在 target_fd 处附加的程序的 eBPF 程序 id 填充 prog_ids

以下标志可能会更改结果:

BPF_F_QUERY_EFFECTIVE

仅返回有关当前在指定的 target_fd 处有效的程序的信息。

返回值

成功返回零。 如果发生错误,则返回 -1,并适当地设置 errno

BPF_RAW_TRACEPOINT_OPEN
描述

将 eBPF 程序附加到跟踪点 name,以原始形式访问跟踪点的内核内部参数。

prog_fd 必须是与已加载的类型为 BPF_PROG_TYPE_RAW_TRACEPOINT 的 eBPF 程序关联的有效文件描述符。

对于公开给相应 eBPF 程序的跟踪点参数内容,不提供 ABI 保证。

BPF_RAW_TRACEPOINT_OPEN 返回的文件描述符应用 close(2) 将删除该 map(但请参阅“注释”)。

返回值

一个新的文件描述符(一个非负整数),如果发生错误,则返回 -1(在这种情况下,会适当地设置 errno)。

BPF_BTF_LOAD
描述

验证并将 BPF 类型格式 (BTF) 元数据加载到内核中,返回与元数据关联的新文件描述符。 有关 BTF 的更多详细信息,请访问 https://linuxkernel.org.cn/doc/html/latest/bpf/btf.html

btf 参数必须指向有效的内存,该内存提供 btf_size 字节的 BTF 二进制元数据。

返回的文件描述符可以传递给其他 bpf() 子命令,例如 BPF_PROG_LOADBPF_MAP_CREATE,以将 BTF 与这些对象关联起来。

BPF_PROG_LOAD 类似,BPF_BTF_LOAD 具有可选参数来指定 btf_log_bufbtf_log_sizebtf_log_level,允许内核返回有关 BTF 验证过程的自由格式日志输出。

返回值

一个新的文件描述符(一个非负整数),如果发生错误,则返回 -1(在这种情况下,会适当地设置 errno)。

BPF_BTF_GET_FD_BY_ID
描述

打开与 btf_id 对应的 BPF 类型格式 (BTF) 的文件描述符。

返回值

一个新的文件描述符(一个非负整数),如果发生错误,则返回 -1(在这种情况下,会适当地设置 errno)。

BPF_TASK_FD_QUERY
描述

获取与由 pidfd 标识的目标进程关联的 eBPF 程序的信息。

如果 pidfd 与 tracepoint、kprobe 或 uprobe perf 事件关联,则 prog_idfd_type 将填充 eBPF 程序的 ID 和类型为 bpf_task_fd_type 的文件描述符类型。如果与 kprobe 或 uprobe 关联,则还会填充 probe_offsetprobe_addr。可选地,如果提供了 buf,则最多将 buf_len 字节的 buf 填充为 tracepoint、kprobe 或 uprobe 的名称。

可以使用 BPF_PROG_GET_FD_BY_IDBPF_OBJ_GET_INFO_BY_FD 更深入地检查生成的 prog_id

返回值

成功返回零。 如果发生错误,则返回 -1,并适当地设置 errno

BPF_MAP_LOOKUP_AND_DELETE_ELEM
描述

在由文件描述符 fd 引用的映射中查找具有给定 key 的元素,如果找到,则删除该元素。

对于 BPF_MAP_TYPE_QUEUEBPF_MAP_TYPE_STACK 映射类型,flags 参数需要设置为 0,但对于其他映射类型,可以指定为

BPF_F_LOCK

查找并删除自旋锁映射的值而不返回锁。如果元素包含自旋锁,则必须指定此项。

BPF_MAP_TYPE_QUEUEBPF_MAP_TYPE_STACK 映射类型将此命令实现为“pop”操作,删除顶部元素而不是与 key 对应的元素。当对这些映射类型发出此操作时,keykey_len 参数应清零。

此命令仅对以下映射类型有效:* BPF_MAP_TYPE_QUEUE * BPF_MAP_TYPE_STACK * BPF_MAP_TYPE_HASH * BPF_MAP_TYPE_PERCPU_HASH * BPF_MAP_TYPE_LRU_HASH * BPF_MAP_TYPE_LRU_PERCPU_HASH

返回值

成功返回零。 如果发生错误,则返回 -1,并适当地设置 errno

BPF_MAP_FREEZE
描述

冻结指定映射的权限。

可以通过传递零 flags 来冻结写入权限。成功后,未来的 syscall 调用将无法更改 map_fd 的映射状态。对于冻结的映射,仍然可以从 eBPF 程序进行写入操作。

不支持 BPF_MAP_TYPE_STRUCT_OPS 类型的映射。

返回值

成功返回零。 如果发生错误,则返回 -1,并适当地设置 errno

BPF_BTF_GET_NEXT_ID
描述

获取当前加载到内核中的下一个 BPF 类型格式 (BTF) 对象。

查找 id 大于 start_id 的 BTF 对象,并在成功时更新 next_id。如果没有其他 BTF 对象的 id 高于 start_id,则返回 -1 并将 errno 设置为 ENOENT

返回值

成功返回零。 如果发生错误,或者没有剩余 id,则返回 -1,并适当地设置 errno

BPF_MAP_LOOKUP_BATCH
描述

迭代并获取映射中的多个元素。

使用两个不透明的值来管理批量操作,in_batchout_batch。最初,in_batch 必须设置为 NULL 以开始批量操作。在每次后续的 BPF_MAP_LOOKUP_BATCH 之后,调用者应将结果 out_batch 作为下一个操作的 in_batch 传递,以便从当前点继续迭代。in_batchout_batch 都必须指向足够大的内存来保存密钥,但对于 BPF_MAP_TYPE_{HASH, PERCPU_HASH, LRU_HASH, LRU_PERCPU_HASH} 类型的映射,批量参数必须至少为 4 个字节宽,而不管密钥大小。

keysvalues 是输出参数,必须指向足够大的内存来保存基于映射 map_fd 的键和值大小的 count 项。keys 缓冲区的大小必须为 key_size * countvalues 缓冲区的大小必须为 value_size * count

elem_flags 参数可以指定为以下之一

BPF_F_LOCK

查找自旋锁 map 的值,而不返回锁。 如果元素包含自旋锁,则必须指定此项。

成功后,映射中的 count 个元素被复制到用户缓冲区中,键被复制到 keys 中,值被复制到 values 中的相应索引中。

如果返回错误且 errno 不是 EFAULT,则 count 设置为成功处理的元素数。

返回值

成功返回零。 如果发生错误,则返回 -1,并适当地设置 errno

可能会将 errno 设置为 ENOSPC,表示在基于哈希的映射类型的迭代期间,keysvalues 太小而无法转储整个桶。

BPF_MAP_LOOKUP_AND_DELETE_BATCH
描述

迭代并删除映射中的所有元素。

此操作的行为与 BPF_MAP_LOOKUP_BATCH 相同,但有两个例外

  • 每个成功返回的元素也会从映射中删除。这至少是 count 个元素。请注意,count 既是输入参数又是输出参数。

  • 当返回时 errno 设置为 EFAULT 时,最多可以删除 count 个元素,而不返回已删除元素的键和值。

返回值

成功返回零。 如果发生错误,则返回 -1,并适当地设置 errno

BPF_MAP_UPDATE_BATCH
描述

key 更新映射中的多个元素。

keysvalues 是输入参数,必须指向足够大的内存来保存基于映射 map_fd 的键和值大小的 count 项。keys 缓冲区的大小必须为 key_size * countvalues 缓冲区的大小必须为 value_size * count

keys 中指定的每个元素按顺序更新为 values 中相应索引中的值。in_batchout_batch 参数将被忽略,并且应清零。

elem_flags 参数应指定为以下之一

BPF_ANY

创建新元素或更新现有元素。

BPF_NOEXIST

仅当新元素不存在时才创建它们。

BPF_EXIST

更新现有元素。

BPF_F_LOCK

更新自旋锁映射元素。如果映射值包含自旋锁,则必须指定此项。

成功后,映射中的 count 个元素将被更新。

如果返回错误且 errno 不是 EFAULT,则 count 设置为成功处理的元素数。

返回值

成功返回零。 如果发生错误,则返回 -1,并适当地设置 errno

可能会将 errno 设置为 EINVALEPERMENOMEME2BIGE2BIG 表示映射中的元素数已达到映射创建时指定的 max_entries 限制。

在特定情况下,可能会将 errno 设置为以下错误代码之一

EEXIST

如果 flags 指定了 BPF_NOEXIST,并且具有 key 的元素已存在于 map 中。

ENOENT

如果 flags 指定了 BPF_EXIST,并且具有 key 的元素不存在于 map 中。

BPF_MAP_DELETE_BATCH
描述

key 删除映射中的多个元素。

keys 参数是一个输入参数,必须指向足够大的内存来保存基于映射 map_fd 的键大小的 count 项,即 key_size * count

keys 中指定的每个元素按顺序删除。in_batchout_batchvalues 参数将被忽略,并且应清零。

elem_flags 参数可以指定为以下之一

BPF_F_LOCK

查找自旋锁 map 的值,而不返回锁。 如果元素包含自旋锁,则必须指定此项。

成功后,映射中的 count 个元素将被更新。

如果返回错误且 errno 不是 EFAULT,则 count 设置为成功处理的元素数。如果 errnoEFAULT,则可能已删除最多 count 个元素。

返回值

成功返回零。 如果发生错误,则返回 -1,并适当地设置 errno

BPF_LINK_CREATE
描述

在指定的 attach_type 钩子上将 eBPF 程序附加到 target_fd,并返回用于管理链接的文件描述符句柄。

返回值

一个新的文件描述符(一个非负整数),如果发生错误,则返回 -1(在这种情况下,会适当地设置 errno)。

BPF_LINK_UPDATE
描述

将指定 link_fd 中的 eBPF 程序更新为 new_prog_fd

返回值

成功返回零。 如果发生错误,则返回 -1,并适当地设置 errno

BPF_LINK_GET_FD_BY_ID
描述

打开与 link_id 对应的 eBPF 链接的文件描述符。

返回值

一个新的文件描述符(一个非负整数),如果发生错误,则返回 -1(在这种情况下,会适当地设置 errno)。

BPF_LINK_GET_NEXT_ID
描述

获取当前加载到内核中的下一个 eBPF 链接。

查找 id 大于 start_id 的 eBPF 链接,并在成功时更新 next_id。如果没有其他 eBPF 链接的 id 高于 start_id,则返回 -1 并将 errno 设置为 ENOENT

返回值

成功返回零。 如果发生错误,或者没有剩余 id,则返回 -1,并适当地设置 errno

BPF_ENABLE_STATS
描述

启用 eBPF 运行时统计信息收集。

默认情况下禁用 eBPF 运行时的运行时统计信息收集,以最大限度地减少相应的性能开销。此命令全局启用统计信息。

多个程序可以独立启用统计信息。在收集所需的统计信息后,可以通过为此函数返回的文件描述符调用 close(2) 来再次禁用 eBPF 运行时统计信息。只有当之前对此子命令的所有未完成文件描述符都被关闭时,才会系统范围地禁用统计信息。

返回值

一个新的文件描述符(一个非负整数),如果发生错误,则返回 -1(在这种情况下,会适当地设置 errno)。

BPF_ITER_CREATE
描述

在指定的 link_fd 之上创建迭代器(如先前使用 BPF_LINK_CREATE 创建的),并返回一个可用于触发迭代的文件描述符。

如果使用 BPF_OBJ_PIN 将生成的文件描述符固定到文件系统中,则后续对该路径的 read(2) 系统调用将触发迭代器使用附加到 link_fd 的 eBPF 程序读取内核状态。

返回值

一个新的文件描述符(一个非负整数),如果发生错误,则返回 -1(在这种情况下,会适当地设置 errno)。

BPF_LINK_DETACH
描述

强制将指定的 link_fd 与其对应的连接点分离。

返回值

成功返回零。 如果发生错误,则返回 -1,并适当地设置 errno

BPF_PROG_BIND_MAP
描述

将映射绑定到 eBPF 程序的生命周期。

map_fd 标识的映射绑定到由 prog_fd 标识的程序,并且仅在 prog_fd 被释放时释放。这可以用于元数据应与程序关联的情况,否则该程序不包含对映射的任何引用(例如,嵌入在 eBPF 程序指令中)。

返回值

成功返回零。 如果发生错误,则返回 -1,并适当地设置 errno

BPF_TOKEN_CREATE
描述

创建 BPF 令牌,其中包含有关它允许的 BPF 相关功能的嵌入信息: - 一组允许的 bpf() 系统调用命令;- 如果允许 BPF_MAP_CREATE 本身,则使用 BPF_MAP_CREATE 命令创建的一组允许的 BPF 映射类型;- 如果允许 BPF_PROG_LOAD 本身,则使用 BPF_PROG_LOAD 命令加载的一组允许的 BPF 程序类型和 BPF 程序附加类型。

BPF 令牌是从 BPF FS 的实例创建(派生)的,假设它具有指定的必要委托挂载选项。此 BPF 令牌可以作为额外的参数传递给各种 bpf() 系统调用命令,以将 BPF 子系统功能授予非特权进程。

当创建时,BPF令牌会“关联”到它所派生的 BPF FS 实例(超级块)的所有者用户命名空间,后续使用 BPF 令牌执行的 BPF 操作将在该用户命名空间内执行能力检查(即,CAP_BPF、CAP_PERFMON、CAP_NET_ADMIN、CAP_SYS_ADMIN)。如果没有 BPF 令牌,则必须在 init 用户命名空间中授予此类能力,这在很大程度上使得 bpf() 系统调用与用户命名空间不兼容。

返回值

一个新的文件描述符(一个非负整数),如果发生错误,则返回 -1(在这种情况下,会适当地设置 errno)。

注意事项

eBPF 对象(映射和程序)可以在进程之间共享。

  • fork(2) 之后,子进程会继承引用相同 eBPF 对象的文件描述符。

  • 引用 eBPF 对象的文件描述符可以通过 unix(7) 域套接字传输。

  • 引用 eBPF 对象的文件描述符可以使用 dup(2) 和类似的调用以通常的方式进行复制。

  • 引用 eBPF 对象的文件描述符可以使用 bpf(2) 的 BPF_OBJ_PIN 命令固定到文件系统。

只有在所有引用该对象的文件描述符都已关闭,并且没有仍然固定在文件系统或附加的引用(例如,绑定到程序或设备)时,eBPF 对象才会被释放。