🐝

Azure VMでRust製eBPF(XDP)プログラムを動かす

に公開

Azure VM で Rust(Aya)のeBPF(XDP)プログラムを動かすまでの環境構築手順を記載します。
Azure VM 上で eBPF(XDP)を実行している記事はなかったので、手順を残しておきます。
環境構築時・プログラム実行時にエラーも出ていたので、誰かの参考になれば幸いです。

環境

使用した OS, VMのサイズは以下の通りです。

  • OS : Ubuntu 24.04
  • サイズ : Standard B2s (2 vcpu 数、4 GiB メモリ)

環境構築

以降の手順はすべて Azure VM に ssh ログインして実行しています。

必要なパッケージをインストール

以下のパッケージをインストールしておかないと、先の手順でエラーになりました。

$ sudo apt update && sudo apt install -y build-essential pkg-config libssl-dev openssl

Rustのインストール

以下を参照してインストールします。

https://www.rust-lang.org/ja/tools/install

実行したコマンドは以下です。

$ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

以下の選択肢は default で進めます。(Enterを押すだけ)

1) Proceed with standard installation (default - just press enter)
2) Customize installation
3) Cancel installation
>

インストール完了後は以下を実行しました。

$ . "$HOME/.cargo/env"

Ayaに必要なツールをインストール

Aya 公式を参照して、必要なツールをインストールします。

https://aya-rs.dev/book/start/development/

実行したのは以下のコマンドです。

$ rustup install stable
$ rustup toolchain install nightly --component rust-src
$ cargo install bpf-linker && cargo install cargo-generate

プロジェクト作成

以下を実行して、プロジェクトを作成します。

$ cargo generate https://github.com/aya-rs/aya-template

以下の3点を聞かれるので、入力します。

  • プロジェクト名 : test
  • eBPFプログラムの種類 : xdp
  • インタフェース : eth0

実行してみる

プロジェクトが作成出来たら、ビルドして実行してみます。

$ cd test
$ cargo build
$ sudo ./target/debug/test

以下のエラーが出ました。

azureuser@test1:~/test$ sudo ./target/debug/test
Error: failed to attach the XDP program with default flags - try changing XdpFlags::default() to XdpFlags::SKB_MODE

Caused by:
    0: `bpf_link_create` failed
    1: Operation not supported (os error 95)

XdpFlags::default() から XdpFlags::SKB_MODE に変更してみるよう書いています。
SKB_MODE は遅いらしい(参考)ので、default() で実行できないか試行錯誤します。

ログに LRO をサポートしていないと出力されていました。

azureuser@test1:~/test$ journalctl -k | tail -n 5
Sep 17 14:17:44 test1 kernel: audit: type=1400 audit(1758118664.023:125): apparmor="STATUS" operation="profile_replace" profile="unconfined" name="/usr/lib/snapd/snap-confine" pid=1191 comm="apparmor_parser"
Sep 17 14:17:44 test1 kernel: audit: type=1400 audit(1758118664.029:126): apparmor="STATUS" operation="profile_replace" profile="unconfined" name="/usr/lib/snapd/snap-confine//mount-namespace-capture-helper" pid=1191 comm="apparmor_parser"
Sep 17 14:17:47 test1 kernel: workqueue: drm_fb_helper_damage_work hogged CPU for >10000us 11 times, consider switching to WQ_UNBOUND
Sep 17 14:18:10 test1 kernel: hv_balloon: Max. dynamic memory size: 4096 MB
Sep 17 14:41:22 test1 kernel: hv_netvsc 7ced8d31-cdbd-7ced-8d31-cdbd7ced8d31 eth0: XDP: not support LRO

LROをオフにしてみます。

$ sudo ethtool -K eth0 lro off

再実行すると実行できました。

azureuser@test1:~/test$ sudo ./target/debug/test
Waiting for Ctrl-C...

環境変数 RUST_LOG=info がないと、パケットを受け取った時の出力が表示されません。
以下のようにすると、パケットを受け取るたびに received a packet が出力されるようになりました。

azureuser@test1:~/test$ export RUST_LOG=info
azureuser@test1:~/test$ sudo -E ./target/debug/test
Waiting for Ctrl-C...
[INFO  test] received a packet
[INFO  test] received a packet
[INFO  test] received a packet
[INFO  test] received a packet

Discussion