/*
 *------------------------------------------------------------------
 * classify_api.c - classify api
 *
 * Copyright (c) 2016 Cisco and/or its affiliates.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *------------------------------------------------------------------
 */

#include <vnet/vnet.h>
#include <vlibmemory/api.h>

#include <vnet/interface.h>
#include <vnet/api_errno.h>

#include <vnet/classify/vnet_classify.h>
#include <vnet/classify/in_out_acl.h>
#include <vnet/classify/policer_classify.h>
#include <vnet/classify/flow_classify.h>
#include <vnet/l2/l2_classify.h>
#include <vnet/ip/ip6.h>
#include <vnet/ip/ip4.h>

#include <classify/classify.api_enum.h>
#include <classify/classify.api_types.h>

#define REPLY_MSG_ID_BASE msg_id_base
#include <vlibapi/api_helper_macros.h>

static u16 msg_id_base;

#define foreach_classify_add_del_table_field    \
_(table_index)                                  \
_(nbuckets)                                     \
_(memory_size)                                  \
_(skip_n_vectors)                               \
_(match_n_vectors)                              \
_(next_table_index)                             \
_(miss_next_index)                              \
_(mask_len)


static void vl_api_classify_pcap_lookup_table_t_handler
  (vl_api_classify_pcap_lookup_table_t * mp)
{
  vnet_classify_main_t *cm = &vnet_classify_main;
  vl_api_registration_t *reg;
  vl_api_classify_pcap_lookup_table_reply_t *rmp;
  int rv = 0;
  u32 table_index = ~0;

  reg = vl_api_client_index_to_registration (mp->client_index);
  if (!reg)
    return;

  u32 n_skip = ntohl (mp->skip_n_vectors);
  u32 n_match = ntohl (mp->match_n_vectors);
  u32 mask_len = ntohl (mp->mask_len);
  u32 sw_if_index = ntohl (mp->sw_if_index);

  if (n_skip > 5 || n_match == 0 || n_match > 5 ||
      mask_len != n_match * sizeof (u32x4) || sw_if_index == ~0 ||
      sw_if_index >= vec_len (cm->classify_table_index_by_sw_if_index))
    {
      rv = VNET_API_ERROR_INVALID_VALUE;
      goto out;
    }

  u32 table_chain;
  table_chain = classify_get_pcap_chain (cm, sw_if_index);

  u8 *mask_vec = 0;
  vec_validate (mask_vec, mask_len - 1);
  clib_memcpy (mask_vec, mp->mask, mask_len);

  if (table_chain != ~0)
    table_index = classify_lookup_chain (table_chain,
					 mask_vec, n_skip, n_match);

  vec_free (mask_vec);

out:
  rmp = vl_msg_api_alloc (sizeof (*rmp));
  rmp->_vl_msg_id =
    ntohs (REPLY_MSG_ID_BASE + VL_API_CLASSIFY_PCAP_LOOKUP_TABLE_REPLY);
  rmp->context = mp->context;
  rmp->retval = ntohl (rv);
  rmp->table_index = htonl (table_index);

  vl_api_send_msg (reg, (u8 *) rmp);
}

static void vl_api_classify_pcap_set_table_t_handler
  (vl_api_classify_pcap_set_table_t * mp)
{
  vnet_classify_main_t *cm = &vnet_classify_main;
  vl_api_classify_pcap_set_table_reply_t *rmp;
  vl_api_registration_t *reg;
  int rv = 0;

  reg = vl_api_client_index_to_registration (mp->client_index);
  if (!reg)
    return;

  u32 table_index = ntohl (mp->table_index);
  u32 sw_if_index = ntohl (mp->sw_if_index);

  if (sw_if_index == ~0 ||
      (table_index != ~0 && pool_is_free_index (cm->tables, table_index)))
    {
      rv = VNET_API_ERROR_INVALID_VALUE;
      goto out;
    }

  /*
   * Maybe reorder tables such that masks are most-specify to least-specific.
   */
  if (table_index != ~0 && mp->sort_masks)
    table_index = classify_sort_table_chain (cm, table_index);

  classify_set_pcap_chain (cm, sw_if_index, table_index);

out:
  rmp = vl_msg_api_alloc (sizeof (*rmp));
  rmp->_vl_msg_id =
    ntohs (REPLY_MSG_ID_BASE + VL_API_CLASSIFY_PCAP_SET_TABLE_REPLY);
  rmp->context = mp->context;
  rmp->retval = ntohl (rv);
  rmp->table_index = htonl (table_index);

  vl_api_send_msg (reg, (u8 *) rmp);
}

