trema 0.4.3 → 0.4.4

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