+
+ if (n) /* name given & found */
+ {
+ if (n[0] != p[0]) /* name and key do not point to the same thing */
+ return -2;
+ }
+ }
+
+
+ if (a->is_del) /* delete the tunnel */
+ {
+ hash_pair_t *hp;
+
+ /* Delete existing tunnel */
+ t = pool_elt_at_index (sm->tunnels, p[0]);
+
+ ip6_delete_route_no_next_hop (&t->key.dst, t->dst_mask_width,
+ a->rx_table_id);
+ vec_free (t->rewrite);
+ /* Remove tunnel from any policy if associated */
+ if (t->policy_index != ~0)
+ {
+ pt=pool_elt_at_index (sm->policies, t->policy_index);
+ for (i=0; i< vec_len (pt->tunnel_indices); i++)
+ {
+ if (pt->tunnel_indices[i] == t - sm->tunnels)
+ {
+ vec_delete (pt->tunnel_indices, 1, i);
+ goto found;
+ }
+ }
+ clib_warning ("Tunnel index %d not found in policy_index %d",
+ t - sm->tunnels, pt - sm->policies);
+ found:
+ /* If this is last tunnel in the policy, clean up the policy too */
+ if (vec_len (pt->tunnel_indices) == 0)
+ {
+ hash_unset_mem (sm->policy_index_by_policy_name, pt->name);
+ vec_free (pt->name);
+ pool_put (sm->policies, pt);
+ }
+ }
+
+ /* Clean up the tunnel by name */
+ if (t->name)
+ {
+ hash_unset_mem (sm->tunnel_index_by_name, t->name);
+ vec_free (t->name);
+ }
+ pool_put (sm->tunnels, t);
+ hp = hash_get_pair (sm->tunnel_index_by_key, &key);
+ key_copy = (void *)(hp->key);
+ hash_unset_mem (sm->tunnel_index_by_key, &key);
+ vec_free (key_copy);
+ return 0;