policer action 27/1327/6
authorMatus Fabian <[email protected]>
Tue, 31 May 2016 14:33:29 +0000 (07:33 -0700)
committerDamjan Marion <[email protected]>
Tue, 12 Jul 2016 15:12:58 +0000 (15:12 +0000)
JIRA: VPP-90

Policer allows you to specify the action to be taken on a packet:
    conform-action (green color)
    exceed-action (yellow color)
    violate-action (red color)
Action to take on packets:
    drop - drops the packet
    transmit - transmits the packet, the packet is not altered
    mark-and-transmit <DSCP> - sets the DSCP value and transmits the packet

Change-Id: I59c037e55e7e2a9fc9b9752e92426f3977f5587b
Signed-off-by: Matus Fabian <[email protected]>
vnet/vnet/policer/node_funcs.c
vnet/vnet/policer/police.h
vnet/vnet/policer/policer.c
vnet/vnet/policer/policer.h
vnet/vnet/policer/xlate.c
vnet/vnet/policer/xlate.h
vpp-api-test/vat/api_format.c
vpp/vpp-api/api.c
vpp/vpp-api/vpe.api

index 739ce45..6147ea5 100644 (file)
 #include <vlib/vlib.h>
 #include <vnet/vnet.h>
 #include <vnet/policer/policer.h>
+#include <vnet/ip/ip.h>
+
+#define IP4_NON_DSCP_BITS 0x03
+#define IP4_DSCP_SHIFT    2
+#define IP6_NON_DSCP_BITS 0xf03fffff
+#define IP6_DSCP_SHIFT    22
 
 /* Dispatch functions meant to be instantiated elsewhere */
 
@@ -56,6 +62,37 @@ static char * vnet_policer_error_strings[] = {
 #undef _
 };
 
