blob: 58de9aeea228659f292bf8909fc76c7dcad0b29b [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;
1210 clib_memcpy (&session->lcl_addr.ip46, mp->lcl_ip,
1211 sizeof (session->peer_addr.ip46));
1212 session->lcl_port = mp->lcl_port;
1213 vppcom_session_table_add_listener (mp->handle, session_index);
Dave Wallaceee45d412017-11-24 21:44:06 -05001214 session->state = STATE_LISTEN;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001215
Dave Wallaceee45d412017-11-24 21:44:06 -05001216 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05001217 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: bind succeeded!",
Dave Wallaceee45d412017-11-24 21:44:06 -05001218 getpid (), mp->handle, mp->context);
1219done_unlock:
Dave Wallace543852a2017-08-03 02:11:34 -04001220 clib_spinlock_unlock (&vcm->sessions_lockp);
1221}
1222
1223static void
1224vl_api_unbind_sock_reply_t_handler (vl_api_unbind_sock_reply_t * mp)
1225{
Dave Wallace4878cbe2017-11-21 03:45:09 -05001226 if (mp->retval)
Dave Wallace048b1d62018-01-03 22:24:41 -05001227 clib_warning ("VCL<%d>: ERROR: sid %u: unbind failed: %U",
Dave Wallace4878cbe2017-11-21 03:45:09 -05001228 getpid (), mp->context, format_api_error,
1229 ntohl (mp->retval));
Dave Wallace543852a2017-08-03 02:11:34 -04001230
Dave Wallace4878cbe2017-11-21 03:45:09 -05001231 else if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05001232 clib_warning ("VCL<%d>: sid %u: unbind succeeded!",
1233 getpid (), mp->context);
Dave Wallace543852a2017-08-03 02:11:34 -04001234}
1235
1236u8 *
1237format_ip4_address (u8 * s, va_list * args)
1238{
1239 u8 *a = va_arg (*args, u8 *);
1240 return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
1241}
1242
1243u8 *
1244format_ip6_address (u8 * s, va_list * args)
1245{
1246 ip6_address_t *a = va_arg (*args, ip6_address_t *);
1247 u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
1248
1249 i_max_n_zero = ARRAY_LEN (a->as_u16);
1250 max_n_zeros = 0;
1251 i_first_zero = i_max_n_zero;
1252 n_zeros = 0;
1253 for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
1254 {
1255 u32 is_zero = a->as_u16[i] == 0;
1256 if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
1257 {
1258 i_first_zero = i;
1259 n_zeros = 0;
1260 }
1261 n_zeros += is_zero;
1262 if ((!is_zero && n_zeros > max_n_zeros)
1263 || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
1264 {
1265 i_max_n_zero = i_first_zero;
1266 max_n_zeros = n_zeros;
1267 i_first_zero = ARRAY_LEN (a->as_u16);
1268 n_zeros = 0;
1269 }
1270 }
1271
1272 last_double_colon = 0;
1273 for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
1274 {
1275 if (i == i_max_n_zero && max_n_zeros > 1)
1276 {
1277 s = format (s, "::");
1278 i += max_n_zeros - 1;
1279 last_double_colon = 1;
1280 }
1281 else
1282 {
1283 s = format (s, "%s%x",
1284 (last_double_colon || i == 0) ? "" : ":",
1285 clib_net_to_host_u16 (a->as_u16[i]));
1286 last_double_colon = 0;
1287 }
1288 }
1289
1290 return s;
1291}
1292
1293/* Format an IP46 address. */
1294u8 *
1295format_ip46_address (u8 * s, va_list * args)
1296{
1297 ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
1298 ip46_type_t type = va_arg (*args, ip46_type_t);
1299 int is_ip4 = 1;
1300
1301 switch (type)
1302 {
1303 case IP46_TYPE_ANY:
1304 is_ip4 = ip46_address_is_ip4 (ip46);
1305 break;
1306 case IP46_TYPE_IP4:
1307 is_ip4 = 1;
1308 break;
1309 case IP46_TYPE_IP6:
1310 is_ip4 = 0;
1311 break;
1312 }
1313
1314 return is_ip4 ?
1315 format (s, "%U", format_ip4_address, &ip46->ip4) :
1316 format (s, "%U", format_ip6_address, &ip46->ip6);
1317}
1318
1319static void
1320vl_api_accept_session_t_handler (vl_api_accept_session_t * mp)
1321{
Dave Wallace543852a2017-08-03 02:11:34 -04001322 svm_fifo_t *rx_fifo, *tx_fifo;
Florin Corasdcf55ce2017-11-16 15:32:50 -08001323 session_t *session, *listen_session;
Dave Wallace543852a2017-08-03 02:11:34 -04001324 u32 session_index;
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001325 vce_event_connect_request_t *ecr;
1326 vce_event_t *ev;
1327 int rv;
1328 u32 ev_idx;
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08001329 uword elts = 0;
Dave Wallace543852a2017-08-03 02:11:34 -04001330
Dave Wallace60caa062017-11-10 17:07:13 -05001331 clib_spinlock_lock (&vcm->sessions_lockp);
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08001332
1333 clib_spinlock_lock (&vcm->session_fifo_lockp);
1334 elts = clib_fifo_free_elts (vcm->client_session_index_fifo);
1335 clib_spinlock_unlock (&vcm->session_fifo_lockp);
1336
1337 if (!elts)
Dave Wallace543852a2017-08-03 02:11:34 -04001338 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001339 clib_warning ("VCL<%d>: client session queue is full!", getpid ());
Dave Wallaced2931962017-11-25 04:17:39 -05001340 vppcom_send_accept_session_reply (mp->handle, mp->context,
Florin Corasdcf55ce2017-11-16 15:32:50 -08001341 VNET_API_ERROR_QUEUE_FULL);
1342 clib_spinlock_unlock (&vcm->sessions_lockp);
1343 return;
1344 }
1345
1346 listen_session = vppcom_session_table_lookup_listener (mp->listener_handle);
1347 if (!listen_session)
1348 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001349 clib_warning ("VCL<%d>: ERROR: couldn't find listen session: "
1350 "unknown vpp listener handle %llx",
1351 getpid (), mp->listener_handle);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001352 vppcom_send_accept_session_reply (mp->handle, mp->context,
1353 VNET_API_ERROR_INVALID_ARGUMENT);
Dave Wallace60caa062017-11-10 17:07:13 -05001354 clib_spinlock_unlock (&vcm->sessions_lockp);
1355 return;
Dave Wallace543852a2017-08-03 02:11:34 -04001356 }
1357
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001358 /* TODO check listener depth and update */
1359 /* TODO on "child" fd close, update listener depth */
1360
Dave Wallace543852a2017-08-03 02:11:34 -04001361 /* Allocate local session and set it up */
1362 pool_get (vcm->sessions, session);
1363 memset (session, 0, sizeof (*session));
1364 session_index = session - vcm->sessions;
1365
1366 rx_fifo = uword_to_pointer (mp->server_rx_fifo, svm_fifo_t *);
1367 rx_fifo->client_session_index = session_index;
1368 tx_fifo = uword_to_pointer (mp->server_tx_fifo, svm_fifo_t *);
1369 tx_fifo->client_session_index = session_index;
1370
Dave Wallace60caa062017-11-10 17:07:13 -05001371 session->vpp_handle = mp->handle;
Dave Wallaced2931962017-11-25 04:17:39 -05001372 session->client_context = mp->context;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001373 session->rx_fifo = rx_fifo;
1374 session->tx_fifo = tx_fifo;
Dave Wallace33e002b2017-09-06 01:20:02 -04001375 session->vpp_event_queue = uword_to_pointer (mp->vpp_event_queue_address,
Florin Corase86a8ed2018-01-05 03:20:25 -08001376 svm_queue_t *);
Dave Wallace543852a2017-08-03 02:11:34 -04001377 session->state = STATE_ACCEPT;
Stevenac1f96d2017-10-24 16:03:58 -07001378 session->peer_port = mp->port;
Dave Wallace35830af2017-10-09 01:43:42 -04001379 session->peer_addr.is_ip4 = mp->is_ip4;
1380 clib_memcpy (&session->peer_addr.ip46, mp->ip,
1381 sizeof (session->peer_addr.ip46));
Dave Wallace543852a2017-08-03 02:11:34 -04001382
1383 /* Add it to lookup table */
1384 hash_set (vcm->session_index_by_vpp_handles, mp->handle, session_index);
Florin Corasdcf55ce2017-11-16 15:32:50 -08001385 session->lcl_port = listen_session->lcl_port;
1386 session->lcl_addr = listen_session->lcl_addr;
Dave Wallace227867f2017-11-13 21:21:53 -05001387
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001388 /* Create an event for handlers */
1389
1390 clib_spinlock_lock (&vcm->event_thread.events_lockp);
1391
1392 pool_get (vcm->event_thread.vce_events, ev);
1393 ev->data = clib_mem_alloc (sizeof (vce_event_connect_request_t));
1394 ev->refcnt = 0;
1395 ev_idx = (u32) (ev - vcm->event_thread.vce_events);
1396 ecr = ev->data;
1397 ev->evk.eid = VCL_EVENT_CONNECT_REQ_ACCEPTED;
1398 listen_session = vppcom_session_table_lookup_listener (mp->listener_handle);
1399 ev->evk.session_index = (u32) (listen_session - vcm->sessions);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001400 ecr->accepted_session_index = session_index;
1401
1402 clib_spinlock_unlock (&vcm->event_thread.events_lockp);
1403
1404 rv = vce_generate_event (&vcm->event_thread, ev_idx);
1405
1406 ASSERT (rv == 0);
Florin Corasdcf55ce2017-11-16 15:32:50 -08001407
Dave Wallace60caa062017-11-10 17:07:13 -05001408 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05001409 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: client accept "
Florin Coras50e8bdb2017-11-27 10:37:05 -08001410 "request from %s address %U port %d queue %p!", getpid (),
Dave Wallaced2931962017-11-25 04:17:39 -05001411 mp->handle, session_index, mp->is_ip4 ? "IPv4" : "IPv6",
1412 format_ip46_address, &mp->ip, mp->is_ip4,
Florin Coras50e8bdb2017-11-27 10:37:05 -08001413 clib_net_to_host_u16 (mp->port), session->vpp_event_queue);
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08001414
1415 if (VPPCOM_DEBUG > 0)
1416 {
1417 session->elog_track.name =
1418 (char *) format (0, "C:%d:S:%d%c", vcm->my_client_index,
1419 session_index, 0);
1420 elog_track_register (&vcm->elog_main, &session->elog_track);
1421
1422 if (session->peer_addr.is_ip4)
1423 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08001424 /* *INDENT-OFF* */
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08001425 ELOG_TYPE_DECLARE (e) =
1426 {
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08001427 .format =
1428 "client_accept:handle:%x addr:%d.%d.%d.%d:%d",
1429 .format_args = "i8i1i1i1i1i2",
1430 };
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08001431
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08001432 CLIB_PACKED (struct {
1433 u64 handle; //8
1434 u8 addr[4]; //4
1435 u16 port; //2
1436 }) * ed;
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08001437
1438 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
1439
1440 ed->handle = mp->handle;
1441 ed->addr[0] = session->peer_addr.ip46.ip4.as_u8[0];
1442 ed->addr[1] = session->peer_addr.ip46.ip4.as_u8[1];
1443 ed->addr[2] = session->peer_addr.ip46.ip4.as_u8[2];
1444 ed->addr[3] = session->peer_addr.ip46.ip4.as_u8[3];
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08001445 ed->port = clib_net_to_host_u16 (session->peer_port);
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08001446 /* *INDENT-ON* */
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08001447 }
1448 else
1449 {
1450 clib_warning ("ip6");
1451 }
1452 }
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08001453
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001454 clib_spinlock_unlock (&vcm->sessions_lockp);
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08001455
Dave Wallace60caa062017-11-10 17:07:13 -05001456}
1457
1458static void
Dave Wallace4878cbe2017-11-21 03:45:09 -05001459vppcom_send_bind_sock (session_t * session, u32 session_index)
Dave Wallace543852a2017-08-03 02:11:34 -04001460{
Dave Wallace543852a2017-08-03 02:11:34 -04001461 vl_api_bind_sock_t *bmp;
1462
1463 /* Assumes caller has acquired spinlock: vcm->sessions_lockp */
Dave Wallace543852a2017-08-03 02:11:34 -04001464 bmp = vl_msg_api_alloc (sizeof (*bmp));
1465 memset (bmp, 0, sizeof (*bmp));
1466
1467 bmp->_vl_msg_id = ntohs (VL_API_BIND_SOCK);
1468 bmp->client_index = vcm->my_client_index;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001469 bmp->context = session_index;
Dave Wallace35830af2017-10-09 01:43:42 -04001470 bmp->is_ip4 = session->lcl_addr.is_ip4;
1471 clib_memcpy (bmp->ip, &session->lcl_addr.ip46, sizeof (bmp->ip));
Stevenac1f96d2017-10-24 16:03:58 -07001472 bmp->port = session->lcl_port;
Dave Wallace543852a2017-08-03 02:11:34 -04001473 bmp->proto = session->proto;
1474 clib_memcpy (bmp->options, session->options, sizeof (bmp->options));
1475 vl_msg_api_send_shmem (vcm->vl_input_queue, (u8 *) & bmp);
1476}
1477
1478static void
Dave Wallace4878cbe2017-11-21 03:45:09 -05001479vppcom_send_unbind_sock (u64 vpp_handle)
Dave Wallace543852a2017-08-03 02:11:34 -04001480{
Dave Wallace543852a2017-08-03 02:11:34 -04001481 vl_api_unbind_sock_t *ump;
Dave Wallace543852a2017-08-03 02:11:34 -04001482
1483 ump = vl_msg_api_alloc (sizeof (*ump));
1484 memset (ump, 0, sizeof (*ump));
1485
1486 ump->_vl_msg_id = ntohs (VL_API_UNBIND_SOCK);
1487 ump->client_index = vcm->my_client_index;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001488 ump->handle = vpp_handle;
Dave Wallace543852a2017-08-03 02:11:34 -04001489 vl_msg_api_send_shmem (vcm->vl_input_queue, (u8 *) & ump);
1490}
1491
1492static int
Dave Wallace543852a2017-08-03 02:11:34 -04001493vppcom_session_unbind (u32 session_index)
1494{
Dave Wallace4878cbe2017-11-21 03:45:09 -05001495 session_t *session = 0;
Dave Wallace543852a2017-08-03 02:11:34 -04001496 int rv;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001497 u64 vpp_handle;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001498 elog_track_t session_elog_track;
Dave Wallace543852a2017-08-03 02:11:34 -04001499
Dave Wallace4878cbe2017-11-21 03:45:09 -05001500 VCL_LOCK_AND_GET_SESSION (session_index, &session);
1501
1502 vpp_handle = session->vpp_handle;
1503 vppcom_session_table_del_listener (vpp_handle);
1504 session->vpp_handle = ~0;
1505 session->state = STATE_DISCONNECT;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001506 session_elog_track = session->elog_track;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001507
Dave Wallace543852a2017-08-03 02:11:34 -04001508 clib_spinlock_unlock (&vcm->sessions_lockp);
1509
Dave Wallace4878cbe2017-11-21 03:45:09 -05001510 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05001511 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
Dave Wallace4878cbe2017-11-21 03:45:09 -05001512 "sending unbind msg! new state 0x%x (%s)",
1513 getpid (), vpp_handle, session_index,
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001514 STATE_DISCONNECT,
1515 vppcom_session_state_str (STATE_DISCONNECT));
Dave Wallace4878cbe2017-11-21 03:45:09 -05001516
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08001517 if (VPPCOM_DEBUG > 0)
1518 {
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08001519 /* *INDENT-OFF* */
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08001520 ELOG_TYPE_DECLARE (e) =
1521 {
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08001522 .format = "unbind: handle:%x",
1523 .format_args = "i8",
1524 };
1525
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08001526 struct
1527 {
1528 u64 handle;
1529 } *ed;
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08001530
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001531 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session_elog_track);
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08001532 ed->handle = vpp_handle;
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08001533 /* *INDENT-ON* */
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08001534 }
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001535
Dave Wallace4878cbe2017-11-21 03:45:09 -05001536 vppcom_send_unbind_sock (vpp_handle);
1537
1538done:
1539 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04001540}
1541
Dave Wallace66cf6eb2017-10-26 02:51:07 -04001542static inline int
Dave Wallace543852a2017-08-03 02:11:34 -04001543vppcom_session_disconnect (u32 session_index)
1544{
Dave Wallace543852a2017-08-03 02:11:34 -04001545 int rv;
Dave Wallace66cf6eb2017-10-26 02:51:07 -04001546 session_t *session;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001547 u64 vpp_handle;
1548 session_state_t state;
Dave Wallace543852a2017-08-03 02:11:34 -04001549
Dave Wallace4878cbe2017-11-21 03:45:09 -05001550 VCL_LOCK_AND_GET_SESSION (session_index, &session);
1551
1552 vpp_handle = session->vpp_handle;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001553 state = session->state;
1554 clib_spinlock_unlock (&vcm->sessions_lockp);
1555
1556 if (VPPCOM_DEBUG > 1)
Dave Wallace543852a2017-08-03 02:11:34 -04001557 {
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001558 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u "
1559 "state 0x%x (%s)",
Dave Wallace4878cbe2017-11-21 03:45:09 -05001560 getpid (), vpp_handle, session_index,
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001561 state, vppcom_session_state_str (state));
Dave Wallace543852a2017-08-03 02:11:34 -04001562 }
Dave Wallace66cf6eb2017-10-26 02:51:07 -04001563
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001564 if (PREDICT_FALSE (state & STATE_LISTEN))
Dave Wallace66cf6eb2017-10-26 02:51:07 -04001565 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001566 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -05001567 "Cannot disconnect a listen socket!",
1568 getpid (), vpp_handle, session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001569 rv = VPPCOM_EBADFD;
1570 goto done;
1571 }
Dave Wallace66cf6eb2017-10-26 02:51:07 -04001572
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001573 /* The peer has already initiated the close,
1574 * so send the disconnect session reply.
Dave Wallace4878cbe2017-11-21 03:45:09 -05001575 */
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001576 if (state & STATE_CLOSE_ON_EMPTY)
Dave Wallace4878cbe2017-11-21 03:45:09 -05001577 {
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001578 //XXX alagalah - Check and drain here?
1579 vppcom_send_disconnect_session_reply (vpp_handle,
1580 session_index, 0 /* rv */ );
1581 if (VPPCOM_DEBUG > 1)
1582 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
1583 "sending disconnect REPLY...",
1584 getpid (), vpp_handle, session_index);
Dave Wallace66cf6eb2017-10-26 02:51:07 -04001585 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05001586
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001587 /* Otherwise, send a disconnect session msg...
Dave Wallace4878cbe2017-11-21 03:45:09 -05001588 */
Dave Wallace66cf6eb2017-10-26 02:51:07 -04001589 else
Dave Wallace227867f2017-11-13 21:21:53 -05001590 {
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001591 if (VPPCOM_DEBUG > 1)
1592 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
1593 "sending disconnect...",
1594 getpid (), vpp_handle, session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001595
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001596 vppcom_send_disconnect_session (vpp_handle, session_index);
Dave Wallace227867f2017-11-13 21:21:53 -05001597 }
Dave Wallace66cf6eb2017-10-26 02:51:07 -04001598
Dave Wallace4878cbe2017-11-21 03:45:09 -05001599done:
1600 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04001601}
1602
1603#define foreach_sock_msg \
1604_(SESSION_ENABLE_DISABLE_REPLY, session_enable_disable_reply) \
1605_(BIND_SOCK_REPLY, bind_sock_reply) \
1606_(UNBIND_SOCK_REPLY, unbind_sock_reply) \
1607_(ACCEPT_SESSION, accept_session) \
Dave Wallace33e002b2017-09-06 01:20:02 -04001608_(CONNECT_SESSION_REPLY, connect_session_reply) \
Dave Wallace543852a2017-08-03 02:11:34 -04001609_(DISCONNECT_SESSION, disconnect_session) \
1610_(DISCONNECT_SESSION_REPLY, disconnect_session_reply) \
1611_(RESET_SESSION, reset_session) \
1612_(APPLICATION_ATTACH_REPLY, application_attach_reply) \
1613_(APPLICATION_DETACH_REPLY, application_detach_reply) \
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001614_(MAP_ANOTHER_SEGMENT, map_another_segment) \
1615_(UNMAP_SEGMENT, unmap_segment)
Dave Wallace543852a2017-08-03 02:11:34 -04001616
1617static void
1618vppcom_api_hookup (void)
1619{
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08001620#define _(N, n) \
Dave Wallace543852a2017-08-03 02:11:34 -04001621 vl_msg_api_set_handlers(VL_API_##N, #n, \
1622 vl_api_##n##_t_handler, \
1623 vl_noop_handler, \
1624 vl_api_##n##_t_endian, \
1625 vl_api_##n##_t_print, \
1626 sizeof(vl_api_##n##_t), 1);
1627 foreach_sock_msg;
1628#undef _
1629}
1630
1631static void
1632vppcom_cfg_init (vppcom_cfg_t * vcl_cfg)
1633{
1634 ASSERT (vcl_cfg);
1635
1636 vcl_cfg->heapsize = (256ULL << 20);
Dave Wallacec8f1ee62017-11-29 22:46:32 -05001637 vcl_cfg->vpp_api_q_length = 1024;
Dave Wallace543852a2017-08-03 02:11:34 -04001638 vcl_cfg->segment_baseva = 0x200000000ULL;
1639 vcl_cfg->segment_size = (256 << 20);
1640 vcl_cfg->add_segment_size = (128 << 20);
1641 vcl_cfg->preallocated_fifo_pairs = 8;
1642 vcl_cfg->rx_fifo_size = (1 << 20);
1643 vcl_cfg->tx_fifo_size = (1 << 20);
1644 vcl_cfg->event_queue_size = 2048;
1645 vcl_cfg->listen_queue_size = CLIB_CACHE_LINE_BYTES / sizeof (u32);
1646 vcl_cfg->app_timeout = 10 * 60.0;
1647 vcl_cfg->session_timeout = 10 * 60.0;
1648 vcl_cfg->accept_timeout = 60.0;
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -08001649 vcl_cfg->event_ring_size = (128 << 10);
1650 vcl_cfg->event_log_path = "/dev/shm";
Dave Wallace543852a2017-08-03 02:11:34 -04001651}
1652
1653static void
1654vppcom_cfg_heapsize (char *conf_fname)
1655{
Dave Wallace543852a2017-08-03 02:11:34 -04001656 vppcom_cfg_t *vcl_cfg = &vcm->cfg;
1657 FILE *fp;
1658 char inbuf[4096];
1659 int argc = 1;
1660 char **argv = NULL;
1661 char *arg = NULL;
1662 char *p;
1663 int i;
1664 u8 *sizep;
1665 u32 size;
Dave Wallace2e005bb2017-11-07 01:21:39 -05001666 void *vcl_mem;
1667 void *heap;
Dave Wallace543852a2017-08-03 02:11:34 -04001668
1669 fp = fopen (conf_fname, "r");
1670 if (fp == NULL)
1671 {
1672 if (VPPCOM_DEBUG > 0)
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05001673 clib_warning ("VCL<%d>: using default heapsize %lld (0x%llx)",
1674 getpid (), vcl_cfg->heapsize, vcl_cfg->heapsize);
Dave Wallace543852a2017-08-03 02:11:34 -04001675 goto defaulted;
1676 }
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05001677
Dave Wallace543852a2017-08-03 02:11:34 -04001678 argv = calloc (1, sizeof (char *));
1679 if (argv == NULL)
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05001680 {
1681 if (VPPCOM_DEBUG > 0)
1682 clib_warning ("VCL<%d>: calloc failed, using default "
1683 "heapsize %lld (0x%llx)",
1684 getpid (), vcl_cfg->heapsize, vcl_cfg->heapsize);
1685 goto defaulted;
1686 }
Dave Wallace543852a2017-08-03 02:11:34 -04001687
1688 while (1)
1689 {
1690 if (fgets (inbuf, 4096, fp) == 0)
1691 break;
1692 p = strtok (inbuf, " \t\n");
1693 while (p != NULL)
1694 {
1695 if (*p == '#')
1696 break;
1697 argc++;
1698 char **tmp = realloc (argv, argc * sizeof (char *));
1699 if (tmp == NULL)
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05001700 {
1701 if (VPPCOM_DEBUG > 0)
1702 clib_warning ("VCL<%d>: realloc failed, "
1703 "using default heapsize %lld (0x%llx)",
1704 getpid (), vcl_cfg->heapsize,
1705 vcl_cfg->heapsize);
1706 goto defaulted;
1707 }
Dave Wallace543852a2017-08-03 02:11:34 -04001708 argv = tmp;
1709 arg = strndup (p, 1024);
1710 if (arg == NULL)
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05001711 {
1712 if (VPPCOM_DEBUG > 0)
1713 clib_warning ("VCL<%d>: strndup failed, "
1714 "using default heapsize %lld (0x%llx)",
1715 getpid (), vcl_cfg->heapsize,
1716 vcl_cfg->heapsize);
1717 goto defaulted;
1718 }
Dave Wallace543852a2017-08-03 02:11:34 -04001719 argv[argc - 1] = arg;
1720 p = strtok (NULL, " \t\n");
1721 }
1722 }
1723
1724 fclose (fp);
Chris Lukeab7b8d92017-09-07 07:40:13 -04001725 fp = NULL;
Dave Wallace543852a2017-08-03 02:11:34 -04001726
1727 char **tmp = realloc (argv, (argc + 1) * sizeof (char *));
1728 if (tmp == NULL)
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05001729 {
1730 if (VPPCOM_DEBUG > 0)
1731 clib_warning ("VCL<%d>: realloc failed, "
1732 "using default heapsize %lld (0x%llx)",
1733 getpid (), vcl_cfg->heapsize, vcl_cfg->heapsize);
1734 goto defaulted;
1735 }
Dave Wallace543852a2017-08-03 02:11:34 -04001736 argv = tmp;
1737 argv[argc] = NULL;
1738
1739 /*
1740 * Look for and parse the "heapsize" config parameter.
1741 * Manual since none of the clib infra has been bootstrapped yet.
1742 *
1743 * Format: heapsize <nn>[mM][gG]
1744 */
1745
1746 for (i = 1; i < (argc - 1); i++)
1747 {
1748 if (!strncmp (argv[i], "heapsize", 8))
1749 {
1750 sizep = (u8 *) argv[i + 1];
1751 size = 0;
1752 while (*sizep >= '0' && *sizep <= '9')
1753 {
1754 size *= 10;
1755 size += *sizep++ - '0';
1756 }
1757 if (size == 0)
1758 {
1759 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001760 clib_warning ("VCL<%d>: parse error '%s %s', "
Dave Wallace543852a2017-08-03 02:11:34 -04001761 "using default heapsize %lld (0x%llx)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05001762 getpid (), argv[i], argv[i + 1],
Dave Wallace543852a2017-08-03 02:11:34 -04001763 vcl_cfg->heapsize, vcl_cfg->heapsize);
1764 goto defaulted;
1765 }
1766
1767 if (*sizep == 'g' || *sizep == 'G')
1768 vcl_cfg->heapsize = size << 30;
1769 else if (*sizep == 'm' || *sizep == 'M')
1770 vcl_cfg->heapsize = size << 20;
1771 else
1772 {
1773 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001774 clib_warning ("VCL<%d>: parse error '%s %s', "
Dave Wallace543852a2017-08-03 02:11:34 -04001775 "using default heapsize %lld (0x%llx)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05001776 getpid (), argv[i], argv[i + 1],
Dave Wallace543852a2017-08-03 02:11:34 -04001777 vcl_cfg->heapsize, vcl_cfg->heapsize);
1778 goto defaulted;
1779 }
1780 }
1781 }
1782
1783defaulted:
Chris Lukeab7b8d92017-09-07 07:40:13 -04001784 if (fp != NULL)
1785 fclose (fp);
1786 if (argv != NULL)
1787 free (argv);
Dave Wallacee7fa24e2017-11-07 13:07:44 -05001788
Dave Wallace2e005bb2017-11-07 01:21:39 -05001789 vcl_mem = mmap (0, vcl_cfg->heapsize, PROT_READ | PROT_WRITE,
1790 MAP_SHARED | MAP_ANONYMOUS, -1, 0);
Steven0cdd5bd2017-11-08 14:14:45 -08001791 if (vcl_mem == MAP_FAILED)
Dave Wallacee7fa24e2017-11-07 13:07:44 -05001792 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001793 clib_unix_error ("VCL<%d>: ERROR: mmap(0, %lld == 0x%llx, "
Dave Wallacee7fa24e2017-11-07 13:07:44 -05001794 "PROT_READ | PROT_WRITE,MAP_SHARED | MAP_ANONYMOUS, "
1795 "-1, 0) failed!",
1796 getpid (), vcl_cfg->heapsize, vcl_cfg->heapsize);
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05001797 ASSERT (vcl_mem != MAP_FAILED);
Dave Wallacee7fa24e2017-11-07 13:07:44 -05001798 return;
1799 }
Dave Wallace2e005bb2017-11-07 01:21:39 -05001800 heap = clib_mem_init (vcl_mem, vcl_cfg->heapsize);
1801 if (!heap)
Dave Wallace2e005bb2017-11-07 01:21:39 -05001802 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001803 clib_warning ("VCL<%d>: ERROR: clib_mem_init() failed!", getpid ());
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05001804 ASSERT (heap);
Dave Wallacee7fa24e2017-11-07 13:07:44 -05001805 return;
Dave Wallace2e005bb2017-11-07 01:21:39 -05001806 }
Dave Wallacee7fa24e2017-11-07 13:07:44 -05001807 vcl_mem = clib_mem_alloc (sizeof (_vppcom_main));
1808 if (!vcl_mem)
1809 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001810 clib_warning ("VCL<%d>: ERROR: clib_mem_alloc() failed!", getpid ());
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05001811 ASSERT (vcl_mem);
Dave Wallacee7fa24e2017-11-07 13:07:44 -05001812 return;
1813 }
1814
1815 clib_memcpy (vcl_mem, &_vppcom_main, sizeof (_vppcom_main));
1816 vcm = vcl_mem;
1817
1818 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001819 clib_warning ("VCL<%d>: allocated VCL heap = %p, size %lld (0x%llx)",
Dave Wallacee7fa24e2017-11-07 13:07:44 -05001820 getpid (), heap, vcl_cfg->heapsize, vcl_cfg->heapsize);
Dave Wallace543852a2017-08-03 02:11:34 -04001821}
1822
1823static void
1824vppcom_cfg_read (char *conf_fname)
1825{
Dave Wallace543852a2017-08-03 02:11:34 -04001826 vppcom_cfg_t *vcl_cfg = &vcm->cfg;
1827 int fd;
1828 unformat_input_t _input, *input = &_input;
1829 unformat_input_t _line_input, *line_input = &_line_input;
1830 u8 vc_cfg_input = 0;
1831 u8 *chroot_path;
1832 struct stat s;
Dave Wallacec8f1ee62017-11-29 22:46:32 -05001833 u32 uid, gid, q_len;
Dave Wallace543852a2017-08-03 02:11:34 -04001834
1835 fd = open (conf_fname, O_RDONLY);
1836 if (fd < 0)
1837 {
1838 if (VPPCOM_DEBUG > 0)
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05001839 clib_warning ("VCL<%d>: using default configuration.",
Dave Wallace2e005bb2017-11-07 01:21:39 -05001840 getpid (), conf_fname);
Dave Wallace543852a2017-08-03 02:11:34 -04001841 goto file_done;
1842 }
1843
1844 if (fstat (fd, &s) < 0)
1845 {
1846 if (VPPCOM_DEBUG > 0)
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05001847 clib_warning ("VCL<%d>: failed to stat `%s', "
1848 "using default configuration", getpid (), conf_fname);
Dave Wallace543852a2017-08-03 02:11:34 -04001849 goto file_done;
1850 }
1851
1852 if (!(S_ISREG (s.st_mode) || S_ISLNK (s.st_mode)))
1853 {
1854 if (VPPCOM_DEBUG > 0)
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05001855 clib_warning ("VCL<%d>: not a regular file `%s', "
1856 "using default configuration", getpid (), conf_fname);
Dave Wallace543852a2017-08-03 02:11:34 -04001857 goto file_done;
1858 }
1859
Dave Barach59b25652017-09-10 15:04:27 -04001860 unformat_init_clib_file (input, fd);
Dave Wallace543852a2017-08-03 02:11:34 -04001861
1862 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1863 {
Chris Lukeb2bcad62017-09-18 08:51:22 -04001864 (void) unformat_user (input, unformat_line_input, line_input);
Dave Wallace543852a2017-08-03 02:11:34 -04001865 unformat_skip_white_space (line_input);
1866
Dave Wallace8af20542017-10-26 03:29:30 -04001867 if (unformat (line_input, "vcl {"))
Dave Wallace543852a2017-08-03 02:11:34 -04001868 {
1869 vc_cfg_input = 1;
1870 continue;
1871 }
1872
1873 if (vc_cfg_input)
1874 {
1875 if (unformat (line_input, "heapsize %s", &chroot_path))
1876 {
1877 vec_terminate_c_string (chroot_path);
1878 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001879 clib_warning ("VCL<%d>: configured heapsize %s, "
Dave Wallace543852a2017-08-03 02:11:34 -04001880 "actual heapsize %lld (0x%llx)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05001881 getpid (), chroot_path, vcl_cfg->heapsize,
Dave Wallace543852a2017-08-03 02:11:34 -04001882 vcl_cfg->heapsize);
1883 vec_free (chroot_path);
1884 }
1885 else if (unformat (line_input, "api-prefix %s", &chroot_path))
1886 {
1887 vec_terminate_c_string (chroot_path);
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05001888 if (vcl_cfg->vpp_api_filename)
1889 vec_free (vcl_cfg->vpp_api_filename);
1890 vcl_cfg->vpp_api_filename = format (0, "/%s-vpe-api%c",
1891 chroot_path, 0);
Dave Wallace543852a2017-08-03 02:11:34 -04001892 vl_set_memory_root_path ((char *) chroot_path);
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05001893
Dave Wallace543852a2017-08-03 02:11:34 -04001894 if (VPPCOM_DEBUG > 0)
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05001895 clib_warning ("VCL<%d>: configured api-prefix (%s) and "
1896 "api filename (%s)", getpid (), chroot_path,
1897 vcl_cfg->vpp_api_filename);
Dave Wallace543852a2017-08-03 02:11:34 -04001898 chroot_path = 0; /* Don't vec_free() it! */
1899 }
Dave Wallacec8f1ee62017-11-29 22:46:32 -05001900 else if (unformat (line_input, "vpp-api-q-length %d", &q_len))
1901 {
1902 if (q_len < vcl_cfg->vpp_api_q_length)
1903 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001904 clib_warning ("VCL<%d>: ERROR: configured vpp-api-q-length "
Dave Wallacec8f1ee62017-11-29 22:46:32 -05001905 "(%u) is too small! Using default: %u ",
1906 getpid (), q_len, vcl_cfg->vpp_api_q_length);
1907 }
1908 else
1909 {
1910 vcl_cfg->vpp_api_q_length = q_len;
1911
1912 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001913 clib_warning ("VCL<%d>: configured vpp-api-q-length %u",
Dave Wallacec8f1ee62017-11-29 22:46:32 -05001914 getpid (), vcl_cfg->vpp_api_q_length);
1915 }
1916 }
Dave Wallace543852a2017-08-03 02:11:34 -04001917 else if (unformat (line_input, "uid %d", &uid))
1918 {
1919 vl_set_memory_uid (uid);
1920 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001921 clib_warning ("VCL<%d>: configured uid %d", getpid (), uid);
Dave Wallace543852a2017-08-03 02:11:34 -04001922 }
1923 else if (unformat (line_input, "gid %d", &gid))
1924 {
1925 vl_set_memory_gid (gid);
1926 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001927 clib_warning ("VCL<%d>: configured gid %d", getpid (), gid);
Dave Wallace543852a2017-08-03 02:11:34 -04001928 }
Dave Wallace8af20542017-10-26 03:29:30 -04001929 else if (unformat (line_input, "segment-baseva 0x%lx",
Dave Wallace543852a2017-08-03 02:11:34 -04001930 &vcl_cfg->segment_baseva))
1931 {
1932 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001933 clib_warning ("VCL<%d>: configured segment_baseva 0x%lx",
Dave Wallace2e005bb2017-11-07 01:21:39 -05001934 getpid (), vcl_cfg->segment_baseva);
Dave Wallace543852a2017-08-03 02:11:34 -04001935 }
1936 else if (unformat (line_input, "segment-size 0x%lx",
1937 &vcl_cfg->segment_size))
1938 {
1939 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001940 clib_warning ("VCL<%d>: configured segment_size 0x%lx (%ld)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05001941 getpid (), vcl_cfg->segment_size,
Dave Wallace543852a2017-08-03 02:11:34 -04001942 vcl_cfg->segment_size);
1943 }
1944 else if (unformat (line_input, "segment-size %ld",
1945 &vcl_cfg->segment_size))
1946 {
1947 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001948 clib_warning ("VCL<%d>: configured segment_size %ld (0x%lx)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05001949 getpid (), vcl_cfg->segment_size,
Dave Wallace543852a2017-08-03 02:11:34 -04001950 vcl_cfg->segment_size);
1951 }
1952 else if (unformat (line_input, "add-segment-size 0x%lx",
1953 &vcl_cfg->add_segment_size))
1954 {
1955 if (VPPCOM_DEBUG > 0)
1956 clib_warning
Dave Wallace048b1d62018-01-03 22:24:41 -05001957 ("VCL<%d>: configured add_segment_size 0x%lx (%ld)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05001958 getpid (), vcl_cfg->add_segment_size,
Dave Wallace543852a2017-08-03 02:11:34 -04001959 vcl_cfg->add_segment_size);
1960 }
1961 else if (unformat (line_input, "add-segment-size %ld",
1962 &vcl_cfg->add_segment_size))
1963 {
1964 if (VPPCOM_DEBUG > 0)
1965 clib_warning
Dave Wallace048b1d62018-01-03 22:24:41 -05001966 ("VCL<%d>: configured add_segment_size %ld (0x%lx)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05001967 getpid (), vcl_cfg->add_segment_size,
Dave Wallace543852a2017-08-03 02:11:34 -04001968 vcl_cfg->add_segment_size);
1969 }
1970 else if (unformat (line_input, "preallocated-fifo-pairs %d",
1971 &vcl_cfg->preallocated_fifo_pairs))
1972 {
1973 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001974 clib_warning ("VCL<%d>: configured preallocated_fifo_pairs "
Dave Wallace2e005bb2017-11-07 01:21:39 -05001975 "%d (0x%x)", getpid (),
Dave Wallace543852a2017-08-03 02:11:34 -04001976 vcl_cfg->preallocated_fifo_pairs,
1977 vcl_cfg->preallocated_fifo_pairs);
1978 }
1979 else if (unformat (line_input, "rx-fifo-size 0x%lx",
1980 &vcl_cfg->rx_fifo_size))
1981 {
1982 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001983 clib_warning ("VCL<%d>: configured rx_fifo_size 0x%lx (%ld)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05001984 getpid (), vcl_cfg->rx_fifo_size,
Dave Wallace543852a2017-08-03 02:11:34 -04001985 vcl_cfg->rx_fifo_size);
1986 }
1987 else if (unformat (line_input, "rx-fifo-size %ld",
1988 &vcl_cfg->rx_fifo_size))
1989 {
1990 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001991 clib_warning ("VCL<%d>: configured rx_fifo_size %ld (0x%lx)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05001992 getpid (), vcl_cfg->rx_fifo_size,
Dave Wallace543852a2017-08-03 02:11:34 -04001993 vcl_cfg->rx_fifo_size);
1994 }
1995 else if (unformat (line_input, "tx-fifo-size 0x%lx",
1996 &vcl_cfg->tx_fifo_size))
1997 {
1998 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001999 clib_warning ("VCL<%d>: configured tx_fifo_size 0x%lx (%ld)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002000 getpid (), vcl_cfg->tx_fifo_size,
Dave Wallace543852a2017-08-03 02:11:34 -04002001 vcl_cfg->tx_fifo_size);
2002 }
2003 else if (unformat (line_input, "tx-fifo-size %ld",
2004 &vcl_cfg->tx_fifo_size))
2005 {
2006 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002007 clib_warning ("VCL<%d>: configured tx_fifo_size %ld (0x%lx)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002008 getpid (), vcl_cfg->tx_fifo_size,
Dave Wallace543852a2017-08-03 02:11:34 -04002009 vcl_cfg->tx_fifo_size);
2010 }
2011 else if (unformat (line_input, "event-queue-size 0x%lx",
2012 &vcl_cfg->event_queue_size))
2013 {
2014 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002015 clib_warning ("VCL<%d>: configured event_queue_size "
2016 "0x%lx (%ld)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002017 getpid (), vcl_cfg->event_queue_size,
Dave Wallace543852a2017-08-03 02:11:34 -04002018 vcl_cfg->event_queue_size);
2019 }
2020 else if (unformat (line_input, "event-queue-size %ld",
2021 &vcl_cfg->event_queue_size))
2022 {
2023 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002024 clib_warning ("VCL<%d>: configured event_queue_size "
2025 "%ld (0x%lx)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002026 getpid (), vcl_cfg->event_queue_size,
Dave Wallace543852a2017-08-03 02:11:34 -04002027 vcl_cfg->event_queue_size);
2028 }
2029 else if (unformat (line_input, "listen-queue-size 0x%lx",
2030 &vcl_cfg->listen_queue_size))
2031 {
2032 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002033 clib_warning ("VCL<%d>: configured listen_queue_size "
2034 "0x%lx (%ld)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002035 getpid (), vcl_cfg->listen_queue_size,
Dave Wallace543852a2017-08-03 02:11:34 -04002036 vcl_cfg->listen_queue_size);
2037 }
2038 else if (unformat (line_input, "listen-queue-size %ld",
2039 &vcl_cfg->listen_queue_size))
2040 {
2041 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002042 clib_warning ("VCL<%d>: configured listen_queue_size "
2043 "%ld (0x%lx)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002044 getpid (), vcl_cfg->listen_queue_size,
Dave Wallace543852a2017-08-03 02:11:34 -04002045 vcl_cfg->listen_queue_size);
2046 }
2047 else if (unformat (line_input, "app-timeout %f",
2048 &vcl_cfg->app_timeout))
2049 {
2050 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002051 clib_warning ("VCL<%d>: configured app_timeout %f",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002052 getpid (), vcl_cfg->app_timeout);
Dave Wallace543852a2017-08-03 02:11:34 -04002053 }
2054 else if (unformat (line_input, "session-timeout %f",
2055 &vcl_cfg->session_timeout))
2056 {
2057 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002058 clib_warning ("VCL<%d>: configured session_timeout %f",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002059 getpid (), vcl_cfg->session_timeout);
Dave Wallace543852a2017-08-03 02:11:34 -04002060 }
2061 else if (unformat (line_input, "accept-timeout %f",
2062 &vcl_cfg->accept_timeout))
2063 {
2064 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002065 clib_warning ("VCL<%d>: configured accept_timeout %f",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002066 getpid (), vcl_cfg->accept_timeout);
Dave Wallace543852a2017-08-03 02:11:34 -04002067 }
Dave Wallace774169b2017-11-01 20:07:40 -04002068 else if (unformat (line_input, "app-proxy-transport-tcp"))
Dave Wallace8af20542017-10-26 03:29:30 -04002069 {
Dave Wallace774169b2017-11-01 20:07:40 -04002070 vcl_cfg->app_proxy_transport_tcp = 1;
Dave Wallace8af20542017-10-26 03:29:30 -04002071 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002072 clib_warning ("VCL<%d>: configured "
2073 "app_proxy_transport_tcp (%d)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002074 getpid (), vcl_cfg->app_proxy_transport_tcp);
Dave Wallace8af20542017-10-26 03:29:30 -04002075 }
Dave Wallace774169b2017-11-01 20:07:40 -04002076 else if (unformat (line_input, "app-proxy-transport-udp"))
Dave Wallace8af20542017-10-26 03:29:30 -04002077 {
Dave Wallace774169b2017-11-01 20:07:40 -04002078 vcl_cfg->app_proxy_transport_udp = 1;
Dave Wallace8af20542017-10-26 03:29:30 -04002079 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002080 clib_warning ("VCL<%d>: configured "
2081 "app_proxy_transport_udp (%d)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002082 getpid (), vcl_cfg->app_proxy_transport_udp);
Dave Wallace8af20542017-10-26 03:29:30 -04002083 }
Dave Wallace774169b2017-11-01 20:07:40 -04002084 else if (unformat (line_input, "app-scope-local"))
Dave Wallace8af20542017-10-26 03:29:30 -04002085 {
Dave Wallace774169b2017-11-01 20:07:40 -04002086 vcl_cfg->app_scope_local = 1;
Dave Wallace8af20542017-10-26 03:29:30 -04002087 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002088 clib_warning ("VCL<%d>: configured app_scope_local (%d)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002089 getpid (), vcl_cfg->app_scope_local);
Dave Wallace774169b2017-11-01 20:07:40 -04002090 }
2091 else if (unformat (line_input, "app-scope-global"))
2092 {
2093 vcl_cfg->app_scope_global = 1;
2094 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002095 clib_warning ("VCL<%d>: configured app_scope_global (%d)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002096 getpid (), vcl_cfg->app_scope_global);
Dave Wallace8af20542017-10-26 03:29:30 -04002097 }
2098 else if (unformat (line_input, "namespace-secret %lu",
2099 &vcl_cfg->namespace_secret))
2100 {
2101 if (VPPCOM_DEBUG > 0)
2102 clib_warning
Dave Wallace048b1d62018-01-03 22:24:41 -05002103 ("VCL<%d>: configured namespace_secret %lu (0x%lx)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002104 getpid (), vcl_cfg->namespace_secret,
Dave Wallace8af20542017-10-26 03:29:30 -04002105 vcl_cfg->namespace_secret);
2106 }
2107 else if (unformat (line_input, "namespace-id %v",
2108 &vcl_cfg->namespace_id))
2109 {
2110 vl_api_application_attach_t *mp;
2111 u32 max_nsid_vec_len = sizeof (mp->namespace_id) - 1;
2112 u32 nsid_vec_len = vec_len (vcl_cfg->namespace_id);
2113 if (nsid_vec_len > max_nsid_vec_len)
2114 {
2115 _vec_len (vcl_cfg->namespace_id) = max_nsid_vec_len;
2116 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002117 clib_warning ("VCL<%d>: configured namespace_id is "
2118 "too long, truncated to %d characters!",
2119 getpid (), max_nsid_vec_len);
Dave Wallace8af20542017-10-26 03:29:30 -04002120 }
2121
2122 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002123 clib_warning ("VCL<%d>: configured namespace_id %v",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002124 getpid (), vcl_cfg->namespace_id);
Dave Wallace8af20542017-10-26 03:29:30 -04002125 }
Dave Wallace543852a2017-08-03 02:11:34 -04002126 else if (unformat (line_input, "}"))
2127 {
2128 vc_cfg_input = 0;
2129 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002130 clib_warning ("VCL<%d>: completed parsing vppcom config!",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002131 getpid ());
Dave Wallace543852a2017-08-03 02:11:34 -04002132 goto input_done;
2133 }
2134 else
2135 {
2136 if (line_input->buffer[line_input->index] != '#')
2137 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002138 clib_warning ("VCL<%d>: Unknown vppcom config option: '%s'",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002139 getpid (), (char *)
Dave Wallace543852a2017-08-03 02:11:34 -04002140 &line_input->buffer[line_input->index]);
2141 }
2142 }
2143 }
2144 }
2145
2146input_done:
2147 unformat_free (input);
2148
2149file_done:
Chris Lukeab7b8d92017-09-07 07:40:13 -04002150 if (fd >= 0)
Dave Wallace543852a2017-08-03 02:11:34 -04002151 close (fd);
2152}
2153
2154/*
2155 * VPPCOM Public API functions
2156 */
2157int
2158vppcom_app_create (char *app_name)
2159{
Dave Wallace543852a2017-08-03 02:11:34 -04002160 vppcom_cfg_t *vcl_cfg = &vcm->cfg;
2161 u8 *heap;
2162 mheap_t *h;
2163 int rv;
2164
2165 if (!vcm->init)
2166 {
2167 char *conf_fname;
Dave Wallace8af20542017-10-26 03:29:30 -04002168 char *env_var_str;
Dave Wallace543852a2017-08-03 02:11:34 -04002169
2170 vcm->init = 1;
Dave Wallace543852a2017-08-03 02:11:34 -04002171 vppcom_cfg_init (vcl_cfg);
Dave Wallace498b3a52017-11-09 13:00:34 -05002172 env_var_str = getenv (VPPCOM_ENV_DEBUG);
2173 if (env_var_str)
2174 {
2175 u32 tmp;
2176 if (sscanf (env_var_str, "%u", &tmp) != 1)
Dave Wallace69d01192018-02-22 16:22:09 -05002177 clib_warning ("VCL<%d>: WARNING: Invalid debug level specified "
2178 "in the environment variable " VPPCOM_ENV_DEBUG
Dave Wallace498b3a52017-11-09 13:00:34 -05002179 " (%s)!\n", getpid (), env_var_str);
2180 else
2181 {
2182 vcm->debug = tmp;
Dave Wallace69d01192018-02-22 16:22:09 -05002183 if (VPPCOM_DEBUG > 0)
2184 clib_warning ("VCL<%d>: configured VCL debug level (%u) from "
2185 VPPCOM_ENV_DEBUG "!", getpid (), vcm->debug);
Dave Wallace498b3a52017-11-09 13:00:34 -05002186 }
2187 }
Dave Wallace8af20542017-10-26 03:29:30 -04002188 conf_fname = getenv (VPPCOM_ENV_CONF);
Dave Wallace543852a2017-08-03 02:11:34 -04002189 if (!conf_fname)
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05002190 conf_fname = VPPCOM_CONF_DEFAULT;
Dave Wallace543852a2017-08-03 02:11:34 -04002191 vppcom_cfg_heapsize (conf_fname);
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05002192 vcl_cfg = &vcm->cfg;
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08002193 clib_spinlock_init (&vcm->session_fifo_lockp);
Dave Wallace2e005bb2017-11-07 01:21:39 -05002194 clib_fifo_validate (vcm->client_session_index_fifo,
2195 vcm->cfg.listen_queue_size);
Dave Wallace543852a2017-08-03 02:11:34 -04002196 vppcom_cfg_read (conf_fname);
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05002197
2198 env_var_str = getenv (VPPCOM_ENV_API_PREFIX);
2199 if (env_var_str)
2200 {
2201 if (vcl_cfg->vpp_api_filename)
2202 vec_free (vcl_cfg->vpp_api_filename);
2203 vcl_cfg->vpp_api_filename = format (0, "/%s-vpe-api%c",
2204 env_var_str, 0);
2205 vl_set_memory_root_path ((char *) env_var_str);
2206
2207 if (VPPCOM_DEBUG > 0)
2208 clib_warning ("VCL<%d>: configured api prefix (%s) and "
2209 "filename (%s) from " VPPCOM_ENV_API_PREFIX "!",
2210 getpid (), env_var_str, vcl_cfg->vpp_api_filename);
2211 }
Dave Wallace8af20542017-10-26 03:29:30 -04002212 env_var_str = getenv (VPPCOM_ENV_APP_NAMESPACE_ID);
2213 if (env_var_str)
2214 {
2215 u32 ns_id_vec_len = strlen (env_var_str);
2216
2217 vec_reset_length (vcm->cfg.namespace_id);
2218 vec_validate (vcm->cfg.namespace_id, ns_id_vec_len - 1);
2219 clib_memcpy (vcm->cfg.namespace_id, env_var_str, ns_id_vec_len);
2220
2221 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002222 clib_warning ("VCL<%d>: configured namespace_id (%v) from "
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08002223 VPPCOM_ENV_APP_NAMESPACE_ID
2224 "!", getpid (), vcm->cfg.namespace_id);
Dave Wallace8af20542017-10-26 03:29:30 -04002225 }
2226 env_var_str = getenv (VPPCOM_ENV_APP_NAMESPACE_SECRET);
2227 if (env_var_str)
2228 {
2229 u64 tmp;
2230 if (sscanf (env_var_str, "%lu", &tmp) != 1)
Dave Wallace69d01192018-02-22 16:22:09 -05002231 clib_warning ("VCL<%d>: WARNING: Invalid namespace secret "
2232 "specified in the environment variable "
Dave Wallace8af20542017-10-26 03:29:30 -04002233 VPPCOM_ENV_APP_NAMESPACE_SECRET
Dave Wallace2e005bb2017-11-07 01:21:39 -05002234 " (%s)!\n", getpid (), env_var_str);
Dave Wallace8af20542017-10-26 03:29:30 -04002235 else
2236 {
2237 vcm->cfg.namespace_secret = tmp;
2238 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002239 clib_warning ("VCL<%d>: configured namespace secret "
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08002240 "(%lu) from "
Dave Wallace9a0546d2018-03-08 11:40:28 -05002241 VPPCOM_ENV_APP_NAMESPACE_SECRET
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08002242 "!", getpid (), vcm->cfg.namespace_secret);
Dave Wallace8af20542017-10-26 03:29:30 -04002243 }
2244 }
Dave Wallace774169b2017-11-01 20:07:40 -04002245 if (getenv (VPPCOM_ENV_APP_PROXY_TRANSPORT_TCP))
Dave Wallace8af20542017-10-26 03:29:30 -04002246 {
Dave Wallace774169b2017-11-01 20:07:40 -04002247 vcm->cfg.app_proxy_transport_tcp = 1;
Dave Wallace8af20542017-10-26 03:29:30 -04002248 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002249 clib_warning ("VCL<%d>: configured app_proxy_transport_tcp "
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08002250 "(%u) from "
2251 VPPCOM_ENV_APP_PROXY_TRANSPORT_TCP
Dave Wallace048b1d62018-01-03 22:24:41 -05002252 "!", getpid (), vcm->cfg.app_proxy_transport_tcp);
Dave Wallace8af20542017-10-26 03:29:30 -04002253 }
Dave Wallace774169b2017-11-01 20:07:40 -04002254 if (getenv (VPPCOM_ENV_APP_PROXY_TRANSPORT_UDP))
Dave Wallace8af20542017-10-26 03:29:30 -04002255 {
Dave Wallace774169b2017-11-01 20:07:40 -04002256 vcm->cfg.app_proxy_transport_udp = 1;
Dave Wallace8af20542017-10-26 03:29:30 -04002257 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002258 clib_warning ("VCL<%d>: configured app_proxy_transport_udp "
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08002259 "(%u) from "
2260 VPPCOM_ENV_APP_PROXY_TRANSPORT_UDP
Dave Wallace048b1d62018-01-03 22:24:41 -05002261 "!", getpid (), vcm->cfg.app_proxy_transport_udp);
Dave Wallace774169b2017-11-01 20:07:40 -04002262 }
2263 if (getenv (VPPCOM_ENV_APP_SCOPE_LOCAL))
2264 {
2265 vcm->cfg.app_scope_local = 1;
2266 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002267 clib_warning ("VCL<%d>: configured app_scope_local (%u) from "
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08002268 VPPCOM_ENV_APP_SCOPE_LOCAL
2269 "!", getpid (), vcm->cfg.app_scope_local);
Dave Wallace774169b2017-11-01 20:07:40 -04002270 }
2271 if (getenv (VPPCOM_ENV_APP_SCOPE_GLOBAL))
2272 {
2273 vcm->cfg.app_scope_global = 1;
2274 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002275 clib_warning ("VCL<%d>: configured app_scope_global (%u) from "
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08002276 VPPCOM_ENV_APP_SCOPE_GLOBAL
2277 "!", getpid (), vcm->cfg.app_scope_global);
Dave Wallace8af20542017-10-26 03:29:30 -04002278 }
2279
Dave Wallace543852a2017-08-03 02:11:34 -04002280 vcm->main_cpu = os_get_thread_index ();
2281 heap = clib_mem_get_per_cpu_heap ();
2282 h = mheap_header (heap);
2283
2284 /* make the main heap thread-safe */
2285 h->flags |= MHEAP_FLAG_THREAD_SAFE;
2286
2287 vcm->session_index_by_vpp_handles = hash_create (0, sizeof (uword));
2288
2289 clib_time_init (&vcm->clib_time);
2290 vppcom_init_error_string_table ();
Florin Corasa332c462018-01-31 06:52:17 -08002291 svm_fifo_segment_main_init (vcl_cfg->segment_baseva,
2292 20 /* timeout in secs */ );
Dave Wallace543852a2017-08-03 02:11:34 -04002293 clib_spinlock_init (&vcm->sessions_lockp);
Dave Wallace543852a2017-08-03 02:11:34 -04002294 }
2295
2296 if (vcm->my_client_index == ~0)
2297 {
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002298
2299 /* API hookup and connect to VPP */
Dave Wallace048b1d62018-01-03 22:24:41 -05002300 vppcom_api_hookup ();
Dave Wallace543852a2017-08-03 02:11:34 -04002301 vcm->app_state = STATE_APP_START;
2302 rv = vppcom_connect_to_vpp (app_name);
2303 if (rv)
2304 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002305 clib_warning ("VCL<%d>: ERROR: couldn't connect to VPP!",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002306 getpid ());
Dave Wallace543852a2017-08-03 02:11:34 -04002307 return rv;
2308 }
2309
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002310 /* State event handling thread */
2311
2312 rv = vce_start_event_thread (&(vcm->event_thread), 20);
2313
2314
Dave Wallace543852a2017-08-03 02:11:34 -04002315 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002316 clib_warning ("VCL<%d>: sending session enable", getpid ());
Dave Wallace543852a2017-08-03 02:11:34 -04002317
Dave Wallace048b1d62018-01-03 22:24:41 -05002318 rv = vppcom_app_session_enable ();
Dave Wallace543852a2017-08-03 02:11:34 -04002319 if (rv)
2320 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002321 clib_warning ("VCL<%d>: ERROR: vppcom_app_session_enable() "
2322 "failed!", getpid ());
Dave Wallace543852a2017-08-03 02:11:34 -04002323 return rv;
2324 }
Dave Wallace543852a2017-08-03 02:11:34 -04002325
Dave Wallace66cf6eb2017-10-26 02:51:07 -04002326 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002327 clib_warning ("VCL<%d>: sending app attach", getpid ());
2328
2329 rv = vppcom_app_attach ();
2330 if (rv)
2331 {
2332 clib_warning ("VCL<%d>: ERROR: vppcom_app_attach() failed!",
2333 getpid ());
2334 return rv;
2335 }
2336
2337 if (VPPCOM_DEBUG > 0)
2338 clib_warning ("VCL<%d>: app_name '%s', my_client_index %d (0x%x)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002339 getpid (), app_name, vcm->my_client_index,
Dave Wallace66cf6eb2017-10-26 02:51:07 -04002340 vcm->my_client_index);
2341 }
Dave Wallace543852a2017-08-03 02:11:34 -04002342
2343 return VPPCOM_OK;
2344}
2345
2346void
2347vppcom_app_destroy (void)
2348{
Dave Wallace543852a2017-08-03 02:11:34 -04002349 int rv;
2350
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 ();
2377 rv = vppcom_wait_for_app_state_change (STATE_APP_ENABLED);
2378 if (PREDICT_FALSE (rv))
2379 {
2380 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002381 clib_warning ("VCL<%d>: application detach timed out! "
2382 "returning %d (%s)",
Dave Wallaceee45d412017-11-24 21:44:06 -05002383 getpid (), rv, vppcom_retval_str (rv));
Dave Wallace543852a2017-08-03 02:11:34 -04002384 }
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -08002385
2386 /* Finished with logging before client gets reset to ~0 */
2387 if (VPPCOM_DEBUG > 0)
2388 write_elog ();
2389
Dave Wallace543852a2017-08-03 02:11:34 -04002390 vl_client_disconnect_from_vlib ();
2391 vcm->my_client_index = ~0;
2392 vcm->app_state = STATE_APP_START;
2393}
2394
2395int
Dave Wallacec04cbf12018-02-07 18:14:02 -05002396vppcom_session_create (u8 proto, u8 is_nonblocking)
Dave Wallace543852a2017-08-03 02:11:34 -04002397{
Dave Wallace543852a2017-08-03 02:11:34 -04002398 session_t *session;
2399 u32 session_index;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002400 session_state_t state;
2401 elog_track_t session_elog_track;
Dave Wallace543852a2017-08-03 02:11:34 -04002402
2403 clib_spinlock_lock (&vcm->sessions_lockp);
2404 pool_get (vcm->sessions, session);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002405 memset (session, 0, sizeof (*session));
Dave Wallace543852a2017-08-03 02:11:34 -04002406 session_index = session - vcm->sessions;
2407
Dave Wallace543852a2017-08-03 02:11:34 -04002408 session->proto = proto;
2409 session->state = STATE_START;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002410 state = session->state;
Dave Wallace4878cbe2017-11-21 03:45:09 -05002411 session->vpp_handle = ~0;
Dave Wallace543852a2017-08-03 02:11:34 -04002412
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002413 if (is_nonblocking)
2414 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_NONBLOCK);
2415 else
2416 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_NONBLOCK);
Dave Wallace543852a2017-08-03 02:11:34 -04002417
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002418 if (VPPCOM_DEBUG > 0)
2419 {
2420 session->elog_track.name =
2421 (char *) format (0, "C:%d:S:%d%c", vcm->my_client_index,
2422 session_index, 0);
2423 elog_track_register (&vcm->elog_main, &session->elog_track);
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002424 session_elog_track = session->elog_track;
2425 }
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002426
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002427 clib_spinlock_unlock (&vcm->sessions_lockp);
2428
2429 if (VPPCOM_DEBUG > 0)
2430 clib_warning ("VCL<%d>: sid %u", getpid (), session_index);
2431
2432 if (VPPCOM_DEBUG > 0)
2433 {
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002434 /* *INDENT-OFF* */
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002435 ELOG_TYPE_DECLARE (e) =
2436 {
Dave Wallacec04cbf12018-02-07 18:14:02 -05002437 .format = "session_create:proto:%d state:%d is_nonblocking:%d",
2438 .format_args = "i4i4i4",
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002439 };
2440
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002441 struct
2442 {
Dave Wallacec04cbf12018-02-07 18:14:02 -05002443 u32 data[3];
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002444 } *ed;
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002445
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002446 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session_elog_track);
2447 ed->data[0] = proto;
2448 ed->data[1] = state;
2449 ed->data[2] = is_nonblocking;
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002450 /* *INDENT-ON* */
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002451 }
2452
Dave Wallace543852a2017-08-03 02:11:34 -04002453 return (int) session_index;
2454}
2455
2456int
2457vppcom_session_close (uint32_t session_index)
2458{
Dave Wallace543852a2017-08-03 02:11:34 -04002459 session_t *session = 0;
2460 int rv;
Dave Wallace66cf6eb2017-10-26 02:51:07 -04002461 u8 is_vep;
2462 u8 is_vep_session;
2463 u32 next_sid;
2464 u32 vep_idx;
Dave Wallaceee45d412017-11-24 21:44:06 -05002465 u64 vpp_handle;
Dave Wallace4878cbe2017-11-21 03:45:09 -05002466 uword *p;
Dave Wallace66cf6eb2017-10-26 02:51:07 -04002467 session_state_t state;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002468 elog_track_t session_elog_track;
Dave Wallace543852a2017-08-03 02:11:34 -04002469
Dave Wallace4878cbe2017-11-21 03:45:09 -05002470 VCL_LOCK_AND_GET_SESSION (session_index, &session);
Dave Wallace66cf6eb2017-10-26 02:51:07 -04002471 is_vep = session->is_vep;
2472 is_vep_session = session->is_vep_session;
2473 next_sid = session->vep.next_sid;
2474 vep_idx = session->vep.vep_idx;
2475 state = session->state;
Dave Wallaceee45d412017-11-24 21:44:06 -05002476 vpp_handle = session->vpp_handle;
Dave Wallace543852a2017-08-03 02:11:34 -04002477 clib_spinlock_unlock (&vcm->sessions_lockp);
2478
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002479 /*
2480 * Why two if(VPPCOM_DEBUG) checks?
2481 *
2482 * Eventually all clib_warnings need their own way of being
2483 * logged and signalled (like severity) where event logging
2484 * is a separate debugging tool. It will make the separation
2485 * easier. ... parting is such sweet sorrow ...
2486 */
2487 if (VPPCOM_DEBUG > 0)
2488 {
2489 session_elog_track = session->elog_track;
2490 }
2491
Dave Wallace543852a2017-08-03 02:11:34 -04002492 if (VPPCOM_DEBUG > 0)
Dave Wallaceee45d412017-11-24 21:44:06 -05002493 {
2494 if (is_vep)
Dave Wallace048b1d62018-01-03 22:24:41 -05002495 clib_warning ("VCL<%d>: vep_idx %u / sid %u: "
2496 "closing epoll session...",
Dave Wallaceee45d412017-11-24 21:44:06 -05002497 getpid (), session_index, session_index);
2498 else
Dave Wallace048b1d62018-01-03 22:24:41 -05002499 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %d: "
2500 "closing session...",
Dave Wallaceee45d412017-11-24 21:44:06 -05002501 getpid (), vpp_handle, session_index);
2502 }
Dave Wallace543852a2017-08-03 02:11:34 -04002503
Dave Wallace66cf6eb2017-10-26 02:51:07 -04002504 if (is_vep)
Dave Wallace543852a2017-08-03 02:11:34 -04002505 {
Dave Wallace66cf6eb2017-10-26 02:51:07 -04002506 while (next_sid != ~0)
Dave Wallace19481612017-09-15 18:47:44 -04002507 {
Dave Wallacef7f809c2017-10-03 01:48:42 -04002508 rv = vppcom_epoll_ctl (session_index, EPOLL_CTL_DEL, next_sid, 0);
Dave Wallaceee45d412017-11-24 21:44:06 -05002509 if ((VPPCOM_DEBUG > 0) && PREDICT_FALSE (rv < 0))
Dave Wallace048b1d62018-01-03 22:24:41 -05002510 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
2511 "EPOLL_CTL_DEL vep_idx %u failed! rv %d (%s)",
2512 getpid (), vpp_handle, next_sid, vep_idx,
Dave Wallace4878cbe2017-11-21 03:45:09 -05002513 rv, vppcom_retval_str (rv));
Dave Wallacef7f809c2017-10-03 01:48:42 -04002514
Dave Wallace4878cbe2017-11-21 03:45:09 -05002515 VCL_LOCK_AND_GET_SESSION (session_index, &session);
Dave Wallace66cf6eb2017-10-26 02:51:07 -04002516 next_sid = session->vep.next_sid;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002517 clib_spinlock_unlock (&vcm->sessions_lockp);
2518 }
2519 }
2520 else
2521 {
Dave Wallace66cf6eb2017-10-26 02:51:07 -04002522 if (is_vep_session)
Dave Wallacef7f809c2017-10-03 01:48:42 -04002523 {
Dave Wallacef7f809c2017-10-03 01:48:42 -04002524 rv = vppcom_epoll_ctl (vep_idx, EPOLL_CTL_DEL, session_index, 0);
2525 if ((VPPCOM_DEBUG > 0) && (rv < 0))
Dave Wallace048b1d62018-01-03 22:24:41 -05002526 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
2527 "EPOLL_CTL_DEL vep_idx %u failed! rv %d (%s)",
Dave Wallaceee45d412017-11-24 21:44:06 -05002528 getpid (), vpp_handle, session_index,
2529 vep_idx, rv, vppcom_retval_str (rv));
Dave Wallacef7f809c2017-10-03 01:48:42 -04002530 }
2531
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002532 if (state & STATE_LISTEN)
Dave Wallacef7f809c2017-10-03 01:48:42 -04002533 {
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002534 rv = vppcom_session_unbind (session_index);
2535 if (PREDICT_FALSE (rv < 0))
Dave Wallace4878cbe2017-11-21 03:45:09 -05002536 {
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002537 if (VPPCOM_DEBUG > 0)
2538 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
2539 "listener unbind failed! rv %d (%s)",
2540 getpid (), vpp_handle, session_index,
2541 rv, vppcom_retval_str (rv));
Dave Wallace4878cbe2017-11-21 03:45:09 -05002542 }
Dave Wallacef7f809c2017-10-03 01:48:42 -04002543 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05002544
2545 else if (state & (CLIENT_STATE_OPEN | SERVER_STATE_OPEN))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002546 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05002547 rv = vppcom_session_disconnect (session_index);
2548 if (PREDICT_FALSE (rv < 0))
Dave Wallace048b1d62018-01-03 22:24:41 -05002549 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -05002550 "session disconnect failed! rv %d (%s)",
2551 getpid (), vpp_handle, session_index,
2552 rv, vppcom_retval_str (rv));
Dave Wallacef7f809c2017-10-03 01:48:42 -04002553 }
Dave Wallace19481612017-09-15 18:47:44 -04002554 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05002555
2556 VCL_LOCK_AND_GET_SESSION (session_index, &session);
Dave Wallaceee45d412017-11-24 21:44:06 -05002557 vpp_handle = session->vpp_handle;
2558 if (vpp_handle != ~0)
Dave Wallace4878cbe2017-11-21 03:45:09 -05002559 {
Dave Wallaceee45d412017-11-24 21:44:06 -05002560 p = hash_get (vcm->session_index_by_vpp_handles, vpp_handle);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002561 if (p)
Dave Wallaceee45d412017-11-24 21:44:06 -05002562 hash_unset (vcm->session_index_by_vpp_handles, vpp_handle);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002563 }
Dave Wallace543852a2017-08-03 02:11:34 -04002564 pool_put_index (vcm->sessions, session_index);
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002565
Dave Wallace66cf6eb2017-10-26 02:51:07 -04002566 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002567
2568 if (VPPCOM_DEBUG > 0)
Dave Wallaceee45d412017-11-24 21:44:06 -05002569 {
2570 if (is_vep)
Dave Wallace048b1d62018-01-03 22:24:41 -05002571 clib_warning ("VCL<%d>: vep_idx %u / sid %u: epoll session removed.",
Dave Wallaceee45d412017-11-24 21:44:06 -05002572 getpid (), session_index, session_index);
2573 else
Dave Wallace048b1d62018-01-03 22:24:41 -05002574 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: session removed.",
Dave Wallaceee45d412017-11-24 21:44:06 -05002575 getpid (), vpp_handle, session_index);
2576 }
Dave Wallacef7f809c2017-10-03 01:48:42 -04002577done:
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002578
2579 if (VPPCOM_DEBUG > 0)
2580 {
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002581 /* *INDENT-OFF* */
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002582 ELOG_TYPE_DECLARE (e) =
2583 {
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002584 .format = "session_close:rv:%d",
2585 .format_args = "i4",
2586 };
2587
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002588 struct
2589 {
2590 u32 data;
2591 } *ed;
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002592
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002593 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session_elog_track);
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002594 ed->data = rv;
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002595 /* *INDENT-ON* */
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002596 }
2597
Dave Wallace543852a2017-08-03 02:11:34 -04002598 return rv;
2599}
2600
2601int
2602vppcom_session_bind (uint32_t session_index, vppcom_endpt_t * ep)
2603{
Dave Wallace543852a2017-08-03 02:11:34 -04002604 session_t *session = 0;
2605 int rv;
2606
2607 if (!ep || !ep->ip)
2608 return VPPCOM_EINVAL;
2609
Dave Wallace4878cbe2017-11-21 03:45:09 -05002610 VCL_LOCK_AND_GET_SESSION (session_index, &session);
Dave Wallace543852a2017-08-03 02:11:34 -04002611
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002612 if (session->is_vep)
2613 {
2614 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace048b1d62018-01-03 22:24:41 -05002615 clib_warning ("VCL<%d>: ERROR: sid %u: cannot "
2616 "bind to an epoll session!", getpid (), session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002617 rv = VPPCOM_EBADFD;
2618 goto done;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002619 }
2620
Dave Wallace35830af2017-10-09 01:43:42 -04002621 session->lcl_addr.is_ip4 = ep->is_ip4;
2622 session->lcl_addr.ip46 = to_ip46 (!ep->is_ip4, ep->ip);
Stevenac1f96d2017-10-24 16:03:58 -07002623 session->lcl_port = ep->port;
2624
2625 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002626 clib_warning ("VCL<%d>: sid %u: binding to local %s address %U "
Dave Wallaceee45d412017-11-24 21:44:06 -05002627 "port %u, proto %s", getpid (), session_index,
2628 session->lcl_addr.is_ip4 ? "IPv4" : "IPv6",
2629 format_ip46_address, &session->lcl_addr.ip46,
2630 session->lcl_addr.is_ip4,
Dave Wallace4878cbe2017-11-21 03:45:09 -05002631 clib_net_to_host_u16 (session->lcl_port),
2632 session->proto ? "UDP" : "TCP");
Dave Wallace543852a2017-08-03 02:11:34 -04002633
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002634 if (VPPCOM_DEBUG > 0)
2635 {
2636 if (session->lcl_addr.is_ip4)
2637 {
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002638 /* *INDENT-OFF* */
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002639 ELOG_TYPE_DECLARE (e) =
2640 {
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002641 .format = "bind local:%s:%d.%d.%d.%d:%d ",
2642 .format_args = "t1i1i1i1i1i2",
2643 .n_enum_strings = 2,
2644 .enum_strings = {"TCP", "UDP",},
2645 };
2646
2647 CLIB_PACKED (struct {
2648 u8 proto;
2649 u8 addr[4];
2650 u16 port;
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002651 }) *ed;
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002652
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002653 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
2654 ed->proto = session->proto;
2655 ed->addr[0] = session->lcl_addr.ip46.ip4.as_u8[0];
2656 ed->addr[1] = session->lcl_addr.ip46.ip4.as_u8[1];
2657 ed->addr[2] = session->lcl_addr.ip46.ip4.as_u8[2];
2658 ed->addr[3] = session->lcl_addr.ip46.ip4.as_u8[3];
2659 ed->port = clib_net_to_host_u16 (session->lcl_port);
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002660 /* *INDENT-ON* */
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002661 }
2662 }
2663
Dave Wallace543852a2017-08-03 02:11:34 -04002664 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002665done:
2666 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04002667}
2668
2669int
Dave Wallace33e002b2017-09-06 01:20:02 -04002670vppcom_session_listen (uint32_t listen_session_index, uint32_t q_len)
Dave Wallace543852a2017-08-03 02:11:34 -04002671{
Dave Wallace33e002b2017-09-06 01:20:02 -04002672 session_t *listen_session = 0;
Dave Wallaceee45d412017-11-24 21:44:06 -05002673 u64 listen_vpp_handle;
2674 int rv, retval;
Dave Wallace543852a2017-08-03 02:11:34 -04002675
Keith Burns (alagalah)aba98de2018-02-22 03:23:40 -08002676 if (q_len == 0 || q_len == ~0)
2677 q_len = vcm->cfg.listen_queue_size;
2678
Dave Wallace4878cbe2017-11-21 03:45:09 -05002679 VCL_LOCK_AND_GET_SESSION (listen_session_index, &listen_session);
Dave Wallace543852a2017-08-03 02:11:34 -04002680
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002681 if (listen_session->is_vep)
2682 {
2683 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace048b1d62018-01-03 22:24:41 -05002684 clib_warning ("VCL<%d>: ERROR: sid %u: cannot listen on an "
Dave Wallace4878cbe2017-11-21 03:45:09 -05002685 "epoll session!", getpid (), listen_session_index);
2686 rv = VPPCOM_EBADFD;
2687 goto done;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002688 }
2689
Dave Wallaceee45d412017-11-24 21:44:06 -05002690 listen_vpp_handle = listen_session->vpp_handle;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002691 if (listen_session->state & STATE_LISTEN)
Dave Wallacee695cb42017-11-02 22:04:42 -04002692 {
2693 clib_spinlock_unlock (&vcm->sessions_lockp);
2694 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002695 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -05002696 "already in listen state!",
2697 getpid (), listen_vpp_handle, listen_session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002698 rv = VPPCOM_OK;
2699 goto done;
Dave Wallacee695cb42017-11-02 22:04:42 -04002700 }
2701
Dave Wallace543852a2017-08-03 02:11:34 -04002702 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002703 clib_warning ("VCL<%d>: vpp handle 0x%llx, "
2704 "sid %u: sending bind request...",
Dave Wallaceee45d412017-11-24 21:44:06 -05002705 getpid (), listen_vpp_handle, listen_session_index);
Dave Wallace543852a2017-08-03 02:11:34 -04002706
Dave Wallace4878cbe2017-11-21 03:45:09 -05002707 vppcom_send_bind_sock (listen_session, listen_session_index);
Dave Wallace543852a2017-08-03 02:11:34 -04002708 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallaceee45d412017-11-24 21:44:06 -05002709 retval =
Dave Wallace33e002b2017-09-06 01:20:02 -04002710 vppcom_wait_for_session_state_change (listen_session_index, STATE_LISTEN,
2711 vcm->cfg.session_timeout);
Dave Wallace543852a2017-08-03 02:11:34 -04002712
Dave Wallace4878cbe2017-11-21 03:45:09 -05002713 VCL_LOCK_AND_GET_SESSION (listen_session_index, &listen_session);
Dave Wallaceee45d412017-11-24 21:44:06 -05002714 if (PREDICT_FALSE (retval))
2715 {
2716 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002717 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: bind failed! "
Dave Wallaceee45d412017-11-24 21:44:06 -05002718 "returning %d (%s)", getpid (),
2719 listen_session->vpp_handle, listen_session_index,
2720 retval, vppcom_retval_str (retval));
2721 clib_spinlock_unlock (&vcm->sessions_lockp);
2722 rv = retval;
2723 goto done;
2724 }
2725
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08002726 clib_spinlock_lock (&vcm->session_fifo_lockp);
Dave Wallace543852a2017-08-03 02:11:34 -04002727 clib_fifo_validate (vcm->client_session_index_fifo, q_len);
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08002728 clib_spinlock_unlock (&vcm->session_fifo_lockp);
2729
Dave Wallacef7f809c2017-10-03 01:48:42 -04002730 clib_spinlock_unlock (&vcm->sessions_lockp);
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08002731
Dave Wallace4878cbe2017-11-21 03:45:09 -05002732done:
2733 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04002734}
2735
2736int
Keith Burns (alagalah)0d2b0d52018-03-06 15:55:22 -08002737vppcom_session_register_listener (uint32_t session_index,
2738 vppcom_session_listener_cb cb,
2739 vppcom_session_listener_errcb
2740 errcb, uint8_t flags, int q_len, void *ptr)
2741{
2742 int rv = VPPCOM_OK;
2743 vce_event_key_t evk;
2744 vppcom_session_listener_t *listener_args;
2745
2746 rv = vppcom_session_listen (session_index, q_len);
2747 if (rv)
2748 {
2749 goto done;
2750 }
2751
2752
2753 /* Register handler for connect_request event on listen_session_index */
2754 listener_args = clib_mem_alloc (sizeof (vppcom_session_listener_t));
2755 listener_args->user_cb = cb;
2756 listener_args->user_cb_data = ptr;
2757 listener_args->user_errcb = errcb;
2758
2759 evk.session_index = session_index;
2760 evk.eid = VCL_EVENT_CONNECT_REQ_ACCEPTED;
2761 (void) vce_register_handler (&vcm->event_thread, &evk,
2762 vce_registered_listener_connect_handler_fn,
2763 listener_args);
2764
2765done:
2766 return rv;
2767}
2768
2769int
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002770validate_args_session_accept_ (session_t * listen_session)
2771{
2772 u32 listen_session_index = listen_session - vcm->sessions;
2773
2774 /* Input validation - expects spinlock on sessions_lockp */
2775 if (listen_session->is_vep)
2776 {
2777 clib_warning ("VCL<%d>: ERROR: sid %u: cannot accept on an "
2778 "epoll session!", getpid (), listen_session_index);
2779 return VPPCOM_EBADFD;
2780 }
2781
2782 if (listen_session->state != STATE_LISTEN)
2783 {
2784 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
2785 "not in listen state! state 0x%x (%s)", getpid (),
2786 listen_session->vpp_handle, listen_session_index,
2787 listen_session->state,
2788 vppcom_session_state_str (listen_session->state));
2789 return VPPCOM_EBADFD;
2790 }
2791 return VPPCOM_OK;
2792}
2793
2794int
Dave Wallace543852a2017-08-03 02:11:34 -04002795vppcom_session_accept (uint32_t listen_session_index, vppcom_endpt_t * ep,
Dave Wallace048b1d62018-01-03 22:24:41 -05002796 uint32_t flags)
Dave Wallace543852a2017-08-03 02:11:34 -04002797{
Dave Wallace33e002b2017-09-06 01:20:02 -04002798 session_t *listen_session = 0;
2799 session_t *client_session = 0;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002800 u32 client_session_index = ~0;
Dave Wallace543852a2017-08-03 02:11:34 -04002801 int rv;
Dave Wallaceee45d412017-11-24 21:44:06 -05002802 u64 listen_vpp_handle;
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002803 vce_event_handler_reg_t *reg;
2804 vce_event_t *ev;
2805 vce_event_connect_request_t *result;
2806 struct timespec ts;
2807 struct timeval tv;
2808 int millisecond_timeout = 1;
2809 int hours_timeout = 20 * 60 * 60;
Dave Wallace543852a2017-08-03 02:11:34 -04002810
Dave Wallace4878cbe2017-11-21 03:45:09 -05002811 VCL_LOCK_AND_GET_SESSION (listen_session_index, &listen_session);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002812 listen_vpp_handle = listen_session->vpp_handle; // For debugging
Dave Wallace543852a2017-08-03 02:11:34 -04002813
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002814 rv = validate_args_session_accept_ (listen_session);
2815 if (rv)
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002816 {
2817 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002818 goto done;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002819 }
2820
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002821 /* Using an aggressive timer of 1ms and a generous timer of
2822 * 20 hours, we can implement a blocking and non-blocking listener
2823 * as both event and time driven */
2824 gettimeofday (&tv, NULL);
2825 ts.tv_nsec = (tv.tv_usec * 1000) + (1000 * millisecond_timeout);
2826 ts.tv_sec = tv.tv_sec;
2827
2828 /* Predict that the Listener is blocking more often than not */
2829 if (PREDICT_TRUE (!VCL_SESS_ATTR_TEST (listen_session->attr,
2830 VCL_SESS_ATTR_NONBLOCK)))
2831 ts.tv_sec += hours_timeout;
Dave Wallace543852a2017-08-03 02:11:34 -04002832
Dave Wallace543852a2017-08-03 02:11:34 -04002833 clib_spinlock_unlock (&vcm->sessions_lockp);
2834
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002835 /* Register handler for connect_request event on listen_session_index */
2836 vce_event_key_t evk;
2837 evk.session_index = listen_session_index;
2838 evk.eid = VCL_EVENT_CONNECT_REQ_ACCEPTED;
2839 reg = vce_register_handler (&vcm->event_thread, &evk,
Keith Burns (alagalah)0d2b0d52018-03-06 15:55:22 -08002840 vce_connect_request_handler_fn, 0);
Keith Burns (alagalah)7cf80e02018-03-08 16:46:25 -08002841 ev = vce_get_event_from_index (&vcm->event_thread, reg->ev_idx);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002842 pthread_mutex_lock (&reg->handler_lock);
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08002843 while (!ev)
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002844 {
2845 rv =
2846 pthread_cond_timedwait (&reg->handler_cond, &reg->handler_lock, &ts);
2847 if (rv == ETIMEDOUT)
2848 {
2849 rv = VPPCOM_EAGAIN;
2850 goto cleanup;
2851 }
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08002852 ev = vce_get_event_from_index (&vcm->event_thread, reg->ev_idx);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002853 }
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08002854 result = (vce_event_connect_request_t *) ev->data;
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002855 client_session_index = result->accepted_session_index;
2856
2857
2858
2859 /* Remove from the FIFO used to service epoll */
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08002860 clib_spinlock_lock (&vcm->session_fifo_lockp);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002861 if (clib_fifo_elts (vcm->client_session_index_fifo))
2862 {
2863 u32 tmp_client_session_index;
2864 clib_fifo_sub1 (vcm->client_session_index_fifo,
2865 tmp_client_session_index);
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08002866 /* It wasn't ours... put it back ... */
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002867 if (tmp_client_session_index != client_session_index)
2868 clib_fifo_add1 (vcm->client_session_index_fifo,
2869 tmp_client_session_index);
2870 }
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08002871 clib_spinlock_unlock (&vcm->session_fifo_lockp);
2872
2873 clib_spinlock_lock (&vcm->sessions_lockp);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002874
Dave Wallace33e002b2017-09-06 01:20:02 -04002875 rv = vppcom_session_at_index (client_session_index, &client_session);
Dave Wallaceee45d412017-11-24 21:44:06 -05002876 if (PREDICT_FALSE (rv))
2877 {
2878 rv = VPPCOM_ECONNABORTED;
Dave Wallace048b1d62018-01-03 22:24:41 -05002879 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: client sid %u "
Dave Wallaceee45d412017-11-24 21:44:06 -05002880 "lookup failed! returning %d (%s)", getpid (),
2881 listen_vpp_handle, listen_session_index,
2882 client_session_index, rv, vppcom_retval_str (rv));
2883 goto done;
2884 }
Dave Wallace543852a2017-08-03 02:11:34 -04002885
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002886 if (flags & O_NONBLOCK)
2887 VCL_SESS_ATTR_SET (client_session->attr, VCL_SESS_ATTR_NONBLOCK);
2888 else
2889 VCL_SESS_ATTR_CLR (client_session->attr, VCL_SESS_ATTR_NONBLOCK);
2890
Dave Wallace543852a2017-08-03 02:11:34 -04002891 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002892 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: Got a client request! "
Dave Wallaceee45d412017-11-24 21:44:06 -05002893 "vpp handle 0x%llx, sid %u, flags %d, is_nonblocking %u",
2894 getpid (), listen_vpp_handle, listen_session_index,
2895 client_session->vpp_handle, client_session_index,
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002896 flags, VCL_SESS_ATTR_TEST (client_session->attr,
2897 VCL_SESS_ATTR_NONBLOCK));
Dave Wallace543852a2017-08-03 02:11:34 -04002898
Dave Wallace048b1d62018-01-03 22:24:41 -05002899 if (ep)
2900 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002901 ep->is_ip4 = client_session->peer_addr.is_ip4;
2902 ep->port = client_session->peer_port;
2903 if (client_session->peer_addr.is_ip4)
2904 clib_memcpy (ep->ip, &client_session->peer_addr.ip46.ip4,
2905 sizeof (ip4_address_t));
2906 else
2907 clib_memcpy (ep->ip, &client_session->peer_addr.ip46.ip6,
2908 sizeof (ip6_address_t));
2909 }
Dave Wallace60caa062017-11-10 17:07:13 -05002910
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002911 vppcom_send_accept_session_reply (client_session->vpp_handle,
2912 client_session->client_context,
2913 0 /* retval OK */ );
Dave Wallace60caa062017-11-10 17:07:13 -05002914
Stevenac1f96d2017-10-24 16:03:58 -07002915 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002916 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: accepted vpp handle "
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002917 "0x%llx, sid %u connection to local %s address "
Dave Wallaceee45d412017-11-24 21:44:06 -05002918 "%U port %u", getpid (), listen_vpp_handle,
2919 listen_session_index, client_session->vpp_handle,
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002920 client_session_index,
Dave Wallace4878cbe2017-11-21 03:45:09 -05002921 client_session->lcl_addr.is_ip4 ? "IPv4" : "IPv6",
2922 format_ip46_address, &client_session->lcl_addr.ip46,
2923 client_session->lcl_addr.is_ip4,
2924 clib_net_to_host_u16 (client_session->lcl_port));
Dave Wallace60caa062017-11-10 17:07:13 -05002925
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002926 if (VPPCOM_DEBUG > 0)
2927 {
2928 client_session->elog_track.name =
2929 (char *) format (0, "C:%d:S:%d%c", vcm->my_client_index,
2930 client_session_index, 0);
2931 elog_track_register (&vcm->elog_main, &client_session->elog_track);
2932
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002933 // Two elog entries due to 20-byte per entry constraint.
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002934 /* *INDENT-OFF* */
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002935 ELOG_TYPE_DECLARE (e) =
2936 {
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002937 .format = "accept: listen_handle:%x from_handle:%x",
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002938 .format_args = "i8i8",
2939 };
2940
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002941 struct
2942 {
2943 u64 handle[2];
2944 } *ed;
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002945
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002946 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, client_session->elog_track);
2947 ed->handle[0] = listen_vpp_handle;
2948 ed->handle[1] = client_session->vpp_handle;
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002949 /* *INDENT-ON* */
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002950
2951 if (client_session->lcl_addr.is_ip4)
2952 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08002953 /* *INDENT-OFF* */
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002954 ELOG_TYPE_DECLARE (e2) =
2955 {
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002956 .format = "accept: S:%d %d.%d.%d.%d:%d ",
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002957 .format_args = "i4i1i1i1i1i2",
2958 };
2959
2960 CLIB_PACKED (struct {
2961 u32 session;
2962 u8 addr[4];
2963 u16 port;
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002964 }) *ed2;
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002965
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002966 ed2 =
2967 ELOG_TRACK_DATA (&vcm->elog_main, e2, client_session->elog_track);
2968 ed2->session = client_session_index;
2969 ed2->addr[0] = client_session->lcl_addr.ip46.ip4.as_u8[0];
2970 ed2->addr[1] = client_session->lcl_addr.ip46.ip4.as_u8[1];
2971 ed2->addr[2] = client_session->lcl_addr.ip46.ip4.as_u8[2];
2972 ed2->addr[3] = client_session->lcl_addr.ip46.ip4.as_u8[3];
2973 ed2->port = clib_net_to_host_u16 (client_session->lcl_port);
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002974 /* *INDENT-ON* */
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002975 }
2976 }
2977
Dave Wallace543852a2017-08-03 02:11:34 -04002978 clib_spinlock_unlock (&vcm->sessions_lockp);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002979
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08002980 rv = (int) client_session_index;
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002981 vce_clear_event (&vcm->event_thread, ev);
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08002982
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002983cleanup:
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08002984 vce_unregister_handler (&vcm->event_thread, reg);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002985 pthread_mutex_unlock (&reg->handler_lock);
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08002986
Dave Wallace4878cbe2017-11-21 03:45:09 -05002987done:
2988 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04002989}
2990
2991int
2992vppcom_session_connect (uint32_t session_index, vppcom_endpt_t * server_ep)
2993{
Dave Wallace543852a2017-08-03 02:11:34 -04002994 session_t *session = 0;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002995 u64 vpp_handle = 0;
Dave Wallaceee45d412017-11-24 21:44:06 -05002996 int rv, retval = VPPCOM_OK;
Dave Wallace543852a2017-08-03 02:11:34 -04002997
Dave Wallace4878cbe2017-11-21 03:45:09 -05002998 VCL_LOCK_AND_GET_SESSION (session_index, &session);
2999
3000 if (PREDICT_FALSE (session->is_vep))
Dave Wallace543852a2017-08-03 02:11:34 -04003001 {
3002 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace048b1d62018-01-03 22:24:41 -05003003 clib_warning ("VCL<%d>: ERROR: sid %u: cannot "
3004 "connect on an epoll session!", getpid (), session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -05003005 rv = VPPCOM_EBADFD;
3006 goto done;
Dave Wallace543852a2017-08-03 02:11:34 -04003007 }
3008
Dave Wallace4878cbe2017-11-21 03:45:09 -05003009 if (PREDICT_FALSE (session->state & CLIENT_STATE_OPEN))
Dave Wallace543852a2017-08-03 02:11:34 -04003010 {
Dave Wallace543852a2017-08-03 02:11:34 -04003011 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05003012 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: session already "
Dave Wallaceee45d412017-11-24 21:44:06 -05003013 "connected to %s %U port %d proto %s, state 0x%x (%s)",
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003014 getpid (), session->vpp_handle, session_index,
Dave Wallace4878cbe2017-11-21 03:45:09 -05003015 session->peer_addr.is_ip4 ? "IPv4" : "IPv6",
3016 format_ip46_address,
3017 &session->peer_addr.ip46, session->peer_addr.is_ip4,
3018 clib_net_to_host_u16 (session->peer_port),
3019 session->proto ? "UDP" : "TCP", session->state,
3020 vppcom_session_state_str (session->state));
3021
3022 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace4878cbe2017-11-21 03:45:09 -05003023 goto done;
Dave Wallace543852a2017-08-03 02:11:34 -04003024 }
3025
Dave Wallace35830af2017-10-09 01:43:42 -04003026 session->peer_addr.is_ip4 = server_ep->is_ip4;
3027 session->peer_addr.ip46 = to_ip46 (!server_ep->is_ip4, server_ep->ip);
Stevenac1f96d2017-10-24 16:03:58 -07003028 session->peer_port = server_ep->port;
Dave Wallace543852a2017-08-03 02:11:34 -04003029
3030 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05003031 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: connecting to server "
Dave Wallaceee45d412017-11-24 21:44:06 -05003032 "%s %U port %d proto %s",
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003033 getpid (), session->vpp_handle, session_index,
Dave Wallace4878cbe2017-11-21 03:45:09 -05003034 session->peer_addr.is_ip4 ? "IPv4" : "IPv6",
3035 format_ip46_address,
3036 &session->peer_addr.ip46, session->peer_addr.is_ip4,
3037 clib_net_to_host_u16 (session->peer_port),
3038 session->proto ? "UDP" : "TCP");
Dave Wallace543852a2017-08-03 02:11:34 -04003039
3040 vppcom_send_connect_sock (session, session_index);
3041 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace4878cbe2017-11-21 03:45:09 -05003042
Dave Wallaceee45d412017-11-24 21:44:06 -05003043 retval =
3044 vppcom_wait_for_session_state_change (session_index, STATE_CONNECT,
3045 vcm->cfg.session_timeout);
3046
3047 VCL_LOCK_AND_GET_SESSION (session_index, &session);
3048 vpp_handle = session->vpp_handle;
3049 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace7876d392017-10-19 03:53:57 -04003050
Dave Wallace4878cbe2017-11-21 03:45:09 -05003051done:
Dave Wallaceee45d412017-11-24 21:44:06 -05003052 if (PREDICT_FALSE (retval))
3053 {
3054 rv = retval;
3055 if (VPPCOM_DEBUG > 0)
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003056 {
3057 if (session)
3058 clib_warning
3059 ("VCL<%d>: vpp handle 0x%llx, sid %u: connect failed! "
3060 "returning %d (%s)", getpid (), vpp_handle,
3061 session_index, rv, vppcom_retval_str (rv));
3062 else
3063 clib_warning ("VCL<%d>: no session for sid %u: connect failed! "
3064 "returning %d (%s)", getpid (),
3065 session_index, rv, vppcom_retval_str (rv));
3066 }
Dave Wallaceee45d412017-11-24 21:44:06 -05003067 }
3068 else if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05003069 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: connected!",
Dave Wallaceee45d412017-11-24 21:44:06 -05003070 getpid (), vpp_handle, session_index);
3071
Dave Wallace4878cbe2017-11-21 03:45:09 -05003072 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04003073}
3074
Steven58f464e2017-10-25 12:33:12 -07003075static inline int
3076vppcom_session_read_internal (uint32_t session_index, void *buf, int n,
3077 u8 peek)
Dave Wallace543852a2017-08-03 02:11:34 -04003078{
Dave Wallace543852a2017-08-03 02:11:34 -04003079 session_t *session = 0;
3080 svm_fifo_t *rx_fifo;
3081 int n_read = 0;
3082 int rv;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003083 int is_nonblocking;
3084
3085 u64 vpp_handle;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003086 u32 poll_et;
Dave Wallace4878cbe2017-11-21 03:45:09 -05003087 session_state_t state;
Dave Wallace543852a2017-08-03 02:11:34 -04003088
3089 ASSERT (buf);
3090
Dave Wallace4878cbe2017-11-21 03:45:09 -05003091 VCL_LOCK_AND_GET_SESSION (session_index, &session);
3092
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003093 is_nonblocking = VCL_SESS_ATTR_TEST (session->attr, VCL_SESS_ATTR_NONBLOCK);
3094 rx_fifo = session->rx_fifo;
3095 state = session->state;
3096 vpp_handle = session->vpp_handle;
3097
Dave Wallace4878cbe2017-11-21 03:45:09 -05003098 if (PREDICT_FALSE (session->is_vep))
Dave Wallace543852a2017-08-03 02:11:34 -04003099 {
3100 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace048b1d62018-01-03 22:24:41 -05003101 clib_warning ("VCL<%d>: ERROR: sid %u: cannot "
3102 "read from an epoll session!", getpid (), session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -05003103 rv = VPPCOM_EBADFD;
3104 goto done;
Dave Wallace543852a2017-08-03 02:11:34 -04003105 }
3106
Dave Wallace4878cbe2017-11-21 03:45:09 -05003107 if (PREDICT_FALSE (!(state & (SERVER_STATE_OPEN | CLIENT_STATE_OPEN))))
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003108 {
3109 clib_spinlock_unlock (&vcm->sessions_lockp);
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08003110 rv = ((state & STATE_DISCONNECT) ? VPPCOM_ECONNRESET : VPPCOM_ENOTCONN);
Dave Wallace4878cbe2017-11-21 03:45:09 -05003111
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003112 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05003113 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: %s session is "
Dave Wallaceee45d412017-11-24 21:44:06 -05003114 "not open! state 0x%x (%s), returning %d (%s)",
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003115 getpid (), vpp_handle, session_index, state,
Dave Wallace4878cbe2017-11-21 03:45:09 -05003116 vppcom_session_state_str (state),
3117 rv, vppcom_retval_str (rv));
3118 goto done;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003119 }
3120
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003121 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003122
3123 do
3124 {
Steven58f464e2017-10-25 12:33:12 -07003125 if (peek)
3126 n_read = svm_fifo_peek (rx_fifo, 0, n, buf);
3127 else
3128 n_read = svm_fifo_dequeue_nowait (rx_fifo, n, buf);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003129 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05003130 while (!is_nonblocking && (n_read <= 0));
Dave Wallacef7f809c2017-10-03 01:48:42 -04003131
Dave Wallace4878cbe2017-11-21 03:45:09 -05003132 if (n_read <= 0)
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003133 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05003134 VCL_LOCK_AND_GET_SESSION (session_index, &session);
3135
3136 poll_et = (((EPOLLET | EPOLLIN) & session->vep.ev.events) ==
3137 (EPOLLET | EPOLLIN));
3138 if (poll_et)
3139 session->vep.et_mask |= EPOLLIN;
3140
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08003141 if (state & STATE_CLOSE_ON_EMPTY)
Dave Wallace4878cbe2017-11-21 03:45:09 -05003142 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05003143 rv = VPPCOM_ECONNRESET;
3144
3145 if (VPPCOM_DEBUG > 1)
3146 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003147 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: Empty fifo "
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003148 "with session state 0x%x (%s)!"
Dave Wallaceee45d412017-11-24 21:44:06 -05003149 " Setting state to 0x%x (%s), returning %d (%s)",
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003150 getpid (), session->vpp_handle, session_index,
Dave Wallace4878cbe2017-11-21 03:45:09 -05003151 state, vppcom_session_state_str (state),
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003152 STATE_DISCONNECT,
3153 vppcom_session_state_str (STATE_DISCONNECT), rv,
3154 vppcom_retval_str (rv));
Dave Wallace4878cbe2017-11-21 03:45:09 -05003155 }
3156
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003157 session->state = STATE_DISCONNECT;
Dave Wallace4878cbe2017-11-21 03:45:09 -05003158 }
3159 else
3160 rv = VPPCOM_EAGAIN;
3161
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003162 clib_spinlock_unlock (&vcm->sessions_lockp);
3163 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05003164 else
3165 rv = n_read;
Dave Wallace543852a2017-08-03 02:11:34 -04003166
Dave Wallace4878cbe2017-11-21 03:45:09 -05003167 if (VPPCOM_DEBUG > 2)
3168 {
3169 if (rv > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05003170 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: read %d bytes "
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003171 "from (%p)", getpid (), vpp_handle,
3172 session_index, n_read, rx_fifo);
Dave Wallace4878cbe2017-11-21 03:45:09 -05003173 else
Dave Wallace048b1d62018-01-03 22:24:41 -05003174 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: nothing read! "
Dave Wallaceee45d412017-11-24 21:44:06 -05003175 "returning %d (%s)", getpid (), vpp_handle,
3176 session_index, rv, vppcom_retval_str (rv));
Dave Wallace4878cbe2017-11-21 03:45:09 -05003177 }
3178done:
3179 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04003180}
3181
Steven58f464e2017-10-25 12:33:12 -07003182int
Dave Wallace048b1d62018-01-03 22:24:41 -05003183vppcom_session_read (uint32_t session_index, void *buf, size_t n)
Steven58f464e2017-10-25 12:33:12 -07003184{
3185 return (vppcom_session_read_internal (session_index, buf, n, 0));
3186}
3187
3188static int
3189vppcom_session_peek (uint32_t session_index, void *buf, int n)
3190{
3191 return (vppcom_session_read_internal (session_index, buf, n, 1));
3192}
3193
Dave Wallace543852a2017-08-03 02:11:34 -04003194static inline int
3195vppcom_session_read_ready (session_t * session, u32 session_index)
3196{
Dave Wallace543852a2017-08-03 02:11:34 -04003197 int ready = 0;
Dave Wallace60caa062017-11-10 17:07:13 -05003198 u32 poll_et;
Dave Wallace4878cbe2017-11-21 03:45:09 -05003199 int rv;
Dave Wallace4878cbe2017-11-21 03:45:09 -05003200 session_state_t state = session->state;
Dave Wallaceee45d412017-11-24 21:44:06 -05003201 u64 vpp_handle = session->vpp_handle;
Dave Wallace543852a2017-08-03 02:11:34 -04003202
3203 /* Assumes caller has acquired spinlock: vcm->sessions_lockp */
Dave Wallace4878cbe2017-11-21 03:45:09 -05003204 if (PREDICT_FALSE (session->is_vep))
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003205 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003206 clib_warning ("VCL<%d>: ERROR: sid %u: cannot read from an "
Dave Wallace4878cbe2017-11-21 03:45:09 -05003207 "epoll session!", getpid (), session_index);
3208 rv = VPPCOM_EBADFD;
3209 goto done;
Dave Wallace543852a2017-08-03 02:11:34 -04003210 }
Dave Wallace33e002b2017-09-06 01:20:02 -04003211
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003212 if (session->state & STATE_LISTEN)
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08003213 {
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08003214 clib_spinlock_lock (&vcm->session_fifo_lockp);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08003215 ready = clib_fifo_elts (vcm->client_session_index_fifo);
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08003216 clib_spinlock_unlock (&vcm->session_fifo_lockp);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08003217 }
Dave Wallace543852a2017-08-03 02:11:34 -04003218 else
3219 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05003220 if (!(state & (SERVER_STATE_OPEN | CLIENT_STATE_OPEN | STATE_LISTEN)))
3221 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08003222 rv = ((state & STATE_DISCONNECT) ? VPPCOM_ECONNRESET :
Dave Wallace4878cbe2017-11-21 03:45:09 -05003223 VPPCOM_ENOTCONN);
3224
3225 if (VPPCOM_DEBUG > 1)
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003226 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: session is "
Dave Wallaceee45d412017-11-24 21:44:06 -05003227 "not open! state 0x%x (%s), returning %d (%s)",
3228 getpid (), vpp_handle, session_index,
Dave Wallace4878cbe2017-11-21 03:45:09 -05003229 state, vppcom_session_state_str (state),
3230 rv, vppcom_retval_str (rv));
3231 goto done;
3232 }
3233
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003234 ready = svm_fifo_max_dequeue (session->rx_fifo);
Dave Wallace543852a2017-08-03 02:11:34 -04003235 }
3236
Dave Wallace4878cbe2017-11-21 03:45:09 -05003237 if (ready == 0)
Dave Wallace60caa062017-11-10 17:07:13 -05003238 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05003239 poll_et =
3240 ((EPOLLET | EPOLLIN) & session->vep.ev.events) == (EPOLLET | EPOLLIN);
3241 if (poll_et)
3242 session->vep.et_mask |= EPOLLIN;
Dave Wallace60caa062017-11-10 17:07:13 -05003243
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08003244 if (state & STATE_CLOSE_ON_EMPTY)
Dave Wallace4878cbe2017-11-21 03:45:09 -05003245 {
3246 rv = VPPCOM_ECONNRESET;
Dave Wallace4878cbe2017-11-21 03:45:09 -05003247
3248 if (VPPCOM_DEBUG > 1)
3249 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003250 clib_warning ("VCL<%d>: vpp handle 0x%llx, "
3251 "sid %u: Empty fifo with"
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003252 " session state 0x%x (%s)! Setting state to "
Dave Wallaceee45d412017-11-24 21:44:06 -05003253 "0x%x (%s), returning %d (%s)",
3254 getpid (), session_index, vpp_handle,
Dave Wallace4878cbe2017-11-21 03:45:09 -05003255 state, vppcom_session_state_str (state),
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003256 STATE_DISCONNECT,
3257 vppcom_session_state_str (STATE_DISCONNECT), rv,
3258 vppcom_retval_str (rv));
Dave Wallace4878cbe2017-11-21 03:45:09 -05003259 }
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003260 session->state = STATE_DISCONNECT;
Dave Wallace4878cbe2017-11-21 03:45:09 -05003261 goto done;
3262 }
3263 }
3264 rv = ready;
Dave Wallace16cb4082017-11-29 03:24:06 -05003265
3266 if (vcm->app_event_queue->cursize &&
3267 !pthread_mutex_trylock (&vcm->app_event_queue->mutex))
3268 {
3269 u32 i, n_to_dequeue = vcm->app_event_queue->cursize;
3270 session_fifo_event_t e;
3271
3272 for (i = 0; i < n_to_dequeue; i++)
Florin Corase86a8ed2018-01-05 03:20:25 -08003273 svm_queue_sub_raw (vcm->app_event_queue, (u8 *) & e);
Dave Wallace16cb4082017-11-29 03:24:06 -05003274
3275 pthread_mutex_unlock (&vcm->app_event_queue->mutex);
3276 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05003277done:
3278 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04003279}
3280
3281int
Dave Wallace048b1d62018-01-03 22:24:41 -05003282vppcom_session_write (uint32_t session_index, void *buf, size_t n)
Dave Wallace543852a2017-08-03 02:11:34 -04003283{
Dave Wallace543852a2017-08-03 02:11:34 -04003284 session_t *session = 0;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003285 svm_fifo_t *tx_fifo = 0;
Florin Corase86a8ed2018-01-05 03:20:25 -08003286 svm_queue_t *q;
Dave Wallace543852a2017-08-03 02:11:34 -04003287 session_fifo_event_t evt;
Dave Wallace4878cbe2017-11-21 03:45:09 -05003288 session_state_t state;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003289 int rv, n_write, is_nonblocking;
3290 u32 poll_et;
Dave Wallaceee45d412017-11-24 21:44:06 -05003291 u64 vpp_handle;
Dave Wallace543852a2017-08-03 02:11:34 -04003292
3293 ASSERT (buf);
3294
Dave Wallace4878cbe2017-11-21 03:45:09 -05003295 VCL_LOCK_AND_GET_SESSION (session_index, &session);
3296
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003297 tx_fifo = session->tx_fifo;
3298 is_nonblocking = VCL_SESS_ATTR_TEST (session->attr, VCL_SESS_ATTR_NONBLOCK);
3299 vpp_handle = session->vpp_handle;
3300 state = session->state;
3301
Dave Wallace4878cbe2017-11-21 03:45:09 -05003302 if (PREDICT_FALSE (session->is_vep))
Dave Wallace543852a2017-08-03 02:11:34 -04003303 {
3304 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace048b1d62018-01-03 22:24:41 -05003305 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -05003306 "cannot write to an epoll session!",
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003307 getpid (), vpp_handle, session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -05003308
3309 rv = VPPCOM_EBADFD;
3310 goto done;
Dave Wallace543852a2017-08-03 02:11:34 -04003311 }
3312
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003313 if (!(session->state & (SERVER_STATE_OPEN | CLIENT_STATE_OPEN)))
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003314 {
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003315 rv =
3316 ((session->state & STATE_DISCONNECT) ? VPPCOM_ECONNRESET :
3317 VPPCOM_ENOTCONN);
Dave Wallace4878cbe2017-11-21 03:45:09 -05003318
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003319 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace4878cbe2017-11-21 03:45:09 -05003320 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05003321 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003322 "session is not open! state 0x%x (%s)",
Dave Wallaceee45d412017-11-24 21:44:06 -05003323 getpid (), vpp_handle, session_index,
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003324 state, vppcom_session_state_str (state));
Dave Wallace4878cbe2017-11-21 03:45:09 -05003325 goto done;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003326 }
3327
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003328 clib_spinlock_unlock (&vcm->sessions_lockp);
3329
Dave Wallace543852a2017-08-03 02:11:34 -04003330 do
3331 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003332 n_write = svm_fifo_enqueue_nowait (tx_fifo, n, (void *) buf);
Dave Wallace543852a2017-08-03 02:11:34 -04003333 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05003334 while (!is_nonblocking && (n_write <= 0));
Dave Wallace543852a2017-08-03 02:11:34 -04003335
3336 /* If event wasn't set, add one */
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003337 if ((n_write > 0) && svm_fifo_set_event (tx_fifo))
Dave Wallace543852a2017-08-03 02:11:34 -04003338 {
Dave Wallace543852a2017-08-03 02:11:34 -04003339 /* Fabricate TX event, send to vpp */
3340 evt.fifo = tx_fifo;
3341 evt.event_type = FIFO_EVENT_APP_TX;
Dave Wallace543852a2017-08-03 02:11:34 -04003342
Dave Wallace4878cbe2017-11-21 03:45:09 -05003343 VCL_LOCK_AND_GET_SESSION (session_index, &session);
3344 q = session->vpp_event_queue;
Dave Wallace543852a2017-08-03 02:11:34 -04003345 ASSERT (q);
Florin Corase86a8ed2018-01-05 03:20:25 -08003346 svm_queue_add (q, (u8 *) & evt, 0 /* do wait for mutex */ );
Dave Wallace4878cbe2017-11-21 03:45:09 -05003347 clib_spinlock_unlock (&vcm->sessions_lockp);
3348 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05003349 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -05003350 "added FIFO_EVENT_APP_TX to "
Dave Wallace4878cbe2017-11-21 03:45:09 -05003351 "vpp_event_q %p, n_write %d", getpid (),
Dave Wallaceee45d412017-11-24 21:44:06 -05003352 vpp_handle, session_index, q, n_write);
Dave Wallace543852a2017-08-03 02:11:34 -04003353 }
3354
Dave Wallace4878cbe2017-11-21 03:45:09 -05003355 if (n_write <= 0)
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003356 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05003357 VCL_LOCK_AND_GET_SESSION (session_index, &session);
3358
3359 poll_et = (((EPOLLET | EPOLLOUT) & session->vep.ev.events) ==
3360 (EPOLLET | EPOLLOUT));
3361 if (poll_et)
3362 session->vep.et_mask |= EPOLLOUT;
3363
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003364 if (session->state & STATE_CLOSE_ON_EMPTY)
Dave Wallace4878cbe2017-11-21 03:45:09 -05003365 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05003366 rv = VPPCOM_ECONNRESET;
3367
3368 if (VPPCOM_DEBUG > 1)
3369 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003370 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003371 "Empty fifo with session state 0x%x (%s)!"
Dave Wallaceee45d412017-11-24 21:44:06 -05003372 " Setting state to 0x%x (%s), returning %d (%s)",
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003373 getpid (), session->vpp_handle, session_index,
3374 session->state,
3375 vppcom_session_state_str (session->state),
3376 STATE_DISCONNECT,
3377 vppcom_session_state_str (STATE_DISCONNECT), rv,
3378 vppcom_retval_str (rv));
Dave Wallace4878cbe2017-11-21 03:45:09 -05003379 }
3380
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003381 session->state = STATE_DISCONNECT;
Dave Wallace4878cbe2017-11-21 03:45:09 -05003382 }
3383 else
3384 rv = VPPCOM_EAGAIN;
3385
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003386 clib_spinlock_unlock (&vcm->sessions_lockp);
3387 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05003388 else
3389 rv = n_write;
Dave Wallacef7f809c2017-10-03 01:48:42 -04003390
Dave Wallace543852a2017-08-03 02:11:34 -04003391 if (VPPCOM_DEBUG > 2)
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003392 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05003393 if (n_write <= 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05003394 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003395 "FIFO-FULL (%p)", getpid (), vpp_handle,
3396 session_index, tx_fifo);
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003397 else
Dave Wallace048b1d62018-01-03 22:24:41 -05003398 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003399 "wrote %d bytes tx-fifo: (%p)", getpid (),
3400 vpp_handle, session_index, n_write, tx_fifo);
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003401 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05003402done:
3403 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04003404}
3405
3406static inline int
3407vppcom_session_write_ready (session_t * session, u32 session_index)
3408{
Dave Wallacef7f809c2017-10-03 01:48:42 -04003409 int ready;
Dave Wallace60caa062017-11-10 17:07:13 -05003410 u32 poll_et;
Dave Wallace4878cbe2017-11-21 03:45:09 -05003411 int rv;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003412
3413 ASSERT (session);
Dave Wallace543852a2017-08-03 02:11:34 -04003414
3415 /* Assumes caller has acquired spinlock: vcm->sessions_lockp */
Dave Wallace4878cbe2017-11-21 03:45:09 -05003416 if (PREDICT_FALSE (session->is_vep))
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003417 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003418 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -05003419 "cannot write to an epoll session!",
3420 getpid (), session->vpp_handle, session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -05003421 rv = VPPCOM_EBADFD;
3422 goto done;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003423 }
3424
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003425 if (PREDICT_FALSE (session->state & STATE_LISTEN))
Dave Wallace33e002b2017-09-06 01:20:02 -04003426 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003427 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -05003428 "cannot write to a listen session!",
3429 getpid (), session->vpp_handle, session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -05003430 rv = VPPCOM_EBADFD;
3431 goto done;
3432 }
3433
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003434 if (!(session->state & (SERVER_STATE_OPEN | CLIENT_STATE_OPEN)))
Dave Wallace4878cbe2017-11-21 03:45:09 -05003435 {
3436 session_state_t state = session->state;
3437
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08003438 rv = ((state & STATE_DISCONNECT) ? VPPCOM_ECONNRESET : VPPCOM_ENOTCONN);
Dave Wallace4878cbe2017-11-21 03:45:09 -05003439
Dave Wallace048b1d62018-01-03 22:24:41 -05003440 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003441 "session is not open! state 0x%x (%s), "
Dave Wallaceee45d412017-11-24 21:44:06 -05003442 "returning %d (%s)", getpid (), session->vpp_handle,
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003443 session_index,
Dave Wallace4878cbe2017-11-21 03:45:09 -05003444 state, vppcom_session_state_str (state),
3445 rv, vppcom_retval_str (rv));
3446 goto done;
Dave Wallace33e002b2017-09-06 01:20:02 -04003447 }
3448
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003449 ready = svm_fifo_max_enqueue (session->tx_fifo);
Dave Wallace543852a2017-08-03 02:11:34 -04003450
Dave Wallace33e002b2017-09-06 01:20:02 -04003451 if (VPPCOM_DEBUG > 3)
Dave Wallace048b1d62018-01-03 22:24:41 -05003452 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -05003453 "peek %s (%p), ready = %d", getpid (),
3454 session->vpp_handle, session_index,
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003455 session->tx_fifo, ready);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003456
Dave Wallace4878cbe2017-11-21 03:45:09 -05003457 if (ready == 0)
3458 {
3459 poll_et = (((EPOLLET | EPOLLOUT) & session->vep.ev.events) ==
3460 (EPOLLET | EPOLLOUT));
3461 if (poll_et)
3462 session->vep.et_mask |= EPOLLOUT;
3463
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003464 if (session->state & STATE_CLOSE_ON_EMPTY)
Dave Wallace4878cbe2017-11-21 03:45:09 -05003465 {
3466 rv = VPPCOM_ECONNRESET;
Dave Wallace4878cbe2017-11-21 03:45:09 -05003467
3468 if (VPPCOM_DEBUG > 1)
3469 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003470 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003471 "Empty fifo with session "
Dave Wallaceee45d412017-11-24 21:44:06 -05003472 "state 0x%x (%s)! Setting state to 0x%x (%s), "
3473 "returning %d (%s)", getpid (),
3474 session->vpp_handle, session_index,
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003475 session->state,
3476 vppcom_session_state_str (session->state),
3477 STATE_DISCONNECT,
3478 vppcom_session_state_str (STATE_DISCONNECT), rv,
3479 vppcom_retval_str (rv));
Dave Wallace4878cbe2017-11-21 03:45:09 -05003480 }
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003481 session->state = STATE_DISCONNECT;
Dave Wallace4878cbe2017-11-21 03:45:09 -05003482 goto done;
3483 }
3484 }
3485 rv = ready;
3486done:
3487 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04003488}
3489
3490int
3491vppcom_select (unsigned long n_bits, unsigned long *read_map,
3492 unsigned long *write_map, unsigned long *except_map,
3493 double time_to_wait)
3494{
Dave Wallace543852a2017-08-03 02:11:34 -04003495 u32 session_index;
3496 session_t *session = 0;
3497 int rv, bits_set = 0;
3498 f64 timeout = clib_time_now (&vcm->clib_time) + time_to_wait;
3499 u32 minbits = clib_max (n_bits, BITS (uword));
3500
3501 ASSERT (sizeof (clib_bitmap_t) == sizeof (long int));
3502
Dave Wallace7876d392017-10-19 03:53:57 -04003503 if (n_bits && read_map)
Dave Wallace543852a2017-08-03 02:11:34 -04003504 {
3505 clib_bitmap_validate (vcm->rd_bitmap, minbits);
Dave Wallace048b1d62018-01-03 22:24:41 -05003506 clib_memcpy (vcm->rd_bitmap, read_map,
3507 vec_len (vcm->rd_bitmap) * sizeof (clib_bitmap_t));
3508 memset (read_map, 0, vec_len (vcm->rd_bitmap) * sizeof (clib_bitmap_t));
Dave Wallace543852a2017-08-03 02:11:34 -04003509 }
Dave Wallace7876d392017-10-19 03:53:57 -04003510 if (n_bits && write_map)
Dave Wallace543852a2017-08-03 02:11:34 -04003511 {
3512 clib_bitmap_validate (vcm->wr_bitmap, minbits);
Dave Wallace048b1d62018-01-03 22:24:41 -05003513 clib_memcpy (vcm->wr_bitmap, write_map,
3514 vec_len (vcm->wr_bitmap) * sizeof (clib_bitmap_t));
3515 memset (write_map, 0,
3516 vec_len (vcm->wr_bitmap) * sizeof (clib_bitmap_t));
Dave Wallace543852a2017-08-03 02:11:34 -04003517 }
Dave Wallace7876d392017-10-19 03:53:57 -04003518 if (n_bits && except_map)
Dave Wallace543852a2017-08-03 02:11:34 -04003519 {
3520 clib_bitmap_validate (vcm->ex_bitmap, minbits);
Dave Wallace048b1d62018-01-03 22:24:41 -05003521 clib_memcpy (vcm->ex_bitmap, except_map,
3522 vec_len (vcm->ex_bitmap) * sizeof (clib_bitmap_t));
3523 memset (except_map, 0,
3524 vec_len (vcm->ex_bitmap) * sizeof (clib_bitmap_t));
Dave Wallace543852a2017-08-03 02:11:34 -04003525 }
3526
3527 do
3528 {
3529 /* *INDENT-OFF* */
Dave Wallacee22aa742017-10-20 12:30:38 -04003530 if (n_bits)
3531 {
3532 if (read_map)
Dave Wallace543852a2017-08-03 02:11:34 -04003533 {
Dave Wallacee22aa742017-10-20 12:30:38 -04003534 clib_bitmap_foreach (session_index, vcm->rd_bitmap,
3535 ({
3536 clib_spinlock_lock (&vcm->sessions_lockp);
3537 rv = vppcom_session_at_index (session_index, &session);
3538 if (rv < 0)
3539 {
3540 clib_spinlock_unlock (&vcm->sessions_lockp);
3541 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05003542 clib_warning ("VCL<%d>: session %d specified in "
Dave Wallace2e005bb2017-11-07 01:21:39 -05003543 "read_map is closed.", getpid (),
Dave Wallacee22aa742017-10-20 12:30:38 -04003544 session_index);
3545 bits_set = VPPCOM_EBADFD;
3546 goto select_done;
3547 }
Dave Wallace8d73e852018-03-08 16:39:28 -05003548 if (session->state & STATE_LISTEN)
3549 {
3550 vce_event_handler_reg_t *reg = 0;
3551 vce_event_key_t evk;
Dave Wallacee22aa742017-10-20 12:30:38 -04003552
Dave Wallace8d73e852018-03-08 16:39:28 -05003553 /* Check if handler already registered for this
3554 * event.
3555 * If not, register handler for connect_request event
3556 * on listen_session_index
3557 */
3558 evk.session_index = session_index;
3559 evk.eid = VCL_EVENT_CONNECT_REQ_ACCEPTED;
3560 reg = vce_get_event_handler (&vcm->event_thread, &evk);
3561 if (!reg)
3562 reg = vce_register_handler (&vcm->event_thread, &evk,
Keith Burns (alagalah)0d2b0d52018-03-06 15:55:22 -08003563 vce_poll_wait_connect_request_handler_fn,
3564 0 /* No callback args */);
Dave Wallace8d73e852018-03-08 16:39:28 -05003565 rv = vppcom_session_read_ready (session, session_index);
3566 if (rv > 0)
3567 {
3568 vce_unregister_handler (&vcm->event_thread, reg);
3569 }
3570 }
3571 else
3572 rv = vppcom_session_read_ready (session, session_index);
Dave Wallacee22aa742017-10-20 12:30:38 -04003573 clib_spinlock_unlock (&vcm->sessions_lockp);
3574 if (except_map && vcm->ex_bitmap &&
3575 clib_bitmap_get (vcm->ex_bitmap, session_index) &&
3576 (rv < 0))
3577 {
Dave Wallacee22aa742017-10-20 12:30:38 -04003578 clib_bitmap_set_no_check (except_map, session_index, 1);
3579 bits_set++;
3580 }
3581 else if (rv > 0)
3582 {
Dave Wallacee22aa742017-10-20 12:30:38 -04003583 clib_bitmap_set_no_check (read_map, session_index, 1);
3584 bits_set++;
3585 }
3586 }));
Dave Wallace543852a2017-08-03 02:11:34 -04003587 }
3588
Dave Wallacee22aa742017-10-20 12:30:38 -04003589 if (write_map)
Dave Wallace543852a2017-08-03 02:11:34 -04003590 {
Dave Wallacee22aa742017-10-20 12:30:38 -04003591 clib_bitmap_foreach (session_index, vcm->wr_bitmap,
3592 ({
3593 clib_spinlock_lock (&vcm->sessions_lockp);
3594 rv = vppcom_session_at_index (session_index, &session);
3595 if (rv < 0)
3596 {
3597 clib_spinlock_unlock (&vcm->sessions_lockp);
3598 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05003599 clib_warning ("VCL<%d>: session %d specified in "
Dave Wallace2e005bb2017-11-07 01:21:39 -05003600 "write_map is closed.", getpid (),
Dave Wallacee22aa742017-10-20 12:30:38 -04003601 session_index);
3602 bits_set = VPPCOM_EBADFD;
3603 goto select_done;
3604 }
Dave Wallace543852a2017-08-03 02:11:34 -04003605
Dave Wallacee22aa742017-10-20 12:30:38 -04003606 rv = vppcom_session_write_ready (session, session_index);
3607 clib_spinlock_unlock (&vcm->sessions_lockp);
3608 if (write_map && (rv > 0))
3609 {
Dave Wallacee22aa742017-10-20 12:30:38 -04003610 clib_bitmap_set_no_check (write_map, session_index, 1);
3611 bits_set++;
3612 }
3613 }));
Dave Wallace543852a2017-08-03 02:11:34 -04003614 }
3615
Dave Wallacee22aa742017-10-20 12:30:38 -04003616 if (except_map)
Dave Wallace543852a2017-08-03 02:11:34 -04003617 {
Dave Wallacee22aa742017-10-20 12:30:38 -04003618 clib_bitmap_foreach (session_index, vcm->ex_bitmap,
3619 ({
3620 clib_spinlock_lock (&vcm->sessions_lockp);
3621 rv = vppcom_session_at_index (session_index, &session);
3622 if (rv < 0)
3623 {
3624 clib_spinlock_unlock (&vcm->sessions_lockp);
3625 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05003626 clib_warning ("VCL<%d>: session %d specified in "
Dave Wallace2e005bb2017-11-07 01:21:39 -05003627 "except_map is closed.", getpid (),
Dave Wallacee22aa742017-10-20 12:30:38 -04003628 session_index);
3629 bits_set = VPPCOM_EBADFD;
3630 goto select_done;
3631 }
Dave Wallace543852a2017-08-03 02:11:34 -04003632
Dave Wallacee22aa742017-10-20 12:30:38 -04003633 rv = vppcom_session_read_ready (session, session_index);
3634 clib_spinlock_unlock (&vcm->sessions_lockp);
3635 if (rv < 0)
3636 {
Dave Wallacee22aa742017-10-20 12:30:38 -04003637 clib_bitmap_set_no_check (except_map, session_index, 1);
3638 bits_set++;
3639 }
3640 }));
Dave Wallace543852a2017-08-03 02:11:34 -04003641 }
Dave Wallacee22aa742017-10-20 12:30:38 -04003642 }
Dave Wallace543852a2017-08-03 02:11:34 -04003643 /* *INDENT-ON* */
3644 }
Dave Wallace048b1d62018-01-03 22:24:41 -05003645 while ((time_to_wait == -1) || (clib_time_now (&vcm->clib_time) < timeout));
Dave Wallace543852a2017-08-03 02:11:34 -04003646
3647select_done:
3648 return (bits_set);
3649}
3650
Dave Wallacef7f809c2017-10-03 01:48:42 -04003651static inline void
3652vep_verify_epoll_chain (u32 vep_idx)
3653{
3654 session_t *session;
3655 vppcom_epoll_t *vep;
3656 int rv;
Dave Wallace498b3a52017-11-09 13:00:34 -05003657 u32 sid = vep_idx;
Dave Wallacef7f809c2017-10-03 01:48:42 -04003658
Dave Wallace498b3a52017-11-09 13:00:34 -05003659 if (VPPCOM_DEBUG <= 1)
Dave Wallacef7f809c2017-10-03 01:48:42 -04003660 return;
3661
3662 /* Assumes caller has acquired spinlock: vcm->sessions_lockp */
3663 rv = vppcom_session_at_index (vep_idx, &session);
3664 if (PREDICT_FALSE (rv))
3665 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003666 clib_warning ("VCL<%d>: ERROR: Invalid vep_idx (%u)!",
3667 getpid (), vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003668 goto done;
3669 }
3670 if (PREDICT_FALSE (!session->is_vep))
3671 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003672 clib_warning ("VCL<%d>: ERROR: vep_idx (%u) is not a vep!",
3673 getpid (), vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003674 goto done;
3675 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05003676 vep = &session->vep;
Dave Wallace048b1d62018-01-03 22:24:41 -05003677 clib_warning ("VCL<%d>: vep_idx (%u): Dumping epoll chain\n"
Dave Wallace498b3a52017-11-09 13:00:34 -05003678 "{\n"
3679 " is_vep = %u\n"
3680 " is_vep_session = %u\n"
Dave Wallace4878cbe2017-11-21 03:45:09 -05003681 " next_sid = 0x%x (%u)\n"
Dave Wallace498b3a52017-11-09 13:00:34 -05003682 " wait_cont_idx = 0x%x (%u)\n"
Dave Wallace4878cbe2017-11-21 03:45:09 -05003683 "}\n", getpid (), vep_idx,
3684 session->is_vep, session->is_vep_session,
3685 vep->next_sid, vep->next_sid,
Dave Wallace498b3a52017-11-09 13:00:34 -05003686 session->wait_cont_idx, session->wait_cont_idx);
Dave Wallace4878cbe2017-11-21 03:45:09 -05003687
3688 for (sid = vep->next_sid; sid != ~0; sid = vep->next_sid)
Dave Wallacef7f809c2017-10-03 01:48:42 -04003689 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05003690 rv = vppcom_session_at_index (sid, &session);
3691 if (PREDICT_FALSE (rv))
Dave Wallacef7f809c2017-10-03 01:48:42 -04003692 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003693 clib_warning ("VCL<%d>: ERROR: Invalid sid (%u)!", getpid (), sid);
Dave Wallace4878cbe2017-11-21 03:45:09 -05003694 goto done;
3695 }
3696 if (PREDICT_FALSE (session->is_vep))
Dave Wallace048b1d62018-01-03 22:24:41 -05003697 clib_warning ("VCL<%d>: ERROR: sid (%u) is a vep!",
3698 getpid (), vep_idx);
Dave Wallace4878cbe2017-11-21 03:45:09 -05003699 else if (PREDICT_FALSE (!session->is_vep_session))
3700 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003701 clib_warning ("VCL<%d>: ERROR: session (%u) "
3702 "is not a vep session!", getpid (), sid);
Dave Wallace4878cbe2017-11-21 03:45:09 -05003703 goto done;
3704 }
3705 vep = &session->vep;
3706 if (PREDICT_FALSE (vep->vep_idx != vep_idx))
Dave Wallace048b1d62018-01-03 22:24:41 -05003707 clib_warning ("VCL<%d>: ERROR: session (%u) vep_idx (%u) != "
Dave Wallace4878cbe2017-11-21 03:45:09 -05003708 "vep_idx (%u)!", getpid (),
3709 sid, session->vep.vep_idx, vep_idx);
3710 if (session->is_vep_session)
3711 {
3712 clib_warning ("vep_idx[%u]: sid 0x%x (%u)\n"
3713 "{\n"
3714 " next_sid = 0x%x (%u)\n"
3715 " prev_sid = 0x%x (%u)\n"
3716 " vep_idx = 0x%x (%u)\n"
3717 " ev.events = 0x%x\n"
3718 " ev.data.u64 = 0x%llx\n"
3719 " et_mask = 0x%x\n"
3720 "}\n",
3721 vep_idx, sid, sid,
3722 vep->next_sid, vep->next_sid,
3723 vep->prev_sid, vep->prev_sid,
3724 vep->vep_idx, vep->vep_idx,
3725 vep->ev.events, vep->ev.data.u64, vep->et_mask);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003726 }
3727 }
Dave Wallacef7f809c2017-10-03 01:48:42 -04003728
3729done:
Dave Wallace048b1d62018-01-03 22:24:41 -05003730 clib_warning ("VCL<%d>: vep_idx (%u): Dump complete!\n",
3731 getpid (), vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003732}
3733
3734int
3735vppcom_epoll_create (void)
3736{
Dave Wallacef7f809c2017-10-03 01:48:42 -04003737 session_t *vep_session;
3738 u32 vep_idx;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003739 elog_track_t vep_elog_track;
Dave Wallacef7f809c2017-10-03 01:48:42 -04003740
3741 clib_spinlock_lock (&vcm->sessions_lockp);
3742 pool_get (vcm->sessions, vep_session);
3743 memset (vep_session, 0, sizeof (*vep_session));
3744 vep_idx = vep_session - vcm->sessions;
3745
3746 vep_session->is_vep = 1;
3747 vep_session->vep.vep_idx = ~0;
3748 vep_session->vep.next_sid = ~0;
3749 vep_session->vep.prev_sid = ~0;
3750 vep_session->wait_cont_idx = ~0;
Dave Wallace4878cbe2017-11-21 03:45:09 -05003751 vep_session->vpp_handle = ~0;
Keith Burns (alagalah)12756512018-03-06 05:55:27 -08003752 vep_session->poll_reg = 0;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003753
3754 if (VPPCOM_DEBUG > 0)
3755 {
3756 vep_session->elog_track.name =
3757 (char *) format (0, "C:%d:VEP:%d%c", vcm->my_client_index,
3758 vep_idx, 0);
3759 elog_track_register (&vcm->elog_main, &vep_session->elog_track);
3760 vep_elog_track = vep_session->elog_track;
3761 }
3762
Dave Wallacef7f809c2017-10-03 01:48:42 -04003763 clib_spinlock_unlock (&vcm->sessions_lockp);
3764
3765 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05003766 clib_warning ("VCL<%d>: Created vep_idx %u / sid %u!",
Dave Wallaceee45d412017-11-24 21:44:06 -05003767 getpid (), vep_idx, vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003768
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08003769 if (VPPCOM_DEBUG > 0)
3770 {
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08003771
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08003772 /* *INDENT-OFF* */
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08003773 ELOG_TYPE_DECLARE (e) =
3774 {
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08003775 .format = "created epoll session:%d",
3776 .format_args = "i4",
3777 };
3778
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08003779 struct
3780 {
3781 u32 data;
3782 } *ed;
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08003783
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003784 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, vep_elog_track);
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08003785 ed->data = vep_idx;
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08003786 /* *INDENT-ON* */
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08003787 }
3788
Dave Wallacef7f809c2017-10-03 01:48:42 -04003789 return (vep_idx);
3790}
3791
3792int
3793vppcom_epoll_ctl (uint32_t vep_idx, int op, uint32_t session_index,
3794 struct epoll_event *event)
3795{
Dave Wallacef7f809c2017-10-03 01:48:42 -04003796 session_t *vep_session;
3797 session_t *session;
3798 int rv;
3799
3800 if (vep_idx == session_index)
3801 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003802 clib_warning ("VCL<%d>: ERROR: vep_idx == session_index (%u)!",
Dave Wallace4878cbe2017-11-21 03:45:09 -05003803 getpid (), vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003804 return VPPCOM_EINVAL;
3805 }
3806
3807 clib_spinlock_lock (&vcm->sessions_lockp);
3808 rv = vppcom_session_at_index (vep_idx, &vep_session);
3809 if (PREDICT_FALSE (rv))
3810 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003811 clib_warning ("VCL<%d>: ERROR: Invalid vep_idx (%u)!", vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003812 goto done;
3813 }
3814 if (PREDICT_FALSE (!vep_session->is_vep))
3815 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003816 clib_warning ("VCL<%d>: ERROR: vep_idx (%u) is not a vep!",
Dave Wallace4878cbe2017-11-21 03:45:09 -05003817 getpid (), vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003818 rv = VPPCOM_EINVAL;
3819 goto done;
3820 }
3821
3822 ASSERT (vep_session->vep.vep_idx == ~0);
3823 ASSERT (vep_session->vep.prev_sid == ~0);
3824
3825 rv = vppcom_session_at_index (session_index, &session);
3826 if (PREDICT_FALSE (rv))
3827 {
3828 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05003829 clib_warning ("VCL<%d>: ERROR: Invalid session_index (%u)!",
Dave Wallace2e005bb2017-11-07 01:21:39 -05003830 getpid (), session_index);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003831 goto done;
3832 }
3833 if (PREDICT_FALSE (session->is_vep))
3834 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05003835 clib_warning ("ERROR: session_index (%u) is a vep!", vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003836 rv = VPPCOM_EINVAL;
3837 goto done;
3838 }
3839
3840 switch (op)
3841 {
3842 case EPOLL_CTL_ADD:
3843 if (PREDICT_FALSE (!event))
3844 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003845 clib_warning ("VCL<%d>: ERROR: EPOLL_CTL_ADD: NULL pointer to "
Dave Wallace2e005bb2017-11-07 01:21:39 -05003846 "epoll_event structure!", getpid ());
Dave Wallacef7f809c2017-10-03 01:48:42 -04003847 rv = VPPCOM_EINVAL;
3848 goto done;
3849 }
3850 if (vep_session->vep.next_sid != ~0)
3851 {
3852 session_t *next_session;
3853 rv = vppcom_session_at_index (vep_session->vep.next_sid,
3854 &next_session);
3855 if (PREDICT_FALSE (rv))
3856 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003857 clib_warning ("VCL<%d>: ERROR: EPOLL_CTL_ADD: Invalid "
Dave Wallace4878cbe2017-11-21 03:45:09 -05003858 "vep.next_sid (%u) on vep_idx (%u)!",
3859 getpid (), vep_session->vep.next_sid, vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003860 goto done;
3861 }
3862 ASSERT (next_session->vep.prev_sid == vep_idx);
3863 next_session->vep.prev_sid = session_index;
3864 }
3865 session->vep.next_sid = vep_session->vep.next_sid;
3866 session->vep.prev_sid = vep_idx;
3867 session->vep.vep_idx = vep_idx;
3868 session->vep.et_mask = VEP_DEFAULT_ET_MASK;
3869 session->vep.ev = *event;
Dave Wallace4878cbe2017-11-21 03:45:09 -05003870 session->is_vep = 0;
Dave Wallacef7f809c2017-10-03 01:48:42 -04003871 session->is_vep_session = 1;
3872 vep_session->vep.next_sid = session_index;
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08003873
3874 /* VCL Event Register handler */
3875 if (session->state & STATE_LISTEN)
3876 {
3877 /* Register handler for connect_request event on listen_session_index */
3878 vce_event_key_t evk;
3879 evk.session_index = session_index;
3880 evk.eid = VCL_EVENT_CONNECT_REQ_ACCEPTED;
Keith Burns (alagalah)12756512018-03-06 05:55:27 -08003881 vep_session->poll_reg =
3882 vce_register_handler (&vcm->event_thread, &evk,
Keith Burns (alagalah)0d2b0d52018-03-06 15:55:22 -08003883 vce_poll_wait_connect_request_handler_fn,
3884 0 /* No callback args */ );
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08003885 }
Dave Wallacef7f809c2017-10-03 01:48:42 -04003886 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05003887 clib_warning ("VCL<%d>: EPOLL_CTL_ADD: vep_idx %u, "
3888 "sid %u, events 0x%x, data 0x%llx!",
3889 getpid (), vep_idx, session_index,
Dave Wallacef7f809c2017-10-03 01:48:42 -04003890 event->events, event->data.u64);
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08003891 if (VPPCOM_DEBUG > 0)
3892 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08003893 /* *INDENT-OFF* */
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08003894 ELOG_TYPE_DECLARE (e) =
3895 {
3896 .format = "epoll_ctladd: events:%x data:%x",
3897 .format_args = "i4i4i8",
3898 };
3899 struct
3900 {
3901 u32 events;
3902 u64 event_data;
3903 } *ed;
3904
3905 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
3906
3907 ed->events = event->events;
3908 ed->event_data = event->data.u64;
3909 /* *INDENT-ON* */
3910 }
Dave Wallacef7f809c2017-10-03 01:48:42 -04003911 break;
3912
3913 case EPOLL_CTL_MOD:
3914 if (PREDICT_FALSE (!event))
3915 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003916 clib_warning ("VCL<%d>: ERROR: EPOLL_CTL_MOD: NULL pointer to "
Dave Wallace2e005bb2017-11-07 01:21:39 -05003917 "epoll_event structure!", getpid ());
Dave Wallacef7f809c2017-10-03 01:48:42 -04003918 rv = VPPCOM_EINVAL;
3919 goto done;
3920 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05003921 else if (PREDICT_FALSE (!session->is_vep_session))
Dave Wallacef7f809c2017-10-03 01:48:42 -04003922 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003923 clib_warning ("VCL<%d>: ERROR: sid %u EPOLL_CTL_MOD: "
Dave Wallace4878cbe2017-11-21 03:45:09 -05003924 "not a vep session!", getpid (), session_index);
3925 rv = VPPCOM_EINVAL;
3926 goto done;
3927 }
3928 else if (PREDICT_FALSE (session->vep.vep_idx != vep_idx))
3929 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003930 clib_warning ("VCL<%d>: ERROR: sid %u EPOLL_CTL_MOD: "
Dave Wallace4878cbe2017-11-21 03:45:09 -05003931 "vep_idx (%u) != vep_idx (%u)!",
3932 getpid (), session_index,
3933 session->vep.vep_idx, vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003934 rv = VPPCOM_EINVAL;
3935 goto done;
3936 }
3937 session->vep.et_mask = VEP_DEFAULT_ET_MASK;
3938 session->vep.ev = *event;
3939 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05003940 clib_warning
3941 ("VCL<%d>: EPOLL_CTL_MOD: vep_idx %u, sid %u, events 0x%x,"
3942 " data 0x%llx!", getpid (), vep_idx, session_index, event->events,
3943 event->data.u64);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003944 break;
3945
3946 case EPOLL_CTL_DEL:
Dave Wallace4878cbe2017-11-21 03:45:09 -05003947 if (PREDICT_FALSE (!session->is_vep_session))
Dave Wallacef7f809c2017-10-03 01:48:42 -04003948 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003949 clib_warning ("VCL<%d>: ERROR: sid %u EPOLL_CTL_DEL: "
Dave Wallace4878cbe2017-11-21 03:45:09 -05003950 "not a vep session!", getpid (), session_index);
3951 rv = VPPCOM_EINVAL;
3952 goto done;
3953 }
3954 else if (PREDICT_FALSE (session->vep.vep_idx != vep_idx))
3955 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003956 clib_warning ("VCL<%d>: ERROR: sid %u EPOLL_CTL_DEL: "
Dave Wallace4878cbe2017-11-21 03:45:09 -05003957 "vep_idx (%u) != vep_idx (%u)!",
3958 getpid (), session_index,
3959 session->vep.vep_idx, vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003960 rv = VPPCOM_EINVAL;
3961 goto done;
3962 }
3963
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08003964 /* VCL Event Un-register handler */
Keith Burns (alagalah)12756512018-03-06 05:55:27 -08003965 if ((session->state & STATE_LISTEN) && vep_session->poll_reg)
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08003966 {
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08003967 (void) vce_unregister_handler (&vcm->event_thread,
3968 vep_session->poll_reg);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08003969 }
3970
Dave Wallacef7f809c2017-10-03 01:48:42 -04003971 vep_session->wait_cont_idx =
3972 (vep_session->wait_cont_idx == session_index) ?
3973 session->vep.next_sid : vep_session->wait_cont_idx;
3974
3975 if (session->vep.prev_sid == vep_idx)
3976 vep_session->vep.next_sid = session->vep.next_sid;
3977 else
3978 {
3979 session_t *prev_session;
3980 rv = vppcom_session_at_index (session->vep.prev_sid, &prev_session);
3981 if (PREDICT_FALSE (rv))
3982 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003983 clib_warning ("VCL<%d>: ERROR: EPOLL_CTL_DEL: Invalid "
Dave Wallace4878cbe2017-11-21 03:45:09 -05003984 "vep.prev_sid (%u) on sid (%u)!",
3985 getpid (), session->vep.prev_sid, session_index);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003986 goto done;
3987 }
3988 ASSERT (prev_session->vep.next_sid == session_index);
3989 prev_session->vep.next_sid = session->vep.next_sid;
3990 }
3991 if (session->vep.next_sid != ~0)
3992 {
3993 session_t *next_session;
3994 rv = vppcom_session_at_index (session->vep.next_sid, &next_session);
3995 if (PREDICT_FALSE (rv))
3996 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003997 clib_warning ("VCL<%d>: ERROR: EPOLL_CTL_DEL: Invalid "
Dave Wallace4878cbe2017-11-21 03:45:09 -05003998 "vep.next_sid (%u) on sid (%u)!",
3999 getpid (), session->vep.next_sid, session_index);
Dave Wallacef7f809c2017-10-03 01:48:42 -04004000 goto done;
4001 }
4002 ASSERT (next_session->vep.prev_sid == session_index);
4003 next_session->vep.prev_sid = session->vep.prev_sid;
4004 }
4005
4006 memset (&session->vep, 0, sizeof (session->vep));
4007 session->vep.next_sid = ~0;
4008 session->vep.prev_sid = ~0;
4009 session->vep.vep_idx = ~0;
4010 session->is_vep_session = 0;
4011 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05004012 clib_warning ("VCL<%d>: EPOLL_CTL_DEL: vep_idx %u, sid %u!",
Dave Wallace2e005bb2017-11-07 01:21:39 -05004013 getpid (), vep_idx, session_index);
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004014 if (VPPCOM_DEBUG > 0)
4015 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08004016 /* *INDENT-OFF* */
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004017 ELOG_TYPE_DECLARE (e) =
4018 {
4019 .format = "epoll_ctldel: vep:%d",
4020 .format_args = "i4",
4021 };
4022 struct
4023 {
4024 u32 data;
4025 } *ed;
4026
4027 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4028
4029 ed->data = vep_idx;
4030 /* *INDENT-ON* */
4031 }
Dave Wallacef7f809c2017-10-03 01:48:42 -04004032 break;
4033
4034 default:
Dave Wallace048b1d62018-01-03 22:24:41 -05004035 clib_warning ("VCL<%d>: ERROR: Invalid operation (%d)!", getpid (), op);
Dave Wallacef7f809c2017-10-03 01:48:42 -04004036 rv = VPPCOM_EINVAL;
4037 }
4038
4039 vep_verify_epoll_chain (vep_idx);
4040
4041done:
4042 clib_spinlock_unlock (&vcm->sessions_lockp);
4043 return rv;
4044}
4045
Dave Wallacef7f809c2017-10-03 01:48:42 -04004046int
4047vppcom_epoll_wait (uint32_t vep_idx, struct epoll_event *events,
4048 int maxevents, double wait_for_time)
4049{
Dave Wallacef7f809c2017-10-03 01:48:42 -04004050 session_t *vep_session;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08004051 elog_track_t vep_elog_track;
Dave Wallacef7f809c2017-10-03 01:48:42 -04004052 int rv;
4053 f64 timeout = clib_time_now (&vcm->clib_time) + wait_for_time;
Dave Wallace2e005bb2017-11-07 01:21:39 -05004054 u32 keep_trying = 1;
Dave Wallacef7f809c2017-10-03 01:48:42 -04004055 int num_ev = 0;
4056 u32 vep_next_sid, wait_cont_idx;
4057 u8 is_vep;
4058
4059 if (PREDICT_FALSE (maxevents <= 0))
4060 {
Dave Wallace048b1d62018-01-03 22:24:41 -05004061 clib_warning ("VCL<%d>: ERROR: Invalid maxevents (%d)!",
Dave Wallace4878cbe2017-11-21 03:45:09 -05004062 getpid (), maxevents);
Dave Wallacef7f809c2017-10-03 01:48:42 -04004063 return VPPCOM_EINVAL;
4064 }
Dave Wallacef7f809c2017-10-03 01:48:42 -04004065 memset (events, 0, sizeof (*events) * maxevents);
4066
4067 VCL_LOCK_AND_GET_SESSION (vep_idx, &vep_session);
4068 vep_next_sid = vep_session->vep.next_sid;
4069 is_vep = vep_session->is_vep;
4070 wait_cont_idx = vep_session->wait_cont_idx;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08004071 vep_elog_track = vep_session->elog_track;
Dave Wallacef7f809c2017-10-03 01:48:42 -04004072 clib_spinlock_unlock (&vcm->sessions_lockp);
4073
4074 if (PREDICT_FALSE (!is_vep))
4075 {
Dave Wallace048b1d62018-01-03 22:24:41 -05004076 clib_warning ("VCL<%d>: ERROR: vep_idx (%u) is not a vep!",
Dave Wallace4878cbe2017-11-21 03:45:09 -05004077 getpid (), vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04004078 rv = VPPCOM_EINVAL;
4079 goto done;
4080 }
Dave Wallacee695cb42017-11-02 22:04:42 -04004081 if (PREDICT_FALSE (vep_next_sid == ~0))
Dave Wallacef7f809c2017-10-03 01:48:42 -04004082 {
Dave Wallace69d01192018-02-22 16:22:09 -05004083 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05004084 clib_warning ("VCL<%d>: WARNING: vep_idx (%u) is empty!",
Dave Wallace2e005bb2017-11-07 01:21:39 -05004085 getpid (), vep_idx);
Dave Wallace69d01192018-02-22 16:22:09 -05004086 if (VPPCOM_DEBUG > 1)
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004087 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08004088 /* *INDENT-OFF* */
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004089 ELOG_TYPE_DECLARE (e) =
4090 {
4091 .format = "WRN: vep_idx:%d empty",
4092 .format_args = "i4",
4093 };
4094 struct
4095 {
4096 u32 data;
4097 } *ed;
4098
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08004099 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, vep_elog_track);
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004100
4101 ed->data = vep_idx;
4102 /* *INDENT-ON* */
4103 }
Dave Wallacef7f809c2017-10-03 01:48:42 -04004104 goto done;
4105 }
4106
4107 do
4108 {
4109 u32 sid;
4110 u32 next_sid = ~0;
4111 session_t *session;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08004112 elog_track_t session_elog_track;
Dave Wallacef7f809c2017-10-03 01:48:42 -04004113
4114 for (sid = (wait_cont_idx == ~0) ? vep_next_sid : wait_cont_idx;
4115 sid != ~0; sid = next_sid)
4116 {
4117 u32 session_events, et_mask, clear_et_mask, session_vep_idx;
4118 u8 add_event, is_vep_session;
4119 int ready;
4120 u64 session_ev_data;
4121
4122 VCL_LOCK_AND_GET_SESSION (sid, &session);
4123 next_sid = session->vep.next_sid;
4124 session_events = session->vep.ev.events;
4125 et_mask = session->vep.et_mask;
4126 is_vep = session->is_vep;
4127 is_vep_session = session->is_vep_session;
4128 session_vep_idx = session->vep.vep_idx;
4129 session_ev_data = session->vep.ev.data.u64;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08004130
4131 if (VPPCOM_DEBUG > 0)
4132 {
4133 session_elog_track = session->elog_track;
4134 }
4135
Dave Wallacef7f809c2017-10-03 01:48:42 -04004136 clib_spinlock_unlock (&vcm->sessions_lockp);
4137
4138 if (PREDICT_FALSE (is_vep))
4139 {
4140 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05004141 clib_warning ("VCL<%d>: ERROR: sid (%u) is a vep!",
Dave Wallace2e005bb2017-11-07 01:21:39 -05004142 getpid (), vep_idx);
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004143 if (VPPCOM_DEBUG > 0)
4144 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08004145 /* *INDENT-OFF* */
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004146 ELOG_TYPE_DECLARE (e) =
4147 {
4148 .format = "ERR:vep_idx:%d is vep",
4149 .format_args = "i4",
4150 };
4151 struct
4152 {
4153 u32 data;
4154 } *ed;
4155
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08004156 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session_elog_track);
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004157
4158 ed->data = vep_idx;
4159 /* *INDENT-ON* */
4160 }
4161
Dave Wallacef7f809c2017-10-03 01:48:42 -04004162 rv = VPPCOM_EINVAL;
4163 goto done;
4164 }
4165 if (PREDICT_FALSE (!is_vep_session))
4166 {
4167 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05004168 clib_warning ("VCL<%d>: ERROR: session (%u) is not "
Dave Wallace2e005bb2017-11-07 01:21:39 -05004169 "a vep session!", getpid (), sid);
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004170 if (VPPCOM_DEBUG > 0)
4171 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08004172 /* *INDENT-OFF* */
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004173 ELOG_TYPE_DECLARE (e) =
4174 {
4175 .format = "ERR:SID:%d not vep",
4176 .format_args = "i4",
4177 };
4178 struct
4179 {
4180 u32 data;
4181 } *ed;
4182
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08004183 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session_elog_track);
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004184
4185 ed->data = sid;
4186 /* *INDENT-ON* */
4187 }
4188
Dave Wallacef7f809c2017-10-03 01:48:42 -04004189 rv = VPPCOM_EINVAL;
4190 goto done;
4191 }
4192 if (PREDICT_FALSE (session_vep_idx != vep_idx))
4193 {
Dave Wallace048b1d62018-01-03 22:24:41 -05004194 clib_warning ("VCL<%d>: ERROR: session (%u) "
Dave Wallacef7f809c2017-10-03 01:48:42 -04004195 "vep_idx (%u) != vep_idx (%u)!",
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08004196 getpid (), sid, session_vep_idx, vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04004197 rv = VPPCOM_EINVAL;
4198 goto done;
4199 }
4200
4201 add_event = clear_et_mask = 0;
4202
Dave Wallace60caa062017-11-10 17:07:13 -05004203 if (EPOLLIN & session_events)
Dave Wallacef7f809c2017-10-03 01:48:42 -04004204 {
4205 VCL_LOCK_AND_GET_SESSION (sid, &session);
4206 ready = vppcom_session_read_ready (session, sid);
4207 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace60caa062017-11-10 17:07:13 -05004208 if ((ready > 0) && (EPOLLIN & et_mask))
Dave Wallacef7f809c2017-10-03 01:48:42 -04004209 {
4210 add_event = 1;
4211 events[num_ev].events |= EPOLLIN;
Dave Wallace60caa062017-11-10 17:07:13 -05004212 if (((EPOLLET | EPOLLIN) & session_events) ==
4213 (EPOLLET | EPOLLIN))
Dave Wallacef7f809c2017-10-03 01:48:42 -04004214 clear_et_mask |= EPOLLIN;
4215 }
4216 else if (ready < 0)
4217 {
4218 add_event = 1;
4219 switch (ready)
4220 {
4221 case VPPCOM_ECONNRESET:
4222 events[num_ev].events |= EPOLLHUP | EPOLLRDHUP;
4223 break;
4224
4225 default:
4226 events[num_ev].events |= EPOLLERR;
4227 break;
4228 }
4229 }
4230 }
4231
Dave Wallace60caa062017-11-10 17:07:13 -05004232 if (EPOLLOUT & session_events)
Dave Wallacef7f809c2017-10-03 01:48:42 -04004233 {
4234 VCL_LOCK_AND_GET_SESSION (sid, &session);
4235 ready = vppcom_session_write_ready (session, sid);
4236 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace60caa062017-11-10 17:07:13 -05004237 if ((ready > 0) && (EPOLLOUT & et_mask))
Dave Wallacef7f809c2017-10-03 01:48:42 -04004238 {
4239 add_event = 1;
4240 events[num_ev].events |= EPOLLOUT;
Dave Wallace60caa062017-11-10 17:07:13 -05004241 if (((EPOLLET | EPOLLOUT) & session_events) ==
4242 (EPOLLET | EPOLLOUT))
Dave Wallacef7f809c2017-10-03 01:48:42 -04004243 clear_et_mask |= EPOLLOUT;
4244 }
4245 else if (ready < 0)
4246 {
4247 add_event = 1;
4248 switch (ready)
4249 {
4250 case VPPCOM_ECONNRESET:
4251 events[num_ev].events |= EPOLLHUP;
4252 break;
4253
4254 default:
4255 events[num_ev].events |= EPOLLERR;
4256 break;
4257 }
4258 }
4259 }
4260
4261 if (add_event)
4262 {
4263 events[num_ev].data.u64 = session_ev_data;
4264 if (EPOLLONESHOT & session_events)
4265 {
4266 VCL_LOCK_AND_GET_SESSION (sid, &session);
4267 session->vep.ev.events = 0;
4268 clib_spinlock_unlock (&vcm->sessions_lockp);
4269 }
4270 num_ev++;
4271 if (num_ev == maxevents)
4272 {
4273 VCL_LOCK_AND_GET_SESSION (vep_idx, &vep_session);
4274 vep_session->wait_cont_idx = next_sid;
4275 clib_spinlock_unlock (&vcm->sessions_lockp);
4276 goto done;
4277 }
4278 }
4279 if (wait_cont_idx != ~0)
4280 {
4281 if (next_sid == ~0)
4282 next_sid = vep_next_sid;
4283 else if (next_sid == wait_cont_idx)
4284 next_sid = ~0;
4285 }
4286 }
Dave Wallace2e005bb2017-11-07 01:21:39 -05004287 if (wait_for_time != -1)
4288 keep_trying = (clib_time_now (&vcm->clib_time) <= timeout) ? 1 : 0;
Dave Wallacef7f809c2017-10-03 01:48:42 -04004289 }
Dave Wallace2e005bb2017-11-07 01:21:39 -05004290 while ((num_ev == 0) && keep_trying);
Dave Wallacef7f809c2017-10-03 01:48:42 -04004291
4292 if (wait_cont_idx != ~0)
4293 {
4294 VCL_LOCK_AND_GET_SESSION (vep_idx, &vep_session);
4295 vep_session->wait_cont_idx = ~0;
4296 clib_spinlock_unlock (&vcm->sessions_lockp);
4297 }
4298done:
4299 return (rv != VPPCOM_OK) ? rv : num_ev;
4300}
4301
Dave Wallace35830af2017-10-09 01:43:42 -04004302int
4303vppcom_session_attr (uint32_t session_index, uint32_t op,
4304 void *buffer, uint32_t * buflen)
4305{
Dave Wallace35830af2017-10-09 01:43:42 -04004306 session_t *session;
4307 int rv = VPPCOM_OK;
4308 u32 *flags = buffer;
Steven2199aab2017-10-15 20:18:47 -07004309 vppcom_endpt_t *ep = buffer;
Dave Wallace35830af2017-10-09 01:43:42 -04004310
4311 VCL_LOCK_AND_GET_SESSION (session_index, &session);
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08004312
4313 ASSERT (session);
4314
Dave Wallace35830af2017-10-09 01:43:42 -04004315 switch (op)
4316 {
4317 case VPPCOM_ATTR_GET_NREAD:
4318 rv = vppcom_session_read_ready (session, session_index);
Dave Wallace227867f2017-11-13 21:21:53 -05004319 if (VPPCOM_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05004320 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_NREAD: sid %u, nread = %d",
Dave Wallace2e005bb2017-11-07 01:21:39 -05004321 getpid (), rv);
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004322 if (VPPCOM_DEBUG > 0)
4323 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08004324 /* *INDENT-OFF* */
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004325 ELOG_TYPE_DECLARE (e) =
4326 {
4327 .format = "VPPCOM_ATTR_GET_NREAD: nread=%d",
4328 .format_args = "i4",
4329 };
4330 struct
4331 {
4332 u32 data;
4333 } *ed;
4334
4335 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4336
4337 ed->data = rv;
4338 /* *INDENT-ON* */
4339 }
4340
Dave Wallace35830af2017-10-09 01:43:42 -04004341 break;
4342
Dave Wallace227867f2017-11-13 21:21:53 -05004343 case VPPCOM_ATTR_GET_NWRITE:
4344 rv = vppcom_session_write_ready (session, session_index);
4345 if (VPPCOM_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05004346 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_NWRITE: sid %u, nwrite = %d",
Dave Wallace227867f2017-11-13 21:21:53 -05004347 getpid (), session_index, rv);
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004348 if (VPPCOM_DEBUG > 0)
4349 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08004350 /* *INDENT-OFF* */
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004351 ELOG_TYPE_DECLARE (e) =
4352 {
4353 .format = "VPPCOM_ATTR_GET_NWRITE: nwrite=%d",
4354 .format_args = "i4",
4355 };
4356 struct
4357 {
4358 u32 data;
4359 } *ed;
4360
4361 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4362
4363 ed->data = rv;
4364 /* *INDENT-ON* */
4365 }
Dave Wallace35830af2017-10-09 01:43:42 -04004366 break;
4367
4368 case VPPCOM_ATTR_GET_FLAGS:
Dave Wallace048b1d62018-01-03 22:24:41 -05004369 if (PREDICT_TRUE (buffer && buflen && (*buflen >= sizeof (*flags))))
Dave Wallace35830af2017-10-09 01:43:42 -04004370 {
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08004371 *flags = O_RDWR | (VCL_SESS_ATTR_TEST (session->attr,
4372 VCL_SESS_ATTR_NONBLOCK));
Dave Wallace35830af2017-10-09 01:43:42 -04004373 *buflen = sizeof (*flags);
Dave Wallace227867f2017-11-13 21:21:53 -05004374 if (VPPCOM_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05004375 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_FLAGS: sid %u, "
Dave Wallace227867f2017-11-13 21:21:53 -05004376 "flags = 0x%08x, is_nonblocking = %u", getpid (),
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08004377 session_index, *flags,
4378 VCL_SESS_ATTR_TEST (session->attr,
4379 VCL_SESS_ATTR_NONBLOCK));
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004380 if (VPPCOM_DEBUG > 0)
4381 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08004382 /* *INDENT-OFF* */
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004383 ELOG_TYPE_DECLARE (e) =
4384 {
4385 .format = "VPPCOM_ATTR_GET_FLAGS: flags=%x is_nonblk=%d",
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004386 .format_args = "i4i4",
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004387 };
4388 struct
4389 {
4390 u32 flags;
4391 u32 is_nonblk;
4392 } *ed;
4393
4394 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4395
4396 ed->flags = *flags;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08004397 ed->is_nonblk = VCL_SESS_ATTR_TEST (session->attr, VCL_SESS_ATTR_NONBLOCK);
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004398 /* *INDENT-ON* */
4399 }
4400
Dave Wallace35830af2017-10-09 01:43:42 -04004401 }
4402 else
4403 rv = VPPCOM_EINVAL;
4404 break;
4405
4406 case VPPCOM_ATTR_SET_FLAGS:
Dave Wallace048b1d62018-01-03 22:24:41 -05004407 if (PREDICT_TRUE (buffer && buflen && (*buflen == sizeof (*flags))))
Dave Wallace35830af2017-10-09 01:43:42 -04004408 {
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08004409 if (*flags & O_NONBLOCK)
4410 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_NONBLOCK);
4411 else
4412 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_NONBLOCK);
4413
Dave Wallace227867f2017-11-13 21:21:53 -05004414 if (VPPCOM_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05004415 clib_warning ("VCL<%d>: VPPCOM_ATTR_SET_FLAGS: sid %u, "
Dave Wallace227867f2017-11-13 21:21:53 -05004416 "flags = 0x%08x, is_nonblocking = %u",
Dave Wallace4878cbe2017-11-21 03:45:09 -05004417 getpid (), session_index, *flags,
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08004418 VCL_SESS_ATTR_TEST (session->attr,
4419 VCL_SESS_ATTR_NONBLOCK));
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004420 if (VPPCOM_DEBUG > 0)
4421 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08004422 /* *INDENT-OFF* */
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004423 ELOG_TYPE_DECLARE (e) =
4424 {
4425 .format = "VPPCOM_ATTR_SET_FLAGS: flags=%x is_nonblk=%d",
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004426 .format_args = "i4i4",
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004427 };
4428 struct
4429 {
4430 u32 flags;
4431 u32 is_nonblk;
4432 } *ed;
4433
4434 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4435
4436 ed->flags = *flags;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08004437 ed->is_nonblk = VCL_SESS_ATTR_TEST (session->attr, VCL_SESS_ATTR_NONBLOCK);
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004438 /* *INDENT-ON* */
4439 }
Dave Wallace35830af2017-10-09 01:43:42 -04004440 }
4441 else
4442 rv = VPPCOM_EINVAL;
4443 break;
4444
4445 case VPPCOM_ATTR_GET_PEER_ADDR:
Dave Wallace048b1d62018-01-03 22:24:41 -05004446 if (PREDICT_TRUE (buffer && buflen &&
4447 (*buflen >= sizeof (*ep)) && ep->ip))
Dave Wallace35830af2017-10-09 01:43:42 -04004448 {
Steven2199aab2017-10-15 20:18:47 -07004449 ep->is_ip4 = session->peer_addr.is_ip4;
Stevenac1f96d2017-10-24 16:03:58 -07004450 ep->port = session->peer_port;
Steven2199aab2017-10-15 20:18:47 -07004451 if (session->peer_addr.is_ip4)
4452 clib_memcpy (ep->ip, &session->peer_addr.ip46.ip4,
4453 sizeof (ip4_address_t));
4454 else
4455 clib_memcpy (ep->ip, &session->peer_addr.ip46.ip6,
4456 sizeof (ip6_address_t));
4457 *buflen = sizeof (*ep);
Dave Wallacefaf9d772017-10-26 16:12:04 -04004458 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05004459 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_PEER_ADDR: sid %u, "
4460 "is_ip4 = %u, addr = %U, port %u", getpid (),
Dave Wallace774169b2017-11-01 20:07:40 -04004461 session_index, ep->is_ip4, format_ip46_address,
Stevenac1f96d2017-10-24 16:03:58 -07004462 &session->peer_addr.ip46, ep->is_ip4,
4463 clib_net_to_host_u16 (ep->port));
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004464 if (VPPCOM_DEBUG > 0)
4465 {
4466 if (ep->is_ip4)
4467 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08004468 /* *INDENT-OFF* */
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004469 ELOG_TYPE_DECLARE (e) =
4470 {
4471 .format = "VPPCOM_ATTR_GET_PEER_ADDR: addr:%d.%d.%d.%d:%d",
4472 .format_args = "i1i1i1i1i2",
4473 };
4474 CLIB_PACKED (struct {
4475 u8 addr[4]; //4
4476 u16 port; //2
4477 }) * ed;
4478
4479 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4480
4481 ed->addr[0] = session->peer_addr.ip46.ip4.as_u8[0];
4482 ed->addr[1] = session->peer_addr.ip46.ip4.as_u8[1];
4483 ed->addr[2] = session->peer_addr.ip46.ip4.as_u8[2];
4484 ed->addr[3] = session->peer_addr.ip46.ip4.as_u8[3];
4485 ed->port = clib_net_to_host_u16 (session->peer_port);
4486 /* *INDENT-ON* */
4487 }
4488 else
4489 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08004490 /* *INDENT-OFF* */
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004491 ELOG_TYPE_DECLARE (e) =
4492 {
4493 .format = "VPPCOM_ATTR_GET_PEER_ADDR: addr:IP6:%d",
4494 .format_args = "i2",
4495 };
4496 CLIB_PACKED (struct {
4497 u16 port; //2
4498 }) * ed;
4499
4500 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4501
4502 ed->port = clib_net_to_host_u16 (session->peer_port);
4503 /* *INDENT-ON* */
4504 }
4505 }
Dave Wallace35830af2017-10-09 01:43:42 -04004506 }
4507 else
4508 rv = VPPCOM_EINVAL;
4509 break;
4510
4511 case VPPCOM_ATTR_GET_LCL_ADDR:
Dave Wallace048b1d62018-01-03 22:24:41 -05004512 if (PREDICT_TRUE (buffer && buflen &&
4513 (*buflen >= sizeof (*ep)) && ep->ip))
Dave Wallace35830af2017-10-09 01:43:42 -04004514 {
Steven2199aab2017-10-15 20:18:47 -07004515 ep->is_ip4 = session->lcl_addr.is_ip4;
Stevenac1f96d2017-10-24 16:03:58 -07004516 ep->port = session->lcl_port;
Steven2199aab2017-10-15 20:18:47 -07004517 if (session->lcl_addr.is_ip4)
4518 clib_memcpy (ep->ip, &session->lcl_addr.ip46.ip4,
4519 sizeof (ip4_address_t));
4520 else
4521 clib_memcpy (ep->ip, &session->lcl_addr.ip46.ip6,
4522 sizeof (ip6_address_t));
4523 *buflen = sizeof (*ep);
Dave Wallacefaf9d772017-10-26 16:12:04 -04004524 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05004525 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_LCL_ADDR: sid %u, "
4526 "is_ip4 = %u, addr = %U port %d", getpid (),
Dave Wallace774169b2017-11-01 20:07:40 -04004527 session_index, ep->is_ip4, format_ip46_address,
Stevenac1f96d2017-10-24 16:03:58 -07004528 &session->lcl_addr.ip46, ep->is_ip4,
4529 clib_net_to_host_u16 (ep->port));
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004530 if (VPPCOM_DEBUG > 0)
4531 {
4532 if (ep->is_ip4)
4533 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08004534 /* *INDENT-OFF* */
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004535 ELOG_TYPE_DECLARE (e) =
4536 {
4537 .format = "VPPCOM_ATTR_GET_LCL_ADDR: addr:%d.%d.%d.%d:%d",
4538 .format_args = "i1i1i1i1i2",
4539 };
4540 CLIB_PACKED (struct {
4541 u8 addr[4]; //4
4542 u16 port; //2
4543 }) * ed;
4544
4545 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4546
4547 ed->addr[0] = session->lcl_addr.ip46.ip4.as_u8[0];
4548 ed->addr[1] = session->lcl_addr.ip46.ip4.as_u8[1];
4549 ed->addr[2] = session->lcl_addr.ip46.ip4.as_u8[2];
4550 ed->addr[3] = session->lcl_addr.ip46.ip4.as_u8[3];
4551 ed->port = clib_net_to_host_u16 (session->peer_port);
4552 /* *INDENT-ON* */
4553 }
4554 else
4555 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08004556 /* *INDENT-OFF* */
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004557 ELOG_TYPE_DECLARE (e) =
4558 {
4559 .format = "VPPCOM_ATTR_GET_LCL_ADDR: addr:IP6:%d",
4560 .format_args = "i2",
4561 };
4562 CLIB_PACKED (struct {
4563 u16 port; //2
4564 }) * ed;
4565
4566 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4567
4568 ed->port = clib_net_to_host_u16 (session->peer_port);
4569 /* *INDENT-ON* */
4570 }
4571 }
Dave Wallace35830af2017-10-09 01:43:42 -04004572 }
4573 else
4574 rv = VPPCOM_EINVAL;
4575 break;
Stevenb5a11602017-10-11 09:59:30 -07004576
Dave Wallace048b1d62018-01-03 22:24:41 -05004577 case VPPCOM_ATTR_GET_LIBC_EPFD:
4578 rv = session->libc_epfd;
4579 if (VPPCOM_DEBUG > 2)
4580 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_LIBC_EPFD: libc_epfd %d",
4581 getpid (), rv);
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004582 if (VPPCOM_DEBUG > 0)
4583 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08004584 /* *INDENT-OFF* */
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004585 ELOG_TYPE_DECLARE (e) =
4586 {
Florin Corasbb16d3f2018-01-29 08:55:25 -08004587 .format = "VPPCOM_ATTR_GET_LIBC_EPFD: libc_epfd=%d",
4588 .format_args = "i4",
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004589 };
4590 CLIB_PACKED (struct {
Florin Corasbb16d3f2018-01-29 08:55:25 -08004591 i32 data;
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08004592 }) *ed;
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004593
4594 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
Florin Corasbb16d3f2018-01-29 08:55:25 -08004595 ed->data = session->libc_epfd;
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004596 /* *INDENT-ON* */
4597 }
4598
Dave Wallace048b1d62018-01-03 22:24:41 -05004599 break;
4600
4601 case VPPCOM_ATTR_SET_LIBC_EPFD:
4602 if (PREDICT_TRUE (buffer && buflen &&
4603 (*buflen == sizeof (session->libc_epfd))))
4604 {
4605 session->libc_epfd = *(int *) buffer;
4606 *buflen = sizeof (session->libc_epfd);
4607
4608 if (VPPCOM_DEBUG > 2)
4609 clib_warning ("VCL<%d>: VPPCOM_ATTR_SET_LIBC_EPFD: libc_epfd %d, "
4610 "buflen %d", getpid (), session->libc_epfd,
4611 *buflen);
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004612 if (VPPCOM_DEBUG > 0)
4613 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08004614 /* *INDENT-OFF* */
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004615 ELOG_TYPE_DECLARE (e) =
4616 {
4617 .format = "VPPCOM_ATTR_SET_LIBC_EPFD: libc_epfd=%s%d buflen=%d",
4618 .format_args = "t1i4i4",
4619 .n_enum_strings = 2,
4620 .enum_strings = {"", "-",},
4621 };
4622 CLIB_PACKED (struct {
4623 u8 sign;
4624 u32 data[2];
4625 }) * ed;
4626
4627 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4628
4629 ed->sign = (session->libc_epfd < 0);
4630 ed->data[0] = abs(session->libc_epfd);
4631 ed->data[1] = *buflen;
4632 /* *INDENT-ON* */
4633 }
Dave Wallace048b1d62018-01-03 22:24:41 -05004634 }
4635 else
4636 rv = VPPCOM_EINVAL;
4637 break;
4638
4639 case VPPCOM_ATTR_GET_PROTOCOL:
4640 if (buffer && buflen && (*buflen >= sizeof (int)))
4641 {
4642 *(int *) buffer = session->proto;
4643 *buflen = sizeof (int);
4644
4645 if (VPPCOM_DEBUG > 2)
4646 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_PROTOCOL: %d (%s), "
4647 "buflen %d", getpid (), *(int *) buffer,
4648 *(int *) buffer ? "UDP" : "TCP", *buflen);
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004649 if (VPPCOM_DEBUG > 0)
4650 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08004651 /* *INDENT-OFF* */
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004652 ELOG_TYPE_DECLARE (e) =
4653 {
4654 .format = "VPPCOM_ATTR_GET_PROTOCOL: %s buflen=%d",
4655 .format_args = "t1i4",
4656 .n_enum_strings = 2,
4657 .enum_strings = {"TCP", "UDP",},
4658 };
4659
4660 CLIB_PACKED (struct {
4661 u8 proto;
4662 u32 buflen;
4663 }) * ed;
4664
4665 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4666 ed->proto = session->proto;
4667 ed->buflen = *(int *) buffer;
4668 /* *INDENT-ON* */
4669 }
Dave Wallace048b1d62018-01-03 22:24:41 -05004670 }
4671 else
4672 rv = VPPCOM_EINVAL;
4673 break;
4674
4675 case VPPCOM_ATTR_GET_LISTEN:
4676 if (buffer && buflen && (*buflen >= sizeof (int)))
4677 {
4678 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
4679 VCL_SESS_ATTR_LISTEN);
4680 *buflen = sizeof (int);
4681
4682 if (VPPCOM_DEBUG > 2)
4683 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_LISTEN: %d, "
4684 "buflen %d", getpid (), *(int *) buffer, *buflen);
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004685 if (VPPCOM_DEBUG > 0)
4686 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08004687 /* *INDENT-OFF* */
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004688 ELOG_TYPE_DECLARE (e) =
4689 {
4690 .format = "VPPCOM_ATTR_GET_LISTEN: %d buflen=%d",
4691 .format_args = "i4i4",
4692 };
4693
4694 struct {
4695 u32 data[2];
4696 } * ed;
4697
4698 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4699 ed->data[0] = *(int *) buffer;
4700 ed->data[1] = *buflen;
4701 /* *INDENT-ON* */
4702 }
Dave Wallace048b1d62018-01-03 22:24:41 -05004703 }
4704 else
4705 rv = VPPCOM_EINVAL;
4706 break;
4707
4708 case VPPCOM_ATTR_GET_ERROR:
4709 if (buffer && buflen && (*buflen >= sizeof (int)))
4710 {
4711 *(int *) buffer = 0;
4712 *buflen = sizeof (int);
4713
4714 if (VPPCOM_DEBUG > 2)
4715 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_ERROR: %d, "
4716 "buflen %d, #VPP-TBD#", getpid (),
4717 *(int *) buffer, *buflen);
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004718 if (VPPCOM_DEBUG > 0)
4719 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08004720 /* *INDENT-OFF* */
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004721 ELOG_TYPE_DECLARE (e) =
4722 {
4723 .format = "VPPCOM_ATTR_GET_ERROR: %d buflen=%d",
4724 .format_args = "i4i4",
4725 };
4726
4727 struct {
4728 u32 data[2];
4729 } * ed;
4730
4731 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4732 ed->data[0] = *(int *) buffer;
4733 ed->data[1] = *buflen;
4734 /* *INDENT-ON* */
4735 }
Dave Wallace048b1d62018-01-03 22:24:41 -05004736 }
4737 else
4738 rv = VPPCOM_EINVAL;
4739 break;
4740
4741 case VPPCOM_ATTR_GET_TX_FIFO_LEN:
4742 if (buffer && buflen && (*buflen >= sizeof (u32)))
4743 {
Dave Wallace048b1d62018-01-03 22:24:41 -05004744
4745 /* VPP-TBD */
4746 *(size_t *) buffer = (session->sndbuf_size ? session->sndbuf_size :
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08004747 session->tx_fifo ? session->tx_fifo->nitems :
Dave Wallace048b1d62018-01-03 22:24:41 -05004748 vcm->cfg.tx_fifo_size);
4749 *buflen = sizeof (u32);
4750
4751 if (VPPCOM_DEBUG > 2)
4752 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_TX_FIFO_LEN: %u (0x%x), "
4753 "buflen %d, #VPP-TBD#", getpid (),
4754 *(size_t *) buffer, *(size_t *) buffer, *buflen);
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004755 if (VPPCOM_DEBUG > 0)
4756 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08004757 /* *INDENT-OFF* */
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004758 ELOG_TYPE_DECLARE (e) =
4759 {
4760 .format = "VPPCOM_ATTR_GET_TX_FIFO_LEN: 0x%x buflen=%d",
4761 .format_args = "i4i4",
4762 };
4763
4764 struct {
4765 u32 data[2];
4766 } * ed;
4767
4768 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4769 ed->data[0] = *(size_t *) buffer;
4770 ed->data[1] = *buflen;
4771 /* *INDENT-ON* */
4772 }
Dave Wallace048b1d62018-01-03 22:24:41 -05004773 }
4774 else
4775 rv = VPPCOM_EINVAL;
4776 break;
4777
4778 case VPPCOM_ATTR_SET_TX_FIFO_LEN:
4779 if (buffer && buflen && (*buflen == sizeof (u32)))
4780 {
4781 /* VPP-TBD */
4782 session->sndbuf_size = *(u32 *) buffer;
4783 if (VPPCOM_DEBUG > 2)
4784 clib_warning ("VCL<%d>: VPPCOM_ATTR_SET_TX_FIFO_LEN: %u (0x%x), "
4785 "buflen %d, #VPP-TBD#", getpid (),
4786 session->sndbuf_size, session->sndbuf_size,
4787 *buflen);
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004788 if (VPPCOM_DEBUG > 0)
4789 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08004790 /* *INDENT-OFF* */
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004791 ELOG_TYPE_DECLARE (e) =
4792 {
4793 .format = "VPPCOM_ATTR_SET_TX_FIFO_LEN: 0x%x buflen=%d",
4794 .format_args = "i4i4",
4795 };
4796
4797 struct {
4798 u32 data[2];
4799 } * ed;
4800
4801 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4802 ed->data[0] = session->sndbuf_size;
4803 ed->data[1] = *buflen;
4804 /* *INDENT-ON* */
4805 }
Dave Wallace048b1d62018-01-03 22:24:41 -05004806 }
4807 else
4808 rv = VPPCOM_EINVAL;
4809 break;
4810
4811 case VPPCOM_ATTR_GET_RX_FIFO_LEN:
4812 if (buffer && buflen && (*buflen >= sizeof (u32)))
4813 {
Dave Wallace048b1d62018-01-03 22:24:41 -05004814
4815 /* VPP-TBD */
4816 *(size_t *) buffer = (session->rcvbuf_size ? session->rcvbuf_size :
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08004817 session->rx_fifo ? session->rx_fifo->nitems :
Dave Wallace048b1d62018-01-03 22:24:41 -05004818 vcm->cfg.rx_fifo_size);
4819 *buflen = sizeof (u32);
4820
4821 if (VPPCOM_DEBUG > 2)
4822 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_RX_FIFO_LEN: %u (0x%x), "
4823 "buflen %d, #VPP-TBD#", getpid (),
4824 *(size_t *) buffer, *(size_t *) buffer, *buflen);
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004825 if (VPPCOM_DEBUG > 0)
4826 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08004827 /* *INDENT-OFF* */
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004828 ELOG_TYPE_DECLARE (e) =
4829 {
4830 .format = "VPPCOM_ATTR_GET_RX_FIFO_LEN: 0x%x buflen=%d",
4831 .format_args = "i4i4",
4832 };
4833
4834 struct {
4835 u32 data[2];
4836 } * ed;
4837
4838 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4839 ed->data[0] = *(size_t *) buffer;
4840 ed->data[1] = *buflen;
4841 /* *INDENT-ON* */
4842 }
Dave Wallace048b1d62018-01-03 22:24:41 -05004843 }
4844 else
4845 rv = VPPCOM_EINVAL;
4846 break;
4847
4848 case VPPCOM_ATTR_SET_RX_FIFO_LEN:
4849 if (buffer && buflen && (*buflen == sizeof (u32)))
4850 {
4851 /* VPP-TBD */
4852 session->rcvbuf_size = *(u32 *) buffer;
4853 if (VPPCOM_DEBUG > 2)
Dave Wallace7e2c31a2018-02-05 20:03:01 -05004854 clib_warning ("VCL<%d>: VPPCOM_ATTR_SET_RX_FIFO_LEN: %u (0x%x), "
Dave Wallace048b1d62018-01-03 22:24:41 -05004855 "buflen %d, #VPP-TBD#", getpid (),
4856 session->sndbuf_size, session->sndbuf_size,
4857 *buflen);
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004858 if (VPPCOM_DEBUG > 0)
4859 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08004860 /* *INDENT-OFF* */
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004861 ELOG_TYPE_DECLARE (e) =
4862 {
Dave Wallace7e2c31a2018-02-05 20:03:01 -05004863 .format = "VPPCOM_ATTR_SET_RX_FIFO_LEN: 0x%x buflen=%d",
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004864 .format_args = "i4i4",
4865 };
4866
4867 struct {
4868 u32 data[2];
4869 } * ed;
4870
4871 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4872 ed->data[0] = session->sndbuf_size;
4873 ed->data[1] = *buflen;
4874 /* *INDENT-ON* */
4875 }
Dave Wallace048b1d62018-01-03 22:24:41 -05004876 }
4877 else
4878 rv = VPPCOM_EINVAL;
4879 break;
4880
4881 case VPPCOM_ATTR_GET_REUSEADDR:
4882 if (buffer && buflen && (*buflen >= sizeof (int)))
4883 {
4884 /* VPP-TBD */
4885 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
4886 VCL_SESS_ATTR_REUSEADDR);
4887 *buflen = sizeof (int);
4888
4889 if (VPPCOM_DEBUG > 2)
4890 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_REUSEADDR: %d, "
4891 "buflen %d, #VPP-TBD#", getpid (), *(int *) buffer,
4892 *buflen);
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004893 if (VPPCOM_DEBUG > 0)
4894 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08004895 /* *INDENT-OFF* */
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004896 ELOG_TYPE_DECLARE (e) =
4897 {
4898 .format = "VPPCOM_ATTR_GET_REUSEADDR: %d buflen=%d",
4899 .format_args = "i4i4",
4900 };
4901
4902 struct {
4903 u32 data[2];
4904 } * ed;
4905
4906 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4907 ed->data[0] = *(int *) buffer;
4908 ed->data[1] = *buflen;
4909 /* *INDENT-ON* */
4910 }
Dave Wallace048b1d62018-01-03 22:24:41 -05004911 }
4912 else
4913 rv = VPPCOM_EINVAL;
4914 break;
4915
Stevenb5a11602017-10-11 09:59:30 -07004916 case VPPCOM_ATTR_SET_REUSEADDR:
Dave Wallace048b1d62018-01-03 22:24:41 -05004917 if (buffer && buflen && (*buflen == sizeof (int)) &&
4918 !VCL_SESS_ATTR_TEST (session->attr, VCL_SESS_ATTR_LISTEN))
4919 {
4920 /* VPP-TBD */
4921 if (*(int *) buffer)
4922 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_REUSEADDR);
4923 else
4924 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_REUSEADDR);
4925
4926 if (VPPCOM_DEBUG > 2)
4927 clib_warning ("VCL<%d>: VPPCOM_ATTR_SET_REUSEADDR: %d, "
4928 "buflen %d, #VPP-TBD#", getpid (),
4929 VCL_SESS_ATTR_TEST (session->attr,
4930 VCL_SESS_ATTR_REUSEADDR),
4931 *buflen);
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004932 if (VPPCOM_DEBUG > 0)
4933 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08004934 /* *INDENT-OFF* */
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004935 ELOG_TYPE_DECLARE (e) =
4936 {
4937 .format = "VPPCOM_ATTR_SET_REUSEADDR: %d buflen=%d",
4938 .format_args = "i4i4",
4939 };
4940
4941 struct {
4942 u32 data[2];
4943 } * ed;
4944
4945 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4946 ed->data[0] = VCL_SESS_ATTR_TEST (session->attr,
4947 VCL_SESS_ATTR_REUSEADDR);
4948 ed->data[1] = *buflen;
4949 /* *INDENT-ON* */
4950 }
Dave Wallace048b1d62018-01-03 22:24:41 -05004951 }
4952 else
4953 rv = VPPCOM_EINVAL;
4954 break;
4955
4956 case VPPCOM_ATTR_GET_REUSEPORT:
4957 if (buffer && buflen && (*buflen >= sizeof (int)))
4958 {
4959 /* VPP-TBD */
4960 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
4961 VCL_SESS_ATTR_REUSEPORT);
4962 *buflen = sizeof (int);
4963
4964 if (VPPCOM_DEBUG > 2)
4965 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_REUSEPORT: %d, "
4966 "buflen %d, #VPP-TBD#", getpid (), *(int *) buffer,
4967 *buflen);
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004968 if (VPPCOM_DEBUG > 0)
4969 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08004970 /* *INDENT-OFF* */
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004971 ELOG_TYPE_DECLARE (e) =
4972 {
4973 .format = "VPPCOM_ATTR_GET_REUSEPORT: %d buflen=%d",
4974 .format_args = "i4i4",
4975 };
4976
4977 struct {
4978 u32 data[2];
4979 } * ed;
4980
4981 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4982 ed->data[0] = *(int *) buffer;
4983 ed->data[1] = *buflen;
4984 /* *INDENT-ON* */
4985 }
Dave Wallace048b1d62018-01-03 22:24:41 -05004986 }
4987 else
4988 rv = VPPCOM_EINVAL;
4989 break;
4990
4991 case VPPCOM_ATTR_SET_REUSEPORT:
4992 if (buffer && buflen && (*buflen == sizeof (int)) &&
4993 !VCL_SESS_ATTR_TEST (session->attr, VCL_SESS_ATTR_LISTEN))
4994 {
4995 /* VPP-TBD */
4996 if (*(int *) buffer)
4997 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_REUSEPORT);
4998 else
4999 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_REUSEPORT);
5000
5001 if (VPPCOM_DEBUG > 2)
5002 clib_warning ("VCL<%d>: VPPCOM_ATTR_SET_REUSEPORT: %d, "
5003 "buflen %d, #VPP-TBD#", getpid (),
5004 VCL_SESS_ATTR_TEST (session->attr,
5005 VCL_SESS_ATTR_REUSEPORT),
5006 *buflen);
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08005007 if (VPPCOM_DEBUG > 0)
5008 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08005009 /* *INDENT-OFF* */
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08005010 ELOG_TYPE_DECLARE (e) =
5011 {
5012 .format = "VPPCOM_ATTR_SET_REUSEPORT: %d buflen=%d",
5013 .format_args = "i4i4",
5014 };
5015
5016 struct {
5017 u32 data[2];
5018 } * ed;
5019
5020 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
5021 ed->data[0] = VCL_SESS_ATTR_TEST (session->attr,
5022 VCL_SESS_ATTR_REUSEPORT);
5023 ed->data[1] = *buflen;
5024 /* *INDENT-ON* */
5025 }
Dave Wallace048b1d62018-01-03 22:24:41 -05005026 }
5027 else
5028 rv = VPPCOM_EINVAL;
5029 break;
5030
5031 case VPPCOM_ATTR_GET_BROADCAST:
5032 if (buffer && buflen && (*buflen >= sizeof (int)))
5033 {
5034 /* VPP-TBD */
5035 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
5036 VCL_SESS_ATTR_BROADCAST);
5037 *buflen = sizeof (int);
5038
5039 if (VPPCOM_DEBUG > 2)
5040 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_BROADCAST: %d, "
5041 "buflen %d, #VPP-TBD#", getpid (), *(int *) buffer,
5042 *buflen);
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08005043 if (VPPCOM_DEBUG > 0)
5044 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08005045 /* *INDENT-OFF* */
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08005046 ELOG_TYPE_DECLARE (e) =
5047 {
5048 .format = "VPPCOM_ATTR_GET_BROADCAST: %d buflen=%d",
5049 .format_args = "i4i4",
5050 };
5051
5052 struct {
5053 u32 data[2];
5054 } * ed;
5055
5056 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
5057 ed->data[0] = *(int *) buffer;
5058 ed->data[1] = *buflen;
5059 /* *INDENT-ON* */
5060 }
Dave Wallace048b1d62018-01-03 22:24:41 -05005061 }
5062 else
5063 rv = VPPCOM_EINVAL;
Stevenb5a11602017-10-11 09:59:30 -07005064 break;
5065
5066 case VPPCOM_ATTR_SET_BROADCAST:
Dave Wallace048b1d62018-01-03 22:24:41 -05005067 if (buffer && buflen && (*buflen == sizeof (int)))
5068 {
5069 /* VPP-TBD */
5070 if (*(int *) buffer)
5071 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_BROADCAST);
5072 else
5073 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_BROADCAST);
5074
5075 if (VPPCOM_DEBUG > 2)
5076 clib_warning ("VCL<%d>: VPPCOM_ATTR_SET_BROADCAST: %d, "
5077 "buflen %d, #VPP-TBD#", getpid (),
5078 VCL_SESS_ATTR_TEST (session->attr,
5079 VCL_SESS_ATTR_BROADCAST),
5080 *buflen);
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005081 if (VPPCOM_DEBUG > 0)
5082 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08005083 /* *INDENT-OFF* */
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005084 ELOG_TYPE_DECLARE (e) =
5085 {
5086 .format = "VPPCOM_ATTR_SET_BROADCAST: %d buflen=%d",
5087 .format_args = "i4i4",
5088 };
5089
5090 struct {
5091 u32 data[2];
5092 } * ed;
5093
5094 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
5095 ed->data[0] = VCL_SESS_ATTR_TEST (session->attr,
5096 VCL_SESS_ATTR_BROADCAST);
5097 ed->data[1] = *buflen;
5098 /* *INDENT-ON* */
5099 }
Dave Wallace048b1d62018-01-03 22:24:41 -05005100 }
5101 else
5102 rv = VPPCOM_EINVAL;
5103 break;
5104
5105 case VPPCOM_ATTR_GET_V6ONLY:
5106 if (buffer && buflen && (*buflen >= sizeof (int)))
5107 {
5108 /* VPP-TBD */
5109 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
5110 VCL_SESS_ATTR_V6ONLY);
5111 *buflen = sizeof (int);
5112
5113 if (VPPCOM_DEBUG > 2)
5114 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_V6ONLY: %d, "
5115 "buflen %d, #VPP-TBD#", getpid (), *(int *) buffer,
5116 *buflen);
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005117 if (VPPCOM_DEBUG > 0)
5118 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08005119 /* *INDENT-OFF* */
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005120 ELOG_TYPE_DECLARE (e) =
5121 {
5122 .format = "VPPCOM_ATTR_GET_V6ONLY: %d buflen=%d",
5123 .format_args = "i4i4",
5124 };
5125
5126 struct {
5127 u32 data[2];
5128 } * ed;
5129
5130 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
5131 ed->data[0] = *(int *) buffer;
5132 ed->data[1] = *buflen;
5133 /* *INDENT-ON* */
5134 }
Dave Wallace048b1d62018-01-03 22:24:41 -05005135 }
5136 else
5137 rv = VPPCOM_EINVAL;
Stevenb5a11602017-10-11 09:59:30 -07005138 break;
5139
5140 case VPPCOM_ATTR_SET_V6ONLY:
Dave Wallace048b1d62018-01-03 22:24:41 -05005141 if (buffer && buflen && (*buflen == sizeof (int)))
5142 {
5143 /* VPP-TBD */
5144 if (*(int *) buffer)
5145 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_V6ONLY);
5146 else
5147 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_V6ONLY);
5148
5149 if (VPPCOM_DEBUG > 2)
5150 clib_warning ("VCL<%d>: VPPCOM_ATTR_SET_V6ONLY: %d, "
5151 "buflen %d, #VPP-TBD#", getpid (),
5152 VCL_SESS_ATTR_TEST (session->attr,
5153 VCL_SESS_ATTR_V6ONLY), *buflen);
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005154 if (VPPCOM_DEBUG > 0)
5155 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08005156 /* *INDENT-OFF* */
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005157 ELOG_TYPE_DECLARE (e) =
5158 {
5159 .format = "VPPCOM_ATTR_SET_V6ONLY: %d buflen=%d",
5160 .format_args = "i4i4",
5161 };
5162
5163 struct {
5164 u32 data[2];
5165 } * ed;
5166
5167 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
5168 ed->data[0] = VCL_SESS_ATTR_TEST (session->attr,
5169 VCL_SESS_ATTR_V6ONLY);
5170 ed->data[1] = *buflen;
5171 /* *INDENT-ON* */
5172 }
Dave Wallace048b1d62018-01-03 22:24:41 -05005173 }
5174 else
5175 rv = VPPCOM_EINVAL;
5176 break;
5177
5178 case VPPCOM_ATTR_GET_KEEPALIVE:
5179 if (buffer && buflen && (*buflen >= sizeof (int)))
5180 {
5181 /* VPP-TBD */
5182 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
5183 VCL_SESS_ATTR_KEEPALIVE);
5184 *buflen = sizeof (int);
5185
5186 if (VPPCOM_DEBUG > 2)
5187 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_KEEPALIVE: %d, "
5188 "buflen %d, #VPP-TBD#", getpid (), *(int *) buffer,
5189 *buflen);
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005190 if (VPPCOM_DEBUG > 0)
5191 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08005192 /* *INDENT-OFF* */
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005193 ELOG_TYPE_DECLARE (e) =
5194 {
5195 .format = "VPPCOM_ATTR_GET_KEEPALIVE: %d buflen=%d",
5196 .format_args = "i4i4",
5197 };
5198
5199 struct {
5200 u32 data[2];
5201 } * ed;
5202
5203 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
5204 ed->data[0] = *(int *) buffer;
5205 ed->data[1] = *buflen;
5206 /* *INDENT-ON* */
5207 }
Dave Wallace048b1d62018-01-03 22:24:41 -05005208 }
5209 else
5210 rv = VPPCOM_EINVAL;
Stevenb5a11602017-10-11 09:59:30 -07005211 break;
Stevenbccd3392017-10-12 20:42:21 -07005212
5213 case VPPCOM_ATTR_SET_KEEPALIVE:
Dave Wallace048b1d62018-01-03 22:24:41 -05005214 if (buffer && buflen && (*buflen == sizeof (int)))
5215 {
5216 /* VPP-TBD */
5217 if (*(int *) buffer)
5218 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_KEEPALIVE);
5219 else
5220 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_KEEPALIVE);
5221
5222 if (VPPCOM_DEBUG > 2)
5223 clib_warning ("VCL<%d>: VPPCOM_ATTR_SET_KEEPALIVE: %d, "
5224 "buflen %d, #VPP-TBD#", getpid (),
5225 VCL_SESS_ATTR_TEST (session->attr,
5226 VCL_SESS_ATTR_KEEPALIVE),
5227 *buflen);
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005228 if (VPPCOM_DEBUG > 0)
5229 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08005230 /* *INDENT-OFF* */
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005231 ELOG_TYPE_DECLARE (e) =
5232 {
5233 .format = "VPPCOM_ATTR_SET_KEEPALIVE: %d buflen=%d",
5234 .format_args = "i4i4",
5235 };
5236
5237 struct {
5238 u32 data[2];
5239 } * ed;
5240
5241 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
5242 ed->data[0] = VCL_SESS_ATTR_TEST (session->attr,
5243 VCL_SESS_ATTR_KEEPALIVE);
5244 ed->data[1] = *buflen;
5245 /* *INDENT-ON* */
5246 }
Dave Wallace048b1d62018-01-03 22:24:41 -05005247 }
5248 else
5249 rv = VPPCOM_EINVAL;
5250 break;
5251
5252 case VPPCOM_ATTR_GET_TCP_NODELAY:
5253 if (buffer && buflen && (*buflen >= sizeof (int)))
5254 {
5255 /* VPP-TBD */
5256 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
5257 VCL_SESS_ATTR_TCP_NODELAY);
5258 *buflen = sizeof (int);
5259
5260 if (VPPCOM_DEBUG > 2)
5261 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_TCP_NODELAY: %d, "
5262 "buflen %d, #VPP-TBD#", getpid (), *(int *) buffer,
5263 *buflen);
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005264 if (VPPCOM_DEBUG > 0)
5265 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08005266 /* *INDENT-OFF* */
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005267 ELOG_TYPE_DECLARE (e) =
5268 {
5269 .format = "VPPCOM_ATTR_GET_TCP_NODELAY: %d buflen=%d",
5270 .format_args = "i4i4",
5271 };
5272
5273 struct {
5274 u32 data[2];
5275 } * ed;
5276
5277 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
5278 ed->data[0] = *(int *) buffer;
5279 ed->data[1] = *buflen;
5280 /* *INDENT-ON* */
5281 }
Dave Wallace048b1d62018-01-03 22:24:41 -05005282 }
5283 else
5284 rv = VPPCOM_EINVAL;
5285 break;
5286
5287 case VPPCOM_ATTR_SET_TCP_NODELAY:
5288 if (buffer && buflen && (*buflen == sizeof (int)))
5289 {
5290 /* VPP-TBD */
5291 if (*(int *) buffer)
5292 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_TCP_NODELAY);
5293 else
5294 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_TCP_NODELAY);
5295
5296 if (VPPCOM_DEBUG > 2)
5297 clib_warning ("VCL<%d>: VPPCOM_ATTR_SET_TCP_NODELAY: %d, "
5298 "buflen %d, #VPP-TBD#", getpid (),
5299 VCL_SESS_ATTR_TEST (session->attr,
5300 VCL_SESS_ATTR_TCP_NODELAY),
5301 *buflen);
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005302 if (VPPCOM_DEBUG > 0)
5303 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08005304 /* *INDENT-OFF* */
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005305 ELOG_TYPE_DECLARE (e) =
5306 {
5307 .format = "VPPCOM_ATTR_SET_TCP_NODELAY: %d buflen=%d",
5308 .format_args = "i4i4",
5309 };
5310
5311 struct {
5312 u32 data[2];
5313 } * ed;
5314
5315 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
5316 ed->data[0] = VCL_SESS_ATTR_TEST (session->attr,
5317 VCL_SESS_ATTR_TCP_NODELAY);
5318 ed->data[1] = *buflen;
5319 /* *INDENT-ON* */
5320 }
Dave Wallace048b1d62018-01-03 22:24:41 -05005321 }
5322 else
5323 rv = VPPCOM_EINVAL;
5324 break;
5325
5326 case VPPCOM_ATTR_GET_TCP_KEEPIDLE:
5327 if (buffer && buflen && (*buflen >= sizeof (int)))
5328 {
5329 /* VPP-TBD */
5330 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
5331 VCL_SESS_ATTR_TCP_KEEPIDLE);
5332 *buflen = sizeof (int);
5333
5334 if (VPPCOM_DEBUG > 2)
5335 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_TCP_KEEPIDLE: %d, "
5336 "buflen %d, #VPP-TBD#", getpid (), *(int *) buffer,
5337 *buflen);
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005338 if (VPPCOM_DEBUG > 0)
5339 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08005340 /* *INDENT-OFF* */
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005341 ELOG_TYPE_DECLARE (e) =
5342 {
5343 .format = "VPPCOM_ATTR_GET_TCP_KEEPIDLE: %d buflen=%d",
5344 .format_args = "i4i4",
5345 };
5346
5347 struct {
5348 u32 data[2];
5349 } * ed;
5350
5351 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
5352 ed->data[0] = *(int *) buffer;
5353 ed->data[1] = *buflen;
5354 /* *INDENT-ON* */
5355 }
Dave Wallace048b1d62018-01-03 22:24:41 -05005356 }
5357 else
5358 rv = VPPCOM_EINVAL;
Stevenbccd3392017-10-12 20:42:21 -07005359 break;
5360
5361 case VPPCOM_ATTR_SET_TCP_KEEPIDLE:
Dave Wallace048b1d62018-01-03 22:24:41 -05005362 if (buffer && buflen && (*buflen == sizeof (int)))
5363 {
5364 /* VPP-TBD */
5365 if (*(int *) buffer)
5366 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_TCP_KEEPIDLE);
5367 else
5368 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_TCP_KEEPIDLE);
5369
5370 if (VPPCOM_DEBUG > 2)
5371 clib_warning ("VCL<%d>: VPPCOM_ATTR_SET_TCP_KEEPIDLE: %d, "
5372 "buflen %d, #VPP-TBD#", getpid (),
5373 VCL_SESS_ATTR_TEST (session->attr,
5374 VCL_SESS_ATTR_TCP_KEEPIDLE),
5375 *buflen);
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005376 if (VPPCOM_DEBUG > 0)
5377 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08005378 /* *INDENT-OFF* */
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005379 ELOG_TYPE_DECLARE (e) =
5380 {
5381 .format = "VPPCOM_ATTR_SET_TCP_KEEPIDLE: %d buflen=%d",
5382 .format_args = "i4i4",
5383 };
5384
5385 struct {
5386 u32 data[2];
5387 } * ed;
5388
5389 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
5390 ed->data[0] = VCL_SESS_ATTR_TEST (session->attr,
5391 VCL_SESS_ATTR_TCP_KEEPIDLE);
5392 ed->data[1] = *buflen;
5393 /* *INDENT-ON* */
5394 }
Dave Wallace048b1d62018-01-03 22:24:41 -05005395 }
5396 else
5397 rv = VPPCOM_EINVAL;
5398 break;
5399
5400 case VPPCOM_ATTR_GET_TCP_KEEPINTVL:
5401 if (buffer && buflen && (*buflen >= sizeof (int)))
5402 {
5403 /* VPP-TBD */
5404 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
5405 VCL_SESS_ATTR_TCP_KEEPINTVL);
5406 *buflen = sizeof (int);
5407
5408 if (VPPCOM_DEBUG > 2)
5409 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_TCP_KEEPINTVL: %d, "
5410 "buflen %d, #VPP-TBD#", getpid (), *(int *) buffer,
5411 *buflen);
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005412 if (VPPCOM_DEBUG > 0)
5413 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08005414 /* *INDENT-OFF* */
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005415 ELOG_TYPE_DECLARE (e) =
5416 {
5417 .format = "VPPCOM_ATTR_GET_TCP_KEEPIDLE: %d buflen=%d",
5418 .format_args = "i4i4",
5419 };
5420
5421 struct {
5422 u32 data[2];
5423 } * ed;
5424
5425 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
5426 ed->data[0] = *(int *) buffer;
5427 ed->data[1] = *buflen;
5428 /* *INDENT-ON* */
5429 }
Dave Wallace048b1d62018-01-03 22:24:41 -05005430 }
5431 else
5432 rv = VPPCOM_EINVAL;
Stevenbccd3392017-10-12 20:42:21 -07005433 break;
5434
5435 case VPPCOM_ATTR_SET_TCP_KEEPINTVL:
Dave Wallace048b1d62018-01-03 22:24:41 -05005436 if (buffer && buflen && (*buflen == sizeof (int)))
5437 {
5438 /* VPP-TBD */
5439 if (*(int *) buffer)
5440 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_TCP_KEEPINTVL);
5441 else
5442 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_TCP_KEEPINTVL);
5443
5444 if (VPPCOM_DEBUG > 2)
5445 clib_warning ("VCL<%d>: VPPCOM_ATTR_SET_TCP_KEEPINTVL: %d, "
5446 "buflen %d, #VPP-TBD#", getpid (),
5447 VCL_SESS_ATTR_TEST (session->attr,
5448 VCL_SESS_ATTR_TCP_KEEPINTVL),
5449 *buflen);
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005450 if (VPPCOM_DEBUG > 0)
5451 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08005452 /* *INDENT-OFF* */
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005453 ELOG_TYPE_DECLARE (e) =
5454 {
5455 .format = "VPPCOM_ATTR_SET_TCP_KEEPINTVL: %d buflen=%d",
5456 .format_args = "i4i4",
5457 };
5458
5459 struct {
5460 u32 data[2];
5461 } * ed;
5462
5463 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
5464 ed->data[0] = VCL_SESS_ATTR_TEST (session->attr,
5465 VCL_SESS_ATTR_TCP_KEEPINTVL);
5466 ed->data[1] = *buflen;
5467 /* *INDENT-ON* */
5468 }
Dave Wallace048b1d62018-01-03 22:24:41 -05005469 }
5470 else
5471 rv = VPPCOM_EINVAL;
5472 break;
5473
5474 case VPPCOM_ATTR_GET_TCP_USER_MSS:
5475 if (buffer && buflen && (*buflen >= sizeof (u32)))
5476 {
5477 /* VPP-TBD */
5478 *(u32 *) buffer = session->user_mss;
5479 *buflen = sizeof (int);
5480
5481 if (VPPCOM_DEBUG > 2)
5482 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_TCP_USER_MSS: %d, "
5483 "buflen %d, #VPP-TBD#", getpid (), *(int *) buffer,
5484 *buflen);
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005485 if (VPPCOM_DEBUG > 0)
5486 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08005487 /* *INDENT-OFF* */
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005488 ELOG_TYPE_DECLARE (e) =
5489 {
5490 .format = "VPPCOM_ATTR_GET_TCP_USER_MSS: %d buflen=%d",
5491 .format_args = "i4i4",
5492 };
5493
5494 struct {
5495 u32 data[2];
5496 } * ed;
5497
5498 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
5499 ed->data[0] = *(int *) buffer;
5500 ed->data[1] = *buflen;
5501 /* *INDENT-ON* */
5502 }
Dave Wallace048b1d62018-01-03 22:24:41 -05005503 }
5504 else
5505 rv = VPPCOM_EINVAL;
5506 break;
5507
5508 case VPPCOM_ATTR_SET_TCP_USER_MSS:
5509 if (buffer && buflen && (*buflen == sizeof (u32)))
5510 {
5511 /* VPP-TBD */
5512 session->user_mss = *(u32 *) buffer;
5513
5514 if (VPPCOM_DEBUG > 2)
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005515 clib_warning ("VCL<%d>: VPPCOM_ATTR_SET_TCP_USER_MSS: %u, "
Dave Wallace048b1d62018-01-03 22:24:41 -05005516 "buflen %d, #VPP-TBD#", getpid (),
5517 session->user_mss, *buflen);
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005518 if (VPPCOM_DEBUG > 0)
5519 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08005520 /* *INDENT-OFF* */
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005521 ELOG_TYPE_DECLARE (e) =
5522 {
5523 .format = "VPPCOM_ATTR_SET_TCP_USER_MSS: %d buflen=%d",
5524 .format_args = "i4i4",
5525 };
5526
5527 struct {
5528 u32 data[2];
5529 } * ed;
5530
5531 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
5532 ed->data[0] = session->user_mss;
5533 ed->data[1] = *buflen;
5534 /* *INDENT-ON* */
5535 }
Dave Wallace048b1d62018-01-03 22:24:41 -05005536 }
5537 else
5538 rv = VPPCOM_EINVAL;
Stevenbccd3392017-10-12 20:42:21 -07005539 break;
Dave Wallacee22aa742017-10-20 12:30:38 -04005540
5541 default:
5542 rv = VPPCOM_EINVAL;
5543 break;
Dave Wallace35830af2017-10-09 01:43:42 -04005544 }
5545
5546done:
5547 clib_spinlock_unlock (&vcm->sessions_lockp);
5548 return rv;
5549}
5550
Stevenac1f96d2017-10-24 16:03:58 -07005551int
5552vppcom_session_recvfrom (uint32_t session_index, void *buffer,
5553 uint32_t buflen, int flags, vppcom_endpt_t * ep)
5554{
Stevenac1f96d2017-10-24 16:03:58 -07005555 int rv = VPPCOM_OK;
5556 session_t *session = 0;
5557
5558 if (ep)
5559 {
5560 clib_spinlock_lock (&vcm->sessions_lockp);
5561 rv = vppcom_session_at_index (session_index, &session);
5562 if (PREDICT_FALSE (rv))
5563 {
5564 clib_spinlock_unlock (&vcm->sessions_lockp);
5565 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05005566 clib_warning ("VCL<%d>: invalid session, "
5567 "sid (%u) has been closed!",
Dave Wallace2e005bb2017-11-07 01:21:39 -05005568 getpid (), session_index);
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005569 if (VPPCOM_DEBUG > 0)
5570 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08005571 /* *INDENT-OFF* */
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005572 ELOG_TYPE_DECLARE (e) =
5573 {
5574 .format = "invalid session: %d closed",
5575 .format_args = "i4",
5576 };
5577
5578 struct {
5579 u32 data;
5580 } * ed;
5581
5582 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, vcm->elog_track);
5583 ed->data = session_index;
5584 /* *INDENT-ON* */
5585 }
Dave Wallacefaf9d772017-10-26 16:12:04 -04005586 rv = VPPCOM_EBADFD;
5587 clib_spinlock_unlock (&vcm->sessions_lockp);
5588 goto done;
Stevenac1f96d2017-10-24 16:03:58 -07005589 }
Stevenac1f96d2017-10-24 16:03:58 -07005590 ep->is_ip4 = session->peer_addr.is_ip4;
5591 ep->port = session->peer_port;
5592 if (session->peer_addr.is_ip4)
5593 clib_memcpy (ep->ip, &session->peer_addr.ip46.ip4,
5594 sizeof (ip4_address_t));
5595 else
5596 clib_memcpy (ep->ip, &session->peer_addr.ip46.ip6,
5597 sizeof (ip6_address_t));
5598 clib_spinlock_unlock (&vcm->sessions_lockp);
Stevenac1f96d2017-10-24 16:03:58 -07005599 }
Steven58f464e2017-10-25 12:33:12 -07005600
5601 if (flags == 0)
Stevenac1f96d2017-10-24 16:03:58 -07005602 rv = vppcom_session_read (session_index, buffer, buflen);
5603 else if (flags & MSG_PEEK)
Steven58f464e2017-10-25 12:33:12 -07005604 rv = vppcom_session_peek (session_index, buffer, buflen);
Stevenac1f96d2017-10-24 16:03:58 -07005605 else
5606 {
Dave Wallace048b1d62018-01-03 22:24:41 -05005607 clib_warning ("VCL<%d>: Unsupport flags for recvfrom %d",
5608 getpid (), flags);
Stevenac1f96d2017-10-24 16:03:58 -07005609 rv = VPPCOM_EAFNOSUPPORT;
5610 }
5611
Dave Wallacefaf9d772017-10-26 16:12:04 -04005612done:
Stevenac1f96d2017-10-24 16:03:58 -07005613 return rv;
5614}
5615
5616int
5617vppcom_session_sendto (uint32_t session_index, void *buffer,
5618 uint32_t buflen, int flags, vppcom_endpt_t * ep)
5619{
Dave Wallace617dffa2017-10-26 14:47:06 -04005620 if (!buffer)
5621 return VPPCOM_EINVAL;
5622
5623 if (ep)
5624 {
5625 // TBD
5626 return VPPCOM_EINVAL;
5627 }
5628
5629 if (flags)
5630 {
5631 // TBD check the flags and do the right thing
5632 if (VPPCOM_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05005633 clib_warning ("VCL<%d>: handling flags 0x%u (%d) "
5634 "not implemented yet.", getpid (), flags, flags);
Dave Wallace617dffa2017-10-26 14:47:06 -04005635 }
5636
5637 return (vppcom_session_write (session_index, buffer, buflen));
Stevenac1f96d2017-10-24 16:03:58 -07005638}
5639
Dave Wallace048b1d62018-01-03 22:24:41 -05005640int
5641vppcom_poll (vcl_poll_t * vp, uint32_t n_sids, double wait_for_time)
5642{
5643 f64 timeout = clib_time_now (&vcm->clib_time) + wait_for_time;
5644 u32 i, keep_trying = 1;
5645 int rv, num_ev = 0;
5646
5647 if (VPPCOM_DEBUG > 3)
5648 clib_warning ("VCL<%d>: vp %p, nsids %u, wait_for_time %f",
5649 getpid (), vp, n_sids, wait_for_time);
5650
5651 if (!vp)
5652 return VPPCOM_EFAULT;
5653
5654 do
5655 {
5656 session_t *session;
5657
5658 for (i = 0; i < n_sids; i++)
5659 {
5660 ASSERT (vp[i].revents);
5661
5662 VCL_LOCK_AND_GET_SESSION (vp[i].sid, &session);
5663 clib_spinlock_unlock (&vcm->sessions_lockp);
5664
5665 if (*vp[i].revents)
5666 *vp[i].revents = 0;
5667
5668 if (POLLIN & vp[i].events)
5669 {
5670 VCL_LOCK_AND_GET_SESSION (vp[i].sid, &session);
5671 rv = vppcom_session_read_ready (session, vp[i].sid);
5672 clib_spinlock_unlock (&vcm->sessions_lockp);
5673 if (rv > 0)
5674 {
5675 *vp[i].revents |= POLLIN;
5676 num_ev++;
5677 }
5678 else if (rv < 0)
5679 {
5680 switch (rv)
5681 {
5682 case VPPCOM_ECONNRESET:
5683 *vp[i].revents = POLLHUP;
5684 break;
5685
5686 default:
5687 *vp[i].revents = POLLERR;
5688 break;
5689 }
5690 num_ev++;
5691 }
5692 }
5693
5694 if (POLLOUT & vp[i].events)
5695 {
5696 VCL_LOCK_AND_GET_SESSION (vp[i].sid, &session);
5697 rv = vppcom_session_write_ready (session, vp[i].sid);
5698 clib_spinlock_unlock (&vcm->sessions_lockp);
5699 if (rv > 0)
5700 {
5701 *vp[i].revents |= POLLOUT;
5702 num_ev++;
5703 }
5704 else if (rv < 0)
5705 {
5706 switch (rv)
5707 {
5708 case VPPCOM_ECONNRESET:
5709 *vp[i].revents = POLLHUP;
5710 break;
5711
5712 default:
5713 *vp[i].revents = POLLERR;
5714 break;
5715 }
5716 num_ev++;
5717 }
5718 }
5719
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08005720 if (0) // Note "done:" label used by VCL_LOCK_AND_GET_SESSION()
Dave Wallace048b1d62018-01-03 22:24:41 -05005721 {
5722 done:
5723 *vp[i].revents = POLLNVAL;
5724 num_ev++;
5725 }
5726 }
5727 if (wait_for_time != -1)
5728 keep_trying = (clib_time_now (&vcm->clib_time) <= timeout) ? 1 : 0;
5729 }
5730 while ((num_ev == 0) && keep_trying);
5731
5732 if (VPPCOM_DEBUG > 3)
5733 {
5734 clib_warning ("VCL<%d>: returning %d", getpid (), num_ev);
5735 for (i = 0; i < n_sids; i++)
5736 {
5737 clib_warning ("VCL<%d>: vp[%d].sid %d (0x%x), .events 0x%x, "
5738 ".revents 0x%x", getpid (), i, vp[i].sid, vp[i].sid,
5739 vp[i].events, *vp[i].revents);
5740 }
5741 }
5742 return num_ev;
5743}
5744
Dave Wallacee22aa742017-10-20 12:30:38 -04005745/*
5746 * fd.io coding-style-patch-verification: ON
5747 *
5748 * Local Variables:
5749 * eval: (c-set-style "gnu")
5750 * End:
5751 */