From 837fbb119c0dcd10594485d15d700ceec7c0f33a Mon Sep 17 00:00:00 2001 From: Juraj Sloboda Date: Wed, 6 Jul 2016 23:11:47 -0700 Subject: Add binary API for IPFIX Change-Id: I3346b18126d65b72726e977dfb11ba4c380056c0 Signed-off-by: Juraj Sloboda --- vnet/vnet/flow/flow_report.c | 2 + vnet/vnet/flow/flow_report.h | 4 +- vpp/vpp-api/api.c | 105 ++++++++++++++++++++++++++++++++++++++++++- vpp/vpp-api/custom_dump.c | 33 +++++++++++++- vpp/vpp-api/vpe.api | 57 +++++++++++++++++++++++ 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 #include +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 #include #include +#include #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; +}; -- cgit 1.2.3-korg