Use lisp_gpeX iface counters to store decap stats 93/1693/5
authorFlorin Coras <[email protected]>
Tue, 21 Jun 2016 20:32:47 +0000 (22:32 +0200)
committerDave Barach <[email protected]>
Thu, 23 Jun 2016 21:48:48 +0000 (21:48 +0000)
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 <[email protected]>
vnet/vnet/lisp-gpe/decap.c
vnet/vnet/lisp-gpe/interface.c
vnet/vnet/lisp-gpe/lisp_gpe.c
vnet/vnet/lisp-gpe/lisp_gpe_error.def

index 4684c29..2376976 100644 (file)
@@ -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 <vnet/lisp-gpe/lisp_gpe_error.def>
-#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,
index bda68d6..c20e902 100644 (file)
@@ -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
index 0eacb38..7ed21ab 100644 (file)
@@ -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 */
index c4c3f75..415fada 100644 (file)
@@ -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")