static void vl_api_classify_pcap_get_tables_t_handler
  (vl_api_classify_pcap_get_tables_t * mp)
{
  vnet_classify_main_t *cm = &vnet_classify_main;
  vl_api_classify_pcap_get_tables_reply_t *rmp;
  vl_api_registration_t *reg;
  int rv = 0;
  u32 *tables = 0;
  u32 count;

  reg = vl_api_client_index_to_registration (mp->client_index);
  if (!reg)
    return;

  u32 sw_if_index = ntohl (mp->sw_if_index);
  if (sw_if_index == ~0
      || sw_if_index >= vec_len (cm->classify_table_index_by_sw_if_index))
    {
      rv = VNET_API_ERROR_INVALID_VALUE;
      goto out;
    }

  u32 table_index = classify_get_pcap_chain (cm, sw_if_index);
  if (table_index == ~0)
    goto out;

  /*
   * Form a vector of all classifier tables in this chain.
   */
  vnet_classify_table_t *t;
  u32 i;

  for (i = table_index; i != ~0; i = t->next_table_index)
    {
      vec_add1 (tables, i);
      t = pool_elt_at_index (cm->tables, i);
    }

out:
  count = vec_len (tables);
  rmp = vl_msg_api_alloc_as_if_client (sizeof (*rmp) + count * sizeof (u32));
  rmp->_vl_msg_id =
    ntohs (REPLY_MSG_ID_BASE + VL_API_CLASSIFY_PCAP_GET_TABLES_REPLY);
  rmp->context = mp->context;
  rmp->retval = ntohl (rv);
  rmp->count = htonl (count);

  for (i = 0; i < count; ++i)
    {
      rmp->indices[i] = htonl (tables[i]);
    }

  vec_free (tables);

  vl_api_send_msg (reg, (u8 *) rmp);
}


static void vl_api_classify_trace_lookup_table_t_handler
  (vl_api_classify_trace_lookup_table_t * mp)
{
  vl_api_classify_trace_lookup_table_reply_t *rmp;
  vl_api_registration_t *reg;
  int rv = 0;
  u32 table_index = ~0;

  reg = vl_api_client_index_to_registration (mp->client_index);
  if (!reg)
    return;

  u32 n_skip = ntohl (mp->skip_n_vectors);
  u32 n_match = ntohl (mp->match_n_vectors);
  u32 mask_len = ntohl (mp->mask_len);
  if (n_skip > 5
      || n_match == 0 || n_match > 5 || mask_len != n_match * sizeof (u32x4))
    {
      rv = VNET_API_ERROR_INVALID_VALUE;
      goto out;
    }

  u32 table_chain;
  table_chain = classify_get_trace_chain ();

  u8 *mask_vec = 0;
  vec_validate (mask_vec, mask_len - 1);
  clib_memcpy (mask_vec, mp->mask, mask_len);

  if (table_chain != ~0)
    table_index = classify_lookup_chain (table_chain,
					 mask_vec, n_skip, n_match);
  vec_free (mask_vec);

out:
  rmp = vl_msg_api_alloc (sizeof (*rmp));
  rmp->_vl_msg_id =
    ntohs ((REPLY_MSG_ID_BASE + VL_API_CLASSIFY_TRACE_LOOKUP_TABLE_REPLY));
  rmp->context = mp->context;
  rmp->retval = ntohl (rv);
  rmp->table_index = htonl (table_index);

  vl_api_send_msg (reg, (u8 *) rmp);
}

