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.
- checksums.yaml +4 -4
- data/Gemfile +7 -7
- data/README.md +3 -3
- data/Rakefile +13 -4
- data/cruise.rb +1 -1
- data/features/examples/switch_monitor.feature +2 -0
- data/features/switch_event/C-add_forward_entry.feature +4 -24
- data/features/switch_event/C-delete_forward_entry.feature +3 -18
- data/features/switch_event/C-dump_forward_entries.feature +2 -12
- data/features/switch_event/C-set_forward_entries.feature +2 -12
- data/features/switch_event/add_forward_entry.feature +44 -29
- data/features/switch_event/delete_forward_entry.feature +31 -16
- data/features/switch_event/dump_forward_entries.feature +23 -13
- data/features/switch_event/set_forward_entries.feature +17 -7
- data/features/trema_commands/dump_flows.feature +1 -0
- data/features/trema_commands/reset_stats.feature +1 -0
- data/features/trema_commands/show_stats.feature +1 -0
- data/ruby/trema/features-reply.c +9 -6
- data/ruby/trema/monkey-patch/integer/validators.rb +36 -0
- data/ruby/trema/monkey-patch/integer.rb +2 -0
- data/ruby/trema/packet-in.c +140 -0
- data/ruby/trema/packet-queue.rb +130 -126
- data/ruby/trema/port.c +11 -0
- data/ruby/trema/queue-get-config-reply.c +8 -5
- data/ruby/trema/set-ip-tos.rb +3 -3
- data/ruby/trema/vendor-action.rb +5 -1
- data/ruby/trema/version.rb +1 -1
- data/spec/trema/echo-reply_spec.rb +8 -8
- data/spec/trema/echo-request_spec.rb +1 -1
- data/spec/trema/hello_spec.rb +6 -6
- data/spec/trema/packet-in_spec.rb +131 -0
- data/spec/trema/queue-get-config-reply_spec.rb +1 -1
- data/spec/trema/set-ip-tos_spec.rb +5 -0
- data/spec/trema/vendor-action_spec.rb +5 -0
- data/src/examples/switch_event_config/.gitignore +0 -1
- data/src/examples/switch_event_config/network.conf +2 -0
- data/src/lib/arp.h +3 -1
- data/src/lib/ether.h +1 -0
- data/src/lib/event_forward_interface.c +9 -4
- data/src/lib/openflow_message.c +6 -0
- data/src/lib/openflow_message.h +1 -0
- data/src/lib/packet_info.c +23 -0
- data/src/lib/packet_info.h +5 -0
- data/src/lib/packet_parser.c +8 -3
- data/src/lib/utility.c +13 -13
- data/src/lib/utility.h +15 -0
- data/src/switch_manager/event_forward_entry_manipulation.c +1 -1
- data/src/switch_manager/secure_channel_listener.c +3 -6
- data/src/switch_manager/switch.c +68 -9
- data/trema.gemspec +4 -4
- data/unittests/lib/event_forward_interface_test.c +30 -0
- data/unittests/lib/openflow_message_test.c +19 -0
- data/unittests/lib/packet_info_test.c +16 -0
- data/unittests/lib/packet_parser_test.c +37 -0
- data/unittests/lib/test_packets/rarp_req.cap +0 -0
- 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 ) (
|
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(
|
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( "
|
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 );
|
data/ruby/trema/set-ip-tos.rb
CHANGED
@@ -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
|
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.
|
49
|
-
raise ArgumentError, "
|
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
|
data/ruby/trema/vendor-action.rb
CHANGED
@@ -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? )
|
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
|
data/ruby/trema/version.rb
CHANGED
@@ -21,44 +21,44 @@ require "trema"
|
|
21
21
|
|
22
22
|
|
23
23
|
module Trema
|
24
|
-
describe EchoReply, ".new"
|
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)"
|
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)"
|
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)"
|
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)"
|
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)"
|
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)"
|
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")'
|
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")'
|
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
|
data/spec/trema/hello_spec.rb
CHANGED
@@ -21,36 +21,36 @@ require "trema"
|
|
21
21
|
|
22
22
|
|
23
23
|
module Trema
|
24
|
-
describe Hello, ".new"
|
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)"
|
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)"
|
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)"
|
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)"
|
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")'
|
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
|
|
data/src/lib/arp.h
CHANGED
data/src/lib/ether.h
CHANGED
@@ -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 );
|
data/src/lib/openflow_message.c
CHANGED
@@ -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 },
|
data/src/lib/openflow_message.h
CHANGED
@@ -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,
|
data/src/lib/packet_info.c
CHANGED
@@ -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 );
|
data/src/lib/packet_info.h
CHANGED
@@ -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 );
|
data/src/lib/packet_parser.c
CHANGED
@@ -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 |=
|
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:
|