dpdk: remove support for dpdk 16.04
[vpp.git] / vnet / vnet / policer / policer.c
index 310c5f5..f60f7a7 100644 (file)
  * 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)
 {
@@ -89,6 +158,38 @@ static u8 * format_policer_type (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 
@@ -103,6 +204,10 @@ u8 * format_policer_config (u8 * s, va_list * va)
   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;
 }
 
@@ -212,6 +317,92 @@ unformat_policer_eb (unformat_input_t * input, va_list * va)
   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)                                           \
@@ -220,21 +411,19 @@ _(eir)                                          \
 _(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))
@@ -248,6 +437,8 @@ configure_policer_command_fn (vlib_main_t * vm,
         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
@@ -260,44 +451,7 @@ configure_policer_command_fn (vlib_main_t * vm,
 
   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) = {
@@ -358,6 +512,13 @@ clib_error_t *policer_init (vlib_main_t * vm)
   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;
 }