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/.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
|
|