aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJuraj Sloboda <jsloboda@cisco.com>2016-07-06 23:11:47 -0700
committerDamjan Marion <dmarion.lists@gmail.com>2016-07-08 11:24:39 +0000
commit837fbb119c0dcd10594485d15d700ceec7c0f33a (patch)
tree096431a38daca4e093eafc90c32afcd8859bd3b8
parent483f668eda5382912d99b81e94a1e34311ded1ed (diff)
Add binary API for IPFIX
Change-Id: I3346b18126d65b72726e977dfb11ba4c380056c0 Signed-off-by: Juraj Sloboda <jsloboda@cisco.com>
-rw-r--r--vnet/vnet/flow/flow_report.c2
-rw-r--r--vnet/vnet/flow/flow_report.h4
-rw-r--r--vpp/vpp-api/api.c105
-rw-r--r--vpp/vpp-api/custom_dump.c33
-rw-r--r--vpp/vpp-api/vpe.api57
5 files changed, 198 insertions, 3 deletions
diff --git a/vnet/vnet/flow/flow_report.c b/vnet/vnet/flow/flow_report.c
index 77f92b132fe..38ad6136ef6 100644
--- a/vnet/vnet/flow/flow_report.c
+++ b/vnet/vnet/flow/flow_report.c
@@ -18,6 +18,8 @@
#include <vnet/flow/flow_report.h>
#include <vnet/api_errno.h>
+flow_report_main_t flow_report_main;
+
int send_template_packet (flow_report_main_t *frm,
flow_report_t *fr,
u32 * buffer_indexp)
diff --git a/vnet/vnet/flow/flow_report.h b/vnet/vnet/flow/flow_report.h
index 50e15449d53..27aa81ae3ca 100644
--- a/vnet/vnet/flow/flow_report.h
+++ b/vnet/vnet/flow/flow_report.h
@@ -97,7 +97,7 @@ typedef struct flow_report_main {
vnet_main_t * vnet_main;
} flow_report_main_t;
-flow_report_main_t flow_report_main;
+extern flow_report_main_t flow_report_main;
extern vlib_node_registration_t flow_report_process_node;
@@ -115,4 +115,6 @@ typedef struct {
int vnet_flow_report_add_del (flow_report_main_t *frm,
vnet_flow_report_add_del_args_t *a);
+void vnet_flow_reports_reset (flow_report_main_t * frm);
+
#endif /* __included_vnet_flow_report_h__ */
diff --git a/vpp/vpp-api/api.c b/vpp/vpp-api/api.c
index 0879d49dcee..330222fb2b6 100644
--- a/vpp/vpp-api/api.c
+++ b/vpp/vpp-api/api.c
@@ -79,6 +79,7 @@
#include <vnet/devices/af_packet/af_packet.h>
#include <vnet/policer/policer.h>
#include <vnet/devices/netmap/netmap.h>
+#include <vnet/flow/flow_report.h>
#undef BIHASH_TYPE
#undef __included_bihash_template_h__
@@ -365,7 +366,9 @@ _(CLASSIFY_TABLE_IDS,classify_table_ids) \
_(CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface) \
_(CLASSIFY_TABLE_INFO,classify_table_info) \
_(CLASSIFY_SESSION_DUMP,classify_session_dump) \
-_(CLASSIFY_SESSION_DETAILS,classify_session_details)
+_(CLASSIFY_SESSION_DETAILS,classify_session_details) \
+_(IPFIX_ENABLE,ipfix_enable) \
+_(IPFIX_DUMP,ipfix_dump)
#define QUOTE_(x) #x
#define QUOTE(x) QUOTE_(x)
@@ -7016,6 +7019,106 @@ static void vl_api_classify_session_dump_t_handler (vl_api_classify_session_dump
}));
}
+static void vl_api_ipfix_enable_t_handler (vl_api_ipfix_enable_t *mp)
+{
+ vlib_main_t *vm = vlib_get_main();
+ flow_report_main_t * frm = &flow_report_main;
+ vl_api_ipfix_enable_reply_t *rmp;
+ ip4_address_t collector, src;
+ u16 collector_port = UDP_DST_PORT_ipfix;
+ u32 path_mtu;
+ u32 template_interval;
+ u32 fib_id;
+ u32 fib_index = ~0;
+ int rv = 0;
+
+ memcpy(collector.data, mp->collector_address, sizeof(collector.data));
+ collector_port = ntohs(mp->collector_port);
+ if (collector_port == (u16)~0)
+ collector_port = UDP_DST_PORT_ipfix;
+ memcpy(src.data, mp->src_address, sizeof(src.data));
+ fib_id = ntohl(mp->vrf_id);
+
+ ip4_main_t * im = &ip4_main;
+ uword * p = hash_get (im->fib_index_by_table_id, fib_id);
+ if (! p) {
+ rv = VNET_API_ERROR_NO_SUCH_FIB;
+ goto out;
+ }
+ fib_index = p[0];
+
+ path_mtu = ntohl(mp->path_mtu);
+ if (path_mtu == ~0)
+ path_mtu = 512; // RFC 7011 section 10.3.3.
+ template_interval = ntohl(mp->template_interval);
+ if (template_interval == ~0)
+ template_interval = 20;
+
+ if (collector.as_u32 == 0) {
+ rv = VNET_API_ERROR_INVALID_VALUE;
+ goto out;
+ }
+
+ if (src.as_u32 == 0) {
+ rv = VNET_API_ERROR_INVALID_VALUE;
+ goto out;
+ }
+
+ if (path_mtu > 1450 /* vpp does not support fragmentation */) {
+ rv = VNET_API_ERROR_INVALID_VALUE;
+ goto out;
+ }
+
+ if (path_mtu < 68) {
+ rv = VNET_API_ERROR_INVALID_VALUE;
+ goto out;
+ }
+
+ /* Reset report streams if we are reconfiguring IP addresses */
+ if (frm->ipfix_collector.as_u32 != collector.as_u32 ||
+ frm->src_address.as_u32 != src.as_u32 ||
+ frm->collector_port != collector_port)
+ vnet_flow_reports_reset(frm);
+
+ frm->ipfix_collector.as_u32 = collector.as_u32;
+ frm->collector_port = collector_port;
+ frm->src_address.as_u32 = src.as_u32;
+ frm->fib_index = fib_index;
+ frm->path_mtu = path_mtu;
+ frm->template_interval = template_interval;
+
+ /* Turn on the flow reporting process */
+ vlib_process_signal_event (vm, flow_report_process_node.index,
+ 1, 0);
+
+out:
+ REPLY_MACRO(VL_API_IPFIX_ENABLE_REPLY);
+}
+
+static void vl_api_ipfix_dump_t_handler (vl_api_ipfix_dump_t *mp)
+{
+ flow_report_main_t * frm = &flow_report_main;
+ unix_shared_memory_queue_t * q;
+ vl_api_ipfix_details_t *rmp;
+
+ q = vl_api_client_index_to_input_queue (mp->client_index);
+
+ rmp = vl_msg_api_alloc (sizeof (*rmp));
+ memset (rmp, 0, sizeof (*rmp));
+ rmp->_vl_msg_id = ntohs(VL_API_IPFIX_DETAILS);
+ rmp->context = mp->context;
+ memcpy(rmp->collector_address, frm->ipfix_collector.data,
+ sizeof(frm->ipfix_collector.data));
+ rmp->collector_port = htons(frm->collector_port);
+ memcpy(rmp->src_address, frm->src_address.data,
+ sizeof(frm->src_address.data));
+ rmp->fib_index = htonl(frm->fib_index);
+ rmp->path_mtu = htonl(frm->path_mtu);
+ rmp->template_interval = htonl(frm->template_interval);
+
+ vl_msg_api_send_shmem (q, (u8 *)&rmp);
+}
+
#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 a2eb1f279a4..9967d5b9630 100644
--- a/vpp/vpp-api/custom_dump.c
+++ b/vpp/vpp-api/custom_dump.c
@@ -1846,6 +1846,35 @@ static void *vl_api_classify_session_dump_t_print
FINISH;
}
+static void *vl_api_ipfix_enable_t_print
+(vl_api_ipfix_enable_t * mp, void *handle)
+{
+ u8 * s;
+
+ s = format (0, "SCRIPT: ipfix_enable ");
+
+ s = format (s, "collector-address %U ", format_ip4_address,
+ (ip4_address_t *) mp->collector_address);
+ s = format (s, "collector-port %d ", ntohs(mp->collector_port));
+ s = format (s, "src-address %U ", format_ip4_address,
+ (ip4_address_t *) mp->src_address);
+ s = format (s, "vrf-id %d ", ntohl(mp->vrf_id));
+ s = format (s, "path-mtu %d ", ntohl(mp->path_mtu));
+ s = format (s, "template-interval %d ", ntohl(mp->template_interval));
+
+ FINISH;
+}
+
+static void *vl_api_ipfix_dump_t_print
+(vl_api_ipfix_dump_t * mp, void *handle)
+{
+ u8 * s;
+
+ s = format (0, "SCRIPT: ipfix_dump ");
+
+ FINISH;
+}
+
#define foreach_custom_print_function \
_(CREATE_LOOPBACK, create_loopback) \
_(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags) \
@@ -1941,7 +1970,9 @@ _(MPLS_FIB_DECAP_DUMP, mpls_fib_decap_dump) \
_(CLASSIFY_TABLE_IDS,classify_table_ids) \
_(CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface) \
_(CLASSIFY_TABLE_INFO,classify_table_info) \
-_(CLASSIFY_SESSION_DUMP,classify_session_dump)
+_(CLASSIFY_SESSION_DUMP,classify_session_dump) \
+_(IPFIX_ENABLE,ipfix_enable) \
+_(IPFIX_DUMP,ipfix_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 f61a3045632..e36240f4389 100644
--- a/vpp/vpp-api/vpe.api
+++ b/vpp/vpp-api/vpe.api
@@ -4012,3 +4012,60 @@ manual_java define classify_session_details {
u32 match_length;
u8 match[match_length];
};
+
+/** \brief Enable and configure IPFIX exporter process request
+ @param client_index - opaque cookie to identify the sender
+ @param context - sender context, to match reply w/ request
+ @param collector_address - address of IPFIX collector
+ @param collector_port - port of IPFIX IPFIX collector
+ @param src_address - address of IPFIX exporter
+ @param vrf_id - VRF / fib table ID
+ @param path_mtu - Path MTU between exporter and collector
+ @param template_interval - number of seconds after which to resend template
+*/
+define ipfix_enable {
+ u32 client_index;
+ u32 context;
+ u8 collector_address[16];
+ u16 collector_port;
+ u8 src_address[16];
+ u32 vrf_id;
+ u32 path_mtu;
+ u32 template_interval;
+};
+
+/** \brief Reply to IPFIX enable and configure request
+ @param context - sender context which was passed in the request
+*/
+define ipfix_enable_reply {
+ u32 context;
+ u32 retval;
+};
+
+/** \brief IPFIX dump request
+ @param client_index - opaque cookie to identify the sender
+ @param context - sender context, to match reply w/ request
+*/
+define ipfix_dump {
+ u32 client_index;
+ u32 context;
+};
+
+/** \brief Reply to IPFIX dump request
+ @param context - sender context which was passed in the request
+ @param collector_address - address of IPFIX collector
+ @param collector_port - port of IPFIX IPFIX collector
+ @param src_address - address of IPFIX exporter
+ @param fib_index - fib table index
+ @param path_mtu - Path MTU between exporter and collector
+ @param template_interval - number of seconds after which to resend template
+*/
+manual_java define ipfix_details {
+ u32 context;
+ u8 collector_address[16];
+ u16 collector_port;
+ u8 src_address[16];
+ u32 fib_index;
+ u32 path_mtu;
+ u32 template_interval;
+};