+static_always_inline
+void vnet_policer_mark (vlib_buffer_t * b, u8 dscp)
+{
+  ethernet_header_t * eh;
+  ip4_header_t * ip4h;
+  ip6_header_t * ip6h;
+  u16 type;
+
+  eh = (ethernet_header_t *) b->data;
+  type = clib_net_to_host_u16 (eh->type);
+
+  if (PREDICT_TRUE(type == ETHERNET_TYPE_IP4))
+    {
+      ip4h = (ip4_header_t *) &(b->data[sizeof(ethernet_header_t)]);;
+      ip4h->tos &= IP4_NON_DSCP_BITS;
+      ip4h->tos |= dscp << IP4_DSCP_SHIFT;
+      ip4h->checksum = ip4_header_checksum (ip4h);
+    }
+  else
+    {
+      if (PREDICT_TRUE(type == ETHERNET_TYPE_IP6))
+        {
+          ip6h = (ip6_header_t *) &(b->data[sizeof(ethernet_header_t)]);
+          ip6h->ip_version_traffic_class_and_flow_label &=
+            clib_host_to_net_u32(IP6_NON_DSCP_BITS);
+          ip6h->ip_version_traffic_class_and_flow_label |=
+            clib_host_to_net_u32(dscp << IP6_DSCP_SHIFT);
+        }
+    }
+}
+
 static inline
 uword vnet_policer_inline (vlib_main_t * vm,
                            vlib_node_runtime_t * node,
@@ -92,6 +129,7 @@ uword vnet_policer_inline (vlib_main_t * vm,
           u32 len0, len1;
           u32 col0, col1;
           policer_read_response_type_st * pol0, * pol1;
+          u8 act0, act1;
           
          /* Prefetch next iteration. */
          {
@@ -149,28 +187,38 @@ uword vnet_policer_inline (vlib_main_t * vm,
           col0 = vnet_police_packet (pol0, len0, 
                                      POLICE_CONFORM /* no chaining */,
                                      time_in_policer_periods);
+          act0 = pol0->action[col0];
 
           len1 = vlib_buffer_length_in_chain (vm, b1);
           pol1 = &pm->policers [pi1];
           col1 = vnet_police_packet (pol1, len1, 
                                      POLICE_CONFORM /* no chaining */,
                                      time_in_policer_periods);
-          
-          if (PREDICT_FALSE(col0 > 0))
+          act1 = pol1->action[col1];
+
+          if (PREDICT_FALSE(act0 == SSE2_QOS_ACTION_DROP)) /* drop action */
             {
               next0 = VNET_POLICER_NEXT_DROP;
               b0->error = node->errors[VNET_POLICER_ERROR_DROP];
             }
-          else
-            transmitted++;
-          
-          if (PREDICT_FALSE(col1 > 0))
+          else /* transmit or mark-and-transmit action */
+            {
+              if (PREDICT_TRUE(act0 == SSE2_QOS_ACTION_MARK_AND_TRANSMIT))
+                vnet_policer_mark(b0, pol0->mark_dscp[col0]);
+              transmitted++;
+            }
+
+          if (PREDICT_FALSE(act1 == SSE2_QOS_ACTION_DROP)) /* drop action */
             {
               next1 = VNET_POLICER_NEXT_DROP;
               b1->error = node->errors[VNET_POLICER_ERROR_DROP];
             }
-          else
-            transmitted++;
+          else /* transmit or mark-and-transmit action */
+            {
+              if (PREDICT_TRUE(act1 == SSE2_QOS_ACTION_MARK_AND_TRANSMIT))
+                vnet_policer_mark(b1, pol1->mark_dscp[col1]);
+              transmitted++;
+            }
 
 
           if (PREDICT_FALSE((node->flags & VLIB_NODE_FLAG_TRACE)))
@@ -207,6 +255,7 @@ uword vnet_policer_inline (vlib_main_t * vm,
           u32 len0;
           u32 col0;
           policer_read_response_type_st * pol0;
+          u8 act0;
 
          bi0 = from[0];
          to_next[0] = bi0;
@@ -238,14 +287,17 @@ uword vnet_policer_inline (vlib_main_t * vm,
           col0 = vnet_police_packet (pol0, len0, 
                                      POLICE_CONFORM /* no chaining */,
                                      time_in_policer_periods);
+          act0 = pol0->action[col0];
           
-          if (PREDICT_FALSE(col0 > 0))
+          if (PREDICT_FALSE(act0 == SSE2_QOS_ACTION_DROP)) /* drop action */
             {
               next0 = VNET_POLICER_NEXT_DROP;
               b0->error = node->errors[VNET_POLICER_ERROR_DROP];
             }
-          else
+          else /* transmit or mark-and-transmit action */
             {
+              if (PREDICT_TRUE(act0 == SSE2_QOS_ACTION_MARK_AND_TRANSMIT))
+                vnet_policer_mark(b0, pol0->mark_dscp[col0]);
               transmitted++;
             }
           
index d2e369c..89f5ffe 100644 (file)
@@ -63,7 +63,9 @@ typedef struct {
     uint32_t single_rate;    // 1 = single rate policer, 0 = two rate policer
     uint32_t color_aware;    // for hierarchical policing
     uint32_t scale;          // power-of-2 shift amount for lower rates
-    uint32_t pad[2];
+    uint8_t action[3];
+    uint8_t mark_dscp[3];
+    uint8_t pad[2];
 
     // Fields are marked as 2R if they are only used for a 2-rate policer,
     // and MOD if they are modified as part of the update operation.
index 9e98de1..8ffa967 100644 (file)
@@ -140,6 +140,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 
@@ -154,6 +186,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;
 }
 
@@ -263,6 +299,54 @@ 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;
+}
 
 #define foreach_config_param                    \
 _(eb)                                           \
@@ -271,7 +355,8 @@ _(eir)                                          \
 _(cir)                                          \
 _(rate_type)                                    \
 _(round_type)                                   \
-_(type)
+_(type)                                         \
+_(action)
 
 static clib_error_t *
 configure_policer_command_fn (vlib_main_t * vm,
index 02c2d22..fba866f 100644 (file)
@@ -48,13 +48,41 @@ typedef enum {
   VNET_POLICER_INDEX_BY_EITHER,
 } vnet_policer_index_t;
 
-typedef 
-enum {
+typedef enum {
   VNET_POLICER_NEXT_TRANSMIT,
   VNET_POLICER_NEXT_DROP,
   VNET_POLICER_N_NEXT,
 } vnet_policer_next_t;
 
+#define foreach_vnet_dscp \
+  _(0 , CS0,  "CS0")  \
+  _(8 , CS1,  "CS1")  \
+  _(10, AF11, "AF11") \
+  _(12, AF12, "AF12") \
+  _(14, AF13, "AF13") \
+  _(16, CS2,  "CS2")  \
+  _(18, AF21, "AF21") \
+  _(20, AF22, "AF22") \
+  _(22, AF23, "AF23") \
+  _(24, CS3,  "CS3")  \
+  _(26, AF31, "AF31") \
+  _(28, AF32, "AF32") \
+  _(30, AF33, "AF33") \
+  _(32, CS4,  "CS4")  \
+  _(34, AF41, "AF41") \
+  _(36, AF42, "AF42") \
+  _(38, AF43, "AF43") \
+  _(40, CS5,  "CS5")  \
+  _(46, EF,   "EF")   \
+  _(48, CS6,  "CS6")  \
+  _(50, CS7,  "CS7")
+
+typedef enum {
+#define _(v,f,str) VNET_DSCP_##f = v,
+  foreach_vnet_dscp
+#undef _
+} vnet_dscp_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,
index d1eab30..f47982e 100644 (file)
@@ -1129,6 +1129,13 @@ sse2_pol_logical_2_physical (sse2_qos_pol_cfg_params_st    *cfg,
     kbps_cfg.rnd_type  = cfg->rnd_type;
     kbps_cfg.rfc       = cfg->rfc;
 
+    phys->action[POLICE_CONFORM]    = cfg->conform_action.action_type;
+    phys->mark_dscp[POLICE_CONFORM] = cfg->conform_action.dscp;
+    phys->action[POLICE_EXCEED]     = cfg->exceed_action.action_type;
+    phys->mark_dscp[POLICE_EXCEED]  = cfg->exceed_action.dscp;
+    phys->action[POLICE_VIOLATE]    = cfg->violate_action.action_type;
+    phys->mark_dscp[POLICE_VIOLATE] = cfg->violate_action.dscp;
+
 #if !defined (INTERNAL_SS) && !defined (X86)
     // convert logical into hw params which involves qos calculations
     rc = sse2_pol_compute_hw_params(&kbps_cfg, &pol_hw);
index b41666c..d3fdede 100644 (file)
@@ -63,6 +63,30 @@ typedef enum {
     SSE2_QOS_RATE_INVALID
 } sse2_qos_rate_type_en;
 
+/*
+ * edt: * enum
+ * Defines type of policer actions.
+ */
+typedef enum {
+    SSE2_QOS_ACTION_DROP = 0,
+    SSE2_QOS_ACTION_TRANSMIT,
+    SSE2_QOS_ACTION_MARK_AND_TRANSMIT
+} sse2_qos_action_type_en;
+
+/*
+ * edt * struct sse2_qos_pol_action_params_st
+ * This structure is used to hold user configured police action parameters.
+ *
+ * element: action_type
+ *      Action type (see sse2_qos_action_type_en).
+ * elemtnt: dscp
+ *      DSCP value to set when action is SSE2_QOS_ACTION_MARK_AND_TRANSMIT.
+ */
+typedef struct sse2_qos_pol_action_params_st_ {
+    uint8_t  action_type;
+    uint8_t  dscp;
+} sse2_qos_pol_action_params_st;
+
 /* 
  * edt: * struct sse2_qos_pol_cfg_params_st
  *
@@ -115,6 +139,9 @@ typedef struct sse2_qos_pol_cfg_params_st_ {
     uint8_t  overwrite_bucket; /* for debugging purposes */
     uint32_t current_bucket;   /* for debugging purposes */
     uint32_t extended_bucket;  /* for debugging purposes */
+    sse2_qos_pol_action_params_st conform_action;
+    sse2_qos_pol_action_params_st exceed_action;
+    sse2_qos_pol_action_params_st violate_action;
 } sse2_qos_pol_cfg_params_st;
 
 
index 9f7a986..b540f72 100644 (file)
@@ -45,6 +45,7 @@
 #include <vnet/cop/cop.h>
 #include <vnet/ip/ip6_hop_by_hop.h>
 #include <vnet/policer/xlate.h>
+#include <vnet/policer/policer.h>
 
 #include "vat/json_format.h"
 
@@ -416,6 +417,37 @@ unformat_policer_type (unformat_input_t * input, va_list * args)
   return 1;
 }
 
+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;
+}
+
+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;
+}
+
 u8 * format_ip4_address (u8 * s, va_list * args)
 {
   u8 * a = va_arg (*args, u8 *);
@@ -2315,15 +2347,63 @@ static u8 * format_policer_round_type (u8 * s, va_list * va)
   return s;
 }
 
+static u8 * format_policer_action_type (u8 * s, va_list * va)
+{
+    u32 i = va_arg (*va, u32);
+
+    if (i == SSE2_QOS_ACTION_DROP)
+        s = format (s, "drop");
+    else if (i == SSE2_QOS_ACTION_TRANSMIT)
+        s = format (s, "transmit");
+    else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
+        s = format (s, "mark-and-transmit");
+    else
+        s = format (s, "ILLEGAL");
+    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 void vl_api_policer_details_t_handler
 (vl_api_policer_details_t * mp)
 {
     vat_main_t * vam = &vat_main;
+    u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
+
+    if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
+        conform_dscp_str = format(0, "%U", format_dscp, mp->conform_dscp);
+    else
+        conform_dscp_str = format(0, "");
+
+    if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
+        exceed_dscp_str = format(0, "%U", format_dscp, mp->exceed_dscp);
+    else
+        exceed_dscp_str = format(0, "");
+
+    if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
+        violate_dscp_str = format(0, "%U", format_dscp, mp->violate_dscp);
+    else
+        violate_dscp_str = format(0, "");
 
     fformat (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
              "rate type %U, round type %U, %s rate, %s color-aware, "
              "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
-             "cur bkt %u, ext lim %u, ext bkt %u, last update %llu\n",
+             "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
+             "conform action %U%s, exceed action %U%s, violate action %U%s\n",
              mp->name,
              format_policer_type, mp->type,
              ntohl(mp->cir),
@@ -2341,7 +2421,17 @@ static void vl_api_policer_details_t_handler
              ntohl(mp->current_bucket),
              ntohl(mp->extended_limit),
              ntohl(mp->extended_bucket),
-             clib_net_to_host_u64(mp->last_update_time));
+             clib_net_to_host_u64(mp->last_update_time),
+             format_policer_action_type, mp->conform_action_type,
+             conform_dscp_str,
+             format_policer_action_type, mp->exceed_action_type,
+             exceed_dscp_str,
+             format_policer_action_type, mp->violate_action_type,
+             violate_dscp_str);
+
+    vec_free(conform_dscp_str);
+    vec_free(exceed_dscp_str);
+    vec_free(violate_dscp_str);
 }
 
 static void vl_api_policer_details_t_handler_json
@@ -2350,10 +2440,17 @@ static void vl_api_policer_details_t_handler_json
     vat_main_t * vam = &vat_main;
     vat_json_node_t *node;
     u8 *rate_type_str, *round_type_str, *type_str;
+    u8 *conform_action_str, *exceed_action_str, *violate_action_str;
 
     rate_type_str = format(0, "%U", format_policer_rate_type, mp->rate_type);
     round_type_str = format(0, "%U", format_policer_round_type, mp->round_type);
     type_str = format(0, "%U", format_policer_type, mp->type);
+    conform_action_str = format(0, "%U", format_policer_action_type,
+                                mp->conform_action_type);
+    exceed_action_str = format(0, "%U", format_policer_action_type,
+                                mp->exceed_action_type);
+    violate_action_str = format(0, "%U", format_policer_action_type,
+                                mp->violate_action_type);
 
     if (VAT_JSON_ARRAY != vam->json_tree.type) {
         ASSERT(VAT_JSON_NONE == vam->json_tree.type);
@@ -2384,10 +2481,31 @@ static void vl_api_policer_details_t_handler_json
                              ntohl(mp->extended_bucket));
     vat_json_object_add_uint(node, "last_update_time",
                              ntohl(mp->last_update_time));
+    vat_json_object_add_string_copy(node, "conform_action", conform_action_str);
+    if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT) {
+        u8 *dscp_str = format(0, "%U", format_dscp, mp->conform_dscp);
+        vat_json_object_add_string_copy(node, "conform_dscp", dscp_str);
+        vec_free(dscp_str);
+    }
+    vat_json_object_add_string_copy(node, "exceed_action", exceed_action_str);
+    if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT) {
+        u8 *dscp_str = format(0, "%U", format_dscp, mp->exceed_dscp);
+        vat_json_object_add_string_copy(node, "exceed_dscp", dscp_str);
+        vec_free(dscp_str);
+    }
+    vat_json_object_add_string_copy(node, "violate_action", violate_action_str);
+    if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT) {
+        u8 *dscp_str = format(0, "%U", format_dscp, mp->violate_dscp);
+        vat_json_object_add_string_copy(node, "violate_dscp", dscp_str);
+        vec_free(dscp_str);
+    }
 
     vec_free(rate_type_str);
     vec_free(round_type_str);
     vec_free(type_str);
+    vec_free(conform_action_str);
+    vec_free(exceed_action_str);
+    vec_free(violate_action_str);
 }
 
 static void vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t * mp)
