mp->is_ip4 = s->transport.is_ip4;
mp->parent_handle = s->parent_handle;
clib_memcpy_fast (&mp->ip, &s->transport.rmt_ip, sizeof (mp->ip));
+ clib_memcpy_fast (&mp->lcl_ip, &s->transport.lcl_ip, sizeof (mp->lcl_ip));
mp->port = s->transport.rmt_port;
mp->proto = s->session_type;
app_send_ctrl_evt_to_vpp (mq, app_evt);
{
VDBG (0, "ERROR: session index %u: connect failed! %U",
session_index, format_api_error, ntohl (mp->retval));
- session->session_state = STATE_FAILED;
+ session->session_state = STATE_FAILED | STATE_DISCONNECT;
session->vpp_handle = mp->handle;
return session_index;
}
+ session->vpp_handle = mp->handle;
+ session->vpp_evt_q = uword_to_pointer (mp->vpp_event_queue_address,
+ svm_msg_q_t *);
rx_fifo = uword_to_pointer (mp->server_rx_fifo, svm_fifo_t *);
tx_fifo = uword_to_pointer (mp->server_tx_fifo, svm_fifo_t *);
if (vcl_wait_for_segment (mp->segment_handle))
{
VDBG (0, "segment for session %u couldn't be mounted!",
session->session_index);
- session->session_state = STATE_FAILED;
- return VCL_INVALID_SESSION_INDEX;
+ session->session_state = STATE_FAILED | STATE_DISCONNECT;
+ vcl_send_session_disconnect (wrk, session);
+ return session_index;
}
rx_fifo->client_session_index = session_index;
rx_fifo->client_thread_index = vcl_get_worker_index ();
tx_fifo->client_thread_index = vcl_get_worker_index ();
- session->vpp_evt_q = uword_to_pointer (mp->vpp_event_queue_address,
- svm_msg_q_t *);
vpp_wrk_index = tx_fifo->master_thread_index;
vec_validate (wrk->vpp_event_queues, vpp_wrk_index);
wrk->vpp_event_queues[vpp_wrk_index] = session->vpp_evt_q;
{
VDBG (0, "ct segment for session %u couldn't be mounted!",
session->session_index);
- session->session_state = STATE_FAILED;
- return VCL_INVALID_SESSION_INDEX;
+ session->session_state = STATE_FAILED | STATE_DISCONNECT;
+ vcl_send_session_disconnect (wrk, session);
+ return session_index;
}
}
session->rx_fifo = rx_fifo;
session->tx_fifo = tx_fifo;
- session->vpp_handle = mp->handle;
session->vpp_thread_index = rx_fifo->master_thread_index;
session->transport.is_ip4 = mp->lcl.is_ip4;
clib_memcpy_fast (&session->transport.lcl_ip, &mp->lcl.ip,
vcl_worker_cleanup (vcl_worker_get_current (), 1 /* notify vpp */ );
vcl_set_worker_index (~0);
vcl_elog_stop (vcm);
- if (vec_len (vcm->workers) == 1)
- vppcom_disconnect_from_vpp ();
- else
- vl_client_send_disconnect (1 /* vpp should cleanup */ );
}
/*
vcl_worker_alloc_and_init ();
/* API hookup and connect to VPP */
- vppcom_api_hookup ();
vcl_elog_init (vcm);
vcm->app_state = STATE_APP_START;
rv = vppcom_connect_to_vpp (app_name);
is_nonblocking = VCL_SESS_ATTR_TEST (listen_session->attr,
VCL_SESS_ATTR_NONBLOCK);
- if (svm_msg_q_is_empty (wrk->app_event_queue) && is_nonblocking)
- return VPPCOM_EAGAIN;
-
while (1)
{
+ if (svm_msg_q_is_empty (wrk->app_event_queue) && is_nonblocking)
+ return VPPCOM_EAGAIN;
+
if (svm_msg_q_sub (wrk->app_event_queue, &msg, SVM_Q_WAIT, 0))
return VPPCOM_EAGAIN;
e = svm_msg_q_msg_data (wrk->app_event_queue, &msg);
if (e->event_type != SESSION_CTRL_EVT_ACCEPTED)
{
- VDBG (0, "discarded event: %u", e->event_type);
+ vcl_handle_mq_event (wrk, e);
svm_msg_q_free_msg (wrk->app_event_queue, &msg);
continue;
}
return vcl_session_handle (client_session);
}
+static void
+vcl_ip_copy_from_ep (ip46_address_t * ip, vppcom_endpt_t * ep)
+{
+ if (ep->is_ip4)
+ clib_memcpy_fast (&ip->ip4, ep->ip, sizeof (ip4_address_t));
+ else
+ clib_memcpy_fast (&ip->ip6, ep->ip, sizeof (ip6_address_t));
+}
+
+void
+vcl_ip_copy_to_ep (ip46_address_t * ip, vppcom_endpt_t * ep, u8 is_ip4)
+{
+ ep->is_ip4 = is_ip4;
+ if (is_ip4)
+ clib_memcpy_fast (ep->ip, &ip->ip4, sizeof (ip4_address_t));
+ else
+ clib_memcpy_fast (ep->ip, &ip->ip6, sizeof (ip6_address_t));
+}
+
int
vppcom_session_connect (uint32_t session_handle, vppcom_endpt_t * server_ep)
{
}
session->transport.is_ip4 = server_ep->is_ip4;
- if (session->transport.is_ip4)
- clib_memcpy_fast (&session->transport.rmt_ip.ip4, server_ep->ip,
- sizeof (ip4_address_t));
- else
- clib_memcpy_fast (&session->transport.rmt_ip.ip6, server_ep->ip,
- sizeof (ip6_address_t));
+ vcl_ip_copy_from_ep (&session->transport.rmt_ip, server_ep);
session->transport.rmt_port = server_ep->port;
session->parent_handle = VCL_INVALID_SESSION_HANDLE;
{
if (is_nonblocking)
{
+ if (vcl_session_is_closing (s))
+ return vcl_session_closing_error (s);
svm_fifo_unset_event (s->rx_fifo);
return VPPCOM_EWOULDBLOCK;
}
svm_msg_q_t *mq;
u8 is_ct;
- if (PREDICT_FALSE (!buf))
+ if (PREDICT_FALSE (!buf || n == 0))
return VPPCOM_EINVAL;
s = vcl_session_get_w_handle (wrk, session_handle);
}
#define vcl_fifo_rx_evt_valid_or_break(_s) \
+if (PREDICT_FALSE (!_s->rx_fifo)) \
+ break; \
if (PREDICT_FALSE (svm_fifo_is_empty (_s->rx_fifo))) \
{ \
if (!vcl_session_is_ct (_s)) \
break;
case SESSION_CTRL_EVT_CONNECTED:
connected_msg = (session_connected_msg_t *) e->data;
- vcl_session_connected_handler (wrk, connected_msg);
+ sid = vcl_session_connected_handler (wrk, connected_msg);
/* Generate EPOLLOUT because there's no connected event */
- sid = vcl_session_index_from_vpp_handle (wrk, connected_msg->handle);
if (!(session = vcl_session_get (wrk, sid)))
break;
session_events = session->vep.ev.events;
add_event = 1;
events[*num_ev].events |= EPOLLOUT;
session_evt_data = session->vep.ev.data.u64;
+ if (session->session_state & STATE_FAILED)
+ events[*num_ev].events |= EPOLLHUP;
break;
case SESSION_CTRL_EVT_DISCONNECTED:
disconnected_msg = (session_disconnected_msg_t *) e->data;
rv = VPPCOM_EINVAL;
break;
+ case VPPCOM_ATTR_SET_LCL_ADDR:
+ if (PREDICT_TRUE (buffer && buflen &&
+ (*buflen >= sizeof (*ep)) && ep->ip))
+ {
+ session->transport.is_ip4 = ep->is_ip4;
+ session->transport.lcl_port = ep->port;
+ vcl_ip_copy_from_ep (&session->transport.lcl_ip, ep);
+ *buflen = sizeof (*ep);
+ VDBG (1, "VPPCOM_ATTR_SET_LCL_ADDR: sh %u, is_ip4 = %u, addr = %U"
+ " port %d", session_handle, ep->is_ip4, format_ip46_address,
+ &session->transport.lcl_ip,
+ ep->is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6,
+ clib_net_to_host_u16 (ep->port));
+ }
+ else
+ rv = VPPCOM_EINVAL;
+ break;
+
case VPPCOM_ATTR_GET_LIBC_EPFD:
rv = session->libc_epfd;
VDBG (2, "VPPCOM_ATTR_GET_LIBC_EPFD: libc_epfd %d", rv);
int
vppcom_worker_register (void)
{
+ vcl_worker_t *wrk;
+ u8 *wrk_name = 0;
+ int rv;
+
if (!vcl_worker_alloc_and_init ())
return VPPCOM_EEXIST;
- if (vcl_worker_set_bapi ())
- return VPPCOM_EEXIST;
+ wrk = vcl_worker_get_current ();
+ wrk_name = format (0, "%s-wrk-%u", vcm->app_name, wrk->wrk_index);
+
+ rv = vppcom_connect_to_vpp ((char *) wrk_name);
+ vec_free (wrk_name);
+
+ if (rv)
+ return VPPCOM_EFAULT;
if (vcl_worker_register_with_vpp ())
return VPPCOM_EEXIST;