XDP RX 元資料¶
本文件介紹 eXpress Data Path (XDP) 程式如何使用一組輔助函式訪問與資料包相關的硬體元資料,以及如何將該元資料傳遞給其他使用者。
通用設計¶
XDP 有權訪問一組 kfunc 來操作 XDP 幀中的元資料。每個希望公開其他資料包元資料的裝置驅動程式都可以實現這些 kfunc。kfunc 集在 include/net/xdp.h 中透過 XDP_METADATA_KFUNC_xxx 宣告。
目前,支援以下 kfunc。將來,隨著支援的元資料越來越多,此集合將會增加
-
__bpf_kfunc int bpf_xdp_metadata_rx_timestamp(const struct xdp_md *ctx, u64 *timestamp)¶
讀取 XDP 幀 RX 時間戳。
引數
const struct xdp_md *ctxXDP 上下文指標。
u64 *timestamp返回值指標。
返回
成功返回 0,錯誤返回
-errno。-EOPNOTSUPP:表示裝置驅動程式未實現 kfunc-ENODATA:表示此幀沒有 RX-timestamp 可用
-
__bpf_kfunc int bpf_xdp_metadata_rx_hash(const struct xdp_md *ctx, u32 *hash, enum xdp_rss_hash_type *rss_type)¶
讀取 XDP 幀 RX 雜湊。
引數
const struct xdp_md *ctxXDP 上下文指標。
u32 *hash返回值指標。
enum xdp_rss_hash_type *rss_typeRSS 型別的返回值指標。
描述
RSS 雜湊型別 (rss_type) 指定 NIC 硬體在計算 RSS 雜湊值時使用的資料包標頭部分。可以透過 enum xdp_rss_hash_type 解碼 RSS 型別,可以匹配單個 L3/L4 位 XDP_RSS_L* 或組合的傳統 _RSS 雜湊型別_ XDP_RSS_TYPE_L*。
返回
成功返回 0,錯誤返回
-errno。-EOPNOTSUPP:表示裝置驅動程式未實現 kfunc-ENODATA:表示此幀沒有 RX-hash 可用
-
__bpf_kfunc int bpf_xdp_metadata_rx_vlan_tag(const struct xdp_md *ctx, __be16 *vlan_proto, u16 *vlan_tci)¶
獲取 XDP 資料包最外層 VLAN 標籤
引數
const struct xdp_md *ctxXDP 上下文指標。
__be16 *vlan_protoVLAN 標籤協議識別符號 (TPID) 的目標指標。
u16 *vlan_tciVLAN TCI(VID + DEI + PCP)的目標指標
描述
如果成功,vlan_proto 包含 _標籤協議識別符號 (TPID)_,通常為 ETH_P_8021Q 或 ETH_P_8021AD,但有些網路可能使用自定義 TPID。vlan_proto 以 **網路位元組順序 (BE)** 儲存,應按如下方式使用:if (vlan_proto == bpf_htons(ETH_P_8021Q)) do_something();
vlan_tci 包含 VLAN 標籤的其餘 16 位。驅動程式應以 **主機位元組順序(通常為 LE)** 提供這些位,因此 bpf 程式不應執行位元組轉換。根據 802.1Q 標準,_VLAN TCI(標籤控制資訊)_ 是一個位欄位,包含:_VLAN 識別符號 (VID)_,可以使用 vlan_tci & 0xfff 讀取,_丟棄資格指示符 (DEI)_ - 1 位,_優先順序程式碼點 (PCP)_ - 3 位。有關 DEI 和 PCP 的詳細含義,請參閱其他來源。
返回
成功返回 0,錯誤返回
-errno。-EOPNOTSUPP:裝置驅動程式未實現 kfunc-ENODATA:VLAN 標籤未剝離或不可用
XDP 程式可以使用這些 kfunc 將元資料讀取到堆疊變數中以供自己使用。或者,要將元資料傳遞給其他使用者,XDP 程式可以將其儲存到資料包前方的元資料區域中。並非所有資料包都一定具有所請求的元資料,在這種情況下,驅動程式會返回 -ENODATA。
並非所有 kfunc 都必須由裝置驅動程式實現;如果未實現,則將使用返回 -EOPNOTSUPP 的預設 kfunc 來指示裝置驅動程式未實現此 kfunc。
在 XDP 幀中,元資料佈局(透過 xdp_buff 訪問)如下所示
+----------+-----------------+------+
| headroom | custom metadata | data |
+----------+-----------------+------+
^ ^
| |
xdp_buff->data_meta xdp_buff->data
XDP 程式可以將單個元資料項以其選擇的任何格式儲存到此 data_meta 區域中。元資料的後續使用者必須透過某種帶外協議(例如 AF_XDP 用例,見下文)就格式達成一致。
AF_XDP¶
AF_XDP 用例意味著 BPF 程式與最終使用者之間存在協議,BPF 程式將 XDP 幀重定向到 AF_XDP 套接字 (XSK)。因此,BPF 程式透過 bpf_xdp_adjust_meta 手動分配固定數量的元資料位元組,並呼叫 kfunc 子集來填充它。使用者空間 XSK 使用者計算 xsk_umem__get_data() - METADATA_SIZE 來找到該元資料。請注意,xsk_umem__get_data 在 libxdp 中定義,METADATA_SIZE 是應用程式特定的常量(AF_XDP 接收描述符_不_顯式攜帶元資料的大小)。
這是 AF_XDP 使用者佈局(請注意缺少 data_meta 指標)
+----------+-----------------+------+
| headroom | custom metadata | data |
+----------+-----------------+------+
^
|
rx_desc->address
XDP_PASS¶
這是 XDP 程式處理的資料包傳遞到核心的路徑。核心從 xdp_buff 內容建立 skb。目前,每個驅動程式都有自定義核心程式碼來解析描述符並在執行此 xdp_buff->skb 轉換時填充 skb 元資料,並且核心在構建 skbs 時不使用 XDP 元資料。但是,TC-BPF 程式可以使用 data_meta 指標訪問 XDP 元資料區域。
將來,我們希望支援這樣一種情況:XDP 程式可以覆蓋用於構建 skbs 的某些元資料。
bpf_redirect_map¶
bpf_redirect_map 可以將幀重定向到其他裝置。某些裝置(例如虛擬乙太網連結)支援在重定向後執行第二個 XDP 程式。但是,最終使用者無法訪問原始硬體描述符,也無法訪問任何原始元資料。這同樣適用於安裝到 devmap 和 cpumap 中的 XDP 程式。
這意味著對於重定向的資料包,目前僅支援自定義元資料,必須由初始 XDP 程式在重定向之前準備好。如果該幀最終傳遞到核心,則從此幀建立的 skb 將不會在其 skb 中填充任何硬體元資料。如果此類資料包稍後重定向到 XSK 中,則也將只能訪問自定義元資料。
bpf_tail_call¶
目前不支援將訪問元資料 kfunc 的程式新增到 BPF_MAP_TYPE_PROG_ARRAY。
支援的裝置¶
可以透過 netlink 查詢特定 netdev 實現的 kfunc。請參閱 Documentation/netlink/specs/netdev.yaml 中設定的 xdp-rx-metadata-features 屬性。
示例¶
有關處理 XDP 元資料的 BPF 程式的示例,請參閱 tools/testing/selftests/bpf/progs/xdp_metadata.c 和 tools/testing/selftests/bpf/prog_tests/xdp_metadata.c。