前言
eBPF之于Linux的作用与JavaScript对HTML的作用相同。 因此,JavaScript改变了静态HTML网站,使我们可以定义一些网页上的触发事件,例如用户的点击、鼠标滑动,这些js程序在浏览器的安全引擎中运行。 使用eBPF,而不是固定的内核,现在可以编写在例如磁盘I/O等事件上运行的触发程序,这些程序在内核中的安全引擎中运行。 实际上,eBPF更像是运行JavaScript的v8引擎,而不是JavaScript程序本身。 eBPF是Linux内核的一部分。
直接在eBPF中进行编程非常困难,与在v8字节码中进行编码相同。它们使用JavaScript编写代码,或者通常是JavaScript之上的框架(jQuery,Angular,React等)。 eBPF也是如此,人们将使用它并通过框架对其进行封装,主要的是框架是bcc和bpftrace。 它们不存在于内核代码库中,而是存在于github上名为iovisor的Linux Foundation项目中。
本文不是介绍如何搭建bcc或者bpftrace的开发环境,而是介绍不借助框架的情况下,ebpf的开发环境如何进行搭建。使用的操作系统是Ubuntu 18,Linux内核版本为5.4.0.48。
下载Linux内核源代码
在下载代码之前,建议先更新Ubuntu中的软件下载源,更新为国内源,下载速度会更加感人。
编辑下载源文件
sudo vim /etc/apt/sources.list
将阿里源放到文件中保存。
1 | deb http://mirrors.aliyun.com/ubuntu/ focal main restricted universe multiverse |
保存好以后,使用下面的命令,进行软件源更新。
1 | sudo apt-get update |
接下来就查看缓存仓库中可以下载的源码
sudo apt search linux-source
使用命令
sudo apt install linux-source
下载源列表中最新的源码压缩包。也可以指定版本进行下载。
sudo apt install linux-source[-version]
建议下载和自身内核版本一致的源代码。
进入/usr/src 查看刚才下载的源码包。
将该压缩包解压。
sudo tar -xjvf linux-source-5.4.0.tar.bz2
编译ebpf样例程序
安装依赖
1 | sudo apt install libncurses5-dev flex bison libelf-dev binutils-dev libssl-dev |
sudo make menuconfig 配置内核选项生成.config文件
可视化配置界面,直接选择save。
生成.config文件,选择ok后,然后选择exit。
编译sampls/bpf目录下的样例文件。
sudo make M=samples/bpf
成功后就会生成.o文件。
根据样例程序自定义ebpf程序
ebpf程序包含两个文件,一个运行在内核态,通常用*_kern.c命名,一个运行在用户态,通常用 *_user.c命名。
为运行在内核空间的示例源代码(kern.c),编译生成.o后缀的目标文件,以便加载到对应BPF提供的钩子中去
为运行在用户空间的示例源代码(user.c),编译生成可以在本机直接运行的可执行文件,以便用户可以直接运行测试
编写ebpf程序放到samples/bpf目录下。
内核态程序:
1 | //mybpf_01_kern.c |
用户态程序:
1 | //mybpf_01_user.c |
修改bpf目录下的Makefile文件。
1 | # SPDX-License-Identifier: GPL-2.0 |
Makefile文件只需修改三处,在上面文件中用“自定义”标识。需要注意的是 hostprogs-y += mybpf_01_kern,等号后面的文件名称,除去.c后缀后,务必写完整。否则会有一个gcc错误“no input file”。