blob: 60c649d325fb0eb05f7da9e4d6f7018c13a9f27d [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
Dave Wallace543852a2017-08-03 02:11:34 -040024static const char *
25vppcom_app_state_str (app_state_t state)
26{
27 char *st;
28
29 switch (state)
30 {
31 case STATE_APP_START:
32 st = "STATE_APP_START";
33 break;
34
35 case STATE_APP_CONN_VPP:
36 st = "STATE_APP_CONN_VPP";
37 break;
38
39 case STATE_APP_ENABLED:
40 st = "STATE_APP_ENABLED";
41 break;
42
43 case STATE_APP_ATTACHED:
44 st = "STATE_APP_ATTACHED";
45 break;
46
47 default:
48 st = "UNKNOWN_APP_STATE";
49 break;
50 }
51
52 return st;
53}
54
Florin Coras697faea2018-06-27 17:10:49 -070055const char *
Dave Wallace543852a2017-08-03 02:11:34 -040056vppcom_session_state_str (session_state_t state)
57{
58 char *st;
59
60 switch (state)
61 {
62 case STATE_START:
63 st = "STATE_START";
64 break;
65
66 case STATE_CONNECT:
67 st = "STATE_CONNECT";
68 break;
69
70 case STATE_LISTEN:
71 st = "STATE_LISTEN";
72 break;
73
74 case STATE_ACCEPT:
75 st = "STATE_ACCEPT";
76 break;
77
Dave Wallace4878cbe2017-11-21 03:45:09 -050078 case STATE_CLOSE_ON_EMPTY:
79 st = "STATE_CLOSE_ON_EMPTY";
80 break;
81
Dave Wallace543852a2017-08-03 02:11:34 -040082 case STATE_DISCONNECT:
83 st = "STATE_DISCONNECT";
84 break;
85
86 case STATE_FAILED:
87 st = "STATE_FAILED";
88 break;
89
90 default:
91 st = "UNKNOWN_STATE";
92 break;
93 }
94
95 return st;
96}
97
Dave Wallace543852a2017-08-03 02:11:34 -040098u8 *
99format_ip4_address (u8 * s, va_list * args)
100{
101 u8 *a = va_arg (*args, u8 *);
102 return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
103}
104
105u8 *
106format_ip6_address (u8 * s, va_list * args)
107{
108 ip6_address_t *a = va_arg (*args, ip6_address_t *);
109 u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
110
111 i_max_n_zero = ARRAY_LEN (a->as_u16);
112 max_n_zeros = 0;
113 i_first_zero = i_max_n_zero;
114 n_zeros = 0;
115 for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
116 {
117 u32 is_zero = a->as_u16[i] == 0;
118 if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
119 {
120 i_first_zero = i;
121 n_zeros = 0;
122 }
123 n_zeros += is_zero;
124 if ((!is_zero && n_zeros > max_n_zeros)
125 || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
126 {
127 i_max_n_zero = i_first_zero;
128 max_n_zeros = n_zeros;
129 i_first_zero = ARRAY_LEN (a->as_u16);
130 n_zeros = 0;
131 }
132 }
133
134 last_double_colon = 0;
135 for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
136 {
137 if (i == i_max_n_zero && max_n_zeros > 1)
138 {
139 s = format (s, "::");
140 i += max_n_zeros - 1;
141 last_double_colon = 1;
142 }
143 else
144 {
145 s = format (s, "%s%x",
146 (last_double_colon || i == 0) ? "" : ":",
147 clib_net_to_host_u16 (a->as_u16[i]));
148 last_double_colon = 0;
149 }
150 }
151
152 return s;
153}
154
155/* Format an IP46 address. */
156u8 *
157format_ip46_address (u8 * s, va_list * args)
158{
159 ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
160 ip46_type_t type = va_arg (*args, ip46_type_t);
161 int is_ip4 = 1;
162
163 switch (type)
164 {
165 case IP46_TYPE_ANY:
166 is_ip4 = ip46_address_is_ip4 (ip46);
167 break;
168 case IP46_TYPE_IP4:
169 is_ip4 = 1;
170 break;
171 case IP46_TYPE_IP6:
172 is_ip4 = 0;
173 break;
174 }
175
176 return is_ip4 ?
177 format (s, "%U", format_ip4_address, &ip46->ip4) :
178 format (s, "%U", format_ip6_address, &ip46->ip6);
179}
180
Florin Coras697faea2018-06-27 17:10:49 -0700181/*
182 * VPPCOM Utility Functions
183 */
184
185static inline void
186vppcom_session_table_del_listener (u64 listener_handle)
Dave Wallace543852a2017-08-03 02:11:34 -0400187{
Florin Coras697faea2018-06-27 17:10:49 -0700188 listener_handle |= 1ULL << 63;
189 hash_unset (vcm->session_index_by_vpp_handles, listener_handle);
190}
191
192static inline int
193vppcom_wait_for_app_state_change (app_state_t app_state)
194{
195 f64 timeout = clib_time_now (&vcm->clib_time) + vcm->cfg.app_timeout;
196
197 while (clib_time_now (&vcm->clib_time) < timeout)
198 {
199 if (vcm->app_state == app_state)
200 return VPPCOM_OK;
201 }
202 VDBG (0, "VCL<%d>: timeout waiting for state %s (%d)", getpid (),
203 vppcom_app_state_str (app_state), app_state);
204 vcl_evt (VCL_EVT_SESSION_TIMEOUT, vcm, app_state);
205
206 return VPPCOM_ETIMEDOUT;
207}
208
209static inline int
210vppcom_wait_for_session_state_change (u32 session_index,
211 session_state_t state,
212 f64 wait_for_time)
213{
214 f64 timeout = clib_time_now (&vcm->clib_time) + wait_for_time;
215 vcl_session_t *volatile session;
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800216 int rv;
Dave Wallace543852a2017-08-03 02:11:34 -0400217
Florin Coras697faea2018-06-27 17:10:49 -0700218 do
Dave Wallace543852a2017-08-03 02:11:34 -0400219 {
Florin Coras697faea2018-06-27 17:10:49 -0700220 VCL_SESSION_LOCK ();
221 rv = vppcom_session_at_index (session_index, &session);
222 if (PREDICT_FALSE (rv))
223 {
224 VCL_SESSION_UNLOCK ();
225 return rv;
226 }
227 if (session->session_state & state)
228 {
229 VCL_SESSION_UNLOCK ();
230 return VPPCOM_OK;
231 }
232 if (session->session_state & STATE_FAILED)
233 {
234 VCL_SESSION_UNLOCK ();
235 return VPPCOM_ECONNREFUSED;
236 }
237
Dave Wallace7e607a72018-06-18 18:41:32 -0400238 VCL_SESSION_UNLOCK ();
Florin Corasdcf55ce2017-11-16 15:32:50 -0800239 }
Florin Coras697faea2018-06-27 17:10:49 -0700240 while (clib_time_now (&vcm->clib_time) < timeout);
Florin Corasdcf55ce2017-11-16 15:32:50 -0800241
Florin Coras697faea2018-06-27 17:10:49 -0700242 VDBG (0, "VCL<%d>: timeout waiting for state 0x%x (%s)", getpid (), state,
243 vppcom_session_state_str (state));
244 vcl_evt (VCL_EVT_SESSION_TIMEOUT, session, session_state);
Dave Wallace543852a2017-08-03 02:11:34 -0400245
Florin Coras697faea2018-06-27 17:10:49 -0700246 return VPPCOM_ETIMEDOUT;
Dave Wallace60caa062017-11-10 17:07:13 -0500247}
248
Florin Coras697faea2018-06-27 17:10:49 -0700249static int
250vppcom_app_session_enable (void)
Dave Wallace543852a2017-08-03 02:11:34 -0400251{
Florin Coras697faea2018-06-27 17:10:49 -0700252 int rv;
Dave Wallace543852a2017-08-03 02:11:34 -0400253
Florin Coras697faea2018-06-27 17:10:49 -0700254 if (vcm->app_state != STATE_APP_ENABLED)
255 {
256 vppcom_send_session_enable_disable (1 /* is_enabled == TRUE */ );
257 rv = vppcom_wait_for_app_state_change (STATE_APP_ENABLED);
258 if (PREDICT_FALSE (rv))
259 {
260 VDBG (0, "VCL<%d>: application session enable timed out! "
261 "returning %d (%s)", getpid (), rv, vppcom_retval_str (rv));
262 return rv;
263 }
264 }
265 return VPPCOM_OK;
Dave Wallace543852a2017-08-03 02:11:34 -0400266}
267
Florin Coras697faea2018-06-27 17:10:49 -0700268static int
269vppcom_app_attach (void)
Dave Wallace543852a2017-08-03 02:11:34 -0400270{
Florin Coras697faea2018-06-27 17:10:49 -0700271 int rv;
Dave Wallace543852a2017-08-03 02:11:34 -0400272
Florin Coras697faea2018-06-27 17:10:49 -0700273 vppcom_app_send_attach ();
274 rv = vppcom_wait_for_app_state_change (STATE_APP_ATTACHED);
275 if (PREDICT_FALSE (rv))
276 {
277 VDBG (0, "VCL<%d>: application attach timed out! returning %d (%s)",
278 getpid (), rv, vppcom_retval_str (rv));
279 return rv;
280 }
Dave Wallace543852a2017-08-03 02:11:34 -0400281
Florin Coras697faea2018-06-27 17:10:49 -0700282 return VPPCOM_OK;
Dave Wallace543852a2017-08-03 02:11:34 -0400283}
284
285static int
Dave Wallace543852a2017-08-03 02:11:34 -0400286vppcom_session_unbind (u32 session_index)
287{
Florin Coras7e12d942018-06-27 14:32:43 -0700288 vcl_session_t *session = 0;
Dave Wallace543852a2017-08-03 02:11:34 -0400289 int rv;
Dave Wallace4878cbe2017-11-21 03:45:09 -0500290 u64 vpp_handle;
Dave Wallace543852a2017-08-03 02:11:34 -0400291
Dave Wallace7e607a72018-06-18 18:41:32 -0400292 VCL_SESSION_LOCK_AND_GET (session_index, &session);
Dave Wallace4878cbe2017-11-21 03:45:09 -0500293
294 vpp_handle = session->vpp_handle;
295 vppcom_session_table_del_listener (vpp_handle);
296 session->vpp_handle = ~0;
Florin Coras7e12d942018-06-27 14:32:43 -0700297 session->session_state = STATE_DISCONNECT;
Dave Wallace4878cbe2017-11-21 03:45:09 -0500298
Dave Wallace7e607a72018-06-18 18:41:32 -0400299 VCL_SESSION_UNLOCK ();
Dave Wallace543852a2017-08-03 02:11:34 -0400300
Florin Coras0d427d82018-06-27 03:24:07 -0700301 VDBG (1, "VCL<%d>: vpp handle 0x%llx, sid %u: sending unbind msg! new state"
302 " 0x%x (%s)", getpid (), vpp_handle, session_index, STATE_DISCONNECT,
303 vppcom_session_state_str (STATE_DISCONNECT));
304 vcl_evt (VCL_EVT_UNBIND, session);
Dave Wallace4878cbe2017-11-21 03:45:09 -0500305 vppcom_send_unbind_sock (vpp_handle);
306
307done:
308 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -0400309}
310
Florin Coras697faea2018-06-27 17:10:49 -0700311static int
Dave Wallace543852a2017-08-03 02:11:34 -0400312vppcom_session_disconnect (u32 session_index)
313{
Dave Wallace543852a2017-08-03 02:11:34 -0400314 int rv;
Florin Coras7e12d942018-06-27 14:32:43 -0700315 vcl_session_t *session;
Dave Wallace4878cbe2017-11-21 03:45:09 -0500316 u64 vpp_handle;
317 session_state_t state;
Dave Wallace543852a2017-08-03 02:11:34 -0400318
Dave Wallace7e607a72018-06-18 18:41:32 -0400319 VCL_SESSION_LOCK_AND_GET (session_index, &session);
Dave Wallace4878cbe2017-11-21 03:45:09 -0500320
321 vpp_handle = session->vpp_handle;
Florin Coras7e12d942018-06-27 14:32:43 -0700322 state = session->session_state;
Dave Wallace7e607a72018-06-18 18:41:32 -0400323 VCL_SESSION_UNLOCK ();
Dave Wallace4878cbe2017-11-21 03:45:09 -0500324
Florin Coras0d427d82018-06-27 03:24:07 -0700325 VDBG (1, "VCL<%d>: vpp handle 0x%llx, sid %u state 0x%x (%s)", getpid (),
326 vpp_handle, session_index, state, vppcom_session_state_str (state));
Dave Wallace66cf6eb2017-10-26 02:51:07 -0400327
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -0800328 if (PREDICT_FALSE (state & STATE_LISTEN))
Dave Wallace66cf6eb2017-10-26 02:51:07 -0400329 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500330 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -0500331 "Cannot disconnect a listen socket!",
332 getpid (), vpp_handle, session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -0500333 rv = VPPCOM_EBADFD;
334 goto done;
335 }
Dave Wallace66cf6eb2017-10-26 02:51:07 -0400336
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -0800337 /* The peer has already initiated the close,
338 * so send the disconnect session reply.
Dave Wallace4878cbe2017-11-21 03:45:09 -0500339 */
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -0800340 if (state & STATE_CLOSE_ON_EMPTY)
Dave Wallace4878cbe2017-11-21 03:45:09 -0500341 {
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -0800342 //XXX alagalah - Check and drain here?
343 vppcom_send_disconnect_session_reply (vpp_handle,
344 session_index, 0 /* rv */ );
Florin Coras0d427d82018-06-27 03:24:07 -0700345 VDBG (1, "VCL<%d>: vpp handle 0x%llx, sid %u: sending disconnect "
346 "REPLY...", getpid (), vpp_handle, session_index);
Dave Wallace66cf6eb2017-10-26 02:51:07 -0400347 }
Dave Wallace4878cbe2017-11-21 03:45:09 -0500348
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -0800349 /* Otherwise, send a disconnect session msg...
Dave Wallace4878cbe2017-11-21 03:45:09 -0500350 */
Dave Wallace66cf6eb2017-10-26 02:51:07 -0400351 else
Dave Wallace227867f2017-11-13 21:21:53 -0500352 {
Florin Coras0d427d82018-06-27 03:24:07 -0700353 VDBG (1, "VCL<%d>: vpp handle 0x%llx, sid %u: sending disconnect...",
354 getpid (), vpp_handle, session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -0500355
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -0800356 vppcom_send_disconnect_session (vpp_handle, session_index);
Dave Wallace227867f2017-11-13 21:21:53 -0500357 }
Dave Wallace66cf6eb2017-10-26 02:51:07 -0400358
Dave Wallace4878cbe2017-11-21 03:45:09 -0500359done:
360 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -0400361}
362
Dave Wallace543852a2017-08-03 02:11:34 -0400363/*
364 * VPPCOM Public API functions
365 */
366int
367vppcom_app_create (char *app_name)
368{
Dave Wallace543852a2017-08-03 02:11:34 -0400369 vppcom_cfg_t *vcl_cfg = &vcm->cfg;
Dave Wallace543852a2017-08-03 02:11:34 -0400370 int rv;
371
372 if (!vcm->init)
373 {
Dave Wallace543852a2017-08-03 02:11:34 -0400374 vcm->init = 1;
Dave Barach6a5adc32018-07-04 10:56:23 -0400375 vppcom_cfg (&vcm->cfg);
376
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -0800377 clib_spinlock_init (&vcm->session_fifo_lockp);
Dave Wallace2e005bb2017-11-07 01:21:39 -0500378 clib_fifo_validate (vcm->client_session_index_fifo,
379 vcm->cfg.listen_queue_size);
Florin Coras697faea2018-06-27 17:10:49 -0700380 clib_spinlock_init (&vcm->sessions_lockp);
Dave Wallaceb5a86ee2018-02-16 18:26:11 -0500381
Dave Wallace8af20542017-10-26 03:29:30 -0400382
Dave Wallace543852a2017-08-03 02:11:34 -0400383 vcm->main_cpu = os_get_thread_index ();
Dave Wallace543852a2017-08-03 02:11:34 -0400384
385 vcm->session_index_by_vpp_handles = hash_create (0, sizeof (uword));
386
387 clib_time_init (&vcm->clib_time);
388 vppcom_init_error_string_table ();
Florin Corasa332c462018-01-31 06:52:17 -0800389 svm_fifo_segment_main_init (vcl_cfg->segment_baseva,
390 20 /* timeout in secs */ );
Dave Wallace543852a2017-08-03 02:11:34 -0400391 }
392
393 if (vcm->my_client_index == ~0)
394 {
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800395 /* API hookup and connect to VPP */
Dave Wallace048b1d62018-01-03 22:24:41 -0500396 vppcom_api_hookup ();
Florin Coras0d427d82018-06-27 03:24:07 -0700397 vcl_elog_init (vcm);
Dave Wallace543852a2017-08-03 02:11:34 -0400398 vcm->app_state = STATE_APP_START;
399 rv = vppcom_connect_to_vpp (app_name);
400 if (rv)
401 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500402 clib_warning ("VCL<%d>: ERROR: couldn't connect to VPP!",
Dave Wallace2e005bb2017-11-07 01:21:39 -0500403 getpid ());
Dave Wallace543852a2017-08-03 02:11:34 -0400404 return rv;
405 }
406
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800407 /* State event handling thread */
408
409 rv = vce_start_event_thread (&(vcm->event_thread), 20);
410
Florin Coras0d427d82018-06-27 03:24:07 -0700411 VDBG (0, "VCL<%d>: sending session enable", getpid ());
Dave Wallace543852a2017-08-03 02:11:34 -0400412
Dave Wallace048b1d62018-01-03 22:24:41 -0500413 rv = vppcom_app_session_enable ();
Dave Wallace543852a2017-08-03 02:11:34 -0400414 if (rv)
415 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500416 clib_warning ("VCL<%d>: ERROR: vppcom_app_session_enable() "
417 "failed!", getpid ());
Dave Wallace543852a2017-08-03 02:11:34 -0400418 return rv;
419 }
Dave Wallace543852a2017-08-03 02:11:34 -0400420
Florin Coras0d427d82018-06-27 03:24:07 -0700421 VDBG (0, "VCL<%d>: sending app attach", getpid ());
Dave Wallace048b1d62018-01-03 22:24:41 -0500422
423 rv = vppcom_app_attach ();
424 if (rv)
425 {
426 clib_warning ("VCL<%d>: ERROR: vppcom_app_attach() failed!",
427 getpid ());
428 return rv;
429 }
430
Florin Coras0d427d82018-06-27 03:24:07 -0700431 VDBG (0, "VCL<%d>: app_name '%s', my_client_index %d (0x%x)",
432 getpid (), app_name, vcm->my_client_index, vcm->my_client_index);
Dave Wallace66cf6eb2017-10-26 02:51:07 -0400433 }
Dave Wallace543852a2017-08-03 02:11:34 -0400434
435 return VPPCOM_OK;
436}
437
438void
439vppcom_app_destroy (void)
440{
Dave Wallace543852a2017-08-03 02:11:34 -0400441 int rv;
Dave Wallacede910062018-03-20 09:22:13 -0400442 f64 orig_app_timeout;
Dave Wallace543852a2017-08-03 02:11:34 -0400443
444 if (vcm->my_client_index == ~0)
445 return;
446
Florin Coras0d427d82018-06-27 03:24:07 -0700447 VDBG (0, "VCL<%d>: detaching from VPP, my_client_index %d (0x%x)",
448 getpid (), vcm->my_client_index, vcm->my_client_index);
449 vcl_evt (VCL_EVT_DETACH, vcm);
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -0800450
Florin Coras697faea2018-06-27 17:10:49 -0700451 vppcom_app_send_detach ();
Dave Wallacede910062018-03-20 09:22:13 -0400452 orig_app_timeout = vcm->cfg.app_timeout;
453 vcm->cfg.app_timeout = 2.0;
Dave Wallace543852a2017-08-03 02:11:34 -0400454 rv = vppcom_wait_for_app_state_change (STATE_APP_ENABLED);
Dave Wallacede910062018-03-20 09:22:13 -0400455 vcm->cfg.app_timeout = orig_app_timeout;
Dave Wallace543852a2017-08-03 02:11:34 -0400456 if (PREDICT_FALSE (rv))
Florin Coras0d427d82018-06-27 03:24:07 -0700457 VDBG (0, "VCL<%d>: application detach timed out! returning %d (%s)",
458 getpid (), rv, vppcom_retval_str (rv));
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -0800459
Florin Coras0d427d82018-06-27 03:24:07 -0700460 vcl_elog_stop (vcm);
Dave Wallace543852a2017-08-03 02:11:34 -0400461 vl_client_disconnect_from_vlib ();
462 vcm->my_client_index = ~0;
463 vcm->app_state = STATE_APP_START;
464}
465
466int
Dave Wallacec04cbf12018-02-07 18:14:02 -0500467vppcom_session_create (u8 proto, u8 is_nonblocking)
Dave Wallace543852a2017-08-03 02:11:34 -0400468{
Florin Coras7e12d942018-06-27 14:32:43 -0700469 vcl_session_t *session;
Dave Wallace543852a2017-08-03 02:11:34 -0400470 u32 session_index;
471
Dave Wallace7e607a72018-06-18 18:41:32 -0400472 VCL_SESSION_LOCK ();
Dave Wallace543852a2017-08-03 02:11:34 -0400473 pool_get (vcm->sessions, session);
Dave Wallacef7f809c2017-10-03 01:48:42 -0400474 memset (session, 0, sizeof (*session));
Dave Wallace543852a2017-08-03 02:11:34 -0400475 session_index = session - vcm->sessions;
476
Florin Coras7e12d942018-06-27 14:32:43 -0700477 session->session_type = proto;
478 session->session_state = STATE_START;
Dave Wallace4878cbe2017-11-21 03:45:09 -0500479 session->vpp_handle = ~0;
Dave Wallace543852a2017-08-03 02:11:34 -0400480
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -0800481 if (is_nonblocking)
482 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_NONBLOCK);
483 else
484 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_NONBLOCK);
Dave Wallace543852a2017-08-03 02:11:34 -0400485
Florin Coras7e12d942018-06-27 14:32:43 -0700486 vcl_evt (VCL_EVT_CREATE, session, session_type, session->session_state,
487 is_nonblocking, session_index);
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -0800488
Dave Wallace7e607a72018-06-18 18:41:32 -0400489 VCL_SESSION_UNLOCK ();
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -0800490
Florin Coras0d427d82018-06-27 03:24:07 -0700491 VDBG (0, "VCL<%d>: sid %u", getpid (), session_index);
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -0800492
Dave Wallace543852a2017-08-03 02:11:34 -0400493 return (int) session_index;
494}
495
496int
497vppcom_session_close (uint32_t session_index)
498{
Florin Coras7e12d942018-06-27 14:32:43 -0700499 vcl_session_t *session = 0;
Dave Wallace543852a2017-08-03 02:11:34 -0400500 int rv;
Dave Wallace66cf6eb2017-10-26 02:51:07 -0400501 u8 is_vep;
502 u8 is_vep_session;
503 u32 next_sid;
504 u32 vep_idx;
Dave Wallaceee45d412017-11-24 21:44:06 -0500505 u64 vpp_handle;
Dave Wallace4878cbe2017-11-21 03:45:09 -0500506 uword *p;
Dave Wallace66cf6eb2017-10-26 02:51:07 -0400507 session_state_t state;
Dave Wallace543852a2017-08-03 02:11:34 -0400508
Dave Wallace7e607a72018-06-18 18:41:32 -0400509 VCL_SESSION_LOCK_AND_GET (session_index, &session);
Dave Wallace66cf6eb2017-10-26 02:51:07 -0400510 is_vep = session->is_vep;
511 is_vep_session = session->is_vep_session;
512 next_sid = session->vep.next_sid;
513 vep_idx = session->vep.vep_idx;
Florin Coras7e12d942018-06-27 14:32:43 -0700514 state = session->session_state;
Dave Wallaceee45d412017-11-24 21:44:06 -0500515 vpp_handle = session->vpp_handle;
Dave Wallace7e607a72018-06-18 18:41:32 -0400516 VCL_SESSION_UNLOCK ();
Dave Wallace543852a2017-08-03 02:11:34 -0400517
518 if (VPPCOM_DEBUG > 0)
Dave Wallaceee45d412017-11-24 21:44:06 -0500519 {
520 if (is_vep)
Dave Wallace048b1d62018-01-03 22:24:41 -0500521 clib_warning ("VCL<%d>: vep_idx %u / sid %u: "
522 "closing epoll session...",
Dave Wallaceee45d412017-11-24 21:44:06 -0500523 getpid (), session_index, session_index);
524 else
Dave Wallace048b1d62018-01-03 22:24:41 -0500525 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %d: "
526 "closing session...",
Dave Wallaceee45d412017-11-24 21:44:06 -0500527 getpid (), vpp_handle, session_index);
528 }
Dave Wallace543852a2017-08-03 02:11:34 -0400529
Dave Wallace66cf6eb2017-10-26 02:51:07 -0400530 if (is_vep)
Dave Wallace543852a2017-08-03 02:11:34 -0400531 {
Dave Wallace66cf6eb2017-10-26 02:51:07 -0400532 while (next_sid != ~0)
Dave Wallace19481612017-09-15 18:47:44 -0400533 {
Dave Wallacef7f809c2017-10-03 01:48:42 -0400534 rv = vppcom_epoll_ctl (session_index, EPOLL_CTL_DEL, next_sid, 0);
Florin Coras0d427d82018-06-27 03:24:07 -0700535 if (PREDICT_FALSE (rv < 0))
536 VDBG (0, "VCL<%d>: vpp handle 0x%llx, sid %u: EPOLL_CTL_DEL "
537 "vep_idx %u failed! rv %d (%s)",
538 getpid (), vpp_handle, next_sid, vep_idx,
539 rv, vppcom_retval_str (rv));
Dave Wallacef7f809c2017-10-03 01:48:42 -0400540
Dave Wallace7e607a72018-06-18 18:41:32 -0400541 VCL_SESSION_LOCK_AND_GET (session_index, &session);
Dave Wallace66cf6eb2017-10-26 02:51:07 -0400542 next_sid = session->vep.next_sid;
Dave Wallace7e607a72018-06-18 18:41:32 -0400543 VCL_SESSION_UNLOCK ();
Dave Wallacef7f809c2017-10-03 01:48:42 -0400544 }
545 }
546 else
547 {
Dave Wallace66cf6eb2017-10-26 02:51:07 -0400548 if (is_vep_session)
Dave Wallacef7f809c2017-10-03 01:48:42 -0400549 {
Dave Wallacef7f809c2017-10-03 01:48:42 -0400550 rv = vppcom_epoll_ctl (vep_idx, EPOLL_CTL_DEL, session_index, 0);
Florin Coras0d427d82018-06-27 03:24:07 -0700551 if (rv < 0)
552 VDBG (0, "VCL<%d>: vpp handle 0x%llx, sid %u: EPOLL_CTL_DEL "
553 "vep_idx %u failed! rv %d (%s)",
554 getpid (), vpp_handle, session_index,
555 vep_idx, rv, vppcom_retval_str (rv));
Dave Wallacef7f809c2017-10-03 01:48:42 -0400556 }
557
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -0800558 if (state & STATE_LISTEN)
Dave Wallacef7f809c2017-10-03 01:48:42 -0400559 {
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -0800560 rv = vppcom_session_unbind (session_index);
561 if (PREDICT_FALSE (rv < 0))
Florin Coras0d427d82018-06-27 03:24:07 -0700562 VDBG (0, "VCL<%d>: vpp handle 0x%llx, sid %u: listener unbind "
563 "failed! rv %d (%s)",
564 getpid (), vpp_handle, session_index,
565 rv, vppcom_retval_str (rv));
Dave Wallacef7f809c2017-10-03 01:48:42 -0400566 }
Dave Wallace4878cbe2017-11-21 03:45:09 -0500567
568 else if (state & (CLIENT_STATE_OPEN | SERVER_STATE_OPEN))
Dave Wallacef7f809c2017-10-03 01:48:42 -0400569 {
Dave Wallace4878cbe2017-11-21 03:45:09 -0500570 rv = vppcom_session_disconnect (session_index);
571 if (PREDICT_FALSE (rv < 0))
Dave Wallace048b1d62018-01-03 22:24:41 -0500572 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -0500573 "session disconnect failed! rv %d (%s)",
574 getpid (), vpp_handle, session_index,
575 rv, vppcom_retval_str (rv));
Dave Wallacef7f809c2017-10-03 01:48:42 -0400576 }
Dave Wallace19481612017-09-15 18:47:44 -0400577 }
Dave Wallace4878cbe2017-11-21 03:45:09 -0500578
Dave Wallace7e607a72018-06-18 18:41:32 -0400579 VCL_SESSION_LOCK_AND_GET (session_index, &session);
Dave Wallaceee45d412017-11-24 21:44:06 -0500580 vpp_handle = session->vpp_handle;
581 if (vpp_handle != ~0)
Dave Wallace4878cbe2017-11-21 03:45:09 -0500582 {
Dave Wallaceee45d412017-11-24 21:44:06 -0500583 p = hash_get (vcm->session_index_by_vpp_handles, vpp_handle);
Dave Wallace4878cbe2017-11-21 03:45:09 -0500584 if (p)
Dave Wallaceee45d412017-11-24 21:44:06 -0500585 hash_unset (vcm->session_index_by_vpp_handles, vpp_handle);
Dave Wallace4878cbe2017-11-21 03:45:09 -0500586 }
Dave Wallace543852a2017-08-03 02:11:34 -0400587 pool_put_index (vcm->sessions, session_index);
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -0800588
Dave Wallace7e607a72018-06-18 18:41:32 -0400589 VCL_SESSION_UNLOCK ();
Dave Wallace4878cbe2017-11-21 03:45:09 -0500590
591 if (VPPCOM_DEBUG > 0)
Dave Wallaceee45d412017-11-24 21:44:06 -0500592 {
593 if (is_vep)
Dave Wallace048b1d62018-01-03 22:24:41 -0500594 clib_warning ("VCL<%d>: vep_idx %u / sid %u: epoll session removed.",
Dave Wallaceee45d412017-11-24 21:44:06 -0500595 getpid (), session_index, session_index);
596 else
Dave Wallace048b1d62018-01-03 22:24:41 -0500597 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: session removed.",
Dave Wallaceee45d412017-11-24 21:44:06 -0500598 getpid (), vpp_handle, session_index);
599 }
Dave Wallacef7f809c2017-10-03 01:48:42 -0400600done:
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -0800601
Florin Coras0d427d82018-06-27 03:24:07 -0700602 vcl_evt (VCL_EVT_CLOSE, session, rv);
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -0800603
Dave Wallace543852a2017-08-03 02:11:34 -0400604 return rv;
605}
606
607int
608vppcom_session_bind (uint32_t session_index, vppcom_endpt_t * ep)
609{
Florin Coras7e12d942018-06-27 14:32:43 -0700610 vcl_session_t *session = 0;
Dave Wallace543852a2017-08-03 02:11:34 -0400611 int rv;
612
613 if (!ep || !ep->ip)
614 return VPPCOM_EINVAL;
615
Dave Wallace7e607a72018-06-18 18:41:32 -0400616 VCL_SESSION_LOCK_AND_GET (session_index, &session);
Dave Wallace543852a2017-08-03 02:11:34 -0400617
Dave Wallace9c4b5b22017-10-18 21:15:48 -0400618 if (session->is_vep)
619 {
Dave Wallace7e607a72018-06-18 18:41:32 -0400620 VCL_SESSION_UNLOCK ();
Dave Wallace048b1d62018-01-03 22:24:41 -0500621 clib_warning ("VCL<%d>: ERROR: sid %u: cannot "
622 "bind to an epoll session!", getpid (), session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -0500623 rv = VPPCOM_EBADFD;
624 goto done;
Dave Wallace9c4b5b22017-10-18 21:15:48 -0400625 }
626
Florin Coras7e12d942018-06-27 14:32:43 -0700627 session->transport.is_ip4 = ep->is_ip4;
628 session->transport.lcl_ip = to_ip46 (ep->is_ip4 ? IP46_TYPE_IP4 :
629 IP46_TYPE_IP6, ep->ip);
630 session->transport.lcl_port = ep->port;
Stevenac1f96d2017-10-24 16:03:58 -0700631
Florin Coras0d427d82018-06-27 03:24:07 -0700632 VDBG (0, "VCL<%d>: sid %u: binding to local %s address %U port %u, "
633 "proto %s", getpid (), session_index,
Florin Coras7e12d942018-06-27 14:32:43 -0700634 session->transport.is_ip4 ? "IPv4" : "IPv6",
635 format_ip46_address, &session->transport.lcl_ip,
636 session->transport.is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6,
637 clib_net_to_host_u16 (session->transport.lcl_port),
638 session->session_type ? "UDP" : "TCP");
Florin Coras0d427d82018-06-27 03:24:07 -0700639 vcl_evt (VCL_EVT_BIND, session);
Dave Wallace7e607a72018-06-18 18:41:32 -0400640 VCL_SESSION_UNLOCK ();
Dave Wallace4878cbe2017-11-21 03:45:09 -0500641done:
642 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -0400643}
644
645int
Dave Wallace33e002b2017-09-06 01:20:02 -0400646vppcom_session_listen (uint32_t listen_session_index, uint32_t q_len)
Dave Wallace543852a2017-08-03 02:11:34 -0400647{
Florin Coras7e12d942018-06-27 14:32:43 -0700648 vcl_session_t *listen_session = 0;
Dave Wallaceee45d412017-11-24 21:44:06 -0500649 u64 listen_vpp_handle;
650 int rv, retval;
Dave Wallace543852a2017-08-03 02:11:34 -0400651
Keith Burns (alagalah)aba98de2018-02-22 03:23:40 -0800652 if (q_len == 0 || q_len == ~0)
653 q_len = vcm->cfg.listen_queue_size;
654
Dave Wallace7e607a72018-06-18 18:41:32 -0400655 VCL_SESSION_LOCK_AND_GET (listen_session_index, &listen_session);
Dave Wallace543852a2017-08-03 02:11:34 -0400656
Dave Wallace9c4b5b22017-10-18 21:15:48 -0400657 if (listen_session->is_vep)
658 {
Dave Wallace7e607a72018-06-18 18:41:32 -0400659 VCL_SESSION_UNLOCK ();
Dave Wallace048b1d62018-01-03 22:24:41 -0500660 clib_warning ("VCL<%d>: ERROR: sid %u: cannot listen on an "
Dave Wallace4878cbe2017-11-21 03:45:09 -0500661 "epoll session!", getpid (), listen_session_index);
662 rv = VPPCOM_EBADFD;
663 goto done;
Dave Wallace9c4b5b22017-10-18 21:15:48 -0400664 }
665
Dave Wallaceee45d412017-11-24 21:44:06 -0500666 listen_vpp_handle = listen_session->vpp_handle;
Florin Coras7e12d942018-06-27 14:32:43 -0700667 if (listen_session->session_state & STATE_LISTEN)
Dave Wallacee695cb42017-11-02 22:04:42 -0400668 {
Dave Wallace7e607a72018-06-18 18:41:32 -0400669 VCL_SESSION_UNLOCK ();
Florin Coras0d427d82018-06-27 03:24:07 -0700670 VDBG (0, "VCL<%d>: vpp handle 0x%llx, sid %u: already in listen state!",
671 getpid (), listen_vpp_handle, listen_session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -0500672 rv = VPPCOM_OK;
673 goto done;
Dave Wallacee695cb42017-11-02 22:04:42 -0400674 }
675
Florin Coras0d427d82018-06-27 03:24:07 -0700676 VDBG (0, "VCL<%d>: vpp handle 0x%llx, sid %u: sending VPP bind+listen "
677 "request...", getpid (), listen_vpp_handle, listen_session_index);
Dave Wallace543852a2017-08-03 02:11:34 -0400678
Dave Wallace4878cbe2017-11-21 03:45:09 -0500679 vppcom_send_bind_sock (listen_session, listen_session_index);
Dave Wallace7e607a72018-06-18 18:41:32 -0400680 VCL_SESSION_UNLOCK ();
Dave Wallaceee45d412017-11-24 21:44:06 -0500681 retval =
Dave Wallace33e002b2017-09-06 01:20:02 -0400682 vppcom_wait_for_session_state_change (listen_session_index, STATE_LISTEN,
683 vcm->cfg.session_timeout);
Dave Wallace543852a2017-08-03 02:11:34 -0400684
Dave Wallace7e607a72018-06-18 18:41:32 -0400685 VCL_SESSION_LOCK_AND_GET (listen_session_index, &listen_session);
Dave Wallaceee45d412017-11-24 21:44:06 -0500686 if (PREDICT_FALSE (retval))
687 {
Florin Coras0d427d82018-06-27 03:24:07 -0700688 VDBG (0, "VCL<%d>: vpp handle 0x%llx, sid %u: bind+listen failed! "
689 "returning %d (%s)", getpid (), listen_session->vpp_handle,
690 listen_session_index, retval, vppcom_retval_str (retval));
Dave Wallace7e607a72018-06-18 18:41:32 -0400691 VCL_SESSION_UNLOCK ();
Dave Wallaceee45d412017-11-24 21:44:06 -0500692 rv = retval;
693 goto done;
694 }
695
Dave Wallace7e607a72018-06-18 18:41:32 -0400696 VCL_ACCEPT_FIFO_LOCK ();
Dave Wallace543852a2017-08-03 02:11:34 -0400697 clib_fifo_validate (vcm->client_session_index_fifo, q_len);
Dave Wallace7e607a72018-06-18 18:41:32 -0400698 VCL_ACCEPT_FIFO_UNLOCK ();
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -0800699
Dave Wallace7e607a72018-06-18 18:41:32 -0400700 VCL_SESSION_UNLOCK ();
Keith Burns (alagalah)0d2b0d52018-03-06 15:55:22 -0800701
702done:
703 return rv;
704}
705
706int
Florin Coras7e12d942018-06-27 14:32:43 -0700707validate_args_session_accept_ (vcl_session_t * listen_session)
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800708{
709 u32 listen_session_index = listen_session - vcm->sessions;
710
711 /* Input validation - expects spinlock on sessions_lockp */
712 if (listen_session->is_vep)
713 {
714 clib_warning ("VCL<%d>: ERROR: sid %u: cannot accept on an "
715 "epoll session!", getpid (), listen_session_index);
716 return VPPCOM_EBADFD;
717 }
718
Florin Coras7e12d942018-06-27 14:32:43 -0700719 if (listen_session->session_state != STATE_LISTEN)
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800720 {
721 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
722 "not in listen state! state 0x%x (%s)", getpid (),
723 listen_session->vpp_handle, listen_session_index,
Florin Coras7e12d942018-06-27 14:32:43 -0700724 listen_session->session_state,
725 vppcom_session_state_str (listen_session->session_state));
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800726 return VPPCOM_EBADFD;
727 }
728 return VPPCOM_OK;
729}
730
731int
Dave Wallace543852a2017-08-03 02:11:34 -0400732vppcom_session_accept (uint32_t listen_session_index, vppcom_endpt_t * ep,
Dave Wallace048b1d62018-01-03 22:24:41 -0500733 uint32_t flags)
Dave Wallace543852a2017-08-03 02:11:34 -0400734{
Florin Coras7e12d942018-06-27 14:32:43 -0700735 vcl_session_t *listen_session = 0;
736 vcl_session_t *client_session = 0;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -0800737 u32 client_session_index = ~0;
Dave Wallace543852a2017-08-03 02:11:34 -0400738 int rv;
Dave Wallaceee45d412017-11-24 21:44:06 -0500739 u64 listen_vpp_handle;
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800740 vce_event_handler_reg_t *reg;
741 vce_event_t *ev;
742 vce_event_connect_request_t *result;
743 struct timespec ts;
744 struct timeval tv;
745 int millisecond_timeout = 1;
746 int hours_timeout = 20 * 60 * 60;
Dave Wallace543852a2017-08-03 02:11:34 -0400747
Dave Wallace7e607a72018-06-18 18:41:32 -0400748 VCL_SESSION_LOCK_AND_GET (listen_session_index, &listen_session);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800749 listen_vpp_handle = listen_session->vpp_handle; // For debugging
Dave Wallace543852a2017-08-03 02:11:34 -0400750
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800751 rv = validate_args_session_accept_ (listen_session);
752 if (rv)
Dave Wallace9c4b5b22017-10-18 21:15:48 -0400753 {
Dave Wallace7e607a72018-06-18 18:41:32 -0400754 VCL_SESSION_UNLOCK ();
Dave Wallace4878cbe2017-11-21 03:45:09 -0500755 goto done;
Dave Wallace9c4b5b22017-10-18 21:15:48 -0400756 }
757
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800758 /* Using an aggressive timer of 1ms and a generous timer of
759 * 20 hours, we can implement a blocking and non-blocking listener
760 * as both event and time driven */
761 gettimeofday (&tv, NULL);
762 ts.tv_nsec = (tv.tv_usec * 1000) + (1000 * millisecond_timeout);
763 ts.tv_sec = tv.tv_sec;
764
765 /* Predict that the Listener is blocking more often than not */
766 if (PREDICT_TRUE (!VCL_SESS_ATTR_TEST (listen_session->attr,
767 VCL_SESS_ATTR_NONBLOCK)))
768 ts.tv_sec += hours_timeout;
Dave Wallace543852a2017-08-03 02:11:34 -0400769
Dave Wallace7e607a72018-06-18 18:41:32 -0400770 VCL_SESSION_UNLOCK ();
Dave Wallace543852a2017-08-03 02:11:34 -0400771
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800772 /* Register handler for connect_request event on listen_session_index */
773 vce_event_key_t evk;
774 evk.session_index = listen_session_index;
775 evk.eid = VCL_EVENT_CONNECT_REQ_ACCEPTED;
776 reg = vce_register_handler (&vcm->event_thread, &evk,
Keith Burns (alagalah)0d2b0d52018-03-06 15:55:22 -0800777 vce_connect_request_handler_fn, 0);
Dave Wallace7e607a72018-06-18 18:41:32 -0400778 VCL_EVENTS_LOCK ();
Keith Burns (alagalah)7cf80e02018-03-08 16:46:25 -0800779 ev = vce_get_event_from_index (&vcm->event_thread, reg->ev_idx);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800780 pthread_mutex_lock (&reg->handler_lock);
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -0800781 while (!ev)
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800782 {
Dave Wallace7e607a72018-06-18 18:41:32 -0400783 VCL_EVENTS_UNLOCK ();
Keith Burns (alagalah)410bcca2018-03-23 13:42:49 -0700784 rv = pthread_cond_timedwait (&reg->handler_cond,
785 &reg->handler_lock, &ts);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800786 if (rv == ETIMEDOUT)
787 {
788 rv = VPPCOM_EAGAIN;
789 goto cleanup;
790 }
Dave Wallace7e607a72018-06-18 18:41:32 -0400791 VCL_EVENTS_LOCK ();
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -0800792 ev = vce_get_event_from_index (&vcm->event_thread, reg->ev_idx);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800793 }
Keith Burns (alagalah)410bcca2018-03-23 13:42:49 -0700794 result = vce_get_event_data (ev, sizeof (*result));
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800795 client_session_index = result->accepted_session_index;
Dave Wallace7e607a72018-06-18 18:41:32 -0400796 VCL_EVENTS_UNLOCK ();
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800797
798 /* Remove from the FIFO used to service epoll */
Dave Wallace7e607a72018-06-18 18:41:32 -0400799 VCL_ACCEPT_FIFO_LOCK ();
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800800 if (clib_fifo_elts (vcm->client_session_index_fifo))
801 {
802 u32 tmp_client_session_index;
803 clib_fifo_sub1 (vcm->client_session_index_fifo,
804 tmp_client_session_index);
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -0800805 /* It wasn't ours... put it back ... */
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800806 if (tmp_client_session_index != client_session_index)
807 clib_fifo_add1 (vcm->client_session_index_fifo,
808 tmp_client_session_index);
809 }
Dave Wallace7e607a72018-06-18 18:41:32 -0400810 VCL_ACCEPT_FIFO_UNLOCK ();
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -0800811
Dave Wallace7e607a72018-06-18 18:41:32 -0400812 VCL_SESSION_LOCK ();
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800813
Dave Wallace33e002b2017-09-06 01:20:02 -0400814 rv = vppcom_session_at_index (client_session_index, &client_session);
Dave Wallaceee45d412017-11-24 21:44:06 -0500815 if (PREDICT_FALSE (rv))
816 {
817 rv = VPPCOM_ECONNABORTED;
Dave Wallace048b1d62018-01-03 22:24:41 -0500818 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: client sid %u "
Dave Wallaceee45d412017-11-24 21:44:06 -0500819 "lookup failed! returning %d (%s)", getpid (),
820 listen_vpp_handle, listen_session_index,
821 client_session_index, rv, vppcom_retval_str (rv));
Dave Wallacee5356442018-03-19 10:38:00 -0400822 goto cleanup;
Dave Wallaceee45d412017-11-24 21:44:06 -0500823 }
Dave Wallace543852a2017-08-03 02:11:34 -0400824
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -0800825 if (flags & O_NONBLOCK)
826 VCL_SESS_ATTR_SET (client_session->attr, VCL_SESS_ATTR_NONBLOCK);
827 else
828 VCL_SESS_ATTR_CLR (client_session->attr, VCL_SESS_ATTR_NONBLOCK);
829
Florin Coras0d427d82018-06-27 03:24:07 -0700830 VDBG (0, "VCL<%d>: vpp handle 0x%llx, sid %u: Got a client request! "
831 "vpp handle 0x%llx, sid %u, flags %d, is_nonblocking %u",
832 getpid (), listen_vpp_handle, listen_session_index,
833 client_session->vpp_handle, client_session_index,
834 flags, VCL_SESS_ATTR_TEST (client_session->attr,
835 VCL_SESS_ATTR_NONBLOCK));
Dave Wallace543852a2017-08-03 02:11:34 -0400836
Dave Wallace048b1d62018-01-03 22:24:41 -0500837 if (ep)
838 {
Florin Coras7e12d942018-06-27 14:32:43 -0700839 ep->is_ip4 = client_session->transport.is_ip4;
840 ep->port = client_session->transport.rmt_port;
841 if (client_session->transport.is_ip4)
842 clib_memcpy (ep->ip, &client_session->transport.rmt_ip.ip4,
Dave Wallace048b1d62018-01-03 22:24:41 -0500843 sizeof (ip4_address_t));
844 else
Florin Coras7e12d942018-06-27 14:32:43 -0700845 clib_memcpy (ep->ip, &client_session->transport.rmt_ip.ip6,
Dave Wallace048b1d62018-01-03 22:24:41 -0500846 sizeof (ip6_address_t));
847 }
Dave Wallace60caa062017-11-10 17:07:13 -0500848
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -0800849 vppcom_send_accept_session_reply (client_session->vpp_handle,
850 client_session->client_context,
851 0 /* retval OK */ );
Dave Wallace60caa062017-11-10 17:07:13 -0500852
Florin Coras0d427d82018-06-27 03:24:07 -0700853 VDBG (0, "VCL<%d>: vpp handle 0x%llx, sid %u: accepted vpp handle 0x%llx,"
854 " sid %u connection from peer %s address %U port %u to local %s address"
855 " %U port %u",
856 getpid (), listen_vpp_handle,
857 listen_session_index, client_session->vpp_handle,
858 client_session_index,
Florin Coras7e12d942018-06-27 14:32:43 -0700859 client_session->transport.is_ip4 ? "IPv4" : "IPv6",
860 format_ip46_address, &client_session->transport.rmt_ip,
861 client_session->transport.is_ip4 ?
Florin Coras0d427d82018-06-27 03:24:07 -0700862 IP46_TYPE_IP4 : IP46_TYPE_IP6,
Florin Coras7e12d942018-06-27 14:32:43 -0700863 clib_net_to_host_u16 (client_session->transport.rmt_port),
864 client_session->transport.is_ip4 ? "IPv4" : "IPv6",
865 format_ip46_address, &client_session->transport.lcl_ip,
866 client_session->transport.is_ip4 ?
Florin Coras0d427d82018-06-27 03:24:07 -0700867 IP46_TYPE_IP4 : IP46_TYPE_IP6,
Florin Coras7e12d942018-06-27 14:32:43 -0700868 clib_net_to_host_u16 (client_session->transport.lcl_port));
Florin Coras0d427d82018-06-27 03:24:07 -0700869 vcl_evt (VCL_EVT_ACCEPT, client_session, listen_session,
870 client_session_index);
Dave Wallace7e607a72018-06-18 18:41:32 -0400871 VCL_SESSION_UNLOCK ();
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800872
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -0800873 rv = (int) client_session_index;
Keith Burns (alagalah)410bcca2018-03-23 13:42:49 -0700874 vce_clear_event (&vcm->event_thread, reg->ev_idx);
875 if (vcm->session_io_thread.io_sessions_lockp)
876 {
877 /* Throw this new accepted session index into the rx poll thread pool */
Dave Wallace7e607a72018-06-18 18:41:32 -0400878 VCL_IO_SESSIONS_LOCK ();
Keith Burns (alagalah)410bcca2018-03-23 13:42:49 -0700879 u32 *active_session_index;
880 pool_get (vcm->session_io_thread.active_session_indexes,
881 active_session_index);
882 *active_session_index = client_session_index;
Dave Wallace7e607a72018-06-18 18:41:32 -0400883 VCL_IO_SESSIONS_UNLOCK ();
Keith Burns (alagalah)410bcca2018-03-23 13:42:49 -0700884 }
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800885cleanup:
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -0800886 vce_unregister_handler (&vcm->event_thread, reg);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800887 pthread_mutex_unlock (&reg->handler_lock);
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -0800888
Dave Wallace4878cbe2017-11-21 03:45:09 -0500889done:
890 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -0400891}
892
893int
894vppcom_session_connect (uint32_t session_index, vppcom_endpt_t * server_ep)
895{
Florin Coras7e12d942018-06-27 14:32:43 -0700896 vcl_session_t *session = 0;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -0800897 u64 vpp_handle = 0;
Dave Wallaceee45d412017-11-24 21:44:06 -0500898 int rv, retval = VPPCOM_OK;
Dave Wallace543852a2017-08-03 02:11:34 -0400899
Dave Wallace7e607a72018-06-18 18:41:32 -0400900 VCL_SESSION_LOCK_AND_GET (session_index, &session);
Dave Wallace4878cbe2017-11-21 03:45:09 -0500901
902 if (PREDICT_FALSE (session->is_vep))
Dave Wallace543852a2017-08-03 02:11:34 -0400903 {
Dave Wallace7e607a72018-06-18 18:41:32 -0400904 VCL_SESSION_UNLOCK ();
Dave Wallace048b1d62018-01-03 22:24:41 -0500905 clib_warning ("VCL<%d>: ERROR: sid %u: cannot "
906 "connect on an epoll session!", getpid (), session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -0500907 rv = VPPCOM_EBADFD;
908 goto done;
Dave Wallace543852a2017-08-03 02:11:34 -0400909 }
910
Florin Coras7e12d942018-06-27 14:32:43 -0700911 if (PREDICT_FALSE (session->session_state & CLIENT_STATE_OPEN))
Dave Wallace543852a2017-08-03 02:11:34 -0400912 {
Florin Coras0d427d82018-06-27 03:24:07 -0700913 VDBG (0, "VCL<%d>: vpp handle 0x%llx, sid %u: session already "
914 "connected to %s %U port %d proto %s, state 0x%x (%s)",
915 getpid (), session->vpp_handle, session_index,
Florin Coras7e12d942018-06-27 14:32:43 -0700916 session->transport.is_ip4 ? "IPv4" : "IPv6",
Florin Coras0d427d82018-06-27 03:24:07 -0700917 format_ip46_address,
Florin Coras7e12d942018-06-27 14:32:43 -0700918 &session->transport.rmt_ip, session->transport.is_ip4 ?
Florin Coras0d427d82018-06-27 03:24:07 -0700919 IP46_TYPE_IP4 : IP46_TYPE_IP6,
Florin Coras7e12d942018-06-27 14:32:43 -0700920 clib_net_to_host_u16 (session->transport.rmt_port),
921 session->session_type ? "UDP" : "TCP", session->session_state,
922 vppcom_session_state_str (session->session_state));
Dave Wallace4878cbe2017-11-21 03:45:09 -0500923
Dave Wallace7e607a72018-06-18 18:41:32 -0400924 VCL_SESSION_UNLOCK ();
Dave Wallace4878cbe2017-11-21 03:45:09 -0500925 goto done;
Dave Wallace543852a2017-08-03 02:11:34 -0400926 }
927
Florin Coras7e12d942018-06-27 14:32:43 -0700928 session->transport.is_ip4 = server_ep->is_ip4;
929 if (session->transport.is_ip4)
930 clib_memcpy (&session->transport.rmt_ip.ip4, server_ep->ip,
Dave Wallaced239f8d2018-06-19 13:37:30 -0400931 sizeof (ip4_address_t));
932 else
Florin Coras7e12d942018-06-27 14:32:43 -0700933 clib_memcpy (&session->transport.rmt_ip.ip6, server_ep->ip,
Dave Wallaced239f8d2018-06-19 13:37:30 -0400934 sizeof (ip6_address_t));
Florin Coras7e12d942018-06-27 14:32:43 -0700935 session->transport.rmt_port = server_ep->port;
Dave Wallace543852a2017-08-03 02:11:34 -0400936
Florin Coras0d427d82018-06-27 03:24:07 -0700937 VDBG (0, "VCL<%d>: vpp handle 0x%llx, sid %u: connecting to server %s %U "
938 "port %d proto %s",
939 getpid (), session->vpp_handle, session_index,
Florin Coras7e12d942018-06-27 14:32:43 -0700940 session->transport.is_ip4 ? "IPv4" : "IPv6",
Florin Coras0d427d82018-06-27 03:24:07 -0700941 format_ip46_address,
Florin Coras7e12d942018-06-27 14:32:43 -0700942 &session->transport.rmt_ip, session->transport.is_ip4 ?
Florin Coras0d427d82018-06-27 03:24:07 -0700943 IP46_TYPE_IP4 : IP46_TYPE_IP6,
Florin Coras7e12d942018-06-27 14:32:43 -0700944 clib_net_to_host_u16 (session->transport.rmt_port),
945 session->session_type ? "UDP" : "TCP");
Dave Wallace543852a2017-08-03 02:11:34 -0400946
947 vppcom_send_connect_sock (session, session_index);
Dave Wallace7e607a72018-06-18 18:41:32 -0400948 VCL_SESSION_UNLOCK ();
Dave Wallace4878cbe2017-11-21 03:45:09 -0500949
Dave Wallaceee45d412017-11-24 21:44:06 -0500950 retval =
951 vppcom_wait_for_session_state_change (session_index, STATE_CONNECT,
952 vcm->cfg.session_timeout);
953
Dave Wallace7e607a72018-06-18 18:41:32 -0400954 VCL_SESSION_LOCK_AND_GET (session_index, &session);
Dave Wallaceee45d412017-11-24 21:44:06 -0500955 vpp_handle = session->vpp_handle;
Dave Wallace7e607a72018-06-18 18:41:32 -0400956 VCL_SESSION_UNLOCK ();
Dave Wallace7876d392017-10-19 03:53:57 -0400957
Dave Wallace4878cbe2017-11-21 03:45:09 -0500958done:
Dave Wallaceee45d412017-11-24 21:44:06 -0500959 if (PREDICT_FALSE (retval))
960 {
961 rv = retval;
962 if (VPPCOM_DEBUG > 0)
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -0800963 {
964 if (session)
Florin Coras0d427d82018-06-27 03:24:07 -0700965 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: connect "
966 "failed! returning %d (%s)", getpid (), vpp_handle,
967 session_index, rv, vppcom_retval_str (rv));
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -0800968 else
969 clib_warning ("VCL<%d>: no session for sid %u: connect failed! "
970 "returning %d (%s)", getpid (),
971 session_index, rv, vppcom_retval_str (rv));
972 }
Dave Wallaceee45d412017-11-24 21:44:06 -0500973 }
Florin Coras0d427d82018-06-27 03:24:07 -0700974 else
975 VDBG (0, "VCL<%d>: vpp handle 0x%llx, sid %u: connected!",
976 getpid (), vpp_handle, session_index);
Dave Wallaceee45d412017-11-24 21:44:06 -0500977
Dave Wallace4878cbe2017-11-21 03:45:09 -0500978 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -0400979}
980
Steven58f464e2017-10-25 12:33:12 -0700981static inline int
982vppcom_session_read_internal (uint32_t session_index, void *buf, int n,
983 u8 peek)
Dave Wallace543852a2017-08-03 02:11:34 -0400984{
Florin Coras7e12d942018-06-27 14:32:43 -0700985 vcl_session_t *session = 0;
Dave Wallace543852a2017-08-03 02:11:34 -0400986 svm_fifo_t *rx_fifo;
987 int n_read = 0;
988 int rv;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -0800989 int is_nonblocking;
990
991 u64 vpp_handle;
Dave Wallace9c4b5b22017-10-18 21:15:48 -0400992 u32 poll_et;
Dave Wallace4878cbe2017-11-21 03:45:09 -0500993 session_state_t state;
Dave Wallace543852a2017-08-03 02:11:34 -0400994
995 ASSERT (buf);
996
Dave Wallace7e607a72018-06-18 18:41:32 -0400997 VCL_SESSION_LOCK_AND_GET (session_index, &session);
Dave Wallace4878cbe2017-11-21 03:45:09 -0500998
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -0800999 is_nonblocking = VCL_SESS_ATTR_TEST (session->attr, VCL_SESS_ATTR_NONBLOCK);
1000 rx_fifo = session->rx_fifo;
Florin Coras7e12d942018-06-27 14:32:43 -07001001 state = session->session_state;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001002 vpp_handle = session->vpp_handle;
1003
Dave Wallace4878cbe2017-11-21 03:45:09 -05001004 if (PREDICT_FALSE (session->is_vep))
Dave Wallace543852a2017-08-03 02:11:34 -04001005 {
Dave Wallace7e607a72018-06-18 18:41:32 -04001006 VCL_SESSION_UNLOCK ();
Dave Wallace048b1d62018-01-03 22:24:41 -05001007 clib_warning ("VCL<%d>: ERROR: sid %u: cannot "
1008 "read from an epoll session!", getpid (), session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001009 rv = VPPCOM_EBADFD;
1010 goto done;
Dave Wallace543852a2017-08-03 02:11:34 -04001011 }
1012
Dave Wallace4878cbe2017-11-21 03:45:09 -05001013 if (PREDICT_FALSE (!(state & (SERVER_STATE_OPEN | CLIENT_STATE_OPEN))))
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001014 {
Dave Wallace7e607a72018-06-18 18:41:32 -04001015 VCL_SESSION_UNLOCK ();
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08001016 rv = ((state & STATE_DISCONNECT) ? VPPCOM_ECONNRESET : VPPCOM_ENOTCONN);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001017
Florin Coras0d427d82018-06-27 03:24:07 -07001018 VDBG (0, "VCL<%d>: vpp handle 0x%llx, sid %u: %s session is not open! "
1019 "state 0x%x (%s), returning %d (%s)",
1020 getpid (), vpp_handle, session_index, state,
1021 vppcom_session_state_str (state), rv, vppcom_retval_str (rv));
Dave Wallace4878cbe2017-11-21 03:45:09 -05001022 goto done;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001023 }
1024
Dave Wallace7e607a72018-06-18 18:41:32 -04001025 VCL_SESSION_UNLOCK ();
Dave Wallacef7f809c2017-10-03 01:48:42 -04001026
1027 do
1028 {
Steven58f464e2017-10-25 12:33:12 -07001029 if (peek)
1030 n_read = svm_fifo_peek (rx_fifo, 0, n, buf);
1031 else
1032 n_read = svm_fifo_dequeue_nowait (rx_fifo, n, buf);
Dave Wallacef7f809c2017-10-03 01:48:42 -04001033 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05001034 while (!is_nonblocking && (n_read <= 0));
Dave Wallacef7f809c2017-10-03 01:48:42 -04001035
Dave Wallace4878cbe2017-11-21 03:45:09 -05001036 if (n_read <= 0)
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001037 {
Dave Wallace7e607a72018-06-18 18:41:32 -04001038 VCL_SESSION_LOCK_AND_GET (session_index, &session);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001039
1040 poll_et = (((EPOLLET | EPOLLIN) & session->vep.ev.events) ==
1041 (EPOLLET | EPOLLIN));
1042 if (poll_et)
1043 session->vep.et_mask |= EPOLLIN;
1044
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08001045 if (state & STATE_CLOSE_ON_EMPTY)
Dave Wallace4878cbe2017-11-21 03:45:09 -05001046 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05001047 rv = VPPCOM_ECONNRESET;
1048
Florin Coras0d427d82018-06-27 03:24:07 -07001049 VDBG (1, "VCL<%d>: vpp handle 0x%llx, sid %u: Empty fifo with "
1050 "session state 0x%x (%s)! Setting state to 0x%x (%s), "
1051 "returning %d (%s)",
1052 getpid (), session->vpp_handle, session_index,
1053 state, vppcom_session_state_str (state),
1054 STATE_DISCONNECT,
1055 vppcom_session_state_str (STATE_DISCONNECT), rv,
1056 vppcom_retval_str (rv));
Dave Wallace4878cbe2017-11-21 03:45:09 -05001057
Florin Coras7e12d942018-06-27 14:32:43 -07001058 session->session_state = STATE_DISCONNECT;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001059 }
1060 else
1061 rv = VPPCOM_EAGAIN;
1062
Dave Wallace7e607a72018-06-18 18:41:32 -04001063 VCL_SESSION_UNLOCK ();
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001064 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05001065 else
1066 rv = n_read;
Dave Wallace543852a2017-08-03 02:11:34 -04001067
Dave Wallace4878cbe2017-11-21 03:45:09 -05001068 if (VPPCOM_DEBUG > 2)
1069 {
1070 if (rv > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001071 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: read %d bytes "
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001072 "from (%p)", getpid (), vpp_handle,
1073 session_index, n_read, rx_fifo);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001074 else
Dave Wallace048b1d62018-01-03 22:24:41 -05001075 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: nothing read! "
Dave Wallaceee45d412017-11-24 21:44:06 -05001076 "returning %d (%s)", getpid (), vpp_handle,
1077 session_index, rv, vppcom_retval_str (rv));
Dave Wallace4878cbe2017-11-21 03:45:09 -05001078 }
1079done:
1080 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04001081}
1082
Steven58f464e2017-10-25 12:33:12 -07001083int
Dave Wallace048b1d62018-01-03 22:24:41 -05001084vppcom_session_read (uint32_t session_index, void *buf, size_t n)
Steven58f464e2017-10-25 12:33:12 -07001085{
1086 return (vppcom_session_read_internal (session_index, buf, n, 0));
1087}
1088
1089static int
1090vppcom_session_peek (uint32_t session_index, void *buf, int n)
1091{
1092 return (vppcom_session_read_internal (session_index, buf, n, 1));
1093}
1094
Dave Wallace543852a2017-08-03 02:11:34 -04001095static inline int
Florin Coras7e12d942018-06-27 14:32:43 -07001096vppcom_session_read_ready (vcl_session_t * session, u32 session_index)
Dave Wallace543852a2017-08-03 02:11:34 -04001097{
Dave Wallace543852a2017-08-03 02:11:34 -04001098 int ready = 0;
Dave Wallace60caa062017-11-10 17:07:13 -05001099 u32 poll_et;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001100 int rv;
Florin Coras7e12d942018-06-27 14:32:43 -07001101 session_state_t state = session->session_state;
Dave Wallaceee45d412017-11-24 21:44:06 -05001102 u64 vpp_handle = session->vpp_handle;
Dave Wallace543852a2017-08-03 02:11:34 -04001103
1104 /* Assumes caller has acquired spinlock: vcm->sessions_lockp */
Dave Wallace4878cbe2017-11-21 03:45:09 -05001105 if (PREDICT_FALSE (session->is_vep))
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001106 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001107 clib_warning ("VCL<%d>: ERROR: sid %u: cannot read from an "
Dave Wallace4878cbe2017-11-21 03:45:09 -05001108 "epoll session!", getpid (), session_index);
1109 rv = VPPCOM_EBADFD;
1110 goto done;
Dave Wallace543852a2017-08-03 02:11:34 -04001111 }
Dave Wallace33e002b2017-09-06 01:20:02 -04001112
Florin Coras7e12d942018-06-27 14:32:43 -07001113 if (session->session_state & STATE_LISTEN)
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001114 {
Dave Wallace7e607a72018-06-18 18:41:32 -04001115 VCL_ACCEPT_FIFO_LOCK ();
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001116 ready = clib_fifo_elts (vcm->client_session_index_fifo);
Dave Wallace7e607a72018-06-18 18:41:32 -04001117 VCL_ACCEPT_FIFO_UNLOCK ();
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001118 }
Dave Wallace543852a2017-08-03 02:11:34 -04001119 else
1120 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05001121 if (!(state & (SERVER_STATE_OPEN | CLIENT_STATE_OPEN | STATE_LISTEN)))
1122 {
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08001123 rv = ((state & STATE_DISCONNECT) ? VPPCOM_ECONNRESET :
Dave Wallace4878cbe2017-11-21 03:45:09 -05001124 VPPCOM_ENOTCONN);
1125
Florin Coras0d427d82018-06-27 03:24:07 -07001126 VDBG (1, "VCL<%d>: vpp handle 0x%llx, sid %u: session is not open!"
1127 " state 0x%x (%s), returning %d (%s)",
1128 getpid (), vpp_handle, session_index,
1129 state, vppcom_session_state_str (state),
1130 rv, vppcom_retval_str (rv));
Dave Wallace4878cbe2017-11-21 03:45:09 -05001131 goto done;
1132 }
1133
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001134 ready = svm_fifo_max_dequeue (session->rx_fifo);
Dave Wallace543852a2017-08-03 02:11:34 -04001135 }
1136
Dave Wallace4878cbe2017-11-21 03:45:09 -05001137 if (ready == 0)
Dave Wallace60caa062017-11-10 17:07:13 -05001138 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05001139 poll_et =
1140 ((EPOLLET | EPOLLIN) & session->vep.ev.events) == (EPOLLET | EPOLLIN);
1141 if (poll_et)
1142 session->vep.et_mask |= EPOLLIN;
Dave Wallace60caa062017-11-10 17:07:13 -05001143
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08001144 if (state & STATE_CLOSE_ON_EMPTY)
Dave Wallace4878cbe2017-11-21 03:45:09 -05001145 {
1146 rv = VPPCOM_ECONNRESET;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001147
Florin Coras0d427d82018-06-27 03:24:07 -07001148 VDBG (1, "VCL<%d>: vpp handle 0x%llx, sid %u: Empty fifo with "
1149 "session state 0x%x (%s)! Setting state to 0x%x (%s), "
1150 "returning %d (%s)",
1151 getpid (), session_index, vpp_handle,
1152 state, vppcom_session_state_str (state),
1153 STATE_DISCONNECT,
1154 vppcom_session_state_str (STATE_DISCONNECT), rv,
1155 vppcom_retval_str (rv));
Florin Coras7e12d942018-06-27 14:32:43 -07001156 session->session_state = STATE_DISCONNECT;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001157 goto done;
1158 }
1159 }
1160 rv = ready;
Dave Wallace16cb4082017-11-29 03:24:06 -05001161
Florin Coras3c2fed52018-07-04 04:15:05 -07001162 if (!svm_msg_q_is_empty (vcm->app_event_queue) &&
1163 !pthread_mutex_trylock (&vcm->app_event_queue->q->mutex))
Dave Wallace16cb4082017-11-29 03:24:06 -05001164 {
Florin Coras3c2fed52018-07-04 04:15:05 -07001165 u32 i, n_to_dequeue = vcm->app_event_queue->q->cursize;
1166 svm_msg_q_msg_t msg;
Dave Wallace16cb4082017-11-29 03:24:06 -05001167
1168 for (i = 0; i < n_to_dequeue; i++)
Florin Coras3c2fed52018-07-04 04:15:05 -07001169 {
1170 svm_queue_sub_raw (vcm->app_event_queue->q, (u8 *) & msg);
1171 svm_msg_q_free_msg (vcm->app_event_queue, &msg);
1172 }
Dave Wallace16cb4082017-11-29 03:24:06 -05001173
Florin Coras3c2fed52018-07-04 04:15:05 -07001174 pthread_mutex_unlock (&vcm->app_event_queue->q->mutex);
Dave Wallace16cb4082017-11-29 03:24:06 -05001175 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05001176done:
1177 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04001178}
1179
1180int
Dave Wallace048b1d62018-01-03 22:24:41 -05001181vppcom_session_write (uint32_t session_index, void *buf, size_t n)
Dave Wallace543852a2017-08-03 02:11:34 -04001182{
Florin Coras7e12d942018-06-27 14:32:43 -07001183 vcl_session_t *session = 0;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001184 svm_fifo_t *tx_fifo = 0;
Florin Coras3c2fed52018-07-04 04:15:05 -07001185 svm_msg_q_t *mq;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001186 session_state_t state;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001187 int rv, n_write, is_nonblocking;
1188 u32 poll_et;
Dave Wallaceee45d412017-11-24 21:44:06 -05001189 u64 vpp_handle;
Dave Wallace543852a2017-08-03 02:11:34 -04001190
1191 ASSERT (buf);
1192
Dave Wallace7e607a72018-06-18 18:41:32 -04001193 VCL_SESSION_LOCK_AND_GET (session_index, &session);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001194
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001195 tx_fifo = session->tx_fifo;
1196 is_nonblocking = VCL_SESS_ATTR_TEST (session->attr, VCL_SESS_ATTR_NONBLOCK);
1197 vpp_handle = session->vpp_handle;
Florin Coras7e12d942018-06-27 14:32:43 -07001198 state = session->session_state;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001199
Dave Wallace4878cbe2017-11-21 03:45:09 -05001200 if (PREDICT_FALSE (session->is_vep))
Dave Wallace543852a2017-08-03 02:11:34 -04001201 {
Dave Wallace7e607a72018-06-18 18:41:32 -04001202 VCL_SESSION_UNLOCK ();
Dave Wallace048b1d62018-01-03 22:24:41 -05001203 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -05001204 "cannot write to an epoll session!",
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001205 getpid (), vpp_handle, session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001206
1207 rv = VPPCOM_EBADFD;
1208 goto done;
Dave Wallace543852a2017-08-03 02:11:34 -04001209 }
1210
Florin Coras7e12d942018-06-27 14:32:43 -07001211 if (!(session->session_state & (SERVER_STATE_OPEN | CLIENT_STATE_OPEN)))
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001212 {
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001213 rv =
Florin Coras7e12d942018-06-27 14:32:43 -07001214 ((session->session_state & STATE_DISCONNECT) ? VPPCOM_ECONNRESET :
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001215 VPPCOM_ENOTCONN);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001216
Dave Wallace7e607a72018-06-18 18:41:32 -04001217 VCL_SESSION_UNLOCK ();
Florin Coras0d427d82018-06-27 03:24:07 -07001218 VDBG (1, "VCL<%d>: vpp handle 0x%llx, sid %u: session is not open! "
1219 "state 0x%x (%s)",
1220 getpid (), vpp_handle, session_index,
1221 state, vppcom_session_state_str (state));
Dave Wallace4878cbe2017-11-21 03:45:09 -05001222 goto done;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001223 }
1224
Dave Wallace7e607a72018-06-18 18:41:32 -04001225 VCL_SESSION_UNLOCK ();
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001226
Dave Wallace543852a2017-08-03 02:11:34 -04001227 do
1228 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001229 n_write = svm_fifo_enqueue_nowait (tx_fifo, n, (void *) buf);
Dave Wallace543852a2017-08-03 02:11:34 -04001230 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05001231 while (!is_nonblocking && (n_write <= 0));
Dave Wallace543852a2017-08-03 02:11:34 -04001232
Keith Burns (alagalah)410bcca2018-03-23 13:42:49 -07001233 /* If event wasn't set, add one
1234 *
1235 * To reduce context switching, can check if an
1236 * event is already there for this event_key, but for now
1237 * this will suffice. */
1238
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001239 if ((n_write > 0) && svm_fifo_set_event (tx_fifo))
Dave Wallace543852a2017-08-03 02:11:34 -04001240 {
Florin Coras3c2fed52018-07-04 04:15:05 -07001241 /* Send TX event to vpp */
Dave Wallace7e607a72018-06-18 18:41:32 -04001242 VCL_SESSION_LOCK_AND_GET (session_index, &session);
Florin Coras3c2fed52018-07-04 04:15:05 -07001243 mq = session->vpp_evt_q;
1244 ASSERT (mq);
1245 app_send_io_evt_to_vpp (mq, tx_fifo, FIFO_EVENT_APP_TX, SVM_Q_WAIT);
Dave Wallace7e607a72018-06-18 18:41:32 -04001246 VCL_SESSION_UNLOCK ();
Florin Coras0d427d82018-06-27 03:24:07 -07001247 VDBG (1, "VCL<%d>: vpp handle 0x%llx, sid %u: added FIFO_EVENT_APP_TX "
1248 "to vpp_event_q %p, n_write %d", getpid (),
Florin Coras3c2fed52018-07-04 04:15:05 -07001249 vpp_handle, session_index, mq, n_write);
Dave Wallace543852a2017-08-03 02:11:34 -04001250 }
1251
Dave Wallace4878cbe2017-11-21 03:45:09 -05001252 if (n_write <= 0)
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001253 {
Dave Wallace7e607a72018-06-18 18:41:32 -04001254 VCL_SESSION_LOCK_AND_GET (session_index, &session);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001255
1256 poll_et = (((EPOLLET | EPOLLOUT) & session->vep.ev.events) ==
1257 (EPOLLET | EPOLLOUT));
1258 if (poll_et)
1259 session->vep.et_mask |= EPOLLOUT;
1260
Florin Coras7e12d942018-06-27 14:32:43 -07001261 if (session->session_state & STATE_CLOSE_ON_EMPTY)
Dave Wallace4878cbe2017-11-21 03:45:09 -05001262 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05001263 rv = VPPCOM_ECONNRESET;
1264
Florin Coras0d427d82018-06-27 03:24:07 -07001265 VDBG (1, "VCL<%d>: vpp handle 0x%llx, sid %u: Empty fifo with "
1266 "session state 0x%x (%s)! Setting state to 0x%x (%s), "
1267 "returning %d (%s)",
1268 getpid (), session->vpp_handle, session_index,
Florin Coras7e12d942018-06-27 14:32:43 -07001269 session->session_state,
1270 vppcom_session_state_str (session->session_state),
Florin Coras0d427d82018-06-27 03:24:07 -07001271 STATE_DISCONNECT,
1272 vppcom_session_state_str (STATE_DISCONNECT), rv,
1273 vppcom_retval_str (rv));
Dave Wallace4878cbe2017-11-21 03:45:09 -05001274
Florin Coras7e12d942018-06-27 14:32:43 -07001275 session->session_state = STATE_DISCONNECT;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001276 }
1277 else
1278 rv = VPPCOM_EAGAIN;
1279
Dave Wallace7e607a72018-06-18 18:41:32 -04001280 VCL_SESSION_UNLOCK ();
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001281 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05001282 else
1283 rv = n_write;
Dave Wallacef7f809c2017-10-03 01:48:42 -04001284
Dave Wallace543852a2017-08-03 02:11:34 -04001285 if (VPPCOM_DEBUG > 2)
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001286 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05001287 if (n_write <= 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001288 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001289 "FIFO-FULL (%p)", getpid (), vpp_handle,
1290 session_index, tx_fifo);
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001291 else
Dave Wallace048b1d62018-01-03 22:24:41 -05001292 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001293 "wrote %d bytes tx-fifo: (%p)", getpid (),
1294 vpp_handle, session_index, n_write, tx_fifo);
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001295 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05001296done:
1297 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04001298}
1299
1300static inline int
Florin Coras7e12d942018-06-27 14:32:43 -07001301vppcom_session_write_ready (vcl_session_t * session, u32 session_index)
Dave Wallace543852a2017-08-03 02:11:34 -04001302{
Dave Wallacef7f809c2017-10-03 01:48:42 -04001303 int ready;
Dave Wallace60caa062017-11-10 17:07:13 -05001304 u32 poll_et;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001305 int rv;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001306
1307 ASSERT (session);
Dave Wallace543852a2017-08-03 02:11:34 -04001308
1309 /* Assumes caller has acquired spinlock: vcm->sessions_lockp */
Dave Wallace4878cbe2017-11-21 03:45:09 -05001310 if (PREDICT_FALSE (session->is_vep))
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001311 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001312 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -05001313 "cannot write to an epoll session!",
1314 getpid (), session->vpp_handle, session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001315 rv = VPPCOM_EBADFD;
1316 goto done;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001317 }
1318
Florin Coras7e12d942018-06-27 14:32:43 -07001319 if (PREDICT_FALSE (session->session_state & STATE_LISTEN))
Dave Wallace33e002b2017-09-06 01:20:02 -04001320 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001321 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -05001322 "cannot write to a listen session!",
1323 getpid (), session->vpp_handle, session_index);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001324 rv = VPPCOM_EBADFD;
1325 goto done;
1326 }
1327
Florin Coras7e12d942018-06-27 14:32:43 -07001328 if (!(session->session_state & (SERVER_STATE_OPEN | CLIENT_STATE_OPEN)))
Dave Wallace4878cbe2017-11-21 03:45:09 -05001329 {
Florin Coras7e12d942018-06-27 14:32:43 -07001330 session_state_t state = session->session_state;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001331
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08001332 rv = ((state & STATE_DISCONNECT) ? VPPCOM_ECONNRESET : VPPCOM_ENOTCONN);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001333
Dave Wallace048b1d62018-01-03 22:24:41 -05001334 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001335 "session is not open! state 0x%x (%s), "
Dave Wallaceee45d412017-11-24 21:44:06 -05001336 "returning %d (%s)", getpid (), session->vpp_handle,
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001337 session_index,
Dave Wallace4878cbe2017-11-21 03:45:09 -05001338 state, vppcom_session_state_str (state),
1339 rv, vppcom_retval_str (rv));
1340 goto done;
Dave Wallace33e002b2017-09-06 01:20:02 -04001341 }
1342
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001343 ready = svm_fifo_max_enqueue (session->tx_fifo);
Dave Wallace543852a2017-08-03 02:11:34 -04001344
Florin Coras0d427d82018-06-27 03:24:07 -07001345 VDBG (3, "VCL<%d>: vpp handle 0x%llx, sid %u: peek %s (%p), ready = %d",
1346 getpid (), session->vpp_handle, session_index, session->tx_fifo,
1347 ready);
Dave Wallacef7f809c2017-10-03 01:48:42 -04001348
Dave Wallace4878cbe2017-11-21 03:45:09 -05001349 if (ready == 0)
1350 {
1351 poll_et = (((EPOLLET | EPOLLOUT) & session->vep.ev.events) ==
1352 (EPOLLET | EPOLLOUT));
1353 if (poll_et)
1354 session->vep.et_mask |= EPOLLOUT;
1355
Florin Coras7e12d942018-06-27 14:32:43 -07001356 if (session->session_state & STATE_CLOSE_ON_EMPTY)
Dave Wallace4878cbe2017-11-21 03:45:09 -05001357 {
1358 rv = VPPCOM_ECONNRESET;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001359
Florin Coras0d427d82018-06-27 03:24:07 -07001360 VDBG (1, "VCL<%d>: vpp handle 0x%llx, sid %u: Empty fifo with "
1361 "session state 0x%x (%s)! Setting state to 0x%x (%s), "
1362 "returning %d (%s)", getpid (),
1363 session->vpp_handle, session_index,
Florin Coras7e12d942018-06-27 14:32:43 -07001364 session->session_state,
1365 vppcom_session_state_str (session->session_state),
Florin Coras0d427d82018-06-27 03:24:07 -07001366 STATE_DISCONNECT,
1367 vppcom_session_state_str (STATE_DISCONNECT), rv,
1368 vppcom_retval_str (rv));
Florin Coras7e12d942018-06-27 14:32:43 -07001369 session->session_state = STATE_DISCONNECT;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001370 goto done;
1371 }
1372 }
1373 rv = ready;
1374done:
1375 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04001376}
1377
1378int
1379vppcom_select (unsigned long n_bits, unsigned long *read_map,
1380 unsigned long *write_map, unsigned long *except_map,
1381 double time_to_wait)
1382{
Dave Wallace543852a2017-08-03 02:11:34 -04001383 u32 session_index;
Florin Coras7e12d942018-06-27 14:32:43 -07001384 vcl_session_t *session = 0;
Dave Wallace543852a2017-08-03 02:11:34 -04001385 int rv, bits_set = 0;
1386 f64 timeout = clib_time_now (&vcm->clib_time) + time_to_wait;
1387 u32 minbits = clib_max (n_bits, BITS (uword));
1388
1389 ASSERT (sizeof (clib_bitmap_t) == sizeof (long int));
1390
Dave Wallace7876d392017-10-19 03:53:57 -04001391 if (n_bits && read_map)
Dave Wallace543852a2017-08-03 02:11:34 -04001392 {
1393 clib_bitmap_validate (vcm->rd_bitmap, minbits);
Dave Wallace048b1d62018-01-03 22:24:41 -05001394 clib_memcpy (vcm->rd_bitmap, read_map,
1395 vec_len (vcm->rd_bitmap) * sizeof (clib_bitmap_t));
1396 memset (read_map, 0, vec_len (vcm->rd_bitmap) * sizeof (clib_bitmap_t));
Dave Wallace543852a2017-08-03 02:11:34 -04001397 }
Dave Wallace7876d392017-10-19 03:53:57 -04001398 if (n_bits && write_map)
Dave Wallace543852a2017-08-03 02:11:34 -04001399 {
1400 clib_bitmap_validate (vcm->wr_bitmap, minbits);
Dave Wallace048b1d62018-01-03 22:24:41 -05001401 clib_memcpy (vcm->wr_bitmap, write_map,
1402 vec_len (vcm->wr_bitmap) * sizeof (clib_bitmap_t));
1403 memset (write_map, 0,
1404 vec_len (vcm->wr_bitmap) * sizeof (clib_bitmap_t));
Dave Wallace543852a2017-08-03 02:11:34 -04001405 }
Dave Wallace7876d392017-10-19 03:53:57 -04001406 if (n_bits && except_map)
Dave Wallace543852a2017-08-03 02:11:34 -04001407 {
1408 clib_bitmap_validate (vcm->ex_bitmap, minbits);
Dave Wallace048b1d62018-01-03 22:24:41 -05001409 clib_memcpy (vcm->ex_bitmap, except_map,
1410 vec_len (vcm->ex_bitmap) * sizeof (clib_bitmap_t));
1411 memset (except_map, 0,
1412 vec_len (vcm->ex_bitmap) * sizeof (clib_bitmap_t));
Dave Wallace543852a2017-08-03 02:11:34 -04001413 }
1414
1415 do
1416 {
1417 /* *INDENT-OFF* */
Dave Wallacee22aa742017-10-20 12:30:38 -04001418 if (n_bits)
1419 {
1420 if (read_map)
Dave Wallace543852a2017-08-03 02:11:34 -04001421 {
Dave Wallacee22aa742017-10-20 12:30:38 -04001422 clib_bitmap_foreach (session_index, vcm->rd_bitmap,
1423 ({
Dave Wallace7e607a72018-06-18 18:41:32 -04001424 VCL_SESSION_LOCK();
Dave Wallacee22aa742017-10-20 12:30:38 -04001425 rv = vppcom_session_at_index (session_index, &session);
1426 if (rv < 0)
1427 {
Dave Wallace7e607a72018-06-18 18:41:32 -04001428 VCL_SESSION_UNLOCK();
Florin Coras0d427d82018-06-27 03:24:07 -07001429 VDBG (1, "VCL<%d>: session %d specified in read_map is"
1430 " closed.", getpid (),
Dave Wallacee22aa742017-10-20 12:30:38 -04001431 session_index);
1432 bits_set = VPPCOM_EBADFD;
1433 goto select_done;
1434 }
Florin Coras7e12d942018-06-27 14:32:43 -07001435 if (session->session_state & STATE_LISTEN)
Dave Wallace8d73e852018-03-08 16:39:28 -05001436 {
1437 vce_event_handler_reg_t *reg = 0;
1438 vce_event_key_t evk;
Dave Wallacee22aa742017-10-20 12:30:38 -04001439
Dave Wallace8d73e852018-03-08 16:39:28 -05001440 /* Check if handler already registered for this
1441 * event.
1442 * If not, register handler for connect_request event
1443 * on listen_session_index
1444 */
1445 evk.session_index = session_index;
1446 evk.eid = VCL_EVENT_CONNECT_REQ_ACCEPTED;
1447 reg = vce_get_event_handler (&vcm->event_thread, &evk);
1448 if (!reg)
1449 reg = vce_register_handler (&vcm->event_thread, &evk,
Keith Burns (alagalah)0d2b0d52018-03-06 15:55:22 -08001450 vce_poll_wait_connect_request_handler_fn,
1451 0 /* No callback args */);
Dave Wallace8d73e852018-03-08 16:39:28 -05001452 rv = vppcom_session_read_ready (session, session_index);
1453 if (rv > 0)
1454 {
1455 vce_unregister_handler (&vcm->event_thread, reg);
1456 }
1457 }
1458 else
1459 rv = vppcom_session_read_ready (session, session_index);
Dave Wallace7e607a72018-06-18 18:41:32 -04001460 VCL_SESSION_UNLOCK();
Dave Wallacee22aa742017-10-20 12:30:38 -04001461 if (except_map && vcm->ex_bitmap &&
1462 clib_bitmap_get (vcm->ex_bitmap, session_index) &&
1463 (rv < 0))
1464 {
Dave Wallacee22aa742017-10-20 12:30:38 -04001465 clib_bitmap_set_no_check (except_map, session_index, 1);
1466 bits_set++;
1467 }
1468 else if (rv > 0)
1469 {
Dave Wallacee22aa742017-10-20 12:30:38 -04001470 clib_bitmap_set_no_check (read_map, session_index, 1);
1471 bits_set++;
1472 }
1473 }));
Dave Wallace543852a2017-08-03 02:11:34 -04001474 }
1475
Dave Wallacee22aa742017-10-20 12:30:38 -04001476 if (write_map)
Dave Wallace543852a2017-08-03 02:11:34 -04001477 {
Dave Wallacee22aa742017-10-20 12:30:38 -04001478 clib_bitmap_foreach (session_index, vcm->wr_bitmap,
1479 ({
Dave Wallace7e607a72018-06-18 18:41:32 -04001480 VCL_SESSION_LOCK();
Dave Wallacee22aa742017-10-20 12:30:38 -04001481 rv = vppcom_session_at_index (session_index, &session);
1482 if (rv < 0)
1483 {
Dave Wallace7e607a72018-06-18 18:41:32 -04001484 VCL_SESSION_UNLOCK();
Florin Coras0d427d82018-06-27 03:24:07 -07001485 VDBG (0, "VCL<%d>: session %d specified in "
Dave Wallace2e005bb2017-11-07 01:21:39 -05001486 "write_map is closed.", getpid (),
Dave Wallacee22aa742017-10-20 12:30:38 -04001487 session_index);
1488 bits_set = VPPCOM_EBADFD;
1489 goto select_done;
1490 }
Dave Wallace543852a2017-08-03 02:11:34 -04001491
Dave Wallacee22aa742017-10-20 12:30:38 -04001492 rv = vppcom_session_write_ready (session, session_index);
Dave Wallace7e607a72018-06-18 18:41:32 -04001493 VCL_SESSION_UNLOCK();
Dave Wallacee22aa742017-10-20 12:30:38 -04001494 if (write_map && (rv > 0))
1495 {
Dave Wallacee22aa742017-10-20 12:30:38 -04001496 clib_bitmap_set_no_check (write_map, session_index, 1);
1497 bits_set++;
1498 }
1499 }));
Dave Wallace543852a2017-08-03 02:11:34 -04001500 }
1501
Dave Wallacee22aa742017-10-20 12:30:38 -04001502 if (except_map)
Dave Wallace543852a2017-08-03 02:11:34 -04001503 {
Dave Wallacee22aa742017-10-20 12:30:38 -04001504 clib_bitmap_foreach (session_index, vcm->ex_bitmap,
1505 ({
Dave Wallace7e607a72018-06-18 18:41:32 -04001506 VCL_SESSION_LOCK();
Dave Wallacee22aa742017-10-20 12:30:38 -04001507 rv = vppcom_session_at_index (session_index, &session);
1508 if (rv < 0)
1509 {
Dave Wallace7e607a72018-06-18 18:41:32 -04001510 VCL_SESSION_UNLOCK();
Florin Coras0d427d82018-06-27 03:24:07 -07001511 VDBG (1, "VCL<%d>: session %d specified in except_map "
1512 "is closed.", getpid (),
Dave Wallacee22aa742017-10-20 12:30:38 -04001513 session_index);
1514 bits_set = VPPCOM_EBADFD;
1515 goto select_done;
1516 }
Dave Wallace543852a2017-08-03 02:11:34 -04001517
Dave Wallacee22aa742017-10-20 12:30:38 -04001518 rv = vppcom_session_read_ready (session, session_index);
Dave Wallace7e607a72018-06-18 18:41:32 -04001519 VCL_SESSION_UNLOCK();
Dave Wallacee22aa742017-10-20 12:30:38 -04001520 if (rv < 0)
1521 {
Dave Wallacee22aa742017-10-20 12:30:38 -04001522 clib_bitmap_set_no_check (except_map, session_index, 1);
1523 bits_set++;
1524 }
1525 }));
Dave Wallace543852a2017-08-03 02:11:34 -04001526 }
Dave Wallacee22aa742017-10-20 12:30:38 -04001527 }
Dave Wallace543852a2017-08-03 02:11:34 -04001528 /* *INDENT-ON* */
1529 }
Dave Wallace048b1d62018-01-03 22:24:41 -05001530 while ((time_to_wait == -1) || (clib_time_now (&vcm->clib_time) < timeout));
Dave Wallace543852a2017-08-03 02:11:34 -04001531
1532select_done:
1533 return (bits_set);
1534}
1535
Dave Wallacef7f809c2017-10-03 01:48:42 -04001536static inline void
1537vep_verify_epoll_chain (u32 vep_idx)
1538{
Florin Coras7e12d942018-06-27 14:32:43 -07001539 vcl_session_t *session;
Dave Wallacef7f809c2017-10-03 01:48:42 -04001540 vppcom_epoll_t *vep;
1541 int rv;
Dave Wallace498b3a52017-11-09 13:00:34 -05001542 u32 sid = vep_idx;
Dave Wallacef7f809c2017-10-03 01:48:42 -04001543
Dave Wallace498b3a52017-11-09 13:00:34 -05001544 if (VPPCOM_DEBUG <= 1)
Dave Wallacef7f809c2017-10-03 01:48:42 -04001545 return;
1546
1547 /* Assumes caller has acquired spinlock: vcm->sessions_lockp */
1548 rv = vppcom_session_at_index (vep_idx, &session);
1549 if (PREDICT_FALSE (rv))
1550 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001551 clib_warning ("VCL<%d>: ERROR: Invalid vep_idx (%u)!",
1552 getpid (), vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04001553 goto done;
1554 }
1555 if (PREDICT_FALSE (!session->is_vep))
1556 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001557 clib_warning ("VCL<%d>: ERROR: vep_idx (%u) is not a vep!",
1558 getpid (), vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04001559 goto done;
1560 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05001561 vep = &session->vep;
Dave Wallace048b1d62018-01-03 22:24:41 -05001562 clib_warning ("VCL<%d>: vep_idx (%u): Dumping epoll chain\n"
Dave Wallace498b3a52017-11-09 13:00:34 -05001563 "{\n"
1564 " is_vep = %u\n"
1565 " is_vep_session = %u\n"
Dave Wallace4878cbe2017-11-21 03:45:09 -05001566 " next_sid = 0x%x (%u)\n"
Dave Wallace498b3a52017-11-09 13:00:34 -05001567 " wait_cont_idx = 0x%x (%u)\n"
Dave Wallace4878cbe2017-11-21 03:45:09 -05001568 "}\n", getpid (), vep_idx,
1569 session->is_vep, session->is_vep_session,
1570 vep->next_sid, vep->next_sid,
Dave Wallace498b3a52017-11-09 13:00:34 -05001571 session->wait_cont_idx, session->wait_cont_idx);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001572
1573 for (sid = vep->next_sid; sid != ~0; sid = vep->next_sid)
Dave Wallacef7f809c2017-10-03 01:48:42 -04001574 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05001575 rv = vppcom_session_at_index (sid, &session);
1576 if (PREDICT_FALSE (rv))
Dave Wallacef7f809c2017-10-03 01:48:42 -04001577 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001578 clib_warning ("VCL<%d>: ERROR: Invalid sid (%u)!", getpid (), sid);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001579 goto done;
1580 }
1581 if (PREDICT_FALSE (session->is_vep))
Dave Wallace048b1d62018-01-03 22:24:41 -05001582 clib_warning ("VCL<%d>: ERROR: sid (%u) is a vep!",
1583 getpid (), vep_idx);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001584 else if (PREDICT_FALSE (!session->is_vep_session))
1585 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001586 clib_warning ("VCL<%d>: ERROR: session (%u) "
1587 "is not a vep session!", getpid (), sid);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001588 goto done;
1589 }
1590 vep = &session->vep;
1591 if (PREDICT_FALSE (vep->vep_idx != vep_idx))
Dave Wallace048b1d62018-01-03 22:24:41 -05001592 clib_warning ("VCL<%d>: ERROR: session (%u) vep_idx (%u) != "
Dave Wallace4878cbe2017-11-21 03:45:09 -05001593 "vep_idx (%u)!", getpid (),
1594 sid, session->vep.vep_idx, vep_idx);
1595 if (session->is_vep_session)
1596 {
1597 clib_warning ("vep_idx[%u]: sid 0x%x (%u)\n"
1598 "{\n"
1599 " next_sid = 0x%x (%u)\n"
1600 " prev_sid = 0x%x (%u)\n"
1601 " vep_idx = 0x%x (%u)\n"
1602 " ev.events = 0x%x\n"
1603 " ev.data.u64 = 0x%llx\n"
1604 " et_mask = 0x%x\n"
1605 "}\n",
1606 vep_idx, sid, sid,
1607 vep->next_sid, vep->next_sid,
1608 vep->prev_sid, vep->prev_sid,
1609 vep->vep_idx, vep->vep_idx,
1610 vep->ev.events, vep->ev.data.u64, vep->et_mask);
Dave Wallacef7f809c2017-10-03 01:48:42 -04001611 }
1612 }
Dave Wallacef7f809c2017-10-03 01:48:42 -04001613
1614done:
Dave Wallace048b1d62018-01-03 22:24:41 -05001615 clib_warning ("VCL<%d>: vep_idx (%u): Dump complete!\n",
1616 getpid (), vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04001617}
1618
1619int
1620vppcom_epoll_create (void)
1621{
Florin Coras7e12d942018-06-27 14:32:43 -07001622 vcl_session_t *vep_session;
Dave Wallacef7f809c2017-10-03 01:48:42 -04001623 u32 vep_idx;
1624
Dave Wallace7e607a72018-06-18 18:41:32 -04001625 VCL_SESSION_LOCK ();
Dave Wallacef7f809c2017-10-03 01:48:42 -04001626 pool_get (vcm->sessions, vep_session);
1627 memset (vep_session, 0, sizeof (*vep_session));
1628 vep_idx = vep_session - vcm->sessions;
1629
1630 vep_session->is_vep = 1;
1631 vep_session->vep.vep_idx = ~0;
1632 vep_session->vep.next_sid = ~0;
1633 vep_session->vep.prev_sid = ~0;
1634 vep_session->wait_cont_idx = ~0;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001635 vep_session->vpp_handle = ~0;
Keith Burns (alagalah)12756512018-03-06 05:55:27 -08001636 vep_session->poll_reg = 0;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001637
Florin Coras0d427d82018-06-27 03:24:07 -07001638 vcl_evt (VCL_EVT_EPOLL_CREATE, vep_session, vep_idx);
Dave Wallace7e607a72018-06-18 18:41:32 -04001639 VCL_SESSION_UNLOCK ();
Dave Wallacef7f809c2017-10-03 01:48:42 -04001640
Florin Coras0d427d82018-06-27 03:24:07 -07001641 VDBG (0, "VCL<%d>: Created vep_idx %u / sid %u!",
1642 getpid (), vep_idx, vep_idx);
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08001643
Dave Wallacef7f809c2017-10-03 01:48:42 -04001644 return (vep_idx);
1645}
1646
1647int
1648vppcom_epoll_ctl (uint32_t vep_idx, int op, uint32_t session_index,
1649 struct epoll_event *event)
1650{
Florin Coras7e12d942018-06-27 14:32:43 -07001651 vcl_session_t *vep_session;
1652 vcl_session_t *session;
Dave Wallacef7f809c2017-10-03 01:48:42 -04001653 int rv;
1654
1655 if (vep_idx == session_index)
1656 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001657 clib_warning ("VCL<%d>: ERROR: vep_idx == session_index (%u)!",
Dave Wallace4878cbe2017-11-21 03:45:09 -05001658 getpid (), vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04001659 return VPPCOM_EINVAL;
1660 }
1661
Dave Wallace7e607a72018-06-18 18:41:32 -04001662 VCL_SESSION_LOCK ();
Dave Wallacef7f809c2017-10-03 01:48:42 -04001663 rv = vppcom_session_at_index (vep_idx, &vep_session);
1664 if (PREDICT_FALSE (rv))
1665 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001666 clib_warning ("VCL<%d>: ERROR: Invalid vep_idx (%u)!", vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04001667 goto done;
1668 }
1669 if (PREDICT_FALSE (!vep_session->is_vep))
1670 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001671 clib_warning ("VCL<%d>: ERROR: vep_idx (%u) is not a vep!",
Dave Wallace4878cbe2017-11-21 03:45:09 -05001672 getpid (), vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04001673 rv = VPPCOM_EINVAL;
1674 goto done;
1675 }
1676
1677 ASSERT (vep_session->vep.vep_idx == ~0);
1678 ASSERT (vep_session->vep.prev_sid == ~0);
1679
1680 rv = vppcom_session_at_index (session_index, &session);
1681 if (PREDICT_FALSE (rv))
1682 {
Florin Coras0d427d82018-06-27 03:24:07 -07001683 VDBG (0, "VCL<%d>: ERROR: Invalid session_index (%u)!",
1684 getpid (), session_index);
Dave Wallacef7f809c2017-10-03 01:48:42 -04001685 goto done;
1686 }
1687 if (PREDICT_FALSE (session->is_vep))
1688 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05001689 clib_warning ("ERROR: session_index (%u) is a vep!", vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04001690 rv = VPPCOM_EINVAL;
1691 goto done;
1692 }
1693
1694 switch (op)
1695 {
1696 case EPOLL_CTL_ADD:
1697 if (PREDICT_FALSE (!event))
1698 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001699 clib_warning ("VCL<%d>: ERROR: EPOLL_CTL_ADD: NULL pointer to "
Dave Wallace2e005bb2017-11-07 01:21:39 -05001700 "epoll_event structure!", getpid ());
Dave Wallacef7f809c2017-10-03 01:48:42 -04001701 rv = VPPCOM_EINVAL;
1702 goto done;
1703 }
1704 if (vep_session->vep.next_sid != ~0)
1705 {
Florin Coras7e12d942018-06-27 14:32:43 -07001706 vcl_session_t *next_session;
Dave Wallacef7f809c2017-10-03 01:48:42 -04001707 rv = vppcom_session_at_index (vep_session->vep.next_sid,
1708 &next_session);
1709 if (PREDICT_FALSE (rv))
1710 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001711 clib_warning ("VCL<%d>: ERROR: EPOLL_CTL_ADD: Invalid "
Dave Wallace4878cbe2017-11-21 03:45:09 -05001712 "vep.next_sid (%u) on vep_idx (%u)!",
1713 getpid (), vep_session->vep.next_sid, vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04001714 goto done;
1715 }
1716 ASSERT (next_session->vep.prev_sid == vep_idx);
1717 next_session->vep.prev_sid = session_index;
1718 }
1719 session->vep.next_sid = vep_session->vep.next_sid;
1720 session->vep.prev_sid = vep_idx;
1721 session->vep.vep_idx = vep_idx;
1722 session->vep.et_mask = VEP_DEFAULT_ET_MASK;
1723 session->vep.ev = *event;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001724 session->is_vep = 0;
Dave Wallacef7f809c2017-10-03 01:48:42 -04001725 session->is_vep_session = 1;
1726 vep_session->vep.next_sid = session_index;
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001727
1728 /* VCL Event Register handler */
Florin Coras7e12d942018-06-27 14:32:43 -07001729 if (session->session_state & STATE_LISTEN)
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001730 {
1731 /* Register handler for connect_request event on listen_session_index */
1732 vce_event_key_t evk;
1733 evk.session_index = session_index;
1734 evk.eid = VCL_EVENT_CONNECT_REQ_ACCEPTED;
Keith Burns (alagalah)12756512018-03-06 05:55:27 -08001735 vep_session->poll_reg =
1736 vce_register_handler (&vcm->event_thread, &evk,
Keith Burns (alagalah)0d2b0d52018-03-06 15:55:22 -08001737 vce_poll_wait_connect_request_handler_fn,
1738 0 /* No callback args */ );
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001739 }
Florin Coras0d427d82018-06-27 03:24:07 -07001740 VDBG (1, "VCL<%d>: EPOLL_CTL_ADD: vep_idx %u, "
1741 "sid %u, events 0x%x, data 0x%llx!",
1742 getpid (), vep_idx, session_index,
1743 event->events, event->data.u64);
1744 vcl_evt (VCL_EVT_EPOLL_CTLADD, session, event->events, event->data.u64);
Dave Wallacef7f809c2017-10-03 01:48:42 -04001745 break;
1746
1747 case EPOLL_CTL_MOD:
1748 if (PREDICT_FALSE (!event))
1749 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001750 clib_warning ("VCL<%d>: ERROR: EPOLL_CTL_MOD: NULL pointer to "
Dave Wallace2e005bb2017-11-07 01:21:39 -05001751 "epoll_event structure!", getpid ());
Dave Wallacef7f809c2017-10-03 01:48:42 -04001752 rv = VPPCOM_EINVAL;
1753 goto done;
1754 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05001755 else if (PREDICT_FALSE (!session->is_vep_session))
Dave Wallacef7f809c2017-10-03 01:48:42 -04001756 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001757 clib_warning ("VCL<%d>: ERROR: sid %u EPOLL_CTL_MOD: "
Dave Wallace4878cbe2017-11-21 03:45:09 -05001758 "not a vep session!", getpid (), session_index);
1759 rv = VPPCOM_EINVAL;
1760 goto done;
1761 }
1762 else if (PREDICT_FALSE (session->vep.vep_idx != vep_idx))
1763 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001764 clib_warning ("VCL<%d>: ERROR: sid %u EPOLL_CTL_MOD: "
Dave Wallace4878cbe2017-11-21 03:45:09 -05001765 "vep_idx (%u) != vep_idx (%u)!",
1766 getpid (), session_index,
1767 session->vep.vep_idx, vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04001768 rv = VPPCOM_EINVAL;
1769 goto done;
1770 }
1771 session->vep.et_mask = VEP_DEFAULT_ET_MASK;
1772 session->vep.ev = *event;
Florin Coras0d427d82018-06-27 03:24:07 -07001773 VDBG (1, "VCL<%d>: EPOLL_CTL_MOD: vep_idx %u, sid %u, events 0x%x,"
1774 " data 0x%llx!", getpid (), vep_idx, session_index, event->events,
1775 event->data.u64);
Dave Wallacef7f809c2017-10-03 01:48:42 -04001776 break;
1777
1778 case EPOLL_CTL_DEL:
Dave Wallace4878cbe2017-11-21 03:45:09 -05001779 if (PREDICT_FALSE (!session->is_vep_session))
Dave Wallacef7f809c2017-10-03 01:48:42 -04001780 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001781 clib_warning ("VCL<%d>: ERROR: sid %u EPOLL_CTL_DEL: "
Dave Wallace4878cbe2017-11-21 03:45:09 -05001782 "not a vep session!", getpid (), session_index);
1783 rv = VPPCOM_EINVAL;
1784 goto done;
1785 }
1786 else if (PREDICT_FALSE (session->vep.vep_idx != vep_idx))
1787 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001788 clib_warning ("VCL<%d>: ERROR: sid %u EPOLL_CTL_DEL: "
Dave Wallace4878cbe2017-11-21 03:45:09 -05001789 "vep_idx (%u) != vep_idx (%u)!",
1790 getpid (), session_index,
1791 session->vep.vep_idx, vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04001792 rv = VPPCOM_EINVAL;
1793 goto done;
1794 }
1795
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001796 /* VCL Event Un-register handler */
Florin Coras7e12d942018-06-27 14:32:43 -07001797 if ((session->session_state & STATE_LISTEN) && vep_session->poll_reg)
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001798 {
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08001799 (void) vce_unregister_handler (&vcm->event_thread,
1800 vep_session->poll_reg);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001801 }
1802
Dave Wallacef7f809c2017-10-03 01:48:42 -04001803 vep_session->wait_cont_idx =
1804 (vep_session->wait_cont_idx == session_index) ?
1805 session->vep.next_sid : vep_session->wait_cont_idx;
1806
1807 if (session->vep.prev_sid == vep_idx)
1808 vep_session->vep.next_sid = session->vep.next_sid;
1809 else
1810 {
Florin Coras7e12d942018-06-27 14:32:43 -07001811 vcl_session_t *prev_session;
Dave Wallacef7f809c2017-10-03 01:48:42 -04001812 rv = vppcom_session_at_index (session->vep.prev_sid, &prev_session);
1813 if (PREDICT_FALSE (rv))
1814 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001815 clib_warning ("VCL<%d>: ERROR: EPOLL_CTL_DEL: Invalid "
Dave Wallace4878cbe2017-11-21 03:45:09 -05001816 "vep.prev_sid (%u) on sid (%u)!",
1817 getpid (), session->vep.prev_sid, session_index);
Dave Wallacef7f809c2017-10-03 01:48:42 -04001818 goto done;
1819 }
1820 ASSERT (prev_session->vep.next_sid == session_index);
1821 prev_session->vep.next_sid = session->vep.next_sid;
1822 }
1823 if (session->vep.next_sid != ~0)
1824 {
Florin Coras7e12d942018-06-27 14:32:43 -07001825 vcl_session_t *next_session;
Dave Wallacef7f809c2017-10-03 01:48:42 -04001826 rv = vppcom_session_at_index (session->vep.next_sid, &next_session);
1827 if (PREDICT_FALSE (rv))
1828 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001829 clib_warning ("VCL<%d>: ERROR: EPOLL_CTL_DEL: Invalid "
Dave Wallace4878cbe2017-11-21 03:45:09 -05001830 "vep.next_sid (%u) on sid (%u)!",
1831 getpid (), session->vep.next_sid, session_index);
Dave Wallacef7f809c2017-10-03 01:48:42 -04001832 goto done;
1833 }
1834 ASSERT (next_session->vep.prev_sid == session_index);
1835 next_session->vep.prev_sid = session->vep.prev_sid;
1836 }
1837
1838 memset (&session->vep, 0, sizeof (session->vep));
1839 session->vep.next_sid = ~0;
1840 session->vep.prev_sid = ~0;
1841 session->vep.vep_idx = ~0;
1842 session->is_vep_session = 0;
Florin Coras0d427d82018-06-27 03:24:07 -07001843 VDBG (1, "VCL<%d>: EPOLL_CTL_DEL: vep_idx %u, sid %u!",
1844 getpid (), vep_idx, session_index);
1845 vcl_evt (VCL_EVT_EPOLL_CTLDEL, session, vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04001846 break;
1847
1848 default:
Dave Wallace048b1d62018-01-03 22:24:41 -05001849 clib_warning ("VCL<%d>: ERROR: Invalid operation (%d)!", getpid (), op);
Dave Wallacef7f809c2017-10-03 01:48:42 -04001850 rv = VPPCOM_EINVAL;
1851 }
1852
1853 vep_verify_epoll_chain (vep_idx);
1854
1855done:
Dave Wallace7e607a72018-06-18 18:41:32 -04001856 VCL_SESSION_UNLOCK ();
Dave Wallacef7f809c2017-10-03 01:48:42 -04001857 return rv;
1858}
1859
Dave Wallacef7f809c2017-10-03 01:48:42 -04001860int
1861vppcom_epoll_wait (uint32_t vep_idx, struct epoll_event *events,
1862 int maxevents, double wait_for_time)
1863{
Florin Coras7e12d942018-06-27 14:32:43 -07001864 vcl_session_t *vep_session;
Dave Wallacef7f809c2017-10-03 01:48:42 -04001865 int rv;
1866 f64 timeout = clib_time_now (&vcm->clib_time) + wait_for_time;
Dave Wallace2e005bb2017-11-07 01:21:39 -05001867 u32 keep_trying = 1;
Dave Wallacef7f809c2017-10-03 01:48:42 -04001868 int num_ev = 0;
1869 u32 vep_next_sid, wait_cont_idx;
1870 u8 is_vep;
1871
1872 if (PREDICT_FALSE (maxevents <= 0))
1873 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001874 clib_warning ("VCL<%d>: ERROR: Invalid maxevents (%d)!",
Dave Wallace4878cbe2017-11-21 03:45:09 -05001875 getpid (), maxevents);
Dave Wallacef7f809c2017-10-03 01:48:42 -04001876 return VPPCOM_EINVAL;
1877 }
Dave Wallacef7f809c2017-10-03 01:48:42 -04001878 memset (events, 0, sizeof (*events) * maxevents);
1879
Dave Wallace7e607a72018-06-18 18:41:32 -04001880 VCL_SESSION_LOCK_AND_GET (vep_idx, &vep_session);
Dave Wallacef7f809c2017-10-03 01:48:42 -04001881 vep_next_sid = vep_session->vep.next_sid;
1882 is_vep = vep_session->is_vep;
1883 wait_cont_idx = vep_session->wait_cont_idx;
Dave Wallace7e607a72018-06-18 18:41:32 -04001884 VCL_SESSION_UNLOCK ();
Dave Wallacef7f809c2017-10-03 01:48:42 -04001885
1886 if (PREDICT_FALSE (!is_vep))
1887 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001888 clib_warning ("VCL<%d>: ERROR: vep_idx (%u) is not a vep!",
Dave Wallace4878cbe2017-11-21 03:45:09 -05001889 getpid (), vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04001890 rv = VPPCOM_EINVAL;
1891 goto done;
1892 }
Dave Wallacee695cb42017-11-02 22:04:42 -04001893 if (PREDICT_FALSE (vep_next_sid == ~0))
Dave Wallacef7f809c2017-10-03 01:48:42 -04001894 {
Florin Coras0d427d82018-06-27 03:24:07 -07001895 VDBG (1, "VCL<%d>: WARNING: vep_idx (%u) is empty!",
1896 getpid (), vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04001897 goto done;
1898 }
1899
1900 do
1901 {
1902 u32 sid;
1903 u32 next_sid = ~0;
Florin Coras7e12d942018-06-27 14:32:43 -07001904 vcl_session_t *session;
Dave Wallacef7f809c2017-10-03 01:48:42 -04001905
1906 for (sid = (wait_cont_idx == ~0) ? vep_next_sid : wait_cont_idx;
1907 sid != ~0; sid = next_sid)
1908 {
1909 u32 session_events, et_mask, clear_et_mask, session_vep_idx;
1910 u8 add_event, is_vep_session;
1911 int ready;
1912 u64 session_ev_data;
1913
Dave Wallace7e607a72018-06-18 18:41:32 -04001914 VCL_SESSION_LOCK_AND_GET (sid, &session);
Dave Wallacef7f809c2017-10-03 01:48:42 -04001915 next_sid = session->vep.next_sid;
1916 session_events = session->vep.ev.events;
1917 et_mask = session->vep.et_mask;
1918 is_vep = session->is_vep;
1919 is_vep_session = session->is_vep_session;
1920 session_vep_idx = session->vep.vep_idx;
1921 session_ev_data = session->vep.ev.data.u64;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001922
Dave Wallace7e607a72018-06-18 18:41:32 -04001923 VCL_SESSION_UNLOCK ();
Dave Wallacef7f809c2017-10-03 01:48:42 -04001924
1925 if (PREDICT_FALSE (is_vep))
1926 {
Florin Coras0d427d82018-06-27 03:24:07 -07001927 VDBG (0, "VCL<%d>: ERROR: sid (%u) is a vep!",
1928 getpid (), vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04001929 rv = VPPCOM_EINVAL;
1930 goto done;
1931 }
1932 if (PREDICT_FALSE (!is_vep_session))
1933 {
Florin Coras0d427d82018-06-27 03:24:07 -07001934 VDBG (0, "VCL<%d>: ERROR: session (%u) is not "
1935 "a vep session!", getpid (), sid);
Dave Wallacef7f809c2017-10-03 01:48:42 -04001936 rv = VPPCOM_EINVAL;
1937 goto done;
1938 }
1939 if (PREDICT_FALSE (session_vep_idx != vep_idx))
1940 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001941 clib_warning ("VCL<%d>: ERROR: session (%u) "
Dave Wallacef7f809c2017-10-03 01:48:42 -04001942 "vep_idx (%u) != vep_idx (%u)!",
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001943 getpid (), sid, session_vep_idx, vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04001944 rv = VPPCOM_EINVAL;
1945 goto done;
1946 }
1947
1948 add_event = clear_et_mask = 0;
1949
Dave Wallace60caa062017-11-10 17:07:13 -05001950 if (EPOLLIN & session_events)
Dave Wallacef7f809c2017-10-03 01:48:42 -04001951 {
Dave Wallace7e607a72018-06-18 18:41:32 -04001952 VCL_SESSION_LOCK_AND_GET (sid, &session);
Dave Wallacef7f809c2017-10-03 01:48:42 -04001953 ready = vppcom_session_read_ready (session, sid);
Dave Wallace7e607a72018-06-18 18:41:32 -04001954 VCL_SESSION_UNLOCK ();
Dave Wallace60caa062017-11-10 17:07:13 -05001955 if ((ready > 0) && (EPOLLIN & et_mask))
Dave Wallacef7f809c2017-10-03 01:48:42 -04001956 {
1957 add_event = 1;
1958 events[num_ev].events |= EPOLLIN;
Dave Wallace60caa062017-11-10 17:07:13 -05001959 if (((EPOLLET | EPOLLIN) & session_events) ==
1960 (EPOLLET | EPOLLIN))
Dave Wallacef7f809c2017-10-03 01:48:42 -04001961 clear_et_mask |= EPOLLIN;
1962 }
1963 else if (ready < 0)
1964 {
1965 add_event = 1;
1966 switch (ready)
1967 {
1968 case VPPCOM_ECONNRESET:
1969 events[num_ev].events |= EPOLLHUP | EPOLLRDHUP;
1970 break;
1971
1972 default:
1973 events[num_ev].events |= EPOLLERR;
1974 break;
1975 }
1976 }
1977 }
1978
Dave Wallace60caa062017-11-10 17:07:13 -05001979 if (EPOLLOUT & session_events)
Dave Wallacef7f809c2017-10-03 01:48:42 -04001980 {
Dave Wallace7e607a72018-06-18 18:41:32 -04001981 VCL_SESSION_LOCK_AND_GET (sid, &session);
Dave Wallacef7f809c2017-10-03 01:48:42 -04001982 ready = vppcom_session_write_ready (session, sid);
Dave Wallace7e607a72018-06-18 18:41:32 -04001983 VCL_SESSION_UNLOCK ();
Dave Wallace60caa062017-11-10 17:07:13 -05001984 if ((ready > 0) && (EPOLLOUT & et_mask))
Dave Wallacef7f809c2017-10-03 01:48:42 -04001985 {
1986 add_event = 1;
1987 events[num_ev].events |= EPOLLOUT;
Dave Wallace60caa062017-11-10 17:07:13 -05001988 if (((EPOLLET | EPOLLOUT) & session_events) ==
1989 (EPOLLET | EPOLLOUT))
Dave Wallacef7f809c2017-10-03 01:48:42 -04001990 clear_et_mask |= EPOLLOUT;
1991 }
1992 else if (ready < 0)
1993 {
1994 add_event = 1;
1995 switch (ready)
1996 {
1997 case VPPCOM_ECONNRESET:
1998 events[num_ev].events |= EPOLLHUP;
1999 break;
2000
2001 default:
2002 events[num_ev].events |= EPOLLERR;
2003 break;
2004 }
2005 }
2006 }
2007
2008 if (add_event)
2009 {
2010 events[num_ev].data.u64 = session_ev_data;
2011 if (EPOLLONESHOT & session_events)
2012 {
Dave Wallace7e607a72018-06-18 18:41:32 -04002013 VCL_SESSION_LOCK_AND_GET (sid, &session);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002014 session->vep.ev.events = 0;
Dave Wallace7e607a72018-06-18 18:41:32 -04002015 VCL_SESSION_UNLOCK ();
Dave Wallacef7f809c2017-10-03 01:48:42 -04002016 }
2017 num_ev++;
2018 if (num_ev == maxevents)
2019 {
Dave Wallace7e607a72018-06-18 18:41:32 -04002020 VCL_SESSION_LOCK_AND_GET (vep_idx, &vep_session);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002021 vep_session->wait_cont_idx = next_sid;
Dave Wallace7e607a72018-06-18 18:41:32 -04002022 VCL_SESSION_UNLOCK ();
Dave Wallacef7f809c2017-10-03 01:48:42 -04002023 goto done;
2024 }
2025 }
2026 if (wait_cont_idx != ~0)
2027 {
2028 if (next_sid == ~0)
2029 next_sid = vep_next_sid;
2030 else if (next_sid == wait_cont_idx)
2031 next_sid = ~0;
2032 }
2033 }
Dave Wallace2e005bb2017-11-07 01:21:39 -05002034 if (wait_for_time != -1)
2035 keep_trying = (clib_time_now (&vcm->clib_time) <= timeout) ? 1 : 0;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002036 }
Dave Wallace2e005bb2017-11-07 01:21:39 -05002037 while ((num_ev == 0) && keep_trying);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002038
2039 if (wait_cont_idx != ~0)
2040 {
Dave Wallace7e607a72018-06-18 18:41:32 -04002041 VCL_SESSION_LOCK_AND_GET (vep_idx, &vep_session);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002042 vep_session->wait_cont_idx = ~0;
Dave Wallace7e607a72018-06-18 18:41:32 -04002043 VCL_SESSION_UNLOCK ();
Dave Wallacef7f809c2017-10-03 01:48:42 -04002044 }
2045done:
2046 return (rv != VPPCOM_OK) ? rv : num_ev;
2047}
2048
Dave Wallace35830af2017-10-09 01:43:42 -04002049int
2050vppcom_session_attr (uint32_t session_index, uint32_t op,
2051 void *buffer, uint32_t * buflen)
2052{
Florin Coras7e12d942018-06-27 14:32:43 -07002053 vcl_session_t *session;
Dave Wallace35830af2017-10-09 01:43:42 -04002054 int rv = VPPCOM_OK;
2055 u32 *flags = buffer;
Steven2199aab2017-10-15 20:18:47 -07002056 vppcom_endpt_t *ep = buffer;
Dave Wallace35830af2017-10-09 01:43:42 -04002057
Dave Wallace7e607a72018-06-18 18:41:32 -04002058 VCL_SESSION_LOCK_AND_GET (session_index, &session);
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002059
2060 ASSERT (session);
2061
Dave Wallace35830af2017-10-09 01:43:42 -04002062 switch (op)
2063 {
2064 case VPPCOM_ATTR_GET_NREAD:
2065 rv = vppcom_session_read_ready (session, session_index);
Florin Coras0d427d82018-06-27 03:24:07 -07002066 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_NREAD: sid %u, nread = %d",
2067 getpid (), rv);
Dave Wallace35830af2017-10-09 01:43:42 -04002068 break;
2069
Dave Wallace227867f2017-11-13 21:21:53 -05002070 case VPPCOM_ATTR_GET_NWRITE:
2071 rv = vppcom_session_write_ready (session, session_index);
Florin Coras0d427d82018-06-27 03:24:07 -07002072 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_NWRITE: sid %u, nwrite = %d",
2073 getpid (), session_index, rv);
Dave Wallace35830af2017-10-09 01:43:42 -04002074 break;
2075
2076 case VPPCOM_ATTR_GET_FLAGS:
Dave Wallace048b1d62018-01-03 22:24:41 -05002077 if (PREDICT_TRUE (buffer && buflen && (*buflen >= sizeof (*flags))))
Dave Wallace35830af2017-10-09 01:43:42 -04002078 {
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002079 *flags = O_RDWR | (VCL_SESS_ATTR_TEST (session->attr,
2080 VCL_SESS_ATTR_NONBLOCK));
Dave Wallace35830af2017-10-09 01:43:42 -04002081 *buflen = sizeof (*flags);
Florin Coras0d427d82018-06-27 03:24:07 -07002082 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_FLAGS: sid %u, flags = 0x%08x, "
2083 "is_nonblocking = %u", getpid (),
2084 session_index, *flags,
2085 VCL_SESS_ATTR_TEST (session->attr, VCL_SESS_ATTR_NONBLOCK));
Dave Wallace35830af2017-10-09 01:43:42 -04002086 }
2087 else
2088 rv = VPPCOM_EINVAL;
2089 break;
2090
2091 case VPPCOM_ATTR_SET_FLAGS:
Dave Wallace048b1d62018-01-03 22:24:41 -05002092 if (PREDICT_TRUE (buffer && buflen && (*buflen == sizeof (*flags))))
Dave Wallace35830af2017-10-09 01:43:42 -04002093 {
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002094 if (*flags & O_NONBLOCK)
2095 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_NONBLOCK);
2096 else
2097 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_NONBLOCK);
2098
Florin Coras0d427d82018-06-27 03:24:07 -07002099 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_FLAGS: sid %u, flags = 0x%08x,"
2100 " is_nonblocking = %u",
2101 getpid (), session_index, *flags,
2102 VCL_SESS_ATTR_TEST (session->attr, VCL_SESS_ATTR_NONBLOCK));
Dave Wallace35830af2017-10-09 01:43:42 -04002103 }
2104 else
2105 rv = VPPCOM_EINVAL;
2106 break;
2107
2108 case VPPCOM_ATTR_GET_PEER_ADDR:
Dave Wallace048b1d62018-01-03 22:24:41 -05002109 if (PREDICT_TRUE (buffer && buflen &&
2110 (*buflen >= sizeof (*ep)) && ep->ip))
Dave Wallace35830af2017-10-09 01:43:42 -04002111 {
Florin Coras7e12d942018-06-27 14:32:43 -07002112 ep->is_ip4 = session->transport.is_ip4;
2113 ep->port = session->transport.rmt_port;
2114 if (session->transport.is_ip4)
2115 clib_memcpy (ep->ip, &session->transport.rmt_ip.ip4,
Steven2199aab2017-10-15 20:18:47 -07002116 sizeof (ip4_address_t));
2117 else
Florin Coras7e12d942018-06-27 14:32:43 -07002118 clib_memcpy (ep->ip, &session->transport.rmt_ip.ip6,
Steven2199aab2017-10-15 20:18:47 -07002119 sizeof (ip6_address_t));
2120 *buflen = sizeof (*ep);
Florin Coras0d427d82018-06-27 03:24:07 -07002121 VDBG (1, "VCL<%d>: VPPCOM_ATTR_GET_PEER_ADDR: sid %u, is_ip4 = %u, "
2122 "addr = %U, port %u", getpid (),
2123 session_index, ep->is_ip4, format_ip46_address,
Florin Coras7e12d942018-06-27 14:32:43 -07002124 &session->transport.rmt_ip,
Florin Coras0d427d82018-06-27 03:24:07 -07002125 ep->is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6,
2126 clib_net_to_host_u16 (ep->port));
Dave Wallace35830af2017-10-09 01:43:42 -04002127 }
2128 else
2129 rv = VPPCOM_EINVAL;
2130 break;
2131
2132 case VPPCOM_ATTR_GET_LCL_ADDR:
Dave Wallace048b1d62018-01-03 22:24:41 -05002133 if (PREDICT_TRUE (buffer && buflen &&
2134 (*buflen >= sizeof (*ep)) && ep->ip))
Dave Wallace35830af2017-10-09 01:43:42 -04002135 {
Florin Coras7e12d942018-06-27 14:32:43 -07002136 ep->is_ip4 = session->transport.is_ip4;
2137 ep->port = session->transport.lcl_port;
2138 if (session->transport.is_ip4)
2139 clib_memcpy (ep->ip, &session->transport.lcl_ip.ip4,
Steven2199aab2017-10-15 20:18:47 -07002140 sizeof (ip4_address_t));
2141 else
Florin Coras7e12d942018-06-27 14:32:43 -07002142 clib_memcpy (ep->ip, &session->transport.lcl_ip.ip6,
Steven2199aab2017-10-15 20:18:47 -07002143 sizeof (ip6_address_t));
2144 *buflen = sizeof (*ep);
Florin Coras0d427d82018-06-27 03:24:07 -07002145 VDBG (1, "VCL<%d>: VPPCOM_ATTR_GET_LCL_ADDR: sid %u, is_ip4 = %u,"
2146 " addr = %U port %d", getpid (),
2147 session_index, ep->is_ip4, format_ip46_address,
Florin Coras7e12d942018-06-27 14:32:43 -07002148 &session->transport.lcl_ip,
Florin Coras0d427d82018-06-27 03:24:07 -07002149 ep->is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6,
2150 clib_net_to_host_u16 (ep->port));
Dave Wallace35830af2017-10-09 01:43:42 -04002151 }
2152 else
2153 rv = VPPCOM_EINVAL;
2154 break;
Stevenb5a11602017-10-11 09:59:30 -07002155
Dave Wallace048b1d62018-01-03 22:24:41 -05002156 case VPPCOM_ATTR_GET_LIBC_EPFD:
2157 rv = session->libc_epfd;
Florin Coras0d427d82018-06-27 03:24:07 -07002158 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_LIBC_EPFD: libc_epfd %d",
2159 getpid (), rv);
Dave Wallace048b1d62018-01-03 22:24:41 -05002160 break;
2161
2162 case VPPCOM_ATTR_SET_LIBC_EPFD:
2163 if (PREDICT_TRUE (buffer && buflen &&
2164 (*buflen == sizeof (session->libc_epfd))))
2165 {
2166 session->libc_epfd = *(int *) buffer;
2167 *buflen = sizeof (session->libc_epfd);
2168
Florin Coras0d427d82018-06-27 03:24:07 -07002169 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_LIBC_EPFD: libc_epfd %d, "
2170 "buflen %d", getpid (), session->libc_epfd, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002171 }
2172 else
2173 rv = VPPCOM_EINVAL;
2174 break;
2175
2176 case VPPCOM_ATTR_GET_PROTOCOL:
2177 if (buffer && buflen && (*buflen >= sizeof (int)))
2178 {
Florin Coras7e12d942018-06-27 14:32:43 -07002179 *(int *) buffer = session->session_type;
Dave Wallace048b1d62018-01-03 22:24:41 -05002180 *buflen = sizeof (int);
2181
Florin Coras0d427d82018-06-27 03:24:07 -07002182 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_PROTOCOL: %d (%s), buflen %d",
2183 getpid (), *(int *) buffer, *(int *) buffer ? "UDP" : "TCP",
2184 *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002185 }
2186 else
2187 rv = VPPCOM_EINVAL;
2188 break;
2189
2190 case VPPCOM_ATTR_GET_LISTEN:
2191 if (buffer && buflen && (*buflen >= sizeof (int)))
2192 {
2193 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
2194 VCL_SESS_ATTR_LISTEN);
2195 *buflen = sizeof (int);
2196
Florin Coras0d427d82018-06-27 03:24:07 -07002197 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_LISTEN: %d, buflen %d",
2198 getpid (), *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002199 }
2200 else
2201 rv = VPPCOM_EINVAL;
2202 break;
2203
2204 case VPPCOM_ATTR_GET_ERROR:
2205 if (buffer && buflen && (*buflen >= sizeof (int)))
2206 {
2207 *(int *) buffer = 0;
2208 *buflen = sizeof (int);
2209
Florin Coras0d427d82018-06-27 03:24:07 -07002210 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_ERROR: %d, buflen %d, #VPP-TBD#",
2211 getpid (), *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002212 }
2213 else
2214 rv = VPPCOM_EINVAL;
2215 break;
2216
2217 case VPPCOM_ATTR_GET_TX_FIFO_LEN:
2218 if (buffer && buflen && (*buflen >= sizeof (u32)))
2219 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002220
2221 /* VPP-TBD */
2222 *(size_t *) buffer = (session->sndbuf_size ? session->sndbuf_size :
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002223 session->tx_fifo ? session->tx_fifo->nitems :
Dave Wallace048b1d62018-01-03 22:24:41 -05002224 vcm->cfg.tx_fifo_size);
2225 *buflen = sizeof (u32);
2226
Florin Coras0d427d82018-06-27 03:24:07 -07002227 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_TX_FIFO_LEN: %u (0x%x), "
2228 "buflen %d, #VPP-TBD#", getpid (),
2229 *(size_t *) buffer, *(size_t *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002230 }
2231 else
2232 rv = VPPCOM_EINVAL;
2233 break;
2234
2235 case VPPCOM_ATTR_SET_TX_FIFO_LEN:
2236 if (buffer && buflen && (*buflen == sizeof (u32)))
2237 {
2238 /* VPP-TBD */
2239 session->sndbuf_size = *(u32 *) buffer;
Florin Coras0d427d82018-06-27 03:24:07 -07002240 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_TX_FIFO_LEN: %u (0x%x), "
2241 "buflen %d, #VPP-TBD#", getpid (),
2242 session->sndbuf_size, session->sndbuf_size, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002243 }
2244 else
2245 rv = VPPCOM_EINVAL;
2246 break;
2247
2248 case VPPCOM_ATTR_GET_RX_FIFO_LEN:
2249 if (buffer && buflen && (*buflen >= sizeof (u32)))
2250 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002251
2252 /* VPP-TBD */
2253 *(size_t *) buffer = (session->rcvbuf_size ? session->rcvbuf_size :
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002254 session->rx_fifo ? session->rx_fifo->nitems :
Dave Wallace048b1d62018-01-03 22:24:41 -05002255 vcm->cfg.rx_fifo_size);
2256 *buflen = sizeof (u32);
2257
Florin Coras0d427d82018-06-27 03:24:07 -07002258 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_RX_FIFO_LEN: %u (0x%x), "
2259 "buflen %d, #VPP-TBD#", getpid (),
2260 *(size_t *) buffer, *(size_t *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002261 }
2262 else
2263 rv = VPPCOM_EINVAL;
2264 break;
2265
2266 case VPPCOM_ATTR_SET_RX_FIFO_LEN:
2267 if (buffer && buflen && (*buflen == sizeof (u32)))
2268 {
2269 /* VPP-TBD */
2270 session->rcvbuf_size = *(u32 *) buffer;
Florin Coras0d427d82018-06-27 03:24:07 -07002271 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_RX_FIFO_LEN: %u (0x%x), "
2272 "buflen %d, #VPP-TBD#", getpid (),
2273 session->sndbuf_size, session->sndbuf_size, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002274 }
2275 else
2276 rv = VPPCOM_EINVAL;
2277 break;
2278
2279 case VPPCOM_ATTR_GET_REUSEADDR:
2280 if (buffer && buflen && (*buflen >= sizeof (int)))
2281 {
2282 /* VPP-TBD */
2283 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
2284 VCL_SESS_ATTR_REUSEADDR);
2285 *buflen = sizeof (int);
2286
Florin Coras0d427d82018-06-27 03:24:07 -07002287 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_REUSEADDR: %d, "
2288 "buflen %d, #VPP-TBD#", getpid (), *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002289 }
2290 else
2291 rv = VPPCOM_EINVAL;
2292 break;
2293
Stevenb5a11602017-10-11 09:59:30 -07002294 case VPPCOM_ATTR_SET_REUSEADDR:
Dave Wallace048b1d62018-01-03 22:24:41 -05002295 if (buffer && buflen && (*buflen == sizeof (int)) &&
2296 !VCL_SESS_ATTR_TEST (session->attr, VCL_SESS_ATTR_LISTEN))
2297 {
2298 /* VPP-TBD */
2299 if (*(int *) buffer)
2300 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_REUSEADDR);
2301 else
2302 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_REUSEADDR);
2303
Florin Coras0d427d82018-06-27 03:24:07 -07002304 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_REUSEADDR: %d, buflen %d,"
2305 " #VPP-TBD#", getpid (),
2306 VCL_SESS_ATTR_TEST (session->attr,
2307 VCL_SESS_ATTR_REUSEADDR), *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002308 }
2309 else
2310 rv = VPPCOM_EINVAL;
2311 break;
2312
2313 case VPPCOM_ATTR_GET_REUSEPORT:
2314 if (buffer && buflen && (*buflen >= sizeof (int)))
2315 {
2316 /* VPP-TBD */
2317 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
2318 VCL_SESS_ATTR_REUSEPORT);
2319 *buflen = sizeof (int);
2320
Florin Coras0d427d82018-06-27 03:24:07 -07002321 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_REUSEPORT: %d, buflen %d,"
2322 " #VPP-TBD#", getpid (), *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002323 }
2324 else
2325 rv = VPPCOM_EINVAL;
2326 break;
2327
2328 case VPPCOM_ATTR_SET_REUSEPORT:
2329 if (buffer && buflen && (*buflen == sizeof (int)) &&
2330 !VCL_SESS_ATTR_TEST (session->attr, VCL_SESS_ATTR_LISTEN))
2331 {
2332 /* VPP-TBD */
2333 if (*(int *) buffer)
2334 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_REUSEPORT);
2335 else
2336 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_REUSEPORT);
2337
Florin Coras0d427d82018-06-27 03:24:07 -07002338 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_REUSEPORT: %d, buflen %d,"
2339 " #VPP-TBD#", getpid (),
2340 VCL_SESS_ATTR_TEST (session->attr,
2341 VCL_SESS_ATTR_REUSEPORT), *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002342 }
2343 else
2344 rv = VPPCOM_EINVAL;
2345 break;
2346
2347 case VPPCOM_ATTR_GET_BROADCAST:
2348 if (buffer && buflen && (*buflen >= sizeof (int)))
2349 {
2350 /* VPP-TBD */
2351 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
2352 VCL_SESS_ATTR_BROADCAST);
2353 *buflen = sizeof (int);
2354
Florin Coras0d427d82018-06-27 03:24:07 -07002355 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_BROADCAST: %d, buflen %d,"
2356 " #VPP-TBD#", getpid (), *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002357 }
2358 else
2359 rv = VPPCOM_EINVAL;
Stevenb5a11602017-10-11 09:59:30 -07002360 break;
2361
2362 case VPPCOM_ATTR_SET_BROADCAST:
Dave Wallace048b1d62018-01-03 22:24:41 -05002363 if (buffer && buflen && (*buflen == sizeof (int)))
2364 {
2365 /* VPP-TBD */
2366 if (*(int *) buffer)
2367 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_BROADCAST);
2368 else
2369 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_BROADCAST);
2370
Florin Coras0d427d82018-06-27 03:24:07 -07002371 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_BROADCAST: %d, buflen %d, "
2372 "#VPP-TBD#", getpid (),
2373 VCL_SESS_ATTR_TEST (session->attr,
2374 VCL_SESS_ATTR_BROADCAST), *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002375 }
2376 else
2377 rv = VPPCOM_EINVAL;
2378 break;
2379
2380 case VPPCOM_ATTR_GET_V6ONLY:
2381 if (buffer && buflen && (*buflen >= sizeof (int)))
2382 {
2383 /* VPP-TBD */
2384 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
2385 VCL_SESS_ATTR_V6ONLY);
2386 *buflen = sizeof (int);
2387
Florin Coras0d427d82018-06-27 03:24:07 -07002388 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_V6ONLY: %d, buflen %d, "
2389 "#VPP-TBD#", getpid (), *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002390 }
2391 else
2392 rv = VPPCOM_EINVAL;
Stevenb5a11602017-10-11 09:59:30 -07002393 break;
2394
2395 case VPPCOM_ATTR_SET_V6ONLY:
Dave Wallace048b1d62018-01-03 22:24:41 -05002396 if (buffer && buflen && (*buflen == sizeof (int)))
2397 {
2398 /* VPP-TBD */
2399 if (*(int *) buffer)
2400 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_V6ONLY);
2401 else
2402 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_V6ONLY);
2403
Florin Coras0d427d82018-06-27 03:24:07 -07002404 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_V6ONLY: %d, buflen %d, "
2405 "#VPP-TBD#", getpid (),
2406 VCL_SESS_ATTR_TEST (session->attr,
2407 VCL_SESS_ATTR_V6ONLY), *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002408 }
2409 else
2410 rv = VPPCOM_EINVAL;
2411 break;
2412
2413 case VPPCOM_ATTR_GET_KEEPALIVE:
2414 if (buffer && buflen && (*buflen >= sizeof (int)))
2415 {
2416 /* VPP-TBD */
2417 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
2418 VCL_SESS_ATTR_KEEPALIVE);
2419 *buflen = sizeof (int);
2420
Florin Coras0d427d82018-06-27 03:24:07 -07002421 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_KEEPALIVE: %d, buflen %d, "
2422 "#VPP-TBD#", getpid (), *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002423 }
2424 else
2425 rv = VPPCOM_EINVAL;
Stevenb5a11602017-10-11 09:59:30 -07002426 break;
Stevenbccd3392017-10-12 20:42:21 -07002427
2428 case VPPCOM_ATTR_SET_KEEPALIVE:
Dave Wallace048b1d62018-01-03 22:24:41 -05002429 if (buffer && buflen && (*buflen == sizeof (int)))
2430 {
2431 /* VPP-TBD */
2432 if (*(int *) buffer)
2433 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_KEEPALIVE);
2434 else
2435 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_KEEPALIVE);
2436
Florin Coras0d427d82018-06-27 03:24:07 -07002437 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_KEEPALIVE: %d, buflen %d, "
2438 "#VPP-TBD#", getpid (),
2439 VCL_SESS_ATTR_TEST (session->attr,
2440 VCL_SESS_ATTR_KEEPALIVE), *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002441 }
2442 else
2443 rv = VPPCOM_EINVAL;
2444 break;
2445
2446 case VPPCOM_ATTR_GET_TCP_NODELAY:
2447 if (buffer && buflen && (*buflen >= sizeof (int)))
2448 {
2449 /* VPP-TBD */
2450 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
2451 VCL_SESS_ATTR_TCP_NODELAY);
2452 *buflen = sizeof (int);
2453
Florin Coras0d427d82018-06-27 03:24:07 -07002454 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_TCP_NODELAY: %d, buflen %d, "
2455 "#VPP-TBD#", getpid (), *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002456 }
2457 else
2458 rv = VPPCOM_EINVAL;
2459 break;
2460
2461 case VPPCOM_ATTR_SET_TCP_NODELAY:
2462 if (buffer && buflen && (*buflen == sizeof (int)))
2463 {
2464 /* VPP-TBD */
2465 if (*(int *) buffer)
2466 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_TCP_NODELAY);
2467 else
2468 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_TCP_NODELAY);
2469
Florin Coras0d427d82018-06-27 03:24:07 -07002470 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_TCP_NODELAY: %d, buflen %d, "
2471 "#VPP-TBD#", getpid (),
2472 VCL_SESS_ATTR_TEST (session->attr,
2473 VCL_SESS_ATTR_TCP_NODELAY), *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002474 }
2475 else
2476 rv = VPPCOM_EINVAL;
2477 break;
2478
2479 case VPPCOM_ATTR_GET_TCP_KEEPIDLE:
2480 if (buffer && buflen && (*buflen >= sizeof (int)))
2481 {
2482 /* VPP-TBD */
2483 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
2484 VCL_SESS_ATTR_TCP_KEEPIDLE);
2485 *buflen = sizeof (int);
2486
Florin Coras0d427d82018-06-27 03:24:07 -07002487 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_TCP_KEEPIDLE: %d, buflen %d, "
2488 "#VPP-TBD#", getpid (), *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002489 }
2490 else
2491 rv = VPPCOM_EINVAL;
Stevenbccd3392017-10-12 20:42:21 -07002492 break;
2493
2494 case VPPCOM_ATTR_SET_TCP_KEEPIDLE:
Dave Wallace048b1d62018-01-03 22:24:41 -05002495 if (buffer && buflen && (*buflen == sizeof (int)))
2496 {
2497 /* VPP-TBD */
2498 if (*(int *) buffer)
2499 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_TCP_KEEPIDLE);
2500 else
2501 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_TCP_KEEPIDLE);
2502
Florin Coras0d427d82018-06-27 03:24:07 -07002503 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_TCP_KEEPIDLE: %d, buflen %d, "
2504 "#VPP-TBD#", getpid (),
2505 VCL_SESS_ATTR_TEST (session->attr,
2506 VCL_SESS_ATTR_TCP_KEEPIDLE), *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002507 }
2508 else
2509 rv = VPPCOM_EINVAL;
2510 break;
2511
2512 case VPPCOM_ATTR_GET_TCP_KEEPINTVL:
2513 if (buffer && buflen && (*buflen >= sizeof (int)))
2514 {
2515 /* VPP-TBD */
2516 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
2517 VCL_SESS_ATTR_TCP_KEEPINTVL);
2518 *buflen = sizeof (int);
2519
Florin Coras0d427d82018-06-27 03:24:07 -07002520 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_TCP_KEEPINTVL: %d, buflen %d, "
2521 "#VPP-TBD#", getpid (), *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002522 }
2523 else
2524 rv = VPPCOM_EINVAL;
Stevenbccd3392017-10-12 20:42:21 -07002525 break;
2526
2527 case VPPCOM_ATTR_SET_TCP_KEEPINTVL:
Dave Wallace048b1d62018-01-03 22:24:41 -05002528 if (buffer && buflen && (*buflen == sizeof (int)))
2529 {
2530 /* VPP-TBD */
2531 if (*(int *) buffer)
2532 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_TCP_KEEPINTVL);
2533 else
2534 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_TCP_KEEPINTVL);
2535
Florin Coras0d427d82018-06-27 03:24:07 -07002536 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_TCP_KEEPINTVL: %d, buflen %d, "
2537 "#VPP-TBD#", getpid (),
2538 VCL_SESS_ATTR_TEST (session->attr,
2539 VCL_SESS_ATTR_TCP_KEEPINTVL), *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002540 }
2541 else
2542 rv = VPPCOM_EINVAL;
2543 break;
2544
2545 case VPPCOM_ATTR_GET_TCP_USER_MSS:
2546 if (buffer && buflen && (*buflen >= sizeof (u32)))
2547 {
2548 /* VPP-TBD */
2549 *(u32 *) buffer = session->user_mss;
2550 *buflen = sizeof (int);
2551
Florin Coras0d427d82018-06-27 03:24:07 -07002552 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_TCP_USER_MSS: %d, buflen %d,"
2553 " #VPP-TBD#", getpid (), *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002554 }
2555 else
2556 rv = VPPCOM_EINVAL;
2557 break;
2558
2559 case VPPCOM_ATTR_SET_TCP_USER_MSS:
2560 if (buffer && buflen && (*buflen == sizeof (u32)))
2561 {
2562 /* VPP-TBD */
2563 session->user_mss = *(u32 *) buffer;
2564
Florin Coras0d427d82018-06-27 03:24:07 -07002565 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_TCP_USER_MSS: %u, buflen %d, "
2566 "#VPP-TBD#", getpid (), session->user_mss, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002567 }
2568 else
2569 rv = VPPCOM_EINVAL;
Stevenbccd3392017-10-12 20:42:21 -07002570 break;
Dave Wallacee22aa742017-10-20 12:30:38 -04002571
2572 default:
2573 rv = VPPCOM_EINVAL;
2574 break;
Dave Wallace35830af2017-10-09 01:43:42 -04002575 }
2576
2577done:
Dave Wallace7e607a72018-06-18 18:41:32 -04002578 VCL_SESSION_UNLOCK ();
Dave Wallace35830af2017-10-09 01:43:42 -04002579 return rv;
2580}
2581
Stevenac1f96d2017-10-24 16:03:58 -07002582int
2583vppcom_session_recvfrom (uint32_t session_index, void *buffer,
2584 uint32_t buflen, int flags, vppcom_endpt_t * ep)
2585{
Stevenac1f96d2017-10-24 16:03:58 -07002586 int rv = VPPCOM_OK;
Florin Coras7e12d942018-06-27 14:32:43 -07002587 vcl_session_t *session = 0;
Stevenac1f96d2017-10-24 16:03:58 -07002588
2589 if (ep)
2590 {
Dave Wallace7e607a72018-06-18 18:41:32 -04002591 VCL_SESSION_LOCK ();
Stevenac1f96d2017-10-24 16:03:58 -07002592 rv = vppcom_session_at_index (session_index, &session);
2593 if (PREDICT_FALSE (rv))
2594 {
Dave Wallace7e607a72018-06-18 18:41:32 -04002595 VCL_SESSION_UNLOCK ();
Florin Coras0d427d82018-06-27 03:24:07 -07002596 VDBG (0, "VCL<%d>: invalid session, sid (%u) has been closed!",
2597 getpid (), session_index);
Dave Wallacefaf9d772017-10-26 16:12:04 -04002598 rv = VPPCOM_EBADFD;
Dave Wallace7e607a72018-06-18 18:41:32 -04002599 VCL_SESSION_UNLOCK ();
Dave Wallacefaf9d772017-10-26 16:12:04 -04002600 goto done;
Stevenac1f96d2017-10-24 16:03:58 -07002601 }
Florin Coras7e12d942018-06-27 14:32:43 -07002602 ep->is_ip4 = session->transport.is_ip4;
2603 ep->port = session->transport.rmt_port;
2604 if (session->transport.is_ip4)
2605 clib_memcpy (ep->ip, &session->transport.rmt_ip.ip4,
Stevenac1f96d2017-10-24 16:03:58 -07002606 sizeof (ip4_address_t));
2607 else
Florin Coras7e12d942018-06-27 14:32:43 -07002608 clib_memcpy (ep->ip, &session->transport.rmt_ip.ip6,
Stevenac1f96d2017-10-24 16:03:58 -07002609 sizeof (ip6_address_t));
Dave Wallace7e607a72018-06-18 18:41:32 -04002610 VCL_SESSION_UNLOCK ();
Stevenac1f96d2017-10-24 16:03:58 -07002611 }
Steven58f464e2017-10-25 12:33:12 -07002612
2613 if (flags == 0)
Stevenac1f96d2017-10-24 16:03:58 -07002614 rv = vppcom_session_read (session_index, buffer, buflen);
2615 else if (flags & MSG_PEEK)
Steven58f464e2017-10-25 12:33:12 -07002616 rv = vppcom_session_peek (session_index, buffer, buflen);
Stevenac1f96d2017-10-24 16:03:58 -07002617 else
2618 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002619 clib_warning ("VCL<%d>: Unsupport flags for recvfrom %d",
2620 getpid (), flags);
Stevenac1f96d2017-10-24 16:03:58 -07002621 rv = VPPCOM_EAFNOSUPPORT;
2622 }
2623
Dave Wallacefaf9d772017-10-26 16:12:04 -04002624done:
Stevenac1f96d2017-10-24 16:03:58 -07002625 return rv;
2626}
2627
2628int
2629vppcom_session_sendto (uint32_t session_index, void *buffer,
2630 uint32_t buflen, int flags, vppcom_endpt_t * ep)
2631{
Dave Wallace617dffa2017-10-26 14:47:06 -04002632 if (!buffer)
2633 return VPPCOM_EINVAL;
2634
2635 if (ep)
2636 {
2637 // TBD
2638 return VPPCOM_EINVAL;
2639 }
2640
2641 if (flags)
2642 {
2643 // TBD check the flags and do the right thing
Florin Coras0d427d82018-06-27 03:24:07 -07002644 VDBG (2, "VCL<%d>: handling flags 0x%u (%d) not implemented yet.",
2645 getpid (), flags, flags);
Dave Wallace617dffa2017-10-26 14:47:06 -04002646 }
2647
2648 return (vppcom_session_write (session_index, buffer, buflen));
Stevenac1f96d2017-10-24 16:03:58 -07002649}
2650
Dave Wallace048b1d62018-01-03 22:24:41 -05002651int
2652vppcom_poll (vcl_poll_t * vp, uint32_t n_sids, double wait_for_time)
2653{
2654 f64 timeout = clib_time_now (&vcm->clib_time) + wait_for_time;
2655 u32 i, keep_trying = 1;
2656 int rv, num_ev = 0;
2657
Florin Coras0d427d82018-06-27 03:24:07 -07002658 VDBG (3, "VCL<%d>: vp %p, nsids %u, wait_for_time %f",
2659 getpid (), vp, n_sids, wait_for_time);
Dave Wallace048b1d62018-01-03 22:24:41 -05002660
2661 if (!vp)
2662 return VPPCOM_EFAULT;
2663
2664 do
2665 {
Florin Coras7e12d942018-06-27 14:32:43 -07002666 vcl_session_t *session;
Dave Wallace048b1d62018-01-03 22:24:41 -05002667
2668 for (i = 0; i < n_sids; i++)
2669 {
2670 ASSERT (vp[i].revents);
2671
Dave Wallace7e607a72018-06-18 18:41:32 -04002672 VCL_SESSION_LOCK_AND_GET (vp[i].sid, &session);
2673 VCL_SESSION_UNLOCK ();
Dave Wallace048b1d62018-01-03 22:24:41 -05002674
2675 if (*vp[i].revents)
2676 *vp[i].revents = 0;
2677
2678 if (POLLIN & vp[i].events)
2679 {
Dave Wallace7e607a72018-06-18 18:41:32 -04002680 VCL_SESSION_LOCK_AND_GET (vp[i].sid, &session);
Dave Wallace048b1d62018-01-03 22:24:41 -05002681 rv = vppcom_session_read_ready (session, vp[i].sid);
Dave Wallace7e607a72018-06-18 18:41:32 -04002682 VCL_SESSION_UNLOCK ();
Dave Wallace048b1d62018-01-03 22:24:41 -05002683 if (rv > 0)
2684 {
2685 *vp[i].revents |= POLLIN;
2686 num_ev++;
2687 }
2688 else if (rv < 0)
2689 {
2690 switch (rv)
2691 {
2692 case VPPCOM_ECONNRESET:
2693 *vp[i].revents = POLLHUP;
2694 break;
2695
2696 default:
2697 *vp[i].revents = POLLERR;
2698 break;
2699 }
2700 num_ev++;
2701 }
2702 }
2703
2704 if (POLLOUT & vp[i].events)
2705 {
Dave Wallace7e607a72018-06-18 18:41:32 -04002706 VCL_SESSION_LOCK_AND_GET (vp[i].sid, &session);
Dave Wallace048b1d62018-01-03 22:24:41 -05002707 rv = vppcom_session_write_ready (session, vp[i].sid);
Dave Wallace7e607a72018-06-18 18:41:32 -04002708 VCL_SESSION_UNLOCK ();
Dave Wallace048b1d62018-01-03 22:24:41 -05002709 if (rv > 0)
2710 {
2711 *vp[i].revents |= POLLOUT;
2712 num_ev++;
2713 }
2714 else if (rv < 0)
2715 {
2716 switch (rv)
2717 {
2718 case VPPCOM_ECONNRESET:
2719 *vp[i].revents = POLLHUP;
2720 break;
2721
2722 default:
2723 *vp[i].revents = POLLERR;
2724 break;
2725 }
2726 num_ev++;
2727 }
2728 }
2729
Dave Wallace7e607a72018-06-18 18:41:32 -04002730 if (0) // Note "done:" label used by VCL_SESSION_LOCK_AND_GET()
Dave Wallace048b1d62018-01-03 22:24:41 -05002731 {
2732 done:
2733 *vp[i].revents = POLLNVAL;
2734 num_ev++;
2735 }
2736 }
2737 if (wait_for_time != -1)
2738 keep_trying = (clib_time_now (&vcm->clib_time) <= timeout) ? 1 : 0;
2739 }
2740 while ((num_ev == 0) && keep_trying);
2741
2742 if (VPPCOM_DEBUG > 3)
2743 {
2744 clib_warning ("VCL<%d>: returning %d", getpid (), num_ev);
2745 for (i = 0; i < n_sids; i++)
2746 {
2747 clib_warning ("VCL<%d>: vp[%d].sid %d (0x%x), .events 0x%x, "
2748 ".revents 0x%x", getpid (), i, vp[i].sid, vp[i].sid,
2749 vp[i].events, *vp[i].revents);
2750 }
2751 }
2752 return num_ev;
2753}
2754
Dave Wallacee22aa742017-10-20 12:30:38 -04002755/*
2756 * fd.io coding-style-patch-verification: ON
2757 *
2758 * Local Variables:
2759 * eval: (c-set-style "gnu")
2760 * End:
2761 */