blob: 794a030456e9fcd27ab1c4711925284117135457 [file] [log] [blame]
Dave Wallace543852a2017-08-03 02:11:34 -04001/*
Dave Wallace33e002b2017-09-06 01:20:02 -04002 * Copyright (c) 2017 Cisco and/or its affiliates.
Dave Wallace543852a2017-08-03 02:11:34 -04003 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this
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#include <stdio.h>
17#include <stdlib.h>
18#include <signal.h>
19#include <svm/svm_fifo_segment.h>
20#include <vlibmemory/api.h>
21#include <vpp/api/vpe_msg_enum.h>
22#include <vnet/session/application_interface.h>
Dave Wallace5c7cf1c2017-10-24 04:12:18 -040023#include <vcl/vppcom.h>
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -080024#include <vcl/vcl_event.h>
Florin Coras0d427d82018-06-27 03:24:07 -070025#include <vcl/vcl_debug.h>
Dave Wallace543852a2017-08-03 02:11:34 -040026#include <vlib/unix/unix.h>
27#include <vppinfra/vec_bootstrap.h>
28
29#define vl_typedefs /* define message structures */
30#include <vpp/api/vpe_all_api_h.h>
31#undef vl_typedefs
32
33/* declare message handlers for each api */
34
35#define vl_endianfun /* define message structures */
36#include <vpp/api/vpe_all_api_h.h>
37#undef vl_endianfun
38
39/* instantiate all the print functions we know about */
40#define vl_print(handle, ...)
41#define vl_printfun
42#include <vpp/api/vpe_all_api_h.h>
43#undef vl_printfun
44
45#if (CLIB_DEBUG > 0)
Dave Wallace498b3a52017-11-09 13:00:34 -050046/* Set VPPCOM_DEBUG_INIT 2 for connection debug,
47 * 3 for read/write debug output
48 * or
49 * export VCL_DEBUG=<#> to set dynamically.
50 */
51#define VPPCOM_DEBUG_INIT 1
Dave Wallace543852a2017-08-03 02:11:34 -040052#else
Dave Wallace498b3a52017-11-09 13:00:34 -050053#define VPPCOM_DEBUG_INIT 0
Dave Wallace543852a2017-08-03 02:11:34 -040054#endif
55
Dave Wallace498b3a52017-11-09 13:00:34 -050056#define VPPCOM_DEBUG vcm->debug
57
Dave Wallace543852a2017-08-03 02:11:34 -040058/*
59 * VPPCOM Private definitions and functions.
60 */
61typedef enum
62{
63 STATE_APP_START,
64 STATE_APP_CONN_VPP,
65 STATE_APP_ENABLED,
66 STATE_APP_ATTACHED,
67} app_state_t;
68
69typedef enum
70{
Dave Wallace4878cbe2017-11-21 03:45:09 -050071 STATE_START = 0x01,
72 STATE_CONNECT = 0x02,
73 STATE_LISTEN = 0x04,
74 STATE_ACCEPT = 0x08,
75 STATE_CLOSE_ON_EMPTY = 0x10,
76 STATE_DISCONNECT = 0x20,
77 STATE_FAILED = 0x40
Dave Wallace543852a2017-08-03 02:11:34 -040078} session_state_t;
79
Dave Wallace4878cbe2017-11-21 03:45:09 -050080#define SERVER_STATE_OPEN (STATE_ACCEPT|STATE_CLOSE_ON_EMPTY)
81#define CLIENT_STATE_OPEN (STATE_CONNECT|STATE_CLOSE_ON_EMPTY)
82
Dave Wallacef7f809c2017-10-03 01:48:42 -040083typedef struct epoll_event vppcom_epoll_event_t;
84
85typedef struct
86{
87 u32 next_sid;
88 u32 prev_sid;
89 u32 vep_idx;
90 vppcom_epoll_event_t ev;
91#define VEP_DEFAULT_ET_MASK (EPOLLIN|EPOLLOUT)
Dave Wallace60caa062017-11-10 17:07:13 -050092#define VEP_UNSUPPORTED_EVENTS (EPOLLONESHOT|EPOLLEXCLUSIVE)
Dave Wallacef7f809c2017-10-03 01:48:42 -040093 u32 et_mask;
94} vppcom_epoll_t;
95
Dave Wallace543852a2017-08-03 02:11:34 -040096typedef struct
97{
Dave Wallace35830af2017-10-09 01:43:42 -040098 u8 is_ip4;
99 ip46_address_t ip46;
100} vppcom_ip46_t;
101
Dave Wallace048b1d62018-01-03 22:24:41 -0500102enum
103{
104 VCL_SESS_ATTR_SERVER,
105 VCL_SESS_ATTR_CUT_THRU,
106 VCL_SESS_ATTR_VEP,
107 VCL_SESS_ATTR_VEP_SESSION,
108 VCL_SESS_ATTR_LISTEN, // SOL_SOCKET,SO_ACCEPTCONN
109 VCL_SESS_ATTR_NONBLOCK, // fcntl,O_NONBLOCK
110 VCL_SESS_ATTR_REUSEADDR, // SOL_SOCKET,SO_REUSEADDR
111 VCL_SESS_ATTR_REUSEPORT, // SOL_SOCKET,SO_REUSEPORT
112 VCL_SESS_ATTR_BROADCAST, // SOL_SOCKET,SO_BROADCAST
113 VCL_SESS_ATTR_V6ONLY, // SOL_TCP,IPV6_V6ONLY
114 VCL_SESS_ATTR_KEEPALIVE, // SOL_SOCKET,SO_KEEPALIVE
115 VCL_SESS_ATTR_TCP_NODELAY, // SOL_TCP,TCP_NODELAY
116 VCL_SESS_ATTR_TCP_KEEPIDLE, // SOL_TCP,TCP_KEEPIDLE
117 VCL_SESS_ATTR_TCP_KEEPINTVL, // SOL_TCP,TCP_KEEPINTVL
118 VCL_SESS_ATTR_MAX
119} vppcom_session_attr_t;
120
121#define VCL_SESS_ATTR_SET(ATTR, VAL) \
122do { \
123 (ATTR) |= 1 << (VAL); \
124 } while (0)
125
126#define VCL_SESS_ATTR_CLR(ATTR, VAL) \
127do { \
128 (ATTR) &= ~(1 << (VAL)); \
129 } while (0)
130
131#define VCL_SESS_ATTR_TEST(ATTR, VAL) \
132 ((ATTR) & (1 << (VAL)) ? 1 : 0)
133
Dave Wallace35830af2017-10-09 01:43:42 -0400134typedef struct
135{
Dave Wallace543852a2017-08-03 02:11:34 -0400136 volatile session_state_t state;
137
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -0800138 svm_fifo_t *rx_fifo;
139 svm_fifo_t *tx_fifo;
Dave Wallace048b1d62018-01-03 22:24:41 -0500140 u32 sndbuf_size; // VPP-TBD: Hack until support setsockopt(SO_SNDBUF)
141 u32 rcvbuf_size; // VPP-TBD: Hack until support setsockopt(SO_RCVBUF)
142 u32 user_mss; // VPP-TBD: Hack until support setsockopt(TCP_MAXSEG)
Dave Wallace60caa062017-11-10 17:07:13 -0500143 u8 *segment_name;
Dave Wallace543852a2017-08-03 02:11:34 -0400144 u32 sm_seg_index;
Dave Wallace60caa062017-11-10 17:07:13 -0500145 u32 client_context;
146 u64 vpp_handle;
Florin Corase86a8ed2018-01-05 03:20:25 -0800147 svm_queue_t *vpp_event_queue;
Dave Wallace543852a2017-08-03 02:11:34 -0400148
149 /* Socket configuration state */
Dave Wallacef7f809c2017-10-03 01:48:42 -0400150 u8 is_vep;
151 u8 is_vep_session;
Dave Wallace048b1d62018-01-03 22:24:41 -0500152 u32 attr;
Dave Wallacef7f809c2017-10-03 01:48:42 -0400153 u32 wait_cont_idx;
154 vppcom_epoll_t vep;
Dave Wallace048b1d62018-01-03 22:24:41 -0500155 int libc_epfd;
Dave Wallace35830af2017-10-09 01:43:42 -0400156 vppcom_ip46_t lcl_addr;
157 vppcom_ip46_t peer_addr;
Stevenac1f96d2017-10-24 16:03:58 -0700158 u16 lcl_port; // network order
159 u16 peer_port; // network order
Dave Wallace543852a2017-08-03 02:11:34 -0400160 u8 proto;
161 u64 client_queue_address;
162 u64 options[16];
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -0800163 elog_track_t elog_track;
Keith Burns (alagalah)12756512018-03-06 05:55:27 -0800164 vce_event_handler_reg_t *poll_reg;
Dave Wallace543852a2017-08-03 02:11:34 -0400165} session_t;
166
167typedef struct vppcom_cfg_t_
168{
169 u64 heapsize;
Dave Wallacec8f1ee62017-11-29 22:46:32 -0500170 u32 vpp_api_q_length;
Dave Wallace543852a2017-08-03 02:11:34 -0400171 u64 segment_baseva;
172 u32 segment_size;
173 u32 add_segment_size;
174 u32 preallocated_fifo_pairs;
175 u32 rx_fifo_size;
176 u32 tx_fifo_size;
177 u32 event_queue_size;
178 u32 listen_queue_size;
Dave Wallace774169b2017-11-01 20:07:40 -0400179 u8 app_proxy_transport_tcp;
180 u8 app_proxy_transport_udp;
181 u8 app_scope_local;
182 u8 app_scope_global;
Dave Wallace8af20542017-10-26 03:29:30 -0400183 u8 *namespace_id;
184 u64 namespace_secret;
Dave Wallace543852a2017-08-03 02:11:34 -0400185 f64 app_timeout;
186 f64 session_timeout;
187 f64 accept_timeout;
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -0800188 u32 event_ring_size;
189 char *event_log_path;
Dave Wallaceb5a86ee2018-02-16 18:26:11 -0500190 u8 *vpp_api_filename;
Dave Wallace543852a2017-08-03 02:11:34 -0400191} vppcom_cfg_t;
192
193typedef struct vppcom_main_t_
194{
195 u8 init;
Dave Wallace498b3a52017-11-09 13:00:34 -0500196 u32 debug;
Dave Wallace543852a2017-08-03 02:11:34 -0400197 int main_cpu;
198
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -0800199 /* FIFO for accepted connections - used in epoll/select */
200 clib_spinlock_t session_fifo_lockp;
201 u32 *client_session_index_fifo;
202
Dave Wallaceb5a86ee2018-02-16 18:26:11 -0500203 /* vpp input queue */
Florin Corase86a8ed2018-01-05 03:20:25 -0800204 svm_queue_t *vl_input_queue;
Dave Wallace543852a2017-08-03 02:11:34 -0400205
206 /* API client handle */
207 u32 my_client_index;
Dave Wallace543852a2017-08-03 02:11:34 -0400208 /* Session pool */
209 clib_spinlock_t sessions_lockp;
210 session_t *sessions;
211
212 /* Hash table for disconnect processing */
213 uword *session_index_by_vpp_handles;
214
215 /* Select bitmaps */
216 clib_bitmap_t *rd_bitmap;
217 clib_bitmap_t *wr_bitmap;
218 clib_bitmap_t *ex_bitmap;
219
220 /* Our event queue */
Florin Corase86a8ed2018-01-05 03:20:25 -0800221 svm_queue_t *app_event_queue;
Dave Wallace543852a2017-08-03 02:11:34 -0400222
223 /* unique segment name counter */
224 u32 unique_segment_index;
225
Dave Wallace543852a2017-08-03 02:11:34 -0400226 /* For deadman timers */
227 clib_time_t clib_time;
228
229 /* State of the connection, shared between msg RX thread and main thread */
230 volatile app_state_t app_state;
231
232 vppcom_cfg_t cfg;
233
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800234 /* Event thread */
235 vce_event_thread_t event_thread;
236
Keith Burns (alagalah)410bcca2018-03-23 13:42:49 -0700237 /* IO thread */
238 vppcom_session_io_thread_t session_io_thread;
239
Florin Coras0d427d82018-06-27 03:24:07 -0700240#ifdef VCL_ELOG
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800241 /* VPP Event-logger */
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -0800242 elog_main_t elog_main;
243 elog_track_t elog_track;
Florin Coras0d427d82018-06-27 03:24:07 -0700244#endif
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -0800245
Dave Wallace543852a2017-08-03 02:11:34 -0400246 /* VNET_API_ERROR_FOO -> "Foo" hash table */
247 uword *error_string_by_error_number;
248} vppcom_main_t;
249
Dave Wallace2e005bb2017-11-07 01:21:39 -0500250/* NOTE: _vppcom_main is only used until the heap is allocated.
251 * Do not access it directly -- use vcm which will point to
252 * the heap allocated copy after init.
253 */
Dave Wallace498b3a52017-11-09 13:00:34 -0500254static vppcom_main_t _vppcom_main = {
255 .debug = VPPCOM_DEBUG_INIT,
256 .my_client_index = ~0
257};
Dave Wallace2e005bb2017-11-07 01:21:39 -0500258
259static vppcom_main_t *vcm = &_vppcom_main;
Dave Wallace543852a2017-08-03 02:11:34 -0400260
Dave Wallace7e607a72018-06-18 18:41:32 -0400261#define VCL_SESSION_LOCK_AND_GET(I, S) \
Dave Wallace048b1d62018-01-03 22:24:41 -0500262do { \
263 clib_spinlock_lock (&vcm->sessions_lockp); \
264 rv = vppcom_session_at_index (I, S); \
265 if (PREDICT_FALSE (rv)) \
266 { \
267 clib_spinlock_unlock (&vcm->sessions_lockp); \
268 clib_warning ("VCL<%d>: ERROR: Invalid ##I (%u)!", \
269 getpid (), I); \
270 goto done; \
271 } \
Dave Wallace60caa062017-11-10 17:07:13 -0500272} while (0)
273
Dave Wallace7e607a72018-06-18 18:41:32 -0400274#define VCL_SESSION_LOCK() clib_spinlock_lock (&(vcm->sessions_lockp))
275#define VCL_SESSION_UNLOCK() clib_spinlock_unlock (&(vcm->sessions_lockp))
276
277#define VCL_IO_SESSIONS_LOCK() \
278 clib_spinlock_lock (&(vcm->session_io_thread.io_sessions_lockp))
279#define VCL_IO_SESSIONS_UNLOCK() \
280 clib_spinlock_unlock (&(vcm->session_io_thread.io_sessions_lockp))
281
282#define VCL_ACCEPT_FIFO_LOCK() clib_spinlock_lock (&(vcm->session_fifo_lockp))
283#define VCL_ACCEPT_FIFO_UNLOCK() \
284 clib_spinlock_unlock (&(vcm->session_fifo_lockp))
285
286#define VCL_EVENTS_LOCK() \
287 clib_spinlock_lock (&(vcm->event_thread.events_lockp))
288#define VCL_EVENTS_UNLOCK() \
289 clib_spinlock_unlock (&(vcm->event_thread.events_lockp))
290
Dave Wallace543852a2017-08-03 02:11:34 -0400291static const char *
292vppcom_app_state_str (app_state_t state)
293{
294 char *st;
295
296 switch (state)
297 {
298 case STATE_APP_START:
299 st = "STATE_APP_START";
300 break;
301
302 case STATE_APP_CONN_VPP:
303 st = "STATE_APP_CONN_VPP";
304 break;
305
306 case STATE_APP_ENABLED:
307 st = "STATE_APP_ENABLED";
308 break;
309
310 case STATE_APP_ATTACHED:
311 st = "STATE_APP_ATTACHED";
312 break;
313
314 default:
315 st = "UNKNOWN_APP_STATE";
316 break;
317 }
318
319 return st;
320}
321
322static const char *
323vppcom_session_state_str (session_state_t state)
324{
325 char *st;
326
327 switch (state)
328 {
329 case STATE_START:
330 st = "STATE_START";
331 break;
332
333 case STATE_CONNECT:
334 st = "STATE_CONNECT";
335 break;
336
337 case STATE_LISTEN:
338 st = "STATE_LISTEN";
339 break;
340
341 case STATE_ACCEPT:
342 st = "STATE_ACCEPT";
343 break;
344
Dave Wallace4878cbe2017-11-21 03:45:09 -0500345 case STATE_CLOSE_ON_EMPTY:
346 st = "STATE_CLOSE_ON_EMPTY";
347 break;
348
Dave Wallace543852a2017-08-03 02:11:34 -0400349 case STATE_DISCONNECT:
350 st = "STATE_DISCONNECT";
351 break;
352
353 case STATE_FAILED:
354 st = "STATE_FAILED";
355 break;
356
357 default:
358 st = "UNKNOWN_STATE";
359 break;
360 }
361
362 return st;
363}
364
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800365
Dave Wallace543852a2017-08-03 02:11:34 -0400366/*
367 * VPPCOM Utility Functions
368 */
Keith Burns (alagalah)410bcca2018-03-23 13:42:49 -0700369
Dave Wallace543852a2017-08-03 02:11:34 -0400370static inline int
371vppcom_session_at_index (u32 session_index, session_t * volatile *sess)
372{
Dave Wallace543852a2017-08-03 02:11:34 -0400373 /* Assumes that caller has acquired spinlock: vcm->sessions_lockp */
374 if (PREDICT_FALSE ((session_index == ~0) ||
375 pool_is_free_index (vcm->sessions, session_index)))
376 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500377 clib_warning ("VCL<%d>: invalid session, sid (%u) has been closed!",
Dave Wallace2e005bb2017-11-07 01:21:39 -0500378 getpid (), session_index);
Dave Wallace543852a2017-08-03 02:11:34 -0400379 return VPPCOM_EBADFD;
380 }
381 *sess = pool_elt_at_index (vcm->sessions, session_index);
382 return VPPCOM_OK;
383}
384
Florin Corasdcf55ce2017-11-16 15:32:50 -0800385static inline void
386vppcom_session_table_add_listener (u64 listener_handle, u32 value)
387{
388 /* Session and listener handles have different formats. The latter has
389 * the thread index in the upper 32 bits while the former has the session
390 * type. Knowing that, for listeners we just flip the MSB to 1 */
391 listener_handle |= 1ULL << 63;
392 hash_set (vcm->session_index_by_vpp_handles, listener_handle, value);
393}
394
395static inline session_t *
396vppcom_session_table_lookup_listener (u64 listener_handle)
397{
398 uword *p;
399 u64 handle = listener_handle | (1ULL << 63);
Dave Wallace4878cbe2017-11-21 03:45:09 -0500400 session_t *session;
401
Florin Corasdcf55ce2017-11-16 15:32:50 -0800402 p = hash_get (vcm->session_index_by_vpp_handles, handle);
403 if (!p)
404 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500405 clib_warning ("VCL<%d>: couldn't find listen session: unknown vpp "
Florin Corasdcf55ce2017-11-16 15:32:50 -0800406 "listener handle %llx", getpid (), listener_handle);
407 return 0;
408 }
409 if (pool_is_free_index (vcm->sessions, p[0]))
410 {
Florin Coras0d427d82018-06-27 03:24:07 -0700411 VDBG (1, "VCL<%d>: invalid listen session, sid (%u)", getpid (), p[0]);
Florin Corasdcf55ce2017-11-16 15:32:50 -0800412 return 0;
413 }
414
Dave Wallace4878cbe2017-11-21 03:45:09 -0500415 session = pool_elt_at_index (vcm->sessions, p[0]);
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -0800416 ASSERT (session->state & STATE_LISTEN);
Dave Wallace4878cbe2017-11-21 03:45:09 -0500417 return session;
Florin Corasdcf55ce2017-11-16 15:32:50 -0800418}
419
420static inline void
421vppcom_session_table_del_listener (u64 listener_handle)
422{
423 listener_handle |= 1ULL << 63;
424 hash_unset (vcm->session_index_by_vpp_handles, listener_handle);
425}
426
Keith Burns (alagalah)0d2b0d52018-03-06 15:55:22 -0800427static inline void
428vppcom_send_accept_session_reply (u64 handle, u32 context, int retval)
429{
430 vl_api_accept_session_reply_t *rmp;
431
432 rmp = vl_msg_api_alloc (sizeof (*rmp));
433 memset (rmp, 0, sizeof (*rmp));
434 rmp->_vl_msg_id = ntohs (VL_API_ACCEPT_SESSION_REPLY);
435 rmp->retval = htonl (retval);
436 rmp->context = context;
437 rmp->handle = handle;
438 vl_msg_api_send_shmem (vcm->vl_input_queue, (u8 *) & rmp);
439}
440
Dave Wallace543852a2017-08-03 02:11:34 -0400441static int
442vppcom_connect_to_vpp (char *app_name)
443{
444 api_main_t *am = &api_main;
Dave Wallaceb5a86ee2018-02-16 18:26:11 -0500445 vppcom_cfg_t *vcl_cfg = &vcm->cfg;
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -0800446 int rv = VPPCOM_OK;
Dave Wallace543852a2017-08-03 02:11:34 -0400447
Dave Wallaceb5a86ee2018-02-16 18:26:11 -0500448 if (!vcl_cfg->vpp_api_filename)
449 vcl_cfg->vpp_api_filename = format (0, "/vpe-api%c", 0);
Dave Wallace048b1d62018-01-03 22:24:41 -0500450
Florin Coras0d427d82018-06-27 03:24:07 -0700451 VDBG (0, "VCL<%d>: app (%s) connecting to VPP api (%s)...",
452 getpid (), app_name, vcl_cfg->vpp_api_filename);
Dave Wallaceb5a86ee2018-02-16 18:26:11 -0500453
454 if (vl_client_connect_to_vlib ((char *) vcl_cfg->vpp_api_filename, app_name,
Dave Wallacec8f1ee62017-11-29 22:46:32 -0500455 vcm->cfg.vpp_api_q_length) < 0)
Dave Wallace543852a2017-08-03 02:11:34 -0400456 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500457 clib_warning ("VCL<%d>: app (%s) connect failed!", getpid (), app_name);
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -0800458 rv = VPPCOM_ECONNREFUSED;
459 }
460 else
461 {
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -0800462 vcm->vl_input_queue = am->shmem_hdr->vl_input_queue;
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800463 vcm->my_client_index = (u32) am->my_client_index;
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -0800464 vcm->app_state = STATE_APP_CONN_VPP;
Dave Wallace9b954252018-01-18 17:01:40 -0500465
Florin Coras0d427d82018-06-27 03:24:07 -0700466 VDBG (0, "VCL<%d>: app (%s) is connected to VPP!", getpid (), app_name);
Dave Wallace543852a2017-08-03 02:11:34 -0400467 }
468
Florin Coras0d427d82018-06-27 03:24:07 -0700469 vcl_evt (VCL_EVT_INIT, vcm);
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -0800470 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -0400471}
472
473static u8 *
474format_api_error (u8 * s, va_list * args)
475{
Dave Wallace543852a2017-08-03 02:11:34 -0400476 i32 error = va_arg (*args, u32);
477 uword *p;
478
479 p = hash_get (vcm->error_string_by_error_number, -error);
480
481 if (p)
482 s = format (s, "%s (%d)", p[0], error);
483 else
484 s = format (s, "%d", error);
485 return s;
486}
487
488static void
489vppcom_init_error_string_table (void)
490{
Dave Wallace543852a2017-08-03 02:11:34 -0400491 vcm->error_string_by_error_number = hash_create (0, sizeof (uword));
492
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -0800493#define _(n, v, s) hash_set (vcm->error_string_by_error_number, -v, s);
Dave Wallace543852a2017-08-03 02:11:34 -0400494 foreach_vnet_api_error;
495#undef _
496
497 hash_set (vcm->error_string_by_error_number, 99, "Misc");
498}
499
500static inline int
501vppcom_wait_for_app_state_change (app_state_t app_state)
502{
Dave Wallace543852a2017-08-03 02:11:34 -0400503 f64 timeout = clib_time_now (&vcm->clib_time) + vcm->cfg.app_timeout;
504
505 while (clib_time_now (&vcm->clib_time) < timeout)
506 {
507 if (vcm->app_state == app_state)
508 return VPPCOM_OK;
509 }
Florin Coras0d427d82018-06-27 03:24:07 -0700510 VDBG (0, "VCL<%d>: timeout waiting for state %s (%d)", getpid (),
511 vppcom_app_state_str (app_state), app_state);
512 vcl_evt (VCL_EVT_SESSION_TIMEOUT, vcm, app_state);
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -0800513
Dave Wallace543852a2017-08-03 02:11:34 -0400514 return VPPCOM_ETIMEDOUT;
515}
516
517static inline int
518vppcom_wait_for_session_state_change (u32 session_index,
519 session_state_t state,
520 f64 wait_for_time)
521{
Dave Wallace543852a2017-08-03 02:11:34 -0400522 f64 timeout = clib_time_now (&vcm->clib_time) + wait_for_time;
523 session_t *volatile session;
524 int rv;
525
526 do
527 {
Dave Wallace7e607a72018-06-18 18:41:32 -0400528 VCL_SESSION_LOCK ();
Dave Wallace543852a2017-08-03 02:11:34 -0400529 rv = vppcom_session_at_index (session_index, &session);
530 if (PREDICT_FALSE (rv))
531 {
Dave Wallace7e607a72018-06-18 18:41:32 -0400532 VCL_SESSION_UNLOCK ();
Dave Wallace543852a2017-08-03 02:11:34 -0400533 return rv;
534 }
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -0800535 if (session->state & state)
Dave Wallace543852a2017-08-03 02:11:34 -0400536 {
Dave Wallace7e607a72018-06-18 18:41:32 -0400537 VCL_SESSION_UNLOCK ();
Dave Wallace543852a2017-08-03 02:11:34 -0400538 return VPPCOM_OK;
539 }
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -0800540 if (session->state & STATE_FAILED)
Dave Wallace4878cbe2017-11-21 03:45:09 -0500541 {
Dave Wallace7e607a72018-06-18 18:41:32 -0400542 VCL_SESSION_UNLOCK ();
Dave Wallace4878cbe2017-11-21 03:45:09 -0500543 return VPPCOM_ECONNREFUSED;
544 }
545
Dave Wallace7e607a72018-06-18 18:41:32 -0400546 VCL_SESSION_UNLOCK ();
Dave Wallace543852a2017-08-03 02:11:34 -0400547 }
548 while (clib_time_now (&vcm->clib_time) < timeout);
549
Florin Coras0d427d82018-06-27 03:24:07 -0700550 VDBG (0, "VCL<%d>: timeout waiting for state 0x%x (%s)", getpid (), state,
551 vppcom_session_state_str (state));
552 vcl_evt (VCL_EVT_SESSION_TIMEOUT, session, state);
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -0800553
Dave Wallace543852a2017-08-03 02:11:34 -0400554 return VPPCOM_ETIMEDOUT;
555}
556
Dave Wallace543852a2017-08-03 02:11:34 -0400557/*
558 * VPP-API message functions
559 */
560static void
561vppcom_send_session_enable_disable (u8 is_enable)
562{
Dave Wallace543852a2017-08-03 02:11:34 -0400563 vl_api_session_enable_disable_t *bmp;
564 bmp = vl_msg_api_alloc (sizeof (*bmp));
565 memset (bmp, 0, sizeof (*bmp));
566
567 bmp->_vl_msg_id = ntohs (VL_API_SESSION_ENABLE_DISABLE);
568 bmp->client_index = vcm->my_client_index;
569 bmp->context = htonl (0xfeedface);
570 bmp->is_enable = is_enable;
571 vl_msg_api_send_shmem (vcm->vl_input_queue, (u8 *) & bmp);
572}
573
574static int
575vppcom_app_session_enable (void)
576{
Dave Wallace543852a2017-08-03 02:11:34 -0400577 int rv;
578
579 if (vcm->app_state != STATE_APP_ENABLED)
580 {
581 vppcom_send_session_enable_disable (1 /* is_enabled == TRUE */ );
582 rv = vppcom_wait_for_app_state_change (STATE_APP_ENABLED);
583 if (PREDICT_FALSE (rv))
584 {
Florin Coras0d427d82018-06-27 03:24:07 -0700585 VDBG (0, "VCL<%d>: application session enable timed out! "
586 "returning %d (%s)", getpid (), rv, vppcom_retval_str (rv));
Dave Wallace543852a2017-08-03 02:11:34 -0400587 return rv;
588 }
589 }
590 return VPPCOM_OK;
591}
592
593static void
594 vl_api_session_enable_disable_reply_t_handler
595 (vl_api_session_enable_disable_reply_t * mp)
596{
Dave Wallace543852a2017-08-03 02:11:34 -0400597 if (mp->retval)
598 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500599 clib_warning ("VCL<%d>: session_enable_disable failed: %U", getpid (),
Dave Wallace543852a2017-08-03 02:11:34 -0400600 format_api_error, ntohl (mp->retval));
601 }
602 else
603 vcm->app_state = STATE_APP_ENABLED;
604}
605
606static void
607vppcom_app_send_attach (void)
608{
Dave Wallace543852a2017-08-03 02:11:34 -0400609 vl_api_application_attach_t *bmp;
Dave Wallace8af20542017-10-26 03:29:30 -0400610 u8 nsid_len = vec_len (vcm->cfg.namespace_id);
Dave Wallace774169b2017-11-01 20:07:40 -0400611 u8 app_is_proxy = (vcm->cfg.app_proxy_transport_tcp ||
612 vcm->cfg.app_proxy_transport_udp);
Dave Wallace8af20542017-10-26 03:29:30 -0400613
Dave Wallace543852a2017-08-03 02:11:34 -0400614 bmp = vl_msg_api_alloc (sizeof (*bmp));
615 memset (bmp, 0, sizeof (*bmp));
616
617 bmp->_vl_msg_id = ntohs (VL_API_APPLICATION_ATTACH);
618 bmp->client_index = vcm->my_client_index;
619 bmp->context = htonl (0xfeedface);
620 bmp->options[APP_OPTIONS_FLAGS] =
Florin Corascea194d2017-10-02 00:18:51 -0700621 APP_OPTIONS_FLAGS_ACCEPT_REDIRECT | APP_OPTIONS_FLAGS_ADD_SEGMENT |
Dave Wallace774169b2017-11-01 20:07:40 -0400622 (vcm->cfg.app_scope_local ? APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE : 0) |
623 (vcm->cfg.app_scope_global ? APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE : 0) |
624 (app_is_proxy ? APP_OPTIONS_FLAGS_IS_PROXY : 0);
625 bmp->options[APP_OPTIONS_PROXY_TRANSPORT] =
Keith Burns (alagalah)410bcca2018-03-23 13:42:49 -0700626 (u64) ((vcm->cfg.app_proxy_transport_tcp ? 1 << TRANSPORT_PROTO_TCP : 0) |
627 (vcm->cfg.app_proxy_transport_udp ? 1 << TRANSPORT_PROTO_UDP : 0));
Florin Corasff6e7692017-12-11 04:59:01 -0800628 bmp->options[APP_OPTIONS_SEGMENT_SIZE] = vcm->cfg.segment_size;
629 bmp->options[APP_OPTIONS_ADD_SEGMENT_SIZE] = vcm->cfg.add_segment_size;
630 bmp->options[APP_OPTIONS_RX_FIFO_SIZE] = vcm->cfg.rx_fifo_size;
631 bmp->options[APP_OPTIONS_TX_FIFO_SIZE] = vcm->cfg.tx_fifo_size;
Florin Corasf32cff62017-12-09 08:15:00 -0800632 bmp->options[APP_OPTIONS_PREALLOC_FIFO_PAIRS] =
633 vcm->cfg.preallocated_fifo_pairs;
Florin Corasff6e7692017-12-11 04:59:01 -0800634 bmp->options[APP_OPTIONS_EVT_QUEUE_SIZE] = vcm->cfg.event_queue_size;
Dave Wallace8af20542017-10-26 03:29:30 -0400635 if (nsid_len)
636 {
637 bmp->namespace_id_len = nsid_len;
638 clib_memcpy (bmp->namespace_id, vcm->cfg.namespace_id, nsid_len);
639 bmp->options[APP_OPTIONS_NAMESPACE_SECRET] = vcm->cfg.namespace_secret;
640 }
Dave Wallace543852a2017-08-03 02:11:34 -0400641 vl_msg_api_send_shmem (vcm->vl_input_queue, (u8 *) & bmp);
642}
643
644static int
645vppcom_app_attach (void)
646{
Dave Wallace543852a2017-08-03 02:11:34 -0400647 int rv;
648
649 vppcom_app_send_attach ();
650 rv = vppcom_wait_for_app_state_change (STATE_APP_ATTACHED);
651 if (PREDICT_FALSE (rv))
652 {
Florin Coras0d427d82018-06-27 03:24:07 -0700653 VDBG (0, "VCL<%d>: application attach timed out! returning %d (%s)",
654 getpid (), rv, vppcom_retval_str (rv));
Dave Wallace543852a2017-08-03 02:11:34 -0400655 return rv;
656 }
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800657
Dave Wallace543852a2017-08-03 02:11:34 -0400658 return VPPCOM_OK;
659}
660
661static void
662vppcom_app_detach (void)
663{
Dave Wallace543852a2017-08-03 02:11:34 -0400664 vl_api_application_detach_t *bmp;
665 bmp = vl_msg_api_alloc (sizeof (*bmp));
666 memset (bmp, 0, sizeof (*bmp));
667
668 bmp->_vl_msg_id = ntohs (VL_API_APPLICATION_DETACH);
669 bmp->client_index = vcm->my_client_index;
670 bmp->context = htonl (0xfeedface);
671 vl_msg_api_send_shmem (vcm->vl_input_queue, (u8 *) & bmp);
672}
673
674static void
675vl_api_application_attach_reply_t_handler (vl_api_application_attach_reply_t *
676 mp)
677{
Dave Wallace543852a2017-08-03 02:11:34 -0400678 static svm_fifo_segment_create_args_t _a;
679 svm_fifo_segment_create_args_t *a = &_a;
680 int rv;
681
682 memset (a, 0, sizeof (*a));
683 if (mp->retval)
684 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500685 clib_warning ("VCL<%d>: attach failed: %U", getpid (),
Dave Wallace543852a2017-08-03 02:11:34 -0400686 format_api_error, ntohl (mp->retval));
687 return;
688 }
689
690 if (mp->segment_name_length == 0)
691 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500692 clib_warning ("VCL<%d>: segment_name_length zero", getpid ());
Dave Wallace543852a2017-08-03 02:11:34 -0400693 return;
694 }
695
696 a->segment_name = (char *) mp->segment_name;
697 a->segment_size = mp->segment_size;
698
699 ASSERT (mp->app_event_queue_address);
700
701 /* Attach to the segment vpp created */
702 rv = svm_fifo_segment_attach (a);
703 vec_reset_length (a->new_segment_indices);
704 if (PREDICT_FALSE (rv))
705 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500706 clib_warning ("VCL<%d>: svm_fifo_segment_attach ('%s') failed",
707 getpid (), mp->segment_name);
Dave Wallace543852a2017-08-03 02:11:34 -0400708 return;
709 }
710
711 vcm->app_event_queue =
Florin Corase86a8ed2018-01-05 03:20:25 -0800712 uword_to_pointer (mp->app_event_queue_address, svm_queue_t *);
Dave Wallace543852a2017-08-03 02:11:34 -0400713
714 vcm->app_state = STATE_APP_ATTACHED;
715}
716
717static void
718vl_api_application_detach_reply_t_handler (vl_api_application_detach_reply_t *
719 mp)
720{
Dave Wallace543852a2017-08-03 02:11:34 -0400721 if (mp->retval)
Dave Wallace048b1d62018-01-03 22:24:41 -0500722 clib_warning ("VCL<%d>: detach failed: %U", getpid (), format_api_error,
Dave Wallace543852a2017-08-03 02:11:34 -0400723 ntohl (mp->retval));
724
725 vcm->app_state = STATE_APP_ENABLED;
726}
727
728static void
729vl_api_disconnect_session_reply_t_handler (vl_api_disconnect_session_reply_t *
730 mp)
731{
Dave Wallace543852a2017-08-03 02:11:34 -0400732 if (mp->retval)
Dave Wallace048b1d62018-01-03 22:24:41 -0500733 clib_warning ("VCL<%d>: vpp handle 0x%llx: disconnect session failed: %U",
Dave Wallace4878cbe2017-11-21 03:45:09 -0500734 getpid (), mp->handle, format_api_error,
735 ntohl (mp->retval));
Dave Wallace543852a2017-08-03 02:11:34 -0400736}
737
738static void
739vl_api_map_another_segment_t_handler (vl_api_map_another_segment_t * mp)
740{
Dave Wallace543852a2017-08-03 02:11:34 -0400741 static svm_fifo_segment_create_args_t _a;
742 svm_fifo_segment_create_args_t *a = &_a;
743 int rv;
744
745 memset (a, 0, sizeof (*a));
746 a->segment_name = (char *) mp->segment_name;
747 a->segment_size = mp->segment_size;
748 /* Attach to the segment vpp created */
749 rv = svm_fifo_segment_attach (a);
750 vec_reset_length (a->new_segment_indices);
751 if (PREDICT_FALSE (rv))
752 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500753 clib_warning ("VCL<%d>: svm_fifo_segment_attach ('%s') failed",
Dave Wallace2e005bb2017-11-07 01:21:39 -0500754 getpid (), mp->segment_name);
Dave Wallace543852a2017-08-03 02:11:34 -0400755 return;
756 }
Florin Coras0d427d82018-06-27 03:24:07 -0700757
758 VDBG (1, "VCL<%d>: mapped new segment '%s' size %d", getpid (),
759 mp->segment_name, mp->segment_size);
Dave Wallace543852a2017-08-03 02:11:34 -0400760}
761
762static void
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -0800763vl_api_unmap_segment_t_handler (vl_api_unmap_segment_t * mp)
764{
765
766/*
767 * XXX Need segment_name to session_id hash,
768 * XXX - have sessionID by handle hash currently
769 */
Florin Coras0d427d82018-06-27 03:24:07 -0700770
771 VDBG (1, "Unmapped segment '%s'", mp->segment_name);
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -0800772}
773
774static void
Dave Wallace543852a2017-08-03 02:11:34 -0400775vl_api_disconnect_session_t_handler (vl_api_disconnect_session_t * mp)
776{
Dave Wallace543852a2017-08-03 02:11:34 -0400777 uword *p;
Dave Wallace543852a2017-08-03 02:11:34 -0400778
779 p = hash_get (vcm->session_index_by_vpp_handles, mp->handle);
780 if (p)
781 {
Dave Wallace4878cbe2017-11-21 03:45:09 -0500782 int rv;
783 session_t *session = 0;
784 u32 session_index = p[0];
785
Dave Wallace7e607a72018-06-18 18:41:32 -0400786 VCL_SESSION_LOCK_AND_GET (session_index, &session);
Dave Wallace4878cbe2017-11-21 03:45:09 -0500787 session->state = STATE_CLOSE_ON_EMPTY;
788
Florin Coras0d427d82018-06-27 03:24:07 -0700789 VDBG (1, "VCL<%d>: vpp handle 0x%llx, sid %u: setting state to 0x%x "
790 "(%s)", getpid (), mp->handle, session_index, session->state,
791 vppcom_session_state_str (session->state));
Dave Wallace7e607a72018-06-18 18:41:32 -0400792 VCL_SESSION_UNLOCK ();
Dave Wallace4878cbe2017-11-21 03:45:09 -0500793 return;
794
795 done:
Florin Coras0d427d82018-06-27 03:24:07 -0700796 VDBG (1, "VCL<%d>: vpp handle 0x%llx, sid %u: session lookup failed!",
797 getpid (), mp->handle, session_index);
Dave Wallace543852a2017-08-03 02:11:34 -0400798 }
799 else
Dave Wallace048b1d62018-01-03 22:24:41 -0500800 clib_warning ("VCL<%d>: vpp handle 0x%llx: session lookup by "
Dave Wallace4878cbe2017-11-21 03:45:09 -0500801 "handle failed!", getpid (), mp->handle);
Dave Wallace543852a2017-08-03 02:11:34 -0400802}
803
804static void
805vl_api_reset_session_t_handler (vl_api_reset_session_t * mp)
806{
Dave Wallace543852a2017-08-03 02:11:34 -0400807 session_t *session = 0;
808 vl_api_reset_session_reply_t *rmp;
809 uword *p;
810 int rv = 0;
811
812 p = hash_get (vcm->session_index_by_vpp_handles, mp->handle);
813 if (p)
814 {
815 int rval;
Dave Wallace7e607a72018-06-18 18:41:32 -0400816 VCL_SESSION_LOCK ();
Dave Wallace543852a2017-08-03 02:11:34 -0400817 rval = vppcom_session_at_index (p[0], &session);
818 if (PREDICT_FALSE (rval))
819 {
Dave Wallace4878cbe2017-11-21 03:45:09 -0500820 rv = VNET_API_ERROR_INVALID_VALUE_2;
Dave Wallace048b1d62018-01-03 22:24:41 -0500821 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -0500822 "session lookup failed! returning %d %U",
823 getpid (), mp->handle, p[0],
824 rv, format_api_error, rv);
Dave Wallace543852a2017-08-03 02:11:34 -0400825 }
826 else
Dave Wallace4878cbe2017-11-21 03:45:09 -0500827 {
828 /* TBD: should this disconnect immediately and
829 * flush the fifos?
830 */
831 session->state = STATE_CLOSE_ON_EMPTY;
832
Florin Coras0d427d82018-06-27 03:24:07 -0700833 VDBG (1, "VCL<%d>: vpp handle 0x%llx, sid %u: state set to %d "
834 "(%s)!", getpid (), mp->handle, p[0], session->state,
835 vppcom_session_state_str (session->state));
Dave Wallace4878cbe2017-11-21 03:45:09 -0500836 }
Dave Wallace7e607a72018-06-18 18:41:32 -0400837 VCL_SESSION_UNLOCK ();
Dave Wallace543852a2017-08-03 02:11:34 -0400838 }
839 else
840 {
Dave Wallace4878cbe2017-11-21 03:45:09 -0500841 rv = VNET_API_ERROR_INVALID_VALUE;
Dave Wallace048b1d62018-01-03 22:24:41 -0500842 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx: session lookup "
Dave Wallace4878cbe2017-11-21 03:45:09 -0500843 "failed! returning %d %U",
844 getpid (), mp->handle, rv, format_api_error, rv);
Dave Wallace543852a2017-08-03 02:11:34 -0400845 }
846
847 rmp = vl_msg_api_alloc (sizeof (*rmp));
848 memset (rmp, 0, sizeof (*rmp));
849 rmp->_vl_msg_id = ntohs (VL_API_RESET_SESSION_REPLY);
850 rmp->retval = htonl (rv);
851 rmp->handle = mp->handle;
852 vl_msg_api_send_shmem (vcm->vl_input_queue, (u8 *) & rmp);
853}
854
855static void
Dave Wallace33e002b2017-09-06 01:20:02 -0400856vl_api_connect_session_reply_t_handler (vl_api_connect_session_reply_t * mp)
Dave Wallace543852a2017-08-03 02:11:34 -0400857{
Dave Wallaceee45d412017-11-24 21:44:06 -0500858 session_t *session = 0;
Dave Wallace543852a2017-08-03 02:11:34 -0400859 u32 session_index;
860 svm_fifo_t *rx_fifo, *tx_fifo;
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -0800861 int rv = VPPCOM_OK;
Dave Wallace543852a2017-08-03 02:11:34 -0400862
Dave Wallace4878cbe2017-11-21 03:45:09 -0500863 session_index = mp->context;
Dave Wallace7e607a72018-06-18 18:41:32 -0400864 VCL_SESSION_LOCK_AND_GET (session_index, &session);
Dave Wallaceee45d412017-11-24 21:44:06 -0500865done:
Dave Wallace543852a2017-08-03 02:11:34 -0400866 if (mp->retval)
867 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500868 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -0500869 "connect failed! %U",
870 getpid (), mp->handle, session_index,
871 format_api_error, ntohl (mp->retval));
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -0800872 if (session)
Dave Wallaceee45d412017-11-24 21:44:06 -0500873 {
874 session->state = STATE_FAILED;
875 session->vpp_handle = mp->handle;
876 }
877 else
878 {
879 clib_warning ("[%s] ERROR: vpp handle 0x%llx, sid %u: "
880 "Invalid session index (%u)!",
881 getpid (), mp->handle, session_index);
882 }
883 goto done_unlock;
Dave Wallace543852a2017-08-03 02:11:34 -0400884 }
885
Dave Wallaceee45d412017-11-24 21:44:06 -0500886 if (rv)
887 goto done_unlock;
Dave Wallace543852a2017-08-03 02:11:34 -0400888
Dave Wallace543852a2017-08-03 02:11:34 -0400889 /*
890 * Setup session
891 */
Keith Burns (alagalah)410bcca2018-03-23 13:42:49 -0700892 if (vcm->session_io_thread.io_sessions_lockp)
893 {
894 // Add this connection to the active io sessions list
Dave Wallace7e607a72018-06-18 18:41:32 -0400895 VCL_IO_SESSIONS_LOCK ();
Keith Burns (alagalah)410bcca2018-03-23 13:42:49 -0700896 u32 *active_session_index;
897 pool_get (vcm->session_io_thread.active_session_indexes,
898 active_session_index);
899 *active_session_index = session_index;
Dave Wallace7e607a72018-06-18 18:41:32 -0400900 VCL_IO_SESSIONS_UNLOCK ();
Keith Burns (alagalah)410bcca2018-03-23 13:42:49 -0700901 }
Dave Wallace33e002b2017-09-06 01:20:02 -0400902 session->vpp_event_queue = uword_to_pointer (mp->vpp_event_queue_address,
Florin Corase86a8ed2018-01-05 03:20:25 -0800903 svm_queue_t *);
Dave Wallace543852a2017-08-03 02:11:34 -0400904
905 rx_fifo = uword_to_pointer (mp->server_rx_fifo, svm_fifo_t *);
906 rx_fifo->client_session_index = session_index;
907 tx_fifo = uword_to_pointer (mp->server_tx_fifo, svm_fifo_t *);
908 tx_fifo->client_session_index = session_index;
909
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -0800910 session->rx_fifo = rx_fifo;
911 session->tx_fifo = tx_fifo;
Dave Wallace60caa062017-11-10 17:07:13 -0500912 session->vpp_handle = mp->handle;
Dave Wallace9d1d73a2017-11-20 02:31:48 -0500913 session->lcl_addr.is_ip4 = mp->is_ip4;
914 clib_memcpy (&session->lcl_addr.ip46, mp->lcl_ip,
915 sizeof (session->peer_addr.ip46));
916 session->lcl_port = mp->lcl_port;
Dave Wallace543852a2017-08-03 02:11:34 -0400917 session->state = STATE_CONNECT;
918
919 /* Add it to lookup table */
920 hash_set (vcm->session_index_by_vpp_handles, mp->handle, session_index);
Dave Wallace60caa062017-11-10 17:07:13 -0500921
Florin Coras0d427d82018-06-27 03:24:07 -0700922 VDBG (1, "VCL<%d>: vpp handle 0x%llx, sid %u: connect succeeded! "
923 "session_rx_fifo %p, refcnt %d, session_tx_fifo %p, refcnt %d",
924 getpid (), mp->handle, session_index, session->rx_fifo,
925 session->rx_fifo->refcnt, session->tx_fifo, session->tx_fifo->refcnt);
Dave Wallaceee45d412017-11-24 21:44:06 -0500926done_unlock:
Dave Wallace7e607a72018-06-18 18:41:32 -0400927 VCL_SESSION_UNLOCK ();
Dave Wallace543852a2017-08-03 02:11:34 -0400928}
929
930static void
931vppcom_send_connect_sock (session_t * session, u32 session_index)
932{
Dave Wallace543852a2017-08-03 02:11:34 -0400933 vl_api_connect_sock_t *cmp;
934
935 /* Assumes caller as acquired the spinlock: vcm->sessions_lockp */
Dave Wallace543852a2017-08-03 02:11:34 -0400936 cmp = vl_msg_api_alloc (sizeof (*cmp));
937 memset (cmp, 0, sizeof (*cmp));
938 cmp->_vl_msg_id = ntohs (VL_API_CONNECT_SOCK);
939 cmp->client_index = vcm->my_client_index;
Dave Wallace33e002b2017-09-06 01:20:02 -0400940 cmp->context = session_index;
Dave Wallace543852a2017-08-03 02:11:34 -0400941
Dave Wallace35830af2017-10-09 01:43:42 -0400942 cmp->is_ip4 = session->peer_addr.is_ip4;
943 clib_memcpy (cmp->ip, &session->peer_addr.ip46, sizeof (cmp->ip));
Stevenac1f96d2017-10-24 16:03:58 -0700944 cmp->port = session->peer_port;
Dave Wallace543852a2017-08-03 02:11:34 -0400945 cmp->proto = session->proto;
946 clib_memcpy (cmp->options, session->options, sizeof (cmp->options));
947 vl_msg_api_send_shmem (vcm->vl_input_queue, (u8 *) & cmp);
948}
949
Dave Wallace66cf6eb2017-10-26 02:51:07 -0400950static inline void
Dave Wallace4878cbe2017-11-21 03:45:09 -0500951vppcom_send_disconnect_session_reply (u64 vpp_handle, u32 session_index,
952 int rv)
953{
954 vl_api_disconnect_session_reply_t *rmp;
955
Florin Coras0d427d82018-06-27 03:24:07 -0700956 VDBG (1, "VCL<%d>: vpp handle 0x%llx, sid %u: sending disconnect msg",
957 getpid (), vpp_handle, session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -0500958
959 rmp = vl_msg_api_alloc (sizeof (*rmp));
960 memset (rmp, 0, sizeof (*rmp));
961
962 rmp->_vl_msg_id = ntohs (VL_API_DISCONNECT_SESSION_REPLY);
963 rmp->retval = htonl (rv);
964 rmp->handle = vpp_handle;
965 vl_msg_api_send_shmem (vcm->vl_input_queue, (u8 *) & rmp);
966}
967
968static inline void
969vppcom_send_disconnect_session (u64 vpp_handle, u32 session_index)
Dave Wallace543852a2017-08-03 02:11:34 -0400970{
Dave Wallace543852a2017-08-03 02:11:34 -0400971 vl_api_disconnect_session_t *dmp;
Dave Wallace543852a2017-08-03 02:11:34 -0400972
Florin Coras0d427d82018-06-27 03:24:07 -0700973 VDBG (1, "VCL<%d>: vpp handle 0x%llx, sid %u: sending disconnect msg",
974 getpid (), vpp_handle, session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -0500975
Dave Wallace543852a2017-08-03 02:11:34 -0400976 dmp = vl_msg_api_alloc (sizeof (*dmp));
977 memset (dmp, 0, sizeof (*dmp));
978 dmp->_vl_msg_id = ntohs (VL_API_DISCONNECT_SESSION);
979 dmp->client_index = vcm->my_client_index;
Dave Wallace4878cbe2017-11-21 03:45:09 -0500980 dmp->handle = vpp_handle;
Dave Wallace543852a2017-08-03 02:11:34 -0400981 vl_msg_api_send_shmem (vcm->vl_input_queue, (u8 *) & dmp);
Dave Wallace543852a2017-08-03 02:11:34 -0400982}
983
984static void
985vl_api_bind_sock_reply_t_handler (vl_api_bind_sock_reply_t * mp)
986{
Dave Wallace543852a2017-08-03 02:11:34 -0400987 session_t *session = 0;
Dave Wallace4878cbe2017-11-21 03:45:09 -0500988 u32 session_index = mp->context;
Dave Wallace543852a2017-08-03 02:11:34 -0400989 int rv;
990
Dave Wallace7e607a72018-06-18 18:41:32 -0400991 VCL_SESSION_LOCK_AND_GET (session_index, &session);
Dave Wallaceee45d412017-11-24 21:44:06 -0500992done:
Dave Wallace543852a2017-08-03 02:11:34 -0400993 if (mp->retval)
Dave Wallace4878cbe2017-11-21 03:45:09 -0500994 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500995 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, "
996 "sid %u: bind failed: %U",
997 getpid (), mp->handle, session_index,
998 format_api_error, ntohl (mp->retval));
Dave Wallace4878cbe2017-11-21 03:45:09 -0500999 rv = vppcom_session_at_index (session_index, &session);
1000 if (rv == VPPCOM_OK)
Dave Wallaceee45d412017-11-24 21:44:06 -05001001 {
1002 session->state = STATE_FAILED;
1003 session->vpp_handle = mp->handle;
1004 }
1005 else
1006 {
1007 clib_warning ("[%s] ERROR: vpp handle 0x%llx, sid %u: "
1008 "Invalid session index (%u)!",
1009 getpid (), mp->handle, session_index);
1010 }
1011 goto done_unlock;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001012 }
Dave Wallace543852a2017-08-03 02:11:34 -04001013
Dave Wallaceee45d412017-11-24 21:44:06 -05001014 session->vpp_handle = mp->handle;
1015 session->lcl_addr.is_ip4 = mp->lcl_is_ip4;
Dave Wallaced239f8d2018-06-19 13:37:30 -04001016 session->lcl_addr.ip46 = to_ip46 (mp->lcl_is_ip4 ? IP46_TYPE_IP4 :
1017 IP46_TYPE_IP6, mp->lcl_ip);
Dave Wallaceee45d412017-11-24 21:44:06 -05001018 session->lcl_port = mp->lcl_port;
1019 vppcom_session_table_add_listener (mp->handle, session_index);
Dave Wallaceee45d412017-11-24 21:44:06 -05001020 session->state = STATE_LISTEN;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001021
Florin Coras0d427d82018-06-27 03:24:07 -07001022 VDBG (1, "VCL<%d>: vpp handle 0x%llx, sid %u: bind succeeded!",
1023 getpid (), mp->handle, mp->context);
Dave Wallaceee45d412017-11-24 21:44:06 -05001024done_unlock:
Dave Wallace7e607a72018-06-18 18:41:32 -04001025 VCL_SESSION_UNLOCK ();
Dave Wallace543852a2017-08-03 02:11:34 -04001026}
1027
1028static void
1029vl_api_unbind_sock_reply_t_handler (vl_api_unbind_sock_reply_t * mp)
1030{
Dave Wallace4878cbe2017-11-21 03:45:09 -05001031 if (mp->retval)
Dave Wallace048b1d62018-01-03 22:24:41 -05001032 clib_warning ("VCL<%d>: ERROR: sid %u: unbind failed: %U",
Dave Wallace4878cbe2017-11-21 03:45:09 -05001033 getpid (), mp->context, format_api_error,
1034 ntohl (mp->retval));
Dave Wallace543852a2017-08-03 02:11:34 -04001035
Florin Coras0d427d82018-06-27 03:24:07 -07001036 else
1037 VDBG (1, "VCL<%d>: sid %u: unbind succeeded!", getpid (), mp->context);
Dave Wallace543852a2017-08-03 02:11:34 -04001038}
1039
1040u8 *
1041format_ip4_address (u8 * s, va_list * args)
1042{
1043 u8 *a = va_arg (*args, u8 *);
1044 return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
1045}
1046
1047u8 *
1048format_ip6_address (u8 * s, va_list * args)
1049{
1050 ip6_address_t *a = va_arg (*args, ip6_address_t *);
1051 u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
1052
1053 i_max_n_zero = ARRAY_LEN (a->as_u16);
1054 max_n_zeros = 0;
1055 i_first_zero = i_max_n_zero;
1056 n_zeros = 0;
1057 for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
1058 {
1059 u32 is_zero = a->as_u16[i] == 0;
1060 if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
1061 {
1062 i_first_zero = i;
1063 n_zeros = 0;
1064 }
1065 n_zeros += is_zero;
1066 if ((!is_zero && n_zeros > max_n_zeros)
1067 || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
1068 {
1069 i_max_n_zero = i_first_zero;
1070 max_n_zeros = n_zeros;
1071 i_first_zero = ARRAY_LEN (a->as_u16);
1072 n_zeros = 0;
1073 }
1074 }
1075
1076 last_double_colon = 0;
1077 for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
1078 {
1079 if (i == i_max_n_zero && max_n_zeros > 1)
1080 {
1081 s = format (s, "::");
1082 i += max_n_zeros - 1;
1083 last_double_colon = 1;
1084 }
1085 else
1086 {
1087 s = format (s, "%s%x",
1088 (last_double_colon || i == 0) ? "" : ":",
1089 clib_net_to_host_u16 (a->as_u16[i]));
1090 last_double_colon = 0;
1091 }
1092 }
1093
1094 return s;
1095}
1096
1097/* Format an IP46 address. */
1098u8 *
1099format_ip46_address (u8 * s, va_list * args)
1100{
1101 ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
1102 ip46_type_t type = va_arg (*args, ip46_type_t);
1103 int is_ip4 = 1;
1104
1105 switch (type)
1106 {
1107 case IP46_TYPE_ANY:
1108 is_ip4 = ip46_address_is_ip4 (ip46);
1109 break;
1110 case IP46_TYPE_IP4:
1111 is_ip4 = 1;
1112 break;
1113 case IP46_TYPE_IP6:
1114 is_ip4 = 0;
1115 break;
1116 }
1117
1118 return is_ip4 ?
1119 format (s, "%U", format_ip4_address, &ip46->ip4) :
1120 format (s, "%U", format_ip6_address, &ip46->ip6);
1121}
1122
1123static void
1124vl_api_accept_session_t_handler (vl_api_accept_session_t * mp)
1125{
Dave Wallace543852a2017-08-03 02:11:34 -04001126 svm_fifo_t *rx_fifo, *tx_fifo;
Florin Corasdcf55ce2017-11-16 15:32:50 -08001127 session_t *session, *listen_session;
Dave Wallace543852a2017-08-03 02:11:34 -04001128 u32 session_index;
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001129 vce_event_connect_request_t *ecr;
1130 vce_event_t *ev;
1131 int rv;
1132 u32 ev_idx;
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08001133 uword elts = 0;
Dave Wallace543852a2017-08-03 02:11:34 -04001134
Dave Wallace7e607a72018-06-18 18:41:32 -04001135 VCL_SESSION_LOCK ();
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08001136
Dave Wallace7e607a72018-06-18 18:41:32 -04001137 VCL_ACCEPT_FIFO_LOCK ();
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08001138 elts = clib_fifo_free_elts (vcm->client_session_index_fifo);
Dave Wallace7e607a72018-06-18 18:41:32 -04001139 VCL_ACCEPT_FIFO_UNLOCK ();
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08001140
1141 if (!elts)
Dave Wallace543852a2017-08-03 02:11:34 -04001142 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001143 clib_warning ("VCL<%d>: client session queue is full!", getpid ());
Dave Wallaced2931962017-11-25 04:17:39 -05001144 vppcom_send_accept_session_reply (mp->handle, mp->context,
Florin Corasdcf55ce2017-11-16 15:32:50 -08001145 VNET_API_ERROR_QUEUE_FULL);
Dave Wallace7e607a72018-06-18 18:41:32 -04001146 VCL_SESSION_UNLOCK ();
Florin Corasdcf55ce2017-11-16 15:32:50 -08001147 return;
1148 }
1149
1150 listen_session = vppcom_session_table_lookup_listener (mp->listener_handle);
1151 if (!listen_session)
1152 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001153 clib_warning ("VCL<%d>: ERROR: couldn't find listen session: "
1154 "unknown vpp listener handle %llx",
1155 getpid (), mp->listener_handle);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001156 vppcom_send_accept_session_reply (mp->handle, mp->context,
1157 VNET_API_ERROR_INVALID_ARGUMENT);
Dave Wallace7e607a72018-06-18 18:41:32 -04001158 VCL_SESSION_UNLOCK ();
Dave Wallace60caa062017-11-10 17:07:13 -05001159 return;
Dave Wallace543852a2017-08-03 02:11:34 -04001160 }
1161
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001162 /* TODO check listener depth and update */
1163 /* TODO on "child" fd close, update listener depth */
1164
Dave Wallace543852a2017-08-03 02:11:34 -04001165 /* Allocate local session and set it up */
1166 pool_get (vcm->sessions, session);
1167 memset (session, 0, sizeof (*session));
Keith Burns (alagalah)410bcca2018-03-23 13:42:49 -07001168 session_index = (u32) (session - vcm->sessions);
Dave Wallace543852a2017-08-03 02:11:34 -04001169
1170 rx_fifo = uword_to_pointer (mp->server_rx_fifo, svm_fifo_t *);
1171 rx_fifo->client_session_index = session_index;
1172 tx_fifo = uword_to_pointer (mp->server_tx_fifo, svm_fifo_t *);
1173 tx_fifo->client_session_index = session_index;
1174
Dave Wallace60caa062017-11-10 17:07:13 -05001175 session->vpp_handle = mp->handle;
Dave Wallaced2931962017-11-25 04:17:39 -05001176 session->client_context = mp->context;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001177 session->rx_fifo = rx_fifo;
1178 session->tx_fifo = tx_fifo;
Dave Wallace33e002b2017-09-06 01:20:02 -04001179 session->vpp_event_queue = uword_to_pointer (mp->vpp_event_queue_address,
Florin Corase86a8ed2018-01-05 03:20:25 -08001180 svm_queue_t *);
Dave Wallace543852a2017-08-03 02:11:34 -04001181 session->state = STATE_ACCEPT;
Stevenac1f96d2017-10-24 16:03:58 -07001182 session->peer_port = mp->port;
Dave Wallace35830af2017-10-09 01:43:42 -04001183 session->peer_addr.is_ip4 = mp->is_ip4;
Dave Wallaced239f8d2018-06-19 13:37:30 -04001184 session->peer_addr.ip46 = to_ip46 (mp->is_ip4 ? IP46_TYPE_IP4 :
1185 IP46_TYPE_IP6, mp->ip);
Dave Wallace543852a2017-08-03 02:11:34 -04001186
1187 /* Add it to lookup table */
1188 hash_set (vcm->session_index_by_vpp_handles, mp->handle, session_index);
Florin Corasdcf55ce2017-11-16 15:32:50 -08001189 session->lcl_port = listen_session->lcl_port;
1190 session->lcl_addr = listen_session->lcl_addr;
Dave Wallace227867f2017-11-13 21:21:53 -05001191
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001192 /* Create an event for handlers */
1193
Dave Wallace7e607a72018-06-18 18:41:32 -04001194 VCL_EVENTS_LOCK ();
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001195
1196 pool_get (vcm->event_thread.vce_events, ev);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001197 ev_idx = (u32) (ev - vcm->event_thread.vce_events);
Keith Burns (alagalah)410bcca2018-03-23 13:42:49 -07001198 ecr = vce_get_event_data (ev, sizeof (*ecr));
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001199 ev->evk.eid = VCL_EVENT_CONNECT_REQ_ACCEPTED;
1200 listen_session = vppcom_session_table_lookup_listener (mp->listener_handle);
1201 ev->evk.session_index = (u32) (listen_session - vcm->sessions);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001202 ecr->accepted_session_index = session_index;
1203
Dave Wallace7e607a72018-06-18 18:41:32 -04001204 VCL_EVENTS_UNLOCK ();
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001205
1206 rv = vce_generate_event (&vcm->event_thread, ev_idx);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001207 ASSERT (rv == 0);
Florin Corasdcf55ce2017-11-16 15:32:50 -08001208
Florin Coras0d427d82018-06-27 03:24:07 -07001209 VDBG (1, "VCL<%d>: vpp handle 0x%llx, sid %u: client accept request from %s"
1210 " address %U port %d queue %p!", getpid (), mp->handle, session_index,
1211 mp->is_ip4 ? "IPv4" : "IPv6", format_ip46_address, &mp->ip,
1212 mp->is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6,
1213 clib_net_to_host_u16 (mp->port), session->vpp_event_queue);
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08001214
Florin Coras0d427d82018-06-27 03:24:07 -07001215 vcl_evt (VCL_EVT_ACCEPT, session, listen_session, session_index);
Dave Wallace7e607a72018-06-18 18:41:32 -04001216 VCL_SESSION_UNLOCK ();
Dave Wallace60caa062017-11-10 17:07:13 -05001217}
1218
Keith Burns (alagalah)410bcca2018-03-23 13:42:49 -07001219/* VPP combines bind and listen as one operation. VCL manages the separation
1220 * of bind and listen locally via vppcom_session_bind() and
1221 * vppcom_session_listen() */
Dave Wallace60caa062017-11-10 17:07:13 -05001222static void
Dave Wallace4878cbe2017-11-21 03:45:09 -05001223vppcom_send_bind_sock (session_t * session, u32 session_index)
Dave Wallace543852a2017-08-03 02:11:34 -04001224{
Dave Wallace543852a2017-08-03 02:11:34 -04001225 vl_api_bind_sock_t *bmp;
1226
1227 /* Assumes caller has acquired spinlock: vcm->sessions_lockp */
Dave Wallace543852a2017-08-03 02:11:34 -04001228 bmp = vl_msg_api_alloc (sizeof (*bmp));
1229 memset (bmp, 0, sizeof (*bmp));
1230
1231 bmp->_vl_msg_id = ntohs (VL_API_BIND_SOCK);
1232 bmp->client_index = vcm->my_client_index;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001233 bmp->context = session_index;
Dave Wallace35830af2017-10-09 01:43:42 -04001234 bmp->is_ip4 = session->lcl_addr.is_ip4;
1235 clib_memcpy (bmp->ip, &session->lcl_addr.ip46, sizeof (bmp->ip));
Stevenac1f96d2017-10-24 16:03:58 -07001236 bmp->port = session->lcl_port;
Dave Wallace543852a2017-08-03 02:11:34 -04001237 bmp->proto = session->proto;
1238 clib_memcpy (bmp->options, session->options, sizeof (bmp->options));
1239 vl_msg_api_send_shmem (vcm->vl_input_queue, (u8 *) & bmp);
1240}
1241
1242static void
Dave Wallace4878cbe2017-11-21 03:45:09 -05001243vppcom_send_unbind_sock (u64 vpp_handle)
Dave Wallace543852a2017-08-03 02:11:34 -04001244{
Dave Wallace543852a2017-08-03 02:11:34 -04001245 vl_api_unbind_sock_t *ump;
Dave Wallace543852a2017-08-03 02:11:34 -04001246
1247 ump = vl_msg_api_alloc (sizeof (*ump));
1248 memset (ump, 0, sizeof (*ump));
1249
1250 ump->_vl_msg_id = ntohs (VL_API_UNBIND_SOCK);
1251 ump->client_index = vcm->my_client_index;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001252 ump->handle = vpp_handle;
Dave Wallace543852a2017-08-03 02:11:34 -04001253 vl_msg_api_send_shmem (vcm->vl_input_queue, (u8 *) & ump);
1254}
1255
1256static int
Dave Wallace543852a2017-08-03 02:11:34 -04001257vppcom_session_unbind (u32 session_index)
1258{
Dave Wallace4878cbe2017-11-21 03:45:09 -05001259 session_t *session = 0;
Dave Wallace543852a2017-08-03 02:11:34 -04001260 int rv;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001261 u64 vpp_handle;
Dave Wallace543852a2017-08-03 02:11:34 -04001262
Dave Wallace7e607a72018-06-18 18:41:32 -04001263 VCL_SESSION_LOCK_AND_GET (session_index, &session);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001264
1265 vpp_handle = session->vpp_handle;
1266 vppcom_session_table_del_listener (vpp_handle);
1267 session->vpp_handle = ~0;
1268 session->state = STATE_DISCONNECT;
1269
Dave Wallace7e607a72018-06-18 18:41:32 -04001270 VCL_SESSION_UNLOCK ();
Dave Wallace543852a2017-08-03 02:11:34 -04001271
Florin Coras0d427d82018-06-27 03:24:07 -07001272 VDBG (1, "VCL<%d>: vpp handle 0x%llx, sid %u: sending unbind msg! new state"
1273 " 0x%x (%s)", getpid (), vpp_handle, session_index, STATE_DISCONNECT,
1274 vppcom_session_state_str (STATE_DISCONNECT));
1275 vcl_evt (VCL_EVT_UNBIND, session);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001276 vppcom_send_unbind_sock (vpp_handle);
1277
1278done:
1279 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04001280}
1281
Dave Wallace66cf6eb2017-10-26 02:51:07 -04001282static inline int
Dave Wallace543852a2017-08-03 02:11:34 -04001283vppcom_session_disconnect (u32 session_index)
1284{
Dave Wallace543852a2017-08-03 02:11:34 -04001285 int rv;
Dave Wallace66cf6eb2017-10-26 02:51:07 -04001286 session_t *session;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001287 u64 vpp_handle;
1288 session_state_t state;
Dave Wallace543852a2017-08-03 02:11:34 -04001289
Dave Wallace7e607a72018-06-18 18:41:32 -04001290 VCL_SESSION_LOCK_AND_GET (session_index, &session);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001291
1292 vpp_handle = session->vpp_handle;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001293 state = session->state;
Dave Wallace7e607a72018-06-18 18:41:32 -04001294 VCL_SESSION_UNLOCK ();
Dave Wallace4878cbe2017-11-21 03:45:09 -05001295
Florin Coras0d427d82018-06-27 03:24:07 -07001296 VDBG (1, "VCL<%d>: vpp handle 0x%llx, sid %u state 0x%x (%s)", getpid (),
1297 vpp_handle, session_index, state, vppcom_session_state_str (state));
Dave Wallace66cf6eb2017-10-26 02:51:07 -04001298
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001299 if (PREDICT_FALSE (state & STATE_LISTEN))
Dave Wallace66cf6eb2017-10-26 02:51:07 -04001300 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001301 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -05001302 "Cannot disconnect a listen socket!",
1303 getpid (), vpp_handle, session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001304 rv = VPPCOM_EBADFD;
1305 goto done;
1306 }
Dave Wallace66cf6eb2017-10-26 02:51:07 -04001307
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001308 /* The peer has already initiated the close,
1309 * so send the disconnect session reply.
Dave Wallace4878cbe2017-11-21 03:45:09 -05001310 */
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001311 if (state & STATE_CLOSE_ON_EMPTY)
Dave Wallace4878cbe2017-11-21 03:45:09 -05001312 {
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001313 //XXX alagalah - Check and drain here?
1314 vppcom_send_disconnect_session_reply (vpp_handle,
1315 session_index, 0 /* rv */ );
Florin Coras0d427d82018-06-27 03:24:07 -07001316 VDBG (1, "VCL<%d>: vpp handle 0x%llx, sid %u: sending disconnect "
1317 "REPLY...", getpid (), vpp_handle, session_index);
Dave Wallace66cf6eb2017-10-26 02:51:07 -04001318 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05001319
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001320 /* Otherwise, send a disconnect session msg...
Dave Wallace4878cbe2017-11-21 03:45:09 -05001321 */
Dave Wallace66cf6eb2017-10-26 02:51:07 -04001322 else
Dave Wallace227867f2017-11-13 21:21:53 -05001323 {
Florin Coras0d427d82018-06-27 03:24:07 -07001324 VDBG (1, "VCL<%d>: vpp handle 0x%llx, sid %u: sending disconnect...",
1325 getpid (), vpp_handle, session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001326
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001327 vppcom_send_disconnect_session (vpp_handle, session_index);
Dave Wallace227867f2017-11-13 21:21:53 -05001328 }
Dave Wallace66cf6eb2017-10-26 02:51:07 -04001329
Dave Wallace4878cbe2017-11-21 03:45:09 -05001330done:
1331 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04001332}
1333
1334#define foreach_sock_msg \
1335_(SESSION_ENABLE_DISABLE_REPLY, session_enable_disable_reply) \
1336_(BIND_SOCK_REPLY, bind_sock_reply) \
1337_(UNBIND_SOCK_REPLY, unbind_sock_reply) \
1338_(ACCEPT_SESSION, accept_session) \
Dave Wallace33e002b2017-09-06 01:20:02 -04001339_(CONNECT_SESSION_REPLY, connect_session_reply) \
Dave Wallace543852a2017-08-03 02:11:34 -04001340_(DISCONNECT_SESSION, disconnect_session) \
1341_(DISCONNECT_SESSION_REPLY, disconnect_session_reply) \
1342_(RESET_SESSION, reset_session) \
1343_(APPLICATION_ATTACH_REPLY, application_attach_reply) \
1344_(APPLICATION_DETACH_REPLY, application_detach_reply) \
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001345_(MAP_ANOTHER_SEGMENT, map_another_segment) \
1346_(UNMAP_SEGMENT, unmap_segment)
Dave Wallace543852a2017-08-03 02:11:34 -04001347
1348static void
1349vppcom_api_hookup (void)
1350{
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08001351#define _(N, n) \
Dave Wallace543852a2017-08-03 02:11:34 -04001352 vl_msg_api_set_handlers(VL_API_##N, #n, \
1353 vl_api_##n##_t_handler, \
1354 vl_noop_handler, \
1355 vl_api_##n##_t_endian, \
1356 vl_api_##n##_t_print, \
1357 sizeof(vl_api_##n##_t), 1);
1358 foreach_sock_msg;
1359#undef _
1360}
1361
1362static void
1363vppcom_cfg_init (vppcom_cfg_t * vcl_cfg)
1364{
1365 ASSERT (vcl_cfg);
1366
1367 vcl_cfg->heapsize = (256ULL << 20);
Dave Wallacec8f1ee62017-11-29 22:46:32 -05001368 vcl_cfg->vpp_api_q_length = 1024;
Dave Wallace543852a2017-08-03 02:11:34 -04001369 vcl_cfg->segment_baseva = 0x200000000ULL;
1370 vcl_cfg->segment_size = (256 << 20);
1371 vcl_cfg->add_segment_size = (128 << 20);
1372 vcl_cfg->preallocated_fifo_pairs = 8;
1373 vcl_cfg->rx_fifo_size = (1 << 20);
1374 vcl_cfg->tx_fifo_size = (1 << 20);
1375 vcl_cfg->event_queue_size = 2048;
1376 vcl_cfg->listen_queue_size = CLIB_CACHE_LINE_BYTES / sizeof (u32);
1377 vcl_cfg->app_timeout = 10 * 60.0;
1378 vcl_cfg->session_timeout = 10 * 60.0;
1379 vcl_cfg->accept_timeout = 60.0;
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -08001380 vcl_cfg->event_ring_size = (128 << 10);
1381 vcl_cfg->event_log_path = "/dev/shm";
Dave Wallace543852a2017-08-03 02:11:34 -04001382}
1383
1384static void
1385vppcom_cfg_heapsize (char *conf_fname)
1386{
Dave Wallace543852a2017-08-03 02:11:34 -04001387 vppcom_cfg_t *vcl_cfg = &vcm->cfg;
1388 FILE *fp;
1389 char inbuf[4096];
1390 int argc = 1;
1391 char **argv = NULL;
1392 char *arg = NULL;
1393 char *p;
1394 int i;
1395 u8 *sizep;
1396 u32 size;
Dave Wallace2e005bb2017-11-07 01:21:39 -05001397 void *vcl_mem;
1398 void *heap;
Dave Wallace543852a2017-08-03 02:11:34 -04001399
1400 fp = fopen (conf_fname, "r");
1401 if (fp == NULL)
1402 {
Florin Coras0d427d82018-06-27 03:24:07 -07001403 VDBG (0, "VCL<%d>: using default heapsize %lld (0x%llx)", getpid (),
1404 vcl_cfg->heapsize, vcl_cfg->heapsize);
Dave Wallace543852a2017-08-03 02:11:34 -04001405 goto defaulted;
1406 }
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05001407
Dave Wallace543852a2017-08-03 02:11:34 -04001408 argv = calloc (1, sizeof (char *));
1409 if (argv == NULL)
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05001410 {
Florin Coras0d427d82018-06-27 03:24:07 -07001411 VDBG (0, "VCL<%d>: calloc failed, using default heapsize %lld (0x%llx)",
1412 getpid (), vcl_cfg->heapsize, vcl_cfg->heapsize);
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05001413 goto defaulted;
1414 }
Dave Wallace543852a2017-08-03 02:11:34 -04001415
1416 while (1)
1417 {
1418 if (fgets (inbuf, 4096, fp) == 0)
1419 break;
1420 p = strtok (inbuf, " \t\n");
1421 while (p != NULL)
1422 {
1423 if (*p == '#')
1424 break;
1425 argc++;
1426 char **tmp = realloc (argv, argc * sizeof (char *));
1427 if (tmp == NULL)
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05001428 {
Florin Coras0d427d82018-06-27 03:24:07 -07001429 VDBG (0, "VCL<%d>: realloc failed, using default heapsize %lld "
1430 "(0x%llx)", getpid (), vcl_cfg->heapsize,
1431 vcl_cfg->heapsize);
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05001432 goto defaulted;
1433 }
Dave Wallace543852a2017-08-03 02:11:34 -04001434 argv = tmp;
1435 arg = strndup (p, 1024);
1436 if (arg == NULL)
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05001437 {
Florin Coras0d427d82018-06-27 03:24:07 -07001438 VDBG (0, "VCL<%d>: strndup failed, using default heapsize %lld "
1439 "(0x%llx)", getpid (), vcl_cfg->heapsize,
1440 vcl_cfg->heapsize);
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05001441 goto defaulted;
1442 }
Dave Wallace543852a2017-08-03 02:11:34 -04001443 argv[argc - 1] = arg;
1444 p = strtok (NULL, " \t\n");
1445 }
1446 }
1447
1448 fclose (fp);
Chris Lukeab7b8d92017-09-07 07:40:13 -04001449 fp = NULL;
Dave Wallace543852a2017-08-03 02:11:34 -04001450
1451 char **tmp = realloc (argv, (argc + 1) * sizeof (char *));
1452 if (tmp == NULL)
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05001453 {
Florin Coras0d427d82018-06-27 03:24:07 -07001454 VDBG (0, "VCL<%d>: realloc failed, using default heapsize %lld "
1455 "(0x%llx)", getpid (), vcl_cfg->heapsize, vcl_cfg->heapsize);
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05001456 goto defaulted;
1457 }
Dave Wallace543852a2017-08-03 02:11:34 -04001458 argv = tmp;
1459 argv[argc] = NULL;
1460
1461 /*
1462 * Look for and parse the "heapsize" config parameter.
1463 * Manual since none of the clib infra has been bootstrapped yet.
1464 *
1465 * Format: heapsize <nn>[mM][gG]
1466 */
1467
1468 for (i = 1; i < (argc - 1); i++)
1469 {
1470 if (!strncmp (argv[i], "heapsize", 8))
1471 {
1472 sizep = (u8 *) argv[i + 1];
1473 size = 0;
1474 while (*sizep >= '0' && *sizep <= '9')
1475 {
1476 size *= 10;
1477 size += *sizep++ - '0';
1478 }
1479 if (size == 0)
1480 {
Florin Coras0d427d82018-06-27 03:24:07 -07001481 VDBG (0, "VCL<%d>: parse error '%s %s', using default "
1482 "heapsize %lld (0x%llx)", getpid (), argv[i], argv[i + 1],
1483 vcl_cfg->heapsize, vcl_cfg->heapsize);
Dave Wallace543852a2017-08-03 02:11:34 -04001484 goto defaulted;
1485 }
1486
1487 if (*sizep == 'g' || *sizep == 'G')
1488 vcl_cfg->heapsize = size << 30;
1489 else if (*sizep == 'm' || *sizep == 'M')
1490 vcl_cfg->heapsize = size << 20;
1491 else
1492 {
Florin Coras0d427d82018-06-27 03:24:07 -07001493 VDBG (0, "VCL<%d>: parse error '%s %s', using default "
1494 "heapsize %lld (0x%llx)", getpid (), argv[i], argv[i + 1],
1495 vcl_cfg->heapsize, vcl_cfg->heapsize);
Dave Wallace543852a2017-08-03 02:11:34 -04001496 goto defaulted;
1497 }
1498 }
1499 }
1500
1501defaulted:
Chris Lukeab7b8d92017-09-07 07:40:13 -04001502 if (fp != NULL)
1503 fclose (fp);
1504 if (argv != NULL)
1505 free (argv);
Dave Wallacee7fa24e2017-11-07 13:07:44 -05001506
Dave Wallace2e005bb2017-11-07 01:21:39 -05001507 vcl_mem = mmap (0, vcl_cfg->heapsize, PROT_READ | PROT_WRITE,
1508 MAP_SHARED | MAP_ANONYMOUS, -1, 0);
Steven0cdd5bd2017-11-08 14:14:45 -08001509 if (vcl_mem == MAP_FAILED)
Dave Wallacee7fa24e2017-11-07 13:07:44 -05001510 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001511 clib_unix_error ("VCL<%d>: ERROR: mmap(0, %lld == 0x%llx, "
Dave Wallacee7fa24e2017-11-07 13:07:44 -05001512 "PROT_READ | PROT_WRITE,MAP_SHARED | MAP_ANONYMOUS, "
1513 "-1, 0) failed!",
1514 getpid (), vcl_cfg->heapsize, vcl_cfg->heapsize);
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05001515 ASSERT (vcl_mem != MAP_FAILED);
Dave Wallacee7fa24e2017-11-07 13:07:44 -05001516 return;
1517 }
Dave Wallace2e005bb2017-11-07 01:21:39 -05001518 heap = clib_mem_init (vcl_mem, vcl_cfg->heapsize);
1519 if (!heap)
Dave Wallace2e005bb2017-11-07 01:21:39 -05001520 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001521 clib_warning ("VCL<%d>: ERROR: clib_mem_init() failed!", getpid ());
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05001522 ASSERT (heap);
Dave Wallacee7fa24e2017-11-07 13:07:44 -05001523 return;
Dave Wallace2e005bb2017-11-07 01:21:39 -05001524 }
Dave Wallacee7fa24e2017-11-07 13:07:44 -05001525 vcl_mem = clib_mem_alloc (sizeof (_vppcom_main));
1526 if (!vcl_mem)
1527 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001528 clib_warning ("VCL<%d>: ERROR: clib_mem_alloc() failed!", getpid ());
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05001529 ASSERT (vcl_mem);
Dave Wallacee7fa24e2017-11-07 13:07:44 -05001530 return;
1531 }
1532
1533 clib_memcpy (vcl_mem, &_vppcom_main, sizeof (_vppcom_main));
1534 vcm = vcl_mem;
1535
Florin Coras0d427d82018-06-27 03:24:07 -07001536 VDBG (0, "VCL<%d>: allocated VCL heap = %p, size %lld (0x%llx)", getpid (),
1537 heap, vcl_cfg->heapsize, vcl_cfg->heapsize);
Dave Wallace543852a2017-08-03 02:11:34 -04001538}
1539
1540static void
1541vppcom_cfg_read (char *conf_fname)
1542{
Dave Wallace543852a2017-08-03 02:11:34 -04001543 vppcom_cfg_t *vcl_cfg = &vcm->cfg;
1544 int fd;
1545 unformat_input_t _input, *input = &_input;
1546 unformat_input_t _line_input, *line_input = &_line_input;
1547 u8 vc_cfg_input = 0;
1548 u8 *chroot_path;
1549 struct stat s;
Dave Wallacec8f1ee62017-11-29 22:46:32 -05001550 u32 uid, gid, q_len;
Dave Wallace543852a2017-08-03 02:11:34 -04001551
1552 fd = open (conf_fname, O_RDONLY);
1553 if (fd < 0)
1554 {
Florin Coras0d427d82018-06-27 03:24:07 -07001555 VDBG (0, "VCL<%d>: using default configuration.", getpid (),
1556 conf_fname);
Dave Wallace543852a2017-08-03 02:11:34 -04001557 goto file_done;
1558 }
1559
1560 if (fstat (fd, &s) < 0)
1561 {
Florin Coras0d427d82018-06-27 03:24:07 -07001562 VDBG (0, "VCL<%d>: failed to stat `%s', using default configuration",
1563 getpid (), conf_fname);
Dave Wallace543852a2017-08-03 02:11:34 -04001564 goto file_done;
1565 }
1566
1567 if (!(S_ISREG (s.st_mode) || S_ISLNK (s.st_mode)))
1568 {
Florin Coras0d427d82018-06-27 03:24:07 -07001569 VDBG (0, "VCL<%d>: not a regular file `%s', using default "
1570 "configuration", getpid (), conf_fname);
Dave Wallace543852a2017-08-03 02:11:34 -04001571 goto file_done;
1572 }
1573
Dave Barach59b25652017-09-10 15:04:27 -04001574 unformat_init_clib_file (input, fd);
Dave Wallace543852a2017-08-03 02:11:34 -04001575
1576 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1577 {
Chris Lukeb2bcad62017-09-18 08:51:22 -04001578 (void) unformat_user (input, unformat_line_input, line_input);
Dave Wallace543852a2017-08-03 02:11:34 -04001579 unformat_skip_white_space (line_input);
1580
Dave Wallace8af20542017-10-26 03:29:30 -04001581 if (unformat (line_input, "vcl {"))
Dave Wallace543852a2017-08-03 02:11:34 -04001582 {
1583 vc_cfg_input = 1;
1584 continue;
1585 }
1586
1587 if (vc_cfg_input)
1588 {
1589 if (unformat (line_input, "heapsize %s", &chroot_path))
1590 {
1591 vec_terminate_c_string (chroot_path);
Florin Coras0d427d82018-06-27 03:24:07 -07001592 VDBG (0, "VCL<%d>: configured heapsize %s, actual heapsize %lld"
1593 " (0x%llx)", getpid (), chroot_path, vcl_cfg->heapsize,
1594 vcl_cfg->heapsize);
Dave Wallace543852a2017-08-03 02:11:34 -04001595 vec_free (chroot_path);
1596 }
1597 else if (unformat (line_input, "api-prefix %s", &chroot_path))
1598 {
1599 vec_terminate_c_string (chroot_path);
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05001600 if (vcl_cfg->vpp_api_filename)
1601 vec_free (vcl_cfg->vpp_api_filename);
1602 vcl_cfg->vpp_api_filename = format (0, "/%s-vpe-api%c",
1603 chroot_path, 0);
Dave Wallace543852a2017-08-03 02:11:34 -04001604 vl_set_memory_root_path ((char *) chroot_path);
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05001605
Florin Coras0d427d82018-06-27 03:24:07 -07001606 VDBG (0, "VCL<%d>: configured api-prefix (%s) and api filename"
1607 " (%s)", getpid (), chroot_path,
1608 vcl_cfg->vpp_api_filename);
Dave Wallace543852a2017-08-03 02:11:34 -04001609 chroot_path = 0; /* Don't vec_free() it! */
1610 }
Dave Wallacec8f1ee62017-11-29 22:46:32 -05001611 else if (unformat (line_input, "vpp-api-q-length %d", &q_len))
1612 {
1613 if (q_len < vcl_cfg->vpp_api_q_length)
1614 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001615 clib_warning ("VCL<%d>: ERROR: configured vpp-api-q-length "
Dave Wallacec8f1ee62017-11-29 22:46:32 -05001616 "(%u) is too small! Using default: %u ",
1617 getpid (), q_len, vcl_cfg->vpp_api_q_length);
1618 }
1619 else
1620 {
1621 vcl_cfg->vpp_api_q_length = q_len;
1622
Florin Coras0d427d82018-06-27 03:24:07 -07001623 VDBG (0, "VCL<%d>: configured vpp-api-q-length %u",
1624 getpid (), vcl_cfg->vpp_api_q_length);
Dave Wallacec8f1ee62017-11-29 22:46:32 -05001625 }
1626 }
Dave Wallace543852a2017-08-03 02:11:34 -04001627 else if (unformat (line_input, "uid %d", &uid))
1628 {
1629 vl_set_memory_uid (uid);
Florin Coras0d427d82018-06-27 03:24:07 -07001630 VDBG (0, "VCL<%d>: configured uid %d", getpid (), uid);
Dave Wallace543852a2017-08-03 02:11:34 -04001631 }
1632 else if (unformat (line_input, "gid %d", &gid))
1633 {
1634 vl_set_memory_gid (gid);
Florin Coras0d427d82018-06-27 03:24:07 -07001635 VDBG (0, "VCL<%d>: configured gid %d", getpid (), gid);
Dave Wallace543852a2017-08-03 02:11:34 -04001636 }
Dave Wallace8af20542017-10-26 03:29:30 -04001637 else if (unformat (line_input, "segment-baseva 0x%lx",
Dave Wallace543852a2017-08-03 02:11:34 -04001638 &vcl_cfg->segment_baseva))
1639 {
Florin Coras0d427d82018-06-27 03:24:07 -07001640 VDBG (0, "VCL<%d>: configured segment_baseva 0x%lx", getpid (),
1641 vcl_cfg->segment_baseva);
Dave Wallace543852a2017-08-03 02:11:34 -04001642 }
1643 else if (unformat (line_input, "segment-size 0x%lx",
1644 &vcl_cfg->segment_size))
1645 {
Florin Coras0d427d82018-06-27 03:24:07 -07001646 VDBG (0, "VCL<%d>: configured segment_size 0x%lx (%ld)",
1647 getpid (), vcl_cfg->segment_size, vcl_cfg->segment_size);
Dave Wallace543852a2017-08-03 02:11:34 -04001648 }
1649 else if (unformat (line_input, "segment-size %ld",
1650 &vcl_cfg->segment_size))
1651 {
Florin Coras0d427d82018-06-27 03:24:07 -07001652 VDBG (0, "VCL<%d>: configured segment_size %ld (0x%lx)",
1653 getpid (), vcl_cfg->segment_size, vcl_cfg->segment_size);
Dave Wallace543852a2017-08-03 02:11:34 -04001654 }
1655 else if (unformat (line_input, "add-segment-size 0x%lx",
1656 &vcl_cfg->add_segment_size))
1657 {
Florin Coras0d427d82018-06-27 03:24:07 -07001658 VDBG (0, "VCL<%d>: configured add_segment_size 0x%lx (%ld)",
1659 getpid (), vcl_cfg->add_segment_size,
1660 vcl_cfg->add_segment_size);
Dave Wallace543852a2017-08-03 02:11:34 -04001661 }
1662 else if (unformat (line_input, "add-segment-size %ld",
1663 &vcl_cfg->add_segment_size))
1664 {
Florin Coras0d427d82018-06-27 03:24:07 -07001665 VDBG (0, "VCL<%d>: configured add_segment_size %ld (0x%lx)",
1666 getpid (), vcl_cfg->add_segment_size,
1667 vcl_cfg->add_segment_size);
Dave Wallace543852a2017-08-03 02:11:34 -04001668 }
1669 else if (unformat (line_input, "preallocated-fifo-pairs %d",
1670 &vcl_cfg->preallocated_fifo_pairs))
1671 {
Florin Coras0d427d82018-06-27 03:24:07 -07001672 VDBG (0, "VCL<%d>: configured preallocated_fifo_pairs %d "
1673 "(0x%x)", getpid (), vcl_cfg->preallocated_fifo_pairs,
1674 vcl_cfg->preallocated_fifo_pairs);
Dave Wallace543852a2017-08-03 02:11:34 -04001675 }
1676 else if (unformat (line_input, "rx-fifo-size 0x%lx",
1677 &vcl_cfg->rx_fifo_size))
1678 {
Florin Coras0d427d82018-06-27 03:24:07 -07001679 VDBG (0, "VCL<%d>: configured rx_fifo_size 0x%lx (%ld)",
1680 getpid (), vcl_cfg->rx_fifo_size, vcl_cfg->rx_fifo_size);
Dave Wallace543852a2017-08-03 02:11:34 -04001681 }
1682 else if (unformat (line_input, "rx-fifo-size %ld",
1683 &vcl_cfg->rx_fifo_size))
1684 {
Florin Coras0d427d82018-06-27 03:24:07 -07001685 VDBG (0, "VCL<%d>: configured rx_fifo_size %ld (0x%lx)",
1686 getpid (), vcl_cfg->rx_fifo_size, vcl_cfg->rx_fifo_size);
Dave Wallace543852a2017-08-03 02:11:34 -04001687 }
1688 else if (unformat (line_input, "tx-fifo-size 0x%lx",
1689 &vcl_cfg->tx_fifo_size))
1690 {
Florin Coras0d427d82018-06-27 03:24:07 -07001691 VDBG (0, "VCL<%d>: configured tx_fifo_size 0x%lx (%ld)",
1692 getpid (), vcl_cfg->tx_fifo_size, vcl_cfg->tx_fifo_size);
Dave Wallace543852a2017-08-03 02:11:34 -04001693 }
1694 else if (unformat (line_input, "tx-fifo-size %ld",
1695 &vcl_cfg->tx_fifo_size))
1696 {
Florin Coras0d427d82018-06-27 03:24:07 -07001697 VDBG (0, "VCL<%d>: configured tx_fifo_size %ld (0x%lx)",
1698 getpid (), vcl_cfg->tx_fifo_size, vcl_cfg->tx_fifo_size);
Dave Wallace543852a2017-08-03 02:11:34 -04001699 }
1700 else if (unformat (line_input, "event-queue-size 0x%lx",
1701 &vcl_cfg->event_queue_size))
1702 {
Florin Coras0d427d82018-06-27 03:24:07 -07001703 VDBG (0, "VCL<%d>: configured event_queue_size 0x%lx (%ld)",
1704 getpid (), vcl_cfg->event_queue_size,
1705 vcl_cfg->event_queue_size);
Dave Wallace543852a2017-08-03 02:11:34 -04001706 }
1707 else if (unformat (line_input, "event-queue-size %ld",
1708 &vcl_cfg->event_queue_size))
1709 {
Florin Coras0d427d82018-06-27 03:24:07 -07001710 VDBG (0, "VCL<%d>: configured event_queue_size %ld (0x%lx)",
1711 getpid (), vcl_cfg->event_queue_size,
1712 vcl_cfg->event_queue_size);
Dave Wallace543852a2017-08-03 02:11:34 -04001713 }
1714 else if (unformat (line_input, "listen-queue-size 0x%lx",
1715 &vcl_cfg->listen_queue_size))
1716 {
Florin Coras0d427d82018-06-27 03:24:07 -07001717 VDBG (0, "VCL<%d>: configured listen_queue_size 0x%lx (%ld)",
1718 getpid (), vcl_cfg->listen_queue_size,
1719 vcl_cfg->listen_queue_size);
Dave Wallace543852a2017-08-03 02:11:34 -04001720 }
1721 else if (unformat (line_input, "listen-queue-size %ld",
1722 &vcl_cfg->listen_queue_size))
1723 {
Florin Coras0d427d82018-06-27 03:24:07 -07001724 VDBG (0, "VCL<%d>: configured listen_queue_size %ld (0x%lx)",
1725 getpid (), vcl_cfg->listen_queue_size,
1726 vcl_cfg->listen_queue_size);
Dave Wallace543852a2017-08-03 02:11:34 -04001727 }
1728 else if (unformat (line_input, "app-timeout %f",
1729 &vcl_cfg->app_timeout))
1730 {
Florin Coras0d427d82018-06-27 03:24:07 -07001731 VDBG (0, "VCL<%d>: configured app_timeout %f",
1732 getpid (), vcl_cfg->app_timeout);
Dave Wallace543852a2017-08-03 02:11:34 -04001733 }
1734 else if (unformat (line_input, "session-timeout %f",
1735 &vcl_cfg->session_timeout))
1736 {
Florin Coras0d427d82018-06-27 03:24:07 -07001737 VDBG (0, "VCL<%d>: configured session_timeout %f",
1738 getpid (), vcl_cfg->session_timeout);
Dave Wallace543852a2017-08-03 02:11:34 -04001739 }
1740 else if (unformat (line_input, "accept-timeout %f",
1741 &vcl_cfg->accept_timeout))
1742 {
Florin Coras0d427d82018-06-27 03:24:07 -07001743 VDBG (0, "VCL<%d>: configured accept_timeout %f",
1744 getpid (), vcl_cfg->accept_timeout);
Dave Wallace543852a2017-08-03 02:11:34 -04001745 }
Dave Wallace774169b2017-11-01 20:07:40 -04001746 else if (unformat (line_input, "app-proxy-transport-tcp"))
Dave Wallace8af20542017-10-26 03:29:30 -04001747 {
Dave Wallace774169b2017-11-01 20:07:40 -04001748 vcl_cfg->app_proxy_transport_tcp = 1;
Florin Coras0d427d82018-06-27 03:24:07 -07001749 VDBG (0, "VCL<%d>: configured app_proxy_transport_tcp (%d)",
1750 getpid (), vcl_cfg->app_proxy_transport_tcp);
Dave Wallace8af20542017-10-26 03:29:30 -04001751 }
Dave Wallace774169b2017-11-01 20:07:40 -04001752 else if (unformat (line_input, "app-proxy-transport-udp"))
Dave Wallace8af20542017-10-26 03:29:30 -04001753 {
Dave Wallace774169b2017-11-01 20:07:40 -04001754 vcl_cfg->app_proxy_transport_udp = 1;
Florin Coras0d427d82018-06-27 03:24:07 -07001755 VDBG (0, "VCL<%d>: configured app_proxy_transport_udp (%d)",
1756 getpid (), vcl_cfg->app_proxy_transport_udp);
Dave Wallace8af20542017-10-26 03:29:30 -04001757 }
Dave Wallace774169b2017-11-01 20:07:40 -04001758 else if (unformat (line_input, "app-scope-local"))
Dave Wallace8af20542017-10-26 03:29:30 -04001759 {
Dave Wallace774169b2017-11-01 20:07:40 -04001760 vcl_cfg->app_scope_local = 1;
Florin Coras0d427d82018-06-27 03:24:07 -07001761 VDBG (0, "VCL<%d>: configured app_scope_local (%d)",
1762 getpid (), vcl_cfg->app_scope_local);
Dave Wallace774169b2017-11-01 20:07:40 -04001763 }
1764 else if (unformat (line_input, "app-scope-global"))
1765 {
1766 vcl_cfg->app_scope_global = 1;
Florin Coras0d427d82018-06-27 03:24:07 -07001767 VDBG (0, "VCL<%d>: configured app_scope_global (%d)",
1768 getpid (), vcl_cfg->app_scope_global);
Dave Wallace8af20542017-10-26 03:29:30 -04001769 }
1770 else if (unformat (line_input, "namespace-secret %lu",
1771 &vcl_cfg->namespace_secret))
1772 {
Florin Coras0d427d82018-06-27 03:24:07 -07001773 VDBG (0, "VCL<%d>: configured namespace_secret %lu (0x%lx)",
1774 getpid (), vcl_cfg->namespace_secret,
1775 vcl_cfg->namespace_secret);
Dave Wallace8af20542017-10-26 03:29:30 -04001776 }
1777 else if (unformat (line_input, "namespace-id %v",
1778 &vcl_cfg->namespace_id))
1779 {
1780 vl_api_application_attach_t *mp;
1781 u32 max_nsid_vec_len = sizeof (mp->namespace_id) - 1;
1782 u32 nsid_vec_len = vec_len (vcl_cfg->namespace_id);
1783 if (nsid_vec_len > max_nsid_vec_len)
1784 {
1785 _vec_len (vcl_cfg->namespace_id) = max_nsid_vec_len;
Florin Coras0d427d82018-06-27 03:24:07 -07001786 VDBG (0, "VCL<%d>: configured namespace_id is too long,"
1787 " truncated to %d characters!",
1788 getpid (), max_nsid_vec_len);
Dave Wallace8af20542017-10-26 03:29:30 -04001789 }
1790
Florin Coras0d427d82018-06-27 03:24:07 -07001791 VDBG (0, "VCL<%d>: configured namespace_id %v",
1792 getpid (), vcl_cfg->namespace_id);
Dave Wallace8af20542017-10-26 03:29:30 -04001793 }
Dave Wallace543852a2017-08-03 02:11:34 -04001794 else if (unformat (line_input, "}"))
1795 {
1796 vc_cfg_input = 0;
Florin Coras0d427d82018-06-27 03:24:07 -07001797 VDBG (0, "VCL<%d>: completed parsing vppcom config!",
1798 getpid ());
Dave Wallace543852a2017-08-03 02:11:34 -04001799 goto input_done;
1800 }
1801 else
1802 {
1803 if (line_input->buffer[line_input->index] != '#')
1804 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001805 clib_warning ("VCL<%d>: Unknown vppcom config option: '%s'",
Dave Wallace2e005bb2017-11-07 01:21:39 -05001806 getpid (), (char *)
Dave Wallace543852a2017-08-03 02:11:34 -04001807 &line_input->buffer[line_input->index]);
1808 }
1809 }
1810 }
1811 }
1812
1813input_done:
1814 unformat_free (input);
1815
1816file_done:
Chris Lukeab7b8d92017-09-07 07:40:13 -04001817 if (fd >= 0)
Dave Wallace543852a2017-08-03 02:11:34 -04001818 close (fd);
1819}
1820
1821/*
1822 * VPPCOM Public API functions
1823 */
1824int
1825vppcom_app_create (char *app_name)
1826{
Dave Wallace543852a2017-08-03 02:11:34 -04001827 vppcom_cfg_t *vcl_cfg = &vcm->cfg;
1828 u8 *heap;
1829 mheap_t *h;
1830 int rv;
1831
1832 if (!vcm->init)
1833 {
1834 char *conf_fname;
Dave Wallace8af20542017-10-26 03:29:30 -04001835 char *env_var_str;
Dave Wallace543852a2017-08-03 02:11:34 -04001836
1837 vcm->init = 1;
Dave Wallace543852a2017-08-03 02:11:34 -04001838 vppcom_cfg_init (vcl_cfg);
Dave Wallace498b3a52017-11-09 13:00:34 -05001839 env_var_str = getenv (VPPCOM_ENV_DEBUG);
1840 if (env_var_str)
1841 {
1842 u32 tmp;
1843 if (sscanf (env_var_str, "%u", &tmp) != 1)
Dave Wallace69d01192018-02-22 16:22:09 -05001844 clib_warning ("VCL<%d>: WARNING: Invalid debug level specified "
1845 "in the environment variable " VPPCOM_ENV_DEBUG
Dave Wallace498b3a52017-11-09 13:00:34 -05001846 " (%s)!\n", getpid (), env_var_str);
1847 else
1848 {
1849 vcm->debug = tmp;
Florin Coras0d427d82018-06-27 03:24:07 -07001850 VDBG (0, "VCL<%d>: configured VCL debug level (%u) from "
1851 VPPCOM_ENV_DEBUG "!", getpid (), vcm->debug);
Dave Wallace498b3a52017-11-09 13:00:34 -05001852 }
1853 }
Dave Wallace8af20542017-10-26 03:29:30 -04001854 conf_fname = getenv (VPPCOM_ENV_CONF);
Dave Wallace543852a2017-08-03 02:11:34 -04001855 if (!conf_fname)
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05001856 conf_fname = VPPCOM_CONF_DEFAULT;
Dave Wallace543852a2017-08-03 02:11:34 -04001857 vppcom_cfg_heapsize (conf_fname);
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05001858 vcl_cfg = &vcm->cfg;
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08001859 clib_spinlock_init (&vcm->session_fifo_lockp);
Dave Wallace2e005bb2017-11-07 01:21:39 -05001860 clib_fifo_validate (vcm->client_session_index_fifo,
1861 vcm->cfg.listen_queue_size);
Dave Wallace543852a2017-08-03 02:11:34 -04001862 vppcom_cfg_read (conf_fname);
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05001863
Keith Burns (alagalah)410bcca2018-03-23 13:42:49 -07001864
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05001865 env_var_str = getenv (VPPCOM_ENV_API_PREFIX);
1866 if (env_var_str)
1867 {
1868 if (vcl_cfg->vpp_api_filename)
1869 vec_free (vcl_cfg->vpp_api_filename);
1870 vcl_cfg->vpp_api_filename = format (0, "/%s-vpe-api%c",
1871 env_var_str, 0);
1872 vl_set_memory_root_path ((char *) env_var_str);
1873
Florin Coras0d427d82018-06-27 03:24:07 -07001874 VDBG (0, "VCL<%d>: configured api prefix (%s) and filename (%s) "
1875 "from " VPPCOM_ENV_API_PREFIX "!",
1876 getpid (), env_var_str, vcl_cfg->vpp_api_filename);
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05001877 }
Dave Wallace8af20542017-10-26 03:29:30 -04001878 env_var_str = getenv (VPPCOM_ENV_APP_NAMESPACE_ID);
1879 if (env_var_str)
1880 {
1881 u32 ns_id_vec_len = strlen (env_var_str);
1882
1883 vec_reset_length (vcm->cfg.namespace_id);
1884 vec_validate (vcm->cfg.namespace_id, ns_id_vec_len - 1);
1885 clib_memcpy (vcm->cfg.namespace_id, env_var_str, ns_id_vec_len);
1886
Florin Coras0d427d82018-06-27 03:24:07 -07001887 VDBG (0, "VCL<%d>: configured namespace_id (%v) from "
1888 VPPCOM_ENV_APP_NAMESPACE_ID "!", getpid (),
1889 vcm->cfg.namespace_id);
Dave Wallace8af20542017-10-26 03:29:30 -04001890 }
1891 env_var_str = getenv (VPPCOM_ENV_APP_NAMESPACE_SECRET);
1892 if (env_var_str)
1893 {
1894 u64 tmp;
1895 if (sscanf (env_var_str, "%lu", &tmp) != 1)
Dave Wallace69d01192018-02-22 16:22:09 -05001896 clib_warning ("VCL<%d>: WARNING: Invalid namespace secret "
1897 "specified in the environment variable "
Dave Wallace8af20542017-10-26 03:29:30 -04001898 VPPCOM_ENV_APP_NAMESPACE_SECRET
Dave Wallace2e005bb2017-11-07 01:21:39 -05001899 " (%s)!\n", getpid (), env_var_str);
Dave Wallace8af20542017-10-26 03:29:30 -04001900 else
1901 {
1902 vcm->cfg.namespace_secret = tmp;
Florin Coras0d427d82018-06-27 03:24:07 -07001903 VDBG (0, "VCL<%d>: configured namespace secret (%lu) from "
1904 VPPCOM_ENV_APP_NAMESPACE_SECRET "!", getpid (),
1905 vcm->cfg.namespace_secret);
Dave Wallace8af20542017-10-26 03:29:30 -04001906 }
1907 }
Dave Wallace774169b2017-11-01 20:07:40 -04001908 if (getenv (VPPCOM_ENV_APP_PROXY_TRANSPORT_TCP))
Dave Wallace8af20542017-10-26 03:29:30 -04001909 {
Dave Wallace774169b2017-11-01 20:07:40 -04001910 vcm->cfg.app_proxy_transport_tcp = 1;
Florin Coras0d427d82018-06-27 03:24:07 -07001911 VDBG (0, "VCL<%d>: configured app_proxy_transport_tcp (%u) from "
1912 VPPCOM_ENV_APP_PROXY_TRANSPORT_TCP "!", getpid (),
1913 vcm->cfg.app_proxy_transport_tcp);
Dave Wallace8af20542017-10-26 03:29:30 -04001914 }
Dave Wallace774169b2017-11-01 20:07:40 -04001915 if (getenv (VPPCOM_ENV_APP_PROXY_TRANSPORT_UDP))
Dave Wallace8af20542017-10-26 03:29:30 -04001916 {
Dave Wallace774169b2017-11-01 20:07:40 -04001917 vcm->cfg.app_proxy_transport_udp = 1;
Florin Coras0d427d82018-06-27 03:24:07 -07001918 VDBG (0, "VCL<%d>: configured app_proxy_transport_udp (%u) from "
1919 VPPCOM_ENV_APP_PROXY_TRANSPORT_UDP "!", getpid (),
1920 vcm->cfg.app_proxy_transport_udp);
Dave Wallace774169b2017-11-01 20:07:40 -04001921 }
1922 if (getenv (VPPCOM_ENV_APP_SCOPE_LOCAL))
1923 {
1924 vcm->cfg.app_scope_local = 1;
Florin Coras0d427d82018-06-27 03:24:07 -07001925 VDBG (0, "VCL<%d>: configured app_scope_local (%u) from "
1926 VPPCOM_ENV_APP_SCOPE_LOCAL "!", getpid (),
1927 vcm->cfg.app_scope_local);
Dave Wallace774169b2017-11-01 20:07:40 -04001928 }
1929 if (getenv (VPPCOM_ENV_APP_SCOPE_GLOBAL))
1930 {
1931 vcm->cfg.app_scope_global = 1;
Florin Coras0d427d82018-06-27 03:24:07 -07001932 VDBG (0, "VCL<%d>: configured app_scope_global (%u) from "
1933 VPPCOM_ENV_APP_SCOPE_GLOBAL "!", getpid (),
1934 vcm->cfg.app_scope_global);
Dave Wallace8af20542017-10-26 03:29:30 -04001935 }
1936
Dave Wallace543852a2017-08-03 02:11:34 -04001937 vcm->main_cpu = os_get_thread_index ();
1938 heap = clib_mem_get_per_cpu_heap ();
1939 h = mheap_header (heap);
1940
1941 /* make the main heap thread-safe */
1942 h->flags |= MHEAP_FLAG_THREAD_SAFE;
1943
1944 vcm->session_index_by_vpp_handles = hash_create (0, sizeof (uword));
1945
1946 clib_time_init (&vcm->clib_time);
1947 vppcom_init_error_string_table ();
Florin Corasa332c462018-01-31 06:52:17 -08001948 svm_fifo_segment_main_init (vcl_cfg->segment_baseva,
1949 20 /* timeout in secs */ );
Dave Wallace543852a2017-08-03 02:11:34 -04001950 clib_spinlock_init (&vcm->sessions_lockp);
Dave Wallace543852a2017-08-03 02:11:34 -04001951 }
1952
1953 if (vcm->my_client_index == ~0)
1954 {
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001955
1956 /* API hookup and connect to VPP */
Dave Wallace048b1d62018-01-03 22:24:41 -05001957 vppcom_api_hookup ();
Florin Coras0d427d82018-06-27 03:24:07 -07001958 vcl_elog_init (vcm);
Dave Wallace543852a2017-08-03 02:11:34 -04001959 vcm->app_state = STATE_APP_START;
1960 rv = vppcom_connect_to_vpp (app_name);
1961 if (rv)
1962 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001963 clib_warning ("VCL<%d>: ERROR: couldn't connect to VPP!",
Dave Wallace2e005bb2017-11-07 01:21:39 -05001964 getpid ());
Dave Wallace543852a2017-08-03 02:11:34 -04001965 return rv;
1966 }
1967
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001968 /* State event handling thread */
1969
1970 rv = vce_start_event_thread (&(vcm->event_thread), 20);
1971
Florin Coras0d427d82018-06-27 03:24:07 -07001972 VDBG (0, "VCL<%d>: sending session enable", getpid ());
Dave Wallace543852a2017-08-03 02:11:34 -04001973
Dave Wallace048b1d62018-01-03 22:24:41 -05001974 rv = vppcom_app_session_enable ();
Dave Wallace543852a2017-08-03 02:11:34 -04001975 if (rv)
1976 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001977 clib_warning ("VCL<%d>: ERROR: vppcom_app_session_enable() "
1978 "failed!", getpid ());
Dave Wallace543852a2017-08-03 02:11:34 -04001979 return rv;
1980 }
Dave Wallace543852a2017-08-03 02:11:34 -04001981
Florin Coras0d427d82018-06-27 03:24:07 -07001982 VDBG (0, "VCL<%d>: sending app attach", getpid ());
Dave Wallace048b1d62018-01-03 22:24:41 -05001983
1984 rv = vppcom_app_attach ();
1985 if (rv)
1986 {
1987 clib_warning ("VCL<%d>: ERROR: vppcom_app_attach() failed!",
1988 getpid ());
1989 return rv;
1990 }
1991
Florin Coras0d427d82018-06-27 03:24:07 -07001992 VDBG (0, "VCL<%d>: app_name '%s', my_client_index %d (0x%x)",
1993 getpid (), app_name, vcm->my_client_index, vcm->my_client_index);
Dave Wallace66cf6eb2017-10-26 02:51:07 -04001994 }
Dave Wallace543852a2017-08-03 02:11:34 -04001995
1996 return VPPCOM_OK;
1997}
1998
1999void
2000vppcom_app_destroy (void)
2001{
Dave Wallace543852a2017-08-03 02:11:34 -04002002 int rv;
Dave Wallacede910062018-03-20 09:22:13 -04002003 f64 orig_app_timeout;
Dave Wallace543852a2017-08-03 02:11:34 -04002004
2005 if (vcm->my_client_index == ~0)
2006 return;
2007
Florin Coras0d427d82018-06-27 03:24:07 -07002008 VDBG (0, "VCL<%d>: detaching from VPP, my_client_index %d (0x%x)",
2009 getpid (), vcm->my_client_index, vcm->my_client_index);
2010 vcl_evt (VCL_EVT_DETACH, vcm);
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -08002011
Dave Wallace543852a2017-08-03 02:11:34 -04002012 vppcom_app_detach ();
Dave Wallacede910062018-03-20 09:22:13 -04002013 orig_app_timeout = vcm->cfg.app_timeout;
2014 vcm->cfg.app_timeout = 2.0;
Dave Wallace543852a2017-08-03 02:11:34 -04002015 rv = vppcom_wait_for_app_state_change (STATE_APP_ENABLED);
Dave Wallacede910062018-03-20 09:22:13 -04002016 vcm->cfg.app_timeout = orig_app_timeout;
Dave Wallace543852a2017-08-03 02:11:34 -04002017 if (PREDICT_FALSE (rv))
Florin Coras0d427d82018-06-27 03:24:07 -07002018 VDBG (0, "VCL<%d>: application detach timed out! returning %d (%s)",
2019 getpid (), rv, vppcom_retval_str (rv));
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -08002020
Florin Coras0d427d82018-06-27 03:24:07 -07002021 vcl_elog_stop (vcm);
Dave Wallace543852a2017-08-03 02:11:34 -04002022 vl_client_disconnect_from_vlib ();
2023 vcm->my_client_index = ~0;
2024 vcm->app_state = STATE_APP_START;
2025}
2026
2027int
Dave Wallacec04cbf12018-02-07 18:14:02 -05002028vppcom_session_create (u8 proto, u8 is_nonblocking)
Dave Wallace543852a2017-08-03 02:11:34 -04002029{
Dave Wallace543852a2017-08-03 02:11:34 -04002030 session_t *session;
2031 u32 session_index;
2032
Dave Wallace7e607a72018-06-18 18:41:32 -04002033 VCL_SESSION_LOCK ();
Dave Wallace543852a2017-08-03 02:11:34 -04002034 pool_get (vcm->sessions, session);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002035 memset (session, 0, sizeof (*session));
Dave Wallace543852a2017-08-03 02:11:34 -04002036 session_index = session - vcm->sessions;
2037
Dave Wallace543852a2017-08-03 02:11:34 -04002038 session->proto = proto;
2039 session->state = STATE_START;
Dave Wallace4878cbe2017-11-21 03:45:09 -05002040 session->vpp_handle = ~0;
Dave Wallace543852a2017-08-03 02:11:34 -04002041
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002042 if (is_nonblocking)
2043 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_NONBLOCK);
2044 else
2045 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_NONBLOCK);
Dave Wallace543852a2017-08-03 02:11:34 -04002046
Florin Coras0d427d82018-06-27 03:24:07 -07002047 vcl_evt (VCL_EVT_CREATE, session, proto, session->state, is_nonblocking,
2048 session_index);
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002049
Dave Wallace7e607a72018-06-18 18:41:32 -04002050 VCL_SESSION_UNLOCK ();
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002051
Florin Coras0d427d82018-06-27 03:24:07 -07002052 VDBG (0, "VCL<%d>: sid %u", getpid (), session_index);
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002053
Dave Wallace543852a2017-08-03 02:11:34 -04002054 return (int) session_index;
2055}
2056
2057int
2058vppcom_session_close (uint32_t session_index)
2059{
Dave Wallace543852a2017-08-03 02:11:34 -04002060 session_t *session = 0;
2061 int rv;
Dave Wallace66cf6eb2017-10-26 02:51:07 -04002062 u8 is_vep;
2063 u8 is_vep_session;
2064 u32 next_sid;
2065 u32 vep_idx;
Dave Wallaceee45d412017-11-24 21:44:06 -05002066 u64 vpp_handle;
Dave Wallace4878cbe2017-11-21 03:45:09 -05002067 uword *p;
Dave Wallace66cf6eb2017-10-26 02:51:07 -04002068 session_state_t state;
Dave Wallace543852a2017-08-03 02:11:34 -04002069
Dave Wallace7e607a72018-06-18 18:41:32 -04002070 VCL_SESSION_LOCK_AND_GET (session_index, &session);
Dave Wallace66cf6eb2017-10-26 02:51:07 -04002071 is_vep = session->is_vep;
2072 is_vep_session = session->is_vep_session;
2073 next_sid = session->vep.next_sid;
2074 vep_idx = session->vep.vep_idx;
2075 state = session->state;
Dave Wallaceee45d412017-11-24 21:44:06 -05002076 vpp_handle = session->vpp_handle;
Dave Wallace7e607a72018-06-18 18:41:32 -04002077 VCL_SESSION_UNLOCK ();
Dave Wallace543852a2017-08-03 02:11:34 -04002078
2079 if (VPPCOM_DEBUG > 0)
Dave Wallaceee45d412017-11-24 21:44:06 -05002080 {
2081 if (is_vep)
Dave Wallace048b1d62018-01-03 22:24:41 -05002082 clib_warning ("VCL<%d>: vep_idx %u / sid %u: "
2083 "closing epoll session...",
Dave Wallaceee45d412017-11-24 21:44:06 -05002084 getpid (), session_index, session_index);
2085 else
Dave Wallace048b1d62018-01-03 22:24:41 -05002086 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %d: "
2087 "closing session...",
Dave Wallaceee45d412017-11-24 21:44:06 -05002088 getpid (), vpp_handle, session_index);
2089 }
Dave Wallace543852a2017-08-03 02:11:34 -04002090
Dave Wallace66cf6eb2017-10-26 02:51:07 -04002091 if (is_vep)
Dave Wallace543852a2017-08-03 02:11:34 -04002092 {
Dave Wallace66cf6eb2017-10-26 02:51:07 -04002093 while (next_sid != ~0)
Dave Wallace19481612017-09-15 18:47:44 -04002094 {
Dave Wallacef7f809c2017-10-03 01:48:42 -04002095 rv = vppcom_epoll_ctl (session_index, EPOLL_CTL_DEL, next_sid, 0);
Florin Coras0d427d82018-06-27 03:24:07 -07002096 if (PREDICT_FALSE (rv < 0))
2097 VDBG (0, "VCL<%d>: vpp handle 0x%llx, sid %u: EPOLL_CTL_DEL "
2098 "vep_idx %u failed! rv %d (%s)",
2099 getpid (), vpp_handle, next_sid, vep_idx,
2100 rv, vppcom_retval_str (rv));
Dave Wallacef7f809c2017-10-03 01:48:42 -04002101
Dave Wallace7e607a72018-06-18 18:41:32 -04002102 VCL_SESSION_LOCK_AND_GET (session_index, &session);
Dave Wallace66cf6eb2017-10-26 02:51:07 -04002103 next_sid = session->vep.next_sid;
Dave Wallace7e607a72018-06-18 18:41:32 -04002104 VCL_SESSION_UNLOCK ();
Dave Wallacef7f809c2017-10-03 01:48:42 -04002105 }
2106 }
2107 else
2108 {
Dave Wallace66cf6eb2017-10-26 02:51:07 -04002109 if (is_vep_session)
Dave Wallacef7f809c2017-10-03 01:48:42 -04002110 {
Dave Wallacef7f809c2017-10-03 01:48:42 -04002111 rv = vppcom_epoll_ctl (vep_idx, EPOLL_CTL_DEL, session_index, 0);
Florin Coras0d427d82018-06-27 03:24:07 -07002112 if (rv < 0)
2113 VDBG (0, "VCL<%d>: vpp handle 0x%llx, sid %u: EPOLL_CTL_DEL "
2114 "vep_idx %u failed! rv %d (%s)",
2115 getpid (), vpp_handle, session_index,
2116 vep_idx, rv, vppcom_retval_str (rv));
Dave Wallacef7f809c2017-10-03 01:48:42 -04002117 }
2118
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002119 if (state & STATE_LISTEN)
Dave Wallacef7f809c2017-10-03 01:48:42 -04002120 {
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002121 rv = vppcom_session_unbind (session_index);
2122 if (PREDICT_FALSE (rv < 0))
Florin Coras0d427d82018-06-27 03:24:07 -07002123 VDBG (0, "VCL<%d>: vpp handle 0x%llx, sid %u: listener unbind "
2124 "failed! rv %d (%s)",
2125 getpid (), vpp_handle, session_index,
2126 rv, vppcom_retval_str (rv));
Dave Wallacef7f809c2017-10-03 01:48:42 -04002127 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05002128
2129 else if (state & (CLIENT_STATE_OPEN | SERVER_STATE_OPEN))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002130 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05002131 rv = vppcom_session_disconnect (session_index);
2132 if (PREDICT_FALSE (rv < 0))
Dave Wallace048b1d62018-01-03 22:24:41 -05002133 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -05002134 "session disconnect failed! rv %d (%s)",
2135 getpid (), vpp_handle, session_index,
2136 rv, vppcom_retval_str (rv));
Dave Wallacef7f809c2017-10-03 01:48:42 -04002137 }
Dave Wallace19481612017-09-15 18:47:44 -04002138 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05002139
Dave Wallace7e607a72018-06-18 18:41:32 -04002140 VCL_SESSION_LOCK_AND_GET (session_index, &session);
Dave Wallaceee45d412017-11-24 21:44:06 -05002141 vpp_handle = session->vpp_handle;
2142 if (vpp_handle != ~0)
Dave Wallace4878cbe2017-11-21 03:45:09 -05002143 {
Dave Wallaceee45d412017-11-24 21:44:06 -05002144 p = hash_get (vcm->session_index_by_vpp_handles, vpp_handle);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002145 if (p)
Dave Wallaceee45d412017-11-24 21:44:06 -05002146 hash_unset (vcm->session_index_by_vpp_handles, vpp_handle);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002147 }
Dave Wallace543852a2017-08-03 02:11:34 -04002148 pool_put_index (vcm->sessions, session_index);
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002149
Dave Wallace7e607a72018-06-18 18:41:32 -04002150 VCL_SESSION_UNLOCK ();
Dave Wallace4878cbe2017-11-21 03:45:09 -05002151
2152 if (VPPCOM_DEBUG > 0)
Dave Wallaceee45d412017-11-24 21:44:06 -05002153 {
2154 if (is_vep)
Dave Wallace048b1d62018-01-03 22:24:41 -05002155 clib_warning ("VCL<%d>: vep_idx %u / sid %u: epoll session removed.",
Dave Wallaceee45d412017-11-24 21:44:06 -05002156 getpid (), session_index, session_index);
2157 else
Dave Wallace048b1d62018-01-03 22:24:41 -05002158 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: session removed.",
Dave Wallaceee45d412017-11-24 21:44:06 -05002159 getpid (), vpp_handle, session_index);
2160 }
Dave Wallacef7f809c2017-10-03 01:48:42 -04002161done:
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002162
Florin Coras0d427d82018-06-27 03:24:07 -07002163 vcl_evt (VCL_EVT_CLOSE, session, rv);
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002164
Dave Wallace543852a2017-08-03 02:11:34 -04002165 return rv;
2166}
2167
2168int
2169vppcom_session_bind (uint32_t session_index, vppcom_endpt_t * ep)
2170{
Dave Wallace543852a2017-08-03 02:11:34 -04002171 session_t *session = 0;
2172 int rv;
2173
2174 if (!ep || !ep->ip)
2175 return VPPCOM_EINVAL;
2176
Dave Wallace7e607a72018-06-18 18:41:32 -04002177 VCL_SESSION_LOCK_AND_GET (session_index, &session);
Dave Wallace543852a2017-08-03 02:11:34 -04002178
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002179 if (session->is_vep)
2180 {
Dave Wallace7e607a72018-06-18 18:41:32 -04002181 VCL_SESSION_UNLOCK ();
Dave Wallace048b1d62018-01-03 22:24:41 -05002182 clib_warning ("VCL<%d>: ERROR: sid %u: cannot "
2183 "bind to an epoll session!", getpid (), session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002184 rv = VPPCOM_EBADFD;
2185 goto done;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002186 }
2187
Dave Wallace35830af2017-10-09 01:43:42 -04002188 session->lcl_addr.is_ip4 = ep->is_ip4;
Dave Wallaced239f8d2018-06-19 13:37:30 -04002189 session->lcl_addr.ip46 = to_ip46 (ep->is_ip4 ? IP46_TYPE_IP4 :
2190 IP46_TYPE_IP6, ep->ip);
Stevenac1f96d2017-10-24 16:03:58 -07002191 session->lcl_port = ep->port;
2192
Florin Coras0d427d82018-06-27 03:24:07 -07002193 VDBG (0, "VCL<%d>: sid %u: binding to local %s address %U port %u, "
2194 "proto %s", getpid (), session_index,
2195 session->lcl_addr.is_ip4 ? "IPv4" : "IPv6",
2196 format_ip46_address, &session->lcl_addr.ip46,
2197 session->lcl_addr.is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6,
2198 clib_net_to_host_u16 (session->lcl_port),
2199 session->proto ? "UDP" : "TCP");
2200 vcl_evt (VCL_EVT_BIND, session);
Dave Wallace7e607a72018-06-18 18:41:32 -04002201 VCL_SESSION_UNLOCK ();
Dave Wallace4878cbe2017-11-21 03:45:09 -05002202done:
2203 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04002204}
2205
2206int
Dave Wallace33e002b2017-09-06 01:20:02 -04002207vppcom_session_listen (uint32_t listen_session_index, uint32_t q_len)
Dave Wallace543852a2017-08-03 02:11:34 -04002208{
Dave Wallace33e002b2017-09-06 01:20:02 -04002209 session_t *listen_session = 0;
Dave Wallaceee45d412017-11-24 21:44:06 -05002210 u64 listen_vpp_handle;
2211 int rv, retval;
Dave Wallace543852a2017-08-03 02:11:34 -04002212
Keith Burns (alagalah)aba98de2018-02-22 03:23:40 -08002213 if (q_len == 0 || q_len == ~0)
2214 q_len = vcm->cfg.listen_queue_size;
2215
Dave Wallace7e607a72018-06-18 18:41:32 -04002216 VCL_SESSION_LOCK_AND_GET (listen_session_index, &listen_session);
Dave Wallace543852a2017-08-03 02:11:34 -04002217
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002218 if (listen_session->is_vep)
2219 {
Dave Wallace7e607a72018-06-18 18:41:32 -04002220 VCL_SESSION_UNLOCK ();
Dave Wallace048b1d62018-01-03 22:24:41 -05002221 clib_warning ("VCL<%d>: ERROR: sid %u: cannot listen on an "
Dave Wallace4878cbe2017-11-21 03:45:09 -05002222 "epoll session!", getpid (), listen_session_index);
2223 rv = VPPCOM_EBADFD;
2224 goto done;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002225 }
2226
Dave Wallaceee45d412017-11-24 21:44:06 -05002227 listen_vpp_handle = listen_session->vpp_handle;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002228 if (listen_session->state & STATE_LISTEN)
Dave Wallacee695cb42017-11-02 22:04:42 -04002229 {
Dave Wallace7e607a72018-06-18 18:41:32 -04002230 VCL_SESSION_UNLOCK ();
Florin Coras0d427d82018-06-27 03:24:07 -07002231 VDBG (0, "VCL<%d>: vpp handle 0x%llx, sid %u: already in listen state!",
2232 getpid (), listen_vpp_handle, listen_session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002233 rv = VPPCOM_OK;
2234 goto done;
Dave Wallacee695cb42017-11-02 22:04:42 -04002235 }
2236
Florin Coras0d427d82018-06-27 03:24:07 -07002237 VDBG (0, "VCL<%d>: vpp handle 0x%llx, sid %u: sending VPP bind+listen "
2238 "request...", getpid (), listen_vpp_handle, listen_session_index);
Dave Wallace543852a2017-08-03 02:11:34 -04002239
Dave Wallace4878cbe2017-11-21 03:45:09 -05002240 vppcom_send_bind_sock (listen_session, listen_session_index);
Dave Wallace7e607a72018-06-18 18:41:32 -04002241 VCL_SESSION_UNLOCK ();
Dave Wallaceee45d412017-11-24 21:44:06 -05002242 retval =
Dave Wallace33e002b2017-09-06 01:20:02 -04002243 vppcom_wait_for_session_state_change (listen_session_index, STATE_LISTEN,
2244 vcm->cfg.session_timeout);
Dave Wallace543852a2017-08-03 02:11:34 -04002245
Dave Wallace7e607a72018-06-18 18:41:32 -04002246 VCL_SESSION_LOCK_AND_GET (listen_session_index, &listen_session);
Dave Wallaceee45d412017-11-24 21:44:06 -05002247 if (PREDICT_FALSE (retval))
2248 {
Florin Coras0d427d82018-06-27 03:24:07 -07002249 VDBG (0, "VCL<%d>: vpp handle 0x%llx, sid %u: bind+listen failed! "
2250 "returning %d (%s)", getpid (), listen_session->vpp_handle,
2251 listen_session_index, retval, vppcom_retval_str (retval));
Dave Wallace7e607a72018-06-18 18:41:32 -04002252 VCL_SESSION_UNLOCK ();
Dave Wallaceee45d412017-11-24 21:44:06 -05002253 rv = retval;
2254 goto done;
2255 }
2256
Dave Wallace7e607a72018-06-18 18:41:32 -04002257 VCL_ACCEPT_FIFO_LOCK ();
Dave Wallace543852a2017-08-03 02:11:34 -04002258 clib_fifo_validate (vcm->client_session_index_fifo, q_len);
Dave Wallace7e607a72018-06-18 18:41:32 -04002259 VCL_ACCEPT_FIFO_UNLOCK ();
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08002260
Dave Wallace7e607a72018-06-18 18:41:32 -04002261 VCL_SESSION_UNLOCK ();
Keith Burns (alagalah)0d2b0d52018-03-06 15:55:22 -08002262
2263done:
2264 return rv;
2265}
2266
2267int
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002268validate_args_session_accept_ (session_t * listen_session)
2269{
2270 u32 listen_session_index = listen_session - vcm->sessions;
2271
2272 /* Input validation - expects spinlock on sessions_lockp */
2273 if (listen_session->is_vep)
2274 {
2275 clib_warning ("VCL<%d>: ERROR: sid %u: cannot accept on an "
2276 "epoll session!", getpid (), listen_session_index);
2277 return VPPCOM_EBADFD;
2278 }
2279
2280 if (listen_session->state != STATE_LISTEN)
2281 {
2282 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
2283 "not in listen state! state 0x%x (%s)", getpid (),
2284 listen_session->vpp_handle, listen_session_index,
2285 listen_session->state,
2286 vppcom_session_state_str (listen_session->state));
2287 return VPPCOM_EBADFD;
2288 }
2289 return VPPCOM_OK;
2290}
2291
2292int
Dave Wallace543852a2017-08-03 02:11:34 -04002293vppcom_session_accept (uint32_t listen_session_index, vppcom_endpt_t * ep,
Dave Wallace048b1d62018-01-03 22:24:41 -05002294 uint32_t flags)
Dave Wallace543852a2017-08-03 02:11:34 -04002295{
Dave Wallace33e002b2017-09-06 01:20:02 -04002296 session_t *listen_session = 0;
2297 session_t *client_session = 0;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002298 u32 client_session_index = ~0;
Dave Wallace543852a2017-08-03 02:11:34 -04002299 int rv;
Dave Wallaceee45d412017-11-24 21:44:06 -05002300 u64 listen_vpp_handle;
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002301 vce_event_handler_reg_t *reg;
2302 vce_event_t *ev;
2303 vce_event_connect_request_t *result;
2304 struct timespec ts;
2305 struct timeval tv;
2306 int millisecond_timeout = 1;
2307 int hours_timeout = 20 * 60 * 60;
Dave Wallace543852a2017-08-03 02:11:34 -04002308
Dave Wallace7e607a72018-06-18 18:41:32 -04002309 VCL_SESSION_LOCK_AND_GET (listen_session_index, &listen_session);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002310 listen_vpp_handle = listen_session->vpp_handle; // For debugging
Dave Wallace543852a2017-08-03 02:11:34 -04002311
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002312 rv = validate_args_session_accept_ (listen_session);
2313 if (rv)
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002314 {
Dave Wallace7e607a72018-06-18 18:41:32 -04002315 VCL_SESSION_UNLOCK ();
Dave Wallace4878cbe2017-11-21 03:45:09 -05002316 goto done;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002317 }
2318
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002319 /* Using an aggressive timer of 1ms and a generous timer of
2320 * 20 hours, we can implement a blocking and non-blocking listener
2321 * as both event and time driven */
2322 gettimeofday (&tv, NULL);
2323 ts.tv_nsec = (tv.tv_usec * 1000) + (1000 * millisecond_timeout);
2324 ts.tv_sec = tv.tv_sec;
2325
2326 /* Predict that the Listener is blocking more often than not */
2327 if (PREDICT_TRUE (!VCL_SESS_ATTR_TEST (listen_session->attr,
2328 VCL_SESS_ATTR_NONBLOCK)))
2329 ts.tv_sec += hours_timeout;
Dave Wallace543852a2017-08-03 02:11:34 -04002330
Dave Wallace7e607a72018-06-18 18:41:32 -04002331 VCL_SESSION_UNLOCK ();
Dave Wallace543852a2017-08-03 02:11:34 -04002332
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002333 /* Register handler for connect_request event on listen_session_index */
2334 vce_event_key_t evk;
2335 evk.session_index = listen_session_index;
2336 evk.eid = VCL_EVENT_CONNECT_REQ_ACCEPTED;
2337 reg = vce_register_handler (&vcm->event_thread, &evk,
Keith Burns (alagalah)0d2b0d52018-03-06 15:55:22 -08002338 vce_connect_request_handler_fn, 0);
Dave Wallace7e607a72018-06-18 18:41:32 -04002339 VCL_EVENTS_LOCK ();
Keith Burns (alagalah)7cf80e02018-03-08 16:46:25 -08002340 ev = vce_get_event_from_index (&vcm->event_thread, reg->ev_idx);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002341 pthread_mutex_lock (&reg->handler_lock);
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08002342 while (!ev)
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002343 {
Dave Wallace7e607a72018-06-18 18:41:32 -04002344 VCL_EVENTS_UNLOCK ();
Keith Burns (alagalah)410bcca2018-03-23 13:42:49 -07002345 rv = pthread_cond_timedwait (&reg->handler_cond,
2346 &reg->handler_lock, &ts);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002347 if (rv == ETIMEDOUT)
2348 {
2349 rv = VPPCOM_EAGAIN;
2350 goto cleanup;
2351 }
Dave Wallace7e607a72018-06-18 18:41:32 -04002352 VCL_EVENTS_LOCK ();
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08002353 ev = vce_get_event_from_index (&vcm->event_thread, reg->ev_idx);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002354 }
Keith Burns (alagalah)410bcca2018-03-23 13:42:49 -07002355 result = vce_get_event_data (ev, sizeof (*result));
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002356 client_session_index = result->accepted_session_index;
Dave Wallace7e607a72018-06-18 18:41:32 -04002357 VCL_EVENTS_UNLOCK ();
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002358
2359 /* Remove from the FIFO used to service epoll */
Dave Wallace7e607a72018-06-18 18:41:32 -04002360 VCL_ACCEPT_FIFO_LOCK ();
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002361 if (clib_fifo_elts (vcm->client_session_index_fifo))
2362 {
2363 u32 tmp_client_session_index;
2364 clib_fifo_sub1 (vcm->client_session_index_fifo,
2365 tmp_client_session_index);
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08002366 /* It wasn't ours... put it back ... */
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002367 if (tmp_client_session_index != client_session_index)
2368 clib_fifo_add1 (vcm->client_session_index_fifo,
2369 tmp_client_session_index);
2370 }
Dave Wallace7e607a72018-06-18 18:41:32 -04002371 VCL_ACCEPT_FIFO_UNLOCK ();
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08002372
Dave Wallace7e607a72018-06-18 18:41:32 -04002373 VCL_SESSION_LOCK ();
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002374
Dave Wallace33e002b2017-09-06 01:20:02 -04002375 rv = vppcom_session_at_index (client_session_index, &client_session);
Dave Wallaceee45d412017-11-24 21:44:06 -05002376 if (PREDICT_FALSE (rv))
2377 {
2378 rv = VPPCOM_ECONNABORTED;
Dave Wallace048b1d62018-01-03 22:24:41 -05002379 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: client sid %u "
Dave Wallaceee45d412017-11-24 21:44:06 -05002380 "lookup failed! returning %d (%s)", getpid (),
2381 listen_vpp_handle, listen_session_index,
2382 client_session_index, rv, vppcom_retval_str (rv));
Dave Wallacee5356442018-03-19 10:38:00 -04002383 goto cleanup;
Dave Wallaceee45d412017-11-24 21:44:06 -05002384 }
Dave Wallace543852a2017-08-03 02:11:34 -04002385
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002386 if (flags & O_NONBLOCK)
2387 VCL_SESS_ATTR_SET (client_session->attr, VCL_SESS_ATTR_NONBLOCK);
2388 else
2389 VCL_SESS_ATTR_CLR (client_session->attr, VCL_SESS_ATTR_NONBLOCK);
2390
Florin Coras0d427d82018-06-27 03:24:07 -07002391 VDBG (0, "VCL<%d>: vpp handle 0x%llx, sid %u: Got a client request! "
2392 "vpp handle 0x%llx, sid %u, flags %d, is_nonblocking %u",
2393 getpid (), listen_vpp_handle, listen_session_index,
2394 client_session->vpp_handle, client_session_index,
2395 flags, VCL_SESS_ATTR_TEST (client_session->attr,
2396 VCL_SESS_ATTR_NONBLOCK));
Dave Wallace543852a2017-08-03 02:11:34 -04002397
Dave Wallace048b1d62018-01-03 22:24:41 -05002398 if (ep)
2399 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002400 ep->is_ip4 = client_session->peer_addr.is_ip4;
2401 ep->port = client_session->peer_port;
2402 if (client_session->peer_addr.is_ip4)
2403 clib_memcpy (ep->ip, &client_session->peer_addr.ip46.ip4,
2404 sizeof (ip4_address_t));
2405 else
2406 clib_memcpy (ep->ip, &client_session->peer_addr.ip46.ip6,
2407 sizeof (ip6_address_t));
2408 }
Dave Wallace60caa062017-11-10 17:07:13 -05002409
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002410 vppcom_send_accept_session_reply (client_session->vpp_handle,
2411 client_session->client_context,
2412 0 /* retval OK */ );
Dave Wallace60caa062017-11-10 17:07:13 -05002413
Florin Coras0d427d82018-06-27 03:24:07 -07002414 VDBG (0, "VCL<%d>: vpp handle 0x%llx, sid %u: accepted vpp handle 0x%llx,"
2415 " sid %u connection from peer %s address %U port %u to local %s address"
2416 " %U port %u",
2417 getpid (), listen_vpp_handle,
2418 listen_session_index, client_session->vpp_handle,
2419 client_session_index,
2420 client_session->peer_addr.is_ip4 ? "IPv4" : "IPv6",
2421 format_ip46_address, &client_session->peer_addr.ip46,
2422 client_session->peer_addr.is_ip4 ?
2423 IP46_TYPE_IP4 : IP46_TYPE_IP6,
2424 clib_net_to_host_u16 (client_session->peer_port),
2425 client_session->lcl_addr.is_ip4 ? "IPv4" : "IPv6",
2426 format_ip46_address, &client_session->lcl_addr.ip46,
2427 client_session->lcl_addr.is_ip4 ?
2428 IP46_TYPE_IP4 : IP46_TYPE_IP6,
2429 clib_net_to_host_u16 (client_session->lcl_port));
2430 vcl_evt (VCL_EVT_ACCEPT, client_session, listen_session,
2431 client_session_index);
Dave Wallace7e607a72018-06-18 18:41:32 -04002432 VCL_SESSION_UNLOCK ();
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002433
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08002434 rv = (int) client_session_index;
Keith Burns (alagalah)410bcca2018-03-23 13:42:49 -07002435 vce_clear_event (&vcm->event_thread, reg->ev_idx);
2436 if (vcm->session_io_thread.io_sessions_lockp)
2437 {
2438 /* Throw this new accepted session index into the rx poll thread pool */
Dave Wallace7e607a72018-06-18 18:41:32 -04002439 VCL_IO_SESSIONS_LOCK ();
Keith Burns (alagalah)410bcca2018-03-23 13:42:49 -07002440 u32 *active_session_index;
2441 pool_get (vcm->session_io_thread.active_session_indexes,
2442 active_session_index);
2443 *active_session_index = client_session_index;
Dave Wallace7e607a72018-06-18 18:41:32 -04002444 VCL_IO_SESSIONS_UNLOCK ();
Keith Burns (alagalah)410bcca2018-03-23 13:42:49 -07002445 }
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002446cleanup:
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08002447 vce_unregister_handler (&vcm->event_thread, reg);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002448 pthread_mutex_unlock (&reg->handler_lock);
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08002449
Dave Wallace4878cbe2017-11-21 03:45:09 -05002450done:
2451 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04002452}
2453
2454int
2455vppcom_session_connect (uint32_t session_index, vppcom_endpt_t * server_ep)
2456{
Dave Wallace543852a2017-08-03 02:11:34 -04002457 session_t *session = 0;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002458 u64 vpp_handle = 0;
Dave Wallaceee45d412017-11-24 21:44:06 -05002459 int rv, retval = VPPCOM_OK;
Dave Wallace543852a2017-08-03 02:11:34 -04002460
Dave Wallace7e607a72018-06-18 18:41:32 -04002461 VCL_SESSION_LOCK_AND_GET (session_index, &session);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002462
2463 if (PREDICT_FALSE (session->is_vep))
Dave Wallace543852a2017-08-03 02:11:34 -04002464 {
Dave Wallace7e607a72018-06-18 18:41:32 -04002465 VCL_SESSION_UNLOCK ();
Dave Wallace048b1d62018-01-03 22:24:41 -05002466 clib_warning ("VCL<%d>: ERROR: sid %u: cannot "
2467 "connect on an epoll session!", getpid (), session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002468 rv = VPPCOM_EBADFD;
2469 goto done;
Dave Wallace543852a2017-08-03 02:11:34 -04002470 }
2471
Dave Wallace4878cbe2017-11-21 03:45:09 -05002472 if (PREDICT_FALSE (session->state & CLIENT_STATE_OPEN))
Dave Wallace543852a2017-08-03 02:11:34 -04002473 {
Florin Coras0d427d82018-06-27 03:24:07 -07002474 VDBG (0, "VCL<%d>: vpp handle 0x%llx, sid %u: session already "
2475 "connected to %s %U port %d proto %s, state 0x%x (%s)",
2476 getpid (), session->vpp_handle, session_index,
2477 session->peer_addr.is_ip4 ? "IPv4" : "IPv6",
2478 format_ip46_address,
2479 &session->peer_addr.ip46, session->peer_addr.is_ip4 ?
2480 IP46_TYPE_IP4 : IP46_TYPE_IP6,
2481 clib_net_to_host_u16 (session->peer_port),
2482 session->proto ? "UDP" : "TCP", session->state,
2483 vppcom_session_state_str (session->state));
Dave Wallace4878cbe2017-11-21 03:45:09 -05002484
Dave Wallace7e607a72018-06-18 18:41:32 -04002485 VCL_SESSION_UNLOCK ();
Dave Wallace4878cbe2017-11-21 03:45:09 -05002486 goto done;
Dave Wallace543852a2017-08-03 02:11:34 -04002487 }
2488
Dave Wallace35830af2017-10-09 01:43:42 -04002489 session->peer_addr.is_ip4 = server_ep->is_ip4;
Dave Wallaced239f8d2018-06-19 13:37:30 -04002490 if (session->peer_addr.is_ip4)
2491 clib_memcpy (&session->peer_addr.ip46.ip4, server_ep->ip,
2492 sizeof (ip4_address_t));
2493 else
2494 clib_memcpy (&session->peer_addr.ip46.ip6, server_ep->ip,
2495 sizeof (ip6_address_t));
Stevenac1f96d2017-10-24 16:03:58 -07002496 session->peer_port = server_ep->port;
Dave Wallace543852a2017-08-03 02:11:34 -04002497
Florin Coras0d427d82018-06-27 03:24:07 -07002498 VDBG (0, "VCL<%d>: vpp handle 0x%llx, sid %u: connecting to server %s %U "
2499 "port %d proto %s",
2500 getpid (), session->vpp_handle, session_index,
2501 session->peer_addr.is_ip4 ? "IPv4" : "IPv6",
2502 format_ip46_address,
2503 &session->peer_addr.ip46, session->peer_addr.is_ip4 ?
2504 IP46_TYPE_IP4 : IP46_TYPE_IP6,
2505 clib_net_to_host_u16 (session->peer_port),
2506 session->proto ? "UDP" : "TCP");
Dave Wallace543852a2017-08-03 02:11:34 -04002507
2508 vppcom_send_connect_sock (session, session_index);
Dave Wallace7e607a72018-06-18 18:41:32 -04002509 VCL_SESSION_UNLOCK ();
Dave Wallace4878cbe2017-11-21 03:45:09 -05002510
Dave Wallaceee45d412017-11-24 21:44:06 -05002511 retval =
2512 vppcom_wait_for_session_state_change (session_index, STATE_CONNECT,
2513 vcm->cfg.session_timeout);
2514
Dave Wallace7e607a72018-06-18 18:41:32 -04002515 VCL_SESSION_LOCK_AND_GET (session_index, &session);
Dave Wallaceee45d412017-11-24 21:44:06 -05002516 vpp_handle = session->vpp_handle;
Dave Wallace7e607a72018-06-18 18:41:32 -04002517 VCL_SESSION_UNLOCK ();
Dave Wallace7876d392017-10-19 03:53:57 -04002518
Dave Wallace4878cbe2017-11-21 03:45:09 -05002519done:
Dave Wallaceee45d412017-11-24 21:44:06 -05002520 if (PREDICT_FALSE (retval))
2521 {
2522 rv = retval;
2523 if (VPPCOM_DEBUG > 0)
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002524 {
2525 if (session)
Florin Coras0d427d82018-06-27 03:24:07 -07002526 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: connect "
2527 "failed! returning %d (%s)", getpid (), vpp_handle,
2528 session_index, rv, vppcom_retval_str (rv));
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002529 else
2530 clib_warning ("VCL<%d>: no session for sid %u: connect failed! "
2531 "returning %d (%s)", getpid (),
2532 session_index, rv, vppcom_retval_str (rv));
2533 }
Dave Wallaceee45d412017-11-24 21:44:06 -05002534 }
Florin Coras0d427d82018-06-27 03:24:07 -07002535 else
2536 VDBG (0, "VCL<%d>: vpp handle 0x%llx, sid %u: connected!",
2537 getpid (), vpp_handle, session_index);
Dave Wallaceee45d412017-11-24 21:44:06 -05002538
Dave Wallace4878cbe2017-11-21 03:45:09 -05002539 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04002540}
2541
Steven58f464e2017-10-25 12:33:12 -07002542static inline int
2543vppcom_session_read_internal (uint32_t session_index, void *buf, int n,
2544 u8 peek)
Dave Wallace543852a2017-08-03 02:11:34 -04002545{
Dave Wallace543852a2017-08-03 02:11:34 -04002546 session_t *session = 0;
2547 svm_fifo_t *rx_fifo;
2548 int n_read = 0;
2549 int rv;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002550 int is_nonblocking;
2551
2552 u64 vpp_handle;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002553 u32 poll_et;
Dave Wallace4878cbe2017-11-21 03:45:09 -05002554 session_state_t state;
Dave Wallace543852a2017-08-03 02:11:34 -04002555
2556 ASSERT (buf);
2557
Dave Wallace7e607a72018-06-18 18:41:32 -04002558 VCL_SESSION_LOCK_AND_GET (session_index, &session);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002559
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002560 is_nonblocking = VCL_SESS_ATTR_TEST (session->attr, VCL_SESS_ATTR_NONBLOCK);
2561 rx_fifo = session->rx_fifo;
2562 state = session->state;
2563 vpp_handle = session->vpp_handle;
2564
Dave Wallace4878cbe2017-11-21 03:45:09 -05002565 if (PREDICT_FALSE (session->is_vep))
Dave Wallace543852a2017-08-03 02:11:34 -04002566 {
Dave Wallace7e607a72018-06-18 18:41:32 -04002567 VCL_SESSION_UNLOCK ();
Dave Wallace048b1d62018-01-03 22:24:41 -05002568 clib_warning ("VCL<%d>: ERROR: sid %u: cannot "
2569 "read from an epoll session!", getpid (), session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002570 rv = VPPCOM_EBADFD;
2571 goto done;
Dave Wallace543852a2017-08-03 02:11:34 -04002572 }
2573
Dave Wallace4878cbe2017-11-21 03:45:09 -05002574 if (PREDICT_FALSE (!(state & (SERVER_STATE_OPEN | CLIENT_STATE_OPEN))))
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002575 {
Dave Wallace7e607a72018-06-18 18:41:32 -04002576 VCL_SESSION_UNLOCK ();
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08002577 rv = ((state & STATE_DISCONNECT) ? VPPCOM_ECONNRESET : VPPCOM_ENOTCONN);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002578
Florin Coras0d427d82018-06-27 03:24:07 -07002579 VDBG (0, "VCL<%d>: vpp handle 0x%llx, sid %u: %s session is not open! "
2580 "state 0x%x (%s), returning %d (%s)",
2581 getpid (), vpp_handle, session_index, state,
2582 vppcom_session_state_str (state), rv, vppcom_retval_str (rv));
Dave Wallace4878cbe2017-11-21 03:45:09 -05002583 goto done;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002584 }
2585
Dave Wallace7e607a72018-06-18 18:41:32 -04002586 VCL_SESSION_UNLOCK ();
Dave Wallacef7f809c2017-10-03 01:48:42 -04002587
2588 do
2589 {
Steven58f464e2017-10-25 12:33:12 -07002590 if (peek)
2591 n_read = svm_fifo_peek (rx_fifo, 0, n, buf);
2592 else
2593 n_read = svm_fifo_dequeue_nowait (rx_fifo, n, buf);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002594 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05002595 while (!is_nonblocking && (n_read <= 0));
Dave Wallacef7f809c2017-10-03 01:48:42 -04002596
Dave Wallace4878cbe2017-11-21 03:45:09 -05002597 if (n_read <= 0)
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002598 {
Dave Wallace7e607a72018-06-18 18:41:32 -04002599 VCL_SESSION_LOCK_AND_GET (session_index, &session);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002600
2601 poll_et = (((EPOLLET | EPOLLIN) & session->vep.ev.events) ==
2602 (EPOLLET | EPOLLIN));
2603 if (poll_et)
2604 session->vep.et_mask |= EPOLLIN;
2605
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08002606 if (state & STATE_CLOSE_ON_EMPTY)
Dave Wallace4878cbe2017-11-21 03:45:09 -05002607 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05002608 rv = VPPCOM_ECONNRESET;
2609
Florin Coras0d427d82018-06-27 03:24:07 -07002610 VDBG (1, "VCL<%d>: vpp handle 0x%llx, sid %u: Empty fifo with "
2611 "session state 0x%x (%s)! Setting state to 0x%x (%s), "
2612 "returning %d (%s)",
2613 getpid (), session->vpp_handle, session_index,
2614 state, vppcom_session_state_str (state),
2615 STATE_DISCONNECT,
2616 vppcom_session_state_str (STATE_DISCONNECT), rv,
2617 vppcom_retval_str (rv));
Dave Wallace4878cbe2017-11-21 03:45:09 -05002618
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002619 session->state = STATE_DISCONNECT;
Dave Wallace4878cbe2017-11-21 03:45:09 -05002620 }
2621 else
2622 rv = VPPCOM_EAGAIN;
2623
Dave Wallace7e607a72018-06-18 18:41:32 -04002624 VCL_SESSION_UNLOCK ();
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002625 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05002626 else
2627 rv = n_read;
Dave Wallace543852a2017-08-03 02:11:34 -04002628
Dave Wallace4878cbe2017-11-21 03:45:09 -05002629 if (VPPCOM_DEBUG > 2)
2630 {
2631 if (rv > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002632 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: read %d bytes "
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002633 "from (%p)", getpid (), vpp_handle,
2634 session_index, n_read, rx_fifo);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002635 else
Dave Wallace048b1d62018-01-03 22:24:41 -05002636 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: nothing read! "
Dave Wallaceee45d412017-11-24 21:44:06 -05002637 "returning %d (%s)", getpid (), vpp_handle,
2638 session_index, rv, vppcom_retval_str (rv));
Dave Wallace4878cbe2017-11-21 03:45:09 -05002639 }
2640done:
2641 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04002642}
2643
Steven58f464e2017-10-25 12:33:12 -07002644int
Dave Wallace048b1d62018-01-03 22:24:41 -05002645vppcom_session_read (uint32_t session_index, void *buf, size_t n)
Steven58f464e2017-10-25 12:33:12 -07002646{
2647 return (vppcom_session_read_internal (session_index, buf, n, 0));
2648}
2649
2650static int
2651vppcom_session_peek (uint32_t session_index, void *buf, int n)
2652{
2653 return (vppcom_session_read_internal (session_index, buf, n, 1));
2654}
2655
Dave Wallace543852a2017-08-03 02:11:34 -04002656static inline int
2657vppcom_session_read_ready (session_t * session, u32 session_index)
2658{
Dave Wallace543852a2017-08-03 02:11:34 -04002659 int ready = 0;
Dave Wallace60caa062017-11-10 17:07:13 -05002660 u32 poll_et;
Dave Wallace4878cbe2017-11-21 03:45:09 -05002661 int rv;
Dave Wallace4878cbe2017-11-21 03:45:09 -05002662 session_state_t state = session->state;
Dave Wallaceee45d412017-11-24 21:44:06 -05002663 u64 vpp_handle = session->vpp_handle;
Dave Wallace543852a2017-08-03 02:11:34 -04002664
2665 /* Assumes caller has acquired spinlock: vcm->sessions_lockp */
Dave Wallace4878cbe2017-11-21 03:45:09 -05002666 if (PREDICT_FALSE (session->is_vep))
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002667 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002668 clib_warning ("VCL<%d>: ERROR: sid %u: cannot read from an "
Dave Wallace4878cbe2017-11-21 03:45:09 -05002669 "epoll session!", getpid (), session_index);
2670 rv = VPPCOM_EBADFD;
2671 goto done;
Dave Wallace543852a2017-08-03 02:11:34 -04002672 }
Dave Wallace33e002b2017-09-06 01:20:02 -04002673
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002674 if (session->state & STATE_LISTEN)
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002675 {
Dave Wallace7e607a72018-06-18 18:41:32 -04002676 VCL_ACCEPT_FIFO_LOCK ();
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002677 ready = clib_fifo_elts (vcm->client_session_index_fifo);
Dave Wallace7e607a72018-06-18 18:41:32 -04002678 VCL_ACCEPT_FIFO_UNLOCK ();
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002679 }
Dave Wallace543852a2017-08-03 02:11:34 -04002680 else
2681 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05002682 if (!(state & (SERVER_STATE_OPEN | CLIENT_STATE_OPEN | STATE_LISTEN)))
2683 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08002684 rv = ((state & STATE_DISCONNECT) ? VPPCOM_ECONNRESET :
Dave Wallace4878cbe2017-11-21 03:45:09 -05002685 VPPCOM_ENOTCONN);
2686
Florin Coras0d427d82018-06-27 03:24:07 -07002687 VDBG (1, "VCL<%d>: vpp handle 0x%llx, sid %u: session is not open!"
2688 " state 0x%x (%s), returning %d (%s)",
2689 getpid (), vpp_handle, session_index,
2690 state, vppcom_session_state_str (state),
2691 rv, vppcom_retval_str (rv));
Dave Wallace4878cbe2017-11-21 03:45:09 -05002692 goto done;
2693 }
2694
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002695 ready = svm_fifo_max_dequeue (session->rx_fifo);
Dave Wallace543852a2017-08-03 02:11:34 -04002696 }
2697
Dave Wallace4878cbe2017-11-21 03:45:09 -05002698 if (ready == 0)
Dave Wallace60caa062017-11-10 17:07:13 -05002699 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05002700 poll_et =
2701 ((EPOLLET | EPOLLIN) & session->vep.ev.events) == (EPOLLET | EPOLLIN);
2702 if (poll_et)
2703 session->vep.et_mask |= EPOLLIN;
Dave Wallace60caa062017-11-10 17:07:13 -05002704
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08002705 if (state & STATE_CLOSE_ON_EMPTY)
Dave Wallace4878cbe2017-11-21 03:45:09 -05002706 {
2707 rv = VPPCOM_ECONNRESET;
Dave Wallace4878cbe2017-11-21 03:45:09 -05002708
Florin Coras0d427d82018-06-27 03:24:07 -07002709 VDBG (1, "VCL<%d>: vpp handle 0x%llx, sid %u: Empty fifo with "
2710 "session state 0x%x (%s)! Setting state to 0x%x (%s), "
2711 "returning %d (%s)",
2712 getpid (), session_index, vpp_handle,
2713 state, vppcom_session_state_str (state),
2714 STATE_DISCONNECT,
2715 vppcom_session_state_str (STATE_DISCONNECT), rv,
2716 vppcom_retval_str (rv));
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002717 session->state = STATE_DISCONNECT;
Dave Wallace4878cbe2017-11-21 03:45:09 -05002718 goto done;
2719 }
2720 }
2721 rv = ready;
Dave Wallace16cb4082017-11-29 03:24:06 -05002722
2723 if (vcm->app_event_queue->cursize &&
2724 !pthread_mutex_trylock (&vcm->app_event_queue->mutex))
2725 {
2726 u32 i, n_to_dequeue = vcm->app_event_queue->cursize;
2727 session_fifo_event_t e;
2728
2729 for (i = 0; i < n_to_dequeue; i++)
Florin Corase86a8ed2018-01-05 03:20:25 -08002730 svm_queue_sub_raw (vcm->app_event_queue, (u8 *) & e);
Dave Wallace16cb4082017-11-29 03:24:06 -05002731
2732 pthread_mutex_unlock (&vcm->app_event_queue->mutex);
2733 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05002734done:
2735 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04002736}
2737
2738int
Dave Wallace048b1d62018-01-03 22:24:41 -05002739vppcom_session_write (uint32_t session_index, void *buf, size_t n)
Dave Wallace543852a2017-08-03 02:11:34 -04002740{
Dave Wallace543852a2017-08-03 02:11:34 -04002741 session_t *session = 0;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002742 svm_fifo_t *tx_fifo = 0;
Florin Corase86a8ed2018-01-05 03:20:25 -08002743 svm_queue_t *q;
Dave Wallace543852a2017-08-03 02:11:34 -04002744 session_fifo_event_t evt;
Dave Wallace4878cbe2017-11-21 03:45:09 -05002745 session_state_t state;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002746 int rv, n_write, is_nonblocking;
2747 u32 poll_et;
Dave Wallaceee45d412017-11-24 21:44:06 -05002748 u64 vpp_handle;
Dave Wallace543852a2017-08-03 02:11:34 -04002749
2750 ASSERT (buf);
2751
Dave Wallace7e607a72018-06-18 18:41:32 -04002752 VCL_SESSION_LOCK_AND_GET (session_index, &session);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002753
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002754 tx_fifo = session->tx_fifo;
2755 is_nonblocking = VCL_SESS_ATTR_TEST (session->attr, VCL_SESS_ATTR_NONBLOCK);
2756 vpp_handle = session->vpp_handle;
2757 state = session->state;
2758
Dave Wallace4878cbe2017-11-21 03:45:09 -05002759 if (PREDICT_FALSE (session->is_vep))
Dave Wallace543852a2017-08-03 02:11:34 -04002760 {
Dave Wallace7e607a72018-06-18 18:41:32 -04002761 VCL_SESSION_UNLOCK ();
Dave Wallace048b1d62018-01-03 22:24:41 -05002762 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -05002763 "cannot write to an epoll session!",
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002764 getpid (), vpp_handle, session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002765
2766 rv = VPPCOM_EBADFD;
2767 goto done;
Dave Wallace543852a2017-08-03 02:11:34 -04002768 }
2769
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002770 if (!(session->state & (SERVER_STATE_OPEN | CLIENT_STATE_OPEN)))
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002771 {
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002772 rv =
2773 ((session->state & STATE_DISCONNECT) ? VPPCOM_ECONNRESET :
2774 VPPCOM_ENOTCONN);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002775
Dave Wallace7e607a72018-06-18 18:41:32 -04002776 VCL_SESSION_UNLOCK ();
Florin Coras0d427d82018-06-27 03:24:07 -07002777 VDBG (1, "VCL<%d>: vpp handle 0x%llx, sid %u: session is not open! "
2778 "state 0x%x (%s)",
2779 getpid (), vpp_handle, session_index,
2780 state, vppcom_session_state_str (state));
Dave Wallace4878cbe2017-11-21 03:45:09 -05002781 goto done;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002782 }
2783
Dave Wallace7e607a72018-06-18 18:41:32 -04002784 VCL_SESSION_UNLOCK ();
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002785
Dave Wallace543852a2017-08-03 02:11:34 -04002786 do
2787 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002788 n_write = svm_fifo_enqueue_nowait (tx_fifo, n, (void *) buf);
Dave Wallace543852a2017-08-03 02:11:34 -04002789 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05002790 while (!is_nonblocking && (n_write <= 0));
Dave Wallace543852a2017-08-03 02:11:34 -04002791
Keith Burns (alagalah)410bcca2018-03-23 13:42:49 -07002792 /* If event wasn't set, add one
2793 *
2794 * To reduce context switching, can check if an
2795 * event is already there for this event_key, but for now
2796 * this will suffice. */
2797
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002798 if ((n_write > 0) && svm_fifo_set_event (tx_fifo))
Dave Wallace543852a2017-08-03 02:11:34 -04002799 {
Dave Wallace543852a2017-08-03 02:11:34 -04002800 /* Fabricate TX event, send to vpp */
2801 evt.fifo = tx_fifo;
2802 evt.event_type = FIFO_EVENT_APP_TX;
Dave Wallace543852a2017-08-03 02:11:34 -04002803
Dave Wallace7e607a72018-06-18 18:41:32 -04002804 VCL_SESSION_LOCK_AND_GET (session_index, &session);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002805 q = session->vpp_event_queue;
Dave Wallace543852a2017-08-03 02:11:34 -04002806 ASSERT (q);
Florin Corase86a8ed2018-01-05 03:20:25 -08002807 svm_queue_add (q, (u8 *) & evt, 0 /* do wait for mutex */ );
Dave Wallace7e607a72018-06-18 18:41:32 -04002808 VCL_SESSION_UNLOCK ();
Florin Coras0d427d82018-06-27 03:24:07 -07002809 VDBG (1, "VCL<%d>: vpp handle 0x%llx, sid %u: added FIFO_EVENT_APP_TX "
2810 "to vpp_event_q %p, n_write %d", getpid (),
2811 vpp_handle, session_index, q, n_write);
Dave Wallace543852a2017-08-03 02:11:34 -04002812 }
2813
Dave Wallace4878cbe2017-11-21 03:45:09 -05002814 if (n_write <= 0)
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002815 {
Dave Wallace7e607a72018-06-18 18:41:32 -04002816 VCL_SESSION_LOCK_AND_GET (session_index, &session);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002817
2818 poll_et = (((EPOLLET | EPOLLOUT) & session->vep.ev.events) ==
2819 (EPOLLET | EPOLLOUT));
2820 if (poll_et)
2821 session->vep.et_mask |= EPOLLOUT;
2822
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002823 if (session->state & STATE_CLOSE_ON_EMPTY)
Dave Wallace4878cbe2017-11-21 03:45:09 -05002824 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05002825 rv = VPPCOM_ECONNRESET;
2826
Florin Coras0d427d82018-06-27 03:24:07 -07002827 VDBG (1, "VCL<%d>: vpp handle 0x%llx, sid %u: Empty fifo with "
2828 "session state 0x%x (%s)! Setting state to 0x%x (%s), "
2829 "returning %d (%s)",
2830 getpid (), session->vpp_handle, session_index,
2831 session->state,
2832 vppcom_session_state_str (session->state),
2833 STATE_DISCONNECT,
2834 vppcom_session_state_str (STATE_DISCONNECT), rv,
2835 vppcom_retval_str (rv));
Dave Wallace4878cbe2017-11-21 03:45:09 -05002836
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002837 session->state = STATE_DISCONNECT;
Dave Wallace4878cbe2017-11-21 03:45:09 -05002838 }
2839 else
2840 rv = VPPCOM_EAGAIN;
2841
Dave Wallace7e607a72018-06-18 18:41:32 -04002842 VCL_SESSION_UNLOCK ();
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002843 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05002844 else
2845 rv = n_write;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002846
Dave Wallace543852a2017-08-03 02:11:34 -04002847 if (VPPCOM_DEBUG > 2)
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002848 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05002849 if (n_write <= 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002850 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002851 "FIFO-FULL (%p)", getpid (), vpp_handle,
2852 session_index, tx_fifo);
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002853 else
Dave Wallace048b1d62018-01-03 22:24:41 -05002854 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002855 "wrote %d bytes tx-fifo: (%p)", getpid (),
2856 vpp_handle, session_index, n_write, tx_fifo);
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002857 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05002858done:
2859 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04002860}
2861
2862static inline int
2863vppcom_session_write_ready (session_t * session, u32 session_index)
2864{
Dave Wallacef7f809c2017-10-03 01:48:42 -04002865 int ready;
Dave Wallace60caa062017-11-10 17:07:13 -05002866 u32 poll_et;
Dave Wallace4878cbe2017-11-21 03:45:09 -05002867 int rv;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002868
2869 ASSERT (session);
Dave Wallace543852a2017-08-03 02:11:34 -04002870
2871 /* Assumes caller has acquired spinlock: vcm->sessions_lockp */
Dave Wallace4878cbe2017-11-21 03:45:09 -05002872 if (PREDICT_FALSE (session->is_vep))
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002873 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002874 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -05002875 "cannot write to an epoll session!",
2876 getpid (), session->vpp_handle, session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002877 rv = VPPCOM_EBADFD;
2878 goto done;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002879 }
2880
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002881 if (PREDICT_FALSE (session->state & STATE_LISTEN))
Dave Wallace33e002b2017-09-06 01:20:02 -04002882 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002883 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -05002884 "cannot write to a listen session!",
2885 getpid (), session->vpp_handle, session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002886 rv = VPPCOM_EBADFD;
2887 goto done;
2888 }
2889
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002890 if (!(session->state & (SERVER_STATE_OPEN | CLIENT_STATE_OPEN)))
Dave Wallace4878cbe2017-11-21 03:45:09 -05002891 {
2892 session_state_t state = session->state;
2893
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08002894 rv = ((state & STATE_DISCONNECT) ? VPPCOM_ECONNRESET : VPPCOM_ENOTCONN);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002895
Dave Wallace048b1d62018-01-03 22:24:41 -05002896 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002897 "session is not open! state 0x%x (%s), "
Dave Wallaceee45d412017-11-24 21:44:06 -05002898 "returning %d (%s)", getpid (), session->vpp_handle,
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002899 session_index,
Dave Wallace4878cbe2017-11-21 03:45:09 -05002900 state, vppcom_session_state_str (state),
2901 rv, vppcom_retval_str (rv));
2902 goto done;
Dave Wallace33e002b2017-09-06 01:20:02 -04002903 }
2904
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002905 ready = svm_fifo_max_enqueue (session->tx_fifo);
Dave Wallace543852a2017-08-03 02:11:34 -04002906
Florin Coras0d427d82018-06-27 03:24:07 -07002907 VDBG (3, "VCL<%d>: vpp handle 0x%llx, sid %u: peek %s (%p), ready = %d",
2908 getpid (), session->vpp_handle, session_index, session->tx_fifo,
2909 ready);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002910
Dave Wallace4878cbe2017-11-21 03:45:09 -05002911 if (ready == 0)
2912 {
2913 poll_et = (((EPOLLET | EPOLLOUT) & session->vep.ev.events) ==
2914 (EPOLLET | EPOLLOUT));
2915 if (poll_et)
2916 session->vep.et_mask |= EPOLLOUT;
2917
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002918 if (session->state & STATE_CLOSE_ON_EMPTY)
Dave Wallace4878cbe2017-11-21 03:45:09 -05002919 {
2920 rv = VPPCOM_ECONNRESET;
Dave Wallace4878cbe2017-11-21 03:45:09 -05002921
Florin Coras0d427d82018-06-27 03:24:07 -07002922 VDBG (1, "VCL<%d>: vpp handle 0x%llx, sid %u: Empty fifo with "
2923 "session state 0x%x (%s)! Setting state to 0x%x (%s), "
2924 "returning %d (%s)", getpid (),
2925 session->vpp_handle, session_index,
2926 session->state,
2927 vppcom_session_state_str (session->state),
2928 STATE_DISCONNECT,
2929 vppcom_session_state_str (STATE_DISCONNECT), rv,
2930 vppcom_retval_str (rv));
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002931 session->state = STATE_DISCONNECT;
Dave Wallace4878cbe2017-11-21 03:45:09 -05002932 goto done;
2933 }
2934 }
2935 rv = ready;
2936done:
2937 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04002938}
2939
2940int
2941vppcom_select (unsigned long n_bits, unsigned long *read_map,
2942 unsigned long *write_map, unsigned long *except_map,
2943 double time_to_wait)
2944{
Dave Wallace543852a2017-08-03 02:11:34 -04002945 u32 session_index;
2946 session_t *session = 0;
2947 int rv, bits_set = 0;
2948 f64 timeout = clib_time_now (&vcm->clib_time) + time_to_wait;
2949 u32 minbits = clib_max (n_bits, BITS (uword));
2950
2951 ASSERT (sizeof (clib_bitmap_t) == sizeof (long int));
2952
Dave Wallace7876d392017-10-19 03:53:57 -04002953 if (n_bits && read_map)
Dave Wallace543852a2017-08-03 02:11:34 -04002954 {
2955 clib_bitmap_validate (vcm->rd_bitmap, minbits);
Dave Wallace048b1d62018-01-03 22:24:41 -05002956 clib_memcpy (vcm->rd_bitmap, read_map,
2957 vec_len (vcm->rd_bitmap) * sizeof (clib_bitmap_t));
2958 memset (read_map, 0, vec_len (vcm->rd_bitmap) * sizeof (clib_bitmap_t));
Dave Wallace543852a2017-08-03 02:11:34 -04002959 }
Dave Wallace7876d392017-10-19 03:53:57 -04002960 if (n_bits && write_map)
Dave Wallace543852a2017-08-03 02:11:34 -04002961 {
2962 clib_bitmap_validate (vcm->wr_bitmap, minbits);
Dave Wallace048b1d62018-01-03 22:24:41 -05002963 clib_memcpy (vcm->wr_bitmap, write_map,
2964 vec_len (vcm->wr_bitmap) * sizeof (clib_bitmap_t));
2965 memset (write_map, 0,
2966 vec_len (vcm->wr_bitmap) * sizeof (clib_bitmap_t));
Dave Wallace543852a2017-08-03 02:11:34 -04002967 }
Dave Wallace7876d392017-10-19 03:53:57 -04002968 if (n_bits && except_map)
Dave Wallace543852a2017-08-03 02:11:34 -04002969 {
2970 clib_bitmap_validate (vcm->ex_bitmap, minbits);
Dave Wallace048b1d62018-01-03 22:24:41 -05002971 clib_memcpy (vcm->ex_bitmap, except_map,
2972 vec_len (vcm->ex_bitmap) * sizeof (clib_bitmap_t));
2973 memset (except_map, 0,
2974 vec_len (vcm->ex_bitmap) * sizeof (clib_bitmap_t));
Dave Wallace543852a2017-08-03 02:11:34 -04002975 }
2976
2977 do
2978 {
2979 /* *INDENT-OFF* */
Dave Wallacee22aa742017-10-20 12:30:38 -04002980 if (n_bits)
2981 {
2982 if (read_map)
Dave Wallace543852a2017-08-03 02:11:34 -04002983 {
Dave Wallacee22aa742017-10-20 12:30:38 -04002984 clib_bitmap_foreach (session_index, vcm->rd_bitmap,
2985 ({
Dave Wallace7e607a72018-06-18 18:41:32 -04002986 VCL_SESSION_LOCK();
Dave Wallacee22aa742017-10-20 12:30:38 -04002987 rv = vppcom_session_at_index (session_index, &session);
2988 if (rv < 0)
2989 {
Dave Wallace7e607a72018-06-18 18:41:32 -04002990 VCL_SESSION_UNLOCK();
Florin Coras0d427d82018-06-27 03:24:07 -07002991 VDBG (1, "VCL<%d>: session %d specified in read_map is"
2992 " closed.", getpid (),
Dave Wallacee22aa742017-10-20 12:30:38 -04002993 session_index);
2994 bits_set = VPPCOM_EBADFD;
2995 goto select_done;
2996 }
Dave Wallace8d73e852018-03-08 16:39:28 -05002997 if (session->state & STATE_LISTEN)
2998 {
2999 vce_event_handler_reg_t *reg = 0;
3000 vce_event_key_t evk;
Dave Wallacee22aa742017-10-20 12:30:38 -04003001
Dave Wallace8d73e852018-03-08 16:39:28 -05003002 /* Check if handler already registered for this
3003 * event.
3004 * If not, register handler for connect_request event
3005 * on listen_session_index
3006 */
3007 evk.session_index = session_index;
3008 evk.eid = VCL_EVENT_CONNECT_REQ_ACCEPTED;
3009 reg = vce_get_event_handler (&vcm->event_thread, &evk);
3010 if (!reg)
3011 reg = vce_register_handler (&vcm->event_thread, &evk,
Keith Burns (alagalah)0d2b0d52018-03-06 15:55:22 -08003012 vce_poll_wait_connect_request_handler_fn,
3013 0 /* No callback args */);
Dave Wallace8d73e852018-03-08 16:39:28 -05003014 rv = vppcom_session_read_ready (session, session_index);
3015 if (rv > 0)
3016 {
3017 vce_unregister_handler (&vcm->event_thread, reg);
3018 }
3019 }
3020 else
3021 rv = vppcom_session_read_ready (session, session_index);
Dave Wallace7e607a72018-06-18 18:41:32 -04003022 VCL_SESSION_UNLOCK();
Dave Wallacee22aa742017-10-20 12:30:38 -04003023 if (except_map && vcm->ex_bitmap &&
3024 clib_bitmap_get (vcm->ex_bitmap, session_index) &&
3025 (rv < 0))
3026 {
Dave Wallacee22aa742017-10-20 12:30:38 -04003027 clib_bitmap_set_no_check (except_map, session_index, 1);
3028 bits_set++;
3029 }
3030 else if (rv > 0)
3031 {
Dave Wallacee22aa742017-10-20 12:30:38 -04003032 clib_bitmap_set_no_check (read_map, session_index, 1);
3033 bits_set++;
3034 }
3035 }));
Dave Wallace543852a2017-08-03 02:11:34 -04003036 }
3037
Dave Wallacee22aa742017-10-20 12:30:38 -04003038 if (write_map)
Dave Wallace543852a2017-08-03 02:11:34 -04003039 {
Dave Wallacee22aa742017-10-20 12:30:38 -04003040 clib_bitmap_foreach (session_index, vcm->wr_bitmap,
3041 ({
Dave Wallace7e607a72018-06-18 18:41:32 -04003042 VCL_SESSION_LOCK();
Dave Wallacee22aa742017-10-20 12:30:38 -04003043 rv = vppcom_session_at_index (session_index, &session);
3044 if (rv < 0)
3045 {
Dave Wallace7e607a72018-06-18 18:41:32 -04003046 VCL_SESSION_UNLOCK();
Florin Coras0d427d82018-06-27 03:24:07 -07003047 VDBG (0, "VCL<%d>: session %d specified in "
Dave Wallace2e005bb2017-11-07 01:21:39 -05003048 "write_map is closed.", getpid (),
Dave Wallacee22aa742017-10-20 12:30:38 -04003049 session_index);
3050 bits_set = VPPCOM_EBADFD;
3051 goto select_done;
3052 }
Dave Wallace543852a2017-08-03 02:11:34 -04003053
Dave Wallacee22aa742017-10-20 12:30:38 -04003054 rv = vppcom_session_write_ready (session, session_index);
Dave Wallace7e607a72018-06-18 18:41:32 -04003055 VCL_SESSION_UNLOCK();
Dave Wallacee22aa742017-10-20 12:30:38 -04003056 if (write_map && (rv > 0))
3057 {
Dave Wallacee22aa742017-10-20 12:30:38 -04003058 clib_bitmap_set_no_check (write_map, session_index, 1);
3059 bits_set++;
3060 }
3061 }));
Dave Wallace543852a2017-08-03 02:11:34 -04003062 }
3063
Dave Wallacee22aa742017-10-20 12:30:38 -04003064 if (except_map)
Dave Wallace543852a2017-08-03 02:11:34 -04003065 {
Dave Wallacee22aa742017-10-20 12:30:38 -04003066 clib_bitmap_foreach (session_index, vcm->ex_bitmap,
3067 ({
Dave Wallace7e607a72018-06-18 18:41:32 -04003068 VCL_SESSION_LOCK();
Dave Wallacee22aa742017-10-20 12:30:38 -04003069 rv = vppcom_session_at_index (session_index, &session);
3070 if (rv < 0)
3071 {
Dave Wallace7e607a72018-06-18 18:41:32 -04003072 VCL_SESSION_UNLOCK();
Florin Coras0d427d82018-06-27 03:24:07 -07003073 VDBG (1, "VCL<%d>: session %d specified in except_map "
3074 "is closed.", getpid (),
Dave Wallacee22aa742017-10-20 12:30:38 -04003075 session_index);
3076 bits_set = VPPCOM_EBADFD;
3077 goto select_done;
3078 }
Dave Wallace543852a2017-08-03 02:11:34 -04003079
Dave Wallacee22aa742017-10-20 12:30:38 -04003080 rv = vppcom_session_read_ready (session, session_index);
Dave Wallace7e607a72018-06-18 18:41:32 -04003081 VCL_SESSION_UNLOCK();
Dave Wallacee22aa742017-10-20 12:30:38 -04003082 if (rv < 0)
3083 {
Dave Wallacee22aa742017-10-20 12:30:38 -04003084 clib_bitmap_set_no_check (except_map, session_index, 1);
3085 bits_set++;
3086 }
3087 }));
Dave Wallace543852a2017-08-03 02:11:34 -04003088 }
Dave Wallacee22aa742017-10-20 12:30:38 -04003089 }
Dave Wallace543852a2017-08-03 02:11:34 -04003090 /* *INDENT-ON* */
3091 }
Dave Wallace048b1d62018-01-03 22:24:41 -05003092 while ((time_to_wait == -1) || (clib_time_now (&vcm->clib_time) < timeout));
Dave Wallace543852a2017-08-03 02:11:34 -04003093
3094select_done:
3095 return (bits_set);
3096}
3097
Dave Wallacef7f809c2017-10-03 01:48:42 -04003098static inline void
3099vep_verify_epoll_chain (u32 vep_idx)
3100{
3101 session_t *session;
3102 vppcom_epoll_t *vep;
3103 int rv;
Dave Wallace498b3a52017-11-09 13:00:34 -05003104 u32 sid = vep_idx;
Dave Wallacef7f809c2017-10-03 01:48:42 -04003105
Dave Wallace498b3a52017-11-09 13:00:34 -05003106 if (VPPCOM_DEBUG <= 1)
Dave Wallacef7f809c2017-10-03 01:48:42 -04003107 return;
3108
3109 /* Assumes caller has acquired spinlock: vcm->sessions_lockp */
3110 rv = vppcom_session_at_index (vep_idx, &session);
3111 if (PREDICT_FALSE (rv))
3112 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003113 clib_warning ("VCL<%d>: ERROR: Invalid vep_idx (%u)!",
3114 getpid (), vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003115 goto done;
3116 }
3117 if (PREDICT_FALSE (!session->is_vep))
3118 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003119 clib_warning ("VCL<%d>: ERROR: vep_idx (%u) is not a vep!",
3120 getpid (), vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003121 goto done;
3122 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05003123 vep = &session->vep;
Dave Wallace048b1d62018-01-03 22:24:41 -05003124 clib_warning ("VCL<%d>: vep_idx (%u): Dumping epoll chain\n"
Dave Wallace498b3a52017-11-09 13:00:34 -05003125 "{\n"
3126 " is_vep = %u\n"
3127 " is_vep_session = %u\n"
Dave Wallace4878cbe2017-11-21 03:45:09 -05003128 " next_sid = 0x%x (%u)\n"
Dave Wallace498b3a52017-11-09 13:00:34 -05003129 " wait_cont_idx = 0x%x (%u)\n"
Dave Wallace4878cbe2017-11-21 03:45:09 -05003130 "}\n", getpid (), vep_idx,
3131 session->is_vep, session->is_vep_session,
3132 vep->next_sid, vep->next_sid,
Dave Wallace498b3a52017-11-09 13:00:34 -05003133 session->wait_cont_idx, session->wait_cont_idx);
Dave Wallace4878cbe2017-11-21 03:45:09 -05003134
3135 for (sid = vep->next_sid; sid != ~0; sid = vep->next_sid)
Dave Wallacef7f809c2017-10-03 01:48:42 -04003136 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05003137 rv = vppcom_session_at_index (sid, &session);
3138 if (PREDICT_FALSE (rv))
Dave Wallacef7f809c2017-10-03 01:48:42 -04003139 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003140 clib_warning ("VCL<%d>: ERROR: Invalid sid (%u)!", getpid (), sid);
Dave Wallace4878cbe2017-11-21 03:45:09 -05003141 goto done;
3142 }
3143 if (PREDICT_FALSE (session->is_vep))
Dave Wallace048b1d62018-01-03 22:24:41 -05003144 clib_warning ("VCL<%d>: ERROR: sid (%u) is a vep!",
3145 getpid (), vep_idx);
Dave Wallace4878cbe2017-11-21 03:45:09 -05003146 else if (PREDICT_FALSE (!session->is_vep_session))
3147 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003148 clib_warning ("VCL<%d>: ERROR: session (%u) "
3149 "is not a vep session!", getpid (), sid);
Dave Wallace4878cbe2017-11-21 03:45:09 -05003150 goto done;
3151 }
3152 vep = &session->vep;
3153 if (PREDICT_FALSE (vep->vep_idx != vep_idx))
Dave Wallace048b1d62018-01-03 22:24:41 -05003154 clib_warning ("VCL<%d>: ERROR: session (%u) vep_idx (%u) != "
Dave Wallace4878cbe2017-11-21 03:45:09 -05003155 "vep_idx (%u)!", getpid (),
3156 sid, session->vep.vep_idx, vep_idx);
3157 if (session->is_vep_session)
3158 {
3159 clib_warning ("vep_idx[%u]: sid 0x%x (%u)\n"
3160 "{\n"
3161 " next_sid = 0x%x (%u)\n"
3162 " prev_sid = 0x%x (%u)\n"
3163 " vep_idx = 0x%x (%u)\n"
3164 " ev.events = 0x%x\n"
3165 " ev.data.u64 = 0x%llx\n"
3166 " et_mask = 0x%x\n"
3167 "}\n",
3168 vep_idx, sid, sid,
3169 vep->next_sid, vep->next_sid,
3170 vep->prev_sid, vep->prev_sid,
3171 vep->vep_idx, vep->vep_idx,
3172 vep->ev.events, vep->ev.data.u64, vep->et_mask);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003173 }
3174 }
Dave Wallacef7f809c2017-10-03 01:48:42 -04003175
3176done:
Dave Wallace048b1d62018-01-03 22:24:41 -05003177 clib_warning ("VCL<%d>: vep_idx (%u): Dump complete!\n",
3178 getpid (), vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003179}
3180
3181int
3182vppcom_epoll_create (void)
3183{
Dave Wallacef7f809c2017-10-03 01:48:42 -04003184 session_t *vep_session;
3185 u32 vep_idx;
3186
Dave Wallace7e607a72018-06-18 18:41:32 -04003187 VCL_SESSION_LOCK ();
Dave Wallacef7f809c2017-10-03 01:48:42 -04003188 pool_get (vcm->sessions, vep_session);
3189 memset (vep_session, 0, sizeof (*vep_session));
3190 vep_idx = vep_session - vcm->sessions;
3191
3192 vep_session->is_vep = 1;
3193 vep_session->vep.vep_idx = ~0;
3194 vep_session->vep.next_sid = ~0;
3195 vep_session->vep.prev_sid = ~0;
3196 vep_session->wait_cont_idx = ~0;
Dave Wallace4878cbe2017-11-21 03:45:09 -05003197 vep_session->vpp_handle = ~0;
Keith Burns (alagalah)12756512018-03-06 05:55:27 -08003198 vep_session->poll_reg = 0;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003199
Florin Coras0d427d82018-06-27 03:24:07 -07003200 vcl_evt (VCL_EVT_EPOLL_CREATE, vep_session, vep_idx);
Dave Wallace7e607a72018-06-18 18:41:32 -04003201 VCL_SESSION_UNLOCK ();
Dave Wallacef7f809c2017-10-03 01:48:42 -04003202
Florin Coras0d427d82018-06-27 03:24:07 -07003203 VDBG (0, "VCL<%d>: Created vep_idx %u / sid %u!",
3204 getpid (), vep_idx, vep_idx);
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08003205
Dave Wallacef7f809c2017-10-03 01:48:42 -04003206 return (vep_idx);
3207}
3208
3209int
3210vppcom_epoll_ctl (uint32_t vep_idx, int op, uint32_t session_index,
3211 struct epoll_event *event)
3212{
Dave Wallacef7f809c2017-10-03 01:48:42 -04003213 session_t *vep_session;
3214 session_t *session;
3215 int rv;
3216
3217 if (vep_idx == session_index)
3218 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003219 clib_warning ("VCL<%d>: ERROR: vep_idx == session_index (%u)!",
Dave Wallace4878cbe2017-11-21 03:45:09 -05003220 getpid (), vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003221 return VPPCOM_EINVAL;
3222 }
3223
Dave Wallace7e607a72018-06-18 18:41:32 -04003224 VCL_SESSION_LOCK ();
Dave Wallacef7f809c2017-10-03 01:48:42 -04003225 rv = vppcom_session_at_index (vep_idx, &vep_session);
3226 if (PREDICT_FALSE (rv))
3227 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003228 clib_warning ("VCL<%d>: ERROR: Invalid vep_idx (%u)!", vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003229 goto done;
3230 }
3231 if (PREDICT_FALSE (!vep_session->is_vep))
3232 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003233 clib_warning ("VCL<%d>: ERROR: vep_idx (%u) is not a vep!",
Dave Wallace4878cbe2017-11-21 03:45:09 -05003234 getpid (), vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003235 rv = VPPCOM_EINVAL;
3236 goto done;
3237 }
3238
3239 ASSERT (vep_session->vep.vep_idx == ~0);
3240 ASSERT (vep_session->vep.prev_sid == ~0);
3241
3242 rv = vppcom_session_at_index (session_index, &session);
3243 if (PREDICT_FALSE (rv))
3244 {
Florin Coras0d427d82018-06-27 03:24:07 -07003245 VDBG (0, "VCL<%d>: ERROR: Invalid session_index (%u)!",
3246 getpid (), session_index);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003247 goto done;
3248 }
3249 if (PREDICT_FALSE (session->is_vep))
3250 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05003251 clib_warning ("ERROR: session_index (%u) is a vep!", vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003252 rv = VPPCOM_EINVAL;
3253 goto done;
3254 }
3255
3256 switch (op)
3257 {
3258 case EPOLL_CTL_ADD:
3259 if (PREDICT_FALSE (!event))
3260 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003261 clib_warning ("VCL<%d>: ERROR: EPOLL_CTL_ADD: NULL pointer to "
Dave Wallace2e005bb2017-11-07 01:21:39 -05003262 "epoll_event structure!", getpid ());
Dave Wallacef7f809c2017-10-03 01:48:42 -04003263 rv = VPPCOM_EINVAL;
3264 goto done;
3265 }
3266 if (vep_session->vep.next_sid != ~0)
3267 {
3268 session_t *next_session;
3269 rv = vppcom_session_at_index (vep_session->vep.next_sid,
3270 &next_session);
3271 if (PREDICT_FALSE (rv))
3272 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003273 clib_warning ("VCL<%d>: ERROR: EPOLL_CTL_ADD: Invalid "
Dave Wallace4878cbe2017-11-21 03:45:09 -05003274 "vep.next_sid (%u) on vep_idx (%u)!",
3275 getpid (), vep_session->vep.next_sid, vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003276 goto done;
3277 }
3278 ASSERT (next_session->vep.prev_sid == vep_idx);
3279 next_session->vep.prev_sid = session_index;
3280 }
3281 session->vep.next_sid = vep_session->vep.next_sid;
3282 session->vep.prev_sid = vep_idx;
3283 session->vep.vep_idx = vep_idx;
3284 session->vep.et_mask = VEP_DEFAULT_ET_MASK;
3285 session->vep.ev = *event;
Dave Wallace4878cbe2017-11-21 03:45:09 -05003286 session->is_vep = 0;
Dave Wallacef7f809c2017-10-03 01:48:42 -04003287 session->is_vep_session = 1;
3288 vep_session->vep.next_sid = session_index;
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08003289
3290 /* VCL Event Register handler */
3291 if (session->state & STATE_LISTEN)
3292 {
3293 /* Register handler for connect_request event on listen_session_index */
3294 vce_event_key_t evk;
3295 evk.session_index = session_index;
3296 evk.eid = VCL_EVENT_CONNECT_REQ_ACCEPTED;
Keith Burns (alagalah)12756512018-03-06 05:55:27 -08003297 vep_session->poll_reg =
3298 vce_register_handler (&vcm->event_thread, &evk,
Keith Burns (alagalah)0d2b0d52018-03-06 15:55:22 -08003299 vce_poll_wait_connect_request_handler_fn,
3300 0 /* No callback args */ );
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08003301 }
Florin Coras0d427d82018-06-27 03:24:07 -07003302 VDBG (1, "VCL<%d>: EPOLL_CTL_ADD: vep_idx %u, "
3303 "sid %u, events 0x%x, data 0x%llx!",
3304 getpid (), vep_idx, session_index,
3305 event->events, event->data.u64);
3306 vcl_evt (VCL_EVT_EPOLL_CTLADD, session, event->events, event->data.u64);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003307 break;
3308
3309 case EPOLL_CTL_MOD:
3310 if (PREDICT_FALSE (!event))
3311 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003312 clib_warning ("VCL<%d>: ERROR: EPOLL_CTL_MOD: NULL pointer to "
Dave Wallace2e005bb2017-11-07 01:21:39 -05003313 "epoll_event structure!", getpid ());
Dave Wallacef7f809c2017-10-03 01:48:42 -04003314 rv = VPPCOM_EINVAL;
3315 goto done;
3316 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05003317 else if (PREDICT_FALSE (!session->is_vep_session))
Dave Wallacef7f809c2017-10-03 01:48:42 -04003318 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003319 clib_warning ("VCL<%d>: ERROR: sid %u EPOLL_CTL_MOD: "
Dave Wallace4878cbe2017-11-21 03:45:09 -05003320 "not a vep session!", getpid (), session_index);
3321 rv = VPPCOM_EINVAL;
3322 goto done;
3323 }
3324 else if (PREDICT_FALSE (session->vep.vep_idx != vep_idx))
3325 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003326 clib_warning ("VCL<%d>: ERROR: sid %u EPOLL_CTL_MOD: "
Dave Wallace4878cbe2017-11-21 03:45:09 -05003327 "vep_idx (%u) != vep_idx (%u)!",
3328 getpid (), session_index,
3329 session->vep.vep_idx, vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003330 rv = VPPCOM_EINVAL;
3331 goto done;
3332 }
3333 session->vep.et_mask = VEP_DEFAULT_ET_MASK;
3334 session->vep.ev = *event;
Florin Coras0d427d82018-06-27 03:24:07 -07003335 VDBG (1, "VCL<%d>: EPOLL_CTL_MOD: vep_idx %u, sid %u, events 0x%x,"
3336 " data 0x%llx!", getpid (), vep_idx, session_index, event->events,
3337 event->data.u64);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003338 break;
3339
3340 case EPOLL_CTL_DEL:
Dave Wallace4878cbe2017-11-21 03:45:09 -05003341 if (PREDICT_FALSE (!session->is_vep_session))
Dave Wallacef7f809c2017-10-03 01:48:42 -04003342 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003343 clib_warning ("VCL<%d>: ERROR: sid %u EPOLL_CTL_DEL: "
Dave Wallace4878cbe2017-11-21 03:45:09 -05003344 "not a vep session!", getpid (), session_index);
3345 rv = VPPCOM_EINVAL;
3346 goto done;
3347 }
3348 else if (PREDICT_FALSE (session->vep.vep_idx != vep_idx))
3349 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003350 clib_warning ("VCL<%d>: ERROR: sid %u EPOLL_CTL_DEL: "
Dave Wallace4878cbe2017-11-21 03:45:09 -05003351 "vep_idx (%u) != vep_idx (%u)!",
3352 getpid (), session_index,
3353 session->vep.vep_idx, vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003354 rv = VPPCOM_EINVAL;
3355 goto done;
3356 }
3357
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08003358 /* VCL Event Un-register handler */
Keith Burns (alagalah)12756512018-03-06 05:55:27 -08003359 if ((session->state & STATE_LISTEN) && vep_session->poll_reg)
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08003360 {
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08003361 (void) vce_unregister_handler (&vcm->event_thread,
3362 vep_session->poll_reg);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08003363 }
3364
Dave Wallacef7f809c2017-10-03 01:48:42 -04003365 vep_session->wait_cont_idx =
3366 (vep_session->wait_cont_idx == session_index) ?
3367 session->vep.next_sid : vep_session->wait_cont_idx;
3368
3369 if (session->vep.prev_sid == vep_idx)
3370 vep_session->vep.next_sid = session->vep.next_sid;
3371 else
3372 {
3373 session_t *prev_session;
3374 rv = vppcom_session_at_index (session->vep.prev_sid, &prev_session);
3375 if (PREDICT_FALSE (rv))
3376 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003377 clib_warning ("VCL<%d>: ERROR: EPOLL_CTL_DEL: Invalid "
Dave Wallace4878cbe2017-11-21 03:45:09 -05003378 "vep.prev_sid (%u) on sid (%u)!",
3379 getpid (), session->vep.prev_sid, session_index);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003380 goto done;
3381 }
3382 ASSERT (prev_session->vep.next_sid == session_index);
3383 prev_session->vep.next_sid = session->vep.next_sid;
3384 }
3385 if (session->vep.next_sid != ~0)
3386 {
3387 session_t *next_session;
3388 rv = vppcom_session_at_index (session->vep.next_sid, &next_session);
3389 if (PREDICT_FALSE (rv))
3390 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003391 clib_warning ("VCL<%d>: ERROR: EPOLL_CTL_DEL: Invalid "
Dave Wallace4878cbe2017-11-21 03:45:09 -05003392 "vep.next_sid (%u) on sid (%u)!",
3393 getpid (), session->vep.next_sid, session_index);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003394 goto done;
3395 }
3396 ASSERT (next_session->vep.prev_sid == session_index);
3397 next_session->vep.prev_sid = session->vep.prev_sid;
3398 }
3399
3400 memset (&session->vep, 0, sizeof (session->vep));
3401 session->vep.next_sid = ~0;
3402 session->vep.prev_sid = ~0;
3403 session->vep.vep_idx = ~0;
3404 session->is_vep_session = 0;
Florin Coras0d427d82018-06-27 03:24:07 -07003405 VDBG (1, "VCL<%d>: EPOLL_CTL_DEL: vep_idx %u, sid %u!",
3406 getpid (), vep_idx, session_index);
3407 vcl_evt (VCL_EVT_EPOLL_CTLDEL, session, vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003408 break;
3409
3410 default:
Dave Wallace048b1d62018-01-03 22:24:41 -05003411 clib_warning ("VCL<%d>: ERROR: Invalid operation (%d)!", getpid (), op);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003412 rv = VPPCOM_EINVAL;
3413 }
3414
3415 vep_verify_epoll_chain (vep_idx);
3416
3417done:
Dave Wallace7e607a72018-06-18 18:41:32 -04003418 VCL_SESSION_UNLOCK ();
Dave Wallacef7f809c2017-10-03 01:48:42 -04003419 return rv;
3420}
3421
Dave Wallacef7f809c2017-10-03 01:48:42 -04003422int
3423vppcom_epoll_wait (uint32_t vep_idx, struct epoll_event *events,
3424 int maxevents, double wait_for_time)
3425{
Dave Wallacef7f809c2017-10-03 01:48:42 -04003426 session_t *vep_session;
3427 int rv;
3428 f64 timeout = clib_time_now (&vcm->clib_time) + wait_for_time;
Dave Wallace2e005bb2017-11-07 01:21:39 -05003429 u32 keep_trying = 1;
Dave Wallacef7f809c2017-10-03 01:48:42 -04003430 int num_ev = 0;
3431 u32 vep_next_sid, wait_cont_idx;
3432 u8 is_vep;
3433
3434 if (PREDICT_FALSE (maxevents <= 0))
3435 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003436 clib_warning ("VCL<%d>: ERROR: Invalid maxevents (%d)!",
Dave Wallace4878cbe2017-11-21 03:45:09 -05003437 getpid (), maxevents);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003438 return VPPCOM_EINVAL;
3439 }
Dave Wallacef7f809c2017-10-03 01:48:42 -04003440 memset (events, 0, sizeof (*events) * maxevents);
3441
Dave Wallace7e607a72018-06-18 18:41:32 -04003442 VCL_SESSION_LOCK_AND_GET (vep_idx, &vep_session);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003443 vep_next_sid = vep_session->vep.next_sid;
3444 is_vep = vep_session->is_vep;
3445 wait_cont_idx = vep_session->wait_cont_idx;
Dave Wallace7e607a72018-06-18 18:41:32 -04003446 VCL_SESSION_UNLOCK ();
Dave Wallacef7f809c2017-10-03 01:48:42 -04003447
3448 if (PREDICT_FALSE (!is_vep))
3449 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003450 clib_warning ("VCL<%d>: ERROR: vep_idx (%u) is not a vep!",
Dave Wallace4878cbe2017-11-21 03:45:09 -05003451 getpid (), vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003452 rv = VPPCOM_EINVAL;
3453 goto done;
3454 }
Dave Wallacee695cb42017-11-02 22:04:42 -04003455 if (PREDICT_FALSE (vep_next_sid == ~0))
Dave Wallacef7f809c2017-10-03 01:48:42 -04003456 {
Florin Coras0d427d82018-06-27 03:24:07 -07003457 VDBG (1, "VCL<%d>: WARNING: vep_idx (%u) is empty!",
3458 getpid (), vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003459 goto done;
3460 }
3461
3462 do
3463 {
3464 u32 sid;
3465 u32 next_sid = ~0;
3466 session_t *session;
3467
3468 for (sid = (wait_cont_idx == ~0) ? vep_next_sid : wait_cont_idx;
3469 sid != ~0; sid = next_sid)
3470 {
3471 u32 session_events, et_mask, clear_et_mask, session_vep_idx;
3472 u8 add_event, is_vep_session;
3473 int ready;
3474 u64 session_ev_data;
3475
Dave Wallace7e607a72018-06-18 18:41:32 -04003476 VCL_SESSION_LOCK_AND_GET (sid, &session);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003477 next_sid = session->vep.next_sid;
3478 session_events = session->vep.ev.events;
3479 et_mask = session->vep.et_mask;
3480 is_vep = session->is_vep;
3481 is_vep_session = session->is_vep_session;
3482 session_vep_idx = session->vep.vep_idx;
3483 session_ev_data = session->vep.ev.data.u64;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003484
Dave Wallace7e607a72018-06-18 18:41:32 -04003485 VCL_SESSION_UNLOCK ();
Dave Wallacef7f809c2017-10-03 01:48:42 -04003486
3487 if (PREDICT_FALSE (is_vep))
3488 {
Florin Coras0d427d82018-06-27 03:24:07 -07003489 VDBG (0, "VCL<%d>: ERROR: sid (%u) is a vep!",
3490 getpid (), vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003491 rv = VPPCOM_EINVAL;
3492 goto done;
3493 }
3494 if (PREDICT_FALSE (!is_vep_session))
3495 {
Florin Coras0d427d82018-06-27 03:24:07 -07003496 VDBG (0, "VCL<%d>: ERROR: session (%u) is not "
3497 "a vep session!", getpid (), sid);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003498 rv = VPPCOM_EINVAL;
3499 goto done;
3500 }
3501 if (PREDICT_FALSE (session_vep_idx != vep_idx))
3502 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003503 clib_warning ("VCL<%d>: ERROR: session (%u) "
Dave Wallacef7f809c2017-10-03 01:48:42 -04003504 "vep_idx (%u) != vep_idx (%u)!",
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003505 getpid (), sid, session_vep_idx, vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003506 rv = VPPCOM_EINVAL;
3507 goto done;
3508 }
3509
3510 add_event = clear_et_mask = 0;
3511
Dave Wallace60caa062017-11-10 17:07:13 -05003512 if (EPOLLIN & session_events)
Dave Wallacef7f809c2017-10-03 01:48:42 -04003513 {
Dave Wallace7e607a72018-06-18 18:41:32 -04003514 VCL_SESSION_LOCK_AND_GET (sid, &session);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003515 ready = vppcom_session_read_ready (session, sid);
Dave Wallace7e607a72018-06-18 18:41:32 -04003516 VCL_SESSION_UNLOCK ();
Dave Wallace60caa062017-11-10 17:07:13 -05003517 if ((ready > 0) && (EPOLLIN & et_mask))
Dave Wallacef7f809c2017-10-03 01:48:42 -04003518 {
3519 add_event = 1;
3520 events[num_ev].events |= EPOLLIN;
Dave Wallace60caa062017-11-10 17:07:13 -05003521 if (((EPOLLET | EPOLLIN) & session_events) ==
3522 (EPOLLET | EPOLLIN))
Dave Wallacef7f809c2017-10-03 01:48:42 -04003523 clear_et_mask |= EPOLLIN;
3524 }
3525 else if (ready < 0)
3526 {
3527 add_event = 1;
3528 switch (ready)
3529 {
3530 case VPPCOM_ECONNRESET:
3531 events[num_ev].events |= EPOLLHUP | EPOLLRDHUP;
3532 break;
3533
3534 default:
3535 events[num_ev].events |= EPOLLERR;
3536 break;
3537 }
3538 }
3539 }
3540
Dave Wallace60caa062017-11-10 17:07:13 -05003541 if (EPOLLOUT & session_events)
Dave Wallacef7f809c2017-10-03 01:48:42 -04003542 {
Dave Wallace7e607a72018-06-18 18:41:32 -04003543 VCL_SESSION_LOCK_AND_GET (sid, &session);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003544 ready = vppcom_session_write_ready (session, sid);
Dave Wallace7e607a72018-06-18 18:41:32 -04003545 VCL_SESSION_UNLOCK ();
Dave Wallace60caa062017-11-10 17:07:13 -05003546 if ((ready > 0) && (EPOLLOUT & et_mask))
Dave Wallacef7f809c2017-10-03 01:48:42 -04003547 {
3548 add_event = 1;
3549 events[num_ev].events |= EPOLLOUT;
Dave Wallace60caa062017-11-10 17:07:13 -05003550 if (((EPOLLET | EPOLLOUT) & session_events) ==
3551 (EPOLLET | EPOLLOUT))
Dave Wallacef7f809c2017-10-03 01:48:42 -04003552 clear_et_mask |= EPOLLOUT;
3553 }
3554 else if (ready < 0)
3555 {
3556 add_event = 1;
3557 switch (ready)
3558 {
3559 case VPPCOM_ECONNRESET:
3560 events[num_ev].events |= EPOLLHUP;
3561 break;
3562
3563 default:
3564 events[num_ev].events |= EPOLLERR;
3565 break;
3566 }
3567 }
3568 }
3569
3570 if (add_event)
3571 {
3572 events[num_ev].data.u64 = session_ev_data;
3573 if (EPOLLONESHOT & session_events)
3574 {
Dave Wallace7e607a72018-06-18 18:41:32 -04003575 VCL_SESSION_LOCK_AND_GET (sid, &session);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003576 session->vep.ev.events = 0;
Dave Wallace7e607a72018-06-18 18:41:32 -04003577 VCL_SESSION_UNLOCK ();
Dave Wallacef7f809c2017-10-03 01:48:42 -04003578 }
3579 num_ev++;
3580 if (num_ev == maxevents)
3581 {
Dave Wallace7e607a72018-06-18 18:41:32 -04003582 VCL_SESSION_LOCK_AND_GET (vep_idx, &vep_session);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003583 vep_session->wait_cont_idx = next_sid;
Dave Wallace7e607a72018-06-18 18:41:32 -04003584 VCL_SESSION_UNLOCK ();
Dave Wallacef7f809c2017-10-03 01:48:42 -04003585 goto done;
3586 }
3587 }
3588 if (wait_cont_idx != ~0)
3589 {
3590 if (next_sid == ~0)
3591 next_sid = vep_next_sid;
3592 else if (next_sid == wait_cont_idx)
3593 next_sid = ~0;
3594 }
3595 }
Dave Wallace2e005bb2017-11-07 01:21:39 -05003596 if (wait_for_time != -1)
3597 keep_trying = (clib_time_now (&vcm->clib_time) <= timeout) ? 1 : 0;
Dave Wallacef7f809c2017-10-03 01:48:42 -04003598 }
Dave Wallace2e005bb2017-11-07 01:21:39 -05003599 while ((num_ev == 0) && keep_trying);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003600
3601 if (wait_cont_idx != ~0)
3602 {
Dave Wallace7e607a72018-06-18 18:41:32 -04003603 VCL_SESSION_LOCK_AND_GET (vep_idx, &vep_session);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003604 vep_session->wait_cont_idx = ~0;
Dave Wallace7e607a72018-06-18 18:41:32 -04003605 VCL_SESSION_UNLOCK ();
Dave Wallacef7f809c2017-10-03 01:48:42 -04003606 }
3607done:
3608 return (rv != VPPCOM_OK) ? rv : num_ev;
3609}
3610
Dave Wallace35830af2017-10-09 01:43:42 -04003611int
3612vppcom_session_attr (uint32_t session_index, uint32_t op,
3613 void *buffer, uint32_t * buflen)
3614{
Dave Wallace35830af2017-10-09 01:43:42 -04003615 session_t *session;
3616 int rv = VPPCOM_OK;
3617 u32 *flags = buffer;
Steven2199aab2017-10-15 20:18:47 -07003618 vppcom_endpt_t *ep = buffer;
Dave Wallace35830af2017-10-09 01:43:42 -04003619
Dave Wallace7e607a72018-06-18 18:41:32 -04003620 VCL_SESSION_LOCK_AND_GET (session_index, &session);
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003621
3622 ASSERT (session);
3623
Dave Wallace35830af2017-10-09 01:43:42 -04003624 switch (op)
3625 {
3626 case VPPCOM_ATTR_GET_NREAD:
3627 rv = vppcom_session_read_ready (session, session_index);
Florin Coras0d427d82018-06-27 03:24:07 -07003628 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_NREAD: sid %u, nread = %d",
3629 getpid (), rv);
Dave Wallace35830af2017-10-09 01:43:42 -04003630 break;
3631
Dave Wallace227867f2017-11-13 21:21:53 -05003632 case VPPCOM_ATTR_GET_NWRITE:
3633 rv = vppcom_session_write_ready (session, session_index);
Florin Coras0d427d82018-06-27 03:24:07 -07003634 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_NWRITE: sid %u, nwrite = %d",
3635 getpid (), session_index, rv);
Dave Wallace35830af2017-10-09 01:43:42 -04003636 break;
3637
3638 case VPPCOM_ATTR_GET_FLAGS:
Dave Wallace048b1d62018-01-03 22:24:41 -05003639 if (PREDICT_TRUE (buffer && buflen && (*buflen >= sizeof (*flags))))
Dave Wallace35830af2017-10-09 01:43:42 -04003640 {
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003641 *flags = O_RDWR | (VCL_SESS_ATTR_TEST (session->attr,
3642 VCL_SESS_ATTR_NONBLOCK));
Dave Wallace35830af2017-10-09 01:43:42 -04003643 *buflen = sizeof (*flags);
Florin Coras0d427d82018-06-27 03:24:07 -07003644 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_FLAGS: sid %u, flags = 0x%08x, "
3645 "is_nonblocking = %u", getpid (),
3646 session_index, *flags,
3647 VCL_SESS_ATTR_TEST (session->attr, VCL_SESS_ATTR_NONBLOCK));
Dave Wallace35830af2017-10-09 01:43:42 -04003648 }
3649 else
3650 rv = VPPCOM_EINVAL;
3651 break;
3652
3653 case VPPCOM_ATTR_SET_FLAGS:
Dave Wallace048b1d62018-01-03 22:24:41 -05003654 if (PREDICT_TRUE (buffer && buflen && (*buflen == sizeof (*flags))))
Dave Wallace35830af2017-10-09 01:43:42 -04003655 {
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003656 if (*flags & O_NONBLOCK)
3657 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_NONBLOCK);
3658 else
3659 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_NONBLOCK);
3660
Florin Coras0d427d82018-06-27 03:24:07 -07003661 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_FLAGS: sid %u, flags = 0x%08x,"
3662 " is_nonblocking = %u",
3663 getpid (), session_index, *flags,
3664 VCL_SESS_ATTR_TEST (session->attr, VCL_SESS_ATTR_NONBLOCK));
Dave Wallace35830af2017-10-09 01:43:42 -04003665 }
3666 else
3667 rv = VPPCOM_EINVAL;
3668 break;
3669
3670 case VPPCOM_ATTR_GET_PEER_ADDR:
Dave Wallace048b1d62018-01-03 22:24:41 -05003671 if (PREDICT_TRUE (buffer && buflen &&
3672 (*buflen >= sizeof (*ep)) && ep->ip))
Dave Wallace35830af2017-10-09 01:43:42 -04003673 {
Steven2199aab2017-10-15 20:18:47 -07003674 ep->is_ip4 = session->peer_addr.is_ip4;
Stevenac1f96d2017-10-24 16:03:58 -07003675 ep->port = session->peer_port;
Steven2199aab2017-10-15 20:18:47 -07003676 if (session->peer_addr.is_ip4)
3677 clib_memcpy (ep->ip, &session->peer_addr.ip46.ip4,
3678 sizeof (ip4_address_t));
3679 else
3680 clib_memcpy (ep->ip, &session->peer_addr.ip46.ip6,
3681 sizeof (ip6_address_t));
3682 *buflen = sizeof (*ep);
Florin Coras0d427d82018-06-27 03:24:07 -07003683 VDBG (1, "VCL<%d>: VPPCOM_ATTR_GET_PEER_ADDR: sid %u, is_ip4 = %u, "
3684 "addr = %U, port %u", getpid (),
3685 session_index, ep->is_ip4, format_ip46_address,
3686 &session->peer_addr.ip46,
3687 ep->is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6,
3688 clib_net_to_host_u16 (ep->port));
Dave Wallace35830af2017-10-09 01:43:42 -04003689 }
3690 else
3691 rv = VPPCOM_EINVAL;
3692 break;
3693
3694 case VPPCOM_ATTR_GET_LCL_ADDR:
Dave Wallace048b1d62018-01-03 22:24:41 -05003695 if (PREDICT_TRUE (buffer && buflen &&
3696 (*buflen >= sizeof (*ep)) && ep->ip))
Dave Wallace35830af2017-10-09 01:43:42 -04003697 {
Steven2199aab2017-10-15 20:18:47 -07003698 ep->is_ip4 = session->lcl_addr.is_ip4;
Stevenac1f96d2017-10-24 16:03:58 -07003699 ep->port = session->lcl_port;
Steven2199aab2017-10-15 20:18:47 -07003700 if (session->lcl_addr.is_ip4)
3701 clib_memcpy (ep->ip, &session->lcl_addr.ip46.ip4,
3702 sizeof (ip4_address_t));
3703 else
3704 clib_memcpy (ep->ip, &session->lcl_addr.ip46.ip6,
3705 sizeof (ip6_address_t));
3706 *buflen = sizeof (*ep);
Florin Coras0d427d82018-06-27 03:24:07 -07003707 VDBG (1, "VCL<%d>: VPPCOM_ATTR_GET_LCL_ADDR: sid %u, is_ip4 = %u,"
3708 " addr = %U port %d", getpid (),
3709 session_index, ep->is_ip4, format_ip46_address,
3710 &session->lcl_addr.ip46,
3711 ep->is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6,
3712 clib_net_to_host_u16 (ep->port));
Dave Wallace35830af2017-10-09 01:43:42 -04003713 }
3714 else
3715 rv = VPPCOM_EINVAL;
3716 break;
Stevenb5a11602017-10-11 09:59:30 -07003717
Dave Wallace048b1d62018-01-03 22:24:41 -05003718 case VPPCOM_ATTR_GET_LIBC_EPFD:
3719 rv = session->libc_epfd;
Florin Coras0d427d82018-06-27 03:24:07 -07003720 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_LIBC_EPFD: libc_epfd %d",
3721 getpid (), rv);
Dave Wallace048b1d62018-01-03 22:24:41 -05003722 break;
3723
3724 case VPPCOM_ATTR_SET_LIBC_EPFD:
3725 if (PREDICT_TRUE (buffer && buflen &&
3726 (*buflen == sizeof (session->libc_epfd))))
3727 {
3728 session->libc_epfd = *(int *) buffer;
3729 *buflen = sizeof (session->libc_epfd);
3730
Florin Coras0d427d82018-06-27 03:24:07 -07003731 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_LIBC_EPFD: libc_epfd %d, "
3732 "buflen %d", getpid (), session->libc_epfd, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003733 }
3734 else
3735 rv = VPPCOM_EINVAL;
3736 break;
3737
3738 case VPPCOM_ATTR_GET_PROTOCOL:
3739 if (buffer && buflen && (*buflen >= sizeof (int)))
3740 {
3741 *(int *) buffer = session->proto;
3742 *buflen = sizeof (int);
3743
Florin Coras0d427d82018-06-27 03:24:07 -07003744 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_PROTOCOL: %d (%s), buflen %d",
3745 getpid (), *(int *) buffer, *(int *) buffer ? "UDP" : "TCP",
3746 *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003747 }
3748 else
3749 rv = VPPCOM_EINVAL;
3750 break;
3751
3752 case VPPCOM_ATTR_GET_LISTEN:
3753 if (buffer && buflen && (*buflen >= sizeof (int)))
3754 {
3755 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
3756 VCL_SESS_ATTR_LISTEN);
3757 *buflen = sizeof (int);
3758
Florin Coras0d427d82018-06-27 03:24:07 -07003759 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_LISTEN: %d, buflen %d",
3760 getpid (), *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003761 }
3762 else
3763 rv = VPPCOM_EINVAL;
3764 break;
3765
3766 case VPPCOM_ATTR_GET_ERROR:
3767 if (buffer && buflen && (*buflen >= sizeof (int)))
3768 {
3769 *(int *) buffer = 0;
3770 *buflen = sizeof (int);
3771
Florin Coras0d427d82018-06-27 03:24:07 -07003772 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_ERROR: %d, buflen %d, #VPP-TBD#",
3773 getpid (), *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003774 }
3775 else
3776 rv = VPPCOM_EINVAL;
3777 break;
3778
3779 case VPPCOM_ATTR_GET_TX_FIFO_LEN:
3780 if (buffer && buflen && (*buflen >= sizeof (u32)))
3781 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003782
3783 /* VPP-TBD */
3784 *(size_t *) buffer = (session->sndbuf_size ? session->sndbuf_size :
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003785 session->tx_fifo ? session->tx_fifo->nitems :
Dave Wallace048b1d62018-01-03 22:24:41 -05003786 vcm->cfg.tx_fifo_size);
3787 *buflen = sizeof (u32);
3788
Florin Coras0d427d82018-06-27 03:24:07 -07003789 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_TX_FIFO_LEN: %u (0x%x), "
3790 "buflen %d, #VPP-TBD#", getpid (),
3791 *(size_t *) buffer, *(size_t *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003792 }
3793 else
3794 rv = VPPCOM_EINVAL;
3795 break;
3796
3797 case VPPCOM_ATTR_SET_TX_FIFO_LEN:
3798 if (buffer && buflen && (*buflen == sizeof (u32)))
3799 {
3800 /* VPP-TBD */
3801 session->sndbuf_size = *(u32 *) buffer;
Florin Coras0d427d82018-06-27 03:24:07 -07003802 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_TX_FIFO_LEN: %u (0x%x), "
3803 "buflen %d, #VPP-TBD#", getpid (),
3804 session->sndbuf_size, session->sndbuf_size, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003805 }
3806 else
3807 rv = VPPCOM_EINVAL;
3808 break;
3809
3810 case VPPCOM_ATTR_GET_RX_FIFO_LEN:
3811 if (buffer && buflen && (*buflen >= sizeof (u32)))
3812 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003813
3814 /* VPP-TBD */
3815 *(size_t *) buffer = (session->rcvbuf_size ? session->rcvbuf_size :
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003816 session->rx_fifo ? session->rx_fifo->nitems :
Dave Wallace048b1d62018-01-03 22:24:41 -05003817 vcm->cfg.rx_fifo_size);
3818 *buflen = sizeof (u32);
3819
Florin Coras0d427d82018-06-27 03:24:07 -07003820 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_RX_FIFO_LEN: %u (0x%x), "
3821 "buflen %d, #VPP-TBD#", getpid (),
3822 *(size_t *) buffer, *(size_t *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003823 }
3824 else
3825 rv = VPPCOM_EINVAL;
3826 break;
3827
3828 case VPPCOM_ATTR_SET_RX_FIFO_LEN:
3829 if (buffer && buflen && (*buflen == sizeof (u32)))
3830 {
3831 /* VPP-TBD */
3832 session->rcvbuf_size = *(u32 *) buffer;
Florin Coras0d427d82018-06-27 03:24:07 -07003833 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_RX_FIFO_LEN: %u (0x%x), "
3834 "buflen %d, #VPP-TBD#", getpid (),
3835 session->sndbuf_size, session->sndbuf_size, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003836 }
3837 else
3838 rv = VPPCOM_EINVAL;
3839 break;
3840
3841 case VPPCOM_ATTR_GET_REUSEADDR:
3842 if (buffer && buflen && (*buflen >= sizeof (int)))
3843 {
3844 /* VPP-TBD */
3845 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
3846 VCL_SESS_ATTR_REUSEADDR);
3847 *buflen = sizeof (int);
3848
Florin Coras0d427d82018-06-27 03:24:07 -07003849 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_REUSEADDR: %d, "
3850 "buflen %d, #VPP-TBD#", getpid (), *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003851 }
3852 else
3853 rv = VPPCOM_EINVAL;
3854 break;
3855
Stevenb5a11602017-10-11 09:59:30 -07003856 case VPPCOM_ATTR_SET_REUSEADDR:
Dave Wallace048b1d62018-01-03 22:24:41 -05003857 if (buffer && buflen && (*buflen == sizeof (int)) &&
3858 !VCL_SESS_ATTR_TEST (session->attr, VCL_SESS_ATTR_LISTEN))
3859 {
3860 /* VPP-TBD */
3861 if (*(int *) buffer)
3862 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_REUSEADDR);
3863 else
3864 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_REUSEADDR);
3865
Florin Coras0d427d82018-06-27 03:24:07 -07003866 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_REUSEADDR: %d, buflen %d,"
3867 " #VPP-TBD#", getpid (),
3868 VCL_SESS_ATTR_TEST (session->attr,
3869 VCL_SESS_ATTR_REUSEADDR), *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003870 }
3871 else
3872 rv = VPPCOM_EINVAL;
3873 break;
3874
3875 case VPPCOM_ATTR_GET_REUSEPORT:
3876 if (buffer && buflen && (*buflen >= sizeof (int)))
3877 {
3878 /* VPP-TBD */
3879 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
3880 VCL_SESS_ATTR_REUSEPORT);
3881 *buflen = sizeof (int);
3882
Florin Coras0d427d82018-06-27 03:24:07 -07003883 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_REUSEPORT: %d, buflen %d,"
3884 " #VPP-TBD#", getpid (), *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003885 }
3886 else
3887 rv = VPPCOM_EINVAL;
3888 break;
3889
3890 case VPPCOM_ATTR_SET_REUSEPORT:
3891 if (buffer && buflen && (*buflen == sizeof (int)) &&
3892 !VCL_SESS_ATTR_TEST (session->attr, VCL_SESS_ATTR_LISTEN))
3893 {
3894 /* VPP-TBD */
3895 if (*(int *) buffer)
3896 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_REUSEPORT);
3897 else
3898 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_REUSEPORT);
3899
Florin Coras0d427d82018-06-27 03:24:07 -07003900 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_REUSEPORT: %d, buflen %d,"
3901 " #VPP-TBD#", getpid (),
3902 VCL_SESS_ATTR_TEST (session->attr,
3903 VCL_SESS_ATTR_REUSEPORT), *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003904 }
3905 else
3906 rv = VPPCOM_EINVAL;
3907 break;
3908
3909 case VPPCOM_ATTR_GET_BROADCAST:
3910 if (buffer && buflen && (*buflen >= sizeof (int)))
3911 {
3912 /* VPP-TBD */
3913 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
3914 VCL_SESS_ATTR_BROADCAST);
3915 *buflen = sizeof (int);
3916
Florin Coras0d427d82018-06-27 03:24:07 -07003917 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_BROADCAST: %d, buflen %d,"
3918 " #VPP-TBD#", getpid (), *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003919 }
3920 else
3921 rv = VPPCOM_EINVAL;
Stevenb5a11602017-10-11 09:59:30 -07003922 break;
3923
3924 case VPPCOM_ATTR_SET_BROADCAST:
Dave Wallace048b1d62018-01-03 22:24:41 -05003925 if (buffer && buflen && (*buflen == sizeof (int)))
3926 {
3927 /* VPP-TBD */
3928 if (*(int *) buffer)
3929 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_BROADCAST);
3930 else
3931 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_BROADCAST);
3932
Florin Coras0d427d82018-06-27 03:24:07 -07003933 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_BROADCAST: %d, buflen %d, "
3934 "#VPP-TBD#", getpid (),
3935 VCL_SESS_ATTR_TEST (session->attr,
3936 VCL_SESS_ATTR_BROADCAST), *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003937 }
3938 else
3939 rv = VPPCOM_EINVAL;
3940 break;
3941
3942 case VPPCOM_ATTR_GET_V6ONLY:
3943 if (buffer && buflen && (*buflen >= sizeof (int)))
3944 {
3945 /* VPP-TBD */
3946 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
3947 VCL_SESS_ATTR_V6ONLY);
3948 *buflen = sizeof (int);
3949
Florin Coras0d427d82018-06-27 03:24:07 -07003950 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_V6ONLY: %d, buflen %d, "
3951 "#VPP-TBD#", getpid (), *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003952 }
3953 else
3954 rv = VPPCOM_EINVAL;
Stevenb5a11602017-10-11 09:59:30 -07003955 break;
3956
3957 case VPPCOM_ATTR_SET_V6ONLY:
Dave Wallace048b1d62018-01-03 22:24:41 -05003958 if (buffer && buflen && (*buflen == sizeof (int)))
3959 {
3960 /* VPP-TBD */
3961 if (*(int *) buffer)
3962 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_V6ONLY);
3963 else
3964 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_V6ONLY);
3965
Florin Coras0d427d82018-06-27 03:24:07 -07003966 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_V6ONLY: %d, buflen %d, "
3967 "#VPP-TBD#", getpid (),
3968 VCL_SESS_ATTR_TEST (session->attr,
3969 VCL_SESS_ATTR_V6ONLY), *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003970 }
3971 else
3972 rv = VPPCOM_EINVAL;
3973 break;
3974
3975 case VPPCOM_ATTR_GET_KEEPALIVE:
3976 if (buffer && buflen && (*buflen >= sizeof (int)))
3977 {
3978 /* VPP-TBD */
3979 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
3980 VCL_SESS_ATTR_KEEPALIVE);
3981 *buflen = sizeof (int);
3982
Florin Coras0d427d82018-06-27 03:24:07 -07003983 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_KEEPALIVE: %d, buflen %d, "
3984 "#VPP-TBD#", getpid (), *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003985 }
3986 else
3987 rv = VPPCOM_EINVAL;
Stevenb5a11602017-10-11 09:59:30 -07003988 break;
Stevenbccd3392017-10-12 20:42:21 -07003989
3990 case VPPCOM_ATTR_SET_KEEPALIVE:
Dave Wallace048b1d62018-01-03 22:24:41 -05003991 if (buffer && buflen && (*buflen == sizeof (int)))
3992 {
3993 /* VPP-TBD */
3994 if (*(int *) buffer)
3995 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_KEEPALIVE);
3996 else
3997 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_KEEPALIVE);
3998
Florin Coras0d427d82018-06-27 03:24:07 -07003999 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_KEEPALIVE: %d, buflen %d, "
4000 "#VPP-TBD#", getpid (),
4001 VCL_SESS_ATTR_TEST (session->attr,
4002 VCL_SESS_ATTR_KEEPALIVE), *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05004003 }
4004 else
4005 rv = VPPCOM_EINVAL;
4006 break;
4007
4008 case VPPCOM_ATTR_GET_TCP_NODELAY:
4009 if (buffer && buflen && (*buflen >= sizeof (int)))
4010 {
4011 /* VPP-TBD */
4012 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
4013 VCL_SESS_ATTR_TCP_NODELAY);
4014 *buflen = sizeof (int);
4015
Florin Coras0d427d82018-06-27 03:24:07 -07004016 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_TCP_NODELAY: %d, buflen %d, "
4017 "#VPP-TBD#", getpid (), *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05004018 }
4019 else
4020 rv = VPPCOM_EINVAL;
4021 break;
4022
4023 case VPPCOM_ATTR_SET_TCP_NODELAY:
4024 if (buffer && buflen && (*buflen == sizeof (int)))
4025 {
4026 /* VPP-TBD */
4027 if (*(int *) buffer)
4028 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_TCP_NODELAY);
4029 else
4030 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_TCP_NODELAY);
4031
Florin Coras0d427d82018-06-27 03:24:07 -07004032 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_TCP_NODELAY: %d, buflen %d, "
4033 "#VPP-TBD#", getpid (),
4034 VCL_SESS_ATTR_TEST (session->attr,
4035 VCL_SESS_ATTR_TCP_NODELAY), *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05004036 }
4037 else
4038 rv = VPPCOM_EINVAL;
4039 break;
4040
4041 case VPPCOM_ATTR_GET_TCP_KEEPIDLE:
4042 if (buffer && buflen && (*buflen >= sizeof (int)))
4043 {
4044 /* VPP-TBD */
4045 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
4046 VCL_SESS_ATTR_TCP_KEEPIDLE);
4047 *buflen = sizeof (int);
4048
Florin Coras0d427d82018-06-27 03:24:07 -07004049 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_TCP_KEEPIDLE: %d, buflen %d, "
4050 "#VPP-TBD#", getpid (), *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05004051 }
4052 else
4053 rv = VPPCOM_EINVAL;
Stevenbccd3392017-10-12 20:42:21 -07004054 break;
4055
4056 case VPPCOM_ATTR_SET_TCP_KEEPIDLE:
Dave Wallace048b1d62018-01-03 22:24:41 -05004057 if (buffer && buflen && (*buflen == sizeof (int)))
4058 {
4059 /* VPP-TBD */
4060 if (*(int *) buffer)
4061 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_TCP_KEEPIDLE);
4062 else
4063 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_TCP_KEEPIDLE);
4064
Florin Coras0d427d82018-06-27 03:24:07 -07004065 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_TCP_KEEPIDLE: %d, buflen %d, "
4066 "#VPP-TBD#", getpid (),
4067 VCL_SESS_ATTR_TEST (session->attr,
4068 VCL_SESS_ATTR_TCP_KEEPIDLE), *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05004069 }
4070 else
4071 rv = VPPCOM_EINVAL;
4072 break;
4073
4074 case VPPCOM_ATTR_GET_TCP_KEEPINTVL:
4075 if (buffer && buflen && (*buflen >= sizeof (int)))
4076 {
4077 /* VPP-TBD */
4078 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
4079 VCL_SESS_ATTR_TCP_KEEPINTVL);
4080 *buflen = sizeof (int);
4081
Florin Coras0d427d82018-06-27 03:24:07 -07004082 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_TCP_KEEPINTVL: %d, buflen %d, "
4083 "#VPP-TBD#", getpid (), *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05004084 }
4085 else
4086 rv = VPPCOM_EINVAL;
Stevenbccd3392017-10-12 20:42:21 -07004087 break;
4088
4089 case VPPCOM_ATTR_SET_TCP_KEEPINTVL:
Dave Wallace048b1d62018-01-03 22:24:41 -05004090 if (buffer && buflen && (*buflen == sizeof (int)))
4091 {
4092 /* VPP-TBD */
4093 if (*(int *) buffer)
4094 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_TCP_KEEPINTVL);
4095 else
4096 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_TCP_KEEPINTVL);
4097
Florin Coras0d427d82018-06-27 03:24:07 -07004098 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_TCP_KEEPINTVL: %d, buflen %d, "
4099 "#VPP-TBD#", getpid (),
4100 VCL_SESS_ATTR_TEST (session->attr,
4101 VCL_SESS_ATTR_TCP_KEEPINTVL), *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05004102 }
4103 else
4104 rv = VPPCOM_EINVAL;
4105 break;
4106
4107 case VPPCOM_ATTR_GET_TCP_USER_MSS:
4108 if (buffer && buflen && (*buflen >= sizeof (u32)))
4109 {
4110 /* VPP-TBD */
4111 *(u32 *) buffer = session->user_mss;
4112 *buflen = sizeof (int);
4113
Florin Coras0d427d82018-06-27 03:24:07 -07004114 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_TCP_USER_MSS: %d, buflen %d,"
4115 " #VPP-TBD#", getpid (), *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05004116 }
4117 else
4118 rv = VPPCOM_EINVAL;
4119 break;
4120
4121 case VPPCOM_ATTR_SET_TCP_USER_MSS:
4122 if (buffer && buflen && (*buflen == sizeof (u32)))
4123 {
4124 /* VPP-TBD */
4125 session->user_mss = *(u32 *) buffer;
4126
Florin Coras0d427d82018-06-27 03:24:07 -07004127 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_TCP_USER_MSS: %u, buflen %d, "
4128 "#VPP-TBD#", getpid (), session->user_mss, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05004129 }
4130 else
4131 rv = VPPCOM_EINVAL;
Stevenbccd3392017-10-12 20:42:21 -07004132 break;
Dave Wallacee22aa742017-10-20 12:30:38 -04004133
4134 default:
4135 rv = VPPCOM_EINVAL;
4136 break;
Dave Wallace35830af2017-10-09 01:43:42 -04004137 }
4138
4139done:
Dave Wallace7e607a72018-06-18 18:41:32 -04004140 VCL_SESSION_UNLOCK ();
Dave Wallace35830af2017-10-09 01:43:42 -04004141 return rv;
4142}
4143
Stevenac1f96d2017-10-24 16:03:58 -07004144int
4145vppcom_session_recvfrom (uint32_t session_index, void *buffer,
4146 uint32_t buflen, int flags, vppcom_endpt_t * ep)
4147{
Stevenac1f96d2017-10-24 16:03:58 -07004148 int rv = VPPCOM_OK;
4149 session_t *session = 0;
4150
4151 if (ep)
4152 {
Dave Wallace7e607a72018-06-18 18:41:32 -04004153 VCL_SESSION_LOCK ();
Stevenac1f96d2017-10-24 16:03:58 -07004154 rv = vppcom_session_at_index (session_index, &session);
4155 if (PREDICT_FALSE (rv))
4156 {
Dave Wallace7e607a72018-06-18 18:41:32 -04004157 VCL_SESSION_UNLOCK ();
Florin Coras0d427d82018-06-27 03:24:07 -07004158 VDBG (0, "VCL<%d>: invalid session, sid (%u) has been closed!",
4159 getpid (), session_index);
Dave Wallacefaf9d772017-10-26 16:12:04 -04004160 rv = VPPCOM_EBADFD;
Dave Wallace7e607a72018-06-18 18:41:32 -04004161 VCL_SESSION_UNLOCK ();
Dave Wallacefaf9d772017-10-26 16:12:04 -04004162 goto done;
Stevenac1f96d2017-10-24 16:03:58 -07004163 }
Stevenac1f96d2017-10-24 16:03:58 -07004164 ep->is_ip4 = session->peer_addr.is_ip4;
4165 ep->port = session->peer_port;
4166 if (session->peer_addr.is_ip4)
4167 clib_memcpy (ep->ip, &session->peer_addr.ip46.ip4,
4168 sizeof (ip4_address_t));
4169 else
4170 clib_memcpy (ep->ip, &session->peer_addr.ip46.ip6,
4171 sizeof (ip6_address_t));
Dave Wallace7e607a72018-06-18 18:41:32 -04004172 VCL_SESSION_UNLOCK ();
Stevenac1f96d2017-10-24 16:03:58 -07004173 }
Steven58f464e2017-10-25 12:33:12 -07004174
4175 if (flags == 0)
Stevenac1f96d2017-10-24 16:03:58 -07004176 rv = vppcom_session_read (session_index, buffer, buflen);
4177 else if (flags & MSG_PEEK)
Steven58f464e2017-10-25 12:33:12 -07004178 rv = vppcom_session_peek (session_index, buffer, buflen);
Stevenac1f96d2017-10-24 16:03:58 -07004179 else
4180 {
Dave Wallace048b1d62018-01-03 22:24:41 -05004181 clib_warning ("VCL<%d>: Unsupport flags for recvfrom %d",
4182 getpid (), flags);
Stevenac1f96d2017-10-24 16:03:58 -07004183 rv = VPPCOM_EAFNOSUPPORT;
4184 }
4185
Dave Wallacefaf9d772017-10-26 16:12:04 -04004186done:
Stevenac1f96d2017-10-24 16:03:58 -07004187 return rv;
4188}
4189
4190int
4191vppcom_session_sendto (uint32_t session_index, void *buffer,
4192 uint32_t buflen, int flags, vppcom_endpt_t * ep)
4193{
Dave Wallace617dffa2017-10-26 14:47:06 -04004194 if (!buffer)
4195 return VPPCOM_EINVAL;
4196
4197 if (ep)
4198 {
4199 // TBD
4200 return VPPCOM_EINVAL;
4201 }
4202
4203 if (flags)
4204 {
4205 // TBD check the flags and do the right thing
Florin Coras0d427d82018-06-27 03:24:07 -07004206 VDBG (2, "VCL<%d>: handling flags 0x%u (%d) not implemented yet.",
4207 getpid (), flags, flags);
Dave Wallace617dffa2017-10-26 14:47:06 -04004208 }
4209
4210 return (vppcom_session_write (session_index, buffer, buflen));
Stevenac1f96d2017-10-24 16:03:58 -07004211}
4212
Dave Wallace048b1d62018-01-03 22:24:41 -05004213int
4214vppcom_poll (vcl_poll_t * vp, uint32_t n_sids, double wait_for_time)
4215{
4216 f64 timeout = clib_time_now (&vcm->clib_time) + wait_for_time;
4217 u32 i, keep_trying = 1;
4218 int rv, num_ev = 0;
4219
Florin Coras0d427d82018-06-27 03:24:07 -07004220 VDBG (3, "VCL<%d>: vp %p, nsids %u, wait_for_time %f",
4221 getpid (), vp, n_sids, wait_for_time);
Dave Wallace048b1d62018-01-03 22:24:41 -05004222
4223 if (!vp)
4224 return VPPCOM_EFAULT;
4225
4226 do
4227 {
4228 session_t *session;
4229
4230 for (i = 0; i < n_sids; i++)
4231 {
4232 ASSERT (vp[i].revents);
4233
Dave Wallace7e607a72018-06-18 18:41:32 -04004234 VCL_SESSION_LOCK_AND_GET (vp[i].sid, &session);
4235 VCL_SESSION_UNLOCK ();
Dave Wallace048b1d62018-01-03 22:24:41 -05004236
4237 if (*vp[i].revents)
4238 *vp[i].revents = 0;
4239
4240 if (POLLIN & vp[i].events)
4241 {
Dave Wallace7e607a72018-06-18 18:41:32 -04004242 VCL_SESSION_LOCK_AND_GET (vp[i].sid, &session);
Dave Wallace048b1d62018-01-03 22:24:41 -05004243 rv = vppcom_session_read_ready (session, vp[i].sid);
Dave Wallace7e607a72018-06-18 18:41:32 -04004244 VCL_SESSION_UNLOCK ();
Dave Wallace048b1d62018-01-03 22:24:41 -05004245 if (rv > 0)
4246 {
4247 *vp[i].revents |= POLLIN;
4248 num_ev++;
4249 }
4250 else if (rv < 0)
4251 {
4252 switch (rv)
4253 {
4254 case VPPCOM_ECONNRESET:
4255 *vp[i].revents = POLLHUP;
4256 break;
4257
4258 default:
4259 *vp[i].revents = POLLERR;
4260 break;
4261 }
4262 num_ev++;
4263 }
4264 }
4265
4266 if (POLLOUT & vp[i].events)
4267 {
Dave Wallace7e607a72018-06-18 18:41:32 -04004268 VCL_SESSION_LOCK_AND_GET (vp[i].sid, &session);
Dave Wallace048b1d62018-01-03 22:24:41 -05004269 rv = vppcom_session_write_ready (session, vp[i].sid);
Dave Wallace7e607a72018-06-18 18:41:32 -04004270 VCL_SESSION_UNLOCK ();
Dave Wallace048b1d62018-01-03 22:24:41 -05004271 if (rv > 0)
4272 {
4273 *vp[i].revents |= POLLOUT;
4274 num_ev++;
4275 }
4276 else if (rv < 0)
4277 {
4278 switch (rv)
4279 {
4280 case VPPCOM_ECONNRESET:
4281 *vp[i].revents = POLLHUP;
4282 break;
4283
4284 default:
4285 *vp[i].revents = POLLERR;
4286 break;
4287 }
4288 num_ev++;
4289 }
4290 }
4291
Dave Wallace7e607a72018-06-18 18:41:32 -04004292 if (0) // Note "done:" label used by VCL_SESSION_LOCK_AND_GET()
Dave Wallace048b1d62018-01-03 22:24:41 -05004293 {
4294 done:
4295 *vp[i].revents = POLLNVAL;
4296 num_ev++;
4297 }
4298 }
4299 if (wait_for_time != -1)
4300 keep_trying = (clib_time_now (&vcm->clib_time) <= timeout) ? 1 : 0;
4301 }
4302 while ((num_ev == 0) && keep_trying);
4303
4304 if (VPPCOM_DEBUG > 3)
4305 {
4306 clib_warning ("VCL<%d>: returning %d", getpid (), num_ev);
4307 for (i = 0; i < n_sids; i++)
4308 {
4309 clib_warning ("VCL<%d>: vp[%d].sid %d (0x%x), .events 0x%x, "
4310 ".revents 0x%x", getpid (), i, vp[i].sid, vp[i].sid,
4311 vp[i].events, *vp[i].revents);
4312 }
4313 }
4314 return num_ev;
4315}
4316
Dave Wallacee22aa742017-10-20 12:30:38 -04004317/*
Dave Wallace7e607a72018-06-18 18:41:32 -04004318 * VPPCOM Event Functions
4319 */
4320
4321void *
4322vppcom_session_io_thread_fn (void *arg)
4323{
4324 vppcom_session_io_thread_t *evt = (vppcom_session_io_thread_t *) arg;
4325 u32 *session_indexes = 0, *session_index;
4326 int i, rv;
4327 u32 bytes = 0;
4328 session_t *session;
4329
4330 while (1)
4331 {
4332 vec_reset_length (session_indexes);
4333 VCE_IO_SESSIONS_LOCK ();
4334 pool_foreach (session_index, evt->active_session_indexes, (
4335 {
4336 vec_add1
4337 (session_indexes,
4338 *session_index);
4339 }
4340 ));
4341 VCE_IO_SESSIONS_UNLOCK ();
4342 if (session_indexes)
4343 {
4344 for (i = 0; i < vec_len (session_indexes); ++i)
4345 {
4346 VCL_SESSION_LOCK_AND_GET (session_indexes[i], &session);
4347 bytes = svm_fifo_max_dequeue (session->rx_fifo);
4348 VCL_SESSION_UNLOCK ();
4349
4350 if (bytes)
4351 {
4352 vppcom_ioevent_t *eio;
4353 vce_event_t *ev;
4354 u32 ev_idx;
4355
4356 VCL_EVENTS_LOCK ();
4357
4358 pool_get (vcm->event_thread.vce_events, ev);
4359 ev_idx = (u32) (ev - vcm->event_thread.vce_events);
4360 eio = vce_get_event_data (ev, sizeof (*eio));
4361 ev->evk.eid = VCL_EVENT_IOEVENT_RX_FIFO;
4362 ev->evk.session_index = session_indexes[i];
4363 eio->bytes = bytes;
4364 eio->session_index = session_indexes[i];
4365
4366 VCL_EVENTS_UNLOCK ();
4367
4368 rv = vce_generate_event (&vcm->event_thread, ev_idx);
4369 }
4370 }
4371 }
4372 struct timespec ts;
4373 ts.tv_sec = 0;
4374 ts.tv_nsec = 1000000; /* 1 millisecond */
4375 nanosleep (&ts, NULL);
4376 }
4377done:
4378 VCL_SESSION_UNLOCK ();
4379 return NULL;
4380}
4381
4382int
4383vppcom_start_io_event_thread (vppcom_session_io_thread_t * evt,
4384 u8 max_sessions)
4385{
4386 pthread_cond_init (&(evt->vce_io_cond), NULL);
4387 pthread_mutex_init (&(evt->vce_io_lock), NULL);
4388
4389 clib_spinlock_init (&(evt->io_sessions_lockp));
4390
4391 return pthread_create (&(evt->thread), NULL /* attr */ ,
4392 vppcom_session_io_thread_fn, evt);
4393}
4394
4395void
4396vce_registered_ioevent_handler_fn (void *arg)
4397{
4398 vce_event_handler_reg_t *reg = (vce_event_handler_reg_t *) arg;
4399 vppcom_ioevent_t *eio;
4400 vce_event_t *ev;
4401 u32 ioevt_ndx = (u64) (reg->handler_fn_args);
4402 vppcom_session_ioevent_t *ioevent, ioevent_;
4403
4404 VCL_EVENTS_LOCK ();
4405 ev = vce_get_event_from_index (&vcm->event_thread, reg->ev_idx);
4406 eio = vce_get_event_data (ev, sizeof (*eio));
4407 VCL_EVENTS_UNLOCK ();
4408
4409 VCL_IO_SESSIONS_LOCK ();
4410 ioevent = pool_elt_at_index (vcm->session_io_thread.ioevents, ioevt_ndx);
4411 ioevent_ = *ioevent;
4412 VCL_IO_SESSIONS_UNLOCK ();
4413 (ioevent_.user_cb) (eio, ioevent_.user_cb_data);
4414 vce_clear_event (&vcm->event_thread, reg->ev_idx);
4415 return;
4416
4417 /*TODO - Unregister check in close for this listener */
4418
4419}
4420
4421void
4422vce_registered_listener_connect_handler_fn (void *arg)
4423{
4424 vce_event_handler_reg_t *reg = (vce_event_handler_reg_t *) arg;
4425 vce_event_connect_request_t *ecr;
4426 vce_event_t *ev;
4427 vppcom_endpt_t ep;
4428
4429 session_t *new_session;
4430 int rv;
4431
4432 vppcom_session_listener_t *session_listener =
4433 (vppcom_session_listener_t *) reg->handler_fn_args;
4434
4435 VCL_EVENTS_LOCK ();
4436 ev = vce_get_event_from_index (&vcm->event_thread, reg->ev_idx);
4437 ecr = vce_get_event_data (ev, sizeof (*ecr));
4438 VCL_EVENTS_UNLOCK ();
4439 VCL_SESSION_LOCK_AND_GET (ecr->accepted_session_index, &new_session);
4440
4441 ep.is_ip4 = new_session->peer_addr.is_ip4;
4442 ep.port = new_session->peer_port;
4443 if (new_session->peer_addr.is_ip4)
4444 clib_memcpy (&ep.ip, &new_session->peer_addr.ip46.ip4,
4445 sizeof (ip4_address_t));
4446 else
4447 clib_memcpy (&ep.ip, &new_session->peer_addr.ip46.ip6,
4448 sizeof (ip6_address_t));
4449
4450 vppcom_send_accept_session_reply (new_session->vpp_handle,
4451 new_session->client_context,
4452 0 /* retval OK */ );
4453 VCL_SESSION_UNLOCK ();
4454
4455 (session_listener->user_cb) (ecr->accepted_session_index, &ep,
4456 session_listener->user_cb_data);
4457
4458 if (vcm->session_io_thread.io_sessions_lockp)
4459 {
4460 /* Throw this new accepted session index into the rx poll thread pool */
4461 VCL_IO_SESSIONS_LOCK ();
4462 u32 *active_session_index;
4463 pool_get (vcm->session_io_thread.active_session_indexes,
4464 active_session_index);
4465 *active_session_index = ecr->accepted_session_index;
4466 VCL_IO_SESSIONS_UNLOCK ();
4467 }
4468
4469 /*TODO - Unregister check in close for this listener */
4470 return;
4471
4472done:
4473 ASSERT (0); // If we can't get a lock or accepted session fails, lets blow up.
4474}
4475
4476/**
4477 * @brief vce_poll_wait_connect_request_handler_fn
4478 * - used by vppcom_epoll_xxxx() for listener sessions
4479 * - when a vl_api_accept_session_t_handler() generates an event
4480 * this callback is alerted and sets the fields that vppcom_epoll_wait()
4481 * expects to see.
4482 *
4483 * @param arg - void* to be cast to vce_event_handler_reg_t*
4484 */
4485void
4486vce_poll_wait_connect_request_handler_fn (void *arg)
4487{
4488 vce_event_handler_reg_t *reg = (vce_event_handler_reg_t *) arg;
4489 vce_event_t *ev;
4490 /* Retrieve the VCL_EVENT_CONNECT_REQ_ACCEPTED event */
4491 ev = vce_get_event_from_index (&vcm->event_thread, reg->ev_idx);
4492 vce_event_connect_request_t *ecr = vce_get_event_data (ev, sizeof (*ecr));
4493
4494 /* Add the accepted_session_index to the FIFO */
4495 VCL_ACCEPT_FIFO_LOCK ();
4496 clib_fifo_add1 (vcm->client_session_index_fifo,
4497 ecr->accepted_session_index);
4498 VCL_ACCEPT_FIFO_UNLOCK ();
4499
4500 /* Recycling the event. */
4501 VCL_EVENTS_LOCK ();
4502 ev->recycle = 1;
4503 clib_fifo_add1 (vcm->event_thread.event_index_fifo, reg->ev_idx);
4504 VCL_EVENTS_UNLOCK ();
4505}
4506
4507int
4508vppcom_session_register_ioevent_cb (uint32_t session_index,
4509 vppcom_session_ioevent_cb cb,
4510 uint8_t rx, void *ptr)
4511{
4512 int rv = VPPCOM_OK;
4513 vce_event_key_t evk;
4514 vppcom_session_ioevent_t *ioevent;
4515
4516 if (!vcm->session_io_thread.io_sessions_lockp)
4517 rv = vppcom_start_io_event_thread (&vcm->session_io_thread, 100 /* DAW_TODO: ??? hard-coded value */
4518 );
4519
4520 if (rv == VPPCOM_OK)
4521 {
4522 void *io_evt_ndx;
4523
4524 /* Register handler for ioevent on session_index */
4525 VCL_IO_SESSIONS_LOCK ();
4526 pool_get (vcm->session_io_thread.ioevents, ioevent);
4527 io_evt_ndx = (void *) (ioevent - vcm->session_io_thread.ioevents);
4528 ioevent->user_cb = cb;
4529 ioevent->user_cb_data = ptr;
4530 VCL_IO_SESSIONS_UNLOCK ();
4531
4532 evk.session_index = session_index;
4533 evk.eid = rx ? VCL_EVENT_IOEVENT_RX_FIFO : VCL_EVENT_IOEVENT_TX_FIFO;
4534
4535 (void) vce_register_handler (&vcm->event_thread, &evk,
4536 vce_registered_ioevent_handler_fn,
4537 io_evt_ndx);
4538 }
4539 return rv;
4540}
4541
4542int
4543vppcom_session_register_listener (uint32_t session_index,
4544 vppcom_session_listener_cb cb,
4545 vppcom_session_listener_errcb
4546 errcb, uint8_t flags, int q_len, void *ptr)
4547{
4548 int rv = VPPCOM_OK;
4549 vce_event_key_t evk;
4550 vppcom_session_listener_t *listener_args;
4551
4552 if (!vcm->session_io_thread.io_sessions_lockp)
4553 rv = vppcom_start_io_event_thread (&vcm->session_io_thread, 100 /* DAW_TODO: ??? hard-coded value */
4554 );
4555 if (rv)
4556 {
4557 goto done;
4558 }
4559 rv = vppcom_session_listen (session_index, q_len);
4560 if (rv)
4561 {
4562 goto done;
4563 }
4564
4565 /* Register handler for connect_request event on listen_session_index */
4566 listener_args = clib_mem_alloc (sizeof (vppcom_session_listener_t)); // DAW_TODO: Use a pool instead of thrashing the memory allocator!
4567 listener_args->user_cb = cb;
4568 listener_args->user_cb_data = ptr;
4569 listener_args->user_errcb = errcb;
4570
4571 evk.session_index = session_index;
4572 evk.eid = VCL_EVENT_CONNECT_REQ_ACCEPTED;
4573 (void) vce_register_handler (&vcm->event_thread, &evk,
4574 vce_registered_listener_connect_handler_fn,
4575 listener_args);
4576
4577done:
4578 return rv;
4579}
4580
4581/*
Dave Wallacee22aa742017-10-20 12:30:38 -04004582 * fd.io coding-style-patch-verification: ON
4583 *
4584 * Local Variables:
4585 * eval: (c-set-style "gnu")
4586 * End:
4587 */