* limitations under the License.
*/
#include <stdint.h>
+#include <stdbool.h>
#include <vnet/policer/policer.h>
#include <vnet/policer/police_inlines.h>
#include <vnet/classify/vnet_classify.h>
u32 *policer_index, u8 is_add)
{
vnet_policer_main_t *pm = &vnet_policer_main;
- policer_read_response_type_st test_policer;
- policer_read_response_type_st *policer;
+ policer_t test_policer;
+ policer_t *policer;
uword *p;
u32 pi;
int rv;
if (rv == 0)
{
- policer_read_response_type_st *pp;
+ policer_t *pp;
qos_pol_cfg_params_st *cp;
int i;
return 0;
}
+int
+policer_bind_worker (u8 *name, u32 worker, bool bind)
+{
+ vnet_policer_main_t *pm = &vnet_policer_main;
+ policer_t *policer;
+ uword *p;
+
+ p = hash_get_mem (pm->policer_index_by_name, name);
+ if (p == 0)
+ {
+ return VNET_API_ERROR_NO_SUCH_ENTRY;
+ }
+
+ policer = &pm->policers[p[0]];
+
+ if (bind)
+ {
+ if (worker >= vlib_num_workers ())
+ {
+ return VNET_API_ERROR_INVALID_WORKER;
+ }
+
+ policer->thread_index = vlib_get_worker_thread_index (worker);
+ }
+ else
+ {
+ policer->thread_index = ~0;
+ }
+ return 0;
+}
+
+int
+policer_input (u8 *name, u32 sw_if_index, bool apply)
+{
+ vnet_policer_main_t *pm = &vnet_policer_main;
+ policer_t *policer;
+ u32 policer_index;
+ uword *p;
+
+ p = hash_get_mem (pm->policer_index_by_name, name);
+ if (p == 0)
+ {
+ return VNET_API_ERROR_NO_SUCH_ENTRY;
+ }
+
+ policer = &pm->policers[p[0]];
+ policer_index = policer - pm->policers;
+
+ if (apply)
+ {
+ vec_validate (pm->policer_index_by_sw_if_index, sw_if_index);
+ pm->policer_index_by_sw_if_index[sw_if_index] = policer_index;
+ }
+ else
+ {
+ pm->policer_index_by_sw_if_index[sw_if_index] = ~0;
+ }
+
+ vnet_feature_enable_disable ("device-input", "policer-input", sw_if_index,
+ apply, 0, 0);
+ return 0;
+}
+
u8 *
format_policer_instance (u8 * s, va_list * va)
{
- policer_read_response_type_st *i
- = va_arg (*va, policer_read_response_type_st *);
+ policer_t *i = va_arg (*va, policer_t *);
uword pi = va_arg (*va, uword);
int result;
vlib_counter_t counts[NUM_POLICE_RESULTS];
_(action)
static clib_error_t *
-configure_policer_command_fn (vlib_main_t * vm,
- unformat_input_t * input,
- vlib_cli_command_t * cmd)
+policer_add_command_fn (vlib_main_t *vm, unformat_input_t *input,
+ vlib_cli_command_t *cmd)
{
qos_pol_cfg_params_st c;
unformat_input_t _line_input, *line_input = &_line_input;
return error;
}
+static clib_error_t *
+policer_del_command_fn (vlib_main_t *vm, unformat_input_t *input,
+ vlib_cli_command_t *cmd)
+{
+ unformat_input_t _line_input, *line_input = &_line_input;
+ clib_error_t *error = NULL;
+ u8 *name = 0;
+
+ /* Get a line of input. */
+ if (!unformat_user (input, unformat_line_input, line_input))
+ return 0;
+
+ while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (line_input, "name %s", &name))
+ ;
+ else
+ {
+ error = clib_error_return (0, "unknown input `%U'",
+ format_unformat_error, line_input);
+ goto done;
+ }
+ }
+
+ error = policer_add_del (vm, name, NULL, NULL, 0);
+
+done:
+ unformat_free (line_input);
+
+ return error;
+}
+
+static clib_error_t *
+policer_bind_command_fn (vlib_main_t *vm, unformat_input_t *input,
+ vlib_cli_command_t *cmd)
+{
+ unformat_input_t _line_input, *line_input = &_line_input;
+ clib_error_t *error = NULL;
+ u8 bind, *name = 0;
+ u32 worker;
+ int rv;
+
+ bind = 1;
+ worker = ~0;
+
+ /* Get a line of input. */
+ if (!unformat_user (input, unformat_line_input, line_input))
+ return 0;
+
+ while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (line_input, "name %s", &name))
+ ;
+ else if (unformat (line_input, "unbind"))
+ bind = 0;
+ else if (unformat (line_input, "%d", &worker))
+ ;
+ else
+ {
+ error = clib_error_return (0, "unknown input `%U'",
+ format_unformat_error, line_input);
+ goto done;
+ }
+ }
+
+ if (bind && ~0 == worker)
+ {
+ error = clib_error_return (0, "specify worker to bind to: `%U'",
+ format_unformat_error, line_input);
+ }
+ else
+ {
+ rv = policer_bind_worker (name, worker, bind);
+
+ if (rv)
+ error = clib_error_return (0, "failed: `%d'", rv);
+ }
+
+done:
+ unformat_free (line_input);
+
+ return error;
+}
+
+static clib_error_t *
+policer_input_command_fn (vlib_main_t *vm, unformat_input_t *input,
+ vlib_cli_command_t *cmd)
+{
+ unformat_input_t _line_input, *line_input = &_line_input;
+ clib_error_t *error = NULL;
+ u8 apply, *name = 0;
+ u32 sw_if_index;
+ int rv;
+
+ apply = 1;
+ sw_if_index = ~0;
+
+ /* Get a line of input. */
+ if (!unformat_user (input, unformat_line_input, line_input))
+ return 0;
+
+ while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (line_input, "name %s", &name))
+ ;
+ else if (unformat (line_input, "unapply"))
+ apply = 0;
+ else if (unformat (line_input, "%U", unformat_vnet_sw_interface,
+ vnet_get_main (), &sw_if_index))
+ ;
+ else
+ {
+ error = clib_error_return (0, "unknown input `%U'",
+ format_unformat_error, line_input);
+ goto done;
+ }
+ }
+
+ if (~0 == sw_if_index)
+ {
+ error = clib_error_return (0, "specify interface to apply to: `%U'",
+ format_unformat_error, line_input);
+ }
+ else
+ {
+ rv = policer_input (name, sw_if_index, apply);
+
+ if (rv)
+ error = clib_error_return (0, "failed: `%d'", rv);
+ }
+
+done:
+ unformat_free (line_input);
+
+ return error;
+}
+
/* *INDENT-OFF* */
VLIB_CLI_COMMAND (configure_policer_command, static) = {
- .path = "configure policer",
- .short_help = "configure policer name <name> <params> ",
- .function = configure_policer_command_fn,
+ .path = "configure policer",
+ .short_help = "configure policer name <name> <params> ",
+ .function = policer_add_command_fn,
+};
+VLIB_CLI_COMMAND (policer_add_command, static) = {
+ .path = "policer add",
+ .short_help = "policer name <name> <params> ",
+ .function = policer_add_command_fn,
+};
+VLIB_CLI_COMMAND (policer_del_command, static) = {
+ .path = "policer del",
+ .short_help = "policer del name <name> ",
+ .function = policer_del_command_fn,
+};
+VLIB_CLI_COMMAND (policer_bind_command, static) = {
+ .path = "policer bind",
+ .short_help = "policer bind [unbind] name <name> <worker>",
+ .function = policer_bind_command_fn,
+};
+VLIB_CLI_COMMAND (policer_input_command, static) = {
+ .path = "policer input",
+ .short_help = "policer input [unapply] name <name> <interfac>",
+ .function = policer_input_command_fn,
};
/* *INDENT-ON* */
u8 *name;
uword *pi;
qos_pol_cfg_params_st *config;
- policer_read_response_type_st *templ;
+ policer_t *templ;
(void) unformat (input, "name %s", &match_name);
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]);
+ if (pi)
+ {
+ vlib_cli_output (vm, "Template %U", format_policer_instance, templ,
+ pi[0]);
+ }
+ else
+ {
+ vlib_cli_output (
+ vm, "Cannot print template - policer index hash lookup failed");
+ }
vlib_cli_output (vm, "-----------");
}
}));
policer_init (vlib_main_t * vm)
{
vnet_policer_main_t *pm = &vnet_policer_main;
- void vnet_policer_node_funcs_reference (void);
-
- vnet_policer_node_funcs_reference ();
pm->vlib_main = vm;
pm->vnet_main = vnet_get_main ();
pm->log_class = vlib_log_register_class ("policer", 0);
+ pm->fq_index = vlib_frame_queue_main_init (policer_input_node.index, 0);
pm->policer_config_by_name = hash_create_string (0, sizeof (uword));
pm->policer_index_by_name = hash_create_string (0, sizeof (uword));