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/.travis.yml +2 -0
- data/CONTRIBUTING.md +12 -0
- data/Gemfile +5 -3
- data/README.md +3 -3
- data/Rakefile +30 -14
- data/bin/trema +3 -0
- data/cruise.rb +1 -1
- data/features/examples/switch_monitor.feature +2 -2
- data/features/switch_event/add_forward_entry.feature +0 -1
- data/features/switch_event/delete_forward_entry.feature +0 -1
- data/features/switch_event/dump_forward_entries.feature +0 -1
- data/features/switch_event/set_forward_entries.feature +0 -1
- data/ruby/trema/command/run.rb +3 -0
- data/ruby/trema/dsl/runner.rb +1 -0
- data/ruby/trema/mac.rb +4 -145
- data/ruby/trema/match.c +8 -8
- data/ruby/trema/packet-in.c +12 -12
- data/ruby/trema/port-mod.c +7 -4
- data/ruby/trema/port.c +4 -1
- data/ruby/trema/set-eth-dst-addr.rb +3 -5
- data/ruby/trema/set-eth-src-addr.rb +5 -6
- data/ruby/trema/stats-reply.c +1 -1
- data/ruby/trema/switch-event.c +10 -10
- data/ruby/trema/trema.c +3 -0
- data/ruby/trema/version.rb +1 -1
- data/spec/spec_helper.rb +1 -1
- data/spec/trema/packet-in_spec.rb +2 -2
- data/spec/trema/set-eth-addr_spec.rb +5 -43
- data/src/examples/learning_switch/learning-switch.rb +2 -0
- data/src/lib/daemon.c +37 -22
- data/src/lib/log.c +31 -0
- data/src/lib/messenger.c +13 -5
- data/src/lib/trema.c +6 -5
- data/src/switch_manager/switch.c +178 -41
- data/src/switch_manager/switchinfo.h +6 -2
- data/trema.gemspec +3 -3
- data/unittests/lib/daemon_test.c +36 -36
- data/unittests/lib/trema_test.c +25 -8
- metadata +124 -96
- checksums.yaml +0 -7
- data/spec/trema/mac_spec.rb +0 -100
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
|
-
|
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
|
-
|
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
|
103
|
-
#undef
|
102
|
+
#ifdef clock_nanosleep
|
103
|
+
#undef clock_nanosleep
|
104
104
|
#endif
|
105
|
-
#define
|
106
|
-
unsigned int
|
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
|
-
|
746
|
+
clock_nanosleep( CLOCK_MONOTONIC, 0, &tv, NULL );
|
746
747
|
}
|
747
748
|
if ( try > max_try ) {
|
748
749
|
error( "Failed to terminate %d.", pid );
|
data/src/switch_manager/switch.c
CHANGED
@@ -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; //
|
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
|
-
|
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 =
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
520
|
+
found = true;
|
521
|
+
break;
|
478
522
|
}
|
479
523
|
}
|
524
|
+
if ( found ) {
|
525
|
+
sw_info->state = SWITCH_STATE_COMPLETED;
|
480
526
|
|
481
|
-
|
482
|
-
|
483
|
-
|
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
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
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
|
-
|
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
|
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
|
-
|
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
|
-
|
529
|
-
|
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
|
-
|
533
|
-
|
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
|
-
|
537
|
-
|
642
|
+
error( "Failed to send switch list request to switch manager." );
|
643
|
+
stop_switch( sw_info );
|
538
644
|
}
|
539
|
-
flush_messenger();
|
540
645
|
|
541
|
-
|
542
|
-
|
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
|
-
|
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
|
|