static void stop_switch() { if ( switch_info.secure_channel_fd >= 0 ) { close( switch_info.secure_channel_fd ); switch_info.secure_channel_fd = -1; } uint8_t state = MESSENGER_OPENFLOW_DISCONNECTED; if ( switch_info.state == SWITCH_STATE_CONNECTION_FAILED ) { state = MESSENGER_OPENFLOW_FAILD_TO_CONNECT; } service_send_state( &switch_info, &switch_info.datapath_id, state ); flush_messenger(); // free service name list iterate_list( switch_info.vendor_service_name_list, xfree_data, NULL ); delete_list( switch_info.vendor_service_name_list ); switch_info.vendor_service_name_list = NULL; iterate_list( switch_info.packetin_service_name_list, xfree_data, NULL ); delete_list( switch_info.packetin_service_name_list ); switch_info.packetin_service_name_list = NULL; iterate_list( switch_info.portstatus_service_name_list, xfree_data, NULL ); delete_list( switch_info.portstatus_service_name_list ); switch_info.portstatus_service_name_list = NULL; iterate_list( switch_info.state_service_name_list, xfree_data, NULL ); delete_list( switch_info.state_service_name_list ); switch_info.state_service_name_list = NULL; stop_trema(); }
int switch_event_disconnected( struct switch_info *sw_info ) { sw_info->state = SWITCH_STATE_DISCONNECTED; if ( sw_info->fragment_buf != NULL ) { free_buffer( sw_info->fragment_buf ); sw_info->fragment_buf = NULL; } if ( sw_info->send_queue != NULL ) { delete_message_queue( sw_info->send_queue ); sw_info->send_queue = NULL; } if ( sw_info->recv_queue != NULL ) { delete_message_queue( sw_info->recv_queue ); sw_info->recv_queue = NULL; } if ( sw_info->secure_channel_fd >= 0 ) { close( sw_info->secure_channel_fd ); sw_info->secure_channel_fd = -1; } // send secure channle disconnect state to application service_send_state( sw_info, &sw_info->datapath_id, MESSENGER_OPENFLOW_DISCONNECTED ); flush_messenger(); debug( "send disconnected state" ); stop_messenger(); return 0; }
static void confirm_self_dpid_is_registered( const list_element *switches, void *user_data ) { struct switch_info *sw_info = user_data; switch_unset_timeout( registration_timeout, sw_info ); debug( "Received switch manager's switch list." ); bool found = false; for ( const list_element *e = switches; e != NULL; e = e->next ) { if ( sw_info->datapath_id == *( uint64_t * ) e->data ) { // self dpid registered debug( "Self dpid found" ); found = true; break; } } if ( found ) { sw_info->state = SWITCH_STATE_COMPLETED; finalize_openflow_application_interface(); // notify state and datapath_id to controllers service_send_state( sw_info, &sw_info->datapath_id, MESSENGER_OPENFLOW_READY ); debug( "send ready state" ); add_periodic_event_callback( ECHO_REQUEST_INTERVAL, echo_request_interval, sw_info ); } else { debug( "Self dpid not found. Retrying..." ); switch_set_timeout( REGISTRATION_RETRY, registration_retry, sw_info ); } }
int switch_event_disconnected( struct switch_info *sw_info ) { int old_state = sw_info->state; sw_info->state = SWITCH_STATE_DISCONNECTED; if ( old_state == SWITCH_STATE_COMPLETED ) { delete_timer_event( echo_request_interval, sw_info ); } if ( sw_info->fragment_buf != NULL ) { free_buffer( sw_info->fragment_buf ); sw_info->fragment_buf = NULL; } if ( sw_info->send_queue != NULL ) { delete_message_queue( sw_info->send_queue ); sw_info->send_queue = NULL; } if ( sw_info->recv_queue != NULL ) { delete_message_queue( sw_info->recv_queue ); sw_info->recv_queue = NULL; } if ( sw_info->secure_channel_fd >= 0 ) { set_readable( switch_info.secure_channel_fd, false ); set_writable( switch_info.secure_channel_fd, false ); delete_fd_handler( switch_info.secure_channel_fd ); close( sw_info->secure_channel_fd ); sw_info->secure_channel_fd = -1; } if ( old_state != SWITCH_STATE_COMPLETED ) { service_send_state( sw_info, &sw_info->datapath_id, MESSENGER_OPENFLOW_FAILD_TO_CONNECT ); } else { // send secure channle disconnect state to application service_send_state( sw_info, &sw_info->datapath_id, MESSENGER_OPENFLOW_DISCONNECTED ); } flush_messenger(); stop_trema(); return 0; }
int switch_event_recv_featuresreply( struct switch_info *sw_info, uint64_t *dpid ) { int ret; uint16_t new_service_name_len; char *new_service_name; switch ( sw_info->state ) { case SWITCH_STATE_WAIT_FEATURES_REPLY: sw_info->datapath_id = *dpid; sw_info->state = SWITCH_STATE_COMPLETED; // cancel to features_reply_wait-timeout timer switch_unset_timeout( switch_event_timeout_features_reply ); // TODO: change process name // TODO: set keepalive-timeout new_service_name_len = SWITCH_MANAGER_PREFIX_STR_LEN + SWITCH_MANAGER_DPID_STR_LEN + 1; new_service_name = xmalloc( new_service_name_len ); snprintf( new_service_name, new_service_name_len, "%s%" PRIx64, SWITCH_MANAGER_PREFIX, sw_info->datapath_id ); // rename service_name of messenger rename_message_received_callback( get_trema_name(), new_service_name ); debug( "Rename service name to %s from %s.", new_service_name, get_trema_name() ); if ( messenger_dump_enabled() ) { stop_messenger_dump(); start_messenger_dump( new_service_name, DEFAULT_DUMP_SERVICE_NAME ); } // notify state and datapath_id service_send_state( sw_info, &sw_info->datapath_id, MESSENGER_OPENFLOW_READY ); debug( "send ready state" ); ret = ofpmsg_send_setconfig( sw_info ); if ( ret < 0 ) { return ret; } ret = ofpmsg_send_delete_all_flows( sw_info ); if ( ret < 0 ) { return ret; } break; case SWITCH_STATE_COMPLETED: // NOP break; default: notice( "Invalid event 'features reply' from a switch." ); return -1; break; } return 0; }
int switch_event_connected( struct switch_info *sw_info ) { int ret; // send secure channel disconnect state to application service_send_state( sw_info, &sw_info->datapath_id, MESSENGER_OPENFLOW_CONNECTED ); debug( "Send connected state" ); ret = ofpmsg_send_hello( sw_info ); if ( ret < 0 ) { return ret; } sw_info->state = SWITCH_STATE_WAIT_HELLO; switch_set_timeout( SWITCH_STATE_TIMEOUT_HELLO, switch_event_timeout_hello, NULL ); return 0; }
int switch_event_recv_featuresreply( struct switch_info *sw_info, uint64_t *dpid ) { int ret; char new_service_name[ SWITCH_MANAGER_PREFIX_STR_LEN + SWITCH_MANAGER_DPID_STR_LEN + 1 ]; const uint16_t new_service_name_len = SWITCH_MANAGER_PREFIX_STR_LEN + SWITCH_MANAGER_DPID_STR_LEN + 1; switch ( sw_info->state ) { case SWITCH_STATE_WAIT_FEATURES_REPLY: sw_info->datapath_id = *dpid; sw_info->state = SWITCH_STATE_COMPLETED; // cancel to features_reply_wait-timeout timer switch_unset_timeout( switch_event_timeout_features_reply, NULL ); // TODO: set keepalive-timeout snprintf( new_service_name, new_service_name_len, "%s%#" PRIx64, SWITCH_MANAGER_PREFIX, sw_info->datapath_id ); // checking duplicate service pid_t pid = get_trema_process_from_name( new_service_name ); if ( pid > 0 ) { // duplicated if ( !terminate_trema_process( pid ) ) { return -1; } } // rename service_name of messenger rename_message_received_callback( get_trema_name(), new_service_name ); debug( "Rename service name from %s to %s.", get_trema_name(), new_service_name ); if ( messenger_dump_enabled() ) { stop_messenger_dump(); start_messenger_dump( new_service_name, DEFAULT_DUMP_SERVICE_NAME ); } set_trema_name( new_service_name ); // notify state and datapath_id service_send_state( sw_info, &sw_info->datapath_id, MESSENGER_OPENFLOW_READY ); debug( "send ready state" ); ret = ofpmsg_send_setconfig( sw_info ); if ( ret < 0 ) { return ret; } if ( switch_info.flow_cleanup ) { ret = ofpmsg_send_delete_all_flows( sw_info ); if ( ret < 0 ) { return ret; } } break; case SWITCH_STATE_COMPLETED: // NOP break; default: notice( "Invalid event 'features reply' from a switch." ); return -1; break; } return 0; }