- vnet_rewrite_for_sw_interface(vnet_get_main(),
- adj_fib_proto_2_nd(proto),
- sw_if_index,
- adj_get_glean_node(proto)->index,
- VNET_REWRITE_FOR_SW_INTERFACE_ADDRESS_BROADCAST,
- &adj->rewrite_header,
- sizeof (adj->rewrite_data));
+ adj_delegate_adj_created(adj);
+
+ return (ai);
+}
+
+/**
+ * adj_glean_update_rewrite
+ */
+void
+adj_glean_update_rewrite (adj_index_t adj_index)
+{
+ ip_adjacency_t *adj;
+
+ ASSERT(ADJ_INDEX_INVALID != adj_index);
+
+ adj = adj_get(adj_index);
+
+ vnet_rewrite_for_sw_interface(vnet_get_main(),
+ adj_fib_proto_2_nd(adj->ia_nh_proto),
+ adj->rewrite_header.sw_if_index,
+ adj->ia_node_index,
+ VNET_REWRITE_FOR_SW_INTERFACE_ADDRESS_BROADCAST,
+ &adj->rewrite_header,
+ sizeof (adj->rewrite_data));
+}
+
+static adj_walk_rc_t
+adj_glean_update_rewrite_walk (adj_index_t ai,
+ void *data)
+{
+ adj_glean_update_rewrite(ai);
+
+ return (ADJ_WALK_RC_CONTINUE);
+}
+
+void
+adj_glean_walk (u32 sw_if_index,
+ adj_walk_cb_t cb,
+ void *data)
+{
+ fib_protocol_t proto;
+
+ FOR_EACH_FIB_IP_PROTOCOL(proto)
+ {
+ adj_index_t ai, *aip, *ais = NULL;
+ ip46_address_t *conn;
+
+ if (vec_len(adj_gleans[proto]) <= sw_if_index ||
+ NULL == adj_gleans[proto][sw_if_index])
+ continue;
+
+ /*
+ * Walk first to collect the indices
+ * then walk the collection. This is safe
+ * to modifications of the hash table
+ */
+ hash_foreach_mem(conn, ai, adj_gleans[proto][sw_if_index],
+ ({
+ vec_add1(ais, ai);
+ }));
+
+ vec_foreach(aip, ais)
+ {
+ if (ADJ_WALK_RC_STOP == cb(*aip, data))
+ break;
+ }
+ vec_free(ais);
+ }
+}
+
+adj_index_t
+adj_glean_get (fib_protocol_t proto,
+ u32 sw_if_index,
+ const ip46_address_t *nh)
+{
+ if (NULL != nh)
+ {
+ return adj_glean_db_lookup(proto, sw_if_index, nh);