void delete_match_entry( struct ofp_match *ofp_match ) { match_entry *delete_entry; list_element *list; pthread_mutex_lock( match_table_head.mutex ); assert( ofp_match != NULL ); if ( !ofp_match->wildcards ) { delete_entry = delete_hash_entry( match_table_head.exact_table, ofp_match ); if ( delete_entry == NULL ) { pthread_mutex_unlock( match_table_head.mutex ); return; } } else { for ( list = match_table_head.wildcard_table; list != NULL; list = list->next ) { delete_entry = list->data; if ( ( ( ( delete_entry->ofp_match.wildcards ^ ofp_match->wildcards ) & OFPFW_ALL ) == 0 ) && compare_match( &delete_entry->ofp_match, ofp_match ) ) { break; } } if ( list == NULL ) { pthread_mutex_unlock( match_table_head.mutex ); return; } delete_element( &match_table_head.wildcard_table, delete_entry ); } free_match_entry( delete_entry ); pthread_mutex_unlock( match_table_head.mutex ); }
static void free_match_table_walker( void *key, void *value, void *user_data ) { match_entry *entry = value; UNUSED( key ); UNUSED( user_data ); free_match_entry( entry ); }
static void finalize_wildcards_match_table( list_element *wildcards_table ) { list_element *element; for ( element = wildcards_table; element != NULL; element = element->next ) { free_match_entry( element->data ); element->data = NULL; } delete_list( wildcards_table ); }
static void free_exact_match_entry( void *key, void *value, void *user_data ) { UNUSED( key ); assert( value != NULL ); UNUSED( user_data ); match_entry *entry = value; free_match_entry( entry ); }
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 * delete_wildcards_match_strict_entry( list_element **wildcards_table, struct ofp_match *match, uint16_t priority ) { assert( match != NULL ); match_entry *entry = lookup_wildcards_match_strict_entry( *wildcards_table, match, priority ); if ( entry == NULL ) { char match_string[ MATCH_STRING_LENGTH ]; match_to_string( match, match_string, sizeof( match_string ) ); warn( "wildcards match entry not found ( match = [%s], priority = %u )", match_string, priority ); return NULL; } void *data = entry->data; delete_element( wildcards_table, entry ); free_match_entry( entry ); return data; }
static void * delete_exact_match_strict_entry( hash_table *exact_table, struct ofp_match *match ) { assert( exact_table != NULL ); assert( match != NULL ); match_entry *entry = lookup_hash_entry( exact_table, match ); if ( entry == NULL ) { char match_string[ MATCH_STRING_LENGTH ]; match_to_string( match, match_string, sizeof( match_string ) ); warn( "exact match entry not found ( match = [%s] )", match_string ); return NULL; } void *data = entry->data; delete_hash_entry( exact_table, match ); free_match_entry( entry ); return data; }
void finalize_match_table( void ) { list_element *list; pthread_mutex_lock( match_table_head.mutex ); foreach_hash( match_table_head.exact_table, free_match_table_walker, NULL ); delete_hash( match_table_head.exact_table ); match_table_head.exact_table = NULL; for ( list = match_table_head.wildcard_table; list != NULL; list = list->next ) { free_match_entry( list->data ); } delete_list( match_table_head.wildcard_table ); match_table_head.wildcard_table = NULL; pthread_mutex_unlock( match_table_head.mutex ); pthread_mutex_destroy( match_table_head.mutex ); xfree( match_table_head.mutex ); match_table_head.mutex = NULL; }