trema 0.4.4 → 0.4.5
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 +7 -0
- data/cruise.rb +1 -0
- data/features/examples/message.vendor-action.feature +2 -0
- data/features/examples/packet_in.feature +2 -0
- data/features/support/hooks.rb +1 -1
- data/ruby/trema/controller.c +2 -3
- data/ruby/trema/features-reply.c +4 -4
- data/ruby/trema/port-status.c +1 -1
- data/ruby/trema/port.c +22 -1
- data/ruby/trema/port.h +1 -1
- data/ruby/trema/process.rb +1 -1
- data/ruby/trema/vendor-stats-reply.rb +1 -1
- data/ruby/trema/version.rb +1 -1
- data/src/lib/daemon.c +13 -1
- data/src/lib/match_table.c +1 -1
- data/src/lib/openflow_message.c +19 -0
- data/src/lib/openflow_message.h +3 -1
- data/src/switch_manager/ofpmsg_recv.c +11 -8
- data/src/switch_manager/switch.c +22 -12
- data/unittests/lib/daemon_test.c +86 -28
- metadata +94 -122
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 56656657a56ff4e4bf6cfa8b906dfa401d954220
|
4
|
+
data.tar.gz: 3cedbb6a843395235cef1387b947251913c814dc
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 03bc85f708bf3192783fa3b77e3ba6c59ddb910ba1919fa78e850cc0de36ddd80ff39c5255ea5a468a698b4663c826dece4aa877650ef80c4bff2533192083b3
|
7
|
+
data.tar.gz: 5766922aab5e81eaa24ebc4fcf1e6798e094de4a48410a853b9ce3f14dcc81cf3ebd3dd25a55a2a2d868c23221c5b0c973a31369e033d1a05dcfbb4d0630bab3
|
data/cruise.rb
CHANGED
@@ -14,10 +14,12 @@ Feature: "Vendor Action" sample application
|
|
14
14
|
Scenario: Run "Packet In" C example
|
15
15
|
Given I run `trema run ../../objects/examples/openflow_message/vendor_action -c vendor_action.conf -d`
|
16
16
|
And wait until "vendor_action" is up
|
17
|
+
And *** sleep 2 ***
|
17
18
|
Then the file "../../tmp/log/openflowd.vendor_action.log" should contain "actions=note:54.72.65.6d.61.00"
|
18
19
|
|
19
20
|
@slow_process
|
20
21
|
Scenario: Run "Packet In" Ruby example
|
21
22
|
Given I run `trema run ../../src/examples/openflow_message/vendor-action.rb -c vendor_action.conf -d`
|
22
23
|
And wait until "VendorActionSampleController" is up
|
24
|
+
And *** sleep 2 ***
|
23
25
|
Then the file "../../tmp/log/openflowd.vendor_action.log" should contain "actions=note:54.72.65.6d.61.00"
|
@@ -21,6 +21,7 @@ Feature: "Packet In" sample application
|
|
21
21
|
Given I run `trema run ../../objects/examples/packet_in/packet_in -c packet_in.conf -d`
|
22
22
|
And wait until "packet_in" is up
|
23
23
|
When I send 1 packet from host1 to host2
|
24
|
+
And *** sleep 1 ***
|
24
25
|
Then the file "../../tmp/log/packet_in.log" should contain "received a packet_in"
|
25
26
|
|
26
27
|
@slow_process
|
@@ -28,4 +29,5 @@ Feature: "Packet In" sample application
|
|
28
29
|
Given I run `trema run ../../src/examples/packet_in/packet-in.rb -c packet_in.conf -d`
|
29
30
|
And wait until "PacketInDumper" is up
|
30
31
|
When I send 1 packet from host1 to host2
|
32
|
+
And *** sleep 1 ***
|
31
33
|
Then the file "../../tmp/log/PacketInDumper.log" should contain "received a packet_in"
|
data/features/support/hooks.rb
CHANGED
data/ruby/trema/controller.c
CHANGED
@@ -439,9 +439,8 @@ controller_send_flow_mod_delete( int argc, VALUE *argv, VALUE self ) {
|
|
439
439
|
* set automatically according to the value of :packet_in.
|
440
440
|
*
|
441
441
|
* @option options [Number] :in_port (OFPP_NONE)
|
442
|
-
* The port
|
443
|
-
*
|
444
|
-
* table.
|
442
|
+
* The port to use in flow table lookup when :actions send the packet
|
443
|
+
* to the special OFPP_TABLE port.
|
445
444
|
*
|
446
445
|
* @option options [Number] :buffer_id (0xffffffff)
|
447
446
|
* The buffer ID assigned by the datapath. If 0xffffffff, the
|
data/ruby/trema/features-reply.c
CHANGED
@@ -255,7 +255,7 @@ handle_switch_ready( uint64_t datapath_id, void *controller ) {
|
|
255
255
|
* Extract and map {Port} to +ofp_phy_port+ structure.
|
256
256
|
*/
|
257
257
|
static VALUE
|
258
|
-
ports_from( const list_element *c_ports ) {
|
258
|
+
ports_from( const list_element *c_ports, uint64_t datapath_id ) {
|
259
259
|
VALUE ports = rb_ary_new();
|
260
260
|
|
261
261
|
if ( c_ports == NULL ) {
|
@@ -266,7 +266,7 @@ ports_from( const list_element *c_ports ) {
|
|
266
266
|
memcpy( port_head, c_ports, sizeof( list_element ) );
|
267
267
|
list_element *port = NULL;
|
268
268
|
for ( port = port_head; port != NULL; port = port->next ) {
|
269
|
-
rb_ary_push( ports, port_from( ( struct ofp_phy_port * ) port->data ) );
|
269
|
+
rb_ary_push( ports, port_from( ( struct ofp_phy_port * ) port->data, datapath_id ) );
|
270
270
|
}
|
271
271
|
xfree( port_head );
|
272
272
|
return ports;
|
@@ -303,7 +303,7 @@ handle_features_reply(
|
|
303
303
|
rb_hash_aset( attributes, ID2SYM( rb_intern( "n_tables" ) ), UINT2NUM( n_tables ) );
|
304
304
|
rb_hash_aset( attributes, ID2SYM( rb_intern( "capabilities" ) ), UINT2NUM( capabilities ) );
|
305
305
|
rb_hash_aset( attributes, ID2SYM( rb_intern( "actions" ) ), UINT2NUM( actions ) );
|
306
|
-
rb_hash_aset( attributes, ID2SYM( rb_intern( "ports" ) ), ports_from( ports ) );
|
306
|
+
rb_hash_aset( attributes, ID2SYM( rb_intern( "ports" ) ), ports_from( ports, datapath_id ) );
|
307
307
|
|
308
308
|
list_element *physical_ports = xmalloc( sizeof( list_element ) );
|
309
309
|
create_list( &physical_ports );
|
@@ -314,7 +314,7 @@ handle_features_reply(
|
|
314
314
|
iterate_list( tmp_ports, append_physical_port, &physical_ports );
|
315
315
|
xfree( tmp_ports );
|
316
316
|
}
|
317
|
-
rb_hash_aset( attributes, ID2SYM( rb_intern( "physical_ports" ) ), ports_from( physical_ports ) );
|
317
|
+
rb_hash_aset( attributes, ID2SYM( rb_intern( "physical_ports" ) ), ports_from( physical_ports, datapath_id ) );
|
318
318
|
xfree( physical_ports );
|
319
319
|
|
320
320
|
VALUE features_reply = rb_funcall( cFeaturesReply, rb_intern( "new" ), 1, attributes );
|
data/ruby/trema/port-status.c
CHANGED
@@ -165,7 +165,7 @@ handle_port_status(
|
|
165
165
|
VALUE attributes = rb_hash_new();
|
166
166
|
rb_hash_aset( attributes, ID2SYM( rb_intern( "datapath_id" ) ), ULL2NUM( datapath_id ) );
|
167
167
|
rb_hash_aset( attributes, ID2SYM( rb_intern( "transaction_id" ) ), UINT2NUM( transaction_id ) );
|
168
|
-
rb_hash_aset( attributes, ID2SYM( rb_intern( "phy_port" ) ), port_from( &phy_port ) );
|
168
|
+
rb_hash_aset( attributes, ID2SYM( rb_intern( "phy_port" ) ), port_from( &phy_port, datapath_id ) );
|
169
169
|
|
170
170
|
VALUE port_status = Qnil;
|
171
171
|
if ( reason == OFPPR_ADD ) {
|
data/ruby/trema/port.c
CHANGED
@@ -33,6 +33,7 @@ VALUE cPort;
|
|
33
33
|
* @example
|
34
34
|
* Port.new(
|
35
35
|
* :number => 1,
|
36
|
+
* :datapath_id => 0x123,
|
36
37
|
* :hw_addr => Mac.new( "4e:1e:9a:7a:44:be" ),
|
37
38
|
* :name => "trema0-0",
|
38
39
|
* :config => 0,
|
@@ -44,6 +45,9 @@ VALUE cPort;
|
|
44
45
|
* )
|
45
46
|
*
|
46
47
|
* @param [Hash] options the options hash.
|
48
|
+
*
|
49
|
+
* @option options [Number] :datapath_id
|
50
|
+
* the switch's datapath ID.
|
47
51
|
*
|
48
52
|
* @option options [Number] :number
|
49
53
|
* the port's unique number.
|
@@ -80,6 +84,9 @@ port_init( VALUE self, VALUE options ) {
|
|
80
84
|
VALUE number = rb_hash_aref( options, ID2SYM( rb_intern( "number" ) ) );
|
81
85
|
rb_iv_set( self, "@number", number );
|
82
86
|
|
87
|
+
VALUE datapath_id = rb_hash_aref( options, ID2SYM( rb_intern( "datapath_id" ) ) );
|
88
|
+
rb_iv_set( self, "@datapath_id", datapath_id );
|
89
|
+
|
83
90
|
VALUE hw_addr = rb_hash_aref( options, ID2SYM( rb_intern( "hw_addr" ) ) );
|
84
91
|
rb_iv_set( self, "@hw_addr", hw_addr );
|
85
92
|
|
@@ -118,6 +125,17 @@ port_number( VALUE self ) {
|
|
118
125
|
}
|
119
126
|
|
120
127
|
|
128
|
+
/*
|
129
|
+
* The switch's datapath ID.
|
130
|
+
*
|
131
|
+
* @return [Number] the value of number.
|
132
|
+
*/
|
133
|
+
static VALUE
|
134
|
+
port_datapath_id( VALUE self ) {
|
135
|
+
return rb_iv_get( self, "@datapath_id" );
|
136
|
+
}
|
137
|
+
|
138
|
+
|
121
139
|
/*
|
122
140
|
* The port's Ethernet address expressed as a {Mac} object.
|
123
141
|
*
|
@@ -335,6 +353,8 @@ Init_port() {
|
|
335
353
|
|
336
354
|
rb_define_method( cPort, "initialize", port_init, 1 );
|
337
355
|
rb_define_method( cPort, "number", port_number, 0 );
|
356
|
+
rb_define_method( cPort, "datapath_id", port_datapath_id, 0 );
|
357
|
+
rb_define_method( cPort, "dpid", port_datapath_id, 0 );
|
338
358
|
rb_define_method( cPort, "hw_addr", port_hw_addr, 0 );
|
339
359
|
rb_define_method( cPort, "name", port_name, 0 );
|
340
360
|
rb_define_method( cPort, "config", port_config, 0 );
|
@@ -354,8 +374,9 @@ Init_port() {
|
|
354
374
|
|
355
375
|
|
356
376
|
VALUE
|
357
|
-
port_from( const struct ofp_phy_port *phy_port ) {
|
377
|
+
port_from( const struct ofp_phy_port *phy_port, uint64_t datapath_id ) {
|
358
378
|
VALUE attributes = rb_hash_new();
|
379
|
+
rb_hash_aset( attributes, ID2SYM( rb_intern( "datapath_id" ) ), ULL2NUM( datapath_id ) );
|
359
380
|
rb_hash_aset( attributes, ID2SYM( rb_intern( "number" ) ), UINT2NUM( phy_port->port_no ) );
|
360
381
|
VALUE hw_addr = rb_funcall( rb_eval_string( "Pio::Mac" ), rb_intern( "new" ), 1, ULL2NUM( mac_to_uint64( phy_port->hw_addr ) ) );
|
361
382
|
rb_hash_aset( attributes, ID2SYM( rb_intern( "hw_addr" ) ), hw_addr );
|
data/ruby/trema/port.h
CHANGED
data/ruby/trema/process.rb
CHANGED
@@ -39,7 +39,7 @@ module Trema
|
|
39
39
|
# @return [Process] the object that encapsulates the process details.
|
40
40
|
#
|
41
41
|
def self.read pid_file, name = nil
|
42
|
-
name = File.basename( pid_file, ".pid" ) if name.nil?
|
42
|
+
name = File.basename( pid_file.to_s, ".pid" ) if name.nil?
|
43
43
|
return new( pid_file, name )
|
44
44
|
end
|
45
45
|
|
data/ruby/trema/version.rb
CHANGED
data/src/lib/daemon.c
CHANGED
@@ -229,6 +229,17 @@ unlink_pid( const char *directory, const char *name ) {
|
|
229
229
|
snprintf( path, PATH_MAX, "%s/%s.pid", directory, name );
|
230
230
|
path[ PATH_MAX - 1 ] = '\0';
|
231
231
|
|
232
|
+
int fd = open( path, O_RDWR, 0 );
|
233
|
+
if ( fd < 0 ) {
|
234
|
+
debug( "Failed to open %s ( %s [%d] ).", path, strerror( errno ), errno );
|
235
|
+
return;
|
236
|
+
}
|
237
|
+
if ( lockf( fd, F_TLOCK, 0 ) == -1 ) {
|
238
|
+
warn( "PID file is locked by another process ( %s ).", path );
|
239
|
+
close( fd );
|
240
|
+
return;
|
241
|
+
}
|
242
|
+
|
232
243
|
int ret = unlink( path );
|
233
244
|
if ( ret < 0 ) {
|
234
245
|
if ( errno == ENOENT ) {
|
@@ -239,6 +250,7 @@ unlink_pid( const char *directory, const char *name ) {
|
|
239
250
|
}
|
240
251
|
}
|
241
252
|
debug( "Unlink pid file ( file = %s, pid = %d )", path, getpid() );
|
253
|
+
close( fd );
|
242
254
|
}
|
243
255
|
|
244
256
|
|
@@ -402,8 +414,8 @@ rename_pid( const char *directory, const char *old, const char *new ) {
|
|
402
414
|
int old_locked_fd = locked_fd;
|
403
415
|
locked_fd = -1;
|
404
416
|
write_pid( directory, new );
|
405
|
-
close( old_locked_fd );
|
406
417
|
unlink_pid( directory, old );
|
418
|
+
close( old_locked_fd );
|
407
419
|
|
408
420
|
debug( "Rename pid file ( old name = %s, new name = %s, pid = %d )", old, new, getpid() );
|
409
421
|
}
|
data/src/lib/match_table.c
CHANGED
data/src/lib/openflow_message.c
CHANGED
@@ -1717,6 +1717,15 @@ validate_hello( const buffer *message ) {
|
|
1717
1717
|
int
|
1718
1718
|
validate_error( const buffer *message ) {
|
1719
1719
|
int ret;
|
1720
|
+
struct ofp_error_msg *error_msg;
|
1721
|
+
const unsigned max_valid_code[OFPET_QUEUE_OP_FAILED + 1] = {
|
1722
|
+
[ OFPET_HELLO_FAILED ] = OFPHFC_EPERM,
|
1723
|
+
[ OFPET_BAD_REQUEST ] = OFPBRC_BUFFER_UNKNOWN,
|
1724
|
+
[ OFPET_BAD_ACTION ] = OFPBAC_BAD_QUEUE,
|
1725
|
+
[ OFPET_FLOW_MOD_FAILED ] = OFPFMFC_UNSUPPORTED,
|
1726
|
+
[ OFPET_PORT_MOD_FAILED ] = OFPPMFC_BAD_HW_ADDR,
|
1727
|
+
[ OFPET_QUEUE_OP_FAILED ] = OFPQOFC_EPERM,
|
1728
|
+
};
|
1720
1729
|
|
1721
1730
|
assert( message != NULL );
|
1722
1731
|
|
@@ -1725,6 +1734,14 @@ validate_error( const buffer *message ) {
|
|
1725
1734
|
return ret;
|
1726
1735
|
}
|
1727
1736
|
|
1737
|
+
error_msg = ( struct ofp_error_msg * ) message->data;
|
1738
|
+
if ( ntohs( error_msg->type ) > OFPET_QUEUE_OP_FAILED ) {
|
1739
|
+
return ERROR_INVALID_ERROR_TYPE;
|
1740
|
+
}
|
1741
|
+
if ( ntohs( error_msg->code ) > max_valid_code[ ntohs( error_msg->type ) ] ) {
|
1742
|
+
return ERROR_INVALID_ERROR_CODE;
|
1743
|
+
}
|
1744
|
+
|
1728
1745
|
return 0;
|
1729
1746
|
}
|
1730
1747
|
|
@@ -3602,6 +3619,8 @@ static struct error_map {
|
|
3602
3619
|
{ ERROR_TOO_LONG_MESSAGE, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN },
|
3603
3620
|
{ ERROR_UNDEFINED_TYPE, OFPET_BAD_REQUEST, OFPBRC_BAD_TYPE },
|
3604
3621
|
{ ERROR_INVALID_TYPE, OFPET_BAD_REQUEST, OFPBRC_BAD_TYPE },
|
3622
|
+
{ ERROR_INVALID_ERROR_TYPE, OFPET_BAD_REQUEST, OFPBRC_BAD_TYPE },
|
3623
|
+
{ ERROR_INVALID_ERROR_CODE, OFPET_BAD_REQUEST, OFPBRC_BAD_TYPE },
|
3605
3624
|
{ 0, 0, 0 },
|
3606
3625
|
}
|
3607
3626
|
},
|
data/src/lib/openflow_message.h
CHANGED
@@ -150,7 +150,7 @@ bool append_action_vendor( openflow_actions *actions, const uint32_t vendor,
|
|
150
150
|
// Return code definitions indicating the result of OpenFlow message validation.
|
151
151
|
enum {
|
152
152
|
SUCCESS = 0,
|
153
|
-
ERROR_UNSUPPORTED_VERSION = -
|
153
|
+
ERROR_UNSUPPORTED_VERSION = -63,
|
154
154
|
ERROR_INVALID_LENGTH,
|
155
155
|
ERROR_TOO_SHORT_MESSAGE,
|
156
156
|
ERROR_TOO_LONG_MESSAGE,
|
@@ -211,6 +211,8 @@ enum {
|
|
211
211
|
ERROR_INVALID_STATS_TYPE,
|
212
212
|
ERROR_INVALID_STATS_REQUEST_FLAGS,
|
213
213
|
ERROR_UNDEFINED_FLOW_MOD_COMMAND,
|
214
|
+
ERROR_INVALID_ERROR_TYPE,
|
215
|
+
ERROR_INVALID_ERROR_CODE,
|
214
216
|
ERROR_UNEXPECTED_ERROR = -255
|
215
217
|
};
|
216
218
|
|
@@ -406,14 +406,17 @@ ofpmsg_recv( struct switch_info *sw_info, buffer *buf ) {
|
|
406
406
|
if ( ret != 0 ) {
|
407
407
|
notice( "Invalid openflow message. type:%d, errno:%d", header->type, ret );
|
408
408
|
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
409
|
+
if ( header->type != OFPT_ERROR ) {
|
410
|
+
// Do not send an error of error
|
411
|
+
error_type = OFPET_BAD_REQUEST;
|
412
|
+
error_code = OFPBRC_BAD_TYPE;
|
413
|
+
get_error_type_and_code( header->type, ret, &error_type, &error_code );
|
414
|
+
debug( "Validation error. type %u, errno %d, error type %u, error code %u",
|
415
|
+
header->type, ret, error_type, error_code );
|
416
|
+
|
417
|
+
ofpmsg_send_error_msg( sw_info, error_type, error_code, buf );
|
418
|
+
free_buffer( buf );
|
419
|
+
}
|
417
420
|
|
418
421
|
return -1;
|
419
422
|
}
|
data/src/switch_manager/switch.c
CHANGED
@@ -386,7 +386,7 @@ registration_timeout( void *user_data ) {
|
|
386
386
|
|
387
387
|
|
388
388
|
static void
|
389
|
-
confirm_self_dpid_is_registered(
|
389
|
+
confirm_self_dpid_is_registered( const list_element *switches, void *user_data );
|
390
390
|
|
391
391
|
|
392
392
|
int
|
@@ -459,7 +459,8 @@ switch_event_recv_featuresreply( struct switch_info *sw_info, uint64_t *dpid ) {
|
|
459
459
|
// Check switch_manager registration
|
460
460
|
debug( "Checking switch manager's switch list." );
|
461
461
|
sw_info->retry_count = REGISTRATION_RETRY_COUNT;
|
462
|
-
|
462
|
+
set_list_switches_reply_handler( confirm_self_dpid_is_registered );
|
463
|
+
if ( send_list_switches_request( sw_info ) ) {
|
463
464
|
switch_set_timeout( REGISTRATION_TIMEOUT, registration_timeout, sw_info );
|
464
465
|
}
|
465
466
|
else {
|
@@ -495,7 +496,8 @@ registration_retry( void *user_data ) {
|
|
495
496
|
sw_info->retry_count--;
|
496
497
|
sw_info->running_timer = false;
|
497
498
|
debug( "Checking switch manager's switch list." );
|
498
|
-
|
499
|
+
set_list_switches_reply_handler( confirm_self_dpid_is_registered );
|
500
|
+
if ( send_list_switches_request( sw_info ) ) {
|
499
501
|
switch_set_timeout( REGISTRATION_TIMEOUT, registration_timeout, sw_info );
|
500
502
|
}
|
501
503
|
else {
|
@@ -506,15 +508,15 @@ registration_retry( void *user_data ) {
|
|
506
508
|
|
507
509
|
|
508
510
|
static void
|
509
|
-
confirm_self_dpid_is_registered(
|
511
|
+
confirm_self_dpid_is_registered( const list_element *switches, void *user_data ) {
|
510
512
|
struct switch_info *sw_info = user_data;
|
511
513
|
|
512
514
|
switch_unset_timeout( registration_timeout, sw_info );
|
513
515
|
|
514
516
|
debug( "Received switch manager's switch list." );
|
515
517
|
bool found = false;
|
516
|
-
for (
|
517
|
-
if ( sw_info->datapath_id ==
|
518
|
+
for ( const list_element *e = switches; e != NULL; e = e->next ) {
|
519
|
+
if ( sw_info->datapath_id == *( uint64_t * ) e->data ) {
|
518
520
|
// self dpid registered
|
519
521
|
debug( "Self dpid found" );
|
520
522
|
found = true;
|
@@ -581,13 +583,19 @@ unregistration_timeout( void *user_data ) {
|
|
581
583
|
|
582
584
|
|
583
585
|
static void
|
584
|
-
confirm_self_dpid_is_unregistered(
|
586
|
+
confirm_self_dpid_is_unregistered( const list_element *switches, void *user_data );
|
585
587
|
|
586
588
|
|
587
589
|
int
|
588
590
|
switch_event_disconnected( struct switch_info *sw_info ) {
|
589
591
|
int old_state = sw_info->state;
|
590
592
|
|
593
|
+
if ( sw_info->state == SWITCH_STATE_DISCONNECTED ||
|
594
|
+
sw_info->state == SWITCH_STATE_CONNECTION_FAILED ) {
|
595
|
+
debug( "already disconnected" );
|
596
|
+
return -1;
|
597
|
+
}
|
598
|
+
|
591
599
|
if ( sw_info->state == SWITCH_STATE_COMPLETED ) {
|
592
600
|
sw_info->state = SWITCH_STATE_DISCONNECTED;
|
593
601
|
}
|
@@ -635,7 +643,8 @@ switch_event_disconnected( struct switch_info *sw_info ) {
|
|
635
643
|
// Check switch_manager registration
|
636
644
|
debug( "Checking switch manager's switch list." );
|
637
645
|
sw_info->retry_count = UNREGISTRATION_RETRY_COUNT;
|
638
|
-
|
646
|
+
set_list_switches_reply_handler( confirm_self_dpid_is_unregistered );
|
647
|
+
if ( send_list_switches_request( sw_info ) ) {
|
639
648
|
switch_set_timeout( UNREGISTRATION_TIMEOUT, unregistration_timeout, sw_info );
|
640
649
|
}
|
641
650
|
else {
|
@@ -658,7 +667,8 @@ unregistration_retry( void *user_data ) {
|
|
658
667
|
sw_info->retry_count--;
|
659
668
|
sw_info->running_timer = false;
|
660
669
|
debug( "Checking switch manager's switch list." );
|
661
|
-
|
670
|
+
set_list_switches_reply_handler( confirm_self_dpid_is_unregistered );
|
671
|
+
if ( send_list_switches_request( sw_info ) ) {
|
662
672
|
switch_set_timeout( UNREGISTRATION_TIMEOUT, unregistration_timeout, sw_info );
|
663
673
|
}
|
664
674
|
else {
|
@@ -669,15 +679,15 @@ unregistration_retry( void *user_data ) {
|
|
669
679
|
|
670
680
|
|
671
681
|
static void
|
672
|
-
confirm_self_dpid_is_unregistered(
|
682
|
+
confirm_self_dpid_is_unregistered( const list_element *switches, void *user_data ) {
|
673
683
|
struct switch_info *sw_info = user_data;
|
674
684
|
|
675
685
|
switch_unset_timeout( unregistration_timeout, sw_info );
|
676
686
|
|
677
687
|
debug( "Received switch manager's switch list." );
|
678
688
|
bool found = false;
|
679
|
-
for (
|
680
|
-
if ( sw_info->datapath_id ==
|
689
|
+
for ( const list_element *e = switches; e != NULL; e = e->next ) {
|
690
|
+
if ( sw_info->datapath_id == *( uint64_t * ) e->data ) {
|
681
691
|
// self dpid registered
|
682
692
|
debug( "Self dpid found" );
|
683
693
|
found = true;
|
data/unittests/lib/daemon_test.c
CHANGED
@@ -249,25 +249,25 @@ test_daemonize_fail_if_setsid_fail() {
|
|
249
249
|
static void
|
250
250
|
test_write_pid_succeed() {
|
251
251
|
extern int locked_fd;
|
252
|
-
|
253
252
|
locked_fd = -1;
|
254
|
-
will_return( mock_open, 1111 );
|
255
|
-
will_return( mock_lockf, 0 );
|
256
253
|
|
257
254
|
// Test if correctly opened.
|
258
255
|
char path[] = "/home/yasuhito/trema/tmp/chess.pid";
|
259
256
|
char buffer[] = "1234\n";
|
257
|
+
int pid_file_fd = 1111;
|
260
258
|
expect_string( mock_open, pathname, path );
|
261
259
|
expect_value( mock_open, flags, ( O_RDWR | O_CREAT ) );
|
262
260
|
expect_value( mock_open, mode, 0600 );
|
261
|
+
will_return( mock_open, pid_file_fd );
|
263
262
|
|
264
263
|
// Test if correctly locked.
|
265
|
-
expect_value( mock_lockf, fd,
|
264
|
+
expect_value( mock_lockf, fd, pid_file_fd );
|
266
265
|
expect_value( mock_lockf, cmd, F_TLOCK );
|
267
266
|
expect_value( mock_lockf, len, 0 );
|
267
|
+
will_return( mock_lockf, 0 );
|
268
268
|
|
269
269
|
// Test if correctly written.
|
270
|
-
expect_value( mock_write, fd,
|
270
|
+
expect_value( mock_write, fd, pid_file_fd );
|
271
271
|
expect_string( mock_write, buf, buffer );
|
272
272
|
expect_value( mock_write, count, strlen( buffer ) );
|
273
273
|
|
@@ -278,15 +278,14 @@ test_write_pid_succeed() {
|
|
278
278
|
static void
|
279
279
|
test_write_pid_fail_if_open_fail() {
|
280
280
|
extern int locked_fd;
|
281
|
-
|
282
281
|
locked_fd = -1;
|
283
|
-
will_return( mock_open, -1 );
|
284
282
|
|
285
283
|
// Test if correctly opened.
|
286
284
|
char path[] = "/home/yasuhito/trema/tmp/chess.pid";
|
287
285
|
expect_string( mock_open, pathname, path );
|
288
286
|
expect_value( mock_open, flags, ( O_RDWR | O_CREAT ) );
|
289
287
|
expect_value( mock_open, mode, 0600 );
|
288
|
+
will_return( mock_open, -1 );
|
290
289
|
|
291
290
|
expect_string( mock_die, message, "Could not create a PID file: /home/yasuhito/trema/tmp/chess.pid" );
|
292
291
|
|
@@ -297,21 +296,21 @@ test_write_pid_fail_if_open_fail() {
|
|
297
296
|
static void
|
298
297
|
test_write_pid_fail_if_lockf_fail() {
|
299
298
|
extern int locked_fd;
|
300
|
-
|
301
299
|
locked_fd = -1;
|
302
|
-
will_return( mock_open, 1111 );
|
303
|
-
will_return( mock_lockf, -1 );
|
304
300
|
|
305
|
-
// Test if correctly
|
301
|
+
// Test if correctly opened.
|
306
302
|
char path[] = "/home/yasuhito/trema/tmp/chess.pid";
|
303
|
+
int pid_file_fd = 1111;
|
307
304
|
expect_string( mock_open, pathname, path );
|
308
305
|
expect_value( mock_open, flags, ( O_RDWR | O_CREAT ) );
|
309
306
|
expect_value( mock_open, mode, 0600 );
|
307
|
+
will_return( mock_open, pid_file_fd );
|
310
308
|
|
311
309
|
// Test if correctly locked.
|
312
|
-
expect_value( mock_lockf, fd,
|
310
|
+
expect_value( mock_lockf, fd, pid_file_fd );
|
313
311
|
expect_value( mock_lockf, cmd, F_TLOCK );
|
314
312
|
expect_value( mock_lockf, len, 0 );
|
313
|
+
will_return( mock_lockf, -1 );
|
315
314
|
|
316
315
|
// lockf_return_value = -1;
|
317
316
|
expect_string( mock_die, message, "Could not acquire a lock on a PID file: /home/yasuhito/trema/tmp/chess.pid" );
|
@@ -322,11 +321,24 @@ test_write_pid_fail_if_lockf_fail() {
|
|
322
321
|
|
323
322
|
static void
|
324
323
|
test_unlink_pid_succeed() {
|
325
|
-
|
324
|
+
// Test if correctly opened.
|
325
|
+
char path[] = "/home/yasuhito/trema/tmp/chess.pid";
|
326
|
+
int pid_file_fd = 1111;
|
327
|
+
expect_string( mock_open, pathname, path );
|
328
|
+
expect_value( mock_open, flags, O_RDWR );
|
329
|
+
expect_value( mock_open, mode, 0 );
|
330
|
+
will_return( mock_open, pid_file_fd );
|
331
|
+
|
332
|
+
// Test if correctly locked.
|
333
|
+
expect_value( mock_lockf, fd, pid_file_fd );
|
334
|
+
expect_value( mock_lockf, cmd, F_TLOCK );
|
335
|
+
expect_value( mock_lockf, len, 0 );
|
336
|
+
will_return( mock_lockf, 0 );
|
326
337
|
|
327
338
|
// Test if correctly unlinked.
|
328
|
-
char path[] = "/home/yasuhito/trema/tmp/chess.pid";
|
329
339
|
expect_string( mock_unlink, pathname, path );
|
340
|
+
will_return( mock_unlink, 0 );
|
341
|
+
expect_value( mock_close, fd, pid_file_fd );
|
330
342
|
|
331
343
|
unlink_pid( "/home/yasuhito/trema/tmp", "chess" );
|
332
344
|
}
|
@@ -334,10 +346,25 @@ test_unlink_pid_succeed() {
|
|
334
346
|
|
335
347
|
static void
|
336
348
|
test_unlink_pid_fail_if_unlink_fail() {
|
337
|
-
|
338
|
-
|
349
|
+
// Test if correctly opened.
|
339
350
|
char path[] = "/home/yasuhito/trema/tmp/chess.pid";
|
351
|
+
int pid_file_fd = 1111;
|
352
|
+
expect_string( mock_open, pathname, path );
|
353
|
+
expect_value( mock_open, flags, O_RDWR );
|
354
|
+
expect_value( mock_open, mode, 0 );
|
355
|
+
will_return( mock_open, pid_file_fd );
|
356
|
+
|
357
|
+
// Test if correctly locked.
|
358
|
+
expect_value( mock_lockf, fd, pid_file_fd );
|
359
|
+
expect_value( mock_lockf, cmd, F_TLOCK );
|
360
|
+
expect_value( mock_lockf, len, 0 );
|
361
|
+
will_return( mock_lockf, 0 );
|
362
|
+
|
363
|
+
// Test if correctly unlinked.
|
340
364
|
expect_string( mock_unlink, pathname, path );
|
365
|
+
errno = EACCES;
|
366
|
+
will_return( mock_unlink, -1 );
|
367
|
+
//expect_value( mock_close, fd, pid_file_fd );
|
341
368
|
|
342
369
|
expect_string( mock_die, message, "Could not remove a PID file: /home/yasuhito/trema/tmp/chess.pid" );
|
343
370
|
|
@@ -345,6 +372,27 @@ test_unlink_pid_fail_if_unlink_fail() {
|
|
345
372
|
}
|
346
373
|
|
347
374
|
|
375
|
+
static void
|
376
|
+
test_unlink_pid_fail_if_lockf_fail() {
|
377
|
+
// Test if correctly opened.
|
378
|
+
char path[] = "/home/yasuhito/trema/tmp/chess.pid";
|
379
|
+
int pid_file_fd = 1111;
|
380
|
+
expect_string( mock_open, pathname, path );
|
381
|
+
expect_value( mock_open, flags, O_RDWR );
|
382
|
+
expect_value( mock_open, mode, 0 );
|
383
|
+
will_return( mock_open, pid_file_fd );
|
384
|
+
|
385
|
+
// Test if correctly locked.
|
386
|
+
expect_value( mock_lockf, fd, pid_file_fd );
|
387
|
+
expect_value( mock_lockf, cmd, F_TLOCK );
|
388
|
+
expect_value( mock_lockf, len, 0 );
|
389
|
+
will_return( mock_lockf, -1 );
|
390
|
+
expect_value( mock_close, fd, pid_file_fd );
|
391
|
+
|
392
|
+
unlink_pid( "/home/yasuhito/trema/tmp", "chess" );
|
393
|
+
}
|
394
|
+
|
395
|
+
|
348
396
|
static void
|
349
397
|
test_read_pid_successed() {
|
350
398
|
// Test if correctly access.
|
@@ -662,35 +710,44 @@ test_read_pid_fail_if_readlink_fail() {
|
|
662
710
|
static void
|
663
711
|
test_rename_pid_successed() {
|
664
712
|
extern int locked_fd;
|
665
|
-
|
666
713
|
locked_fd = 2222;
|
667
|
-
will_return( mock_open, 1111 );
|
668
|
-
will_return( mock_lockf, 0 );
|
669
714
|
|
670
715
|
// Test if correctly opened.
|
671
716
|
char new_path[] = "/home/yasuhito/trema/tmp/hello.pid";
|
672
717
|
char buffer[] = "1234\n";
|
718
|
+
int new_pid_file_fd = 3333;
|
673
719
|
expect_string( mock_open, pathname, new_path );
|
674
720
|
expect_value( mock_open, flags, ( O_RDWR | O_CREAT ) );
|
675
721
|
expect_value( mock_open, mode, 0600 );
|
676
|
-
|
722
|
+
will_return( mock_open, new_pid_file_fd );
|
677
723
|
// Test if correctly locked.
|
678
|
-
expect_value( mock_lockf, fd,
|
724
|
+
expect_value( mock_lockf, fd, new_pid_file_fd );
|
679
725
|
expect_value( mock_lockf, cmd, F_TLOCK );
|
680
726
|
expect_value( mock_lockf, len, 0 );
|
681
|
-
|
727
|
+
will_return( mock_lockf, 0 );
|
682
728
|
// Test if correctly written.
|
683
|
-
expect_value( mock_write, fd,
|
729
|
+
expect_value( mock_write, fd, new_pid_file_fd );
|
684
730
|
expect_string( mock_write, buf, buffer );
|
685
731
|
expect_value( mock_write, count, strlen( buffer ) );
|
686
732
|
|
687
|
-
|
688
|
-
|
689
|
-
will_return( mock_unlink, 0 );
|
690
|
-
|
691
|
-
// Test if correctly unlinked.
|
733
|
+
// Test if correctly opened.
|
692
734
|
char old_path[] = "/home/yasuhito/trema/tmp/bye.pid";
|
735
|
+
int old_pid_file_fd = 4444;
|
736
|
+
expect_string( mock_open, pathname, old_path );
|
737
|
+
expect_value( mock_open, flags, O_RDWR );
|
738
|
+
expect_value( mock_open, mode, 0 );
|
739
|
+
will_return( mock_open, old_pid_file_fd );
|
740
|
+
// Test if correctly locked.
|
741
|
+
expect_value( mock_lockf, fd, old_pid_file_fd );
|
742
|
+
expect_value( mock_lockf, cmd, F_TLOCK );
|
743
|
+
expect_value( mock_lockf, len, 0 );
|
744
|
+
will_return( mock_lockf, 0 );
|
745
|
+
// Test if correctly unlinked.
|
693
746
|
expect_string( mock_unlink, pathname, old_path );
|
747
|
+
will_return( mock_unlink, 0 );
|
748
|
+
expect_value( mock_close, fd, old_pid_file_fd );
|
749
|
+
|
750
|
+
expect_value( mock_close, fd, 2222 );
|
694
751
|
|
695
752
|
// Go
|
696
753
|
rename_pid( "/home/yasuhito/trema/tmp", "bye", "hello" );
|
@@ -718,6 +775,7 @@ main() {
|
|
718
775
|
// unlink_pid() tsets.
|
719
776
|
unit_test( test_unlink_pid_succeed ),
|
720
777
|
unit_test( test_unlink_pid_fail_if_unlink_fail ),
|
778
|
+
unit_test( test_unlink_pid_fail_if_lockf_fail ),
|
721
779
|
|
722
780
|
// read_pid() tests.
|
723
781
|
unit_test( test_read_pid_successed ),
|
metadata
CHANGED
@@ -1,127 +1,111 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: trema
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
prerelease:
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 4
|
9
|
-
- 4
|
10
|
-
version: 0.4.4
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.4.5
|
11
5
|
platform: ruby
|
12
|
-
authors:
|
6
|
+
authors:
|
13
7
|
- Yasuhito Takamiya
|
14
8
|
autorequire:
|
15
9
|
bindir: bin
|
16
10
|
cert_chain: []
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
- !ruby/object:Gem::Dependency
|
21
|
-
version_requirements: &id001 !ruby/object:Gem::Requirement
|
22
|
-
none: false
|
23
|
-
requirements:
|
24
|
-
- - ">="
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
hash: 3
|
27
|
-
segments:
|
28
|
-
- 0
|
29
|
-
version: "0"
|
11
|
+
date: 2013-11-08 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
30
14
|
name: bundler
|
31
|
-
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
32
20
|
type: :runtime
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: gli
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
38
31
|
- - ~>
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
hash: 45
|
41
|
-
segments:
|
42
|
-
- 2
|
43
|
-
- 8
|
44
|
-
- 1
|
32
|
+
- !ruby/object:Gem::Version
|
45
33
|
version: 2.8.1
|
46
|
-
name: gli
|
47
|
-
prerelease: false
|
48
34
|
type: :runtime
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
none: false
|
53
|
-
requirements:
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
54
38
|
- - ~>
|
55
|
-
- !ruby/object:Gem::Version
|
56
|
-
|
57
|
-
|
58
|
-
- 0
|
59
|
-
- 5
|
60
|
-
- 0
|
61
|
-
version: 0.5.0
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 2.8.1
|
41
|
+
- !ruby/object:Gem::Dependency
|
62
42
|
name: paper_house
|
63
|
-
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 0.5.0
|
64
48
|
type: :runtime
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
none: false
|
69
|
-
requirements:
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
70
52
|
- - ~>
|
71
|
-
- !ruby/object:Gem::Version
|
72
|
-
|
73
|
-
|
74
|
-
- 0
|
75
|
-
- 2
|
76
|
-
- 6
|
77
|
-
version: 0.2.6
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 0.5.0
|
55
|
+
- !ruby/object:Gem::Dependency
|
78
56
|
name: pio
|
79
|
-
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.2.6
|
80
62
|
type: :runtime
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
none: false
|
85
|
-
requirements:
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
86
66
|
- - ~>
|
87
|
-
- !ruby/object:Gem::Version
|
88
|
-
|
89
|
-
|
90
|
-
- 10
|
91
|
-
- 1
|
92
|
-
- 0
|
93
|
-
version: 10.1.0
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 0.2.6
|
69
|
+
- !ruby/object:Gem::Dependency
|
94
70
|
name: rake
|
95
|
-
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ~>
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 10.1.0
|
96
76
|
type: :runtime
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
none: false
|
101
|
-
requirements:
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
102
80
|
- - ~>
|
103
|
-
- !ruby/object:Gem::Version
|
104
|
-
|
105
|
-
|
106
|
-
- 4
|
107
|
-
- 0
|
108
|
-
- 1
|
109
|
-
version: 4.0.1
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 10.1.0
|
83
|
+
- !ruby/object:Gem::Dependency
|
110
84
|
name: rdoc
|
111
|
-
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ~>
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 4.0.1
|
112
90
|
type: :runtime
|
113
|
-
|
114
|
-
|
115
|
-
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ~>
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 4.0.1
|
97
|
+
description: Trema is a full-stack, easy-to-use framework for developing OpenFlow
|
98
|
+
controllers in Ruby and C.
|
99
|
+
email:
|
116
100
|
- yasuhito@gmail.com
|
117
|
-
executables:
|
101
|
+
executables:
|
118
102
|
- trema
|
119
103
|
- trema-config
|
120
|
-
extensions:
|
104
|
+
extensions:
|
121
105
|
- Rakefile
|
122
|
-
extra_rdoc_files:
|
106
|
+
extra_rdoc_files:
|
123
107
|
- README.md
|
124
|
-
files:
|
108
|
+
files:
|
125
109
|
- .gitignore
|
126
110
|
- .ruby-version
|
127
111
|
- .travis.yml
|
@@ -811,40 +795,28 @@ files:
|
|
811
795
|
- vendor/ruby-ifconfig-1.2/test/unit/tc_openbsd.rb
|
812
796
|
- vendor/ruby-ifconfig-1.2/test/unit/tc_sunos.rb
|
813
797
|
homepage: http://github.com/trema/trema
|
814
|
-
licenses:
|
798
|
+
licenses:
|
815
799
|
- GPL2
|
800
|
+
metadata: {}
|
816
801
|
post_install_message:
|
817
802
|
rdoc_options: []
|
818
|
-
|
819
|
-
require_paths:
|
803
|
+
require_paths:
|
820
804
|
- ruby
|
821
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
822
|
-
|
823
|
-
|
824
|
-
|
825
|
-
- !ruby/object:Gem::Version
|
826
|
-
hash: 57
|
827
|
-
segments:
|
828
|
-
- 1
|
829
|
-
- 8
|
830
|
-
- 7
|
805
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
806
|
+
requirements:
|
807
|
+
- - '>='
|
808
|
+
- !ruby/object:Gem::Version
|
831
809
|
version: 1.8.7
|
832
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
833
|
-
|
834
|
-
|
835
|
-
|
836
|
-
|
837
|
-
hash: 3
|
838
|
-
segments:
|
839
|
-
- 0
|
840
|
-
version: "0"
|
810
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
811
|
+
requirements:
|
812
|
+
- - '>='
|
813
|
+
- !ruby/object:Gem::Version
|
814
|
+
version: '0'
|
841
815
|
requirements: []
|
842
|
-
|
843
816
|
rubyforge_project:
|
844
|
-
rubygems_version:
|
817
|
+
rubygems_version: 2.0.3
|
845
818
|
signing_key:
|
846
|
-
specification_version:
|
819
|
+
specification_version: 4
|
847
820
|
summary: Full-stack OpenFlow framework.
|
848
821
|
test_files: []
|
849
|
-
|
850
822
|
has_rdoc:
|