Trema で OpenFlow ネットワークプログラミング



GREE Advent Calendar 2013 22


""  TCP/UDP IP L4, L3  OpenFlow  L1  Layer-1 

 Ethernet IP L1  L3  L4  OpenFlow 

 OpenFlow  "Trema" 

Trema 


3 OpenFlow  SDN  NFV 

 SDN  NFV 

"Virtual eXtensible Local Area Network"  VXLAN"Network Virtualization using Generic Routing Encapsulation"  NVGRE 

GNU  Linux, YAML 



 Trema  OpenFlow  SDN, NFV OpenFlow  SDN Trema  OpenFlow  OpenFlow 

NFV =>  (Ruby on Rails )
SDN =>  (Ruby )
OpenFlow =>  (libc )
Trema => C (libc)  (glibc )

 Trema 


C glibc  BSD 

OpenFlow  ()  Trema  OpenFlow 

Trema :  OpenFlow NEC 
Floodlight :  Big Switch  OpenFlow 
Ryu : OpenStack Neutron  Ryu Neutron  REST API 使調NTT 
OpenDaylight : OpenFlow  SDN  SDN () cisco 

Trema  Trema  Trema::Pio 


PCIPTrema 

Trema  OpenFlow PC OpenFlow 



Trema GitHub  Trema Trema  GitHub  

 Trema  trema "trema --help" 使Trema run C Ruby 

今回は仮想ネットワークの動作を確認するだけなので、用意されているサンプルプログラムを実行します。ここではサンプルプログラム dumper (src/examples/dumper/dumper.rb) を使用します。dumper は、コントローラに通知される各種イベントに対して、イベントとイベントに付随するメタデータ (メッセージデータ) の中身を標準出力に書き出すコントローラアプリケーションです。

仮想ネットワークを使用するには -c オプションに対して、Trema 仮想ネットワーク用の設定ファイルのパスを渡します。サンプルプログラム dumper と同じディレクトリに、仮想ネットワーク用の設定ファイル (dumper.conf) が置かれているのでこれを指定して Trema を起動します。尚、仮想ネットワークを使用する場合、TAP デバイスを作成するため root 権限を要求してくるため、root 権限を与えてやります。

ここで、仮想ネットワークの設定ファイルの中身を見てみます。

ここでは、二つの仮想ホストが一つの仮想スイッチに接続する仮想ネットワークを作る設定をしています。また見ての通り、Trema 仮想ネットワークの設定ファイルは Ruby の内部 DSL で記述されます。

dumper.conf には、vswitch, vhost, link の 3 種類のメソッドコールが記述されており、それぞれが「仮想スイッチ」「仮想ホスト」「仮想リンク」の定義になります。vswitch と vhost の引数でそれぞれ仮想スイッチ、仮想ホストにラベルをつけてやれます。またブロックで内部で、それぞれのメタ情報を設定してやることもできます。

vswitch では、OpenFlow スイッチを識別する 64 ビットの識別子 ( datapath_id ) を設定しています。サンプルでは何も指定していませんが、vhost に対して仮想ホストの IP アドレス、MAC アドレスを以下のように指定してやる事もできます。

作成した仮想ネットワークに対してトラフィックを流してやるには、trema コマンドのサブコマンドの一つ send_packets コマンドを使用します。Trema のリポジトリで "trema send_packets --help" と実行すると、send_packets コマンドの使用法を教えてくれます。

それでは試しに host1 からトラフィックを出して見たいと思います。trema を起動したのとは別のコンソールから、以下コマンドを実行してみてください。以下のコマンドで dumper.conf で定義した host1 から host2 に対して UDP パケットが送られます。



trema run 

trema  "show_stats"  "dump_flows" 使 "--help" 使

使

Trema  /sbin/ifconfig trema-  NIC  TAP 

ここで、仮想スイッチと仮想ホストの実体 (プロセス) を ps コマンドで見て行きましょう。trema 関連のプロセスを確認できます。



switch_manager  OpenFlow  TCP  OpenFlow 

 phost  ovs-openflowd ovs-openflowd Open vSwitch  openflow Open vSwitch OpenFlow  SDN ovs-openflowd v1.2  openflow  test-openflowd v1.3 Trema  openvswitch  ovs-openflowd  (*)

 phost Trema  ARP  ICMP (ECHO),  UDP 

 cli  trema cli 

ps1.1M  700K 使

PCTCP 

(*) Trema  Trema  OpenFlow  OpenFlow v1.3.x 1 OpenFlow v1.3.x  trema-edge  (Nick ) 

Trema  : Tremashark


 Trema  Tremashark 

Tremashark @stereocat  

Tremashark  OpenFlow Wireshark  Trema Wireshark OpenFlow  libpcap OpenFlow  syslog http://www.slideshare.net/chibayasunobu/tremashark

Tremashark 便

trema  run  -s Tremashark 



Trema  learning-switch.rb learning-switch.rb  OpenFlow  L2 Learning Switch -s  trema run objects/tremashark/tremashark OpenFlow  OpenFlow  Wireshark 

 (host1)  (host2) 


host1  host2  (dpid: 0xabc) PacketIn  PacketOut 

 printf gdb Tremashark 

Trema::Pio 


 Trema  Trema Pio 

IPC Ruby  Ethernet 



Ethernet  MAC  (12 byte)  8 byte  datapath_id  4 byte  OpenFlow 

 Ethernet 

ここでは、packet_in オブジェクトの送信元と宛先アドレスフィールドをそれぞれマージしてバイナリに変換し、先頭 64 bit だけ取り出して、数値に戻すという処理をしなければなりません。メンテナンス性を著しく害した非常にダメな感じのやり方です。

加えて、こうしたオレオレなトラフィックをデータプレーンに流して、既存のネットワーク機器に入ったりなんかしちゃと、ビックリさせてエラーとか吐かせちゃうかもしれないので、ここは LLDP などの既存のプロトコルのパケットを生成し、また取得したパケットを解析できるようにしたいです。

そこで役に立つのが Trema::Pio です。例えば先程のコードを LLDP パケットを送り出すモノに書き換えたいと思います。 Trema Pio を使うと以下のようにしてできます。

邪魔なオレオレコードを無くすことができました。受信側のパース処理においても同様です。





Trema::Pio  Trema Trema  packet_in CONTROLLER_DEFINED_TYPE 

 ARP, ICMP  DHCP  VLAN 


Trema 使

Trema 


 OpenFlow  2013 SDN SDN Firewall  VPN, Network Isolation  REST API  SDN  OpenFlow OpenFlow  SDN 

Trema  OpenFlow SDN  SDN OpenContrail  OpenDaylight 
 SDN  OpenFlow 

 Rubyist  Chef 稿