Linux内核功能eBPF入门学习(一): BPF、eBPF、BCC等基本概念

您所在的位置:网站首页 linux50内核 Linux内核功能eBPF入门学习(一): BPF、eBPF、BCC等基本概念

Linux内核功能eBPF入门学习(一): BPF、eBPF、BCC等基本概念

2023-03-14 14:13| 来源: 网络整理| 查看: 265

目录 目录 说明 BPF eBPF带来的新变化 eBPF使用 升级内核 eBPF代码示例 eBPF代码编译装载 使用BCC简化eBPF应用开发过程 BCC安装 BCC收集的eBPF应用 参考 说明

eBPF是kernel 3.15中引入的全新设计,将原先的BPF发展成一个指令集更复杂、应用范围更广的“内核虚拟机”。

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

BCC是一个python库,实现了map创建、代码编译、解析、注入等操作,使开发人员只需聚焦于用C语言开发要注入的内核代码。 文章eBPF简史从eBPF的前身BPF讲起,将eBPF的来龙去脉介绍的很明白,是难得的好文章,建议直接过去阅读,这里就不摘抄了。 BPF: the universal in-kernel virtual machine介绍了BPF从网络子系统中的报文复制功能到内核通用虚拟机eBPF的演变过程。

BPF

BPF是很早就有的内核特性,在内核中将报文“镜像”了一份,并用BPF指令检查镜像出来的报文、决定报文的去留,即在1)抛弃报文和2)将其复制到用户空间之间抉择。

具体实现就不去了解了,BPF好歹设计了一套指令集,虽然比较简单,但没有扎实的编译原理基础,估计一时半会儿也看不懂,这里只收集一下相关文档:

The BSD Packet Filter: A New Architecture for User-level Packet Capture Kernel Documentation:BPF Documentation Linux Socket Filtering aka Berkeley Packet Filter (BPF)

另外学到了一个新知识,tcpdump使用的libpcap是基于BPF的,在使用tcpdump或者libpcap时传入的“host 192.168.1.1”、“tcp and port 80”等是过滤表达式。

过滤表达式会被编译成BPF指令,在tcpdump命令后面加上-d参数可以看到:

$ tcpdump -d -i eth0 tcp and port 80 (000) ldh [12] (001) jeq #0x86dd jt 2 jf 8 (002) ldb [20] (003) jeq #0x6 jt 4 jf 19 (004) ldh [54] (005) jeq #0x50 jt 18 jf 6 (006) ldh [56] (007) jeq #0x50 jt 18 jf 19 (008) jeq #0x800 jt 9 jf 19 (009) ldb [23] (010) jeq #0x6 jt 11 jf 19 (011) ldh [20] (012) jset #0x1fff jt 19 jf 13 (013) ldxb 4*([14]&0xf) (014) ldh [x + 14] (015) jeq #0x50 jt 18 jf 16 (016) ldh [x + 16] (017) jeq #0x50 jt 18 jf 19 (018) ret #65535 (019) ret #0

这些BPF指令是在内核中被BPF解释执行的。

eBPF带来的新变化

原先的BPF依然支持,用cBPF指代。eBPF全新设计了更丰富的指令集、增加了寄存器,性能大幅提高:

The original patch that added support for eBPF in the 3.15 kernel showed that eBPF was up to four times faster on x86-64 than the old classic BPF (cBPF) implementation for some network filter microbenchmarks, and most were 1.5 times faster.

增加了名为bpf的系统调用,为用户态程序提供与内核中的eBPF进行交互的途径:

int bpf(int cmd, union bpf_attr *attr, unsigned int size);

cmd是eBPF支持的cmd,分为三类: 操作注入的代码、操作用于通信的map、前两个操作的混合。

通过eBPF可以做更多的事情,不再仅仅是进行报文复制和过滤,网络方面可以切入到更深的层次,在更“靠前”的阶段进行干预,例如XDP借助eBPF在报文刚收到的时候就进行干预,使用XDP(eXpress Data Path)防御DDoS攻击。

还可以:

