24 #define app_interface_check_thread_and_barrier(_fn, _arg) \ 25 if (PREDICT_FALSE (!vlib_thread_is_main_w_barrier ())) \ 27 vlib_rpc_call_main_thread (_fn, (u8 *) _arg, sizeof(*_arg)); \ 36 clib_memset (app_listener, 0,
sizeof (*app_listener));
56 clib_memset (app_listener, 0xfa,
sizeof (*app_listener));
100 u32 table_index, fib_proto;
136 u32 al_index, table_index;
233 *listener = app_listener;
340 app_ns->ip4_fib_index);
343 app_ns->ip6_fib_index);
353 return app_ns->local_table_index;
448 clib_warning (
"No session connected callback function provided");
450 clib_warning (
"No session disconnect callback function provided");
452 clib_warning (
"No session reset callback function provided");
468 clib_warning (
"memfd seg: vpp's event qs IN binary api svm region");
475 clib_warning (
"shm seg: vpp's event qs NOT IN binary api svm region");
491 options = a->options;
501 clib_warning (
"mq eventfds can only be used if socket transport is " 502 "used for binary api");
503 return VNET_API_ERROR_APP_UNSUPPORTED_CFG;
507 return VNET_API_ERROR_APP_UNSUPPORTED_CFG;
511 return VNET_API_ERROR_APP_UNSUPPORTED_CFG;
517 app->
cb_fns = *a->session_cb_vft;
525 app->
flags |= APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
535 props->add_segment = 1;
544 props->use_mq_eventfd = 1;
555 props->segment_type = seg_type;
565 APP_DBG (
"New app name: %v api index: %u index %u", app->
name,
592 app_wrk = app_worker_get (wrk_map->wrk_index);
593 app_worker_free (app_wrk);
612 u32 *wrks = 0, *wrk_index;
615 if (api_client_index == ~0)
621 APP_DBG (
"Detaching for app %v index %u api client index %u", app->
name,
640 args->api_client_index = api_client_index;
708 sm->first_is_protected = 1;
735 return VNET_API_ERROR_INVALID_VALUE;
748 a->segment = &fs->
ssvm;
758 return VNET_API_ERROR_INVALID_VALUE;
762 return VNET_API_ERROR_INVALID_VALUE;
777 if (
vec_len (namespace_id) == 0)
786 return VNET_API_ERROR_APP_INVALID_NS;
789 return VNET_API_ERROR_APP_INVALID_NS;
790 if (app_ns->ns_secret != secret)
791 return VNET_API_ERROR_APP_WRONG_NS_SECRET;
803 clib_warning (
"api client index %u does not have an api registration!",
805 return format (0,
"unknown");
822 u32 app_ns_index = 0;
832 return VNET_API_ERROR_INVALID_VALUE;
835 return VNET_API_ERROR_APP_ALREADY_ATTACHED;
838 if (!a->use_sock_api)
874 a->segment = &fs->
ssvm;
894 return VNET_API_ERROR_APPLICATION_NOT_ATTACHED;
910 clib_warning (
"sw_if_index %u not configured with ip %U",
915 return (is_lep ||
ip_is_local (sep->fib_index, &sep->ip, sep->is_ip4));
923 u32 ns_index, fib_index;
928 if (app->
flags & APP_OPTIONS_FLAGS_IS_TRANSPORT_APP)
929 ns_index = sep->ns_index;
942 fib_index = sep->fib_index;
944 fib_index = sep->is_ip4 ? app_ns->ip4_fib_index : app_ns->ip6_fib_index;
945 sep->peer.fib_index = fib_index;
946 sep->fib_index = fib_index;
950 sep->sw_if_index = app_ns->sw_if_index;
956 && sep->peer.sw_if_index != app_ns->sw_if_index)
957 clib_warning (
"Local sw_if_index different from app ns sw_if_index");
959 sep->peer.sw_if_index = app_ns->sw_if_index;
975 return SESSION_E_NOAPP;
979 return SESSION_E_INVALID_APPWRK;
981 a->sep_ext.app_wrk_index = app_wrk->
wrk_index;
985 return SESSION_E_INVALID_NS;
994 return SESSION_E_ALREADY_LISTENING;
1026 return SESSION_E_INVALID_RMT_IP;
1041 a->sep_ext.original_tp = a->sep_ext.transport_proto;
1042 a->sep_ext.transport_proto = TRANSPORT_PROTO_NONE;
1046 a->sep_ext.transport_proto = a->sep_ext.original_tp;
1064 return SESSION_E_NOAPP;
1067 return SESSION_E_NOLISTEN;
1071 clib_warning (
"app doesn't own handle %llu!", a->handle);
1072 return SESSION_E_OWNER;
1079 return SESSION_E_INVALID_APPWRK;
1093 return SESSION_E_NOSESSION;
1097 return SESSION_E_OWNER;
1115 return SESSION_E_INVALID_APPWRK;
1124 return SESSION_E_NOAPP;
1143 return (app->
flags & APP_OPTIONS_FLAGS_IS_PROXY);
1149 return (app->
flags & APP_OPTIONS_FLAGS_IS_BUILTIN);
1161 return app->
flags & APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
1167 return app->
flags & APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
1190 sep.is_ip4 = is_ip4;
1192 sep.sw_if_index = app_ns->sw_if_index;
1198 app->
flags &= ~APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
1204 s->
flags |= SESSION_F_PROXY;
1218 sep.is_ip4 = is_ip4;
1272 transport_proto, is_start);
1274 transport_proto, is_start);
1288 if (transports & (1 << tp))
1304 if (transports & (1 << tp))
1365 vlib_cli_output (vm,
"%U", format_app_worker_listener, app_wrk,
1366 handle, sm_index, verbose);
1396 int key_len = 0, cert_len = 0;
1400 s =
format (s,
"DEFAULT (cert:%d, key:%d)", cert_len, key_len);
1410 u32 engine = va_arg (*args,
u32);
1414 return format (s,
"none");
1416 return format (s,
"mbedtls");
1418 return format (s,
"openssl");
1420 return format (s,
"picotls");
1422 return format (s,
"vpp");
1424 return format (s,
"unknown engine");
1432 u8 *
a = va_arg (*args,
u8 *);
1435 else if (
unformat (input,
"openssl"))
1437 else if (
unformat (input,
"picotls"))
1462 const u8 *app_ns_name, *app_name;
1469 s =
format (s,
"%-10s%-20s%-40s",
"Index",
"Name",
"Namespace");
1483 s =
format (s,
"app-name %v app-index %u ns-index %u seg-size %U\n",
1486 s =
format (s,
"rx-fifo-size %U tx-fifo-size %U workers:\n",
1578 for (i = 0; i < n_threads; i++)
1596 int do_server = 0, do_client = 0, do_mq = 0;
1607 else if (
unformat (input,
"client"))
1611 else if (
unformat (input,
"%u", &app_index))
1613 else if (
unformat (input,
"verbose"))
1620 if (do_mq && app_index != ~0)
1648 if (app_index != ~0)
1659 if (!do_server && !do_client)
1734 return (VNET_API_ERROR_INVALID_VALUE);
1765 .short_help =
"show app [app_id] [server|client] [mq] [verbose]",
1771 .path =
"show app certificate",
1772 .short_help =
"list app certs and keys present in store",
u32 segment_manager_index(segment_manager_t *sm)
static void application_name_table_del(application_t *app)
u8 ip_interface_has_address(u32 sw_if_index, ip46_address_t *ip, u8 is_ip4)
u32 al_index
App listener index in app's listener pool if a listener.
struct _vnet_app_worker_add_del_args vnet_app_worker_add_del_args_t
#define ENDPOINT_INVALID_INDEX
#define APP_NAMESPACE_INVALID_INDEX
session_t * app_worker_proxy_listener(app_worker_t *app, u8 fib_proto, u8 transport_proto)
#define hash_set(h, key, value)
void segment_manager_segment_reader_unlock(segment_manager_t *sm)
u64 segment_manager_segment_handle(segment_manager_t *sm, fifo_segment_t *segment)
app_cert_key_pair_t * app_cert_key_pair_get_default()
static void application_detach_process(application_t *app, u32 api_client_index)
int vnet_app_add_cert_key_pair(vnet_app_add_cert_key_pair_args_t *a)
u32 al_index
app listener index in app pool
#define hash_unset(h, key)
vl_api_wireguard_peer_flags_t flags
#define SESSION_TABLE_INVALID_INDEX
u64 session_lookup_endpoint_listener(u32 table_index, session_endpoint_t *sep, u8 use_rules)
Lookup listener for session endpoint in table.
u32 ns_index
Namespace the application belongs to.
u8 application_has_global_scope(application_t *app)
struct _vnet_connect_args vnet_connect_args_t
#define pool_foreach(VAR, POOL)
Iterate through pool.
struct _vnet_unlisten_args_t vnet_unlisten_args_t
int application_change_listener_owner(session_t *s, app_worker_t *app_wrk)
u32 session_index
Index in thread pool where session was allocated.
int session_stop_listen(session_t *s)
Ask transport to stop listening on local transport endpoint.
#define session_cli_return_if_not_enabled()
u8 ip_is_local(u32 fib_index, ip46_address_t *ip46_address, u8 is_ip4)
Checks that an ip is local to the requested fib.
static clib_error_t * show_app_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
transport_connection_t * listen_session_get_transport(session_t *s)
static svm_msg_q_t * session_main_get_vpp_event_queue(u32 thread_index)
crypto_engine_type_t app_crypto_engine_type_add(void)
static app_worker_t * app_listener_select_worker(application_t *app, app_listener_t *al)
app_cert_key_pair_t * app_cert_key_pair_get(u32 index)
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
transport_connection_t * session_get_transport(session_t *s)
application_t * application_lookup_name(const u8 *name)
svm_fifo_t * rx_fifo
Pointers to rx/tx buffers.
int segment_manager_init_first(segment_manager_t *sm)
Initializes segment manager based on options provided.
app_listener_t * app_listener_get_w_session(session_t *ls)
int app_worker_connect_session(app_worker_t *app, session_endpoint_t *tep, u32 api_context)
u32 session_lookup_get_index_for_fib(u32 fib_proto, u32 fib_index)
static session_t * listen_session_get_from_handle(session_handle_t handle)
int vnet_app_del_cert_key_pair(u32 index)
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
u8 * format_svm_msg_q(u8 *s, va_list *args)
Format message queue, shows msg count for each ring.
application_t * application_lookup(u32 api_client_index)
app_listener_t * app_listener_get(application_t *app, u32 app_listener_index)
app_listener_t * listeners
Pool of listeners for the app.
u32 wrk_map_index
Worker index in app's map pool.
session_handle_t app_listener_handle(app_listener_t *al)
static session_t * listen_session_alloc(u8 thread_index, session_type_t type)
static uword * clib_bitmap_set(uword *ai, uword i, uword value)
Sets the ith bit of a bitmap to new_value Removes trailing zeros from the bitmap. ...
#define hash_set_mem(h, key, value)
app_cert_key_pair_t * cert_key_pair_store
Pool from which we allocate certificates (key, cert)
static u8 session_endpoint_fib_proto(session_endpoint_t *sep)
static session_t * session_get(u32 si, u32 thread_index)
int vnet_unlisten(vnet_unlisten_args_t *a)
void(* session_reset_callback)(session_t *s)
Notify app that session was reset.
uword * listeners_table
Lookup tables for listeners.
struct _vnet_application_add_tls_cert_args_t vnet_app_add_tls_cert_args_t
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
uword unformat_crypto_engine(unformat_input_t *input, va_list *args)
vlib_main_t ** vlib_mains
clib_error_t * vnet_app_add_tls_cert(vnet_app_add_tls_cert_args_t *a)
app_worker_t * application_get_worker(application_t *app, u32 wrk_map_index)
#define SESSION_ENDPOINT_NULL
static u8 session_endpoint_in_ns(session_endpoint_t *sep)
application_t * application_get_if_valid(u32 app_index)
enum fib_protocol_t_ fib_protocol_t
Protocol Type.
struct _vnet_bind_args_t vnet_listen_args_t
segment_manager_props_t * application_segment_manager_properties(application_t *app)
static session_handle_t session_handle(session_t *s)
u32 ctx_index
index in crypto context pool
static int application_alloc_and_init(app_init_args_t *a)
u32 app_index
owning app index
int application_is_proxy(application_t *app)
enum ssvm_segment_type_ ssvm_segment_type_t
u32 first_segment_manager
First segment manager has in the the first segment the application's event fifo.
#define VLIB_INIT_FUNCTION(x)
struct _vnet_disconnect_args_t vnet_disconnect_args_t
void segment_manager_dealloc_fifos(svm_fifo_t *rx_fifo, svm_fifo_t *tx_fifo)
u32 local_index
local listening session index
u32 session_index
global listening session index
description fragment has unexpected format
#define hash_foreach(key_var, value_var, h, body)
#define clib_error_return(e, args...)
#define vec_search(v, E)
Search a vector for the index of the entry that matches.
u32 app_namespace_index_from_id(const u8 *ns_id)
static int app_validate_namespace(u8 *namespace_id, u64 secret, u32 *app_ns_index)
#define SESSION_INVALID_HANDLE
u8 tls_engine
Preferred tls engine.
struct _vnet_app_attach_args_t vnet_app_attach_args_t
struct _session_endpoint_cfg session_endpoint_cfg_t
static const u8 * app_get_name(application_t *app)
#define pool_flush(VAR, POOL, BODY)
Remove all elements from a pool in a safe way.
static app_main_t app_main
static void application_verify_cb_fns(session_cb_vft_t *cb_fns)
clib_error_t * vnet_app_add_tls_key(vnet_app_add_tls_key_args_t *a)
int application_is_builtin(application_t *app)
u32 app_namespace_get_fib_index(app_namespace_t *app_ns, u8 fib_proto)
static session_type_t session_type_from_proto_and_ip(transport_proto_t proto, u8 is_ip4)
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
#define hash_unset_mem(h, key)
session_t * app_listener_get_local_session(app_listener_t *al)
static uword clib_bitmap_first_set(uword *ai)
Return the lowest numbered set bit in a bitmap.
static void application_api_table_del(u32 api_client_index)
static session_t * session_get_from_handle(session_handle_t handle)
session_t * app_listener_get_session(app_listener_t *al)
u32 app_index
Index of application that owns the listener.
const u8 * application_name_from_index(u32 app_index)
Returns app name for app-index.
u8 * format_crypto_engine(u8 *s, va_list *args)
static u32 app_worker_map_index(application_t *app, app_worker_map_t *map)
#define pool_put(P, E)
Free an object E in pool P.
#define APP_INVALID_INDEX
#define vec_dup(V)
Return copy of vector (no header, no alignment)
struct _segment_manager_props segment_manager_props_t
app_namespace_t * app_namespace_get(u32 index)
static void appliction_format_app_mq(vlib_main_t *vm, application_t *app)
u32 wrk_index
Worker index in global worker pool.
static clib_error_t * show_certificate_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
u32 application_session_table(application_t *app, u8 fib_proto)
#define SESSION_INVALID_INDEX
app_worker_t * app_worker_alloc(application_t *app)
session_handle_t app_listen_session_handle(session_t *ls)
Get app listener handle for listening session.
u32 n_subscribers
refcount of sessions using said context
u8 * format_cert_key_pair(u8 *s, va_list *args)
static u64 listen_session_get_handle(session_t *s)
u8 * format_app_worker_listener(u8 *s, va_list *args)
app_worker_map_t * worker_maps
Pool of mappings that keep track of workers associated to this app.
format_function_t format_ip46_address
int vnet_application_attach(vnet_app_attach_args_t *a)
Attach application to vpp.
static session_t * session_get_from_handle_if_valid(session_handle_t handle)
#define pool_free(p)
Free a pool.
An API client registration, only in vpp/vlib.
svm_msg_q_t * segment_manager_event_queue(segment_manager_t *sm)
u32 application_local_session_table(application_t *app)
int(* session_connected_callback)(u32 app_wrk_index, u32 opaque, session_t *s, session_error_t code)
Connection request callback.
app_cert_key_pair_t * app_cert_key_pair_get_if_valid(u32 index)
ssvm_private_t ssvm
ssvm segment data
u32 ckpair_index
certificate & key
uword * app_by_name
Hash table of builtin apps by name.
segment_manager_t * segment_manager_alloc(void)
static void app_listener_free(application_t *app, app_listener_t *app_listener)
int(* app_cert_key_pair_delete_callback)(app_cert_key_pair_t *ckpair)
Cert and key pair delete notification.
session_t * app_worker_first_listener(app_worker_t *app, u8 fib_proto, u8 transport_proto)
sll srl srl sll sra u16x4 i
#define vec_free(V)
Free vector's memory (no header).
segment_manager_props_t sm_properties
Segment manager properties.
static application_t * application_alloc(void)
int session_lookup_del_session_endpoint(u32 table_index, session_endpoint_t *sep)
void session_free(session_t *s)
#define clib_warning(format, args...)
static void session_endpoint_update_for_app(session_endpoint_cfg_t *sep, application_t *app, u8 is_connect)
Don't register connection in lookup.
clib_bitmap_t * workers
workers accepting connections
struct _transport_connection transport_connection_t
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
const u8 * app_namespace_id_from_index(u32 index)
void application_format_all_clients(vlib_main_t *vm, int verbose)
static vl_api_registration_t * vl_api_client_index_to_registration(u32 index)
int session_lookup_add_session_endpoint(u32 table_index, session_endpoint_t *sep, u64 value)
static u8 vlib_thread_is_main_w_barrier(void)
static void application_name_table_add(application_t *app)
struct _app_namespace app_namespace_t
application_t * application_get(u32 app_index)
int vnet_app_add_cert_key_interest(u32 index, u32 app_index)
Ask for app cb on pair deletion.
#define VLIB_CLI_COMMAND(x,...)
segment_manager_props_t * application_get_segment_manager_properties(u32 app_index)
int session_listen(session_t *ls, session_endpoint_cfg_t *sep)
Ask transport to listen on session endpoint.
static u32 session_index_from_handle(session_handle_t handle)
#define hash_create(elts, value_bytes)
int app_listener_alloc_and_init(application_t *app, session_endpoint_cfg_t *sep, app_listener_t **listener)
app_listener_t * app_listener_get_w_handle(session_handle_t handle)
Get app listener for listener session handle.
static uword hash_elts(void *v)
int application_alloc_worker_and_init(application_t *app, app_worker_t **wrk)
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
segment_manager_props_t * segment_manager_props_init(segment_manager_props_t *props)
app_worker_t * application_listener_select_worker(session_t *ls)
static u8 * app_name_from_api_index(u32 api_client_index)
int vnet_listen(vnet_listen_args_t *a)
uword * app_by_api_client_index
Hash table of apps by api client index.
fifo_segment_t * segment_manager_get_segment_w_lock(segment_manager_t *sm, u32 segment_index)
Reads a segment from the segment manager's pool and acquires reader lock.
int vnet_application_detach(vnet_app_detach_args_t *a)
Detach application from vpp.
void application_remove_proxy(application_t *app)
session_cb_vft_t cb_fns
Callbacks: shoulder-taps for the server/client.
struct _vnet_application_add_tls_key_args_t vnet_app_add_tls_key_args_t
enum _transport_proto transport_proto_t
struct _vnet_app_add_cert_key_pair_args_ vnet_app_add_cert_key_pair_args_t
#define clib_bitmap_free(v)
Free a bitmap.
u32 accept_rotor
last worker to accept a connection
struct _vnet_app_detach_args_t vnet_app_detach_args_t
int vnet_connect(vnet_connect_args_t *a)
static vlib_main_t * vlib_get_main(void)
static void listen_session_free(session_t *s)
u8 ip_is_zero(ip46_address_t *ip46_address, u8 is_ip4)
u32 app_index
App index in app pool.
#define hash_create_vec(elts, key_bytes, value_bytes)
app_worker_t * app_worker_get(u32 wrk_index)
application_t * app_pool
Pool from which we allocate all applications.
static void application_free(application_t *app)
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
u8 * format_application(u8 *s, va_list *args)
void(* session_disconnect_callback)(session_t *s)
Notify app that session is closing.
u8 * name
Name registered by builtin apps.
void session_close(session_t *s)
Initialize session closing procedure.
session_handle_t ls_handle
session handle of the local or global listening session that also identifies the app listener ...
static u8 session_endpoint_is_zero(session_endpoint_t *sep)
static app_worker_map_t * app_worker_map_alloc(application_t *app)
ssvm_private_t * session_main_get_evt_q_segment(void)
int vnet_disconnect_session(vnet_disconnect_args_t *a)
app_worker_t * application_get_default_worker(application_t *app)
struct _segment_manager segment_manager_t
#define SESSION_ENDPOINT_CFG_NULL
segment_manager_t * segment_manager_get(u32 index)
u32 application_n_workers(application_t *app)
void app_listener_cleanup(app_listener_t *al)
int vnet_app_worker_add_del(vnet_app_worker_add_del_args_t *a)
static void application_api_table_add(u32 app_index, u32 api_client_index)
static void application_format_listeners(application_t *app, int verbose)
int app_worker_start_listen(app_worker_t *app_wrk, app_listener_t *lstnr)
static clib_error_t * application_start_stop_proxy_fib_proto(application_t *app, u8 fib_proto, u8 transport_proto, u8 is_start)
#define hash_get_mem(h, key)
#define app_interface_check_thread_and_barrier(_fn, _arg)
u8 app_crypto_engine_n_types(void)
u32 app_index
Index of owning app.
app_listener_t * app_listener_lookup(application_t *app, session_endpoint_cfg_t *sep_ext)
static struct option options[]
static void application_start_stop_proxy_local_scope(application_t *app, u8 transport_proto, u8 is_start)
int app_worker_stop_listen(app_worker_t *app_wrk, app_listener_t *al)
void app_worker_free(app_worker_t *app_wrk)
static app_cert_key_pair_t * app_cert_key_pair_alloc()
#define transport_proto_foreach(VAR, BODY)
static app_worker_map_t * app_worker_map_get(application_t *app, u32 map_index)
#define vec_foreach(var, vec)
Vector iterator.
enum crypto_engine_type_ crypto_engine_type_t
u32 app_wrk_index
Index of the app worker that owns the session.
void application_setup_proxy(application_t *app)
void app_worker_format_connects(app_worker_t *app_wrk, int verbose)
static u8 session_endpoint_is_local(session_endpoint_t *sep)
static u8 application_verify_cfg(ssvm_segment_type_t st)
Check app config for given segment type.
static void application_format_connects(application_t *app, int verbose)
int(* session_accept_callback)(session_t *new_session)
Notify server of newly accepted session.
int application_is_builtin_proxy(application_t *app)
u32 api_client_index
API index for the worker.
struct _session_endpoint session_endpoint_t
static void app_worker_map_free(application_t *app, app_worker_map_t *map)
void application_start_stop_proxy(application_t *app, transport_proto_t transport_proto, u8 is_start)
svm_msg_q_t * event_queue
Application listens for events on this svm queue.
u8 * format_app_worker(u8 *s, va_list *args)
static transport_service_type_t session_transport_service_type(session_t *s)
void application_format_all_listeners(vlib_main_t *vm, int verbose)
#define APP_DBG(_fmt, _args...)
clib_error_t * application_init(vlib_main_t *vm)
crypto_engine_type_t last_crypto_engine
static session_t * listen_session_get(u32 ls_index)
static clib_error_t * appliction_format_all_app_mq(vlib_main_t *vm)
void ct_session_endpoint(session_t *ll, session_endpoint_t *sep)
static app_listener_t * app_listener_alloc(application_t *app)
u8 * format_crypto_context(u8 *s, va_list *args)
u8 application_has_local_scope(application_t *app)
static uword pool_elts(void *v)
Number of active elements in a pool.