九色91_成人精品一区二区三区中文字幕_国产精品久久久久一区二区三区_欧美精品久久_国产精品99久久久久久久vr_www.国产视频

Hello! 歡迎來(lái)到小浪云!


基于ubuntu22.04-深入淺出 eBPF


我早前接觸ebpf技術(shù)時(shí),對(duì)其用途和解決的問(wèn)題一頭霧水,因此未能深入研究。幸運(yùn)的是,近期我有機(jī)會(huì)深入探討這一技術(shù)。

什么是BPF?BPF,即Berkley Packet Filter(伯克利報(bào)文過(guò)濾器),其設(shè)計(jì)靈感來(lái)源于1992年Steven McCanne和Van Jacobson撰寫(xiě)的論文《The BSD packet Filter: A New architecture for user-level packet capture》(《BSD數(shù)據(jù)包過(guò)濾器:一種用于用戶級(jí)數(shù)據(jù)包捕獲的新體系結(jié)構(gòu)》)。最初,BPF是在BSD內(nèi)核中實(shí)現(xiàn)的,后因其卓越的設(shè)計(jì)理念,被其他操作系統(tǒng)Linux所采用。

基于ubuntu22.04-深入淺出 eBPF該論文中,作者描述了他們?cè)?a href="http://www.albr2v3.cn/help/index.php/tag/unix">unix內(nèi)核中實(shí)現(xiàn)網(wǎng)絡(luò)數(shù)據(jù)包過(guò)濾的方法,這種新技術(shù)比當(dāng)時(shí)最先進(jìn)的數(shù)據(jù)包過(guò)濾技術(shù)快20倍。下圖來(lái)自論文:

基于ubuntu22.04-深入淺出 eBPF簡(jiǎn)而言之,BPF作為網(wǎng)絡(luò)報(bào)文傳輸?shù)呐月锋溌罚?dāng)接收到的網(wǎng)絡(luò)報(bào)文到達(dá)內(nèi)核驅(qū)動(dòng)程序后,報(bào)文在傳輸給網(wǎng)絡(luò)協(xié)議的同時(shí),會(huì)將其副本傳輸給BPF。之后,報(bào)文會(huì)通過(guò)BPF程序的內(nèi)部邏輯進(jìn)行過(guò)濾,最終再送到用戶程序。

BPF在數(shù)據(jù)包過(guò)濾上引入了兩大創(chuàng)新:

  1. 一個(gè)新的虛擬機(jī)(VM)設(shè)計(jì),能夠有效地在基于寄存器結(jié)構(gòu)的CPU上運(yùn)行;
  2. 應(yīng)用程序使用緩存只復(fù)制與過(guò)濾數(shù)據(jù)包相關(guān)的數(shù)據(jù),不會(huì)復(fù)制數(shù)據(jù)包的所有信息,最大程度地減少BPF處理的數(shù)據(jù),提高處理效率。我們熟悉的tcpdump就是基于BPF技術(shù),堪稱一個(gè)神器。

什么是eBPF?BPF發(fā)展至今,已升級(jí)為eBPF,即「extended Berkeley Packet Filter」。它演變成了一套通用執(zhí)行引擎,提供基于系統(tǒng)或程序事件高效安全執(zhí)行特定代碼的能力,不再局限于內(nèi)核開(kāi)發(fā)者。其應(yīng)用場(chǎng)景擴(kuò)展到網(wǎng)絡(luò)分析、性能分析、系統(tǒng)追蹤、網(wǎng)絡(luò)優(yōu)化等多種類型的工具和平臺(tái)。

基于ubuntu22.04-深入淺出 eBPFeBPF技術(shù)架構(gòu)圖:

基于ubuntu22.04-深入淺出 eBPFeBPF主要分為用戶空間程序與內(nèi)核程序兩部分:

