diff options
author | Matus Fabian <matfabia@cisco.com> | 2016-06-20 08:10:42 -0700 |
---|---|---|
committer | Dave Barach <openvpp@barachs.net> | 2016-07-26 15:52:03 +0000 |
commit | 70e6a8dd52b5c2814737b9a75763ff239a7e053d (patch) | |
tree | 403733620fb32f571da1b9bf5be9ce740a9b1054 /vpp | |
parent | ac0798db359eb0de2eae1a54b63dfaa9534984c8 (diff) |
policer classify
JIRA: VPP-114
If the classifier finds a matching entry, it sends packet to the policer,
packet should be pre-colored for color-aware policers.
Change-Id: I10cb53b49907137769418f230df2cab577d0f3a0
Signed-off-by: Matus Fabian <matfabia@cisco.com>
Diffstat (limited to 'vpp')
-rw-r--r-- | vpp/vpp-api/api.c | 84 | ||||
-rw-r--r-- | vpp/vpp-api/custom_dump.c | 160 | ||||
-rw-r--r-- | vpp/vpp-api/vpe.api | 56 |
3 files changed, 297 insertions, 3 deletions
diff --git a/vpp/vpp-api/api.c b/vpp/vpp-api/api.c index feb1a61a..822b9906 100644 --- a/vpp/vpp-api/api.c +++ b/vpp/vpp-api/api.c @@ -66,6 +66,7 @@ #include <vlibmemory/api.h> #include <vnet/classify/vnet_classify.h> #include <vnet/classify/input_acl.h> +#include <vnet/classify/policer_classify.h> #include <vnet/l2/l2_classify.h> #include <vnet/vxlan/vxlan.h> #include <vnet/gre/gre.h> @@ -353,6 +354,8 @@ _(AF_PACKET_CREATE, af_packet_create) \ _(AF_PACKET_DELETE, af_packet_delete) \ _(POLICER_ADD_DEL, policer_add_del) \ _(POLICER_DUMP, policer_dump) \ +_(POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface) \ +_(POLICER_CLASSIFY_DUMP, policer_classify_dump) \ _(NETMAP_CREATE, netmap_create) \ _(NETMAP_DELETE, netmap_delete) \ _(MPLS_GRE_TUNNEL_DUMP, mpls_gre_tunnel_dump) \ @@ -6435,6 +6438,7 @@ vl_api_policer_add_del_t_handler u8 *name = NULL; sse2_qos_pol_cfg_params_st cfg; clib_error_t * error; + u32 policer_index; name = format(0, "%s", mp->name); @@ -6452,13 +6456,20 @@ vl_api_policer_add_del_t_handler cfg.exceed_action.dscp = mp->exceed_dscp; cfg.violate_action.action_type = mp->violate_action_type; cfg.violate_action.dscp = mp->violate_dscp; + cfg.color_aware = mp->color_aware; - error = policer_add_del(vm, name, &cfg, mp->is_add); + error = policer_add_del(vm, name, &cfg, &policer_index, mp->is_add); if (error) rv = VNET_API_ERROR_UNSPECIFIED; - REPLY_MACRO(VL_API_POLICER_ADD_DEL_REPLY); + REPLY_MACRO2(VL_API_POLICER_ADD_DEL_REPLY, + ({ + if (rv == 0 && mp->is_add) + rmp->policer_index = ntohl(policer_index); + else + rmp->policer_index = ~0; + })); } static void @@ -6546,6 +6557,75 @@ vl_api_policer_dump_t_handler } static void +vl_api_policer_classify_set_interface_t_handler +(vl_api_policer_classify_set_interface_t * mp) +{ + vlib_main_t *vm = vlib_get_main(); + vl_api_policer_classify_set_interface_reply_t * rmp; + int rv; + u32 sw_if_index, ip4_table_index, ip6_table_index, l2_table_index; + + ip4_table_index = ntohl(mp->ip4_table_index); + ip6_table_index = ntohl(mp->ip6_table_index); + l2_table_index = ntohl(mp->l2_table_index); + sw_if_index = ntohl(mp->sw_if_index); + + VALIDATE_SW_IF_INDEX(mp); + + rv = vnet_set_policer_classify_intfc(vm, sw_if_index, ip4_table_index, + ip6_table_index, l2_table_index, + mp->is_add); + + BAD_SW_IF_INDEX_LABEL; + + REPLY_MACRO(VL_API_POLICER_CLASSIFY_SET_INTERFACE_REPLY); +} + +static void +send_policer_classify_details (u32 sw_if_index, + u32 table_index, + unix_shared_memory_queue_t *q, + u32 context) +{ + vl_api_policer_classify_details_t * mp; + + mp = vl_msg_api_alloc (sizeof (*mp)); + memset (mp, 0, sizeof (*mp)); + mp->_vl_msg_id = ntohs (VL_API_POLICER_CLASSIFY_DETAILS); + mp->context = context; + mp->sw_if_index= htonl(sw_if_index); + mp->table_index= htonl(table_index); + + vl_msg_api_send_shmem (q, (u8 *)&mp); +} + +static void +vl_api_policer_classify_dump_t_handler +(vl_api_policer_classify_dump_t *mp) +{ + unix_shared_memory_queue_t * q; + policer_classify_main_t * pcm = &policer_classify_main; + u32 * vec_tbl; + int i; + + q = vl_api_client_index_to_input_queue (mp->client_index); + if (q == 0) + return; + + vec_tbl = pcm->classify_table_index_by_sw_if_index[mp->type]; + + if (vec_len(vec_tbl)) { + for (i = 0; i < vec_len (vec_tbl); i++) { + if (vec_elt(vec_tbl, i) == ~0) + continue; + + send_policer_classify_details(i, vec_elt(vec_tbl, i), q, + mp->context); + } + } +} + +static void vl_api_netmap_create_t_handler (vl_api_netmap_create_t *mp) { diff --git a/vpp/vpp-api/custom_dump.c b/vpp/vpp-api/custom_dump.c index 53eb2c4d..651fdd35 100644 --- a/vpp/vpp-api/custom_dump.c +++ b/vpp/vpp-api/custom_dump.c @@ -27,6 +27,9 @@ #include <vnet/l2/l2_input.h> #include <vnet/sr/sr_packet.h> #include <vnet/vxlan-gpe/vxlan_gpe.h> +#include <vnet/classify/policer_classify.h> +#include <vnet/policer/xlate.h> +#include <vnet/policer/policer.h> #include <vlib/vlib.h> #include <vlib/unix/unix.h> #include <vlibapi/api.h> @@ -1746,6 +1749,157 @@ static void * vl_api_af_packet_delete_t_print FINISH; } +static u8 * format_policer_action (u8 * s, va_list * va) +{ + u32 action = va_arg (*va, u32); + u32 dscp = va_arg (*va, u32); + char * t = 0; + + if (action == SSE2_QOS_ACTION_DROP) + s = format (s, "drop"); + else if (action == SSE2_QOS_ACTION_TRANSMIT) + s = format (s, "transmit"); + else if (action == SSE2_QOS_ACTION_MARK_AND_TRANSMIT) { + s = format (s, "mark-and-transmit "); + switch (dscp) { + #define _(v,f,str) case VNET_DSCP_##f: t = str; break; + foreach_vnet_dscp + #undef _ + default: + break; + } + s = format (s, "%s", t); + } + + return s; +} + +static void * vl_api_policer_add_del_t_print +(vl_api_policer_add_del_t * mp, void *handle) +{ + u8 * s; + + s = format (0, "SCRIPT: policer_add_del "); + s = format (s, "name %s ", mp->name); + s = format (s, "cir %d ", mp->cir); + s = format (s, "eir %d ", mp->eir); + s = format (s, "cb %d ", mp->cb); + s = format (s, "eb %d ", mp->eb); + + switch (mp->rate_type) { + case SSE2_QOS_RATE_KBPS: + s = format (s, "rate_type kbps "); + break; + case SSE2_QOS_RATE_PPS: + s = format (s, "rate_type pps "); + break; + default: + break; + } + + switch (mp->round_type) { + case SSE2_QOS_ROUND_TO_CLOSEST: + s = format (s, "round_type closest "); + break; + case SSE2_QOS_ROUND_TO_UP: + s = format (s, "round_type up "); + break; + case SSE2_QOS_ROUND_TO_DOWN: + s = format (s, "round_type down "); + break; + default: + break; + } + + switch (mp->type) { + case SSE2_QOS_POLICER_TYPE_1R2C: + s = format (s, "type 1r2c "); + break; + case SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697: + s = format (s, "type 1r3c "); + break; + case SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698: + s = format (s, "type 2r3c-2698 "); + break; + case SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115: + s = format (s, "type 2r3c-4115 "); + break; + case SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1: + s = format (s, "type 2r3c-mef5cf1 "); + break; + default: + break; + } + + s = format (s, "conform_action %U ", format_policer_action, + mp->conform_action_type, mp->conform_dscp); + s = format (s, "exceed_action %U ", format_policer_action, + mp->exceed_action_type, mp->exceed_dscp); + s = format (s, "violate_action %U ", format_policer_action, + mp->violate_action_type, mp->violate_dscp); + + if (mp->color_aware) + s = format (s, "color-aware "); + if (mp->is_add == 0) + s = format (s, "del "); + + FINISH; +} + +static void * vl_api_policer_dump_t_print +(vl_api_policer_dump_t * mp, void *handle) +{ + u8 * s; + + s = format (0, "SCRIPT: policer_dump "); + if (mp->match_name_valid) + s = format (s, "name %s ", mp->match_name); + + FINISH; +} + +static void * vl_api_policer_classify_set_interface_t_print +(vl_api_policer_classify_set_interface_t * mp, void *handle) +{ + u8 * s; + + s = format (0, "SCRIPT: policer_classify_set_interface "); + s = format (s, "sw_if_index %d ", ntohl(mp->sw_if_index)); + if (mp->ip4_table_index != ~0) + s = format (s, "ip4-table %d ", ntohl(mp->ip4_table_index)); + if (mp->ip6_table_index != ~0) + s = format (s, "ip6-table %d ", ntohl(mp->ip6_table_index)); + if (mp->l2_table_index != ~0) + s = format (s, "l2-table %d ", ntohl(mp->l2_table_index)); + if (mp->is_add == 0) + s = format (s, "del "); + + FINISH; +} + +static void * vl_api_policer_classify_dump_t_print +(vl_api_policer_classify_dump_t * mp, void *handle) +{ + u8 * s; + + s = format (0, "SCRIPT: policer_classify_dump "); + switch (mp->type) { + case POLICER_CLASSIFY_TABLE_IP4: + s = format (s, "type ip4 "); + break; + case POLICER_CLASSIFY_TABLE_IP6: + s = format (s, "type ip6 "); + break; + case POLICER_CLASSIFY_TABLE_L2: + s = format (s, "type l2 "); + break; + default: + break; + } + + FINISH; +} + static void *vl_api_sw_interface_clear_stats_t_print (vl_api_sw_interface_clear_stats_t * mp, void *handle) { @@ -2031,7 +2185,11 @@ _(IPFIX_DUMP,ipfix_dump) \ _(GET_NEXT_INDEX, get_next_index) \ _(PG_CREATE_INTERFACE,pg_create_interface) \ _(PG_CAPTURE, pg_capture) \ -_(PG_ENABLE_DISABLE, pg_enable_disable) +_(PG_ENABLE_DISABLE, pg_enable_disable) \ +_(POLICER_ADD_DEL, policer_add_del) \ +_(POLICER_DUMP, policer_dump) \ +_(POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface) \ +_(POLICER_CLASSIFY_DUMP, policer_classify_dump) void vl_msg_api_custom_dump_configure (api_main_t *am) { diff --git a/vpp/vpp-api/vpe.api b/vpp/vpp-api/vpe.api index 1477289b..4571c92d 100644 --- a/vpp/vpp-api/vpe.api +++ b/vpp/vpp-api/vpe.api @@ -3644,6 +3644,7 @@ define af_packet_delete_reply { @param rate_type - rate type @param round_type - rounding type @param type - policer algorithm + @param color_aware - 0=color-blind, 1=color-aware @param conform_action_type - conform action type @param conform_dscp - DSCP for conform mar-and-transmit action @param exceed_action_type - exceed action type @@ -3664,6 +3665,7 @@ define policer_add_del { u8 rate_type; u8 round_type; u8 type; + u8 color_aware; u8 conform_action_type; u8 conform_dscp; u8 exceed_action_type; @@ -3675,10 +3677,12 @@ define policer_add_del { /** \brief Add/del policer response @param context - sender context, to match reply w/ request @param retval - return value for request + @param policer_index - for add, returned index of the new policer */ define policer_add_del_reply { u32 context; i32 retval; + u32 policer_index; }; /** \brief Get list of policers @@ -3751,6 +3755,58 @@ define policer_details { u64 last_update_time; }; +/** \brief Set/unset policer classify interface + @param client_index - opaque cookie to identify the sender + @param context - sender context, to match reply w/ request + @param sw_if_index - interface to set/unset policer classify + @param ip4_table_index - ip4 classify table index (~0 for skip) + @param ip6_table_index - ip6 classify table index (~0 for skip) + @param l2_table_index - l2 classify table index (~0 for skip) + @param is_add - Set if non-zero, else unset + Note: User is recommeneded to use just one valid table_index per call. + (ip4_table_index, ip6_table_index, or l2_table_index) +*/ +define policer_classify_set_interface { + u32 client_index; + u32 context; + u32 sw_if_index; + u32 ip4_table_index; + u32 ip6_table_index; + u32 l2_table_index; + u8 is_add; +}; + +/** \brief Set/unset policer classify interface response + @param context - sender context, to match reply w/ request + @param retval - return value for request +*/ +define policer_classify_set_interface_reply { + u32 context; + i32 retval; +}; + +/** \brief Get list of policer classify interfaces and tables + @param client_index - opaque cookie to identify the sender + @param context - sender context, to match reply w/ request + @param type - classify table type +*/ +define policer_classify_dump { + u32 client_index; + u32 context; + u8 type; +}; + +/** \brief Policer iclassify operational state response. + @param context - sender context, to match reply w/ request + @param sw_if_index - software interface index + @param table_index - classify table index +*/ +define policer_classify_details { + u32 context; + u32 sw_if_index; + u32 table_index; +}; + /** \brief Create netmap @param client_index - opaque cookie to identify the sender @param context - sender context, to match reply w/ request |