Tremaとtrema edgeの違い

5,084 views

Published on

Document for develop OFC App by Trema-Edge.

Published in: Technology

Tremaとtrema edgeの違い

  1. 1. 意外に違う Trema と Trema-Edge oshiba
  2. 2. 自己紹介  PythonとRubyが好きで、 色々遊んでます!  フレームワークをあれこれ触って楽しん でます。  会社でOpenFlowスイッチ扱ってます。
  3. 3. 今日お話しする内容 TremaEdgeを使ってみて分かった、 Tremaとの違いどころを色々と書きます。 Pio試したり、Sinatra試したりすると中々手ごわいこと (ズバリ書くと不具合)があったため、その辺りを重点的に。 ※ 今後修正されると思うので、そのときにはこの資料は 意味をなさないね! (2014年2月17日で作りました)
  4. 4. What is TremaEdge ? Trema TremaEdge OF v1.0 対応 OF v1.3 対応 要するにTremaのOF1.3用 フレームワークです
  5. 5. ちなみに。。。 OF v1.3になったことによる変更点は、 あんまり解説しません。 マスタリングTCP/IPのOpenFlowとか読んでね! 解説しない理由: めんどくさいから(変更点多すぎ) ※ 混乱しそうな場所だけほんのちょっと触れるかも ※ あと、Ruby2.0になったことによる違いも触れないです
  6. 6. まず、起動するだけ class TestController < Controller def start puts “ Hello Trema! ” end end 何も変化無し。
  7. 7. ハンドラ定義 ※ ハンドラ名はものによって変わってる OpenFlowメッセージが変わったの で def packet_in dpid, message end def port_status dpid, message end def port_desc_multipart_reply dpid, message end def packet_in dpid, message end ポート情報一覧の 取得用 ※FeaturesRequest/Re plyで受け取れなくなっ た情報 今まで通りメソッドを定義。
  8. 8. タイマ定義とかメッセージ送信 とか # タイマ定義 add_timer_event :discover_neighbor, 5, :periodic # フロー追加 send_flow_mod_add( dpid, options) #メッセージ送信 send_message dpid, PortMultipartRequest.new 基本、今まで通り。 ※ フロー追加はoptionについて変更 有(instructionとか)
  9. 9. ここから変更点とか問題点とか ・ ・ ・ ・ ・ ・ PacketInのときのパケット情報取得 PortStatusのポート情報受け取り PacketOutでデータのみのパケット出力 色々な便利メソッドの有無 Sinatraと連携 Trema::Pioと連携
  10. 10. PacketInのときのパケット情報取得  マッチ条件の名前がベース eth_dst、eth_src、ipv4_dst とか https://github.com/trema/tremaedge/blob/develop/ruby/trema/match.rb をチェック!
  11. 11. PortStatusのポート情報受け取り Trema def port_status dpid, message message.phy_port.port_no end  TremaEdge def port_status dpid, message phy_port message.port_no がない end  理由:TremaEdgeでは、 PortStatusがPortクラスを継承する形で作られている
  12. 12. 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…
  13. 13. 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(), :packet_inオプションが指定さ buffer_id, れていないと、ちゃんと動く in_port, ようになっていない。 actions, NULL ); } 一部改変が必要
  14. 14. 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 ); dataに対するfree自体は既に処理 があるため、追記はしない } ~中略~ if ( buffer_id == OFP_NO_BUFFER && //条件を1つ追加 ( !NIL_P( r_opt_message ) || !NIL_P(r_opt_data) )) { ~中略~ else { :dataのオプション指定があった場合を想定 ~中略~
  15. 15. PacketOutでデータのみのパケット出力  これだけではNG! send_packet_out( dpid, # :data => packet, :data => packet.unpack(“C*”), :buffer_id => OFP_NO_BUFFER, :actions => SendOutPort.new( OFPP_ALL ) Arrayで渡さないといけないので、 unpackをする必要がある )
  16. 16. Sinatraと連携 普通に使うと以下のようなメッセージが出 てしまい、Sinatraが動かない。。。 「Logger」に問題がありそう? クラスじゃないというメッセー ジが出てる。
  17. 17. Sinatraと連携 Sinatra のLoggerクラスと TremaのLoggerモジュールがバッティングしてる。 Sinatra Trema-Edge Logger クラス 競合 Logger モジュール Tremaだと、「DefaultLogger」だったのでOKだった。。。
  18. 18. Sinatraと連携(回避策) Loggerモジュールの名前を変えてあげる。 # logger.cについて(145行目) mLogger = rb_define_module_under( mTrema, "TremaLogger" ); # logger.rbについて(20行目) module TremaLogger # controller.rbについて(33行目) include TremaLogger
  19. 19. Sinatraと連携(変更後) エラーは出ない。ルートを書けば問題なく動作 少なくとも、GET、POST、DELETEは動作
  20. 20. Trema::Pioと連携 require "pio" class TestPacket < Controller def start puts "start" end end require しただけでエラー 動かない。。。 error: field '[:octets, {:type=>:uint8, :initial_length=>6}]' is an illegal fieldname in Pio::Type::MacAddress
  21. 21. Trema::Pioと連携 どうやら、Trema-Edgeの問題。。。 # Trema-Edgeで動かした場合 class Fuga end p Fuga.superclass p Fuga.superclass.respond_to? "string" p Fuga.superclass.respond_to? “array" Object true true Objectクラスに対して、stringやarrayがクラスメソッ ドとして存在してしまっている。
  22. 22. Trema::Pioと連携 この”string”や”array”が、bindataを使ったPioのソースにお ける、arrayやstringの宣言的な箇所で問題を起こしている。 こういう箇所で問題になる
  23. 23. Trema::Pioと連携(回避策) arrayとかstringが使えないので、とりあえずPio側を書き換え。 pio_arrayとかpio_stringにする。 class PioString < Bindata::String end class PioArray < Bindata::Array end こんな感じの宣言箇所を arrayから、pio_arrayに変更 stringから、pio_stringに変更 sugyoさんからもっとよさそうな回避策も出てました。 でも試してないからここでは書くのをやめました。
  24. 24. 色々な便利メソッドの有無 message-helperに今後は纏められる? (sugyoさんがissueあげてた) でも、今はまだ、ほとんどない。。。 send_flow_mod_add、 send_group_mod_addぐら いしかない。。。
  25. 25. 色々な便利メソッドの有無 残念ながら以下みたいなのは自分で定義する必要あり ・ 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 Portクラスに 追加する 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に追加するなど
  26. 26. 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
  27. 27. 最後に注意事項(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は、今まで通りセットした順番どおりに実行される
  28. 28. 以上です! 有難うございました。 oshiba

×