trema 0.3.19 → 0.3.20
Sign up to get free protection for your applications and to get access to all the features.
- 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:
|