BPF virutal machine in userspace

最近在2017 系統軟體系列課程討論區 中看到轉載的專案 rbpf。大概瞭解了一下是一個跑 在 userspace,由 Rust 語言撰寫的 eBPF virtual machine。原開發者設計的本意是

Why implementing an eBPF virtual machine in Rust?

As of this writing, there is no particular use case for this crate at the best
of the author's knowledge. The author happens to work with BPF on Linux and to
know how uBPF works, and he wanted to learn and experiment with Rust—no more
than that.

原本的專案是由 uBPF 得來的靈感,看到這邊一直有個疑問:我們在 userspace 的程式中 使用 BPF virtual machine 可以帶來什麼好處?(或是說我們會在何時使用 uBPF)?

eBPF

eBPF 是 kernel 中內建的 virtual machine,原本是給像 tcpdump 這類的指令過濾封包 使用。由於這類指令執行於 userspace,如果將所有封包傳到 userspace 才過濾的話效率 太差,但又需要由 userspace 撰寫稍微複雜的規則。透過 eBPF 我們可以在 userspace 透 過 restrict C 寫控制條件,經由 LLVM 編譯成 eBPF bytecode 在 kernel 這個大平台運行 。

在以上特性下,eBPF 被延伸到許多 kernel 子系統中,例如 tracing、seccomp、與 netfilter 等。做 data filter 也比以往透過 predicate-tree walking 的方式快、彈性 佳(只能寫一些簡單的規則 vs 可以寫 C 程式)。但是寫 eBPF 程式有一些限制:

  1. 只能操作特定數據,除了 map 外只能存取由類似 argument 的方式傳進去的數據,比如 說像 sk_buff 的資料內容。
  2. 無法和所有子系統互動,而是透過由子系統所提供的 helper function 互動。
  3. 只接受有限制的 C 程式 (restruct C, 不能用 loop, 不能有 global variable 等, kernel 中會有 verifer 檢查程式是否符合規則,但 uBPF 的話也許不會有這些限制 也說不定)

由這個思路來看,我們在 userspace 整合 eBPF virtual machine ,可以得到什麼效 益呢?我個人覺得:

  1. 我們可以實現簡單的 C 程式擴展而不需要重新編譯與載入原本的程式。
  2. BPF 程式無法存取所有的資料或呼叫任意函數,只能使用原先系統允許的資料範圍(map 或是預定義的資料結構, 如 sk_buff)與功能(helper),相對安全。
  3. 透過 JIT 取得彈性與效能的平衡。

有哪些專案使用 userspace BPF virtual machine?

目前找到兩個使用 uBPF 的專案

  1. perf tools: Support uBPF script: 目前積極整合 perf tool 與 eBPF 的貢獻者 Wang Nang 發佈的 patch。原意是透過 uBPF 擴展 perf 的功能,做更好的資料呈現。
  2. A slightly different use of the BCC tools: 開發者主要在設計 sensor network 的機制時,不同的 application 使用不同的 network protocol 時,透過 uBPF 做 protocol forwarding,可以共用底層的通訊協議而 不需要另外安裝 network protocol,兼具快速且安全的特性。

Viller Hsiao

All about C/C++/Python, Embedded Linux/RTOS, and Web programming