目次
- L7データのダンプを取る
- ウィンドウズの計算機でtcpチェックサムを計算



1.tremaでコントロールプレインとデータプレインを分離する方法
2.tremaで仮想ホストではなくリアルなインターフェースを使う方法

本「OpenFlow実践入門」にもネットにも見つけられなかったので書き残しておきます。

参照:Trema のコントローラと仮想ネットワークをそれぞれ別々に動かす
http://ranosgrant.cocolog-nifty.com/blog/2013/04/trema-4cea.html


■■■ ネットワーク環境 ■■■
======================================================
              10.10.10.1(リモートアクセスでの管理用)
              eth0
eth1 --------------- Ubuntu136 --------------- eth2
|.136                              .141
|                                 |
192.168.1.0/24                      192.168.2.0/24
|                                 |
|.141                              .141
eth1 --------------- Ubuntu141 --------------- eth2
              eth0
              10.10.10.2(リモートアクセスでの管理用)
======================================================
3つのインタフェースを持つUbuntu2台をVM上で動かしています。

- Ubuntu136: コントロールパスとデータパス両方
- Ubuntu141: データパスのみ



■■■ Ubuntu136上でのスクリプト&設定 ■■■
================================================================================
root@ubuntu:/home/hiro/test/trema# cat learning-switch.rb
class LearningSwitch < Controller
def start
@fdb = {}
end

def switch_ready datapath_id
info "Switch #{ datapath_id.to_hex } is UP"
end

def switch_disconnected( datapath_id )
info "Switch #{ datapath_id.to_hex } is DOWN"
end

def packet_in( datapath_id, message )
info "packet_in. dp: " + datapath_id.to_hex + ", in_port: " + message.in_port.to_s
@fdb[ message.macsa ] = message.in_port
port_no = @fdb[ message.macda ]
if port_no
flow_mod datapath_id, message, port_no
packet_out datapath_id, message, port_no
else
flood datapath_id, message
end
end

private

def flow_mod( datapath_id, message, port_no )
send_flow_mod_add(
datapath_id,
:match => ExactMatch.from( message ),
:actions => SendOutPort.new( port_no )
)
end

def packet_out( datapath_id, message, port_no )
send_packet_out(
datapath_id,
:packet_in => message,
:actions => SendOutPort.new( port_no )
)
end

def flood( datapath_id, message )
packet_out datapath_id, message, OFPP_FLOOD
end
end

root@ubuntu:/home/hiro/test/trema# cat learning-switch2.conf
vswitch("lsw") {
datapath_id "0x136"
ip "192.168.1.136"
}
link "lsw", "eth1"
link "lsw", "eth2"
================================================================================

"learning-switch2.conf"には仮想ホストもそれへのリンクも設定していません。
単に仮想スイッチと実インタフェースへのリンクをしているだけです。

「ip "192.168.1.136"」が重要で、データパス側からコントローラパスに向けて接続する
ので、データパスだけのホストには必ずこれを設定しておく必要があります。



■■■ Ubuntu141上でのスクリプト&設定 ■■■
=============================================================
root@ubuntu:/home/hiro/test/trema# cat empty.rb
class Empty < Controller
end

root@ubuntu:/home/hiro/test/trema# cat learning-switch2.conf
vswitch("lsw") {
datapath_id "0x141"
ip "192.168.1.136"
}
link "lsw", "eth1"
link "lsw", "eth2"
=============================================================

このホストはコントローラとしては動かないためrubyスクリプトは空のクラスだけでOKで
す。
設定には
- 実インタフェースと仮想スイッチをリンク
- コントローラのIPを指定
というキモを押さえておけばいいです。



■■■ 実行してみる@Ubuntu136(コントロールパス側) ■■■
-------------------------------------------------------------------------------
root@ubuntu:/home/hiro/test/trema# trema run learning-switch.rb -c learning-switch2.conf
Switch 0x136 is UP
packet_in. dp: 0x136, in_port: 1
packet_in. dp: 0x136, in_port: 2
packet_in. dp: 0x136, in_port: 1
packet_in. dp: 0x136, in_port: 1
packet_in. dp: 0x136, in_port: 1
packet_in. dp: 0x136, in_port: 1
Switch 0x141 is UP
packet_in. dp: 0x136, in_port: 1
packet_in. dp: 0x141, in_port: 1
packet_in. dp: 0x141, in_port: 1
packet_in. dp: 0x136, in_port: 1
packet_in. dp: 0x141, in_port: 1

root@ubuntu:/home/hiro/test/trema# curl 192.168.2.141
<html><body><h1>It works!</h1>
<p>This is the default web page for this server.</p>
<p>The web server software is running but no content has been added, yet.</p>
</body></html>
root@ubuntu:/home/hiro/test/trema# curl 192.168.1.141
<html><body><h1>It works!</h1>
<p>This is the default web page for this server.</p>
<p>The web server software is running but no content has been added, yet.</p>
</body></html>
-------------------------------------------------------------------------------

■■■ 実行してみる@Ubuntu141(データパス側) ■■■
-------------------------------------
root@ubuntu:/home/hiro/test/trema# trema run empty.rb -c learning-switch2.conf
-------------------------------------

上記の通り、コントロールパス側からデータパス側にcurlでHTTPリクエストを送っています。
データパス側には元々ウェブサーバが動いているのでレスポンスを返します。

その通信をイベントハンドラがキャッチしてpacket_in関数が実行されます。
それにより、
info "packet_in. dp: " + datapath_id.to_hex + ", in_port: " + message.in_port.to_s
に書いた通り、どちらのデータパスか判別するためにdatapath_idを出力させ、eth1と
eth2のどちらのインタフェースにパケットが入ってきたのか判別するためin_portを出力
させています。

どうやら設定で
link "lsw", "eth1"
のようにインターフェース名を指定しても、tremaのin_portでは1や2などとして番号で認
識されているようです。

質問・間違い指摘などは shimizu@tokyovalley.com へ。
Hiro