class Trema::Switch

OpenFlow switch.

Constants

OPENFLOW_HEADER_LENGTH

Attributes

error_message[R]

Public Class Methods

new(socket) click to toggle source
# File lib/trema/switch.rb, line 14
def initialize(socket)
  @socket = socket
end

Public Instance Methods

datapath_id() click to toggle source
# File lib/trema/switch.rb, line 25
def datapath_id
  raise 'Switch is not initialized.' unless @features_reply
  @features_reply.datapath_id
end
Also aliased as: dpid
dpid()
Alias for: datapath_id
init() click to toggle source
# File lib/trema/switch.rb, line 18
def init
  exchange_hello_messages
  exchange_echo_messages
  exchange_features_messages
  self
end
read() click to toggle source
# File lib/trema/switch.rb, line 35
def read
  OpenFlow.read read_openflow_binary
end
write(message) click to toggle source
# File lib/trema/switch.rb, line 31
def write(message)
  @socket.write message.to_binary
end

Private Instance Methods

drain(length) click to toggle source
# File lib/trema/switch.rb, line 85
def drain(length)
  buffer = ''
  loop do
    buffer += @socket.readpartial(length - buffer.length)
    break if buffer.length == length
  end
  buffer
end
exchange_echo_messages() click to toggle source
# File lib/trema/switch.rb, line 46
def exchange_echo_messages
  write Echo::Request.new
  expect_receiving Echo::Reply
end
exchange_features_messages() click to toggle source
# File lib/trema/switch.rb, line 51
def exchange_features_messages
  write Features::Request.new
  @features_reply = expect_receiving(Features::Reply)
end
exchange_hello_messages() click to toggle source
# File lib/trema/switch.rb, line 41
def exchange_hello_messages
  write Hello.new
  expect_receiving Hello
end
expect_receiving(expected_message_klass) click to toggle source

rubocop:disable MethodLength

# File lib/trema/switch.rb, line 57
def expect_receiving(expected_message_klass)
  loop do
    message = read
    case message
    when expected_message_klass
      return message
    when Echo::Request
      write Echo::Reply.new(xid: message.xid)
    when PacketIn, PortStatus # , FlowRemoved (not implemented yet)
      return
    when OpenFlow10::Error::HelloFailed, OpenFlow13::Error::HelloFailed
      @error_message = message
      fail InitError, message.description
    else
      raise "Failed to receive #{expected_message_klass} message"
    end
  end
end
read_openflow_binary() click to toggle source

rubocop:enable MethodLength

# File lib/trema/switch.rb, line 77
def read_openflow_binary
  header_binary = drain(OPENFLOW_HEADER_LENGTH)
  header = OpenFlowHeaderParser.read(header_binary)
  body_binary = drain(header.message_length - OPENFLOW_HEADER_LENGTH)
  raise if (header_binary + body_binary).length != header.message_length
  header_binary + body_binary
end