当前位置: 首页 > news >正文

13:eBPF 崛起——从一个包过滤器到一个完整的操作系统的可编程平台

大家好,我是毛衣哥。上一期讲了经典 BPF,这一期聊聊它的升级版——eBPF。它不再只是抓包工具了,它变成了一台可以塞进内核的瑞士军刀。说真的,第一次看到 eBPF 能干的事,我头都大了。

1992 年的 BPF 非常好——但二十多年过去了,它几乎没变过。它只能做一件事:过滤网络包。
2014 年,一个叫 Alexei Starovoitov 的内核工程师提交了一个补丁,把 BPF 扩展成了 eBPF(extended BPF)。
这个补丁彻底改变了 BPF 的命运——从此它不再是一个"网络包过滤器",它变成了一个"可以在内核里安全执行用户代码的平台"。


1992-2014:经典 BPF 的二十二年停滞期

经典 BPF 在 1992 年到 2014 年这 22 年里,几乎没有任何实质性的变化:

  • 还是那 2 个寄存器(A 和 X)
  • 还是那 11 条指令
  • 还是只能做网络包过滤
  • 程序大小被限制在 4096 条指令以内

为什么停滞了这么久?不是因为 BPF 不好——而是因为没有这个需求。

2000 年代的内核社区更关心的是:如何让 Linux 支持更多的硬件、如何提高文件系统的性能、如何完善虚拟化。没有人想过要用 BPF 来做除了网络包过滤之外的任何事情。

直到数据中心和云计算爆发,人们开始问:能不能在不修改内核代码的情况下,对内核进行观测和调试?


eBPF:不仅仅是"extended"

Alexei Starovoitov 在 2014 年向 Linux 内核社区提交了 eBPF 的初始实现(Linux 3.18,2014 年 12 月合并)。他对 BPF 做了根本性的扩展:

经典 BPF eBPF 寄存器数 2 个(A, X) 10 个(R0-R9 + 栈帧指针) 寄存器宽度 32 位 64 位 指令类型 11 种 100+ 种 Map(键值存储) 不支持 支持 内核辅助函数 不支持 200+ 个 JIT 编译器 无 x86_64、ARM64 等 程序大小上限 4096 指令 100 万指令 可附加的钩子点 只附加到 socket kprobe、tracepoint、XDP……

这已经不是 BPF 的"扩展"了——这是一次彻底的重新设计。


eBPF 能做什么

可观测性:
一段 eBPF 程序 attach 到内核的malloc()函数的入口和出口,记录每次调用的参数和返回值,通过 map 把统计结果传给用户态程序。不需要改一行应用代码,不需要重启进程。这就是 BCC 和 bpftrace 的基础。

网络安全:
在数据包进入完整的网络协议栈之前,eBPF(配合 XDP)可以决定:放行、丢弃、转发、甚至修改。Cloudflare 的 DDoS 防护系统就是用 XDP + eBPF 实现的,每秒可以处理数千万个数据包。

容器网络:
Cilium 用 eBPF 代替 iptables,直接在内核中生成高效的 BPF 程序来做包路由和负载均衡。传统的 iptables 是线性搜索(规则越多越慢),eBPF 用哈希表做路由查找(O(1)),性能差异巨大。

抓包:
在现代 Linux 上,tcpdump 可以选择使用 eBPF 作为后端。eBPF 的 JIT 编译器会把 BPF 字节码编译成本地机器码,比经典 BPF 的解释执行快 3-5 倍。


// eBPF 验证器伪代码(简化版) function verify_ebpf_program(prog): // 1. 控制流检查 cfg = build_control_flow_graph(prog.instructions) if has_loop(cfg): reject("BPF program contains loop!") // 2. 寄存器状态跟踪 for i, insn in enumerate(prog.instructions): state = track_registers(prog, i) if state.r0 == UNINIT and insn.uses_r0: reject("Use of uninitialized register R0!") // 3. 内存边界检查 for insn in prog.instructions: if insn.opcode == LDX and insn.offset > prog.max_packet_size: reject("Memory access out of bounds!") // 4. 辅助函数权限检查 for insn in prog.instructions: if insn.opcode == CALL: helper = get_helper(insn.func_id) if not helper.allow_unprivileged: if not current_process.has_capability(helper.required_cap): reject("Insufficient capabilities!") // 全部通过→加载到内核执行 load_to_kernel(prog) // eBPF 加载流程 function load_ebpf_program(prog_bytes): // 用户态:编译成 eBPF 字节码 prog = compile_to_ebpf(prog_bytes) // 内核态:验证器检查 if not verify_ebpf_program(prog): return ERROR // JIT 编译为本地机器码 native_code = jit_compile(prog) // 附加到钩子点(kprobe/tracepoint/XDP...) attach_to_hook(native_code, "kprobe/__alloc_skb") return OK

