blob: 05c1dbbb50111bcaa430bdc2d51a96aa2908f465 [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>
Dave Wallace543852a2017-08-03 02:11:34 -040018#include <svm/svm_fifo_segment.h>
Dave Wallace5c7cf1c2017-10-24 04:12:18 -040019#include <vcl/vppcom.h>
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -080020#include <vcl/vcl_event.h>
Florin Coras0d427d82018-06-27 03:24:07 -070021#include <vcl/vcl_debug.h>
Florin Coras697faea2018-06-27 17:10:49 -070022#include <vcl/vcl_private.h>
Dave Wallace7e607a72018-06-18 18:41:32 -040023
Florin Coras54693d22018-07-17 10:46:29 -070024static u8 not_ready;
25
26void
27sigsegv_signal (int signum)
28{
29 not_ready = 1;
30}
31
32static void
33vcl_wait_for_memory (void *mem)
34{
35 u8 __clib_unused test;
Florin Coras460dce62018-07-27 05:45:06 -070036 if (vcm->mounting_segment)
37 {
38 while (vcm->mounting_segment)
39 ;
40 return;
41 }
Florin Coras54693d22018-07-17 10:46:29 -070042 if (1 || vcm->debug)
43 {
Florin Coras460dce62018-07-27 05:45:06 -070044 usleep (1e5);
Florin Coras54693d22018-07-17 10:46:29 -070045 return;
46 }
47 if (signal (SIGSEGV, sigsegv_signal))
48 {
49 perror ("signal()");
50 return;
51 }
52 not_ready = 0;
53
54again:
55 test = *(u8 *) mem;
56 if (not_ready)
57 {
58 not_ready = 0;
59 usleep (1);
60 goto again;
61 }
62
63 signal (SIGSEGV, SIG_DFL);
64}
65
Dave Wallace543852a2017-08-03 02:11:34 -040066static const char *
67vppcom_app_state_str (app_state_t state)
68{
69 char *st;
70
71 switch (state)
72 {
73 case STATE_APP_START:
74 st = "STATE_APP_START";
75 break;
76
77 case STATE_APP_CONN_VPP:
78 st = "STATE_APP_CONN_VPP";
79 break;
80
81 case STATE_APP_ENABLED:
82 st = "STATE_APP_ENABLED";
83 break;
84
85 case STATE_APP_ATTACHED:
86 st = "STATE_APP_ATTACHED";
87 break;
88
89 default:
90 st = "UNKNOWN_APP_STATE";
91 break;
92 }
93
94 return st;
95}
96
Florin Coras697faea2018-06-27 17:10:49 -070097const char *
Dave Wallace543852a2017-08-03 02:11:34 -040098vppcom_session_state_str (session_state_t state)
99{
100 char *st;
101
102 switch (state)
103 {
104 case STATE_START:
105 st = "STATE_START";
106 break;
107
108 case STATE_CONNECT:
109 st = "STATE_CONNECT";
110 break;
111
112 case STATE_LISTEN:
113 st = "STATE_LISTEN";
114 break;
115
116 case STATE_ACCEPT:
117 st = "STATE_ACCEPT";
118 break;
119
Dave Wallace4878cbe2017-11-21 03:45:09 -0500120 case STATE_CLOSE_ON_EMPTY:
121 st = "STATE_CLOSE_ON_EMPTY";
122 break;
123
Dave Wallace543852a2017-08-03 02:11:34 -0400124 case STATE_DISCONNECT:
125 st = "STATE_DISCONNECT";
126 break;
127
128 case STATE_FAILED:
129 st = "STATE_FAILED";
130 break;
131
132 default:
133 st = "UNKNOWN_STATE";
134 break;
135 }
136
137 return st;
138}
139
Dave Wallace543852a2017-08-03 02:11:34 -0400140u8 *
141format_ip4_address (u8 * s, va_list * args)
142{
143 u8 *a = va_arg (*args, u8 *);
144 return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
145}
146
147u8 *
148format_ip6_address (u8 * s, va_list * args)
149{
150 ip6_address_t *a = va_arg (*args, ip6_address_t *);
151 u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
152
153 i_max_n_zero = ARRAY_LEN (a->as_u16);
154 max_n_zeros = 0;
155 i_first_zero = i_max_n_zero;
156 n_zeros = 0;
157 for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
158 {
159 u32 is_zero = a->as_u16[i] == 0;
160 if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
161 {
162 i_first_zero = i;
163 n_zeros = 0;
164 }
165 n_zeros += is_zero;
166 if ((!is_zero && n_zeros > max_n_zeros)
167 || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
168 {
169 i_max_n_zero = i_first_zero;
170 max_n_zeros = n_zeros;
171 i_first_zero = ARRAY_LEN (a->as_u16);
172 n_zeros = 0;
173 }
174 }
175
176 last_double_colon = 0;
177 for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
178 {
179 if (i == i_max_n_zero && max_n_zeros > 1)
180 {
181 s = format (s, "::");
182 i += max_n_zeros - 1;
183 last_double_colon = 1;
184 }
185 else
186 {
187 s = format (s, "%s%x",
188 (last_double_colon || i == 0) ? "" : ":",
189 clib_net_to_host_u16 (a->as_u16[i]));
190 last_double_colon = 0;
191 }
192 }
193
194 return s;
195}
196
197/* Format an IP46 address. */
198u8 *
199format_ip46_address (u8 * s, va_list * args)
200{
201 ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
202 ip46_type_t type = va_arg (*args, ip46_type_t);
203 int is_ip4 = 1;
204
205 switch (type)
206 {
207 case IP46_TYPE_ANY:
208 is_ip4 = ip46_address_is_ip4 (ip46);
209 break;
210 case IP46_TYPE_IP4:
211 is_ip4 = 1;
212 break;
213 case IP46_TYPE_IP6:
214 is_ip4 = 0;
215 break;
216 }
217
218 return is_ip4 ?
219 format (s, "%U", format_ip4_address, &ip46->ip4) :
220 format (s, "%U", format_ip6_address, &ip46->ip6);
221}
222
Florin Coras697faea2018-06-27 17:10:49 -0700223/*
224 * VPPCOM Utility Functions
225 */
226
227static inline void
228vppcom_session_table_del_listener (u64 listener_handle)
Dave Wallace543852a2017-08-03 02:11:34 -0400229{
Florin Coras697faea2018-06-27 17:10:49 -0700230 listener_handle |= 1ULL << 63;
231 hash_unset (vcm->session_index_by_vpp_handles, listener_handle);
232}
233
234static inline int
235vppcom_wait_for_app_state_change (app_state_t app_state)
236{
237 f64 timeout = clib_time_now (&vcm->clib_time) + vcm->cfg.app_timeout;
238
239 while (clib_time_now (&vcm->clib_time) < timeout)
240 {
241 if (vcm->app_state == app_state)
242 return VPPCOM_OK;
243 }
244 VDBG (0, "VCL<%d>: timeout waiting for state %s (%d)", getpid (),
245 vppcom_app_state_str (app_state), app_state);
246 vcl_evt (VCL_EVT_SESSION_TIMEOUT, vcm, app_state);
247
248 return VPPCOM_ETIMEDOUT;
249}
250
Florin Corasc9fbd662018-08-24 12:59:56 -0700251static svm_msg_q_t *
252vcl_session_vpp_evt_q (vcl_session_t * s)
253{
254 if (vcl_session_is_ct (s))
255 return vcm->vpp_event_queues[0];
256 else
257 return vcm->vpp_event_queues[s->tx_fifo->master_thread_index];
258}
259
Florin Coras54693d22018-07-17 10:46:29 -0700260static void
261vcl_send_session_accepted_reply (svm_msg_q_t * mq, u32 context,
262 session_handle_t handle, int retval)
263{
264 app_session_evt_t _app_evt, *app_evt = &_app_evt;
265 session_accepted_reply_msg_t *rmp;
266 app_alloc_ctrl_evt_to_vpp (mq, app_evt, SESSION_CTRL_EVT_ACCEPTED_REPLY);
267 rmp = (session_accepted_reply_msg_t *) app_evt->evt->data;
268 rmp->handle = handle;
269 rmp->context = context;
270 rmp->retval = retval;
271 app_send_ctrl_evt_to_vpp (mq, app_evt);
272}
273
Florin Coras99368312018-08-02 10:45:44 -0700274static void
275vcl_send_session_disconnected_reply (svm_msg_q_t * mq, u32 context,
276 session_handle_t handle, int retval)
277{
278 app_session_evt_t _app_evt, *app_evt = &_app_evt;
279 session_disconnected_reply_msg_t *rmp;
280 app_alloc_ctrl_evt_to_vpp (mq, app_evt,
281 SESSION_CTRL_EVT_DISCONNECTED_REPLY);
282 rmp = (session_disconnected_reply_msg_t *) app_evt->evt->data;
283 rmp->handle = handle;
284 rmp->context = context;
285 rmp->retval = retval;
286 app_send_ctrl_evt_to_vpp (mq, app_evt);
287}
288
Florin Corasc9fbd662018-08-24 12:59:56 -0700289static void
290vcl_send_session_reset_reply (svm_msg_q_t * mq, u32 context,
291 session_handle_t handle, int retval)
292{
293 app_session_evt_t _app_evt, *app_evt = &_app_evt;
294 session_reset_reply_msg_t *rmp;
295 app_alloc_ctrl_evt_to_vpp (mq, app_evt, SESSION_CTRL_EVT_RESET_REPLY);
296 rmp = (session_reset_reply_msg_t *) app_evt->evt->data;
297 rmp->handle = handle;
298 rmp->context = context;
299 rmp->retval = retval;
300 app_send_ctrl_evt_to_vpp (mq, app_evt);
301}
302
Florin Coras54693d22018-07-17 10:46:29 -0700303static u32
304vcl_session_accepted_handler (session_accepted_msg_t * mp)
305{
306 vcl_session_t *session, *listen_session;
307 svm_fifo_t *rx_fifo, *tx_fifo;
Florin Coras99368312018-08-02 10:45:44 -0700308 u32 session_index, vpp_wrk_index;
309 svm_msg_q_t *evt_q;
Florin Coras54693d22018-07-17 10:46:29 -0700310
311 VCL_SESSION_LOCK ();
312
Florin Coras99368312018-08-02 10:45:44 -0700313 session = vcl_session_alloc ();
314 session_index = vcl_session_index (session);
315
Florin Coras54693d22018-07-17 10:46:29 -0700316 listen_session = vppcom_session_table_lookup_listener (mp->listener_handle);
317 if (!listen_session)
318 {
319 svm_msg_q_t *evt_q;
320 evt_q = uword_to_pointer (mp->vpp_event_queue_address, svm_msg_q_t *);
321 clib_warning ("VCL<%d>: ERROR: couldn't find listen session: "
322 "unknown vpp listener handle %llx",
323 getpid (), mp->listener_handle);
324 vcl_send_session_accepted_reply (evt_q, mp->context, mp->handle,
325 VNET_API_ERROR_INVALID_ARGUMENT);
Florin Coras99368312018-08-02 10:45:44 -0700326 vcl_session_free (session);
327 VCL_SESSION_UNLOCK ();
Florin Coras54693d22018-07-17 10:46:29 -0700328 return VCL_INVALID_SESSION_INDEX;
329 }
330
Florin Coras54693d22018-07-17 10:46:29 -0700331 rx_fifo = uword_to_pointer (mp->server_rx_fifo, svm_fifo_t *);
332 tx_fifo = uword_to_pointer (mp->server_tx_fifo, svm_fifo_t *);
333
334 if (mp->server_event_queue_address)
335 {
336 session->vpp_evt_q = uword_to_pointer (mp->client_event_queue_address,
337 svm_msg_q_t *);
338 session->our_evt_q = uword_to_pointer (mp->server_event_queue_address,
339 svm_msg_q_t *);
340 vcl_wait_for_memory (session->vpp_evt_q);
Florin Coras54693d22018-07-17 10:46:29 -0700341 rx_fifo->master_session_index = session_index;
342 tx_fifo->master_session_index = session_index;
Florin Coras99368312018-08-02 10:45:44 -0700343 vec_validate (vcm->vpp_event_queues, 0);
344 evt_q = uword_to_pointer (mp->vpp_event_queue_address, svm_msg_q_t *);
345 vcm->vpp_event_queues[0] = evt_q;
Florin Coras54693d22018-07-17 10:46:29 -0700346 }
347 else
348 {
349 session->vpp_evt_q = uword_to_pointer (mp->vpp_event_queue_address,
350 svm_msg_q_t *);
351 rx_fifo->client_session_index = session_index;
352 tx_fifo->client_session_index = session_index;
Florin Coras99368312018-08-02 10:45:44 -0700353
354 vpp_wrk_index = tx_fifo->master_thread_index;
355 vec_validate (vcm->vpp_event_queues, vpp_wrk_index);
356 vcm->vpp_event_queues[vpp_wrk_index] = session->vpp_evt_q;
Florin Coras54693d22018-07-17 10:46:29 -0700357 }
358
359 session->vpp_handle = mp->handle;
360 session->client_context = mp->context;
361 session->rx_fifo = rx_fifo;
362 session->tx_fifo = tx_fifo;
363
364 session->session_state = STATE_ACCEPT;
365 session->transport.rmt_port = mp->port;
366 session->transport.is_ip4 = mp->is_ip4;
367 clib_memcpy (&session->transport.rmt_ip, mp->ip, sizeof (ip46_address_t));
368
369 hash_set (vcm->session_index_by_vpp_handles, mp->handle, session_index);
370 session->transport.lcl_port = listen_session->transport.lcl_port;
371 session->transport.lcl_ip = listen_session->transport.lcl_ip;
Florin Coras460dce62018-07-27 05:45:06 -0700372 session->session_type = listen_session->session_type;
373 session->is_dgram = session->session_type == VPPCOM_PROTO_UDP;
Florin Coras54693d22018-07-17 10:46:29 -0700374
375 VDBG (1, "VCL<%d>: vpp handle 0x%llx, sid %u: client accept request from %s"
376 " address %U port %d queue %p!", getpid (), mp->handle, session_index,
377 mp->is_ip4 ? "IPv4" : "IPv6", format_ip46_address, &mp->ip,
378 mp->is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6,
379 clib_net_to_host_u16 (mp->port), session->vpp_evt_q);
380 vcl_evt (VCL_EVT_ACCEPT, session, listen_session, session_index);
381
382 VCL_SESSION_UNLOCK ();
383 return session_index;
384}
385
386static u32
387vcl_session_connected_handler (session_connected_msg_t * mp)
388{
Florin Coras99368312018-08-02 10:45:44 -0700389 u32 session_index, vpp_wrk_index;
Florin Coras54693d22018-07-17 10:46:29 -0700390 svm_fifo_t *rx_fifo, *tx_fifo;
Florin Coras99368312018-08-02 10:45:44 -0700391 vcl_session_t *session = 0;
392 svm_msg_q_t *evt_q;
Florin Coras54693d22018-07-17 10:46:29 -0700393 int rv = VPPCOM_OK;
394
395 session_index = mp->context;
396 VCL_SESSION_LOCK_AND_GET (session_index, &session);
397done:
398 if (mp->retval)
399 {
400 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
401 "connect failed! %U",
402 getpid (), mp->handle, session_index,
403 format_api_error, ntohl (mp->retval));
404 if (session)
405 {
406 session->session_state = STATE_FAILED;
407 session->vpp_handle = mp->handle;
408 }
409 else
410 {
411 clib_warning ("[%s] ERROR: vpp handle 0x%llx, sid %u: "
412 "Invalid session index (%u)!",
413 getpid (), mp->handle, session_index);
414 }
415 goto done_unlock;
416 }
417
418 if (rv)
419 goto done_unlock;
420
Florin Coras460dce62018-07-27 05:45:06 -0700421 rx_fifo = uword_to_pointer (mp->server_rx_fifo, svm_fifo_t *);
422 tx_fifo = uword_to_pointer (mp->server_tx_fifo, svm_fifo_t *);
423 vcl_wait_for_memory (rx_fifo);
424 rx_fifo->client_session_index = session_index;
425 tx_fifo->client_session_index = session_index;
426
Florin Coras54693d22018-07-17 10:46:29 -0700427 if (mp->client_event_queue_address)
428 {
429 session->vpp_evt_q = uword_to_pointer (mp->server_event_queue_address,
430 svm_msg_q_t *);
431 session->our_evt_q = uword_to_pointer (mp->client_event_queue_address,
432 svm_msg_q_t *);
Florin Coras99368312018-08-02 10:45:44 -0700433
434 vec_validate (vcm->vpp_event_queues, 0);
435 evt_q = uword_to_pointer (mp->vpp_event_queue_address, svm_msg_q_t *);
436 vcm->vpp_event_queues[0] = evt_q;
Florin Coras54693d22018-07-17 10:46:29 -0700437 }
438 else
Florin Coras99368312018-08-02 10:45:44 -0700439 {
440 session->vpp_evt_q = uword_to_pointer (mp->vpp_event_queue_address,
441 svm_msg_q_t *);
442 vpp_wrk_index = tx_fifo->master_thread_index;
443 vec_validate (vcm->vpp_event_queues, vpp_wrk_index);
444 vcm->vpp_event_queues[vpp_wrk_index] = session->vpp_evt_q;
445 }
Florin Coras54693d22018-07-17 10:46:29 -0700446
Florin Coras54693d22018-07-17 10:46:29 -0700447 session->rx_fifo = rx_fifo;
448 session->tx_fifo = tx_fifo;
449 session->vpp_handle = mp->handle;
450 session->transport.is_ip4 = mp->is_ip4;
451 clib_memcpy (&session->transport.lcl_ip, mp->lcl_ip,
452 sizeof (session->transport.lcl_ip));
453 session->transport.lcl_port = mp->lcl_port;
454 session->session_state = STATE_CONNECT;
455
456 /* Add it to lookup table */
457 hash_set (vcm->session_index_by_vpp_handles, mp->handle, session_index);
458
459 VDBG (1, "VCL<%d>: vpp handle 0x%llx, sid %u: connect succeeded! "
460 "session_rx_fifo %p, refcnt %d, session_tx_fifo %p, refcnt %d",
461 getpid (), mp->handle, session_index, session->rx_fifo,
462 session->rx_fifo->refcnt, session->tx_fifo, session->tx_fifo->refcnt);
463done_unlock:
464 VCL_SESSION_UNLOCK ();
465 return session_index;
466}
467
Florin Corasc9fbd662018-08-24 12:59:56 -0700468static u32
Florin Coras60116992018-08-27 09:52:18 -0700469vcl_session_reset_handler (session_reset_msg_t * reset_msg)
Florin Corasc9fbd662018-08-24 12:59:56 -0700470{
471 vcl_session_t *session;
472 u32 sid;
473
474 sid = vcl_session_get_index_from_handle (reset_msg->handle);
475 session = vcl_session_get (sid);
476 if (!session)
477 {
478 VDBG (0, "request to reset unknown handle 0x%llx", reset_msg->handle);
479 return VCL_INVALID_SESSION_INDEX;
480 }
481 session->session_state = STATE_CLOSE_ON_EMPTY;
482 VDBG (0, "reset handle 0x%llx, sid %u ", reset_msg->handle, sid);
483 vcl_send_session_reset_reply (vcl_session_vpp_evt_q (session),
484 vcm->my_client_index, reset_msg->handle, 0);
485 return sid;
486}
487
Florin Coras60116992018-08-27 09:52:18 -0700488static u32
489vcl_session_bound_handler (session_bound_msg_t * mp)
490{
491 vcl_session_t *session;
492 u32 sid = mp->context;
493
494 session = vcl_session_get (sid);
495 if (mp->retval)
496 {
497 VDBG (0, "VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: bind failed: %U",
498 getpid (), mp->handle, sid, format_api_error, ntohl (mp->retval));
499 if (session)
500 {
501 session->session_state = STATE_FAILED;
502 session->vpp_handle = mp->handle;
503 return sid;
504 }
505 else
506 {
507 clib_warning ("[%s] ERROR: vpp handle 0x%llx, sid %u: "
508 "Invalid session index (%u)!",
509 getpid (), mp->handle, sid);
510 return VCL_INVALID_SESSION_INDEX;
511 }
512 }
513
514 session->vpp_handle = mp->handle;
515 session->transport.is_ip4 = mp->lcl_is_ip4;
516 clib_memcpy (&session->transport.lcl_ip, mp->lcl_ip,
517 sizeof (ip46_address_t));
518 session->transport.lcl_port = mp->lcl_port;
519 vppcom_session_table_add_listener (mp->handle, sid);
520 session->session_state = STATE_LISTEN;
521
522 if (session->is_dgram)
523 {
524 svm_fifo_t *rx_fifo, *tx_fifo;
525 session->vpp_evt_q = uword_to_pointer (mp->vpp_evt_q, svm_msg_q_t *);
526 rx_fifo = uword_to_pointer (mp->rx_fifo, svm_fifo_t *);
527 rx_fifo->client_session_index = sid;
528 tx_fifo = uword_to_pointer (mp->tx_fifo, svm_fifo_t *);
529 tx_fifo->client_session_index = sid;
530 session->rx_fifo = rx_fifo;
531 session->tx_fifo = tx_fifo;
532 }
533
534 VDBG (1, "VCL<%d>: vpp handle 0x%llx, sid %u: bind succeeded!",
535 getpid (), mp->handle, sid);
536 return sid;
537}
538
Florin Coras54693d22018-07-17 10:46:29 -0700539int
540vcl_handle_mq_ctrl_event (session_event_t * e)
541{
542 session_accepted_msg_t *accepted_msg;
543 session_disconnected_msg_t *disconnected_msg;
544 vcl_session_msg_t *vcl_msg;
545 vcl_session_t *session;
546 u64 handle;
547 u32 sid;
548
549 switch (e->event_type)
550 {
551 case FIFO_EVENT_APP_RX:
552 clib_warning ("unhandled rx: sid %u (0x%x)",
553 e->fifo->client_session_index,
554 e->fifo->client_session_index);
555 break;
556 case SESSION_CTRL_EVT_ACCEPTED:
557 accepted_msg = (session_accepted_msg_t *) e->data;
558 handle = accepted_msg->listener_handle;
559 session = vppcom_session_table_lookup_listener (handle);
560 if (!session)
561 {
562 clib_warning ("VCL<%d>: ERROR: couldn't find listen session:"
563 "listener handle %llx", getpid (), handle);
564 break;
565 }
566
567 clib_fifo_add2 (session->accept_evts_fifo, vcl_msg);
568 vcl_msg->accepted_msg = *accepted_msg;
569 break;
570 case SESSION_CTRL_EVT_CONNECTED:
571 vcl_session_connected_handler ((session_connected_msg_t *) e->data);
572 break;
573 case SESSION_CTRL_EVT_DISCONNECTED:
574 disconnected_msg = (session_disconnected_msg_t *) e->data;
575 sid = vcl_session_get_index_from_handle (disconnected_msg->handle);
576 session = vcl_session_get (sid);
Florin Corasc9fbd662018-08-24 12:59:56 -0700577 if (!session)
578 {
579 VDBG (0, "request to disconnect unknown handle 0x%llx",
580 disconnected_msg->handle);
581 break;
582 }
Florin Coras54693d22018-07-17 10:46:29 -0700583 session->session_state = STATE_DISCONNECT;
Florin Corasc9fbd662018-08-24 12:59:56 -0700584 VDBG (0, "disconnected handle 0xllx, sid %u", disconnected_msg->handle,
585 sid);
586 break;
587 case SESSION_CTRL_EVT_RESET:
Florin Coras60116992018-08-27 09:52:18 -0700588 vcl_session_reset_handler ((session_reset_msg_t *) e->data);
589 break;
590 case SESSION_CTRL_EVT_BOUND:
591 vcl_session_bound_handler ((session_bound_msg_t *) e->data);
Florin Coras54693d22018-07-17 10:46:29 -0700592 break;
593 default:
594 clib_warning ("unhandled %u", e->event_type);
595 }
596 return VPPCOM_OK;
597}
598
Florin Coras697faea2018-06-27 17:10:49 -0700599static inline int
600vppcom_wait_for_session_state_change (u32 session_index,
601 session_state_t state,
602 f64 wait_for_time)
603{
604 f64 timeout = clib_time_now (&vcm->clib_time) + wait_for_time;
605 vcl_session_t *volatile session;
Florin Coras54693d22018-07-17 10:46:29 -0700606 svm_msg_q_msg_t msg;
607 session_event_t *e;
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800608 int rv;
Dave Wallace543852a2017-08-03 02:11:34 -0400609
Florin Coras697faea2018-06-27 17:10:49 -0700610 do
Dave Wallace543852a2017-08-03 02:11:34 -0400611 {
Florin Coras697faea2018-06-27 17:10:49 -0700612 VCL_SESSION_LOCK ();
613 rv = vppcom_session_at_index (session_index, &session);
614 if (PREDICT_FALSE (rv))
615 {
616 VCL_SESSION_UNLOCK ();
617 return rv;
618 }
619 if (session->session_state & state)
620 {
621 VCL_SESSION_UNLOCK ();
622 return VPPCOM_OK;
623 }
624 if (session->session_state & STATE_FAILED)
625 {
626 VCL_SESSION_UNLOCK ();
627 return VPPCOM_ECONNREFUSED;
628 }
Dave Wallace7e607a72018-06-18 18:41:32 -0400629 VCL_SESSION_UNLOCK ();
Florin Coras54693d22018-07-17 10:46:29 -0700630
631 if (svm_msg_q_sub (vcm->app_event_queue, &msg, SVM_Q_NOWAIT, 0))
632 continue;
633 e = svm_msg_q_msg_data (vcm->app_event_queue, &msg);
634 vcl_handle_mq_ctrl_event (e);
635 svm_msg_q_free_msg (vcm->app_event_queue, &msg);
Florin Corasdcf55ce2017-11-16 15:32:50 -0800636 }
Florin Coras697faea2018-06-27 17:10:49 -0700637 while (clib_time_now (&vcm->clib_time) < timeout);
Florin Corasdcf55ce2017-11-16 15:32:50 -0800638
Florin Coras697faea2018-06-27 17:10:49 -0700639 VDBG (0, "VCL<%d>: timeout waiting for state 0x%x (%s)", getpid (), state,
640 vppcom_session_state_str (state));
641 vcl_evt (VCL_EVT_SESSION_TIMEOUT, session, session_state);
Dave Wallace543852a2017-08-03 02:11:34 -0400642
Florin Coras697faea2018-06-27 17:10:49 -0700643 return VPPCOM_ETIMEDOUT;
Dave Wallace60caa062017-11-10 17:07:13 -0500644}
645
Florin Coras697faea2018-06-27 17:10:49 -0700646static int
647vppcom_app_session_enable (void)
Dave Wallace543852a2017-08-03 02:11:34 -0400648{
Florin Coras697faea2018-06-27 17:10:49 -0700649 int rv;
Dave Wallace543852a2017-08-03 02:11:34 -0400650
Florin Coras697faea2018-06-27 17:10:49 -0700651 if (vcm->app_state != STATE_APP_ENABLED)
652 {
653 vppcom_send_session_enable_disable (1 /* is_enabled == TRUE */ );
654 rv = vppcom_wait_for_app_state_change (STATE_APP_ENABLED);
655 if (PREDICT_FALSE (rv))
656 {
657 VDBG (0, "VCL<%d>: application session enable timed out! "
658 "returning %d (%s)", getpid (), rv, vppcom_retval_str (rv));
659 return rv;
660 }
661 }
662 return VPPCOM_OK;
Dave Wallace543852a2017-08-03 02:11:34 -0400663}
664
Florin Coras697faea2018-06-27 17:10:49 -0700665static int
666vppcom_app_attach (void)
Dave Wallace543852a2017-08-03 02:11:34 -0400667{
Florin Coras697faea2018-06-27 17:10:49 -0700668 int rv;
Dave Wallace543852a2017-08-03 02:11:34 -0400669
Florin Coras697faea2018-06-27 17:10:49 -0700670 vppcom_app_send_attach ();
671 rv = vppcom_wait_for_app_state_change (STATE_APP_ATTACHED);
672 if (PREDICT_FALSE (rv))
673 {
674 VDBG (0, "VCL<%d>: application attach timed out! returning %d (%s)",
675 getpid (), rv, vppcom_retval_str (rv));
676 return rv;
677 }
Dave Wallace543852a2017-08-03 02:11:34 -0400678
Florin Coras697faea2018-06-27 17:10:49 -0700679 return VPPCOM_OK;
Dave Wallace543852a2017-08-03 02:11:34 -0400680}
681
682static int
Dave Wallace543852a2017-08-03 02:11:34 -0400683vppcom_session_unbind (u32 session_index)
684{
Florin Coras7e12d942018-06-27 14:32:43 -0700685 vcl_session_t *session = 0;
Dave Wallace543852a2017-08-03 02:11:34 -0400686 int rv;
Dave Wallace4878cbe2017-11-21 03:45:09 -0500687 u64 vpp_handle;
Dave Wallace543852a2017-08-03 02:11:34 -0400688
Dave Wallace7e607a72018-06-18 18:41:32 -0400689 VCL_SESSION_LOCK_AND_GET (session_index, &session);
Dave Wallace4878cbe2017-11-21 03:45:09 -0500690
691 vpp_handle = session->vpp_handle;
692 vppcom_session_table_del_listener (vpp_handle);
693 session->vpp_handle = ~0;
Florin Coras7e12d942018-06-27 14:32:43 -0700694 session->session_state = STATE_DISCONNECT;
Dave Wallace4878cbe2017-11-21 03:45:09 -0500695
Dave Wallace7e607a72018-06-18 18:41:32 -0400696 VCL_SESSION_UNLOCK ();
Dave Wallace543852a2017-08-03 02:11:34 -0400697
Florin Coras0d427d82018-06-27 03:24:07 -0700698 VDBG (1, "VCL<%d>: vpp handle 0x%llx, sid %u: sending unbind msg! new state"
699 " 0x%x (%s)", getpid (), vpp_handle, session_index, STATE_DISCONNECT,
700 vppcom_session_state_str (STATE_DISCONNECT));
701 vcl_evt (VCL_EVT_UNBIND, session);
Dave Wallace4878cbe2017-11-21 03:45:09 -0500702 vppcom_send_unbind_sock (vpp_handle);
703
704done:
705 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -0400706}
707
Florin Coras697faea2018-06-27 17:10:49 -0700708static int
Dave Wallace543852a2017-08-03 02:11:34 -0400709vppcom_session_disconnect (u32 session_index)
710{
Florin Coras99368312018-08-02 10:45:44 -0700711 svm_msg_q_t *vpp_evt_q;
Florin Coras7e12d942018-06-27 14:32:43 -0700712 vcl_session_t *session;
Dave Wallace4878cbe2017-11-21 03:45:09 -0500713 session_state_t state;
Florin Coras99368312018-08-02 10:45:44 -0700714 u64 vpp_handle;
715 int rv;
Dave Wallace543852a2017-08-03 02:11:34 -0400716
Dave Wallace7e607a72018-06-18 18:41:32 -0400717 VCL_SESSION_LOCK_AND_GET (session_index, &session);
Dave Wallace4878cbe2017-11-21 03:45:09 -0500718
719 vpp_handle = session->vpp_handle;
Florin Coras7e12d942018-06-27 14:32:43 -0700720 state = session->session_state;
Dave Wallace7e607a72018-06-18 18:41:32 -0400721 VCL_SESSION_UNLOCK ();
Dave Wallace4878cbe2017-11-21 03:45:09 -0500722
Florin Coras0d427d82018-06-27 03:24:07 -0700723 VDBG (1, "VCL<%d>: vpp handle 0x%llx, sid %u state 0x%x (%s)", getpid (),
724 vpp_handle, session_index, state, vppcom_session_state_str (state));
Dave Wallace66cf6eb2017-10-26 02:51:07 -0400725
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -0800726 if (PREDICT_FALSE (state & STATE_LISTEN))
Dave Wallace66cf6eb2017-10-26 02:51:07 -0400727 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500728 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -0500729 "Cannot disconnect a listen socket!",
730 getpid (), vpp_handle, session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -0500731 rv = VPPCOM_EBADFD;
732 goto done;
733 }
Dave Wallace66cf6eb2017-10-26 02:51:07 -0400734
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -0800735 if (state & STATE_CLOSE_ON_EMPTY)
Dave Wallace4878cbe2017-11-21 03:45:09 -0500736 {
Florin Coras99368312018-08-02 10:45:44 -0700737 vpp_evt_q = vcl_session_vpp_evt_q (session);
738 vcl_send_session_disconnected_reply (vpp_evt_q, vcm->my_client_index,
739 vpp_handle, 0);
Florin Coras0d427d82018-06-27 03:24:07 -0700740 VDBG (1, "VCL<%d>: vpp handle 0x%llx, sid %u: sending disconnect "
741 "REPLY...", getpid (), vpp_handle, session_index);
Dave Wallace66cf6eb2017-10-26 02:51:07 -0400742 }
743 else
Dave Wallace227867f2017-11-13 21:21:53 -0500744 {
Florin Coras0d427d82018-06-27 03:24:07 -0700745 VDBG (1, "VCL<%d>: vpp handle 0x%llx, sid %u: sending disconnect...",
746 getpid (), vpp_handle, session_index);
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -0800747 vppcom_send_disconnect_session (vpp_handle, session_index);
Dave Wallace227867f2017-11-13 21:21:53 -0500748 }
Dave Wallace66cf6eb2017-10-26 02:51:07 -0400749
Dave Wallace4878cbe2017-11-21 03:45:09 -0500750done:
751 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -0400752}
753
Dave Wallace543852a2017-08-03 02:11:34 -0400754/*
755 * VPPCOM Public API functions
756 */
757int
758vppcom_app_create (char *app_name)
759{
Dave Wallace543852a2017-08-03 02:11:34 -0400760 vppcom_cfg_t *vcl_cfg = &vcm->cfg;
Dave Wallace543852a2017-08-03 02:11:34 -0400761 int rv;
762
763 if (!vcm->init)
764 {
Dave Wallace543852a2017-08-03 02:11:34 -0400765 vcm->init = 1;
Dave Barach6a5adc32018-07-04 10:56:23 -0400766 vppcom_cfg (&vcm->cfg);
Florin Coras99368312018-08-02 10:45:44 -0700767 vcl_cfg = &vcm->cfg;
768
769 vcm->mqs_epfd = -1;
770 if (vcl_cfg->use_mq_eventfd)
771 vcm->mqs_epfd = epoll_create (1);
Dave Barach6a5adc32018-07-04 10:56:23 -0400772
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -0800773 clib_spinlock_init (&vcm->session_fifo_lockp);
Dave Wallace2e005bb2017-11-07 01:21:39 -0500774 clib_fifo_validate (vcm->client_session_index_fifo,
775 vcm->cfg.listen_queue_size);
Florin Coras697faea2018-06-27 17:10:49 -0700776 clib_spinlock_init (&vcm->sessions_lockp);
Dave Wallaceb5a86ee2018-02-16 18:26:11 -0500777
Dave Wallace8af20542017-10-26 03:29:30 -0400778
Dave Wallace543852a2017-08-03 02:11:34 -0400779 vcm->main_cpu = os_get_thread_index ();
Dave Wallace543852a2017-08-03 02:11:34 -0400780
781 vcm->session_index_by_vpp_handles = hash_create (0, sizeof (uword));
Florin Coras99368312018-08-02 10:45:44 -0700782 vcm->ct_registration_by_mq = hash_create (0, sizeof (uword));
783 clib_spinlock_init (&vcm->ct_registration_lock);
Dave Wallace543852a2017-08-03 02:11:34 -0400784
785 clib_time_init (&vcm->clib_time);
786 vppcom_init_error_string_table ();
Florin Corasa332c462018-01-31 06:52:17 -0800787 svm_fifo_segment_main_init (vcl_cfg->segment_baseva,
788 20 /* timeout in secs */ );
Florin Coras99368312018-08-02 10:45:44 -0700789 vec_validate (vcm->mq_events, 64);
790 vec_validate (vcm->mq_msg_vector, 128);
791 vec_reset_length (vcm->mq_msg_vector);
Dave Wallace543852a2017-08-03 02:11:34 -0400792 }
793
794 if (vcm->my_client_index == ~0)
795 {
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800796 /* API hookup and connect to VPP */
Dave Wallace048b1d62018-01-03 22:24:41 -0500797 vppcom_api_hookup ();
Florin Coras0d427d82018-06-27 03:24:07 -0700798 vcl_elog_init (vcm);
Dave Wallace543852a2017-08-03 02:11:34 -0400799 vcm->app_state = STATE_APP_START;
800 rv = vppcom_connect_to_vpp (app_name);
801 if (rv)
802 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500803 clib_warning ("VCL<%d>: ERROR: couldn't connect to VPP!",
Dave Wallace2e005bb2017-11-07 01:21:39 -0500804 getpid ());
Dave Wallace543852a2017-08-03 02:11:34 -0400805 return rv;
806 }
807
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800808 /* State event handling thread */
809
810 rv = vce_start_event_thread (&(vcm->event_thread), 20);
811
Florin Coras0d427d82018-06-27 03:24:07 -0700812 VDBG (0, "VCL<%d>: sending session enable", getpid ());
Dave Wallace543852a2017-08-03 02:11:34 -0400813
Dave Wallace048b1d62018-01-03 22:24:41 -0500814 rv = vppcom_app_session_enable ();
Dave Wallace543852a2017-08-03 02:11:34 -0400815 if (rv)
816 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500817 clib_warning ("VCL<%d>: ERROR: vppcom_app_session_enable() "
818 "failed!", getpid ());
Dave Wallace543852a2017-08-03 02:11:34 -0400819 return rv;
820 }
Dave Wallace543852a2017-08-03 02:11:34 -0400821
Florin Coras0d427d82018-06-27 03:24:07 -0700822 VDBG (0, "VCL<%d>: sending app attach", getpid ());
Dave Wallace048b1d62018-01-03 22:24:41 -0500823
824 rv = vppcom_app_attach ();
825 if (rv)
826 {
827 clib_warning ("VCL<%d>: ERROR: vppcom_app_attach() failed!",
828 getpid ());
829 return rv;
830 }
831
Florin Coras0d427d82018-06-27 03:24:07 -0700832 VDBG (0, "VCL<%d>: app_name '%s', my_client_index %d (0x%x)",
833 getpid (), app_name, vcm->my_client_index, vcm->my_client_index);
Dave Wallace66cf6eb2017-10-26 02:51:07 -0400834 }
Dave Wallace543852a2017-08-03 02:11:34 -0400835
836 return VPPCOM_OK;
837}
838
839void
840vppcom_app_destroy (void)
841{
Dave Wallace543852a2017-08-03 02:11:34 -0400842 int rv;
Dave Wallacede910062018-03-20 09:22:13 -0400843 f64 orig_app_timeout;
Dave Wallace543852a2017-08-03 02:11:34 -0400844
845 if (vcm->my_client_index == ~0)
846 return;
847
Florin Coras0d427d82018-06-27 03:24:07 -0700848 VDBG (0, "VCL<%d>: detaching from VPP, my_client_index %d (0x%x)",
849 getpid (), vcm->my_client_index, vcm->my_client_index);
850 vcl_evt (VCL_EVT_DETACH, vcm);
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -0800851
Florin Coras697faea2018-06-27 17:10:49 -0700852 vppcom_app_send_detach ();
Dave Wallacede910062018-03-20 09:22:13 -0400853 orig_app_timeout = vcm->cfg.app_timeout;
854 vcm->cfg.app_timeout = 2.0;
Dave Wallace543852a2017-08-03 02:11:34 -0400855 rv = vppcom_wait_for_app_state_change (STATE_APP_ENABLED);
Dave Wallacede910062018-03-20 09:22:13 -0400856 vcm->cfg.app_timeout = orig_app_timeout;
Dave Wallace543852a2017-08-03 02:11:34 -0400857 if (PREDICT_FALSE (rv))
Florin Coras0d427d82018-06-27 03:24:07 -0700858 VDBG (0, "VCL<%d>: application detach timed out! returning %d (%s)",
859 getpid (), rv, vppcom_retval_str (rv));
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -0800860
Florin Coras0d427d82018-06-27 03:24:07 -0700861 vcl_elog_stop (vcm);
Dave Wallace543852a2017-08-03 02:11:34 -0400862 vl_client_disconnect_from_vlib ();
863 vcm->my_client_index = ~0;
864 vcm->app_state = STATE_APP_START;
865}
866
867int
Dave Wallacec04cbf12018-02-07 18:14:02 -0500868vppcom_session_create (u8 proto, u8 is_nonblocking)
Dave Wallace543852a2017-08-03 02:11:34 -0400869{
Florin Coras7e12d942018-06-27 14:32:43 -0700870 vcl_session_t *session;
Dave Wallace543852a2017-08-03 02:11:34 -0400871 u32 session_index;
872
Dave Wallace7e607a72018-06-18 18:41:32 -0400873 VCL_SESSION_LOCK ();
Dave Wallace543852a2017-08-03 02:11:34 -0400874 pool_get (vcm->sessions, session);
Dave Wallacef7f809c2017-10-03 01:48:42 -0400875 memset (session, 0, sizeof (*session));
Dave Wallace543852a2017-08-03 02:11:34 -0400876 session_index = session - vcm->sessions;
877
Florin Coras7e12d942018-06-27 14:32:43 -0700878 session->session_type = proto;
879 session->session_state = STATE_START;
Dave Wallace4878cbe2017-11-21 03:45:09 -0500880 session->vpp_handle = ~0;
Florin Coras460dce62018-07-27 05:45:06 -0700881 session->is_dgram = proto == VPPCOM_PROTO_UDP;
Dave Wallace543852a2017-08-03 02:11:34 -0400882
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -0800883 if (is_nonblocking)
884 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_NONBLOCK);
Dave Wallace543852a2017-08-03 02:11:34 -0400885
Florin Coras7e12d942018-06-27 14:32:43 -0700886 vcl_evt (VCL_EVT_CREATE, session, session_type, session->session_state,
887 is_nonblocking, session_index);
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -0800888
Dave Wallace7e607a72018-06-18 18:41:32 -0400889 VCL_SESSION_UNLOCK ();
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -0800890
Florin Coras0d427d82018-06-27 03:24:07 -0700891 VDBG (0, "VCL<%d>: sid %u", getpid (), session_index);
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -0800892
Dave Wallace543852a2017-08-03 02:11:34 -0400893 return (int) session_index;
894}
895
896int
897vppcom_session_close (uint32_t session_index)
898{
Florin Coras7e12d942018-06-27 14:32:43 -0700899 vcl_session_t *session = 0;
Dave Wallace543852a2017-08-03 02:11:34 -0400900 int rv;
Dave Wallace66cf6eb2017-10-26 02:51:07 -0400901 u8 is_vep;
902 u8 is_vep_session;
903 u32 next_sid;
904 u32 vep_idx;
Dave Wallaceee45d412017-11-24 21:44:06 -0500905 u64 vpp_handle;
Dave Wallace4878cbe2017-11-21 03:45:09 -0500906 uword *p;
Dave Wallace66cf6eb2017-10-26 02:51:07 -0400907 session_state_t state;
Dave Wallace543852a2017-08-03 02:11:34 -0400908
Dave Wallace7e607a72018-06-18 18:41:32 -0400909 VCL_SESSION_LOCK_AND_GET (session_index, &session);
Dave Wallace66cf6eb2017-10-26 02:51:07 -0400910 is_vep = session->is_vep;
911 is_vep_session = session->is_vep_session;
912 next_sid = session->vep.next_sid;
913 vep_idx = session->vep.vep_idx;
Florin Coras7e12d942018-06-27 14:32:43 -0700914 state = session->session_state;
Dave Wallaceee45d412017-11-24 21:44:06 -0500915 vpp_handle = session->vpp_handle;
Dave Wallace7e607a72018-06-18 18:41:32 -0400916 VCL_SESSION_UNLOCK ();
Dave Wallace543852a2017-08-03 02:11:34 -0400917
918 if (VPPCOM_DEBUG > 0)
Dave Wallaceee45d412017-11-24 21:44:06 -0500919 {
920 if (is_vep)
Dave Wallace048b1d62018-01-03 22:24:41 -0500921 clib_warning ("VCL<%d>: vep_idx %u / sid %u: "
922 "closing epoll session...",
Dave Wallaceee45d412017-11-24 21:44:06 -0500923 getpid (), session_index, session_index);
924 else
Dave Wallace048b1d62018-01-03 22:24:41 -0500925 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %d: "
926 "closing session...",
Dave Wallaceee45d412017-11-24 21:44:06 -0500927 getpid (), vpp_handle, session_index);
928 }
Dave Wallace543852a2017-08-03 02:11:34 -0400929
Dave Wallace66cf6eb2017-10-26 02:51:07 -0400930 if (is_vep)
Dave Wallace543852a2017-08-03 02:11:34 -0400931 {
Dave Wallace66cf6eb2017-10-26 02:51:07 -0400932 while (next_sid != ~0)
Dave Wallace19481612017-09-15 18:47:44 -0400933 {
Dave Wallacef7f809c2017-10-03 01:48:42 -0400934 rv = vppcom_epoll_ctl (session_index, EPOLL_CTL_DEL, next_sid, 0);
Florin Coras0d427d82018-06-27 03:24:07 -0700935 if (PREDICT_FALSE (rv < 0))
936 VDBG (0, "VCL<%d>: vpp handle 0x%llx, sid %u: EPOLL_CTL_DEL "
937 "vep_idx %u failed! rv %d (%s)",
938 getpid (), vpp_handle, next_sid, vep_idx,
939 rv, vppcom_retval_str (rv));
Dave Wallacef7f809c2017-10-03 01:48:42 -0400940
Dave Wallace7e607a72018-06-18 18:41:32 -0400941 VCL_SESSION_LOCK_AND_GET (session_index, &session);
Dave Wallace66cf6eb2017-10-26 02:51:07 -0400942 next_sid = session->vep.next_sid;
Dave Wallace7e607a72018-06-18 18:41:32 -0400943 VCL_SESSION_UNLOCK ();
Dave Wallacef7f809c2017-10-03 01:48:42 -0400944 }
945 }
946 else
947 {
Dave Wallace66cf6eb2017-10-26 02:51:07 -0400948 if (is_vep_session)
Dave Wallacef7f809c2017-10-03 01:48:42 -0400949 {
Dave Wallacef7f809c2017-10-03 01:48:42 -0400950 rv = vppcom_epoll_ctl (vep_idx, EPOLL_CTL_DEL, session_index, 0);
Florin Coras0d427d82018-06-27 03:24:07 -0700951 if (rv < 0)
952 VDBG (0, "VCL<%d>: vpp handle 0x%llx, sid %u: EPOLL_CTL_DEL "
953 "vep_idx %u failed! rv %d (%s)",
954 getpid (), vpp_handle, session_index,
955 vep_idx, rv, vppcom_retval_str (rv));
Dave Wallacef7f809c2017-10-03 01:48:42 -0400956 }
957
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -0800958 if (state & STATE_LISTEN)
Dave Wallacef7f809c2017-10-03 01:48:42 -0400959 {
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -0800960 rv = vppcom_session_unbind (session_index);
961 if (PREDICT_FALSE (rv < 0))
Florin Coras0d427d82018-06-27 03:24:07 -0700962 VDBG (0, "VCL<%d>: vpp handle 0x%llx, sid %u: listener unbind "
963 "failed! rv %d (%s)",
964 getpid (), vpp_handle, session_index,
965 rv, vppcom_retval_str (rv));
Dave Wallacef7f809c2017-10-03 01:48:42 -0400966 }
Dave Wallace4878cbe2017-11-21 03:45:09 -0500967 else if (state & (CLIENT_STATE_OPEN | SERVER_STATE_OPEN))
Dave Wallacef7f809c2017-10-03 01:48:42 -0400968 {
Dave Wallace4878cbe2017-11-21 03:45:09 -0500969 rv = vppcom_session_disconnect (session_index);
970 if (PREDICT_FALSE (rv < 0))
Dave Wallace048b1d62018-01-03 22:24:41 -0500971 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -0500972 "session disconnect failed! rv %d (%s)",
973 getpid (), vpp_handle, session_index,
974 rv, vppcom_retval_str (rv));
Dave Wallacef7f809c2017-10-03 01:48:42 -0400975 }
Dave Wallace19481612017-09-15 18:47:44 -0400976 }
Dave Wallace4878cbe2017-11-21 03:45:09 -0500977
Dave Wallace7e607a72018-06-18 18:41:32 -0400978 VCL_SESSION_LOCK_AND_GET (session_index, &session);
Florin Coras99368312018-08-02 10:45:44 -0700979 if (vcl_session_is_ct (session))
980 {
981 vcl_cut_through_registration_t *ctr;
982 uword mq_addr;
983
984 mq_addr = pointer_to_uword (session->our_evt_q);
985 ctr = vcl_ct_registration_lock_and_lookup (mq_addr);
986 ASSERT (ctr);
987 if (ctr->epoll_evt_conn_index != ~0)
988 vcl_mq_epoll_del_evfd (ctr->epoll_evt_conn_index);
989 VDBG (0, "Removing ct registration %u",
990 vcl_ct_registration_index (ctr));
991 vcl_ct_registration_del (ctr);
992 vcl_ct_registration_unlock ();
993 }
Florin Coras54693d22018-07-17 10:46:29 -0700994
Dave Wallaceee45d412017-11-24 21:44:06 -0500995 vpp_handle = session->vpp_handle;
996 if (vpp_handle != ~0)
Dave Wallace4878cbe2017-11-21 03:45:09 -0500997 {
Dave Wallaceee45d412017-11-24 21:44:06 -0500998 p = hash_get (vcm->session_index_by_vpp_handles, vpp_handle);
Dave Wallace4878cbe2017-11-21 03:45:09 -0500999 if (p)
Dave Wallaceee45d412017-11-24 21:44:06 -05001000 hash_unset (vcm->session_index_by_vpp_handles, vpp_handle);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001001 }
Dave Wallace543852a2017-08-03 02:11:34 -04001002 pool_put_index (vcm->sessions, session_index);
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001003
Dave Wallace7e607a72018-06-18 18:41:32 -04001004 VCL_SESSION_UNLOCK ();
Dave Wallace4878cbe2017-11-21 03:45:09 -05001005
1006 if (VPPCOM_DEBUG > 0)
Dave Wallaceee45d412017-11-24 21:44:06 -05001007 {
1008 if (is_vep)
Dave Wallace048b1d62018-01-03 22:24:41 -05001009 clib_warning ("VCL<%d>: vep_idx %u / sid %u: epoll session removed.",
Dave Wallaceee45d412017-11-24 21:44:06 -05001010 getpid (), session_index, session_index);
1011 else
Dave Wallace048b1d62018-01-03 22:24:41 -05001012 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: session removed.",
Dave Wallaceee45d412017-11-24 21:44:06 -05001013 getpid (), vpp_handle, session_index);
1014 }
Dave Wallacef7f809c2017-10-03 01:48:42 -04001015done:
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08001016
Florin Coras0d427d82018-06-27 03:24:07 -07001017 vcl_evt (VCL_EVT_CLOSE, session, rv);
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08001018
Dave Wallace543852a2017-08-03 02:11:34 -04001019 return rv;
1020}
1021
1022int
1023vppcom_session_bind (uint32_t session_index, vppcom_endpt_t * ep)
1024{
Florin Coras7e12d942018-06-27 14:32:43 -07001025 vcl_session_t *session = 0;
Dave Wallace543852a2017-08-03 02:11:34 -04001026 int rv;
1027
1028 if (!ep || !ep->ip)
1029 return VPPCOM_EINVAL;
1030
Dave Wallace7e607a72018-06-18 18:41:32 -04001031 VCL_SESSION_LOCK_AND_GET (session_index, &session);
Dave Wallace543852a2017-08-03 02:11:34 -04001032
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001033 if (session->is_vep)
1034 {
Dave Wallace7e607a72018-06-18 18:41:32 -04001035 VCL_SESSION_UNLOCK ();
Dave Wallace048b1d62018-01-03 22:24:41 -05001036 clib_warning ("VCL<%d>: ERROR: sid %u: cannot "
1037 "bind to an epoll session!", getpid (), session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001038 rv = VPPCOM_EBADFD;
1039 goto done;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001040 }
1041
Florin Coras7e12d942018-06-27 14:32:43 -07001042 session->transport.is_ip4 = ep->is_ip4;
Florin Coras54693d22018-07-17 10:46:29 -07001043 if (ep->is_ip4)
1044 clib_memcpy (&session->transport.lcl_ip.ip4, ep->ip,
1045 sizeof (ip4_address_t));
1046 else
1047 clib_memcpy (&session->transport.lcl_ip.ip6, ep->ip,
1048 sizeof (ip6_address_t));
Florin Coras7e12d942018-06-27 14:32:43 -07001049 session->transport.lcl_port = ep->port;
Stevenac1f96d2017-10-24 16:03:58 -07001050
Florin Coras0d427d82018-06-27 03:24:07 -07001051 VDBG (0, "VCL<%d>: sid %u: binding to local %s address %U port %u, "
1052 "proto %s", getpid (), session_index,
Florin Coras7e12d942018-06-27 14:32:43 -07001053 session->transport.is_ip4 ? "IPv4" : "IPv6",
1054 format_ip46_address, &session->transport.lcl_ip,
1055 session->transport.is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6,
1056 clib_net_to_host_u16 (session->transport.lcl_port),
1057 session->session_type ? "UDP" : "TCP");
Florin Coras0d427d82018-06-27 03:24:07 -07001058 vcl_evt (VCL_EVT_BIND, session);
Dave Wallace7e607a72018-06-18 18:41:32 -04001059 VCL_SESSION_UNLOCK ();
Florin Coras460dce62018-07-27 05:45:06 -07001060
1061 if (session->session_type == VPPCOM_PROTO_UDP)
1062 vppcom_session_listen (session_index, 10);
1063
Dave Wallace4878cbe2017-11-21 03:45:09 -05001064done:
1065 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04001066}
1067
1068int
Dave Wallace33e002b2017-09-06 01:20:02 -04001069vppcom_session_listen (uint32_t listen_session_index, uint32_t q_len)
Dave Wallace543852a2017-08-03 02:11:34 -04001070{
Florin Coras7e12d942018-06-27 14:32:43 -07001071 vcl_session_t *listen_session = 0;
Dave Wallaceee45d412017-11-24 21:44:06 -05001072 u64 listen_vpp_handle;
1073 int rv, retval;
Dave Wallace543852a2017-08-03 02:11:34 -04001074
Keith Burns (alagalah)aba98de2018-02-22 03:23:40 -08001075 if (q_len == 0 || q_len == ~0)
1076 q_len = vcm->cfg.listen_queue_size;
1077
Dave Wallace7e607a72018-06-18 18:41:32 -04001078 VCL_SESSION_LOCK_AND_GET (listen_session_index, &listen_session);
Dave Wallace543852a2017-08-03 02:11:34 -04001079
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001080 if (listen_session->is_vep)
1081 {
Dave Wallace7e607a72018-06-18 18:41:32 -04001082 VCL_SESSION_UNLOCK ();
Dave Wallace048b1d62018-01-03 22:24:41 -05001083 clib_warning ("VCL<%d>: ERROR: sid %u: cannot listen on an "
Dave Wallace4878cbe2017-11-21 03:45:09 -05001084 "epoll session!", getpid (), listen_session_index);
1085 rv = VPPCOM_EBADFD;
1086 goto done;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001087 }
1088
Dave Wallaceee45d412017-11-24 21:44:06 -05001089 listen_vpp_handle = listen_session->vpp_handle;
Florin Coras7e12d942018-06-27 14:32:43 -07001090 if (listen_session->session_state & STATE_LISTEN)
Dave Wallacee695cb42017-11-02 22:04:42 -04001091 {
Dave Wallace7e607a72018-06-18 18:41:32 -04001092 VCL_SESSION_UNLOCK ();
Florin Coras0d427d82018-06-27 03:24:07 -07001093 VDBG (0, "VCL<%d>: vpp handle 0x%llx, sid %u: already in listen state!",
1094 getpid (), listen_vpp_handle, listen_session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001095 rv = VPPCOM_OK;
1096 goto done;
Dave Wallacee695cb42017-11-02 22:04:42 -04001097 }
1098
Florin Coras0d427d82018-06-27 03:24:07 -07001099 VDBG (0, "VCL<%d>: vpp handle 0x%llx, sid %u: sending VPP bind+listen "
1100 "request...", getpid (), listen_vpp_handle, listen_session_index);
Dave Wallace543852a2017-08-03 02:11:34 -04001101
Dave Wallace4878cbe2017-11-21 03:45:09 -05001102 vppcom_send_bind_sock (listen_session, listen_session_index);
Dave Wallace7e607a72018-06-18 18:41:32 -04001103 VCL_SESSION_UNLOCK ();
Florin Coras54693d22018-07-17 10:46:29 -07001104 retval = vppcom_wait_for_session_state_change (listen_session_index,
1105 STATE_LISTEN,
1106 vcm->cfg.session_timeout);
Dave Wallace543852a2017-08-03 02:11:34 -04001107
Dave Wallace7e607a72018-06-18 18:41:32 -04001108 VCL_SESSION_LOCK_AND_GET (listen_session_index, &listen_session);
Dave Wallaceee45d412017-11-24 21:44:06 -05001109 if (PREDICT_FALSE (retval))
1110 {
Florin Coras0d427d82018-06-27 03:24:07 -07001111 VDBG (0, "VCL<%d>: vpp handle 0x%llx, sid %u: bind+listen failed! "
1112 "returning %d (%s)", getpid (), listen_session->vpp_handle,
1113 listen_session_index, retval, vppcom_retval_str (retval));
Dave Wallace7e607a72018-06-18 18:41:32 -04001114 VCL_SESSION_UNLOCK ();
Dave Wallaceee45d412017-11-24 21:44:06 -05001115 rv = retval;
1116 goto done;
1117 }
1118
Dave Wallace7e607a72018-06-18 18:41:32 -04001119 VCL_SESSION_UNLOCK ();
Keith Burns (alagalah)0d2b0d52018-03-06 15:55:22 -08001120
1121done:
1122 return rv;
1123}
1124
1125int
Florin Coras7e12d942018-06-27 14:32:43 -07001126validate_args_session_accept_ (vcl_session_t * listen_session)
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001127{
1128 u32 listen_session_index = listen_session - vcm->sessions;
1129
1130 /* Input validation - expects spinlock on sessions_lockp */
1131 if (listen_session->is_vep)
1132 {
1133 clib_warning ("VCL<%d>: ERROR: sid %u: cannot accept on an "
1134 "epoll session!", getpid (), listen_session_index);
1135 return VPPCOM_EBADFD;
1136 }
1137
Florin Coras7e12d942018-06-27 14:32:43 -07001138 if (listen_session->session_state != STATE_LISTEN)
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001139 {
1140 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
1141 "not in listen state! state 0x%x (%s)", getpid (),
1142 listen_session->vpp_handle, listen_session_index,
Florin Coras7e12d942018-06-27 14:32:43 -07001143 listen_session->session_state,
1144 vppcom_session_state_str (listen_session->session_state));
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001145 return VPPCOM_EBADFD;
1146 }
1147 return VPPCOM_OK;
1148}
1149
1150int
Dave Wallace543852a2017-08-03 02:11:34 -04001151vppcom_session_accept (uint32_t listen_session_index, vppcom_endpt_t * ep,
Dave Wallace048b1d62018-01-03 22:24:41 -05001152 uint32_t flags)
Dave Wallace543852a2017-08-03 02:11:34 -04001153{
Florin Coras54693d22018-07-17 10:46:29 -07001154 session_accepted_msg_t accepted_msg;
Florin Coras7e12d942018-06-27 14:32:43 -07001155 vcl_session_t *listen_session = 0;
1156 vcl_session_t *client_session = 0;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001157 u32 client_session_index = ~0;
Florin Coras54693d22018-07-17 10:46:29 -07001158 svm_msg_q_t *vpp_evt_q;
1159 vcl_session_msg_t *evt;
Dave Wallaceee45d412017-11-24 21:44:06 -05001160 u64 listen_vpp_handle;
Florin Coras54693d22018-07-17 10:46:29 -07001161 svm_msg_q_msg_t msg;
1162 session_event_t *e;
1163 u8 is_nonblocking;
1164 int rv;
Dave Wallace543852a2017-08-03 02:11:34 -04001165
Dave Wallace7e607a72018-06-18 18:41:32 -04001166 VCL_SESSION_LOCK_AND_GET (listen_session_index, &listen_session);
Dave Wallace543852a2017-08-03 02:11:34 -04001167
Florin Coras54693d22018-07-17 10:46:29 -07001168 if (validate_args_session_accept_ (listen_session))
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001169 {
Dave Wallace7e607a72018-06-18 18:41:32 -04001170 VCL_SESSION_UNLOCK ();
Dave Wallace4878cbe2017-11-21 03:45:09 -05001171 goto done;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001172 }
1173
Dave Wallace7e607a72018-06-18 18:41:32 -04001174 VCL_SESSION_UNLOCK ();
Dave Wallace543852a2017-08-03 02:11:34 -04001175
Florin Coras54693d22018-07-17 10:46:29 -07001176 if (clib_fifo_elts (listen_session->accept_evts_fifo))
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001177 {
Florin Coras54693d22018-07-17 10:46:29 -07001178 clib_fifo_sub2 (listen_session->accept_evts_fifo, evt);
1179 accepted_msg = evt->accepted_msg;
1180 goto handle;
1181 }
1182
1183 is_nonblocking = VCL_SESS_ATTR_TEST (listen_session->attr,
1184 VCL_SESS_ATTR_NONBLOCK);
1185 if (svm_msg_q_is_empty (vcm->app_event_queue) && is_nonblocking)
1186 return VPPCOM_EAGAIN;
1187
1188 while (1)
1189 {
1190 if (svm_msg_q_sub (vcm->app_event_queue, &msg, SVM_Q_WAIT, 0))
1191 return VPPCOM_EAGAIN;
1192
1193 e = svm_msg_q_msg_data (vcm->app_event_queue, &msg);
1194 if (e->event_type != SESSION_CTRL_EVT_ACCEPTED)
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001195 {
Florin Coras54693d22018-07-17 10:46:29 -07001196 clib_warning ("discarded event: %u", e->event_type);
1197 svm_msg_q_free_msg (vcm->app_event_queue, &msg);
1198 continue;
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001199 }
Florin Coras54693d22018-07-17 10:46:29 -07001200 clib_memcpy (&accepted_msg, e->data, sizeof (accepted_msg));
1201 svm_msg_q_free_msg (vcm->app_event_queue, &msg);
1202 break;
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001203 }
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001204
Florin Coras54693d22018-07-17 10:46:29 -07001205handle:
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08001206
Florin Coras54693d22018-07-17 10:46:29 -07001207 client_session_index = vcl_session_accepted_handler (&accepted_msg);
Florin Coras99368312018-08-02 10:45:44 -07001208 listen_session = vcl_session_get (listen_session_index);
Florin Coras54693d22018-07-17 10:46:29 -07001209 VCL_SESSION_LOCK_AND_GET (client_session_index, &client_session);
1210 rv = client_session_index;
Dave Wallace543852a2017-08-03 02:11:34 -04001211
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001212 if (flags & O_NONBLOCK)
1213 VCL_SESS_ATTR_SET (client_session->attr, VCL_SESS_ATTR_NONBLOCK);
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001214
Florin Coras54693d22018-07-17 10:46:29 -07001215 listen_vpp_handle = listen_session->vpp_handle;
Florin Coras0d427d82018-06-27 03:24:07 -07001216 VDBG (0, "VCL<%d>: vpp handle 0x%llx, sid %u: Got a client request! "
1217 "vpp handle 0x%llx, sid %u, flags %d, is_nonblocking %u",
1218 getpid (), listen_vpp_handle, listen_session_index,
1219 client_session->vpp_handle, client_session_index,
1220 flags, VCL_SESS_ATTR_TEST (client_session->attr,
1221 VCL_SESS_ATTR_NONBLOCK));
Dave Wallace543852a2017-08-03 02:11:34 -04001222
Dave Wallace048b1d62018-01-03 22:24:41 -05001223 if (ep)
1224 {
Florin Coras7e12d942018-06-27 14:32:43 -07001225 ep->is_ip4 = client_session->transport.is_ip4;
1226 ep->port = client_session->transport.rmt_port;
1227 if (client_session->transport.is_ip4)
1228 clib_memcpy (ep->ip, &client_session->transport.rmt_ip.ip4,
Dave Wallace048b1d62018-01-03 22:24:41 -05001229 sizeof (ip4_address_t));
1230 else
Florin Coras7e12d942018-06-27 14:32:43 -07001231 clib_memcpy (ep->ip, &client_session->transport.rmt_ip.ip6,
Dave Wallace048b1d62018-01-03 22:24:41 -05001232 sizeof (ip6_address_t));
1233 }
Dave Wallace60caa062017-11-10 17:07:13 -05001234
Florin Coras54693d22018-07-17 10:46:29 -07001235 if (accepted_msg.server_event_queue_address)
1236 vpp_evt_q = uword_to_pointer (accepted_msg.vpp_event_queue_address,
1237 svm_msg_q_t *);
1238 else
1239 vpp_evt_q = client_session->vpp_evt_q;
Florin Coras99368312018-08-02 10:45:44 -07001240
Florin Coras54693d22018-07-17 10:46:29 -07001241 vcl_send_session_accepted_reply (vpp_evt_q, client_session->client_context,
1242 client_session->vpp_handle, 0);
Dave Wallace60caa062017-11-10 17:07:13 -05001243
Florin Coras54693d22018-07-17 10:46:29 -07001244 VDBG (0, "VCL<%d>: vpp handle 0x%llx, sid %u: accepted vpp handle 0x%llx, "
1245 "sid %u connection from peer %s address %U port %u to local %s "
1246 "address %U port %u", getpid (), listen_vpp_handle,
Florin Coras0d427d82018-06-27 03:24:07 -07001247 listen_session_index, client_session->vpp_handle,
1248 client_session_index,
Florin Coras7e12d942018-06-27 14:32:43 -07001249 client_session->transport.is_ip4 ? "IPv4" : "IPv6",
1250 format_ip46_address, &client_session->transport.rmt_ip,
Florin Coras54693d22018-07-17 10:46:29 -07001251 client_session->transport.is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6,
Florin Coras7e12d942018-06-27 14:32:43 -07001252 clib_net_to_host_u16 (client_session->transport.rmt_port),
1253 client_session->transport.is_ip4 ? "IPv4" : "IPv6",
1254 format_ip46_address, &client_session->transport.lcl_ip,
Florin Coras54693d22018-07-17 10:46:29 -07001255 client_session->transport.is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6,
Florin Coras7e12d942018-06-27 14:32:43 -07001256 clib_net_to_host_u16 (client_session->transport.lcl_port));
Florin Coras0d427d82018-06-27 03:24:07 -07001257 vcl_evt (VCL_EVT_ACCEPT, client_session, listen_session,
1258 client_session_index);
Dave Wallace7e607a72018-06-18 18:41:32 -04001259 VCL_SESSION_UNLOCK ();
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001260
Dave Wallace4878cbe2017-11-21 03:45:09 -05001261done:
1262 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04001263}
1264
1265int
1266vppcom_session_connect (uint32_t session_index, vppcom_endpt_t * server_ep)
1267{
Florin Coras7e12d942018-06-27 14:32:43 -07001268 vcl_session_t *session = 0;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001269 u64 vpp_handle = 0;
Dave Wallaceee45d412017-11-24 21:44:06 -05001270 int rv, retval = VPPCOM_OK;
Dave Wallace543852a2017-08-03 02:11:34 -04001271
Dave Wallace7e607a72018-06-18 18:41:32 -04001272 VCL_SESSION_LOCK_AND_GET (session_index, &session);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001273
1274 if (PREDICT_FALSE (session->is_vep))
Dave Wallace543852a2017-08-03 02:11:34 -04001275 {
Dave Wallace7e607a72018-06-18 18:41:32 -04001276 VCL_SESSION_UNLOCK ();
Dave Wallace048b1d62018-01-03 22:24:41 -05001277 clib_warning ("VCL<%d>: ERROR: sid %u: cannot "
1278 "connect on an epoll session!", getpid (), session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001279 rv = VPPCOM_EBADFD;
1280 goto done;
Dave Wallace543852a2017-08-03 02:11:34 -04001281 }
1282
Florin Coras7e12d942018-06-27 14:32:43 -07001283 if (PREDICT_FALSE (session->session_state & CLIENT_STATE_OPEN))
Dave Wallace543852a2017-08-03 02:11:34 -04001284 {
Florin Coras0d427d82018-06-27 03:24:07 -07001285 VDBG (0, "VCL<%d>: vpp handle 0x%llx, sid %u: session already "
1286 "connected to %s %U port %d proto %s, state 0x%x (%s)",
1287 getpid (), session->vpp_handle, session_index,
Florin Coras7e12d942018-06-27 14:32:43 -07001288 session->transport.is_ip4 ? "IPv4" : "IPv6",
Florin Coras0d427d82018-06-27 03:24:07 -07001289 format_ip46_address,
Florin Coras7e12d942018-06-27 14:32:43 -07001290 &session->transport.rmt_ip, session->transport.is_ip4 ?
Florin Coras0d427d82018-06-27 03:24:07 -07001291 IP46_TYPE_IP4 : IP46_TYPE_IP6,
Florin Coras7e12d942018-06-27 14:32:43 -07001292 clib_net_to_host_u16 (session->transport.rmt_port),
1293 session->session_type ? "UDP" : "TCP", session->session_state,
1294 vppcom_session_state_str (session->session_state));
Dave Wallace4878cbe2017-11-21 03:45:09 -05001295
Dave Wallace7e607a72018-06-18 18:41:32 -04001296 VCL_SESSION_UNLOCK ();
Dave Wallace4878cbe2017-11-21 03:45:09 -05001297 goto done;
Dave Wallace543852a2017-08-03 02:11:34 -04001298 }
1299
Florin Coras7e12d942018-06-27 14:32:43 -07001300 session->transport.is_ip4 = server_ep->is_ip4;
1301 if (session->transport.is_ip4)
1302 clib_memcpy (&session->transport.rmt_ip.ip4, server_ep->ip,
Dave Wallaced239f8d2018-06-19 13:37:30 -04001303 sizeof (ip4_address_t));
1304 else
Florin Coras7e12d942018-06-27 14:32:43 -07001305 clib_memcpy (&session->transport.rmt_ip.ip6, server_ep->ip,
Dave Wallaced239f8d2018-06-19 13:37:30 -04001306 sizeof (ip6_address_t));
Florin Coras7e12d942018-06-27 14:32:43 -07001307 session->transport.rmt_port = server_ep->port;
Dave Wallace543852a2017-08-03 02:11:34 -04001308
Florin Coras0d427d82018-06-27 03:24:07 -07001309 VDBG (0, "VCL<%d>: vpp handle 0x%llx, sid %u: connecting to server %s %U "
1310 "port %d proto %s",
1311 getpid (), session->vpp_handle, session_index,
Florin Coras7e12d942018-06-27 14:32:43 -07001312 session->transport.is_ip4 ? "IPv4" : "IPv6",
Florin Coras0d427d82018-06-27 03:24:07 -07001313 format_ip46_address,
Florin Coras7e12d942018-06-27 14:32:43 -07001314 &session->transport.rmt_ip, session->transport.is_ip4 ?
Florin Coras0d427d82018-06-27 03:24:07 -07001315 IP46_TYPE_IP4 : IP46_TYPE_IP6,
Florin Coras7e12d942018-06-27 14:32:43 -07001316 clib_net_to_host_u16 (session->transport.rmt_port),
1317 session->session_type ? "UDP" : "TCP");
Dave Wallace543852a2017-08-03 02:11:34 -04001318
1319 vppcom_send_connect_sock (session, session_index);
Dave Wallace7e607a72018-06-18 18:41:32 -04001320 VCL_SESSION_UNLOCK ();
Dave Wallace4878cbe2017-11-21 03:45:09 -05001321
Florin Coras54693d22018-07-17 10:46:29 -07001322 retval = vppcom_wait_for_session_state_change (session_index, STATE_CONNECT,
1323 vcm->cfg.session_timeout);
Dave Wallaceee45d412017-11-24 21:44:06 -05001324
Dave Wallace7e607a72018-06-18 18:41:32 -04001325 VCL_SESSION_LOCK_AND_GET (session_index, &session);
Dave Wallaceee45d412017-11-24 21:44:06 -05001326 vpp_handle = session->vpp_handle;
Dave Wallace7e607a72018-06-18 18:41:32 -04001327 VCL_SESSION_UNLOCK ();
Dave Wallace7876d392017-10-19 03:53:57 -04001328
Dave Wallace4878cbe2017-11-21 03:45:09 -05001329done:
Dave Wallaceee45d412017-11-24 21:44:06 -05001330 if (PREDICT_FALSE (retval))
1331 {
1332 rv = retval;
1333 if (VPPCOM_DEBUG > 0)
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001334 {
1335 if (session)
Florin Coras0d427d82018-06-27 03:24:07 -07001336 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: connect "
1337 "failed! returning %d (%s)", getpid (), vpp_handle,
1338 session_index, rv, vppcom_retval_str (rv));
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001339 else
1340 clib_warning ("VCL<%d>: no session for sid %u: connect failed! "
1341 "returning %d (%s)", getpid (),
1342 session_index, rv, vppcom_retval_str (rv));
1343 }
Dave Wallaceee45d412017-11-24 21:44:06 -05001344 }
Florin Coras0d427d82018-06-27 03:24:07 -07001345 else
1346 VDBG (0, "VCL<%d>: vpp handle 0x%llx, sid %u: connected!",
1347 getpid (), vpp_handle, session_index);
Dave Wallaceee45d412017-11-24 21:44:06 -05001348
Dave Wallace4878cbe2017-11-21 03:45:09 -05001349 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04001350}
1351
Florin Coras54693d22018-07-17 10:46:29 -07001352static u8
1353vcl_is_rx_evt_for_session (session_event_t * e, u32 sid, u8 is_ct)
1354{
1355 if (!is_ct)
1356 return (e->event_type == FIFO_EVENT_APP_RX
1357 && e->fifo->client_session_index == sid);
1358 else
1359 return (e->event_type == SESSION_IO_EVT_CT_TX);
1360}
1361
Florin Coras460dce62018-07-27 05:45:06 -07001362static inline u8
1363vcl_session_is_readable (vcl_session_t * s)
1364{
1365 return ((s->session_state & STATE_OPEN)
1366 || (s->session_state == STATE_LISTEN
1367 && s->session_type == VPPCOM_PROTO_UDP));
1368}
1369
Steven58f464e2017-10-25 12:33:12 -07001370static inline int
1371vppcom_session_read_internal (uint32_t session_index, void *buf, int n,
1372 u8 peek)
Dave Wallace543852a2017-08-03 02:11:34 -04001373{
Florin Coras54693d22018-07-17 10:46:29 -07001374 int n_read = 0, rv, is_nonblocking;
Florin Coras460dce62018-07-27 05:45:06 -07001375 vcl_session_t *s = 0;
Dave Wallace543852a2017-08-03 02:11:34 -04001376 svm_fifo_t *rx_fifo;
Florin Coras54693d22018-07-17 10:46:29 -07001377 svm_msg_q_msg_t msg;
1378 session_event_t *e;
1379 svm_msg_q_t *mq;
1380 u8 is_full;
Dave Wallace543852a2017-08-03 02:11:34 -04001381
1382 ASSERT (buf);
1383
Florin Coras460dce62018-07-27 05:45:06 -07001384 VCL_SESSION_LOCK_AND_GET (session_index, &s);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001385
Florin Coras460dce62018-07-27 05:45:06 -07001386 if (PREDICT_FALSE (s->is_vep))
Dave Wallace543852a2017-08-03 02:11:34 -04001387 {
Dave Wallace7e607a72018-06-18 18:41:32 -04001388 VCL_SESSION_UNLOCK ();
Dave Wallace048b1d62018-01-03 22:24:41 -05001389 clib_warning ("VCL<%d>: ERROR: sid %u: cannot "
1390 "read from an epoll session!", getpid (), session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001391 rv = VPPCOM_EBADFD;
1392 goto done;
Dave Wallace543852a2017-08-03 02:11:34 -04001393 }
1394
Florin Coras460dce62018-07-27 05:45:06 -07001395 is_nonblocking = VCL_SESS_ATTR_TEST (s->attr, VCL_SESS_ATTR_NONBLOCK);
1396 rx_fifo = s->rx_fifo;
Florin Coras54693d22018-07-17 10:46:29 -07001397
Florin Coras460dce62018-07-27 05:45:06 -07001398 if (PREDICT_FALSE (!vcl_session_is_readable (s)))
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001399 {
Florin Coras460dce62018-07-27 05:45:06 -07001400 session_state_t state = s->session_state;
Dave Wallace7e607a72018-06-18 18:41:32 -04001401 VCL_SESSION_UNLOCK ();
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08001402 rv = ((state & STATE_DISCONNECT) ? VPPCOM_ECONNRESET : VPPCOM_ENOTCONN);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001403
Florin Coras0d427d82018-06-27 03:24:07 -07001404 VDBG (0, "VCL<%d>: vpp handle 0x%llx, sid %u: %s session is not open! "
1405 "state 0x%x (%s), returning %d (%s)",
Florin Coras460dce62018-07-27 05:45:06 -07001406 getpid (), s->vpp_handle, session_index, state,
Florin Coras0d427d82018-06-27 03:24:07 -07001407 vppcom_session_state_str (state), rv, vppcom_retval_str (rv));
Dave Wallace4878cbe2017-11-21 03:45:09 -05001408 goto done;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001409 }
1410
Dave Wallace7e607a72018-06-18 18:41:32 -04001411 VCL_SESSION_UNLOCK ();
Florin Coras460dce62018-07-27 05:45:06 -07001412 mq = vcl_session_is_ct (s) ? s->our_evt_q : vcm->app_event_queue;
Florin Coras99368312018-08-02 10:45:44 -07001413 svm_fifo_unset_event (rx_fifo);
Florin Coras54693d22018-07-17 10:46:29 -07001414 is_full = svm_fifo_is_full (rx_fifo);
Dave Wallacef7f809c2017-10-03 01:48:42 -04001415
Florin Coras54693d22018-07-17 10:46:29 -07001416 if (svm_fifo_is_empty (rx_fifo))
Dave Wallacef7f809c2017-10-03 01:48:42 -04001417 {
Florin Coras54693d22018-07-17 10:46:29 -07001418 if (is_nonblocking)
Dave Wallace4878cbe2017-11-21 03:45:09 -05001419 {
Florin Coras54693d22018-07-17 10:46:29 -07001420 rv = VPPCOM_OK;
1421 goto done;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001422 }
Florin Coras54693d22018-07-17 10:46:29 -07001423 while (1)
1424 {
Florin Coras99368312018-08-02 10:45:44 -07001425 svm_msg_q_lock (mq);
Florin Coras54693d22018-07-17 10:46:29 -07001426 if (svm_msg_q_is_empty (mq))
1427 svm_msg_q_wait (mq);
Florin Coras99368312018-08-02 10:45:44 -07001428
Florin Coras54693d22018-07-17 10:46:29 -07001429 svm_msg_q_sub_w_lock (mq, &msg);
1430 e = svm_msg_q_msg_data (mq, &msg);
Florin Coras99368312018-08-02 10:45:44 -07001431 svm_msg_q_unlock (mq);
Florin Coras54693d22018-07-17 10:46:29 -07001432 if (!vcl_is_rx_evt_for_session (e, session_index,
Florin Coras460dce62018-07-27 05:45:06 -07001433 s->our_evt_q != 0))
Florin Coras54693d22018-07-17 10:46:29 -07001434 {
1435 vcl_handle_mq_ctrl_event (e);
1436 svm_msg_q_free_msg (mq, &msg);
1437 continue;
1438 }
Florin Coras99368312018-08-02 10:45:44 -07001439 svm_fifo_unset_event (rx_fifo);
Florin Coras54693d22018-07-17 10:46:29 -07001440 svm_msg_q_free_msg (mq, &msg);
Florin Coras60f1fc12018-08-16 14:57:31 -07001441 if (PREDICT_FALSE (s->session_state == STATE_CLOSE_ON_EMPTY))
1442 return 0;
1443 if (svm_fifo_is_empty (rx_fifo))
1444 continue;
Florin Coras54693d22018-07-17 10:46:29 -07001445 break;
1446 }
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001447 }
Florin Coras54693d22018-07-17 10:46:29 -07001448
Florin Coras460dce62018-07-27 05:45:06 -07001449 if (s->is_dgram)
Florin Coras99368312018-08-02 10:45:44 -07001450 n_read = app_recv_dgram_raw (rx_fifo, buf, n, &s->transport, 0, peek);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001451 else
Florin Coras99368312018-08-02 10:45:44 -07001452 n_read = app_recv_stream_raw (rx_fifo, buf, n, 0, peek);
Florin Coras54693d22018-07-17 10:46:29 -07001453
Florin Coras460dce62018-07-27 05:45:06 -07001454 if (vcl_session_is_ct (s) && is_full)
Florin Coras99368312018-08-02 10:45:44 -07001455 {
1456 /* If the peer is not polling send notification */
1457 if (!svm_fifo_has_event (s->rx_fifo))
1458 app_send_io_evt_to_vpp (s->vpp_evt_q, s->rx_fifo,
1459 SESSION_IO_EVT_CT_RX, SVM_Q_WAIT);
1460 }
Florin Coras54693d22018-07-17 10:46:29 -07001461
Dave Wallace4878cbe2017-11-21 03:45:09 -05001462 if (VPPCOM_DEBUG > 2)
1463 {
Florin Coras54693d22018-07-17 10:46:29 -07001464 if (n_read > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001465 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: read %d bytes "
Florin Coras460dce62018-07-27 05:45:06 -07001466 "from (%p)", getpid (), s->vpp_handle,
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001467 session_index, n_read, rx_fifo);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001468 else
Dave Wallace048b1d62018-01-03 22:24:41 -05001469 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: nothing read! "
Florin Coras460dce62018-07-27 05:45:06 -07001470 "returning %d (%s)", getpid (), s->vpp_handle,
Dave Wallaceee45d412017-11-24 21:44:06 -05001471 session_index, rv, vppcom_retval_str (rv));
Dave Wallace4878cbe2017-11-21 03:45:09 -05001472 }
Florin Coras54693d22018-07-17 10:46:29 -07001473 return n_read;
1474
Dave Wallace4878cbe2017-11-21 03:45:09 -05001475done:
1476 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04001477}
1478
Steven58f464e2017-10-25 12:33:12 -07001479int
Dave Wallace048b1d62018-01-03 22:24:41 -05001480vppcom_session_read (uint32_t session_index, void *buf, size_t n)
Steven58f464e2017-10-25 12:33:12 -07001481{
1482 return (vppcom_session_read_internal (session_index, buf, n, 0));
1483}
1484
1485static int
1486vppcom_session_peek (uint32_t session_index, void *buf, int n)
1487{
1488 return (vppcom_session_read_internal (session_index, buf, n, 1));
1489}
1490
Dave Wallace543852a2017-08-03 02:11:34 -04001491static inline int
Florin Coras54693d22018-07-17 10:46:29 -07001492vppcom_session_read_ready (vcl_session_t * session)
Dave Wallace543852a2017-08-03 02:11:34 -04001493{
Dave Wallace543852a2017-08-03 02:11:34 -04001494 /* Assumes caller has acquired spinlock: vcm->sessions_lockp */
Dave Wallace4878cbe2017-11-21 03:45:09 -05001495 if (PREDICT_FALSE (session->is_vep))
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001496 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001497 clib_warning ("VCL<%d>: ERROR: sid %u: cannot read from an "
Florin Coras54693d22018-07-17 10:46:29 -07001498 "epoll session!", getpid (), vcl_session_index (session));
1499 return VPPCOM_EBADFD;
1500 }
1501
1502 if (PREDICT_FALSE (!(session->session_state & (STATE_OPEN | STATE_LISTEN))))
1503 {
1504 session_state_t state = session->session_state;
1505 int rv;
1506
1507 rv = ((state & STATE_DISCONNECT) ? VPPCOM_ECONNRESET : VPPCOM_ENOTCONN);
1508
1509 VDBG (1, "VCL<%d>: vpp handle 0x%llx, sid %u: session is not open!"
1510 " state 0x%x (%s), returning %d (%s)", getpid (),
1511 session->vpp_handle, vcl_session_index (session), state,
1512 vppcom_session_state_str (state), rv, vppcom_retval_str (rv));
1513 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04001514 }
Dave Wallace33e002b2017-09-06 01:20:02 -04001515
Florin Coras7e12d942018-06-27 14:32:43 -07001516 if (session->session_state & STATE_LISTEN)
Florin Coras54693d22018-07-17 10:46:29 -07001517 return clib_fifo_elts (session->accept_evts_fifo);
1518
1519 return svm_fifo_max_dequeue (session->rx_fifo);
1520}
1521
1522static u8
1523vcl_is_tx_evt_for_session (session_event_t * e, u32 sid, u8 is_ct)
1524{
1525 if (!is_ct)
1526 return (e->event_type == FIFO_EVENT_APP_TX
1527 && e->fifo->client_session_index == sid);
Dave Wallace543852a2017-08-03 02:11:34 -04001528 else
Florin Coras54693d22018-07-17 10:46:29 -07001529 return (e->event_type == SESSION_IO_EVT_CT_RX);
Dave Wallace543852a2017-08-03 02:11:34 -04001530}
1531
1532int
Dave Wallace048b1d62018-01-03 22:24:41 -05001533vppcom_session_write (uint32_t session_index, void *buf, size_t n)
Dave Wallace543852a2017-08-03 02:11:34 -04001534{
Florin Coras54693d22018-07-17 10:46:29 -07001535 int rv, n_write, is_nonblocking;
Florin Coras460dce62018-07-27 05:45:06 -07001536 vcl_session_t *s = 0;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001537 svm_fifo_t *tx_fifo = 0;
Florin Coras460dce62018-07-27 05:45:06 -07001538 session_evt_type_t et;
Florin Coras54693d22018-07-17 10:46:29 -07001539 svm_msg_q_msg_t msg;
1540 session_event_t *e;
Florin Coras3c2fed52018-07-04 04:15:05 -07001541 svm_msg_q_t *mq;
Dave Wallace543852a2017-08-03 02:11:34 -04001542
1543 ASSERT (buf);
1544
Florin Coras460dce62018-07-27 05:45:06 -07001545 VCL_SESSION_LOCK_AND_GET (session_index, &s);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001546
Florin Coras460dce62018-07-27 05:45:06 -07001547 tx_fifo = s->tx_fifo;
1548 is_nonblocking = VCL_SESS_ATTR_TEST (s->attr, VCL_SESS_ATTR_NONBLOCK);
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001549
Florin Coras460dce62018-07-27 05:45:06 -07001550 if (PREDICT_FALSE (s->is_vep))
Dave Wallace543852a2017-08-03 02:11:34 -04001551 {
Dave Wallace7e607a72018-06-18 18:41:32 -04001552 VCL_SESSION_UNLOCK ();
Dave Wallace048b1d62018-01-03 22:24:41 -05001553 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -05001554 "cannot write to an epoll session!",
Florin Coras460dce62018-07-27 05:45:06 -07001555 getpid (), s->vpp_handle, session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001556
1557 rv = VPPCOM_EBADFD;
1558 goto done;
Dave Wallace543852a2017-08-03 02:11:34 -04001559 }
1560
Florin Coras460dce62018-07-27 05:45:06 -07001561 if (!(s->session_state & STATE_OPEN))
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001562 {
Florin Coras460dce62018-07-27 05:45:06 -07001563 session_state_t state = s->session_state;
Florin Coras54693d22018-07-17 10:46:29 -07001564 rv = ((state & STATE_DISCONNECT) ? VPPCOM_ECONNRESET : VPPCOM_ENOTCONN);
Dave Wallace7e607a72018-06-18 18:41:32 -04001565 VCL_SESSION_UNLOCK ();
Florin Coras0d427d82018-06-27 03:24:07 -07001566 VDBG (1, "VCL<%d>: vpp handle 0x%llx, sid %u: session is not open! "
1567 "state 0x%x (%s)",
Florin Coras460dce62018-07-27 05:45:06 -07001568 getpid (), s->vpp_handle, session_index,
Florin Coras0d427d82018-06-27 03:24:07 -07001569 state, vppcom_session_state_str (state));
Dave Wallace4878cbe2017-11-21 03:45:09 -05001570 goto done;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001571 }
1572
Dave Wallace7e607a72018-06-18 18:41:32 -04001573 VCL_SESSION_UNLOCK ();
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001574
Florin Coras460dce62018-07-27 05:45:06 -07001575 mq = vcl_session_is_ct (s) ? s->our_evt_q : vcm->app_event_queue;
Florin Coras54693d22018-07-17 10:46:29 -07001576 if (svm_fifo_is_full (tx_fifo))
Dave Wallace543852a2017-08-03 02:11:34 -04001577 {
Florin Coras54693d22018-07-17 10:46:29 -07001578 if (is_nonblocking)
1579 {
1580 rv = VPPCOM_EWOULDBLOCK;
1581 goto done;
1582 }
Florin Coras60f1fc12018-08-16 14:57:31 -07001583 while (svm_fifo_is_full (tx_fifo))
Florin Coras54693d22018-07-17 10:46:29 -07001584 {
Florin Coras99368312018-08-02 10:45:44 -07001585 svm_msg_q_lock (mq);
Florin Coras99368312018-08-02 10:45:44 -07001586 while (svm_msg_q_is_empty (mq) && svm_msg_q_timedwait (mq, 10e-6))
1587 ;
Florin Coras54693d22018-07-17 10:46:29 -07001588 svm_msg_q_sub_w_lock (mq, &msg);
1589 e = svm_msg_q_msg_data (mq, &msg);
Florin Coras99368312018-08-02 10:45:44 -07001590 svm_msg_q_unlock (mq);
1591
Florin Coras54693d22018-07-17 10:46:29 -07001592 if (!vcl_is_tx_evt_for_session (e, session_index,
Florin Coras460dce62018-07-27 05:45:06 -07001593 s->our_evt_q != 0))
Florin Coras60f1fc12018-08-16 14:57:31 -07001594 vcl_handle_mq_ctrl_event (e);
Florin Coras54693d22018-07-17 10:46:29 -07001595 svm_msg_q_free_msg (mq, &msg);
Florin Coras54693d22018-07-17 10:46:29 -07001596 }
Dave Wallace543852a2017-08-03 02:11:34 -04001597 }
Dave Wallace543852a2017-08-03 02:11:34 -04001598
Florin Coras460dce62018-07-27 05:45:06 -07001599 ASSERT (FIFO_EVENT_APP_TX + 1 == SESSION_IO_EVT_CT_TX);
1600 et = FIFO_EVENT_APP_TX + vcl_session_is_ct (s);
1601 if (s->is_dgram)
1602 n_write = app_send_dgram_raw (tx_fifo, &s->transport,
1603 s->vpp_evt_q, buf, n, et, SVM_Q_WAIT);
1604 else
1605 n_write = app_send_stream_raw (tx_fifo, s->vpp_evt_q, buf, n, et,
1606 SVM_Q_WAIT);
Keith Burns (alagalah)410bcca2018-03-23 13:42:49 -07001607
Florin Coras460dce62018-07-27 05:45:06 -07001608 ASSERT (n_write > 0);
Dave Wallace543852a2017-08-03 02:11:34 -04001609
1610 if (VPPCOM_DEBUG > 2)
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001611 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05001612 if (n_write <= 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001613 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
Florin Coras460dce62018-07-27 05:45:06 -07001614 "FIFO-FULL (%p)", getpid (), s->vpp_handle,
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001615 session_index, tx_fifo);
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001616 else
Dave Wallace048b1d62018-01-03 22:24:41 -05001617 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001618 "wrote %d bytes tx-fifo: (%p)", getpid (),
Florin Coras460dce62018-07-27 05:45:06 -07001619 s->vpp_handle, session_index, n_write, tx_fifo);
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001620 }
Florin Coras54693d22018-07-17 10:46:29 -07001621 return n_write;
1622
Dave Wallace4878cbe2017-11-21 03:45:09 -05001623done:
1624 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04001625}
1626
Florin Coras99368312018-08-02 10:45:44 -07001627static vcl_session_t *
1628vcl_ct_session_get_from_fifo (svm_fifo_t * f, u8 type)
1629{
1630 vcl_session_t *s;
1631 s = vcl_session_get (f->client_session_index);
1632 if (s)
1633 {
1634 /* rx fifo */
1635 if (type == 0 && s->rx_fifo == f)
1636 return s;
1637 /* tx fifo */
1638 if (type == 1 && s->tx_fifo == f)
1639 return s;
1640 }
1641 s = vcl_session_get (f->master_session_index);
1642 if (s)
1643 {
1644 if (type == 0 && s->rx_fifo == f)
1645 return s;
1646 if (type == 1 && s->tx_fifo == f)
1647 return s;
1648 }
1649 return 0;
1650}
1651
Dave Wallace543852a2017-08-03 02:11:34 -04001652static inline int
Florin Coras7e12d942018-06-27 14:32:43 -07001653vppcom_session_write_ready (vcl_session_t * session, u32 session_index)
Dave Wallace543852a2017-08-03 02:11:34 -04001654{
Dave Wallace543852a2017-08-03 02:11:34 -04001655 /* Assumes caller has acquired spinlock: vcm->sessions_lockp */
Dave Wallace4878cbe2017-11-21 03:45:09 -05001656 if (PREDICT_FALSE (session->is_vep))
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001657 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001658 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -05001659 "cannot write to an epoll session!",
1660 getpid (), session->vpp_handle, session_index);
Florin Coras54693d22018-07-17 10:46:29 -07001661 return VPPCOM_EBADFD;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001662 }
1663
Florin Coras7e12d942018-06-27 14:32:43 -07001664 if (PREDICT_FALSE (session->session_state & STATE_LISTEN))
Dave Wallace33e002b2017-09-06 01:20:02 -04001665 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001666 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -05001667 "cannot write to a listen session!",
1668 getpid (), session->vpp_handle, session_index);
Florin Coras54693d22018-07-17 10:46:29 -07001669 return VPPCOM_EBADFD;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001670 }
1671
Florin Coras54693d22018-07-17 10:46:29 -07001672 if (PREDICT_FALSE (!(session->session_state & STATE_OPEN)))
Dave Wallace4878cbe2017-11-21 03:45:09 -05001673 {
Florin Coras7e12d942018-06-27 14:32:43 -07001674 session_state_t state = session->session_state;
Florin Coras54693d22018-07-17 10:46:29 -07001675 int rv;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001676
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08001677 rv = ((state & STATE_DISCONNECT) ? VPPCOM_ECONNRESET : VPPCOM_ENOTCONN);
Dave Wallace048b1d62018-01-03 22:24:41 -05001678 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001679 "session is not open! state 0x%x (%s), "
Dave Wallaceee45d412017-11-24 21:44:06 -05001680 "returning %d (%s)", getpid (), session->vpp_handle,
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001681 session_index,
Dave Wallace4878cbe2017-11-21 03:45:09 -05001682 state, vppcom_session_state_str (state),
1683 rv, vppcom_retval_str (rv));
Florin Coras54693d22018-07-17 10:46:29 -07001684 return rv;
Dave Wallace33e002b2017-09-06 01:20:02 -04001685 }
1686
Florin Coras0d427d82018-06-27 03:24:07 -07001687 VDBG (3, "VCL<%d>: vpp handle 0x%llx, sid %u: peek %s (%p), ready = %d",
1688 getpid (), session->vpp_handle, session_index, session->tx_fifo,
Florin Coras54693d22018-07-17 10:46:29 -07001689 svm_fifo_max_enqueue (session->tx_fifo));
Dave Wallacef7f809c2017-10-03 01:48:42 -04001690
Florin Coras54693d22018-07-17 10:46:29 -07001691 return svm_fifo_max_enqueue (session->tx_fifo);
1692}
1693
Florin Coras99368312018-08-02 10:45:44 -07001694static inline int
1695vcl_mq_dequeue_batch (svm_msg_q_t * mq)
1696{
1697 svm_msg_q_msg_t *msg;
1698 u32 n_msgs;
1699 int i;
1700
1701 n_msgs = svm_msg_q_size (mq);
1702 for (i = 0; i < n_msgs; i++)
1703 {
1704 vec_add2 (vcm->mq_msg_vector, msg, 1);
1705 svm_msg_q_sub_w_lock (mq, msg);
1706 }
1707 return n_msgs;
1708}
1709
Florin Coras54693d22018-07-17 10:46:29 -07001710static int
1711vcl_select_handle_mq (svm_msg_q_t * mq, unsigned long n_bits,
1712 unsigned long *read_map, unsigned long *write_map,
1713 unsigned long *except_map, double time_to_wait,
1714 u32 * bits_set)
1715{
1716 session_disconnected_msg_t *disconnected_msg;
Florin Coras99368312018-08-02 10:45:44 -07001717 session_connected_msg_t *connected_msg;
Florin Coras54693d22018-07-17 10:46:29 -07001718 session_accepted_msg_t *accepted_msg;
1719 vcl_session_msg_t *vcl_msg;
1720 vcl_session_t *session;
Florin Coras99368312018-08-02 10:45:44 -07001721 svm_msg_q_msg_t *msg;
Florin Coras54693d22018-07-17 10:46:29 -07001722 session_event_t *e;
Florin Coras99368312018-08-02 10:45:44 -07001723 u32 i, sid;
Florin Coras54693d22018-07-17 10:46:29 -07001724 u64 handle;
1725
1726 svm_msg_q_lock (mq);
1727 if (svm_msg_q_is_empty (mq))
Dave Wallace4878cbe2017-11-21 03:45:09 -05001728 {
Florin Coras54693d22018-07-17 10:46:29 -07001729 if (*bits_set)
Dave Wallace4878cbe2017-11-21 03:45:09 -05001730 {
Florin Coras54693d22018-07-17 10:46:29 -07001731 svm_msg_q_unlock (mq);
1732 return 0;
1733 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05001734
Florin Coras54693d22018-07-17 10:46:29 -07001735 if (!time_to_wait)
1736 {
1737 svm_msg_q_unlock (mq);
1738 return 0;
1739 }
1740 else if (time_to_wait < 0)
1741 {
1742 svm_msg_q_wait (mq);
1743 }
1744 else
1745 {
1746 if (svm_msg_q_timedwait (mq, time_to_wait))
1747 {
1748 svm_msg_q_unlock (mq);
1749 return 0;
1750 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05001751 }
1752 }
Florin Coras99368312018-08-02 10:45:44 -07001753 vcl_mq_dequeue_batch (mq);
Florin Coras54693d22018-07-17 10:46:29 -07001754 svm_msg_q_unlock (mq);
1755
Florin Coras99368312018-08-02 10:45:44 -07001756 for (i = 0; i < vec_len (vcm->mq_msg_vector); i++)
Florin Coras54693d22018-07-17 10:46:29 -07001757 {
Florin Coras99368312018-08-02 10:45:44 -07001758 msg = vec_elt_at_index (vcm->mq_msg_vector, i);
1759 e = svm_msg_q_msg_data (mq, msg);
Florin Coras54693d22018-07-17 10:46:29 -07001760 switch (e->event_type)
1761 {
1762 case FIFO_EVENT_APP_RX:
1763 sid = e->fifo->client_session_index;
1764 session = vcl_session_get (sid);
Florin Coras54693d22018-07-17 10:46:29 -07001765 if (sid < n_bits && read_map)
1766 {
1767 clib_bitmap_set_no_check (read_map, sid, 1);
1768 *bits_set += 1;
1769 }
1770 break;
1771 case FIFO_EVENT_APP_TX:
1772 sid = e->fifo->client_session_index;
1773 session = vcl_session_get (sid);
Florin Coras60f1fc12018-08-16 14:57:31 -07001774 if (!session)
Florin Coras54693d22018-07-17 10:46:29 -07001775 break;
1776 if (sid < n_bits && write_map)
1777 {
1778 clib_bitmap_set_no_check (write_map, sid, 1);
1779 *bits_set += 1;
1780 }
1781 break;
1782 case SESSION_IO_EVT_CT_TX:
1783 session = vcl_ct_session_get_from_fifo (e->fifo, 0);
1784 sid = vcl_session_index (session);
Florin Coras54693d22018-07-17 10:46:29 -07001785 if (sid < n_bits && read_map)
1786 {
1787 clib_bitmap_set_no_check (read_map, sid, 1);
1788 *bits_set += 1;
1789 }
1790 break;
1791 break;
1792 case SESSION_IO_EVT_CT_RX:
1793 session = vcl_ct_session_get_from_fifo (e->fifo, 1);
1794 sid = vcl_session_index (session);
Florin Coras60f1fc12018-08-16 14:57:31 -07001795 if (!session)
Florin Coras54693d22018-07-17 10:46:29 -07001796 break;
1797 if (sid < n_bits && write_map)
1798 {
1799 clib_bitmap_set_no_check (write_map, sid, 1);
1800 *bits_set += 1;
1801 }
1802 break;
1803 case SESSION_CTRL_EVT_ACCEPTED:
1804 accepted_msg = (session_accepted_msg_t *) e->data;
1805 handle = accepted_msg->listener_handle;
1806 session = vppcom_session_table_lookup_listener (handle);
1807 if (!session)
1808 {
1809 clib_warning ("VCL<%d>: ERROR: couldn't find listen session:"
1810 "listener handle %llx", getpid (), handle);
1811 break;
1812 }
1813
1814 clib_fifo_add2 (session->accept_evts_fifo, vcl_msg);
1815 vcl_msg->accepted_msg = *accepted_msg;
1816 sid = session - vcm->sessions;
1817 if (sid < n_bits && read_map)
1818 {
1819 clib_bitmap_set_no_check (read_map, sid, 1);
1820 *bits_set += 1;
1821 }
1822 break;
Florin Coras99368312018-08-02 10:45:44 -07001823 case SESSION_CTRL_EVT_CONNECTED:
1824 connected_msg = (session_connected_msg_t *) e->data;
1825 vcl_session_connected_handler (connected_msg);
1826 break;
Florin Coras54693d22018-07-17 10:46:29 -07001827 case SESSION_CTRL_EVT_DISCONNECTED:
1828 disconnected_msg = (session_disconnected_msg_t *) e->data;
1829 sid = vcl_session_get_index_from_handle (disconnected_msg->handle);
1830 if (sid < n_bits && except_map)
1831 {
1832 clib_bitmap_set_no_check (except_map, sid, 1);
1833 *bits_set += 1;
1834 }
1835 break;
Florin Corasc9fbd662018-08-24 12:59:56 -07001836 case SESSION_CTRL_EVT_RESET:
Florin Coras60116992018-08-27 09:52:18 -07001837 sid = vcl_session_reset_handler ((session_reset_msg_t *) e->data);
Florin Corasc9fbd662018-08-24 12:59:56 -07001838 if (sid < n_bits && except_map)
1839 {
1840 clib_bitmap_set_no_check (except_map, sid, 1);
1841 *bits_set += 1;
1842 }
1843 break;
Florin Coras54693d22018-07-17 10:46:29 -07001844 default:
1845 clib_warning ("unhandled: %u", e->event_type);
1846 break;
1847 }
Florin Coras99368312018-08-02 10:45:44 -07001848 svm_msg_q_free_msg (mq, msg);
Florin Coras54693d22018-07-17 10:46:29 -07001849 }
1850
Florin Coras99368312018-08-02 10:45:44 -07001851 vec_reset_length (vcm->mq_msg_vector);
Florin Coras54693d22018-07-17 10:46:29 -07001852 return *bits_set;
Dave Wallace543852a2017-08-03 02:11:34 -04001853}
1854
Florin Coras99368312018-08-02 10:45:44 -07001855static int
1856vppcom_select_condvar (unsigned long n_bits, unsigned long *read_map,
1857 unsigned long *write_map, unsigned long *except_map,
1858 double time_to_wait, u32 * bits_set)
1859{
1860 double total_wait = 0, wait_slice;
1861 vcl_cut_through_registration_t *cr;
1862
1863 time_to_wait = (time_to_wait == -1) ? 10e9 : time_to_wait;
1864 wait_slice = vcm->cut_through_registrations ? 10e-6 : time_to_wait;
1865 do
1866 {
1867 /* *INDENT-OFF* */
1868 pool_foreach (cr, vcm->cut_through_registrations, ({
1869 vcl_select_handle_mq (cr->mq, n_bits, read_map, write_map, except_map,
1870 0, bits_set);
1871 }));
1872 /* *INDENT-ON* */
1873
1874 vcl_select_handle_mq (vcm->app_event_queue, n_bits, read_map, write_map,
1875 except_map, time_to_wait, bits_set);
1876 total_wait += wait_slice;
1877 if (*bits_set)
1878 return *bits_set;
1879 }
1880 while (total_wait < time_to_wait);
1881
1882 return 0;
1883}
1884
1885static int
1886vppcom_select_eventfd (unsigned long n_bits, unsigned long *read_map,
1887 unsigned long *write_map, unsigned long *except_map,
1888 double time_to_wait, u32 * bits_set)
1889{
1890 vcl_mq_evt_conn_t *mqc;
1891 int __clib_unused n_read;
1892 int n_mq_evts, i;
1893 u64 buf;
1894
1895 vec_validate (vcm->mq_events, pool_elts (vcm->mq_evt_conns));
1896 n_mq_evts = epoll_wait (vcm->mqs_epfd, vcm->mq_events,
1897 vec_len (vcm->mq_events), time_to_wait);
1898 for (i = 0; i < n_mq_evts; i++)
1899 {
1900 mqc = vcl_mq_evt_conn_get (vcm->mq_events[i].data.u32);
1901 n_read = read (mqc->mq_fd, &buf, sizeof (buf));
1902 vcl_select_handle_mq (mqc->mq, n_bits, read_map, write_map,
1903 except_map, 0, bits_set);
1904 }
1905
1906 return (n_mq_evts > 0 ? (int) *bits_set : 0);
1907}
1908
Dave Wallace543852a2017-08-03 02:11:34 -04001909int
1910vppcom_select (unsigned long n_bits, unsigned long *read_map,
1911 unsigned long *write_map, unsigned long *except_map,
1912 double time_to_wait)
1913{
Florin Coras54693d22018-07-17 10:46:29 -07001914 u32 sid, minbits = clib_max (n_bits, BITS (uword)), bits_set = 0;
Florin Coras7e12d942018-06-27 14:32:43 -07001915 vcl_session_t *session = 0;
Florin Coras54693d22018-07-17 10:46:29 -07001916 int rv;
Dave Wallace543852a2017-08-03 02:11:34 -04001917
1918 ASSERT (sizeof (clib_bitmap_t) == sizeof (long int));
1919
Dave Wallace7876d392017-10-19 03:53:57 -04001920 if (n_bits && read_map)
Dave Wallace543852a2017-08-03 02:11:34 -04001921 {
1922 clib_bitmap_validate (vcm->rd_bitmap, minbits);
Dave Wallace048b1d62018-01-03 22:24:41 -05001923 clib_memcpy (vcm->rd_bitmap, read_map,
1924 vec_len (vcm->rd_bitmap) * sizeof (clib_bitmap_t));
1925 memset (read_map, 0, vec_len (vcm->rd_bitmap) * sizeof (clib_bitmap_t));
Dave Wallace543852a2017-08-03 02:11:34 -04001926 }
Dave Wallace7876d392017-10-19 03:53:57 -04001927 if (n_bits && write_map)
Dave Wallace543852a2017-08-03 02:11:34 -04001928 {
1929 clib_bitmap_validate (vcm->wr_bitmap, minbits);
Dave Wallace048b1d62018-01-03 22:24:41 -05001930 clib_memcpy (vcm->wr_bitmap, write_map,
1931 vec_len (vcm->wr_bitmap) * sizeof (clib_bitmap_t));
1932 memset (write_map, 0,
1933 vec_len (vcm->wr_bitmap) * sizeof (clib_bitmap_t));
Dave Wallace543852a2017-08-03 02:11:34 -04001934 }
Dave Wallace7876d392017-10-19 03:53:57 -04001935 if (n_bits && except_map)
Dave Wallace543852a2017-08-03 02:11:34 -04001936 {
1937 clib_bitmap_validate (vcm->ex_bitmap, minbits);
Dave Wallace048b1d62018-01-03 22:24:41 -05001938 clib_memcpy (vcm->ex_bitmap, except_map,
1939 vec_len (vcm->ex_bitmap) * sizeof (clib_bitmap_t));
1940 memset (except_map, 0,
1941 vec_len (vcm->ex_bitmap) * sizeof (clib_bitmap_t));
Dave Wallace543852a2017-08-03 02:11:34 -04001942 }
1943
Florin Coras54693d22018-07-17 10:46:29 -07001944 if (!n_bits)
1945 return 0;
1946
1947 if (!write_map)
1948 goto check_rd;
1949
1950 /* *INDENT-OFF* */
1951 clib_bitmap_foreach (sid, vcm->wr_bitmap, ({
Florin Coras54693d22018-07-17 10:46:29 -07001952 if (!(session = vcl_session_get (sid)))
1953 {
Florin Coras54693d22018-07-17 10:46:29 -07001954 VDBG (0, "VCL<%d>: session %d specified in write_map is closed.",
1955 getpid (), sid);
1956 return VPPCOM_EBADFD;
1957 }
1958
1959 rv = svm_fifo_is_full (session->tx_fifo);
Florin Coras54693d22018-07-17 10:46:29 -07001960 if (!rv)
1961 {
1962 clib_bitmap_set_no_check (write_map, sid, 1);
1963 bits_set++;
1964 }
1965 }));
1966
1967check_rd:
1968 if (!read_map)
1969 goto check_mq;
Florin Coras99368312018-08-02 10:45:44 -07001970
Florin Coras54693d22018-07-17 10:46:29 -07001971 clib_bitmap_foreach (sid, vcm->rd_bitmap, ({
Florin Coras54693d22018-07-17 10:46:29 -07001972 if (!(session = vcl_session_get (sid)))
1973 {
Florin Coras54693d22018-07-17 10:46:29 -07001974 VDBG (0, "VCL<%d>: session %d specified in write_map is closed.",
1975 getpid (), sid);
1976 return VPPCOM_EBADFD;
1977 }
1978
1979 rv = vppcom_session_read_ready (session);
Florin Coras54693d22018-07-17 10:46:29 -07001980 if (rv)
1981 {
1982 clib_bitmap_set_no_check (read_map, sid, 1);
1983 bits_set++;
1984 }
1985 }));
1986 /* *INDENT-ON* */
1987
1988check_mq:
Dave Wallace543852a2017-08-03 02:11:34 -04001989
Florin Coras99368312018-08-02 10:45:44 -07001990 if (vcm->cfg.use_mq_eventfd)
1991 vppcom_select_eventfd (n_bits, read_map, write_map, except_map,
1992 time_to_wait, &bits_set);
1993 else
1994 vppcom_select_condvar (n_bits, read_map, write_map, except_map,
1995 time_to_wait, &bits_set);
Florin Coras54693d22018-07-17 10:46:29 -07001996
Dave Wallace543852a2017-08-03 02:11:34 -04001997 return (bits_set);
1998}
1999
Dave Wallacef7f809c2017-10-03 01:48:42 -04002000static inline void
2001vep_verify_epoll_chain (u32 vep_idx)
2002{
Florin Coras7e12d942018-06-27 14:32:43 -07002003 vcl_session_t *session;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002004 vppcom_epoll_t *vep;
2005 int rv;
Dave Wallace498b3a52017-11-09 13:00:34 -05002006 u32 sid = vep_idx;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002007
Dave Wallace498b3a52017-11-09 13:00:34 -05002008 if (VPPCOM_DEBUG <= 1)
Dave Wallacef7f809c2017-10-03 01:48:42 -04002009 return;
2010
2011 /* Assumes caller has acquired spinlock: vcm->sessions_lockp */
2012 rv = vppcom_session_at_index (vep_idx, &session);
2013 if (PREDICT_FALSE (rv))
2014 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002015 clib_warning ("VCL<%d>: ERROR: Invalid vep_idx (%u)!",
2016 getpid (), vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002017 goto done;
2018 }
2019 if (PREDICT_FALSE (!session->is_vep))
2020 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002021 clib_warning ("VCL<%d>: ERROR: vep_idx (%u) is not a vep!",
2022 getpid (), vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002023 goto done;
2024 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05002025 vep = &session->vep;
Dave Wallace048b1d62018-01-03 22:24:41 -05002026 clib_warning ("VCL<%d>: vep_idx (%u): Dumping epoll chain\n"
Dave Wallace498b3a52017-11-09 13:00:34 -05002027 "{\n"
2028 " is_vep = %u\n"
2029 " is_vep_session = %u\n"
Dave Wallace4878cbe2017-11-21 03:45:09 -05002030 " next_sid = 0x%x (%u)\n"
Dave Wallace498b3a52017-11-09 13:00:34 -05002031 " wait_cont_idx = 0x%x (%u)\n"
Dave Wallace4878cbe2017-11-21 03:45:09 -05002032 "}\n", getpid (), vep_idx,
2033 session->is_vep, session->is_vep_session,
2034 vep->next_sid, vep->next_sid,
Dave Wallace498b3a52017-11-09 13:00:34 -05002035 session->wait_cont_idx, session->wait_cont_idx);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002036
2037 for (sid = vep->next_sid; sid != ~0; sid = vep->next_sid)
Dave Wallacef7f809c2017-10-03 01:48:42 -04002038 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05002039 rv = vppcom_session_at_index (sid, &session);
2040 if (PREDICT_FALSE (rv))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002041 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002042 clib_warning ("VCL<%d>: ERROR: Invalid sid (%u)!", getpid (), sid);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002043 goto done;
2044 }
2045 if (PREDICT_FALSE (session->is_vep))
Dave Wallace048b1d62018-01-03 22:24:41 -05002046 clib_warning ("VCL<%d>: ERROR: sid (%u) is a vep!",
2047 getpid (), vep_idx);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002048 else if (PREDICT_FALSE (!session->is_vep_session))
2049 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002050 clib_warning ("VCL<%d>: ERROR: session (%u) "
2051 "is not a vep session!", getpid (), sid);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002052 goto done;
2053 }
2054 vep = &session->vep;
2055 if (PREDICT_FALSE (vep->vep_idx != vep_idx))
Dave Wallace048b1d62018-01-03 22:24:41 -05002056 clib_warning ("VCL<%d>: ERROR: session (%u) vep_idx (%u) != "
Dave Wallace4878cbe2017-11-21 03:45:09 -05002057 "vep_idx (%u)!", getpid (),
2058 sid, session->vep.vep_idx, vep_idx);
2059 if (session->is_vep_session)
2060 {
2061 clib_warning ("vep_idx[%u]: sid 0x%x (%u)\n"
2062 "{\n"
2063 " next_sid = 0x%x (%u)\n"
2064 " prev_sid = 0x%x (%u)\n"
2065 " vep_idx = 0x%x (%u)\n"
2066 " ev.events = 0x%x\n"
2067 " ev.data.u64 = 0x%llx\n"
2068 " et_mask = 0x%x\n"
2069 "}\n",
2070 vep_idx, sid, sid,
2071 vep->next_sid, vep->next_sid,
2072 vep->prev_sid, vep->prev_sid,
2073 vep->vep_idx, vep->vep_idx,
2074 vep->ev.events, vep->ev.data.u64, vep->et_mask);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002075 }
2076 }
Dave Wallacef7f809c2017-10-03 01:48:42 -04002077
2078done:
Dave Wallace048b1d62018-01-03 22:24:41 -05002079 clib_warning ("VCL<%d>: vep_idx (%u): Dump complete!\n",
2080 getpid (), vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002081}
2082
2083int
2084vppcom_epoll_create (void)
2085{
Florin Coras7e12d942018-06-27 14:32:43 -07002086 vcl_session_t *vep_session;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002087 u32 vep_idx;
2088
Dave Wallace7e607a72018-06-18 18:41:32 -04002089 VCL_SESSION_LOCK ();
Dave Wallacef7f809c2017-10-03 01:48:42 -04002090 pool_get (vcm->sessions, vep_session);
2091 memset (vep_session, 0, sizeof (*vep_session));
2092 vep_idx = vep_session - vcm->sessions;
2093
2094 vep_session->is_vep = 1;
2095 vep_session->vep.vep_idx = ~0;
2096 vep_session->vep.next_sid = ~0;
2097 vep_session->vep.prev_sid = ~0;
2098 vep_session->wait_cont_idx = ~0;
Dave Wallace4878cbe2017-11-21 03:45:09 -05002099 vep_session->vpp_handle = ~0;
Keith Burns (alagalah)12756512018-03-06 05:55:27 -08002100 vep_session->poll_reg = 0;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002101
Florin Coras0d427d82018-06-27 03:24:07 -07002102 vcl_evt (VCL_EVT_EPOLL_CREATE, vep_session, vep_idx);
Dave Wallace7e607a72018-06-18 18:41:32 -04002103 VCL_SESSION_UNLOCK ();
Dave Wallacef7f809c2017-10-03 01:48:42 -04002104
Florin Coras0d427d82018-06-27 03:24:07 -07002105 VDBG (0, "VCL<%d>: Created vep_idx %u / sid %u!",
2106 getpid (), vep_idx, vep_idx);
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002107
Dave Wallacef7f809c2017-10-03 01:48:42 -04002108 return (vep_idx);
2109}
2110
2111int
2112vppcom_epoll_ctl (uint32_t vep_idx, int op, uint32_t session_index,
2113 struct epoll_event *event)
2114{
Florin Coras7e12d942018-06-27 14:32:43 -07002115 vcl_session_t *vep_session;
2116 vcl_session_t *session;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002117 int rv;
2118
2119 if (vep_idx == session_index)
2120 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002121 clib_warning ("VCL<%d>: ERROR: vep_idx == session_index (%u)!",
Dave Wallace4878cbe2017-11-21 03:45:09 -05002122 getpid (), vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002123 return VPPCOM_EINVAL;
2124 }
2125
Dave Wallace7e607a72018-06-18 18:41:32 -04002126 VCL_SESSION_LOCK ();
Dave Wallacef7f809c2017-10-03 01:48:42 -04002127 rv = vppcom_session_at_index (vep_idx, &vep_session);
2128 if (PREDICT_FALSE (rv))
2129 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002130 clib_warning ("VCL<%d>: ERROR: Invalid vep_idx (%u)!", vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002131 goto done;
2132 }
2133 if (PREDICT_FALSE (!vep_session->is_vep))
2134 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002135 clib_warning ("VCL<%d>: ERROR: vep_idx (%u) is not a vep!",
Dave Wallace4878cbe2017-11-21 03:45:09 -05002136 getpid (), vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002137 rv = VPPCOM_EINVAL;
2138 goto done;
2139 }
2140
2141 ASSERT (vep_session->vep.vep_idx == ~0);
2142 ASSERT (vep_session->vep.prev_sid == ~0);
2143
2144 rv = vppcom_session_at_index (session_index, &session);
2145 if (PREDICT_FALSE (rv))
2146 {
Florin Coras0d427d82018-06-27 03:24:07 -07002147 VDBG (0, "VCL<%d>: ERROR: Invalid session_index (%u)!",
2148 getpid (), session_index);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002149 goto done;
2150 }
2151 if (PREDICT_FALSE (session->is_vep))
2152 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05002153 clib_warning ("ERROR: session_index (%u) is a vep!", vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002154 rv = VPPCOM_EINVAL;
2155 goto done;
2156 }
2157
2158 switch (op)
2159 {
2160 case EPOLL_CTL_ADD:
2161 if (PREDICT_FALSE (!event))
2162 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002163 clib_warning ("VCL<%d>: ERROR: EPOLL_CTL_ADD: NULL pointer to "
Dave Wallace2e005bb2017-11-07 01:21:39 -05002164 "epoll_event structure!", getpid ());
Dave Wallacef7f809c2017-10-03 01:48:42 -04002165 rv = VPPCOM_EINVAL;
2166 goto done;
2167 }
2168 if (vep_session->vep.next_sid != ~0)
2169 {
Florin Coras7e12d942018-06-27 14:32:43 -07002170 vcl_session_t *next_session;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002171 rv = vppcom_session_at_index (vep_session->vep.next_sid,
2172 &next_session);
2173 if (PREDICT_FALSE (rv))
2174 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002175 clib_warning ("VCL<%d>: ERROR: EPOLL_CTL_ADD: Invalid "
Dave Wallace4878cbe2017-11-21 03:45:09 -05002176 "vep.next_sid (%u) on vep_idx (%u)!",
2177 getpid (), vep_session->vep.next_sid, vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002178 goto done;
2179 }
2180 ASSERT (next_session->vep.prev_sid == vep_idx);
2181 next_session->vep.prev_sid = session_index;
2182 }
2183 session->vep.next_sid = vep_session->vep.next_sid;
2184 session->vep.prev_sid = vep_idx;
2185 session->vep.vep_idx = vep_idx;
2186 session->vep.et_mask = VEP_DEFAULT_ET_MASK;
2187 session->vep.ev = *event;
Dave Wallace4878cbe2017-11-21 03:45:09 -05002188 session->is_vep = 0;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002189 session->is_vep_session = 1;
2190 vep_session->vep.next_sid = session_index;
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002191
2192 /* VCL Event Register handler */
Florin Coras7e12d942018-06-27 14:32:43 -07002193 if (session->session_state & STATE_LISTEN)
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002194 {
2195 /* Register handler for connect_request event on listen_session_index */
2196 vce_event_key_t evk;
2197 evk.session_index = session_index;
2198 evk.eid = VCL_EVENT_CONNECT_REQ_ACCEPTED;
Keith Burns (alagalah)12756512018-03-06 05:55:27 -08002199 vep_session->poll_reg =
2200 vce_register_handler (&vcm->event_thread, &evk,
Keith Burns (alagalah)0d2b0d52018-03-06 15:55:22 -08002201 vce_poll_wait_connect_request_handler_fn,
2202 0 /* No callback args */ );
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002203 }
Florin Coras0d427d82018-06-27 03:24:07 -07002204 VDBG (1, "VCL<%d>: EPOLL_CTL_ADD: vep_idx %u, "
2205 "sid %u, events 0x%x, data 0x%llx!",
2206 getpid (), vep_idx, session_index,
2207 event->events, event->data.u64);
2208 vcl_evt (VCL_EVT_EPOLL_CTLADD, session, event->events, event->data.u64);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002209 break;
2210
2211 case EPOLL_CTL_MOD:
2212 if (PREDICT_FALSE (!event))
2213 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002214 clib_warning ("VCL<%d>: ERROR: EPOLL_CTL_MOD: NULL pointer to "
Dave Wallace2e005bb2017-11-07 01:21:39 -05002215 "epoll_event structure!", getpid ());
Dave Wallacef7f809c2017-10-03 01:48:42 -04002216 rv = VPPCOM_EINVAL;
2217 goto done;
2218 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05002219 else if (PREDICT_FALSE (!session->is_vep_session))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002220 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002221 clib_warning ("VCL<%d>: ERROR: sid %u EPOLL_CTL_MOD: "
Dave Wallace4878cbe2017-11-21 03:45:09 -05002222 "not a vep session!", getpid (), session_index);
2223 rv = VPPCOM_EINVAL;
2224 goto done;
2225 }
2226 else if (PREDICT_FALSE (session->vep.vep_idx != vep_idx))
2227 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002228 clib_warning ("VCL<%d>: ERROR: sid %u EPOLL_CTL_MOD: "
Dave Wallace4878cbe2017-11-21 03:45:09 -05002229 "vep_idx (%u) != vep_idx (%u)!",
2230 getpid (), session_index,
2231 session->vep.vep_idx, vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002232 rv = VPPCOM_EINVAL;
2233 goto done;
2234 }
2235 session->vep.et_mask = VEP_DEFAULT_ET_MASK;
2236 session->vep.ev = *event;
Florin Coras0d427d82018-06-27 03:24:07 -07002237 VDBG (1, "VCL<%d>: EPOLL_CTL_MOD: vep_idx %u, sid %u, events 0x%x,"
2238 " data 0x%llx!", getpid (), vep_idx, session_index, event->events,
2239 event->data.u64);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002240 break;
2241
2242 case EPOLL_CTL_DEL:
Dave Wallace4878cbe2017-11-21 03:45:09 -05002243 if (PREDICT_FALSE (!session->is_vep_session))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002244 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002245 clib_warning ("VCL<%d>: ERROR: sid %u EPOLL_CTL_DEL: "
Dave Wallace4878cbe2017-11-21 03:45:09 -05002246 "not a vep session!", getpid (), session_index);
2247 rv = VPPCOM_EINVAL;
2248 goto done;
2249 }
2250 else if (PREDICT_FALSE (session->vep.vep_idx != vep_idx))
2251 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002252 clib_warning ("VCL<%d>: ERROR: sid %u EPOLL_CTL_DEL: "
Dave Wallace4878cbe2017-11-21 03:45:09 -05002253 "vep_idx (%u) != vep_idx (%u)!",
2254 getpid (), session_index,
2255 session->vep.vep_idx, vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002256 rv = VPPCOM_EINVAL;
2257 goto done;
2258 }
2259
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002260 /* VCL Event Un-register handler */
Florin Coras7e12d942018-06-27 14:32:43 -07002261 if ((session->session_state & STATE_LISTEN) && vep_session->poll_reg)
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002262 {
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08002263 (void) vce_unregister_handler (&vcm->event_thread,
2264 vep_session->poll_reg);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002265 }
2266
Dave Wallacef7f809c2017-10-03 01:48:42 -04002267 vep_session->wait_cont_idx =
2268 (vep_session->wait_cont_idx == session_index) ?
2269 session->vep.next_sid : vep_session->wait_cont_idx;
2270
2271 if (session->vep.prev_sid == vep_idx)
2272 vep_session->vep.next_sid = session->vep.next_sid;
2273 else
2274 {
Florin Coras7e12d942018-06-27 14:32:43 -07002275 vcl_session_t *prev_session;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002276 rv = vppcom_session_at_index (session->vep.prev_sid, &prev_session);
2277 if (PREDICT_FALSE (rv))
2278 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002279 clib_warning ("VCL<%d>: ERROR: EPOLL_CTL_DEL: Invalid "
Dave Wallace4878cbe2017-11-21 03:45:09 -05002280 "vep.prev_sid (%u) on sid (%u)!",
2281 getpid (), session->vep.prev_sid, session_index);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002282 goto done;
2283 }
2284 ASSERT (prev_session->vep.next_sid == session_index);
2285 prev_session->vep.next_sid = session->vep.next_sid;
2286 }
2287 if (session->vep.next_sid != ~0)
2288 {
Florin Coras7e12d942018-06-27 14:32:43 -07002289 vcl_session_t *next_session;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002290 rv = vppcom_session_at_index (session->vep.next_sid, &next_session);
2291 if (PREDICT_FALSE (rv))
2292 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002293 clib_warning ("VCL<%d>: ERROR: EPOLL_CTL_DEL: Invalid "
Dave Wallace4878cbe2017-11-21 03:45:09 -05002294 "vep.next_sid (%u) on sid (%u)!",
2295 getpid (), session->vep.next_sid, session_index);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002296 goto done;
2297 }
2298 ASSERT (next_session->vep.prev_sid == session_index);
2299 next_session->vep.prev_sid = session->vep.prev_sid;
2300 }
2301
2302 memset (&session->vep, 0, sizeof (session->vep));
2303 session->vep.next_sid = ~0;
2304 session->vep.prev_sid = ~0;
2305 session->vep.vep_idx = ~0;
2306 session->is_vep_session = 0;
Florin Coras0d427d82018-06-27 03:24:07 -07002307 VDBG (1, "VCL<%d>: EPOLL_CTL_DEL: vep_idx %u, sid %u!",
2308 getpid (), vep_idx, session_index);
2309 vcl_evt (VCL_EVT_EPOLL_CTLDEL, session, vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002310 break;
2311
2312 default:
Dave Wallace048b1d62018-01-03 22:24:41 -05002313 clib_warning ("VCL<%d>: ERROR: Invalid operation (%d)!", getpid (), op);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002314 rv = VPPCOM_EINVAL;
2315 }
2316
2317 vep_verify_epoll_chain (vep_idx);
2318
2319done:
Dave Wallace7e607a72018-06-18 18:41:32 -04002320 VCL_SESSION_UNLOCK ();
Dave Wallacef7f809c2017-10-03 01:48:42 -04002321 return rv;
2322}
2323
Florin Coras54693d22018-07-17 10:46:29 -07002324static int
2325vcl_epoll_wait_handle_mq (svm_msg_q_t * mq, struct epoll_event *events,
2326 u32 maxevents, double wait_for_time, u32 * num_ev)
2327{
2328 session_disconnected_msg_t *disconnected_msg;
2329 session_connected_msg_t *connected_msg;
2330 session_accepted_msg_t *accepted_msg;
Florin Coras54693d22018-07-17 10:46:29 -07002331 u64 session_evt_data = ~0, handle;
Florin Coras99368312018-08-02 10:45:44 -07002332 u32 sid = ~0, session_events;
Florin Coras54693d22018-07-17 10:46:29 -07002333 vcl_session_msg_t *vcl_msg;
2334 vcl_session_t *session;
Florin Coras99368312018-08-02 10:45:44 -07002335 svm_msg_q_msg_t *msg;
Florin Coras54693d22018-07-17 10:46:29 -07002336 session_event_t *e;
2337 u8 add_event;
2338 int i;
2339
2340 svm_msg_q_lock (mq);
2341 if (svm_msg_q_is_empty (mq))
2342 {
2343 if (!wait_for_time)
2344 {
2345 svm_msg_q_unlock (mq);
2346 return 0;
2347 }
2348 else if (wait_for_time < 0)
2349 {
2350 svm_msg_q_wait (mq);
2351 }
2352 else
2353 {
Florin Coras60f1fc12018-08-16 14:57:31 -07002354 if (svm_msg_q_timedwait (mq, wait_for_time / 1e3))
Florin Coras54693d22018-07-17 10:46:29 -07002355 {
2356 svm_msg_q_unlock (mq);
2357 return 0;
2358 }
2359 }
2360 }
Florin Coras99368312018-08-02 10:45:44 -07002361 vcl_mq_dequeue_batch (mq);
Florin Coras54693d22018-07-17 10:46:29 -07002362 svm_msg_q_unlock (mq);
2363
Florin Coras99368312018-08-02 10:45:44 -07002364 for (i = 0; i < vec_len (vcm->mq_msg_vector); i++)
Florin Coras54693d22018-07-17 10:46:29 -07002365 {
Florin Coras99368312018-08-02 10:45:44 -07002366 msg = vec_elt_at_index (vcm->mq_msg_vector, i);
2367 e = svm_msg_q_msg_data (mq, msg);
Florin Coras54693d22018-07-17 10:46:29 -07002368 add_event = 0;
2369 switch (e->event_type)
2370 {
2371 case FIFO_EVENT_APP_RX:
2372 sid = e->fifo->client_session_index;
Florin Coras54693d22018-07-17 10:46:29 -07002373 session = vcl_session_get (sid);
2374 session_events = session->vep.ev.events;
Florin Coras99368312018-08-02 10:45:44 -07002375 if (!(EPOLLIN & session->vep.ev.events))
2376 break;
Florin Coras60f1fc12018-08-16 14:57:31 -07002377 add_event = 1;
2378 events[*num_ev].events |= EPOLLIN;
2379 session_evt_data = session->vep.ev.data.u64;
Florin Coras54693d22018-07-17 10:46:29 -07002380 break;
2381 case FIFO_EVENT_APP_TX:
2382 sid = e->fifo->client_session_index;
Florin Coras54693d22018-07-17 10:46:29 -07002383 session = vcl_session_get (sid);
2384 session_events = session->vep.ev.events;
Florin Coras99368312018-08-02 10:45:44 -07002385 if (!(EPOLLOUT & session_events))
2386 break;
Florin Coras60f1fc12018-08-16 14:57:31 -07002387 add_event = 1;
2388 events[*num_ev].events |= EPOLLOUT;
2389 session_evt_data = session->vep.ev.data.u64;
Florin Coras54693d22018-07-17 10:46:29 -07002390 break;
2391 case SESSION_IO_EVT_CT_TX:
2392 session = vcl_ct_session_get_from_fifo (e->fifo, 0);
2393 sid = vcl_session_index (session);
2394 session_events = session->vep.ev.events;
Florin Coras99368312018-08-02 10:45:44 -07002395 if (!(EPOLLIN & session->vep.ev.events))
2396 break;
Florin Coras60f1fc12018-08-16 14:57:31 -07002397 add_event = 1;
2398 events[*num_ev].events |= EPOLLIN;
2399 session_evt_data = session->vep.ev.data.u64;
Florin Coras54693d22018-07-17 10:46:29 -07002400 break;
2401 case SESSION_IO_EVT_CT_RX:
2402 session = vcl_ct_session_get_from_fifo (e->fifo, 1);
2403 sid = vcl_session_index (session);
2404 session_events = session->vep.ev.events;
Florin Coras99368312018-08-02 10:45:44 -07002405 if (!(EPOLLOUT & session_events))
2406 break;
Florin Coras60f1fc12018-08-16 14:57:31 -07002407 add_event = 1;
2408 events[*num_ev].events |= EPOLLOUT;
2409 session_evt_data = session->vep.ev.data.u64;
Florin Coras54693d22018-07-17 10:46:29 -07002410 break;
2411 case SESSION_CTRL_EVT_ACCEPTED:
2412 accepted_msg = (session_accepted_msg_t *) e->data;
2413 handle = accepted_msg->listener_handle;
2414 session = vppcom_session_table_lookup_listener (handle);
2415 if (!session)
2416 {
2417 clib_warning ("VCL<%d>: ERROR: couldn't find listen session:"
2418 "listener handle %llx", getpid (), handle);
2419 break;
2420 }
2421
2422 clib_fifo_add2 (session->accept_evts_fifo, vcl_msg);
2423 vcl_msg->accepted_msg = *accepted_msg;
2424 session_events = session->vep.ev.events;
2425 if (!(EPOLLIN & session_events))
2426 break;
2427
2428 add_event = 1;
2429 events[*num_ev].events |= EPOLLIN;
2430 session_evt_data = session->vep.ev.data.u64;
2431 break;
2432 case SESSION_CTRL_EVT_CONNECTED:
2433 connected_msg = (session_connected_msg_t *) e->data;
2434 vcl_session_connected_handler (connected_msg);
2435 /* Generate EPOLLOUT because there's no connected event */
2436 sid = vcl_session_get_index_from_handle (connected_msg->handle);
2437 clib_spinlock_lock (&vcm->sessions_lockp);
2438 session = vcl_session_get (sid);
2439 session_events = session->vep.ev.events;
2440 if (EPOLLOUT & session_events)
2441 {
2442 add_event = 1;
2443 events[*num_ev].events |= EPOLLOUT;
2444 session_evt_data = session->vep.ev.data.u64;
2445 }
2446 clib_spinlock_unlock (&vcm->sessions_lockp);
2447 break;
2448 case SESSION_CTRL_EVT_DISCONNECTED:
2449 disconnected_msg = (session_disconnected_msg_t *) e->data;
2450 sid = vcl_session_get_index_from_handle (disconnected_msg->handle);
2451 clib_spinlock_lock (&vcm->sessions_lockp);
Florin Corasc9fbd662018-08-24 12:59:56 -07002452 if (!(session = vcl_session_get (sid)))
2453 break;
Florin Coras54693d22018-07-17 10:46:29 -07002454 add_event = 1;
2455 events[*num_ev].events |= EPOLLHUP | EPOLLRDHUP;
2456 session_evt_data = session->vep.ev.data.u64;
2457 session_events = session->vep.ev.events;
2458 clib_spinlock_unlock (&vcm->sessions_lockp);
2459 break;
Florin Corasc9fbd662018-08-24 12:59:56 -07002460 case SESSION_CTRL_EVT_RESET:
Florin Coras60116992018-08-27 09:52:18 -07002461 sid = vcl_session_reset_handler ((session_reset_msg_t *) e->data);
Florin Corasc9fbd662018-08-24 12:59:56 -07002462 if (!(session = vcl_session_get (sid)))
2463 break;
2464 add_event = 1;
2465 events[*num_ev].events |= EPOLLHUP | EPOLLRDHUP;
2466 session_evt_data = session->vep.ev.data.u64;
2467 session_events = session->vep.ev.events;
2468 break;
Florin Coras54693d22018-07-17 10:46:29 -07002469 default:
2470 clib_warning ("unhandled: %u", e->event_type);
Florin Coras99368312018-08-02 10:45:44 -07002471 svm_msg_q_free_msg (mq, msg);
Florin Coras54693d22018-07-17 10:46:29 -07002472 continue;
2473 }
Florin Coras99368312018-08-02 10:45:44 -07002474 svm_msg_q_free_msg (mq, msg);
Florin Coras54693d22018-07-17 10:46:29 -07002475
2476 if (add_event)
2477 {
2478 events[*num_ev].data.u64 = session_evt_data;
2479 if (EPOLLONESHOT & session_events)
2480 {
2481 clib_spinlock_lock (&vcm->sessions_lockp);
2482 session = vcl_session_get (sid);
2483 session->vep.ev.events = 0;
2484 clib_spinlock_unlock (&vcm->sessions_lockp);
2485 }
2486 *num_ev += 1;
2487 if (*num_ev == maxevents)
2488 break;
2489 }
2490 }
Florin Coras99368312018-08-02 10:45:44 -07002491
2492 vec_reset_length (vcm->mq_msg_vector);
Florin Coras54693d22018-07-17 10:46:29 -07002493 return *num_ev;
2494}
2495
Florin Coras99368312018-08-02 10:45:44 -07002496static int
2497vppcom_epoll_wait_condvar (struct epoll_event *events, int maxevents,
2498 double wait_for_time)
2499{
2500 vcl_cut_through_registration_t *cr;
2501 double total_wait = 0, wait_slice;
2502 u32 num_ev = 0;
2503 int rv;
2504
2505 wait_for_time = (wait_for_time == -1) ? (double) 10e9 : wait_for_time;
2506 wait_slice = vcm->cut_through_registrations ? 10e-6 : wait_for_time;
2507
2508 do
2509 {
2510 /* *INDENT-OFF* */
2511 pool_foreach (cr, vcm->cut_through_registrations, ({
2512 vcl_epoll_wait_handle_mq (cr->mq, events, maxevents, 0, &num_ev);
2513 }));
2514 /* *INDENT-ON* */
2515
2516 rv = vcl_epoll_wait_handle_mq (vcm->app_event_queue, events, maxevents,
2517 num_ev ? 0 : wait_slice, &num_ev);
2518 if (rv)
2519 total_wait += wait_slice;
2520 if (num_ev)
2521 return num_ev;
2522 }
2523 while (total_wait < wait_for_time);
2524 return (int) num_ev;
2525}
2526
2527static int
2528vppcom_epoll_wait_eventfd (struct epoll_event *events, int maxevents,
2529 double wait_for_time)
2530{
2531 vcl_mq_evt_conn_t *mqc;
2532 int __clib_unused n_read;
2533 int n_mq_evts, i;
2534 u32 n_evts = 0;
2535 u64 buf;
2536
2537 vec_validate (vcm->mq_events, pool_elts (vcm->mq_evt_conns));
2538 n_mq_evts = epoll_wait (vcm->mqs_epfd, vcm->mq_events,
2539 vec_len (vcm->mq_events), wait_for_time);
2540 for (i = 0; i < n_mq_evts; i++)
2541 {
2542 mqc = vcl_mq_evt_conn_get (vcm->mq_events[i].data.u32);
2543 n_read = read (mqc->mq_fd, &buf, sizeof (buf));
2544 vcl_epoll_wait_handle_mq (mqc->mq, events, maxevents, 0, &n_evts);
2545 }
2546
2547 return (int) n_evts;
2548}
2549
Dave Wallacef7f809c2017-10-03 01:48:42 -04002550int
2551vppcom_epoll_wait (uint32_t vep_idx, struct epoll_event *events,
2552 int maxevents, double wait_for_time)
2553{
Florin Coras7e12d942018-06-27 14:32:43 -07002554 vcl_session_t *vep_session;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002555
2556 if (PREDICT_FALSE (maxevents <= 0))
2557 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002558 clib_warning ("VCL<%d>: ERROR: Invalid maxevents (%d)!",
Dave Wallace4878cbe2017-11-21 03:45:09 -05002559 getpid (), maxevents);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002560 return VPPCOM_EINVAL;
2561 }
Dave Wallacef7f809c2017-10-03 01:48:42 -04002562
Florin Coras54693d22018-07-17 10:46:29 -07002563 clib_spinlock_lock (&vcm->sessions_lockp);
2564 vep_session = vcl_session_get (vep_idx);
2565 if (PREDICT_FALSE (!vep_session->is_vep))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002566 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002567 clib_warning ("VCL<%d>: ERROR: vep_idx (%u) is not a vep!",
Dave Wallace4878cbe2017-11-21 03:45:09 -05002568 getpid (), vep_idx);
Florin Coras54693d22018-07-17 10:46:29 -07002569 clib_spinlock_unlock (&vcm->sessions_lockp);
2570 return VPPCOM_EINVAL;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002571 }
Florin Coras54693d22018-07-17 10:46:29 -07002572 clib_spinlock_unlock (&vcm->sessions_lockp);
2573
2574 memset (events, 0, sizeof (*events) * maxevents);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002575
Florin Coras99368312018-08-02 10:45:44 -07002576 if (vcm->cfg.use_mq_eventfd)
2577 return vppcom_epoll_wait_eventfd (events, maxevents, wait_for_time);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002578
Florin Coras99368312018-08-02 10:45:44 -07002579 return vppcom_epoll_wait_condvar (events, maxevents, wait_for_time);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002580}
2581
Dave Wallace35830af2017-10-09 01:43:42 -04002582int
2583vppcom_session_attr (uint32_t session_index, uint32_t op,
2584 void *buffer, uint32_t * buflen)
2585{
Florin Coras7e12d942018-06-27 14:32:43 -07002586 vcl_session_t *session;
Dave Wallace35830af2017-10-09 01:43:42 -04002587 int rv = VPPCOM_OK;
2588 u32 *flags = buffer;
Steven2199aab2017-10-15 20:18:47 -07002589 vppcom_endpt_t *ep = buffer;
Dave Wallace35830af2017-10-09 01:43:42 -04002590
Dave Wallace7e607a72018-06-18 18:41:32 -04002591 VCL_SESSION_LOCK_AND_GET (session_index, &session);
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002592
2593 ASSERT (session);
2594
Dave Wallace35830af2017-10-09 01:43:42 -04002595 switch (op)
2596 {
2597 case VPPCOM_ATTR_GET_NREAD:
Florin Coras54693d22018-07-17 10:46:29 -07002598 rv = vppcom_session_read_ready (session);
Florin Coras0d427d82018-06-27 03:24:07 -07002599 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_NREAD: sid %u, nread = %d",
2600 getpid (), rv);
Dave Wallace35830af2017-10-09 01:43:42 -04002601 break;
2602
Dave Wallace227867f2017-11-13 21:21:53 -05002603 case VPPCOM_ATTR_GET_NWRITE:
2604 rv = vppcom_session_write_ready (session, session_index);
Florin Coras0d427d82018-06-27 03:24:07 -07002605 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_NWRITE: sid %u, nwrite = %d",
2606 getpid (), session_index, rv);
Dave Wallace35830af2017-10-09 01:43:42 -04002607 break;
2608
2609 case VPPCOM_ATTR_GET_FLAGS:
Dave Wallace048b1d62018-01-03 22:24:41 -05002610 if (PREDICT_TRUE (buffer && buflen && (*buflen >= sizeof (*flags))))
Dave Wallace35830af2017-10-09 01:43:42 -04002611 {
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002612 *flags = O_RDWR | (VCL_SESS_ATTR_TEST (session->attr,
2613 VCL_SESS_ATTR_NONBLOCK));
Dave Wallace35830af2017-10-09 01:43:42 -04002614 *buflen = sizeof (*flags);
Florin Coras0d427d82018-06-27 03:24:07 -07002615 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_FLAGS: sid %u, flags = 0x%08x, "
2616 "is_nonblocking = %u", getpid (),
2617 session_index, *flags,
2618 VCL_SESS_ATTR_TEST (session->attr, VCL_SESS_ATTR_NONBLOCK));
Dave Wallace35830af2017-10-09 01:43:42 -04002619 }
2620 else
2621 rv = VPPCOM_EINVAL;
2622 break;
2623
2624 case VPPCOM_ATTR_SET_FLAGS:
Dave Wallace048b1d62018-01-03 22:24:41 -05002625 if (PREDICT_TRUE (buffer && buflen && (*buflen == sizeof (*flags))))
Dave Wallace35830af2017-10-09 01:43:42 -04002626 {
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002627 if (*flags & O_NONBLOCK)
2628 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_NONBLOCK);
2629 else
2630 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_NONBLOCK);
2631
Florin Coras0d427d82018-06-27 03:24:07 -07002632 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_FLAGS: sid %u, flags = 0x%08x,"
2633 " is_nonblocking = %u",
2634 getpid (), session_index, *flags,
2635 VCL_SESS_ATTR_TEST (session->attr, VCL_SESS_ATTR_NONBLOCK));
Dave Wallace35830af2017-10-09 01:43:42 -04002636 }
2637 else
2638 rv = VPPCOM_EINVAL;
2639 break;
2640
2641 case VPPCOM_ATTR_GET_PEER_ADDR:
Dave Wallace048b1d62018-01-03 22:24:41 -05002642 if (PREDICT_TRUE (buffer && buflen &&
2643 (*buflen >= sizeof (*ep)) && ep->ip))
Dave Wallace35830af2017-10-09 01:43:42 -04002644 {
Florin Coras7e12d942018-06-27 14:32:43 -07002645 ep->is_ip4 = session->transport.is_ip4;
2646 ep->port = session->transport.rmt_port;
2647 if (session->transport.is_ip4)
2648 clib_memcpy (ep->ip, &session->transport.rmt_ip.ip4,
Steven2199aab2017-10-15 20:18:47 -07002649 sizeof (ip4_address_t));
2650 else
Florin Coras7e12d942018-06-27 14:32:43 -07002651 clib_memcpy (ep->ip, &session->transport.rmt_ip.ip6,
Steven2199aab2017-10-15 20:18:47 -07002652 sizeof (ip6_address_t));
2653 *buflen = sizeof (*ep);
Florin Coras0d427d82018-06-27 03:24:07 -07002654 VDBG (1, "VCL<%d>: VPPCOM_ATTR_GET_PEER_ADDR: sid %u, is_ip4 = %u, "
2655 "addr = %U, port %u", getpid (),
2656 session_index, ep->is_ip4, format_ip46_address,
Florin Coras7e12d942018-06-27 14:32:43 -07002657 &session->transport.rmt_ip,
Florin Coras0d427d82018-06-27 03:24:07 -07002658 ep->is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6,
2659 clib_net_to_host_u16 (ep->port));
Dave Wallace35830af2017-10-09 01:43:42 -04002660 }
2661 else
2662 rv = VPPCOM_EINVAL;
2663 break;
2664
2665 case VPPCOM_ATTR_GET_LCL_ADDR:
Dave Wallace048b1d62018-01-03 22:24:41 -05002666 if (PREDICT_TRUE (buffer && buflen &&
2667 (*buflen >= sizeof (*ep)) && ep->ip))
Dave Wallace35830af2017-10-09 01:43:42 -04002668 {
Florin Coras7e12d942018-06-27 14:32:43 -07002669 ep->is_ip4 = session->transport.is_ip4;
2670 ep->port = session->transport.lcl_port;
2671 if (session->transport.is_ip4)
2672 clib_memcpy (ep->ip, &session->transport.lcl_ip.ip4,
Steven2199aab2017-10-15 20:18:47 -07002673 sizeof (ip4_address_t));
2674 else
Florin Coras7e12d942018-06-27 14:32:43 -07002675 clib_memcpy (ep->ip, &session->transport.lcl_ip.ip6,
Steven2199aab2017-10-15 20:18:47 -07002676 sizeof (ip6_address_t));
2677 *buflen = sizeof (*ep);
Florin Coras0d427d82018-06-27 03:24:07 -07002678 VDBG (1, "VCL<%d>: VPPCOM_ATTR_GET_LCL_ADDR: sid %u, is_ip4 = %u,"
2679 " addr = %U port %d", getpid (),
2680 session_index, ep->is_ip4, format_ip46_address,
Florin Coras7e12d942018-06-27 14:32:43 -07002681 &session->transport.lcl_ip,
Florin Coras0d427d82018-06-27 03:24:07 -07002682 ep->is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6,
2683 clib_net_to_host_u16 (ep->port));
Dave Wallace35830af2017-10-09 01:43:42 -04002684 }
2685 else
2686 rv = VPPCOM_EINVAL;
2687 break;
Stevenb5a11602017-10-11 09:59:30 -07002688
Dave Wallace048b1d62018-01-03 22:24:41 -05002689 case VPPCOM_ATTR_GET_LIBC_EPFD:
2690 rv = session->libc_epfd;
Florin Coras0d427d82018-06-27 03:24:07 -07002691 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_LIBC_EPFD: libc_epfd %d",
2692 getpid (), rv);
Dave Wallace048b1d62018-01-03 22:24:41 -05002693 break;
2694
2695 case VPPCOM_ATTR_SET_LIBC_EPFD:
2696 if (PREDICT_TRUE (buffer && buflen &&
2697 (*buflen == sizeof (session->libc_epfd))))
2698 {
2699 session->libc_epfd = *(int *) buffer;
2700 *buflen = sizeof (session->libc_epfd);
2701
Florin Coras0d427d82018-06-27 03:24:07 -07002702 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_LIBC_EPFD: libc_epfd %d, "
2703 "buflen %d", getpid (), session->libc_epfd, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002704 }
2705 else
2706 rv = VPPCOM_EINVAL;
2707 break;
2708
2709 case VPPCOM_ATTR_GET_PROTOCOL:
2710 if (buffer && buflen && (*buflen >= sizeof (int)))
2711 {
Florin Coras7e12d942018-06-27 14:32:43 -07002712 *(int *) buffer = session->session_type;
Dave Wallace048b1d62018-01-03 22:24:41 -05002713 *buflen = sizeof (int);
2714
Florin Coras0d427d82018-06-27 03:24:07 -07002715 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_PROTOCOL: %d (%s), buflen %d",
2716 getpid (), *(int *) buffer, *(int *) buffer ? "UDP" : "TCP",
2717 *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002718 }
2719 else
2720 rv = VPPCOM_EINVAL;
2721 break;
2722
2723 case VPPCOM_ATTR_GET_LISTEN:
2724 if (buffer && buflen && (*buflen >= sizeof (int)))
2725 {
2726 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
2727 VCL_SESS_ATTR_LISTEN);
2728 *buflen = sizeof (int);
2729
Florin Coras0d427d82018-06-27 03:24:07 -07002730 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_LISTEN: %d, buflen %d",
2731 getpid (), *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002732 }
2733 else
2734 rv = VPPCOM_EINVAL;
2735 break;
2736
2737 case VPPCOM_ATTR_GET_ERROR:
2738 if (buffer && buflen && (*buflen >= sizeof (int)))
2739 {
2740 *(int *) buffer = 0;
2741 *buflen = sizeof (int);
2742
Florin Coras0d427d82018-06-27 03:24:07 -07002743 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_ERROR: %d, buflen %d, #VPP-TBD#",
2744 getpid (), *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002745 }
2746 else
2747 rv = VPPCOM_EINVAL;
2748 break;
2749
2750 case VPPCOM_ATTR_GET_TX_FIFO_LEN:
2751 if (buffer && buflen && (*buflen >= sizeof (u32)))
2752 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002753
2754 /* VPP-TBD */
2755 *(size_t *) buffer = (session->sndbuf_size ? session->sndbuf_size :
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002756 session->tx_fifo ? session->tx_fifo->nitems :
Dave Wallace048b1d62018-01-03 22:24:41 -05002757 vcm->cfg.tx_fifo_size);
2758 *buflen = sizeof (u32);
2759
Florin Coras0d427d82018-06-27 03:24:07 -07002760 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_TX_FIFO_LEN: %u (0x%x), "
2761 "buflen %d, #VPP-TBD#", getpid (),
2762 *(size_t *) buffer, *(size_t *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002763 }
2764 else
2765 rv = VPPCOM_EINVAL;
2766 break;
2767
2768 case VPPCOM_ATTR_SET_TX_FIFO_LEN:
2769 if (buffer && buflen && (*buflen == sizeof (u32)))
2770 {
2771 /* VPP-TBD */
2772 session->sndbuf_size = *(u32 *) buffer;
Florin Coras0d427d82018-06-27 03:24:07 -07002773 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_TX_FIFO_LEN: %u (0x%x), "
2774 "buflen %d, #VPP-TBD#", getpid (),
2775 session->sndbuf_size, session->sndbuf_size, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002776 }
2777 else
2778 rv = VPPCOM_EINVAL;
2779 break;
2780
2781 case VPPCOM_ATTR_GET_RX_FIFO_LEN:
2782 if (buffer && buflen && (*buflen >= sizeof (u32)))
2783 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002784
2785 /* VPP-TBD */
2786 *(size_t *) buffer = (session->rcvbuf_size ? session->rcvbuf_size :
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002787 session->rx_fifo ? session->rx_fifo->nitems :
Dave Wallace048b1d62018-01-03 22:24:41 -05002788 vcm->cfg.rx_fifo_size);
2789 *buflen = sizeof (u32);
2790
Florin Coras0d427d82018-06-27 03:24:07 -07002791 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_RX_FIFO_LEN: %u (0x%x), "
2792 "buflen %d, #VPP-TBD#", getpid (),
2793 *(size_t *) buffer, *(size_t *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002794 }
2795 else
2796 rv = VPPCOM_EINVAL;
2797 break;
2798
2799 case VPPCOM_ATTR_SET_RX_FIFO_LEN:
2800 if (buffer && buflen && (*buflen == sizeof (u32)))
2801 {
2802 /* VPP-TBD */
2803 session->rcvbuf_size = *(u32 *) buffer;
Florin Coras0d427d82018-06-27 03:24:07 -07002804 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_RX_FIFO_LEN: %u (0x%x), "
2805 "buflen %d, #VPP-TBD#", getpid (),
2806 session->sndbuf_size, session->sndbuf_size, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002807 }
2808 else
2809 rv = VPPCOM_EINVAL;
2810 break;
2811
2812 case VPPCOM_ATTR_GET_REUSEADDR:
2813 if (buffer && buflen && (*buflen >= sizeof (int)))
2814 {
2815 /* VPP-TBD */
2816 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
2817 VCL_SESS_ATTR_REUSEADDR);
2818 *buflen = sizeof (int);
2819
Florin Coras0d427d82018-06-27 03:24:07 -07002820 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_REUSEADDR: %d, "
2821 "buflen %d, #VPP-TBD#", getpid (), *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002822 }
2823 else
2824 rv = VPPCOM_EINVAL;
2825 break;
2826
Stevenb5a11602017-10-11 09:59:30 -07002827 case VPPCOM_ATTR_SET_REUSEADDR:
Dave Wallace048b1d62018-01-03 22:24:41 -05002828 if (buffer && buflen && (*buflen == sizeof (int)) &&
2829 !VCL_SESS_ATTR_TEST (session->attr, VCL_SESS_ATTR_LISTEN))
2830 {
2831 /* VPP-TBD */
2832 if (*(int *) buffer)
2833 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_REUSEADDR);
2834 else
2835 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_REUSEADDR);
2836
Florin Coras0d427d82018-06-27 03:24:07 -07002837 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_REUSEADDR: %d, buflen %d,"
2838 " #VPP-TBD#", getpid (),
2839 VCL_SESS_ATTR_TEST (session->attr,
2840 VCL_SESS_ATTR_REUSEADDR), *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002841 }
2842 else
2843 rv = VPPCOM_EINVAL;
2844 break;
2845
2846 case VPPCOM_ATTR_GET_REUSEPORT:
2847 if (buffer && buflen && (*buflen >= sizeof (int)))
2848 {
2849 /* VPP-TBD */
2850 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
2851 VCL_SESS_ATTR_REUSEPORT);
2852 *buflen = sizeof (int);
2853
Florin Coras0d427d82018-06-27 03:24:07 -07002854 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_REUSEPORT: %d, buflen %d,"
2855 " #VPP-TBD#", getpid (), *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002856 }
2857 else
2858 rv = VPPCOM_EINVAL;
2859 break;
2860
2861 case VPPCOM_ATTR_SET_REUSEPORT:
2862 if (buffer && buflen && (*buflen == sizeof (int)) &&
2863 !VCL_SESS_ATTR_TEST (session->attr, VCL_SESS_ATTR_LISTEN))
2864 {
2865 /* VPP-TBD */
2866 if (*(int *) buffer)
2867 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_REUSEPORT);
2868 else
2869 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_REUSEPORT);
2870
Florin Coras0d427d82018-06-27 03:24:07 -07002871 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_REUSEPORT: %d, buflen %d,"
2872 " #VPP-TBD#", getpid (),
2873 VCL_SESS_ATTR_TEST (session->attr,
2874 VCL_SESS_ATTR_REUSEPORT), *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002875 }
2876 else
2877 rv = VPPCOM_EINVAL;
2878 break;
2879
2880 case VPPCOM_ATTR_GET_BROADCAST:
2881 if (buffer && buflen && (*buflen >= sizeof (int)))
2882 {
2883 /* VPP-TBD */
2884 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
2885 VCL_SESS_ATTR_BROADCAST);
2886 *buflen = sizeof (int);
2887
Florin Coras0d427d82018-06-27 03:24:07 -07002888 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_BROADCAST: %d, buflen %d,"
2889 " #VPP-TBD#", getpid (), *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002890 }
2891 else
2892 rv = VPPCOM_EINVAL;
Stevenb5a11602017-10-11 09:59:30 -07002893 break;
2894
2895 case VPPCOM_ATTR_SET_BROADCAST:
Dave Wallace048b1d62018-01-03 22:24:41 -05002896 if (buffer && buflen && (*buflen == sizeof (int)))
2897 {
2898 /* VPP-TBD */
2899 if (*(int *) buffer)
2900 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_BROADCAST);
2901 else
2902 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_BROADCAST);
2903
Florin Coras0d427d82018-06-27 03:24:07 -07002904 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_BROADCAST: %d, buflen %d, "
2905 "#VPP-TBD#", getpid (),
2906 VCL_SESS_ATTR_TEST (session->attr,
2907 VCL_SESS_ATTR_BROADCAST), *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002908 }
2909 else
2910 rv = VPPCOM_EINVAL;
2911 break;
2912
2913 case VPPCOM_ATTR_GET_V6ONLY:
2914 if (buffer && buflen && (*buflen >= sizeof (int)))
2915 {
2916 /* VPP-TBD */
2917 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
2918 VCL_SESS_ATTR_V6ONLY);
2919 *buflen = sizeof (int);
2920
Florin Coras0d427d82018-06-27 03:24:07 -07002921 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_V6ONLY: %d, buflen %d, "
2922 "#VPP-TBD#", getpid (), *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002923 }
2924 else
2925 rv = VPPCOM_EINVAL;
Stevenb5a11602017-10-11 09:59:30 -07002926 break;
2927
2928 case VPPCOM_ATTR_SET_V6ONLY:
Dave Wallace048b1d62018-01-03 22:24:41 -05002929 if (buffer && buflen && (*buflen == sizeof (int)))
2930 {
2931 /* VPP-TBD */
2932 if (*(int *) buffer)
2933 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_V6ONLY);
2934 else
2935 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_V6ONLY);
2936
Florin Coras0d427d82018-06-27 03:24:07 -07002937 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_V6ONLY: %d, buflen %d, "
2938 "#VPP-TBD#", getpid (),
2939 VCL_SESS_ATTR_TEST (session->attr,
2940 VCL_SESS_ATTR_V6ONLY), *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002941 }
2942 else
2943 rv = VPPCOM_EINVAL;
2944 break;
2945
2946 case VPPCOM_ATTR_GET_KEEPALIVE:
2947 if (buffer && buflen && (*buflen >= sizeof (int)))
2948 {
2949 /* VPP-TBD */
2950 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
2951 VCL_SESS_ATTR_KEEPALIVE);
2952 *buflen = sizeof (int);
2953
Florin Coras0d427d82018-06-27 03:24:07 -07002954 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_KEEPALIVE: %d, buflen %d, "
2955 "#VPP-TBD#", getpid (), *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002956 }
2957 else
2958 rv = VPPCOM_EINVAL;
Stevenb5a11602017-10-11 09:59:30 -07002959 break;
Stevenbccd3392017-10-12 20:42:21 -07002960
2961 case VPPCOM_ATTR_SET_KEEPALIVE:
Dave Wallace048b1d62018-01-03 22:24:41 -05002962 if (buffer && buflen && (*buflen == sizeof (int)))
2963 {
2964 /* VPP-TBD */
2965 if (*(int *) buffer)
2966 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_KEEPALIVE);
2967 else
2968 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_KEEPALIVE);
2969
Florin Coras0d427d82018-06-27 03:24:07 -07002970 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_KEEPALIVE: %d, buflen %d, "
2971 "#VPP-TBD#", getpid (),
2972 VCL_SESS_ATTR_TEST (session->attr,
2973 VCL_SESS_ATTR_KEEPALIVE), *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002974 }
2975 else
2976 rv = VPPCOM_EINVAL;
2977 break;
2978
2979 case VPPCOM_ATTR_GET_TCP_NODELAY:
2980 if (buffer && buflen && (*buflen >= sizeof (int)))
2981 {
2982 /* VPP-TBD */
2983 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
2984 VCL_SESS_ATTR_TCP_NODELAY);
2985 *buflen = sizeof (int);
2986
Florin Coras0d427d82018-06-27 03:24:07 -07002987 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_TCP_NODELAY: %d, buflen %d, "
2988 "#VPP-TBD#", getpid (), *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002989 }
2990 else
2991 rv = VPPCOM_EINVAL;
2992 break;
2993
2994 case VPPCOM_ATTR_SET_TCP_NODELAY:
2995 if (buffer && buflen && (*buflen == sizeof (int)))
2996 {
2997 /* VPP-TBD */
2998 if (*(int *) buffer)
2999 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_TCP_NODELAY);
3000 else
3001 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_TCP_NODELAY);
3002
Florin Coras0d427d82018-06-27 03:24:07 -07003003 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_TCP_NODELAY: %d, buflen %d, "
3004 "#VPP-TBD#", getpid (),
3005 VCL_SESS_ATTR_TEST (session->attr,
3006 VCL_SESS_ATTR_TCP_NODELAY), *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003007 }
3008 else
3009 rv = VPPCOM_EINVAL;
3010 break;
3011
3012 case VPPCOM_ATTR_GET_TCP_KEEPIDLE:
3013 if (buffer && buflen && (*buflen >= sizeof (int)))
3014 {
3015 /* VPP-TBD */
3016 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
3017 VCL_SESS_ATTR_TCP_KEEPIDLE);
3018 *buflen = sizeof (int);
3019
Florin Coras0d427d82018-06-27 03:24:07 -07003020 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_TCP_KEEPIDLE: %d, buflen %d, "
3021 "#VPP-TBD#", getpid (), *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003022 }
3023 else
3024 rv = VPPCOM_EINVAL;
Stevenbccd3392017-10-12 20:42:21 -07003025 break;
3026
3027 case VPPCOM_ATTR_SET_TCP_KEEPIDLE:
Dave Wallace048b1d62018-01-03 22:24:41 -05003028 if (buffer && buflen && (*buflen == sizeof (int)))
3029 {
3030 /* VPP-TBD */
3031 if (*(int *) buffer)
3032 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_TCP_KEEPIDLE);
3033 else
3034 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_TCP_KEEPIDLE);
3035
Florin Coras0d427d82018-06-27 03:24:07 -07003036 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_TCP_KEEPIDLE: %d, buflen %d, "
3037 "#VPP-TBD#", getpid (),
3038 VCL_SESS_ATTR_TEST (session->attr,
3039 VCL_SESS_ATTR_TCP_KEEPIDLE), *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003040 }
3041 else
3042 rv = VPPCOM_EINVAL;
3043 break;
3044
3045 case VPPCOM_ATTR_GET_TCP_KEEPINTVL:
3046 if (buffer && buflen && (*buflen >= sizeof (int)))
3047 {
3048 /* VPP-TBD */
3049 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
3050 VCL_SESS_ATTR_TCP_KEEPINTVL);
3051 *buflen = sizeof (int);
3052
Florin Coras0d427d82018-06-27 03:24:07 -07003053 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_TCP_KEEPINTVL: %d, buflen %d, "
3054 "#VPP-TBD#", getpid (), *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003055 }
3056 else
3057 rv = VPPCOM_EINVAL;
Stevenbccd3392017-10-12 20:42:21 -07003058 break;
3059
3060 case VPPCOM_ATTR_SET_TCP_KEEPINTVL:
Dave Wallace048b1d62018-01-03 22:24:41 -05003061 if (buffer && buflen && (*buflen == sizeof (int)))
3062 {
3063 /* VPP-TBD */
3064 if (*(int *) buffer)
3065 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_TCP_KEEPINTVL);
3066 else
3067 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_TCP_KEEPINTVL);
3068
Florin Coras0d427d82018-06-27 03:24:07 -07003069 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_TCP_KEEPINTVL: %d, buflen %d, "
3070 "#VPP-TBD#", getpid (),
3071 VCL_SESS_ATTR_TEST (session->attr,
3072 VCL_SESS_ATTR_TCP_KEEPINTVL), *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003073 }
3074 else
3075 rv = VPPCOM_EINVAL;
3076 break;
3077
3078 case VPPCOM_ATTR_GET_TCP_USER_MSS:
3079 if (buffer && buflen && (*buflen >= sizeof (u32)))
3080 {
3081 /* VPP-TBD */
3082 *(u32 *) buffer = session->user_mss;
3083 *buflen = sizeof (int);
3084
Florin Coras0d427d82018-06-27 03:24:07 -07003085 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_TCP_USER_MSS: %d, buflen %d,"
3086 " #VPP-TBD#", getpid (), *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003087 }
3088 else
3089 rv = VPPCOM_EINVAL;
3090 break;
3091
3092 case VPPCOM_ATTR_SET_TCP_USER_MSS:
3093 if (buffer && buflen && (*buflen == sizeof (u32)))
3094 {
3095 /* VPP-TBD */
3096 session->user_mss = *(u32 *) buffer;
3097
Florin Coras0d427d82018-06-27 03:24:07 -07003098 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_TCP_USER_MSS: %u, buflen %d, "
3099 "#VPP-TBD#", getpid (), session->user_mss, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003100 }
3101 else
3102 rv = VPPCOM_EINVAL;
Stevenbccd3392017-10-12 20:42:21 -07003103 break;
Dave Wallacee22aa742017-10-20 12:30:38 -04003104
3105 default:
3106 rv = VPPCOM_EINVAL;
3107 break;
Dave Wallace35830af2017-10-09 01:43:42 -04003108 }
3109
3110done:
Dave Wallace7e607a72018-06-18 18:41:32 -04003111 VCL_SESSION_UNLOCK ();
Dave Wallace35830af2017-10-09 01:43:42 -04003112 return rv;
3113}
3114
Stevenac1f96d2017-10-24 16:03:58 -07003115int
3116vppcom_session_recvfrom (uint32_t session_index, void *buffer,
3117 uint32_t buflen, int flags, vppcom_endpt_t * ep)
3118{
Stevenac1f96d2017-10-24 16:03:58 -07003119 int rv = VPPCOM_OK;
Florin Coras7e12d942018-06-27 14:32:43 -07003120 vcl_session_t *session = 0;
Stevenac1f96d2017-10-24 16:03:58 -07003121
3122 if (ep)
3123 {
Dave Wallace7e607a72018-06-18 18:41:32 -04003124 VCL_SESSION_LOCK ();
Stevenac1f96d2017-10-24 16:03:58 -07003125 rv = vppcom_session_at_index (session_index, &session);
3126 if (PREDICT_FALSE (rv))
3127 {
Dave Wallace7e607a72018-06-18 18:41:32 -04003128 VCL_SESSION_UNLOCK ();
Florin Coras0d427d82018-06-27 03:24:07 -07003129 VDBG (0, "VCL<%d>: invalid session, sid (%u) has been closed!",
3130 getpid (), session_index);
Dave Wallace7e607a72018-06-18 18:41:32 -04003131 VCL_SESSION_UNLOCK ();
Florin Coras460dce62018-07-27 05:45:06 -07003132 return VPPCOM_EBADFD;
Stevenac1f96d2017-10-24 16:03:58 -07003133 }
Florin Coras7e12d942018-06-27 14:32:43 -07003134 ep->is_ip4 = session->transport.is_ip4;
3135 ep->port = session->transport.rmt_port;
Dave Wallace7e607a72018-06-18 18:41:32 -04003136 VCL_SESSION_UNLOCK ();
Stevenac1f96d2017-10-24 16:03:58 -07003137 }
Steven58f464e2017-10-25 12:33:12 -07003138
3139 if (flags == 0)
Stevenac1f96d2017-10-24 16:03:58 -07003140 rv = vppcom_session_read (session_index, buffer, buflen);
3141 else if (flags & MSG_PEEK)
Steven58f464e2017-10-25 12:33:12 -07003142 rv = vppcom_session_peek (session_index, buffer, buflen);
Stevenac1f96d2017-10-24 16:03:58 -07003143 else
3144 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003145 clib_warning ("VCL<%d>: Unsupport flags for recvfrom %d",
3146 getpid (), flags);
Florin Coras460dce62018-07-27 05:45:06 -07003147 return VPPCOM_EAFNOSUPPORT;
Stevenac1f96d2017-10-24 16:03:58 -07003148 }
3149
Florin Coras99368312018-08-02 10:45:44 -07003150 if (ep)
3151 {
3152 if (session->transport.is_ip4)
3153 clib_memcpy (ep->ip, &session->transport.rmt_ip.ip4,
3154 sizeof (ip4_address_t));
3155 else
3156 clib_memcpy (ep->ip, &session->transport.rmt_ip.ip6,
3157 sizeof (ip6_address_t));
3158 }
Florin Coras460dce62018-07-27 05:45:06 -07003159
Stevenac1f96d2017-10-24 16:03:58 -07003160 return rv;
3161}
3162
3163int
3164vppcom_session_sendto (uint32_t session_index, void *buffer,
3165 uint32_t buflen, int flags, vppcom_endpt_t * ep)
3166{
Dave Wallace617dffa2017-10-26 14:47:06 -04003167 if (!buffer)
3168 return VPPCOM_EINVAL;
3169
3170 if (ep)
3171 {
3172 // TBD
3173 return VPPCOM_EINVAL;
3174 }
3175
3176 if (flags)
3177 {
3178 // TBD check the flags and do the right thing
Florin Coras0d427d82018-06-27 03:24:07 -07003179 VDBG (2, "VCL<%d>: handling flags 0x%u (%d) not implemented yet.",
3180 getpid (), flags, flags);
Dave Wallace617dffa2017-10-26 14:47:06 -04003181 }
3182
3183 return (vppcom_session_write (session_index, buffer, buflen));
Stevenac1f96d2017-10-24 16:03:58 -07003184}
3185
Dave Wallace048b1d62018-01-03 22:24:41 -05003186int
3187vppcom_poll (vcl_poll_t * vp, uint32_t n_sids, double wait_for_time)
3188{
3189 f64 timeout = clib_time_now (&vcm->clib_time) + wait_for_time;
3190 u32 i, keep_trying = 1;
3191 int rv, num_ev = 0;
3192
Florin Coras0d427d82018-06-27 03:24:07 -07003193 VDBG (3, "VCL<%d>: vp %p, nsids %u, wait_for_time %f",
3194 getpid (), vp, n_sids, wait_for_time);
Dave Wallace048b1d62018-01-03 22:24:41 -05003195
3196 if (!vp)
3197 return VPPCOM_EFAULT;
3198
3199 do
3200 {
Florin Coras7e12d942018-06-27 14:32:43 -07003201 vcl_session_t *session;
Dave Wallace048b1d62018-01-03 22:24:41 -05003202
3203 for (i = 0; i < n_sids; i++)
3204 {
3205 ASSERT (vp[i].revents);
3206
Dave Wallace7e607a72018-06-18 18:41:32 -04003207 VCL_SESSION_LOCK_AND_GET (vp[i].sid, &session);
3208 VCL_SESSION_UNLOCK ();
Dave Wallace048b1d62018-01-03 22:24:41 -05003209
3210 if (*vp[i].revents)
3211 *vp[i].revents = 0;
3212
3213 if (POLLIN & vp[i].events)
3214 {
Dave Wallace7e607a72018-06-18 18:41:32 -04003215 VCL_SESSION_LOCK_AND_GET (vp[i].sid, &session);
Florin Coras54693d22018-07-17 10:46:29 -07003216 rv = vppcom_session_read_ready (session);
Dave Wallace7e607a72018-06-18 18:41:32 -04003217 VCL_SESSION_UNLOCK ();
Dave Wallace048b1d62018-01-03 22:24:41 -05003218 if (rv > 0)
3219 {
3220 *vp[i].revents |= POLLIN;
3221 num_ev++;
3222 }
3223 else if (rv < 0)
3224 {
3225 switch (rv)
3226 {
3227 case VPPCOM_ECONNRESET:
3228 *vp[i].revents = POLLHUP;
3229 break;
3230
3231 default:
3232 *vp[i].revents = POLLERR;
3233 break;
3234 }
3235 num_ev++;
3236 }
3237 }
3238
3239 if (POLLOUT & vp[i].events)
3240 {
Dave Wallace7e607a72018-06-18 18:41:32 -04003241 VCL_SESSION_LOCK_AND_GET (vp[i].sid, &session);
Dave Wallace048b1d62018-01-03 22:24:41 -05003242 rv = vppcom_session_write_ready (session, vp[i].sid);
Dave Wallace7e607a72018-06-18 18:41:32 -04003243 VCL_SESSION_UNLOCK ();
Dave Wallace048b1d62018-01-03 22:24:41 -05003244 if (rv > 0)
3245 {
3246 *vp[i].revents |= POLLOUT;
3247 num_ev++;
3248 }
3249 else if (rv < 0)
3250 {
3251 switch (rv)
3252 {
3253 case VPPCOM_ECONNRESET:
3254 *vp[i].revents = POLLHUP;
3255 break;
3256
3257 default:
3258 *vp[i].revents = POLLERR;
3259 break;
3260 }
3261 num_ev++;
3262 }
3263 }
3264
Dave Wallace7e607a72018-06-18 18:41:32 -04003265 if (0) // Note "done:" label used by VCL_SESSION_LOCK_AND_GET()
Dave Wallace048b1d62018-01-03 22:24:41 -05003266 {
3267 done:
3268 *vp[i].revents = POLLNVAL;
3269 num_ev++;
3270 }
3271 }
3272 if (wait_for_time != -1)
3273 keep_trying = (clib_time_now (&vcm->clib_time) <= timeout) ? 1 : 0;
3274 }
3275 while ((num_ev == 0) && keep_trying);
3276
3277 if (VPPCOM_DEBUG > 3)
3278 {
3279 clib_warning ("VCL<%d>: returning %d", getpid (), num_ev);
3280 for (i = 0; i < n_sids; i++)
3281 {
3282 clib_warning ("VCL<%d>: vp[%d].sid %d (0x%x), .events 0x%x, "
3283 ".revents 0x%x", getpid (), i, vp[i].sid, vp[i].sid,
3284 vp[i].events, *vp[i].revents);
3285 }
3286 }
3287 return num_ev;
3288}
3289
Florin Coras99368312018-08-02 10:45:44 -07003290int
3291vppcom_mq_epoll_fd (void)
3292{
3293 return vcm->mqs_epfd;
3294}
3295
Dave Wallacee22aa742017-10-20 12:30:38 -04003296/*
3297 * fd.io coding-style-patch-verification: ON
3298 *
3299 * Local Variables:
3300 * eval: (c-set-style "gnu")
3301 * End:
3302 */