登录
首页 >  Golang >  Go问答

BPF尾调用的使用问题

来源:stackoverflow

时间:2024-02-23 13:30:30 413浏览 收藏

知识点掌握了,还需要不断练习才能熟练运用。下面golang学习网给大家带来一个Golang开发实战,手把手教大家学习《BPF尾调用的使用问题》,在实现功能的过程中也带大家重新温习相关知识点,温故而知新,回头看看说不定又有不一样的感悟!

问题内容

在以下代码中,bpf 程序 tail_prog 未从 main_prog 调用 tail:

#include 
#include 

struct bpf_map_def sec("maps") jump_table = {
   .type = bpf_map_type_prog_array,
   .key_size = sizeof(__u32),
   .value_size = sizeof(__u32),
   .max_entries = 8,
};

sec("xdp")
int main_prog(struct xdp_md *ctx) {
    bpf_printk("making tail call");
    bpf_tail_call(ctx, &jump_table, 0);

    return xdp_pass;
}

sec("xdp_1")
int tail_prog(struct xdp_md *ctx) {
    bpf_printk("inside tail call");

    return xdp_pass;
}

char _license[] sec("license") = "gpl";

我观察到仅打印了 main_prog 中的打印内容。

我正在使用 cilium 的 ebpf go 包加载 bpf 程序。以下是加载程序和地图的代码:

type BpfObjects struct {
    MainProg *ebpf.Program  `ebpf:"main_prog"`
    TailProg *ebpf.Program  `ebpf:"tail_prog"`
    JumpTable *ebpf.Map     `ebpf:"jump_table"`
}

    var objects BpfObjects

    spec, err := ebpf.LoadCollectionSpec("prog.o")

    if err != nil {
        log.Fatalln("ebpf.LoadCollectionSpec", err)
    }

    if err := spec.LoadAndAssign(&objects, nil); err != nil {
        log.Fatalln("ebpf.LoadAndAssign", err)
    }

    objects.JumpTable.Update(0, objects.TailProg.FD(), ebpf.UpdateAny)

据此,跳转表已从用户空间初始化,这就是我认为上面最后一行应该做的事情。但是,无论该行是否存在,我都没有看到任何区别。


正确答案


我没有查看从 update 函数返回的错误:update 无法编组密钥:编码 int:binary.write:无效类型 int。因此,程序数组映射没有更新。我更改为以下内容:

err = objects.JumpTable.Update(uint32(0), uint32(objects.CopyHttpHostnameProg.FD()), ebpf.UpdateAny)

    if err != nil {
        println("Update", err.Error())
    }

如果您传递 0 作为密钥,则密钥的大小为 8 个字节,这就是为什么您必须执行 uint32(0),它与映射的定义匹配。现在尾部调用成功了。

终于介绍完啦!小伙伴们,这篇关于《BPF尾调用的使用问题》的介绍应该让你收获多多了吧!欢迎大家收藏或分享给更多需要学习的朋友吧~golang学习网公众号也会发布Golang相关知识,快来关注吧!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>