/*
 * Copyright (c) 2015-2019 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/session/application.h>
#include <vnet/session/application_interface.h>
#include <vnet/session/application_local.h>
#include <vnet/session/session_rules_table.h>
#include <vnet/session/session_table.h>
#include <vnet/session/session.h>

#include <vnet/vnet_msg_enum.h>

#define vl_typedefs		/* define message structures */
#include <vnet/vnet_all_api_h.h>
#undef vl_typedefs

#define vl_endianfun		/* define message structures */
#include <vnet/vnet_all_api_h.h>
#undef vl_endianfun

/* instantiate all the print functions we know about */
#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
#define vl_printfun
#include <vnet/vnet_all_api_h.h>
#undef vl_printfun

#include <vlibapi/api_helper_macros.h>

#define foreach_session_api_msg                                         \
_(MAP_ANOTHER_SEGMENT_REPLY, map_another_segment_reply)                 \
_(APPLICATION_ATTACH, application_attach)				\
_(APP_ATTACH, app_attach)						\
_(APPLICATION_DETACH, application_detach)				\
_(BIND_URI, bind_uri)                                                   \
_(UNBIND_URI, unbind_uri)                                               \
_(CONNECT_URI, connect_uri)                                             \
_(DISCONNECT_SESSION, disconnect_session)                               \
_(DISCONNECT_SESSION_REPLY, disconnect_session_reply)                   \
_(BIND_SOCK, bind_sock)							\
_(UNBIND_SOCK, unbind_sock)                                             \
_(CONNECT_SOCK, connect_sock)                                          	\
_(SESSION_ENABLE_DISABLE, session_enable_disable)                   	\
_(APP_NAMESPACE_ADD_DEL, app_namespace_add_del)				\
_(SESSION_RULE_ADD_DEL, session_rule_add_del)				\
_(SESSION_RULES_DUMP, session_rules_dump)				\
_(APPLICATION_TLS_CERT_ADD, application_tls_cert_add)			\
_(APPLICATION_TLS_KEY_ADD, application_tls_key_add)			\
_(APP_ADD_CERT_KEY_PAIR, app_add_cert_key_pair)				\
_(APP_DEL_CERT_KEY_PAIR, app_del_cert_key_pair)				\
_(APP_WORKER_ADD_DEL, app_worker_add_del)				\

static int
session_send_fds (vl_api_registration_t * reg, int fds[], int n_fds)
{
  clib_error_t *error;
  if (vl_api_registration_file_index (reg) == VL_API_INVALID_FI)
    {
      clib_warning ("can't send memfd fd");
      return -1;
    }
  error = vl_api_send_fd_msg (reg, fds, n_fds);
  if (error)
    {
      clib_error_report (error);
      return -1;
    }
  return 0;
}

/* ### WILL BE DEPRECATED POST 20.01 ### */
static int
send_add_segment_callback (u32 api_client_index, u64 segment_handle)
{
  int fds[SESSION_N_FD_TYPE], n_fds = 0;
  vl_api_map_another_segment_t *mp;
  vl_api_registration_t *reg;
  fifo_segment_t *fs;
  ssvm_private_t *sp;
  u8 fd_flags = 0;

  reg = vl_mem_api_client_index_to_registration (api_client_index);
  if (!reg)
    {
      clib_warning ("no api registration for client: %u", api_client_index);
      return -1;
    }

  fs = segment_manager_get_segment_w_handle (segment_handle);
  sp = &fs->ssvm;
  if (ssvm_type (sp) == SSVM_SEGMENT_MEMFD)
    {
      if (vl_api_registration_file_index (reg) == VL_API_INVALID_FI)
	{
	  clib_warning ("can't send memfd fd");
	  return -1;
	}

      fd_flags |= SESSION_FD_F_MEMFD_SEGMENT;
      fds[n_fds] = sp->fd;
      n_fds += 1;
    }

  mp = vl_mem_api_alloc_as_if_client_w_reg (reg, sizeof (*mp));
  clib_memset (mp, 0, sizeof (*mp));
  mp->_vl_msg_id = clib_host_to_net_u16 (VL_API_MAP_ANOTHER_SEGMENT);
  mp->segment_size = sp->ssvm_size;
  mp->fd_flags = fd_flags;
  mp->segment_handle = clib_host_to_net_u64 (segment_handle);
  strncpy ((char *) mp->segment_name, (char *) sp->name,
	   sizeof (mp->segment_name) - 1);

  vl_msg_api_send_shmem (reg->vl_input_queue, (u8 *) & mp);

  if (n_fds)
    return session_send_fds (reg, fds, n_fds);

  return 0;
}

/* ### WILL BE DEPRECATED POST 20.01 ### */
static int
send_del_segment_callback (u32 api_client_index, u64 segment_handle)
{
  vl_api_unmap_segment_t *mp;
  vl_api_registration_t *reg;

  reg = vl_mem_api_client_index_to_registration (api_client_index);
  if (!reg)
    {
      clib_warning ("no registration: %u", api_client_index);
      return -1;
    }

  mp = vl_mem_api_alloc_as_if_client_w_reg (reg, sizeof (*mp));
  clib_memset (mp, 0, sizeof (*mp));
  mp->_vl_msg_id = clib_host_to_net_u16 (VL_API_UNMAP_SEGMENT);
  mp->segment_handle = clib_host_to_net_u64 (segment_handle);
  vl_msg_api_send_shmem (reg->vl_input_queue, (u8 *) & mp);

  return 0;
}

static int
mq_try_lock_and_alloc_msg (svm_msg_q_t * app_mq, svm_msg_q_msg_t * msg)
{
  int rv;
  u8 try = 0;
  while (try < 100)
    {
      rv = svm_msg_q_lock_and_alloc_msg_w_ring (app_mq,
						SESSION_MQ_CTRL_EVT_RING,
						SVM_Q_NOWAIT, msg);
      if (!rv)
	return 0;
      try++;
      usleep (1);
    }
  clib_warning ("failed to alloc msg");
  return -1;
}

static int
mq_send_session_accepted_cb (session_t * s)
{
  app_worker_t *app_wrk = app_worker_get (s->app_wrk_index);
  svm_msg_q_msg_t _msg, *msg = &_msg;
  svm_msg_q_t *vpp_queue, *app_mq;
  session_t *listener;
  session_accepted_msg_t *mp;
  session_event_t *evt;
  application_t *app;

  app = application_get (app_wrk->app_index);
  app_mq = app_wrk->event_queue;
  if (mq_try_lock_and_alloc_msg (app_mq, msg))
    return -1;

  evt = svm_msg_q_msg_data (app_mq, msg);
  clib_memset (evt, 0, sizeof (*evt));
  evt->event_type = SESSION_CTRL_EVT_ACCEPTED;
  mp = (session_accepted_msg_t *) evt->data;
  clib_memset (mp, 0, sizeof (*mp));
  mp->context = app->app_index;
  mp->server_rx_fifo = pointer_to_uword (s->rx_fifo);
  mp->server_tx_fifo = pointer_to_uword (s->tx_fifo);
  mp->segment_handle = session_segment_handle (s);
  mp->flags = s->flags;

  if (session_has_transport (s))
    {
      listener = listen_session_get_from_handle (s->listener_handle);
      mp->listener_handle = app_listen_session_handle (listener);
      if (application_is_proxy (app))
	{
	  listener =
	    app_worker_first_listener (app_wrk, session_get_fib_proto (s),
				       session_get_transport_proto (s));
	  if (listener)
	    mp->listener_handle = listen_session_get_handle (listener);
	}
      vpp_queue = session_main_get_vpp_event_queue (s->thread_index);
      mp->vpp_event_queue_address = pointer_to_uword (vpp_queue);
      mp->handle = session_handle (s);

      session_get_endpoint (s, &mp->rmt, 0 /* is_lcl */ );
    }
  else
    {
      ct_connection_t *ct;

      ct = (ct_connection_t *) session_get_transport (s);
      listener = listen_session_get_from_handle (s->listener_handle);
      mp->listener_handle = app_listen_session_handle (listener);
      mp->rmt.is_ip4 = session_type_is_ip4 (listener->session_type);
      mp->rmt.port = ct->c_rmt_port;
      mp->handle = session_handle (s);
      vpp_queue = session_main_get_vpp_event_queue (0);
      mp->vpp_event_queue_address = pointer_to_uword (vpp_queue);
    }
  svm_msg_q_add_and_unlock (app_mq, msg);

  return 0;
}

