Netfilter 的 flowtable 基礎設施

本文件描述了 Netfilter flowtable 基礎設施,它允許您透過 flowtable 資料路徑定義快速通道。此基礎設施還提供硬體解除安裝支援。flowtable 支援第 3 層 IPv4 和 IPv6 以及第 4 層 TCP 和 UDP 協議。

概述

一旦流的第一個資料包成功透過 IP 轉發路徑,從第二個資料包開始,您可以決定透過您的規則集將該流解除安裝到 flowtable。 flowtable 基礎設施提供了一個規則操作,允許您指定何時將流新增到 flowtable。

在 flowtable 中找到匹配條目的資料包(即 flowtable 命中)透過 neigh_xmit() 傳輸到輸出網路裝置,因此,資料包繞過傳統的 IP 轉發路徑(可見的效果是您無法在入口後出現的任何 Netfilter 鉤子中看到這些資料包)。 如果 flowtable 中沒有匹配的條目(即 flowtable 未命中),則資料包遵循傳統的 IP 轉發路徑。

flowtable 使用可調整大小的雜湊表。 查詢基於以下 n 元組選擇器:第 2 層協議封裝(VLAN 和 PPPoE)、第 3 層源和目標、第 4 層源和目標埠以及輸入介面(如果存在多個 conntrack 區域,則很有用)。

“flow add”操作允許您填充 flowtable,使用者有選擇地指定哪些流被放入 flowtable。 因此,除非使用者明確指示流透過策略使用這種新的替代轉發路徑,否則資料包將遵循傳統的 IP 轉發路徑。

flowtable 資料路徑在圖 1 中表示,該圖描述了經典的 IP 轉發路徑,包括 Netfilter 鉤子和 flowtable 快速通道繞過。

                                       userspace process
                                        ^              |
                                        |              |
                                   _____|____     ____\/___
                                  /          \   /         \
                                  |   input   |  |  output  |
                                  \__________/   \_________/
                                       ^               |
                                       |               |
    _________      __________      ---------     _____\/_____
   /         \    /          \     |Routing |   /            \
-->  ingress  ---> prerouting ---> |decision|   | postrouting |--> neigh_xmit
   \_________/    \__________/     ----------   \____________/          ^
     |      ^                          |               ^                |
 flowtable  |                     ____\/___            |                |
     |      |                    /         \           |                |
  __\/___   |                    | forward |------------                |
  |-----|   |                    \_________/                            |
  |-----|   |                 'flow offload' rule                       |
  |-----|   |                   adds entry to                           |
  |_____|   |                     flowtable                             |
     |      |                                                           |
    / \     |                                                           |
   /hit\_no_|                                                           |
   \ ? /                                                                |
    \ /                                                                 |
     |__yes_________________fastpath bypass ____________________________|

             Fig.1 Netfilter hooks and flowtable interactions

flowtable 條目還儲存 NAT 配置,因此所有資料包都根據從經典 IP 轉發路徑指定的 NAT 策略進行處理。 TTL 在呼叫 neigh_xmit() 之前遞減。 由於缺少傳輸標頭,碎片化的流量會傳遞到經典的 IP 轉發路徑,在這種情況下,無法進行 flowtable 查詢。 TCP RST 和 FIN 資料包也會傳遞到經典的 IP 轉發路徑,以便優雅地釋放流。 超過 MTU 的資料包也會傳遞到經典的轉發路徑,以便向傳送者報告資料包過大 ICMP 錯誤。

示例配置

啟用 flowtable 繞過相對容易,您只需要建立一個 flowtable 並在您的轉發鏈中新增一個規則

table inet x {
        flowtable f {
                hook ingress priority 0; devices = { eth0, eth1 };
        }
        chain y {
                type filter hook forward priority 0; policy accept;
                ip protocol tcp flow add @f
                counter packets 0 bytes 0
        }
}

此示例將 flowtable “f” 新增到 eth0 和 eth1 網路裝置的入口鉤子。 如果您需要執行資源分割槽,您可以根據需要建立任意數量的 flowtable。 flowtable 優先順序定義了鉤子在管道中執行的順序,如果您已經有一個 nftables 入口鏈,這將非常方便(確保 flowtable 優先順序小於 nftables 入口鏈,因此 flowtable 在管道中先執行)。

