#include <vnet/devices/netmap/netmap.h>
#include <vnet/flow/flow_report.h>
#include <vnet/ipsec-gre/ipsec_gre.h>
+#include <vnet/flow/flow_report_classify.h>
#undef BIHASH_TYPE
#undef __included_bihash_template_h__
vl_msg_api_send_shmem (q, (u8 *)&rmp); \
} while(0);
+#define REPLY_MACRO3(t, n, body) \
+do { \
+ unix_shared_memory_queue_t * q; \
+ rv = vl_msg_api_pd_handler (mp, rv); \
+ q = vl_api_client_index_to_input_queue (mp->client_index); \
+ if (!q) \
+ return; \
+ \
+ rmp = vl_msg_api_alloc (sizeof (*rmp) + n); \
+ rmp->_vl_msg_id = ntohs((t)); \
+ rmp->context = mp->context; \
+ rmp->retval = ntohl(rv); \
+ do {body;} while (0); \
+ vl_msg_api_send_shmem (q, (u8 *)&rmp); \
+} while(0);
+
#if (1 || CLIB_DEBUG > 0) /* "trust, but verify" */
#define VALIDATE_SW_IF_INDEX(mp) \
_(SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered) \
_(CREATE_LOOPBACK, create_loopback) \
_(CONTROL_PING, control_ping) \
-_(NOPRINT_CONTROL_PING, noprint_control_ping) \
_(CLI_REQUEST, cli_request) \
+_(CLI_INBAND, cli_inband) \
_(SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit) \
_(L2_PATCH_ADD_DEL, l2_patch_add_del) \
_(CLASSIFY_ADD_DEL_TABLE, classify_add_del_table) \
_(COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable) \
_(GET_NODE_GRAPH, get_node_graph) \
_(SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats) \
-_(TRACE_PROFILE_ADD, trace_profile_add) \
-_(TRACE_PROFILE_APPLY, trace_profile_apply) \
-_(TRACE_PROFILE_DEL, trace_profile_del) \
+_(IOAM_ENABLE, ioam_enable) \
+_(IOAM_DISABLE, ioam_disable) \
_(LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set) \
_(LISP_ADD_DEL_LOCATOR, lisp_add_del_locator) \
_(LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid) \
_(CLASSIFY_TABLE_INFO,classify_table_info) \
_(CLASSIFY_SESSION_DUMP,classify_session_dump) \
_(CLASSIFY_SESSION_DETAILS,classify_session_details) \
-_(IPFIX_ENABLE,ipfix_enable) \
-_(IPFIX_DUMP,ipfix_dump) \
+_(SET_IPFIX_EXPORTER, set_ipfix_exporter) \
+_(IPFIX_EXPORTER_DUMP, ipfix_exporter_dump) \
+_(SET_IPFIX_CLASSIFY_STREAM, set_ipfix_classify_stream) \
+_(IPFIX_CLASSIFY_STREAM_DUMP, ipfix_classify_stream_dump) \
+_(IPFIX_CLASSIFY_TABLE_ADD_DEL, ipfix_classify_table_add_del) \
+_(IPFIX_CLASSIFY_TABLE_DUMP, ipfix_classify_table_dump) \
_(GET_NEXT_INDEX, get_next_index) \
_(PG_CREATE_INTERFACE, pg_create_interface) \
_(PG_CAPTURE, pg_capture) \
/* *INDENT-ON* */
}
-static void vl_api_noprint_control_ping_t_handler
- (vl_api_noprint_control_ping_t * mp)
-{
- vl_api_noprint_control_ping_reply_t *rmp;
- int rv = 0;
-
- /* *INDENT-OFF* */
- REPLY_MACRO2(VL_API_NOPRINT_CONTROL_PING_REPLY,
- ({
- rmp->vpe_pid = ntohl (getpid());
- }));
- /* *INDENT-ON* */
-}
-
static void
shmem_cli_output (uword arg, u8 * buffer, uword buffer_bytes)
{
vl_msg_api_send_shmem (q, (u8 *) & rp);
}
+static void
+inband_cli_output (uword arg, u8 * buffer, uword buffer_bytes)
+{
+ u8 **mem_vecp = (u8 **) arg;
+ u8 *mem_vec = *mem_vecp;
+ u32 offset = vec_len (mem_vec);
+
+ vec_validate (mem_vec, offset + buffer_bytes - 1);
+ clib_memcpy (mem_vec + offset, buffer, buffer_bytes);
+ *mem_vecp = mem_vec;
+}
+
+static void
+vl_api_cli_inband_t_handler (vl_api_cli_inband_t * mp)
+{
+ vl_api_cli_inband_reply_t *rmp;
+ int rv = 0;
+ unix_shared_memory_queue_t *q;
+ vlib_main_t *vm = vlib_get_main ();
+ unformat_input_t input;
+ u8 *out_vec = 0;
+
+ q = vl_api_client_index_to_input_queue (mp->client_index);
+ if (!q)
+ return;
+
+ unformat_init_string (&input, (char *) mp->cmd, ntohl (mp->length));
+ vlib_cli_input (vm, &input, inband_cli_output, (uword) & out_vec);
+
+ u32 len = vec_len (out_vec);
+ /* *INDENT-OFF* */
+ REPLY_MACRO3(VL_API_CLI_INBAND_REPLY, len,
+ ({
+ rmp->length = htonl (len);
+ clib_memcpy (rmp->reply, out_vec, len);
+ }));
+ /* *INDENT-ON* */
+ vec_free (out_vec);
+}
+
static void
vl_api_set_arp_neighbor_limit_t_handler (vl_api_set_arp_neighbor_limit_t * mp)
{
VALIDATE_SW_IF_INDEX (mp);
- rv = vnet_l2_classify_set_tables (sw_if_index, ip4_table_index,
- ip6_table_index, other_table_index);
+ if (mp->is_input)
+ rv = vnet_l2_input_classify_set_tables (sw_if_index, ip4_table_index,
+ ip6_table_index,
+ other_table_index);
+ else
+ rv = vnet_l2_output_classify_set_tables (sw_if_index, ip4_table_index,
+ ip6_table_index,
+ other_table_index);
if (rv == 0)
{
else
enable = 0;
- vnet_l2_classify_enable_disable (sw_if_index, enable);
+ if (mp->is_input)
+ vnet_l2_input_classify_enable_disable (sw_if_index, enable);
+ else
+ vnet_l2_output_classify_enable_disable (sw_if_index, enable);
}
BAD_SW_IF_INDEX_LABEL;
memset (a, 0, sizeof (*a));
a->is_add = mp->is_add;
+ a->teb = mp->teb;
/* ip addresses sent in network byte order */
clib_memcpy (&(a->src), mp->src_address, 4);
clib_memcpy (rmp->src_address, &(t->tunnel_src), 4);
clib_memcpy (rmp->dst_address, &(t->tunnel_dst), 4);
rmp->outer_fib_id = htonl (im->fibs[t->outer_fib_index].table_id);
+ rmp->teb = t->teb;
rmp->sw_if_index = htonl (t->sw_if_index);
rmp->context = context;
static void
vl_api_lisp_locator_dump_t_handler (vl_api_lisp_locator_dump_t * mp)
{
+ u8 *ls_name = 0;
unix_shared_memory_queue_t *q = 0;
lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
locator_set_t *lsit = 0;
locator_t *loc = 0;
u32 ls_index = ~0, *locit = 0;
- u8 filter;
+ uword *p = 0;
q = vl_api_client_index_to_input_queue (mp->client_index);
if (q == 0)
return;
}
- ls_index = htonl (mp->locator_set_index);
-
- lsit = pool_elt_at_index (lcm->locator_set_pool, ls_index);
-
- filter = mp->filter;
- if (filter && !((1 == filter && lsit->local) ||
- (2 == filter && !lsit->local)))
+ if (mp->is_index_set)
+ ls_index = htonl (mp->ls_index);
+ else
{
- return;
+ /* make sure we get a proper C-string */
+ mp->ls_name[sizeof (mp->ls_name) - 1] = 0;
+ ls_name = format (0, "%s", mp->ls_name);
+ p = hash_get_mem (lcm->locator_set_index_by_name, ls_name);
+ if (!p)
+ goto out;
+ ls_index = p[0];
}
+ if (pool_is_free_index (lcm->locator_set_pool, ls_index))
+ return;
+
+ lsit = pool_elt_at_index (lcm->locator_set_pool, ls_index);
+
vec_foreach (locit, lsit->locator_indices)
{
loc = pool_elt_at_index (lcm->locator_pool, locit[0]);
send_lisp_locator_details (lcm, loc, q, mp->context);
};
+out:
+ vec_free (ls_name);
}
static void
rmp->_vl_msg_id = ntohs (VL_API_LISP_LOCATOR_SET_DETAILS);
rmp->context = context;
- rmp->local = lsit->local;
- rmp->locator_set_index = htonl (ls_index);
+ rmp->ls_index = htonl (ls_index);
if (lsit->local)
{
ASSERT (lsit->name != NULL);
- strncpy ((char *) rmp->locator_set_name,
- (char *) lsit->name, ARRAY_LEN (rmp->locator_set_name) - 1);
+ strncpy ((char *) rmp->ls_name, (char *) lsit->name,
+ vec_len (lsit->name));
}
else
{
- str = format (0, "remote-%d", ls_index);
- strncpy ((char *) rmp->locator_set_name, (char *) str,
- ARRAY_LEN (rmp->locator_set_name) - 1);
+ str = format (0, "<remote-%d>", ls_index);
+ strncpy ((char *) rmp->ls_name, (char *) str, vec_len (str));
vec_free (str);
}
unix_shared_memory_queue_t *q = NULL;
lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
locator_set_t *lsit = NULL;
- u32 index;
u8 filter;
q = vl_api_client_index_to_input_queue (mp->client_index);
}
filter = mp->filter;
- index = 0;
/* *INDENT-OFF* */
pool_foreach (lsit, lcm->locator_set_pool,
({
if (filter && !((1 == filter && lsit->local) ||
- (2 == filter && !lsit->local))) {
- index++;
- continue;
- }
- send_lisp_locator_set_details(lcm, lsit, q, mp->context, index++);
+ (2 == filter && !lsit->local)))
+ {
+ continue;
+ }
+ send_lisp_locator_set_details (lcm, lsit, q, mp->context,
+ lsit - lcm->locator_set_pool);
}));
/* *INDENT-ON* */
}
+static void
+lisp_fid_put_api (u8 * dst, fid_address_t * src, u8 * prefix_length)
+{
+ ASSERT (prefix_length);
+ ip_prefix_t *ippref = &fid_addr_ippref (src);
+
+ switch (fid_addr_type (src))
+ {
+ case FID_ADDR_IP_PREF:
+ if (ip_prefix_version (ippref) == IP4)
+ clib_memcpy (dst, &ip_prefix_v4 (ippref), 4);
+ else
+ clib_memcpy (dst, &ip_prefix_v6 (ippref), 16);
+ prefix_length[0] = ip_prefix_len (ippref);
+ break;
+
+ case FID_ADDR_MAC:
+ prefix_length[0] = 0;
+ clib_memcpy (dst, fid_addr_mac (src), 6);
+ break;
+
+ default:
+ clib_warning ("Unknown FID type %d!", fid_addr_type (src));
+ break;
+ }
+}
+
+static u8
+fid_type_to_api_type (fid_address_t * fid)
+{
+ ip_prefix_t *ippref;
+
+ switch (fid_addr_type (fid))
+ {
+ case FID_ADDR_IP_PREF:
+ ippref = &fid_addr_ippref (fid);
+ if (ip_prefix_version (ippref) == IP4)
+ return 0;
+ else if (ip_prefix_version (ippref) == IP6)
+ return 1;
+ else
+ return ~0;
+
+ case FID_ADDR_MAC:
+ return 2;
+ }
+
+ return ~0;
+}
+
static void
send_lisp_eid_table_details (mapping_t * mapit,
unix_shared_memory_queue_t * q,
u32 context, u8 filter)
{
+ fid_address_t *fid;
lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
locator_set_t *ls = 0;
vl_api_lisp_eid_table_details_t *rmp = NULL;
switch (gid_address_type (gid))
{
+ case GID_ADDR_SRC_DST:
+ rmp->is_src_dst = 1;
+ fid = &gid_address_sd_src (gid);
+ rmp->eid_type = fid_type_to_api_type (fid);
+ lisp_fid_put_api (rmp->seid, &gid_address_sd_src (gid),
+ &rmp->seid_prefix_len);
+ lisp_fid_put_api (rmp->eid, &gid_address_sd_dst (gid),
+ &rmp->eid_prefix_len);
+ break;
case GID_ADDR_IP_PREFIX:
rmp->eid_prefix_len = ip_prefix_len (ip_prefix);
if (ip_prefix_version (ip_prefix) == IP4)
/* *INDENT-ON* */
}
-static void vl_api_trace_profile_add_t_handler
- (vl_api_trace_profile_add_t * mp)
+static void
+vl_api_ioam_enable_t_handler (vl_api_ioam_enable_t * mp)
{
int rv = 0;
- vl_api_trace_profile_add_reply_t *rmp;
+ vl_api_ioam_enable_reply_t *rmp;
clib_error_t *error;
/* Ignoring the profile id as currently a single profile
* is supported */
- error = ip6_ioam_trace_profile_set (mp->trace_num_elt, mp->trace_type,
- ntohl (mp->node_id),
- ntohl (mp->trace_app_data),
- mp->pow_enable, mp->trace_tsp,
- mp->trace_ppc);
+ error = ip6_ioam_enable (mp->trace_enable, mp->pow_enable, mp->trace_ppc);
if (error)
{
clib_error_report (error);
rv = clib_error_get_code (error);
}
- REPLY_MACRO (VL_API_TRACE_PROFILE_ADD_REPLY);
+ REPLY_MACRO (VL_API_IOAM_ENABLE_REPLY);
}
-static void vl_api_trace_profile_apply_t_handler
- (vl_api_trace_profile_apply_t * mp)
-{
- int rv = 0;
- vl_api_trace_profile_apply_reply_t *rmp;
-
- if (mp->enable != 0)
- {
- rv = ip6_ioam_set_destination ((ip6_address_t *) (&mp->dest_ipv6),
- ntohl (mp->prefix_length),
- ntohl (mp->vrf_id),
- mp->trace_op == IOAM_HBYH_ADD,
- mp->trace_op == IOAM_HBYH_POP,
- mp->trace_op == IOAM_HBYH_MOD);
- }
- else
- {
- //ip6_ioam_clear_destination(&ip6, mp->prefix_length, mp->vrf_id);
- }
- REPLY_MACRO (VL_API_TRACE_PROFILE_APPLY_REPLY);
-}
-
-static void vl_api_trace_profile_del_t_handler
- (vl_api_trace_profile_del_t * mp)
+static void
+vl_api_ioam_disable_t_handler (vl_api_ioam_disable_t * mp)
{
int rv = 0;
- vl_api_trace_profile_del_reply_t *rmp;
+ vl_api_ioam_disable_reply_t *rmp;
clib_error_t *error;
error = clear_ioam_rewrite_fn ();
rv = clib_error_get_code (error);
}
- REPLY_MACRO (VL_API_TRACE_PROFILE_DEL_REPLY);
+ REPLY_MACRO (VL_API_IOAM_DISABLE_REPLY);
}
static void
vnet_classify_table_t *t;
q = vl_api_client_index_to_input_queue (mp->client_index);
+ if (!q)
+ return;
/* *INDENT-OFF* */
pool_foreach (t, cm->tables,
}
static void
-vl_api_ipfix_enable_t_handler (vl_api_ipfix_enable_t * mp)
+vl_api_set_ipfix_exporter_t_handler (vl_api_set_ipfix_exporter_t * mp)
{
vlib_main_t *vm = vlib_get_main ();
flow_report_main_t *frm = &flow_report_main;
- vl_api_ipfix_enable_reply_t *rmp;
+ vl_api_set_ipfix_exporter_reply_t *rmp;
ip4_address_t collector, src;
u16 collector_port = UDP_DST_PORT_ipfix;
u32 path_mtu;
u32 template_interval;
+ u8 udp_checksum;
u32 fib_id;
u32 fib_index = ~0;
int rv = 0;
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)
+ if (fib_id == ~0)
{
- rv = VNET_API_ERROR_NO_SUCH_FIB;
- goto out;
+ fib_index = ~0;
+ }
+ else
+ {
+ 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];
}
- fib_index = p[0];
path_mtu = ntohl (mp->path_mtu);
if (path_mtu == ~0)
template_interval = ntohl (mp->template_interval);
if (template_interval == ~0)
template_interval = 20;
+ udp_checksum = mp->udp_checksum;
if (collector.as_u32 == 0)
{
frm->fib_index = fib_index;
frm->path_mtu = path_mtu;
frm->template_interval = template_interval;
+ frm->udp_checksum = udp_checksum;
/* 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);
+ REPLY_MACRO (VL_API_SET_IPFIX_EXPORTER_REPLY);
}
static void
-vl_api_ipfix_dump_t_handler (vl_api_ipfix_dump_t * mp)
+vl_api_ipfix_exporter_dump_t_handler (vl_api_ipfix_exporter_dump_t * mp)
{
flow_report_main_t *frm = &flow_report_main;
unix_shared_memory_queue_t *q;
- vl_api_ipfix_details_t *rmp;
+ vl_api_ipfix_exporter_details_t *rmp;
+ ip4_main_t *im = &ip4_main;
+ u32 vrf_id;
q = vl_api_client_index_to_input_queue (mp->client_index);
if (!q)
rmp = vl_msg_api_alloc (sizeof (*rmp));
memset (rmp, 0, sizeof (*rmp));
- rmp->_vl_msg_id = ntohs (VL_API_IPFIX_DETAILS);
+ rmp->_vl_msg_id = ntohs (VL_API_IPFIX_EXPORTER_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);
+ if (frm->fib_index == ~0)
+ vrf_id = ~0;
+ else
+ vrf_id = im->fibs[frm->fib_index].table_id;
+ rmp->vrf_id = htonl (vrf_id);
rmp->path_mtu = htonl (frm->path_mtu);
rmp->template_interval = htonl (frm->template_interval);
+ rmp->udp_checksum = (frm->udp_checksum != 0);
vl_msg_api_send_shmem (q, (u8 *) & rmp);
}
+static void
+ vl_api_set_ipfix_classify_stream_t_handler
+ (vl_api_set_ipfix_classify_stream_t * mp)
+{
+ vl_api_set_ipfix_classify_stream_reply_t *rmp;
+ flow_report_classify_main_t *fcm = &flow_report_classify_main;
+ flow_report_main_t *frm = &flow_report_main;
+ u32 domain_id = 0;
+ u32 src_port = UDP_DST_PORT_ipfix;
+ int rv = 0;
+
+ domain_id = ntohl (mp->domain_id);
+ src_port = ntohs (mp->src_port);
+
+ if (fcm->src_port != 0 &&
+ (fcm->domain_id != domain_id || fcm->src_port != (u16) src_port))
+ {
+ int rv = vnet_stream_change (frm, fcm->domain_id, fcm->src_port,
+ domain_id, (u16) src_port);
+ ASSERT (rv == 0);
+ }
+
+ fcm->domain_id = domain_id;
+ fcm->src_port = (u16) src_port;
+
+ REPLY_MACRO (VL_API_SET_IPFIX_CLASSIFY_STREAM_REPLY);
+}
+
+static void
+ vl_api_ipfix_classify_stream_dump_t_handler
+ (vl_api_ipfix_classify_stream_dump_t * mp)
+{
+ flow_report_classify_main_t *fcm = &flow_report_classify_main;
+ unix_shared_memory_queue_t *q;
+ vl_api_ipfix_classify_stream_details_t *rmp;
+
+ q = vl_api_client_index_to_input_queue (mp->client_index);
+ if (!q)
+ return;
+
+ rmp = vl_msg_api_alloc (sizeof (*rmp));
+ memset (rmp, 0, sizeof (*rmp));
+ rmp->_vl_msg_id = ntohs (VL_API_IPFIX_CLASSIFY_STREAM_DETAILS);
+ rmp->context = mp->context;
+ rmp->domain_id = htonl (fcm->domain_id);
+ rmp->src_port = htons (fcm->src_port);
+
+ vl_msg_api_send_shmem (q, (u8 *) & rmp);
+}
+
+static void
+ vl_api_ipfix_classify_table_add_del_t_handler
+ (vl_api_ipfix_classify_table_add_del_t * mp)
+{
+ vl_api_ipfix_classify_table_add_del_reply_t *rmp;
+ flow_report_classify_main_t *fcm = &flow_report_classify_main;
+ flow_report_main_t *frm = &flow_report_main;
+ vnet_flow_report_add_del_args_t args;
+ ipfix_classify_table_t *table;
+ int is_add;
+ u32 classify_table_index;
+ u8 ip_version;
+ u8 transport_protocol;
+ int rv = 0;
+
+ classify_table_index = ntohl (mp->table_id);
+ ip_version = mp->ip_version;
+ transport_protocol = mp->transport_protocol;
+ is_add = mp->is_add;
+
+ if (fcm->src_port == 0)
+ {
+ /* call set_ipfix_classify_stream first */
+ rv = VNET_API_ERROR_UNSPECIFIED;
+ goto out;
+ }
+
+ memset (&args, 0, sizeof (args));
+
+ table = 0;
+ int i;
+ for (i = 0; i < vec_len (fcm->tables); i++)
+ if (ipfix_classify_table_index_valid (i))
+ if (fcm->tables[i].classify_table_index == classify_table_index)
+ {
+ table = &fcm->tables[i];
+ break;
+ }
+
+ if (is_add)
+ {
+ if (table)
+ {
+ rv = VNET_API_ERROR_VALUE_EXIST;
+ goto out;
+ }
+ table = ipfix_classify_add_table ();
+ table->classify_table_index = classify_table_index;
+ }
+ else
+ {
+ if (!table)
+ {
+ rv = VNET_API_ERROR_NO_SUCH_ENTRY;
+ goto out;
+ }
+ }
+
+ table->ip_version = ip_version;
+ table->transport_protocol = transport_protocol;
+
+ args.opaque.as_uword = table - fcm->tables;
+ args.rewrite_callback = ipfix_classify_template_rewrite;
+ args.flow_data_callback = ipfix_classify_send_flows;
+ args.is_add = is_add;
+ args.domain_id = fcm->domain_id;
+ args.src_port = fcm->src_port;
+
+ rv = vnet_flow_report_add_del (frm, &args);
+
+ /* If deleting, or add failed */
+ if (is_add == 0 || (rv && is_add))
+ ipfix_classify_delete_table (table - fcm->tables);
+
+out:
+ REPLY_MACRO (VL_API_SET_IPFIX_CLASSIFY_STREAM_REPLY);
+}
+
+static void
+send_ipfix_classify_table_details (u32 table_index,
+ unix_shared_memory_queue_t * q,
+ u32 context)
+{
+ flow_report_classify_main_t *fcm = &flow_report_classify_main;
+ vl_api_ipfix_classify_table_details_t *mp;
+
+ ipfix_classify_table_t *table = &fcm->tables[table_index];
+
+ mp = vl_msg_api_alloc (sizeof (*mp));
+ memset (mp, 0, sizeof (*mp));
+ mp->_vl_msg_id = ntohs (VL_API_IPFIX_CLASSIFY_TABLE_DETAILS);
+ mp->context = context;
+ mp->table_id = htonl (table->classify_table_index);
+ mp->ip_version = table->ip_version;
+ mp->transport_protocol = table->transport_protocol;
+
+ vl_msg_api_send_shmem (q, (u8 *) & mp);
+}
+
+static void
+ vl_api_ipfix_classify_table_dump_t_handler
+ (vl_api_ipfix_classify_table_dump_t * mp)
+{
+ flow_report_classify_main_t *fcm = &flow_report_classify_main;
+ unix_shared_memory_queue_t *q;
+ u32 i;
+
+ q = vl_api_client_index_to_input_queue (mp->client_index);
+ if (!q)
+ return;
+
+ for (i = 0; i < vec_len (fcm->tables); i++)
+ if (ipfix_classify_table_index_valid (i))
+ send_ipfix_classify_table_details (i, q, mp->context);
+}
+
static void
vl_api_pg_create_interface_t_handler (vl_api_pg_create_interface_t * mp)
{