aboutsummaryrefslogtreecommitdiffstats
path: root/vpp
diff options
context:
space:
mode:
authorMatus Fabian <matfabia@cisco.com>2016-06-20 08:10:42 -0700
committerDave Barach <openvpp@barachs.net>2016-07-26 15:52:03 +0000
commit70e6a8dd52b5c2814737b9a75763ff239a7e053d (patch)
tree403733620fb32f571da1b9bf5be9ce740a9b1054 /vpp
parentac0798db359eb0de2eae1a54b63dfaa9534984c8 (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.c84
-rw-r--r--vpp/vpp-api/custom_dump.c160
-rw-r--r--vpp/vpp-api/vpe.api56
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