session_types.h revision 91f90d08
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_INVALID_INDEX ((u32)~0)
23#define SESSION_INVALID_HANDLE ((u64)~0)
24#define SESSION_CTRL_MSG_MAX_SIZE 84
25
26#define foreach_session_endpoint_fields				\
27  foreach_transport_endpoint_cfg_fields				\
28  _(u8, transport_proto)					\
29
30typedef struct _session_endpoint
31{
32#define _(type, name) type name;
33  foreach_session_endpoint_fields
34#undef _
35} session_endpoint_t;
36
37typedef struct _session_endpoint_cfg
38{
39#define _(type, name) type name;
40  foreach_session_endpoint_fields
41#undef _
42  u32 app_wrk_index;
43  u32 opaque;
44  u32 ns_index;
45  u8 original_tp;
46  u8 *hostname;
47  u64 parent_handle;
48  u32 ckpair_index;
49  u8 crypto_engine;
50} session_endpoint_cfg_t;
51
52#define SESSION_IP46_ZERO			\
53{						\
54    .ip6 = {					\
55	{ 0, 0, },				\
56    },						\
57}
58
59#define TRANSPORT_ENDPOINT_NULL			\
60{						\
61  .sw_if_index = ENDPOINT_INVALID_INDEX,	\
62  .ip = SESSION_IP46_ZERO,			\
63  .fib_index = ENDPOINT_INVALID_INDEX,		\
64  .is_ip4 = 0,					\
65  .port = 0,					\
66}
67#define SESSION_ENDPOINT_NULL 			\
68{						\
69  .sw_if_index = ENDPOINT_INVALID_INDEX,	\
70  .ip = SESSION_IP46_ZERO,			\
71  .fib_index = ENDPOINT_INVALID_INDEX,		\
72  .is_ip4 = 0,					\
73  .port = 0,					\
74  .peer = TRANSPORT_ENDPOINT_NULL,		\
75  .transport_proto = 0,				\
76}
77#define SESSION_ENDPOINT_CFG_NULL 		\
78{						\
79  .sw_if_index = ENDPOINT_INVALID_INDEX,	\
80  .ip = SESSION_IP46_ZERO,			\
81  .fib_index = ENDPOINT_INVALID_INDEX,		\
82  .is_ip4 = 0,					\
83  .port = 0,					\
84  .peer = TRANSPORT_ENDPOINT_NULL,		\
85  .transport_proto = 0,				\
86  .app_wrk_index = ENDPOINT_INVALID_INDEX,	\
87  .opaque = ENDPOINT_INVALID_INDEX,		\
88  .hostname = 0,				\
89  .parent_handle = SESSION_INVALID_HANDLE,	\
90  .ckpair_index = 0				\
91}
92
93#define session_endpoint_to_transport(_sep) ((transport_endpoint_t *)_sep)
94#define session_endpoint_to_transport_cfg(_sep)		\
95  ((transport_endpoint_cfg_t *)_sep)
96
97always_inline u8
98session_endpoint_fib_proto (session_endpoint_t * sep)
99{
100  return sep->is_ip4 ? FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6;
101}
102
103static inline u8
104session_endpoint_is_local (session_endpoint_t * sep)
105{
106  return (ip_is_zero (&sep->ip, sep->is_ip4)
107	  || ip_is_local_host (&sep->ip, sep->is_ip4));
108}
109
110static inline u8
111session_endpoint_is_zero (session_endpoint_t * sep)
112{
113  return ip_is_zero (&sep->ip, sep->is_ip4);
114}
115
116typedef u8 session_type_t;
117typedef u64 session_handle_t;
118
119typedef enum
120{
121  SESSION_CLEANUP_TRANSPORT,
122  SESSION_CLEANUP_SESSION,
123} session_cleanup_ntf_t;
124
125/*
126 * Session states
127 */
128#define foreach_session_state				\
129  _(CREATED, "created")					\
130  _(LISTENING, "listening")				\
131  _(CONNECTING, "connecting")				\
132  _(ACCEPTING, "accepting")				\
133  _(READY, "ready")					\
134  _(OPENED, "opened")					\
135  _(TRANSPORT_CLOSING, "transport-closing")		\
136  _(CLOSING, "closing")					\
137  _(APP_CLOSED, "app-closed")				\
138  _(TRANSPORT_CLOSED, "transport-closed")		\
139  _(CLOSED, "closed")					\
140  _(TRANSPORT_DELETED, "transport-deleted")		\
141
142typedef enum
143{
144#define _(sym, str) SESSION_STATE_ ## sym,
145  foreach_session_state
146#undef _
147    SESSION_N_STATES,
148} session_state_t;
149
150#define foreach_session_flag				\
151  _(RX_EVT, "rx-event")					\
152  _(PROXY, "proxy")					\
153  _(CUSTOM_TX, "custom-tx")				\
154  _(IS_MIGRATING, "migrating")				\
155
156typedef enum session_flags_bits_
157{
158#define _(sym, str) SESSION_F_BIT_ ## sym,
159  foreach_session_flag
160#undef _
161  SESSION_N_FLAGS
162} session_flag_bits_t;
163
164typedef enum session_flags_
165{
166#define _(sym, str) SESSION_F_ ## sym = 1 << SESSION_F_BIT_ ## sym,
167  foreach_session_flag
168#undef _
169} session_flags_t;
170
171typedef struct session_
172{
173  /** Pointers to rx/tx buffers. Once allocated, these do not move */
174  svm_fifo_t *rx_fifo;
175  svm_fifo_t *tx_fifo;
176
177  /** Type built from transport and network protocol types */
178  session_type_t session_type;
179
180  /** State in session layer state machine. See @ref session_state_t */
181  volatile u8 session_state;
182
183  /** Index in thread pool where session was allocated */
184  u32 session_index;
185
186  /** Index of the app worker that owns the session */
187  u32 app_wrk_index;
188
189  /** Index of the thread that allocated the session */
190  u8 thread_index;
191
192  /** Session flags. See @ref session_flags_t */
193  u32 flags;
194
195  /** Index of the transport connection associated to the session */
196  u32 connection_index;
197
198  /** Index of application that owns the listener. Set only if a listener */
199  u32 app_index;
200
201  union
202  {
203    /** Parent listener session index if the result of an accept */
204    session_handle_t listener_handle;
205
206    /** App listener index in app's listener pool if a listener */
207    u32 al_index;
208  };
209
210  /** Opaque, for general use */
211  u32 opaque;
212
213    CLIB_CACHE_LINE_ALIGN_MARK (pad);
214} session_t;
215
216always_inline session_type_t
217session_type_from_proto_and_ip (transport_proto_t proto, u8 is_ip4)
218{
219  return (proto << 1 | is_ip4);
220}
221
222always_inline transport_proto_t
223session_type_transport_proto (session_type_t st)
224{
225  return (st >> 1);
226}
227
228always_inline u8
229session_type_is_ip4 (session_type_t st)
230{
231  return (st & 1);
232}
233
234always_inline transport_proto_t
235session_get_transport_proto (session_t * s)
236{
237  return (s->session_type >> 1);
238}
239
240always_inline fib_protocol_t
241session_get_fib_proto (session_t * s)
242{
243  u8 is_ip4 = s->session_type & 1;
244  return (is_ip4 ? FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6);
245}
246
247always_inline u8
248session_has_transport (session_t * s)
249{
250  return (session_get_transport_proto (s) != TRANSPORT_PROTO_NONE);
251}
252
253static inline transport_service_type_t
254session_transport_service_type (session_t * s)
255{
256  transport_proto_t tp;
257  tp = session_get_transport_proto (s);
258  return transport_protocol_service_type (tp);
259}
260
261static inline transport_tx_fn_type_t
262session_transport_tx_fn_type (session_t * s)
263{
264  transport_proto_t tp;
265  tp = session_get_transport_proto (s);
266  return transport_protocol_tx_fn_type (tp);
267}
268
269static inline u8
270session_tx_is_dgram (session_t * s)
271{
272  return (session_transport_tx_fn_type (s) == TRANSPORT_TX_DGRAM);
273}
274
275always_inline session_handle_t
276session_handle (session_t * s)
277{
278  return ((u64) s->thread_index << 32) | (u64) s->session_index;
279}
280
281always_inline u32
282session_index_from_handle (session_handle_t handle)
283{
284  return handle & 0xFFFFFFFF;
285}
286
287always_inline u32
288session_thread_from_handle (session_handle_t handle)
289{
290  return handle >> 32;
291}
292
293always_inline void
294session_parse_handle (session_handle_t handle, u32 * index,
295		      u32 * thread_index)
296{
297  *index = session_index_from_handle (handle);
298  *thread_index = session_thread_from_handle (handle);
299}
300
301static inline session_handle_t
302session_make_handle (u32 session_index, u32 thread_index)
303{
304  return (((u64) thread_index << 32) | (u64) session_index);
305}
306
307typedef enum
308{
309  SESSION_IO_EVT_RX,
310  SESSION_IO_EVT_TX,
311  SESSION_IO_EVT_TX_FLUSH,
312  SESSION_IO_EVT_BUILTIN_RX,
313  SESSION_IO_EVT_BUILTIN_TX,
314  SESSION_CTRL_EVT_RPC,
315  SESSION_CTRL_EVT_CLOSE,
316  SESSION_CTRL_EVT_RESET,
317  SESSION_CTRL_EVT_BOUND,
318  SESSION_CTRL_EVT_UNLISTEN_REPLY,
319  SESSION_CTRL_EVT_ACCEPTED,
320  SESSION_CTRL_EVT_ACCEPTED_REPLY,
321  SESSION_CTRL_EVT_CONNECTED,
322  SESSION_CTRL_EVT_DISCONNECTED,
323  SESSION_CTRL_EVT_DISCONNECTED_REPLY,
324  SESSION_CTRL_EVT_RESET_REPLY,
325  SESSION_CTRL_EVT_REQ_WORKER_UPDATE,
326  SESSION_CTRL_EVT_WORKER_UPDATE,
327  SESSION_CTRL_EVT_WORKER_UPDATE_REPLY,
328  SESSION_CTRL_EVT_DISCONNECT,
329  SESSION_CTRL_EVT_CONNECT,
330  SESSION_CTRL_EVT_CONNECT_URI,
331  SESSION_CTRL_EVT_LISTEN,
332  SESSION_CTRL_EVT_LISTEN_URI,
333  SESSION_CTRL_EVT_UNLISTEN,
334  SESSION_CTRL_EVT_APP_DETACH,
335} session_evt_type_t;
336
337#define foreach_session_ctrl_evt				\
338  _(LISTEN, listen)						\
339  _(LISTEN_URI, listen_uri)					\
340  _(BOUND, bound)						\
341  _(UNLISTEN, unlisten)						\
342  _(UNLISTEN_REPLY, unlisten_reply)				\
343  _(ACCEPTED, accepted)						\
344  _(ACCEPTED_REPLY, accepted_reply)				\
345  _(CONNECT, connect)						\
346  _(CONNECT_URI, connect_uri)					\
347  _(CONNECTED, connected)					\
348  _(DISCONNECT, disconnect)					\
349  _(DISCONNECTED, disconnected)					\
350  _(DISCONNECTED_REPLY, disconnected_reply)			\
351  _(RESET_REPLY, reset_reply)					\
352  _(REQ_WORKER_UPDATE, req_worker_update)			\
353  _(WORKER_UPDATE, worker_update)				\
354  _(WORKER_UPDATE_REPLY, worker_update_reply)			\
355  _(APP_DETACH, app_detach)					\
356
357
358/* Deprecated and will be removed. Use types above */
359#define FIFO_EVENT_APP_RX SESSION_IO_EVT_RX
360#define FIFO_EVENT_APP_TX SESSION_IO_EVT_TX
361#define FIFO_EVENT_DISCONNECT SESSION_CTRL_EVT_CLOSE
362#define FIFO_EVENT_BUILTIN_RX SESSION_IO_EVT_BUILTIN_RX
363#define FIFO_EVENT_BUILTIN_TX SESSION_IO_EVT_BUILTIN_TX
364
365typedef enum
366{
367  SESSION_MQ_IO_EVT_RING,
368  SESSION_MQ_CTRL_EVT_RING,
369  SESSION_MQ_N_RINGS
370} session_mq_rings_e;
371
372typedef struct
373{
374  void *fp;
375  void *arg;
376} session_rpc_args_t;
377
378typedef struct
379{
380  u8 event_type;
381  u8 postponed;
382  union
383  {
384    u32 session_index;
385    session_handle_t session_handle;
386    session_rpc_args_t rpc_args;
387    u32 ctrl_data_index;
388    struct
389    {
390      u8 data[0];
391    };
392  };
393} __clib_packed session_event_t;
394
395#define SESSION_MSG_NULL { }
396
397typedef struct session_dgram_pre_hdr_
398{
399  u32 data_length;
400  u32 data_offset;
401} session_dgram_pre_hdr_t;
402
403typedef struct session_dgram_header_
404{
405  u32 data_length;
406  u32 data_offset;
407  ip46_address_t rmt_ip;
408  ip46_address_t lcl_ip;
409  u16 rmt_port;
410  u16 lcl_port;
411  u8 is_ip4;
412} __clib_packed session_dgram_hdr_t;
413
414#define SESSION_CONN_ID_LEN 37
415#define SESSION_CONN_HDR_LEN 45
416
417STATIC_ASSERT (sizeof (session_dgram_hdr_t) == (SESSION_CONN_ID_LEN + 8),
418	       "session conn id wrong length");
419#endif /* SRC_VNET_SESSION_SESSION_TYPES_H_ */
420
421/*
422 * fd.io coding-style-patch-verification: ON
423 *
424 * Local Variables:
425 * eval: (c-set-style "gnu")
426 * End:
427 */
428