static inline void
mq_send_session_close_evt (app_worker_t * app_wrk, session_handle_t sh,
			   session_evt_type_t evt_type)
{
  svm_msg_q_msg_t _msg, *msg = &_msg;
  session_disconnected_msg_t *mp;
  svm_msg_q_t *app_mq;
  session_event_t *evt;

  app_mq = app_wrk->event_queue;
  if (mq_try_lock_and_alloc_msg (app_mq, msg))
    return;
  evt = svm_msg_q_msg_data (app_mq, msg);
  clib_memset (evt, 0, sizeof (*evt));
  evt->event_type = evt_type;
  mp = (session_disconnected_msg_t *) evt->data;
  mp->handle = sh;
  mp->context = app_wrk->api_client_index;
  svm_msg_q_add_and_unlock (app_mq, msg);
}

static inline void
mq_notify_close_subscribers (u32 app_index, session_handle_t sh,
			     svm_fifo_t * f, session_evt_type_t evt_type)
{
  app_worker_t *app_wrk;
  application_t *app;
  int i;

  app = application_get (app_index);
  if (!app)
    return;

  for (i = 0; i < f->n_subscribers; i++)
    {
      if (!(app_wrk = application_get_worker (app, f->subscribers[i])))
	continue;
      mq_send_session_close_evt (app_wrk, sh, SESSION_CTRL_EVT_DISCONNECTED);
    }
}

static void
mq_send_session_disconnected_cb (session_t * s)
{
  app_worker_t *app_wrk = app_worker_get (s->app_wrk_index);
  session_handle_t sh = session_handle (s);

  mq_send_session_close_evt (app_wrk, session_handle (s),
			     SESSION_CTRL_EVT_DISCONNECTED);

  if (svm_fifo_n_subscribers (s->rx_fifo))
    mq_notify_close_subscribers (app_wrk->app_index, sh, s->rx_fifo,
				 SESSION_CTRL_EVT_DISCONNECTED);
}

static void
mq_send_session_reset_cb (session_t * s)
{
  app_worker_t *app_wrk = app_worker_get (s->app_wrk_index);
  session_handle_t sh = session_handle (s);

  mq_send_session_close_evt (app_wrk, sh, SESSION_CTRL_EVT_RESET);

  if (svm_fifo_n_subscribers (s->rx_fifo))
    mq_notify_close_subscribers (app_wrk->app_index, sh, s->rx_fifo,
				 SESSION_CTRL_EVT_RESET);
}

int
mq_send_session_connected_cb (u32 app_wrk_index, u32 api_context,
			      session_t * s, u8 is_fail)
{
  svm_msg_q_msg_t _msg, *msg = &_msg;
  session_connected_msg_t *mp;
  svm_msg_q_t *vpp_mq, *app_mq;
  transport_connection_t *tc;
  app_worker_t *app_wrk;
  session_event_t *evt;

  app_wrk = app_worker_get (app_wrk_index);
  app_mq = app_wrk->event_queue;
  if (!app_mq)
    {
      clib_warning ("app %u with api index: %u not attached",
		    app_wrk->app_index, app_wrk->api_client_index);
      return -1;
    }

  if (mq_try_lock_and_alloc_msg (app_mq, msg))
    return -1;

  evt = svm_msg_q_msg_data (app_mq, msg);
  clib_memset (evt, 0, sizeof (*evt));
  evt->event_type = SESSION_CTRL_EVT_CONNECTED;
  mp = (session_connected_msg_t *) evt->data;
  clib_memset (mp, 0, sizeof (*mp));
  mp->context = api_context;

  if (is_fail)
    goto done;

  if (session_has_transport (s))
    {
      tc = session_get_transport (s);
      if (!tc)
	{
	  is_fail = 1;
	  goto done;
	}

      vpp_mq = session_main_get_vpp_event_queue (s->thread_index);
      mp->handle = session_handle (s);
      mp->vpp_event_queue_address = pointer_to_uword (vpp_mq);

      session_get_endpoint (s, &mp->lcl, 1 /* is_lcl */ );

      mp->server_rx_fifo = pointer_to_uword (s->rx_fifo);
      mp->server_tx_fifo = pointer_to_uword (s->tx_fifo);
      mp->segment_handle = session_segment_handle (s);
    }
  else
    {
      ct_connection_t *cct;
      session_t *ss;

      cct = (ct_connection_t *) session_get_transport (s);
      mp->handle = session_handle (s);
      mp->lcl.port = cct->c_lcl_port;
      mp->lcl.is_ip4 = cct->c_is_ip4;
      vpp_mq = session_main_get_vpp_event_queue (0);
      mp->vpp_event_queue_address = pointer_to_uword (vpp_mq);
      mp->server_rx_fifo = pointer_to_uword (s->rx_fifo);
      mp->server_tx_fifo = pointer_to_uword (s->tx_fifo);
      mp->segment_handle = session_segment_handle (s);
      ss = ct_session_get_peer (s);
      mp->ct_rx_fifo = pointer_to_uword (ss->tx_fifo);
      mp->ct_tx_fifo = pointer_to_uword (ss->rx_fifo);
      mp->ct_segment_handle = session_segment_handle (ss);
    }

done:
  mp->retval = is_fail ?
    clib_host_to_net_u32 (VNET_API_ERROR_SESSION_CONNECT) : 0;

  svm_msg_q_add_and_unlock (app_mq, msg);
  return 0;
}

int
mq_send_session_bound_cb (u32 app_wrk_index, u32 api_context,
			  session_handle_t handle, int rv)
{
  svm_msg_q_msg_t _msg, *msg = &_msg;
  svm_msg_q_t *app_mq, *vpp_evt_q;
  transport_endpoint_t tep;
  session_bound_msg_t *mp;
  app_worker_t *app_wrk;
  session_event_t *evt;
  app_listener_t *al;
  session_t *ls = 0;
  app_wrk = app_worker_get (app_wrk_index);
  app_mq = app_wrk->event_queue;
  if (!app_mq)
    {
      clib_warning ("app %u with api index: %u not attached",
		    app_wrk->app_index, app_wrk->api_client_index);
      return -1;
    }

  if (mq_try_lock_and_alloc_msg (app_mq, msg))
    return -1;

  evt = svm_msg_q_msg_data (app_mq, msg);
  clib_memset (evt, 0, sizeof (*evt));
  evt->event_type = SESSION_CTRL_EVT_BOUND;
  mp = (session_bound_msg_t *) evt->data;
  mp->context = api_context;

  if (rv)
    goto done;

  mp->handle = handle;
  al = app_listener_get_w_handle (handle);
  if (al->session_index != SESSION_INVALID_INDEX)
    ls = app_listener_get_session (al);
  else
    ls = app_listener_get_local_session (al);

  session_get_endpoint (ls, &tep, 1 /* is_lcl */ );
  mp->lcl_port = tep.port;
  mp->lcl_is_ip4 = tep.is_ip4;
  clib_memcpy_fast (mp->lcl_ip, &tep.ip, sizeof (tep.ip));

  vpp_evt_q = session_main_get_vpp_event_queue (0);
  mp->vpp_evt_q = pointer_to_uword (vpp_evt_q);

  if (session_transport_service_type (ls) == TRANSPORT_SERVICE_CL)
    {
      mp->rx_fifo = pointer_to_uword (ls->rx_fifo);
      mp->tx_fifo = pointer_to_uword (ls->tx_fifo);
    }

done:
  mp->retval = rv;
  svm_msg_q_add_and_unlock (app_mq, msg);
  return 0;
}