@@ -11353,6 +11471,7 @@ api_policer_add_del (vat_main_t * vam)
     u8 rate_type = 0;
     u8 round_type = 0;
     u8 type = 0;
+    sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
 
     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
         if (unformat (i, "del"))
@@ -11375,6 +11494,15 @@ api_policer_add_del (vat_main_t * vam)
             ;
         else if (unformat (i, "type %U", unformat_policer_type, &type))
             ;
+        else if (unformat (i, "conform_action %U", unformat_policer_action_type,
+                           &conform_action))
+            ;
+        else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
+                           &exceed_action))
+            ;
+        else if (unformat (i, "violate_action %U", unformat_policer_action_type,
+                           &violate_action))
+            ;
         else
           break;
     }
@@ -11401,6 +11529,12 @@ api_policer_add_del (vat_main_t * vam)
     mp->rate_type = rate_type;
     mp->round_type = round_type;
     mp->type = type;
+    mp->conform_action_type = conform_action.action_type;
+    mp->conform_dscp = conform_action.dscp;
+    mp->exceed_action_type = exceed_action.action_type;
+    mp->exceed_dscp = exceed_action.dscp;
+    mp->violate_action_type = violate_action.action_type;
+    mp->violate_dscp = violate_action.dscp;
 
     S; W;
     /* NOTREACHED */
