blob: ad0b7a1cc9c5e64e4be035cf03749c370483babc [file] [log] [blame]
Dave Wallace543852a2017-08-03 02:11:34 -04001/*
Dave Wallace33e002b2017-09-06 01:20:02 -04002 * Copyright (c) 2017 Cisco and/or its affiliates.
Dave Wallace543852a2017-08-03 02:11:34 -04003 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this
5 * You may obtain a copy of the License at:
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include <stdio.h>
17#include <stdlib.h>
18#include <signal.h>
19#include <svm/svm_fifo_segment.h>
20#include <vlibmemory/api.h>
21#include <vpp/api/vpe_msg_enum.h>
22#include <vnet/session/application_interface.h>
Dave Wallace5c7cf1c2017-10-24 04:12:18 -040023#include <vcl/vppcom.h>
Dave Wallace543852a2017-08-03 02:11:34 -040024#include <vlib/unix/unix.h>
25#include <vppinfra/vec_bootstrap.h>
26
27#define vl_typedefs /* define message structures */
28#include <vpp/api/vpe_all_api_h.h>
29#undef vl_typedefs
30
31/* declare message handlers for each api */
32
33#define vl_endianfun /* define message structures */
34#include <vpp/api/vpe_all_api_h.h>
35#undef vl_endianfun
36
37/* instantiate all the print functions we know about */
38#define vl_print(handle, ...)
39#define vl_printfun
40#include <vpp/api/vpe_all_api_h.h>
41#undef vl_printfun
42
43#if (CLIB_DEBUG > 0)
Dave Wallace498b3a52017-11-09 13:00:34 -050044/* Set VPPCOM_DEBUG_INIT 2 for connection debug,
45 * 3 for read/write debug output
46 * or
47 * export VCL_DEBUG=<#> to set dynamically.
48 */
49#define VPPCOM_DEBUG_INIT 1
Dave Wallace543852a2017-08-03 02:11:34 -040050#else
Dave Wallace498b3a52017-11-09 13:00:34 -050051#define VPPCOM_DEBUG_INIT 0
Dave Wallace543852a2017-08-03 02:11:34 -040052#endif
53
Dave Wallace498b3a52017-11-09 13:00:34 -050054#define VPPCOM_DEBUG vcm->debug
55
Dave Wallace543852a2017-08-03 02:11:34 -040056/*
57 * VPPCOM Private definitions and functions.
58 */
59typedef enum
60{
61 STATE_APP_START,
62 STATE_APP_CONN_VPP,
63 STATE_APP_ENABLED,
64 STATE_APP_ATTACHED,
65} app_state_t;
66
67typedef enum
68{
Dave Wallace4878cbe2017-11-21 03:45:09 -050069 STATE_START = 0x01,
70 STATE_CONNECT = 0x02,
71 STATE_LISTEN = 0x04,
72 STATE_ACCEPT = 0x08,
73 STATE_CLOSE_ON_EMPTY = 0x10,
74 STATE_DISCONNECT = 0x20,
75 STATE_FAILED = 0x40
Dave Wallace543852a2017-08-03 02:11:34 -040076} session_state_t;
77
Dave Wallace4878cbe2017-11-21 03:45:09 -050078#define SERVER_STATE_OPEN (STATE_ACCEPT|STATE_CLOSE_ON_EMPTY)
79#define CLIENT_STATE_OPEN (STATE_CONNECT|STATE_CLOSE_ON_EMPTY)
80
Dave Wallacef7f809c2017-10-03 01:48:42 -040081typedef struct epoll_event vppcom_epoll_event_t;
82
83typedef struct
84{
85 u32 next_sid;
86 u32 prev_sid;
87 u32 vep_idx;
88 vppcom_epoll_event_t ev;
89#define VEP_DEFAULT_ET_MASK (EPOLLIN|EPOLLOUT)
Dave Wallace60caa062017-11-10 17:07:13 -050090#define VEP_UNSUPPORTED_EVENTS (EPOLLONESHOT|EPOLLEXCLUSIVE)
Dave Wallacef7f809c2017-10-03 01:48:42 -040091 u32 et_mask;
92} vppcom_epoll_t;
93
Dave Wallace543852a2017-08-03 02:11:34 -040094typedef struct
95{
Dave Wallace35830af2017-10-09 01:43:42 -040096 u8 is_ip4;
97 ip46_address_t ip46;
98} vppcom_ip46_t;
99
100typedef struct
101{
Dave Wallace543852a2017-08-03 02:11:34 -0400102 volatile session_state_t state;
103
104 svm_fifo_t *server_rx_fifo;
105 svm_fifo_t *server_tx_fifo;
Dave Wallace60caa062017-11-10 17:07:13 -0500106 u8 *segment_name;
Dave Wallace543852a2017-08-03 02:11:34 -0400107 u32 sm_seg_index;
Dave Wallace60caa062017-11-10 17:07:13 -0500108 u32 client_context;
109 u64 vpp_handle;
Dave Wallace33e002b2017-09-06 01:20:02 -0400110 unix_shared_memory_queue_t *vpp_event_queue;
Dave Wallace543852a2017-08-03 02:11:34 -0400111
112 /* Socket configuration state */
Dave Wallacef7f809c2017-10-03 01:48:42 -0400113 /* TBD: covert 'is_*' vars to bit in u8 flags; */
Dave Wallace543852a2017-08-03 02:11:34 -0400114 u8 is_server;
115 u8 is_listen;
116 u8 is_cut_thru;
117 u8 is_nonblocking;
Dave Wallacef7f809c2017-10-03 01:48:42 -0400118 u8 is_vep;
119 u8 is_vep_session;
120 u32 wait_cont_idx;
121 vppcom_epoll_t vep;
Dave Wallace543852a2017-08-03 02:11:34 -0400122 u32 vrf;
Dave Wallace35830af2017-10-09 01:43:42 -0400123 vppcom_ip46_t lcl_addr;
124 vppcom_ip46_t peer_addr;
Stevenac1f96d2017-10-24 16:03:58 -0700125 u16 lcl_port; // network order
126 u16 peer_port; // network order
Dave Wallace543852a2017-08-03 02:11:34 -0400127 u8 proto;
128 u64 client_queue_address;
129 u64 options[16];
130} session_t;
131
132typedef struct vppcom_cfg_t_
133{
134 u64 heapsize;
Dave Wallacec8f1ee62017-11-29 22:46:32 -0500135 u32 vpp_api_q_length;
Dave Wallace543852a2017-08-03 02:11:34 -0400136 u64 segment_baseva;
137 u32 segment_size;
138 u32 add_segment_size;
139 u32 preallocated_fifo_pairs;
140 u32 rx_fifo_size;
141 u32 tx_fifo_size;
142 u32 event_queue_size;
143 u32 listen_queue_size;
Dave Wallace774169b2017-11-01 20:07:40 -0400144 u8 app_proxy_transport_tcp;
145 u8 app_proxy_transport_udp;
146 u8 app_scope_local;
147 u8 app_scope_global;
Dave Wallace8af20542017-10-26 03:29:30 -0400148 u8 *namespace_id;
149 u64 namespace_secret;
Dave Wallace543852a2017-08-03 02:11:34 -0400150 f64 app_timeout;
151 f64 session_timeout;
152 f64 accept_timeout;
153} vppcom_cfg_t;
154
155typedef struct vppcom_main_t_
156{
157 u8 init;
Dave Wallace498b3a52017-11-09 13:00:34 -0500158 u32 debug;
Dave Wallace543852a2017-08-03 02:11:34 -0400159 u32 *client_session_index_fifo;
Dave Wallace543852a2017-08-03 02:11:34 -0400160 int main_cpu;
161
162 /* vpe input queue */
163 unix_shared_memory_queue_t *vl_input_queue;
164
165 /* API client handle */
166 u32 my_client_index;
167
168 /* Session pool */
169 clib_spinlock_t sessions_lockp;
170 session_t *sessions;
171
172 /* Hash table for disconnect processing */
173 uword *session_index_by_vpp_handles;
174
175 /* Select bitmaps */
176 clib_bitmap_t *rd_bitmap;
177 clib_bitmap_t *wr_bitmap;
178 clib_bitmap_t *ex_bitmap;
179
180 /* Our event queue */
181 unix_shared_memory_queue_t *app_event_queue;
182
183 /* unique segment name counter */
184 u32 unique_segment_index;
185
Dave Wallace543852a2017-08-03 02:11:34 -0400186 /* For deadman timers */
187 clib_time_t clib_time;
188
189 /* State of the connection, shared between msg RX thread and main thread */
190 volatile app_state_t app_state;
191
192 vppcom_cfg_t cfg;
193
194 /* VNET_API_ERROR_FOO -> "Foo" hash table */
195 uword *error_string_by_error_number;
196} vppcom_main_t;
197
Dave Wallace2e005bb2017-11-07 01:21:39 -0500198/* NOTE: _vppcom_main is only used until the heap is allocated.
199 * Do not access it directly -- use vcm which will point to
200 * the heap allocated copy after init.
201 */
Dave Wallace498b3a52017-11-09 13:00:34 -0500202static vppcom_main_t _vppcom_main = {
203 .debug = VPPCOM_DEBUG_INIT,
204 .my_client_index = ~0
205};
Dave Wallace2e005bb2017-11-07 01:21:39 -0500206
207static vppcom_main_t *vcm = &_vppcom_main;
Dave Wallace543852a2017-08-03 02:11:34 -0400208
Dave Wallace60caa062017-11-10 17:07:13 -0500209#define VCL_LOCK_AND_GET_SESSION(I, S) \
210do { \
211 clib_spinlock_lock (&vcm->sessions_lockp); \
212 rv = vppcom_session_at_index (I, S); \
213 if (PREDICT_FALSE (rv)) \
214 { \
215 clib_spinlock_unlock (&vcm->sessions_lockp); \
Dave Wallace4878cbe2017-11-21 03:45:09 -0500216 clib_warning ("[%s] ERROR: Invalid ##I (%u)!", \
217 getpid (), I); \
Dave Wallace60caa062017-11-10 17:07:13 -0500218 goto done; \
219 } \
220} while (0)
221
Dave Wallace543852a2017-08-03 02:11:34 -0400222static const char *
223vppcom_app_state_str (app_state_t state)
224{
225 char *st;
226
227 switch (state)
228 {
229 case STATE_APP_START:
230 st = "STATE_APP_START";
231 break;
232
233 case STATE_APP_CONN_VPP:
234 st = "STATE_APP_CONN_VPP";
235 break;
236
237 case STATE_APP_ENABLED:
238 st = "STATE_APP_ENABLED";
239 break;
240
241 case STATE_APP_ATTACHED:
242 st = "STATE_APP_ATTACHED";
243 break;
244
245 default:
246 st = "UNKNOWN_APP_STATE";
247 break;
248 }
249
250 return st;
251}
252
253static const char *
254vppcom_session_state_str (session_state_t state)
255{
256 char *st;
257
258 switch (state)
259 {
260 case STATE_START:
261 st = "STATE_START";
262 break;
263
264 case STATE_CONNECT:
265 st = "STATE_CONNECT";
266 break;
267
268 case STATE_LISTEN:
269 st = "STATE_LISTEN";
270 break;
271
272 case STATE_ACCEPT:
273 st = "STATE_ACCEPT";
274 break;
275
Dave Wallace4878cbe2017-11-21 03:45:09 -0500276 case STATE_CLOSE_ON_EMPTY:
277 st = "STATE_CLOSE_ON_EMPTY";
278 break;
279
Dave Wallace543852a2017-08-03 02:11:34 -0400280 case STATE_DISCONNECT:
281 st = "STATE_DISCONNECT";
282 break;
283
284 case STATE_FAILED:
285 st = "STATE_FAILED";
286 break;
287
288 default:
289 st = "UNKNOWN_STATE";
290 break;
291 }
292
293 return st;
294}
295
296/*
297 * VPPCOM Utility Functions
298 */
299static inline int
300vppcom_session_at_index (u32 session_index, session_t * volatile *sess)
301{
Dave Wallace543852a2017-08-03 02:11:34 -0400302 /* Assumes that caller has acquired spinlock: vcm->sessions_lockp */
303 if (PREDICT_FALSE ((session_index == ~0) ||
304 pool_is_free_index (vcm->sessions, session_index)))
305 {
Dave Wallacef7f809c2017-10-03 01:48:42 -0400306 clib_warning ("[%d] invalid session, sid (%u) has been closed!",
Dave Wallace2e005bb2017-11-07 01:21:39 -0500307 getpid (), session_index);
Dave Wallace543852a2017-08-03 02:11:34 -0400308 return VPPCOM_EBADFD;
309 }
310 *sess = pool_elt_at_index (vcm->sessions, session_index);
311 return VPPCOM_OK;
312}
313
Florin Corasdcf55ce2017-11-16 15:32:50 -0800314static inline void
315vppcom_session_table_add_listener (u64 listener_handle, u32 value)
316{
317 /* Session and listener handles have different formats. The latter has
318 * the thread index in the upper 32 bits while the former has the session
319 * type. Knowing that, for listeners we just flip the MSB to 1 */
320 listener_handle |= 1ULL << 63;
321 hash_set (vcm->session_index_by_vpp_handles, listener_handle, value);
322}
323
324static inline session_t *
325vppcom_session_table_lookup_listener (u64 listener_handle)
326{
327 uword *p;
328 u64 handle = listener_handle | (1ULL << 63);
Dave Wallace4878cbe2017-11-21 03:45:09 -0500329 session_t *session;
330
Florin Corasdcf55ce2017-11-16 15:32:50 -0800331 p = hash_get (vcm->session_index_by_vpp_handles, handle);
332 if (!p)
333 {
334 clib_warning ("[%d] couldn't find listen session: unknown vpp "
335 "listener handle %llx", getpid (), listener_handle);
336 return 0;
337 }
338 if (pool_is_free_index (vcm->sessions, p[0]))
339 {
340 if (VPPCOM_DEBUG > 1)
341 clib_warning ("[%d] invalid listen session, sid (%u)", getpid (),
342 p[0]);
343 return 0;
344 }
345
Dave Wallace4878cbe2017-11-21 03:45:09 -0500346 session = pool_elt_at_index (vcm->sessions, p[0]);
347 ASSERT (session->is_listen);
348 return session;
Florin Corasdcf55ce2017-11-16 15:32:50 -0800349}
350
351static inline void
352vppcom_session_table_del_listener (u64 listener_handle)
353{
354 listener_handle |= 1ULL << 63;
355 hash_unset (vcm->session_index_by_vpp_handles, listener_handle);
356}
357
Dave Wallace543852a2017-08-03 02:11:34 -0400358static int
359vppcom_connect_to_vpp (char *app_name)
360{
361 api_main_t *am = &api_main;
Dave Wallace543852a2017-08-03 02:11:34 -0400362
363 if (VPPCOM_DEBUG > 0)
364 printf ("\nConnecting to VPP api...");
Dave Wallacec8f1ee62017-11-29 22:46:32 -0500365 if (vl_client_connect_to_vlib ("/vpe-api", app_name,
366 vcm->cfg.vpp_api_q_length) < 0)
Dave Wallace543852a2017-08-03 02:11:34 -0400367 {
Dave Wallace2e005bb2017-11-07 01:21:39 -0500368 clib_warning ("[%d] connect to vpp (%s) failed!", getpid (), app_name);
Dave Wallace543852a2017-08-03 02:11:34 -0400369 return VPPCOM_ECONNREFUSED;
370 }
371
372 vcm->vl_input_queue = am->shmem_hdr->vl_input_queue;
373 vcm->my_client_index = am->my_client_index;
374 if (VPPCOM_DEBUG > 0)
375 printf (" connected!\n");
376
377 vcm->app_state = STATE_APP_CONN_VPP;
378 return VPPCOM_OK;
379}
380
381static u8 *
382format_api_error (u8 * s, va_list * args)
383{
Dave Wallace543852a2017-08-03 02:11:34 -0400384 i32 error = va_arg (*args, u32);
385 uword *p;
386
387 p = hash_get (vcm->error_string_by_error_number, -error);
388
389 if (p)
390 s = format (s, "%s (%d)", p[0], error);
391 else
392 s = format (s, "%d", error);
393 return s;
394}
395
396static void
397vppcom_init_error_string_table (void)
398{
Dave Wallace543852a2017-08-03 02:11:34 -0400399 vcm->error_string_by_error_number = hash_create (0, sizeof (uword));
400
401#define _(n,v,s) hash_set (vcm->error_string_by_error_number, -v, s);
402 foreach_vnet_api_error;
403#undef _
404
405 hash_set (vcm->error_string_by_error_number, 99, "Misc");
406}
407
408static inline int
409vppcom_wait_for_app_state_change (app_state_t app_state)
410{
Dave Wallace543852a2017-08-03 02:11:34 -0400411 f64 timeout = clib_time_now (&vcm->clib_time) + vcm->cfg.app_timeout;
412
413 while (clib_time_now (&vcm->clib_time) < timeout)
414 {
415 if (vcm->app_state == app_state)
416 return VPPCOM_OK;
417 }
418 if (VPPCOM_DEBUG > 0)
Dave Wallace2e005bb2017-11-07 01:21:39 -0500419 clib_warning ("[%d] timeout waiting for state %s (%d)", getpid (),
Dave Wallace543852a2017-08-03 02:11:34 -0400420 vppcom_app_state_str (app_state), app_state);
421 return VPPCOM_ETIMEDOUT;
422}
423
424static inline int
425vppcom_wait_for_session_state_change (u32 session_index,
426 session_state_t state,
427 f64 wait_for_time)
428{
Dave Wallace543852a2017-08-03 02:11:34 -0400429 f64 timeout = clib_time_now (&vcm->clib_time) + wait_for_time;
430 session_t *volatile session;
431 int rv;
432
433 do
434 {
435 clib_spinlock_lock (&vcm->sessions_lockp);
436 rv = vppcom_session_at_index (session_index, &session);
437 if (PREDICT_FALSE (rv))
438 {
439 clib_spinlock_unlock (&vcm->sessions_lockp);
440 return rv;
441 }
442 if (session->state == state)
443 {
444 clib_spinlock_unlock (&vcm->sessions_lockp);
445 return VPPCOM_OK;
446 }
Dave Wallace4878cbe2017-11-21 03:45:09 -0500447 if (session->state == STATE_FAILED)
448 {
449 clib_spinlock_unlock (&vcm->sessions_lockp);
450 return VPPCOM_ECONNREFUSED;
451 }
452
Dave Wallace543852a2017-08-03 02:11:34 -0400453 clib_spinlock_unlock (&vcm->sessions_lockp);
454 }
455 while (clib_time_now (&vcm->clib_time) < timeout);
456
457 if (VPPCOM_DEBUG > 0)
Dave Wallace4878cbe2017-11-21 03:45:09 -0500458 clib_warning ("[%d] timeout waiting for state 0x%x (%s)", getpid (),
459 state, vppcom_session_state_str (state));
Dave Wallace543852a2017-08-03 02:11:34 -0400460 return VPPCOM_ETIMEDOUT;
461}
462
463static inline int
464vppcom_wait_for_client_session_index (f64 wait_for_time)
465{
Dave Wallace543852a2017-08-03 02:11:34 -0400466 f64 timeout = clib_time_now (&vcm->clib_time) + wait_for_time;
467
468 do
469 {
470 if (clib_fifo_elts (vcm->client_session_index_fifo))
471 return VPPCOM_OK;
472 }
473 while (clib_time_now (&vcm->clib_time) < timeout);
474
475 if (wait_for_time == 0)
476 return VPPCOM_EAGAIN;
477
478 if (VPPCOM_DEBUG > 0)
Dave Wallace2e005bb2017-11-07 01:21:39 -0500479 clib_warning ("[%d] timeout waiting for client_session_index", getpid ());
Dave Wallace543852a2017-08-03 02:11:34 -0400480 return VPPCOM_ETIMEDOUT;
481}
482
483/*
484 * VPP-API message functions
485 */
486static void
487vppcom_send_session_enable_disable (u8 is_enable)
488{
Dave Wallace543852a2017-08-03 02:11:34 -0400489 vl_api_session_enable_disable_t *bmp;
490 bmp = vl_msg_api_alloc (sizeof (*bmp));
491 memset (bmp, 0, sizeof (*bmp));
492
493 bmp->_vl_msg_id = ntohs (VL_API_SESSION_ENABLE_DISABLE);
494 bmp->client_index = vcm->my_client_index;
495 bmp->context = htonl (0xfeedface);
496 bmp->is_enable = is_enable;
497 vl_msg_api_send_shmem (vcm->vl_input_queue, (u8 *) & bmp);
498}
499
500static int
501vppcom_app_session_enable (void)
502{
Dave Wallace543852a2017-08-03 02:11:34 -0400503 int rv;
504
505 if (vcm->app_state != STATE_APP_ENABLED)
506 {
507 vppcom_send_session_enable_disable (1 /* is_enabled == TRUE */ );
508 rv = vppcom_wait_for_app_state_change (STATE_APP_ENABLED);
509 if (PREDICT_FALSE (rv))
510 {
511 if (VPPCOM_DEBUG > 0)
Dave Wallaceee45d412017-11-24 21:44:06 -0500512 clib_warning ("[%d] application session enable timed out! "
513 "returning %d (%s)",
514 getpid (), rv, vppcom_retval_str (rv));
Dave Wallace543852a2017-08-03 02:11:34 -0400515 return rv;
516 }
517 }
518 return VPPCOM_OK;
519}
520
521static void
522 vl_api_session_enable_disable_reply_t_handler
523 (vl_api_session_enable_disable_reply_t * mp)
524{
Dave Wallace543852a2017-08-03 02:11:34 -0400525 if (mp->retval)
526 {
Dave Wallace2e005bb2017-11-07 01:21:39 -0500527 clib_warning ("[%d] session_enable_disable failed: %U", getpid (),
Dave Wallace543852a2017-08-03 02:11:34 -0400528 format_api_error, ntohl (mp->retval));
529 }
530 else
531 vcm->app_state = STATE_APP_ENABLED;
532}
533
534static void
535vppcom_app_send_attach (void)
536{
Dave Wallace543852a2017-08-03 02:11:34 -0400537 vl_api_application_attach_t *bmp;
Dave Wallace8af20542017-10-26 03:29:30 -0400538 u8 nsid_len = vec_len (vcm->cfg.namespace_id);
Dave Wallace774169b2017-11-01 20:07:40 -0400539 u8 app_is_proxy = (vcm->cfg.app_proxy_transport_tcp ||
540 vcm->cfg.app_proxy_transport_udp);
Dave Wallace8af20542017-10-26 03:29:30 -0400541
Dave Wallace543852a2017-08-03 02:11:34 -0400542 bmp = vl_msg_api_alloc (sizeof (*bmp));
543 memset (bmp, 0, sizeof (*bmp));
544
545 bmp->_vl_msg_id = ntohs (VL_API_APPLICATION_ATTACH);
546 bmp->client_index = vcm->my_client_index;
547 bmp->context = htonl (0xfeedface);
548 bmp->options[APP_OPTIONS_FLAGS] =
Florin Corascea194d2017-10-02 00:18:51 -0700549 APP_OPTIONS_FLAGS_ACCEPT_REDIRECT | APP_OPTIONS_FLAGS_ADD_SEGMENT |
Dave Wallace774169b2017-11-01 20:07:40 -0400550 (vcm->cfg.app_scope_local ? APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE : 0) |
551 (vcm->cfg.app_scope_global ? APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE : 0) |
552 (app_is_proxy ? APP_OPTIONS_FLAGS_IS_PROXY : 0);
553 bmp->options[APP_OPTIONS_PROXY_TRANSPORT] =
554 (vcm->cfg.app_proxy_transport_tcp ? 1 << TRANSPORT_PROTO_TCP : 0) |
555 (vcm->cfg.app_proxy_transport_udp ? 1 << TRANSPORT_PROTO_UDP : 0);
Dave Wallace543852a2017-08-03 02:11:34 -0400556 bmp->options[SESSION_OPTIONS_SEGMENT_SIZE] = vcm->cfg.segment_size;
557 bmp->options[SESSION_OPTIONS_ADD_SEGMENT_SIZE] = vcm->cfg.add_segment_size;
558 bmp->options[SESSION_OPTIONS_RX_FIFO_SIZE] = vcm->cfg.rx_fifo_size;
559 bmp->options[SESSION_OPTIONS_TX_FIFO_SIZE] = vcm->cfg.tx_fifo_size;
Dave Wallace8af20542017-10-26 03:29:30 -0400560 if (nsid_len)
561 {
562 bmp->namespace_id_len = nsid_len;
563 clib_memcpy (bmp->namespace_id, vcm->cfg.namespace_id, nsid_len);
564 bmp->options[APP_OPTIONS_NAMESPACE_SECRET] = vcm->cfg.namespace_secret;
565 }
Dave Wallace543852a2017-08-03 02:11:34 -0400566 vl_msg_api_send_shmem (vcm->vl_input_queue, (u8 *) & bmp);
567}
568
569static int
570vppcom_app_attach (void)
571{
Dave Wallace543852a2017-08-03 02:11:34 -0400572 int rv;
573
574 vppcom_app_send_attach ();
575 rv = vppcom_wait_for_app_state_change (STATE_APP_ATTACHED);
576 if (PREDICT_FALSE (rv))
577 {
578 if (VPPCOM_DEBUG > 0)
Dave Wallaceee45d412017-11-24 21:44:06 -0500579 clib_warning ("[%d] application attach timed out! returning %d (%s)",
580 getpid (), rv, vppcom_retval_str (rv));
Dave Wallace543852a2017-08-03 02:11:34 -0400581 return rv;
582 }
583 return VPPCOM_OK;
584}
585
586static void
587vppcom_app_detach (void)
588{
Dave Wallace543852a2017-08-03 02:11:34 -0400589 vl_api_application_detach_t *bmp;
590 bmp = vl_msg_api_alloc (sizeof (*bmp));
591 memset (bmp, 0, sizeof (*bmp));
592
593 bmp->_vl_msg_id = ntohs (VL_API_APPLICATION_DETACH);
594 bmp->client_index = vcm->my_client_index;
595 bmp->context = htonl (0xfeedface);
596 vl_msg_api_send_shmem (vcm->vl_input_queue, (u8 *) & bmp);
597}
598
599static void
600vl_api_application_attach_reply_t_handler (vl_api_application_attach_reply_t *
601 mp)
602{
Dave Wallace543852a2017-08-03 02:11:34 -0400603 static svm_fifo_segment_create_args_t _a;
604 svm_fifo_segment_create_args_t *a = &_a;
605 int rv;
606
607 memset (a, 0, sizeof (*a));
608 if (mp->retval)
609 {
Dave Wallace2e005bb2017-11-07 01:21:39 -0500610 clib_warning ("[%d] attach failed: %U", getpid (),
Dave Wallace543852a2017-08-03 02:11:34 -0400611 format_api_error, ntohl (mp->retval));
612 return;
613 }
614
615 if (mp->segment_name_length == 0)
616 {
Dave Wallace2e005bb2017-11-07 01:21:39 -0500617 clib_warning ("[%d] segment_name_length zero", getpid ());
Dave Wallace543852a2017-08-03 02:11:34 -0400618 return;
619 }
620
621 a->segment_name = (char *) mp->segment_name;
622 a->segment_size = mp->segment_size;
623
624 ASSERT (mp->app_event_queue_address);
625
626 /* Attach to the segment vpp created */
627 rv = svm_fifo_segment_attach (a);
628 vec_reset_length (a->new_segment_indices);
629 if (PREDICT_FALSE (rv))
630 {
Dave Wallace2e005bb2017-11-07 01:21:39 -0500631 clib_warning ("[%d] svm_fifo_segment_attach ('%s') failed", getpid (),
Dave Wallace543852a2017-08-03 02:11:34 -0400632 mp->segment_name);
633 return;
634 }
635
636 vcm->app_event_queue =
637 uword_to_pointer (mp->app_event_queue_address,
638 unix_shared_memory_queue_t *);
639
640 vcm->app_state = STATE_APP_ATTACHED;
641}
642
643static void
644vl_api_application_detach_reply_t_handler (vl_api_application_detach_reply_t *
645 mp)
646{
Dave Wallace543852a2017-08-03 02:11:34 -0400647 if (mp->retval)
Dave Wallace2e005bb2017-11-07 01:21:39 -0500648 clib_warning ("[%d] detach failed: %U", getpid (), format_api_error,
Dave Wallace543852a2017-08-03 02:11:34 -0400649 ntohl (mp->retval));
650
651 vcm->app_state = STATE_APP_ENABLED;
652}
653
654static void
655vl_api_disconnect_session_reply_t_handler (vl_api_disconnect_session_reply_t *
656 mp)
657{
Dave Wallace543852a2017-08-03 02:11:34 -0400658 if (mp->retval)
Dave Wallace4878cbe2017-11-21 03:45:09 -0500659 clib_warning ("[%d] vpp handle 0x%llx: disconnect session failed: %U",
660 getpid (), mp->handle, format_api_error,
661 ntohl (mp->retval));
Dave Wallace543852a2017-08-03 02:11:34 -0400662}
663
664static void
665vl_api_map_another_segment_t_handler (vl_api_map_another_segment_t * mp)
666{
Dave Wallace543852a2017-08-03 02:11:34 -0400667 static svm_fifo_segment_create_args_t _a;
668 svm_fifo_segment_create_args_t *a = &_a;
669 int rv;
670
671 memset (a, 0, sizeof (*a));
672 a->segment_name = (char *) mp->segment_name;
673 a->segment_size = mp->segment_size;
674 /* Attach to the segment vpp created */
675 rv = svm_fifo_segment_attach (a);
676 vec_reset_length (a->new_segment_indices);
677 if (PREDICT_FALSE (rv))
678 {
679 clib_warning ("[%d] svm_fifo_segment_attach ('%s') failed",
Dave Wallace2e005bb2017-11-07 01:21:39 -0500680 getpid (), mp->segment_name);
Dave Wallace543852a2017-08-03 02:11:34 -0400681 return;
682 }
683 if (VPPCOM_DEBUG > 1)
Dave Wallace2e005bb2017-11-07 01:21:39 -0500684 clib_warning ("[%d] mapped new segment '%s' size %d", getpid (),
Dave Wallace543852a2017-08-03 02:11:34 -0400685 mp->segment_name, mp->segment_size);
686}
687
688static void
689vl_api_disconnect_session_t_handler (vl_api_disconnect_session_t * mp)
690{
Dave Wallace543852a2017-08-03 02:11:34 -0400691 uword *p;
Dave Wallace543852a2017-08-03 02:11:34 -0400692
693 p = hash_get (vcm->session_index_by_vpp_handles, mp->handle);
694 if (p)
695 {
Dave Wallace4878cbe2017-11-21 03:45:09 -0500696 int rv;
697 session_t *session = 0;
698 u32 session_index = p[0];
699
700 VCL_LOCK_AND_GET_SESSION (session_index, &session);
701 session->state = STATE_CLOSE_ON_EMPTY;
702
703 if (VPPCOM_DEBUG > 1)
704 clib_warning ("[%d] vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -0500705 "setting state to 0x%x (%s)",
Dave Wallace4878cbe2017-11-21 03:45:09 -0500706 getpid (), mp->handle, session_index, session->state,
707 vppcom_session_state_str (session->state));
Dave Wallace543852a2017-08-03 02:11:34 -0400708 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace4878cbe2017-11-21 03:45:09 -0500709 return;
710
711 done:
712 if (VPPCOM_DEBUG > 1)
713 clib_warning ("[%d] vpp handle 0x%llx, sid %u: "
714 "session lookup failed!",
715 getpid (), mp->handle, session_index);
Dave Wallace543852a2017-08-03 02:11:34 -0400716 }
717 else
Dave Wallace4878cbe2017-11-21 03:45:09 -0500718 clib_warning ("[%d] vpp handle 0x%llx: session lookup by "
719 "handle failed!", getpid (), mp->handle);
Dave Wallace543852a2017-08-03 02:11:34 -0400720}
721
722static void
723vl_api_reset_session_t_handler (vl_api_reset_session_t * mp)
724{
Dave Wallace543852a2017-08-03 02:11:34 -0400725 session_t *session = 0;
726 vl_api_reset_session_reply_t *rmp;
727 uword *p;
728 int rv = 0;
729
730 p = hash_get (vcm->session_index_by_vpp_handles, mp->handle);
731 if (p)
732 {
733 int rval;
734 clib_spinlock_lock (&vcm->sessions_lockp);
735 rval = vppcom_session_at_index (p[0], &session);
736 if (PREDICT_FALSE (rval))
737 {
Dave Wallace4878cbe2017-11-21 03:45:09 -0500738 rv = VNET_API_ERROR_INVALID_VALUE_2;
Dave Wallaceee45d412017-11-24 21:44:06 -0500739 clib_warning ("[%d] ERROR: vpp handle 0x%llx, sid %u: "
740 "session lookup failed! returning %d %U",
741 getpid (), mp->handle, p[0],
742 rv, format_api_error, rv);
Dave Wallace543852a2017-08-03 02:11:34 -0400743 }
744 else
Dave Wallace4878cbe2017-11-21 03:45:09 -0500745 {
746 /* TBD: should this disconnect immediately and
747 * flush the fifos?
748 */
749 session->state = STATE_CLOSE_ON_EMPTY;
750
751 if (VPPCOM_DEBUG > 1)
752 clib_warning ("[%d] vpp handle 0x%llx, sid %u: "
753 "state set to %d (%s)!", getpid (),
754 mp->handle, p[0], session->state,
755 vppcom_session_state_str (session->state));
756 }
Dave Wallace543852a2017-08-03 02:11:34 -0400757 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace543852a2017-08-03 02:11:34 -0400758 }
759 else
760 {
Dave Wallace4878cbe2017-11-21 03:45:09 -0500761 rv = VNET_API_ERROR_INVALID_VALUE;
762 clib_warning ("[%d] ERROR: vpp handle 0x%llx: session lookup "
763 "failed! returning %d %U",
764 getpid (), mp->handle, rv, format_api_error, rv);
Dave Wallace543852a2017-08-03 02:11:34 -0400765 }
766
767 rmp = vl_msg_api_alloc (sizeof (*rmp));
768 memset (rmp, 0, sizeof (*rmp));
769 rmp->_vl_msg_id = ntohs (VL_API_RESET_SESSION_REPLY);
770 rmp->retval = htonl (rv);
771 rmp->handle = mp->handle;
772 vl_msg_api_send_shmem (vcm->vl_input_queue, (u8 *) & rmp);
773}
774
775static void
Dave Wallace33e002b2017-09-06 01:20:02 -0400776vl_api_connect_session_reply_t_handler (vl_api_connect_session_reply_t * mp)
Dave Wallace543852a2017-08-03 02:11:34 -0400777{
Dave Wallaceee45d412017-11-24 21:44:06 -0500778 session_t *session = 0;
Dave Wallace543852a2017-08-03 02:11:34 -0400779 u32 session_index;
780 svm_fifo_t *rx_fifo, *tx_fifo;
781 u8 is_cut_thru = 0;
782 int rv;
783
Dave Wallace4878cbe2017-11-21 03:45:09 -0500784 session_index = mp->context;
Dave Wallaceee45d412017-11-24 21:44:06 -0500785 VCL_LOCK_AND_GET_SESSION (session_index, &session);
786done:
Dave Wallace543852a2017-08-03 02:11:34 -0400787 if (mp->retval)
788 {
Dave Wallaceee45d412017-11-24 21:44:06 -0500789 clib_warning ("[%d] ERROR: vpp handle 0x%llx, sid %u: "
790 "connect failed! %U",
791 getpid (), mp->handle, session_index,
792 format_api_error, ntohl (mp->retval));
793 if (rv == VPPCOM_OK)
794 {
795 session->state = STATE_FAILED;
796 session->vpp_handle = mp->handle;
797 }
798 else
799 {
800 clib_warning ("[%s] ERROR: vpp handle 0x%llx, sid %u: "
801 "Invalid session index (%u)!",
802 getpid (), mp->handle, session_index);
803 }
804 goto done_unlock;
Dave Wallace543852a2017-08-03 02:11:34 -0400805 }
806
Dave Wallaceee45d412017-11-24 21:44:06 -0500807 if (rv)
808 goto done_unlock;
Dave Wallace543852a2017-08-03 02:11:34 -0400809
810 /* We've been redirected */
811 if (mp->segment_name_length > 0)
812 {
813 static svm_fifo_segment_create_args_t _a;
814 svm_fifo_segment_create_args_t *a = &_a;
815
816 is_cut_thru = 1;
817 memset (a, 0, sizeof (*a));
818 a->segment_name = (char *) mp->segment_name;
819 if (VPPCOM_DEBUG > 1)
Dave Wallace60caa062017-11-10 17:07:13 -0500820 clib_warning ("[%d] cut-thru segment: %s\n",
821 getpid (), a->segment_name);
822
Dave Wallace543852a2017-08-03 02:11:34 -0400823 rv = svm_fifo_segment_attach (a);
824 vec_reset_length (a->new_segment_indices);
825 if (PREDICT_FALSE (rv))
826 {
827 clib_warning ("[%d] sm_fifo_segment_attach ('%s') failed",
Dave Wallace2e005bb2017-11-07 01:21:39 -0500828 getpid (), a->segment_name);
Dave Wallaceee45d412017-11-24 21:44:06 -0500829 goto done_unlock;
Dave Wallace543852a2017-08-03 02:11:34 -0400830 }
831 }
832
833 /*
834 * Setup session
835 */
Dave Wallace543852a2017-08-03 02:11:34 -0400836 session->is_cut_thru = is_cut_thru;
Dave Wallace33e002b2017-09-06 01:20:02 -0400837 session->vpp_event_queue = uword_to_pointer (mp->vpp_event_queue_address,
838 unix_shared_memory_queue_t *);
Dave Wallace543852a2017-08-03 02:11:34 -0400839
840 rx_fifo = uword_to_pointer (mp->server_rx_fifo, svm_fifo_t *);
841 rx_fifo->client_session_index = session_index;
842 tx_fifo = uword_to_pointer (mp->server_tx_fifo, svm_fifo_t *);
843 tx_fifo->client_session_index = session_index;
844
845 session->server_rx_fifo = rx_fifo;
846 session->server_tx_fifo = tx_fifo;
Dave Wallace60caa062017-11-10 17:07:13 -0500847 session->vpp_handle = mp->handle;
Dave Wallace9d1d73a2017-11-20 02:31:48 -0500848 session->lcl_addr.is_ip4 = mp->is_ip4;
849 clib_memcpy (&session->lcl_addr.ip46, mp->lcl_ip,
850 sizeof (session->peer_addr.ip46));
851 session->lcl_port = mp->lcl_port;
Dave Wallace543852a2017-08-03 02:11:34 -0400852 session->state = STATE_CONNECT;
853
854 /* Add it to lookup table */
855 hash_set (vcm->session_index_by_vpp_handles, mp->handle, session_index);
Dave Wallace60caa062017-11-10 17:07:13 -0500856
857 if (VPPCOM_DEBUG > 1)
Dave Wallaceee45d412017-11-24 21:44:06 -0500858 clib_warning ("[%d] vpp handle 0x%llx, sid %u: connect succeeded!"
859 " session_rx_fifo %p, refcnt %d,"
860 " session_tx_fifo %p, refcnt %d",
861 getpid (), mp->handle, session_index,
Dave Wallace60caa062017-11-10 17:07:13 -0500862 session->server_rx_fifo,
863 session->server_rx_fifo->refcnt,
864 session->server_tx_fifo, session->server_tx_fifo->refcnt);
Dave Wallaceee45d412017-11-24 21:44:06 -0500865done_unlock:
Dave Wallace543852a2017-08-03 02:11:34 -0400866 clib_spinlock_unlock (&vcm->sessions_lockp);
867}
868
869static void
870vppcom_send_connect_sock (session_t * session, u32 session_index)
871{
Dave Wallace543852a2017-08-03 02:11:34 -0400872 vl_api_connect_sock_t *cmp;
873
874 /* Assumes caller as acquired the spinlock: vcm->sessions_lockp */
875 session->is_server = 0;
876 cmp = vl_msg_api_alloc (sizeof (*cmp));
877 memset (cmp, 0, sizeof (*cmp));
878 cmp->_vl_msg_id = ntohs (VL_API_CONNECT_SOCK);
879 cmp->client_index = vcm->my_client_index;
Dave Wallace33e002b2017-09-06 01:20:02 -0400880 cmp->context = session_index;
Dave Wallace543852a2017-08-03 02:11:34 -0400881
Dave Wallace543852a2017-08-03 02:11:34 -0400882 cmp->vrf = session->vrf;
Dave Wallace35830af2017-10-09 01:43:42 -0400883 cmp->is_ip4 = session->peer_addr.is_ip4;
884 clib_memcpy (cmp->ip, &session->peer_addr.ip46, sizeof (cmp->ip));
Stevenac1f96d2017-10-24 16:03:58 -0700885 cmp->port = session->peer_port;
Dave Wallace543852a2017-08-03 02:11:34 -0400886 cmp->proto = session->proto;
887 clib_memcpy (cmp->options, session->options, sizeof (cmp->options));
888 vl_msg_api_send_shmem (vcm->vl_input_queue, (u8 *) & cmp);
889}
890
Dave Wallace66cf6eb2017-10-26 02:51:07 -0400891static inline void
Dave Wallace4878cbe2017-11-21 03:45:09 -0500892vppcom_send_disconnect_session_reply (u64 vpp_handle, u32 session_index,
893 int rv)
894{
895 vl_api_disconnect_session_reply_t *rmp;
896
897 if (VPPCOM_DEBUG > 1)
898 clib_warning ("[%d] vpp handle 0x%llx, sid %u: sending disconnect msg",
899 getpid (), vpp_handle, session_index);
900
901 rmp = vl_msg_api_alloc (sizeof (*rmp));
902 memset (rmp, 0, sizeof (*rmp));
903
904 rmp->_vl_msg_id = ntohs (VL_API_DISCONNECT_SESSION_REPLY);
905 rmp->retval = htonl (rv);
906 rmp->handle = vpp_handle;
907 vl_msg_api_send_shmem (vcm->vl_input_queue, (u8 *) & rmp);
908}
909
910static inline void
911vppcom_send_disconnect_session (u64 vpp_handle, u32 session_index)
Dave Wallace543852a2017-08-03 02:11:34 -0400912{
Dave Wallace543852a2017-08-03 02:11:34 -0400913 vl_api_disconnect_session_t *dmp;
Dave Wallace543852a2017-08-03 02:11:34 -0400914
Dave Wallace4878cbe2017-11-21 03:45:09 -0500915 if (VPPCOM_DEBUG > 1)
916 clib_warning ("[%d] vpp handle 0x%llx, sid %u: sending disconnect msg",
917 getpid (), vpp_handle, session_index);
918
Dave Wallace543852a2017-08-03 02:11:34 -0400919 dmp = vl_msg_api_alloc (sizeof (*dmp));
920 memset (dmp, 0, sizeof (*dmp));
921 dmp->_vl_msg_id = ntohs (VL_API_DISCONNECT_SESSION);
922 dmp->client_index = vcm->my_client_index;
Dave Wallace4878cbe2017-11-21 03:45:09 -0500923 dmp->handle = vpp_handle;
Dave Wallace543852a2017-08-03 02:11:34 -0400924 vl_msg_api_send_shmem (vcm->vl_input_queue, (u8 *) & dmp);
Dave Wallace543852a2017-08-03 02:11:34 -0400925}
926
927static void
928vl_api_bind_sock_reply_t_handler (vl_api_bind_sock_reply_t * mp)
929{
Dave Wallace543852a2017-08-03 02:11:34 -0400930 session_t *session = 0;
Dave Wallace4878cbe2017-11-21 03:45:09 -0500931 u32 session_index = mp->context;
Dave Wallace543852a2017-08-03 02:11:34 -0400932 int rv;
933
Dave Wallaceee45d412017-11-24 21:44:06 -0500934 VCL_LOCK_AND_GET_SESSION (session_index, &session);
935done:
Dave Wallace543852a2017-08-03 02:11:34 -0400936 if (mp->retval)
Dave Wallace4878cbe2017-11-21 03:45:09 -0500937 {
Dave Wallaceee45d412017-11-24 21:44:06 -0500938 clib_warning ("[%d] ERROR: vpp handle 0x%llx, sid %u: bind failed: %U",
939 getpid (), mp->handle, session_index, format_api_error,
Dave Wallace4878cbe2017-11-21 03:45:09 -0500940 ntohl (mp->retval));
941 rv = vppcom_session_at_index (session_index, &session);
942 if (rv == VPPCOM_OK)
Dave Wallaceee45d412017-11-24 21:44:06 -0500943 {
944 session->state = STATE_FAILED;
945 session->vpp_handle = mp->handle;
946 }
947 else
948 {
949 clib_warning ("[%s] ERROR: vpp handle 0x%llx, sid %u: "
950 "Invalid session index (%u)!",
951 getpid (), mp->handle, session_index);
952 }
953 goto done_unlock;
Dave Wallace4878cbe2017-11-21 03:45:09 -0500954 }
Dave Wallace543852a2017-08-03 02:11:34 -0400955
Dave Wallaceee45d412017-11-24 21:44:06 -0500956 session->vpp_handle = mp->handle;
957 session->lcl_addr.is_ip4 = mp->lcl_is_ip4;
958 clib_memcpy (&session->lcl_addr.ip46, mp->lcl_ip,
959 sizeof (session->peer_addr.ip46));
960 session->lcl_port = mp->lcl_port;
961 vppcom_session_table_add_listener (mp->handle, session_index);
962 session->is_listen = 1;
963 session->state = STATE_LISTEN;
Dave Wallace4878cbe2017-11-21 03:45:09 -0500964
Dave Wallaceee45d412017-11-24 21:44:06 -0500965 if (VPPCOM_DEBUG > 1)
966 clib_warning ("[%d] vpp handle 0x%llx, sid %u: bind succeeded!",
967 getpid (), mp->handle, mp->context);
968done_unlock:
Dave Wallace543852a2017-08-03 02:11:34 -0400969 clib_spinlock_unlock (&vcm->sessions_lockp);
970}
971
972static void
973vl_api_unbind_sock_reply_t_handler (vl_api_unbind_sock_reply_t * mp)
974{
Dave Wallace4878cbe2017-11-21 03:45:09 -0500975 if (mp->retval)
976 clib_warning ("[%d] ERROR: sid %u: unbind failed: %U",
977 getpid (), mp->context, format_api_error,
978 ntohl (mp->retval));
Dave Wallace543852a2017-08-03 02:11:34 -0400979
Dave Wallace4878cbe2017-11-21 03:45:09 -0500980 else if (VPPCOM_DEBUG > 1)
981 clib_warning ("[%d] sid %u: unbind succeeded!", getpid (), mp->context);
Dave Wallace543852a2017-08-03 02:11:34 -0400982}
983
984u8 *
985format_ip4_address (u8 * s, va_list * args)
986{
987 u8 *a = va_arg (*args, u8 *);
988 return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
989}
990
991u8 *
992format_ip6_address (u8 * s, va_list * args)
993{
994 ip6_address_t *a = va_arg (*args, ip6_address_t *);
995 u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
996
997 i_max_n_zero = ARRAY_LEN (a->as_u16);
998 max_n_zeros = 0;
999 i_first_zero = i_max_n_zero;
1000 n_zeros = 0;
1001 for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
1002 {
1003 u32 is_zero = a->as_u16[i] == 0;
1004 if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
1005 {
1006 i_first_zero = i;
1007 n_zeros = 0;
1008 }
1009 n_zeros += is_zero;
1010 if ((!is_zero && n_zeros > max_n_zeros)
1011 || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
1012 {
1013 i_max_n_zero = i_first_zero;
1014 max_n_zeros = n_zeros;
1015 i_first_zero = ARRAY_LEN (a->as_u16);
1016 n_zeros = 0;
1017 }
1018 }
1019
1020 last_double_colon = 0;
1021 for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
1022 {
1023 if (i == i_max_n_zero && max_n_zeros > 1)
1024 {
1025 s = format (s, "::");
1026 i += max_n_zeros - 1;
1027 last_double_colon = 1;
1028 }
1029 else
1030 {
1031 s = format (s, "%s%x",
1032 (last_double_colon || i == 0) ? "" : ":",
1033 clib_net_to_host_u16 (a->as_u16[i]));
1034 last_double_colon = 0;
1035 }
1036 }
1037
1038 return s;
1039}
1040
1041/* Format an IP46 address. */
1042u8 *
1043format_ip46_address (u8 * s, va_list * args)
1044{
1045 ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
1046 ip46_type_t type = va_arg (*args, ip46_type_t);
1047 int is_ip4 = 1;
1048
1049 switch (type)
1050 {
1051 case IP46_TYPE_ANY:
1052 is_ip4 = ip46_address_is_ip4 (ip46);
1053 break;
1054 case IP46_TYPE_IP4:
1055 is_ip4 = 1;
1056 break;
1057 case IP46_TYPE_IP6:
1058 is_ip4 = 0;
1059 break;
1060 }
1061
1062 return is_ip4 ?
1063 format (s, "%U", format_ip4_address, &ip46->ip4) :
1064 format (s, "%U", format_ip6_address, &ip46->ip6);
1065}
1066
Dave Wallace60caa062017-11-10 17:07:13 -05001067static inline void
Florin Coras50e8bdb2017-11-27 10:37:05 -08001068vppcom_send_accept_session_reply (u64 handle, u32 context, int retval)
Dave Wallace60caa062017-11-10 17:07:13 -05001069{
1070 vl_api_accept_session_reply_t *rmp;
1071
1072 rmp = vl_msg_api_alloc (sizeof (*rmp));
1073 memset (rmp, 0, sizeof (*rmp));
1074 rmp->_vl_msg_id = ntohs (VL_API_ACCEPT_SESSION_REPLY);
1075 rmp->retval = htonl (retval);
Dave Wallaced2931962017-11-25 04:17:39 -05001076 rmp->context = context;
Dave Wallace60caa062017-11-10 17:07:13 -05001077 rmp->handle = handle;
1078 vl_msg_api_send_shmem (vcm->vl_input_queue, (u8 *) & rmp);
1079}
1080
Dave Wallace543852a2017-08-03 02:11:34 -04001081static void
1082vl_api_accept_session_t_handler (vl_api_accept_session_t * mp)
1083{
Dave Wallace543852a2017-08-03 02:11:34 -04001084 svm_fifo_t *rx_fifo, *tx_fifo;
Florin Corasdcf55ce2017-11-16 15:32:50 -08001085 session_t *session, *listen_session;
Dave Wallace543852a2017-08-03 02:11:34 -04001086 u32 session_index;
Dave Wallace543852a2017-08-03 02:11:34 -04001087
Dave Wallace60caa062017-11-10 17:07:13 -05001088 clib_spinlock_lock (&vcm->sessions_lockp);
Dave Wallace543852a2017-08-03 02:11:34 -04001089 if (!clib_fifo_free_elts (vcm->client_session_index_fifo))
1090 {
Dave Wallace2e005bb2017-11-07 01:21:39 -05001091 clib_warning ("[%d] client session queue is full!", getpid ());
Dave Wallaced2931962017-11-25 04:17:39 -05001092 vppcom_send_accept_session_reply (mp->handle, mp->context,
Florin Corasdcf55ce2017-11-16 15:32:50 -08001093 VNET_API_ERROR_QUEUE_FULL);
1094 clib_spinlock_unlock (&vcm->sessions_lockp);
1095 return;
1096 }
1097
1098 listen_session = vppcom_session_table_lookup_listener (mp->listener_handle);
1099 if (!listen_session)
1100 {
1101 clib_warning ("[%d] ERROR: couldn't find listen session: unknown vpp "
1102 "listener handle %llx", getpid (), mp->listener_handle);
Dave Wallace60caa062017-11-10 17:07:13 -05001103 clib_spinlock_unlock (&vcm->sessions_lockp);
1104 return;
Dave Wallace543852a2017-08-03 02:11:34 -04001105 }
1106
Dave Wallace543852a2017-08-03 02:11:34 -04001107 /* Allocate local session and set it up */
1108 pool_get (vcm->sessions, session);
1109 memset (session, 0, sizeof (*session));
1110 session_index = session - vcm->sessions;
1111
1112 rx_fifo = uword_to_pointer (mp->server_rx_fifo, svm_fifo_t *);
1113 rx_fifo->client_session_index = session_index;
1114 tx_fifo = uword_to_pointer (mp->server_tx_fifo, svm_fifo_t *);
1115 tx_fifo->client_session_index = session_index;
1116
Dave Wallace60caa062017-11-10 17:07:13 -05001117 session->vpp_handle = mp->handle;
Dave Wallaced2931962017-11-25 04:17:39 -05001118 session->client_context = mp->context;
Dave Wallace543852a2017-08-03 02:11:34 -04001119 session->server_rx_fifo = rx_fifo;
1120 session->server_tx_fifo = tx_fifo;
Dave Wallace33e002b2017-09-06 01:20:02 -04001121 session->vpp_event_queue = uword_to_pointer (mp->vpp_event_queue_address,
1122 unix_shared_memory_queue_t *);
Dave Wallace543852a2017-08-03 02:11:34 -04001123 session->state = STATE_ACCEPT;
1124 session->is_cut_thru = 0;
Dave Wallace19481612017-09-15 18:47:44 -04001125 session->is_server = 1;
Stevenac1f96d2017-10-24 16:03:58 -07001126 session->peer_port = mp->port;
Dave Wallace35830af2017-10-09 01:43:42 -04001127 session->peer_addr.is_ip4 = mp->is_ip4;
1128 clib_memcpy (&session->peer_addr.ip46, mp->ip,
1129 sizeof (session->peer_addr.ip46));
Dave Wallace543852a2017-08-03 02:11:34 -04001130
1131 /* Add it to lookup table */
1132 hash_set (vcm->session_index_by_vpp_handles, mp->handle, session_index);
Florin Corasdcf55ce2017-11-16 15:32:50 -08001133 session->lcl_port = listen_session->lcl_port;
1134 session->lcl_addr = listen_session->lcl_addr;
Dave Wallace227867f2017-11-13 21:21:53 -05001135
1136 /* TBD: move client_session_index_fifo into listener session */
Dave Wallace543852a2017-08-03 02:11:34 -04001137 clib_fifo_add1 (vcm->client_session_index_fifo, session_index);
Florin Corasdcf55ce2017-11-16 15:32:50 -08001138
Dave Wallacef7f809c2017-10-03 01:48:42 -04001139 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace543852a2017-08-03 02:11:34 -04001140
Dave Wallace60caa062017-11-10 17:07:13 -05001141 if (VPPCOM_DEBUG > 1)
Dave Wallaced2931962017-11-25 04:17:39 -05001142 clib_warning ("[%d] vpp handle 0x%llx, sid %u: client accept "
Florin Coras50e8bdb2017-11-27 10:37:05 -08001143 "request from %s address %U port %d queue %p!", getpid (),
Dave Wallaced2931962017-11-25 04:17:39 -05001144 mp->handle, session_index, mp->is_ip4 ? "IPv4" : "IPv6",
1145 format_ip46_address, &mp->ip, mp->is_ip4,
Florin Coras50e8bdb2017-11-27 10:37:05 -08001146 clib_net_to_host_u16 (mp->port), session->vpp_event_queue);
Dave Wallace60caa062017-11-10 17:07:13 -05001147}
1148
1149static void
Dave Wallaceee45d412017-11-24 21:44:06 -05001150vppcom_send_connect_session_reply (session_t * session, u32 session_index,
Dave Wallaced2931962017-11-25 04:17:39 -05001151 u64 vpp_handle, u32 context, int retval)
Dave Wallace60caa062017-11-10 17:07:13 -05001152{
1153 vl_api_connect_session_reply_t *rmp;
1154 u32 len;
1155 unix_shared_memory_queue_t *client_q;
1156
Dave Wallace543852a2017-08-03 02:11:34 -04001157 rmp = vl_msg_api_alloc (sizeof (*rmp));
1158 memset (rmp, 0, sizeof (*rmp));
Dave Wallace60caa062017-11-10 17:07:13 -05001159 rmp->_vl_msg_id = ntohs (VL_API_CONNECT_SESSION_REPLY);
Dave Wallaced2931962017-11-25 04:17:39 -05001160
1161 if (!session)
1162 {
1163 rmp->context = context;
1164 rmp->handle = vpp_handle;
1165 rmp->retval = htonl (retval);
1166 vl_msg_api_send_shmem (vcm->vl_input_queue, (u8 *) & rmp);
1167 return;
1168 }
1169
Dave Wallace227867f2017-11-13 21:21:53 -05001170 rmp->context = session->client_context;
Dave Wallace60caa062017-11-10 17:07:13 -05001171 rmp->retval = htonl (retval);
Dave Wallace227867f2017-11-13 21:21:53 -05001172 rmp->handle = session->vpp_handle;
1173 rmp->server_rx_fifo = pointer_to_uword (session->server_rx_fifo);
1174 rmp->server_tx_fifo = pointer_to_uword (session->server_tx_fifo);
1175 rmp->vpp_event_queue_address = pointer_to_uword (session->vpp_event_queue);
1176 rmp->segment_size = vcm->cfg.segment_size;
1177 len = vec_len (session->segment_name);
1178 rmp->segment_name_length = clib_min (len, sizeof (rmp->segment_name));
1179 clib_memcpy (rmp->segment_name, session->segment_name,
1180 rmp->segment_name_length - 1);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001181 clib_memcpy (rmp->lcl_ip, session->peer_addr.ip46.as_u8,
Dave Wallace227867f2017-11-13 21:21:53 -05001182 sizeof (rmp->lcl_ip));
Dave Wallace4878cbe2017-11-21 03:45:09 -05001183 rmp->is_ip4 = session->peer_addr.is_ip4;
1184 rmp->lcl_port = session->peer_port;
Dave Wallace60caa062017-11-10 17:07:13 -05001185 client_q = uword_to_pointer (session->client_queue_address,
1186 unix_shared_memory_queue_t *);
1187 ASSERT (client_q);
1188 vl_msg_api_send_shmem (client_q, (u8 *) & rmp);
Dave Wallace543852a2017-08-03 02:11:34 -04001189}
1190
1191/*
1192 * Acting as server for redirected connect requests
1193 */
1194static void
1195vl_api_connect_sock_t_handler (vl_api_connect_sock_t * mp)
1196{
Dave Wallace543852a2017-08-03 02:11:34 -04001197 u32 session_index;
Dave Wallace543852a2017-08-03 02:11:34 -04001198 session_t *session = 0;
Dave Wallace543852a2017-08-03 02:11:34 -04001199
Dave Wallacef7f809c2017-10-03 01:48:42 -04001200 clib_spinlock_lock (&vcm->sessions_lockp);
Dave Wallace543852a2017-08-03 02:11:34 -04001201 if (!clib_fifo_free_elts (vcm->client_session_index_fifo))
1202 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05001203 clib_spinlock_unlock (&vcm->sessions_lockp);
1204
Dave Wallace543852a2017-08-03 02:11:34 -04001205 if (VPPCOM_DEBUG > 1)
Dave Wallace2e005bb2017-11-07 01:21:39 -05001206 clib_warning ("[%d] client session queue is full!", getpid ());
Dave Wallace4878cbe2017-11-21 03:45:09 -05001207
Dave Wallaced2931962017-11-25 04:17:39 -05001208 /* TBD: Fix api to include vpp handle */
1209 vppcom_send_connect_session_reply (0 /* session */ , 0 /* sid */ ,
1210 0 /* handle */ , mp->context,
1211 VNET_API_ERROR_QUEUE_FULL);
Dave Wallace60caa062017-11-10 17:07:13 -05001212 return;
Dave Wallace543852a2017-08-03 02:11:34 -04001213 }
1214
Dave Wallace543852a2017-08-03 02:11:34 -04001215 pool_get (vcm->sessions, session);
1216 memset (session, 0, sizeof (*session));
1217 session_index = session - vcm->sessions;
1218
Dave Wallace60caa062017-11-10 17:07:13 -05001219 session->client_context = mp->context;
1220 session->vpp_handle = session_index;
Dave Wallace543852a2017-08-03 02:11:34 -04001221 session->client_queue_address = mp->client_queue_address;
1222 session->is_cut_thru = 1;
1223 session->is_server = 1;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001224 session->lcl_port = mp->port;
1225 session->lcl_addr.is_ip4 = mp->is_ip4;
1226 clib_memcpy (&session->lcl_addr.ip46, mp->ip,
1227 sizeof (session->lcl_addr.ip46));
1228
1229 /* TBD: missing peer info in api msg.
1230 */
Dave Wallace35830af2017-10-09 01:43:42 -04001231 session->peer_addr.is_ip4 = mp->is_ip4;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001232 ASSERT (session->lcl_addr.is_ip4 == session->peer_addr.is_ip4);
Dave Wallace6d5c4cd2017-08-15 16:56:29 -04001233
Dave Wallace543852a2017-08-03 02:11:34 -04001234 session->state = STATE_ACCEPT;
Dave Wallace543852a2017-08-03 02:11:34 -04001235 clib_fifo_add1 (vcm->client_session_index_fifo, session_index);
Dave Wallace2e005bb2017-11-07 01:21:39 -05001236 if (VPPCOM_DEBUG > 1)
Dave Wallace4878cbe2017-11-21 03:45:09 -05001237 clib_warning ("[%d] sid %u: Got a cut-thru connect request! "
1238 "clib_fifo_elts %u!\n", getpid (), session_index,
1239 clib_fifo_elts (vcm->client_session_index_fifo));
Dave Wallacef7f809c2017-10-03 01:48:42 -04001240 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace543852a2017-08-03 02:11:34 -04001241}
1242
1243static void
Dave Wallace4878cbe2017-11-21 03:45:09 -05001244vppcom_send_bind_sock (session_t * session, u32 session_index)
Dave Wallace543852a2017-08-03 02:11:34 -04001245{
Dave Wallace543852a2017-08-03 02:11:34 -04001246 vl_api_bind_sock_t *bmp;
1247
1248 /* Assumes caller has acquired spinlock: vcm->sessions_lockp */
1249 session->is_server = 1;
1250 bmp = vl_msg_api_alloc (sizeof (*bmp));
1251 memset (bmp, 0, sizeof (*bmp));
1252
1253 bmp->_vl_msg_id = ntohs (VL_API_BIND_SOCK);
1254 bmp->client_index = vcm->my_client_index;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001255 bmp->context = session_index;
Dave Wallace543852a2017-08-03 02:11:34 -04001256 bmp->vrf = session->vrf;
Dave Wallace35830af2017-10-09 01:43:42 -04001257 bmp->is_ip4 = session->lcl_addr.is_ip4;
1258 clib_memcpy (bmp->ip, &session->lcl_addr.ip46, sizeof (bmp->ip));
Stevenac1f96d2017-10-24 16:03:58 -07001259 bmp->port = session->lcl_port;
Dave Wallace543852a2017-08-03 02:11:34 -04001260 bmp->proto = session->proto;
1261 clib_memcpy (bmp->options, session->options, sizeof (bmp->options));
1262 vl_msg_api_send_shmem (vcm->vl_input_queue, (u8 *) & bmp);
1263}
1264
1265static void
Dave Wallace4878cbe2017-11-21 03:45:09 -05001266vppcom_send_unbind_sock (u64 vpp_handle)
Dave Wallace543852a2017-08-03 02:11:34 -04001267{
Dave Wallace543852a2017-08-03 02:11:34 -04001268 vl_api_unbind_sock_t *ump;
Dave Wallace543852a2017-08-03 02:11:34 -04001269
1270 ump = vl_msg_api_alloc (sizeof (*ump));
1271 memset (ump, 0, sizeof (*ump));
1272
1273 ump->_vl_msg_id = ntohs (VL_API_UNBIND_SOCK);
1274 ump->client_index = vcm->my_client_index;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001275 ump->handle = vpp_handle;
Dave Wallace543852a2017-08-03 02:11:34 -04001276 vl_msg_api_send_shmem (vcm->vl_input_queue, (u8 *) & ump);
1277}
1278
1279static int
Dave Wallace543852a2017-08-03 02:11:34 -04001280vppcom_session_unbind (u32 session_index)
1281{
Dave Wallace4878cbe2017-11-21 03:45:09 -05001282 session_t *session = 0;
Dave Wallace543852a2017-08-03 02:11:34 -04001283 int rv;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001284 u64 vpp_handle;
Dave Wallace543852a2017-08-03 02:11:34 -04001285
Dave Wallace4878cbe2017-11-21 03:45:09 -05001286 VCL_LOCK_AND_GET_SESSION (session_index, &session);
1287
1288 vpp_handle = session->vpp_handle;
1289 vppcom_session_table_del_listener (vpp_handle);
1290 session->vpp_handle = ~0;
1291 session->state = STATE_DISCONNECT;
1292
Dave Wallace543852a2017-08-03 02:11:34 -04001293 clib_spinlock_unlock (&vcm->sessions_lockp);
1294
Dave Wallace4878cbe2017-11-21 03:45:09 -05001295 if (VPPCOM_DEBUG > 1)
1296 clib_warning ("[%d] vpp handle 0x%llx, sid %u: "
1297 "sending unbind msg! new state 0x%x (%s)",
1298 getpid (), vpp_handle, session_index,
1299 session->state, vppcom_session_state_str (session->state));
1300
1301 vppcom_send_unbind_sock (vpp_handle);
1302
1303done:
1304 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04001305}
1306
Dave Wallace66cf6eb2017-10-26 02:51:07 -04001307static inline int
Dave Wallace543852a2017-08-03 02:11:34 -04001308vppcom_session_disconnect (u32 session_index)
1309{
Dave Wallace543852a2017-08-03 02:11:34 -04001310 int rv;
Dave Wallace66cf6eb2017-10-26 02:51:07 -04001311 session_t *session;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001312 u8 is_cut_thru, is_listen, is_server;
1313 u64 vpp_handle;
1314 session_state_t state;
Dave Wallace543852a2017-08-03 02:11:34 -04001315
Dave Wallace4878cbe2017-11-21 03:45:09 -05001316 VCL_LOCK_AND_GET_SESSION (session_index, &session);
1317
1318 vpp_handle = session->vpp_handle;
1319 is_server = session->is_server;
1320 is_listen = session->is_listen;
1321 is_cut_thru = session->is_cut_thru;
1322 state = session->state;
1323 clib_spinlock_unlock (&vcm->sessions_lockp);
1324
1325 if (VPPCOM_DEBUG > 1)
Dave Wallace543852a2017-08-03 02:11:34 -04001326 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05001327 clib_warning ("[%d] vpp handle 0x%llx, sid %u: %s state 0x%x (%s), "
1328 "is_cut_thru %d, is_listen %d",
1329 getpid (), vpp_handle, session_index,
1330 is_server ? "server" : "client",
1331 state, vppcom_session_state_str (state),
1332 is_cut_thru, is_listen);
Dave Wallace543852a2017-08-03 02:11:34 -04001333 }
Dave Wallace66cf6eb2017-10-26 02:51:07 -04001334
Dave Wallace4878cbe2017-11-21 03:45:09 -05001335 if (PREDICT_FALSE (is_listen))
Dave Wallace66cf6eb2017-10-26 02:51:07 -04001336 {
Dave Wallaceee45d412017-11-24 21:44:06 -05001337 clib_warning ("[%d] ERROR: vpp handle 0x%llx, sid %u: "
1338 "Cannot disconnect a listen socket!",
1339 getpid (), vpp_handle, session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001340 rv = VPPCOM_EBADFD;
1341 goto done;
1342 }
Dave Wallace66cf6eb2017-10-26 02:51:07 -04001343
Dave Wallace4878cbe2017-11-21 03:45:09 -05001344 /* Through the VPP host stack...
1345 */
1346 else if (!is_cut_thru)
1347 {
1348 /* The peer has already initiated the close,
1349 * so send the disconnect session reply.
Dave Wallace227867f2017-11-13 21:21:53 -05001350 */
Dave Wallace4878cbe2017-11-21 03:45:09 -05001351 if (state & STATE_CLOSE_ON_EMPTY)
1352 {
1353 vppcom_send_disconnect_session_reply (vpp_handle,
1354 session_index, 0 /* rv */ );
1355 if (VPPCOM_DEBUG > 1)
Dave Wallaceee45d412017-11-24 21:44:06 -05001356 clib_warning ("[%d] vpp handle 0x%llx, sid %u: "
1357 "sending disconnect REPLY...",
1358 getpid (), vpp_handle, session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001359 }
1360
1361 /* Otherwise, send a disconnect session msg...
1362 */
1363 else
1364 {
1365 if (VPPCOM_DEBUG > 1)
Dave Wallaceee45d412017-11-24 21:44:06 -05001366 clib_warning ("[%d] vpp handle 0x%llx, sid %u: "
1367 "sending disconnect...",
1368 getpid (), vpp_handle, session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001369
1370 vppcom_send_disconnect_session (vpp_handle, session_index);
1371 }
Dave Wallace66cf6eb2017-10-26 02:51:07 -04001372 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05001373
1374 /* Cut-thru connections...
1375 *
1376 * server: free fifos and segment allocated during connect/redirect
1377 * client: no cleanup required
1378 */
Dave Wallace66cf6eb2017-10-26 02:51:07 -04001379 else
Dave Wallace227867f2017-11-13 21:21:53 -05001380 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05001381 if (is_server)
1382 {
1383 svm_fifo_segment_main_t *sm = &svm_fifo_segment_main;
1384 svm_fifo_segment_private_t *seg;
1385
1386 VCL_LOCK_AND_GET_SESSION (session_index, &session);
1387
1388 if (VPPCOM_DEBUG > 1)
1389 clib_warning ("[%d] sid %d: freeing cut-thru fifos in "
Dave Wallaceee45d412017-11-24 21:44:06 -05001390 "sm_seg_index %d! "
1391 " server_rx_fifo %p, refcnt = %d"
1392 " server_tx_fifo %p, refcnt = %d",
Dave Wallace4878cbe2017-11-21 03:45:09 -05001393 getpid (), session_index, session->sm_seg_index,
1394 session->server_rx_fifo,
1395 session->server_rx_fifo->refcnt,
1396 session->server_tx_fifo,
1397 session->server_tx_fifo->refcnt);
1398
1399 seg = vec_elt_at_index (sm->segments, session->sm_seg_index);
1400 svm_fifo_segment_free_fifo (seg, session->server_rx_fifo,
1401 FIFO_SEGMENT_RX_FREELIST);
1402 svm_fifo_segment_free_fifo (seg, session->server_tx_fifo,
1403 FIFO_SEGMENT_TX_FREELIST);
1404 svm_fifo_segment_delete (seg);
1405
1406 /* TBD: Send cut-thru disconnect event to client */
1407
1408 clib_spinlock_unlock (&vcm->sessions_lockp);
1409 }
1410 else
1411 {
1412 /* TBD: Send cut-thru disconnect event to server */
1413 }
Dave Wallace227867f2017-11-13 21:21:53 -05001414 }
Dave Wallace66cf6eb2017-10-26 02:51:07 -04001415
Dave Wallace4878cbe2017-11-21 03:45:09 -05001416done:
1417 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04001418}
1419
1420#define foreach_sock_msg \
1421_(SESSION_ENABLE_DISABLE_REPLY, session_enable_disable_reply) \
1422_(BIND_SOCK_REPLY, bind_sock_reply) \
1423_(UNBIND_SOCK_REPLY, unbind_sock_reply) \
1424_(ACCEPT_SESSION, accept_session) \
1425_(CONNECT_SOCK, connect_sock) \
Dave Wallace33e002b2017-09-06 01:20:02 -04001426_(CONNECT_SESSION_REPLY, connect_session_reply) \
Dave Wallace543852a2017-08-03 02:11:34 -04001427_(DISCONNECT_SESSION, disconnect_session) \
1428_(DISCONNECT_SESSION_REPLY, disconnect_session_reply) \
1429_(RESET_SESSION, reset_session) \
1430_(APPLICATION_ATTACH_REPLY, application_attach_reply) \
1431_(APPLICATION_DETACH_REPLY, application_detach_reply) \
1432_(MAP_ANOTHER_SEGMENT, map_another_segment)
1433
1434static void
1435vppcom_api_hookup (void)
1436{
1437#define _(N,n) \
1438 vl_msg_api_set_handlers(VL_API_##N, #n, \
1439 vl_api_##n##_t_handler, \
1440 vl_noop_handler, \
1441 vl_api_##n##_t_endian, \
1442 vl_api_##n##_t_print, \
1443 sizeof(vl_api_##n##_t), 1);
1444 foreach_sock_msg;
1445#undef _
1446}
1447
1448static void
1449vppcom_cfg_init (vppcom_cfg_t * vcl_cfg)
1450{
1451 ASSERT (vcl_cfg);
1452
1453 vcl_cfg->heapsize = (256ULL << 20);
Dave Wallacec8f1ee62017-11-29 22:46:32 -05001454 vcl_cfg->vpp_api_q_length = 1024;
Dave Wallace543852a2017-08-03 02:11:34 -04001455 vcl_cfg->segment_baseva = 0x200000000ULL;
1456 vcl_cfg->segment_size = (256 << 20);
1457 vcl_cfg->add_segment_size = (128 << 20);
1458 vcl_cfg->preallocated_fifo_pairs = 8;
1459 vcl_cfg->rx_fifo_size = (1 << 20);
1460 vcl_cfg->tx_fifo_size = (1 << 20);
1461 vcl_cfg->event_queue_size = 2048;
1462 vcl_cfg->listen_queue_size = CLIB_CACHE_LINE_BYTES / sizeof (u32);
1463 vcl_cfg->app_timeout = 10 * 60.0;
1464 vcl_cfg->session_timeout = 10 * 60.0;
1465 vcl_cfg->accept_timeout = 60.0;
1466}
1467
1468static void
1469vppcom_cfg_heapsize (char *conf_fname)
1470{
Dave Wallace543852a2017-08-03 02:11:34 -04001471 vppcom_cfg_t *vcl_cfg = &vcm->cfg;
1472 FILE *fp;
1473 char inbuf[4096];
1474 int argc = 1;
1475 char **argv = NULL;
1476 char *arg = NULL;
1477 char *p;
1478 int i;
1479 u8 *sizep;
1480 u32 size;
Dave Wallace2e005bb2017-11-07 01:21:39 -05001481 void *vcl_mem;
1482 void *heap;
Dave Wallace543852a2017-08-03 02:11:34 -04001483
1484 fp = fopen (conf_fname, "r");
1485 if (fp == NULL)
1486 {
1487 if (VPPCOM_DEBUG > 0)
1488 fprintf (stderr, "open configuration file '%s' failed\n", conf_fname);
1489 goto defaulted;
1490 }
1491 argv = calloc (1, sizeof (char *));
1492 if (argv == NULL)
1493 goto defaulted;
1494
1495 while (1)
1496 {
1497 if (fgets (inbuf, 4096, fp) == 0)
1498 break;
1499 p = strtok (inbuf, " \t\n");
1500 while (p != NULL)
1501 {
1502 if (*p == '#')
1503 break;
1504 argc++;
1505 char **tmp = realloc (argv, argc * sizeof (char *));
1506 if (tmp == NULL)
Chris Lukeab7b8d92017-09-07 07:40:13 -04001507 goto defaulted;
Dave Wallace543852a2017-08-03 02:11:34 -04001508 argv = tmp;
1509 arg = strndup (p, 1024);
1510 if (arg == NULL)
Chris Lukeab7b8d92017-09-07 07:40:13 -04001511 goto defaulted;
Dave Wallace543852a2017-08-03 02:11:34 -04001512 argv[argc - 1] = arg;
1513 p = strtok (NULL, " \t\n");
1514 }
1515 }
1516
1517 fclose (fp);
Chris Lukeab7b8d92017-09-07 07:40:13 -04001518 fp = NULL;
Dave Wallace543852a2017-08-03 02:11:34 -04001519
1520 char **tmp = realloc (argv, (argc + 1) * sizeof (char *));
1521 if (tmp == NULL)
1522 goto defaulted;
1523 argv = tmp;
1524 argv[argc] = NULL;
1525
1526 /*
1527 * Look for and parse the "heapsize" config parameter.
1528 * Manual since none of the clib infra has been bootstrapped yet.
1529 *
1530 * Format: heapsize <nn>[mM][gG]
1531 */
1532
1533 for (i = 1; i < (argc - 1); i++)
1534 {
1535 if (!strncmp (argv[i], "heapsize", 8))
1536 {
1537 sizep = (u8 *) argv[i + 1];
1538 size = 0;
1539 while (*sizep >= '0' && *sizep <= '9')
1540 {
1541 size *= 10;
1542 size += *sizep++ - '0';
1543 }
1544 if (size == 0)
1545 {
1546 if (VPPCOM_DEBUG > 0)
1547 clib_warning ("[%d] parse error '%s %s', "
1548 "using default heapsize %lld (0x%llx)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05001549 getpid (), argv[i], argv[i + 1],
Dave Wallace543852a2017-08-03 02:11:34 -04001550 vcl_cfg->heapsize, vcl_cfg->heapsize);
1551 goto defaulted;
1552 }
1553
1554 if (*sizep == 'g' || *sizep == 'G')
1555 vcl_cfg->heapsize = size << 30;
1556 else if (*sizep == 'm' || *sizep == 'M')
1557 vcl_cfg->heapsize = size << 20;
1558 else
1559 {
1560 if (VPPCOM_DEBUG > 0)
1561 clib_warning ("[%d] parse error '%s %s', "
1562 "using default heapsize %lld (0x%llx)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05001563 getpid (), argv[i], argv[i + 1],
Dave Wallace543852a2017-08-03 02:11:34 -04001564 vcl_cfg->heapsize, vcl_cfg->heapsize);
1565 goto defaulted;
1566 }
1567 }
1568 }
1569
1570defaulted:
Chris Lukeab7b8d92017-09-07 07:40:13 -04001571 if (fp != NULL)
1572 fclose (fp);
1573 if (argv != NULL)
1574 free (argv);
Dave Wallacee7fa24e2017-11-07 13:07:44 -05001575
Dave Wallace2e005bb2017-11-07 01:21:39 -05001576 vcl_mem = mmap (0, vcl_cfg->heapsize, PROT_READ | PROT_WRITE,
1577 MAP_SHARED | MAP_ANONYMOUS, -1, 0);
Steven0cdd5bd2017-11-08 14:14:45 -08001578 if (vcl_mem == MAP_FAILED)
Dave Wallacee7fa24e2017-11-07 13:07:44 -05001579 {
1580 clib_unix_error ("[%d] ERROR: mmap(0, %lld == 0x%llx, "
1581 "PROT_READ | PROT_WRITE,MAP_SHARED | MAP_ANONYMOUS, "
1582 "-1, 0) failed!",
1583 getpid (), vcl_cfg->heapsize, vcl_cfg->heapsize);
1584 return;
1585 }
Dave Wallace2e005bb2017-11-07 01:21:39 -05001586 heap = clib_mem_init (vcl_mem, vcl_cfg->heapsize);
1587 if (!heap)
Dave Wallace2e005bb2017-11-07 01:21:39 -05001588 {
Dave Wallacee7fa24e2017-11-07 13:07:44 -05001589 clib_warning ("[%d] ERROR: clib_mem_init() failed!", getpid ());
1590 return;
Dave Wallace2e005bb2017-11-07 01:21:39 -05001591 }
Dave Wallacee7fa24e2017-11-07 13:07:44 -05001592 vcl_mem = clib_mem_alloc (sizeof (_vppcom_main));
1593 if (!vcl_mem)
1594 {
1595 clib_warning ("[%d] ERROR: clib_mem_alloc() failed!", getpid ());
1596 return;
1597 }
1598
1599 clib_memcpy (vcl_mem, &_vppcom_main, sizeof (_vppcom_main));
1600 vcm = vcl_mem;
1601
1602 if (VPPCOM_DEBUG > 0)
1603 clib_warning ("[%d] allocated VCL heap = %p, size %lld (0x%llx)",
1604 getpid (), heap, vcl_cfg->heapsize, vcl_cfg->heapsize);
Dave Wallace543852a2017-08-03 02:11:34 -04001605}
1606
1607static void
1608vppcom_cfg_read (char *conf_fname)
1609{
Dave Wallace543852a2017-08-03 02:11:34 -04001610 vppcom_cfg_t *vcl_cfg = &vcm->cfg;
1611 int fd;
1612 unformat_input_t _input, *input = &_input;
1613 unformat_input_t _line_input, *line_input = &_line_input;
1614 u8 vc_cfg_input = 0;
1615 u8 *chroot_path;
1616 struct stat s;
Dave Wallacec8f1ee62017-11-29 22:46:32 -05001617 u32 uid, gid, q_len;
Dave Wallace543852a2017-08-03 02:11:34 -04001618
1619 fd = open (conf_fname, O_RDONLY);
1620 if (fd < 0)
1621 {
1622 if (VPPCOM_DEBUG > 0)
1623 clib_warning ("[%d] open configuration file '%s' failed!",
Dave Wallace2e005bb2017-11-07 01:21:39 -05001624 getpid (), conf_fname);
Dave Wallace543852a2017-08-03 02:11:34 -04001625 goto file_done;
1626 }
1627
1628 if (fstat (fd, &s) < 0)
1629 {
1630 if (VPPCOM_DEBUG > 0)
Dave Wallace2e005bb2017-11-07 01:21:39 -05001631 clib_warning ("[%d] failed to stat `%s'", getpid (), conf_fname);
Dave Wallace543852a2017-08-03 02:11:34 -04001632 goto file_done;
1633 }
1634
1635 if (!(S_ISREG (s.st_mode) || S_ISLNK (s.st_mode)))
1636 {
1637 if (VPPCOM_DEBUG > 0)
Dave Wallace2e005bb2017-11-07 01:21:39 -05001638 clib_warning ("[%d] not a regular file `%s'", getpid (), conf_fname);
Dave Wallace543852a2017-08-03 02:11:34 -04001639 goto file_done;
1640 }
1641
Dave Barach59b25652017-09-10 15:04:27 -04001642 unformat_init_clib_file (input, fd);
Dave Wallace543852a2017-08-03 02:11:34 -04001643
1644 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1645 {
Chris Lukeb2bcad62017-09-18 08:51:22 -04001646 (void) unformat_user (input, unformat_line_input, line_input);
Dave Wallace543852a2017-08-03 02:11:34 -04001647 unformat_skip_white_space (line_input);
1648
Dave Wallace8af20542017-10-26 03:29:30 -04001649 if (unformat (line_input, "vcl {"))
Dave Wallace543852a2017-08-03 02:11:34 -04001650 {
1651 vc_cfg_input = 1;
1652 continue;
1653 }
1654
1655 if (vc_cfg_input)
1656 {
1657 if (unformat (line_input, "heapsize %s", &chroot_path))
1658 {
1659 vec_terminate_c_string (chroot_path);
1660 if (VPPCOM_DEBUG > 0)
1661 clib_warning ("[%d] configured heapsize %s, "
1662 "actual heapsize %lld (0x%llx)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05001663 getpid (), chroot_path, vcl_cfg->heapsize,
Dave Wallace543852a2017-08-03 02:11:34 -04001664 vcl_cfg->heapsize);
1665 vec_free (chroot_path);
1666 }
1667 else if (unformat (line_input, "api-prefix %s", &chroot_path))
1668 {
1669 vec_terminate_c_string (chroot_path);
1670 vl_set_memory_root_path ((char *) chroot_path);
1671 if (VPPCOM_DEBUG > 0)
1672 clib_warning ("[%d] configured api-prefix %s",
Dave Wallace2e005bb2017-11-07 01:21:39 -05001673 getpid (), chroot_path);
Dave Wallace543852a2017-08-03 02:11:34 -04001674 chroot_path = 0; /* Don't vec_free() it! */
1675 }
Dave Wallacec8f1ee62017-11-29 22:46:32 -05001676 else if (unformat (line_input, "vpp-api-q-length %d", &q_len))
1677 {
1678 if (q_len < vcl_cfg->vpp_api_q_length)
1679 {
1680 clib_warning ("[%d] ERROR: configured vpp-api-q-length "
1681 "(%u) is too small! Using default: %u ",
1682 getpid (), q_len, vcl_cfg->vpp_api_q_length);
1683 }
1684 else
1685 {
1686 vcl_cfg->vpp_api_q_length = q_len;
1687
1688 if (VPPCOM_DEBUG > 0)
1689 clib_warning ("[%d] configured vpp-api-q-length %u",
1690 getpid (), vcl_cfg->vpp_api_q_length);
1691 }
1692 }
Dave Wallace543852a2017-08-03 02:11:34 -04001693 else if (unformat (line_input, "uid %d", &uid))
1694 {
1695 vl_set_memory_uid (uid);
1696 if (VPPCOM_DEBUG > 0)
Dave Wallace2e005bb2017-11-07 01:21:39 -05001697 clib_warning ("[%d] configured uid %d", getpid (), uid);
Dave Wallace543852a2017-08-03 02:11:34 -04001698 }
1699 else if (unformat (line_input, "gid %d", &gid))
1700 {
1701 vl_set_memory_gid (gid);
1702 if (VPPCOM_DEBUG > 0)
Dave Wallace2e005bb2017-11-07 01:21:39 -05001703 clib_warning ("[%d] configured gid %d", getpid (), gid);
Dave Wallace543852a2017-08-03 02:11:34 -04001704 }
Dave Wallace8af20542017-10-26 03:29:30 -04001705 else if (unformat (line_input, "segment-baseva 0x%lx",
Dave Wallace543852a2017-08-03 02:11:34 -04001706 &vcl_cfg->segment_baseva))
1707 {
1708 if (VPPCOM_DEBUG > 0)
Dave Wallace8af20542017-10-26 03:29:30 -04001709 clib_warning ("[%d] configured segment_baseva 0x%lx",
Dave Wallace2e005bb2017-11-07 01:21:39 -05001710 getpid (), vcl_cfg->segment_baseva);
Dave Wallace543852a2017-08-03 02:11:34 -04001711 }
1712 else if (unformat (line_input, "segment-size 0x%lx",
1713 &vcl_cfg->segment_size))
1714 {
1715 if (VPPCOM_DEBUG > 0)
1716 clib_warning ("[%d] configured segment_size 0x%lx (%ld)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05001717 getpid (), vcl_cfg->segment_size,
Dave Wallace543852a2017-08-03 02:11:34 -04001718 vcl_cfg->segment_size);
1719 }
1720 else if (unformat (line_input, "segment-size %ld",
1721 &vcl_cfg->segment_size))
1722 {
1723 if (VPPCOM_DEBUG > 0)
1724 clib_warning ("[%d] configured segment_size %ld (0x%lx)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05001725 getpid (), vcl_cfg->segment_size,
Dave Wallace543852a2017-08-03 02:11:34 -04001726 vcl_cfg->segment_size);
1727 }
1728 else if (unformat (line_input, "add-segment-size 0x%lx",
1729 &vcl_cfg->add_segment_size))
1730 {
1731 if (VPPCOM_DEBUG > 0)
1732 clib_warning
1733 ("[%d] configured add_segment_size 0x%lx (%ld)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05001734 getpid (), vcl_cfg->add_segment_size,
Dave Wallace543852a2017-08-03 02:11:34 -04001735 vcl_cfg->add_segment_size);
1736 }
1737 else if (unformat (line_input, "add-segment-size %ld",
1738 &vcl_cfg->add_segment_size))
1739 {
1740 if (VPPCOM_DEBUG > 0)
1741 clib_warning
1742 ("[%d] configured add_segment_size %ld (0x%lx)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05001743 getpid (), vcl_cfg->add_segment_size,
Dave Wallace543852a2017-08-03 02:11:34 -04001744 vcl_cfg->add_segment_size);
1745 }
1746 else if (unformat (line_input, "preallocated-fifo-pairs %d",
1747 &vcl_cfg->preallocated_fifo_pairs))
1748 {
1749 if (VPPCOM_DEBUG > 0)
1750 clib_warning ("[%d] configured preallocated_fifo_pairs "
Dave Wallace2e005bb2017-11-07 01:21:39 -05001751 "%d (0x%x)", getpid (),
Dave Wallace543852a2017-08-03 02:11:34 -04001752 vcl_cfg->preallocated_fifo_pairs,
1753 vcl_cfg->preallocated_fifo_pairs);
1754 }
1755 else if (unformat (line_input, "rx-fifo-size 0x%lx",
1756 &vcl_cfg->rx_fifo_size))
1757 {
1758 if (VPPCOM_DEBUG > 0)
1759 clib_warning ("[%d] configured rx_fifo_size 0x%lx (%ld)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05001760 getpid (), vcl_cfg->rx_fifo_size,
Dave Wallace543852a2017-08-03 02:11:34 -04001761 vcl_cfg->rx_fifo_size);
1762 }
1763 else if (unformat (line_input, "rx-fifo-size %ld",
1764 &vcl_cfg->rx_fifo_size))
1765 {
1766 if (VPPCOM_DEBUG > 0)
1767 clib_warning ("[%d] configured rx_fifo_size %ld (0x%lx)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05001768 getpid (), vcl_cfg->rx_fifo_size,
Dave Wallace543852a2017-08-03 02:11:34 -04001769 vcl_cfg->rx_fifo_size);
1770 }
1771 else if (unformat (line_input, "tx-fifo-size 0x%lx",
1772 &vcl_cfg->tx_fifo_size))
1773 {
1774 if (VPPCOM_DEBUG > 0)
1775 clib_warning ("[%d] configured tx_fifo_size 0x%lx (%ld)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05001776 getpid (), vcl_cfg->tx_fifo_size,
Dave Wallace543852a2017-08-03 02:11:34 -04001777 vcl_cfg->tx_fifo_size);
1778 }
1779 else if (unformat (line_input, "tx-fifo-size %ld",
1780 &vcl_cfg->tx_fifo_size))
1781 {
1782 if (VPPCOM_DEBUG > 0)
1783 clib_warning ("[%d] configured tx_fifo_size %ld (0x%lx)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05001784 getpid (), vcl_cfg->tx_fifo_size,
Dave Wallace543852a2017-08-03 02:11:34 -04001785 vcl_cfg->tx_fifo_size);
1786 }
1787 else if (unformat (line_input, "event-queue-size 0x%lx",
1788 &vcl_cfg->event_queue_size))
1789 {
1790 if (VPPCOM_DEBUG > 0)
1791 clib_warning ("[%d] configured event_queue_size 0x%lx (%ld)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05001792 getpid (), vcl_cfg->event_queue_size,
Dave Wallace543852a2017-08-03 02:11:34 -04001793 vcl_cfg->event_queue_size);
1794 }
1795 else if (unformat (line_input, "event-queue-size %ld",
1796 &vcl_cfg->event_queue_size))
1797 {
1798 if (VPPCOM_DEBUG > 0)
1799 clib_warning ("[%d] configured event_queue_size %ld (0x%lx)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05001800 getpid (), vcl_cfg->event_queue_size,
Dave Wallace543852a2017-08-03 02:11:34 -04001801 vcl_cfg->event_queue_size);
1802 }
1803 else if (unformat (line_input, "listen-queue-size 0x%lx",
1804 &vcl_cfg->listen_queue_size))
1805 {
1806 if (VPPCOM_DEBUG > 0)
1807 clib_warning ("[%d] configured listen_queue_size 0x%lx (%ld)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05001808 getpid (), vcl_cfg->listen_queue_size,
Dave Wallace543852a2017-08-03 02:11:34 -04001809 vcl_cfg->listen_queue_size);
1810 }
1811 else if (unformat (line_input, "listen-queue-size %ld",
1812 &vcl_cfg->listen_queue_size))
1813 {
1814 if (VPPCOM_DEBUG > 0)
1815 clib_warning ("[%d] configured listen_queue_size %ld (0x%lx)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05001816 getpid (), vcl_cfg->listen_queue_size,
Dave Wallace543852a2017-08-03 02:11:34 -04001817 vcl_cfg->listen_queue_size);
1818 }
1819 else if (unformat (line_input, "app-timeout %f",
1820 &vcl_cfg->app_timeout))
1821 {
1822 if (VPPCOM_DEBUG > 0)
1823 clib_warning ("[%d] configured app_timeout %f",
Dave Wallace2e005bb2017-11-07 01:21:39 -05001824 getpid (), vcl_cfg->app_timeout);
Dave Wallace543852a2017-08-03 02:11:34 -04001825 }
1826 else if (unformat (line_input, "session-timeout %f",
1827 &vcl_cfg->session_timeout))
1828 {
1829 if (VPPCOM_DEBUG > 0)
1830 clib_warning ("[%d] configured session_timeout %f",
Dave Wallace2e005bb2017-11-07 01:21:39 -05001831 getpid (), vcl_cfg->session_timeout);
Dave Wallace543852a2017-08-03 02:11:34 -04001832 }
1833 else if (unformat (line_input, "accept-timeout %f",
1834 &vcl_cfg->accept_timeout))
1835 {
1836 if (VPPCOM_DEBUG > 0)
1837 clib_warning ("[%d] configured accept_timeout %f",
Dave Wallace2e005bb2017-11-07 01:21:39 -05001838 getpid (), vcl_cfg->accept_timeout);
Dave Wallace543852a2017-08-03 02:11:34 -04001839 }
Dave Wallace774169b2017-11-01 20:07:40 -04001840 else if (unformat (line_input, "app-proxy-transport-tcp"))
Dave Wallace8af20542017-10-26 03:29:30 -04001841 {
Dave Wallace774169b2017-11-01 20:07:40 -04001842 vcl_cfg->app_proxy_transport_tcp = 1;
Dave Wallace8af20542017-10-26 03:29:30 -04001843 if (VPPCOM_DEBUG > 0)
Dave Wallace774169b2017-11-01 20:07:40 -04001844 clib_warning ("[%d] configured app_proxy_transport_tcp (%d)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05001845 getpid (), vcl_cfg->app_proxy_transport_tcp);
Dave Wallace8af20542017-10-26 03:29:30 -04001846 }
Dave Wallace774169b2017-11-01 20:07:40 -04001847 else if (unformat (line_input, "app-proxy-transport-udp"))
Dave Wallace8af20542017-10-26 03:29:30 -04001848 {
Dave Wallace774169b2017-11-01 20:07:40 -04001849 vcl_cfg->app_proxy_transport_udp = 1;
Dave Wallace8af20542017-10-26 03:29:30 -04001850 if (VPPCOM_DEBUG > 0)
Dave Wallace774169b2017-11-01 20:07:40 -04001851 clib_warning ("[%d] configured app_proxy_transport_udp (%d)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05001852 getpid (), vcl_cfg->app_proxy_transport_udp);
Dave Wallace8af20542017-10-26 03:29:30 -04001853 }
Dave Wallace774169b2017-11-01 20:07:40 -04001854 else if (unformat (line_input, "app-scope-local"))
Dave Wallace8af20542017-10-26 03:29:30 -04001855 {
Dave Wallace774169b2017-11-01 20:07:40 -04001856 vcl_cfg->app_scope_local = 1;
Dave Wallace8af20542017-10-26 03:29:30 -04001857 if (VPPCOM_DEBUG > 0)
Dave Wallace774169b2017-11-01 20:07:40 -04001858 clib_warning ("[%d] configured app_scope_local (%d)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05001859 getpid (), vcl_cfg->app_scope_local);
Dave Wallace774169b2017-11-01 20:07:40 -04001860 }
1861 else if (unformat (line_input, "app-scope-global"))
1862 {
1863 vcl_cfg->app_scope_global = 1;
1864 if (VPPCOM_DEBUG > 0)
1865 clib_warning ("[%d] configured app_scope_global (%d)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05001866 getpid (), vcl_cfg->app_scope_global);
Dave Wallace8af20542017-10-26 03:29:30 -04001867 }
1868 else if (unformat (line_input, "namespace-secret %lu",
1869 &vcl_cfg->namespace_secret))
1870 {
1871 if (VPPCOM_DEBUG > 0)
1872 clib_warning
1873 ("[%d] configured namespace_secret %lu (0x%lx)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05001874 getpid (), vcl_cfg->namespace_secret,
Dave Wallace8af20542017-10-26 03:29:30 -04001875 vcl_cfg->namespace_secret);
1876 }
1877 else if (unformat (line_input, "namespace-id %v",
1878 &vcl_cfg->namespace_id))
1879 {
1880 vl_api_application_attach_t *mp;
1881 u32 max_nsid_vec_len = sizeof (mp->namespace_id) - 1;
1882 u32 nsid_vec_len = vec_len (vcl_cfg->namespace_id);
1883 if (nsid_vec_len > max_nsid_vec_len)
1884 {
1885 _vec_len (vcl_cfg->namespace_id) = max_nsid_vec_len;
1886 if (VPPCOM_DEBUG > 0)
1887 clib_warning ("[%d] configured namespace_id is too long,"
Dave Wallace2e005bb2017-11-07 01:21:39 -05001888 " truncated to %d characters!", getpid (),
Dave Wallace8af20542017-10-26 03:29:30 -04001889 max_nsid_vec_len);
1890 }
1891
1892 if (VPPCOM_DEBUG > 0)
1893 clib_warning ("[%d] configured namespace_id %v",
Dave Wallace2e005bb2017-11-07 01:21:39 -05001894 getpid (), vcl_cfg->namespace_id);
Dave Wallace8af20542017-10-26 03:29:30 -04001895 }
Dave Wallace543852a2017-08-03 02:11:34 -04001896 else if (unformat (line_input, "}"))
1897 {
1898 vc_cfg_input = 0;
1899 if (VPPCOM_DEBUG > 0)
1900 clib_warning ("[%d] completed parsing vppcom config!",
Dave Wallace2e005bb2017-11-07 01:21:39 -05001901 getpid ());
Dave Wallace543852a2017-08-03 02:11:34 -04001902 goto input_done;
1903 }
1904 else
1905 {
1906 if (line_input->buffer[line_input->index] != '#')
1907 {
1908 clib_warning ("[%d] Unknown vppcom config option: '%s'",
Dave Wallace2e005bb2017-11-07 01:21:39 -05001909 getpid (), (char *)
Dave Wallace543852a2017-08-03 02:11:34 -04001910 &line_input->buffer[line_input->index]);
1911 }
1912 }
1913 }
1914 }
1915
1916input_done:
1917 unformat_free (input);
1918
1919file_done:
Chris Lukeab7b8d92017-09-07 07:40:13 -04001920 if (fd >= 0)
Dave Wallace543852a2017-08-03 02:11:34 -04001921 close (fd);
1922}
1923
1924/*
1925 * VPPCOM Public API functions
1926 */
1927int
1928vppcom_app_create (char *app_name)
1929{
Dave Wallace543852a2017-08-03 02:11:34 -04001930 vppcom_cfg_t *vcl_cfg = &vcm->cfg;
1931 u8 *heap;
1932 mheap_t *h;
1933 int rv;
1934
1935 if (!vcm->init)
1936 {
1937 char *conf_fname;
Dave Wallace8af20542017-10-26 03:29:30 -04001938 char *env_var_str;
Dave Wallace543852a2017-08-03 02:11:34 -04001939
1940 vcm->init = 1;
Dave Wallace543852a2017-08-03 02:11:34 -04001941 vppcom_cfg_init (vcl_cfg);
Dave Wallace498b3a52017-11-09 13:00:34 -05001942 env_var_str = getenv (VPPCOM_ENV_DEBUG);
1943 if (env_var_str)
1944 {
1945 u32 tmp;
1946 if (sscanf (env_var_str, "%u", &tmp) != 1)
1947 clib_warning ("[%d] Invalid debug level specified in "
1948 "the environment variable "
1949 VPPCOM_ENV_DEBUG
1950 " (%s)!\n", getpid (), env_var_str);
1951 else
1952 {
1953 vcm->debug = tmp;
1954 clib_warning ("[%d] configured debug level (%u) from "
1955 VPPCOM_ENV_DEBUG "!", getpid (), vcm->debug);
1956 }
1957 }
Dave Wallace8af20542017-10-26 03:29:30 -04001958 conf_fname = getenv (VPPCOM_ENV_CONF);
Dave Wallace543852a2017-08-03 02:11:34 -04001959 if (!conf_fname)
1960 {
1961 conf_fname = VPPCOM_CONF_DEFAULT;
1962 if (VPPCOM_DEBUG > 0)
Dave Wallace2e005bb2017-11-07 01:21:39 -05001963 clib_warning ("[%d] getenv '%s' failed!", getpid (),
Dave Wallace8af20542017-10-26 03:29:30 -04001964 VPPCOM_ENV_CONF);
Dave Wallace543852a2017-08-03 02:11:34 -04001965 }
1966 vppcom_cfg_heapsize (conf_fname);
Dave Wallace2e005bb2017-11-07 01:21:39 -05001967 clib_fifo_validate (vcm->client_session_index_fifo,
1968 vcm->cfg.listen_queue_size);
Dave Wallace543852a2017-08-03 02:11:34 -04001969 vppcom_cfg_read (conf_fname);
Dave Wallace8af20542017-10-26 03:29:30 -04001970 env_var_str = getenv (VPPCOM_ENV_APP_NAMESPACE_ID);
1971 if (env_var_str)
1972 {
1973 u32 ns_id_vec_len = strlen (env_var_str);
1974
1975 vec_reset_length (vcm->cfg.namespace_id);
1976 vec_validate (vcm->cfg.namespace_id, ns_id_vec_len - 1);
1977 clib_memcpy (vcm->cfg.namespace_id, env_var_str, ns_id_vec_len);
1978
1979 if (VPPCOM_DEBUG > 0)
1980 clib_warning ("[%d] configured namespace_id (%v) from "
Dave Wallace2e005bb2017-11-07 01:21:39 -05001981 VPPCOM_ENV_APP_NAMESPACE_ID "!", getpid (),
Dave Wallace8af20542017-10-26 03:29:30 -04001982 vcm->cfg.namespace_id);
1983 }
1984 env_var_str = getenv (VPPCOM_ENV_APP_NAMESPACE_SECRET);
1985 if (env_var_str)
1986 {
1987 u64 tmp;
1988 if (sscanf (env_var_str, "%lu", &tmp) != 1)
1989 clib_warning ("[%d] Invalid namespace secret specified in "
1990 "the environment variable "
1991 VPPCOM_ENV_APP_NAMESPACE_SECRET
Dave Wallace2e005bb2017-11-07 01:21:39 -05001992 " (%s)!\n", getpid (), env_var_str);
Dave Wallace8af20542017-10-26 03:29:30 -04001993 else
1994 {
1995 vcm->cfg.namespace_secret = tmp;
1996 if (VPPCOM_DEBUG > 0)
1997 clib_warning ("[%d] configured namespace secret (%lu) from "
Dave Wallace2e005bb2017-11-07 01:21:39 -05001998 VPPCOM_ENV_APP_NAMESPACE_ID "!", getpid (),
Dave Wallace8af20542017-10-26 03:29:30 -04001999 vcm->cfg.namespace_secret);
2000 }
2001 }
Dave Wallace774169b2017-11-01 20:07:40 -04002002 if (getenv (VPPCOM_ENV_APP_PROXY_TRANSPORT_TCP))
Dave Wallace8af20542017-10-26 03:29:30 -04002003 {
Dave Wallace774169b2017-11-01 20:07:40 -04002004 vcm->cfg.app_proxy_transport_tcp = 1;
Dave Wallace8af20542017-10-26 03:29:30 -04002005 if (VPPCOM_DEBUG > 0)
Dave Wallace774169b2017-11-01 20:07:40 -04002006 clib_warning ("[%d] configured app_proxy_transport_tcp (%u) from "
Dave Wallace2e005bb2017-11-07 01:21:39 -05002007 VPPCOM_ENV_APP_PROXY_TRANSPORT_TCP "!", getpid (),
Dave Wallace774169b2017-11-01 20:07:40 -04002008 vcm->cfg.app_proxy_transport_tcp);
Dave Wallace8af20542017-10-26 03:29:30 -04002009 }
Dave Wallace774169b2017-11-01 20:07:40 -04002010 if (getenv (VPPCOM_ENV_APP_PROXY_TRANSPORT_UDP))
Dave Wallace8af20542017-10-26 03:29:30 -04002011 {
Dave Wallace774169b2017-11-01 20:07:40 -04002012 vcm->cfg.app_proxy_transport_udp = 1;
Dave Wallace8af20542017-10-26 03:29:30 -04002013 if (VPPCOM_DEBUG > 0)
Dave Wallace774169b2017-11-01 20:07:40 -04002014 clib_warning ("[%d] configured app_proxy_transport_udp (%u) from "
Dave Wallace2e005bb2017-11-07 01:21:39 -05002015 VPPCOM_ENV_APP_PROXY_TRANSPORT_UDP "!", getpid (),
Dave Wallace774169b2017-11-01 20:07:40 -04002016 vcm->cfg.app_proxy_transport_udp);
2017 }
2018 if (getenv (VPPCOM_ENV_APP_SCOPE_LOCAL))
2019 {
2020 vcm->cfg.app_scope_local = 1;
2021 if (VPPCOM_DEBUG > 0)
2022 clib_warning ("[%d] configured app_scope_local (%u) from "
Dave Wallace2e005bb2017-11-07 01:21:39 -05002023 VPPCOM_ENV_APP_SCOPE_LOCAL "!", getpid (),
Dave Wallace774169b2017-11-01 20:07:40 -04002024 vcm->cfg.app_scope_local);
2025 }
2026 if (getenv (VPPCOM_ENV_APP_SCOPE_GLOBAL))
2027 {
2028 vcm->cfg.app_scope_global = 1;
2029 if (VPPCOM_DEBUG > 0)
2030 clib_warning ("[%d] configured app_scope_global (%u) from "
Dave Wallace2e005bb2017-11-07 01:21:39 -05002031 VPPCOM_ENV_APP_SCOPE_GLOBAL "!", getpid (),
Dave Wallace774169b2017-11-01 20:07:40 -04002032 vcm->cfg.app_scope_global);
Dave Wallace8af20542017-10-26 03:29:30 -04002033 }
2034
Dave Wallace543852a2017-08-03 02:11:34 -04002035 vcm->main_cpu = os_get_thread_index ();
2036 heap = clib_mem_get_per_cpu_heap ();
2037 h = mheap_header (heap);
2038
2039 /* make the main heap thread-safe */
2040 h->flags |= MHEAP_FLAG_THREAD_SAFE;
2041
2042 vcm->session_index_by_vpp_handles = hash_create (0, sizeof (uword));
2043
2044 clib_time_init (&vcm->clib_time);
2045 vppcom_init_error_string_table ();
2046 svm_fifo_segment_init (vcl_cfg->segment_baseva,
2047 20 /* timeout in secs */ );
2048 clib_spinlock_init (&vcm->sessions_lockp);
2049 vppcom_api_hookup ();
2050 }
2051
2052 if (vcm->my_client_index == ~0)
2053 {
2054 vcm->app_state = STATE_APP_START;
2055 rv = vppcom_connect_to_vpp (app_name);
2056 if (rv)
2057 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05002058 clib_warning ("[%d] ERROR: couldn't connect to VPP!", getpid ());
Dave Wallace543852a2017-08-03 02:11:34 -04002059 return rv;
2060 }
2061
2062 if (VPPCOM_DEBUG > 0)
Dave Wallace2e005bb2017-11-07 01:21:39 -05002063 clib_warning ("[%d] sending session enable", getpid ());
Dave Wallace543852a2017-08-03 02:11:34 -04002064
2065 rv = vppcom_app_session_enable ();
2066 if (rv)
2067 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05002068 clib_warning ("[%d] ERROR: vppcom_app_session_enable() failed!",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002069 getpid ());
Dave Wallace543852a2017-08-03 02:11:34 -04002070 return rv;
2071 }
2072
2073 if (VPPCOM_DEBUG > 0)
Dave Wallace2e005bb2017-11-07 01:21:39 -05002074 clib_warning ("[%d] sending app attach", getpid ());
Dave Wallace543852a2017-08-03 02:11:34 -04002075
2076 rv = vppcom_app_attach ();
2077 if (rv)
2078 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05002079 clib_warning ("[%d] ERROR: vppcom_app_attach() failed!", getpid ());
Dave Wallace543852a2017-08-03 02:11:34 -04002080 return rv;
2081 }
Dave Wallace543852a2017-08-03 02:11:34 -04002082
Dave Wallace66cf6eb2017-10-26 02:51:07 -04002083 if (VPPCOM_DEBUG > 0)
2084 clib_warning ("[%d] app_name '%s', my_client_index %d (0x%x)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002085 getpid (), app_name, vcm->my_client_index,
Dave Wallace66cf6eb2017-10-26 02:51:07 -04002086 vcm->my_client_index);
2087 }
Dave Wallace543852a2017-08-03 02:11:34 -04002088
2089 return VPPCOM_OK;
2090}
2091
2092void
2093vppcom_app_destroy (void)
2094{
Dave Wallace543852a2017-08-03 02:11:34 -04002095 int rv;
2096
2097 if (vcm->my_client_index == ~0)
2098 return;
2099
2100 if (VPPCOM_DEBUG > 0)
2101 clib_warning ("[%d] detaching from VPP, my_client_index %d (0x%x)",
Dave Wallace2e005bb2017-11-07 01:21:39 -05002102 getpid (), vcm->my_client_index, vcm->my_client_index);
Dave Wallace543852a2017-08-03 02:11:34 -04002103
2104 vppcom_app_detach ();
2105 rv = vppcom_wait_for_app_state_change (STATE_APP_ENABLED);
2106 if (PREDICT_FALSE (rv))
2107 {
2108 if (VPPCOM_DEBUG > 0)
Dave Wallaceee45d412017-11-24 21:44:06 -05002109 clib_warning ("[%d] application detach timed out! returning %d (%s)",
2110 getpid (), rv, vppcom_retval_str (rv));
Dave Wallace543852a2017-08-03 02:11:34 -04002111 }
2112 vl_client_disconnect_from_vlib ();
2113 vcm->my_client_index = ~0;
2114 vcm->app_state = STATE_APP_START;
2115}
2116
2117int
2118vppcom_session_create (u32 vrf, u8 proto, u8 is_nonblocking)
2119{
Dave Wallace543852a2017-08-03 02:11:34 -04002120 session_t *session;
2121 u32 session_index;
2122
2123 clib_spinlock_lock (&vcm->sessions_lockp);
2124 pool_get (vcm->sessions, session);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002125 memset (session, 0, sizeof (*session));
Dave Wallace543852a2017-08-03 02:11:34 -04002126 session_index = session - vcm->sessions;
2127
2128 session->vrf = vrf;
2129 session->proto = proto;
2130 session->state = STATE_START;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002131 session->is_nonblocking = is_nonblocking ? 1 : 0;
Dave Wallace4878cbe2017-11-21 03:45:09 -05002132 session->vpp_handle = ~0;
Dave Wallace543852a2017-08-03 02:11:34 -04002133 clib_spinlock_unlock (&vcm->sessions_lockp);
2134
2135 if (VPPCOM_DEBUG > 0)
Dave Wallace4878cbe2017-11-21 03:45:09 -05002136 clib_warning ("[%d] sid %u", getpid (), session_index);
Dave Wallace543852a2017-08-03 02:11:34 -04002137
2138 return (int) session_index;
2139}
2140
2141int
2142vppcom_session_close (uint32_t session_index)
2143{
Dave Wallace543852a2017-08-03 02:11:34 -04002144 session_t *session = 0;
2145 int rv;
Dave Wallace66cf6eb2017-10-26 02:51:07 -04002146 u8 is_listen;
Dave Wallace66cf6eb2017-10-26 02:51:07 -04002147 u8 is_vep;
2148 u8 is_vep_session;
2149 u32 next_sid;
2150 u32 vep_idx;
Dave Wallaceee45d412017-11-24 21:44:06 -05002151 u64 vpp_handle;
Dave Wallace4878cbe2017-11-21 03:45:09 -05002152 uword *p;
Dave Wallace66cf6eb2017-10-26 02:51:07 -04002153 session_state_t state;
Dave Wallace543852a2017-08-03 02:11:34 -04002154
Dave Wallace4878cbe2017-11-21 03:45:09 -05002155 VCL_LOCK_AND_GET_SESSION (session_index, &session);
Dave Wallace66cf6eb2017-10-26 02:51:07 -04002156 is_listen = session->is_listen;
Dave Wallace66cf6eb2017-10-26 02:51:07 -04002157 is_vep = session->is_vep;
2158 is_vep_session = session->is_vep_session;
2159 next_sid = session->vep.next_sid;
2160 vep_idx = session->vep.vep_idx;
2161 state = session->state;
Dave Wallaceee45d412017-11-24 21:44:06 -05002162 vpp_handle = session->vpp_handle;
Dave Wallace543852a2017-08-03 02:11:34 -04002163 clib_spinlock_unlock (&vcm->sessions_lockp);
2164
2165 if (VPPCOM_DEBUG > 0)
Dave Wallaceee45d412017-11-24 21:44:06 -05002166 {
2167 if (is_vep)
2168 clib_warning ("[%d] vep_idx %u / sid %u: closing epoll session...",
2169 getpid (), session_index, session_index);
2170 else
2171 clib_warning ("[%d] vpp handle 0x%llx, sid %d: closing session...",
2172 getpid (), vpp_handle, session_index);
2173 }
Dave Wallace543852a2017-08-03 02:11:34 -04002174
Dave Wallace66cf6eb2017-10-26 02:51:07 -04002175 if (is_vep)
Dave Wallace543852a2017-08-03 02:11:34 -04002176 {
Dave Wallace66cf6eb2017-10-26 02:51:07 -04002177 while (next_sid != ~0)
Dave Wallace19481612017-09-15 18:47:44 -04002178 {
Dave Wallacef7f809c2017-10-03 01:48:42 -04002179 rv = vppcom_epoll_ctl (session_index, EPOLL_CTL_DEL, next_sid, 0);
Dave Wallaceee45d412017-11-24 21:44:06 -05002180 if ((VPPCOM_DEBUG > 0) && PREDICT_FALSE (rv < 0))
2181 clib_warning ("[%d] vpp handle 0x%llx, sid %u: EPOLL_CTL_DEL "
2182 "vep_idx %u failed! rv %d (%s)", getpid (),
2183 vpp_handle, next_sid, vep_idx,
Dave Wallace4878cbe2017-11-21 03:45:09 -05002184 rv, vppcom_retval_str (rv));
Dave Wallacef7f809c2017-10-03 01:48:42 -04002185
Dave Wallace4878cbe2017-11-21 03:45:09 -05002186 VCL_LOCK_AND_GET_SESSION (session_index, &session);
Dave Wallace66cf6eb2017-10-26 02:51:07 -04002187 next_sid = session->vep.next_sid;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002188 clib_spinlock_unlock (&vcm->sessions_lockp);
2189 }
2190 }
2191 else
2192 {
Dave Wallace66cf6eb2017-10-26 02:51:07 -04002193 if (is_vep_session)
Dave Wallacef7f809c2017-10-03 01:48:42 -04002194 {
Dave Wallacef7f809c2017-10-03 01:48:42 -04002195 rv = vppcom_epoll_ctl (vep_idx, EPOLL_CTL_DEL, session_index, 0);
2196 if ((VPPCOM_DEBUG > 0) && (rv < 0))
Dave Wallaceee45d412017-11-24 21:44:06 -05002197 clib_warning ("[%d] vpp handle 0x%llx, sid %u: EPOLL_CTL_DEL "
2198 "vep_idx %u failed! rv %d (%s)",
2199 getpid (), vpp_handle, session_index,
2200 vep_idx, rv, vppcom_retval_str (rv));
Dave Wallacef7f809c2017-10-03 01:48:42 -04002201 }
2202
Dave Wallace4878cbe2017-11-21 03:45:09 -05002203 if (is_listen)
Dave Wallacef7f809c2017-10-03 01:48:42 -04002204 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05002205 if (state == STATE_LISTEN)
2206 {
2207 rv = vppcom_session_unbind (session_index);
2208 if (PREDICT_FALSE (rv < 0))
2209 {
2210 if (VPPCOM_DEBUG > 0)
Dave Wallaceee45d412017-11-24 21:44:06 -05002211 clib_warning ("[%d] vpp handle 0x%llx, sid %u: "
2212 "listener unbind failed! rv %d (%s)",
2213 getpid (), vpp_handle, session_index,
2214 rv, vppcom_retval_str (rv));
Dave Wallace4878cbe2017-11-21 03:45:09 -05002215 }
2216 }
Dave Wallacef7f809c2017-10-03 01:48:42 -04002217 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05002218
2219 else if (state & (CLIENT_STATE_OPEN | SERVER_STATE_OPEN))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002220 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05002221 rv = vppcom_session_disconnect (session_index);
2222 if (PREDICT_FALSE (rv < 0))
Dave Wallaceee45d412017-11-24 21:44:06 -05002223 clib_warning ("[%d] ERROR: vpp handle 0x%llx, sid %u: "
2224 "session disconnect failed! rv %d (%s)",
2225 getpid (), vpp_handle, session_index,
2226 rv, vppcom_retval_str (rv));
Dave Wallacef7f809c2017-10-03 01:48:42 -04002227 }
Dave Wallace19481612017-09-15 18:47:44 -04002228 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05002229
2230 VCL_LOCK_AND_GET_SESSION (session_index, &session);
Dave Wallaceee45d412017-11-24 21:44:06 -05002231 vpp_handle = session->vpp_handle;
2232 if (vpp_handle != ~0)
Dave Wallace4878cbe2017-11-21 03:45:09 -05002233 {
Dave Wallaceee45d412017-11-24 21:44:06 -05002234 p = hash_get (vcm->session_index_by_vpp_handles, vpp_handle);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002235 if (p)
Dave Wallaceee45d412017-11-24 21:44:06 -05002236 hash_unset (vcm->session_index_by_vpp_handles, vpp_handle);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002237 }
Dave Wallace543852a2017-08-03 02:11:34 -04002238 pool_put_index (vcm->sessions, session_index);
Dave Wallace66cf6eb2017-10-26 02:51:07 -04002239 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002240
2241 if (VPPCOM_DEBUG > 0)
Dave Wallaceee45d412017-11-24 21:44:06 -05002242 {
2243 if (is_vep)
2244 clib_warning ("[%d] vep_idx %u / sid %u: epoll session removed.",
2245 getpid (), session_index, session_index);
2246 else
2247 clib_warning ("[%d] vpp handle 0x%llx, sid %u: session removed.",
2248 getpid (), vpp_handle, session_index);
2249 }
Dave Wallacef7f809c2017-10-03 01:48:42 -04002250done:
Dave Wallace543852a2017-08-03 02:11:34 -04002251 return rv;
2252}
2253
2254int
2255vppcom_session_bind (uint32_t session_index, vppcom_endpt_t * ep)
2256{
Dave Wallace543852a2017-08-03 02:11:34 -04002257 session_t *session = 0;
2258 int rv;
2259
2260 if (!ep || !ep->ip)
2261 return VPPCOM_EINVAL;
2262
Dave Wallace4878cbe2017-11-21 03:45:09 -05002263 VCL_LOCK_AND_GET_SESSION (session_index, &session);
Dave Wallace543852a2017-08-03 02:11:34 -04002264
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002265 if (session->is_vep)
2266 {
2267 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002268 clib_warning ("[%d] ERROR: sid %u: cannot bind to an epoll session!",
2269 getpid (), session_index);
2270 rv = VPPCOM_EBADFD;
2271 goto done;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002272 }
2273
Dave Wallace543852a2017-08-03 02:11:34 -04002274 session->vrf = ep->vrf;
Dave Wallace35830af2017-10-09 01:43:42 -04002275 session->lcl_addr.is_ip4 = ep->is_ip4;
2276 session->lcl_addr.ip46 = to_ip46 (!ep->is_ip4, ep->ip);
Stevenac1f96d2017-10-24 16:03:58 -07002277 session->lcl_port = ep->port;
2278
2279 if (VPPCOM_DEBUG > 0)
Dave Wallaceee45d412017-11-24 21:44:06 -05002280 clib_warning ("[%d] sid %u: binding to local %s address %U "
2281 "port %u, proto %s", getpid (), session_index,
2282 session->lcl_addr.is_ip4 ? "IPv4" : "IPv6",
2283 format_ip46_address, &session->lcl_addr.ip46,
2284 session->lcl_addr.is_ip4,
Dave Wallace4878cbe2017-11-21 03:45:09 -05002285 clib_net_to_host_u16 (session->lcl_port),
2286 session->proto ? "UDP" : "TCP");
Dave Wallace543852a2017-08-03 02:11:34 -04002287
2288 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002289done:
2290 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04002291}
2292
2293int
Dave Wallace33e002b2017-09-06 01:20:02 -04002294vppcom_session_listen (uint32_t listen_session_index, uint32_t q_len)
Dave Wallace543852a2017-08-03 02:11:34 -04002295{
Dave Wallace33e002b2017-09-06 01:20:02 -04002296 session_t *listen_session = 0;
Dave Wallaceee45d412017-11-24 21:44:06 -05002297 u64 listen_vpp_handle;
2298 int rv, retval;
Dave Wallace543852a2017-08-03 02:11:34 -04002299
Dave Wallace4878cbe2017-11-21 03:45:09 -05002300 VCL_LOCK_AND_GET_SESSION (listen_session_index, &listen_session);
Dave Wallace543852a2017-08-03 02:11:34 -04002301
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002302 if (listen_session->is_vep)
2303 {
2304 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002305 clib_warning ("[%d] ERROR: sid %u: cannot listen on an "
2306 "epoll session!", getpid (), listen_session_index);
2307 rv = VPPCOM_EBADFD;
2308 goto done;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002309 }
2310
Dave Wallaceee45d412017-11-24 21:44:06 -05002311 listen_vpp_handle = listen_session->vpp_handle;
Dave Wallacee695cb42017-11-02 22:04:42 -04002312 if (listen_session->is_listen)
2313 {
2314 clib_spinlock_unlock (&vcm->sessions_lockp);
2315 if (VPPCOM_DEBUG > 0)
Dave Wallaceee45d412017-11-24 21:44:06 -05002316 clib_warning ("[%d] vpp handle 0x%llx, sid %u: "
2317 "already in listen state!",
2318 getpid (), listen_vpp_handle, listen_session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002319 rv = VPPCOM_OK;
2320 goto done;
Dave Wallacee695cb42017-11-02 22:04:42 -04002321 }
2322
Dave Wallace543852a2017-08-03 02:11:34 -04002323 if (VPPCOM_DEBUG > 0)
Dave Wallaceee45d412017-11-24 21:44:06 -05002324 clib_warning ("[%d] vpp handle 0x%llx, sid %u: sending bind request...",
2325 getpid (), listen_vpp_handle, listen_session_index);
Dave Wallace543852a2017-08-03 02:11:34 -04002326
Dave Wallace4878cbe2017-11-21 03:45:09 -05002327 vppcom_send_bind_sock (listen_session, listen_session_index);
Dave Wallace543852a2017-08-03 02:11:34 -04002328 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallaceee45d412017-11-24 21:44:06 -05002329 retval =
Dave Wallace33e002b2017-09-06 01:20:02 -04002330 vppcom_wait_for_session_state_change (listen_session_index, STATE_LISTEN,
2331 vcm->cfg.session_timeout);
Dave Wallace543852a2017-08-03 02:11:34 -04002332
Dave Wallace4878cbe2017-11-21 03:45:09 -05002333 VCL_LOCK_AND_GET_SESSION (listen_session_index, &listen_session);
Dave Wallaceee45d412017-11-24 21:44:06 -05002334 if (PREDICT_FALSE (retval))
2335 {
2336 if (VPPCOM_DEBUG > 0)
2337 clib_warning ("[%d] vpp handle 0x%llx, sid %u: bind failed! "
2338 "returning %d (%s)", getpid (),
2339 listen_session->vpp_handle, listen_session_index,
2340 retval, vppcom_retval_str (retval));
2341 clib_spinlock_unlock (&vcm->sessions_lockp);
2342 rv = retval;
2343 goto done;
2344 }
2345
Dave Wallace543852a2017-08-03 02:11:34 -04002346 clib_fifo_validate (vcm->client_session_index_fifo, q_len);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002347 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002348done:
2349 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04002350}
2351
2352int
2353vppcom_session_accept (uint32_t listen_session_index, vppcom_endpt_t * ep,
Dave Wallace227867f2017-11-13 21:21:53 -05002354 uint32_t flags, double wait_for_time)
Dave Wallace543852a2017-08-03 02:11:34 -04002355{
Dave Wallace33e002b2017-09-06 01:20:02 -04002356 session_t *listen_session = 0;
2357 session_t *client_session = 0;
Dave Wallace227867f2017-11-13 21:21:53 -05002358 u32 client_session_index = ~0;
Dave Wallace543852a2017-08-03 02:11:34 -04002359 int rv;
2360 f64 wait_for;
Dave Wallace60caa062017-11-10 17:07:13 -05002361 char *cut_thru_str;
Dave Wallaceee45d412017-11-24 21:44:06 -05002362 u64 listen_vpp_handle;
Dave Wallace543852a2017-08-03 02:11:34 -04002363
Dave Wallace4878cbe2017-11-21 03:45:09 -05002364 VCL_LOCK_AND_GET_SESSION (listen_session_index, &listen_session);
Dave Wallace543852a2017-08-03 02:11:34 -04002365
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002366 if (listen_session->is_vep)
2367 {
2368 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002369 clib_warning ("[%d] ERROR: sid %u: cannot accept on an "
2370 "epoll session!", getpid (), listen_session_index);
2371 rv = VPPCOM_EBADFD;
2372 goto done;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002373 }
2374
Dave Wallaceee45d412017-11-24 21:44:06 -05002375 listen_vpp_handle = listen_session->vpp_handle;
Dave Wallace33e002b2017-09-06 01:20:02 -04002376 if (listen_session->state != STATE_LISTEN)
Dave Wallace543852a2017-08-03 02:11:34 -04002377 {
Dave Wallaceee45d412017-11-24 21:44:06 -05002378 clib_warning ("[%d] ERROR: vpp handle 0x%llx, sid %u: "
2379 "not in listen state! state 0x%x (%s)", getpid (),
2380 listen_vpp_handle, listen_session_index,
2381 listen_session->state,
Dave Wallace4878cbe2017-11-21 03:45:09 -05002382 vppcom_session_state_str (listen_session->state));
Dave Wallaceee45d412017-11-24 21:44:06 -05002383 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002384 rv = VPPCOM_EBADFD;
2385 goto done;
Dave Wallace543852a2017-08-03 02:11:34 -04002386 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05002387 wait_for = ((listen_session->is_nonblocking) ? 0 :
2388 (wait_for_time < 0) ? vcm->cfg.accept_timeout : wait_for_time);
Dave Wallace543852a2017-08-03 02:11:34 -04002389
Dave Wallace543852a2017-08-03 02:11:34 -04002390 clib_spinlock_unlock (&vcm->sessions_lockp);
2391
2392 while (1)
2393 {
2394 rv = vppcom_wait_for_client_session_index (wait_for);
2395 if (rv)
2396 {
2397 if ((VPPCOM_DEBUG > 0))
Dave Wallaceee45d412017-11-24 21:44:06 -05002398 clib_warning ("[%d] vpp handle 0x%llx, sid %u: accept failed! "
2399 "returning %d (%s)", getpid (),
2400 listen_vpp_handle, listen_session_index,
Dave Wallace4878cbe2017-11-21 03:45:09 -05002401 rv, vppcom_retval_str (rv));
Dave Wallace543852a2017-08-03 02:11:34 -04002402 if ((wait_for == 0) || (wait_for_time > 0))
Dave Wallace4878cbe2017-11-21 03:45:09 -05002403 goto done;
Dave Wallace543852a2017-08-03 02:11:34 -04002404 }
2405 else
2406 break;
2407 }
2408
Dave Wallace543852a2017-08-03 02:11:34 -04002409 clib_spinlock_lock (&vcm->sessions_lockp);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002410 clib_fifo_sub1 (vcm->client_session_index_fifo, client_session_index);
Dave Wallace33e002b2017-09-06 01:20:02 -04002411 rv = vppcom_session_at_index (client_session_index, &client_session);
Dave Wallaceee45d412017-11-24 21:44:06 -05002412 if (PREDICT_FALSE (rv))
2413 {
2414 rv = VPPCOM_ECONNABORTED;
2415 clib_warning ("[%d] vpp handle 0x%llx, sid %u: client sid %u "
2416 "lookup failed! returning %d (%s)", getpid (),
2417 listen_vpp_handle, listen_session_index,
2418 client_session_index, rv, vppcom_retval_str (rv));
2419 goto done;
2420 }
Dave Wallace543852a2017-08-03 02:11:34 -04002421
Dave Wallace227867f2017-11-13 21:21:53 -05002422 client_session->is_nonblocking = (flags & O_NONBLOCK) ? 1 : 0;
Dave Wallace543852a2017-08-03 02:11:34 -04002423 if (VPPCOM_DEBUG > 0)
Dave Wallaceee45d412017-11-24 21:44:06 -05002424 clib_warning ("[%d] vpp handle 0x%llx, sid %u: Got a client request! "
2425 "vpp handle 0x%llx, sid %u, flags %d, is_nonblocking %u",
2426 getpid (), listen_vpp_handle, listen_session_index,
2427 client_session->vpp_handle, client_session_index,
Dave Wallace227867f2017-11-13 21:21:53 -05002428 flags, client_session->is_nonblocking);
Dave Wallace543852a2017-08-03 02:11:34 -04002429
Dave Wallace33e002b2017-09-06 01:20:02 -04002430 ep->vrf = client_session->vrf;
2431 ep->is_cut_thru = client_session->is_cut_thru;
Dave Wallace35830af2017-10-09 01:43:42 -04002432 ep->is_ip4 = client_session->peer_addr.is_ip4;
Stevenac1f96d2017-10-24 16:03:58 -07002433 ep->port = client_session->peer_port;
Dave Wallace35830af2017-10-09 01:43:42 -04002434 if (client_session->peer_addr.is_ip4)
2435 clib_memcpy (ep->ip, &client_session->peer_addr.ip46.ip4,
2436 sizeof (ip4_address_t));
Dave Wallace33e002b2017-09-06 01:20:02 -04002437 else
Dave Wallace35830af2017-10-09 01:43:42 -04002438 clib_memcpy (ep->ip, &client_session->peer_addr.ip46.ip6,
2439 sizeof (ip6_address_t));
Dave Wallace60caa062017-11-10 17:07:13 -05002440
2441 if (client_session->is_server && client_session->is_cut_thru)
2442 {
2443 static svm_fifo_segment_create_args_t _a;
2444 svm_fifo_segment_create_args_t *a = &_a;
2445 svm_fifo_segment_private_t *seg;
2446
Dave Wallace4878cbe2017-11-21 03:45:09 -05002447 cut_thru_str = " cut-thru ";
Dave Wallace60caa062017-11-10 17:07:13 -05002448
2449 /* Create the segment */
2450 memset (a, 0, sizeof (*a));
2451 a->segment_name = (char *)
2452 format ((u8 *) a->segment_name, "%d:segment%d%c",
2453 getpid (), vcm->unique_segment_index++, 0);
2454 a->segment_size = vcm->cfg.segment_size;
2455 a->preallocated_fifo_pairs = vcm->cfg.preallocated_fifo_pairs;
2456 a->rx_fifo_size = vcm->cfg.rx_fifo_size;
2457 a->tx_fifo_size = vcm->cfg.tx_fifo_size;
2458
2459 rv = svm_fifo_segment_create (a);
2460 if (PREDICT_FALSE (rv))
2461 {
Dave Wallaceee45d412017-11-24 21:44:06 -05002462 clib_warning ("[%d] ERROR: vpp handle 0x%llx, sid %u: "
2463 "client sid %u svm_fifo_segment_create ('%s') "
2464 "failed! rv %d", getpid (), listen_vpp_handle,
2465 listen_session_index, client_session_index,
2466 a->segment_name, rv);
Dave Wallace60caa062017-11-10 17:07:13 -05002467 vec_reset_length (a->new_segment_indices);
2468 rv = VNET_API_ERROR_URI_FIFO_CREATE_FAILED;
Dave Wallaceee45d412017-11-24 21:44:06 -05002469 vppcom_send_connect_session_reply (client_session,
Dave Wallaced2931962017-11-25 04:17:39 -05002470 client_session_index,
2471 client_session->vpp_handle,
2472 client_session->client_context,
2473 rv);
Dave Wallace60caa062017-11-10 17:07:13 -05002474 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002475 rv = VPPCOM_ENOMEM;
2476 goto done;
Dave Wallace60caa062017-11-10 17:07:13 -05002477 }
2478
2479 client_session->segment_name = vec_dup ((u8 *) a->segment_name);
2480 client_session->sm_seg_index = a->new_segment_indices[0];
2481 vec_free (a->new_segment_indices);
2482
2483 seg = svm_fifo_segment_get_segment (client_session->sm_seg_index);
2484 client_session->server_rx_fifo =
2485 svm_fifo_segment_alloc_fifo (seg, vcm->cfg.rx_fifo_size,
2486 FIFO_SEGMENT_RX_FREELIST);
2487 if (PREDICT_FALSE (!client_session->server_rx_fifo))
2488 {
2489 svm_fifo_segment_delete (seg);
Dave Wallaceee45d412017-11-24 21:44:06 -05002490 clib_warning ("[%d] ERROR: vpp handle 0x%llx, sid %u: "
2491 "client sid %u rx fifo alloc failed! "
2492 "size %ld (0x%lx)", getpid (), listen_vpp_handle,
2493 listen_session_index, client_session_index,
Dave Wallace4878cbe2017-11-21 03:45:09 -05002494 vcm->cfg.rx_fifo_size, vcm->cfg.rx_fifo_size);
Dave Wallace60caa062017-11-10 17:07:13 -05002495 rv = VNET_API_ERROR_URI_FIFO_CREATE_FAILED;
Dave Wallaceee45d412017-11-24 21:44:06 -05002496 vppcom_send_connect_session_reply (client_session,
Dave Wallaced2931962017-11-25 04:17:39 -05002497 client_session_index,
2498 client_session->vpp_handle,
2499 client_session->client_context,
2500 rv);
Dave Wallace60caa062017-11-10 17:07:13 -05002501 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002502 rv = VPPCOM_ENOMEM;
2503 goto done;
Dave Wallace60caa062017-11-10 17:07:13 -05002504 }
2505 client_session->server_rx_fifo->master_session_index =
2506 client_session_index;
2507
2508 client_session->server_tx_fifo =
2509 svm_fifo_segment_alloc_fifo (seg, vcm->cfg.tx_fifo_size,
2510 FIFO_SEGMENT_TX_FREELIST);
2511 if (PREDICT_FALSE (!client_session->server_tx_fifo))
2512 {
2513 svm_fifo_segment_delete (seg);
Dave Wallaceee45d412017-11-24 21:44:06 -05002514 clib_warning ("[%d] ERROR: vpp handle 0x%llx, sid %u: "
2515 "client sid %u tx fifo alloc failed! "
2516 "size %ld (0x%lx)", getpid (), listen_vpp_handle,
2517 listen_session_index, client_session_index,
Dave Wallace4878cbe2017-11-21 03:45:09 -05002518 vcm->cfg.tx_fifo_size, vcm->cfg.tx_fifo_size);
Dave Wallace60caa062017-11-10 17:07:13 -05002519 rv = VNET_API_ERROR_URI_FIFO_CREATE_FAILED;
Dave Wallaceee45d412017-11-24 21:44:06 -05002520 vppcom_send_connect_session_reply (client_session,
Dave Wallaced2931962017-11-25 04:17:39 -05002521 client_session_index,
2522 client_session->vpp_handle,
2523 client_session->client_context,
2524 rv);
Dave Wallace60caa062017-11-10 17:07:13 -05002525 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002526 rv = VPPCOM_ENOMEM;
2527 goto done;
Dave Wallace60caa062017-11-10 17:07:13 -05002528 }
2529 client_session->server_tx_fifo->master_session_index =
2530 client_session_index;
2531
2532 if (VPPCOM_DEBUG > 1)
Dave Wallaceee45d412017-11-24 21:44:06 -05002533 clib_warning ("[%d] vpp handle 0x%llx, sid %u: client sid %u "
2534 "created segment '%s', rx_fifo %p, tx_fifo %p",
2535 getpid (), listen_vpp_handle, listen_session_index,
2536 client_session_index, client_session->segment_name,
Dave Wallace60caa062017-11-10 17:07:13 -05002537 client_session->server_rx_fifo,
2538 client_session->server_tx_fifo);
2539
2540#ifdef CUT_THRU_EVENT_QUEUE /* TBD */
2541 {
2542 void *oldheap;
2543 ssvm_shared_header_t *sh = seg->ssvm.sh;
2544
2545 ssvm_lock_non_recursive (sh, 1);
2546 oldheap = ssvm_push_heap (sh);
2547 event_q = client_session->vpp_event_queue =
2548 unix_shared_memory_queue_init (vcm->cfg.event_queue_size,
2549 sizeof (session_fifo_event_t),
2550 getpid (), 0 /* signal not sent */ );
2551 ssvm_pop_heap (oldheap);
2552 ssvm_unlock_non_recursive (sh);
2553 }
2554#endif
Dave Wallaceee45d412017-11-24 21:44:06 -05002555 vppcom_send_connect_session_reply (client_session,
2556 client_session_index,
Dave Wallaced2931962017-11-25 04:17:39 -05002557 client_session->vpp_handle,
2558 client_session->client_context,
Dave Wallaceee45d412017-11-24 21:44:06 -05002559 0 /* retval OK */ );
Dave Wallace60caa062017-11-10 17:07:13 -05002560 }
2561 else
2562 {
2563 cut_thru_str = " ";
Dave Wallaced2931962017-11-25 04:17:39 -05002564 vppcom_send_accept_session_reply (client_session->vpp_handle,
2565 client_session->client_context,
2566 0 /* retval OK */ );
Dave Wallace60caa062017-11-10 17:07:13 -05002567 }
2568
Stevenac1f96d2017-10-24 16:03:58 -07002569 if (VPPCOM_DEBUG > 0)
Dave Wallaceee45d412017-11-24 21:44:06 -05002570 clib_warning ("[%d] vpp handle 0x%llx, sid %u: accepted vpp handle "
2571 "0x%llx, sid %u%sconnection to local %s address "
2572 "%U port %u", getpid (), listen_vpp_handle,
2573 listen_session_index, client_session->vpp_handle,
2574 client_session_index, cut_thru_str,
Dave Wallace4878cbe2017-11-21 03:45:09 -05002575 client_session->lcl_addr.is_ip4 ? "IPv4" : "IPv6",
2576 format_ip46_address, &client_session->lcl_addr.ip46,
2577 client_session->lcl_addr.is_ip4,
2578 clib_net_to_host_u16 (client_session->lcl_port));
Dave Wallace60caa062017-11-10 17:07:13 -05002579
Dave Wallace543852a2017-08-03 02:11:34 -04002580 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002581 rv = (int) client_session_index;
2582done:
2583 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04002584}
2585
2586int
2587vppcom_session_connect (uint32_t session_index, vppcom_endpt_t * server_ep)
2588{
Dave Wallace543852a2017-08-03 02:11:34 -04002589 session_t *session = 0;
Dave Wallaceee45d412017-11-24 21:44:06 -05002590 int rv, retval = VPPCOM_OK;
2591 u64 vpp_handle = ~0;
Dave Wallace543852a2017-08-03 02:11:34 -04002592
Dave Wallace4878cbe2017-11-21 03:45:09 -05002593 VCL_LOCK_AND_GET_SESSION (session_index, &session);
2594
2595 if (PREDICT_FALSE (session->is_vep))
Dave Wallace543852a2017-08-03 02:11:34 -04002596 {
2597 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002598 clib_warning ("[%d] ERROR: sid %u: cannot connect on an epoll session!",
2599 getpid (), session_index);
2600 rv = VPPCOM_EBADFD;
2601 goto done;
Dave Wallace543852a2017-08-03 02:11:34 -04002602 }
2603
Dave Wallaceee45d412017-11-24 21:44:06 -05002604 vpp_handle = session->vpp_handle;
Dave Wallace4878cbe2017-11-21 03:45:09 -05002605 if (PREDICT_FALSE (session->is_server))
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002606 {
2607 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallaceee45d412017-11-24 21:44:06 -05002608 clib_warning ("[%d] ERROR: vpp handle 0x%llx, sid %u: is in use "
2609 "as a server session!", getpid (), vpp_handle,
2610 session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002611 rv = VPPCOM_EBADFD;
2612 goto done;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002613 }
2614
Dave Wallace4878cbe2017-11-21 03:45:09 -05002615 if (PREDICT_FALSE (session->state & CLIENT_STATE_OPEN))
Dave Wallace543852a2017-08-03 02:11:34 -04002616 {
Dave Wallace543852a2017-08-03 02:11:34 -04002617 if (VPPCOM_DEBUG > 0)
Dave Wallaceee45d412017-11-24 21:44:06 -05002618 clib_warning ("[%d] vpp handle 0x%llx, sid %u: session already "
2619 "connected to %s %U port %d proto %s, state 0x%x (%s)",
2620 getpid (), vpp_handle, session_index,
Dave Wallace4878cbe2017-11-21 03:45:09 -05002621 session->peer_addr.is_ip4 ? "IPv4" : "IPv6",
2622 format_ip46_address,
2623 &session->peer_addr.ip46, session->peer_addr.is_ip4,
2624 clib_net_to_host_u16 (session->peer_port),
2625 session->proto ? "UDP" : "TCP", session->state,
2626 vppcom_session_state_str (session->state));
2627
2628 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002629 goto done;
Dave Wallace543852a2017-08-03 02:11:34 -04002630 }
2631
2632 session->vrf = server_ep->vrf;
Dave Wallace35830af2017-10-09 01:43:42 -04002633 session->peer_addr.is_ip4 = server_ep->is_ip4;
2634 session->peer_addr.ip46 = to_ip46 (!server_ep->is_ip4, server_ep->ip);
Stevenac1f96d2017-10-24 16:03:58 -07002635 session->peer_port = server_ep->port;
Dave Wallace543852a2017-08-03 02:11:34 -04002636
2637 if (VPPCOM_DEBUG > 0)
Dave Wallaceee45d412017-11-24 21:44:06 -05002638 clib_warning ("[%d] vpp handle 0x%llx, sid %u: connecting to server "
2639 "%s %U port %d proto %s",
2640 getpid (), vpp_handle, session_index,
Dave Wallace4878cbe2017-11-21 03:45:09 -05002641 session->peer_addr.is_ip4 ? "IPv4" : "IPv6",
2642 format_ip46_address,
2643 &session->peer_addr.ip46, session->peer_addr.is_ip4,
2644 clib_net_to_host_u16 (session->peer_port),
2645 session->proto ? "UDP" : "TCP");
Dave Wallace543852a2017-08-03 02:11:34 -04002646
2647 vppcom_send_connect_sock (session, session_index);
2648 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002649
Dave Wallaceee45d412017-11-24 21:44:06 -05002650 retval =
2651 vppcom_wait_for_session_state_change (session_index, STATE_CONNECT,
2652 vcm->cfg.session_timeout);
2653
2654 VCL_LOCK_AND_GET_SESSION (session_index, &session);
2655 vpp_handle = session->vpp_handle;
2656 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace7876d392017-10-19 03:53:57 -04002657
Dave Wallace4878cbe2017-11-21 03:45:09 -05002658done:
Dave Wallaceee45d412017-11-24 21:44:06 -05002659 if (PREDICT_FALSE (retval))
2660 {
2661 rv = retval;
2662 if (VPPCOM_DEBUG > 0)
2663 clib_warning ("[%d] vpp handle 0x%llx, sid %u: connect failed! "
2664 "returning %d (%s)", getpid (), vpp_handle,
2665 session_index, rv, vppcom_retval_str (rv));
2666 }
2667 else if (VPPCOM_DEBUG > 0)
2668 clib_warning ("[%d] vpp handle 0x%llx, sid %u: connected!",
2669 getpid (), vpp_handle, session_index);
2670
Dave Wallace4878cbe2017-11-21 03:45:09 -05002671 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04002672}
2673
Steven58f464e2017-10-25 12:33:12 -07002674static inline int
2675vppcom_session_read_internal (uint32_t session_index, void *buf, int n,
2676 u8 peek)
Dave Wallace543852a2017-08-03 02:11:34 -04002677{
Dave Wallace543852a2017-08-03 02:11:34 -04002678 session_t *session = 0;
2679 svm_fifo_t *rx_fifo;
2680 int n_read = 0;
2681 int rv;
2682 char *fifo_str;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002683 u32 poll_et;
Dave Wallace4878cbe2017-11-21 03:45:09 -05002684 session_state_t state;
2685 u8 is_server;
2686 u8 is_nonblocking;
Dave Wallaceee45d412017-11-24 21:44:06 -05002687 u64 vpp_handle;
Dave Wallace543852a2017-08-03 02:11:34 -04002688
2689 ASSERT (buf);
2690
Dave Wallace4878cbe2017-11-21 03:45:09 -05002691 VCL_LOCK_AND_GET_SESSION (session_index, &session);
2692
2693 if (PREDICT_FALSE (session->is_vep))
Dave Wallace543852a2017-08-03 02:11:34 -04002694 {
2695 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002696 clib_warning ("[%d] ERROR: sid %u: cannot read from an epoll session!",
2697 getpid (), session_index);
2698 rv = VPPCOM_EBADFD;
2699 goto done;
Dave Wallace543852a2017-08-03 02:11:34 -04002700 }
2701
Dave Wallaceee45d412017-11-24 21:44:06 -05002702 vpp_handle = session->vpp_handle;
Dave Wallace4878cbe2017-11-21 03:45:09 -05002703 is_server = session->is_server;
2704 is_nonblocking = session->is_nonblocking;
2705 state = session->state;
2706 if (PREDICT_FALSE (!(state & (SERVER_STATE_OPEN | CLIENT_STATE_OPEN))))
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002707 {
2708 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002709 rv = ((state == STATE_DISCONNECT) ?
2710 VPPCOM_ECONNRESET : VPPCOM_ENOTCONN);
2711
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002712 if (VPPCOM_DEBUG > 0)
Dave Wallaceee45d412017-11-24 21:44:06 -05002713 clib_warning ("[%d] vpp handle 0x%llx, sid %u: %s session is "
2714 "not open! state 0x%x (%s), returning %d (%s)",
2715 getpid (), vpp_handle, session_index,
2716 is_server ? "server" : "client", state,
Dave Wallace4878cbe2017-11-21 03:45:09 -05002717 vppcom_session_state_str (state),
2718 rv, vppcom_retval_str (rv));
2719 goto done;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002720 }
2721
Dave Wallace4878cbe2017-11-21 03:45:09 -05002722 rx_fifo = ((!session->is_cut_thru || is_server) ?
Dave Wallace33e002b2017-09-06 01:20:02 -04002723 session->server_rx_fifo : session->server_tx_fifo);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002724 fifo_str = ((!session->is_cut_thru || is_server) ?
Dave Wallace33e002b2017-09-06 01:20:02 -04002725 "server_rx_fifo" : "server_tx_fifo");
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002726 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002727
2728 do
2729 {
Steven58f464e2017-10-25 12:33:12 -07002730 if (peek)
2731 n_read = svm_fifo_peek (rx_fifo, 0, n, buf);
2732 else
2733 n_read = svm_fifo_dequeue_nowait (rx_fifo, n, buf);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002734 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05002735 while (!is_nonblocking && (n_read <= 0));
Dave Wallacef7f809c2017-10-03 01:48:42 -04002736
Dave Wallace4878cbe2017-11-21 03:45:09 -05002737 if (n_read <= 0)
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002738 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05002739 VCL_LOCK_AND_GET_SESSION (session_index, &session);
2740
2741 poll_et = (((EPOLLET | EPOLLIN) & session->vep.ev.events) ==
2742 (EPOLLET | EPOLLIN));
2743 if (poll_et)
2744 session->vep.et_mask |= EPOLLIN;
2745
2746 if (state == STATE_CLOSE_ON_EMPTY)
2747 {
2748 session_state_t new_state = STATE_DISCONNECT;
2749 rv = VPPCOM_ECONNRESET;
2750
2751 if (VPPCOM_DEBUG > 1)
2752 {
Dave Wallaceee45d412017-11-24 21:44:06 -05002753 clib_warning ("[%d] vpp handle 0x%llx, sid %u: Empty fifo "
2754 "with %s session state 0x%x (%s)!"
2755 " Setting state to 0x%x (%s), returning %d (%s)",
2756 getpid (), vpp_handle, session_index,
Dave Wallace4878cbe2017-11-21 03:45:09 -05002757 is_server ? "server" : "client",
2758 state, vppcom_session_state_str (state),
2759 new_state, vppcom_session_state_str (new_state),
2760 rv, vppcom_retval_str (rv));
2761 }
2762
2763 session->state = new_state;
2764 }
2765 else
2766 rv = VPPCOM_EAGAIN;
2767
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002768 clib_spinlock_unlock (&vcm->sessions_lockp);
2769 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05002770 else
2771 rv = n_read;
Dave Wallace543852a2017-08-03 02:11:34 -04002772
Dave Wallace4878cbe2017-11-21 03:45:09 -05002773 if (VPPCOM_DEBUG > 2)
2774 {
2775 if (rv > 0)
Dave Wallaceee45d412017-11-24 21:44:06 -05002776 clib_warning ("[%d] vpp handle 0x%llx, sid %u: read %d bytes "
2777 "from %s (%p)", getpid (), vpp_handle,
Dave Wallace4878cbe2017-11-21 03:45:09 -05002778 session_index, n_read, fifo_str, rx_fifo);
2779 else
Dave Wallaceee45d412017-11-24 21:44:06 -05002780 clib_warning ("[%d] vpp handle 0x%llx, sid %u: nothing read! "
2781 "returning %d (%s)", getpid (), vpp_handle,
2782 session_index, rv, vppcom_retval_str (rv));
Dave Wallace4878cbe2017-11-21 03:45:09 -05002783 }
2784done:
2785 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04002786}
2787
Steven58f464e2017-10-25 12:33:12 -07002788int
2789vppcom_session_read (uint32_t session_index, void *buf, int n)
2790{
2791 return (vppcom_session_read_internal (session_index, buf, n, 0));
2792}
2793
2794static int
2795vppcom_session_peek (uint32_t session_index, void *buf, int n)
2796{
2797 return (vppcom_session_read_internal (session_index, buf, n, 1));
2798}
2799
Dave Wallace543852a2017-08-03 02:11:34 -04002800static inline int
2801vppcom_session_read_ready (session_t * session, u32 session_index)
2802{
Dave Wallace498b3a52017-11-09 13:00:34 -05002803 svm_fifo_t *rx_fifo = 0;
Dave Wallace543852a2017-08-03 02:11:34 -04002804 int ready = 0;
Dave Wallace60caa062017-11-10 17:07:13 -05002805 u32 poll_et;
Dave Wallace4878cbe2017-11-21 03:45:09 -05002806 int rv;
2807 u8 is_server = session->is_server;
2808 session_state_t state = session->state;
Dave Wallaceee45d412017-11-24 21:44:06 -05002809 u64 vpp_handle = session->vpp_handle;
Dave Wallace543852a2017-08-03 02:11:34 -04002810
2811 /* Assumes caller has acquired spinlock: vcm->sessions_lockp */
Dave Wallace4878cbe2017-11-21 03:45:09 -05002812 if (PREDICT_FALSE (session->is_vep))
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002813 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05002814 clib_warning ("[%d] ERROR: sid %u: cannot read from an "
2815 "epoll session!", getpid (), session_index);
2816 rv = VPPCOM_EBADFD;
2817 goto done;
Dave Wallace543852a2017-08-03 02:11:34 -04002818 }
Dave Wallace33e002b2017-09-06 01:20:02 -04002819
2820 if (session->is_listen)
Dave Wallace543852a2017-08-03 02:11:34 -04002821 ready = clib_fifo_elts (vcm->client_session_index_fifo);
2822 else
2823 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05002824 if (!(state & (SERVER_STATE_OPEN | CLIENT_STATE_OPEN | STATE_LISTEN)))
2825 {
2826 rv = ((state == STATE_DISCONNECT) ? VPPCOM_ECONNRESET :
2827 VPPCOM_ENOTCONN);
2828
2829 if (VPPCOM_DEBUG > 1)
Dave Wallaceee45d412017-11-24 21:44:06 -05002830 clib_warning ("[%d] vpp handle 0x%llx, sid %u: %s session is "
2831 "not open! state 0x%x (%s), returning %d (%s)",
2832 getpid (), vpp_handle, session_index,
2833 is_server ? "server" : "client",
Dave Wallace4878cbe2017-11-21 03:45:09 -05002834 state, vppcom_session_state_str (state),
2835 rv, vppcom_retval_str (rv));
2836 goto done;
2837 }
2838
2839 rx_fifo = ((!session->is_cut_thru || is_server) ?
Dave Wallace33e002b2017-09-06 01:20:02 -04002840 session->server_rx_fifo : session->server_tx_fifo);
Dave Wallace543852a2017-08-03 02:11:34 -04002841
Dave Wallace33e002b2017-09-06 01:20:02 -04002842 ready = svm_fifo_max_dequeue (rx_fifo);
Dave Wallace543852a2017-08-03 02:11:34 -04002843 }
2844
Dave Wallace4878cbe2017-11-21 03:45:09 -05002845 if (ready == 0)
Dave Wallace60caa062017-11-10 17:07:13 -05002846 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05002847 poll_et =
2848 ((EPOLLET | EPOLLIN) & session->vep.ev.events) == (EPOLLET | EPOLLIN);
2849 if (poll_et)
2850 session->vep.et_mask |= EPOLLIN;
Dave Wallace60caa062017-11-10 17:07:13 -05002851
Dave Wallace4878cbe2017-11-21 03:45:09 -05002852 if (state == STATE_CLOSE_ON_EMPTY)
2853 {
2854 rv = VPPCOM_ECONNRESET;
2855 session_state_t new_state = STATE_DISCONNECT;
2856
2857 if (VPPCOM_DEBUG > 1)
2858 {
Dave Wallaceee45d412017-11-24 21:44:06 -05002859 clib_warning ("[%d] vpp handle 0x%llx, sid %u: Empty fifo with"
2860 " %s session state 0x%x (%s)! Setting state to "
2861 "0x%x (%s), returning %d (%s)",
2862 getpid (), session_index, vpp_handle,
Dave Wallace4878cbe2017-11-21 03:45:09 -05002863 is_server ? "server" : "client",
2864 state, vppcom_session_state_str (state),
2865 new_state, vppcom_session_state_str (new_state),
2866 rv, vppcom_retval_str (rv));
2867 }
2868 session->state = new_state;
2869 goto done;
2870 }
2871 }
2872 rv = ready;
Dave Wallace16cb4082017-11-29 03:24:06 -05002873
2874 if (vcm->app_event_queue->cursize &&
2875 !pthread_mutex_trylock (&vcm->app_event_queue->mutex))
2876 {
2877 u32 i, n_to_dequeue = vcm->app_event_queue->cursize;
2878 session_fifo_event_t e;
2879
2880 for (i = 0; i < n_to_dequeue; i++)
2881 unix_shared_memory_queue_sub_raw (vcm->app_event_queue, (u8 *) & e);
2882
2883 pthread_mutex_unlock (&vcm->app_event_queue->mutex);
2884 }
2885
Dave Wallace4878cbe2017-11-21 03:45:09 -05002886done:
2887 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04002888}
2889
2890int
2891vppcom_session_write (uint32_t session_index, void *buf, int n)
2892{
Dave Wallace543852a2017-08-03 02:11:34 -04002893 session_t *session = 0;
2894 svm_fifo_t *tx_fifo;
2895 unix_shared_memory_queue_t *q;
2896 session_fifo_event_t evt;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002897 int rv, n_write;
Dave Wallace543852a2017-08-03 02:11:34 -04002898 char *fifo_str;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002899 u32 poll_et;
Dave Wallace4878cbe2017-11-21 03:45:09 -05002900 u8 is_server;
2901 u8 is_nonblocking;
2902 session_state_t state;
Dave Wallaceee45d412017-11-24 21:44:06 -05002903 u64 vpp_handle;
Dave Wallace543852a2017-08-03 02:11:34 -04002904
2905 ASSERT (buf);
2906
Dave Wallace4878cbe2017-11-21 03:45:09 -05002907 VCL_LOCK_AND_GET_SESSION (session_index, &session);
2908
2909 if (PREDICT_FALSE (session->is_vep))
Dave Wallace543852a2017-08-03 02:11:34 -04002910 {
2911 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallaceee45d412017-11-24 21:44:06 -05002912 clib_warning ("[%d] ERROR: vpp handle 0x%llx, sid %u: "
2913 "cannot write to an epoll session!",
2914 getpid (), session->vpp_handle, session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002915
2916 rv = VPPCOM_EBADFD;
2917 goto done;
Dave Wallace543852a2017-08-03 02:11:34 -04002918 }
2919
Dave Wallace4878cbe2017-11-21 03:45:09 -05002920 is_server = session->is_server;
2921 is_nonblocking = session->is_nonblocking;
Dave Wallaceee45d412017-11-24 21:44:06 -05002922 vpp_handle = session->vpp_handle;
Dave Wallace4878cbe2017-11-21 03:45:09 -05002923 state = session->state;
2924 if (!(state & (SERVER_STATE_OPEN | CLIENT_STATE_OPEN)))
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002925 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05002926 rv = ((state == STATE_DISCONNECT) ? VPPCOM_ECONNRESET :
2927 VPPCOM_ENOTCONN);
2928
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002929 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002930 if (VPPCOM_DEBUG > 1)
Dave Wallaceee45d412017-11-24 21:44:06 -05002931 clib_warning ("[%d] vpp handle 0x%llx, sid %u: "
2932 "%s session is not open! state 0x%x (%s)",
2933 getpid (), vpp_handle, session_index,
2934 is_server ? "server" : "client", state,
Dave Wallace4878cbe2017-11-21 03:45:09 -05002935 vppcom_session_state_str (state));
2936 goto done;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002937 }
2938
Dave Wallace4878cbe2017-11-21 03:45:09 -05002939 tx_fifo = ((!session->is_cut_thru || is_server) ?
Dave Wallace543852a2017-08-03 02:11:34 -04002940 session->server_tx_fifo : session->server_rx_fifo);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002941 fifo_str = ((!session->is_cut_thru || is_server) ?
Dave Wallace543852a2017-08-03 02:11:34 -04002942 "server_tx_fifo" : "server_rx_fifo");
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002943 clib_spinlock_unlock (&vcm->sessions_lockp);
2944
Dave Wallace543852a2017-08-03 02:11:34 -04002945 do
2946 {
Dave Wallacef7f809c2017-10-03 01:48:42 -04002947 n_write = svm_fifo_enqueue_nowait (tx_fifo, n, buf);
Dave Wallace543852a2017-08-03 02:11:34 -04002948 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05002949 while (!is_nonblocking && (n_write <= 0));
Dave Wallace543852a2017-08-03 02:11:34 -04002950
2951 /* If event wasn't set, add one */
Dave Wallacef7f809c2017-10-03 01:48:42 -04002952 if (!session->is_cut_thru && (n_write > 0) && svm_fifo_set_event (tx_fifo))
Dave Wallace543852a2017-08-03 02:11:34 -04002953 {
Dave Wallace543852a2017-08-03 02:11:34 -04002954 /* Fabricate TX event, send to vpp */
2955 evt.fifo = tx_fifo;
2956 evt.event_type = FIFO_EVENT_APP_TX;
Dave Wallace543852a2017-08-03 02:11:34 -04002957
Dave Wallace4878cbe2017-11-21 03:45:09 -05002958 VCL_LOCK_AND_GET_SESSION (session_index, &session);
2959 q = session->vpp_event_queue;
Dave Wallace543852a2017-08-03 02:11:34 -04002960 ASSERT (q);
2961 unix_shared_memory_queue_add (q, (u8 *) & evt,
2962 0 /* do wait for mutex */ );
Dave Wallace4878cbe2017-11-21 03:45:09 -05002963 clib_spinlock_unlock (&vcm->sessions_lockp);
2964 if (VPPCOM_DEBUG > 1)
Dave Wallaceee45d412017-11-24 21:44:06 -05002965 clib_warning ("[%d] vpp handle 0x%llx, sid %u: "
2966 "added FIFO_EVENT_APP_TX to "
Dave Wallace4878cbe2017-11-21 03:45:09 -05002967 "vpp_event_q %p, n_write %d", getpid (),
Dave Wallaceee45d412017-11-24 21:44:06 -05002968 vpp_handle, session_index, q, n_write);
Dave Wallace543852a2017-08-03 02:11:34 -04002969 }
2970
Dave Wallace4878cbe2017-11-21 03:45:09 -05002971 if (n_write <= 0)
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002972 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05002973 VCL_LOCK_AND_GET_SESSION (session_index, &session);
2974
2975 poll_et = (((EPOLLET | EPOLLOUT) & session->vep.ev.events) ==
2976 (EPOLLET | EPOLLOUT));
2977 if (poll_et)
2978 session->vep.et_mask |= EPOLLOUT;
2979
2980 if (state == STATE_CLOSE_ON_EMPTY)
2981 {
2982 session_state_t new_state = STATE_DISCONNECT;
2983 rv = VPPCOM_ECONNRESET;
2984
2985 if (VPPCOM_DEBUG > 1)
2986 {
Dave Wallaceee45d412017-11-24 21:44:06 -05002987 clib_warning ("[%d] vpp handle 0x%llx, sid %u: "
2988 "Empty fifo with %s session state 0x%x (%s)!"
2989 " Setting state to 0x%x (%s), returning %d (%s)",
2990 getpid (), vpp_handle, session_index,
Dave Wallace4878cbe2017-11-21 03:45:09 -05002991 is_server ? "server" : "client",
2992 state, vppcom_session_state_str (state),
2993 new_state, vppcom_session_state_str (new_state),
2994 rv, vppcom_retval_str (rv));
2995 }
2996
2997 session->state = new_state;
2998 }
2999 else
3000 rv = VPPCOM_EAGAIN;
3001
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003002 clib_spinlock_unlock (&vcm->sessions_lockp);
3003 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05003004 else
3005 rv = n_write;
Dave Wallacef7f809c2017-10-03 01:48:42 -04003006
Dave Wallace543852a2017-08-03 02:11:34 -04003007 if (VPPCOM_DEBUG > 2)
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003008 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05003009 if (n_write <= 0)
Dave Wallaceee45d412017-11-24 21:44:06 -05003010 clib_warning ("[%d] vpp handle 0x%llx, sid %u: "
3011 "FIFO-FULL %s (%p)", getpid (), vpp_handle,
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003012 session_index, fifo_str, tx_fifo);
3013 else
Dave Wallaceee45d412017-11-24 21:44:06 -05003014 clib_warning ("[%d] vpp handle 0x%llx, sid %u: "
3015 "wrote %d bytes to %s (%p)", getpid (), vpp_handle,
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003016 session_index, n_write, fifo_str, tx_fifo);
3017 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05003018done:
3019 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04003020}
3021
3022static inline int
3023vppcom_session_write_ready (session_t * session, u32 session_index)
3024{
Dave Wallace543852a2017-08-03 02:11:34 -04003025 svm_fifo_t *tx_fifo;
Dave Wallace33e002b2017-09-06 01:20:02 -04003026 char *fifo_str;
Dave Wallacef7f809c2017-10-03 01:48:42 -04003027 int ready;
Dave Wallace60caa062017-11-10 17:07:13 -05003028 u32 poll_et;
Dave Wallace4878cbe2017-11-21 03:45:09 -05003029 int rv;
3030 u8 is_server = session->is_server;
3031 session_state_t state = session->state;
Dave Wallace543852a2017-08-03 02:11:34 -04003032
3033 /* Assumes caller has acquired spinlock: vcm->sessions_lockp */
Dave Wallace4878cbe2017-11-21 03:45:09 -05003034 if (PREDICT_FALSE (session->is_vep))
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003035 {
Dave Wallaceee45d412017-11-24 21:44:06 -05003036 clib_warning ("[%d] ERROR: vpp handle 0x%llx, sid %u: "
3037 "cannot write to an epoll session!",
3038 getpid (), session->vpp_handle, session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -05003039 rv = VPPCOM_EBADFD;
3040 goto done;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04003041 }
3042
Dave Wallace4878cbe2017-11-21 03:45:09 -05003043 if (PREDICT_FALSE (session->is_listen))
Dave Wallace33e002b2017-09-06 01:20:02 -04003044 {
Dave Wallaceee45d412017-11-24 21:44:06 -05003045 clib_warning ("[%d] ERROR: vpp handle 0x%llx, sid %u: "
3046 "cannot write to a listen session!",
3047 getpid (), session->vpp_handle, session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -05003048 rv = VPPCOM_EBADFD;
3049 goto done;
3050 }
3051
3052 if (!(state & (SERVER_STATE_OPEN | CLIENT_STATE_OPEN)))
3053 {
3054 session_state_t state = session->state;
3055
3056 rv = ((state == STATE_DISCONNECT) ? VPPCOM_ECONNRESET :
3057 VPPCOM_ENOTCONN);
3058
Dave Wallaceee45d412017-11-24 21:44:06 -05003059 clib_warning ("[%d] ERROR: vpp handle 0x%llx, sid %u: "
3060 "%s session is not open! state 0x%x (%s), "
3061 "returning %d (%s)", getpid (), session->vpp_handle,
Dave Wallace4878cbe2017-11-21 03:45:09 -05003062 session_index, is_server ? "server" : "client",
3063 state, vppcom_session_state_str (state),
3064 rv, vppcom_retval_str (rv));
3065 goto done;
Dave Wallace33e002b2017-09-06 01:20:02 -04003066 }
3067
Dave Wallace543852a2017-08-03 02:11:34 -04003068 tx_fifo = ((!session->is_cut_thru || session->is_server) ?
3069 session->server_tx_fifo : session->server_rx_fifo);
Dave Wallace33e002b2017-09-06 01:20:02 -04003070 fifo_str = ((!session->is_cut_thru || session->is_server) ?
3071 "server_tx_fifo" : "server_rx_fifo");
Dave Wallace543852a2017-08-03 02:11:34 -04003072
Dave Wallacef7f809c2017-10-03 01:48:42 -04003073 ready = svm_fifo_max_enqueue (tx_fifo);
Dave Wallace543852a2017-08-03 02:11:34 -04003074
Dave Wallace33e002b2017-09-06 01:20:02 -04003075 if (VPPCOM_DEBUG > 3)
Dave Wallaceee45d412017-11-24 21:44:06 -05003076 clib_warning ("[%d] vpp handle 0x%llx, sid %u: "
3077 "peek %s (%p), ready = %d", getpid (),
3078 session->vpp_handle, session_index,
3079 fifo_str, tx_fifo, ready);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003080
Dave Wallace4878cbe2017-11-21 03:45:09 -05003081 if (ready == 0)
3082 {
3083 poll_et = (((EPOLLET | EPOLLOUT) & session->vep.ev.events) ==
3084 (EPOLLET | EPOLLOUT));
3085 if (poll_et)
3086 session->vep.et_mask |= EPOLLOUT;
3087
3088 if (state == STATE_CLOSE_ON_EMPTY)
3089 {
3090 rv = VPPCOM_ECONNRESET;
3091 session_state_t new_state = STATE_DISCONNECT;
3092
3093 if (VPPCOM_DEBUG > 1)
3094 {
Dave Wallaceee45d412017-11-24 21:44:06 -05003095 clib_warning ("[%d] vpp handle 0x%llx, sid %u: "
3096 "Empty fifo with %s session "
3097 "state 0x%x (%s)! Setting state to 0x%x (%s), "
3098 "returning %d (%s)", getpid (),
3099 session->vpp_handle, session_index,
Dave Wallace4878cbe2017-11-21 03:45:09 -05003100 is_server ? "server" : "client",
3101 state, vppcom_session_state_str (state),
3102 new_state, vppcom_session_state_str (new_state),
3103 rv, vppcom_retval_str (rv));
3104 }
3105 session->state = new_state;
3106 goto done;
3107 }
3108 }
3109 rv = ready;
3110done:
3111 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04003112}
3113
3114int
3115vppcom_select (unsigned long n_bits, unsigned long *read_map,
3116 unsigned long *write_map, unsigned long *except_map,
3117 double time_to_wait)
3118{
Dave Wallace543852a2017-08-03 02:11:34 -04003119 u32 session_index;
3120 session_t *session = 0;
3121 int rv, bits_set = 0;
3122 f64 timeout = clib_time_now (&vcm->clib_time) + time_to_wait;
3123 u32 minbits = clib_max (n_bits, BITS (uword));
3124
3125 ASSERT (sizeof (clib_bitmap_t) == sizeof (long int));
3126
Dave Wallace7876d392017-10-19 03:53:57 -04003127 if (n_bits && read_map)
Dave Wallace543852a2017-08-03 02:11:34 -04003128 {
3129 clib_bitmap_validate (vcm->rd_bitmap, minbits);
3130 clib_memcpy (vcm->rd_bitmap, read_map, vec_len (vcm->rd_bitmap));
3131 memset (read_map, 0, vec_len (vcm->rd_bitmap));
3132 }
Dave Wallace7876d392017-10-19 03:53:57 -04003133 if (n_bits && write_map)
Dave Wallace543852a2017-08-03 02:11:34 -04003134 {
3135 clib_bitmap_validate (vcm->wr_bitmap, minbits);
3136 clib_memcpy (vcm->wr_bitmap, write_map, vec_len (vcm->wr_bitmap));
3137 memset (write_map, 0, vec_len (vcm->wr_bitmap));
3138 }
Dave Wallace7876d392017-10-19 03:53:57 -04003139 if (n_bits && except_map)
Dave Wallace543852a2017-08-03 02:11:34 -04003140 {
3141 clib_bitmap_validate (vcm->ex_bitmap, minbits);
3142 clib_memcpy (vcm->ex_bitmap, except_map, vec_len (vcm->ex_bitmap));
3143 memset (except_map, 0, vec_len (vcm->ex_bitmap));
3144 }
3145
3146 do
3147 {
3148 /* *INDENT-OFF* */
Dave Wallacee22aa742017-10-20 12:30:38 -04003149 if (n_bits)
3150 {
3151 if (read_map)
Dave Wallace543852a2017-08-03 02:11:34 -04003152 {
Dave Wallacee22aa742017-10-20 12:30:38 -04003153 clib_bitmap_foreach (session_index, vcm->rd_bitmap,
3154 ({
3155 clib_spinlock_lock (&vcm->sessions_lockp);
3156 rv = vppcom_session_at_index (session_index, &session);
3157 if (rv < 0)
3158 {
3159 clib_spinlock_unlock (&vcm->sessions_lockp);
3160 if (VPPCOM_DEBUG > 1)
3161 clib_warning ("[%d] session %d specified in "
Dave Wallace2e005bb2017-11-07 01:21:39 -05003162 "read_map is closed.", getpid (),
Dave Wallacee22aa742017-10-20 12:30:38 -04003163 session_index);
3164 bits_set = VPPCOM_EBADFD;
3165 goto select_done;
3166 }
3167
3168 rv = vppcom_session_read_ready (session, session_index);
3169 clib_spinlock_unlock (&vcm->sessions_lockp);
3170 if (except_map && vcm->ex_bitmap &&
3171 clib_bitmap_get (vcm->ex_bitmap, session_index) &&
3172 (rv < 0))
3173 {
3174 // TBD: clib_warning
3175 clib_bitmap_set_no_check (except_map, session_index, 1);
3176 bits_set++;
3177 }
3178 else if (rv > 0)
3179 {
3180 // TBD: clib_warning
3181 clib_bitmap_set_no_check (read_map, session_index, 1);
3182 bits_set++;
3183 }
3184 }));
Dave Wallace543852a2017-08-03 02:11:34 -04003185 }
3186
Dave Wallacee22aa742017-10-20 12:30:38 -04003187 if (write_map)
Dave Wallace543852a2017-08-03 02:11:34 -04003188 {
Dave Wallacee22aa742017-10-20 12:30:38 -04003189 clib_bitmap_foreach (session_index, vcm->wr_bitmap,
3190 ({
3191 clib_spinlock_lock (&vcm->sessions_lockp);
3192 rv = vppcom_session_at_index (session_index, &session);
3193 if (rv < 0)
3194 {
3195 clib_spinlock_unlock (&vcm->sessions_lockp);
3196 if (VPPCOM_DEBUG > 0)
3197 clib_warning ("[%d] session %d specified in "
Dave Wallace2e005bb2017-11-07 01:21:39 -05003198 "write_map is closed.", getpid (),
Dave Wallacee22aa742017-10-20 12:30:38 -04003199 session_index);
3200 bits_set = VPPCOM_EBADFD;
3201 goto select_done;
3202 }
Dave Wallace543852a2017-08-03 02:11:34 -04003203
Dave Wallacee22aa742017-10-20 12:30:38 -04003204 rv = vppcom_session_write_ready (session, session_index);
3205 clib_spinlock_unlock (&vcm->sessions_lockp);
3206 if (write_map && (rv > 0))
3207 {
3208 // TBD: clib_warning
3209 clib_bitmap_set_no_check (write_map, session_index, 1);
3210 bits_set++;
3211 }
3212 }));
Dave Wallace543852a2017-08-03 02:11:34 -04003213 }
3214
Dave Wallacee22aa742017-10-20 12:30:38 -04003215 if (except_map)
Dave Wallace543852a2017-08-03 02:11:34 -04003216 {
Dave Wallacee22aa742017-10-20 12:30:38 -04003217 clib_bitmap_foreach (session_index, vcm->ex_bitmap,
3218 ({
3219 clib_spinlock_lock (&vcm->sessions_lockp);
3220 rv = vppcom_session_at_index (session_index, &session);
3221 if (rv < 0)
3222 {
3223 clib_spinlock_unlock (&vcm->sessions_lockp);
3224 if (VPPCOM_DEBUG > 1)
3225 clib_warning ("[%d] session %d specified in "
Dave Wallace2e005bb2017-11-07 01:21:39 -05003226 "except_map is closed.", getpid (),
Dave Wallacee22aa742017-10-20 12:30:38 -04003227 session_index);
3228 bits_set = VPPCOM_EBADFD;
3229 goto select_done;
3230 }
Dave Wallace543852a2017-08-03 02:11:34 -04003231
Dave Wallacee22aa742017-10-20 12:30:38 -04003232 rv = vppcom_session_read_ready (session, session_index);
3233 clib_spinlock_unlock (&vcm->sessions_lockp);
3234 if (rv < 0)
3235 {
3236 // TBD: clib_warning
3237 clib_bitmap_set_no_check (except_map, session_index, 1);
3238 bits_set++;
3239 }
3240 }));
Dave Wallace543852a2017-08-03 02:11:34 -04003241 }
Dave Wallacee22aa742017-10-20 12:30:38 -04003242 }
Dave Wallace543852a2017-08-03 02:11:34 -04003243 /* *INDENT-ON* */
3244 }
3245 while (clib_time_now (&vcm->clib_time) < timeout);
3246
3247select_done:
3248 return (bits_set);
3249}
3250
Dave Wallacef7f809c2017-10-03 01:48:42 -04003251static inline void
3252vep_verify_epoll_chain (u32 vep_idx)
3253{
3254 session_t *session;
3255 vppcom_epoll_t *vep;
3256 int rv;
Dave Wallace498b3a52017-11-09 13:00:34 -05003257 u32 sid = vep_idx;
Dave Wallacef7f809c2017-10-03 01:48:42 -04003258
Dave Wallace498b3a52017-11-09 13:00:34 -05003259 if (VPPCOM_DEBUG <= 1)
Dave Wallacef7f809c2017-10-03 01:48:42 -04003260 return;
3261
3262 /* Assumes caller has acquired spinlock: vcm->sessions_lockp */
3263 rv = vppcom_session_at_index (vep_idx, &session);
3264 if (PREDICT_FALSE (rv))
3265 {
Dave Wallace2e005bb2017-11-07 01:21:39 -05003266 clib_warning ("[%d] ERROR: Invalid vep_idx (%u)!", getpid (), vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003267 goto done;
3268 }
3269 if (PREDICT_FALSE (!session->is_vep))
3270 {
Dave Wallace2e005bb2017-11-07 01:21:39 -05003271 clib_warning ("[%d] ERROR: vep_idx (%u) is not a vep!", getpid (),
Dave Wallace774169b2017-11-01 20:07:40 -04003272 vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003273 goto done;
3274 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05003275 vep = &session->vep;
Dave Wallace498b3a52017-11-09 13:00:34 -05003276 clib_warning ("[%d] vep_idx (%u): Dumping epoll chain\n"
3277 "{\n"
3278 " is_vep = %u\n"
3279 " is_vep_session = %u\n"
Dave Wallace4878cbe2017-11-21 03:45:09 -05003280 " next_sid = 0x%x (%u)\n"
Dave Wallace498b3a52017-11-09 13:00:34 -05003281 " wait_cont_idx = 0x%x (%u)\n"
Dave Wallace4878cbe2017-11-21 03:45:09 -05003282 "}\n", getpid (), vep_idx,
3283 session->is_vep, session->is_vep_session,
3284 vep->next_sid, vep->next_sid,
Dave Wallace498b3a52017-11-09 13:00:34 -05003285 session->wait_cont_idx, session->wait_cont_idx);
Dave Wallace4878cbe2017-11-21 03:45:09 -05003286
3287 for (sid = vep->next_sid; sid != ~0; sid = vep->next_sid)
Dave Wallacef7f809c2017-10-03 01:48:42 -04003288 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05003289 rv = vppcom_session_at_index (sid, &session);
3290 if (PREDICT_FALSE (rv))
Dave Wallacef7f809c2017-10-03 01:48:42 -04003291 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05003292 clib_warning ("[%d] ERROR: Invalid sid (%u)!", getpid (), sid);
3293 goto done;
3294 }
3295 if (PREDICT_FALSE (session->is_vep))
3296 clib_warning ("[%d] ERROR: sid (%u) is a vep!", getpid (), vep_idx);
3297 else if (PREDICT_FALSE (!session->is_vep_session))
3298 {
3299 clib_warning ("[%d] ERROR: session (%u) is not a vep session!",
3300 getpid (), sid);
3301 goto done;
3302 }
3303 vep = &session->vep;
3304 if (PREDICT_FALSE (vep->vep_idx != vep_idx))
3305 clib_warning ("[%d] ERROR: session (%u) vep_idx (%u) != "
3306 "vep_idx (%u)!", getpid (),
3307 sid, session->vep.vep_idx, vep_idx);
3308 if (session->is_vep_session)
3309 {
3310 clib_warning ("vep_idx[%u]: sid 0x%x (%u)\n"
3311 "{\n"
3312 " next_sid = 0x%x (%u)\n"
3313 " prev_sid = 0x%x (%u)\n"
3314 " vep_idx = 0x%x (%u)\n"
3315 " ev.events = 0x%x\n"
3316 " ev.data.u64 = 0x%llx\n"
3317 " et_mask = 0x%x\n"
3318 "}\n",
3319 vep_idx, sid, sid,
3320 vep->next_sid, vep->next_sid,
3321 vep->prev_sid, vep->prev_sid,
3322 vep->vep_idx, vep->vep_idx,
3323 vep->ev.events, vep->ev.data.u64, vep->et_mask);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003324 }
3325 }
Dave Wallacef7f809c2017-10-03 01:48:42 -04003326
3327done:
Dave Wallace498b3a52017-11-09 13:00:34 -05003328 clib_warning ("[%d] vep_idx (%u): Dump complete!\n", getpid (), vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003329}
3330
3331int
3332vppcom_epoll_create (void)
3333{
Dave Wallacef7f809c2017-10-03 01:48:42 -04003334 session_t *vep_session;
3335 u32 vep_idx;
3336
3337 clib_spinlock_lock (&vcm->sessions_lockp);
3338 pool_get (vcm->sessions, vep_session);
3339 memset (vep_session, 0, sizeof (*vep_session));
3340 vep_idx = vep_session - vcm->sessions;
3341
3342 vep_session->is_vep = 1;
3343 vep_session->vep.vep_idx = ~0;
3344 vep_session->vep.next_sid = ~0;
3345 vep_session->vep.prev_sid = ~0;
3346 vep_session->wait_cont_idx = ~0;
Dave Wallace4878cbe2017-11-21 03:45:09 -05003347 vep_session->vpp_handle = ~0;
Dave Wallacef7f809c2017-10-03 01:48:42 -04003348 clib_spinlock_unlock (&vcm->sessions_lockp);
3349
3350 if (VPPCOM_DEBUG > 0)
Dave Wallaceee45d412017-11-24 21:44:06 -05003351 clib_warning ("[%d] Created vep_idx %u / sid %u!",
3352 getpid (), vep_idx, vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003353
3354 return (vep_idx);
3355}
3356
3357int
3358vppcom_epoll_ctl (uint32_t vep_idx, int op, uint32_t session_index,
3359 struct epoll_event *event)
3360{
Dave Wallacef7f809c2017-10-03 01:48:42 -04003361 session_t *vep_session;
3362 session_t *session;
3363 int rv;
3364
3365 if (vep_idx == session_index)
3366 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05003367 clib_warning ("[%d] ERROR: vep_idx == session_index (%u)!",
3368 getpid (), vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003369 return VPPCOM_EINVAL;
3370 }
3371
3372 clib_spinlock_lock (&vcm->sessions_lockp);
3373 rv = vppcom_session_at_index (vep_idx, &vep_session);
3374 if (PREDICT_FALSE (rv))
3375 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05003376 clib_warning ("[%d] ERROR: Invalid vep_idx (%u)!", vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003377 goto done;
3378 }
3379 if (PREDICT_FALSE (!vep_session->is_vep))
3380 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05003381 clib_warning ("[%d] ERROR: vep_idx (%u) is not a vep!",
3382 getpid (), vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003383 rv = VPPCOM_EINVAL;
3384 goto done;
3385 }
3386
3387 ASSERT (vep_session->vep.vep_idx == ~0);
3388 ASSERT (vep_session->vep.prev_sid == ~0);
3389
3390 rv = vppcom_session_at_index (session_index, &session);
3391 if (PREDICT_FALSE (rv))
3392 {
3393 if (VPPCOM_DEBUG > 0)
Dave Wallace774169b2017-11-01 20:07:40 -04003394 clib_warning ("[%d] ERROR: Invalid session_index (%u)!",
Dave Wallace2e005bb2017-11-07 01:21:39 -05003395 getpid (), session_index);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003396 goto done;
3397 }
3398 if (PREDICT_FALSE (session->is_vep))
3399 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05003400 clib_warning ("ERROR: session_index (%u) is a vep!", vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003401 rv = VPPCOM_EINVAL;
3402 goto done;
3403 }
3404
3405 switch (op)
3406 {
3407 case EPOLL_CTL_ADD:
3408 if (PREDICT_FALSE (!event))
3409 {
Dave Wallace774169b2017-11-01 20:07:40 -04003410 clib_warning ("[%d] ERROR: EPOLL_CTL_ADD: NULL pointer to "
Dave Wallace2e005bb2017-11-07 01:21:39 -05003411 "epoll_event structure!", getpid ());
Dave Wallacef7f809c2017-10-03 01:48:42 -04003412 rv = VPPCOM_EINVAL;
3413 goto done;
3414 }
3415 if (vep_session->vep.next_sid != ~0)
3416 {
3417 session_t *next_session;
3418 rv = vppcom_session_at_index (vep_session->vep.next_sid,
3419 &next_session);
3420 if (PREDICT_FALSE (rv))
3421 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05003422 clib_warning ("[%d] ERROR: EPOLL_CTL_ADD: Invalid "
3423 "vep.next_sid (%u) on vep_idx (%u)!",
3424 getpid (), vep_session->vep.next_sid, vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003425 goto done;
3426 }
3427 ASSERT (next_session->vep.prev_sid == vep_idx);
3428 next_session->vep.prev_sid = session_index;
3429 }
3430 session->vep.next_sid = vep_session->vep.next_sid;
3431 session->vep.prev_sid = vep_idx;
3432 session->vep.vep_idx = vep_idx;
3433 session->vep.et_mask = VEP_DEFAULT_ET_MASK;
3434 session->vep.ev = *event;
Dave Wallace4878cbe2017-11-21 03:45:09 -05003435 session->is_vep = 0;
Dave Wallacef7f809c2017-10-03 01:48:42 -04003436 session->is_vep_session = 1;
3437 vep_session->vep.next_sid = session_index;
3438 if (VPPCOM_DEBUG > 1)
Dave Wallace774169b2017-11-01 20:07:40 -04003439 clib_warning ("[%d] EPOLL_CTL_ADD: vep_idx %u, sid %u, events 0x%x,"
Dave Wallace2e005bb2017-11-07 01:21:39 -05003440 " data 0x%llx!", getpid (), vep_idx, session_index,
Dave Wallacef7f809c2017-10-03 01:48:42 -04003441 event->events, event->data.u64);
3442 break;
3443
3444 case EPOLL_CTL_MOD:
3445 if (PREDICT_FALSE (!event))
3446 {
Dave Wallace774169b2017-11-01 20:07:40 -04003447 clib_warning ("[%d] ERROR: EPOLL_CTL_MOD: NULL pointer to "
Dave Wallace2e005bb2017-11-07 01:21:39 -05003448 "epoll_event structure!", getpid ());
Dave Wallacef7f809c2017-10-03 01:48:42 -04003449 rv = VPPCOM_EINVAL;
3450 goto done;
3451 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05003452 else if (PREDICT_FALSE (!session->is_vep_session))
Dave Wallacef7f809c2017-10-03 01:48:42 -04003453 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05003454 clib_warning ("[%d] ERROR: sid %u EPOLL_CTL_MOD: "
3455 "not a vep session!", getpid (), session_index);
3456 rv = VPPCOM_EINVAL;
3457 goto done;
3458 }
3459 else if (PREDICT_FALSE (session->vep.vep_idx != vep_idx))
3460 {
3461 clib_warning ("[%d] ERROR: sid %u EPOLL_CTL_MOD: "
3462 "vep_idx (%u) != vep_idx (%u)!",
3463 getpid (), session_index,
3464 session->vep.vep_idx, vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003465 rv = VPPCOM_EINVAL;
3466 goto done;
3467 }
3468 session->vep.et_mask = VEP_DEFAULT_ET_MASK;
3469 session->vep.ev = *event;
3470 if (VPPCOM_DEBUG > 1)
Dave Wallace774169b2017-11-01 20:07:40 -04003471 clib_warning ("[%d] EPOLL_CTL_MOD: vep_idx %u, sid %u, events 0x%x,"
Dave Wallace2e005bb2017-11-07 01:21:39 -05003472 " data 0x%llx!", getpid (), vep_idx, session_index,
Dave Wallacef7f809c2017-10-03 01:48:42 -04003473 event->events, event->data.u64);
3474 break;
3475
3476 case EPOLL_CTL_DEL:
Dave Wallace4878cbe2017-11-21 03:45:09 -05003477 if (PREDICT_FALSE (!session->is_vep_session))
Dave Wallacef7f809c2017-10-03 01:48:42 -04003478 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05003479 clib_warning ("[%d] ERROR: sid %u EPOLL_CTL_DEL: "
3480 "not a vep session!", getpid (), session_index);
3481 rv = VPPCOM_EINVAL;
3482 goto done;
3483 }
3484 else if (PREDICT_FALSE (session->vep.vep_idx != vep_idx))
3485 {
3486 clib_warning ("[%d] ERROR: sid %u EPOLL_CTL_DEL: "
3487 "vep_idx (%u) != vep_idx (%u)!",
3488 getpid (), session_index,
3489 session->vep.vep_idx, vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003490 rv = VPPCOM_EINVAL;
3491 goto done;
3492 }
3493
3494 vep_session->wait_cont_idx =
3495 (vep_session->wait_cont_idx == session_index) ?
3496 session->vep.next_sid : vep_session->wait_cont_idx;
3497
3498 if (session->vep.prev_sid == vep_idx)
3499 vep_session->vep.next_sid = session->vep.next_sid;
3500 else
3501 {
3502 session_t *prev_session;
3503 rv = vppcom_session_at_index (session->vep.prev_sid, &prev_session);
3504 if (PREDICT_FALSE (rv))
3505 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05003506 clib_warning ("[%d] ERROR: EPOLL_CTL_DEL: Invalid "
3507 "vep.prev_sid (%u) on sid (%u)!",
3508 getpid (), session->vep.prev_sid, session_index);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003509 goto done;
3510 }
3511 ASSERT (prev_session->vep.next_sid == session_index);
3512 prev_session->vep.next_sid = session->vep.next_sid;
3513 }
3514 if (session->vep.next_sid != ~0)
3515 {
3516 session_t *next_session;
3517 rv = vppcom_session_at_index (session->vep.next_sid, &next_session);
3518 if (PREDICT_FALSE (rv))
3519 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05003520 clib_warning ("[%d] ERROR: EPOLL_CTL_DEL: Invalid "
3521 "vep.next_sid (%u) on sid (%u)!",
3522 getpid (), session->vep.next_sid, session_index);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003523 goto done;
3524 }
3525 ASSERT (next_session->vep.prev_sid == session_index);
3526 next_session->vep.prev_sid = session->vep.prev_sid;
3527 }
3528
3529 memset (&session->vep, 0, sizeof (session->vep));
3530 session->vep.next_sid = ~0;
3531 session->vep.prev_sid = ~0;
3532 session->vep.vep_idx = ~0;
3533 session->is_vep_session = 0;
3534 if (VPPCOM_DEBUG > 1)
Dave Wallace774169b2017-11-01 20:07:40 -04003535 clib_warning ("[%d] EPOLL_CTL_DEL: vep_idx %u, sid %u!",
Dave Wallace2e005bb2017-11-07 01:21:39 -05003536 getpid (), vep_idx, session_index);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003537 break;
3538
3539 default:
Dave Wallace2e005bb2017-11-07 01:21:39 -05003540 clib_warning ("[%d] ERROR: Invalid operation (%d)!", getpid (), op);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003541 rv = VPPCOM_EINVAL;
3542 }
3543
3544 vep_verify_epoll_chain (vep_idx);
3545
3546done:
3547 clib_spinlock_unlock (&vcm->sessions_lockp);
3548 return rv;
3549}
3550
Dave Wallacef7f809c2017-10-03 01:48:42 -04003551int
3552vppcom_epoll_wait (uint32_t vep_idx, struct epoll_event *events,
3553 int maxevents, double wait_for_time)
3554{
Dave Wallacef7f809c2017-10-03 01:48:42 -04003555 session_t *vep_session;
3556 int rv;
3557 f64 timeout = clib_time_now (&vcm->clib_time) + wait_for_time;
Dave Wallace2e005bb2017-11-07 01:21:39 -05003558 u32 keep_trying = 1;
Dave Wallacef7f809c2017-10-03 01:48:42 -04003559 int num_ev = 0;
3560 u32 vep_next_sid, wait_cont_idx;
3561 u8 is_vep;
3562
3563 if (PREDICT_FALSE (maxevents <= 0))
3564 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05003565 clib_warning ("[%d] ERROR: Invalid maxevents (%d)!",
3566 getpid (), maxevents);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003567 return VPPCOM_EINVAL;
3568 }
Dave Wallacef7f809c2017-10-03 01:48:42 -04003569 memset (events, 0, sizeof (*events) * maxevents);
3570
3571 VCL_LOCK_AND_GET_SESSION (vep_idx, &vep_session);
3572 vep_next_sid = vep_session->vep.next_sid;
3573 is_vep = vep_session->is_vep;
3574 wait_cont_idx = vep_session->wait_cont_idx;
3575 clib_spinlock_unlock (&vcm->sessions_lockp);
3576
3577 if (PREDICT_FALSE (!is_vep))
3578 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05003579 clib_warning ("[%d] ERROR: vep_idx (%u) is not a vep!",
3580 getpid (), vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003581 rv = VPPCOM_EINVAL;
3582 goto done;
3583 }
Dave Wallacee695cb42017-11-02 22:04:42 -04003584 if (PREDICT_FALSE (vep_next_sid == ~0))
Dave Wallacef7f809c2017-10-03 01:48:42 -04003585 {
Dave Wallacee695cb42017-11-02 22:04:42 -04003586 if (VPPCOM_DEBUG > 0)
3587 clib_warning ("[%d] WARNING: vep_idx (%u) is empty!",
Dave Wallace2e005bb2017-11-07 01:21:39 -05003588 getpid (), vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003589 goto done;
3590 }
3591
3592 do
3593 {
3594 u32 sid;
3595 u32 next_sid = ~0;
3596 session_t *session;
3597
3598 for (sid = (wait_cont_idx == ~0) ? vep_next_sid : wait_cont_idx;
3599 sid != ~0; sid = next_sid)
3600 {
3601 u32 session_events, et_mask, clear_et_mask, session_vep_idx;
3602 u8 add_event, is_vep_session;
3603 int ready;
3604 u64 session_ev_data;
3605
3606 VCL_LOCK_AND_GET_SESSION (sid, &session);
3607 next_sid = session->vep.next_sid;
3608 session_events = session->vep.ev.events;
3609 et_mask = session->vep.et_mask;
3610 is_vep = session->is_vep;
3611 is_vep_session = session->is_vep_session;
3612 session_vep_idx = session->vep.vep_idx;
3613 session_ev_data = session->vep.ev.data.u64;
3614 clib_spinlock_unlock (&vcm->sessions_lockp);
3615
3616 if (PREDICT_FALSE (is_vep))
3617 {
3618 if (VPPCOM_DEBUG > 0)
Dave Wallace774169b2017-11-01 20:07:40 -04003619 clib_warning ("[%d] ERROR: sid (%u) is a vep!",
Dave Wallace2e005bb2017-11-07 01:21:39 -05003620 getpid (), vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003621 rv = VPPCOM_EINVAL;
3622 goto done;
3623 }
3624 if (PREDICT_FALSE (!is_vep_session))
3625 {
3626 if (VPPCOM_DEBUG > 0)
Dave Wallace774169b2017-11-01 20:07:40 -04003627 clib_warning ("[%d] ERROR: session (%u) is not "
Dave Wallace2e005bb2017-11-07 01:21:39 -05003628 "a vep session!", getpid (), sid);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003629 rv = VPPCOM_EINVAL;
3630 goto done;
3631 }
3632 if (PREDICT_FALSE (session_vep_idx != vep_idx))
3633 {
Dave Wallace774169b2017-11-01 20:07:40 -04003634 clib_warning ("[%d] ERROR: session (%u) "
Dave Wallacef7f809c2017-10-03 01:48:42 -04003635 "vep_idx (%u) != vep_idx (%u)!",
Dave Wallace2e005bb2017-11-07 01:21:39 -05003636 getpid (), sid, session->vep.vep_idx, vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003637 rv = VPPCOM_EINVAL;
3638 goto done;
3639 }
3640
3641 add_event = clear_et_mask = 0;
3642
Dave Wallace60caa062017-11-10 17:07:13 -05003643 if (EPOLLIN & session_events)
Dave Wallacef7f809c2017-10-03 01:48:42 -04003644 {
3645 VCL_LOCK_AND_GET_SESSION (sid, &session);
3646 ready = vppcom_session_read_ready (session, sid);
3647 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace60caa062017-11-10 17:07:13 -05003648 if ((ready > 0) && (EPOLLIN & et_mask))
Dave Wallacef7f809c2017-10-03 01:48:42 -04003649 {
3650 add_event = 1;
3651 events[num_ev].events |= EPOLLIN;
Dave Wallace60caa062017-11-10 17:07:13 -05003652 if (((EPOLLET | EPOLLIN) & session_events) ==
3653 (EPOLLET | EPOLLIN))
Dave Wallacef7f809c2017-10-03 01:48:42 -04003654 clear_et_mask |= EPOLLIN;
3655 }
3656 else if (ready < 0)
3657 {
3658 add_event = 1;
3659 switch (ready)
3660 {
3661 case VPPCOM_ECONNRESET:
3662 events[num_ev].events |= EPOLLHUP | EPOLLRDHUP;
3663 break;
3664
3665 default:
3666 events[num_ev].events |= EPOLLERR;
3667 break;
3668 }
3669 }
3670 }
3671
Dave Wallace60caa062017-11-10 17:07:13 -05003672 if (EPOLLOUT & session_events)
Dave Wallacef7f809c2017-10-03 01:48:42 -04003673 {
3674 VCL_LOCK_AND_GET_SESSION (sid, &session);
3675 ready = vppcom_session_write_ready (session, sid);
3676 clib_spinlock_unlock (&vcm->sessions_lockp);
Dave Wallace60caa062017-11-10 17:07:13 -05003677 if ((ready > 0) && (EPOLLOUT & et_mask))
Dave Wallacef7f809c2017-10-03 01:48:42 -04003678 {
3679 add_event = 1;
3680 events[num_ev].events |= EPOLLOUT;
Dave Wallace60caa062017-11-10 17:07:13 -05003681 if (((EPOLLET | EPOLLOUT) & session_events) ==
3682 (EPOLLET | EPOLLOUT))
Dave Wallacef7f809c2017-10-03 01:48:42 -04003683 clear_et_mask |= EPOLLOUT;
3684 }
3685 else if (ready < 0)
3686 {
3687 add_event = 1;
3688 switch (ready)
3689 {
3690 case VPPCOM_ECONNRESET:
3691 events[num_ev].events |= EPOLLHUP;
3692 break;
3693
3694 default:
3695 events[num_ev].events |= EPOLLERR;
3696 break;
3697 }
3698 }
3699 }
3700
3701 if (add_event)
3702 {
3703 events[num_ev].data.u64 = session_ev_data;
3704 if (EPOLLONESHOT & session_events)
3705 {
3706 VCL_LOCK_AND_GET_SESSION (sid, &session);
3707 session->vep.ev.events = 0;
3708 clib_spinlock_unlock (&vcm->sessions_lockp);
3709 }
3710 num_ev++;
3711 if (num_ev == maxevents)
3712 {
3713 VCL_LOCK_AND_GET_SESSION (vep_idx, &vep_session);
3714 vep_session->wait_cont_idx = next_sid;
3715 clib_spinlock_unlock (&vcm->sessions_lockp);
3716 goto done;
3717 }
3718 }
3719 if (wait_cont_idx != ~0)
3720 {
3721 if (next_sid == ~0)
3722 next_sid = vep_next_sid;
3723 else if (next_sid == wait_cont_idx)
3724 next_sid = ~0;
3725 }
3726 }
Dave Wallace2e005bb2017-11-07 01:21:39 -05003727 if (wait_for_time != -1)
3728 keep_trying = (clib_time_now (&vcm->clib_time) <= timeout) ? 1 : 0;
Dave Wallacef7f809c2017-10-03 01:48:42 -04003729 }
Dave Wallace2e005bb2017-11-07 01:21:39 -05003730 while ((num_ev == 0) && keep_trying);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003731
3732 if (wait_cont_idx != ~0)
3733 {
3734 VCL_LOCK_AND_GET_SESSION (vep_idx, &vep_session);
3735 vep_session->wait_cont_idx = ~0;
3736 clib_spinlock_unlock (&vcm->sessions_lockp);
3737 }
3738done:
3739 return (rv != VPPCOM_OK) ? rv : num_ev;
3740}
3741
Dave Wallace35830af2017-10-09 01:43:42 -04003742int
3743vppcom_session_attr (uint32_t session_index, uint32_t op,
3744 void *buffer, uint32_t * buflen)
3745{
Dave Wallace35830af2017-10-09 01:43:42 -04003746 session_t *session;
3747 int rv = VPPCOM_OK;
3748 u32 *flags = buffer;
Steven2199aab2017-10-15 20:18:47 -07003749 vppcom_endpt_t *ep = buffer;
Dave Wallace35830af2017-10-09 01:43:42 -04003750
3751 VCL_LOCK_AND_GET_SESSION (session_index, &session);
3752 switch (op)
3753 {
3754 case VPPCOM_ATTR_GET_NREAD:
3755 rv = vppcom_session_read_ready (session, session_index);
Dave Wallace227867f2017-11-13 21:21:53 -05003756 if (VPPCOM_DEBUG > 2)
3757 clib_warning ("[%d] VPPCOM_ATTR_GET_NREAD: sid %u, nread = %d",
Dave Wallace2e005bb2017-11-07 01:21:39 -05003758 getpid (), rv);
Dave Wallace35830af2017-10-09 01:43:42 -04003759 break;
3760
Dave Wallace227867f2017-11-13 21:21:53 -05003761 case VPPCOM_ATTR_GET_NWRITE:
3762 rv = vppcom_session_write_ready (session, session_index);
3763 if (VPPCOM_DEBUG > 2)
3764 clib_warning ("[%d] VPPCOM_ATTR_GET_NWRITE: sid %u, nwrite = %d",
3765 getpid (), session_index, rv);
Dave Wallace35830af2017-10-09 01:43:42 -04003766 break;
3767
3768 case VPPCOM_ATTR_GET_FLAGS:
3769 if (buffer && buflen && (*buflen >= sizeof (*flags)))
3770 {
3771 *flags = O_RDWR | ((session->is_nonblocking) ? O_NONBLOCK : 0);
3772 *buflen = sizeof (*flags);
Dave Wallace227867f2017-11-13 21:21:53 -05003773 if (VPPCOM_DEBUG > 2)
3774 clib_warning ("[%d] VPPCOM_ATTR_GET_FLAGS: sid %u, "
3775 "flags = 0x%08x, is_nonblocking = %u", getpid (),
3776 session_index, *flags, session->is_nonblocking);
Dave Wallace35830af2017-10-09 01:43:42 -04003777 }
3778 else
3779 rv = VPPCOM_EINVAL;
3780 break;
3781
3782 case VPPCOM_ATTR_SET_FLAGS:
3783 if (buffer && buflen && (*buflen >= sizeof (*flags)))
3784 {
3785 session->is_nonblocking = (*flags & O_NONBLOCK) ? 1 : 0;
Dave Wallace227867f2017-11-13 21:21:53 -05003786 if (VPPCOM_DEBUG > 2)
3787 clib_warning ("[%d] VPPCOM_ATTR_SET_FLAGS: sid %u, "
3788 "flags = 0x%08x, is_nonblocking = %u",
Dave Wallace4878cbe2017-11-21 03:45:09 -05003789 getpid (), session_index, *flags,
3790 session->is_nonblocking);
Dave Wallace35830af2017-10-09 01:43:42 -04003791 }
3792 else
3793 rv = VPPCOM_EINVAL;
3794 break;
3795
3796 case VPPCOM_ATTR_GET_PEER_ADDR:
Steven2199aab2017-10-15 20:18:47 -07003797 if (buffer && buflen && (*buflen >= sizeof (*ep)))
Dave Wallace35830af2017-10-09 01:43:42 -04003798 {
Steven2199aab2017-10-15 20:18:47 -07003799 ep->vrf = session->vrf;
3800 ep->is_ip4 = session->peer_addr.is_ip4;
Stevenac1f96d2017-10-24 16:03:58 -07003801 ep->port = session->peer_port;
Steven2199aab2017-10-15 20:18:47 -07003802 if (session->peer_addr.is_ip4)
3803 clib_memcpy (ep->ip, &session->peer_addr.ip46.ip4,
3804 sizeof (ip4_address_t));
3805 else
3806 clib_memcpy (ep->ip, &session->peer_addr.ip46.ip6,
3807 sizeof (ip6_address_t));
3808 *buflen = sizeof (*ep);
Dave Wallacefaf9d772017-10-26 16:12:04 -04003809 if (VPPCOM_DEBUG > 1)
Dave Wallace227867f2017-11-13 21:21:53 -05003810 clib_warning ("[%d] VPPCOM_ATTR_GET_PEER_ADDR: sid %u, is_ip4 = "
Dave Wallace2e005bb2017-11-07 01:21:39 -05003811 "%u, addr = %U, port %u", getpid (),
Dave Wallace774169b2017-11-01 20:07:40 -04003812 session_index, ep->is_ip4, format_ip46_address,
Stevenac1f96d2017-10-24 16:03:58 -07003813 &session->peer_addr.ip46, ep->is_ip4,
3814 clib_net_to_host_u16 (ep->port));
Dave Wallace35830af2017-10-09 01:43:42 -04003815 }
3816 else
3817 rv = VPPCOM_EINVAL;
3818 break;
3819
3820 case VPPCOM_ATTR_GET_LCL_ADDR:
Steven2199aab2017-10-15 20:18:47 -07003821 if (buffer && buflen && (*buflen >= sizeof (*ep)))
Dave Wallace35830af2017-10-09 01:43:42 -04003822 {
Steven2199aab2017-10-15 20:18:47 -07003823 ep->vrf = session->vrf;
3824 ep->is_ip4 = session->lcl_addr.is_ip4;
Stevenac1f96d2017-10-24 16:03:58 -07003825 ep->port = session->lcl_port;
Steven2199aab2017-10-15 20:18:47 -07003826 if (session->lcl_addr.is_ip4)
3827 clib_memcpy (ep->ip, &session->lcl_addr.ip46.ip4,
3828 sizeof (ip4_address_t));
3829 else
3830 clib_memcpy (ep->ip, &session->lcl_addr.ip46.ip6,
3831 sizeof (ip6_address_t));
3832 *buflen = sizeof (*ep);
Dave Wallacefaf9d772017-10-26 16:12:04 -04003833 if (VPPCOM_DEBUG > 1)
Dave Wallace227867f2017-11-13 21:21:53 -05003834 clib_warning ("[%d] VPPCOM_ATTR_GET_LCL_ADDR: sid %u, is_ip4 = "
Dave Wallace2e005bb2017-11-07 01:21:39 -05003835 "%u, addr = %U port %d", getpid (),
Dave Wallace774169b2017-11-01 20:07:40 -04003836 session_index, ep->is_ip4, format_ip46_address,
Stevenac1f96d2017-10-24 16:03:58 -07003837 &session->lcl_addr.ip46, ep->is_ip4,
3838 clib_net_to_host_u16 (ep->port));
Dave Wallace35830af2017-10-09 01:43:42 -04003839 }
3840 else
3841 rv = VPPCOM_EINVAL;
3842 break;
Stevenb5a11602017-10-11 09:59:30 -07003843
3844 case VPPCOM_ATTR_SET_REUSEADDR:
3845 break;
3846
3847 case VPPCOM_ATTR_SET_BROADCAST:
3848 break;
3849
3850 case VPPCOM_ATTR_SET_V6ONLY:
3851 break;
Stevenbccd3392017-10-12 20:42:21 -07003852
3853 case VPPCOM_ATTR_SET_KEEPALIVE:
3854 break;
3855
3856 case VPPCOM_ATTR_SET_TCP_KEEPIDLE:
3857 break;
3858
3859 case VPPCOM_ATTR_SET_TCP_KEEPINTVL:
3860 break;
Dave Wallacee22aa742017-10-20 12:30:38 -04003861
3862 default:
3863 rv = VPPCOM_EINVAL;
3864 break;
Dave Wallace35830af2017-10-09 01:43:42 -04003865 }
3866
3867done:
3868 clib_spinlock_unlock (&vcm->sessions_lockp);
3869 return rv;
3870}
3871
Stevenac1f96d2017-10-24 16:03:58 -07003872int
3873vppcom_session_recvfrom (uint32_t session_index, void *buffer,
3874 uint32_t buflen, int flags, vppcom_endpt_t * ep)
3875{
Stevenac1f96d2017-10-24 16:03:58 -07003876 int rv = VPPCOM_OK;
3877 session_t *session = 0;
3878
3879 if (ep)
3880 {
3881 clib_spinlock_lock (&vcm->sessions_lockp);
3882 rv = vppcom_session_at_index (session_index, &session);
3883 if (PREDICT_FALSE (rv))
3884 {
3885 clib_spinlock_unlock (&vcm->sessions_lockp);
3886 if (VPPCOM_DEBUG > 0)
3887 clib_warning ("[%d] invalid session, sid (%u) has been closed!",
Dave Wallace2e005bb2017-11-07 01:21:39 -05003888 getpid (), session_index);
Dave Wallacefaf9d772017-10-26 16:12:04 -04003889 rv = VPPCOM_EBADFD;
3890 clib_spinlock_unlock (&vcm->sessions_lockp);
3891 goto done;
Stevenac1f96d2017-10-24 16:03:58 -07003892 }
3893 ep->vrf = session->vrf;
3894 ep->is_ip4 = session->peer_addr.is_ip4;
3895 ep->port = session->peer_port;
3896 if (session->peer_addr.is_ip4)
3897 clib_memcpy (ep->ip, &session->peer_addr.ip46.ip4,
3898 sizeof (ip4_address_t));
3899 else
3900 clib_memcpy (ep->ip, &session->peer_addr.ip46.ip6,
3901 sizeof (ip6_address_t));
3902 clib_spinlock_unlock (&vcm->sessions_lockp);
Stevenac1f96d2017-10-24 16:03:58 -07003903 }
Steven58f464e2017-10-25 12:33:12 -07003904
3905 if (flags == 0)
Stevenac1f96d2017-10-24 16:03:58 -07003906 rv = vppcom_session_read (session_index, buffer, buflen);
3907 else if (flags & MSG_PEEK)
Steven58f464e2017-10-25 12:33:12 -07003908 rv = vppcom_session_peek (session_index, buffer, buflen);
Stevenac1f96d2017-10-24 16:03:58 -07003909 else
3910 {
Dave Wallace2e005bb2017-11-07 01:21:39 -05003911 clib_warning ("[%d] Unsupport flags for recvfrom %d", getpid (), flags);
Stevenac1f96d2017-10-24 16:03:58 -07003912 rv = VPPCOM_EAFNOSUPPORT;
3913 }
3914
Dave Wallacefaf9d772017-10-26 16:12:04 -04003915done:
Stevenac1f96d2017-10-24 16:03:58 -07003916 return rv;
3917}
3918
3919int
3920vppcom_session_sendto (uint32_t session_index, void *buffer,
3921 uint32_t buflen, int flags, vppcom_endpt_t * ep)
3922{
Dave Wallace617dffa2017-10-26 14:47:06 -04003923 if (!buffer)
3924 return VPPCOM_EINVAL;
3925
3926 if (ep)
3927 {
3928 // TBD
3929 return VPPCOM_EINVAL;
3930 }
3931
3932 if (flags)
3933 {
3934 // TBD check the flags and do the right thing
3935 if (VPPCOM_DEBUG > 2)
3936 clib_warning ("[%d] handling flags 0x%u (%d) not implemented yet.",
Dave Wallace2e005bb2017-11-07 01:21:39 -05003937 getpid (), flags, flags);
Dave Wallace617dffa2017-10-26 14:47:06 -04003938 }
3939
3940 return (vppcom_session_write (session_index, buffer, buflen));
Stevenac1f96d2017-10-24 16:03:58 -07003941}
3942
Dave Wallacee22aa742017-10-20 12:30:38 -04003943/*
3944 * fd.io coding-style-patch-verification: ON
3945 *
3946 * Local Variables:
3947 * eval: (c-set-style "gnu")
3948 * End:
3949 */