* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#include <stdint.h>
#include <vnet/policer/policer.h>
+#include <vnet/classify/vnet_classify.h>
+
+clib_error_t *
+policer_add_del (vlib_main_t *vm,
+ u8 * name,
+ sse2_qos_pol_cfg_params_st * cfg,
+ 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;
+ uword * p;
+ u32 pi;
+ int rv;
+
+ p = hash_get_mem (pm->policer_config_by_name, name);
+
+ if (is_add == 0)
+ {
+ if (p == 0)
+ {
+ vec_free(name);
+ return clib_error_return (0, "No such policer configuration");
+ }
+ hash_unset_mem (pm->policer_config_by_name, name);
+ hash_unset_mem (pm->policer_index_by_name, name);
+ vec_free(name);
+ return 0;
+ }
+
+ if (p != 0)
+ {
+ vec_free(name);
+ return clib_error_return (0, "Policer already exists");
+ }
+
+ /* Vet the configuration before adding it to the table */
+ rv = sse2_pol_logical_2_physical (cfg, &test_policer);
+
+ if (rv == 0)
+ {
+ policer_read_response_type_st *pp;
+ sse2_qos_pol_cfg_params_st *cp;
+
+ pool_get (pm->configs, cp);
+ pool_get (pm->policer_templates, pp);
+
+ ASSERT (cp - pm->configs == pp - pm->policer_templates);
+
+ clib_memcpy (cp, cfg, sizeof (*cp));
+ clib_memcpy (pp, &test_policer, sizeof (*pp));
+
+ hash_set_mem (pm->policer_config_by_name, name, cp - pm->configs);
+ pool_get_aligned (pm->policers, policer, CLIB_CACHE_LINE_BYTES);
+ policer[0] = pp[0];
+ pi = policer - pm->policers;
+ hash_set_mem (pm->policer_index_by_name, name, pi);
+ *policer_index = pi;
+ }
+ else
+ {
+ vec_free (name);
+ return clib_error_return (0, "Config failed sanity check");
+ }
+
+ return 0;
+}
u8 * format_policer_instance (u8 * s, va_list * va)
{
return s;
}
+static u8 * format_dscp (u8 * s, va_list * va)
+{
+ u32 i = va_arg (*va, u32);
+ char * t = 0;
+
+ switch (i) {
+ #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
+ foreach_vnet_dscp
+ #undef _
+ default:
+ return format (s, "ILLEGAL");
+ }
+ s = format (s, "%s", t);
+ return s;
+}
+
+static u8 * format_policer_action_type (u8 * s, va_list * va)
+{
+ sse2_qos_pol_action_params_st * a
+ = va_arg (*va, sse2_qos_pol_action_params_st *);
+
+ if (a->action_type == SSE2_QOS_ACTION_DROP)
+ s = format (s, "drop");
+ else if (a->action_type == SSE2_QOS_ACTION_TRANSMIT)
+ s = format (s, "transmit");
+ else if (a->action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
+ s = format (s, "mark-and-transmit %U", format_dscp, a->dscp);
+ else
+ s = format (s, "ILLEGAL");
+ return s;
+}
+
u8 * format_policer_config (u8 * s, va_list * va)
{
sse2_qos_pol_cfg_params_st * c
s = format (s, "rate type %U, round type %U\n",
format_policer_rate_type, c,
format_policer_round_type, c);
+ s = format (s, "conform action %U, exceed action %U, violate action %U\n",
+ format_policer_action_type, &c->conform_action,
+ format_policer_action_type, &c->exceed_action,
+ format_policer_action_type, &c->violate_action);
return s;
}
return 0;
}
+static uword
+unformat_dscp (unformat_input_t * input, va_list * va)
+{
+ u8 * r = va_arg (*va, u8 *);
+
+ if (0) ;
+#define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
+ foreach_vnet_dscp
+#undef _
+ else
+ return 0;
+ return 1;
+}
+
+static uword
+unformat_policer_action_type (unformat_input_t * input, va_list * va)
+{
+ sse2_qos_pol_action_params_st * a
+ = va_arg (*va, sse2_qos_pol_action_params_st *);
+
+ if (unformat (input, "drop"))
+ a->action_type = SSE2_QOS_ACTION_DROP;
+ else if (unformat (input, "transmit"))
+ a->action_type = SSE2_QOS_ACTION_TRANSMIT;
+ else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
+ a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
+ else
+ return 0;
+ return 1;
+}
+
+static uword
+unformat_policer_action (unformat_input_t * input, va_list * va)
+{
+ sse2_qos_pol_cfg_params_st * c
+ = va_arg (*va, sse2_qos_pol_cfg_params_st *);
+
+ if (unformat (input, "conform-action %U", unformat_policer_action_type,
+ &c->conform_action))
+ return 1;
+ else if (unformat (input, "exceed-action %U", unformat_policer_action_type,
+ &c->exceed_action))
+ return 1;
+ else if (unformat (input, "violate-action %U", unformat_policer_action_type,
+ &c->violate_action))
+ return 1;
+ return 0;
+}
+
+static uword
+unformat_policer_classify_next_index (unformat_input_t * input, va_list * va)
+{
+ u32 * r = va_arg (*va, u32 *);
+ vnet_policer_main_t *pm = &vnet_policer_main;
+ uword * p;
+ u8 * match_name = 0;
+
+ if (unformat (input, "%s", &match_name))
+ ;
+ else
+ return 0;
+
+ p = hash_get_mem (pm->policer_index_by_name, match_name);
+
+ if (p == 0)
+ return 0;
+
+ *r = p[0];
+
+ return 1;
+}
+
+static uword
+unformat_policer_classify_precolor (unformat_input_t * input, va_list * va)
+{
+ u32 * r = va_arg (*va, u32 *);
+
+ if (unformat (input, "conform-color"))
+ *r = POLICE_CONFORM;
+ else if (unformat (input, "exceed-color"))
+ *r = POLICE_EXCEED;
+ else
+ return 0;
+
+ return 1;
+}
#define foreach_config_param \
_(eb) \
_(cir) \
_(rate_type) \
_(round_type) \
-_(type)
+_(type) \
+_(action)
static clib_error_t *
configure_policer_command_fn (vlib_main_t * vm,
unformat_input_t * input,
vlib_cli_command_t * cmd)
{
- vnet_policer_main_t *pm = &vnet_policer_main;
sse2_qos_pol_cfg_params_st c;
- policer_read_response_type_st test_policer;
unformat_input_t _line_input, * line_input = &_line_input;
- int is_add = 1;
- int rv;
+ u8 is_add = 1;
u8 * name = 0;
- uword * p;
+ u32 pi;
/* Get a line of input. */
if (! unformat_user (input, unformat_line_input, line_input))
is_add = 0;
else if (unformat(line_input, "name %s", &name))
;
+ else if (unformat(line_input, "color-aware"))
+ c.color_aware = 1;
#define _(a) else if (unformat (line_input, "%U", unformat_policer_##a, &c)) ;
foreach_config_param
unformat_free (line_input);
- if (is_add == 0)
- {
- p = hash_get_mem (pm->policer_config_by_name, name);
- if (p == 0)
- {
- vec_free(name);
- return clib_error_return (0, "No such policer configuration");
- }
- hash_unset_mem (pm->policer_config_by_name, name);
- vec_free(name);
- return 0;
- }
-
- /* Vet the configuration before adding it to the table */
- rv = sse2_pol_logical_2_physical (&c, &test_policer);
-
- if (rv == 0)
- {
- policer_read_response_type_st *pp;
- sse2_qos_pol_cfg_params_st *cp;
-
- pool_get (pm->configs, cp);
- pool_get (pm->policer_templates, pp);
-
- ASSERT (cp - pm->configs == pp - pm->policer_templates);
-
- memcpy (cp, &c, sizeof (*cp));
- memcpy (pp, &test_policer, sizeof (*pp));
-
- hash_set_mem (pm->policer_config_by_name, name, cp - pm->configs);
- }
- else
- {
- vec_free (name);
- return clib_error_return (0, "Config failed sanity check");
- }
-
- return 0;
+ return policer_add_del(vm, name, &c, &pi, is_add);
}
VLIB_CLI_COMMAND (configure_policer_command, static) = {
pm->vnet_main = vnet_get_main();
pm->policer_config_by_name = hash_create_string (0, sizeof (uword));
+ pm->policer_index_by_name = hash_create_string (0, sizeof (uword));
+
+ vnet_classify_register_unformat_policer_next_index_fn
+ (unformat_policer_classify_next_index);
+ vnet_classify_register_unformat_opaque_index_fn
+ (unformat_policer_classify_precolor);
+
return 0;
}