u32 sw_if_index)
{
adj_index_t adj_index;
- ip_adjacency_t *adj;
adj_index = adj_nbr_find(nh_proto, link_type, nh_addr, sw_if_index);
if (ADJ_INDEX_INVALID == adj_index)
{
+ ip_adjacency_t *adj;
vnet_main_t *vnm;
vnm = vnet_get_main();
adj_lock(adj_index);
}
+ adj_delegate_adj_created(adj_get(adj_index));
return (adj_index);
}
ADJ_NBR_REWRITE_FLAG_COMPLETE,
rewrite);
+ adj_delegate_adj_created(adj_get(adj_index));
+
return (adj_index);
}
* adj_nbr_update_rewrite
*
* Update the adjacency's rewrite string. A NULL string implies the
- * rewrite is reset (i.e. when ARP/ND etnry is gone).
+ * rewrite is reset (i.e. when ARP/ND entry is gone).
* NB: the adj being updated may be handling traffic in the DP.
*/
void
* adj_nbr_update_rewrite_internal
*
* Update the adjacency's rewrite string. A NULL string implies the
- * rewrite is reset (i.e. when ARP/ND etnry is gone).
+ * rewrite is reset (i.e. when ARP/ND entry is gone).
* NB: the adj being updated may be handling traffic in the DP.
*/
void
u8 *rewrite)
{
ip_adjacency_t *walk_adj;
- adj_index_t walk_ai;
+ adj_index_t walk_ai, ai;
vlib_main_t * vm;
u32 old_next;
int do_walk;
vm = vlib_get_main();
old_next = adj->lookup_next_index;
- walk_ai = adj_get_index(adj);
+ ai = walk_ai = adj_get_index(adj);
if (VNET_LINK_MPLS == adj->ia_link)
{
/*
* DPO, this adj will no longer be in use and its lock count will drop to 0.
* We don't want it to be deleted as part of this endeavour.
*/
- adj_lock(adj_get_index(adj));
+ adj_lock(ai);
adj_lock(walk_ai);
/*
};
fib_walk_sync(FIB_NODE_TYPE_ADJ, walk_ai, &bw_ctx);
+ /*
+ * fib_walk_sync may allocate a new adjacency and potentially cuase a
+ * realloc for adj_pool. When that happens, adj pointer is no longer
+ * valid here. We refresh the adj pointer accordingly.
+ */
+ adj = adj_get (ai);
}
/*
vlib_worker_thread_barrier_sync(vm);
adj->lookup_next_index = adj_next_index;
+ adj->ia_node_index = this_node;
if (NULL != rewrite)
{
*/
if (do_walk)
{
+ walk_adj = adj_get(walk_ai);
walk_adj->ia_flags &= ~ADJ_FLAG_SYNC_WALK_ACTIVE;
}
- adj_unlock(adj_get_index(adj));
+ adj_unlock(ai);
adj_unlock(walk_ai);
}
u64 count;
} adj_db_count_ctx_t;
-static void
+static int
adj_db_count (BVT(clib_bihash_kv) * kvp,
void *arg)
{
adj_db_count_ctx_t * ctx = arg;
ctx->count++;
+ return (BIHASH_WALK_CONTINUE);
}
u32
void *awc_ctx;
} adj_walk_ctx_t;
-static void
+static int
adj_nbr_walk_cb (BVT(clib_bihash_kv) * kvp,
void *arg)
{
adj_walk_ctx_t *ctx = arg;
// FIXME: can't stop early...
- ctx->awc_cb(kvp->value, ctx->awc_ctx);
+ if (ADJ_WALK_RC_STOP == ctx->awc_cb(kvp->value, ctx->awc_ctx))
+ return (BIHASH_WALK_STOP);
+ return (BIHASH_WALK_CONTINUE);
}
void
if (!ADJ_NBR_ITF_OK(adj_nh_proto, sw_if_index))
return;
- vnet_link_t linkt;
- adj_index_t ai;
-
- FOR_EACH_VNET_LINK(linkt)
+ switch (adj_nh_proto)
{
- ai = adj_nbr_find (FIB_PROTOCOL_IP4, linkt, nh, sw_if_index);
-
- if (INDEX_INVALID != ai)
- cb(ai, ctx);
+ case FIB_PROTOCOL_IP4:
+ adj_nbr_walk_nh4(sw_if_index, &nh->ip4, cb, ctx);
+ break;
+ case FIB_PROTOCOL_IP6:
+ adj_nbr_walk_nh6(sw_if_index, &nh->ip6, cb, ctx);
+ break;
+ case FIB_PROTOCOL_MPLS:
+ ASSERT(0);
+ break;
}
}
};
ip_adjacency_t *adj;
+ adj_lock(ai);
+
adj = adj_get(ai);
adj->ia_flags |= ADJ_FLAG_SYNC_WALK_ACTIVE;
fib_walk_sync(FIB_NODE_TYPE_ADJ, ai, &bw_ctx);
adj->ia_flags &= ~ADJ_FLAG_SYNC_WALK_ACTIVE;
+ adj_unlock(ai);
return (ADJ_WALK_RC_CONTINUE);
}
vlib_cli_command_t * cmd)
{
adj_index_t ai = ADJ_INDEX_INVALID;
+ ip46_address_t nh = ip46_address_initializer;
u32 sw_if_index = ~0;
while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
{
- if (unformat (input, "%d", &ai))
+ if (unformat (input, "%U",
+ unformat_vnet_sw_interface, vnet_get_main(),
+ &sw_if_index))
;
else if (unformat (input, "%U",
- unformat_vnet_sw_interface, vnet_get_main(),
- &sw_if_index))
+ unformat_ip46_address, &nh, IP46_TYPE_ANY))
+ ;
+ else if (unformat (input, "%d", &ai))
;
else
break;
{
fib_protocol_t proto;
- for (proto = FIB_PROTOCOL_IP4; proto <= FIB_PROTOCOL_IP6; proto++)
- {
- adj_nbr_walk(sw_if_index, proto,
- adj_nbr_show_one,
- vm);
- }
+ if (ip46_address_is_zero(&nh))
+ {
+ for (proto = FIB_PROTOCOL_IP4; proto <= FIB_PROTOCOL_IP6; proto++)
+ {
+ adj_nbr_walk(sw_if_index, proto,
+ adj_nbr_show_one,
+ vm);
+ }
+ }
+ else
+ {
+ proto = (ip46_address_is_ip4(&nh) ?
+ FIB_PROTOCOL_IP4 :
+ FIB_PROTOCOL_IP6);
+ adj_nbr_walk_nh(sw_if_index, proto, &nh,
+ adj_nbr_show_one,
+ vm);
+ }
}
else
{