経路変更要求

以降の通信を他のルータ宛てに向け直すこと

 ICMP にはルーティングに関連したデバイスに情報を教えるために使われる指示と応答がいろいろあります。 よく見かけるのは、PING によって使用される ICMP Echo 要求と Echo 応答で、遠隔地のステーションが存在しているかどうかを確かめることができます。 ICMP によってステーションのアドレスマスクを得ることもできるますし、目的地に到達できないということを送信元に知らせることもできます。

 ここでは経路変更要求という ICMP について説明します。これは、送信者に対し、自分の送信したフレームの IP アドレスが正しくないことを知らせたり、 今後どこへ送ったらよいのかを知らせたりするために使われるものです。

 一つのイーサネットセグメントやトークンリング上にたくさんのエンドノードが存在し、それらがたった一つのルータにアクセスするような場合を考えてみましょう。 すべてのステーションのデフォルトゲートウェイに、そのルータの IP アドレスが設定されています。 遠隔地宛のフレームは、どれも利用可能なたった一つのルータであるそのルータに送られ、ルータが最終目的地のネットワークに向かってフレームを転送します。

 この簡単なネットワークが拡張され、そのネットワークにルータが2台になると、あるエンドノードにとっては異なる状況が発生します。 255.255.0.0 でマスクされた 160.6.0.0というネットワークを考えてみましょう。 エンドノード 160.6.0.2 が 160.6.0.3 にフレームを送る場合、ARP がブロードキャストされ、フレームは直接送られます。 160.6.0.2 が 165.1.0.3 にフレームを送る場合は、まず経路があるかどうかを見るためにルーティングテーブルを探します。 この例では、160.6.0.2 は動作し始めたばかりで、ルーティングテーブル内にデフォルトゲートウェイ以外のエントリはありません。 デフォルトゲートウェイは 160.6.0.1 で、同じセグメント内にあります。そこでこのエンドノードはデフォルトゲートウェイのデータリンクアドレスを知るために ARP を送信し、 フレームを宛先データリンク(デフォルトゲートウェイ)に転送します。 デフォルトゲートウェイに加え、今やこのセグメントには、二番目のルータが存在します。 このエンドノードがデフォルトゲートウェイではないルータを経由してしかフレームを宛先に送ることができないとしましょう。 こちらのルータを 160.6.0.201 とします。

 このエンドノードは 160.6.0.201 のルータを経由してでなければ届かない 170.1.2.3 という宛先にフレームを送りたいのです。 このルータは同じセグメントにあるがデフォルトゲートウェイではありません。エンドノードは前と全く同じやり方で動作します。 フレームがデフォルトゲートウェイ( 160.6.0.1 )に送られます。 今度は、デフォルトゲートウェイは、もう一つのルータ( 160.6.0.201 )がそのフレームを転送するのにふさわしいルータであることに気が付きました。 すると次の二つのことが起こります。(1)デフォルトゲートウェイは ICMP 経路変更要求メッセージを発信元エンドノードに送り、160.6.0.201 に直接送るように言います。 (2)デフォルトゲートウェイはもとのフレームを 160.6.0.201 に送り、エンドノードが再送しなくてすむようにします。

 この動作を要約しましょう。デフォルトゲートウェイが自分が持っているのとは別の IP アドレスへ送るべきフレームを受取ったら、 デフォルトゲートウェイは ICMP 経路変更要求メッセージ使って発信元に通知します。この場合は、経路変更要求によって、 ネットワーク 170.1.0.0 にフレームを送るときは、ルータ 160.6.0.201 に送らなければならないと、160.6.0.2 に告げます。 エンドノードは通常通り ARP を出して、160.6.0.201 のデータリンクアドレスを決めますが、それ以降は 170.1.0.0 へのフレームは、 デフォルトゲートウェイではなく、もう一つのルータへ送ることになります。

 ARP キャッシュとルーティングテーブルの内容から考えれば、ICMP 経路変更要求の効果は次のようになします。 最初ルーティングテーブルには、デフォルトゲートウェイのアドレスしかありませんでした。160.6.0.1 がデフォルトゲートウェイのアドレスです。 ルーティングテーブルは 0.0.0.0(これはデフォルトゲートウェイを示す)= 160.6.0.1 となっています。 ARP キャッシュは最初は空でした。

 ステーションは、起動されるとデフォルトゲートウェイのデータリンクアドレスを 得るために ARP を行います。 ARP 応答によってデータリンクアドレスを得ます。これを MAC#1 としましょう。MAC アドレスはネットワークインターフェイスカードの物理アドレスとも、ハードウェアアドレスとも呼ばれます。

 このステーションは「 170.1.0.0 に送るためには 160.6.0.201 というルータへ送れ」という経路変更要求を受け、 ルーティングテーブルの内容が以下のように更新されます。

