trema 0.3.19 → 0.3.20

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 (56) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +7 -7
  3. data/README.md +3 -3
  4. data/Rakefile +13 -4
  5. data/cruise.rb +1 -1
  6. data/features/examples/switch_monitor.feature +2 -0
  7. data/features/switch_event/C-add_forward_entry.feature +4 -24
  8. data/features/switch_event/C-delete_forward_entry.feature +3 -18
  9. data/features/switch_event/C-dump_forward_entries.feature +2 -12
  10. data/features/switch_event/C-set_forward_entries.feature +2 -12
  11. data/features/switch_event/add_forward_entry.feature +44 -29
  12. data/features/switch_event/delete_forward_entry.feature +31 -16
  13. data/features/switch_event/dump_forward_entries.feature +23 -13
  14. data/features/switch_event/set_forward_entries.feature +17 -7
  15. data/features/trema_commands/dump_flows.feature +1 -0
  16. data/features/trema_commands/reset_stats.feature +1 -0
  17. data/features/trema_commands/show_stats.feature +1 -0
  18. data/ruby/trema/features-reply.c +9 -6
  19. data/ruby/trema/monkey-patch/integer/validators.rb +36 -0
  20. data/ruby/trema/monkey-patch/integer.rb +2 -0
  21. data/ruby/trema/packet-in.c +140 -0
  22. data/ruby/trema/packet-queue.rb +130 -126
  23. data/ruby/trema/port.c +11 -0
  24. data/ruby/trema/queue-get-config-reply.c +8 -5
  25. data/ruby/trema/set-ip-tos.rb +3 -3
  26. data/ruby/trema/vendor-action.rb +5 -1
  27. data/ruby/trema/version.rb +1 -1
  28. data/spec/trema/echo-reply_spec.rb +8 -8
  29. data/spec/trema/echo-request_spec.rb +1 -1
  30. data/spec/trema/hello_spec.rb +6 -6
  31. data/spec/trema/packet-in_spec.rb +131 -0
  32. data/spec/trema/queue-get-config-reply_spec.rb +1 -1
  33. data/spec/trema/set-ip-tos_spec.rb +5 -0
  34. data/spec/trema/vendor-action_spec.rb +5 -0
  35. data/src/examples/switch_event_config/.gitignore +0 -1
  36. data/src/examples/switch_event_config/network.conf +2 -0
  37. data/src/lib/arp.h +3 -1
  38. data/src/lib/ether.h +1 -0
  39. data/src/lib/event_forward_interface.c +9 -4
  40. data/src/lib/openflow_message.c +6 -0
  41. data/src/lib/openflow_message.h +1 -0
  42. data/src/lib/packet_info.c +23 -0
  43. data/src/lib/packet_info.h +5 -0
  44. data/src/lib/packet_parser.c +8 -3
  45. data/src/lib/utility.c +13 -13
  46. data/src/lib/utility.h +15 -0
  47. data/src/switch_manager/event_forward_entry_manipulation.c +1 -1
  48. data/src/switch_manager/secure_channel_listener.c +3 -6
  49. data/src/switch_manager/switch.c +68 -9
  50. data/trema.gemspec +4 -4
  51. data/unittests/lib/event_forward_interface_test.c +30 -0
  52. data/unittests/lib/openflow_message_test.c +19 -0
  53. data/unittests/lib/packet_info_test.c +16 -0
  54. data/unittests/lib/packet_parser_test.c +37 -0
  55. data/unittests/lib/test_packets/rarp_req.cap +0 -0
  56. metadata +9 -6
