我正在使用tc
将我的eBPF(使用 clang 编译的 C 代码)附加到网络。
我正在使用eBPF Maps来存储一些数据。
具体来说,我用于从 BPF 程序内部bpf_map_update_elem
更新eBPF 映射,但我还想从程序外部更改映射的内容。
地图结构:
struct rt_val {
int ifaceno;
int macaddr[6];
};
union key_4 {
__u32 b32[2];
__u8 b8[8];
};
struct bpf_map_def SEC("maps") lpm_map_fwd = {
.type = BPF_MAP_TYPE_LPM_TRIE,
.key_size = 8,
.value_size = sizeof(struct rt_val),
.max_entries = 50,
.map_flags = BPF_F_NO_PREALLOC,
};
Run Code Online (Sandbox Code Playgroud)
地图更新和查找都很好。
但我想从程序执行外部动态更改 eBPF Map 的内容。
任何有关相同的意见/建议将不胜感激!
资源:
系统细节:
uname -r
:4.15.0-47-通用OS
:Ubuntu 18您已经找到了从用户空间更新 eBPF 映射所需的所有工具。
bpf()
系统bpf(cmd, attr, size)
调用用于执行更新。作为第一个参数传递cmd
的指示您要执行什么类型的操作:在您的情况下,这将是BPF_MAP_UPDATE_ELEM
. 然后您链接的手册页解释了如何构建attr
:在您的情况下(用于地图更新),它应该是:
struct { /* Used by BPF_MAP_*_ELEM and BPF_MAP_GET_NEXT_KEY commands */
__u32 map_fd;
__aligned_u64 key;
union {
__aligned_u64 value;
/* [...] */
};
__u64 flags;
};
Run Code Online (Sandbox Code Playgroud)
这意味着您应该构建一个union bpf_attr
并将文件描述符传递给映射、要更新的条目的键、该键的新值以及可能的一些标志。
可以获得地图的文件描述符:
bpf()
使用以下命令再次调用系统调用BPF_MAP_GET_FD_BY_ID
,bpf()
,但在您使用 tc 加载程序的情况下则不然)。请注意,libbpf(随内核一起提供或在 GitHub 上镜像)提供了bpf()
系统调用的包装器,可以使事情变得更容易。
实际上,您不需要重新实现所有这些。正如您在标题中提到的,bpftool 允许您从命令行更新地图,而无需重新实现整个过程。
编辑:在 Ubuntu 19.10 (eoan) 上,bpftool 打包为linux-tools-common
软件包的一部分。请阅读以下有关旧版本的说明。
截至撰写本文时,bpftool 尚未针对Debian/Ubuntu 进行打包,这意味着您必须从源代码构建它。它是随内核一起提供的,因此下载需要一些时间,但构建实际上非常简单:
struct { /* Used by BPF_MAP_*_ELEM and BPF_MAP_GET_NEXT_KEY commands */
__u32 map_fd;
__aligned_u64 key;
union {
__aligned_u64 value;
/* [...] */
};
__u64 flags;
};
Run Code Online (Sandbox Code Playgroud)
或者,此页面上打包有一个非官方版本(免责声明:来自我的公司)。打包的二进制文件是静态构建的,应该可以在所有 x86_64 Linux 机器上运行。
之后,您可以使用它列出系统上当前存在的地图:
$ git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
$ cd linux
$ cd tools/bpf/bpftool
$ make
(# make install)
(# make doc doc-install)
Run Code Online (Sandbox Code Playgroud)
每个地图的 ID 将显示在左侧。找到与要更新的地图相关的 ID(或者如果地图已固定,请记下其路径,随选项一起显示-f
),然后使用以下选项之一:
# bpftool -f map show
Run Code Online (Sandbox Code Playgroud)
例如:
# bpftool map update id <id> key <key> value <new_value>
# bpftool map update pinned <path> key <key> value <new_value>
Run Code Online (Sandbox Code Playgroud)
(注意:我会使用 s 数组__u8
而不是int
s 来在您的 中存储 MAC 地址struct rt_val
。您的macaddr
可能会占用 24 个字节。)
如果您不确定值如何存储在地图中,请立即将其转储到控制台中:
# bpftool map update id 17 key 0x1 0 0 0 0 0 0 0 value 0x1 0x2 0x3...
Run Code Online (Sandbox Code Playgroud)
我不知道任何现有的 bpftool 教程,但您可以在该工具的手册页中找到所有详细信息。我还在Twitter 上写了一些有关它的提示。
归档时间: |
|
查看次数: |
7774 次 |
最近记录: |