static void vl_api_classify_trace_set_table_t_handler
  (vl_api_classify_trace_set_table_t * mp)
{
  vnet_classify_main_t *cm = &vnet_classify_main;
  vl_api_classify_trace_set_table_reply_t *rmp;
  vl_api_registration_t *reg;
  int rv = 0;

  reg = vl_api_client_index_to_registration (mp->client_index);
  if (!reg)
    return;

  u32 table_index = ntohl (mp->table_index);
  if (table_index != ~0 && pool_is_free_index (cm->tables, table_index))
    {
      rv = VNET_API_ERROR_INVALID_VALUE;
      goto out;
    }

  /*
   * Maybe reorder tables such that masks are most-specific to least-specific.
   */
  if (table_index != ~0 && mp->sort_masks)
    table_index = classify_sort_table_chain (cm, table_index);

  classify_set_trace_chain (cm, table_index);

out:
  rmp = vl_msg_api_alloc (sizeof (*rmp));
  rmp->_vl_msg_id =
    ntohs ((REPLY_MSG_ID_BASE + VL_API_CLASSIFY_TRACE_SET_TABLE_REPLY));
  rmp->context = mp->context;
  rmp->retval = ntohl (rv);
  rmp->table_index = htonl (table_index);

  vl_api_send_msg (reg, (u8 *) rmp);
}

static void vl_api_classify_trace_get_tables_t_handler
  (vl_api_classify_trace_get_tables_t * mp)
{
  vnet_classify_main_t *cm = &vnet_classify_main;
  vl_api_classify_trace_get_tables_reply_t *rmp;
  vl_api_registration_t *reg;
  int rv = 0;
  u32 *tables = 0;
  u32 count;

  reg = vl_api_client_index_to_registration (mp->client_index);
  if (!reg)
    return;

  u32 table_index = classify_get_trace_chain ();
  if (table_index == ~0)
    goto out;

  /*
   * Form a vector of all classifier tables in this chain.
   */
  vnet_classify_table_t *t;
  u32 i;

  for (i = table_index; i != ~0; i = t->next_table_index)
    {
      vec_add1 (tables, i);
      t = pool_elt_at_index (cm->tables, i);
    }

out:
  count = vec_len (tables);
  rmp = vl_msg_api_alloc_as_if_client (sizeof (*rmp) + count * sizeof (u32));
  rmp->_vl_msg_id =
    ntohs (REPLY_MSG_ID_BASE + VL_API_CLASSIFY_TRACE_GET_TABLES_REPLY);
  rmp->context = mp->context;
  rmp->retval = ntohl (rv);
  rmp->count = htonl (count);

  for (i = 0; i < count; ++i)
    {
      rmp->indices[i] = htonl (tables[i]);
    }

  vec_free (tables);

  vl_api_send_msg (reg, (u8 *) rmp);
}


static void vl_api_classify_add_del_table_t_handler
  (vl_api_classify_add_del_table_t * mp)
{
  vl_api_classify_add_del_table_reply_t *rmp;
  vnet_classify_main_t *cm = &vnet_classify_main;
  vnet_classify_table_t *t;
  int rv;

#define _(a) u32 a;
  foreach_classify_add_del_table_field;
#undef _

#define _(a) a = ntohl(mp->a);
  foreach_classify_add_del_table_field;
#undef _

  if (mask_len != match_n_vectors * sizeof (u32x4))
    {
      rv = VNET_API_ERROR_INVALID_VALUE;
      goto out;
    }

  /* The underlying API fails silently, on purpose, so check here */
  if (mp->is_add == 0)		/* delete */
    {
      if (pool_is_free_index (cm->tables, table_index))
	{
	  rv = VNET_API_ERROR_NO_SUCH_TABLE;
	  goto out;
	}
    }
  else				/* add or update */
    {
      if (table_index != ~0 && pool_is_free_index (cm->tables, table_index))
	table_index = ~0;
    }

  u8 current_data_flag = mp->current_data_flag;
  i16 current_data_offset = clib_net_to_host_i16 (mp->current_data_offset);

  rv = vnet_classify_add_del_table
    (cm, mp->mask, nbuckets, memory_size,
     skip_n_vectors, match_n_vectors,
     next_table_index, miss_next_index, &table_index,
     current_data_flag, current_data_offset, mp->is_add, mp->del_chain);

out:
  REPLY_MACRO2(VL_API_CLASSIFY_ADD_DEL_TABLE_REPLY,
  ({
    if (rv == 0 && mp->is_add)
      {
        t = pool_elt_at_index (cm->tables, table_index);
        rmp->skip_n_vectors = htonl(t->skip_n_vectors);
        rmp->match_n_vectors = htonl(t->match_n_vectors);
        rmp->new_table_index = htonl(table_index);
      }
    else
      {
        rmp->skip_n_vectors = ~0;
        rmp->match_n_vectors = ~0;
        rmp->new_table_index = ~0;
      }
  }));
}

