static bool insert_wildcards_match_entry( list_element **wildcards_table, struct ofp_match *match, uint16_t priority, void *data ) { assert( match != NULL ); list_element *element; for ( element = *wildcards_table; element != NULL; element = element->next ) { match_entry *entry = element->data; if ( entry->priority < priority ) { break; } assert( entry != NULL ); if ( entry->priority == priority && compare_match_strict( &entry->match, match ) ) { char match_string[ MATCH_STRING_LENGTH ]; match_to_string( match, match_string, sizeof( match_string ) ); warn( "wildcards match entry already exists ( match = [%s], priority = %u )", match_string, priority ); return false; } } match_entry *new_entry = allocate_match_entry( match, priority, data ); if ( element == NULL ) { // tail append_to_tail( wildcards_table, new_entry ); } else if ( element == *wildcards_table ) { // head insert_in_front( wildcards_table, new_entry ); } else { // insert before insert_before( wildcards_table, element->data, new_entry ); } return true; }
static OFDPE insert_flow_entry( flow_table *table, flow_entry *entry, const uint16_t flags ) { assert( table != NULL ); assert( entry != NULL ); list_element *element = table->entries; while( element != NULL ) { list_element *next = element->next; flow_entry *e = element->data; assert( e != NULL ); if ( e->priority < entry->priority ) { break; } if ( e->priority == entry->priority ) { if ( e->table_miss && !entry->table_miss ) { break; } if ( ( flags & OFPFF_CHECK_OVERLAP ) != 0 && compare_match( e->match, entry->match ) ) { return ERROR_OFDPE_FLOW_MOD_FAILED_OVERLAP; } if ( compare_match_strict( e->match, entry->match ) ) { if ( ( flags & OFPFF_RESET_COUNTS ) != 0 ) { entry->byte_count = e->byte_count; entry->packet_count = e->packet_count; } flow_table *table = get_flow_table( e->table_id ); assert( table != NULL ); delete_flow_entry_from_table( table, e, 0, false ); } } element = next; } if ( element == NULL ) { // tail append_to_tail( &table->entries, entry ); } else if ( element == table->entries ) { // head insert_in_front( &table->entries, entry ); } else { // insert before insert_before( &table->entries, element->data, entry ); } increment_active_count( table->features.table_id ); return OFDPE_SUCCESS; }
void insert_match_entry( struct ofp_match *ofp_match, uint16_t priority, const char *service_name, const char *entry_name ) { match_entry *new_entry, *entry; list_element *list; pthread_mutex_lock( match_table_head.mutex ); new_entry = allocate_match_entry( ofp_match, priority, service_name, entry_name ); if ( !ofp_match->wildcards ) { entry = lookup_hash_entry( match_table_head.exact_table, ofp_match ); if ( entry != NULL ) { warn( "insert entry exits" ); free_match_entry( new_entry ); pthread_mutex_unlock( match_table_head.mutex ); return; } insert_hash_entry( match_table_head.exact_table, &new_entry->ofp_match, new_entry ); pthread_mutex_unlock( match_table_head.mutex ); return; } // wildcard flags are set for ( list = match_table_head.wildcard_table; list != NULL; list = list->next ) { entry = list->data; if ( entry->priority <= new_entry->priority ) { break; } } if ( list == NULL ) { // wildcard_table is null or tail append_to_tail( &match_table_head.wildcard_table, new_entry ); pthread_mutex_unlock( match_table_head.mutex ); return; } if ( list == match_table_head.wildcard_table ) { // head insert_in_front( &match_table_head.wildcard_table, new_entry ); pthread_mutex_unlock( match_table_head.mutex ); return; } // insert brefore insert_before( &match_table_head.wildcard_table, list->data, new_entry ); pthread_mutex_unlock( match_table_head.mutex ); }
static void insert_data( list_element **head, const topology_link_status *s ) { list_element *element; for ( element = *head; element != NULL; element = element->next ) { const topology_link_status *entry = element->data; if ( entry->from_dpid > s->from_dpid ) { break; } if ( entry->from_dpid < s->from_dpid ) { continue; } if ( entry->from_portno > s->from_portno ) { break; } if ( entry->from_portno < s->from_portno ) { continue; } if ( entry->to_dpid > s->to_dpid ) { break; } if ( entry->to_dpid < s->to_dpid ) { continue; } if ( entry->to_portno > s->to_portno ) { break; } } if ( element == NULL ) { append_to_tail( head, ( void * ) ( intptr_t ) s ); } else if ( element == *head ) { insert_in_front( head, ( void * ) ( intptr_t ) s ); } else { insert_before( head, element->data, ( void * ) ( intptr_t ) s ); } }
int main( int argc, char *argv[] ) { int ret; int i; char *service_name; char management_service_name[ MESSENGER_SERVICE_NAME_LENGTH ]; init_trema( &argc, &argv ); option_parser( argc, argv ); create_list( &switch_info.vendor_service_name_list ); create_list( &switch_info.packetin_service_name_list ); create_list( &switch_info.portstatus_service_name_list ); create_list( &switch_info.state_service_name_list ); // FIXME #define VENDER_PREFIX "vendor::" #define PACKET_IN_PREFIX "packet_in::" #define PORTSTATUS_PREFIX "port_status::" #define STATE_PREFIX "state_notify::" for ( i = optind; i < argc; i++ ) { if ( strncmp( argv[i], VENDER_PREFIX, strlen( VENDER_PREFIX ) ) == 0 ) { service_name = xstrdup( argv[i] + strlen( VENDER_PREFIX ) ); insert_in_front( &switch_info.vendor_service_name_list, service_name ); } else if ( strncmp( argv[i], PACKET_IN_PREFIX, strlen( PACKET_IN_PREFIX ) ) == 0 ) { service_name = xstrdup( argv[i] + strlen( PACKET_IN_PREFIX ) ); insert_in_front( &switch_info.packetin_service_name_list, service_name ); } else if ( strncmp( argv[i], PORTSTATUS_PREFIX, strlen( PORTSTATUS_PREFIX ) ) == 0 ) { service_name = xstrdup( argv[i] + strlen( PORTSTATUS_PREFIX ) ); insert_in_front( &switch_info.portstatus_service_name_list, service_name ); } else if ( strncmp( argv[i], STATE_PREFIX, strlen( STATE_PREFIX ) ) == 0 ) { service_name = xstrdup( argv[i] + strlen( STATE_PREFIX ) ); insert_in_front( &switch_info.state_service_name_list, service_name ); } } fcntl( switch_info.secure_channel_fd, F_SETFL, O_NONBLOCK ); // default switch configuration switch_info.config_flags = OFPC_FRAG_NORMAL; switch_info.miss_send_len = UINT16_MAX; switch_info.fragment_buf = NULL; switch_info.send_queue = create_message_queue(); switch_info.recv_queue = create_message_queue(); init_xid_table(); init_cookie_table(); set_fd_set_callback( secure_channel_fd_set ); set_check_fd_isset_callback( secure_channel_fd_isset ); add_message_received_callback( get_trema_name(), service_recv ); snprintf( management_service_name , MESSENGER_SERVICE_NAME_LENGTH, "%s.m", get_trema_name() ); management_service_name[ MESSENGER_SERVICE_NAME_LENGTH - 1 ] = '\0'; add_message_received_callback( management_service_name, management_recv ); ret = switch_event_connected( &switch_info ); if ( ret < 0 ) { error( "Failed to set connected state." ); return -1; } start_trema(); finalize_xid_table(); finalize_cookie_table(); return 0; }
int main( int argc, char *argv[] ) { int ret; int i; char *service_name; char management_service_name[ MESSENGER_SERVICE_NAME_LENGTH ]; init_trema( &argc, &argv ); option_parser( argc, argv ); create_list( &switch_info.vendor_service_name_list ); create_list( &switch_info.packetin_service_name_list ); create_list( &switch_info.portstatus_service_name_list ); create_list( &switch_info.state_service_name_list ); // FIXME #define VENDER_PREFIX "vendor::" #define PACKET_IN_PREFIX "packet_in::" #define PORTSTATUS_PREFIX "port_status::" #define STATE_PREFIX "state_notify::" for ( i = optind; i < argc; i++ ) { if ( strncmp( argv[i], VENDER_PREFIX, strlen( VENDER_PREFIX ) ) == 0 ) { service_name = xstrdup( argv[i] + strlen( VENDER_PREFIX ) ); insert_in_front( &switch_info.vendor_service_name_list, service_name ); } else if ( strncmp( argv[i], PACKET_IN_PREFIX, strlen( PACKET_IN_PREFIX ) ) == 0 ) { service_name = xstrdup( argv[i] + strlen( PACKET_IN_PREFIX ) ); insert_in_front( &switch_info.packetin_service_name_list, service_name ); } else if ( strncmp( argv[i], PORTSTATUS_PREFIX, strlen( PORTSTATUS_PREFIX ) ) == 0 ) { service_name = xstrdup( argv[i] + strlen( PORTSTATUS_PREFIX ) ); insert_in_front( &switch_info.portstatus_service_name_list, service_name ); } else if ( strncmp( argv[i], STATE_PREFIX, strlen( STATE_PREFIX ) ) == 0 ) { service_name = xstrdup( argv[i] + strlen( STATE_PREFIX ) ); insert_in_front( &switch_info.state_service_name_list, service_name ); } } struct sigaction signal_exit; memset( &signal_exit, 0, sizeof( struct sigaction ) ); signal_exit.sa_handler = handle_sigterm; sigaction( SIGINT, &signal_exit, NULL ); sigaction( SIGTERM, &signal_exit, NULL ); fcntl( switch_info.secure_channel_fd, F_SETFL, O_NONBLOCK ); set_fd_handler( switch_info.secure_channel_fd, secure_channel_read, NULL, secure_channel_write, NULL ); set_readable( switch_info.secure_channel_fd, true ); set_writable( switch_info.secure_channel_fd, false ); // default switch configuration switch_info.config_flags = OFPC_FRAG_NORMAL; switch_info.miss_send_len = UINT16_MAX; switch_info.fragment_buf = NULL; switch_info.send_queue = create_message_queue(); switch_info.recv_queue = create_message_queue(); switch_info.running_timer = false; switch_info.echo_request_xid = 0; init_xid_table(); if ( switch_info.cookie_translation ) { init_cookie_table(); } add_message_received_callback( get_trema_name(), service_recv ); snprintf( management_service_name , MESSENGER_SERVICE_NAME_LENGTH, "%s.m", get_trema_name() ); management_service_name[ MESSENGER_SERVICE_NAME_LENGTH - 1 ] = '\0'; add_message_received_callback( management_service_name, management_recv ); ret = switch_event_connected( &switch_info ); if ( ret < 0 ) { error( "Failed to set connected state." ); return -1; } flush_secure_channel( &switch_info ); start_trema(); finalize_xid_table(); if ( switch_info.cookie_translation ) { finalize_cookie_table(); } if ( switch_info.secure_channel_fd >= 0 ) { delete_fd_handler( switch_info.secure_channel_fd ); } return 0; }