blob: a66926d8731a9577f8bbb2731955a932d8a9bf00 [file] [log] [blame]
Dave Wallace543852a2017-08-03 02:11:34 -04001/*
Dave Wallace33e002b2017-09-06 01:20:02 -04002 * Copyright (c) 2017 Cisco and/or its affiliates.
Dave Wallace543852a2017-08-03 02:11:34 -04003 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this
5 * You may obtain a copy of the License at:
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include <stdio.h>
17#include <stdlib.h>
18#include <signal.h>
19#include <svm/svm_fifo_segment.h>
20#include <vlibmemory/api.h>
21#include <vpp/api/vpe_msg_enum.h>
22#include <vnet/session/application_interface.h>
Dave Wallace5c7cf1c2017-10-24 04:12:18 -040023#include <vcl/vppcom.h>
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -080024#include <vcl/vcl_event.h>
Dave Wallace543852a2017-08-03 02:11:34 -040025#include <vlib/unix/unix.h>
26#include <vppinfra/vec_bootstrap.h>
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -080027#include <vppinfra/elog.h>
Dave Wallace543852a2017-08-03 02:11:34 -040028
29#define vl_typedefs /* define message structures */
30#include <vpp/api/vpe_all_api_h.h>
31#undef vl_typedefs
32
33/* declare message handlers for each api */
34
35#define vl_endianfun /* define message structures */
36#include <vpp/api/vpe_all_api_h.h>
37#undef vl_endianfun
38
39/* instantiate all the print functions we know about */
40#define vl_print(handle, ...)
41#define vl_printfun
42#include <vpp/api/vpe_all_api_h.h>
43#undef vl_printfun
44
45#if (CLIB_DEBUG > 0)
Dave Wallace498b3a52017-11-09 13:00:34 -050046/* Set VPPCOM_DEBUG_INIT 2 for connection debug,
47 * 3 for read/write debug output
48 * or
49 * export VCL_DEBUG=<#> to set dynamically.
50 */
51#define VPPCOM_DEBUG_INIT 1
Dave Wallace543852a2017-08-03 02:11:34 -040052#else
Dave Wallace498b3a52017-11-09 13:00:34 -050053#define VPPCOM_DEBUG_INIT 0
Dave Wallace543852a2017-08-03 02:11:34 -040054#endif
55
Dave Wallace498b3a52017-11-09 13:00:34 -050056#define VPPCOM_DEBUG vcm->debug
57
Dave Wallace543852a2017-08-03 02:11:34 -040058/*
59 * VPPCOM Private definitions and functions.
60 */
61typedef enum
62{
63 STATE_APP_START,
64 STATE_APP_CONN_VPP,
65 STATE_APP_ENABLED,
66 STATE_APP_ATTACHED,
67} app_state_t;
68
69typedef enum
70{
Dave Wallace4878cbe2017-11-21 03:45:09 -050071 STATE_START = 0x01,
72 STATE_CONNECT = 0x02,
73 STATE_LISTEN = 0x04,
74 STATE_ACCEPT = 0x08,
75 STATE_CLOSE_ON_EMPTY = 0x10,
76 STATE_DISCONNECT = 0x20,
77 STATE_FAILED = 0x40
Dave Wallace543852a2017-08-03 02:11:34 -040078} session_state_t;
79
Dave Wallace4878cbe2017-11-21 03:45:09 -050080#define SERVER_STATE_OPEN (STATE_ACCEPT|STATE_CLOSE_ON_EMPTY)
81#define CLIENT_STATE_OPEN (STATE_CONNECT|STATE_CLOSE_ON_EMPTY)
82
Dave Wallacef7f809c2017-10-03 01:48:42 -040083typedef struct epoll_event vppcom_epoll_event_t;
84
85typedef struct
86{
87 u32 next_sid;
88 u32 prev_sid;
89 u32 vep_idx;
90 vppcom_epoll_event_t ev;
91#define VEP_DEFAULT_ET_MASK (EPOLLIN|EPOLLOUT)
Dave Wallace60caa062017-11-10 17:07:13 -050092#define VEP_UNSUPPORTED_EVENTS (EPOLLONESHOT|EPOLLEXCLUSIVE)
Dave Wallacef7f809c2017-10-03 01:48:42 -040093 u32 et_mask;
94} vppcom_epoll_t;
95
Dave Wallace543852a2017-08-03 02:11:34 -040096typedef struct
97{
Dave Wallace35830af2017-10-09 01:43:42 -040098 u8 is_ip4;
99 ip46_address_t ip46;
100} vppcom_ip46_t;
101
Dave Wallace048b1d62018-01-03 22:24:41 -0500102enum
103{
104 VCL_SESS_ATTR_SERVER,
105 VCL_SESS_ATTR_CUT_THRU,
106 VCL_SESS_ATTR_VEP,
107 VCL_SESS_ATTR_VEP_SESSION,
108 VCL_SESS_ATTR_LISTEN, // SOL_SOCKET,SO_ACCEPTCONN
109 VCL_SESS_ATTR_NONBLOCK, // fcntl,O_NONBLOCK
110 VCL_SESS_ATTR_REUSEADDR, // SOL_SOCKET,SO_REUSEADDR
111 VCL_SESS_ATTR_REUSEPORT, // SOL_SOCKET,SO_REUSEPORT
112 VCL_SESS_ATTR_BROADCAST, // SOL_SOCKET,SO_BROADCAST
113 VCL_SESS_ATTR_V6ONLY, // SOL_TCP,IPV6_V6ONLY
114 VCL_SESS_ATTR_KEEPALIVE, // SOL_SOCKET,SO_KEEPALIVE
115 VCL_SESS_ATTR_TCP_NODELAY, // SOL_TCP,TCP_NODELAY
116 VCL_SESS_ATTR_TCP_KEEPIDLE, // SOL_TCP,TCP_KEEPIDLE
117 VCL_SESS_ATTR_TCP_KEEPINTVL, // SOL_TCP,TCP_KEEPINTVL
118 VCL_SESS_ATTR_MAX
119} vppcom_session_attr_t;
120
121#define VCL_SESS_ATTR_SET(ATTR, VAL) \
122do { \
123 (ATTR) |= 1 << (VAL); \
124 } while (0)
125
126#define VCL_SESS_ATTR_CLR(ATTR, VAL) \
127do { \
128 (ATTR) &= ~(1 << (VAL)); \
129 } while (0)
130
131#define VCL_SESS_ATTR_TEST(ATTR, VAL) \
132 ((ATTR) & (1 << (VAL)) ? 1 : 0)
133
Dave Wallace35830af2017-10-09 01:43:42 -0400134typedef struct
135{
Dave Wallace543852a2017-08-03 02:11:34 -0400136 volatile session_state_t state;
137
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -0800138 svm_fifo_t *rx_fifo;
139 svm_fifo_t *tx_fifo;
Dave Wallace048b1d62018-01-03 22:24:41 -0500140 u32 sndbuf_size; // VPP-TBD: Hack until support setsockopt(SO_SNDBUF)
141 u32 rcvbuf_size; // VPP-TBD: Hack until support setsockopt(SO_RCVBUF)
142 u32 user_mss; // VPP-TBD: Hack until support setsockopt(TCP_MAXSEG)
Dave Wallace60caa062017-11-10 17:07:13 -0500143 u8 *segment_name;
Dave Wallace543852a2017-08-03 02:11:34 -0400144 u32 sm_seg_index;
Dave Wallace60caa062017-11-10 17:07:13 -0500145 u32 client_context;
146 u64 vpp_handle;
Florin Corase86a8ed2018-01-05 03:20:25 -0800147 svm_queue_t *vpp_event_queue;
Dave Wallace543852a2017-08-03 02:11:34 -0400148
149 /* Socket configuration state */
Dave Wallacef7f809c2017-10-03 01:48:42 -0400150 u8 is_vep;
151 u8 is_vep_session;
Dave Wallace048b1d62018-01-03 22:24:41 -0500152 u32 attr;
Dave Wallacef7f809c2017-10-03 01:48:42 -0400153 u32 wait_cont_idx;
154 vppcom_epoll_t vep;
Dave Wallace048b1d62018-01-03 22:24:41 -0500155 int libc_epfd;
Dave Wallace35830af2017-10-09 01:43:42 -0400156 vppcom_ip46_t lcl_addr;
157 vppcom_ip46_t peer_addr;
Stevenac1f96d2017-10-24 16:03:58 -0700158 u16 lcl_port; // network order
159 u16 peer_port; // network order
Dave Wallace543852a2017-08-03 02:11:34 -0400160 u8 proto;
161 u64 client_queue_address;
162 u64 options[16];
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -0800163 elog_track_t elog_track;
Keith Burns (alagalah)12756512018-03-06 05:55:27 -0800164 vce_event_handler_reg_t *poll_reg;
Dave Wallace543852a2017-08-03 02:11:34 -0400165} session_t;
166
167typedef struct vppcom_cfg_t_
168{
169 u64 heapsize;
Dave Wallacec8f1ee62017-11-29 22:46:32 -0500170 u32 vpp_api_q_length;
Dave Wallace543852a2017-08-03 02:11:34 -0400171 u64 segment_baseva;
172 u32 segment_size;
173 u32 add_segment_size;
174 u32 preallocated_fifo_pairs;
175 u32 rx_fifo_size;
176 u32 tx_fifo_size;
177 u32 event_queue_size;
178 u32 listen_queue_size;
Dave Wallace774169b2017-11-01 20:07:40 -0400179 u8 app_proxy_transport_tcp;
180 u8 app_proxy_transport_udp;
181 u8 app_scope_local;
182 u8 app_scope_global;
Dave Wallace8af20542017-10-26 03:29:30 -0400183 u8 *namespace_id;
184 u64 namespace_secret;
Dave Wallace543852a2017-08-03 02:11:34 -0400185 f64 app_timeout;
186 f64 session_timeout;
187 f64 accept_timeout;
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -0800188 u32 event_ring_size;
189 char *event_log_path;
Dave Wallaceb5a86ee2018-02-16 18:26:11 -0500190 u8 *vpp_api_filename;
Dave Wallace543852a2017-08-03 02:11:34 -0400191} vppcom_cfg_t;
192
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800193/* VPPCOM Event typedefs */
194typedef enum vcl_event_id_
195{
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -0800196 VCL_EVENT_INVALID_EVENT,
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800197 VCL_EVENT_CONNECT_REQ_ACCEPTED,
Keith Burns (alagalah)410bcca2018-03-23 13:42:49 -0700198 VCL_EVENT_IOEVENT_RX_FIFO,
199 VCL_EVENT_IOEVENT_TX_FIFO,
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800200 VCL_EVENT_N_EVENTS
201} vcl_event_id_t;
202
Keith Burns (alagalah)410bcca2018-03-23 13:42:49 -0700203
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800204typedef struct vce_event_connect_request_
205{
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800206 u32 accepted_session_index;
207} vce_event_connect_request_t;
208
Keith Burns (alagalah)0d2b0d52018-03-06 15:55:22 -0800209typedef struct vppcom_session_listener
210{
211 vppcom_session_listener_cb user_cb;
212 vppcom_session_listener_errcb user_errcb;
213 void *user_cb_data;
214} vppcom_session_listener_t;
215
Keith Burns (alagalah)410bcca2018-03-23 13:42:49 -0700216typedef struct vppcom_session_ioevent_
217{
218 vppcom_session_ioevent_cb user_cb;
219 void *user_cb_data;
220} vppcom_session_ioevent_t;
221
222typedef struct vppcom_session_io_thread_
223{
224 pthread_t thread;
225 pthread_mutex_t vce_io_lock;
226 pthread_cond_t vce_io_cond;
227 u32 *active_session_indexes; //pool
228 vppcom_session_ioevent_t *ioevents; //pool
229 clib_spinlock_t io_sessions_lockp;
230} vppcom_session_io_thread_t;
231
Dave Wallace543852a2017-08-03 02:11:34 -0400232typedef struct vppcom_main_t_
233{
234 u8 init;
Dave Wallace498b3a52017-11-09 13:00:34 -0500235 u32 debug;
Dave Wallace543852a2017-08-03 02:11:34 -0400236 int main_cpu;
237
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -0800238 /* FIFO for accepted connections - used in epoll/select */
239 clib_spinlock_t session_fifo_lockp;
240 u32 *client_session_index_fifo;
241
Dave Wallaceb5a86ee2018-02-16 18:26:11 -0500242 /* vpp input queue */
Florin Corase86a8ed2018-01-05 03:20:25 -0800243 svm_queue_t *vl_input_queue;
Dave Wallace543852a2017-08-03 02:11:34 -0400244
245 /* API client handle */
246 u32 my_client_index;
Dave Wallace543852a2017-08-03 02:11:34 -0400247 /* Session pool */
248 clib_spinlock_t sessions_lockp;
249 session_t *sessions;
250
251 /* Hash table for disconnect processing */
252 uword *session_index_by_vpp_handles;
253
254 /* Select bitmaps */
255 clib_bitmap_t *rd_bitmap;
256 clib_bitmap_t *wr_bitmap;
257 clib_bitmap_t *ex_bitmap;
258
259 /* Our event queue */
Florin Corase86a8ed2018-01-05 03:20:25 -0800260 svm_queue_t *app_event_queue;
Dave Wallace543852a2017-08-03 02:11:34 -0400261
262 /* unique segment name counter */
263 u32 unique_segment_index;
264
Dave Wallace543852a2017-08-03 02:11:34 -0400265 /* For deadman timers */
266 clib_time_t clib_time;
267
268 /* State of the connection, shared between msg RX thread and main thread */
269 volatile app_state_t app_state;
270
271 vppcom_cfg_t cfg;
272
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800273 /* Event thread */
274 vce_event_thread_t event_thread;
275
Keith Burns (alagalah)410bcca2018-03-23 13:42:49 -0700276 /* IO thread */
277 vppcom_session_io_thread_t session_io_thread;
278
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800279 /* VPP Event-logger */
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -0800280 elog_main_t elog_main;
281 elog_track_t elog_track;
282
Dave Wallace543852a2017-08-03 02:11:34 -0400283 /* VNET_API_ERROR_FOO -> "Foo" hash table */
284 uword *error_string_by_error_number;
285} vppcom_main_t;
286
Dave Wallace2e005bb2017-11-07 01:21:39 -0500287/* NOTE: _vppcom_main is only used until the heap is allocated.
288 * Do not access it directly -- use vcm which will point to
289 * the heap allocated copy after init.
290 */
Dave Wallace498b3a52017-11-09 13:00:34 -0500291static vppcom_main_t _vppcom_main = {
292 .debug = VPPCOM_DEBUG_INIT,
293 .my_client_index = ~0
294};
Dave Wallace2e005bb2017-11-07 01:21:39 -0500295
296static vppcom_main_t *vcm = &_vppcom_main;
Dave Wallace543852a2017-08-03 02:11:34 -0400297
Dave Wallace048b1d62018-01-03 22:24:41 -0500298#define VCL_LOCK_AND_GET_SESSION(I, S) \
299do { \
300 clib_spinlock_lock (&vcm->sessions_lockp); \
301 rv = vppcom_session_at_index (I, S); \
302 if (PREDICT_FALSE (rv)) \
303 { \
304 clib_spinlock_unlock (&vcm->sessions_lockp); \
305 clib_warning ("VCL<%d>: ERROR: Invalid ##I (%u)!", \
306 getpid (), I); \
307 goto done; \
308 } \
Dave Wallace60caa062017-11-10 17:07:13 -0500309} while (0)
310
Dave Wallace543852a2017-08-03 02:11:34 -0400311static const char *
312vppcom_app_state_str (app_state_t state)
313{
314 char *st;
315
316 switch (state)
317 {
318 case STATE_APP_START:
319 st = "STATE_APP_START";
320 break;
321
322 case STATE_APP_CONN_VPP:
323 st = "STATE_APP_CONN_VPP";
324 break;
325
326 case STATE_APP_ENABLED:
327 st = "STATE_APP_ENABLED";
328 break;
329
330 case STATE_APP_ATTACHED:
331 st = "STATE_APP_ATTACHED";
332 break;
333
334 default:
335 st = "UNKNOWN_APP_STATE";
336 break;
337 }
338
339 return st;
340}
341
342static const char *
343vppcom_session_state_str (session_state_t state)
344{
345 char *st;
346
347 switch (state)
348 {
349 case STATE_START:
350 st = "STATE_START";
351 break;
352
353 case STATE_CONNECT:
354 st = "STATE_CONNECT";
355 break;
356
357 case STATE_LISTEN:
358 st = "STATE_LISTEN";
359 break;
360
361 case STATE_ACCEPT:
362 st = "STATE_ACCEPT";
363 break;
364
Dave Wallace4878cbe2017-11-21 03:45:09 -0500365 case STATE_CLOSE_ON_EMPTY:
366 st = "STATE_CLOSE_ON_EMPTY";
367 break;
368
Dave Wallace543852a2017-08-03 02:11:34 -0400369 case STATE_DISCONNECT:
370 st = "STATE_DISCONNECT";
371 break;
372
373 case STATE_FAILED:
374 st = "STATE_FAILED";
375 break;
376
377 default:
378 st = "UNKNOWN_STATE";
379 break;
380 }
381
382 return st;
383}
384
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800385
Dave Wallace543852a2017-08-03 02:11:34 -0400386/*
387 * VPPCOM Utility Functions
388 */
Keith Burns (alagalah)410bcca2018-03-23 13:42:49 -0700389
390
391
Dave Wallace543852a2017-08-03 02:11:34 -0400392static inline int
393vppcom_session_at_index (u32 session_index, session_t * volatile *sess)
394{
Dave Wallace543852a2017-08-03 02:11:34 -0400395 /* Assumes that caller has acquired spinlock: vcm->sessions_lockp */
396 if (PREDICT_FALSE ((session_index == ~0) ||
397 pool_is_free_index (vcm->sessions, session_index)))
398 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500399 clib_warning ("VCL<%d>: invalid session, sid (%u) has been closed!",
Dave Wallace2e005bb2017-11-07 01:21:39 -0500400 getpid (), session_index);
Dave Wallace543852a2017-08-03 02:11:34 -0400401 return VPPCOM_EBADFD;
402 }
403 *sess = pool_elt_at_index (vcm->sessions, session_index);
404 return VPPCOM_OK;
405}
406
Keith Burns (alagalah)410bcca2018-03-23 13:42:49 -0700407void *
408vppcom_session_io_thread_fn (void *arg)
409{
410 vppcom_session_io_thread_t *evt = (vppcom_session_io_thread_t *) arg;
411 u32 *session_indexes = 0, *session_index;
412 int i, rv;
413 u32 bytes = 0;
414 session_t *session;
415
416 while (1)
417 {
418 vec_reset_length (session_indexes);
419 clib_spinlock_lock (&evt->io_sessions_lockp);
420 pool_foreach (session_index, evt->active_session_indexes, (
421 {
422 vec_add1
423 (session_indexes,
424 *session_index);
425 }
426 ));
427 clib_spinlock_unlock (&evt->io_sessions_lockp);
428 if (session_indexes)
429 {
430 for (i = 0; i < vec_len (session_indexes); ++i)
431 {
432 VCL_LOCK_AND_GET_SESSION (session_indexes[i], &session);
433 bytes = svm_fifo_max_dequeue (session->rx_fifo);
434 clib_spinlock_unlock (&vcm->sessions_lockp);
435
436 if (bytes)
437 {
438 vppcom_ioevent_t *eio;
439 vce_event_t *ev;
440 u32 ev_idx;
441
442 clib_spinlock_lock (&vcm->event_thread.events_lockp);
443
444 pool_get (vcm->event_thread.vce_events, ev);
445 ev_idx = (u32) (ev - vcm->event_thread.vce_events);
446 eio = vce_get_event_data (ev, sizeof (*eio));
447 ev->evk.eid = VCL_EVENT_IOEVENT_RX_FIFO;
448 ev->evk.session_index = session_indexes[i];
449 eio->bytes = bytes;
450 eio->session_index = session_indexes[i];
451
452 clib_spinlock_unlock (&vcm->event_thread.events_lockp);
453
454 rv = vce_generate_event (&vcm->event_thread, ev_idx);
455 }
456 }
457 }
458 struct timespec ts;
459 ts.tv_sec = 0;
460 ts.tv_nsec = 1000000; /* 1 millisecond */
461 nanosleep (&ts, NULL);
462 }
463done:
464 clib_spinlock_unlock (&vcm->sessions_lockp);
465 return NULL;
466}
467
468int
469vppcom_start_io_event_thread (vppcom_session_io_thread_t * evt,
470 u8 max_sessions)
471{
472 pthread_cond_init (&(evt->vce_io_cond), NULL);
473 pthread_mutex_init (&(evt->vce_io_lock), NULL);
474
475 clib_spinlock_init (&(evt->io_sessions_lockp));
476
477 return pthread_create (&(evt->thread), NULL /* attr */ ,
478 vppcom_session_io_thread_fn, evt);
479}
480
481
Florin Corasdcf55ce2017-11-16 15:32:50 -0800482static inline void
483vppcom_session_table_add_listener (u64 listener_handle, u32 value)
484{
485 /* Session and listener handles have different formats. The latter has
486 * the thread index in the upper 32 bits while the former has the session
487 * type. Knowing that, for listeners we just flip the MSB to 1 */
488 listener_handle |= 1ULL << 63;
489 hash_set (vcm->session_index_by_vpp_handles, listener_handle, value);
490}
491
492static inline session_t *
493vppcom_session_table_lookup_listener (u64 listener_handle)
494{
495 uword *p;
496 u64 handle = listener_handle | (1ULL << 63);
Dave Wallace4878cbe2017-11-21 03:45:09 -0500497 session_t *session;
498
Florin Corasdcf55ce2017-11-16 15:32:50 -0800499 p = hash_get (vcm->session_index_by_vpp_handles, handle);
500 if (!p)
501 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500502 clib_warning ("VCL<%d>: couldn't find listen session: unknown vpp "
Florin Corasdcf55ce2017-11-16 15:32:50 -0800503 "listener handle %llx", getpid (), listener_handle);
504 return 0;
505 }
506 if (pool_is_free_index (vcm->sessions, p[0]))
507 {
508 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -0500509 clib_warning ("VCL<%d>: invalid listen session, sid (%u)",
510 getpid (), p[0]);
Florin Corasdcf55ce2017-11-16 15:32:50 -0800511 return 0;
512 }
513
Dave Wallace4878cbe2017-11-21 03:45:09 -0500514 session = pool_elt_at_index (vcm->sessions, p[0]);
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -0800515 ASSERT (session->state & STATE_LISTEN);
Dave Wallace4878cbe2017-11-21 03:45:09 -0500516 return session;
Florin Corasdcf55ce2017-11-16 15:32:50 -0800517}
518
519static inline void
520vppcom_session_table_del_listener (u64 listener_handle)
521{
522 listener_handle |= 1ULL << 63;
523 hash_unset (vcm->session_index_by_vpp_handles, listener_handle);
524}
525
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -0800526static void
527write_elog (void)
528{
529 elog_main_t *em = &vcm->elog_main;
530 char *chroot_file;
531 clib_error_t *error = 0;
532
533 chroot_file =
534 (char *) format (0, "%s/%d-%d-vcl-elog%c", vcm->cfg.event_log_path,
535 vcm->my_client_index, getpid (), 0);
536 error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
537 if (error)
538 {
539 clib_error_report (error);
540 }
541 if (VPPCOM_DEBUG > 0)
542 clib_warning ("[%d] Event Log:'%s' ", getpid (), chroot_file);
543
544}
545
Keith Burns (alagalah)0d2b0d52018-03-06 15:55:22 -0800546static inline void
547vppcom_send_accept_session_reply (u64 handle, u32 context, int retval)
548{
549 vl_api_accept_session_reply_t *rmp;
550
551 rmp = vl_msg_api_alloc (sizeof (*rmp));
552 memset (rmp, 0, sizeof (*rmp));
553 rmp->_vl_msg_id = ntohs (VL_API_ACCEPT_SESSION_REPLY);
554 rmp->retval = htonl (retval);
555 rmp->context = context;
556 rmp->handle = handle;
557 vl_msg_api_send_shmem (vcm->vl_input_queue, (u8 *) & rmp);
558}
559
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800560/*
561 * VPPCOM Event Functions
562 */
563
Keith Burns (alagalah)0d2b0d52018-03-06 15:55:22 -0800564void
Keith Burns (alagalah)410bcca2018-03-23 13:42:49 -0700565vce_registered_ioevent_handler_fn (void *arg)
566{
567 vce_event_handler_reg_t *reg = (vce_event_handler_reg_t *) arg;
568 vppcom_ioevent_t *eio;
569 vce_event_t *ev;
570 u32 ioevt_ndx = (u64) (reg->handler_fn_args);
571 vppcom_session_ioevent_t *ioevent, ioevent_;
572
573 clib_spinlock_lock (&(vcm->event_thread.events_lockp));
574 ev = vce_get_event_from_index (&vcm->event_thread, reg->ev_idx);
575 eio = vce_get_event_data (ev, sizeof (*eio));
576 clib_spinlock_unlock (&(vcm->event_thread.events_lockp));
577
578 clib_spinlock_lock (&vcm->session_io_thread.io_sessions_lockp);
579 ioevent = pool_elt_at_index (vcm->session_io_thread.ioevents, ioevt_ndx);
580 ioevent_ = *ioevent;
581 clib_spinlock_unlock (&vcm->session_io_thread.io_sessions_lockp);
582 (ioevent_.user_cb) (eio, ioevent_.user_cb_data);
583 vce_clear_event (&vcm->event_thread, reg->ev_idx);
584 return;
585
586 /*TODO - Unregister check in close for this listener */
587
588}
589
590void
Keith Burns (alagalah)0d2b0d52018-03-06 15:55:22 -0800591vce_registered_listener_connect_handler_fn (void *arg)
592{
593 vce_event_handler_reg_t *reg = (vce_event_handler_reg_t *) arg;
594 vce_event_connect_request_t *ecr;
595 vce_event_t *ev;
596 vppcom_endpt_t ep;
597
598 session_t *new_session;
599 int rv;
600
601 vppcom_session_listener_t *session_listener =
602 (vppcom_session_listener_t *) reg->handler_fn_args;
603
Keith Burns (alagalah)410bcca2018-03-23 13:42:49 -0700604 clib_spinlock_lock (&(vcm->event_thread.events_lockp));
Keith Burns (alagalah)0d2b0d52018-03-06 15:55:22 -0800605 ev = vce_get_event_from_index (&vcm->event_thread, reg->ev_idx);
Keith Burns (alagalah)410bcca2018-03-23 13:42:49 -0700606 ecr = vce_get_event_data (ev, sizeof (*ecr));
607 clib_spinlock_unlock (&(vcm->event_thread.events_lockp));
Keith Burns (alagalah)0d2b0d52018-03-06 15:55:22 -0800608 VCL_LOCK_AND_GET_SESSION (ecr->accepted_session_index, &new_session);
609
Keith Burns (alagalah)0d2b0d52018-03-06 15:55:22 -0800610 ep.is_ip4 = new_session->peer_addr.is_ip4;
611 ep.port = new_session->peer_port;
612 if (new_session->peer_addr.is_ip4)
613 clib_memcpy (&ep.ip, &new_session->peer_addr.ip46.ip4,
614 sizeof (ip4_address_t));
615 else
616 clib_memcpy (&ep.ip, &new_session->peer_addr.ip46.ip6,
617 sizeof (ip6_address_t));
618
619 vppcom_send_accept_session_reply (new_session->vpp_handle,
620 new_session->client_context,
621 0 /* retval OK */ );
622 clib_spinlock_unlock (&vcm->sessions_lockp);
623
624 (session_listener->user_cb) (ecr->accepted_session_index, &ep,
625 session_listener->user_cb_data);
626
Keith Burns (alagalah)410bcca2018-03-23 13:42:49 -0700627 if (vcm->session_io_thread.io_sessions_lockp)
628 {
629 /* Throw this new accepted session index into the rx poll thread pool */
630 clib_spinlock_lock (&vcm->session_io_thread.io_sessions_lockp);
631 u32 *active_session_index;
632 pool_get (vcm->session_io_thread.active_session_indexes,
633 active_session_index);
634 *active_session_index = ecr->accepted_session_index;
635 clib_spinlock_unlock (&vcm->session_io_thread.io_sessions_lockp);
636 }
Keith Burns (alagalah)0d2b0d52018-03-06 15:55:22 -0800637
Keith Burns (alagalah)410bcca2018-03-23 13:42:49 -0700638 /*TODO - Unregister check in close for this listener */
Keith Burns (alagalah)0d2b0d52018-03-06 15:55:22 -0800639 return;
640
641done:
642 ASSERT (0); // If we can't get a lock or accepted session fails, lets blow up.
643}
644
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800645/**
646 * * @brief vce_connect_request_handler_fn
647 * - used for listener sessions
648 * - when a vl_api_accept_session_t_handler() generates an event
649 * this callback is alerted and sets fields that consumers such as
650 * vppcom_session_accept() expect to see, ie. accepted_client_index
651 *
652 * @param arg - void* to be cast to vce_event_handler_reg_t*
653 */
654void
655vce_connect_request_handler_fn (void *arg)
656{
657 vce_event_handler_reg_t *reg = (vce_event_handler_reg_t *) arg;
658
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800659 pthread_mutex_lock (&reg->handler_lock);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800660 pthread_cond_signal (&reg->handler_cond);
661 pthread_mutex_unlock (&reg->handler_lock);
662}
663
664/**
Dave Wallace8d73e852018-03-08 16:39:28 -0500665 * @brief vce_poll_wait_connect_request_handler_fn
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800666 * - used by vppcom_epoll_xxxx() for listener sessions
667 * - when a vl_api_accept_session_t_handler() generates an event
668 * this callback is alerted and sets the fields that vppcom_epoll_wait()
669 * expects to see.
670 *
671 * @param arg - void* to be cast to vce_event_handler_reg_t*
672 */
673void
Dave Wallace8d73e852018-03-08 16:39:28 -0500674vce_poll_wait_connect_request_handler_fn (void *arg)
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800675{
676 vce_event_handler_reg_t *reg = (vce_event_handler_reg_t *) arg;
677 vce_event_t *ev;
678 /* Retrieve the VCL_EVENT_CONNECT_REQ_ACCEPTED event */
679 ev = vce_get_event_from_index (&vcm->event_thread, reg->ev_idx);
Keith Burns (alagalah)410bcca2018-03-23 13:42:49 -0700680 vce_event_connect_request_t *ecr = vce_get_event_data (ev, sizeof (*ecr));
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800681
682 /* Add the accepted_session_index to the FIFO */
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -0800683 clib_spinlock_lock (&vcm->session_fifo_lockp);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800684 clib_fifo_add1 (vcm->client_session_index_fifo,
685 ecr->accepted_session_index);
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -0800686 clib_spinlock_unlock (&vcm->session_fifo_lockp);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800687
688 /* Recycling the event. */
689 clib_spinlock_lock (&(vcm->event_thread.events_lockp));
Keith Burns (alagalah)410bcca2018-03-23 13:42:49 -0700690 ev->recycle = 1;
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800691 clib_fifo_add1 (vcm->event_thread.event_index_fifo, reg->ev_idx);
692 clib_spinlock_unlock (&(vcm->event_thread.events_lockp));
693}
694
Dave Wallace543852a2017-08-03 02:11:34 -0400695static int
696vppcom_connect_to_vpp (char *app_name)
697{
698 api_main_t *am = &api_main;
Dave Wallaceb5a86ee2018-02-16 18:26:11 -0500699 vppcom_cfg_t *vcl_cfg = &vcm->cfg;
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -0800700 int rv = VPPCOM_OK;
Dave Wallace543852a2017-08-03 02:11:34 -0400701
Dave Wallaceb5a86ee2018-02-16 18:26:11 -0500702 if (!vcl_cfg->vpp_api_filename)
703 vcl_cfg->vpp_api_filename = format (0, "/vpe-api%c", 0);
Dave Wallace048b1d62018-01-03 22:24:41 -0500704
Dave Wallaceb5a86ee2018-02-16 18:26:11 -0500705 if (VPPCOM_DEBUG > 0)
706 clib_warning ("VCL<%d>: app (%s) connecting to VPP api (%s)...",
707 getpid (), app_name, vcl_cfg->vpp_api_filename);
708
709 if (vl_client_connect_to_vlib ((char *) vcl_cfg->vpp_api_filename, app_name,
Dave Wallacec8f1ee62017-11-29 22:46:32 -0500710 vcm->cfg.vpp_api_q_length) < 0)
Dave Wallace543852a2017-08-03 02:11:34 -0400711 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500712 clib_warning ("VCL<%d>: app (%s) connect failed!", getpid (), app_name);
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -0800713 rv = VPPCOM_ECONNREFUSED;
714 }
715 else
716 {
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -0800717 vcm->vl_input_queue = am->shmem_hdr->vl_input_queue;
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800718 vcm->my_client_index = (u32) am->my_client_index;
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -0800719 vcm->app_state = STATE_APP_CONN_VPP;
Dave Wallace9b954252018-01-18 17:01:40 -0500720
721 if (VPPCOM_DEBUG > 0)
722 clib_warning ("VCL<%d>: app (%s) is connected to VPP!",
723 getpid (), app_name);
Dave Wallace543852a2017-08-03 02:11:34 -0400724 }
725
Dave Wallace543852a2017-08-03 02:11:34 -0400726 if (VPPCOM_DEBUG > 0)
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -0800727 {
728 vcm->elog_main.lock =
729 clib_mem_alloc_aligned (CLIB_CACHE_LINE_BYTES, CLIB_CACHE_LINE_BYTES);
730 vcm->elog_main.lock[0] = 0;
731 vcm->elog_main.event_ring_size = vcm->cfg.event_ring_size;
732 elog_init (&vcm->elog_main, vcm->elog_main.event_ring_size);
733 elog_enable_disable (&vcm->elog_main, 1);
Dave Wallace543852a2017-08-03 02:11:34 -0400734
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -0800735 vcm->elog_track.name =
736 (char *) format (0, "P:%d:C:%d%c", getpid (),
737 vcm->my_client_index, 0);
738 elog_track_register (&vcm->elog_main, &vcm->elog_track);
739
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -0800740 /* *INDENT-OFF* */
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -0800741 ELOG_TYPE_DECLARE (e) =
742 {
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -0800743 .format = "connect_vpp:rv:%d",
744 .format_args = "i4",
745 };
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -0800746 struct
747 {
748 u32 data;
749 } *ed;
750 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, vcm->elog_track);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800751 ed->data = (u32) rv;
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -0800752 /* *INDENT-ON* */
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -0800753 }
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -0800754 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -0400755}
756
757static u8 *
758format_api_error (u8 * s, va_list * args)
759{
Dave Wallace543852a2017-08-03 02:11:34 -0400760 i32 error = va_arg (*args, u32);
761 uword *p;
762
763 p = hash_get (vcm->error_string_by_error_number, -error);
764
765 if (p)
766 s = format (s, "%s (%d)", p[0], error);
767 else
768 s = format (s, "%d", error);
769 return s;
770}
771
772static void
773vppcom_init_error_string_table (void)
774{
Dave Wallace543852a2017-08-03 02:11:34 -0400775 vcm->error_string_by_error_number = hash_create (0, sizeof (uword));
776
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -0800777#define _(n, v, s) hash_set (vcm->error_string_by_error_number, -v, s);
Dave Wallace543852a2017-08-03 02:11:34 -0400778 foreach_vnet_api_error;
779#undef _
780
781 hash_set (vcm->error_string_by_error_number, 99, "Misc");
782}
783
784static inline int
785vppcom_wait_for_app_state_change (app_state_t app_state)
786{
Dave Wallace543852a2017-08-03 02:11:34 -0400787 f64 timeout = clib_time_now (&vcm->clib_time) + vcm->cfg.app_timeout;
788
789 while (clib_time_now (&vcm->clib_time) < timeout)
790 {
791 if (vcm->app_state == app_state)
792 return VPPCOM_OK;
793 }
794 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -0500795 clib_warning ("VCL<%d>: timeout waiting for state %s (%d)", getpid (),
Dave Wallace543852a2017-08-03 02:11:34 -0400796 vppcom_app_state_str (app_state), app_state);
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -0800797
798 if (VPPCOM_DEBUG > 0)
799 {
800 /* *INDENT-OFF* */
801 ELOG_TYPE_DECLARE (e) =
802 {
803 .format = "ERR: timeout state:%d",
804 .format_args = "i4",
805 };
806 struct
807 {
808 u32 data;
809 } *ed;
810
811 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, vcm->elog_track);
812
813 ed->data = app_state;
814 /* *INDENT-ON* */
815 }
816
Dave Wallace543852a2017-08-03 02:11:34 -0400817 return VPPCOM_ETIMEDOUT;
818}
819
820static inline int
821vppcom_wait_for_session_state_change (u32 session_index,
822 session_state_t state,
823 f64 wait_for_time)
824{
Dave Wallace543852a2017-08-03 02:11:34 -0400825 f64 timeout = clib_time_now (&vcm->clib_time) + wait_for_time;
826 session_t *volatile session;
827 int rv;
828
829 do
830 {
831 clib_spinlock_lock (&vcm->sessions_lockp);
832 rv = vppcom_session_at_index (session_index, &session);
833 if (PREDICT_FALSE (rv))
834 {
835 clib_spinlock_unlock (&vcm->sessions_lockp);
836 return rv;
837 }
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -0800838 if (session->state & state)
Dave Wallace543852a2017-08-03 02:11:34 -0400839 {
840 clib_spinlock_unlock (&vcm->sessions_lockp);
841 return VPPCOM_OK;
842 }
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -0800843 if (session->state & STATE_FAILED)
Dave Wallace4878cbe2017-11-21 03:45:09 -0500844 {
845 clib_spinlock_unlock (&vcm->sessions_lockp);
846 return VPPCOM_ECONNREFUSED;
847 }
848
Dave Wallace543852a2017-08-03 02:11:34 -0400849 clib_spinlock_unlock (&vcm->sessions_lockp);
850 }
851 while (clib_time_now (&vcm->clib_time) < timeout);
852
853 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -0500854 clib_warning ("VCL<%d>: timeout waiting for state 0x%x (%s)", getpid (),
Dave Wallace4878cbe2017-11-21 03:45:09 -0500855 state, vppcom_session_state_str (state));
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -0800856
857 if (VPPCOM_DEBUG > 0)
858 {
859 /* *INDENT-OFF* */
860 ELOG_TYPE_DECLARE (e) =
861 {
862 .format = "ERR: timeout state:%d",
863 .format_args = "i4",
864 };
865 struct
866 {
867 u32 data;
868 } *ed;
869
870 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
871
872 ed->data = state;
873 /* *INDENT-ON* */
874 }
875
Dave Wallace543852a2017-08-03 02:11:34 -0400876 return VPPCOM_ETIMEDOUT;
877}
878
Dave Wallace543852a2017-08-03 02:11:34 -0400879/*
880 * VPP-API message functions
881 */
882static void
883vppcom_send_session_enable_disable (u8 is_enable)
884{
Dave Wallace543852a2017-08-03 02:11:34 -0400885 vl_api_session_enable_disable_t *bmp;
886 bmp = vl_msg_api_alloc (sizeof (*bmp));
887 memset (bmp, 0, sizeof (*bmp));
888
889 bmp->_vl_msg_id = ntohs (VL_API_SESSION_ENABLE_DISABLE);
890 bmp->client_index = vcm->my_client_index;
891 bmp->context = htonl (0xfeedface);
892 bmp->is_enable = is_enable;
893 vl_msg_api_send_shmem (vcm->vl_input_queue, (u8 *) & bmp);
894}
895
896static int
897vppcom_app_session_enable (void)
898{
Dave Wallace543852a2017-08-03 02:11:34 -0400899 int rv;
900
901 if (vcm->app_state != STATE_APP_ENABLED)
902 {
903 vppcom_send_session_enable_disable (1 /* is_enabled == TRUE */ );
904 rv = vppcom_wait_for_app_state_change (STATE_APP_ENABLED);
905 if (PREDICT_FALSE (rv))
906 {
907 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -0500908 clib_warning ("VCL<%d>: application session enable timed out! "
Dave Wallaceee45d412017-11-24 21:44:06 -0500909 "returning %d (%s)",
910 getpid (), rv, vppcom_retval_str (rv));
Dave Wallace543852a2017-08-03 02:11:34 -0400911 return rv;
912 }
913 }
914 return VPPCOM_OK;
915}
916
917static void
918 vl_api_session_enable_disable_reply_t_handler
919 (vl_api_session_enable_disable_reply_t * mp)
920{
Dave Wallace543852a2017-08-03 02:11:34 -0400921 if (mp->retval)
922 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500923 clib_warning ("VCL<%d>: session_enable_disable failed: %U", getpid (),
Dave Wallace543852a2017-08-03 02:11:34 -0400924 format_api_error, ntohl (mp->retval));
925 }
926 else
927 vcm->app_state = STATE_APP_ENABLED;
928}
929
930static void
931vppcom_app_send_attach (void)
932{
Dave Wallace543852a2017-08-03 02:11:34 -0400933 vl_api_application_attach_t *bmp;
Dave Wallace8af20542017-10-26 03:29:30 -0400934 u8 nsid_len = vec_len (vcm->cfg.namespace_id);
Dave Wallace774169b2017-11-01 20:07:40 -0400935 u8 app_is_proxy = (vcm->cfg.app_proxy_transport_tcp ||
936 vcm->cfg.app_proxy_transport_udp);
Dave Wallace8af20542017-10-26 03:29:30 -0400937
Dave Wallace543852a2017-08-03 02:11:34 -0400938 bmp = vl_msg_api_alloc (sizeof (*bmp));
939 memset (bmp, 0, sizeof (*bmp));
940
941 bmp->_vl_msg_id = ntohs (VL_API_APPLICATION_ATTACH);
942 bmp->client_index = vcm->my_client_index;
943 bmp->context = htonl (0xfeedface);
944 bmp->options[APP_OPTIONS_FLAGS] =
Florin Corascea194d2017-10-02 00:18:51 -0700945 APP_OPTIONS_FLAGS_ACCEPT_REDIRECT | APP_OPTIONS_FLAGS_ADD_SEGMENT |
Dave Wallace774169b2017-11-01 20:07:40 -0400946 (vcm->cfg.app_scope_local ? APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE : 0) |
947 (vcm->cfg.app_scope_global ? APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE : 0) |
948 (app_is_proxy ? APP_OPTIONS_FLAGS_IS_PROXY : 0);
949 bmp->options[APP_OPTIONS_PROXY_TRANSPORT] =
Keith Burns (alagalah)410bcca2018-03-23 13:42:49 -0700950 (u64) ((vcm->cfg.app_proxy_transport_tcp ? 1 << TRANSPORT_PROTO_TCP : 0) |
951 (vcm->cfg.app_proxy_transport_udp ? 1 << TRANSPORT_PROTO_UDP : 0));
Florin Corasff6e7692017-12-11 04:59:01 -0800952 bmp->options[APP_OPTIONS_SEGMENT_SIZE] = vcm->cfg.segment_size;
953 bmp->options[APP_OPTIONS_ADD_SEGMENT_SIZE] = vcm->cfg.add_segment_size;
954 bmp->options[APP_OPTIONS_RX_FIFO_SIZE] = vcm->cfg.rx_fifo_size;
955 bmp->options[APP_OPTIONS_TX_FIFO_SIZE] = vcm->cfg.tx_fifo_size;
Florin Corasf32cff62017-12-09 08:15:00 -0800956 bmp->options[APP_OPTIONS_PREALLOC_FIFO_PAIRS] =
957 vcm->cfg.preallocated_fifo_pairs;
Florin Corasff6e7692017-12-11 04:59:01 -0800958 bmp->options[APP_OPTIONS_EVT_QUEUE_SIZE] = vcm->cfg.event_queue_size;
Dave Wallace8af20542017-10-26 03:29:30 -0400959 if (nsid_len)
960 {
961 bmp->namespace_id_len = nsid_len;
962 clib_memcpy (bmp->namespace_id, vcm->cfg.namespace_id, nsid_len);
963 bmp->options[APP_OPTIONS_NAMESPACE_SECRET] = vcm->cfg.namespace_secret;
964 }
Dave Wallace543852a2017-08-03 02:11:34 -0400965 vl_msg_api_send_shmem (vcm->vl_input_queue, (u8 *) & bmp);
966}
967
968static int
969vppcom_app_attach (void)
970{
Dave Wallace543852a2017-08-03 02:11:34 -0400971 int rv;
972
973 vppcom_app_send_attach ();
974 rv = vppcom_wait_for_app_state_change (STATE_APP_ATTACHED);
975 if (PREDICT_FALSE (rv))
976 {
977 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -0500978 clib_warning ("VCL<%d>: application attach timed out! "
979 "returning %d (%s)",
Dave Wallaceee45d412017-11-24 21:44:06 -0500980 getpid (), rv, vppcom_retval_str (rv));
Dave Wallace543852a2017-08-03 02:11:34 -0400981 return rv;
982 }
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800983
Dave Wallace543852a2017-08-03 02:11:34 -0400984 return VPPCOM_OK;
985}
986
987static void
988vppcom_app_detach (void)
989{
Dave Wallace543852a2017-08-03 02:11:34 -0400990 vl_api_application_detach_t *bmp;
991 bmp = vl_msg_api_alloc (sizeof (*bmp));
992 memset (bmp, 0, sizeof (*bmp));
993
994 bmp->_vl_msg_id = ntohs (VL_API_APPLICATION_DETACH);
995 bmp->client_index = vcm->my_client_index;
996 bmp->context = htonl (0xfeedface);
997 vl_msg_api_send_shmem (vcm->vl_input_queue, (u8 *) & bmp);
998}
999
1000static void
1001vl_api_application_attach_reply_t_handler (vl_api_application_attach_reply_t *
1002 mp)
1003{
Dave Wallace543852a2017-08-03 02:11:34 -04001004 static svm_fifo_segment_create_args_t _a;
1005 svm_fifo_segment_create_args_t *a = &_a;
1006 int rv;
1007
1008 memset (a, 0, sizeof (*a));
1009 if (mp->retval)
1010 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001011 clib_warning ("VCL<%d>: attach failed: %U", getpid (),
Dave Wallace543852a2017-08-03 02:11:34 -04001012 format_api_error, ntohl (mp->retval));
1013 return;
1014 }
1015
1016 if (mp->segment_name_length == 0)
1017 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001018 clib_warning ("VCL<%d>: segment_name_length zero", getpid ());
Dave Wallace543852a2017-08-03 02:11:34 -04001019 return;
1020 }
1021
1022 a->segment_name = (char *) mp->segment_name;
1023 a->segment_size = mp->segment_size;
1024
1025 ASSERT (mp->app_event_queue_address);
1026
1027 /* Attach to the segment vpp created */
1028 rv = svm_fifo_segment_attach (a);
1029 vec_reset_length (a->new_segment_indices);
1030 if (PREDICT_FALSE (rv))
1031 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001032 clib_warning ("VCL<%d>: svm_fifo_segment_attach ('%s') failed",
1033 getpid (), mp->segment_name);
Dave Wallace543852a2017-08-03 02:11:34 -04001034 return;
1035 }
1036
1037 vcm->app_event_queue =
Florin Corase86a8ed2018-01-05 03:20:25 -08001038 uword_to_pointer (mp->app_event_queue_address, svm_queue_t *);
Dave Wallace543852a2017-08-03 02:11:34 -04001039
1040 vcm->app_state = STATE_APP_ATTACHED;
1041}
1042
1043static void
1044vl_api_application_detach_reply_t_handler (vl_api_application_detach_reply_t *
1045 mp)
1046{
Dave Wallace543852a2017-08-03 02:11:34 -04001047 if (mp->retval)
Dave Wallace048b1d62018-01-03 22:24:41 -05001048 clib_warning ("VCL<%d>: detach failed: %U", getpid (), format_api_error,
Dave Wallace543852a2017-08-03 02:11:34 -04001049 ntohl (mp->retval));
1050
1051 vcm->app_state = STATE_APP_ENABLED;
1052}
1053
1054static void
1055vl_api_disconnect_session_reply_t_handler (vl_api_disconnect_session_reply_t *
1056 mp)
1057{
Dave Wallace543852a2017-08-03 02:11:34 -04001058 if (mp->retval)
Dave Wallace048b1d62018-01-03 22:24:41 -05001059 clib_warning ("VCL<%d>: vpp handle 0x%llx: disconnect session failed: %U",
Dave Wallace4878cbe2017-11-21 03:45:09 -05001060 getpid (), mp->handle, format_api_error,
1061 ntohl (mp->retval));
Dave Wallace543852a2017-08-03 02:11:34 -04001062}
1063
1064static void
1065vl_api_map_another_segment_t_handler (vl_api_map_another_segment_t * mp)
1066{
Dave Wallace543852a2017-08-03 02:11:34 -04001067 static svm_fifo_segment_create_args_t _a;
1068 svm_fifo_segment_create_args_t *a = &_a;
1069 int rv;
1070
1071 memset (a, 0, sizeof (*a));
1072 a->segment_name = (char *) mp->segment_name;
1073 a->segment_size = mp->segment_size;
1074 /* Attach to the segment vpp created */
1075 rv = svm_fifo_segment_attach (a);
1076 vec_reset_length (a->new_segment_indices);
1077 if (PREDICT_FALSE (rv))
1078 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001079 clib_warning ("VCL<%d>: svm_fifo_segment_attach ('%s') failed",
Dave Wallace2e005bb2017-11-07 01:21:39 -05001080 getpid (), mp->segment_name);
Dave Wallace543852a2017-08-03 02:11:34 -04001081 return;
1082 }
1083 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05001084 clib_warning ("VCL<%d>: mapped new segment '%s' size %d", getpid (),
Dave Wallace543852a2017-08-03 02:11:34 -04001085 mp->segment_name, mp->segment_size);
1086}
1087
1088static void
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001089vl_api_unmap_segment_t_handler (vl_api_unmap_segment_t * mp)
1090{
1091
1092/*
1093 * XXX Need segment_name to session_id hash,
1094 * XXX - have sessionID by handle hash currently
1095 */
Dave Wallace69d01192018-02-22 16:22:09 -05001096 if (VPPCOM_DEBUG > 1)
1097 clib_warning ("Unmapped segment '%s'", mp->segment_name);
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001098}
1099
1100static void
Dave Wallace543852a2017-08-03 02:11:34 -04001101vl_api_disconnect_session_t_handler (vl_api_disconnect_session_t * mp)
1102{
Dave Wallace543852a2017-08-03 02:11:34 -04001103 uword *p;
Dave Wallace543852a2017-08-03 02:11:34 -04001104
1105 p = hash_get (vcm->session_index_by_vpp_handles, mp->handle);
1106 if (p)
1107 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05001108 int rv;
1109 session_t *session = 0;
1110 u32 session_index = p[0];
1111
1112 VCL_LOCK_AND_GET_SESSION (session_index, &session);
1113 session->state = STATE_CLOSE_ON_EMPTY;
1114
1115 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05001116 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -05001117 "setting state to 0x%x (%s)",
Dave Wallace4878cbe2017-11-21 03:45:09 -05001118 getpid (), mp->handle, session_index, session->state,
1119 vppcom_session_state_str (session->state));
Dave Wallace543852a2017-08-03 02:11:34 -04001120 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001121 return;
1122
1123 done:
1124 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05001125 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
Dave Wallace4878cbe2017-11-21 03:45:09 -05001126 "session lookup failed!",
1127 getpid (), mp->handle, session_index);
Dave Wallace543852a2017-08-03 02:11:34 -04001128 }
1129 else
Dave Wallace048b1d62018-01-03 22:24:41 -05001130 clib_warning ("VCL<%d>: vpp handle 0x%llx: session lookup by "
Dave Wallace4878cbe2017-11-21 03:45:09 -05001131 "handle failed!", getpid (), mp->handle);
Dave Wallace543852a2017-08-03 02:11:34 -04001132}
1133
1134static void
1135vl_api_reset_session_t_handler (vl_api_reset_session_t * mp)
1136{
Dave Wallace543852a2017-08-03 02:11:34 -04001137 session_t *session = 0;
1138 vl_api_reset_session_reply_t *rmp;
1139 uword *p;
1140 int rv = 0;
1141
1142 p = hash_get (vcm->session_index_by_vpp_handles, mp->handle);
1143 if (p)
1144 {
1145 int rval;
1146 clib_spinlock_lock (&vcm->sessions_lockp);
1147 rval = vppcom_session_at_index (p[0], &session);
1148 if (PREDICT_FALSE (rval))
1149 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05001150 rv = VNET_API_ERROR_INVALID_VALUE_2;
Dave Wallace048b1d62018-01-03 22:24:41 -05001151 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -05001152 "session lookup failed! returning %d %U",
1153 getpid (), mp->handle, p[0],
1154 rv, format_api_error, rv);
Dave Wallace543852a2017-08-03 02:11:34 -04001155 }
1156 else
Dave Wallace4878cbe2017-11-21 03:45:09 -05001157 {
1158 /* TBD: should this disconnect immediately and
1159 * flush the fifos?
1160 */
1161 session->state = STATE_CLOSE_ON_EMPTY;
1162
1163 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05001164 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
Dave Wallace4878cbe2017-11-21 03:45:09 -05001165 "state set to %d (%s)!", getpid (),
1166 mp->handle, p[0], session->state,
1167 vppcom_session_state_str (session->state));
1168 }
Dave Wallace543852a2017-08-03 02:11:34 -04001169 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace543852a2017-08-03 02:11:34 -04001170 }
1171 else
1172 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05001173 rv = VNET_API_ERROR_INVALID_VALUE;
Dave Wallace048b1d62018-01-03 22:24:41 -05001174 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx: session lookup "
Dave Wallace4878cbe2017-11-21 03:45:09 -05001175 "failed! returning %d %U",
1176 getpid (), mp->handle, rv, format_api_error, rv);
Dave Wallace543852a2017-08-03 02:11:34 -04001177 }
1178
1179 rmp = vl_msg_api_alloc (sizeof (*rmp));
1180 memset (rmp, 0, sizeof (*rmp));
1181 rmp->_vl_msg_id = ntohs (VL_API_RESET_SESSION_REPLY);
1182 rmp->retval = htonl (rv);
1183 rmp->handle = mp->handle;
1184 vl_msg_api_send_shmem (vcm->vl_input_queue, (u8 *) & rmp);
1185}
1186
1187static void
Dave Wallace33e002b2017-09-06 01:20:02 -04001188vl_api_connect_session_reply_t_handler (vl_api_connect_session_reply_t * mp)
Dave Wallace543852a2017-08-03 02:11:34 -04001189{
Dave Wallaceee45d412017-11-24 21:44:06 -05001190 session_t *session = 0;
Dave Wallace543852a2017-08-03 02:11:34 -04001191 u32 session_index;
1192 svm_fifo_t *rx_fifo, *tx_fifo;
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08001193 int rv = VPPCOM_OK;
Dave Wallace543852a2017-08-03 02:11:34 -04001194
Dave Wallace4878cbe2017-11-21 03:45:09 -05001195 session_index = mp->context;
Dave Wallaceee45d412017-11-24 21:44:06 -05001196 VCL_LOCK_AND_GET_SESSION (session_index, &session);
1197done:
Dave Wallace543852a2017-08-03 02:11:34 -04001198 if (mp->retval)
1199 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001200 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -05001201 "connect failed! %U",
1202 getpid (), mp->handle, session_index,
1203 format_api_error, ntohl (mp->retval));
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08001204 if (session)
Dave Wallaceee45d412017-11-24 21:44:06 -05001205 {
1206 session->state = STATE_FAILED;
1207 session->vpp_handle = mp->handle;
1208 }
1209 else
1210 {
1211 clib_warning ("[%s] ERROR: vpp handle 0x%llx, sid %u: "
1212 "Invalid session index (%u)!",
1213 getpid (), mp->handle, session_index);
1214 }
1215 goto done_unlock;
Dave Wallace543852a2017-08-03 02:11:34 -04001216 }
1217
Dave Wallaceee45d412017-11-24 21:44:06 -05001218 if (rv)
1219 goto done_unlock;
Dave Wallace543852a2017-08-03 02:11:34 -04001220
Dave Wallace543852a2017-08-03 02:11:34 -04001221 /*
1222 * Setup session
1223 */
Keith Burns (alagalah)410bcca2018-03-23 13:42:49 -07001224 if (vcm->session_io_thread.io_sessions_lockp)
1225 {
1226 // Add this connection to the active io sessions list
1227 clib_spinlock_lock (&vcm->session_io_thread.io_sessions_lockp);
1228 u32 *active_session_index;
1229 pool_get (vcm->session_io_thread.active_session_indexes,
1230 active_session_index);
1231 *active_session_index = session_index;
1232 clib_spinlock_unlock (&vcm->session_io_thread.io_sessions_lockp);
1233 }
Dave Wallace33e002b2017-09-06 01:20:02 -04001234 session->vpp_event_queue = uword_to_pointer (mp->vpp_event_queue_address,
Florin Corase86a8ed2018-01-05 03:20:25 -08001235 svm_queue_t *);
Dave Wallace543852a2017-08-03 02:11:34 -04001236
1237 rx_fifo = uword_to_pointer (mp->server_rx_fifo, svm_fifo_t *);
1238 rx_fifo->client_session_index = session_index;
1239 tx_fifo = uword_to_pointer (mp->server_tx_fifo, svm_fifo_t *);
1240 tx_fifo->client_session_index = session_index;
1241
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001242 session->rx_fifo = rx_fifo;
1243 session->tx_fifo = tx_fifo;
Dave Wallace60caa062017-11-10 17:07:13 -05001244 session->vpp_handle = mp->handle;
Dave Wallace9d1d73a2017-11-20 02:31:48 -05001245 session->lcl_addr.is_ip4 = mp->is_ip4;
1246 clib_memcpy (&session->lcl_addr.ip46, mp->lcl_ip,
1247 sizeof (session->peer_addr.ip46));
1248 session->lcl_port = mp->lcl_port;
Dave Wallace543852a2017-08-03 02:11:34 -04001249 session->state = STATE_CONNECT;
1250
1251 /* Add it to lookup table */
1252 hash_set (vcm->session_index_by_vpp_handles, mp->handle, session_index);
Dave Wallace60caa062017-11-10 17:07:13 -05001253
1254 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05001255 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: connect succeeded!"
Dave Wallaceee45d412017-11-24 21:44:06 -05001256 " session_rx_fifo %p, refcnt %d,"
1257 " session_tx_fifo %p, refcnt %d",
1258 getpid (), mp->handle, session_index,
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001259 session->rx_fifo,
1260 session->rx_fifo->refcnt,
1261 session->tx_fifo, session->tx_fifo->refcnt);
Dave Wallaceee45d412017-11-24 21:44:06 -05001262done_unlock:
Dave Wallace543852a2017-08-03 02:11:34 -04001263 clib_spinlock_unlock (&vcm->sessions_lockp);
1264}
1265
1266static void
1267vppcom_send_connect_sock (session_t * session, u32 session_index)
1268{
Dave Wallace543852a2017-08-03 02:11:34 -04001269 vl_api_connect_sock_t *cmp;
1270
1271 /* Assumes caller as acquired the spinlock: vcm->sessions_lockp */
Dave Wallace543852a2017-08-03 02:11:34 -04001272 cmp = vl_msg_api_alloc (sizeof (*cmp));
1273 memset (cmp, 0, sizeof (*cmp));
1274 cmp->_vl_msg_id = ntohs (VL_API_CONNECT_SOCK);
1275 cmp->client_index = vcm->my_client_index;
Dave Wallace33e002b2017-09-06 01:20:02 -04001276 cmp->context = session_index;
Dave Wallace543852a2017-08-03 02:11:34 -04001277
Dave Wallace35830af2017-10-09 01:43:42 -04001278 cmp->is_ip4 = session->peer_addr.is_ip4;
1279 clib_memcpy (cmp->ip, &session->peer_addr.ip46, sizeof (cmp->ip));
Stevenac1f96d2017-10-24 16:03:58 -07001280 cmp->port = session->peer_port;
Dave Wallace543852a2017-08-03 02:11:34 -04001281 cmp->proto = session->proto;
1282 clib_memcpy (cmp->options, session->options, sizeof (cmp->options));
1283 vl_msg_api_send_shmem (vcm->vl_input_queue, (u8 *) & cmp);
1284}
1285
Dave Wallace66cf6eb2017-10-26 02:51:07 -04001286static inline void
Dave Wallace4878cbe2017-11-21 03:45:09 -05001287vppcom_send_disconnect_session_reply (u64 vpp_handle, u32 session_index,
1288 int rv)
1289{
1290 vl_api_disconnect_session_reply_t *rmp;
1291
1292 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05001293 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
1294 "sending disconnect msg",
Dave Wallace4878cbe2017-11-21 03:45:09 -05001295 getpid (), vpp_handle, session_index);
1296
1297 rmp = vl_msg_api_alloc (sizeof (*rmp));
1298 memset (rmp, 0, sizeof (*rmp));
1299
1300 rmp->_vl_msg_id = ntohs (VL_API_DISCONNECT_SESSION_REPLY);
1301 rmp->retval = htonl (rv);
1302 rmp->handle = vpp_handle;
1303 vl_msg_api_send_shmem (vcm->vl_input_queue, (u8 *) & rmp);
1304}
1305
1306static inline void
1307vppcom_send_disconnect_session (u64 vpp_handle, u32 session_index)
Dave Wallace543852a2017-08-03 02:11:34 -04001308{
Dave Wallace543852a2017-08-03 02:11:34 -04001309 vl_api_disconnect_session_t *dmp;
Dave Wallace543852a2017-08-03 02:11:34 -04001310
Dave Wallace4878cbe2017-11-21 03:45:09 -05001311 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05001312 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
1313 "sending disconnect msg",
Dave Wallace4878cbe2017-11-21 03:45:09 -05001314 getpid (), vpp_handle, session_index);
1315
Dave Wallace543852a2017-08-03 02:11:34 -04001316 dmp = vl_msg_api_alloc (sizeof (*dmp));
1317 memset (dmp, 0, sizeof (*dmp));
1318 dmp->_vl_msg_id = ntohs (VL_API_DISCONNECT_SESSION);
1319 dmp->client_index = vcm->my_client_index;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001320 dmp->handle = vpp_handle;
Dave Wallace543852a2017-08-03 02:11:34 -04001321 vl_msg_api_send_shmem (vcm->vl_input_queue, (u8 *) & dmp);
Dave Wallace543852a2017-08-03 02:11:34 -04001322}
1323
1324static void
1325vl_api_bind_sock_reply_t_handler (vl_api_bind_sock_reply_t * mp)
1326{
Dave Wallace543852a2017-08-03 02:11:34 -04001327 session_t *session = 0;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001328 u32 session_index = mp->context;
Dave Wallace543852a2017-08-03 02:11:34 -04001329 int rv;
1330
Dave Wallaceee45d412017-11-24 21:44:06 -05001331 VCL_LOCK_AND_GET_SESSION (session_index, &session);
1332done:
Dave Wallace543852a2017-08-03 02:11:34 -04001333 if (mp->retval)
Dave Wallace4878cbe2017-11-21 03:45:09 -05001334 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001335 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, "
1336 "sid %u: bind failed: %U",
1337 getpid (), mp->handle, session_index,
1338 format_api_error, ntohl (mp->retval));
Dave Wallace4878cbe2017-11-21 03:45:09 -05001339 rv = vppcom_session_at_index (session_index, &session);
1340 if (rv == VPPCOM_OK)
Dave Wallaceee45d412017-11-24 21:44:06 -05001341 {
1342 session->state = STATE_FAILED;
1343 session->vpp_handle = mp->handle;
1344 }
1345 else
1346 {
1347 clib_warning ("[%s] ERROR: vpp handle 0x%llx, sid %u: "
1348 "Invalid session index (%u)!",
1349 getpid (), mp->handle, session_index);
1350 }
1351 goto done_unlock;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001352 }
Dave Wallace543852a2017-08-03 02:11:34 -04001353
Dave Wallaceee45d412017-11-24 21:44:06 -05001354 session->vpp_handle = mp->handle;
1355 session->lcl_addr.is_ip4 = mp->lcl_is_ip4;
Dave Wallacede910062018-03-20 09:22:13 -04001356 session->lcl_addr.ip46 = to_ip46 (!mp->lcl_is_ip4, mp->lcl_ip);
Dave Wallaceee45d412017-11-24 21:44:06 -05001357 session->lcl_port = mp->lcl_port;
1358 vppcom_session_table_add_listener (mp->handle, session_index);
Dave Wallaceee45d412017-11-24 21:44:06 -05001359 session->state = STATE_LISTEN;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001360
Dave Wallaceee45d412017-11-24 21:44:06 -05001361 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05001362 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: bind succeeded!",
Dave Wallaceee45d412017-11-24 21:44:06 -05001363 getpid (), mp->handle, mp->context);
1364done_unlock:
Dave Wallace543852a2017-08-03 02:11:34 -04001365 clib_spinlock_unlock (&vcm->sessions_lockp);
1366}
1367
1368static void
1369vl_api_unbind_sock_reply_t_handler (vl_api_unbind_sock_reply_t * mp)
1370{
Dave Wallace4878cbe2017-11-21 03:45:09 -05001371 if (mp->retval)
Dave Wallace048b1d62018-01-03 22:24:41 -05001372 clib_warning ("VCL<%d>: ERROR: sid %u: unbind failed: %U",
Dave Wallace4878cbe2017-11-21 03:45:09 -05001373 getpid (), mp->context, format_api_error,
1374 ntohl (mp->retval));
Dave Wallace543852a2017-08-03 02:11:34 -04001375
Dave Wallace4878cbe2017-11-21 03:45:09 -05001376 else if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05001377 clib_warning ("VCL<%d>: sid %u: unbind succeeded!",
1378 getpid (), mp->context);
Dave Wallace543852a2017-08-03 02:11:34 -04001379}
1380
1381u8 *
1382format_ip4_address (u8 * s, va_list * args)
1383{
1384 u8 *a = va_arg (*args, u8 *);
1385 return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
1386}
1387
1388u8 *
1389format_ip6_address (u8 * s, va_list * args)
1390{
1391 ip6_address_t *a = va_arg (*args, ip6_address_t *);
1392 u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
1393
1394 i_max_n_zero = ARRAY_LEN (a->as_u16);
1395 max_n_zeros = 0;
1396 i_first_zero = i_max_n_zero;
1397 n_zeros = 0;
1398 for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
1399 {
1400 u32 is_zero = a->as_u16[i] == 0;
1401 if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
1402 {
1403 i_first_zero = i;
1404 n_zeros = 0;
1405 }
1406 n_zeros += is_zero;
1407 if ((!is_zero && n_zeros > max_n_zeros)
1408 || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
1409 {
1410 i_max_n_zero = i_first_zero;
1411 max_n_zeros = n_zeros;
1412 i_first_zero = ARRAY_LEN (a->as_u16);
1413 n_zeros = 0;
1414 }
1415 }
1416
1417 last_double_colon = 0;
1418 for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
1419 {
1420 if (i == i_max_n_zero && max_n_zeros > 1)
1421 {
1422 s = format (s, "::");
1423 i += max_n_zeros - 1;
1424 last_double_colon = 1;
1425 }
1426 else
1427 {
1428 s = format (s, "%s%x",
1429 (last_double_colon || i == 0) ? "" : ":",
1430 clib_net_to_host_u16 (a->as_u16[i]));
1431 last_double_colon = 0;
1432 }
1433 }
1434
1435 return s;
1436}
1437
1438/* Format an IP46 address. */
1439u8 *
1440format_ip46_address (u8 * s, va_list * args)
1441{
1442 ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
1443 ip46_type_t type = va_arg (*args, ip46_type_t);
1444 int is_ip4 = 1;
1445
1446 switch (type)
1447 {
1448 case IP46_TYPE_ANY:
1449 is_ip4 = ip46_address_is_ip4 (ip46);
1450 break;
1451 case IP46_TYPE_IP4:
1452 is_ip4 = 1;
1453 break;
1454 case IP46_TYPE_IP6:
1455 is_ip4 = 0;
1456 break;
1457 }
1458
1459 return is_ip4 ?
1460 format (s, "%U", format_ip4_address, &ip46->ip4) :
1461 format (s, "%U", format_ip6_address, &ip46->ip6);
1462}
1463
1464static void
1465vl_api_accept_session_t_handler (vl_api_accept_session_t * mp)
1466{
Dave Wallace543852a2017-08-03 02:11:34 -04001467 svm_fifo_t *rx_fifo, *tx_fifo;
Florin Corasdcf55ce2017-11-16 15:32:50 -08001468 session_t *session, *listen_session;
Dave Wallace543852a2017-08-03 02:11:34 -04001469 u32 session_index;
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001470 vce_event_connect_request_t *ecr;
1471 vce_event_t *ev;
1472 int rv;
1473 u32 ev_idx;
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08001474 uword elts = 0;
Dave Wallace543852a2017-08-03 02:11:34 -04001475
Dave Wallace60caa062017-11-10 17:07:13 -05001476 clib_spinlock_lock (&vcm->sessions_lockp);
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08001477
1478 clib_spinlock_lock (&vcm->session_fifo_lockp);
1479 elts = clib_fifo_free_elts (vcm->client_session_index_fifo);
1480 clib_spinlock_unlock (&vcm->session_fifo_lockp);
1481
1482 if (!elts)
Dave Wallace543852a2017-08-03 02:11:34 -04001483 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001484 clib_warning ("VCL<%d>: client session queue is full!", getpid ());
Dave Wallaced2931962017-11-25 04:17:39 -05001485 vppcom_send_accept_session_reply (mp->handle, mp->context,
Florin Corasdcf55ce2017-11-16 15:32:50 -08001486 VNET_API_ERROR_QUEUE_FULL);
1487 clib_spinlock_unlock (&vcm->sessions_lockp);
1488 return;
1489 }
1490
1491 listen_session = vppcom_session_table_lookup_listener (mp->listener_handle);
1492 if (!listen_session)
1493 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001494 clib_warning ("VCL<%d>: ERROR: couldn't find listen session: "
1495 "unknown vpp listener handle %llx",
1496 getpid (), mp->listener_handle);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001497 vppcom_send_accept_session_reply (mp->handle, mp->context,
1498 VNET_API_ERROR_INVALID_ARGUMENT);
Dave Wallace60caa062017-11-10 17:07:13 -05001499 clib_spinlock_unlock (&vcm->sessions_lockp);
1500 return;
Dave Wallace543852a2017-08-03 02:11:34 -04001501 }
1502
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001503 /* TODO check listener depth and update */
1504 /* TODO on "child" fd close, update listener depth */
1505
Dave Wallace543852a2017-08-03 02:11:34 -04001506 /* Allocate local session and set it up */
1507 pool_get (vcm->sessions, session);
1508 memset (session, 0, sizeof (*session));
Keith Burns (alagalah)410bcca2018-03-23 13:42:49 -07001509 session_index = (u32) (session - vcm->sessions);
Dave Wallace543852a2017-08-03 02:11:34 -04001510
1511 rx_fifo = uword_to_pointer (mp->server_rx_fifo, svm_fifo_t *);
1512 rx_fifo->client_session_index = session_index;
1513 tx_fifo = uword_to_pointer (mp->server_tx_fifo, svm_fifo_t *);
1514 tx_fifo->client_session_index = session_index;
1515
Dave Wallace60caa062017-11-10 17:07:13 -05001516 session->vpp_handle = mp->handle;
Dave Wallaced2931962017-11-25 04:17:39 -05001517 session->client_context = mp->context;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001518 session->rx_fifo = rx_fifo;
1519 session->tx_fifo = tx_fifo;
Dave Wallace33e002b2017-09-06 01:20:02 -04001520 session->vpp_event_queue = uword_to_pointer (mp->vpp_event_queue_address,
Florin Corase86a8ed2018-01-05 03:20:25 -08001521 svm_queue_t *);
Dave Wallace543852a2017-08-03 02:11:34 -04001522 session->state = STATE_ACCEPT;
Stevenac1f96d2017-10-24 16:03:58 -07001523 session->peer_port = mp->port;
Dave Wallace35830af2017-10-09 01:43:42 -04001524 session->peer_addr.is_ip4 = mp->is_ip4;
Dave Wallacede910062018-03-20 09:22:13 -04001525 session->peer_addr.ip46 = to_ip46 (!mp->is_ip4, mp->ip);
Dave Wallace543852a2017-08-03 02:11:34 -04001526
1527 /* Add it to lookup table */
1528 hash_set (vcm->session_index_by_vpp_handles, mp->handle, session_index);
Florin Corasdcf55ce2017-11-16 15:32:50 -08001529 session->lcl_port = listen_session->lcl_port;
1530 session->lcl_addr = listen_session->lcl_addr;
Dave Wallace227867f2017-11-13 21:21:53 -05001531
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001532 /* Create an event for handlers */
1533
1534 clib_spinlock_lock (&vcm->event_thread.events_lockp);
1535
1536 pool_get (vcm->event_thread.vce_events, ev);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001537 ev_idx = (u32) (ev - vcm->event_thread.vce_events);
Keith Burns (alagalah)410bcca2018-03-23 13:42:49 -07001538 ecr = vce_get_event_data (ev, sizeof (*ecr));
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001539 ev->evk.eid = VCL_EVENT_CONNECT_REQ_ACCEPTED;
1540 listen_session = vppcom_session_table_lookup_listener (mp->listener_handle);
1541 ev->evk.session_index = (u32) (listen_session - vcm->sessions);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001542 ecr->accepted_session_index = session_index;
1543
1544 clib_spinlock_unlock (&vcm->event_thread.events_lockp);
1545
1546 rv = vce_generate_event (&vcm->event_thread, ev_idx);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001547 ASSERT (rv == 0);
Florin Corasdcf55ce2017-11-16 15:32:50 -08001548
Dave Wallace60caa062017-11-10 17:07:13 -05001549 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05001550 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: client accept "
Florin Coras50e8bdb2017-11-27 10:37:05 -08001551 "request from %s address %U port %d queue %p!", getpid (),
Dave Wallaced2931962017-11-25 04:17:39 -05001552 mp->handle, session_index, mp->is_ip4 ? "IPv4" : "IPv6",
Dave Wallacede910062018-03-20 09:22:13 -04001553 format_ip46_address, &mp->ip,
1554 mp->is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6,
Florin Coras50e8bdb2017-11-27 10:37:05 -08001555 clib_net_to_host_u16 (mp->port), session->vpp_event_queue);
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08001556
1557 if (VPPCOM_DEBUG > 0)
1558 {
1559 session->elog_track.name =
1560 (char *) format (0, "C:%d:S:%d%c", vcm->my_client_index,
1561 session_index, 0);
1562 elog_track_register (&vcm->elog_main, &session->elog_track);
1563
1564 if (session->peer_addr.is_ip4)
1565 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08001566 /* *INDENT-OFF* */
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08001567 ELOG_TYPE_DECLARE (e) =
1568 {
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08001569 .format =
1570 "client_accept:handle:%x addr:%d.%d.%d.%d:%d",
1571 .format_args = "i8i1i1i1i1i2",
1572 };
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08001573
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08001574 CLIB_PACKED (struct {
1575 u64 handle; //8
1576 u8 addr[4]; //4
1577 u16 port; //2
1578 }) * ed;
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08001579
1580 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
1581
1582 ed->handle = mp->handle;
1583 ed->addr[0] = session->peer_addr.ip46.ip4.as_u8[0];
1584 ed->addr[1] = session->peer_addr.ip46.ip4.as_u8[1];
1585 ed->addr[2] = session->peer_addr.ip46.ip4.as_u8[2];
1586 ed->addr[3] = session->peer_addr.ip46.ip4.as_u8[3];
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08001587 ed->port = clib_net_to_host_u16 (session->peer_port);
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08001588 /* *INDENT-ON* */
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08001589 }
1590 else
1591 {
1592 clib_warning ("ip6");
1593 }
1594 }
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08001595
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001596 clib_spinlock_unlock (&vcm->sessions_lockp);
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08001597
Dave Wallace60caa062017-11-10 17:07:13 -05001598}
1599
Keith Burns (alagalah)410bcca2018-03-23 13:42:49 -07001600/* VPP combines bind and listen as one operation. VCL manages the separation
1601 * of bind and listen locally via vppcom_session_bind() and
1602 * vppcom_session_listen() */
Dave Wallace60caa062017-11-10 17:07:13 -05001603static void
Dave Wallace4878cbe2017-11-21 03:45:09 -05001604vppcom_send_bind_sock (session_t * session, u32 session_index)
Dave Wallace543852a2017-08-03 02:11:34 -04001605{
Dave Wallace543852a2017-08-03 02:11:34 -04001606 vl_api_bind_sock_t *bmp;
1607
1608 /* Assumes caller has acquired spinlock: vcm->sessions_lockp */
Dave Wallace543852a2017-08-03 02:11:34 -04001609 bmp = vl_msg_api_alloc (sizeof (*bmp));
1610 memset (bmp, 0, sizeof (*bmp));
1611
1612 bmp->_vl_msg_id = ntohs (VL_API_BIND_SOCK);
1613 bmp->client_index = vcm->my_client_index;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001614 bmp->context = session_index;
Dave Wallace35830af2017-10-09 01:43:42 -04001615 bmp->is_ip4 = session->lcl_addr.is_ip4;
1616 clib_memcpy (bmp->ip, &session->lcl_addr.ip46, sizeof (bmp->ip));
Stevenac1f96d2017-10-24 16:03:58 -07001617 bmp->port = session->lcl_port;
Dave Wallace543852a2017-08-03 02:11:34 -04001618 bmp->proto = session->proto;
1619 clib_memcpy (bmp->options, session->options, sizeof (bmp->options));
1620 vl_msg_api_send_shmem (vcm->vl_input_queue, (u8 *) & bmp);
1621}
1622
1623static void
Dave Wallace4878cbe2017-11-21 03:45:09 -05001624vppcom_send_unbind_sock (u64 vpp_handle)
Dave Wallace543852a2017-08-03 02:11:34 -04001625{
Dave Wallace543852a2017-08-03 02:11:34 -04001626 vl_api_unbind_sock_t *ump;
Dave Wallace543852a2017-08-03 02:11:34 -04001627
1628 ump = vl_msg_api_alloc (sizeof (*ump));
1629 memset (ump, 0, sizeof (*ump));
1630
1631 ump->_vl_msg_id = ntohs (VL_API_UNBIND_SOCK);
1632 ump->client_index = vcm->my_client_index;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001633 ump->handle = vpp_handle;
Dave Wallace543852a2017-08-03 02:11:34 -04001634 vl_msg_api_send_shmem (vcm->vl_input_queue, (u8 *) & ump);
1635}
1636
1637static int
Dave Wallace543852a2017-08-03 02:11:34 -04001638vppcom_session_unbind (u32 session_index)
1639{
Dave Wallace4878cbe2017-11-21 03:45:09 -05001640 session_t *session = 0;
Dave Wallace543852a2017-08-03 02:11:34 -04001641 int rv;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001642 u64 vpp_handle;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001643 elog_track_t session_elog_track;
Dave Wallace543852a2017-08-03 02:11:34 -04001644
Dave Wallace4878cbe2017-11-21 03:45:09 -05001645 VCL_LOCK_AND_GET_SESSION (session_index, &session);
1646
1647 vpp_handle = session->vpp_handle;
1648 vppcom_session_table_del_listener (vpp_handle);
1649 session->vpp_handle = ~0;
1650 session->state = STATE_DISCONNECT;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001651 session_elog_track = session->elog_track;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001652
Dave Wallace543852a2017-08-03 02:11:34 -04001653 clib_spinlock_unlock (&vcm->sessions_lockp);
1654
Dave Wallace4878cbe2017-11-21 03:45:09 -05001655 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05001656 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
Dave Wallace4878cbe2017-11-21 03:45:09 -05001657 "sending unbind msg! new state 0x%x (%s)",
1658 getpid (), vpp_handle, session_index,
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001659 STATE_DISCONNECT,
1660 vppcom_session_state_str (STATE_DISCONNECT));
Dave Wallace4878cbe2017-11-21 03:45:09 -05001661
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08001662 if (VPPCOM_DEBUG > 0)
1663 {
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08001664 /* *INDENT-OFF* */
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08001665 ELOG_TYPE_DECLARE (e) =
1666 {
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08001667 .format = "unbind: handle:%x",
1668 .format_args = "i8",
1669 };
1670
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08001671 struct
1672 {
1673 u64 handle;
1674 } *ed;
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08001675
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001676 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session_elog_track);
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08001677 ed->handle = vpp_handle;
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08001678 /* *INDENT-ON* */
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08001679 }
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001680
Dave Wallace4878cbe2017-11-21 03:45:09 -05001681 vppcom_send_unbind_sock (vpp_handle);
1682
1683done:
1684 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04001685}
1686
Dave Wallace66cf6eb2017-10-26 02:51:07 -04001687static inline int
Dave Wallace543852a2017-08-03 02:11:34 -04001688vppcom_session_disconnect (u32 session_index)
1689{
Dave Wallace543852a2017-08-03 02:11:34 -04001690 int rv;
Dave Wallace66cf6eb2017-10-26 02:51:07 -04001691 session_t *session;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001692 u64 vpp_handle;
1693 session_state_t state;
Dave Wallace543852a2017-08-03 02:11:34 -04001694
Dave Wallace4878cbe2017-11-21 03:45:09 -05001695 VCL_LOCK_AND_GET_SESSION (session_index, &session);
1696
1697 vpp_handle = session->vpp_handle;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001698 state = session->state;
1699 clib_spinlock_unlock (&vcm->sessions_lockp);
1700
1701 if (VPPCOM_DEBUG > 1)
Dave Wallace543852a2017-08-03 02:11:34 -04001702 {
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001703 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u "
1704 "state 0x%x (%s)",
Dave Wallace4878cbe2017-11-21 03:45:09 -05001705 getpid (), vpp_handle, session_index,
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001706 state, vppcom_session_state_str (state));
Dave Wallace543852a2017-08-03 02:11:34 -04001707 }
Dave Wallace66cf6eb2017-10-26 02:51:07 -04001708
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001709 if (PREDICT_FALSE (state & STATE_LISTEN))
Dave Wallace66cf6eb2017-10-26 02:51:07 -04001710 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001711 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -05001712 "Cannot disconnect a listen socket!",
1713 getpid (), vpp_handle, session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001714 rv = VPPCOM_EBADFD;
1715 goto done;
1716 }
Dave Wallace66cf6eb2017-10-26 02:51:07 -04001717
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001718 /* The peer has already initiated the close,
1719 * so send the disconnect session reply.
Dave Wallace4878cbe2017-11-21 03:45:09 -05001720 */
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001721 if (state & STATE_CLOSE_ON_EMPTY)
Dave Wallace4878cbe2017-11-21 03:45:09 -05001722 {
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001723 //XXX alagalah - Check and drain here?
1724 vppcom_send_disconnect_session_reply (vpp_handle,
1725 session_index, 0 /* rv */ );
1726 if (VPPCOM_DEBUG > 1)
1727 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
1728 "sending disconnect REPLY...",
1729 getpid (), vpp_handle, session_index);
Dave Wallace66cf6eb2017-10-26 02:51:07 -04001730 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05001731
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001732 /* Otherwise, send a disconnect session msg...
Dave Wallace4878cbe2017-11-21 03:45:09 -05001733 */
Dave Wallace66cf6eb2017-10-26 02:51:07 -04001734 else
Dave Wallace227867f2017-11-13 21:21:53 -05001735 {
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001736 if (VPPCOM_DEBUG > 1)
1737 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
1738 "sending disconnect...",
1739 getpid (), vpp_handle, session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001740
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001741 vppcom_send_disconnect_session (vpp_handle, session_index);
Dave Wallace227867f2017-11-13 21:21:53 -05001742 }
Dave Wallace66cf6eb2017-10-26 02:51:07 -04001743
Dave Wallace4878cbe2017-11-21 03:45:09 -05001744done:
1745 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04001746}
1747
1748#define foreach_sock_msg \
1749_(SESSION_ENABLE_DISABLE_REPLY, session_enable_disable_reply) \
1750_(BIND_SOCK_REPLY, bind_sock_reply) \
1751_(UNBIND_SOCK_REPLY, unbind_sock_reply) \
1752_(ACCEPT_SESSION, accept_session) \
Dave Wallace33e002b2017-09-06 01:20:02 -04001753_(CONNECT_SESSION_REPLY, connect_session_reply) \
Dave Wallace543852a2017-08-03 02:11:34 -04001754_(DISCONNECT_SESSION, disconnect_session) \
1755_(DISCONNECT_SESSION_REPLY, disconnect_session_reply) \
1756_(RESET_SESSION, reset_session) \
1757_(APPLICATION_ATTACH_REPLY, application_attach_reply) \
1758_(APPLICATION_DETACH_REPLY, application_detach_reply) \
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001759_(MAP_ANOTHER_SEGMENT, map_another_segment) \
1760_(UNMAP_SEGMENT, unmap_segment)
Dave Wallace543852a2017-08-03 02:11:34 -04001761
1762static void
1763vppcom_api_hookup (void)
1764{
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08001765#define _(N, n) \
Dave Wallace543852a2017-08-03 02:11:34 -04001766 vl_msg_api_set_handlers(VL_API_##N, #n, \
1767 vl_api_##n##_t_handler, \
1768 vl_noop_handler, \
1769 vl_api_##n##_t_endian, \
1770 vl_api_##n##_t_print, \
1771 sizeof(vl_api_##n##_t), 1);
1772 foreach_sock_msg;
1773#undef _
1774}
1775
1776static void
1777vppcom_cfg_init (vppcom_cfg_t * vcl_cfg)
1778{
1779 ASSERT (vcl_cfg);
1780
1781 vcl_cfg->heapsize = (256ULL << 20);
Dave Wallacec8f1ee62017-11-29 22:46:32 -05001782 vcl_cfg->vpp_api_q_length = 1024;
Dave Wallace543852a2017-08-03 02:11:34 -04001783 vcl_cfg->segment_baseva = 0x200000000ULL;
1784 vcl_cfg->segment_size = (256 << 20);
1785 vcl_cfg->add_segment_size = (128 << 20);
1786 vcl_cfg->preallocated_fifo_pairs = 8;
1787 vcl_cfg->rx_fifo_size = (1 << 20);
1788 vcl_cfg->tx_fifo_size = (1 << 20);
1789 vcl_cfg->event_queue_size = 2048;
1790 vcl_cfg->listen_queue_size = CLIB_CACHE_LINE_BYTES / sizeof (u32);
1791 vcl_cfg->app_timeout = 10 * 60.0;
1792 vcl_cfg->session_timeout = 10 * 60.0;
1793 vcl_cfg->accept_timeout = 60.0;
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -08001794 vcl_cfg->event_ring_size = (128 << 10);
1795 vcl_cfg->event_log_path = "/dev/shm";
Dave Wallace543852a2017-08-03 02:11:34 -04001796}
1797
1798static void
1799vppcom_cfg_heapsize (char *conf_fname)
1800{
Dave Wallace543852a2017-08-03 02:11:34 -04001801 vppcom_cfg_t *vcl_cfg = &vcm->cfg;
1802 FILE *fp;
1803 char inbuf[4096];
1804 int argc = 1;
1805 char **argv = NULL;
1806 char *arg = NULL;
1807 char *p;
1808 int i;
1809 u8 *sizep;
1810 u32 size;
Dave Wallace2e005bb2017-11-07 01:21:39 -05001811 void *vcl_mem;
1812 void *heap;
Dave Wallace543852a2017-08-03 02:11:34 -04001813
1814 fp = fopen (conf_fname, "r");
1815 if (fp == NULL)
1816 {
1817 if (VPPCOM_DEBUG > 0)
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05001818 clib_warning ("VCL<%d>: using default heapsize %lld (0x%llx)",
1819 getpid (), vcl_cfg->heapsize, vcl_cfg->heapsize);
Dave Wallace543852a2017-08-03 02:11:34 -04001820 goto defaulted;
1821 }
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05001822
Dave Wallace543852a2017-08-03 02:11:34 -04001823 argv = calloc (1, sizeof (char *));
1824 if (argv == NULL)
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05001825 {
1826 if (VPPCOM_DEBUG > 0)
1827 clib_warning ("VCL<%d>: calloc failed, using default "
1828 "heapsize %lld (0x%llx)",
1829 getpid (), vcl_cfg->heapsize, vcl_cfg->heapsize);
1830 goto defaulted;
1831 }
Dave Wallace543852a2017-08-03 02:11:34 -04001832
1833 while (1)
1834 {
1835 if (fgets (inbuf, 4096, fp) == 0)
1836 break;
1837 p = strtok (inbuf, " \t\n");
1838 while (p != NULL)
1839 {
1840 if (*p == '#')
1841 break;
1842 argc++;
1843 char **tmp = realloc (argv, argc * sizeof (char *));
1844 if (tmp == NULL)
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05001845 {
1846 if (VPPCOM_DEBUG > 0)
1847 clib_warning ("VCL<%d>: realloc failed, "
1848 "using default heapsize %lld (0x%llx)",
1849 getpid (), vcl_cfg->heapsize,
1850 vcl_cfg->heapsize);
1851 goto defaulted;
1852 }
Dave Wallace543852a2017-08-03 02:11:34 -04001853 argv = tmp;
1854 arg = strndup (p, 1024);
1855 if (arg == NULL)
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05001856 {
1857 if (VPPCOM_DEBUG > 0)
1858 clib_warning ("VCL<%d>: strndup failed, "
1859 "using default heapsize %lld (0x%llx)",
1860 getpid (), vcl_cfg->heapsize,
1861 vcl_cfg->heapsize);
1862 goto defaulted;
1863 }
Dave Wallace543852a2017-08-03 02:11:34 -04001864 argv[argc - 1] = arg;
1865 p = strtok (NULL, " \t\n");
1866 }
1867 }
1868
1869 fclose (fp);
Chris Lukeab7b8d92017-09-07 07:40:13 -04001870 fp = NULL;
Dave Wallace543852a2017-08-03 02:11:34 -04001871
1872 char **tmp = realloc (argv, (argc + 1) * sizeof (char *));
1873 if (tmp == NULL)
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05001874 {
1875 if (VPPCOM_DEBUG > 0)
1876 clib_warning ("VCL<%d>: realloc failed, "
1877 "using default heapsize %lld (0x%llx)",
1878 getpid (), vcl_cfg->heapsize, vcl_cfg->heapsize);
1879 goto defaulted;
1880 }
Dave Wallace543852a2017-08-03 02:11:34 -04001881 argv = tmp;
1882 argv[argc] = NULL;
1883
1884 /*
1885 * Look for and parse the "heapsize" config parameter.
1886 * Manual since none of the clib infra has been bootstrapped yet.
1887 *
1888 * Format: heapsize <nn>[mM][gG]
1889 */
1890
1891 for (i = 1; i < (argc - 1); i++)
1892 {
1893 if (!strncmp (argv[i], "heapsize", 8))
1894 {
1895 sizep = (u8 *) argv[i + 1];
1896 size = 0;
1897 while (*sizep >= '0' && *sizep <= '9')
1898 {
1899 size *= 10;
1900 size += *sizep++ - '0';
1901 }
1902 if (size == 0)
1903 {
1904 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001905 clib_warning ("VCL<%d>: parse error '%s %s', "
Dave Wallace543852a2017-08-03 02:11:34 -04001906 "using default heapsize %lld (0x%llx)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05001907 getpid (), argv[i], argv[i + 1],
Dave Wallace543852a2017-08-03 02:11:34 -04001908 vcl_cfg->heapsize, vcl_cfg->heapsize);
1909 goto defaulted;
1910 }
1911
1912 if (*sizep == 'g' || *sizep == 'G')
1913 vcl_cfg->heapsize = size << 30;
1914 else if (*sizep == 'm' || *sizep == 'M')
1915 vcl_cfg->heapsize = size << 20;
1916 else
1917 {
1918 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001919 clib_warning ("VCL<%d>: parse error '%s %s', "
Dave Wallace543852a2017-08-03 02:11:34 -04001920 "using default heapsize %lld (0x%llx)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05001921 getpid (), argv[i], argv[i + 1],
Dave Wallace543852a2017-08-03 02:11:34 -04001922 vcl_cfg->heapsize, vcl_cfg->heapsize);
1923 goto defaulted;
1924 }
1925 }
1926 }
1927
1928defaulted:
Chris Lukeab7b8d92017-09-07 07:40:13 -04001929 if (fp != NULL)
1930 fclose (fp);
1931 if (argv != NULL)
1932 free (argv);
Dave Wallacee7fa24e2017-11-07 13:07:44 -05001933
Dave Wallace2e005bb2017-11-07 01:21:39 -05001934 vcl_mem = mmap (0, vcl_cfg->heapsize, PROT_READ | PROT_WRITE,
1935 MAP_SHARED | MAP_ANONYMOUS, -1, 0);
Steven0cdd5bd2017-11-08 14:14:45 -08001936 if (vcl_mem == MAP_FAILED)
Dave Wallacee7fa24e2017-11-07 13:07:44 -05001937 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001938 clib_unix_error ("VCL<%d>: ERROR: mmap(0, %lld == 0x%llx, "
Dave Wallacee7fa24e2017-11-07 13:07:44 -05001939 "PROT_READ | PROT_WRITE,MAP_SHARED | MAP_ANONYMOUS, "
1940 "-1, 0) failed!",
1941 getpid (), vcl_cfg->heapsize, vcl_cfg->heapsize);
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05001942 ASSERT (vcl_mem != MAP_FAILED);
Dave Wallacee7fa24e2017-11-07 13:07:44 -05001943 return;
1944 }
Dave Wallace2e005bb2017-11-07 01:21:39 -05001945 heap = clib_mem_init (vcl_mem, vcl_cfg->heapsize);
1946 if (!heap)
Dave Wallace2e005bb2017-11-07 01:21:39 -05001947 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001948 clib_warning ("VCL<%d>: ERROR: clib_mem_init() failed!", getpid ());
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05001949 ASSERT (heap);
Dave Wallacee7fa24e2017-11-07 13:07:44 -05001950 return;
Dave Wallace2e005bb2017-11-07 01:21:39 -05001951 }
Dave Wallacee7fa24e2017-11-07 13:07:44 -05001952 vcl_mem = clib_mem_alloc (sizeof (_vppcom_main));
1953 if (!vcl_mem)
1954 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001955 clib_warning ("VCL<%d>: ERROR: clib_mem_alloc() failed!", getpid ());
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05001956 ASSERT (vcl_mem);
Dave Wallacee7fa24e2017-11-07 13:07:44 -05001957 return;
1958 }
1959
1960 clib_memcpy (vcl_mem, &_vppcom_main, sizeof (_vppcom_main));
1961 vcm = vcl_mem;
1962
1963 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001964 clib_warning ("VCL<%d>: allocated VCL heap = %p, size %lld (0x%llx)",
Dave Wallacee7fa24e2017-11-07 13:07:44 -05001965 getpid (), heap, vcl_cfg->heapsize, vcl_cfg->heapsize);
Dave Wallace543852a2017-08-03 02:11:34 -04001966}
1967
1968static void
1969vppcom_cfg_read (char *conf_fname)
1970{
Dave Wallace543852a2017-08-03 02:11:34 -04001971 vppcom_cfg_t *vcl_cfg = &vcm->cfg;
1972 int fd;
1973 unformat_input_t _input, *input = &_input;
1974 unformat_input_t _line_input, *line_input = &_line_input;
1975 u8 vc_cfg_input = 0;
1976 u8 *chroot_path;
1977 struct stat s;
Dave Wallacec8f1ee62017-11-29 22:46:32 -05001978 u32 uid, gid, q_len;
Dave Wallace543852a2017-08-03 02:11:34 -04001979
1980 fd = open (conf_fname, O_RDONLY);
1981 if (fd < 0)
1982 {
1983 if (VPPCOM_DEBUG > 0)
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05001984 clib_warning ("VCL<%d>: using default configuration.",
Dave Wallace2e005bb2017-11-07 01:21:39 -05001985 getpid (), conf_fname);
Dave Wallace543852a2017-08-03 02:11:34 -04001986 goto file_done;
1987 }
1988
1989 if (fstat (fd, &s) < 0)
1990 {
1991 if (VPPCOM_DEBUG > 0)
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05001992 clib_warning ("VCL<%d>: failed to stat `%s', "
1993 "using default configuration", getpid (), conf_fname);
Dave Wallace543852a2017-08-03 02:11:34 -04001994 goto file_done;
1995 }
1996
1997 if (!(S_ISREG (s.st_mode) || S_ISLNK (s.st_mode)))
1998 {
1999 if (VPPCOM_DEBUG > 0)
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05002000 clib_warning ("VCL<%d>: not a regular file `%s', "
2001 "using default configuration", getpid (), conf_fname);
Dave Wallace543852a2017-08-03 02:11:34 -04002002 goto file_done;
2003 }
2004
Dave Barach59b25652017-09-10 15:04:27 -04002005 unformat_init_clib_file (input, fd);
Dave Wallace543852a2017-08-03 02:11:34 -04002006
2007 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
2008 {
Chris Lukeb2bcad62017-09-18 08:51:22 -04002009 (void) unformat_user (input, unformat_line_input, line_input);
Dave Wallace543852a2017-08-03 02:11:34 -04002010 unformat_skip_white_space (line_input);
2011
Dave Wallace8af20542017-10-26 03:29:30 -04002012 if (unformat (line_input, "vcl {"))
Dave Wallace543852a2017-08-03 02:11:34 -04002013 {
2014 vc_cfg_input = 1;
2015 continue;
2016 }
2017
2018 if (vc_cfg_input)
2019 {
2020 if (unformat (line_input, "heapsize %s", &chroot_path))
2021 {
2022 vec_terminate_c_string (chroot_path);
2023 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002024 clib_warning ("VCL<%d>: configured heapsize %s, "
Dave Wallace543852a2017-08-03 02:11:34 -04002025 "actual heapsize %lld (0x%llx)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002026 getpid (), chroot_path, vcl_cfg->heapsize,
Dave Wallace543852a2017-08-03 02:11:34 -04002027 vcl_cfg->heapsize);
2028 vec_free (chroot_path);
2029 }
2030 else if (unformat (line_input, "api-prefix %s", &chroot_path))
2031 {
2032 vec_terminate_c_string (chroot_path);
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05002033 if (vcl_cfg->vpp_api_filename)
2034 vec_free (vcl_cfg->vpp_api_filename);
2035 vcl_cfg->vpp_api_filename = format (0, "/%s-vpe-api%c",
2036 chroot_path, 0);
Dave Wallace543852a2017-08-03 02:11:34 -04002037 vl_set_memory_root_path ((char *) chroot_path);
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05002038
Dave Wallace543852a2017-08-03 02:11:34 -04002039 if (VPPCOM_DEBUG > 0)
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05002040 clib_warning ("VCL<%d>: configured api-prefix (%s) and "
2041 "api filename (%s)", getpid (), chroot_path,
2042 vcl_cfg->vpp_api_filename);
Dave Wallace543852a2017-08-03 02:11:34 -04002043 chroot_path = 0; /* Don't vec_free() it! */
2044 }
Dave Wallacec8f1ee62017-11-29 22:46:32 -05002045 else if (unformat (line_input, "vpp-api-q-length %d", &q_len))
2046 {
2047 if (q_len < vcl_cfg->vpp_api_q_length)
2048 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002049 clib_warning ("VCL<%d>: ERROR: configured vpp-api-q-length "
Dave Wallacec8f1ee62017-11-29 22:46:32 -05002050 "(%u) is too small! Using default: %u ",
2051 getpid (), q_len, vcl_cfg->vpp_api_q_length);
2052 }
2053 else
2054 {
2055 vcl_cfg->vpp_api_q_length = q_len;
2056
2057 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002058 clib_warning ("VCL<%d>: configured vpp-api-q-length %u",
Dave Wallacec8f1ee62017-11-29 22:46:32 -05002059 getpid (), vcl_cfg->vpp_api_q_length);
2060 }
2061 }
Dave Wallace543852a2017-08-03 02:11:34 -04002062 else if (unformat (line_input, "uid %d", &uid))
2063 {
2064 vl_set_memory_uid (uid);
2065 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002066 clib_warning ("VCL<%d>: configured uid %d", getpid (), uid);
Dave Wallace543852a2017-08-03 02:11:34 -04002067 }
2068 else if (unformat (line_input, "gid %d", &gid))
2069 {
2070 vl_set_memory_gid (gid);
2071 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002072 clib_warning ("VCL<%d>: configured gid %d", getpid (), gid);
Dave Wallace543852a2017-08-03 02:11:34 -04002073 }
Dave Wallace8af20542017-10-26 03:29:30 -04002074 else if (unformat (line_input, "segment-baseva 0x%lx",
Dave Wallace543852a2017-08-03 02:11:34 -04002075 &vcl_cfg->segment_baseva))
2076 {
2077 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002078 clib_warning ("VCL<%d>: configured segment_baseva 0x%lx",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002079 getpid (), vcl_cfg->segment_baseva);
Dave Wallace543852a2017-08-03 02:11:34 -04002080 }
2081 else if (unformat (line_input, "segment-size 0x%lx",
2082 &vcl_cfg->segment_size))
2083 {
2084 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002085 clib_warning ("VCL<%d>: configured segment_size 0x%lx (%ld)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002086 getpid (), vcl_cfg->segment_size,
Dave Wallace543852a2017-08-03 02:11:34 -04002087 vcl_cfg->segment_size);
2088 }
2089 else if (unformat (line_input, "segment-size %ld",
2090 &vcl_cfg->segment_size))
2091 {
2092 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002093 clib_warning ("VCL<%d>: configured segment_size %ld (0x%lx)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002094 getpid (), vcl_cfg->segment_size,
Dave Wallace543852a2017-08-03 02:11:34 -04002095 vcl_cfg->segment_size);
2096 }
2097 else if (unformat (line_input, "add-segment-size 0x%lx",
2098 &vcl_cfg->add_segment_size))
2099 {
2100 if (VPPCOM_DEBUG > 0)
2101 clib_warning
Dave Wallace048b1d62018-01-03 22:24:41 -05002102 ("VCL<%d>: configured add_segment_size 0x%lx (%ld)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002103 getpid (), vcl_cfg->add_segment_size,
Dave Wallace543852a2017-08-03 02:11:34 -04002104 vcl_cfg->add_segment_size);
2105 }
2106 else if (unformat (line_input, "add-segment-size %ld",
2107 &vcl_cfg->add_segment_size))
2108 {
2109 if (VPPCOM_DEBUG > 0)
2110 clib_warning
Dave Wallace048b1d62018-01-03 22:24:41 -05002111 ("VCL<%d>: configured add_segment_size %ld (0x%lx)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002112 getpid (), vcl_cfg->add_segment_size,
Dave Wallace543852a2017-08-03 02:11:34 -04002113 vcl_cfg->add_segment_size);
2114 }
2115 else if (unformat (line_input, "preallocated-fifo-pairs %d",
2116 &vcl_cfg->preallocated_fifo_pairs))
2117 {
2118 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002119 clib_warning ("VCL<%d>: configured preallocated_fifo_pairs "
Dave Wallace2e005bb2017-11-07 01:21:39 -05002120 "%d (0x%x)", getpid (),
Dave Wallace543852a2017-08-03 02:11:34 -04002121 vcl_cfg->preallocated_fifo_pairs,
2122 vcl_cfg->preallocated_fifo_pairs);
2123 }
2124 else if (unformat (line_input, "rx-fifo-size 0x%lx",
2125 &vcl_cfg->rx_fifo_size))
2126 {
2127 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002128 clib_warning ("VCL<%d>: configured rx_fifo_size 0x%lx (%ld)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002129 getpid (), vcl_cfg->rx_fifo_size,
Dave Wallace543852a2017-08-03 02:11:34 -04002130 vcl_cfg->rx_fifo_size);
2131 }
2132 else if (unformat (line_input, "rx-fifo-size %ld",
2133 &vcl_cfg->rx_fifo_size))
2134 {
2135 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002136 clib_warning ("VCL<%d>: configured rx_fifo_size %ld (0x%lx)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002137 getpid (), vcl_cfg->rx_fifo_size,
Dave Wallace543852a2017-08-03 02:11:34 -04002138 vcl_cfg->rx_fifo_size);
2139 }
2140 else if (unformat (line_input, "tx-fifo-size 0x%lx",
2141 &vcl_cfg->tx_fifo_size))
2142 {
2143 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002144 clib_warning ("VCL<%d>: configured tx_fifo_size 0x%lx (%ld)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002145 getpid (), vcl_cfg->tx_fifo_size,
Dave Wallace543852a2017-08-03 02:11:34 -04002146 vcl_cfg->tx_fifo_size);
2147 }
2148 else if (unformat (line_input, "tx-fifo-size %ld",
2149 &vcl_cfg->tx_fifo_size))
2150 {
2151 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002152 clib_warning ("VCL<%d>: configured tx_fifo_size %ld (0x%lx)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002153 getpid (), vcl_cfg->tx_fifo_size,
Dave Wallace543852a2017-08-03 02:11:34 -04002154 vcl_cfg->tx_fifo_size);
2155 }
2156 else if (unformat (line_input, "event-queue-size 0x%lx",
2157 &vcl_cfg->event_queue_size))
2158 {
2159 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002160 clib_warning ("VCL<%d>: configured event_queue_size "
2161 "0x%lx (%ld)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002162 getpid (), vcl_cfg->event_queue_size,
Dave Wallace543852a2017-08-03 02:11:34 -04002163 vcl_cfg->event_queue_size);
2164 }
2165 else if (unformat (line_input, "event-queue-size %ld",
2166 &vcl_cfg->event_queue_size))
2167 {
2168 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002169 clib_warning ("VCL<%d>: configured event_queue_size "
2170 "%ld (0x%lx)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002171 getpid (), vcl_cfg->event_queue_size,
Dave Wallace543852a2017-08-03 02:11:34 -04002172 vcl_cfg->event_queue_size);
2173 }
2174 else if (unformat (line_input, "listen-queue-size 0x%lx",
2175 &vcl_cfg->listen_queue_size))
2176 {
2177 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002178 clib_warning ("VCL<%d>: configured listen_queue_size "
2179 "0x%lx (%ld)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002180 getpid (), vcl_cfg->listen_queue_size,
Dave Wallace543852a2017-08-03 02:11:34 -04002181 vcl_cfg->listen_queue_size);
2182 }
2183 else if (unformat (line_input, "listen-queue-size %ld",
2184 &vcl_cfg->listen_queue_size))
2185 {
2186 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002187 clib_warning ("VCL<%d>: configured listen_queue_size "
2188 "%ld (0x%lx)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002189 getpid (), vcl_cfg->listen_queue_size,
Dave Wallace543852a2017-08-03 02:11:34 -04002190 vcl_cfg->listen_queue_size);
2191 }
2192 else if (unformat (line_input, "app-timeout %f",
2193 &vcl_cfg->app_timeout))
2194 {
2195 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002196 clib_warning ("VCL<%d>: configured app_timeout %f",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002197 getpid (), vcl_cfg->app_timeout);
Dave Wallace543852a2017-08-03 02:11:34 -04002198 }
2199 else if (unformat (line_input, "session-timeout %f",
2200 &vcl_cfg->session_timeout))
2201 {
2202 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002203 clib_warning ("VCL<%d>: configured session_timeout %f",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002204 getpid (), vcl_cfg->session_timeout);
Dave Wallace543852a2017-08-03 02:11:34 -04002205 }
2206 else if (unformat (line_input, "accept-timeout %f",
2207 &vcl_cfg->accept_timeout))
2208 {
2209 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002210 clib_warning ("VCL<%d>: configured accept_timeout %f",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002211 getpid (), vcl_cfg->accept_timeout);
Dave Wallace543852a2017-08-03 02:11:34 -04002212 }
Dave Wallace774169b2017-11-01 20:07:40 -04002213 else if (unformat (line_input, "app-proxy-transport-tcp"))
Dave Wallace8af20542017-10-26 03:29:30 -04002214 {
Dave Wallace774169b2017-11-01 20:07:40 -04002215 vcl_cfg->app_proxy_transport_tcp = 1;
Dave Wallace8af20542017-10-26 03:29:30 -04002216 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002217 clib_warning ("VCL<%d>: configured "
2218 "app_proxy_transport_tcp (%d)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002219 getpid (), vcl_cfg->app_proxy_transport_tcp);
Dave Wallace8af20542017-10-26 03:29:30 -04002220 }
Dave Wallace774169b2017-11-01 20:07:40 -04002221 else if (unformat (line_input, "app-proxy-transport-udp"))
Dave Wallace8af20542017-10-26 03:29:30 -04002222 {
Dave Wallace774169b2017-11-01 20:07:40 -04002223 vcl_cfg->app_proxy_transport_udp = 1;
Dave Wallace8af20542017-10-26 03:29:30 -04002224 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002225 clib_warning ("VCL<%d>: configured "
2226 "app_proxy_transport_udp (%d)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002227 getpid (), vcl_cfg->app_proxy_transport_udp);
Dave Wallace8af20542017-10-26 03:29:30 -04002228 }
Dave Wallace774169b2017-11-01 20:07:40 -04002229 else if (unformat (line_input, "app-scope-local"))
Dave Wallace8af20542017-10-26 03:29:30 -04002230 {
Dave Wallace774169b2017-11-01 20:07:40 -04002231 vcl_cfg->app_scope_local = 1;
Dave Wallace8af20542017-10-26 03:29:30 -04002232 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002233 clib_warning ("VCL<%d>: configured app_scope_local (%d)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002234 getpid (), vcl_cfg->app_scope_local);
Dave Wallace774169b2017-11-01 20:07:40 -04002235 }
2236 else if (unformat (line_input, "app-scope-global"))
2237 {
2238 vcl_cfg->app_scope_global = 1;
2239 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002240 clib_warning ("VCL<%d>: configured app_scope_global (%d)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002241 getpid (), vcl_cfg->app_scope_global);
Dave Wallace8af20542017-10-26 03:29:30 -04002242 }
2243 else if (unformat (line_input, "namespace-secret %lu",
2244 &vcl_cfg->namespace_secret))
2245 {
2246 if (VPPCOM_DEBUG > 0)
2247 clib_warning
Dave Wallace048b1d62018-01-03 22:24:41 -05002248 ("VCL<%d>: configured namespace_secret %lu (0x%lx)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002249 getpid (), vcl_cfg->namespace_secret,
Dave Wallace8af20542017-10-26 03:29:30 -04002250 vcl_cfg->namespace_secret);
2251 }
2252 else if (unformat (line_input, "namespace-id %v",
2253 &vcl_cfg->namespace_id))
2254 {
2255 vl_api_application_attach_t *mp;
2256 u32 max_nsid_vec_len = sizeof (mp->namespace_id) - 1;
2257 u32 nsid_vec_len = vec_len (vcl_cfg->namespace_id);
2258 if (nsid_vec_len > max_nsid_vec_len)
2259 {
2260 _vec_len (vcl_cfg->namespace_id) = max_nsid_vec_len;
2261 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002262 clib_warning ("VCL<%d>: configured namespace_id is "
2263 "too long, truncated to %d characters!",
2264 getpid (), max_nsid_vec_len);
Dave Wallace8af20542017-10-26 03:29:30 -04002265 }
2266
2267 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002268 clib_warning ("VCL<%d>: configured namespace_id %v",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002269 getpid (), vcl_cfg->namespace_id);
Dave Wallace8af20542017-10-26 03:29:30 -04002270 }
Dave Wallace543852a2017-08-03 02:11:34 -04002271 else if (unformat (line_input, "}"))
2272 {
2273 vc_cfg_input = 0;
2274 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002275 clib_warning ("VCL<%d>: completed parsing vppcom config!",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002276 getpid ());
Dave Wallace543852a2017-08-03 02:11:34 -04002277 goto input_done;
2278 }
2279 else
2280 {
2281 if (line_input->buffer[line_input->index] != '#')
2282 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002283 clib_warning ("VCL<%d>: Unknown vppcom config option: '%s'",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002284 getpid (), (char *)
Dave Wallace543852a2017-08-03 02:11:34 -04002285 &line_input->buffer[line_input->index]);
2286 }
2287 }
2288 }
2289 }
2290
2291input_done:
2292 unformat_free (input);
2293
2294file_done:
Chris Lukeab7b8d92017-09-07 07:40:13 -04002295 if (fd >= 0)
Dave Wallace543852a2017-08-03 02:11:34 -04002296 close (fd);
2297}
2298
2299/*
2300 * VPPCOM Public API functions
2301 */
2302int
2303vppcom_app_create (char *app_name)
2304{
Dave Wallace543852a2017-08-03 02:11:34 -04002305 vppcom_cfg_t *vcl_cfg = &vcm->cfg;
2306 u8 *heap;
2307 mheap_t *h;
2308 int rv;
2309
2310 if (!vcm->init)
2311 {
2312 char *conf_fname;
Dave Wallace8af20542017-10-26 03:29:30 -04002313 char *env_var_str;
Dave Wallace543852a2017-08-03 02:11:34 -04002314
2315 vcm->init = 1;
Dave Wallace543852a2017-08-03 02:11:34 -04002316 vppcom_cfg_init (vcl_cfg);
Dave Wallace498b3a52017-11-09 13:00:34 -05002317 env_var_str = getenv (VPPCOM_ENV_DEBUG);
2318 if (env_var_str)
2319 {
2320 u32 tmp;
2321 if (sscanf (env_var_str, "%u", &tmp) != 1)
Dave Wallace69d01192018-02-22 16:22:09 -05002322 clib_warning ("VCL<%d>: WARNING: Invalid debug level specified "
2323 "in the environment variable " VPPCOM_ENV_DEBUG
Dave Wallace498b3a52017-11-09 13:00:34 -05002324 " (%s)!\n", getpid (), env_var_str);
2325 else
2326 {
2327 vcm->debug = tmp;
Dave Wallace69d01192018-02-22 16:22:09 -05002328 if (VPPCOM_DEBUG > 0)
2329 clib_warning ("VCL<%d>: configured VCL debug level (%u) from "
2330 VPPCOM_ENV_DEBUG "!", getpid (), vcm->debug);
Dave Wallace498b3a52017-11-09 13:00:34 -05002331 }
2332 }
Dave Wallace8af20542017-10-26 03:29:30 -04002333 conf_fname = getenv (VPPCOM_ENV_CONF);
Dave Wallace543852a2017-08-03 02:11:34 -04002334 if (!conf_fname)
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05002335 conf_fname = VPPCOM_CONF_DEFAULT;
Dave Wallace543852a2017-08-03 02:11:34 -04002336 vppcom_cfg_heapsize (conf_fname);
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05002337 vcl_cfg = &vcm->cfg;
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08002338 clib_spinlock_init (&vcm->session_fifo_lockp);
Dave Wallace2e005bb2017-11-07 01:21:39 -05002339 clib_fifo_validate (vcm->client_session_index_fifo,
2340 vcm->cfg.listen_queue_size);
Dave Wallace543852a2017-08-03 02:11:34 -04002341 vppcom_cfg_read (conf_fname);
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05002342
Keith Burns (alagalah)410bcca2018-03-23 13:42:49 -07002343
Dave Wallaceb5a86ee2018-02-16 18:26:11 -05002344 env_var_str = getenv (VPPCOM_ENV_API_PREFIX);
2345 if (env_var_str)
2346 {
2347 if (vcl_cfg->vpp_api_filename)
2348 vec_free (vcl_cfg->vpp_api_filename);
2349 vcl_cfg->vpp_api_filename = format (0, "/%s-vpe-api%c",
2350 env_var_str, 0);
2351 vl_set_memory_root_path ((char *) env_var_str);
2352
2353 if (VPPCOM_DEBUG > 0)
2354 clib_warning ("VCL<%d>: configured api prefix (%s) and "
2355 "filename (%s) from " VPPCOM_ENV_API_PREFIX "!",
2356 getpid (), env_var_str, vcl_cfg->vpp_api_filename);
2357 }
Dave Wallace8af20542017-10-26 03:29:30 -04002358 env_var_str = getenv (VPPCOM_ENV_APP_NAMESPACE_ID);
2359 if (env_var_str)
2360 {
2361 u32 ns_id_vec_len = strlen (env_var_str);
2362
2363 vec_reset_length (vcm->cfg.namespace_id);
2364 vec_validate (vcm->cfg.namespace_id, ns_id_vec_len - 1);
2365 clib_memcpy (vcm->cfg.namespace_id, env_var_str, ns_id_vec_len);
2366
2367 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002368 clib_warning ("VCL<%d>: configured namespace_id (%v) from "
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08002369 VPPCOM_ENV_APP_NAMESPACE_ID
2370 "!", getpid (), vcm->cfg.namespace_id);
Dave Wallace8af20542017-10-26 03:29:30 -04002371 }
2372 env_var_str = getenv (VPPCOM_ENV_APP_NAMESPACE_SECRET);
2373 if (env_var_str)
2374 {
2375 u64 tmp;
2376 if (sscanf (env_var_str, "%lu", &tmp) != 1)
Dave Wallace69d01192018-02-22 16:22:09 -05002377 clib_warning ("VCL<%d>: WARNING: Invalid namespace secret "
2378 "specified in the environment variable "
Dave Wallace8af20542017-10-26 03:29:30 -04002379 VPPCOM_ENV_APP_NAMESPACE_SECRET
Dave Wallace2e005bb2017-11-07 01:21:39 -05002380 " (%s)!\n", getpid (), env_var_str);
Dave Wallace8af20542017-10-26 03:29:30 -04002381 else
2382 {
2383 vcm->cfg.namespace_secret = tmp;
2384 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002385 clib_warning ("VCL<%d>: configured namespace secret "
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08002386 "(%lu) from "
Dave Wallace9a0546d2018-03-08 11:40:28 -05002387 VPPCOM_ENV_APP_NAMESPACE_SECRET
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08002388 "!", getpid (), vcm->cfg.namespace_secret);
Dave Wallace8af20542017-10-26 03:29:30 -04002389 }
2390 }
Dave Wallace774169b2017-11-01 20:07:40 -04002391 if (getenv (VPPCOM_ENV_APP_PROXY_TRANSPORT_TCP))
Dave Wallace8af20542017-10-26 03:29:30 -04002392 {
Dave Wallace774169b2017-11-01 20:07:40 -04002393 vcm->cfg.app_proxy_transport_tcp = 1;
Dave Wallace8af20542017-10-26 03:29:30 -04002394 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002395 clib_warning ("VCL<%d>: configured app_proxy_transport_tcp "
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08002396 "(%u) from "
2397 VPPCOM_ENV_APP_PROXY_TRANSPORT_TCP
Dave Wallace048b1d62018-01-03 22:24:41 -05002398 "!", getpid (), vcm->cfg.app_proxy_transport_tcp);
Dave Wallace8af20542017-10-26 03:29:30 -04002399 }
Dave Wallace774169b2017-11-01 20:07:40 -04002400 if (getenv (VPPCOM_ENV_APP_PROXY_TRANSPORT_UDP))
Dave Wallace8af20542017-10-26 03:29:30 -04002401 {
Dave Wallace774169b2017-11-01 20:07:40 -04002402 vcm->cfg.app_proxy_transport_udp = 1;
Dave Wallace8af20542017-10-26 03:29:30 -04002403 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002404 clib_warning ("VCL<%d>: configured app_proxy_transport_udp "
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08002405 "(%u) from "
2406 VPPCOM_ENV_APP_PROXY_TRANSPORT_UDP
Dave Wallace048b1d62018-01-03 22:24:41 -05002407 "!", getpid (), vcm->cfg.app_proxy_transport_udp);
Dave Wallace774169b2017-11-01 20:07:40 -04002408 }
2409 if (getenv (VPPCOM_ENV_APP_SCOPE_LOCAL))
2410 {
2411 vcm->cfg.app_scope_local = 1;
2412 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002413 clib_warning ("VCL<%d>: configured app_scope_local (%u) from "
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08002414 VPPCOM_ENV_APP_SCOPE_LOCAL
2415 "!", getpid (), vcm->cfg.app_scope_local);
Dave Wallace774169b2017-11-01 20:07:40 -04002416 }
2417 if (getenv (VPPCOM_ENV_APP_SCOPE_GLOBAL))
2418 {
2419 vcm->cfg.app_scope_global = 1;
2420 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002421 clib_warning ("VCL<%d>: configured app_scope_global (%u) from "
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08002422 VPPCOM_ENV_APP_SCOPE_GLOBAL
2423 "!", getpid (), vcm->cfg.app_scope_global);
Dave Wallace8af20542017-10-26 03:29:30 -04002424 }
2425
Dave Wallace543852a2017-08-03 02:11:34 -04002426 vcm->main_cpu = os_get_thread_index ();
2427 heap = clib_mem_get_per_cpu_heap ();
2428 h = mheap_header (heap);
2429
2430 /* make the main heap thread-safe */
2431 h->flags |= MHEAP_FLAG_THREAD_SAFE;
2432
2433 vcm->session_index_by_vpp_handles = hash_create (0, sizeof (uword));
2434
2435 clib_time_init (&vcm->clib_time);
2436 vppcom_init_error_string_table ();
Florin Corasa332c462018-01-31 06:52:17 -08002437 svm_fifo_segment_main_init (vcl_cfg->segment_baseva,
2438 20 /* timeout in secs */ );
Dave Wallace543852a2017-08-03 02:11:34 -04002439 clib_spinlock_init (&vcm->sessions_lockp);
Dave Wallace543852a2017-08-03 02:11:34 -04002440 }
2441
2442 if (vcm->my_client_index == ~0)
2443 {
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002444
2445 /* API hookup and connect to VPP */
Dave Wallace048b1d62018-01-03 22:24:41 -05002446 vppcom_api_hookup ();
Dave Wallace543852a2017-08-03 02:11:34 -04002447 vcm->app_state = STATE_APP_START;
2448 rv = vppcom_connect_to_vpp (app_name);
2449 if (rv)
2450 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002451 clib_warning ("VCL<%d>: ERROR: couldn't connect to VPP!",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002452 getpid ());
Dave Wallace543852a2017-08-03 02:11:34 -04002453 return rv;
2454 }
2455
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002456 /* State event handling thread */
2457
2458 rv = vce_start_event_thread (&(vcm->event_thread), 20);
2459
Dave Wallace543852a2017-08-03 02:11:34 -04002460 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002461 clib_warning ("VCL<%d>: sending session enable", getpid ());
Dave Wallace543852a2017-08-03 02:11:34 -04002462
Dave Wallace048b1d62018-01-03 22:24:41 -05002463 rv = vppcom_app_session_enable ();
Dave Wallace543852a2017-08-03 02:11:34 -04002464 if (rv)
2465 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002466 clib_warning ("VCL<%d>: ERROR: vppcom_app_session_enable() "
2467 "failed!", getpid ());
Dave Wallace543852a2017-08-03 02:11:34 -04002468 return rv;
2469 }
Dave Wallace543852a2017-08-03 02:11:34 -04002470
Dave Wallace66cf6eb2017-10-26 02:51:07 -04002471 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002472 clib_warning ("VCL<%d>: sending app attach", getpid ());
2473
2474 rv = vppcom_app_attach ();
2475 if (rv)
2476 {
2477 clib_warning ("VCL<%d>: ERROR: vppcom_app_attach() failed!",
2478 getpid ());
2479 return rv;
2480 }
2481
2482 if (VPPCOM_DEBUG > 0)
2483 clib_warning ("VCL<%d>: app_name '%s', my_client_index %d (0x%x)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002484 getpid (), app_name, vcm->my_client_index,
Dave Wallace66cf6eb2017-10-26 02:51:07 -04002485 vcm->my_client_index);
2486 }
Dave Wallace543852a2017-08-03 02:11:34 -04002487
2488 return VPPCOM_OK;
2489}
2490
2491void
2492vppcom_app_destroy (void)
2493{
Dave Wallace543852a2017-08-03 02:11:34 -04002494 int rv;
Dave Wallacede910062018-03-20 09:22:13 -04002495 f64 orig_app_timeout;
Dave Wallace543852a2017-08-03 02:11:34 -04002496
2497 if (vcm->my_client_index == ~0)
2498 return;
2499
2500 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002501 clib_warning ("VCL<%d>: detaching from VPP, my_client_index %d (0x%x)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002502 getpid (), vcm->my_client_index, vcm->my_client_index);
Dave Wallace543852a2017-08-03 02:11:34 -04002503
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -08002504 if (VPPCOM_DEBUG > 0)
2505 {
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002506 /* *INDENT-OFF* */
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -08002507 ELOG_TYPE_DECLARE (e) =
2508 {
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002509 .format = "app_detach:C:%d",
2510 .format_args = "i4",
2511 };
2512
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -08002513 struct
2514 {
2515 u32 data;
2516 } *ed;
2517 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, vcm->elog_track);
2518 ed->data = vcm->my_client_index;
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002519 /* *INDENT-ON* */
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -08002520 }
2521
Dave Wallace543852a2017-08-03 02:11:34 -04002522 vppcom_app_detach ();
Dave Wallacede910062018-03-20 09:22:13 -04002523 orig_app_timeout = vcm->cfg.app_timeout;
2524 vcm->cfg.app_timeout = 2.0;
Dave Wallace543852a2017-08-03 02:11:34 -04002525 rv = vppcom_wait_for_app_state_change (STATE_APP_ENABLED);
Dave Wallacede910062018-03-20 09:22:13 -04002526 vcm->cfg.app_timeout = orig_app_timeout;
Dave Wallace543852a2017-08-03 02:11:34 -04002527 if (PREDICT_FALSE (rv))
2528 {
2529 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002530 clib_warning ("VCL<%d>: application detach timed out! "
2531 "returning %d (%s)",
Dave Wallaceee45d412017-11-24 21:44:06 -05002532 getpid (), rv, vppcom_retval_str (rv));
Dave Wallace543852a2017-08-03 02:11:34 -04002533 }
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -08002534
2535 /* Finished with logging before client gets reset to ~0 */
2536 if (VPPCOM_DEBUG > 0)
2537 write_elog ();
2538
Dave Wallace543852a2017-08-03 02:11:34 -04002539 vl_client_disconnect_from_vlib ();
2540 vcm->my_client_index = ~0;
2541 vcm->app_state = STATE_APP_START;
2542}
2543
2544int
Dave Wallacec04cbf12018-02-07 18:14:02 -05002545vppcom_session_create (u8 proto, u8 is_nonblocking)
Dave Wallace543852a2017-08-03 02:11:34 -04002546{
Dave Wallace543852a2017-08-03 02:11:34 -04002547 session_t *session;
2548 u32 session_index;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002549 session_state_t state;
2550 elog_track_t session_elog_track;
Dave Wallace543852a2017-08-03 02:11:34 -04002551
2552 clib_spinlock_lock (&vcm->sessions_lockp);
2553 pool_get (vcm->sessions, session);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002554 memset (session, 0, sizeof (*session));
Dave Wallace543852a2017-08-03 02:11:34 -04002555 session_index = session - vcm->sessions;
2556
Dave Wallace543852a2017-08-03 02:11:34 -04002557 session->proto = proto;
2558 session->state = STATE_START;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002559 state = session->state;
Dave Wallace4878cbe2017-11-21 03:45:09 -05002560 session->vpp_handle = ~0;
Dave Wallace543852a2017-08-03 02:11:34 -04002561
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002562 if (is_nonblocking)
2563 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_NONBLOCK);
2564 else
2565 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_NONBLOCK);
Dave Wallace543852a2017-08-03 02:11:34 -04002566
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002567 if (VPPCOM_DEBUG > 0)
2568 {
2569 session->elog_track.name =
2570 (char *) format (0, "C:%d:S:%d%c", vcm->my_client_index,
2571 session_index, 0);
2572 elog_track_register (&vcm->elog_main, &session->elog_track);
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002573 session_elog_track = session->elog_track;
2574 }
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002575
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002576 clib_spinlock_unlock (&vcm->sessions_lockp);
2577
2578 if (VPPCOM_DEBUG > 0)
2579 clib_warning ("VCL<%d>: sid %u", getpid (), session_index);
2580
2581 if (VPPCOM_DEBUG > 0)
2582 {
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002583 /* *INDENT-OFF* */
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002584 ELOG_TYPE_DECLARE (e) =
2585 {
Dave Wallacec04cbf12018-02-07 18:14:02 -05002586 .format = "session_create:proto:%d state:%d is_nonblocking:%d",
2587 .format_args = "i4i4i4",
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002588 };
2589
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002590 struct
2591 {
Dave Wallacec04cbf12018-02-07 18:14:02 -05002592 u32 data[3];
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002593 } *ed;
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002594
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002595 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session_elog_track);
2596 ed->data[0] = proto;
2597 ed->data[1] = state;
2598 ed->data[2] = is_nonblocking;
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002599 /* *INDENT-ON* */
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002600 }
2601
Dave Wallace543852a2017-08-03 02:11:34 -04002602 return (int) session_index;
2603}
2604
2605int
2606vppcom_session_close (uint32_t session_index)
2607{
Dave Wallace543852a2017-08-03 02:11:34 -04002608 session_t *session = 0;
2609 int rv;
Dave Wallace66cf6eb2017-10-26 02:51:07 -04002610 u8 is_vep;
2611 u8 is_vep_session;
2612 u32 next_sid;
2613 u32 vep_idx;
Dave Wallaceee45d412017-11-24 21:44:06 -05002614 u64 vpp_handle;
Dave Wallace4878cbe2017-11-21 03:45:09 -05002615 uword *p;
Dave Wallace66cf6eb2017-10-26 02:51:07 -04002616 session_state_t state;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002617 elog_track_t session_elog_track;
Dave Wallace543852a2017-08-03 02:11:34 -04002618
Dave Wallace4878cbe2017-11-21 03:45:09 -05002619 VCL_LOCK_AND_GET_SESSION (session_index, &session);
Dave Wallace66cf6eb2017-10-26 02:51:07 -04002620 is_vep = session->is_vep;
2621 is_vep_session = session->is_vep_session;
2622 next_sid = session->vep.next_sid;
2623 vep_idx = session->vep.vep_idx;
2624 state = session->state;
Dave Wallaceee45d412017-11-24 21:44:06 -05002625 vpp_handle = session->vpp_handle;
Dave Wallace543852a2017-08-03 02:11:34 -04002626 clib_spinlock_unlock (&vcm->sessions_lockp);
2627
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002628 /*
2629 * Why two if(VPPCOM_DEBUG) checks?
2630 *
2631 * Eventually all clib_warnings need their own way of being
2632 * logged and signalled (like severity) where event logging
2633 * is a separate debugging tool. It will make the separation
2634 * easier. ... parting is such sweet sorrow ...
2635 */
2636 if (VPPCOM_DEBUG > 0)
2637 {
2638 session_elog_track = session->elog_track;
2639 }
2640
Dave Wallace543852a2017-08-03 02:11:34 -04002641 if (VPPCOM_DEBUG > 0)
Dave Wallaceee45d412017-11-24 21:44:06 -05002642 {
2643 if (is_vep)
Dave Wallace048b1d62018-01-03 22:24:41 -05002644 clib_warning ("VCL<%d>: vep_idx %u / sid %u: "
2645 "closing epoll session...",
Dave Wallaceee45d412017-11-24 21:44:06 -05002646 getpid (), session_index, session_index);
2647 else
Dave Wallace048b1d62018-01-03 22:24:41 -05002648 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %d: "
2649 "closing session...",
Dave Wallaceee45d412017-11-24 21:44:06 -05002650 getpid (), vpp_handle, session_index);
2651 }
Dave Wallace543852a2017-08-03 02:11:34 -04002652
Dave Wallace66cf6eb2017-10-26 02:51:07 -04002653 if (is_vep)
Dave Wallace543852a2017-08-03 02:11:34 -04002654 {
Dave Wallace66cf6eb2017-10-26 02:51:07 -04002655 while (next_sid != ~0)
Dave Wallace19481612017-09-15 18:47:44 -04002656 {
Dave Wallacef7f809c2017-10-03 01:48:42 -04002657 rv = vppcom_epoll_ctl (session_index, EPOLL_CTL_DEL, next_sid, 0);
Dave Wallaceee45d412017-11-24 21:44:06 -05002658 if ((VPPCOM_DEBUG > 0) && PREDICT_FALSE (rv < 0))
Dave Wallace048b1d62018-01-03 22:24:41 -05002659 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
2660 "EPOLL_CTL_DEL vep_idx %u failed! rv %d (%s)",
2661 getpid (), vpp_handle, next_sid, vep_idx,
Dave Wallace4878cbe2017-11-21 03:45:09 -05002662 rv, vppcom_retval_str (rv));
Dave Wallacef7f809c2017-10-03 01:48:42 -04002663
Dave Wallace4878cbe2017-11-21 03:45:09 -05002664 VCL_LOCK_AND_GET_SESSION (session_index, &session);
Dave Wallace66cf6eb2017-10-26 02:51:07 -04002665 next_sid = session->vep.next_sid;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002666 clib_spinlock_unlock (&vcm->sessions_lockp);
2667 }
2668 }
2669 else
2670 {
Dave Wallace66cf6eb2017-10-26 02:51:07 -04002671 if (is_vep_session)
Dave Wallacef7f809c2017-10-03 01:48:42 -04002672 {
Dave Wallacef7f809c2017-10-03 01:48:42 -04002673 rv = vppcom_epoll_ctl (vep_idx, EPOLL_CTL_DEL, session_index, 0);
2674 if ((VPPCOM_DEBUG > 0) && (rv < 0))
Dave Wallace048b1d62018-01-03 22:24:41 -05002675 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
2676 "EPOLL_CTL_DEL vep_idx %u failed! rv %d (%s)",
Dave Wallaceee45d412017-11-24 21:44:06 -05002677 getpid (), vpp_handle, session_index,
2678 vep_idx, rv, vppcom_retval_str (rv));
Dave Wallacef7f809c2017-10-03 01:48:42 -04002679 }
2680
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002681 if (state & STATE_LISTEN)
Dave Wallacef7f809c2017-10-03 01:48:42 -04002682 {
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002683 rv = vppcom_session_unbind (session_index);
2684 if (PREDICT_FALSE (rv < 0))
Dave Wallace4878cbe2017-11-21 03:45:09 -05002685 {
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002686 if (VPPCOM_DEBUG > 0)
2687 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
2688 "listener unbind failed! rv %d (%s)",
2689 getpid (), vpp_handle, session_index,
2690 rv, vppcom_retval_str (rv));
Dave Wallace4878cbe2017-11-21 03:45:09 -05002691 }
Dave Wallacef7f809c2017-10-03 01:48:42 -04002692 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05002693
2694 else if (state & (CLIENT_STATE_OPEN | SERVER_STATE_OPEN))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002695 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05002696 rv = vppcom_session_disconnect (session_index);
2697 if (PREDICT_FALSE (rv < 0))
Dave Wallace048b1d62018-01-03 22:24:41 -05002698 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -05002699 "session disconnect failed! rv %d (%s)",
2700 getpid (), vpp_handle, session_index,
2701 rv, vppcom_retval_str (rv));
Dave Wallacef7f809c2017-10-03 01:48:42 -04002702 }
Dave Wallace19481612017-09-15 18:47:44 -04002703 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05002704
2705 VCL_LOCK_AND_GET_SESSION (session_index, &session);
Dave Wallaceee45d412017-11-24 21:44:06 -05002706 vpp_handle = session->vpp_handle;
2707 if (vpp_handle != ~0)
Dave Wallace4878cbe2017-11-21 03:45:09 -05002708 {
Dave Wallaceee45d412017-11-24 21:44:06 -05002709 p = hash_get (vcm->session_index_by_vpp_handles, vpp_handle);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002710 if (p)
Dave Wallaceee45d412017-11-24 21:44:06 -05002711 hash_unset (vcm->session_index_by_vpp_handles, vpp_handle);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002712 }
Dave Wallace543852a2017-08-03 02:11:34 -04002713 pool_put_index (vcm->sessions, session_index);
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002714
Dave Wallace66cf6eb2017-10-26 02:51:07 -04002715 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002716
2717 if (VPPCOM_DEBUG > 0)
Dave Wallaceee45d412017-11-24 21:44:06 -05002718 {
2719 if (is_vep)
Dave Wallace048b1d62018-01-03 22:24:41 -05002720 clib_warning ("VCL<%d>: vep_idx %u / sid %u: epoll session removed.",
Dave Wallaceee45d412017-11-24 21:44:06 -05002721 getpid (), session_index, session_index);
2722 else
Dave Wallace048b1d62018-01-03 22:24:41 -05002723 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: session removed.",
Dave Wallaceee45d412017-11-24 21:44:06 -05002724 getpid (), vpp_handle, session_index);
2725 }
Dave Wallacef7f809c2017-10-03 01:48:42 -04002726done:
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002727
2728 if (VPPCOM_DEBUG > 0)
2729 {
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002730 /* *INDENT-OFF* */
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002731 ELOG_TYPE_DECLARE (e) =
2732 {
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002733 .format = "session_close:rv:%d",
2734 .format_args = "i4",
2735 };
2736
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002737 struct
2738 {
2739 u32 data;
2740 } *ed;
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002741
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002742 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session_elog_track);
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002743 ed->data = rv;
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002744 /* *INDENT-ON* */
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002745 }
2746
Dave Wallace543852a2017-08-03 02:11:34 -04002747 return rv;
2748}
2749
2750int
2751vppcom_session_bind (uint32_t session_index, vppcom_endpt_t * ep)
2752{
Dave Wallace543852a2017-08-03 02:11:34 -04002753 session_t *session = 0;
2754 int rv;
2755
2756 if (!ep || !ep->ip)
2757 return VPPCOM_EINVAL;
2758
Dave Wallace4878cbe2017-11-21 03:45:09 -05002759 VCL_LOCK_AND_GET_SESSION (session_index, &session);
Dave Wallace543852a2017-08-03 02:11:34 -04002760
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002761 if (session->is_vep)
2762 {
2763 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace048b1d62018-01-03 22:24:41 -05002764 clib_warning ("VCL<%d>: ERROR: sid %u: cannot "
2765 "bind to an epoll session!", getpid (), session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002766 rv = VPPCOM_EBADFD;
2767 goto done;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002768 }
2769
Dave Wallace35830af2017-10-09 01:43:42 -04002770 session->lcl_addr.is_ip4 = ep->is_ip4;
2771 session->lcl_addr.ip46 = to_ip46 (!ep->is_ip4, ep->ip);
Stevenac1f96d2017-10-24 16:03:58 -07002772 session->lcl_port = ep->port;
2773
2774 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002775 clib_warning ("VCL<%d>: sid %u: binding to local %s address %U "
Dave Wallaceee45d412017-11-24 21:44:06 -05002776 "port %u, proto %s", getpid (), session_index,
2777 session->lcl_addr.is_ip4 ? "IPv4" : "IPv6",
2778 format_ip46_address, &session->lcl_addr.ip46,
Dave Wallacede910062018-03-20 09:22:13 -04002779 session->lcl_addr.is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6,
Dave Wallace4878cbe2017-11-21 03:45:09 -05002780 clib_net_to_host_u16 (session->lcl_port),
2781 session->proto ? "UDP" : "TCP");
Dave Wallace543852a2017-08-03 02:11:34 -04002782
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002783 if (VPPCOM_DEBUG > 0)
2784 {
2785 if (session->lcl_addr.is_ip4)
2786 {
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002787 /* *INDENT-OFF* */
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002788 ELOG_TYPE_DECLARE (e) =
2789 {
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002790 .format = "bind local:%s:%d.%d.%d.%d:%d ",
2791 .format_args = "t1i1i1i1i1i2",
2792 .n_enum_strings = 2,
2793 .enum_strings = {"TCP", "UDP",},
2794 };
2795
2796 CLIB_PACKED (struct {
2797 u8 proto;
2798 u8 addr[4];
2799 u16 port;
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002800 }) *ed;
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002801
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002802 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
2803 ed->proto = session->proto;
2804 ed->addr[0] = session->lcl_addr.ip46.ip4.as_u8[0];
2805 ed->addr[1] = session->lcl_addr.ip46.ip4.as_u8[1];
2806 ed->addr[2] = session->lcl_addr.ip46.ip4.as_u8[2];
2807 ed->addr[3] = session->lcl_addr.ip46.ip4.as_u8[3];
2808 ed->port = clib_net_to_host_u16 (session->lcl_port);
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08002809 /* *INDENT-ON* */
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002810 }
2811 }
2812
Dave Wallace543852a2017-08-03 02:11:34 -04002813 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002814done:
2815 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04002816}
2817
2818int
Dave Wallace33e002b2017-09-06 01:20:02 -04002819vppcom_session_listen (uint32_t listen_session_index, uint32_t q_len)
Dave Wallace543852a2017-08-03 02:11:34 -04002820{
Dave Wallace33e002b2017-09-06 01:20:02 -04002821 session_t *listen_session = 0;
Dave Wallaceee45d412017-11-24 21:44:06 -05002822 u64 listen_vpp_handle;
2823 int rv, retval;
Dave Wallace543852a2017-08-03 02:11:34 -04002824
Keith Burns (alagalah)aba98de2018-02-22 03:23:40 -08002825 if (q_len == 0 || q_len == ~0)
2826 q_len = vcm->cfg.listen_queue_size;
2827
Dave Wallace4878cbe2017-11-21 03:45:09 -05002828 VCL_LOCK_AND_GET_SESSION (listen_session_index, &listen_session);
Dave Wallace543852a2017-08-03 02:11:34 -04002829
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002830 if (listen_session->is_vep)
2831 {
2832 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace048b1d62018-01-03 22:24:41 -05002833 clib_warning ("VCL<%d>: ERROR: sid %u: cannot listen on an "
Dave Wallace4878cbe2017-11-21 03:45:09 -05002834 "epoll session!", getpid (), listen_session_index);
2835 rv = VPPCOM_EBADFD;
2836 goto done;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002837 }
2838
Dave Wallaceee45d412017-11-24 21:44:06 -05002839 listen_vpp_handle = listen_session->vpp_handle;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002840 if (listen_session->state & STATE_LISTEN)
Dave Wallacee695cb42017-11-02 22:04:42 -04002841 {
2842 clib_spinlock_unlock (&vcm->sessions_lockp);
2843 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002844 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -05002845 "already in listen state!",
2846 getpid (), listen_vpp_handle, listen_session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002847 rv = VPPCOM_OK;
2848 goto done;
Dave Wallacee695cb42017-11-02 22:04:42 -04002849 }
2850
Dave Wallace543852a2017-08-03 02:11:34 -04002851 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002852 clib_warning ("VCL<%d>: vpp handle 0x%llx, "
Keith Burns (alagalah)410bcca2018-03-23 13:42:49 -07002853 "sid %u: sending VPP bind+listen request...",
Dave Wallaceee45d412017-11-24 21:44:06 -05002854 getpid (), listen_vpp_handle, listen_session_index);
Dave Wallace543852a2017-08-03 02:11:34 -04002855
Dave Wallace4878cbe2017-11-21 03:45:09 -05002856 vppcom_send_bind_sock (listen_session, listen_session_index);
Dave Wallace543852a2017-08-03 02:11:34 -04002857 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallaceee45d412017-11-24 21:44:06 -05002858 retval =
Dave Wallace33e002b2017-09-06 01:20:02 -04002859 vppcom_wait_for_session_state_change (listen_session_index, STATE_LISTEN,
2860 vcm->cfg.session_timeout);
Dave Wallace543852a2017-08-03 02:11:34 -04002861
Dave Wallace4878cbe2017-11-21 03:45:09 -05002862 VCL_LOCK_AND_GET_SESSION (listen_session_index, &listen_session);
Dave Wallaceee45d412017-11-24 21:44:06 -05002863 if (PREDICT_FALSE (retval))
2864 {
2865 if (VPPCOM_DEBUG > 0)
Keith Burns (alagalah)410bcca2018-03-23 13:42:49 -07002866 clib_warning
2867 ("VCL<%d>: vpp handle 0x%llx, sid %u: bind+listen failed! "
2868 "returning %d (%s)", getpid (), listen_session->vpp_handle,
2869 listen_session_index, retval, vppcom_retval_str (retval));
Dave Wallaceee45d412017-11-24 21:44:06 -05002870 clib_spinlock_unlock (&vcm->sessions_lockp);
2871 rv = retval;
2872 goto done;
2873 }
2874
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08002875 clib_spinlock_lock (&vcm->session_fifo_lockp);
Dave Wallace543852a2017-08-03 02:11:34 -04002876 clib_fifo_validate (vcm->client_session_index_fifo, q_len);
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08002877 clib_spinlock_unlock (&vcm->session_fifo_lockp);
2878
Dave Wallacef7f809c2017-10-03 01:48:42 -04002879 clib_spinlock_unlock (&vcm->sessions_lockp);
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08002880
Dave Wallace4878cbe2017-11-21 03:45:09 -05002881done:
2882 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04002883}
2884
2885int
Keith Burns (alagalah)0d2b0d52018-03-06 15:55:22 -08002886vppcom_session_register_listener (uint32_t session_index,
2887 vppcom_session_listener_cb cb,
2888 vppcom_session_listener_errcb
2889 errcb, uint8_t flags, int q_len, void *ptr)
2890{
2891 int rv = VPPCOM_OK;
2892 vce_event_key_t evk;
2893 vppcom_session_listener_t *listener_args;
2894
Keith Burns (alagalah)410bcca2018-03-23 13:42:49 -07002895 if (!vcm->session_io_thread.io_sessions_lockp)
2896 rv = vppcom_start_io_event_thread (&vcm->session_io_thread, 100 /* DAW_TODO: ??? hard-coded value */
2897 );
2898 if (rv)
2899 {
2900 goto done;
2901 }
Keith Burns (alagalah)0d2b0d52018-03-06 15:55:22 -08002902 rv = vppcom_session_listen (session_index, q_len);
2903 if (rv)
2904 {
2905 goto done;
2906 }
2907
Keith Burns (alagalah)0d2b0d52018-03-06 15:55:22 -08002908 /* Register handler for connect_request event on listen_session_index */
Keith Burns (alagalah)410bcca2018-03-23 13:42:49 -07002909 listener_args = clib_mem_alloc (sizeof (vppcom_session_listener_t)); // DAW_TODO: Use a pool instead of thrashing the memory allocator!
Keith Burns (alagalah)0d2b0d52018-03-06 15:55:22 -08002910 listener_args->user_cb = cb;
2911 listener_args->user_cb_data = ptr;
2912 listener_args->user_errcb = errcb;
2913
2914 evk.session_index = session_index;
2915 evk.eid = VCL_EVENT_CONNECT_REQ_ACCEPTED;
2916 (void) vce_register_handler (&vcm->event_thread, &evk,
2917 vce_registered_listener_connect_handler_fn,
2918 listener_args);
2919
2920done:
2921 return rv;
2922}
2923
2924int
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002925validate_args_session_accept_ (session_t * listen_session)
2926{
2927 u32 listen_session_index = listen_session - vcm->sessions;
2928
2929 /* Input validation - expects spinlock on sessions_lockp */
2930 if (listen_session->is_vep)
2931 {
2932 clib_warning ("VCL<%d>: ERROR: sid %u: cannot accept on an "
2933 "epoll session!", getpid (), listen_session_index);
2934 return VPPCOM_EBADFD;
2935 }
2936
2937 if (listen_session->state != STATE_LISTEN)
2938 {
2939 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
2940 "not in listen state! state 0x%x (%s)", getpid (),
2941 listen_session->vpp_handle, listen_session_index,
2942 listen_session->state,
2943 vppcom_session_state_str (listen_session->state));
2944 return VPPCOM_EBADFD;
2945 }
2946 return VPPCOM_OK;
2947}
2948
2949int
Dave Wallace543852a2017-08-03 02:11:34 -04002950vppcom_session_accept (uint32_t listen_session_index, vppcom_endpt_t * ep,
Dave Wallace048b1d62018-01-03 22:24:41 -05002951 uint32_t flags)
Dave Wallace543852a2017-08-03 02:11:34 -04002952{
Dave Wallace33e002b2017-09-06 01:20:02 -04002953 session_t *listen_session = 0;
2954 session_t *client_session = 0;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002955 u32 client_session_index = ~0;
Dave Wallace543852a2017-08-03 02:11:34 -04002956 int rv;
Dave Wallaceee45d412017-11-24 21:44:06 -05002957 u64 listen_vpp_handle;
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002958 vce_event_handler_reg_t *reg;
2959 vce_event_t *ev;
2960 vce_event_connect_request_t *result;
2961 struct timespec ts;
2962 struct timeval tv;
2963 int millisecond_timeout = 1;
2964 int hours_timeout = 20 * 60 * 60;
Dave Wallace543852a2017-08-03 02:11:34 -04002965
Dave Wallace4878cbe2017-11-21 03:45:09 -05002966 VCL_LOCK_AND_GET_SESSION (listen_session_index, &listen_session);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002967 listen_vpp_handle = listen_session->vpp_handle; // For debugging
Dave Wallace543852a2017-08-03 02:11:34 -04002968
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002969 rv = validate_args_session_accept_ (listen_session);
2970 if (rv)
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002971 {
2972 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002973 goto done;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002974 }
2975
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002976 /* Using an aggressive timer of 1ms and a generous timer of
2977 * 20 hours, we can implement a blocking and non-blocking listener
2978 * as both event and time driven */
2979 gettimeofday (&tv, NULL);
2980 ts.tv_nsec = (tv.tv_usec * 1000) + (1000 * millisecond_timeout);
2981 ts.tv_sec = tv.tv_sec;
2982
2983 /* Predict that the Listener is blocking more often than not */
2984 if (PREDICT_TRUE (!VCL_SESS_ATTR_TEST (listen_session->attr,
2985 VCL_SESS_ATTR_NONBLOCK)))
2986 ts.tv_sec += hours_timeout;
Dave Wallace543852a2017-08-03 02:11:34 -04002987
Dave Wallace543852a2017-08-03 02:11:34 -04002988 clib_spinlock_unlock (&vcm->sessions_lockp);
2989
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002990 /* Register handler for connect_request event on listen_session_index */
2991 vce_event_key_t evk;
2992 evk.session_index = listen_session_index;
2993 evk.eid = VCL_EVENT_CONNECT_REQ_ACCEPTED;
2994 reg = vce_register_handler (&vcm->event_thread, &evk,
Keith Burns (alagalah)0d2b0d52018-03-06 15:55:22 -08002995 vce_connect_request_handler_fn, 0);
Keith Burns (alagalah)410bcca2018-03-23 13:42:49 -07002996 clib_spinlock_lock (&(vcm->event_thread.events_lockp));
Keith Burns (alagalah)7cf80e02018-03-08 16:46:25 -08002997 ev = vce_get_event_from_index (&vcm->event_thread, reg->ev_idx);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002998 pthread_mutex_lock (&reg->handler_lock);
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08002999 while (!ev)
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08003000 {
Keith Burns (alagalah)410bcca2018-03-23 13:42:49 -07003001 clib_spinlock_unlock (&(vcm->event_thread.events_lockp));
3002 rv = pthread_cond_timedwait (&reg->handler_cond,
3003 &reg->handler_lock, &ts);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08003004 if (rv == ETIMEDOUT)
3005 {
3006 rv = VPPCOM_EAGAIN;
3007 goto cleanup;
3008 }
Keith Burns (alagalah)410bcca2018-03-23 13:42:49 -07003009 clib_spinlock_lock (&(vcm->event_thread.events_lockp));
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08003010 ev = vce_get_event_from_index (&vcm->event_thread, reg->ev_idx);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08003011 }
Keith Burns (alagalah)410bcca2018-03-23 13:42:49 -07003012 result = vce_get_event_data (ev, sizeof (*result));
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08003013 client_session_index = result->accepted_session_index;
Keith Burns (alagalah)410bcca2018-03-23 13:42:49 -07003014 clib_spinlock_unlock (&(vcm->event_thread.events_lockp));
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08003015
3016 /* Remove from the FIFO used to service epoll */
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08003017 clib_spinlock_lock (&vcm->session_fifo_lockp);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08003018 if (clib_fifo_elts (vcm->client_session_index_fifo))
3019 {
3020 u32 tmp_client_session_index;
3021 clib_fifo_sub1 (vcm->client_session_index_fifo,
3022 tmp_client_session_index);
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08003023 /* It wasn't ours... put it back ... */
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08003024 if (tmp_client_session_index != client_session_index)
3025 clib_fifo_add1 (vcm->client_session_index_fifo,
3026 tmp_client_session_index);
3027 }
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08003028 clib_spinlock_unlock (&vcm->session_fifo_lockp);
3029
3030 clib_spinlock_lock (&vcm->sessions_lockp);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08003031
Dave Wallace33e002b2017-09-06 01:20:02 -04003032 rv = vppcom_session_at_index (client_session_index, &client_session);
Dave Wallaceee45d412017-11-24 21:44:06 -05003033 if (PREDICT_FALSE (rv))
3034 {
3035 rv = VPPCOM_ECONNABORTED;
Dave Wallace048b1d62018-01-03 22:24:41 -05003036 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: client sid %u "
Dave Wallaceee45d412017-11-24 21:44:06 -05003037 "lookup failed! returning %d (%s)", getpid (),
3038 listen_vpp_handle, listen_session_index,
3039 client_session_index, rv, vppcom_retval_str (rv));
Dave Wallacee5356442018-03-19 10:38:00 -04003040 goto cleanup;
Dave Wallaceee45d412017-11-24 21:44:06 -05003041 }
Dave Wallace543852a2017-08-03 02:11:34 -04003042
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003043 if (flags & O_NONBLOCK)
3044 VCL_SESS_ATTR_SET (client_session->attr, VCL_SESS_ATTR_NONBLOCK);
3045 else
3046 VCL_SESS_ATTR_CLR (client_session->attr, VCL_SESS_ATTR_NONBLOCK);
3047
Dave Wallace543852a2017-08-03 02:11:34 -04003048 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05003049 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: Got a client request! "
Dave Wallaceee45d412017-11-24 21:44:06 -05003050 "vpp handle 0x%llx, sid %u, flags %d, is_nonblocking %u",
3051 getpid (), listen_vpp_handle, listen_session_index,
3052 client_session->vpp_handle, client_session_index,
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003053 flags, VCL_SESS_ATTR_TEST (client_session->attr,
3054 VCL_SESS_ATTR_NONBLOCK));
Dave Wallace543852a2017-08-03 02:11:34 -04003055
Dave Wallace048b1d62018-01-03 22:24:41 -05003056 if (ep)
3057 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003058 ep->is_ip4 = client_session->peer_addr.is_ip4;
3059 ep->port = client_session->peer_port;
3060 if (client_session->peer_addr.is_ip4)
3061 clib_memcpy (ep->ip, &client_session->peer_addr.ip46.ip4,
3062 sizeof (ip4_address_t));
3063 else
3064 clib_memcpy (ep->ip, &client_session->peer_addr.ip46.ip6,
3065 sizeof (ip6_address_t));
3066 }
Dave Wallace60caa062017-11-10 17:07:13 -05003067
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003068 vppcom_send_accept_session_reply (client_session->vpp_handle,
3069 client_session->client_context,
3070 0 /* retval OK */ );
Dave Wallace60caa062017-11-10 17:07:13 -05003071
Stevenac1f96d2017-10-24 16:03:58 -07003072 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05003073 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: accepted vpp handle "
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003074 "0x%llx, sid %u connection to local %s address "
Dave Wallaceee45d412017-11-24 21:44:06 -05003075 "%U port %u", getpid (), listen_vpp_handle,
3076 listen_session_index, client_session->vpp_handle,
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003077 client_session_index,
Dave Wallace4878cbe2017-11-21 03:45:09 -05003078 client_session->lcl_addr.is_ip4 ? "IPv4" : "IPv6",
3079 format_ip46_address, &client_session->lcl_addr.ip46,
Dave Wallacede910062018-03-20 09:22:13 -04003080 client_session->lcl_addr.is_ip4 ?
3081 IP46_TYPE_IP4 : IP46_TYPE_IP6,
Dave Wallace4878cbe2017-11-21 03:45:09 -05003082 clib_net_to_host_u16 (client_session->lcl_port));
Dave Wallace60caa062017-11-10 17:07:13 -05003083
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08003084 if (VPPCOM_DEBUG > 0)
3085 {
3086 client_session->elog_track.name =
3087 (char *) format (0, "C:%d:S:%d%c", vcm->my_client_index,
3088 client_session_index, 0);
3089 elog_track_register (&vcm->elog_main, &client_session->elog_track);
3090
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003091 // Two elog entries due to 20-byte per entry constraint.
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08003092 /* *INDENT-OFF* */
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08003093 ELOG_TYPE_DECLARE (e) =
3094 {
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003095 .format = "accept: listen_handle:%x from_handle:%x",
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08003096 .format_args = "i8i8",
3097 };
3098
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08003099 struct
3100 {
3101 u64 handle[2];
3102 } *ed;
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08003103
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08003104 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, client_session->elog_track);
3105 ed->handle[0] = listen_vpp_handle;
3106 ed->handle[1] = client_session->vpp_handle;
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08003107 /* *INDENT-ON* */
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08003108
3109 if (client_session->lcl_addr.is_ip4)
3110 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08003111 /* *INDENT-OFF* */
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08003112 ELOG_TYPE_DECLARE (e2) =
3113 {
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003114 .format = "accept: S:%d %d.%d.%d.%d:%d ",
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08003115 .format_args = "i4i1i1i1i1i2",
3116 };
3117
3118 CLIB_PACKED (struct {
3119 u32 session;
3120 u8 addr[4];
3121 u16 port;
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08003122 }) *ed2;
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08003123
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08003124 ed2 =
3125 ELOG_TRACK_DATA (&vcm->elog_main, e2, client_session->elog_track);
3126 ed2->session = client_session_index;
3127 ed2->addr[0] = client_session->lcl_addr.ip46.ip4.as_u8[0];
3128 ed2->addr[1] = client_session->lcl_addr.ip46.ip4.as_u8[1];
3129 ed2->addr[2] = client_session->lcl_addr.ip46.ip4.as_u8[2];
3130 ed2->addr[3] = client_session->lcl_addr.ip46.ip4.as_u8[3];
3131 ed2->port = clib_net_to_host_u16 (client_session->lcl_port);
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08003132 /* *INDENT-ON* */
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08003133 }
3134 }
3135
Dave Wallace543852a2017-08-03 02:11:34 -04003136 clib_spinlock_unlock (&vcm->sessions_lockp);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08003137
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08003138 rv = (int) client_session_index;
Keith Burns (alagalah)410bcca2018-03-23 13:42:49 -07003139 vce_clear_event (&vcm->event_thread, reg->ev_idx);
3140 if (vcm->session_io_thread.io_sessions_lockp)
3141 {
3142 /* Throw this new accepted session index into the rx poll thread pool */
3143 clib_spinlock_lock (&vcm->session_io_thread.io_sessions_lockp);
3144 u32 *active_session_index;
3145 pool_get (vcm->session_io_thread.active_session_indexes,
3146 active_session_index);
3147 *active_session_index = client_session_index;
3148 clib_spinlock_unlock (&vcm->session_io_thread.io_sessions_lockp);
3149 }
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08003150cleanup:
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08003151 vce_unregister_handler (&vcm->event_thread, reg);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08003152 pthread_mutex_unlock (&reg->handler_lock);
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08003153
Dave Wallace4878cbe2017-11-21 03:45:09 -05003154done:
3155 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04003156}
3157
3158int
3159vppcom_session_connect (uint32_t session_index, vppcom_endpt_t * server_ep)
3160{
Dave Wallace543852a2017-08-03 02:11:34 -04003161 session_t *session = 0;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003162 u64 vpp_handle = 0;
Dave Wallaceee45d412017-11-24 21:44:06 -05003163 int rv, retval = VPPCOM_OK;
Dave Wallace543852a2017-08-03 02:11:34 -04003164
Dave Wallace4878cbe2017-11-21 03:45:09 -05003165 VCL_LOCK_AND_GET_SESSION (session_index, &session);
3166
3167 if (PREDICT_FALSE (session->is_vep))
Dave Wallace543852a2017-08-03 02:11:34 -04003168 {
3169 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace048b1d62018-01-03 22:24:41 -05003170 clib_warning ("VCL<%d>: ERROR: sid %u: cannot "
3171 "connect on an epoll session!", getpid (), session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -05003172 rv = VPPCOM_EBADFD;
3173 goto done;
Dave Wallace543852a2017-08-03 02:11:34 -04003174 }
3175
Dave Wallace4878cbe2017-11-21 03:45:09 -05003176 if (PREDICT_FALSE (session->state & CLIENT_STATE_OPEN))
Dave Wallace543852a2017-08-03 02:11:34 -04003177 {
Dave Wallace543852a2017-08-03 02:11:34 -04003178 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05003179 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: session already "
Dave Wallaceee45d412017-11-24 21:44:06 -05003180 "connected to %s %U port %d proto %s, state 0x%x (%s)",
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003181 getpid (), session->vpp_handle, session_index,
Dave Wallace4878cbe2017-11-21 03:45:09 -05003182 session->peer_addr.is_ip4 ? "IPv4" : "IPv6",
3183 format_ip46_address,
Dave Wallacede910062018-03-20 09:22:13 -04003184 &session->peer_addr.ip46, session->peer_addr.is_ip4 ?
3185 IP46_TYPE_IP4 : IP46_TYPE_IP6,
Dave Wallace4878cbe2017-11-21 03:45:09 -05003186 clib_net_to_host_u16 (session->peer_port),
3187 session->proto ? "UDP" : "TCP", session->state,
3188 vppcom_session_state_str (session->state));
3189
3190 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace4878cbe2017-11-21 03:45:09 -05003191 goto done;
Dave Wallace543852a2017-08-03 02:11:34 -04003192 }
3193
Dave Wallace35830af2017-10-09 01:43:42 -04003194 session->peer_addr.is_ip4 = server_ep->is_ip4;
3195 session->peer_addr.ip46 = to_ip46 (!server_ep->is_ip4, server_ep->ip);
Stevenac1f96d2017-10-24 16:03:58 -07003196 session->peer_port = server_ep->port;
Dave Wallace543852a2017-08-03 02:11:34 -04003197
3198 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05003199 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: connecting to server "
Dave Wallaceee45d412017-11-24 21:44:06 -05003200 "%s %U port %d proto %s",
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003201 getpid (), session->vpp_handle, session_index,
Dave Wallace4878cbe2017-11-21 03:45:09 -05003202 session->peer_addr.is_ip4 ? "IPv4" : "IPv6",
3203 format_ip46_address,
Dave Wallacede910062018-03-20 09:22:13 -04003204 &session->peer_addr.ip46, session->peer_addr.is_ip4 ?
3205 IP46_TYPE_IP4 : IP46_TYPE_IP6,
Dave Wallace4878cbe2017-11-21 03:45:09 -05003206 clib_net_to_host_u16 (session->peer_port),
3207 session->proto ? "UDP" : "TCP");
Dave Wallace543852a2017-08-03 02:11:34 -04003208
3209 vppcom_send_connect_sock (session, session_index);
3210 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace4878cbe2017-11-21 03:45:09 -05003211
Dave Wallaceee45d412017-11-24 21:44:06 -05003212 retval =
3213 vppcom_wait_for_session_state_change (session_index, STATE_CONNECT,
3214 vcm->cfg.session_timeout);
3215
3216 VCL_LOCK_AND_GET_SESSION (session_index, &session);
3217 vpp_handle = session->vpp_handle;
3218 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace7876d392017-10-19 03:53:57 -04003219
Dave Wallace4878cbe2017-11-21 03:45:09 -05003220done:
Dave Wallaceee45d412017-11-24 21:44:06 -05003221 if (PREDICT_FALSE (retval))
3222 {
3223 rv = retval;
3224 if (VPPCOM_DEBUG > 0)
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003225 {
3226 if (session)
3227 clib_warning
3228 ("VCL<%d>: vpp handle 0x%llx, sid %u: connect failed! "
3229 "returning %d (%s)", getpid (), vpp_handle,
3230 session_index, rv, vppcom_retval_str (rv));
3231 else
3232 clib_warning ("VCL<%d>: no session for sid %u: connect failed! "
3233 "returning %d (%s)", getpid (),
3234 session_index, rv, vppcom_retval_str (rv));
3235 }
Dave Wallaceee45d412017-11-24 21:44:06 -05003236 }
3237 else if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05003238 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: connected!",
Dave Wallaceee45d412017-11-24 21:44:06 -05003239 getpid (), vpp_handle, session_index);
3240
Dave Wallace4878cbe2017-11-21 03:45:09 -05003241 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04003242}
3243
Steven58f464e2017-10-25 12:33:12 -07003244static inline int
3245vppcom_session_read_internal (uint32_t session_index, void *buf, int n,
3246 u8 peek)
Dave Wallace543852a2017-08-03 02:11:34 -04003247{
Dave Wallace543852a2017-08-03 02:11:34 -04003248 session_t *session = 0;
3249 svm_fifo_t *rx_fifo;
3250 int n_read = 0;
3251 int rv;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003252 int is_nonblocking;
3253
3254 u64 vpp_handle;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003255 u32 poll_et;
Dave Wallace4878cbe2017-11-21 03:45:09 -05003256 session_state_t state;
Dave Wallace543852a2017-08-03 02:11:34 -04003257
3258 ASSERT (buf);
3259
Dave Wallace4878cbe2017-11-21 03:45:09 -05003260 VCL_LOCK_AND_GET_SESSION (session_index, &session);
3261
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003262 is_nonblocking = VCL_SESS_ATTR_TEST (session->attr, VCL_SESS_ATTR_NONBLOCK);
3263 rx_fifo = session->rx_fifo;
3264 state = session->state;
3265 vpp_handle = session->vpp_handle;
3266
Dave Wallace4878cbe2017-11-21 03:45:09 -05003267 if (PREDICT_FALSE (session->is_vep))
Dave Wallace543852a2017-08-03 02:11:34 -04003268 {
3269 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace048b1d62018-01-03 22:24:41 -05003270 clib_warning ("VCL<%d>: ERROR: sid %u: cannot "
3271 "read from an epoll session!", getpid (), session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -05003272 rv = VPPCOM_EBADFD;
3273 goto done;
Dave Wallace543852a2017-08-03 02:11:34 -04003274 }
3275
Dave Wallace4878cbe2017-11-21 03:45:09 -05003276 if (PREDICT_FALSE (!(state & (SERVER_STATE_OPEN | CLIENT_STATE_OPEN))))
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003277 {
3278 clib_spinlock_unlock (&vcm->sessions_lockp);
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08003279 rv = ((state & STATE_DISCONNECT) ? VPPCOM_ECONNRESET : VPPCOM_ENOTCONN);
Dave Wallace4878cbe2017-11-21 03:45:09 -05003280
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003281 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05003282 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: %s session is "
Dave Wallaceee45d412017-11-24 21:44:06 -05003283 "not open! state 0x%x (%s), returning %d (%s)",
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003284 getpid (), vpp_handle, session_index, state,
Dave Wallace4878cbe2017-11-21 03:45:09 -05003285 vppcom_session_state_str (state),
3286 rv, vppcom_retval_str (rv));
3287 goto done;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003288 }
3289
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003290 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003291
3292 do
3293 {
Steven58f464e2017-10-25 12:33:12 -07003294 if (peek)
3295 n_read = svm_fifo_peek (rx_fifo, 0, n, buf);
3296 else
3297 n_read = svm_fifo_dequeue_nowait (rx_fifo, n, buf);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003298 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05003299 while (!is_nonblocking && (n_read <= 0));
Dave Wallacef7f809c2017-10-03 01:48:42 -04003300
Dave Wallace4878cbe2017-11-21 03:45:09 -05003301 if (n_read <= 0)
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003302 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05003303 VCL_LOCK_AND_GET_SESSION (session_index, &session);
3304
3305 poll_et = (((EPOLLET | EPOLLIN) & session->vep.ev.events) ==
3306 (EPOLLET | EPOLLIN));
3307 if (poll_et)
3308 session->vep.et_mask |= EPOLLIN;
3309
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08003310 if (state & STATE_CLOSE_ON_EMPTY)
Dave Wallace4878cbe2017-11-21 03:45:09 -05003311 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05003312 rv = VPPCOM_ECONNRESET;
3313
3314 if (VPPCOM_DEBUG > 1)
3315 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003316 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: Empty fifo "
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003317 "with session state 0x%x (%s)!"
Dave Wallaceee45d412017-11-24 21:44:06 -05003318 " Setting state to 0x%x (%s), returning %d (%s)",
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003319 getpid (), session->vpp_handle, session_index,
Dave Wallace4878cbe2017-11-21 03:45:09 -05003320 state, vppcom_session_state_str (state),
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003321 STATE_DISCONNECT,
3322 vppcom_session_state_str (STATE_DISCONNECT), rv,
3323 vppcom_retval_str (rv));
Dave Wallace4878cbe2017-11-21 03:45:09 -05003324 }
3325
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003326 session->state = STATE_DISCONNECT;
Dave Wallace4878cbe2017-11-21 03:45:09 -05003327 }
3328 else
3329 rv = VPPCOM_EAGAIN;
3330
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003331 clib_spinlock_unlock (&vcm->sessions_lockp);
3332 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05003333 else
3334 rv = n_read;
Dave Wallace543852a2017-08-03 02:11:34 -04003335
Dave Wallace4878cbe2017-11-21 03:45:09 -05003336 if (VPPCOM_DEBUG > 2)
3337 {
3338 if (rv > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05003339 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: read %d bytes "
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003340 "from (%p)", getpid (), vpp_handle,
3341 session_index, n_read, rx_fifo);
Dave Wallace4878cbe2017-11-21 03:45:09 -05003342 else
Dave Wallace048b1d62018-01-03 22:24:41 -05003343 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: nothing read! "
Dave Wallaceee45d412017-11-24 21:44:06 -05003344 "returning %d (%s)", getpid (), vpp_handle,
3345 session_index, rv, vppcom_retval_str (rv));
Dave Wallace4878cbe2017-11-21 03:45:09 -05003346 }
3347done:
3348 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04003349}
3350
Steven58f464e2017-10-25 12:33:12 -07003351int
Dave Wallace048b1d62018-01-03 22:24:41 -05003352vppcom_session_read (uint32_t session_index, void *buf, size_t n)
Steven58f464e2017-10-25 12:33:12 -07003353{
3354 return (vppcom_session_read_internal (session_index, buf, n, 0));
3355}
3356
3357static int
3358vppcom_session_peek (uint32_t session_index, void *buf, int n)
3359{
3360 return (vppcom_session_read_internal (session_index, buf, n, 1));
3361}
3362
Dave Wallace543852a2017-08-03 02:11:34 -04003363static inline int
3364vppcom_session_read_ready (session_t * session, u32 session_index)
3365{
Dave Wallace543852a2017-08-03 02:11:34 -04003366 int ready = 0;
Dave Wallace60caa062017-11-10 17:07:13 -05003367 u32 poll_et;
Dave Wallace4878cbe2017-11-21 03:45:09 -05003368 int rv;
Dave Wallace4878cbe2017-11-21 03:45:09 -05003369 session_state_t state = session->state;
Dave Wallaceee45d412017-11-24 21:44:06 -05003370 u64 vpp_handle = session->vpp_handle;
Dave Wallace543852a2017-08-03 02:11:34 -04003371
3372 /* Assumes caller has acquired spinlock: vcm->sessions_lockp */
Dave Wallace4878cbe2017-11-21 03:45:09 -05003373 if (PREDICT_FALSE (session->is_vep))
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003374 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003375 clib_warning ("VCL<%d>: ERROR: sid %u: cannot read from an "
Dave Wallace4878cbe2017-11-21 03:45:09 -05003376 "epoll session!", getpid (), session_index);
3377 rv = VPPCOM_EBADFD;
3378 goto done;
Dave Wallace543852a2017-08-03 02:11:34 -04003379 }
Dave Wallace33e002b2017-09-06 01:20:02 -04003380
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003381 if (session->state & STATE_LISTEN)
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08003382 {
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08003383 clib_spinlock_lock (&vcm->session_fifo_lockp);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08003384 ready = clib_fifo_elts (vcm->client_session_index_fifo);
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08003385 clib_spinlock_unlock (&vcm->session_fifo_lockp);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08003386 }
Dave Wallace543852a2017-08-03 02:11:34 -04003387 else
3388 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05003389 if (!(state & (SERVER_STATE_OPEN | CLIENT_STATE_OPEN | STATE_LISTEN)))
3390 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08003391 rv = ((state & STATE_DISCONNECT) ? VPPCOM_ECONNRESET :
Dave Wallace4878cbe2017-11-21 03:45:09 -05003392 VPPCOM_ENOTCONN);
3393
3394 if (VPPCOM_DEBUG > 1)
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003395 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: session is "
Dave Wallaceee45d412017-11-24 21:44:06 -05003396 "not open! state 0x%x (%s), returning %d (%s)",
3397 getpid (), vpp_handle, session_index,
Dave Wallace4878cbe2017-11-21 03:45:09 -05003398 state, vppcom_session_state_str (state),
3399 rv, vppcom_retval_str (rv));
3400 goto done;
3401 }
3402
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003403 ready = svm_fifo_max_dequeue (session->rx_fifo);
Dave Wallace543852a2017-08-03 02:11:34 -04003404 }
3405
Dave Wallace4878cbe2017-11-21 03:45:09 -05003406 if (ready == 0)
Dave Wallace60caa062017-11-10 17:07:13 -05003407 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05003408 poll_et =
3409 ((EPOLLET | EPOLLIN) & session->vep.ev.events) == (EPOLLET | EPOLLIN);
3410 if (poll_et)
3411 session->vep.et_mask |= EPOLLIN;
Dave Wallace60caa062017-11-10 17:07:13 -05003412
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08003413 if (state & STATE_CLOSE_ON_EMPTY)
Dave Wallace4878cbe2017-11-21 03:45:09 -05003414 {
3415 rv = VPPCOM_ECONNRESET;
Dave Wallace4878cbe2017-11-21 03:45:09 -05003416
3417 if (VPPCOM_DEBUG > 1)
3418 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003419 clib_warning ("VCL<%d>: vpp handle 0x%llx, "
3420 "sid %u: Empty fifo with"
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003421 " session state 0x%x (%s)! Setting state to "
Dave Wallaceee45d412017-11-24 21:44:06 -05003422 "0x%x (%s), returning %d (%s)",
3423 getpid (), session_index, vpp_handle,
Dave Wallace4878cbe2017-11-21 03:45:09 -05003424 state, vppcom_session_state_str (state),
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003425 STATE_DISCONNECT,
3426 vppcom_session_state_str (STATE_DISCONNECT), rv,
3427 vppcom_retval_str (rv));
Dave Wallace4878cbe2017-11-21 03:45:09 -05003428 }
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003429 session->state = STATE_DISCONNECT;
Dave Wallace4878cbe2017-11-21 03:45:09 -05003430 goto done;
3431 }
3432 }
3433 rv = ready;
Dave Wallace16cb4082017-11-29 03:24:06 -05003434
3435 if (vcm->app_event_queue->cursize &&
3436 !pthread_mutex_trylock (&vcm->app_event_queue->mutex))
3437 {
3438 u32 i, n_to_dequeue = vcm->app_event_queue->cursize;
3439 session_fifo_event_t e;
3440
3441 for (i = 0; i < n_to_dequeue; i++)
Florin Corase86a8ed2018-01-05 03:20:25 -08003442 svm_queue_sub_raw (vcm->app_event_queue, (u8 *) & e);
Dave Wallace16cb4082017-11-29 03:24:06 -05003443
3444 pthread_mutex_unlock (&vcm->app_event_queue->mutex);
3445 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05003446done:
3447 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04003448}
3449
3450int
Keith Burns (alagalah)410bcca2018-03-23 13:42:49 -07003451vppcom_session_register_ioevent_cb (uint32_t session_index,
3452 vppcom_session_ioevent_cb cb,
3453 uint8_t rx, void *ptr)
3454{
3455 int rv = VPPCOM_OK;
3456 vce_event_key_t evk;
3457 vppcom_session_ioevent_t *ioevent;
3458
3459 if (!vcm->session_io_thread.io_sessions_lockp)
3460 rv = vppcom_start_io_event_thread (&vcm->session_io_thread, 100 /* DAW_TODO: ??? hard-coded value */
3461 );
3462
3463 if (rv == VPPCOM_OK)
3464 {
3465 void *io_evt_ndx;
3466
3467 /* Register handler for ioevent on session_index */
3468 clib_spinlock_lock (&vcm->session_io_thread.io_sessions_lockp);
3469 pool_get (vcm->session_io_thread.ioevents, ioevent);
3470 io_evt_ndx = (void *) (ioevent - vcm->session_io_thread.ioevents);
3471 ioevent->user_cb = cb;
3472 ioevent->user_cb_data = ptr;
3473 clib_spinlock_unlock (&vcm->session_io_thread.io_sessions_lockp);
3474
3475 evk.session_index = session_index;
3476 evk.eid = rx ? VCL_EVENT_IOEVENT_RX_FIFO : VCL_EVENT_IOEVENT_TX_FIFO;
3477
3478 (void) vce_register_handler (&vcm->event_thread, &evk,
3479 vce_registered_ioevent_handler_fn,
3480 io_evt_ndx);
3481 }
3482 return rv;
3483}
3484
3485int
Dave Wallace048b1d62018-01-03 22:24:41 -05003486vppcom_session_write (uint32_t session_index, void *buf, size_t n)
Dave Wallace543852a2017-08-03 02:11:34 -04003487{
Dave Wallace543852a2017-08-03 02:11:34 -04003488 session_t *session = 0;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003489 svm_fifo_t *tx_fifo = 0;
Florin Corase86a8ed2018-01-05 03:20:25 -08003490 svm_queue_t *q;
Dave Wallace543852a2017-08-03 02:11:34 -04003491 session_fifo_event_t evt;
Dave Wallace4878cbe2017-11-21 03:45:09 -05003492 session_state_t state;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003493 int rv, n_write, is_nonblocking;
3494 u32 poll_et;
Dave Wallaceee45d412017-11-24 21:44:06 -05003495 u64 vpp_handle;
Dave Wallace543852a2017-08-03 02:11:34 -04003496
3497 ASSERT (buf);
3498
Dave Wallace4878cbe2017-11-21 03:45:09 -05003499 VCL_LOCK_AND_GET_SESSION (session_index, &session);
3500
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003501 tx_fifo = session->tx_fifo;
3502 is_nonblocking = VCL_SESS_ATTR_TEST (session->attr, VCL_SESS_ATTR_NONBLOCK);
3503 vpp_handle = session->vpp_handle;
3504 state = session->state;
3505
Dave Wallace4878cbe2017-11-21 03:45:09 -05003506 if (PREDICT_FALSE (session->is_vep))
Dave Wallace543852a2017-08-03 02:11:34 -04003507 {
3508 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace048b1d62018-01-03 22:24:41 -05003509 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -05003510 "cannot write to an epoll session!",
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003511 getpid (), vpp_handle, session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -05003512
3513 rv = VPPCOM_EBADFD;
3514 goto done;
Dave Wallace543852a2017-08-03 02:11:34 -04003515 }
3516
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003517 if (!(session->state & (SERVER_STATE_OPEN | CLIENT_STATE_OPEN)))
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003518 {
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003519 rv =
3520 ((session->state & STATE_DISCONNECT) ? VPPCOM_ECONNRESET :
3521 VPPCOM_ENOTCONN);
Dave Wallace4878cbe2017-11-21 03:45:09 -05003522
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003523 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace4878cbe2017-11-21 03:45:09 -05003524 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05003525 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003526 "session is not open! state 0x%x (%s)",
Dave Wallaceee45d412017-11-24 21:44:06 -05003527 getpid (), vpp_handle, session_index,
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003528 state, vppcom_session_state_str (state));
Dave Wallace4878cbe2017-11-21 03:45:09 -05003529 goto done;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003530 }
3531
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003532 clib_spinlock_unlock (&vcm->sessions_lockp);
3533
Dave Wallace543852a2017-08-03 02:11:34 -04003534 do
3535 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003536 n_write = svm_fifo_enqueue_nowait (tx_fifo, n, (void *) buf);
Dave Wallace543852a2017-08-03 02:11:34 -04003537 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05003538 while (!is_nonblocking && (n_write <= 0));
Dave Wallace543852a2017-08-03 02:11:34 -04003539
Keith Burns (alagalah)410bcca2018-03-23 13:42:49 -07003540 /* If event wasn't set, add one
3541 *
3542 * To reduce context switching, can check if an
3543 * event is already there for this event_key, but for now
3544 * this will suffice. */
3545
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003546 if ((n_write > 0) && svm_fifo_set_event (tx_fifo))
Dave Wallace543852a2017-08-03 02:11:34 -04003547 {
Dave Wallace543852a2017-08-03 02:11:34 -04003548 /* Fabricate TX event, send to vpp */
3549 evt.fifo = tx_fifo;
3550 evt.event_type = FIFO_EVENT_APP_TX;
Dave Wallace543852a2017-08-03 02:11:34 -04003551
Dave Wallace4878cbe2017-11-21 03:45:09 -05003552 VCL_LOCK_AND_GET_SESSION (session_index, &session);
3553 q = session->vpp_event_queue;
Dave Wallace543852a2017-08-03 02:11:34 -04003554 ASSERT (q);
Florin Corase86a8ed2018-01-05 03:20:25 -08003555 svm_queue_add (q, (u8 *) & evt, 0 /* do wait for mutex */ );
Dave Wallace4878cbe2017-11-21 03:45:09 -05003556 clib_spinlock_unlock (&vcm->sessions_lockp);
3557 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05003558 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -05003559 "added FIFO_EVENT_APP_TX to "
Dave Wallace4878cbe2017-11-21 03:45:09 -05003560 "vpp_event_q %p, n_write %d", getpid (),
Dave Wallaceee45d412017-11-24 21:44:06 -05003561 vpp_handle, session_index, q, n_write);
Dave Wallace543852a2017-08-03 02:11:34 -04003562 }
3563
Dave Wallace4878cbe2017-11-21 03:45:09 -05003564 if (n_write <= 0)
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003565 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05003566 VCL_LOCK_AND_GET_SESSION (session_index, &session);
3567
3568 poll_et = (((EPOLLET | EPOLLOUT) & session->vep.ev.events) ==
3569 (EPOLLET | EPOLLOUT));
3570 if (poll_et)
3571 session->vep.et_mask |= EPOLLOUT;
3572
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003573 if (session->state & STATE_CLOSE_ON_EMPTY)
Dave Wallace4878cbe2017-11-21 03:45:09 -05003574 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05003575 rv = VPPCOM_ECONNRESET;
3576
3577 if (VPPCOM_DEBUG > 1)
3578 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003579 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003580 "Empty fifo with session state 0x%x (%s)!"
Dave Wallaceee45d412017-11-24 21:44:06 -05003581 " Setting state to 0x%x (%s), returning %d (%s)",
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003582 getpid (), session->vpp_handle, session_index,
3583 session->state,
3584 vppcom_session_state_str (session->state),
3585 STATE_DISCONNECT,
3586 vppcom_session_state_str (STATE_DISCONNECT), rv,
3587 vppcom_retval_str (rv));
Dave Wallace4878cbe2017-11-21 03:45:09 -05003588 }
3589
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003590 session->state = STATE_DISCONNECT;
Dave Wallace4878cbe2017-11-21 03:45:09 -05003591 }
3592 else
3593 rv = VPPCOM_EAGAIN;
3594
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003595 clib_spinlock_unlock (&vcm->sessions_lockp);
3596 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05003597 else
3598 rv = n_write;
Dave Wallacef7f809c2017-10-03 01:48:42 -04003599
Dave Wallace543852a2017-08-03 02:11:34 -04003600 if (VPPCOM_DEBUG > 2)
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003601 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05003602 if (n_write <= 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05003603 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003604 "FIFO-FULL (%p)", getpid (), vpp_handle,
3605 session_index, tx_fifo);
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003606 else
Dave Wallace048b1d62018-01-03 22:24:41 -05003607 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003608 "wrote %d bytes tx-fifo: (%p)", getpid (),
3609 vpp_handle, session_index, n_write, tx_fifo);
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003610 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05003611done:
3612 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04003613}
3614
3615static inline int
3616vppcom_session_write_ready (session_t * session, u32 session_index)
3617{
Dave Wallacef7f809c2017-10-03 01:48:42 -04003618 int ready;
Dave Wallace60caa062017-11-10 17:07:13 -05003619 u32 poll_et;
Dave Wallace4878cbe2017-11-21 03:45:09 -05003620 int rv;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003621
3622 ASSERT (session);
Dave Wallace543852a2017-08-03 02:11:34 -04003623
3624 /* Assumes caller has acquired spinlock: vcm->sessions_lockp */
Dave Wallace4878cbe2017-11-21 03:45:09 -05003625 if (PREDICT_FALSE (session->is_vep))
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003626 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003627 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -05003628 "cannot write to an epoll session!",
3629 getpid (), session->vpp_handle, session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -05003630 rv = VPPCOM_EBADFD;
3631 goto done;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003632 }
3633
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003634 if (PREDICT_FALSE (session->state & STATE_LISTEN))
Dave Wallace33e002b2017-09-06 01:20:02 -04003635 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003636 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -05003637 "cannot write to a listen session!",
3638 getpid (), session->vpp_handle, session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -05003639 rv = VPPCOM_EBADFD;
3640 goto done;
3641 }
3642
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003643 if (!(session->state & (SERVER_STATE_OPEN | CLIENT_STATE_OPEN)))
Dave Wallace4878cbe2017-11-21 03:45:09 -05003644 {
3645 session_state_t state = session->state;
3646
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08003647 rv = ((state & STATE_DISCONNECT) ? VPPCOM_ECONNRESET : VPPCOM_ENOTCONN);
Dave Wallace4878cbe2017-11-21 03:45:09 -05003648
Dave Wallace048b1d62018-01-03 22:24:41 -05003649 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003650 "session is not open! state 0x%x (%s), "
Dave Wallaceee45d412017-11-24 21:44:06 -05003651 "returning %d (%s)", getpid (), session->vpp_handle,
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003652 session_index,
Dave Wallace4878cbe2017-11-21 03:45:09 -05003653 state, vppcom_session_state_str (state),
3654 rv, vppcom_retval_str (rv));
3655 goto done;
Dave Wallace33e002b2017-09-06 01:20:02 -04003656 }
3657
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003658 ready = svm_fifo_max_enqueue (session->tx_fifo);
Dave Wallace543852a2017-08-03 02:11:34 -04003659
Dave Wallace33e002b2017-09-06 01:20:02 -04003660 if (VPPCOM_DEBUG > 3)
Dave Wallace048b1d62018-01-03 22:24:41 -05003661 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -05003662 "peek %s (%p), ready = %d", getpid (),
3663 session->vpp_handle, session_index,
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003664 session->tx_fifo, ready);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003665
Dave Wallace4878cbe2017-11-21 03:45:09 -05003666 if (ready == 0)
3667 {
3668 poll_et = (((EPOLLET | EPOLLOUT) & session->vep.ev.events) ==
3669 (EPOLLET | EPOLLOUT));
3670 if (poll_et)
3671 session->vep.et_mask |= EPOLLOUT;
3672
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003673 if (session->state & STATE_CLOSE_ON_EMPTY)
Dave Wallace4878cbe2017-11-21 03:45:09 -05003674 {
3675 rv = VPPCOM_ECONNRESET;
Dave Wallace4878cbe2017-11-21 03:45:09 -05003676
3677 if (VPPCOM_DEBUG > 1)
3678 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003679 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003680 "Empty fifo with session "
Dave Wallaceee45d412017-11-24 21:44:06 -05003681 "state 0x%x (%s)! Setting state to 0x%x (%s), "
3682 "returning %d (%s)", getpid (),
3683 session->vpp_handle, session_index,
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003684 session->state,
3685 vppcom_session_state_str (session->state),
3686 STATE_DISCONNECT,
3687 vppcom_session_state_str (STATE_DISCONNECT), rv,
3688 vppcom_retval_str (rv));
Dave Wallace4878cbe2017-11-21 03:45:09 -05003689 }
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003690 session->state = STATE_DISCONNECT;
Dave Wallace4878cbe2017-11-21 03:45:09 -05003691 goto done;
3692 }
3693 }
3694 rv = ready;
3695done:
3696 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04003697}
3698
3699int
3700vppcom_select (unsigned long n_bits, unsigned long *read_map,
3701 unsigned long *write_map, unsigned long *except_map,
3702 double time_to_wait)
3703{
Dave Wallace543852a2017-08-03 02:11:34 -04003704 u32 session_index;
3705 session_t *session = 0;
3706 int rv, bits_set = 0;
3707 f64 timeout = clib_time_now (&vcm->clib_time) + time_to_wait;
3708 u32 minbits = clib_max (n_bits, BITS (uword));
3709
3710 ASSERT (sizeof (clib_bitmap_t) == sizeof (long int));
3711
Dave Wallace7876d392017-10-19 03:53:57 -04003712 if (n_bits && read_map)
Dave Wallace543852a2017-08-03 02:11:34 -04003713 {
3714 clib_bitmap_validate (vcm->rd_bitmap, minbits);
Dave Wallace048b1d62018-01-03 22:24:41 -05003715 clib_memcpy (vcm->rd_bitmap, read_map,
3716 vec_len (vcm->rd_bitmap) * sizeof (clib_bitmap_t));
3717 memset (read_map, 0, vec_len (vcm->rd_bitmap) * sizeof (clib_bitmap_t));
Dave Wallace543852a2017-08-03 02:11:34 -04003718 }
Dave Wallace7876d392017-10-19 03:53:57 -04003719 if (n_bits && write_map)
Dave Wallace543852a2017-08-03 02:11:34 -04003720 {
3721 clib_bitmap_validate (vcm->wr_bitmap, minbits);
Dave Wallace048b1d62018-01-03 22:24:41 -05003722 clib_memcpy (vcm->wr_bitmap, write_map,
3723 vec_len (vcm->wr_bitmap) * sizeof (clib_bitmap_t));
3724 memset (write_map, 0,
3725 vec_len (vcm->wr_bitmap) * sizeof (clib_bitmap_t));
Dave Wallace543852a2017-08-03 02:11:34 -04003726 }
Dave Wallace7876d392017-10-19 03:53:57 -04003727 if (n_bits && except_map)
Dave Wallace543852a2017-08-03 02:11:34 -04003728 {
3729 clib_bitmap_validate (vcm->ex_bitmap, minbits);
Dave Wallace048b1d62018-01-03 22:24:41 -05003730 clib_memcpy (vcm->ex_bitmap, except_map,
3731 vec_len (vcm->ex_bitmap) * sizeof (clib_bitmap_t));
3732 memset (except_map, 0,
3733 vec_len (vcm->ex_bitmap) * sizeof (clib_bitmap_t));
Dave Wallace543852a2017-08-03 02:11:34 -04003734 }
3735
3736 do
3737 {
3738 /* *INDENT-OFF* */
Dave Wallacee22aa742017-10-20 12:30:38 -04003739 if (n_bits)
3740 {
3741 if (read_map)
Dave Wallace543852a2017-08-03 02:11:34 -04003742 {
Dave Wallacee22aa742017-10-20 12:30:38 -04003743 clib_bitmap_foreach (session_index, vcm->rd_bitmap,
3744 ({
3745 clib_spinlock_lock (&vcm->sessions_lockp);
3746 rv = vppcom_session_at_index (session_index, &session);
3747 if (rv < 0)
3748 {
3749 clib_spinlock_unlock (&vcm->sessions_lockp);
3750 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05003751 clib_warning ("VCL<%d>: session %d specified in "
Dave Wallace2e005bb2017-11-07 01:21:39 -05003752 "read_map is closed.", getpid (),
Dave Wallacee22aa742017-10-20 12:30:38 -04003753 session_index);
3754 bits_set = VPPCOM_EBADFD;
3755 goto select_done;
3756 }
Dave Wallace8d73e852018-03-08 16:39:28 -05003757 if (session->state & STATE_LISTEN)
3758 {
3759 vce_event_handler_reg_t *reg = 0;
3760 vce_event_key_t evk;
Dave Wallacee22aa742017-10-20 12:30:38 -04003761
Dave Wallace8d73e852018-03-08 16:39:28 -05003762 /* Check if handler already registered for this
3763 * event.
3764 * If not, register handler for connect_request event
3765 * on listen_session_index
3766 */
3767 evk.session_index = session_index;
3768 evk.eid = VCL_EVENT_CONNECT_REQ_ACCEPTED;
3769 reg = vce_get_event_handler (&vcm->event_thread, &evk);
3770 if (!reg)
3771 reg = vce_register_handler (&vcm->event_thread, &evk,
Keith Burns (alagalah)0d2b0d52018-03-06 15:55:22 -08003772 vce_poll_wait_connect_request_handler_fn,
3773 0 /* No callback args */);
Dave Wallace8d73e852018-03-08 16:39:28 -05003774 rv = vppcom_session_read_ready (session, session_index);
3775 if (rv > 0)
3776 {
3777 vce_unregister_handler (&vcm->event_thread, reg);
3778 }
3779 }
3780 else
3781 rv = vppcom_session_read_ready (session, session_index);
Dave Wallacee22aa742017-10-20 12:30:38 -04003782 clib_spinlock_unlock (&vcm->sessions_lockp);
3783 if (except_map && vcm->ex_bitmap &&
3784 clib_bitmap_get (vcm->ex_bitmap, session_index) &&
3785 (rv < 0))
3786 {
Dave Wallacee22aa742017-10-20 12:30:38 -04003787 clib_bitmap_set_no_check (except_map, session_index, 1);
3788 bits_set++;
3789 }
3790 else if (rv > 0)
3791 {
Dave Wallacee22aa742017-10-20 12:30:38 -04003792 clib_bitmap_set_no_check (read_map, session_index, 1);
3793 bits_set++;
3794 }
3795 }));
Dave Wallace543852a2017-08-03 02:11:34 -04003796 }
3797
Dave Wallacee22aa742017-10-20 12:30:38 -04003798 if (write_map)
Dave Wallace543852a2017-08-03 02:11:34 -04003799 {
Dave Wallacee22aa742017-10-20 12:30:38 -04003800 clib_bitmap_foreach (session_index, vcm->wr_bitmap,
3801 ({
3802 clib_spinlock_lock (&vcm->sessions_lockp);
3803 rv = vppcom_session_at_index (session_index, &session);
3804 if (rv < 0)
3805 {
3806 clib_spinlock_unlock (&vcm->sessions_lockp);
3807 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05003808 clib_warning ("VCL<%d>: session %d specified in "
Dave Wallace2e005bb2017-11-07 01:21:39 -05003809 "write_map is closed.", getpid (),
Dave Wallacee22aa742017-10-20 12:30:38 -04003810 session_index);
3811 bits_set = VPPCOM_EBADFD;
3812 goto select_done;
3813 }
Dave Wallace543852a2017-08-03 02:11:34 -04003814
Dave Wallacee22aa742017-10-20 12:30:38 -04003815 rv = vppcom_session_write_ready (session, session_index);
3816 clib_spinlock_unlock (&vcm->sessions_lockp);
3817 if (write_map && (rv > 0))
3818 {
Dave Wallacee22aa742017-10-20 12:30:38 -04003819 clib_bitmap_set_no_check (write_map, session_index, 1);
3820 bits_set++;
3821 }
3822 }));
Dave Wallace543852a2017-08-03 02:11:34 -04003823 }
3824
Dave Wallacee22aa742017-10-20 12:30:38 -04003825 if (except_map)
Dave Wallace543852a2017-08-03 02:11:34 -04003826 {
Dave Wallacee22aa742017-10-20 12:30:38 -04003827 clib_bitmap_foreach (session_index, vcm->ex_bitmap,
3828 ({
3829 clib_spinlock_lock (&vcm->sessions_lockp);
3830 rv = vppcom_session_at_index (session_index, &session);
3831 if (rv < 0)
3832 {
3833 clib_spinlock_unlock (&vcm->sessions_lockp);
3834 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05003835 clib_warning ("VCL<%d>: session %d specified in "
Dave Wallace2e005bb2017-11-07 01:21:39 -05003836 "except_map is closed.", getpid (),
Dave Wallacee22aa742017-10-20 12:30:38 -04003837 session_index);
3838 bits_set = VPPCOM_EBADFD;
3839 goto select_done;
3840 }
Dave Wallace543852a2017-08-03 02:11:34 -04003841
Dave Wallacee22aa742017-10-20 12:30:38 -04003842 rv = vppcom_session_read_ready (session, session_index);
3843 clib_spinlock_unlock (&vcm->sessions_lockp);
3844 if (rv < 0)
3845 {
Dave Wallacee22aa742017-10-20 12:30:38 -04003846 clib_bitmap_set_no_check (except_map, session_index, 1);
3847 bits_set++;
3848 }
3849 }));
Dave Wallace543852a2017-08-03 02:11:34 -04003850 }
Dave Wallacee22aa742017-10-20 12:30:38 -04003851 }
Dave Wallace543852a2017-08-03 02:11:34 -04003852 /* *INDENT-ON* */
3853 }
Dave Wallace048b1d62018-01-03 22:24:41 -05003854 while ((time_to_wait == -1) || (clib_time_now (&vcm->clib_time) < timeout));
Dave Wallace543852a2017-08-03 02:11:34 -04003855
3856select_done:
3857 return (bits_set);
3858}
3859
Dave Wallacef7f809c2017-10-03 01:48:42 -04003860static inline void
3861vep_verify_epoll_chain (u32 vep_idx)
3862{
3863 session_t *session;
3864 vppcom_epoll_t *vep;
3865 int rv;
Dave Wallace498b3a52017-11-09 13:00:34 -05003866 u32 sid = vep_idx;
Dave Wallacef7f809c2017-10-03 01:48:42 -04003867
Dave Wallace498b3a52017-11-09 13:00:34 -05003868 if (VPPCOM_DEBUG <= 1)
Dave Wallacef7f809c2017-10-03 01:48:42 -04003869 return;
3870
3871 /* Assumes caller has acquired spinlock: vcm->sessions_lockp */
3872 rv = vppcom_session_at_index (vep_idx, &session);
3873 if (PREDICT_FALSE (rv))
3874 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003875 clib_warning ("VCL<%d>: ERROR: Invalid vep_idx (%u)!",
3876 getpid (), vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003877 goto done;
3878 }
3879 if (PREDICT_FALSE (!session->is_vep))
3880 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003881 clib_warning ("VCL<%d>: ERROR: vep_idx (%u) is not a vep!",
3882 getpid (), vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003883 goto done;
3884 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05003885 vep = &session->vep;
Dave Wallace048b1d62018-01-03 22:24:41 -05003886 clib_warning ("VCL<%d>: vep_idx (%u): Dumping epoll chain\n"
Dave Wallace498b3a52017-11-09 13:00:34 -05003887 "{\n"
3888 " is_vep = %u\n"
3889 " is_vep_session = %u\n"
Dave Wallace4878cbe2017-11-21 03:45:09 -05003890 " next_sid = 0x%x (%u)\n"
Dave Wallace498b3a52017-11-09 13:00:34 -05003891 " wait_cont_idx = 0x%x (%u)\n"
Dave Wallace4878cbe2017-11-21 03:45:09 -05003892 "}\n", getpid (), vep_idx,
3893 session->is_vep, session->is_vep_session,
3894 vep->next_sid, vep->next_sid,
Dave Wallace498b3a52017-11-09 13:00:34 -05003895 session->wait_cont_idx, session->wait_cont_idx);
Dave Wallace4878cbe2017-11-21 03:45:09 -05003896
3897 for (sid = vep->next_sid; sid != ~0; sid = vep->next_sid)
Dave Wallacef7f809c2017-10-03 01:48:42 -04003898 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05003899 rv = vppcom_session_at_index (sid, &session);
3900 if (PREDICT_FALSE (rv))
Dave Wallacef7f809c2017-10-03 01:48:42 -04003901 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003902 clib_warning ("VCL<%d>: ERROR: Invalid sid (%u)!", getpid (), sid);
Dave Wallace4878cbe2017-11-21 03:45:09 -05003903 goto done;
3904 }
3905 if (PREDICT_FALSE (session->is_vep))
Dave Wallace048b1d62018-01-03 22:24:41 -05003906 clib_warning ("VCL<%d>: ERROR: sid (%u) is a vep!",
3907 getpid (), vep_idx);
Dave Wallace4878cbe2017-11-21 03:45:09 -05003908 else if (PREDICT_FALSE (!session->is_vep_session))
3909 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003910 clib_warning ("VCL<%d>: ERROR: session (%u) "
3911 "is not a vep session!", getpid (), sid);
Dave Wallace4878cbe2017-11-21 03:45:09 -05003912 goto done;
3913 }
3914 vep = &session->vep;
3915 if (PREDICT_FALSE (vep->vep_idx != vep_idx))
Dave Wallace048b1d62018-01-03 22:24:41 -05003916 clib_warning ("VCL<%d>: ERROR: session (%u) vep_idx (%u) != "
Dave Wallace4878cbe2017-11-21 03:45:09 -05003917 "vep_idx (%u)!", getpid (),
3918 sid, session->vep.vep_idx, vep_idx);
3919 if (session->is_vep_session)
3920 {
3921 clib_warning ("vep_idx[%u]: sid 0x%x (%u)\n"
3922 "{\n"
3923 " next_sid = 0x%x (%u)\n"
3924 " prev_sid = 0x%x (%u)\n"
3925 " vep_idx = 0x%x (%u)\n"
3926 " ev.events = 0x%x\n"
3927 " ev.data.u64 = 0x%llx\n"
3928 " et_mask = 0x%x\n"
3929 "}\n",
3930 vep_idx, sid, sid,
3931 vep->next_sid, vep->next_sid,
3932 vep->prev_sid, vep->prev_sid,
3933 vep->vep_idx, vep->vep_idx,
3934 vep->ev.events, vep->ev.data.u64, vep->et_mask);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003935 }
3936 }
Dave Wallacef7f809c2017-10-03 01:48:42 -04003937
3938done:
Dave Wallace048b1d62018-01-03 22:24:41 -05003939 clib_warning ("VCL<%d>: vep_idx (%u): Dump complete!\n",
3940 getpid (), vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003941}
3942
3943int
3944vppcom_epoll_create (void)
3945{
Dave Wallacef7f809c2017-10-03 01:48:42 -04003946 session_t *vep_session;
3947 u32 vep_idx;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003948 elog_track_t vep_elog_track;
Dave Wallacef7f809c2017-10-03 01:48:42 -04003949
3950 clib_spinlock_lock (&vcm->sessions_lockp);
3951 pool_get (vcm->sessions, vep_session);
3952 memset (vep_session, 0, sizeof (*vep_session));
3953 vep_idx = vep_session - vcm->sessions;
3954
3955 vep_session->is_vep = 1;
3956 vep_session->vep.vep_idx = ~0;
3957 vep_session->vep.next_sid = ~0;
3958 vep_session->vep.prev_sid = ~0;
3959 vep_session->wait_cont_idx = ~0;
Dave Wallace4878cbe2017-11-21 03:45:09 -05003960 vep_session->vpp_handle = ~0;
Keith Burns (alagalah)12756512018-03-06 05:55:27 -08003961 vep_session->poll_reg = 0;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003962
3963 if (VPPCOM_DEBUG > 0)
3964 {
3965 vep_session->elog_track.name =
3966 (char *) format (0, "C:%d:VEP:%d%c", vcm->my_client_index,
3967 vep_idx, 0);
3968 elog_track_register (&vcm->elog_main, &vep_session->elog_track);
3969 vep_elog_track = vep_session->elog_track;
3970 }
3971
Dave Wallacef7f809c2017-10-03 01:48:42 -04003972 clib_spinlock_unlock (&vcm->sessions_lockp);
3973
3974 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05003975 clib_warning ("VCL<%d>: Created vep_idx %u / sid %u!",
Dave Wallaceee45d412017-11-24 21:44:06 -05003976 getpid (), vep_idx, vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003977
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08003978 if (VPPCOM_DEBUG > 0)
3979 {
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08003980
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08003981 /* *INDENT-OFF* */
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08003982 ELOG_TYPE_DECLARE (e) =
3983 {
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08003984 .format = "created epoll session:%d",
3985 .format_args = "i4",
3986 };
3987
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08003988 struct
3989 {
3990 u32 data;
3991 } *ed;
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08003992
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003993 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, vep_elog_track);
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08003994 ed->data = vep_idx;
Keith Burns (alagalah)d3046592018-01-16 14:20:34 -08003995 /* *INDENT-ON* */
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08003996 }
3997
Dave Wallacef7f809c2017-10-03 01:48:42 -04003998 return (vep_idx);
3999}
4000
4001int
4002vppcom_epoll_ctl (uint32_t vep_idx, int op, uint32_t session_index,
4003 struct epoll_event *event)
4004{
Dave Wallacef7f809c2017-10-03 01:48:42 -04004005 session_t *vep_session;
4006 session_t *session;
4007 int rv;
4008
4009 if (vep_idx == session_index)
4010 {
Dave Wallace048b1d62018-01-03 22:24:41 -05004011 clib_warning ("VCL<%d>: ERROR: vep_idx == session_index (%u)!",
Dave Wallace4878cbe2017-11-21 03:45:09 -05004012 getpid (), vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04004013 return VPPCOM_EINVAL;
4014 }
4015
4016 clib_spinlock_lock (&vcm->sessions_lockp);
4017 rv = vppcom_session_at_index (vep_idx, &vep_session);
4018 if (PREDICT_FALSE (rv))
4019 {
Dave Wallace048b1d62018-01-03 22:24:41 -05004020 clib_warning ("VCL<%d>: ERROR: Invalid vep_idx (%u)!", vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04004021 goto done;
4022 }
4023 if (PREDICT_FALSE (!vep_session->is_vep))
4024 {
Dave Wallace048b1d62018-01-03 22:24:41 -05004025 clib_warning ("VCL<%d>: ERROR: vep_idx (%u) is not a vep!",
Dave Wallace4878cbe2017-11-21 03:45:09 -05004026 getpid (), vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04004027 rv = VPPCOM_EINVAL;
4028 goto done;
4029 }
4030
4031 ASSERT (vep_session->vep.vep_idx == ~0);
4032 ASSERT (vep_session->vep.prev_sid == ~0);
4033
4034 rv = vppcom_session_at_index (session_index, &session);
4035 if (PREDICT_FALSE (rv))
4036 {
4037 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05004038 clib_warning ("VCL<%d>: ERROR: Invalid session_index (%u)!",
Dave Wallace2e005bb2017-11-07 01:21:39 -05004039 getpid (), session_index);
Dave Wallacef7f809c2017-10-03 01:48:42 -04004040 goto done;
4041 }
4042 if (PREDICT_FALSE (session->is_vep))
4043 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05004044 clib_warning ("ERROR: session_index (%u) is a vep!", vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04004045 rv = VPPCOM_EINVAL;
4046 goto done;
4047 }
4048
4049 switch (op)
4050 {
4051 case EPOLL_CTL_ADD:
4052 if (PREDICT_FALSE (!event))
4053 {
Dave Wallace048b1d62018-01-03 22:24:41 -05004054 clib_warning ("VCL<%d>: ERROR: EPOLL_CTL_ADD: NULL pointer to "
Dave Wallace2e005bb2017-11-07 01:21:39 -05004055 "epoll_event structure!", getpid ());
Dave Wallacef7f809c2017-10-03 01:48:42 -04004056 rv = VPPCOM_EINVAL;
4057 goto done;
4058 }
4059 if (vep_session->vep.next_sid != ~0)
4060 {
4061 session_t *next_session;
4062 rv = vppcom_session_at_index (vep_session->vep.next_sid,
4063 &next_session);
4064 if (PREDICT_FALSE (rv))
4065 {
Dave Wallace048b1d62018-01-03 22:24:41 -05004066 clib_warning ("VCL<%d>: ERROR: EPOLL_CTL_ADD: Invalid "
Dave Wallace4878cbe2017-11-21 03:45:09 -05004067 "vep.next_sid (%u) on vep_idx (%u)!",
4068 getpid (), vep_session->vep.next_sid, vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04004069 goto done;
4070 }
4071 ASSERT (next_session->vep.prev_sid == vep_idx);
4072 next_session->vep.prev_sid = session_index;
4073 }
4074 session->vep.next_sid = vep_session->vep.next_sid;
4075 session->vep.prev_sid = vep_idx;
4076 session->vep.vep_idx = vep_idx;
4077 session->vep.et_mask = VEP_DEFAULT_ET_MASK;
4078 session->vep.ev = *event;
Dave Wallace4878cbe2017-11-21 03:45:09 -05004079 session->is_vep = 0;
Dave Wallacef7f809c2017-10-03 01:48:42 -04004080 session->is_vep_session = 1;
4081 vep_session->vep.next_sid = session_index;
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08004082
4083 /* VCL Event Register handler */
4084 if (session->state & STATE_LISTEN)
4085 {
4086 /* Register handler for connect_request event on listen_session_index */
4087 vce_event_key_t evk;
4088 evk.session_index = session_index;
4089 evk.eid = VCL_EVENT_CONNECT_REQ_ACCEPTED;
Keith Burns (alagalah)12756512018-03-06 05:55:27 -08004090 vep_session->poll_reg =
4091 vce_register_handler (&vcm->event_thread, &evk,
Keith Burns (alagalah)0d2b0d52018-03-06 15:55:22 -08004092 vce_poll_wait_connect_request_handler_fn,
4093 0 /* No callback args */ );
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08004094 }
Dave Wallacef7f809c2017-10-03 01:48:42 -04004095 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05004096 clib_warning ("VCL<%d>: EPOLL_CTL_ADD: vep_idx %u, "
4097 "sid %u, events 0x%x, data 0x%llx!",
4098 getpid (), vep_idx, session_index,
Dave Wallacef7f809c2017-10-03 01:48:42 -04004099 event->events, event->data.u64);
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004100 if (VPPCOM_DEBUG > 0)
4101 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08004102 /* *INDENT-OFF* */
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004103 ELOG_TYPE_DECLARE (e) =
4104 {
4105 .format = "epoll_ctladd: events:%x data:%x",
4106 .format_args = "i4i4i8",
4107 };
4108 struct
4109 {
4110 u32 events;
4111 u64 event_data;
4112 } *ed;
4113
4114 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4115
4116 ed->events = event->events;
4117 ed->event_data = event->data.u64;
4118 /* *INDENT-ON* */
4119 }
Dave Wallacef7f809c2017-10-03 01:48:42 -04004120 break;
4121
4122 case EPOLL_CTL_MOD:
4123 if (PREDICT_FALSE (!event))
4124 {
Dave Wallace048b1d62018-01-03 22:24:41 -05004125 clib_warning ("VCL<%d>: ERROR: EPOLL_CTL_MOD: NULL pointer to "
Dave Wallace2e005bb2017-11-07 01:21:39 -05004126 "epoll_event structure!", getpid ());
Dave Wallacef7f809c2017-10-03 01:48:42 -04004127 rv = VPPCOM_EINVAL;
4128 goto done;
4129 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05004130 else if (PREDICT_FALSE (!session->is_vep_session))
Dave Wallacef7f809c2017-10-03 01:48:42 -04004131 {
Dave Wallace048b1d62018-01-03 22:24:41 -05004132 clib_warning ("VCL<%d>: ERROR: sid %u EPOLL_CTL_MOD: "
Dave Wallace4878cbe2017-11-21 03:45:09 -05004133 "not a vep session!", getpid (), session_index);
4134 rv = VPPCOM_EINVAL;
4135 goto done;
4136 }
4137 else if (PREDICT_FALSE (session->vep.vep_idx != vep_idx))
4138 {
Dave Wallace048b1d62018-01-03 22:24:41 -05004139 clib_warning ("VCL<%d>: ERROR: sid %u EPOLL_CTL_MOD: "
Dave Wallace4878cbe2017-11-21 03:45:09 -05004140 "vep_idx (%u) != vep_idx (%u)!",
4141 getpid (), session_index,
4142 session->vep.vep_idx, vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04004143 rv = VPPCOM_EINVAL;
4144 goto done;
4145 }
4146 session->vep.et_mask = VEP_DEFAULT_ET_MASK;
4147 session->vep.ev = *event;
4148 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05004149 clib_warning
4150 ("VCL<%d>: EPOLL_CTL_MOD: vep_idx %u, sid %u, events 0x%x,"
4151 " data 0x%llx!", getpid (), vep_idx, session_index, event->events,
4152 event->data.u64);
Dave Wallacef7f809c2017-10-03 01:48:42 -04004153 break;
4154
4155 case EPOLL_CTL_DEL:
Dave Wallace4878cbe2017-11-21 03:45:09 -05004156 if (PREDICT_FALSE (!session->is_vep_session))
Dave Wallacef7f809c2017-10-03 01:48:42 -04004157 {
Dave Wallace048b1d62018-01-03 22:24:41 -05004158 clib_warning ("VCL<%d>: ERROR: sid %u EPOLL_CTL_DEL: "
Dave Wallace4878cbe2017-11-21 03:45:09 -05004159 "not a vep session!", getpid (), session_index);
4160 rv = VPPCOM_EINVAL;
4161 goto done;
4162 }
4163 else if (PREDICT_FALSE (session->vep.vep_idx != vep_idx))
4164 {
Dave Wallace048b1d62018-01-03 22:24:41 -05004165 clib_warning ("VCL<%d>: ERROR: sid %u EPOLL_CTL_DEL: "
Dave Wallace4878cbe2017-11-21 03:45:09 -05004166 "vep_idx (%u) != vep_idx (%u)!",
4167 getpid (), session_index,
4168 session->vep.vep_idx, vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04004169 rv = VPPCOM_EINVAL;
4170 goto done;
4171 }
4172
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08004173 /* VCL Event Un-register handler */
Keith Burns (alagalah)12756512018-03-06 05:55:27 -08004174 if ((session->state & STATE_LISTEN) && vep_session->poll_reg)
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08004175 {
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08004176 (void) vce_unregister_handler (&vcm->event_thread,
4177 vep_session->poll_reg);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08004178 }
4179
Dave Wallacef7f809c2017-10-03 01:48:42 -04004180 vep_session->wait_cont_idx =
4181 (vep_session->wait_cont_idx == session_index) ?
4182 session->vep.next_sid : vep_session->wait_cont_idx;
4183
4184 if (session->vep.prev_sid == vep_idx)
4185 vep_session->vep.next_sid = session->vep.next_sid;
4186 else
4187 {
4188 session_t *prev_session;
4189 rv = vppcom_session_at_index (session->vep.prev_sid, &prev_session);
4190 if (PREDICT_FALSE (rv))
4191 {
Dave Wallace048b1d62018-01-03 22:24:41 -05004192 clib_warning ("VCL<%d>: ERROR: EPOLL_CTL_DEL: Invalid "
Dave Wallace4878cbe2017-11-21 03:45:09 -05004193 "vep.prev_sid (%u) on sid (%u)!",
4194 getpid (), session->vep.prev_sid, session_index);
Dave Wallacef7f809c2017-10-03 01:48:42 -04004195 goto done;
4196 }
4197 ASSERT (prev_session->vep.next_sid == session_index);
4198 prev_session->vep.next_sid = session->vep.next_sid;
4199 }
4200 if (session->vep.next_sid != ~0)
4201 {
4202 session_t *next_session;
4203 rv = vppcom_session_at_index (session->vep.next_sid, &next_session);
4204 if (PREDICT_FALSE (rv))
4205 {
Dave Wallace048b1d62018-01-03 22:24:41 -05004206 clib_warning ("VCL<%d>: ERROR: EPOLL_CTL_DEL: Invalid "
Dave Wallace4878cbe2017-11-21 03:45:09 -05004207 "vep.next_sid (%u) on sid (%u)!",
4208 getpid (), session->vep.next_sid, session_index);
Dave Wallacef7f809c2017-10-03 01:48:42 -04004209 goto done;
4210 }
4211 ASSERT (next_session->vep.prev_sid == session_index);
4212 next_session->vep.prev_sid = session->vep.prev_sid;
4213 }
4214
4215 memset (&session->vep, 0, sizeof (session->vep));
4216 session->vep.next_sid = ~0;
4217 session->vep.prev_sid = ~0;
4218 session->vep.vep_idx = ~0;
4219 session->is_vep_session = 0;
4220 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05004221 clib_warning ("VCL<%d>: EPOLL_CTL_DEL: vep_idx %u, sid %u!",
Dave Wallace2e005bb2017-11-07 01:21:39 -05004222 getpid (), vep_idx, session_index);
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004223 if (VPPCOM_DEBUG > 0)
4224 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08004225 /* *INDENT-OFF* */
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004226 ELOG_TYPE_DECLARE (e) =
4227 {
4228 .format = "epoll_ctldel: vep:%d",
4229 .format_args = "i4",
4230 };
4231 struct
4232 {
4233 u32 data;
4234 } *ed;
4235
4236 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4237
4238 ed->data = vep_idx;
4239 /* *INDENT-ON* */
4240 }
Dave Wallacef7f809c2017-10-03 01:48:42 -04004241 break;
4242
4243 default:
Dave Wallace048b1d62018-01-03 22:24:41 -05004244 clib_warning ("VCL<%d>: ERROR: Invalid operation (%d)!", getpid (), op);
Dave Wallacef7f809c2017-10-03 01:48:42 -04004245 rv = VPPCOM_EINVAL;
4246 }
4247
4248 vep_verify_epoll_chain (vep_idx);
4249
4250done:
4251 clib_spinlock_unlock (&vcm->sessions_lockp);
4252 return rv;
4253}
4254
Dave Wallacef7f809c2017-10-03 01:48:42 -04004255int
4256vppcom_epoll_wait (uint32_t vep_idx, struct epoll_event *events,
4257 int maxevents, double wait_for_time)
4258{
Dave Wallacef7f809c2017-10-03 01:48:42 -04004259 session_t *vep_session;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08004260 elog_track_t vep_elog_track;
Dave Wallacef7f809c2017-10-03 01:48:42 -04004261 int rv;
4262 f64 timeout = clib_time_now (&vcm->clib_time) + wait_for_time;
Dave Wallace2e005bb2017-11-07 01:21:39 -05004263 u32 keep_trying = 1;
Dave Wallacef7f809c2017-10-03 01:48:42 -04004264 int num_ev = 0;
4265 u32 vep_next_sid, wait_cont_idx;
4266 u8 is_vep;
4267
4268 if (PREDICT_FALSE (maxevents <= 0))
4269 {
Dave Wallace048b1d62018-01-03 22:24:41 -05004270 clib_warning ("VCL<%d>: ERROR: Invalid maxevents (%d)!",
Dave Wallace4878cbe2017-11-21 03:45:09 -05004271 getpid (), maxevents);
Dave Wallacef7f809c2017-10-03 01:48:42 -04004272 return VPPCOM_EINVAL;
4273 }
Dave Wallacef7f809c2017-10-03 01:48:42 -04004274 memset (events, 0, sizeof (*events) * maxevents);
4275
4276 VCL_LOCK_AND_GET_SESSION (vep_idx, &vep_session);
4277 vep_next_sid = vep_session->vep.next_sid;
4278 is_vep = vep_session->is_vep;
4279 wait_cont_idx = vep_session->wait_cont_idx;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08004280 vep_elog_track = vep_session->elog_track;
Dave Wallacef7f809c2017-10-03 01:48:42 -04004281 clib_spinlock_unlock (&vcm->sessions_lockp);
4282
4283 if (PREDICT_FALSE (!is_vep))
4284 {
Dave Wallace048b1d62018-01-03 22:24:41 -05004285 clib_warning ("VCL<%d>: ERROR: vep_idx (%u) is not a vep!",
Dave Wallace4878cbe2017-11-21 03:45:09 -05004286 getpid (), vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04004287 rv = VPPCOM_EINVAL;
4288 goto done;
4289 }
Dave Wallacee695cb42017-11-02 22:04:42 -04004290 if (PREDICT_FALSE (vep_next_sid == ~0))
Dave Wallacef7f809c2017-10-03 01:48:42 -04004291 {
Dave Wallace69d01192018-02-22 16:22:09 -05004292 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05004293 clib_warning ("VCL<%d>: WARNING: vep_idx (%u) is empty!",
Dave Wallace2e005bb2017-11-07 01:21:39 -05004294 getpid (), vep_idx);
Dave Wallace69d01192018-02-22 16:22:09 -05004295 if (VPPCOM_DEBUG > 1)
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004296 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08004297 /* *INDENT-OFF* */
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004298 ELOG_TYPE_DECLARE (e) =
4299 {
4300 .format = "WRN: vep_idx:%d empty",
4301 .format_args = "i4",
4302 };
4303 struct
4304 {
4305 u32 data;
4306 } *ed;
4307
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08004308 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, vep_elog_track);
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004309
4310 ed->data = vep_idx;
4311 /* *INDENT-ON* */
4312 }
Dave Wallacef7f809c2017-10-03 01:48:42 -04004313 goto done;
4314 }
4315
4316 do
4317 {
4318 u32 sid;
4319 u32 next_sid = ~0;
4320 session_t *session;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08004321 elog_track_t session_elog_track;
Dave Wallacef7f809c2017-10-03 01:48:42 -04004322
4323 for (sid = (wait_cont_idx == ~0) ? vep_next_sid : wait_cont_idx;
4324 sid != ~0; sid = next_sid)
4325 {
4326 u32 session_events, et_mask, clear_et_mask, session_vep_idx;
4327 u8 add_event, is_vep_session;
4328 int ready;
4329 u64 session_ev_data;
4330
4331 VCL_LOCK_AND_GET_SESSION (sid, &session);
4332 next_sid = session->vep.next_sid;
4333 session_events = session->vep.ev.events;
4334 et_mask = session->vep.et_mask;
4335 is_vep = session->is_vep;
4336 is_vep_session = session->is_vep_session;
4337 session_vep_idx = session->vep.vep_idx;
4338 session_ev_data = session->vep.ev.data.u64;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08004339
4340 if (VPPCOM_DEBUG > 0)
4341 {
4342 session_elog_track = session->elog_track;
4343 }
4344
Dave Wallacef7f809c2017-10-03 01:48:42 -04004345 clib_spinlock_unlock (&vcm->sessions_lockp);
4346
4347 if (PREDICT_FALSE (is_vep))
4348 {
4349 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05004350 clib_warning ("VCL<%d>: ERROR: sid (%u) is a vep!",
Dave Wallace2e005bb2017-11-07 01:21:39 -05004351 getpid (), vep_idx);
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004352 if (VPPCOM_DEBUG > 0)
4353 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08004354 /* *INDENT-OFF* */
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004355 ELOG_TYPE_DECLARE (e) =
4356 {
4357 .format = "ERR:vep_idx:%d is vep",
4358 .format_args = "i4",
4359 };
4360 struct
4361 {
4362 u32 data;
4363 } *ed;
4364
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08004365 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session_elog_track);
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004366
4367 ed->data = vep_idx;
4368 /* *INDENT-ON* */
4369 }
4370
Dave Wallacef7f809c2017-10-03 01:48:42 -04004371 rv = VPPCOM_EINVAL;
4372 goto done;
4373 }
4374 if (PREDICT_FALSE (!is_vep_session))
4375 {
4376 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05004377 clib_warning ("VCL<%d>: ERROR: session (%u) is not "
Dave Wallace2e005bb2017-11-07 01:21:39 -05004378 "a vep session!", getpid (), sid);
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004379 if (VPPCOM_DEBUG > 0)
4380 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08004381 /* *INDENT-OFF* */
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004382 ELOG_TYPE_DECLARE (e) =
4383 {
4384 .format = "ERR:SID:%d not vep",
4385 .format_args = "i4",
4386 };
4387 struct
4388 {
4389 u32 data;
4390 } *ed;
4391
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08004392 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session_elog_track);
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004393
4394 ed->data = sid;
4395 /* *INDENT-ON* */
4396 }
4397
Dave Wallacef7f809c2017-10-03 01:48:42 -04004398 rv = VPPCOM_EINVAL;
4399 goto done;
4400 }
4401 if (PREDICT_FALSE (session_vep_idx != vep_idx))
4402 {
Dave Wallace048b1d62018-01-03 22:24:41 -05004403 clib_warning ("VCL<%d>: ERROR: session (%u) "
Dave Wallacef7f809c2017-10-03 01:48:42 -04004404 "vep_idx (%u) != vep_idx (%u)!",
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08004405 getpid (), sid, session_vep_idx, vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04004406 rv = VPPCOM_EINVAL;
4407 goto done;
4408 }
4409
4410 add_event = clear_et_mask = 0;
4411
Dave Wallace60caa062017-11-10 17:07:13 -05004412 if (EPOLLIN & session_events)
Dave Wallacef7f809c2017-10-03 01:48:42 -04004413 {
4414 VCL_LOCK_AND_GET_SESSION (sid, &session);
4415 ready = vppcom_session_read_ready (session, sid);
4416 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace60caa062017-11-10 17:07:13 -05004417 if ((ready > 0) && (EPOLLIN & et_mask))
Dave Wallacef7f809c2017-10-03 01:48:42 -04004418 {
4419 add_event = 1;
4420 events[num_ev].events |= EPOLLIN;
Dave Wallace60caa062017-11-10 17:07:13 -05004421 if (((EPOLLET | EPOLLIN) & session_events) ==
4422 (EPOLLET | EPOLLIN))
Dave Wallacef7f809c2017-10-03 01:48:42 -04004423 clear_et_mask |= EPOLLIN;
4424 }
4425 else if (ready < 0)
4426 {
4427 add_event = 1;
4428 switch (ready)
4429 {
4430 case VPPCOM_ECONNRESET:
4431 events[num_ev].events |= EPOLLHUP | EPOLLRDHUP;
4432 break;
4433
4434 default:
4435 events[num_ev].events |= EPOLLERR;
4436 break;
4437 }
4438 }
4439 }
4440
Dave Wallace60caa062017-11-10 17:07:13 -05004441 if (EPOLLOUT & session_events)
Dave Wallacef7f809c2017-10-03 01:48:42 -04004442 {
4443 VCL_LOCK_AND_GET_SESSION (sid, &session);
4444 ready = vppcom_session_write_ready (session, sid);
4445 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace60caa062017-11-10 17:07:13 -05004446 if ((ready > 0) && (EPOLLOUT & et_mask))
Dave Wallacef7f809c2017-10-03 01:48:42 -04004447 {
4448 add_event = 1;
4449 events[num_ev].events |= EPOLLOUT;
Dave Wallace60caa062017-11-10 17:07:13 -05004450 if (((EPOLLET | EPOLLOUT) & session_events) ==
4451 (EPOLLET | EPOLLOUT))
Dave Wallacef7f809c2017-10-03 01:48:42 -04004452 clear_et_mask |= EPOLLOUT;
4453 }
4454 else if (ready < 0)
4455 {
4456 add_event = 1;
4457 switch (ready)
4458 {
4459 case VPPCOM_ECONNRESET:
4460 events[num_ev].events |= EPOLLHUP;
4461 break;
4462
4463 default:
4464 events[num_ev].events |= EPOLLERR;
4465 break;
4466 }
4467 }
4468 }
4469
4470 if (add_event)
4471 {
4472 events[num_ev].data.u64 = session_ev_data;
4473 if (EPOLLONESHOT & session_events)
4474 {
4475 VCL_LOCK_AND_GET_SESSION (sid, &session);
4476 session->vep.ev.events = 0;
4477 clib_spinlock_unlock (&vcm->sessions_lockp);
4478 }
4479 num_ev++;
4480 if (num_ev == maxevents)
4481 {
4482 VCL_LOCK_AND_GET_SESSION (vep_idx, &vep_session);
4483 vep_session->wait_cont_idx = next_sid;
4484 clib_spinlock_unlock (&vcm->sessions_lockp);
4485 goto done;
4486 }
4487 }
4488 if (wait_cont_idx != ~0)
4489 {
4490 if (next_sid == ~0)
4491 next_sid = vep_next_sid;
4492 else if (next_sid == wait_cont_idx)
4493 next_sid = ~0;
4494 }
4495 }
Dave Wallace2e005bb2017-11-07 01:21:39 -05004496 if (wait_for_time != -1)
4497 keep_trying = (clib_time_now (&vcm->clib_time) <= timeout) ? 1 : 0;
Dave Wallacef7f809c2017-10-03 01:48:42 -04004498 }
Dave Wallace2e005bb2017-11-07 01:21:39 -05004499 while ((num_ev == 0) && keep_trying);
Dave Wallacef7f809c2017-10-03 01:48:42 -04004500
4501 if (wait_cont_idx != ~0)
4502 {
4503 VCL_LOCK_AND_GET_SESSION (vep_idx, &vep_session);
4504 vep_session->wait_cont_idx = ~0;
4505 clib_spinlock_unlock (&vcm->sessions_lockp);
4506 }
4507done:
4508 return (rv != VPPCOM_OK) ? rv : num_ev;
4509}
4510
Dave Wallace35830af2017-10-09 01:43:42 -04004511int
4512vppcom_session_attr (uint32_t session_index, uint32_t op,
4513 void *buffer, uint32_t * buflen)
4514{
Dave Wallace35830af2017-10-09 01:43:42 -04004515 session_t *session;
4516 int rv = VPPCOM_OK;
4517 u32 *flags = buffer;
Steven2199aab2017-10-15 20:18:47 -07004518 vppcom_endpt_t *ep = buffer;
Dave Wallace35830af2017-10-09 01:43:42 -04004519
4520 VCL_LOCK_AND_GET_SESSION (session_index, &session);
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08004521
4522 ASSERT (session);
4523
Dave Wallace35830af2017-10-09 01:43:42 -04004524 switch (op)
4525 {
4526 case VPPCOM_ATTR_GET_NREAD:
4527 rv = vppcom_session_read_ready (session, session_index);
Dave Wallace227867f2017-11-13 21:21:53 -05004528 if (VPPCOM_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05004529 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_NREAD: sid %u, nread = %d",
Dave Wallace2e005bb2017-11-07 01:21:39 -05004530 getpid (), rv);
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004531 if (VPPCOM_DEBUG > 0)
4532 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08004533 /* *INDENT-OFF* */
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004534 ELOG_TYPE_DECLARE (e) =
4535 {
4536 .format = "VPPCOM_ATTR_GET_NREAD: nread=%d",
4537 .format_args = "i4",
4538 };
4539 struct
4540 {
4541 u32 data;
4542 } *ed;
4543
4544 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4545
4546 ed->data = rv;
4547 /* *INDENT-ON* */
4548 }
4549
Dave Wallace35830af2017-10-09 01:43:42 -04004550 break;
4551
Dave Wallace227867f2017-11-13 21:21:53 -05004552 case VPPCOM_ATTR_GET_NWRITE:
4553 rv = vppcom_session_write_ready (session, session_index);
4554 if (VPPCOM_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05004555 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_NWRITE: sid %u, nwrite = %d",
Dave Wallace227867f2017-11-13 21:21:53 -05004556 getpid (), session_index, rv);
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004557 if (VPPCOM_DEBUG > 0)
4558 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08004559 /* *INDENT-OFF* */
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004560 ELOG_TYPE_DECLARE (e) =
4561 {
4562 .format = "VPPCOM_ATTR_GET_NWRITE: nwrite=%d",
4563 .format_args = "i4",
4564 };
4565 struct
4566 {
4567 u32 data;
4568 } *ed;
4569
4570 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4571
4572 ed->data = rv;
4573 /* *INDENT-ON* */
4574 }
Dave Wallace35830af2017-10-09 01:43:42 -04004575 break;
4576
4577 case VPPCOM_ATTR_GET_FLAGS:
Dave Wallace048b1d62018-01-03 22:24:41 -05004578 if (PREDICT_TRUE (buffer && buflen && (*buflen >= sizeof (*flags))))
Dave Wallace35830af2017-10-09 01:43:42 -04004579 {
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08004580 *flags = O_RDWR | (VCL_SESS_ATTR_TEST (session->attr,
4581 VCL_SESS_ATTR_NONBLOCK));
Dave Wallace35830af2017-10-09 01:43:42 -04004582 *buflen = sizeof (*flags);
Dave Wallace227867f2017-11-13 21:21:53 -05004583 if (VPPCOM_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05004584 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_FLAGS: sid %u, "
Dave Wallace227867f2017-11-13 21:21:53 -05004585 "flags = 0x%08x, is_nonblocking = %u", getpid (),
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08004586 session_index, *flags,
4587 VCL_SESS_ATTR_TEST (session->attr,
4588 VCL_SESS_ATTR_NONBLOCK));
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004589 if (VPPCOM_DEBUG > 0)
4590 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08004591 /* *INDENT-OFF* */
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004592 ELOG_TYPE_DECLARE (e) =
4593 {
4594 .format = "VPPCOM_ATTR_GET_FLAGS: flags=%x is_nonblk=%d",
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004595 .format_args = "i4i4",
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004596 };
4597 struct
4598 {
4599 u32 flags;
4600 u32 is_nonblk;
4601 } *ed;
4602
4603 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4604
4605 ed->flags = *flags;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08004606 ed->is_nonblk = VCL_SESS_ATTR_TEST (session->attr, VCL_SESS_ATTR_NONBLOCK);
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004607 /* *INDENT-ON* */
4608 }
4609
Dave Wallace35830af2017-10-09 01:43:42 -04004610 }
4611 else
4612 rv = VPPCOM_EINVAL;
4613 break;
4614
4615 case VPPCOM_ATTR_SET_FLAGS:
Dave Wallace048b1d62018-01-03 22:24:41 -05004616 if (PREDICT_TRUE (buffer && buflen && (*buflen == sizeof (*flags))))
Dave Wallace35830af2017-10-09 01:43:42 -04004617 {
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08004618 if (*flags & O_NONBLOCK)
4619 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_NONBLOCK);
4620 else
4621 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_NONBLOCK);
4622
Dave Wallace227867f2017-11-13 21:21:53 -05004623 if (VPPCOM_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05004624 clib_warning ("VCL<%d>: VPPCOM_ATTR_SET_FLAGS: sid %u, "
Dave Wallace227867f2017-11-13 21:21:53 -05004625 "flags = 0x%08x, is_nonblocking = %u",
Dave Wallace4878cbe2017-11-21 03:45:09 -05004626 getpid (), session_index, *flags,
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08004627 VCL_SESS_ATTR_TEST (session->attr,
4628 VCL_SESS_ATTR_NONBLOCK));
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004629 if (VPPCOM_DEBUG > 0)
4630 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08004631 /* *INDENT-OFF* */
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004632 ELOG_TYPE_DECLARE (e) =
4633 {
4634 .format = "VPPCOM_ATTR_SET_FLAGS: flags=%x is_nonblk=%d",
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004635 .format_args = "i4i4",
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004636 };
4637 struct
4638 {
4639 u32 flags;
4640 u32 is_nonblk;
4641 } *ed;
4642
4643 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4644
4645 ed->flags = *flags;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08004646 ed->is_nonblk = VCL_SESS_ATTR_TEST (session->attr, VCL_SESS_ATTR_NONBLOCK);
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004647 /* *INDENT-ON* */
4648 }
Dave Wallace35830af2017-10-09 01:43:42 -04004649 }
4650 else
4651 rv = VPPCOM_EINVAL;
4652 break;
4653
4654 case VPPCOM_ATTR_GET_PEER_ADDR:
Dave Wallace048b1d62018-01-03 22:24:41 -05004655 if (PREDICT_TRUE (buffer && buflen &&
4656 (*buflen >= sizeof (*ep)) && ep->ip))
Dave Wallace35830af2017-10-09 01:43:42 -04004657 {
Steven2199aab2017-10-15 20:18:47 -07004658 ep->is_ip4 = session->peer_addr.is_ip4;
Stevenac1f96d2017-10-24 16:03:58 -07004659 ep->port = session->peer_port;
Steven2199aab2017-10-15 20:18:47 -07004660 if (session->peer_addr.is_ip4)
4661 clib_memcpy (ep->ip, &session->peer_addr.ip46.ip4,
4662 sizeof (ip4_address_t));
4663 else
4664 clib_memcpy (ep->ip, &session->peer_addr.ip46.ip6,
4665 sizeof (ip6_address_t));
4666 *buflen = sizeof (*ep);
Dave Wallacefaf9d772017-10-26 16:12:04 -04004667 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05004668 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_PEER_ADDR: sid %u, "
4669 "is_ip4 = %u, addr = %U, port %u", getpid (),
Dave Wallace774169b2017-11-01 20:07:40 -04004670 session_index, ep->is_ip4, format_ip46_address,
Dave Wallacede910062018-03-20 09:22:13 -04004671 &session->peer_addr.ip46,
4672 ep->is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6,
Stevenac1f96d2017-10-24 16:03:58 -07004673 clib_net_to_host_u16 (ep->port));
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004674 if (VPPCOM_DEBUG > 0)
4675 {
4676 if (ep->is_ip4)
4677 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08004678 /* *INDENT-OFF* */
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004679 ELOG_TYPE_DECLARE (e) =
4680 {
4681 .format = "VPPCOM_ATTR_GET_PEER_ADDR: addr:%d.%d.%d.%d:%d",
4682 .format_args = "i1i1i1i1i2",
4683 };
4684 CLIB_PACKED (struct {
4685 u8 addr[4]; //4
4686 u16 port; //2
4687 }) * ed;
4688
4689 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4690
4691 ed->addr[0] = session->peer_addr.ip46.ip4.as_u8[0];
4692 ed->addr[1] = session->peer_addr.ip46.ip4.as_u8[1];
4693 ed->addr[2] = session->peer_addr.ip46.ip4.as_u8[2];
4694 ed->addr[3] = session->peer_addr.ip46.ip4.as_u8[3];
4695 ed->port = clib_net_to_host_u16 (session->peer_port);
4696 /* *INDENT-ON* */
4697 }
4698 else
4699 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08004700 /* *INDENT-OFF* */
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004701 ELOG_TYPE_DECLARE (e) =
4702 {
4703 .format = "VPPCOM_ATTR_GET_PEER_ADDR: addr:IP6:%d",
4704 .format_args = "i2",
4705 };
4706 CLIB_PACKED (struct {
4707 u16 port; //2
4708 }) * ed;
4709
4710 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4711
4712 ed->port = clib_net_to_host_u16 (session->peer_port);
4713 /* *INDENT-ON* */
4714 }
4715 }
Dave Wallace35830af2017-10-09 01:43:42 -04004716 }
4717 else
4718 rv = VPPCOM_EINVAL;
4719 break;
4720
4721 case VPPCOM_ATTR_GET_LCL_ADDR:
Dave Wallace048b1d62018-01-03 22:24:41 -05004722 if (PREDICT_TRUE (buffer && buflen &&
4723 (*buflen >= sizeof (*ep)) && ep->ip))
Dave Wallace35830af2017-10-09 01:43:42 -04004724 {
Steven2199aab2017-10-15 20:18:47 -07004725 ep->is_ip4 = session->lcl_addr.is_ip4;
Stevenac1f96d2017-10-24 16:03:58 -07004726 ep->port = session->lcl_port;
Steven2199aab2017-10-15 20:18:47 -07004727 if (session->lcl_addr.is_ip4)
4728 clib_memcpy (ep->ip, &session->lcl_addr.ip46.ip4,
4729 sizeof (ip4_address_t));
4730 else
4731 clib_memcpy (ep->ip, &session->lcl_addr.ip46.ip6,
4732 sizeof (ip6_address_t));
4733 *buflen = sizeof (*ep);
Dave Wallacefaf9d772017-10-26 16:12:04 -04004734 if (VPPCOM_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05004735 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_LCL_ADDR: sid %u, "
4736 "is_ip4 = %u, addr = %U port %d", getpid (),
Dave Wallace774169b2017-11-01 20:07:40 -04004737 session_index, ep->is_ip4, format_ip46_address,
Dave Wallacede910062018-03-20 09:22:13 -04004738 &session->lcl_addr.ip46,
4739 ep->is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6,
Stevenac1f96d2017-10-24 16:03:58 -07004740 clib_net_to_host_u16 (ep->port));
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004741 if (VPPCOM_DEBUG > 0)
4742 {
4743 if (ep->is_ip4)
4744 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08004745 /* *INDENT-OFF* */
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004746 ELOG_TYPE_DECLARE (e) =
4747 {
4748 .format = "VPPCOM_ATTR_GET_LCL_ADDR: addr:%d.%d.%d.%d:%d",
4749 .format_args = "i1i1i1i1i2",
4750 };
4751 CLIB_PACKED (struct {
4752 u8 addr[4]; //4
4753 u16 port; //2
4754 }) * ed;
4755
4756 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4757
4758 ed->addr[0] = session->lcl_addr.ip46.ip4.as_u8[0];
4759 ed->addr[1] = session->lcl_addr.ip46.ip4.as_u8[1];
4760 ed->addr[2] = session->lcl_addr.ip46.ip4.as_u8[2];
4761 ed->addr[3] = session->lcl_addr.ip46.ip4.as_u8[3];
4762 ed->port = clib_net_to_host_u16 (session->peer_port);
4763 /* *INDENT-ON* */
4764 }
4765 else
4766 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08004767 /* *INDENT-OFF* */
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004768 ELOG_TYPE_DECLARE (e) =
4769 {
4770 .format = "VPPCOM_ATTR_GET_LCL_ADDR: addr:IP6:%d",
4771 .format_args = "i2",
4772 };
4773 CLIB_PACKED (struct {
4774 u16 port; //2
4775 }) * ed;
4776
4777 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4778
4779 ed->port = clib_net_to_host_u16 (session->peer_port);
4780 /* *INDENT-ON* */
4781 }
4782 }
Dave Wallace35830af2017-10-09 01:43:42 -04004783 }
4784 else
4785 rv = VPPCOM_EINVAL;
4786 break;
Stevenb5a11602017-10-11 09:59:30 -07004787
Dave Wallace048b1d62018-01-03 22:24:41 -05004788 case VPPCOM_ATTR_GET_LIBC_EPFD:
4789 rv = session->libc_epfd;
4790 if (VPPCOM_DEBUG > 2)
4791 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_LIBC_EPFD: libc_epfd %d",
4792 getpid (), rv);
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004793 if (VPPCOM_DEBUG > 0)
4794 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08004795 /* *INDENT-OFF* */
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004796 ELOG_TYPE_DECLARE (e) =
4797 {
Florin Corasbb16d3f2018-01-29 08:55:25 -08004798 .format = "VPPCOM_ATTR_GET_LIBC_EPFD: libc_epfd=%d",
4799 .format_args = "i4",
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004800 };
4801 CLIB_PACKED (struct {
Florin Corasbb16d3f2018-01-29 08:55:25 -08004802 i32 data;
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08004803 }) *ed;
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004804
4805 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
Florin Corasbb16d3f2018-01-29 08:55:25 -08004806 ed->data = session->libc_epfd;
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004807 /* *INDENT-ON* */
4808 }
4809
Dave Wallace048b1d62018-01-03 22:24:41 -05004810 break;
4811
4812 case VPPCOM_ATTR_SET_LIBC_EPFD:
4813 if (PREDICT_TRUE (buffer && buflen &&
4814 (*buflen == sizeof (session->libc_epfd))))
4815 {
4816 session->libc_epfd = *(int *) buffer;
4817 *buflen = sizeof (session->libc_epfd);
4818
4819 if (VPPCOM_DEBUG > 2)
4820 clib_warning ("VCL<%d>: VPPCOM_ATTR_SET_LIBC_EPFD: libc_epfd %d, "
4821 "buflen %d", getpid (), session->libc_epfd,
4822 *buflen);
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004823 if (VPPCOM_DEBUG > 0)
4824 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08004825 /* *INDENT-OFF* */
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004826 ELOG_TYPE_DECLARE (e) =
4827 {
4828 .format = "VPPCOM_ATTR_SET_LIBC_EPFD: libc_epfd=%s%d buflen=%d",
4829 .format_args = "t1i4i4",
4830 .n_enum_strings = 2,
4831 .enum_strings = {"", "-",},
4832 };
4833 CLIB_PACKED (struct {
4834 u8 sign;
4835 u32 data[2];
4836 }) * ed;
4837
4838 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4839
4840 ed->sign = (session->libc_epfd < 0);
4841 ed->data[0] = abs(session->libc_epfd);
4842 ed->data[1] = *buflen;
4843 /* *INDENT-ON* */
4844 }
Dave Wallace048b1d62018-01-03 22:24:41 -05004845 }
4846 else
4847 rv = VPPCOM_EINVAL;
4848 break;
4849
4850 case VPPCOM_ATTR_GET_PROTOCOL:
4851 if (buffer && buflen && (*buflen >= sizeof (int)))
4852 {
4853 *(int *) buffer = session->proto;
4854 *buflen = sizeof (int);
4855
4856 if (VPPCOM_DEBUG > 2)
4857 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_PROTOCOL: %d (%s), "
4858 "buflen %d", getpid (), *(int *) buffer,
4859 *(int *) buffer ? "UDP" : "TCP", *buflen);
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004860 if (VPPCOM_DEBUG > 0)
4861 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08004862 /* *INDENT-OFF* */
Keith Burns (alagalah)504a71f2018-01-17 15:16:32 -08004863 ELOG_TYPE_DECLARE (e) =
4864 {
4865 .format = "VPPCOM_ATTR_GET_PROTOCOL: %s buflen=%d",
4866 .format_args = "t1i4",
4867 .n_enum_strings = 2,
4868 .enum_strings = {"TCP", "UDP",},
4869 };
4870
4871 CLIB_PACKED (struct {
4872 u8 proto;
4873 u32 buflen;
4874 }) * ed;
4875
4876 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4877 ed->proto = session->proto;
4878 ed->buflen = *(int *) buffer;
4879 /* *INDENT-ON* */
4880 }
Dave Wallace048b1d62018-01-03 22:24:41 -05004881 }
4882 else
4883 rv = VPPCOM_EINVAL;
4884 break;
4885
4886 case VPPCOM_ATTR_GET_LISTEN:
4887 if (buffer && buflen && (*buflen >= sizeof (int)))
4888 {
4889 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
4890 VCL_SESS_ATTR_LISTEN);
4891 *buflen = sizeof (int);
4892
4893 if (VPPCOM_DEBUG > 2)
4894 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_LISTEN: %d, "
4895 "buflen %d", getpid (), *(int *) buffer, *buflen);
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004896 if (VPPCOM_DEBUG > 0)
4897 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08004898 /* *INDENT-OFF* */
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004899 ELOG_TYPE_DECLARE (e) =
4900 {
4901 .format = "VPPCOM_ATTR_GET_LISTEN: %d buflen=%d",
4902 .format_args = "i4i4",
4903 };
4904
4905 struct {
4906 u32 data[2];
4907 } * ed;
4908
4909 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4910 ed->data[0] = *(int *) buffer;
4911 ed->data[1] = *buflen;
4912 /* *INDENT-ON* */
4913 }
Dave Wallace048b1d62018-01-03 22:24:41 -05004914 }
4915 else
4916 rv = VPPCOM_EINVAL;
4917 break;
4918
4919 case VPPCOM_ATTR_GET_ERROR:
4920 if (buffer && buflen && (*buflen >= sizeof (int)))
4921 {
4922 *(int *) buffer = 0;
4923 *buflen = sizeof (int);
4924
4925 if (VPPCOM_DEBUG > 2)
4926 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_ERROR: %d, "
4927 "buflen %d, #VPP-TBD#", getpid (),
4928 *(int *) buffer, *buflen);
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004929 if (VPPCOM_DEBUG > 0)
4930 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08004931 /* *INDENT-OFF* */
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004932 ELOG_TYPE_DECLARE (e) =
4933 {
4934 .format = "VPPCOM_ATTR_GET_ERROR: %d buflen=%d",
4935 .format_args = "i4i4",
4936 };
4937
4938 struct {
4939 u32 data[2];
4940 } * ed;
4941
4942 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4943 ed->data[0] = *(int *) buffer;
4944 ed->data[1] = *buflen;
4945 /* *INDENT-ON* */
4946 }
Dave Wallace048b1d62018-01-03 22:24:41 -05004947 }
4948 else
4949 rv = VPPCOM_EINVAL;
4950 break;
4951
4952 case VPPCOM_ATTR_GET_TX_FIFO_LEN:
4953 if (buffer && buflen && (*buflen >= sizeof (u32)))
4954 {
Dave Wallace048b1d62018-01-03 22:24:41 -05004955
4956 /* VPP-TBD */
4957 *(size_t *) buffer = (session->sndbuf_size ? session->sndbuf_size :
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08004958 session->tx_fifo ? session->tx_fifo->nitems :
Dave Wallace048b1d62018-01-03 22:24:41 -05004959 vcm->cfg.tx_fifo_size);
4960 *buflen = sizeof (u32);
4961
4962 if (VPPCOM_DEBUG > 2)
4963 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_TX_FIFO_LEN: %u (0x%x), "
4964 "buflen %d, #VPP-TBD#", getpid (),
4965 *(size_t *) buffer, *(size_t *) buffer, *buflen);
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004966 if (VPPCOM_DEBUG > 0)
4967 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08004968 /* *INDENT-OFF* */
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004969 ELOG_TYPE_DECLARE (e) =
4970 {
4971 .format = "VPPCOM_ATTR_GET_TX_FIFO_LEN: 0x%x buflen=%d",
4972 .format_args = "i4i4",
4973 };
4974
4975 struct {
4976 u32 data[2];
4977 } * ed;
4978
4979 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
4980 ed->data[0] = *(size_t *) buffer;
4981 ed->data[1] = *buflen;
4982 /* *INDENT-ON* */
4983 }
Dave Wallace048b1d62018-01-03 22:24:41 -05004984 }
4985 else
4986 rv = VPPCOM_EINVAL;
4987 break;
4988
4989 case VPPCOM_ATTR_SET_TX_FIFO_LEN:
4990 if (buffer && buflen && (*buflen == sizeof (u32)))
4991 {
4992 /* VPP-TBD */
4993 session->sndbuf_size = *(u32 *) buffer;
4994 if (VPPCOM_DEBUG > 2)
4995 clib_warning ("VCL<%d>: VPPCOM_ATTR_SET_TX_FIFO_LEN: %u (0x%x), "
4996 "buflen %d, #VPP-TBD#", getpid (),
4997 session->sndbuf_size, session->sndbuf_size,
4998 *buflen);
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08004999 if (VPPCOM_DEBUG > 0)
5000 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08005001 /* *INDENT-OFF* */
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08005002 ELOG_TYPE_DECLARE (e) =
5003 {
5004 .format = "VPPCOM_ATTR_SET_TX_FIFO_LEN: 0x%x buflen=%d",
5005 .format_args = "i4i4",
5006 };
5007
5008 struct {
5009 u32 data[2];
5010 } * ed;
5011
5012 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
5013 ed->data[0] = session->sndbuf_size;
5014 ed->data[1] = *buflen;
5015 /* *INDENT-ON* */
5016 }
Dave Wallace048b1d62018-01-03 22:24:41 -05005017 }
5018 else
5019 rv = VPPCOM_EINVAL;
5020 break;
5021
5022 case VPPCOM_ATTR_GET_RX_FIFO_LEN:
5023 if (buffer && buflen && (*buflen >= sizeof (u32)))
5024 {
Dave Wallace048b1d62018-01-03 22:24:41 -05005025
5026 /* VPP-TBD */
5027 *(size_t *) buffer = (session->rcvbuf_size ? session->rcvbuf_size :
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08005028 session->rx_fifo ? session->rx_fifo->nitems :
Dave Wallace048b1d62018-01-03 22:24:41 -05005029 vcm->cfg.rx_fifo_size);
5030 *buflen = sizeof (u32);
5031
5032 if (VPPCOM_DEBUG > 2)
5033 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_RX_FIFO_LEN: %u (0x%x), "
5034 "buflen %d, #VPP-TBD#", getpid (),
5035 *(size_t *) buffer, *(size_t *) buffer, *buflen);
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08005036 if (VPPCOM_DEBUG > 0)
5037 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08005038 /* *INDENT-OFF* */
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08005039 ELOG_TYPE_DECLARE (e) =
5040 {
5041 .format = "VPPCOM_ATTR_GET_RX_FIFO_LEN: 0x%x buflen=%d",
5042 .format_args = "i4i4",
5043 };
5044
5045 struct {
5046 u32 data[2];
5047 } * ed;
5048
5049 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
5050 ed->data[0] = *(size_t *) buffer;
5051 ed->data[1] = *buflen;
5052 /* *INDENT-ON* */
5053 }
Dave Wallace048b1d62018-01-03 22:24:41 -05005054 }
5055 else
5056 rv = VPPCOM_EINVAL;
5057 break;
5058
5059 case VPPCOM_ATTR_SET_RX_FIFO_LEN:
5060 if (buffer && buflen && (*buflen == sizeof (u32)))
5061 {
5062 /* VPP-TBD */
5063 session->rcvbuf_size = *(u32 *) buffer;
5064 if (VPPCOM_DEBUG > 2)
Dave Wallace7e2c31a2018-02-05 20:03:01 -05005065 clib_warning ("VCL<%d>: VPPCOM_ATTR_SET_RX_FIFO_LEN: %u (0x%x), "
Dave Wallace048b1d62018-01-03 22:24:41 -05005066 "buflen %d, #VPP-TBD#", getpid (),
5067 session->sndbuf_size, session->sndbuf_size,
5068 *buflen);
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08005069 if (VPPCOM_DEBUG > 0)
5070 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08005071 /* *INDENT-OFF* */
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08005072 ELOG_TYPE_DECLARE (e) =
5073 {
Dave Wallace7e2c31a2018-02-05 20:03:01 -05005074 .format = "VPPCOM_ATTR_SET_RX_FIFO_LEN: 0x%x buflen=%d",
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08005075 .format_args = "i4i4",
5076 };
5077
5078 struct {
5079 u32 data[2];
5080 } * ed;
5081
5082 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
5083 ed->data[0] = session->sndbuf_size;
5084 ed->data[1] = *buflen;
5085 /* *INDENT-ON* */
5086 }
Dave Wallace048b1d62018-01-03 22:24:41 -05005087 }
5088 else
5089 rv = VPPCOM_EINVAL;
5090 break;
5091
5092 case VPPCOM_ATTR_GET_REUSEADDR:
5093 if (buffer && buflen && (*buflen >= sizeof (int)))
5094 {
5095 /* VPP-TBD */
5096 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
5097 VCL_SESS_ATTR_REUSEADDR);
5098 *buflen = sizeof (int);
5099
5100 if (VPPCOM_DEBUG > 2)
5101 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_REUSEADDR: %d, "
5102 "buflen %d, #VPP-TBD#", getpid (), *(int *) buffer,
5103 *buflen);
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08005104 if (VPPCOM_DEBUG > 0)
5105 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08005106 /* *INDENT-OFF* */
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08005107 ELOG_TYPE_DECLARE (e) =
5108 {
5109 .format = "VPPCOM_ATTR_GET_REUSEADDR: %d buflen=%d",
5110 .format_args = "i4i4",
5111 };
5112
5113 struct {
5114 u32 data[2];
5115 } * ed;
5116
5117 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
5118 ed->data[0] = *(int *) buffer;
5119 ed->data[1] = *buflen;
5120 /* *INDENT-ON* */
5121 }
Dave Wallace048b1d62018-01-03 22:24:41 -05005122 }
5123 else
5124 rv = VPPCOM_EINVAL;
5125 break;
5126
Stevenb5a11602017-10-11 09:59:30 -07005127 case VPPCOM_ATTR_SET_REUSEADDR:
Dave Wallace048b1d62018-01-03 22:24:41 -05005128 if (buffer && buflen && (*buflen == sizeof (int)) &&
5129 !VCL_SESS_ATTR_TEST (session->attr, VCL_SESS_ATTR_LISTEN))
5130 {
5131 /* VPP-TBD */
5132 if (*(int *) buffer)
5133 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_REUSEADDR);
5134 else
5135 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_REUSEADDR);
5136
5137 if (VPPCOM_DEBUG > 2)
5138 clib_warning ("VCL<%d>: VPPCOM_ATTR_SET_REUSEADDR: %d, "
5139 "buflen %d, #VPP-TBD#", getpid (),
5140 VCL_SESS_ATTR_TEST (session->attr,
5141 VCL_SESS_ATTR_REUSEADDR),
5142 *buflen);
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08005143 if (VPPCOM_DEBUG > 0)
5144 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08005145 /* *INDENT-OFF* */
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08005146 ELOG_TYPE_DECLARE (e) =
5147 {
5148 .format = "VPPCOM_ATTR_SET_REUSEADDR: %d buflen=%d",
5149 .format_args = "i4i4",
5150 };
5151
5152 struct {
5153 u32 data[2];
5154 } * ed;
5155
5156 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
5157 ed->data[0] = VCL_SESS_ATTR_TEST (session->attr,
5158 VCL_SESS_ATTR_REUSEADDR);
5159 ed->data[1] = *buflen;
5160 /* *INDENT-ON* */
5161 }
Dave Wallace048b1d62018-01-03 22:24:41 -05005162 }
5163 else
5164 rv = VPPCOM_EINVAL;
5165 break;
5166
5167 case VPPCOM_ATTR_GET_REUSEPORT:
5168 if (buffer && buflen && (*buflen >= sizeof (int)))
5169 {
5170 /* VPP-TBD */
5171 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
5172 VCL_SESS_ATTR_REUSEPORT);
5173 *buflen = sizeof (int);
5174
5175 if (VPPCOM_DEBUG > 2)
5176 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_REUSEPORT: %d, "
5177 "buflen %d, #VPP-TBD#", getpid (), *(int *) buffer,
5178 *buflen);
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08005179 if (VPPCOM_DEBUG > 0)
5180 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08005181 /* *INDENT-OFF* */
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08005182 ELOG_TYPE_DECLARE (e) =
5183 {
5184 .format = "VPPCOM_ATTR_GET_REUSEPORT: %d buflen=%d",
5185 .format_args = "i4i4",
5186 };
5187
5188 struct {
5189 u32 data[2];
5190 } * ed;
5191
5192 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
5193 ed->data[0] = *(int *) buffer;
5194 ed->data[1] = *buflen;
5195 /* *INDENT-ON* */
5196 }
Dave Wallace048b1d62018-01-03 22:24:41 -05005197 }
5198 else
5199 rv = VPPCOM_EINVAL;
5200 break;
5201
5202 case VPPCOM_ATTR_SET_REUSEPORT:
5203 if (buffer && buflen && (*buflen == sizeof (int)) &&
5204 !VCL_SESS_ATTR_TEST (session->attr, VCL_SESS_ATTR_LISTEN))
5205 {
5206 /* VPP-TBD */
5207 if (*(int *) buffer)
5208 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_REUSEPORT);
5209 else
5210 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_REUSEPORT);
5211
5212 if (VPPCOM_DEBUG > 2)
5213 clib_warning ("VCL<%d>: VPPCOM_ATTR_SET_REUSEPORT: %d, "
5214 "buflen %d, #VPP-TBD#", getpid (),
5215 VCL_SESS_ATTR_TEST (session->attr,
5216 VCL_SESS_ATTR_REUSEPORT),
5217 *buflen);
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08005218 if (VPPCOM_DEBUG > 0)
5219 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08005220 /* *INDENT-OFF* */
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08005221 ELOG_TYPE_DECLARE (e) =
5222 {
5223 .format = "VPPCOM_ATTR_SET_REUSEPORT: %d buflen=%d",
5224 .format_args = "i4i4",
5225 };
5226
5227 struct {
5228 u32 data[2];
5229 } * ed;
5230
5231 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
5232 ed->data[0] = VCL_SESS_ATTR_TEST (session->attr,
5233 VCL_SESS_ATTR_REUSEPORT);
5234 ed->data[1] = *buflen;
5235 /* *INDENT-ON* */
5236 }
Dave Wallace048b1d62018-01-03 22:24:41 -05005237 }
5238 else
5239 rv = VPPCOM_EINVAL;
5240 break;
5241
5242 case VPPCOM_ATTR_GET_BROADCAST:
5243 if (buffer && buflen && (*buflen >= sizeof (int)))
5244 {
5245 /* VPP-TBD */
5246 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
5247 VCL_SESS_ATTR_BROADCAST);
5248 *buflen = sizeof (int);
5249
5250 if (VPPCOM_DEBUG > 2)
5251 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_BROADCAST: %d, "
5252 "buflen %d, #VPP-TBD#", getpid (), *(int *) buffer,
5253 *buflen);
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08005254 if (VPPCOM_DEBUG > 0)
5255 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08005256 /* *INDENT-OFF* */
Keith Burns (alagalah)21673552018-01-18 16:01:34 -08005257 ELOG_TYPE_DECLARE (e) =
5258 {
5259 .format = "VPPCOM_ATTR_GET_BROADCAST: %d buflen=%d",
5260 .format_args = "i4i4",
5261 };
5262
5263 struct {
5264 u32 data[2];
5265 } * ed;
5266
5267 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
5268 ed->data[0] = *(int *) buffer;
5269 ed->data[1] = *buflen;
5270 /* *INDENT-ON* */
5271 }
Dave Wallace048b1d62018-01-03 22:24:41 -05005272 }
5273 else
5274 rv = VPPCOM_EINVAL;
Stevenb5a11602017-10-11 09:59:30 -07005275 break;
5276
5277 case VPPCOM_ATTR_SET_BROADCAST:
Dave Wallace048b1d62018-01-03 22:24:41 -05005278 if (buffer && buflen && (*buflen == sizeof (int)))
5279 {
5280 /* VPP-TBD */
5281 if (*(int *) buffer)
5282 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_BROADCAST);
5283 else
5284 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_BROADCAST);
5285
5286 if (VPPCOM_DEBUG > 2)
5287 clib_warning ("VCL<%d>: VPPCOM_ATTR_SET_BROADCAST: %d, "
5288 "buflen %d, #VPP-TBD#", getpid (),
5289 VCL_SESS_ATTR_TEST (session->attr,
5290 VCL_SESS_ATTR_BROADCAST),
5291 *buflen);
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005292 if (VPPCOM_DEBUG > 0)
5293 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08005294 /* *INDENT-OFF* */
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005295 ELOG_TYPE_DECLARE (e) =
5296 {
5297 .format = "VPPCOM_ATTR_SET_BROADCAST: %d buflen=%d",
5298 .format_args = "i4i4",
5299 };
5300
5301 struct {
5302 u32 data[2];
5303 } * ed;
5304
5305 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
5306 ed->data[0] = VCL_SESS_ATTR_TEST (session->attr,
5307 VCL_SESS_ATTR_BROADCAST);
5308 ed->data[1] = *buflen;
5309 /* *INDENT-ON* */
5310 }
Dave Wallace048b1d62018-01-03 22:24:41 -05005311 }
5312 else
5313 rv = VPPCOM_EINVAL;
5314 break;
5315
5316 case VPPCOM_ATTR_GET_V6ONLY:
5317 if (buffer && buflen && (*buflen >= sizeof (int)))
5318 {
5319 /* VPP-TBD */
5320 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
5321 VCL_SESS_ATTR_V6ONLY);
5322 *buflen = sizeof (int);
5323
5324 if (VPPCOM_DEBUG > 2)
5325 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_V6ONLY: %d, "
5326 "buflen %d, #VPP-TBD#", getpid (), *(int *) buffer,
5327 *buflen);
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005328 if (VPPCOM_DEBUG > 0)
5329 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08005330 /* *INDENT-OFF* */
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005331 ELOG_TYPE_DECLARE (e) =
5332 {
5333 .format = "VPPCOM_ATTR_GET_V6ONLY: %d buflen=%d",
5334 .format_args = "i4i4",
5335 };
5336
5337 struct {
5338 u32 data[2];
5339 } * ed;
5340
5341 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
5342 ed->data[0] = *(int *) buffer;
5343 ed->data[1] = *buflen;
5344 /* *INDENT-ON* */
5345 }
Dave Wallace048b1d62018-01-03 22:24:41 -05005346 }
5347 else
5348 rv = VPPCOM_EINVAL;
Stevenb5a11602017-10-11 09:59:30 -07005349 break;
5350
5351 case VPPCOM_ATTR_SET_V6ONLY:
Dave Wallace048b1d62018-01-03 22:24:41 -05005352 if (buffer && buflen && (*buflen == sizeof (int)))
5353 {
5354 /* VPP-TBD */
5355 if (*(int *) buffer)
5356 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_V6ONLY);
5357 else
5358 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_V6ONLY);
5359
5360 if (VPPCOM_DEBUG > 2)
5361 clib_warning ("VCL<%d>: VPPCOM_ATTR_SET_V6ONLY: %d, "
5362 "buflen %d, #VPP-TBD#", getpid (),
5363 VCL_SESS_ATTR_TEST (session->attr,
5364 VCL_SESS_ATTR_V6ONLY), *buflen);
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005365 if (VPPCOM_DEBUG > 0)
5366 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08005367 /* *INDENT-OFF* */
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005368 ELOG_TYPE_DECLARE (e) =
5369 {
5370 .format = "VPPCOM_ATTR_SET_V6ONLY: %d buflen=%d",
5371 .format_args = "i4i4",
5372 };
5373
5374 struct {
5375 u32 data[2];
5376 } * ed;
5377
5378 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
5379 ed->data[0] = VCL_SESS_ATTR_TEST (session->attr,
5380 VCL_SESS_ATTR_V6ONLY);
5381 ed->data[1] = *buflen;
5382 /* *INDENT-ON* */
5383 }
Dave Wallace048b1d62018-01-03 22:24:41 -05005384 }
5385 else
5386 rv = VPPCOM_EINVAL;
5387 break;
5388
5389 case VPPCOM_ATTR_GET_KEEPALIVE:
5390 if (buffer && buflen && (*buflen >= sizeof (int)))
5391 {
5392 /* VPP-TBD */
5393 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
5394 VCL_SESS_ATTR_KEEPALIVE);
5395 *buflen = sizeof (int);
5396
5397 if (VPPCOM_DEBUG > 2)
5398 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_KEEPALIVE: %d, "
5399 "buflen %d, #VPP-TBD#", getpid (), *(int *) buffer,
5400 *buflen);
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005401 if (VPPCOM_DEBUG > 0)
5402 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08005403 /* *INDENT-OFF* */
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005404 ELOG_TYPE_DECLARE (e) =
5405 {
5406 .format = "VPPCOM_ATTR_GET_KEEPALIVE: %d buflen=%d",
5407 .format_args = "i4i4",
5408 };
5409
5410 struct {
5411 u32 data[2];
5412 } * ed;
5413
5414 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
5415 ed->data[0] = *(int *) buffer;
5416 ed->data[1] = *buflen;
5417 /* *INDENT-ON* */
5418 }
Dave Wallace048b1d62018-01-03 22:24:41 -05005419 }
5420 else
5421 rv = VPPCOM_EINVAL;
Stevenb5a11602017-10-11 09:59:30 -07005422 break;
Stevenbccd3392017-10-12 20:42:21 -07005423
5424 case VPPCOM_ATTR_SET_KEEPALIVE:
Dave Wallace048b1d62018-01-03 22:24:41 -05005425 if (buffer && buflen && (*buflen == sizeof (int)))
5426 {
5427 /* VPP-TBD */
5428 if (*(int *) buffer)
5429 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_KEEPALIVE);
5430 else
5431 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_KEEPALIVE);
5432
5433 if (VPPCOM_DEBUG > 2)
5434 clib_warning ("VCL<%d>: VPPCOM_ATTR_SET_KEEPALIVE: %d, "
5435 "buflen %d, #VPP-TBD#", getpid (),
5436 VCL_SESS_ATTR_TEST (session->attr,
5437 VCL_SESS_ATTR_KEEPALIVE),
5438 *buflen);
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005439 if (VPPCOM_DEBUG > 0)
5440 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08005441 /* *INDENT-OFF* */
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005442 ELOG_TYPE_DECLARE (e) =
5443 {
5444 .format = "VPPCOM_ATTR_SET_KEEPALIVE: %d buflen=%d",
5445 .format_args = "i4i4",
5446 };
5447
5448 struct {
5449 u32 data[2];
5450 } * ed;
5451
5452 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
5453 ed->data[0] = VCL_SESS_ATTR_TEST (session->attr,
5454 VCL_SESS_ATTR_KEEPALIVE);
5455 ed->data[1] = *buflen;
5456 /* *INDENT-ON* */
5457 }
Dave Wallace048b1d62018-01-03 22:24:41 -05005458 }
5459 else
5460 rv = VPPCOM_EINVAL;
5461 break;
5462
5463 case VPPCOM_ATTR_GET_TCP_NODELAY:
5464 if (buffer && buflen && (*buflen >= sizeof (int)))
5465 {
5466 /* VPP-TBD */
5467 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
5468 VCL_SESS_ATTR_TCP_NODELAY);
5469 *buflen = sizeof (int);
5470
5471 if (VPPCOM_DEBUG > 2)
5472 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_TCP_NODELAY: %d, "
5473 "buflen %d, #VPP-TBD#", getpid (), *(int *) buffer,
5474 *buflen);
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005475 if (VPPCOM_DEBUG > 0)
5476 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08005477 /* *INDENT-OFF* */
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005478 ELOG_TYPE_DECLARE (e) =
5479 {
5480 .format = "VPPCOM_ATTR_GET_TCP_NODELAY: %d buflen=%d",
5481 .format_args = "i4i4",
5482 };
5483
5484 struct {
5485 u32 data[2];
5486 } * ed;
5487
5488 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
5489 ed->data[0] = *(int *) buffer;
5490 ed->data[1] = *buflen;
5491 /* *INDENT-ON* */
5492 }
Dave Wallace048b1d62018-01-03 22:24:41 -05005493 }
5494 else
5495 rv = VPPCOM_EINVAL;
5496 break;
5497
5498 case VPPCOM_ATTR_SET_TCP_NODELAY:
5499 if (buffer && buflen && (*buflen == sizeof (int)))
5500 {
5501 /* VPP-TBD */
5502 if (*(int *) buffer)
5503 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_TCP_NODELAY);
5504 else
5505 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_TCP_NODELAY);
5506
5507 if (VPPCOM_DEBUG > 2)
5508 clib_warning ("VCL<%d>: VPPCOM_ATTR_SET_TCP_NODELAY: %d, "
5509 "buflen %d, #VPP-TBD#", getpid (),
5510 VCL_SESS_ATTR_TEST (session->attr,
5511 VCL_SESS_ATTR_TCP_NODELAY),
5512 *buflen);
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005513 if (VPPCOM_DEBUG > 0)
5514 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08005515 /* *INDENT-OFF* */
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005516 ELOG_TYPE_DECLARE (e) =
5517 {
5518 .format = "VPPCOM_ATTR_SET_TCP_NODELAY: %d buflen=%d",
5519 .format_args = "i4i4",
5520 };
5521
5522 struct {
5523 u32 data[2];
5524 } * ed;
5525
5526 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
5527 ed->data[0] = VCL_SESS_ATTR_TEST (session->attr,
5528 VCL_SESS_ATTR_TCP_NODELAY);
5529 ed->data[1] = *buflen;
5530 /* *INDENT-ON* */
5531 }
Dave Wallace048b1d62018-01-03 22:24:41 -05005532 }
5533 else
5534 rv = VPPCOM_EINVAL;
5535 break;
5536
5537 case VPPCOM_ATTR_GET_TCP_KEEPIDLE:
5538 if (buffer && buflen && (*buflen >= sizeof (int)))
5539 {
5540 /* VPP-TBD */
5541 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
5542 VCL_SESS_ATTR_TCP_KEEPIDLE);
5543 *buflen = sizeof (int);
5544
5545 if (VPPCOM_DEBUG > 2)
5546 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_TCP_KEEPIDLE: %d, "
5547 "buflen %d, #VPP-TBD#", getpid (), *(int *) buffer,
5548 *buflen);
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005549 if (VPPCOM_DEBUG > 0)
5550 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08005551 /* *INDENT-OFF* */
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005552 ELOG_TYPE_DECLARE (e) =
5553 {
5554 .format = "VPPCOM_ATTR_GET_TCP_KEEPIDLE: %d buflen=%d",
5555 .format_args = "i4i4",
5556 };
5557
5558 struct {
5559 u32 data[2];
5560 } * ed;
5561
5562 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
5563 ed->data[0] = *(int *) buffer;
5564 ed->data[1] = *buflen;
5565 /* *INDENT-ON* */
5566 }
Dave Wallace048b1d62018-01-03 22:24:41 -05005567 }
5568 else
5569 rv = VPPCOM_EINVAL;
Stevenbccd3392017-10-12 20:42:21 -07005570 break;
5571
5572 case VPPCOM_ATTR_SET_TCP_KEEPIDLE:
Dave Wallace048b1d62018-01-03 22:24:41 -05005573 if (buffer && buflen && (*buflen == sizeof (int)))
5574 {
5575 /* VPP-TBD */
5576 if (*(int *) buffer)
5577 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_TCP_KEEPIDLE);
5578 else
5579 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_TCP_KEEPIDLE);
5580
5581 if (VPPCOM_DEBUG > 2)
5582 clib_warning ("VCL<%d>: VPPCOM_ATTR_SET_TCP_KEEPIDLE: %d, "
5583 "buflen %d, #VPP-TBD#", getpid (),
5584 VCL_SESS_ATTR_TEST (session->attr,
5585 VCL_SESS_ATTR_TCP_KEEPIDLE),
5586 *buflen);
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005587 if (VPPCOM_DEBUG > 0)
5588 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08005589 /* *INDENT-OFF* */
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005590 ELOG_TYPE_DECLARE (e) =
5591 {
5592 .format = "VPPCOM_ATTR_SET_TCP_KEEPIDLE: %d buflen=%d",
5593 .format_args = "i4i4",
5594 };
5595
5596 struct {
5597 u32 data[2];
5598 } * ed;
5599
5600 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
5601 ed->data[0] = VCL_SESS_ATTR_TEST (session->attr,
5602 VCL_SESS_ATTR_TCP_KEEPIDLE);
5603 ed->data[1] = *buflen;
5604 /* *INDENT-ON* */
5605 }
Dave Wallace048b1d62018-01-03 22:24:41 -05005606 }
5607 else
5608 rv = VPPCOM_EINVAL;
5609 break;
5610
5611 case VPPCOM_ATTR_GET_TCP_KEEPINTVL:
5612 if (buffer && buflen && (*buflen >= sizeof (int)))
5613 {
5614 /* VPP-TBD */
5615 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
5616 VCL_SESS_ATTR_TCP_KEEPINTVL);
5617 *buflen = sizeof (int);
5618
5619 if (VPPCOM_DEBUG > 2)
5620 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_TCP_KEEPINTVL: %d, "
5621 "buflen %d, #VPP-TBD#", getpid (), *(int *) buffer,
5622 *buflen);
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005623 if (VPPCOM_DEBUG > 0)
5624 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08005625 /* *INDENT-OFF* */
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005626 ELOG_TYPE_DECLARE (e) =
5627 {
5628 .format = "VPPCOM_ATTR_GET_TCP_KEEPIDLE: %d buflen=%d",
5629 .format_args = "i4i4",
5630 };
5631
5632 struct {
5633 u32 data[2];
5634 } * ed;
5635
5636 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
5637 ed->data[0] = *(int *) buffer;
5638 ed->data[1] = *buflen;
5639 /* *INDENT-ON* */
5640 }
Dave Wallace048b1d62018-01-03 22:24:41 -05005641 }
5642 else
5643 rv = VPPCOM_EINVAL;
Stevenbccd3392017-10-12 20:42:21 -07005644 break;
5645
5646 case VPPCOM_ATTR_SET_TCP_KEEPINTVL:
Dave Wallace048b1d62018-01-03 22:24:41 -05005647 if (buffer && buflen && (*buflen == sizeof (int)))
5648 {
5649 /* VPP-TBD */
5650 if (*(int *) buffer)
5651 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_TCP_KEEPINTVL);
5652 else
5653 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_TCP_KEEPINTVL);
5654
5655 if (VPPCOM_DEBUG > 2)
5656 clib_warning ("VCL<%d>: VPPCOM_ATTR_SET_TCP_KEEPINTVL: %d, "
5657 "buflen %d, #VPP-TBD#", getpid (),
5658 VCL_SESS_ATTR_TEST (session->attr,
5659 VCL_SESS_ATTR_TCP_KEEPINTVL),
5660 *buflen);
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005661 if (VPPCOM_DEBUG > 0)
5662 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08005663 /* *INDENT-OFF* */
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005664 ELOG_TYPE_DECLARE (e) =
5665 {
5666 .format = "VPPCOM_ATTR_SET_TCP_KEEPINTVL: %d buflen=%d",
5667 .format_args = "i4i4",
5668 };
5669
5670 struct {
5671 u32 data[2];
5672 } * ed;
5673
5674 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
5675 ed->data[0] = VCL_SESS_ATTR_TEST (session->attr,
5676 VCL_SESS_ATTR_TCP_KEEPINTVL);
5677 ed->data[1] = *buflen;
5678 /* *INDENT-ON* */
5679 }
Dave Wallace048b1d62018-01-03 22:24:41 -05005680 }
5681 else
5682 rv = VPPCOM_EINVAL;
5683 break;
5684
5685 case VPPCOM_ATTR_GET_TCP_USER_MSS:
5686 if (buffer && buflen && (*buflen >= sizeof (u32)))
5687 {
5688 /* VPP-TBD */
5689 *(u32 *) buffer = session->user_mss;
5690 *buflen = sizeof (int);
5691
5692 if (VPPCOM_DEBUG > 2)
5693 clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_TCP_USER_MSS: %d, "
5694 "buflen %d, #VPP-TBD#", getpid (), *(int *) buffer,
5695 *buflen);
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005696 if (VPPCOM_DEBUG > 0)
5697 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08005698 /* *INDENT-OFF* */
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005699 ELOG_TYPE_DECLARE (e) =
5700 {
5701 .format = "VPPCOM_ATTR_GET_TCP_USER_MSS: %d buflen=%d",
5702 .format_args = "i4i4",
5703 };
5704
5705 struct {
5706 u32 data[2];
5707 } * ed;
5708
5709 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
5710 ed->data[0] = *(int *) buffer;
5711 ed->data[1] = *buflen;
5712 /* *INDENT-ON* */
5713 }
Dave Wallace048b1d62018-01-03 22:24:41 -05005714 }
5715 else
5716 rv = VPPCOM_EINVAL;
5717 break;
5718
5719 case VPPCOM_ATTR_SET_TCP_USER_MSS:
5720 if (buffer && buflen && (*buflen == sizeof (u32)))
5721 {
5722 /* VPP-TBD */
5723 session->user_mss = *(u32 *) buffer;
5724
5725 if (VPPCOM_DEBUG > 2)
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005726 clib_warning ("VCL<%d>: VPPCOM_ATTR_SET_TCP_USER_MSS: %u, "
Dave Wallace048b1d62018-01-03 22:24:41 -05005727 "buflen %d, #VPP-TBD#", getpid (),
5728 session->user_mss, *buflen);
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005729 if (VPPCOM_DEBUG > 0)
5730 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08005731 /* *INDENT-OFF* */
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005732 ELOG_TYPE_DECLARE (e) =
5733 {
5734 .format = "VPPCOM_ATTR_SET_TCP_USER_MSS: %d buflen=%d",
5735 .format_args = "i4i4",
5736 };
5737
5738 struct {
5739 u32 data[2];
5740 } * ed;
5741
5742 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, session->elog_track);
5743 ed->data[0] = session->user_mss;
5744 ed->data[1] = *buflen;
5745 /* *INDENT-ON* */
5746 }
Dave Wallace048b1d62018-01-03 22:24:41 -05005747 }
5748 else
5749 rv = VPPCOM_EINVAL;
Stevenbccd3392017-10-12 20:42:21 -07005750 break;
Dave Wallacee22aa742017-10-20 12:30:38 -04005751
5752 default:
5753 rv = VPPCOM_EINVAL;
5754 break;
Dave Wallace35830af2017-10-09 01:43:42 -04005755 }
5756
5757done:
5758 clib_spinlock_unlock (&vcm->sessions_lockp);
5759 return rv;
5760}
5761
Stevenac1f96d2017-10-24 16:03:58 -07005762int
5763vppcom_session_recvfrom (uint32_t session_index, void *buffer,
5764 uint32_t buflen, int flags, vppcom_endpt_t * ep)
5765{
Stevenac1f96d2017-10-24 16:03:58 -07005766 int rv = VPPCOM_OK;
5767 session_t *session = 0;
5768
5769 if (ep)
5770 {
5771 clib_spinlock_lock (&vcm->sessions_lockp);
5772 rv = vppcom_session_at_index (session_index, &session);
5773 if (PREDICT_FALSE (rv))
5774 {
5775 clib_spinlock_unlock (&vcm->sessions_lockp);
5776 if (VPPCOM_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05005777 clib_warning ("VCL<%d>: invalid session, "
5778 "sid (%u) has been closed!",
Dave Wallace2e005bb2017-11-07 01:21:39 -05005779 getpid (), session_index);
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005780 if (VPPCOM_DEBUG > 0)
5781 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08005782 /* *INDENT-OFF* */
Keith Burns (alagalah)4e578062018-01-19 14:26:35 -08005783 ELOG_TYPE_DECLARE (e) =
5784 {
5785 .format = "invalid session: %d closed",
5786 .format_args = "i4",
5787 };
5788
5789 struct {
5790 u32 data;
5791 } * ed;
5792
5793 ed = ELOG_TRACK_DATA (&vcm->elog_main, e, vcm->elog_track);
5794 ed->data = session_index;
5795 /* *INDENT-ON* */
5796 }
Dave Wallacefaf9d772017-10-26 16:12:04 -04005797 rv = VPPCOM_EBADFD;
5798 clib_spinlock_unlock (&vcm->sessions_lockp);
5799 goto done;
Stevenac1f96d2017-10-24 16:03:58 -07005800 }
Stevenac1f96d2017-10-24 16:03:58 -07005801 ep->is_ip4 = session->peer_addr.is_ip4;
5802 ep->port = session->peer_port;
5803 if (session->peer_addr.is_ip4)
5804 clib_memcpy (ep->ip, &session->peer_addr.ip46.ip4,
5805 sizeof (ip4_address_t));
5806 else
5807 clib_memcpy (ep->ip, &session->peer_addr.ip46.ip6,
5808 sizeof (ip6_address_t));
5809 clib_spinlock_unlock (&vcm->sessions_lockp);
Stevenac1f96d2017-10-24 16:03:58 -07005810 }
Steven58f464e2017-10-25 12:33:12 -07005811
5812 if (flags == 0)
Stevenac1f96d2017-10-24 16:03:58 -07005813 rv = vppcom_session_read (session_index, buffer, buflen);
5814 else if (flags & MSG_PEEK)
Steven58f464e2017-10-25 12:33:12 -07005815 rv = vppcom_session_peek (session_index, buffer, buflen);
Stevenac1f96d2017-10-24 16:03:58 -07005816 else
5817 {
Dave Wallace048b1d62018-01-03 22:24:41 -05005818 clib_warning ("VCL<%d>: Unsupport flags for recvfrom %d",
5819 getpid (), flags);
Stevenac1f96d2017-10-24 16:03:58 -07005820 rv = VPPCOM_EAFNOSUPPORT;
5821 }
5822
Dave Wallacefaf9d772017-10-26 16:12:04 -04005823done:
Stevenac1f96d2017-10-24 16:03:58 -07005824 return rv;
5825}
5826
5827int
5828vppcom_session_sendto (uint32_t session_index, void *buffer,
5829 uint32_t buflen, int flags, vppcom_endpt_t * ep)
5830{
Dave Wallace617dffa2017-10-26 14:47:06 -04005831 if (!buffer)
5832 return VPPCOM_EINVAL;
5833
5834 if (ep)
5835 {
5836 // TBD
5837 return VPPCOM_EINVAL;
5838 }
5839
5840 if (flags)
5841 {
5842 // TBD check the flags and do the right thing
5843 if (VPPCOM_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05005844 clib_warning ("VCL<%d>: handling flags 0x%u (%d) "
5845 "not implemented yet.", getpid (), flags, flags);
Dave Wallace617dffa2017-10-26 14:47:06 -04005846 }
5847
5848 return (vppcom_session_write (session_index, buffer, buflen));
Stevenac1f96d2017-10-24 16:03:58 -07005849}
5850
Dave Wallace048b1d62018-01-03 22:24:41 -05005851int
5852vppcom_poll (vcl_poll_t * vp, uint32_t n_sids, double wait_for_time)
5853{
5854 f64 timeout = clib_time_now (&vcm->clib_time) + wait_for_time;
5855 u32 i, keep_trying = 1;
5856 int rv, num_ev = 0;
5857
5858 if (VPPCOM_DEBUG > 3)
5859 clib_warning ("VCL<%d>: vp %p, nsids %u, wait_for_time %f",
5860 getpid (), vp, n_sids, wait_for_time);
5861
5862 if (!vp)
5863 return VPPCOM_EFAULT;
5864
5865 do
5866 {
5867 session_t *session;
5868
5869 for (i = 0; i < n_sids; i++)
5870 {
5871 ASSERT (vp[i].revents);
5872
5873 VCL_LOCK_AND_GET_SESSION (vp[i].sid, &session);
5874 clib_spinlock_unlock (&vcm->sessions_lockp);
5875
5876 if (*vp[i].revents)
5877 *vp[i].revents = 0;
5878
5879 if (POLLIN & vp[i].events)
5880 {
5881 VCL_LOCK_AND_GET_SESSION (vp[i].sid, &session);
5882 rv = vppcom_session_read_ready (session, vp[i].sid);
5883 clib_spinlock_unlock (&vcm->sessions_lockp);
5884 if (rv > 0)
5885 {
5886 *vp[i].revents |= POLLIN;
5887 num_ev++;
5888 }
5889 else if (rv < 0)
5890 {
5891 switch (rv)
5892 {
5893 case VPPCOM_ECONNRESET:
5894 *vp[i].revents = POLLHUP;
5895 break;
5896
5897 default:
5898 *vp[i].revents = POLLERR;
5899 break;
5900 }
5901 num_ev++;
5902 }
5903 }
5904
5905 if (POLLOUT & vp[i].events)
5906 {
5907 VCL_LOCK_AND_GET_SESSION (vp[i].sid, &session);
5908 rv = vppcom_session_write_ready (session, vp[i].sid);
5909 clib_spinlock_unlock (&vcm->sessions_lockp);
5910 if (rv > 0)
5911 {
5912 *vp[i].revents |= POLLOUT;
5913 num_ev++;
5914 }
5915 else if (rv < 0)
5916 {
5917 switch (rv)
5918 {
5919 case VPPCOM_ECONNRESET:
5920 *vp[i].revents = POLLHUP;
5921 break;
5922
5923 default:
5924 *vp[i].revents = POLLERR;
5925 break;
5926 }
5927 num_ev++;
5928 }
5929 }
5930
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08005931 if (0) // Note "done:" label used by VCL_LOCK_AND_GET_SESSION()
Dave Wallace048b1d62018-01-03 22:24:41 -05005932 {
5933 done:
5934 *vp[i].revents = POLLNVAL;
5935 num_ev++;
5936 }
5937 }
5938 if (wait_for_time != -1)
5939 keep_trying = (clib_time_now (&vcm->clib_time) <= timeout) ? 1 : 0;
5940 }
5941 while ((num_ev == 0) && keep_trying);
5942
5943 if (VPPCOM_DEBUG > 3)
5944 {
5945 clib_warning ("VCL<%d>: returning %d", getpid (), num_ev);
5946 for (i = 0; i < n_sids; i++)
5947 {
5948 clib_warning ("VCL<%d>: vp[%d].sid %d (0x%x), .events 0x%x, "
5949 ".revents 0x%x", getpid (), i, vp[i].sid, vp[i].sid,
5950 vp[i].events, *vp[i].revents);
5951 }
5952 }
5953 return num_ev;
5954}
5955
Dave Wallacee22aa742017-10-20 12:30:38 -04005956/*
5957 * fd.io coding-style-patch-verification: ON
5958 *
5959 * Local Variables:
5960 * eval: (c-set-style "gnu")
5961 * End:
5962 */