void
mq_send_unlisten_reply (app_worker_t * app_wrk, session_handle_t sh,
			u32 context, int rv)
{
  svm_msg_q_msg_t _msg, *msg = &_msg;
  session_unlisten_reply_msg_t *ump;
  svm_msg_q_t *app_mq;
  session_event_t *evt;

  app_mq = app_wrk->event_queue;
  if (mq_try_lock_and_alloc_msg (app_mq, msg))
    return;

  evt = svm_msg_q_msg_data (app_mq, msg);
  clib_memset (evt, 0, sizeof (*evt));
  evt->event_type = SESSION_CTRL_EVT_UNLISTEN_REPLY;
  ump = (session_unlisten_reply_msg_t *) evt->data;
  ump->context = context;
  ump->handle = sh;
  ump->retval = rv;
  svm_msg_q_add_and_unlock (app_mq, msg);
}

static void
mq_send_session_migrate_cb (session_t * s, session_handle_t new_sh)
{
  svm_msg_q_msg_t _msg, *msg = &_msg;
  session_migrated_msg_t *mp;
  svm_msg_q_t *vpp_evt_q;
  app_worker_t *app_wrk;
  session_event_t *evt;
  svm_msg_q_t *app_mq;

  app_wrk = app_worker_get (s->app_wrk_index);
  app_mq = app_wrk->event_queue;
  if (mq_try_lock_and_alloc_msg (app_mq, msg))
    return;

  evt = svm_msg_q_msg_data (app_mq, msg);
  clib_memset (evt, 0, sizeof (*evt));
  evt->event_type = SESSION_CTRL_EVT_MIGRATED;
  mp = (session_migrated_msg_t *) evt->data;
  mp->handle = session_handle (s);
  mp->new_handle = new_sh;
  mp->vpp_thread_index = session_thread_from_handle (new_sh);
  vpp_evt_q = session_main_get_vpp_event_queue (mp->vpp_thread_index);
  mp->vpp_evt_q = pointer_to_uword (vpp_evt_q);
  svm_msg_q_add_and_unlock (app_mq, msg);
}

static int
mq_send_add_segment_cb (u32 app_wrk_index, u64 segment_handle)
{
  int fds[SESSION_N_FD_TYPE], n_fds = 0;
  svm_msg_q_msg_t _msg, *msg = &_msg;
  session_app_add_segment_msg_t *mp;
  vl_api_registration_t *reg;
  app_worker_t *app_wrk;
  session_event_t *evt;
  svm_msg_q_t *app_mq;
  fifo_segment_t *fs;
  ssvm_private_t *sp;
  u8 fd_flags = 0;

  app_wrk = app_worker_get (app_wrk_index);

  reg = vl_mem_api_client_index_to_registration (app_wrk->api_client_index);
  if (!reg)
    {
      clib_warning ("no api registration for client: %u",
		    app_wrk->api_client_index);
      return -1;
    }

  fs = segment_manager_get_segment_w_handle (segment_handle);
  sp = &fs->ssvm;
  if (ssvm_type (sp) == SSVM_SEGMENT_MEMFD)
    {
      if (vl_api_registration_file_index (reg) == VL_API_INVALID_FI)
	{
	  clib_warning ("can't send memfd fd");
	  return -1;
	}

      fd_flags |= SESSION_FD_F_MEMFD_SEGMENT;
      fds[n_fds] = sp->fd;
      n_fds += 1;
    }

  app_mq = app_wrk->event_queue;
  if (mq_try_lock_and_alloc_msg (app_mq, msg))
    return -1;

  if (n_fds)
    session_send_fds (reg, fds, n_fds);

  evt = svm_msg_q_msg_data (app_mq, msg);
  clib_memset (evt, 0, sizeof (*evt));
  evt->event_type = SESSION_CTRL_EVT_APP_ADD_SEGMENT;
  mp = (session_app_add_segment_msg_t *) evt->data;
  clib_memset (mp, 0, sizeof (*mp));
  mp->segment_size = sp->ssvm_size;
  mp->fd_flags = fd_flags;
  mp->segment_handle = segment_handle;
  strncpy ((char *) mp->segment_name, (char *) sp->name,
	   sizeof (mp->segment_name) - 1);

  svm_msg_q_add_and_unlock (app_mq, msg);

  return 0;
}

static int
mq_send_del_segment_cb (u32 app_wrk_index, u64 segment_handle)
{
  svm_msg_q_msg_t _msg, *msg = &_msg;
  session_app_del_segment_msg_t *mp;
  vl_api_registration_t *reg;
  app_worker_t *app_wrk;
  session_event_t *evt;
  svm_msg_q_t *app_mq;

  app_wrk = app_worker_get (app_wrk_index);
  reg = vl_mem_api_client_index_to_registration (app_wrk->api_client_index);
  if (!reg)
    {
      clib_warning ("no registration: %u", app_wrk->api_client_index);
      return -1;
    }

  app_mq = app_wrk->event_queue;
  if (mq_try_lock_and_alloc_msg (app_mq, msg))
    return -1;

  evt = svm_msg_q_msg_data (app_mq, msg);
  clib_memset (evt, 0, sizeof (*evt));
  evt->event_type = SESSION_CTRL_EVT_APP_DEL_SEGMENT;
  mp = (session_app_del_segment_msg_t *) evt->data;
  clib_memset (mp, 0, sizeof (*mp));
  mp->segment_handle = segment_handle;
  svm_msg_q_add_and_unlock (app_mq, msg);

  return 0;
}

static void
mq_send_session_cleanup_cb (session_t * s, session_cleanup_ntf_t ntf)
{
  svm_msg_q_msg_t _msg, *msg = &_msg;
  session_cleanup_msg_t *mp;
  svm_msg_q_t *app_mq;
  session_event_t *evt;
  app_worker_t *app_wrk;

  /* Only propagate session cleanup notification */
  if (ntf == SESSION_CLEANUP_TRANSPORT)
    return;

  app_wrk = app_worker_get_if_valid (s->app_wrk_index);
  if (!app_wrk)
    return;

  app_mq = app_wrk->event_queue;
  if (mq_try_lock_and_alloc_msg (app_mq, msg))
    return;

  evt = svm_msg_q_msg_data (app_mq, msg);
  clib_memset (evt, 0, sizeof (*evt));
  evt->event_type = SESSION_CTRL_EVT_CLEANUP;
  mp = (session_cleanup_msg_t *) evt->data;
  mp->handle = session_handle (s);
  svm_msg_q_add_and_unlock (app_mq, msg);
}

