trema 0.1.3.2 → 0.2.0

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/ruby/trema/util.rb CHANGED
@@ -50,6 +50,11 @@ EOF
50
50
 
51
51
 
52
52
  def cleanup session
53
+ # [FIXME] Use session.switch_manager
54
+ sm_pid = File.join( Trema.pid, "switch_manager.pid" )
55
+ if FileTest.exist?( sm_pid )
56
+ Trema::Process.read( sm_pid ).kill!
57
+ end
53
58
  session.apps.each do | name, app |
54
59
  app.shutdown!
55
60
  end
@@ -63,7 +68,7 @@ EOF
63
68
  link.delete!
64
69
  end
65
70
 
66
- Dir.glob( File.join Trema.pid_directory, "*.pid" ).each do | each |
71
+ Dir.glob( File.join Trema.pid, "*.pid" ).each do | each |
67
72
  Trema::Process.read( each ).kill!
68
73
  end
69
74
 
@@ -20,6 +20,7 @@
20
20
 
21
21
  require File.join( File.dirname( __FILE__ ), "..", "..", "spec_helper" )
22
22
  require "trema/dsl/runner"
23
+ require "trema/ordered-hash"
23
24
 
24
25
 
25
26
  module Trema
@@ -128,13 +129,25 @@ module Trema
128
129
  host2 = mock( "host2" )
129
130
 
130
131
  host0.should_receive( :run! ).once.ordered
131
- host0.should_receive( :add_arp_entry ).with( [ host1, host2 ] ).once.ordered
132
+ host0.should_receive( :add_arp_entry ).with do | arg |
133
+ arg.size.should == 2
134
+ arg.should include( host1 )
135
+ arg.should include( host2 )
136
+ end
132
137
 
133
138
  host1.should_receive( :run! ).once.ordered
134
- host1.should_receive( :add_arp_entry ).with( [ host0, host2 ] ).once.ordered
139
+ host1.should_receive( :add_arp_entry ).with do | arg |
140
+ arg.size.should == 2
141
+ arg.should include( host0 )
142
+ arg.should include( host2 )
143
+ end
135
144
 
136
145
  host2.should_receive( :run! ).once.ordered
137
- host2.should_receive( :add_arp_entry ).with( [ host0, host1 ] ).once.ordered
146
+ host2.should_receive( :add_arp_entry ).with do | arg |
147
+ arg.size.should == 2
148
+ arg.should include( host0 )
149
+ arg.should include( host1 )
150
+ end
138
151
 
139
152
  context = mock(
140
153
  "context",
@@ -179,14 +192,19 @@ module Trema
179
192
 
180
193
 
181
194
  it "should run apps" do
182
- app0 = mock( "app0" )
195
+ apps = OrderedHash.new
196
+
197
+ app0 = mock( "app0", :name => "app0" )
183
198
  app0.should_receive( :daemonize! ).once.ordered
199
+ apps[ "app0" ] = app0
184
200
 
185
- app1 = mock( "app1" )
201
+ app1 = mock( "app1", :name => "app1" )
186
202
  app1.should_receive( :daemonize! ).once.ordered
203
+ apps[ "app1" ] = app1
187
204
 
188
- app2 = mock( "app2", :name => "App2" )
205
+ app2 = mock( "app2", :name => "app2" )
189
206
  app2.should_receive( :run! ).once.ordered
207
+ apps[ "app2" ] = app2
190
208
 
191
209
  context = mock(
192
210
  "context",
@@ -196,7 +214,7 @@ module Trema
196
214
  :links => {},
197
215
  :hosts => {},
198
216
  :switches => {},
199
- :apps => { "app0" => app0, "app1" => app1, "app2" => app2 }
217
+ :apps => apps
200
218
  )
201
219
 
202
220
  Runner.new( context ).run
@@ -204,14 +222,19 @@ module Trema
204
222
 
205
223
 
206
224
  it "should daemonize apps" do
225
+ apps = OrderedHash.new
226
+
207
227
  app0 = mock( "app0" )
208
228
  app0.should_receive( :daemonize! ).once.ordered
229
+ apps[ "app0" ] = app0
209
230
 
210
231
  app1 = mock( "app1" )
211
232
  app1.should_receive( :daemonize! ).once.ordered
233
+ apps[ "app1" ] = app1
212
234
 
213
235
  app2 = mock( "app2", :name => "App2" )
214
236
  app2.should_receive( :daemonize! ).once.ordered
237
+ apps[ "app2" ] = app2
215
238
 
216
239
  context = mock(
217
240
  "context",
@@ -221,7 +244,7 @@ module Trema
221
244
  :links => {},
222
245
  :hosts => {},
223
246
  :switches => {},
224
- :apps => { "app0" => app0, "app1" => app1, "app2" => app2 }
247
+ :apps => apps
225
248
  )
226
249
 
227
250
  Runner.new( context ).daemonize
@@ -59,7 +59,7 @@ describe EchoRequest, ".new( VALID OPTIONS )" do
59
59
  }.run( EchoRequestController ) {
60
60
  echo_request = EchoRequest.new( :transaction_id => 1234, :user_data => 'this is a test' )
61
61
  controller( "EchoRequestController" ).send_message( 0xabc, echo_request )
62
- log_file = Trema.log_directory + "/openflowd.echo_request.log"
62
+ log_file = Trema.log + "/openflowd.echo_request.log"
63
63
  IO.read( log_file ).should include( "OFPT_ECHO_REPLY" )
64
64
  sleep 1
65
65
  }
