Add TX statistics for nsh-gre tunnel 25/925/2
authorHongjun Ni <hongjun.ni@intel.com>
Fri, 29 Apr 2016 00:02:52 +0000 (17:02 -0700)
committerDave Barach <openvpp@barachs.net>
Fri, 29 Apr 2016 12:41:23 +0000 (12:41 +0000)
Change-Id: I20e4abcc82c00e43dd441f1882cb6be531b6876e
Signed-off-by: Hongjun Ni <hongjun.ni@intel.com>
vnet/vnet/nsh-gre/encap.c

index 8521aea..78b0217 100644 (file)
@@ -64,13 +64,18 @@ nsh_gre_encap (vlib_main_t * vm,
   u32 n_left_from, next_index, * from, * to_next;
   nsh_gre_main_t * ngm = &nsh_gre_main;
   vnet_main_t * vnm = ngm->vnet_main;
+  vnet_interface_main_t * im = &vnm->interface_main;
   u32 pkts_encapsulated = 0;
   u16 old_l0 = 0, old_l1 = 0;
+  u32 cpu_index = os_get_cpu_number();
+  u32 stats_sw_if_index, stats_n_packets, stats_n_bytes;
 
   from = vlib_frame_vector_args (from_frame);
   n_left_from = from_frame->n_vectors;
 
   next_index = node->cached_next_index;
+  stats_sw_if_index = node->runtime_data[0];
+  stats_n_packets = stats_n_bytes = 0;
 
   while (n_left_from > 0)
     {
@@ -85,6 +90,7 @@ nsh_gre_encap (vlib_main_t * vm,
          vlib_buffer_t * b0, * b1;
          u32 next0 = NSH_GRE_ENCAP_NEXT_IP4_LOOKUP;
          u32 next1 = NSH_GRE_ENCAP_NEXT_IP4_LOOKUP;
+          u32 sw_if_index0, sw_if_index1, len0, len1;
           vnet_hw_interface_t * hi0, * hi1;
           ip4_header_t * ip0, * ip1;
           u64 * copy_src0, * copy_dst0;
@@ -119,7 +125,10 @@ nsh_gre_encap (vlib_main_t * vm,
          b0 = vlib_get_buffer (vm, bi0);
          b1 = vlib_get_buffer (vm, bi1);
 
-          hi0 = vnet_get_sup_hw_interface 
+          /* 1-wide cache? */
+          sw_if_index0 = vnet_buffer(b0)->sw_if_index[VLIB_TX];
+          sw_if_index1 = vnet_buffer(b1)->sw_if_index[VLIB_TX];
+          hi0 = vnet_get_sup_hw_interface
             (vnm, vnet_buffer(b0)->sw_if_index[VLIB_TX]);
           hi1 = vnet_get_sup_hw_interface 
             (vnm, vnet_buffer(b1)->sw_if_index[VLIB_TX]);
@@ -183,9 +192,43 @@ nsh_gre_encap (vlib_main_t * vm,
           /* Reset to look up tunnel partner in the configured FIB */
           vnet_buffer(b0)->sw_if_index[VLIB_TX] = t0->encap_fib_index;
           vnet_buffer(b1)->sw_if_index[VLIB_TX] = t1->encap_fib_index;
+          vnet_buffer(b0)->sw_if_index[VLIB_RX] = sw_if_index0;
+          vnet_buffer(b1)->sw_if_index[VLIB_RX] = sw_if_index1;
           pkts_encapsulated += 2;
 
-          if (PREDICT_FALSE(b0->flags & VLIB_BUFFER_IS_TRACED)) 
+          len0 = vlib_buffer_length_in_chain(vm, b0);
+          len1 = vlib_buffer_length_in_chain(vm, b0);
+          stats_n_packets += 2;
+          stats_n_bytes += len0 + len1;
+
+          /* Batch stats increment on the same vxlan tunnel so counter is not
+           incremented per packet. Note stats are still incremented for deleted
+           and admin-down tunnel where packets are dropped. It is not worthwhile
+           to check for this rare case and affect normal path performance. */
+          if (PREDICT_FALSE(
+              (sw_if_index0 != stats_sw_if_index)
+                  || (sw_if_index1 != stats_sw_if_index))) {
+            stats_n_packets -= 2;
+            stats_n_bytes -= len0 + len1;
+            if (sw_if_index0 == sw_if_index1) {
+              if (stats_n_packets)
+                vlib_increment_combined_counter(
+                    im->combined_sw_if_counters + VNET_INTERFACE_COUNTER_TX,
+                    cpu_index, stats_sw_if_index, stats_n_packets, stats_n_bytes);
+              stats_sw_if_index = sw_if_index0;
+              stats_n_packets = 2;
+              stats_n_bytes = len0 + len1;
+            } else {
+              vlib_increment_combined_counter(
+                  im->combined_sw_if_counters + VNET_INTERFACE_COUNTER_TX,
+                  cpu_index, sw_if_index0, 1, len0);
+              vlib_increment_combined_counter(
+                  im->combined_sw_if_counters + VNET_INTERFACE_COUNTER_TX,
+                  cpu_index, sw_if_index1, 1, len1);
+            }
+          }
+
+          if (PREDICT_FALSE(b0->flags & VLIB_BUFFER_IS_TRACED))
             {
               nsh_gre_encap_trace_t *tr = 
                 vlib_add_trace (vm, node, b0, sizeof (*tr));
@@ -209,6 +252,7 @@ nsh_gre_encap (vlib_main_t * vm,
          u32 bi0;
          vlib_buffer_t * b0;
          u32 next0 = NSH_GRE_ENCAP_NEXT_IP4_LOOKUP;
+      u32 sw_if_index0, len0;
           vnet_hw_interface_t * hi0;
           ip4_header_t * ip0;
           u64 * copy_src0, * copy_dst0;
@@ -226,7 +270,8 @@ nsh_gre_encap (vlib_main_t * vm,
          b0 = vlib_get_buffer (vm, bi0);
 
           /* 1-wide cache? */
-          hi0 = vnet_get_sup_hw_interface 
+          sw_if_index0 = vnet_buffer(b0)->sw_if_index[VLIB_TX];
+          hi0 = vnet_get_sup_hw_interface
             (vnm, vnet_buffer(b0)->sw_if_index[VLIB_TX]);
 
           t0 = pool_elt_at_index (ngm->tunnels, hi0->dev_instance);
@@ -262,9 +307,29 @@ nsh_gre_encap (vlib_main_t * vm,
 
           /* Reset to look up tunnel partner in the configured FIB */
           vnet_buffer(b0)->sw_if_index[VLIB_TX] = t0->encap_fib_index;
+          vnet_buffer(b0)->sw_if_index[VLIB_RX] = sw_if_index0;
           pkts_encapsulated ++;
 
-          if (PREDICT_FALSE(b0->flags & VLIB_BUFFER_IS_TRACED)) 
+          len0 = vlib_buffer_length_in_chain(vm, b0);
+          stats_n_packets += 1;
+          stats_n_bytes += len0;
+
+          /* Batch stats increment on the same vxlan tunnel so counter is not
+           incremented per packet. Note stats are still incremented for deleted
+           and admin-down tunnel where packets are dropped. It is not worthwhile
+           to check for this rare case and affect normal path performance. */
+          if (PREDICT_FALSE(sw_if_index0 != stats_sw_if_index)) {
+            stats_n_packets -= 1;
+            stats_n_bytes -= len0;
+            if (stats_n_packets)
+              vlib_increment_combined_counter(
+                  im->combined_sw_if_counters + VNET_INTERFACE_COUNTER_TX,
+                  cpu_index, stats_sw_if_index, stats_n_packets, stats_n_bytes);
+            stats_n_packets = 1;
+            stats_n_bytes = len0;
+            stats_sw_if_index = sw_if_index0;
+          }
+          if (PREDICT_FALSE(b0->flags & VLIB_BUFFER_IS_TRACED))
             {
               nsh_gre_encap_trace_t *tr = 
                 vlib_add_trace (vm, node, b0, sizeof (*tr));
@@ -280,6 +345,14 @@ nsh_gre_encap (vlib_main_t * vm,
   vlib_node_increment_counter (vm, node->node_index, 
                                NSH_GRE_ENCAP_ERROR_ENCAPSULATED, 
                                pkts_encapsulated);
+  /* Increment any remaining batch stats */
+  if (stats_n_packets) {
+    vlib_increment_combined_counter(
+        im->combined_sw_if_counters + VNET_INTERFACE_COUNTER_TX, cpu_index,
+        stats_sw_if_index, stats_n_packets, stats_n_bytes);
+    node->runtime_data[0] = stats_sw_if_index;
+  }
+
   return from_frame->n_vectors;
 }