内核态约束
1. 内核态eBPF无法使用C语言标准库。因为不支持malloc,所以无法扩展skb空间且无法直接从内核态拷贝整个报文到用户态。
2. 内核态eBPF无法获取当前时间,bpf_ktime_get_ns函数返回系统启动后运行纳秒数,不包括系统暂停时间。
https://www.man7.org/linux/man-pages/man7/bpf-helpers.7.html
3. 内核态和用户态只能通过全局变量(本质也是map)和map来完成数据交互。推荐使用pinning map即持久化map,对应目录是/sys/fs/bpf/,方便用户态加载。
4. 内核态实时上报数据必须用BPF_MAP_TYPE_PERF_EVENT_ARRAY。写法参考cilium中上报trace和drop事件的map,定义在bpf/lib/events.h。
用户态约束
1. 用户态cilium/ebpf库中,bpf2go生成的go结构体首字母小写即开头是bpf,后面是变量名改成驼峰,只有main包才能访问。为了避免循环引用,可以通过go channel把别的包数据传递给main包。
2. 用户态cilium/ebpf库中,bpf2go使用反射把eBPF map内的数据转为go结构体,完成内核态与用户态之间传输。用户态手动定义结构体的问题在于,除了首字母大写,go-binary库不是简单的memcpy,可能会让go结构体成员读到的值是错误的。推荐自动生成Go结构体,bpf2go -type参数指定C结构体类型,C代码中加上struct key类型 *unused_xxx __attribute__((unused));
标签:map,bpf,eBPF,用户,约束,内核,go From: https://www.cnblogs.com/WJQ2017/p/18173195