@@ -23,47 +23,28 @@ require "trema/executables"
23
23
 
24
24
 
25
25
  describe Trema::Executables do
26
- it "should know the path of tremashark executable" do
27
- Trema::Executables.should respond_to( :tremashark )
28
- end
29
-
30
-
31
- it "should know the path of switch_manager executable" do
32
- Trema::Executables.should respond_to( :switch_manager )
33
- end
34
-
35
-
36
- it "should know the path of switch_manager executable" do
37
- Trema::Executables.should respond_to( :switch_manager )
38
- end
39
-
40
-
41
- it "should know the path of packetin_filter executable" do
42
- Trema::Executables.should respond_to( :packetin_filter )
43
- end
44
-
45
-
46
- it "should know the path of phost executable" do
47
- Trema::Executables.should respond_to( :phost )
48
- end
49
-
50
-
51
- it "should know the path of phost's cli executable" do
52
- Trema::Executables.should respond_to( :cli )
53
- end
54
-
55
-
56
- it "should know the path of ovs-openflowd executable" do
57
- Trema::Executables.should respond_to( :ovs_openflowd )
58
- end
59
-
60
-
61
- it "should detect if all executables are compled or not" do
62
- FileTest.stub!( :executable? ).and_return( true )
63
- Trema::Executables.compiled?.should be_true
64
-
65
- FileTest.stub!( :executable? ).and_return( false )
66
- Trema::Executables.compiled?.should be_false
26
+ subject { Trema::Executables }
27
+
28
+ its ( :cli ) { should be_a( String ) }
29
+ its ( :ovs_ofctl ) { should be_a( String ) }
30
+ its ( :ovs_openflowd ) { should be_a( String ) }
31
+ its ( :packet_capture ) { should be_a( String ) }
32
+ its ( :packetin_filter ) { should be_a( String ) }
33
+ its ( :phost ) { should be_a( String ) }
34
+ its ( :stdin_relay ) { should be_a( String ) }
35
+ its ( :switch ) { should be_a( String ) }
36
+ its ( :switch_manager ) { should be_a( String ) }
37
+ its ( :syslog_relay ) { should be_a( String ) }
38
+ its ( :tremashark ) { should be_a( String ) }
39
+
40
+ context "when Trema is compiled" do
41
+ before { FileTest.stub!( :executable? ).and_return( true ) }
42
+ its ( :compiled? ) { should be_true }
43
+ end
44
+
45
+ context "when Trema is not compiled" do
46
+ before { FileTest.stub!( :executable? ).and_return( false ) }
47
+ its ( :compiled? ) { should be_false }
67
48
  end
68
49
  end
69
50
 
@@ -1,4 +1,4 @@
1
- #
1
+
2
2
  # Author: Nick Karanatsios <nickkaranatsios@gmail.com>
3
3
  #
4
4
  # Copyright (C) 2008-2012 NEC Corporation
@@ -31,9 +31,23 @@ describe Trema::PacketIn do
31
31
 
32
32
  class PacketInController < Controller; end
33
33
 
