IPv6トンネルの一端がもう一端にpingを送っても、返ってくるのは常に片方向だけです。インターフェースは起動しており、ルートも正しく見え、ログにも説明はありません。割り当てたアドレスはサブネットルーターanycastアドレスで、ホストアドレスではまったくありません。両端のリンクでは配送先はただ一つ、送信者自身です。タイムアウト値をいくら変えても直りません。アドレスが、あなたが思っている動作をしていないからです。

アドレスを指し示す症状

リンク上のホストはすべて応答しますが、インターフェース識別子が全ゼロのホストだけは応答しません。その形式宛てのパケットは定義上サブネット内のルーターに配送されるため、ポイントツーポイントトンネルでは送信した機械自身に戻ってきます。遠端からは到達不能なピアに見え、近端からは沈黙に見えます。同じプレフィックスの別の識別子に差し替えると、他に何も変えずに症状は消えます。これがルートに触る前に取るべき確認です。

全ゼロの識別子はanycastとして予約されている

RFC 4291は全ゼロのインターフェース識別子をサブネットルーターanycastアドレスとして保持しているため、/64の例である 2001:db8:4a::/64 には利用可能なホストが存在しません。 2001:db8:4a::この予約には意味があります。ルーター広告と近隣探索はこの形式を宛先にし、ルーターは自身が提供するプレフィックスに応答します。その値をトンネル端点に割り当てることは、リーフにルーターの役割を与えることであり、だから何も返ってきません。プレフィックス内の他の識別子はホストとして機能するので、修正は通常一桁で済みます。

この予約は、トンネル端点から名乗る権利のない役割として扱うべきで、ルートで回避すべき奇癖ではありません。

ホストアドレスを割り当て、プレフィックスをルーティングする

両端には ::1 と ::2 を選び、片方を ip -6 addr add 2001:db8:4a::2/64 dev tun0で追加したうえで、遠端のプレフィックスにはアドレスを与えようとするのではなく、ルーティングします。 2001:db8:4a::/64 のルートをトンネル経由にすると遠端に到達できるようになりますが、アドレスだけではローカルインターフェースが設定されるだけです。

フルトンネルには第三の手順があり、デバイス経由のグローバルunicast向けデフォルトルートを入れます。これはすべてをトンネルに送るIPv6版です。これを省くと、IPv4がトンネル内を通る間もIPv6は物理リンクを使い続けるため、ホストは覆われていると思っていた通信をまさに漏らします。次のコマンドで確認してください: ip -6 route get 2001:4860:4860::8888 。そして、答えを決めつけずにどのデバイスを挙げているかを読み取ります。

multicastはルーティングの前に拒否される

Androidは VpnService.Builder のアドレスとルートを LinkAddress経由で検証し、そのコンストラクターはmulticastを真っ向から拒否します。multicastプレフィックスをルートとして渡すと、結果はルートではなく不正なLinkAddressパラメーターの失敗になります。これはネットワークではなく検証の答えです。この拒否は媒体と一致します。ポイントツーポイントのtunデバイスにはリンク層のmulticastがなく、その上のグループルートにはインストールできる配送モデルがありません。グループアドレスは手作業で設定するのではなく、スタック自身が作成して消費します。

IPv6のall-nodesアドレスとsolicited-nodeアドレスも同じ規則の下にあります。インターフェースがそれらを運ぶのは、スタックがそこに置いたからであり、ポリシーが意図したからではありません。

トンネルが代わりに運べるもの

トンネルをまたぐmulticastディスカバリ を移すには、グループメンバーシップを理解する層が必要です。Ethernetセグメントを提示するTAPブリッジ、アプリケーションレベルのリレー、あるいはどのピアに複製するかを明示的に指定されたルーティングプロトコルです。VpnServiceモデルにはそのどれも存在せず、アプリケーションはパケットを読み書きするだけで、トンネルのためにグループへ参加する呼び出しはありません。グループを理解するコンポーネントを追加するか、設計からその要件を外してください。

対照的にunicastは、上記のアドレスとルート以外に何も必要としません。だからこそトンネルは通常それを運ぶものと期待され、ディスカバリプロトコルが失敗すると非難されるのです。

何かを割り当てる前の三つの確認

アドレスがanycastの形式でないこと、multicastでないこと、プレフィックスがデバイスに割り当てられただけでなくルーティングされていることを確認してください。そのうえでテストを実際のホストである宛先に送ります。anycastアドレスに向けたpingは送信者を測るだけで、経路については何も教えてくれないからです。この三つの確認を変更記録に残し、次の配備で再発見しないようにしてください。

プラットフォームが一度もインストールしなかったルートは、待ち時間を延ばしてもデバッグできません。ホストであったことのないアドレスは、より良いpingでは修復できません。

関連記事