/* ### WILL BE DEPRECATED POST 20.01 ### */
static session_cb_vft_t session_mq_cb_vft_old = {
  .session_accept_callback = mq_send_session_accepted_cb,
  .session_disconnect_callback = mq_send_session_disconnected_cb,
  .session_connected_callback = mq_send_session_connected_cb,
  .session_reset_callback = mq_send_session_reset_cb,
  .session_migrate_callback = mq_send_session_migrate_cb,
  .add_segment_callback = send_add_segment_callback,
  .del_segment_callback = send_del_segment_callback,
};

static session_cb_vft_t session_mq_cb_vft = {
  .session_accept_callback = mq_send_session_accepted_cb,
  .session_disconnect_callback = mq_send_session_disconnected_cb,
  .session_connected_callback = mq_send_session_connected_cb,
  .session_reset_callback = mq_send_session_reset_cb,
  .session_migrate_callback = mq_send_session_migrate_cb,
  .session_cleanup_callback = mq_send_session_cleanup_cb,
  .add_segment_callback = mq_send_add_segment_cb,
  .del_segment_callback = mq_send_del_segment_cb,
};

static void
vl_api_session_enable_disable_t_handler (vl_api_session_enable_disable_t * mp)
{
  vl_api_session_enable_disable_reply_t *rmp;
  vlib_main_t *vm = vlib_get_main ();
  int rv = 0;

  vnet_session_enable_disable (vm, mp->is_enable);
  REPLY_MACRO (VL_API_SESSION_ENABLE_DISABLE_REPLY);
}

/* ### WILL BE DEPRECATED POST 20.01 ### */
static void
vl_api_application_attach_t_handler (vl_api_application_attach_t * mp)
{
  int rv = 0, fds[SESSION_N_FD_TYPE], n_fds = 0;
  vl_api_application_attach_reply_t *rmp;
  ssvm_private_t *segp, *evt_q_segment;
  vnet_app_attach_args_t _a, *a = &_a;
  vl_api_registration_t *reg;
  u8 fd_flags = 0;

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

  if (session_main_is_enabled () == 0)
    {
      rv = VNET_API_ERROR_FEATURE_DISABLED;
      goto done;
    }

  STATIC_ASSERT (sizeof (u64) * APP_OPTIONS_N_OPTIONS <=
		 sizeof (mp->options),
		 "Out of options, fix api message definition");

  clib_memset (a, 0, sizeof (*a));
  a->api_client_index = mp->client_index;
  a->options = mp->options;
  a->session_cb_vft = &session_mq_cb_vft_old;
  if (mp->namespace_id_len > 64)
    {
      rv = VNET_API_ERROR_INVALID_VALUE;
      goto done;
    }

  if (mp->namespace_id_len)
    {
      vec_validate (a->namespace_id, mp->namespace_id_len - 1);
      clib_memcpy_fast (a->namespace_id, mp->namespace_id,
			mp->namespace_id_len);
    }

  if ((rv = vnet_application_attach (a)))
    {
      clib_warning ("attach returned: %d", rv);
      vec_free (a->namespace_id);
      goto done;
    }
  vec_free (a->namespace_id);

  /* Send event queues segment */
  if ((evt_q_segment = session_main_get_evt_q_segment ()))
    {
      fd_flags |= SESSION_FD_F_VPP_MQ_SEGMENT;
      fds[n_fds] = evt_q_segment->fd;
      n_fds += 1;
    }
  /* Send fifo segment fd if needed */
  if (ssvm_type (a->segment) == SSVM_SEGMENT_MEMFD)
    {
      fd_flags |= SESSION_FD_F_MEMFD_SEGMENT;
      fds[n_fds] = a->segment->fd;
      n_fds += 1;
    }
  if (a->options[APP_OPTIONS_FLAGS] & APP_OPTIONS_FLAGS_EVT_MQ_USE_EVENTFD)
    {
      fd_flags |= SESSION_FD_F_MQ_EVENTFD;
      fds[n_fds] = svm_msg_q_get_producer_eventfd (a->app_evt_q);
      n_fds += 1;
    }

done:

  /* *INDENT-OFF* */
  REPLY_MACRO2 (VL_API_APPLICATION_ATTACH_REPLY, ({
    if (!rv)
      {
	segp = a->segment;
	rmp->app_index = clib_host_to_net_u32 (a->app_index);
	rmp->segment_name_length = 0;
	rmp->segment_size = segp->ssvm_size;
	if (vec_len (segp->name))
	  {
	    memcpy (rmp->segment_name, segp->name, vec_len (segp->name));
	    rmp->segment_name_length = vec_len (segp->name);
	  }
	rmp->app_event_queue_address = pointer_to_uword (a->app_evt_q);
	rmp->n_fds = n_fds;
	rmp->fd_flags = fd_flags;
	rmp->segment_handle = clib_host_to_net_u64 (a->segment_handle);
      }
  }));
  /* *INDENT-ON* */

  if (n_fds)
    session_send_fds (reg, fds, n_fds);
}

static void
vl_api_app_attach_t_handler (vl_api_app_attach_t * mp)
{
  int rv = 0, fds[SESSION_N_FD_TYPE], n_fds = 0;
  vl_api_app_attach_reply_t *rmp;
  ssvm_private_t *segp, *evt_q_segment;
  vnet_app_attach_args_t _a, *a = &_a;
  u8 fd_flags = 0, ctrl_thread;
  vl_api_registration_t *reg;
  svm_msg_q_t *ctrl_mq;

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

  if (session_main_is_enabled () == 0)
    {
      rv = VNET_API_ERROR_FEATURE_DISABLED;
      goto done;
    }

  STATIC_ASSERT (sizeof (u64) * APP_OPTIONS_N_OPTIONS <=
		 sizeof (mp->options),
		 "Out of options, fix api message definition");

  clib_memset (a, 0, sizeof (*a));
  a->api_client_index = mp->client_index;
  a->options = mp->options;
  a->session_cb_vft = &session_mq_cb_vft;
  if (mp->namespace_id_len > 64)
    {
      rv = VNET_API_ERROR_INVALID_VALUE;
      goto done;
    }

  if (mp->namespace_id_len)
    {
      vec_validate (a->namespace_id, mp->namespace_id_len - 1);
      clib_memcpy_fast (a->namespace_id, mp->namespace_id,
			mp->namespace_id_len);
    }

  if ((rv = vnet_application_attach (a)))
    {
      clib_warning ("attach returned: %d", rv);
      vec_free (a->namespace_id);
      goto done;
    }
  vec_free (a->namespace_id);

  /* Send event queues segment */
  if ((evt_q_segment = session_main_get_evt_q_segment ()))
    {
      fd_flags |= SESSION_FD_F_VPP_MQ_SEGMENT;
      fds[n_fds] = evt_q_segment->fd;
      n_fds += 1;
    }
  /* Send fifo segment fd if needed */
  if (ssvm_type (a->segment) == SSVM_SEGMENT_MEMFD)
    {
      fd_flags |= SESSION_FD_F_MEMFD_SEGMENT;
      fds[n_fds] = a->segment->fd;
      n_fds += 1;
    }
  if (a->options[APP_OPTIONS_FLAGS] & APP_OPTIONS_FLAGS_EVT_MQ_USE_EVENTFD)
    {
      fd_flags |= SESSION_FD_F_MQ_EVENTFD;
      fds[n_fds] = svm_msg_q_get_producer_eventfd (a->app_evt_q);
      n_fds += 1;
    }

done:
  /* *INDENT-OFF* */
  REPLY_MACRO2 (VL_API_APP_ATTACH_REPLY, ({
    if (!rv)
      {
	ctrl_thread = vlib_num_workers () ? 1 : 0;
	ctrl_mq = session_main_get_vpp_event_queue (ctrl_thread);
	segp = a->segment;
	rmp->app_index = clib_host_to_net_u32 (a->app_index);
	rmp->app_mq = pointer_to_uword (a->app_evt_q);
	rmp->vpp_ctrl_mq = pointer_to_uword (ctrl_mq);
	rmp->vpp_ctrl_mq_thread = ctrl_thread;
	rmp->n_fds = n_fds;
	rmp->fd_flags = fd_flags;
	if (vec_len (segp->name))
	  {
	    memcpy (rmp->segment_name, segp->name, vec_len (segp->name));
	    rmp->segment_name_length = vec_len (segp->name);
	  }
	rmp->segment_size = segp->ssvm_size;
	rmp->segment_handle = clib_host_to_net_u64 (a->segment_handle);
      }
  }));
  /* *INDENT-ON* */

  if (n_fds)
    session_send_fds (reg, fds, n_fds);
}

