Class: Trema::Controller

Inherits:
Object
  • Object
show all
Includes:
Pio
Defined in:
lib/trema/controller.rb

Overview

The base class of Trema controller. Subclass and override handlers to implement a custom OpenFlow controller.

rubocop:disable ClassLength

Defined Under Namespace

Classes: FlowModAdd13Option, FlowModAddOption, FlowModDeleteOption, PacketOutOption

Constant Summary collapse

SWITCH =

rubocop:disable MutableConstant

{}
DEFAULT_TCP_PORT =
6653

Instance Attribute Summary collapse

OpenFlow Message collapse

Handlers collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(port_number = DEFAULT_TCP_PORT, logging_level = :info) ⇒ Controller

Returns a new instance of Controller.



142
143
144
145
146
147
# File 'lib/trema/controller.rb', line 142

def initialize(port_number = DEFAULT_TCP_PORT, logging_level = :info)
  @port_number = port_number
  @threads = []
  @logger = Logger.new(name)
  @logger.level = logging_level
end

Instance Attribute Details

#loggerLogger (readonly)

Returns:



117
118
119
# File 'lib/trema/controller.rb', line 117

def logger
  @logger
end

Class Method Details

._handler(_name) ⇒ Object



211
212
213
# File 'lib/trema/controller.rb', line 211

def self._handler(_name)
  # Noop.
end

.create(port_number = DEFAULT_TCP_PORT, logging_level = :info) ⇒ Object



134
135
136
137
138
139
# File 'lib/trema/controller.rb', line 134

def self.create(port_number = DEFAULT_TCP_PORT, logging_level = :info)
  unless @controller_klass
    raise NoControllerDefined, 'No controller class is defined'
  end
  @controller_klass.new(port_number, logging_level)
end

.inherited(subclass) ⇒ Object



129
130
131
# File 'lib/trema/controller.rb', line 129

def self.inherited(subclass)
  @controller_klass = subclass
end

.timer_event(handler, options) ⇒ Object



119
120
121
122
# File 'lib/trema/controller.rb', line 119

def self.timer_event(handler, options)
  @timer_handlers ||= {}
  @timer_handlers[handler] = options.fetch(:interval)
end

.timer_handlersObject



124
125
126
# File 'lib/trema/controller.rb', line 124

def self.timer_handlers
  @timer_handlers || {}
end

Instance Method Details

#echo_request(datapath_id, message) ⇒ Object

The default handler for echo request messages. Override this to implement a custom handler.



229
230
231
232
# File 'lib/trema/controller.rb', line 229

def echo_request(datapath_id, message)
  echo_reply = Echo::Reply.new(transaction_id: message.xid)
  send_message datapath_id, echo_reply
end

#nameObject



160
161
162
# File 'lib/trema/controller.rb', line 160

def name
  self.class.name
end

#packet_in(datapath_id, message) ⇒ Object

Packet In message handler. Override this to implement a custom handler.



238
# File 'lib/trema/controller.rb', line 238

_handler :packet_in

#run(args) ⇒ Object

Starts this controller. Usually you do not need to invoke explicitly, because this is called implicitly by “trema run” command.



153
154
155
156
157
158
# File 'lib/trema/controller.rb', line 153

def run(args)
  maybe_send_handler :start, args
  socket = TCPServer.open('<any>', @port_number)
  start_timers
  loop { start_switch_thread(socket.accept) }
end

#send_flow_mod_add(datapath_id, options) ⇒ Object



170
171
172
173
174
175
176
177
178
179
180
181
# File 'lib/trema/controller.rb', line 170

def send_flow_mod_add(datapath_id, options)
  flow_mod =
    case Pio::OpenFlow.version
    when :OpenFlow10
      FlowMod.new(FlowModAddOption.new(options).to_hash)
    when :OpenFlow13
      FlowMod.new(FlowModAdd13Option.new(options).to_hash)
    else
      raise "Unsupported OpenFlow version: #{Pio::OpenFlow.version}"
    end
  send_message datapath_id, flow_mod
end

#send_flow_mod_delete(datapath_id, options) ⇒ Object



183
184
185
186
# File 'lib/trema/controller.rb', line 183

def send_flow_mod_delete(datapath_id, options)
  flow_mod = FlowMod.new(FlowModDeleteOption.new(options).to_hash)
  send_message datapath_id, flow_mod
end

#send_message(datapath_id, message) ⇒ Object



193
194
195
196
197
198
# File 'lib/trema/controller.rb', line 193

def send_message(datapath_id, message)
  Trema.logger.debug "Sending #{message.inspect}"
  SWITCH.fetch(datapath_id).write message
rescue KeyError, Errno::ECONNRESET, Errno::EPIPE
  logger.debug "Switch #{datapath_id} is disconnected."
end

#send_message_binary(datapath_id, binary) ⇒ Object



200
201
202
203
204
# File 'lib/trema/controller.rb', line 200

def send_message_binary(datapath_id, binary)
  SWITCH.fetch(datapath_id).write_binary binary
rescue KeyError, Errno::ECONNRESET, Errno::EPIPE
  logger.debug "Switch #{datapath_id} is disconnected."
end

#send_packet_out(datapath_id, options) ⇒ Object



188
189
190
191
# File 'lib/trema/controller.rb', line 188

def send_packet_out(datapath_id, options)
  packet_out = PacketOut.new(PacketOutOption.new(options).to_hash)
  send_message datapath_id, packet_out
end

#start(argv) ⇒ Object

Start event handler. Override this to implement a custom handler.



219
# File 'lib/trema/controller.rb', line 219

_handler :start

#stopObject



164
165
166
# File 'lib/trema/controller.rb', line 164

def stop
  @threads.map(&:kill)
end

#switch_ready(datapath_id) ⇒ Object

Switch Ready event handler. Override this to implement a custom handler.



225
# File 'lib/trema/controller.rb', line 225

_handler :switch_ready