目录

文章目录

  • 目录
  • eBPF 诞生的背景
  • eBPF
  • eBPF 与 cBPF 的区别
  • eBPF 与 Kernel 的区别
  • eBPF 的逻辑框架
  • eBPF 的运行原理
  • eBPF 的整体设计
    • eBPF JIT Compiler
    • eBPF Verifier
    • eBPF Maps
    • eBPF Helpers
    • eBPF Hooks
    • eBPF Tail and Function Calls

eBPF 诞生的背景

Linux Kernel 原有的的一个数据包过滤模块是 netfilter,其具有很好的扩展性,能够满足大部分网络应用需求。但该框架也存在很多明显问题:

  1. 路径太长:netfilter 框架在 TCP/IP Stack 的 L3 Layer,报文需要先经过 L2,IP 层才能开始处理。那么,如果执行的只是丢弃报文的话,就会白白浪费了很多 CPU 资源,影响整体性能;

  2. 规则太多:netfilter 框架类似于一套可以自由添加策略/规则的专家系统,并没有对规则进行合并优化,这些都严重依赖操作人员技术水平,随着规模的增大,规则数量 n 成指数级增长,而报文处理又是 O(N) 复杂度,最终性能会直线下降。

  3. O(N) 复杂度:如下图,极端情况下,报文需要依次遍历所有 Rules,才被匹配,这也会极大影响地报文处理性能;

总的来说,TCP/IP Stack 是为了通泛型场景准备的,不针对特殊型场景。

例如最经典的高性能转发场景。随着互联网流量越来愈大,网卡性能越来强。Linux Kernel TCP/IP Stack 在 10Mbps、100Mbps 网卡的慢速时代是可以满足需求的,而现在到了 1000Mbps、10Gbps、40Gbps、100Gbps 网卡的时代,TCP/IP Stack 复杂的处理逻辑就捉襟见肘了,会把大量报文堵在内核里。

为了解决这个问题有 1 个思路,2 种方式。思路就是 Bypass Kernel,方式就是:

  1. Upload(Userspace Stack):DPDK/VPP、XDP/eBPF etc.
  2. Offload(Smart NIC):FPGA、P4、XDP/eBPF etc.

eBPF

2014 年,Alexei Starovoitov 实现了 eBPF(extended Berkeley Packet Filter,扩展的 BPF)。eBPF 最早出现在 Kernel 3.18,此后原来的 BPF 就被称为 cBPF(classic BPF,经典 BPF),cBPF 现在已经基本废弃了,被 eBPF 取代。

经过 Extend(扩展)后,eBPF 演进成为了一个通用的执行框架,不再像 BPF 只能被特定的应用程序使用。eBPF 现在可以广泛的被用于观测(跟踪、性能调优等)、安全、网络等多个领域。这使得 eBPF 不再局限于 Kernel TCP/IP Stack,已经成为了 Kernel 的顶级子系统,即:eBPF 子系统。

目前,Facebook、NetFlix 、CloudFlare 等知名互联网公司内部广泛采用基于 eBPF 技术的各种程序用于性能分析、排查问题、负载均衡、防范 DDoS 攻击,据相关信息显示在 Facebook 的机器上内置一系列 eBPF 的相关工具。

eBPF 与 cBPF 的区别

  1. cBPF 支持的功能比较单一,只能够作用于网络的数据包的过滤上;而 eBPF 除了能够支持网络的数据包的过滤上,也支持其他的事件类型,例如:XDP、Perf Event、kprobe、tracepoint 等。cBPF 的功能在 eBPF 其实对应的就是 Socket 的部分。

  2. 引入 Map 机制。在 cBPF 我们通过接收队列将过滤后数据获取出来,但是在 eBPF 我们可以将数据放到 Map 存储中。Map 存储是 Userspace 和 Kernel 共享的,所以一般是在 Kernel 中将数据存入到 Map 中,然后在 Userspace 可以直接取出数据。

  3. 指令集变得更复杂了,与此同时,有了专门的用于编译 BPF bytecode 的编译器 LLVM/Clang。

  4. 还有在安全机制方面等等一些改变。

eBPF 与 Kernel 的区别

eBPF 的逻辑框架

eBPF 最核心的转变是,将 eBPF 的应用程序扩展到了 User Space,这成为了 BPF 技术的转折点。正如 Alexei 在提交补丁的注释中写到:“这个补丁展示了 eBPF 的潜力”。

