+ /* Special-case local, drop adjs */
+ switch (adj->lookup_next_index)
+ {
+ case IP_LOOKUP_NEXT_LOCAL:
+ case IP_LOOKUP_NEXT_DROP:
+ return;
+ default:
+ break;
+ }
+
+
+ if (adj->n_adj == 1)
+ {
+ uword signature;
+ uword * p;
+ u32 this_ai;
+ ip_adjacency_t * this_adj, * prev_adj = 0;
+ if (adj->share_count > 0)
+ {
+ adj->share_count --;
+ return;
+ }
+
+ signature = vnet_ip_adjacency_signature (adj);
+ p = hash_get (lm->adj_index_by_signature, signature);
+ if (p == 0)
+ {
+ clib_warning ("adj 0x%llx signature %llx not in table",
+ adj, signature);
+ goto bag_it;
+ }
+ this_ai = p[0];
+ /* At the top of the signature chain (likely)? */
+ if (this_ai == adj_index)
+ {
+ if (adj->next_adj_with_signature == 0)
+ {
+ hash_unset (lm->adj_index_by_signature, signature);
+ goto bag_it;
+ }
+ else
+ {
+ this_adj = ip_get_adjacency (lm, adj->next_adj_with_signature);
+ hash_unset (lm->adj_index_by_signature, signature);
+ hash_set (lm->adj_index_by_signature, signature,
+ this_adj->heap_handle);
+ }
+ }
+ else /* walk signature chain */
+ {
+ this_adj = ip_get_adjacency (lm, this_ai);
+ while (this_adj != adj)
+ {
+ prev_adj = this_adj;
+ this_adj = ip_get_adjacency
+ (lm, this_adj->next_adj_with_signature);
+ ASSERT(this_adj->heap_handle != 0);
+ }
+ prev_adj->next_adj_with_signature = this_adj->next_adj_with_signature;
+ }
+ }
+
+ bag_it: