tremaとtrema edgeの違い

28
意意意意意 Trema 意 Trema- Edge oshiba

Upload: hiroshi-oshiba

Post on 11-Jun-2015

2.835 views

Category:

Technology


0 download

DESCRIPTION

Document for develop OFC App by Trema-Edge.

TRANSCRIPT

Page 1: Tremaとtrema edgeの違い

意外に違う Trema と Trema-Edge

oshiba

Page 2: Tremaとtrema edgeの違い

自己紹介

Python と Ruby が好きで、 色々遊んでます!

フレームワークをあれこれ触って楽しんでます。

会社で OpenFlow スイッチ扱ってます。

Page 3: Tremaとtrema edgeの違い

今日お話しする内容TremaEdge を使ってみて分かった、Trema との違いどころを色々と書きます。

Pio 試したり、 Sinatra 試したりすると中々手ごわいこと( ズバリ書くと不具合 ) があったため、その辺りを重点的

に。※  今後修正されると思うので、そのときにはこの資料

は意味をなさないね!(2014 年 2 月 17 日で作りました )

Page 4: Tremaとtrema edgeの違い

What is TremaEdge ?

要するに Trema の OF1.3用

フレームワークです

Trema TremaEdge

OF v1.0  対応

OF v1.3  対応

Page 5: Tremaとtrema edgeの違い

ちなみに。。。

OF v1.3 になったことによる変更点は、あんまり解説しません。

マスタリング TCP/IP の OpenFlow とか読んでね!

解説しない理由: めんどくさいから ( 変更点多すぎ )※  混乱しそうな場所だけほんのちょっと触れるかも

※  あと、 Ruby2.0 になったことによる違いも触れないです

Page 6: Tremaとtrema edgeの違い

まず、起動するだけ

class TestController < Controller

def start

puts “ Hello Trema! ”

end

end

何も変化無し。

Page 7: Tremaとtrema edgeの違い

ハンドラ定義

def packet_in dpid, messageenddef port_status dpid, messageenddef port_desc_multipart_reply dpid, messageenddef packet_in dpid, messageend

ハンドラ名はものによって変わってる

※   OpenFlow メッセージが変わったので

今まで通りメソッドを定義。

ポート情報一覧の取得用※FeaturesRequest/Reply で受け取れなくなった情報

Page 8: Tremaとtrema edgeの違い

タイマ定義とかメッセージ送信とか

# タイマ定義add_timer_event :discover_neighbor, 5, :periodic

# フロー追加send_flow_mod_add( dpid, options)

# メッセージ送信send_message dpid, PortMultipartRequest.new

基本、今まで通り。

※  フロー追加は option について変更有 (instruction とか )

Page 9: Tremaとtrema edgeの違い

ここから変更点とか問題点とか

・  PacketIn のときのパケット情報取得・  PortStatus のポート情報受け取り・  PacketOut でデータのみのパケット出

力・ 色々な便利メソッドの有無・  Sinatra と連携・  Trema::Pio と連携

Page 10: Tremaとtrema edgeの違い

PacketIn のときのパケット情報取得 マッチ条件の名前がベース

eth_dst 、 eth_src 、 ipv4_dst  とか

https://github.com/trema/trema-edge/blob/develop/ruby/trema/match.rb

をチェック!

Page 11: Tremaとtrema edgeの違い

PortStatus のポート情報受け取り

Tremadef port_status dpid, message message.phy_port.port_noend TremaEdgedef port_status dpid, message message.port_noend

理由: TremaEdge では、PortStatus が Port クラスを継承する形で作られている

phy_portがない

Page 12: Tremaとtrema edgeの違い

PacketOut でデータのみのパケット出力

# PacketIn ベースのリアクティブな処理 send_packet_out( dpid, :packet_in => packet_in, :actions => SendOutPort.new( OFPP_ALL )

  )# バイナリデータを渡す形の処理 send_packet_out( dpid, :data => packet, :buffer_id => OFP_NO_BUFFER, :actions => SendOutPort.new( OFPP_ALL )

  ) An Ethernet frame must be provided if buffer_id is equal to 0xffffffff データを渡しても NG…

Page 13: Tremaとtrema edgeの違い