index 4d4c71c..9acda74 100644 (file)
@@ -6328,6 +6328,12 @@ vl_api_policer_add_del_t_handler
     cfg.rb.kbps.eir_kbps = mp->eir;
     cfg.rb.kbps.cb_bytes = mp->cb;
     cfg.rb.kbps.eb_bytes = mp->eb;
+    cfg.conform_action.action_type = mp->conform_action_type;
+    cfg.conform_action.dscp = mp->conform_dscp;
+    cfg.exceed_action.action_type = mp->exceed_action_type;
+    cfg.exceed_action.dscp = mp->exceed_dscp;
+    cfg.violate_action.action_type = mp->violate_action_type;
+    cfg.violate_action.dscp = mp->violate_dscp;
 
     error = policer_add_del(vm, name, &cfg, mp->is_add);
 
@@ -6357,6 +6363,12 @@ send_policer_details (u8 *name,
     mp->rate_type = config->rate_type;
     mp->round_type = config->rnd_type;
     mp->type = config->rfc;
+    mp->conform_action_type = config->conform_action.action_type;
+    mp->conform_dscp = config->conform_action.dscp;
+    mp->exceed_action_type = config->exceed_action.action_type;
+    mp->exceed_dscp = config->exceed_action.dscp;
+    mp->violate_action_type = config->violate_action.action_type;
+    mp->violate_dscp = config->violate_action.dscp;
     mp->single_rate = templ->single_rate ? 1 : 0;
     mp->color_aware = templ->color_aware ? 1 : 0;
     mp->scale = htonl(templ->scale);
index 63ca847..ffc2575 100644 (file)
@@ -3619,6 +3619,12 @@ define af_packet_delete_reply {
     @param rate_type - rate type
     @param round_type - rounding type
     @param type - policer algorithm
+    @param conform_action_type - conform action type
+    @param conform_dscp - DSCP for conform mar-and-transmit action
+    @param exceed_action_type - exceed action type
+    @param exceed_dscp - DSCP for exceed mar-and-transmit action
+    @param violate_action_type - violate action type
+    @param violate_dscp - DSCP for violate mar-and-transmit action
 */
 define policer_add_del {
     u32 client_index;
@@ -3633,6 +3639,12 @@ define policer_add_del {
     u8 rate_type;
     u8 round_type;
     u8 type;
+    u8 conform_action_type;
+    u8 conform_dscp;
+    u8 exceed_action_type;
+    u8 exceed_dscp;
+    u8 violate_action_type;
+    u8 violate_dscp;
 };
 
 /** \brief Add/del policer response
@@ -3668,6 +3680,12 @@ define policer_dump {
     @param rate_type - rate type
     @param round_type - rounding type
     @param type - policer algorithm
+    @param conform_action_type - conform action type
+    @param conform_dscp - DSCP for conform mar-and-transmit action
+    @param exceed_action_type - exceed action type
+    @param exceed_dscp - DSCP for exceed mar-and-transmit action
+    @param violate_action_type - violate action type
+    @param violate_dscp - DSCP for violate mar-and-transmit action
     @param single_rate - 1 = single rate policer, 0 = two rate policer
     @param color_aware - for hierarchical policing
     @param scale - power-of-2 shift amount for lower rates
@@ -3690,6 +3708,12 @@ manual_java define policer_details {
     u8 rate_type;
     u8 round_type;
     u8 type;
+    u8 conform_action_type;
+    u8 conform_dscp;
+    u8 exceed_action_type;
+    u8 exceed_dscp;
+    u8 violate_action_type;
+    u8 violate_dscp;
     u8 single_rate;
     u8 color_aware;
     u32 scale;