blob: cab2f6039e9f34e62f1144b2de6fba0fce4d9709 [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>
Dave Wallace543852a2017-08-03 02:11:34 -040025#include <vlib/unix/unix.h>
26#include <vppinfra/vec_bootstrap.h>
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -080027#include <vppinfra/elog.h>
Dave Wallace543852a2017-08-03 02:11:34 -040028
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
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800193/* VPPCOM Event typedefs */
194typedef enum vcl_event_id_
195{
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -0800196 VCL_EVENT_INVALID_EVENT,
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800197 VCL_EVENT_CONNECT_REQ_ACCEPTED,
198 VCL_EVENT_N_EVENTS
199} vcl_event_id_t;
200
201typedef struct vce_event_connect_request_
202{
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800203 u32 accepted_session_index;
204} vce_event_connect_request_t;
205
Keith Burns (alagalah)0d2b0d52018-03-06 15:55:22 -0800206typedef struct vppcom_session_listener
207{
208 vppcom_session_listener_cb user_cb;
209 vppcom_session_listener_errcb user_errcb;
210 void *user_cb_data;
211} vppcom_session_listener_t;
212
Dave Wallace543852a2017-08-03 02:11:34 -0400213typedef struct vppcom_main_t_
214{
215 u8 init;
Dave Wallace498b3a52017-11-09 13:00:34 -0500216 u32 debug;
Dave Wallace543852a2017-08-03 02:11:34 -0400217 int main_cpu;
218
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -0800219 /* FIFO for accepted connections - used in epoll/select */
220 clib_spinlock_t session_fifo_lockp;
221 u32 *client_session_index_fifo;
222
Dave Wallaceb5a86ee2018-02-16 18:26:11 -0500223 /* vpp input queue */
Florin Corase86a8ed2018-01-05 03:20:25 -0800224 svm_queue_t *vl_input_queue;
Dave Wallace543852a2017-08-03 02:11:34 -0400225
226 /* API client handle */
227 u32 my_client_index;
Dave Wallace543852a2017-08-03 02:11:34 -0400228 /* Session pool */
229 clib_spinlock_t sessions_lockp;
230 session_t *sessions;
231
232 /* Hash table for disconnect processing */
233 uword *session_index_by_vpp_handles;
234
235 /* Select bitmaps */
236 clib_bitmap_t *rd_bitmap;
237 clib_bitmap_t *wr_bitmap;
238 clib_bitmap_t *ex_bitmap;
239
240 /* Our event queue */
Florin Corase86a8ed2018-01-05 03:20:25 -0800241 svm_queue_t *app_event_queue;
Dave Wallace543852a2017-08-03 02:11:34 -0400242
243 /* unique segment name counter */
244 u32 unique_segment_index;
245
Dave Wallace543852a2017-08-03 02:11:34 -0400246 /* For deadman timers */
247 clib_time_t clib_time;
248
249 /* State of the connection, shared between msg RX thread and main thread */
250 volatile app_state_t app_state;
251
252 vppcom_cfg_t cfg;
253
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800254 /* Event thread */
255 vce_event_thread_t event_thread;
256
257 /* VPP Event-logger */
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -0800258 elog_main_t elog_main;
259 elog_track_t elog_track;
260
Dave Wallace543852a2017-08-03 02:11:34 -0400261 /* VNET_API_ERROR_FOO -> "Foo" hash table */
262 uword *error_string_by_error_number;
263} vppcom_main_t;
264
Dave Wallace2e005bb2017-11-07 01:21:39 -0500265/* NOTE: _vppcom_main is only used until the heap is allocated.
266 * Do not access it directly -- use vcm which will point to
267 * the heap allocated copy after init.
268 */
Dave Wallace498b3a52017-11-09 13:00:34 -0500269static vppcom_main_t _vppcom_main = {
270 .debug = VPPCOM_DEBUG_INIT,
271 .my_client_index = ~0
272};
Dave Wallace2e005bb2017-11-07 01:21:39 -0500273
274static vppcom_main_t *vcm = &_vppcom_main;
Dave Wallace543852a2017-08-03 02:11:34 -0400275
Dave Wallace048b1d62018-01-03 22:24:41 -0500276#define VCL_LOCK_AND_GET_SESSION(I, S) \
277do { \
278 clib_spinlock_lock (&vcm->sessions_lockp); \
279 rv = vppcom_session_at_index (I, S); \
280 if (PREDICT_FALSE (rv)) \
281 { \
282 clib_spinlock_unlock (&vcm->sessions_lockp); \
283 clib_warning ("VCL<%d>: ERROR: Invalid ##I (%u)!", \
284 getpid (), I); \
285 goto done; \
286 } \
Dave Wallace60caa062017-11-10 17:07:13 -0500287} while (0)
288
Dave Wallace543852a2017-08-03 02:11:34 -0400289static const char *
290vppcom_app_state_str (app_state_t state)
291{
292 char *st;
293
294 switch (state)
295 {
296 case STATE_APP_START:
297 st = "STATE_APP_START";
298 break;
299
300 case STATE_APP_CONN_VPP:
301 st = "STATE_APP_CONN_VPP";
302 break;
303
304 case STATE_APP_ENABLED:
305 st = "STATE_APP_ENABLED";
306 break;
307
308 case STATE_APP_ATTACHED:
309 st = "STATE_APP_ATTACHED";
310 break;
311
312 default:
313 st = "UNKNOWN_APP_STATE";
314 break;
315 }
316
317 return st;
318}
319
320static const char *
321vppcom_session_state_str (session_state_t state)
322{
323 char *st;
324
325 switch (state)
326 {
327 case STATE_START:
328 st = "STATE_START";
329 break;
330
331 case STATE_CONNECT:
332 st = "STATE_CONNECT";
333 break;
334
335 case STATE_LISTEN:
336 st = "STATE_LISTEN";
337 break;
338
339 case STATE_ACCEPT:
340 st = "STATE_ACCEPT";
341 break;
342
Dave Wallace4878cbe2017-11-21 03:45:09 -0500343 case STATE_CLOSE_ON_EMPTY:
344 st = "STATE_CLOSE_ON_EMPTY";
345 break;
346
Dave Wallace543852a2017-08-03 02:11:34 -0400347 case STATE_DISCONNECT:
348 st = "STATE_DISCONNECT";
349 break;
350
351 case STATE_FAILED:
352 st = "STATE_FAILED";
353 break;
354
355 default:
356 st = "UNKNOWN_STATE";
357 break;
358 }
359
360 return st;
361}
362
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800363
Dave Wallace543852a2017-08-03 02:11:34 -0400364/*
365 * VPPCOM Utility Functions
366 */
367static inline int
368vppcom_session_at_index (u32 session_index, session_t * volatile *sess)
369{
Dave Wallace543852a2017-08-03 02:11:34 -0400370 /* Assumes that caller has acquired spinlock: vcm->sessions_lockp */
371 if (PREDICT_FALSE ((session_index == ~0) ||
372 pool_is_free_index (vcm->sessions, session_index)))
373 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500374 clib_warning ("VCL<%d>: invalid session, sid (%u) has been closed!",
Dave Wallace2e005bb2017-11-07 01:21:39 -0500375 getpid (), session_index);
Dave Wallace543852a2017-08-03 02:11:34 -0400376 return VPPCOM_EBADFD;
377 }
378 *sess = pool_elt_at_index (vcm->sessions, session_index);
379 return VPPCOM_OK;
380}
381
Florin Corasdcf55ce2017-11-16 15:32:50 -0800382static inline void
383vppcom_session_table_add_listener (u64 listener_handle, u32 value)
384{
385 /* Session and listener handles have different formats. The latter has
386 * the thread index in the upper 32 bits while the former has the session
387 * type. Knowing that, for listeners we just flip the MSB to 1 */
388 listener_handle |= 1ULL << 63;
389 hash_set (vcm->session_index_by_vpp_handles, listener_handle, value);
390}
391
392static inline session_t *
393vppcom_session_table_lookup_listener (u64 listener_handle)
394{
395 uword *p;
396 u64 handle = listener_handle | (1ULL << 63);
Dave Wallace4878cbe2017-11-21 03:45:09 -0500397 session_t *session;
398
Florin Corasdcf55ce2017-11-16 15:32:50 -0800399 p = hash_get (vcm->session_index_by_vpp_handles, handle);
400 if (!p)
401 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500402 clib_warning ("VCL<%d>: couldn't find listen session: unknown vpp "
Florin Corasdcf55ce2017-11-16 15:32:50 -0800403 "listener handle %llx", getpid (), listener_handle);
404 return 0;
405 }
406 if (pool_is_free_index (vcm->sessions, p[0]))
407 {
408 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -0500409 clib_warning ("VCL<%d>: invalid listen session, sid (%u)",
410 getpid (), p[0]);
Florin Corasdcf55ce2017-11-16 15:32:50 -0800411 return 0;
412 }
413
Dave Wallace4878cbe2017-11-21 03:45:09 -0500414 session = pool_elt_at_index (vcm->sessions, p[0]);
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -0800415 ASSERT (session->state & STATE_LISTEN);
Dave Wallace4878cbe2017-11-21 03:45:09 -0500416 return session;
Florin Corasdcf55ce2017-11-16 15:32:50 -0800417}
418
419static inline void
420vppcom_session_table_del_listener (u64 listener_handle)
421{
422 listener_handle |= 1ULL << 63;
423 hash_unset (vcm->session_index_by_vpp_handles, listener_handle);
424}
425
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -0800426static void
427write_elog (void)
428{
429 elog_main_t *em = &vcm->elog_main;
430 char *chroot_file;
431 clib_error_t *error = 0;
432
433 chroot_file =
434 (char *) format (0, "%s/%d-%d-vcl-elog%c", vcm->cfg.event_log_path,
435 vcm->my_client_index, getpid (), 0);
436 error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
437 if (error)
438 {
439 clib_error_report (error);
440 }
441 if (VPPCOM_DEBUG > 0)
442 clib_warning ("[%d] Event Log:'%s' ", getpid (), chroot_file);
443
444}
445
Keith Burns (alagalah)0d2b0d52018-03-06 15:55:22 -0800446static inline void
447vppcom_send_accept_session_reply (u64 handle, u32 context, int retval)
448{
449 vl_api_accept_session_reply_t *rmp;
450
451 rmp = vl_msg_api_alloc (sizeof (*rmp));
452 memset (rmp, 0, sizeof (*rmp));
453 rmp->_vl_msg_id = ntohs (VL_API_ACCEPT_SESSION_REPLY);
454 rmp->retval = htonl (retval);
455 rmp->context = context;
456 rmp->handle = handle;
457 vl_msg_api_send_shmem (vcm->vl_input_queue, (u8 *) & rmp);
458}
459
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800460/*
461 * VPPCOM Event Functions
462 */
463
Keith Burns (alagalah)0d2b0d52018-03-06 15:55:22 -0800464void
465vce_registered_listener_connect_handler_fn (void *arg)
466{
467 vce_event_handler_reg_t *reg = (vce_event_handler_reg_t *) arg;
468 vce_event_connect_request_t *ecr;
469 vce_event_t *ev;
470 vppcom_endpt_t ep;
471
472 session_t *new_session;
473 int rv;
474
475 vppcom_session_listener_t *session_listener =
476 (vppcom_session_listener_t *) reg->handler_fn_args;
477
478 ev = vce_get_event_from_index (&vcm->event_thread, reg->ev_idx);
479
480 ecr = (vce_event_connect_request_t *) ev->data;
481 VCL_LOCK_AND_GET_SESSION (ecr->accepted_session_index, &new_session);
482
483
484 ep.is_ip4 = new_session->peer_addr.is_ip4;
485 ep.port = new_session->peer_port;
486 if (new_session->peer_addr.is_ip4)
487 clib_memcpy (&ep.ip, &new_session->peer_addr.ip46.ip4,
488 sizeof (ip4_address_t));
489 else
490 clib_memcpy (&ep.ip, &new_session->peer_addr.ip46.ip6,
491 sizeof (ip6_address_t));
492
493 vppcom_send_accept_session_reply (new_session->vpp_handle,
494 new_session->client_context,
495 0 /* retval OK */ );
496 clib_spinlock_unlock (&vcm->sessions_lockp);
497
498 (session_listener->user_cb) (ecr->accepted_session_index, &ep,
499 session_listener->user_cb_data);
500
501 /*TODO - Unregister check in close for this listener */
502
503 return;
504
505done:
506 ASSERT (0); // If we can't get a lock or accepted session fails, lets blow up.
507}
508
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800509/**
510 * * @brief vce_connect_request_handler_fn
511 * - used for listener sessions
512 * - when a vl_api_accept_session_t_handler() generates an event
513 * this callback is alerted and sets fields that consumers such as
514 * vppcom_session_accept() expect to see, ie. accepted_client_index
515 *
516 * @param arg - void* to be cast to vce_event_handler_reg_t*
517 */
518void
519vce_connect_request_handler_fn (void *arg)
520{
521 vce_event_handler_reg_t *reg = (vce_event_handler_reg_t *) arg;
522
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800523 pthread_mutex_lock (&reg->handler_lock);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800524 pthread_cond_signal (&reg->handler_cond);
525 pthread_mutex_unlock (&reg->handler_lock);
526}
527
528/**
Dave Wallace8d73e852018-03-08 16:39:28 -0500529 * @brief vce_poll_wait_connect_request_handler_fn
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800530 * - used by vppcom_epoll_xxxx() for listener sessions
531 * - when a vl_api_accept_session_t_handler() generates an event
532 * this callback is alerted and sets the fields that vppcom_epoll_wait()
533 * expects to see.
534 *
535 * @param arg - void* to be cast to vce_event_handler_reg_t*
536 */
537void
Dave Wallace8d73e852018-03-08 16:39:28 -0500538vce_poll_wait_connect_request_handler_fn (void *arg)
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800539{
540 vce_event_handler_reg_t *reg = (vce_event_handler_reg_t *) arg;
541 vce_event_t *ev;
542 /* Retrieve the VCL_EVENT_CONNECT_REQ_ACCEPTED event */
543 ev = vce_get_event_from_index (&vcm->event_thread, reg->ev_idx);
544 vce_event_connect_request_t *ecr = (vce_event_connect_request_t *) ev->data;
545
546 /* Add the accepted_session_index to the FIFO */
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -0800547 clib_spinlock_lock (&vcm->session_fifo_lockp);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800548 clib_fifo_add1 (vcm->client_session_index_fifo,
549 ecr->accepted_session_index);
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -0800550 clib_spinlock_unlock (&vcm->session_fifo_lockp);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800551
552 /* Recycling the event. */
553 clib_spinlock_lock (&(vcm->event_thread.events_lockp));
554 vcm->event_thread.recycle_event = 1;
555 clib_fifo_add1 (vcm->event_thread.event_index_fifo, reg->ev_idx);
556 clib_spinlock_unlock (&(vcm->event_thread.events_lockp));
557}
558
Dave Wallace543852a2017-08-03 02:11:34 -0400559static int
560vppcom_connect_to_vpp (char *app_name)
561{
562 api_main_t *am = &api_main;
Dave Wallaceb5a86ee2018-02-16 18:26:11 -0500563 vppcom_cfg_t *vcl_cfg = &vcm->cfg;
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -0800564 int rv = VPPCOM_OK;
Dave Wallace543852a2017-08-03 02:11:34 -0400565
Dave Wallaceb5a86ee2018-02-16 18:26:11 -0500566 if (!vcl_cfg->vpp_api_filename)
567 vcl_cfg->vpp_api_filename = format (0, "/vpe-api%c", 0);
Dave Wallace048b1d62018-01-03 22:24:41 -0500568
Dave Wallaceb5a86ee2018-02-16 18:26:11 -0500569 if (VPPCOM_DEBUG > 0)
570 clib_warning ("VCL<%d>: app (%s) connecting to VPP api (%s)...",
571 getpid (), app_name, vcl_cfg->vpp_api_filename);
572
573 if (vl_client_connect_to_vlib ((char *) vcl_cfg->vpp_api_filename, app_name,
Dave Wallacec8f1ee62017-11-29 22:46:32 -0500574 vcm->cfg.vpp_api_q_length) < 0)
Dave Wallace543852a2017-08-03 02:11:34 -0400575 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500576 clib_warning ("VCL<%d>: app (%s) connect failed!", getpid (), app_name);
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -0800577 rv = VPPCOM_ECONNREFUSED;
578 }
579 else
580 {
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -0800581 vcm->vl_input_queue = am->shmem_hdr->vl_input_queue;
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800582 vcm->my_client_index = (u32) am->my_client_index;
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -0800583 vcm->app_state = STATE_APP_CONN_VPP;
Dave Wallace9b954252018-01-18 17:01:40 -0500584
585 if (VPPCOM_DEBUG > 0)
586 clib_warning ("VCL<%d>: app (%s) is connected to VPP!",
587 getpid (), app_name);
Dave Wallace543852a2017-08-03 02:11:34 -0400588 }
589
Dave Wallace543852a2017-08-03 02:11:34 -0400590 if (VPPCOM_DEBUG > 0)
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -0800591 {
592 vcm->elog_main.lock =
593 clib_mem_alloc_aligned (CLIB_CACHE_LINE_BYTES, CLIB_CACHE_LINE_BYTES);
594 vcm->elog_main.lock[0] = 0;
595 vcm->elog_main.event_ring_size = vcm->cfg.event_ring_size;
596 elog_init (&vcm->elog_main, vcm->elog_main.event_ring_size);
597 elog_enable_disable (&vcm->elog_main, 1);
Dave Wallace543852a2017-08-03 02:11:34 -0400598
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -0800599 vcm->elog_track.name =
600 (char *) format (0, "P:%d:C:%d%c", getpid (),
601 vcm->my_client_index, 0);
602 elog_track_register (&vcm->elog_main, &vcm->elog_track);
603
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -0800604 /* *INDENT-OFF* */
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -0800605 ELOG_TYPE_DECLARE (e) =
606 {
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -0800607 .format = "connect_vpp:rv:%d",
608 .format_args = "i4",
609 };
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -0800610 struct
611 {
612 u32 data;
613 } *ed;
614 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, vcm->elog_track);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800615 ed->data = (u32) rv;
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -0800616 /* *INDENT-ON* */
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -0800617 }
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -0800618 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -0400619}
620
621static u8 *
622format_api_error (u8 * s, va_list * args)
623{
Dave Wallace543852a2017-08-03 02:11:34 -0400624 i32 error = va_arg (*args, u32);
625 uword *p;
626
627 p = hash_get (vcm->error_string_by_error_number, -error);
628
629 if (p)
630 s = format (s, "%s (%d)", p[0], error);
631 else
632 s = format (s, "%d", error);
633 return s;
634}
635
636static void
637vppcom_init_error_string_table (void)
638{
Dave Wallace543852a2017-08-03 02:11:34 -0400639 vcm->error_string_by_error_number = hash_create (0, sizeof (uword));
640
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -0800641#define _(n, v, s) hash_set (vcm->error_string_by_error_number, -v, s);
Dave Wallace543852a2017-08-03 02:11:34 -0400642 foreach_vnet_api_error;
643#undef _
644
645 hash_set (vcm->error_string_by_error_number, 99, "Misc");
646}
647
648static inline int
649vppcom_wait_for_app_state_change (app_state_t app_state)
650{
Dave Wallace543852a2017-08-03 02:11:34 -0400651 f64 timeout = clib_time_now (&vcm->clib_time) + vcm->cfg.app_timeout;
652
653 while (clib_time_now (&vcm->clib_time) < timeout)
654 {
655 if (vcm->app_state == app_state)
656 return VPPCOM_OK;
657 }
658 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -0500659 clib_warning ("VCL<%d>: timeout waiting for state %s (%d)", getpid (),
Dave Wallace543852a2017-08-03 02:11:34 -0400660 vppcom_app_state_str (app_state), app_state);
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -0800661
662 if (VPPCOM_DEBUG > 0)
663 {
664 /* *INDENT-OFF* */
665 ELOG_TYPE_DECLARE (e) =
666 {
667 .format = "ERR: timeout state:%d",
668 .format_args = "i4",
669 };
670 struct
671 {
672 u32 data;
673 } *ed;
674
675 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, vcm->elog_track);
676
677 ed->data = app_state;
678 /* *INDENT-ON* */
679 }
680
Dave Wallace543852a2017-08-03 02:11:34 -0400681 return VPPCOM_ETIMEDOUT;
682}
683
684static inline int
685vppcom_wait_for_session_state_change (u32 session_index,
686 session_state_t state,
687 f64 wait_for_time)
688{
Dave Wallace543852a2017-08-03 02:11:34 -0400689 f64 timeout = clib_time_now (&vcm->clib_time) + wait_for_time;
690 session_t *volatile session;
691 int rv;
692
693 do
694 {
695 clib_spinlock_lock (&vcm->sessions_lockp);
696 rv = vppcom_session_at_index (session_index, &session);
697 if (PREDICT_FALSE (rv))
698 {
699 clib_spinlock_unlock (&vcm->sessions_lockp);
700 return rv;
701 }
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -0800702 if (session->state & state)
Dave Wallace543852a2017-08-03 02:11:34 -0400703 {
704 clib_spinlock_unlock (&vcm->sessions_lockp);
705 return VPPCOM_OK;
706 }
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -0800707 if (session->state & STATE_FAILED)
Dave Wallace4878cbe2017-11-21 03:45:09 -0500708 {
709 clib_spinlock_unlock (&vcm->sessions_lockp);
710 return VPPCOM_ECONNREFUSED;
711 }
712
Dave Wallace543852a2017-08-03 02:11:34 -0400713 clib_spinlock_unlock (&vcm->sessions_lockp);
714 }
715 while (clib_time_now (&vcm->clib_time) < timeout);
716
717 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -0500718 clib_warning ("VCL<%d>: timeout waiting for state 0x%x (%s)", getpid (),
Dave Wallace4878cbe2017-11-21 03:45:09 -0500719 state, vppcom_session_state_str (state));
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -0800720
721 if (VPPCOM_DEBUG > 0)
722 {
723 /* *INDENT-OFF* */
724 ELOG_TYPE_DECLARE (e) =
725 {
726 .format = "ERR: timeout state:%d",
727 .format_args = "i4",
728 };
729 struct
730 {
731 u32 data;
732 } *ed;
733
734 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
735
736 ed->data = state;
737 /* *INDENT-ON* */
738 }
739
Dave Wallace543852a2017-08-03 02:11:34 -0400740 return VPPCOM_ETIMEDOUT;
741}
742
Dave Wallace543852a2017-08-03 02:11:34 -0400743/*
744 * VPP-API message functions
745 */
746static void
747vppcom_send_session_enable_disable (u8 is_enable)
748{
Dave Wallace543852a2017-08-03 02:11:34 -0400749 vl_api_session_enable_disable_t *bmp;
750 bmp = vl_msg_api_alloc (sizeof (*bmp));
751 memset (bmp, 0, sizeof (*bmp));
752
753 bmp->_vl_msg_id = ntohs (VL_API_SESSION_ENABLE_DISABLE);
754 bmp->client_index = vcm->my_client_index;
755 bmp->context = htonl (0xfeedface);
756 bmp->is_enable = is_enable;
757 vl_msg_api_send_shmem (vcm->vl_input_queue, (u8 *) & bmp);
758}
759
760static int
761vppcom_app_session_enable (void)
762{
Dave Wallace543852a2017-08-03 02:11:34 -0400763 int rv;
764
765 if (vcm->app_state != STATE_APP_ENABLED)
766 {
767 vppcom_send_session_enable_disable (1 /* is_enabled == TRUE */ );
768 rv = vppcom_wait_for_app_state_change (STATE_APP_ENABLED);
769 if (PREDICT_FALSE (rv))
770 {
771 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -0500772 clib_warning ("VCL<%d>: application session enable timed out! "
Dave Wallaceee45d412017-11-24 21:44:06 -0500773 "returning %d (%s)",
774 getpid (), rv, vppcom_retval_str (rv));
Dave Wallace543852a2017-08-03 02:11:34 -0400775 return rv;
776 }
777 }
778 return VPPCOM_OK;
779}
780
781static void
782 vl_api_session_enable_disable_reply_t_handler
783 (vl_api_session_enable_disable_reply_t * mp)
784{
Dave Wallace543852a2017-08-03 02:11:34 -0400785 if (mp->retval)
786 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500787 clib_warning ("VCL<%d>: session_enable_disable failed: %U", getpid (),
Dave Wallace543852a2017-08-03 02:11:34 -0400788 format_api_error, ntohl (mp->retval));
789 }
790 else
791 vcm->app_state = STATE_APP_ENABLED;
792}
793
794static void
795vppcom_app_send_attach (void)
796{
Dave Wallace543852a2017-08-03 02:11:34 -0400797 vl_api_application_attach_t *bmp;
Dave Wallace8af20542017-10-26 03:29:30 -0400798 u8 nsid_len = vec_len (vcm->cfg.namespace_id);
Dave Wallace774169b2017-11-01 20:07:40 -0400799 u8 app_is_proxy = (vcm->cfg.app_proxy_transport_tcp ||
800 vcm->cfg.app_proxy_transport_udp);
Dave Wallace8af20542017-10-26 03:29:30 -0400801
Dave Wallace543852a2017-08-03 02:11:34 -0400802 bmp = vl_msg_api_alloc (sizeof (*bmp));
803 memset (bmp, 0, sizeof (*bmp));
804
805 bmp->_vl_msg_id = ntohs (VL_API_APPLICATION_ATTACH);
806 bmp->client_index = vcm->my_client_index;
807 bmp->context = htonl (0xfeedface);
808 bmp->options[APP_OPTIONS_FLAGS] =
Florin Corascea194d2017-10-02 00:18:51 -0700809 APP_OPTIONS_FLAGS_ACCEPT_REDIRECT | APP_OPTIONS_FLAGS_ADD_SEGMENT |
Dave Wallace774169b2017-11-01 20:07:40 -0400810 (vcm->cfg.app_scope_local ? APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE : 0) |
811 (vcm->cfg.app_scope_global ? APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE : 0) |
812 (app_is_proxy ? APP_OPTIONS_FLAGS_IS_PROXY : 0);
813 bmp->options[APP_OPTIONS_PROXY_TRANSPORT] =
814 (vcm->cfg.app_proxy_transport_tcp ? 1 << TRANSPORT_PROTO_TCP : 0) |
815 (vcm->cfg.app_proxy_transport_udp ? 1 << TRANSPORT_PROTO_UDP : 0);
Florin Corasff6e7692017-12-11 04:59:01 -0800816 bmp->options[APP_OPTIONS_SEGMENT_SIZE] = vcm->cfg.segment_size;
817 bmp->options[APP_OPTIONS_ADD_SEGMENT_SIZE] = vcm->cfg.add_segment_size;
818 bmp->options[APP_OPTIONS_RX_FIFO_SIZE] = vcm->cfg.rx_fifo_size;
819 bmp->options[APP_OPTIONS_TX_FIFO_SIZE] = vcm->cfg.tx_fifo_size;
Florin Corasf32cff62017-12-09 08:15:00 -0800820 bmp->options[APP_OPTIONS_PREALLOC_FIFO_PAIRS] =
821 vcm->cfg.preallocated_fifo_pairs;
Florin Corasff6e7692017-12-11 04:59:01 -0800822 bmp->options[APP_OPTIONS_EVT_QUEUE_SIZE] = vcm->cfg.event_queue_size;
Dave Wallace8af20542017-10-26 03:29:30 -0400823 if (nsid_len)
824 {
825 bmp->namespace_id_len = nsid_len;
826 clib_memcpy (bmp->namespace_id, vcm->cfg.namespace_id, nsid_len);
827 bmp->options[APP_OPTIONS_NAMESPACE_SECRET] = vcm->cfg.namespace_secret;
828 }
Dave Wallace543852a2017-08-03 02:11:34 -0400829 vl_msg_api_send_shmem (vcm->vl_input_queue, (u8 *) & bmp);
830}
831
832static int
833vppcom_app_attach (void)
834{
Dave Wallace543852a2017-08-03 02:11:34 -0400835 int rv;
836
837 vppcom_app_send_attach ();
838 rv = vppcom_wait_for_app_state_change (STATE_APP_ATTACHED);
839 if (PREDICT_FALSE (rv))
840 {
841 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -0500842 clib_warning ("VCL<%d>: application attach timed out! "
843 "returning %d (%s)",
Dave Wallaceee45d412017-11-24 21:44:06 -0500844 getpid (), rv, vppcom_retval_str (rv));
Dave Wallace543852a2017-08-03 02:11:34 -0400845 return rv;
846 }
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800847
Dave Wallace543852a2017-08-03 02:11:34 -0400848 return VPPCOM_OK;
849}
850
851static void
852vppcom_app_detach (void)
853{
Dave Wallace543852a2017-08-03 02:11:34 -0400854 vl_api_application_detach_t *bmp;
855 bmp = vl_msg_api_alloc (sizeof (*bmp));
856 memset (bmp, 0, sizeof (*bmp));
857
858 bmp->_vl_msg_id = ntohs (VL_API_APPLICATION_DETACH);
859 bmp->client_index = vcm->my_client_index;
860 bmp->context = htonl (0xfeedface);
861 vl_msg_api_send_shmem (vcm->vl_input_queue, (u8 *) & bmp);
862}
863
864static void
865vl_api_application_attach_reply_t_handler (vl_api_application_attach_reply_t *
866 mp)
867{
Dave Wallace543852a2017-08-03 02:11:34 -0400868 static svm_fifo_segment_create_args_t _a;
869 svm_fifo_segment_create_args_t *a = &_a;
870 int rv;
871
872 memset (a, 0, sizeof (*a));
873 if (mp->retval)
874 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500875 clib_warning ("VCL<%d>: attach failed: %U", getpid (),
Dave Wallace543852a2017-08-03 02:11:34 -0400876 format_api_error, ntohl (mp->retval));
877 return;
878 }
879
880 if (mp->segment_name_length == 0)
881 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500882 clib_warning ("VCL<%d>: segment_name_length zero", getpid ());
Dave Wallace543852a2017-08-03 02:11:34 -0400883 return;
884 }
885
886 a->segment_name = (char *) mp->segment_name;
887 a->segment_size = mp->segment_size;
888
889 ASSERT (mp->app_event_queue_address);
890
891 /* Attach to the segment vpp created */
892 rv = svm_fifo_segment_attach (a);
893 vec_reset_length (a->new_segment_indices);
894 if (PREDICT_FALSE (rv))
895 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500896 clib_warning ("VCL<%d>: svm_fifo_segment_attach ('%s') failed",
897 getpid (), mp->segment_name);
Dave Wallace543852a2017-08-03 02:11:34 -0400898 return;
899 }
900
901 vcm->app_event_queue =
Florin Corase86a8ed2018-01-05 03:20:25 -0800902 uword_to_pointer (mp->app_event_queue_address, svm_queue_t *);
Dave Wallace543852a2017-08-03 02:11:34 -0400903
904 vcm->app_state = STATE_APP_ATTACHED;
905}
906
907static void
908vl_api_application_detach_reply_t_handler (vl_api_application_detach_reply_t *
909 mp)
910{
Dave Wallace543852a2017-08-03 02:11:34 -0400911 if (mp->retval)
Dave Wallace048b1d62018-01-03 22:24:41 -0500912 clib_warning ("VCL<%d>: detach failed: %U", getpid (), format_api_error,
Dave Wallace543852a2017-08-03 02:11:34 -0400913 ntohl (mp->retval));
914
915 vcm->app_state = STATE_APP_ENABLED;
916}
917
918static void
919vl_api_disconnect_session_reply_t_handler (vl_api_disconnect_session_reply_t *
920 mp)
921{
Dave Wallace543852a2017-08-03 02:11:34 -0400922 if (mp->retval)
Dave Wallace048b1d62018-01-03 22:24:41 -0500923 clib_warning ("VCL<%d>: vpp handle 0x%llx: disconnect session failed: %U",
Dave Wallace4878cbe2017-11-21 03:45:09 -0500924 getpid (), mp->handle, format_api_error,
925 ntohl (mp->retval));
Dave Wallace543852a2017-08-03 02:11:34 -0400926}
927
928static void
929vl_api_map_another_segment_t_handler (vl_api_map_another_segment_t * mp)
930{
Dave Wallace543852a2017-08-03 02:11:34 -0400931 static svm_fifo_segment_create_args_t _a;
932 svm_fifo_segment_create_args_t *a = &_a;
933 int rv;
934
935 memset (a, 0, sizeof (*a));
936 a->segment_name = (char *) mp->segment_name;
937 a->segment_size = mp->segment_size;
938 /* Attach to the segment vpp created */
939 rv = svm_fifo_segment_attach (a);
940 vec_reset_length (a->new_segment_indices);
941 if (PREDICT_FALSE (rv))
942 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500943 clib_warning ("VCL<%d>: svm_fifo_segment_attach ('%s') failed",
Dave Wallace2e005bb2017-11-07 01:21:39 -0500944 getpid (), mp->segment_name);
Dave Wallace543852a2017-08-03 02:11:34 -0400945 return;
946 }
947 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -0500948 clib_warning ("VCL<%d>: mapped new segment '%s' size %d", getpid (),
Dave Wallace543852a2017-08-03 02:11:34 -0400949 mp->segment_name, mp->segment_size);
950}
951
952static void
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -0800953vl_api_unmap_segment_t_handler (vl_api_unmap_segment_t * mp)
954{
955
956/*
957 * XXX Need segment_name to session_id hash,
958 * XXX - have sessionID by handle hash currently
959 */
Dave Wallace69d01192018-02-22 16:22:09 -0500960 if (VPPCOM_DEBUG > 1)
961 clib_warning ("Unmapped segment '%s'", mp->segment_name);
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -0800962}
963
964static void
Dave Wallace543852a2017-08-03 02:11:34 -0400965vl_api_disconnect_session_t_handler (vl_api_disconnect_session_t * mp)
966{
Dave Wallace543852a2017-08-03 02:11:34 -0400967 uword *p;
Dave Wallace543852a2017-08-03 02:11:34 -0400968
969 p = hash_get (vcm->session_index_by_vpp_handles, mp->handle);
970 if (p)
971 {
Dave Wallace4878cbe2017-11-21 03:45:09 -0500972 int rv;
973 session_t *session = 0;
974 u32 session_index = p[0];
975
976 VCL_LOCK_AND_GET_SESSION (session_index, &session);
977 session->state = STATE_CLOSE_ON_EMPTY;
978
979 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -0500980 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -0500981 "setting state to 0x%x (%s)",
Dave Wallace4878cbe2017-11-21 03:45:09 -0500982 getpid (), mp->handle, session_index, session->state,
983 vppcom_session_state_str (session->state));
Dave Wallace543852a2017-08-03 02:11:34 -0400984 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace4878cbe2017-11-21 03:45:09 -0500985 return;
986
987 done:
988 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -0500989 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
Dave Wallace4878cbe2017-11-21 03:45:09 -0500990 "session lookup failed!",
991 getpid (), mp->handle, session_index);
Dave Wallace543852a2017-08-03 02:11:34 -0400992 }
993 else
Dave Wallace048b1d62018-01-03 22:24:41 -0500994 clib_warning ("VCL<%d>: vpp handle 0x%llx: session lookup by "
Dave Wallace4878cbe2017-11-21 03:45:09 -0500995 "handle failed!", getpid (), mp->handle);
Dave Wallace543852a2017-08-03 02:11:34 -0400996}
997
998static void
999vl_api_reset_session_t_handler (vl_api_reset_session_t * mp)
1000{
Dave Wallace543852a2017-08-03 02:11:34 -04001001 session_t *session = 0;
1002 vl_api_reset_session_reply_t *rmp;
1003 uword *p;
1004 int rv = 0;
1005
1006 p = hash_get (vcm->session_index_by_vpp_handles, mp->handle);
1007 if (p)
1008 {
1009 int rval;
1010 clib_spinlock_lock (&vcm->sessions_lockp);
1011 rval = vppcom_session_at_index (p[0], &session);
1012 if (PREDICT_FALSE (rval))
1013 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05001014 rv = VNET_API_ERROR_INVALID_VALUE_2;
Dave Wallace048b1d62018-01-03 22:24:41 -05001015 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -05001016 "session lookup failed! returning %d %U",
1017 getpid (), mp->handle, p[0],
1018 rv, format_api_error, rv);
Dave Wallace543852a2017-08-03 02:11:34 -04001019 }
1020 else
Dave Wallace4878cbe2017-11-21 03:45:09 -05001021 {
1022 /* TBD: should this disconnect immediately and
1023 * flush the fifos?
1024 */
1025 session->state = STATE_CLOSE_ON_EMPTY;
1026
1027 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05001028 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
Dave Wallace4878cbe2017-11-21 03:45:09 -05001029 "state set to %d (%s)!", getpid (),
1030 mp->handle, p[0], session->state,
1031 vppcom_session_state_str (session->state));
1032 }
Dave Wallace543852a2017-08-03 02:11:34 -04001033 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace543852a2017-08-03 02:11:34 -04001034 }
1035 else
1036 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05001037 rv = VNET_API_ERROR_INVALID_VALUE;
Dave Wallace048b1d62018-01-03 22:24:41 -05001038 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx: session lookup "
Dave Wallace4878cbe2017-11-21 03:45:09 -05001039 "failed! returning %d %U",
1040 getpid (), mp->handle, rv, format_api_error, rv);
Dave Wallace543852a2017-08-03 02:11:34 -04001041 }
1042
1043 rmp = vl_msg_api_alloc (sizeof (*rmp));
1044 memset (rmp, 0, sizeof (*rmp));
1045 rmp->_vl_msg_id = ntohs (VL_API_RESET_SESSION_REPLY);
1046 rmp->retval = htonl (rv);
1047 rmp->handle = mp->handle;
1048 vl_msg_api_send_shmem (vcm->vl_input_queue, (u8 *) & rmp);
1049}
1050
1051static void
Dave Wallace33e002b2017-09-06 01:20:02 -04001052vl_api_connect_session_reply_t_handler (vl_api_connect_session_reply_t * mp)
Dave Wallace543852a2017-08-03 02:11:34 -04001053{
Dave Wallaceee45d412017-11-24 21:44:06 -05001054 session_t *session = 0;
Dave Wallace543852a2017-08-03 02:11:34 -04001055 u32 session_index;
1056 svm_fifo_t *rx_fifo, *tx_fifo;
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08001057 int rv = VPPCOM_OK;
Dave Wallace543852a2017-08-03 02:11:34 -04001058
Dave Wallace4878cbe2017-11-21 03:45:09 -05001059 session_index = mp->context;
Dave Wallaceee45d412017-11-24 21:44:06 -05001060 VCL_LOCK_AND_GET_SESSION (session_index, &session);
1061done:
Dave Wallace543852a2017-08-03 02:11:34 -04001062 if (mp->retval)
1063 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001064 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -05001065 "connect failed! %U",
1066 getpid (), mp->handle, session_index,
1067 format_api_error, ntohl (mp->retval));
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08001068 if (session)
Dave Wallaceee45d412017-11-24 21:44:06 -05001069 {
1070 session->state = STATE_FAILED;
1071 session->vpp_handle = mp->handle;
1072 }
1073 else
1074 {
1075 clib_warning ("[%s] ERROR: vpp handle 0x%llx, sid %u: "
1076 "Invalid session index (%u)!",
1077 getpid (), mp->handle, session_index);
1078 }
1079 goto done_unlock;
Dave Wallace543852a2017-08-03 02:11:34 -04001080 }
1081
Dave Wallaceee45d412017-11-24 21:44:06 -05001082 if (rv)
1083 goto done_unlock;
Dave Wallace543852a2017-08-03 02:11:34 -04001084
Dave Wallace543852a2017-08-03 02:11:34 -04001085 /*
1086 * Setup session
1087 */
Dave Wallace33e002b2017-09-06 01:20:02 -04001088 session->vpp_event_queue = uword_to_pointer (mp->vpp_event_queue_address,
Florin Corase86a8ed2018-01-05 03:20:25 -08001089 svm_queue_t *);
Dave Wallace543852a2017-08-03 02:11:34 -04001090
1091 rx_fifo = uword_to_pointer (mp->server_rx_fifo, svm_fifo_t *);
1092 rx_fifo->client_session_index = session_index;
1093 tx_fifo = uword_to_pointer (mp->server_tx_fifo, svm_fifo_t *);
1094 tx_fifo->client_session_index = session_index;
1095
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001096 session->rx_fifo = rx_fifo;
1097 session->tx_fifo = tx_fifo;
Dave Wallace60caa062017-11-10 17:07:13 -05001098 session->vpp_handle = mp->handle;
Dave Wallace9d1d73a2017-11-20 02:31:48 -05001099 session->lcl_addr.is_ip4 = mp->is_ip4;
1100 clib_memcpy (&session->lcl_addr.ip46, mp->lcl_ip,
1101 sizeof (session->peer_addr.ip46));
1102 session->lcl_port = mp->lcl_port;
Dave Wallace543852a2017-08-03 02:11:34 -04001103 session->state = STATE_CONNECT;
1104
1105 /* Add it to lookup table */
1106 hash_set (vcm->session_index_by_vpp_handles, mp->handle, session_index);
Dave Wallace60caa062017-11-10 17:07:13 -05001107
1108 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05001109 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: connect succeeded!"
Dave Wallaceee45d412017-11-24 21:44:06 -05001110 " session_rx_fifo %p, refcnt %d,"
1111 " session_tx_fifo %p, refcnt %d",
1112 getpid (), mp->handle, session_index,
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001113 session->rx_fifo,
1114 session->rx_fifo->refcnt,
1115 session->tx_fifo, session->tx_fifo->refcnt);
Dave Wallaceee45d412017-11-24 21:44:06 -05001116done_unlock:
Dave Wallace543852a2017-08-03 02:11:34 -04001117 clib_spinlock_unlock (&vcm->sessions_lockp);
1118}
1119
1120static void
1121vppcom_send_connect_sock (session_t * session, u32 session_index)
1122{
Dave Wallace543852a2017-08-03 02:11:34 -04001123 vl_api_connect_sock_t *cmp;
1124
1125 /* Assumes caller as acquired the spinlock: vcm->sessions_lockp */
Dave Wallace543852a2017-08-03 02:11:34 -04001126 cmp = vl_msg_api_alloc (sizeof (*cmp));
1127 memset (cmp, 0, sizeof (*cmp));
1128 cmp->_vl_msg_id = ntohs (VL_API_CONNECT_SOCK);
1129 cmp->client_index = vcm->my_client_index;
Dave Wallace33e002b2017-09-06 01:20:02 -04001130 cmp->context = session_index;
Dave Wallace543852a2017-08-03 02:11:34 -04001131
Dave Wallace35830af2017-10-09 01:43:42 -04001132 cmp->is_ip4 = session->peer_addr.is_ip4;
1133 clib_memcpy (cmp->ip, &session->peer_addr.ip46, sizeof (cmp->ip));
Stevenac1f96d2017-10-24 16:03:58 -07001134 cmp->port = session->peer_port;
Dave Wallace543852a2017-08-03 02:11:34 -04001135 cmp->proto = session->proto;
1136 clib_memcpy (cmp->options, session->options, sizeof (cmp->options));
1137 vl_msg_api_send_shmem (vcm->vl_input_queue, (u8 *) & cmp);
1138}
1139
Dave Wallace66cf6eb2017-10-26 02:51:07 -04001140static inline void
Dave Wallace4878cbe2017-11-21 03:45:09 -05001141vppcom_send_disconnect_session_reply (u64 vpp_handle, u32 session_index,
1142 int rv)
1143{
1144 vl_api_disconnect_session_reply_t *rmp;
1145
1146 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05001147 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
1148 "sending disconnect msg",
Dave Wallace4878cbe2017-11-21 03:45:09 -05001149 getpid (), vpp_handle, session_index);
1150
1151 rmp = vl_msg_api_alloc (sizeof (*rmp));
1152 memset (rmp, 0, sizeof (*rmp));
1153
1154 rmp->_vl_msg_id = ntohs (VL_API_DISCONNECT_SESSION_REPLY);
1155 rmp->retval = htonl (rv);
1156 rmp->handle = vpp_handle;
1157 vl_msg_api_send_shmem (vcm->vl_input_queue, (u8 *) & rmp);
1158}
1159
1160static inline void
1161vppcom_send_disconnect_session (u64 vpp_handle, u32 session_index)
Dave Wallace543852a2017-08-03 02:11:34 -04001162{
Dave Wallace543852a2017-08-03 02:11:34 -04001163 vl_api_disconnect_session_t *dmp;
Dave Wallace543852a2017-08-03 02:11:34 -04001164
Dave Wallace4878cbe2017-11-21 03:45:09 -05001165 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05001166 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
1167 "sending disconnect msg",
Dave Wallace4878cbe2017-11-21 03:45:09 -05001168 getpid (), vpp_handle, session_index);
1169
Dave Wallace543852a2017-08-03 02:11:34 -04001170 dmp = vl_msg_api_alloc (sizeof (*dmp));
1171 memset (dmp, 0, sizeof (*dmp));
1172 dmp->_vl_msg_id = ntohs (VL_API_DISCONNECT_SESSION);
1173 dmp->client_index = vcm->my_client_index;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001174 dmp->handle = vpp_handle;
Dave Wallace543852a2017-08-03 02:11:34 -04001175 vl_msg_api_send_shmem (vcm->vl_input_queue, (u8 *) & dmp);
Dave Wallace543852a2017-08-03 02:11:34 -04001176}
1177
1178static void
1179vl_api_bind_sock_reply_t_handler (vl_api_bind_sock_reply_t * mp)
1180{
Dave Wallace543852a2017-08-03 02:11:34 -04001181 session_t *session = 0;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001182 u32 session_index = mp->context;
Dave Wallace543852a2017-08-03 02:11:34 -04001183 int rv;
1184
Dave Wallaceee45d412017-11-24 21:44:06 -05001185 VCL_LOCK_AND_GET_SESSION (session_index, &session);
1186done:
Dave Wallace543852a2017-08-03 02:11:34 -04001187 if (mp->retval)
Dave Wallace4878cbe2017-11-21 03:45:09 -05001188 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001189 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, "
1190 "sid %u: bind failed: %U",
1191 getpid (), mp->handle, session_index,
1192 format_api_error, ntohl (mp->retval));
Dave Wallace4878cbe2017-11-21 03:45:09 -05001193 rv = vppcom_session_at_index (session_index, &session);
1194 if (rv == VPPCOM_OK)
Dave Wallaceee45d412017-11-24 21:44:06 -05001195 {
1196 session->state = STATE_FAILED;
1197 session->vpp_handle = mp->handle;
1198 }
1199 else
1200 {
1201 clib_warning ("[%s] ERROR: vpp handle 0x%llx, sid %u: "
1202 "Invalid session index (%u)!",
1203 getpid (), mp->handle, session_index);
1204 }
1205 goto done_unlock;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001206 }
Dave Wallace543852a2017-08-03 02:11:34 -04001207
Dave Wallaceee45d412017-11-24 21:44:06 -05001208 session->vpp_handle = mp->handle;
1209 session->lcl_addr.is_ip4 = mp->lcl_is_ip4;
Dave Wallacede910062018-03-20 09:22:13 -04001210 session->lcl_addr.ip46 = to_ip46 (!mp->lcl_is_ip4, mp->lcl_ip);
Dave Wallaceee45d412017-11-24 21:44:06 -05001211 session->lcl_port = mp->lcl_port;
1212 vppcom_session_table_add_listener (mp->handle, session_index);
Dave Wallaceee45d412017-11-24 21:44:06 -05001213 session->state = STATE_LISTEN;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001214
Dave Wallaceee45d412017-11-24 21:44:06 -05001215 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05001216 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: bind succeeded!",
Dave Wallaceee45d412017-11-24 21:44:06 -05001217 getpid (), mp->handle, mp->context);
1218done_unlock:
Dave Wallace543852a2017-08-03 02:11:34 -04001219 clib_spinlock_unlock (&vcm->sessions_lockp);
1220}
1221
1222static void
1223vl_api_unbind_sock_reply_t_handler (vl_api_unbind_sock_reply_t * mp)
1224{
Dave Wallace4878cbe2017-11-21 03:45:09 -05001225 if (mp->retval)
Dave Wallace048b1d62018-01-03 22:24:41 -05001226 clib_warning ("VCL<%d>: ERROR: sid %u: unbind failed: %U",
Dave Wallace4878cbe2017-11-21 03:45:09 -05001227 getpid (), mp->context, format_api_error,
1228 ntohl (mp->retval));
Dave Wallace543852a2017-08-03 02:11:34 -04001229
Dave Wallace4878cbe2017-11-21 03:45:09 -05001230 else if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05001231 clib_warning ("VCL<%d>: sid %u: unbind succeeded!",
1232 getpid (), mp->context);
Dave Wallace543852a2017-08-03 02:11:34 -04001233}
1234
1235u8 *
1236format_ip4_address (u8 * s, va_list * args)
1237{
1238 u8 *a = va_arg (*args, u8 *);
1239 return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
1240}
1241
1242u8 *
1243format_ip6_address (u8 * s, va_list * args)
1244{
1245 ip6_address_t *a = va_arg (*args, ip6_address_t *);
1246 u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
1247
1248 i_max_n_zero = ARRAY_LEN (a->as_u16);
1249 max_n_zeros = 0;
1250 i_first_zero = i_max_n_zero;
1251 n_zeros = 0;
1252 for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
1253 {
1254 u32 is_zero = a->as_u16[i] == 0;
1255 if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
1256 {
1257 i_first_zero = i;
1258 n_zeros = 0;
1259 }
1260 n_zeros += is_zero;
1261 if ((!is_zero && n_zeros > max_n_zeros)
1262 || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
1263 {
1264 i_max_n_zero = i_first_zero;
1265 max_n_zeros = n_zeros;
1266 i_first_zero = ARRAY_LEN (a->as_u16);
1267 n_zeros = 0;
1268 }
1269 }
1270
1271 last_double_colon = 0;
1272 for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
1273 {
1274 if (i == i_max_n_zero && max_n_zeros > 1)
1275 {
1276 s = format (s, "::");
1277 i += max_n_zeros - 1;
1278 last_double_colon = 1;
1279 }
1280 else
1281 {
1282 s = format (s, "%s%x",
1283 (last_double_colon || i == 0) ? "" : ":",
1284 clib_net_to_host_u16 (a->as_u16[i]));
1285 last_double_colon = 0;
1286 }
1287 }
1288
1289 return s;
1290}
1291
1292/* Format an IP46 address. */
1293u8 *
1294format_ip46_address (u8 * s, va_list * args)
1295{
1296 ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
1297 ip46_type_t type = va_arg (*args, ip46_type_t);
1298 int is_ip4 = 1;
1299
1300 switch (type)
1301 {
1302 case IP46_TYPE_ANY:
1303 is_ip4 = ip46_address_is_ip4 (ip46);
1304 break;
1305 case IP46_TYPE_IP4:
1306 is_ip4 = 1;
1307 break;
1308 case IP46_TYPE_IP6:
1309 is_ip4 = 0;
1310 break;
1311 }
1312
1313 return is_ip4 ?
1314 format (s, "%U", format_ip4_address, &ip46->ip4) :
1315 format (s, "%U", format_ip6_address, &ip46->ip6);
1316}
1317
1318static void
1319vl_api_accept_session_t_handler (vl_api_accept_session_t * mp)
1320{
Dave Wallace543852a2017-08-03 02:11:34 -04001321 svm_fifo_t *rx_fifo, *tx_fifo;
Florin Corasdcf55ce2017-11-16 15:32:50 -08001322 session_t *session, *listen_session;
Dave Wallace543852a2017-08-03 02:11:34 -04001323 u32 session_index;
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001324 vce_event_connect_request_t *ecr;
1325 vce_event_t *ev;
1326 int rv;
1327 u32 ev_idx;
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08001328 uword elts = 0;
Dave Wallace543852a2017-08-03 02:11:34 -04001329
Dave Wallace60caa062017-11-10 17:07:13 -05001330 clib_spinlock_lock (&vcm->sessions_lockp);
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08001331
1332 clib_spinlock_lock (&vcm->session_fifo_lockp);
1333 elts = clib_fifo_free_elts (vcm->client_session_index_fifo);
1334 clib_spinlock_unlock (&vcm->session_fifo_lockp);
1335
1336 if (!elts)
Dave Wallace543852a2017-08-03 02:11:34 -04001337 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001338 clib_warning ("VCL<%d>: client session queue is full!", getpid ());
Dave Wallaced2931962017-11-25 04:17:39 -05001339 vppcom_send_accept_session_reply (mp->handle, mp->context,
Florin Corasdcf55ce2017-11-16 15:32:50 -08001340 VNET_API_ERROR_QUEUE_FULL);
1341 clib_spinlock_unlock (&vcm->sessions_lockp);
1342 return;
1343 }
1344
1345 listen_session = vppcom_session_table_lookup_listener (mp->listener_handle);
1346 if (!listen_session)
1347 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001348 clib_warning ("VCL<%d>: ERROR: couldn't find listen session: "
1349 "unknown vpp listener handle %llx",
1350 getpid (), mp->listener_handle);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001351 vppcom_send_accept_session_reply (mp->handle, mp->context,
1352 VNET_API_ERROR_INVALID_ARGUMENT);
Dave Wallace60caa062017-11-10 17:07:13 -05001353 clib_spinlock_unlock (&vcm->sessions_lockp);
1354 return;
Dave Wallace543852a2017-08-03 02:11:34 -04001355 }
1356
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001357 /* TODO check listener depth and update */
1358 /* TODO on "child" fd close, update listener depth */
1359
Dave Wallace543852a2017-08-03 02:11:34 -04001360 /* Allocate local session and set it up */
1361 pool_get (vcm->sessions, session);
1362 memset (session, 0, sizeof (*session));
1363 session_index = session - vcm->sessions;
1364
1365 rx_fifo = uword_to_pointer (mp->server_rx_fifo, svm_fifo_t *);
1366 rx_fifo->client_session_index = session_index;
1367 tx_fifo = uword_to_pointer (mp->server_tx_fifo, svm_fifo_t *);
1368 tx_fifo->client_session_index = session_index;
1369
Dave Wallace60caa062017-11-10 17:07:13 -05001370 session->vpp_handle = mp->handle;
Dave Wallaced2931962017-11-25 04:17:39 -05001371 session->client_context = mp->context;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001372 session->rx_fifo = rx_fifo;
1373 session->tx_fifo = tx_fifo;
Dave Wallace33e002b2017-09-06 01:20:02 -04001374 session->vpp_event_queue = uword_to_pointer (mp->vpp_event_queue_address,
Florin Corase86a8ed2018-01-05 03:20:25 -08001375 svm_queue_t *);
Dave Wallace543852a2017-08-03 02:11:34 -04001376 session->state = STATE_ACCEPT;
Stevenac1f96d2017-10-24 16:03:58 -07001377 session->peer_port = mp->port;
Dave Wallace35830af2017-10-09 01:43:42 -04001378 session->peer_addr.is_ip4 = mp->is_ip4;
Dave Wallacede910062018-03-20 09:22:13 -04001379 session->peer_addr.ip46 = to_ip46 (!mp->is_ip4, mp->ip);
Dave Wallace543852a2017-08-03 02:11:34 -04001380
1381 /* Add it to lookup table */
1382 hash_set (vcm->session_index_by_vpp_handles, mp->handle, session_index);
Florin Corasdcf55ce2017-11-16 15:32:50 -08001383 session->lcl_port = listen_session->lcl_port;
1384 session->lcl_addr = listen_session->lcl_addr;
Dave Wallace227867f2017-11-13 21:21:53 -05001385
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001386 /* Create an event for handlers */
1387
1388 clib_spinlock_lock (&vcm->event_thread.events_lockp);
1389
1390 pool_get (vcm->event_thread.vce_events, ev);
1391 ev->data = clib_mem_alloc (sizeof (vce_event_connect_request_t));
1392 ev->refcnt = 0;
1393 ev_idx = (u32) (ev - vcm->event_thread.vce_events);
1394 ecr = ev->data;
1395 ev->evk.eid = VCL_EVENT_CONNECT_REQ_ACCEPTED;
1396 listen_session = vppcom_session_table_lookup_listener (mp->listener_handle);
1397 ev->evk.session_index = (u32) (listen_session - vcm->sessions);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001398 ecr->accepted_session_index = session_index;
1399
1400 clib_spinlock_unlock (&vcm->event_thread.events_lockp);
1401
1402 rv = vce_generate_event (&vcm->event_thread, ev_idx);
1403
1404 ASSERT (rv == 0);
Florin Corasdcf55ce2017-11-16 15:32:50 -08001405
Dave Wallace60caa062017-11-10 17:07:13 -05001406 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05001407 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: client accept "
Florin Coras50e8bdb2017-11-27 10:37:05 -08001408 "request from %s address %U port %d queue %p!", getpid (),
Dave Wallaced2931962017-11-25 04:17:39 -05001409 mp->handle, session_index, mp->is_ip4 ? "IPv4" : "IPv6",
Dave Wallacede910062018-03-20 09:22:13 -04001410 format_ip46_address, &mp->ip,
1411 mp->is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6,
Florin Coras50e8bdb2017-11-27 10:37:05 -08001412 clib_net_to_host_u16 (mp->port), session->vpp_event_queue);
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08001413
1414 if (VPPCOM_DEBUG > 0)
1415 {
1416 session->elog_track.name =
1417 (char *) format (0, "C:%d:S:%d%c", vcm->my_client_index,
1418 session_index, 0);
1419 elog_track_register (&vcm->elog_main, &session->elog_track);
1420
1421 if (session->peer_addr.is_ip4)
1422 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08001423 /* *INDENT-OFF* */
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08001424 ELOG_TYPE_DECLARE (e) =
1425 {
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08001426 .format =
1427 "client_accept:handle:%x addr:%d.%d.%d.%d:%d",
1428 .format_args = "i8i1i1i1i1i2",
1429 };
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08001430
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08001431 CLIB_PACKED (struct {
1432 u64 handle; //8
1433 u8 addr[4]; //4
1434 u16 port; //2
1435 }) * ed;
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08001436
1437 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
1438
1439 ed->handle = mp->handle;
1440 ed->addr[0] = session->peer_addr.ip46.ip4.as_u8[0];
1441 ed->addr[1] = session->peer_addr.ip46.ip4.as_u8[1];
1442 ed->addr[2] = session->peer_addr.ip46.ip4.as_u8[2];
1443 ed->addr[3] = session->peer_addr.ip46.ip4.as_u8[3];
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08001444 ed->port = clib_net_to_host_u16 (session->peer_port);
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08001445 /* *INDENT-ON* */
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08001446 }
1447 else
1448 {
1449 clib_warning ("ip6");
1450 }
1451 }
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08001452
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001453 clib_spinlock_unlock (&vcm->sessions_lockp);
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08001454
Dave Wallace60caa062017-11-10 17:07:13 -05001455}
1456
1457static void
Dave Wallace4878cbe2017-11-21 03:45:09 -05001458vppcom_send_bind_sock (session_t * session, u32 session_index)
Dave Wallace543852a2017-08-03 02:11:34 -04001459{
Dave Wallace543852a2017-08-03 02:11:34 -04001460 vl_api_bind_sock_t *bmp;
1461
1462 /* Assumes caller has acquired spinlock: vcm->sessions_lockp */
Dave Wallace543852a2017-08-03 02:11:34 -04001463 bmp = vl_msg_api_alloc (sizeof (*bmp));
1464 memset (bmp, 0, sizeof (*bmp));
1465
1466 bmp->_vl_msg_id = ntohs (VL_API_BIND_SOCK);
1467 bmp->client_index = vcm->my_client_index;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001468 bmp->context = session_index;
Dave Wallace35830af2017-10-09 01:43:42 -04001469 bmp->is_ip4 = session->lcl_addr.is_ip4;
1470 clib_memcpy (bmp->ip, &session->lcl_addr.ip46, sizeof (bmp->ip));
Stevenac1f96d2017-10-24 16:03:58 -07001471 bmp->port = session->lcl_port;
Dave Wallace543852a2017-08-03 02:11:34 -04001472 bmp->proto = session->proto;
1473 clib_memcpy (bmp->options, session->options, sizeof (bmp->options));
1474 vl_msg_api_send_shmem (vcm->vl_input_queue, (u8 *) & bmp);
1475}
1476
1477static void
Dave Wallace4878cbe2017-11-21 03:45:09 -05001478vppcom_send_unbind_sock (u64 vpp_handle)
Dave Wallace543852a2017-08-03 02:11:34 -04001479{
Dave Wallace543852a2017-08-03 02:11:34 -04001480 vl_api_unbind_sock_t *ump;
Dave Wallace543852a2017-08-03 02:11:34 -04001481
1482 ump = vl_msg_api_alloc (sizeof (*ump));
1483 memset (ump, 0, sizeof (*ump));
1484
1485 ump->_vl_msg_id = ntohs (VL_API_UNBIND_SOCK);
1486 ump->client_index = vcm->my_client_index;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001487 ump->handle = vpp_handle;
Dave Wallace543852a2017-08-03 02:11:34 -04001488 vl_msg_api_send_shmem (vcm->vl_input_queue, (u8 *) & ump);
1489}
1490
1491static int
Dave Wallace543852a2017-08-03 02:11:34 -04001492vppcom_session_unbind (u32 session_index)
1493{
Dave Wallace4878cbe2017-11-21 03:45:09 -05001494 session_t *session = 0;
Dave Wallace543852a2017-08-03 02:11:34 -04001495 int rv;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001496 u64 vpp_handle;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001497 elog_track_t session_elog_track;
Dave Wallace543852a2017-08-03 02:11:34 -04001498
Dave Wallace4878cbe2017-11-21 03:45:09 -05001499 VCL_LOCK_AND_GET_SESSION (session_index, &session);
1500
1501 vpp_handle = session->vpp_handle;
1502 vppcom_session_table_del_listener (vpp_handle);
1503 session->vpp_handle = ~0;
1504 session->state = STATE_DISCONNECT;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001505 session_elog_track = session->elog_track;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001506
Dave Wallace543852a2017-08-03 02:11:34 -04001507 clib_spinlock_unlock (&vcm->sessions_lockp);
1508
Dave Wallace4878cbe2017-11-21 03:45:09 -05001509 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05001510 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
Dave Wallace4878cbe2017-11-21 03:45:09 -05001511 "sending unbind msg! new state 0x%x (%s)",
1512 getpid (), vpp_handle, session_index,
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001513 STATE_DISCONNECT,
1514 vppcom_session_state_str (STATE_DISCONNECT));
Dave Wallace4878cbe2017-11-21 03:45:09 -05001515
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08001516 if (VPPCOM_DEBUG > 0)
1517 {
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08001518 /* *INDENT-OFF* */
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08001519 ELOG_TYPE_DECLARE (e) =
1520 {
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08001521 .format = "unbind: handle:%x",
1522 .format_args = "i8",
1523 };
1524
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08001525 struct
1526 {
1527 u64 handle;
1528 } *ed;
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08001529
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001530 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session_elog_track);
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08001531 ed->handle = vpp_handle;
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08001532 /* *INDENT-ON* */
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08001533 }
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001534
Dave Wallace4878cbe2017-11-21 03:45:09 -05001535 vppcom_send_unbind_sock (vpp_handle);
1536
1537done:
1538 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04001539}
1540
Dave Wallace66cf6eb2017-10-26 02:51:07 -04001541static inline int
Dave Wallace543852a2017-08-03 02:11:34 -04001542vppcom_session_disconnect (u32 session_index)
1543{
Dave Wallace543852a2017-08-03 02:11:34 -04001544 int rv;
Dave Wallace66cf6eb2017-10-26 02:51:07 -04001545 session_t *session;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001546 u64 vpp_handle;
1547 session_state_t state;
Dave Wallace543852a2017-08-03 02:11:34 -04001548
Dave Wallace4878cbe2017-11-21 03:45:09 -05001549 VCL_LOCK_AND_GET_SESSION (session_index, &session);
1550
1551 vpp_handle = session->vpp_handle;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001552 state = session->state;
1553 clib_spinlock_unlock (&vcm->sessions_lockp);
1554
1555 if (VPPCOM_DEBUG > 1)
Dave Wallace543852a2017-08-03 02:11:34 -04001556 {
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001557 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u "
1558 "state 0x%x (%s)",
Dave Wallace4878cbe2017-11-21 03:45:09 -05001559 getpid (), vpp_handle, session_index,
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001560 state, vppcom_session_state_str (state));
Dave Wallace543852a2017-08-03 02:11:34 -04001561 }
Dave Wallace66cf6eb2017-10-26 02:51:07 -04001562
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001563 if (PREDICT_FALSE (state & STATE_LISTEN))
Dave Wallace66cf6eb2017-10-26 02:51:07 -04001564 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001565 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -05001566 "Cannot disconnect a listen socket!",
1567 getpid (), vpp_handle, session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001568 rv = VPPCOM_EBADFD;
1569 goto done;
1570 }
Dave Wallace66cf6eb2017-10-26 02:51:07 -04001571
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001572 /* The peer has already initiated the close,
1573 * so send the disconnect session reply.
Dave Wallace4878cbe2017-11-21 03:45:09 -05001574 */
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001575 if (state & STATE_CLOSE_ON_EMPTY)
Dave Wallace4878cbe2017-11-21 03:45:09 -05001576 {
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001577 //XXX alagalah - Check and drain here?
1578 vppcom_send_disconnect_session_reply (vpp_handle,
1579 session_index, 0 /* rv */ );
1580 if (VPPCOM_DEBUG > 1)
1581 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
1582 "sending disconnect REPLY...",
1583 getpid (), vpp_handle, session_index);
Dave Wallace66cf6eb2017-10-26 02:51:07 -04001584 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05001585
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001586 /* Otherwise, send a disconnect session msg...
Dave Wallace4878cbe2017-11-21 03:45:09 -05001587 */
Dave Wallace66cf6eb2017-10-26 02:51:07 -04001588 else
Dave Wallace227867f2017-11-13 21:21:53 -05001589 {
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001590 if (VPPCOM_DEBUG > 1)
1591 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
1592 "sending disconnect...",
1593 getpid (), vpp_handle, session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001594
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001595 vppcom_send_disconnect_session (vpp_handle, session_index);
Dave Wallace227867f2017-11-13 21:21:53 -05001596 }
Dave Wallace66cf6eb2017-10-26 02:51:07 -04001597
Dave Wallace4878cbe2017-11-21 03:45:09 -05001598done:
1599 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04001600}
1601
1602#define foreach_sock_msg \
1603_(SESSION_ENABLE_DISABLE_REPLY, session_enable_disable_reply) \
1604_(BIND_SOCK_REPLY, bind_sock_reply) \
1605_(UNBIND_SOCK_REPLY, unbind_sock_reply) \
1606_(ACCEPT_SESSION, accept_session) \
Dave Wallace33e002b2017-09-06 01:20:02 -04001607_(CONNECT_SESSION_REPLY, connect_session_reply) \
Dave Wallace543852a2017-08-03 02:11:34 -04001608_(DISCONNECT_SESSION, disconnect_session) \
1609_(DISCONNECT_SESSION_REPLY, disconnect_session_reply) \
1610_(RESET_SESSION, reset_session) \
1611_(APPLICATION_ATTACH_REPLY, application_attach_reply) \
1612_(APPLICATION_DETACH_REPLY, application_detach_reply) \
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001613_(MAP_ANOTHER_SEGMENT, map_another_segment) \
1614_(UNMAP_SEGMENT, unmap_segment)
Dave Wallace543852a2017-08-03 02:11:34 -04001615
1616static void
1617vppcom_api_hookup (void)
1618{
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08001619#define _(N, n) \
Dave Wallace543852a2017-08-03 02:11:34 -04001620 vl_msg_api_set_handlers(VL_API_##N, #n, \
1621 vl_api_##n##_t_handler, \
1622 vl_noop_handler, \
1623 vl_api_##n##_t_endian, \
1624 vl_api_##n##_t_print, \
1625 sizeof(vl_api_##n##_t), 1);
1626 foreach_sock_msg;
1627#undef _
1628}
1629
1630static void
1631vppcom_cfg_init (vppcom_cfg_t * vcl_cfg)
1632{
1633 ASSERT (vcl_cfg);
1634
1635 vcl_cfg->heapsize = (256ULL << 20);
Dave Wallacec8f1ee62017-11-29 22:46:32 -05001636 vcl_cfg->vpp_api_q_length = 1024;
Dave Wallace543852a2017-08-03 02:11:34 -04001637 vcl_cfg->segment_baseva = 0x200000000ULL;
1638 vcl_cfg->segment_size = (256 << 20);
1639 vcl_cfg->add_segment_size = (128 << 20);
1640 vcl_cfg->preallocated_fifo_pairs = 8;
1641 vcl_cfg->rx_fifo_size = (1 << 20);
1642 vcl_cfg->tx_fifo_size = (1 << 20);
1643 vcl_cfg->event_queue_size = 2048;
1644 vcl_cfg->listen_queue_size = CLIB_CACHE_LINE_BYTES / sizeof (u32);
1645 vcl_cfg->app_timeout = 10 * 60.0;
1646 vcl_cfg->session_timeout = 10 * 60.0;
1647 vcl_cfg->accept_timeout = 60.0;
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -08001648 vcl_cfg->event_ring_size = (128 << 10);
1649 vcl_cfg->event_log_path = "/dev/shm";
Dave Wallace543852a2017-08-03 02:11:34 -04001650}
1651
1652static void
1653vppcom_cfg_heapsize (char *conf_fname)
1654{
Dave Wallace543852a2017-08-03 02:11:34 -04001655 vppcom_cfg_t *vcl_cfg = &vcm->cfg;
1656 FILE *fp;
1657 char inbuf[4096];
1658 int argc = 1;
1659 char **argv = NULL;
1660 char *arg = NULL;
1661 char *p;
1662 int i;
1663 u8 *sizep;
1664 u32 size;
Dave Wallace2e005bb2017-11-07 01:21:39 -05001665 void *vcl_mem;
1666 void *heap;
Dave Wallace543852a2017-08-03 02:11:34 -04001667
1668 fp = fopen (conf_fname, "r");
1669 if (fp == NULL)
1670 {
1671 if (VPPCOM_DEBUG > 0)
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05001672 clib_warning ("VCL<%d>: using default heapsize %lld (0x%llx)",
1673 getpid (), vcl_cfg->heapsize, vcl_cfg->heapsize);
Dave Wallace543852a2017-08-03 02:11:34 -04001674 goto defaulted;
1675 }
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05001676
Dave Wallace543852a2017-08-03 02:11:34 -04001677 argv = calloc (1, sizeof (char *));
1678 if (argv == NULL)
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05001679 {
1680 if (VPPCOM_DEBUG > 0)
1681 clib_warning ("VCL<%d>: calloc failed, using default "
1682 "heapsize %lld (0x%llx)",
1683 getpid (), vcl_cfg->heapsize, vcl_cfg->heapsize);
1684 goto defaulted;
1685 }
Dave Wallace543852a2017-08-03 02:11:34 -04001686
1687 while (1)
1688 {
1689 if (fgets (inbuf, 4096, fp) == 0)
1690 break;
1691 p = strtok (inbuf, " \t\n");
1692 while (p != NULL)
1693 {
1694 if (*p == '#')
1695 break;
1696 argc++;
1697 char **tmp = realloc (argv, argc * sizeof (char *));
1698 if (tmp == NULL)
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05001699 {
1700 if (VPPCOM_DEBUG > 0)
1701 clib_warning ("VCL<%d>: realloc failed, "
1702 "using default heapsize %lld (0x%llx)",
1703 getpid (), vcl_cfg->heapsize,
1704 vcl_cfg->heapsize);
1705 goto defaulted;
1706 }
Dave Wallace543852a2017-08-03 02:11:34 -04001707 argv = tmp;
1708 arg = strndup (p, 1024);
1709 if (arg == NULL)
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05001710 {
1711 if (VPPCOM_DEBUG > 0)
1712 clib_warning ("VCL<%d>: strndup failed, "
1713 "using default heapsize %lld (0x%llx)",
1714 getpid (), vcl_cfg->heapsize,
1715 vcl_cfg->heapsize);
1716 goto defaulted;
1717 }
Dave Wallace543852a2017-08-03 02:11:34 -04001718 argv[argc - 1] = arg;
1719 p = strtok (NULL, " \t\n");
1720 }
1721 }
1722
1723 fclose (fp);
Chris Lukeab7b8d92017-09-07 07:40:13 -04001724 fp = NULL;
Dave Wallace543852a2017-08-03 02:11:34 -04001725
1726 char **tmp = realloc (argv, (argc + 1) * sizeof (char *));
1727 if (tmp == NULL)
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05001728 {
1729 if (VPPCOM_DEBUG > 0)
1730 clib_warning ("VCL<%d>: realloc failed, "
1731 "using default heapsize %lld (0x%llx)",
1732 getpid (), vcl_cfg->heapsize, vcl_cfg->heapsize);
1733 goto defaulted;
1734 }
Dave Wallace543852a2017-08-03 02:11:34 -04001735 argv = tmp;
1736 argv[argc] = NULL;
1737
1738 /*
1739 * Look for and parse the "heapsize" config parameter.
1740 * Manual since none of the clib infra has been bootstrapped yet.
1741 *
1742 * Format: heapsize <nn>[mM][gG]
1743 */
1744
1745 for (i = 1; i < (argc - 1); i++)
1746 {
1747 if (!strncmp (argv[i], "heapsize", 8))
1748 {
1749 sizep = (u8 *) argv[i + 1];
1750 size = 0;
1751 while (*sizep >= '0' && *sizep <= '9')
1752 {
1753 size *= 10;
1754 size += *sizep++ - '0';
1755 }
1756 if (size == 0)
1757 {
1758 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001759 clib_warning ("VCL<%d>: parse error '%s %s', "
Dave Wallace543852a2017-08-03 02:11:34 -04001760 "using default heapsize %lld (0x%llx)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05001761 getpid (), argv[i], argv[i + 1],
Dave Wallace543852a2017-08-03 02:11:34 -04001762 vcl_cfg->heapsize, vcl_cfg->heapsize);
1763 goto defaulted;
1764 }
1765
1766 if (*sizep == 'g' || *sizep == 'G')
1767 vcl_cfg->heapsize = size << 30;
1768 else if (*sizep == 'm' || *sizep == 'M')
1769 vcl_cfg->heapsize = size << 20;
1770 else
1771 {
1772 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001773 clib_warning ("VCL<%d>: parse error '%s %s', "
Dave Wallace543852a2017-08-03 02:11:34 -04001774 "using default heapsize %lld (0x%llx)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05001775 getpid (), argv[i], argv[i + 1],
Dave Wallace543852a2017-08-03 02:11:34 -04001776 vcl_cfg->heapsize, vcl_cfg->heapsize);
1777 goto defaulted;
1778 }
1779 }
1780 }
1781
1782defaulted:
Chris Lukeab7b8d92017-09-07 07:40:13 -04001783 if (fp != NULL)
1784 fclose (fp);
1785 if (argv != NULL)
1786 free (argv);
Dave Wallacee7fa24e2017-11-07 13:07:44 -05001787
Dave Wallace2e005bb2017-11-07 01:21:39 -05001788 vcl_mem = mmap (0, vcl_cfg->heapsize, PROT_READ | PROT_WRITE,
1789 MAP_SHARED | MAP_ANONYMOUS, -1, 0);
Steven0cdd5bd2017-11-08 14:14:45 -08001790 if (vcl_mem == MAP_FAILED)
Dave Wallacee7fa24e2017-11-07 13:07:44 -05001791 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001792 clib_unix_error ("VCL<%d>: ERROR: mmap(0, %lld == 0x%llx, "
Dave Wallacee7fa24e2017-11-07 13:07:44 -05001793 "PROT_READ | PROT_WRITE,MAP_SHARED | MAP_ANONYMOUS, "
1794 "-1, 0) failed!",
1795 getpid (), vcl_cfg->heapsize, vcl_cfg->heapsize);
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05001796 ASSERT (vcl_mem != MAP_FAILED);
Dave Wallacee7fa24e2017-11-07 13:07:44 -05001797 return;
1798 }
Dave Wallace2e005bb2017-11-07 01:21:39 -05001799 heap = clib_mem_init (vcl_mem, vcl_cfg->heapsize);
1800 if (!heap)
Dave Wallace2e005bb2017-11-07 01:21:39 -05001801 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001802 clib_warning ("VCL<%d>: ERROR: clib_mem_init() failed!", getpid ());
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05001803 ASSERT (heap);
Dave Wallacee7fa24e2017-11-07 13:07:44 -05001804 return;
Dave Wallace2e005bb2017-11-07 01:21:39 -05001805 }
Dave Wallacee7fa24e2017-11-07 13:07:44 -05001806 vcl_mem = clib_mem_alloc (sizeof (_vppcom_main));
1807 if (!vcl_mem)
1808 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001809 clib_warning ("VCL<%d>: ERROR: clib_mem_alloc() failed!", getpid ());
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05001810 ASSERT (vcl_mem);
Dave Wallacee7fa24e2017-11-07 13:07:44 -05001811 return;
1812 }
1813
1814 clib_memcpy (vcl_mem, &_vppcom_main, sizeof (_vppcom_main));
1815 vcm = vcl_mem;
1816
1817 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001818 clib_warning ("VCL<%d>: allocated VCL heap = %p, size %lld (0x%llx)",
Dave Wallacee7fa24e2017-11-07 13:07:44 -05001819 getpid (), heap, vcl_cfg->heapsize, vcl_cfg->heapsize);
Dave Wallace543852a2017-08-03 02:11:34 -04001820}
1821
1822static void
1823vppcom_cfg_read (char *conf_fname)
1824{
Dave Wallace543852a2017-08-03 02:11:34 -04001825 vppcom_cfg_t *vcl_cfg = &vcm->cfg;
1826 int fd;
1827 unformat_input_t _input, *input = &_input;
1828 unformat_input_t _line_input, *line_input = &_line_input;
1829 u8 vc_cfg_input = 0;
1830 u8 *chroot_path;
1831 struct stat s;
Dave Wallacec8f1ee62017-11-29 22:46:32 -05001832 u32 uid, gid, q_len;
Dave Wallace543852a2017-08-03 02:11:34 -04001833
1834 fd = open (conf_fname, O_RDONLY);
1835 if (fd < 0)
1836 {
1837 if (VPPCOM_DEBUG > 0)
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05001838 clib_warning ("VCL<%d>: using default configuration.",
Dave Wallace2e005bb2017-11-07 01:21:39 -05001839 getpid (), conf_fname);
Dave Wallace543852a2017-08-03 02:11:34 -04001840 goto file_done;
1841 }
1842
1843 if (fstat (fd, &s) < 0)
1844 {
1845 if (VPPCOM_DEBUG > 0)
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05001846 clib_warning ("VCL<%d>: failed to stat `%s', "
1847 "using default configuration", getpid (), conf_fname);
Dave Wallace543852a2017-08-03 02:11:34 -04001848 goto file_done;
1849 }
1850
1851 if (!(S_ISREG (s.st_mode) || S_ISLNK (s.st_mode)))
1852 {
1853 if (VPPCOM_DEBUG > 0)
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05001854 clib_warning ("VCL<%d>: not a regular file `%s', "
1855 "using default configuration", getpid (), conf_fname);
Dave Wallace543852a2017-08-03 02:11:34 -04001856 goto file_done;
1857 }
1858
Dave Barach59b25652017-09-10 15:04:27 -04001859 unformat_init_clib_file (input, fd);
Dave Wallace543852a2017-08-03 02:11:34 -04001860
1861 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1862 {
Chris Lukeb2bcad62017-09-18 08:51:22 -04001863 (void) unformat_user (input, unformat_line_input, line_input);
Dave Wallace543852a2017-08-03 02:11:34 -04001864 unformat_skip_white_space (line_input);
1865
Dave Wallace8af20542017-10-26 03:29:30 -04001866 if (unformat (line_input, "vcl {"))
Dave Wallace543852a2017-08-03 02:11:34 -04001867 {
1868 vc_cfg_input = 1;
1869 continue;
1870 }
1871
1872 if (vc_cfg_input)
1873 {
1874 if (unformat (line_input, "heapsize %s", &chroot_path))
1875 {
1876 vec_terminate_c_string (chroot_path);
1877 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001878 clib_warning ("VCL<%d>: configured heapsize %s, "
Dave Wallace543852a2017-08-03 02:11:34 -04001879 "actual heapsize %lld (0x%llx)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05001880 getpid (), chroot_path, vcl_cfg->heapsize,
Dave Wallace543852a2017-08-03 02:11:34 -04001881 vcl_cfg->heapsize);
1882 vec_free (chroot_path);
1883 }
1884 else if (unformat (line_input, "api-prefix %s", &chroot_path))
1885 {
1886 vec_terminate_c_string (chroot_path);
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05001887 if (vcl_cfg->vpp_api_filename)
1888 vec_free (vcl_cfg->vpp_api_filename);
1889 vcl_cfg->vpp_api_filename = format (0, "/%s-vpe-api%c",
1890 chroot_path, 0);
Dave Wallace543852a2017-08-03 02:11:34 -04001891 vl_set_memory_root_path ((char *) chroot_path);
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05001892
Dave Wallace543852a2017-08-03 02:11:34 -04001893 if (VPPCOM_DEBUG > 0)
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05001894 clib_warning ("VCL<%d>: configured api-prefix (%s) and "
1895 "api filename (%s)", getpid (), chroot_path,
1896 vcl_cfg->vpp_api_filename);
Dave Wallace543852a2017-08-03 02:11:34 -04001897 chroot_path = 0; /* Don't vec_free() it! */
1898 }
Dave Wallacec8f1ee62017-11-29 22:46:32 -05001899 else if (unformat (line_input, "vpp-api-q-length %d", &q_len))
1900 {
1901 if (q_len < vcl_cfg->vpp_api_q_length)
1902 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001903 clib_warning ("VCL<%d>: ERROR: configured vpp-api-q-length "
Dave Wallacec8f1ee62017-11-29 22:46:32 -05001904 "(%u) is too small! Using default: %u ",
1905 getpid (), q_len, vcl_cfg->vpp_api_q_length);
1906 }
1907 else
1908 {
1909 vcl_cfg->vpp_api_q_length = q_len;
1910
1911 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001912 clib_warning ("VCL<%d>: configured vpp-api-q-length %u",
Dave Wallacec8f1ee62017-11-29 22:46:32 -05001913 getpid (), vcl_cfg->vpp_api_q_length);
1914 }
1915 }
Dave Wallace543852a2017-08-03 02:11:34 -04001916 else if (unformat (line_input, "uid %d", &uid))
1917 {
1918 vl_set_memory_uid (uid);
1919 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001920 clib_warning ("VCL<%d>: configured uid %d", getpid (), uid);
Dave Wallace543852a2017-08-03 02:11:34 -04001921 }
1922 else if (unformat (line_input, "gid %d", &gid))
1923 {
1924 vl_set_memory_gid (gid);
1925 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001926 clib_warning ("VCL<%d>: configured gid %d", getpid (), gid);
Dave Wallace543852a2017-08-03 02:11:34 -04001927 }
Dave Wallace8af20542017-10-26 03:29:30 -04001928 else if (unformat (line_input, "segment-baseva 0x%lx",
Dave Wallace543852a2017-08-03 02:11:34 -04001929 &vcl_cfg->segment_baseva))
1930 {
1931 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001932 clib_warning ("VCL<%d>: configured segment_baseva 0x%lx",
Dave Wallace2e005bb2017-11-07 01:21:39 -05001933 getpid (), vcl_cfg->segment_baseva);
Dave Wallace543852a2017-08-03 02:11:34 -04001934 }
1935 else if (unformat (line_input, "segment-size 0x%lx",
1936 &vcl_cfg->segment_size))
1937 {
1938 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001939 clib_warning ("VCL<%d>: configured segment_size 0x%lx (%ld)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05001940 getpid (), vcl_cfg->segment_size,
Dave Wallace543852a2017-08-03 02:11:34 -04001941 vcl_cfg->segment_size);
1942 }
1943 else if (unformat (line_input, "segment-size %ld",
1944 &vcl_cfg->segment_size))
1945 {
1946 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001947 clib_warning ("VCL<%d>: configured segment_size %ld (0x%lx)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05001948 getpid (), vcl_cfg->segment_size,
Dave Wallace543852a2017-08-03 02:11:34 -04001949 vcl_cfg->segment_size);
1950 }
1951 else if (unformat (line_input, "add-segment-size 0x%lx",
1952 &vcl_cfg->add_segment_size))
1953 {
1954 if (VPPCOM_DEBUG > 0)
1955 clib_warning
Dave Wallace048b1d62018-01-03 22:24:41 -05001956 ("VCL<%d>: configured add_segment_size 0x%lx (%ld)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05001957 getpid (), vcl_cfg->add_segment_size,
Dave Wallace543852a2017-08-03 02:11:34 -04001958 vcl_cfg->add_segment_size);
1959 }
1960 else if (unformat (line_input, "add-segment-size %ld",
1961 &vcl_cfg->add_segment_size))
1962 {
1963 if (VPPCOM_DEBUG > 0)
1964 clib_warning
Dave Wallace048b1d62018-01-03 22:24:41 -05001965 ("VCL<%d>: configured add_segment_size %ld (0x%lx)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05001966 getpid (), vcl_cfg->add_segment_size,
Dave Wallace543852a2017-08-03 02:11:34 -04001967 vcl_cfg->add_segment_size);
1968 }
1969 else if (unformat (line_input, "preallocated-fifo-pairs %d",
1970 &vcl_cfg->preallocated_fifo_pairs))
1971 {
1972 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001973 clib_warning ("VCL<%d>: configured preallocated_fifo_pairs "
Dave Wallace2e005bb2017-11-07 01:21:39 -05001974 "%d (0x%x)", getpid (),
Dave Wallace543852a2017-08-03 02:11:34 -04001975 vcl_cfg->preallocated_fifo_pairs,
1976 vcl_cfg->preallocated_fifo_pairs);
1977 }
1978 else if (unformat (line_input, "rx-fifo-size 0x%lx",
1979 &vcl_cfg->rx_fifo_size))
1980 {
1981 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001982 clib_warning ("VCL<%d>: configured rx_fifo_size 0x%lx (%ld)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05001983 getpid (), vcl_cfg->rx_fifo_size,
Dave Wallace543852a2017-08-03 02:11:34 -04001984 vcl_cfg->rx_fifo_size);
1985 }
1986 else if (unformat (line_input, "rx-fifo-size %ld",
1987 &vcl_cfg->rx_fifo_size))
1988 {
1989 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001990 clib_warning ("VCL<%d>: configured rx_fifo_size %ld (0x%lx)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05001991 getpid (), vcl_cfg->rx_fifo_size,
Dave Wallace543852a2017-08-03 02:11:34 -04001992 vcl_cfg->rx_fifo_size);
1993 }
1994 else if (unformat (line_input, "tx-fifo-size 0x%lx",
1995 &vcl_cfg->tx_fifo_size))
1996 {
1997 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001998 clib_warning ("VCL<%d>: configured tx_fifo_size 0x%lx (%ld)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05001999 getpid (), vcl_cfg->tx_fifo_size,
Dave Wallace543852a2017-08-03 02:11:34 -04002000 vcl_cfg->tx_fifo_size);
2001 }
2002 else if (unformat (line_input, "tx-fifo-size %ld",
2003 &vcl_cfg->tx_fifo_size))
2004 {
2005 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002006 clib_warning ("VCL<%d>: configured tx_fifo_size %ld (0x%lx)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002007 getpid (), vcl_cfg->tx_fifo_size,
Dave Wallace543852a2017-08-03 02:11:34 -04002008 vcl_cfg->tx_fifo_size);
2009 }
2010 else if (unformat (line_input, "event-queue-size 0x%lx",
2011 &vcl_cfg->event_queue_size))
2012 {
2013 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002014 clib_warning ("VCL<%d>: configured event_queue_size "
2015 "0x%lx (%ld)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002016 getpid (), vcl_cfg->event_queue_size,
Dave Wallace543852a2017-08-03 02:11:34 -04002017 vcl_cfg->event_queue_size);
2018 }
2019 else if (unformat (line_input, "event-queue-size %ld",
2020 &vcl_cfg->event_queue_size))
2021 {
2022 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002023 clib_warning ("VCL<%d>: configured event_queue_size "
2024 "%ld (0x%lx)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002025 getpid (), vcl_cfg->event_queue_size,
Dave Wallace543852a2017-08-03 02:11:34 -04002026 vcl_cfg->event_queue_size);
2027 }
2028 else if (unformat (line_input, "listen-queue-size 0x%lx",
2029 &vcl_cfg->listen_queue_size))
2030 {
2031 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002032 clib_warning ("VCL<%d>: configured listen_queue_size "
2033 "0x%lx (%ld)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002034 getpid (), vcl_cfg->listen_queue_size,
Dave Wallace543852a2017-08-03 02:11:34 -04002035 vcl_cfg->listen_queue_size);
2036 }
2037 else if (unformat (line_input, "listen-queue-size %ld",
2038 &vcl_cfg->listen_queue_size))
2039 {
2040 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002041 clib_warning ("VCL<%d>: configured listen_queue_size "
2042 "%ld (0x%lx)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002043 getpid (), vcl_cfg->listen_queue_size,
Dave Wallace543852a2017-08-03 02:11:34 -04002044 vcl_cfg->listen_queue_size);
2045 }
2046 else if (unformat (line_input, "app-timeout %f",
2047 &vcl_cfg->app_timeout))
2048 {
2049 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002050 clib_warning ("VCL<%d>: configured app_timeout %f",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002051 getpid (), vcl_cfg->app_timeout);
Dave Wallace543852a2017-08-03 02:11:34 -04002052 }
2053 else if (unformat (line_input, "session-timeout %f",
2054 &vcl_cfg->session_timeout))
2055 {
2056 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002057 clib_warning ("VCL<%d>: configured session_timeout %f",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002058 getpid (), vcl_cfg->session_timeout);
Dave Wallace543852a2017-08-03 02:11:34 -04002059 }
2060 else if (unformat (line_input, "accept-timeout %f",
2061 &vcl_cfg->accept_timeout))
2062 {
2063 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002064 clib_warning ("VCL<%d>: configured accept_timeout %f",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002065 getpid (), vcl_cfg->accept_timeout);
Dave Wallace543852a2017-08-03 02:11:34 -04002066 }
Dave Wallace774169b2017-11-01 20:07:40 -04002067 else if (unformat (line_input, "app-proxy-transport-tcp"))
Dave Wallace8af20542017-10-26 03:29:30 -04002068 {
Dave Wallace774169b2017-11-01 20:07:40 -04002069 vcl_cfg->app_proxy_transport_tcp = 1;
Dave Wallace8af20542017-10-26 03:29:30 -04002070 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002071 clib_warning ("VCL<%d>: configured "
2072 "app_proxy_transport_tcp (%d)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002073 getpid (), vcl_cfg->app_proxy_transport_tcp);
Dave Wallace8af20542017-10-26 03:29:30 -04002074 }
Dave Wallace774169b2017-11-01 20:07:40 -04002075 else if (unformat (line_input, "app-proxy-transport-udp"))
Dave Wallace8af20542017-10-26 03:29:30 -04002076 {
Dave Wallace774169b2017-11-01 20:07:40 -04002077 vcl_cfg->app_proxy_transport_udp = 1;
Dave Wallace8af20542017-10-26 03:29:30 -04002078 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002079 clib_warning ("VCL<%d>: configured "
2080 "app_proxy_transport_udp (%d)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002081 getpid (), vcl_cfg->app_proxy_transport_udp);
Dave Wallace8af20542017-10-26 03:29:30 -04002082 }
Dave Wallace774169b2017-11-01 20:07:40 -04002083 else if (unformat (line_input, "app-scope-local"))
Dave Wallace8af20542017-10-26 03:29:30 -04002084 {
Dave Wallace774169b2017-11-01 20:07:40 -04002085 vcl_cfg->app_scope_local = 1;
Dave Wallace8af20542017-10-26 03:29:30 -04002086 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002087 clib_warning ("VCL<%d>: configured app_scope_local (%d)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002088 getpid (), vcl_cfg->app_scope_local);
Dave Wallace774169b2017-11-01 20:07:40 -04002089 }
2090 else if (unformat (line_input, "app-scope-global"))
2091 {
2092 vcl_cfg->app_scope_global = 1;
2093 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002094 clib_warning ("VCL<%d>: configured app_scope_global (%d)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002095 getpid (), vcl_cfg->app_scope_global);
Dave Wallace8af20542017-10-26 03:29:30 -04002096 }
2097 else if (unformat (line_input, "namespace-secret %lu",
2098 &vcl_cfg->namespace_secret))
2099 {
2100 if (VPPCOM_DEBUG > 0)
2101 clib_warning
Dave Wallace048b1d62018-01-03 22:24:41 -05002102 ("VCL<%d>: configured namespace_secret %lu (0x%lx)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002103 getpid (), vcl_cfg->namespace_secret,
Dave Wallace8af20542017-10-26 03:29:30 -04002104 vcl_cfg->namespace_secret);
2105 }
2106 else if (unformat (line_input, "namespace-id %v",
2107 &vcl_cfg->namespace_id))
2108 {
2109 vl_api_application_attach_t *mp;
2110 u32 max_nsid_vec_len = sizeof (mp->namespace_id) - 1;
2111 u32 nsid_vec_len = vec_len (vcl_cfg->namespace_id);
2112 if (nsid_vec_len > max_nsid_vec_len)
2113 {
2114 _vec_len (vcl_cfg->namespace_id) = max_nsid_vec_len;
2115 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002116 clib_warning ("VCL<%d>: configured namespace_id is "
2117 "too long, truncated to %d characters!",
2118 getpid (), max_nsid_vec_len);
Dave Wallace8af20542017-10-26 03:29:30 -04002119 }
2120
2121 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002122 clib_warning ("VCL<%d>: configured namespace_id %v",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002123 getpid (), vcl_cfg->namespace_id);
Dave Wallace8af20542017-10-26 03:29:30 -04002124 }
Dave Wallace543852a2017-08-03 02:11:34 -04002125 else if (unformat (line_input, "}"))
2126 {
2127 vc_cfg_input = 0;
2128 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002129 clib_warning ("VCL<%d>: completed parsing vppcom config!",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002130 getpid ());
Dave Wallace543852a2017-08-03 02:11:34 -04002131 goto input_done;
2132 }
2133 else
2134 {
2135 if (line_input->buffer[line_input->index] != '#')
2136 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002137 clib_warning ("VCL<%d>: Unknown vppcom config option: '%s'",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002138 getpid (), (char *)
Dave Wallace543852a2017-08-03 02:11:34 -04002139 &line_input->buffer[line_input->index]);
2140 }
2141 }
2142 }
2143 }
2144
2145input_done:
2146 unformat_free (input);
2147
2148file_done:
Chris Lukeab7b8d92017-09-07 07:40:13 -04002149 if (fd >= 0)
Dave Wallace543852a2017-08-03 02:11:34 -04002150 close (fd);
2151}
2152
2153/*
2154 * VPPCOM Public API functions
2155 */
2156int
2157vppcom_app_create (char *app_name)
2158{
Dave Wallace543852a2017-08-03 02:11:34 -04002159 vppcom_cfg_t *vcl_cfg = &vcm->cfg;
2160 u8 *heap;
2161 mheap_t *h;
2162 int rv;
2163
2164 if (!vcm->init)
2165 {
2166 char *conf_fname;
Dave Wallace8af20542017-10-26 03:29:30 -04002167 char *env_var_str;
Dave Wallace543852a2017-08-03 02:11:34 -04002168
2169 vcm->init = 1;
Dave Wallace543852a2017-08-03 02:11:34 -04002170 vppcom_cfg_init (vcl_cfg);
Dave Wallace498b3a52017-11-09 13:00:34 -05002171 env_var_str = getenv (VPPCOM_ENV_DEBUG);
2172 if (env_var_str)
2173 {
2174 u32 tmp;
2175 if (sscanf (env_var_str, "%u", &tmp) != 1)
Dave Wallace69d01192018-02-22 16:22:09 -05002176 clib_warning ("VCL<%d>: WARNING: Invalid debug level specified "
2177 "in the environment variable " VPPCOM_ENV_DEBUG
Dave Wallace498b3a52017-11-09 13:00:34 -05002178 " (%s)!\n", getpid (), env_var_str);
2179 else
2180 {
2181 vcm->debug = tmp;
Dave Wallace69d01192018-02-22 16:22:09 -05002182 if (VPPCOM_DEBUG > 0)
2183 clib_warning ("VCL<%d>: configured VCL debug level (%u) from "
2184 VPPCOM_ENV_DEBUG "!", getpid (), vcm->debug);
Dave Wallace498b3a52017-11-09 13:00:34 -05002185 }
2186 }
Dave Wallace8af20542017-10-26 03:29:30 -04002187 conf_fname = getenv (VPPCOM_ENV_CONF);
Dave Wallace543852a2017-08-03 02:11:34 -04002188 if (!conf_fname)
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05002189 conf_fname = VPPCOM_CONF_DEFAULT;
Dave Wallace543852a2017-08-03 02:11:34 -04002190 vppcom_cfg_heapsize (conf_fname);
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05002191 vcl_cfg = &vcm->cfg;
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08002192 clib_spinlock_init (&vcm->session_fifo_lockp);
Dave Wallace2e005bb2017-11-07 01:21:39 -05002193 clib_fifo_validate (vcm->client_session_index_fifo,
2194 vcm->cfg.listen_queue_size);
Dave Wallace543852a2017-08-03 02:11:34 -04002195 vppcom_cfg_read (conf_fname);
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05002196
2197 env_var_str = getenv (VPPCOM_ENV_API_PREFIX);
2198 if (env_var_str)
2199 {
2200 if (vcl_cfg->vpp_api_filename)
2201 vec_free (vcl_cfg->vpp_api_filename);
2202 vcl_cfg->vpp_api_filename = format (0, "/%s-vpe-api%c",
2203 env_var_str, 0);
2204 vl_set_memory_root_path ((char *) env_var_str);
2205
2206 if (VPPCOM_DEBUG > 0)
2207 clib_warning ("VCL<%d>: configured api prefix (%s) and "
2208 "filename (%s) from " VPPCOM_ENV_API_PREFIX "!",
2209 getpid (), env_var_str, vcl_cfg->vpp_api_filename);
2210 }
Dave Wallace8af20542017-10-26 03:29:30 -04002211 env_var_str = getenv (VPPCOM_ENV_APP_NAMESPACE_ID);
2212 if (env_var_str)
2213 {
2214 u32 ns_id_vec_len = strlen (env_var_str);
2215
2216 vec_reset_length (vcm->cfg.namespace_id);
2217 vec_validate (vcm->cfg.namespace_id, ns_id_vec_len - 1);
2218 clib_memcpy (vcm->cfg.namespace_id, env_var_str, ns_id_vec_len);
2219
2220 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002221 clib_warning ("VCL<%d>: configured namespace_id (%v) from "
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08002222 VPPCOM_ENV_APP_NAMESPACE_ID
2223 "!", getpid (), vcm->cfg.namespace_id);
Dave Wallace8af20542017-10-26 03:29:30 -04002224 }
2225 env_var_str = getenv (VPPCOM_ENV_APP_NAMESPACE_SECRET);
2226 if (env_var_str)
2227 {
2228 u64 tmp;
2229 if (sscanf (env_var_str, "%lu", &tmp) != 1)
Dave Wallace69d01192018-02-22 16:22:09 -05002230 clib_warning ("VCL<%d>: WARNING: Invalid namespace secret "
2231 "specified in the environment variable "
Dave Wallace8af20542017-10-26 03:29:30 -04002232 VPPCOM_ENV_APP_NAMESPACE_SECRET
Dave Wallace2e005bb2017-11-07 01:21:39 -05002233 " (%s)!\n", getpid (), env_var_str);
Dave Wallace8af20542017-10-26 03:29:30 -04002234 else
2235 {
2236 vcm->cfg.namespace_secret = tmp;
2237 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002238 clib_warning ("VCL<%d>: configured namespace secret "
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08002239 "(%lu) from "
Dave Wallace9a0546d2018-03-08 11:40:28 -05002240 VPPCOM_ENV_APP_NAMESPACE_SECRET
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08002241 "!", getpid (), vcm->cfg.namespace_secret);
Dave Wallace8af20542017-10-26 03:29:30 -04002242 }
2243 }
Dave Wallace774169b2017-11-01 20:07:40 -04002244 if (getenv (VPPCOM_ENV_APP_PROXY_TRANSPORT_TCP))
Dave Wallace8af20542017-10-26 03:29:30 -04002245 {
Dave Wallace774169b2017-11-01 20:07:40 -04002246 vcm->cfg.app_proxy_transport_tcp = 1;
Dave Wallace8af20542017-10-26 03:29:30 -04002247 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002248 clib_warning ("VCL<%d>: configured app_proxy_transport_tcp "
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08002249 "(%u) from "
2250 VPPCOM_ENV_APP_PROXY_TRANSPORT_TCP
Dave Wallace048b1d62018-01-03 22:24:41 -05002251 "!", getpid (), vcm->cfg.app_proxy_transport_tcp);
Dave Wallace8af20542017-10-26 03:29:30 -04002252 }
Dave Wallace774169b2017-11-01 20:07:40 -04002253 if (getenv (VPPCOM_ENV_APP_PROXY_TRANSPORT_UDP))
Dave Wallace8af20542017-10-26 03:29:30 -04002254 {
Dave Wallace774169b2017-11-01 20:07:40 -04002255 vcm->cfg.app_proxy_transport_udp = 1;
Dave Wallace8af20542017-10-26 03:29:30 -04002256 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002257 clib_warning ("VCL<%d>: configured app_proxy_transport_udp "
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08002258 "(%u) from "
2259 VPPCOM_ENV_APP_PROXY_TRANSPORT_UDP
Dave Wallace048b1d62018-01-03 22:24:41 -05002260 "!", getpid (), vcm->cfg.app_proxy_transport_udp);
Dave Wallace774169b2017-11-01 20:07:40 -04002261 }
2262 if (getenv (VPPCOM_ENV_APP_SCOPE_LOCAL))
2263 {
2264 vcm->cfg.app_scope_local = 1;
2265 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002266 clib_warning ("VCL<%d>: configured app_scope_local (%u) from "
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08002267 VPPCOM_ENV_APP_SCOPE_LOCAL
2268 "!", getpid (), vcm->cfg.app_scope_local);
Dave Wallace774169b2017-11-01 20:07:40 -04002269 }
2270 if (getenv (VPPCOM_ENV_APP_SCOPE_GLOBAL))
2271 {
2272 vcm->cfg.app_scope_global = 1;
2273 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002274 clib_warning ("VCL<%d>: configured app_scope_global (%u) from "
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08002275 VPPCOM_ENV_APP_SCOPE_GLOBAL
2276 "!", getpid (), vcm->cfg.app_scope_global);
Dave Wallace8af20542017-10-26 03:29:30 -04002277 }
2278
Dave Wallace543852a2017-08-03 02:11:34 -04002279 vcm->main_cpu = os_get_thread_index ();
2280 heap = clib_mem_get_per_cpu_heap ();
2281 h = mheap_header (heap);
2282
2283 /* make the main heap thread-safe */
2284 h->flags |= MHEAP_FLAG_THREAD_SAFE;
2285
2286 vcm->session_index_by_vpp_handles = hash_create (0, sizeof (uword));
2287
2288 clib_time_init (&vcm->clib_time);
2289 vppcom_init_error_string_table ();
Florin Corasa332c462018-01-31 06:52:17 -08002290 svm_fifo_segment_main_init (vcl_cfg->segment_baseva,
2291 20 /* timeout in secs */ );
Dave Wallace543852a2017-08-03 02:11:34 -04002292 clib_spinlock_init (&vcm->sessions_lockp);
Dave Wallace543852a2017-08-03 02:11:34 -04002293 }
2294
2295 if (vcm->my_client_index == ~0)
2296 {
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002297
2298 /* API hookup and connect to VPP */
Dave Wallace048b1d62018-01-03 22:24:41 -05002299 vppcom_api_hookup ();
Dave Wallace543852a2017-08-03 02:11:34 -04002300 vcm->app_state = STATE_APP_START;
2301 rv = vppcom_connect_to_vpp (app_name);
2302 if (rv)
2303 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002304 clib_warning ("VCL<%d>: ERROR: couldn't connect to VPP!",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002305 getpid ());
Dave Wallace543852a2017-08-03 02:11:34 -04002306 return rv;
2307 }
2308
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002309 /* State event handling thread */
2310
2311 rv = vce_start_event_thread (&(vcm->event_thread), 20);
2312
2313
Dave Wallace543852a2017-08-03 02:11:34 -04002314 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002315 clib_warning ("VCL<%d>: sending session enable", getpid ());
Dave Wallace543852a2017-08-03 02:11:34 -04002316
Dave Wallace048b1d62018-01-03 22:24:41 -05002317 rv = vppcom_app_session_enable ();
Dave Wallace543852a2017-08-03 02:11:34 -04002318 if (rv)
2319 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002320 clib_warning ("VCL<%d>: ERROR: vppcom_app_session_enable() "
2321 "failed!", getpid ());
Dave Wallace543852a2017-08-03 02:11:34 -04002322 return rv;
2323 }
Dave Wallace543852a2017-08-03 02:11:34 -04002324
Dave Wallace66cf6eb2017-10-26 02:51:07 -04002325 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002326 clib_warning ("VCL<%d>: sending app attach", getpid ());
2327
2328 rv = vppcom_app_attach ();
2329 if (rv)
2330 {
2331 clib_warning ("VCL<%d>: ERROR: vppcom_app_attach() failed!",
2332 getpid ());
2333 return rv;
2334 }
2335
2336 if (VPPCOM_DEBUG > 0)
2337 clib_warning ("VCL<%d>: app_name '%s', my_client_index %d (0x%x)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002338 getpid (), app_name, vcm->my_client_index,
Dave Wallace66cf6eb2017-10-26 02:51:07 -04002339 vcm->my_client_index);
2340 }
Dave Wallace543852a2017-08-03 02:11:34 -04002341
2342 return VPPCOM_OK;
2343}
2344
2345void
2346vppcom_app_destroy (void)
2347{
Dave Wallace543852a2017-08-03 02:11:34 -04002348 int rv;
Dave Wallacede910062018-03-20 09:22:13 -04002349 f64 orig_app_timeout;
Dave Wallace543852a2017-08-03 02:11:34 -04002350
2351 if (vcm->my_client_index == ~0)
2352 return;
2353
2354 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002355 clib_warning ("VCL<%d>: detaching from VPP, my_client_index %d (0x%x)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002356 getpid (), vcm->my_client_index, vcm->my_client_index);
Dave Wallace543852a2017-08-03 02:11:34 -04002357
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -08002358 if (VPPCOM_DEBUG > 0)
2359 {
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002360 /* *INDENT-OFF* */
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -08002361 ELOG_TYPE_DECLARE (e) =
2362 {
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002363 .format = "app_detach:C:%d",
2364 .format_args = "i4",
2365 };
2366
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -08002367 struct
2368 {
2369 u32 data;
2370 } *ed;
2371 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, vcm->elog_track);
2372 ed->data = vcm->my_client_index;
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002373 /* *INDENT-ON* */
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -08002374 }
2375
Dave Wallace543852a2017-08-03 02:11:34 -04002376 vppcom_app_detach ();
Dave Wallacede910062018-03-20 09:22:13 -04002377 orig_app_timeout = vcm->cfg.app_timeout;
2378 vcm->cfg.app_timeout = 2.0;
Dave Wallace543852a2017-08-03 02:11:34 -04002379 rv = vppcom_wait_for_app_state_change (STATE_APP_ENABLED);
Dave Wallacede910062018-03-20 09:22:13 -04002380 vcm->cfg.app_timeout = orig_app_timeout;
Dave Wallace543852a2017-08-03 02:11:34 -04002381 if (PREDICT_FALSE (rv))
2382 {
2383 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002384 clib_warning ("VCL<%d>: application detach timed out! "
2385 "returning %d (%s)",
Dave Wallaceee45d412017-11-24 21:44:06 -05002386 getpid (), rv, vppcom_retval_str (rv));
Dave Wallace543852a2017-08-03 02:11:34 -04002387 }
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -08002388
2389 /* Finished with logging before client gets reset to ~0 */
2390 if (VPPCOM_DEBUG > 0)
2391 write_elog ();
2392
Dave Wallace543852a2017-08-03 02:11:34 -04002393 vl_client_disconnect_from_vlib ();
2394 vcm->my_client_index = ~0;
2395 vcm->app_state = STATE_APP_START;
2396}
2397
2398int
Dave Wallacec04cbf12018-02-07 18:14:02 -05002399vppcom_session_create (u8 proto, u8 is_nonblocking)
Dave Wallace543852a2017-08-03 02:11:34 -04002400{
Dave Wallace543852a2017-08-03 02:11:34 -04002401 session_t *session;
2402 u32 session_index;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002403 session_state_t state;
2404 elog_track_t session_elog_track;
Dave Wallace543852a2017-08-03 02:11:34 -04002405
2406 clib_spinlock_lock (&vcm->sessions_lockp);
2407 pool_get (vcm->sessions, session);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002408 memset (session, 0, sizeof (*session));
Dave Wallace543852a2017-08-03 02:11:34 -04002409 session_index = session - vcm->sessions;
2410
Dave Wallace543852a2017-08-03 02:11:34 -04002411 session->proto = proto;
2412 session->state = STATE_START;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002413 state = session->state;
Dave Wallace4878cbe2017-11-21 03:45:09 -05002414 session->vpp_handle = ~0;
Dave Wallace543852a2017-08-03 02:11:34 -04002415
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002416 if (is_nonblocking)
2417 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_NONBLOCK);
2418 else
2419 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_NONBLOCK);
Dave Wallace543852a2017-08-03 02:11:34 -04002420
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002421 if (VPPCOM_DEBUG > 0)
2422 {
2423 session->elog_track.name =
2424 (char *) format (0, "C:%d:S:%d%c", vcm->my_client_index,
2425 session_index, 0);
2426 elog_track_register (&vcm->elog_main, &session->elog_track);
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002427 session_elog_track = session->elog_track;
2428 }
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002429
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002430 clib_spinlock_unlock (&vcm->sessions_lockp);
2431
2432 if (VPPCOM_DEBUG > 0)
2433 clib_warning ("VCL<%d>: sid %u", getpid (), session_index);
2434
2435 if (VPPCOM_DEBUG > 0)
2436 {
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002437 /* *INDENT-OFF* */
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002438 ELOG_TYPE_DECLARE (e) =
2439 {
Dave Wallacec04cbf12018-02-07 18:14:02 -05002440 .format = "session_create:proto:%d state:%d is_nonblocking:%d",
2441 .format_args = "i4i4i4",
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002442 };
2443
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002444 struct
2445 {
Dave Wallacec04cbf12018-02-07 18:14:02 -05002446 u32 data[3];
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002447 } *ed;
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002448
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002449 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session_elog_track);
2450 ed->data[0] = proto;
2451 ed->data[1] = state;
2452 ed->data[2] = is_nonblocking;
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002453 /* *INDENT-ON* */
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002454 }
2455
Dave Wallace543852a2017-08-03 02:11:34 -04002456 return (int) session_index;
2457}
2458
2459int
2460vppcom_session_close (uint32_t session_index)
2461{
Dave Wallace543852a2017-08-03 02:11:34 -04002462 session_t *session = 0;
2463 int rv;
Dave Wallace66cf6eb2017-10-26 02:51:07 -04002464 u8 is_vep;
2465 u8 is_vep_session;
2466 u32 next_sid;
2467 u32 vep_idx;
Dave Wallaceee45d412017-11-24 21:44:06 -05002468 u64 vpp_handle;
Dave Wallace4878cbe2017-11-21 03:45:09 -05002469 uword *p;
Dave Wallace66cf6eb2017-10-26 02:51:07 -04002470 session_state_t state;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002471 elog_track_t session_elog_track;
Dave Wallace543852a2017-08-03 02:11:34 -04002472
Dave Wallace4878cbe2017-11-21 03:45:09 -05002473 VCL_LOCK_AND_GET_SESSION (session_index, &session);
Dave Wallace66cf6eb2017-10-26 02:51:07 -04002474 is_vep = session->is_vep;
2475 is_vep_session = session->is_vep_session;
2476 next_sid = session->vep.next_sid;
2477 vep_idx = session->vep.vep_idx;
2478 state = session->state;
Dave Wallaceee45d412017-11-24 21:44:06 -05002479 vpp_handle = session->vpp_handle;
Dave Wallace543852a2017-08-03 02:11:34 -04002480 clib_spinlock_unlock (&vcm->sessions_lockp);
2481
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002482 /*
2483 * Why two if(VPPCOM_DEBUG) checks?
2484 *
2485 * Eventually all clib_warnings need their own way of being
2486 * logged and signalled (like severity) where event logging
2487 * is a separate debugging tool. It will make the separation
2488 * easier. ... parting is such sweet sorrow ...
2489 */
2490 if (VPPCOM_DEBUG > 0)
2491 {
2492 session_elog_track = session->elog_track;
2493 }
2494
Dave Wallace543852a2017-08-03 02:11:34 -04002495 if (VPPCOM_DEBUG > 0)
Dave Wallaceee45d412017-11-24 21:44:06 -05002496 {
2497 if (is_vep)
Dave Wallace048b1d62018-01-03 22:24:41 -05002498 clib_warning ("VCL<%d>: vep_idx %u / sid %u: "
2499 "closing epoll session...",
Dave Wallaceee45d412017-11-24 21:44:06 -05002500 getpid (), session_index, session_index);
2501 else
Dave Wallace048b1d62018-01-03 22:24:41 -05002502 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %d: "
2503 "closing session...",
Dave Wallaceee45d412017-11-24 21:44:06 -05002504 getpid (), vpp_handle, session_index);
2505 }
Dave Wallace543852a2017-08-03 02:11:34 -04002506
Dave Wallace66cf6eb2017-10-26 02:51:07 -04002507 if (is_vep)
Dave Wallace543852a2017-08-03 02:11:34 -04002508 {
Dave Wallace66cf6eb2017-10-26 02:51:07 -04002509 while (next_sid != ~0)
Dave Wallace19481612017-09-15 18:47:44 -04002510 {
Dave Wallacef7f809c2017-10-03 01:48:42 -04002511 rv = vppcom_epoll_ctl (session_index, EPOLL_CTL_DEL, next_sid, 0);
Dave Wallaceee45d412017-11-24 21:44:06 -05002512 if ((VPPCOM_DEBUG > 0) && PREDICT_FALSE (rv < 0))
Dave Wallace048b1d62018-01-03 22:24:41 -05002513 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
2514 "EPOLL_CTL_DEL vep_idx %u failed! rv %d (%s)",
2515 getpid (), vpp_handle, next_sid, vep_idx,
Dave Wallace4878cbe2017-11-21 03:45:09 -05002516 rv, vppcom_retval_str (rv));
Dave Wallacef7f809c2017-10-03 01:48:42 -04002517
Dave Wallace4878cbe2017-11-21 03:45:09 -05002518 VCL_LOCK_AND_GET_SESSION (session_index, &session);
Dave Wallace66cf6eb2017-10-26 02:51:07 -04002519 next_sid = session->vep.next_sid;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002520 clib_spinlock_unlock (&vcm->sessions_lockp);
2521 }
2522 }
2523 else
2524 {
Dave Wallace66cf6eb2017-10-26 02:51:07 -04002525 if (is_vep_session)
Dave Wallacef7f809c2017-10-03 01:48:42 -04002526 {
Dave Wallacef7f809c2017-10-03 01:48:42 -04002527 rv = vppcom_epoll_ctl (vep_idx, EPOLL_CTL_DEL, session_index, 0);
2528 if ((VPPCOM_DEBUG > 0) && (rv < 0))
Dave Wallace048b1d62018-01-03 22:24:41 -05002529 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
2530 "EPOLL_CTL_DEL vep_idx %u failed! rv %d (%s)",
Dave Wallaceee45d412017-11-24 21:44:06 -05002531 getpid (), vpp_handle, session_index,
2532 vep_idx, rv, vppcom_retval_str (rv));
Dave Wallacef7f809c2017-10-03 01:48:42 -04002533 }
2534
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002535 if (state & STATE_LISTEN)
Dave Wallacef7f809c2017-10-03 01:48:42 -04002536 {
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002537 rv = vppcom_session_unbind (session_index);
2538 if (PREDICT_FALSE (rv < 0))
Dave Wallace4878cbe2017-11-21 03:45:09 -05002539 {
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002540 if (VPPCOM_DEBUG > 0)
2541 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
2542 "listener unbind failed! rv %d (%s)",
2543 getpid (), vpp_handle, session_index,
2544 rv, vppcom_retval_str (rv));
Dave Wallace4878cbe2017-11-21 03:45:09 -05002545 }
Dave Wallacef7f809c2017-10-03 01:48:42 -04002546 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05002547
2548 else if (state & (CLIENT_STATE_OPEN | SERVER_STATE_OPEN))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002549 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05002550 rv = vppcom_session_disconnect (session_index);
2551 if (PREDICT_FALSE (rv < 0))
Dave Wallace048b1d62018-01-03 22:24:41 -05002552 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -05002553 "session disconnect failed! rv %d (%s)",
2554 getpid (), vpp_handle, session_index,
2555 rv, vppcom_retval_str (rv));
Dave Wallacef7f809c2017-10-03 01:48:42 -04002556 }
Dave Wallace19481612017-09-15 18:47:44 -04002557 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05002558
2559 VCL_LOCK_AND_GET_SESSION (session_index, &session);
Dave Wallaceee45d412017-11-24 21:44:06 -05002560 vpp_handle = session->vpp_handle;
2561 if (vpp_handle != ~0)
Dave Wallace4878cbe2017-11-21 03:45:09 -05002562 {
Dave Wallaceee45d412017-11-24 21:44:06 -05002563 p = hash_get (vcm->session_index_by_vpp_handles, vpp_handle);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002564 if (p)
Dave Wallaceee45d412017-11-24 21:44:06 -05002565 hash_unset (vcm->session_index_by_vpp_handles, vpp_handle);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002566 }
Dave Wallace543852a2017-08-03 02:11:34 -04002567 pool_put_index (vcm->sessions, session_index);
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002568
Dave Wallace66cf6eb2017-10-26 02:51:07 -04002569 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002570
2571 if (VPPCOM_DEBUG > 0)
Dave Wallaceee45d412017-11-24 21:44:06 -05002572 {
2573 if (is_vep)
Dave Wallace048b1d62018-01-03 22:24:41 -05002574 clib_warning ("VCL<%d>: vep_idx %u / sid %u: epoll session removed.",
Dave Wallaceee45d412017-11-24 21:44:06 -05002575 getpid (), session_index, session_index);
2576 else
Dave Wallace048b1d62018-01-03 22:24:41 -05002577 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: session removed.",
Dave Wallaceee45d412017-11-24 21:44:06 -05002578 getpid (), vpp_handle, session_index);
2579 }
Dave Wallacef7f809c2017-10-03 01:48:42 -04002580done:
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002581
2582 if (VPPCOM_DEBUG > 0)
2583 {
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002584 /* *INDENT-OFF* */
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002585 ELOG_TYPE_DECLARE (e) =
2586 {
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002587 .format = "session_close:rv:%d",
2588 .format_args = "i4",
2589 };
2590
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002591 struct
2592 {
2593 u32 data;
2594 } *ed;
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002595
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002596 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session_elog_track);
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002597 ed->data = rv;
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002598 /* *INDENT-ON* */
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002599 }
2600
Dave Wallace543852a2017-08-03 02:11:34 -04002601 return rv;
2602}
2603
2604int
2605vppcom_session_bind (uint32_t session_index, vppcom_endpt_t * ep)
2606{
Dave Wallace543852a2017-08-03 02:11:34 -04002607 session_t *session = 0;
2608 int rv;
2609
2610 if (!ep || !ep->ip)
2611 return VPPCOM_EINVAL;
2612
Dave Wallace4878cbe2017-11-21 03:45:09 -05002613 VCL_LOCK_AND_GET_SESSION (session_index, &session);
Dave Wallace543852a2017-08-03 02:11:34 -04002614
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002615 if (session->is_vep)
2616 {
2617 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace048b1d62018-01-03 22:24:41 -05002618 clib_warning ("VCL<%d>: ERROR: sid %u: cannot "
2619 "bind to an epoll session!", getpid (), session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002620 rv = VPPCOM_EBADFD;
2621 goto done;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002622 }
2623
Dave Wallace35830af2017-10-09 01:43:42 -04002624 session->lcl_addr.is_ip4 = ep->is_ip4;
2625 session->lcl_addr.ip46 = to_ip46 (!ep->is_ip4, ep->ip);
Stevenac1f96d2017-10-24 16:03:58 -07002626 session->lcl_port = ep->port;
2627
2628 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002629 clib_warning ("VCL<%d>: sid %u: binding to local %s address %U "
Dave Wallaceee45d412017-11-24 21:44:06 -05002630 "port %u, proto %s", getpid (), session_index,
2631 session->lcl_addr.is_ip4 ? "IPv4" : "IPv6",
2632 format_ip46_address, &session->lcl_addr.ip46,
Dave Wallacede910062018-03-20 09:22:13 -04002633 session->lcl_addr.is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6,
Dave Wallace4878cbe2017-11-21 03:45:09 -05002634 clib_net_to_host_u16 (session->lcl_port),
2635 session->proto ? "UDP" : "TCP");
Dave Wallace543852a2017-08-03 02:11:34 -04002636
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002637 if (VPPCOM_DEBUG > 0)
2638 {
2639 if (session->lcl_addr.is_ip4)
2640 {
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002641 /* *INDENT-OFF* */
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002642 ELOG_TYPE_DECLARE (e) =
2643 {
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002644 .format = "bind local:%s:%d.%d.%d.%d:%d ",
2645 .format_args = "t1i1i1i1i1i2",
2646 .n_enum_strings = 2,
2647 .enum_strings = {"TCP", "UDP",},
2648 };
2649
2650 CLIB_PACKED (struct {
2651 u8 proto;
2652 u8 addr[4];
2653 u16 port;
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002654 }) *ed;
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002655
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002656 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
2657 ed->proto = session->proto;
2658 ed->addr[0] = session->lcl_addr.ip46.ip4.as_u8[0];
2659 ed->addr[1] = session->lcl_addr.ip46.ip4.as_u8[1];
2660 ed->addr[2] = session->lcl_addr.ip46.ip4.as_u8[2];
2661 ed->addr[3] = session->lcl_addr.ip46.ip4.as_u8[3];
2662 ed->port = clib_net_to_host_u16 (session->lcl_port);
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002663 /* *INDENT-ON* */
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002664 }
2665 }
2666
Dave Wallace543852a2017-08-03 02:11:34 -04002667 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002668done:
2669 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04002670}
2671
2672int
Dave Wallace33e002b2017-09-06 01:20:02 -04002673vppcom_session_listen (uint32_t listen_session_index, uint32_t q_len)
Dave Wallace543852a2017-08-03 02:11:34 -04002674{
Dave Wallace33e002b2017-09-06 01:20:02 -04002675 session_t *listen_session = 0;
Dave Wallaceee45d412017-11-24 21:44:06 -05002676 u64 listen_vpp_handle;
2677 int rv, retval;
Dave Wallace543852a2017-08-03 02:11:34 -04002678
Keith Burns (alagalah)aba98de2018-02-22 03:23:40 -08002679 if (q_len == 0 || q_len == ~0)
2680 q_len = vcm->cfg.listen_queue_size;
2681
Dave Wallace4878cbe2017-11-21 03:45:09 -05002682 VCL_LOCK_AND_GET_SESSION (listen_session_index, &listen_session);
Dave Wallace543852a2017-08-03 02:11:34 -04002683
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002684 if (listen_session->is_vep)
2685 {
2686 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace048b1d62018-01-03 22:24:41 -05002687 clib_warning ("VCL<%d>: ERROR: sid %u: cannot listen on an "
Dave Wallace4878cbe2017-11-21 03:45:09 -05002688 "epoll session!", getpid (), listen_session_index);
2689 rv = VPPCOM_EBADFD;
2690 goto done;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002691 }
2692
Dave Wallaceee45d412017-11-24 21:44:06 -05002693 listen_vpp_handle = listen_session->vpp_handle;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002694 if (listen_session->state & STATE_LISTEN)
Dave Wallacee695cb42017-11-02 22:04:42 -04002695 {
2696 clib_spinlock_unlock (&vcm->sessions_lockp);
2697 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002698 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -05002699 "already in listen state!",
2700 getpid (), listen_vpp_handle, listen_session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002701 rv = VPPCOM_OK;
2702 goto done;
Dave Wallacee695cb42017-11-02 22:04:42 -04002703 }
2704
Dave Wallace543852a2017-08-03 02:11:34 -04002705 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002706 clib_warning ("VCL<%d>: vpp handle 0x%llx, "
2707 "sid %u: sending bind request...",
Dave Wallaceee45d412017-11-24 21:44:06 -05002708 getpid (), listen_vpp_handle, listen_session_index);
Dave Wallace543852a2017-08-03 02:11:34 -04002709
Dave Wallace4878cbe2017-11-21 03:45:09 -05002710 vppcom_send_bind_sock (listen_session, listen_session_index);
Dave Wallace543852a2017-08-03 02:11:34 -04002711 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallaceee45d412017-11-24 21:44:06 -05002712 retval =
Dave Wallace33e002b2017-09-06 01:20:02 -04002713 vppcom_wait_for_session_state_change (listen_session_index, STATE_LISTEN,
2714 vcm->cfg.session_timeout);
Dave Wallace543852a2017-08-03 02:11:34 -04002715
Dave Wallace4878cbe2017-11-21 03:45:09 -05002716 VCL_LOCK_AND_GET_SESSION (listen_session_index, &listen_session);
Dave Wallaceee45d412017-11-24 21:44:06 -05002717 if (PREDICT_FALSE (retval))
2718 {
2719 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002720 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: bind failed! "
Dave Wallaceee45d412017-11-24 21:44:06 -05002721 "returning %d (%s)", getpid (),
2722 listen_session->vpp_handle, listen_session_index,
2723 retval, vppcom_retval_str (retval));
2724 clib_spinlock_unlock (&vcm->sessions_lockp);
2725 rv = retval;
2726 goto done;
2727 }
2728
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08002729 clib_spinlock_lock (&vcm->session_fifo_lockp);
Dave Wallace543852a2017-08-03 02:11:34 -04002730 clib_fifo_validate (vcm->client_session_index_fifo, q_len);
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08002731 clib_spinlock_unlock (&vcm->session_fifo_lockp);
2732
Dave Wallacef7f809c2017-10-03 01:48:42 -04002733 clib_spinlock_unlock (&vcm->sessions_lockp);
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08002734
Dave Wallace4878cbe2017-11-21 03:45:09 -05002735done:
2736 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04002737}
2738
2739int
Keith Burns (alagalah)0d2b0d52018-03-06 15:55:22 -08002740vppcom_session_register_listener (uint32_t session_index,
2741 vppcom_session_listener_cb cb,
2742 vppcom_session_listener_errcb
2743 errcb, uint8_t flags, int q_len, void *ptr)
2744{
2745 int rv = VPPCOM_OK;
2746 vce_event_key_t evk;
2747 vppcom_session_listener_t *listener_args;
2748
2749 rv = vppcom_session_listen (session_index, q_len);
2750 if (rv)
2751 {
2752 goto done;
2753 }
2754
2755
2756 /* Register handler for connect_request event on listen_session_index */
2757 listener_args = clib_mem_alloc (sizeof (vppcom_session_listener_t));
2758 listener_args->user_cb = cb;
2759 listener_args->user_cb_data = ptr;
2760 listener_args->user_errcb = errcb;
2761
2762 evk.session_index = session_index;
2763 evk.eid = VCL_EVENT_CONNECT_REQ_ACCEPTED;
2764 (void) vce_register_handler (&vcm->event_thread, &evk,
2765 vce_registered_listener_connect_handler_fn,
2766 listener_args);
2767
2768done:
2769 return rv;
2770}
2771
2772int
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002773validate_args_session_accept_ (session_t * listen_session)
2774{
2775 u32 listen_session_index = listen_session - vcm->sessions;
2776
2777 /* Input validation - expects spinlock on sessions_lockp */
2778 if (listen_session->is_vep)
2779 {
2780 clib_warning ("VCL<%d>: ERROR: sid %u: cannot accept on an "
2781 "epoll session!", getpid (), listen_session_index);
2782 return VPPCOM_EBADFD;
2783 }
2784
2785 if (listen_session->state != STATE_LISTEN)
2786 {
2787 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
2788 "not in listen state! state 0x%x (%s)", getpid (),
2789 listen_session->vpp_handle, listen_session_index,
2790 listen_session->state,
2791 vppcom_session_state_str (listen_session->state));
2792 return VPPCOM_EBADFD;
2793 }
2794 return VPPCOM_OK;
2795}
2796
2797int
Dave Wallace543852a2017-08-03 02:11:34 -04002798vppcom_session_accept (uint32_t listen_session_index, vppcom_endpt_t * ep,
Dave Wallace048b1d62018-01-03 22:24:41 -05002799 uint32_t flags)
Dave Wallace543852a2017-08-03 02:11:34 -04002800{
Dave Wallace33e002b2017-09-06 01:20:02 -04002801 session_t *listen_session = 0;
2802 session_t *client_session = 0;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002803 u32 client_session_index = ~0;
Dave Wallace543852a2017-08-03 02:11:34 -04002804 int rv;
Dave Wallaceee45d412017-11-24 21:44:06 -05002805 u64 listen_vpp_handle;
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002806 vce_event_handler_reg_t *reg;
2807 vce_event_t *ev;
2808 vce_event_connect_request_t *result;
2809 struct timespec ts;
2810 struct timeval tv;
2811 int millisecond_timeout = 1;
2812 int hours_timeout = 20 * 60 * 60;
Dave Wallace543852a2017-08-03 02:11:34 -04002813
Dave Wallace4878cbe2017-11-21 03:45:09 -05002814 VCL_LOCK_AND_GET_SESSION (listen_session_index, &listen_session);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002815 listen_vpp_handle = listen_session->vpp_handle; // For debugging
Dave Wallace543852a2017-08-03 02:11:34 -04002816
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002817 rv = validate_args_session_accept_ (listen_session);
2818 if (rv)
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002819 {
2820 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002821 goto done;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002822 }
2823
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002824 /* Using an aggressive timer of 1ms and a generous timer of
2825 * 20 hours, we can implement a blocking and non-blocking listener
2826 * as both event and time driven */
2827 gettimeofday (&tv, NULL);
2828 ts.tv_nsec = (tv.tv_usec * 1000) + (1000 * millisecond_timeout);
2829 ts.tv_sec = tv.tv_sec;
2830
2831 /* Predict that the Listener is blocking more often than not */
2832 if (PREDICT_TRUE (!VCL_SESS_ATTR_TEST (listen_session->attr,
2833 VCL_SESS_ATTR_NONBLOCK)))
2834 ts.tv_sec += hours_timeout;
Dave Wallace543852a2017-08-03 02:11:34 -04002835
Dave Wallace543852a2017-08-03 02:11:34 -04002836 clib_spinlock_unlock (&vcm->sessions_lockp);
2837
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002838 /* Register handler for connect_request event on listen_session_index */
2839 vce_event_key_t evk;
2840 evk.session_index = listen_session_index;
2841 evk.eid = VCL_EVENT_CONNECT_REQ_ACCEPTED;
2842 reg = vce_register_handler (&vcm->event_thread, &evk,
Keith Burns (alagalah)0d2b0d52018-03-06 15:55:22 -08002843 vce_connect_request_handler_fn, 0);
Keith Burns (alagalah)7cf80e02018-03-08 16:46:25 -08002844 ev = vce_get_event_from_index (&vcm->event_thread, reg->ev_idx);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002845 pthread_mutex_lock (&reg->handler_lock);
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08002846 while (!ev)
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002847 {
2848 rv =
2849 pthread_cond_timedwait (&reg->handler_cond, &reg->handler_lock, &ts);
2850 if (rv == ETIMEDOUT)
2851 {
2852 rv = VPPCOM_EAGAIN;
2853 goto cleanup;
2854 }
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08002855 ev = vce_get_event_from_index (&vcm->event_thread, reg->ev_idx);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002856 }
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08002857 result = (vce_event_connect_request_t *) ev->data;
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002858 client_session_index = result->accepted_session_index;
2859
2860
2861
2862 /* Remove from the FIFO used to service epoll */
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08002863 clib_spinlock_lock (&vcm->session_fifo_lockp);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002864 if (clib_fifo_elts (vcm->client_session_index_fifo))
2865 {
2866 u32 tmp_client_session_index;
2867 clib_fifo_sub1 (vcm->client_session_index_fifo,
2868 tmp_client_session_index);
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08002869 /* It wasn't ours... put it back ... */
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002870 if (tmp_client_session_index != client_session_index)
2871 clib_fifo_add1 (vcm->client_session_index_fifo,
2872 tmp_client_session_index);
2873 }
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08002874 clib_spinlock_unlock (&vcm->session_fifo_lockp);
2875
2876 clib_spinlock_lock (&vcm->sessions_lockp);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002877
Dave Wallace33e002b2017-09-06 01:20:02 -04002878 rv = vppcom_session_at_index (client_session_index, &client_session);
Dave Wallaceee45d412017-11-24 21:44:06 -05002879 if (PREDICT_FALSE (rv))
2880 {
2881 rv = VPPCOM_ECONNABORTED;
Dave Wallace048b1d62018-01-03 22:24:41 -05002882 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: client sid %u "
Dave Wallaceee45d412017-11-24 21:44:06 -05002883 "lookup failed! returning %d (%s)", getpid (),
2884 listen_vpp_handle, listen_session_index,
2885 client_session_index, rv, vppcom_retval_str (rv));
Dave Wallacee5356442018-03-19 10:38:00 -04002886 goto cleanup;
Dave Wallaceee45d412017-11-24 21:44:06 -05002887 }
Dave Wallace543852a2017-08-03 02:11:34 -04002888
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002889 if (flags & O_NONBLOCK)
2890 VCL_SESS_ATTR_SET (client_session->attr, VCL_SESS_ATTR_NONBLOCK);
2891 else
2892 VCL_SESS_ATTR_CLR (client_session->attr, VCL_SESS_ATTR_NONBLOCK);
2893
Dave Wallace543852a2017-08-03 02:11:34 -04002894 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002895 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: Got a client request! "
Dave Wallaceee45d412017-11-24 21:44:06 -05002896 "vpp handle 0x%llx, sid %u, flags %d, is_nonblocking %u",
2897 getpid (), listen_vpp_handle, listen_session_index,
2898 client_session->vpp_handle, client_session_index,
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002899 flags, VCL_SESS_ATTR_TEST (client_session->attr,
2900 VCL_SESS_ATTR_NONBLOCK));
Dave Wallace543852a2017-08-03 02:11:34 -04002901
Dave Wallace048b1d62018-01-03 22:24:41 -05002902 if (ep)
2903 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002904 ep->is_ip4 = client_session->peer_addr.is_ip4;
2905 ep->port = client_session->peer_port;
2906 if (client_session->peer_addr.is_ip4)
2907 clib_memcpy (ep->ip, &client_session->peer_addr.ip46.ip4,
2908 sizeof (ip4_address_t));
2909 else
2910 clib_memcpy (ep->ip, &client_session->peer_addr.ip46.ip6,
2911 sizeof (ip6_address_t));
2912 }
Dave Wallace60caa062017-11-10 17:07:13 -05002913
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002914 vppcom_send_accept_session_reply (client_session->vpp_handle,
2915 client_session->client_context,
2916 0 /* retval OK */ );
Dave Wallace60caa062017-11-10 17:07:13 -05002917
Stevenac1f96d2017-10-24 16:03:58 -07002918 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002919 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: accepted vpp handle "
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002920 "0x%llx, sid %u connection to local %s address "
Dave Wallaceee45d412017-11-24 21:44:06 -05002921 "%U port %u", getpid (), listen_vpp_handle,
2922 listen_session_index, client_session->vpp_handle,
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002923 client_session_index,
Dave Wallace4878cbe2017-11-21 03:45:09 -05002924 client_session->lcl_addr.is_ip4 ? "IPv4" : "IPv6",
2925 format_ip46_address, &client_session->lcl_addr.ip46,
Dave Wallacede910062018-03-20 09:22:13 -04002926 client_session->lcl_addr.is_ip4 ?
2927 IP46_TYPE_IP4 : IP46_TYPE_IP6,
Dave Wallace4878cbe2017-11-21 03:45:09 -05002928 clib_net_to_host_u16 (client_session->lcl_port));
Dave Wallace60caa062017-11-10 17:07:13 -05002929
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002930 if (VPPCOM_DEBUG > 0)
2931 {
2932 client_session->elog_track.name =
2933 (char *) format (0, "C:%d:S:%d%c", vcm->my_client_index,
2934 client_session_index, 0);
2935 elog_track_register (&vcm->elog_main, &client_session->elog_track);
2936
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002937 // Two elog entries due to 20-byte per entry constraint.
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002938 /* *INDENT-OFF* */
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002939 ELOG_TYPE_DECLARE (e) =
2940 {
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002941 .format = "accept: listen_handle:%x from_handle:%x",
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002942 .format_args = "i8i8",
2943 };
2944
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002945 struct
2946 {
2947 u64 handle[2];
2948 } *ed;
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002949
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002950 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, client_session->elog_track);
2951 ed->handle[0] = listen_vpp_handle;
2952 ed->handle[1] = client_session->vpp_handle;
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002953 /* *INDENT-ON* */
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002954
2955 if (client_session->lcl_addr.is_ip4)
2956 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08002957 /* *INDENT-OFF* */
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002958 ELOG_TYPE_DECLARE (e2) =
2959 {
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002960 .format = "accept: S:%d %d.%d.%d.%d:%d ",
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002961 .format_args = "i4i1i1i1i1i2",
2962 };
2963
2964 CLIB_PACKED (struct {
2965 u32 session;
2966 u8 addr[4];
2967 u16 port;
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002968 }) *ed2;
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002969
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002970 ed2 =
2971 ELOG_TRACK_DATA (&vcm->elog_main, e2, client_session->elog_track);
2972 ed2->session = client_session_index;
2973 ed2->addr[0] = client_session->lcl_addr.ip46.ip4.as_u8[0];
2974 ed2->addr[1] = client_session->lcl_addr.ip46.ip4.as_u8[1];
2975 ed2->addr[2] = client_session->lcl_addr.ip46.ip4.as_u8[2];
2976 ed2->addr[3] = client_session->lcl_addr.ip46.ip4.as_u8[3];
2977 ed2->port = clib_net_to_host_u16 (client_session->lcl_port);
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002978 /* *INDENT-ON* */
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002979 }
2980 }
2981
Dave Wallace543852a2017-08-03 02:11:34 -04002982 clib_spinlock_unlock (&vcm->sessions_lockp);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002983
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08002984 rv = (int) client_session_index;
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002985 vce_clear_event (&vcm->event_thread, ev);
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08002986
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002987cleanup:
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08002988 vce_unregister_handler (&vcm->event_thread, reg);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002989 pthread_mutex_unlock (&reg->handler_lock);
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08002990
Dave Wallace4878cbe2017-11-21 03:45:09 -05002991done:
2992 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04002993}
2994
2995int
2996vppcom_session_connect (uint32_t session_index, vppcom_endpt_t * server_ep)
2997{
Dave Wallace543852a2017-08-03 02:11:34 -04002998 session_t *session = 0;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002999 u64 vpp_handle = 0;
Dave Wallaceee45d412017-11-24 21:44:06 -05003000 int rv, retval = VPPCOM_OK;
Dave Wallace543852a2017-08-03 02:11:34 -04003001
Dave Wallace4878cbe2017-11-21 03:45:09 -05003002 VCL_LOCK_AND_GET_SESSION (session_index, &session);
3003
3004 if (PREDICT_FALSE (session->is_vep))
Dave Wallace543852a2017-08-03 02:11:34 -04003005 {
3006 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace048b1d62018-01-03 22:24:41 -05003007 clib_warning ("VCL<%d>: ERROR: sid %u: cannot "
3008 "connect on an epoll session!", getpid (), session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -05003009 rv = VPPCOM_EBADFD;
3010 goto done;
Dave Wallace543852a2017-08-03 02:11:34 -04003011 }
3012
Dave Wallace4878cbe2017-11-21 03:45:09 -05003013 if (PREDICT_FALSE (session->state & CLIENT_STATE_OPEN))
Dave Wallace543852a2017-08-03 02:11:34 -04003014 {
Dave Wallace543852a2017-08-03 02:11:34 -04003015 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05003016 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: session already "
Dave Wallaceee45d412017-11-24 21:44:06 -05003017 "connected to %s %U port %d proto %s, state 0x%x (%s)",
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003018 getpid (), session->vpp_handle, session_index,
Dave Wallace4878cbe2017-11-21 03:45:09 -05003019 session->peer_addr.is_ip4 ? "IPv4" : "IPv6",
3020 format_ip46_address,
Dave Wallacede910062018-03-20 09:22:13 -04003021 &session->peer_addr.ip46, session->peer_addr.is_ip4 ?
3022 IP46_TYPE_IP4 : IP46_TYPE_IP6,
Dave Wallace4878cbe2017-11-21 03:45:09 -05003023 clib_net_to_host_u16 (session->peer_port),
3024 session->proto ? "UDP" : "TCP", session->state,
3025 vppcom_session_state_str (session->state));
3026
3027 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace4878cbe2017-11-21 03:45:09 -05003028 goto done;
Dave Wallace543852a2017-08-03 02:11:34 -04003029 }
3030
Dave Wallace35830af2017-10-09 01:43:42 -04003031 session->peer_addr.is_ip4 = server_ep->is_ip4;
3032 session->peer_addr.ip46 = to_ip46 (!server_ep->is_ip4, server_ep->ip);
Stevenac1f96d2017-10-24 16:03:58 -07003033 session->peer_port = server_ep->port;
Dave Wallace543852a2017-08-03 02:11:34 -04003034
3035 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05003036 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: connecting to server "
Dave Wallaceee45d412017-11-24 21:44:06 -05003037 "%s %U port %d proto %s",
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003038 getpid (), session->vpp_handle, session_index,
Dave Wallace4878cbe2017-11-21 03:45:09 -05003039 session->peer_addr.is_ip4 ? "IPv4" : "IPv6",
3040 format_ip46_address,
Dave Wallacede910062018-03-20 09:22:13 -04003041 &session->peer_addr.ip46, session->peer_addr.is_ip4 ?
3042 IP46_TYPE_IP4 : IP46_TYPE_IP6,
Dave Wallace4878cbe2017-11-21 03:45:09 -05003043 clib_net_to_host_u16 (session->peer_port),
3044 session->proto ? "UDP" : "TCP");
Dave Wallace543852a2017-08-03 02:11:34 -04003045
3046 vppcom_send_connect_sock (session, session_index);
3047 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace4878cbe2017-11-21 03:45:09 -05003048
Dave Wallaceee45d412017-11-24 21:44:06 -05003049 retval =
3050 vppcom_wait_for_session_state_change (session_index, STATE_CONNECT,
3051 vcm->cfg.session_timeout);
3052
3053 VCL_LOCK_AND_GET_SESSION (session_index, &session);
3054 vpp_handle = session->vpp_handle;
3055 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace7876d392017-10-19 03:53:57 -04003056
Dave Wallace4878cbe2017-11-21 03:45:09 -05003057done:
Dave Wallaceee45d412017-11-24 21:44:06 -05003058 if (PREDICT_FALSE (retval))
3059 {
3060 rv = retval;
3061 if (VPPCOM_DEBUG > 0)
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003062 {
3063 if (session)
3064 clib_warning
3065 ("VCL<%d>: vpp handle 0x%llx, sid %u: connect failed! "
3066 "returning %d (%s)", getpid (), vpp_handle,
3067 session_index, rv, vppcom_retval_str (rv));
3068 else
3069 clib_warning ("VCL<%d>: no session for sid %u: connect failed! "
3070 "returning %d (%s)", getpid (),
3071 session_index, rv, vppcom_retval_str (rv));
3072 }
Dave Wallaceee45d412017-11-24 21:44:06 -05003073 }
3074 else if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05003075 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: connected!",
Dave Wallaceee45d412017-11-24 21:44:06 -05003076 getpid (), vpp_handle, session_index);
3077
Dave Wallace4878cbe2017-11-21 03:45:09 -05003078 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04003079}
3080
Steven58f464e2017-10-25 12:33:12 -07003081static inline int
3082vppcom_session_read_internal (uint32_t session_index, void *buf, int n,
3083 u8 peek)
Dave Wallace543852a2017-08-03 02:11:34 -04003084{
Dave Wallace543852a2017-08-03 02:11:34 -04003085 session_t *session = 0;
3086 svm_fifo_t *rx_fifo;
3087 int n_read = 0;
3088 int rv;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003089 int is_nonblocking;
3090
3091 u64 vpp_handle;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003092 u32 poll_et;
Dave Wallace4878cbe2017-11-21 03:45:09 -05003093 session_state_t state;
Dave Wallace543852a2017-08-03 02:11:34 -04003094
3095 ASSERT (buf);
3096
Dave Wallace4878cbe2017-11-21 03:45:09 -05003097 VCL_LOCK_AND_GET_SESSION (session_index, &session);
3098
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003099 is_nonblocking = VCL_SESS_ATTR_TEST (session->attr, VCL_SESS_ATTR_NONBLOCK);
3100 rx_fifo = session->rx_fifo;
3101 state = session->state;
3102 vpp_handle = session->vpp_handle;
3103
Dave Wallace4878cbe2017-11-21 03:45:09 -05003104 if (PREDICT_FALSE (session->is_vep))
Dave Wallace543852a2017-08-03 02:11:34 -04003105 {
3106 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace048b1d62018-01-03 22:24:41 -05003107 clib_warning ("VCL<%d>: ERROR: sid %u: cannot "
3108 "read from an epoll session!", getpid (), session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -05003109 rv = VPPCOM_EBADFD;
3110 goto done;
Dave Wallace543852a2017-08-03 02:11:34 -04003111 }
3112
Dave Wallace4878cbe2017-11-21 03:45:09 -05003113 if (PREDICT_FALSE (!(state & (SERVER_STATE_OPEN | CLIENT_STATE_OPEN))))
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003114 {
3115 clib_spinlock_unlock (&vcm->sessions_lockp);
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08003116 rv = ((state & STATE_DISCONNECT) ? VPPCOM_ECONNRESET : VPPCOM_ENOTCONN);
Dave Wallace4878cbe2017-11-21 03:45:09 -05003117
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003118 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05003119 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: %s session is "
Dave Wallaceee45d412017-11-24 21:44:06 -05003120 "not open! state 0x%x (%s), returning %d (%s)",
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003121 getpid (), vpp_handle, session_index, state,
Dave Wallace4878cbe2017-11-21 03:45:09 -05003122 vppcom_session_state_str (state),
3123 rv, vppcom_retval_str (rv));
3124 goto done;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003125 }
3126
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003127 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003128
3129 do
3130 {
Steven58f464e2017-10-25 12:33:12 -07003131 if (peek)
3132 n_read = svm_fifo_peek (rx_fifo, 0, n, buf);
3133 else
3134 n_read = svm_fifo_dequeue_nowait (rx_fifo, n, buf);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003135 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05003136 while (!is_nonblocking && (n_read <= 0));
Dave Wallacef7f809c2017-10-03 01:48:42 -04003137
Dave Wallace4878cbe2017-11-21 03:45:09 -05003138 if (n_read <= 0)
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003139 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05003140 VCL_LOCK_AND_GET_SESSION (session_index, &session);
3141
3142 poll_et = (((EPOLLET | EPOLLIN) & session->vep.ev.events) ==
3143 (EPOLLET | EPOLLIN));
3144 if (poll_et)
3145 session->vep.et_mask |= EPOLLIN;
3146
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08003147 if (state & STATE_CLOSE_ON_EMPTY)
Dave Wallace4878cbe2017-11-21 03:45:09 -05003148 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05003149 rv = VPPCOM_ECONNRESET;
3150
3151 if (VPPCOM_DEBUG > 1)
3152 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003153 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: Empty fifo "
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003154 "with session state 0x%x (%s)!"
Dave Wallaceee45d412017-11-24 21:44:06 -05003155 " Setting state to 0x%x (%s), returning %d (%s)",
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003156 getpid (), session->vpp_handle, session_index,
Dave Wallace4878cbe2017-11-21 03:45:09 -05003157 state, vppcom_session_state_str (state),
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003158 STATE_DISCONNECT,
3159 vppcom_session_state_str (STATE_DISCONNECT), rv,
3160 vppcom_retval_str (rv));
Dave Wallace4878cbe2017-11-21 03:45:09 -05003161 }
3162
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003163 session->state = STATE_DISCONNECT;
Dave Wallace4878cbe2017-11-21 03:45:09 -05003164 }
3165 else
3166 rv = VPPCOM_EAGAIN;
3167
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003168 clib_spinlock_unlock (&vcm->sessions_lockp);
3169 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05003170 else
3171 rv = n_read;
Dave Wallace543852a2017-08-03 02:11:34 -04003172
Dave Wallace4878cbe2017-11-21 03:45:09 -05003173 if (VPPCOM_DEBUG > 2)
3174 {
3175 if (rv > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05003176 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: read %d bytes "
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003177 "from (%p)", getpid (), vpp_handle,
3178 session_index, n_read, rx_fifo);
Dave Wallace4878cbe2017-11-21 03:45:09 -05003179 else
Dave Wallace048b1d62018-01-03 22:24:41 -05003180 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: nothing read! "
Dave Wallaceee45d412017-11-24 21:44:06 -05003181 "returning %d (%s)", getpid (), vpp_handle,
3182 session_index, rv, vppcom_retval_str (rv));
Dave Wallace4878cbe2017-11-21 03:45:09 -05003183 }
3184done:
3185 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04003186}
3187
Steven58f464e2017-10-25 12:33:12 -07003188int
Dave Wallace048b1d62018-01-03 22:24:41 -05003189vppcom_session_read (uint32_t session_index, void *buf, size_t n)
Steven58f464e2017-10-25 12:33:12 -07003190{
3191 return (vppcom_session_read_internal (session_index, buf, n, 0));
3192}
3193
3194static int
3195vppcom_session_peek (uint32_t session_index, void *buf, int n)
3196{
3197 return (vppcom_session_read_internal (session_index, buf, n, 1));
3198}
3199
Dave Wallace543852a2017-08-03 02:11:34 -04003200static inline int
3201vppcom_session_read_ready (session_t * session, u32 session_index)
3202{
Dave Wallace543852a2017-08-03 02:11:34 -04003203 int ready = 0;
Dave Wallace60caa062017-11-10 17:07:13 -05003204 u32 poll_et;
Dave Wallace4878cbe2017-11-21 03:45:09 -05003205 int rv;
Dave Wallace4878cbe2017-11-21 03:45:09 -05003206 session_state_t state = session->state;
Dave Wallaceee45d412017-11-24 21:44:06 -05003207 u64 vpp_handle = session->vpp_handle;
Dave Wallace543852a2017-08-03 02:11:34 -04003208
3209 /* Assumes caller has acquired spinlock: vcm->sessions_lockp */
Dave Wallace4878cbe2017-11-21 03:45:09 -05003210 if (PREDICT_FALSE (session->is_vep))
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003211 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003212 clib_warning ("VCL<%d>: ERROR: sid %u: cannot read from an "
Dave Wallace4878cbe2017-11-21 03:45:09 -05003213 "epoll session!", getpid (), session_index);
3214 rv = VPPCOM_EBADFD;
3215 goto done;
Dave Wallace543852a2017-08-03 02:11:34 -04003216 }
Dave Wallace33e002b2017-09-06 01:20:02 -04003217
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003218 if (session->state & STATE_LISTEN)
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08003219 {
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08003220 clib_spinlock_lock (&vcm->session_fifo_lockp);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08003221 ready = clib_fifo_elts (vcm->client_session_index_fifo);
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08003222 clib_spinlock_unlock (&vcm->session_fifo_lockp);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08003223 }
Dave Wallace543852a2017-08-03 02:11:34 -04003224 else
3225 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05003226 if (!(state & (SERVER_STATE_OPEN | CLIENT_STATE_OPEN | STATE_LISTEN)))
3227 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08003228 rv = ((state & STATE_DISCONNECT) ? VPPCOM_ECONNRESET :
Dave Wallace4878cbe2017-11-21 03:45:09 -05003229 VPPCOM_ENOTCONN);
3230
3231 if (VPPCOM_DEBUG > 1)
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003232 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: session is "
Dave Wallaceee45d412017-11-24 21:44:06 -05003233 "not open! state 0x%x (%s), returning %d (%s)",
3234 getpid (), vpp_handle, session_index,
Dave Wallace4878cbe2017-11-21 03:45:09 -05003235 state, vppcom_session_state_str (state),
3236 rv, vppcom_retval_str (rv));
3237 goto done;
3238 }
3239
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003240 ready = svm_fifo_max_dequeue (session->rx_fifo);
Dave Wallace543852a2017-08-03 02:11:34 -04003241 }
3242
Dave Wallace4878cbe2017-11-21 03:45:09 -05003243 if (ready == 0)
Dave Wallace60caa062017-11-10 17:07:13 -05003244 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05003245 poll_et =
3246 ((EPOLLET | EPOLLIN) & session->vep.ev.events) == (EPOLLET | EPOLLIN);
3247 if (poll_et)
3248 session->vep.et_mask |= EPOLLIN;
Dave Wallace60caa062017-11-10 17:07:13 -05003249
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08003250 if (state & STATE_CLOSE_ON_EMPTY)
Dave Wallace4878cbe2017-11-21 03:45:09 -05003251 {
3252 rv = VPPCOM_ECONNRESET;
Dave Wallace4878cbe2017-11-21 03:45:09 -05003253
3254 if (VPPCOM_DEBUG > 1)
3255 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003256 clib_warning ("VCL<%d>: vpp handle 0x%llx, "
3257 "sid %u: Empty fifo with"
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003258 " session state 0x%x (%s)! Setting state to "
Dave Wallaceee45d412017-11-24 21:44:06 -05003259 "0x%x (%s), returning %d (%s)",
3260 getpid (), session_index, vpp_handle,
Dave Wallace4878cbe2017-11-21 03:45:09 -05003261 state, vppcom_session_state_str (state),
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003262 STATE_DISCONNECT,
3263 vppcom_session_state_str (STATE_DISCONNECT), rv,
3264 vppcom_retval_str (rv));
Dave Wallace4878cbe2017-11-21 03:45:09 -05003265 }
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003266 session->state = STATE_DISCONNECT;
Dave Wallace4878cbe2017-11-21 03:45:09 -05003267 goto done;
3268 }
3269 }
3270 rv = ready;
Dave Wallace16cb4082017-11-29 03:24:06 -05003271
3272 if (vcm->app_event_queue->cursize &&
3273 !pthread_mutex_trylock (&vcm->app_event_queue->mutex))
3274 {
3275 u32 i, n_to_dequeue = vcm->app_event_queue->cursize;
3276 session_fifo_event_t e;
3277
3278 for (i = 0; i < n_to_dequeue; i++)
Florin Corase86a8ed2018-01-05 03:20:25 -08003279 svm_queue_sub_raw (vcm->app_event_queue, (u8 *) & e);
Dave Wallace16cb4082017-11-29 03:24:06 -05003280
3281 pthread_mutex_unlock (&vcm->app_event_queue->mutex);
3282 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05003283done:
3284 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04003285}
3286
3287int
Dave Wallace048b1d62018-01-03 22:24:41 -05003288vppcom_session_write (uint32_t session_index, void *buf, size_t n)
Dave Wallace543852a2017-08-03 02:11:34 -04003289{
Dave Wallace543852a2017-08-03 02:11:34 -04003290 session_t *session = 0;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003291 svm_fifo_t *tx_fifo = 0;
Florin Corase86a8ed2018-01-05 03:20:25 -08003292 svm_queue_t *q;
Dave Wallace543852a2017-08-03 02:11:34 -04003293 session_fifo_event_t evt;
Dave Wallace4878cbe2017-11-21 03:45:09 -05003294 session_state_t state;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003295 int rv, n_write, is_nonblocking;
3296 u32 poll_et;
Dave Wallaceee45d412017-11-24 21:44:06 -05003297 u64 vpp_handle;
Dave Wallace543852a2017-08-03 02:11:34 -04003298
3299 ASSERT (buf);
3300
Dave Wallace4878cbe2017-11-21 03:45:09 -05003301 VCL_LOCK_AND_GET_SESSION (session_index, &session);
3302
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003303 tx_fifo = session->tx_fifo;
3304 is_nonblocking = VCL_SESS_ATTR_TEST (session->attr, VCL_SESS_ATTR_NONBLOCK);
3305 vpp_handle = session->vpp_handle;
3306 state = session->state;
3307
Dave Wallace4878cbe2017-11-21 03:45:09 -05003308 if (PREDICT_FALSE (session->is_vep))
Dave Wallace543852a2017-08-03 02:11:34 -04003309 {
3310 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace048b1d62018-01-03 22:24:41 -05003311 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -05003312 "cannot write to an epoll session!",
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003313 getpid (), vpp_handle, session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -05003314
3315 rv = VPPCOM_EBADFD;
3316 goto done;
Dave Wallace543852a2017-08-03 02:11:34 -04003317 }
3318
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003319 if (!(session->state & (SERVER_STATE_OPEN | CLIENT_STATE_OPEN)))
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003320 {
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003321 rv =
3322 ((session->state & STATE_DISCONNECT) ? VPPCOM_ECONNRESET :
3323 VPPCOM_ENOTCONN);
Dave Wallace4878cbe2017-11-21 03:45:09 -05003324
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003325 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace4878cbe2017-11-21 03:45:09 -05003326 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05003327 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003328 "session is not open! state 0x%x (%s)",
Dave Wallaceee45d412017-11-24 21:44:06 -05003329 getpid (), vpp_handle, session_index,
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003330 state, vppcom_session_state_str (state));
Dave Wallace4878cbe2017-11-21 03:45:09 -05003331 goto done;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003332 }
3333
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003334 clib_spinlock_unlock (&vcm->sessions_lockp);
3335
Dave Wallace543852a2017-08-03 02:11:34 -04003336 do
3337 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003338 n_write = svm_fifo_enqueue_nowait (tx_fifo, n, (void *) buf);
Dave Wallace543852a2017-08-03 02:11:34 -04003339 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05003340 while (!is_nonblocking && (n_write <= 0));
Dave Wallace543852a2017-08-03 02:11:34 -04003341
3342 /* If event wasn't set, add one */
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003343 if ((n_write > 0) && svm_fifo_set_event (tx_fifo))
Dave Wallace543852a2017-08-03 02:11:34 -04003344 {
Dave Wallace543852a2017-08-03 02:11:34 -04003345 /* Fabricate TX event, send to vpp */
3346 evt.fifo = tx_fifo;
3347 evt.event_type = FIFO_EVENT_APP_TX;
Dave Wallace543852a2017-08-03 02:11:34 -04003348
Dave Wallace4878cbe2017-11-21 03:45:09 -05003349 VCL_LOCK_AND_GET_SESSION (session_index, &session);
3350 q = session->vpp_event_queue;
Dave Wallace543852a2017-08-03 02:11:34 -04003351 ASSERT (q);
Florin Corase86a8ed2018-01-05 03:20:25 -08003352 svm_queue_add (q, (u8 *) & evt, 0 /* do wait for mutex */ );
Dave Wallace4878cbe2017-11-21 03:45:09 -05003353 clib_spinlock_unlock (&vcm->sessions_lockp);
3354 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05003355 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -05003356 "added FIFO_EVENT_APP_TX to "
Dave Wallace4878cbe2017-11-21 03:45:09 -05003357 "vpp_event_q %p, n_write %d", getpid (),
Dave Wallaceee45d412017-11-24 21:44:06 -05003358 vpp_handle, session_index, q, n_write);
Dave Wallace543852a2017-08-03 02:11:34 -04003359 }
3360
Dave Wallace4878cbe2017-11-21 03:45:09 -05003361 if (n_write <= 0)
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003362 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05003363 VCL_LOCK_AND_GET_SESSION (session_index, &session);
3364
3365 poll_et = (((EPOLLET | EPOLLOUT) & session->vep.ev.events) ==
3366 (EPOLLET | EPOLLOUT));
3367 if (poll_et)
3368 session->vep.et_mask |= EPOLLOUT;
3369
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003370 if (session->state & STATE_CLOSE_ON_EMPTY)
Dave Wallace4878cbe2017-11-21 03:45:09 -05003371 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05003372 rv = VPPCOM_ECONNRESET;
3373
3374 if (VPPCOM_DEBUG > 1)
3375 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003376 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003377 "Empty fifo with session state 0x%x (%s)!"
Dave Wallaceee45d412017-11-24 21:44:06 -05003378 " Setting state to 0x%x (%s), returning %d (%s)",
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003379 getpid (), session->vpp_handle, session_index,
3380 session->state,
3381 vppcom_session_state_str (session->state),
3382 STATE_DISCONNECT,
3383 vppcom_session_state_str (STATE_DISCONNECT), rv,
3384 vppcom_retval_str (rv));
Dave Wallace4878cbe2017-11-21 03:45:09 -05003385 }
3386
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003387 session->state = STATE_DISCONNECT;
Dave Wallace4878cbe2017-11-21 03:45:09 -05003388 }
3389 else
3390 rv = VPPCOM_EAGAIN;
3391
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003392 clib_spinlock_unlock (&vcm->sessions_lockp);
3393 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05003394 else
3395 rv = n_write;
Dave Wallacef7f809c2017-10-03 01:48:42 -04003396
Dave Wallace543852a2017-08-03 02:11:34 -04003397 if (VPPCOM_DEBUG > 2)
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003398 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05003399 if (n_write <= 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05003400 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003401 "FIFO-FULL (%p)", getpid (), vpp_handle,
3402 session_index, tx_fifo);
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003403 else
Dave Wallace048b1d62018-01-03 22:24:41 -05003404 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003405 "wrote %d bytes tx-fifo: (%p)", getpid (),
3406 vpp_handle, session_index, n_write, tx_fifo);
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003407 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05003408done:
3409 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04003410}
3411
3412static inline int
3413vppcom_session_write_ready (session_t * session, u32 session_index)
3414{
Dave Wallacef7f809c2017-10-03 01:48:42 -04003415 int ready;
Dave Wallace60caa062017-11-10 17:07:13 -05003416 u32 poll_et;
Dave Wallace4878cbe2017-11-21 03:45:09 -05003417 int rv;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003418
3419 ASSERT (session);
Dave Wallace543852a2017-08-03 02:11:34 -04003420
3421 /* Assumes caller has acquired spinlock: vcm->sessions_lockp */
Dave Wallace4878cbe2017-11-21 03:45:09 -05003422 if (PREDICT_FALSE (session->is_vep))
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003423 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003424 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -05003425 "cannot write to an epoll session!",
3426 getpid (), session->vpp_handle, session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -05003427 rv = VPPCOM_EBADFD;
3428 goto done;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003429 }
3430
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003431 if (PREDICT_FALSE (session->state & STATE_LISTEN))
Dave Wallace33e002b2017-09-06 01:20:02 -04003432 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003433 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -05003434 "cannot write to a listen session!",
3435 getpid (), session->vpp_handle, session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -05003436 rv = VPPCOM_EBADFD;
3437 goto done;
3438 }
3439
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003440 if (!(session->state & (SERVER_STATE_OPEN | CLIENT_STATE_OPEN)))
Dave Wallace4878cbe2017-11-21 03:45:09 -05003441 {
3442 session_state_t state = session->state;
3443
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08003444 rv = ((state & STATE_DISCONNECT) ? VPPCOM_ECONNRESET : VPPCOM_ENOTCONN);
Dave Wallace4878cbe2017-11-21 03:45:09 -05003445
Dave Wallace048b1d62018-01-03 22:24:41 -05003446 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003447 "session is not open! state 0x%x (%s), "
Dave Wallaceee45d412017-11-24 21:44:06 -05003448 "returning %d (%s)", getpid (), session->vpp_handle,
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003449 session_index,
Dave Wallace4878cbe2017-11-21 03:45:09 -05003450 state, vppcom_session_state_str (state),
3451 rv, vppcom_retval_str (rv));
3452 goto done;
Dave Wallace33e002b2017-09-06 01:20:02 -04003453 }
3454
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003455 ready = svm_fifo_max_enqueue (session->tx_fifo);
Dave Wallace543852a2017-08-03 02:11:34 -04003456
Dave Wallace33e002b2017-09-06 01:20:02 -04003457 if (VPPCOM_DEBUG > 3)
Dave Wallace048b1d62018-01-03 22:24:41 -05003458 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -05003459 "peek %s (%p), ready = %d", getpid (),
3460 session->vpp_handle, session_index,
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003461 session->tx_fifo, ready);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003462
Dave Wallace4878cbe2017-11-21 03:45:09 -05003463 if (ready == 0)
3464 {
3465 poll_et = (((EPOLLET | EPOLLOUT) & session->vep.ev.events) ==
3466 (EPOLLET | EPOLLOUT));
3467 if (poll_et)
3468 session->vep.et_mask |= EPOLLOUT;
3469
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003470 if (session->state & STATE_CLOSE_ON_EMPTY)
Dave Wallace4878cbe2017-11-21 03:45:09 -05003471 {
3472 rv = VPPCOM_ECONNRESET;
Dave Wallace4878cbe2017-11-21 03:45:09 -05003473
3474 if (VPPCOM_DEBUG > 1)
3475 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003476 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003477 "Empty fifo with session "
Dave Wallaceee45d412017-11-24 21:44:06 -05003478 "state 0x%x (%s)! Setting state to 0x%x (%s), "
3479 "returning %d (%s)", getpid (),
3480 session->vpp_handle, session_index,
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003481 session->state,
3482 vppcom_session_state_str (session->state),
3483 STATE_DISCONNECT,
3484 vppcom_session_state_str (STATE_DISCONNECT), rv,
3485 vppcom_retval_str (rv));
Dave Wallace4878cbe2017-11-21 03:45:09 -05003486 }
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003487 session->state = STATE_DISCONNECT;
Dave Wallace4878cbe2017-11-21 03:45:09 -05003488 goto done;
3489 }
3490 }
3491 rv = ready;
3492done:
3493 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04003494}
3495
3496int
3497vppcom_select (unsigned long n_bits, unsigned long *read_map,
3498 unsigned long *write_map, unsigned long *except_map,
3499 double time_to_wait)
3500{
Dave Wallace543852a2017-08-03 02:11:34 -04003501 u32 session_index;
3502 session_t *session = 0;
3503 int rv, bits_set = 0;
3504 f64 timeout = clib_time_now (&vcm->clib_time) + time_to_wait;
3505 u32 minbits = clib_max (n_bits, BITS (uword));
3506
3507 ASSERT (sizeof (clib_bitmap_t) == sizeof (long int));
3508
Dave Wallace7876d392017-10-19 03:53:57 -04003509 if (n_bits && read_map)
Dave Wallace543852a2017-08-03 02:11:34 -04003510 {
3511 clib_bitmap_validate (vcm->rd_bitmap, minbits);
Dave Wallace048b1d62018-01-03 22:24:41 -05003512 clib_memcpy (vcm->rd_bitmap, read_map,
3513 vec_len (vcm->rd_bitmap) * sizeof (clib_bitmap_t));
3514 memset (read_map, 0, vec_len (vcm->rd_bitmap) * sizeof (clib_bitmap_t));
Dave Wallace543852a2017-08-03 02:11:34 -04003515 }
Dave Wallace7876d392017-10-19 03:53:57 -04003516 if (n_bits && write_map)
Dave Wallace543852a2017-08-03 02:11:34 -04003517 {
3518 clib_bitmap_validate (vcm->wr_bitmap, minbits);
Dave Wallace048b1d62018-01-03 22:24:41 -05003519 clib_memcpy (vcm->wr_bitmap, write_map,
3520 vec_len (vcm->wr_bitmap) * sizeof (clib_bitmap_t));
3521 memset (write_map, 0,
3522 vec_len (vcm->wr_bitmap) * sizeof (clib_bitmap_t));
Dave Wallace543852a2017-08-03 02:11:34 -04003523 }
Dave Wallace7876d392017-10-19 03:53:57 -04003524 if (n_bits && except_map)
Dave Wallace543852a2017-08-03 02:11:34 -04003525 {
3526 clib_bitmap_validate (vcm->ex_bitmap, minbits);
Dave Wallace048b1d62018-01-03 22:24:41 -05003527 clib_memcpy (vcm->ex_bitmap, except_map,
3528 vec_len (vcm->ex_bitmap) * sizeof (clib_bitmap_t));
3529 memset (except_map, 0,
3530 vec_len (vcm->ex_bitmap) * sizeof (clib_bitmap_t));
Dave Wallace543852a2017-08-03 02:11:34 -04003531 }
3532
3533 do
3534 {
3535 /* *INDENT-OFF* */
Dave Wallacee22aa742017-10-20 12:30:38 -04003536 if (n_bits)
3537 {
3538 if (read_map)
Dave Wallace543852a2017-08-03 02:11:34 -04003539 {
Dave Wallacee22aa742017-10-20 12:30:38 -04003540 clib_bitmap_foreach (session_index, vcm->rd_bitmap,
3541 ({
3542 clib_spinlock_lock (&vcm->sessions_lockp);
3543 rv = vppcom_session_at_index (session_index, &session);
3544 if (rv < 0)
3545 {
3546 clib_spinlock_unlock (&vcm->sessions_lockp);
3547 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05003548 clib_warning ("VCL<%d>: session %d specified in "
Dave Wallace2e005bb2017-11-07 01:21:39 -05003549 "read_map is closed.", getpid (),
Dave Wallacee22aa742017-10-20 12:30:38 -04003550 session_index);
3551 bits_set = VPPCOM_EBADFD;
3552 goto select_done;
3553 }
Dave Wallace8d73e852018-03-08 16:39:28 -05003554 if (session->state & STATE_LISTEN)
3555 {
3556 vce_event_handler_reg_t *reg = 0;
3557 vce_event_key_t evk;
Dave Wallacee22aa742017-10-20 12:30:38 -04003558
Dave Wallace8d73e852018-03-08 16:39:28 -05003559 /* Check if handler already registered for this
3560 * event.
3561 * If not, register handler for connect_request event
3562 * on listen_session_index
3563 */
3564 evk.session_index = session_index;
3565 evk.eid = VCL_EVENT_CONNECT_REQ_ACCEPTED;
3566 reg = vce_get_event_handler (&vcm->event_thread, &evk);
3567 if (!reg)
3568 reg = vce_register_handler (&vcm->event_thread, &evk,
Keith Burns (alagalah)0d2b0d52018-03-06 15:55:22 -08003569 vce_poll_wait_connect_request_handler_fn,
3570 0 /* No callback args */);
Dave Wallace8d73e852018-03-08 16:39:28 -05003571 rv = vppcom_session_read_ready (session, session_index);
3572 if (rv > 0)
3573 {
3574 vce_unregister_handler (&vcm->event_thread, reg);
3575 }
3576 }
3577 else
3578 rv = vppcom_session_read_ready (session, session_index);
Dave Wallacee22aa742017-10-20 12:30:38 -04003579 clib_spinlock_unlock (&vcm->sessions_lockp);
3580 if (except_map && vcm->ex_bitmap &&
3581 clib_bitmap_get (vcm->ex_bitmap, session_index) &&
3582 (rv < 0))
3583 {
Dave Wallacee22aa742017-10-20 12:30:38 -04003584 clib_bitmap_set_no_check (except_map, session_index, 1);
3585 bits_set++;
3586 }
3587 else if (rv > 0)
3588 {
Dave Wallacee22aa742017-10-20 12:30:38 -04003589 clib_bitmap_set_no_check (read_map, session_index, 1);
3590 bits_set++;
3591 }
3592 }));
Dave Wallace543852a2017-08-03 02:11:34 -04003593 }
3594
Dave Wallacee22aa742017-10-20 12:30:38 -04003595 if (write_map)
Dave Wallace543852a2017-08-03 02:11:34 -04003596 {
Dave Wallacee22aa742017-10-20 12:30:38 -04003597 clib_bitmap_foreach (session_index, vcm->wr_bitmap,
3598 ({
3599 clib_spinlock_lock (&vcm->sessions_lockp);
3600 rv = vppcom_session_at_index (session_index, &session);
3601 if (rv < 0)
3602 {
3603 clib_spinlock_unlock (&vcm->sessions_lockp);
3604 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05003605 clib_warning ("VCL<%d>: session %d specified in "
Dave Wallace2e005bb2017-11-07 01:21:39 -05003606 "write_map is closed.", getpid (),
Dave Wallacee22aa742017-10-20 12:30:38 -04003607 session_index);
3608 bits_set = VPPCOM_EBADFD;
3609 goto select_done;
3610 }
Dave Wallace543852a2017-08-03 02:11:34 -04003611
Dave Wallacee22aa742017-10-20 12:30:38 -04003612 rv = vppcom_session_write_ready (session, session_index);
3613 clib_spinlock_unlock (&vcm->sessions_lockp);
3614 if (write_map && (rv > 0))
3615 {
Dave Wallacee22aa742017-10-20 12:30:38 -04003616 clib_bitmap_set_no_check (write_map, session_index, 1);
3617 bits_set++;
3618 }
3619 }));
Dave Wallace543852a2017-08-03 02:11:34 -04003620 }
3621
Dave Wallacee22aa742017-10-20 12:30:38 -04003622 if (except_map)
Dave Wallace543852a2017-08-03 02:11:34 -04003623 {
Dave Wallacee22aa742017-10-20 12:30:38 -04003624 clib_bitmap_foreach (session_index, vcm->ex_bitmap,
3625 ({
3626 clib_spinlock_lock (&vcm->sessions_lockp);
3627 rv = vppcom_session_at_index (session_index, &session);
3628 if (rv < 0)
3629 {
3630 clib_spinlock_unlock (&vcm->sessions_lockp);
3631 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05003632 clib_warning ("VCL<%d>: session %d specified in "
Dave Wallace2e005bb2017-11-07 01:21:39 -05003633 "except_map is closed.", getpid (),
Dave Wallacee22aa742017-10-20 12:30:38 -04003634 session_index);
3635 bits_set = VPPCOM_EBADFD;
3636 goto select_done;
3637 }
Dave Wallace543852a2017-08-03 02:11:34 -04003638
Dave Wallacee22aa742017-10-20 12:30:38 -04003639 rv = vppcom_session_read_ready (session, session_index);
3640 clib_spinlock_unlock (&vcm->sessions_lockp);
3641 if (rv < 0)
3642 {
Dave Wallacee22aa742017-10-20 12:30:38 -04003643 clib_bitmap_set_no_check (except_map, session_index, 1);
3644 bits_set++;
3645 }
3646 }));
Dave Wallace543852a2017-08-03 02:11:34 -04003647 }
Dave Wallacee22aa742017-10-20 12:30:38 -04003648 }
Dave Wallace543852a2017-08-03 02:11:34 -04003649 /* *INDENT-ON* */
3650 }
Dave Wallace048b1d62018-01-03 22:24:41 -05003651 while ((time_to_wait == -1) || (clib_time_now (&vcm->clib_time) < timeout));
Dave Wallace543852a2017-08-03 02:11:34 -04003652
3653select_done:
3654 return (bits_set);
3655}
3656
Dave Wallacef7f809c2017-10-03 01:48:42 -04003657static inline void
3658vep_verify_epoll_chain (u32 vep_idx)
3659{
3660 session_t *session;
3661 vppcom_epoll_t *vep;
3662 int rv;
Dave Wallace498b3a52017-11-09 13:00:34 -05003663 u32 sid = vep_idx;
Dave Wallacef7f809c2017-10-03 01:48:42 -04003664
Dave Wallace498b3a52017-11-09 13:00:34 -05003665 if (VPPCOM_DEBUG <= 1)
Dave Wallacef7f809c2017-10-03 01:48:42 -04003666 return;
3667
3668 /* Assumes caller has acquired spinlock: vcm->sessions_lockp */
3669 rv = vppcom_session_at_index (vep_idx, &session);
3670 if (PREDICT_FALSE (rv))
3671 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003672 clib_warning ("VCL<%d>: ERROR: Invalid vep_idx (%u)!",
3673 getpid (), vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003674 goto done;
3675 }
3676 if (PREDICT_FALSE (!session->is_vep))
3677 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003678 clib_warning ("VCL<%d>: ERROR: vep_idx (%u) is not a vep!",
3679 getpid (), vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003680 goto done;
3681 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05003682 vep = &session->vep;
Dave Wallace048b1d62018-01-03 22:24:41 -05003683 clib_warning ("VCL<%d>: vep_idx (%u): Dumping epoll chain\n"
Dave Wallace498b3a52017-11-09 13:00:34 -05003684 "{\n"
3685 " is_vep = %u\n"
3686 " is_vep_session = %u\n"
Dave Wallace4878cbe2017-11-21 03:45:09 -05003687 " next_sid = 0x%x (%u)\n"
Dave Wallace498b3a52017-11-09 13:00:34 -05003688 " wait_cont_idx = 0x%x (%u)\n"
Dave Wallace4878cbe2017-11-21 03:45:09 -05003689 "}\n", getpid (), vep_idx,
3690 session->is_vep, session->is_vep_session,
3691 vep->next_sid, vep->next_sid,
Dave Wallace498b3a52017-11-09 13:00:34 -05003692 session->wait_cont_idx, session->wait_cont_idx);
Dave Wallace4878cbe2017-11-21 03:45:09 -05003693
3694 for (sid = vep->next_sid; sid != ~0; sid = vep->next_sid)
Dave Wallacef7f809c2017-10-03 01:48:42 -04003695 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05003696 rv = vppcom_session_at_index (sid, &session);
3697 if (PREDICT_FALSE (rv))
Dave Wallacef7f809c2017-10-03 01:48:42 -04003698 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003699 clib_warning ("VCL<%d>: ERROR: Invalid sid (%u)!", getpid (), sid);
Dave Wallace4878cbe2017-11-21 03:45:09 -05003700 goto done;
3701 }
3702 if (PREDICT_FALSE (session->is_vep))
Dave Wallace048b1d62018-01-03 22:24:41 -05003703 clib_warning ("VCL<%d>: ERROR: sid (%u) is a vep!",
3704 getpid (), vep_idx);
Dave Wallace4878cbe2017-11-21 03:45:09 -05003705 else if (PREDICT_FALSE (!session->is_vep_session))
3706 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003707 clib_warning ("VCL<%d>: ERROR: session (%u) "
3708 "is not a vep session!", getpid (), sid);
Dave Wallace4878cbe2017-11-21 03:45:09 -05003709 goto done;
3710 }
3711 vep = &session->vep;
3712 if (PREDICT_FALSE (vep->vep_idx != vep_idx))
Dave Wallace048b1d62018-01-03 22:24:41 -05003713 clib_warning ("VCL<%d>: ERROR: session (%u) vep_idx (%u) != "
Dave Wallace4878cbe2017-11-21 03:45:09 -05003714 "vep_idx (%u)!", getpid (),
3715 sid, session->vep.vep_idx, vep_idx);
3716 if (session->is_vep_session)
3717 {
3718 clib_warning ("vep_idx[%u]: sid 0x%x (%u)\n"
3719 "{\n"
3720 " next_sid = 0x%x (%u)\n"
3721 " prev_sid = 0x%x (%u)\n"
3722 " vep_idx = 0x%x (%u)\n"
3723 " ev.events = 0x%x\n"
3724 " ev.data.u64 = 0x%llx\n"
3725 " et_mask = 0x%x\n"
3726 "}\n",
3727 vep_idx, sid, sid,
3728 vep->next_sid, vep->next_sid,
3729 vep->prev_sid, vep->prev_sid,
3730 vep->vep_idx, vep->vep_idx,
3731 vep->ev.events, vep->ev.data.u64, vep->et_mask);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003732 }
3733 }
Dave Wallacef7f809c2017-10-03 01:48:42 -04003734
3735done:
Dave Wallace048b1d62018-01-03 22:24:41 -05003736 clib_warning ("VCL<%d>: vep_idx (%u): Dump complete!\n",
3737 getpid (), vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003738}
3739
3740int
3741vppcom_epoll_create (void)
3742{
Dave Wallacef7f809c2017-10-03 01:48:42 -04003743 session_t *vep_session;
3744 u32 vep_idx;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003745 elog_track_t vep_elog_track;
Dave Wallacef7f809c2017-10-03 01:48:42 -04003746
3747 clib_spinlock_lock (&vcm->sessions_lockp);
3748 pool_get (vcm->sessions, vep_session);
3749 memset (vep_session, 0, sizeof (*vep_session));
3750 vep_idx = vep_session - vcm->sessions;
3751
3752 vep_session->is_vep = 1;
3753 vep_session->vep.vep_idx = ~0;
3754 vep_session->vep.next_sid = ~0;
3755 vep_session->vep.prev_sid = ~0;
3756 vep_session->wait_cont_idx = ~0;
Dave Wallace4878cbe2017-11-21 03:45:09 -05003757 vep_session->vpp_handle = ~0;
Keith Burns (alagalah)12756512018-03-06 05:55:27 -08003758 vep_session->poll_reg = 0;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003759
3760 if (VPPCOM_DEBUG > 0)
3761 {
3762 vep_session->elog_track.name =
3763 (char *) format (0, "C:%d:VEP:%d%c", vcm->my_client_index,
3764 vep_idx, 0);
3765 elog_track_register (&vcm->elog_main, &vep_session->elog_track);
3766 vep_elog_track = vep_session->elog_track;
3767 }
3768
Dave Wallacef7f809c2017-10-03 01:48:42 -04003769 clib_spinlock_unlock (&vcm->sessions_lockp);
3770
3771 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05003772 clib_warning ("VCL<%d>: Created vep_idx %u / sid %u!",
Dave Wallaceee45d412017-11-24 21:44:06 -05003773 getpid (), vep_idx, vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003774
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08003775 if (VPPCOM_DEBUG > 0)
3776 {
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08003777
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08003778 /* *INDENT-OFF* */
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08003779 ELOG_TYPE_DECLARE (e) =
3780 {
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08003781 .format = "created epoll session:%d",
3782 .format_args = "i4",
3783 };
3784
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08003785 struct
3786 {
3787 u32 data;
3788 } *ed;
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08003789
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003790 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, vep_elog_track);
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08003791 ed->data = vep_idx;
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08003792 /* *INDENT-ON* */
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08003793 }
3794
Dave Wallacef7f809c2017-10-03 01:48:42 -04003795 return (vep_idx);
3796}
3797
3798int
3799vppcom_epoll_ctl (uint32_t vep_idx, int op, uint32_t session_index,
3800 struct epoll_event *event)
3801{
Dave Wallacef7f809c2017-10-03 01:48:42 -04003802 session_t *vep_session;
3803 session_t *session;
3804 int rv;
3805
3806 if (vep_idx == session_index)
3807 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003808 clib_warning ("VCL<%d>: ERROR: vep_idx == session_index (%u)!",
Dave Wallace4878cbe2017-11-21 03:45:09 -05003809 getpid (), vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003810 return VPPCOM_EINVAL;
3811 }
3812
3813 clib_spinlock_lock (&vcm->sessions_lockp);
3814 rv = vppcom_session_at_index (vep_idx, &vep_session);
3815 if (PREDICT_FALSE (rv))
3816 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003817 clib_warning ("VCL<%d>: ERROR: Invalid vep_idx (%u)!", vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003818 goto done;
3819 }
3820 if (PREDICT_FALSE (!vep_session->is_vep))
3821 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003822 clib_warning ("VCL<%d>: ERROR: vep_idx (%u) is not a vep!",
Dave Wallace4878cbe2017-11-21 03:45:09 -05003823 getpid (), vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003824 rv = VPPCOM_EINVAL;
3825 goto done;
3826 }
3827
3828 ASSERT (vep_session->vep.vep_idx == ~0);
3829 ASSERT (vep_session->vep.prev_sid == ~0);
3830
3831 rv = vppcom_session_at_index (session_index, &session);
3832 if (PREDICT_FALSE (rv))
3833 {
3834 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05003835 clib_warning ("VCL<%d>: ERROR: Invalid session_index (%u)!",
Dave Wallace2e005bb2017-11-07 01:21:39 -05003836 getpid (), session_index);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003837 goto done;
3838 }
3839 if (PREDICT_FALSE (session->is_vep))
3840 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05003841 clib_warning ("ERROR: session_index (%u) is a vep!", vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003842 rv = VPPCOM_EINVAL;
3843 goto done;
3844 }
3845
3846 switch (op)
3847 {
3848 case EPOLL_CTL_ADD:
3849 if (PREDICT_FALSE (!event))
3850 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003851 clib_warning ("VCL<%d>: ERROR: EPOLL_CTL_ADD: NULL pointer to "
Dave Wallace2e005bb2017-11-07 01:21:39 -05003852 "epoll_event structure!", getpid ());
Dave Wallacef7f809c2017-10-03 01:48:42 -04003853 rv = VPPCOM_EINVAL;
3854 goto done;
3855 }
3856 if (vep_session->vep.next_sid != ~0)
3857 {
3858 session_t *next_session;
3859 rv = vppcom_session_at_index (vep_session->vep.next_sid,
3860 &next_session);
3861 if (PREDICT_FALSE (rv))
3862 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003863 clib_warning ("VCL<%d>: ERROR: EPOLL_CTL_ADD: Invalid "
Dave Wallace4878cbe2017-11-21 03:45:09 -05003864 "vep.next_sid (%u) on vep_idx (%u)!",
3865 getpid (), vep_session->vep.next_sid, vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003866 goto done;
3867 }
3868 ASSERT (next_session->vep.prev_sid == vep_idx);
3869 next_session->vep.prev_sid = session_index;
3870 }
3871 session->vep.next_sid = vep_session->vep.next_sid;
3872 session->vep.prev_sid = vep_idx;
3873 session->vep.vep_idx = vep_idx;
3874 session->vep.et_mask = VEP_DEFAULT_ET_MASK;
3875 session->vep.ev = *event;
Dave Wallace4878cbe2017-11-21 03:45:09 -05003876 session->is_vep = 0;
Dave Wallacef7f809c2017-10-03 01:48:42 -04003877 session->is_vep_session = 1;
3878 vep_session->vep.next_sid = session_index;
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08003879
3880 /* VCL Event Register handler */
3881 if (session->state & STATE_LISTEN)
3882 {
3883 /* Register handler for connect_request event on listen_session_index */
3884 vce_event_key_t evk;
3885 evk.session_index = session_index;
3886 evk.eid = VCL_EVENT_CONNECT_REQ_ACCEPTED;
Keith Burns (alagalah)12756512018-03-06 05:55:27 -08003887 vep_session->poll_reg =
3888 vce_register_handler (&vcm->event_thread, &evk,
Keith Burns (alagalah)0d2b0d52018-03-06 15:55:22 -08003889 vce_poll_wait_connect_request_handler_fn,
3890 0 /* No callback args */ );
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08003891 }
Dave Wallacef7f809c2017-10-03 01:48:42 -04003892 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05003893 clib_warning ("VCL<%d>: EPOLL_CTL_ADD: vep_idx %u, "
3894 "sid %u, events 0x%x, data 0x%llx!",
3895 getpid (), vep_idx, session_index,
Dave Wallacef7f809c2017-10-03 01:48:42 -04003896 event->events, event->data.u64);
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08003897 if (VPPCOM_DEBUG > 0)
3898 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08003899 /* *INDENT-OFF* */
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08003900 ELOG_TYPE_DECLARE (e) =
3901 {
3902 .format = "epoll_ctladd: events:%x data:%x",
3903 .format_args = "i4i4i8",
3904 };
3905 struct
3906 {
3907 u32 events;
3908 u64 event_data;
3909 } *ed;
3910
3911 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
3912
3913 ed->events = event->events;
3914 ed->event_data = event->data.u64;
3915 /* *INDENT-ON* */
3916 }
Dave Wallacef7f809c2017-10-03 01:48:42 -04003917 break;
3918
3919 case EPOLL_CTL_MOD:
3920 if (PREDICT_FALSE (!event))
3921 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003922 clib_warning ("VCL<%d>: ERROR: EPOLL_CTL_MOD: NULL pointer to "
Dave Wallace2e005bb2017-11-07 01:21:39 -05003923 "epoll_event structure!", getpid ());
Dave Wallacef7f809c2017-10-03 01:48:42 -04003924 rv = VPPCOM_EINVAL;
3925 goto done;
3926 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05003927 else if (PREDICT_FALSE (!session->is_vep_session))
Dave Wallacef7f809c2017-10-03 01:48:42 -04003928 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003929 clib_warning ("VCL<%d>: ERROR: sid %u EPOLL_CTL_MOD: "
Dave Wallace4878cbe2017-11-21 03:45:09 -05003930 "not a vep session!", getpid (), session_index);
3931 rv = VPPCOM_EINVAL;
3932 goto done;
3933 }
3934 else if (PREDICT_FALSE (session->vep.vep_idx != vep_idx))
3935 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003936 clib_warning ("VCL<%d>: ERROR: sid %u EPOLL_CTL_MOD: "
Dave Wallace4878cbe2017-11-21 03:45:09 -05003937 "vep_idx (%u) != vep_idx (%u)!",
3938 getpid (), session_index,
3939 session->vep.vep_idx, vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003940 rv = VPPCOM_EINVAL;
3941 goto done;
3942 }
3943 session->vep.et_mask = VEP_DEFAULT_ET_MASK;
3944 session->vep.ev = *event;
3945 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05003946 clib_warning
3947 ("VCL<%d>: EPOLL_CTL_MOD: vep_idx %u, sid %u, events 0x%x,"
3948 " data 0x%llx!", getpid (), vep_idx, session_index, event->events,
3949 event->data.u64);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003950 break;
3951
3952 case EPOLL_CTL_DEL:
Dave Wallace4878cbe2017-11-21 03:45:09 -05003953 if (PREDICT_FALSE (!session->is_vep_session))
Dave Wallacef7f809c2017-10-03 01:48:42 -04003954 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003955 clib_warning ("VCL<%d>: ERROR: sid %u EPOLL_CTL_DEL: "
Dave Wallace4878cbe2017-11-21 03:45:09 -05003956 "not a vep session!", getpid (), session_index);
3957 rv = VPPCOM_EINVAL;
3958 goto done;
3959 }
3960 else if (PREDICT_FALSE (session->vep.vep_idx != vep_idx))
3961 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003962 clib_warning ("VCL<%d>: ERROR: sid %u EPOLL_CTL_DEL: "
Dave Wallace4878cbe2017-11-21 03:45:09 -05003963 "vep_idx (%u) != vep_idx (%u)!",
3964 getpid (), session_index,
3965 session->vep.vep_idx, vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003966 rv = VPPCOM_EINVAL;
3967 goto done;
3968 }
3969
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08003970 /* VCL Event Un-register handler */
Keith Burns (alagalah)12756512018-03-06 05:55:27 -08003971 if ((session->state & STATE_LISTEN) && vep_session->poll_reg)
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08003972 {
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08003973 (void) vce_unregister_handler (&vcm->event_thread,
3974 vep_session->poll_reg);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08003975 }
3976
Dave Wallacef7f809c2017-10-03 01:48:42 -04003977 vep_session->wait_cont_idx =
3978 (vep_session->wait_cont_idx == session_index) ?
3979 session->vep.next_sid : vep_session->wait_cont_idx;
3980
3981 if (session->vep.prev_sid == vep_idx)
3982 vep_session->vep.next_sid = session->vep.next_sid;
3983 else
3984 {
3985 session_t *prev_session;
3986 rv = vppcom_session_at_index (session->vep.prev_sid, &prev_session);
3987 if (PREDICT_FALSE (rv))
3988 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003989 clib_warning ("VCL<%d>: ERROR: EPOLL_CTL_DEL: Invalid "
Dave Wallace4878cbe2017-11-21 03:45:09 -05003990 "vep.prev_sid (%u) on sid (%u)!",
3991 getpid (), session->vep.prev_sid, session_index);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003992 goto done;
3993 }
3994 ASSERT (prev_session->vep.next_sid == session_index);
3995 prev_session->vep.next_sid = session->vep.next_sid;
3996 }
3997 if (session->vep.next_sid != ~0)
3998 {
3999 session_t *next_session;
4000 rv = vppcom_session_at_index (session->vep.next_sid, &next_session);
4001 if (PREDICT_FALSE (rv))
4002 {
Dave Wallace048b1d62018-01-03 22:24:41 -05004003 clib_warning ("VCL<%d>: ERROR: EPOLL_CTL_DEL: Invalid "
Dave Wallace4878cbe2017-11-21 03:45:09 -05004004 "vep.next_sid (%u) on sid (%u)!",
4005 getpid (), session->vep.next_sid, session_index);
Dave Wallacef7f809c2017-10-03 01:48:42 -04004006 goto done;
4007 }
4008 ASSERT (next_session->vep.prev_sid == session_index);
4009 next_session->vep.prev_sid = session->vep.prev_sid;
4010 }
4011
4012 memset (&session->vep, 0, sizeof (session->vep));
4013 session->vep.next_sid = ~0;
4014 session->vep.prev_sid = ~0;
4015 session->vep.vep_idx = ~0;
4016 session->is_vep_session = 0;
4017 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05004018 clib_warning ("VCL<%d>: EPOLL_CTL_DEL: vep_idx %u, sid %u!",
Dave Wallace2e005bb2017-11-07 01:21:39 -05004019 getpid (), vep_idx, session_index);
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004020 if (VPPCOM_DEBUG > 0)
4021 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08004022 /* *INDENT-OFF* */
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004023 ELOG_TYPE_DECLARE (e) =
4024 {
4025 .format = "epoll_ctldel: vep:%d",
4026 .format_args = "i4",
4027 };
4028 struct
4029 {
4030 u32 data;
4031 } *ed;
4032
4033 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4034
4035 ed->data = vep_idx;
4036 /* *INDENT-ON* */
4037 }
Dave Wallacef7f809c2017-10-03 01:48:42 -04004038 break;
4039
4040 default:
Dave Wallace048b1d62018-01-03 22:24:41 -05004041 clib_warning ("VCL<%d>: ERROR: Invalid operation (%d)!", getpid (), op);
Dave Wallacef7f809c2017-10-03 01:48:42 -04004042 rv = VPPCOM_EINVAL;
4043 }
4044
4045 vep_verify_epoll_chain (vep_idx);
4046
4047done:
4048 clib_spinlock_unlock (&vcm->sessions_lockp);
4049 return rv;
4050}
4051
Dave Wallacef7f809c2017-10-03 01:48:42 -04004052int
4053vppcom_epoll_wait (uint32_t vep_idx, struct epoll_event *events,
4054 int maxevents, double wait_for_time)
4055{
Dave Wallacef7f809c2017-10-03 01:48:42 -04004056 session_t *vep_session;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08004057 elog_track_t vep_elog_track;
Dave Wallacef7f809c2017-10-03 01:48:42 -04004058 int rv;
4059 f64 timeout = clib_time_now (&vcm->clib_time) + wait_for_time;
Dave Wallace2e005bb2017-11-07 01:21:39 -05004060 u32 keep_trying = 1;
Dave Wallacef7f809c2017-10-03 01:48:42 -04004061 int num_ev = 0;
4062 u32 vep_next_sid, wait_cont_idx;
4063 u8 is_vep;
4064
4065 if (PREDICT_FALSE (maxevents <= 0))
4066 {
Dave Wallace048b1d62018-01-03 22:24:41 -05004067 clib_warning ("VCL<%d>: ERROR: Invalid maxevents (%d)!",
Dave Wallace4878cbe2017-11-21 03:45:09 -05004068 getpid (), maxevents);
Dave Wallacef7f809c2017-10-03 01:48:42 -04004069 return VPPCOM_EINVAL;
4070 }
Dave Wallacef7f809c2017-10-03 01:48:42 -04004071 memset (events, 0, sizeof (*events) * maxevents);
4072
4073 VCL_LOCK_AND_GET_SESSION (vep_idx, &vep_session);
4074 vep_next_sid = vep_session->vep.next_sid;
4075 is_vep = vep_session->is_vep;
4076 wait_cont_idx = vep_session->wait_cont_idx;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08004077 vep_elog_track = vep_session->elog_track;
Dave Wallacef7f809c2017-10-03 01:48:42 -04004078 clib_spinlock_unlock (&vcm->sessions_lockp);
4079
4080 if (PREDICT_FALSE (!is_vep))
4081 {
Dave Wallace048b1d62018-01-03 22:24:41 -05004082 clib_warning ("VCL<%d>: ERROR: vep_idx (%u) is not a vep!",
Dave Wallace4878cbe2017-11-21 03:45:09 -05004083 getpid (), vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04004084 rv = VPPCOM_EINVAL;
4085 goto done;
4086 }
Dave Wallacee695cb42017-11-02 22:04:42 -04004087 if (PREDICT_FALSE (vep_next_sid == ~0))
Dave Wallacef7f809c2017-10-03 01:48:42 -04004088 {
Dave Wallace69d01192018-02-22 16:22:09 -05004089 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05004090 clib_warning ("VCL<%d>: WARNING: vep_idx (%u) is empty!",
Dave Wallace2e005bb2017-11-07 01:21:39 -05004091 getpid (), vep_idx);
Dave Wallace69d01192018-02-22 16:22:09 -05004092 if (VPPCOM_DEBUG > 1)
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004093 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08004094 /* *INDENT-OFF* */
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004095 ELOG_TYPE_DECLARE (e) =
4096 {
4097 .format = "WRN: vep_idx:%d empty",
4098 .format_args = "i4",
4099 };
4100 struct
4101 {
4102 u32 data;
4103 } *ed;
4104
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08004105 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, vep_elog_track);
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004106
4107 ed->data = vep_idx;
4108 /* *INDENT-ON* */
4109 }
Dave Wallacef7f809c2017-10-03 01:48:42 -04004110 goto done;
4111 }
4112
4113 do
4114 {
4115 u32 sid;
4116 u32 next_sid = ~0;
4117 session_t *session;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08004118 elog_track_t session_elog_track;
Dave Wallacef7f809c2017-10-03 01:48:42 -04004119
4120 for (sid = (wait_cont_idx == ~0) ? vep_next_sid : wait_cont_idx;
4121 sid != ~0; sid = next_sid)
4122 {
4123 u32 session_events, et_mask, clear_et_mask, session_vep_idx;
4124 u8 add_event, is_vep_session;
4125 int ready;
4126 u64 session_ev_data;
4127
4128 VCL_LOCK_AND_GET_SESSION (sid, &session);
4129 next_sid = session->vep.next_sid;
4130 session_events = session->vep.ev.events;
4131 et_mask = session->vep.et_mask;
4132 is_vep = session->is_vep;
4133 is_vep_session = session->is_vep_session;
4134 session_vep_idx = session->vep.vep_idx;
4135 session_ev_data = session->vep.ev.data.u64;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08004136
4137 if (VPPCOM_DEBUG > 0)
4138 {
4139 session_elog_track = session->elog_track;
4140 }
4141
Dave Wallacef7f809c2017-10-03 01:48:42 -04004142 clib_spinlock_unlock (&vcm->sessions_lockp);
4143
4144 if (PREDICT_FALSE (is_vep))
4145 {
4146 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05004147 clib_warning ("VCL<%d>: ERROR: sid (%u) is a vep!",
Dave Wallace2e005bb2017-11-07 01:21:39 -05004148 getpid (), vep_idx);
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004149 if (VPPCOM_DEBUG > 0)
4150 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08004151 /* *INDENT-OFF* */
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004152 ELOG_TYPE_DECLARE (e) =
4153 {
4154 .format = "ERR:vep_idx:%d is vep",
4155 .format_args = "i4",
4156 };
4157 struct
4158 {
4159 u32 data;
4160 } *ed;
4161
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08004162 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session_elog_track);
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004163
4164 ed->data = vep_idx;
4165 /* *INDENT-ON* */
4166 }
4167
Dave Wallacef7f809c2017-10-03 01:48:42 -04004168 rv = VPPCOM_EINVAL;
4169 goto done;
4170 }
4171 if (PREDICT_FALSE (!is_vep_session))
4172 {
4173 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05004174 clib_warning ("VCL<%d>: ERROR: session (%u) is not "
Dave Wallace2e005bb2017-11-07 01:21:39 -05004175 "a vep session!", getpid (), sid);
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004176 if (VPPCOM_DEBUG > 0)
4177 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08004178 /* *INDENT-OFF* */
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004179 ELOG_TYPE_DECLARE (e) =
4180 {
4181 .format = "ERR:SID:%d not vep",
4182 .format_args = "i4",
4183 };
4184 struct
4185 {
4186 u32 data;
4187 } *ed;
4188
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08004189 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session_elog_track);
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004190
4191 ed->data = sid;
4192 /* *INDENT-ON* */
4193 }
4194
Dave Wallacef7f809c2017-10-03 01:48:42 -04004195 rv = VPPCOM_EINVAL;
4196 goto done;
4197 }
4198 if (PREDICT_FALSE (session_vep_idx != vep_idx))
4199 {
Dave Wallace048b1d62018-01-03 22:24:41 -05004200 clib_warning ("VCL<%d>: ERROR: session (%u) "
Dave Wallacef7f809c2017-10-03 01:48:42 -04004201 "vep_idx (%u) != vep_idx (%u)!",
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08004202 getpid (), sid, session_vep_idx, vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04004203 rv = VPPCOM_EINVAL;
4204 goto done;
4205 }
4206
4207 add_event = clear_et_mask = 0;
4208
Dave Wallace60caa062017-11-10 17:07:13 -05004209 if (EPOLLIN & session_events)
Dave Wallacef7f809c2017-10-03 01:48:42 -04004210 {
4211 VCL_LOCK_AND_GET_SESSION (sid, &session);
4212 ready = vppcom_session_read_ready (session, sid);
4213 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace60caa062017-11-10 17:07:13 -05004214 if ((ready > 0) && (EPOLLIN & et_mask))
Dave Wallacef7f809c2017-10-03 01:48:42 -04004215 {
4216 add_event = 1;
4217 events[num_ev].events |= EPOLLIN;
Dave Wallace60caa062017-11-10 17:07:13 -05004218 if (((EPOLLET | EPOLLIN) & session_events) ==
4219 (EPOLLET | EPOLLIN))
Dave Wallacef7f809c2017-10-03 01:48:42 -04004220 clear_et_mask |= EPOLLIN;
4221 }
4222 else if (ready < 0)
4223 {
4224 add_event = 1;
4225 switch (ready)
4226 {
4227 case VPPCOM_ECONNRESET:
4228 events[num_ev].events |= EPOLLHUP | EPOLLRDHUP;
4229 break;
4230
4231 default:
4232 events[num_ev].events |= EPOLLERR;
4233 break;
4234 }
4235 }
4236 }
4237
Dave Wallace60caa062017-11-10 17:07:13 -05004238 if (EPOLLOUT & session_events)
Dave Wallacef7f809c2017-10-03 01:48:42 -04004239 {
4240 VCL_LOCK_AND_GET_SESSION (sid, &session);
4241 ready = vppcom_session_write_ready (session, sid);
4242 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace60caa062017-11-10 17:07:13 -05004243 if ((ready > 0) && (EPOLLOUT & et_mask))
Dave Wallacef7f809c2017-10-03 01:48:42 -04004244 {
4245 add_event = 1;
4246 events[num_ev].events |= EPOLLOUT;
Dave Wallace60caa062017-11-10 17:07:13 -05004247 if (((EPOLLET | EPOLLOUT) & session_events) ==
4248 (EPOLLET | EPOLLOUT))
Dave Wallacef7f809c2017-10-03 01:48:42 -04004249 clear_et_mask |= EPOLLOUT;
4250 }
4251 else if (ready < 0)
4252 {
4253 add_event = 1;
4254 switch (ready)
4255 {
4256 case VPPCOM_ECONNRESET:
4257 events[num_ev].events |= EPOLLHUP;
4258 break;
4259
4260 default:
4261 events[num_ev].events |= EPOLLERR;
4262 break;
4263 }
4264 }
4265 }
4266
4267 if (add_event)
4268 {
4269 events[num_ev].data.u64 = session_ev_data;
4270 if (EPOLLONESHOT & session_events)
4271 {
4272 VCL_LOCK_AND_GET_SESSION (sid, &session);
4273 session->vep.ev.events = 0;
4274 clib_spinlock_unlock (&vcm->sessions_lockp);
4275 }
4276 num_ev++;
4277 if (num_ev == maxevents)
4278 {
4279 VCL_LOCK_AND_GET_SESSION (vep_idx, &vep_session);
4280 vep_session->wait_cont_idx = next_sid;
4281 clib_spinlock_unlock (&vcm->sessions_lockp);
4282 goto done;
4283 }
4284 }
4285 if (wait_cont_idx != ~0)
4286 {
4287 if (next_sid == ~0)
4288 next_sid = vep_next_sid;
4289 else if (next_sid == wait_cont_idx)
4290 next_sid = ~0;
4291 }
4292 }
Dave Wallace2e005bb2017-11-07 01:21:39 -05004293 if (wait_for_time != -1)
4294 keep_trying = (clib_time_now (&vcm->clib_time) <= timeout) ? 1 : 0;
Dave Wallacef7f809c2017-10-03 01:48:42 -04004295 }
Dave Wallace2e005bb2017-11-07 01:21:39 -05004296 while ((num_ev == 0) && keep_trying);
Dave Wallacef7f809c2017-10-03 01:48:42 -04004297
4298 if (wait_cont_idx != ~0)
4299 {
4300 VCL_LOCK_AND_GET_SESSION (vep_idx, &vep_session);
4301 vep_session->wait_cont_idx = ~0;
4302 clib_spinlock_unlock (&vcm->sessions_lockp);
4303 }
4304done:
4305 return (rv != VPPCOM_OK) ? rv : num_ev;
4306}
4307
Dave Wallace35830af2017-10-09 01:43:42 -04004308int
4309vppcom_session_attr (uint32_t session_index, uint32_t op,
4310 void *buffer, uint32_t * buflen)
4311{
Dave Wallace35830af2017-10-09 01:43:42 -04004312 session_t *session;
4313 int rv = VPPCOM_OK;
4314 u32 *flags = buffer;
Steven2199aab2017-10-15 20:18:47 -07004315 vppcom_endpt_t *ep = buffer;
Dave Wallace35830af2017-10-09 01:43:42 -04004316
4317 VCL_LOCK_AND_GET_SESSION (session_index, &session);
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08004318
4319 ASSERT (session);
4320
Dave Wallace35830af2017-10-09 01:43:42 -04004321 switch (op)
4322 {
4323 case VPPCOM_ATTR_GET_NREAD:
4324 rv = vppcom_session_read_ready (session, session_index);
Dave Wallace227867f2017-11-13 21:21:53 -05004325 if (VPPCOM_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05004326 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_NREAD: sid %u, nread = %d",
Dave Wallace2e005bb2017-11-07 01:21:39 -05004327 getpid (), rv);
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004328 if (VPPCOM_DEBUG > 0)
4329 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08004330 /* *INDENT-OFF* */
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004331 ELOG_TYPE_DECLARE (e) =
4332 {
4333 .format = "VPPCOM_ATTR_GET_NREAD: nread=%d",
4334 .format_args = "i4",
4335 };
4336 struct
4337 {
4338 u32 data;
4339 } *ed;
4340
4341 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4342
4343 ed->data = rv;
4344 /* *INDENT-ON* */
4345 }
4346
Dave Wallace35830af2017-10-09 01:43:42 -04004347 break;
4348
Dave Wallace227867f2017-11-13 21:21:53 -05004349 case VPPCOM_ATTR_GET_NWRITE:
4350 rv = vppcom_session_write_ready (session, session_index);
4351 if (VPPCOM_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05004352 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_NWRITE: sid %u, nwrite = %d",
Dave Wallace227867f2017-11-13 21:21:53 -05004353 getpid (), session_index, rv);
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004354 if (VPPCOM_DEBUG > 0)
4355 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08004356 /* *INDENT-OFF* */
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004357 ELOG_TYPE_DECLARE (e) =
4358 {
4359 .format = "VPPCOM_ATTR_GET_NWRITE: nwrite=%d",
4360 .format_args = "i4",
4361 };
4362 struct
4363 {
4364 u32 data;
4365 } *ed;
4366
4367 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4368
4369 ed->data = rv;
4370 /* *INDENT-ON* */
4371 }
Dave Wallace35830af2017-10-09 01:43:42 -04004372 break;
4373
4374 case VPPCOM_ATTR_GET_FLAGS:
Dave Wallace048b1d62018-01-03 22:24:41 -05004375 if (PREDICT_TRUE (buffer && buflen && (*buflen >= sizeof (*flags))))
Dave Wallace35830af2017-10-09 01:43:42 -04004376 {
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08004377 *flags = O_RDWR | (VCL_SESS_ATTR_TEST (session->attr,
4378 VCL_SESS_ATTR_NONBLOCK));
Dave Wallace35830af2017-10-09 01:43:42 -04004379 *buflen = sizeof (*flags);
Dave Wallace227867f2017-11-13 21:21:53 -05004380 if (VPPCOM_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05004381 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_FLAGS: sid %u, "
Dave Wallace227867f2017-11-13 21:21:53 -05004382 "flags = 0x%08x, is_nonblocking = %u", getpid (),
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08004383 session_index, *flags,
4384 VCL_SESS_ATTR_TEST (session->attr,
4385 VCL_SESS_ATTR_NONBLOCK));
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004386 if (VPPCOM_DEBUG > 0)
4387 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08004388 /* *INDENT-OFF* */
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004389 ELOG_TYPE_DECLARE (e) =
4390 {
4391 .format = "VPPCOM_ATTR_GET_FLAGS: flags=%x is_nonblk=%d",
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004392 .format_args = "i4i4",
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004393 };
4394 struct
4395 {
4396 u32 flags;
4397 u32 is_nonblk;
4398 } *ed;
4399
4400 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4401
4402 ed->flags = *flags;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08004403 ed->is_nonblk = VCL_SESS_ATTR_TEST (session->attr, VCL_SESS_ATTR_NONBLOCK);
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004404 /* *INDENT-ON* */
4405 }
4406
Dave Wallace35830af2017-10-09 01:43:42 -04004407 }
4408 else
4409 rv = VPPCOM_EINVAL;
4410 break;
4411
4412 case VPPCOM_ATTR_SET_FLAGS:
Dave Wallace048b1d62018-01-03 22:24:41 -05004413 if (PREDICT_TRUE (buffer && buflen && (*buflen == sizeof (*flags))))
Dave Wallace35830af2017-10-09 01:43:42 -04004414 {
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08004415 if (*flags & O_NONBLOCK)
4416 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_NONBLOCK);
4417 else
4418 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_NONBLOCK);
4419
Dave Wallace227867f2017-11-13 21:21:53 -05004420 if (VPPCOM_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05004421 clib_warning ("VCL<%d>: VPPCOM_ATTR_SET_FLAGS: sid %u, "
Dave Wallace227867f2017-11-13 21:21:53 -05004422 "flags = 0x%08x, is_nonblocking = %u",
Dave Wallace4878cbe2017-11-21 03:45:09 -05004423 getpid (), session_index, *flags,
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08004424 VCL_SESS_ATTR_TEST (session->attr,
4425 VCL_SESS_ATTR_NONBLOCK));
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004426 if (VPPCOM_DEBUG > 0)
4427 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08004428 /* *INDENT-OFF* */
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004429 ELOG_TYPE_DECLARE (e) =
4430 {
4431 .format = "VPPCOM_ATTR_SET_FLAGS: flags=%x is_nonblk=%d",
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004432 .format_args = "i4i4",
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004433 };
4434 struct
4435 {
4436 u32 flags;
4437 u32 is_nonblk;
4438 } *ed;
4439
4440 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4441
4442 ed->flags = *flags;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08004443 ed->is_nonblk = VCL_SESS_ATTR_TEST (session->attr, VCL_SESS_ATTR_NONBLOCK);
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004444 /* *INDENT-ON* */
4445 }
Dave Wallace35830af2017-10-09 01:43:42 -04004446 }
4447 else
4448 rv = VPPCOM_EINVAL;
4449 break;
4450
4451 case VPPCOM_ATTR_GET_PEER_ADDR:
Dave Wallace048b1d62018-01-03 22:24:41 -05004452 if (PREDICT_TRUE (buffer && buflen &&
4453 (*buflen >= sizeof (*ep)) && ep->ip))
Dave Wallace35830af2017-10-09 01:43:42 -04004454 {
Steven2199aab2017-10-15 20:18:47 -07004455 ep->is_ip4 = session->peer_addr.is_ip4;
Stevenac1f96d2017-10-24 16:03:58 -07004456 ep->port = session->peer_port;
Steven2199aab2017-10-15 20:18:47 -07004457 if (session->peer_addr.is_ip4)
4458 clib_memcpy (ep->ip, &session->peer_addr.ip46.ip4,
4459 sizeof (ip4_address_t));
4460 else
4461 clib_memcpy (ep->ip, &session->peer_addr.ip46.ip6,
4462 sizeof (ip6_address_t));
4463 *buflen = sizeof (*ep);
Dave Wallacefaf9d772017-10-26 16:12:04 -04004464 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05004465 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_PEER_ADDR: sid %u, "
4466 "is_ip4 = %u, addr = %U, port %u", getpid (),
Dave Wallace774169b2017-11-01 20:07:40 -04004467 session_index, ep->is_ip4, format_ip46_address,
Dave Wallacede910062018-03-20 09:22:13 -04004468 &session->peer_addr.ip46,
4469 ep->is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6,
Stevenac1f96d2017-10-24 16:03:58 -07004470 clib_net_to_host_u16 (ep->port));
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004471 if (VPPCOM_DEBUG > 0)
4472 {
4473 if (ep->is_ip4)
4474 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08004475 /* *INDENT-OFF* */
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004476 ELOG_TYPE_DECLARE (e) =
4477 {
4478 .format = "VPPCOM_ATTR_GET_PEER_ADDR: addr:%d.%d.%d.%d:%d",
4479 .format_args = "i1i1i1i1i2",
4480 };
4481 CLIB_PACKED (struct {
4482 u8 addr[4]; //4
4483 u16 port; //2
4484 }) * ed;
4485
4486 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4487
4488 ed->addr[0] = session->peer_addr.ip46.ip4.as_u8[0];
4489 ed->addr[1] = session->peer_addr.ip46.ip4.as_u8[1];
4490 ed->addr[2] = session->peer_addr.ip46.ip4.as_u8[2];
4491 ed->addr[3] = session->peer_addr.ip46.ip4.as_u8[3];
4492 ed->port = clib_net_to_host_u16 (session->peer_port);
4493 /* *INDENT-ON* */
4494 }
4495 else
4496 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08004497 /* *INDENT-OFF* */
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004498 ELOG_TYPE_DECLARE (e) =
4499 {
4500 .format = "VPPCOM_ATTR_GET_PEER_ADDR: addr:IP6:%d",
4501 .format_args = "i2",
4502 };
4503 CLIB_PACKED (struct {
4504 u16 port; //2
4505 }) * ed;
4506
4507 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4508
4509 ed->port = clib_net_to_host_u16 (session->peer_port);
4510 /* *INDENT-ON* */
4511 }
4512 }
Dave Wallace35830af2017-10-09 01:43:42 -04004513 }
4514 else
4515 rv = VPPCOM_EINVAL;
4516 break;
4517
4518 case VPPCOM_ATTR_GET_LCL_ADDR:
Dave Wallace048b1d62018-01-03 22:24:41 -05004519 if (PREDICT_TRUE (buffer && buflen &&
4520 (*buflen >= sizeof (*ep)) && ep->ip))
Dave Wallace35830af2017-10-09 01:43:42 -04004521 {
Steven2199aab2017-10-15 20:18:47 -07004522 ep->is_ip4 = session->lcl_addr.is_ip4;
Stevenac1f96d2017-10-24 16:03:58 -07004523 ep->port = session->lcl_port;
Steven2199aab2017-10-15 20:18:47 -07004524 if (session->lcl_addr.is_ip4)
4525 clib_memcpy (ep->ip, &session->lcl_addr.ip46.ip4,
4526 sizeof (ip4_address_t));
4527 else
4528 clib_memcpy (ep->ip, &session->lcl_addr.ip46.ip6,
4529 sizeof (ip6_address_t));
4530 *buflen = sizeof (*ep);
Dave Wallacefaf9d772017-10-26 16:12:04 -04004531 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05004532 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_LCL_ADDR: sid %u, "
4533 "is_ip4 = %u, addr = %U port %d", getpid (),
Dave Wallace774169b2017-11-01 20:07:40 -04004534 session_index, ep->is_ip4, format_ip46_address,
Dave Wallacede910062018-03-20 09:22:13 -04004535 &session->lcl_addr.ip46,
4536 ep->is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6,
Stevenac1f96d2017-10-24 16:03:58 -07004537 clib_net_to_host_u16 (ep->port));
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004538 if (VPPCOM_DEBUG > 0)
4539 {
4540 if (ep->is_ip4)
4541 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08004542 /* *INDENT-OFF* */
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004543 ELOG_TYPE_DECLARE (e) =
4544 {
4545 .format = "VPPCOM_ATTR_GET_LCL_ADDR: addr:%d.%d.%d.%d:%d",
4546 .format_args = "i1i1i1i1i2",
4547 };
4548 CLIB_PACKED (struct {
4549 u8 addr[4]; //4
4550 u16 port; //2
4551 }) * ed;
4552
4553 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4554
4555 ed->addr[0] = session->lcl_addr.ip46.ip4.as_u8[0];
4556 ed->addr[1] = session->lcl_addr.ip46.ip4.as_u8[1];
4557 ed->addr[2] = session->lcl_addr.ip46.ip4.as_u8[2];
4558 ed->addr[3] = session->lcl_addr.ip46.ip4.as_u8[3];
4559 ed->port = clib_net_to_host_u16 (session->peer_port);
4560 /* *INDENT-ON* */
4561 }
4562 else
4563 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08004564 /* *INDENT-OFF* */
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004565 ELOG_TYPE_DECLARE (e) =
4566 {
4567 .format = "VPPCOM_ATTR_GET_LCL_ADDR: addr:IP6:%d",
4568 .format_args = "i2",
4569 };
4570 CLIB_PACKED (struct {
4571 u16 port; //2
4572 }) * ed;
4573
4574 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4575
4576 ed->port = clib_net_to_host_u16 (session->peer_port);
4577 /* *INDENT-ON* */
4578 }
4579 }
Dave Wallace35830af2017-10-09 01:43:42 -04004580 }
4581 else
4582 rv = VPPCOM_EINVAL;
4583 break;
Stevenb5a11602017-10-11 09:59:30 -07004584
Dave Wallace048b1d62018-01-03 22:24:41 -05004585 case VPPCOM_ATTR_GET_LIBC_EPFD:
4586 rv = session->libc_epfd;
4587 if (VPPCOM_DEBUG > 2)
4588 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_LIBC_EPFD: libc_epfd %d",
4589 getpid (), rv);
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004590 if (VPPCOM_DEBUG > 0)
4591 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08004592 /* *INDENT-OFF* */
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004593 ELOG_TYPE_DECLARE (e) =
4594 {
Florin Corasbb16d3f2018-01-29 08:55:25 -08004595 .format = "VPPCOM_ATTR_GET_LIBC_EPFD: libc_epfd=%d",
4596 .format_args = "i4",
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004597 };
4598 CLIB_PACKED (struct {
Florin Corasbb16d3f2018-01-29 08:55:25 -08004599 i32 data;
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08004600 }) *ed;
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004601
4602 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
Florin Corasbb16d3f2018-01-29 08:55:25 -08004603 ed->data = session->libc_epfd;
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004604 /* *INDENT-ON* */
4605 }
4606
Dave Wallace048b1d62018-01-03 22:24:41 -05004607 break;
4608
4609 case VPPCOM_ATTR_SET_LIBC_EPFD:
4610 if (PREDICT_TRUE (buffer && buflen &&
4611 (*buflen == sizeof (session->libc_epfd))))
4612 {
4613 session->libc_epfd = *(int *) buffer;
4614 *buflen = sizeof (session->libc_epfd);
4615
4616 if (VPPCOM_DEBUG > 2)
4617 clib_warning ("VCL<%d>: VPPCOM_ATTR_SET_LIBC_EPFD: libc_epfd %d, "
4618 "buflen %d", getpid (), session->libc_epfd,
4619 *buflen);
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004620 if (VPPCOM_DEBUG > 0)
4621 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08004622 /* *INDENT-OFF* */
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004623 ELOG_TYPE_DECLARE (e) =
4624 {
4625 .format = "VPPCOM_ATTR_SET_LIBC_EPFD: libc_epfd=%s%d buflen=%d",
4626 .format_args = "t1i4i4",
4627 .n_enum_strings = 2,
4628 .enum_strings = {"", "-",},
4629 };
4630 CLIB_PACKED (struct {
4631 u8 sign;
4632 u32 data[2];
4633 }) * ed;
4634
4635 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4636
4637 ed->sign = (session->libc_epfd < 0);
4638 ed->data[0] = abs(session->libc_epfd);
4639 ed->data[1] = *buflen;
4640 /* *INDENT-ON* */
4641 }
Dave Wallace048b1d62018-01-03 22:24:41 -05004642 }
4643 else
4644 rv = VPPCOM_EINVAL;
4645 break;
4646
4647 case VPPCOM_ATTR_GET_PROTOCOL:
4648 if (buffer && buflen && (*buflen >= sizeof (int)))
4649 {
4650 *(int *) buffer = session->proto;
4651 *buflen = sizeof (int);
4652
4653 if (VPPCOM_DEBUG > 2)
4654 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_PROTOCOL: %d (%s), "
4655 "buflen %d", getpid (), *(int *) buffer,
4656 *(int *) buffer ? "UDP" : "TCP", *buflen);
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004657 if (VPPCOM_DEBUG > 0)
4658 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08004659 /* *INDENT-OFF* */
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004660 ELOG_TYPE_DECLARE (e) =
4661 {
4662 .format = "VPPCOM_ATTR_GET_PROTOCOL: %s buflen=%d",
4663 .format_args = "t1i4",
4664 .n_enum_strings = 2,
4665 .enum_strings = {"TCP", "UDP",},
4666 };
4667
4668 CLIB_PACKED (struct {
4669 u8 proto;
4670 u32 buflen;
4671 }) * ed;
4672
4673 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4674 ed->proto = session->proto;
4675 ed->buflen = *(int *) buffer;
4676 /* *INDENT-ON* */
4677 }
Dave Wallace048b1d62018-01-03 22:24:41 -05004678 }
4679 else
4680 rv = VPPCOM_EINVAL;
4681 break;
4682
4683 case VPPCOM_ATTR_GET_LISTEN:
4684 if (buffer && buflen && (*buflen >= sizeof (int)))
4685 {
4686 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
4687 VCL_SESS_ATTR_LISTEN);
4688 *buflen = sizeof (int);
4689
4690 if (VPPCOM_DEBUG > 2)
4691 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_LISTEN: %d, "
4692 "buflen %d", getpid (), *(int *) buffer, *buflen);
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004693 if (VPPCOM_DEBUG > 0)
4694 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08004695 /* *INDENT-OFF* */
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004696 ELOG_TYPE_DECLARE (e) =
4697 {
4698 .format = "VPPCOM_ATTR_GET_LISTEN: %d buflen=%d",
4699 .format_args = "i4i4",
4700 };
4701
4702 struct {
4703 u32 data[2];
4704 } * ed;
4705
4706 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4707 ed->data[0] = *(int *) buffer;
4708 ed->data[1] = *buflen;
4709 /* *INDENT-ON* */
4710 }
Dave Wallace048b1d62018-01-03 22:24:41 -05004711 }
4712 else
4713 rv = VPPCOM_EINVAL;
4714 break;
4715
4716 case VPPCOM_ATTR_GET_ERROR:
4717 if (buffer && buflen && (*buflen >= sizeof (int)))
4718 {
4719 *(int *) buffer = 0;
4720 *buflen = sizeof (int);
4721
4722 if (VPPCOM_DEBUG > 2)
4723 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_ERROR: %d, "
4724 "buflen %d, #VPP-TBD#", getpid (),
4725 *(int *) buffer, *buflen);
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004726 if (VPPCOM_DEBUG > 0)
4727 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08004728 /* *INDENT-OFF* */
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004729 ELOG_TYPE_DECLARE (e) =
4730 {
4731 .format = "VPPCOM_ATTR_GET_ERROR: %d buflen=%d",
4732 .format_args = "i4i4",
4733 };
4734
4735 struct {
4736 u32 data[2];
4737 } * ed;
4738
4739 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4740 ed->data[0] = *(int *) buffer;
4741 ed->data[1] = *buflen;
4742 /* *INDENT-ON* */
4743 }
Dave Wallace048b1d62018-01-03 22:24:41 -05004744 }
4745 else
4746 rv = VPPCOM_EINVAL;
4747 break;
4748
4749 case VPPCOM_ATTR_GET_TX_FIFO_LEN:
4750 if (buffer && buflen && (*buflen >= sizeof (u32)))
4751 {
Dave Wallace048b1d62018-01-03 22:24:41 -05004752
4753 /* VPP-TBD */
4754 *(size_t *) buffer = (session->sndbuf_size ? session->sndbuf_size :
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08004755 session->tx_fifo ? session->tx_fifo->nitems :
Dave Wallace048b1d62018-01-03 22:24:41 -05004756 vcm->cfg.tx_fifo_size);
4757 *buflen = sizeof (u32);
4758
4759 if (VPPCOM_DEBUG > 2)
4760 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_TX_FIFO_LEN: %u (0x%x), "
4761 "buflen %d, #VPP-TBD#", getpid (),
4762 *(size_t *) buffer, *(size_t *) buffer, *buflen);
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004763 if (VPPCOM_DEBUG > 0)
4764 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08004765 /* *INDENT-OFF* */
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004766 ELOG_TYPE_DECLARE (e) =
4767 {
4768 .format = "VPPCOM_ATTR_GET_TX_FIFO_LEN: 0x%x buflen=%d",
4769 .format_args = "i4i4",
4770 };
4771
4772 struct {
4773 u32 data[2];
4774 } * ed;
4775
4776 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4777 ed->data[0] = *(size_t *) buffer;
4778 ed->data[1] = *buflen;
4779 /* *INDENT-ON* */
4780 }
Dave Wallace048b1d62018-01-03 22:24:41 -05004781 }
4782 else
4783 rv = VPPCOM_EINVAL;
4784 break;
4785
4786 case VPPCOM_ATTR_SET_TX_FIFO_LEN:
4787 if (buffer && buflen && (*buflen == sizeof (u32)))
4788 {
4789 /* VPP-TBD */
4790 session->sndbuf_size = *(u32 *) buffer;
4791 if (VPPCOM_DEBUG > 2)
4792 clib_warning ("VCL<%d>: VPPCOM_ATTR_SET_TX_FIFO_LEN: %u (0x%x), "
4793 "buflen %d, #VPP-TBD#", getpid (),
4794 session->sndbuf_size, session->sndbuf_size,
4795 *buflen);
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004796 if (VPPCOM_DEBUG > 0)
4797 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08004798 /* *INDENT-OFF* */
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004799 ELOG_TYPE_DECLARE (e) =
4800 {
4801 .format = "VPPCOM_ATTR_SET_TX_FIFO_LEN: 0x%x buflen=%d",
4802 .format_args = "i4i4",
4803 };
4804
4805 struct {
4806 u32 data[2];
4807 } * ed;
4808
4809 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4810 ed->data[0] = session->sndbuf_size;
4811 ed->data[1] = *buflen;
4812 /* *INDENT-ON* */
4813 }
Dave Wallace048b1d62018-01-03 22:24:41 -05004814 }
4815 else
4816 rv = VPPCOM_EINVAL;
4817 break;
4818
4819 case VPPCOM_ATTR_GET_RX_FIFO_LEN:
4820 if (buffer && buflen && (*buflen >= sizeof (u32)))
4821 {
Dave Wallace048b1d62018-01-03 22:24:41 -05004822
4823 /* VPP-TBD */
4824 *(size_t *) buffer = (session->rcvbuf_size ? session->rcvbuf_size :
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08004825 session->rx_fifo ? session->rx_fifo->nitems :
Dave Wallace048b1d62018-01-03 22:24:41 -05004826 vcm->cfg.rx_fifo_size);
4827 *buflen = sizeof (u32);
4828
4829 if (VPPCOM_DEBUG > 2)
4830 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_RX_FIFO_LEN: %u (0x%x), "
4831 "buflen %d, #VPP-TBD#", getpid (),
4832 *(size_t *) buffer, *(size_t *) buffer, *buflen);
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004833 if (VPPCOM_DEBUG > 0)
4834 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08004835 /* *INDENT-OFF* */
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004836 ELOG_TYPE_DECLARE (e) =
4837 {
4838 .format = "VPPCOM_ATTR_GET_RX_FIFO_LEN: 0x%x buflen=%d",
4839 .format_args = "i4i4",
4840 };
4841
4842 struct {
4843 u32 data[2];
4844 } * ed;
4845
4846 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4847 ed->data[0] = *(size_t *) buffer;
4848 ed->data[1] = *buflen;
4849 /* *INDENT-ON* */
4850 }
Dave Wallace048b1d62018-01-03 22:24:41 -05004851 }
4852 else
4853 rv = VPPCOM_EINVAL;
4854 break;
4855
4856 case VPPCOM_ATTR_SET_RX_FIFO_LEN:
4857 if (buffer && buflen && (*buflen == sizeof (u32)))
4858 {
4859 /* VPP-TBD */
4860 session->rcvbuf_size = *(u32 *) buffer;
4861 if (VPPCOM_DEBUG > 2)
Dave Wallace7e2c31a2018-02-05 20:03:01 -05004862 clib_warning ("VCL<%d>: VPPCOM_ATTR_SET_RX_FIFO_LEN: %u (0x%x), "
Dave Wallace048b1d62018-01-03 22:24:41 -05004863 "buflen %d, #VPP-TBD#", getpid (),
4864 session->sndbuf_size, session->sndbuf_size,
4865 *buflen);
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004866 if (VPPCOM_DEBUG > 0)
4867 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08004868 /* *INDENT-OFF* */
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004869 ELOG_TYPE_DECLARE (e) =
4870 {
Dave Wallace7e2c31a2018-02-05 20:03:01 -05004871 .format = "VPPCOM_ATTR_SET_RX_FIFO_LEN: 0x%x buflen=%d",
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004872 .format_args = "i4i4",
4873 };
4874
4875 struct {
4876 u32 data[2];
4877 } * ed;
4878
4879 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4880 ed->data[0] = session->sndbuf_size;
4881 ed->data[1] = *buflen;
4882 /* *INDENT-ON* */
4883 }
Dave Wallace048b1d62018-01-03 22:24:41 -05004884 }
4885 else
4886 rv = VPPCOM_EINVAL;
4887 break;
4888
4889 case VPPCOM_ATTR_GET_REUSEADDR:
4890 if (buffer && buflen && (*buflen >= sizeof (int)))
4891 {
4892 /* VPP-TBD */
4893 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
4894 VCL_SESS_ATTR_REUSEADDR);
4895 *buflen = sizeof (int);
4896
4897 if (VPPCOM_DEBUG > 2)
4898 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_REUSEADDR: %d, "
4899 "buflen %d, #VPP-TBD#", getpid (), *(int *) buffer,
4900 *buflen);
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004901 if (VPPCOM_DEBUG > 0)
4902 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08004903 /* *INDENT-OFF* */
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004904 ELOG_TYPE_DECLARE (e) =
4905 {
4906 .format = "VPPCOM_ATTR_GET_REUSEADDR: %d buflen=%d",
4907 .format_args = "i4i4",
4908 };
4909
4910 struct {
4911 u32 data[2];
4912 } * ed;
4913
4914 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4915 ed->data[0] = *(int *) buffer;
4916 ed->data[1] = *buflen;
4917 /* *INDENT-ON* */
4918 }
Dave Wallace048b1d62018-01-03 22:24:41 -05004919 }
4920 else
4921 rv = VPPCOM_EINVAL;
4922 break;
4923
Stevenb5a11602017-10-11 09:59:30 -07004924 case VPPCOM_ATTR_SET_REUSEADDR:
Dave Wallace048b1d62018-01-03 22:24:41 -05004925 if (buffer && buflen && (*buflen == sizeof (int)) &&
4926 !VCL_SESS_ATTR_TEST (session->attr, VCL_SESS_ATTR_LISTEN))
4927 {
4928 /* VPP-TBD */
4929 if (*(int *) buffer)
4930 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_REUSEADDR);
4931 else
4932 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_REUSEADDR);
4933
4934 if (VPPCOM_DEBUG > 2)
4935 clib_warning ("VCL<%d>: VPPCOM_ATTR_SET_REUSEADDR: %d, "
4936 "buflen %d, #VPP-TBD#", getpid (),
4937 VCL_SESS_ATTR_TEST (session->attr,
4938 VCL_SESS_ATTR_REUSEADDR),
4939 *buflen);
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004940 if (VPPCOM_DEBUG > 0)
4941 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08004942 /* *INDENT-OFF* */
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004943 ELOG_TYPE_DECLARE (e) =
4944 {
4945 .format = "VPPCOM_ATTR_SET_REUSEADDR: %d buflen=%d",
4946 .format_args = "i4i4",
4947 };
4948
4949 struct {
4950 u32 data[2];
4951 } * ed;
4952
4953 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4954 ed->data[0] = VCL_SESS_ATTR_TEST (session->attr,
4955 VCL_SESS_ATTR_REUSEADDR);
4956 ed->data[1] = *buflen;
4957 /* *INDENT-ON* */
4958 }
Dave Wallace048b1d62018-01-03 22:24:41 -05004959 }
4960 else
4961 rv = VPPCOM_EINVAL;
4962 break;
4963
4964 case VPPCOM_ATTR_GET_REUSEPORT:
4965 if (buffer && buflen && (*buflen >= sizeof (int)))
4966 {
4967 /* VPP-TBD */
4968 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
4969 VCL_SESS_ATTR_REUSEPORT);
4970 *buflen = sizeof (int);
4971
4972 if (VPPCOM_DEBUG > 2)
4973 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_REUSEPORT: %d, "
4974 "buflen %d, #VPP-TBD#", getpid (), *(int *) buffer,
4975 *buflen);
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004976 if (VPPCOM_DEBUG > 0)
4977 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08004978 /* *INDENT-OFF* */
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004979 ELOG_TYPE_DECLARE (e) =
4980 {
4981 .format = "VPPCOM_ATTR_GET_REUSEPORT: %d buflen=%d",
4982 .format_args = "i4i4",
4983 };
4984
4985 struct {
4986 u32 data[2];
4987 } * ed;
4988
4989 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4990 ed->data[0] = *(int *) buffer;
4991 ed->data[1] = *buflen;
4992 /* *INDENT-ON* */
4993 }
Dave Wallace048b1d62018-01-03 22:24:41 -05004994 }
4995 else
4996 rv = VPPCOM_EINVAL;
4997 break;
4998
4999 case VPPCOM_ATTR_SET_REUSEPORT:
5000 if (buffer && buflen && (*buflen == sizeof (int)) &&
5001 !VCL_SESS_ATTR_TEST (session->attr, VCL_SESS_ATTR_LISTEN))
5002 {
5003 /* VPP-TBD */
5004 if (*(int *) buffer)
5005 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_REUSEPORT);
5006 else
5007 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_REUSEPORT);
5008
5009 if (VPPCOM_DEBUG > 2)
5010 clib_warning ("VCL<%d>: VPPCOM_ATTR_SET_REUSEPORT: %d, "
5011 "buflen %d, #VPP-TBD#", getpid (),
5012 VCL_SESS_ATTR_TEST (session->attr,
5013 VCL_SESS_ATTR_REUSEPORT),
5014 *buflen);
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08005015 if (VPPCOM_DEBUG > 0)
5016 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08005017 /* *INDENT-OFF* */
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08005018 ELOG_TYPE_DECLARE (e) =
5019 {
5020 .format = "VPPCOM_ATTR_SET_REUSEPORT: %d buflen=%d",
5021 .format_args = "i4i4",
5022 };
5023
5024 struct {
5025 u32 data[2];
5026 } * ed;
5027
5028 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
5029 ed->data[0] = VCL_SESS_ATTR_TEST (session->attr,
5030 VCL_SESS_ATTR_REUSEPORT);
5031 ed->data[1] = *buflen;
5032 /* *INDENT-ON* */
5033 }
Dave Wallace048b1d62018-01-03 22:24:41 -05005034 }
5035 else
5036 rv = VPPCOM_EINVAL;
5037 break;
5038
5039 case VPPCOM_ATTR_GET_BROADCAST:
5040 if (buffer && buflen && (*buflen >= sizeof (int)))
5041 {
5042 /* VPP-TBD */
5043 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
5044 VCL_SESS_ATTR_BROADCAST);
5045 *buflen = sizeof (int);
5046
5047 if (VPPCOM_DEBUG > 2)
5048 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_BROADCAST: %d, "
5049 "buflen %d, #VPP-TBD#", getpid (), *(int *) buffer,
5050 *buflen);
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08005051 if (VPPCOM_DEBUG > 0)
5052 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08005053 /* *INDENT-OFF* */
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08005054 ELOG_TYPE_DECLARE (e) =
5055 {
5056 .format = "VPPCOM_ATTR_GET_BROADCAST: %d buflen=%d",
5057 .format_args = "i4i4",
5058 };
5059
5060 struct {
5061 u32 data[2];
5062 } * ed;
5063
5064 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
5065 ed->data[0] = *(int *) buffer;
5066 ed->data[1] = *buflen;
5067 /* *INDENT-ON* */
5068 }
Dave Wallace048b1d62018-01-03 22:24:41 -05005069 }
5070 else
5071 rv = VPPCOM_EINVAL;
Stevenb5a11602017-10-11 09:59:30 -07005072 break;
5073
5074 case VPPCOM_ATTR_SET_BROADCAST:
Dave Wallace048b1d62018-01-03 22:24:41 -05005075 if (buffer && buflen && (*buflen == sizeof (int)))
5076 {
5077 /* VPP-TBD */
5078 if (*(int *) buffer)
5079 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_BROADCAST);
5080 else
5081 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_BROADCAST);
5082
5083 if (VPPCOM_DEBUG > 2)
5084 clib_warning ("VCL<%d>: VPPCOM_ATTR_SET_BROADCAST: %d, "
5085 "buflen %d, #VPP-TBD#", getpid (),
5086 VCL_SESS_ATTR_TEST (session->attr,
5087 VCL_SESS_ATTR_BROADCAST),
5088 *buflen);
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005089 if (VPPCOM_DEBUG > 0)
5090 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08005091 /* *INDENT-OFF* */
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005092 ELOG_TYPE_DECLARE (e) =
5093 {
5094 .format = "VPPCOM_ATTR_SET_BROADCAST: %d buflen=%d",
5095 .format_args = "i4i4",
5096 };
5097
5098 struct {
5099 u32 data[2];
5100 } * ed;
5101
5102 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
5103 ed->data[0] = VCL_SESS_ATTR_TEST (session->attr,
5104 VCL_SESS_ATTR_BROADCAST);
5105 ed->data[1] = *buflen;
5106 /* *INDENT-ON* */
5107 }
Dave Wallace048b1d62018-01-03 22:24:41 -05005108 }
5109 else
5110 rv = VPPCOM_EINVAL;
5111 break;
5112
5113 case VPPCOM_ATTR_GET_V6ONLY:
5114 if (buffer && buflen && (*buflen >= sizeof (int)))
5115 {
5116 /* VPP-TBD */
5117 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
5118 VCL_SESS_ATTR_V6ONLY);
5119 *buflen = sizeof (int);
5120
5121 if (VPPCOM_DEBUG > 2)
5122 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_V6ONLY: %d, "
5123 "buflen %d, #VPP-TBD#", getpid (), *(int *) buffer,
5124 *buflen);
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005125 if (VPPCOM_DEBUG > 0)
5126 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08005127 /* *INDENT-OFF* */
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005128 ELOG_TYPE_DECLARE (e) =
5129 {
5130 .format = "VPPCOM_ATTR_GET_V6ONLY: %d buflen=%d",
5131 .format_args = "i4i4",
5132 };
5133
5134 struct {
5135 u32 data[2];
5136 } * ed;
5137
5138 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
5139 ed->data[0] = *(int *) buffer;
5140 ed->data[1] = *buflen;
5141 /* *INDENT-ON* */
5142 }
Dave Wallace048b1d62018-01-03 22:24:41 -05005143 }
5144 else
5145 rv = VPPCOM_EINVAL;
Stevenb5a11602017-10-11 09:59:30 -07005146 break;
5147
5148 case VPPCOM_ATTR_SET_V6ONLY:
Dave Wallace048b1d62018-01-03 22:24:41 -05005149 if (buffer && buflen && (*buflen == sizeof (int)))
5150 {
5151 /* VPP-TBD */
5152 if (*(int *) buffer)
5153 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_V6ONLY);
5154 else
5155 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_V6ONLY);
5156
5157 if (VPPCOM_DEBUG > 2)
5158 clib_warning ("VCL<%d>: VPPCOM_ATTR_SET_V6ONLY: %d, "
5159 "buflen %d, #VPP-TBD#", getpid (),
5160 VCL_SESS_ATTR_TEST (session->attr,
5161 VCL_SESS_ATTR_V6ONLY), *buflen);
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005162 if (VPPCOM_DEBUG > 0)
5163 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08005164 /* *INDENT-OFF* */
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005165 ELOG_TYPE_DECLARE (e) =
5166 {
5167 .format = "VPPCOM_ATTR_SET_V6ONLY: %d buflen=%d",
5168 .format_args = "i4i4",
5169 };
5170
5171 struct {
5172 u32 data[2];
5173 } * ed;
5174
5175 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
5176 ed->data[0] = VCL_SESS_ATTR_TEST (session->attr,
5177 VCL_SESS_ATTR_V6ONLY);
5178 ed->data[1] = *buflen;
5179 /* *INDENT-ON* */
5180 }
Dave Wallace048b1d62018-01-03 22:24:41 -05005181 }
5182 else
5183 rv = VPPCOM_EINVAL;
5184 break;
5185
5186 case VPPCOM_ATTR_GET_KEEPALIVE:
5187 if (buffer && buflen && (*buflen >= sizeof (int)))
5188 {
5189 /* VPP-TBD */
5190 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
5191 VCL_SESS_ATTR_KEEPALIVE);
5192 *buflen = sizeof (int);
5193
5194 if (VPPCOM_DEBUG > 2)
5195 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_KEEPALIVE: %d, "
5196 "buflen %d, #VPP-TBD#", getpid (), *(int *) buffer,
5197 *buflen);
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005198 if (VPPCOM_DEBUG > 0)
5199 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08005200 /* *INDENT-OFF* */
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005201 ELOG_TYPE_DECLARE (e) =
5202 {
5203 .format = "VPPCOM_ATTR_GET_KEEPALIVE: %d buflen=%d",
5204 .format_args = "i4i4",
5205 };
5206
5207 struct {
5208 u32 data[2];
5209 } * ed;
5210
5211 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
5212 ed->data[0] = *(int *) buffer;
5213 ed->data[1] = *buflen;
5214 /* *INDENT-ON* */
5215 }
Dave Wallace048b1d62018-01-03 22:24:41 -05005216 }
5217 else
5218 rv = VPPCOM_EINVAL;
Stevenb5a11602017-10-11 09:59:30 -07005219 break;
Stevenbccd3392017-10-12 20:42:21 -07005220
5221 case VPPCOM_ATTR_SET_KEEPALIVE:
Dave Wallace048b1d62018-01-03 22:24:41 -05005222 if (buffer && buflen && (*buflen == sizeof (int)))
5223 {
5224 /* VPP-TBD */
5225 if (*(int *) buffer)
5226 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_KEEPALIVE);
5227 else
5228 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_KEEPALIVE);
5229
5230 if (VPPCOM_DEBUG > 2)
5231 clib_warning ("VCL<%d>: VPPCOM_ATTR_SET_KEEPALIVE: %d, "
5232 "buflen %d, #VPP-TBD#", getpid (),
5233 VCL_SESS_ATTR_TEST (session->attr,
5234 VCL_SESS_ATTR_KEEPALIVE),
5235 *buflen);
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005236 if (VPPCOM_DEBUG > 0)
5237 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08005238 /* *INDENT-OFF* */
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005239 ELOG_TYPE_DECLARE (e) =
5240 {
5241 .format = "VPPCOM_ATTR_SET_KEEPALIVE: %d buflen=%d",
5242 .format_args = "i4i4",
5243 };
5244
5245 struct {
5246 u32 data[2];
5247 } * ed;
5248
5249 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
5250 ed->data[0] = VCL_SESS_ATTR_TEST (session->attr,
5251 VCL_SESS_ATTR_KEEPALIVE);
5252 ed->data[1] = *buflen;
5253 /* *INDENT-ON* */
5254 }
Dave Wallace048b1d62018-01-03 22:24:41 -05005255 }
5256 else
5257 rv = VPPCOM_EINVAL;
5258 break;
5259
5260 case VPPCOM_ATTR_GET_TCP_NODELAY:
5261 if (buffer && buflen && (*buflen >= sizeof (int)))
5262 {
5263 /* VPP-TBD */
5264 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
5265 VCL_SESS_ATTR_TCP_NODELAY);
5266 *buflen = sizeof (int);
5267
5268 if (VPPCOM_DEBUG > 2)
5269 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_TCP_NODELAY: %d, "
5270 "buflen %d, #VPP-TBD#", getpid (), *(int *) buffer,
5271 *buflen);
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005272 if (VPPCOM_DEBUG > 0)
5273 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08005274 /* *INDENT-OFF* */
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005275 ELOG_TYPE_DECLARE (e) =
5276 {
5277 .format = "VPPCOM_ATTR_GET_TCP_NODELAY: %d buflen=%d",
5278 .format_args = "i4i4",
5279 };
5280
5281 struct {
5282 u32 data[2];
5283 } * ed;
5284
5285 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
5286 ed->data[0] = *(int *) buffer;
5287 ed->data[1] = *buflen;
5288 /* *INDENT-ON* */
5289 }
Dave Wallace048b1d62018-01-03 22:24:41 -05005290 }
5291 else
5292 rv = VPPCOM_EINVAL;
5293 break;
5294
5295 case VPPCOM_ATTR_SET_TCP_NODELAY:
5296 if (buffer && buflen && (*buflen == sizeof (int)))
5297 {
5298 /* VPP-TBD */
5299 if (*(int *) buffer)
5300 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_TCP_NODELAY);
5301 else
5302 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_TCP_NODELAY);
5303
5304 if (VPPCOM_DEBUG > 2)
5305 clib_warning ("VCL<%d>: VPPCOM_ATTR_SET_TCP_NODELAY: %d, "
5306 "buflen %d, #VPP-TBD#", getpid (),
5307 VCL_SESS_ATTR_TEST (session->attr,
5308 VCL_SESS_ATTR_TCP_NODELAY),
5309 *buflen);
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005310 if (VPPCOM_DEBUG > 0)
5311 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08005312 /* *INDENT-OFF* */
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005313 ELOG_TYPE_DECLARE (e) =
5314 {
5315 .format = "VPPCOM_ATTR_SET_TCP_NODELAY: %d buflen=%d",
5316 .format_args = "i4i4",
5317 };
5318
5319 struct {
5320 u32 data[2];
5321 } * ed;
5322
5323 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
5324 ed->data[0] = VCL_SESS_ATTR_TEST (session->attr,
5325 VCL_SESS_ATTR_TCP_NODELAY);
5326 ed->data[1] = *buflen;
5327 /* *INDENT-ON* */
5328 }
Dave Wallace048b1d62018-01-03 22:24:41 -05005329 }
5330 else
5331 rv = VPPCOM_EINVAL;
5332 break;
5333
5334 case VPPCOM_ATTR_GET_TCP_KEEPIDLE:
5335 if (buffer && buflen && (*buflen >= sizeof (int)))
5336 {
5337 /* VPP-TBD */
5338 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
5339 VCL_SESS_ATTR_TCP_KEEPIDLE);
5340 *buflen = sizeof (int);
5341
5342 if (VPPCOM_DEBUG > 2)
5343 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_TCP_KEEPIDLE: %d, "
5344 "buflen %d, #VPP-TBD#", getpid (), *(int *) buffer,
5345 *buflen);
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005346 if (VPPCOM_DEBUG > 0)
5347 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08005348 /* *INDENT-OFF* */
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005349 ELOG_TYPE_DECLARE (e) =
5350 {
5351 .format = "VPPCOM_ATTR_GET_TCP_KEEPIDLE: %d buflen=%d",
5352 .format_args = "i4i4",
5353 };
5354
5355 struct {
5356 u32 data[2];
5357 } * ed;
5358
5359 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
5360 ed->data[0] = *(int *) buffer;
5361 ed->data[1] = *buflen;
5362 /* *INDENT-ON* */
5363 }
Dave Wallace048b1d62018-01-03 22:24:41 -05005364 }
5365 else
5366 rv = VPPCOM_EINVAL;
Stevenbccd3392017-10-12 20:42:21 -07005367 break;
5368
5369 case VPPCOM_ATTR_SET_TCP_KEEPIDLE:
Dave Wallace048b1d62018-01-03 22:24:41 -05005370 if (buffer && buflen && (*buflen == sizeof (int)))
5371 {
5372 /* VPP-TBD */
5373 if (*(int *) buffer)
5374 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_TCP_KEEPIDLE);
5375 else
5376 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_TCP_KEEPIDLE);
5377
5378 if (VPPCOM_DEBUG > 2)
5379 clib_warning ("VCL<%d>: VPPCOM_ATTR_SET_TCP_KEEPIDLE: %d, "
5380 "buflen %d, #VPP-TBD#", getpid (),
5381 VCL_SESS_ATTR_TEST (session->attr,
5382 VCL_SESS_ATTR_TCP_KEEPIDLE),
5383 *buflen);
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005384 if (VPPCOM_DEBUG > 0)
5385 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08005386 /* *INDENT-OFF* */
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005387 ELOG_TYPE_DECLARE (e) =
5388 {
5389 .format = "VPPCOM_ATTR_SET_TCP_KEEPIDLE: %d buflen=%d",
5390 .format_args = "i4i4",
5391 };
5392
5393 struct {
5394 u32 data[2];
5395 } * ed;
5396
5397 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
5398 ed->data[0] = VCL_SESS_ATTR_TEST (session->attr,
5399 VCL_SESS_ATTR_TCP_KEEPIDLE);
5400 ed->data[1] = *buflen;
5401 /* *INDENT-ON* */
5402 }
Dave Wallace048b1d62018-01-03 22:24:41 -05005403 }
5404 else
5405 rv = VPPCOM_EINVAL;
5406 break;
5407
5408 case VPPCOM_ATTR_GET_TCP_KEEPINTVL:
5409 if (buffer && buflen && (*buflen >= sizeof (int)))
5410 {
5411 /* VPP-TBD */
5412 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
5413 VCL_SESS_ATTR_TCP_KEEPINTVL);
5414 *buflen = sizeof (int);
5415
5416 if (VPPCOM_DEBUG > 2)
5417 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_TCP_KEEPINTVL: %d, "
5418 "buflen %d, #VPP-TBD#", getpid (), *(int *) buffer,
5419 *buflen);
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005420 if (VPPCOM_DEBUG > 0)
5421 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08005422 /* *INDENT-OFF* */
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005423 ELOG_TYPE_DECLARE (e) =
5424 {
5425 .format = "VPPCOM_ATTR_GET_TCP_KEEPIDLE: %d buflen=%d",
5426 .format_args = "i4i4",
5427 };
5428
5429 struct {
5430 u32 data[2];
5431 } * ed;
5432
5433 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
5434 ed->data[0] = *(int *) buffer;
5435 ed->data[1] = *buflen;
5436 /* *INDENT-ON* */
5437 }
Dave Wallace048b1d62018-01-03 22:24:41 -05005438 }
5439 else
5440 rv = VPPCOM_EINVAL;
Stevenbccd3392017-10-12 20:42:21 -07005441 break;
5442
5443 case VPPCOM_ATTR_SET_TCP_KEEPINTVL:
Dave Wallace048b1d62018-01-03 22:24:41 -05005444 if (buffer && buflen && (*buflen == sizeof (int)))
5445 {
5446 /* VPP-TBD */
5447 if (*(int *) buffer)
5448 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_TCP_KEEPINTVL);
5449 else
5450 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_TCP_KEEPINTVL);
5451
5452 if (VPPCOM_DEBUG > 2)
5453 clib_warning ("VCL<%d>: VPPCOM_ATTR_SET_TCP_KEEPINTVL: %d, "
5454 "buflen %d, #VPP-TBD#", getpid (),
5455 VCL_SESS_ATTR_TEST (session->attr,
5456 VCL_SESS_ATTR_TCP_KEEPINTVL),
5457 *buflen);
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005458 if (VPPCOM_DEBUG > 0)
5459 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08005460 /* *INDENT-OFF* */
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005461 ELOG_TYPE_DECLARE (e) =
5462 {
5463 .format = "VPPCOM_ATTR_SET_TCP_KEEPINTVL: %d buflen=%d",
5464 .format_args = "i4i4",
5465 };
5466
5467 struct {
5468 u32 data[2];
5469 } * ed;
5470
5471 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
5472 ed->data[0] = VCL_SESS_ATTR_TEST (session->attr,
5473 VCL_SESS_ATTR_TCP_KEEPINTVL);
5474 ed->data[1] = *buflen;
5475 /* *INDENT-ON* */
5476 }
Dave Wallace048b1d62018-01-03 22:24:41 -05005477 }
5478 else
5479 rv = VPPCOM_EINVAL;
5480 break;
5481
5482 case VPPCOM_ATTR_GET_TCP_USER_MSS:
5483 if (buffer && buflen && (*buflen >= sizeof (u32)))
5484 {
5485 /* VPP-TBD */
5486 *(u32 *) buffer = session->user_mss;
5487 *buflen = sizeof (int);
5488
5489 if (VPPCOM_DEBUG > 2)
5490 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_TCP_USER_MSS: %d, "
5491 "buflen %d, #VPP-TBD#", getpid (), *(int *) buffer,
5492 *buflen);
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005493 if (VPPCOM_DEBUG > 0)
5494 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08005495 /* *INDENT-OFF* */
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005496 ELOG_TYPE_DECLARE (e) =
5497 {
5498 .format = "VPPCOM_ATTR_GET_TCP_USER_MSS: %d buflen=%d",
5499 .format_args = "i4i4",
5500 };
5501
5502 struct {
5503 u32 data[2];
5504 } * ed;
5505
5506 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
5507 ed->data[0] = *(int *) buffer;
5508 ed->data[1] = *buflen;
5509 /* *INDENT-ON* */
5510 }
Dave Wallace048b1d62018-01-03 22:24:41 -05005511 }
5512 else
5513 rv = VPPCOM_EINVAL;
5514 break;
5515
5516 case VPPCOM_ATTR_SET_TCP_USER_MSS:
5517 if (buffer && buflen && (*buflen == sizeof (u32)))
5518 {
5519 /* VPP-TBD */
5520 session->user_mss = *(u32 *) buffer;
5521
5522 if (VPPCOM_DEBUG > 2)
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005523 clib_warning ("VCL<%d>: VPPCOM_ATTR_SET_TCP_USER_MSS: %u, "
Dave Wallace048b1d62018-01-03 22:24:41 -05005524 "buflen %d, #VPP-TBD#", getpid (),
5525 session->user_mss, *buflen);
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005526 if (VPPCOM_DEBUG > 0)
5527 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08005528 /* *INDENT-OFF* */
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005529 ELOG_TYPE_DECLARE (e) =
5530 {
5531 .format = "VPPCOM_ATTR_SET_TCP_USER_MSS: %d buflen=%d",
5532 .format_args = "i4i4",
5533 };
5534
5535 struct {
5536 u32 data[2];
5537 } * ed;
5538
5539 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
5540 ed->data[0] = session->user_mss;
5541 ed->data[1] = *buflen;
5542 /* *INDENT-ON* */
5543 }
Dave Wallace048b1d62018-01-03 22:24:41 -05005544 }
5545 else
5546 rv = VPPCOM_EINVAL;
Stevenbccd3392017-10-12 20:42:21 -07005547 break;
Dave Wallacee22aa742017-10-20 12:30:38 -04005548
5549 default:
5550 rv = VPPCOM_EINVAL;
5551 break;
Dave Wallace35830af2017-10-09 01:43:42 -04005552 }
5553
5554done:
5555 clib_spinlock_unlock (&vcm->sessions_lockp);
5556 return rv;
5557}
5558
Stevenac1f96d2017-10-24 16:03:58 -07005559int
5560vppcom_session_recvfrom (uint32_t session_index, void *buffer,
5561 uint32_t buflen, int flags, vppcom_endpt_t * ep)
5562{
Stevenac1f96d2017-10-24 16:03:58 -07005563 int rv = VPPCOM_OK;
5564 session_t *session = 0;
5565
5566 if (ep)
5567 {
5568 clib_spinlock_lock (&vcm->sessions_lockp);
5569 rv = vppcom_session_at_index (session_index, &session);
5570 if (PREDICT_FALSE (rv))
5571 {
5572 clib_spinlock_unlock (&vcm->sessions_lockp);
5573 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05005574 clib_warning ("VCL<%d>: invalid session, "
5575 "sid (%u) has been closed!",
Dave Wallace2e005bb2017-11-07 01:21:39 -05005576 getpid (), session_index);
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005577 if (VPPCOM_DEBUG > 0)
5578 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08005579 /* *INDENT-OFF* */
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005580 ELOG_TYPE_DECLARE (e) =
5581 {
5582 .format = "invalid session: %d closed",
5583 .format_args = "i4",
5584 };
5585
5586 struct {
5587 u32 data;
5588 } * ed;
5589
5590 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, vcm->elog_track);
5591 ed->data = session_index;
5592 /* *INDENT-ON* */
5593 }
Dave Wallacefaf9d772017-10-26 16:12:04 -04005594 rv = VPPCOM_EBADFD;
5595 clib_spinlock_unlock (&vcm->sessions_lockp);
5596 goto done;
Stevenac1f96d2017-10-24 16:03:58 -07005597 }
Stevenac1f96d2017-10-24 16:03:58 -07005598 ep->is_ip4 = session->peer_addr.is_ip4;
5599 ep->port = session->peer_port;
5600 if (session->peer_addr.is_ip4)
5601 clib_memcpy (ep->ip, &session->peer_addr.ip46.ip4,
5602 sizeof (ip4_address_t));
5603 else
5604 clib_memcpy (ep->ip, &session->peer_addr.ip46.ip6,
5605 sizeof (ip6_address_t));
5606 clib_spinlock_unlock (&vcm->sessions_lockp);
Stevenac1f96d2017-10-24 16:03:58 -07005607 }
Steven58f464e2017-10-25 12:33:12 -07005608
5609 if (flags == 0)
Stevenac1f96d2017-10-24 16:03:58 -07005610 rv = vppcom_session_read (session_index, buffer, buflen);
5611 else if (flags & MSG_PEEK)
Steven58f464e2017-10-25 12:33:12 -07005612 rv = vppcom_session_peek (session_index, buffer, buflen);
Stevenac1f96d2017-10-24 16:03:58 -07005613 else
5614 {
Dave Wallace048b1d62018-01-03 22:24:41 -05005615 clib_warning ("VCL<%d>: Unsupport flags for recvfrom %d",
5616 getpid (), flags);
Stevenac1f96d2017-10-24 16:03:58 -07005617 rv = VPPCOM_EAFNOSUPPORT;
5618 }
5619
Dave Wallacefaf9d772017-10-26 16:12:04 -04005620done:
Stevenac1f96d2017-10-24 16:03:58 -07005621 return rv;
5622}
5623
5624int
5625vppcom_session_sendto (uint32_t session_index, void *buffer,
5626 uint32_t buflen, int flags, vppcom_endpt_t * ep)
5627{
Dave Wallace617dffa2017-10-26 14:47:06 -04005628 if (!buffer)
5629 return VPPCOM_EINVAL;
5630
5631 if (ep)
5632 {
5633 // TBD
5634 return VPPCOM_EINVAL;
5635 }
5636
5637 if (flags)
5638 {
5639 // TBD check the flags and do the right thing
5640 if (VPPCOM_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05005641 clib_warning ("VCL<%d>: handling flags 0x%u (%d) "
5642 "not implemented yet.", getpid (), flags, flags);
Dave Wallace617dffa2017-10-26 14:47:06 -04005643 }
5644
5645 return (vppcom_session_write (session_index, buffer, buflen));
Stevenac1f96d2017-10-24 16:03:58 -07005646}
5647
Dave Wallace048b1d62018-01-03 22:24:41 -05005648int
5649vppcom_poll (vcl_poll_t * vp, uint32_t n_sids, double wait_for_time)
5650{
5651 f64 timeout = clib_time_now (&vcm->clib_time) + wait_for_time;
5652 u32 i, keep_trying = 1;
5653 int rv, num_ev = 0;
5654
5655 if (VPPCOM_DEBUG > 3)
5656 clib_warning ("VCL<%d>: vp %p, nsids %u, wait_for_time %f",
5657 getpid (), vp, n_sids, wait_for_time);
5658
5659 if (!vp)
5660 return VPPCOM_EFAULT;
5661
5662 do
5663 {
5664 session_t *session;
5665
5666 for (i = 0; i < n_sids; i++)
5667 {
5668 ASSERT (vp[i].revents);
5669
5670 VCL_LOCK_AND_GET_SESSION (vp[i].sid, &session);
5671 clib_spinlock_unlock (&vcm->sessions_lockp);
5672
5673 if (*vp[i].revents)
5674 *vp[i].revents = 0;
5675
5676 if (POLLIN & vp[i].events)
5677 {
5678 VCL_LOCK_AND_GET_SESSION (vp[i].sid, &session);
5679 rv = vppcom_session_read_ready (session, vp[i].sid);
5680 clib_spinlock_unlock (&vcm->sessions_lockp);
5681 if (rv > 0)
5682 {
5683 *vp[i].revents |= POLLIN;
5684 num_ev++;
5685 }
5686 else if (rv < 0)
5687 {
5688 switch (rv)
5689 {
5690 case VPPCOM_ECONNRESET:
5691 *vp[i].revents = POLLHUP;
5692 break;
5693
5694 default:
5695 *vp[i].revents = POLLERR;
5696 break;
5697 }
5698 num_ev++;
5699 }
5700 }
5701
5702 if (POLLOUT & vp[i].events)
5703 {
5704 VCL_LOCK_AND_GET_SESSION (vp[i].sid, &session);
5705 rv = vppcom_session_write_ready (session, vp[i].sid);
5706 clib_spinlock_unlock (&vcm->sessions_lockp);
5707 if (rv > 0)
5708 {
5709 *vp[i].revents |= POLLOUT;
5710 num_ev++;
5711 }
5712 else if (rv < 0)
5713 {
5714 switch (rv)
5715 {
5716 case VPPCOM_ECONNRESET:
5717 *vp[i].revents = POLLHUP;
5718 break;
5719
5720 default:
5721 *vp[i].revents = POLLERR;
5722 break;
5723 }
5724 num_ev++;
5725 }
5726 }
5727
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08005728 if (0) // Note "done:" label used by VCL_LOCK_AND_GET_SESSION()
Dave Wallace048b1d62018-01-03 22:24:41 -05005729 {
5730 done:
5731 *vp[i].revents = POLLNVAL;
5732 num_ev++;
5733 }
5734 }
5735 if (wait_for_time != -1)
5736 keep_trying = (clib_time_now (&vcm->clib_time) <= timeout) ? 1 : 0;
5737 }
5738 while ((num_ev == 0) && keep_trying);
5739
5740 if (VPPCOM_DEBUG > 3)
5741 {
5742 clib_warning ("VCL<%d>: returning %d", getpid (), num_ev);
5743 for (i = 0; i < n_sids; i++)
5744 {
5745 clib_warning ("VCL<%d>: vp[%d].sid %d (0x%x), .events 0x%x, "
5746 ".revents 0x%x", getpid (), i, vp[i].sid, vp[i].sid,
5747 vp[i].events, *vp[i].revents);
5748 }
5749 }
5750 return num_ev;
5751}
5752
Dave Wallacee22aa742017-10-20 12:30:38 -04005753/*
5754 * fd.io coding-style-patch-verification: ON
5755 *
5756 * Local Variables:
5757 * eval: (c-set-style "gnu")
5758 * End:
5759 */