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; }
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 bool insert_exact_match_entry( hash_table *exact_table, struct ofp_match *match, void *data ) { 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 already exists ( match = [%s] )", match_string ); return false; } match_entry *new_entry = allocate_match_entry( match, 0 /* dummy priority */, data ); match_entry *conflict_entry = insert_hash_entry( exact_table, &new_entry->match, new_entry ); assert( conflict_entry == NULL ); return true; }