はじめに
Cisco社のExpress Forwarding技術(以下CEFと呼ぶ)は、インターネットや企業ネットワークなどといった大規模IPネットワークで将来必要となる高度なパフォーマンス要求にもミートするようにデザインされた、拡張性の高い分散型レイヤ3スイッチング・ソリューションです。
出典 URL:http://www.cisco.com/web/JP/product/hs/ios/cef_wp.html
これはCiscoのホームページから抜粋した文章ですが、この説明では何のことやらわかりにくいですね。
私はCiscoが作った技術の中でも一番エクセレントなものがCEFだと思っているのですが、市販されている書籍やWebの説明は技術的すぎてわかりにくく感じるので、今回は、このCEFについて補足してみたいと思います。
ルータは何をやっているのか?
まずルータがIPパケットを転送するときに何をしているか、考えて見ましょう。
最近のルータはQoSやセキュリティ機能などさまざまな仕事をしていますが、もっとも基本的な動作は「IPアドレスに従ってパケットを転送する」ということですよね。このときのステップを大雑把に並べると、以下のようになります。
到着したパケットから宛先IPアドレスを読む
ルーティングテーブルを検索し、ネクストホップのIPアドレスを知る
ネクストホップへ到達するためのレイヤ2アドレスを調べる
EthernetであればARPテーブルを参照して調べる。もしARPテーブルに載っていなければ、ARPパケットを飛ばして目的のMACアドレスを取得する。
パケットのL2ヘッダをネクストホップ宛てに書き換える
Ethernetであれば宛先と送信元のMACアドレスを書き換える、等。
ネクストホップ向けのインターフェースからパケットを出力する
IPパケットが到着するたびに、この動作を繰り返すわけです。
また、②の処理において、ネクストホップのIPアドレスは1回の検索で見つかるとは限りません。たとえば、以下のようにデフォルトルートを設定したとします。
ip route 0.0.0.0 0.0.0.0 192.168.20.1
show ip route
をすると、以下のようになりますね。
192.168.20.0/24 is subnetted, 1 subnets
C 192.168.20.0 is directly connected, Ethernet0
S* 0.0.0.0/0 [1/0] via 192.168.20.1
このルータは、宛先IPアドレスをルーティングテーブルで検索し、見つからないとデフォルトルートの宛先である192.168.20.1へ転送しようとします。
そこで、192.168.20.1へ送るにはどうすればよいのか? もう一度ルーティングテーブルを検索すると、Ethernet0のインターフェースに接続されていることがわかります。なので、次はARPテーブルを検索して、Ethernet0のインターフェースに接続されている192.168.20.1のMACアドレスを調べることになります。
つまり、1つのパケットを転送するために、ルーティングテーブルを2回とARPテーブルを1回の、計3回も検索をしなければいけないのです。
このように、ルーティングテーブルを2回以上サーチしなければ宛先が判断できない状況のことを「リカーシブル・ルックアップ」と呼ぶ場合があります。
リカーシブル・ルックアップの状況は複雑なスタティックルートやBGPを使用している場合などに顕著に発生し、ルータの性能を著しく悪化させる原因となります。ですから、どこのメーカでも、リカーシブル・ルックアップを減らして効率化するための工夫を、いろいろと行っているのです。
ファスト・スイッチング
まず、Cisco以外のルータで多く用いられている方法が「ファスト・スイッチング」です(メーカによってさまざまな呼び方をしていますが、Cisco以外のほとんどのルータやL3スイッチが、この方法を用いています) 。この方法は「キャッシング」を使います。
図1 ファスト・スイッチング
たとえば大容量のファイルを転送するような場合、Ethernetの最大フレーム長が1518バイトしかありませんので、たくさんのIPパケットに分割して情報を送る必要があります。
このとき、最初の1パケット目は普通にルーティングテーブルやARPテーブルを参照して処理しますが、その結果をキャッシュメモリに記憶しておいて、後続のパケットは、どうせ同じ相手に転送するのですから、キャッシュに蓄えられた情報を使いましょう、という方法です。
つまり、宛先が同じIPアドレスであれば、ルーティングテーブルを検索せずにキャッシュに残っている情報を使うことで、処理を効率化します。
CEF(セフ)
こちらはキャッシュとは逆の発想で、最初に高速検索用のテーブルを作ってしまう、という方法です。
(実際にはもっと複雑ですが)大まかには、ルーティングテーブルの情報に基づいて、Forwarding Information Base(FIB)というテーブル(実際にはツリー構造)を作ります。それから、( これも大まかですが)ARPテーブルなど主にレイヤ2の情報に基づいて、アジャセンシーテーブル(隣接テーブル)というものを作ります。
端的に言うと、ネイバールータ(隣接するルータ)へパケットを送るときに必要になるL2ヘッダ(MACフレーム)の情報が、全てアジャセンシーテーブルに入っています。
また、FIBテーブルの中に格納されている情報はIPアドレスやMACアドレスなどではなく、「 ポインタ」です。C言語を勉強されたことのある方ならピンと来ると思いますが、ポインタは別の情報が格納されたメモリの場所(アドレス)を示しています。FIBテーブルのポインタは、( これも厳密には例外がありますが)アジャセンシーテーブルのアドレスを指しているのです。
具体的な例を見てみましょう。
図2 CEFによるルーティング
図2の場合、ルータにNet.D宛てのパケットが到着しています(Net.Dは、Neighbor-3の先にあります) 。
すると、まずFIBテーブルが検索されます。FIBテーブルで「Net.D」を検索すると、ポインタ情報が格納されています。このポインタは、アジャセンシーテーブルのNeighbor-3に関する情報が格納されたメモリのアドレスを示しているのです。ですから、そのアドレスに格納された情報を取得すると、そこには、Neighbor-3へパケットを転送するときに必要になるレイヤ2の情報が全て入っているのです。
ルータはレイヤ2の情報を書き換えてパケットを出力すれば「一丁あがり」です。
同じように、Net.B宛てのパケットが到着した場合であれば、FIBテーブルを検索し、ポインターに示されたアドレスにジャンプして情報を取得すると、そこにはNeighbor-2へ送るためのレイヤ2情報が入っているのでパケットを書き換えて一丁あがり、という仕組みです。
つまり、デフォルトルートでも、BGPを使っていても、どんなに複雑なスタティックルートが設定されていても、CEFでは、パケット転送のために必要な情報を「必ず1回の検索で」全て見つけることができるようになっています。
CEFの威力を測る
ファスト・スイッチングでは、最初の1つ目のパケットはCPU処理になりますが、後続のパケットの宛先が同じIPアドレスであればキャッシュがヒットしますので、大量の情報を同じ宛先へ送る場合には効果的です。特に測定器を用いて性能測定する場合など、同じIPアドレスを宛先としたトラフィックのみで計測すれば、見かけ上の性能は高くなります。
しかし現実には、特に最近のWEB2.0と言われるようなテクノロジーでは、ファイル転送のように大きなデータを連続して送るのではなく、細かなデータを散発的に送受信する傾向があります。
このような状況ではCEFのメリットが出るはずなのですが、実際のところはどうなのでしょうか。そこで、ファスト・スイッチ方式のYAMAHA RTX1200と、CEFのCisco892Jで比較検証してみました。
まず、全てのパケットが同じ宛先IPアドレスの場合(1フロー)でスループットを計測すると、892Jが760Mbps、RTX1200が320Mbpsでした(※) 。
そこからフロー数(宛先アドレスの種類)を増やしていくと、RTX1200のみスループットが徐々に低下していきます。1万フローくらいまでは大きな低下ではありませんでしたが、6万フローを少し超えたあたりでキャッシュが完全にオーバーフローするらしく、全てのパケットがCPU処理になって大幅に性能が低下しました。
6万5000フローで測定すると、892Jは760Mbpsのままですが、RTX1200は4.2Mbpsであり、ピーク時の1.3%にまで低下したことになります。
図3 ファスト・スイッチングとCEFスループット比較
この結果をどう見るかはケースバイケースで変わってくるでしょうが、RTX1200でも1万フローくらいまでは大きな性能低下はなかったわけですから、一般のオフィス用途では問題ないと言えるでしょう。強いて言えば、IPアドレスを変えながらパケットを吐きまくるような、たちの悪いワーム型のウィルスが蔓延したりすると、ルーターのキャッシュがオーバーフローしてネットワークが使えなくなってしまう、というようなシナリオがあり得なくも無いかもしれません。
まあ、同じような値段で買えるなら、CEFのほうが「お買い得感」はあるのではないでしょうか。
なお、CEFはシスコの特許技術であり、他のメーカでは採用されていないようです。