在用戶空間,程序通過(guò)LLVM/Clang編譯成eBPF可接受的字節(jié)碼并提交到內(nèi)核,并負(fù)責(zé)讀取內(nèi)核回傳的消息事件或統(tǒng)計(jì)信息。eBPF提供了兩種內(nèi)核態(tài)與用戶態(tài)傳遞數(shù)據(jù)的方式,即內(nèi)核態(tài)可以將自定義perf_event消息事件發(fā)往用戶態(tài),或用戶態(tài)通過(guò)文件描述符讀寫(xiě)存儲(chǔ)在內(nèi)核中的k/v map數(shù)據(jù)。在內(nèi)核空間,為了確保穩(wěn)定與安全,eBPF接收的字節(jié)碼首先會(huì)交給Verifier進(jìn)行安全驗(yàn)證,如驗(yàn)證程序循環(huán)次數(shù)、數(shù)組越界問(wèn)題、無(wú)法訪問(wèn)的指令等。只有通過(guò)校驗(yàn)的字節(jié)碼才會(huì)提交到內(nèi)核自帶編譯器或JIT編譯器編譯成可直接執(zhí)行的機(jī)器指令。同時(shí),eBPF對(duì)提交程序提出限制,如程序大小限制、最大可使用大小限制、可調(diào)用函數(shù)限制、循環(huán)次數(shù)限制等。從架構(gòu)圖中可以看出,eBPF在內(nèi)核態(tài)依賴內(nèi)核探針工作,其中kprobes實(shí)現(xiàn)內(nèi)核函數(shù)動(dòng)態(tài)跟蹤;uprobes實(shí)現(xiàn)用戶函數(shù)動(dòng)態(tài)跟蹤;tracepoints是內(nèi)核中的靜態(tài)跟蹤點(diǎn);perf_events支持定時(shí)采樣和PMC。

eBPF環(huán)境搭建為了驗(yàn)證eBPF程序編寫(xiě),我在Ubuntu22.04中搭建了eBPF環(huán)境,ubuntu22.04的安裝流程在此不贅述。以下操作均在root用戶下執(zhí)行。

更新系統(tǒng)的包索引和包列表:

# apt update

編譯BPF程序需要系統(tǒng)安裝必備的linux-headers包:

# sudo apt install Linux-headers-$(uname -r)

安裝eBPF依賴工具

# apt install -y bison flex build-essential git cmake make libelf-dev strace tar libfl-dev libssl-dev libedit-dev zlib1g-dev  Python  python3-distutils

安裝LLVM,并檢查版本:

# apt install llvm # llc -version Ubuntu LLVM version 14.0.0  .....     wasm32     - WebAssembly 32-bit     wasm64     - WebAssembly 64-bit     x86        - 32-bit X86: Pentium-Pro and above     x86-64     - 64-bit X86: EM64T and AMD64     xcore      - XCore # 

安裝Clang,并檢查版本:

# apt install clang # clang -version Ubuntu clang version 14.0.0-1ubuntu1 Target: x86_64-pc-linux-gnu Thread model: posix InstalledDir: /usr/bin # 

查看當(dāng)前ubuntu的內(nèi)核版本,安裝對(duì)應(yīng)的內(nèi)核源碼,并解壓源碼:

# apt-cache search linux-source linux-source - Linux kernel source with Ubuntu patches linux-source-5.19.0 - Linux kernel source for version 5.19.0 with Ubuntu patches # apt install linux-source-5.19.0 # cd /usr/src # tar -jxvf linux-source-5.19.0.tar.bz2 # cd linux-source-5.19.0

編譯內(nèi)核源碼的bpf模塊,如果沒(méi)有報(bào)錯(cuò),說(shuō)明已經(jīng)完成環(huán)境搭建:

