では、受信ホストの存在をスイッチはどのようにして知るのでしょうか? 受信ホストは、受信開始時にIGMP(Internet Group Management Protocol)パケットを出して「どの動画を観たいか」をスイッチに伝えます。スイッチは、このIGMPパケットを受け取ったポートに対してのみパケットを送信します。
require "set"
class MFC
def initialize
@db = Hash.new do | hash, key | ← グループの一覧を初期化
hash[ key ] = Set.new
end
end
def learn group, port ← グループに受信者接続ポートを登録
members( group ).add( port )
end
def remove group, port ← グループからポートを削除
members( group ).delete( port )
end
def members group ← グループの受信ホストが接続するすべてのポートを検索
@db[ group.to_i ]
end
en
SimpleMulticastクラス
SimpleMulticastクラスは、コントローラの本体です(リスト2)。
リスト2 SimpleMulticastクラス(simple-multicast.rb)
require "mfc"
class SimpleMulticast ← MFCオブジェクトを用意
end
def packet_in datapath_id, messageif message.igmp?← (1)packet_inしたパケットがIGMPか?handle_igmp messageelsemembers = @mfc.members( message.ipv4_daddr )← グループのメンバー一覧flow_mod datapath_id, members, messagepacket_out datapath_id, members, messageendend
private ← 以下プライベートメソッドdef handle_igmp message← (2)IGMPパケット受信時の処理group = message.igmp_group← IGMPパケット中のグループアドレスの値port = message.in_portif message.igmp_v2_membership_report?@mfc.learn group, port← グループへ参加elsif message.igmp_v2_leave_group?@mfc.remove group, port← グループを脱退endenddef flow_mod datapath_id, members, message← (3)フローを設定send_flow_mod_add(datapath_id,:match => ExactMatch.from( message ),:actions => output_actions( members ),← 視聴者のポートだけに出力:hard_timeout => 5← flow_modの有効期限は5秒)end
def packet_out datapath_id, members, message ← packet_inパケットの転送
send_packet_out(
datapath_id,
:packet_in => message,
:actions => output_actions( members ) ← 視聴者のいるすべてのポートに出力
)
end
def output_actions members ← 視聴者のいるポートだけに出力するアクション
members.collect do | each |
ActionOutput.new( :port => each )
end
end
end