api: multiple connections per process
[vpp.git] / src / vcl / vcl_bapi.c
index b283981..a98b181 100644 (file)
@@ -108,13 +108,13 @@ vcl_vpp_worker_segment_handle (u32 wrk_index)
 }
 
 static void
-vl_api_application_attach_reply_t_handler (vl_api_application_attach_reply_t *
-                                          mp)
+vl_api_app_attach_reply_t_handler (vl_api_app_attach_reply_t * mp)
 {
   vcl_worker_t *wrk = vcl_worker_get (0);
+  svm_msg_q_t *ctrl_mq;
   u64 segment_handle;
+  int *fds = 0, i;
   u32 n_fds = 0;
-  int *fds = 0;
 
   if (mp->retval)
     {
@@ -122,8 +122,11 @@ vl_api_application_attach_reply_t_handler (vl_api_application_attach_reply_t *
       goto failed;
     }
 
-  wrk->app_event_queue = uword_to_pointer (mp->app_event_queue_address,
-                                          svm_msg_q_t *);
+  wrk->app_event_queue = uword_to_pointer (mp->app_mq, svm_msg_q_t *);
+  ctrl_mq = uword_to_pointer (mp->vpp_ctrl_mq, svm_msg_q_t *);
+  vec_validate (wrk->vpp_event_queues, mp->vpp_ctrl_mq_thread);
+  wrk->vpp_event_queues[mp->vpp_ctrl_mq_thread] = ctrl_mq;
+  vcm->ctrl_mq = wrk->ctrl_mq = ctrl_mq;
   segment_handle = clib_net_to_host_u64 (mp->segment_handle);
   if (segment_handle == VCL_INVALID_SEGMENT_HANDLE)
     {
@@ -134,7 +137,8 @@ vl_api_application_attach_reply_t_handler (vl_api_application_attach_reply_t *
   if (mp->n_fds)
     {
       vec_validate (fds, mp->n_fds);
-      vl_socket_client_recv_fd_msg (fds, mp->n_fds, 5);
+      if (vl_socket_client_recv_fd_msg (fds, mp->n_fds, 5))
+       goto failed;
 
       if (mp->fd_flags & SESSION_FD_F_VPP_MQ_SEGMENT)
        if (vcl_segment_attach (vcl_vpp_worker_segment_handle (0),
@@ -169,13 +173,16 @@ vl_api_application_attach_reply_t_handler (vl_api_application_attach_reply_t *
 
 failed:
   vcm->app_state = STATE_APP_FAILED;
+  for (i = clib_max (n_fds - 1, 0); i < vec_len (fds); i++)
+    close (fds[i]);
+  vec_free (fds);
 }
 
 static void
 vl_api_app_worker_add_del_reply_t_handler (vl_api_app_worker_add_del_reply_t *
                                           mp)
 {
-  int n_fds = 0, *fds = 0;
+  int n_fds = 0, *fds = 0, i;
   u64 segment_handle;
   vcl_worker_t *wrk;
   u32 wrk_index;
@@ -198,6 +205,7 @@ vl_api_app_worker_add_del_reply_t_handler (vl_api_app_worker_add_del_reply_t *
   wrk->vpp_wrk_index = clib_net_to_host_u32 (mp->wrk_index);
   wrk->app_event_queue = uword_to_pointer (mp->app_event_queue_address,
                                           svm_msg_q_t *);
+  wrk->ctrl_mq = vcm->ctrl_mq;
 
   segment_handle = clib_net_to_host_u64 (mp->segment_handle);
   if (segment_handle == VCL_INVALID_SEGMENT_HANDLE)
@@ -209,7 +217,8 @@ vl_api_app_worker_add_del_reply_t_handler (vl_api_app_worker_add_del_reply_t *
   if (mp->n_fds)
     {
       vec_validate (fds, mp->n_fds);
-      vl_socket_client_recv_fd_msg (fds, mp->n_fds, 5);
+      if (vl_socket_client_recv_fd_msg (fds, mp->n_fds, 5))
+       goto failed;
 
       if (mp->fd_flags & SESSION_FD_F_VPP_MQ_SEGMENT)
        if (vcl_segment_attach (vcl_vpp_worker_segment_handle (wrk_index),
@@ -243,17 +252,9 @@ vl_api_app_worker_add_del_reply_t_handler (vl_api_app_worker_add_del_reply_t *
 
 failed:
   vcm->app_state = STATE_APP_FAILED;
-}
-
-static void
-vl_api_application_detach_reply_t_handler (vl_api_application_detach_reply_t *
-                                          mp)
-{
-  if (mp->retval)
-    clib_warning ("VCL<%d>: detach failed: %U", getpid (), format_api_error,
-                 ntohl (mp->retval));
-
-  vcm->app_state = STATE_APP_ENABLED;
+  for (i = clib_max (n_fds - 1, 0); i < vec_len (fds); i++)
+    close (fds[i]);
+  vec_free (fds);
 }
 
 static void
@@ -296,51 +297,13 @@ vl_api_unmap_segment_t_handler (vl_api_unmap_segment_t * mp)
   VDBG (1, "Unmapped segment: %d", segment_handle);
 }
 
-static void
-vl_api_bind_sock_reply_t_handler (vl_api_bind_sock_reply_t * mp)
-{
-  /* Expecting a similar message on mq. So ignore this */
-  VDBG (0, "bapi bind retval: %u!", mp->retval);
-}
-
-static void
-vl_api_unbind_sock_reply_t_handler (vl_api_unbind_sock_reply_t * mp)
-{
-  if (mp->retval)
-    VDBG (0, "ERROR: sid %u: unbind failed: %U", mp->context,
-         format_api_error, ntohl (mp->retval));
-
-  VDBG (1, "sid %u: unbind succeeded!", mp->context);
-
-}
-
-static void
-vl_api_disconnect_session_reply_t_handler (vl_api_disconnect_session_reply_t *
-                                          mp)
-{
-  if (mp->retval)
-    VDBG (0, "ERROR: sid %u: disconnect failed: %U", mp->context,
-         format_api_error, ntohl (mp->retval));
-}
-
-static void
-vl_api_connect_sock_reply_t_handler (vl_api_connect_sock_reply_t * mp)
-{
-  if (mp->retval)
-    VDBG (0, "ERROR: connect failed: %U", format_api_error,
-         ntohl (mp->retval));
-}
-
 static void
   vl_api_application_tls_cert_add_reply_t_handler
   (vl_api_application_tls_cert_add_reply_t * mp)
 {
   if (mp->retval)
-    {
-      clib_warning ("VCL<%d>: add cert failed: %U", getpid (),
-                   format_api_error, ntohl (mp->retval));
-      return;
-    }
+    VDBG (0, "add cert failed: %U", format_api_error, ntohl (mp->retval));
+  vcm->app_state = STATE_APP_READY;
 }
 
 static void
@@ -348,22 +311,13 @@ static void
   (vl_api_application_tls_key_add_reply_t * mp)
 {
   if (mp->retval)
-    {
-      clib_warning ("VCL<%d>: add key failed: %U", getpid (),
-                   format_api_error, ntohl (mp->retval));
-      return;
-    }
-
+    VDBG (0, "add key failed: %U", format_api_error, ntohl (mp->retval));
+  vcm->app_state = STATE_APP_READY;
 }
 
 #define foreach_sock_msg                                               \
 _(SESSION_ENABLE_DISABLE_REPLY, session_enable_disable_reply)          \
-_(BIND_SOCK_REPLY, bind_sock_reply)                                    \
-_(UNBIND_SOCK_REPLY, unbind_sock_reply)                                \
-_(CONNECT_SOCK_REPLY, connect_sock_reply)                              \
-_(DISCONNECT_SESSION_REPLY, disconnect_session_reply)                  \
-_(APPLICATION_ATTACH_REPLY, application_attach_reply)                  \
-_(APPLICATION_DETACH_REPLY, application_detach_reply)                  \
+_(APP_ATTACH_REPLY, app_attach_reply)                                  \
 _(APPLICATION_TLS_CERT_ADD_REPLY, application_tls_cert_add_reply)      \
 _(APPLICATION_TLS_KEY_ADD_REPLY, application_tls_key_add_reply)        \
 _(MAP_ANOTHER_SEGMENT, map_another_segment)                            \
@@ -406,15 +360,18 @@ void
 vppcom_app_send_attach (void)
 {
   vcl_worker_t *wrk = vcl_worker_get_current ();
-  vl_api_application_attach_t *bmp;
+  u8 tls_engine = CRYPTO_ENGINE_OPENSSL;
+  vl_api_app_attach_t *bmp;
   u8 nsid_len = vec_len (vcm->cfg.namespace_id);
   u8 app_is_proxy = (vcm->cfg.app_proxy_transport_tcp ||
                     vcm->cfg.app_proxy_transport_udp);
 
+  tls_engine = vcm->cfg.tls_engine ? vcm->cfg.tls_engine : tls_engine;
+
   bmp = vl_msg_api_alloc (sizeof (*bmp));
   memset (bmp, 0, sizeof (*bmp));
 
-  bmp->_vl_msg_id = ntohs (VL_API_APPLICATION_ATTACH);
+  bmp->_vl_msg_id = ntohs (VL_API_APP_ATTACH);
   bmp->client_index = wrk->my_client_index;
   bmp->context = htonl (0xfeedface);
   bmp->options[APP_OPTIONS_FLAGS] =
@@ -433,7 +390,7 @@ vppcom_app_send_attach (void)
   bmp->options[APP_OPTIONS_PREALLOC_FIFO_PAIRS] =
     vcm->cfg.preallocated_fifo_pairs;
   bmp->options[APP_OPTIONS_EVT_QUEUE_SIZE] = vcm->cfg.event_queue_size;
-  bmp->options[APP_OPTIONS_TLS_ENGINE] = TLS_ENGINE_OPENSSL;
+  bmp->options[APP_OPTIONS_TLS_ENGINE] = tls_engine;
   if (nsid_len)
     {
       bmp->namespace_id_len = nsid_len;
@@ -496,79 +453,6 @@ vcl_send_child_worker_del (vcl_worker_t * child_wrk)
   vl_msg_api_send_shmem (wrk->vl_input_queue, (u8 *) & mp);
 }
 
-void
-vppcom_send_connect_sock (vcl_session_t * session)
-{
-  vcl_worker_t *wrk = vcl_worker_get_current ();
-  vl_api_connect_sock_t *cmp;
-
-  cmp = vl_msg_api_alloc (sizeof (*cmp));
-  memset (cmp, 0, sizeof (*cmp));
-  cmp->_vl_msg_id = ntohs (VL_API_CONNECT_SOCK);
-  cmp->client_index = wrk->my_client_index;
-  cmp->context = session->session_index;
-  cmp->wrk_index = wrk->vpp_wrk_index;
-  cmp->is_ip4 = session->transport.is_ip4;
-  clib_memcpy_fast (cmp->ip, &session->transport.rmt_ip, sizeof (cmp->ip));
-  cmp->port = session->transport.rmt_port;
-  cmp->proto = session->session_type;
-  vl_msg_api_send_shmem (wrk->vl_input_queue, (u8 *) & cmp);
-}
-
-void
-vppcom_send_disconnect_session (u64 vpp_handle)
-{
-  vcl_worker_t *wrk = vcl_worker_get_current ();
-  vl_api_disconnect_session_t *dmp;
-
-  dmp = vl_msg_api_alloc (sizeof (*dmp));
-  memset (dmp, 0, sizeof (*dmp));
-  dmp->_vl_msg_id = ntohs (VL_API_DISCONNECT_SESSION);
-  dmp->client_index = wrk->my_client_index;
-  dmp->handle = vpp_handle;
-  vl_msg_api_send_shmem (wrk->vl_input_queue, (u8 *) & dmp);
-}
-
-/* VPP combines bind and listen as one operation. VCL manages the separation
- * of bind and listen locally via vppcom_session_bind() and
- * vppcom_session_listen() */
-void
-vppcom_send_bind_sock (vcl_session_t * session)
-{
-  vcl_worker_t *wrk = vcl_worker_get_current ();
-  vl_api_bind_sock_t *bmp;
-
-  /* Assumes caller has acquired spinlock: vcm->sessions_lockp */
-  bmp = vl_msg_api_alloc (sizeof (*bmp));
-  memset (bmp, 0, sizeof (*bmp));
-
-  bmp->_vl_msg_id = ntohs (VL_API_BIND_SOCK);
-  bmp->client_index = wrk->my_client_index;
-  bmp->context = session->session_index;
-  bmp->wrk_index = wrk->vpp_wrk_index;
-  bmp->is_ip4 = session->transport.is_ip4;
-  clib_memcpy_fast (bmp->ip, &session->transport.lcl_ip, sizeof (bmp->ip));
-  bmp->port = session->transport.lcl_port;
-  bmp->proto = session->session_type;
-  vl_msg_api_send_shmem (wrk->vl_input_queue, (u8 *) & bmp);
-}
-
-void
-vppcom_send_unbind_sock (vcl_worker_t * wrk, u64 vpp_handle)
-{
-  vl_api_unbind_sock_t *ump;
-
-  ump = vl_msg_api_alloc (sizeof (*ump));
-  memset (ump, 0, sizeof (*ump));
-
-  ump->_vl_msg_id = ntohs (VL_API_UNBIND_SOCK);
-  ump->client_index = wrk->my_client_index;
-  ump->wrk_index = wrk->vpp_wrk_index;
-  ump->handle = vpp_handle;
-  ump->context = wrk->wrk_index;
-  vl_msg_api_send_shmem (wrk->vl_input_queue, (u8 *) & ump);
-}
-
 void
 vppcom_send_application_tls_cert_add (vcl_session_t * session, char *cert,
                                      u32 cert_len)
@@ -584,7 +468,6 @@ vppcom_send_application_tls_cert_add (vcl_session_t * session, char *cert,
   cert_mp->cert_len = clib_host_to_net_u16 (cert_len);
   clib_memcpy_fast (cert_mp->cert, cert, cert_len);
   vl_msg_api_send_shmem (wrk->vl_input_queue, (u8 *) & cert_mp);
-
 }
 
 void
@@ -602,7 +485,6 @@ vppcom_send_application_tls_key_add (vcl_session_t * session, char *key,
   key_mp->key_len = clib_host_to_net_u16 (key_len);
   clib_memcpy_fast (key_mp->key, key, key_len);
   vl_msg_api_send_shmem (wrk->vl_input_queue, (u8 *) & key_mp);
-
 }
 
 u32
@@ -628,7 +510,7 @@ int
 vppcom_connect_to_vpp (char *app_name)
 {
   vcl_worker_t *wrk = vcl_worker_get_current ();
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
   vppcom_cfg_t *vcl_cfg = &vcm->cfg;
 
   if (vcl_cfg->vpp_api_socket_name)
@@ -672,6 +554,17 @@ vppcom_connect_to_vpp (char *app_name)
   return VPPCOM_OK;
 }
 
+void
+vppcom_disconnect_from_vpp (void)
+{
+  vppcom_cfg_t *vcl_cfg = &vcm->cfg;
+
+  if (vcl_cfg->vpp_api_socket_name)
+    vl_socket_client_disconnect ();
+  else
+    vl_client_disconnect_from_vlib ();
+}
+
 /*
  * fd.io coding-style-patch-verification: ON
  *