检查一:程序必须是 DAG(有向无环图)

**检查二:寄存器状态跟踪。**验证器逐条跟踪每条指令执行时每个寄存器的可能值。未初始化的寄存器被用于内存访问——拒绝。

**检查三:内存访问边界检查。**确保所有内存访问都在合法范围之内。

**检查四:辅助函数权限。**某些特定操作需要特定的能力(capability)。

这四道检查确保了:你加载的 eBPF 程序不可能搞崩内核。验证器在加载时就拒绝恶意程序——不会等到运行时。


经典 BPF vs eBPF——抓包场景下的性能

经典 BPF(解释执行): ~50-100 纳秒 eBPF(JIT 编译执行): ~10-30 纳秒

对 tcpdump 普通场景来说差异不大。对 Cilium 和 XDP 这种每秒处理千万级数据包的场景来说,3-5 倍的差异就非常显著了。


下期预告:环形缓冲区——内核和用户态之间的快递中转站。tcpdump 的-B参数到底在调什么?

DumpAny 怎么做:eBPF 和 DumpAny 解决的是不同层面的问题——eBPF 在内核里编程,DumpAny 在应用层做协议解析。但它们的扩展哲学是一样的:eBPF 通过 kprobe/tracepoint 等挂载点让开发者在内核的任意位置注入逻辑;DumpAny 通过协议插件机制让开发者在代理的任意阶段注入解析逻辑——收到 TCP 流 → 识别协议类型 → 分发到对应的解析器 → 格式化展示。一个是内核可编程,一个是代理可编程。同一个思想,差了 20 年的技术栈。


http://www.jsqmd.com/news/1392452/

相关文章:

  • SAP Gateway Task Gateway 中 Software Version 的配置原理与 Provider 路由机制
  • 2026智慧商业大数据可视化大屏推荐,企业该怎么选? - 选型|行业|价格|案例
  • LeetCode 1004:最大连续1的个数 III(滑动窗口) —— 题解
  • 老板一句“这个月线索为什么下降”,智能问数能查到什么?
  • 行业板块轮动因子实战从板块资金到因子建模的本地化Python全流程
  • Socket编程:客户端与服务器通信全解析(网络编程)
  • 代理(静态和动态)
  • 2026年消防设施操作员证报名入口,正规报考中心报名通道汇总 - 中科资质认证报考中心
  • 硬件测试内容之十三:LDO(芯片)
  • 郑州考公党必看!大学生毕业后档案存放流程!不用线下跑! - 实时传讯
  • 完整入门vscode-mermaid-preview:3步实现Mermaid图表实时预览与高清导出
  • 不同传感器前中后融合方案简介
  • 2026 年太原空调加氟空调出售,中央空调维修怎么预约? - LYL仔仔
  • Kettle数据迁移全复盘:从旧系统到新平台的8条实战经验清单
  • 手把手教你学 Simulink—— 整流器电磁干扰(EMI)滤波器设计与传导骚扰仿真
  • 【AI智能体速通】05.Agentic AI
  • Kimi LeetCode 3901. 好子序列查询 Python3实现
  • gcc编译器,以及源文件的翻译
  • 如何筛选靠谱的线上投票平台?2026年全场景通用投票工具深度评测
  • 从英语到斯瓦希里语,AI功能机的多语言适配怎么做?
  • POB汉化工具 PoeCharm 完整上手:3步安装与天赋技能配置实测
  • AI-实践 开发日志
  • 中国路况,中国速度——佳研 AI 让汽车碰撞仿真不再“卡脖子” - 2027品牌AI展
  • AI论文指令大合集:deepseek,kimi,豆包等各AI工具齐齐发力,轻松搞定论文写作难题
  • Databricks中用PySpark找到表里的最短唯一键
  • notepad-- 文件对比实战指南:3 步上手差异比对,5 个技巧让代码核查快 10 倍
  • TVA-具身智能最新进展(3):主动视觉感知提升实时性
  • 个体自发用 AI 提效已是职场常态,企业统一推进为何反而频频遇阻
  • 武汉江夏初中毕业生技术学校推荐 i3D AI 三维专业本地可参观试学 - 荆楚笔记
  • GHelper完整使用指南:如何用一个轻量小工具接管华硕笔记本性能控制