Add configure policer API 99/1099/3
authorMatus Fabian <[email protected]>
Fri, 13 May 2016 12:44:48 +0000 (05:44 -0700)
committerDave Barach <[email protected]>
Mon, 16 May 2016 13:30:40 +0000 (13:30 +0000)
JIRA: VPP-67

Change-Id: I04560d78e2eb131cd6cc31472b70b3d3e8fdd79a
Signed-off-by: Matus Fabian <[email protected]>
vnet/Makefile.am
vnet/vnet/policer/policer.c
vnet/vnet/policer/policer.h
vpp-api-test/vat/api_format.c
vpp/api/api.c
vpp/api/vpe.api

index 8a9f214..dddcdbf 100644 (file)
@@ -58,6 +58,8 @@ libvnet_la_SOURCES +=                         \
 
 nobase_include_HEADERS +=                      \
   vnet/policer/police.h                                \
+  vnet/policer/policer.h                       \
+  vnet/policer/fix_types.h                     \
   vnet/policer/xlate.h
 
 ########################################
index 2dbd02b..9e98de1 100644 (file)
 #include <stdint.h>
 #include <vnet/policer/policer.h>
 
+clib_error_t *
+policer_add_del (vlib_main_t *vm,
+                 u8 * name, sse2_qos_pol_cfg_params_st * cfg,
+                 u8 is_add)
+{
+  vnet_policer_main_t *pm = &vnet_policer_main;
+  policer_read_response_type_st test_policer;
+  uword * p;
+  int rv;
+
+  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 (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);
+    }
+  else
+    {
+      vec_free (name);
+      return clib_error_return (0, "Config failed sanity check");
+    }
+
+  return 0;
+}
+
 u8 * format_policer_instance (u8 * s, va_list * va)
 {
   policer_read_response_type_st * i 
@@ -228,14 +278,10 @@ 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;
 
   /* Get a line of input. */
   if (! unformat_user (input, unformat_line_input, line_input))
@@ -261,44 +307,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);
-
-      clib_memcpy (cp, &c, sizeof (*cp));
-      clib_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, is_add);
 }
 
 VLIB_CLI_COMMAND (configure_policer_command, static) = {
index f91521e..02c2d22 100644 (file)
@@ -56,5 +56,8 @@ enum {
 } vnet_policer_next_t;
 
 u8 * format_policer_instance (u8 * s, va_list * va);
+clib_error_t * policer_add_del (vlib_main_t *vm,
+                                u8 * name, sse2_qos_pol_cfg_params_st * cfg,
+                                u8 is_add);
 
 #endif /* __included_policer_h__ */
index bf1a393..4776e2a 100644 (file)
@@ -43,6 +43,7 @@
 #include <vnet/map/map.h>
 #include <vnet/cop/cop.h>
 #include <vnet/ip/ip6_hop_by_hop.h>
+#include <vnet/policer/xlate.h>
 
 #include "vat/json_format.h"
 
@@ -364,6 +365,56 @@ unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
 #endif
 }
 