34
+ class PacketInSendController < Controller
35
+ def packet_in datapath_id, message
36
+ send_flow_mod_add(
37
+ datapath_id,
38
+ :match => Match.from( message ),
39
+ :actions => Trema::ActionOutput.new( :port => 2 )
40
+ )
41
+ send_packet_out(
42
+ datapath_id,
43
+ :packet_in => message,
44
+ :actions => Trema::ActionOutput.new( :port => 2 )
45
+ )
46
+ end
47
+ end
34
48
 
35
49
  context "when instance is created" do
36
- it "should have valid datapath_id" do
50
+ it "should have valid datapath_id and in_port" do
37
51
  network {
38
52
  vswitch( "test" ) { datapath_id 0xabc }
39
53
  vhost "host1"
@@ -44,17 +58,20 @@ describe Trema::PacketIn do
44
58
  controller( "PacketInController" ).should_receive( :packet_in ) do | datapath_id, message |
45
59
  datapath_id.should == 0xabc
46
60
  message.datapath_id.should == 0xabc
61
+ message.in_port.should > 0
47
62
  end
48
63
  send_and_wait
49
64
  }
50
65
  end
51
66
 
52
67
 
53
- it "should have user data" do
68
+ it "should have vaild user data" do
54
69
  network {
55
70
  vswitch( "test" ) { datapath_id 0xabc }
56
- vhost "host1"
57
- vhost "host2"
71
+ vhost( "host1" ) { mac "00:00:00:00:00:01"
72
+ ip "192.168.1.1" }
73
+ vhost( "host2" ) { mac "00:00:00:00:00:02"
74
+ ip "192.168.1.2" }
58
75
  link "test", "host1"
59
76
  link "test", "host2"
60
77
  }.run( PacketInController ) {
@@ -63,103 +80,394 @@ describe Trema::PacketIn do
63
80
  message.total_len.should > 20
64
81
  message.data.should be_instance_of( String )
65
82
  message.buffered?.should be_false
83
+
84
+ message.macsa.should be_instance_of( Trema::Mac )
85
+ message.macsa.to_s.should == "00:00:00:00:00:01"
86
+ message.macda.should be_instance_of( Trema::Mac )
87
+ message.macda.to_s.should == "00:00:00:00:00:02"
88
+
89
+ message.eth_type.should == 0x0800
90
+ message.ipv4?.should == true
91
+ message.ipv4_version.should == 4
92
+ message.ipv4_saddr.should be_instance_of( Trema::IP )
93
+ message.ipv4_saddr.to_s.should == "192.168.1.1"
94
+ message.ipv4_daddr.should be_instance_of( Trema::IP )
95
+ message.ipv4_daddr.to_s.should == "192.168.1.2"
66
96
  end
67
97
  send_and_wait
68
98
  }
69
99
  end
100
+ end
70
101
 
71
-
72
- it "should have user L2 information (macsa)" do
102
+ context "when reading packet content" do
103
+ it "should have correct ARP packet fields" do
73
104
  network {
74
- vswitch( "test" ) { datapath_id 0xabc }
75
- vhost( "host1" ) { mac "00:00:00:00:00:01" }
76
- vhost( "host2" ) { mac "00:00:00:00:00:02" }
77
- link "test", "host1"
78
- link "test", "host2"
79
- }.run( PacketInController ) {
80
- controller( "PacketInController" ).should_receive( :packet_in ) do | datapath_id, message |
81
- message.macsa.should be_instance_of( Trema::Mac )
82
- message.macsa.to_s.should == "00:00:00:00:00:01"
105
+ vswitch( "packet-in" ) { datapath_id 0xabc }
106
+ vhost "host1"
107
+ vhost ( "host2" ) { mac "00:00:00:00:00:02" }
108
+ link "host1", "packet-in"
109
+ link "host2", "packet-in"
110
+ }.run( PacketInSendController ) {
111
+ data = [
112
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, # dst
113
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, # src
114
+ 0x08, 0x06, # ether type
115
+ # arp
116
+ 0x00, 0x01, # hardware type
117
+ 0x08, 0x00, # protocol type
118
+ 0x06, # hardware address length
119
+ 0x04, # protocol address length
120
+ 0x00, 0x02, # operation
121
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, # sender hardware address
122
+ 0xc0, 0xa8, 0x00, 0x01, # sender protocol address
123
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, # target hardware address
124
+ 0xc0, 0xa8, 0x00, 0x02, # target protocol address
125
+ # padding to 64 bytes
126
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
127
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
128
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
129
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
130
+ 0x00, 0x00
131
+ ].pack( "C*" )
132
+ controller( "PacketInSendController" ).should_receive( :packet_in ) do | datapath_id, message |
133
+ message.in_port.should > 0
134
+ message.vtag?.should be_false
135
+ message.arp?.should be_true
136
+ message.ipv4?.should be_false
137
+ message.tcp?.should be_false
138
+ message.udp?.should be_false
139
+ message.icmpv4?.should be_false
140
+ message.igmp?.should be_false
141
+
142
+ message.arp_oper.should == 2
143
+ message.arp_sha.to_s.should == "00:00:00:00:00:01"
144
+ message.arp_spa.to_s.should == "192.168.0.1"
145
+ message.arp_tha.to_s.should == "00:00:00:00:00:02"
146
+ message.arp_tpa.to_s.should == "192.168.0.2"
83
147
  end
84
- send_and_wait
148
+
149
+ controller( "PacketInSendController" ).send_packet_out(
150
+ 0xabc,
151
+ :data => data,
152
+ :actions => Trema::ActionOutput.new( :port => Controller::OFPP_CONTROLLER )
153
+ )
154
+ sleep 2
85
155
  }
