+ int done = 0;
+ int i;
+
+ while (!done)
+ {
+ vec_foreach_index (i, e->adjacencies)
+ if (vec_elt (e->adjacencies, i) == adj_index)
+ {
+ vec_del1 (e->adjacencies, i);
+ continue;
+ }
+ done = 1;
+ }
+}
+
+static void
+arp_ip4_entry_add_adj (ethernet_arp_ip4_entry_t * e, u32 adj_index)
+{
+ int i;
+ vec_foreach_index (i, e->adjacencies)
+ if (vec_elt (e->adjacencies, i) == adj_index)
+ return;
+ vec_add1 (e->adjacencies, adj_index);
+}
+
+static void
+arp_add_del_adj_cb (struct ip_lookup_main_t *lm,
+ u32 adj_index, ip_adjacency_t * adj, u32 is_del)
+{
+ ethernet_arp_main_t *am = ðernet_arp_main;
+ ip4_main_t *im = &ip4_main;
+ ethernet_arp_ip4_key_t k;
+ ethernet_arp_ip4_entry_t *e = 0;
+ uword *p;
+ u32 ai;
+
+ for (ai = adj->heap_handle; ai < adj->heap_handle + adj->n_adj; ai++)
+ {
+ adj = ip_get_adjacency (lm, ai);
+ if (adj->lookup_next_index == IP_LOOKUP_NEXT_ARP
+ && adj->arp.next_hop.ip4.as_u32)
+ {
+ k.sw_if_index = adj->rewrite_header.sw_if_index;
+ k.ip4_address.as_u32 = adj->arp.next_hop.ip4.as_u32;
+ k.fib_index =
+ im->fib_index_by_sw_if_index[adj->rewrite_header.sw_if_index];
+ p = mhash_get (&am->ip4_entry_by_key, &k);
+ if (p)
+ e = pool_elt_at_index (am->ip4_entry_pool, p[0]);
+ }
+ else
+ continue;
+
+ if (is_del)
+ {
+ if (!e)
+ clib_warning ("Adjacency contains unknown ARP next hop %U (del)",
+ format_ip46_address, &adj->arp.next_hop,
+ IP46_TYPE_IP4);
+ else
+ arp_ip4_entry_del_adj (e, adj->heap_handle);
+ }
+ else /* add */
+ {
+ if (!e)
+ clib_warning ("Adjacency contains unknown ARP next hop %U (add)",
+ format_ip46_address, &adj->arp.next_hop,
+ IP46_TYPE_IP4);
+ else
+ arp_ip4_entry_add_adj (e, adj->heap_handle);
+ }
+ }
+}
+
+static clib_error_t *
+ethernet_arp_init (vlib_main_t * vm)
+{
+ ethernet_arp_main_t *am = ðernet_arp_main;
+ pg_node_t *pn;
+ clib_error_t *error;
+ ip4_main_t *im = &ip4_main;
+ ip_lookup_main_t *lm = &im->lookup_main;
+
+ if ((error = vlib_call_init_function (vm, ethernet_init)))
+ return error;