policer action
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 <matfabia@cisco.com>
This commit is contained in:

committed by
Damjan Marion

parent
41da02d96b
commit
4ac74c9599
@ -18,6 +18,12 @@
|
||||
#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++;
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
Reference in New Issue
Block a user