86
156
  end
87
-
88
157
 
89
- it "should have user L2 information (macda)" do
158
+ it "should have correct TCP packet fields" do
90
159
  network {
91
- vswitch( "test" ) { datapath_id 0xabc }
92
- vhost( "host1" ) { mac "00:00:00:00:00:01" }
93
- vhost( "host2" ) { mac "00:00:00:00:00:02" }
94
- link "test", "host1"
95
- link "test", "host2"
96
- }.run( PacketInController ) {
97
- controller( "PacketInController" ).should_receive( :packet_in ) do | datapath_id, message |
98
- message.macda.should be_instance_of( Trema::Mac )
99
- message.macda.to_s.should == "00:00:00:00:00:02"
160
+ vswitch( "packet-in" ) { datapath_id 0xabc }
161
+ vhost "host1"
162
+ vhost ( "host2" ) {
163
+ ip "192.168.0.2"
164
+ netmask "255.255.0.0"
165
+ mac "00:00:00:00:00:02"
166
+ }
167
+ link "host1", "packet-in"
168
+ link "host2", "packet-in"
169
+ }.run( PacketInSendController ) {
170
+ data = [
171
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, # dst
172
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, # src
173
+ 0x08, 0x00, # ether type
174
+ # ipv4
175
+ 0x45, 0x00, # version
176
+ 0x00, 0x28, # length
177
+ 0x00, 0x00,
178
+ 0x00, 0x00,
179
+ 0x00, # ttl
180
+ 0x06, # protocol
181
+ 0x39, 0x7d, # checksum
182
+ 0xc0, 0xa8, 0x00, 0x01, # src
183
+ 0xc0, 0xa8, 0x00, 0x02, # dst
184
+ # tcp
185
+ 0x00, 0x01, # src port
186
+ 0x00, 0x02, # dst port
187
+ 0x00, 0x00, 0x00, 0x00, # sequence number
188
+ 0x00, 0x00, 0x00, 0x00, # acknowledgement number
189
+ 0x50, # data offset,
190
+ 0x00, # flags
191
+ 0x00, 0x00, # window size
192
+ 0x2e, 0x86, # checksum
193
+ 0x00, 0x00, # urgent pointer
194
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
195
+ ].pack( "C*" )
196
+ controller( "PacketInSendController" ).should_receive( :packet_in ) do | datapath_id, message |
197
+ message.in_port.should > 0
198
+ message.vtag?.should be_false
199
+ message.arp?.should be_false
200
+ message.ipv4?.should be_true
201
+ message.udp?.should be_false
202
+ message.tcp?.should be_true
203
+ message.icmpv4?.should be_false
204
+ message.igmp?.should be_false
205
+
206
+ message.ipv4_version.should == 4
207
+ message.ipv4_ihl.should == 5
208
+ message.ipv4_tos.should == 0
209
+ message.ipv4_tot_len.should == 0x28
210
+ message.ipv4_id.should == 0
211
+ message.ipv4_frag_off.should == 0
212
+ message.ipv4_ttl.should == 0
213
+ message.ipv4_protocol.should == 6
214
+ message.ipv4_checksum.should == 0x397d
215
+ message.ipv4_saddr.to_s.should == "192.168.0.1"
216
+ message.ipv4_daddr.to_s.should == "192.168.0.2"
217
+
218
+ message.tcp_src_port.should == 1
219
+ message.tcp_dst_port.should == 2
220
+ message.tcp_seq_no.should == 0
221
+ message.tcp_ack_no.should == 0
222
+ message.tcp_offset.should == 5
223
+ message.tcp_flags.should == 0
224
+ message.tcp_window.should == 0
225
+ message.tcp_checksum.should == 11910 # 0x2e86
226
+ message.tcp_urgent.should == 0
100
227
  end
101
- send_and_wait
228
+
229
+ controller( "PacketInSendController" ).send_packet_out(
230
+ 0xabc,
231
+ :data => data,
232
+ :actions => Trema::ActionOutput.new( :port => Controller::OFPP_CONTROLLER )
233
+ )
234
+ sleep 2
102
235
  }
