今日も秋田で IoT

旧 Trema 日記

Flow エントリをポート指定で消す (その2)

今回は、ポート番号の指定によりフローエントリを消す方法について、実際に動かして試してみましょう。

以下の内容のコントローラを outport_test.rb というファイル名で用意します。

class OutportTest < Controller
  def switch_ready dpid
    send_flow_mod_add(
      dpid,
      :match => Match.new( :in_port => 1 ),
      :actions => SendOutPort.new( 2 )
    )
    send_flow_mod_add(
      dpid,
      :priority => 10000,
      :match => Match.new( :in_port => 1 ),
      :actions => SendOutPort.new( 3 )
    )
    send_message dpid, FeaturesRequest.new
  end


  def features_reply dpid, message
    message.ports.each do | each |
      puts "Port no: #{ each.number }, name: #{ each.name }"
    end
  end


  def port_status dpid, message
    return if message.phy_port.state & Port::OFPPS_LINK_DOWN == 0
    puts "Port #{ message.phy_port.number } is down."
    send_flow_mod_delete(
      dpid,
      :match => Match.new,
      :out_port => message.phy_port.number
    )
  end
end

エミュレータ用の設定ファイル (outport_test.conf) も用意しましょう。

vswitch {  datapath_id "0x1" }

vhost ( "host1" )
vhost ( "host2" )
vhost ( "host3" ) 

link "0x1", "host1"
link "0x1", "host2"
link "0x1", "host3"

まずは作成したコントローラを実行してみましょう。Features Request を用いて取得したポート番号と名前の一覧が表示されます。

$ trema run ./outport_test.rb  -c ./test.conf 
Port no: 3, name: trema0-0
Port no: 2, name: trema2-0
Port no: 65534, name: vsw_0x1
Port no: 1, name: trema1-0

このコントローラは、switch_ready の段階で二つのフローエントリを設定します。trema apps に用意されている flow_dumper を用いて、フローエントリが二つ設定されていることを確認してみましょう。

$ cd ../apps/flow_dumper/
$ trema run ./flow-dumper.rb 
[0x1] table_id = 0, priority = 65535, cookie = 0x357c000000000001, idle_timeout = 0, hard_timeout = 0, duration = 2, packet_count = 0, byte_count = 0, match = [wildcards = 0x3820fe(dl_src|dl_dst|dl_type|dl_vlan|dl_vlan_pcp|nw_proto|nw_tos|nw_src(32)|nw_dst(32)|tp_src|tp_dst), in_port = 1, dl_src = 00:00:00:00:00:00, dl_dst = 00:00:00:00:00:00, dl_vlan = 0, dl_vlan_pcp = 0, dl_type = 0, nw_tos = 0, nw_proto = 0, nw_src = 0.0.0.0/0, nw_dst = 0.0.0.0/0, tp_src = 0, tp_dst = 0], actions = [Trema::SendOutPort: port_number=2, max_len=65535]
[0x1] table_id = 0, priority = 10000, cookie = 0x357c000000000002, idle_timeout = 0, hard_timeout = 0, duration = 2, packet_count = 0, byte_count = 0, match = [wildcards = 0x3820fe(dl_src|dl_dst|dl_type|dl_vlan|dl_vlan_pcp|nw_proto|nw_tos|nw_src(32)|nw_dst(32)|tp_src|tp_dst), in_port = 1, dl_src = 00:00:00:00:00:00, dl_dst = 00:00:00:00:00:00, dl_vlan = 0, dl_vlan_pcp = 0, dl_type = 0, nw_tos = 0, nw_proto = 0, nw_src = 0.0.0.0/0, nw_dst = 0.0.0.0/0, tp_src = 0, tp_dst = 0], actions = [Trema::SendOutPort: port_number=3, max_len=65535]

次にポート 2 をダウンさせ、該当するフローエントリの削除を確認してみましょう。ポート 2 の名前は、trema2-0 なので、これを ifconfig でダウンさせてみます。その後、flow-dumper.rb でフローエントリを確認してみましょう。

$ sudo ifconfig trema2-0 down
$ trema run ./flow-dumper.rb 
[0x1] table_id = 0, priority = 10000, cookie = 0x357c000000000002, idle_timeout = 0, hard_timeout = 0, duration = 10, packet_count = 0, byte_count = 0, match = [wildcards = 0x3820fe(dl_src|dl_dst|dl_type|dl_vlan|dl_vlan_pcp|nw_proto|nw_tos|nw_src(32)|nw_dst(32)|tp_src|tp_dst), in_port = 1, dl_src = 00:00:00:00:00:00, dl_dst = 00:00:00:00:00:00, dl_vlan = 0, dl_vlan_pcp = 0, dl_type = 0, nw_tos = 0, nw_proto = 0, nw_src = 0.0.0.0/0, nw_dst = 0.0.0.0/0, tp_src = 0, tp_dst = 0], actions = [Trema::SendOutPort: port_number=3, max_len=65535]

出力ポートが 2 であるフローエントリが削除されていることが確認できたでしょうか?