四つの確認が、機能するマーク規則と機能する経路を分ける。規則が読むのはどのマークか、検索の時点でパケットがまだそれを運んでいるか、後続のパケットに接続マークが復元されたか、そして対応する規則のマスクと優先度が発火を許しているかどうか。増えていくカウンタが証明するのは、何らかの規則が何かに一致したことだけである。カーネルが経路を選んだときパケットが何を運んでいたかについては何も語らない。

二つのマークは別の場所に住み、別の予定で失効する。

二つのマーク、二つの寿命

パケットマークは一つの skb に属し、その skb とともにフックを通り、ポリシールーティングの fwmark セレクタによって消費される。接続マークは conntrack エントリに属し、そのフローのパケットを通じて残り、何かが書き戻すまでルーティング規則からは見えない。パケットマークを接続に保存するのは保管であり、復元は別の操作である。どちらも暗黙には起きない。

だからこそ、ルールセットは整合して見えるのにルーティング判断はゼロを見る。値は保存され、何もそれを復元しなかったのである。

両者の間のコピーは、自分で書く手順である

重要な二つの文は逆向きに走る。一方はパケットのマークを接続に保存し、他方は接続のマークをパケットに読み込む。どちらが必要かは、フローに対して分類がいつ行われるかで決まる。設計によってはパケットマークだけで足りるし、回避策が両方を使ったからという理由で conntrack のマーキングを足すのは、単純なポリシーが二つ目の故障モードを手に入れる道である。

ct mark set meta mark
meta mark set ct mark

規則の隣に方向を書き留めておくこと。一見したところ構文からは明らかではない。一行目は保存し、二行目は復元し、どちらも他方を含意しない。

それを消費する検索より前に分類する

ローカルで生成されたトラフィックと LAN から転送されたトラフィックは異なるフックを通り、異なる時点でルーティング判断に到達する。ルーター自身の接続で機能する出力規則は、転送されたクライアントのパケットがその検索より前にマークされたことを証明しない。分類は、それを消費する検索がまだ起きていない場所に置き、同じチェーン内の後続の規則が値を上書きしないか確認する。チェーン内の順序は設定の一部であり、実装の詳細ではない。

接続状態の永続化にも明示的な計画が要る。フローの最初のパケットだけが分類されるなら、後続のパケットには保存されたマークの復元が必要で、さもなければマークのない経路をたどる。これが、接続を表すマークとパケットを表すマークの違いである。

経路にマーク付きの問いを立てる

ip route get 10.77.0.10 mark 0x2

規則とテーブルを調べ、次にマークを含めて経路に問い合わせる。ポリシーに影響するなら送信元や受信インターフェースも加える。マークなしの普通の検索は別の問いに答えるので、望まない経路を喜んで報告する。規則の値だけでなくマスクと優先度も確認し、選ばれたテーブルに使える経路があることを確かめる。

増えていくカウンタは、何らかの規則が何らかのパケットに一致した証拠である。最終的なパケットが正しい判断点で意図したマークを運んでいた証拠ではない。

マーク、方向、タイミング、マスクを読む。四つの確認で、経路は謎ではなくなる。

関連記事