PacketOut でデータのみのパケット出力VALUE r_opt_message = HASH_REF( options, packet_in );~中略~if ( buffer_id == OFP_NO_BUFFER && !NIL_P( r_opt_message ) ) {~中略~else {

  packet_out = create_packet_out(

     get_transaction_id(),

     buffer_id,

     in_port,

     actions,

     NULL

  );

}

一部改変が必要

:packet_in オプションが指定されていないと、ちゃんと動くようになっていない。

Page 14: Tremaとtrema edgeの違い

PacketOut でデータのみのパケット出力~改変例~

VALUE r_opt_message = HASH_REF( options, packet_in );VALUE r_opt_data = HASH_REF( options, data ); // データオプション追

加~中略~if ( !NIL_P( r_opt_message ) ) {

~中略~else if( !NIL_P(r_opt_data) ){ // データオプション追加 data = r_array_to_buffer( r_opt_data );

}

~中略~if ( buffer_id == OFP_NO_BUFFER && // 条件を1つ追加 ( !NIL_P( r_opt_message ) || !NIL_P(r_opt_data) )) {

~中略~else {

~中略~:data のオプション指定があった場合を想定

data に対する free 自体は既に処理があるため、追記はしない

Page 15: Tremaとtrema edgeの違い

これだけでは NG!

PacketOut でデータのみのパケット出力

send_packet_out( dpid,# :data => packet, :data => packet.unpack(“C*”), :buffer_id => OFP_NO_BUFFER, :actions => SendOutPort.new( OFPP_ALL )   )

Array で渡さないといけないので、 unpack をする必要がある

Page 16: Tremaとtrema edgeの違い

Sinatra と連携普通に使うと以下のようなメッセージが出てしまい、 Sinatra が動かない。。。

「 Logger 」に問題がありそう?クラスじゃないというメッセージが出てる。

Page 17: Tremaとtrema edgeの違い

Sinatra と連携Sinatra の Logger クラスとTrema の Logger モジュールがバッティングしてる。

Sinatra

Loggerクラス

Trema-Edge

Loggerモジュー

ル競合

Trema だと、「 DefaultLogger 」だったので OK だった。。。

Page 18: Tremaとtrema edgeの違い

# logger.c について (145 行目 )

mLogger = rb_define_module_under( mTrema, "TremaLogger" );

# logger.rb について (20 行目 )

module TremaLogger

# controller.rb について (33 行目 )

include TremaLogger

Sinatra と連携 ( 回避策 )

Logger モジュールの名前を変えてあげる。

Page 19: Tremaとtrema edgeの違い

Sinatra と連携 ( 変更後 )

エラーは出ない。ルートを書けば問題なく動作

少なくとも、 GET 、 POST 、 DELETE は動作

Page 20: Tremaとtrema edgeの違い

Trema::Pio と連携require "pio"

class TestPacket < Controller

def start

puts "start"

end

end

error: field '[:octets, {:type=>:uint8, :initial_length=>6}]' is an illegal fieldname in Pio::Type::MacAddress

require しただけでエラー動かない。。。

Page 21: Tremaとtrema edgeの違い

Trema::Pio と連携どうやら、 Trema-Edge の問題。。。

Objecttruetrue

# Trema-Edge で動かした場合class Fuga

end

p Fuga.superclass

p Fuga.superclass.respond_to? "string"

p Fuga.superclass.respond_to? “array"

Object クラスに対して、 string や array がクラスメソッドとして存在してしまっている。

Page 22: Tremaとtrema edgeの違い

Trema::Pio と連携この” string” や” array” が、 bindata を使った Pio のソースにおける、 array や string の宣言的な箇所で問題を起こしている。

こういう箇所で問題になる

Page 23: Tremaとtrema edgeの違い

class PioString < Bindata::String

end

class PioArray < Bindata::Array

end

Trema::Pio と連携(回避策)array とか string が使えないので、とりあえず Pio 側を書き換え。pio_array とか pio_string にする。

こんな感じの宣言箇所をarray から、 pio_array に変更 string から、 pio_string に変更

sugyo さんからもっとよさそうな回避策も出てました。でも試してないからここでは書くのをやめました。

Page 24: Tremaとtrema edgeの違い

色々な便利メソッドの有無message-helper に今後は纏められる?(sugyo さんが issue あげてた )

でも、今はまだ、ほとんどない。。。

send_flow_mod_add 、send_group_mod_add ぐらいしかない。。。

Page 25: Tremaとtrema edgeの違い

色々な便利メソッドの有無残念ながら以下みたいなのは自分で定義する必要あり・  send_flow_mod_delete

・  Port クラスの port.up?  もしくは port.down?

def up?

if(self.state | 1 == 0)

return true

end

return false

end

def down?

return (not self.up?)

end

def send_flow_mod_delete datapath_id, options

options[ :command ] = OFPFC_DELETE

options[ :table_id ] = OFPTT_ALL if options[ :table_id ].nil?

options[ :match ] = Match.new if options[ :match ].nil?

options[ :cookie ] = 0 if options[ :cookie ].nil?

options[ :cookie_mask ] = 0 if options[ :cookie_mask ].nil?

options[ :out_port ] = OFPP_ANY if options[ :out_port ].nil?

options[ :out_group ] = OFPG_ANY if options[ :out_group ].nil?

send_flow_mod datapath_id, options

end

message-helper に追加するなどPort クラスに追加する

Page 26: Tremaとtrema edgeの違い

Stats メッセージについてMultipart メッセージになったことにより、名前が変わっているので注意。

# PortStats を取る場合send_message dpid, PortMultipartRequest.new

# GroupStats を取る場合send_message dpid, GroupDescMultipartRequest.new

# FlowStats を取る場合send_message dpid, FlowMultipartRequest.new( cookie: 0x0 )

def flow_multipart_reply dpid, message # FlowStats のハンドラend

def group_desc_multipart_reply dpid, message # GroupStats のハンドラend

def port_multipart_reply dpid, message # PortStats のハンドラend

Page 27: Tremaとtrema edgeの違い

最後に注意事項( OF 1.3 関連)

FeaturesReply にはポート情報は入ってない( PortMultipartRequest/Reply が必要になります)

フローエントリには Instructions というものが増えてる フローの削除でクッキー番号の指定と out_group の指定を考えてあげ

る必要がある PacketIn 用のフローを入れないと、 PacketIn しない ポート番号以外に、物理ポート番号とかあるから気をつけて OFPP_NONE とかなくなった アクションについて set_field とか push/pop tag とか色々細かくなっ

たから気をつけて アクションは即時実行( APPLY_ACTION )とパイプライン終了後に

実行する WRITE_ACTION がある WRITE_ACTION には実行順序が決められている APPLY_ACTION は、今まで通りセットした順番どおりに実行される

Page 28: Tremaとtrema edgeの違い

以上です!有難うございました。oshiba