X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fplugins%2Fhs_apps%2Fsapi%2Fvpp_echo_bapi.c;h=c3b53c86ae2a42b8289adb548c17a0b0dfa91d4a;hb=85a9c101bffe99da141b496f95966258b922a440;hp=dafcd8a42b60e11f24f07cf555258672d3df3398;hpb=ecd1fc7dfa6a36d1774f71093380b3548a22346b;p=vpp.git diff --git a/src/plugins/hs_apps/sapi/vpp_echo_bapi.c b/src/plugins/hs_apps/sapi/vpp_echo_bapi.c index dafcd8a42b6..c3b53c86ae2 100644 --- a/src/plugins/hs_apps/sapi/vpp_echo_bapi.c +++ b/src/plugins/hs_apps/sapi/vpp_echo_bapi.c @@ -18,6 +18,9 @@ #include +#define REPLY_MSG_ID_BASE msg_id_base +static u16 msg_id_base; + /* * * Binary API Messages @@ -27,51 +30,28 @@ void echo_send_attach (echo_main_t * em) { - vl_api_application_attach_t *bmp; - vl_api_application_tls_cert_add_t *cert_mp; - vl_api_application_tls_key_add_t *key_mp; - + vl_api_app_attach_t *bmp; bmp = vl_msg_api_alloc (sizeof (*bmp)); clib_memset (bmp, 0, sizeof (*bmp)); - bmp->_vl_msg_id = ntohs (VL_API_APPLICATION_ATTACH); + bmp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_APP_ATTACH); bmp->client_index = em->my_client_index; bmp->context = ntohl (0xfeedface); bmp->options[APP_OPTIONS_FLAGS] = APP_OPTIONS_FLAGS_ACCEPT_REDIRECT; bmp->options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_ADD_SEGMENT; - bmp->options[APP_OPTIONS_PREALLOC_FIFO_PAIRS] = 16; + bmp->options[APP_OPTIONS_PREALLOC_FIFO_PAIRS] = em->prealloc_fifo_pairs; bmp->options[APP_OPTIONS_RX_FIFO_SIZE] = em->fifo_size; bmp->options[APP_OPTIONS_TX_FIFO_SIZE] = em->fifo_size; bmp->options[APP_OPTIONS_ADD_SEGMENT_SIZE] = 128 << 20; bmp->options[APP_OPTIONS_SEGMENT_SIZE] = 256 << 20; - bmp->options[APP_OPTIONS_EVT_QUEUE_SIZE] = 256; + bmp->options[APP_OPTIONS_EVT_QUEUE_SIZE] = em->evt_q_size; if (em->appns_id) { - bmp->namespace_id_len = vec_len (em->appns_id); - clib_memcpy_fast (bmp->namespace_id, em->appns_id, - bmp->namespace_id_len); + vl_api_vec_to_api_string (em->appns_id, &bmp->namespace_id); bmp->options[APP_OPTIONS_FLAGS] |= em->appns_flags; bmp->options[APP_OPTIONS_NAMESPACE_SECRET] = em->appns_secret; } vl_msg_api_send_shmem (em->vl_input_queue, (u8 *) & bmp); - - cert_mp = vl_msg_api_alloc (sizeof (*cert_mp) + test_srv_crt_rsa_len); - clib_memset (cert_mp, 0, sizeof (*cert_mp)); - cert_mp->_vl_msg_id = ntohs (VL_API_APPLICATION_TLS_CERT_ADD); - cert_mp->client_index = em->my_client_index; - cert_mp->context = ntohl (0xfeedface); - cert_mp->cert_len = clib_host_to_net_u16 (test_srv_crt_rsa_len); - clib_memcpy_fast (cert_mp->cert, test_srv_crt_rsa, test_srv_crt_rsa_len); - vl_msg_api_send_shmem (em->vl_input_queue, (u8 *) & cert_mp); - - key_mp = vl_msg_api_alloc (sizeof (*key_mp) + test_srv_key_rsa_len); - clib_memset (key_mp, 0, sizeof (*key_mp) + test_srv_key_rsa_len); - key_mp->_vl_msg_id = ntohs (VL_API_APPLICATION_TLS_KEY_ADD); - key_mp->client_index = em->my_client_index; - key_mp->context = ntohl (0xfeedface); - key_mp->key_len = clib_host_to_net_u16 (test_srv_key_rsa_len); - clib_memcpy_fast (key_mp->key, test_srv_key_rsa, test_srv_key_rsa_len); - vl_msg_api_send_shmem (em->vl_input_queue, (u8 *) & key_mp); } void @@ -81,66 +61,161 @@ echo_send_detach (echo_main_t * em) bmp = vl_msg_api_alloc (sizeof (*bmp)); clib_memset (bmp, 0, sizeof (*bmp)); - bmp->_vl_msg_id = ntohs (VL_API_APPLICATION_DETACH); + bmp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_APPLICATION_DETACH); + bmp->client_index = em->my_client_index; + bmp->context = ntohl (0xfeedface); + + vl_msg_api_send_shmem (em->vl_input_queue, (u8 *) & bmp); +} + +void +echo_send_add_cert_key (echo_main_t * em) +{ + u32 cert_len = test_srv_crt_rsa_len; + u32 key_len = test_srv_key_rsa_len; + vl_api_app_add_cert_key_pair_t *bmp; + + bmp = vl_msg_api_alloc (sizeof (*bmp) + cert_len + key_len); + clib_memset (bmp, 0, sizeof (*bmp) + cert_len + key_len); + + bmp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_APP_ADD_CERT_KEY_PAIR); bmp->client_index = em->my_client_index; bmp->context = ntohl (0xfeedface); + bmp->cert_len = clib_host_to_net_u16 (cert_len); + bmp->certkey_len = clib_host_to_net_u16 (key_len + cert_len); + clib_memcpy_fast (bmp->certkey, test_srv_crt_rsa, cert_len); + clib_memcpy_fast (bmp->certkey + cert_len, test_srv_key_rsa, key_len); + vl_msg_api_send_shmem (em->vl_input_queue, (u8 *) & bmp); } void -echo_send_listen (echo_main_t * em) +echo_send_del_cert_key (echo_main_t * em) { - vl_api_bind_uri_t *bmp; + vl_api_app_del_cert_key_pair_t *bmp; bmp = vl_msg_api_alloc (sizeof (*bmp)); clib_memset (bmp, 0, sizeof (*bmp)); - bmp->_vl_msg_id = ntohs (VL_API_BIND_URI); + bmp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_APP_DEL_CERT_KEY_PAIR); bmp->client_index = em->my_client_index; bmp->context = ntohl (0xfeedface); - memcpy (bmp->uri, em->uri, vec_len (em->uri)); + bmp->index = clib_host_to_net_u32 (em->ckpair_index); vl_msg_api_send_shmem (em->vl_input_queue, (u8 *) & bmp); } -void -echo_send_unbind (echo_main_t * em) +static u8 +echo_transport_needs_crypto (transport_proto_t proto) { - vl_api_unbind_uri_t *ump; + return proto == TRANSPORT_PROTO_TLS || proto == TRANSPORT_PROTO_DTLS || + proto == TRANSPORT_PROTO_QUIC; +} - ump = vl_msg_api_alloc (sizeof (*ump)); - clib_memset (ump, 0, sizeof (*ump)); +static void +echo_msg_add_crypto_ext_config (echo_main_t *em, uword *offset) +{ + transport_endpt_ext_cfg_t cfg; + svm_fifo_chunk_t *c; - ump->_vl_msg_id = ntohs (VL_API_UNBIND_URI); - ump->client_index = em->my_client_index; - memcpy (ump->uri, em->uri, vec_len (em->uri)); - vl_msg_api_send_shmem (em->vl_input_queue, (u8 *) & ump); + c = echo_segment_alloc_chunk (ECHO_MQ_SEG_HANDLE, 0, sizeof (cfg), offset); + if (!c) + return; + + memset (&cfg, 0, sizeof (cfg)); + cfg.type = TRANSPORT_ENDPT_EXT_CFG_CRYPTO; + cfg.len = sizeof (cfg); + cfg.crypto.ckpair_index = em->ckpair_index; + cfg.crypto.crypto_engine = em->crypto_engine; + clib_memcpy_fast (c->data, &cfg, cfg.len); } void -echo_send_connect (u8 * uri, u32 opaque) +echo_send_listen (echo_main_t * em, ip46_address_t * ip) { - echo_main_t *em = &echo_main; - vl_api_connect_uri_t *cmp; - cmp = vl_msg_api_alloc (sizeof (*cmp)); - clib_memset (cmp, 0, sizeof (*cmp)); - cmp->_vl_msg_id = ntohs (VL_API_CONNECT_URI); - cmp->client_index = em->my_client_index; - cmp->context = ntohl (opaque); - memcpy (cmp->uri, uri, vec_len (uri)); - vl_msg_api_send_shmem (em->vl_input_queue, (u8 *) & cmp); + app_session_evt_t _app_evt, *app_evt = &_app_evt; + session_listen_msg_t *mp; + svm_msg_q_t *mq = em->ctrl_mq; + + app_alloc_ctrl_evt_to_vpp (mq, app_evt, SESSION_CTRL_EVT_LISTEN); + mp = (session_listen_msg_t *) app_evt->evt->data; + memset (mp, 0, sizeof (*mp)); + mp->client_index = em->my_client_index; + mp->context = ntohl (0xfeedface); + mp->wrk_index = 0; + mp->is_ip4 = em->uri_elts.is_ip4; + clib_memcpy_fast (&mp->ip, ip, sizeof (mp->ip)); + mp->port = em->uri_elts.port; + mp->proto = em->uri_elts.transport_proto; + if (echo_transport_needs_crypto (mp->proto)) + echo_msg_add_crypto_ext_config (em, &mp->ext_config); + app_send_ctrl_evt_to_vpp (mq, app_evt); } void -echo_send_disconnect_session (u64 handle, u32 opaque) +echo_send_unbind (echo_main_t * em, echo_session_t * s) { - echo_main_t *em = &echo_main; - vl_api_disconnect_session_t *dmp; - dmp = vl_msg_api_alloc (sizeof (*dmp)); - clib_memset (dmp, 0, sizeof (*dmp)); - dmp->_vl_msg_id = ntohs (VL_API_DISCONNECT_SESSION); - dmp->client_index = em->my_client_index; - dmp->handle = handle; - ECHO_LOG (1, "Disconnect session 0x%lx", dmp->handle); - vl_msg_api_send_shmem (em->vl_input_queue, (u8 *) & dmp); + app_session_evt_t _app_evt, *app_evt = &_app_evt; + session_unlisten_msg_t *mp; + svm_msg_q_t *mq = em->ctrl_mq; + + app_alloc_ctrl_evt_to_vpp (mq, app_evt, SESSION_CTRL_EVT_UNLISTEN); + mp = (session_unlisten_msg_t *) app_evt->evt->data; + memset (mp, 0, sizeof (*mp)); + mp->client_index = em->my_client_index; + mp->wrk_index = 0; + mp->handle = s->vpp_session_handle; + mp->context = 0; + app_send_ctrl_evt_to_vpp (mq, app_evt); +} + +void +echo_send_connect (echo_main_t * em, void *args) +{ + app_session_evt_t _app_evt, *app_evt = &_app_evt; + session_connect_msg_t *mp; + echo_connect_args_t *a = (echo_connect_args_t *) args; + svm_msg_q_t *mq = em->ctrl_mq; + + clib_atomic_sub_fetch (&em->max_sim_connects, 1); + while (em->max_sim_connects <= 0) + ; + + app_alloc_ctrl_evt_to_vpp (mq, app_evt, SESSION_CTRL_EVT_CONNECT); + mp = (session_connect_msg_t *) app_evt->evt->data; + memset (mp, 0, sizeof (*mp)); + mp->client_index = em->my_client_index; + mp->context = ntohl (a->context); + mp->wrk_index = 0; + mp->is_ip4 = em->uri_elts.is_ip4; + clib_memcpy_fast (&mp->ip, &a->ip, sizeof (mp->ip)); + clib_memcpy_fast (&mp->lcl_ip, &a->lcl_ip, sizeof (mp->ip)); + mp->port = em->uri_elts.port; + mp->proto = em->uri_elts.transport_proto; + mp->parent_handle = a->parent_session_handle; + if (echo_transport_needs_crypto (mp->proto)) + echo_msg_add_crypto_ext_config (em, &mp->ext_config); + mp->flags = em->connect_flag; + app_send_ctrl_evt_to_vpp (mq, app_evt); +} + +void +echo_send_disconnect_session (echo_main_t * em, void *args) +{ + echo_session_t *s; + app_session_evt_t _app_evt, *app_evt = &_app_evt; + session_disconnect_msg_t *mp; + svm_msg_q_t *mq = em->ctrl_mq; + echo_disconnect_args_t *a = (echo_disconnect_args_t *) args; + + app_alloc_ctrl_evt_to_vpp (mq, app_evt, SESSION_CTRL_EVT_DISCONNECT); + mp = (session_disconnect_msg_t *) app_evt->evt->data; + memset (mp, 0, sizeof (*mp)); + mp->client_index = em->my_client_index; + mp->handle = a->session_handle; + app_send_ctrl_evt_to_vpp (mq, app_evt); + + if (!(s = echo_get_session_from_handle (em, mp->handle))) + return; + em->proto_cb_vft->sent_disconnect_cb (s); } /* @@ -149,11 +224,13 @@ echo_send_disconnect_session (u64 handle, u32 opaque) * */ -static int -ssvm_segment_attach (char *name, ssvm_segment_type_t type, int fd) +int +echo_segment_attach (u64 segment_handle, char *name, ssvm_segment_type_t type, + int fd) { fifo_segment_create_args_t _a, *a = &_a; - fifo_segment_main_t *sm = &echo_main.segment_main; + echo_main_t *em = &echo_main; + fifo_segment_main_t *sm; int rv; clib_memset (a, 0, sizeof (*a)); @@ -163,269 +240,345 @@ ssvm_segment_attach (char *name, ssvm_segment_type_t type, int fd) if (type == SSVM_SEGMENT_MEMFD) a->memfd_fd = fd; + sm = &em->segment_main; + if ((rv = fifo_segment_attach (sm, a))) return rv; - vec_reset_length (a->new_segment_indices); + + clib_spinlock_lock (&em->segment_handles_lock); + hash_set (em->shared_segment_handles, segment_handle, + a->new_segment_indices[0]); + clib_spinlock_unlock (&em->segment_handles_lock); + + vec_free (a->new_segment_indices); return 0; } -static inline void -echo_segment_handle_add_del (echo_main_t * em, u64 segment_handle, u8 add) +u32 +echo_segment_lookup (u64 segment_handle) { + echo_main_t *em = &echo_main; + uword *segment_idxp; + + ECHO_LOG (3, "Check if segment mapped 0x%lx...", segment_handle); + clib_spinlock_lock (&em->segment_handles_lock); - if (add) - hash_set (em->shared_segment_handles, segment_handle, 1); - else - hash_unset (em->shared_segment_handles, segment_handle); + segment_idxp = hash_get (em->shared_segment_handles, segment_handle); clib_spinlock_unlock (&em->segment_handles_lock); + if (segment_idxp) + return ((u32) *segment_idxp); + + ECHO_LOG (2, "Segment not mapped (0x%lx)", segment_handle); + return ~0; } -/* - * - * Binary API callbacks - * - */ +void +echo_segment_detach (u64 segment_handle) +{ + echo_main_t *em = &echo_main; + fifo_segment_main_t *sm; -static void -vl_api_application_attach_reply_t_handler (vl_api_application_attach_reply_t * - mp) + u32 segment_index = echo_segment_lookup (segment_handle); + if (segment_index == (u32) ~0) + return; + + sm = &em->segment_main; + + clib_spinlock_lock (&em->segment_handles_lock); + fifo_segment_delete (sm, fifo_segment_get_segment (sm, segment_index)); + hash_unset (em->shared_segment_handles, segment_handle); + clib_spinlock_unlock (&em->segment_handles_lock); +} + +int +echo_attach_session (uword segment_handle, uword rxf_offset, uword txf_offset, + uword mq_offset, echo_session_t *s) { echo_main_t *em = &echo_main; - int *fds = 0, i; - u32 n_fds = 0; - u64 segment_handle; - segment_handle = clib_net_to_host_u64 (mp->segment_handle); - ECHO_LOG (1, "Attached returned app %u", htons (mp->app_index)); + u32 fs_index, eqs_index; + fifo_segment_t *fs; - if (mp->retval) + fs_index = echo_segment_lookup (segment_handle); + if (fs_index == (u32) ~0) { - ECHO_FAIL ("attach failed: %U", format_api_error, - clib_net_to_host_u32 (mp->retval)); - return; + ECHO_LOG (0, "ERROR: segment for session %u is not mounted!", + s->session_index); + return -1; } - if (mp->segment_name_length == 0) + if (mq_offset != (uword) ~0) { - ECHO_FAIL ("segment_name_length zero"); - return; + eqs_index = echo_segment_lookup (ECHO_MQ_SEG_HANDLE); + ASSERT (eqs_index != (u32) ~0); } - ASSERT (mp->app_event_queue_address); - em->our_event_queue = uword_to_pointer (mp->app_event_queue_address, - svm_msg_q_t *); + clib_spinlock_lock (&em->segment_handles_lock); + + fs = fifo_segment_get_segment (&em->segment_main, fs_index); + s->rx_fifo = fifo_segment_alloc_fifo_w_offset (fs, rxf_offset); + s->tx_fifo = fifo_segment_alloc_fifo_w_offset (fs, txf_offset); + s->rx_fifo->segment_index = fs_index; + s->tx_fifo->segment_index = fs_index; + s->rx_fifo->shr->client_session_index = s->session_index; + s->tx_fifo->shr->client_session_index = s->session_index; - if (mp->n_fds) + if (mq_offset != (uword) ~0) { - vec_validate (fds, mp->n_fds); - if (vl_socket_client_recv_fd_msg (fds, mp->n_fds, 5)) - { - ECHO_FAIL ("vl_socket_client_recv_fd_msg failed"); - goto failed; - } + fs = fifo_segment_get_segment (&em->segment_main, eqs_index); + s->vpp_evt_q = fifo_segment_msg_q_attach (fs, mq_offset, + s->rx_fifo->shr->slice_index); + } - if (mp->fd_flags & SESSION_FD_F_VPP_MQ_SEGMENT) - if (ssvm_segment_attach (0, SSVM_SEGMENT_MEMFD, fds[n_fds++])) - { - ECHO_FAIL ("svm_fifo_segment_attach failed"); - goto failed; - } + clib_spinlock_unlock (&em->segment_handles_lock); - if (mp->fd_flags & SESSION_FD_F_MEMFD_SEGMENT) - if (ssvm_segment_attach ((char *) mp->segment_name, - SSVM_SEGMENT_MEMFD, fds[n_fds++])) - { - ECHO_FAIL ("svm_fifo_segment_attach ('%s') failed", - mp->segment_name); - goto failed; - } - if (mp->fd_flags & SESSION_FD_F_MQ_EVENTFD) - svm_msg_q_set_consumer_eventfd (em->our_event_queue, fds[n_fds++]); + return 0; +} - vec_free (fds); +int +echo_segment_attach_mq (uword segment_handle, uword mq_offset, u32 mq_index, + svm_msg_q_t **mq) +{ + echo_main_t *em = &echo_main; + fifo_segment_t *fs; + u32 fs_index; + + fs_index = echo_segment_lookup (segment_handle); + if (fs_index == (u32) ~0) + { + ECHO_LOG (0, "ERROR: mq segment %lx for is not attached!", + segment_handle); + return -1; } - else + + clib_spinlock_lock (&em->segment_handles_lock); + + fs = fifo_segment_get_segment (&em->segment_main, fs_index); + *mq = fifo_segment_msg_q_attach (fs, mq_offset, mq_index); + + clib_spinlock_unlock (&em->segment_handles_lock); + + return 0; +} + +svm_fifo_chunk_t * +echo_segment_alloc_chunk (uword segment_handle, u32 slice_index, u32 size, + uword *offset) +{ + echo_main_t *em = &echo_main; + svm_fifo_chunk_t *c; + fifo_segment_t *fs; + u32 fs_index; + + fs_index = echo_segment_lookup (segment_handle); + if (fs_index == (u32) ~0) { - if (ssvm_segment_attach ((char *) mp->segment_name, SSVM_SEGMENT_SHM, - -1)) - { - ECHO_FAIL ("svm_fifo_segment_attach ('%s') failed", - mp->segment_name); - return; - } + ECHO_LOG (0, "ERROR: mq segment %lx for is not attached!", + segment_handle); + return 0; } - echo_segment_handle_add_del (em, segment_handle, 1 /* add */ ); - ECHO_LOG (1, "Mapped segment 0x%lx", segment_handle); - em->state = STATE_ATTACHED; - return; -failed: - for (i = clib_max (n_fds - 1, 0); i < vec_len (fds); i++) - close (fds[i]); - vec_free (fds); + clib_spinlock_lock (&em->segment_handles_lock); + + fs = fifo_segment_get_segment (&em->segment_main, fs_index); + c = fifo_segment_alloc_chunk_w_slice (fs, slice_index, size); + *offset = fifo_segment_chunk_offset (fs, c); + + clib_spinlock_unlock (&em->segment_handles_lock); + + return c; } +/* + * + * Binary API callbacks + * + */ + static void -vl_api_application_detach_reply_t_handler (vl_api_application_detach_reply_t * - mp) + vl_api_app_add_cert_key_pair_reply_t_handler + (vl_api_app_add_cert_key_pair_reply_t * mp) { + echo_main_t *em = &echo_main; if (mp->retval) { - ECHO_FAIL ("detach returned with err: %d", mp->retval); + ECHO_FAIL (ECHO_FAIL_VL_API_CERT_KEY_ADD_REPLY, + "Adding cert and key returned %d", + clib_net_to_host_u32 (mp->retval)); return; } - echo_main.state = STATE_DETACHED; + /* No concurrency here, only bapi thread writes */ + if (em->state != STATE_ATTACHED_NO_CERT) + { + ECHO_FAIL (ECHO_FAIL_VL_API_CERT_KEY_ADD_REPLY, "Wrong state"); + return; + } + em->ckpair_index = clib_net_to_host_u32 (mp->index); + em->state = STATE_ATTACHED; } - static void -vl_api_unmap_segment_t_handler (vl_api_unmap_segment_t * mp) + vl_api_app_del_cert_key_pair_reply_t_handler + (vl_api_app_del_cert_key_pair_reply_t * mp) { echo_main_t *em = &echo_main; - u64 segment_handle = clib_net_to_host_u64 (mp->segment_handle); - echo_segment_handle_add_del (em, segment_handle, 0 /* add */ ); - ECHO_LOG (1, "Unmaped segment 0x%lx", segment_handle); + if (mp->retval) + { + ECHO_FAIL (ECHO_FAIL_VL_API_CERT_KEY_DEL_REPLY, + "Delete cert and key returned %d", + clib_net_to_host_u32 (mp->retval)); + return; + } + em->state = STATE_CLEANED_CERT_KEY; } static void -vl_api_map_another_segment_t_handler (vl_api_map_another_segment_t * mp) +vl_api_app_attach_reply_t_handler (vl_api_app_attach_reply_t * mp) { - fifo_segment_main_t *sm = &echo_main.segment_main; - fifo_segment_create_args_t _a, *a = &_a; echo_main_t *em = &echo_main; - int *fds = 0, i; - char *seg_name = (char *) mp->segment_name; - u64 segment_handle = clib_net_to_host_u64 (mp->segment_handle); + int *fds = 0, i, rv; + u32 n_fds = 0; + u64 segment_handle; + char *segment_name = 0; - if (mp->fd_flags & SESSION_FD_F_MEMFD_SEGMENT) + segment_handle = clib_net_to_host_u64 (mp->segment_handle); + ECHO_LOG (2, "Attached returned app %u", htons (mp->app_index)); + + if (mp->retval) { - vec_validate (fds, 1); - if (vl_socket_client_recv_fd_msg (fds, 1, 5)) + ECHO_FAIL (ECHO_FAIL_VL_API_APP_ATTACH, "attach failed: %U", + format_api_error, clib_net_to_host_u32 (mp->retval)); + return; + } + + if (!mp->app_mq) + { + ECHO_FAIL (ECHO_FAIL_VL_API_NULL_APP_MQ, "NULL app_mq"); + return; + } + + if (mp->n_fds) + { + vec_validate (fds, mp->n_fds); + if (vl_socket_client_recv_fd_msg (fds, mp->n_fds, 5)) { - ECHO_FAIL ("vl_socket_client_recv_fd_msg failed"); + ECHO_FAIL (ECHO_FAIL_VL_API_RECV_FD_MSG, + "vl_socket_client_recv_fd_msg failed"); goto failed; } - if (ssvm_segment_attach (seg_name, SSVM_SEGMENT_MEMFD, fds[0])) + if (mp->fd_flags & SESSION_FD_F_VPP_MQ_SEGMENT) + if (echo_segment_attach (ECHO_MQ_SEG_HANDLE, 0, SSVM_SEGMENT_MEMFD, + fds[n_fds++])) + { + ECHO_FAIL (ECHO_FAIL_VL_API_SVM_FIFO_SEG_ATTACH, + "svm_fifo_segment_attach failed on SSVM_SEGMENT_MEMFD"); + goto failed; + } + echo_segment_attach_mq (ECHO_MQ_SEG_HANDLE, mp->vpp_ctrl_mq, + mp->vpp_ctrl_mq_thread, &em->ctrl_mq); + + if (mp->fd_flags & SESSION_FD_F_MEMFD_SEGMENT) { - ECHO_FAIL ("svm_fifo_segment_attach ('%s')" - "failed on SSVM_SEGMENT_MEMFD", seg_name); - goto failed; + segment_name = vl_api_from_api_to_new_c_string (&mp->segment_name); + rv = echo_segment_attach (segment_handle, segment_name, + SSVM_SEGMENT_MEMFD, fds[n_fds++]); + if (rv != 0) + { + ECHO_FAIL (ECHO_FAIL_VL_API_SVM_FIFO_SEG_ATTACH, + "svm_fifo_segment_attach ('%s') " + "failed on SSVM_SEGMENT_MEMFD", segment_name); + vec_free (segment_name); + goto failed; + } + vec_free (segment_name); } + echo_segment_attach_mq (segment_handle, mp->app_mq, 0, &em->app_mq); + + if (mp->fd_flags & SESSION_FD_F_MQ_EVENTFD) + svm_msg_q_set_eventfd (em->app_mq, fds[n_fds++]); + vec_free (fds); } else { - clib_memset (a, 0, sizeof (*a)); - a->segment_name = seg_name; - a->segment_size = mp->segment_size; - /* Attach to the segment vpp created */ - if (fifo_segment_attach (sm, a)) + segment_name = vl_api_from_api_to_new_c_string (&mp->segment_name); + rv = echo_segment_attach (segment_handle, segment_name, SSVM_SEGMENT_SHM, + -1); + if (rv != 0) { - ECHO_FAIL ("svm_fifo_segment_attach ('%s') failed", seg_name); + ECHO_FAIL (ECHO_FAIL_VL_API_SVM_FIFO_SEG_ATTACH, + "svm_fifo_segment_attach ('%s') " + "failed on SSVM_SEGMENT_SHM", segment_name); + vec_free (segment_name); goto failed; } + vec_free (segment_name); } - echo_segment_handle_add_del (em, segment_handle, 1 /* add */ ); - ECHO_LOG (1, "Mapped segment 0x%lx", segment_handle); - return; + ECHO_LOG (2, "Mapped segment 0x%lx", segment_handle); + em->state = STATE_ATTACHED_NO_CERT; + return; failed: - for (i = 0; i < vec_len (fds); i++) + for (i = clib_max (n_fds - 1, 0); i < vec_len (fds); i++) close (fds[i]); vec_free (fds); } static void -vl_api_bind_uri_reply_t_handler (vl_api_bind_uri_reply_t * mp) -{ - if (mp->retval) - { - ECHO_FAIL ("bind failed: %U", format_api_error, - clib_net_to_host_u32 (mp->retval)); - } -} - -static void -vl_api_unbind_uri_reply_t_handler (vl_api_unbind_uri_reply_t * mp) -{ - echo_session_t *listen_session; - echo_main_t *em = &echo_main; - if (mp->retval != 0) - { - ECHO_FAIL ("returned %d", ntohl (mp->retval)); - return; - } - listen_session = pool_elt_at_index (em->sessions, em->listen_session_index); - em->proto_cb_vft->cleanup_cb (listen_session, 0 /* parent_died */ ); - em->state = STATE_DISCONNECTED; -} - -static void -vl_api_disconnect_session_reply_t_handler (vl_api_disconnect_session_reply_t * +vl_api_application_detach_reply_t_handler (vl_api_application_detach_reply_t * mp) { - echo_main_t *em = &echo_main; - echo_session_t *s; - if (mp->retval) { - ECHO_FAIL ("vpp complained about disconnect: %d", ntohl (mp->retval)); + ECHO_FAIL (ECHO_FAIL_VL_API_DETACH_REPLY, + "app detach returned with err: %d", mp->retval); return; } - - ECHO_LOG (1, "Got disonnected reply for session 0x%lx", mp->handle); - if (!(s = echo_get_session_from_handle (em, mp->handle))) - return; - em->proto_cb_vft->disconnected_reply_cb (s); + echo_main.state = STATE_DETACHED; } -static void - vl_api_application_tls_cert_add_reply_t_handler - (vl_api_application_tls_cert_add_reply_t * mp) -{ - if (mp->retval) - ECHO_FAIL ("failed to add tls cert"); -} +#define foreach_quic_echo_msg \ +_(APP_ATTACH_REPLY, app_attach_reply) \ +_(APPLICATION_DETACH_REPLY, application_detach_reply) \ +_(APP_ADD_CERT_KEY_PAIR_REPLY, app_add_cert_key_pair_reply) \ +_(APP_DEL_CERT_KEY_PAIR_REPLY, app_del_cert_key_pair_reply) -static void - vl_api_application_tls_key_add_reply_t_handler - (vl_api_application_tls_key_add_reply_t * mp) -{ - if (mp->retval) - ECHO_FAIL ("failed to add tls key"); -} +#define vl_print(handle, ...) fformat (handle, __VA_ARGS__) +#define vl_endianfun +#include +#undef vl_endianfun -static void -vl_api_connect_uri_reply_t_handler (vl_api_connect_uri_reply_t * mp) -{ - echo_main_t *em = &echo_main; - if (mp->retval && (em->proto_cb_vft->connected_cb)) - em->proto_cb_vft->connected_cb ((session_connected_bundled_msg_t *) mp, - mp->context, 1 /* is_failed */ ); -} +#define vl_calcsizefun +#include +#undef vl_calcsizefun -#define foreach_quic_echo_msg \ -_(BIND_URI_REPLY, bind_uri_reply) \ -_(UNBIND_URI_REPLY, unbind_uri_reply) \ -_(DISCONNECT_SESSION_REPLY, disconnect_session_reply) \ -_(APPLICATION_ATTACH_REPLY, application_attach_reply) \ -_(APPLICATION_DETACH_REPLY, application_detach_reply) \ -_(MAP_ANOTHER_SEGMENT, map_another_segment) \ -_(UNMAP_SEGMENT, unmap_segment) \ -_(APPLICATION_TLS_CERT_ADD_REPLY, application_tls_cert_add_reply) \ -_(APPLICATION_TLS_KEY_ADD_REPLY, application_tls_key_add_reply) \ -_(CONNECT_URI_REPLY, connect_uri_reply) \ +#define vl_printfun +#include +#undef vl_printfun + +#define vl_api_version(n, v) static u32 api_version = v; +#include +#undef vl_api_version void echo_api_hookup (echo_main_t * em) { -#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); + u8 *name = format (0, "session_%08x%c", api_version, 0); + + REPLY_MSG_ID_BASE = vl_client_get_first_plugin_msg_id ((char *) name); + + vec_free (name); + + if (REPLY_MSG_ID_BASE == (u16) ~0) + return; + +#define _(N, n) \ + vl_msg_api_set_handlers ( \ + REPLY_MSG_ID_BASE + 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, vl_api_##n##_t_print_json, \ + vl_api_##n##_t_tojson, vl_api_##n##_t_fromjson, \ + vl_api_##n##_t_calc_size); foreach_quic_echo_msg; #undef _ }