From 4ac74c9599c73510900c18ff4c86ca390993adac Mon Sep 17 00:00:00 2001 From: Matus Fabian Date: Tue, 31 May 2016 07:33:29 -0700 Subject: 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 - sets the DSCP value and transmits the packet Change-Id: I59c037e55e7e2a9fc9b9752e92426f3977f5587b Signed-off-by: Matus Fabian --- vnet/vnet/policer/node_funcs.c | 72 ++++++++++++++++++--- vnet/vnet/policer/police.h | 4 +- vnet/vnet/policer/policer.c | 87 +++++++++++++++++++++++++- vnet/vnet/policer/policer.h | 32 +++++++++- vnet/vnet/policer/xlate.c | 7 +++ vnet/vnet/policer/xlate.h | 27 ++++++++ vpp-api-test/vat/api_format.c | 138 ++++++++++++++++++++++++++++++++++++++++- vpp/vpp-api/api.c | 12 ++++ vpp/vpp-api/vpe.api | 24 +++++++ 9 files changed, 387 insertions(+), 16 deletions(-) diff --git a/vnet/vnet/policer/node_funcs.c b/vnet/vnet/policer/node_funcs.c index 739ce4551b6..6147ea51c1a 100644 --- a/vnet/vnet/policer/node_funcs.c +++ b/vnet/vnet/policer/node_funcs.c @@ -18,6 +18,12 @@ #include #include #include +#include + +#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++; } diff --git a/vnet/vnet/policer/police.h b/vnet/vnet/policer/police.h index d2e369c655f..89f5ffee2ad 100644 --- a/vnet/vnet/policer/police.h +++ b/vnet/vnet/policer/police.h @@ -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. diff --git a/vnet/vnet/policer/policer.c b/vnet/vnet/policer/policer.c index 9e98de17cc8..8ffa967bd48 100644 --- a/vnet/vnet/policer/policer.c +++ b/vnet/vnet/policer/policer.c @@ -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, diff --git a/vnet/vnet/policer/policer.h b/vnet/vnet/policer/policer.h index 02c2d228edd..fba866f4773 100644 --- a/vnet/vnet/policer/policer.h +++ b/vnet/vnet/policer/policer.h @@ -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, diff --git a/vnet/vnet/policer/xlate.c b/vnet/vnet/policer/xlate.c index d1eab304d39..f47982e31ee 100644 --- a/vnet/vnet/policer/xlate.c +++ b/vnet/vnet/policer/xlate.c @@ -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); diff --git a/vnet/vnet/policer/xlate.h b/vnet/vnet/policer/xlate.h index b41666c897e..d3fdeded55f 100644 --- a/vnet/vnet/policer/xlate.h +++ b/vnet/vnet/policer/xlate.h @@ -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; diff --git a/vpp-api-test/vat/api_format.c b/vpp-api-test/vat/api_format.c index 9f7a986118e..b540f72c8c6 100644 --- a/vpp-api-test/vat/api_format.c +++ b/vpp-api-test/vat/api_format.c @@ -45,6 +45,7 @@ #include #include #include +#include #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 */ diff --git a/vpp/vpp-api/api.c b/vpp/vpp-api/api.c index 4d4c71c621c..9acda74547b 100644 --- a/vpp/vpp-api/api.c +++ b/vpp/vpp-api/api.c @@ -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); diff --git a/vpp/vpp-api/vpe.api b/vpp/vpp-api/vpe.api index 63ca8477646..ffc2575223f 100644 --- a/vpp/vpp-api/vpe.api +++ b/vpp/vpp-api/vpe.api @@ -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; -- cgit 1.2.3-korg