需要注意的是,正如前文所述,cBPF 是 tcpdump 等应用程序所使用的数据包过滤语言,但新的 Linux Kernel 只运行 eBPF,所以 cBPF bytecode 会在程序执行之前被透明地转换为 Kernel 中的 eBPF 形式。

由此,我们通常统一称呼 eBPF 在 Userspace 的应用程序扩展为 BPF Program,而不区分 cBPF 或 eBPF,但我们也同样知道,Kernel 中已经没有 cBPF 了。

BPF Program 强调安全性和稳定性,看上去更像 Kernel Module,但不同,eBPF Program 不需要重新编译 Kernel 就可以安全运行,而不会造成 OS 的崩溃。

eBPF 的运行原理

BPF Program 是基于事件触发的。首先需要将 BPF Program Attach 到某个事件上,当这个事件触发时,就会执行这个 BPF Program。这就是 BPF Program 的工作原理。

例如:我们将 BPF Program Attach 到 kprobe 类型的事件上,这个 kprobe 事件是个函数,当 CPU 执行到这个函数时,就会触发执行我们的 BPF Program。

eBPF 的整体设计

可见,BPF 不仅是提供了 VM-Like 的指令集,并且还提供了围绕其自身的高级基础设施,例如:

  • Key/Value Store Map。
  • 利用了 Kernel Function 的辅助函数。
  • 调用其他 BPF Program 的尾调用。
  • 安全加固原语。
  • 用于储存对象(Map、程序)的伪文件系统。
  • 允许将 BPF 卸载到 NIC 的基础功能。

而 LLVM/Clang 则提供了一个 BPF backend,由此可以使用像 Clang 这样的工具将 C 编译成 BPF 目标文件,然后可以将其加载到 Kernel 中。

eBPF JIT Compiler

eBPF JIT Compiler 是一个 VM-Like 实现。在 Userspace 使用 C 语言编写程序,然后在前端使用 LLVM/Clang 编译生成 BPF bytecode,再加载到 Kernel 中,由 JIT Compiler 将 bytecode 编译成 CPU 平台指令集。

eBPF JIT Compiler 支持 BPF Program 的动态加载和卸载,同时还保证了 CPU 平台的执行性能。

eBPF Verifier

BPF Program 是程序员编写的程序,需要在加载进 Kernel 之前进行安全性检查。

Verifier(程序校验器)就是在将 BPF bytecode 加载到 Kernel 之前对 bytecode 进行安全检查,例如:判断是否有循环,程序长度是否超过限制,程序内存访问是否越界,程序是否包含不可达的指令等。Verifier 会拒绝任何不安全的 BPF Program,并提供安全沙箱运行环境。

eBPF Maps

eBPF Maps 的本质是 Key/Value Store,作为 BPF 框架中的用户态程序和内核态程序之间、以及内核态程序之间的通信媒介,类似于进程间通信的共享内存访问。

用户态程序可以在 BPF Maps 中预定义规则,BPF Program 匹配 Maps 中的规则对数据包进行过滤等。BPF Program 将数据包统计信息存入 Maps,用户态程序可访问 Maps 获取数据包统计信息。

BPF Map 的类型:

  • Hash tables, Arrays
  • LRU (Least Recently Used)
  • Ring Buffer
  • Stack Trace
  • LPM (Longest Prefix match)

BPF Map 的作用:

  • 查看程序状态。
  • 进行程序配置。
  • 程序间共享数据。
  • 和用户空间共享状态、指标和统计。

eBPF Helpers

eBPF Helpers 内含了一系列 Kernel 的辅助函数,包括:

  • 访问 Socket。
  • 访问进程栈。
  • 访问 System Call 的参数。
  • 访问进程或 cgroup 的上下文。
  • 访问 Map。
  • 获取当前时间。
  • 生成随机数。
  • 处理网络数据包和转发。
  • 执行尾调用。
  • etc.

eBPF Hooks

Hooks(挂钩点):

  • Userspace 函数(uprobes)
  • System Calls
  • Kernel 函数(kprobes)
  • fentry/fexit
  • Tracking Point
  • 网络设备(tc、XDP)
  • 网络路由
  • TCP 拥塞算法
  • Socket(数据面)

eBPF Tail and Function Calls

尾调用的作用:

  • 将 BPF Program 链接在一起。
  • 将 BPF Program 拆分为独立的逻辑组件。
  • 使 BPF Program 可组合。

函数调用的作用:

  • 重用内部的功能程序。
  • 减少程序大小(避免内联)。