+uword
+unformat_policer_rate_type (unformat_input_t * input, va_list * args)
+{
+  u8 * r = va_arg (*args, u8 *);
+
+  if (unformat (input, "kbps"))
+    *r = SSE2_QOS_RATE_KBPS;
+  else if (unformat(input, "pps"))
+    *r = SSE2_QOS_RATE_PPS;
+  else
+    return 0;
+  return 1;
+}
+
+uword
+unformat_policer_round_type (unformat_input_t * input, va_list * args)
+{
+  u8 * r = va_arg (*args, u8 *);
+
+  if (unformat(input, "closest"))
+    *r = SSE2_QOS_ROUND_TO_CLOSEST;
+  else if (unformat (input, "up"))
+    *r = SSE2_QOS_ROUND_TO_UP;
+  else if (unformat (input, "down"))
+    *r = SSE2_QOS_ROUND_TO_DOWN;
+  else
+    return 0;
+  return 1;
+}
+
+uword
+unformat_policer_type (unformat_input_t * input, va_list * args)
+{
+  u8 * r = va_arg (*args, u8 *);
+
+  if (unformat (input, "1r2c"))
+    *r = SSE2_QOS_POLICER_TYPE_1R2C;
+  else if (unformat (input, "1r3c"))
+    *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
+  else if (unformat (input, "2r3c-2698"))
+    *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
+  else if (unformat (input, "2r3c-4115"))
+    *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
+  else if (unformat (input, "2r3c-mef5cf1"))
+    *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
+  else
+    return 0;
+  return 1;
+}
+
 u8 * format_ip4_address (u8 * s, va_list * args)
 {
   u8 * a = va_arg (*args, u8 *);
@@ -2179,7 +2230,8 @@ _(lisp_gpe_add_del_iface_reply)                         \
 _(lisp_enable_disable_reply)                            \
 _(vxlan_gpe_add_del_tunnel_reply)                      \
 _(af_packet_create_reply)                               \
-_(af_packet_delete_reply)
+_(af_packet_delete_reply)                               \
+_(policer_add_del_reply)
 
 #define _(n)                                    \
     static void vl_api_##n##_t_handler          \
@@ -2359,7 +2411,8 @@ _(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details)                 \
 _(LISP_ENABLE_DISABLE_STATUS_DETAILS,                                   \
   lisp_enable_disable_status_details)                                   \
 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
-_(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)
+_(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
+_(POLICER_ADD_DEL_REPLY, policer_add_del_reply)
 
 /* M: construct, but don't yet send a message */
 
@@ -10206,6 +10259,75 @@ api_af_packet_delete (vat_main_t * vam)
     return 0;
 }
 
+static int
+api_policer_add_del (vat_main_t * vam)
+{
+    unformat_input_t * i = vam->input;
+    vl_api_policer_add_del_t * mp;
+    f64 timeout;
+    u8 is_add = 1;
+    u8 * name = 0;
+    u32 cir = 0;
+    u32 eir = 0;
+    u64 cb = 0;
+    u64 eb = 0;
+    u8 rate_type = 0;
+    u8 round_type = 0;
+    u8 type = 0;
+
+    while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
+        if (unformat (i, "del"))
+            is_add = 0;
+        else if (unformat (i, "name %s", &name))
+            vec_add1 (name, 0);
+        else if (unformat (i, "cir %u", &cir))
+            ;
+        else if (unformat (i, "eir %u", &eir))
+            ;
+        else if (unformat (i, "cb %u", &cb))
+            ;
+        else if (unformat (i, "eb %u", &eb))
+            ;
+        else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
+                           &rate_type))
+            ;
+        else if (unformat (i, "round_type %U", unformat_policer_round_type,
+                           &round_type))
+            ;
+        else if (unformat (i, "type %U", unformat_policer_type, &type))
+            ;
+        else
+          break;
+    }
+
+    if (!vec_len (name)) {
+        errmsg ("policer name must be specified");
+        return -99;
+    }
+
+    if (vec_len (name) > 64) {
+        errmsg ("policer name too long");
+        return -99;
+    }
+
+    M(POLICER_ADD_DEL, policer_add_del);
+
+    clib_memcpy (mp->name, name, vec_len (name));
+    vec_free (name);
+    mp->is_add = is_add;
+    mp->cir = cir;
+    mp->eir = eir;
+    mp->cb = cb;
+    mp->eb = eb;
+    mp->rate_type = rate_type;
+    mp->round_type = round_type;
+    mp->type = type;
+
+    S; W;
+    /* NOTREACHED */
+    return 0;
+}
+
 static int q_or_quit (vat_main_t * vam)
 {
     longjmp (vam->jump_buf, 1);
@@ -10691,7 +10813,8 @@ _(lisp_gpe_tunnel_dump, "")                                             \
 _(lisp_map_resolver_dump, "")                                           \
 _(lisp_enable_disable_status_dump, "")                                  \
 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
-_(af_packet_delete, "name <host interface name>")
+_(af_packet_delete, "name <host interface name>")                       \
+_(policer_add_del, "name <policer name> <params> [del]")
 
 /* List of command functions, CLI names map directly to functions */
 #define foreach_cli_function                                    \
index 0d5f224..f81b9c9 100644 (file)
@@ -74,6 +74,7 @@
 #include <vnet/cop/cop.h>
 #include <vnet/ip/ip6_hop_by_hop.h>
 #include <vnet/devices/af_packet/af_packet.h>
+#include <vnet/policer/policer.h>
 
 #undef BIHASH_TYPE
 #undef __included_bihash_template_h__
@@ -335,7 +336,8 @@ _(LISP_ENABLE_DISABLE_STATUS_DUMP,                                      \
   lisp_enable_disable_status_dump)                                      \
 _(SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del)                   \
 _(AF_PACKET_CREATE, af_packet_create)                                   \
-_(AF_PACKET_DELETE, af_packet_delete)
+_(AF_PACKET_DELETE, af_packet_delete)                                   \
+_(POLICER_ADD_DEL, policer_add_del)
 
 #define QUOTE_(x) #x
 #define QUOTE(x) QUOTE_(x)
@@ -5932,6 +5934,36 @@ vl_api_af_packet_delete_t_handler
     REPLY_MACRO(VL_API_AF_PACKET_DELETE_REPLY);
 }
 
