1

因此,根据标题,我正在尝试加载 XDP 程序,但令人惊讶的是,bpf 验证程序会以著名的后端错误向我吐口水:

libbpf: load bpf program failed: Invalid argument
libbpf: -- BEGIN DUMP LOG ---
libbpf: 
back-edge from insn 271 to 69

libbpf: -- END LOG --
libbpf: failed to load program 'xdp_prog'

尽管在我受限的 ebpf C 代码中唯一的 for 循环(在编译时已知迭代次数)是由pragma unroll. __alwais_inline这是一个代码片段,显示了在d 函数中定义的受影响的 for 循环:

#pragma unroll
for (i = 0; i < 8; i++)
{
    int k = idx + i;
    mask = bpf_map_lookup_elem(&a_map, &k);
    if (!mask || (mask->an_idx == 0))
        return -1;

    *m_key = *key;
    foo(m_key, mask);  // an __alwais_inline func

    id = bpf_map_lookup_elem(&b_map, m_key);
    if (id)
    {
        *out_id = *id;
        return 0;
    }
}

也许问题在于clang无法展开循环?如果这是正确的,为什么它会失败,有什么解决方法吗?手动展开循环是不可接受的,因为它会导致可怕的、不可维护的和不可读的代码。

哦,我正在与:

  • 内核 4.19.3
  • llvm-clang 8

有什么想法吗?

更新
刚刚注意到,即使是下面的虚拟 for 循环似乎也没有展开,bpf 验证器抱怨后端:

#pragma unroll
for (i = 0; i < 8; i++)
{
    int k = i;
    mask = bpf_map_lookup_elem(&a_map, &k);
}

难道只有我,因为这没有任何意义吗?

4

1 回答 1

-1

我编写了以下代码,它可以工作。

#pragma clang loop unroll(full)
for (int i = 0; i < 128; i++)
{
    if (bpf_map_lookup_elem(&conntrack_hash_tab, &reply_key) == NULL)
    {
        break;
    }
    reply_key.dport = reply_key.dport+1;
}
于 2019-07-29T07:23:53.447 回答