trema 0.4.3 → 0.4.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.
- data/.travis.yml +2 -0
- data/CONTRIBUTING.md +12 -0
- data/Gemfile +5 -3
- data/README.md +3 -3
- data/Rakefile +30 -14
- data/bin/trema +3 -0
- data/cruise.rb +1 -1
- data/features/examples/switch_monitor.feature +2 -2
- data/features/switch_event/add_forward_entry.feature +0 -1
- data/features/switch_event/delete_forward_entry.feature +0 -1
- data/features/switch_event/dump_forward_entries.feature +0 -1
- data/features/switch_event/set_forward_entries.feature +0 -1
- data/ruby/trema/command/run.rb +3 -0
- data/ruby/trema/dsl/runner.rb +1 -0
- data/ruby/trema/mac.rb +4 -145
- data/ruby/trema/match.c +8 -8
- data/ruby/trema/packet-in.c +12 -12
- data/ruby/trema/port-mod.c +7 -4
- data/ruby/trema/port.c +4 -1
- data/ruby/trema/set-eth-dst-addr.rb +3 -5
- data/ruby/trema/set-eth-src-addr.rb +5 -6
- data/ruby/trema/stats-reply.c +1 -1
- data/ruby/trema/switch-event.c +10 -10
- data/ruby/trema/trema.c +3 -0
- data/ruby/trema/version.rb +1 -1
- data/spec/spec_helper.rb +1 -1
- data/spec/trema/packet-in_spec.rb +2 -2
- data/spec/trema/set-eth-addr_spec.rb +5 -43
- data/src/examples/learning_switch/learning-switch.rb +2 -0
- data/src/lib/daemon.c +37 -22
- data/src/lib/log.c +31 -0
- data/src/lib/messenger.c +13 -5
- data/src/lib/trema.c +6 -5
- data/src/switch_manager/switch.c +178 -41
- data/src/switch_manager/switchinfo.h +6 -2
- data/trema.gemspec +3 -3
- data/unittests/lib/daemon_test.c +36 -36
- data/unittests/lib/trema_test.c +25 -8
- metadata +124 -96
- checksums.yaml +0 -7
- data/spec/trema/mac_spec.rb +0 -100
data/.travis.yml
CHANGED
data/CONTRIBUTING.md
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
# Contributing to Trema
|
2
|
+
|
3
|
+
* Check out the latest develop to make sure the feature hasn't been
|
4
|
+
implemented or the bug hasn't been fixed yet.
|
5
|
+
* Check out the issue tracker to make sure someone already hasn't
|
6
|
+
requested it and/or contributed it.
|
7
|
+
* Fork the project.
|
8
|
+
* Commit and push until you are happy with your contribution.
|
9
|
+
* Make sure to add tests for it. This is important so I don't break it
|
10
|
+
in a future version unintentionally.
|
11
|
+
* Squash your commits.
|
12
|
+
* Create a pull-request.
|
data/Gemfile
CHANGED
@@ -16,14 +16,16 @@ group :development do
|
|
16
16
|
gem "aruba", "~> 0.5.3"
|
17
17
|
gem "cucumber", "~> 1.3.8"
|
18
18
|
gem "flay", "~> 2.4.0"
|
19
|
-
gem "flog", "~> 4.
|
19
|
+
gem "flog", "~> 4.2.0"
|
20
20
|
gem "rcov", "~> 1.0.0" if RUBY_VERSION < "1.9.0"
|
21
21
|
gem "redcarpet", "~> 2.3.0" if RUBY_VERSION < "1.9.0"
|
22
22
|
gem "redcarpet", "~> 3.0.0" if RUBY_VERSION >= "1.9.0"
|
23
|
-
gem "reek", "~> 1.3.
|
23
|
+
gem "reek", "~> 1.3.4"
|
24
24
|
gem "relish", "~> 0.7"
|
25
25
|
gem "rspec", "~> 2.14.1"
|
26
|
-
gem "yard", "~> 0.8.7.
|
26
|
+
gem "yard", "~> 0.8.7.2"
|
27
|
+
gem 'mime-types', '~> 1.25' if RUBY_VERSION < '1.9.0'
|
28
|
+
gem 'mime-types', '~> 2.0' if RUBY_VERSION >= '1.9.0'
|
27
29
|
end
|
28
30
|
|
29
31
|
|
data/README.md
CHANGED
@@ -49,15 +49,15 @@ Getting Started
|
|
49
49
|
1.Install the prerequisites at the command prompt:
|
50
50
|
|
51
51
|
(In Ubuntu or Debian GNU/Linux)
|
52
|
-
$ sudo apt-get install gcc make ruby rubygems ruby-dev libpcap-dev libsqlite3-dev libglib2.0-dev
|
52
|
+
$ sudo apt-get install gcc make git ruby rubygems ruby-dev libpcap-dev libsqlite3-dev libglib2.0-dev
|
53
53
|
|
54
54
|
(In Ubuntu 10.04)
|
55
|
-
$ sudo apt-get install gcc make ruby rubygems ruby-dev libopenssl-ruby libpcap-dev libsqlite3-dev libglib2.0-dev
|
55
|
+
$ sudo apt-get install gcc make git ruby rubygems ruby-dev libopenssl-ruby libpcap-dev libsqlite3-dev libglib2.0-dev
|
56
56
|
$ sudo gem install rubygems-update
|
57
57
|
$ sudo /var/lib/gems/1.8/bin/update_rubygems
|
58
58
|
|
59
59
|
(In Fedora 16-19)
|
60
|
-
$ sudo yum install gcc make ruby rubygems ruby-devel libpcap-devel libsqlite3x-devel glib2-devel
|
60
|
+
$ sudo yum install gcc make git ruby rubygems ruby-devel libpcap-devel libsqlite3x-devel glib2-devel
|
61
61
|
|
62
62
|
2.Install Trema at the command prompt:
|
63
63
|
|
data/Rakefile
CHANGED
@@ -105,7 +105,7 @@ end
|
|
105
105
|
|
106
106
|
desc "Build Trema Ruby library."
|
107
107
|
task "rubylib" => "libtrema:static"
|
108
|
-
PaperHouse::
|
108
|
+
PaperHouse::RubyExtensionTask.new "rubylib" do | task |
|
109
109
|
task.library_name = "trema"
|
110
110
|
task.target_directory = Trema.ruby
|
111
111
|
task.sources = "#{ Trema.ruby }/trema/*.c"
|
@@ -191,8 +191,8 @@ file Trema.openflow_h => Trema.objects do
|
|
191
191
|
end
|
192
192
|
directory Trema.objects
|
193
193
|
|
194
|
-
CLOBBER.include
|
195
|
-
CLOBBER.include File.join( Trema.
|
194
|
+
CLOBBER.include( Trema.vendor_openflow ) if FileTest.exists?( Trema.vendor_openflow )
|
195
|
+
CLOBBER.include( File.join( Trema.objects, "openflow" ) ) if FileTest.exists?( File.join( Trema.objects, "openflow" ) )
|
196
196
|
|
197
197
|
|
198
198
|
################################################################################
|
@@ -205,6 +205,24 @@ def phost_src
|
|
205
205
|
File.join Trema.vendor_phost, "src"
|
206
206
|
end
|
207
207
|
|
208
|
+
def phost_objects
|
209
|
+
FileList[ File.join( phost_src, "*.o" ) ]
|
210
|
+
end
|
211
|
+
|
212
|
+
def phost_vendor_binary
|
213
|
+
File.join phost_src, "phost"
|
214
|
+
end
|
215
|
+
|
216
|
+
def phost_cli_vendor_binary
|
217
|
+
File.join phost_src, "cli"
|
218
|
+
end
|
219
|
+
|
220
|
+
def phost_clean_targets
|
221
|
+
( phost_objects + [ phost_vendor_binary, phost_cli_vendor_binary ] ).select do | each |
|
222
|
+
FileTest.exists? each
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
208
226
|
file Trema::Executables.phost do
|
209
227
|
cd phost_src do
|
210
228
|
sh "make"
|
@@ -221,10 +239,8 @@ file Trema::Executables.cli do
|
|
221
239
|
install File.join( phost_src, "cli" ), Trema::Executables.cli, :mode => 0755
|
222
240
|
end
|
223
241
|
|
224
|
-
CLEAN.include
|
225
|
-
|
226
|
-
CLEAN.include File.join( phost_src, "cli" )
|
227
|
-
CLOBBER.include Trema.phost
|
242
|
+
CLEAN.include phost_clean_targets
|
243
|
+
CLOBBER.include( Trema.phost ) if FileTest.exists?( Trema.phost )
|
228
244
|
|
229
245
|
|
230
246
|
################################################################################
|
@@ -253,8 +269,8 @@ file Trema::Executables.ovs_openflowd do
|
|
253
269
|
end
|
254
270
|
end
|
255
271
|
|
256
|
-
CLEAN.include Trema.vendor_openvswitch
|
257
|
-
CLOBBER.include Trema.openvswitch
|
272
|
+
CLEAN.include( Trema.vendor_openvswitch ) if FileTest.exists?( Trema.vendor_openvswitch )
|
273
|
+
CLOBBER.include( Trema.openvswitch ) if FileTest.exists?( Trema.openvswitch )
|
258
274
|
|
259
275
|
|
260
276
|
################################################################################
|
@@ -298,8 +314,8 @@ file cbench_command => Trema.openflow_h do
|
|
298
314
|
end
|
299
315
|
end
|
300
316
|
|
301
|
-
CLEAN.include Trema.oflops
|
302
|
-
CLOBBER.include Trema.vendor_oflops
|
317
|
+
CLEAN.include( Trema.oflops ) if FileTest.exists?( Trema.oflops )
|
318
|
+
CLOBBER.include( Trema.vendor_oflops ) if FileTest.exists?( Trema.vendor_oflops )
|
303
319
|
|
304
320
|
|
305
321
|
################################################################################
|
@@ -315,8 +331,8 @@ file Trema.libcmockery_a do
|
|
315
331
|
end
|
316
332
|
end
|
317
333
|
|
318
|
-
CLEAN.include Trema.vendor_cmockery
|
319
|
-
CLOBBER.include Trema.cmockery
|
334
|
+
CLEAN.include( Trema.vendor_cmockery ) if FileTest.exists?( Trema.vendor_cmockery )
|
335
|
+
CLOBBER.include( Trema.cmockery ) if FileTest.exists?( Trema.cmockery )
|
320
336
|
|
321
337
|
|
322
338
|
################################################################################
|
@@ -736,7 +752,7 @@ directory $wireshark_plugins_dir
|
|
736
752
|
|
737
753
|
task :openflow_wireshark_plugin => $wireshark_plugin
|
738
754
|
|
739
|
-
CLEAN.include Trema.vendor_openflow_git
|
755
|
+
CLEAN.include( Trema.vendor_openflow_git ) if FileTest.exists?( Trema.vendor_openflow_git )
|
740
756
|
|
741
757
|
|
742
758
|
################################################################################
|
data/bin/trema
CHANGED
@@ -60,6 +60,9 @@ class BinTrema
|
|
60
60
|
c.desc "Specifies emulated network configuration"
|
61
61
|
c.flag [ :c, :conf ]
|
62
62
|
|
63
|
+
c.desc "Disables initial flow cleanup for a connected switch"
|
64
|
+
c.switch [ :r, :no_flow_cleanup ], :negatable => false
|
65
|
+
|
63
66
|
c.action do | global_options, options, args |
|
64
67
|
trema_run options
|
65
68
|
end
|
data/cruise.rb
CHANGED
@@ -17,7 +17,7 @@ Feature: "Switch Monitor" sample application
|
|
17
17
|
Given I run `trema run ../../objects/examples/switch_monitor/switch_monitor -c switch_monitor.conf -d`
|
18
18
|
And wait until "switch_monitor" is up
|
19
19
|
When I run `trema kill 0x3`
|
20
|
-
And *** sleep
|
20
|
+
And *** sleep 2 ***
|
21
21
|
Then the file "../../tmp/log/switch_monitor.log" should contain "Switch 0x3 is DOWN"
|
22
22
|
When I run `trema up 0x3`
|
23
23
|
And *** sleep 10 ***
|
@@ -28,7 +28,7 @@ Feature: "Switch Monitor" sample application
|
|
28
28
|
Given I run `trema run ../../src/examples/switch_monitor/switch-monitor.rb -c switch_monitor.conf -d`
|
29
29
|
And wait until "SwitchMonitor" is up
|
30
30
|
When I run `trema kill 0x3`
|
31
|
-
And *** sleep
|
31
|
+
And *** sleep 2 ***
|
32
32
|
Then the file "../../tmp/log/SwitchMonitor.log" should contain "Switch 0x3 is DOWN"
|
33
33
|
When I run `trema up 0x3`
|
34
34
|
And *** sleep 10 ***
|
data/ruby/trema/command/run.rb
CHANGED
data/ruby/trema/dsl/runner.rb
CHANGED
data/ruby/trema/mac.rb
CHANGED
@@ -16,154 +16,12 @@
|
|
16
16
|
#
|
17
17
|
|
18
18
|
|
19
|
-
require "
|
19
|
+
require "rubygems"
|
20
|
+
require "pio"
|
20
21
|
|
21
22
|
|
22
23
|
module Trema
|
23
|
-
|
24
|
-
# Ethernet address class
|
25
|
-
#
|
26
|
-
class Mac
|
27
|
-
extend Forwardable
|
28
|
-
def_delegator :@value, :hash
|
29
|
-
|
30
|
-
|
31
|
-
#
|
32
|
-
# Returns an Ethernet address in its numeric presentation.
|
33
|
-
#
|
34
|
-
# @example
|
35
|
-
# Mac.new("11:22:33:44:55:66") #=> 18838586676582
|
36
|
-
#
|
37
|
-
# @return [Number] the Ethernet address in numeric format
|
38
|
-
#
|
39
|
-
attr_reader :value
|
40
|
-
|
41
|
-
|
42
|
-
#
|
43
|
-
# Creates a {Mac} instance that encapsulates Ethernet addresses.
|
44
|
-
#
|
45
|
-
# @overload initialize(value)
|
46
|
-
#
|
47
|
-
# @param [String,Integer] value
|
48
|
-
# the Ethernet address to set to.
|
49
|
-
#
|
50
|
-
# @example address as a hexadecimal string
|
51
|
-
# Mac.new("11:22:33:44:55:66")
|
52
|
-
#
|
53
|
-
# @example address as a hexadecimal number
|
54
|
-
# Mac.new(0xffffffffffff)
|
55
|
-
#
|
56
|
-
# @raise [ArgumentError] if invalid format is detected.
|
57
|
-
# @raise [TypeError] if supplied argument is not a String or Integer.
|
58
|
-
#
|
59
|
-
def initialize value
|
60
|
-
case value
|
61
|
-
when String
|
62
|
-
@value = create_from( value )
|
63
|
-
when Integer
|
64
|
-
@value = value
|
65
|
-
validate_value_range
|
66
|
-
when Mac
|
67
|
-
@value = create_from( value.to_s )
|
68
|
-
else
|
69
|
-
raise TypeError, "Invalid MAC address: #{ value.inspect }"
|
70
|
-
end
|
71
|
-
@string = string_format
|
72
|
-
end
|
73
|
-
|
74
|
-
|
75
|
-
#
|
76
|
-
# Returns the Ethernet address as 6 pairs of hexadecimal digits
|
77
|
-
# delimited by colons.
|
78
|
-
#
|
79
|
-
# @example
|
80
|
-
# Mac.new(18838586676582).to_s #=> "11:22:33:44:55:66"
|
81
|
-
#
|
82
|
-
# @return [String] the Ethernet address in String format
|
83
|
-
#
|
84
|
-
def to_s
|
85
|
-
@string
|
86
|
-
end
|
87
|
-
|
88
|
-
|
89
|
-
#
|
90
|
-
# Returns an array of decimal numbers converted from Ethernet's
|
91
|
-
# address string format.
|
92
|
-
#
|
93
|
-
# @example
|
94
|
-
# Mac.new("11:22:33:44:55:66").to_a #=> [ 0x11, 0x22, 0x33, 0x44, 0x55, 0x66 ]
|
95
|
-
#
|
96
|
-
# @return [Array] the Ethernet address in Array format
|
97
|
-
#
|
98
|
-
def to_a
|
99
|
-
@string.split( ":" ).collect do | each |
|
100
|
-
each.hex
|
101
|
-
end
|
102
|
-
end
|
103
|
-
|
104
|
-
|
105
|
-
#
|
106
|
-
# @private
|
107
|
-
#
|
108
|
-
def == other
|
109
|
-
@value == other.value
|
110
|
-
end
|
111
|
-
alias :eql? :==
|
112
|
-
|
113
|
-
|
114
|
-
#
|
115
|
-
# Returns true if Ethernet address is a multicast address.
|
116
|
-
#
|
117
|
-
# @example
|
118
|
-
# Mac.new("01:00:00:00:00:00").multicast? #=> true
|
119
|
-
# Mac.new("00:00:00:00:00:00").multicast? #=> false
|
120
|
-
#
|
121
|
-
# @return [Boolean] whether the Ethernet address is multicast
|
122
|
-
#
|
123
|
-
def multicast?
|
124
|
-
to_a[ 0 ] & 1 == 1
|
125
|
-
end
|
126
|
-
|
127
|
-
|
128
|
-
#
|
129
|
-
# Returns true if Ethernet address is a broadcast address.
|
130
|
-
#
|
131
|
-
# @example
|
132
|
-
# Mac.new("ff:ff:ff:ff:ff:ff").broadcast? #=> true
|
133
|
-
#
|
134
|
-
# @return [Boolean] whether the Ethernet address is broadcast
|
135
|
-
#
|
136
|
-
def broadcast?
|
137
|
-
to_a.all? { | each | each == 0xff }
|
138
|
-
end
|
139
|
-
|
140
|
-
|
141
|
-
################################################################################
|
142
|
-
private
|
143
|
-
################################################################################
|
144
|
-
|
145
|
-
|
146
|
-
def create_from string
|
147
|
-
octet_regex = "[0-9a-fA-F][0-9a-fA-F]"
|
148
|
-
if /^(#{ octet_regex }:){5}(#{ octet_regex })$/=~ string
|
149
|
-
string.gsub( ":", "" ).hex
|
150
|
-
else
|
151
|
-
raise ArgumentError, %{Invalid MAC address: "#{ string }"}
|
152
|
-
end
|
153
|
-
end
|
154
|
-
|
155
|
-
|
156
|
-
def validate_value_range
|
157
|
-
unless ( @value >= 0 and @value <= 0xffffffffffff )
|
158
|
-
raise ArgumentError, "Invalid MAC address: #{ @value }"
|
159
|
-
end
|
160
|
-
end
|
161
|
-
|
162
|
-
|
163
|
-
def string_format
|
164
|
-
sprintf( "%012x", @value ).unpack( "a2" * 6 ).join( ":" )
|
165
|
-
end
|
166
|
-
end
|
24
|
+
Mac = Pio::Mac
|
167
25
|
end
|
168
26
|
|
169
27
|
|
@@ -172,3 +30,4 @@ end
|
|
172
30
|
### coding: utf-8-unix
|
173
31
|
### indent-tabs-mode: nil
|
174
32
|
### End:
|
33
|
+
|
data/ruby/trema/match.c
CHANGED
@@ -238,7 +238,7 @@ match_dl( VALUE self, uint8_t which ) {
|
|
238
238
|
else {
|
239
239
|
dl_addr = match->dl_dst;
|
240
240
|
}
|
241
|
-
return rb_funcall( rb_eval_string( "
|
241
|
+
return rb_funcall( rb_eval_string( "Pio::Mac" ), rb_intern( "new" ), 1, ULL2NUM( mac_to_uint64( dl_addr ) ) );
|
242
242
|
}
|
243
243
|
|
244
244
|
|
@@ -395,16 +395,16 @@ match_tp_dst( VALUE self ) {
|
|
395
395
|
* @option options [Number] :in_port
|
396
396
|
* the physical port number to match.
|
397
397
|
*
|
398
|
-
* @option options [String,Number,
|
398
|
+
* @option options [String,Number,Mac] :dl_src
|
399
399
|
* the source ethernet address to match specified either as 6
|
400
400
|
* pairs of hexadecimal digits delimited by colon or as a
|
401
|
-
* hexadecimal number or as a
|
401
|
+
* hexadecimal number or as a Mac object.
|
402
402
|
* (eg. "00:11:22:33:44:55" or 0x001122334455 or Mac.new("00:11:22:33:44:55")).
|
403
403
|
*
|
404
404
|
* @option options [String,Number] :dl_dst
|
405
405
|
* the destination ethernet address to match specified either as a
|
406
406
|
* 6 pairs of hexadecimal digits delimited by colon or as a
|
407
|
-
* hexadecimal number or as a
|
407
|
+
* hexadecimal number or as a Mac object.
|
408
408
|
* (eg. "00:11:22:33:44:55" or 0x001122334455 or Mac.new("00:11:22:33:44:55")).
|
409
409
|
*
|
410
410
|
* @option options [Number] :dl_type
|
@@ -472,11 +472,11 @@ match_init( int argc, VALUE *argv, VALUE self ) {
|
|
472
472
|
VALUE dl_src = rb_hash_aref( options, ID2SYM( rb_intern( "dl_src" ) ) );
|
473
473
|
if ( dl_src != Qnil ) {
|
474
474
|
VALUE dl_addr;
|
475
|
-
if ( rb_obj_is_kind_of( dl_src, rb_eval_string( "
|
475
|
+
if ( rb_obj_is_kind_of( dl_src, rb_eval_string( "Pio::Mac" ) ) ) {
|
476
476
|
dl_addr = dl_src;
|
477
477
|
}
|
478
478
|
else {
|
479
|
-
dl_addr = rb_funcall( rb_eval_string( "
|
479
|
+
dl_addr = rb_funcall( rb_eval_string( "Pio::Mac" ), rb_intern( "new" ), 1, dl_src );
|
480
480
|
}
|
481
481
|
dl_addr_to_a( dl_addr, match->dl_src );
|
482
482
|
match->wildcards &= ( uint32_t ) ~OFPFW_DL_SRC;
|
@@ -485,11 +485,11 @@ match_init( int argc, VALUE *argv, VALUE self ) {
|
|
485
485
|
VALUE dl_dst = rb_hash_aref( options, ID2SYM( rb_intern( "dl_dst" ) ) );
|
486
486
|
if ( dl_dst != Qnil ) {
|
487
487
|
VALUE dl_addr;
|
488
|
-
if ( rb_obj_is_kind_of( dl_dst, rb_eval_string( "
|
488
|
+
if ( rb_obj_is_kind_of( dl_dst, rb_eval_string( "Pio::Mac" ) ) ) {
|
489
489
|
dl_addr = dl_dst;
|
490
490
|
}
|
491
491
|
else {
|
492
|
-
dl_addr = rb_funcall( rb_eval_string( "
|
492
|
+
dl_addr = rb_funcall( rb_eval_string( "Pio::Mac" ), rb_intern( "new" ), 1, dl_dst );
|
493
493
|
}
|
494
494
|
dl_addr_to_a( dl_addr, match->dl_dst );
|
495
495
|
match->wildcards &= ( uint32_t ) ~OFPFW_DL_DST;
|