如何在不超出跳跃复杂度的情况下为大数据结构设计eBPF映射?

How to design eBPF map for large data structures without exceeding jump complexity?

提问人:Deputation 提问时间:11/8/2023 最后编辑:Deputation 更新时间:11/8/2023 访问量:46

问:

在过去的几个月里,我一直在与eBPF合作。

我一直在研究一个解决方案,由于某种原因,它要求我制作一个 BPF 映射,其中一个 u32 映射到包含数百个条目 (ACL) 的结构,让我演示一下:


struct array_of_elements
{
    /*some data, around 9 members, all necessary to perform a scan on TC ingress*/
};

struct data_structure
{
    struct array_of_elements arr[600];
};

struct
{
    __uint(type, BPF_MAP_TYPE_HASH);
    __uint(max_entries, 10000);
    __type(key, u32);
    __type(value, struct data_structure);
} internal_map SEC(".maps");

当我在 arr 中处理数据时,问题就出现了。我有几个循环,看起来像这样:

for (int i = 0; i < 600; i++)
{
    if (lookup_result->arr[i].present) { /* some processing */ }
}

将元素数量增加到 600 以上会触发“跳转复杂度过高”错误。该数组模拟 ACL,需要迭代才能进行处理。我尝试使用嵌套的 BPF 映射,但限制似乎是通过数组的循环,而不是数组本身。

我尝试实现内-外 BPF 映射设置,将 BPF 映射映射到 BPF 数组,但没有成功,因为这里的问题不是我有一个数组,而是我必须遍历它。

一个繁琐的解决方法是将数组元素用作哈希图中的键,但这种方法既不可扩展,也不可维护。对于这个问题,有没有更优雅的解决方案,在遵守验证者限制的同时避免过度循环?

Linux 网络 linux-kernel ebpf xdp-bpf

评论


答:

0赞 Dylan Reimerink 11/8/2023 #1

我建议研究一种映射类型,例如 LPM 或其他一些索引 ACL 的方法。即使您可以修复验证程序限制,您的程序也会很慢,这可能会影响数据包处理速度和吞吐量。

如果无法做到这一点,您应该考虑使用bpf_loop帮助程序。它被设计为允许大循环,而不会妨碍验证者。唯一的缺点是它至少需要 v5.17 的内核。