X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvcl%2Fvppcom.c;h=e8366d70566452e57a0b7bcf42b2e09010ce8d4d;hb=e535644dd3066eb843c7b0056a7f6346a36e702a;hp=1f9857676e270e16f82da8755399c3b27c96cd8c;hpb=00f44cc1f7f3cc10c0d6b147c0bceb831a9e97fb;p=vpp.git diff --git a/src/vcl/vppcom.c b/src/vcl/vppcom.c index 1f9857676e2..e8366d70566 100644 --- a/src/vcl/vppcom.c +++ b/src/vcl/vppcom.c @@ -203,6 +203,13 @@ typedef struct vce_event_connect_request_ u32 accepted_session_index; } vce_event_connect_request_t; +typedef struct vppcom_session_listener +{ + vppcom_session_listener_cb user_cb; + vppcom_session_listener_errcb user_errcb; + void *user_cb_data; +} vppcom_session_listener_t; + typedef struct vppcom_main_t_ { u8 init; @@ -436,10 +443,69 @@ write_elog (void) } +static inline void +vppcom_send_accept_session_reply (u64 handle, u32 context, int retval) +{ + vl_api_accept_session_reply_t *rmp; + + rmp = vl_msg_api_alloc (sizeof (*rmp)); + memset (rmp, 0, sizeof (*rmp)); + rmp->_vl_msg_id = ntohs (VL_API_ACCEPT_SESSION_REPLY); + rmp->retval = htonl (retval); + rmp->context = context; + rmp->handle = handle; + vl_msg_api_send_shmem (vcm->vl_input_queue, (u8 *) & rmp); +} + /* * VPPCOM Event Functions */ +void +vce_registered_listener_connect_handler_fn (void *arg) +{ + vce_event_handler_reg_t *reg = (vce_event_handler_reg_t *) arg; + vce_event_connect_request_t *ecr; + vce_event_t *ev; + vppcom_endpt_t ep; + + session_t *new_session; + int rv; + + vppcom_session_listener_t *session_listener = + (vppcom_session_listener_t *) reg->handler_fn_args; + + ev = vce_get_event_from_index (&vcm->event_thread, reg->ev_idx); + + ecr = (vce_event_connect_request_t *) ev->data; + VCL_LOCK_AND_GET_SESSION (ecr->accepted_session_index, &new_session); + + + ep.is_ip4 = new_session->peer_addr.is_ip4; + ep.port = new_session->peer_port; + if (new_session->peer_addr.is_ip4) + clib_memcpy (&ep.ip, &new_session->peer_addr.ip46.ip4, + sizeof (ip4_address_t)); + else + clib_memcpy (&ep.ip, &new_session->peer_addr.ip46.ip6, + sizeof (ip6_address_t)); + + vppcom_send_accept_session_reply (new_session->vpp_handle, + new_session->client_context, + 0 /* retval OK */ ); + clib_spinlock_unlock (&vcm->sessions_lockp); + + (session_listener->user_cb) (ecr->accepted_session_index, &ep, + session_listener->user_cb_data); + + /*TODO - Unregister check in close for this listener */ + + return; + +done: + ASSERT (0); // If we can't get a lock or accepted session fails, lets blow up. +} + /** * * @brief vce_connect_request_handler_fn * - used for listener sessions @@ -460,7 +526,7 @@ vce_connect_request_handler_fn (void *arg) } /** - * @brief vce_epoll_wait_connect_request_handler_fn + * @brief vce_poll_wait_connect_request_handler_fn * - used by vppcom_epoll_xxxx() for listener sessions * - when a vl_api_accept_session_t_handler() generates an event * this callback is alerted and sets the fields that vppcom_epoll_wait() @@ -469,7 +535,7 @@ vce_connect_request_handler_fn (void *arg) * @param arg - void* to be cast to vce_event_handler_reg_t* */ void -vce_epoll_wait_connect_request_handler_fn (void *arg) +vce_poll_wait_connect_request_handler_fn (void *arg) { vce_event_handler_reg_t *reg = (vce_event_handler_reg_t *) arg; vce_event_t *ev; @@ -1250,20 +1316,6 @@ format_ip46_address (u8 * s, va_list * args) format (s, "%U", format_ip6_address, &ip46->ip6); } -static inline void -vppcom_send_accept_session_reply (u64 handle, u32 context, int retval) -{ - vl_api_accept_session_reply_t *rmp; - - rmp = vl_msg_api_alloc (sizeof (*rmp)); - memset (rmp, 0, sizeof (*rmp)); - rmp->_vl_msg_id = ntohs (VL_API_ACCEPT_SESSION_REPLY); - rmp->retval = htonl (retval); - rmp->context = context; - rmp->handle = handle; - vl_msg_api_send_shmem (vcm->vl_input_queue, (u8 *) & rmp); -} - static void vl_api_accept_session_t_handler (vl_api_accept_session_t * mp) { @@ -2681,6 +2733,39 @@ done: return rv; } +int +vppcom_session_register_listener (uint32_t session_index, + vppcom_session_listener_cb cb, + vppcom_session_listener_errcb + errcb, uint8_t flags, int q_len, void *ptr) +{ + int rv = VPPCOM_OK; + vce_event_key_t evk; + vppcom_session_listener_t *listener_args; + + rv = vppcom_session_listen (session_index, q_len); + if (rv) + { + goto done; + } + + + /* Register handler for connect_request event on listen_session_index */ + listener_args = clib_mem_alloc (sizeof (vppcom_session_listener_t)); + listener_args->user_cb = cb; + listener_args->user_cb_data = ptr; + listener_args->user_errcb = errcb; + + evk.session_index = session_index; + evk.eid = VCL_EVENT_CONNECT_REQ_ACCEPTED; + (void) vce_register_handler (&vcm->event_thread, &evk, + vce_registered_listener_connect_handler_fn, + listener_args); + +done: + return rv; +} + int validate_args_session_accept_ (session_t * listen_session) { @@ -2752,9 +2837,8 @@ vppcom_session_accept (uint32_t listen_session_index, vppcom_endpt_t * ep, evk.session_index = listen_session_index; evk.eid = VCL_EVENT_CONNECT_REQ_ACCEPTED; reg = vce_register_handler (&vcm->event_thread, &evk, - vce_connect_request_handler_fn); - - ev = 0; + vce_connect_request_handler_fn, 0); + ev = vce_get_event_from_index (&vcm->event_thread, reg->ev_idx); pthread_mutex_lock (®->handler_lock); while (!ev) { @@ -2796,7 +2880,7 @@ vppcom_session_accept (uint32_t listen_session_index, vppcom_endpt_t * ep, "lookup failed! returning %d (%s)", getpid (), listen_vpp_handle, listen_session_index, client_session_index, rv, vppcom_retval_str (rv)); - goto done; + goto cleanup; } if (flags & O_NONBLOCK) @@ -3461,8 +3545,31 @@ vppcom_select (unsigned long n_bits, unsigned long *read_map, bits_set = VPPCOM_EBADFD; goto select_done; } - - rv = vppcom_session_read_ready (session, session_index); + if (session->state & STATE_LISTEN) + { + vce_event_handler_reg_t *reg = 0; + vce_event_key_t evk; + + /* Check if handler already registered for this + * event. + * If not, register handler for connect_request event + * on listen_session_index + */ + evk.session_index = session_index; + evk.eid = VCL_EVENT_CONNECT_REQ_ACCEPTED; + reg = vce_get_event_handler (&vcm->event_thread, &evk); + if (!reg) + reg = vce_register_handler (&vcm->event_thread, &evk, + vce_poll_wait_connect_request_handler_fn, + 0 /* No callback args */); + rv = vppcom_session_read_ready (session, session_index); + if (rv > 0) + { + vce_unregister_handler (&vcm->event_thread, reg); + } + } + else + rv = vppcom_session_read_ready (session, session_index); clib_spinlock_unlock (&vcm->sessions_lockp); if (except_map && vcm->ex_bitmap && clib_bitmap_get (vcm->ex_bitmap, session_index) && @@ -3773,7 +3880,8 @@ vppcom_epoll_ctl (uint32_t vep_idx, int op, uint32_t session_index, evk.eid = VCL_EVENT_CONNECT_REQ_ACCEPTED; vep_session->poll_reg = vce_register_handler (&vcm->event_thread, &evk, - vce_epoll_wait_connect_request_handler_fn); + vce_poll_wait_connect_request_handler_fn, + 0 /* No callback args */ ); } if (VPPCOM_DEBUG > 1) clib_warning ("VCL<%d>: EPOLL_CTL_ADD: vep_idx %u, "