blob: c3d6180022f2367e971703129402dc9e064a4035 [file] [log] [blame]
Dave Barach68b0fb02017-02-28 15:15:56 -05001/*
Florin Coras288eaab2019-02-03 15:26:14 -08002 * Copyright (c) 2017-2019 Cisco and/or its affiliates.
Dave Barach68b0fb02017-02-28 15:15:56 -05003 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef SRC_VNET_SESSION_APPLICATION_H_
17#define SRC_VNET_SESSION_APPLICATION_H_
18
Florin Corasc1a42652019-02-08 18:27:29 -080019#include <vnet/session/application_interface.h>
20#include <vnet/session/application_namespace.h>
Florin Coras1ee78302019-02-05 15:51:15 -080021#include <vnet/session/session_types.h>
Florin Coras6cf30ad2017-04-04 23:08:23 -070022#include <vnet/session/segment_manager.h>
Dave Barach68b0fb02017-02-28 15:15:56 -050023
Florin Coras15531972018-08-12 23:50:53 -070024#define APP_DEBUG 0
25
26#if APP_DEBUG > 0
27#define APP_DBG(_fmt, _args...) clib_warning (_fmt, ##_args)
28#else
29#define APP_DBG(_fmt, _args...)
30#endif
31
Florin Coras20c24232021-11-22 21:19:01 -080032typedef struct app_wrk_postponed_msg_
33{
34 u32 len;
35 u8 event_type;
36 u8 ring;
37 u8 is_sapi;
38 int fd;
Florin Coras6ac74e42022-01-10 14:26:21 -080039 u8 data[SESSION_CTRL_MSG_TX_MAX_SIZE];
Florin Coras20c24232021-11-22 21:19:01 -080040} app_wrk_postponed_msg_t;
41
Florin Coras15531972018-08-12 23:50:53 -070042typedef struct app_worker_
Dave Barach68b0fb02017-02-28 15:15:56 -050043{
Florin Corasab2f6db2018-08-31 14:31:41 -070044 CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
45
Florin Coras15531972018-08-12 23:50:53 -070046 /** Worker index in global worker pool*/
47 u32 wrk_index;
Dave Barach68b0fb02017-02-28 15:15:56 -050048
Florin Coras15531972018-08-12 23:50:53 -070049 /** Worker index in app's map pool */
50 u32 wrk_map_index;
Dave Barach68b0fb02017-02-28 15:15:56 -050051
Florin Coras15531972018-08-12 23:50:53 -070052 /** Index of owning app */
53 u32 app_index;
Florin Corascea194d2017-10-02 00:18:51 -070054
Dave Barach68b0fb02017-02-28 15:15:56 -050055 /** Application listens for events on this svm queue */
Florin Coras3c2fed52018-07-04 04:15:05 -070056 svm_msg_q_t *event_queue;
Dave Barach68b0fb02017-02-28 15:15:56 -050057
Florin Coras94a6df02021-05-06 15:32:14 -070058 /**
59 * Segment manager used for outgoing connects issued by the app. By
60 * convention this is the first segment manager allocated by the worker
61 * so it's also the one that holds the first segment with the app's
62 * message queue in it.
63 */
Florin Coras6cf30ad2017-04-04 23:08:23 -070064 u32 connects_seg_manager;
65
Florin Corasc87c91d2017-08-16 19:55:49 -070066 /** Lookup tables for listeners. Value is segment manager index */
Florin Coras6cf30ad2017-04-04 23:08:23 -070067 uword *listeners_table;
68
Florin Coras053a0e42018-11-13 15:52:38 -080069 /** API index for the worker. Needed for multi-process apps */
Florin Corasc1f5a432018-11-20 11:31:26 -080070 u32 api_client_index;
Florin Coras053a0e42018-11-13 15:52:38 -080071
Florin Coras20c24232021-11-22 21:19:01 -080072 /** Set if mq is congested */
73 u8 mq_congested;
74
Florin Coras15531972018-08-12 23:50:53 -070075 u8 app_is_builtin;
Florin Corasd50ff7f2020-04-16 04:30:22 +000076
Florin Corasea727642021-05-07 19:39:43 -070077 /** Pool of half-open session handles. Tracked in case worker detaches */
78 session_handle_t *half_open_table;
Florin Corasc8e812f2020-05-14 05:32:18 +000079
80 /** Protects detached seg managers */
81 clib_spinlock_t detached_seg_managers_lock;
82
83 /** Vector of detached listener segment managers */
84 u32 *detached_seg_managers;
Florin Coras20c24232021-11-22 21:19:01 -080085
86 /** Fifo of messages postponed because of mq congestion */
87 app_wrk_postponed_msg_t *postponed_mq_msgs;
88
89 /** Lock to add/sub message from ref @postponed_mq_msgs */
90 clib_spinlock_t postponed_mq_msgs_lock;
Florin Coras15531972018-08-12 23:50:53 -070091} app_worker_t;
92
93typedef struct app_worker_map_
94{
95 u32 wrk_index;
96} app_worker_map_t;
97
Florin Corasab2f6db2018-08-31 14:31:41 -070098typedef struct app_listener_
99{
100 clib_bitmap_t *workers; /**< workers accepting connections */
101 u32 accept_rotor; /**< last worker to accept a connection */
Florin Coras87d66332019-06-11 12:31:31 -0700102 u32 al_index; /**< app listener index in app pool */
103 u32 app_index; /**< owning app index */
104 u32 local_index; /**< local listening session index */
105 u32 session_index; /**< global listening session index */
106 session_handle_t ls_handle; /**< session handle of the local or global
107 listening session that also identifies
108 the app listener */
Florin Corasab2f6db2018-08-31 14:31:41 -0700109} app_listener_t;
110
Florin Coras41d5f542021-01-15 13:49:33 -0800111typedef enum app_rx_mq_flags_
112{
113 APP_RX_MQ_F_PENDING = 1 << 0,
114 APP_RX_MQ_F_POSTPONED = 1 << 1,
115} app_rx_mq_flags_t;
116
117typedef struct app_rx_mq_elt_
118{
119 struct app_rx_mq_elt_ *next;
120 struct app_rx_mq_elt_ *prev;
121 svm_msg_q_t *mq;
122 uword file_index;
123 u32 app_index;
124 u8 flags;
125} app_rx_mq_elt_t;
126
Florin Coras15531972018-08-12 23:50:53 -0700127typedef struct application_
128{
129 /** App index in app pool */
130 u32 app_index;
131
Florin Coras15531972018-08-12 23:50:53 -0700132 /** Flags */
133 u32 flags;
134
135 /** Callbacks: shoulder-taps for the server/client */
136 session_cb_vft_t cb_fns;
137
138 /** Segment manager properties. Shared by all segment managers */
Florin Coras88001c62019-04-24 14:44:46 -0700139 segment_manager_props_t sm_properties;
Florin Coras15531972018-08-12 23:50:53 -0700140
141 /** Pool of mappings that keep track of workers associated to this app */
142 app_worker_map_t *worker_maps;
143
144 /** Name registered by builtin apps */
145 u8 *name;
146
147 /** Namespace the application belongs to */
148 u32 ns_index;
149
150 u16 proxied_transports;
151
Florin Corasab2f6db2018-08-31 14:31:41 -0700152 /** Pool of listeners for the app */
153 app_listener_t *listeners;
154
Florin Coras58d36f02018-03-09 13:05:53 -0800155 /** Preferred tls engine */
156 u8 tls_engine;
Florin Corasab2f6db2018-08-31 14:31:41 -0700157
Nathan Skrzypczakc298f372019-11-12 16:41:00 +0100158 /** quic initialization vector */
159 char quic_iv[17];
160 u8 quic_iv_set;
Nathan Skrzypczak60f3e652019-03-19 13:57:31 +0100161
Florin Coras41d5f542021-01-15 13:49:33 -0800162 /** Segment where rx mqs were allocated */
163 fifo_segment_t rx_mqs_segment;
164
165 /**
166 * Fixed vector of rx mqs that can be a part of pending_rx_mqs
167 * linked list maintained by the app sublayer for each worker
168 */
169 app_rx_mq_elt_t *rx_mqs;
Dave Barach68b0fb02017-02-28 15:15:56 -0500170} application_t;
171
Florin Coras41d5f542021-01-15 13:49:33 -0800172typedef struct app_rx_mq_handle_
173{
174 union
175 {
176 struct
177 {
178 u32 app_index;
179 u32 thread_index;
180 };
181 u64 as_u64;
182 };
183} __attribute__ ((aligned (sizeof (u64)))) app_rx_mq_handle_t;
184
185/**
186 * App sublayer per vpp worker state
187 */
188typedef struct asl_wrk_
189{
190 /** Linked list of mqs with pending messages */
191 app_rx_mq_elt_t *pending_rx_mqs;
192} appsl_wrk_t;
193
Florin Coras15531972018-08-12 23:50:53 -0700194typedef struct app_main_
195{
196 /**
197 * Pool from which we allocate all applications
198 */
199 application_t *app_pool;
200
201 /**
Florin Coras15531972018-08-12 23:50:53 -0700202 * Hash table of apps by api client index
203 */
204 uword *app_by_api_client_index;
205
206 /**
207 * Hash table of builtin apps by name
208 */
209 uword *app_by_name;
Nathan Skrzypczak79f89532019-09-13 11:08:13 +0200210
211 /**
212 * Pool from which we allocate certificates (key, cert)
213 */
214 app_cert_key_pair_t *cert_key_pair_store;
Florin Coras79ba25d2019-10-20 19:32:47 -0700215
216 /*
217 * Last registered crypto engine type
218 */
219 crypto_engine_type_t last_crypto_engine;
Florin Coras41d5f542021-01-15 13:49:33 -0800220
221 /**
222 * App sublayer per-worker state
223 */
224 appsl_wrk_t *wrk;
Florin Coras15531972018-08-12 23:50:53 -0700225} app_main_t;
226
Florin Coras15531972018-08-12 23:50:53 -0700227typedef struct app_init_args_
228{
229#define _(_type, _name) _type _name;
230 foreach_app_init_args
231#undef _
232} app_init_args_t;
233
234typedef struct _vnet_app_worker_add_del_args
235{
236 u32 app_index; /**< App for which a new worker is requested */
Florin Coras349f8ca2018-11-20 16:52:49 -0800237 u32 wrk_map_index; /**< Index to delete or return value if add */
Florin Corasc1f5a432018-11-20 11:31:26 -0800238 u32 api_client_index; /**< Binary API client index */
Florin Coras15531972018-08-12 23:50:53 -0700239 ssvm_private_t *segment; /**< First segment in segment manager */
Florin Corasfa76a762018-11-29 12:40:10 -0800240 u64 segment_handle; /**< Handle for the segment */
Florin Coras15531972018-08-12 23:50:53 -0700241 svm_msg_q_t *evt_q; /**< Worker message queue */
242 u8 is_add; /**< Flag set if addition */
243} vnet_app_worker_add_del_args_t;
244
Florin Corascea194d2017-10-02 00:18:51 -0700245#define APP_INVALID_INDEX ((u32)~0)
246#define APP_NS_INVALID_INDEX ((u32)~0)
Florin Corasc87c91d2017-08-16 19:55:49 -0700247#define APP_INVALID_SEGMENT_MANAGER_INDEX ((u32) ~0)
248
Florin Corasc9940fc2019-02-05 20:55:11 -0800249app_listener_t *app_listener_get (application_t * app, u32 al_index);
250int app_listener_alloc_and_init (application_t * app,
251 session_endpoint_cfg_t * sep,
252 app_listener_t ** listener);
253void app_listener_cleanup (app_listener_t * app_listener);
254session_handle_t app_listener_handle (app_listener_t * app_listener);
255app_listener_t *app_listener_lookup (application_t * app,
256 session_endpoint_cfg_t * sep);
Florin Coras87d66332019-06-11 12:31:31 -0700257
258/**
259 * Get app listener handle for listening session
260 *
261 * For a given listening session, this can return either the session
262 * handle of the app listener associated to the listening session or,
263 * if no such app listener exists, the session's handle
264 *
265 * @param ls listening session
266 * @return app listener or listening session handle
267 */
268session_handle_t app_listen_session_handle (session_t * ls);
269/**
270 * Get app listener for listener session handle
271 *
272 * Should only be called on handles that have an app listener, i.e.,
273 * were obtained at the end of a @ref vnet_listen call.
274 *
275 * @param handle handle of the app listener. This is the handle of
276 * either the global or local listener
277 * @return pointer to app listener or 0
278 */
Florin Corasc9940fc2019-02-05 20:55:11 -0800279app_listener_t *app_listener_get_w_handle (session_handle_t handle);
280app_listener_t *app_listener_get_w_session (session_t * ls);
Florin Corasc9940fc2019-02-05 20:55:11 -0800281session_t *app_listener_get_session (app_listener_t * al);
Florin Corasd4295e62019-02-22 13:11:38 -0800282session_t *app_listener_get_local_session (app_listener_t * al);
Florin Corasc9940fc2019-02-05 20:55:11 -0800283
Dave Barach68b0fb02017-02-28 15:15:56 -0500284application_t *application_get (u32 index);
Florin Corase04c2992017-03-01 08:17:34 -0800285application_t *application_get_if_valid (u32 index);
Dave Barach68b0fb02017-02-28 15:15:56 -0500286application_t *application_lookup (u32 api_client_index);
Florin Coras0bee9ce2018-03-22 21:24:31 -0700287application_t *application_lookup_name (const u8 * name);
Florin Coras15531972018-08-12 23:50:53 -0700288app_worker_t *application_get_worker (application_t * app, u32 wrk_index);
289app_worker_t *application_get_default_worker (application_t * app);
Florin Corasc9940fc2019-02-05 20:55:11 -0800290app_worker_t *application_listener_select_worker (session_t * ls);
Florin Coras623eb562019-02-03 19:28:34 -0800291int application_change_listener_owner (session_t * s, app_worker_t * app_wrk);
Dave Barach52851e62017-08-07 09:35:25 -0400292int application_is_proxy (application_t * app);
Florin Coras7999e832017-10-31 01:51:04 -0700293int application_is_builtin (application_t * app);
294int application_is_builtin_proxy (application_t * app);
Florin Corascea194d2017-10-02 00:18:51 -0700295u32 application_session_table (application_t * app, u8 fib_proto);
296u32 application_local_session_table (application_t * app);
Florin Coras053a0e42018-11-13 15:52:38 -0800297const u8 *application_name_from_index (u32 app_or_wrk);
Florin Corascea194d2017-10-02 00:18:51 -0700298u8 application_has_local_scope (application_t * app);
299u8 application_has_global_scope (application_t * app);
Florin Coras7999e832017-10-31 01:51:04 -0700300void application_setup_proxy (application_t * app);
301void application_remove_proxy (application_t * app);
Nathan Skrzypczakb3ea73e2021-08-05 10:22:52 +0200302void application_namespace_cleanup (app_namespace_t *app_ns);
qinyangaf9b7152023-06-27 01:11:53 -0700303int application_original_dst_is_enabled (application_t *app);
Florin Coras7999e832017-10-31 01:51:04 -0700304
Florin Coras88001c62019-04-24 14:44:46 -0700305segment_manager_props_t *application_get_segment_manager_properties (u32
306 app_index);
Florin Corasab2f6db2018-08-31 14:31:41 -0700307
Florin Coras88001c62019-04-24 14:44:46 -0700308segment_manager_props_t
Florin Corasa332c462018-01-31 06:52:17 -0800309 * application_segment_manager_properties (application_t * app);
310
Florin Coras41d5f542021-01-15 13:49:33 -0800311svm_msg_q_t *application_rx_mq_get (application_t *app, u32 mq_index);
312u8 application_use_private_rx_mqs (void);
313fifo_segment_t *application_get_rx_mqs_segment (application_t *app);
314void application_enable_rx_mqs_nodes (u8 is_en);
315
Florin Corasab2f6db2018-08-31 14:31:41 -0700316/*
Florin Coras623eb562019-02-03 19:28:34 -0800317 * App worker
318 */
319
320app_worker_t *app_worker_alloc (application_t * app);
321int application_alloc_worker_and_init (application_t * app,
322 app_worker_t ** wrk);
323app_worker_t *app_worker_get (u32 wrk_index);
324app_worker_t *app_worker_get_if_valid (u32 wrk_index);
325application_t *app_worker_get_app (u32 wrk_index);
326int app_worker_own_session (app_worker_t * app_wrk, session_t * s);
327void app_worker_free (app_worker_t * app_wrk);
Florin Coras89a9f612021-05-11 11:55:07 -0700328int app_worker_connect_session (app_worker_t *app, session_endpoint_cfg_t *sep,
329 session_handle_t *rsh);
Filip Tehlar0028e6f2023-06-28 10:47:32 +0200330session_error_t app_worker_start_listen (app_worker_t *app_wrk,
331 app_listener_t *lstnr);
Florin Corasc9940fc2019-02-05 20:55:11 -0800332int app_worker_stop_listen (app_worker_t * app_wrk, app_listener_t * al);
Florin Corasa27a46e2019-02-18 13:02:28 -0800333int app_worker_init_accepted (session_t * s);
334int app_worker_accept_notify (app_worker_t * app_wrk, session_t * s);
335int app_worker_init_connected (app_worker_t * app_wrk, session_t * s);
336int app_worker_connect_notify (app_worker_t * app_wrk, session_t * s,
Florin Coras00e01d32019-10-21 16:07:46 -0700337 session_error_t err, u32 opaque);
Florin Corasea727642021-05-07 19:39:43 -0700338int app_worker_add_half_open (app_worker_t *app_wrk, session_handle_t sh);
Florin Coras2c876f92021-05-10 21:12:27 -0700339int app_worker_del_half_open (app_worker_t *app_wrk, session_t *s);
Florin Corasbf7ce2c2019-03-06 14:44:42 -0800340int app_worker_close_notify (app_worker_t * app_wrk, session_t * s);
Florin Coras692b9492019-07-12 15:01:53 -0700341int app_worker_transport_closed_notify (app_worker_t * app_wrk,
342 session_t * s);
Florin Coras69b68ef2019-04-02 11:38:51 -0700343int app_worker_reset_notify (app_worker_t * app_wrk, session_t * s);
Florin Coras70f26d52019-07-08 11:47:18 -0700344int app_worker_cleanup_notify (app_worker_t * app_wrk, session_t * s,
345 session_cleanup_ntf_t ntf);
Florin Coras49568af2019-07-31 16:46:24 -0700346int app_worker_migrate_notify (app_worker_t * app_wrk, session_t * s,
347 session_handle_t new_sh);
Florin Corasbf7ce2c2019-03-06 14:44:42 -0800348int app_worker_builtin_rx (app_worker_t * app_wrk, session_t * s);
Florin Coras0e573f52019-05-07 16:28:16 -0700349int app_worker_builtin_tx (app_worker_t * app_wrk, session_t * s);
Ryujiro Shibuyad8f48e22020-01-22 12:11:42 +0000350int app_worker_session_fifo_tuning (app_worker_t * app_wrk, session_t * s,
351 svm_fifo_t * f,
352 session_ft_action_t act, u32 len);
Florin Coras623eb562019-02-03 19:28:34 -0800353segment_manager_t *app_worker_get_listen_segment_manager (app_worker_t *,
354 session_t *);
355segment_manager_t *app_worker_get_connect_segment_manager (app_worker_t *);
Florin Coras2b81e3c2019-02-27 07:55:46 -0800356int app_worker_add_segment_notify (app_worker_t * app_wrk,
357 u64 segment_handle);
358int app_worker_del_segment_notify (app_worker_t * app_wrk,
359 u64 segment_handle);
Florin Coras623eb562019-02-03 19:28:34 -0800360u32 app_worker_n_listeners (app_worker_t * app);
361session_t *app_worker_first_listener (app_worker_t * app,
362 u8 fib_proto, u8 transport_proto);
Florin Coras20c24232021-11-22 21:19:01 -0800363void app_wrk_send_ctrl_evt_fd (app_worker_t *app_wrk, u8 evt_type, void *msg,
364 u32 msg_len, int fd);
365void app_wrk_send_ctrl_evt (app_worker_t *app_wrk, u8 evt_type, void *msg,
366 u32 msg_len);
Florin Coras623eb562019-02-03 19:28:34 -0800367int app_worker_send_event (app_worker_t * app, session_t * s, u8 evt);
368int app_worker_lock_and_send_event (app_worker_t * app, session_t * s,
369 u8 evt_type);
370session_t *app_worker_proxy_listener (app_worker_t * app, u8 fib_proto,
371 u8 transport_proto);
Florin Corasc8e812f2020-05-14 05:32:18 +0000372void app_worker_del_detached_sm (app_worker_t * app_wrk, u32 sm_index);
Florin Coras623eb562019-02-03 19:28:34 -0800373u8 *format_app_worker (u8 * s, va_list * args);
374u8 *format_app_worker_listener (u8 * s, va_list * args);
Nathan Skrzypczakde6caf42019-10-09 14:41:48 +0200375u8 *format_crypto_engine (u8 * s, va_list * args);
376u8 *format_crypto_context (u8 * s, va_list * args);
Florin Coras623eb562019-02-03 19:28:34 -0800377void app_worker_format_connects (app_worker_t * app_wrk, int verbose);
Filip Tehlar0028e6f2023-06-28 10:47:32 +0200378session_error_t vnet_app_worker_add_del (vnet_app_worker_add_del_args_t *a);
Florin Coras371ca502018-02-21 12:07:41 -0800379
Florin Coras371ca502018-02-21 12:07:41 -0800380uword unformat_application_proto (unformat_input_t * input, va_list * args);
Florin Corasf8f516a2018-02-08 15:10:09 -0800381
Nathan Skrzypczak79f89532019-09-13 11:08:13 +0200382app_cert_key_pair_t *app_cert_key_pair_get (u32 index);
383app_cert_key_pair_t *app_cert_key_pair_get_if_valid (u32 index);
384app_cert_key_pair_t *app_cert_key_pair_get_default ();
Florin Coras458089b2019-08-21 16:20:44 -0700385
386/* Needed while we support both bapi and mq ctrl messages */
387int mq_send_session_bound_cb (u32 app_wrk_index, u32 api_context,
388 session_handle_t handle, int rv);
389int mq_send_session_connected_cb (u32 app_wrk_index, u32 api_context,
Florin Coras00e01d32019-10-21 16:07:46 -0700390 session_t * s, session_error_t err);
Florin Coras458089b2019-08-21 16:20:44 -0700391void mq_send_unlisten_reply (app_worker_t * app_wrk, session_handle_t sh,
392 u32 context, int rv);
Florin Coras98078ab2021-08-12 18:12:09 -0700393void sapi_socket_close_w_handle (u32 api_handle);
Florin Coras458089b2019-08-21 16:20:44 -0700394
Florin Coras79ba25d2019-10-20 19:32:47 -0700395crypto_engine_type_t app_crypto_engine_type_add (void);
396u8 app_crypto_engine_n_types (void);
397
Dave Barach68b0fb02017-02-28 15:15:56 -0500398#endif /* SRC_VNET_SESSION_APPLICATION_H_ */
399
400/*
401 * fd.io coding-style-patch-verification: ON
402 *
403 * Local Variables:
404 * eval: (c-set-style "gnu")
405 * End:
406 */