bpf

BPF 的全称是 Berkeley Packet Filter,是一个用于过滤(filter)网络报文(packet)的架构。(例如tcpdump),目前称为Cbpf(Classical bpf)。BPF 在数据包过滤上引入了两大革新:

由于这些巨大的改进,所有的 Unix 系统都选择采用 BPF 作为网络数据包过滤技术,直到今天,许多 Unix 内核的派生系统中(包括 Linux 内核)仍使用该实现。

ebpf

eBPF演进为一个通用执行引擎,可基于此开发性能分析工具、软件定义网络等诸多场景,原来的 BPF 就被称为经典 BPF,缩写cBPF(classic BPF),cBPF现在已经基本废弃。现在,Linux 内核只运行eBPF。

eBPF全称extended BPF,Linux Kernel 3.15 中引入的全新设计, 是对既有BPF架构进行了全面扩展,一方面,支持了更多领域的应用,比如:内核追踪(Kernel Tracing)、应用性能调优/监控、流控(Traffic Control)等;另一方面,在接口的设计以及易用性上,也有了较大的改进。

eBPF支持在用户态将C语言编写的一小段“内核代码”注入到内核中运行,注入时要先用llvm编译得到使用BPF指令集的 ELF 文件,然后从ELF文件中解析出可以注入内核的部分,最后用 bpf_load_program() 方法完成注入。 用户态程序和注入到内核中的程序通过共用一个位于内核的 eBPF MAP实现通信。为了防止注入的代码导致内核崩溃,eBPF 会对注入的代码进行严格检查,拒绝不合格的代码的注入。

  1. eBPF prog load的严格的verify机制
  2. eBPF访问内核资源需借助各种eBPF 的helper func,helper func函数能在最坏的情况下保证安全
  3. 现在,Linux 内核只运行 eBPF,内核会将加载的BPF字节码 透明地转换成 eBPF 再执行

Untitled

eBPF程序执行过程

用户态程序与内核态程序交互