/* ### WILL BE DEPRECATED POST 20.01 ### */
static void
vl_api_application_detach_t_handler (vl_api_application_detach_t * mp)
{
  vl_api_application_detach_reply_t *rmp;
  int rv = VNET_API_ERROR_INVALID_VALUE_2;
  vnet_app_detach_args_t _a, *a = &_a;
  application_t *app;

  if (session_main_is_enabled () == 0)
    {
      rv = VNET_API_ERROR_FEATURE_DISABLED;
      goto done;
    }

  app = application_lookup (mp->client_index);
  if (app)
    {
      a->app_index = app->app_index;
      a->api_client_index = mp->client_index;
      rv = vnet_application_detach (a);
    }

done:
  REPLY_MACRO (VL_API_APPLICATION_DETACH_REPLY);
}

/* ### WILL BE DEPRECATED POST 20.01 ### */
static void
vl_api_bind_uri_t_handler (vl_api_bind_uri_t * mp)
{
  vl_api_bind_uri_reply_t *rmp;
  vnet_listen_args_t _a, *a = &_a;
  application_t *app = 0;
  app_worker_t *app_wrk;
  int rv;

  if (session_main_is_enabled () == 0)
    {
      rv = VNET_API_ERROR_FEATURE_DISABLED;
      goto done;
    }

  app = application_lookup (mp->client_index);
  if (app)
    {
      clib_memset (a, 0, sizeof (*a));
      a->uri = (char *) mp->uri;
      a->app_index = app->app_index;
      rv = vnet_bind_uri (a);
    }
  else
    {
      rv = VNET_API_ERROR_APPLICATION_NOT_ATTACHED;
    }

done:

  REPLY_MACRO (VL_API_BIND_URI_REPLY);

  if (app)
    {
      app_wrk = application_get_worker (app, 0);
      mq_send_session_bound_cb (app_wrk->wrk_index, mp->context, a->handle,
				rv);
    }
}

/* ### WILL BE DEPRECATED POST 20.01 ### */
static void
vl_api_unbind_uri_t_handler (vl_api_unbind_uri_t * mp)
{
  vl_api_unbind_uri_reply_t *rmp;
  application_t *app;
  vnet_unlisten_args_t _a, *a = &_a;
  int rv;

  if (session_main_is_enabled () == 0)
    {
      rv = VNET_API_ERROR_FEATURE_DISABLED;
      goto done;
    }

  app = application_lookup (mp->client_index);
  if (app)
    {
      a->uri = (char *) mp->uri;
      a->app_index = app->app_index;
      a->wrk_map_index = 0;
      rv = vnet_unbind_uri (a);
    }
  else
    {
      rv = VNET_API_ERROR_APPLICATION_NOT_ATTACHED;
    }

done:
  REPLY_MACRO (VL_API_UNBIND_URI_REPLY);
}

/* ### WILL BE DEPRECATED POST 20.01 ### */
static void
vl_api_connect_uri_t_handler (vl_api_connect_uri_t * mp)
{
  vl_api_connect_uri_reply_t *rmp;
  vnet_connect_args_t _a, *a = &_a;
  application_t *app;
  int rv = 0;

  if (session_main_is_enabled () == 0)
    {
      rv = VNET_API_ERROR_FEATURE_DISABLED;
      goto done;
    }

  app = application_lookup (mp->client_index);
  if (app)
    {
      clib_memset (a, 0, sizeof (*a));
      a->uri = (char *) mp->uri;
      a->api_context = mp->context;
      a->app_index = app->app_index;
      if ((rv = vnet_connect_uri (a)))
	clib_warning ("connect_uri returned: %d", rv);
    }
  else
    {
      rv = VNET_API_ERROR_APPLICATION_NOT_ATTACHED;
    }

  /*
   * Don't reply to stream (tcp) connects. The reply will come once
   * the connection is established. In case of the redirects, the reply
   * will come from the server app.
   */
  if (rv == 0)
    return;

done:
  REPLY_MACRO (VL_API_CONNECT_URI_REPLY);
}

/* ### WILL BE DEPRECATED POST 20.01 ### */
static void
vl_api_disconnect_session_t_handler (vl_api_disconnect_session_t * mp)
{
  vl_api_disconnect_session_reply_t *rmp;
  vnet_disconnect_args_t _a, *a = &_a;
  application_t *app;
  int rv = 0;

  if (session_main_is_enabled () == 0)
    {
      rv = VNET_API_ERROR_FEATURE_DISABLED;
      goto done;
    }

  app = application_lookup (mp->client_index);
  if (app)
    {
      a->handle = mp->handle;
      a->app_index = app->app_index;
      rv = vnet_disconnect_session (a);
    }
  else
    {
      rv = VNET_API_ERROR_APPLICATION_NOT_ATTACHED;
    }

done:
  REPLY_MACRO2 (VL_API_DISCONNECT_SESSION_REPLY, rmp->handle = mp->handle);
}

/* ### WILL BE DEPRECATED POST 20.01 ### */
static void
vl_api_disconnect_session_reply_t_handler (vl_api_disconnect_session_reply_t *
					   mp)
{
  vnet_disconnect_args_t _a, *a = &_a;
  application_t *app;

  /* Client objected to disconnecting the session, log and continue */
  if (mp->retval)
    {
      clib_warning ("client retval %d", mp->retval);
      return;
    }

  /* Disconnect has been confirmed. Confirm close to transport */
  app = application_lookup (mp->context);
  if (app)
    {
      a->handle = mp->handle;
      a->app_index = app->app_index;
      vnet_disconnect_session (a);
    }
}

/* ### WILL BE DEPRECATED POST 20.01 ### */
static void
vl_api_map_another_segment_reply_t_handler (vl_api_map_another_segment_reply_t
					    * mp)
{
  clib_warning ("not implemented");
}

/* ### WILL BE DEPRECATED POST 20.01 ### */
static void
vl_api_bind_sock_t_handler (vl_api_bind_sock_t * mp)
{
  vnet_listen_args_t _a, *a = &_a;
  vl_api_bind_sock_reply_t *rmp;
  application_t *app = 0;
  app_worker_t *app_wrk;
  ip46_address_t *ip46;
  int rv = 0;

  if (session_main_is_enabled () == 0)
    {
      rv = VNET_API_ERROR_FEATURE_DISABLED;
      goto done;
    }

  app = application_lookup (mp->client_index);
  if (!app)
    {
      rv = VNET_API_ERROR_APPLICATION_NOT_ATTACHED;
      goto done;
    }

  ip46 = (ip46_address_t *) mp->ip;
  clib_memset (a, 0, sizeof (*a));
  a->sep.is_ip4 = mp->is_ip4;
  a->sep.ip = *ip46;
  a->sep.port = mp->port;
  a->sep.fib_index = mp->vrf;
  a->sep.sw_if_index = ENDPOINT_INVALID_INDEX;
  a->sep.transport_proto = mp->proto;
  a->app_index = app->app_index;
  a->wrk_map_index = mp->wrk_index;

  if ((rv = vnet_listen (a)))
    clib_warning ("listen returned: %d", rv);

done:
  /* Actual reply sent only over mq */
  REPLY_MACRO (VL_API_BIND_SOCK_REPLY);

  if (app)
    {
      app_wrk = application_get_worker (app, mp->wrk_index);
      mq_send_session_bound_cb (app_wrk->wrk_index, mp->context, a->handle,
				rv);
    }
}