0.0.0.0=160.6.0.1
170.1.0.0=160.6.0.201

 次回にフレームをネットワーク 170.1.0.0 へ送る場合、ルーティングテーブルは宛先への正しい「隣りルータ」である 160.6.0.201 を返します。 しかしステーションは、160.6.0.201 のデータリンクアドレスを知るまで、この「隣りルータ」へはフレームを送ることができません。 160.6.0.201 のデータリンクアドレスを知るため ARP を行い、ARP キャッシュに以下の内容が含まれるようになります。

160.6.0.1=MAC#1
160.6.0.201=MAC#201

 こういう動作が、ネットワークに影響を与えるほど続きます。古くなった ARP キャッシュの内容は数秒経ったら消えますが、 ルーティングテーブルの内容は 20 分経たないと消えないか、または、その経路は使われないまま残ってしまいます。


同一セグメント上の複数サブネット


 残りの部分を読めば、同一セグメント上で複数サブネットを使うことを定義した新しい RFC が 1995 年に確立したことに気が付くでしょう。 それらには、ここで説明するよりもより適切であると考えられているデバイスの動作が定義されています。 そこでここでは「今までの方法」という項目の中でこの問題について考えることにします。 そして「今日の方法」という項目で、新しい RFC について考えます。


今までの方法


 理想的な世界では、ルータ上の一つのポートには、同じアドレスマスク設定のステーションしか存在しないネットワークに接続されていることになっています。 つまりすべてのステーションが同じネットワークまたはサブネット(位置決め部分のアドレスがすべてのステーションで同一の設定となっているということです)に属することを意味しています。 このようにしておくと、ルータの動作は容易になります。ポート毎に一つのネットワークまたはサブネット。ステーションはすべて同じ設定。

 しかし、実際は理想世界ではありません。セグメント上のステーションに異なるネットワーク/サブネットを設定することは可能です(たぶん?)。 ここではセグメントとは、単一のイーサネットセグメントやトークンリングだけではなく、 リピータやブリッジやスイッチなどで相互接続された物理的なセグメントまたはリングのグループを指しています。 大雑把に、ランダムに設定されたネットワークや、ランダム設定とほぼ同じネットワークといったものについて思い浮かべてください。 どちらか一方で、ルータが 12 個のポートを持ち、それぞれのポートに別のサブネットが設定されている状態を考えてみましょう。 このルータがスイッチに交換されました。ポート1に接続されているセグメント上のステーションが、ポート5に接続されているセグメントのステーションと通信をしたい場合、 ステーションは宛先アドレスが同一セグメント上にはないことを理解します( IP アドレスとマスクがルータに接続されているときとは変わっていないとします)。 送信ステーションは新しいデフォルトゲートウェイ(ここではポート2のセグメントに接続されているとします)のデータリンクアドレスを指定します。 デフォルトゲートウェイは送信ステーションに対して、宛先へは直接送信できるということを知らせるために「経路変更要求」と使います。 160.6.0.2 が、170.1.2.3 と通信したい場合の、更新後のルーティングテーブルを見てみましょう。

0.0.0.0=160.6.0.1
170.1.2.3=170.1.2.3

 何かおかしなところがあるでしょうか? 「経路変更要求」メッセージは、170.1.2.3 宛てのフレームは、170.1.2.3 に「経路変更」すべきだと告げました。 これは同じ IP アドレスです。次のフレームが 170.1.2.3 へ送られるときのステーションの動作を見てみましょう。

 160.6.0.2 は未だに宛先を遠隔地にあると認識しています。 ルーティングテーブルに、170.1.2.3(ホスト直接の経路)や 170.1.0.0(ネットワーク経由の経路)があるかどうか調べなければならないからです。 今度は宛先が見つかります(そしてホスト直接の経路であると理解します)。 160.6.0.2 はルーティングテーブルの内容から、170.1.2.3 向きのフレームは IP アドレス 170.1.2.3 へ送るべきであり、 アドレス 170.1.2.3 のデータリンクアドレスを知るために ARP を使わなければならないと思います。 170.1.2.3 が本当に直接送ることができるところにあれば(スイッチ経由で)、ARP に応え、アドレス MAC#123(170.1.2.3 のデータリンクアドレスとします)が ARP キャッシュに加えられます。そしてフレームは宛先マシンへ直接転送されることになります。

 送信ステーションが自分で気づけば、フレームをルータのデータリンクアドレスへ転送するべきだったと考えるでしょう。 データリンクの宛先へは実際、直接届くので、「経路変更要求」は直接送るように「騙す」のですが、 その宛先は、本当は異なるサブネットの宛先であると設定されています(しかし物理的には同じ場所に存在します)。 複数のサブネットが、論理的に同一のセグメント上に設定されていることになります。 このような場合、ICMP 経路変更要求は、送信ステーションを「騙し」て、本当の宛先データリンクを使わせるようにします。


今日の方法


 「今までの方法」の項目では、RFC 1122 と RFC 1812 に背く例を説明しました。

 RFC 1812 の 3.2.2.2 にはこう書かれています。

 指定された新しいゲートウェイアドレスが、経路変更要求が送られて来た(サブ)ネットワークと同じところに接続されていない場合(紹介2、付録Aに記述されています)、 あるいは、経路変更要求メッセージの発信元が、指定された宛先から見て、最初のルータでない場合( 3.3.1 に記述されています)、 経路変更要求メッセージには反応するべきではありません。

 これは、ホストが「今までの方法」に書かれた経路変更要求を無視しなければならないことを意味しています。

 RFC 1812 の 5.2.7.2 には次のようにあります。

 ルータは以下のすべての状態を満たすまで、経路変更要求メッセージを生成してはなりません。