static void vl_api_classify_add_del_session_t_handler
  (vl_api_classify_add_del_session_t * mp)
{
  vnet_classify_main_t *cm = &vnet_classify_main;
  vl_api_classify_add_del_session_reply_t *rmp;
  int rv;
  u32 table_index, hit_next_index, opaque_index, metadata, match_len;
  i32 advance;
  u8 action;
  vnet_classify_table_t *t;

  table_index = ntohl (mp->table_index);
  hit_next_index = ntohl (mp->hit_next_index);
  opaque_index = ntohl (mp->opaque_index);
  advance = ntohl (mp->advance);
  action = mp->action;
  metadata = ntohl (mp->metadata);
  match_len = ntohl (mp->match_len);

  if (pool_is_free_index (cm->tables, table_index))
    {
      rv = VNET_API_ERROR_NO_SUCH_TABLE;
      goto out;
    }

  t = pool_elt_at_index (cm->tables, table_index);

  if (match_len != (t->skip_n_vectors + t->match_n_vectors) * sizeof (u32x4))
    {
      rv = VNET_API_ERROR_INVALID_VALUE;
      goto out;
    }

  rv = vnet_classify_add_del_session
    (cm, table_index, mp->match, hit_next_index, opaque_index,
     advance, action, metadata, mp->is_add);

out:
  REPLY_MACRO (VL_API_CLASSIFY_ADD_DEL_SESSION_REPLY);
}

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, vl_api_registration_t * reg,
			       u32 context)
{
  vl_api_policer_classify_details_t *mp;

  mp = vl_msg_api_alloc (sizeof (*mp));
  clib_memset (mp, 0, sizeof (*mp));
  mp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_POLICER_CLASSIFY_DETAILS);
  mp->context = context;
  mp->sw_if_index = htonl (sw_if_index);
  mp->table_index = htonl (table_index);

  vl_api_send_msg (reg, (u8 *) mp);
}

static void
vl_api_policer_classify_dump_t_handler (vl_api_policer_classify_dump_t * mp)
{
  vl_api_registration_t *reg;
  policer_classify_main_t *pcm = &policer_classify_main;
  u32 *vec_tbl;
  int i;
  u32 filter_sw_if_index;

  reg = vl_api_client_index_to_registration (mp->client_index);
  if (!reg)
    return;

  filter_sw_if_index = ntohl (mp->sw_if_index);
  if (filter_sw_if_index
      >= vec_len (pcm->classify_table_index_by_sw_if_index[mp->type]))
    return;

  if (filter_sw_if_index != ~0)
    vec_tbl =
      &pcm->classify_table_index_by_sw_if_index[mp->type][filter_sw_if_index];
  else
    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), reg,
					 mp->context);
	}
    }
}

static void
vl_api_classify_table_ids_t_handler (vl_api_classify_table_ids_t * mp)
{
  vl_api_registration_t *reg;

  reg = vl_api_client_index_to_registration (mp->client_index);
  if (!reg)
    return;

  vnet_classify_main_t *cm = &vnet_classify_main;
  vnet_classify_table_t *t;
  u32 *table_ids = 0;
  u32 count;

   pool_foreach (t, cm->tables)
    {
     vec_add1 (table_ids, ntohl(t - cm->tables));
   }
  count = vec_len (table_ids);

  vl_api_classify_table_ids_reply_t *rmp;
  rmp = vl_msg_api_alloc_as_if_client (sizeof (*rmp) + count * sizeof (u32));
  rmp->_vl_msg_id =
    ntohs (REPLY_MSG_ID_BASE + VL_API_CLASSIFY_TABLE_IDS_REPLY);
  rmp->context = mp->context;
  rmp->count = ntohl (count);
  clib_memcpy (rmp->ids, table_ids, count * sizeof (u32));
  rmp->retval = 0;

  vl_api_send_msg (reg, (u8 *) rmp);

  vec_free (table_ids);
}