103
236
  end
104
237
 
105
-
106
- it "should have user L3 information" do
238
+ it "should have correct UDP packet fields" do
107
239
  network {
108
- vswitch( "test" ) { datapath_id 0xabc }
109
- vhost( "host1" ) { ip "192.168.1.1" }
110
- vhost( "host2" ) { ip "192.168.1.2" }
111
- link "test", "host1"
112
- link "test", "host2"
113
- }.run( PacketInController ) {
114
- controller( "PacketInController" ).should_receive( :packet_in ) do | datapath_id, message |
115
- message.eth_type.should == 0x0800
116
- message.ipv4?.should == true
240
+ vswitch( "packet-in" ) { datapath_id 0xabc }
241
+ vhost "host1"
242
+ vhost ( "host2" ) {
243
+ ip "192.168.0.2"
244
+ netmask "255.255.0.0"
245
+ mac "00:00:00:00:00:02"
246
+ }
247
+ link "host1", "packet-in"
248
+ link "host2", "packet-in"
249
+ }.run( PacketInSendController ) {
250
+ data = [
251
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, # dst
252
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, # src
253
+ 0x08, 0x00, # ether type
254
+ # ipv4
255
+ 0x45, 0x00, # version
256
+ 0x00, 0x32, # length
257
+ 0x00, 0x00,
258
+ 0x00, 0x00,
259
+ 0x40, # ttl
260
+ 0x11, # protocol
261
+ 0xf9, 0x68, # checksum
262
+ 0xc0, 0xa8, 0x00, 0x01, # src
263
+ 0xc0, 0xa8, 0x00, 0x02, # dst
264
+ # udp
265
+ 0x00, 0x01, # src port
266
+ 0x00, 0x02, # dst port
267
+ 0x00, 0x1e, # length
268
+ 0x00, 0x00, # checksum
269
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
270
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
271
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
272
+ ].pack( "C*" )
273
+ controller( "PacketInSendController" ).should_receive( :packet_in ) do | datapath_id, message |
274
+ message.in_port.should > 0
275
+ message.vtag?.should be_false
276
+ message.arp?.should be_false
277
+ message.ipv4?.should be_true
278
+ message.tcp?.should be_false
279
+ message.udp?.should be_true
280
+ message.icmpv4?.should be_false
281
+ message.igmp?.should be_false
282
+
117
283
  message.ipv4_version.should == 4
118
- message.ipv4_protocol == 17
119
- message.ipv4_saddr.should be_instance_of( Trema::IP )
120
- message.ipv4_saddr.to_s.should == "192.168.1.1"
121
- message.ipv4_daddr.should be_instance_of( Trema::IP )
122
- message.ipv4_daddr.to_s.should == "192.168.1.2"
284
+ message.ipv4_ihl.should == 5
285
+ message.ipv4_tos.should == 0
286
+ message.ipv4_tot_len.should == 0x32
287
+ message.ipv4_id.should == 0
288
+ message.ipv4_frag_off.should == 0
289
+ message.ipv4_ttl.should == 0x40
290
+ message.ipv4_protocol.should == 17
291
+ message.ipv4_checksum.should == 0xf968
292
+ message.ipv4_saddr.to_s.should == "192.168.0.1"
293
+ message.ipv4_daddr.to_s.should == "192.168.0.2"
294
+
295
+ message.udp_src_port.should == 1
296
+ message.udp_dst_port.should == 2
297
+ message.udp_checksum.should == 0
298
+ message.udp_len.should == 0x1e
123
299
  end
124
- send_and_wait
300
+
301
+ controller( "PacketInSendController" ).send_packet_out(
302
+ 0xabc,
303
+ :data => data,
304
+ :actions => Trema::ActionOutput.new( :port => Controller::OFPP_CONTROLLER )
305
+ )
306
+ sleep 2
125
307
  }
