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

SWITCH =
{}
DEFAULT_TCP_PORT =
6653

Class Attribute Summary collapse

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) ⇒ Controller



145
146
147
148
149
150
# File 'lib/trema/controller.rb', line 145

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

Class Attribute Details

.logging_levelObject

Returns the value of attribute logging_level



111
112
113
# File 'lib/trema/controller.rb', line 111

def logging_level
  @logging_level
end

Instance Attribute Details

#loggerLogger (readonly)



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

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) ⇒ Object



137
138
139
140
141
142
# File 'lib/trema/controller.rb', line 137

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

.inherited(subclass) ⇒ Object



132
133
134
# File 'lib/trema/controller.rb', line 132

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

.timer_event(handler, options) ⇒ Object



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

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

.timer_handlersObject



127
128
129
# File 'lib/trema/controller.rb', line 127

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



166
167
168
# File 'lib/trema/controller.rb', line 166

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.



156
157
158
159
160
161
162
163
164
# File 'lib/trema/controller.rb', line 156

def run(args)
  drb_socket_file =
    File.expand_path(File.join(Phut.socket_dir, "#{name}.ctl"))
  @drb = DRb::DRbServer.new 'drbunix:' + drb_socket_file, self
  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



177
178
179
180
181
182
183
184
185
186
187
188
# File 'lib/trema/controller.rb', line 177

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
      fail "Unsupported OpenFlow version: #{Pio::OpenFlow.version}"
    end
  send_message datapath_id, flow_mod
end

#send_flow_mod_delete(datapath_id, options) ⇒ Object



190
191
192
193
# File 'lib/trema/controller.rb', line 190

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



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

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

#send_packet_out(datapath_id, options) ⇒ Object



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

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



170
171
172
173
# File 'lib/trema/controller.rb', line 170

def stop
  @drb.stop_service if @drb
  @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