static void
  vl_api_classify_table_by_interface_t_handler
  (vl_api_classify_table_by_interface_t * mp)
{
  vl_api_classify_table_by_interface_reply_t *rmp;
  int rv = 0;

  u32 sw_if_index = ntohl (mp->sw_if_index);
  u32 *acl = 0;

  vec_validate (acl, IN_OUT_ACL_N_TABLES - 1);
  vec_set (acl, ~0);

  VALIDATE_SW_IF_INDEX (mp);

  in_out_acl_main_t *am = &in_out_acl_main;

  int if_idx;
  u32 type;

  for (type = 0; type < IN_OUT_ACL_N_TABLES; type++)
    {
      u32 *vec_tbl =
	am->classify_table_index_by_sw_if_index[IN_OUT_ACL_INPUT_TABLE_GROUP]
	[type];
      if (vec_len (vec_tbl))
	{
	  for (if_idx = 0; if_idx < vec_len (vec_tbl); if_idx++)
	    {
	      if (vec_elt (vec_tbl, if_idx) == ~0 || sw_if_index != if_idx)
		{
		  continue;
		}
	      acl[type] = vec_elt (vec_tbl, if_idx);
	    }
	}
    }

  BAD_SW_IF_INDEX_LABEL;

   REPLY_MACRO2(VL_API_CLASSIFY_TABLE_BY_INTERFACE_REPLY,
   ({
     rmp->sw_if_index = ntohl(sw_if_index);
     rmp->l2_table_id = ntohl(acl[IN_OUT_ACL_TABLE_L2]);
     rmp->ip4_table_id = ntohl(acl[IN_OUT_ACL_TABLE_IP4]);
     rmp->ip6_table_id = ntohl(acl[IN_OUT_ACL_TABLE_IP6]);
   }));
  vec_free (acl);
}

static void
vl_api_classify_table_info_t_handler (vl_api_classify_table_info_t * mp)
{
  vl_api_registration_t *reg;

  reg = vl_api_client_index_to_registration (mp->client_index);
  if (!reg)
    return;

  vl_api_classify_table_info_reply_t *rmp = 0;

  vnet_classify_main_t *cm = &vnet_classify_main;
  u32 table_id = ntohl (mp->table_id);
  vnet_classify_table_t *t;

  pool_foreach (t, cm->tables)
    {
      if (table_id == t - cm->tables)
	{
	  rmp = vl_msg_api_alloc_as_if_client (
	    sizeof (*rmp) + t->match_n_vectors * sizeof (u32x4));
	  rmp->_vl_msg_id =
	    ntohs (REPLY_MSG_ID_BASE + VL_API_CLASSIFY_TABLE_INFO_REPLY);
	  rmp->context = mp->context;
	  rmp->table_id = ntohl (table_id);
	  rmp->nbuckets = ntohl (t->nbuckets);
	  rmp->match_n_vectors = ntohl (t->match_n_vectors);
	  rmp->skip_n_vectors = ntohl (t->skip_n_vectors);
	  rmp->active_sessions = ntohl (t->active_elements);
	  rmp->next_table_index = ntohl (t->next_table_index);
	  rmp->miss_next_index = ntohl (t->miss_next_index);
	  rmp->mask_length = ntohl (t->match_n_vectors * sizeof (u32x4));
	  clib_memcpy (rmp->mask, t->mask,
		       t->match_n_vectors * sizeof (u32x4));
	  rmp->retval = 0;
	  break;
	}
    }

  if (rmp == 0)
    {
      rmp = vl_msg_api_alloc (sizeof (*rmp));
      rmp->_vl_msg_id =
	ntohs (REPLY_MSG_ID_BASE + VL_API_CLASSIFY_TABLE_INFO_REPLY);
      rmp->context = mp->context;
      rmp->retval = ntohl (VNET_API_ERROR_CLASSIFY_TABLE_NOT_FOUND);
    }

  vl_api_send_msg (reg, (u8 *) rmp);
}

static void
send_classify_session_details (vl_api_registration_t * reg,
			       u32 table_id,
			       u32 match_length,
			       vnet_classify_entry_t * e, u32 context)
{
  vl_api_classify_session_details_t *rmp;

  rmp = vl_msg_api_alloc (sizeof (*rmp) + match_length);
  clib_memset (rmp, 0, sizeof (*rmp));
  rmp->_vl_msg_id =
    ntohs (REPLY_MSG_ID_BASE + VL_API_CLASSIFY_SESSION_DETAILS);
  rmp->context = context;
  rmp->table_id = ntohl (table_id);
  rmp->hit_next_index = ntohl (e->next_index);
  rmp->advance = ntohl (e->advance);
  rmp->opaque_index = ntohl (e->opaque_index);
  rmp->match_length = ntohl (match_length);
  clib_memcpy (rmp->match, e->key, match_length);

  vl_api_send_msg (reg, (u8 *) rmp);
}

