diff options
-rw-r--r-- | src/vnet/adj/adj.c | 121 | ||||
-rw-r--r-- | src/vnet/adj/adj.h | 15 | ||||
-rw-r--r-- | src/vnet/ip/ip4_forward.c | 52 | ||||
-rw-r--r-- | src/vnet/ip/ip6_forward.c | 48 |
4 files changed, 175 insertions, 61 deletions
diff --git a/src/vnet/adj/adj.c b/src/vnet/adj/adj.c index 11f1680d329..4ed4999f516 100644 --- a/src/vnet/adj/adj.c +++ b/src/vnet/adj/adj.c @@ -35,6 +35,12 @@ vlib_combined_counter_main_t adjacency_counters; */ ip_adjacency_t *adj_pool; +/** + * @brief Global Config for enabling per-adjacency counters. + * By default these are disabled. + */ +int adj_per_adj_counters; + always_inline void adj_poison (ip_adjacency_t * adj) { @@ -375,11 +381,16 @@ adj_show (vlib_main_t * vm, { adj_index_t ai = ADJ_INDEX_INVALID; u32 sw_if_index = ~0; + int summary = 0; while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) { if (unformat (input, "%d", &ai)) ; + else if (unformat (input, "sum")) + summary = 1; + else if (unformat (input, "summary")) + summary = 1; else if (unformat (input, "%U", unformat_vnet_sw_interface, vnet_get_main(), &sw_if_index)) @@ -388,39 +399,49 @@ adj_show (vlib_main_t * vm, break; } - if (ADJ_INDEX_INVALID != ai) + if (summary) { - if (pool_is_free_index(adj_pool, ai)) - { - vlib_cli_output (vm, "adjacency %d invalid", ai); - return 0; - } - - vlib_cli_output (vm, "[@%d] %U", - ai, - format_ip_adjacency, ai, - FORMAT_IP_ADJACENCY_DETAIL); + vlib_cli_output (vm, "Number of adjacenies: %d", pool_elts(adj_pool)); + vlib_cli_output (vm, "Per-adjacency counters: %s", + (adj_are_counters_enabled() ? + "enabled": + "disabled")); } else { - /* *INDENT-OFF* */ - pool_foreach_index(ai, adj_pool, - ({ - if (~0 != sw_if_index && - sw_if_index != adj_get_sw_if_index(ai)) - { - } - else + if (ADJ_INDEX_INVALID != ai) + { + if (pool_is_free_index(adj_pool, ai)) { - vlib_cli_output (vm, "[@%d] %U", - ai, - format_ip_adjacency, ai, - FORMAT_IP_ADJACENCY_NONE); - } - })); - /* *INDENT-ON* */ - } + vlib_cli_output (vm, "adjacency %d invalid", ai); + return 0; + } + vlib_cli_output (vm, "[@%d] %U", + ai, + format_ip_adjacency, ai, + FORMAT_IP_ADJACENCY_DETAIL); + } + else + { + /* *INDENT-OFF* */ + pool_foreach_index(ai, adj_pool, + ({ + if (~0 != sw_if_index && + sw_if_index != adj_get_sw_if_index(ai)) + { + } + else + { + vlib_cli_output (vm, "[@%d] %U", + ai, + format_ip_adjacency, ai, + FORMAT_IP_ADJACENCY_NONE); + } + })); + /* *INDENT-ON* */ + } + } return 0; } @@ -438,6 +459,50 @@ adj_show (vlib_main_t * vm, ?*/ VLIB_CLI_COMMAND (adj_show_command, static) = { .path = "show adj", - .short_help = "show adj [<adj_index>] [interface]", + .short_help = "show adj [<adj_index>] [interface] [summary]", .function = adj_show, }; + +/** + * @brief CLI invoked function to enable/disable per-adj counters + */ +static clib_error_t * +adj_cli_counters_set (vlib_main_t * vm, + unformat_input_t * input, + vlib_cli_command_t * cmd) +{ + clib_error_t *error = NULL; + int enable = ~0; + + while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) + { + if (unformat (input, "enable")) + enable = 1; + else if (unformat (input, "disable")) + enable = 0; + else + break; + } + + if (enable != ~0) + { + /* user requested something sensible */ + adj_per_adj_counters = enable; + } + else + { + error = clib_error_return (0, "specify 'enable' or 'disable'"); + } + + return (error); +} + +/*? + * Enabe/disble 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", + .short_help = "adjacency counters [enable|disable]", + .function = adj_cli_counters_set, +}; diff --git a/src/vnet/adj/adj.h b/src/vnet/adj/adj.h index 29bae6733b3..fcc5890c7d7 100644 --- a/src/vnet/adj/adj.h +++ b/src/vnet/adj/adj.h @@ -109,6 +109,12 @@ extern ip_adjacency_t *adj_pool; extern vlib_combined_counter_main_t adjacency_counters; /** + * @brief Global Config for enabling per-adjacency counters + * This is configurable because it comes with a non-negligible + * performance cost. */ +extern int adj_per_adj_counters; + +/** * @brief * Get a pointer to an adjacency object from its index */ @@ -118,4 +124,13 @@ adj_get (adj_index_t adj_index) return (vec_elt_at_index(adj_pool, adj_index)); } +/** + * @brief Get the global configuration option for enabling per-adj counters + */ +static inline int +adj_are_counters_enabled (void) +{ + return (adj_per_adj_counters); +} + #endif diff --git a/src/vnet/ip/ip4_forward.c b/src/vnet/ip/ip4_forward.c index b3721e63d97..31b687d7347 100644 --- a/src/vnet/ip/ip4_forward.c +++ b/src/vnet/ip/ip4_forward.c @@ -2326,7 +2326,8 @@ typedef enum always_inline uword ip4_rewrite_inline (vlib_main_t * vm, vlib_node_runtime_t * node, - vlib_frame_t * frame, int is_midchain, int is_mcast) + vlib_frame_t * frame, + int do_counters, int is_midchain, int is_mcast) { ip_lookup_main_t *lm = &ip4_main.lookup_main; u32 *from = vlib_frame_vector_args (frame); @@ -2487,10 +2488,13 @@ ip4_rewrite_inline (vlib_main_t * vm, /* * pre-fetch the per-adjacency counters */ - vlib_prefetch_combined_counter (&adjacency_counters, - cpu_index, adj_index0); - vlib_prefetch_combined_counter (&adjacency_counters, - cpu_index, adj_index1); + if (do_counters) + { + vlib_prefetch_combined_counter (&adjacency_counters, + cpu_index, adj_index0); + vlib_prefetch_combined_counter (&adjacency_counters, + cpu_index, adj_index1); + } /* Don't adjust the buffer for ttl issue; icmp-error node wants * to see the IP headerr */ @@ -2525,15 +2529,20 @@ ip4_rewrite_inline (vlib_main_t * vm, /* * Bump the per-adjacency counters */ - vlib_increment_combined_counter - (&adjacency_counters, - cpu_index, - adj_index0, 1, vlib_buffer_length_in_chain (vm, p0) + rw_len0); - - vlib_increment_combined_counter - (&adjacency_counters, - cpu_index, - adj_index1, 1, vlib_buffer_length_in_chain (vm, p1) + rw_len1); + if (do_counters) + { + vlib_increment_combined_counter + (&adjacency_counters, + cpu_index, + adj_index0, 1, + vlib_buffer_length_in_chain (vm, p0) + rw_len0); + + vlib_increment_combined_counter + (&adjacency_counters, + cpu_index, + adj_index1, 1, + vlib_buffer_length_in_chain (vm, p1) + rw_len1); + } if (is_midchain) { @@ -2722,21 +2731,30 @@ static uword ip4_rewrite (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame) { - return ip4_rewrite_inline (vm, node, frame, 0, 0); + if (adj_are_counters_enabled ()) + return ip4_rewrite_inline (vm, node, frame, 1, 0, 0); + else + return ip4_rewrite_inline (vm, node, frame, 0, 0, 0); } static uword ip4_midchain (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame) { - return ip4_rewrite_inline (vm, node, frame, 1, 0); + if (adj_are_counters_enabled ()) + return ip4_rewrite_inline (vm, node, frame, 1, 1, 0); + else + return ip4_rewrite_inline (vm, node, frame, 0, 1, 0); } static uword ip4_rewrite_mcast (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame) { - return ip4_rewrite_inline (vm, node, frame, 0, 1); + if (adj_are_counters_enabled ()) + return ip4_rewrite_inline (vm, node, frame, 1, 0, 1); + else + return ip4_rewrite_inline (vm, node, frame, 0, 0, 1); } /* *INDENT-OFF* */ diff --git a/src/vnet/ip/ip6_forward.c b/src/vnet/ip/ip6_forward.c index 066ee54b884..91a303d4857 100644 --- a/src/vnet/ip/ip6_forward.c +++ b/src/vnet/ip/ip6_forward.c @@ -1911,7 +1911,8 @@ typedef enum always_inline uword ip6_rewrite_inline (vlib_main_t * vm, vlib_node_runtime_t * node, - vlib_frame_t * frame, int is_midchain, int is_mcast) + vlib_frame_t * frame, + int do_counters, int is_midchain, int is_mcast) { ip_lookup_main_t *lm = &ip6_main.lookup_main; u32 *from = vlib_frame_vector_args (frame); @@ -2042,14 +2043,17 @@ ip6_rewrite_inline (vlib_main_t * vm, vnet_buffer (p0)->ip.save_rewrite_length = rw_len0; vnet_buffer (p1)->ip.save_rewrite_length = rw_len1; - vlib_increment_combined_counter - (&adjacency_counters, - cpu_index, - adj_index0, 1, vlib_buffer_length_in_chain (vm, p0) + rw_len0); - vlib_increment_combined_counter - (&adjacency_counters, - cpu_index, adj_index1, - 1, vlib_buffer_length_in_chain (vm, p1) + rw_len1); + if (do_counters) + { + vlib_increment_combined_counter + (&adjacency_counters, + cpu_index, adj_index0, 1, + vlib_buffer_length_in_chain (vm, p0) + rw_len0); + vlib_increment_combined_counter + (&adjacency_counters, + cpu_index, adj_index1, 1, + vlib_buffer_length_in_chain (vm, p1) + rw_len1); + } /* Check MTU of outgoing interface. */ error0 = @@ -2175,10 +2179,13 @@ ip6_rewrite_inline (vlib_main_t * vm, rw_len0 = adj0[0].rewrite_header.data_bytes; vnet_buffer (p0)->ip.save_rewrite_length = rw_len0; - vlib_increment_combined_counter - (&adjacency_counters, - cpu_index, - adj_index0, 1, vlib_buffer_length_in_chain (vm, p0) + rw_len0); + if (do_counters) + { + vlib_increment_combined_counter + (&adjacency_counters, + cpu_index, adj_index0, 1, + vlib_buffer_length_in_chain (vm, p0) + rw_len0); + } /* Check MTU of outgoing interface. */ error0 = @@ -2238,21 +2245,30 @@ static uword ip6_rewrite (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame) { - return ip6_rewrite_inline (vm, node, frame, 0, 0); + if (adj_are_counters_enabled ()) + return ip6_rewrite_inline (vm, node, frame, 1, 0, 0); + else + return ip6_rewrite_inline (vm, node, frame, 0, 0, 0); } static uword ip6_rewrite_mcast (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame) { - return ip6_rewrite_inline (vm, node, frame, 0, 1); + if (adj_are_counters_enabled ()) + return ip6_rewrite_inline (vm, node, frame, 1, 0, 1); + else + return ip6_rewrite_inline (vm, node, frame, 0, 0, 1); } static uword ip6_midchain (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame) { - return ip6_rewrite_inline (vm, node, frame, 1, 0); + if (adj_are_counters_enabled ()) + return ip6_rewrite_inline (vm, node, frame, 1, 1, 0); + else + return ip6_rewrite_inline (vm, node, frame, 0, 1, 0); } /* *INDENT-OFF* */ |