BPF
BPF是Berkeley Packet Filter这种冷门技术诞生于1992年,其作用是提高网络数据包过滤工具的性能。2013年,Alexei Starovoitov向Linux社区提交重新实现BP内核补丁,通过他和他Daniel Borkmann的共同完善,相关工作在2014年正式并入Linux内核主线。此举将BPF它已经成为一个更通用的执行引擎,可以完成各种任务,包括创建先进的性能分析工具。
BPF提供了一种在各种内核事件和应用程序事件发生时运行一小段程序的机制。该技术将内核变成完全可编程,允许用户定制和控制它们的系统,以解决现实问题。
BPF由指令集、存储对象和辅助函数组成的灵活高效的技术。由于采用了虚拟指令集规范,也可以视为虚拟机。这些指令由Linux内核的BPF具体来说,模块提供了两种执行机制:一种解释器和一种解释器BPF指令动态转换为本地化指令的即时指令(JIT)编译器。实际执行前,BPF指令必须先通过验证器(verifer)确保安全检查BPF程序本身不会崩溃或损坏内核。目前BPF网络、可观测性和安全性是三大应用领域。
eBPF
扩展后的BPF通常缩写为eBPF。eBPF增加了更多的寄存器,将字长从32位增加到64位,创造了灵活性BPF映射型存储(map),并允许调用一些有限的内核功能。同时eBPF设计为即时编译(JIT),机器指令和寄存器可以一对一映射。这使得以前的处理器本地指令优化技术得以应用BPF之上。BPF为了支持这些扩展,这些扩展,并且可以拒绝任何不安全的代码。
BPF Vs eBPF
对比项 | 经典BPF | 扩展BPF |
寄存器数量 | 二、寄存器A和X | 10个;R0~R9,此外R10只读帧指针寄存器 |
寄存器宽度 | 32位 | 64位 |
存储 | 16个内存槽:M[0~15] | 512字节大小的栈空间,无限映射存储 |
内核调用有限 | 非常受限,JIT专用 | 可用,通过bpf_call指令 |
支持的事件类型 | 网络数据包,sccomp-BFP | 网络数据包、内核函数、用户态函数、跟踪点、用户态标记PMC |
该技术简称最早的代码补丁eBPF(extended BPF),不过Alexiei然后把它改回来BPF。