# cp -v /boot/config-$(uname -r) .config # make oldconfig && make prepare # make headers_install # apt-get install libcap-dev  # make M=samples/bpf     CC  samples/bpf/../../tools/testing/selftests/bpf/cgroup_helpers.o   CC  samples/bpf/../../tools/testing/selftests/bpf/trace_helpers.o   CC  samples/bpf/cookie_uid_helper_example.o   CC  samples/bpf/cpustat_user.o   CC  samples/bpf/fds_example.o ... WARNING: Symbol version dump "Module.symvers" is missing.          Modules may not have dependencies or modversions.          You may get many unresolved symbol warnings.

eBPF樣例編寫(xiě)內(nèi)核源碼的samples/bpf目錄下提供了許多實(shí)例供學(xué)習(xí),通過(guò)目錄下的makefile可以構(gòu)建其中的bpf程序。如果我們用c語(yǔ)言編寫(xiě)B(tài)PF程序,可以直接在該目錄提供的環(huán)境中進(jìn)行編譯。

samples/bpf下的程序通常由xxx_user.c和xxx_kern.c組成:

xxx_user.c:為用戶空間程序,用于設(shè)置BPF程序的相關(guān)配置、加載BPF程序至內(nèi)核、設(shè)置BPF程序中的map值和讀取BPF程序運(yùn)行過(guò)程中發(fā)送至用戶空間的消息等。目前xxx_user.c與xxx_kern.c程序在交互實(shí)現(xiàn)上都是基于bpf()系統(tǒng)調(diào)用完成的。直接使用bpf()系統(tǒng)調(diào)用涉及的參數(shù)和細(xì)節(jié)較多,使用門(mén)檻較高,因此為了方便用戶空間程序更加易用,內(nèi)核提供了libbpf庫(kù)封裝了對(duì)于bpf()系統(tǒng)調(diào)用的細(xì)節(jié)。 xxx_kern.c:為BPF程序代碼,通過(guò)clang編譯成字節(jié)碼加載至內(nèi)核中,在對(duì)應(yīng)事件觸發(fā)時(shí)運(yùn)行,可以接受用戶空間程序發(fā)送的各種數(shù)據(jù),并將運(yùn)行時(shí)產(chǎn)生的數(shù)據(jù)發(fā)送至用戶空間程序。

編寫(xiě)一個(gè)樣例流程,在目錄samples/bpf中新建兩個(gè)文件:youyeetoo_user.c和youyeetoo_kern.c,并在makefile中加入構(gòu)建:

youyeetoo_user.c的內(nèi)容:

#include <stdio.h> #include <unistd.h> #include <bpf> #include "trace_helpers.h" <p>int main(int ac, char *<em>argv) { struct bpf_link </em>link = NULL; struct bpf_program <em>prog; struct bpf_object </em>obj; char filename[256];</p><pre class="brush:php;toolbar:false">snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);  obj = bpf_object__open_file(filename, NULL); if (libbpf_get_error(obj)) {     fprintf(stderr, "ERROR: opening BPF object file failedn");     return 0; }  prog = bpf_object__find_program_by_name(obj, "bpf_prog"); if (!prog) {     fprintf(stderr, "ERROR: finding a prog in obj file failedn");     goto cleanup; }  /* load BPF program */ if (bpf_object__load(obj)) {     fprintf(stderr, "ERROR: loading BPF object file failedn");     goto cleanup; }  link = bpf_program__attach(prog); if (libbpf_get_error(link)) {     fprintf(stderr, "ERROR: bpf_program__attach failedn");     link = NULL;     goto cleanup; }  read_trace_pipe();

cleanup: bpf_link__destroy(link); bpf_object__close(obj); return 0; }

youyeetoo_kern.c的內(nèi)容:

#include <uapi></p><h1>include <linux></h1><h1>include <bpf></h1><h1>include <bpf></h1><p>SEC("tracepoint/syscalls/sys_enter_execve") int bpf_prog1(struct pt_regs *ctx) { char fmt[] = "youyeetoo %s !n"; char comm[16]; bpf_get_current_comm(&comm, sizeof(comm)); bpf_trace_printk(fmt, sizeof(fmt), comm); return 0; }</p><p>char _license[] SEC("license") = "GPL"; u32 _version SEC("version") = LINUX_VERSION_CODE; </bpf></bpf></linux></uapi>

