+u32
+vnet_arp_glean_add(u32 fib_index, void * next_hop_arg)
+{
+ ethernet_arp_main_t * am = ðernet_arp_main;
+ ip4_main_t * im = &ip4_main;
+ ip_lookup_main_t * lm = &im->lookup_main;
+ ip4_address_t * next_hop = next_hop_arg;
+ ip_adjacency_t add_adj, *adj;
+ ip4_add_del_route_args_t args;
+ ethernet_arp_ip4_entry_t * e;
+ ethernet_arp_ip4_key_t k;
+ u32 adj_index;
+
+ adj_index = ip4_fib_lookup_with_table(im, fib_index, next_hop, 0);
+ adj = ip_get_adjacency(lm, adj_index);
+
+ if (!adj || adj->lookup_next_index != IP_LOOKUP_NEXT_ARP)
+ return ~0;
+
+ if (adj->arp.next_hop.ip4.as_u32 != 0)
+ return adj_index;
+
+ k.sw_if_index = adj->rewrite_header.sw_if_index;
+ k.fib_index = fib_index;
+ k.ip4_address.as_u32 = next_hop->as_u32;
+
+ if (mhash_get (&am->ip4_entry_by_key, &k))
+ return adj_index;
+
+ pool_get (am->ip4_entry_pool, e);
+ mhash_set (&am->ip4_entry_by_key, &k, e - am->ip4_entry_pool, /* old value */ 0);
+ e->key = k;
+ e->cpu_time_last_updated = clib_cpu_time_now ();
+ e->flags = ETHERNET_ARP_IP4_ENTRY_FLAG_GLEAN;
+
+ memset(&args, 0, sizeof(args));
+ clib_memcpy(&add_adj, adj, sizeof(add_adj));
+ ip46_address_set_ip4(&add_adj.arp.next_hop, next_hop); /* install neighbor /32 route */
+ args.table_index_or_table_id = fib_index;
+ args.flags = IP4_ROUTE_FLAG_FIB_INDEX | IP4_ROUTE_FLAG_ADD| IP4_ROUTE_FLAG_NEIGHBOR;
+ args.dst_address.as_u32 = next_hop->as_u32;
+ args.dst_address_length = 32;
+ args.adj_index = ~0;
+ args.add_adj = &add_adj;
+ args.n_add_adj = 1;
+ ip4_add_del_route (im, &args);
+ return ip4_fib_lookup_with_table (im, fib_index, next_hop, 0);
+}
+