0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看威廉希尔官方网站 视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

基于ubuntu22.04-深入浅出 eBPF

Rice嵌入式开发威廉希尔官方网站 分享 2023-06-12 11:20 次阅读

笔者在很早之前就看eBPF这类似的文章,那时候看这个威廉希尔官方网站 一脸懵逼,不知道它是用来做什么,可以解决什么问题。所以也没有太关注这个威廉希尔官方网站 。很庆幸最近刚好有机会研究这个威廉希尔官方网站 。

什么是BPF

「BPF的全称是Berkaley Packet Filter,即伯克利报文过法器,它的设计思想来源于 1992 年Steven McCanne和Van Jacobson写的一篇论文“The BSD packet filter. A New architecture for user-level packet apture' (《BSD数据包过滤器:一种用于用户级数据包捕获的新休系结构》)。最初,BPF是在 BSD 内核实现的,后来,由于其出色的设计思想,其他操作系统也将其引入包括 Linux。」

53eb6f40-07f1-11ee-9c1d-dac502259ad0.png

「在这篇论文中,作者描述了他们如何在Unix内核实现网络数据包过滤,这种新的威廉希尔官方网站 比当时最先进的数据包过滤威廉希尔官方网站 快20倍。如下图来源于论文:」

543fb0f0-07f1-11ee-9c1d-dac502259ad0.png

「通俗易懂的理解上图,BPF是作为网络报文传输的旁路链路,当接收到的网络报文到达内阁驱动程序后,网络报文在传输给网络协议栈的同时,会额外将网络报文的副本传输给BPF。之后网络报文会经过BPF程序的内部逻辑进行过滤,最终再送到用户程序。」

「BPF 在数据包过滤上引入了两大革新:」

  • 一个新的虚拟机(VM)设计,可以有效地工作在基于寄存器结构的CPU之上;
  • 应用程序使用缓存只复制与过滤数据包相关的数据,不会复制数据包的所有信息,最大程度地减少BPF处理的数据,提高处理效率。

「我们熟悉的tcpdump就是基于BPF威廉希尔官方网站 ,好比一个神器站另外一个神器的绝作。」

什么是eBPF

BPF发展到现在名称升级为eBPF: 「extended Berkeley Packet Filter」。它演进成为了一套通用执行引擎,提供可基于系统或程序事件高效安全执行特定代码的通用能力,通用能力的使用者不再局限于内核开发者。其使用场景不再仅仅是网络分析,可以基于eBPF开发性能分析、系统追踪、网络优化等多种类型的工具和平台。

5463e196-07f1-11ee-9c1d-dac502259ad0.png

eBPF原理

** eBPF威廉希尔官方网站 架构图:**549d3d42-07f1-11ee-9c1d-dac502259ad0.png

eBPF主要分为用户空间程序与内核程序两大部分:

  • 在用户空间,程序通过LLVM/Clang被编译成eBPF可接受的字节码并提交到内核,以及负责读取内核回传的消息事件或统计信息。eBPF提供了两种内核态与用户态传递数据的方式,内核态可以将自定义perf_event消息事件发往用户态,或用户态通过文件描述符读写存储在内核中的k/v Map数据。

  • 在内核空间,为了稳定与安全,eBPF接收的字节码首先会交给Verifier进行安全验证,如验证程序循环次数,数组越界问题,无法访问的指令等等。只有校验通过的字节码才会提交到内核自带编译器或JIT编译器编译成可直接执行的机器指令。同时,eBPF对提交程序提出限制,如程序大小限制,最大可使用堆栈大小限制,可调用函数限制,循环次数限制等。

  • 从上面的架构图可以看出,eBPF在内核态会依赖内核探针进行工作,其中kprobes实现内核函数动态跟踪;uprobes实现用户函数动态跟踪;tracepoints是内核中的静态跟踪点;perf_events支持定时采样和PMC。

eBPF环境搭建

为了有一个eBPF程序编写验证的平台,我在ubuntu22.04中搭建了eBPF环境,ubuntu22.04安装流程在这里不在过多的介绍。「以下的操作都在root用户下执行」

  1. 更新系统的包索引和包列表:
#aptupdate
  1. 编译 BPF 程序需要系统安装必备的 linux-headers 包:
#sudoaptinstalllinux-headers-$(uname-r)
  1. 安装eBPF依赖工具:
#aptinstall-ybisonflexbuild-essentialgitcmakemakelibelf-devstracetarlibfl-devlibssl-devlibedit-devzlib1g-devpythonpython3-distutils
  1. 安装LLVM,并检查一下版本:
#aptinstallllvm
#llc-version
UbuntuLLVMversion14.0.0

.....
wasm32-WebAssembly32-bit
wasm64-WebAssembly64-bit
x86-32-bitX86:Pentium-Proandabove
x86-64-64-bitX86:EM64TandAMD64
xcore-XCore
#
  1. 安装Clang,并检查一下版本:
#aptinstallclang
#clang-version
Ubuntuclangversion14.0.0-1ubuntu1
Target:x86_64-pc-linux-gnu
Threadmodel:posix
InstalledDir:/usr/bin
#
  1. 查看但钱ubuntu的内核版本,安装对应的内核源码,并解压源码:
