BPF尾调用未被调用

huangapple go评论132阅读模式
英文:

BPF tail call not called

问题

在下面的代码中,tail_prog程序没有从main_prog中调用:

  1. #include <linux/bpf.h>
  2. #include <bpf/bpf_helpers.h>
  3. struct bpf_map_def SEC("maps") jump_table = {
  4. .type = BPF_MAP_TYPE_PROG_ARRAY,
  5. .key_size = sizeof(__u32),
  6. .value_size = sizeof(__u32),
  7. .max_entries = 8,
  8. };
  9. SEC("xdp")
  10. int main_prog(struct xdp_md *ctx) {
  11. bpf_printk("Making tail call");
  12. bpf_tail_call(ctx, &jump_table, 0);
  13. return XDP_PASS;
  14. }
  15. SEC("xdp_1")
  16. int tail_prog(struct xdp_md *ctx) {
  17. bpf_printk("Inside tail call");
  18. return XDP_PASS;
  19. }
  20. char _license[] SEC("license") = "GPL";

我观察到只有main_prog中的打印语句被打印出来。

我正在使用Cilium的eBPF Go包加载BPF程序。以下是加载程序和映射的代码:

  1. type BpfObjects struct {
  2. MainProg *ebpf.Program `ebpf:"main_prog"`
  3. TailProg *ebpf.Program `ebpf:"tail_prog"`
  4. JumpTable *ebpf.Map `ebpf:"jump_table"`
  5. }
  6. var objects BpfObjects
  7. spec, err := ebpf.LoadCollectionSpec("prog.o")
  8. if err != nil {
  9. log.Fatalln("ebpf.LoadCollectionSpec", err)
  10. }
  11. if err := spec.LoadAndAssign(&objects, nil); err != nil {
  12. log.Fatalln("ebpf.LoadAndAssign", err)
  13. }
  14. objects.JumpTable.Update(0, objects.TailProg.FD(), ebpf.UpdateAny)

根据这里的说明,跳转表必须从用户空间初始化,这就是我认为上面最后一行代码应该做的事情。然而,无论该行是否存在,我都没有看到任何区别。

英文:

In the following code BPF program tail_prog is not getting tail called from main_prog:

  1. #include &lt;linux/bpf.h&gt;
  2. #include &lt;bpf/bpf_helpers.h&gt;
  3. struct bpf_map_def SEC(&quot;maps&quot;) jump_table = {
  4. .type = BPF_MAP_TYPE_PROG_ARRAY,
  5. .key_size = sizeof(__u32),
  6. .value_size = sizeof(__u32),
  7. .max_entries = 8,
  8. };
  9. SEC(&quot;xdp&quot;)
  10. int main_prog(struct xdp_md *ctx) {
  11. bpf_printk(&quot;Making tail call&quot;);
  12. bpf_tail_call(ctx, &amp;jump_table, 0);
  13. return XDP_PASS;
  14. }
  15. SEC(&quot;xdp_1&quot;)
  16. int tail_prog(struct xdp_md *ctx) {
  17. bpf_printk(&quot;Inside tail call&quot;);
  18. return XDP_PASS;
  19. }
  20. char _license[] SEC(&quot;license&quot;) = &quot;GPL&quot;;

I observe only the print in main_prog is printed.

I'm loading the BPF programs using Cilium's eBPF Go package. Here's the code for loading the programs and maps:

  1. type BpfObjects struct {
  2. MainProg *ebpf.Program `ebpf:&quot;main_prog&quot;`
  3. TailProg *ebpf.Program `ebpf:&quot;tail_prog&quot;`
  4. JumpTable *ebpf.Map `ebpf:&quot;jump_table&quot;`
  5. }
  6. var objects BpfObjects
  7. spec, err := ebpf.LoadCollectionSpec(&quot;prog.o&quot;)
  8. if err != nil {
  9. log.Fatalln(&quot;ebpf.LoadCollectionSpec&quot;, err)
  10. }
  11. if err := spec.LoadAndAssign(&amp;objects, nil); err != nil {
  12. log.Fatalln(&quot;ebpf.LoadAndAssign&quot;, err)
  13. }
  14. objects.JumpTable.Update(0, objects.TailProg.FD(), ebpf.UpdateAny)

According to this, the jump table has be initialized from user space, which is what I think the last line above is supposed to do. However, I don't see any difference whether that line is there or not.

答案1

得分: 2

我没有注意到Update函数返回的错误:Update can't marshal key: encoding int: binary.Write: invalid type int。因此,程序数组映射没有被更新。我改成了以下方式:

  1. err = objects.JumpTable.Update(uint32(0), uint32(objects.CopyHttpHostnameProg.FD()), ebpf.UpdateAny)
  2. if err != nil {
  3. println("Update", err.Error())
  4. }

如果将0作为键传递,键的大小为8个字节,这就是为什么你需要使用uint32(0),以匹配映射的定义。现在尾调用成功了。

英文:

I wasn't looking at the error returned from the Update function: Update can&#39;t marshal key: encoding int: binary.Write: invalid type int. Therefore, the program array map was not updated. I changed to the following:

  1. err = objects.JumpTable.Update(uint32(0), uint32(objects.CopyHttpHostnameProg.FD()), ebpf.UpdateAny)
  2. if err != nil {
  3. println(&quot;Update&quot;, err.Error())
  4. }

If you pass 0 as the key, the size of the key is 8 bytes, which is why you have to do uint32(0), which matches the map's definition. Now the tail calls succeed.

huangapple
  • 本文由 发表于 2022年1月28日 05:45:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/70886166.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定