trema 0.4.3 → 0.4.4

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.
data/src/lib/log.c CHANGED
@@ -25,6 +25,9 @@
25
25
  #include <string.h>
26
26
  #include <syslog.h>
27
27
  #include <time.h>
28
+ #ifdef DEBUG
29
+ #include <sys/time.h>
30
+ #endif
28
31
  #include "bool.h"
29
32
  #include "log.h"
30
33
  #include "trema_wrapper.h"
@@ -130,7 +133,13 @@ static const size_t max_message_length = 1024;
130
133
 
131
134
  static void
132
135
  log_file( int priority, const char *format, va_list ap ) {
136
+ #ifdef DEBUG
137
+ struct timeval tv;
138
+ gettimeofday( &tv, NULL );
139
+ time_t tm = tv.tv_sec;
140
+ #else
133
141
  time_t tm = time( NULL );
142
+ #endif
134
143
  char now[ 26 ];
135
144
  asctime_r( localtime( &tm ), now );
136
145
  now[ 24 ] = '\0'; // chomp
@@ -143,7 +152,11 @@ log_file( int priority, const char *format, va_list ap ) {
143
152
  vsnprintf( message, max_message_length, format, new_ap );
144
153
  va_end( new_ap );
145
154
 
155
+ #ifdef DEBUG
156
+ trema_fprintf( fd, "%s %03dms [%s] %s\n", now, tv.tv_usec / 1000, priority_name, message );
157
+ #else
146
158
  trema_fprintf( fd, "%s [%s] %s\n", now, priority_name, message );
159
+ #endif
147
160
  fflush( fd );
148
161
  }
149
162
 
@@ -210,6 +223,9 @@ get_log_directory() {
210
223
  return log_directory;
211
224
  }
212
225
 
226
+ #ifdef DEBUG
227
+ pid_t trema_log_pid = 0;
228
+ #endif
213
229
 
214
230
  static FILE *
215
231
  open_log_file( bool append ) {
@@ -217,7 +233,14 @@ open_log_file( bool append ) {
217
233
  assert( strlen( get_ident_string() ) > 0 );
218
234
 
219
235
  char pathname[ PATH_MAX ];
236
+ #ifdef DEBUG
237
+ if ( trema_log_pid == 0 ) {
238
+ trema_log_pid = getpid();
239
+ }
240
+ sprintf( pathname, "%s/%s.%d.log", get_log_directory(), get_ident_string(), trema_log_pid );
241
+ #else
220
242
  sprintf( pathname, "%s/%s.log", get_log_directory(), get_ident_string() );
243
+ #endif
221
244
  FILE *log = fopen( pathname, append ? "a" : "w" );
222
245
 
223
246
  if ( log == NULL ) {
@@ -369,11 +392,19 @@ rename_log( const char *new_ident ) {
369
392
 
370
393
  if ( output & LOGGING_TYPE_FILE ) {
371
394
  char old_path[ PATH_MAX ];
395
+ #ifdef DEBUG
396
+ snprintf( old_path, PATH_MAX, "%s/%s.%d.log", get_log_directory(), get_ident_string(), trema_log_pid );
397
+ #else
372
398
  snprintf( old_path, PATH_MAX, "%s/%s.log", get_log_directory(), get_ident_string() );
399
+ #endif
373
400
  old_path[ PATH_MAX - 1 ] = '\0';
374
401
  char new_path[ PATH_MAX ];
375
402
  set_ident_string( new_ident );
403
+ #ifdef DEBUG
404
+ snprintf( new_path, PATH_MAX, "%s/%s.%d.log", get_log_directory(), get_ident_string(), trema_log_pid );
405
+ #else
376
406
  snprintf( new_path, PATH_MAX, "%s/%s.log", get_log_directory(), get_ident_string() );
407
+ #endif
377
408
  new_path[ PATH_MAX - 1 ] = '\0';
378
409
 
379
410
  unlink( new_path );
data/src/lib/messenger.c CHANGED
@@ -776,14 +776,22 @@ rename_message_callback( const char *old_service_name, const char *new_service_n
776
776
  return false;
777
777
  }
778
778
 
779
+ bool success = true;
779
780
  for ( element = old_rq->message_callbacks->next; element; element = element->next ) {
780
781
  cb = element->data;
781
- add_message_callback( new_service_name, cb->message_type, cb->function );
782
+ if ( !add_message_callback( new_service_name, cb->message_type, cb->function ) ) {
783
+ success = false;
784
+ break;
785
+ }
786
+ }
787
+ if ( success ) {
788
+ delete_receive_queue( old_rq->service_name, old_rq, NULL );
789
+ }
790
+ else if ( ( new_rq = lookup_hash_entry( receive_queues, new_service_name ) ) != NULL ) {
791
+ delete_receive_queue( new_rq->service_name, new_rq, NULL );
782
792
  }
783
793
 
784
- delete_receive_queue( old_rq->service_name, old_rq, NULL );
785
-
786
- return true;
794
+ return success;
787
795
  }
788
796
 
789
797
  static bool
@@ -1198,7 +1206,7 @@ _clear_send_queue( const char *service_name ) {
1198
1206
  send_queue *sq = lookup_hash_entry( send_queues, service_name );
1199
1207
 
1200
1208
  if ( NULL == sq ) {
1201
- error( "Send queue is already deleted or not created yet ( service_name = %s ).", service_name );
1209
+ warn( "Send queue is already deleted or not created yet ( service_name = %s ).", service_name );
1202
1210
  return false;
1203
1211
  }
1204
1212
  if ( NULL == sq->buffer ) {
data/src/lib/trema.c CHANGED
@@ -99,11 +99,11 @@ pid_t mock_read_pid( const char *directory, const char *name );
99
99
  #define kill mock_kill
100
100
  int mock_kill( pid_t pid, int sig );
101
101
 
102
- #ifdef sleep
103
- #undef sleep
102
+ #ifdef clock_nanosleep
103
+ #undef clock_nanosleep
104
104
  #endif
105
- #define sleep mock_sleep
106
- unsigned int mock_sleep( unsigned int seconds );
105
+ #define clock_nanosleep mock_clock_nanosleep
106
+ unsigned int mock_clock_nanosleep( clockid_t clock_id, int flags, const struct timespec *request, struct timespec *remain);
107
107
 
108
108
  #ifdef init_event_handler
109
109
  #undef init_event_handler
@@ -741,8 +741,9 @@ terminate_trema_process( pid_t pid ) {
741
741
 
742
742
  int try = 0;
743
743
  const int max_try = 10;
744
+ struct timespec tv = { 0, 500000000 };
744
745
  while ( kill( pid, 0 ) == 0 && ++try <= max_try ) {
745
- sleep( 1 );
746
+ clock_nanosleep( CLOCK_MONOTONIC, 0, &tv, NULL );
746
747
  }
747
748
  if ( try > max_try ) {
748
749
  error( "Failed to terminate %d.", pid );
@@ -57,8 +57,14 @@ struct switch_info switch_info;
57
57
 
58
58
  static const time_t COOKIE_TABLE_AGING_INTERVAL = 3600; // sec.
59
59
  static const time_t ECHO_REQUEST_INTERVAL = 60; // sec.
60
- static const time_t ECHO_REPLY_TIMEOUT = 2; // ses.
60
+ static const time_t ECHO_REPLY_TIMEOUT = 2; // sec.
61
61
  static const time_t WARNING_ECHO_RTT = 500; // msec. The value must is less than 1000.
62
+ static const time_t REGISTRATION_RETRY = 1; // sec.
63
+ static const int REGISTRATION_RETRY_COUNT = 1;
64
+ static const time_t REGISTRATION_TIMEOUT = 1; // sec.
65
+ static const time_t UNREGISTRATION_RETRY = 1; // sec.
66
+ static const int UNREGISTRATION_RETRY_COUNT = 1;
67
+ static const time_t UNREGISTRATION_TIMEOUT = 1; // sec.
62
68
 
63
69
 
64
70
  static bool age_cookie_table_enabled = false;
@@ -308,6 +314,7 @@ static void
308
314
  echo_reply_timeout( void *user_data ) {
309
315
  UNUSED( user_data );
310
316
 
317
+ switch_info.running_timer = false;
311
318
  error( "Echo request timeout ( datapath id %#" PRIx64 ").", switch_info.datapath_id );
312
319
  switch_event_disconnected( &switch_info );
313
320
  }
@@ -368,7 +375,18 @@ echo_request_interval( void *user_data ) {
368
375
 
369
376
 
370
377
  static void
371
- confirm_self_dpid_is_registerd( uint64_t* dpids, size_t n_dpids, void *user_data );
378
+ registration_timeout( void *user_data ) {
379
+ struct switch_info *sw_info = user_data;
380
+
381
+ sw_info->running_timer = false;
382
+
383
+ error( "Registration timeout ( datapath id %#" PRIx64 " ).", sw_info->datapath_id );
384
+ switch_event_disconnected( sw_info );
385
+ }
386
+
387
+
388
+ static void
389
+ confirm_self_dpid_is_registered( uint64_t* dpids, size_t n_dpids, void *user_data );
372
390
 
373
391
 
374
392
  int
@@ -381,7 +399,7 @@ switch_event_recv_featuresreply( struct switch_info *sw_info, uint64_t *dpid ) {
381
399
  case SWITCH_STATE_WAIT_FEATURES_REPLY:
382
400
 
383
401
  sw_info->datapath_id = *dpid;
384
- sw_info->state = SWITCH_STATE_COMPLETED;
402
+ sw_info->state = SWITCH_STATE_WAIT_REGISTRATION;
385
403
 
386
404
  // cancel to features_reply_wait-timeout timer
387
405
  switch_unset_timeout( switch_event_timeout_features_reply, NULL );
@@ -392,7 +410,7 @@ switch_event_recv_featuresreply( struct switch_info *sw_info, uint64_t *dpid ) {
392
410
  // checking duplicate service
393
411
  pid_t pid = get_pid_by_trema_name( new_service_name );
394
412
  if ( pid > 0 ) {
395
- // duplicated
413
+ debug( "duplicated datapath-id %#" PRIx64, sw_info->datapath_id );
396
414
  if ( !terminate_trema_process( pid ) ) {
397
415
  return -1;
398
416
  }
@@ -440,12 +458,17 @@ switch_event_recv_featuresreply( struct switch_info *sw_info, uint64_t *dpid ) {
440
458
  init_event_forward_interface();
441
459
  // Check switch_manager registration
442
460
  debug( "Checking switch manager's switch list." );
443
- if ( !send_efi_switch_list_request( confirm_self_dpid_is_registerd, sw_info ) ) {
461
+ sw_info->retry_count = REGISTRATION_RETRY_COUNT;
462
+ if ( send_efi_switch_list_request( confirm_self_dpid_is_registered, sw_info ) ) {
463
+ switch_set_timeout( REGISTRATION_TIMEOUT, registration_timeout, sw_info );
464
+ }
465
+ else {
444
466
  error( "Failed to send switch list request to switch manager." );
445
467
  return -1;
446
468
  }
447
469
  break;
448
470
 
471
+ case SWITCH_STATE_WAIT_REGISTRATION:
449
472
  case SWITCH_STATE_COMPLETED:
450
473
  // NOP
451
474
  break;
@@ -462,47 +485,118 @@ switch_event_recv_featuresreply( struct switch_info *sw_info, uint64_t *dpid ) {
462
485
 
463
486
 
464
487
  static void
465
- notify_state_to_controllers( struct switch_info *sw_info );
488
+ registration_retry( void *user_data ) {
489
+ struct switch_info *sw_info = user_data;
490
+
491
+ if ( sw_info->retry_count == 0 ) {
492
+ switch_event_disconnected( sw_info );
493
+ return;
494
+ }
495
+ sw_info->retry_count--;
496
+ sw_info->running_timer = false;
497
+ debug( "Checking switch manager's switch list." );
498
+ if ( send_efi_switch_list_request( confirm_self_dpid_is_registered, sw_info ) ) {
499
+ switch_set_timeout( REGISTRATION_TIMEOUT, registration_timeout, sw_info );
500
+ }
501
+ else {
502
+ error( "Failed to send switch list request to switch manager." );
503
+ switch_event_disconnected( sw_info );
504
+ }
505
+ }
466
506
 
467
507
 
468
508
  static void
469
- confirm_self_dpid_is_registerd( uint64_t* dpids, size_t n_dpids, void *user_data ) {
509
+ confirm_self_dpid_is_registered( uint64_t* dpids, size_t n_dpids, void *user_data ) {
470
510
  struct switch_info *sw_info = user_data;
471
511
 
512
+ switch_unset_timeout( registration_timeout, sw_info );
513
+
472
514
  debug( "Received switch manager's switch list." );
515
+ bool found = false;
473
516
  for ( size_t i = 0 ; i < n_dpids ; ++i ) {
474
517
  if ( sw_info->datapath_id == dpids[ i ] ) {
475
518
  // self dpid registered
476
519
  debug( "Self dpid found" );
477
- return notify_state_to_controllers( sw_info );
520
+ found = true;
521
+ break;
478
522
  }
479
523
  }
524
+ if ( found ) {
525
+ sw_info->state = SWITCH_STATE_COMPLETED;
480
526
 
481
- debug( "Self dpid not found. Retrying..." );
482
- if ( !send_efi_switch_list_request( confirm_self_dpid_is_registerd, sw_info ) ){
483
- error( "Failed to send switch list request to switch manager on retry." );
527
+ // notify state and datapath_id to controllers
528
+ service_send_state( sw_info, &sw_info->datapath_id, MESSENGER_OPENFLOW_READY );
529
+ debug( "send ready state" );
530
+
531
+ add_periodic_event_callback( ECHO_REQUEST_INTERVAL, echo_request_interval, sw_info );
532
+ }
533
+ else {
534
+ debug( "Self dpid not found. Retrying..." );
535
+ switch_set_timeout( REGISTRATION_RETRY, registration_retry, sw_info );
484
536
  }
485
537
  }
486
538
 
487
539
 
488
540
  static void
489
- notify_state_to_controllers( struct switch_info *sw_info ) {
490
- // notify state and datapath_id to controllers
491
- service_send_state( sw_info, &sw_info->datapath_id, MESSENGER_OPENFLOW_READY );
492
- debug( "send ready state" );
541
+ stop_switch( struct switch_info *sw_info ) {
542
+ if ( sw_info->secure_channel_fd >= 0 ) {
543
+ close( sw_info->secure_channel_fd );
544
+ sw_info->secure_channel_fd = -1;
545
+ }
546
+ uint8_t state = MESSENGER_OPENFLOW_DISCONNECTED;
547
+ if ( sw_info->state == SWITCH_STATE_CONNECTION_FAILED ) {
548
+ state = MESSENGER_OPENFLOW_FAILD_TO_CONNECT;
549
+ }
550
+ service_send_state( sw_info, &sw_info->datapath_id, state );
551
+ flush_messenger();
493
552
 
494
- add_periodic_event_callback( ECHO_REQUEST_INTERVAL, echo_request_interval, sw_info );
495
- }
553
+ // free service name list
554
+ iterate_list( sw_info->vendor_service_name_list, xfree_data, NULL );
555
+ delete_list( sw_info->vendor_service_name_list );
556
+ sw_info->vendor_service_name_list = NULL;
557
+ iterate_list( sw_info->packetin_service_name_list, xfree_data, NULL );
558
+ delete_list( sw_info->packetin_service_name_list );
559
+ sw_info->packetin_service_name_list = NULL;
560
+ iterate_list( sw_info->portstatus_service_name_list, xfree_data, NULL );
561
+ delete_list( sw_info->portstatus_service_name_list );
562
+ sw_info->portstatus_service_name_list = NULL;
563
+ iterate_list( sw_info->state_service_name_list, xfree_data, NULL );
564
+ delete_list( sw_info->state_service_name_list );
565
+ sw_info->state_service_name_list = NULL;
566
+
567
+ stop_trema();
568
+ }
569
+
570
+
571
+ static void
572
+ unregistration_timeout( void *user_data ) {
573
+ struct switch_info *sw_info = user_data;
574
+
575
+ sw_info->running_timer = false;
576
+
577
+ warn( "Unregistration timeout ( datapath id %#" PRIx64 " ).", sw_info->datapath_id );
578
+
579
+ stop_switch( sw_info );
580
+ }
581
+
582
+
583
+ static void
584
+ confirm_self_dpid_is_unregistered( uint64_t* dpids, size_t n_dpids, void *user_data );
496
585
 
497
586
 
498
587
  int
499
588
  switch_event_disconnected( struct switch_info *sw_info ) {
500
589
  int old_state = sw_info->state;
501
590
 
502
- sw_info->state = SWITCH_STATE_DISCONNECTED;
591
+ if ( sw_info->state == SWITCH_STATE_COMPLETED ) {
592
+ sw_info->state = SWITCH_STATE_DISCONNECTED;
593
+ }
594
+ else {
595
+ sw_info->state = SWITCH_STATE_CONNECTION_FAILED;
596
+ }
503
597
 
504
598
  if ( old_state == SWITCH_STATE_COMPLETED ) {
505
- delete_timer_event( echo_request_interval, sw_info );
599
+ switch_unset_timeout( echo_reply_timeout, NULL );
506
600
  }
507
601
 
508
602
  if ( sw_info->fragment_buf != NULL ) {
@@ -524,37 +618,80 @@ switch_event_disconnected( struct switch_info *sw_info ) {
524
618
  set_readable( switch_info.secure_channel_fd, false );
525
619
  set_writable( switch_info.secure_channel_fd, false );
526
620
  delete_fd_handler( switch_info.secure_channel_fd );
621
+ }
527
622
 
528
- close( sw_info->secure_channel_fd );
529
- sw_info->secure_channel_fd = -1;
623
+ uint8_t state = MESSENGER_OPENFLOW_DISCONNECTED;
624
+ if ( sw_info->state == SWITCH_STATE_CONNECTION_FAILED ) {
625
+ state = MESSENGER_OPENFLOW_FAILD_TO_CONNECT;
530
626
  }
531
627
 
532
- if ( old_state != SWITCH_STATE_COMPLETED ) {
533
- service_send_state( sw_info, &sw_info->datapath_id, MESSENGER_OPENFLOW_FAILD_TO_CONNECT );
628
+ debug( "Notify switch_disconnected to switch manager." );
629
+ char switch_manager[] = SWITCH_MANAGER;
630
+ list_element switch_manager_only_list;
631
+ switch_manager_only_list.next = NULL;
632
+ switch_manager_only_list.data = switch_manager;
633
+ service_send_to_application( &switch_manager_only_list, state, &sw_info->datapath_id, NULL );
634
+
635
+ // Check switch_manager registration
636
+ debug( "Checking switch manager's switch list." );
637
+ sw_info->retry_count = UNREGISTRATION_RETRY_COUNT;
638
+ if ( send_efi_switch_list_request( confirm_self_dpid_is_unregistered, sw_info ) ) {
639
+ switch_set_timeout( UNREGISTRATION_TIMEOUT, unregistration_timeout, sw_info );
534
640
  }
535
641
  else {
536
- // send secure channle disconnect state to application
537
- service_send_state( sw_info, &sw_info->datapath_id, MESSENGER_OPENFLOW_DISCONNECTED );
642
+ error( "Failed to send switch list request to switch manager." );
643
+ stop_switch( sw_info );
538
644
  }
539
- flush_messenger();
540
645
 
541
- // free service name list
542
- iterate_list( sw_info->vendor_service_name_list, xfree_data, NULL );
543
- delete_list( sw_info->vendor_service_name_list );
544
- sw_info->vendor_service_name_list = NULL;
545
- iterate_list( sw_info->packetin_service_name_list, xfree_data, NULL );
546
- delete_list( sw_info->packetin_service_name_list );
547
- sw_info->packetin_service_name_list = NULL;
548
- iterate_list( sw_info->portstatus_service_name_list, xfree_data, NULL );
549
- delete_list( sw_info->portstatus_service_name_list );
550
- sw_info->portstatus_service_name_list = NULL;
551
- iterate_list( sw_info->state_service_name_list, xfree_data, NULL );
552
- delete_list( sw_info->state_service_name_list );
553
- sw_info->state_service_name_list = NULL;
646
+ return 0;
647
+ }
554
648
 
555
- stop_trema();
556
649
 
557
- return 0;
650
+ static void
651
+ unregistration_retry( void *user_data ) {
652
+ struct switch_info *sw_info = user_data;
653
+
654
+ if ( sw_info->retry_count == 0 ) {
655
+ stop_switch( sw_info );
656
+ return;
657
+ }
658
+ sw_info->retry_count--;
659
+ sw_info->running_timer = false;
660
+ debug( "Checking switch manager's switch list." );
661
+ if ( send_efi_switch_list_request( confirm_self_dpid_is_unregistered, sw_info ) ) {
662
+ switch_set_timeout( UNREGISTRATION_TIMEOUT, unregistration_timeout, sw_info );
663
+ }
664
+ else {
665
+ error( "Failed to send switch list request to switch manager." );
666
+ stop_switch( sw_info );
667
+ }
668
+ }
669
+
670
+
671
+ static void
672
+ confirm_self_dpid_is_unregistered( uint64_t* dpids, size_t n_dpids, void *user_data ) {
673
+ struct switch_info *sw_info = user_data;
674
+
675
+ switch_unset_timeout( unregistration_timeout, sw_info );
676
+
677
+ debug( "Received switch manager's switch list." );
678
+ bool found = false;
679
+ for ( size_t i = 0 ; i < n_dpids ; ++i ) {
680
+ if ( sw_info->datapath_id == dpids[ i ] ) {
681
+ // self dpid registered
682
+ debug( "Self dpid found" );
683
+ found = true;
684
+ break;
685
+ }
686
+ }
687
+ if ( found ) {
688
+ debug( "Self dpid found. Retrying..." );
689
+ switch_set_timeout( UNREGISTRATION_RETRY, unregistration_retry, sw_info );
690
+ }
691
+ else {
692
+ // The switch has been deleted from the switch list
693
+ stop_switch( sw_info );
694
+ }
558
695
  }
559
696
 
560
697