#apt-cachesearchlinux-source
linux-source-LinuxkernelsourcewithUbuntupatches
linux-source-5.19.0-Linuxkernelsourceforversion5.19.0withUbuntupatches
#aptinstalllinux-source-5.19.0
#cd/usr/src
#tar-jxvflinux-source-5.19.0.tar.bz2
#cdlinux-source-5.19.0
  1. 编译内核源码的bpf模块,如果没有报错,说明已经完成环境搭建:
#cp-v/boot/config-$(uname-r).config
#makeoldconfig&&makeprepare
#makeheaders_install
#apt-getinstalllibcap-dev
#makeM=samples/bpf
CCsamples/bpf/../../tools/testing/selftests/bpf/cgroup_helpers.o
CCsamples/bpf/../../tools/testing/selftests/bpf/trace_helpers.o
CCsamples/bpf/cookie_uid_helper_example.o
CCsamples/bpf/cpustat_user.o
CCsamples/bpf/fds_example.o
....

WARNING:Symbolversiondump"Module.symvers"ismissing.
Modulesmaynothavedependenciesormodversions.
Youmaygetmanyunresolvedsymbolwarnings.

eBPF样例编写

在内核源码的samples/bpf目录下提供了很多实例供我们学习,通过目录下的makefile就可以构建里面的bpf程序,如果我们用 C 语言编写的 BPF 程序编译可以直接在该目录提供的环境中进行编译。

samples/bpf 下的程序一般组成方式是 xxx_user.c 和 xxx_kern.c:

  • xxx_user.c:为用户空间的程序用于设置 BPF 程序的相关配置、加载 BPF 程序至内核、设置 BPF 程序中的 map 值和读取 BPF 程序运行过程中发送至用户空间的消息等。目前 xxx_user.c 与 xxx_kern.c 程序在交互实现都是基于 bpf() 系统调用完成的。直接使用 bpf() 系统调用涉及的参数和细节比较多,使用门槛较高,因此为了方便用户空间程序更加易用,内核提供了 libbpf 库封装了对于 bpf() 系统调用的细节。
  • xxx_kern.c:为 BPF 程序代码,通过 clang 编译成字节码加载至内核中,在对应事件触发的时候运行,可以接受用户空间程序发送的各种数据,并将运行时产生的数据发送至用户空间程序。

编写一个样例流程,在目录samples/bpf中新建两个文件:youyeetoo_user.c和youyeetoo_kern.c,并且在makefile中加入构建:

  1. youyeetoo_user.c的内容:
#include
#include
#include
#include"trace_helpers.h"

intmain(intac,char**argv)
{
structbpf_link*link=NULL;
structbpf_program*prog;
structbpf_object*obj;
charfilename[256];

snprintf(filename,sizeof(filename),"%s_kern.o",argv[0]);
obj=bpf_object__open_file(filename,NULL);
if(libbpf_get_error(obj)){
fprintf(stderr,"ERROR:openingBPFobjectfilefailedn");
return0;
}

prog=bpf_object__find_program_by_name(obj,"bpf_prog");
if(!prog){
fprintf(stderr,"ERROR:findingaproginobjfilefailedn");
gotocleanup;
}

/*loadBPFprogram*/
if(bpf_object__load(obj)){
fprintf(stderr,"ERROR:loadingBPFobjectfilefailedn");
gotocleanup;
}

link=bpf_program__attach(prog);
if(libbpf_get_error(link)){
fprintf(stderr,"ERROR:bpf_program__attachfailedn");
link=NULL;
gotocleanup;
}

read_trace_pipe();

cleanup:
bpf_link__destroy(link);
bpf_object__close(obj);
return0;
}

  1. youyeetoo_kern.c的内容:
#include
#include
#include
#include

SEC("tracepoint/syscalls/sys_enter_execve")
intbpf_prog1(structpt_regs*ctx)
{
charfmt[]="youyeetoo%s!n";
charcomm[16];
bpf_get_current_comm(&comm,sizeof(comm));
bpf_trace_printk(fmt,sizeof(fmt),comm);

return0;
}

char_license[]SEC("license")="GPL";
u32_versionSEC("version")=LINUX_VERSION_CODE;
  1. Makefile 文件修改:
#diff-uMakefile.oldMakefile
---Makefile.old2021-09-2603:16:16.883348130+0000
+++Makefile2021-09-2603:20:46.732277872+0000
@@-55,6+55,7@@
tprogs-y+=xdp_sample_pkts
tprogs-y+=ibumad
tprogs-y+=hbm
+tprogs-y+=youyeetoo

#Libbpfdependencies
LIBBPF=$(TOOLS_PATH)/lib/bpf/libbpf.a
@@-113,6+114,7@@
xdp_sample_pkts-objs:=xdp_sample_pkts_user.o
ibumad-objs:=ibumad_user.o
hbm-objs:=hbm.o$(CGROUP_HELPERS)
+youyeetoo-objs:=youyeetoo_user.o$(TRACE_HELPERS)

