X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fsession%2Fsession.c;h=ed940d593c5a3ec3765fcf7f1afbdff17fd82df8;hb=4fde4ae0363de45d867eb3472e43b89ae34d3bd1;hp=79f93c406937ee99e5e2c90bf98510a80317259e;hpb=57660d9df62756c5db1516be0dbb48505f996e82;p=vpp.git diff --git a/src/vnet/session/session.c b/src/vnet/session/session.c index 79f93c40693..ed940d593c5 100644 --- a/src/vnet/session/session.c +++ b/src/vnet/session/session.c @@ -18,7 +18,6 @@ */ #include -#include #include #include #include @@ -735,10 +734,9 @@ session_main_flush_all_enqueue_events (u8 transport_proto) return errors; } -static inline int -session_stream_connect_notify_inline (transport_connection_t * tc, - session_error_t err, - session_state_t opened_state) +int +session_stream_connect_notify (transport_connection_t * tc, + session_error_t err) { u32 opaque = 0, new_ti, new_si; app_worker_t *app_wrk; @@ -782,7 +780,7 @@ session_stream_connect_notify_inline (transport_connection_t * tc, } s = session_get (new_si, new_ti); - s->session_state = opened_state; + s->session_state = SESSION_STATE_READY; session_lookup_add_connection (tc, session_handle (s)); if (app_worker_connect_notify (app_wrk, s, SESSION_E_NONE, opaque)) @@ -795,18 +793,29 @@ session_stream_connect_notify_inline (transport_connection_t * tc, return 0; } -int -session_stream_connect_notify (transport_connection_t * tc, - session_error_t err) +static void +session_switch_pool_reply (void *arg) { - return session_stream_connect_notify_inline (tc, err, SESSION_STATE_READY); -} + u32 session_index = pointer_to_uword (arg); + segment_manager_t *sm; + app_worker_t *app_wrk; + session_t *s; -int -session_ho_stream_connect_notify (transport_connection_t * tc, - session_error_t err) -{ - return session_stream_connect_notify_inline (tc, err, SESSION_STATE_OPENED); + s = session_get_if_valid (session_index, vlib_get_thread_index ()); + if (!s) + return; + + app_wrk = app_worker_get_if_valid (s->app_wrk_index); + if (!app_wrk) + return; + + /* Attach fifos to the right session and segment slice */ + sm = app_worker_get_connect_segment_manager (app_wrk); + segment_manager_attach_fifo (sm, s->rx_fifo, s); + segment_manager_attach_fifo (sm, s->tx_fifo, s); + + /* Notify app that it has data on the new session */ + session_enqueue_notify (s); } typedef struct _session_switch_pool_args @@ -824,28 +833,38 @@ static void session_switch_pool (void *cb_args) { session_switch_pool_args_t *args = (session_switch_pool_args_t *) cb_args; + session_handle_t new_sh; + segment_manager_t *sm; app_worker_t *app_wrk; session_t *s; + void *rargs; ASSERT (args->thread_index == vlib_get_thread_index ()); s = session_get (args->session_index, args->thread_index); - s->tx_fifo->master_session_index = args->new_session_index; - s->tx_fifo->master_thread_index = args->new_thread_index; + transport_cleanup (session_get_transport_proto (s), s->connection_index, s->thread_index); + new_sh = session_make_handle (args->new_session_index, + args->new_thread_index); + app_wrk = app_worker_get_if_valid (s->app_wrk_index); if (app_wrk) { - session_handle_t new_sh; - new_sh = session_make_handle (args->new_session_index, - args->new_thread_index); - app_worker_migrate_notify (app_wrk, s, new_sh); + /* Cleanup fifo segment slice state for fifos */ + sm = app_worker_get_connect_segment_manager (app_wrk); + segment_manager_detach_fifo (sm, s->rx_fifo); + segment_manager_detach_fifo (sm, s->tx_fifo); - /* Trigger app read on the new thread */ - session_enqueue_notify_thread (new_sh); + /* Notify app, using old session, about the migration event */ + app_worker_migrate_notify (app_wrk, s, new_sh); } + /* Trigger app read and fifo updates on the new thread */ + rargs = uword_to_pointer (args->new_session_index, void *); + session_send_rpc_evt_to_thread (args->new_thread_index, + session_switch_pool_reply, rargs); + session_free (s); clib_mem_free (cb_args); } @@ -865,10 +884,9 @@ session_dgram_connect_notify (transport_connection_t * tc, */ new_s = session_clone_safe (tc->s_index, old_thread_index); new_s->connection_index = tc->c_index; - new_s->rx_fifo->master_session_index = new_s->session_index; - new_s->rx_fifo->master_thread_index = new_s->thread_index; new_s->session_state = SESSION_STATE_READY; new_s->flags |= SESSION_F_IS_MIGRATING; + session_lookup_add_connection (tc, session_handle (new_s)); /* @@ -1070,7 +1088,10 @@ session_stream_accept (transport_connection_t * tc, u32 listener_index, s->session_state = SESSION_STATE_CREATED; if ((rv = app_worker_init_accepted (s))) - return rv; + { + session_free (s); + return rv; + } session_lookup_add_connection (tc, session_handle (s)); @@ -1078,9 +1099,46 @@ session_stream_accept (transport_connection_t * tc, u32 listener_index, if (notify) { app_worker_t *app_wrk = app_worker_get (s->app_wrk_index); - return app_worker_accept_notify (app_wrk, s); + if ((rv = app_worker_accept_notify (app_wrk, s))) + { + session_lookup_del_session (s); + segment_manager_dealloc_fifos (s->rx_fifo, s->tx_fifo); + session_free (s); + return rv; + } + } + + return 0; +} + +int +session_dgram_accept (transport_connection_t * tc, u32 listener_index, + u32 thread_index) +{ + app_worker_t *app_wrk; + session_t *s; + int rv; + + s = session_alloc_for_connection (tc); + s->listener_handle = ((u64) thread_index << 32) | (u64) listener_index; + + if ((rv = app_worker_init_accepted (s))) + { + session_free (s); + return rv; + } + + app_wrk = app_worker_get (s->app_wrk_index); + if ((rv = app_worker_accept_notify (app_wrk, s))) + { + segment_manager_dealloc_fifos (s->rx_fifo, s->tx_fifo); + session_free (s); + return rv; } + s->session_state = SESSION_STATE_READY; + session_lookup_add_connection (tc, session_handle (s)); + return 0; } @@ -1152,8 +1210,7 @@ session_open_vc (u32 app_wrk_index, session_endpoint_t * rmt, u32 opaque) * thing but better than allocating a separate half-open pool. */ tc->s_index = opaque; - if (transport_half_open_has_fifos (rmt->transport_proto)) - return session_ho_stream_connect_notify (tc, 0 /* is_fail */ ); + return 0; } @@ -1212,7 +1269,8 @@ int session_listen (session_t * ls, session_endpoint_cfg_t * sep) { transport_endpoint_t *tep; - u32 tc_index, s_index; + int tc_index; + u32 s_index; /* Transport bind/listen */ tep = session_endpoint_to_transport (sep); @@ -1220,8 +1278,8 @@ session_listen (session_t * ls, session_endpoint_cfg_t * sep) tc_index = transport_start_listen (session_get_transport_proto (ls), s_index, tep); - if (tc_index == (u32) ~ 0) - return -1; + if (tc_index < 0) + return tc_index; /* Attach transport to session. Lookup tables are populated by the app * worker because local tables (for ct sessions) are not backed by a fib */ @@ -1243,14 +1301,17 @@ session_stop_listen (session_t * s) transport_connection_t *tc; if (s->session_state != SESSION_STATE_LISTENING) - return -1; + return SESSION_E_NOLISTEN; tc = transport_get_listener (tp, s->connection_index); + + /* If no transport, assume everything was cleaned up already */ if (!tc) - return VNET_API_ERROR_ADDRESS_NOT_IN_USE; + return SESSION_E_NONE; if (!(tc->flags & TRANSPORT_CONNECTION_F_NO_LOOKUP)) session_lookup_del_connection (tc); + transport_stop_listen (tp, s->connection_index); return 0; } @@ -1627,6 +1688,8 @@ session_manager_main_enable (vlib_main_t * vm) /* Enable transports */ transport_enable_disable (vm, 1); + session_debug_init (); + return 0; }