static void
vl_api_classify_session_dump_t_handler (vl_api_classify_session_dump_t * mp)
{
  vnet_classify_main_t *cm = &vnet_classify_main;
  vl_api_registration_t *reg;

  u32 table_id = ntohl (mp->table_id);
  vnet_classify_table_t *t;

  reg = vl_api_client_index_to_registration (mp->client_index);
  if (!reg)
    return;

  pool_foreach (t, cm->tables)
   {
    if (table_id == t - cm->tables)
      {
        vnet_classify_bucket_t * b;
        vnet_classify_entry_t * v, * save_v;
        int i, j, k;

        for (i = 0; i < t->nbuckets; i++)
          {
            b = &t->buckets [i];
            if (b->offset == 0)
              continue;

            save_v = vnet_classify_get_entry (t, b->offset);
            for (j = 0; j < (1<<b->log2_pages); j++)
              {
                for (k = 0; k < t->entries_per_page; k++)
                  {
                    v = vnet_classify_entry_at_index
                      (t, save_v, j*t->entries_per_page + k);
                    if (vnet_classify_entry_is_free (v))
                      continue;

                    send_classify_session_details
                      (reg, table_id, t->match_n_vectors * sizeof (u32x4),
                       v, mp->context);
                  }
              }
          }
        break;
      }
  }
}

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, vl_api_registration_t * reg,
			    u32 context)
{
  vl_api_flow_classify_details_t *mp;

  mp = vl_msg_api_alloc (sizeof (*mp));
  clib_memset (mp, 0, sizeof (*mp));
  mp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_FLOW_CLASSIFY_DETAILS);
  mp->context = context;
  mp->sw_if_index = htonl (sw_if_index);
  mp->table_index = htonl (table_index);

  vl_api_send_msg (reg, (u8 *) mp);
}

static void
vl_api_flow_classify_dump_t_handler (vl_api_flow_classify_dump_t * mp)
{
  vl_api_registration_t *reg;
  flow_classify_main_t *pcm = &flow_classify_main;
  u32 *vec_tbl;
  int i;
  u32 filter_sw_if_index;

  reg = vl_api_client_index_to_registration (mp->client_index);
  if (!reg)
    return;

  filter_sw_if_index = ntohl (mp->sw_if_index);
  if (filter_sw_if_index
      >= vec_len (pcm->classify_table_index_by_sw_if_index[mp->type]))
    return;

  if (filter_sw_if_index != ~0)
    vec_tbl =
      &pcm->classify_table_index_by_sw_if_index[mp->type][filter_sw_if_index];
  else
    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), reg,
				      mp->context);
	}
    }
}

static void vl_api_classify_set_interface_ip_table_t_handler
  (vl_api_classify_set_interface_ip_table_t * mp)
{
  vlib_main_t *vm = vlib_get_main ();
  vl_api_classify_set_interface_ip_table_reply_t *rmp;
  int rv;

  VALIDATE_SW_IF_INDEX (mp);

  u32 table_index = ntohl (mp->table_index);
  u32 sw_if_index = ntohl (mp->sw_if_index);

  if (mp->is_ipv6)
    rv = vnet_set_ip6_classify_intfc (vm, sw_if_index, table_index);
  else
    rv = vnet_set_ip4_classify_intfc (vm, sw_if_index, table_index);

  BAD_SW_IF_INDEX_LABEL;

  REPLY_MACRO (VL_API_CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY);
}

static void vl_api_classify_set_interface_l2_tables_t_handler
  (vl_api_classify_set_interface_l2_tables_t * mp)
{
  vl_api_classify_set_interface_l2_tables_reply_t *rmp;
  int rv;
  u32 sw_if_index, ip4_table_index, ip6_table_index, other_table_index;
  int enable;

  ip4_table_index = ntohl (mp->ip4_table_index);
  ip6_table_index = ntohl (mp->ip6_table_index);
  other_table_index = ntohl (mp->other_table_index);
  sw_if_index = ntohl (mp->sw_if_index);

  VALIDATE_SW_IF_INDEX (mp);

  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)
    {
      if (ip4_table_index != ~0 || ip6_table_index != ~0
	  || other_table_index != ~0)
	enable = 1;
      else
	enable = 0;

      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;

  REPLY_MACRO (VL_API_CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY);
}