#Tellkbuildtoalwaysbuildtheprograms
always-y:=$(tprogs-y)
@@-174,6+176,7@@
always-y+=hbm_out_kern.o
always-y+=hbm_edt_kern.o
always-y+=xdpsock_kern.o
+always-y+=youyeetoo_kern.o

ifeq($(ARCH),arm)
#Stripallexcept-D__LINUX_ARM_ARCH__optionneededtohandlelinux

eBPF样例验证

  1. 编译样例:
#makeM=samples/bpf
CCsamples/bpf/../../tools/testing/selftests/bpf/cgroup_helpers.o
CCsamples/bpf/../../tools/testing/selftests/bpf/trace_helpers.o
CCsamples/bpf/cookie_uid_helper_example.o
CCsamples/bpf/cpustat_user.o
CCsamples/bpf/fds_example.o
....
LDsamples/bpf/youyeetoo
CLANG-bpfsamples/bpf/youyeetoo_kern.o
WARNING:Symbolversiondump"Module.symvers"ismissing.
Modulesmaynothavedependenciesormodversions.
Youmaygetmanyunresolvedsymbolwarnings.
  1. 在samples/bpf下查看编译结果,可以看到youyeetoo可执行文件:
#ls-alyouyeetoo*
-rwxr-xr-x1rootroot4079766919:08youyeetoo
-rw-r--r--1rootroot4516910:44youyeetoo_kern.c
-rw-r--r--1rootroot52166919:08youyeetoo_kern.o
-rw-r--r--1rootroot9976910:40youyeetoo_user.c
-rw-r--r--1rootroot33606919:08youyeetoo_user.o
  1. 在ubuntu中运行两个终端,用来测试youyeetoo:
54c3c17e-07f1-11ee-9c1d-dac502259ad0.png
  1. 在终端以运行youyeetoo可执行文件,在终端2中执行任意命令,在终端1查看程序是否能够监测到,如果成功监测到新进程运行便会输出一条“bpf_trace_printk: Hello”
54e76c46-07f1-11ee-9c1d-dac502259ad0.png


原文标题:基于ubuntu22.04-深入浅出 eBPF

文章出处:【微信公众号:Rice 嵌入式开发威廉希尔官方网站 分享】欢迎添加关注!文章转载请注明出处。


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • UNIX
    +关注

    关注

    0

    文章

    296

    浏览量

    41491
  • BPF
    BPF
    +关注

    关注

    0

    文章

    25

    浏览量

    4006
收藏 人收藏

    评论

    相关推荐

    基于ebpf的性能工具-bpftrace脚本语法

    ,并且介绍了如何运行bpftrace脚本,这篇文章将介绍bpftrace脚本的语法。 基于ubuntu22.04-深入浅出 eBPF 基于ebpf的性能工具
    的头像 发表于 09-04 16:04 1038次阅读
    基于<b class='flag-5'>ebpf</b>的性能工具-bpftrace脚本语法

    深入浅出AVR

    深入浅出AVR,一本书。
    发表于 07-15 12:02

    深入浅出玩转FPGA

    深入浅出玩转FPGA
    发表于 07-21 09:21

    深入浅出ARM7

    深入浅出ARM7
    发表于 08-18 10:12

    HDMI威廉希尔官方网站 深入浅出

    HDMI威廉希尔官方网站 深入浅出
    发表于 08-19 10:52

    深入浅出Android

    深入浅出Android
    发表于 08-20 10:14

    深入浅出Android

    深入浅出Android
    发表于 04-26 10:48

    深入浅出安防视频监控系统

    深入浅出安防视频监控系统深入浅出安防视频监控系统
    发表于 05-22 19:28

    深入浅出AVR

    深入浅出AVR
    发表于 08-23 10:10

    深入浅出数据分析

    深入浅出数据分析,有需要的朋友下来看看。
    发表于 01-15 14:22 0次下载

    深入浅出谈多层面板布线技巧

    深入浅出谈多层面板布线技巧
    发表于 12-13 22:20 0次下载

    深入浅出Android—Android开发经典教材

    深入浅出Android—Android开发经典教材
    发表于 10-24 08:52 15次下载
    <b class='flag-5'>深入浅出</b>Android—Android开发经典教材

    深入浅出数字信号处理

    深入浅出数字信号处理
    发表于 12-07 20:14 538次阅读

    基于ebpf的性能工具-bpftrace

    在前面我已经分享了关于ebpf入门的文章: 基于ubuntu22.04-深入浅出 eBPF 。 这篇文章介绍一个基于ebpf威廉希尔官方网站 的强大工具-
    的头像 发表于 09-04 16:02 682次阅读
    基于<b class='flag-5'>ebpf</b>的性能工具-bpftrace

    ebpf的快速开发工具--libbpf-bootstrap

    基于ubuntu22.04-深入浅出 eBPF 基于ebpf的性能工具-bpftrace 基于ebpf的性能工具-bpftrace脚本语法
    的头像 发表于 09-25 09:04 1014次阅读
    <b class='flag-5'>ebpf</b>的快速开发工具--libbpf-bootstrap