openflow-controller 0.1.3 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/bin/ofctl +50 -0
  3. data/lib/controller.rb +43 -5
  4. metadata +1 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 109e1c4911c835a90566e9c2224d057e23f12468
4
- data.tar.gz: fecc6e282c364e83adba7df511c94b8c5139652d
3
+ metadata.gz: 3b55169812a488fa57a7c87739769f155f821614
4
+ data.tar.gz: 42f7ef4847a2f6858e5f486643accdc78bef68e9
5
5
  SHA512:
6
- metadata.gz: 761495183bcae351fa9bf46a316687f8b313e92e1c11088679c3aeb56261584eaa647a1fd9c582a6ee393bd8aedc7cb9f83db6ab1548b4ccd432bed2e656194f
7
- data.tar.gz: cfe6b8c90161837ac64dcd7507d5a07906bc6beda68de255280be5903ab2429f791a239c64407c8b1fddd7cc6ef8452b56c3a3024ff2ea93519ced28bcbca771
6
+ metadata.gz: ae798f44ea134543fcfbf0239bc1c6a3b995830e70babe2b3718d77c2467a9a3c1cbe6de15aa12e66ab52fc90b049ce3ecc43df0844031558528927b6a5384b4
7
+ data.tar.gz: 37be1296345a3d69b6441bd3c704027ff282669cef09649212c944fbfd04646725a41fa5bd1a04b36c8d7f0f06e00728062d9189de050484a5eae0a4780e8128
data/bin/ofctl CHANGED
@@ -1,7 +1,22 @@
1
1
  #!/usr/bin/env ruby
2
2
  require 'gli'
3
+ require 'readline'
3
4
  require_relative '../lib/controller'
4
5
 
6
+ PROMPT = '> '
7
+
8
+ def run_console(controller, ip, port, *args)
9
+ Thread.new { controller.run ip, port, args }
10
+
11
+ loop do
12
+ begin
13
+ puts " => #{eval(Readline.readline(PROMPT, true)).inspect}"
14
+ rescue StandardError => e
15
+ puts "#{e.class}: #{e.message}"
16
+ end
17
+ end
18
+ end
19
+
5
20
  module CommandLine
6
21
  extend GLI::App
7
22
 
@@ -35,6 +50,41 @@ module CommandLine
35
50
  end
36
51
  end
37
52
 
53
+ desc 'Runs a Simple OpenFlow Controller with REPL'
54
+ command :console do |c|
55
+ c.flag :ip,
56
+ desc: 'IP Address',
57
+ must_match: /\d+\.\d+\.\d+\.\d+/,
58
+ required: false,
59
+ default_value: OFController::DEFAULT_IP_ADDRESS
60
+ c.flag :port,
61
+ desc: 'Port Number',
62
+ type: Integer,
63
+ required: false,
64
+ default_value: OFController::DEFAULT_TCP_PORT
65
+ c.switch :debug,
66
+ desc: 'Run in Debug Mode',
67
+ default_value: false
68
+
69
+ c.action do |_global_options, options, args|
70
+ controller = if options[:debug]
71
+ OFController.new(Logger::DEBUG)
72
+ else
73
+ OFController.new
74
+ end
75
+
76
+ prompt = '> '
77
+ controller.logger.formatter = proc do |severity, datetime, _progname, msg|
78
+ buf = PROMPT + Readline::line_buffer
79
+ "\r" + ' ' * buf.length + "\r" +
80
+ "#{datetime} (#{severity}) -- #{msg}\n" +
81
+ buf
82
+ end
83
+
84
+ run_console controller, options[:ip], options[:port], args
85
+ end
86
+ end
87
+
38
88
  default_command :help
39
89
 
40
90
  exit run(ARGV)
data/lib/controller.rb CHANGED
@@ -31,6 +31,7 @@ class OFController
31
31
 
32
32
  def initialize(level = Logger::INFO)
33
33
  @switches = {}
34
+ @messages = {}
34
35
  @logger = Logger.new($stdout).tap do |logger|
35
36
  logger.formatter = proc do |severity, datetime, _progname, msg|
36
37
  "#{datetime} (#{severity}) -- #{msg}\n"
@@ -48,12 +49,41 @@ class OFController
48
49
  loop { start_switch_thread socket.accept }
49
50
  end
50
51
 
51
- def send_message(datapath_id, msg)
52
- @switches.fetch(datapath_id).send(msg)
52
+ def datapath_ids
53
+ @switches.keys
54
+ end
55
+
56
+ def send_message(datapath_id, msg = nil)
57
+ if msg.nil?
58
+ msg = datapath_id
59
+ datapath_id = datapath_ids.first
60
+ end
61
+ @switches.fetch(datapath_id.to_s).send(msg)
62
+ end
63
+
64
+ def broadcast(msg)
65
+ datapath_ids.each { |did| send_message did, msg }
66
+ end
67
+
68
+ def messages_for(datapath_id)
69
+ @messages.fetch(datapath_id.to_s)
70
+ end
71
+
72
+ def last_message_for(datapath_id)
73
+ messages_for(datapath_id).last
74
+ end
75
+
76
+ def messages
77
+ messages_for datapath_ids.first
78
+ end
79
+
80
+ def last_message
81
+ messages.last
53
82
  end
54
83
 
55
84
  def start(*_args) end
56
85
  def switch_ready(_datapath_id) end
86
+ def message_received(_datapath_id, _msg) end
57
87
  def error(_datapath_id, _msg) end
58
88
  def echo_request(datapath_id, msg)
59
89
  send_message datapath_id, OFEchoReply.new(xid: msg.xid)
@@ -94,7 +124,8 @@ class OFController
94
124
 
95
125
  def create_and_register_new_switch(socket)
96
126
  switch = OFSwitch.new(self, socket)
97
- @switches[switch.datapath_id] = switch
127
+ @messages[switch.datapath_id.to_s] = []
128
+ @switches[switch.datapath_id.to_s] = switch
98
129
  end
99
130
 
100
131
  def start_switch_main(datapath_id)
@@ -108,13 +139,20 @@ class OFController
108
139
  end
109
140
 
110
141
  def unregister_switch(datapath_id)
111
- @switches.delete(datapath_id)
142
+ @messages.delete(datapath_id.to_s)
143
+ @switches.delete(datapath_id.to_s)
112
144
  logger.info "Switch #{datapath_id} is disconnected."
113
145
  maybe_send_handler :switch_disconnected, datapath_id
114
146
  end
115
147
 
116
148
  def handle_openflow_message(datapath_id)
117
- msg = @switches.fetch(datapath_id).receive
149
+ msg = @switches.fetch(datapath_id.to_s).receive
150
+
151
+ unless msg.class == OFEchoRequest
152
+ logger.debug "Switch #{datapath_id} received #{msg.type} message."
153
+ @messages[datapath_id.to_s] << msg
154
+ maybe_send_handler :message_received, datapath_id, msg
155
+ end
118
156
 
119
157
  case msg
120
158
  when OFError
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: openflow-controller
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jérémy Pagé