几句话说清楚20:eBPF的机制

怎么出来的eBPF

用Linux Kernel Module来做一个类比说明eBPF诞生的目的。

Kernel Module的主要目的就是让用户可以通过这种机制,实现对内核的“赋能”,动态添加一些内核本身不支持的功能,比如硬件的驱动能力,新的文件系统或是系统调用。当然也可以融合到现有的内核处理流程中,比如在netfilter的某个hook点中添加包处理方法等。

Kernel Module的优点:

  • 动态添加/删除,无需重新编译内核
  • 减小内核体积

缺点:

  • 一旦出现BUG可能导致内核直接崩溃
  • 增加内核攻击面,影响内核安全

eBPF要做的事情也非常类似,但它想要克服Kernel Module的缺点,即确保执行的代码绝对安全。

eBPF的使用方式

为了达到这一目的,eBPF在内核中实现了一个虚拟机执行用户的指令。与Kernel Module直接在真实的物理硬件上执行用户的指令不同,eBPF提供给用户一个虚拟的RISC处理器,以及一组相关的指令。用户可以直接用这组指令编写程序。同时,程序在下发到该虚拟机之前也会经过eBPF的检查,比如会不会进入无限循环,会不会访问不合法的内存地址等等。只有在通过检查之后才可以进入执行的环节。

同时eBPF生态链中也有将高级语言转换成虚拟处理器指令的工具,这个主要靠LLVM提供。

eBPF的架构

对eBPF来说,和Kernle Module一样,也是通过特定的Hook点监听内核中的特定事件,进而执行用户定义的处理。这些Hook点包括:

  • 静态tracepoint
  • 动态内核态探针(Dynamic Kernel probes)
  • 动态用户态探针(Dynamic User Probes)
  • 其他hook点

针对主要是监控、跟踪使用的eBPF应用来说,主要通过这种方式取得内核运行时的一些参数和统计信息。例如,系统调用的参数值、返回值,通过eBPF map将得到的信息送给用户态程序,进而在用户态完成后处理流程。

另外一类应用则直接在一些内核处理流程中加入自己的处理逻辑,例如XDP,就是在网卡驱动和内核协议栈之间插入了eBPF扩展的网包过滤、转发功能。

© 2020 DecodeZ All Rights Reserved. 本站访客数人次 本站总访问量
Theme by hiero