Makefile文件修改:

# diff -u Makefile.old Makefile --- Makefile.old    2021-09-26 03:16:16.883348130 +0000 +++ Makefile    2021-09-26 03:20:46.732277872 +0000 @@ -55,6 +55,7 @@ tprogs-y += xdp_sample_pkts tprogs-y += ibumad tprogs-y += hbm +tprogs-y += youyeetoo</p><h1>Libbpf dependencies</h1><p>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)</p><h1>Tell kbuild to always build the programs</h1><p>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</p><p>ifeq ($(ARCH), arm)</p><h1>Strip all except -D<strong>LINUX_ARM_ARCH</strong> option needed to handle linux

eBPF樣例驗(yàn)證編譯樣例:

# make M=samples/bpf</h1><p>CC  samples/bpf/../../tools/testing/selftests/bpf/cgroup_helpers.o CC  samples/bpf/../../tools/testing/selftests/bpf/trace_helpers.o CC  samples/bpf/cookie_uid_helper_example.o CC  samples/bpf/cpustat_user.o CC  samples/bpf/fds_example.o ... LD  samples/bpf/youyeetoo CLANG-bpf  samples/bpf/youyeetoo_kern.o WARNING: Symbol version dump "Module.symvers" is missing. Modules may not have dependencies or modversions. You may get many unresolved symbol warnings.

在samples/bpf下查看編譯結(jié)果,可以看到y(tǒng)ouyeetoo可執(zhí)行文件:

# ls -al youyeetoo* -rwxr-xr-x 1 root root 407976  6月  9 19:08 youyeetoo -rw-r--r-- 1 root root    451  6月  9 10:44 youyeetoo_kern.c -rw-r--r-- 1 root root   5216  6月  9 19:08 youyeetoo_kern.o -rw-r--r-- 1 root root    997  6月  9 10:40 youyeetoo_user.c -rw-r--r-- 1 root root   3360  6月  9 19:08 youyeetoo_user.o

在ubuntu中運(yùn)行兩個(gè)終端,用來(lái)測(cè)試youyeetoo:

基于ubuntu22.04-深入淺出 eBPF在終端1中運(yùn)行youyeetoo可執(zhí)行文件,在終端2中執(zhí)行任意命令,在終端1查看程序是否能夠監(jiān)測(cè)到,如果成功監(jiān)測(cè)到新進(jìn)程運(yùn)行便會(huì)輸出一條“bpf_trace_printk: Hello”

基于ubuntu22.04-深入淺出 eBPF

相關(guān)閱讀

主站蜘蛛池模板: 久久久久久久久综合 | 三级黄视频在线观看 | 美女亚洲一区 | 久草成人网 | 国产japanhdxxxx麻豆| 成人欧美一区二区三区白人 | 最新中文字幕在线 | 久久午夜精品 | 欧美视频三级 | 亚洲一区二区三区观看 | 免费h在线 | 波多野结衣一区二区 | 天天插天天操 | 亚洲精品福利视频 | 人碰人操| 亚洲成人免费观看 | 国产精品高清一区二区 | 在线视频成人 | 久久另类视频 | 91不卡在线 | 国产成人精品久久二区二区91 | 国产精品69av | 国产成人99久久亚洲综合精品 | 中文字幕在线看第二 | 国产目拍亚洲精品99久久精品 | 一区在线视频 | 久久久久久综合 | 成人免费看片又大又黄 | 亚洲精品久久久久中文字幕欢迎你 | 一区二区中文 | 请别相信他免费喜剧电影在线观看 | 毛片大全| 亚洲狠狠| 久久999| 国产在线精品区 | 在线观看中文字幕视频 | 亚洲精品一区二区在线 | 久久国产精品视频 | 国产区一区 | 日韩不卡一区二区三区 | 久久一区二区三区四区 |