GRE を使って OpenFlow ネットワークを作る

前回は etherip を使ってトンネルを組む方法について紹介しましたが、今回は GRE を使う方法について紹介します。
Linux には kernel module として動作する GRE ドライバが存在しますが、今回は Openvswitch に組み込まれている GRE 機能を使用します。そのため lsmod で Kernel module (ip_gre) を確認し、組み込まれていれば rmmod しておいてください。
今回の構成は、以下のとおりです。
f:id:kazuya_ax:20120415152028p:image:w360

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 となります。これらを図示すると以下のようになります。
f:id:kazuya_ax:20120418170048p:image:w360

今回のようにトンネルを使う構成では、以下のいずれかを選択する必要があります。

  • 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