static void vl_api_input_acl_set_interface_t_handler
  (vl_api_input_acl_set_interface_t * mp)
{
  vlib_main_t *vm = vlib_get_main ();
  vl_api_input_acl_set_interface_reply_t *rmp;
  int rv;

  VALIDATE_SW_IF_INDEX (mp);

  u32 ip4_table_index = ntohl (mp->ip4_table_index);
  u32 ip6_table_index = ntohl (mp->ip6_table_index);
  u32 l2_table_index = ntohl (mp->l2_table_index);
  u32 sw_if_index = ntohl (mp->sw_if_index);

  rv = vnet_set_input_acl_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_INPUT_ACL_SET_INTERFACE_REPLY);
}

static void
vl_api_punt_acl_add_del_t_handler (vl_api_punt_acl_add_del_t *mp)
{
  vlib_main_t *vm = vlib_get_main ();
  vl_api_punt_acl_add_del_reply_t *rmp;
  int rv;

  rv = vnet_set_in_out_acl_intfc (
    vm, 0 /* sw_if_index */, ~0 /* ip4_table_index */,
    ~0 /* ip6_table_index */, ~0 /* l2_table_index */,
    ntohl (mp->ip4_table_index), ntohl (mp->ip6_table_index), mp->is_add,
    0 /* is_output */);

  REPLY_MACRO (VL_API_PUNT_ACL_ADD_DEL_REPLY);
}

static void
vl_api_punt_acl_get_t_handler (vl_api_punt_acl_get_t *mp)
{
  vl_api_punt_acl_get_reply_t *rmp;
  int rv = 0;

  const in_out_acl_main_t *am = &in_out_acl_main;

  u32 *const *tables =
    am->classify_table_index_by_sw_if_index[IN_OUT_ACL_INPUT_TABLE_GROUP];
  const u32 *ip4_table = tables[IN_OUT_ACL_TABLE_IP4_PUNT];
  const u32 *ip6_table = tables[IN_OUT_ACL_TABLE_IP6_PUNT];
  const u32 ip4_table_index = vec_len (ip4_table) ? ip4_table[0] : ~0;
  const u32 ip6_table_index = vec_len (ip6_table) ? ip6_table[0] : ~0;

  REPLY_MACRO2 (VL_API_PUNT_ACL_GET_REPLY, ({
		  rmp->ip4_table_index = ntohl (ip4_table_index);
		  rmp->ip6_table_index = ntohl (ip6_table_index);
		}));
}

static void vl_api_output_acl_set_interface_t_handler
  (vl_api_output_acl_set_interface_t * mp)
{
  vlib_main_t *vm = vlib_get_main ();
  vl_api_output_acl_set_interface_reply_t *rmp;
  int rv;

  VALIDATE_SW_IF_INDEX (mp);

  u32 ip4_table_index = ntohl (mp->ip4_table_index);
  u32 ip6_table_index = ntohl (mp->ip6_table_index);
  u32 l2_table_index = ntohl (mp->l2_table_index);
  u32 sw_if_index = ntohl (mp->sw_if_index);

  rv = vnet_set_output_acl_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_OUTPUT_ACL_SET_INTERFACE_REPLY);
}

#include <classify/classify.api.c>

static clib_error_t *
classify_api_hookup (vlib_main_t * vm)
{
  api_main_t *am = vlibapi_get_main ();

  /*
   * Trace space for classifier mask+match
   */
  vl_api_increase_msg_trace_size (am, VL_API_CLASSIFY_ADD_DEL_TABLE,
				  5 * sizeof (u32x4));
  vl_api_increase_msg_trace_size (am, VL_API_CLASSIFY_ADD_DEL_SESSION,
				  5 * sizeof (u32x4));

  /*
   * Set up the (msg_name, crc, message-id) table
   */
  msg_id_base = setup_message_id_table ();

  return 0;
}

VLIB_API_INIT_FUNCTION (classify_api_hookup);

/*
 * fd.io coding-style-patch-verification: ON
 *
 * Local Variables:
 * eval: (c-set-style "gnu")
 * End:
 */