126
308
  end
127
309
 
128
-
129
- it "should have user L4 information (udp)" do
310
+ it "should have correct VLAN and ICMPv4 packet fields" do
130
311
  network {
131
- vswitch( "test" ) { datapath_id 0xabc }
132
- vhost( "host1" )
133
- vhost( "host2" )
134
- link "test", "host1"
135
- link "test", "host2"
136
- }.run( PacketInController ) {
137
- controller( "PacketInController" ).should_receive( :packet_in ) do | datapath_id, message |
138
- message.udp?.should == true
139
- message.udp_src_port.should == 9000
140
- message.udp_dst_port.should == 9001
312
+ vswitch( "packet-in" ) { datapath_id 0xabc }
313
+ vhost "host1"
314
+ vhost ( "host2" ) {
315
+ ip "192.168.32.1"
316
+ netmask "255.255.255.0"
317
+ mac "00:00:00:00:00:02"
318
+ }
319
+ link "host1", "packet-in"
320
+ link "host2", "packet-in"
321
+ }.run( PacketInSendController ) {
322
+ data = [
323
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, # dst
324
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, # src
325
+ # vlan tag
326
+ 0x81, 0x00, # tpid
327
+ 0x0f, 0x9f, # tci
328
+ 0x08, 0x00, # ether type
329
+ # ipv4
330
+ 0x45, 0x00, # version
331
+ 0x00, 0x3c, # length
332
+ 0x8c, 0x1b,
333
+ 0x00, 0x00,
334
+ 0x80, # ttl
335
+ 0x01, # protocol
336
+ 0xed, 0x09, # checksum
337
+ 0xc0, 0xa8, 0x20, 0x4a, # src
338
+ 0xc0, 0xa8, 0x20, 0x01, # dst
339
+ # icmp
340
+ 0x08, # type
341
+ 0x00, # code
342
+ 0xe9, 0x5b, # checksum
343
+ 0x04, 0x00, # id
344
+ 0x60, 0x00, # seq
345
+ 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
346
+ 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,
347
+ 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x61,
348
+ 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69
349
+ ].pack( "C*" )
350
+ controller( "PacketInSendController" ).should_receive( :packet_in ) do | datapath_id, message |
351
+ message.in_port.should > 0
352
+ message.vtag?.should be_true
353
+ message.arp?.should be_false
354
+ message.ipv4?.should be_true
355
+ message.udp?.should be_false
356
+ message.tcp?.should be_false
357
+ message.icmpv4?.should be_true
358
+ message.igmp?.should be_false
359
+
360
+ message.vlan_tpid.should == 0x8100
361
+ message.vlan_tci.should == 0x0f9f
362
+ message.vlan_prio.should == 0
363
+ message.vlan_cfi.should == 0
364
+ message.vlan_vid.should == 0xf9f
365
+ message.eth_type.should == 0x0800
366
+
367
+ message.ipv4_version.should == 4
368
+ message.ipv4_ihl.should == 5
369
+ message.ipv4_tos.should == 0
370
+ message.ipv4_tot_len.should == 0x003c
371
+ message.ipv4_id.should == 0x8c1b
372
+ message.ipv4_frag_off.should == 0
373
+ message.ipv4_ttl.should == 0x80
374
+ message.ipv4_protocol.should == 1
375
+ message.ipv4_checksum.should == 0xed09
376
+ message.ipv4_saddr.to_s.should == "192.168.32.74"
377
+ message.ipv4_daddr.to_s.should == "192.168.32.1"
378
+
379
+ message.icmpv4_type.should == 8
380
+ message.icmpv4_code.should == 0
381
+ message.icmpv4_checksum.should == 0xe95b
382
+ message.icmpv4_id.should == 0x0400
383
+ message.icmpv4_seq.should == 0x6000
141
384
  end
142
- send_packets "host1", "host2", :tp_src => 9000, :tp_dst => 9001
385
+
386
+ controller( "PacketInSendController" ).send_packet_out(
387
+ 0xabc,
388
+ :data => data,
389
+ :actions => Trema::ActionOutput.new( :port => Controller::OFPP_CONTROLLER )
390
+ )
143
391
  sleep 2
144
392
  }