轉發鏈 “y” 中的 “flow offload” 操作會將一個條目新增到 flowtable,用於來自回覆方向的 TCP syn-ack 資料包。 一旦流被解除安裝,您將觀察到,對於透過轉發繞過轉發的資料包,上述示例中的計數器規則不會被更新。

當列出您的連線跟蹤表時,您可以透過 [OFFLOAD] 標籤來識別解除安裝的流。

# conntrack -L
tcp      6 src=10.141.10.2 dst=192.168.10.2 sport=52728 dport=5201 src=192.168.10.2 dst=192.168.10.1 sport=5201 dport=52728 [OFFLOAD] mark=0 use=2

第 2 層封裝

自從 Linux 核心 5.13 以來,flowtable 基礎設施發現了 VLAN 和 PPPoE 網路裝置背後的真實網路裝置。 flowtable 軟體資料路徑解析 VLAN 和 PPPoE 第 2 層標頭以提取乙太網型別和 VLAN ID / PPPoE 會話 ID,這些資訊用於 flowtable 查詢。 flowtable 資料路徑還處理第 2 層解封裝。

您不需要將 PPPoE 和 VLAN 裝置新增到您的 flowtable,相反,真實裝置足以讓 flowtable 跟蹤您的流。

橋接和 IP 轉發

自從 Linux 核心 5.13 以來,您可以將橋接埠新增到 flowtable。 flowtable 基礎設施發現了橋接裝置背後的拓撲結構。 這允許 flowtable 在您的交換機/路由器中的橋接埠(在下面的示例圖中表示為 eth1 和 eth2)和閘道器裝置(表示為 eth0)之間定義一個快速通道繞過。

        fastpath bypass
 .-------------------------.
/                           \
|           IP forwarding   |
|          /             \ \/
|       br0               eth0 ..... eth0
.       / \                          *host B*
 -> eth1  eth2
     .           *switch/router*
     .
     .
   eth0
 *host A*

flowtable 基礎設施還支援橋接 VLAN 過濾操作,例如 PVID 和 untagged。 您還可以在橋接埠之上堆疊一個經典的 VLAN 裝置。

如果您希望您的 flowtable 在橋接埠和 IP 轉發路徑之間定義一個快速通道,您必須將您的橋接埠(由真實網路裝置表示)新增到您的 flowtable 定義中。

計數器

flowtable 可以透過在您的 flowtable 定義中指定計數器語句來與現有的連線跟蹤條目同步資料包和位元組計數器,例如

table inet x {
        flowtable f {
                hook ingress priority 0; devices = { eth0, eth1 };
                counter
        }
}

自從 Linux 核心 5.7 以來,計數器支援可用。

硬體解除安裝

如果您的網路裝置提供硬體解除安裝支援,您可以透過在您的 flowtable 定義中使用 “offload” 標誌來啟用它,例如

table inet x {
        flowtable f {
                hook ingress priority 0; devices = { eth0, eth1 };
                flags offload;
        }
}

有一個工作佇列將流新增到硬體。 請注意,在工作佇列有機會將流解除安裝到網路裝置之前,一些資料包可能仍然在 flowtable 軟體路徑上執行。

當列出您的連線跟蹤表時,您可以透過 [HW_OFFLOAD] 標籤來識別硬體解除安裝的流。 請注意,[OFFLOAD] 標籤是指軟體解除安裝模式,因此 [OFFLOAD](指軟體 flowtable 快速通道)和 [HW_OFFLOAD](指流正在使用的硬體解除安裝資料路徑)之間存在區別。

flowtable 硬體解除安裝基礎設施還支援 DSA(分散式交換機架構)。

限制

flowtable 的行為類似於快取。 如果用於傳輸的目標 MAC 地址或出口網路裝置發生更改,則 flowtable 條目可能會變得過時。

如果出現以下情況,這可能會成為一個問題:

  • 您在軟體模式下執行 flowtable,並且您在您的設定中組合了橋接和 IP 轉發。

  • 硬體解除安裝已啟用。

更多閱讀

本文件基於 LWN.net 文章 [1][2]。 Rafal Milecki 還編寫了一個非常完整和全面的摘要,稱為“網路加速狀態”,描述了該基礎設施被主線化之前的情況 [3],並且它還對這項工作做了一個粗略的總結 [4]