summaryrefslogtreecommitdiffstats
path: root/vpp
diff options
context:
space:
mode:
authorJuraj Sloboda <jsloboda@cisco.com>2016-08-07 23:45:24 -0700
committerDamjan Marion <dmarion.lists@gmail.com>2016-10-10 20:51:28 +0000
commit506b24564d32c7aca58055a710eba64ed942c1c4 (patch)
treeef8597b915da95ea3149111569c5f708c65138c9 /vpp
parent477570e587b6b5a8f356a2727794155fa912d59f (diff)
ipfix: add classification nodes for flow statistics (VPP-204)
In order to have meaningfull IPFIX implementation we should be able to classify all packets flowing through vpp. But existing IPv4 and IPv6 classifier nodes are called only if destination IP address is local to vpp. This commit adds new IPv4 and IPv6 classifier nodes that should be used for collecting flow statistics. Change-Id: I60e60105663ba15b5200862a23bb817047fe4d1a Signed-off-by: Juraj Sloboda <jsloboda@cisco.com>
Diffstat (limited to 'vpp')
-rw-r--r--vpp/vpp-api/api.c72
-rw-r--r--vpp/vpp-api/custom_dump.c42
-rw-r--r--vpp/vpp-api/vpe.api51
3 files changed, 163 insertions, 2 deletions
diff --git a/vpp/vpp-api/api.c b/vpp/vpp-api/api.c
index a7382492160..0ef6966af0f 100644
--- a/vpp/vpp-api/api.c
+++ b/vpp/vpp-api/api.c
@@ -68,6 +68,7 @@
#include <vnet/classify/vnet_classify.h>
#include <vnet/classify/input_acl.h>
#include <vnet/classify/policer_classify.h>
+#include <vnet/classify/flow_classify.h>
#include <vnet/l2/l2_classify.h>
#include <vnet/vxlan/vxlan.h>
#include <vnet/gre/gre.h>
@@ -425,7 +426,9 @@ _(IPSEC_GRE_ADD_DEL_TUNNEL, ipsec_gre_add_del_tunnel) \
_(IPSEC_GRE_TUNNEL_DUMP, ipsec_gre_tunnel_dump) \
_(DELETE_SUBIF, delete_subif) \
_(L2_INTERFACE_PBB_TAG_REWRITE, l2_interface_pbb_tag_rewrite) \
-_(PUNT, punt)
+_(PUNT, punt) \
+_(FLOW_CLASSIFY_SET_INTERFACE, flow_classify_set_interface) \
+_(FLOW_CLASSIFY_DUMP, flow_classify_dump)
#define QUOTE_(x) #x
#define QUOTE(x) QUOTE_(x)
@@ -8526,6 +8529,73 @@ vl_api_punt_t_handler (vl_api_punt_t * mp)
REPLY_MACRO (VL_API_PUNT_REPLY);
}
+static void
+ vl_api_flow_classify_set_interface_t_handler
+ (vl_api_flow_classify_set_interface_t * mp)
+{
+ vlib_main_t *vm = vlib_get_main ();
+ vl_api_flow_classify_set_interface_reply_t *rmp;
+ int rv;
+ u32 sw_if_index, ip4_table_index, ip6_table_index;
+
+ ip4_table_index = ntohl (mp->ip4_table_index);
+ ip6_table_index = ntohl (mp->ip6_table_index);
+ sw_if_index = ntohl (mp->sw_if_index);
+
+ VALIDATE_SW_IF_INDEX (mp);
+
+ rv = vnet_set_flow_classify_intfc (vm, sw_if_index, ip4_table_index,
+ ip6_table_index, mp->is_add);
+
+ BAD_SW_IF_INDEX_LABEL;
+
+ REPLY_MACRO (VL_API_FLOW_CLASSIFY_SET_INTERFACE_REPLY);
+}
+
+static void
+send_flow_classify_details (u32 sw_if_index,
+ u32 table_index,
+ unix_shared_memory_queue_t * q, u32 context)
+{
+ vl_api_flow_classify_details_t *mp;
+
+ mp = vl_msg_api_alloc (sizeof (*mp));
+ memset (mp, 0, sizeof (*mp));
+ mp->_vl_msg_id = ntohs (VL_API_FLOW_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_flow_classify_dump_t_handler (vl_api_flow_classify_dump_t * mp)
+{
+ unix_shared_memory_queue_t *q;
+ flow_classify_main_t *pcm = &flow_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_flow_classify_details (i, vec_elt (vec_tbl, i), q,
+ mp->context);
+ }
+ }
+}
+
#define BOUNCE_HANDLER(nn) \
static void vl_api_##nn##_t_handler ( \
vl_api_##nn##_t *mp) \
diff --git a/vpp/vpp-api/custom_dump.c b/vpp/vpp-api/custom_dump.c
index 718e5646abf..096c1aa85fa 100644
--- a/vpp/vpp-api/custom_dump.c
+++ b/vpp/vpp-api/custom_dump.c
@@ -30,6 +30,7 @@
#include <vnet/classify/policer_classify.h>
#include <vnet/policer/xlate.h>
#include <vnet/policer/policer.h>
+#include <vnet/classify/flow_classify.h>
#include <vlib/vlib.h>
#include <vlib/unix/unix.h>
#include <vlibapi/api.h>
@@ -2771,6 +2772,23 @@ static void *vl_api_l2_interface_pbb_tag_rewrite_t_print
FINISH;
}
+static void *vl_api_flow_classify_set_interface_t_print
+ (vl_api_flow_classify_set_interface_t * mp, void *handle)
+{
+ u8 *s;
+
+ s = format (0, "SCRIPT: flow_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->is_add == 0)
+ s = format (s, "del ");
+
+ FINISH;
+}
+
static void *
vl_api_punt_t_print (vl_api_punt_t * mp, void *handle)
{
@@ -2792,6 +2810,26 @@ vl_api_punt_t_print (vl_api_punt_t * mp, void *handle)
FINISH;
}
+static void *vl_api_flow_classify_dump_t_print
+ (vl_api_flow_classify_dump_t * mp, void *handle)
+{
+ u8 *s;
+
+ s = format (0, "SCRIPT: flow_classify_dump ");
+ switch (mp->type)
+ {
+ case FLOW_CLASSIFY_TABLE_IP4:
+ s = format (s, "type ip4 ");
+ break;
+ case FLOW_CLASSIFY_TABLE_IP6:
+ s = format (s, "type ip6 ");
+ break;
+ default:
+ break;
+ }
+
+ FINISH;
+}
#define foreach_custom_print_no_arg_function \
_(lisp_eid_table_vni_dump) \
@@ -2955,7 +2993,9 @@ _(IPSEC_GRE_ADD_DEL_TUNNEL, ipsec_gre_add_del_tunnel) \
_(IPSEC_GRE_TUNNEL_DUMP, ipsec_gre_tunnel_dump) \
_(DELETE_SUBIF, delete_subif) \
_(L2_INTERFACE_PBB_TAG_REWRITE, l2_interface_pbb_tag_rewrite) \
-_(PUNT, punt)
+_(PUNT, punt) \
+_(FLOW_CLASSIFY_SET_INTERFACE, flow_classify_set_interface) \
+_(FLOW_CLASSIFY_DUMP, flow_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 0f1b0a8f455..a48d345a105 100644
--- a/vpp/vpp-api/vpe.api
+++ b/vpp/vpp-api/vpe.api
@@ -4791,6 +4791,57 @@ define ipfix_classify_table_details {
u8 transport_protocol;
};
+/** \brief Set/unset flow 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 flow 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 flow_classify_set_interface {
+ u32 client_index;
+ u32 context;
+ u32 sw_if_index;
+ u32 ip4_table_index;
+ u32 ip6_table_index;
+ u8 is_add;
+};
+
+/** \brief Set/unset flow classify interface response
+ @param context - sender context, to match reply w/ request
+ @param retval - return value for request
+*/
+define flow_classify_set_interface_reply {
+ u32 context;
+ i32 retval;
+};
+
+/** \brief Get list of flow 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 flow_classify_dump {
+ u32 client_index;
+ u32 context;
+ u8 type;
+};
+
+/** \brief Flow classify 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 flow_classify_details {
+ u32 context;
+ u32 sw_if_index;
+ u32 table_index;
+};
+
/** \brief Query relative index via node names
@param client_index - opaque cookie to identify the sender
@param context - sender context, to match reply w/ request