X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fsession%2Fapplication.c;h=c66548507e51b965a0cc7b21a21d490e5f9a0d5a;hb=HEAD;hp=7f88c7a5ff0eb5c4b4eea93c5e0b61b7605d83dc;hpb=8c2bdf86199729e2a7c0564f989690e3e076a19c;p=vpp.git diff --git a/src/vnet/session/application.c b/src/vnet/session/application.c index 7f88c7a5ff0..c66548507e5 100644 --- a/src/vnet/session/application.c +++ b/src/vnet/session/application.c @@ -31,10 +31,12 @@ static app_main_t app_main; static app_listener_t * app_listener_alloc (application_t * app) { + app_main_t *am = &app_main; app_listener_t *app_listener; - pool_get (app->listeners, app_listener); + + pool_get (am->listeners, app_listener); clib_memset (app_listener, 0, sizeof (*app_listener)); - app_listener->al_index = app_listener - app->listeners; + app_listener->al_index = app_listener - am->listeners; app_listener->app_index = app->app_index; app_listener->session_index = SESSION_INVALID_INDEX; app_listener->local_index = SESSION_INVALID_INDEX; @@ -43,18 +45,23 @@ app_listener_alloc (application_t * app) } app_listener_t * -app_listener_get (application_t * app, u32 app_listener_index) +app_listener_get (u32 app_listener_index) { - return pool_elt_at_index (app->listeners, app_listener_index); + app_main_t *am = &app_main; + + return pool_elt_at_index (am->listeners, app_listener_index); } static void app_listener_free (application_t * app, app_listener_t * app_listener) { + app_main_t *am = &app_main; + clib_bitmap_free (app_listener->workers); + vec_free (app_listener->cl_listeners); if (CLIB_DEBUG) clib_memset (app_listener, 0xfa, sizeof (*app_listener)); - pool_put (app->listeners, app_listener); + pool_put (am->listeners, app_listener); } session_handle_t @@ -63,24 +70,14 @@ app_listener_handle (app_listener_t * al) return al->ls_handle; } -app_listener_t * -app_listener_get_w_session (session_t * ls) -{ - application_t *app; - - app = application_get_if_valid (ls->app_index); - if (!app) - return 0; - return app_listener_get (app, ls->al_index); -} - session_handle_t app_listen_session_handle (session_t * ls) { app_listener_t *al; - al = app_listener_get_w_session (ls); - if (!al) + /* TODO(fcoras): quic session handles */ + if (ls->al_index == SESSION_INVALID_INDEX) return listen_session_get_handle (ls); + al = app_listener_get (ls->al_index); return al->ls_handle; } @@ -91,7 +88,7 @@ app_listener_get_w_handle (session_handle_t handle) ls = session_get_from_handle_if_valid (handle); if (!ls) return 0; - return app_listener_get_w_session (ls); + return app_listener_get (ls->al_index); } app_listener_t * @@ -112,7 +109,7 @@ app_listener_lookup (application_t * app, session_endpoint_cfg_t * sep_ext) if (handle != SESSION_INVALID_HANDLE) { ls = listen_session_get_from_handle (handle); - return app_listener_get_w_session (ls); + return app_listener_get (ls->al_index); } } @@ -122,7 +119,7 @@ app_listener_lookup (application_t * app, session_endpoint_cfg_t * sep_ext) if (handle != SESSION_INVALID_HANDLE) { ls = listen_session_get_from_handle (handle); - return app_listener_get_w_session ((session_t *) ls); + return app_listener_get (ls->al_index); } /* @@ -144,7 +141,7 @@ app_listener_lookup (application_t * app, session_endpoint_cfg_t * sep_ext) if (handle != SESSION_INVALID_HANDLE) { ls = listen_session_get_from_handle (handle); - return app_listener_get_w_session ((session_t *) ls); + return app_listener_get (ls->al_index); } } } @@ -181,7 +178,6 @@ app_listener_alloc_and_init (application_t * app, local_st = session_type_from_proto_and_ip (TRANSPORT_PROTO_NONE, sep->is_ip4); ls = listen_session_alloc (0, local_st); - ls->app_index = app->app_index; ls->app_wrk_index = sep->app_wrk_index; lh = session_handle (ls); @@ -189,11 +185,12 @@ app_listener_alloc_and_init (application_t * app, { ls = session_get_from_handle (lh); session_free (ls); + app_listener_free (app, app_listener); return rv; } ls = session_get_from_handle (lh); - app_listener = app_listener_get (app, al_index); + app_listener = app_listener_get (al_index); app_listener->local_index = ls->session_index; app_listener->ls_handle = lh; ls->al_index = al_index; @@ -212,7 +209,6 @@ app_listener_alloc_and_init (application_t * app, * build it's own specific listening connection. */ ls = listen_session_alloc (0, st); - ls->app_index = app->app_index; ls->app_wrk_index = sep->app_wrk_index; /* Listen pool can be reallocated if the transport is @@ -223,10 +219,11 @@ app_listener_alloc_and_init (application_t * app, { ls = listen_session_get_from_handle (lh); session_free (ls); + app_listener_free (app, app_listener); return rv; } ls = listen_session_get_from_handle (lh); - app_listener = app_listener_get (app, al_index); + app_listener = app_listener_get (al_index); app_listener->session_index = ls->session_index; app_listener->ls_handle = lh; ls->al_index = al_index; @@ -288,8 +285,9 @@ app_listener_cleanup (app_listener_t * al) } static app_worker_t * -app_listener_select_worker (application_t * app, app_listener_t * al) +app_listener_select_worker (app_listener_t *al) { + application_t *app; u32 wrk_index; app = application_get (al->app_index); @@ -319,6 +317,13 @@ app_listener_get_local_session (app_listener_t * al) return listen_session_get (al->local_index); } +session_t * +app_listener_get_wrk_cl_session (app_listener_t *al, u32 wrk_map_index) +{ + u32 si = vec_elt (al->cl_listeners, wrk_map_index); + return session_get (si, 0 /* listener thread */); +} + static app_worker_map_t * app_worker_map_alloc (application_t * app) { @@ -723,6 +728,12 @@ application_get_if_valid (u32 app_index) return pool_elt_at_index (app_main.app_pool, app_index); } +static int +_null_app_tx_callback (session_t *s) +{ + return 0; +} + static void application_verify_cb_fns (session_cb_vft_t * cb_fns) { @@ -734,6 +745,8 @@ application_verify_cb_fns (session_cb_vft_t * cb_fns) clib_warning ("No session disconnect callback function provided"); if (cb_fns->session_reset_callback == 0) clib_warning ("No session reset callback function provided"); + if (!cb_fns->builtin_app_tx_callback) + cb_fns->builtin_app_tx_callback = _null_app_tx_callback; } /** @@ -763,8 +776,8 @@ application_verify_cfg (ssvm_segment_type_t st) return 1; } -static int -application_alloc_and_init (app_init_args_t * a) +static session_error_t +application_alloc_and_init (app_init_args_t *a) { ssvm_segment_type_t seg_type = SSVM_SEGMENT_MEMFD; segment_manager_props_t *props; @@ -785,15 +798,15 @@ application_alloc_and_init (app_init_args_t * a) { clib_warning ("mq eventfds can only be used if socket transport is " "used for binary api"); - return VNET_API_ERROR_APP_UNSUPPORTED_CFG; + return SESSION_E_NOSUPPORT; } if (!application_verify_cfg (seg_type)) - return VNET_API_ERROR_APP_UNSUPPORTED_CFG; + return SESSION_E_NOSUPPORT; if (opts[APP_OPTIONS_PREALLOC_FIFO_PAIRS] && opts[APP_OPTIONS_PREALLOC_FIFO_HDRS]) - return VNET_API_ERROR_APP_UNSUPPORTED_CFG; + return SESSION_E_NOSUPPORT; /* Check that the obvious things are properly set up */ application_verify_cb_fns (a->session_cb_vft); @@ -819,6 +832,8 @@ application_alloc_and_init (app_init_args_t * a) props->add_segment_size = opts[APP_OPTIONS_ADD_SEGMENT_SIZE]; props->add_segment = 1; } + if (opts[APP_OPTIONS_FLAGS] & APP_OPTIONS_FLAGS_USE_HUGE_PAGE) + props->huge_page = 1; if (opts[APP_OPTIONS_RX_FIFO_SIZE]) props->rx_fifo_size = opts[APP_OPTIONS_RX_FIFO_SIZE]; if (opts[APP_OPTIONS_TX_FIFO_SIZE]) @@ -872,12 +887,10 @@ application_free (application_t * app) * Free workers */ - /* *INDENT-OFF* */ pool_flush (wrk_map, app->worker_maps, ({ app_wrk = app_worker_get (wrk_map->wrk_index); app_worker_free (app_wrk); })); - /* *INDENT-ON* */ pool_free (app->worker_maps); /* @@ -920,13 +933,11 @@ application_detach_process (application_t * app, u32 api_client_index) APP_DBG ("Detaching for app %v index %u api client index %u", app->name, app->app_index, api_client_index); - /* *INDENT-OFF* */ pool_foreach (wrk_map, app->worker_maps) { app_wrk = app_worker_get (wrk_map->wrk_index); if (app_wrk->api_client_index == api_client_index) vec_add1 (wrks, app_wrk->wrk_index); } - /* *INDENT-ON* */ if (!vec_len (wrks)) { @@ -997,12 +1008,55 @@ application_n_workers (application_t * app) app_worker_t * application_listener_select_worker (session_t * ls) { - application_t *app; app_listener_t *al; - app = application_get (ls->app_index); - al = app_listener_get (app, ls->al_index); - return app_listener_select_worker (app, al); + al = app_listener_get (ls->al_index); + return app_listener_select_worker (al); +} + +always_inline u32 +app_listener_cl_flow_hash (session_dgram_hdr_t *hdr) +{ + u32 hash = 0; + + if (hdr->is_ip4) + { + hash = clib_crc32c_u32 (hash, hdr->rmt_ip.ip4.as_u32); + hash = clib_crc32c_u32 (hash, hdr->lcl_ip.ip4.as_u32); + hash = clib_crc32c_u16 (hash, hdr->rmt_port); + hash = clib_crc32c_u16 (hash, hdr->lcl_port); + } + else + { + hash = clib_crc32c_u64 (hash, hdr->rmt_ip.ip6.as_u64[0]); + hash = clib_crc32c_u64 (hash, hdr->rmt_ip.ip6.as_u64[1]); + hash = clib_crc32c_u64 (hash, hdr->lcl_ip.ip6.as_u64[0]); + hash = clib_crc32c_u64 (hash, hdr->lcl_ip.ip6.as_u64[1]); + hash = clib_crc32c_u16 (hash, hdr->rmt_port); + hash = clib_crc32c_u16 (hash, hdr->lcl_port); + } + + return hash; +} + +session_t * +app_listener_select_wrk_cl_session (session_t *ls, session_dgram_hdr_t *hdr) +{ + u32 wrk_map_index = 0; + app_listener_t *al; + + al = app_listener_get (ls->al_index); + /* Crude test to check if only worker 0 is set */ + if (al->workers[0] != 1) + { + u32 hash = app_listener_cl_flow_hash (hdr); + hash %= vec_len (al->workers) * sizeof (uword); + wrk_map_index = clib_bitmap_next_set (al->workers, hash); + if (wrk_map_index == ~0) + wrk_map_index = clib_bitmap_first_set (al->workers); + } + + return app_listener_get_wrk_cl_session (al, wrk_map_index); } int @@ -1044,8 +1098,8 @@ application_alloc_worker_and_init (application_t * app, app_worker_t ** wrk) return 0; } -int -vnet_app_worker_add_del (vnet_app_worker_add_del_args_t * a) +session_error_t +vnet_app_worker_add_del (vnet_app_worker_add_del_args_t *a) { fifo_segment_t *fs; app_worker_map_t *wrk_map; @@ -1056,7 +1110,7 @@ vnet_app_worker_add_del (vnet_app_worker_add_del_args_t * a) app = application_get (a->app_index); if (!app) - return VNET_API_ERROR_INVALID_VALUE; + return SESSION_E_INVALID; if (a->is_add) { @@ -1079,11 +1133,11 @@ vnet_app_worker_add_del (vnet_app_worker_add_del_args_t * a) { wrk_map = app_worker_map_get (app, a->wrk_map_index); if (!wrk_map) - return VNET_API_ERROR_INVALID_VALUE; + return SESSION_E_INVALID; app_wrk = app_worker_get (wrk_map->wrk_index); if (!app_wrk) - return VNET_API_ERROR_INVALID_VALUE; + return SESSION_E_INVALID; application_api_table_del (app_wrk->api_client_index); if (appns_sapi_enabled ()) @@ -1096,8 +1150,8 @@ vnet_app_worker_add_del (vnet_app_worker_add_del_args_t * a) return 0; } -static int -app_validate_namespace (u8 * namespace_id, u64 secret, u32 * app_ns_index) +static session_error_t +app_validate_namespace (u8 *namespace_id, u64 secret, u32 *app_ns_index) { app_namespace_t *app_ns; if (vec_len (namespace_id) == 0) @@ -1109,12 +1163,12 @@ app_validate_namespace (u8 * namespace_id, u64 secret, u32 * app_ns_index) *app_ns_index = app_namespace_index_from_id (namespace_id); if (*app_ns_index == APP_NAMESPACE_INVALID_INDEX) - return VNET_API_ERROR_APP_INVALID_NS; + return SESSION_E_INVALID_NS; app_ns = app_namespace_get (*app_ns_index); if (!app_ns) - return VNET_API_ERROR_APP_INVALID_NS; + return SESSION_E_INVALID_NS; if (app_ns->ns_secret != secret) - return VNET_API_ERROR_APP_WRONG_NS_SECRET; + return SESSION_E_WRONG_NS_SECRET; return 0; } @@ -1138,8 +1192,8 @@ app_name_from_api_index (u32 api_client_index) * to external app and a segment manager for shared memory fifo based * communication with the external app. */ -int -vnet_application_attach (vnet_app_attach_args_t * a) +session_error_t +vnet_application_attach (vnet_app_attach_args_t *a) { fifo_segment_t *fs; application_t *app = 0; @@ -1148,17 +1202,17 @@ vnet_application_attach (vnet_app_attach_args_t * a) u32 app_ns_index = 0; u8 *app_name = 0; u64 secret; - int rv; + session_error_t rv; if (a->api_client_index != APP_INVALID_INDEX) app = application_lookup (a->api_client_index); else if (a->name) app = application_lookup_name (a->name); else - return VNET_API_ERROR_INVALID_VALUE; + return SESSION_E_INVALID; if (app) - return VNET_API_ERROR_APP_ALREADY_ATTACHED; + return SESSION_E_APP_ATTACHED; /* Socket api sets the name and validates namespace prior to attach */ if (!a->use_sock_api) @@ -1212,8 +1266,8 @@ vnet_application_attach (vnet_app_attach_args_t * a) /** * Detach application from vpp */ -int -vnet_application_detach (vnet_app_detach_args_t * a) +session_error_t +vnet_application_detach (vnet_app_detach_args_t *a) { application_t *app; @@ -1221,7 +1275,7 @@ vnet_application_detach (vnet_app_detach_args_t * a) if (!app) { clib_warning ("app not attached"); - return VNET_API_ERROR_APPLICATION_NOT_ATTACHED; + return SESSION_E_NOAPP; } app_interface_check_thread_and_barrier (vnet_application_detach, a); @@ -1295,8 +1349,8 @@ session_endpoint_update_for_app (session_endpoint_cfg_t * sep, } } -int -vnet_listen (vnet_listen_args_t * a) +session_error_t +vnet_listen (vnet_listen_args_t *a) { app_listener_t *app_listener; app_worker_t *app_wrk; @@ -1349,13 +1403,13 @@ vnet_listen (vnet_listen_args_t * a) return 0; } -int -vnet_connect (vnet_connect_args_t * a) +session_error_t +vnet_connect (vnet_connect_args_t *a) { app_worker_t *client_wrk; application_t *client; - ASSERT (vlib_thread_is_main_w_barrier ()); + ASSERT (session_vlib_thread_is_cl_thread ()); if (session_endpoint_is_zero (&a->sep)) return SESSION_E_INVALID_RMT_IP; @@ -1373,7 +1427,7 @@ vnet_connect (vnet_connect_args_t * a) */ if (application_has_local_scope (client)) { - int rv; + session_error_t rv; a->sep_ext.original_tp = a->sep_ext.transport_proto; a->sep_ext.transport_proto = TRANSPORT_PROTO_NONE; @@ -1388,8 +1442,8 @@ vnet_connect (vnet_connect_args_t * a) return app_worker_connect_session (client_wrk, &a->sep_ext, &a->sh); } -int -vnet_unlisten (vnet_unlisten_args_t * a) +session_error_t +vnet_unlisten (vnet_unlisten_args_t *a) { app_worker_t *app_wrk; app_listener_t *al; @@ -1419,7 +1473,7 @@ vnet_unlisten (vnet_unlisten_args_t * a) return app_worker_stop_listen (app_wrk, al); } -int +session_error_t vnet_shutdown_session (vnet_shutdown_args_t *a) { app_worker_t *app_wrk; @@ -1440,8 +1494,8 @@ vnet_shutdown_session (vnet_shutdown_args_t *a) return 0; } -int -vnet_disconnect_session (vnet_disconnect_args_t * a) +session_error_t +vnet_disconnect_session (vnet_disconnect_args_t *a) { app_worker_t *app_wrk; session_t *s; @@ -1481,7 +1535,7 @@ application_change_listener_owner (session_t * s, app_worker_t * app_wrk) if (!app) return SESSION_E_NOAPP; - app_listener = app_listener_get (app, s->al_index); + app_listener = app_listener_get (s->al_index); /* Only remove from lb for now */ app_listener->workers = clib_bitmap_set (app_listener->workers, @@ -1525,6 +1579,12 @@ application_has_global_scope (application_t * app) return app->flags & APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE; } +int +application_original_dst_is_enabled (application_t *app) +{ + return app->flags & APP_OPTIONS_FLAGS_GET_ORIGINAL_DST; +} + static clib_error_t * application_start_stop_proxy_fib_proto (application_t * app, u8 fib_proto, u8 transport_proto, u8 is_start) @@ -1681,12 +1741,11 @@ application_format_listeners (application_t * app, int verbose) if (!app) { - vlib_cli_output (vm, "%U", format_app_worker_listener, 0 /* header */ , + vlib_cli_output (vm, "%U", format_app_worker_listener, NULL /* header */, 0, 0, verbose); return; } - /* *INDENT-OFF* */ pool_foreach (wrk_map, app->worker_maps) { app_wrk = app_worker_get (wrk_map->wrk_index); if (hash_elts (app_wrk->listeners_table) == 0) @@ -1696,7 +1755,6 @@ application_format_listeners (application_t * app, int verbose) handle, sm_index, verbose); })); } - /* *INDENT-ON* */ } static void @@ -1711,12 +1769,10 @@ application_format_connects (application_t * app, int verbose) return; } - /* *INDENT-OFF* */ pool_foreach (wrk_map, app->worker_maps) { app_wrk = app_worker_get (wrk_map->wrk_index); app_worker_format_connects (app_wrk, verbose); } - /* *INDENT-ON* */ } u8 * @@ -1817,12 +1873,10 @@ format_application (u8 * s, va_list * args) format_memory_size, props->rx_fifo_size, format_memory_size, props->tx_fifo_size); - /* *INDENT-OFF* */ pool_foreach (wrk_map, app->worker_maps) { app_wrk = app_worker_get (wrk_map->wrk_index); s = format (s, "%U", format_app_worker, app_wrk); } - /* *INDENT-ON* */ return s; } @@ -1840,11 +1894,9 @@ application_format_all_listeners (vlib_main_t * vm, int verbose) application_format_listeners (0, verbose); - /* *INDENT-OFF* */ pool_foreach (app, app_main.app_pool) { application_format_listeners (app, verbose); } - /* *INDENT-ON* */ } void @@ -1860,11 +1912,9 @@ application_format_all_clients (vlib_main_t * vm, int verbose) application_format_connects (0, verbose); - /* *INDENT-OFF* */ pool_foreach (app, app_main.app_pool) { application_format_connects (app, verbose); } - /* *INDENT-ON* */ } static clib_error_t * @@ -1874,11 +1924,9 @@ show_certificate_command_fn (vlib_main_t * vm, unformat_input_t * input, app_cert_key_pair_t *ckpair; session_cli_return_if_not_enabled (); - /* *INDENT-OFF* */ pool_foreach (ckpair, app_main.cert_key_pair_store) { vlib_cli_output (vm, "%U", format_cert_key_pair, ckpair); } - /* *INDENT-ON* */ return 0; } @@ -1889,14 +1937,12 @@ appliction_format_app_mq (vlib_main_t * vm, application_t * app) app_worker_t *wrk; int i; - /* *INDENT-OFF* */ pool_foreach (map, app->worker_maps) { wrk = app_worker_get (map->wrk_index); vlib_cli_output (vm, "[A%d][%d]%U", app->app_index, map->wrk_index, format_svm_msg_q, wrk->event_queue); } - /* *INDENT-ON* */ for (i = 0; i < vec_len (app->rx_mqs); i++) vlib_cli_output (vm, "[A%d][R%d]%U", app->app_index, i, format_svm_msg_q, @@ -1917,11 +1963,9 @@ appliction_format_all_app_mq (vlib_main_t * vm) session_main_get_vpp_event_queue (i)); } - /* *INDENT-OFF* */ pool_foreach (app, app_main.app_pool) { appliction_format_app_mq (vm, app); } - /* *INDENT-ON* */ return 0; } @@ -2072,7 +2116,7 @@ vnet_app_del_cert_key_pair (u32 index) u32 *app_index; if (!(ckpair = app_cert_key_pair_get_if_valid (index))) - return (VNET_API_ERROR_INVALID_VALUE); + return SESSION_E_INVALID; vec_foreach (app_index, ckpair->app_interests) {