blob: 7edb69c4c73c37507eb3679787e1d74593d3ec18 [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>
Dave Wallace543852a2017-08-03 02:11:34 -040024#include <vlib/unix/unix.h>
25#include <vppinfra/vec_bootstrap.h>
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -080026#include <vppinfra/elog.h>
Dave Wallace543852a2017-08-03 02:11:34 -040027
28#define vl_typedefs /* define message structures */
29#include <vpp/api/vpe_all_api_h.h>
30#undef vl_typedefs
31
32/* declare message handlers for each api */
33
34#define vl_endianfun /* define message structures */
35#include <vpp/api/vpe_all_api_h.h>
36#undef vl_endianfun
37
38/* instantiate all the print functions we know about */
39#define vl_print(handle, ...)
40#define vl_printfun
41#include <vpp/api/vpe_all_api_h.h>
42#undef vl_printfun
43
44#if (CLIB_DEBUG > 0)
Dave Wallace498b3a52017-11-09 13:00:34 -050045/* Set VPPCOM_DEBUG_INIT 2 for connection debug,
46 * 3 for read/write debug output
47 * or
48 * export VCL_DEBUG=<#> to set dynamically.
49 */
50#define VPPCOM_DEBUG_INIT 1
Dave Wallace543852a2017-08-03 02:11:34 -040051#else
Dave Wallace498b3a52017-11-09 13:00:34 -050052#define VPPCOM_DEBUG_INIT 0
Dave Wallace543852a2017-08-03 02:11:34 -040053#endif
54
Dave Wallace498b3a52017-11-09 13:00:34 -050055#define VPPCOM_DEBUG vcm->debug
56
Dave Wallace543852a2017-08-03 02:11:34 -040057/*
58 * VPPCOM Private definitions and functions.
59 */
60typedef enum
61{
62 STATE_APP_START,
63 STATE_APP_CONN_VPP,
64 STATE_APP_ENABLED,
65 STATE_APP_ATTACHED,
66} app_state_t;
67
68typedef enum
69{
Dave Wallace4878cbe2017-11-21 03:45:09 -050070 STATE_START = 0x01,
71 STATE_CONNECT = 0x02,
72 STATE_LISTEN = 0x04,
73 STATE_ACCEPT = 0x08,
74 STATE_CLOSE_ON_EMPTY = 0x10,
75 STATE_DISCONNECT = 0x20,
76 STATE_FAILED = 0x40
Dave Wallace543852a2017-08-03 02:11:34 -040077} session_state_t;
78
Dave Wallace4878cbe2017-11-21 03:45:09 -050079#define SERVER_STATE_OPEN (STATE_ACCEPT|STATE_CLOSE_ON_EMPTY)
80#define CLIENT_STATE_OPEN (STATE_CONNECT|STATE_CLOSE_ON_EMPTY)
81
Dave Wallacef7f809c2017-10-03 01:48:42 -040082typedef struct epoll_event vppcom_epoll_event_t;
83
84typedef struct
85{
86 u32 next_sid;
87 u32 prev_sid;
88 u32 vep_idx;
89 vppcom_epoll_event_t ev;
90#define VEP_DEFAULT_ET_MASK (EPOLLIN|EPOLLOUT)
Dave Wallace60caa062017-11-10 17:07:13 -050091#define VEP_UNSUPPORTED_EVENTS (EPOLLONESHOT|EPOLLEXCLUSIVE)
Dave Wallacef7f809c2017-10-03 01:48:42 -040092 u32 et_mask;
93} vppcom_epoll_t;
94
Dave Wallace543852a2017-08-03 02:11:34 -040095typedef struct
96{
Dave Wallace35830af2017-10-09 01:43:42 -040097 u8 is_ip4;
98 ip46_address_t ip46;
99} vppcom_ip46_t;
100
Dave Wallace048b1d62018-01-03 22:24:41 -0500101enum
102{
103 VCL_SESS_ATTR_SERVER,
104 VCL_SESS_ATTR_CUT_THRU,
105 VCL_SESS_ATTR_VEP,
106 VCL_SESS_ATTR_VEP_SESSION,
107 VCL_SESS_ATTR_LISTEN, // SOL_SOCKET,SO_ACCEPTCONN
108 VCL_SESS_ATTR_NONBLOCK, // fcntl,O_NONBLOCK
109 VCL_SESS_ATTR_REUSEADDR, // SOL_SOCKET,SO_REUSEADDR
110 VCL_SESS_ATTR_REUSEPORT, // SOL_SOCKET,SO_REUSEPORT
111 VCL_SESS_ATTR_BROADCAST, // SOL_SOCKET,SO_BROADCAST
112 VCL_SESS_ATTR_V6ONLY, // SOL_TCP,IPV6_V6ONLY
113 VCL_SESS_ATTR_KEEPALIVE, // SOL_SOCKET,SO_KEEPALIVE
114 VCL_SESS_ATTR_TCP_NODELAY, // SOL_TCP,TCP_NODELAY
115 VCL_SESS_ATTR_TCP_KEEPIDLE, // SOL_TCP,TCP_KEEPIDLE
116 VCL_SESS_ATTR_TCP_KEEPINTVL, // SOL_TCP,TCP_KEEPINTVL
117 VCL_SESS_ATTR_MAX
118} vppcom_session_attr_t;
119
120#define VCL_SESS_ATTR_SET(ATTR, VAL) \
121do { \
122 (ATTR) |= 1 << (VAL); \
123 } while (0)
124
125#define VCL_SESS_ATTR_CLR(ATTR, VAL) \
126do { \
127 (ATTR) &= ~(1 << (VAL)); \
128 } while (0)
129
130#define VCL_SESS_ATTR_TEST(ATTR, VAL) \
131 ((ATTR) & (1 << (VAL)) ? 1 : 0)
132
Dave Wallace35830af2017-10-09 01:43:42 -0400133typedef struct
134{
Dave Wallace543852a2017-08-03 02:11:34 -0400135 volatile session_state_t state;
136
137 svm_fifo_t *server_rx_fifo;
138 svm_fifo_t *server_tx_fifo;
Dave Wallace048b1d62018-01-03 22:24:41 -0500139 u32 sndbuf_size; // VPP-TBD: Hack until support setsockopt(SO_SNDBUF)
140 u32 rcvbuf_size; // VPP-TBD: Hack until support setsockopt(SO_RCVBUF)
141 u32 user_mss; // VPP-TBD: Hack until support setsockopt(TCP_MAXSEG)
Dave Wallace60caa062017-11-10 17:07:13 -0500142 u8 *segment_name;
Dave Wallace543852a2017-08-03 02:11:34 -0400143 u32 sm_seg_index;
Dave Wallace60caa062017-11-10 17:07:13 -0500144 u32 client_context;
145 u64 vpp_handle;
Florin Corase86a8ed2018-01-05 03:20:25 -0800146 svm_queue_t *vpp_event_queue;
Dave Wallace543852a2017-08-03 02:11:34 -0400147
148 /* Socket configuration state */
Dave Wallace048b1d62018-01-03 22:24:41 -0500149 /* TBD: covert 'is_*' vars to bit in session->attr; */
Dave Wallace543852a2017-08-03 02:11:34 -0400150 u8 is_server;
151 u8 is_listen;
152 u8 is_cut_thru;
153 u8 is_nonblocking;
Dave Wallacef7f809c2017-10-03 01:48:42 -0400154 u8 is_vep;
155 u8 is_vep_session;
Dave Wallace048b1d62018-01-03 22:24:41 -0500156 u32 attr;
Dave Wallacef7f809c2017-10-03 01:48:42 -0400157 u32 wait_cont_idx;
158 vppcom_epoll_t vep;
Dave Wallace048b1d62018-01-03 22:24:41 -0500159 int libc_epfd;
Dave Wallace35830af2017-10-09 01:43:42 -0400160 vppcom_ip46_t lcl_addr;
161 vppcom_ip46_t peer_addr;
Stevenac1f96d2017-10-24 16:03:58 -0700162 u16 lcl_port; // network order
163 u16 peer_port; // network order
Dave Wallace543852a2017-08-03 02:11:34 -0400164 u8 proto;
165 u64 client_queue_address;
166 u64 options[16];
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -0800167 elog_track_t elog_track;
Dave Wallace543852a2017-08-03 02:11:34 -0400168} session_t;
169
170typedef struct vppcom_cfg_t_
171{
172 u64 heapsize;
Dave Wallacec8f1ee62017-11-29 22:46:32 -0500173 u32 vpp_api_q_length;
Dave Wallace543852a2017-08-03 02:11:34 -0400174 u64 segment_baseva;
175 u32 segment_size;
176 u32 add_segment_size;
177 u32 preallocated_fifo_pairs;
178 u32 rx_fifo_size;
179 u32 tx_fifo_size;
180 u32 event_queue_size;
181 u32 listen_queue_size;
Dave Wallace774169b2017-11-01 20:07:40 -0400182 u8 app_proxy_transport_tcp;
183 u8 app_proxy_transport_udp;
184 u8 app_scope_local;
185 u8 app_scope_global;
Dave Wallace8af20542017-10-26 03:29:30 -0400186 u8 *namespace_id;
187 u64 namespace_secret;
Dave Wallace543852a2017-08-03 02:11:34 -0400188 f64 app_timeout;
189 f64 session_timeout;
190 f64 accept_timeout;
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -0800191 u32 event_ring_size;
192 char *event_log_path;
Dave Wallace543852a2017-08-03 02:11:34 -0400193} vppcom_cfg_t;
194
195typedef struct vppcom_main_t_
196{
197 u8 init;
Dave Wallace498b3a52017-11-09 13:00:34 -0500198 u32 debug;
Dave Wallace543852a2017-08-03 02:11:34 -0400199 u32 *client_session_index_fifo;
Dave Wallace543852a2017-08-03 02:11:34 -0400200 int main_cpu;
201
202 /* vpe input queue */
Florin Corase86a8ed2018-01-05 03:20:25 -0800203 svm_queue_t *vl_input_queue;
Dave Wallace543852a2017-08-03 02:11:34 -0400204
205 /* API client handle */
206 u32 my_client_index;
207
208 /* Session pool */
209 clib_spinlock_t sessions_lockp;
210 session_t *sessions;
211
212 /* Hash table for disconnect processing */
213 uword *session_index_by_vpp_handles;
214
215 /* Select bitmaps */
216 clib_bitmap_t *rd_bitmap;
217 clib_bitmap_t *wr_bitmap;
218 clib_bitmap_t *ex_bitmap;
219
220 /* Our event queue */
Florin Corase86a8ed2018-01-05 03:20:25 -0800221 svm_queue_t *app_event_queue;
Dave Wallace543852a2017-08-03 02:11:34 -0400222
223 /* unique segment name counter */
224 u32 unique_segment_index;
225
Dave Wallace543852a2017-08-03 02:11:34 -0400226 /* For deadman timers */
227 clib_time_t clib_time;
228
229 /* State of the connection, shared between msg RX thread and main thread */
230 volatile app_state_t app_state;
231
232 vppcom_cfg_t cfg;
233
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -0800234 /* Event logging */
235 elog_main_t elog_main;
236 elog_track_t elog_track;
237
Dave Wallace543852a2017-08-03 02:11:34 -0400238 /* VNET_API_ERROR_FOO -> "Foo" hash table */
239 uword *error_string_by_error_number;
240} vppcom_main_t;
241
Dave Wallace2e005bb2017-11-07 01:21:39 -0500242/* NOTE: _vppcom_main is only used until the heap is allocated.
243 * Do not access it directly -- use vcm which will point to
244 * the heap allocated copy after init.
245 */
Dave Wallace498b3a52017-11-09 13:00:34 -0500246static vppcom_main_t _vppcom_main = {
247 .debug = VPPCOM_DEBUG_INIT,
248 .my_client_index = ~0
249};
Dave Wallace2e005bb2017-11-07 01:21:39 -0500250
251static vppcom_main_t *vcm = &_vppcom_main;
Dave Wallace543852a2017-08-03 02:11:34 -0400252
Dave Wallace048b1d62018-01-03 22:24:41 -0500253#define VCL_LOCK_AND_GET_SESSION(I, S) \
254do { \
255 clib_spinlock_lock (&vcm->sessions_lockp); \
256 rv = vppcom_session_at_index (I, S); \
257 if (PREDICT_FALSE (rv)) \
258 { \
259 clib_spinlock_unlock (&vcm->sessions_lockp); \
260 clib_warning ("VCL<%d>: ERROR: Invalid ##I (%u)!", \
261 getpid (), I); \
262 goto done; \
263 } \
Dave Wallace60caa062017-11-10 17:07:13 -0500264} while (0)
265
Dave Wallace543852a2017-08-03 02:11:34 -0400266static const char *
267vppcom_app_state_str (app_state_t state)
268{
269 char *st;
270
271 switch (state)
272 {
273 case STATE_APP_START:
274 st = "STATE_APP_START";
275 break;
276
277 case STATE_APP_CONN_VPP:
278 st = "STATE_APP_CONN_VPP";
279 break;
280
281 case STATE_APP_ENABLED:
282 st = "STATE_APP_ENABLED";
283 break;
284
285 case STATE_APP_ATTACHED:
286 st = "STATE_APP_ATTACHED";
287 break;
288
289 default:
290 st = "UNKNOWN_APP_STATE";
291 break;
292 }
293
294 return st;
295}
296
297static const char *
298vppcom_session_state_str (session_state_t state)
299{
300 char *st;
301
302 switch (state)
303 {
304 case STATE_START:
305 st = "STATE_START";
306 break;
307
308 case STATE_CONNECT:
309 st = "STATE_CONNECT";
310 break;
311
312 case STATE_LISTEN:
313 st = "STATE_LISTEN";
314 break;
315
316 case STATE_ACCEPT:
317 st = "STATE_ACCEPT";
318 break;
319
Dave Wallace4878cbe2017-11-21 03:45:09 -0500320 case STATE_CLOSE_ON_EMPTY:
321 st = "STATE_CLOSE_ON_EMPTY";
322 break;
323
Dave Wallace543852a2017-08-03 02:11:34 -0400324 case STATE_DISCONNECT:
325 st = "STATE_DISCONNECT";
326 break;
327
328 case STATE_FAILED:
329 st = "STATE_FAILED";
330 break;
331
332 default:
333 st = "UNKNOWN_STATE";
334 break;
335 }
336
337 return st;
338}
339
340/*
341 * VPPCOM Utility Functions
342 */
343static inline int
344vppcom_session_at_index (u32 session_index, session_t * volatile *sess)
345{
Dave Wallace543852a2017-08-03 02:11:34 -0400346 /* Assumes that caller has acquired spinlock: vcm->sessions_lockp */
347 if (PREDICT_FALSE ((session_index == ~0) ||
348 pool_is_free_index (vcm->sessions, session_index)))
349 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500350 clib_warning ("VCL<%d>: invalid session, sid (%u) has been closed!",
Dave Wallace2e005bb2017-11-07 01:21:39 -0500351 getpid (), session_index);
Dave Wallace543852a2017-08-03 02:11:34 -0400352 return VPPCOM_EBADFD;
353 }
354 *sess = pool_elt_at_index (vcm->sessions, session_index);
355 return VPPCOM_OK;
356}
357
Florin Corasdcf55ce2017-11-16 15:32:50 -0800358static inline void
359vppcom_session_table_add_listener (u64 listener_handle, u32 value)
360{
361 /* Session and listener handles have different formats. The latter has
362 * the thread index in the upper 32 bits while the former has the session
363 * type. Knowing that, for listeners we just flip the MSB to 1 */
364 listener_handle |= 1ULL << 63;
365 hash_set (vcm->session_index_by_vpp_handles, listener_handle, value);
366}
367
368static inline session_t *
369vppcom_session_table_lookup_listener (u64 listener_handle)
370{
371 uword *p;
372 u64 handle = listener_handle | (1ULL << 63);
Dave Wallace4878cbe2017-11-21 03:45:09 -0500373 session_t *session;
374
Florin Corasdcf55ce2017-11-16 15:32:50 -0800375 p = hash_get (vcm->session_index_by_vpp_handles, handle);
376 if (!p)
377 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500378 clib_warning ("VCL<%d>: couldn't find listen session: unknown vpp "
Florin Corasdcf55ce2017-11-16 15:32:50 -0800379 "listener handle %llx", getpid (), listener_handle);
380 return 0;
381 }
382 if (pool_is_free_index (vcm->sessions, p[0]))
383 {
384 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -0500385 clib_warning ("VCL<%d>: invalid listen session, sid (%u)",
386 getpid (), p[0]);
Florin Corasdcf55ce2017-11-16 15:32:50 -0800387 return 0;
388 }
389
Dave Wallace4878cbe2017-11-21 03:45:09 -0500390 session = pool_elt_at_index (vcm->sessions, p[0]);
391 ASSERT (session->is_listen);
392 return session;
Florin Corasdcf55ce2017-11-16 15:32:50 -0800393}
394
395static inline void
396vppcom_session_table_del_listener (u64 listener_handle)
397{
398 listener_handle |= 1ULL << 63;
399 hash_unset (vcm->session_index_by_vpp_handles, listener_handle);
400}
401
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -0800402static void
403write_elog (void)
404{
405 elog_main_t *em = &vcm->elog_main;
406 char *chroot_file;
407 clib_error_t *error = 0;
408
409 chroot_file =
410 (char *) format (0, "%s/%d-%d-vcl-elog%c", vcm->cfg.event_log_path,
411 vcm->my_client_index, getpid (), 0);
412 error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
413 if (error)
414 {
415 clib_error_report (error);
416 }
417 if (VPPCOM_DEBUG > 0)
418 clib_warning ("[%d] Event Log:'%s' ", getpid (), chroot_file);
419
420}
421
Dave Wallace543852a2017-08-03 02:11:34 -0400422static int
423vppcom_connect_to_vpp (char *app_name)
424{
425 api_main_t *am = &api_main;
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -0800426 int rv = VPPCOM_OK;
Dave Wallace543852a2017-08-03 02:11:34 -0400427
428 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -0500429 clib_warning ("VCL<%d>: app (%s) connecting to VPP api...",
430 getpid (), app_name);
431
Dave Wallacec8f1ee62017-11-29 22:46:32 -0500432 if (vl_client_connect_to_vlib ("/vpe-api", app_name,
433 vcm->cfg.vpp_api_q_length) < 0)
Dave Wallace543852a2017-08-03 02:11:34 -0400434 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500435 clib_warning ("VCL<%d>: app (%s) connect failed!", getpid (), app_name);
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -0800436 rv = VPPCOM_ECONNREFUSED;
437 }
438 else
439 {
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -0800440 vcm->vl_input_queue = am->shmem_hdr->vl_input_queue;
441 vcm->my_client_index = am->my_client_index;
442 vcm->app_state = STATE_APP_CONN_VPP;
Dave Wallace9b954252018-01-18 17:01:40 -0500443
444 if (VPPCOM_DEBUG > 0)
445 clib_warning ("VCL<%d>: app (%s) is connected to VPP!",
446 getpid (), app_name);
Dave Wallace543852a2017-08-03 02:11:34 -0400447 }
448
Dave Wallace543852a2017-08-03 02:11:34 -0400449 if (VPPCOM_DEBUG > 0)
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -0800450 {
451 vcm->elog_main.lock =
452 clib_mem_alloc_aligned (CLIB_CACHE_LINE_BYTES, CLIB_CACHE_LINE_BYTES);
453 vcm->elog_main.lock[0] = 0;
454 vcm->elog_main.event_ring_size = vcm->cfg.event_ring_size;
455 elog_init (&vcm->elog_main, vcm->elog_main.event_ring_size);
456 elog_enable_disable (&vcm->elog_main, 1);
Dave Wallace543852a2017-08-03 02:11:34 -0400457
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -0800458 vcm->elog_track.name =
459 (char *) format (0, "P:%d:C:%d%c", getpid (),
460 vcm->my_client_index, 0);
461 elog_track_register (&vcm->elog_main, &vcm->elog_track);
462
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -0800463 /* *INDENT-OFF* */
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -0800464 ELOG_TYPE_DECLARE (e) =
465 {
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -0800466 .format = "connect_vpp:rv:%d",
467 .format_args = "i4",
468 };
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -0800469 struct
470 {
471 u32 data;
472 } *ed;
473 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, vcm->elog_track);
474 ed->data = rv;
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -0800475 /* *INDENT-ON* */
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -0800476 }
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -0800477 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -0400478}
479
480static u8 *
481format_api_error (u8 * s, va_list * args)
482{
Dave Wallace543852a2017-08-03 02:11:34 -0400483 i32 error = va_arg (*args, u32);
484 uword *p;
485
486 p = hash_get (vcm->error_string_by_error_number, -error);
487
488 if (p)
489 s = format (s, "%s (%d)", p[0], error);
490 else
491 s = format (s, "%d", error);
492 return s;
493}
494
495static void
496vppcom_init_error_string_table (void)
497{
Dave Wallace543852a2017-08-03 02:11:34 -0400498 vcm->error_string_by_error_number = hash_create (0, sizeof (uword));
499
500#define _(n,v,s) hash_set (vcm->error_string_by_error_number, -v, s);
501 foreach_vnet_api_error;
502#undef _
503
504 hash_set (vcm->error_string_by_error_number, 99, "Misc");
505}
506
507static inline int
508vppcom_wait_for_app_state_change (app_state_t app_state)
509{
Dave Wallace543852a2017-08-03 02:11:34 -0400510 f64 timeout = clib_time_now (&vcm->clib_time) + vcm->cfg.app_timeout;
511
512 while (clib_time_now (&vcm->clib_time) < timeout)
513 {
514 if (vcm->app_state == app_state)
515 return VPPCOM_OK;
516 }
517 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -0500518 clib_warning ("VCL<%d>: timeout waiting for state %s (%d)", getpid (),
Dave Wallace543852a2017-08-03 02:11:34 -0400519 vppcom_app_state_str (app_state), app_state);
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -0800520
521 if (VPPCOM_DEBUG > 0)
522 {
523 /* *INDENT-OFF* */
524 ELOG_TYPE_DECLARE (e) =
525 {
526 .format = "ERR: timeout state:%d",
527 .format_args = "i4",
528 };
529 struct
530 {
531 u32 data;
532 } *ed;
533
534 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, vcm->elog_track);
535
536 ed->data = app_state;
537 /* *INDENT-ON* */
538 }
539
Dave Wallace543852a2017-08-03 02:11:34 -0400540 return VPPCOM_ETIMEDOUT;
541}
542
543static inline int
544vppcom_wait_for_session_state_change (u32 session_index,
545 session_state_t state,
546 f64 wait_for_time)
547{
Dave Wallace543852a2017-08-03 02:11:34 -0400548 f64 timeout = clib_time_now (&vcm->clib_time) + wait_for_time;
549 session_t *volatile session;
550 int rv;
551
552 do
553 {
554 clib_spinlock_lock (&vcm->sessions_lockp);
555 rv = vppcom_session_at_index (session_index, &session);
556 if (PREDICT_FALSE (rv))
557 {
558 clib_spinlock_unlock (&vcm->sessions_lockp);
559 return rv;
560 }
561 if (session->state == state)
562 {
563 clib_spinlock_unlock (&vcm->sessions_lockp);
564 return VPPCOM_OK;
565 }
Dave Wallace4878cbe2017-11-21 03:45:09 -0500566 if (session->state == STATE_FAILED)
567 {
568 clib_spinlock_unlock (&vcm->sessions_lockp);
569 return VPPCOM_ECONNREFUSED;
570 }
571
Dave Wallace543852a2017-08-03 02:11:34 -0400572 clib_spinlock_unlock (&vcm->sessions_lockp);
573 }
574 while (clib_time_now (&vcm->clib_time) < timeout);
575
576 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -0500577 clib_warning ("VCL<%d>: timeout waiting for state 0x%x (%s)", getpid (),
Dave Wallace4878cbe2017-11-21 03:45:09 -0500578 state, vppcom_session_state_str (state));
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -0800579
580 if (VPPCOM_DEBUG > 0)
581 {
582 /* *INDENT-OFF* */
583 ELOG_TYPE_DECLARE (e) =
584 {
585 .format = "ERR: timeout state:%d",
586 .format_args = "i4",
587 };
588 struct
589 {
590 u32 data;
591 } *ed;
592
593 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
594
595 ed->data = state;
596 /* *INDENT-ON* */
597 }
598
Dave Wallace543852a2017-08-03 02:11:34 -0400599 return VPPCOM_ETIMEDOUT;
600}
601
602static inline int
603vppcom_wait_for_client_session_index (f64 wait_for_time)
604{
Dave Wallace543852a2017-08-03 02:11:34 -0400605 f64 timeout = clib_time_now (&vcm->clib_time) + wait_for_time;
606
607 do
608 {
609 if (clib_fifo_elts (vcm->client_session_index_fifo))
610 return VPPCOM_OK;
611 }
612 while (clib_time_now (&vcm->clib_time) < timeout);
613
614 if (wait_for_time == 0)
615 return VPPCOM_EAGAIN;
616
617 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -0500618 clib_warning ("VCL<%d>: timeout waiting for client_session_index",
619 getpid ());
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -0800620
621 if (VPPCOM_DEBUG > 0)
622 {
623 /* *INDENT-OFF* */
624 ELOG_TYPE_DECLARE (e) =
625 {
626 .format = "ERR: timeout waiting for session index :%d",
627 .format_args = "i4",
628 };
629 struct
630 {
631 u32 data;
632 } *ed;
633
634 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, vcm->elog_track);
635
636 ed->data = getpid();
637 /* *INDENT-ON* */
638 }
639
Dave Wallace543852a2017-08-03 02:11:34 -0400640 return VPPCOM_ETIMEDOUT;
641}
642
643/*
644 * VPP-API message functions
645 */
646static void
647vppcom_send_session_enable_disable (u8 is_enable)
648{
Dave Wallace543852a2017-08-03 02:11:34 -0400649 vl_api_session_enable_disable_t *bmp;
650 bmp = vl_msg_api_alloc (sizeof (*bmp));
651 memset (bmp, 0, sizeof (*bmp));
652
653 bmp->_vl_msg_id = ntohs (VL_API_SESSION_ENABLE_DISABLE);
654 bmp->client_index = vcm->my_client_index;
655 bmp->context = htonl (0xfeedface);
656 bmp->is_enable = is_enable;
657 vl_msg_api_send_shmem (vcm->vl_input_queue, (u8 *) & bmp);
658}
659
660static int
661vppcom_app_session_enable (void)
662{
Dave Wallace543852a2017-08-03 02:11:34 -0400663 int rv;
664
665 if (vcm->app_state != STATE_APP_ENABLED)
666 {
667 vppcom_send_session_enable_disable (1 /* is_enabled == TRUE */ );
668 rv = vppcom_wait_for_app_state_change (STATE_APP_ENABLED);
669 if (PREDICT_FALSE (rv))
670 {
671 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -0500672 clib_warning ("VCL<%d>: application session enable timed out! "
Dave Wallaceee45d412017-11-24 21:44:06 -0500673 "returning %d (%s)",
674 getpid (), rv, vppcom_retval_str (rv));
Dave Wallace543852a2017-08-03 02:11:34 -0400675 return rv;
676 }
677 }
678 return VPPCOM_OK;
679}
680
681static void
682 vl_api_session_enable_disable_reply_t_handler
683 (vl_api_session_enable_disable_reply_t * mp)
684{
Dave Wallace543852a2017-08-03 02:11:34 -0400685 if (mp->retval)
686 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500687 clib_warning ("VCL<%d>: session_enable_disable failed: %U", getpid (),
Dave Wallace543852a2017-08-03 02:11:34 -0400688 format_api_error, ntohl (mp->retval));
689 }
690 else
691 vcm->app_state = STATE_APP_ENABLED;
692}
693
694static void
695vppcom_app_send_attach (void)
696{
Dave Wallace543852a2017-08-03 02:11:34 -0400697 vl_api_application_attach_t *bmp;
Dave Wallace8af20542017-10-26 03:29:30 -0400698 u8 nsid_len = vec_len (vcm->cfg.namespace_id);
Dave Wallace774169b2017-11-01 20:07:40 -0400699 u8 app_is_proxy = (vcm->cfg.app_proxy_transport_tcp ||
700 vcm->cfg.app_proxy_transport_udp);
Dave Wallace8af20542017-10-26 03:29:30 -0400701
Dave Wallace543852a2017-08-03 02:11:34 -0400702 bmp = vl_msg_api_alloc (sizeof (*bmp));
703 memset (bmp, 0, sizeof (*bmp));
704
705 bmp->_vl_msg_id = ntohs (VL_API_APPLICATION_ATTACH);
706 bmp->client_index = vcm->my_client_index;
707 bmp->context = htonl (0xfeedface);
708 bmp->options[APP_OPTIONS_FLAGS] =
Florin Corascea194d2017-10-02 00:18:51 -0700709 APP_OPTIONS_FLAGS_ACCEPT_REDIRECT | APP_OPTIONS_FLAGS_ADD_SEGMENT |
Dave Wallace774169b2017-11-01 20:07:40 -0400710 (vcm->cfg.app_scope_local ? APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE : 0) |
711 (vcm->cfg.app_scope_global ? APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE : 0) |
712 (app_is_proxy ? APP_OPTIONS_FLAGS_IS_PROXY : 0);
713 bmp->options[APP_OPTIONS_PROXY_TRANSPORT] =
714 (vcm->cfg.app_proxy_transport_tcp ? 1 << TRANSPORT_PROTO_TCP : 0) |
715 (vcm->cfg.app_proxy_transport_udp ? 1 << TRANSPORT_PROTO_UDP : 0);
Florin Corasff6e7692017-12-11 04:59:01 -0800716 bmp->options[APP_OPTIONS_SEGMENT_SIZE] = vcm->cfg.segment_size;
717 bmp->options[APP_OPTIONS_ADD_SEGMENT_SIZE] = vcm->cfg.add_segment_size;
718 bmp->options[APP_OPTIONS_RX_FIFO_SIZE] = vcm->cfg.rx_fifo_size;
719 bmp->options[APP_OPTIONS_TX_FIFO_SIZE] = vcm->cfg.tx_fifo_size;
Florin Corasf32cff62017-12-09 08:15:00 -0800720 bmp->options[APP_OPTIONS_PREALLOC_FIFO_PAIRS] =
721 vcm->cfg.preallocated_fifo_pairs;
Florin Corasff6e7692017-12-11 04:59:01 -0800722 bmp->options[APP_OPTIONS_EVT_QUEUE_SIZE] = vcm->cfg.event_queue_size;
Dave Wallace8af20542017-10-26 03:29:30 -0400723 if (nsid_len)
724 {
725 bmp->namespace_id_len = nsid_len;
726 clib_memcpy (bmp->namespace_id, vcm->cfg.namespace_id, nsid_len);
727 bmp->options[APP_OPTIONS_NAMESPACE_SECRET] = vcm->cfg.namespace_secret;
728 }
Dave Wallace543852a2017-08-03 02:11:34 -0400729 vl_msg_api_send_shmem (vcm->vl_input_queue, (u8 *) & bmp);
730}
731
732static int
733vppcom_app_attach (void)
734{
Dave Wallace543852a2017-08-03 02:11:34 -0400735 int rv;
736
737 vppcom_app_send_attach ();
738 rv = vppcom_wait_for_app_state_change (STATE_APP_ATTACHED);
739 if (PREDICT_FALSE (rv))
740 {
741 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -0500742 clib_warning ("VCL<%d>: application attach timed out! "
743 "returning %d (%s)",
Dave Wallaceee45d412017-11-24 21:44:06 -0500744 getpid (), rv, vppcom_retval_str (rv));
Dave Wallace543852a2017-08-03 02:11:34 -0400745 return rv;
746 }
747 return VPPCOM_OK;
748}
749
750static void
751vppcom_app_detach (void)
752{
Dave Wallace543852a2017-08-03 02:11:34 -0400753 vl_api_application_detach_t *bmp;
754 bmp = vl_msg_api_alloc (sizeof (*bmp));
755 memset (bmp, 0, sizeof (*bmp));
756
757 bmp->_vl_msg_id = ntohs (VL_API_APPLICATION_DETACH);
758 bmp->client_index = vcm->my_client_index;
759 bmp->context = htonl (0xfeedface);
760 vl_msg_api_send_shmem (vcm->vl_input_queue, (u8 *) & bmp);
761}
762
763static void
764vl_api_application_attach_reply_t_handler (vl_api_application_attach_reply_t *
765 mp)
766{
Dave Wallace543852a2017-08-03 02:11:34 -0400767 static svm_fifo_segment_create_args_t _a;
768 svm_fifo_segment_create_args_t *a = &_a;
769 int rv;
770
771 memset (a, 0, sizeof (*a));
772 if (mp->retval)
773 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500774 clib_warning ("VCL<%d>: attach failed: %U", getpid (),
Dave Wallace543852a2017-08-03 02:11:34 -0400775 format_api_error, ntohl (mp->retval));
776 return;
777 }
778
779 if (mp->segment_name_length == 0)
780 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500781 clib_warning ("VCL<%d>: segment_name_length zero", getpid ());
Dave Wallace543852a2017-08-03 02:11:34 -0400782 return;
783 }
784
785 a->segment_name = (char *) mp->segment_name;
786 a->segment_size = mp->segment_size;
787
788 ASSERT (mp->app_event_queue_address);
789
790 /* Attach to the segment vpp created */
791 rv = svm_fifo_segment_attach (a);
792 vec_reset_length (a->new_segment_indices);
793 if (PREDICT_FALSE (rv))
794 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500795 clib_warning ("VCL<%d>: svm_fifo_segment_attach ('%s') failed",
796 getpid (), mp->segment_name);
Dave Wallace543852a2017-08-03 02:11:34 -0400797 return;
798 }
799
800 vcm->app_event_queue =
Florin Corase86a8ed2018-01-05 03:20:25 -0800801 uword_to_pointer (mp->app_event_queue_address, svm_queue_t *);
Dave Wallace543852a2017-08-03 02:11:34 -0400802
803 vcm->app_state = STATE_APP_ATTACHED;
804}
805
806static void
807vl_api_application_detach_reply_t_handler (vl_api_application_detach_reply_t *
808 mp)
809{
Dave Wallace543852a2017-08-03 02:11:34 -0400810 if (mp->retval)
Dave Wallace048b1d62018-01-03 22:24:41 -0500811 clib_warning ("VCL<%d>: detach failed: %U", getpid (), format_api_error,
Dave Wallace543852a2017-08-03 02:11:34 -0400812 ntohl (mp->retval));
813
814 vcm->app_state = STATE_APP_ENABLED;
815}
816
817static void
818vl_api_disconnect_session_reply_t_handler (vl_api_disconnect_session_reply_t *
819 mp)
820{
Dave Wallace543852a2017-08-03 02:11:34 -0400821 if (mp->retval)
Dave Wallace048b1d62018-01-03 22:24:41 -0500822 clib_warning ("VCL<%d>: vpp handle 0x%llx: disconnect session failed: %U",
Dave Wallace4878cbe2017-11-21 03:45:09 -0500823 getpid (), mp->handle, format_api_error,
824 ntohl (mp->retval));
Dave Wallace543852a2017-08-03 02:11:34 -0400825}
826
827static void
828vl_api_map_another_segment_t_handler (vl_api_map_another_segment_t * mp)
829{
Dave Wallace543852a2017-08-03 02:11:34 -0400830 static svm_fifo_segment_create_args_t _a;
831 svm_fifo_segment_create_args_t *a = &_a;
832 int rv;
833
834 memset (a, 0, sizeof (*a));
835 a->segment_name = (char *) mp->segment_name;
836 a->segment_size = mp->segment_size;
837 /* Attach to the segment vpp created */
838 rv = svm_fifo_segment_attach (a);
839 vec_reset_length (a->new_segment_indices);
840 if (PREDICT_FALSE (rv))
841 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500842 clib_warning ("VCL<%d>: svm_fifo_segment_attach ('%s') failed",
Dave Wallace2e005bb2017-11-07 01:21:39 -0500843 getpid (), mp->segment_name);
Dave Wallace543852a2017-08-03 02:11:34 -0400844 return;
845 }
846 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -0500847 clib_warning ("VCL<%d>: mapped new segment '%s' size %d", getpid (),
Dave Wallace543852a2017-08-03 02:11:34 -0400848 mp->segment_name, mp->segment_size);
849}
850
851static void
852vl_api_disconnect_session_t_handler (vl_api_disconnect_session_t * mp)
853{
Dave Wallace543852a2017-08-03 02:11:34 -0400854 uword *p;
Dave Wallace543852a2017-08-03 02:11:34 -0400855
856 p = hash_get (vcm->session_index_by_vpp_handles, mp->handle);
857 if (p)
858 {
Dave Wallace4878cbe2017-11-21 03:45:09 -0500859 int rv;
860 session_t *session = 0;
861 u32 session_index = p[0];
862
863 VCL_LOCK_AND_GET_SESSION (session_index, &session);
864 session->state = STATE_CLOSE_ON_EMPTY;
865
866 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -0500867 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -0500868 "setting state to 0x%x (%s)",
Dave Wallace4878cbe2017-11-21 03:45:09 -0500869 getpid (), mp->handle, session_index, session->state,
870 vppcom_session_state_str (session->state));
Dave Wallace543852a2017-08-03 02:11:34 -0400871 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace4878cbe2017-11-21 03:45:09 -0500872 return;
873
874 done:
875 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -0500876 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
Dave Wallace4878cbe2017-11-21 03:45:09 -0500877 "session lookup failed!",
878 getpid (), mp->handle, session_index);
Dave Wallace543852a2017-08-03 02:11:34 -0400879 }
880 else
Dave Wallace048b1d62018-01-03 22:24:41 -0500881 clib_warning ("VCL<%d>: vpp handle 0x%llx: session lookup by "
Dave Wallace4878cbe2017-11-21 03:45:09 -0500882 "handle failed!", getpid (), mp->handle);
Dave Wallace543852a2017-08-03 02:11:34 -0400883}
884
885static void
886vl_api_reset_session_t_handler (vl_api_reset_session_t * mp)
887{
Dave Wallace543852a2017-08-03 02:11:34 -0400888 session_t *session = 0;
889 vl_api_reset_session_reply_t *rmp;
890 uword *p;
891 int rv = 0;
892
893 p = hash_get (vcm->session_index_by_vpp_handles, mp->handle);
894 if (p)
895 {
896 int rval;
897 clib_spinlock_lock (&vcm->sessions_lockp);
898 rval = vppcom_session_at_index (p[0], &session);
899 if (PREDICT_FALSE (rval))
900 {
Dave Wallace4878cbe2017-11-21 03:45:09 -0500901 rv = VNET_API_ERROR_INVALID_VALUE_2;
Dave Wallace048b1d62018-01-03 22:24:41 -0500902 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -0500903 "session lookup failed! returning %d %U",
904 getpid (), mp->handle, p[0],
905 rv, format_api_error, rv);
Dave Wallace543852a2017-08-03 02:11:34 -0400906 }
907 else
Dave Wallace4878cbe2017-11-21 03:45:09 -0500908 {
909 /* TBD: should this disconnect immediately and
910 * flush the fifos?
911 */
912 session->state = STATE_CLOSE_ON_EMPTY;
913
914 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -0500915 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
Dave Wallace4878cbe2017-11-21 03:45:09 -0500916 "state set to %d (%s)!", getpid (),
917 mp->handle, p[0], session->state,
918 vppcom_session_state_str (session->state));
919 }
Dave Wallace543852a2017-08-03 02:11:34 -0400920 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace543852a2017-08-03 02:11:34 -0400921 }
922 else
923 {
Dave Wallace4878cbe2017-11-21 03:45:09 -0500924 rv = VNET_API_ERROR_INVALID_VALUE;
Dave Wallace048b1d62018-01-03 22:24:41 -0500925 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx: session lookup "
Dave Wallace4878cbe2017-11-21 03:45:09 -0500926 "failed! returning %d %U",
927 getpid (), mp->handle, rv, format_api_error, rv);
Dave Wallace543852a2017-08-03 02:11:34 -0400928 }
929
930 rmp = vl_msg_api_alloc (sizeof (*rmp));
931 memset (rmp, 0, sizeof (*rmp));
932 rmp->_vl_msg_id = ntohs (VL_API_RESET_SESSION_REPLY);
933 rmp->retval = htonl (rv);
934 rmp->handle = mp->handle;
935 vl_msg_api_send_shmem (vcm->vl_input_queue, (u8 *) & rmp);
936}
937
938static void
Dave Wallace33e002b2017-09-06 01:20:02 -0400939vl_api_connect_session_reply_t_handler (vl_api_connect_session_reply_t * mp)
Dave Wallace543852a2017-08-03 02:11:34 -0400940{
Dave Wallaceee45d412017-11-24 21:44:06 -0500941 session_t *session = 0;
Dave Wallace543852a2017-08-03 02:11:34 -0400942 u32 session_index;
943 svm_fifo_t *rx_fifo, *tx_fifo;
944 u8 is_cut_thru = 0;
945 int rv;
946
Dave Wallace4878cbe2017-11-21 03:45:09 -0500947 session_index = mp->context;
Dave Wallaceee45d412017-11-24 21:44:06 -0500948 VCL_LOCK_AND_GET_SESSION (session_index, &session);
949done:
Dave Wallace543852a2017-08-03 02:11:34 -0400950 if (mp->retval)
951 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500952 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -0500953 "connect failed! %U",
954 getpid (), mp->handle, session_index,
955 format_api_error, ntohl (mp->retval));
956 if (rv == VPPCOM_OK)
957 {
958 session->state = STATE_FAILED;
959 session->vpp_handle = mp->handle;
960 }
961 else
962 {
963 clib_warning ("[%s] ERROR: vpp handle 0x%llx, sid %u: "
964 "Invalid session index (%u)!",
965 getpid (), mp->handle, session_index);
966 }
967 goto done_unlock;
Dave Wallace543852a2017-08-03 02:11:34 -0400968 }
969
Dave Wallaceee45d412017-11-24 21:44:06 -0500970 if (rv)
971 goto done_unlock;
Dave Wallace543852a2017-08-03 02:11:34 -0400972
973 /* We've been redirected */
974 if (mp->segment_name_length > 0)
975 {
976 static svm_fifo_segment_create_args_t _a;
977 svm_fifo_segment_create_args_t *a = &_a;
978
979 is_cut_thru = 1;
980 memset (a, 0, sizeof (*a));
981 a->segment_name = (char *) mp->segment_name;
982 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -0500983 clib_warning ("VCL<%d>: cut-thru segment: %s\n",
Dave Wallace60caa062017-11-10 17:07:13 -0500984 getpid (), a->segment_name);
985
Dave Wallace543852a2017-08-03 02:11:34 -0400986 rv = svm_fifo_segment_attach (a);
987 vec_reset_length (a->new_segment_indices);
988 if (PREDICT_FALSE (rv))
989 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500990 clib_warning ("VCL<%d>: sm_fifo_segment_attach ('%s') failed",
Dave Wallace2e005bb2017-11-07 01:21:39 -0500991 getpid (), a->segment_name);
Dave Wallaceee45d412017-11-24 21:44:06 -0500992 goto done_unlock;
Dave Wallace543852a2017-08-03 02:11:34 -0400993 }
994 }
995
996 /*
997 * Setup session
998 */
Dave Wallace543852a2017-08-03 02:11:34 -0400999 session->is_cut_thru = is_cut_thru;
Dave Wallace33e002b2017-09-06 01:20:02 -04001000 session->vpp_event_queue = uword_to_pointer (mp->vpp_event_queue_address,
Florin Corase86a8ed2018-01-05 03:20:25 -08001001 svm_queue_t *);
Dave Wallace543852a2017-08-03 02:11:34 -04001002
1003 rx_fifo = uword_to_pointer (mp->server_rx_fifo, svm_fifo_t *);
1004 rx_fifo->client_session_index = session_index;
1005 tx_fifo = uword_to_pointer (mp->server_tx_fifo, svm_fifo_t *);
1006 tx_fifo->client_session_index = session_index;
1007
1008 session->server_rx_fifo = rx_fifo;
1009 session->server_tx_fifo = tx_fifo;
Dave Wallace60caa062017-11-10 17:07:13 -05001010 session->vpp_handle = mp->handle;
Dave Wallace9d1d73a2017-11-20 02:31:48 -05001011 session->lcl_addr.is_ip4 = mp->is_ip4;
1012 clib_memcpy (&session->lcl_addr.ip46, mp->lcl_ip,
1013 sizeof (session->peer_addr.ip46));
1014 session->lcl_port = mp->lcl_port;
Dave Wallace543852a2017-08-03 02:11:34 -04001015 session->state = STATE_CONNECT;
1016
1017 /* Add it to lookup table */
1018 hash_set (vcm->session_index_by_vpp_handles, mp->handle, session_index);
Dave Wallace60caa062017-11-10 17:07:13 -05001019
1020 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05001021 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: connect succeeded!"
Dave Wallaceee45d412017-11-24 21:44:06 -05001022 " session_rx_fifo %p, refcnt %d,"
1023 " session_tx_fifo %p, refcnt %d",
1024 getpid (), mp->handle, session_index,
Dave Wallace60caa062017-11-10 17:07:13 -05001025 session->server_rx_fifo,
1026 session->server_rx_fifo->refcnt,
1027 session->server_tx_fifo, session->server_tx_fifo->refcnt);
Dave Wallaceee45d412017-11-24 21:44:06 -05001028done_unlock:
Dave Wallace543852a2017-08-03 02:11:34 -04001029 clib_spinlock_unlock (&vcm->sessions_lockp);
1030}
1031
1032static void
1033vppcom_send_connect_sock (session_t * session, u32 session_index)
1034{
Dave Wallace543852a2017-08-03 02:11:34 -04001035 vl_api_connect_sock_t *cmp;
1036
1037 /* Assumes caller as acquired the spinlock: vcm->sessions_lockp */
1038 session->is_server = 0;
1039 cmp = vl_msg_api_alloc (sizeof (*cmp));
1040 memset (cmp, 0, sizeof (*cmp));
1041 cmp->_vl_msg_id = ntohs (VL_API_CONNECT_SOCK);
1042 cmp->client_index = vcm->my_client_index;
Dave Wallace33e002b2017-09-06 01:20:02 -04001043 cmp->context = session_index;
Dave Wallace543852a2017-08-03 02:11:34 -04001044
Dave Wallace35830af2017-10-09 01:43:42 -04001045 cmp->is_ip4 = session->peer_addr.is_ip4;
1046 clib_memcpy (cmp->ip, &session->peer_addr.ip46, sizeof (cmp->ip));
Stevenac1f96d2017-10-24 16:03:58 -07001047 cmp->port = session->peer_port;
Dave Wallace543852a2017-08-03 02:11:34 -04001048 cmp->proto = session->proto;
1049 clib_memcpy (cmp->options, session->options, sizeof (cmp->options));
1050 vl_msg_api_send_shmem (vcm->vl_input_queue, (u8 *) & cmp);
1051}
1052
Dave Wallace66cf6eb2017-10-26 02:51:07 -04001053static inline void
Dave Wallace4878cbe2017-11-21 03:45:09 -05001054vppcom_send_disconnect_session_reply (u64 vpp_handle, u32 session_index,
1055 int rv)
1056{
1057 vl_api_disconnect_session_reply_t *rmp;
1058
1059 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05001060 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
1061 "sending disconnect msg",
Dave Wallace4878cbe2017-11-21 03:45:09 -05001062 getpid (), vpp_handle, session_index);
1063
1064 rmp = vl_msg_api_alloc (sizeof (*rmp));
1065 memset (rmp, 0, sizeof (*rmp));
1066
1067 rmp->_vl_msg_id = ntohs (VL_API_DISCONNECT_SESSION_REPLY);
1068 rmp->retval = htonl (rv);
1069 rmp->handle = vpp_handle;
1070 vl_msg_api_send_shmem (vcm->vl_input_queue, (u8 *) & rmp);
1071}
1072
1073static inline void
1074vppcom_send_disconnect_session (u64 vpp_handle, u32 session_index)
Dave Wallace543852a2017-08-03 02:11:34 -04001075{
Dave Wallace543852a2017-08-03 02:11:34 -04001076 vl_api_disconnect_session_t *dmp;
Dave Wallace543852a2017-08-03 02:11:34 -04001077
Dave Wallace4878cbe2017-11-21 03:45:09 -05001078 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05001079 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
1080 "sending disconnect msg",
Dave Wallace4878cbe2017-11-21 03:45:09 -05001081 getpid (), vpp_handle, session_index);
1082
Dave Wallace543852a2017-08-03 02:11:34 -04001083 dmp = vl_msg_api_alloc (sizeof (*dmp));
1084 memset (dmp, 0, sizeof (*dmp));
1085 dmp->_vl_msg_id = ntohs (VL_API_DISCONNECT_SESSION);
1086 dmp->client_index = vcm->my_client_index;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001087 dmp->handle = vpp_handle;
Dave Wallace543852a2017-08-03 02:11:34 -04001088 vl_msg_api_send_shmem (vcm->vl_input_queue, (u8 *) & dmp);
Dave Wallace543852a2017-08-03 02:11:34 -04001089}
1090
1091static void
1092vl_api_bind_sock_reply_t_handler (vl_api_bind_sock_reply_t * mp)
1093{
Dave Wallace543852a2017-08-03 02:11:34 -04001094 session_t *session = 0;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001095 u32 session_index = mp->context;
Dave Wallace543852a2017-08-03 02:11:34 -04001096 int rv;
1097
Dave Wallaceee45d412017-11-24 21:44:06 -05001098 VCL_LOCK_AND_GET_SESSION (session_index, &session);
1099done:
Dave Wallace543852a2017-08-03 02:11:34 -04001100 if (mp->retval)
Dave Wallace4878cbe2017-11-21 03:45:09 -05001101 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001102 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, "
1103 "sid %u: bind failed: %U",
1104 getpid (), mp->handle, session_index,
1105 format_api_error, ntohl (mp->retval));
Dave Wallace4878cbe2017-11-21 03:45:09 -05001106 rv = vppcom_session_at_index (session_index, &session);
1107 if (rv == VPPCOM_OK)
Dave Wallaceee45d412017-11-24 21:44:06 -05001108 {
1109 session->state = STATE_FAILED;
1110 session->vpp_handle = mp->handle;
1111 }
1112 else
1113 {
1114 clib_warning ("[%s] ERROR: vpp handle 0x%llx, sid %u: "
1115 "Invalid session index (%u)!",
1116 getpid (), mp->handle, session_index);
1117 }
1118 goto done_unlock;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001119 }
Dave Wallace543852a2017-08-03 02:11:34 -04001120
Dave Wallaceee45d412017-11-24 21:44:06 -05001121 session->vpp_handle = mp->handle;
1122 session->lcl_addr.is_ip4 = mp->lcl_is_ip4;
1123 clib_memcpy (&session->lcl_addr.ip46, mp->lcl_ip,
1124 sizeof (session->peer_addr.ip46));
1125 session->lcl_port = mp->lcl_port;
1126 vppcom_session_table_add_listener (mp->handle, session_index);
1127 session->is_listen = 1;
1128 session->state = STATE_LISTEN;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001129
Dave Wallaceee45d412017-11-24 21:44:06 -05001130 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05001131 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: bind succeeded!",
Dave Wallaceee45d412017-11-24 21:44:06 -05001132 getpid (), mp->handle, mp->context);
1133done_unlock:
Dave Wallace543852a2017-08-03 02:11:34 -04001134 clib_spinlock_unlock (&vcm->sessions_lockp);
1135}
1136
1137static void
1138vl_api_unbind_sock_reply_t_handler (vl_api_unbind_sock_reply_t * mp)
1139{
Dave Wallace4878cbe2017-11-21 03:45:09 -05001140 if (mp->retval)
Dave Wallace048b1d62018-01-03 22:24:41 -05001141 clib_warning ("VCL<%d>: ERROR: sid %u: unbind failed: %U",
Dave Wallace4878cbe2017-11-21 03:45:09 -05001142 getpid (), mp->context, format_api_error,
1143 ntohl (mp->retval));
Dave Wallace543852a2017-08-03 02:11:34 -04001144
Dave Wallace4878cbe2017-11-21 03:45:09 -05001145 else if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05001146 clib_warning ("VCL<%d>: sid %u: unbind succeeded!",
1147 getpid (), mp->context);
Dave Wallace543852a2017-08-03 02:11:34 -04001148}
1149
1150u8 *
1151format_ip4_address (u8 * s, va_list * args)
1152{
1153 u8 *a = va_arg (*args, u8 *);
1154 return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
1155}
1156
1157u8 *
1158format_ip6_address (u8 * s, va_list * args)
1159{
1160 ip6_address_t *a = va_arg (*args, ip6_address_t *);
1161 u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
1162
1163 i_max_n_zero = ARRAY_LEN (a->as_u16);
1164 max_n_zeros = 0;
1165 i_first_zero = i_max_n_zero;
1166 n_zeros = 0;
1167 for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
1168 {
1169 u32 is_zero = a->as_u16[i] == 0;
1170 if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
1171 {
1172 i_first_zero = i;
1173 n_zeros = 0;
1174 }
1175 n_zeros += is_zero;
1176 if ((!is_zero && n_zeros > max_n_zeros)
1177 || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
1178 {
1179 i_max_n_zero = i_first_zero;
1180 max_n_zeros = n_zeros;
1181 i_first_zero = ARRAY_LEN (a->as_u16);
1182 n_zeros = 0;
1183 }
1184 }
1185
1186 last_double_colon = 0;
1187 for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
1188 {
1189 if (i == i_max_n_zero && max_n_zeros > 1)
1190 {
1191 s = format (s, "::");
1192 i += max_n_zeros - 1;
1193 last_double_colon = 1;
1194 }
1195 else
1196 {
1197 s = format (s, "%s%x",
1198 (last_double_colon || i == 0) ? "" : ":",
1199 clib_net_to_host_u16 (a->as_u16[i]));
1200 last_double_colon = 0;
1201 }
1202 }
1203
1204 return s;
1205}
1206
1207/* Format an IP46 address. */
1208u8 *
1209format_ip46_address (u8 * s, va_list * args)
1210{
1211 ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
1212 ip46_type_t type = va_arg (*args, ip46_type_t);
1213 int is_ip4 = 1;
1214
1215 switch (type)
1216 {
1217 case IP46_TYPE_ANY:
1218 is_ip4 = ip46_address_is_ip4 (ip46);
1219 break;
1220 case IP46_TYPE_IP4:
1221 is_ip4 = 1;
1222 break;
1223 case IP46_TYPE_IP6:
1224 is_ip4 = 0;
1225 break;
1226 }
1227
1228 return is_ip4 ?
1229 format (s, "%U", format_ip4_address, &ip46->ip4) :
1230 format (s, "%U", format_ip6_address, &ip46->ip6);
1231}
1232
Dave Wallace60caa062017-11-10 17:07:13 -05001233static inline void
Florin Coras50e8bdb2017-11-27 10:37:05 -08001234vppcom_send_accept_session_reply (u64 handle, u32 context, int retval)
Dave Wallace60caa062017-11-10 17:07:13 -05001235{
1236 vl_api_accept_session_reply_t *rmp;
1237
1238 rmp = vl_msg_api_alloc (sizeof (*rmp));
1239 memset (rmp, 0, sizeof (*rmp));
1240 rmp->_vl_msg_id = ntohs (VL_API_ACCEPT_SESSION_REPLY);
1241 rmp->retval = htonl (retval);
Dave Wallaced2931962017-11-25 04:17:39 -05001242 rmp->context = context;
Dave Wallace60caa062017-11-10 17:07:13 -05001243 rmp->handle = handle;
1244 vl_msg_api_send_shmem (vcm->vl_input_queue, (u8 *) & rmp);
1245}
1246
Dave Wallace543852a2017-08-03 02:11:34 -04001247static void
1248vl_api_accept_session_t_handler (vl_api_accept_session_t * mp)
1249{
Dave Wallace543852a2017-08-03 02:11:34 -04001250 svm_fifo_t *rx_fifo, *tx_fifo;
Florin Corasdcf55ce2017-11-16 15:32:50 -08001251 session_t *session, *listen_session;
Dave Wallace543852a2017-08-03 02:11:34 -04001252 u32 session_index;
Dave Wallace543852a2017-08-03 02:11:34 -04001253
Dave Wallace60caa062017-11-10 17:07:13 -05001254 clib_spinlock_lock (&vcm->sessions_lockp);
Dave Wallace543852a2017-08-03 02:11:34 -04001255 if (!clib_fifo_free_elts (vcm->client_session_index_fifo))
1256 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001257 clib_warning ("VCL<%d>: client session queue is full!", getpid ());
Dave Wallaced2931962017-11-25 04:17:39 -05001258 vppcom_send_accept_session_reply (mp->handle, mp->context,
Florin Corasdcf55ce2017-11-16 15:32:50 -08001259 VNET_API_ERROR_QUEUE_FULL);
1260 clib_spinlock_unlock (&vcm->sessions_lockp);
1261 return;
1262 }
1263
1264 listen_session = vppcom_session_table_lookup_listener (mp->listener_handle);
1265 if (!listen_session)
1266 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001267 clib_warning ("VCL<%d>: ERROR: couldn't find listen session: "
1268 "unknown vpp listener handle %llx",
1269 getpid (), mp->listener_handle);
Dave Wallace60caa062017-11-10 17:07:13 -05001270 clib_spinlock_unlock (&vcm->sessions_lockp);
1271 return;
Dave Wallace543852a2017-08-03 02:11:34 -04001272 }
1273
Dave Wallace543852a2017-08-03 02:11:34 -04001274 /* Allocate local session and set it up */
1275 pool_get (vcm->sessions, session);
1276 memset (session, 0, sizeof (*session));
1277 session_index = session - vcm->sessions;
1278
1279 rx_fifo = uword_to_pointer (mp->server_rx_fifo, svm_fifo_t *);
1280 rx_fifo->client_session_index = session_index;
1281 tx_fifo = uword_to_pointer (mp->server_tx_fifo, svm_fifo_t *);
1282 tx_fifo->client_session_index = session_index;
1283
Dave Wallace60caa062017-11-10 17:07:13 -05001284 session->vpp_handle = mp->handle;
Dave Wallaced2931962017-11-25 04:17:39 -05001285 session->client_context = mp->context;
Dave Wallace543852a2017-08-03 02:11:34 -04001286 session->server_rx_fifo = rx_fifo;
1287 session->server_tx_fifo = tx_fifo;
Dave Wallace33e002b2017-09-06 01:20:02 -04001288 session->vpp_event_queue = uword_to_pointer (mp->vpp_event_queue_address,
Florin Corase86a8ed2018-01-05 03:20:25 -08001289 svm_queue_t *);
Dave Wallace543852a2017-08-03 02:11:34 -04001290 session->state = STATE_ACCEPT;
1291 session->is_cut_thru = 0;
Dave Wallace19481612017-09-15 18:47:44 -04001292 session->is_server = 1;
Stevenac1f96d2017-10-24 16:03:58 -07001293 session->peer_port = mp->port;
Dave Wallace35830af2017-10-09 01:43:42 -04001294 session->peer_addr.is_ip4 = mp->is_ip4;
1295 clib_memcpy (&session->peer_addr.ip46, mp->ip,
1296 sizeof (session->peer_addr.ip46));
Dave Wallace543852a2017-08-03 02:11:34 -04001297
1298 /* Add it to lookup table */
1299 hash_set (vcm->session_index_by_vpp_handles, mp->handle, session_index);
Florin Corasdcf55ce2017-11-16 15:32:50 -08001300 session->lcl_port = listen_session->lcl_port;
1301 session->lcl_addr = listen_session->lcl_addr;
Dave Wallace227867f2017-11-13 21:21:53 -05001302
1303 /* TBD: move client_session_index_fifo into listener session */
Dave Wallace543852a2017-08-03 02:11:34 -04001304 clib_fifo_add1 (vcm->client_session_index_fifo, session_index);
Florin Corasdcf55ce2017-11-16 15:32:50 -08001305
Dave Wallacef7f809c2017-10-03 01:48:42 -04001306 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace543852a2017-08-03 02:11:34 -04001307
Dave Wallace60caa062017-11-10 17:07:13 -05001308 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05001309 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: client accept "
Florin Coras50e8bdb2017-11-27 10:37:05 -08001310 "request from %s address %U port %d queue %p!", getpid (),
Dave Wallaced2931962017-11-25 04:17:39 -05001311 mp->handle, session_index, mp->is_ip4 ? "IPv4" : "IPv6",
1312 format_ip46_address, &mp->ip, mp->is_ip4,
Florin Coras50e8bdb2017-11-27 10:37:05 -08001313 clib_net_to_host_u16 (mp->port), session->vpp_event_queue);
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08001314
1315 if (VPPCOM_DEBUG > 0)
1316 {
1317 session->elog_track.name =
1318 (char *) format (0, "C:%d:S:%d%c", vcm->my_client_index,
1319 session_index, 0);
1320 elog_track_register (&vcm->elog_main, &session->elog_track);
1321
1322 if (session->peer_addr.is_ip4)
1323 {
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08001324 /* *INDENT-OFF* */
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08001325 ELOG_TYPE_DECLARE (e) =
1326 {
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08001327 .format =
1328 "client_accept:handle:%x addr:%d.%d.%d.%d:%d",
1329 .format_args = "i8i1i1i1i1i2",
1330 };
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08001331
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08001332 CLIB_PACKED (struct {
1333 u64 handle; //8
1334 u8 addr[4]; //4
1335 u16 port; //2
1336 }) * ed;
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08001337
1338 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
1339
1340 ed->handle = mp->handle;
1341 ed->addr[0] = session->peer_addr.ip46.ip4.as_u8[0];
1342 ed->addr[1] = session->peer_addr.ip46.ip4.as_u8[1];
1343 ed->addr[2] = session->peer_addr.ip46.ip4.as_u8[2];
1344 ed->addr[3] = session->peer_addr.ip46.ip4.as_u8[3];
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08001345 ed->port = clib_net_to_host_u16 (session->peer_port);
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08001346 /* *INDENT-ON* */
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08001347 }
1348 else
1349 {
1350 clib_warning ("ip6");
1351 }
1352 }
1353
Dave Wallace60caa062017-11-10 17:07:13 -05001354}
1355
1356static void
Dave Wallaceee45d412017-11-24 21:44:06 -05001357vppcom_send_connect_session_reply (session_t * session, u32 session_index,
Dave Wallaced2931962017-11-25 04:17:39 -05001358 u64 vpp_handle, u32 context, int retval)
Dave Wallace60caa062017-11-10 17:07:13 -05001359{
1360 vl_api_connect_session_reply_t *rmp;
1361 u32 len;
Florin Corase86a8ed2018-01-05 03:20:25 -08001362 svm_queue_t *client_q;
Dave Wallace60caa062017-11-10 17:07:13 -05001363
Dave Wallace543852a2017-08-03 02:11:34 -04001364 rmp = vl_msg_api_alloc (sizeof (*rmp));
1365 memset (rmp, 0, sizeof (*rmp));
Dave Wallace60caa062017-11-10 17:07:13 -05001366 rmp->_vl_msg_id = ntohs (VL_API_CONNECT_SESSION_REPLY);
Dave Wallaced2931962017-11-25 04:17:39 -05001367
1368 if (!session)
1369 {
1370 rmp->context = context;
1371 rmp->handle = vpp_handle;
1372 rmp->retval = htonl (retval);
1373 vl_msg_api_send_shmem (vcm->vl_input_queue, (u8 *) & rmp);
1374 return;
1375 }
1376
Dave Wallace227867f2017-11-13 21:21:53 -05001377 rmp->context = session->client_context;
Dave Wallace60caa062017-11-10 17:07:13 -05001378 rmp->retval = htonl (retval);
Dave Wallace227867f2017-11-13 21:21:53 -05001379 rmp->handle = session->vpp_handle;
1380 rmp->server_rx_fifo = pointer_to_uword (session->server_rx_fifo);
1381 rmp->server_tx_fifo = pointer_to_uword (session->server_tx_fifo);
1382 rmp->vpp_event_queue_address = pointer_to_uword (session->vpp_event_queue);
1383 rmp->segment_size = vcm->cfg.segment_size;
1384 len = vec_len (session->segment_name);
1385 rmp->segment_name_length = clib_min (len, sizeof (rmp->segment_name));
1386 clib_memcpy (rmp->segment_name, session->segment_name,
1387 rmp->segment_name_length - 1);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001388 clib_memcpy (rmp->lcl_ip, session->peer_addr.ip46.as_u8,
Dave Wallace227867f2017-11-13 21:21:53 -05001389 sizeof (rmp->lcl_ip));
Dave Wallace4878cbe2017-11-21 03:45:09 -05001390 rmp->is_ip4 = session->peer_addr.is_ip4;
1391 rmp->lcl_port = session->peer_port;
Florin Corase86a8ed2018-01-05 03:20:25 -08001392 client_q = uword_to_pointer (session->client_queue_address, svm_queue_t *);
Dave Wallace60caa062017-11-10 17:07:13 -05001393 ASSERT (client_q);
1394 vl_msg_api_send_shmem (client_q, (u8 *) & rmp);
Dave Wallace543852a2017-08-03 02:11:34 -04001395}
1396
1397/*
1398 * Acting as server for redirected connect requests
1399 */
1400static void
1401vl_api_connect_sock_t_handler (vl_api_connect_sock_t * mp)
1402{
Dave Wallace543852a2017-08-03 02:11:34 -04001403 u32 session_index;
Dave Wallace543852a2017-08-03 02:11:34 -04001404 session_t *session = 0;
Dave Wallace543852a2017-08-03 02:11:34 -04001405
Dave Wallacef7f809c2017-10-03 01:48:42 -04001406 clib_spinlock_lock (&vcm->sessions_lockp);
Dave Wallace543852a2017-08-03 02:11:34 -04001407 if (!clib_fifo_free_elts (vcm->client_session_index_fifo))
1408 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05001409 clib_spinlock_unlock (&vcm->sessions_lockp);
1410
Dave Wallace543852a2017-08-03 02:11:34 -04001411 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05001412 clib_warning ("VCL<%d>: client session queue is full!", getpid ());
Dave Wallace4878cbe2017-11-21 03:45:09 -05001413
Dave Wallaced2931962017-11-25 04:17:39 -05001414 /* TBD: Fix api to include vpp handle */
1415 vppcom_send_connect_session_reply (0 /* session */ , 0 /* sid */ ,
1416 0 /* handle */ , mp->context,
1417 VNET_API_ERROR_QUEUE_FULL);
Dave Wallace60caa062017-11-10 17:07:13 -05001418 return;
Dave Wallace543852a2017-08-03 02:11:34 -04001419 }
1420
Dave Wallace543852a2017-08-03 02:11:34 -04001421 pool_get (vcm->sessions, session);
1422 memset (session, 0, sizeof (*session));
1423 session_index = session - vcm->sessions;
1424
Dave Wallace60caa062017-11-10 17:07:13 -05001425 session->client_context = mp->context;
1426 session->vpp_handle = session_index;
Dave Wallace543852a2017-08-03 02:11:34 -04001427 session->client_queue_address = mp->client_queue_address;
1428 session->is_cut_thru = 1;
1429 session->is_server = 1;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001430 session->lcl_port = mp->port;
1431 session->lcl_addr.is_ip4 = mp->is_ip4;
1432 clib_memcpy (&session->lcl_addr.ip46, mp->ip,
1433 sizeof (session->lcl_addr.ip46));
1434
1435 /* TBD: missing peer info in api msg.
1436 */
Dave Wallace35830af2017-10-09 01:43:42 -04001437 session->peer_addr.is_ip4 = mp->is_ip4;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001438 ASSERT (session->lcl_addr.is_ip4 == session->peer_addr.is_ip4);
Dave Wallace6d5c4cd2017-08-15 16:56:29 -04001439
Dave Wallace543852a2017-08-03 02:11:34 -04001440 session->state = STATE_ACCEPT;
Dave Wallace543852a2017-08-03 02:11:34 -04001441 clib_fifo_add1 (vcm->client_session_index_fifo, session_index);
Dave Wallace2e005bb2017-11-07 01:21:39 -05001442 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05001443 clib_warning ("VCL<%d>: sid %u: Got a cut-thru connect request! "
Dave Wallace4878cbe2017-11-21 03:45:09 -05001444 "clib_fifo_elts %u!\n", getpid (), session_index,
1445 clib_fifo_elts (vcm->client_session_index_fifo));
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08001446
1447 if (VPPCOM_DEBUG > 0)
1448 {
1449 session->elog_track.name =
1450 (char *) format (0, "C:%d:S:%d%c", vcm->my_client_index,
1451 session_index, 0);
1452 elog_track_register (&vcm->elog_main, &session->elog_track);
1453
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08001454 /* *INDENT-OFF* */
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08001455 ELOG_TYPE_DECLARE (e) =
1456 {
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08001457 .format = "cut-thru-connect:S:%d clib_fifo_elts:%d",
1458 .format_args = "i4i4",
1459 };
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08001460
1461 struct
1462 {
1463 u32 data[2];
1464 } *ed;
1465
1466 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
1467
1468 ed->data[0] = session_index;
1469 ed->data[1] = clib_fifo_elts (vcm->client_session_index_fifo);
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08001470 /* *INDENT-ON* */
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08001471 }
1472
Dave Wallacef7f809c2017-10-03 01:48:42 -04001473 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace543852a2017-08-03 02:11:34 -04001474}
1475
1476static void
Dave Wallace4878cbe2017-11-21 03:45:09 -05001477vppcom_send_bind_sock (session_t * session, u32 session_index)
Dave Wallace543852a2017-08-03 02:11:34 -04001478{
Dave Wallace543852a2017-08-03 02:11:34 -04001479 vl_api_bind_sock_t *bmp;
1480
1481 /* Assumes caller has acquired spinlock: vcm->sessions_lockp */
1482 session->is_server = 1;
1483 bmp = vl_msg_api_alloc (sizeof (*bmp));
1484 memset (bmp, 0, sizeof (*bmp));
1485
1486 bmp->_vl_msg_id = ntohs (VL_API_BIND_SOCK);
1487 bmp->client_index = vcm->my_client_index;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001488 bmp->context = session_index;
Dave Wallace35830af2017-10-09 01:43:42 -04001489 bmp->is_ip4 = session->lcl_addr.is_ip4;
1490 clib_memcpy (bmp->ip, &session->lcl_addr.ip46, sizeof (bmp->ip));
Stevenac1f96d2017-10-24 16:03:58 -07001491 bmp->port = session->lcl_port;
Dave Wallace543852a2017-08-03 02:11:34 -04001492 bmp->proto = session->proto;
1493 clib_memcpy (bmp->options, session->options, sizeof (bmp->options));
1494 vl_msg_api_send_shmem (vcm->vl_input_queue, (u8 *) & bmp);
1495}
1496
1497static void
Dave Wallace4878cbe2017-11-21 03:45:09 -05001498vppcom_send_unbind_sock (u64 vpp_handle)
Dave Wallace543852a2017-08-03 02:11:34 -04001499{
Dave Wallace543852a2017-08-03 02:11:34 -04001500 vl_api_unbind_sock_t *ump;
Dave Wallace543852a2017-08-03 02:11:34 -04001501
1502 ump = vl_msg_api_alloc (sizeof (*ump));
1503 memset (ump, 0, sizeof (*ump));
1504
1505 ump->_vl_msg_id = ntohs (VL_API_UNBIND_SOCK);
1506 ump->client_index = vcm->my_client_index;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001507 ump->handle = vpp_handle;
Dave Wallace543852a2017-08-03 02:11:34 -04001508 vl_msg_api_send_shmem (vcm->vl_input_queue, (u8 *) & ump);
1509}
1510
1511static int
Dave Wallace543852a2017-08-03 02:11:34 -04001512vppcom_session_unbind (u32 session_index)
1513{
Dave Wallace4878cbe2017-11-21 03:45:09 -05001514 session_t *session = 0;
Dave Wallace543852a2017-08-03 02:11:34 -04001515 int rv;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001516 u64 vpp_handle;
Dave Wallace543852a2017-08-03 02:11:34 -04001517
Dave Wallace4878cbe2017-11-21 03:45:09 -05001518 VCL_LOCK_AND_GET_SESSION (session_index, &session);
1519
1520 vpp_handle = session->vpp_handle;
1521 vppcom_session_table_del_listener (vpp_handle);
1522 session->vpp_handle = ~0;
1523 session->state = STATE_DISCONNECT;
1524
Dave Wallace543852a2017-08-03 02:11:34 -04001525 clib_spinlock_unlock (&vcm->sessions_lockp);
1526
Dave Wallace4878cbe2017-11-21 03:45:09 -05001527 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05001528 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
Dave Wallace4878cbe2017-11-21 03:45:09 -05001529 "sending unbind msg! new state 0x%x (%s)",
1530 getpid (), vpp_handle, session_index,
1531 session->state, vppcom_session_state_str (session->state));
1532
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08001533 if (VPPCOM_DEBUG > 0)
1534 {
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08001535 /* *INDENT-OFF* */
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08001536 ELOG_TYPE_DECLARE (e) =
1537 {
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08001538 .format = "unbind: handle:%x",
1539 .format_args = "i8",
1540 };
1541
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08001542 struct
1543 {
1544 u64 handle;
1545 } *ed;
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08001546
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08001547 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
1548 ed->handle = vpp_handle;
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08001549 /* *INDENT-ON* */
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08001550 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05001551 vppcom_send_unbind_sock (vpp_handle);
1552
1553done:
1554 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04001555}
1556
Dave Wallace66cf6eb2017-10-26 02:51:07 -04001557static inline int
Dave Wallace543852a2017-08-03 02:11:34 -04001558vppcom_session_disconnect (u32 session_index)
1559{
Dave Wallace543852a2017-08-03 02:11:34 -04001560 int rv;
Dave Wallace66cf6eb2017-10-26 02:51:07 -04001561 session_t *session;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001562 u8 is_cut_thru, is_listen, is_server;
1563 u64 vpp_handle;
1564 session_state_t state;
Dave Wallace543852a2017-08-03 02:11:34 -04001565
Dave Wallace4878cbe2017-11-21 03:45:09 -05001566 VCL_LOCK_AND_GET_SESSION (session_index, &session);
1567
1568 vpp_handle = session->vpp_handle;
1569 is_server = session->is_server;
1570 is_listen = session->is_listen;
1571 is_cut_thru = session->is_cut_thru;
1572 state = session->state;
1573 clib_spinlock_unlock (&vcm->sessions_lockp);
1574
1575 if (VPPCOM_DEBUG > 1)
Dave Wallace543852a2017-08-03 02:11:34 -04001576 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001577 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: %s "
1578 "state 0x%x (%s), is_cut_thru %d, is_listen %d",
Dave Wallace4878cbe2017-11-21 03:45:09 -05001579 getpid (), vpp_handle, session_index,
1580 is_server ? "server" : "client",
1581 state, vppcom_session_state_str (state),
1582 is_cut_thru, is_listen);
Dave Wallace543852a2017-08-03 02:11:34 -04001583 }
Dave Wallace66cf6eb2017-10-26 02:51:07 -04001584
Dave Wallace4878cbe2017-11-21 03:45:09 -05001585 if (PREDICT_FALSE (is_listen))
Dave Wallace66cf6eb2017-10-26 02:51:07 -04001586 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001587 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -05001588 "Cannot disconnect a listen socket!",
1589 getpid (), vpp_handle, session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001590 rv = VPPCOM_EBADFD;
1591 goto done;
1592 }
Dave Wallace66cf6eb2017-10-26 02:51:07 -04001593
Dave Wallace4878cbe2017-11-21 03:45:09 -05001594 /* Through the VPP host stack...
1595 */
1596 else if (!is_cut_thru)
1597 {
1598 /* The peer has already initiated the close,
1599 * so send the disconnect session reply.
Dave Wallace227867f2017-11-13 21:21:53 -05001600 */
Dave Wallace4878cbe2017-11-21 03:45:09 -05001601 if (state & STATE_CLOSE_ON_EMPTY)
1602 {
1603 vppcom_send_disconnect_session_reply (vpp_handle,
1604 session_index, 0 /* rv */ );
1605 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05001606 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -05001607 "sending disconnect REPLY...",
1608 getpid (), vpp_handle, session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001609 }
1610
1611 /* Otherwise, send a disconnect session msg...
1612 */
1613 else
1614 {
1615 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05001616 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -05001617 "sending disconnect...",
1618 getpid (), vpp_handle, session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001619
1620 vppcom_send_disconnect_session (vpp_handle, session_index);
1621 }
Dave Wallace66cf6eb2017-10-26 02:51:07 -04001622 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05001623
1624 /* Cut-thru connections...
1625 *
1626 * server: free fifos and segment allocated during connect/redirect
1627 * client: no cleanup required
1628 */
Dave Wallace66cf6eb2017-10-26 02:51:07 -04001629 else
Dave Wallace227867f2017-11-13 21:21:53 -05001630 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05001631 if (is_server)
1632 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05001633 svm_fifo_segment_private_t *seg;
1634
1635 VCL_LOCK_AND_GET_SESSION (session_index, &session);
1636
1637 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05001638 clib_warning ("VCL<%d>: sid %d: freeing cut-thru fifos in "
Dave Wallaceee45d412017-11-24 21:44:06 -05001639 "sm_seg_index %d! "
1640 " server_rx_fifo %p, refcnt = %d"
1641 " server_tx_fifo %p, refcnt = %d",
Dave Wallace4878cbe2017-11-21 03:45:09 -05001642 getpid (), session_index, session->sm_seg_index,
1643 session->server_rx_fifo,
1644 session->server_rx_fifo->refcnt,
1645 session->server_tx_fifo,
1646 session->server_tx_fifo->refcnt);
1647
Florin Corasb384b542018-01-15 01:08:33 -08001648 seg = svm_fifo_segment_get_segment (session->sm_seg_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001649 svm_fifo_segment_free_fifo (seg, session->server_rx_fifo,
1650 FIFO_SEGMENT_RX_FREELIST);
1651 svm_fifo_segment_free_fifo (seg, session->server_tx_fifo,
1652 FIFO_SEGMENT_TX_FREELIST);
1653 svm_fifo_segment_delete (seg);
1654
1655 /* TBD: Send cut-thru disconnect event to client */
1656
1657 clib_spinlock_unlock (&vcm->sessions_lockp);
1658 }
1659 else
1660 {
1661 /* TBD: Send cut-thru disconnect event to server */
1662 }
Dave Wallace227867f2017-11-13 21:21:53 -05001663 }
Dave Wallace66cf6eb2017-10-26 02:51:07 -04001664
Dave Wallace4878cbe2017-11-21 03:45:09 -05001665done:
1666 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04001667}
1668
1669#define foreach_sock_msg \
1670_(SESSION_ENABLE_DISABLE_REPLY, session_enable_disable_reply) \
1671_(BIND_SOCK_REPLY, bind_sock_reply) \
1672_(UNBIND_SOCK_REPLY, unbind_sock_reply) \
1673_(ACCEPT_SESSION, accept_session) \
1674_(CONNECT_SOCK, connect_sock) \
Dave Wallace33e002b2017-09-06 01:20:02 -04001675_(CONNECT_SESSION_REPLY, connect_session_reply) \
Dave Wallace543852a2017-08-03 02:11:34 -04001676_(DISCONNECT_SESSION, disconnect_session) \
1677_(DISCONNECT_SESSION_REPLY, disconnect_session_reply) \
1678_(RESET_SESSION, reset_session) \
1679_(APPLICATION_ATTACH_REPLY, application_attach_reply) \
1680_(APPLICATION_DETACH_REPLY, application_detach_reply) \
1681_(MAP_ANOTHER_SEGMENT, map_another_segment)
1682
1683static void
1684vppcom_api_hookup (void)
1685{
1686#define _(N,n) \
1687 vl_msg_api_set_handlers(VL_API_##N, #n, \
1688 vl_api_##n##_t_handler, \
1689 vl_noop_handler, \
1690 vl_api_##n##_t_endian, \
1691 vl_api_##n##_t_print, \
1692 sizeof(vl_api_##n##_t), 1);
1693 foreach_sock_msg;
1694#undef _
1695}
1696
1697static void
1698vppcom_cfg_init (vppcom_cfg_t * vcl_cfg)
1699{
1700 ASSERT (vcl_cfg);
1701
1702 vcl_cfg->heapsize = (256ULL << 20);
Dave Wallacec8f1ee62017-11-29 22:46:32 -05001703 vcl_cfg->vpp_api_q_length = 1024;
Dave Wallace543852a2017-08-03 02:11:34 -04001704 vcl_cfg->segment_baseva = 0x200000000ULL;
1705 vcl_cfg->segment_size = (256 << 20);
1706 vcl_cfg->add_segment_size = (128 << 20);
1707 vcl_cfg->preallocated_fifo_pairs = 8;
1708 vcl_cfg->rx_fifo_size = (1 << 20);
1709 vcl_cfg->tx_fifo_size = (1 << 20);
1710 vcl_cfg->event_queue_size = 2048;
1711 vcl_cfg->listen_queue_size = CLIB_CACHE_LINE_BYTES / sizeof (u32);
1712 vcl_cfg->app_timeout = 10 * 60.0;
1713 vcl_cfg->session_timeout = 10 * 60.0;
1714 vcl_cfg->accept_timeout = 60.0;
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -08001715 vcl_cfg->event_ring_size = (128 << 10);
1716 vcl_cfg->event_log_path = "/dev/shm";
Dave Wallace543852a2017-08-03 02:11:34 -04001717}
1718
1719static void
1720vppcom_cfg_heapsize (char *conf_fname)
1721{
Dave Wallace543852a2017-08-03 02:11:34 -04001722 vppcom_cfg_t *vcl_cfg = &vcm->cfg;
1723 FILE *fp;
1724 char inbuf[4096];
1725 int argc = 1;
1726 char **argv = NULL;
1727 char *arg = NULL;
1728 char *p;
1729 int i;
1730 u8 *sizep;
1731 u32 size;
Dave Wallace2e005bb2017-11-07 01:21:39 -05001732 void *vcl_mem;
1733 void *heap;
Dave Wallace543852a2017-08-03 02:11:34 -04001734
1735 fp = fopen (conf_fname, "r");
1736 if (fp == NULL)
1737 {
1738 if (VPPCOM_DEBUG > 0)
1739 fprintf (stderr, "open configuration file '%s' failed\n", conf_fname);
1740 goto defaulted;
1741 }
1742 argv = calloc (1, sizeof (char *));
1743 if (argv == NULL)
1744 goto defaulted;
1745
1746 while (1)
1747 {
1748 if (fgets (inbuf, 4096, fp) == 0)
1749 break;
1750 p = strtok (inbuf, " \t\n");
1751 while (p != NULL)
1752 {
1753 if (*p == '#')
1754 break;
1755 argc++;
1756 char **tmp = realloc (argv, argc * sizeof (char *));
1757 if (tmp == NULL)
Chris Lukeab7b8d92017-09-07 07:40:13 -04001758 goto defaulted;
Dave Wallace543852a2017-08-03 02:11:34 -04001759 argv = tmp;
1760 arg = strndup (p, 1024);
1761 if (arg == NULL)
Chris Lukeab7b8d92017-09-07 07:40:13 -04001762 goto defaulted;
Dave Wallace543852a2017-08-03 02:11:34 -04001763 argv[argc - 1] = arg;
1764 p = strtok (NULL, " \t\n");
1765 }
1766 }
1767
1768 fclose (fp);
Chris Lukeab7b8d92017-09-07 07:40:13 -04001769 fp = NULL;
Dave Wallace543852a2017-08-03 02:11:34 -04001770
1771 char **tmp = realloc (argv, (argc + 1) * sizeof (char *));
1772 if (tmp == NULL)
1773 goto defaulted;
1774 argv = tmp;
1775 argv[argc] = NULL;
1776
1777 /*
1778 * Look for and parse the "heapsize" config parameter.
1779 * Manual since none of the clib infra has been bootstrapped yet.
1780 *
1781 * Format: heapsize <nn>[mM][gG]
1782 */
1783
1784 for (i = 1; i < (argc - 1); i++)
1785 {
1786 if (!strncmp (argv[i], "heapsize", 8))
1787 {
1788 sizep = (u8 *) argv[i + 1];
1789 size = 0;
1790 while (*sizep >= '0' && *sizep <= '9')
1791 {
1792 size *= 10;
1793 size += *sizep++ - '0';
1794 }
1795 if (size == 0)
1796 {
1797 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001798 clib_warning ("VCL<%d>: parse error '%s %s', "
Dave Wallace543852a2017-08-03 02:11:34 -04001799 "using default heapsize %lld (0x%llx)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05001800 getpid (), argv[i], argv[i + 1],
Dave Wallace543852a2017-08-03 02:11:34 -04001801 vcl_cfg->heapsize, vcl_cfg->heapsize);
1802 goto defaulted;
1803 }
1804
1805 if (*sizep == 'g' || *sizep == 'G')
1806 vcl_cfg->heapsize = size << 30;
1807 else if (*sizep == 'm' || *sizep == 'M')
1808 vcl_cfg->heapsize = size << 20;
1809 else
1810 {
1811 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001812 clib_warning ("VCL<%d>: parse error '%s %s', "
Dave Wallace543852a2017-08-03 02:11:34 -04001813 "using default heapsize %lld (0x%llx)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05001814 getpid (), argv[i], argv[i + 1],
Dave Wallace543852a2017-08-03 02:11:34 -04001815 vcl_cfg->heapsize, vcl_cfg->heapsize);
1816 goto defaulted;
1817 }
1818 }
1819 }
1820
1821defaulted:
Chris Lukeab7b8d92017-09-07 07:40:13 -04001822 if (fp != NULL)
1823 fclose (fp);
1824 if (argv != NULL)
1825 free (argv);
Dave Wallacee7fa24e2017-11-07 13:07:44 -05001826
Dave Wallace2e005bb2017-11-07 01:21:39 -05001827 vcl_mem = mmap (0, vcl_cfg->heapsize, PROT_READ | PROT_WRITE,
1828 MAP_SHARED | MAP_ANONYMOUS, -1, 0);
Steven0cdd5bd2017-11-08 14:14:45 -08001829 if (vcl_mem == MAP_FAILED)
Dave Wallacee7fa24e2017-11-07 13:07:44 -05001830 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001831 clib_unix_error ("VCL<%d>: ERROR: mmap(0, %lld == 0x%llx, "
Dave Wallacee7fa24e2017-11-07 13:07:44 -05001832 "PROT_READ | PROT_WRITE,MAP_SHARED | MAP_ANONYMOUS, "
1833 "-1, 0) failed!",
1834 getpid (), vcl_cfg->heapsize, vcl_cfg->heapsize);
1835 return;
1836 }
Dave Wallace2e005bb2017-11-07 01:21:39 -05001837 heap = clib_mem_init (vcl_mem, vcl_cfg->heapsize);
1838 if (!heap)
Dave Wallace2e005bb2017-11-07 01:21:39 -05001839 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001840 clib_warning ("VCL<%d>: ERROR: clib_mem_init() failed!", getpid ());
Dave Wallacee7fa24e2017-11-07 13:07:44 -05001841 return;
Dave Wallace2e005bb2017-11-07 01:21:39 -05001842 }
Dave Wallacee7fa24e2017-11-07 13:07:44 -05001843 vcl_mem = clib_mem_alloc (sizeof (_vppcom_main));
1844 if (!vcl_mem)
1845 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001846 clib_warning ("VCL<%d>: ERROR: clib_mem_alloc() failed!", getpid ());
Dave Wallacee7fa24e2017-11-07 13:07:44 -05001847 return;
1848 }
1849
1850 clib_memcpy (vcl_mem, &_vppcom_main, sizeof (_vppcom_main));
1851 vcm = vcl_mem;
1852
1853 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001854 clib_warning ("VCL<%d>: allocated VCL heap = %p, size %lld (0x%llx)",
Dave Wallacee7fa24e2017-11-07 13:07:44 -05001855 getpid (), heap, vcl_cfg->heapsize, vcl_cfg->heapsize);
Dave Wallace543852a2017-08-03 02:11:34 -04001856}
1857
1858static void
1859vppcom_cfg_read (char *conf_fname)
1860{
Dave Wallace543852a2017-08-03 02:11:34 -04001861 vppcom_cfg_t *vcl_cfg = &vcm->cfg;
1862 int fd;
1863 unformat_input_t _input, *input = &_input;
1864 unformat_input_t _line_input, *line_input = &_line_input;
1865 u8 vc_cfg_input = 0;
1866 u8 *chroot_path;
1867 struct stat s;
Dave Wallacec8f1ee62017-11-29 22:46:32 -05001868 u32 uid, gid, q_len;
Dave Wallace543852a2017-08-03 02:11:34 -04001869
1870 fd = open (conf_fname, O_RDONLY);
1871 if (fd < 0)
1872 {
1873 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001874 clib_warning ("VCL<%d>: open configuration file '%s' failed!",
Dave Wallace2e005bb2017-11-07 01:21:39 -05001875 getpid (), conf_fname);
Dave Wallace543852a2017-08-03 02:11:34 -04001876 goto file_done;
1877 }
1878
1879 if (fstat (fd, &s) < 0)
1880 {
1881 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001882 clib_warning ("VCL<%d>: failed to stat `%s'", getpid (), conf_fname);
Dave Wallace543852a2017-08-03 02:11:34 -04001883 goto file_done;
1884 }
1885
1886 if (!(S_ISREG (s.st_mode) || S_ISLNK (s.st_mode)))
1887 {
1888 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001889 clib_warning ("VCL<%d>: not a regular file `%s'",
1890 getpid (), conf_fname);
Dave Wallace543852a2017-08-03 02:11:34 -04001891 goto file_done;
1892 }
1893
Dave Barach59b25652017-09-10 15:04:27 -04001894 unformat_init_clib_file (input, fd);
Dave Wallace543852a2017-08-03 02:11:34 -04001895
1896 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1897 {
Chris Lukeb2bcad62017-09-18 08:51:22 -04001898 (void) unformat_user (input, unformat_line_input, line_input);
Dave Wallace543852a2017-08-03 02:11:34 -04001899 unformat_skip_white_space (line_input);
1900
Dave Wallace8af20542017-10-26 03:29:30 -04001901 if (unformat (line_input, "vcl {"))
Dave Wallace543852a2017-08-03 02:11:34 -04001902 {
1903 vc_cfg_input = 1;
1904 continue;
1905 }
1906
1907 if (vc_cfg_input)
1908 {
1909 if (unformat (line_input, "heapsize %s", &chroot_path))
1910 {
1911 vec_terminate_c_string (chroot_path);
1912 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001913 clib_warning ("VCL<%d>: configured heapsize %s, "
Dave Wallace543852a2017-08-03 02:11:34 -04001914 "actual heapsize %lld (0x%llx)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05001915 getpid (), chroot_path, vcl_cfg->heapsize,
Dave Wallace543852a2017-08-03 02:11:34 -04001916 vcl_cfg->heapsize);
1917 vec_free (chroot_path);
1918 }
1919 else if (unformat (line_input, "api-prefix %s", &chroot_path))
1920 {
1921 vec_terminate_c_string (chroot_path);
1922 vl_set_memory_root_path ((char *) chroot_path);
1923 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001924 clib_warning ("VCL<%d>: configured api-prefix %s",
Dave Wallace2e005bb2017-11-07 01:21:39 -05001925 getpid (), chroot_path);
Dave Wallace543852a2017-08-03 02:11:34 -04001926 chroot_path = 0; /* Don't vec_free() it! */
1927 }
Dave Wallacec8f1ee62017-11-29 22:46:32 -05001928 else if (unformat (line_input, "vpp-api-q-length %d", &q_len))
1929 {
1930 if (q_len < vcl_cfg->vpp_api_q_length)
1931 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001932 clib_warning ("VCL<%d>: ERROR: configured vpp-api-q-length "
Dave Wallacec8f1ee62017-11-29 22:46:32 -05001933 "(%u) is too small! Using default: %u ",
1934 getpid (), q_len, vcl_cfg->vpp_api_q_length);
1935 }
1936 else
1937 {
1938 vcl_cfg->vpp_api_q_length = q_len;
1939
1940 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001941 clib_warning ("VCL<%d>: configured vpp-api-q-length %u",
Dave Wallacec8f1ee62017-11-29 22:46:32 -05001942 getpid (), vcl_cfg->vpp_api_q_length);
1943 }
1944 }
Dave Wallace543852a2017-08-03 02:11:34 -04001945 else if (unformat (line_input, "uid %d", &uid))
1946 {
1947 vl_set_memory_uid (uid);
1948 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001949 clib_warning ("VCL<%d>: configured uid %d", getpid (), uid);
Dave Wallace543852a2017-08-03 02:11:34 -04001950 }
1951 else if (unformat (line_input, "gid %d", &gid))
1952 {
1953 vl_set_memory_gid (gid);
1954 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001955 clib_warning ("VCL<%d>: configured gid %d", getpid (), gid);
Dave Wallace543852a2017-08-03 02:11:34 -04001956 }
Dave Wallace8af20542017-10-26 03:29:30 -04001957 else if (unformat (line_input, "segment-baseva 0x%lx",
Dave Wallace543852a2017-08-03 02:11:34 -04001958 &vcl_cfg->segment_baseva))
1959 {
1960 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001961 clib_warning ("VCL<%d>: configured segment_baseva 0x%lx",
Dave Wallace2e005bb2017-11-07 01:21:39 -05001962 getpid (), vcl_cfg->segment_baseva);
Dave Wallace543852a2017-08-03 02:11:34 -04001963 }
1964 else if (unformat (line_input, "segment-size 0x%lx",
1965 &vcl_cfg->segment_size))
1966 {
1967 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001968 clib_warning ("VCL<%d>: configured segment_size 0x%lx (%ld)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05001969 getpid (), vcl_cfg->segment_size,
Dave Wallace543852a2017-08-03 02:11:34 -04001970 vcl_cfg->segment_size);
1971 }
1972 else if (unformat (line_input, "segment-size %ld",
1973 &vcl_cfg->segment_size))
1974 {
1975 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001976 clib_warning ("VCL<%d>: configured segment_size %ld (0x%lx)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05001977 getpid (), vcl_cfg->segment_size,
Dave Wallace543852a2017-08-03 02:11:34 -04001978 vcl_cfg->segment_size);
1979 }
1980 else if (unformat (line_input, "add-segment-size 0x%lx",
1981 &vcl_cfg->add_segment_size))
1982 {
1983 if (VPPCOM_DEBUG > 0)
1984 clib_warning
Dave Wallace048b1d62018-01-03 22:24:41 -05001985 ("VCL<%d>: configured add_segment_size 0x%lx (%ld)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05001986 getpid (), vcl_cfg->add_segment_size,
Dave Wallace543852a2017-08-03 02:11:34 -04001987 vcl_cfg->add_segment_size);
1988 }
1989 else if (unformat (line_input, "add-segment-size %ld",
1990 &vcl_cfg->add_segment_size))
1991 {
1992 if (VPPCOM_DEBUG > 0)
1993 clib_warning
Dave Wallace048b1d62018-01-03 22:24:41 -05001994 ("VCL<%d>: configured add_segment_size %ld (0x%lx)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05001995 getpid (), vcl_cfg->add_segment_size,
Dave Wallace543852a2017-08-03 02:11:34 -04001996 vcl_cfg->add_segment_size);
1997 }
1998 else if (unformat (line_input, "preallocated-fifo-pairs %d",
1999 &vcl_cfg->preallocated_fifo_pairs))
2000 {
2001 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002002 clib_warning ("VCL<%d>: configured preallocated_fifo_pairs "
Dave Wallace2e005bb2017-11-07 01:21:39 -05002003 "%d (0x%x)", getpid (),
Dave Wallace543852a2017-08-03 02:11:34 -04002004 vcl_cfg->preallocated_fifo_pairs,
2005 vcl_cfg->preallocated_fifo_pairs);
2006 }
2007 else if (unformat (line_input, "rx-fifo-size 0x%lx",
2008 &vcl_cfg->rx_fifo_size))
2009 {
2010 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002011 clib_warning ("VCL<%d>: configured rx_fifo_size 0x%lx (%ld)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002012 getpid (), vcl_cfg->rx_fifo_size,
Dave Wallace543852a2017-08-03 02:11:34 -04002013 vcl_cfg->rx_fifo_size);
2014 }
2015 else if (unformat (line_input, "rx-fifo-size %ld",
2016 &vcl_cfg->rx_fifo_size))
2017 {
2018 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002019 clib_warning ("VCL<%d>: configured rx_fifo_size %ld (0x%lx)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002020 getpid (), vcl_cfg->rx_fifo_size,
Dave Wallace543852a2017-08-03 02:11:34 -04002021 vcl_cfg->rx_fifo_size);
2022 }
2023 else if (unformat (line_input, "tx-fifo-size 0x%lx",
2024 &vcl_cfg->tx_fifo_size))
2025 {
2026 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002027 clib_warning ("VCL<%d>: configured tx_fifo_size 0x%lx (%ld)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002028 getpid (), vcl_cfg->tx_fifo_size,
Dave Wallace543852a2017-08-03 02:11:34 -04002029 vcl_cfg->tx_fifo_size);
2030 }
2031 else if (unformat (line_input, "tx-fifo-size %ld",
2032 &vcl_cfg->tx_fifo_size))
2033 {
2034 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002035 clib_warning ("VCL<%d>: configured tx_fifo_size %ld (0x%lx)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002036 getpid (), vcl_cfg->tx_fifo_size,
Dave Wallace543852a2017-08-03 02:11:34 -04002037 vcl_cfg->tx_fifo_size);
2038 }
2039 else if (unformat (line_input, "event-queue-size 0x%lx",
2040 &vcl_cfg->event_queue_size))
2041 {
2042 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002043 clib_warning ("VCL<%d>: configured event_queue_size "
2044 "0x%lx (%ld)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002045 getpid (), vcl_cfg->event_queue_size,
Dave Wallace543852a2017-08-03 02:11:34 -04002046 vcl_cfg->event_queue_size);
2047 }
2048 else if (unformat (line_input, "event-queue-size %ld",
2049 &vcl_cfg->event_queue_size))
2050 {
2051 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002052 clib_warning ("VCL<%d>: configured event_queue_size "
2053 "%ld (0x%lx)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002054 getpid (), vcl_cfg->event_queue_size,
Dave Wallace543852a2017-08-03 02:11:34 -04002055 vcl_cfg->event_queue_size);
2056 }
2057 else if (unformat (line_input, "listen-queue-size 0x%lx",
2058 &vcl_cfg->listen_queue_size))
2059 {
2060 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002061 clib_warning ("VCL<%d>: configured listen_queue_size "
2062 "0x%lx (%ld)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002063 getpid (), vcl_cfg->listen_queue_size,
Dave Wallace543852a2017-08-03 02:11:34 -04002064 vcl_cfg->listen_queue_size);
2065 }
2066 else if (unformat (line_input, "listen-queue-size %ld",
2067 &vcl_cfg->listen_queue_size))
2068 {
2069 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002070 clib_warning ("VCL<%d>: configured listen_queue_size "
2071 "%ld (0x%lx)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002072 getpid (), vcl_cfg->listen_queue_size,
Dave Wallace543852a2017-08-03 02:11:34 -04002073 vcl_cfg->listen_queue_size);
2074 }
2075 else if (unformat (line_input, "app-timeout %f",
2076 &vcl_cfg->app_timeout))
2077 {
2078 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002079 clib_warning ("VCL<%d>: configured app_timeout %f",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002080 getpid (), vcl_cfg->app_timeout);
Dave Wallace543852a2017-08-03 02:11:34 -04002081 }
2082 else if (unformat (line_input, "session-timeout %f",
2083 &vcl_cfg->session_timeout))
2084 {
2085 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002086 clib_warning ("VCL<%d>: configured session_timeout %f",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002087 getpid (), vcl_cfg->session_timeout);
Dave Wallace543852a2017-08-03 02:11:34 -04002088 }
2089 else if (unformat (line_input, "accept-timeout %f",
2090 &vcl_cfg->accept_timeout))
2091 {
2092 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002093 clib_warning ("VCL<%d>: configured accept_timeout %f",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002094 getpid (), vcl_cfg->accept_timeout);
Dave Wallace543852a2017-08-03 02:11:34 -04002095 }
Dave Wallace774169b2017-11-01 20:07:40 -04002096 else if (unformat (line_input, "app-proxy-transport-tcp"))
Dave Wallace8af20542017-10-26 03:29:30 -04002097 {
Dave Wallace774169b2017-11-01 20:07:40 -04002098 vcl_cfg->app_proxy_transport_tcp = 1;
Dave Wallace8af20542017-10-26 03:29:30 -04002099 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002100 clib_warning ("VCL<%d>: configured "
2101 "app_proxy_transport_tcp (%d)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002102 getpid (), vcl_cfg->app_proxy_transport_tcp);
Dave Wallace8af20542017-10-26 03:29:30 -04002103 }
Dave Wallace774169b2017-11-01 20:07:40 -04002104 else if (unformat (line_input, "app-proxy-transport-udp"))
Dave Wallace8af20542017-10-26 03:29:30 -04002105 {
Dave Wallace774169b2017-11-01 20:07:40 -04002106 vcl_cfg->app_proxy_transport_udp = 1;
Dave Wallace8af20542017-10-26 03:29:30 -04002107 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002108 clib_warning ("VCL<%d>: configured "
2109 "app_proxy_transport_udp (%d)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002110 getpid (), vcl_cfg->app_proxy_transport_udp);
Dave Wallace8af20542017-10-26 03:29:30 -04002111 }
Dave Wallace774169b2017-11-01 20:07:40 -04002112 else if (unformat (line_input, "app-scope-local"))
Dave Wallace8af20542017-10-26 03:29:30 -04002113 {
Dave Wallace774169b2017-11-01 20:07:40 -04002114 vcl_cfg->app_scope_local = 1;
Dave Wallace8af20542017-10-26 03:29:30 -04002115 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002116 clib_warning ("VCL<%d>: configured app_scope_local (%d)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002117 getpid (), vcl_cfg->app_scope_local);
Dave Wallace774169b2017-11-01 20:07:40 -04002118 }
2119 else if (unformat (line_input, "app-scope-global"))
2120 {
2121 vcl_cfg->app_scope_global = 1;
2122 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002123 clib_warning ("VCL<%d>: configured app_scope_global (%d)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002124 getpid (), vcl_cfg->app_scope_global);
Dave Wallace8af20542017-10-26 03:29:30 -04002125 }
2126 else if (unformat (line_input, "namespace-secret %lu",
2127 &vcl_cfg->namespace_secret))
2128 {
2129 if (VPPCOM_DEBUG > 0)
2130 clib_warning
Dave Wallace048b1d62018-01-03 22:24:41 -05002131 ("VCL<%d>: configured namespace_secret %lu (0x%lx)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002132 getpid (), vcl_cfg->namespace_secret,
Dave Wallace8af20542017-10-26 03:29:30 -04002133 vcl_cfg->namespace_secret);
2134 }
2135 else if (unformat (line_input, "namespace-id %v",
2136 &vcl_cfg->namespace_id))
2137 {
2138 vl_api_application_attach_t *mp;
2139 u32 max_nsid_vec_len = sizeof (mp->namespace_id) - 1;
2140 u32 nsid_vec_len = vec_len (vcl_cfg->namespace_id);
2141 if (nsid_vec_len > max_nsid_vec_len)
2142 {
2143 _vec_len (vcl_cfg->namespace_id) = max_nsid_vec_len;
2144 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002145 clib_warning ("VCL<%d>: configured namespace_id is "
2146 "too long, truncated to %d characters!",
2147 getpid (), max_nsid_vec_len);
Dave Wallace8af20542017-10-26 03:29:30 -04002148 }
2149
2150 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002151 clib_warning ("VCL<%d>: configured namespace_id %v",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002152 getpid (), vcl_cfg->namespace_id);
Dave Wallace8af20542017-10-26 03:29:30 -04002153 }
Dave Wallace543852a2017-08-03 02:11:34 -04002154 else if (unformat (line_input, "}"))
2155 {
2156 vc_cfg_input = 0;
2157 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002158 clib_warning ("VCL<%d>: completed parsing vppcom config!",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002159 getpid ());
Dave Wallace543852a2017-08-03 02:11:34 -04002160 goto input_done;
2161 }
2162 else
2163 {
2164 if (line_input->buffer[line_input->index] != '#')
2165 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002166 clib_warning ("VCL<%d>: Unknown vppcom config option: '%s'",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002167 getpid (), (char *)
Dave Wallace543852a2017-08-03 02:11:34 -04002168 &line_input->buffer[line_input->index]);
2169 }
2170 }
2171 }
2172 }
2173
2174input_done:
2175 unformat_free (input);
2176
2177file_done:
Chris Lukeab7b8d92017-09-07 07:40:13 -04002178 if (fd >= 0)
Dave Wallace543852a2017-08-03 02:11:34 -04002179 close (fd);
2180}
2181
2182/*
2183 * VPPCOM Public API functions
2184 */
2185int
2186vppcom_app_create (char *app_name)
2187{
Dave Wallace543852a2017-08-03 02:11:34 -04002188 vppcom_cfg_t *vcl_cfg = &vcm->cfg;
2189 u8 *heap;
2190 mheap_t *h;
2191 int rv;
2192
2193 if (!vcm->init)
2194 {
2195 char *conf_fname;
Dave Wallace8af20542017-10-26 03:29:30 -04002196 char *env_var_str;
Dave Wallace543852a2017-08-03 02:11:34 -04002197
2198 vcm->init = 1;
Dave Wallace543852a2017-08-03 02:11:34 -04002199 vppcom_cfg_init (vcl_cfg);
Dave Wallace498b3a52017-11-09 13:00:34 -05002200 env_var_str = getenv (VPPCOM_ENV_DEBUG);
2201 if (env_var_str)
2202 {
2203 u32 tmp;
2204 if (sscanf (env_var_str, "%u", &tmp) != 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002205 clib_warning ("VCL<%d>: Invalid debug level specified in "
Dave Wallace498b3a52017-11-09 13:00:34 -05002206 "the environment variable "
2207 VPPCOM_ENV_DEBUG
2208 " (%s)!\n", getpid (), env_var_str);
2209 else
2210 {
2211 vcm->debug = tmp;
Dave Wallace048b1d62018-01-03 22:24:41 -05002212 clib_warning ("VCL<%d>: configured VCL debug level (%u) from "
Dave Wallace498b3a52017-11-09 13:00:34 -05002213 VPPCOM_ENV_DEBUG "!", getpid (), vcm->debug);
2214 }
2215 }
Dave Wallace8af20542017-10-26 03:29:30 -04002216 conf_fname = getenv (VPPCOM_ENV_CONF);
Dave Wallace543852a2017-08-03 02:11:34 -04002217 if (!conf_fname)
2218 {
2219 conf_fname = VPPCOM_CONF_DEFAULT;
2220 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002221 clib_warning ("VCL<%d>: getenv '%s' failed!", getpid (),
Dave Wallace8af20542017-10-26 03:29:30 -04002222 VPPCOM_ENV_CONF);
Dave Wallace543852a2017-08-03 02:11:34 -04002223 }
2224 vppcom_cfg_heapsize (conf_fname);
Dave Wallace2e005bb2017-11-07 01:21:39 -05002225 clib_fifo_validate (vcm->client_session_index_fifo,
2226 vcm->cfg.listen_queue_size);
Dave Wallace543852a2017-08-03 02:11:34 -04002227 vppcom_cfg_read (conf_fname);
Dave Wallace8af20542017-10-26 03:29:30 -04002228 env_var_str = getenv (VPPCOM_ENV_APP_NAMESPACE_ID);
2229 if (env_var_str)
2230 {
2231 u32 ns_id_vec_len = strlen (env_var_str);
2232
2233 vec_reset_length (vcm->cfg.namespace_id);
2234 vec_validate (vcm->cfg.namespace_id, ns_id_vec_len - 1);
2235 clib_memcpy (vcm->cfg.namespace_id, env_var_str, ns_id_vec_len);
2236
2237 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002238 clib_warning ("VCL<%d>: configured namespace_id (%v) from "
Dave Wallace2e005bb2017-11-07 01:21:39 -05002239 VPPCOM_ENV_APP_NAMESPACE_ID "!", getpid (),
Dave Wallace8af20542017-10-26 03:29:30 -04002240 vcm->cfg.namespace_id);
2241 }
2242 env_var_str = getenv (VPPCOM_ENV_APP_NAMESPACE_SECRET);
2243 if (env_var_str)
2244 {
2245 u64 tmp;
2246 if (sscanf (env_var_str, "%lu", &tmp) != 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002247 clib_warning ("VCL<%d>: Invalid namespace secret specified in "
Dave Wallace8af20542017-10-26 03:29:30 -04002248 "the environment variable "
2249 VPPCOM_ENV_APP_NAMESPACE_SECRET
Dave Wallace2e005bb2017-11-07 01:21:39 -05002250 " (%s)!\n", getpid (), env_var_str);
Dave Wallace8af20542017-10-26 03:29:30 -04002251 else
2252 {
2253 vcm->cfg.namespace_secret = tmp;
2254 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002255 clib_warning ("VCL<%d>: configured namespace secret "
2256 "(%lu) from " VPPCOM_ENV_APP_NAMESPACE_ID "!",
2257 getpid (), vcm->cfg.namespace_secret);
Dave Wallace8af20542017-10-26 03:29:30 -04002258 }
2259 }
Dave Wallace774169b2017-11-01 20:07:40 -04002260 if (getenv (VPPCOM_ENV_APP_PROXY_TRANSPORT_TCP))
Dave Wallace8af20542017-10-26 03:29:30 -04002261 {
Dave Wallace774169b2017-11-01 20:07:40 -04002262 vcm->cfg.app_proxy_transport_tcp = 1;
Dave Wallace8af20542017-10-26 03:29:30 -04002263 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002264 clib_warning ("VCL<%d>: configured app_proxy_transport_tcp "
2265 "(%u) from " VPPCOM_ENV_APP_PROXY_TRANSPORT_TCP
2266 "!", getpid (), vcm->cfg.app_proxy_transport_tcp);
Dave Wallace8af20542017-10-26 03:29:30 -04002267 }
Dave Wallace774169b2017-11-01 20:07:40 -04002268 if (getenv (VPPCOM_ENV_APP_PROXY_TRANSPORT_UDP))
Dave Wallace8af20542017-10-26 03:29:30 -04002269 {
Dave Wallace774169b2017-11-01 20:07:40 -04002270 vcm->cfg.app_proxy_transport_udp = 1;
Dave Wallace8af20542017-10-26 03:29:30 -04002271 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002272 clib_warning ("VCL<%d>: configured app_proxy_transport_udp "
2273 "(%u) from " VPPCOM_ENV_APP_PROXY_TRANSPORT_UDP
2274 "!", getpid (), vcm->cfg.app_proxy_transport_udp);
Dave Wallace774169b2017-11-01 20:07:40 -04002275 }
2276 if (getenv (VPPCOM_ENV_APP_SCOPE_LOCAL))
2277 {
2278 vcm->cfg.app_scope_local = 1;
2279 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002280 clib_warning ("VCL<%d>: configured app_scope_local (%u) from "
Dave Wallace2e005bb2017-11-07 01:21:39 -05002281 VPPCOM_ENV_APP_SCOPE_LOCAL "!", getpid (),
Dave Wallace774169b2017-11-01 20:07:40 -04002282 vcm->cfg.app_scope_local);
2283 }
2284 if (getenv (VPPCOM_ENV_APP_SCOPE_GLOBAL))
2285 {
2286 vcm->cfg.app_scope_global = 1;
2287 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002288 clib_warning ("VCL<%d>: configured app_scope_global (%u) from "
Dave Wallace2e005bb2017-11-07 01:21:39 -05002289 VPPCOM_ENV_APP_SCOPE_GLOBAL "!", getpid (),
Dave Wallace774169b2017-11-01 20:07:40 -04002290 vcm->cfg.app_scope_global);
Dave Wallace8af20542017-10-26 03:29:30 -04002291 }
2292
Dave Wallace543852a2017-08-03 02:11:34 -04002293 vcm->main_cpu = os_get_thread_index ();
2294 heap = clib_mem_get_per_cpu_heap ();
2295 h = mheap_header (heap);
2296
2297 /* make the main heap thread-safe */
2298 h->flags |= MHEAP_FLAG_THREAD_SAFE;
2299
2300 vcm->session_index_by_vpp_handles = hash_create (0, sizeof (uword));
2301
2302 clib_time_init (&vcm->clib_time);
2303 vppcom_init_error_string_table ();
Florin Corasa332c462018-01-31 06:52:17 -08002304 svm_fifo_segment_main_init (vcl_cfg->segment_baseva,
2305 20 /* timeout in secs */ );
Dave Wallace543852a2017-08-03 02:11:34 -04002306 clib_spinlock_init (&vcm->sessions_lockp);
Dave Wallace543852a2017-08-03 02:11:34 -04002307 }
2308
2309 if (vcm->my_client_index == ~0)
2310 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002311 vppcom_api_hookup ();
Dave Wallace543852a2017-08-03 02:11:34 -04002312 vcm->app_state = STATE_APP_START;
2313 rv = vppcom_connect_to_vpp (app_name);
2314 if (rv)
2315 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002316 clib_warning ("VCL<%d>: ERROR: couldn't connect to VPP!",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002317 getpid ());
Dave Wallace543852a2017-08-03 02:11:34 -04002318 return rv;
2319 }
2320
2321 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002322 clib_warning ("VCL<%d>: sending session enable", getpid ());
Dave Wallace543852a2017-08-03 02:11:34 -04002323
Dave Wallace048b1d62018-01-03 22:24:41 -05002324 rv = vppcom_app_session_enable ();
Dave Wallace543852a2017-08-03 02:11:34 -04002325 if (rv)
2326 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002327 clib_warning ("VCL<%d>: ERROR: vppcom_app_session_enable() "
2328 "failed!", getpid ());
Dave Wallace543852a2017-08-03 02:11:34 -04002329 return rv;
2330 }
Dave Wallace543852a2017-08-03 02:11:34 -04002331
Dave Wallace66cf6eb2017-10-26 02:51:07 -04002332 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002333 clib_warning ("VCL<%d>: sending app attach", getpid ());
2334
2335 rv = vppcom_app_attach ();
2336 if (rv)
2337 {
2338 clib_warning ("VCL<%d>: ERROR: vppcom_app_attach() failed!",
2339 getpid ());
2340 return rv;
2341 }
2342
2343 if (VPPCOM_DEBUG > 0)
2344 clib_warning ("VCL<%d>: app_name '%s', my_client_index %d (0x%x)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002345 getpid (), app_name, vcm->my_client_index,
Dave Wallace66cf6eb2017-10-26 02:51:07 -04002346 vcm->my_client_index);
2347 }
Dave Wallace543852a2017-08-03 02:11:34 -04002348
2349 return VPPCOM_OK;
2350}
2351
2352void
2353vppcom_app_destroy (void)
2354{
Dave Wallace543852a2017-08-03 02:11:34 -04002355 int rv;
2356
2357 if (vcm->my_client_index == ~0)
2358 return;
2359
2360 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002361 clib_warning ("VCL<%d>: detaching from VPP, my_client_index %d (0x%x)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002362 getpid (), vcm->my_client_index, vcm->my_client_index);
Dave Wallace543852a2017-08-03 02:11:34 -04002363
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -08002364 if (VPPCOM_DEBUG > 0)
2365 {
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002366 /* *INDENT-OFF* */
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -08002367 ELOG_TYPE_DECLARE (e) =
2368 {
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002369 .format = "app_detach:C:%d",
2370 .format_args = "i4",
2371 };
2372
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -08002373 struct
2374 {
2375 u32 data;
2376 } *ed;
2377 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, vcm->elog_track);
2378 ed->data = vcm->my_client_index;
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002379 /* *INDENT-ON* */
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -08002380 }
2381
Dave Wallace543852a2017-08-03 02:11:34 -04002382 vppcom_app_detach ();
2383 rv = vppcom_wait_for_app_state_change (STATE_APP_ENABLED);
2384 if (PREDICT_FALSE (rv))
2385 {
2386 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002387 clib_warning ("VCL<%d>: application detach timed out! "
2388 "returning %d (%s)",
Dave Wallaceee45d412017-11-24 21:44:06 -05002389 getpid (), rv, vppcom_retval_str (rv));
Dave Wallace543852a2017-08-03 02:11:34 -04002390 }
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -08002391
2392 /* Finished with logging before client gets reset to ~0 */
2393 if (VPPCOM_DEBUG > 0)
2394 write_elog ();
2395
Dave Wallace543852a2017-08-03 02:11:34 -04002396 vl_client_disconnect_from_vlib ();
2397 vcm->my_client_index = ~0;
2398 vcm->app_state = STATE_APP_START;
2399}
2400
2401int
Dave Wallacec04cbf12018-02-07 18:14:02 -05002402vppcom_session_create (u8 proto, u8 is_nonblocking)
Dave Wallace543852a2017-08-03 02:11:34 -04002403{
Dave Wallace543852a2017-08-03 02:11:34 -04002404 session_t *session;
2405 u32 session_index;
2406
2407 clib_spinlock_lock (&vcm->sessions_lockp);
2408 pool_get (vcm->sessions, session);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002409 memset (session, 0, sizeof (*session));
Dave Wallace543852a2017-08-03 02:11:34 -04002410 session_index = session - vcm->sessions;
2411
Dave Wallace543852a2017-08-03 02:11:34 -04002412 session->proto = proto;
2413 session->state = STATE_START;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002414 session->is_nonblocking = is_nonblocking ? 1 : 0;
Dave Wallace4878cbe2017-11-21 03:45:09 -05002415 session->vpp_handle = ~0;
Dave Wallace543852a2017-08-03 02:11:34 -04002416 clib_spinlock_unlock (&vcm->sessions_lockp);
2417
2418 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002419 clib_warning ("VCL<%d>: sid %u", getpid (), session_index);
Dave Wallace543852a2017-08-03 02:11:34 -04002420
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002421 if (VPPCOM_DEBUG > 0)
2422 {
2423 session->elog_track.name =
2424 (char *) format (0, "C:%d:S:%d%c", vcm->my_client_index,
2425 session_index, 0);
2426 elog_track_register (&vcm->elog_main, &session->elog_track);
2427
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002428 /* *INDENT-OFF* */
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002429 ELOG_TYPE_DECLARE (e) =
2430 {
Dave Wallacec04cbf12018-02-07 18:14:02 -05002431 .format = "session_create:proto:%d state:%d is_nonblocking:%d",
2432 .format_args = "i4i4i4",
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002433 };
2434
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002435 struct
2436 {
Dave Wallacec04cbf12018-02-07 18:14:02 -05002437 u32 data[3];
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002438 } *ed;
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002439
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002440 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
Dave Wallacec04cbf12018-02-07 18:14:02 -05002441 ed->data[0] = session->proto;
2442 ed->data[1] = session->state;
2443 ed->data[2] = session->is_nonblocking;
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002444 /* *INDENT-ON* */
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002445 }
2446
Dave Wallace543852a2017-08-03 02:11:34 -04002447 return (int) session_index;
2448}
2449
2450int
2451vppcom_session_close (uint32_t session_index)
2452{
Dave Wallace543852a2017-08-03 02:11:34 -04002453 session_t *session = 0;
2454 int rv;
Dave Wallace66cf6eb2017-10-26 02:51:07 -04002455 u8 is_listen;
Dave Wallace66cf6eb2017-10-26 02:51:07 -04002456 u8 is_vep;
2457 u8 is_vep_session;
2458 u32 next_sid;
2459 u32 vep_idx;
Dave Wallaceee45d412017-11-24 21:44:06 -05002460 u64 vpp_handle;
Dave Wallace4878cbe2017-11-21 03:45:09 -05002461 uword *p;
Dave Wallace66cf6eb2017-10-26 02:51:07 -04002462 session_state_t state;
Dave Wallace543852a2017-08-03 02:11:34 -04002463
Dave Wallace4878cbe2017-11-21 03:45:09 -05002464 VCL_LOCK_AND_GET_SESSION (session_index, &session);
Dave Wallace66cf6eb2017-10-26 02:51:07 -04002465 is_listen = session->is_listen;
Dave Wallace66cf6eb2017-10-26 02:51:07 -04002466 is_vep = session->is_vep;
2467 is_vep_session = session->is_vep_session;
2468 next_sid = session->vep.next_sid;
2469 vep_idx = session->vep.vep_idx;
2470 state = session->state;
Dave Wallaceee45d412017-11-24 21:44:06 -05002471 vpp_handle = session->vpp_handle;
Dave Wallace543852a2017-08-03 02:11:34 -04002472 clib_spinlock_unlock (&vcm->sessions_lockp);
2473
2474 if (VPPCOM_DEBUG > 0)
Dave Wallaceee45d412017-11-24 21:44:06 -05002475 {
2476 if (is_vep)
Dave Wallace048b1d62018-01-03 22:24:41 -05002477 clib_warning ("VCL<%d>: vep_idx %u / sid %u: "
2478 "closing epoll session...",
Dave Wallaceee45d412017-11-24 21:44:06 -05002479 getpid (), session_index, session_index);
2480 else
Dave Wallace048b1d62018-01-03 22:24:41 -05002481 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %d: "
2482 "closing session...",
Dave Wallaceee45d412017-11-24 21:44:06 -05002483 getpid (), vpp_handle, session_index);
2484 }
Dave Wallace543852a2017-08-03 02:11:34 -04002485
Dave Wallace66cf6eb2017-10-26 02:51:07 -04002486 if (is_vep)
Dave Wallace543852a2017-08-03 02:11:34 -04002487 {
Dave Wallace66cf6eb2017-10-26 02:51:07 -04002488 while (next_sid != ~0)
Dave Wallace19481612017-09-15 18:47:44 -04002489 {
Dave Wallacef7f809c2017-10-03 01:48:42 -04002490 rv = vppcom_epoll_ctl (session_index, EPOLL_CTL_DEL, next_sid, 0);
Dave Wallaceee45d412017-11-24 21:44:06 -05002491 if ((VPPCOM_DEBUG > 0) && PREDICT_FALSE (rv < 0))
Dave Wallace048b1d62018-01-03 22:24:41 -05002492 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
2493 "EPOLL_CTL_DEL vep_idx %u failed! rv %d (%s)",
2494 getpid (), vpp_handle, next_sid, vep_idx,
Dave Wallace4878cbe2017-11-21 03:45:09 -05002495 rv, vppcom_retval_str (rv));
Dave Wallacef7f809c2017-10-03 01:48:42 -04002496
Dave Wallace4878cbe2017-11-21 03:45:09 -05002497 VCL_LOCK_AND_GET_SESSION (session_index, &session);
Dave Wallace66cf6eb2017-10-26 02:51:07 -04002498 next_sid = session->vep.next_sid;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002499 clib_spinlock_unlock (&vcm->sessions_lockp);
2500 }
2501 }
2502 else
2503 {
Dave Wallace66cf6eb2017-10-26 02:51:07 -04002504 if (is_vep_session)
Dave Wallacef7f809c2017-10-03 01:48:42 -04002505 {
Dave Wallacef7f809c2017-10-03 01:48:42 -04002506 rv = vppcom_epoll_ctl (vep_idx, EPOLL_CTL_DEL, session_index, 0);
2507 if ((VPPCOM_DEBUG > 0) && (rv < 0))
Dave Wallace048b1d62018-01-03 22:24:41 -05002508 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
2509 "EPOLL_CTL_DEL vep_idx %u failed! rv %d (%s)",
Dave Wallaceee45d412017-11-24 21:44:06 -05002510 getpid (), vpp_handle, session_index,
2511 vep_idx, rv, vppcom_retval_str (rv));
Dave Wallacef7f809c2017-10-03 01:48:42 -04002512 }
2513
Dave Wallace4878cbe2017-11-21 03:45:09 -05002514 if (is_listen)
Dave Wallacef7f809c2017-10-03 01:48:42 -04002515 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05002516 if (state == STATE_LISTEN)
2517 {
2518 rv = vppcom_session_unbind (session_index);
2519 if (PREDICT_FALSE (rv < 0))
2520 {
2521 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002522 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -05002523 "listener unbind failed! rv %d (%s)",
2524 getpid (), vpp_handle, session_index,
2525 rv, vppcom_retval_str (rv));
Dave Wallace4878cbe2017-11-21 03:45:09 -05002526 }
2527 }
Dave Wallacef7f809c2017-10-03 01:48:42 -04002528 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05002529
2530 else if (state & (CLIENT_STATE_OPEN | SERVER_STATE_OPEN))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002531 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05002532 rv = vppcom_session_disconnect (session_index);
2533 if (PREDICT_FALSE (rv < 0))
Dave Wallace048b1d62018-01-03 22:24:41 -05002534 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -05002535 "session disconnect failed! rv %d (%s)",
2536 getpid (), vpp_handle, session_index,
2537 rv, vppcom_retval_str (rv));
Dave Wallacef7f809c2017-10-03 01:48:42 -04002538 }
Dave Wallace19481612017-09-15 18:47:44 -04002539 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05002540
2541 VCL_LOCK_AND_GET_SESSION (session_index, &session);
Dave Wallaceee45d412017-11-24 21:44:06 -05002542 vpp_handle = session->vpp_handle;
2543 if (vpp_handle != ~0)
Dave Wallace4878cbe2017-11-21 03:45:09 -05002544 {
Dave Wallaceee45d412017-11-24 21:44:06 -05002545 p = hash_get (vcm->session_index_by_vpp_handles, vpp_handle);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002546 if (p)
Dave Wallaceee45d412017-11-24 21:44:06 -05002547 hash_unset (vcm->session_index_by_vpp_handles, vpp_handle);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002548 }
Dave Wallace543852a2017-08-03 02:11:34 -04002549 pool_put_index (vcm->sessions, session_index);
Dave Wallace66cf6eb2017-10-26 02:51:07 -04002550 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002551
2552 if (VPPCOM_DEBUG > 0)
Dave Wallaceee45d412017-11-24 21:44:06 -05002553 {
2554 if (is_vep)
Dave Wallace048b1d62018-01-03 22:24:41 -05002555 clib_warning ("VCL<%d>: vep_idx %u / sid %u: epoll session removed.",
Dave Wallaceee45d412017-11-24 21:44:06 -05002556 getpid (), session_index, session_index);
2557 else
Dave Wallace048b1d62018-01-03 22:24:41 -05002558 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: session removed.",
Dave Wallaceee45d412017-11-24 21:44:06 -05002559 getpid (), vpp_handle, session_index);
2560 }
Dave Wallacef7f809c2017-10-03 01:48:42 -04002561done:
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002562
2563 if (VPPCOM_DEBUG > 0)
2564 {
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002565 /* *INDENT-OFF* */
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002566 ELOG_TYPE_DECLARE (e) =
2567 {
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002568 .format = "session_close:rv:%d",
2569 .format_args = "i4",
2570 };
2571
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002572 struct
2573 {
2574 u32 data;
2575 } *ed;
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002576
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002577 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
2578 ed->data = rv;
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002579 /* *INDENT-ON* */
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002580 }
2581
Dave Wallace543852a2017-08-03 02:11:34 -04002582 return rv;
2583}
2584
2585int
2586vppcom_session_bind (uint32_t session_index, vppcom_endpt_t * ep)
2587{
Dave Wallace543852a2017-08-03 02:11:34 -04002588 session_t *session = 0;
2589 int rv;
2590
2591 if (!ep || !ep->ip)
2592 return VPPCOM_EINVAL;
2593
Dave Wallace4878cbe2017-11-21 03:45:09 -05002594 VCL_LOCK_AND_GET_SESSION (session_index, &session);
Dave Wallace543852a2017-08-03 02:11:34 -04002595
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002596 if (session->is_vep)
2597 {
2598 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace048b1d62018-01-03 22:24:41 -05002599 clib_warning ("VCL<%d>: ERROR: sid %u: cannot "
2600 "bind to an epoll session!", getpid (), session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002601 rv = VPPCOM_EBADFD;
2602 goto done;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002603 }
2604
Dave Wallace35830af2017-10-09 01:43:42 -04002605 session->lcl_addr.is_ip4 = ep->is_ip4;
2606 session->lcl_addr.ip46 = to_ip46 (!ep->is_ip4, ep->ip);
Stevenac1f96d2017-10-24 16:03:58 -07002607 session->lcl_port = ep->port;
2608
2609 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002610 clib_warning ("VCL<%d>: sid %u: binding to local %s address %U "
Dave Wallaceee45d412017-11-24 21:44:06 -05002611 "port %u, proto %s", getpid (), session_index,
2612 session->lcl_addr.is_ip4 ? "IPv4" : "IPv6",
2613 format_ip46_address, &session->lcl_addr.ip46,
2614 session->lcl_addr.is_ip4,
Dave Wallace4878cbe2017-11-21 03:45:09 -05002615 clib_net_to_host_u16 (session->lcl_port),
2616 session->proto ? "UDP" : "TCP");
Dave Wallace543852a2017-08-03 02:11:34 -04002617
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002618 if (VPPCOM_DEBUG > 0)
2619 {
2620 if (session->lcl_addr.is_ip4)
2621 {
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002622 /* *INDENT-OFF* */
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002623 ELOG_TYPE_DECLARE (e) =
2624 {
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002625 .format = "bind local:%s:%d.%d.%d.%d:%d ",
2626 .format_args = "t1i1i1i1i1i2",
2627 .n_enum_strings = 2,
2628 .enum_strings = {"TCP", "UDP",},
2629 };
2630
2631 CLIB_PACKED (struct {
2632 u8 proto;
2633 u8 addr[4];
2634 u16 port;
2635 }) * ed;
2636
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002637 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
2638 ed->proto = session->proto;
2639 ed->addr[0] = session->lcl_addr.ip46.ip4.as_u8[0];
2640 ed->addr[1] = session->lcl_addr.ip46.ip4.as_u8[1];
2641 ed->addr[2] = session->lcl_addr.ip46.ip4.as_u8[2];
2642 ed->addr[3] = session->lcl_addr.ip46.ip4.as_u8[3];
2643 ed->port = clib_net_to_host_u16 (session->lcl_port);
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002644 /* *INDENT-ON* */
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002645 }
2646 }
2647
Dave Wallace543852a2017-08-03 02:11:34 -04002648 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002649done:
2650 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04002651}
2652
2653int
Dave Wallace33e002b2017-09-06 01:20:02 -04002654vppcom_session_listen (uint32_t listen_session_index, uint32_t q_len)
Dave Wallace543852a2017-08-03 02:11:34 -04002655{
Dave Wallace33e002b2017-09-06 01:20:02 -04002656 session_t *listen_session = 0;
Dave Wallaceee45d412017-11-24 21:44:06 -05002657 u64 listen_vpp_handle;
2658 int rv, retval;
Dave Wallace543852a2017-08-03 02:11:34 -04002659
Dave Wallace4878cbe2017-11-21 03:45:09 -05002660 VCL_LOCK_AND_GET_SESSION (listen_session_index, &listen_session);
Dave Wallace543852a2017-08-03 02:11:34 -04002661
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002662 if (listen_session->is_vep)
2663 {
2664 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace048b1d62018-01-03 22:24:41 -05002665 clib_warning ("VCL<%d>: ERROR: sid %u: cannot listen on an "
Dave Wallace4878cbe2017-11-21 03:45:09 -05002666 "epoll session!", getpid (), listen_session_index);
2667 rv = VPPCOM_EBADFD;
2668 goto done;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002669 }
2670
Dave Wallaceee45d412017-11-24 21:44:06 -05002671 listen_vpp_handle = listen_session->vpp_handle;
Dave Wallacee695cb42017-11-02 22:04:42 -04002672 if (listen_session->is_listen)
2673 {
2674 clib_spinlock_unlock (&vcm->sessions_lockp);
2675 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002676 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -05002677 "already in listen state!",
2678 getpid (), listen_vpp_handle, listen_session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002679 rv = VPPCOM_OK;
2680 goto done;
Dave Wallacee695cb42017-11-02 22:04:42 -04002681 }
2682
Dave Wallace543852a2017-08-03 02:11:34 -04002683 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002684 clib_warning ("VCL<%d>: vpp handle 0x%llx, "
2685 "sid %u: sending bind request...",
Dave Wallaceee45d412017-11-24 21:44:06 -05002686 getpid (), listen_vpp_handle, listen_session_index);
Dave Wallace543852a2017-08-03 02:11:34 -04002687
Dave Wallace4878cbe2017-11-21 03:45:09 -05002688 vppcom_send_bind_sock (listen_session, listen_session_index);
Dave Wallace543852a2017-08-03 02:11:34 -04002689 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallaceee45d412017-11-24 21:44:06 -05002690 retval =
Dave Wallace33e002b2017-09-06 01:20:02 -04002691 vppcom_wait_for_session_state_change (listen_session_index, STATE_LISTEN,
2692 vcm->cfg.session_timeout);
Dave Wallace543852a2017-08-03 02:11:34 -04002693
Dave Wallace4878cbe2017-11-21 03:45:09 -05002694 VCL_LOCK_AND_GET_SESSION (listen_session_index, &listen_session);
Dave Wallaceee45d412017-11-24 21:44:06 -05002695 if (PREDICT_FALSE (retval))
2696 {
2697 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002698 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: bind failed! "
Dave Wallaceee45d412017-11-24 21:44:06 -05002699 "returning %d (%s)", getpid (),
2700 listen_session->vpp_handle, listen_session_index,
2701 retval, vppcom_retval_str (retval));
2702 clib_spinlock_unlock (&vcm->sessions_lockp);
2703 rv = retval;
2704 goto done;
2705 }
2706
Dave Wallace543852a2017-08-03 02:11:34 -04002707 clib_fifo_validate (vcm->client_session_index_fifo, q_len);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002708 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002709done:
2710 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04002711}
2712
2713int
2714vppcom_session_accept (uint32_t listen_session_index, vppcom_endpt_t * ep,
Dave Wallace048b1d62018-01-03 22:24:41 -05002715 uint32_t flags)
Dave Wallace543852a2017-08-03 02:11:34 -04002716{
Dave Wallace33e002b2017-09-06 01:20:02 -04002717 session_t *listen_session = 0;
2718 session_t *client_session = 0;
Florin Corasa332c462018-01-31 06:52:17 -08002719 u32 client_session_index = ~0, n_fifos;
Dave Wallace543852a2017-08-03 02:11:34 -04002720 int rv;
2721 f64 wait_for;
Dave Wallace60caa062017-11-10 17:07:13 -05002722 char *cut_thru_str;
Dave Wallaceee45d412017-11-24 21:44:06 -05002723 u64 listen_vpp_handle;
Dave Wallace543852a2017-08-03 02:11:34 -04002724
Dave Wallace4878cbe2017-11-21 03:45:09 -05002725 VCL_LOCK_AND_GET_SESSION (listen_session_index, &listen_session);
Dave Wallace543852a2017-08-03 02:11:34 -04002726
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002727 if (listen_session->is_vep)
2728 {
2729 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace048b1d62018-01-03 22:24:41 -05002730 clib_warning ("VCL<%d>: ERROR: sid %u: cannot accept on an "
Dave Wallace4878cbe2017-11-21 03:45:09 -05002731 "epoll session!", getpid (), listen_session_index);
2732 rv = VPPCOM_EBADFD;
2733 goto done;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002734 }
2735
Dave Wallaceee45d412017-11-24 21:44:06 -05002736 listen_vpp_handle = listen_session->vpp_handle;
Dave Wallace33e002b2017-09-06 01:20:02 -04002737 if (listen_session->state != STATE_LISTEN)
Dave Wallace543852a2017-08-03 02:11:34 -04002738 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002739 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -05002740 "not in listen state! state 0x%x (%s)", getpid (),
2741 listen_vpp_handle, listen_session_index,
2742 listen_session->state,
Dave Wallace4878cbe2017-11-21 03:45:09 -05002743 vppcom_session_state_str (listen_session->state));
Dave Wallaceee45d412017-11-24 21:44:06 -05002744 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002745 rv = VPPCOM_EBADFD;
2746 goto done;
Dave Wallace543852a2017-08-03 02:11:34 -04002747 }
Dave Wallace048b1d62018-01-03 22:24:41 -05002748 wait_for = (listen_session->is_nonblocking) ? 0 : vcm->cfg.accept_timeout;
Dave Wallace543852a2017-08-03 02:11:34 -04002749
Dave Wallace543852a2017-08-03 02:11:34 -04002750 clib_spinlock_unlock (&vcm->sessions_lockp);
2751
2752 while (1)
2753 {
2754 rv = vppcom_wait_for_client_session_index (wait_for);
2755 if (rv)
2756 {
2757 if ((VPPCOM_DEBUG > 0))
Dave Wallace048b1d62018-01-03 22:24:41 -05002758 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
2759 "accept failed! returning %d (%s)", getpid (),
Dave Wallaceee45d412017-11-24 21:44:06 -05002760 listen_vpp_handle, listen_session_index,
Dave Wallace4878cbe2017-11-21 03:45:09 -05002761 rv, vppcom_retval_str (rv));
Dave Wallace048b1d62018-01-03 22:24:41 -05002762 if (wait_for == 0)
Dave Wallace4878cbe2017-11-21 03:45:09 -05002763 goto done;
Dave Wallace543852a2017-08-03 02:11:34 -04002764 }
2765 else
2766 break;
2767 }
2768
Dave Wallace543852a2017-08-03 02:11:34 -04002769 clib_spinlock_lock (&vcm->sessions_lockp);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002770 clib_fifo_sub1 (vcm->client_session_index_fifo, client_session_index);
Dave Wallace33e002b2017-09-06 01:20:02 -04002771 rv = vppcom_session_at_index (client_session_index, &client_session);
Dave Wallaceee45d412017-11-24 21:44:06 -05002772 if (PREDICT_FALSE (rv))
2773 {
2774 rv = VPPCOM_ECONNABORTED;
Dave Wallace048b1d62018-01-03 22:24:41 -05002775 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: client sid %u "
Dave Wallaceee45d412017-11-24 21:44:06 -05002776 "lookup failed! returning %d (%s)", getpid (),
2777 listen_vpp_handle, listen_session_index,
2778 client_session_index, rv, vppcom_retval_str (rv));
2779 goto done;
2780 }
Dave Wallace543852a2017-08-03 02:11:34 -04002781
Dave Wallace227867f2017-11-13 21:21:53 -05002782 client_session->is_nonblocking = (flags & O_NONBLOCK) ? 1 : 0;
Dave Wallace543852a2017-08-03 02:11:34 -04002783 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002784 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: Got a client request! "
Dave Wallaceee45d412017-11-24 21:44:06 -05002785 "vpp handle 0x%llx, sid %u, flags %d, is_nonblocking %u",
2786 getpid (), listen_vpp_handle, listen_session_index,
2787 client_session->vpp_handle, client_session_index,
Dave Wallace227867f2017-11-13 21:21:53 -05002788 flags, client_session->is_nonblocking);
Dave Wallace543852a2017-08-03 02:11:34 -04002789
Dave Wallace048b1d62018-01-03 22:24:41 -05002790 if (ep)
2791 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002792 ep->is_cut_thru = client_session->is_cut_thru;
2793 ep->is_ip4 = client_session->peer_addr.is_ip4;
2794 ep->port = client_session->peer_port;
2795 if (client_session->peer_addr.is_ip4)
2796 clib_memcpy (ep->ip, &client_session->peer_addr.ip46.ip4,
2797 sizeof (ip4_address_t));
2798 else
2799 clib_memcpy (ep->ip, &client_session->peer_addr.ip46.ip6,
2800 sizeof (ip6_address_t));
2801 }
Dave Wallace60caa062017-11-10 17:07:13 -05002802
2803 if (client_session->is_server && client_session->is_cut_thru)
2804 {
2805 static svm_fifo_segment_create_args_t _a;
2806 svm_fifo_segment_create_args_t *a = &_a;
2807 svm_fifo_segment_private_t *seg;
2808
Dave Wallace4878cbe2017-11-21 03:45:09 -05002809 cut_thru_str = " cut-thru ";
Dave Wallace60caa062017-11-10 17:07:13 -05002810
2811 /* Create the segment */
2812 memset (a, 0, sizeof (*a));
2813 a->segment_name = (char *)
2814 format ((u8 *) a->segment_name, "%d:segment%d%c",
2815 getpid (), vcm->unique_segment_index++, 0);
2816 a->segment_size = vcm->cfg.segment_size;
Dave Wallace60caa062017-11-10 17:07:13 -05002817
2818 rv = svm_fifo_segment_create (a);
2819 if (PREDICT_FALSE (rv))
2820 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002821 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -05002822 "client sid %u svm_fifo_segment_create ('%s') "
2823 "failed! rv %d", getpid (), listen_vpp_handle,
2824 listen_session_index, client_session_index,
2825 a->segment_name, rv);
Dave Wallace60caa062017-11-10 17:07:13 -05002826 vec_reset_length (a->new_segment_indices);
2827 rv = VNET_API_ERROR_URI_FIFO_CREATE_FAILED;
Dave Wallaceee45d412017-11-24 21:44:06 -05002828 vppcom_send_connect_session_reply (client_session,
Dave Wallaced2931962017-11-25 04:17:39 -05002829 client_session_index,
2830 client_session->vpp_handle,
2831 client_session->client_context,
2832 rv);
Dave Wallace60caa062017-11-10 17:07:13 -05002833 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002834 rv = VPPCOM_ENOMEM;
2835 goto done;
Dave Wallace60caa062017-11-10 17:07:13 -05002836 }
2837
2838 client_session->segment_name = vec_dup ((u8 *) a->segment_name);
2839 client_session->sm_seg_index = a->new_segment_indices[0];
2840 vec_free (a->new_segment_indices);
2841
2842 seg = svm_fifo_segment_get_segment (client_session->sm_seg_index);
Florin Corasa332c462018-01-31 06:52:17 -08002843 if (vcm->cfg.preallocated_fifo_pairs)
2844 {
2845 n_fifos = vcm->cfg.preallocated_fifo_pairs;
2846 svm_fifo_segment_preallocate_fifo_pairs (seg, vcm->cfg.rx_fifo_size,
2847 vcm->cfg.tx_fifo_size,
2848 &n_fifos);
2849 }
2850
Dave Wallace60caa062017-11-10 17:07:13 -05002851 client_session->server_rx_fifo =
2852 svm_fifo_segment_alloc_fifo (seg, vcm->cfg.rx_fifo_size,
2853 FIFO_SEGMENT_RX_FREELIST);
2854 if (PREDICT_FALSE (!client_session->server_rx_fifo))
2855 {
2856 svm_fifo_segment_delete (seg);
Dave Wallace048b1d62018-01-03 22:24:41 -05002857 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -05002858 "client sid %u rx fifo alloc failed! "
2859 "size %ld (0x%lx)", getpid (), listen_vpp_handle,
2860 listen_session_index, client_session_index,
Dave Wallace4878cbe2017-11-21 03:45:09 -05002861 vcm->cfg.rx_fifo_size, vcm->cfg.rx_fifo_size);
Dave Wallace60caa062017-11-10 17:07:13 -05002862 rv = VNET_API_ERROR_URI_FIFO_CREATE_FAILED;
Dave Wallaceee45d412017-11-24 21:44:06 -05002863 vppcom_send_connect_session_reply (client_session,
Dave Wallaced2931962017-11-25 04:17:39 -05002864 client_session_index,
2865 client_session->vpp_handle,
2866 client_session->client_context,
2867 rv);
Dave Wallace60caa062017-11-10 17:07:13 -05002868 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002869 rv = VPPCOM_ENOMEM;
2870 goto done;
Dave Wallace60caa062017-11-10 17:07:13 -05002871 }
2872 client_session->server_rx_fifo->master_session_index =
2873 client_session_index;
2874
2875 client_session->server_tx_fifo =
2876 svm_fifo_segment_alloc_fifo (seg, vcm->cfg.tx_fifo_size,
2877 FIFO_SEGMENT_TX_FREELIST);
2878 if (PREDICT_FALSE (!client_session->server_tx_fifo))
2879 {
2880 svm_fifo_segment_delete (seg);
Dave Wallace048b1d62018-01-03 22:24:41 -05002881 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -05002882 "client sid %u tx fifo alloc failed! "
2883 "size %ld (0x%lx)", getpid (), listen_vpp_handle,
2884 listen_session_index, client_session_index,
Dave Wallace4878cbe2017-11-21 03:45:09 -05002885 vcm->cfg.tx_fifo_size, vcm->cfg.tx_fifo_size);
Dave Wallace60caa062017-11-10 17:07:13 -05002886 rv = VNET_API_ERROR_URI_FIFO_CREATE_FAILED;
Dave Wallaceee45d412017-11-24 21:44:06 -05002887 vppcom_send_connect_session_reply (client_session,
Dave Wallaced2931962017-11-25 04:17:39 -05002888 client_session_index,
2889 client_session->vpp_handle,
2890 client_session->client_context,
2891 rv);
Dave Wallace60caa062017-11-10 17:07:13 -05002892 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002893 rv = VPPCOM_ENOMEM;
2894 goto done;
Dave Wallace60caa062017-11-10 17:07:13 -05002895 }
2896 client_session->server_tx_fifo->master_session_index =
2897 client_session_index;
2898
2899 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002900 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: client sid %u "
Dave Wallaceee45d412017-11-24 21:44:06 -05002901 "created segment '%s', rx_fifo %p, tx_fifo %p",
2902 getpid (), listen_vpp_handle, listen_session_index,
2903 client_session_index, client_session->segment_name,
Dave Wallace60caa062017-11-10 17:07:13 -05002904 client_session->server_rx_fifo,
2905 client_session->server_tx_fifo);
2906
2907#ifdef CUT_THRU_EVENT_QUEUE /* TBD */
2908 {
2909 void *oldheap;
2910 ssvm_shared_header_t *sh = seg->ssvm.sh;
2911
2912 ssvm_lock_non_recursive (sh, 1);
2913 oldheap = ssvm_push_heap (sh);
2914 event_q = client_session->vpp_event_queue =
Florin Corase86a8ed2018-01-05 03:20:25 -08002915 svm_queue_init (vcm->cfg.event_queue_size,
2916 sizeof (session_fifo_event_t),
2917 getpid (), 0 /* signal not sent */ );
Dave Wallace60caa062017-11-10 17:07:13 -05002918 ssvm_pop_heap (oldheap);
2919 ssvm_unlock_non_recursive (sh);
2920 }
2921#endif
Dave Wallaceee45d412017-11-24 21:44:06 -05002922 vppcom_send_connect_session_reply (client_session,
2923 client_session_index,
Dave Wallaced2931962017-11-25 04:17:39 -05002924 client_session->vpp_handle,
2925 client_session->client_context,
Dave Wallaceee45d412017-11-24 21:44:06 -05002926 0 /* retval OK */ );
Dave Wallace60caa062017-11-10 17:07:13 -05002927 }
2928 else
2929 {
2930 cut_thru_str = " ";
Dave Wallaced2931962017-11-25 04:17:39 -05002931 vppcom_send_accept_session_reply (client_session->vpp_handle,
2932 client_session->client_context,
2933 0 /* retval OK */ );
Dave Wallace60caa062017-11-10 17:07:13 -05002934 }
2935
Stevenac1f96d2017-10-24 16:03:58 -07002936 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002937 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: accepted vpp handle "
Dave Wallaceee45d412017-11-24 21:44:06 -05002938 "0x%llx, sid %u%sconnection to local %s address "
2939 "%U port %u", getpid (), listen_vpp_handle,
2940 listen_session_index, client_session->vpp_handle,
2941 client_session_index, cut_thru_str,
Dave Wallace4878cbe2017-11-21 03:45:09 -05002942 client_session->lcl_addr.is_ip4 ? "IPv4" : "IPv6",
2943 format_ip46_address, &client_session->lcl_addr.ip46,
2944 client_session->lcl_addr.is_ip4,
2945 clib_net_to_host_u16 (client_session->lcl_port));
Dave Wallace60caa062017-11-10 17:07:13 -05002946
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002947 if (VPPCOM_DEBUG > 0)
2948 {
2949 client_session->elog_track.name =
2950 (char *) format (0, "C:%d:S:%d%c", vcm->my_client_index,
2951 client_session_index, 0);
2952 elog_track_register (&vcm->elog_main, &client_session->elog_track);
2953
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002954 /* *INDENT-OFF* */
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002955 ELOG_TYPE_DECLARE (e) =
2956 {
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002957 .format = "accept cut-thru: listen_handle:%x from_handle:%x",
2958 .format_args = "i8i8",
2959 };
2960
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002961 struct
2962 {
2963 u64 handle[2];
2964 } *ed;
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002965
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002966 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, client_session->elog_track);
2967 ed->handle[0] = listen_vpp_handle;
2968 ed->handle[1] = client_session->vpp_handle;
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002969 /* *INDENT-ON* */
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002970
2971 if (client_session->lcl_addr.is_ip4)
2972 {
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002973 /* *INDENT-OFF* */
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002974 ELOG_TYPE_DECLARE (e2) =
2975 {
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002976 .format = "accept cut-thru: S:%d %d.%d.%d.%d:%d ",
2977 .format_args = "i4i1i1i1i1i2",
2978 };
2979
2980 CLIB_PACKED (struct {
2981 u32 session;
2982 u8 addr[4];
2983 u16 port;
2984 }) * ed2;
2985
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002986 ed2 =
2987 ELOG_TRACK_DATA (&vcm->elog_main, e2, client_session->elog_track);
2988 ed2->session = client_session_index;
2989 ed2->addr[0] = client_session->lcl_addr.ip46.ip4.as_u8[0];
2990 ed2->addr[1] = client_session->lcl_addr.ip46.ip4.as_u8[1];
2991 ed2->addr[2] = client_session->lcl_addr.ip46.ip4.as_u8[2];
2992 ed2->addr[3] = client_session->lcl_addr.ip46.ip4.as_u8[3];
2993 ed2->port = clib_net_to_host_u16 (client_session->lcl_port);
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002994 /* *INDENT-ON* */
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002995 }
2996 }
2997
Dave Wallace543852a2017-08-03 02:11:34 -04002998 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002999 rv = (int) client_session_index;
3000done:
3001 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04003002}
3003
3004int
3005vppcom_session_connect (uint32_t session_index, vppcom_endpt_t * server_ep)
3006{
Dave Wallace543852a2017-08-03 02:11:34 -04003007 session_t *session = 0;
Dave Wallaceee45d412017-11-24 21:44:06 -05003008 int rv, retval = VPPCOM_OK;
3009 u64 vpp_handle = ~0;
Dave Wallace543852a2017-08-03 02:11:34 -04003010
Dave Wallace4878cbe2017-11-21 03:45:09 -05003011 VCL_LOCK_AND_GET_SESSION (session_index, &session);
3012
3013 if (PREDICT_FALSE (session->is_vep))
Dave Wallace543852a2017-08-03 02:11:34 -04003014 {
3015 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace048b1d62018-01-03 22:24:41 -05003016 clib_warning ("VCL<%d>: ERROR: sid %u: cannot "
3017 "connect on an epoll session!", getpid (), session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -05003018 rv = VPPCOM_EBADFD;
3019 goto done;
Dave Wallace543852a2017-08-03 02:11:34 -04003020 }
3021
Dave Wallaceee45d412017-11-24 21:44:06 -05003022 vpp_handle = session->vpp_handle;
Dave Wallace4878cbe2017-11-21 03:45:09 -05003023 if (PREDICT_FALSE (session->is_server))
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003024 {
3025 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace048b1d62018-01-03 22:24:41 -05003026 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: is in use "
Dave Wallaceee45d412017-11-24 21:44:06 -05003027 "as a server session!", getpid (), vpp_handle,
3028 session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -05003029 rv = VPPCOM_EBADFD;
3030 goto done;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003031 }
3032
Dave Wallace4878cbe2017-11-21 03:45:09 -05003033 if (PREDICT_FALSE (session->state & CLIENT_STATE_OPEN))
Dave Wallace543852a2017-08-03 02:11:34 -04003034 {
Dave Wallace543852a2017-08-03 02:11:34 -04003035 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05003036 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: session already "
Dave Wallaceee45d412017-11-24 21:44:06 -05003037 "connected to %s %U port %d proto %s, state 0x%x (%s)",
3038 getpid (), vpp_handle, session_index,
Dave Wallace4878cbe2017-11-21 03:45:09 -05003039 session->peer_addr.is_ip4 ? "IPv4" : "IPv6",
3040 format_ip46_address,
3041 &session->peer_addr.ip46, session->peer_addr.is_ip4,
3042 clib_net_to_host_u16 (session->peer_port),
3043 session->proto ? "UDP" : "TCP", session->state,
3044 vppcom_session_state_str (session->state));
3045
3046 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace4878cbe2017-11-21 03:45:09 -05003047 goto done;
Dave Wallace543852a2017-08-03 02:11:34 -04003048 }
3049
Dave Wallace35830af2017-10-09 01:43:42 -04003050 session->peer_addr.is_ip4 = server_ep->is_ip4;
3051 session->peer_addr.ip46 = to_ip46 (!server_ep->is_ip4, server_ep->ip);
Stevenac1f96d2017-10-24 16:03:58 -07003052 session->peer_port = server_ep->port;
Dave Wallace543852a2017-08-03 02:11:34 -04003053
3054 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05003055 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: connecting to server "
Dave Wallaceee45d412017-11-24 21:44:06 -05003056 "%s %U port %d proto %s",
3057 getpid (), vpp_handle, session_index,
Dave Wallace4878cbe2017-11-21 03:45:09 -05003058 session->peer_addr.is_ip4 ? "IPv4" : "IPv6",
3059 format_ip46_address,
3060 &session->peer_addr.ip46, session->peer_addr.is_ip4,
3061 clib_net_to_host_u16 (session->peer_port),
3062 session->proto ? "UDP" : "TCP");
Dave Wallace543852a2017-08-03 02:11:34 -04003063
3064 vppcom_send_connect_sock (session, session_index);
3065 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace4878cbe2017-11-21 03:45:09 -05003066
Dave Wallaceee45d412017-11-24 21:44:06 -05003067 retval =
3068 vppcom_wait_for_session_state_change (session_index, STATE_CONNECT,
3069 vcm->cfg.session_timeout);
3070
3071 VCL_LOCK_AND_GET_SESSION (session_index, &session);
3072 vpp_handle = session->vpp_handle;
3073 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace7876d392017-10-19 03:53:57 -04003074
Dave Wallace4878cbe2017-11-21 03:45:09 -05003075done:
Dave Wallaceee45d412017-11-24 21:44:06 -05003076 if (PREDICT_FALSE (retval))
3077 {
3078 rv = retval;
3079 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05003080 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: connect failed! "
Dave Wallaceee45d412017-11-24 21:44:06 -05003081 "returning %d (%s)", getpid (), vpp_handle,
3082 session_index, rv, vppcom_retval_str (rv));
3083 }
3084 else if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05003085 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: connected!",
Dave Wallaceee45d412017-11-24 21:44:06 -05003086 getpid (), vpp_handle, session_index);
3087
Dave Wallace4878cbe2017-11-21 03:45:09 -05003088 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04003089}
3090
Steven58f464e2017-10-25 12:33:12 -07003091static inline int
3092vppcom_session_read_internal (uint32_t session_index, void *buf, int n,
3093 u8 peek)
Dave Wallace543852a2017-08-03 02:11:34 -04003094{
Dave Wallace543852a2017-08-03 02:11:34 -04003095 session_t *session = 0;
3096 svm_fifo_t *rx_fifo;
3097 int n_read = 0;
3098 int rv;
3099 char *fifo_str;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003100 u32 poll_et;
Dave Wallace4878cbe2017-11-21 03:45:09 -05003101 session_state_t state;
3102 u8 is_server;
3103 u8 is_nonblocking;
Dave Wallaceee45d412017-11-24 21:44:06 -05003104 u64 vpp_handle;
Dave Wallace543852a2017-08-03 02:11:34 -04003105
3106 ASSERT (buf);
3107
Dave Wallace4878cbe2017-11-21 03:45:09 -05003108 VCL_LOCK_AND_GET_SESSION (session_index, &session);
3109
3110 if (PREDICT_FALSE (session->is_vep))
Dave Wallace543852a2017-08-03 02:11:34 -04003111 {
3112 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace048b1d62018-01-03 22:24:41 -05003113 clib_warning ("VCL<%d>: ERROR: sid %u: cannot "
3114 "read from an epoll session!", getpid (), session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -05003115 rv = VPPCOM_EBADFD;
3116 goto done;
Dave Wallace543852a2017-08-03 02:11:34 -04003117 }
3118
Dave Wallaceee45d412017-11-24 21:44:06 -05003119 vpp_handle = session->vpp_handle;
Dave Wallace4878cbe2017-11-21 03:45:09 -05003120 is_server = session->is_server;
3121 is_nonblocking = session->is_nonblocking;
3122 state = session->state;
3123 if (PREDICT_FALSE (!(state & (SERVER_STATE_OPEN | CLIENT_STATE_OPEN))))
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003124 {
3125 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace4878cbe2017-11-21 03:45:09 -05003126 rv = ((state == STATE_DISCONNECT) ?
3127 VPPCOM_ECONNRESET : VPPCOM_ENOTCONN);
3128
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003129 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05003130 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: %s session is "
Dave Wallaceee45d412017-11-24 21:44:06 -05003131 "not open! state 0x%x (%s), returning %d (%s)",
3132 getpid (), vpp_handle, session_index,
3133 is_server ? "server" : "client", state,
Dave Wallace4878cbe2017-11-21 03:45:09 -05003134 vppcom_session_state_str (state),
3135 rv, vppcom_retval_str (rv));
3136 goto done;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003137 }
3138
Dave Wallace4878cbe2017-11-21 03:45:09 -05003139 rx_fifo = ((!session->is_cut_thru || is_server) ?
Dave Wallace33e002b2017-09-06 01:20:02 -04003140 session->server_rx_fifo : session->server_tx_fifo);
Dave Wallace4878cbe2017-11-21 03:45:09 -05003141 fifo_str = ((!session->is_cut_thru || is_server) ?
Dave Wallace33e002b2017-09-06 01:20:02 -04003142 "server_rx_fifo" : "server_tx_fifo");
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003143 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003144
3145 do
3146 {
Steven58f464e2017-10-25 12:33:12 -07003147 if (peek)
3148 n_read = svm_fifo_peek (rx_fifo, 0, n, buf);
3149 else
3150 n_read = svm_fifo_dequeue_nowait (rx_fifo, n, buf);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003151 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05003152 while (!is_nonblocking && (n_read <= 0));
Dave Wallacef7f809c2017-10-03 01:48:42 -04003153
Dave Wallace4878cbe2017-11-21 03:45:09 -05003154 if (n_read <= 0)
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003155 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05003156 VCL_LOCK_AND_GET_SESSION (session_index, &session);
3157
3158 poll_et = (((EPOLLET | EPOLLIN) & session->vep.ev.events) ==
3159 (EPOLLET | EPOLLIN));
3160 if (poll_et)
3161 session->vep.et_mask |= EPOLLIN;
3162
3163 if (state == STATE_CLOSE_ON_EMPTY)
3164 {
3165 session_state_t new_state = STATE_DISCONNECT;
3166 rv = VPPCOM_ECONNRESET;
3167
3168 if (VPPCOM_DEBUG > 1)
3169 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003170 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: Empty fifo "
Dave Wallaceee45d412017-11-24 21:44:06 -05003171 "with %s session state 0x%x (%s)!"
3172 " Setting state to 0x%x (%s), returning %d (%s)",
3173 getpid (), vpp_handle, session_index,
Dave Wallace4878cbe2017-11-21 03:45:09 -05003174 is_server ? "server" : "client",
3175 state, vppcom_session_state_str (state),
3176 new_state, vppcom_session_state_str (new_state),
3177 rv, vppcom_retval_str (rv));
3178 }
3179
3180 session->state = new_state;
3181 }
3182 else
3183 rv = VPPCOM_EAGAIN;
3184
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003185 clib_spinlock_unlock (&vcm->sessions_lockp);
3186 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05003187 else
3188 rv = n_read;
Dave Wallace543852a2017-08-03 02:11:34 -04003189
Dave Wallace4878cbe2017-11-21 03:45:09 -05003190 if (VPPCOM_DEBUG > 2)
3191 {
3192 if (rv > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05003193 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: read %d bytes "
Dave Wallaceee45d412017-11-24 21:44:06 -05003194 "from %s (%p)", getpid (), vpp_handle,
Dave Wallace4878cbe2017-11-21 03:45:09 -05003195 session_index, n_read, fifo_str, rx_fifo);
3196 else
Dave Wallace048b1d62018-01-03 22:24:41 -05003197 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: nothing read! "
Dave Wallaceee45d412017-11-24 21:44:06 -05003198 "returning %d (%s)", getpid (), vpp_handle,
3199 session_index, rv, vppcom_retval_str (rv));
Dave Wallace4878cbe2017-11-21 03:45:09 -05003200 }
3201done:
3202 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04003203}
3204
Steven58f464e2017-10-25 12:33:12 -07003205int
Dave Wallace048b1d62018-01-03 22:24:41 -05003206vppcom_session_read (uint32_t session_index, void *buf, size_t n)
Steven58f464e2017-10-25 12:33:12 -07003207{
3208 return (vppcom_session_read_internal (session_index, buf, n, 0));
3209}
3210
3211static int
3212vppcom_session_peek (uint32_t session_index, void *buf, int n)
3213{
3214 return (vppcom_session_read_internal (session_index, buf, n, 1));
3215}
3216
Dave Wallace543852a2017-08-03 02:11:34 -04003217static inline int
3218vppcom_session_read_ready (session_t * session, u32 session_index)
3219{
Dave Wallace498b3a52017-11-09 13:00:34 -05003220 svm_fifo_t *rx_fifo = 0;
Dave Wallace543852a2017-08-03 02:11:34 -04003221 int ready = 0;
Dave Wallace60caa062017-11-10 17:07:13 -05003222 u32 poll_et;
Dave Wallace4878cbe2017-11-21 03:45:09 -05003223 int rv;
3224 u8 is_server = session->is_server;
3225 session_state_t state = session->state;
Dave Wallaceee45d412017-11-24 21:44:06 -05003226 u64 vpp_handle = session->vpp_handle;
Dave Wallace543852a2017-08-03 02:11:34 -04003227
3228 /* Assumes caller has acquired spinlock: vcm->sessions_lockp */
Dave Wallace4878cbe2017-11-21 03:45:09 -05003229 if (PREDICT_FALSE (session->is_vep))
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003230 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003231 clib_warning ("VCL<%d>: ERROR: sid %u: cannot read from an "
Dave Wallace4878cbe2017-11-21 03:45:09 -05003232 "epoll session!", getpid (), session_index);
3233 rv = VPPCOM_EBADFD;
3234 goto done;
Dave Wallace543852a2017-08-03 02:11:34 -04003235 }
Dave Wallace33e002b2017-09-06 01:20:02 -04003236
3237 if (session->is_listen)
Dave Wallace543852a2017-08-03 02:11:34 -04003238 ready = clib_fifo_elts (vcm->client_session_index_fifo);
3239 else
3240 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05003241 if (!(state & (SERVER_STATE_OPEN | CLIENT_STATE_OPEN | STATE_LISTEN)))
3242 {
3243 rv = ((state == STATE_DISCONNECT) ? VPPCOM_ECONNRESET :
3244 VPPCOM_ENOTCONN);
3245
3246 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05003247 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: %s session is "
Dave Wallaceee45d412017-11-24 21:44:06 -05003248 "not open! state 0x%x (%s), returning %d (%s)",
3249 getpid (), vpp_handle, session_index,
3250 is_server ? "server" : "client",
Dave Wallace4878cbe2017-11-21 03:45:09 -05003251 state, vppcom_session_state_str (state),
3252 rv, vppcom_retval_str (rv));
3253 goto done;
3254 }
3255
3256 rx_fifo = ((!session->is_cut_thru || is_server) ?
Dave Wallace33e002b2017-09-06 01:20:02 -04003257 session->server_rx_fifo : session->server_tx_fifo);
Dave Wallace543852a2017-08-03 02:11:34 -04003258
Dave Wallace33e002b2017-09-06 01:20:02 -04003259 ready = svm_fifo_max_dequeue (rx_fifo);
Dave Wallace543852a2017-08-03 02:11:34 -04003260 }
3261
Dave Wallace4878cbe2017-11-21 03:45:09 -05003262 if (ready == 0)
Dave Wallace60caa062017-11-10 17:07:13 -05003263 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05003264 poll_et =
3265 ((EPOLLET | EPOLLIN) & session->vep.ev.events) == (EPOLLET | EPOLLIN);
3266 if (poll_et)
3267 session->vep.et_mask |= EPOLLIN;
Dave Wallace60caa062017-11-10 17:07:13 -05003268
Dave Wallace4878cbe2017-11-21 03:45:09 -05003269 if (state == STATE_CLOSE_ON_EMPTY)
3270 {
3271 rv = VPPCOM_ECONNRESET;
3272 session_state_t new_state = STATE_DISCONNECT;
3273
3274 if (VPPCOM_DEBUG > 1)
3275 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003276 clib_warning ("VCL<%d>: vpp handle 0x%llx, "
3277 "sid %u: Empty fifo with"
Dave Wallaceee45d412017-11-24 21:44:06 -05003278 " %s session state 0x%x (%s)! Setting state to "
3279 "0x%x (%s), returning %d (%s)",
3280 getpid (), session_index, vpp_handle,
Dave Wallace4878cbe2017-11-21 03:45:09 -05003281 is_server ? "server" : "client",
3282 state, vppcom_session_state_str (state),
3283 new_state, vppcom_session_state_str (new_state),
3284 rv, vppcom_retval_str (rv));
3285 }
3286 session->state = new_state;
3287 goto done;
3288 }
3289 }
3290 rv = ready;
Dave Wallace16cb4082017-11-29 03:24:06 -05003291
3292 if (vcm->app_event_queue->cursize &&
3293 !pthread_mutex_trylock (&vcm->app_event_queue->mutex))
3294 {
3295 u32 i, n_to_dequeue = vcm->app_event_queue->cursize;
3296 session_fifo_event_t e;
3297
3298 for (i = 0; i < n_to_dequeue; i++)
Florin Corase86a8ed2018-01-05 03:20:25 -08003299 svm_queue_sub_raw (vcm->app_event_queue, (u8 *) & e);
Dave Wallace16cb4082017-11-29 03:24:06 -05003300
3301 pthread_mutex_unlock (&vcm->app_event_queue->mutex);
3302 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05003303done:
3304 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04003305}
3306
3307int
Dave Wallace048b1d62018-01-03 22:24:41 -05003308vppcom_session_write (uint32_t session_index, void *buf, size_t n)
Dave Wallace543852a2017-08-03 02:11:34 -04003309{
Dave Wallace543852a2017-08-03 02:11:34 -04003310 session_t *session = 0;
3311 svm_fifo_t *tx_fifo;
Florin Corase86a8ed2018-01-05 03:20:25 -08003312 svm_queue_t *q;
Dave Wallace543852a2017-08-03 02:11:34 -04003313 session_fifo_event_t evt;
Dave Wallacef7f809c2017-10-03 01:48:42 -04003314 int rv, n_write;
Dave Wallace543852a2017-08-03 02:11:34 -04003315 char *fifo_str;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003316 u32 poll_et;
Dave Wallace4878cbe2017-11-21 03:45:09 -05003317 u8 is_server;
3318 u8 is_nonblocking;
3319 session_state_t state;
Dave Wallaceee45d412017-11-24 21:44:06 -05003320 u64 vpp_handle;
Dave Wallace543852a2017-08-03 02:11:34 -04003321
3322 ASSERT (buf);
3323
Dave Wallace4878cbe2017-11-21 03:45:09 -05003324 VCL_LOCK_AND_GET_SESSION (session_index, &session);
3325
3326 if (PREDICT_FALSE (session->is_vep))
Dave Wallace543852a2017-08-03 02:11:34 -04003327 {
3328 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace048b1d62018-01-03 22:24:41 -05003329 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -05003330 "cannot write to an epoll session!",
3331 getpid (), session->vpp_handle, session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -05003332
3333 rv = VPPCOM_EBADFD;
3334 goto done;
Dave Wallace543852a2017-08-03 02:11:34 -04003335 }
3336
Dave Wallace4878cbe2017-11-21 03:45:09 -05003337 is_server = session->is_server;
3338 is_nonblocking = session->is_nonblocking;
Dave Wallaceee45d412017-11-24 21:44:06 -05003339 vpp_handle = session->vpp_handle;
Dave Wallace4878cbe2017-11-21 03:45:09 -05003340 state = session->state;
3341 if (!(state & (SERVER_STATE_OPEN | CLIENT_STATE_OPEN)))
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003342 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05003343 rv = ((state == STATE_DISCONNECT) ? VPPCOM_ECONNRESET :
3344 VPPCOM_ENOTCONN);
3345
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003346 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace4878cbe2017-11-21 03:45:09 -05003347 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05003348 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -05003349 "%s session is not open! state 0x%x (%s)",
3350 getpid (), vpp_handle, session_index,
3351 is_server ? "server" : "client", state,
Dave Wallace4878cbe2017-11-21 03:45:09 -05003352 vppcom_session_state_str (state));
3353 goto done;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003354 }
3355
Dave Wallace4878cbe2017-11-21 03:45:09 -05003356 tx_fifo = ((!session->is_cut_thru || is_server) ?
Dave Wallace543852a2017-08-03 02:11:34 -04003357 session->server_tx_fifo : session->server_rx_fifo);
Dave Wallace4878cbe2017-11-21 03:45:09 -05003358 fifo_str = ((!session->is_cut_thru || is_server) ?
Dave Wallace543852a2017-08-03 02:11:34 -04003359 "server_tx_fifo" : "server_rx_fifo");
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003360 clib_spinlock_unlock (&vcm->sessions_lockp);
3361
Dave Wallace543852a2017-08-03 02:11:34 -04003362 do
3363 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003364 n_write = svm_fifo_enqueue_nowait (tx_fifo, n, (void *) buf);
Dave Wallace543852a2017-08-03 02:11:34 -04003365 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05003366 while (!is_nonblocking && (n_write <= 0));
Dave Wallace543852a2017-08-03 02:11:34 -04003367
3368 /* If event wasn't set, add one */
Dave Wallacef7f809c2017-10-03 01:48:42 -04003369 if (!session->is_cut_thru && (n_write > 0) && svm_fifo_set_event (tx_fifo))
Dave Wallace543852a2017-08-03 02:11:34 -04003370 {
Dave Wallace543852a2017-08-03 02:11:34 -04003371 /* Fabricate TX event, send to vpp */
3372 evt.fifo = tx_fifo;
3373 evt.event_type = FIFO_EVENT_APP_TX;
Dave Wallace543852a2017-08-03 02:11:34 -04003374
Dave Wallace4878cbe2017-11-21 03:45:09 -05003375 VCL_LOCK_AND_GET_SESSION (session_index, &session);
3376 q = session->vpp_event_queue;
Dave Wallace543852a2017-08-03 02:11:34 -04003377 ASSERT (q);
Florin Corase86a8ed2018-01-05 03:20:25 -08003378 svm_queue_add (q, (u8 *) & evt, 0 /* do wait for mutex */ );
Dave Wallace4878cbe2017-11-21 03:45:09 -05003379 clib_spinlock_unlock (&vcm->sessions_lockp);
3380 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05003381 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -05003382 "added FIFO_EVENT_APP_TX to "
Dave Wallace4878cbe2017-11-21 03:45:09 -05003383 "vpp_event_q %p, n_write %d", getpid (),
Dave Wallaceee45d412017-11-24 21:44:06 -05003384 vpp_handle, session_index, q, n_write);
Dave Wallace543852a2017-08-03 02:11:34 -04003385 }
3386
Dave Wallace4878cbe2017-11-21 03:45:09 -05003387 if (n_write <= 0)
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003388 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05003389 VCL_LOCK_AND_GET_SESSION (session_index, &session);
3390
3391 poll_et = (((EPOLLET | EPOLLOUT) & session->vep.ev.events) ==
3392 (EPOLLET | EPOLLOUT));
3393 if (poll_et)
3394 session->vep.et_mask |= EPOLLOUT;
3395
3396 if (state == STATE_CLOSE_ON_EMPTY)
3397 {
3398 session_state_t new_state = STATE_DISCONNECT;
3399 rv = VPPCOM_ECONNRESET;
3400
3401 if (VPPCOM_DEBUG > 1)
3402 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003403 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -05003404 "Empty fifo with %s session state 0x%x (%s)!"
3405 " Setting state to 0x%x (%s), returning %d (%s)",
3406 getpid (), vpp_handle, session_index,
Dave Wallace4878cbe2017-11-21 03:45:09 -05003407 is_server ? "server" : "client",
3408 state, vppcom_session_state_str (state),
3409 new_state, vppcom_session_state_str (new_state),
3410 rv, vppcom_retval_str (rv));
3411 }
3412
3413 session->state = new_state;
3414 }
3415 else
3416 rv = VPPCOM_EAGAIN;
3417
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003418 clib_spinlock_unlock (&vcm->sessions_lockp);
3419 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05003420 else
3421 rv = n_write;
Dave Wallacef7f809c2017-10-03 01:48:42 -04003422
Dave Wallace543852a2017-08-03 02:11:34 -04003423 if (VPPCOM_DEBUG > 2)
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003424 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05003425 if (n_write <= 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05003426 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -05003427 "FIFO-FULL %s (%p)", getpid (), vpp_handle,
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003428 session_index, fifo_str, tx_fifo);
3429 else
Dave Wallace048b1d62018-01-03 22:24:41 -05003430 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -05003431 "wrote %d bytes to %s (%p)", getpid (), vpp_handle,
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003432 session_index, n_write, fifo_str, tx_fifo);
3433 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05003434done:
3435 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04003436}
3437
3438static inline int
3439vppcom_session_write_ready (session_t * session, u32 session_index)
3440{
Dave Wallace543852a2017-08-03 02:11:34 -04003441 svm_fifo_t *tx_fifo;
Dave Wallace33e002b2017-09-06 01:20:02 -04003442 char *fifo_str;
Dave Wallacef7f809c2017-10-03 01:48:42 -04003443 int ready;
Dave Wallace60caa062017-11-10 17:07:13 -05003444 u32 poll_et;
Dave Wallace4878cbe2017-11-21 03:45:09 -05003445 int rv;
3446 u8 is_server = session->is_server;
3447 session_state_t state = session->state;
Dave Wallace543852a2017-08-03 02:11:34 -04003448
3449 /* Assumes caller has acquired spinlock: vcm->sessions_lockp */
Dave Wallace4878cbe2017-11-21 03:45:09 -05003450 if (PREDICT_FALSE (session->is_vep))
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003451 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003452 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -05003453 "cannot write to an epoll session!",
3454 getpid (), session->vpp_handle, session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -05003455 rv = VPPCOM_EBADFD;
3456 goto done;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003457 }
3458
Dave Wallace4878cbe2017-11-21 03:45:09 -05003459 if (PREDICT_FALSE (session->is_listen))
Dave Wallace33e002b2017-09-06 01:20:02 -04003460 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003461 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -05003462 "cannot write to a listen session!",
3463 getpid (), session->vpp_handle, session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -05003464 rv = VPPCOM_EBADFD;
3465 goto done;
3466 }
3467
3468 if (!(state & (SERVER_STATE_OPEN | CLIENT_STATE_OPEN)))
3469 {
3470 session_state_t state = session->state;
3471
3472 rv = ((state == STATE_DISCONNECT) ? VPPCOM_ECONNRESET :
3473 VPPCOM_ENOTCONN);
3474
Dave Wallace048b1d62018-01-03 22:24:41 -05003475 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -05003476 "%s session is not open! state 0x%x (%s), "
3477 "returning %d (%s)", getpid (), session->vpp_handle,
Dave Wallace4878cbe2017-11-21 03:45:09 -05003478 session_index, is_server ? "server" : "client",
3479 state, vppcom_session_state_str (state),
3480 rv, vppcom_retval_str (rv));
3481 goto done;
Dave Wallace33e002b2017-09-06 01:20:02 -04003482 }
3483
Dave Wallace543852a2017-08-03 02:11:34 -04003484 tx_fifo = ((!session->is_cut_thru || session->is_server) ?
3485 session->server_tx_fifo : session->server_rx_fifo);
Dave Wallace33e002b2017-09-06 01:20:02 -04003486 fifo_str = ((!session->is_cut_thru || session->is_server) ?
3487 "server_tx_fifo" : "server_rx_fifo");
Dave Wallace543852a2017-08-03 02:11:34 -04003488
Dave Wallacef7f809c2017-10-03 01:48:42 -04003489 ready = svm_fifo_max_enqueue (tx_fifo);
Dave Wallace543852a2017-08-03 02:11:34 -04003490
Dave Wallace33e002b2017-09-06 01:20:02 -04003491 if (VPPCOM_DEBUG > 3)
Dave Wallace048b1d62018-01-03 22:24:41 -05003492 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -05003493 "peek %s (%p), ready = %d", getpid (),
3494 session->vpp_handle, session_index,
3495 fifo_str, tx_fifo, ready);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003496
Dave Wallace4878cbe2017-11-21 03:45:09 -05003497 if (ready == 0)
3498 {
3499 poll_et = (((EPOLLET | EPOLLOUT) & session->vep.ev.events) ==
3500 (EPOLLET | EPOLLOUT));
3501 if (poll_et)
3502 session->vep.et_mask |= EPOLLOUT;
3503
3504 if (state == STATE_CLOSE_ON_EMPTY)
3505 {
3506 rv = VPPCOM_ECONNRESET;
3507 session_state_t new_state = STATE_DISCONNECT;
3508
3509 if (VPPCOM_DEBUG > 1)
3510 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003511 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -05003512 "Empty fifo with %s session "
3513 "state 0x%x (%s)! Setting state to 0x%x (%s), "
3514 "returning %d (%s)", getpid (),
3515 session->vpp_handle, session_index,
Dave Wallace4878cbe2017-11-21 03:45:09 -05003516 is_server ? "server" : "client",
3517 state, vppcom_session_state_str (state),
3518 new_state, vppcom_session_state_str (new_state),
3519 rv, vppcom_retval_str (rv));
3520 }
3521 session->state = new_state;
3522 goto done;
3523 }
3524 }
3525 rv = ready;
3526done:
3527 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04003528}
3529
3530int
3531vppcom_select (unsigned long n_bits, unsigned long *read_map,
3532 unsigned long *write_map, unsigned long *except_map,
3533 double time_to_wait)
3534{
Dave Wallace543852a2017-08-03 02:11:34 -04003535 u32 session_index;
3536 session_t *session = 0;
3537 int rv, bits_set = 0;
3538 f64 timeout = clib_time_now (&vcm->clib_time) + time_to_wait;
3539 u32 minbits = clib_max (n_bits, BITS (uword));
3540
3541 ASSERT (sizeof (clib_bitmap_t) == sizeof (long int));
3542
Dave Wallace7876d392017-10-19 03:53:57 -04003543 if (n_bits && read_map)
Dave Wallace543852a2017-08-03 02:11:34 -04003544 {
3545 clib_bitmap_validate (vcm->rd_bitmap, minbits);
Dave Wallace048b1d62018-01-03 22:24:41 -05003546 clib_memcpy (vcm->rd_bitmap, read_map,
3547 vec_len (vcm->rd_bitmap) * sizeof (clib_bitmap_t));
3548 memset (read_map, 0, vec_len (vcm->rd_bitmap) * sizeof (clib_bitmap_t));
Dave Wallace543852a2017-08-03 02:11:34 -04003549 }
Dave Wallace7876d392017-10-19 03:53:57 -04003550 if (n_bits && write_map)
Dave Wallace543852a2017-08-03 02:11:34 -04003551 {
3552 clib_bitmap_validate (vcm->wr_bitmap, minbits);
Dave Wallace048b1d62018-01-03 22:24:41 -05003553 clib_memcpy (vcm->wr_bitmap, write_map,
3554 vec_len (vcm->wr_bitmap) * sizeof (clib_bitmap_t));
3555 memset (write_map, 0,
3556 vec_len (vcm->wr_bitmap) * sizeof (clib_bitmap_t));
Dave Wallace543852a2017-08-03 02:11:34 -04003557 }
Dave Wallace7876d392017-10-19 03:53:57 -04003558 if (n_bits && except_map)
Dave Wallace543852a2017-08-03 02:11:34 -04003559 {
3560 clib_bitmap_validate (vcm->ex_bitmap, minbits);
Dave Wallace048b1d62018-01-03 22:24:41 -05003561 clib_memcpy (vcm->ex_bitmap, except_map,
3562 vec_len (vcm->ex_bitmap) * sizeof (clib_bitmap_t));
3563 memset (except_map, 0,
3564 vec_len (vcm->ex_bitmap) * sizeof (clib_bitmap_t));
Dave Wallace543852a2017-08-03 02:11:34 -04003565 }
3566
3567 do
3568 {
3569 /* *INDENT-OFF* */
Dave Wallacee22aa742017-10-20 12:30:38 -04003570 if (n_bits)
3571 {
3572 if (read_map)
Dave Wallace543852a2017-08-03 02:11:34 -04003573 {
Dave Wallacee22aa742017-10-20 12:30:38 -04003574 clib_bitmap_foreach (session_index, vcm->rd_bitmap,
3575 ({
3576 clib_spinlock_lock (&vcm->sessions_lockp);
3577 rv = vppcom_session_at_index (session_index, &session);
3578 if (rv < 0)
3579 {
3580 clib_spinlock_unlock (&vcm->sessions_lockp);
3581 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05003582 clib_warning ("VCL<%d>: session %d specified in "
Dave Wallace2e005bb2017-11-07 01:21:39 -05003583 "read_map is closed.", getpid (),
Dave Wallacee22aa742017-10-20 12:30:38 -04003584 session_index);
3585 bits_set = VPPCOM_EBADFD;
3586 goto select_done;
3587 }
3588
3589 rv = vppcom_session_read_ready (session, session_index);
3590 clib_spinlock_unlock (&vcm->sessions_lockp);
3591 if (except_map && vcm->ex_bitmap &&
3592 clib_bitmap_get (vcm->ex_bitmap, session_index) &&
3593 (rv < 0))
3594 {
Dave Wallacee22aa742017-10-20 12:30:38 -04003595 clib_bitmap_set_no_check (except_map, session_index, 1);
3596 bits_set++;
3597 }
3598 else if (rv > 0)
3599 {
Dave Wallacee22aa742017-10-20 12:30:38 -04003600 clib_bitmap_set_no_check (read_map, session_index, 1);
3601 bits_set++;
3602 }
3603 }));
Dave Wallace543852a2017-08-03 02:11:34 -04003604 }
3605
Dave Wallacee22aa742017-10-20 12:30:38 -04003606 if (write_map)
Dave Wallace543852a2017-08-03 02:11:34 -04003607 {
Dave Wallacee22aa742017-10-20 12:30:38 -04003608 clib_bitmap_foreach (session_index, vcm->wr_bitmap,
3609 ({
3610 clib_spinlock_lock (&vcm->sessions_lockp);
3611 rv = vppcom_session_at_index (session_index, &session);
3612 if (rv < 0)
3613 {
3614 clib_spinlock_unlock (&vcm->sessions_lockp);
3615 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05003616 clib_warning ("VCL<%d>: session %d specified in "
Dave Wallace2e005bb2017-11-07 01:21:39 -05003617 "write_map is closed.", getpid (),
Dave Wallacee22aa742017-10-20 12:30:38 -04003618 session_index);
3619 bits_set = VPPCOM_EBADFD;
3620 goto select_done;
3621 }
Dave Wallace543852a2017-08-03 02:11:34 -04003622
Dave Wallacee22aa742017-10-20 12:30:38 -04003623 rv = vppcom_session_write_ready (session, session_index);
3624 clib_spinlock_unlock (&vcm->sessions_lockp);
3625 if (write_map && (rv > 0))
3626 {
Dave Wallacee22aa742017-10-20 12:30:38 -04003627 clib_bitmap_set_no_check (write_map, session_index, 1);
3628 bits_set++;
3629 }
3630 }));
Dave Wallace543852a2017-08-03 02:11:34 -04003631 }
3632
Dave Wallacee22aa742017-10-20 12:30:38 -04003633 if (except_map)
Dave Wallace543852a2017-08-03 02:11:34 -04003634 {
Dave Wallacee22aa742017-10-20 12:30:38 -04003635 clib_bitmap_foreach (session_index, vcm->ex_bitmap,
3636 ({
3637 clib_spinlock_lock (&vcm->sessions_lockp);
3638 rv = vppcom_session_at_index (session_index, &session);
3639 if (rv < 0)
3640 {
3641 clib_spinlock_unlock (&vcm->sessions_lockp);
3642 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05003643 clib_warning ("VCL<%d>: session %d specified in "
Dave Wallace2e005bb2017-11-07 01:21:39 -05003644 "except_map is closed.", getpid (),
Dave Wallacee22aa742017-10-20 12:30:38 -04003645 session_index);
3646 bits_set = VPPCOM_EBADFD;
3647 goto select_done;
3648 }
Dave Wallace543852a2017-08-03 02:11:34 -04003649
Dave Wallacee22aa742017-10-20 12:30:38 -04003650 rv = vppcom_session_read_ready (session, session_index);
3651 clib_spinlock_unlock (&vcm->sessions_lockp);
3652 if (rv < 0)
3653 {
Dave Wallacee22aa742017-10-20 12:30:38 -04003654 clib_bitmap_set_no_check (except_map, session_index, 1);
3655 bits_set++;
3656 }
3657 }));
Dave Wallace543852a2017-08-03 02:11:34 -04003658 }
Dave Wallacee22aa742017-10-20 12:30:38 -04003659 }
Dave Wallace543852a2017-08-03 02:11:34 -04003660 /* *INDENT-ON* */
3661 }
Dave Wallace048b1d62018-01-03 22:24:41 -05003662 while ((time_to_wait == -1) || (clib_time_now (&vcm->clib_time) < timeout));
Dave Wallace543852a2017-08-03 02:11:34 -04003663
3664select_done:
3665 return (bits_set);
3666}
3667
Dave Wallacef7f809c2017-10-03 01:48:42 -04003668static inline void
3669vep_verify_epoll_chain (u32 vep_idx)
3670{
3671 session_t *session;
3672 vppcom_epoll_t *vep;
3673 int rv;
Dave Wallace498b3a52017-11-09 13:00:34 -05003674 u32 sid = vep_idx;
Dave Wallacef7f809c2017-10-03 01:48:42 -04003675
Dave Wallace498b3a52017-11-09 13:00:34 -05003676 if (VPPCOM_DEBUG <= 1)
Dave Wallacef7f809c2017-10-03 01:48:42 -04003677 return;
3678
3679 /* Assumes caller has acquired spinlock: vcm->sessions_lockp */
3680 rv = vppcom_session_at_index (vep_idx, &session);
3681 if (PREDICT_FALSE (rv))
3682 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003683 clib_warning ("VCL<%d>: ERROR: Invalid vep_idx (%u)!",
3684 getpid (), vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003685 goto done;
3686 }
3687 if (PREDICT_FALSE (!session->is_vep))
3688 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003689 clib_warning ("VCL<%d>: ERROR: vep_idx (%u) is not a vep!",
3690 getpid (), vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003691 goto done;
3692 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05003693 vep = &session->vep;
Dave Wallace048b1d62018-01-03 22:24:41 -05003694 clib_warning ("VCL<%d>: vep_idx (%u): Dumping epoll chain\n"
Dave Wallace498b3a52017-11-09 13:00:34 -05003695 "{\n"
3696 " is_vep = %u\n"
3697 " is_vep_session = %u\n"
Dave Wallace4878cbe2017-11-21 03:45:09 -05003698 " next_sid = 0x%x (%u)\n"
Dave Wallace498b3a52017-11-09 13:00:34 -05003699 " wait_cont_idx = 0x%x (%u)\n"
Dave Wallace4878cbe2017-11-21 03:45:09 -05003700 "}\n", getpid (), vep_idx,
3701 session->is_vep, session->is_vep_session,
3702 vep->next_sid, vep->next_sid,
Dave Wallace498b3a52017-11-09 13:00:34 -05003703 session->wait_cont_idx, session->wait_cont_idx);
Dave Wallace4878cbe2017-11-21 03:45:09 -05003704
3705 for (sid = vep->next_sid; sid != ~0; sid = vep->next_sid)
Dave Wallacef7f809c2017-10-03 01:48:42 -04003706 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05003707 rv = vppcom_session_at_index (sid, &session);
3708 if (PREDICT_FALSE (rv))
Dave Wallacef7f809c2017-10-03 01:48:42 -04003709 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003710 clib_warning ("VCL<%d>: ERROR: Invalid sid (%u)!", getpid (), sid);
Dave Wallace4878cbe2017-11-21 03:45:09 -05003711 goto done;
3712 }
3713 if (PREDICT_FALSE (session->is_vep))
Dave Wallace048b1d62018-01-03 22:24:41 -05003714 clib_warning ("VCL<%d>: ERROR: sid (%u) is a vep!",
3715 getpid (), vep_idx);
Dave Wallace4878cbe2017-11-21 03:45:09 -05003716 else if (PREDICT_FALSE (!session->is_vep_session))
3717 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003718 clib_warning ("VCL<%d>: ERROR: session (%u) "
3719 "is not a vep session!", getpid (), sid);
Dave Wallace4878cbe2017-11-21 03:45:09 -05003720 goto done;
3721 }
3722 vep = &session->vep;
3723 if (PREDICT_FALSE (vep->vep_idx != vep_idx))
Dave Wallace048b1d62018-01-03 22:24:41 -05003724 clib_warning ("VCL<%d>: ERROR: session (%u) vep_idx (%u) != "
Dave Wallace4878cbe2017-11-21 03:45:09 -05003725 "vep_idx (%u)!", getpid (),
3726 sid, session->vep.vep_idx, vep_idx);
3727 if (session->is_vep_session)
3728 {
3729 clib_warning ("vep_idx[%u]: sid 0x%x (%u)\n"
3730 "{\n"
3731 " next_sid = 0x%x (%u)\n"
3732 " prev_sid = 0x%x (%u)\n"
3733 " vep_idx = 0x%x (%u)\n"
3734 " ev.events = 0x%x\n"
3735 " ev.data.u64 = 0x%llx\n"
3736 " et_mask = 0x%x\n"
3737 "}\n",
3738 vep_idx, sid, sid,
3739 vep->next_sid, vep->next_sid,
3740 vep->prev_sid, vep->prev_sid,
3741 vep->vep_idx, vep->vep_idx,
3742 vep->ev.events, vep->ev.data.u64, vep->et_mask);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003743 }
3744 }
Dave Wallacef7f809c2017-10-03 01:48:42 -04003745
3746done:
Dave Wallace048b1d62018-01-03 22:24:41 -05003747 clib_warning ("VCL<%d>: vep_idx (%u): Dump complete!\n",
3748 getpid (), vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003749}
3750
3751int
3752vppcom_epoll_create (void)
3753{
Dave Wallacef7f809c2017-10-03 01:48:42 -04003754 session_t *vep_session;
3755 u32 vep_idx;
3756
3757 clib_spinlock_lock (&vcm->sessions_lockp);
3758 pool_get (vcm->sessions, vep_session);
3759 memset (vep_session, 0, sizeof (*vep_session));
3760 vep_idx = vep_session - vcm->sessions;
3761
3762 vep_session->is_vep = 1;
3763 vep_session->vep.vep_idx = ~0;
3764 vep_session->vep.next_sid = ~0;
3765 vep_session->vep.prev_sid = ~0;
3766 vep_session->wait_cont_idx = ~0;
Dave Wallace4878cbe2017-11-21 03:45:09 -05003767 vep_session->vpp_handle = ~0;
Dave Wallacef7f809c2017-10-03 01:48:42 -04003768 clib_spinlock_unlock (&vcm->sessions_lockp);
3769
3770 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05003771 clib_warning ("VCL<%d>: Created vep_idx %u / sid %u!",
Dave Wallaceee45d412017-11-24 21:44:06 -05003772 getpid (), vep_idx, vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003773
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08003774 if (VPPCOM_DEBUG > 0)
3775 {
3776 vep_session->elog_track.name =
3777 (char *) format (0, "C:%d:VEP:%d%c", vcm->my_client_index,
3778 vep_idx, 0);
3779 elog_track_register (&vcm->elog_main, &vep_session->elog_track);
3780
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08003781 /* *INDENT-OFF* */
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08003782 ELOG_TYPE_DECLARE (e) =
3783 {
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08003784 .format = "created epoll session:%d",
3785 .format_args = "i4",
3786 };
3787
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08003788 struct
3789 {
3790 u32 data;
3791 } *ed;
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08003792
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08003793 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, vep_session->elog_track);
3794 ed->data = vep_idx;
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08003795 /* *INDENT-ON* */
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08003796 }
3797
Dave Wallacef7f809c2017-10-03 01:48:42 -04003798 return (vep_idx);
3799}
3800
3801int
3802vppcom_epoll_ctl (uint32_t vep_idx, int op, uint32_t session_index,
3803 struct epoll_event *event)
3804{
Dave Wallacef7f809c2017-10-03 01:48:42 -04003805 session_t *vep_session;
3806 session_t *session;
3807 int rv;
3808
3809 if (vep_idx == session_index)
3810 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003811 clib_warning ("VCL<%d>: ERROR: vep_idx == session_index (%u)!",
Dave Wallace4878cbe2017-11-21 03:45:09 -05003812 getpid (), vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003813 return VPPCOM_EINVAL;
3814 }
3815
3816 clib_spinlock_lock (&vcm->sessions_lockp);
3817 rv = vppcom_session_at_index (vep_idx, &vep_session);
3818 if (PREDICT_FALSE (rv))
3819 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003820 clib_warning ("VCL<%d>: ERROR: Invalid vep_idx (%u)!", vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003821 goto done;
3822 }
3823 if (PREDICT_FALSE (!vep_session->is_vep))
3824 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003825 clib_warning ("VCL<%d>: ERROR: vep_idx (%u) is not a vep!",
Dave Wallace4878cbe2017-11-21 03:45:09 -05003826 getpid (), vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003827 rv = VPPCOM_EINVAL;
3828 goto done;
3829 }
3830
3831 ASSERT (vep_session->vep.vep_idx == ~0);
3832 ASSERT (vep_session->vep.prev_sid == ~0);
3833
3834 rv = vppcom_session_at_index (session_index, &session);
3835 if (PREDICT_FALSE (rv))
3836 {
3837 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05003838 clib_warning ("VCL<%d>: ERROR: Invalid session_index (%u)!",
Dave Wallace2e005bb2017-11-07 01:21:39 -05003839 getpid (), session_index);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003840 goto done;
3841 }
3842 if (PREDICT_FALSE (session->is_vep))
3843 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05003844 clib_warning ("ERROR: session_index (%u) is a vep!", vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003845 rv = VPPCOM_EINVAL;
3846 goto done;
3847 }
3848
3849 switch (op)
3850 {
3851 case EPOLL_CTL_ADD:
3852 if (PREDICT_FALSE (!event))
3853 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003854 clib_warning ("VCL<%d>: ERROR: EPOLL_CTL_ADD: NULL pointer to "
Dave Wallace2e005bb2017-11-07 01:21:39 -05003855 "epoll_event structure!", getpid ());
Dave Wallacef7f809c2017-10-03 01:48:42 -04003856 rv = VPPCOM_EINVAL;
3857 goto done;
3858 }
3859 if (vep_session->vep.next_sid != ~0)
3860 {
3861 session_t *next_session;
3862 rv = vppcom_session_at_index (vep_session->vep.next_sid,
3863 &next_session);
3864 if (PREDICT_FALSE (rv))
3865 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003866 clib_warning ("VCL<%d>: ERROR: EPOLL_CTL_ADD: Invalid "
Dave Wallace4878cbe2017-11-21 03:45:09 -05003867 "vep.next_sid (%u) on vep_idx (%u)!",
3868 getpid (), vep_session->vep.next_sid, vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003869 goto done;
3870 }
3871 ASSERT (next_session->vep.prev_sid == vep_idx);
3872 next_session->vep.prev_sid = session_index;
3873 }
3874 session->vep.next_sid = vep_session->vep.next_sid;
3875 session->vep.prev_sid = vep_idx;
3876 session->vep.vep_idx = vep_idx;
3877 session->vep.et_mask = VEP_DEFAULT_ET_MASK;
3878 session->vep.ev = *event;
Dave Wallace4878cbe2017-11-21 03:45:09 -05003879 session->is_vep = 0;
Dave Wallacef7f809c2017-10-03 01:48:42 -04003880 session->is_vep_session = 1;
3881 vep_session->vep.next_sid = session_index;
3882 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05003883 clib_warning ("VCL<%d>: EPOLL_CTL_ADD: vep_idx %u, "
3884 "sid %u, events 0x%x, data 0x%llx!",
3885 getpid (), vep_idx, session_index,
Dave Wallacef7f809c2017-10-03 01:48:42 -04003886 event->events, event->data.u64);
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08003887 if (VPPCOM_DEBUG > 0)
3888 {
3889 /* *INDENT-OFF* */
3890 ELOG_TYPE_DECLARE (e) =
3891 {
3892 .format = "epoll_ctladd: events:%x data:%x",
3893 .format_args = "i4i4i8",
3894 };
3895 struct
3896 {
3897 u32 events;
3898 u64 event_data;
3899 } *ed;
3900
3901 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
3902
3903 ed->events = event->events;
3904 ed->event_data = event->data.u64;
3905 /* *INDENT-ON* */
3906 }
Dave Wallacef7f809c2017-10-03 01:48:42 -04003907 break;
3908
3909 case EPOLL_CTL_MOD:
3910 if (PREDICT_FALSE (!event))
3911 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003912 clib_warning ("VCL<%d>: ERROR: EPOLL_CTL_MOD: NULL pointer to "
Dave Wallace2e005bb2017-11-07 01:21:39 -05003913 "epoll_event structure!", getpid ());
Dave Wallacef7f809c2017-10-03 01:48:42 -04003914 rv = VPPCOM_EINVAL;
3915 goto done;
3916 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05003917 else if (PREDICT_FALSE (!session->is_vep_session))
Dave Wallacef7f809c2017-10-03 01:48:42 -04003918 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003919 clib_warning ("VCL<%d>: ERROR: sid %u EPOLL_CTL_MOD: "
Dave Wallace4878cbe2017-11-21 03:45:09 -05003920 "not a vep session!", getpid (), session_index);
3921 rv = VPPCOM_EINVAL;
3922 goto done;
3923 }
3924 else if (PREDICT_FALSE (session->vep.vep_idx != vep_idx))
3925 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003926 clib_warning ("VCL<%d>: ERROR: sid %u EPOLL_CTL_MOD: "
Dave Wallace4878cbe2017-11-21 03:45:09 -05003927 "vep_idx (%u) != vep_idx (%u)!",
3928 getpid (), session_index,
3929 session->vep.vep_idx, vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003930 rv = VPPCOM_EINVAL;
3931 goto done;
3932 }
3933 session->vep.et_mask = VEP_DEFAULT_ET_MASK;
3934 session->vep.ev = *event;
3935 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05003936 clib_warning
3937 ("VCL<%d>: EPOLL_CTL_MOD: vep_idx %u, sid %u, events 0x%x,"
3938 " data 0x%llx!", getpid (), vep_idx, session_index, event->events,
3939 event->data.u64);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003940 break;
3941
3942 case EPOLL_CTL_DEL:
Dave Wallace4878cbe2017-11-21 03:45:09 -05003943 if (PREDICT_FALSE (!session->is_vep_session))
Dave Wallacef7f809c2017-10-03 01:48:42 -04003944 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003945 clib_warning ("VCL<%d>: ERROR: sid %u EPOLL_CTL_DEL: "
Dave Wallace4878cbe2017-11-21 03:45:09 -05003946 "not a vep session!", getpid (), session_index);
3947 rv = VPPCOM_EINVAL;
3948 goto done;
3949 }
3950 else if (PREDICT_FALSE (session->vep.vep_idx != vep_idx))
3951 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003952 clib_warning ("VCL<%d>: ERROR: sid %u EPOLL_CTL_DEL: "
Dave Wallace4878cbe2017-11-21 03:45:09 -05003953 "vep_idx (%u) != vep_idx (%u)!",
3954 getpid (), session_index,
3955 session->vep.vep_idx, vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003956 rv = VPPCOM_EINVAL;
3957 goto done;
3958 }
3959
3960 vep_session->wait_cont_idx =
3961 (vep_session->wait_cont_idx == session_index) ?
3962 session->vep.next_sid : vep_session->wait_cont_idx;
3963
3964 if (session->vep.prev_sid == vep_idx)
3965 vep_session->vep.next_sid = session->vep.next_sid;
3966 else
3967 {
3968 session_t *prev_session;
3969 rv = vppcom_session_at_index (session->vep.prev_sid, &prev_session);
3970 if (PREDICT_FALSE (rv))
3971 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003972 clib_warning ("VCL<%d>: ERROR: EPOLL_CTL_DEL: Invalid "
Dave Wallace4878cbe2017-11-21 03:45:09 -05003973 "vep.prev_sid (%u) on sid (%u)!",
3974 getpid (), session->vep.prev_sid, session_index);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003975 goto done;
3976 }
3977 ASSERT (prev_session->vep.next_sid == session_index);
3978 prev_session->vep.next_sid = session->vep.next_sid;
3979 }
3980 if (session->vep.next_sid != ~0)
3981 {
3982 session_t *next_session;
3983 rv = vppcom_session_at_index (session->vep.next_sid, &next_session);
3984 if (PREDICT_FALSE (rv))
3985 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003986 clib_warning ("VCL<%d>: ERROR: EPOLL_CTL_DEL: Invalid "
Dave Wallace4878cbe2017-11-21 03:45:09 -05003987 "vep.next_sid (%u) on sid (%u)!",
3988 getpid (), session->vep.next_sid, session_index);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003989 goto done;
3990 }
3991 ASSERT (next_session->vep.prev_sid == session_index);
3992 next_session->vep.prev_sid = session->vep.prev_sid;
3993 }
3994
3995 memset (&session->vep, 0, sizeof (session->vep));
3996 session->vep.next_sid = ~0;
3997 session->vep.prev_sid = ~0;
3998 session->vep.vep_idx = ~0;
3999 session->is_vep_session = 0;
4000 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05004001 clib_warning ("VCL<%d>: EPOLL_CTL_DEL: vep_idx %u, sid %u!",
Dave Wallace2e005bb2017-11-07 01:21:39 -05004002 getpid (), vep_idx, session_index);
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004003 if (VPPCOM_DEBUG > 0)
4004 {
4005 /* *INDENT-OFF* */
4006 ELOG_TYPE_DECLARE (e) =
4007 {
4008 .format = "epoll_ctldel: vep:%d",
4009 .format_args = "i4",
4010 };
4011 struct
4012 {
4013 u32 data;
4014 } *ed;
4015
4016 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4017
4018 ed->data = vep_idx;
4019 /* *INDENT-ON* */
4020 }
Dave Wallacef7f809c2017-10-03 01:48:42 -04004021 break;
4022
4023 default:
Dave Wallace048b1d62018-01-03 22:24:41 -05004024 clib_warning ("VCL<%d>: ERROR: Invalid operation (%d)!", getpid (), op);
Dave Wallacef7f809c2017-10-03 01:48:42 -04004025 rv = VPPCOM_EINVAL;
4026 }
4027
4028 vep_verify_epoll_chain (vep_idx);
4029
4030done:
4031 clib_spinlock_unlock (&vcm->sessions_lockp);
4032 return rv;
4033}
4034
Dave Wallacef7f809c2017-10-03 01:48:42 -04004035int
4036vppcom_epoll_wait (uint32_t vep_idx, struct epoll_event *events,
4037 int maxevents, double wait_for_time)
4038{
Dave Wallacef7f809c2017-10-03 01:48:42 -04004039 session_t *vep_session;
4040 int rv;
4041 f64 timeout = clib_time_now (&vcm->clib_time) + wait_for_time;
Dave Wallace2e005bb2017-11-07 01:21:39 -05004042 u32 keep_trying = 1;
Dave Wallacef7f809c2017-10-03 01:48:42 -04004043 int num_ev = 0;
4044 u32 vep_next_sid, wait_cont_idx;
4045 u8 is_vep;
4046
4047 if (PREDICT_FALSE (maxevents <= 0))
4048 {
Dave Wallace048b1d62018-01-03 22:24:41 -05004049 clib_warning ("VCL<%d>: ERROR: Invalid maxevents (%d)!",
Dave Wallace4878cbe2017-11-21 03:45:09 -05004050 getpid (), maxevents);
Dave Wallacef7f809c2017-10-03 01:48:42 -04004051 return VPPCOM_EINVAL;
4052 }
Dave Wallacef7f809c2017-10-03 01:48:42 -04004053 memset (events, 0, sizeof (*events) * maxevents);
4054
4055 VCL_LOCK_AND_GET_SESSION (vep_idx, &vep_session);
4056 vep_next_sid = vep_session->vep.next_sid;
4057 is_vep = vep_session->is_vep;
4058 wait_cont_idx = vep_session->wait_cont_idx;
4059 clib_spinlock_unlock (&vcm->sessions_lockp);
4060
4061 if (PREDICT_FALSE (!is_vep))
4062 {
Dave Wallace048b1d62018-01-03 22:24:41 -05004063 clib_warning ("VCL<%d>: ERROR: vep_idx (%u) is not a vep!",
Dave Wallace4878cbe2017-11-21 03:45:09 -05004064 getpid (), vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04004065 rv = VPPCOM_EINVAL;
4066 goto done;
4067 }
Dave Wallacee695cb42017-11-02 22:04:42 -04004068 if (PREDICT_FALSE (vep_next_sid == ~0))
Dave Wallacef7f809c2017-10-03 01:48:42 -04004069 {
Dave Wallacee695cb42017-11-02 22:04:42 -04004070 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05004071 clib_warning ("VCL<%d>: WARNING: vep_idx (%u) is empty!",
Dave Wallace2e005bb2017-11-07 01:21:39 -05004072 getpid (), vep_idx);
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004073 if (VPPCOM_DEBUG > 0)
4074 {
4075 /* *INDENT-OFF* */
4076 ELOG_TYPE_DECLARE (e) =
4077 {
4078 .format = "WRN: vep_idx:%d empty",
4079 .format_args = "i4",
4080 };
4081 struct
4082 {
4083 u32 data;
4084 } *ed;
4085
4086 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, vep_session->elog_track);
4087
4088 ed->data = vep_idx;
4089 /* *INDENT-ON* */
4090 }
Dave Wallacef7f809c2017-10-03 01:48:42 -04004091 goto done;
4092 }
4093
4094 do
4095 {
4096 u32 sid;
4097 u32 next_sid = ~0;
4098 session_t *session;
4099
4100 for (sid = (wait_cont_idx == ~0) ? vep_next_sid : wait_cont_idx;
4101 sid != ~0; sid = next_sid)
4102 {
4103 u32 session_events, et_mask, clear_et_mask, session_vep_idx;
4104 u8 add_event, is_vep_session;
4105 int ready;
4106 u64 session_ev_data;
4107
4108 VCL_LOCK_AND_GET_SESSION (sid, &session);
4109 next_sid = session->vep.next_sid;
4110 session_events = session->vep.ev.events;
4111 et_mask = session->vep.et_mask;
4112 is_vep = session->is_vep;
4113 is_vep_session = session->is_vep_session;
4114 session_vep_idx = session->vep.vep_idx;
4115 session_ev_data = session->vep.ev.data.u64;
4116 clib_spinlock_unlock (&vcm->sessions_lockp);
4117
4118 if (PREDICT_FALSE (is_vep))
4119 {
4120 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05004121 clib_warning ("VCL<%d>: ERROR: sid (%u) is a vep!",
Dave Wallace2e005bb2017-11-07 01:21:39 -05004122 getpid (), vep_idx);
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004123 if (VPPCOM_DEBUG > 0)
4124 {
4125 /* *INDENT-OFF* */
4126 ELOG_TYPE_DECLARE (e) =
4127 {
4128 .format = "ERR:vep_idx:%d is vep",
4129 .format_args = "i4",
4130 };
4131 struct
4132 {
4133 u32 data;
4134 } *ed;
4135
4136 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4137
4138 ed->data = vep_idx;
4139 /* *INDENT-ON* */
4140 }
4141
Dave Wallacef7f809c2017-10-03 01:48:42 -04004142 rv = VPPCOM_EINVAL;
4143 goto done;
4144 }
4145 if (PREDICT_FALSE (!is_vep_session))
4146 {
4147 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05004148 clib_warning ("VCL<%d>: ERROR: session (%u) is not "
Dave Wallace2e005bb2017-11-07 01:21:39 -05004149 "a vep session!", getpid (), sid);
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004150 if (VPPCOM_DEBUG > 0)
4151 {
4152 /* *INDENT-OFF* */
4153 ELOG_TYPE_DECLARE (e) =
4154 {
4155 .format = "ERR:SID:%d not vep",
4156 .format_args = "i4",
4157 };
4158 struct
4159 {
4160 u32 data;
4161 } *ed;
4162
4163 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4164
4165 ed->data = sid;
4166 /* *INDENT-ON* */
4167 }
4168
Dave Wallacef7f809c2017-10-03 01:48:42 -04004169 rv = VPPCOM_EINVAL;
4170 goto done;
4171 }
4172 if (PREDICT_FALSE (session_vep_idx != vep_idx))
4173 {
Dave Wallace048b1d62018-01-03 22:24:41 -05004174 clib_warning ("VCL<%d>: ERROR: session (%u) "
Dave Wallacef7f809c2017-10-03 01:48:42 -04004175 "vep_idx (%u) != vep_idx (%u)!",
Dave Wallace2e005bb2017-11-07 01:21:39 -05004176 getpid (), sid, session->vep.vep_idx, vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04004177 rv = VPPCOM_EINVAL;
4178 goto done;
4179 }
4180
4181 add_event = clear_et_mask = 0;
4182
Dave Wallace60caa062017-11-10 17:07:13 -05004183 if (EPOLLIN & session_events)
Dave Wallacef7f809c2017-10-03 01:48:42 -04004184 {
4185 VCL_LOCK_AND_GET_SESSION (sid, &session);
4186 ready = vppcom_session_read_ready (session, sid);
4187 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace60caa062017-11-10 17:07:13 -05004188 if ((ready > 0) && (EPOLLIN & et_mask))
Dave Wallacef7f809c2017-10-03 01:48:42 -04004189 {
4190 add_event = 1;
4191 events[num_ev].events |= EPOLLIN;
Dave Wallace60caa062017-11-10 17:07:13 -05004192 if (((EPOLLET | EPOLLIN) & session_events) ==
4193 (EPOLLET | EPOLLIN))
Dave Wallacef7f809c2017-10-03 01:48:42 -04004194 clear_et_mask |= EPOLLIN;
4195 }
4196 else if (ready < 0)
4197 {
4198 add_event = 1;
4199 switch (ready)
4200 {
4201 case VPPCOM_ECONNRESET:
4202 events[num_ev].events |= EPOLLHUP | EPOLLRDHUP;
4203 break;
4204
4205 default:
4206 events[num_ev].events |= EPOLLERR;
4207 break;
4208 }
4209 }
4210 }
4211
Dave Wallace60caa062017-11-10 17:07:13 -05004212 if (EPOLLOUT & session_events)
Dave Wallacef7f809c2017-10-03 01:48:42 -04004213 {
4214 VCL_LOCK_AND_GET_SESSION (sid, &session);
4215 ready = vppcom_session_write_ready (session, sid);
4216 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace60caa062017-11-10 17:07:13 -05004217 if ((ready > 0) && (EPOLLOUT & et_mask))
Dave Wallacef7f809c2017-10-03 01:48:42 -04004218 {
4219 add_event = 1;
4220 events[num_ev].events |= EPOLLOUT;
Dave Wallace60caa062017-11-10 17:07:13 -05004221 if (((EPOLLET | EPOLLOUT) & session_events) ==
4222 (EPOLLET | EPOLLOUT))
Dave Wallacef7f809c2017-10-03 01:48:42 -04004223 clear_et_mask |= EPOLLOUT;
4224 }
4225 else if (ready < 0)
4226 {
4227 add_event = 1;
4228 switch (ready)
4229 {
4230 case VPPCOM_ECONNRESET:
4231 events[num_ev].events |= EPOLLHUP;
4232 break;
4233
4234 default:
4235 events[num_ev].events |= EPOLLERR;
4236 break;
4237 }
4238 }
4239 }
4240
4241 if (add_event)
4242 {
4243 events[num_ev].data.u64 = session_ev_data;
4244 if (EPOLLONESHOT & session_events)
4245 {
4246 VCL_LOCK_AND_GET_SESSION (sid, &session);
4247 session->vep.ev.events = 0;
4248 clib_spinlock_unlock (&vcm->sessions_lockp);
4249 }
4250 num_ev++;
4251 if (num_ev == maxevents)
4252 {
4253 VCL_LOCK_AND_GET_SESSION (vep_idx, &vep_session);
4254 vep_session->wait_cont_idx = next_sid;
4255 clib_spinlock_unlock (&vcm->sessions_lockp);
4256 goto done;
4257 }
4258 }
4259 if (wait_cont_idx != ~0)
4260 {
4261 if (next_sid == ~0)
4262 next_sid = vep_next_sid;
4263 else if (next_sid == wait_cont_idx)
4264 next_sid = ~0;
4265 }
4266 }
Dave Wallace2e005bb2017-11-07 01:21:39 -05004267 if (wait_for_time != -1)
4268 keep_trying = (clib_time_now (&vcm->clib_time) <= timeout) ? 1 : 0;
Dave Wallacef7f809c2017-10-03 01:48:42 -04004269 }
Dave Wallace2e005bb2017-11-07 01:21:39 -05004270 while ((num_ev == 0) && keep_trying);
Dave Wallacef7f809c2017-10-03 01:48:42 -04004271
4272 if (wait_cont_idx != ~0)
4273 {
4274 VCL_LOCK_AND_GET_SESSION (vep_idx, &vep_session);
4275 vep_session->wait_cont_idx = ~0;
4276 clib_spinlock_unlock (&vcm->sessions_lockp);
4277 }
4278done:
4279 return (rv != VPPCOM_OK) ? rv : num_ev;
4280}
4281
Dave Wallace35830af2017-10-09 01:43:42 -04004282int
4283vppcom_session_attr (uint32_t session_index, uint32_t op,
4284 void *buffer, uint32_t * buflen)
4285{
Dave Wallace35830af2017-10-09 01:43:42 -04004286 session_t *session;
4287 int rv = VPPCOM_OK;
4288 u32 *flags = buffer;
Steven2199aab2017-10-15 20:18:47 -07004289 vppcom_endpt_t *ep = buffer;
Dave Wallace35830af2017-10-09 01:43:42 -04004290
4291 VCL_LOCK_AND_GET_SESSION (session_index, &session);
4292 switch (op)
4293 {
4294 case VPPCOM_ATTR_GET_NREAD:
4295 rv = vppcom_session_read_ready (session, session_index);
Dave Wallace227867f2017-11-13 21:21:53 -05004296 if (VPPCOM_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05004297 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_NREAD: sid %u, nread = %d",
Dave Wallace2e005bb2017-11-07 01:21:39 -05004298 getpid (), rv);
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004299 if (VPPCOM_DEBUG > 0)
4300 {
4301 /* *INDENT-OFF* */
4302 ELOG_TYPE_DECLARE (e) =
4303 {
4304 .format = "VPPCOM_ATTR_GET_NREAD: nread=%d",
4305 .format_args = "i4",
4306 };
4307 struct
4308 {
4309 u32 data;
4310 } *ed;
4311
4312 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4313
4314 ed->data = rv;
4315 /* *INDENT-ON* */
4316 }
4317
Dave Wallace35830af2017-10-09 01:43:42 -04004318 break;
4319
Dave Wallace227867f2017-11-13 21:21:53 -05004320 case VPPCOM_ATTR_GET_NWRITE:
4321 rv = vppcom_session_write_ready (session, session_index);
4322 if (VPPCOM_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05004323 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_NWRITE: sid %u, nwrite = %d",
Dave Wallace227867f2017-11-13 21:21:53 -05004324 getpid (), session_index, rv);
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004325 if (VPPCOM_DEBUG > 0)
4326 {
4327 /* *INDENT-OFF* */
4328 ELOG_TYPE_DECLARE (e) =
4329 {
4330 .format = "VPPCOM_ATTR_GET_NWRITE: nwrite=%d",
4331 .format_args = "i4",
4332 };
4333 struct
4334 {
4335 u32 data;
4336 } *ed;
4337
4338 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4339
4340 ed->data = rv;
4341 /* *INDENT-ON* */
4342 }
Dave Wallace35830af2017-10-09 01:43:42 -04004343 break;
4344
4345 case VPPCOM_ATTR_GET_FLAGS:
Dave Wallace048b1d62018-01-03 22:24:41 -05004346 if (PREDICT_TRUE (buffer && buflen && (*buflen >= sizeof (*flags))))
Dave Wallace35830af2017-10-09 01:43:42 -04004347 {
4348 *flags = O_RDWR | ((session->is_nonblocking) ? O_NONBLOCK : 0);
4349 *buflen = sizeof (*flags);
Dave Wallace227867f2017-11-13 21:21:53 -05004350 if (VPPCOM_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05004351 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_FLAGS: sid %u, "
Dave Wallace227867f2017-11-13 21:21:53 -05004352 "flags = 0x%08x, is_nonblocking = %u", getpid (),
4353 session_index, *flags, session->is_nonblocking);
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004354 if (VPPCOM_DEBUG > 0)
4355 {
4356 /* *INDENT-OFF* */
4357 ELOG_TYPE_DECLARE (e) =
4358 {
4359 .format = "VPPCOM_ATTR_GET_FLAGS: flags=%x is_nonblk=%d",
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004360 .format_args = "i4i4",
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004361 };
4362 struct
4363 {
4364 u32 flags;
4365 u32 is_nonblk;
4366 } *ed;
4367
4368 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4369
4370 ed->flags = *flags;
4371 ed->is_nonblk = session->is_nonblocking;
4372 /* *INDENT-ON* */
4373 }
4374
Dave Wallace35830af2017-10-09 01:43:42 -04004375 }
4376 else
4377 rv = VPPCOM_EINVAL;
4378 break;
4379
4380 case VPPCOM_ATTR_SET_FLAGS:
Dave Wallace048b1d62018-01-03 22:24:41 -05004381 if (PREDICT_TRUE (buffer && buflen && (*buflen == sizeof (*flags))))
Dave Wallace35830af2017-10-09 01:43:42 -04004382 {
4383 session->is_nonblocking = (*flags & O_NONBLOCK) ? 1 : 0;
Dave Wallace227867f2017-11-13 21:21:53 -05004384 if (VPPCOM_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05004385 clib_warning ("VCL<%d>: VPPCOM_ATTR_SET_FLAGS: sid %u, "
Dave Wallace227867f2017-11-13 21:21:53 -05004386 "flags = 0x%08x, is_nonblocking = %u",
Dave Wallace4878cbe2017-11-21 03:45:09 -05004387 getpid (), session_index, *flags,
4388 session->is_nonblocking);
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004389 if (VPPCOM_DEBUG > 0)
4390 {
4391 /* *INDENT-OFF* */
4392 ELOG_TYPE_DECLARE (e) =
4393 {
4394 .format = "VPPCOM_ATTR_SET_FLAGS: flags=%x is_nonblk=%d",
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004395 .format_args = "i4i4",
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004396 };
4397 struct
4398 {
4399 u32 flags;
4400 u32 is_nonblk;
4401 } *ed;
4402
4403 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4404
4405 ed->flags = *flags;
4406 ed->is_nonblk = session->is_nonblocking;
4407 /* *INDENT-ON* */
4408 }
Dave Wallace35830af2017-10-09 01:43:42 -04004409 }
4410 else
4411 rv = VPPCOM_EINVAL;
4412 break;
4413
4414 case VPPCOM_ATTR_GET_PEER_ADDR:
Dave Wallace048b1d62018-01-03 22:24:41 -05004415 if (PREDICT_TRUE (buffer && buflen &&
4416 (*buflen >= sizeof (*ep)) && ep->ip))
Dave Wallace35830af2017-10-09 01:43:42 -04004417 {
Steven2199aab2017-10-15 20:18:47 -07004418 ep->is_ip4 = session->peer_addr.is_ip4;
Stevenac1f96d2017-10-24 16:03:58 -07004419 ep->port = session->peer_port;
Steven2199aab2017-10-15 20:18:47 -07004420 if (session->peer_addr.is_ip4)
4421 clib_memcpy (ep->ip, &session->peer_addr.ip46.ip4,
4422 sizeof (ip4_address_t));
4423 else
4424 clib_memcpy (ep->ip, &session->peer_addr.ip46.ip6,
4425 sizeof (ip6_address_t));
4426 *buflen = sizeof (*ep);
Dave Wallacefaf9d772017-10-26 16:12:04 -04004427 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05004428 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_PEER_ADDR: sid %u, "
4429 "is_ip4 = %u, addr = %U, port %u", getpid (),
Dave Wallace774169b2017-11-01 20:07:40 -04004430 session_index, ep->is_ip4, format_ip46_address,
Stevenac1f96d2017-10-24 16:03:58 -07004431 &session->peer_addr.ip46, ep->is_ip4,
4432 clib_net_to_host_u16 (ep->port));
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004433 if (VPPCOM_DEBUG > 0)
4434 {
4435 if (ep->is_ip4)
4436 {
4437 /* *INDENT-OFF* */
4438 ELOG_TYPE_DECLARE (e) =
4439 {
4440 .format = "VPPCOM_ATTR_GET_PEER_ADDR: addr:%d.%d.%d.%d:%d",
4441 .format_args = "i1i1i1i1i2",
4442 };
4443 CLIB_PACKED (struct {
4444 u8 addr[4]; //4
4445 u16 port; //2
4446 }) * ed;
4447
4448 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4449
4450 ed->addr[0] = session->peer_addr.ip46.ip4.as_u8[0];
4451 ed->addr[1] = session->peer_addr.ip46.ip4.as_u8[1];
4452 ed->addr[2] = session->peer_addr.ip46.ip4.as_u8[2];
4453 ed->addr[3] = session->peer_addr.ip46.ip4.as_u8[3];
4454 ed->port = clib_net_to_host_u16 (session->peer_port);
4455 /* *INDENT-ON* */
4456 }
4457 else
4458 {
4459 /* *INDENT-OFF* */
4460 ELOG_TYPE_DECLARE (e) =
4461 {
4462 .format = "VPPCOM_ATTR_GET_PEER_ADDR: addr:IP6:%d",
4463 .format_args = "i2",
4464 };
4465 CLIB_PACKED (struct {
4466 u16 port; //2
4467 }) * ed;
4468
4469 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4470
4471 ed->port = clib_net_to_host_u16 (session->peer_port);
4472 /* *INDENT-ON* */
4473 }
4474 }
Dave Wallace35830af2017-10-09 01:43:42 -04004475 }
4476 else
4477 rv = VPPCOM_EINVAL;
4478 break;
4479
4480 case VPPCOM_ATTR_GET_LCL_ADDR:
Dave Wallace048b1d62018-01-03 22:24:41 -05004481 if (PREDICT_TRUE (buffer && buflen &&
4482 (*buflen >= sizeof (*ep)) && ep->ip))
Dave Wallace35830af2017-10-09 01:43:42 -04004483 {
Steven2199aab2017-10-15 20:18:47 -07004484 ep->is_ip4 = session->lcl_addr.is_ip4;
Stevenac1f96d2017-10-24 16:03:58 -07004485 ep->port = session->lcl_port;
Steven2199aab2017-10-15 20:18:47 -07004486 if (session->lcl_addr.is_ip4)
4487 clib_memcpy (ep->ip, &session->lcl_addr.ip46.ip4,
4488 sizeof (ip4_address_t));
4489 else
4490 clib_memcpy (ep->ip, &session->lcl_addr.ip46.ip6,
4491 sizeof (ip6_address_t));
4492 *buflen = sizeof (*ep);
Dave Wallacefaf9d772017-10-26 16:12:04 -04004493 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05004494 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_LCL_ADDR: sid %u, "
4495 "is_ip4 = %u, addr = %U port %d", getpid (),
Dave Wallace774169b2017-11-01 20:07:40 -04004496 session_index, ep->is_ip4, format_ip46_address,
Stevenac1f96d2017-10-24 16:03:58 -07004497 &session->lcl_addr.ip46, ep->is_ip4,
4498 clib_net_to_host_u16 (ep->port));
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004499 if (VPPCOM_DEBUG > 0)
4500 {
4501 if (ep->is_ip4)
4502 {
4503 /* *INDENT-OFF* */
4504 ELOG_TYPE_DECLARE (e) =
4505 {
4506 .format = "VPPCOM_ATTR_GET_LCL_ADDR: addr:%d.%d.%d.%d:%d",
4507 .format_args = "i1i1i1i1i2",
4508 };
4509 CLIB_PACKED (struct {
4510 u8 addr[4]; //4
4511 u16 port; //2
4512 }) * ed;
4513
4514 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4515
4516 ed->addr[0] = session->lcl_addr.ip46.ip4.as_u8[0];
4517 ed->addr[1] = session->lcl_addr.ip46.ip4.as_u8[1];
4518 ed->addr[2] = session->lcl_addr.ip46.ip4.as_u8[2];
4519 ed->addr[3] = session->lcl_addr.ip46.ip4.as_u8[3];
4520 ed->port = clib_net_to_host_u16 (session->peer_port);
4521 /* *INDENT-ON* */
4522 }
4523 else
4524 {
4525 /* *INDENT-OFF* */
4526 ELOG_TYPE_DECLARE (e) =
4527 {
4528 .format = "VPPCOM_ATTR_GET_LCL_ADDR: addr:IP6:%d",
4529 .format_args = "i2",
4530 };
4531 CLIB_PACKED (struct {
4532 u16 port; //2
4533 }) * ed;
4534
4535 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4536
4537 ed->port = clib_net_to_host_u16 (session->peer_port);
4538 /* *INDENT-ON* */
4539 }
4540 }
Dave Wallace35830af2017-10-09 01:43:42 -04004541 }
4542 else
4543 rv = VPPCOM_EINVAL;
4544 break;
Stevenb5a11602017-10-11 09:59:30 -07004545
Dave Wallace048b1d62018-01-03 22:24:41 -05004546 case VPPCOM_ATTR_GET_LIBC_EPFD:
4547 rv = session->libc_epfd;
4548 if (VPPCOM_DEBUG > 2)
4549 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_LIBC_EPFD: libc_epfd %d",
4550 getpid (), rv);
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004551 if (VPPCOM_DEBUG > 0)
4552 {
4553 /* *INDENT-OFF* */
4554 ELOG_TYPE_DECLARE (e) =
4555 {
Florin Corasbb16d3f2018-01-29 08:55:25 -08004556 .format = "VPPCOM_ATTR_GET_LIBC_EPFD: libc_epfd=%d",
4557 .format_args = "i4",
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004558 };
4559 CLIB_PACKED (struct {
Florin Corasbb16d3f2018-01-29 08:55:25 -08004560 i32 data;
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004561 }) * ed;
4562
4563 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
Florin Corasbb16d3f2018-01-29 08:55:25 -08004564 ed->data = session->libc_epfd;
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004565 /* *INDENT-ON* */
4566 }
4567
Dave Wallace048b1d62018-01-03 22:24:41 -05004568 break;
4569
4570 case VPPCOM_ATTR_SET_LIBC_EPFD:
4571 if (PREDICT_TRUE (buffer && buflen &&
4572 (*buflen == sizeof (session->libc_epfd))))
4573 {
4574 session->libc_epfd = *(int *) buffer;
4575 *buflen = sizeof (session->libc_epfd);
4576
4577 if (VPPCOM_DEBUG > 2)
4578 clib_warning ("VCL<%d>: VPPCOM_ATTR_SET_LIBC_EPFD: libc_epfd %d, "
4579 "buflen %d", getpid (), session->libc_epfd,
4580 *buflen);
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004581 if (VPPCOM_DEBUG > 0)
4582 {
4583 /* *INDENT-OFF* */
4584 ELOG_TYPE_DECLARE (e) =
4585 {
4586 .format = "VPPCOM_ATTR_SET_LIBC_EPFD: libc_epfd=%s%d buflen=%d",
4587 .format_args = "t1i4i4",
4588 .n_enum_strings = 2,
4589 .enum_strings = {"", "-",},
4590 };
4591 CLIB_PACKED (struct {
4592 u8 sign;
4593 u32 data[2];
4594 }) * ed;
4595
4596 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4597
4598 ed->sign = (session->libc_epfd < 0);
4599 ed->data[0] = abs(session->libc_epfd);
4600 ed->data[1] = *buflen;
4601 /* *INDENT-ON* */
4602 }
Dave Wallace048b1d62018-01-03 22:24:41 -05004603 }
4604 else
4605 rv = VPPCOM_EINVAL;
4606 break;
4607
4608 case VPPCOM_ATTR_GET_PROTOCOL:
4609 if (buffer && buflen && (*buflen >= sizeof (int)))
4610 {
4611 *(int *) buffer = session->proto;
4612 *buflen = sizeof (int);
4613
4614 if (VPPCOM_DEBUG > 2)
4615 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_PROTOCOL: %d (%s), "
4616 "buflen %d", getpid (), *(int *) buffer,
4617 *(int *) buffer ? "UDP" : "TCP", *buflen);
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004618 if (VPPCOM_DEBUG > 0)
4619 {
4620 /* *INDENT-OFF* */
4621 ELOG_TYPE_DECLARE (e) =
4622 {
4623 .format = "VPPCOM_ATTR_GET_PROTOCOL: %s buflen=%d",
4624 .format_args = "t1i4",
4625 .n_enum_strings = 2,
4626 .enum_strings = {"TCP", "UDP",},
4627 };
4628
4629 CLIB_PACKED (struct {
4630 u8 proto;
4631 u32 buflen;
4632 }) * ed;
4633
4634 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4635 ed->proto = session->proto;
4636 ed->buflen = *(int *) buffer;
4637 /* *INDENT-ON* */
4638 }
Dave Wallace048b1d62018-01-03 22:24:41 -05004639 }
4640 else
4641 rv = VPPCOM_EINVAL;
4642 break;
4643
4644 case VPPCOM_ATTR_GET_LISTEN:
4645 if (buffer && buflen && (*buflen >= sizeof (int)))
4646 {
4647 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
4648 VCL_SESS_ATTR_LISTEN);
4649 *buflen = sizeof (int);
4650
4651 if (VPPCOM_DEBUG > 2)
4652 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_LISTEN: %d, "
4653 "buflen %d", getpid (), *(int *) buffer, *buflen);
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004654 if (VPPCOM_DEBUG > 0)
4655 {
4656 /* *INDENT-OFF* */
4657 ELOG_TYPE_DECLARE (e) =
4658 {
4659 .format = "VPPCOM_ATTR_GET_LISTEN: %d buflen=%d",
4660 .format_args = "i4i4",
4661 };
4662
4663 struct {
4664 u32 data[2];
4665 } * ed;
4666
4667 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4668 ed->data[0] = *(int *) buffer;
4669 ed->data[1] = *buflen;
4670 /* *INDENT-ON* */
4671 }
Dave Wallace048b1d62018-01-03 22:24:41 -05004672 }
4673 else
4674 rv = VPPCOM_EINVAL;
4675 break;
4676
4677 case VPPCOM_ATTR_GET_ERROR:
4678 if (buffer && buflen && (*buflen >= sizeof (int)))
4679 {
4680 *(int *) buffer = 0;
4681 *buflen = sizeof (int);
4682
4683 if (VPPCOM_DEBUG > 2)
4684 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_ERROR: %d, "
4685 "buflen %d, #VPP-TBD#", getpid (),
4686 *(int *) buffer, *buflen);
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004687 if (VPPCOM_DEBUG > 0)
4688 {
4689 /* *INDENT-OFF* */
4690 ELOG_TYPE_DECLARE (e) =
4691 {
4692 .format = "VPPCOM_ATTR_GET_ERROR: %d buflen=%d",
4693 .format_args = "i4i4",
4694 };
4695
4696 struct {
4697 u32 data[2];
4698 } * ed;
4699
4700 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4701 ed->data[0] = *(int *) buffer;
4702 ed->data[1] = *buflen;
4703 /* *INDENT-ON* */
4704 }
Dave Wallace048b1d62018-01-03 22:24:41 -05004705 }
4706 else
4707 rv = VPPCOM_EINVAL;
4708 break;
4709
4710 case VPPCOM_ATTR_GET_TX_FIFO_LEN:
4711 if (buffer && buflen && (*buflen >= sizeof (u32)))
4712 {
4713 svm_fifo_t *tx_fifo;
4714
4715 tx_fifo = ((!session->is_cut_thru || session->is_server) ?
4716 session->server_tx_fifo : session->server_rx_fifo);
4717
4718 /* VPP-TBD */
4719 *(size_t *) buffer = (session->sndbuf_size ? session->sndbuf_size :
4720 tx_fifo ? tx_fifo->nitems :
4721 vcm->cfg.tx_fifo_size);
4722 *buflen = sizeof (u32);
4723
4724 if (VPPCOM_DEBUG > 2)
4725 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_TX_FIFO_LEN: %u (0x%x), "
4726 "buflen %d, #VPP-TBD#", getpid (),
4727 *(size_t *) buffer, *(size_t *) buffer, *buflen);
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004728 if (VPPCOM_DEBUG > 0)
4729 {
4730 /* *INDENT-OFF* */
4731 ELOG_TYPE_DECLARE (e) =
4732 {
4733 .format = "VPPCOM_ATTR_GET_TX_FIFO_LEN: 0x%x buflen=%d",
4734 .format_args = "i4i4",
4735 };
4736
4737 struct {
4738 u32 data[2];
4739 } * ed;
4740
4741 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4742 ed->data[0] = *(size_t *) buffer;
4743 ed->data[1] = *buflen;
4744 /* *INDENT-ON* */
4745 }
Dave Wallace048b1d62018-01-03 22:24:41 -05004746 }
4747 else
4748 rv = VPPCOM_EINVAL;
4749 break;
4750
4751 case VPPCOM_ATTR_SET_TX_FIFO_LEN:
4752 if (buffer && buflen && (*buflen == sizeof (u32)))
4753 {
4754 /* VPP-TBD */
4755 session->sndbuf_size = *(u32 *) buffer;
4756 if (VPPCOM_DEBUG > 2)
4757 clib_warning ("VCL<%d>: VPPCOM_ATTR_SET_TX_FIFO_LEN: %u (0x%x), "
4758 "buflen %d, #VPP-TBD#", getpid (),
4759 session->sndbuf_size, session->sndbuf_size,
4760 *buflen);
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004761 if (VPPCOM_DEBUG > 0)
4762 {
4763 /* *INDENT-OFF* */
4764 ELOG_TYPE_DECLARE (e) =
4765 {
4766 .format = "VPPCOM_ATTR_SET_TX_FIFO_LEN: 0x%x buflen=%d",
4767 .format_args = "i4i4",
4768 };
4769
4770 struct {
4771 u32 data[2];
4772 } * ed;
4773
4774 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4775 ed->data[0] = session->sndbuf_size;
4776 ed->data[1] = *buflen;
4777 /* *INDENT-ON* */
4778 }
Dave Wallace048b1d62018-01-03 22:24:41 -05004779 }
4780 else
4781 rv = VPPCOM_EINVAL;
4782 break;
4783
4784 case VPPCOM_ATTR_GET_RX_FIFO_LEN:
4785 if (buffer && buflen && (*buflen >= sizeof (u32)))
4786 {
4787 svm_fifo_t *rx_fifo;
4788
4789 rx_fifo = ((!session->is_cut_thru || session->is_server) ?
4790 session->server_rx_fifo : session->server_tx_fifo);
4791
4792 /* VPP-TBD */
4793 *(size_t *) buffer = (session->rcvbuf_size ? session->rcvbuf_size :
4794 rx_fifo ? rx_fifo->nitems :
4795 vcm->cfg.rx_fifo_size);
4796 *buflen = sizeof (u32);
4797
4798 if (VPPCOM_DEBUG > 2)
4799 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_RX_FIFO_LEN: %u (0x%x), "
4800 "buflen %d, #VPP-TBD#", getpid (),
4801 *(size_t *) buffer, *(size_t *) buffer, *buflen);
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004802 if (VPPCOM_DEBUG > 0)
4803 {
4804 /* *INDENT-OFF* */
4805 ELOG_TYPE_DECLARE (e) =
4806 {
4807 .format = "VPPCOM_ATTR_GET_RX_FIFO_LEN: 0x%x buflen=%d",
4808 .format_args = "i4i4",
4809 };
4810
4811 struct {
4812 u32 data[2];
4813 } * ed;
4814
4815 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4816 ed->data[0] = *(size_t *) buffer;
4817 ed->data[1] = *buflen;
4818 /* *INDENT-ON* */
4819 }
Dave Wallace048b1d62018-01-03 22:24:41 -05004820 }
4821 else
4822 rv = VPPCOM_EINVAL;
4823 break;
4824
4825 case VPPCOM_ATTR_SET_RX_FIFO_LEN:
4826 if (buffer && buflen && (*buflen == sizeof (u32)))
4827 {
4828 /* VPP-TBD */
4829 session->rcvbuf_size = *(u32 *) buffer;
4830 if (VPPCOM_DEBUG > 2)
Dave Wallace7e2c31a2018-02-05 20:03:01 -05004831 clib_warning ("VCL<%d>: VPPCOM_ATTR_SET_RX_FIFO_LEN: %u (0x%x), "
Dave Wallace048b1d62018-01-03 22:24:41 -05004832 "buflen %d, #VPP-TBD#", getpid (),
4833 session->sndbuf_size, session->sndbuf_size,
4834 *buflen);
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004835 if (VPPCOM_DEBUG > 0)
4836 {
4837 /* *INDENT-OFF* */
4838 ELOG_TYPE_DECLARE (e) =
4839 {
Dave Wallace7e2c31a2018-02-05 20:03:01 -05004840 .format = "VPPCOM_ATTR_SET_RX_FIFO_LEN: 0x%x buflen=%d",
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004841 .format_args = "i4i4",
4842 };
4843
4844 struct {
4845 u32 data[2];
4846 } * ed;
4847
4848 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4849 ed->data[0] = session->sndbuf_size;
4850 ed->data[1] = *buflen;
4851 /* *INDENT-ON* */
4852 }
Dave Wallace048b1d62018-01-03 22:24:41 -05004853 }
4854 else
4855 rv = VPPCOM_EINVAL;
4856 break;
4857
4858 case VPPCOM_ATTR_GET_REUSEADDR:
4859 if (buffer && buflen && (*buflen >= sizeof (int)))
4860 {
4861 /* VPP-TBD */
4862 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
4863 VCL_SESS_ATTR_REUSEADDR);
4864 *buflen = sizeof (int);
4865
4866 if (VPPCOM_DEBUG > 2)
4867 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_REUSEADDR: %d, "
4868 "buflen %d, #VPP-TBD#", getpid (), *(int *) buffer,
4869 *buflen);
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004870 if (VPPCOM_DEBUG > 0)
4871 {
4872 /* *INDENT-OFF* */
4873 ELOG_TYPE_DECLARE (e) =
4874 {
4875 .format = "VPPCOM_ATTR_GET_REUSEADDR: %d buflen=%d",
4876 .format_args = "i4i4",
4877 };
4878
4879 struct {
4880 u32 data[2];
4881 } * ed;
4882
4883 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4884 ed->data[0] = *(int *) buffer;
4885 ed->data[1] = *buflen;
4886 /* *INDENT-ON* */
4887 }
Dave Wallace048b1d62018-01-03 22:24:41 -05004888 }
4889 else
4890 rv = VPPCOM_EINVAL;
4891 break;
4892
Stevenb5a11602017-10-11 09:59:30 -07004893 case VPPCOM_ATTR_SET_REUSEADDR:
Dave Wallace048b1d62018-01-03 22:24:41 -05004894 if (buffer && buflen && (*buflen == sizeof (int)) &&
4895 !VCL_SESS_ATTR_TEST (session->attr, VCL_SESS_ATTR_LISTEN))
4896 {
4897 /* VPP-TBD */
4898 if (*(int *) buffer)
4899 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_REUSEADDR);
4900 else
4901 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_REUSEADDR);
4902
4903 if (VPPCOM_DEBUG > 2)
4904 clib_warning ("VCL<%d>: VPPCOM_ATTR_SET_REUSEADDR: %d, "
4905 "buflen %d, #VPP-TBD#", getpid (),
4906 VCL_SESS_ATTR_TEST (session->attr,
4907 VCL_SESS_ATTR_REUSEADDR),
4908 *buflen);
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004909 if (VPPCOM_DEBUG > 0)
4910 {
4911 /* *INDENT-OFF* */
4912 ELOG_TYPE_DECLARE (e) =
4913 {
4914 .format = "VPPCOM_ATTR_SET_REUSEADDR: %d buflen=%d",
4915 .format_args = "i4i4",
4916 };
4917
4918 struct {
4919 u32 data[2];
4920 } * ed;
4921
4922 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4923 ed->data[0] = VCL_SESS_ATTR_TEST (session->attr,
4924 VCL_SESS_ATTR_REUSEADDR);
4925 ed->data[1] = *buflen;
4926 /* *INDENT-ON* */
4927 }
Dave Wallace048b1d62018-01-03 22:24:41 -05004928 }
4929 else
4930 rv = VPPCOM_EINVAL;
4931 break;
4932
4933 case VPPCOM_ATTR_GET_REUSEPORT:
4934 if (buffer && buflen && (*buflen >= sizeof (int)))
4935 {
4936 /* VPP-TBD */
4937 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
4938 VCL_SESS_ATTR_REUSEPORT);
4939 *buflen = sizeof (int);
4940
4941 if (VPPCOM_DEBUG > 2)
4942 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_REUSEPORT: %d, "
4943 "buflen %d, #VPP-TBD#", getpid (), *(int *) buffer,
4944 *buflen);
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004945 if (VPPCOM_DEBUG > 0)
4946 {
4947 /* *INDENT-OFF* */
4948 ELOG_TYPE_DECLARE (e) =
4949 {
4950 .format = "VPPCOM_ATTR_GET_REUSEPORT: %d buflen=%d",
4951 .format_args = "i4i4",
4952 };
4953
4954 struct {
4955 u32 data[2];
4956 } * ed;
4957
4958 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4959 ed->data[0] = *(int *) buffer;
4960 ed->data[1] = *buflen;
4961 /* *INDENT-ON* */
4962 }
Dave Wallace048b1d62018-01-03 22:24:41 -05004963 }
4964 else
4965 rv = VPPCOM_EINVAL;
4966 break;
4967
4968 case VPPCOM_ATTR_SET_REUSEPORT:
4969 if (buffer && buflen && (*buflen == sizeof (int)) &&
4970 !VCL_SESS_ATTR_TEST (session->attr, VCL_SESS_ATTR_LISTEN))
4971 {
4972 /* VPP-TBD */
4973 if (*(int *) buffer)
4974 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_REUSEPORT);
4975 else
4976 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_REUSEPORT);
4977
4978 if (VPPCOM_DEBUG > 2)
4979 clib_warning ("VCL<%d>: VPPCOM_ATTR_SET_REUSEPORT: %d, "
4980 "buflen %d, #VPP-TBD#", getpid (),
4981 VCL_SESS_ATTR_TEST (session->attr,
4982 VCL_SESS_ATTR_REUSEPORT),
4983 *buflen);
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004984 if (VPPCOM_DEBUG > 0)
4985 {
4986 /* *INDENT-OFF* */
4987 ELOG_TYPE_DECLARE (e) =
4988 {
4989 .format = "VPPCOM_ATTR_SET_REUSEPORT: %d buflen=%d",
4990 .format_args = "i4i4",
4991 };
4992
4993 struct {
4994 u32 data[2];
4995 } * ed;
4996
4997 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4998 ed->data[0] = VCL_SESS_ATTR_TEST (session->attr,
4999 VCL_SESS_ATTR_REUSEPORT);
5000 ed->data[1] = *buflen;
5001 /* *INDENT-ON* */
5002 }
Dave Wallace048b1d62018-01-03 22:24:41 -05005003 }
5004 else
5005 rv = VPPCOM_EINVAL;
5006 break;
5007
5008 case VPPCOM_ATTR_GET_BROADCAST:
5009 if (buffer && buflen && (*buflen >= sizeof (int)))
5010 {
5011 /* VPP-TBD */
5012 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
5013 VCL_SESS_ATTR_BROADCAST);
5014 *buflen = sizeof (int);
5015
5016 if (VPPCOM_DEBUG > 2)
5017 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_BROADCAST: %d, "
5018 "buflen %d, #VPP-TBD#", getpid (), *(int *) buffer,
5019 *buflen);
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08005020 if (VPPCOM_DEBUG > 0)
5021 {
5022 /* *INDENT-OFF* */
5023 ELOG_TYPE_DECLARE (e) =
5024 {
5025 .format = "VPPCOM_ATTR_GET_BROADCAST: %d buflen=%d",
5026 .format_args = "i4i4",
5027 };
5028
5029 struct {
5030 u32 data[2];
5031 } * ed;
5032
5033 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
5034 ed->data[0] = *(int *) buffer;
5035 ed->data[1] = *buflen;
5036 /* *INDENT-ON* */
5037 }
Dave Wallace048b1d62018-01-03 22:24:41 -05005038 }
5039 else
5040 rv = VPPCOM_EINVAL;
Stevenb5a11602017-10-11 09:59:30 -07005041 break;
5042
5043 case VPPCOM_ATTR_SET_BROADCAST:
Dave Wallace048b1d62018-01-03 22:24:41 -05005044 if (buffer && buflen && (*buflen == sizeof (int)))
5045 {
5046 /* VPP-TBD */
5047 if (*(int *) buffer)
5048 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_BROADCAST);
5049 else
5050 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_BROADCAST);
5051
5052 if (VPPCOM_DEBUG > 2)
5053 clib_warning ("VCL<%d>: VPPCOM_ATTR_SET_BROADCAST: %d, "
5054 "buflen %d, #VPP-TBD#", getpid (),
5055 VCL_SESS_ATTR_TEST (session->attr,
5056 VCL_SESS_ATTR_BROADCAST),
5057 *buflen);
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005058 if (VPPCOM_DEBUG > 0)
5059 {
5060 /* *INDENT-OFF* */
5061 ELOG_TYPE_DECLARE (e) =
5062 {
5063 .format = "VPPCOM_ATTR_SET_BROADCAST: %d buflen=%d",
5064 .format_args = "i4i4",
5065 };
5066
5067 struct {
5068 u32 data[2];
5069 } * ed;
5070
5071 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
5072 ed->data[0] = VCL_SESS_ATTR_TEST (session->attr,
5073 VCL_SESS_ATTR_BROADCAST);
5074 ed->data[1] = *buflen;
5075 /* *INDENT-ON* */
5076 }
Dave Wallace048b1d62018-01-03 22:24:41 -05005077 }
5078 else
5079 rv = VPPCOM_EINVAL;
5080 break;
5081
5082 case VPPCOM_ATTR_GET_V6ONLY:
5083 if (buffer && buflen && (*buflen >= sizeof (int)))
5084 {
5085 /* VPP-TBD */
5086 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
5087 VCL_SESS_ATTR_V6ONLY);
5088 *buflen = sizeof (int);
5089
5090 if (VPPCOM_DEBUG > 2)
5091 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_V6ONLY: %d, "
5092 "buflen %d, #VPP-TBD#", getpid (), *(int *) buffer,
5093 *buflen);
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005094 if (VPPCOM_DEBUG > 0)
5095 {
5096 /* *INDENT-OFF* */
5097 ELOG_TYPE_DECLARE (e) =
5098 {
5099 .format = "VPPCOM_ATTR_GET_V6ONLY: %d buflen=%d",
5100 .format_args = "i4i4",
5101 };
5102
5103 struct {
5104 u32 data[2];
5105 } * ed;
5106
5107 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
5108 ed->data[0] = *(int *) buffer;
5109 ed->data[1] = *buflen;
5110 /* *INDENT-ON* */
5111 }
Dave Wallace048b1d62018-01-03 22:24:41 -05005112 }
5113 else
5114 rv = VPPCOM_EINVAL;
Stevenb5a11602017-10-11 09:59:30 -07005115 break;
5116
5117 case VPPCOM_ATTR_SET_V6ONLY:
Dave Wallace048b1d62018-01-03 22:24:41 -05005118 if (buffer && buflen && (*buflen == sizeof (int)))
5119 {
5120 /* VPP-TBD */
5121 if (*(int *) buffer)
5122 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_V6ONLY);
5123 else
5124 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_V6ONLY);
5125
5126 if (VPPCOM_DEBUG > 2)
5127 clib_warning ("VCL<%d>: VPPCOM_ATTR_SET_V6ONLY: %d, "
5128 "buflen %d, #VPP-TBD#", getpid (),
5129 VCL_SESS_ATTR_TEST (session->attr,
5130 VCL_SESS_ATTR_V6ONLY), *buflen);
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005131 if (VPPCOM_DEBUG > 0)
5132 {
5133 /* *INDENT-OFF* */
5134 ELOG_TYPE_DECLARE (e) =
5135 {
5136 .format = "VPPCOM_ATTR_SET_V6ONLY: %d buflen=%d",
5137 .format_args = "i4i4",
5138 };
5139
5140 struct {
5141 u32 data[2];
5142 } * ed;
5143
5144 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
5145 ed->data[0] = VCL_SESS_ATTR_TEST (session->attr,
5146 VCL_SESS_ATTR_V6ONLY);
5147 ed->data[1] = *buflen;
5148 /* *INDENT-ON* */
5149 }
Dave Wallace048b1d62018-01-03 22:24:41 -05005150 }
5151 else
5152 rv = VPPCOM_EINVAL;
5153 break;
5154
5155 case VPPCOM_ATTR_GET_KEEPALIVE:
5156 if (buffer && buflen && (*buflen >= sizeof (int)))
5157 {
5158 /* VPP-TBD */
5159 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
5160 VCL_SESS_ATTR_KEEPALIVE);
5161 *buflen = sizeof (int);
5162
5163 if (VPPCOM_DEBUG > 2)
5164 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_KEEPALIVE: %d, "
5165 "buflen %d, #VPP-TBD#", getpid (), *(int *) buffer,
5166 *buflen);
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005167 if (VPPCOM_DEBUG > 0)
5168 {
5169 /* *INDENT-OFF* */
5170 ELOG_TYPE_DECLARE (e) =
5171 {
5172 .format = "VPPCOM_ATTR_GET_KEEPALIVE: %d buflen=%d",
5173 .format_args = "i4i4",
5174 };
5175
5176 struct {
5177 u32 data[2];
5178 } * ed;
5179
5180 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
5181 ed->data[0] = *(int *) buffer;
5182 ed->data[1] = *buflen;
5183 /* *INDENT-ON* */
5184 }
Dave Wallace048b1d62018-01-03 22:24:41 -05005185 }
5186 else
5187 rv = VPPCOM_EINVAL;
Stevenb5a11602017-10-11 09:59:30 -07005188 break;
Stevenbccd3392017-10-12 20:42:21 -07005189
5190 case VPPCOM_ATTR_SET_KEEPALIVE:
Dave Wallace048b1d62018-01-03 22:24:41 -05005191 if (buffer && buflen && (*buflen == sizeof (int)))
5192 {
5193 /* VPP-TBD */
5194 if (*(int *) buffer)
5195 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_KEEPALIVE);
5196 else
5197 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_KEEPALIVE);
5198
5199 if (VPPCOM_DEBUG > 2)
5200 clib_warning ("VCL<%d>: VPPCOM_ATTR_SET_KEEPALIVE: %d, "
5201 "buflen %d, #VPP-TBD#", getpid (),
5202 VCL_SESS_ATTR_TEST (session->attr,
5203 VCL_SESS_ATTR_KEEPALIVE),
5204 *buflen);
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005205 if (VPPCOM_DEBUG > 0)
5206 {
5207 /* *INDENT-OFF* */
5208 ELOG_TYPE_DECLARE (e) =
5209 {
5210 .format = "VPPCOM_ATTR_SET_KEEPALIVE: %d buflen=%d",
5211 .format_args = "i4i4",
5212 };
5213
5214 struct {
5215 u32 data[2];
5216 } * ed;
5217
5218 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
5219 ed->data[0] = VCL_SESS_ATTR_TEST (session->attr,
5220 VCL_SESS_ATTR_KEEPALIVE);
5221 ed->data[1] = *buflen;
5222 /* *INDENT-ON* */
5223 }
Dave Wallace048b1d62018-01-03 22:24:41 -05005224 }
5225 else
5226 rv = VPPCOM_EINVAL;
5227 break;
5228
5229 case VPPCOM_ATTR_GET_TCP_NODELAY:
5230 if (buffer && buflen && (*buflen >= sizeof (int)))
5231 {
5232 /* VPP-TBD */
5233 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
5234 VCL_SESS_ATTR_TCP_NODELAY);
5235 *buflen = sizeof (int);
5236
5237 if (VPPCOM_DEBUG > 2)
5238 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_TCP_NODELAY: %d, "
5239 "buflen %d, #VPP-TBD#", getpid (), *(int *) buffer,
5240 *buflen);
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005241 if (VPPCOM_DEBUG > 0)
5242 {
5243 /* *INDENT-OFF* */
5244 ELOG_TYPE_DECLARE (e) =
5245 {
5246 .format = "VPPCOM_ATTR_GET_TCP_NODELAY: %d buflen=%d",
5247 .format_args = "i4i4",
5248 };
5249
5250 struct {
5251 u32 data[2];
5252 } * ed;
5253
5254 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
5255 ed->data[0] = *(int *) buffer;
5256 ed->data[1] = *buflen;
5257 /* *INDENT-ON* */
5258 }
Dave Wallace048b1d62018-01-03 22:24:41 -05005259 }
5260 else
5261 rv = VPPCOM_EINVAL;
5262 break;
5263
5264 case VPPCOM_ATTR_SET_TCP_NODELAY:
5265 if (buffer && buflen && (*buflen == sizeof (int)))
5266 {
5267 /* VPP-TBD */
5268 if (*(int *) buffer)
5269 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_TCP_NODELAY);
5270 else
5271 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_TCP_NODELAY);
5272
5273 if (VPPCOM_DEBUG > 2)
5274 clib_warning ("VCL<%d>: VPPCOM_ATTR_SET_TCP_NODELAY: %d, "
5275 "buflen %d, #VPP-TBD#", getpid (),
5276 VCL_SESS_ATTR_TEST (session->attr,
5277 VCL_SESS_ATTR_TCP_NODELAY),
5278 *buflen);
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005279 if (VPPCOM_DEBUG > 0)
5280 {
5281 /* *INDENT-OFF* */
5282 ELOG_TYPE_DECLARE (e) =
5283 {
5284 .format = "VPPCOM_ATTR_SET_TCP_NODELAY: %d buflen=%d",
5285 .format_args = "i4i4",
5286 };
5287
5288 struct {
5289 u32 data[2];
5290 } * ed;
5291
5292 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
5293 ed->data[0] = VCL_SESS_ATTR_TEST (session->attr,
5294 VCL_SESS_ATTR_TCP_NODELAY);
5295 ed->data[1] = *buflen;
5296 /* *INDENT-ON* */
5297 }
Dave Wallace048b1d62018-01-03 22:24:41 -05005298 }
5299 else
5300 rv = VPPCOM_EINVAL;
5301 break;
5302
5303 case VPPCOM_ATTR_GET_TCP_KEEPIDLE:
5304 if (buffer && buflen && (*buflen >= sizeof (int)))
5305 {
5306 /* VPP-TBD */
5307 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
5308 VCL_SESS_ATTR_TCP_KEEPIDLE);
5309 *buflen = sizeof (int);
5310
5311 if (VPPCOM_DEBUG > 2)
5312 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_TCP_KEEPIDLE: %d, "
5313 "buflen %d, #VPP-TBD#", getpid (), *(int *) buffer,
5314 *buflen);
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005315 if (VPPCOM_DEBUG > 0)
5316 {
5317 /* *INDENT-OFF* */
5318 ELOG_TYPE_DECLARE (e) =
5319 {
5320 .format = "VPPCOM_ATTR_GET_TCP_KEEPIDLE: %d buflen=%d",
5321 .format_args = "i4i4",
5322 };
5323
5324 struct {
5325 u32 data[2];
5326 } * ed;
5327
5328 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
5329 ed->data[0] = *(int *) buffer;
5330 ed->data[1] = *buflen;
5331 /* *INDENT-ON* */
5332 }
Dave Wallace048b1d62018-01-03 22:24:41 -05005333 }
5334 else
5335 rv = VPPCOM_EINVAL;
Stevenbccd3392017-10-12 20:42:21 -07005336 break;
5337
5338 case VPPCOM_ATTR_SET_TCP_KEEPIDLE:
Dave Wallace048b1d62018-01-03 22:24:41 -05005339 if (buffer && buflen && (*buflen == sizeof (int)))
5340 {
5341 /* VPP-TBD */
5342 if (*(int *) buffer)
5343 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_TCP_KEEPIDLE);
5344 else
5345 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_TCP_KEEPIDLE);
5346
5347 if (VPPCOM_DEBUG > 2)
5348 clib_warning ("VCL<%d>: VPPCOM_ATTR_SET_TCP_KEEPIDLE: %d, "
5349 "buflen %d, #VPP-TBD#", getpid (),
5350 VCL_SESS_ATTR_TEST (session->attr,
5351 VCL_SESS_ATTR_TCP_KEEPIDLE),
5352 *buflen);
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005353 if (VPPCOM_DEBUG > 0)
5354 {
5355 /* *INDENT-OFF* */
5356 ELOG_TYPE_DECLARE (e) =
5357 {
5358 .format = "VPPCOM_ATTR_SET_TCP_KEEPIDLE: %d buflen=%d",
5359 .format_args = "i4i4",
5360 };
5361
5362 struct {
5363 u32 data[2];
5364 } * ed;
5365
5366 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
5367 ed->data[0] = VCL_SESS_ATTR_TEST (session->attr,
5368 VCL_SESS_ATTR_TCP_KEEPIDLE);
5369 ed->data[1] = *buflen;
5370 /* *INDENT-ON* */
5371 }
Dave Wallace048b1d62018-01-03 22:24:41 -05005372 }
5373 else
5374 rv = VPPCOM_EINVAL;
5375 break;
5376
5377 case VPPCOM_ATTR_GET_TCP_KEEPINTVL:
5378 if (buffer && buflen && (*buflen >= sizeof (int)))
5379 {
5380 /* VPP-TBD */
5381 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
5382 VCL_SESS_ATTR_TCP_KEEPINTVL);
5383 *buflen = sizeof (int);
5384
5385 if (VPPCOM_DEBUG > 2)
5386 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_TCP_KEEPINTVL: %d, "
5387 "buflen %d, #VPP-TBD#", getpid (), *(int *) buffer,
5388 *buflen);
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005389 if (VPPCOM_DEBUG > 0)
5390 {
5391 /* *INDENT-OFF* */
5392 ELOG_TYPE_DECLARE (e) =
5393 {
5394 .format = "VPPCOM_ATTR_GET_TCP_KEEPIDLE: %d buflen=%d",
5395 .format_args = "i4i4",
5396 };
5397
5398 struct {
5399 u32 data[2];
5400 } * ed;
5401
5402 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
5403 ed->data[0] = *(int *) buffer;
5404 ed->data[1] = *buflen;
5405 /* *INDENT-ON* */
5406 }
Dave Wallace048b1d62018-01-03 22:24:41 -05005407 }
5408 else
5409 rv = VPPCOM_EINVAL;
Stevenbccd3392017-10-12 20:42:21 -07005410 break;
5411
5412 case VPPCOM_ATTR_SET_TCP_KEEPINTVL:
Dave Wallace048b1d62018-01-03 22:24:41 -05005413 if (buffer && buflen && (*buflen == sizeof (int)))
5414 {
5415 /* VPP-TBD */
5416 if (*(int *) buffer)
5417 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_TCP_KEEPINTVL);
5418 else
5419 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_TCP_KEEPINTVL);
5420
5421 if (VPPCOM_DEBUG > 2)
5422 clib_warning ("VCL<%d>: VPPCOM_ATTR_SET_TCP_KEEPINTVL: %d, "
5423 "buflen %d, #VPP-TBD#", getpid (),
5424 VCL_SESS_ATTR_TEST (session->attr,
5425 VCL_SESS_ATTR_TCP_KEEPINTVL),
5426 *buflen);
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005427 if (VPPCOM_DEBUG > 0)
5428 {
5429 /* *INDENT-OFF* */
5430 ELOG_TYPE_DECLARE (e) =
5431 {
5432 .format = "VPPCOM_ATTR_SET_TCP_KEEPINTVL: %d buflen=%d",
5433 .format_args = "i4i4",
5434 };
5435
5436 struct {
5437 u32 data[2];
5438 } * ed;
5439
5440 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
5441 ed->data[0] = VCL_SESS_ATTR_TEST (session->attr,
5442 VCL_SESS_ATTR_TCP_KEEPINTVL);
5443 ed->data[1] = *buflen;
5444 /* *INDENT-ON* */
5445 }
Dave Wallace048b1d62018-01-03 22:24:41 -05005446 }
5447 else
5448 rv = VPPCOM_EINVAL;
5449 break;
5450
5451 case VPPCOM_ATTR_GET_TCP_USER_MSS:
5452 if (buffer && buflen && (*buflen >= sizeof (u32)))
5453 {
5454 /* VPP-TBD */
5455 *(u32 *) buffer = session->user_mss;
5456 *buflen = sizeof (int);
5457
5458 if (VPPCOM_DEBUG > 2)
5459 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_TCP_USER_MSS: %d, "
5460 "buflen %d, #VPP-TBD#", getpid (), *(int *) buffer,
5461 *buflen);
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005462 if (VPPCOM_DEBUG > 0)
5463 {
5464 /* *INDENT-OFF* */
5465 ELOG_TYPE_DECLARE (e) =
5466 {
5467 .format = "VPPCOM_ATTR_GET_TCP_USER_MSS: %d buflen=%d",
5468 .format_args = "i4i4",
5469 };
5470
5471 struct {
5472 u32 data[2];
5473 } * ed;
5474
5475 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
5476 ed->data[0] = *(int *) buffer;
5477 ed->data[1] = *buflen;
5478 /* *INDENT-ON* */
5479 }
Dave Wallace048b1d62018-01-03 22:24:41 -05005480 }
5481 else
5482 rv = VPPCOM_EINVAL;
5483 break;
5484
5485 case VPPCOM_ATTR_SET_TCP_USER_MSS:
5486 if (buffer && buflen && (*buflen == sizeof (u32)))
5487 {
5488 /* VPP-TBD */
5489 session->user_mss = *(u32 *) buffer;
5490
5491 if (VPPCOM_DEBUG > 2)
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005492 clib_warning ("VCL<%d>: VPPCOM_ATTR_SET_TCP_USER_MSS: %u, "
Dave Wallace048b1d62018-01-03 22:24:41 -05005493 "buflen %d, #VPP-TBD#", getpid (),
5494 session->user_mss, *buflen);
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005495 if (VPPCOM_DEBUG > 0)
5496 {
5497 /* *INDENT-OFF* */
5498 ELOG_TYPE_DECLARE (e) =
5499 {
5500 .format = "VPPCOM_ATTR_SET_TCP_USER_MSS: %d buflen=%d",
5501 .format_args = "i4i4",
5502 };
5503
5504 struct {
5505 u32 data[2];
5506 } * ed;
5507
5508 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
5509 ed->data[0] = session->user_mss;
5510 ed->data[1] = *buflen;
5511 /* *INDENT-ON* */
5512 }
Dave Wallace048b1d62018-01-03 22:24:41 -05005513 }
5514 else
5515 rv = VPPCOM_EINVAL;
Stevenbccd3392017-10-12 20:42:21 -07005516 break;
Dave Wallacee22aa742017-10-20 12:30:38 -04005517
5518 default:
5519 rv = VPPCOM_EINVAL;
5520 break;
Dave Wallace35830af2017-10-09 01:43:42 -04005521 }
5522
5523done:
5524 clib_spinlock_unlock (&vcm->sessions_lockp);
5525 return rv;
5526}
5527
Stevenac1f96d2017-10-24 16:03:58 -07005528int
5529vppcom_session_recvfrom (uint32_t session_index, void *buffer,
5530 uint32_t buflen, int flags, vppcom_endpt_t * ep)
5531{
Stevenac1f96d2017-10-24 16:03:58 -07005532 int rv = VPPCOM_OK;
5533 session_t *session = 0;
5534
5535 if (ep)
5536 {
5537 clib_spinlock_lock (&vcm->sessions_lockp);
5538 rv = vppcom_session_at_index (session_index, &session);
5539 if (PREDICT_FALSE (rv))
5540 {
5541 clib_spinlock_unlock (&vcm->sessions_lockp);
5542 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05005543 clib_warning ("VCL<%d>: invalid session, "
5544 "sid (%u) has been closed!",
Dave Wallace2e005bb2017-11-07 01:21:39 -05005545 getpid (), session_index);
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005546 if (VPPCOM_DEBUG > 0)
5547 {
5548 /* *INDENT-OFF* */
5549 ELOG_TYPE_DECLARE (e) =
5550 {
5551 .format = "invalid session: %d closed",
5552 .format_args = "i4",
5553 };
5554
5555 struct {
5556 u32 data;
5557 } * ed;
5558
5559 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, vcm->elog_track);
5560 ed->data = session_index;
5561 /* *INDENT-ON* */
5562 }
Dave Wallacefaf9d772017-10-26 16:12:04 -04005563 rv = VPPCOM_EBADFD;
5564 clib_spinlock_unlock (&vcm->sessions_lockp);
5565 goto done;
Stevenac1f96d2017-10-24 16:03:58 -07005566 }
Stevenac1f96d2017-10-24 16:03:58 -07005567 ep->is_ip4 = session->peer_addr.is_ip4;
5568 ep->port = session->peer_port;
5569 if (session->peer_addr.is_ip4)
5570 clib_memcpy (ep->ip, &session->peer_addr.ip46.ip4,
5571 sizeof (ip4_address_t));
5572 else
5573 clib_memcpy (ep->ip, &session->peer_addr.ip46.ip6,
5574 sizeof (ip6_address_t));
5575 clib_spinlock_unlock (&vcm->sessions_lockp);
Stevenac1f96d2017-10-24 16:03:58 -07005576 }
Steven58f464e2017-10-25 12:33:12 -07005577
5578 if (flags == 0)
Stevenac1f96d2017-10-24 16:03:58 -07005579 rv = vppcom_session_read (session_index, buffer, buflen);
5580 else if (flags & MSG_PEEK)
Steven58f464e2017-10-25 12:33:12 -07005581 rv = vppcom_session_peek (session_index, buffer, buflen);
Stevenac1f96d2017-10-24 16:03:58 -07005582 else
5583 {
Dave Wallace048b1d62018-01-03 22:24:41 -05005584 clib_warning ("VCL<%d>: Unsupport flags for recvfrom %d",
5585 getpid (), flags);
Stevenac1f96d2017-10-24 16:03:58 -07005586 rv = VPPCOM_EAFNOSUPPORT;
5587 }
5588
Dave Wallacefaf9d772017-10-26 16:12:04 -04005589done:
Stevenac1f96d2017-10-24 16:03:58 -07005590 return rv;
5591}
5592
5593int
5594vppcom_session_sendto (uint32_t session_index, void *buffer,
5595 uint32_t buflen, int flags, vppcom_endpt_t * ep)
5596{
Dave Wallace617dffa2017-10-26 14:47:06 -04005597 if (!buffer)
5598 return VPPCOM_EINVAL;
5599
5600 if (ep)
5601 {
5602 // TBD
5603 return VPPCOM_EINVAL;
5604 }
5605
5606 if (flags)
5607 {
5608 // TBD check the flags and do the right thing
5609 if (VPPCOM_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05005610 clib_warning ("VCL<%d>: handling flags 0x%u (%d) "
5611 "not implemented yet.", getpid (), flags, flags);
Dave Wallace617dffa2017-10-26 14:47:06 -04005612 }
5613
5614 return (vppcom_session_write (session_index, buffer, buflen));
Stevenac1f96d2017-10-24 16:03:58 -07005615}
5616
Dave Wallace048b1d62018-01-03 22:24:41 -05005617int
5618vppcom_poll (vcl_poll_t * vp, uint32_t n_sids, double wait_for_time)
5619{
5620 f64 timeout = clib_time_now (&vcm->clib_time) + wait_for_time;
5621 u32 i, keep_trying = 1;
5622 int rv, num_ev = 0;
5623
5624 if (VPPCOM_DEBUG > 3)
5625 clib_warning ("VCL<%d>: vp %p, nsids %u, wait_for_time %f",
5626 getpid (), vp, n_sids, wait_for_time);
5627
5628 if (!vp)
5629 return VPPCOM_EFAULT;
5630
5631 do
5632 {
5633 session_t *session;
5634
5635 for (i = 0; i < n_sids; i++)
5636 {
5637 ASSERT (vp[i].revents);
5638
5639 VCL_LOCK_AND_GET_SESSION (vp[i].sid, &session);
5640 clib_spinlock_unlock (&vcm->sessions_lockp);
5641
5642 if (*vp[i].revents)
5643 *vp[i].revents = 0;
5644
5645 if (POLLIN & vp[i].events)
5646 {
5647 VCL_LOCK_AND_GET_SESSION (vp[i].sid, &session);
5648 rv = vppcom_session_read_ready (session, vp[i].sid);
5649 clib_spinlock_unlock (&vcm->sessions_lockp);
5650 if (rv > 0)
5651 {
5652 *vp[i].revents |= POLLIN;
5653 num_ev++;
5654 }
5655 else if (rv < 0)
5656 {
5657 switch (rv)
5658 {
5659 case VPPCOM_ECONNRESET:
5660 *vp[i].revents = POLLHUP;
5661 break;
5662
5663 default:
5664 *vp[i].revents = POLLERR;
5665 break;
5666 }
5667 num_ev++;
5668 }
5669 }
5670
5671 if (POLLOUT & vp[i].events)
5672 {
5673 VCL_LOCK_AND_GET_SESSION (vp[i].sid, &session);
5674 rv = vppcom_session_write_ready (session, vp[i].sid);
5675 clib_spinlock_unlock (&vcm->sessions_lockp);
5676 if (rv > 0)
5677 {
5678 *vp[i].revents |= POLLOUT;
5679 num_ev++;
5680 }
5681 else if (rv < 0)
5682 {
5683 switch (rv)
5684 {
5685 case VPPCOM_ECONNRESET:
5686 *vp[i].revents = POLLHUP;
5687 break;
5688
5689 default:
5690 *vp[i].revents = POLLERR;
5691 break;
5692 }
5693 num_ev++;
5694 }
5695 }
5696
5697 if (0)
5698 {
5699 done:
5700 *vp[i].revents = POLLNVAL;
5701 num_ev++;
5702 }
5703 }
5704 if (wait_for_time != -1)
5705 keep_trying = (clib_time_now (&vcm->clib_time) <= timeout) ? 1 : 0;
5706 }
5707 while ((num_ev == 0) && keep_trying);
5708
5709 if (VPPCOM_DEBUG > 3)
5710 {
5711 clib_warning ("VCL<%d>: returning %d", getpid (), num_ev);
5712 for (i = 0; i < n_sids; i++)
5713 {
5714 clib_warning ("VCL<%d>: vp[%d].sid %d (0x%x), .events 0x%x, "
5715 ".revents 0x%x", getpid (), i, vp[i].sid, vp[i].sid,
5716 vp[i].events, *vp[i].revents);
5717 }
5718 }
5719 return num_ev;
5720}
5721
Dave Wallacee22aa742017-10-20 12:30:38 -04005722/*
5723 * fd.io coding-style-patch-verification: ON
5724 *
5725 * Local Variables:
5726 * eval: (c-set-style "gnu")
5727 * End:
5728 */