/* ### WILL BE DEPRECATED POST 20.01 ### */
static void
vl_api_unbind_sock_t_handler (vl_api_unbind_sock_t * mp)
{
  vl_api_unbind_sock_reply_t *rmp;
  vnet_unlisten_args_t _a, *a = &_a;
  app_worker_t *app_wrk;
  application_t *app = 0;
  int rv = 0;

  if (session_main_is_enabled () == 0)
    {
      rv = VNET_API_ERROR_FEATURE_DISABLED;
      goto done;
    }

  app = application_lookup (mp->client_index);
  if (app)
    {
      a->app_index = app->app_index;
      a->handle = mp->handle;
      a->wrk_map_index = mp->wrk_index;
      if ((rv = vnet_unlisten (a)))
	clib_warning ("unlisten returned: %d", rv);
    }
  else
    {
      rv = VNET_API_ERROR_APPLICATION_NOT_ATTACHED;
    }

done:
  REPLY_MACRO (VL_API_UNBIND_SOCK_REPLY);

  if (!app)
    return;

  app_wrk = application_get_worker (app, a->wrk_map_index);
  if (!app_wrk)
    return;

  mq_send_unlisten_reply (app_wrk, mp->handle, mp->context, rv);
}

/* ### WILL BE DEPRECATED POST 20.01 ### */
static void
vl_api_connect_sock_t_handler (vl_api_connect_sock_t * mp)
{
  vl_api_connect_sock_reply_t *rmp;
  vnet_connect_args_t _a, *a = &_a;
  application_t *app = 0;
  int rv = 0;

  if (session_main_is_enabled () == 0)
    {
      rv = VNET_API_ERROR_FEATURE_DISABLED;
      goto done;
    }

  app = application_lookup (mp->client_index);
  if (app)
    {
      svm_queue_t *client_q;
      ip46_address_t *ip46 = (ip46_address_t *) mp->ip;

      clib_memset (a, 0, sizeof (*a));
      client_q = vl_api_client_index_to_input_queue (mp->client_index);
      mp->client_queue_address = pointer_to_uword (client_q);
      a->sep.is_ip4 = mp->is_ip4;
      a->sep.ip = *ip46;
      a->sep.port = mp->port;
      a->sep.transport_proto = mp->proto;
      a->sep.peer.fib_index = mp->vrf;
      a->sep.peer.sw_if_index = ENDPOINT_INVALID_INDEX;
      a->sep_ext.parent_handle = mp->parent_handle;
      if (mp->hostname_len)
	{
	  vec_validate (a->sep_ext.hostname, mp->hostname_len - 1);
	  clib_memcpy_fast (a->sep_ext.hostname, mp->hostname,
			    mp->hostname_len);
	}
      a->api_context = mp->context;
      a->app_index = app->app_index;
      a->wrk_map_index = mp->wrk_index;
      if ((rv = vnet_connect (a)))
	clib_warning ("connect returned: %U", format_vnet_api_errno, rv);
      vec_free (a->sep_ext.hostname);
    }
  else
    {
      rv = VNET_API_ERROR_APPLICATION_NOT_ATTACHED;
    }

  if (rv == 0)
    return;

  /* Got some error, relay it */

done:
  REPLY_MACRO (VL_API_CONNECT_SOCK_REPLY);

  if (app)
    {
      app_worker_t *app_wrk = application_get_worker (app, mp->wrk_index);
      mq_send_session_connected_cb (app_wrk->wrk_index, mp->context, 0, 1);
    }
}

static void
vl_api_app_worker_add_del_t_handler (vl_api_app_worker_add_del_t * mp)
{
  int rv = 0, fds[SESSION_N_FD_TYPE], n_fds = 0;
  vl_api_app_worker_add_del_reply_t *rmp;
  vl_api_registration_t *reg;
  application_t *app;
  u8 fd_flags = 0;

  if (session_main_is_enabled () == 0)
    {
      rv = VNET_API_ERROR_FEATURE_DISABLED;
      goto done;
    }

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

  app = application_get_if_valid (clib_net_to_host_u32 (mp->app_index));
  if (!app)
    {
      rv = VNET_API_ERROR_INVALID_VALUE;
      goto done;
    }

  vnet_app_worker_add_del_args_t args = {
    .app_index = app->app_index,
    .wrk_map_index = clib_net_to_host_u32 (mp->wrk_index),
    .api_client_index = mp->client_index,
    .is_add = mp->is_add
  };
  rv = vnet_app_worker_add_del (&args);
  if (rv)
    {
      clib_warning ("app worker add/del returned: %d", rv);
      goto done;
    }

  if (!mp->is_add)
    goto done;

  /* Send fifo segment fd if needed */
  if (ssvm_type (args.segment) == SSVM_SEGMENT_MEMFD)
    {
      fd_flags |= SESSION_FD_F_MEMFD_SEGMENT;
      fds[n_fds] = args.segment->fd;
      n_fds += 1;
    }
  if (application_segment_manager_properties (app)->use_mq_eventfd)
    {
      fd_flags |= SESSION_FD_F_MQ_EVENTFD;
      fds[n_fds] = svm_msg_q_get_producer_eventfd (args.evt_q);
      n_fds += 1;
    }

  /* *INDENT-OFF* */
done:
  REPLY_MACRO2 (VL_API_APP_WORKER_ADD_DEL_REPLY, ({
    rmp->is_add = mp->is_add;
    rmp->wrk_index = clib_host_to_net_u32 (args.wrk_map_index);
    rmp->segment_handle = clib_host_to_net_u64 (args.segment_handle);
    if (!rv && mp->is_add)
      {
	if (vec_len (args.segment->name))
	  {
	    memcpy (rmp->segment_name, args.segment->name,
	            vec_len (args.segment->name));
	    rmp->segment_name_length = vec_len (args.segment->name);
	  }
	rmp->app_event_queue_address = pointer_to_uword (args.evt_q);
	rmp->n_fds = n_fds;
	rmp->fd_flags = fd_flags;
      }
  }));
  /* *INDENT-ON* */

  if (n_fds)
    session_send_fds (reg, fds, n_fds);
}

