From 0f6b7960716d09129bec60fe942a6bed1ef729d5 Mon Sep 17 00:00:00 2001 From: Florin Coras Date: Tue, 21 Jun 2016 22:32:47 +0200 Subject: Use lisp_gpeX iface counters to store decap stats The patch switches to using LISP interface counters for storing the number of decapsulated packets instead of using per decap node stats. It also removes the encap node (iface tx node) stats since the iface output node already keeps track of the number of encapsulated packets. Change-Id: I636702a824264c173792f2f0c7fec0b0f4c6a9f7 Signed-off-by: Florin Coras --- vnet/vnet/lisp-gpe/decap.c | 75 +++++++++++++++++++++++------------ vnet/vnet/lisp-gpe/interface.c | 26 ++++++++---- vnet/vnet/lisp-gpe/lisp_gpe.c | 4 +- vnet/vnet/lisp-gpe/lisp_gpe_error.def | 2 +- 4 files changed, 71 insertions(+), 36 deletions(-) (limited to 'vnet') diff --git a/vnet/vnet/lisp-gpe/decap.c b/vnet/vnet/lisp-gpe/decap.c index 4684c29315e..23769765ab7 100644 --- a/vnet/vnet/lisp-gpe/decap.c +++ b/vnet/vnet/lisp-gpe/decap.c @@ -77,14 +77,42 @@ next_protocol_to_next_index (lisp_gpe_header_t * lgh, u8 * next_header) return LISP_GPE_INPUT_NEXT_DROP; } +static_always_inline void +incr_decap_stats (vnet_main_t * vnm, u32 cpu_index, u32 length, u32 sw_if_index, + u32 * last_sw_if_index, u32 * n_packets, u32 * n_bytes) +{ + vnet_interface_main_t * im; + + if (PREDICT_TRUE(sw_if_index == *last_sw_if_index)) + { + *n_packets += 1; + *n_bytes += length; + } + else + { + if (PREDICT_TRUE(*last_sw_if_index != ~0)) + { + im = &vnm->interface_main; + + vlib_increment_combined_counter ( + im->combined_sw_if_counters + VNET_INTERFACE_COUNTER_RX, + cpu_index, *last_sw_if_index, *n_packets, *n_bytes); + } + *last_sw_if_index = sw_if_index; + *n_packets = 1; + *n_bytes = length; + } +} + static uword lisp_gpe_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * from_frame, u8 is_v4) { - u32 n_left_from, next_index, * from, * to_next; - u32 pkts_decapsulated = 0; + u32 n_left_from, next_index, * from, * to_next, cpu_index; + u32 n_bytes = 0, n_packets = 0, last_sw_if_index = ~0, drops = 0; lisp_gpe_main_t * lgm = &lisp_gpe_main; + cpu_index = os_get_cpu_number(); from = vlib_frame_vector_args (from_frame); n_left_from = from_frame->n_vectors; @@ -187,26 +215,32 @@ lisp_gpe_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node, if (si0) { + incr_decap_stats (lgm->vnet_main, cpu_index, + vlib_buffer_length_in_chain (vm, b0), si0[0], + &last_sw_if_index, &n_packets, &n_bytes); vnet_buffer(b0)->sw_if_index[VLIB_RX] = si0[0]; - pkts_decapsulated++; error0 = 0; } else { next0 = LISP_GPE_INPUT_NEXT_DROP; - error0 = LISP_GPE_ERROR_NO_SUCH_TUNNEL; + error0 = LISP_GPE_ERROR_NO_TUNNEL; + drops++; } if (si1) { + incr_decap_stats (lgm->vnet_main, cpu_index, + vlib_buffer_length_in_chain (vm, b1), si1[0], + &last_sw_if_index, &n_packets, &n_bytes); vnet_buffer(b1)->sw_if_index[VLIB_RX] = si1[0]; - pkts_decapsulated++; error1 = 0; } else { next1 = LISP_GPE_INPUT_NEXT_DROP; - error1 = LISP_GPE_ERROR_NO_SUCH_TUNNEL; + error1 = LISP_GPE_ERROR_NO_TUNNEL; + drops++; } b0->error = error0 ? node->errors[error0] : 0; @@ -304,14 +338,17 @@ lisp_gpe_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node, if (si0) { + incr_decap_stats (lgm->vnet_main, cpu_index, + vlib_buffer_length_in_chain (vm, b0), si0[0], + &last_sw_if_index, &n_packets, &n_bytes); vnet_buffer(b0)->sw_if_index[VLIB_RX] = si0[0]; - pkts_decapsulated++; error0 = 0; } else { next0 = LISP_GPE_INPUT_NEXT_DROP; - error0 = LISP_GPE_ERROR_NO_SUCH_TUNNEL; + error0 = LISP_GPE_ERROR_NO_TUNNEL; + drops++; } /* TODO error handling if security is implemented */ @@ -332,9 +369,12 @@ lisp_gpe_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_put_next_frame (vm, node, next_index, n_left_to_next); } + + /* flush iface stats */ + incr_decap_stats (lgm->vnet_main, cpu_index, 0, ~0, &last_sw_if_index, + &n_packets, &n_bytes); vlib_node_increment_counter (vm, lisp_gpe_ip4_input_node.index, - LISP_GPE_ERROR_DECAPSULATED, - pkts_decapsulated); + LISP_GPE_ERROR_NO_TUNNEL, drops); return from_frame->n_vectors; } @@ -352,22 +392,11 @@ lisp_gpe_ip6_input (vlib_main_t * vm, vlib_node_runtime_t * node, return lisp_gpe_input_inline(vm, node, from_frame, 0); } -static char * lisp_gpe_error_strings[] = { -#define lisp_gpe_error(n,s) s, -#include -#undef lisp_gpe_error -#undef _ -}; - VLIB_REGISTER_NODE (lisp_gpe_ip4_input_node) = { .function = lisp_gpe_ip4_input, .name = "lisp-gpe-ip4-input", /* Takes a vector of packets. */ .vector_size = sizeof (u32), - - .n_errors = LISP_GPE_N_ERROR, - .error_strings = lisp_gpe_error_strings, - .n_next_nodes = LISP_GPE_INPUT_N_NEXT, .next_nodes = { #define _(s,n) [LISP_GPE_INPUT_NEXT_##s] = n, @@ -385,10 +414,6 @@ VLIB_REGISTER_NODE (lisp_gpe_ip6_input_node) = { .name = "lisp-gpe-ip6-input", /* Takes a vector of packets. */ .vector_size = sizeof (u32), - - .n_errors = LISP_GPE_N_ERROR, - .error_strings = lisp_gpe_error_strings, - .n_next_nodes = LISP_GPE_INPUT_N_NEXT, .next_nodes = { #define _(s,n) [LISP_GPE_INPUT_NEXT_##s] = n, diff --git a/vnet/vnet/lisp-gpe/interface.c b/vnet/vnet/lisp-gpe/interface.c index bda68d6ea4b..c20e902c725 100644 --- a/vnet/vnet/lisp-gpe/interface.c +++ b/vnet/vnet/lisp-gpe/interface.c @@ -154,7 +154,6 @@ lisp_gpe_interface_tx (vlib_main_t * vm, vlib_node_runtime_t * node, { u32 n_left_from, next_index, * from, * to_next; lisp_gpe_main_t * lgm = &lisp_gpe_main; - u32 pkts_encapsulated = 0; from = vlib_frame_vector_args (from_frame); n_left_from = from_frame->n_vectors; @@ -249,8 +248,6 @@ lisp_gpe_interface_tx (vlib_main_t * vm, vlib_node_runtime_t * node, tr->tunnel_index = t1 - lgm->tunnels; } - pkts_encapsulated += 2; - vlib_validate_buffer_enqueue_x2(vm, node, next_index, to_next, n_left_to_next, bi0, bi1, next0, next1); @@ -281,8 +278,6 @@ lisp_gpe_interface_tx (vlib_main_t * vm, vlib_node_runtime_t * node, /* Reset to look up tunnel partner in the configured FIB */ vnet_buffer(b0)->sw_if_index[VLIB_TX] = t0->encap_fib_index; - pkts_encapsulated++; - if (PREDICT_FALSE(b0->flags & VLIB_BUFFER_IS_TRACED)) { lisp_gpe_tx_trace_t *tr = vlib_add_trace (vm, node, b0, @@ -295,8 +290,7 @@ lisp_gpe_interface_tx (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_put_next_frame (vm, node, next_index, n_left_to_next); } - vlib_node_increment_counter (vm, node->node_index, - LISP_GPE_ERROR_ENCAPSULATED, pkts_encapsulated); + return from_frame->n_vectors; } @@ -512,6 +506,22 @@ vnet_lisp_gpe_add_del_iface (vnet_lisp_gpe_add_del_iface_args_t * a, { hw_if_index = lgm->free_lisp_gpe_tunnel_hw_if_indices[flen - 1]; _vec_len(lgm->free_lisp_gpe_tunnel_hw_if_indices) -= 1; + + hi = vnet_get_hw_interface (vnm, hw_if_index); + + /* clear old stats of freed interface before reuse */ + vnet_interface_main_t * im = &vnm->interface_main; + vnet_interface_counter_lock (im); + vlib_zero_combined_counter ( + &im->combined_sw_if_counters[VNET_INTERFACE_COUNTER_TX], + hi->sw_if_index); + vlib_zero_combined_counter ( + &im->combined_sw_if_counters[VNET_INTERFACE_COUNTER_RX], + hi->sw_if_index); + vlib_zero_simple_counter ( + &im->sw_if_counters[VNET_INTERFACE_COUNTER_DROP], + hi->sw_if_index); + vnet_interface_counter_unlock (im); } else { @@ -519,9 +529,9 @@ vnet_lisp_gpe_add_del_iface (vnet_lisp_gpe_add_del_iface_args_t * a, lisp_gpe_device_class.index, a->table_id, lisp_gpe_hw_class.index, 0); + hi = vnet_get_hw_interface (vnm, hw_if_index); } - hi = vnet_get_hw_interface (vnm, hw_if_index); hash_set(lgm->lisp_gpe_hw_if_index_by_table_id, a->table_id, hw_if_index); /* set tunnel termination: post decap, packets are tagged as having been diff --git a/vnet/vnet/lisp-gpe/lisp_gpe.c b/vnet/vnet/lisp-gpe/lisp_gpe.c index 0eacb385c58..7ed21abfab7 100644 --- a/vnet/vnet/lisp-gpe/lisp_gpe.c +++ b/vnet/vnet/lisp-gpe/lisp_gpe.c @@ -276,8 +276,8 @@ vnet_lisp_gpe_add_del_fwd_entry (vnet_lisp_gpe_add_del_fwd_entry_args_t * a, lgm->lgpe_ip4_lookup_next_index_by_table_id : lgm->lgpe_ip6_lookup_next_index_by_table_id; lookup_next_index = hash_get(lnip, a->table_id); - lgpe_sw_if_index = hash_get(lgm->lisp_gpe_hw_if_index_by_table_id, - a->table_id); + lgpe_sw_if_index = hash_get(lgm->tunnel_term_sw_if_index_by_vni, + a->vni); /* the assumption is that the interface must've been created before * programming the dp */ diff --git a/vnet/vnet/lisp-gpe/lisp_gpe_error.def b/vnet/vnet/lisp-gpe/lisp_gpe_error.def index c4c3f75d8eb..415fada73d2 100644 --- a/vnet/vnet/lisp-gpe/lisp_gpe_error.def +++ b/vnet/vnet/lisp-gpe/lisp_gpe_error.def @@ -15,4 +15,4 @@ lisp_gpe_error (ENCAPSULATED, "good packets encapsulated") lisp_gpe_error (DECAPSULATED, "good packets decapsulated") -lisp_gpe_error (NO_SUCH_TUNNEL, "no such tunnel packets") +lisp_gpe_error (NO_TUNNEL, "tunnel does not exist") -- cgit 1.2.3-korg