+ vl_api_cop_whitelist_enable_disable_reply_t *rmp;
+ cop_whitelist_enable_disable_args_t _a, *a = &_a;
+ u32 sw_if_index = ntohl (mp->sw_if_index);
+ int rv;
+
+ VALIDATE_SW_IF_INDEX (mp);
+
+ a->sw_if_index = sw_if_index;
+ a->ip4 = mp->ip4;
+ a->ip6 = mp->ip6;
+ a->default_cop = mp->default_cop;
+ a->fib_id = ntohl (mp->fib_id);
+
+ rv = cop_whitelist_enable_disable (a);
+
+ BAD_SW_IF_INDEX_LABEL;
+
+ REPLY_MACRO (VL_API_COP_WHITELIST_ENABLE_DISABLE_REPLY);
+}
+
+static void
+vl_api_get_node_graph_t_handler (vl_api_get_node_graph_t * mp)
+{
+ int rv = 0;
+ u8 *vector = 0;
+ api_main_t *am = &api_main;
+ vlib_main_t *vm = vlib_get_main ();
+ void *oldheap;
+ vl_api_get_node_graph_reply_t *rmp;
+
+ pthread_mutex_lock (&am->vlib_rp->mutex);
+ oldheap = svm_push_data_heap (am->vlib_rp);
+
+ /*
+ * Keep the number of memcpy ops to a minimum (e.g. 1).
+ */
+ vec_validate (vector, 16384);
+ vec_reset_length (vector);
+
+ /* $$$$ FIXME */
+ vector = vlib_node_serialize (&vm->node_main, vector,
+ (u32) ~ 0 /* all threads */ ,
+ 1 /* include nexts */ ,
+ 1 /* include stats */ );
+
+ svm_pop_heap (oldheap);
+ pthread_mutex_unlock (&am->vlib_rp->mutex);
+
+ /* *INDENT-OFF* */
+ REPLY_MACRO2(VL_API_GET_NODE_GRAPH_REPLY,
+ ({
+ rmp->reply_in_shmem = (uword) vector;
+ }));
+ /* *INDENT-ON* */
+}
+
+static void
+vl_api_ioam_enable_t_handler (vl_api_ioam_enable_t * mp)
+{
+ int rv = 0;
+ 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_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_IOAM_ENABLE_REPLY);
+}
+
+static void
+vl_api_ioam_disable_t_handler (vl_api_ioam_disable_t * mp)
+{
+ int rv = 0;
+ vl_api_ioam_disable_reply_t *rmp;
+ clib_error_t *error;
+
+ error = clear_ioam_rewrite_fn ();
+ if (error)
+ {
+ clib_error_report (error);
+ rv = clib_error_get_code (error);
+ }
+
+ REPLY_MACRO (VL_API_IOAM_DISABLE_REPLY);
+}
+
+static void
+vl_api_af_packet_create_t_handler (vl_api_af_packet_create_t * mp)
+{
+ vlib_main_t *vm = vlib_get_main ();
+ vl_api_af_packet_create_reply_t *rmp;
+ int rv = 0;
+ u8 *host_if_name = NULL;
+ u32 sw_if_index;
+
+ host_if_name = format (0, "%s", mp->host_if_name);
+ vec_add1 (host_if_name, 0);
+
+ rv = af_packet_create_if (vm, host_if_name,
+ mp->use_random_hw_addr ? 0 : mp->hw_addr,
+ &sw_if_index);
+
+ vec_free (host_if_name);
+
+ /* *INDENT-OFF* */
+ REPLY_MACRO2(VL_API_AF_PACKET_CREATE_REPLY,
+ ({
+ rmp->sw_if_index = clib_host_to_net_u32(sw_if_index);
+ }));
+ /* *INDENT-ON* */
+}
+
+static void
+vl_api_af_packet_delete_t_handler (vl_api_af_packet_delete_t * mp)
+{
+ vlib_main_t *vm = vlib_get_main ();
+ vl_api_af_packet_delete_reply_t *rmp;
+ int rv = 0;
+ u8 *host_if_name = NULL;
+
+ host_if_name = format (0, "%s", mp->host_if_name);
+ vec_add1 (host_if_name, 0);
+
+ rv = af_packet_delete_if (vm, host_if_name);
+
+ vec_free (host_if_name);
+
+ REPLY_MACRO (VL_API_AF_PACKET_DELETE_REPLY);
+}
+
+static void
+vl_api_policer_add_del_t_handler (vl_api_policer_add_del_t * mp)
+{
+ vlib_main_t *vm = vlib_get_main ();
+ vl_api_policer_add_del_reply_t *rmp;
+ int rv = 0;
+ u8 *name = NULL;
+ sse2_qos_pol_cfg_params_st cfg;
+ clib_error_t *error;
+ u32 policer_index;
+
+ name = format (0, "%s", mp->name);
+
+ memset (&cfg, 0, sizeof (cfg));
+ cfg.rfc = mp->type;
+ cfg.rnd_type = mp->round_type;
+ cfg.rate_type = mp->rate_type;
+ cfg.rb.kbps.cir_kbps = mp->cir;
+ cfg.rb.kbps.eir_kbps = mp->eir;
+ cfg.rb.kbps.cb_bytes = mp->cb;
+ cfg.rb.kbps.eb_bytes = mp->eb;
+ cfg.conform_action.action_type = mp->conform_action_type;
+ cfg.conform_action.dscp = mp->conform_dscp;
+ cfg.exceed_action.action_type = mp->exceed_action_type;
+ 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, &policer_index, mp->is_add);
+
+ if (error)
+ rv = VNET_API_ERROR_UNSPECIFIED;
+
+ /* *INDENT-OFF* */
+ 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;
+ }));
+ /* *INDENT-ON* */
+}
+
+static void
+send_policer_details (u8 * name,
+ sse2_qos_pol_cfg_params_st * config,
+ policer_read_response_type_st * templ,
+ unix_shared_memory_queue_t * q, u32 context)
+{
+ vl_api_policer_details_t *mp;
+
+ mp = vl_msg_api_alloc (sizeof (*mp));
+ memset (mp, 0, sizeof (*mp));
+ mp->_vl_msg_id = ntohs (VL_API_POLICER_DETAILS);
+ mp->context = context;
+ mp->cir = htonl (config->rb.kbps.cir_kbps);
+ mp->eir = htonl (config->rb.kbps.eir_kbps);
+ mp->cb = htonl (config->rb.kbps.cb_bytes);
+ mp->eb = htonl (config->rb.kbps.eb_bytes);
+ mp->rate_type = config->rate_type;
+ mp->round_type = config->rnd_type;
+ mp->type = config->rfc;
+ mp->conform_action_type = config->conform_action.action_type;
+ mp->conform_dscp = config->conform_action.dscp;
+ mp->exceed_action_type = config->exceed_action.action_type;
+ mp->exceed_dscp = config->exceed_action.dscp;
+ mp->violate_action_type = config->violate_action.action_type;
+ mp->violate_dscp = config->violate_action.dscp;
+ mp->single_rate = templ->single_rate ? 1 : 0;
+ mp->color_aware = templ->color_aware ? 1 : 0;
+ mp->scale = htonl (templ->scale);
+ mp->cir_tokens_per_period = htonl (templ->cir_tokens_per_period);
+ mp->pir_tokens_per_period = htonl (templ->pir_tokens_per_period);
+ mp->current_limit = htonl (templ->current_limit);
+ mp->current_bucket = htonl (templ->current_bucket);
+ mp->extended_limit = htonl (templ->extended_limit);
+ mp->extended_bucket = htonl (templ->extended_bucket);
+ mp->last_update_time = clib_host_to_net_u64 (templ->last_update_time);
+
+ strncpy ((char *) mp->name, (char *) name, ARRAY_LEN (mp->name) - 1);
+
+ vl_msg_api_send_shmem (q, (u8 *) & mp);
+}
+
+static void
+vl_api_policer_dump_t_handler (vl_api_policer_dump_t * mp)
+{
+ unix_shared_memory_queue_t *q;
+ vnet_policer_main_t *pm = &vnet_policer_main;
+ hash_pair_t *hp;
+ uword *p;
+ u32 pool_index;
+ u8 *match_name = 0;
+ u8 *name;
+ sse2_qos_pol_cfg_params_st *config;
+ policer_read_response_type_st *templ;
+
+ q = vl_api_client_index_to_input_queue (mp->client_index);
+ if (q == 0)
+ return;
+
+ if (mp->match_name_valid)
+ {
+ match_name = format (0, "%s%c", mp->match_name, 0);
+ }
+
+ if (mp->match_name_valid)
+ {
+ p = hash_get_mem (pm->policer_config_by_name, match_name);
+ if (p)
+ {
+ pool_index = p[0];
+ config = pool_elt_at_index (pm->configs, pool_index);
+ templ = pool_elt_at_index (pm->policer_templates, pool_index);
+ send_policer_details (match_name, config, templ, q, mp->context);
+ }
+ }
+ else
+ {
+ /* *INDENT-OFF* */
+ hash_foreach_pair (hp, pm->policer_config_by_name,
+ ({
+ name = (u8 *) hp->key;
+ pool_index = hp->value[0];
+ config = pool_elt_at_index (pm->configs, pool_index);
+ templ = pool_elt_at_index (pm->policer_templates, pool_index);
+ send_policer_details(name, config, templ, q, mp->context);
+ }));
+ /* *INDENT-ON* */
+ }
+}
+
+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)
+{
+ vlib_main_t *vm = vlib_get_main ();
+ vl_api_netmap_create_reply_t *rmp;
+ int rv = 0;
+ u8 *if_name = NULL;
+
+ if_name = format (0, "%s", mp->netmap_if_name);
+ vec_add1 (if_name, 0);
+
+ rv =
+ netmap_create_if (vm, if_name, mp->use_random_hw_addr ? 0 : mp->hw_addr,
+ mp->is_pipe, mp->is_master, 0);
+
+ vec_free (if_name);
+
+ REPLY_MACRO (VL_API_NETMAP_CREATE_REPLY);
+}
+
+static void
+vl_api_netmap_delete_t_handler (vl_api_netmap_delete_t * mp)
+{
+ vlib_main_t *vm = vlib_get_main ();
+ vl_api_netmap_delete_reply_t *rmp;
+ int rv = 0;
+ u8 *if_name = NULL;
+
+ if_name = format (0, "%s", mp->netmap_if_name);
+ vec_add1 (if_name, 0);
+
+ rv = netmap_delete_if (vm, if_name);
+
+ vec_free (if_name);
+
+ REPLY_MACRO (VL_API_NETMAP_DELETE_REPLY);
+}
+
+static void
+vl_api_mpls_gre_tunnel_details_t_handler (vl_api_mpls_gre_tunnel_details_t *
+ mp)
+{
+ clib_warning ("BUG");
+}
+
+static void
+send_mpls_gre_tunnel_entry (vpe_api_main_t * am,
+ unix_shared_memory_queue_t * q,
+ mpls_gre_tunnel_t * gt, u32 index, u32 context)
+{
+ vl_api_mpls_gre_tunnel_details_t *mp;
+ mpls_main_t *mm = &mpls_main;
+ mpls_encap_t *e;
+ int i;
+ u32 nlabels;
+
+ e = pool_elt_at_index (mm->encaps, gt->encap_index);
+ nlabels = vec_len (e->labels);
+
+ mp = vl_msg_api_alloc (sizeof (*mp) + nlabels * sizeof (u32));
+ memset (mp, 0, sizeof (*mp));
+ mp->_vl_msg_id = ntohs (VL_API_MPLS_GRE_TUNNEL_DETAILS);
+ mp->context = context;
+
+ mp->tunnel_index = htonl (index);
+ mp->tunnel_src = gt->tunnel_src.as_u32;
+ mp->tunnel_dst = gt->tunnel_dst.as_u32;
+ mp->intfc_address = gt->intfc_address.as_u32;
+ mp->mask_width = htonl (gt->mask_width);
+ mp->inner_fib_index = htonl (gt->inner_fib_index);
+ mp->outer_fib_index = htonl (gt->outer_fib_index);
+ mp->encap_index = htonl (gt->encap_index);
+ mp->hw_if_index = htonl (gt->hw_if_index);
+ mp->l2_only = htonl (gt->l2_only);
+ mp->nlabels = htonl (nlabels);
+
+ for (i = 0; i < nlabels; i++)
+ {
+ mp->labels[i] =
+ htonl (vnet_mpls_uc_get_label
+ (clib_host_to_net_u32 (e->labels[i].label_exp_s_ttl)));
+ }
+
+ vl_msg_api_send_shmem (q, (u8 *) & mp);
+}
+
+static void
+vl_api_mpls_gre_tunnel_dump_t_handler (vl_api_mpls_gre_tunnel_dump_t * mp)
+{
+ vpe_api_main_t *am = &vpe_api_main;
+ unix_shared_memory_queue_t *q;
+ mpls_main_t *mm = &mpls_main;
+ mpls_gre_tunnel_t *gt;
+ u32 index = ntohl (mp->tunnel_index);
+
+ q = vl_api_client_index_to_input_queue (mp->client_index);
+ if (q == 0)
+ return;
+
+ if (index != ~0)
+ {
+ if (!pool_is_free_index (mm->gre_tunnels, index))
+ {
+ gt = pool_elt_at_index (mm->gre_tunnels, index);
+ send_mpls_gre_tunnel_entry (am, q, gt, gt - mm->gre_tunnels,
+ mp->context);
+ }
+ }
+ else
+ {
+ /* *INDENT-OFF* */
+ pool_foreach (gt, mm->gre_tunnels,
+ ({
+ send_mpls_gre_tunnel_entry (am, q, gt, gt - mm->gre_tunnels,
+ mp->context);
+ }));
+ /* *INDENT-ON* */
+ }
+}
+
+static void
+vl_api_mpls_eth_tunnel_details_t_handler (vl_api_mpls_eth_tunnel_details_t *
+ mp)
+{
+ clib_warning ("BUG");
+}
+
+static void
+send_mpls_eth_tunnel_entry (vpe_api_main_t * am,
+ unix_shared_memory_queue_t * q,
+ mpls_eth_tunnel_t * et, u32 index, u32 context)
+{
+ mpls_main_t *mm = &mpls_main;
+ mpls_encap_t *e;
+ int i;
+ u32 nlabels;
+ vl_api_mpls_eth_tunnel_details_t *mp;
+
+ e = pool_elt_at_index (mm->encaps, et->encap_index);
+ nlabels = vec_len (e->labels);
+
+ mp = vl_msg_api_alloc (sizeof (*mp) + nlabels * sizeof (u32));
+ memset (mp, 0, sizeof (*mp));
+ mp->_vl_msg_id = ntohs (VL_API_MPLS_ETH_TUNNEL_DETAILS);
+ mp->context = context;
+
+ mp->tunnel_index = htonl (index);
+ memcpy (mp->tunnel_dst_mac, et->tunnel_dst, 6);
+ mp->intfc_address = et->intfc_address.as_u32;
+ mp->tx_sw_if_index = htonl (et->tx_sw_if_index);
+ mp->inner_fib_index = htonl (et->inner_fib_index);
+ mp->mask_width = htonl (et->mask_width);
+ mp->encap_index = htonl (et->encap_index);
+ mp->hw_if_index = htonl (et->hw_if_index);
+ mp->l2_only = htonl (et->l2_only);
+ mp->nlabels = htonl (nlabels);
+
+ for (i = 0; i < nlabels; i++)
+ {
+ mp->labels[i] =
+ htonl (vnet_mpls_uc_get_label
+ (clib_host_to_net_u32 (e->labels[i].label_exp_s_ttl)));
+ }
+
+ vl_msg_api_send_shmem (q, (u8 *) & mp);
+}
+
+static void
+vl_api_mpls_eth_tunnel_dump_t_handler (vl_api_mpls_eth_tunnel_dump_t * mp)
+{
+ vpe_api_main_t *am = &vpe_api_main;
+ unix_shared_memory_queue_t *q;
+ mpls_main_t *mm = &mpls_main;
+ mpls_eth_tunnel_t *et;
+ u32 index = ntohl (mp->tunnel_index);
+
+ q = vl_api_client_index_to_input_queue (mp->client_index);
+ if (q == 0)
+ return;
+
+ if (index != ~0)
+ {
+ if (!pool_is_free_index (mm->eth_tunnels, index))
+ {
+ et = pool_elt_at_index (mm->eth_tunnels, index);
+ send_mpls_eth_tunnel_entry (am, q, et, et - mm->eth_tunnels,
+ mp->context);
+ }
+ }
+ else
+ {
+ /* *INDENT-OFF* */
+ pool_foreach (et, mm->eth_tunnels,
+ ({
+ send_mpls_eth_tunnel_entry (am, q, et, et - mm->eth_tunnels,
+ mp->context);
+ }));
+ /* *INDENT-ON* */
+ }
+}
+
+static void
+vl_api_mpls_fib_encap_details_t_handler (vl_api_mpls_fib_encap_details_t * mp)
+{
+ clib_warning ("BUG");
+}
+
+static void
+send_mpls_fib_encap_details (vpe_api_main_t * am,
+ unix_shared_memory_queue_t * q,
+ show_mpls_fib_t * s, u32 context)
+{
+ vl_api_mpls_fib_encap_details_t *mp;
+ mpls_main_t *mm = &mpls_main;
+ mpls_encap_t *e;
+ int i;
+ u32 nlabels;
+
+ e = pool_elt_at_index (mm->encaps, s->entry_index);
+ nlabels = vec_len (e->labels);
+
+ mp = vl_msg_api_alloc (sizeof (*mp) + nlabels * sizeof (u32));
+ memset (mp, 0, sizeof (*mp));
+ mp->_vl_msg_id = ntohs (VL_API_MPLS_FIB_ENCAP_DETAILS);
+ mp->context = context;
+
+ mp->fib_index = htonl (s->fib_index);
+ mp->entry_index = htonl (s->entry_index);
+ mp->dest = s->dest;
+ mp->s_bit = htonl (s->s_bit);
+
+ mp->nlabels = htonl (nlabels);
+
+ for (i = 0; i < nlabels; i++)
+ {
+ mp->labels[i] =
+ htonl (vnet_mpls_uc_get_label
+ (clib_host_to_net_u32 (e->labels[i].label_exp_s_ttl)));
+ }
+
+ vl_msg_api_send_shmem (q, (u8 *) & mp);
+}
+
+static void
+vl_api_mpls_fib_encap_dump_t_handler (vl_api_mpls_fib_encap_dump_t * mp)
+{
+ vpe_api_main_t *am = &vpe_api_main;
+ unix_shared_memory_queue_t *q;
+ vlib_main_t *vm = &vlib_global_main;
+ u64 key;
+ u32 value;
+ show_mpls_fib_t *records = 0;
+ show_mpls_fib_t *s;
+ mpls_main_t *mm = &mpls_main;
+ ip4_fib_t *rx_fib;
+
+ q = vl_api_client_index_to_input_queue (mp->client_index);
+ if (q == 0)
+ return;
+
+ /* *INDENT-OFF* */
+ hash_foreach (key, value, mm->mpls_encap_by_fib_and_dest,
+ ({
+ vec_add2 (records, s, 1);
+ s->fib_index = (u32)(key>>32);
+ s->dest = (u32)(key & 0xFFFFFFFF);
+ s->entry_index = (u32) value;
+ }));
+ /* *INDENT-ON* */
+
+ if (0 == vec_len (records))
+ {
+ vlib_cli_output (vm, "MPLS encap table empty");
+ goto out;
+ }
+
+ /* sort output by dst address within fib */
+ vec_sort_with_function (records, mpls_dest_cmp);
+ vec_sort_with_function (records, mpls_fib_index_cmp);
+ vlib_cli_output (vm, "MPLS encap table");
+ vlib_cli_output (vm, "%=6s%=16s%=16s", "Table", "Dest address", "Labels");
+ vec_foreach (s, records)
+ {
+ rx_fib = ip4_fib_get (s->fib_index);
+ vlib_cli_output (vm, "%=6d%=16U%=16U", rx_fib->table_id,
+ format_ip4_address, &s->dest, format_mpls_encap_index,
+ mm, s->entry_index);
+ send_mpls_fib_encap_details (am, q, s, mp->context);
+ }
+
+out:
+ vec_free (records);
+}
+
+static void
+vl_api_mpls_fib_decap_details_t_handler (vl_api_mpls_fib_decap_details_t * mp)
+{
+ clib_warning ("BUG");
+}
+
+static void
+send_mpls_fib_decap_details (vpe_api_main_t * am,
+ unix_shared_memory_queue_t * q,
+ show_mpls_fib_t * s,
+ u32 rx_table_id,
+ u32 tx_table_id, char *swif_tag, u32 context)
+{
+ vl_api_mpls_fib_decap_details_t *mp;
+
+ mp = vl_msg_api_alloc (sizeof (*mp));
+ memset (mp, 0, sizeof (*mp));
+ mp->_vl_msg_id = ntohs (VL_API_MPLS_FIB_DECAP_DETAILS);
+ mp->context = context;
+
+ mp->fib_index = htonl (s->fib_index);
+ mp->entry_index = htonl (s->entry_index);
+ mp->dest = s->dest;
+ mp->s_bit = htonl (s->s_bit);
+ mp->label = htonl (s->label);
+ mp->rx_table_id = htonl (rx_table_id);
+ mp->tx_table_id = htonl (tx_table_id);
+ strncpy ((char *) mp->swif_tag,
+ (char *) swif_tag, ARRAY_LEN (mp->swif_tag) - 1);
+
+ vl_msg_api_send_shmem (q, (u8 *) & mp);
+}
+
+static void
+vl_api_mpls_fib_decap_dump_t_handler (vl_api_mpls_fib_decap_dump_t * mp)
+{
+ vpe_api_main_t *am = &vpe_api_main;
+ unix_shared_memory_queue_t *q;
+ vlib_main_t *vm = &vlib_global_main;
+ u64 key;
+ u32 value;
+ show_mpls_fib_t *records = 0;
+ show_mpls_fib_t *s;
+ mpls_main_t *mm = &mpls_main;
+ ip4_fib_t *rx_fib;
+ ip4_fib_t *tx_fib;
+ u32 tx_table_id;
+ char *swif_tag;
+
+ q = vl_api_client_index_to_input_queue (mp->client_index);
+ if (q == 0)
+ return;
+
+ /* *INDENT-OFF* */
+ hash_foreach (key, value, mm->mpls_decap_by_rx_fib_and_label,
+ ({
+ vec_add2 (records, s, 1);
+ s->fib_index = (u32)(key>>32);
+ s->entry_index = (u32) value;
+ s->label = ((u32) key)>>12;
+ s->s_bit = (key & (1<<8)) != 0;
+ }));
+ /* *INDENT-ON* */
+
+ if (!vec_len (records))
+ {
+ vlib_cli_output (vm, "MPLS decap table empty");
+ goto out;
+ }
+
+ vec_sort_with_function (records, mpls_label_cmp);
+ vlib_cli_output (vm, "MPLS decap table");
+ vlib_cli_output (vm, "%=10s%=15s%=6s%=6s", "RX Table", "TX Table/Intfc",
+ "Label", "S-bit");
+ vec_foreach (s, records)
+ {
+ mpls_decap_t *d;
+ d = pool_elt_at_index (mm->decaps, s->entry_index);
+ if (d->next_index == MPLS_LOOKUP_NEXT_IP4_INPUT)
+ {
+ tx_fib = ip4_fib_get (d->tx_fib_index);
+ tx_table_id = tx_fib->table_id;
+ swif_tag = " ";
+ }
+ else
+ {
+ tx_table_id = d->tx_fib_index;
+ swif_tag = "(i) ";
+ }
+ rx_fib = ip4_fib_get (s->fib_index);
+
+ vlib_cli_output (vm, "%=10d%=10d%=5s%=6d%=6d", rx_fib->table_id,
+ tx_table_id, swif_tag, s->label, s->s_bit);
+
+ send_mpls_fib_decap_details (am, q, s, rx_fib->table_id,
+ tx_table_id, swif_tag, mp->context);
+ }
+
+out:
+ vec_free (records);
+}
+
+static void
+vl_api_classify_table_ids_t_handler (vl_api_classify_table_ids_t * mp)
+{
+ unix_shared_memory_queue_t *q;
+
+ q = vl_api_client_index_to_input_queue (mp->client_index);
+ if (q == 0)
+ return;