如何在接口之间共享 ebpf 映射

问题描述

是否可以在两个网络接口之间共享一个 ebpf Map。 我想编写一个 XDP 程序并将其挂接到两个设备上,即 eth0 和 eth1。实现要求它们都使用相同的映射。 是否可以加载相同的程序,将它们挂接到 eth0 和 eth1 并使用相同的 Map。

谢谢大家!

解决方法

是的,这完全有可能。 eBPF 映射附加到接口,它是在内核中创建的,然后由以下一个或多个引用:

  • 文件描述符,来自创建地图的应用程序,
  • 一个使用地图的 eBPF 程序,
  • 另一个专用类型映射(映射数组、映射哈希)中的引用,
  • eBPF 虚拟文件系统中的固定路径。

eBPF 映射可以在连续的程序运行之间、内核和用户空间之间共享,或者 - 对于您的用例 - 在不同的 eBPF 程序之间共享,无论它们连接到什么接口。请注意,无论如何,给定的程序甚至可以分离,然后重新附加到另一个界面。

对于多个程序重用一个地图,这是通过在加载程序时指向同一个地图来完成的:加载一个地图时会发生什么是你获得了地图的句柄(它的 id 或它的固定路径,对于例如),从该句柄获取映射的文件描述符,并在加载之前将此文件描述符放入您的 eBPF 字节码中。然后内核将文件描述符翻译成相关的内存地址。

在实践中大部分时间发生的是,这个“重定位”步骤(将文件描述符放在字节码中)由您用来加载程序的框架为您处理,例如 libbpf 或 bcc 工具。例如,libbpf 有一个 bpf_map__reuse_fd(struct bpf_map *map,int fd) 函数,可以在解析目标文件以提取字节码之后但在加载之前为程序使用的特定映射显式重用给定的文件描述符。