eBPF 應用程序開發:快人一步
這篇文章提供了關於 eBPF 應用程序開發的指南。正如標題所示,文章主要關注 eBPF 201 的概念,而不是提供另一篇關於 eBPF 技術是什麼的入門級文章。我們提供了簡短的介紹,但主要關注需要部署生產 eBPF 應用程序的開發團隊的下一組概念和最佳實踐。我們將探討使 BPF 應用程序可以在多個內核版本和環境中部署和維護的編程語言和工具鏈。
eBPF 101: 簡短回顧
BPF/eBPF 是由輕量級的隔離虛擬機和一組輔助函數組成的操作系統內核技術。在本文中,我們關注 Linux[1] 內核中的 eBPF,儘管它也適用於其他操作系統平臺,如 Windows 和 FreeBSD。
這項技術使用戶能夠在內核中運行提供的程序,以擴展內核的功能。驗證程序在加載到內核之前會檢查 BPF 程序,以確保它們不會危及內核的可靠性。這些程序會被 JIT(Just-In-Time)編譯成本機指令,因此它們足夠高效,可以在性能要求最高的情況下執行,例如網絡數據包處理。
總體的好處是以一種安全、更靈活且開發速度更快的方式爲操作系統內核提供可編程性和可擴展性,而不是開發內核模塊或直接增強主要內核功能本身。
下圖中的圖表顯示了 Linux 內核中的 BPF 虛擬機、BPF 程序可以附加的掛鉤點以及 BPF 程序可用的各種映射和輔助函數。
如果你對 eBPF 還不熟悉,eBPF 詳盡介紹 [2] 將爲你提供一個很好的基礎,然後再閱讀本文的其餘部分。
技術成熟度
BPF 已經從早期作爲 Linux 內核的數據包過濾引擎(圖 2)的時代走來了很長的路。在過去的十年中,eBPF VM 已經成爲一種通用執行引擎,由 Clang[3] 工具鏈支持,具有許多不同用途的程序類型和輔助函數。最近,重點放在了開發者和操作用戶體驗上,由 BTF、CO-RE 和 libbpf 支持。
BPF 功能已經在從 3.15 到最新的 6.x 版本的許多內核中引入。在任何給定的內核版本中找出可用的功能集可能是困難的。BCC 項目維護了一個有用的 BPF 功能按 Linux 內核版本排序的列表 [4],它可以幫助你確定在給定的 Linux 內核中的功能可用性。
eBPF 應用程序開發常見問題解答
以下是開發人員在學習 eBPF 應用程序開發時常遇到的一些常見問題。在本文中,我們試圖提供這些問題的一些答案,同時注意到這個領域仍在不斷髮展,一些內容將在未來發生變化。
Q:用於 eBPF 應用程序的編程語言和開發工具有哪些選擇,以及每種選擇的利弊是什麼?
A:這將在本文的選擇您的 eBPF 應用程序棧 [5] 部分中進行討論。
Q:我們瞭解 eBPF 的概念,但迄今爲止還沒有進行任何內核開發。爲了有效地開發 eBPF 應用程序,我們需要了解內核源代碼的相關部分和開發環境嗎?
A:開發內核經驗不是開發基於 eBPF 的應用程序所必需的。然而,強烈建議對內核中相關的功能領域有很好的瞭解。例如,當開發網絡應用程序時,您應該瞭解與網絡套接字、內核數據包路徑、netfilter 功能等相關的一些內核內部內容。
Q:在跨目標方式開發 eBPF 應用程序時,其中開發涉及多個開發系統和內核版本,同時存在多個目標系統和平臺,旨在實現跨所有這些平臺的可移植性和可維護性,我們需要了解哪些內容?
A:這將在本文的 eBPF 應用程序跨開發、可移植性、CO-RE 和內核 API 穩定性 [6] 部分中進行討論。
Q:有哪些實際的分發 eBPF 程序和在單個系統中併發安裝來自多個供應商的程序的操作模型?
A:在撰寫本文時,這是一個新興的開發領域。目前,eBPF 程序通常被打包爲較大項目中的不可分割的子組件,例如 Cilium[7] 或 Pixie[8]。結合和安裝多個獨立的基於 eBPF 的應用程序可能會導致不一致或錯誤的行爲,特別是如果在使用的 eBPF 附加點中存在重疊(如在最近的案例 [9] 中所示)。
新項目,如 libxdp[10] 和 bpfd[11],正在添加功能以解決此類操作問題。我們期望在未來的文章中更詳細地介紹這些項目。
Q:上游核心 eBPF 開發模型是什麼,我們如何跟蹤仍在開發中的 eBPF 功能?
A:新的 eBPF 內核基礎設施和功能是在 Linux 內核的 “bpf-next” git 存儲庫中開發的,最終合併到主要的 Linux 存儲庫中,作爲正式的 Linux 內核發佈的一部分。該過程在 BPF 開發 FAQ[12] 中有更詳細的描述。
此外,內核 BPF 函數越來越多地作爲 kfuncs[13](內核函數)添加。它們提供了 eBPF 應用程序可以調用的 API,但相對於內核 BPF 輔助函數的穩定性較低,後者被認爲是內核 ABI 的一部分。正在使用的 kfunc API 將得到支持和維護,但不屬於內核 ABI。
Q:在編寫 eBPF 應用程序時,需要注意哪些軟件許可要求?
A:Linux 內核 eBPF 運行時的組件使用 GPLv2 許可證。這包括參考解釋器、驗證器、JIT 編譯器和 BPF 助手等組件。所有 kfuncs 和許多(但不是全部)BPF 助手都是 GPL 許可的,這意味着 BPF 應用程序通常(儘管不總是)需要以 GPL-v2 兼容許可證發佈。請注意,沒有兼容許可歸屬的 BPF 驗證器將不允許加載 BPF 應用程序。爲了啓用一些寬鬆的下游代碼重用,應用程序可以考慮使用雙重許可,此外將其 BPF 應用程序許可爲諸如 MIT、BSD-2-Clause 等寬鬆許可證。有關更多詳細信息,請參閱 Linux 內核文檔的 BPF 許可指南 [14]。
Q:eBPF 技術是否促進或與內核數據平面卸載技術交匯?
A:對於 Linux 內核功能,特別是網絡功能的硬件卸載到智能網卡是一個廣泛的話題,涵蓋了許多超出本博客範圍的技術。暫時簡要說明一下,您確實可以利用 eBPF 技術來進行硬件卸載。例如,像 ConnectX-6[15] 這樣的某些智能網卡支持將基於 XDP 的 eBPF 程序從主機 CPU 卸載到網卡上的 CPU。
選擇您的 eBPF 應用程序棧
在啓動新的 eBPF 項目時,開發團隊需要決定使用哪種軟件棧來開發計劃中的應用程序。有多種編程語言和可用的庫,具有不同的成熟度和與最新內核 BPF 功能的特性相匹配。
以下是 eBPF 應用程序的常見選擇,也是新項目的不錯選擇:
-
用戶空間程序使用 C[16],內核空間 BPF 程序使用 C
-
用戶空間程序使用 Golang[17],內核空間 BPF 程序使用 C
-
用戶空間程序使用 Rust[18],內核空間 BPF 程序使用 Rust
這些應用程序開發棧如圖 3 所示。
還有一種低代碼選項,團隊可以利用可用工具,如 iproute2 的 tc、bpftool 和 bpftrace 來處理計劃中應用程序的用戶空間和 / 或內核 BPF 程序。
需要注意的一個關鍵點是,以這種方式列出這些選項並不排除在這些選項以及其他選項之間混合和匹配的可能性。例如,您可以使用 C 編寫內核空間 eBPF 程序,然後在用戶空間使用 Golang 或 Rust 編寫相應的程序,通常有很多理由這樣做。還有更多的選項,包括通過直接調用內核 ebpf 系統調用 [19] 或使用像 BCC[20] 這樣的框架編寫自己的自定義 eBPF 加載程序。但通常情況下,本文列出的選項將更適合新項目,我們將討論這些選項以闡明一些核心概念。
使用 C 和帶 libbpf(可選的 libbpf-bootstrap)的 C
這種軟件棧選擇通常是最全面的,支持最新的 eBPF 功能和工具。
關於 libbpf
libbpf[21] 是一個 C 庫,提供 eBPF 實用函數和定義,用戶空間程序可以使用它來管理內核空間的 eBPF 程序。這個應用程序棧選項是最新的,是上游 Linux 源代碼倉庫的一部分,與最新的 eBPF 功能保持一致,並用於測試新的內核 eBPF 功能。這個庫和內核 BPF 代碼由內核開發人員共同編寫、審查和測試,作爲引入新的 eBPF 功能的一部分。libbpf 還是 CO-RE(Compile Once Run Everywhere)[22] 功能的官方實現,該功能在提供 eBPF 程序可移植性方面顯著改進了開發人員的體驗,後文將詳細討論。
在 Linux 源代碼倉庫中,libbpf 位於 tools/lib/bpf[23]。API 文檔可在 https://libbpf.readthedocs.io/en/latest/api.html 到。
與內核源代碼分開維護的 libbpf 的鏡像 [24] 應該用於包含在應用程序中。該 API 包括一些關鍵的定義,如 eBPF 幫助函數的原型定義,用戶空間類型定義以匹配相應的內核類型,並用於加載和附加程序以設置 eBPF 映射的函數。libbpf 庫於 2022 年中發佈了 1.0 版本 [25],並且正在積極開發,最近發佈了 1.2 版本 [26]。
關於 libbpf-bootstrap
libbpf-bootstrap[27] 是 libbpf 的伴隨倉庫之一,提供了使用 libbpf 功能的一組有用的模板和示例程序 [28]。這是一個快速編寫用戶空間程序的良好起點,該程序將與最新的 eBPF 功能一起使用。libbpf-bootstrap 倉庫還說明了使用 bpftool 實用程序準備 eBPF 骨架程序的方法。骨架是一組由用戶空間程序使用的類型和函數的定義,以便輕鬆打開、加載、附加和銷燬 eBPF 程序對象。
建議和要點
1. 這經常是編寫 eBPF 應用程序時的一個不錯的棧選擇。
在我們看來,這種應用程序棧是開發團隊採用的一個可靠選擇,特別是如果需要使用 C 語言用戶空間程序或者需要最新的 eBPF 功能,這些功能可能並不總是通過其他用戶空間加載器和其他編程語言和工具的實用程序獲得。
舉例來說,在撰寫本文時,這是作者用來管理、加載和附加使用新 eBPF kfuncs(內核函數)的 eBPF 應用程序的幾個可行選項之一。
2. 在應用程序倉庫中將 libbpf 和 bpftool 作爲 git 子模塊包含。
我們還注意到,開發人員通常應通過將 libbpf 包含爲其應用程序程序倉庫中的 Git 子模塊來使用 libbpf。這可以確保他們始終使用 libbpf 的最新發布版本,而不是他們可能在開發系統上擁有的內核源代碼版本,或者由 Linux 發行版捆綁的版本。
3. 考慮使用 libbpf-bootstrap 作爲應用程序程序的參考倉庫。
在作者看來,libbpf-bootstrap 是用於新的 eBPF 項目或基於 libbpf 的應用程序的參考倉庫。它作爲使用 libbpf 的最佳實踐示例進行維護(例如,使用 libbpf 和 bpftool 作爲 Git 子模塊)。
Go 和 C 與 Cilium ebpf、libbpfgo
當在 Golang 中編寫 eBPF 應用程序的用戶空間部分時,這是一個不錯的選擇。例如,當 eBPF 應用程序的用戶空間部分是 Kubernetes Operator 或 CRD 控制器時,通常會使用 Golang 編寫。
Cilium ebpf 庫 [29] 是一個獨立的純 Golang eBPF 實用工具庫,獨立於 Cilium 項目的其他應用程序,比如 Cilium Kubernetes CNI 插件。libbpfgo[30] 是另一個此類 eBPF 實用函數庫,用戶空間 Golang 應用程序可以使用它來加載 eBPF 對象文件(從任何語言編譯而來),附加到各種 eBPF 鉤子點等等。
libbpfgo 使用圍繞我們在前一節中討論的 C 語言 libbpf 庫的 Golang 包裝器調用,因此有可能支持更多最新的核心 eBPF 功能。Cilium eBPF 庫不是 libbpf 庫的包裝器,背後的社區略顯多樣化(相對於 libbpfgo),包括供應商 Isovalent 和 CloudFlare。
Rust and Rust with Aya
Aya[31] 是一個用於 BPF 應用程序開發的純 Rust 庫,旨在與 libbpf 具有功能相當。與上文描述的 Cilium eBPF 庫類似,Aya 不包含圍繞 C 語言 libbpf 庫的包裝函數。正如前面提到的,用於 eBPF 內核程序的編程語言和工具鏈與應用程序的用戶空間程序所使用的語言和工具無關。我們將在未來的一篇文章中詳細描述這個選項,屆時我們將介紹 Aya[32] 和 bpfd[33] 項目。
eBPF 應用程序跨平臺開發、可移植性、CO-RE 和內核 API 穩定性
最佳實踐的 eBPF 應用程序開發從一開始就考慮了跨平臺開發、可移植性和可維護性。最近的 eBPF 內核增強功能,比如 CO-RE(編譯一次,隨處運行)[34] 大大改進了這一領域的開發體驗。
圖 4 顯示了一個支持不同開發環境和不同目標系統的開發模型。開發環境使用了前面討論的 C 與 libbpf。
在圖中,一個開發人員正在使用運行內核 5.6 的開發計算機,而另一位開發人員則使用內核 5.10。這兩位開發人員可以在兩個不同的目標系統上進行測試,第一個目標系統運行帶有內核 5.2 的 Debian,而第二個目標系統運行 Red Hat 企業 Linux[35],內核已升級到 5.16 版本。
直到最近,這種開發模型無法用於 eBPF 應用程序,特別是那些與在內核版本之間更改的原始內核數據類型和結構進行交互的應用程序。因此,eBPF 應用程序必須在加載到目標系統時即時編譯(使用其他加載功能,如 BCC[36] 的內置 CLANG/ LLVM)以獲取實際目標系統內核的內核頭文件和類型信息。
然而,被稱爲 CO-RE(Compile Once Run Everywhere)的新 eBPF 基礎架構使單個 eBPF 二進制對象能夠在不同的內核版本上加載和運行,無需重新編譯或複雜的解決方法。請參考本文 [37] 及其附帶的 CO-RE 指南 [38],其中提供了有關 CO-RE 和開發人員最佳實踐的出色詳細信息。
推薦和要點
1. 在可能的情況下,使用支持 CO-RE 的 eBPF 加載器,該加載器支持基於內核數據類型的重定位能力。
本文前一節中討論的 3 種應用程序堆棧選項都支持 CO-RE。其他 eBPF 加載器選項,如 BCC 框架,目前不支持 CO-RE。
2. 遵循 CO-RE 最佳實踐。
這包括使用編譯器 / Clang 屬性,例如__attribute__((preserve_access_index))
,以確保 eBPF 程序使用的內核數據類型的可重定位性,使用諸如BPF_CORE_READ()
宏之類的助手,以有效地訪問內核數據,即使有多層指針間接引用,以及使用 CO-RE 功能來以編程方式檢測內核版本和內核配置信息,以處理更復雜的內核數據類型更改,如 CO-RE 指南 [39] 中所述。
3. 考慮使用 vmlinux.h
來簡化包含頭文件,而不是開發系統中打包的內核頭文件。
vmlinux.h
文件是可以通過 bpftool 工具生成的文件,用於包括內核映像中的所有數據類型。這是一個方便的單個頭文件,供 eBPF 程序從中包括,而不是一組廣泛而有些特殊的內核頭文件,可能會因開發人員的系統而異。我們建議創建此文件的精簡版本,只包括應用程序實際需要的內核定義。這可以確保:
-
與目標內核版本的數據類型保持一致
-
可以充分利用 CO-RE 重定位
-
具有適當大小的頭文件,更容易維護
4. 針對所有目標內核版本和相關子系統配置測試 eBPF 應用程序。
即使遵循所有 CO-RE 最佳實踐,也很重要測試任何 eBPF 應用程序,測試所有或一組寬泛的內核版本以及相關內核子系統和模塊配置的變化,以確保在所有目標部署中具有完全的可移植性和正確性。
5. 確定應用程序所需的最低內核版本。
首先,閱讀 BPF 功能文檔 [40],以確定包含所需功能的內核版本範圍。例如:
-
cgroup/connect4 程序支持是在 4.17 中添加的。
-
BPF 有界循環是在 5.3 中添加的。
然後,您可以選擇編寫您的應用程序,僅使用內核版本中可用的 eBPF 函數,或者使用 BPF 功能探測來在運行時檢測功能的可用性。
您的 BPF 程序可以檢查內核版本:
#include <bpf/bpf_helpers.h>
extern int LINUX_KERNEL_VERSION __kconfig;
int probe_kernel()
{
if (LINUX_KERNEL_VERSION > KERNEL_VERSION(4, 18, 0)) {
/* 我們在支持的內核版本上 */
} else {
/* 記錄錯誤並優雅退出 */
}
...
}
您的 BPF 程序還可以探測單個內核功能或結構定義:
extern bool CONFIG_LWTUNNEL_BPF __kconfig __weak;
if (CONFIG_LWTUNNEL_BPF) {
/* 從BPF配置lwtunnel */
}
if (bpf_core_type_exists(struct bpf_ringbuf)) {
/* 使用ringbuf而不是perf緩衝區 */
}
運行中的 BPF 程序的架構
下圖顯示了用戶空間應用程序及其嵌入式 BPF 程序的視圖。該應用程序鏈接到 libbpf,libbpf 代表應用程序創建 BPF 映射並加載程序。
在此圖中,我們可以看到 BPF 程序連接到網絡數據路徑中的tc
鉤子。用戶空間應用程序和 BPF 程序共享訪問由內核中的 BPF 子系統管理的映射。BPF 程序還使用助手函數從其他內核子系統中訪問數據。
使用 libbpf 的 C 應用程序示例
這裏討論的主題最好通過示例應用程序來演示。我們將使用 DNS 跟蹤實用程序來突出顯示主要要點。
libbpf-bootstrap[41] 爲使用 libbpf 的 C 項目提供了一個很好的起點。在這裏,我們通過複製 libbpf-bootstrap 的 Makefile 和項目佈局,並根據自己的需求進行調整,創建了一個 dns-trace 實用程序項目:
.
├── Makefile
├── dns-trace.bpf.c # BPF代碼
├── dns-trace.c # 用戶空間代碼
├── dns-trace.h # 共享定義
├── libbpf # libbpf git子模塊
└── .output
├── dns-trace.skel.h # 骨架,由bpftool生成
└── vmlinux.h # 所有內核類型定義,由bpftool生成
共享定義
dns-trace 實用程序有一個 BPF 部分,用於攔截 DNS 數據包,以及一個用戶空間部分,用於解碼 DNS 消息並報告各種指標。BPF 程序捕獲的數據以事件流的形式通過 BPF 環形緩衝區發送到用戶空間程序。struct dns_event
在 BPF 和用戶空間程序中都被使用。請注意確保類型定義對兩個編譯單元都可以解析。
-
用戶空間程序使用系統頭文件,包括 UAPI 導出的內核類型,如
__u32
和 libbpf 頭文件。 -
BPF 程序也在包括生成的
<vmlinux.h>
時具有訪問 UAPI 導出的內核類型的能力,同時還包括了所有內核類型定義。
任何要包括在兩個編譯單元中的結構都需要使用 UAPI 導出的內核類型並避免內核的內部類型定義。
struct dns_event {
__u64 duration;
char ifname[IFNAMSIZ];
__u32 srcip;
__u32 dstip;
__u16 length;
unsigned char payload[MAXMSG];
__u16 id;
__u16 flags;
};
訪問內核數據結構
BPF 程序連接到net_dev_queue
內核跟蹤點,以攔截主機上運行的任何程序發送或接收的所有數據包。跟蹤點上下文包括一個指向保存數據包數據的struct sk_buff
的指針。我們只對訪問sk_buff->data
和sk_buff->len
字段感興趣,因此我們可以使用 CO-RE 來訪問它們。BPF 程序定義了自己的struct sk_buff
的私有版本,其中只包含我們需要的字段。該結構使用preserve_access_index
屬性進行註釋,以便在加載 BPF 程序時進行 CO-RE 重定位。
struct sk_buff {
unsigned char *data;
unsigned int len;
} __attribute__((preserve_access_index));
struct trace_event_raw_net_dev_template {
struct sk_buff *skbaddr;
} __attribute__((preserve_access_index));
此項目本地的struct sk_buff
定義清晰地說明了我們實際需要的結構的子集。C 代碼使用BPF_CORE_READ()
宏來訪問struct sk_buff
字段,再次在加載 BPF 程序時啓用 CO-RE 重定位到運行的內核。
SEC("tracepoint/net/net_dev_queue")
int trace_net_packets(struct trace_event_raw_net_dev_template *ctx) {
unsigned char *data = BPF_CORE_READ(ctx, skbaddr, data);
unsigned int len = BPF_CORE_READ(ctx, skbaddr, len);
do_trace(data, len);
return BPF_OK;
}
用戶空間應用程序
用戶空間應用程序通過生成的 BPF 程序骨架使用 libbpf 來加載 BPF 程序並訪問 BPF 程序中定義的映射。骨架由項目 Makefile 中的bpftool gen skeleton
生成。骨架派生自 BPF 程序,因此所有映射應該在 BPF C 代碼中定義,然後通過用戶空間代碼中的骨架訪問器引用。
生成的骨架提供了加載 BPF 代碼和附加 BPF 程序的函數:
/* Load and verify BPF object file */
skel = dns_trace_bpf__open();
if (!skel) {
fprintf(stderr, "Failed to open and load BPF skeleton\n");
return 1;
}
/* Load & verify BPF programs */
err = dns_trace_bpf__load(skel);
if (err) {
fprintf(stderr, "Failed to load and verify BPF skeleton\n");
goto cleanup;
}
/* Attach tracepoints */
err = dns_trace_bpf__attach(skel);
if (err) {
fprintf(stderr, "Failed to attach BPF skeleton\n");
goto cleanup;
}
從用戶空間程序中設置和輪詢 BPF 環形緩衝區所需的代碼非常少:
struct ring_buffer* ringbuf =
ring_buffer__new(bpf_map__fd(skel->maps.dns_events), process_event, NULL, NULL);
while (!exiting) {
ring_buffer__poll(ringbuf, 100);
}
應用程序使用與 BPF 程序共享的struct dns_event
定義從 BPF 程序的環形緩衝區接收事件。
eBPF 文檔體系
BPF 子系統和支持庫擁有大量文檔資源,但它們分散在不同的位置。以下是一些有用的鏈接,可幫助您訪問最相關的文檔:
-
eBPF Foundation: eBPF 文檔 [42]
-
內核文檔: BPF 文檔 [43], BPF 映射 [44], 程序類型 [45], BPF kfuncs[46]
-
手冊頁: bpf-helpers[47], bpftool
-
庫文檔: libbpf[48], libxdp[49], Aya[50], Cilium ebpf[51]
-
參考博客: BPF CO-RE 參考指南 [52]
-
示例: libbpf-bootstrap[53], 實用 BPF 示例 [54]
需要注意的是,BPF 領域沒有單一的權威指南,而且仍有很多未記錄的知識。
eBPF 術語
-
BTF: BPF 類型格式是一種用於存儲有關 Linux 內核或 BPF 程序類型信息的緊湊編碼。它用於通過 BPF CO-RE 實現 BPF 程序的可移植性。
-
CO-RE: BPF CO-RE(編譯一次,到處運行)使得編寫可在多個內核版本上運行的可移植 BPF 應用程序成爲可能,無需修改或重新編譯目標機器。
-
內核用戶空間 API(UAPI): UAPI 是內核和用戶空間之間的接口,由系統調用、頭文件、sysfs、procfs、BPF 輔助函數等組成。
譯者注
原文來自 RedHat 的博客 BPF application development: Beyond the basics [55] 本文爲機翻 + 人工矯正。
筆者的 eCapture[56] 項目,用戶空間加載器使用 ebpfmanager[57] 類庫,包裝了 cilium/ebpf 類庫,也是純 Go 的加載器。在這裏也推薦給大家。
參考資料
[1]
Linux: https://developers.redhat.com/topics/linux/
[2]
eBPF 詳盡介紹: https://lwn.net/Articles/740157/
[3]
Clang: https://developers.redhat.com/products/gcc-clang-llvm-go-rust/overview
[4]
BPF 功能按 Linux 內核版本排序的列表: https://github.com/iovisor/bcc/blob/master/docs/kernel-versions.md
[5]
選擇您的 eBPF 應用程序棧: https://developers.redhat.com/articles/2023/04/28/ebpf-application-development-beyond-basics#choosing_your_ebpf_application_stack
[6]
eBPF 應用程序跨開發、可移植性、CO-RE 和內核 API 穩定性: https://developers.redhat.com/articles/2023/04/28/ebpf-application-development-beyond-basics#ebpf_application_cross_development__portability__co_re__and_kernel_api_stability
[7]
Cilium: https://cilium.io/
[8]
Pixie: https://github.com/redhat-et/bpf-docs/blob/main/app-dev/px.dev
[9]
最近的案例: https://youtu.be/u0PGas8D24w?t=178
[10]
libxdp: https://github.com/xdp-project/xdp-tools/tree/master/lib/libxdp
[11]
bpfd: https://github.com/redhat-et/bpfd
[12]
BPF 開發 FAQ: https://docs.kernel.org/bpf/bpf_devel_QA.html#q-how-do-the-changes-make-their-way-into-linux
[13]
kfuncs: https://docs.kernel.org/bpf/kfuncs.html
[14]
BPF 許可指南: https://docs.kernel.org/bpf/bpf_licensing.html
[15]
ConnectX-6: https://developer.nvidia.com/blog/accelerating-with-xdp-over-mellanox-connectx-nics/
[16]
C: https://developers.redhat.com/topics/c
[17]
Golang: https://developers.redhat.com/topics/go
[18]
Rust: https://developers.redhat.com/topics/rust
[19]
內核 ebpf 系統調用: https://docs.kernel.org/userspace-api/ebpf/syscall.html
[20]
BCC: https://github.com/iovisor/bcc
[21]
libbpf: https://github.com/libbpf/libbpf
[22]
CO-RE(Compile Once Run Everywhere): https://nakryiko.com/posts/bpf-core-reference-guide/
[23]
tools/lib/bpf: https://elixir.bootlin.com/linux/v6.0.11/source/tools/lib/bpf
[24]
libbpf 的鏡像: https://github.com/libbpf/libbpf
[25]
於 2022 年中發佈了 1.0 版本: https://nakryiko.com/posts/libbpf-v1/
[26]
最近發佈了 1.2 版本: https://github.com/libbpf/libbpf/releases/tag/v1.2.0
[27]
libbpf-bootstrap: https://github.com/libbpf/libbpf-bootstrap
[28]
一組有用的模板和示例程序: https://nakryiko.com/posts/libbpf-bootstrap/
[29]
Cilium ebpf 庫: https://github.com/cilium/ebpf
[30]
libbpfgo: https://github.com/aquasecurity/libbpfgo
[31]
Aya: https://aya-rs.dev/book/
[32]
Aya: https://aya-rs.dev/book/
[33]
bpfd: https://github.com/redhat-et/bpfd
[34]
CO-RE(編譯一次,隨處運行): https://nakryiko.com/posts/bpf-core-reference-guide/
[35]
Red Hat 企業 Linux: https://developers.redhat.com/products/rhel/download#rhel3ways
[36]
BCC: https://github.com/iovisor/bcc
[37]
本文: https://nakryiko.com/posts/bpf-portability-and-co-re/
[38]
CO-RE 指南: https://nakryiko.com/posts/bpf-core-reference-guide/
[39]
CO-RE 指南: https://nakryiko.com/posts/bpf-core-reference-guide/
[40]
BPF 功能文檔: https://github.com/iovisor/bcc/blob/master/docs/kernel-versions.md
[41]
libbpf-bootstrap: https://github.com/libbpf/libbpf-bootstrap
[42]
eBPF 文檔: https://ebpf.foundation/what-is-ebpf/
[43]
BPF 文檔: https://docs.kernel.org/bpf/index.html
[44]
BPF 映射: https://docs.kernel.org/bpf/maps.html
[45]
程序類型: https://docs.kernel.org/bpf/libbpf/program_types.html#program-types-and-elf
[46]
BPF kfuncs: https://docs.kernel.org/bpf/kfuncs.html
[47]
bpf-helpers: https://man7.org/linux/man-pages/man7/bpf-helpers.7.html
[48]
libbpf: https://libbpf.readthedocs.io/en/latest/api.html
[49]
libxdp: https://github.com/xdp-project/xdp-tools/tree/master/lib/libxdp
[50]
Aya: https://aya-rs.dev/
[51]
Cilium ebpf: https://pkg.go.dev/github.com/cilium/ebpf
[52]
BPF CO-RE 參考指南: https://nakryiko.com/posts/bpf-core-reference-guide/
[53]
libbpf-bootstrap: https://github.com/libbpf/libbpf-bootstrap
[54]
實用 BPF 示例: https://github.com/xdp-project/bpf-examples
[55]
BPF application development: Beyond the basics : https://developers.redhat.com/articles/2023/10/19/ebpf-application-development-beyond-basics
[56]
eCapture: https://github.com/gojue/ecapture
[57]
ebpfmanager: https://github.com/gojue/ebpfmanager
[58]
Java 高級開發: https://job.meituan.com/web/position/detail?jobUnionId=2039344677
[59]
C/C++ 技術專家(零信任方向): https://job.meituan.com/web/position/detail?jobUnionId=1601389658
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/rSvTIDCIhhJnBQ5UIpmG8A