@@ -131,16 +131,20 @@ get_property( struct ofp_packet_queue *pq, VALUE packet_queue ) {
131
131
  struct ofp_queue_prop_header *qph;
132
132
  qph = ( struct ofp_queue_prop_header * ) ( ( char * ) pq + offset );
133
133
 
134
- uint16_t properties_length = ( uint16_t ) ( pq->len - offset );
134
+ uint16_t properties_length = ( uint16_t ) ( qph->len - offset );
135
135
  struct ofp_queue_prop_min_rate *qpmr;
136
136
  while ( properties_length > 0 ) {
137
137
  if ( qph->property == OFPQT_MIN_RATE ) {
138
138
  qpmr = ( struct ofp_queue_prop_min_rate * ) qph;
139
- rb_funcall( rb_eval_string( "Trema::MinRateQueue" ), rb_intern( "new" ), 4,
139
+ rb_funcall(
140
+ rb_eval_string( "Trema::MinRateQueue" ),
141
+ rb_intern( "new" ),
142
+ 4,
140
143
  UINT2NUM( qph->property ),
141
144
  UINT2NUM( qph->len ),
142
145
  UINT2NUM( qpmr->rate ),
143
- packet_queue );
146
+ packet_queue
147
+ );
144
148
  }
145
149
  properties_length = ( uint16_t ) ( properties_length - pq->len );
146
150
  if ( properties_length > 0 ) {
@@ -170,7 +174,6 @@ handle_queue_get_config_reply(
170
174
  VALUE pq_attributes = rb_hash_new();
171
175
  VALUE packet_queue;
172
176
 
173
-
174
177
  rb_hash_aset( attributes, ID2SYM( rb_intern( "datapath_id" ) ), ULL2NUM( datapath_id ) );
175
178
  rb_hash_aset( attributes, ID2SYM( rb_intern( "transaction_id" ) ), UINT2NUM( transaction_id ) );
176
179
  rb_hash_aset( attributes, ID2SYM( rb_intern( "port" ) ), UINT2NUM( port ) );
@@ -187,7 +190,7 @@ handle_queue_get_config_reply(
187
190
  get_property( pq, packet_queue );
188
191
  queue = queue->next;
189
192
  }
190
- rb_hash_aset( attributes, ID2SYM( rb_intern( "queues" ) ), rb_eval_string( "PacketQueue.queues" ) );
193
+ rb_hash_aset( attributes, ID2SYM( rb_intern( "queues" ) ), rb_eval_string( "Trema::Queue.queues" ) );
191
194
  }
192
195
  VALUE queue_get_config_reply = rb_funcall( cQueueGetConfigReply, rb_intern( "new" ), 1, attributes );
193
196
  rb_funcall( controller, rb_intern( "queue_get_config_reply" ), 2, ULL2NUM( datapath_id ), queue_get_config_reply );
@@ -38,15 +38,15 @@ module Trema
38
38
  # @param [Integer] type_of_service
39
39
  # the ToS/DSCP field to set to.
40
40
  #
41
- # @raise [ArgumentError] if type_of_service argument is not an unsigned 8-bit Integer.
41
+ # @raise [ArgumentError] if type_of_service value is invalid.
42
42
  # @raise [TypeError] if type_of_service argument is not an Integer.
43
43
  #
44
44
  def initialize type_of_service
45
45
  unless type_of_service.is_a?( Integer )
46
46
  raise TypeError, "ToS must be an unsigned 8-bit integer"
47
47
  end
48
- unless type_of_service.unsigned_8bit?
49
- raise ArgumentError, "ToS must be an unsigned 8-bit integer"
48
+ unless type_of_service.valid_nw_tos?
49
+ raise ArgumentError, "Invalid type_of_service (ToS) value."
50
50
  end
51
51
  @type_of_service = type_of_service
52
52
  end
@@ -49,6 +49,7 @@ module Trema
49
49
  # @raise [TypeError] if vendor ID is not an Integer.
50
50
  # @raise [ArgumentError] if vendor ID is not an unsigned 32-bit Integer.
51
51
  # @raise [TypeError] if body is not an Array.
52
+ # @raise [ArgumentError] if body length is not a multiple of 8.
52
53
  #
53
54
  def initialize vendor_id, body = nil
54
55
  unless vendor_id.is_a?( Integer )
@@ -57,9 +58,12 @@ module Trema
57
58
  unless vendor_id.unsigned_32bit?
58
59
  raise ArgumentError, "Vendor ID must be an unsigned 32-bit integer"
59
60
  end
60
- if ( not body.nil? ) and ( not body.is_a?( Array ) )
61
+ if ( not body.nil? ) and ( not body.is_a?( Array ) )
61
62
  raise TypeError, "Body must be an Array"
62
63
  end
64
+ if ( not body.nil? ) and ( body.size % 8 != 0 )
65
+ raise ArgumentError, "Body length must be a multiple of 8"
66
+ end
63
67
 
64
68
  @vendor_id = vendor_id
65
69
  @body = body
@@ -17,7 +17,7 @@
17
17
 
18
18
 
19
19
  module Trema
20
- VERSION = "0.3.19"
20
+ VERSION = "0.3.20"
21
21
  end
22
22
 
23
23
 
@@ -21,44 +21,44 @@ require "trema"
21
21
 
22
22
 
23
23
  module Trema
24
- describe EchoReply, ".new", :nosudo => true do
24
+ describe EchoReply, ".new" do
25
25
  it_should_behave_like "any Openflow message with default transaction ID"
26
26
  its( :user_data ) { should be_nil }
27
27
  end
28
28
 
29
29
 
30
- describe EchoReply, ".new(nil)", :nosudo => true do
30
+ describe EchoReply, ".new(nil)" do
31
31
  subject { EchoReply.new( nil ) }
32
32
  it_should_behave_like "any Openflow message with default transaction ID"
33
33
  its( :user_data ) { should be_nil }
34
34
  end
35
35
 
36
36
 
37
- describe EchoReply, ".new(transaction_id)", :nosudo => true do
37
+ describe EchoReply, ".new(transaction_id)" do
38
38
  subject { EchoReply.new( transaction_id ) }
39
39
  it_should_behave_like "any Openflow message with transaction ID"
40
40
  end
41
41
 
42
42
 
43
- describe EchoReply, ".new(:transaction_id => value)", :nosudo => true do
43
+ describe EchoReply, ".new(:transaction_id => value)" do
44
44
  subject { EchoReply.new( :transaction_id => transaction_id ) }
45
45
  it_should_behave_like "any Openflow message with transaction ID"
46
46
  end
47
47
 
48
48
 
49
- describe EchoReply, ".new(:xid => value)", :nosudo => true do
49
+ describe EchoReply, ".new(:xid => value)" do
50
50
  subject { EchoReply.new( :xid => xid ) }
51
51
  it_should_behave_like "any Openflow message with xid"
52
52
  end
53
53
 
54
54
 
55
- describe EchoReply, ".new(:user_data => value)", :nosudo => true do
55
+ describe EchoReply, ".new(:user_data => value)" do
56
56
  subject { EchoReply.new( :user_data => user_data ) }
57
57
  it_should_behave_like "any Openflow message with user_data"
58
58
  end
59
59
 
60
60
 
61
- describe EchoReply, ".new(:transaction_id => value, :user_data => value)", :nosudo => true do
61
+ describe EchoReply, ".new(:transaction_id => value, :user_data => value)" do
62
62
  subject { EchoReply.new( :transaction_id => transaction_id, :user_data => user_data ) }
63
63
 
64
64
  context 'transaction_id: 123, user_data: "USER DATA"' do
@@ -71,7 +71,7 @@ module Trema
71
71
  end
72
72
 
73
73
 
74
- describe EchoReply, '.new("INVALID OPTION")', :nosudo => true do
74
+ describe EchoReply, '.new("INVALID OPTION")' do
75
75
  it { expect { EchoReply.new "INVALID OPTION" }.to raise_error( TypeError ) }
76
76
  end
77
77
  end
@@ -115,7 +115,7 @@ module Trema
115
115
  end
116
116
 
117
117
 
118
- describe EchoRequest, '.new("INVALID OPTION")', :nosudo => true do
118
+ describe EchoRequest, '.new("INVALID OPTION")' do
119
119
  it { expect { EchoRequest.new "INVALID OPTION" }.to raise_error( TypeError ) }
120
120
  end
121
121
  end
@@ -21,36 +21,36 @@ require "trema"
21
21
 
22
22
 
23
23
  module Trema
24
- describe Hello, ".new", :nosudo => true do
24
+ describe Hello, ".new" do
25
25
  it_should_behave_like "any Openflow message with default transaction ID"
26
26
  end
27
27
 
28
28
 
29
- describe Hello, ".new(nil)", :nosudo => true do
29
+ describe Hello, ".new(nil)" do
30
30
  subject { Hello.new( nil ) }
31
31
  it_should_behave_like "any Openflow message with default transaction ID"
32
32
  end
33
33
 
34
34
 
35
- describe Hello, ".new(transaction_id)", :nosudo => true do
35
+ describe Hello, ".new(transaction_id)" do
36
36
  subject { Hello.new( transaction_id ) }
37
37
  it_should_behave_like "any Openflow message with transaction ID"
38
38
  end
39
39
 
40
40
 
41
- describe Hello, ".new(:transaction_id => value)", :nosudo => true do
41
+ describe Hello, ".new(:transaction_id => value)" do
42
42
  subject { Hello.new( :transaction_id => transaction_id ) }
43
43
  it_should_behave_like "any Openflow message with transaction ID"
44
44
  end
45
45
 
46
46
 
47
- describe Hello, ".new(:xid => value)", :nosudo => true do
47
+ describe Hello, ".new(:xid => value)" do
48
48
  subject { Hello.new( :xid => xid ) }
49
49
  it_should_behave_like "any Openflow message with xid"
50
50
  end
51
51
 
52
52
 
53
- describe Hello, '.new("INVALID OPTION")', :nosudo => true do
53
+ describe Hello, '.new("INVALID OPTION")' do
54
54
  it { expect { Hello.new "INVALID OPTION" }.to raise_error( TypeError ) }
55
55
  end
56
56
  end
@@ -130,6 +130,7 @@ describe Trema::PacketIn do
130
130
  expect( message.in_port ).to be > 0
131
131
  expect( message.vtag? ).to be_false
132
132
  expect( message.arp? ).to be_true
133
+ expect( message.rarp? ).to be_false
133
134
  expect( message.ipv4? ).to be_false
134
135
  expect( message.lldp? ).to be_false
135
136
  expect( message.tcp? ).to be_false
@@ -145,6 +146,125 @@ describe Trema::PacketIn do
145
146
  expect( message.arp_request? ).to be_false
146
147
  expect( message.arp_reply? ).to be_true
147
148
 
149
+ expect( message.rarp_oper ).to be_nil
150
+ expect( message.rarp_sha ).to be_nil
151
+ expect( message.rarp_spa ).to be_nil
152
+ expect( message.rarp_tha ).to be_nil
153
+ expect( message.rarp_tpa ).to be_nil
154
+ expect( message.rarp_request? ).to be_false
155
+ expect( message.rarp_reply? ).to be_false
156
+
157
+ expect( message.vlan_tpid ).to be_nil
158
+ expect( message.vlan_tci ).to be_nil
159
+ expect( message.vlan_prio ).to be_nil
160
+ expect( message.vlan_cfi ).to be_nil
161
+ expect( message.vlan_vid ).to be_nil
162
+
163
+ expect( message.ipv4_version ).to be_nil
164
+ expect( message.ipv4_ihl ).to be_nil
165
+ expect( message.ipv4_tos ).to be_nil
166
+ expect( message.ipv4_tot_len ).to be_nil
167
+ expect( message.ipv4_id ).to be_nil
168
+ expect( message.ipv4_frag_off ).to be_nil
169
+ expect( message.ipv4_ttl ).to be_nil
170
+ expect( message.ipv4_protocol ).to be_nil
171
+ expect( message.ipv4_checksum ).to be_nil
172
+ expect( message.ipv4_saddr ).to be_nil
173
+ expect( message.ipv4_daddr ).to be_nil
174
+
175
+ expect( message.icmpv4_type ).to be_nil
176
+ expect( message.icmpv4_code ).to be_nil
177
+ expect( message.icmpv4_checksum ).to be_nil
178
+ expect( message.icmpv4_id ).to be_nil
179
+ expect( message.icmpv4_seq ).to be_nil
180
+ expect( message.icmpv4_gateway ).to be_nil
181
+
182
+ expect( message.igmp_type ).to be_nil
183
+ expect( message.igmp_checksum ).to be_nil
184
+ expect( message.igmp_group ).to be_nil
185
+
186
+ expect( message.tcp_src_port ).to be_nil
187
+ expect( message.tcp_dst_port ).to be_nil
188
+ expect( message.tcp_seq_no ).to be_nil
189
+ expect( message.tcp_ack_no ).to be_nil
190
+ expect( message.tcp_offset ).to be_nil
191
+ expect( message.tcp_flags ).to be_nil
192
+ expect( message.tcp_window ).to be_nil
193
+ expect( message.tcp_checksum ).to be_nil
194
+ expect( message.tcp_urgent ).to be_nil
195
+
196
+ expect( message.udp_src_port ).to be_nil
197
+ expect( message.udp_dst_port ).to be_nil
198
+ expect( message.udp_checksum ).to be_nil
199
+ expect( message.udp_len ).to be_nil
200
+ end
201
+
202
+ controller( "PacketInSendController" ).send_packet_out(
203
+ 0xabc,
204
+ :data => data,
205
+ :actions => Trema::ActionOutput.new( :port => Controller::OFPP_CONTROLLER )
206
+ )
207
+ sleep 2
208
+ }
209
+ end
210
+
211
+ it "should have correct RARP packet fields" do
212
+ network {
213
+ vswitch( "packet-in" ) { datapath_id 0xabc }
214
+ vhost "host1"
215
+ vhost ( "host2" ) { mac "00:00:00:00:00:02" }
216
+ link "host1", "packet-in"
217
+ link "host2", "packet-in"
218
+ }.run( PacketInSendController ) {
219
+ data = [
220
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, # dst
221
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, # src
222
+ 0x80, 0x35, # ether type
223
+ # rarp
224
+ 0x00, 0x01, # hardware type
225
+ 0x08, 0x00, # protocol type
226
+ 0x06, # hardware address length
227
+ 0x04, # protocol address length
228
+ 0x00, 0x03, # operation
229
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, # sender hardware address
230
+ 0xc0, 0xa8, 0x00, 0x01, # sender protocol address
231
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, # target hardware address
232
+ 0x00, 0x00, 0x00, 0x00, # target protocol address
233
+ # padding to 64 bytes
234
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
235
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
236
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
237
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
238
+ 0x00, 0x00
239
+ ].pack( "C*" )
240
+ controller( "PacketInSendController" ).should_receive( :packet_in ) do | datapath_id, message |
241
+ expect( message.in_port ).to be > 0
242
+ expect( message.vtag? ).to be_false
243
+ expect( message.arp? ).to be_false
244
+ expect( message.rarp? ).to be_true
245
+ expect( message.ipv4? ).to be_false
246
+ expect( message.lldp? ).to be_false
247
+ expect( message.tcp? ).to be_false
248
+ expect( message.udp? ).to be_false
249
+ expect( message.icmpv4? ).to be_false
250
+ expect( message.igmp? ).to be_false
251
+
252
+ expect( message.arp_oper ).to be_nil
253
+ expect( message.arp_sha ).to be_nil
254
+ expect( message.arp_spa ).to be_nil
255
+ expect( message.arp_tha ).to be_nil
256
+ expect( message.arp_tpa ).to be_nil
257
+ expect( message.arp_request? ).to be_false
258
+ expect( message.arp_reply? ).to be_false
259
+
260
+ expect( message.rarp_oper ).to eq( 3 )
261
+ expect( message.rarp_sha.to_s ).to eq( "00:00:00:00:00:01" )
262
+ expect( message.rarp_spa.to_s ).to eq( "192.168.0.1" )
263
+ expect( message.rarp_tha.to_s ).to eq( "00:00:00:00:00:02" )
264
+ expect( message.rarp_tpa.to_s ).to eq( "0.0.0.0" )
265
+ expect( message.rarp_request? ).to be_true
266
+ expect( message.rarp_reply? ).to be_false
267
+
148
268
  expect( message.vlan_tpid ).to be_nil
149
269
  expect( message.vlan_tci ).to be_nil
150
270
  expect( message.vlan_prio ).to be_nil
@@ -241,6 +361,7 @@ describe Trema::PacketIn do
241
361
  expect( message.in_port ).to be > 0
242
362
  expect( message.vtag? ).to be_false
243
363
  expect( message.arp? ).to be_false
364
+ expect( message.rarp? ).to be_false
244
365
  expect( message.ipv4? ).to be_true
245
366
  expect( message.lldp? ).to be_false
246
367
  expect( message.udp? ).to be_false
@@ -275,6 +396,12 @@ describe Trema::PacketIn do
275
396
  expect( message.arp_spa ).to be_nil
276
397
  expect( message.arp_tha ).to be_nil
277
398
  expect( message.arp_tpa ).to be_nil
399
+
400
+ expect( message.rarp_oper ).to be_nil
401
+ expect( message.rarp_sha ).to be_nil
402
+ expect( message.rarp_spa ).to be_nil
403
+ expect( message.rarp_tha ).to be_nil
404
+ expect( message.rarp_tpa ).to be_nil
278
405
  end
279
406
 
280
407
  controller( "PacketInSendController" ).send_packet_out(
@@ -325,6 +452,7 @@ describe Trema::PacketIn do
325
452
  expect( message.in_port ).to be > 0
326
453
  expect( message.vtag? ).to be_false
327
454
  expect( message.arp? ).to be_false
455
+ expect( message.rarp? ).to be_false
328
456
  expect( message.ipv4? ).to be_true
329
457
  expect( message.lldp? ).to be_false
330
458
  expect( message.tcp? ).to be_false
@@ -406,6 +534,7 @@ describe Trema::PacketIn do
406
534
  expect( message.in_port ).to be > 0
407
535
  expect( message.vtag? ).to be_true
408
536
  expect( message.arp? ).to be_false
537
+ expect( message.rarp? ).to be_false
409
538
  expect( message.ipv4? ).to be_true
410
539
  expect( message.lldp? ).to be_false
411
540
  expect( message.udp? ).to be_false
@@ -490,6 +619,7 @@ describe Trema::PacketIn do
490
619
  expect( message.in_port ).to be > 0
491
620
  expect( message.vtag? ).to be_false
492
621
  expect( message.arp? ).to be_false
622
+ expect( message.rarp? ).to be_false
493
623
  expect( message.ipv4? ).to be_true
494
624
  expect( message.lldp? ).to be_false
495
625
  expect( message.udp? ).to be_false
@@ -555,6 +685,7 @@ describe Trema::PacketIn do
555
685
  expect( message.in_port ).to be > 0
556
686
  expect( message.vtag? ).to be_false
557
687
  expect( message.arp? ).to be_false
688
+ expect( message.rarp? ).to be_false
558
689
  expect( message.ipv4? ).to be_false
559
690
  expect( message.lldp? ).to be_true
560
691
  expect( message.udp? ).to be_false
@@ -29,7 +29,7 @@ describe QueueGetConfigReply, ".new( VALID OPTIONS )" do
29
29
  QueueGetConfigReply.new( :datapath_id => 0xabc,
30
30
  :transaction_id => 123,
31
31
  :port => 1,
32
- :queues => Queue.queues
32
+ :queues => Trema::Queue.queues
33
33
  )
34
34
  end
35
35
  its( "queues.length" ) { should == 2 }
@@ -40,6 +40,11 @@ describe SetIpTos, ".new( type_of_service )", :type => "actions" do
40
40
  it { expect { subject }.to raise_error( TypeError ) }
41
41
  end
42
42
 
43
+ context "with type_of_service (1)" do
44
+ let( :type_of_service ) { 1 }
45
+ it { expect { subject }.to raise_error( ArgumentError ) }
46
+ end
47
+
43
48
  context "when sending a Flow Mod with SetIpTos" do
44
49
  let( :type_of_service ) { 4 }
45
50
 
@@ -45,6 +45,11 @@ describe VendorAction, ".new(0x00002320, body)", :type => "actions" do
45
45
  it { expect { subject }.to raise_error( TypeError ) }
46
46
  end
47
47
 
48
+ context "with body 9 octets long" do
49
+ let( :body ) { [ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 ] }
50
+ it { expect { subject }.to raise_error( ArgumentError ) }
51
+ end
52
+
48
53
  context "when sending a Flow Mod with VendorAction" do
49
54
  let( :body ) { [ 0x00, 0x08, 0x54, 0x72, 0x65, 0x6d, 0x61, 0x00 ] }
50
55
 
@@ -2,6 +2,5 @@ add_forward_entry
2
2
  delete_forward_entry
3
3
  dump_forward_entries
4
4
  set_forward_entries
5
- nw_dsl.conf
6
5
  switch_event_config_add.conf
7
6
 
@@ -0,0 +1,2 @@
1
+ vswitch { datapath_id 0x1 }
2
+ vswitch { datapath_id 0x2 }
data/src/lib/arp.h CHANGED
@@ -48,7 +48,9 @@ typedef struct arp_header {
48
48
 
49
49
 
50
50
  #define ARP_OP_REQUEST 1
51
- #define ARP_OP_REPLY 2
51
+ #define ARP_OP_REPLY 2
52
+ #define ARP_OP_RREQUEST 3
53
+ #define ARP_OP_RREPLY 4
52
54
 
53
55
 
54
56
  #endif // ARP_H
data/src/lib/ether.h CHANGED
@@ -39,6 +39,7 @@
39
39
  #define ETH_ETHTYPE_8023 0x05dc
40
40
  #define ETH_ETHTYPE_IPV4 0x0800
41
41
  #define ETH_ETHTYPE_ARP 0x0806
42
+ #define ETH_ETHTYPE_RARP 0x8035
42
43
  #define ETH_ETHTYPE_TPID 0x8100
43
44
  #define ETH_ETHTYPE_IPV6 0x86DD
44
45
  #define ETH_ETHTYPE_EAPOL 0x88c7
@@ -649,7 +649,6 @@ all_sw_tx*
649
649
  _insert_tx( size_t n_dpids, struct event_forward_operation_to_all_request_param *param ) {
650
650
  all_sw_tx *tx = xcalloc( 1, sizeof(all_sw_tx) );
651
651
  tx->txid = get_txid();
652
- info( "txid %#x Start dispatching to switches", tx->txid );
653
652
  tx->request_param = param;
654
653
  tx->tx_result = EFI_OPERATION_SUCCEEDED;
655
654
  tx->waiting_dpid = create_hash_with_size( compare_datapath_id,
@@ -666,7 +665,8 @@ _dispatch_to_all_switch( uint64_t *dpids, size_t n_dpids, void *user_data ) {
666
665
  struct event_forward_operation_to_all_request_param *param = user_data;
667
666
 
668
667
  all_sw_tx *tx = _insert_tx( n_dpids, param );
669
-
668
+ info( "txid %#x Start dispatching to switches", tx->txid );
669
+ debug( "dispatching to %zd switches", n_dpids );
670
670
  // copy dpid hash to transaction.
671
671
  for ( size_t i = 0 ; i < n_dpids ; ++i ) {
672
672
  uint64_t *dpid = xmalloc( sizeof( uint64_t ) );
@@ -715,11 +715,16 @@ _dispatch_to_all_switch( uint64_t *dpids, size_t n_dpids, void *user_data ) {
715
715
  }
716
716
  }
717
717
 
718
- if ( tx->tx_result == EFI_OPERATION_FAILED ) {
718
+ if ( n_dpids == 0 || tx->tx_result == EFI_OPERATION_FAILED ) {
719
+ if ( n_dpids == 0 ) {
720
+ info( "txid %#x completed. No switches found.", tx->txid );
721
+ }
722
+ else if ( tx->tx_result == EFI_OPERATION_FAILED ) {
723
+ info( "txid %#x completed with failure.", tx->txid );
724
+ }
719
725
  if ( param->callback != NULL ) {
720
726
  param->callback( tx->tx_result, param->user_data );
721
727
  }
722
- info( "txid %#x completed with failure.", tx->txid );
723
728
  // remove and cleanup tx
724
729
  delete_hash_entry( efi_tx_table, &tx->txid );
725
730
  xfree_all_sw_tx( tx );
@@ -1638,6 +1638,7 @@ append_action_vendor( openflow_actions *actions, const uint32_t vendor, const bu
1638
1638
  debug( "Appending a vendor action ( vendor = %#" PRIx32 ", body length = %u ).", vendor, body_length );
1639
1639
 
1640
1640
  assert( actions != NULL );
1641
+ assert( ( body_length % 8 ) == 0 );
1641
1642
 
1642
1643
  action_vendor = ( struct ofp_action_vendor_header * )
1643
1644
  xcalloc( 1, sizeof( struct ofp_action_vendor_header ) + body_length );
@@ -3457,6 +3458,9 @@ validate_action_vendor( const struct ofp_action_vendor_header *action ) {
3457
3458
  if ( ntohs( action->len ) < sizeof( struct ofp_action_vendor_header ) ) {
3458
3459
  return ERROR_TOO_SHORT_ACTION_VENDOR;
3459
3460
  }
3461
+ else if ( ntohs( action->len ) % 8 != 0 ) {
3462
+ return ERROR_INVALID_LENGTH_ACTION_VENDOR;
3463
+ }
3460
3464
 
3461
3465
  // action->vendor
3462
3466
 
@@ -3758,6 +3762,7 @@ static struct error_map {
3758
3762
  { ERROR_TOO_LONG_ACTION_ENQUEUE, OFPET_BAD_ACTION, OFPBAC_BAD_LEN },
3759
3763
  { ERROR_INVALID_PORT_NO, OFPET_BAD_ACTION, OFPBAC_BAD_OUT_PORT },
3760
3764
  { ERROR_TOO_SHORT_ACTION_VENDOR, OFPET_BAD_ACTION, OFPBAC_BAD_LEN },
3765
+ { ERROR_INVALID_LENGTH_ACTION_VENDOR, OFPET_BAD_ACTION, OFPBAC_BAD_LEN },
3761
3766
  { ERROR_UNDEFINED_ACTION_TYPE, OFPET_BAD_ACTION, OFPBAC_BAD_TYPE },
3762
3767
  { 0, 0, 0 },
3763
3768
  }
@@ -3800,6 +3805,7 @@ static struct error_map {
3800
3805
  { ERROR_TOO_LONG_ACTION_ENQUEUE, OFPET_BAD_ACTION, OFPBAC_BAD_LEN },
3801
3806
  { ERROR_INVALID_PORT_NO, OFPET_BAD_ACTION, OFPBAC_BAD_OUT_PORT },
3802
3807
  { ERROR_TOO_SHORT_ACTION_VENDOR, OFPET_BAD_ACTION, OFPBAC_BAD_LEN },
3808
+ { ERROR_INVALID_LENGTH_ACTION_VENDOR, OFPET_BAD_ACTION, OFPBAC_BAD_LEN },
3803
3809
  { ERROR_UNDEFINED_ACTION_TYPE, OFPET_BAD_ACTION, OFPBAC_BAD_TYPE },
3804
3810
  { ERROR_INVALID_WILDCARDS, OFPET_FLOW_MOD_FAILED, OFPFMFC_EPERM }, // FIXME
3805
3811
  { ERROR_UNDEFINED_FLOW_MOD_COMMAND, OFPET_FLOW_MOD_FAILED, OFPFMFC_BAD_COMMAND },
@@ -202,6 +202,7 @@ enum {
202
202
  ERROR_TOO_SHORT_ACTION_ENQUEUE,
203
203
  ERROR_TOO_LONG_ACTION_ENQUEUE,
204
204
  ERROR_TOO_SHORT_ACTION_VENDOR,
205
+ ERROR_INVALID_LENGTH_ACTION_VENDOR,
205
206
  ERROR_UNSUPPORTED_STATS_TYPE,
206
207
  ERROR_INVALID_STATS_REPLY_FLAGS,
207
208
  ERROR_INVALID_FLOW_PRIORITY,
@@ -124,6 +124,13 @@ packet_type_arp( const buffer *frame ) {
124
124
  }
125
125
 
126
126
 
127
+ bool
128
+ packet_type_rarp( const buffer *frame ) {
129
+ die_if_NULL( frame );
130
+ return if_packet_type( frame, NW_RARP );
131
+ }
132
+
133
+
127
134
  bool
128
135
  packet_type_ipv4( const buffer *frame ) {
129
136
  die_if_NULL( frame );
@@ -218,6 +225,22 @@ packet_type_arp_reply( const buffer *frame ) {
218
225
  }
219
226
 
220
227
 
228
+ bool
229
+ packet_type_rarp_request( const buffer *frame ) {
230
+ die_if_NULL( frame );
231
+ return ( if_packet_type( frame, NW_RARP ) &
232
+ if_arp_opcode( frame, ARP_OP_RREQUEST ) );
233
+ }
234
+
235
+
236
+ bool
237
+ packet_type_rarp_reply( const buffer *frame ) {
238
+ die_if_NULL( frame );
239
+ return ( if_packet_type( frame, NW_RARP ) &
240
+ if_arp_opcode( frame, ARP_OP_RREPLY ) );
241
+ }
242
+
243
+
221
244
  static bool
222
245
  if_icmpv4_type( const buffer *frame, const uint32_t type ) {
223
246
  die_if_NULL( frame );
@@ -48,6 +48,7 @@ enum {
48
48
  NW_ARP = 0x00001000,
49
49
  NW_IGMP = 0x00002000,
50
50
  NW_LLDP = 0x00004000,
51
+ NW_RARP = 0x00008000,
51
52
  TP_TCP = 0x00010000,
52
53
  TP_UDP = 0x00020000,
53
54
  TP_ETHERIP = 0x00040000,
@@ -58,6 +59,7 @@ enum {
58
59
  ETH_VTAG_SNAP = ETH_8021Q | ETH_8023_SNAP,
59
60
  ETH_ARP = ETH_DIX | NW_ARP,
60
61
  ETH_LLDP = ETH_DIX | NW_LLDP,
62
+ ETH_RARP = ETH_DIX | NW_RARP,
61
63
  ETH_IPV4 = ETH_DIX | NW_IPV4,
62
64
  ETH_IPV4_ICMPV4 = ETH_IPV4 | NW_ICMPV4,
63
65
  ETH_IPV4_IGMP = ETH_IPV4 | NW_IGMP,
@@ -191,6 +193,7 @@ bool packet_type_eth_llc( const buffer *frame );
191
193
  bool packet_type_eth_snap( const buffer *frame );
192
194
  bool packet_type_ether( const buffer *frame );
193
195
  bool packet_type_arp( const buffer *frame );
196
+ bool packet_type_rarp( const buffer *frame );
194
197
  bool packet_type_ipv4( const buffer *frame );
195
198
  bool packet_type_ipv6( const buffer *frame );
196
199
  bool packet_type_lldp( const buffer *frame );
@@ -204,6 +207,8 @@ bool packet_type_ipv4_etherip( const buffer *frame );
204
207
 
205
208
  bool packet_type_arp_request( const buffer *frame );
206
209
  bool packet_type_arp_reply( const buffer *frame );
210
+ bool packet_type_rarp_request( const buffer *frame );
211
+ bool packet_type_rarp_reply( const buffer *frame );
207
212
 
208
213
  bool packet_type_icmpv4_echo_reply( const buffer *frame );
209
214
  bool packet_type_icmpv4_dst_unreach( const buffer *frame );
@@ -119,7 +119,7 @@ parse_ether( buffer *buf ) {
119
119
 
120
120
 
121
121
  static void
122
- parse_arp( buffer *buf ) {
122
+ parse_arp( buffer *buf, uint32_t format ) {
123
123
  assert( buf != NULL );
124
124
 
125
125
  packet_info *packet_info = buf->user_data;
@@ -144,7 +144,7 @@ parse_arp( buffer *buf ) {
144
144
  memcpy( packet_info->arp_tha, arp_header->tha, ETH_ADDRLEN );
145
145
  packet_info->arp_tpa = ntohl( arp_header->tip );
146
146
 
147
- packet_info->format |= NW_ARP;
147
+ packet_info->format |= format;
148
148
  }
149
149
 
150
150
 
@@ -441,7 +441,12 @@ parse_packet( buffer *buf ) {
441
441
  switch ( packet_info->eth_type ) {
442
442
  case ETH_ETHTYPE_ARP:
443
443
  packet_info->l3_header = packet_info->l2_payload;
444
- parse_arp( buf );
444
+ parse_arp( buf, NW_ARP );
445
+ break;
446
+
447
+ case ETH_ETHTYPE_RARP:
448
+ packet_info->l3_header = packet_info->l2_payload;
449
+ parse_arp( buf, NW_RARP );
445
450
  break;
446
451
 
447
452
  case ETH_ETHTYPE_IPV4: