X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fadj%2Fadj_nbr.c;h=811d0b8faa2f17c6093b6ef255651876c221deab;hb=8f5fef2c7;hp=fc7a7fcd93c1ab479148fb13ff567de39e3d1f81;hpb=5f3fcb96296a4769f55f60270e10c6294c604db9;p=vpp.git diff --git a/src/vnet/adj/adj_nbr.c b/src/vnet/adj/adj_nbr.c index fc7a7fcd93c..811d0b8faa2 100644 --- a/src/vnet/adj/adj_nbr.c +++ b/src/vnet/adj/adj_nbr.c @@ -23,23 +23,36 @@ * Key: interface(for the vector index), address (and its proto), * link-type/ether-type. */ -static BVT(clib_bihash) **adj_nbr_tables[FIB_PROTOCOL_MAX]; - -// FIXME SIZE APPROPRIATELY. ASK DAVEB. -#define ADJ_NBR_DEFAULT_HASH_NUM_BUCKETS (64 * 64) -#define ADJ_NBR_DEFAULT_HASH_MEMORY_SIZE (32<<20) +static uword **adj_nbr_tables[FIB_PROTOCOL_IP_MAX]; +typedef struct adj_nbr_key_t_ +{ + ip46_address_t ank_ip; + u64 ank_linkt; +} adj_nbr_key_t; #define ADJ_NBR_SET_KEY(_key, _lt, _nh) \ { \ - _key.key[0] = (_nh)->as_u64[0]; \ - _key.key[1] = (_nh)->as_u64[1]; \ - _key.key[2] = (_lt); \ + ip46_address_copy(&(_key).ank_ip, (_nh)); \ + _key.ank_linkt = (_lt); \ } #define ADJ_NBR_ITF_OK(_proto, _itf) \ (((_itf) < vec_len(adj_nbr_tables[_proto])) && \ - (NULL != adj_nbr_tables[_proto][sw_if_index])) + (NULL != adj_nbr_tables[_proto][(_itf)])) + +#define ADJ_NBR_ASSERT_NH_PROTO(nh_proto, err) \ + do { \ + ASSERT (nh_proto < FIB_PROTOCOL_IP_MAX); \ + const fib_protocol_t nh_proto__ = (nh_proto); \ + if (nh_proto__ >= FIB_PROTOCOL_IP_MAX) \ + { \ + clib_warning ("BUG: protocol %d > %d\n", \ + (int)nh_proto__, \ + FIB_PROTOCOL_IP_MAX); \ + return err; \ + } \ + } while (0) static void adj_nbr_insert (fib_protocol_t nh_proto, @@ -48,7 +61,9 @@ adj_nbr_insert (fib_protocol_t nh_proto, u32 sw_if_index, adj_index_t adj_index) { - BVT(clib_bihash_kv) kv; + adj_nbr_key_t kv; + + ADJ_NBR_ASSERT_NH_PROTO (nh_proto,); if (sw_if_index >= vec_len(adj_nbr_tables[nh_proto])) { @@ -57,22 +72,13 @@ adj_nbr_insert (fib_protocol_t nh_proto, if (NULL == adj_nbr_tables[nh_proto][sw_if_index]) { 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], - 0, - sizeof(BVT(clib_bihash))); - - BV(clib_bihash_init) (adj_nbr_tables[nh_proto][sw_if_index], - "Adjacency Neighbour table", - ADJ_NBR_DEFAULT_HASH_NUM_BUCKETS, - ADJ_NBR_DEFAULT_HASH_MEMORY_SIZE); + hash_create_mem(0, sizeof(adj_nbr_key_t), sizeof(adj_index_t)); } ADJ_NBR_SET_KEY(kv, link_type, nh_addr); - kv.value = adj_index; - BV(clib_bihash_add_del) (adj_nbr_tables[nh_proto][sw_if_index], &kv, 1); + hash_set_mem_alloc (&adj_nbr_tables[nh_proto][sw_if_index], + &kv, adj_index); } void @@ -82,39 +88,46 @@ adj_nbr_remove (adj_index_t ai, const ip46_address_t *nh_addr, u32 sw_if_index) { - BVT(clib_bihash_kv) kv; + adj_nbr_key_t kv; + + ADJ_NBR_ASSERT_NH_PROTO (nh_proto,); if (!ADJ_NBR_ITF_OK(nh_proto, sw_if_index)) return; ADJ_NBR_SET_KEY(kv, link_type, nh_addr); - kv.value = ai; - BV(clib_bihash_add_del) (adj_nbr_tables[nh_proto][sw_if_index], &kv, 0); + hash_unset_mem_free(&adj_nbr_tables[nh_proto][sw_if_index], &kv); + + if (0 == hash_elts(adj_nbr_tables[nh_proto][sw_if_index])) + { + hash_free(adj_nbr_tables[nh_proto][sw_if_index]); + } } -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, u32 sw_if_index) { - BVT(clib_bihash_kv) kv; + adj_nbr_key_t kv; + uword *p; + + ADJ_NBR_ASSERT_NH_PROTO (nh_proto, ADJ_INDEX_INVALID); ADJ_NBR_SET_KEY(kv, link_type, nh_addr); if (!ADJ_NBR_ITF_OK(nh_proto, sw_if_index)) return (ADJ_INDEX_INVALID); - if (BV(clib_bihash_search)(adj_nbr_tables[nh_proto][sw_if_index], - &kv, &kv) < 0) - { - return (ADJ_INDEX_INVALID); - } - else + p = hash_get_mem(adj_nbr_tables[nh_proto][sw_if_index], &kv); + + if (p) { - return (kv.value); + return (p[0]); } + return (ADJ_INDEX_INVALID); } static inline u32 @@ -166,9 +179,16 @@ adj_nbr_evaluate_feature (adj_index_t ai) { feature_count = fm->feature_count_by_sw_if_index[arc_index][sw_if_index]; if (feature_count > 0) + { + vnet_feature_config_main_t *cm; + adj->rewrite_header.flags |= VNET_REWRITE_HAS_FEATURES; - } + cm = &fm->feature_config_mains[arc_index]; + adj->ia_cfg_index = vec_elt (cm->config_index_by_sw_if_index, + sw_if_index); + } + } return; } @@ -195,11 +215,34 @@ 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); } +void +adj_nbr_set_mtu (adj_index_t adj_index, u16 mtu) +{ + ip_adjacency_t *adj; + + ASSERT(ADJ_INDEX_INVALID != adj_index); + + adj = adj_get(adj_index); + + if (0 == mtu) + vnet_rewrite_update_mtu(vnet_get_main(), adj->ia_link, + &adj->rewrite_header); + else + { + vnet_rewrite_update_mtu(vnet_get_main(), adj->ia_link, + &adj->rewrite_header); + adj->rewrite_header.max_l3_packet_bytes = + clib_min (adj->rewrite_header.max_l3_packet_bytes, mtu); + } +} + /* * adj_nbr_add_or_lock * @@ -217,12 +260,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(); @@ -230,7 +273,12 @@ adj_nbr_add_or_lock (fib_protocol_t nh_proto, 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); @@ -241,6 +289,7 @@ adj_nbr_add_or_lock (fib_protocol_t nh_proto, * So ask the interface to do it. */ vnet_update_adjacency_for_sw_interface(vnm, sw_if_index, adj_index); + adj_delegate_adj_created(adj_get(adj_index)); } else { @@ -258,33 +307,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 @@ -326,7 +375,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 @@ -337,7 +386,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; @@ -345,12 +394,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, @@ -387,9 +436,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); /* @@ -400,7 +449,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 @@ -411,7 +460,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 @@ -433,7 +482,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. @@ -442,6 +491,12 @@ adj_nbr_update_rewrite_internal (ip_adjacency_t *adj, }; 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); } /* @@ -454,6 +509,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) { @@ -477,7 +533,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); @@ -500,33 +556,21 @@ 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_delegate_adj_modified(adj); + adj_unlock(ai); adj_unlock(walk_ai); } -typedef struct adj_db_count_ctx_t_ { - u64 count; -} adj_db_count_ctx_t; - -static void -adj_db_count (BVT(clib_bihash_kv) * kvp, - void *arg) -{ - adj_db_count_ctx_t * ctx = arg; - ctx->count++; -} - u32 adj_nbr_db_size (void) { - adj_db_count_ctx_t ctx = { - .count = 0, - }; fib_protocol_t proto; u32 sw_if_index = 0; + u64 count = 0; for (proto = FIB_PROTOCOL_IP4; proto <= FIB_PROTOCOL_IP6; proto++) { @@ -534,76 +578,46 @@ adj_nbr_db_size (void) { if (NULL != adj_nbr_tables[proto][sw_if_index]) { - BV(clib_bihash_foreach_key_value_pair) ( - adj_nbr_tables[proto][sw_if_index], - adj_db_count, - &ctx); + count += hash_elts(adj_nbr_tables[proto][sw_if_index]); } } } - return (ctx.count); + return (count); } /** - * @brief Context for a walk of the adjacency neighbour DB + * @brief Walk all adjacencies on a link for a given next-hop protocol */ -typedef struct adj_walk_ctx_t_ -{ - adj_walk_cb_t awc_cb; - void *awc_ctx; -} adj_walk_ctx_t; - -static void -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); -} - void adj_nbr_walk (u32 sw_if_index, fib_protocol_t adj_nh_proto, adj_walk_cb_t cb, void *ctx) { - if (!ADJ_NBR_ITF_OK(adj_nh_proto, sw_if_index)) - return; - - adj_walk_ctx_t awc = { - .awc_ctx = ctx, - .awc_cb = cb, - }; + adj_index_t ai, *ais, *aip; + adj_nbr_key_t *key; - BV(clib_bihash_foreach_key_value_pair) ( - adj_nbr_tables[adj_nh_proto][sw_if_index], - adj_nbr_walk_cb, - &awc); -} + ADJ_NBR_ASSERT_NH_PROTO (adj_nh_proto,); -/** - * @brief Context for a walk of the adjacency neighbour DB - */ -typedef struct adj_walk_nh_ctx_t_ -{ - adj_walk_cb_t awc_cb; - void *awc_ctx; - const ip46_address_t *awc_nh; -} adj_walk_nh_ctx_t; + if (!ADJ_NBR_ITF_OK(adj_nh_proto, sw_if_index)) + return; -static void -adj_nbr_walk_nh_cb (BVT(clib_bihash_kv) * kvp, - void *arg) -{ - ip_adjacency_t *adj; - adj_walk_nh_ctx_t *ctx = arg; + ais = NULL; - adj = adj_get(kvp->value); + /* elements may be removed from the table during the walk, so + * collect the set first then process them */ + hash_foreach_mem (key, ai, adj_nbr_tables[adj_nh_proto][sw_if_index], + ({ + vec_add1(ais, ai); + })); - if (!ip46_address_cmp(&adj->sub_type.nbr.next_hop, ctx->awc_nh)) - ctx->awc_cb(kvp->value, ctx->awc_ctx); + vec_foreach(aip, ais) + { + /* An adj may be deleted during the walk so check first */ + if (!pool_is_free_index(adj_pool, *aip)) + cb(*aip, ctx); + } + vec_free(ais); } /** @@ -622,17 +636,16 @@ adj_nbr_walk_nh4 (u32 sw_if_index, ip46_address_t nh = { .ip4 = *addr, }; + vnet_link_t linkt; + adj_index_t ai; - adj_walk_nh_ctx_t awc = { - .awc_ctx = ctx, - .awc_cb = cb, - .awc_nh = &nh, - }; + FOR_EACH_VNET_LINK(linkt) + { + ai = adj_nbr_find (FIB_PROTOCOL_IP4, linkt, &nh, sw_if_index); - BV(clib_bihash_foreach_key_value_pair) ( - adj_nbr_tables[FIB_PROTOCOL_IP4][sw_if_index], - adj_nbr_walk_nh_cb, - &awc); + if (INDEX_INVALID != ai) + cb(ai, ctx); + } } /** @@ -651,17 +664,16 @@ adj_nbr_walk_nh6 (u32 sw_if_index, ip46_address_t nh = { .ip6 = *addr, }; + vnet_link_t linkt; + adj_index_t ai; - adj_walk_nh_ctx_t awc = { - .awc_ctx = ctx, - .awc_cb = cb, - .awc_nh = &nh, - }; + FOR_EACH_VNET_LINK(linkt) + { + ai = adj_nbr_find (FIB_PROTOCOL_IP6, linkt, &nh, sw_if_index); - BV(clib_bihash_foreach_key_value_pair) ( - adj_nbr_tables[FIB_PROTOCOL_IP6][sw_if_index], - adj_nbr_walk_nh_cb, - &awc); + if (INDEX_INVALID != ai) + cb(ai, ctx); + } } /** @@ -675,19 +687,23 @@ adj_nbr_walk_nh (u32 sw_if_index, adj_walk_cb_t cb, void *ctx) { + ADJ_NBR_ASSERT_NH_PROTO (adj_nh_proto,); + if (!ADJ_NBR_ITF_OK(adj_nh_proto, sw_if_index)) return; - adj_walk_nh_ctx_t awc = { - .awc_ctx = ctx, - .awc_cb = cb, - .awc_nh = nh, - }; - - BV(clib_bihash_foreach_key_value_pair) ( - adj_nbr_tables[adj_nh_proto][sw_if_index], - adj_nbr_walk_nh_cb, - &awc); + switch (adj_nh_proto) + { + 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; + } } /** @@ -719,7 +735,6 @@ adj_nbr_interface_state_change_one (adj_index_t ai, * 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 : @@ -731,10 +746,15 @@ adj_nbr_interface_state_change_one (adj_index_t ai, */ .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); } @@ -776,7 +796,7 @@ VNET_SW_INTERFACE_ADMIN_UP_DOWN_FUNCTION_PRIO( * @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) @@ -793,6 +813,7 @@ adj_nbr_hw_sw_interface_state_change (vnet_main_t * vnm, adj_nbr_interface_state_change_one, ctx); } + return (WALK_CONTINUE); } /** @@ -834,9 +855,17 @@ adj_nbr_interface_delete_one (adj_index_t ai, fib_node_back_walk_ctx_t bw_ctx = { .fnbw_reason = FIB_NODE_BW_REASON_FLAG_INTERFACE_DELETE, }; + 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); } @@ -902,15 +931,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; @@ -927,12 +960,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 { @@ -968,21 +1013,6 @@ VLIB_CLI_COMMAND (ip4_show_fib_command, static) = { .function = adj_nbr_show, }; -static ip46_type_t -adj_proto_to_46 (fib_protocol_t proto) -{ - switch (proto) - { - case FIB_PROTOCOL_IP4: - return (IP46_TYPE_IP4); - case FIB_PROTOCOL_IP6: - return (IP46_TYPE_IP6); - default: - return (IP46_TYPE_IP4); - } - return (IP46_TYPE_IP4); -} - u8* format_adj_nbr_incomplete (u8* s, va_list *ap) { @@ -996,10 +1026,8 @@ format_adj_nbr_incomplete (u8* s, va_list *ap) format_ip46_address, &adj->sub_type.nbr.next_hop, adj_proto_to_46(adj->ia_nh_proto)); s = format (s, " %U", - format_vnet_sw_interface_name, - vnm, - vnet_get_sw_interface(vnm, - adj->rewrite_header.sw_if_index)); + format_vnet_sw_if_index_name, + vnm, adj->rewrite_header.sw_if_index); return (s); } @@ -1048,12 +1076,14 @@ const static dpo_vft_t adj_nbr_dpo_vft = { .dv_format = format_adj_nbr, .dv_mem_show = adj_mem_show, .dv_get_urpf = adj_dpo_get_urpf, + .dv_get_mtu = adj_dpo_get_mtu, }; const static dpo_vft_t adj_nbr_incompl_dpo_vft = { .dv_lock = adj_dpo_lock, .dv_unlock = adj_dpo_unlock, .dv_format = format_adj_nbr_incomplete, .dv_get_urpf = adj_dpo_get_urpf, + .dv_get_mtu = adj_dpo_get_mtu, }; /**