eBPF

eBPF前生

BPF(Berkeley Packet Filter):用于过滤网络报文(packet)
两大特点:
1、过滤:根据用户输入规则过滤报文
2、拷贝:负责用网卡驱动层拷贝符合条件的数据包到用户空间
目的:解决当时包过滤机制效率低下的问题

eBPF、XDP链接

https://docs.cilium.io/en/v1.8/bpf/
http://arthurchiao.art/blog/cilium-bpf-xdp-reference-guide-zh/#prog_type_xdp

BPF应用示例

tcpdump -d -i lo tcp and dst port 7070

作用:只抓取流经本机的数据包
-d: 将输入的表达式转化为人类可读的看似汇编的代码

#以下代码可以在任意支持 tcpdump 的类 Unix 平台上运行,输出大同小异   
bash-3.2$ sudo tcpdump -d -i lo tcp and dst port 7070
(000) ldh [12]
(001) jeq #0x86dd jt 2 jf 6 #检测是否为 ipv6 报文,若为假(jf)则按照 ipv4 报文处理(L006)
(002) ldb [20]
(003) jeq #0x6 jt 4 jf 15 #检测是否为 tcp 报文
(004) ldh [56]
(005) jeq #0x1b9e jt 14 jf 15 #检测是否目标端口为 7070(0x1b9e),若为真(jt)则跳转 L014
(006) jeq #0x800 jt 7 jf 15 #检测是否为 ipv4 报文
(007) ldb [23]
(008) jeq #0x6 jt 9 jf 15 #检测是否为 tcp 报文
(009) ldh [20]
(010) jset #0x1fff jt 15 jf 11 #检测是否为 ip 分片(IP fragmentation)报文
(011) ldxb 4*([14]&0xf)
(012) ldh [x + 16] #找到 tcp 报文中 dest port 的所在位置
(013) jeq #0x1b9e jt 14 jf 15 #检测是否目标端口为 7070(0x1b9e),若为真(jt)则跳转 L014
(014) ret #262144 #该报文符合要求
(015) ret #0 #该报文不符合要求

tcp and dst port 8080:用户输入的过滤规则
Pseudo Machine Language(tcpdump经由libpcap转码而来的过滤包条件)

BPF JIT引入

JIT(Just-In-Time)Compiler(及时编译器),在一些特定硬件平台,进行提速
bpf_int_jit_compile(): 将传入的BPF伪代码加以编译,编译结果取代的原有的处理函数
sk_run_filter(): 负责报文到来时进行过滤的操作,提升效率

BPF演进

eBPF(extend BPF)的演进,应用场景扩展:流控,应用性能调优/监控,内核跟踪等,大大改进接口设计及易用性
硬件变革推动软件变革,系统开销已经从硬件转到软件:
1、硬件发展:如:NVMe
2、软件发展:如:多核异步编程Seastar,用户态高性能软件栈SPDK,DPDK,内核态演进eBPF、io_uring

eBPF Hooks

Where can you hook? Kernel functions(kprobes), userspace functions(uprobes), system calls, fentry/fexit, tracepoints, network devices(tc/xdp), network routes, TCP congestion algorithms. sockets(data level)

eBPF架构

eBPF可将用户态定义的代码段动态注入内核执行,无需重新编译内核
动态注入的过程:
1、用户态编写C代码,动态注入内核中执行
2、Llvm编译解析生成BPF字节码
3、代码安全检查(两轮检查)
4、用户空间与内核空间共享Map
5、无需重新编译内核源码,灵活高效,安全轻量
特点:
1、高效(先过滤后缓存)
2、灵活(用户自定义,动态注入内核,无需重新编译内核,可灵活挂载不同协议层Kernel函数)
3、安全(Verifier两轮检查)
4、轻量级

eBPF工具库

BCC提供python库,实现了map创建,代码编译,解析,注入等操作,使开发人员只需聚焦于C语言开发要注入的内核代码

posted @ 2020-08-20 13:26  ruixing  阅读(697)  评论(0编辑  收藏  举报