X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fadj%2Fadj.c;h=201561fe485eb9335f9f75ab71a3545023a2b7ec;hb=2f4586d9b3507243918c11ce99b9d151d5bde7a0;hp=b844073ecfb605eefc29eaa4dcc42996869d169e;hpb=521a8d7df423a0b5aaf259d49ca9230705bc25ee;p=vpp.git diff --git a/src/vnet/adj/adj.c b/src/vnet/adj/adj.c index b844073ecfb..201561fe485 100644 --- a/src/vnet/adj/adj.c +++ b/src/vnet/adj/adj.c @@ -20,6 +20,7 @@ #include #include #include +#include /* Adjacency packet/byte counters indexed by adjacency index. */ vlib_combined_counter_main_t adjacency_counters = { @@ -32,6 +33,11 @@ vlib_combined_counter_main_t adjacency_counters = { */ ip_adjacency_t *adj_pool; +/** + * The adjacency logger + */ +vlib_log_class_t adj_logger; + /** * @brief Global Config for enabling per-adjacency counters. * By default these are disabled. @@ -63,15 +69,33 @@ ip_adjacency_t * adj_alloc (fib_protocol_t proto) { ip_adjacency_t *adj; + u8 need_barrier_sync = pool_get_will_expand (adj_pool); + vlib_main_t *vm; + vm = vlib_get_main(); + + ASSERT (vm->thread_index == 0); + + /* If the adj_pool will expand, stop the parade. */ + if (need_barrier_sync) + vlib_worker_thread_barrier_sync (vm); pool_get_aligned(adj_pool, adj, CLIB_CACHE_LINE_BYTES); adj_poison(adj); - /* Make sure certain fields are always initialized. */ /* Validate adjacency counters. */ + if (need_barrier_sync == 0) + { + /* If the adj counter pool will expand, stop the parade */ + need_barrier_sync = vlib_validate_combined_counter_will_expand + (&adjacency_counters, adj_get_index (adj)); + if (need_barrier_sync) + vlib_worker_thread_barrier_sync (vm); + } vlib_validate_combined_counter(&adjacency_counters, adj_get_index(adj)); + + /* Make sure certain fields are always initialized. */ vlib_zero_combined_counter(&adjacency_counters, adj_get_index(adj)); fib_node_init(&adj->ia_node, @@ -79,6 +103,7 @@ adj_alloc (fib_protocol_t proto) adj->ia_nh_proto = proto; adj->ia_flags = 0; + adj->ia_cfg_index = 0; adj->rewrite_header.sw_if_index = ~0; adj->rewrite_header.flags = 0; adj->lookup_next_index = 0; @@ -88,6 +113,9 @@ adj_alloc (fib_protocol_t proto) clib_memset(&adj->sub_type.midchain.next_dpo, 0, sizeof(adj->sub_type.midchain.next_dpo)); + if (need_barrier_sync) + vlib_worker_thread_barrier_release (vm); + return (adj); } @@ -139,6 +167,10 @@ format_ip_adjacency (u8 * s, va_list * args) adj_index = va_arg (*args, u32); fiaf = va_arg (*args, format_ip_adjacency_flags_t); + + if (!adj_is_valid(adj_index)) + return format(s, ""); + adj = adj_get(adj_index); switch (adj->lookup_next_index) @@ -178,8 +210,8 @@ format_ip_adjacency (u8 * s, va_list * args) s = format (s, "\n flags:%U", format_adj_flags, adj->ia_flags); s = format (s, "\n counts:[%Ld:%Ld]", counts.packets, counts.bytes); s = format (s, "\n locks:%d", adj->ia_node.fn_locks); - s = format(s, "\n delegates:\n "); - adj_delegate_format(s, adj); + s = format(s, "\n delegates:"); + s = adj_delegate_format(s, adj); s = format(s, "\n children:"); if (fib_node_list_get_size(adj->ia_node.fn_children)) @@ -213,7 +245,7 @@ adj_recursive_loop_detect (adj_index_t ai, case IP_LOOKUP_NEXT_ICMP_ERROR: case IP_LOOKUP_N_NEXT: /* - * these adjcencey types are terminal graph nodes, so there's no + * these adjacency types are terminal graph nodes, so there's no * possibility of a loop down here. */ break; @@ -245,7 +277,7 @@ adj_last_lock_gone (ip_adjacency_t *adj) switch (adj->lookup_next_index) { case IP_LOOKUP_NEXT_MIDCHAIN: - dpo_reset(&adj->sub_type.midchain.next_dpo); + adj_midchain_teardown(adj); /* FALL THROUGH */ case IP_LOOKUP_NEXT_ARP: case IP_LOOKUP_NEXT_REWRITE: @@ -260,11 +292,12 @@ adj_last_lock_gone (ip_adjacency_t *adj) adj->rewrite_header.sw_if_index); break; case IP_LOOKUP_NEXT_GLEAN: - adj_glean_remove(adj->ia_nh_proto, - adj->rewrite_header.sw_if_index); + adj_glean_remove(adj); break; - case IP_LOOKUP_NEXT_MCAST: case IP_LOOKUP_NEXT_MCAST_MIDCHAIN: + adj_midchain_teardown(adj); + /* FALL THROUGH */ + case IP_LOOKUP_NEXT_MCAST: adj_mcast_remove(adj->ia_nh_proto, adj->rewrite_header.sw_if_index); break; @@ -279,12 +312,12 @@ adj_last_lock_gone (ip_adjacency_t *adj) break; } - vlib_worker_thread_barrier_release(vm); fib_node_deinit(&adj->ia_node); ASSERT(0 == vec_len(adj->ia_delegates)); vec_free(adj->ia_delegates); pool_put(adj_pool, adj); + vlib_worker_thread_barrier_release(vm); } u32 @@ -297,6 +330,16 @@ adj_dpo_get_urpf (const dpo_id_t *dpo) return (adj->rewrite_header.sw_if_index); } +u16 +adj_dpo_get_mtu (const dpo_id_t *dpo) +{ + ip_adjacency_t *adj; + + adj = adj_get(dpo->dpoi_index); + + return (adj->rewrite_header.max_l3_packet_bytes); +} + void adj_lock (adj_index_t adj_index) { @@ -310,7 +353,6 @@ adj_lock (adj_index_t adj_index) adj = adj_get(adj_index); ASSERT(adj); - ADJ_DBG(adj, "lock"); fib_node_lock(&adj->ia_node); } @@ -327,9 +369,6 @@ adj_unlock (adj_index_t adj_index) adj = adj_get(adj_index); ASSERT(adj); - ADJ_DBG(adj, "unlock"); - ASSERT(adj); - fib_node_unlock(&adj->ia_node); } @@ -365,7 +404,7 @@ adj_child_remove (adj_index_t adj_index, } /* - * Context for the walk to update the cached feture flags. + * Context for the walk to update the cached feature flags. */ typedef struct adj_feature_update_t_ { @@ -393,18 +432,27 @@ adj_feature_update_walk_cb (adj_index_t ai, ((ctx->arc == mpls_main.output_feature_arc_index) && (VNET_LINK_MPLS == adj->ia_link))) { + vnet_feature_main_t *fm = &feature_main; + vnet_feature_config_main_t *cm; + + cm = &fm->feature_config_mains[ctx->arc]; + if (ctx->enable) adj->rewrite_header.flags |= VNET_REWRITE_HAS_FEATURES; else adj->rewrite_header.flags &= ~VNET_REWRITE_HAS_FEATURES; + + adj->ia_cfg_index = vec_elt (cm->config_index_by_sw_if_index, + adj->rewrite_header.sw_if_index); } return (ADJ_WALK_RC_CONTINUE); } -void +static void adj_feature_update (u32 sw_if_index, u8 arc_index, - u8 is_enable) + u8 is_enable, + void *data) { /* * Walk all the adjacencies on the interface to update the cached @@ -427,14 +475,29 @@ adj_mtu_update_walk_cb (adj_index_t ai, vnet_rewrite_update_mtu (vnet_get_main(), adj->ia_link, &adj->rewrite_header); + adj_delegate_adj_modified(adj); + + /** + * Backwalk to all Path MTU trackers, casual like .. + */ + { + fib_node_back_walk_ctx_t bw_ctx = { + .fnbw_reason = FIB_NODE_BW_REASON_FLAG_ADJ_MTU, + }; + + fib_walk_async(FIB_NODE_TYPE_ADJ, ai, + FIB_WALK_PRIORITY_LOW, &bw_ctx); + } return (ADJ_WALK_RC_CONTINUE); } -static void +static clib_error_t * adj_mtu_update (vnet_main_t * vnm, u32 sw_if_index, u32 flags) { adj_walk (sw_if_index, adj_mtu_update_walk_cb, NULL); + + return (NULL); } VNET_SW_INTERFACE_MTU_CHANGE_FUNCTION(adj_mtu_update); @@ -535,10 +598,32 @@ static fib_node_back_walk_rc_t adj_back_walk_notify (fib_node_t *node, fib_node_back_walk_ctx_t *ctx) { - /* - * Que pasa. yo soj en el final! - */ - ASSERT(0); + ip_adjacency_t *adj; + + adj = ADJ_FROM_NODE(node); + + switch (adj->lookup_next_index) + { + case IP_LOOKUP_NEXT_MIDCHAIN: + adj_midchain_delegate_restack(adj_get_index(adj)); + break; + case IP_LOOKUP_NEXT_ARP: + case IP_LOOKUP_NEXT_REWRITE: + case IP_LOOKUP_NEXT_BCAST: + case IP_LOOKUP_NEXT_GLEAN: + case IP_LOOKUP_NEXT_MCAST: + case IP_LOOKUP_NEXT_MCAST_MIDCHAIN: + case IP_LOOKUP_NEXT_DROP: + case IP_LOOKUP_NEXT_PUNT: + case IP_LOOKUP_NEXT_LOCAL: + case IP_LOOKUP_NEXT_ICMP_ERROR: + case IP_LOOKUP_N_NEXT: + /* + * Que pasa. yo soj en el final! + */ + ASSERT(0); + break; + } return (FIB_NODE_BACK_WALK_CONTINUE); } @@ -562,6 +647,10 @@ adj_module_init (vlib_main_t * vm) adj_midchain_module_init(); adj_mcast_module_init(); + vnet_feature_register(adj_feature_update, NULL); + + adj_logger = vlib_log_register_class("adj", "adj"); + return (NULL); } @@ -580,9 +669,7 @@ adj_show (vlib_main_t * vm, { if (unformat (input, "%d", &ai)) ; - else if (unformat (input, "sum")) - summary = 1; - else if (unformat (input, "summary")) + else if (unformat (input, "summary") || unformat (input, "sum")) summary = 1; else if (unformat (input, "%U", unformat_vnet_sw_interface, vnet_get_main(), @@ -617,9 +704,8 @@ adj_show (vlib_main_t * vm, } else { - /* *INDENT-OFF* */ - pool_foreach_index(ai, adj_pool, - ({ + pool_foreach_index (ai, adj_pool) + { if (~0 != sw_if_index && sw_if_index != adj_get_sw_if_index(ai)) { @@ -631,8 +717,7 @@ adj_show (vlib_main_t * vm, format_ip_adjacency, ai, FORMAT_IP_ADJACENCY_NONE); } - })); - /* *INDENT-ON* */ + } } } return 0; @@ -691,8 +776,8 @@ adj_cli_counters_set (vlib_main_t * vm, } /*? - * Enabe/disble per-adjacency counters. This is optional because it comes with - * a non-negligible performance cost. + * Enable/disable per-adjacency counters. This is optional because it comes + * with a non-negligible performance cost. ?*/ VLIB_CLI_COMMAND (adj_cli_counters_set_command, static) = { .path = "adjacency counters",