Linux 封包處理的 XDP 與 eBPF
14 分鐘閱讀 - 2026年5月27日
XDP 和 eBPF 如何在 NIC 驅動程式層級處理每秒數百萬個封包。基準、DDoS 使用案例、工具鏈設定和硬體需求。
用於高效能封包處理的 XDP 與 eBPF
XDP(eXpress Data Path)與 eBPF(extended Berkeley Packet Filter)讓 Linux 能在內核的標準網路堆疊介入之前,先行處理網路封包。XDP 無需為每個傳入封包分配記憶體結構,而是直接在 NIC 驅動程式層級攔截流量,決定如何處理,並將其丟棄、轉發或重新導向。 其結果是每核心每秒可處理數百萬個封包,且 CPU 開銷僅為傳統工具(如 iptables.
eBPF 與 XDP 如何協同運作
eBPF 是 Linux 核心內部的虛擬機器。它執行經過安全性驗證(無無限迴圈、無未授權記憶體存取)的自訂位元組碼,並透過即時編譯(JIT)轉譯為原生 CPU 指令。程式執行範圍受限,無法呼叫任意核心函式,僅能使用預先定義的一組輔助函式來執行諸如映射查詢和封包重定向等任務。
在狀態管理方面,eBPF 使用映射(maps),這是一種可跨封包抵達持續存在的鍵值儲存(哈希表、陣列、LPM 試圖)。映射可在使用者空間讀寫,因此您無需重新載入程式即可更新封鎖清單或路由規則。
XDP 是 eBPF 的掛鉤點。它掛載於 NIC 驅動程式的接收路徑上,位於核心分配 sk_buff 結構體(傳統網路堆疊所依賴的、每封封包 200-300 位元的元資料物件)之前。跳過該分配步驟正是性能提升的來源。
XDP 具備三種運作模式:
- 原生模式:在 NIC 驅動程式內部執行。效能最佳。
- 卸載模式:在 NIC 的 ASIC 上運行。完全釋放 CPU 資源。
- 通用模式:在
sk_buff。適用於在未受支援的硬體上進行測試,但無性能優勢。
處理每個封包後,XDP 程式會返回一個判定結果:
| 判定 | 動作 |
|---|---|
XDP_DROP | 在驅動程式層級丟棄封包 |
XDP_PASS | 轉發至標準網路堆疊 |
XDP_TX | 透過相同介面發送出去 |
XDP_REDIRECT | 重定向至另一張網路介面卡或 AF_XDP 使用者空間套接字 |
XDP_ABORTED | 因程式錯誤而丟棄,並記錄追蹤事件 |
XDP 與 iptables:效能基準測試
數據令人震驚。 iptables 每核心每秒處理約 200,000 個封包。 nftables 則將此效能提升至約 400,000 pps。在原生模式下,XDP 能在相同硬體上以每個核心處理 1,000 萬至 4,000 萬 pps。
原因很簡單: XDP_DROP 需要一次邊界檢查和一個回傳值。一個 iptables DROP 則需要 sk_buff 需進行記憶體分配、netfilter 鏈路遍歷、連線追蹤查詢、DROP 動作本身,以及後續的記憶體釋放。在 100 Gbps 且封包大小為 64 位元組的情況下,伺服器每秒需處理 1.48 億個封包,每個封包僅剩約 100 奈秒。在此規模下, sk_buff 記憶體分配便成為瓶頸。
CPU 資源的節省同樣顯著。在某項基準測試中,將封鎖清單從 iptables 遷移至 XDP,在 100 萬封包每秒的基準測試中,將軟體中斷的 CPU 使用率從 28% 降至 3%。這釋放出的處理餘裕,可在同一台伺服器上執行應用程式、資料庫或虛擬機器。
DDoS 緩解與安全
XDP 最強大的主機應用場景在於 DDoS 緩解。由於其在驅動程式層級運作,惡意封包在觸及核心網路堆疊之前即被拋棄。單一執行 XDP 的核心每秒可拋棄 2,600 萬個封包。
Cloudflare 自 2018 年起便採用名為 L4Drop 的 XDP 系統來緩解流量型 DDoS 攻擊。該系統在 XDP 執行環境中處理並拋棄攻擊流量,防止其抵達應用層。Meta 的 Katran 是一款開源的 XDP 第 4 層負載平衡器,為 Facebook 和 Instagram 處理流量,每核心處理速度超過 1,000 萬封包/秒。
至於動態過濾,eBPF 映射如 BPF_MAP_TYPE_LPM_TRIE 讓您能透過單次查詢管理涵蓋單一 IP 及 CIDR 子網的 IP 封鎖清單。更新由使用者空間即時進行,無需重新載入程式。在攻擊發生期間,您可以利用 bpftool:
bpftool map update id <MAP_ID> key <KEY_VALUE> value <VALUE>在可觀測性方面,eBPF 直接從核心資料路徑收集各應用程式、各 IP 及各流量流的指標。 xdp_md 上下文提供如 ingress_ifindex 和 rx_queue_index等遙測資料,讓您能識別哪些介面或佇列正承受壓力。針對長期監控,像 ebpf_exporter 等工具可將原始 eBPF 映射資料轉換為與 Prometheus 相容的指標,以便在 Grafana 中進行視覺化呈現。
工具、部署與硬體需求
工具鏈以 Clang 和 LLVM 為起點,用於將受限 C 語言編譯為 eBPF 位元組碼。接著,您需要一個載入器函式庫:
libbpf: 適用於生產環境的標準 C 函式庫。支援 CO-RE(一次編譯,隨處執行)以實現跨核心的可移植性。libxdp: 專為 XDP 設計,支援在單一介面上執行多個 XDP 程式。cilium/ebpf:專為基於 Go 的堆疊設計的純 Go 函式庫。
在管理方面, bpftool 可讓您檢視執行中的程式及映射內容。 xdp-loader (來自 xdp-tools 套件) 負責載入與卸載。BCC 適用於搭配 Python/Lua 前端進行原型開發,但 libbpf 若用於生產環境,搭配 CO-RE 才是更佳的選擇。
部署前請啟用 BPF JIT 編譯器:
sysctl -w net.core.bpf_jit_enable=1若要實現零停機更新,請使用 XDP_FLAGS_REPLACE 標誌以原子式地替換正在執行的程式。將映射固定至 /sys/fs/bpf/ ,使其在載入器退出後仍能保留。
硬體與核心相容性
XDP 雖於 4.8 版核心中引入,但建議使用 5.x 或更新版本以獲得完整功能集。請使用 uname -r 並確認 BPF 檔案系統是否存在於 /sys/fs/bpf/.
您的網路介面卡 (NIC) 驅動程式決定了可用的 XDP 功能:
| 驅動程式 | 基本 XDP | 重定向 | 零拷貝 (AF_XDP) |
|---|---|---|---|
mlx5_core | 是 | 是 | 是 |
i40e | 是 | 是 | 是 |
ixgbe | 是 | 是 | 是 |
virtio_net | 是 | 是 | 否 |
ena (Amazon) | 是 | 是 | 否 |
請使用 ethtool -i <interface>。若不支援原生模式,系統將回退至通用模式,該模式會在 sk_buff ,且無法提供任何效能優勢。
在掛載 XDP 程式之前請先停用 GRO 和 LRO,因為它們會產生衝突:
ethtool -K <iface> gro off lro off標準 XDP 要求封包必須能容納於單一 4,096 位元組的記憶體頁中。在 i40e 和 ice 驅動程式上,x86 的 MTU 限制為 3,046 位元組。
XDP 入門指南
首先評估您的環境。執行 uname -r 以確認核心版本為 4.8 以上(建議使用 5.x 系列),並執行 ethtool -i <interface> 以檢查是否支援原生 XDP 驅動程式。
請從可觀察性著手,而非直接實施強制措施。使用 eBPF 映射來分類和統計流量,以便建立正常活動的基準線。在了解流量模式後,再轉向強制措施:先以 xdpgeneric 模式進行測試,隨後切換至 xdpdrv (原生) 模式進行正式部署。
請注意,XDP 處理的是封包層級的過濾,而非原始頻寬。針對 100 Gbps 的大規模攻擊,應搭配裸機基礎架構與 BGP FlowSpec,在流量抵達伺服器之前即管理上游流量。
若您正在執行需要快速封包過濾的高流量工作負載,FDC 的專用伺服器可提供裸機基礎架構,讓您充分發揮 XDP 的效能。
如何在 Linux 上優化儲存空間
15 分鐘閱讀 - 2026年5月22日