static void
vl_api_app_namespace_add_del_t_handler (vl_api_app_namespace_add_del_t * mp)
{
  vl_api_app_namespace_add_del_reply_t *rmp;
  u32 appns_index = 0;
  u8 *ns_id = 0;
  int rv = 0;
  if (session_main_is_enabled () == 0)
    {
      rv = VNET_API_ERROR_FEATURE_DISABLED;
      goto done;
    }

  if (mp->namespace_id_len > ARRAY_LEN (mp->namespace_id))
    {
      rv = VNET_API_ERROR_INVALID_VALUE;
      goto done;
    }

  vec_validate (ns_id, mp->namespace_id_len - 1);
  clib_memcpy_fast (ns_id, mp->namespace_id, mp->namespace_id_len);
  vnet_app_namespace_add_del_args_t args = {
    .ns_id = ns_id,
    .secret = clib_net_to_host_u64 (mp->secret),
    .sw_if_index = clib_net_to_host_u32 (mp->sw_if_index),
    .ip4_fib_id = clib_net_to_host_u32 (mp->ip4_fib_id),
    .ip6_fib_id = clib_net_to_host_u32 (mp->ip6_fib_id),
    .is_add = 1
  };
  rv = vnet_app_namespace_add_del (&args);
  if (!rv)
    {
      appns_index = app_namespace_index_from_id (ns_id);
      if (appns_index == APP_NAMESPACE_INVALID_INDEX)
	{
	  clib_warning ("app ns lookup failed");
	  rv = VNET_API_ERROR_UNSPECIFIED;
	}
    }
  vec_free (ns_id);

  /* *INDENT-OFF* */
done:
  REPLY_MACRO2 (VL_API_APP_NAMESPACE_ADD_DEL_REPLY, ({
    if (!rv)
      rmp->appns_index = clib_host_to_net_u32 (appns_index);
  }));
  /* *INDENT-ON* */
}

static void
vl_api_session_rule_add_del_t_handler (vl_api_session_rule_add_del_t * mp)
{
  vl_api_session_rule_add_del_reply_t *rmp;
  session_rule_add_del_args_t args;
  session_rule_table_add_del_args_t *table_args = &args.table_args;
  u8 fib_proto;
  int rv = 0;

  clib_memset (&args, 0, sizeof (args));
  fib_proto = mp->is_ip4 ? FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6;

  table_args->lcl.fp_len = mp->lcl_plen;
  table_args->lcl.fp_proto = fib_proto;
  table_args->rmt.fp_len = mp->rmt_plen;
  table_args->rmt.fp_proto = fib_proto;
  table_args->lcl_port = mp->lcl_port;
  table_args->rmt_port = mp->rmt_port;
  table_args->action_index = clib_net_to_host_u32 (mp->action_index);
  table_args->is_add = mp->is_add;
  mp->tag[sizeof (mp->tag) - 1] = 0;
  table_args->tag = format (0, "%s", mp->tag);
  args.appns_index = clib_net_to_host_u32 (mp->appns_index);
  args.scope = mp->scope;
  args.transport_proto = mp->transport_proto;

  clib_memset (&table_args->lcl.fp_addr, 0, sizeof (table_args->lcl.fp_addr));
  clib_memset (&table_args->rmt.fp_addr, 0, sizeof (table_args->rmt.fp_addr));
  ip_set (&table_args->lcl.fp_addr, mp->lcl_ip, mp->is_ip4);
  ip_set (&table_args->rmt.fp_addr, mp->rmt_ip, mp->is_ip4);
  rv = vnet_session_rule_add_del (&args);
  if (rv)
    clib_warning ("rule add del returned: %d", rv);
  vec_free (table_args->tag);
  REPLY_MACRO (VL_API_SESSION_RULE_ADD_DEL_REPLY);
}