限制进程可以使用的系统调用,seccomp;

输出内核中的数据,进行内核调试、性能分析、调用跟踪;

调试用户态程序,Userland Statically Defined Tracepoints ;

eBPF使用

eBPF是kernel 3.15开始支持的,在kernel 3.17源码中获得了一个单独的bpf目录,建议直接使用3.17以及以上版本的内核。下面这四篇文章可以帮你搭建对eBPF的认知框架:

LWN.net: A thorough introduction to eBPF

LWN.net: An introduction to the BPF Compiler Collection

LWN.net: Some advanced BCC topics

LWN.net: Using user-space tracepoints with BPF

升级内核

见:CentOS7/6内核升级的简单方法:借助ELRepo,用yum命令更新内核。

eBPF代码示例

samples/bpf,暂时没有找到相关资料,目前以学习bcc的使用为主,2019-02-25 18:11:40

eBPF代码编译装载

同上一节。

使用BCC简化eBPF应用开发过程

BCC首先提供了一个名为bcc的python库,简化了eBPF应用的开发过程,然后它收集大量的eBPF应用,主要是性能分析相关的。 可以直接使用bcc已经收集的命令调查问题(bcc Tutorial),也可以用bcc提供的python库自己开发eBPF应用(bcc Python Developer Tutorial)。

Kernel版本需要是4.1以上(2019-02-25 18:08:15),并且要安装kernel-devel,如果没有安装kernel-devel,eBPF应用会汇编译失败(bcc收集的命令运行时也会出现下面错误):

# execsnoop chdir(/lib/modules/4.20.12-1.el7.elrepo.x86_64/build): No such file or directory Traceback (most recent call last): File "/usr/share/bcc/tools/execsnoop", line 166, in b = BPF(text=bpf_text) File "/usr/lib/python2.7/site-packages/bcc/__init__.py", line 318, in __init__ raise Exception("Failed to compile BPF text") Exception: Failed to compile BPF text BCC安装

直接用yum安装:

yum install bcc-tools

用rpm -ql可以看到所有bcc文件,tools/目录中是bcc提供的命令,可以用man查看对应的手册,比如man bcc-argdist:

$ rpm -ql bcc-tools /usr/share/bcc /usr/share/bcc/introspection /usr/share/bcc/introspection/bps /usr/share/bcc/tools /usr/share/bcc/tools/argdist /usr/share/bcc/tools/bashreadline /usr/share/bcc/tools/biolatency ... /usr/share/bcc/tools/doc /usr/share/bcc/tools/doc/argdist_example.txt /usr/share/bcc/tools/doc/bashreadline_example.txt /usr/share/bcc/tools/doc/biolatency_example.txt /usr/share/bcc/tools/doc/biosnoop_example.txt ... /usr/share/man/man8/bcc-argdist.8.gz /usr/share/man/man8/bcc-bashreadline.8.gz /usr/share/man/man8/bcc-biolatency.8.gz /usr/share/man/man8/bcc-biosnoop.8.gz /usr/share/man/man8/bcc-biotop.8.gz BCC收集的eBPF应用

BCC的命令较多,单开一篇笔记,这篇到此为止。

参考 张亦鸣: eBPF 简史 BCC - Tools for BPF-based Linux IO analysis, networking, monitoring, and more Kernel Documentation:BPF Documentation Linux Socket Filtering aka Berkeley Packet Filter (BPF) The BSD Packet Filter: A New Architecture for User-level Packet Capture A thorough introduction to eBPF XDP:eXpress Data Path How to Upgrade Kernel on CentOS 7 Welcome to the ELRepo Project CentOS7/6内核升级的简单方法:借助ELRepo,用yum命令更新内核 LWN.net: An introduction to the BPF Compiler Collection samples/bpf LWN.net: Some advanced BCC topics LWN.net: Using user-space tracepoints with BPF Installing BCC bcc Tutorial bcc Python Developer Tutorial BPF: the universal in-kernel virtual machine 使用XDP(eXpress Data Path)防御DDoS攻击


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3