X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fsession%2Fapplication.c;h=d718b03e6a5cb5f8e2c8ae39094dfa2a28e891ab;hb=26cd0242c95025e0d644db3a80dfe8dee83b6d7a;hp=a93e4b9dbbf421c4d24538e6b45372dbada607e5;hpb=7da8829d8152ef5105a57231fd1d91700e9b4f6c;p=vpp.git diff --git a/src/vnet/session/application.c b/src/vnet/session/application.c index a93e4b9dbbf..d718b03e6a5 100644 --- a/src/vnet/session/application.c +++ b/src/vnet/session/application.c @@ -101,6 +101,8 @@ app_listener_lookup (application_t * app, session_endpoint_cfg_t * sep_ext) session_endpoint_t *sep; session_handle_t handle; session_t *ls; + void *iface_ip; + ip46_address_t original_ip; sep = (session_endpoint_t *) sep_ext; if (application_has_local_scope (app) && session_endpoint_is_local (sep)) @@ -123,6 +125,30 @@ app_listener_lookup (application_t * app, session_endpoint_cfg_t * sep_ext) return app_listener_get_w_session ((session_t *) ls); } + /* + * When binds to "inaddr_any", we add zero address in the local lookup table + * and interface address in the global lookup table. If local scope disable, + * the latter is the only clue to find the listener. + */ + if (!application_has_local_scope (app) && + ip_is_zero (&sep_ext->ip, sep_ext->is_ip4) && + sep_ext->sw_if_index != ENDPOINT_INVALID_INDEX) + { + if ((iface_ip = ip_interface_get_first_ip (sep_ext->sw_if_index, + sep_ext->is_ip4))) + { + ip_copy (&original_ip, &sep_ext->ip, sep_ext->is_ip4); + ip_set (&sep_ext->ip, iface_ip, sep_ext->is_ip4); + handle = session_lookup_endpoint_listener (table_index, sep, 1); + ip_copy (&sep_ext->ip, &original_ip, sep_ext->is_ip4); + if (handle != SESSION_INVALID_HANDLE) + { + ls = listen_session_get_from_handle (handle); + return app_listener_get_w_session ((session_t *) ls); + } + } + } + return 0; } @@ -215,9 +241,9 @@ app_listener_alloc_and_init (application_t * app, { fib_protocol_t fib_proto; fib_proto = session_endpoint_fib_proto ((session_endpoint_t *) sep); - table_index = session_lookup_get_index_for_fib (fib_proto, - sep->fib_index); - ASSERT (table_index != SESSION_TABLE_INVALID_INDEX); + /* Assume namespace vetted previously so make sure table exists */ + table_index = session_lookup_get_or_alloc_index_for_fib ( + fib_proto, sep->fib_index); session_lookup_add_session_endpoint (table_index, (session_endpoint_t *) sep, lh); @@ -615,8 +641,8 @@ app_rx_mqs_alloc (application_t *app) cfg->q_nitems = evt_q_length; cfg->ring_cfgs = rc; - eqs->ssvm.ssvm_size = svm_msg_q_size_to_alloc (cfg) * n_mqs + (16 << 10); - eqs->ssvm.name = format (0, "%s-rx-mqs-seg%c", app->name, 0); + eqs->ssvm.ssvm_size = svm_msg_q_size_to_alloc (cfg) * n_mqs + (1 << 20); + eqs->ssvm.name = format (0, "%v-rx-mqs-seg%c", app->name, 0); if (ssvm_server_init (&eqs->ssvm, SSVM_SEGMENT_MEMFD)) { @@ -658,7 +684,7 @@ application_get_rx_mqs_segment (application_t *app) { if (application_use_private_rx_mqs ()) return &app->rx_mqs_segment; - return session_main_get_evt_q_segment (); + return session_main_get_wrk_mqs_segment (); } void @@ -721,14 +747,14 @@ application_verify_cfg (ssvm_segment_type_t st) u8 is_valid; if (st == SSVM_SEGMENT_MEMFD) { - is_valid = (session_main_get_evt_q_segment () != 0); + is_valid = (session_main_get_wrk_mqs_segment () != 0); if (!is_valid) clib_warning ("memfd seg: vpp's event qs IN binary api svm region"); return is_valid; } else if (st == SSVM_SEGMENT_SHM) { - is_valid = (session_main_get_evt_q_segment () == 0); + is_valid = (session_main_get_wrk_mqs_segment () == 0); if (!is_valid) clib_warning ("shm seg: vpp's event qs NOT IN binary api svm region"); return is_valid; @@ -743,18 +769,19 @@ application_alloc_and_init (app_init_args_t * a) ssvm_segment_type_t seg_type = SSVM_SEGMENT_MEMFD; segment_manager_props_t *props; application_t *app; - u64 *options; + u64 *opts; app = application_alloc (); - options = a->options; + opts = a->options; /* * Make sure we support the requested configuration */ - if (options[APP_OPTIONS_FLAGS] & APP_OPTIONS_FLAGS_IS_BUILTIN) + if ((opts[APP_OPTIONS_FLAGS] & APP_OPTIONS_FLAGS_IS_BUILTIN) && + !(opts[APP_OPTIONS_FLAGS] & APP_OPTIONS_FLAGS_MEMFD_FOR_BUILTIN)) seg_type = SSVM_SEGMENT_PRIVATE; - if ((options[APP_OPTIONS_FLAGS] & APP_OPTIONS_FLAGS_EVT_MQ_USE_EVENTFD) - && seg_type != SSVM_SEGMENT_MEMFD) + if ((opts[APP_OPTIONS_FLAGS] & APP_OPTIONS_FLAGS_EVT_MQ_USE_EVENTFD) && + seg_type != SSVM_SEGMENT_MEMFD) { clib_warning ("mq eventfds can only be used if socket transport is " "used for binary api"); @@ -764,17 +791,17 @@ application_alloc_and_init (app_init_args_t * a) if (!application_verify_cfg (seg_type)) return VNET_API_ERROR_APP_UNSUPPORTED_CFG; - if (options[APP_OPTIONS_PREALLOC_FIFO_PAIRS] - && options[APP_OPTIONS_PREALLOC_FIFO_HDRS]) + if (opts[APP_OPTIONS_PREALLOC_FIFO_PAIRS] && + opts[APP_OPTIONS_PREALLOC_FIFO_HDRS]) return VNET_API_ERROR_APP_UNSUPPORTED_CFG; /* Check that the obvious things are properly set up */ application_verify_cb_fns (a->session_cb_vft); - app->flags = options[APP_OPTIONS_FLAGS]; + app->flags = opts[APP_OPTIONS_FLAGS]; app->cb_fns = *a->session_cb_vft; - app->ns_index = options[APP_OPTIONS_NAMESPACE]; - app->proxied_transports = options[APP_OPTIONS_PROXY_TRANSPORT]; + app->ns_index = opts[APP_OPTIONS_NAMESPACE]; + app->proxied_transports = opts[APP_OPTIONS_PROXY_TRANSPORT]; app->name = vec_dup (a->name); /* If no scope enabled, default to global */ @@ -784,32 +811,32 @@ application_alloc_and_init (app_init_args_t * a) props = application_segment_manager_properties (app); segment_manager_props_init (props); - props->segment_size = options[APP_OPTIONS_SEGMENT_SIZE]; - props->prealloc_fifos = options[APP_OPTIONS_PREALLOC_FIFO_PAIRS]; - props->prealloc_fifo_hdrs = options[APP_OPTIONS_PREALLOC_FIFO_HDRS]; - if (options[APP_OPTIONS_ADD_SEGMENT_SIZE]) + props->segment_size = opts[APP_OPTIONS_SEGMENT_SIZE]; + props->prealloc_fifos = opts[APP_OPTIONS_PREALLOC_FIFO_PAIRS]; + props->prealloc_fifo_hdrs = opts[APP_OPTIONS_PREALLOC_FIFO_HDRS]; + if (opts[APP_OPTIONS_ADD_SEGMENT_SIZE]) { - props->add_segment_size = options[APP_OPTIONS_ADD_SEGMENT_SIZE]; + props->add_segment_size = opts[APP_OPTIONS_ADD_SEGMENT_SIZE]; props->add_segment = 1; } - if (options[APP_OPTIONS_RX_FIFO_SIZE]) - props->rx_fifo_size = options[APP_OPTIONS_RX_FIFO_SIZE]; - if (options[APP_OPTIONS_TX_FIFO_SIZE]) - props->tx_fifo_size = options[APP_OPTIONS_TX_FIFO_SIZE]; - if (options[APP_OPTIONS_EVT_QUEUE_SIZE]) - props->evt_q_size = options[APP_OPTIONS_EVT_QUEUE_SIZE]; - if (options[APP_OPTIONS_FLAGS] & APP_OPTIONS_FLAGS_EVT_MQ_USE_EVENTFD) + if (opts[APP_OPTIONS_RX_FIFO_SIZE]) + props->rx_fifo_size = opts[APP_OPTIONS_RX_FIFO_SIZE]; + if (opts[APP_OPTIONS_TX_FIFO_SIZE]) + props->tx_fifo_size = opts[APP_OPTIONS_TX_FIFO_SIZE]; + if (opts[APP_OPTIONS_EVT_QUEUE_SIZE]) + props->evt_q_size = opts[APP_OPTIONS_EVT_QUEUE_SIZE]; + if (opts[APP_OPTIONS_FLAGS] & APP_OPTIONS_FLAGS_EVT_MQ_USE_EVENTFD) props->use_mq_eventfd = 1; - if (options[APP_OPTIONS_TLS_ENGINE]) - app->tls_engine = options[APP_OPTIONS_TLS_ENGINE]; - if (options[APP_OPTIONS_MAX_FIFO_SIZE]) - props->max_fifo_size = options[APP_OPTIONS_MAX_FIFO_SIZE]; - if (options[APP_OPTIONS_HIGH_WATERMARK]) - props->high_watermark = options[APP_OPTIONS_HIGH_WATERMARK]; - if (options[APP_OPTIONS_LOW_WATERMARK]) - props->low_watermark = options[APP_OPTIONS_LOW_WATERMARK]; - if (options[APP_OPTIONS_PCT_FIRST_ALLOC]) - props->pct_first_alloc = options[APP_OPTIONS_PCT_FIRST_ALLOC]; + if (opts[APP_OPTIONS_TLS_ENGINE]) + app->tls_engine = opts[APP_OPTIONS_TLS_ENGINE]; + if (opts[APP_OPTIONS_MAX_FIFO_SIZE]) + props->max_fifo_size = opts[APP_OPTIONS_MAX_FIFO_SIZE]; + if (opts[APP_OPTIONS_HIGH_WATERMARK]) + props->high_watermark = opts[APP_OPTIONS_HIGH_WATERMARK]; + if (opts[APP_OPTIONS_LOW_WATERMARK]) + props->low_watermark = opts[APP_OPTIONS_LOW_WATERMARK]; + if (opts[APP_OPTIONS_PCT_FIRST_ALLOC]) + props->pct_first_alloc = opts[APP_OPTIONS_PCT_FIRST_ALLOC]; props->segment_type = seg_type; /* Add app to lookup by api_client_index table */ @@ -920,6 +947,31 @@ application_detach_process (application_t * app, u32 api_client_index) vec_free (wrks); } +void +application_namespace_cleanup (app_namespace_t *app_ns) +{ + u32 *app_indices = 0, *app_index; + application_t *app; + u32 ns_index; + + ns_index = app_namespace_index (app_ns); + pool_foreach (app, app_main.app_pool) + if (app->ns_index == ns_index) + vec_add1 (app_indices, app->ns_index); + + vec_foreach (app_index, app_indices) + { + app = application_get (*app_index); + + if (application_is_proxy (app)) + application_remove_proxy (app); + app->flags &= ~APP_OPTIONS_FLAGS_IS_PROXY; + + application_free (app); + } + vec_free (app_indices); +} + app_worker_t * application_get_worker (application_t * app, u32 wrk_map_index) { @@ -982,7 +1034,7 @@ application_alloc_worker_and_init (application_t * app, app_worker_t ** wrk) /* * Setup app worker */ - app_wrk->first_segment_manager = segment_manager_index (sm); + app_wrk->connects_seg_manager = segment_manager_index (sm); app_wrk->listeners_table = hash_create (0, sizeof (u64)); app_wrk->event_queue = segment_manager_event_queue (sm); app_wrk->app_is_builtin = application_is_builtin (app); @@ -1015,7 +1067,7 @@ vnet_app_worker_add_del (vnet_app_worker_add_del_args_t * a) app_wrk->api_client_index = a->api_client_index; application_api_table_add (app->app_index, a->api_client_index); - sm = segment_manager_get (app_wrk->first_segment_manager); + sm = segment_manager_get (app_wrk->connects_seg_manager); fs = segment_manager_get_segment_w_lock (sm, 0); a->segment = &fs->ssvm; a->segment_handle = segment_manager_segment_handle (sm, fs); @@ -1034,6 +1086,8 @@ vnet_app_worker_add_del (vnet_app_worker_add_del_args_t * a) return VNET_API_ERROR_INVALID_VALUE; application_api_table_del (app_wrk->api_client_index); + if (appns_sapi_enabled ()) + sapi_socket_close_w_handle (app_wrk->api_client_index); app_worker_free (app_wrk); app_worker_map_free (app, wrk_map); if (application_n_workers (app) == 0) @@ -1131,7 +1185,7 @@ vnet_application_attach (vnet_app_attach_args_t * a) a->app_evt_q = app_wrk->event_queue; app_wrk->api_client_index = a->api_client_index; - sm = segment_manager_get (app_wrk->first_segment_manager); + sm = segment_manager_get (app_wrk->connects_seg_manager); fs = segment_manager_get_segment_w_lock (sm, 0); if (application_is_proxy (app)) @@ -1139,7 +1193,7 @@ vnet_application_attach (vnet_app_attach_args_t * a) application_setup_proxy (app); /* The segment manager pool is reallocated because a new listener * is added. Re-grab segment manager to avoid dangling reference */ - sm = segment_manager_get (app_wrk->first_segment_manager); + sm = segment_manager_get (app_wrk->connects_seg_manager); } ASSERT (vec_len (fs->ssvm.name) <= 128); @@ -1305,6 +1359,8 @@ vnet_connect (vnet_connect_args_t * a) session_endpoint_update_for_app (&a->sep_ext, client, 1 /* is_connect */ ); client_wrk = application_get_worker (client, a->wrk_map_index); + a->sep_ext.opaque = a->api_context; + /* * First check the local scope for locally attached destinations. * If we have local scope, we pass *all* connects through it since we may @@ -1316,15 +1372,15 @@ vnet_connect (vnet_connect_args_t * a) a->sep_ext.original_tp = a->sep_ext.transport_proto; a->sep_ext.transport_proto = TRANSPORT_PROTO_NONE; - rv = app_worker_connect_session (client_wrk, &a->sep, a->api_context); - if (rv <= 0) - return rv; + rv = app_worker_connect_session (client_wrk, &a->sep_ext, &a->sh); a->sep_ext.transport_proto = a->sep_ext.original_tp; + if (!rv || rv != SESSION_E_LOCAL_CONNECT) + return rv; } /* * Not connecting to a local server, propagate to transport */ - return app_worker_connect_session (client_wrk, &a->sep, a->api_context); + return app_worker_connect_session (client_wrk, &a->sep_ext, &a->sh); } int @@ -1358,6 +1414,27 @@ vnet_unlisten (vnet_unlisten_args_t * a) return app_worker_stop_listen (app_wrk, al); } +int +vnet_shutdown_session (vnet_shutdown_args_t *a) +{ + app_worker_t *app_wrk; + session_t *s; + + s = session_get_from_handle_if_valid (a->handle); + if (!s) + return SESSION_E_NOSESSION; + + app_wrk = app_worker_get (s->app_wrk_index); + if (app_wrk->app_index != a->app_index) + return SESSION_E_OWNER; + + /* We're peeking into another's thread pool. Make sure */ + ASSERT (s->session_index == session_index_from_handle (a->handle)); + + session_half_close (s); + return 0; +} + int vnet_disconnect_session (vnet_disconnect_args_t * a) { @@ -1559,12 +1636,8 @@ application_setup_proxy (application_t * app) ASSERT (application_is_proxy (app)); - /* *INDENT-OFF* */ - transport_proto_foreach (tp, ({ - if (transports & (1 << tp)) - application_start_stop_proxy (app, tp, 1); - })); - /* *INDENT-ON* */ + transport_proto_foreach (tp, transports) + application_start_stop_proxy (app, tp, 1); } void @@ -1575,12 +1648,8 @@ application_remove_proxy (application_t * app) ASSERT (application_is_proxy (app)); - /* *INDENT-OFF* */ - transport_proto_foreach (tp, ({ - if (transports & (1 << tp)) - application_start_stop_proxy (app, tp, 0); - })); - /* *INDENT-ON* */ + transport_proto_foreach (tp, transports) + application_start_stop_proxy (app, tp, 0); } segment_manager_props_t * @@ -1855,10 +1924,11 @@ static clib_error_t * show_app_command_fn (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd) { - int do_server = 0, do_client = 0, do_mq = 0; + int do_server = 0, do_client = 0, do_mq = 0, do_transports = 0; application_t *app; u32 app_index = ~0; int verbose = 0; + u8 is_ta; session_cli_return_if_not_enabled (); @@ -1868,6 +1938,8 @@ show_app_command_fn (vlib_main_t * vm, unformat_input_t * input, do_server = 1; else if (unformat (input, "client")) do_client = 1; + else if (unformat (input, "transports")) + do_transports = 1; else if (unformat (input, "mq")) do_mq = 1; else if (unformat (input, "%u", &app_index)) @@ -1921,11 +1993,11 @@ show_app_command_fn (vlib_main_t * vm, unformat_input_t * input, if (!do_server && !do_client) { vlib_cli_output (vm, "%U", format_application, 0, 0); - /* *INDENT-OFF* */ pool_foreach (app, app_main.app_pool) { - vlib_cli_output (vm, "%U", format_application, app, 0); + is_ta = app->flags & APP_OPTIONS_FLAGS_IS_TRANSPORT_APP; + if ((!do_transports && !is_ta) || (do_transports && is_ta)) + vlib_cli_output (vm, "%U", format_application, app, 0); } - /* *INDENT-ON* */ } return 0; @@ -2028,23 +2100,20 @@ application_init (vlib_main_t * vm) return 0; } -/* *INDENT-OFF* */ VLIB_INIT_FUNCTION (application_init); -VLIB_CLI_COMMAND (show_app_command, static) = -{ +VLIB_CLI_COMMAND (show_app_command, static) = { .path = "show app", - .short_help = "show app [app_id] [server|client] [mq] [verbose]", + .short_help = "show app [index] [server|client] [mq] [verbose] " + "[transports]", .function = show_app_command_fn, }; -VLIB_CLI_COMMAND (show_certificate_command, static) = -{ +VLIB_CLI_COMMAND (show_certificate_command, static) = { .path = "show app certificate", .short_help = "list app certs and keys present in store", .function = show_certificate_command_fn, }; -/* *INDENT-ON* */ crypto_engine_type_t app_crypto_engine_type_add (void)