XDP/eBPF — eBPF相关推荐

  1. DPDK and XDP and ebpf

    另外除了以下文章还有个ebpf https://qiita.com/sg-matsumoto/items/8194320db32d4d8f7a16 图片上传有问题,原文参考 https://cloud ...

  2. 一文读懂eBPF/XDP

    目录 XDP概述 XDP数据结构 XDP与eBPF的关系 XDP操作模式 XDP操作结果码 XDP和iproute2加载器 XDP和BCC XDP概述 XDP是Linux网络路径上内核集成的数据包处理 ...

  3. 聊聊风口上的 eBPF

    eBPF 是一个用于访问 Linux 内核服务和硬件的新技术,由于其灵活性和高性能等特点,被迅速用于网络.出错.跟踪以及防火墙等多场景.目前国内已有少数企业开始尝试将 eBPF 引入生产实践,又拍云也 ...

  4. ebpf深入理解和应用介绍

    1. ebpf概述 1.1 ebpf发展历史 BPF,及伯克利包过滤器Berkeley Packet Filter,最初构想提出于 1992 年,其目的是为了提供一种过滤包的方法,并且要避免从内核空间 ...

  5. Sysdig and Falco now powered by eBPF

    By Gianluca Borello on February 27, 2019 https://sysdig.com/ 目录 An introduction to eBPF eBPF purpose ...

  6. [译转] eBPF 概念和基本原理

    译文:https://cloud.tencent.com/developer/article/1749470 https://tonydeng.github.io/sdn-handbook/linux ...

  7. eBPF学习记录(一)eBPF介绍

    一.什么是eBPF eBPF, 从它的全称"扩展的伯克利数据包过滤器 (Extended Berkeley Packet Filter)" 来看,它是一种数据包过滤技术,是从 BP ...

  8. eBPF(extended Berkeley Packet Filter):Linux系统最具颠覆性的“白盒测试”

    eBPF--Linux系统地图上的"沙盒游戏" 简单介绍eBPF eBPF为什么叫eBPF eBPF家族和全局概览 成熟的eBPF使用场景 跟踪和采样 可视化和监控 网络 安全 e ...

  9. 深入理解 Linux eBPF:一个完整阅读清单(转载)

    linux eBPF是3.17内核开始引入的一个全新设计,代码目录主要在kernel/bpf 下,它的全称是 extended BPF(eBPF), 目前关于eBPF的资料还比较乱,很难得看到一篇对e ...

最新文章

  1. Libgdx学习笔记:Simple text input
  2. 知识图谱(历史回顾及技术挑战)
  3. linux系统取消自检,[转载]取消Linux启动自检
  4. Python基础入门一(2)
  5. python聚类dbscan案例经纬度_用DBSCAN聚类经纬度坐标
  6. 走近webpack(3)--图片的处理
  7. 前端学习(661):逻辑运算符
  8. 学习10:Python重要知识
  9. 路由重分布列表控制例子
  10. redis3.0搭建分布式集群
  11. 管理中的计算机应用真题,0051管理系统中计算机应用试题历年真题
  12. 生成式模型(generative) vs 判别式模型(discriminative)
  13. mapper mysl实现批量插入 更新
  14. [25年后的统计系会是什么样?
  15. 大神总结的一套PCB学习方法! 真得很受用!
  16. Vue 之 .eslintrc.js 文件
  17. 好的示波器可以显示正常的方波,自己制作示波器只有正弦波
  18. 腾讯云点播视频播放器使用步骤 uniapp
  19. 接口授权时已经有access_token了为啥还需要refresh_token
  20. 马化腾:电力时代孕育了计算机,人工智能兴盛于云计算

热门文章

  1. php 5.2.17 mysql_Apache 2.2.15 整合php 5.2.17 Mysql-5.5.8
  2. oracle下使用sql命令,ORACLE笔记(2)ORACLE 学习中用到的SQL命令
  3. 用 js判断 一个数是否是素数(质数)_2020-09-20:如何判断一个数是质数?
  4. java枚举体_Java枚举体
  5. Objetive-C枚举位移操作Swift枚举位移操作
  6. 在你休息时,你的大脑运动皮层中重放习得的神经放电序列
  7. UE4全景插件Nvidia Ansel Photography
  8. java 数据合并算法_Java与算法之(11) - 合并排序
  9. 马斯克躺枪得州最严堕胎法案,因拒绝表态遭炮轰!“不站女权就抵制特斯拉”...
  10. 李飞飞点赞「ARM」:一种让模型快速适应数据变化的元学习方法 | 开源