參考鏈接:
https://toutiao.io/posts/glvi9rz/preview
https://houmin.cc/posts/28ca4f79/
http://arthurchiao.art/blog/understanding-ebpf-datapath-in-cilium-zh/
1.xdp 獲得的數據
以太網幀 數據結構體是 ethhdr,使用 xdp_buff 結構體來表示以太網幀的頭部
2.tc獲得的數據
ip數據報 數據結構體是 sk_buffer
tc BPF hook 的 BPF 程序可以讀取 skb 的 mark
、pkt_type
、 protocol
、priority
、queue_mapping
、napi_id
、cb[]
、hash
、tc_classid
、tc_index
、vlan 元數據、XDP 層傳過來的自定義元數據以及其他信息。 tc BPF 的 BPF 上下文中使用了 struct __sk_buff
,這個結構體中的所有成員字段都定 義在 linux/bpf.h
系統頭文件。
3.sk_buff
和 xdp_buff
完全不同,二者各有優劣
sk_buff
修改與其關聯的元數據非常方便,但它包含了大量協議相關的信息(例如 GSO 相關的狀態),這使得無法僅僅通過重寫包數據來切換協議。- 這是因為協議棧是基於元數據處理包的,而不是每次都去讀包的內容。因此,BPF 輔助函數需要額外的轉換,並且還要正確處理
sk_buff
內部信息。 xdp_buff
沒有這些問題,因為它所處的階段非常早,此時內核還沒有分配sk_buff
,因此很容易實現各種類型的數據包重寫。- 但是,
xdp_buff
的缺點是在它這個階段進行 mangling 的時候,無法利用到sk_buff
元數據。 - 解決這個問題的方式是從 XDP BPF 傳遞自定義的元數據到 tc BPF。這樣,根據使用場景的不同,可以同時利用這兩者 BPF 程序,以達到互補的效果。
4.hook 觸發點
tc BPF 程序在數據路徑上的 ingress 和 egress 點都可以觸發;而 XDP BPF 程序只能在 ingress 點觸發。內核兩個 hook 點:
- ingress hook
sch_handle_ingress()
:由__netif_receive_skb_core()
觸發 - egress hook
sch_handle_egress()
:由__dev_queue_xmit()
觸發
__netif_receive_skb_core()
和 __dev_queue_xmit()
是 data path 的主要接收和發送函數,不考慮 XDP 的話(XDP 可能會攔截或修改,導致不經過這兩個 hook 點), 每個網絡進入或離開系統的網絡包都會經過這兩個點,從而使得 tc BPF 程序具備完全可觀測性。
是否依賴驅動支持
tc BPF 程序不需要驅動做任何改動,因為它們運行在網絡棧通用層中的 hook 點。因此,它們可以 attach 到任何類型的網絡設備上。
Ingress
這提供了很好的靈活性,但跟運行在原生 XDP 層的程序相比,性能要差一些。然而,tc BPF 程序仍然是內核的通用 data path 做完 GRO 之后、且處理任何協議之前 最早的處理點。傳統的 iptables 防火牆也是在這里處理的,例如 iptables PREROUTING 或 nftables ingress hook 或其他數據包包處理過程。
Egress
類似的,對於 egress,tc BPF 程序在將包交給驅動之前的最晚的地方執行,這個地方在傳統 iptables 防火牆 hook 之后(例如 iptables POSTROUTING), 但在內核 GSO 引擎之前。
唯一需要驅動做改動的場景是:將 tc BPF 程序 offload 到網卡。形式通常和 XDP offload 類似,只是特性列表不同,因為二者的 BPF 輸入上下文、輔助函數和返回碼( verdict)不同。支持 offload tc BPF 程序的驅動 Netronome/nfp。
相對於DPDK,XDP:
優點
-
無需第三方代碼庫和許可
-
同時支持輪詢式和中斷式網絡
-
無需分配大頁
-
無需專用的CPU
-
無需定義新的安全網絡模型
缺點
注意XDP的性能提升是有代價的,它犧牲了通用型和公平性
-
XDP不提供緩存隊列(qdisc),TX設備太慢時直接丟包,因而不要在RX比TX快的設備上使用XDP
-
XDP程序是專用的,不具備網絡協議棧的通用性
如何選擇?
-
內核延伸項目,不想bypass內核的下一代高性能方案;
-
想直接重用內核代碼;
-
不支持DPDK程序環境;
XDP適合場景
-
DDoS防御
-
防火牆
-
基於XDP_TX的負載均衡
-
網絡統計
-
流量監控
-
棧前過濾/處理
-
...