+static void
+vl_api_policer_add_del_t_handler
+(vl_api_policer_add_del_t *mp)
+{
+    vlib_main_t * vm = vlib_get_main();
+    vl_api_policer_add_del_reply_t *rmp;
+    int rv = 0;
+    u8 *name = NULL;
+    sse2_qos_pol_cfg_params_st cfg;
+    clib_error_t * error;
+
+    name = format(0, "%s", mp->name);
+
+    memset (&cfg, 0, sizeof (cfg));
+    cfg.rfc = mp->type;
+    cfg.rnd_type = mp->round_type;
+    cfg.rate_type = mp->rate_type;
+    cfg.rb.kbps.cir_kbps = mp->cir;
+    cfg.rb.kbps.eir_kbps = mp->eir;
+    cfg.rb.kbps.cb_bytes = mp->cb;
+    cfg.rb.kbps.eb_bytes = mp->eb;
+
+    error = policer_add_del(vm, name, &cfg, mp->is_add);
+
+    if (error)
+      rv = VNET_API_ERROR_UNSPECIFIED;
+
+    REPLY_MACRO(VL_API_POLICER_ADD_DEL_REPLY);
+}
+
 #define BOUNCE_HANDLER(nn)                                              \
 static void vl_api_##nn##_t_handler (                                   \
     vl_api_##nn##_t *mp)                                                \
index df3b2af..a61c260 100644 (file)
@@ -3475,3 +3475,40 @@ define af_packet_delete_reply {
     u32 context;
     i32 retval;
 };
+
+/** \brief Add/del policer
+    @param client_index - opaque cookie to identify the sender
+    @param context - sender context, to match reply w/ request
+    @param is_add - add policer if non-zero, else delete
+    @param name - policer name
+    @param cir - CIR
+    @param eir - EIR
+    @param cb - Committed Burst
+    @param eb - Excess or Peak Burst
+    @param rate_type - rate type
+    @param round_type - rounding type
+    @param type - policer algorithm
+*/
+define policer_add_del {
+    u32 client_index;
+    u32 context;
+
+    u8 is_add;
+    u8 name[64];
+    u32 cir;
+    u32 eir;
+    u64 cb;
+    u64 eb;
+    u8 rate_type;
+    u8 round_type;
+    u8 type;
+};
+
+/** \brief Add/del policer response
+    @param context - sender context, to match reply w/ request
+    @param retval - return value for request
+*/
+define policer_add_del_reply {
+    u32 context;
+    i32 retval;
+};