transport: cleanup
[vpp.git] / src / vnet / session / session_types.h
1 /*
2  * Copyright (c) 2017-2019 Cisco and/or its affiliates.
3  * 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_SESSION_TYPES_H_
17 #define SRC_VNET_SESSION_SESSION_TYPES_H_
18
19 #include <svm/svm_fifo.h>
20 #include <vnet/session/transport_types.h>
21
22 #define SESSION_LOCAL_HANDLE_PREFIX 0x7FFFFFFF
23
24 #define foreach_session_endpoint_fields                         \
25   foreach_transport_endpoint_cfg_fields                         \
26   _(u8, transport_proto)                                        \
27
28 typedef struct _session_endpoint
29 {
30 #define _(type, name) type name;
31   foreach_session_endpoint_fields
32 #undef _
33 } session_endpoint_t;
34
35 typedef struct _session_endpoint_cfg
36 {
37 #define _(type, name) type name;
38   foreach_session_endpoint_fields
39 #undef _
40   u32 app_wrk_index;
41   u32 opaque;
42   u8 *hostname;
43 } session_endpoint_cfg_t;
44
45 #define SESSION_IP46_ZERO                       \
46 {                                               \
47     .ip6 = {                                    \
48         { 0, 0, },                              \
49     },                                          \
50 }
51
52 #define TRANSPORT_ENDPOINT_NULL                 \
53 {                                               \
54   .sw_if_index = ENDPOINT_INVALID_INDEX,        \
55   .ip = SESSION_IP46_ZERO,                      \
56   .fib_index = ENDPOINT_INVALID_INDEX,          \
57   .is_ip4 = 0,                                  \
58   .port = 0,                                    \
59 }
60 #define SESSION_ENDPOINT_NULL                   \
61 {                                               \
62   .sw_if_index = ENDPOINT_INVALID_INDEX,        \
63   .ip = SESSION_IP46_ZERO,                      \
64   .fib_index = ENDPOINT_INVALID_INDEX,          \
65   .is_ip4 = 0,                                  \
66   .port = 0,                                    \
67   .peer = TRANSPORT_ENDPOINT_NULL,              \
68   .transport_proto = 0,                         \
69 }
70 #define SESSION_ENDPOINT_CFG_NULL               \
71 {                                               \
72   .sw_if_index = ENDPOINT_INVALID_INDEX,        \
73   .ip = SESSION_IP46_ZERO,                      \
74   .fib_index = ENDPOINT_INVALID_INDEX,          \
75   .is_ip4 = 0,                                  \
76   .port = 0,                                    \
77   .peer = TRANSPORT_ENDPOINT_NULL,              \
78   .transport_proto = 0,                         \
79   .app_wrk_index = ENDPOINT_INVALID_INDEX,      \
80   .opaque = ENDPOINT_INVALID_INDEX,             \
81   .hostname = 0,                                \
82 }
83
84 #define session_endpoint_to_transport(_sep) ((transport_endpoint_t *)_sep)
85 #define session_endpoint_to_transport_cfg(_sep)         \
86   ((transport_endpoint_cfg_t *)_sep)
87
88 always_inline u8
89 session_endpoint_fib_proto (session_endpoint_t * sep)
90 {
91   return sep->is_ip4 ? FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6;
92 }
93
94 typedef u8 session_type_t;
95 typedef u64 session_handle_t;
96
97 /*
98  * Application session state
99  */
100 typedef enum
101 {
102   SESSION_STATE_LISTENING,
103   SESSION_STATE_CONNECTING,
104   SESSION_STATE_ACCEPTING,
105   SESSION_STATE_READY,
106   SESSION_STATE_OPENED,
107   SESSION_STATE_TRANSPORT_CLOSING,
108   SESSION_STATE_CLOSING,
109   SESSION_STATE_CLOSED_WAITING,
110   SESSION_STATE_TRANSPORT_CLOSED,
111   SESSION_STATE_CLOSED,
112   SESSION_STATE_N_STATES,
113 } session_state_t;
114
115 typedef struct generic_session_
116 {
117   svm_fifo_t *rx_fifo;          /**< rx fifo */
118   svm_fifo_t *tx_fifo;          /**< tx fifo */
119   session_type_t session_type;  /**< session type */
120   volatile u8 session_state;    /**< session state */
121   u32 session_index;            /**< index in owning pool */
122 } generic_session_t;
123
124 typedef struct session_
125 {
126   /** fifo pointers. Once allocated, these do not move */
127   svm_fifo_t *rx_fifo;
128   svm_fifo_t *tx_fifo;
129
130   /** Type */
131   session_type_t session_type;
132
133   /** State */
134   volatile u8 session_state;
135
136   /** Session index in per_thread pool */
137   u32 session_index;
138
139   /** App worker pool index */
140   u32 app_wrk_index;
141
142   u8 thread_index;
143
144   /** To avoid n**2 "one event per frame" check */
145   u64 enqueue_epoch;
146
147   /** svm segment index where fifos were allocated */
148   u32 svm_segment_index;
149
150   /** Transport specific */
151   u32 connection_index;
152
153   union
154   {
155     /** Parent listener session if the result of an accept */
156     u32 listener_index;
157
158     /** Application index if a listener */
159     u32 app_index;
160   };
161
162   union
163   {
164     /** Transport app index for apps acting as transports */
165     u32 t_app_index;
166
167     /** Index in listener app's listener db */
168     u32 listener_db_index;
169
170     /** Opaque, for general use */
171     u32 opaque;
172   };
173
174     CLIB_CACHE_LINE_ALIGN_MARK (pad);
175 } session_t;
176
177 always_inline session_type_t
178 session_type_from_proto_and_ip (transport_proto_t proto, u8 is_ip4)
179 {
180   return (proto << 1 | is_ip4);
181 }
182
183 always_inline transport_proto_t
184 session_type_transport_proto (session_type_t st)
185 {
186   return (st >> 1);
187 }
188
189 always_inline u8
190 session_type_is_ip4 (session_type_t st)
191 {
192   return (st & 1);
193 }
194
195 always_inline transport_proto_t
196 session_get_transport_proto (session_t * s)
197 {
198   return (s->session_type >> 1);
199 }
200
201 always_inline fib_protocol_t
202 session_get_fib_proto (session_t * s)
203 {
204   u8 is_ip4 = s->session_type & 1;
205   return (is_ip4 ? FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6);
206 }
207
208 always_inline u8
209 session_has_transport (session_t * s)
210 {
211   return (session_get_transport_proto (s) != TRANSPORT_PROTO_NONE);
212 }
213
214 static inline transport_service_type_t
215 session_transport_service_type (session_t * s)
216 {
217   transport_proto_t tp;
218   tp = session_get_transport_proto (s);
219   return transport_protocol_service_type (tp);
220 }
221
222 static inline transport_tx_fn_type_t
223 session_transport_tx_fn_type (session_t * s)
224 {
225   transport_proto_t tp;
226   tp = session_get_transport_proto (s);
227   return transport_protocol_tx_fn_type (tp);
228 }
229
230 static inline u8
231 session_tx_is_dgram (session_t * s)
232 {
233   return (session_transport_tx_fn_type (s) == TRANSPORT_TX_DGRAM);
234 }
235
236 always_inline session_handle_t
237 session_handle (session_t * s)
238 {
239   return ((u64) s->thread_index << 32) | (u64) s->session_index;
240 }
241
242 always_inline u32
243 session_index_from_handle (session_handle_t handle)
244 {
245   return handle & 0xFFFFFFFF;
246 }
247
248 always_inline u32
249 session_thread_from_handle (session_handle_t handle)
250 {
251   return handle >> 32;
252 }
253
254 always_inline void
255 session_parse_handle (session_handle_t handle, u32 * index,
256                       u32 * thread_index)
257 {
258   *index = session_index_from_handle (handle);
259   *thread_index = session_thread_from_handle (handle);
260 }
261
262 always_inline u8
263 session_handle_is_local (session_handle_t handle)
264 {
265   if ((handle >> 32) == SESSION_LOCAL_HANDLE_PREFIX)
266     return 1;
267   return 0;
268 }
269
270 typedef struct local_session_
271 {
272   /** fifo pointers. Once allocated, these do not move */
273   svm_fifo_t *rx_fifo;
274   svm_fifo_t *tx_fifo;
275
276   /** Type */
277   session_type_t session_type;
278
279   /** State */
280   volatile u8 session_state;
281
282   /** Session index */
283   u32 session_index;
284
285   /** Server index */
286   u32 app_wrk_index;
287
288   /** Port for connection. Overlaps thread_index/enqueue_epoch */
289   u16 port;
290
291   /** Partly overlaps enqueue_epoch */
292   u8 pad_epoch[7];
293
294   /** Segment index where fifos were allocated */
295   u32 svm_segment_index;
296
297   /** Transport listener index. Overlaps connection index */
298   u32 transport_listener_index;
299
300   union
301   {
302     u32 listener_index;
303     u32 app_index;
304   };
305
306   u32 listener_db_index;
307
308   /** Has transport embedded when listener not purely local */
309   session_type_t listener_session_type;
310
311   /**
312    * Client data
313    */
314   u32 client_wrk_index;
315   u32 client_opaque;
316
317   u64 server_evt_q;
318   u64 client_evt_q;
319
320     CLIB_CACHE_LINE_ALIGN_MARK (pad);
321 } local_session_t;
322
323 always_inline u32
324 local_session_id (local_session_t * ls)
325 {
326   ASSERT (ls->session_index < (2 << 16));
327   u32 app_or_wrk_index;
328
329   if (ls->session_state == SESSION_STATE_LISTENING)
330     {
331       ASSERT (ls->app_index < (2 << 16));
332       app_or_wrk_index = ls->app_index;
333     }
334   else
335     {
336       ASSERT (ls->app_wrk_index < (2 << 16));
337       app_or_wrk_index = ls->app_wrk_index;
338     }
339
340   return ((u32) app_or_wrk_index << 16 | (u32) ls->session_index);
341 }
342
343 always_inline void
344 local_session_parse_id (u32 ls_id, u32 * app_or_wrk, u32 * session_index)
345 {
346   *app_or_wrk = ls_id >> 16;
347   *session_index = ls_id & 0xFF;
348 }
349
350 always_inline void
351 local_session_parse_handle (session_handle_t handle, u32 * app_or_wrk_index,
352                             u32 * session_index)
353 {
354   u32 bottom;
355   ASSERT ((handle >> 32) == SESSION_LOCAL_HANDLE_PREFIX);
356   bottom = (handle & 0xFFFFFFFF);
357   local_session_parse_id (bottom, app_or_wrk_index, session_index);
358 }
359
360 always_inline session_handle_t
361 application_local_session_handle (local_session_t * ls)
362 {
363   return ((u64) SESSION_LOCAL_HANDLE_PREFIX << 32)
364     | (u64) local_session_id (ls);
365 }
366
367 #endif /* SRC_VNET_SESSION_SESSION_TYPES_H_ */
368
369 /*
370  * fd.io coding-style-patch-verification: ON
371  *
372  * Local Variables:
373  * eval: (c-set-style "gnu")
374  * End:
375  */