Trema の仮想ネットワークの落とし穴。ARPなしで通信してしまう
[ 2013年2月3日 追記。 回避策がありました。新しい OS を必要としますが、こちらに書いたネットワークネームスペース機能を使うことでARPも含んだテストが仮想ネットワーク機能でもできます。 ]
OpenFlow フレームワークの Trema 用に書いた5行のリピーターハブを改造して、UDPのポート番号で通信を制限するファイアウォールのようなものを作ろうとして落とし穴にはまりました。失敗事例紹介です。
■教訓
Trema の仮想ネットワーク機能で仮想ホスト同士の通信ができても現実のネットワークで通信できるとは限らない。
ARP が通るフローを定義しているか確認せよ。
目的によっては ARP だけでなく、例えば ICMP Echo を通すべきかなども考慮しないといけないかもしれません。
■失敗コード
やろうとしたことは宛先がUDPポート60000のパケットだけを通すというものです。
class Test1 < Controller def switch_ready( datapath_id ) send_flow_mod_add( datapath_id, :match => Match.new( :dl_type => 0x0800, # IP :nw_proto => 17, # UDP :tp_dst => 60000 # UDP Port ), :actions => SendOutPort.new( OFPP_FLOOD ) ) end end
マッチングルールを書くにあたって、書籍『OpenFlow ネットワーク入門』(初版、コロナ社)のP.136 に記載の「表6.10 Matchクラスのインスタンス化オプションのキー」を参考にしました。:dl_type も書かないとダメだということはこの本のおかげで気がつきました。
■仮想ネットワークでのテスト
きちんと通信できました。
仮想ネットワーク定義:
vswitch("vsw1") { datapath_id "0x1" } vhost("host2") { ip "192.168.0.2" } vhost("host1") { ip "192.168.0.1" } link "vsw1", "host2" link "vsw1", "host1"
実行結果:
$ trema dump_flow vsw1 NXST_FLOW reply (xid=0x4): cookie=0x1, duration=227.119s, table=0, n_packets=1, n_bytes=64, priority=65535, udp,tp_dst=60000 actions=FLOOD $ trema show_stats host2 Sent packets: Received packets: $ trema send_packets --source host1 --dest host2 --tp_dst 50000 $ trema show_stats host2Sent packets: Received packets: $ trema send_packets --source host1 --dest host2 --tp_dst 60000 $ trema show_stats host2Sent packets: Received packets: ip_dst,tp_dst,ip_src,tp_src,n_pkts,n_octets 192.168.0.2,60000,192.168.0.1,1,1,50
host2 めがけてUDPポート50000で通信した時には host2 の統計情報は空ですがUDPポート60000だとパケットが受信されています。
■リアルの世界では
2台のLinuxで nc コマンドで通信を試しました。
・構成:
[Linux(IP: 10.0.0.3)] --- [OpenFlowスイッチ] --- [Linux(IP: 10.0.0.4)]
・1台目(IPアドレス 10.0.0.4): udp 60000 で待ち受け
実行コマンド:
$ nc -u -l 60000
これでUDPポート60000でデータが来るのを待ちデータが来たら表示するようにしておきます。
・2台目(IPアドレス 10.0.0.3): udp 60000 めがけて送信
実行コマンド:
$ nc -u 10.0.0.4 60000 aaaa --- 入力して改行 bbbb --- 入力して改行
2台目にて、nc コマンドを実行すると標準入力からの入力待ちになるので、文字を入力して改行するとその行が1台目側で表示されるはずですが、何もでません。
2台目側で arp -a コマンドで確認してみると...解決できていない
$ arp -a ? (10.0.0.4) at <incomplete> on eth0
本当なら <imcomplete> のところは MAC アドレスがでるべきです。
■修正後のコード
ARP が通るようにフローエントリを追加しました。
class Test1 < Controller
def switch_ready( datapath_id )
send_flow_mod_add(
datapath_id,
:match => Match.new(
:dl_type => 0x0806 # ARP
),
:actions => SendOutPort.new( OFPP_FLOOD )
)
send_flow_mod_add(
datapath_id,
:match => Match.new(
:dl_type => 0x0800, # IP
:nw_proto => 17, # UDP
:tp_dst => 60000 # UDP Port
),
:actions => SendOutPort.new( OFPP_FLOOD )
)
end
end
このコードに変更して、2台で再度ncコマンドを起動し直したらうまく動きました。
« 【TremaでOpenFlowプログラミング】リピーターハブを5行で作る | トップページ | Trema の仮想ネットワーク機能には『OpenFlow実践入門』に書いてない強力な機能がありました。 »
「OpenFlow」カテゴリの記事
- ◆ 【Open vSwitchのみで OpenFlowプログラミング】VLAN ID コンバータ 改(2013.08.10)
- ◆ 【Open vSwitchのみで OpenFlowプログラミング】VLAN ID コンバータ(2013.08.05)
- ◆ 【TremaでOpenFlowプログラミング】VLAN ID コンバータ(2013.05.12)
- ◆ Linux のネットワークネームスペース機能と Open vSwitch で仮想ネットワーク(OpenFlowスイッチとTrema)(2013.05.11)
- ◆ OpenFlow 1.0.0 メッセージと Trema API(Ruby) との対応表(2013.05.08)
「Trema」カテゴリの記事
- ◆【改訂】OpenFlow フレームワーク Trema 0.4 のインストール手順【0.4.7対応】(2014.06.11)
- ◆ Trema 0.4.7インストール失敗とバージョン指定インストール(2014.06.08)
- ◆ OpenFlowフレームワーク Trema 0.4 のインストール(2013.10.06)
- ◆ 【TremaでOpenFlowプログラミング】VLAN ID コンバータ(2013.05.12)
- ◆ Linux のネットワークネームスペース機能と Open vSwitch で仮想ネットワーク(OpenFlowスイッチとTrema)(2013.05.11)
「TremaでOpenFlowプログラミング」カテゴリの記事
- ◆ 【TremaでOpenFlowプログラミング】VLAN ID コンバータ(2013.05.12)
- ◆ OpenFlow 1.0.0 メッセージと Trema API(Ruby) との対応表(2013.05.08)
- ネットワークネームスペース機能使用時の Trema 停止エラー軽減方法(2013.03.16)
- 【TremaでOpenFlowプログラミング】マッチングルール早見表(2013.03.02)
- Trema の仮想ネットワーク機能には『OpenFlow実践入門』に書いてない強力な機能がありました。(2013.02.03)
この記事へのコメントは終了しました。
« 【TremaでOpenFlowプログラミング】リピーターハブを5行で作る | トップページ | Trema の仮想ネットワーク機能には『OpenFlow実践入門』に書いてない強力な機能がありました。 »
コメント