policer: add counters
[vpp.git] / src / vnet / policer / policer.c
index cd754e2..fbb3055 100644 (file)
  */
 #include <stdint.h>
 #include <vnet/policer/policer.h>
+#include <vnet/policer/police_inlines.h>
 #include <vnet/classify/vnet_classify.h>
 
+vnet_policer_main_t vnet_policer_main;
+
+u8 *
+format_policer_handoff_trace (u8 *s, va_list *args)
+{
+  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
+  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
+  policer_handoff_trace_t *t = va_arg (*args, policer_handoff_trace_t *);
+
+  s = format (s, "policer %d, handoff thread %d to %d", t->policer_index,
+             t->current_worker_index, t->next_worker_index);
+
+  return s;
+}
+
+vlib_combined_counter_main_t policer_counters[] = {
+  {
+    .name = "Policer-Conform",
+    .stat_segment_name = "/net/policer/conform",
+  },
+  {
+    .name = "Policer-Exceed",
+    .stat_segment_name = "/net/policer/exceed",
+  },
+  {
+    .name = "Policer-Violate",
+    .stat_segment_name = "/net/policer/violate",
+  },
+};
+
 clib_error_t *
 policer_add_del (vlib_main_t * vm,
                 u8 * name,
@@ -33,13 +64,26 @@ policer_add_del (vlib_main_t * vm,
 
   if (is_add == 0)
     {
+      /* free policer config and template */
       if (p == 0)
        {
          vec_free (name);
          return clib_error_return (0, "No such policer configuration");
        }
+      pool_put_index (pm->configs, p[0]);
+      pool_put_index (pm->policer_templates, p[0]);
       hash_unset_mem (pm->policer_config_by_name, name);
+
+      /* free policer */
+      p = hash_get_mem (pm->policer_index_by_name, name);
+      if (p == 0)
+       {
+         vec_free (name);
+         return clib_error_return (0, "No such policer");
+       }
+      pool_put_index (pm->policers, p[0]);
       hash_unset_mem (pm->policer_index_by_name, name);
+
       vec_free (name);
       return 0;
     }
@@ -57,6 +101,7 @@ policer_add_del (vlib_main_t * vm,
     {
       policer_read_response_type_st *pp;
       sse2_qos_pol_cfg_params_st *cp;
+      int i;
 
       pool_get (pm->configs, cp);
       pool_get (pm->policer_templates, pp);
@@ -72,6 +117,13 @@ policer_add_del (vlib_main_t * vm,
       pi = policer - pm->policers;
       hash_set_mem (pm->policer_index_by_name, name, pi);
       *policer_index = pi;
+      policer->thread_index = ~0;
+
+      for (i = 0; i < NUM_POLICE_RESULTS; i++)
+       {
+         vlib_validate_combined_counter (&policer_counters[i], pi);
+         vlib_zero_combined_counter (&policer_counters[i], pi);
+       }
     }
   else
     {
@@ -87,6 +139,15 @@ format_policer_instance (u8 * s, va_list * va)
 {
   policer_read_response_type_st *i
     = va_arg (*va, policer_read_response_type_st *);
+  uword pi = va_arg (*va, uword);
+  int result;
+  vlib_counter_t counts[NUM_POLICE_RESULTS];
+
+  for (result = 0; result < NUM_POLICE_RESULTS; result++)
+    {
+      vlib_get_combined_counter (&policer_counters[result], pi,
+                                &counts[result]);
+    }
 
   s = format (s, "policer at %llx: %s rate, %s color-aware\n",
              i, i->single_rate ? "single" : "dual",
@@ -97,6 +158,12 @@ format_policer_instance (u8 * s, va_list * va)
              i->current_limit,
              i->current_bucket, i->extended_limit, i->extended_bucket);
   s = format (s, "last update %llu\n", i->last_update_time);
+  s = format (s, "conform %llu packets, %llu bytes\n",
+             counts[POLICE_CONFORM].packets, counts[POLICE_CONFORM].bytes);
+  s = format (s, "exceed %llu packets, %llu bytes\n",
+             counts[POLICE_EXCEED].packets, counts[POLICE_EXCEED].bytes);
+  s = format (s, "violate %llu packets, %llu bytes\n",
+             counts[POLICE_VIOLATE].packets, counts[POLICE_VIOLATE].bytes);
   return s;
 }
 
@@ -419,7 +486,7 @@ configure_policer_command_fn (vlib_main_t * vm,
   if (!unformat_user (input, unformat_line_input, line_input))
     return 0;
 
-  memset (&c, 0, sizeof (c));
+  clib_memset (&c, 0, sizeof (c));
 
   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
     {
@@ -466,6 +533,7 @@ show_policer_command_fn (vlib_main_t * vm,
   u32 pool_index;
   u8 *match_name = 0;
   u8 *name;
+  uword *pi;
   sse2_qos_pol_cfg_params_st *config;
   policer_read_response_type_st *templ;
 
@@ -477,14 +545,16 @@ show_policer_command_fn (vlib_main_t * vm,
     name = (u8 *) p->key;
     if (match_name == 0 || !strcmp((char *) name, (char *) match_name))
       {
-        pool_index = p->value[0];
-        config = pool_elt_at_index (pm->configs, pool_index);
-        templ = pool_elt_at_index (pm->policer_templates, pool_index);
-        vlib_cli_output (vm, "Name \"%s\" %U ",
-                         name, format_policer_config, config);
-        vlib_cli_output (vm, "Template %U",
-                         format_policer_instance, templ);
-        vlib_cli_output (vm, "-----------");
+       pi = hash_get_mem (pm->policer_index_by_name, name);
+
+       pool_index = p->value[0];
+       config = pool_elt_at_index (pm->configs, pool_index);
+       templ = pool_elt_at_index (pm->policer_templates, pool_index);
+       vlib_cli_output (vm, "Name \"%s\" %U ", name, format_policer_config,
+                        config);
+       vlib_cli_output (vm, "Template %U", format_policer_instance, templ,
+                        pi[0]);
+       vlib_cli_output (vm, "-----------");
       }
   }));
   /* *INDENT-ON* */
@@ -500,6 +570,27 @@ VLIB_CLI_COMMAND (show_policer_command, static) = {
 };
 /* *INDENT-ON* */
 
+static clib_error_t *
+show_policer_pools_command_fn (vlib_main_t * vm,
+                              unformat_input_t * input,
+                              vlib_cli_command_t * cmd)
+{
+  vnet_policer_main_t *pm = &vnet_policer_main;
+
+  vlib_cli_output (vm, "pool sizes: configs=%d templates=%d policers=%d",
+                  pool_elts (pm->configs),
+                  pool_elts (pm->policer_templates),
+                  pool_elts (pm->policers));
+  return 0;
+}
+/* *INDENT-OFF* */
+VLIB_CLI_COMMAND (show_policer_pools_command, static) = {
+    .path = "show policer pools",
+    .short_help = "show policer pools",
+    .function = show_policer_pools_command_fn,
+};
+/* *INDENT-ON* */
+
 clib_error_t *
 policer_init (vlib_main_t * vm)
 {