/* This search function returns a node pointer, and can be used in * conjunction with avtab_search_next_node() */ struct avtab_node* avtab_search_node(struct avtab *h, struct avtab_key *key) { int hvalue; struct avtab_node *cur; u16 specified = key->specified & ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD); if ( !h ) return NULL; hvalue = AVTAB_HASH(key); for ( cur = h->htable[hvalue]; cur; cur = cur->next ) { if ( key->source_type == cur->key.source_type && key->target_type == cur->key.target_type && key->target_class == cur->key.target_class && (specified & cur->key.specified) ) return cur; if ( key->source_type < cur->key.source_type ) break; if ( key->source_type == cur->key.source_type && key->target_type < cur->key.target_type ) break; if ( key->source_type == cur->key.source_type && key->target_type == cur->key.target_type && key->target_class < cur->key.target_class ) break; } return NULL; }
int avtab_insert(struct avtab *h, struct avtab_key *key, struct avtab_datum *datum) { int hvalue; struct avtab_node *prev, *cur, *newnode; if (!h) return -EINVAL; hvalue = AVTAB_HASH(key); for (prev = NULL, cur = h->htable[hvalue]; cur; prev = cur, cur = cur->next) { if (key->source_type == cur->key.source_type && key->target_type == cur->key.target_type && key->target_class == cur->key.target_class && (datum->specified & cur->datum.specified)) return -EEXIST; if (key->source_type < cur->key.source_type) break; if (key->source_type == cur->key.source_type && key->target_type < cur->key.target_type) break; if (key->source_type == cur->key.source_type && key->target_type == cur->key.target_type && key->target_class < cur->key.target_class) break; } newnode = avtab_insert_node(h, hvalue, prev, cur, key, datum); if(!newnode) return -ENOMEM; return 0; }
/* Unlike avtab_insert(), this function allow multiple insertions of the same * key/specified mask into the table, as needed by the conditional avtab. * It also returns a pointer to the node inserted. */ struct avtab_node * avtab_insert_nonunique(struct avtab * h, struct avtab_key * key, struct avtab_datum * datum) { int hvalue; struct avtab_node *prev, *cur, *newnode; u16 specified = key->specified & ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD); if ( !h ) return NULL; hvalue = AVTAB_HASH(key); for ( prev = NULL, cur = h->htable[hvalue]; cur; prev = cur, cur = cur->next ) { if ( key->source_type == cur->key.source_type && key->target_type == cur->key.target_type && key->target_class == cur->key.target_class && (specified & cur->key.specified) ) break; if ( key->source_type < cur->key.source_type ) break; if ( key->source_type == cur->key.source_type && key->target_type < cur->key.target_type ) break; if ( key->source_type == cur->key.source_type && key->target_type == cur->key.target_type && key->target_class < cur->key.target_class ) break; } newnode = avtab_insert_node(h, hvalue, prev, cur, key, datum); return newnode; }
struct avtab_datum *avtab_search(struct avtab *h, struct avtab_key *key, int specified) { int hvalue; struct avtab_node *cur; if (!h) return NULL; hvalue = AVTAB_HASH(key); for (cur = h->htable[hvalue]; cur; cur = cur->next) { if (key->source_type == cur->key.source_type && key->target_type == cur->key.target_type && key->target_class == cur->key.target_class && (specified & cur->datum.specified)) return &cur->datum; if (key->source_type < cur->key.source_type) break; if (key->source_type == cur->key.source_type && key->target_type < cur->key.target_type) break; if (key->source_type == cur->key.source_type && key->target_type == cur->key.target_type && key->target_class < cur->key.target_class) break; } return NULL; }