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 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
@@ -358,6 +358,7 @@ $options.parse! ARGV
358
358
 
359
359
 
360
360
  def init_cruise
361
+ FileUtils.rm_f File.expand_path(File.join(File.dirname(__FILE__), 'Gemfile.lock'))
361
362
  sh "bundle install"
362
363
  sh "bundle update"
363
364
  sh "bundle exec rake clobber"
@@ -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"
@@ -19,7 +19,7 @@
19
19
  require "trema/path"
20
20
 
21
21
 
22
- def wait_until_all_pid_files_are_deleted timeout = 10
22
+ def wait_until_all_pid_files_are_deleted timeout = 12
23
23
  elapsed = 0
24
24
  loop do
25
25
  raise "Failed to clean up remaining processes." if elapsed > timeout
@@ -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 from which the frame is to be sent. OFPP_NONE if
443
- * none. OFPP_TABLE to perform the actions defined in the flow
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
@@ -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 );
@@ -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
@@ -31,7 +31,7 @@ extern VALUE cPort;
31
31
  void Init_port( void );
32
32
 
33
33
 
34
- VALUE port_from( const struct ofp_phy_port *phy_port );
34
+ VALUE port_from( const struct ofp_phy_port *phy_port, uint64_t datapath_id );
35
35
 
36
36
 
37
37
  #endif // PORT_H
@@ -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
 
@@ -30,7 +30,7 @@ module Trema
30
30
  # be created as a result of parsing the +OFPT_STATS_REPLY(OFPST_VENDOR)+
31
31
  # openflow message.
32
32
  #
33
- # @overload initialize(otions={})
33
+ # @overload initialize(options={})
34
34
  #
35
35
  # @example
36
36
  # VendorStatsReply.new(
@@ -17,7 +17,7 @@
17
17
 
18
18
 
19
19
  module Trema
20
- VERSION = "0.4.4"
20
+ VERSION = "0.4.5"
21
21
  end
22
22
 
23
23
 
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
  }
@@ -30,7 +30,7 @@
30
30
 
31
31
  #define VLAN_VID_MASK 0x0fff // 12 bits
32
32
  #define VLAN_PCP_MASK 0x07 // 3 bits
33
- #define NW_TOS_MASK 0x3f // 6 bits
33
+ #define NW_TOS_MASK 0xfc // upper 6 bits
34
34
 
35
35
  #define MATCH_STRING_LENGTH 1024
36
36
 
@@ -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
  },
@@ -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 = -60,
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
- error_type = OFPET_BAD_REQUEST;
410
- error_code = OFPBRC_BAD_TYPE;
411
- get_error_type_and_code( header->type, ret, &error_type, &error_code );
412
- debug( "Validation error. type %u, errno %d, error type %u, error code %u",
413
- header->type, ret, error_type, error_code );
414
-
415
- ofpmsg_send_error_msg( sw_info, error_type, error_code, buf );
416
- free_buffer( buf );
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
  }
@@ -386,7 +386,7 @@ registration_timeout( void *user_data ) {
386
386
 
387
387
 
388
388
  static void
389
- confirm_self_dpid_is_registered( uint64_t* dpids, size_t n_dpids, void *user_data );
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
- if ( send_efi_switch_list_request( confirm_self_dpid_is_registered, sw_info ) ) {
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
- if ( send_efi_switch_list_request( confirm_self_dpid_is_registered, sw_info ) ) {
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( uint64_t* dpids, size_t n_dpids, void *user_data ) {
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 ( size_t i = 0 ; i < n_dpids ; ++i ) {
517
- if ( sw_info->datapath_id == dpids[ i ] ) {
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( uint64_t* dpids, size_t n_dpids, void *user_data );
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
- if ( send_efi_switch_list_request( confirm_self_dpid_is_unregistered, sw_info ) ) {
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
- if ( send_efi_switch_list_request( confirm_self_dpid_is_unregistered, sw_info ) ) {
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( uint64_t* dpids, size_t n_dpids, void *user_data ) {
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 ( size_t i = 0 ; i < n_dpids ; ++i ) {
680
- if ( sw_info->datapath_id == dpids[ i ] ) {
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;
@@ -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, 1111 );
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, 1111 );
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 locked.
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, 1111 );
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
- will_return( mock_unlink, 0 );
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
- will_return( mock_unlink, -1 );
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, 1111 );
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, 1111 );
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
- expect_value( mock_close, fd, 2222 );
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
- hash: 7
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
- date: 2013-10-28 00:00:00 Z
19
- dependencies:
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
- prerelease: false
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
32
20
  type: :runtime
33
- requirement: *id001
34
- - !ruby/object:Gem::Dependency
35
- version_requirements: &id002 !ruby/object:Gem::Requirement
36
- none: false
37
- requirements:
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
- requirement: *id002
50
- - !ruby/object:Gem::Dependency
51
- version_requirements: &id003 !ruby/object:Gem::Requirement
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
- hash: 11
57
- segments:
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
- prerelease: false
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: 0.5.0
64
48
  type: :runtime
65
- requirement: *id003
66
- - !ruby/object:Gem::Dependency
67
- version_requirements: &id004 !ruby/object:Gem::Requirement
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
- hash: 27
73
- segments:
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
- prerelease: false
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 0.2.6
80
62
  type: :runtime
81
- requirement: *id004
82
- - !ruby/object:Gem::Dependency
83
- version_requirements: &id005 !ruby/object:Gem::Requirement
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
- hash: 75
89
- segments:
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
- prerelease: false
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ~>
74
+ - !ruby/object:Gem::Version
75
+ version: 10.1.0
96
76
  type: :runtime
97
- requirement: *id005
98
- - !ruby/object:Gem::Dependency
99
- version_requirements: &id006 !ruby/object:Gem::Requirement
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
- hash: 61
105
- segments:
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
- prerelease: false
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ~>
88
+ - !ruby/object:Gem::Version
89
+ version: 4.0.1
112
90
  type: :runtime
113
- requirement: *id006
114
- description: Trema is a full-stack, easy-to-use framework for developing OpenFlow controllers in Ruby and C.
115
- email:
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
- none: false
823
- requirements:
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
- none: false
834
- requirements:
835
- - - ">="
836
- - !ruby/object:Gem::Version
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: 1.8.25
817
+ rubygems_version: 2.0.3
845
818
  signing_key:
846
- specification_version: 3
819
+ specification_version: 4
847
820
  summary: Full-stack OpenFlow framework.
848
821
  test_files: []
849
-
850
822
  has_rdoc: