オープンルータ・コンペティション
Interop 2012 の併催イベントとして、オープンルータ・コンペティションが開催されました。6/13 に最終審査会が開かれたので、見学してきました。
最終審査会では、一次審査を通過した10チームのプレゼンが行われました。
FPGA 付きの NIC を使ってワイヤーレートの L3 ルーティングを実現したチームまるたかが、グランプリ(さくらインターネット賞)を受賞しました。
また準グランプリ(NEC賞)には、このブログでも以前に紹介した@SRCHACKさんのプロジェクトが選ばれました。
最終審査会参加の10チームのうち、OpenFlow 関連の4チームすべてで Trema を使っていただいたようです。オープンソースのよいところですね。
OpenFlow 以外にも多くの素晴らしい成果の発表がありました。コンペティションの名前にもあるように、"オープン" な成果が、今後の新しいアイデアの礎になっていくといいな思います。
そんな願いも込めて、まとめサイトを作りました。公開されている情報をまとめていますので、ご参考に。
Openvswitch を userspace で動かす
今回は Openvswitch (ovs-vswitchd) を userspace で動作させる方法を試してみたので紹介します。
以前にも openvswitch の userspace での動作について紹介しましたが、その時用いていたのは ovs-openflowd でした。こちらの方は 1.4.0 にはすでに同梱されていないので、今回は ovs-vswitchd を使う方法を紹介します。
設定
基本的には、以前紹介した kernel-module を使う方法とほとんど同じです。違う点は以下の二点だけです。
今回は kernel-module を使用しないので、lsmod で確認し、openvswitch_mod をアンロードしておきます。
$ rmmod openvswitch_mod
あとは ovs-vsctl で以下のような設定を入れればいいだけです。
$ ovs-vsctl set bridge ofs0 datapath_type=netdev
ただし、userspace での動作では、前回 紹介した openvswitch 組み込みの gre 機能は使えないようです。
試してみる
あるホスト上で動作する二つの VM 間を openvswitch でつなぎ、その ovs を Trema/routing_switch で OpenFlow 動作をさせます。kernel module を使った場合と userspace のみで動作させた場合の、二つの VM 間のスループットの違いについて netperf を使って調べてみました。kernel module を使った場合は 1465Mbps, userspace で動作させた場合は 248Mbps となり、だいたい 6 倍くらいの差が出るようです。(ざっくりと測定した結果なので、条件によっては異なる結果がでるかもしれません。その辺はご了承を。)
GRE を使って OpenFlow ネットワークを作る
前回は etherip を使ってトンネルを組む方法について紹介しましたが、今回は GRE を使う方法について紹介します。
Linux には kernel module として動作する GRE ドライバが存在しますが、今回は Openvswitch に組み込まれている GRE 機能を使用します。そのため lsmod で Kernel module (ip_gre) を確認し、組み込まれていれば rmmod しておいてください。
今回の構成は、以下のとおりです。
Openvswitch の設定
openvswitch は以下のように設定を行います。
ovs-vsctl add-bridge ofs0 ovs-vsctl add-port ofs0 vnet0 ovs-vsctl add-port ofs0 gre0 ovs-vsctl set interface gre0 type=gre options:remote_ip=192.168.1.2 options:pmtud=false
対向側も remote_ip のアドレス以外は同様に設定します。
gre0 は、openvswitch 内部のみで作られ、使用されるインターフェイス名なので、ifconfig 等では表示されません。
設定は以上で終わりです。後は、前回と同様に Trema/routing_switch を動作させ、VM 間の疎通確認を行ってみてください。
MTU の話
EtherIP や GRE を使うとカプセル化を行わなければならない分、パケットのサイズが大きくなります。そのためネットワークの MTU についての考慮が必要になります。
一般的な Ethernet ではフレームの最大長は FCS を除くと 1514 ですが、トンネルを使った場合以下のようになります。
- EtherIP : 1478 = 1514 - 14(Ethernet header) - 20(IP header) - 2(EtherIP header)
- GRE : 1476 = 1514 - 14(Ethernet header) - 20(IP header) - 4(GRE header)
例えば GRE トンネルで IP ネットワークを作った場合の MTU は、1462 となります。これらを図示すると以下のようになります。
今回のようにトンネルを使う構成では、以下のいずれかを選択する必要があります。
- VM が接続する 192.168.2.0 のネットワークの MTU を小さくする(今回の場合 1462 にする)。
- VM が接続するネットワークの MTU は 1500 のままとし、GRE のパケットのフラグメントを許容する。
今回はフラグメントを行うこととし、そのために openvswitch の pmtud の機能を使わないよう設定しています。
フラグメントが発生した場合、トンネルの終端側でリアセンブルを行う必要があるため、その分パフォーマンスが低下します。Nicira が提案している STT では、ハードウェアへのオフロード機能を活用して、この問題に対処しているようです。STT に関しては、internet-draft が出ているので、そのうち内容紹介を行いたいと思います。
追記(2012/4/24)
gre の設定方法に誤りがありましたので、以下のように訂正しました。
誤 : ovs-vsctl set interface gre0 type=gre options:remote_ip=192.168.1.2,pmtud=false 正 : ovs-vsctl set interface gre0 type=gre options:remote_ip=192.168.1.2 options:pmtud=false
EtherIP を使って OpenFlow ネットワークを作る
今回は EtherIP を使って、openvswitch 同士を接続してみたいと思います。ハードウェア OpenFlow スイッチを持っていなくても、トンネルを使うことで、オーバーレイで OpenFlow ネットワークを作ることが出来ます。今回は、以下のような構成を作ることが目標です。
etherip のインストール
EtherIP の Kernel module 実装である EtherIP for Linux を使用します。kernel module は kernel のバージョンが違うと build 出来ないことがあるので、最新版を利用しましょう。ここ から取ってきます。
$ git clone git://git.8bytes.org/scm/etherip.git $ cd etherip $ make $ make driver $ sudo make install $ sudo make driver-install
kernel module のロードと tunnel endpoint の設定
対向の IP アドレスを 192.168.1.2 としたトンネルインターフェス ethip0 を、以下のように作ります。
$ sudo insmod /lib/modules/`uname -r`/misc/etherip.ko $ sudo /usr/sbin/ethiptunnel -a -d 192.168.1.2 -n ethip0 $ sudo ifconfig ethip0 up
192.168.1.2 側の PC も同様に設定を行ってください。こちら側からのトンネルの対向のアドレスは 192.168.1.1 になります。
openvswitch の設定
openvswitch のインストールと初期設定は、こちら を参考にしてください。
$ sudo ovs-vsctl add-br ofs0 $ sudo ovs-vsctl add-port ethip0 $ sudo ovs-vsctl add-port vnet0 $ sudo ovs-vsctl set-controller ofs0 tcp:192.168.1.1:6633
二台とも同様な設定を行って下さい。
trema/routing_switch の起動
Trema は 192.168.1.1 側のマシンで動作させます。
$ cd trema/ $ ./trema run -c ../apps/routing_switch/routing_switch_null.conf -d $ TREMA_HOME=. ../apps/show_description/show_description Manufacturer description: Nicira Networks, Inc. Hardware description: Open vSwitch ... 省略
show_description コマンドにより、openvswitch 二台分の情報が表示されるはずです。次にトポロジーが正しく認識できているかを次のコマンドで確認します。
$ TREMA_HOME=. ../apps/topology/show_topology
二台の openvswitch の datapath_id と、それらの間のリンクに関する情報が表示されるはずです。
ここまで出来ていれば、VM 間の通信が出来るはずです。一方の VM 上から対向の VM に対して、ping を打ってみましょう。
次回は、EtherIP の代わりに GRE を使う方法について紹介したと思います。
C 言語で Match を書く (その1)
今回は、C 言語で Match を書いてみましょう。
送信元 IP アドレス 192.168.1.0/24、宛先 IP アドレス 192.168.2.0/24 とマッチさせる Flow_mod を設定するコントローラは、以下のようになります。
ポイントは二点です。
- 宛先 IP アドレスをマッチ条件に用いる場合には、dl_type = 0x0800 もマッチ条件として用いる必要があります(詳しくはここ)。
- 以前説明したように、今回のケースでは wildcard は 11,0010,0000,1000,1110,1111b = 0x3208ef である必要があります。nw_src, nw_dst の mask は 24 ビットなので、wildcard として扱うのは下位 8 ビットとなり、それぞれ 001000b = 8 を設定しています。
build した後、network.conf を使って、起動してみましょう。
$ ./trema run ./matchtest -c ./network.conf -d $ ./trema dump_flows 0x1 NXST_FLOW reply (xid=0x4): cookie=0x1, duration=3.536s, table=0, n_packets=0, n_bytes=0, priority=65535,ip,nw_src=192.168.1.0/24,nw_dst=192.168.2.0/24 actions=drop
想定したとおりのフローエントリができたでしょうか?