class OpenFlow::Controller::Controller

Constants

DEFAULT_IP_ADDRESS
DEFAULT_TCP_PORT

Attributes

logger[R]

Public Class Methods

create() click to toggle source
# File lib/openflow-controller/controller.rb, line 22
def self.create
  @instance = (@controller_class || self).new
end
inherited(subclass) click to toggle source
# File lib/openflow-controller/controller.rb, line 18
def self.inherited(subclass)
  @controller_class = subclass
end
instance() click to toggle source
# File lib/openflow-controller/controller.rb, line 26
def self.instance
  @instance
end
new() click to toggle source
# File lib/openflow-controller/controller.rb, line 41
def initialize
  @switches = {}
  @messages = {}
  @logger = Logger.new($stdout).tap do |logger|
    logger.formatter = proc do |severity, datetime, _progname, msg|
      "#{datetime} (#{severity}) -- #{msg}\n"
    end
    logger.level = Logger::INFO
  end
end
timer_event(handler, options) click to toggle source
# File lib/openflow-controller/controller.rb, line 30
def self.timer_event(handler, options)
  @timer_handlers ||= {}
  @timer_handlers[handler] = options.fetch(:interval)
end
timer_handlers() click to toggle source
# File lib/openflow-controller/controller.rb, line 35
def self.timer_handlers
  @timer_handlers || {}
end

Public Instance Methods

broadcast(msg) click to toggle source
# File lib/openflow-controller/controller.rb, line 85
def broadcast(msg)
  datapath_ids.each { |did| send_message did, msg }
end
datapath_ids() click to toggle source
# File lib/openflow-controller/controller.rb, line 69
def datapath_ids
  @switches.keys.map(&:to_i)
end
echo_request(datapath_id, msg) click to toggle source
# File lib/openflow-controller/controller.rb, line 109
def echo_request(datapath_id, msg)
  send_message datapath_id, EchoReply.new(xid: msg.xid)
end
error(_datapath_id, _msg) click to toggle source
# File lib/openflow-controller/controller.rb, line 108
def error(_datapath_id, _msg) end
flow_removed(_datapath_id, _msg) click to toggle source
# File lib/openflow-controller/controller.rb, line 116
def flow_removed(_datapath_id, _msg) end
get_binding() click to toggle source
# File lib/openflow-controller/controller.rb, line 56
def get_binding
  binding
end
last_message() click to toggle source
# File lib/openflow-controller/controller.rb, line 101
def last_message
  messages.last
end
last_message_for(datapath_id) click to toggle source
# File lib/openflow-controller/controller.rb, line 93
def last_message_for(datapath_id)
  messages_for(datapath_id).last
end
message_received(_datapath_id, _msg) click to toggle source
# File lib/openflow-controller/controller.rb, line 107
def message_received(_datapath_id, _msg) end
messages() click to toggle source
# File lib/openflow-controller/controller.rb, line 97
def messages
  messages_for datapath_ids.first
end
messages_for(datapath_id) click to toggle source
# File lib/openflow-controller/controller.rb, line 89
def messages_for(datapath_id)
  @messages.fetch(datapath_id.to_s)
end
packet_in(_datapath_id, _msg) click to toggle source
# File lib/openflow-controller/controller.rb, line 112
def packet_in(_datapath_id, _msg) end
port_add(_datapath_id, _msg) click to toggle source
# File lib/openflow-controller/controller.rb, line 113
def port_add(_datapath_id, _msg) end
port_delete(_datapath_id, _msg) click to toggle source
# File lib/openflow-controller/controller.rb, line 114
def port_delete(_datapath_id, _msg) end
port_modify(_datapath_id, _msg) click to toggle source
# File lib/openflow-controller/controller.rb, line 115
def port_modify(_datapath_id, _msg) end
run(ip = DEFAULT_IP_ADDRESS, port = DEFAULT_TCP_PORT, *args) click to toggle source
# File lib/openflow-controller/controller.rb, line 60
def run(ip = DEFAULT_IP_ADDRESS, port = DEFAULT_TCP_PORT, *args)
  maybe_send_handler :start, *args
  socket = TCPServer.open(ip, port)
  socket.setsockopt(:SOCKET, :REUSEADDR, true)
  logger.info "Controller running on #{ip}:#{port}."
  start_timers
  loop { start_switch_thread socket.accept }
