はじめに
「合言葉を」異口同音にささやく。「デンマーク」
アルトゥル・シュニッツラー
「夢奇譚」
平穏と思える日常生活にも、思わぬところに「闇」が潜んでいるものです。アメリカの最古の秘密結社の1つ、トライステロをご存じでしょうか。トライステロは裏社会の地下郵便組織で、その流通ネットワークはなんと全米に広がっています。恐ろしいことに、トライステロは重要な社会インフラの1つである郵便事業を通じて、あらゆる歴史的事件に社会の裏側から関与し続けていると言われています。
ところで、アメリカの街中で図1のような小さなラッパの落書きに気づいたことはありませんか? これはトライステロのマークで、メンバーどうしが秘密裡に連絡を取り合うのに使うと言われています。このマークがある場所にはアジトがある可能性が高く危険なため、賢明な読者のみなさまはどうか近づかないでください[1]。
この連載で紹介しているTremaも、その実体はトレマと呼ばれる秘密結社によって作られたフリーソフトウェアです。トレマは闇プログラマや闇エンジニアを抱える地下組織であり、OpenFlowフレームワークTremaを通じてネットワーク界の大変革をもくろんでいます。
トライステロと同じく、トレマも図2のような秘密のマークを使って連絡を取り合っています。ぱっと見、どこにでもある道路標識のようにカムフラージュされているところに注目してください。まさに、思わぬ日常に闇は潜んでいるのです。
今回は、我々「トレマ探検隊」が知られざる秘密結社トレマの秘密に迫ります。謎のソフトウェアTremaの全貌は? 闇組織トレマに入るには?実に丸1年の歳月を費やし、命がけで調査した結果をここに公開します。もちろん、世界初公開です!
調査報告:Tremaの全貌
いきなりTremaのソースコードに飛び込むのもよいですが、すぐに迷ってしまうのが関の山です。我々トレマ探検隊が道案内をしましょう。まずは、大まかなファイル構成をつかんでおくとソースコード探検に便利です。
ファイル構成
Tremaをダウンロードすると、いくつかのファイルとディレクトリがあることがわかります。次に主要なものを挙げましょう。
- build.rb:ビルドスクリプト
- cruise.rb:すべてのテストコードを実行するテストスイート。開発者向け
- features/:受け入れテスト一式。開発者向け
- ruby/:Rubyライブラリのソースコード
- spec/:Rubyのユニットテスト一式。開発者向け
- src/examples/:サンプルアプリ(後述)
- src/lib/:Cライブラリのソースコード
- trema:tremaコマンド本体
- unittests/:Cのユニットテスト一式。開発者向け
この中でもTremaで何か作りたい人が真っ先に読むべきは、サンプルアプリ(src/examples/)です。
サンプルアプリ
サンプルアプリは簡単なアプリケーションをたくさん含んでおり、実際のAPIの使い方を調べるのに便利です。基本的にはCとRubyの両方で書かれているため、両者のAPI対応を調べるのにも使えます。
表1におもなサンプルアプリをまとめておきます。この表では、簡単な順に上から並べていますので、順に読んでいくことをお勧めします。
TremaにはたくさんのAPIがあり、表1に掲載したサンプルではまだまだすべてを紹介しきれていません。新しいサンプルアプリを作成した人は、ぜひGitHubでPullリクエストを送ってください。あなたの名前が作者リスト(README.md)に載るかもしれません!
表1 Tremaのおもなサンプルアプリ
アプリ | 説明 |
hello_trema | すべての基本、Helloと表示するだけのサンプル(連載第7回に掲載)。これをtrema runに渡せば、手っ取り早くTremaを試すことができる。Tremaを始めたばかりの初心者向け |
packet_in | OpenFlowメッセージの中でも重要なpacket_inメッセージをハンドルするサンプル。ハンドラの定義方法やpacket_inメッセージの基本が学べる |
switch_monitor | スイッチの起動、切断を捕捉するサンプル(連載第7回に掲載)。ハンドラを複数使ったコントローラの実装が学べる |
dumper | 受け取ったすべてのOpenFlowメッセージを文字列としてダンプするサンプル。OpenFlowメッセージのハンドル方法が学べる |
switch_info | features_requestメッセージをスイッチに送信し、スイッチから受信したスイッチ情報を出力するサンプル。コントローラからスイッチへOpenFlowメッセージを送る方法が学べる |
repeater_hub | 受け取ったパケットを、入ってきたポート以外に出力する、いわゆるリピータハブをOpenFlowで実装したサンプル(連載第9回に掲載)。重要なメッセージであるflow_modとpacket_outの基本が学べる |
learning_switch | いわゆるL2スイッチをエミュレートするサンプル。普通のスイッチの基本構成(FDBなど)を学ぶことができる。これは1台のOpenFlowスイッチのみで動作するが、複数スイッチ向けにはmulti_learning_switchを参照すること |
traffic_monitor | learning_switchを拡張し、ユーザごとのトラフィックを測れるようにしたサンプル(連載第8回に掲載)。スイッチのフローが消えたときに送信されるflow_removed メッセージの応用例としておもしろい |
multi_learning_switch | learning_switchの複数スイッチ対応版。learning_switchとの違い、とくにスイッチごとにFDBを管理している部分に注目 |
Trema Apps
Trema Appsは、Tremaを使った実用的/実験的なアプリケーションを集めたリポジトリです。Tremaと同様にGitHub上で公開されており、次の手順で取得できます。
それでは、Trema Appsの中でもとくに実用的なアプリを中心に解説していきましょう。
Routing Switch
Routing Switchは、複数のOpenFlowスイッチで構成されるネットワークを1つのL2スイッチに仮想化します(図3)。サンプルプログラムのlearning_switchと異なり、ループのあるネットワークトポロジにも対応しています。
また、multi_learning_switchとは異なり、routing_switchはパケットの送信元と宛先のホストが異なるスイッチに接続している場合にも対応しています。スイッチにパケットが届くと図3に示すように、パケットを受信したスイッチから宛先ホストに送出するスイッチまでの最短パスを計算します。そして、計算されたパス上の各スイッチに「同一の特徴を持つパケットを、最短パス上の次のスイッチへと転送せよ」というfl ow_modメッセージを送ります。
Sliceable Routing Switch
Sliceable Routing Switchは、OpenFlowネットワーク全体をスライスに分割し、複数のL2スイッチに仮想化します。ちょうど、L2スイッチを複数のVLANに分けて使うイメージです。
スライスを2つ設定した例を図4に示します。同一のスライスに接続されたホストどうしはパケットをやりとりできますが、異なるスライスに接続されたホストどうしではできません。このようにうまくスライスを設定することで、アプリケーションやグループ別など用途に応じて独立したネットワークを作ることができます。
Topology
Topologyは、複数のOpenFlowスイッチ間の接続関係(ネットワークトポロジ)を取得するためのユーティリティ的なアプリケーションです。前述のRouting SwitchやSliceable RoutingSwitchで最短パスを決める際に利用されます。
ネットワークトポロジの検出には、OpenFlowで標準的なLink Layer Discovery Protocol(LLDP)(注2)を用います(図5)。Topologyからpacket_outにより送信されたLLDPパケットは、LLDPが到達した隣のスイッチからpacket_inでTopologyへと戻ります。LLDPパケット中には、それが経由したスイッチとポート情報などが含まれています。そのため、これを繰り返すことでネットワーク中のすべてのスイッチ間の接続関係を知ることができます。
Redirectable Routing Switch
Routing Switchのもう1つの亜種で、ユーザ認証とパケットのリダイレクト機能を付け加えたものです。認証されていないホストのパケットは、ほかのサーバに強制的にリダイレクトされます。このしくみを使えば、たとえば認証していないユーザのHTTPセッションを強制的にあるサイトへ飛ばすといったことが簡単にできます。
Learning switch with memcached
サンプルプログラムのlearning_switchと同じ機能を持ちますが、FDB部分にmemcached[3]を用いています。Rubyのmemcachedライブラリを使うことで、オリジナルのlearning_switchにほとんど変更を加えずにmemcached対応しています。
Multi learning switch with memcached
サンプルプログラムのmulti_learning_switchをmemcached対応したものです。
Flow dumper
OpenFlowスイッチのフローテーブルを取得するためのユーティリティです。デバッグツールとしてとても便利です。
Packetin dispatcher
packet_in メッセージを複数のTrema アプリケーションに振り分けるためのサンプルです。物理アドレスから、ユニキャストかブロードキャストかを判断します。
Broadcast helper
ブロードキャストやマルチキャストなど、コントローラに負荷の大きいトラフィックを分けるためのアプリです。
Flow manager
フローエントリとパス情報を管理するアプリケーションおよびAPIを提供します。実験的な実装なので、APIは変更される可能性があります。
実録・秘密結社トレマに潜入!
検索エンジンの海をさまよった結果、ついに我々はトレマとの接触に成功した。指定された場所は関東某所。こんな場所でソフトウェアの開発を? というほど意外な場所にトレマ本部はあった。
Tremaメンバーと接触
我々を案内してくれたのは、キーボードで顔を隠した謎の男。我々をTremaプロジェクトの闇プログラマや闇エンジニアたち(写真1)と引き合わせてくれると言う。
キーボード男「まずはみんなの紹介だ。本名は明かせないが、GitHubのアカウント名とTwitterのアカウント名を教えよう。」
- yasuhito(@yasuhito)
高性能計算(HPC)を専門とし、ネットワークのことは専門外。世界中どこでも便所サンダルで現れる。Tremaの設計や実装方針を割と勝手に決めてしまう自称リーダー。
- sugyo
別の秘密結社K○M△プロジェクトから参加。IPv6のプロトコルスタックの開発に長年従事してきたネットワーク界のスーパーハッカー。Tremaの各種デーモンを担当。
- kazuyas(@countone)
自称インターネット屋、ルータ屋さん。L2よりL3、とくに経路制御が大好きで、OpenFlowはL3っぽくないなどとボヤきつつTremaのパケットパーサー部分を書いた。
- chibacchie
経験豊富なネットワークエンジニア兼プログラマ。TremaのOpenFlowプロトコルスタックやデバッグツールTremashark、および数多くのTremaアプリを開発している。
- eff(@effy55)
ギークハウス武蔵小杉管理人。Tremaプロセス間のメッセージング機構を開発。現在はTremaで何やら小難しいものを作ろうとしているらしいが、その全容は誰も知らない。
Tremaの掟
キーボード男「TremaはGPL2だし、GitHubに置いてあるから、OpenFlowプログラミングに興味があれば誰でも参加できるんだ。でも、そのためにはちょっとした掟があるんだ。それを紹介しよう。」
使いたいものしか作らない
キーボード男「俺たちは自分たちの使いたいものしか作らないんだ。『必要だから作った』ってのが一番品質が良いからね。だから、使ってもない人間の『ここはこうしたほうがよい』『こんなのダメ』という意見はきっぱり無視するんだ。」
シンプルに保つ
キーボード男「全部入りの重量級ソフトウェアはみっともないし、使いにくいもんだ。『お客さんに言われたんで、さっそくこういう機能を付けてみました!』とかアホだろ? 俺たちが目指しているのはバカでかい空母なんかじゃなくて、自由に乗り回せる自転車。たとえ『こういう機能ほしいかも?』と思っても、まずは却下しよう。それが本当に必要と確信できるまで実装しないことが大事だ。」
性能は二の次
キーボード男「さっきの話と似てるけど、必要のない高速化はしないことにしてるんだ。アルゴリズムも変に凝ったものは使わない。ポインタの小細工で米粒みたいな高速化をしてもバグるだけで無意味だよ。そんなことよりコードをいかにきれいに読みやすくできるか──コーディング規則の統一はもちろんだが、極端な話、行末の無駄なスペースにまで目を光らせてるよ。」
テスト中毒
キーボード男「よく言われることだけど、テストされていない機能は存在しないのと一緒だ。Trema にコミットしたい人は、まずはテストコードを書いてほしい。そしてテストコードをまた書いて、最後に実装だ。そう、テスト中毒みたいな奴に来てほしいんだ。」
なんか外タレのインタビューみたいですね。キーボード男さん、ありがとうございました。
まとめ
今回はいつもと趣向を変え、Tremaプロジェクトの深い部分を紹介しました。今回学んだことは次の2つです。
- Tremaでアプリケーションを書きたい人は、まずsrc/examples/以下のサンプルアプリを読みましょう。より高度なサンプルはTremaAppsリポジトリで発見できます。
- Tremaの開発に参加したい人は、「掟」を読んで設計思想を知ろう。簡単なサンプルアプリを書いてコミットしてみよう。そして、秘密結社トレマの一員になろう!
次回は、いよいよTremaを使って自宅や職場のネットワークをOpenFlowに置き換える方法を紹介します。我々の成功例や問題が起こったときの解決方法など、実践テクニックが満載です!