RustAya 编写 eBPF 程序( 二 )


$ source "$HOME/.cargo/env"$ rustup install stable# rustup 命令已经默认安装info: syncing channel updates for 'stable-x86_64-unknown-linux-gnu'stable-x86_64-unknown-linux-gnu unchanged - rustc 1.65.0 (897e37553 2022-11-02)info: checking for self-updates$ rustup toolchain install nightly --component rust-src...info: installing component 'rustfmt'nightly-x86_64-unknown-linux-gnu installed - rustc 1.67.0-nightly (09508489e 2022-11-04)info: checking for self-updates$ rustup toolchain liststable-x86_64-unknown-linux-gnu (default)nightly-x86_64-unknown-linux-gnu安装 nightly 以后我们可以使用 rustup toolchain list 查看本地开发环境的开发工具链 。
2.3 安装 bpf-linker 依赖 和 bpftool 工具为了使用 Aya,我们还需要安装依赖包bpf-linker,但其依赖与LLVM/Clang 等工具,因此我们也需要提前安装:
$ sudo apt-get update$ sudo apt-get install llvm clang -y$ cargo install bpf-linker最后,为了生成内核数据结构的绑定,我们还必须安装 bpftool,可以从发行版中安装或从源代码中构建,这里我选用发行版安装方式(基于 Ubuntu 22.04),源码安装可参考 bpftool 仓库说明文档:
$ sudo apt install linux-tools-common linux-tools-5.15.0-52-generic linux-cloud-tools-5.15.0-52-generic -y支持我们完成了基于 Aya 开发的整个环境及依赖的安装 。
3. Aya 向导创建 eBPF 程序3.1 使用向导创建项目Aya 提供了一套模版向导用于创建 eBPF 对应的程序类型,向导创建依赖于 cargo-generate,因此我们需要在运行程序向导前提前安装:
$ cargo install cargo-generate

我在安装 cargo-generate 过程中遇到了如下的错误,主要是由于依赖 openssl 库问题导致,如果你也遇到类似问题可参考 cargo-generate 安装指南 和 Rust OpenSSL 文档,如果一切顺利,则可忽略此处的提示 。
...warning: build failed, waiting for other jobs to finish...error: failed to compile `cargo-generate v0.16.0`, intermediate artifacts can be found at `/tmp/cargo-install8NrREg...$ sudo apt install openssl pkg-config libssl-dev gcc m4 ca-certificates make perl -y# 重新安装即可
在完成依赖后,我们就可以使用向导来创建 eBPF 项目,这里以 XDP 类型程序为例:
$ cargo generate https://github.com/aya-rs/aya-template
RustAya 编写 eBPF 程序

文章插图
这里我们输入项目名称 myapp,eBPF 程序类型选择 xdp,完成相关设定后,向导会自动帮我们创建一个名为 myapp 的 Rust 项目,项目包括了一个最简单的 XDP 类型的 eBPF 程序及相对应的用户空间程序 。myapp 目录的整体夹头如下所示:
├── Cargo.lock├── Cargo.toml├── README.md├── myapp# 用户空间程序│   ├── Cargo.toml│   └── src│  └── main.rs├── myapp-common# eBPF 程序与用户空间程序复用的代码库│   ├── Cargo.toml│   └── src│  └── lib.rs├── myapp-ebpf# eBPF 程序│   ├── Cargo.lock│   ├── Cargo.toml│   ├── rust-toolchain.toml│   └── src│  └── main.rs└── xtask# build 相关的代码├── Cargo.toml└── src├── build_ebpf.rs├── main.rs└── run.rs8 directories, 15 files生成的 eBPF 程序位于 myapp-ebpf/src 目录下,文件名为 main.rs,完整内容如下所示:
$ cat myapp-ebpf/src/main.rs#![no_std]#![no_main]use aya_bpf::{bindings::xdp_action,macros::xdp,programs::XdpContext,};use aya_log_ebpf::info;#[xdp(name="myapp")]pub fn myapp(ctx: XdpContext) -> u32 {match try_myapp(ctx) {Ok(ret) => ret,Err(_) => xdp_action::XDP_ABORTED,}}fn try_myapp(ctx: XdpContext) -> Result<u32, u32> {info!(&ctx, "received a packet"); // 每接受到一个数据包则打印一个日志Ok(xdp_action::XDP_PASS)}#[panic_handler]fn panic(_info: &core::panic::PanicInfo) -> ! {unsafe { core::hint::unreachable_unchecked() }}

经验总结扩展阅读