パケットが受信したのと同じ物理インターフェイスへ転送され、
パケットの発信元 IP アドレスが、最も近いルータの IP アドレスと同じ論理 IP アドレスであり、かつ
パケットが IP の始点で経路を指定しないとき。

 ICMP 経路変更要求で使われる発信元アドレスは、宛先アドレスと同じ論理(サブ)ネットワークに属していなければなりません。 これは、ルータが「今までの方法」の項目に書かれたような経路変更要求メッセージを生成してはならないことを意味しています。


経路変更要求が実装されていない低機能 IP


 すべての IP 実装が−特に低速のデバイスでは− すべての ICMP 機能を持っているわけではありません。 IP で通信を行うものは、ICMP Echo と Echo 応答( PING コマンドのことです)を持っているとされていますが、経路変更要求の機能はそうではありません。 このような場合、代わりのルータや異なるサブネットにあると設定されたローカル上の宛先への経路変更要求は、実行されないでしょう。 発信元ステーションは、同じルータにフレームを送り続けることでしょう。ルータの方は経路変更要求を送信元に送り、元のフレームの方を宛先に転送しつづけるでしょう。 やり取りは成り立ちますが、経路変更要求だけでなく、元のフレームのコピー(一つは発信者からルータへ、もう一つはルータから宛先へ)が余分なトラフィックとして発生することになります。 トラフィックの負荷は必要以上になり、負荷のせいで、伝播遅延のせいで、パフォーマンスが下がることでしょう。

 このような IP 実装の不足を補うため、ステーションに送る経路変更要求の数を設定するパラメータを設けているルータベンダもあります。 たとえば、シスコのルータでは最大 15 フレームで経路変更要求を止めることにしています。 ルータは入ってくるフレームを正しい宛先に転送しますが、こうすれば少なくとも不必要で、無視されてしまう ICMP フレームは振るい落とされます。 このようなルータのオプションは問題を解決するわけではありませんが(ワークステーションの方が経路変更要求を持っていないので)、 少なくとも悪いステーションがさらに悪くなるのを防ぐことはできます(顧みられない ICMP 経路変更要求がなくなることになるからです)。

 問題を本当に解決するためには(根本的解決は、経路変更要求を持つことですが)、ワークステーションやルータに代理 ARP を持たせることです。 デフォルトでは、ほとんどのルータは代理 ARP を動作させています。ワークステーションは動作させていないかもしれません。 代理 ARP を使えば、ICMP の問題をまるごと回避することができます。すべてのステーションがすべての宛先に対して ARP を行うからです。


アドレスマスクに関する問題


 ステーションに間違ったアドレスマスクが設定されていたら、宛先が離れたところにあるのか同じところにあるのかがわからなくなるという混乱が生じます。 マスクの間違っているステーションは正しい宛先を作り出すことができないので、宛先のネットワークが正しく判断されません。 離れたところにある宛先が、同じところにあると判断されると、発信元の送った ARP は失敗します。 同じところにある宛先が離れたところにあると判断されたら、送信元はデフォルトゲートウェイに転送をし、そのため経路変更要求が発生し、ルーティングテーブルが書き換えられます。 このような不適切な動作はプロトコルアナライザを使うことによって見ることができます。

 ルータで代理 ARP が動作していると、ワークステーション上の間違ったアドレスマスクが隠されます。 離れたところにある宛先が、本当に同じところにあると考えたステーションは、離れた宛先に対して間違った ARP を行います。 ルータは ARP(代理応答)に応えるます。

 代理 ARP について言えば、ネットワーク上にあるたくさんの間違ったアドレスマスクを隠すことができます。 ルータの代理機能に付随してくる誤設定を受け入れるという限りにおいて、これに問題はありません。 ネットワークを再設定するとき(明日にも起こるかもしれません?)には、問題が噴出することになるでしょう。 ルータの代理機能によって隠された一貫性のないマスクというものは、都合の悪いときにこそ化けて出てくるものです。 (明日から3日間休み!という金曜日の5時5分前なんかに!)

 実験的に代理 ARP の機能を外してみましょう。次のような場合には行っては行けません。 (1)デフォルトゲートウェイを呼び出さない設定になっているとき、またはワークステーション上で代理 ARP を動作させているとき。 (2)ネットワーク上で重要なアプリケーションを動かしているとき。 注意深く行いましょう。代理 ARP を止めると、予測できない問題が起こるかもしれません。 ネットワークが代理 ARP を使わないように設定されているのなら、機能を止めても適切に動作するはずです。 実験的にどんな問題が起こるか見てみましょう。そして、大きな問題が起こる前、制御可能な状態のときに、問題を解決しましょう。