X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fadj%2Fadj_nbr.c;h=75313267ea18ab660300d172fb651117316c0b20;hb=14053c9db;hp=ff535295b4b8e7461c7ae7fde240219dcb984d42;hpb=b7b929931a07fbb27b43d5cd105f366c3e29807e;p=vpp.git diff --git a/src/vnet/adj/adj_nbr.c b/src/vnet/adj/adj_nbr.c index ff535295b4b..75313267ea1 100644 --- a/src/vnet/adj/adj_nbr.c +++ b/src/vnet/adj/adj_nbr.c @@ -18,6 +18,8 @@ #include #include +#include + /* * Vector Hash tables of neighbour (traditional) adjacencies * Key: interface(for the vector index), address (and its proto), @@ -195,6 +197,8 @@ adj_nbr_alloc (fib_protocol_t nh_proto, 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); @@ -217,12 +221,12 @@ adj_nbr_add_or_lock (fib_protocol_t nh_proto, 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(); @@ -252,6 +256,7 @@ adj_nbr_add_or_lock (fib_protocol_t nh_proto, adj_lock(adj_index); } + adj_delegate_adj_created(adj_get(adj_index)); return (adj_index); } @@ -263,33 +268,33 @@ adj_nbr_add_or_lock_w_rewrite (fib_protocol_t nh_proto, 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)); + 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 - * rewirte 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 @@ -331,7 +336,7 @@ adj_nbr_update_rewrite (adj_index_t adj_index, * adj_nbr_update_rewrite_internal * * Update the adjacency's rewrite string. A NULL string implies the - * rewirte 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 @@ -342,7 +347,7 @@ adj_nbr_update_rewrite_internal (ip_adjacency_t *adj, 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; @@ -350,12 +355,12 @@ adj_nbr_update_rewrite_internal (ip_adjacency_t *adj, 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) { /* * The link type MPLS has no children in the control plane graph, it only - * has children in the data-palne graph. The backwalk is up the former. + * has children in the data-plane graph. The backwalk is up the former. * So we need to walk from its IP cousin. */ walk_ai = adj_nbr_find(adj->ia_nh_proto, @@ -392,9 +397,9 @@ adj_nbr_update_rewrite_internal (ip_adjacency_t *adj, * lock the adjacencies that are affected by updates this walk will provoke. * Since the aim of the walk is to update children to link to a different * 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 endevour. + * 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); /* @@ -405,7 +410,7 @@ adj_nbr_update_rewrite_internal (ip_adjacency_t *adj, * ideally we would only want to suspend forwarding via this adj whilst we * do this, but we do not have that level of granularity - it's suspend all * worker threads or nothing. - * The other chioces are: + * The other choices are: * - to mark the adj down and back walk so child load-balances drop this adj * from the set. * - update the next_node index of this adj to point to error-drop @@ -416,7 +421,7 @@ adj_nbr_update_rewrite_internal (ip_adjacency_t *adj, * node. So from the options above, updating the next_node of the adj to * be drop will work, but it relies on each graph node v4/v6/mpls, rewrite/ * arp/midchain always be valid w.r.t. a mis-match of adj type and node type - * (i.e. a rewrite adj in the arp node). This is not enforcable. Getting it + * (i.e. a rewrite adj in the arp node). This is not enforceable. Getting it * wrong will lead to hard to find bugs since its a race condition. So we * choose the more reliable method of updating the children to use the drop, * then switching adj's type, then updating the children again. Did I mention @@ -438,7 +443,7 @@ adj_nbr_update_rewrite_internal (ip_adjacency_t *adj, fib_node_back_walk_ctx_t bw_ctx = { .fnbw_reason = FIB_NODE_BW_REASON_FLAG_ADJ_DOWN, /* - * force this walk to be synchrous. if we don't and a node in the graph + * force this walk to be synchronous. if we don't and a node in the graph * (a heavily shared path-list) chooses to back-ground the walk (make it * async) then it will pause and we will do the adj update below, before * all the children are updated. not good. @@ -459,6 +464,7 @@ adj_nbr_update_rewrite_internal (ip_adjacency_t *adj, vlib_worker_thread_barrier_sync(vm); adj->lookup_next_index = adj_next_index; + adj->ia_node_index = this_node; if (NULL != rewrite) { @@ -482,7 +488,7 @@ adj_nbr_update_rewrite_internal (ip_adjacency_t *adj, next_node); /* - * done with the rewirte update - let the workers loose. + * done with the rewrite update - let the workers loose. */ vlib_worker_thread_barrier_release(vm); @@ -505,10 +511,11 @@ adj_nbr_update_rewrite_internal (ip_adjacency_t *adj, */ 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); } @@ -516,12 +523,13 @@ typedef struct adj_db_count_ctx_t_ { 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 @@ -558,14 +566,16 @@ typedef struct adj_walk_ctx_t_ 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 @@ -658,15 +668,17 @@ adj_nbr_walk_nh (u32 sw_if_index, 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; } } @@ -821,12 +833,15 @@ adj_nbr_interface_delete_one (adj_index_t ai, }; 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); } @@ -892,15 +907,19 @@ adj_nbr_show (vlib_main_t * vm, 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; @@ -917,12 +936,24 @@ adj_nbr_show (vlib_main_t * vm, { 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 {