static void
send_session_rule_details4 (mma_rule_16_t * rule, u8 is_local,
			    u8 transport_proto, u32 appns_index, u8 * tag,
			    vl_api_registration_t * reg, u32 context)
{
  vl_api_session_rules_details_t *rmp = 0;
  session_mask_or_match_4_t *match =
    (session_mask_or_match_4_t *) & rule->match;
  session_mask_or_match_4_t *mask =
    (session_mask_or_match_4_t *) & rule->mask;

  rmp = vl_msg_api_alloc (sizeof (*rmp));
  clib_memset (rmp, 0, sizeof (*rmp));
  rmp->_vl_msg_id = ntohs (VL_API_SESSION_RULES_DETAILS);
  rmp->context = context;

  rmp->is_ip4 = 1;
  clib_memcpy_fast (rmp->lcl_ip, &match->lcl_ip, sizeof (match->lcl_ip));
  clib_memcpy_fast (rmp->rmt_ip, &match->rmt_ip, sizeof (match->rmt_ip));
  rmp->lcl_plen = ip4_mask_to_preflen (&mask->lcl_ip);
  rmp->rmt_plen = ip4_mask_to_preflen (&mask->rmt_ip);
  rmp->lcl_port = match->lcl_port;
  rmp->rmt_port = match->rmt_port;
  rmp->action_index = clib_host_to_net_u32 (rule->action_index);
  rmp->scope =
    is_local ? SESSION_RULE_SCOPE_LOCAL : SESSION_RULE_SCOPE_GLOBAL;
  rmp->transport_proto = transport_proto;
  rmp->appns_index = clib_host_to_net_u32 (appns_index);
  if (tag)
    {
      clib_memcpy_fast (rmp->tag, tag, vec_len (tag));
      rmp->tag[vec_len (tag)] = 0;
    }

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

static void
send_session_rule_details6 (mma_rule_40_t * rule, u8 is_local,
			    u8 transport_proto, u32 appns_index, u8 * tag,
			    vl_api_registration_t * reg, u32 context)
{
  vl_api_session_rules_details_t *rmp = 0;
  session_mask_or_match_6_t *match =
    (session_mask_or_match_6_t *) & rule->match;
  session_mask_or_match_6_t *mask =
    (session_mask_or_match_6_t *) & rule->mask;

  rmp = vl_msg_api_alloc (sizeof (*rmp));
  clib_memset (rmp, 0, sizeof (*rmp));
  rmp->_vl_msg_id = ntohs (VL_API_SESSION_RULES_DETAILS);
  rmp->context = context;

  rmp->is_ip4 = 0;
  clib_memcpy_fast (rmp->lcl_ip, &match->lcl_ip, sizeof (match->lcl_ip));
  clib_memcpy_fast (rmp->rmt_ip, &match->rmt_ip, sizeof (match->rmt_ip));
  rmp->lcl_plen = ip6_mask_to_preflen (&mask->lcl_ip);
  rmp->rmt_plen = ip6_mask_to_preflen (&mask->rmt_ip);
  rmp->lcl_port = match->lcl_port;
  rmp->rmt_port = match->rmt_port;
  rmp->action_index = clib_host_to_net_u32 (rule->action_index);
  rmp->scope =
    is_local ? SESSION_RULE_SCOPE_LOCAL : SESSION_RULE_SCOPE_GLOBAL;
  rmp->transport_proto = transport_proto;
  rmp->appns_index = clib_host_to_net_u32 (appns_index);
  if (tag)
    {
      clib_memcpy_fast (rmp->tag, tag, vec_len (tag));
      rmp->tag[vec_len (tag)] = 0;
    }

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

static void
send_session_rules_table_details (session_rules_table_t * srt, u8 fib_proto,
				  u8 tp, u8 is_local, u32 appns_index,
				  vl_api_registration_t * reg, u32 context)
{
  mma_rule_16_t *rule16;
  mma_rule_40_t *rule40;
  mma_rules_table_16_t *srt16;
  mma_rules_table_40_t *srt40;
  u32 ri;

  if (is_local || fib_proto == FIB_PROTOCOL_IP4)
    {
      u8 *tag = 0;
      /* *INDENT-OFF* */
      srt16 = &srt->session_rules_tables_16;
      pool_foreach (rule16, srt16->rules, ({
	ri = mma_rules_table_rule_index_16 (srt16, rule16);
	tag = session_rules_table_rule_tag (srt, ri, 1);
        send_session_rule_details4 (rule16, is_local, tp, appns_index, tag,
                                    reg, context);
      }));
      /* *INDENT-ON* */
    }
  if (is_local || fib_proto == FIB_PROTOCOL_IP6)
    {
      u8 *tag = 0;
      /* *INDENT-OFF* */
      srt40 = &srt->session_rules_tables_40;
      pool_foreach (rule40, srt40->rules, ({
	ri = mma_rules_table_rule_index_40 (srt40, rule40);
	tag = session_rules_table_rule_tag (srt, ri, 1);
        send_session_rule_details6 (rule40, is_local, tp, appns_index, tag,
                                    reg, context);
      }));
      /* *INDENT-ON* */
    }
}

static void
vl_api_session_rules_dump_t_handler (vl_api_one_map_server_dump_t * mp)
{
  vl_api_registration_t *reg;
  session_table_t *st;
  u8 tp;

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

  /* *INDENT-OFF* */
  session_table_foreach (st, ({
    for (tp = 0; tp < TRANSPORT_N_PROTO; tp++)
      {
        send_session_rules_table_details (&st->session_rules[tp],
                                          st->active_fib_proto, tp,
                                          st->is_local, st->appns_index, reg,
                                          mp->context);
      }
  }));
  /* *INDENT-ON* */
}

static void
vl_api_app_add_cert_key_pair_t_handler (vl_api_app_add_cert_key_pair_t * mp)
{
  vl_api_app_add_cert_key_pair_reply_t *rmp;
  vnet_app_add_cert_key_pair_args_t _a, *a = &_a;
  u32 certkey_len, key_len, cert_len;
  int rv = 0;
  if (session_main_is_enabled () == 0)
    {
      rv = VNET_API_ERROR_FEATURE_DISABLED;
      goto done;
    }

  cert_len = clib_net_to_host_u16 (mp->cert_len);
  if (cert_len > 10000)
    {
      rv = VNET_API_ERROR_INVALID_VALUE;
      goto done;
    }

  certkey_len = clib_net_to_host_u16 (mp->certkey_len);
  if (certkey_len < cert_len)
    {
      rv = VNET_API_ERROR_INVALID_VALUE;
      goto done;
    }

  key_len = certkey_len - cert_len;
  if (key_len > 10000)
    {
      rv = VNET_API_ERROR_INVALID_VALUE;
      goto done;
    }

  clib_memset (a, 0, sizeof (*a));
  vec_validate (a->cert, cert_len);
  vec_validate (a->key, key_len);
  clib_memcpy_fast (a->cert, mp->certkey, cert_len);
  clib_memcpy_fast (a->key, mp->certkey + cert_len, key_len);
  rv = vnet_app_add_cert_key_pair (a);
  vec_free (a->cert);
  vec_free (a->key);

done:
  /* *INDENT-OFF* */
  REPLY_MACRO2 (VL_API_APP_ADD_CERT_KEY_PAIR_REPLY, ({
    if (!rv)
      rmp->index = clib_host_to_net_u32 (a->index);
  }));
  /* *INDENT-ON* */
}

static void
vl_api_app_del_cert_key_pair_t_handler (vl_api_app_del_cert_key_pair_t * mp)
{
  vl_api_app_del_cert_key_pair_reply_t *rmp;
  u32 ckpair_index;
  int rv = 0;
  if (session_main_is_enabled () == 0)
    {
      rv = VNET_API_ERROR_FEATURE_DISABLED;
      goto done;
    }
  ckpair_index = clib_net_to_host_u32 (mp->index);
  rv = vnet_app_del_cert_key_pair (ckpair_index);

done:
  REPLY_MACRO (VL_API_APP_DEL_CERT_KEY_PAIR_REPLY);
}

/* ### WILL BE DEPRECATED POST 20.01 ### */
static void
vl_api_application_tls_cert_add_t_handler (vl_api_application_tls_cert_add_t *
					   mp)
{
  vl_api_application_tls_cert_add_reply_t *rmp;
  app_cert_key_pair_t *ckpair;
  application_t *app;
  u32 cert_len;
  int rv = 0;
  if (session_main_is_enabled () == 0)
    {
      rv = VNET_API_ERROR_FEATURE_DISABLED;
      goto done;
    }
  if (!(app = application_lookup (mp->client_index)))
    {
      rv = VNET_API_ERROR_APPLICATION_NOT_ATTACHED;
      goto done;
    }
  cert_len = clib_net_to_host_u16 (mp->cert_len);
  if (cert_len > 10000)
    {
      rv = VNET_API_ERROR_INVALID_VALUE;
      goto done;
    }
  ckpair = app_cert_key_pair_get_default ();
  vec_validate (ckpair->cert, cert_len);
  clib_memcpy_fast (ckpair->cert, mp->cert, cert_len);

done:
  REPLY_MACRO (VL_API_APPLICATION_TLS_CERT_ADD_REPLY);
}

/* ### WILL BE DEPRECATED POST 20.01 ### */
static void
vl_api_application_tls_key_add_t_handler (vl_api_application_tls_key_add_t *
					  mp)
{
  vl_api_application_tls_key_add_reply_t *rmp;
  app_cert_key_pair_t *ckpair;
  application_t *app;
  u32 key_len;
  int rv = 0;
  if (session_main_is_enabled () == 0)
    {
      rv = VNET_API_ERROR_FEATURE_DISABLED;
      goto done;
    }
  if (!(app = application_lookup (mp->client_index)))
    {
      rv = VNET_API_ERROR_APPLICATION_NOT_ATTACHED;
      goto done;
    }
  key_len = clib_net_to_host_u16 (mp->key_len);
  if (key_len > 10000)
    {
      rv = VNET_API_ERROR_INVALID_VALUE;
      goto done;
    }
  ckpair = app_cert_key_pair_get_default ();
  vec_validate (ckpair->key, key_len);
  clib_memcpy_fast (ckpair->key, mp->key, key_len);
done:
  REPLY_MACRO (VL_API_APPLICATION_TLS_KEY_ADD_REPLY);
}

static clib_error_t *
application_reaper_cb (u32 client_index)
{
  application_t *app = application_lookup (client_index);
  vnet_app_detach_args_t _a, *a = &_a;
  if (app)
    {
      a->app_index = app->app_index;
      a->api_client_index = client_index;
      vnet_application_detach (a);
    }
  return 0;
}

VL_MSG_API_REAPER_FUNCTION (application_reaper_cb);

#define vl_msg_name_crc_list
#include <vnet/vnet_all_api_h.h>
#undef vl_msg_name_crc_list

static void
setup_message_id_table (api_main_t * am)
{
#define _(id,n,crc) vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id);
  foreach_vl_msg_name_crc_session;
#undef _
}

/*
 * session_api_hookup
 * Add uri's API message handlers to the table.
 * vlib has already mapped shared memory and
 * added the client registration handlers.
 * See .../open-repo/vlib/memclnt_vlib.c:memclnt_process()
 */
static clib_error_t *
session_api_hookup (vlib_main_t * vm)
{
  api_main_t *am = vlibapi_get_main ();

#define _(N,n)                                                  \
    vl_msg_api_set_handlers(VL_API_##N, #n,                     \
                           vl_api_##n##_t_handler,              \
                           vl_noop_handler,                     \
                           vl_api_##n##_t_endian,               \
                           vl_api_##n##_t_print,                \
                           sizeof(vl_api_##n##_t), 1);
  foreach_session_api_msg;
#undef _

  /*
   * Messages which bounce off the data-plane to
   * an API client. Simply tells the message handling infra not
   * to free the message.
   *
   * Bounced message handlers MUST NOT block the data plane
   */
  am->message_bounce[VL_API_CONNECT_URI] = 1;
  am->message_bounce[VL_API_CONNECT_SOCK] = 1;

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

  return 0;
}

VLIB_API_INIT_FUNCTION (session_api_hookup);

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