#include <vnet/ethernet/arp_packet.h>
#include <vnet/fib/fib_walk.h>
+#include <vppinfra/bihash_24_8.h>
+
/*
* Vector Hash tables of neighbour (traditional) adjacencies
* Key: interface(for the vector index), address (and its proto),
adj_nbr_tables[nh_proto][sw_if_index] =
clib_mem_alloc_aligned(sizeof(BVT(clib_bihash)),
CLIB_CACHE_LINE_BYTES);
- memset(adj_nbr_tables[nh_proto][sw_if_index],
+ clib_memset(adj_nbr_tables[nh_proto][sw_if_index],
0,
sizeof(BVT(clib_bihash)));
BV(clib_bihash_add_del) (adj_nbr_tables[nh_proto][sw_if_index], &kv, 0);
}
-static adj_index_t
+adj_index_t
adj_nbr_find (fib_protocol_t nh_proto,
vnet_link_t link_type,
const ip46_address_t *nh_addr,
adj->ia_link = link_type;
adj->ia_nh_proto = nh_proto;
adj->rewrite_header.sw_if_index = sw_if_index;
+ vnet_rewrite_update_mtu(vnet_get_main(), adj->ia_link,
+ &adj->rewrite_header);
adj_nbr_evaluate_feature (adj_get_index(adj));
return (adj);
adj_index = adj_get_index(adj);
adj_lock(adj_index);
- vnet_rewrite_init(vnm, sw_if_index,
+ if (ip46_address_is_equal(&ADJ_BCAST_ADDR, nh_addr))
+ {
+ adj->lookup_next_index = IP_LOOKUP_NEXT_BCAST;
+ }
+
+ vnet_rewrite_init(vnm, sw_if_index, link_type,
adj_get_nd_node(nh_proto),
vnet_tx_node_index_for_sw_interface(vnm, sw_if_index),
&adj->rewrite_header);
u8 *rewrite)
{
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)
{
- adj = adj_nbr_alloc(nh_proto, link_type, nh_addr, sw_if_index);
+ ip_adjacency_t *adj;
+
+ adj = adj_nbr_alloc(nh_proto, link_type, nh_addr, sw_if_index);
adj->rewrite_header.sw_if_index = sw_if_index;
- }
- else
- {
- adj = adj_get(adj_index);
+ adj_index = adj_get_index(adj);
}
- adj_lock(adj_get_index(adj));
- adj_nbr_update_rewrite(adj_get_index(adj),
+ adj_lock(adj_index);
+ adj_nbr_update_rewrite(adj_index,
ADJ_NBR_REWRITE_FLAG_COMPLETE,
rewrite);
- return (adj_get_index(adj));
+ return (adj_index);
}
/**
* since this is the walk that provides convergence
*/
adj_nbr_interface_state_change_ctx_t *ctx = arg;
-
fib_node_back_walk_ctx_t bw_ctx = {
.fnbw_reason = ((ctx->flags & ADJ_NBR_INTERFACE_UP) ?
FIB_NODE_BW_REASON_FLAG_INTERFACE_UP :
*/
.fnbw_flags = (!(ctx->flags & ADJ_NBR_INTERFACE_UP) ?
FIB_NODE_BW_FLAG_FORCE_SYNC :
- 0),
+ FIB_NODE_BW_FLAG_NONE),
};
+ ip_adjacency_t *adj;
+
+ 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;
return (ADJ_WALK_RC_CONTINUE);
}
* @brief Invoked on each SW interface of a HW interface when the
* HW interface state changes
*/
-static void
+static walk_rc_t
adj_nbr_hw_sw_interface_state_change (vnet_main_t * vnm,
u32 sw_if_index,
void *arg)
adj_nbr_interface_state_change_one,
ctx);
}
+ return (WALK_CONTINUE);
}
/**
fib_node_back_walk_ctx_t bw_ctx = {
.fnbw_reason = FIB_NODE_BW_REASON_FLAG_INTERFACE_DELETE,
};
+ ip_adjacency_t *adj;
+
+ 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;
return (ADJ_WALK_RC_CONTINUE);
}