end
send_message(datapath_id, msg = nil) click to toggle source
# File lib/openflow-controller/controller.rb, line 77
def send_message(datapath_id, msg = nil)
  if msg.nil?
    msg         = datapath_id
    datapath_id = datapath_ids.first
  end
  @switches.fetch(datapath_id.to_s).send(msg)
end
set_debug() click to toggle source
# File lib/openflow-controller/controller.rb, line 52
def set_debug
  @logger.level = Logger::DEBUG
end
start(*_args) click to toggle source
# File lib/openflow-controller/controller.rb, line 105
def start(*_args) end
switch_ready(_datapath_id) click to toggle source
# File lib/openflow-controller/controller.rb, line 106
def switch_ready(_datapath_id) end
switches() click to toggle source
# File lib/openflow-controller/controller.rb, line 73
def switches
  @switches.values
end

Private Instance Methods

create_and_register_new_switch(socket) click to toggle source
# File lib/openflow-controller/controller.rb, line 146
def create_and_register_new_switch(socket)
  switch = Switch.new(self, socket)
  @messages[switch.datapath_id.to_s] = []
  @switches[switch.datapath_id.to_s] = switch
end
handle_openflow_message(datapath_id) click to toggle source
# File lib/openflow-controller/controller.rb, line 169
def handle_openflow_message(datapath_id)
  msg = @switches.fetch(datapath_id.to_s).receive

  unless msg.class == EchoRequest
    logger.debug "Switch #{datapath_id} received #{msg.type} message."
    @messages[datapath_id.to_s] << msg
    maybe_send_handler :message_received, datapath_id, msg
  end

  case msg
  when Error
    maybe_send_handler :error, datapath_id, msg
  when EchoRequest
    maybe_send_handler :echo_request, datapath_id, msg
  when FeaturesReply
    maybe_send_handler :features_reply, datapath_id, msg
  when PacketIn
    maybe_send_handler :packet_in, datapath_id, msg
  when PortStatus
    case msg.reason
    when :add
      maybe_send_handler :port_add, datapath_id, msg
    when :delete
      maybe_send_handler :port_delete, datapath_id, msg
    when :modify
      maybe_send_handler :port_modify, datapath_id, msg
    # else
    end
  when FlowRemoved
    maybe_send_handler :flow_removed, datapath_id, msg
  # else
  end
end
maybe_send_handler(handler, *args) click to toggle source
# File lib/openflow-controller/controller.rb, line 120
def maybe_send_handler(handler, *args)
  @handler_mutex ||= Mutex.new
  @handler_mutex.synchronize do
    __send__(handler, *args) if respond_to?(handler)
  end
end
start_switch_main(datapath_id) click to toggle source
# File lib/openflow-controller/controller.rb, line 152
def start_switch_main(datapath_id)
  logger.info "Switch #{datapath_id} is ready."
  maybe_send_handler :switch_ready, datapath_id
  loop { handle_openflow_message(datapath_id) }
rescue => exception
  logger.debug "Switch #{datapath_id} error: #{exception}."
  logger.debug exception.backtrace
  unregister_switch(datapath_id)
end
start_switch_thread(socket) click to toggle source
# File lib/openflow-controller/controller.rb, line 138
def start_switch_thread(socket)
  logger.debug 'Socket accepted.'
  Thread.new do
    switch = create_and_register_new_switch(socket)
    start_switch_main(switch.datapath_id)
  end
end
start_timers() click to toggle source
# File lib/openflow-controller/controller.rb, line 127
def start_timers
  self.class.timer_handlers.each do |handler, interval|
    Thread.new do
      loop do
        maybe_send_handler handler
        sleep interval
      end
    end
  end
end
unregister_switch(datapath_id) click to toggle source
# File lib/openflow-controller/controller.rb, line 162
def unregister_switch(datapath_id)
  @messages.delete(datapath_id.to_s)
  @switches.delete(datapath_id.to_s)
  logger.info "Switch #{datapath_id} is disconnected."
  maybe_send_handler :switch_disconnected, datapath_id
end