145
393
  end
146
394
 
147
-
148
- it "should have valid input port" do
395
+ it "should have correct IGMP packet fields" do
149
396
  network {
150
- vswitch( "test" ) { datapath_id 0xabc }
397
+ vswitch( "packet-in" ) { datapath_id 0xabc }
151
398
  vhost "host1"
152
399
  vhost "host2"
153
- link "test", "host1"
154
- link "test", "host2"
155
- }.run( PacketInController ) {
156
- controller( "PacketInController" ).should_receive( :packet_in ) do | datapath_id, message |
400
+ link "host1", "packet-in"
401
+ link "host2", "packet-in"
402
+ }.run( PacketInSendController ) {
403
+ data = [
404
+ 0x01, 0x00, 0x5e, 0x00, 0x00, 0x01, # dst
405
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, # src
406
+ 0x08, 0x00, # ether type
407
+ # ipv4
408
+ 0x46, 0xc0, # version
409
+ 0x00, 0x20, # length
410
+ 0x3a, 0xea,
411
+ 0x00, 0x00,
412
+ 0x01, # ttl
413
+ 0x02, # protocol
414
+ 0xe4, 0x58, # checksum
415
+ 0xc0, 0xa8, 0x64, 0x2b, # src
416
+ 0xe0, 0x00, 0x00, 0x01, # dst
417
+ 0x94, 0x04, 0x00, 0x00,
418
+ # igmp
419
+ 0x11, # type
420
+ 0x64, # code
421
+ 0xee, 0x9b, # checksum
422
+ 0x00, 0x00, 0x00, 0x00,
423
+ 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
424
+ 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,
425
+ 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x61,
426
+ 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69
427
+ ].pack( "C*" )
428
+ controller( "PacketInSendController" ).should_receive( :packet_in ) do | datapath_id, message |
157
429
  message.in_port.should > 0
430
+ message.vtag?.should be_false
431
+ message.arp?.should be_false
432
+ message.ipv4?.should be_true
433
+ message.udp?.should be_false
434
+ message.tcp?.should be_false
435
+ message.icmpv4?.should be_false
436
+ message.igmp?.should be_true
437
+
438
+ message.igmp_membership_query?.should be_true
439
+ message.igmp_v1_membership_report?.should be_false
440
+ message.igmp_v2_membership_report?.should be_false
441
+ message.igmp_v2_leave_group?.should be_false
442
+ message.igmp_v3_membership_report?.should be_false
443
+
444
+ message.ipv4_version.should == 4
445
+ message.ipv4_ihl.should == 6
446
+ message.ipv4_tos.should == 0xc0
447
+ message.ipv4_tot_len.should == 0x0020
448
+ message.ipv4_id.should == 0x3aea
449
+ message.ipv4_frag_off.should == 0
450
+ message.ipv4_ttl.should == 1
451
+ message.ipv4_protocol.should == 2
452
+ message.ipv4_checksum.should == 0xe458
453
+ message.ipv4_saddr.to_s.should == "192.168.100.43"
454
+ message.ipv4_daddr.to_s.should == "224.0.0.1"
455
+
456
+ message.igmp_type.should == 0x11
457
+ message.igmp_checksum.should == 0xee9b
158
458
  end
159
- send_and_wait
459
+
460
+ controller( "PacketInSendController" ).send_packet_out(
461
+ 0xabc,
462
+ :data => data,
463
+ :actions => Trema::ActionOutput.new( :port => Controller::OFPP_CONTROLLER )
464
+ )
465
+ sleep 2
160
466
  }
161
467
  end
468
+
162
469
  end
470
+
163
471
  end
164
472
 
165
473