X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvcl%2Fvppcom.c;h=cab2f6039e9f34e62f1144b2de6fba0fce4d9709;hb=de91006803f823a149b04738dd2bbfe18bfe9791;hp=c0b09e833d72ab55efa4570acd7960e21b650c99;hpb=8d73e856ca9c62271495cef9059063d9abd8ae3c;p=vpp.git diff --git a/src/vcl/vppcom.c b/src/vcl/vppcom.c index c0b09e833d7..cab2f6039e9 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 @@ -1141,8 +1207,7 @@ done: session->vpp_handle = mp->handle; session->lcl_addr.is_ip4 = mp->lcl_is_ip4; - clib_memcpy (&session->lcl_addr.ip46, mp->lcl_ip, - sizeof (session->peer_addr.ip46)); + session->lcl_addr.ip46 = to_ip46 (!mp->lcl_is_ip4, mp->lcl_ip); session->lcl_port = mp->lcl_port; vppcom_session_table_add_listener (mp->handle, session_index); session->state = STATE_LISTEN; @@ -1250,20 +1315,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) { @@ -1325,8 +1376,7 @@ vl_api_accept_session_t_handler (vl_api_accept_session_t * mp) session->state = STATE_ACCEPT; session->peer_port = mp->port; session->peer_addr.is_ip4 = mp->is_ip4; - clib_memcpy (&session->peer_addr.ip46, mp->ip, - sizeof (session->peer_addr.ip46)); + session->peer_addr.ip46 = to_ip46 (!mp->is_ip4, mp->ip); /* Add it to lookup table */ hash_set (vcm->session_index_by_vpp_handles, mp->handle, session_index); @@ -1357,7 +1407,8 @@ vl_api_accept_session_t_handler (vl_api_accept_session_t * mp) clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: client accept " "request from %s address %U port %d queue %p!", getpid (), mp->handle, session_index, mp->is_ip4 ? "IPv4" : "IPv6", - format_ip46_address, &mp->ip, mp->is_ip4, + format_ip46_address, &mp->ip, + mp->is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6, clib_net_to_host_u16 (mp->port), session->vpp_event_queue); if (VPPCOM_DEBUG > 0) @@ -2295,6 +2346,7 @@ void vppcom_app_destroy (void) { int rv; + f64 orig_app_timeout; if (vcm->my_client_index == ~0) return; @@ -2322,7 +2374,10 @@ vppcom_app_destroy (void) } vppcom_app_detach (); + orig_app_timeout = vcm->cfg.app_timeout; + vcm->cfg.app_timeout = 2.0; rv = vppcom_wait_for_app_state_change (STATE_APP_ENABLED); + vcm->cfg.app_timeout = orig_app_timeout; if (PREDICT_FALSE (rv)) { if (VPPCOM_DEBUG > 0) @@ -2575,7 +2630,7 @@ vppcom_session_bind (uint32_t session_index, vppcom_endpt_t * ep) "port %u, proto %s", getpid (), session_index, session->lcl_addr.is_ip4 ? "IPv4" : "IPv6", format_ip46_address, &session->lcl_addr.ip46, - session->lcl_addr.is_ip4, + session->lcl_addr.is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6, clib_net_to_host_u16 (session->lcl_port), session->proto ? "UDP" : "TCP"); @@ -2681,6 +2736,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,10 +2840,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); - + 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) { @@ -2797,7 +2883,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) @@ -2837,7 +2923,8 @@ vppcom_session_accept (uint32_t listen_session_index, vppcom_endpt_t * ep, client_session_index, client_session->lcl_addr.is_ip4 ? "IPv4" : "IPv6", format_ip46_address, &client_session->lcl_addr.ip46, - client_session->lcl_addr.is_ip4, + client_session->lcl_addr.is_ip4 ? + IP46_TYPE_IP4 : IP46_TYPE_IP6, clib_net_to_host_u16 (client_session->lcl_port)); if (VPPCOM_DEBUG > 0) @@ -2931,7 +3018,8 @@ vppcom_session_connect (uint32_t session_index, vppcom_endpt_t * server_ep) getpid (), session->vpp_handle, session_index, session->peer_addr.is_ip4 ? "IPv4" : "IPv6", format_ip46_address, - &session->peer_addr.ip46, session->peer_addr.is_ip4, + &session->peer_addr.ip46, session->peer_addr.is_ip4 ? + IP46_TYPE_IP4 : IP46_TYPE_IP6, clib_net_to_host_u16 (session->peer_port), session->proto ? "UDP" : "TCP", session->state, vppcom_session_state_str (session->state)); @@ -2950,7 +3038,8 @@ vppcom_session_connect (uint32_t session_index, vppcom_endpt_t * server_ep) getpid (), session->vpp_handle, session_index, session->peer_addr.is_ip4 ? "IPv4" : "IPv6", format_ip46_address, - &session->peer_addr.ip46, session->peer_addr.is_ip4, + &session->peer_addr.ip46, session->peer_addr.is_ip4 ? + IP46_TYPE_IP4 : IP46_TYPE_IP6, clib_net_to_host_u16 (session->peer_port), session->proto ? "UDP" : "TCP"); @@ -3477,7 +3566,8 @@ vppcom_select (unsigned long n_bits, unsigned long *read_map, 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); + vce_poll_wait_connect_request_handler_fn, + 0 /* No callback args */); rv = vppcom_session_read_ready (session, session_index); if (rv > 0) { @@ -3796,7 +3886,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_poll_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, " @@ -4374,7 +4465,8 @@ vppcom_session_attr (uint32_t session_index, uint32_t op, clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_PEER_ADDR: sid %u, " "is_ip4 = %u, addr = %U, port %u", getpid (), session_index, ep->is_ip4, format_ip46_address, - &session->peer_addr.ip46, ep->is_ip4, + &session->peer_addr.ip46, + ep->is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6, clib_net_to_host_u16 (ep->port)); if (VPPCOM_DEBUG > 0) { @@ -4440,7 +4532,8 @@ vppcom_session_attr (uint32_t session_index, uint32_t op, clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_LCL_ADDR: sid %u, " "is_ip4 = %u, addr = %U port %d", getpid (), session_index, ep->is_ip4, format_ip46_address, - &session->lcl_addr.ip46, ep->is_ip4, + &session->lcl_addr.ip46, + ep->is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6, clib_net_to_host_u16 (ep->port)); if (VPPCOM_DEBUG > 0) {