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 程式。