c语言 - 像 "bpf_map_update_elem" 这样的 bps API 映射助手的详细流程是什么?



在我的理解中,当用户空间使用bpf_map_update_elem(int fd, void *key, void *value, __u64 flags)时,

首先,用户空间通过fd找到地图;

第二,用户空间在用户空间中形成内存;

和。。。。

我知道一点,但具体过程还不清楚。

所以我想知道用户空间运行 API 映射助手时的细节是什么。

因为你提到了"用户空间",我不确定你在说什么。因此,让我们从一些澄清开始。

BPF 映射(或至少大多数现有类型,包括哈希映射和数组(可以通过两种方式访问:

  • 从用户空间,由系统上运行并具有足够权限的任何应用程序
  • 从内核空间,从 BPF 程序

从用户空间来看,没有"助手"功能。与映射的交互完全(*(通过bpf()系统调用完成(BPF_MAP_LOOKUP_ELEMBPF_MAP_UPDATE_ELEMBPF_MAP_DELETE_ELEM命令作为其第一个参数传递给系统调用(。有关更多详细信息,请参阅bpf(2)手册页。这是您在用户空间应用程序中使用的内容,该应用程序将加载和管理 BPF 程序和映射,例如bpftool

从内核空间,即从 BPF 程序,事情的工作方式不同,访问是通过 BPF "助手"之一(如bpf_map_update_elem(struct bpf_map *map, const void *key, const void *value, u64 flags)(完成的。有关现有帮助程序的详细信息,请参见bpf-helpers(7)手册页。您可以在 Cilium 指南中找到有关这些帮助程序调用的详细信息,或者显然可以通过阅读内核代码(例如数组映射(找到。它们看起来像低级 C 函数调用,使用 BPF 寄存器传递必要的参数,然后它从 BPF 程序指令调用到作为内核二进制文件的一部分编译的帮助程序中。

所以你提到了bpf_map_update_elem()和用户空间。虽然这是内核端帮助程序的名称,但我怀疑您可能在谈论 libbpf 库提供的同名函数,以提供围绕bpf()系统调用的包装器。因此,此函数发生的情况非常简单。

无需从用户空间中的文件描述符
  • 中查找映射:实际上情况恰恰相反,文件描述符是从用户空间中的映射打开的(例如,从其映射 ID 或从/sys/fs/bpf 虚拟文件系统下的固定路径(。因此,fd 被传递给bpf()系统调用,并由内核用作对映射的引用。
  • 我不确定你的意思,但"用户空间在用户空间中产生内存"。这里不需要分配任何内存:此时keyvalue应该已经填满,它们通过bpf()系统调用传递给内核,以告知要更新的条目以及值。旗帜也是如此。
  • 一旦调用了bpf(),内核端发生的事情就相当简单了。大多数情况下,内核检查权限,验证参数(以确保它们安全且与映射一致(,然后更新实际数据。对于数组映射,最终会调用array_map_update_elem()(也与内核端的 BPF 帮助程序一起使用,请参阅上面的链接(。

(*( 某些交互实际上可以在没有bpf()系统调用的情况下完成,我相信使用存储在 BPF 映射中的"全局数据",使用内核内存mmap()的应用程序。但这超出了数组和映射的基本用法范围。

相关内容

  • 没有找到相关文章

最新更新