blob: 1e3229171dadca5d3385e75f0c547bf232912e53 [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#ifndef __included_session_h__
16#define __included_session_h__
17
Florin Coras2062ec02019-07-15 13:15:18 -070018#include <vppinfra/llist.h>
Florin Coras288eaab2019-02-03 15:26:14 -080019#include <vnet/session/session_types.h>
Florin Coras04e53442017-07-16 17:12:15 -070020#include <vnet/session/session_lookup.h>
Florin Coras3e350af2017-03-30 02:54:28 -070021#include <vnet/session/session_debug.h>
Florin Coras288eaab2019-02-03 15:26:14 -080022#include <svm/message_queue.h>
Florin Coras31c99552019-03-01 13:00:58 -080023#include <svm/ssvm.h>
Dave Barach68b0fb02017-02-28 15:15:56 -050024
Florin Coras3e350af2017-03-30 02:54:28 -070025#define foreach_session_input_error \
Dave Barach68b0fb02017-02-28 15:15:56 -050026_(NO_SESSION, "No session drops") \
27_(NO_LISTENER, "No listener for dst port drops") \
28_(ENQUEUED, "Packets pushed into rx fifo") \
29_(NOT_READY, "Session not ready packets") \
30_(FIFO_FULL, "Packets dropped for lack of rx fifo space") \
31_(EVENT_FIFO_FULL, "Events not sent for lack of event fifo space") \
32_(API_QUEUE_FULL, "Sessions not created for lack of API queue space") \
33_(NEW_SEG_NO_SPACE, "Created segment, couldn't allocate a fifo pair") \
Florin Corasa332c462018-01-31 06:52:17 -080034_(NO_SPACE, "Couldn't allocate a fifo pair") \
35_(SEG_CREATE, "Couldn't create a new segment")
Dave Barach68b0fb02017-02-28 15:15:56 -050036
37typedef enum
38{
39#define _(sym,str) SESSION_ERROR_##sym,
40 foreach_session_input_error
41#undef _
42 SESSION_N_ERROR,
43} session_error_t;
44
Florin Coras8e43d042018-05-04 15:46:57 -070045typedef struct session_tx_context_
46{
47 CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
Florin Coras288eaab2019-02-03 15:26:14 -080048 session_t *s;
Florin Coras8e43d042018-05-04 15:46:57 -070049 transport_proto_vft_t *transport_vft;
50 transport_connection_t *tc;
Florin Coras8e43d042018-05-04 15:46:57 -070051 u32 max_dequeue;
52 u32 snd_space;
53 u32 left_to_snd;
54 u32 tx_offset;
55 u32 max_len_to_snd;
56 u16 deq_per_first_buf;
57 u16 deq_per_buf;
58 u16 snd_mss;
Florin Corasf08f26d2018-05-10 13:20:47 -070059 u16 n_segs_per_evt;
Florin Coras8e43d042018-05-04 15:46:57 -070060 u8 n_bufs_per_seg;
61 CLIB_CACHE_LINE_ALIGN_MARK (cacheline1);
62 session_dgram_hdr_t hdr;
63} session_tx_context_t;
64
Florin Coras2062ec02019-07-15 13:15:18 -070065typedef struct session_evt_elt
66{
67 clib_llist_anchor_t evt_list;
68 session_event_t evt;
69} session_evt_elt_t;
70
Florin Coras31c99552019-03-01 13:00:58 -080071typedef struct session_worker_
Dave Barach68b0fb02017-02-28 15:15:56 -050072{
Florin Coras5a7ca7b2018-10-30 12:01:48 -070073 CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
Dave Barach68b0fb02017-02-28 15:15:56 -050074
Florin Coras5a7ca7b2018-10-30 12:01:48 -070075 /** Worker session pool */
Florin Coras288eaab2019-02-03 15:26:14 -080076 session_t *sessions;
Florin Coras3cbc04b2017-10-02 00:18:51 -070077
Florin Coras5a7ca7b2018-10-30 12:01:48 -070078 /** vpp event message queue for worker */
79 svm_msg_q_t *vpp_event_queue;
Florin Coras8e43d042018-05-04 15:46:57 -070080
Florin Corasd67f1122018-05-21 17:47:40 -070081 /** Our approximation of a "complete" dispatch loop period */
Florin Coras5a7ca7b2018-10-30 12:01:48 -070082 f64 dispatch_period;
Florin Corasd67f1122018-05-21 17:47:40 -070083
84 /** vlib_time_now last time around the track */
Florin Coras5a7ca7b2018-10-30 12:01:48 -070085 f64 last_vlib_time;
Florin Corasd67f1122018-05-21 17:47:40 -070086
Florin Coras5a7ca7b2018-10-30 12:01:48 -070087 /** Per-proto vector of sessions to enqueue */
88 u32 *session_to_enqueue[TRANSPORT_N_PROTO];
89
90 /** Context for session tx */
91 session_tx_context_t ctx;
92
93 /** Vector of tx buffer free lists */
94 u32 *tx_buffers;
95
Florin Coras2062ec02019-07-15 13:15:18 -070096 /** Pool of session event list elements */
97 session_evt_elt_t *event_elts;
Florin Coras5a7ca7b2018-10-30 12:01:48 -070098
Florin Coras2062ec02019-07-15 13:15:18 -070099 /** Head of list of elements */
100 clib_llist_index_t new_head;
Florin Coras5a7ca7b2018-10-30 12:01:48 -0700101
Florin Coras2062ec02019-07-15 13:15:18 -0700102 /** Head of list of pending events */
103 clib_llist_index_t pending_head;
Florin Coras5a7ca7b2018-10-30 12:01:48 -0700104
Florin Coras2062ec02019-07-15 13:15:18 -0700105 /** Head of list of postponed events */
106 clib_llist_index_t postponed_head;
107
108 /** Head of list of disconnect events */
109 clib_llist_index_t disconnects_head;
Florin Coras5f56d732018-10-30 10:21:59 -0700110
Florin Coras5a7ca7b2018-10-30 12:01:48 -0700111 /** Peekers rw lock */
112 clib_rwlock_t peekers_rw_locks;
113
Florin Corasc44a5582018-11-01 16:30:54 -0700114 u32 last_tx_packets;
115
Florin Corascca96182019-07-19 07:34:13 -0700116#if SESSION_DEBUG
117 /** last event poll time by thread */
118 f64 last_event_poll;
119#endif
Florin Coras31c99552019-03-01 13:00:58 -0800120} session_worker_t;
Florin Coras5a7ca7b2018-10-30 12:01:48 -0700121
Florin Coras1bcad5c2019-01-09 20:04:38 -0800122typedef int (session_fifo_rx_fn) (vlib_main_t * vm,
123 vlib_node_runtime_t * node,
Florin Coras31c99552019-03-01 13:00:58 -0800124 session_worker_t * wrk,
Florin Coras2062ec02019-07-15 13:15:18 -0700125 session_evt_elt_t * e, int *n_tx_pkts);
Florin Coras1bcad5c2019-01-09 20:04:38 -0800126
127extern session_fifo_rx_fn session_tx_fifo_peek_and_snd;
128extern session_fifo_rx_fn session_tx_fifo_dequeue_and_snd;
129extern session_fifo_rx_fn session_tx_fifo_dequeue_internal;
130
131u8 session_node_lookup_fifo_event (svm_fifo_t * f, session_event_t * e);
132
Florin Coras31c99552019-03-01 13:00:58 -0800133typedef struct session_main_
Florin Coras5a7ca7b2018-10-30 12:01:48 -0700134{
135 /** Worker contexts */
Florin Coras31c99552019-03-01 13:00:58 -0800136 session_worker_t *wrk;
Dave Barach68b0fb02017-02-28 15:15:56 -0500137
Florin Corasb384b542018-01-15 01:08:33 -0800138 /** Event queues memfd segment initialized only if so configured */
139 ssvm_private_t evt_qs_segment;
140
Florin Coras93e65802017-11-29 00:07:11 -0500141 /** Unique segment name counter */
142 u32 unique_segment_name_counter;
143
144 /** Per transport rx function that can either dequeue or peek */
Florin Coras561af9b2017-12-09 10:19:43 -0800145 session_fifo_rx_fn **session_tx_fns;
146
147 /** Per session type output nodes. Could optimize to group nodes by
148 * fib but lookup would then require session type parsing in session node.
149 * Trade memory for speed, for now */
150 u32 *session_type_to_next;
Florin Coras93e65802017-11-29 00:07:11 -0500151
Florin Coras5a7ca7b2018-10-30 12:01:48 -0700152 /*
153 * Config parameters
154 */
155
Florin Coras93e65802017-11-29 00:07:11 -0500156 /** Session manager is enabled */
157 u8 is_enabled;
158
Dave Barach10d8cc62017-05-30 09:30:07 -0400159 /** vpp fifo event queue configured length */
160 u32 configured_event_queue_length;
161
Florin Corasb384b542018-01-15 01:08:33 -0800162 /** Session ssvm segment configs*/
163 uword session_baseva;
Florin Corasa332c462018-01-31 06:52:17 -0800164 uword session_va_space_size;
Florin Corasb4c14912019-02-09 13:51:25 -0800165 uword evt_qs_segment_size;
Florin Corasb384b542018-01-15 01:08:33 -0800166 u8 evt_qs_use_memfd_seg;
167
168 /** Session table size parameters */
Florin Coras66b11312017-07-31 17:18:03 -0700169 u32 configured_v4_session_table_buckets;
170 u32 configured_v4_session_table_memory;
171 u32 configured_v4_halfopen_table_buckets;
172 u32 configured_v4_halfopen_table_memory;
173 u32 configured_v6_session_table_buckets;
174 u32 configured_v6_session_table_memory;
175 u32 configured_v6_halfopen_table_buckets;
176 u32 configured_v6_halfopen_table_memory;
177
Florin Coras93e65802017-11-29 00:07:11 -0500178 /** Transport table (preallocation) size parameters */
179 u32 local_endpoints_table_memory;
180 u32 local_endpoints_table_buckets;
Florin Corase04c2992017-03-01 08:17:34 -0800181
Dave Barach2c25a622017-06-26 11:35:07 -0400182 /** Preallocate session config parameter */
183 u32 preallocated_sessions;
184
Florin Coras31c99552019-03-01 13:00:58 -0800185} session_main_t;
Dave Barach68b0fb02017-02-28 15:15:56 -0500186
Florin Coras31c99552019-03-01 13:00:58 -0800187extern session_main_t session_main;
Florin Corase04c2992017-03-01 08:17:34 -0800188extern vlib_node_registration_t session_queue_node;
Florin Corasfd542f12018-05-16 19:28:24 -0700189extern vlib_node_registration_t session_queue_process_node;
Florin Coras653e43f2019-03-04 10:56:23 -0800190extern vlib_node_registration_t session_queue_pre_input_node;
Florin Corasfd542f12018-05-16 19:28:24 -0700191
192#define SESSION_Q_PROCESS_FLUSH_FRAMES 1
193#define SESSION_Q_PROCESS_STOP 2
Dave Barach68b0fb02017-02-28 15:15:56 -0500194
Florin Coras2062ec02019-07-15 13:15:18 -0700195static inline session_evt_elt_t *
196session_evt_elt_alloc (session_worker_t * wrk)
197{
198 session_evt_elt_t *elt;
199 pool_get (wrk->event_elts, elt);
200 return elt;
201}
202
203static inline void
204session_evt_elt_free (session_worker_t * wrk, session_evt_elt_t * elt)
205{
206 pool_put (wrk->event_elts, elt);
207}
208
209static inline session_evt_elt_t *
210session_evt_pending_head (session_worker_t * wrk)
211{
212 return pool_elt_at_index (wrk->event_elts, wrk->pending_head);
213}
214
215static inline session_evt_elt_t *
216session_evt_postponed_head (session_worker_t * wrk)
217{
218 return pool_elt_at_index (wrk->event_elts, wrk->postponed_head);
219}
220
221static inline session_evt_elt_t *
222session_evt_pending_disconnects_head (session_worker_t * wrk)
223{
224 return pool_elt_at_index (wrk->event_elts, wrk->disconnects_head);
225}
226
227static inline void
228session_evt_add_pending (session_worker_t * wrk, session_evt_elt_t * elt)
229{
230 clib_llist_add_tail (wrk->event_elts, evt_list, elt,
231 session_evt_pending_head (wrk));
232}
233
234static inline void
235session_evt_add_postponed (session_worker_t * wrk, session_evt_elt_t * elt)
236{
237 clib_llist_add_tail (wrk->event_elts, evt_list, elt,
238 session_evt_postponed_head (wrk));
239}
240
241static inline void
242session_evt_add_pending_disconnects (session_worker_t * wrk,
243 session_evt_elt_t * elt)
244{
245 clib_llist_add_tail (wrk->event_elts, evt_list, elt,
246 session_evt_pending_disconnects_head (wrk));
247}
248
Dave Barach2c25a622017-06-26 11:35:07 -0400249always_inline u8
Florin Coras31c99552019-03-01 13:00:58 -0800250session_is_valid (u32 si, u8 thread_index)
Dave Barach2c25a622017-06-26 11:35:07 -0400251{
Florin Coras288eaab2019-02-03 15:26:14 -0800252 session_t *s;
Florin Coras31c99552019-03-01 13:00:58 -0800253 s = pool_elt_at_index (session_main.wrk[thread_index].sessions, si);
Florin Coras653e43f2019-03-04 10:56:23 -0800254 if (s->session_state == SESSION_STATE_CLOSED)
255 return 1;
256
Florin Coras31c99552019-03-01 13:00:58 -0800257 if (s->thread_index != thread_index || s->session_index != si)
Dave Barach2c25a622017-06-26 11:35:07 -0400258 return 0;
259 return 1;
260}
261
Florin Coras288eaab2019-02-03 15:26:14 -0800262session_t *session_alloc (u32 thread_index);
Florin Coras288eaab2019-02-03 15:26:14 -0800263void session_free (session_t * s);
264void session_free_w_fifos (session_t * s);
Florin Coras3cbc04b2017-10-02 00:18:51 -0700265
Florin Coras288eaab2019-02-03 15:26:14 -0800266always_inline session_t *
Florin Corascea194d2017-10-02 00:18:51 -0700267session_get (u32 si, u32 thread_index)
Dave Barach68b0fb02017-02-28 15:15:56 -0500268{
Florin Coras31c99552019-03-01 13:00:58 -0800269 ASSERT (session_is_valid (si, thread_index));
270 return pool_elt_at_index (session_main.wrk[thread_index].sessions, si);
Dave Barach68b0fb02017-02-28 15:15:56 -0500271}
272
Florin Coras288eaab2019-02-03 15:26:14 -0800273always_inline session_t *
Florin Coras3cbc04b2017-10-02 00:18:51 -0700274session_get_if_valid (u64 si, u32 thread_index)
Dave Barach68b0fb02017-02-28 15:15:56 -0500275{
Florin Coras31c99552019-03-01 13:00:58 -0800276 if (thread_index >= vec_len (session_main.wrk))
Dave Barach68b0fb02017-02-28 15:15:56 -0500277 return 0;
278
Florin Coras31c99552019-03-01 13:00:58 -0800279 if (pool_is_free_index (session_main.wrk[thread_index].sessions, si))
Dave Barach68b0fb02017-02-28 15:15:56 -0500280 return 0;
281
Florin Coras31c99552019-03-01 13:00:58 -0800282 ASSERT (session_is_valid (si, thread_index));
283 return pool_elt_at_index (session_main.wrk[thread_index].sessions, si);
Dave Barach68b0fb02017-02-28 15:15:56 -0500284}
285
Florin Coras288eaab2019-02-03 15:26:14 -0800286always_inline session_t *
Florin Corasf8f516a2018-02-08 15:10:09 -0800287session_get_from_handle (session_handle_t handle)
Florin Coras6cf30ad2017-04-04 23:08:23 -0700288{
Florin Coras31c99552019-03-01 13:00:58 -0800289 session_main_t *smm = &session_main;
Florin Corasf8f516a2018-02-08 15:10:09 -0800290 u32 session_index, thread_index;
291 session_parse_handle (handle, &session_index, &thread_index);
Florin Coras5a7ca7b2018-10-30 12:01:48 -0700292 return pool_elt_at_index (smm->wrk[thread_index].sessions, session_index);
Florin Corasf8f516a2018-02-08 15:10:09 -0800293}
294
Florin Coras288eaab2019-02-03 15:26:14 -0800295always_inline session_t *
Florin Corasf8f516a2018-02-08 15:10:09 -0800296session_get_from_handle_if_valid (session_handle_t handle)
297{
298 u32 session_index, thread_index;
299 session_parse_handle (handle, &session_index, &thread_index);
300 return session_get_if_valid (session_index, thread_index);
301}
302
Florin Coras31c99552019-03-01 13:00:58 -0800303u64 session_segment_handle (session_t * s);
Florin Corasfa76a762018-11-29 12:40:10 -0800304
Florin Coras3cbc04b2017-10-02 00:18:51 -0700305/**
306 * Acquires a lock that blocks a session pool from expanding.
307 *
308 * This is typically used for safely peeking into other threads'
309 * pools in order to clone elements. Lock should be dropped as soon
310 * as possible by calling @ref session_pool_remove_peeker.
311 *
312 * NOTE: Avoid using pool_elt_at_index while the lock is held because
313 * it may lead to free elt bitmap expansion/contraction!
314 */
315always_inline void
316session_pool_add_peeker (u32 thread_index)
317{
Florin Coras31c99552019-03-01 13:00:58 -0800318 session_worker_t *wrk = &session_main.wrk[thread_index];
Florin Coras3cbc04b2017-10-02 00:18:51 -0700319 if (thread_index == vlib_get_thread_index ())
320 return;
Florin Coras5a7ca7b2018-10-30 12:01:48 -0700321 clib_rwlock_reader_lock (&wrk->peekers_rw_locks);
Florin Coras3cbc04b2017-10-02 00:18:51 -0700322}
323
324always_inline void
325session_pool_remove_peeker (u32 thread_index)
326{
Florin Coras31c99552019-03-01 13:00:58 -0800327 session_worker_t *wrk = &session_main.wrk[thread_index];
Florin Coras3cbc04b2017-10-02 00:18:51 -0700328 if (thread_index == vlib_get_thread_index ())
329 return;
Florin Coras5a7ca7b2018-10-30 12:01:48 -0700330 clib_rwlock_reader_unlock (&wrk->peekers_rw_locks);
Florin Coras3cbc04b2017-10-02 00:18:51 -0700331}
332
333/**
334 * Get session from handle and 'lock' pool resize if not in same thread
335 *
336 * Caller should drop the peek 'lock' as soon as possible.
337 */
Florin Coras288eaab2019-02-03 15:26:14 -0800338always_inline session_t *
Florin Coras3cbc04b2017-10-02 00:18:51 -0700339session_get_from_handle_safe (u64 handle)
340{
Florin Coras3cbc04b2017-10-02 00:18:51 -0700341 u32 thread_index = session_thread_from_handle (handle);
Florin Coras31c99552019-03-01 13:00:58 -0800342 session_worker_t *wrk = &session_main.wrk[thread_index];
Florin Coras5a7ca7b2018-10-30 12:01:48 -0700343
Florin Coras3cbc04b2017-10-02 00:18:51 -0700344 if (thread_index == vlib_get_thread_index ())
345 {
Florin Coras5a7ca7b2018-10-30 12:01:48 -0700346 return pool_elt_at_index (wrk->sessions,
Florin Coras3cbc04b2017-10-02 00:18:51 -0700347 session_index_from_handle (handle));
348 }
349 else
350 {
351 session_pool_add_peeker (thread_index);
352 /* Don't use pool_elt_at index. See @ref session_pool_add_peeker */
Florin Coras5a7ca7b2018-10-30 12:01:48 -0700353 return wrk->sessions + session_index_from_handle (handle);
Florin Coras3cbc04b2017-10-02 00:18:51 -0700354 }
355}
356
Dave Barach68b0fb02017-02-28 15:15:56 -0500357always_inline u32
Florin Coras1ee78302019-02-05 15:51:15 -0800358session_get_index (session_t * s)
359{
Florin Coras31c99552019-03-01 13:00:58 -0800360 return (s - session_main.wrk[s->thread_index].sessions);
Florin Coras1ee78302019-02-05 15:51:15 -0800361}
362
363always_inline session_t *
364session_clone_safe (u32 session_index, u32 thread_index)
365{
366 session_t *old_s, *new_s;
367 u32 current_thread_index = vlib_get_thread_index ();
368
369 /* If during the memcpy pool is reallocated AND the memory allocator
370 * decides to give the old chunk of memory to somebody in a hurry to
371 * scribble something on it, we have a problem. So add this thread as
372 * a session pool peeker.
373 */
374 session_pool_add_peeker (thread_index);
375 new_s = session_alloc (current_thread_index);
Florin Coras31c99552019-03-01 13:00:58 -0800376 old_s = session_main.wrk[thread_index].sessions + session_index;
Florin Coras1ee78302019-02-05 15:51:15 -0800377 clib_memcpy_fast (new_s, old_s, sizeof (*new_s));
378 session_pool_remove_peeker (thread_index);
379 new_s->thread_index = current_thread_index;
380 new_s->session_index = session_get_index (new_s);
381 return new_s;
382}
383
384int session_open (u32 app_index, session_endpoint_t * tep, u32 opaque);
385int session_listen (session_t * s, session_endpoint_cfg_t * sep);
386int session_stop_listen (session_t * s);
387void session_close (session_t * s);
388void session_transport_close (session_t * s);
389void session_transport_cleanup (session_t * s);
390int session_send_io_evt_to_thread (svm_fifo_t * f,
391 session_evt_type_t evt_type);
Florin Coras653e43f2019-03-04 10:56:23 -0800392int session_enqueue_notify (session_t * s);
Florin Coras1ee78302019-02-05 15:51:15 -0800393int session_dequeue_notify (session_t * s);
394int session_send_io_evt_to_thread_custom (void *data, u32 thread_index,
395 session_evt_type_t evt_type);
396void session_send_rpc_evt_to_thread (u32 thread_index, void *fp,
397 void *rpc_args);
Nathan Skrzypczak60f3e652019-03-19 13:57:31 +0100398void session_send_rpc_evt_to_thread_force (u32 thread_index, void *fp,
399 void *rpc_args);
Florin Coras1ee78302019-02-05 15:51:15 -0800400transport_connection_t *session_get_transport (session_t * s);
Florin Coras09d18c22019-04-24 11:10:02 -0700401void session_get_endpoint (session_t * s, transport_endpoint_t * tep,
402 u8 is_lcl);
Florin Coras1ee78302019-02-05 15:51:15 -0800403
Florin Coras31c99552019-03-01 13:00:58 -0800404u8 *format_session (u8 * s, va_list * args);
405uword unformat_session (unformat_input_t * input, va_list * args);
Florin Coras1ee78302019-02-05 15:51:15 -0800406uword unformat_transport_connection (unformat_input_t * input,
407 va_list * args);
408
409/*
410 * Interface to transport protos
411 */
412
413int session_enqueue_stream_connection (transport_connection_t * tc,
414 vlib_buffer_t * b, u32 offset,
415 u8 queue_event, u8 is_in_order);
416int session_enqueue_dgram_connection (session_t * s,
417 session_dgram_hdr_t * hdr,
418 vlib_buffer_t * b, u8 proto,
419 u8 queue_event);
Florin Coras1ee78302019-02-05 15:51:15 -0800420int session_stream_connect_notify (transport_connection_t * tc, u8 is_fail);
421int session_dgram_connect_notify (transport_connection_t * tc,
422 u32 old_thread_index,
423 session_t ** new_session);
Florin Corasa27a46e2019-02-18 13:02:28 -0800424int session_stream_accept_notify (transport_connection_t * tc);
Florin Coras1ee78302019-02-05 15:51:15 -0800425void session_transport_closing_notify (transport_connection_t * tc);
426void session_transport_delete_notify (transport_connection_t * tc);
427void session_transport_closed_notify (transport_connection_t * tc);
428void session_transport_reset_notify (transport_connection_t * tc);
Florin Corasc9940fc2019-02-05 20:55:11 -0800429int session_stream_accept (transport_connection_t * tc, u32 listener_index,
Nathan Skrzypczak2f0f96b2019-06-13 10:14:28 +0200430 u32 thread_index, u8 notify);
Florin Coras1ee78302019-02-05 15:51:15 -0800431void session_register_transport (transport_proto_t transport_proto,
432 const transport_proto_vft_t * vft, u8 is_ip4,
433 u32 output_node);
Florin Coras31c99552019-03-01 13:00:58 -0800434int session_tx_fifo_peek_bytes (transport_connection_t * tc, u8 * buffer,
435 u32 offset, u32 max_bytes);
436u32 session_tx_fifo_dequeue_drop (transport_connection_t * tc, u32 max_bytes);
Florin Coras1ee78302019-02-05 15:51:15 -0800437
438always_inline u32
Florin Corasd2aab832018-05-22 11:39:59 -0700439transport_max_rx_enqueue (transport_connection_t * tc)
Dave Barach68b0fb02017-02-28 15:15:56 -0500440{
Florin Coras288eaab2019-02-03 15:26:14 -0800441 session_t *s = session_get (tc->s_index, tc->thread_index);
Sirshak Das28aa5392019-02-05 01:33:33 -0600442 return svm_fifo_max_enqueue_prod (s->rx_fifo);
Dave Barach68b0fb02017-02-28 15:15:56 -0500443}
444
Florin Corase04c2992017-03-01 08:17:34 -0800445always_inline u32
Florin Coras42ceddb2018-12-12 10:56:01 -0800446transport_max_tx_dequeue (transport_connection_t * tc)
447{
Florin Coras288eaab2019-02-03 15:26:14 -0800448 session_t *s = session_get (tc->s_index, tc->thread_index);
Sirshak Das28aa5392019-02-05 01:33:33 -0600449 return svm_fifo_max_dequeue_cons (s->tx_fifo);
Florin Coras42ceddb2018-12-12 10:56:01 -0800450}
451
452always_inline u32
Florin Corasf65074e2019-03-31 17:17:11 -0700453transport_max_rx_dequeue (transport_connection_t * tc)
454{
455 session_t *s = session_get (tc->s_index, tc->thread_index);
456 return svm_fifo_max_dequeue (s->rx_fifo);
457}
458
459always_inline u32
Florin Corasd2aab832018-05-22 11:39:59 -0700460transport_rx_fifo_size (transport_connection_t * tc)
Florin Corase04c2992017-03-01 08:17:34 -0800461{
Florin Coras288eaab2019-02-03 15:26:14 -0800462 session_t *s = session_get (tc->s_index, tc->thread_index);
463 return s->rx_fifo->nitems;
Florin Corase04c2992017-03-01 08:17:34 -0800464}
465
Florin Coras3cbc04b2017-10-02 00:18:51 -0700466always_inline u32
Florin Corasd2aab832018-05-22 11:39:59 -0700467transport_tx_fifo_size (transport_connection_t * tc)
468{
Florin Coras288eaab2019-02-03 15:26:14 -0800469 session_t *s = session_get (tc->s_index, tc->thread_index);
470 return s->tx_fifo->nitems;
Florin Corasd2aab832018-05-22 11:39:59 -0700471}
472
Florin Coras7ac053b2018-11-05 15:57:21 -0800473always_inline u8
474transport_rx_fifo_has_ooo_data (transport_connection_t * tc)
475{
Florin Coras288eaab2019-02-03 15:26:14 -0800476 session_t *s = session_get (tc->c_index, tc->thread_index);
477 return svm_fifo_has_ooo_data (s->rx_fifo);
Florin Coras7ac053b2018-11-05 15:57:21 -0800478}
479
Florin Corasd67f1122018-05-21 17:47:40 -0700480always_inline f64
481transport_dispatch_period (u32 thread_index)
482{
Florin Coras31c99552019-03-01 13:00:58 -0800483 return session_main.wrk[thread_index].dispatch_period;
Florin Corasd67f1122018-05-21 17:47:40 -0700484}
485
486always_inline f64
487transport_time_now (u32 thread_index)
488{
Florin Coras31c99552019-03-01 13:00:58 -0800489 return session_main.wrk[thread_index].last_vlib_time;
Florin Corasd67f1122018-05-21 17:47:40 -0700490}
491
Florin Coras3ec66b02018-08-23 16:27:05 -0700492always_inline void
493transport_add_tx_event (transport_connection_t * tc)
494{
Florin Coras288eaab2019-02-03 15:26:14 -0800495 session_t *s = session_get (tc->s_index, tc->thread_index);
496 if (svm_fifo_has_event (s->tx_fifo))
Florin Coras3ec66b02018-08-23 16:27:05 -0700497 return;
Florin Corasf6c43132019-03-01 12:41:21 -0800498 session_send_io_evt_to_thread (s->tx_fifo, SESSION_IO_EVT_TX);
Florin Coras3ec66b02018-08-23 16:27:05 -0700499}
500
Florin Coras1ee78302019-02-05 15:51:15 -0800501/*
502 * Listen sessions
503 */
Florin Coras6cf30ad2017-04-04 23:08:23 -0700504
505always_inline u64
Florin Coras288eaab2019-02-03 15:26:14 -0800506listen_session_get_handle (session_t * s)
Florin Coras6cf30ad2017-04-04 23:08:23 -0700507{
Aloys Augustincdb71702019-04-08 17:54:39 +0200508 ASSERT (s->session_state == SESSION_STATE_LISTENING ||
509 session_get_transport_proto (s) == TRANSPORT_PROTO_QUIC);
Florin Coras5c9083d2018-04-13 06:39:07 -0700510 return session_handle (s);
Florin Coras6cf30ad2017-04-04 23:08:23 -0700511}
512
Florin Coras288eaab2019-02-03 15:26:14 -0800513always_inline session_t *
Florin Corasf8f516a2018-02-08 15:10:09 -0800514listen_session_get_from_handle (session_handle_t handle)
Florin Coras6cf30ad2017-04-04 23:08:23 -0700515{
Florin Coras5c9083d2018-04-13 06:39:07 -0700516 return session_get_from_handle (handle);
Florin Coras6cf30ad2017-04-04 23:08:23 -0700517}
518
Florin Coras371ca502018-02-21 12:07:41 -0800519always_inline void
Florin Coras5c9083d2018-04-13 06:39:07 -0700520listen_session_parse_handle (session_handle_t handle, u32 * index,
521 u32 * thread_index)
Florin Coras371ca502018-02-21 12:07:41 -0800522{
Florin Coras5c9083d2018-04-13 06:39:07 -0700523 session_parse_handle (handle, index, thread_index);
Florin Coras371ca502018-02-21 12:07:41 -0800524}
525
Florin Coras288eaab2019-02-03 15:26:14 -0800526always_inline session_t *
Florin Corasba7d8f52019-02-22 13:11:38 -0800527listen_session_alloc (u8 thread_index, session_type_t type)
Florin Coras6cf30ad2017-04-04 23:08:23 -0700528{
Florin Coras288eaab2019-02-03 15:26:14 -0800529 session_t *s;
Florin Coras5c9083d2018-04-13 06:39:07 -0700530 s = session_alloc (thread_index);
Florin Coras6cf30ad2017-04-04 23:08:23 -0700531 s->session_type = type;
532 s->session_state = SESSION_STATE_LISTENING;
Florin Coras6cf30ad2017-04-04 23:08:23 -0700533 return s;
534}
535
Florin Coras288eaab2019-02-03 15:26:14 -0800536always_inline session_t *
Florin Corasba7d8f52019-02-22 13:11:38 -0800537listen_session_get (u32 ls_index)
Florin Coras6cf30ad2017-04-04 23:08:23 -0700538{
Florin Corasba7d8f52019-02-22 13:11:38 -0800539 return session_get (ls_index, 0);
Florin Coras6cf30ad2017-04-04 23:08:23 -0700540}
541
542always_inline void
Florin Corasba7d8f52019-02-22 13:11:38 -0800543listen_session_free (session_t * s)
Florin Coras6cf30ad2017-04-04 23:08:23 -0700544{
Florin Coras5c9083d2018-04-13 06:39:07 -0700545 session_free (s);
Florin Coras6cf30ad2017-04-04 23:08:23 -0700546}
547
Florin Coras288eaab2019-02-03 15:26:14 -0800548transport_connection_t *listen_session_get_transport (session_t * s);
Florin Coras3cbc04b2017-10-02 00:18:51 -0700549
Florin Coras1ee78302019-02-05 15:51:15 -0800550/*
Florin Coras31c99552019-03-01 13:00:58 -0800551 * Session layer functions
Florin Coras1ee78302019-02-05 15:51:15 -0800552 */
553
Florin Coras31c99552019-03-01 13:00:58 -0800554always_inline session_main_t *
555vnet_get_session_main ()
Florin Coras1ee78302019-02-05 15:51:15 -0800556{
Florin Coras31c99552019-03-01 13:00:58 -0800557 return &session_main;
Florin Coras1ee78302019-02-05 15:51:15 -0800558}
559
Florin Coras31c99552019-03-01 13:00:58 -0800560always_inline session_worker_t *
561session_main_get_worker (u32 thread_index)
Florin Coras1ee78302019-02-05 15:51:15 -0800562{
Florin Coras31c99552019-03-01 13:00:58 -0800563 return &session_main.wrk[thread_index];
Florin Coras1ee78302019-02-05 15:51:15 -0800564}
565
566always_inline svm_msg_q_t *
Florin Coras31c99552019-03-01 13:00:58 -0800567session_main_get_vpp_event_queue (u32 thread_index)
Florin Coras1ee78302019-02-05 15:51:15 -0800568{
Florin Coras31c99552019-03-01 13:00:58 -0800569 return session_main.wrk[thread_index].vpp_event_queue;
Florin Coras1ee78302019-02-05 15:51:15 -0800570}
Florin Corasfd542f12018-05-16 19:28:24 -0700571
Florin Coras6cf30ad2017-04-04 23:08:23 -0700572always_inline u8
Florin Coras31c99552019-03-01 13:00:58 -0800573session_main_is_enabled ()
Florin Coras6cf30ad2017-04-04 23:08:23 -0700574{
Florin Coras31c99552019-03-01 13:00:58 -0800575 return session_main.is_enabled == 1;
Florin Coras6cf30ad2017-04-04 23:08:23 -0700576}
577
Florin Corascea194d2017-10-02 00:18:51 -0700578#define session_cli_return_if_not_enabled() \
579do { \
Florin Coras31c99552019-03-01 13:00:58 -0800580 if (!session_main.is_enabled) \
Florin Corascea194d2017-10-02 00:18:51 -0700581 return clib_error_return(0, "session layer is not enabled"); \
582} while (0)
583
Florin Coras31c99552019-03-01 13:00:58 -0800584int session_main_flush_enqueue_events (u8 proto, u32 thread_index);
585int session_main_flush_all_enqueue_events (u8 transport_proto);
Florin Coras1ee78302019-02-05 15:51:15 -0800586void session_flush_frames_main_thread (vlib_main_t * vm);
Florin Coras31c99552019-03-01 13:00:58 -0800587ssvm_private_t *session_main_get_evt_q_segment (void);
Dave Barach2a863912017-11-28 10:11:42 -0500588void session_node_enable_disable (u8 is_en);
Florin Coras1ee78302019-02-05 15:51:15 -0800589clib_error_t *vnet_session_enable_disable (vlib_main_t * vm, u8 is_en);
Dave Barach2a863912017-11-28 10:11:42 -0500590
Dave Barach68b0fb02017-02-28 15:15:56 -0500591#endif /* __included_session_h__ */
592
593/*
594 * fd.io coding-style-patch-verification: ON
595 *
596 * Local Variables:
597 * eval: (c-set-style "gnu")
598 * End:
599 */