Virtio 上の pfSense:オフロードを切るまで TCP が停止する
仮想化した pfSense は ping には応答するものの、大きな TCP で停止します。NIC を交換するのではなく、virtio のチェックサムオフロード経路を切り、そのコストを測定してください。
あるクライアントの報告では、トンネルは接続し、ping も返り、ログインページも読み込まれるのに、その後の転送が毎回同じ地点で固まるといいます。このパターンだけで、到達性は働いていて持続的なスループットは働いていないと分かります。ファイアウォールを開く前に、VPN がそもそもこの障害に関与しているかを確かめてください。経路にトンネルを置かず同じゲートウェイで大きな TCP を流し、それも固まるなら OpenVPN は最初から無関係です。
virtio の NIC を使う pfSense ゲストが、まさにその形で失敗する理由は十分にあります。
小さなパケットは通るが、大きな TCP は止まる
ハンドシェイク、DNS 応答、ICMP エコーは小さく、たいていは通ります。持続的な転送はゲストにセグメント化を強制し、壊れたオフロード経路はそこで表面化します。障害は対称である必要はなく、送信が健全でも受信が落ちる、あるいはその逆になるため、ログインはできても最初の大きな応答で止まることがあります。同じクライアントが別のゲートウェイでは動くため、責任は最新の構成要素に押し付けられます。
そこで、トンネルなしでゲートウェイを試します。数秒間続く程度の LAN から WAN へのダウンロードで十分で、後から比べても意味があるように、設定を変える前に済ませる必要があります。
オフロードが実際に約束するもの
virtio は準仮想化で、ホストとゲストが作業を分担し、ホストはチェックサムとセグメント化の機能を通知し、ゲストが始めたことを終えることを期待します。ゲストのスタックがそうしなければ、フレームは不完全なチェックサムのまま出ていくか、ホストに破棄されます。エミュレートされた E1000 はより単純で遅いモデルを提供し、それなら pfSense を一行も変えずに問題は消えます。機能の折衝はデバイスごとに行われるため、あるゲストは何か月も動き、作り直した双子は初日に失敗するのです。
折衝された組み合わせは、取り込んだ設定だけでなく、ハイパーバイザーの版と選んだ NIC のモデルにも依存します。
チェックボックス一つで virtio を保てる
pfSense の画面では、システム、次に詳細設定、次にネットワークの中に「ハードウェアチェックサムオフロードを無効化」というチェックボックスがあります。これを入れるとゲストはチェックサムをソフトウェアで計算し、pfSense の背後にある FreeBSD スタックが準仮想デバイスに期待する内容と一致します。同じページの関連する二つの項目が、ハードウェア TCP セグメンテーションオフロードとハードウェアのラージレシーブオフロードを扱います。ハンドシェイクは通るのに大きな転送が通らないときは、これらに手を伸ばしてください。
変更する間も NIC は virtio のままにしてください。E1000 に変えると VM の寿命のあいだ毎パケットで CPU を焼き、ホストを引き継ぐ誰からも設定の問題が見えなくなるため、これは少し遅いが予測できるデータ経路より悪い取引です。
受け入れたコストを測る
ソフトウェアのチェックサム計算は作業をゲストへ移すので、無料だと決めつけず、後でスループットを測ります。小さな VM では代償は現実にありますが、静かな取りこぼしと違って見えていて安定しています。変更の前後でインターフェースのエラーカウンタとゲストのカーネルログを比べます。ブリッジを絞り込むハイパーバイザーは別の証拠を持つ別の障害で、どのオフロードフラグでも治りません。
試験ごとに一つだけ変え、メニューの経路、入れたチェックボックス、測った数値を書き留めます。次に作り直したゲストに向き合う人は、三つとも欲しがるでしょう。
BSD 系の他のファイアウォールも独自のインターフェース設定に同等の制御を備えているので、メニューの経路が違っても理屈は通用します。