BPF 許可

背景

  • 經典 BPF 採用 BSD 許可

“BPF”最初在 http://www.tcpdump.org/papers/bpf-usenix93.pdf 中作為 BSD Packet Filter 引入。相應的指令集及其實現源自 BSD 並採用 BSD 許可。該原始指令集現在被稱為“經典 BPF”。

然而,指令集是機器語言互動的規範,類似於程式語言。它不是程式碼。因此,在特定上下文中,應用 BSD 許可可能會產生誤導,因為指令集可能不受版權保護。

  • eBPF(擴充套件 BPF)指令集仍採用 BSD 許可

2014 年,經典 BPF 指令集得到了顯著擴充套件。我們通常將此指令集稱為 eBPF,以與 cBPF 區分開來。eBPF 指令集仍採用 BSD 許可。

eBPF 的實現

使用 eBPF 指令集需要在核心空間和使用者空間中都實現程式碼。

在 Linux 核心中

eBPF 直譯器和各種即時編譯器的參考實現是 Linux 的一部分,並採用 GPLv2 許可。eBPF 輔助函式的實現也採用 GPLv2 許可。直譯器、JIT、輔助函式和驗證器統稱為 eBPF 執行時。

在使用者空間中

還有采用 Apache2 (https://github.com/iovisor/ubpf)、MIT (https://github.com/qmonnet/rbpf) 和 BSD (https://github.com/DPDK/dpdk/blob/main/lib/librte_bpf) 許可的 eBPF 執行時(直譯器、JIT、輔助函式)實現。

在硬體中

硬體可以選擇原生執行 eBPF 指令,並透過使用專有許可的韌體來提供硬體中的 eBPF 執行時。

在其他作業系統中

eBPF 指令集和執行時的其他核心或使用者空間實現可以採用專有許可。

在 Linux 核心中使用 BPF 程式

Linux 核心(儘管採用 GPLv2 許可)允許根據以下規則連結專有核心模組:Linux 核心許可規則

當載入核心模組時,Linux 核心會檢查它打算使用的函式。如果任何函式被標記為“僅限 GPL”,則相應的模組或程式必須具有與 GPL 相容的許可。

將 BPF 程式載入到 Linux 核心中類似於載入核心模組。BPF 是在執行時載入的,而不是靜態連結到 Linux 核心。BPF 程式載入遵循與核心模組相同的許可檢查規則。如果 BPF 程式不使用“僅限 GPL”的 BPF 輔助函式,則它們可以是專有的。

此外,截至 2021 年 8 月,某些 BPF 程式型別——Linux 安全模組 (LSM) 和 TCP 擁塞控制 (struct_ops)——即使不直接使用“僅限 GPL”的輔助函式,也要求與 GPL 相容。Linux 核心的 LSM 和 TCP 擁塞控制模組的註冊步驟是透過 EXPORT_SYMBOL_GPL 核心函式完成的。從這個意義上說,LSM 和 struct_ops BPF 程式是隱式呼叫“僅限 GPL”函式的。同樣的限制也適用於透過不穩定介面(也稱為“kfunc”)直接呼叫核心函式的 BPF 程式。

將 BPF 程式與使用者空間應用程式打包

通常,同一包中採用專有許可的應用程式和為 Linux 核心編寫的 GPL 許可的 BPF 程式可以共存,因為它們是獨立的可執行程序。這適用於 cBPF 和 eBPF 程式。