*/
#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,
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;
}
{
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);
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
{
{
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",
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;
}
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)
{
u32 pool_index;
u8 *match_name = 0;
u8 *name;
+ uword *pi;
sse2_qos_pol_cfg_params_st *config;
policer_read_response_type_st *templ;
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* */
};
/* *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)
{