trema 0.4.4 → 0.4.5

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