blob: 10cf17a5185f2f88e7bc921d193167194db20b24 [file] [log] [blame]
Dave Wallace543852a2017-08-03 02:11:34 -04001/*
Florin Coras5e062572019-03-14 19:07:51 -07002 * Copyright (c) 2017-2019 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 Wallace5c7cf1c2017-10-24 04:12:18 -040018#include <vcl/vppcom.h>
Florin Coras0d427d82018-06-27 03:24:07 -070019#include <vcl/vcl_debug.h>
Florin Coras697faea2018-06-27 17:10:49 -070020#include <vcl/vcl_private.h>
Florin Coras88001c62019-04-24 14:44:46 -070021#include <svm/fifo_segment.h>
Dave Wallace7e607a72018-06-18 18:41:32 -040022
Florin Coras134a9962018-08-28 11:32:04 -070023__thread uword __vcl_worker_index = ~0;
24
Florin Corasd85de682018-11-29 17:02:29 -080025static int
26vcl_wait_for_segment (u64 segment_handle)
Florin Coras54693d22018-07-17 10:46:29 -070027{
Florin Corasd85de682018-11-29 17:02:29 -080028 vcl_worker_t *wrk = vcl_worker_get_current ();
29 u32 wait_for_seconds = 10, segment_index;
30 f64 timeout;
Florin Coras54693d22018-07-17 10:46:29 -070031
Florin Corasd85de682018-11-29 17:02:29 -080032 if (segment_handle == VCL_INVALID_SEGMENT_HANDLE)
Florin Coras5f45e012019-01-23 09:21:30 -080033 return 0;
Florin Coras54693d22018-07-17 10:46:29 -070034
Florin Corasd85de682018-11-29 17:02:29 -080035 timeout = clib_time_now (&wrk->clib_time) + wait_for_seconds;
36 while (clib_time_now (&wrk->clib_time) < timeout)
Florin Coras54693d22018-07-17 10:46:29 -070037 {
Florin Corasd85de682018-11-29 17:02:29 -080038 segment_index = vcl_segment_table_lookup (segment_handle);
39 if (segment_index != VCL_INVALID_SEGMENT_INDEX)
40 return 0;
41 usleep (10);
Florin Coras54693d22018-07-17 10:46:29 -070042 }
Florin Corasd85de682018-11-29 17:02:29 -080043 return 1;
Florin Coras54693d22018-07-17 10:46:29 -070044}
45
Florin Coras30e79c22019-01-02 19:31:22 -080046static inline int
Florin Corase003a1b2019-06-05 10:47:16 -070047vcl_mq_dequeue_batch (vcl_worker_t * wrk, svm_msg_q_t * mq, u32 n_max_msg)
Florin Coras30e79c22019-01-02 19:31:22 -080048{
49 svm_msg_q_msg_t *msg;
50 u32 n_msgs;
51 int i;
52
Florin Corase003a1b2019-06-05 10:47:16 -070053 n_msgs = clib_min (svm_msg_q_size (mq), n_max_msg);
Florin Coras30e79c22019-01-02 19:31:22 -080054 for (i = 0; i < n_msgs; i++)
55 {
56 vec_add2 (wrk->mq_msg_vector, msg, 1);
57 svm_msg_q_sub_w_lock (mq, msg);
58 }
59 return n_msgs;
60}
61
Florin Coras697faea2018-06-27 17:10:49 -070062const char *
Florin Coras288eaab2019-02-03 15:26:14 -080063vppcom_session_state_str (vcl_session_state_t state)
Dave Wallace543852a2017-08-03 02:11:34 -040064{
65 char *st;
66
67 switch (state)
68 {
69 case STATE_START:
70 st = "STATE_START";
71 break;
72
73 case STATE_CONNECT:
74 st = "STATE_CONNECT";
75 break;
76
77 case STATE_LISTEN:
78 st = "STATE_LISTEN";
79 break;
80
81 case STATE_ACCEPT:
82 st = "STATE_ACCEPT";
83 break;
84
Florin Coras3c7d4f92018-12-14 11:28:43 -080085 case STATE_VPP_CLOSING:
86 st = "STATE_VPP_CLOSING";
Dave Wallace4878cbe2017-11-21 03:45:09 -050087 break;
88
Dave Wallace543852a2017-08-03 02:11:34 -040089 case STATE_DISCONNECT:
90 st = "STATE_DISCONNECT";
91 break;
92
93 case STATE_FAILED:
94 st = "STATE_FAILED";
95 break;
96
Florin Coras2d675d72019-01-28 15:54:27 -080097 case STATE_UPDATED:
98 st = "STATE_UPDATED";
99 break;
100
101 case STATE_LISTEN_NO_MQ:
102 st = "STATE_LISTEN_NO_MQ";
103 break;
104
Dave Wallace543852a2017-08-03 02:11:34 -0400105 default:
106 st = "UNKNOWN_STATE";
107 break;
108 }
109
110 return st;
111}
112
Dave Wallace543852a2017-08-03 02:11:34 -0400113u8 *
114format_ip4_address (u8 * s, va_list * args)
115{
116 u8 *a = va_arg (*args, u8 *);
117 return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
118}
119
120u8 *
121format_ip6_address (u8 * s, va_list * args)
122{
123 ip6_address_t *a = va_arg (*args, ip6_address_t *);
124 u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
125
126 i_max_n_zero = ARRAY_LEN (a->as_u16);
127 max_n_zeros = 0;
128 i_first_zero = i_max_n_zero;
129 n_zeros = 0;
130 for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
131 {
132 u32 is_zero = a->as_u16[i] == 0;
133 if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
134 {
135 i_first_zero = i;
136 n_zeros = 0;
137 }
138 n_zeros += is_zero;
139 if ((!is_zero && n_zeros > max_n_zeros)
140 || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
141 {
142 i_max_n_zero = i_first_zero;
143 max_n_zeros = n_zeros;
144 i_first_zero = ARRAY_LEN (a->as_u16);
145 n_zeros = 0;
146 }
147 }
148
149 last_double_colon = 0;
150 for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
151 {
152 if (i == i_max_n_zero && max_n_zeros > 1)
153 {
154 s = format (s, "::");
155 i += max_n_zeros - 1;
156 last_double_colon = 1;
157 }
158 else
159 {
160 s = format (s, "%s%x",
161 (last_double_colon || i == 0) ? "" : ":",
162 clib_net_to_host_u16 (a->as_u16[i]));
163 last_double_colon = 0;
164 }
165 }
166
167 return s;
168}
169
170/* Format an IP46 address. */
171u8 *
172format_ip46_address (u8 * s, va_list * args)
173{
174 ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
175 ip46_type_t type = va_arg (*args, ip46_type_t);
176 int is_ip4 = 1;
177
178 switch (type)
179 {
180 case IP46_TYPE_ANY:
181 is_ip4 = ip46_address_is_ip4 (ip46);
182 break;
183 case IP46_TYPE_IP4:
184 is_ip4 = 1;
185 break;
186 case IP46_TYPE_IP6:
187 is_ip4 = 0;
188 break;
189 }
190
191 return is_ip4 ?
192 format (s, "%U", format_ip4_address, &ip46->ip4) :
193 format (s, "%U", format_ip6_address, &ip46->ip6);
194}
195
Florin Coras697faea2018-06-27 17:10:49 -0700196/*
197 * VPPCOM Utility Functions
198 */
199
Florin Coras458089b2019-08-21 16:20:44 -0700200static void
201vcl_send_session_listen (vcl_worker_t * wrk, vcl_session_t * s)
202{
203 app_session_evt_t _app_evt, *app_evt = &_app_evt;
204 session_listen_msg_t *mp;
205 svm_msg_q_t *mq;
206
207 mq = vcl_worker_ctrl_mq (wrk);
208 app_alloc_ctrl_evt_to_vpp (mq, app_evt, SESSION_CTRL_EVT_LISTEN);
209 mp = (session_listen_msg_t *) app_evt->evt->data;
210 memset (mp, 0, sizeof (*mp));
211 mp->client_index = wrk->my_client_index;
212 mp->context = s->session_index;
213 mp->wrk_index = wrk->vpp_wrk_index;
214 mp->is_ip4 = s->transport.is_ip4;
215 clib_memcpy_fast (&mp->ip, &s->transport.lcl_ip, sizeof (mp->ip));
216 mp->port = s->transport.lcl_port;
217 mp->proto = s->session_type;
218 app_send_ctrl_evt_to_vpp (mq, app_evt);
219}
220
221static void
222vcl_send_session_connect (vcl_worker_t * wrk, vcl_session_t * s)
223{
224 app_session_evt_t _app_evt, *app_evt = &_app_evt;
225 session_connect_msg_t *mp;
226 svm_msg_q_t *mq;
227
228 mq = vcl_worker_ctrl_mq (wrk);
229 app_alloc_ctrl_evt_to_vpp (mq, app_evt, SESSION_CTRL_EVT_CONNECT);
230 mp = (session_connect_msg_t *) app_evt->evt->data;
231 memset (mp, 0, sizeof (*mp));
232 mp->client_index = wrk->my_client_index;
233 mp->context = s->session_index;
234 mp->wrk_index = wrk->vpp_wrk_index;
235 mp->is_ip4 = s->transport.is_ip4;
236 mp->parent_handle = s->parent_handle;
237 clib_memcpy_fast (&mp->ip, &s->transport.rmt_ip, sizeof (mp->ip));
Florin Corasef7cbf62019-10-17 09:56:27 -0700238 clib_memcpy_fast (&mp->lcl_ip, &s->transport.lcl_ip, sizeof (mp->lcl_ip));
Florin Coras458089b2019-08-21 16:20:44 -0700239 mp->port = s->transport.rmt_port;
240 mp->proto = s->session_type;
241 app_send_ctrl_evt_to_vpp (mq, app_evt);
242}
243
244void
245vcl_send_session_unlisten (vcl_worker_t * wrk, vcl_session_t * s)
246{
247 app_session_evt_t _app_evt, *app_evt = &_app_evt;
248 session_unlisten_msg_t *mp;
249 svm_msg_q_t *mq;
250
251 mq = vcl_worker_ctrl_mq (wrk);
252 app_alloc_ctrl_evt_to_vpp (mq, app_evt, SESSION_CTRL_EVT_UNLISTEN);
253 mp = (session_unlisten_msg_t *) app_evt->evt->data;
254 memset (mp, 0, sizeof (*mp));
255 mp->client_index = wrk->my_client_index;
256 mp->wrk_index = wrk->vpp_wrk_index;
257 mp->handle = s->vpp_handle;
258 mp->context = wrk->wrk_index;
259 app_send_ctrl_evt_to_vpp (mq, app_evt);
260}
261
262static void
263vcl_send_session_disconnect (vcl_worker_t * wrk, vcl_session_t * s)
264{
265 app_session_evt_t _app_evt, *app_evt = &_app_evt;
266 session_disconnect_msg_t *mp;
267 svm_msg_q_t *mq;
268
269 /* Send to thread that owns the session */
270 mq = s->vpp_evt_q;
271 app_alloc_ctrl_evt_to_vpp (mq, app_evt, SESSION_CTRL_EVT_DISCONNECT);
272 mp = (session_disconnect_msg_t *) app_evt->evt->data;
273 memset (mp, 0, sizeof (*mp));
274 mp->client_index = wrk->my_client_index;
275 mp->handle = s->vpp_handle;
276 app_send_ctrl_evt_to_vpp (mq, app_evt);
277}
278
279static void
280vcl_send_app_detach (vcl_worker_t * wrk)
281{
282 app_session_evt_t _app_evt, *app_evt = &_app_evt;
283 session_app_detach_msg_t *mp;
284 svm_msg_q_t *mq;
285
286 mq = vcl_worker_ctrl_mq (wrk);
287 app_alloc_ctrl_evt_to_vpp (mq, app_evt, SESSION_CTRL_EVT_APP_DETACH);
288 mp = (session_app_detach_msg_t *) app_evt->evt->data;
289 memset (mp, 0, sizeof (*mp));
290 mp->client_index = wrk->my_client_index;
291 app_send_ctrl_evt_to_vpp (mq, app_evt);
292}
Florin Coras697faea2018-06-27 17:10:49 -0700293
Florin Coras54693d22018-07-17 10:46:29 -0700294static void
295vcl_send_session_accepted_reply (svm_msg_q_t * mq, u32 context,
296 session_handle_t handle, int retval)
297{
298 app_session_evt_t _app_evt, *app_evt = &_app_evt;
299 session_accepted_reply_msg_t *rmp;
300 app_alloc_ctrl_evt_to_vpp (mq, app_evt, SESSION_CTRL_EVT_ACCEPTED_REPLY);
301 rmp = (session_accepted_reply_msg_t *) app_evt->evt->data;
302 rmp->handle = handle;
303 rmp->context = context;
304 rmp->retval = retval;
305 app_send_ctrl_evt_to_vpp (mq, app_evt);
306}
307
Florin Coras99368312018-08-02 10:45:44 -0700308static void
309vcl_send_session_disconnected_reply (svm_msg_q_t * mq, u32 context,
310 session_handle_t handle, int retval)
311{
312 app_session_evt_t _app_evt, *app_evt = &_app_evt;
313 session_disconnected_reply_msg_t *rmp;
314 app_alloc_ctrl_evt_to_vpp (mq, app_evt,
315 SESSION_CTRL_EVT_DISCONNECTED_REPLY);
316 rmp = (session_disconnected_reply_msg_t *) app_evt->evt->data;
317 rmp->handle = handle;
318 rmp->context = context;
319 rmp->retval = retval;
320 app_send_ctrl_evt_to_vpp (mq, app_evt);
321}
322
Florin Corasc9fbd662018-08-24 12:59:56 -0700323static void
324vcl_send_session_reset_reply (svm_msg_q_t * mq, u32 context,
325 session_handle_t handle, int retval)
326{
327 app_session_evt_t _app_evt, *app_evt = &_app_evt;
328 session_reset_reply_msg_t *rmp;
329 app_alloc_ctrl_evt_to_vpp (mq, app_evt, SESSION_CTRL_EVT_RESET_REPLY);
330 rmp = (session_reset_reply_msg_t *) app_evt->evt->data;
331 rmp->handle = handle;
332 rmp->context = context;
333 rmp->retval = retval;
334 app_send_ctrl_evt_to_vpp (mq, app_evt);
335}
336
Florin Coras30e79c22019-01-02 19:31:22 -0800337void
338vcl_send_session_worker_update (vcl_worker_t * wrk, vcl_session_t * s,
339 u32 wrk_index)
340{
341 app_session_evt_t _app_evt, *app_evt = &_app_evt;
342 session_worker_update_msg_t *mp;
343 svm_msg_q_t *mq;
344
345 mq = vcl_session_vpp_evt_q (wrk, s);
346 app_alloc_ctrl_evt_to_vpp (mq, app_evt, SESSION_CTRL_EVT_WORKER_UPDATE);
347 mp = (session_worker_update_msg_t *) app_evt->evt->data;
348 mp->client_index = wrk->my_client_index;
349 mp->handle = s->vpp_handle;
350 mp->req_wrk_index = wrk->vpp_wrk_index;
351 mp->wrk_index = wrk_index;
352 app_send_ctrl_evt_to_vpp (mq, app_evt);
353}
354
Florin Coras54693d22018-07-17 10:46:29 -0700355static u32
Florin Coras00cca802019-06-06 09:38:44 -0700356vcl_session_accepted_handler (vcl_worker_t * wrk, session_accepted_msg_t * mp,
357 u32 ls_index)
Florin Coras54693d22018-07-17 10:46:29 -0700358{
359 vcl_session_t *session, *listen_session;
360 svm_fifo_t *rx_fifo, *tx_fifo;
Florin Coras134a9962018-08-28 11:32:04 -0700361 u32 vpp_wrk_index;
Florin Coras99368312018-08-02 10:45:44 -0700362 svm_msg_q_t *evt_q;
Florin Coras54693d22018-07-17 10:46:29 -0700363
Florin Coras134a9962018-08-28 11:32:04 -0700364 session = vcl_session_alloc (wrk);
Florin Coras99368312018-08-02 10:45:44 -0700365
Florin Coras00cca802019-06-06 09:38:44 -0700366 listen_session = vcl_session_get (wrk, ls_index);
367 if (listen_session->vpp_handle != mp->listener_handle)
Florin Coras54693d22018-07-17 10:46:29 -0700368 {
Florin Coras00cca802019-06-06 09:38:44 -0700369 VDBG (0, "ERROR: listener handle %lu does not match session %u",
370 mp->listener_handle, ls_index);
371 goto error;
372 }
373
374 if (vcl_wait_for_segment (mp->segment_handle))
375 {
376 VDBG (0, "ERROR: segment for session %u couldn't be mounted!",
377 session->session_index);
378 goto error;
Florin Coras54693d22018-07-17 10:46:29 -0700379 }
380
Florin Coras54693d22018-07-17 10:46:29 -0700381 rx_fifo = uword_to_pointer (mp->server_rx_fifo, svm_fifo_t *);
382 tx_fifo = uword_to_pointer (mp->server_tx_fifo, svm_fifo_t *);
Florin Coras653e43f2019-03-04 10:56:23 -0800383 session->vpp_evt_q = uword_to_pointer (mp->vpp_event_queue_address,
384 svm_msg_q_t *);
385 rx_fifo->client_session_index = session->session_index;
386 tx_fifo->client_session_index = session->session_index;
387 rx_fifo->client_thread_index = vcl_get_worker_index ();
388 tx_fifo->client_thread_index = vcl_get_worker_index ();
389 vpp_wrk_index = tx_fifo->master_thread_index;
390 vec_validate (wrk->vpp_event_queues, vpp_wrk_index);
391 wrk->vpp_event_queues[vpp_wrk_index] = session->vpp_evt_q;
Florin Coras54693d22018-07-17 10:46:29 -0700392
393 session->vpp_handle = mp->handle;
Florin Coras3c7d4f92018-12-14 11:28:43 -0800394 session->vpp_thread_index = rx_fifo->master_thread_index;
Florin Coras54693d22018-07-17 10:46:29 -0700395 session->rx_fifo = rx_fifo;
396 session->tx_fifo = tx_fifo;
397
398 session->session_state = STATE_ACCEPT;
Florin Coras09d18c22019-04-24 11:10:02 -0700399 session->transport.rmt_port = mp->rmt.port;
400 session->transport.is_ip4 = mp->rmt.is_ip4;
401 clib_memcpy_fast (&session->transport.rmt_ip, &mp->rmt.ip,
Dave Barach178cf492018-11-13 16:34:13 -0500402 sizeof (ip46_address_t));
Florin Coras54693d22018-07-17 10:46:29 -0700403
Florin Coras134a9962018-08-28 11:32:04 -0700404 vcl_session_table_add_vpp_handle (wrk, mp->handle, session->session_index);
Florin Coras54693d22018-07-17 10:46:29 -0700405 session->transport.lcl_port = listen_session->transport.lcl_port;
406 session->transport.lcl_ip = listen_session->transport.lcl_ip;
Florin Coras460dce62018-07-27 05:45:06 -0700407 session->session_type = listen_session->session_type;
Nathan Skrzypczak9fd99622019-05-16 14:38:44 +0200408 session->is_dgram = vcl_proto_is_dgram (session->session_type);
409 session->listener_index = listen_session->session_index;
410 listen_session->n_accepted_sessions++;
Florin Coras54693d22018-07-17 10:46:29 -0700411
Florin Coras5e062572019-03-14 19:07:51 -0700412 VDBG (1, "session %u [0x%llx]: client accept request from %s address %U"
413 " port %d queue %p!", session->session_index, mp->handle,
Florin Coras09d18c22019-04-24 11:10:02 -0700414 mp->rmt.is_ip4 ? "IPv4" : "IPv6", format_ip46_address, &mp->rmt.ip,
415 mp->rmt.is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6,
416 clib_net_to_host_u16 (mp->rmt.port), session->vpp_evt_q);
Florin Coras54693d22018-07-17 10:46:29 -0700417 vcl_evt (VCL_EVT_ACCEPT, session, listen_session, session_index);
418
Florin Coras00cca802019-06-06 09:38:44 -0700419 vcl_send_session_accepted_reply (session->vpp_evt_q, mp->context,
420 session->vpp_handle, 0);
421
Florin Coras134a9962018-08-28 11:32:04 -0700422 return session->session_index;
Florin Coras00cca802019-06-06 09:38:44 -0700423
424error:
425 evt_q = uword_to_pointer (mp->vpp_event_queue_address, svm_msg_q_t *);
426 vcl_send_session_accepted_reply (evt_q, mp->context, mp->handle,
427 VNET_API_ERROR_INVALID_ARGUMENT);
428 vcl_session_free (wrk, session);
429 return VCL_INVALID_SESSION_INDEX;
Florin Coras54693d22018-07-17 10:46:29 -0700430}
431
432static u32
Florin Coras134a9962018-08-28 11:32:04 -0700433vcl_session_connected_handler (vcl_worker_t * wrk,
434 session_connected_msg_t * mp)
Florin Coras54693d22018-07-17 10:46:29 -0700435{
Florin Coras99368312018-08-02 10:45:44 -0700436 u32 session_index, vpp_wrk_index;
Florin Coras54693d22018-07-17 10:46:29 -0700437 svm_fifo_t *rx_fifo, *tx_fifo;
Florin Coras99368312018-08-02 10:45:44 -0700438 vcl_session_t *session = 0;
Florin Coras54693d22018-07-17 10:46:29 -0700439
440 session_index = mp->context;
Florin Coras134a9962018-08-28 11:32:04 -0700441 session = vcl_session_get (wrk, session_index);
Florin Coras070453d2018-08-24 17:04:27 -0700442 if (!session)
443 {
Florin Coras5e062572019-03-14 19:07:51 -0700444 VDBG (0, "ERROR: vpp handle 0x%llx has no session index (%u)!",
445 mp->handle, session_index);
Florin Coras070453d2018-08-24 17:04:27 -0700446 return VCL_INVALID_SESSION_INDEX;
447 }
Florin Coras54693d22018-07-17 10:46:29 -0700448 if (mp->retval)
449 {
Florin Coras5e062572019-03-14 19:07:51 -0700450 VDBG (0, "ERROR: session index %u: connect failed! %U",
451 session_index, format_api_error, ntohl (mp->retval));
Florin Coras070453d2018-08-24 17:04:27 -0700452 session->session_state = STATE_FAILED;
453 session->vpp_handle = mp->handle;
454 return session_index;
Florin Coras54693d22018-07-17 10:46:29 -0700455 }
456
Florin Coras460dce62018-07-27 05:45:06 -0700457 rx_fifo = uword_to_pointer (mp->server_rx_fifo, svm_fifo_t *);
458 tx_fifo = uword_to_pointer (mp->server_tx_fifo, svm_fifo_t *);
Florin Corasd85de682018-11-29 17:02:29 -0800459 if (vcl_wait_for_segment (mp->segment_handle))
460 {
Florin Coras653e43f2019-03-04 10:56:23 -0800461 VDBG (0, "segment for session %u couldn't be mounted!",
462 session->session_index);
Florin Coras5e062572019-03-14 19:07:51 -0700463 session->session_state = STATE_FAILED;
Florin Corasd85de682018-11-29 17:02:29 -0800464 return VCL_INVALID_SESSION_INDEX;
465 }
466
Florin Coras460dce62018-07-27 05:45:06 -0700467 rx_fifo->client_session_index = session_index;
468 tx_fifo->client_session_index = session_index;
Florin Coras21795132018-09-09 09:40:51 -0700469 rx_fifo->client_thread_index = vcl_get_worker_index ();
470 tx_fifo->client_thread_index = vcl_get_worker_index ();
Florin Coras460dce62018-07-27 05:45:06 -0700471
Florin Coras653e43f2019-03-04 10:56:23 -0800472 session->vpp_evt_q = uword_to_pointer (mp->vpp_event_queue_address,
473 svm_msg_q_t *);
474 vpp_wrk_index = tx_fifo->master_thread_index;
475 vec_validate (wrk->vpp_event_queues, vpp_wrk_index);
476 wrk->vpp_event_queues[vpp_wrk_index] = session->vpp_evt_q;
Florin Coras99368312018-08-02 10:45:44 -0700477
Florin Coras653e43f2019-03-04 10:56:23 -0800478 if (mp->ct_rx_fifo)
Florin Coras99368312018-08-02 10:45:44 -0700479 {
Florin Coras653e43f2019-03-04 10:56:23 -0800480 session->ct_rx_fifo = uword_to_pointer (mp->ct_rx_fifo, svm_fifo_t *);
481 session->ct_tx_fifo = uword_to_pointer (mp->ct_tx_fifo, svm_fifo_t *);
482 if (vcl_wait_for_segment (mp->ct_segment_handle))
483 {
484 VDBG (0, "ct segment for session %u couldn't be mounted!",
485 session->session_index);
Florin Coras5e062572019-03-14 19:07:51 -0700486 session->session_state = STATE_FAILED;
Florin Coras653e43f2019-03-04 10:56:23 -0800487 return VCL_INVALID_SESSION_INDEX;
488 }
Florin Coras99368312018-08-02 10:45:44 -0700489 }
Florin Coras54693d22018-07-17 10:46:29 -0700490
Florin Coras54693d22018-07-17 10:46:29 -0700491 session->rx_fifo = rx_fifo;
492 session->tx_fifo = tx_fifo;
493 session->vpp_handle = mp->handle;
Florin Coras3c7d4f92018-12-14 11:28:43 -0800494 session->vpp_thread_index = rx_fifo->master_thread_index;
Florin Coras09d18c22019-04-24 11:10:02 -0700495 session->transport.is_ip4 = mp->lcl.is_ip4;
496 clib_memcpy_fast (&session->transport.lcl_ip, &mp->lcl.ip,
Dave Barach178cf492018-11-13 16:34:13 -0500497 sizeof (session->transport.lcl_ip));
Florin Coras09d18c22019-04-24 11:10:02 -0700498 session->transport.lcl_port = mp->lcl.port;
Florin Coras54693d22018-07-17 10:46:29 -0700499 session->session_state = STATE_CONNECT;
500
501 /* Add it to lookup table */
Florin Coras3c7d4f92018-12-14 11:28:43 -0800502 vcl_session_table_add_vpp_handle (wrk, mp->handle, session_index);
Florin Coras54693d22018-07-17 10:46:29 -0700503
Florin Coras5e062572019-03-14 19:07:51 -0700504 VDBG (1, "session %u [0x%llx] connected! rx_fifo %p, refcnt %d, tx_fifo %p,"
505 " refcnt %d", session_index, mp->handle, session->rx_fifo,
Florin Coras54693d22018-07-17 10:46:29 -0700506 session->rx_fifo->refcnt, session->tx_fifo, session->tx_fifo->refcnt);
Florin Coras070453d2018-08-24 17:04:27 -0700507
Florin Coras54693d22018-07-17 10:46:29 -0700508 return session_index;
509}
510
Florin Coras3c7d4f92018-12-14 11:28:43 -0800511static int
512vcl_flag_accepted_session (vcl_session_t * session, u64 handle, u32 flags)
513{
514 vcl_session_msg_t *accepted_msg;
515 int i;
516
517 for (i = 0; i < vec_len (session->accept_evts_fifo); i++)
518 {
519 accepted_msg = &session->accept_evts_fifo[i];
520 if (accepted_msg->accepted_msg.handle == handle)
521 {
Florin Corasb0f662f2018-12-27 14:51:46 -0800522 accepted_msg->flags |= flags;
Florin Coras3c7d4f92018-12-14 11:28:43 -0800523 return 1;
524 }
525 }
526 return 0;
527}
528
Florin Corasc9fbd662018-08-24 12:59:56 -0700529static u32
Florin Coras134a9962018-08-28 11:32:04 -0700530vcl_session_reset_handler (vcl_worker_t * wrk,
531 session_reset_msg_t * reset_msg)
Florin Corasc9fbd662018-08-24 12:59:56 -0700532{
533 vcl_session_t *session;
534 u32 sid;
535
Florin Coras134a9962018-08-28 11:32:04 -0700536 sid = vcl_session_index_from_vpp_handle (wrk, reset_msg->handle);
537 session = vcl_session_get (wrk, sid);
Florin Corasc9fbd662018-08-24 12:59:56 -0700538 if (!session)
539 {
540 VDBG (0, "request to reset unknown handle 0x%llx", reset_msg->handle);
541 return VCL_INVALID_SESSION_INDEX;
542 }
Florin Coras3c7d4f92018-12-14 11:28:43 -0800543
544 /* Caught a reset before actually accepting the session */
545 if (session->session_state == STATE_LISTEN)
546 {
547
548 if (!vcl_flag_accepted_session (session, reset_msg->handle,
549 VCL_ACCEPTED_F_RESET))
550 VDBG (0, "session was not accepted!");
551 return VCL_INVALID_SESSION_INDEX;
552 }
553
554 session->session_state = STATE_DISCONNECT;
555 VDBG (0, "reset session %u [0x%llx]", sid, reset_msg->handle);
Florin Corasc9fbd662018-08-24 12:59:56 -0700556 return sid;
557}
558
Florin Coras60116992018-08-27 09:52:18 -0700559static u32
Florin Coras134a9962018-08-28 11:32:04 -0700560vcl_session_bound_handler (vcl_worker_t * wrk, session_bound_msg_t * mp)
Florin Coras60116992018-08-27 09:52:18 -0700561{
562 vcl_session_t *session;
563 u32 sid = mp->context;
564
Florin Coras134a9962018-08-28 11:32:04 -0700565 session = vcl_session_get (wrk, sid);
Florin Coras60116992018-08-27 09:52:18 -0700566 if (mp->retval)
567 {
Florin Coras5e062572019-03-14 19:07:51 -0700568 VERR ("session %u [0x%llx]: bind failed: %U", sid, mp->handle,
Florin Corasd85de682018-11-29 17:02:29 -0800569 format_api_error, mp->retval);
Florin Coras60116992018-08-27 09:52:18 -0700570 if (session)
571 {
572 session->session_state = STATE_FAILED;
573 session->vpp_handle = mp->handle;
574 return sid;
575 }
576 else
577 {
Florin Coras5e062572019-03-14 19:07:51 -0700578 VDBG (0, "ERROR: session %u [0x%llx]: Invalid session index!",
579 sid, mp->handle);
Florin Coras60116992018-08-27 09:52:18 -0700580 return VCL_INVALID_SESSION_INDEX;
581 }
582 }
583
584 session->vpp_handle = mp->handle;
585 session->transport.is_ip4 = mp->lcl_is_ip4;
Dave Barach178cf492018-11-13 16:34:13 -0500586 clib_memcpy_fast (&session->transport.lcl_ip, mp->lcl_ip,
587 sizeof (ip46_address_t));
Florin Coras60116992018-08-27 09:52:18 -0700588 session->transport.lcl_port = mp->lcl_port;
Florin Coras134a9962018-08-28 11:32:04 -0700589 vcl_session_table_add_listener (wrk, mp->handle, sid);
Florin Coras60116992018-08-27 09:52:18 -0700590 session->session_state = STATE_LISTEN;
591
Florin Coras5f45e012019-01-23 09:21:30 -0800592 session->vpp_evt_q = uword_to_pointer (mp->vpp_evt_q, svm_msg_q_t *);
593 vec_validate (wrk->vpp_event_queues, 0);
594 wrk->vpp_event_queues[0] = session->vpp_evt_q;
595
Florin Coras60116992018-08-27 09:52:18 -0700596 if (session->is_dgram)
597 {
598 svm_fifo_t *rx_fifo, *tx_fifo;
599 session->vpp_evt_q = uword_to_pointer (mp->vpp_evt_q, svm_msg_q_t *);
600 rx_fifo = uword_to_pointer (mp->rx_fifo, svm_fifo_t *);
601 rx_fifo->client_session_index = sid;
602 tx_fifo = uword_to_pointer (mp->tx_fifo, svm_fifo_t *);
603 tx_fifo->client_session_index = sid;
604 session->rx_fifo = rx_fifo;
605 session->tx_fifo = tx_fifo;
606 }
607
Florin Coras05ecfcc2018-12-12 18:19:39 -0800608 VDBG (0, "session %u [0x%llx]: listen succeeded!", sid, mp->handle);
Florin Coras60116992018-08-27 09:52:18 -0700609 return sid;
610}
611
Florin Corasdfae9f92019-02-20 19:48:31 -0800612static void
613vcl_session_unlisten_reply_handler (vcl_worker_t * wrk, void *data)
614{
615 session_unlisten_reply_msg_t *mp = (session_unlisten_reply_msg_t *) data;
616 vcl_session_t *s;
617
618 s = vcl_session_get_w_vpp_handle (wrk, mp->handle);
619 if (!s || s->session_state != STATE_DISCONNECT)
620 {
621 VDBG (0, "Unlisten reply with wrong handle %llx", mp->handle);
622 return;
623 }
624
625 if (mp->retval)
626 VDBG (0, "ERROR: session %u [0xllx]: unlisten failed: %U",
627 s->session_index, mp->handle, format_api_error, ntohl (mp->retval));
628
629 if (mp->context != wrk->wrk_index)
630 VDBG (0, "wrong context");
631
632 vcl_session_table_del_vpp_handle (wrk, mp->handle);
633 vcl_session_free (wrk, s);
634}
635
Florin Coras3c7d4f92018-12-14 11:28:43 -0800636static vcl_session_t *
637vcl_session_accepted (vcl_worker_t * wrk, session_accepted_msg_t * msg)
638{
639 vcl_session_msg_t *vcl_msg;
640 vcl_session_t *session;
641
642 session = vcl_session_get_w_vpp_handle (wrk, msg->handle);
643 if (PREDICT_FALSE (session != 0))
Florin Corasb0f662f2018-12-27 14:51:46 -0800644 VWRN ("session overlap handle %lu state %u!", msg->handle,
645 session->session_state);
Florin Coras3c7d4f92018-12-14 11:28:43 -0800646
647 session = vcl_session_table_lookup_listener (wrk, msg->listener_handle);
648 if (!session)
649 {
650 VERR ("couldn't find listen session: listener handle %llx",
651 msg->listener_handle);
652 return 0;
653 }
654
655 clib_fifo_add2 (session->accept_evts_fifo, vcl_msg);
656 vcl_msg->accepted_msg = *msg;
657 /* Session handle points to listener until fully accepted by app */
658 vcl_session_table_add_vpp_handle (wrk, msg->handle, session->session_index);
659
660 return session;
661}
662
663static vcl_session_t *
664vcl_session_disconnected_handler (vcl_worker_t * wrk,
665 session_disconnected_msg_t * msg)
666{
667 vcl_session_t *session;
668
669 session = vcl_session_get_w_vpp_handle (wrk, msg->handle);
670 if (!session)
671 {
672 VDBG (0, "request to disconnect unknown handle 0x%llx", msg->handle);
673 return 0;
674 }
675
676 /* Caught a disconnect before actually accepting the session */
677 if (session->session_state == STATE_LISTEN)
678 {
Florin Coras3c7d4f92018-12-14 11:28:43 -0800679 if (!vcl_flag_accepted_session (session, msg->handle,
680 VCL_ACCEPTED_F_CLOSED))
681 VDBG (0, "session was not accepted!");
682 return 0;
683 }
684
685 session->session_state = STATE_VPP_CLOSING;
686 return session;
687}
688
Florin Coras30e79c22019-01-02 19:31:22 -0800689static void
690vcl_session_req_worker_update_handler (vcl_worker_t * wrk, void *data)
691{
692 session_req_worker_update_msg_t *msg;
693 vcl_session_t *s;
694
695 msg = (session_req_worker_update_msg_t *) data;
696 s = vcl_session_get_w_vpp_handle (wrk, msg->session_handle);
697 if (!s)
698 return;
699
700 vec_add1 (wrk->pending_session_wrk_updates, s->session_index);
701}
702
703static void
704vcl_session_worker_update_reply_handler (vcl_worker_t * wrk, void *data)
705{
706 session_worker_update_reply_msg_t *msg;
707 vcl_session_t *s;
708
709 msg = (session_worker_update_reply_msg_t *) data;
710 s = vcl_session_get_w_vpp_handle (wrk, msg->handle);
711 if (!s)
712 {
713 VDBG (0, "unknown handle 0x%llx", msg->handle);
714 return;
715 }
716 if (vcl_wait_for_segment (msg->segment_handle))
717 {
718 clib_warning ("segment for session %u couldn't be mounted!",
719 s->session_index);
720 return;
721 }
Florin Coras30e79c22019-01-02 19:31:22 -0800722
Florin Coras5f45e012019-01-23 09:21:30 -0800723 if (s->rx_fifo)
724 {
725 s->rx_fifo = uword_to_pointer (msg->rx_fifo, svm_fifo_t *);
726 s->tx_fifo = uword_to_pointer (msg->tx_fifo, svm_fifo_t *);
727 s->rx_fifo->client_session_index = s->session_index;
728 s->tx_fifo->client_session_index = s->session_index;
729 s->rx_fifo->client_thread_index = wrk->wrk_index;
730 s->tx_fifo->client_thread_index = wrk->wrk_index;
731 }
Florin Coras30e79c22019-01-02 19:31:22 -0800732 s->session_state = STATE_UPDATED;
733
Florin Coras30e79c22019-01-02 19:31:22 -0800734 VDBG (0, "session %u[0x%llx] moved to worker %u", s->session_index,
735 s->vpp_handle, wrk->wrk_index);
736}
737
Florin Coras86f04502018-09-12 16:08:01 -0700738static int
739vcl_handle_mq_event (vcl_worker_t * wrk, session_event_t * e)
Florin Coras54693d22018-07-17 10:46:29 -0700740{
Florin Coras54693d22018-07-17 10:46:29 -0700741 session_disconnected_msg_t *disconnected_msg;
Florin Coras54693d22018-07-17 10:46:29 -0700742 vcl_session_t *session;
Florin Coras54693d22018-07-17 10:46:29 -0700743
744 switch (e->event_type)
745 {
Florin Coras653e43f2019-03-04 10:56:23 -0800746 case SESSION_IO_EVT_RX:
747 case SESSION_IO_EVT_TX:
Florin Corasc0737e92019-03-04 14:19:39 -0800748 session = vcl_session_get (wrk, e->session_index);
Florin Coras653e43f2019-03-04 10:56:23 -0800749 if (!session || !(session->session_state & STATE_OPEN))
750 break;
Florin Coras86f04502018-09-12 16:08:01 -0700751 vec_add1 (wrk->unhandled_evts_vector, *e);
Florin Coras54693d22018-07-17 10:46:29 -0700752 break;
753 case SESSION_CTRL_EVT_ACCEPTED:
Florin Coras3c7d4f92018-12-14 11:28:43 -0800754 vcl_session_accepted (wrk, (session_accepted_msg_t *) e->data);
Florin Coras54693d22018-07-17 10:46:29 -0700755 break;
756 case SESSION_CTRL_EVT_CONNECTED:
Florin Coras134a9962018-08-28 11:32:04 -0700757 vcl_session_connected_handler (wrk,
758 (session_connected_msg_t *) e->data);
Florin Coras54693d22018-07-17 10:46:29 -0700759 break;
760 case SESSION_CTRL_EVT_DISCONNECTED:
761 disconnected_msg = (session_disconnected_msg_t *) e->data;
Florin Coras3c7d4f92018-12-14 11:28:43 -0800762 session = vcl_session_disconnected_handler (wrk, disconnected_msg);
Florin Corasc9fbd662018-08-24 12:59:56 -0700763 if (!session)
Florin Coras3c7d4f92018-12-14 11:28:43 -0800764 break;
Florin Coras3c7d4f92018-12-14 11:28:43 -0800765 VDBG (0, "disconnected session %u [0x%llx]", session->session_index,
766 session->vpp_handle);
Florin Corasc9fbd662018-08-24 12:59:56 -0700767 break;
768 case SESSION_CTRL_EVT_RESET:
Florin Coras134a9962018-08-28 11:32:04 -0700769 vcl_session_reset_handler (wrk, (session_reset_msg_t *) e->data);
Florin Coras60116992018-08-27 09:52:18 -0700770 break;
771 case SESSION_CTRL_EVT_BOUND:
Florin Coras134a9962018-08-28 11:32:04 -0700772 vcl_session_bound_handler (wrk, (session_bound_msg_t *) e->data);
Florin Coras54693d22018-07-17 10:46:29 -0700773 break;
Florin Corasdfae9f92019-02-20 19:48:31 -0800774 case SESSION_CTRL_EVT_UNLISTEN_REPLY:
775 vcl_session_unlisten_reply_handler (wrk, e->data);
776 break;
Florin Coras30e79c22019-01-02 19:31:22 -0800777 case SESSION_CTRL_EVT_REQ_WORKER_UPDATE:
778 vcl_session_req_worker_update_handler (wrk, e->data);
779 break;
780 case SESSION_CTRL_EVT_WORKER_UPDATE_REPLY:
781 vcl_session_worker_update_reply_handler (wrk, e->data);
782 break;
Florin Coras54693d22018-07-17 10:46:29 -0700783 default:
784 clib_warning ("unhandled %u", e->event_type);
785 }
786 return VPPCOM_OK;
787}
788
Florin Coras30e79c22019-01-02 19:31:22 -0800789static int
Florin Coras697faea2018-06-27 17:10:49 -0700790vppcom_wait_for_session_state_change (u32 session_index,
Florin Coras288eaab2019-02-03 15:26:14 -0800791 vcl_session_state_t state,
Florin Coras697faea2018-06-27 17:10:49 -0700792 f64 wait_for_time)
793{
Florin Coras134a9962018-08-28 11:32:04 -0700794 vcl_worker_t *wrk = vcl_worker_get_current ();
795 f64 timeout = clib_time_now (&wrk->clib_time) + wait_for_time;
Florin Coras697faea2018-06-27 17:10:49 -0700796 vcl_session_t *volatile session;
Florin Coras54693d22018-07-17 10:46:29 -0700797 svm_msg_q_msg_t msg;
798 session_event_t *e;
Dave Wallace543852a2017-08-03 02:11:34 -0400799
Florin Coras697faea2018-06-27 17:10:49 -0700800 do
Dave Wallace543852a2017-08-03 02:11:34 -0400801 {
Florin Coras134a9962018-08-28 11:32:04 -0700802 session = vcl_session_get (wrk, session_index);
Florin Coras070453d2018-08-24 17:04:27 -0700803 if (PREDICT_FALSE (!session))
Florin Coras697faea2018-06-27 17:10:49 -0700804 {
Florin Coras070453d2018-08-24 17:04:27 -0700805 return VPPCOM_EBADFD;
Florin Coras697faea2018-06-27 17:10:49 -0700806 }
807 if (session->session_state & state)
808 {
Florin Coras697faea2018-06-27 17:10:49 -0700809 return VPPCOM_OK;
810 }
811 if (session->session_state & STATE_FAILED)
812 {
Florin Coras697faea2018-06-27 17:10:49 -0700813 return VPPCOM_ECONNREFUSED;
814 }
Florin Coras54693d22018-07-17 10:46:29 -0700815
Florin Coras134a9962018-08-28 11:32:04 -0700816 if (svm_msg_q_sub (wrk->app_event_queue, &msg, SVM_Q_NOWAIT, 0))
Florin Corasdc2e2512018-12-03 17:47:26 -0800817 {
818 usleep (100);
819 continue;
820 }
Florin Coras134a9962018-08-28 11:32:04 -0700821 e = svm_msg_q_msg_data (wrk->app_event_queue, &msg);
Florin Coras86f04502018-09-12 16:08:01 -0700822 vcl_handle_mq_event (wrk, e);
Florin Coras134a9962018-08-28 11:32:04 -0700823 svm_msg_q_free_msg (wrk->app_event_queue, &msg);
Florin Corasdcf55ce2017-11-16 15:32:50 -0800824 }
Florin Coras134a9962018-08-28 11:32:04 -0700825 while (clib_time_now (&wrk->clib_time) < timeout);
Florin Corasdcf55ce2017-11-16 15:32:50 -0800826
Florin Coras05ecfcc2018-12-12 18:19:39 -0800827 VDBG (0, "timeout waiting for state 0x%x (%s)", state,
Florin Coras697faea2018-06-27 17:10:49 -0700828 vppcom_session_state_str (state));
829 vcl_evt (VCL_EVT_SESSION_TIMEOUT, session, session_state);
Dave Wallace543852a2017-08-03 02:11:34 -0400830
Florin Coras697faea2018-06-27 17:10:49 -0700831 return VPPCOM_ETIMEDOUT;
Dave Wallace60caa062017-11-10 17:07:13 -0500832}
833
Florin Coras30e79c22019-01-02 19:31:22 -0800834static void
835vcl_handle_pending_wrk_updates (vcl_worker_t * wrk)
836{
Florin Coras288eaab2019-02-03 15:26:14 -0800837 vcl_session_state_t state;
Florin Coras30e79c22019-01-02 19:31:22 -0800838 vcl_session_t *s;
839 u32 *sip;
840
841 if (PREDICT_TRUE (vec_len (wrk->pending_session_wrk_updates) == 0))
842 return;
843
844 vec_foreach (sip, wrk->pending_session_wrk_updates)
845 {
846 s = vcl_session_get (wrk, *sip);
847 vcl_send_session_worker_update (wrk, s, wrk->wrk_index);
848 state = s->session_state;
849 vppcom_wait_for_session_state_change (s->session_index, STATE_UPDATED, 5);
850 s->session_state = state;
851 }
852 vec_reset_length (wrk->pending_session_wrk_updates);
853}
854
Florin Corasf9240dc2019-01-15 08:03:17 -0800855void
Florin Coras30e79c22019-01-02 19:31:22 -0800856vcl_flush_mq_events (void)
857{
858 vcl_worker_t *wrk = vcl_worker_get_current ();
859 svm_msg_q_msg_t *msg;
860 session_event_t *e;
861 svm_msg_q_t *mq;
862 int i;
863
864 mq = wrk->app_event_queue;
865 svm_msg_q_lock (mq);
Florin Corase003a1b2019-06-05 10:47:16 -0700866 vcl_mq_dequeue_batch (wrk, mq, ~0);
Florin Coras30e79c22019-01-02 19:31:22 -0800867 svm_msg_q_unlock (mq);
868
869 for (i = 0; i < vec_len (wrk->mq_msg_vector); i++)
870 {
871 msg = vec_elt_at_index (wrk->mq_msg_vector, i);
872 e = svm_msg_q_msg_data (mq, msg);
873 vcl_handle_mq_event (wrk, e);
874 svm_msg_q_free_msg (mq, msg);
875 }
876 vec_reset_length (wrk->mq_msg_vector);
877 vcl_handle_pending_wrk_updates (wrk);
878}
879
Florin Coras697faea2018-06-27 17:10:49 -0700880static int
881vppcom_app_session_enable (void)
Dave Wallace543852a2017-08-03 02:11:34 -0400882{
Florin Coras697faea2018-06-27 17:10:49 -0700883 int rv;
Dave Wallace543852a2017-08-03 02:11:34 -0400884
Florin Coras697faea2018-06-27 17:10:49 -0700885 if (vcm->app_state != STATE_APP_ENABLED)
886 {
887 vppcom_send_session_enable_disable (1 /* is_enabled == TRUE */ );
Florin Coras134a9962018-08-28 11:32:04 -0700888 rv = vcl_wait_for_app_state_change (STATE_APP_ENABLED);
Florin Coras697faea2018-06-27 17:10:49 -0700889 if (PREDICT_FALSE (rv))
890 {
Florin Coras5e062572019-03-14 19:07:51 -0700891 VDBG (0, "application session enable timed out! returning %d (%s)",
892 rv, vppcom_retval_str (rv));
Florin Coras697faea2018-06-27 17:10:49 -0700893 return rv;
894 }
895 }
896 return VPPCOM_OK;
Dave Wallace543852a2017-08-03 02:11:34 -0400897}
898
Florin Coras697faea2018-06-27 17:10:49 -0700899static int
900vppcom_app_attach (void)
Dave Wallace543852a2017-08-03 02:11:34 -0400901{
Florin Coras697faea2018-06-27 17:10:49 -0700902 int rv;
Dave Wallace543852a2017-08-03 02:11:34 -0400903
Florin Coras697faea2018-06-27 17:10:49 -0700904 vppcom_app_send_attach ();
Florin Coras134a9962018-08-28 11:32:04 -0700905 rv = vcl_wait_for_app_state_change (STATE_APP_ATTACHED);
Florin Coras697faea2018-06-27 17:10:49 -0700906 if (PREDICT_FALSE (rv))
907 {
Florin Coras5e062572019-03-14 19:07:51 -0700908 VDBG (0, "application attach timed out! returning %d (%s)", rv,
909 vppcom_retval_str (rv));
Florin Coras697faea2018-06-27 17:10:49 -0700910 return rv;
911 }
Dave Wallace543852a2017-08-03 02:11:34 -0400912
Florin Coras697faea2018-06-27 17:10:49 -0700913 return VPPCOM_OK;
Dave Wallace543852a2017-08-03 02:11:34 -0400914}
915
916static int
Florin Corasab2f6db2018-08-31 14:31:41 -0700917vppcom_session_unbind (u32 session_handle)
Dave Wallace543852a2017-08-03 02:11:34 -0400918{
Florin Coras134a9962018-08-28 11:32:04 -0700919 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Corasaaff5ee2019-07-08 13:00:00 -0700920 session_accepted_msg_t *accepted_msg;
Florin Coras7e12d942018-06-27 14:32:43 -0700921 vcl_session_t *session = 0;
Florin Corasaaff5ee2019-07-08 13:00:00 -0700922 vcl_session_msg_t *evt;
Dave Wallace543852a2017-08-03 02:11:34 -0400923
Florin Corasab2f6db2018-08-31 14:31:41 -0700924 session = vcl_session_get_w_handle (wrk, session_handle);
Florin Coras070453d2018-08-24 17:04:27 -0700925 if (!session)
926 return VPPCOM_EBADFD;
Dave Wallace4878cbe2017-11-21 03:45:09 -0500927
Florin Corasaaff5ee2019-07-08 13:00:00 -0700928 /* Flush pending accept events, if any */
929 while (clib_fifo_elts (session->accept_evts_fifo))
930 {
931 clib_fifo_sub2 (session->accept_evts_fifo, evt);
932 accepted_msg = &evt->accepted_msg;
933 vcl_session_table_del_vpp_handle (wrk, accepted_msg->handle);
934 vcl_send_session_accepted_reply (session->vpp_evt_q,
935 accepted_msg->context,
936 session->vpp_handle, -1);
937 }
938 clib_fifo_free (session->accept_evts_fifo);
939
Florin Coras458089b2019-08-21 16:20:44 -0700940 vcl_send_session_unlisten (wrk, session);
Dave Wallace4878cbe2017-11-21 03:45:09 -0500941
Florin Coras5e062572019-03-14 19:07:51 -0700942 VDBG (1, "session %u [0x%llx]: sending unbind!", session->session_index,
Florin Coras458089b2019-08-21 16:20:44 -0700943 session->vpp_handle);
Florin Coras0d427d82018-06-27 03:24:07 -0700944 vcl_evt (VCL_EVT_UNBIND, session);
Florin Coras458089b2019-08-21 16:20:44 -0700945
946 session->vpp_handle = ~0;
947 session->session_state = STATE_DISCONNECT;
Dave Wallace4878cbe2017-11-21 03:45:09 -0500948
Florin Coras070453d2018-08-24 17:04:27 -0700949 return VPPCOM_OK;
Dave Wallace543852a2017-08-03 02:11:34 -0400950}
951
Florin Coras697faea2018-06-27 17:10:49 -0700952static int
Florin Corasab2f6db2018-08-31 14:31:41 -0700953vppcom_session_disconnect (u32 session_handle)
Dave Wallace543852a2017-08-03 02:11:34 -0400954{
Florin Coras134a9962018-08-28 11:32:04 -0700955 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras99368312018-08-02 10:45:44 -0700956 svm_msg_q_t *vpp_evt_q;
Nathan Skrzypczak9fd99622019-05-16 14:38:44 +0200957 vcl_session_t *session, *listen_session;
Florin Coras288eaab2019-02-03 15:26:14 -0800958 vcl_session_state_t state;
Florin Coras99368312018-08-02 10:45:44 -0700959 u64 vpp_handle;
Dave Wallace543852a2017-08-03 02:11:34 -0400960
Florin Corasab2f6db2018-08-31 14:31:41 -0700961 session = vcl_session_get_w_handle (wrk, session_handle);
Florin Coras21795132018-09-09 09:40:51 -0700962 if (!session)
963 return VPPCOM_EBADFD;
964
Dave Wallace4878cbe2017-11-21 03:45:09 -0500965 vpp_handle = session->vpp_handle;
Florin Coras7e12d942018-06-27 14:32:43 -0700966 state = session->session_state;
Dave Wallace4878cbe2017-11-21 03:45:09 -0500967
Florin Coras5e062572019-03-14 19:07:51 -0700968 VDBG (1, "session %u [0x%llx] state 0x%x (%s)", session->session_index,
969 vpp_handle, state, vppcom_session_state_str (state));
Dave Wallace66cf6eb2017-10-26 02:51:07 -0400970
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -0800971 if (PREDICT_FALSE (state & STATE_LISTEN))
Dave Wallace66cf6eb2017-10-26 02:51:07 -0400972 {
Florin Coras5e062572019-03-14 19:07:51 -0700973 VDBG (0, "ERROR: Cannot disconnect a listen socket!");
Florin Coras070453d2018-08-24 17:04:27 -0700974 return VPPCOM_EBADFD;
Dave Wallace4878cbe2017-11-21 03:45:09 -0500975 }
Dave Wallace66cf6eb2017-10-26 02:51:07 -0400976
Florin Coras3c7d4f92018-12-14 11:28:43 -0800977 if (state & STATE_VPP_CLOSING)
Dave Wallace4878cbe2017-11-21 03:45:09 -0500978 {
Florin Coras134a9962018-08-28 11:32:04 -0700979 vpp_evt_q = vcl_session_vpp_evt_q (wrk, session);
Florin Coras47c40e22018-11-26 17:01:36 -0800980 vcl_send_session_disconnected_reply (vpp_evt_q, wrk->my_client_index,
Florin Coras99368312018-08-02 10:45:44 -0700981 vpp_handle, 0);
Florin Coras5e062572019-03-14 19:07:51 -0700982 VDBG (1, "session %u [0x%llx]: sending disconnect REPLY...",
983 session->session_index, vpp_handle);
Dave Wallace66cf6eb2017-10-26 02:51:07 -0400984 }
985 else
Dave Wallace227867f2017-11-13 21:21:53 -0500986 {
Florin Coras5e062572019-03-14 19:07:51 -0700987 VDBG (1, "session %u [0x%llx]: sending disconnect...",
988 session->session_index, vpp_handle);
Florin Coras458089b2019-08-21 16:20:44 -0700989 vcl_send_session_disconnect (wrk, session);
Dave Wallace227867f2017-11-13 21:21:53 -0500990 }
Dave Wallace66cf6eb2017-10-26 02:51:07 -0400991
Nathan Skrzypczak9fd99622019-05-16 14:38:44 +0200992 if (session->listener_index != VCL_INVALID_SESSION_INDEX)
993 {
994 listen_session = vcl_session_get (wrk, session->listener_index);
995 listen_session->n_accepted_sessions--;
996 }
997
Florin Coras070453d2018-08-24 17:04:27 -0700998 return VPPCOM_OK;
Dave Wallace543852a2017-08-03 02:11:34 -0400999}
1000
Florin Coras940f78f2018-11-30 12:11:20 -08001001/**
1002 * Handle app exit
1003 *
1004 * Notify vpp of the disconnect and mark the worker as free. If we're the
1005 * last worker, do a full cleanup otherwise, since we're probably a forked
1006 * child, avoid syscalls as much as possible. We might've lost privileges.
1007 */
1008void
1009vppcom_app_exit (void)
1010{
1011 if (!pool_elts (vcm->workers))
1012 return;
Florin Coras01f3f892018-12-02 12:45:53 -08001013 vcl_worker_cleanup (vcl_worker_get_current (), 1 /* notify vpp */ );
1014 vcl_set_worker_index (~0);
Florin Coras940f78f2018-11-30 12:11:20 -08001015 vcl_elog_stop (vcm);
1016 if (vec_len (vcm->workers) == 1)
Florin Coras470b2a62019-08-03 18:53:48 -07001017 vppcom_disconnect_from_vpp ();
Florin Coras940f78f2018-11-30 12:11:20 -08001018 else
Florin Coraseaec2a62018-12-04 16:34:05 -08001019 vl_client_send_disconnect (1 /* vpp should cleanup */ );
Florin Coras940f78f2018-11-30 12:11:20 -08001020}
1021
Dave Wallace543852a2017-08-03 02:11:34 -04001022/*
1023 * VPPCOM Public API functions
1024 */
1025int
1026vppcom_app_create (char *app_name)
1027{
Dave Wallace543852a2017-08-03 02:11:34 -04001028 vppcom_cfg_t *vcl_cfg = &vcm->cfg;
Dave Wallace543852a2017-08-03 02:11:34 -04001029 int rv;
1030
Florin Coras47c40e22018-11-26 17:01:36 -08001031 if (vcm->is_init)
Dave Wallace543852a2017-08-03 02:11:34 -04001032 {
Florin Coras955bfbb2018-12-04 13:43:45 -08001033 VDBG (1, "already initialized");
1034 return VPPCOM_EEXIST;
Dave Wallace543852a2017-08-03 02:11:34 -04001035 }
1036
Florin Coras47c40e22018-11-26 17:01:36 -08001037 vcm->is_init = 1;
1038 vppcom_cfg (&vcm->cfg);
1039 vcl_cfg = &vcm->cfg;
1040
1041 vcm->main_cpu = pthread_self ();
1042 vcm->main_pid = getpid ();
1043 vcm->app_name = format (0, "%s", app_name);
1044 vppcom_init_error_string_table ();
Florin Coras88001c62019-04-24 14:44:46 -07001045 fifo_segment_main_init (&vcm->segment_main, vcl_cfg->segment_baseva,
1046 20 /* timeout in secs */ );
Florin Coras47c40e22018-11-26 17:01:36 -08001047 pool_alloc (vcm->workers, vcl_cfg->max_workers);
1048 clib_spinlock_init (&vcm->workers_lock);
Florin Corasd85de682018-11-29 17:02:29 -08001049 clib_rwlock_init (&vcm->segment_table_lock);
Florin Coras940f78f2018-11-30 12:11:20 -08001050 atexit (vppcom_app_exit);
Florin Coras47c40e22018-11-26 17:01:36 -08001051
1052 /* Allocate default worker */
1053 vcl_worker_alloc_and_init ();
1054
1055 /* API hookup and connect to VPP */
1056 vppcom_api_hookup ();
1057 vcl_elog_init (vcm);
1058 vcm->app_state = STATE_APP_START;
1059 rv = vppcom_connect_to_vpp (app_name);
1060 if (rv)
Dave Wallace543852a2017-08-03 02:11:34 -04001061 {
Florin Coras47c40e22018-11-26 17:01:36 -08001062 VERR ("couldn't connect to VPP!");
1063 return rv;
Dave Wallace66cf6eb2017-10-26 02:51:07 -04001064 }
Florin Coras47c40e22018-11-26 17:01:36 -08001065 VDBG (0, "sending session enable");
1066 rv = vppcom_app_session_enable ();
1067 if (rv)
1068 {
1069 VERR ("vppcom_app_session_enable() failed!");
1070 return rv;
1071 }
1072
1073 VDBG (0, "sending app attach");
1074 rv = vppcom_app_attach ();
1075 if (rv)
1076 {
1077 VERR ("vppcom_app_attach() failed!");
1078 return rv;
1079 }
1080
1081 VDBG (0, "app_name '%s', my_client_index %d (0x%x)", app_name,
1082 vcm->workers[0].my_client_index, vcm->workers[0].my_client_index);
Dave Wallace543852a2017-08-03 02:11:34 -04001083
1084 return VPPCOM_OK;
1085}
1086
1087void
1088vppcom_app_destroy (void)
1089{
Dave Wallace543852a2017-08-03 02:11:34 -04001090 int rv;
Dave Wallacede910062018-03-20 09:22:13 -04001091 f64 orig_app_timeout;
Dave Wallace543852a2017-08-03 02:11:34 -04001092
Florin Coras940f78f2018-11-30 12:11:20 -08001093 if (!pool_elts (vcm->workers))
1094 return;
1095
Florin Coras0d427d82018-06-27 03:24:07 -07001096 vcl_evt (VCL_EVT_DETACH, vcm);
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -08001097
Florin Coras940f78f2018-11-30 12:11:20 -08001098 if (pool_elts (vcm->workers) == 1)
Florin Coras47c40e22018-11-26 17:01:36 -08001099 {
Florin Coras458089b2019-08-21 16:20:44 -07001100 vcl_send_app_detach (vcl_worker_get_current ());
Florin Coras47c40e22018-11-26 17:01:36 -08001101 orig_app_timeout = vcm->cfg.app_timeout;
1102 vcm->cfg.app_timeout = 2.0;
1103 rv = vcl_wait_for_app_state_change (STATE_APP_ENABLED);
1104 vcm->cfg.app_timeout = orig_app_timeout;
1105 if (PREDICT_FALSE (rv))
1106 VDBG (0, "application detach timed out! returning %d (%s)", rv,
1107 vppcom_retval_str (rv));
Florin Coras940f78f2018-11-30 12:11:20 -08001108 vec_free (vcm->app_name);
Florin Coras01f3f892018-12-02 12:45:53 -08001109 vcl_worker_cleanup (vcl_worker_get_current (), 0 /* notify vpp */ );
Florin Coras47c40e22018-11-26 17:01:36 -08001110 }
1111 else
1112 {
Florin Coras01f3f892018-12-02 12:45:53 -08001113 vcl_worker_cleanup (vcl_worker_get_current (), 1 /* notify vpp */ );
Florin Coras47c40e22018-11-26 17:01:36 -08001114 }
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -08001115
Florin Coras01f3f892018-12-02 12:45:53 -08001116 vcl_set_worker_index (~0);
Florin Coras0d427d82018-06-27 03:24:07 -07001117 vcl_elog_stop (vcm);
Dave Wallace543852a2017-08-03 02:11:34 -04001118 vl_client_disconnect_from_vlib ();
Dave Wallace543852a2017-08-03 02:11:34 -04001119}
1120
1121int
Dave Wallacec04cbf12018-02-07 18:14:02 -05001122vppcom_session_create (u8 proto, u8 is_nonblocking)
Dave Wallace543852a2017-08-03 02:11:34 -04001123{
Florin Coras134a9962018-08-28 11:32:04 -07001124 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras7e12d942018-06-27 14:32:43 -07001125 vcl_session_t *session;
Dave Wallace543852a2017-08-03 02:11:34 -04001126
Florin Coras134a9962018-08-28 11:32:04 -07001127 session = vcl_session_alloc (wrk);
Dave Wallace543852a2017-08-03 02:11:34 -04001128
Florin Coras7e12d942018-06-27 14:32:43 -07001129 session->session_type = proto;
1130 session->session_state = STATE_START;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001131 session->vpp_handle = ~0;
Nathan Skrzypczak9fd99622019-05-16 14:38:44 +02001132 session->is_dgram = vcl_proto_is_dgram (proto);
Dave Wallace543852a2017-08-03 02:11:34 -04001133
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001134 if (is_nonblocking)
1135 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_NONBLOCK);
Dave Wallace543852a2017-08-03 02:11:34 -04001136
Florin Coras7e12d942018-06-27 14:32:43 -07001137 vcl_evt (VCL_EVT_CREATE, session, session_type, session->session_state,
1138 is_nonblocking, session_index);
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08001139
Florin Coras5e062572019-03-14 19:07:51 -07001140 VDBG (0, "created session %u", session->session_index);
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08001141
Florin Coras134a9962018-08-28 11:32:04 -07001142 return vcl_session_handle (session);
Dave Wallace543852a2017-08-03 02:11:34 -04001143}
1144
1145int
Florin Corasf9240dc2019-01-15 08:03:17 -08001146vcl_session_cleanup (vcl_worker_t * wrk, vcl_session_t * session,
1147 vcl_session_handle_t sh, u8 do_disconnect)
Dave Wallace543852a2017-08-03 02:11:34 -04001148{
Florin Coras288eaab2019-02-03 15:26:14 -08001149 vcl_session_state_t state;
Florin Coras134a9962018-08-28 11:32:04 -07001150 u32 next_sh, vep_sh;
1151 int rv = VPPCOM_OK;
1152 u64 vpp_handle;
Florin Corasf9240dc2019-01-15 08:03:17 -08001153 u8 is_vep;
Florin Coras47c40e22018-11-26 17:01:36 -08001154
Dave Wallace66cf6eb2017-10-26 02:51:07 -04001155 is_vep = session->is_vep;
Florin Coras134a9962018-08-28 11:32:04 -07001156 next_sh = session->vep.next_sh;
1157 vep_sh = session->vep.vep_sh;
Florin Coras7e12d942018-06-27 14:32:43 -07001158 state = session->session_state;
Dave Wallaceee45d412017-11-24 21:44:06 -05001159 vpp_handle = session->vpp_handle;
Dave Wallace543852a2017-08-03 02:11:34 -04001160
Florin Corasf9240dc2019-01-15 08:03:17 -08001161 VDBG (1, "session %u [0x%llx] closing", session->session_index, vpp_handle);
Dave Wallace543852a2017-08-03 02:11:34 -04001162
Dave Wallace66cf6eb2017-10-26 02:51:07 -04001163 if (is_vep)
Dave Wallace543852a2017-08-03 02:11:34 -04001164 {
Florin Coras134a9962018-08-28 11:32:04 -07001165 while (next_sh != ~0)
Dave Wallace19481612017-09-15 18:47:44 -04001166 {
Florin Corasf9240dc2019-01-15 08:03:17 -08001167 rv = vppcom_epoll_ctl (sh, EPOLL_CTL_DEL, next_sh, 0);
Florin Coras0d427d82018-06-27 03:24:07 -07001168 if (PREDICT_FALSE (rv < 0))
Florin Coras5e062572019-03-14 19:07:51 -07001169 VDBG (0, "vpp handle 0x%llx, sh %u: EPOLL_CTL_DEL vep_idx %u"
Florin Coras47c40e22018-11-26 17:01:36 -08001170 " failed! rv %d (%s)", vpp_handle, next_sh, vep_sh, rv,
1171 vppcom_retval_str (rv));
Dave Wallacef7f809c2017-10-03 01:48:42 -04001172
Florin Coras134a9962018-08-28 11:32:04 -07001173 next_sh = session->vep.next_sh;
Dave Wallacef7f809c2017-10-03 01:48:42 -04001174 }
1175 }
1176 else
1177 {
Florin Coras47c40e22018-11-26 17:01:36 -08001178 if (session->is_vep_session)
Dave Wallacef7f809c2017-10-03 01:48:42 -04001179 {
Florin Corasf9240dc2019-01-15 08:03:17 -08001180 rv = vppcom_epoll_ctl (vep_sh, EPOLL_CTL_DEL, sh, 0);
Florin Coras0d427d82018-06-27 03:24:07 -07001181 if (rv < 0)
Florin Corasf9240dc2019-01-15 08:03:17 -08001182 VDBG (0, "session %u [0x%llx]: EPOLL_CTL_DEL vep_idx %u "
1183 "failed! rv %d (%s)", session->session_index, vpp_handle,
1184 vep_sh, rv, vppcom_retval_str (rv));
Dave Wallacef7f809c2017-10-03 01:48:42 -04001185 }
1186
Florin Coras47c40e22018-11-26 17:01:36 -08001187 if (!do_disconnect)
Florin Coras30e79c22019-01-02 19:31:22 -08001188 {
Florin Coras0ef8ef22019-01-18 08:37:13 -08001189 VDBG (1, "session %u [0x%llx] disconnect skipped",
Florin Corasf9240dc2019-01-15 08:03:17 -08001190 session->session_index, vpp_handle);
Florin Coras30e79c22019-01-02 19:31:22 -08001191 goto cleanup;
1192 }
Florin Coras47c40e22018-11-26 17:01:36 -08001193
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001194 if (state & STATE_LISTEN)
Dave Wallacef7f809c2017-10-03 01:48:42 -04001195 {
Florin Corasf9240dc2019-01-15 08:03:17 -08001196 rv = vppcom_session_unbind (sh);
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001197 if (PREDICT_FALSE (rv < 0))
Florin Corasf9240dc2019-01-15 08:03:17 -08001198 VDBG (0, "session %u [0x%llx]: listener unbind failed! "
1199 "rv %d (%s)", session->session_index, vpp_handle, rv,
Florin Coras47c40e22018-11-26 17:01:36 -08001200 vppcom_retval_str (rv));
Florin Corasdfae9f92019-02-20 19:48:31 -08001201 return rv;
Dave Wallacef7f809c2017-10-03 01:48:42 -04001202 }
Nathan Skrzypczak9fd99622019-05-16 14:38:44 +02001203 else if ((state & STATE_OPEN)
1204 || (vcl_session_is_connectable_listener (wrk, session)))
Dave Wallacef7f809c2017-10-03 01:48:42 -04001205 {
Florin Corasf9240dc2019-01-15 08:03:17 -08001206 rv = vppcom_session_disconnect (sh);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001207 if (PREDICT_FALSE (rv < 0))
Florin Corasf9240dc2019-01-15 08:03:17 -08001208 VDBG (0, "ERROR: session %u [0x%llx]: disconnect failed!"
1209 " rv %d (%s)", session->session_index, vpp_handle,
1210 rv, vppcom_retval_str (rv));
Dave Wallacef7f809c2017-10-03 01:48:42 -04001211 }
Florin Corasb0f662f2018-12-27 14:51:46 -08001212 else if (state == STATE_DISCONNECT)
1213 {
1214 svm_msg_q_t *mq = vcl_session_vpp_evt_q (wrk, session);
1215 vcl_send_session_reset_reply (mq, wrk->my_client_index,
1216 session->vpp_handle, 0);
1217 }
Dave Wallace19481612017-09-15 18:47:44 -04001218 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05001219
Florin Coras0ef8ef22019-01-18 08:37:13 -08001220 VDBG (0, "session %u [0x%llx] removed", session->session_index, vpp_handle);
1221
Florin Corasf9240dc2019-01-15 08:03:17 -08001222cleanup:
Florin Coras30e79c22019-01-02 19:31:22 -08001223 vcl_session_table_del_vpp_handle (wrk, vpp_handle);
Florin Coras134a9962018-08-28 11:32:04 -07001224 vcl_session_free (wrk, session);
Florin Coras0d427d82018-06-27 03:24:07 -07001225 vcl_evt (VCL_EVT_CLOSE, session, rv);
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08001226
Dave Wallace543852a2017-08-03 02:11:34 -04001227 return rv;
1228}
1229
1230int
Florin Corasf9240dc2019-01-15 08:03:17 -08001231vppcom_session_close (uint32_t session_handle)
1232{
1233 vcl_worker_t *wrk = vcl_worker_get_current ();
1234 vcl_session_t *session;
1235
1236 session = vcl_session_get_w_handle (wrk, session_handle);
1237 if (!session)
1238 return VPPCOM_EBADFD;
1239 return vcl_session_cleanup (wrk, session, session_handle,
1240 1 /* do_disconnect */ );
1241}
1242
1243int
Florin Coras134a9962018-08-28 11:32:04 -07001244vppcom_session_bind (uint32_t session_handle, vppcom_endpt_t * ep)
Dave Wallace543852a2017-08-03 02:11:34 -04001245{
Florin Coras134a9962018-08-28 11:32:04 -07001246 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras7e12d942018-06-27 14:32:43 -07001247 vcl_session_t *session = 0;
Dave Wallace543852a2017-08-03 02:11:34 -04001248
1249 if (!ep || !ep->ip)
1250 return VPPCOM_EINVAL;
1251
Florin Coras134a9962018-08-28 11:32:04 -07001252 session = vcl_session_get_w_handle (wrk, session_handle);
Florin Coras070453d2018-08-24 17:04:27 -07001253 if (!session)
1254 return VPPCOM_EBADFD;
Dave Wallace543852a2017-08-03 02:11:34 -04001255
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001256 if (session->is_vep)
1257 {
Florin Coras5e062572019-03-14 19:07:51 -07001258 VDBG (0, "ERROR: cannot bind to epoll session %u!",
1259 session->session_index);
Florin Coras070453d2018-08-24 17:04:27 -07001260 return VPPCOM_EBADFD;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001261 }
1262
Florin Coras7e12d942018-06-27 14:32:43 -07001263 session->transport.is_ip4 = ep->is_ip4;
Florin Coras54693d22018-07-17 10:46:29 -07001264 if (ep->is_ip4)
Dave Barach178cf492018-11-13 16:34:13 -05001265 clib_memcpy_fast (&session->transport.lcl_ip.ip4, ep->ip,
1266 sizeof (ip4_address_t));
Florin Coras54693d22018-07-17 10:46:29 -07001267 else
Dave Barach178cf492018-11-13 16:34:13 -05001268 clib_memcpy_fast (&session->transport.lcl_ip.ip6, ep->ip,
1269 sizeof (ip6_address_t));
Florin Coras7e12d942018-06-27 14:32:43 -07001270 session->transport.lcl_port = ep->port;
Stevenac1f96d2017-10-24 16:03:58 -07001271
Florin Coras5e062572019-03-14 19:07:51 -07001272 VDBG (0, "session %u handle %u: binding to local %s address %U port %u, "
1273 "proto %s", session->session_index, session_handle,
Florin Coras7e12d942018-06-27 14:32:43 -07001274 session->transport.is_ip4 ? "IPv4" : "IPv6",
1275 format_ip46_address, &session->transport.lcl_ip,
1276 session->transport.is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6,
1277 clib_net_to_host_u16 (session->transport.lcl_port),
Ping Yu34a3a082018-11-30 19:16:17 -05001278 vppcom_proto_str (session->session_type));
Florin Coras0d427d82018-06-27 03:24:07 -07001279 vcl_evt (VCL_EVT_BIND, session);
Florin Coras460dce62018-07-27 05:45:06 -07001280
1281 if (session->session_type == VPPCOM_PROTO_UDP)
Florin Coras134a9962018-08-28 11:32:04 -07001282 vppcom_session_listen (session_handle, 10);
Florin Coras460dce62018-07-27 05:45:06 -07001283
Florin Coras070453d2018-08-24 17:04:27 -07001284 return VPPCOM_OK;
Dave Wallace543852a2017-08-03 02:11:34 -04001285}
1286
1287int
Florin Coras134a9962018-08-28 11:32:04 -07001288vppcom_session_listen (uint32_t listen_sh, uint32_t q_len)
Dave Wallace543852a2017-08-03 02:11:34 -04001289{
Florin Coras134a9962018-08-28 11:32:04 -07001290 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras7e12d942018-06-27 14:32:43 -07001291 vcl_session_t *listen_session = 0;
Dave Wallaceee45d412017-11-24 21:44:06 -05001292 u64 listen_vpp_handle;
Florin Coras070453d2018-08-24 17:04:27 -07001293 int rv;
1294
Florin Coras134a9962018-08-28 11:32:04 -07001295 listen_session = vcl_session_get_w_handle (wrk, listen_sh);
Florin Coras05ecfcc2018-12-12 18:19:39 -08001296 if (!listen_session || listen_session->is_vep)
Florin Coras070453d2018-08-24 17:04:27 -07001297 return VPPCOM_EBADFD;
Dave Wallace543852a2017-08-03 02:11:34 -04001298
Keith Burns (alagalah)aba98de2018-02-22 03:23:40 -08001299 if (q_len == 0 || q_len == ~0)
1300 q_len = vcm->cfg.listen_queue_size;
1301
Dave Wallaceee45d412017-11-24 21:44:06 -05001302 listen_vpp_handle = listen_session->vpp_handle;
Florin Coras7e12d942018-06-27 14:32:43 -07001303 if (listen_session->session_state & STATE_LISTEN)
Dave Wallacee695cb42017-11-02 22:04:42 -04001304 {
Florin Coras05ecfcc2018-12-12 18:19:39 -08001305 VDBG (0, "session %u [0x%llx]: already in listen state!",
1306 listen_sh, listen_vpp_handle);
Florin Coras070453d2018-08-24 17:04:27 -07001307 return VPPCOM_OK;
Dave Wallacee695cb42017-11-02 22:04:42 -04001308 }
1309
Nathan Skrzypczak9fd99622019-05-16 14:38:44 +02001310 VDBG (0, "session %u: sending vpp listen request...", listen_sh);
Dave Wallace543852a2017-08-03 02:11:34 -04001311
Florin Coras070453d2018-08-24 17:04:27 -07001312 /*
1313 * Send listen request to vpp and wait for reply
1314 */
Florin Coras458089b2019-08-21 16:20:44 -07001315 vcl_send_session_listen (wrk, listen_session);
Florin Coras134a9962018-08-28 11:32:04 -07001316 rv = vppcom_wait_for_session_state_change (listen_session->session_index,
1317 STATE_LISTEN,
1318 vcm->cfg.session_timeout);
Dave Wallace543852a2017-08-03 02:11:34 -04001319
Florin Coras070453d2018-08-24 17:04:27 -07001320 if (PREDICT_FALSE (rv))
Dave Wallaceee45d412017-11-24 21:44:06 -05001321 {
Florin Coras134a9962018-08-28 11:32:04 -07001322 listen_session = vcl_session_get_w_handle (wrk, listen_sh);
Florin Coras05ecfcc2018-12-12 18:19:39 -08001323 VDBG (0, "session %u [0x%llx]: listen failed! returning %d (%s)",
1324 listen_sh, listen_session->vpp_handle, rv,
1325 vppcom_retval_str (rv));
Florin Coras070453d2018-08-24 17:04:27 -07001326 return rv;
Dave Wallaceee45d412017-11-24 21:44:06 -05001327 }
1328
Florin Coras070453d2018-08-24 17:04:27 -07001329 return VPPCOM_OK;
Keith Burns (alagalah)0d2b0d52018-03-06 15:55:22 -08001330}
1331
Ping Yu34a3a082018-11-30 19:16:17 -05001332int
1333vppcom_session_tls_add_cert (uint32_t session_handle, char *cert,
1334 uint32_t cert_len)
1335{
1336
1337 vcl_worker_t *wrk = vcl_worker_get_current ();
1338 vcl_session_t *session = 0;
1339
1340 session = vcl_session_get_w_handle (wrk, session_handle);
1341 if (!session)
1342 return VPPCOM_EBADFD;
1343
1344 if (cert_len == 0 || cert_len == ~0)
1345 return VPPCOM_EBADFD;
1346
1347 /*
1348 * Send listen request to vpp and wait for reply
1349 */
1350 vppcom_send_application_tls_cert_add (session, cert, cert_len);
Florin Coras458089b2019-08-21 16:20:44 -07001351 vcm->app_state = STATE_APP_ADDING_TLS_DATA;
1352 vcl_wait_for_app_state_change (STATE_APP_READY);
Ping Yu34a3a082018-11-30 19:16:17 -05001353 return VPPCOM_OK;
1354
1355}
1356
1357int
1358vppcom_session_tls_add_key (uint32_t session_handle, char *key,
1359 uint32_t key_len)
1360{
1361
1362 vcl_worker_t *wrk = vcl_worker_get_current ();
1363 vcl_session_t *session = 0;
1364
1365 session = vcl_session_get_w_handle (wrk, session_handle);
1366 if (!session)
1367 return VPPCOM_EBADFD;
1368
1369 if (key_len == 0 || key_len == ~0)
1370 return VPPCOM_EBADFD;
1371
Ping Yu34a3a082018-11-30 19:16:17 -05001372 vppcom_send_application_tls_key_add (session, key, key_len);
Florin Coras458089b2019-08-21 16:20:44 -07001373 vcm->app_state = STATE_APP_ADDING_TLS_DATA;
1374 vcl_wait_for_app_state_change (STATE_APP_READY);
Ping Yu34a3a082018-11-30 19:16:17 -05001375 return VPPCOM_OK;
Ping Yu34a3a082018-11-30 19:16:17 -05001376}
1377
Florin Coras134a9962018-08-28 11:32:04 -07001378static int
Florin Coras5e062572019-03-14 19:07:51 -07001379validate_args_session_accept_ (vcl_worker_t * wrk, vcl_session_t * ls)
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001380{
Florin Coras5e062572019-03-14 19:07:51 -07001381 if (ls->is_vep)
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001382 {
Florin Coras5e062572019-03-14 19:07:51 -07001383 VDBG (0, "ERROR: cannot accept on epoll session %u!",
1384 ls->session_index);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001385 return VPPCOM_EBADFD;
1386 }
1387
Nathan Skrzypczak9fd99622019-05-16 14:38:44 +02001388 if ((ls->session_state != STATE_LISTEN)
1389 && (!vcl_session_is_connectable_listener (wrk, ls)))
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001390 {
Nathan Skrzypczak9fd99622019-05-16 14:38:44 +02001391 VDBG (0,
1392 "ERROR: session [0x%llx]: not in listen state! state 0x%x"
1393 " (%s)", ls->vpp_handle, ls->session_state,
Florin Coras5e062572019-03-14 19:07:51 -07001394 vppcom_session_state_str (ls->session_state));
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001395 return VPPCOM_EBADFD;
1396 }
1397 return VPPCOM_OK;
1398}
1399
1400int
Nathan Skrzypczak9fd99622019-05-16 14:38:44 +02001401vppcom_unformat_proto (uint8_t * proto, char *proto_str)
1402{
1403 if (!strcmp (proto_str, "TCP"))
1404 *proto = VPPCOM_PROTO_TCP;
1405 else if (!strcmp (proto_str, "tcp"))
1406 *proto = VPPCOM_PROTO_TCP;
1407 else if (!strcmp (proto_str, "UDP"))
1408 *proto = VPPCOM_PROTO_UDP;
1409 else if (!strcmp (proto_str, "udp"))
1410 *proto = VPPCOM_PROTO_UDP;
1411 else if (!strcmp (proto_str, "UDPC"))
1412 *proto = VPPCOM_PROTO_UDPC;
1413 else if (!strcmp (proto_str, "udpc"))
1414 *proto = VPPCOM_PROTO_UDPC;
1415 else if (!strcmp (proto_str, "SCTP"))
1416 *proto = VPPCOM_PROTO_SCTP;
1417 else if (!strcmp (proto_str, "sctp"))
1418 *proto = VPPCOM_PROTO_SCTP;
1419 else if (!strcmp (proto_str, "TLS"))
1420 *proto = VPPCOM_PROTO_TLS;
1421 else if (!strcmp (proto_str, "tls"))
1422 *proto = VPPCOM_PROTO_TLS;
1423 else if (!strcmp (proto_str, "QUIC"))
1424 *proto = VPPCOM_PROTO_QUIC;
1425 else if (!strcmp (proto_str, "quic"))
1426 *proto = VPPCOM_PROTO_QUIC;
1427 else
1428 return 1;
1429 return 0;
1430}
1431
1432int
Florin Coras134a9962018-08-28 11:32:04 -07001433vppcom_session_accept (uint32_t listen_session_handle, vppcom_endpt_t * ep,
Dave Wallace048b1d62018-01-03 22:24:41 -05001434 uint32_t flags)
Dave Wallace543852a2017-08-03 02:11:34 -04001435{
Florin Coras3c7d4f92018-12-14 11:28:43 -08001436 u32 client_session_index = ~0, listen_session_index, accept_flags = 0;
Florin Coras134a9962018-08-28 11:32:04 -07001437 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras54693d22018-07-17 10:46:29 -07001438 session_accepted_msg_t accepted_msg;
Florin Coras7e12d942018-06-27 14:32:43 -07001439 vcl_session_t *listen_session = 0;
1440 vcl_session_t *client_session = 0;
Florin Coras54693d22018-07-17 10:46:29 -07001441 vcl_session_msg_t *evt;
Florin Coras54693d22018-07-17 10:46:29 -07001442 svm_msg_q_msg_t msg;
1443 session_event_t *e;
1444 u8 is_nonblocking;
1445 int rv;
Dave Wallace543852a2017-08-03 02:11:34 -04001446
Florin Coras134a9962018-08-28 11:32:04 -07001447 listen_session = vcl_session_get_w_handle (wrk, listen_session_handle);
Florin Coras070453d2018-08-24 17:04:27 -07001448 if (!listen_session)
1449 return VPPCOM_EBADFD;
Dave Wallace543852a2017-08-03 02:11:34 -04001450
Florin Coras134a9962018-08-28 11:32:04 -07001451 listen_session_index = listen_session->session_index;
1452 if ((rv = validate_args_session_accept_ (wrk, listen_session)))
Florin Coras070453d2018-08-24 17:04:27 -07001453 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04001454
Florin Coras54693d22018-07-17 10:46:29 -07001455 if (clib_fifo_elts (listen_session->accept_evts_fifo))
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001456 {
Florin Coras54693d22018-07-17 10:46:29 -07001457 clib_fifo_sub2 (listen_session->accept_evts_fifo, evt);
Florin Coras3c7d4f92018-12-14 11:28:43 -08001458 accept_flags = evt->flags;
Florin Coras54693d22018-07-17 10:46:29 -07001459 accepted_msg = evt->accepted_msg;
1460 goto handle;
1461 }
1462
1463 is_nonblocking = VCL_SESS_ATTR_TEST (listen_session->attr,
1464 VCL_SESS_ATTR_NONBLOCK);
Florin Coras134a9962018-08-28 11:32:04 -07001465 if (svm_msg_q_is_empty (wrk->app_event_queue) && is_nonblocking)
Florin Coras54693d22018-07-17 10:46:29 -07001466 return VPPCOM_EAGAIN;
1467
1468 while (1)
1469 {
Florin Coras134a9962018-08-28 11:32:04 -07001470 if (svm_msg_q_sub (wrk->app_event_queue, &msg, SVM_Q_WAIT, 0))
Florin Coras54693d22018-07-17 10:46:29 -07001471 return VPPCOM_EAGAIN;
1472
Florin Coras134a9962018-08-28 11:32:04 -07001473 e = svm_msg_q_msg_data (wrk->app_event_queue, &msg);
Florin Coras54693d22018-07-17 10:46:29 -07001474 if (e->event_type != SESSION_CTRL_EVT_ACCEPTED)
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001475 {
Florin Coras00cca802019-06-06 09:38:44 -07001476 VDBG (0, "discarded event: %u", e->event_type);
Florin Coras134a9962018-08-28 11:32:04 -07001477 svm_msg_q_free_msg (wrk->app_event_queue, &msg);
Florin Coras54693d22018-07-17 10:46:29 -07001478 continue;
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001479 }
Dave Barach178cf492018-11-13 16:34:13 -05001480 clib_memcpy_fast (&accepted_msg, e->data, sizeof (accepted_msg));
Florin Coras134a9962018-08-28 11:32:04 -07001481 svm_msg_q_free_msg (wrk->app_event_queue, &msg);
Florin Coras54693d22018-07-17 10:46:29 -07001482 break;
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001483 }
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001484
Florin Coras54693d22018-07-17 10:46:29 -07001485handle:
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08001486
Florin Coras00cca802019-06-06 09:38:44 -07001487 client_session_index = vcl_session_accepted_handler (wrk, &accepted_msg,
1488 listen_session_index);
1489 if (client_session_index == VCL_INVALID_SESSION_INDEX)
1490 return VPPCOM_ECONNABORTED;
1491
Florin Coras134a9962018-08-28 11:32:04 -07001492 listen_session = vcl_session_get (wrk, listen_session_index);
1493 client_session = vcl_session_get (wrk, client_session_index);
Dave Wallace543852a2017-08-03 02:11:34 -04001494
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001495 if (flags & O_NONBLOCK)
1496 VCL_SESS_ATTR_SET (client_session->attr, VCL_SESS_ATTR_NONBLOCK);
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001497
Florin Coras5e062572019-03-14 19:07:51 -07001498 VDBG (1, "listener %u [0x%llx]: Got a connect request! session %u [0x%llx],"
1499 " flags %d, is_nonblocking %u", listen_session->session_index,
1500 listen_session->vpp_handle, client_session_index,
1501 client_session->vpp_handle, flags,
1502 VCL_SESS_ATTR_TEST (client_session->attr, VCL_SESS_ATTR_NONBLOCK));
Dave Wallace543852a2017-08-03 02:11:34 -04001503
Dave Wallace048b1d62018-01-03 22:24:41 -05001504 if (ep)
1505 {
Florin Coras7e12d942018-06-27 14:32:43 -07001506 ep->is_ip4 = client_session->transport.is_ip4;
1507 ep->port = client_session->transport.rmt_port;
1508 if (client_session->transport.is_ip4)
Dave Barach178cf492018-11-13 16:34:13 -05001509 clib_memcpy_fast (ep->ip, &client_session->transport.rmt_ip.ip4,
1510 sizeof (ip4_address_t));
Dave Wallace048b1d62018-01-03 22:24:41 -05001511 else
Dave Barach178cf492018-11-13 16:34:13 -05001512 clib_memcpy_fast (ep->ip, &client_session->transport.rmt_ip.ip6,
1513 sizeof (ip6_address_t));
Dave Wallace048b1d62018-01-03 22:24:41 -05001514 }
Dave Wallace60caa062017-11-10 17:07:13 -05001515
Florin Coras05ecfcc2018-12-12 18:19:39 -08001516 VDBG (0, "listener %u [0x%llx] accepted %u [0x%llx] peer: %U:%u "
Florin Coras5e062572019-03-14 19:07:51 -07001517 "local: %U:%u", listen_session_handle, listen_session->vpp_handle,
Florin Coras05ecfcc2018-12-12 18:19:39 -08001518 client_session_index, client_session->vpp_handle,
Florin Coras7e12d942018-06-27 14:32:43 -07001519 format_ip46_address, &client_session->transport.rmt_ip,
Florin Coras54693d22018-07-17 10:46:29 -07001520 client_session->transport.is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6,
Florin Coras7e12d942018-06-27 14:32:43 -07001521 clib_net_to_host_u16 (client_session->transport.rmt_port),
Florin Coras7e12d942018-06-27 14:32:43 -07001522 format_ip46_address, &client_session->transport.lcl_ip,
Florin Coras54693d22018-07-17 10:46:29 -07001523 client_session->transport.is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6,
Florin Coras7e12d942018-06-27 14:32:43 -07001524 clib_net_to_host_u16 (client_session->transport.lcl_port));
Florin Coras0d427d82018-06-27 03:24:07 -07001525 vcl_evt (VCL_EVT_ACCEPT, client_session, listen_session,
1526 client_session_index);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001527
Florin Coras3c7d4f92018-12-14 11:28:43 -08001528 /*
1529 * Session might have been closed already
1530 */
1531 if (accept_flags)
1532 {
Florin Coras3c7d4f92018-12-14 11:28:43 -08001533 if (accept_flags & VCL_ACCEPTED_F_CLOSED)
Florin Corasb0f662f2018-12-27 14:51:46 -08001534 client_session->session_state = STATE_VPP_CLOSING;
Florin Coras3c7d4f92018-12-14 11:28:43 -08001535 else if (accept_flags & VCL_ACCEPTED_F_RESET)
Florin Corasb0f662f2018-12-27 14:51:46 -08001536 client_session->session_state = STATE_DISCONNECT;
Florin Coras3c7d4f92018-12-14 11:28:43 -08001537 }
Florin Corasab2f6db2018-08-31 14:31:41 -07001538 return vcl_session_handle (client_session);
Dave Wallace543852a2017-08-03 02:11:34 -04001539}
1540
Florin Corasef7cbf62019-10-17 09:56:27 -07001541static void
1542vcl_ip_copy_from_ep (ip46_address_t * ip, vppcom_endpt_t * ep)
1543{
1544 if (ep->is_ip4)
1545 clib_memcpy_fast (&ip->ip4, ep->ip, sizeof (ip4_address_t));
1546 else
1547 clib_memcpy_fast (&ip->ip6, ep->ip, sizeof (ip6_address_t));
1548}
1549
1550void
1551vcl_ip_copy_to_ep (ip46_address_t * ip, vppcom_endpt_t * ep, u8 is_ip4)
1552{
1553 ep->is_ip4 = is_ip4;
1554 if (is_ip4)
1555 clib_memcpy_fast (ep->ip, &ip->ip4, sizeof (ip4_address_t));
1556 else
1557 clib_memcpy_fast (ep->ip, &ip->ip6, sizeof (ip6_address_t));
1558}
1559
Dave Wallace543852a2017-08-03 02:11:34 -04001560int
Florin Coras134a9962018-08-28 11:32:04 -07001561vppcom_session_connect (uint32_t session_handle, vppcom_endpt_t * server_ep)
Dave Wallace543852a2017-08-03 02:11:34 -04001562{
Florin Coras134a9962018-08-28 11:32:04 -07001563 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras7e12d942018-06-27 14:32:43 -07001564 vcl_session_t *session = 0;
Florin Coras134a9962018-08-28 11:32:04 -07001565 u32 session_index;
Florin Coras070453d2018-08-24 17:04:27 -07001566 int rv;
Dave Wallace543852a2017-08-03 02:11:34 -04001567
Florin Coras134a9962018-08-28 11:32:04 -07001568 session = vcl_session_get_w_handle (wrk, session_handle);
Florin Coras070453d2018-08-24 17:04:27 -07001569 if (!session)
1570 return VPPCOM_EBADFD;
Florin Coras134a9962018-08-28 11:32:04 -07001571 session_index = session->session_index;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001572
1573 if (PREDICT_FALSE (session->is_vep))
Dave Wallace543852a2017-08-03 02:11:34 -04001574 {
Florin Coras5e062572019-03-14 19:07:51 -07001575 VDBG (0, "ERROR: cannot connect epoll session %u!",
1576 session->session_index);
Florin Coras070453d2018-08-24 17:04:27 -07001577 return VPPCOM_EBADFD;
Dave Wallace543852a2017-08-03 02:11:34 -04001578 }
1579
Florin Coras7e12d942018-06-27 14:32:43 -07001580 if (PREDICT_FALSE (session->session_state & CLIENT_STATE_OPEN))
Dave Wallace543852a2017-08-03 02:11:34 -04001581 {
Florin Coras7baeb712019-01-04 17:05:43 -08001582 VDBG (0, "session handle %u [0x%llx]: session already "
Florin Coras0d427d82018-06-27 03:24:07 -07001583 "connected to %s %U port %d proto %s, state 0x%x (%s)",
Florin Coras7baeb712019-01-04 17:05:43 -08001584 session_handle, session->vpp_handle,
Nathan Skrzypczak9fd99622019-05-16 14:38:44 +02001585 session->transport.is_ip4 ? "IPv4" : "IPv6", format_ip46_address,
Florin Coras7e12d942018-06-27 14:32:43 -07001586 &session->transport.rmt_ip, session->transport.is_ip4 ?
Florin Coras0d427d82018-06-27 03:24:07 -07001587 IP46_TYPE_IP4 : IP46_TYPE_IP6,
Florin Coras7e12d942018-06-27 14:32:43 -07001588 clib_net_to_host_u16 (session->transport.rmt_port),
Ping Yu34a3a082018-11-30 19:16:17 -05001589 vppcom_proto_str (session->session_type), session->session_state,
Florin Coras7e12d942018-06-27 14:32:43 -07001590 vppcom_session_state_str (session->session_state));
Florin Coras070453d2018-08-24 17:04:27 -07001591 return VPPCOM_OK;
Dave Wallace543852a2017-08-03 02:11:34 -04001592 }
1593
Florin Coras7e12d942018-06-27 14:32:43 -07001594 session->transport.is_ip4 = server_ep->is_ip4;
Florin Corasef7cbf62019-10-17 09:56:27 -07001595 vcl_ip_copy_from_ep (&session->transport.rmt_ip, server_ep);
Florin Coras7e12d942018-06-27 14:32:43 -07001596 session->transport.rmt_port = server_ep->port;
Nathan Skrzypczak8ac1d6d2019-07-17 11:02:20 +02001597 session->parent_handle = VCL_INVALID_SESSION_HANDLE;
Dave Wallace543852a2017-08-03 02:11:34 -04001598
Nathan Skrzypczak9fd99622019-05-16 14:38:44 +02001599 VDBG (0, "session handle %u: connecting to server %s %U "
1600 "port %d proto %s", session_handle,
Florin Coras7e12d942018-06-27 14:32:43 -07001601 session->transport.is_ip4 ? "IPv4" : "IPv6",
Florin Coras0d427d82018-06-27 03:24:07 -07001602 format_ip46_address,
Florin Coras7e12d942018-06-27 14:32:43 -07001603 &session->transport.rmt_ip, session->transport.is_ip4 ?
Florin Coras0d427d82018-06-27 03:24:07 -07001604 IP46_TYPE_IP4 : IP46_TYPE_IP6,
Florin Coras7e12d942018-06-27 14:32:43 -07001605 clib_net_to_host_u16 (session->transport.rmt_port),
Ping Yu34a3a082018-11-30 19:16:17 -05001606 vppcom_proto_str (session->session_type));
Dave Wallace543852a2017-08-03 02:11:34 -04001607
Florin Coras458089b2019-08-21 16:20:44 -07001608 vcl_send_session_connect (wrk, session);
Florin Coras57c88932019-08-29 12:03:17 -07001609
1610 if (VCL_SESS_ATTR_TEST (session->attr, VCL_SESS_ATTR_NONBLOCK))
1611 return VPPCOM_EINPROGRESS;
1612
1613 /*
1614 * Wait for reply from vpp if blocking
1615 */
Florin Coras070453d2018-08-24 17:04:27 -07001616 rv = vppcom_wait_for_session_state_change (session_index, STATE_CONNECT,
1617 vcm->cfg.session_timeout);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001618
Florin Coras134a9962018-08-28 11:32:04 -07001619 session = vcl_session_get (wrk, session_index);
Florin Coras5e062572019-03-14 19:07:51 -07001620 VDBG (0, "session %u [0x%llx]: connect %s!", session->session_index,
1621 session->vpp_handle, rv ? "failed" : "succeeded");
Dave Wallaceee45d412017-11-24 21:44:06 -05001622
Dave Wallace4878cbe2017-11-21 03:45:09 -05001623 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04001624}
1625
Nathan Skrzypczak9fd99622019-05-16 14:38:44 +02001626int
1627vppcom_session_stream_connect (uint32_t session_handle,
1628 uint32_t parent_session_handle)
1629{
1630 vcl_worker_t *wrk = vcl_worker_get_current ();
1631 vcl_session_t *session, *parent_session;
1632 u32 session_index, parent_session_index;
1633 int rv;
1634
1635 session = vcl_session_get_w_handle (wrk, session_handle);
1636 if (!session)
1637 return VPPCOM_EBADFD;
1638 parent_session = vcl_session_get_w_handle (wrk, parent_session_handle);
1639 if (!parent_session)
1640 return VPPCOM_EBADFD;
1641
1642 session_index = session->session_index;
1643 parent_session_index = parent_session->session_index;
1644 if (PREDICT_FALSE (session->is_vep))
1645 {
1646 VDBG (0, "ERROR: cannot connect epoll session %u!",
1647 session->session_index);
1648 return VPPCOM_EBADFD;
1649 }
1650
1651 if (PREDICT_FALSE (session->session_state & CLIENT_STATE_OPEN))
1652 {
1653 VDBG (0, "session handle %u [0x%llx]: session already "
1654 "connected to session %u [0x%llx] proto %s, state 0x%x (%s)",
1655 session_handle, session->vpp_handle,
1656 parent_session_handle, parent_session->vpp_handle,
1657 vppcom_proto_str (session->session_type), session->session_state,
1658 vppcom_session_state_str (session->session_state));
1659 return VPPCOM_OK;
1660 }
1661
1662 /* Connect to quic session specifics */
1663 session->transport.is_ip4 = parent_session->transport.is_ip4;
1664 session->transport.rmt_ip.ip4.as_u32 = (uint32_t) 1;
1665 session->transport.rmt_port = 0;
Nathan Skrzypczak8ac1d6d2019-07-17 11:02:20 +02001666 session->parent_handle = parent_session->vpp_handle;
Nathan Skrzypczak9fd99622019-05-16 14:38:44 +02001667
1668 VDBG (0, "session handle %u: connecting to session %u [0x%llx]",
1669 session_handle, parent_session_handle, parent_session->vpp_handle);
1670
1671 /*
1672 * Send connect request and wait for reply from vpp
1673 */
Florin Coras458089b2019-08-21 16:20:44 -07001674 vcl_send_session_connect (wrk, session);
Nathan Skrzypczak9fd99622019-05-16 14:38:44 +02001675 rv = vppcom_wait_for_session_state_change (session_index, STATE_CONNECT,
1676 vcm->cfg.session_timeout);
1677
1678 session->listener_index = parent_session_index;
1679 parent_session = vcl_session_get_w_handle (wrk, parent_session_handle);
Florin Coras028eaf02019-07-19 12:15:52 -07001680 if (parent_session)
1681 parent_session->n_accepted_sessions++;
Nathan Skrzypczak9fd99622019-05-16 14:38:44 +02001682
1683 session = vcl_session_get (wrk, session_index);
1684 VDBG (0, "session %u [0x%llx]: connect %s!", session->session_index,
1685 session->vpp_handle, rv ? "failed" : "succeeded");
1686
1687 return rv;
1688}
1689
Florin Coras54693d22018-07-17 10:46:29 -07001690static u8
1691vcl_is_rx_evt_for_session (session_event_t * e, u32 sid, u8 is_ct)
1692{
Florin Corasc0737e92019-03-04 14:19:39 -08001693 return (e->event_type == SESSION_IO_EVT_RX && e->session_index == sid);
Florin Coras54693d22018-07-17 10:46:29 -07001694}
1695
Steven58f464e2017-10-25 12:33:12 -07001696static inline int
Florin Coras134a9962018-08-28 11:32:04 -07001697vppcom_session_read_internal (uint32_t session_handle, void *buf, int n,
Steven58f464e2017-10-25 12:33:12 -07001698 u8 peek)
Dave Wallace543852a2017-08-03 02:11:34 -04001699{
Florin Coras134a9962018-08-28 11:32:04 -07001700 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras6d0106e2019-01-29 20:11:58 -08001701 int n_read = 0, is_nonblocking;
Florin Coras460dce62018-07-27 05:45:06 -07001702 vcl_session_t *s = 0;
Dave Wallace543852a2017-08-03 02:11:34 -04001703 svm_fifo_t *rx_fifo;
Florin Coras54693d22018-07-17 10:46:29 -07001704 svm_msg_q_msg_t msg;
1705 session_event_t *e;
1706 svm_msg_q_t *mq;
Florin Coras41c9e042018-09-11 00:10:41 -07001707 u8 is_ct;
Dave Wallace543852a2017-08-03 02:11:34 -04001708
Florin Coras070453d2018-08-24 17:04:27 -07001709 if (PREDICT_FALSE (!buf))
1710 return VPPCOM_EINVAL;
Dave Wallace543852a2017-08-03 02:11:34 -04001711
Florin Coras134a9962018-08-28 11:32:04 -07001712 s = vcl_session_get_w_handle (wrk, session_handle);
Florin Coras2cba8532018-09-11 16:33:36 -07001713 if (PREDICT_FALSE (!s || s->is_vep))
Florin Coras070453d2018-08-24 17:04:27 -07001714 return VPPCOM_EBADFD;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001715
Florin Coras6d0106e2019-01-29 20:11:58 -08001716 if (PREDICT_FALSE (!vcl_session_is_open (s)))
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001717 {
Florin Coras5e062572019-03-14 19:07:51 -07001718 VDBG (0, "session %u[0x%llx] is not open! state 0x%x (%s)",
Florin Coras6d0106e2019-01-29 20:11:58 -08001719 s->session_index, s->vpp_handle, s->session_state,
1720 vppcom_session_state_str (s->session_state));
1721 return vcl_session_closed_error (s);
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001722 }
1723
Florin Coras2cba8532018-09-11 16:33:36 -07001724 is_nonblocking = VCL_SESS_ATTR_TEST (s->attr, VCL_SESS_ATTR_NONBLOCK);
Florin Coras41c9e042018-09-11 00:10:41 -07001725 is_ct = vcl_session_is_ct (s);
Florin Coras653e43f2019-03-04 10:56:23 -08001726 mq = wrk->app_event_queue;
1727 rx_fifo = is_ct ? s->ct_rx_fifo : s->rx_fifo;
Florin Corasaa27eb92018-10-13 12:20:01 -07001728 s->has_rx_evt = 0;
Dave Wallacef7f809c2017-10-03 01:48:42 -04001729
Sirshak Das28aa5392019-02-05 01:33:33 -06001730 if (svm_fifo_is_empty_cons (rx_fifo))
Dave Wallacef7f809c2017-10-03 01:48:42 -04001731 {
Florin Coras54693d22018-07-17 10:46:29 -07001732 if (is_nonblocking)
Florin Corasc0737e92019-03-04 14:19:39 -08001733 {
1734 svm_fifo_unset_event (s->rx_fifo);
1735 return VPPCOM_EWOULDBLOCK;
1736 }
Sirshak Das28aa5392019-02-05 01:33:33 -06001737 while (svm_fifo_is_empty_cons (rx_fifo))
Florin Coras54693d22018-07-17 10:46:29 -07001738 {
Florin Coras6d0106e2019-01-29 20:11:58 -08001739 if (vcl_session_is_closing (s))
1740 return vcl_session_closing_error (s);
1741
Florin Corasc0737e92019-03-04 14:19:39 -08001742 svm_fifo_unset_event (s->rx_fifo);
Florin Coras99368312018-08-02 10:45:44 -07001743 svm_msg_q_lock (mq);
Florin Coras54693d22018-07-17 10:46:29 -07001744 if (svm_msg_q_is_empty (mq))
1745 svm_msg_q_wait (mq);
Florin Coras99368312018-08-02 10:45:44 -07001746
Florin Coras54693d22018-07-17 10:46:29 -07001747 svm_msg_q_sub_w_lock (mq, &msg);
1748 e = svm_msg_q_msg_data (mq, &msg);
Florin Coras99368312018-08-02 10:45:44 -07001749 svm_msg_q_unlock (mq);
Florin Coras41c9e042018-09-11 00:10:41 -07001750 if (!vcl_is_rx_evt_for_session (e, s->session_index, is_ct))
Florin Corasc0737e92019-03-04 14:19:39 -08001751 vcl_handle_mq_event (wrk, e);
Florin Coras54693d22018-07-17 10:46:29 -07001752 svm_msg_q_free_msg (mq, &msg);
Florin Coras54693d22018-07-17 10:46:29 -07001753 }
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001754 }
Florin Coras54693d22018-07-17 10:46:29 -07001755
Florin Coras460dce62018-07-27 05:45:06 -07001756 if (s->is_dgram)
Florin Coras99368312018-08-02 10:45:44 -07001757 n_read = app_recv_dgram_raw (rx_fifo, buf, n, &s->transport, 0, peek);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001758 else
Florin Coras99368312018-08-02 10:45:44 -07001759 n_read = app_recv_stream_raw (rx_fifo, buf, n, 0, peek);
Florin Coras54693d22018-07-17 10:46:29 -07001760
Sirshak Das28aa5392019-02-05 01:33:33 -06001761 if (svm_fifo_is_empty_cons (rx_fifo))
Florin Corasc0737e92019-03-04 14:19:39 -08001762 svm_fifo_unset_event (s->rx_fifo);
Florin Coras41c9e042018-09-11 00:10:41 -07001763
Florin Coras317b8e02019-04-17 09:57:46 -07001764 /* Cut-through sessions might request tx notifications on rx fifos */
Florin Coras2d379d82019-06-28 12:45:12 -07001765 if (PREDICT_FALSE (rx_fifo->want_deq_ntf))
Florin Coras317b8e02019-04-17 09:57:46 -07001766 {
1767 app_send_io_evt_to_vpp (s->vpp_evt_q, s->rx_fifo->master_session_index,
1768 SESSION_IO_EVT_RX, SVM_Q_WAIT);
Florin Coras2d379d82019-06-28 12:45:12 -07001769 svm_fifo_reset_has_deq_ntf (s->rx_fifo);
Florin Coras317b8e02019-04-17 09:57:46 -07001770 }
1771
Florin Coras5e062572019-03-14 19:07:51 -07001772 VDBG (2, "session %u[0x%llx]: read %d bytes from (%p)", s->session_index,
1773 s->vpp_handle, n_read, rx_fifo);
Florin Coras2cba8532018-09-11 16:33:36 -07001774
Florin Coras54693d22018-07-17 10:46:29 -07001775 return n_read;
Dave Wallace543852a2017-08-03 02:11:34 -04001776}
1777
Steven58f464e2017-10-25 12:33:12 -07001778int
Florin Coras134a9962018-08-28 11:32:04 -07001779vppcom_session_read (uint32_t session_handle, void *buf, size_t n)
Steven58f464e2017-10-25 12:33:12 -07001780{
Florin Coras134a9962018-08-28 11:32:04 -07001781 return (vppcom_session_read_internal (session_handle, buf, n, 0));
Steven58f464e2017-10-25 12:33:12 -07001782}
1783
1784static int
Florin Coras134a9962018-08-28 11:32:04 -07001785vppcom_session_peek (uint32_t session_handle, void *buf, int n)
Steven58f464e2017-10-25 12:33:12 -07001786{
Florin Coras134a9962018-08-28 11:32:04 -07001787 return (vppcom_session_read_internal (session_handle, buf, n, 1));
Steven58f464e2017-10-25 12:33:12 -07001788}
1789
Florin Coras2cba8532018-09-11 16:33:36 -07001790int
1791vppcom_session_read_segments (uint32_t session_handle,
1792 vppcom_data_segments_t ds)
1793{
1794 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras6d0106e2019-01-29 20:11:58 -08001795 int n_read = 0, is_nonblocking;
Florin Coras2cba8532018-09-11 16:33:36 -07001796 vcl_session_t *s = 0;
1797 svm_fifo_t *rx_fifo;
1798 svm_msg_q_msg_t msg;
1799 session_event_t *e;
1800 svm_msg_q_t *mq;
1801 u8 is_ct;
1802
1803 s = vcl_session_get_w_handle (wrk, session_handle);
1804 if (PREDICT_FALSE (!s || s->is_vep))
1805 return VPPCOM_EBADFD;
1806
Florin Coras6d0106e2019-01-29 20:11:58 -08001807 if (PREDICT_FALSE (!vcl_session_is_open (s)))
1808 return vcl_session_closed_error (s);
Florin Coras2cba8532018-09-11 16:33:36 -07001809
1810 is_nonblocking = VCL_SESS_ATTR_TEST (s->attr, VCL_SESS_ATTR_NONBLOCK);
1811 is_ct = vcl_session_is_ct (s);
1812 mq = is_ct ? s->our_evt_q : wrk->app_event_queue;
1813 rx_fifo = s->rx_fifo;
Florin Corasaa27eb92018-10-13 12:20:01 -07001814 s->has_rx_evt = 0;
Florin Coras2cba8532018-09-11 16:33:36 -07001815
Florin Coras653e43f2019-03-04 10:56:23 -08001816 if (is_ct)
1817 svm_fifo_unset_event (s->rx_fifo);
1818
Sirshak Das28aa5392019-02-05 01:33:33 -06001819 if (svm_fifo_is_empty_cons (rx_fifo))
Florin Coras2cba8532018-09-11 16:33:36 -07001820 {
1821 if (is_nonblocking)
1822 {
1823 svm_fifo_unset_event (rx_fifo);
Florin Corasaa27eb92018-10-13 12:20:01 -07001824 return VPPCOM_EWOULDBLOCK;
Florin Coras2cba8532018-09-11 16:33:36 -07001825 }
Sirshak Das28aa5392019-02-05 01:33:33 -06001826 while (svm_fifo_is_empty_cons (rx_fifo))
Florin Coras2cba8532018-09-11 16:33:36 -07001827 {
Florin Coras6d0106e2019-01-29 20:11:58 -08001828 if (vcl_session_is_closing (s))
1829 return vcl_session_closing_error (s);
1830
Florin Coras2cba8532018-09-11 16:33:36 -07001831 svm_fifo_unset_event (rx_fifo);
1832 svm_msg_q_lock (mq);
1833 if (svm_msg_q_is_empty (mq))
1834 svm_msg_q_wait (mq);
1835
1836 svm_msg_q_sub_w_lock (mq, &msg);
1837 e = svm_msg_q_msg_data (mq, &msg);
1838 svm_msg_q_unlock (mq);
1839 if (!vcl_is_rx_evt_for_session (e, s->session_index, is_ct))
Florin Coras05ce4b82018-12-15 18:30:43 -08001840 vcl_handle_mq_event (wrk, e);
Florin Coras2cba8532018-09-11 16:33:36 -07001841 svm_msg_q_free_msg (mq, &msg);
Florin Coras2cba8532018-09-11 16:33:36 -07001842 }
1843 }
1844
Florin Coras88001c62019-04-24 14:44:46 -07001845 n_read = svm_fifo_segments (rx_fifo, (svm_fifo_seg_t *) ds);
Florin Coras2cba8532018-09-11 16:33:36 -07001846 svm_fifo_unset_event (rx_fifo);
1847
Florin Coras2cba8532018-09-11 16:33:36 -07001848 return n_read;
1849}
1850
1851void
1852vppcom_session_free_segments (uint32_t session_handle,
1853 vppcom_data_segments_t ds)
1854{
1855 vcl_worker_t *wrk = vcl_worker_get_current ();
1856 vcl_session_t *s;
1857
1858 s = vcl_session_get_w_handle (wrk, session_handle);
1859 if (PREDICT_FALSE (!s || s->is_vep))
1860 return;
1861
Florin Coras88001c62019-04-24 14:44:46 -07001862 svm_fifo_segments_free (s->rx_fifo, (svm_fifo_seg_t *) ds);
Florin Coras2cba8532018-09-11 16:33:36 -07001863}
1864
Florin Coras2cba8532018-09-11 16:33:36 -07001865int
1866vppcom_data_segment_copy (void *buf, vppcom_data_segments_t ds, u32 max_bytes)
1867{
1868 u32 first_copy = clib_min (ds[0].len, max_bytes);
Dave Barach178cf492018-11-13 16:34:13 -05001869 clib_memcpy_fast (buf, ds[0].data, first_copy);
Florin Coras2cba8532018-09-11 16:33:36 -07001870 if (first_copy < max_bytes)
1871 {
Dave Barach178cf492018-11-13 16:34:13 -05001872 clib_memcpy_fast (buf + first_copy, ds[1].data,
1873 clib_min (ds[1].len, max_bytes - first_copy));
Florin Coras2cba8532018-09-11 16:33:36 -07001874 }
1875 return 0;
1876}
1877
Florin Coras54693d22018-07-17 10:46:29 -07001878static u8
1879vcl_is_tx_evt_for_session (session_event_t * e, u32 sid, u8 is_ct)
1880{
Florin Corasc0737e92019-03-04 14:19:39 -08001881 return (e->event_type == SESSION_IO_EVT_TX && e->session_index == sid);
Dave Wallace543852a2017-08-03 02:11:34 -04001882}
1883
Florin Coras42ceddb2018-12-12 10:56:01 -08001884static inline int
1885vppcom_session_write_inline (uint32_t session_handle, void *buf, size_t n,
1886 u8 is_flush)
Dave Wallace543852a2017-08-03 02:11:34 -04001887{
Florin Coras134a9962018-08-28 11:32:04 -07001888 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras6d0106e2019-01-29 20:11:58 -08001889 int n_write, is_nonblocking;
Florin Coras460dce62018-07-27 05:45:06 -07001890 vcl_session_t *s = 0;
Florin Coras460dce62018-07-27 05:45:06 -07001891 session_evt_type_t et;
Florin Coras54693d22018-07-17 10:46:29 -07001892 svm_msg_q_msg_t msg;
Florin Coras14ed6df2019-03-06 21:13:42 -08001893 svm_fifo_t *tx_fifo;
Florin Coras54693d22018-07-17 10:46:29 -07001894 session_event_t *e;
Florin Coras3c2fed52018-07-04 04:15:05 -07001895 svm_msg_q_t *mq;
Florin Coras0e88e852018-09-17 22:09:02 -07001896 u8 is_ct;
Dave Wallace543852a2017-08-03 02:11:34 -04001897
Florin Coras070453d2018-08-24 17:04:27 -07001898 if (PREDICT_FALSE (!buf))
1899 return VPPCOM_EINVAL;
Dave Wallace543852a2017-08-03 02:11:34 -04001900
Florin Coras134a9962018-08-28 11:32:04 -07001901 s = vcl_session_get_w_handle (wrk, session_handle);
Florin Coras070453d2018-08-24 17:04:27 -07001902 if (PREDICT_FALSE (!s))
1903 return VPPCOM_EBADFD;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001904
Florin Coras460dce62018-07-27 05:45:06 -07001905 if (PREDICT_FALSE (s->is_vep))
Dave Wallace543852a2017-08-03 02:11:34 -04001906 {
Florin Coras6d0106e2019-01-29 20:11:58 -08001907 VDBG (0, "ERROR: session %u [0x%llx]: cannot write to an epoll"
1908 " session!", s->session_index, s->vpp_handle);
Florin Coras070453d2018-08-24 17:04:27 -07001909 return VPPCOM_EBADFD;
Dave Wallace543852a2017-08-03 02:11:34 -04001910 }
1911
Florin Coras6d0106e2019-01-29 20:11:58 -08001912 if (PREDICT_FALSE (!vcl_session_is_open (s)))
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001913 {
Florin Coras6d0106e2019-01-29 20:11:58 -08001914 VDBG (1, "session %u [0x%llx]: is not open! state 0x%x (%s)",
1915 s->session_index, s->vpp_handle, s->session_state,
1916 vppcom_session_state_str (s->session_state));
1917 return vcl_session_closed_error (s);;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001918 }
1919
Florin Coras0e88e852018-09-17 22:09:02 -07001920 is_ct = vcl_session_is_ct (s);
Florin Coras653e43f2019-03-04 10:56:23 -08001921 tx_fifo = is_ct ? s->ct_tx_fifo : s->tx_fifo;
Florin Coras0e88e852018-09-17 22:09:02 -07001922 is_nonblocking = VCL_SESS_ATTR_TEST (s->attr, VCL_SESS_ATTR_NONBLOCK);
Sirshak Das28aa5392019-02-05 01:33:33 -06001923
Florin Coras653e43f2019-03-04 10:56:23 -08001924 mq = wrk->app_event_queue;
Sirshak Das28aa5392019-02-05 01:33:33 -06001925 if (svm_fifo_is_full_prod (tx_fifo))
Dave Wallace543852a2017-08-03 02:11:34 -04001926 {
Florin Coras54693d22018-07-17 10:46:29 -07001927 if (is_nonblocking)
1928 {
Florin Coras070453d2018-08-24 17:04:27 -07001929 return VPPCOM_EWOULDBLOCK;
Florin Coras54693d22018-07-17 10:46:29 -07001930 }
Sirshak Das28aa5392019-02-05 01:33:33 -06001931 while (svm_fifo_is_full_prod (tx_fifo))
Florin Coras54693d22018-07-17 10:46:29 -07001932 {
Florin Coras2d379d82019-06-28 12:45:12 -07001933 svm_fifo_add_want_deq_ntf (tx_fifo, SVM_FIFO_WANT_DEQ_NOTIF);
Florin Coras6d0106e2019-01-29 20:11:58 -08001934 if (vcl_session_is_closing (s))
1935 return vcl_session_closing_error (s);
Florin Coras99368312018-08-02 10:45:44 -07001936 svm_msg_q_lock (mq);
Florin Corasaa27eb92018-10-13 12:20:01 -07001937 if (svm_msg_q_is_empty (mq))
1938 svm_msg_q_wait (mq);
Florin Coras0e88e852018-09-17 22:09:02 -07001939
Florin Coras54693d22018-07-17 10:46:29 -07001940 svm_msg_q_sub_w_lock (mq, &msg);
1941 e = svm_msg_q_msg_data (mq, &msg);
Florin Coras99368312018-08-02 10:45:44 -07001942 svm_msg_q_unlock (mq);
1943
Florin Coras0e88e852018-09-17 22:09:02 -07001944 if (!vcl_is_tx_evt_for_session (e, s->session_index, is_ct))
Florin Coras86f04502018-09-12 16:08:01 -07001945 vcl_handle_mq_event (wrk, e);
Florin Coras54693d22018-07-17 10:46:29 -07001946 svm_msg_q_free_msg (mq, &msg);
Florin Coras54693d22018-07-17 10:46:29 -07001947 }
Dave Wallace543852a2017-08-03 02:11:34 -04001948 }
Dave Wallace543852a2017-08-03 02:11:34 -04001949
Florin Coras653e43f2019-03-04 10:56:23 -08001950 et = SESSION_IO_EVT_TX;
1951 if (is_flush && !is_ct)
Florin Coras42ceddb2018-12-12 10:56:01 -08001952 et = SESSION_IO_EVT_TX_FLUSH;
1953
Florin Coras460dce62018-07-27 05:45:06 -07001954 if (s->is_dgram)
1955 n_write = app_send_dgram_raw (tx_fifo, &s->transport,
Florin Coras653e43f2019-03-04 10:56:23 -08001956 s->vpp_evt_q, buf, n, et,
Florin Coras14ed6df2019-03-06 21:13:42 -08001957 0 /* do_evt */ , SVM_Q_WAIT);
Florin Coras460dce62018-07-27 05:45:06 -07001958 else
1959 n_write = app_send_stream_raw (tx_fifo, s->vpp_evt_q, buf, n, et,
Florin Coras14ed6df2019-03-06 21:13:42 -08001960 0 /* do_evt */ , SVM_Q_WAIT);
Florin Coras653e43f2019-03-04 10:56:23 -08001961
Florin Coras14ed6df2019-03-06 21:13:42 -08001962 if (svm_fifo_set_event (s->tx_fifo))
Florin Corasc0737e92019-03-04 14:19:39 -08001963 app_send_io_evt_to_vpp (s->vpp_evt_q, s->tx_fifo->master_session_index,
1964 et, SVM_Q_WAIT);
Keith Burns (alagalah)410bcca2018-03-23 13:42:49 -07001965
Florin Coras460dce62018-07-27 05:45:06 -07001966 ASSERT (n_write > 0);
Dave Wallace543852a2017-08-03 02:11:34 -04001967
Florin Coras6d0106e2019-01-29 20:11:58 -08001968 VDBG (2, "session %u [0x%llx]: wrote %d bytes", s->session_index,
1969 s->vpp_handle, n_write);
Florin Coras0e88e852018-09-17 22:09:02 -07001970
Florin Coras54693d22018-07-17 10:46:29 -07001971 return n_write;
Dave Wallace543852a2017-08-03 02:11:34 -04001972}
1973
Florin Coras42ceddb2018-12-12 10:56:01 -08001974int
1975vppcom_session_write (uint32_t session_handle, void *buf, size_t n)
1976{
1977 return vppcom_session_write_inline (session_handle, buf, n,
1978 0 /* is_flush */ );
1979}
1980
Florin Corasb0f662f2018-12-27 14:51:46 -08001981int
1982vppcom_session_write_msg (uint32_t session_handle, void *buf, size_t n)
1983{
1984 return vppcom_session_write_inline (session_handle, buf, n,
1985 1 /* is_flush */ );
1986}
1987
Florin Corasc0737e92019-03-04 14:19:39 -08001988#define vcl_fifo_rx_evt_valid_or_break(_s) \
1989if (PREDICT_FALSE (svm_fifo_is_empty (_s->rx_fifo))) \
1990 { \
1991 if (!vcl_session_is_ct (_s)) \
1992 { \
1993 svm_fifo_unset_event (_s->rx_fifo); \
1994 if (svm_fifo_is_empty (_s->rx_fifo)) \
1995 break; \
1996 } \
1997 else if (svm_fifo_is_empty (_s->ct_rx_fifo)) \
1998 { \
1999 svm_fifo_unset_event (_s->ct_rx_fifo); \
2000 if (svm_fifo_is_empty (_s->ct_rx_fifo)) \
2001 break; \
2002 } \
2003 } \
Florin Coras6d4bb422018-09-04 22:07:27 -07002004
Florin Coras86f04502018-09-12 16:08:01 -07002005static void
2006vcl_select_handle_mq_event (vcl_worker_t * wrk, session_event_t * e,
2007 unsigned long n_bits, unsigned long *read_map,
2008 unsigned long *write_map,
2009 unsigned long *except_map, u32 * bits_set)
Florin Coras54693d22018-07-17 10:46:29 -07002010{
2011 session_disconnected_msg_t *disconnected_msg;
Florin Coras99368312018-08-02 10:45:44 -07002012 session_connected_msg_t *connected_msg;
Florin Coras54693d22018-07-17 10:46:29 -07002013 vcl_session_t *session;
Florin Coras86f04502018-09-12 16:08:01 -07002014 u32 sid;
2015
2016 switch (e->event_type)
2017 {
Florin Corasc0737e92019-03-04 14:19:39 -08002018 case SESSION_IO_EVT_RX:
2019 sid = e->session_index;
Florin Coras86f04502018-09-12 16:08:01 -07002020 session = vcl_session_get (wrk, sid);
2021 if (!session)
2022 break;
Florin Corasfff68f72019-03-13 16:01:38 -07002023 vcl_fifo_rx_evt_valid_or_break (session);
Florin Coras86f04502018-09-12 16:08:01 -07002024 if (sid < n_bits && read_map)
2025 {
David Johnsond9818dd2018-12-14 14:53:41 -05002026 clib_bitmap_set_no_check ((uword *) read_map, sid, 1);
Florin Coras86f04502018-09-12 16:08:01 -07002027 *bits_set += 1;
2028 }
2029 break;
Florin Corasfe97da32019-03-06 10:09:04 -08002030 case SESSION_IO_EVT_TX:
Florin Corasc0737e92019-03-04 14:19:39 -08002031 sid = e->session_index;
Florin Coras86f04502018-09-12 16:08:01 -07002032 session = vcl_session_get (wrk, sid);
2033 if (!session)
2034 break;
2035 if (sid < n_bits && write_map)
2036 {
David Johnsond9818dd2018-12-14 14:53:41 -05002037 clib_bitmap_set_no_check ((uword *) write_map, sid, 1);
Florin Coras86f04502018-09-12 16:08:01 -07002038 *bits_set += 1;
2039 }
2040 break;
Florin Coras86f04502018-09-12 16:08:01 -07002041 case SESSION_CTRL_EVT_ACCEPTED:
Florin Coras3c7d4f92018-12-14 11:28:43 -08002042 session = vcl_session_accepted (wrk,
2043 (session_accepted_msg_t *) e->data);
Florin Coras86f04502018-09-12 16:08:01 -07002044 if (!session)
Florin Coras3c7d4f92018-12-14 11:28:43 -08002045 break;
Florin Coras86f04502018-09-12 16:08:01 -07002046 sid = session->session_index;
2047 if (sid < n_bits && read_map)
2048 {
David Johnsond9818dd2018-12-14 14:53:41 -05002049 clib_bitmap_set_no_check ((uword *) read_map, sid, 1);
Florin Coras86f04502018-09-12 16:08:01 -07002050 *bits_set += 1;
2051 }
2052 break;
2053 case SESSION_CTRL_EVT_CONNECTED:
2054 connected_msg = (session_connected_msg_t *) e->data;
Florin Coras57c88932019-08-29 12:03:17 -07002055 sid = vcl_session_connected_handler (wrk, connected_msg);
2056 if (sid == VCL_INVALID_SESSION_INDEX)
2057 break;
2058 if (sid < n_bits && write_map)
2059 {
2060 clib_bitmap_set_no_check ((uword *) write_map, sid, 1);
2061 *bits_set += 1;
2062 }
Florin Coras86f04502018-09-12 16:08:01 -07002063 break;
2064 case SESSION_CTRL_EVT_DISCONNECTED:
2065 disconnected_msg = (session_disconnected_msg_t *) e->data;
Florin Coras3c7d4f92018-12-14 11:28:43 -08002066 session = vcl_session_disconnected_handler (wrk, disconnected_msg);
2067 if (!session)
2068 break;
2069 sid = session->session_index;
Florin Coras86f04502018-09-12 16:08:01 -07002070 if (sid < n_bits && except_map)
2071 {
David Johnsond9818dd2018-12-14 14:53:41 -05002072 clib_bitmap_set_no_check ((uword *) except_map, sid, 1);
Florin Coras86f04502018-09-12 16:08:01 -07002073 *bits_set += 1;
2074 }
2075 break;
2076 case SESSION_CTRL_EVT_RESET:
2077 sid = vcl_session_reset_handler (wrk, (session_reset_msg_t *) e->data);
2078 if (sid < n_bits && except_map)
2079 {
David Johnsond9818dd2018-12-14 14:53:41 -05002080 clib_bitmap_set_no_check ((uword *) except_map, sid, 1);
Florin Coras86f04502018-09-12 16:08:01 -07002081 *bits_set += 1;
2082 }
2083 break;
Florin Corasdfae9f92019-02-20 19:48:31 -08002084 case SESSION_CTRL_EVT_UNLISTEN_REPLY:
2085 vcl_session_unlisten_reply_handler (wrk, e->data);
2086 break;
Florin Coras30e79c22019-01-02 19:31:22 -08002087 case SESSION_CTRL_EVT_WORKER_UPDATE_REPLY:
2088 vcl_session_worker_update_reply_handler (wrk, e->data);
2089 break;
2090 case SESSION_CTRL_EVT_REQ_WORKER_UPDATE:
2091 vcl_session_req_worker_update_handler (wrk, e->data);
2092 break;
Florin Coras86f04502018-09-12 16:08:01 -07002093 default:
2094 clib_warning ("unhandled: %u", e->event_type);
2095 break;
2096 }
2097}
2098
2099static int
2100vcl_select_handle_mq (vcl_worker_t * wrk, svm_msg_q_t * mq,
2101 unsigned long n_bits, unsigned long *read_map,
2102 unsigned long *write_map, unsigned long *except_map,
2103 double time_to_wait, u32 * bits_set)
2104{
Florin Coras99368312018-08-02 10:45:44 -07002105 svm_msg_q_msg_t *msg;
Florin Coras54693d22018-07-17 10:46:29 -07002106 session_event_t *e;
Florin Coras86f04502018-09-12 16:08:01 -07002107 u32 i;
Florin Coras54693d22018-07-17 10:46:29 -07002108
2109 svm_msg_q_lock (mq);
2110 if (svm_msg_q_is_empty (mq))
Dave Wallace4878cbe2017-11-21 03:45:09 -05002111 {
Florin Coras54693d22018-07-17 10:46:29 -07002112 if (*bits_set)
Dave Wallace4878cbe2017-11-21 03:45:09 -05002113 {
Florin Coras54693d22018-07-17 10:46:29 -07002114 svm_msg_q_unlock (mq);
2115 return 0;
2116 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05002117
Florin Coras54693d22018-07-17 10:46:29 -07002118 if (!time_to_wait)
2119 {
2120 svm_msg_q_unlock (mq);
2121 return 0;
2122 }
2123 else if (time_to_wait < 0)
2124 {
2125 svm_msg_q_wait (mq);
2126 }
2127 else
2128 {
2129 if (svm_msg_q_timedwait (mq, time_to_wait))
2130 {
2131 svm_msg_q_unlock (mq);
2132 return 0;
2133 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05002134 }
2135 }
Florin Corase003a1b2019-06-05 10:47:16 -07002136 vcl_mq_dequeue_batch (wrk, mq, ~0);
Florin Coras54693d22018-07-17 10:46:29 -07002137 svm_msg_q_unlock (mq);
2138
Florin Coras134a9962018-08-28 11:32:04 -07002139 for (i = 0; i < vec_len (wrk->mq_msg_vector); i++)
Florin Coras54693d22018-07-17 10:46:29 -07002140 {
Florin Coras134a9962018-08-28 11:32:04 -07002141 msg = vec_elt_at_index (wrk->mq_msg_vector, i);
Florin Coras99368312018-08-02 10:45:44 -07002142 e = svm_msg_q_msg_data (mq, msg);
Florin Coras86f04502018-09-12 16:08:01 -07002143 vcl_select_handle_mq_event (wrk, e, n_bits, read_map, write_map,
2144 except_map, bits_set);
Florin Coras99368312018-08-02 10:45:44 -07002145 svm_msg_q_free_msg (mq, msg);
Florin Coras54693d22018-07-17 10:46:29 -07002146 }
Florin Coras134a9962018-08-28 11:32:04 -07002147 vec_reset_length (wrk->mq_msg_vector);
Florin Coras30e79c22019-01-02 19:31:22 -08002148 vcl_handle_pending_wrk_updates (wrk);
Florin Coras54693d22018-07-17 10:46:29 -07002149 return *bits_set;
Dave Wallace543852a2017-08-03 02:11:34 -04002150}
2151
Florin Coras99368312018-08-02 10:45:44 -07002152static int
Florin Coras294afe22019-01-07 17:49:17 -08002153vppcom_select_condvar (vcl_worker_t * wrk, int n_bits,
2154 vcl_si_set * read_map, vcl_si_set * write_map,
2155 vcl_si_set * except_map, double time_to_wait,
Florin Coras134a9962018-08-28 11:32:04 -07002156 u32 * bits_set)
Florin Coras99368312018-08-02 10:45:44 -07002157{
Florin Coras14ed6df2019-03-06 21:13:42 -08002158 double wait = 0, start = 0;
2159
2160 if (!*bits_set)
2161 {
2162 wait = time_to_wait;
2163 start = clib_time_now (&wrk->clib_time);
2164 }
2165
2166 do
2167 {
2168 vcl_select_handle_mq (wrk, wrk->app_event_queue, n_bits, read_map,
2169 write_map, except_map, wait, bits_set);
2170 if (*bits_set)
2171 return *bits_set;
2172 if (wait == -1)
2173 continue;
2174
2175 wait = wait - (clib_time_now (&wrk->clib_time) - start);
2176 }
2177 while (wait > 0);
2178
2179 return 0;
Florin Coras99368312018-08-02 10:45:44 -07002180}
2181
2182static int
Florin Coras294afe22019-01-07 17:49:17 -08002183vppcom_select_eventfd (vcl_worker_t * wrk, int n_bits,
2184 vcl_si_set * read_map, vcl_si_set * write_map,
2185 vcl_si_set * except_map, double time_to_wait,
Florin Coras134a9962018-08-28 11:32:04 -07002186 u32 * bits_set)
Florin Coras99368312018-08-02 10:45:44 -07002187{
2188 vcl_mq_evt_conn_t *mqc;
2189 int __clib_unused n_read;
2190 int n_mq_evts, i;
2191 u64 buf;
2192
Florin Coras134a9962018-08-28 11:32:04 -07002193 vec_validate (wrk->mq_events, pool_elts (wrk->mq_evt_conns));
2194 n_mq_evts = epoll_wait (wrk->mqs_epfd, wrk->mq_events,
2195 vec_len (wrk->mq_events), time_to_wait);
Florin Coras99368312018-08-02 10:45:44 -07002196 for (i = 0; i < n_mq_evts; i++)
2197 {
Florin Coras134a9962018-08-28 11:32:04 -07002198 mqc = vcl_mq_evt_conn_get (wrk, wrk->mq_events[i].data.u32);
Florin Coras99368312018-08-02 10:45:44 -07002199 n_read = read (mqc->mq_fd, &buf, sizeof (buf));
Florin Coras134a9962018-08-28 11:32:04 -07002200 vcl_select_handle_mq (wrk, mqc->mq, n_bits, read_map, write_map,
Florin Coras99368312018-08-02 10:45:44 -07002201 except_map, 0, bits_set);
2202 }
2203
2204 return (n_mq_evts > 0 ? (int) *bits_set : 0);
2205}
2206
Dave Wallace543852a2017-08-03 02:11:34 -04002207int
Florin Coras294afe22019-01-07 17:49:17 -08002208vppcom_select (int n_bits, vcl_si_set * read_map, vcl_si_set * write_map,
2209 vcl_si_set * except_map, double time_to_wait)
Dave Wallace543852a2017-08-03 02:11:34 -04002210{
Florin Coras54693d22018-07-17 10:46:29 -07002211 u32 sid, minbits = clib_max (n_bits, BITS (uword)), bits_set = 0;
Florin Coras134a9962018-08-28 11:32:04 -07002212 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras7e12d942018-06-27 14:32:43 -07002213 vcl_session_t *session = 0;
Florin Coras86f04502018-09-12 16:08:01 -07002214 int rv, i;
Dave Wallace543852a2017-08-03 02:11:34 -04002215
Dave Wallace7876d392017-10-19 03:53:57 -04002216 if (n_bits && read_map)
Dave Wallace543852a2017-08-03 02:11:34 -04002217 {
Florin Coras134a9962018-08-28 11:32:04 -07002218 clib_bitmap_validate (wrk->rd_bitmap, minbits);
Dave Barach178cf492018-11-13 16:34:13 -05002219 clib_memcpy_fast (wrk->rd_bitmap, read_map,
Florin Coras294afe22019-01-07 17:49:17 -08002220 vec_len (wrk->rd_bitmap) * sizeof (vcl_si_set));
2221 memset (read_map, 0, vec_len (wrk->rd_bitmap) * sizeof (vcl_si_set));
Dave Wallace543852a2017-08-03 02:11:34 -04002222 }
Dave Wallace7876d392017-10-19 03:53:57 -04002223 if (n_bits && write_map)
Dave Wallace543852a2017-08-03 02:11:34 -04002224 {
Florin Coras134a9962018-08-28 11:32:04 -07002225 clib_bitmap_validate (wrk->wr_bitmap, minbits);
Dave Barach178cf492018-11-13 16:34:13 -05002226 clib_memcpy_fast (wrk->wr_bitmap, write_map,
Florin Coras294afe22019-01-07 17:49:17 -08002227 vec_len (wrk->wr_bitmap) * sizeof (vcl_si_set));
2228 memset (write_map, 0, vec_len (wrk->wr_bitmap) * sizeof (vcl_si_set));
Dave Wallace543852a2017-08-03 02:11:34 -04002229 }
Dave Wallace7876d392017-10-19 03:53:57 -04002230 if (n_bits && except_map)
Dave Wallace543852a2017-08-03 02:11:34 -04002231 {
Florin Coras134a9962018-08-28 11:32:04 -07002232 clib_bitmap_validate (wrk->ex_bitmap, minbits);
Dave Barach178cf492018-11-13 16:34:13 -05002233 clib_memcpy_fast (wrk->ex_bitmap, except_map,
Florin Coras294afe22019-01-07 17:49:17 -08002234 vec_len (wrk->ex_bitmap) * sizeof (vcl_si_set));
2235 memset (except_map, 0, vec_len (wrk->ex_bitmap) * sizeof (vcl_si_set));
Dave Wallace543852a2017-08-03 02:11:34 -04002236 }
2237
Florin Coras54693d22018-07-17 10:46:29 -07002238 if (!n_bits)
2239 return 0;
2240
2241 if (!write_map)
2242 goto check_rd;
2243
2244 /* *INDENT-OFF* */
Florin Coras134a9962018-08-28 11:32:04 -07002245 clib_bitmap_foreach (sid, wrk->wr_bitmap, ({
2246 if (!(session = vcl_session_get (wrk, sid)))
Florin Coras54693d22018-07-17 10:46:29 -07002247 {
Florin Coras47c40e22018-11-26 17:01:36 -08002248 if (except_map && sid < minbits)
2249 clib_bitmap_set_no_check (except_map, sid, 1);
2250 continue;
Florin Coras54693d22018-07-17 10:46:29 -07002251 }
2252
Sirshak Das28aa5392019-02-05 01:33:33 -06002253 rv = svm_fifo_is_full_prod (session->tx_fifo);
Florin Coras54693d22018-07-17 10:46:29 -07002254 if (!rv)
2255 {
David Johnsond9818dd2018-12-14 14:53:41 -05002256 clib_bitmap_set_no_check ((uword*)write_map, sid, 1);
Florin Coras54693d22018-07-17 10:46:29 -07002257 bits_set++;
2258 }
Florin Coras294afe22019-01-07 17:49:17 -08002259 else
Florin Coras2d379d82019-06-28 12:45:12 -07002260 svm_fifo_add_want_deq_ntf (session->tx_fifo, SVM_FIFO_WANT_DEQ_NOTIF);
Florin Coras54693d22018-07-17 10:46:29 -07002261 }));
2262
2263check_rd:
2264 if (!read_map)
2265 goto check_mq;
Florin Coras99368312018-08-02 10:45:44 -07002266
Florin Coras134a9962018-08-28 11:32:04 -07002267 clib_bitmap_foreach (sid, wrk->rd_bitmap, ({
2268 if (!(session = vcl_session_get (wrk, sid)))
Florin Coras54693d22018-07-17 10:46:29 -07002269 {
Florin Coras47c40e22018-11-26 17:01:36 -08002270 if (except_map && sid < minbits)
2271 clib_bitmap_set_no_check (except_map, sid, 1);
2272 continue;
Florin Coras54693d22018-07-17 10:46:29 -07002273 }
2274
Florin Coras0ef8ef22019-01-18 08:37:13 -08002275 rv = vcl_session_read_ready (session);
Florin Coras54693d22018-07-17 10:46:29 -07002276 if (rv)
2277 {
David Johnsond9818dd2018-12-14 14:53:41 -05002278 clib_bitmap_set_no_check ((uword*)read_map, sid, 1);
Florin Coras54693d22018-07-17 10:46:29 -07002279 bits_set++;
2280 }
2281 }));
2282 /* *INDENT-ON* */
2283
2284check_mq:
Dave Wallace543852a2017-08-03 02:11:34 -04002285
Florin Coras86f04502018-09-12 16:08:01 -07002286 for (i = 0; i < vec_len (wrk->unhandled_evts_vector); i++)
2287 {
2288 vcl_select_handle_mq_event (wrk, &wrk->unhandled_evts_vector[i], n_bits,
2289 read_map, write_map, except_map, &bits_set);
2290 }
2291 vec_reset_length (wrk->unhandled_evts_vector);
2292
Florin Coras99368312018-08-02 10:45:44 -07002293 if (vcm->cfg.use_mq_eventfd)
Florin Coras134a9962018-08-28 11:32:04 -07002294 vppcom_select_eventfd (wrk, n_bits, read_map, write_map, except_map,
Florin Coras99368312018-08-02 10:45:44 -07002295 time_to_wait, &bits_set);
2296 else
Florin Coras134a9962018-08-28 11:32:04 -07002297 vppcom_select_condvar (wrk, n_bits, read_map, write_map, except_map,
Florin Coras99368312018-08-02 10:45:44 -07002298 time_to_wait, &bits_set);
Florin Coras54693d22018-07-17 10:46:29 -07002299
Dave Wallace543852a2017-08-03 02:11:34 -04002300 return (bits_set);
2301}
2302
Dave Wallacef7f809c2017-10-03 01:48:42 -04002303static inline void
Florin Coras7e5e62b2019-07-30 14:08:23 -07002304vep_verify_epoll_chain (vcl_worker_t * wrk, u32 vep_handle)
Dave Wallacef7f809c2017-10-03 01:48:42 -04002305{
Florin Coras7e12d942018-06-27 14:32:43 -07002306 vcl_session_t *session;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002307 vppcom_epoll_t *vep;
Florin Coras7e5e62b2019-07-30 14:08:23 -07002308 u32 sh = vep_handle;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002309
Florin Corasc0737e92019-03-04 14:19:39 -08002310 if (VPPCOM_DEBUG <= 2)
Dave Wallacef7f809c2017-10-03 01:48:42 -04002311 return;
2312
Florin Coras7e5e62b2019-07-30 14:08:23 -07002313 session = vcl_session_get_w_handle (wrk, vep_handle);
Florin Coras070453d2018-08-24 17:04:27 -07002314 if (PREDICT_FALSE (!session))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002315 {
Florin Coras7e5e62b2019-07-30 14:08:23 -07002316 VDBG (0, "ERROR: Invalid vep_sh (%u)!", vep_handle);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002317 goto done;
2318 }
2319 if (PREDICT_FALSE (!session->is_vep))
2320 {
Florin Coras7e5e62b2019-07-30 14:08:23 -07002321 VDBG (0, "ERROR: vep_sh (%u) is not a vep!", vep_handle);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002322 goto done;
2323 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05002324 vep = &session->vep;
Florin Coras7e5e62b2019-07-30 14:08:23 -07002325 VDBG (0, "vep_sh (%u): Dumping epoll chain\n"
Florin Coras5e062572019-03-14 19:07:51 -07002326 "{\n"
2327 " is_vep = %u\n"
2328 " is_vep_session = %u\n"
Florin Coras7e5e62b2019-07-30 14:08:23 -07002329 " next_sh = 0x%x (%u)\n"
2330 "}\n", vep_handle, session->is_vep, session->is_vep_session,
Florin Coras5e062572019-03-14 19:07:51 -07002331 vep->next_sh, vep->next_sh);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002332
Florin Coras7e5e62b2019-07-30 14:08:23 -07002333 for (sh = vep->next_sh; sh != ~0; sh = vep->next_sh)
Dave Wallacef7f809c2017-10-03 01:48:42 -04002334 {
Florin Coras7e5e62b2019-07-30 14:08:23 -07002335 session = vcl_session_get_w_handle (wrk, sh);
Florin Coras070453d2018-08-24 17:04:27 -07002336 if (PREDICT_FALSE (!session))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002337 {
Florin Coras7e5e62b2019-07-30 14:08:23 -07002338 VDBG (0, "ERROR: Invalid sh (%u)!", sh);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002339 goto done;
2340 }
2341 if (PREDICT_FALSE (session->is_vep))
Florin Coras5e062572019-03-14 19:07:51 -07002342 {
Florin Coras7e5e62b2019-07-30 14:08:23 -07002343 VDBG (0, "ERROR: sh (%u) is a vep!", vep_handle);
Florin Coras5e062572019-03-14 19:07:51 -07002344 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05002345 else if (PREDICT_FALSE (!session->is_vep_session))
2346 {
Florin Coras7e5e62b2019-07-30 14:08:23 -07002347 VDBG (0, "ERROR: sh (%u) is not a vep session handle!", sh);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002348 goto done;
2349 }
2350 vep = &session->vep;
Florin Coras7e5e62b2019-07-30 14:08:23 -07002351 if (PREDICT_FALSE (vep->vep_sh != vep_handle))
2352 VDBG (0, "ERROR: session (%u) vep_sh (%u) != vep_sh (%u)!",
2353 sh, session->vep.vep_sh, vep_handle);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002354 if (session->is_vep_session)
2355 {
Florin Coras7e5e62b2019-07-30 14:08:23 -07002356 VDBG (0, "vep_sh[%u]: sh 0x%x (%u)\n"
Florin Coras5e062572019-03-14 19:07:51 -07002357 "{\n"
Florin Coras7e5e62b2019-07-30 14:08:23 -07002358 " next_sh = 0x%x (%u)\n"
2359 " prev_sh = 0x%x (%u)\n"
2360 " vep_sh = 0x%x (%u)\n"
Florin Coras5e062572019-03-14 19:07:51 -07002361 " ev.events = 0x%x\n"
2362 " ev.data.u64 = 0x%llx\n"
2363 " et_mask = 0x%x\n"
2364 "}\n",
Florin Coras7e5e62b2019-07-30 14:08:23 -07002365 vep_handle, sh, sh, vep->next_sh, vep->next_sh, vep->prev_sh,
Florin Coras5e062572019-03-14 19:07:51 -07002366 vep->prev_sh, vep->vep_sh, vep->vep_sh, vep->ev.events,
2367 vep->ev.data.u64, vep->et_mask);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002368 }
2369 }
Dave Wallacef7f809c2017-10-03 01:48:42 -04002370
2371done:
Florin Coras7e5e62b2019-07-30 14:08:23 -07002372 VDBG (0, "vep_sh (%u): Dump complete!\n", vep_handle);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002373}
2374
2375int
2376vppcom_epoll_create (void)
2377{
Florin Coras134a9962018-08-28 11:32:04 -07002378 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras7e12d942018-06-27 14:32:43 -07002379 vcl_session_t *vep_session;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002380
Florin Coras134a9962018-08-28 11:32:04 -07002381 vep_session = vcl_session_alloc (wrk);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002382
2383 vep_session->is_vep = 1;
Florin Coras134a9962018-08-28 11:32:04 -07002384 vep_session->vep.vep_sh = ~0;
2385 vep_session->vep.next_sh = ~0;
2386 vep_session->vep.prev_sh = ~0;
Dave Wallace4878cbe2017-11-21 03:45:09 -05002387 vep_session->vpp_handle = ~0;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002388
Florin Corasa7a1a222018-12-30 17:11:31 -08002389 vcl_evt (VCL_EVT_EPOLL_CREATE, vep_session, vep_session->session_index);
2390 VDBG (0, "Created vep_idx %u", vep_session->session_index);
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002391
Florin Corasab2f6db2018-08-31 14:31:41 -07002392 return vcl_session_handle (vep_session);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002393}
2394
2395int
Florin Coras134a9962018-08-28 11:32:04 -07002396vppcom_epoll_ctl (uint32_t vep_handle, int op, uint32_t session_handle,
Dave Wallacef7f809c2017-10-03 01:48:42 -04002397 struct epoll_event *event)
2398{
Florin Coras134a9962018-08-28 11:32:04 -07002399 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras7e12d942018-06-27 14:32:43 -07002400 vcl_session_t *vep_session;
2401 vcl_session_t *session;
Florin Coras070453d2018-08-24 17:04:27 -07002402 int rv = VPPCOM_OK;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002403
Florin Coras134a9962018-08-28 11:32:04 -07002404 if (vep_handle == session_handle)
Dave Wallacef7f809c2017-10-03 01:48:42 -04002405 {
Florin Corasa7a1a222018-12-30 17:11:31 -08002406 VDBG (0, "vep_sh == session handle (%u)!", vep_handle);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002407 return VPPCOM_EINVAL;
2408 }
2409
Florin Coras134a9962018-08-28 11:32:04 -07002410 vep_session = vcl_session_get_w_handle (wrk, vep_handle);
Florin Coras070453d2018-08-24 17:04:27 -07002411 if (PREDICT_FALSE (!vep_session))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002412 {
Florin Corasa7a1a222018-12-30 17:11:31 -08002413 VDBG (0, "Invalid vep_sh (%u)!", vep_handle);
Florin Coras070453d2018-08-24 17:04:27 -07002414 return VPPCOM_EBADFD;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002415 }
2416 if (PREDICT_FALSE (!vep_session->is_vep))
2417 {
Florin Corasa7a1a222018-12-30 17:11:31 -08002418 VDBG (0, "vep_sh (%u) is not a vep!", vep_handle);
Florin Coras070453d2018-08-24 17:04:27 -07002419 return VPPCOM_EINVAL;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002420 }
2421
Florin Coras134a9962018-08-28 11:32:04 -07002422 ASSERT (vep_session->vep.vep_sh == ~0);
2423 ASSERT (vep_session->vep.prev_sh == ~0);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002424
Florin Coras134a9962018-08-28 11:32:04 -07002425 session = vcl_session_get_w_handle (wrk, session_handle);
Florin Coras070453d2018-08-24 17:04:27 -07002426 if (PREDICT_FALSE (!session))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002427 {
Florin Corasa7a1a222018-12-30 17:11:31 -08002428 VDBG (0, "Invalid session_handle (%u)!", session_handle);
Florin Coras070453d2018-08-24 17:04:27 -07002429 return VPPCOM_EBADFD;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002430 }
2431 if (PREDICT_FALSE (session->is_vep))
2432 {
Florin Corasa7a1a222018-12-30 17:11:31 -08002433 VDBG (0, "session_handle (%u) is a vep!", vep_handle);
Florin Coras070453d2018-08-24 17:04:27 -07002434 return VPPCOM_EINVAL;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002435 }
2436
2437 switch (op)
2438 {
2439 case EPOLL_CTL_ADD:
2440 if (PREDICT_FALSE (!event))
2441 {
Florin Corasa7a1a222018-12-30 17:11:31 -08002442 VDBG (0, "EPOLL_CTL_ADD: NULL pointer to epoll_event structure!");
Florin Coras070453d2018-08-24 17:04:27 -07002443 return VPPCOM_EINVAL;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002444 }
Florin Coras134a9962018-08-28 11:32:04 -07002445 if (vep_session->vep.next_sh != ~0)
Dave Wallacef7f809c2017-10-03 01:48:42 -04002446 {
Florin Coras7e12d942018-06-27 14:32:43 -07002447 vcl_session_t *next_session;
Florin Corasab2f6db2018-08-31 14:31:41 -07002448 next_session = vcl_session_get_w_handle (wrk,
2449 vep_session->vep.next_sh);
Florin Coras070453d2018-08-24 17:04:27 -07002450 if (PREDICT_FALSE (!next_session))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002451 {
Florin Coras5e062572019-03-14 19:07:51 -07002452 VDBG (0, "EPOLL_CTL_ADD: Invalid vep.next_sh (%u) on "
Florin Corasa7a1a222018-12-30 17:11:31 -08002453 "vep_idx (%u)!", vep_session->vep.next_sh, vep_handle);
Florin Coras070453d2018-08-24 17:04:27 -07002454 return VPPCOM_EBADFD;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002455 }
Florin Coras134a9962018-08-28 11:32:04 -07002456 ASSERT (next_session->vep.prev_sh == vep_handle);
2457 next_session->vep.prev_sh = session_handle;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002458 }
Florin Coras134a9962018-08-28 11:32:04 -07002459 session->vep.next_sh = vep_session->vep.next_sh;
2460 session->vep.prev_sh = vep_handle;
2461 session->vep.vep_sh = vep_handle;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002462 session->vep.et_mask = VEP_DEFAULT_ET_MASK;
2463 session->vep.ev = *event;
Dave Wallace4878cbe2017-11-21 03:45:09 -05002464 session->is_vep = 0;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002465 session->is_vep_session = 1;
Florin Coras134a9962018-08-28 11:32:04 -07002466 vep_session->vep.next_sh = session_handle;
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002467
Florin Coras1bcad5c2019-01-09 20:04:38 -08002468 if (session->tx_fifo)
Florin Coras2d379d82019-06-28 12:45:12 -07002469 svm_fifo_add_want_deq_ntf (session->tx_fifo,
2470 SVM_FIFO_WANT_DEQ_NOTIF_IF_FULL);
Florin Coras1bcad5c2019-01-09 20:04:38 -08002471
Florin Corasa7a1a222018-12-30 17:11:31 -08002472 VDBG (1, "EPOLL_CTL_ADD: vep_sh %u, sh %u, events 0x%x, data 0x%llx!",
2473 vep_handle, session_handle, event->events, event->data.u64);
Florin Coras0d427d82018-06-27 03:24:07 -07002474 vcl_evt (VCL_EVT_EPOLL_CTLADD, session, event->events, event->data.u64);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002475 break;
2476
2477 case EPOLL_CTL_MOD:
2478 if (PREDICT_FALSE (!event))
2479 {
Florin Corasa7a1a222018-12-30 17:11:31 -08002480 VDBG (0, "EPOLL_CTL_MOD: NULL pointer to epoll_event structure!");
Dave Wallacef7f809c2017-10-03 01:48:42 -04002481 rv = VPPCOM_EINVAL;
2482 goto done;
2483 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05002484 else if (PREDICT_FALSE (!session->is_vep_session))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002485 {
Florin Coras5e062572019-03-14 19:07:51 -07002486 VDBG (0, "sh %u EPOLL_CTL_MOD: not a vep session!", session_handle);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002487 rv = VPPCOM_EINVAL;
2488 goto done;
2489 }
Florin Coras134a9962018-08-28 11:32:04 -07002490 else if (PREDICT_FALSE (session->vep.vep_sh != vep_handle))
Dave Wallace4878cbe2017-11-21 03:45:09 -05002491 {
Florin Corasa7a1a222018-12-30 17:11:31 -08002492 VDBG (0, "EPOLL_CTL_MOD: sh %u vep_sh (%u) != vep_sh (%u)!",
2493 session_handle, session->vep.vep_sh, vep_handle);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002494 rv = VPPCOM_EINVAL;
2495 goto done;
2496 }
2497 session->vep.et_mask = VEP_DEFAULT_ET_MASK;
2498 session->vep.ev = *event;
Florin Corasa7a1a222018-12-30 17:11:31 -08002499 VDBG (1, "EPOLL_CTL_MOD: vep_sh %u, sh %u, events 0x%x, data 0x%llx!",
2500 vep_handle, session_handle, event->events, event->data.u64);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002501 break;
2502
2503 case EPOLL_CTL_DEL:
Dave Wallace4878cbe2017-11-21 03:45:09 -05002504 if (PREDICT_FALSE (!session->is_vep_session))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002505 {
Florin Corasa7a1a222018-12-30 17:11:31 -08002506 VDBG (0, "EPOLL_CTL_DEL: %u not a vep session!", session_handle);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002507 rv = VPPCOM_EINVAL;
2508 goto done;
2509 }
Florin Coras134a9962018-08-28 11:32:04 -07002510 else if (PREDICT_FALSE (session->vep.vep_sh != vep_handle))
Dave Wallace4878cbe2017-11-21 03:45:09 -05002511 {
Florin Corasa7a1a222018-12-30 17:11:31 -08002512 VDBG (0, "EPOLL_CTL_DEL: sh %u vep_sh (%u) != vep_sh (%u)!",
2513 session_handle, session->vep.vep_sh, vep_handle);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002514 rv = VPPCOM_EINVAL;
2515 goto done;
2516 }
2517
Florin Coras134a9962018-08-28 11:32:04 -07002518 if (session->vep.prev_sh == vep_handle)
2519 vep_session->vep.next_sh = session->vep.next_sh;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002520 else
2521 {
Florin Coras7e12d942018-06-27 14:32:43 -07002522 vcl_session_t *prev_session;
Florin Corasab2f6db2018-08-31 14:31:41 -07002523 prev_session = vcl_session_get_w_handle (wrk, session->vep.prev_sh);
Florin Coras070453d2018-08-24 17:04:27 -07002524 if (PREDICT_FALSE (!prev_session))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002525 {
Florin Coras5e062572019-03-14 19:07:51 -07002526 VDBG (0, "EPOLL_CTL_DEL: Invalid prev_sh (%u) on sh (%u)!",
Florin Corasa7a1a222018-12-30 17:11:31 -08002527 session->vep.prev_sh, session_handle);
Florin Coras070453d2018-08-24 17:04:27 -07002528 return VPPCOM_EBADFD;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002529 }
Florin Coras134a9962018-08-28 11:32:04 -07002530 ASSERT (prev_session->vep.next_sh == session_handle);
2531 prev_session->vep.next_sh = session->vep.next_sh;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002532 }
Florin Coras134a9962018-08-28 11:32:04 -07002533 if (session->vep.next_sh != ~0)
Dave Wallacef7f809c2017-10-03 01:48:42 -04002534 {
Florin Coras7e12d942018-06-27 14:32:43 -07002535 vcl_session_t *next_session;
Florin Corasab2f6db2018-08-31 14:31:41 -07002536 next_session = vcl_session_get_w_handle (wrk, session->vep.next_sh);
Florin Coras070453d2018-08-24 17:04:27 -07002537 if (PREDICT_FALSE (!next_session))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002538 {
Florin Coras5e062572019-03-14 19:07:51 -07002539 VDBG (0, "EPOLL_CTL_DEL: Invalid next_sh (%u) on sh (%u)!",
Florin Corasa7a1a222018-12-30 17:11:31 -08002540 session->vep.next_sh, session_handle);
Florin Coras070453d2018-08-24 17:04:27 -07002541 return VPPCOM_EBADFD;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002542 }
Florin Coras134a9962018-08-28 11:32:04 -07002543 ASSERT (next_session->vep.prev_sh == session_handle);
2544 next_session->vep.prev_sh = session->vep.prev_sh;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002545 }
2546
2547 memset (&session->vep, 0, sizeof (session->vep));
Florin Coras134a9962018-08-28 11:32:04 -07002548 session->vep.next_sh = ~0;
2549 session->vep.prev_sh = ~0;
2550 session->vep.vep_sh = ~0;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002551 session->is_vep_session = 0;
Florin Coras1bcad5c2019-01-09 20:04:38 -08002552
2553 if (session->tx_fifo)
Florin Coras2d379d82019-06-28 12:45:12 -07002554 svm_fifo_del_want_deq_ntf (session->tx_fifo, SVM_FIFO_NO_DEQ_NOTIF);
Florin Coras1bcad5c2019-01-09 20:04:38 -08002555
Florin Coras5e062572019-03-14 19:07:51 -07002556 VDBG (1, "EPOLL_CTL_DEL: vep_idx %u, sh %u!", vep_handle,
Florin Corasa7a1a222018-12-30 17:11:31 -08002557 session_handle);
Florin Coras134a9962018-08-28 11:32:04 -07002558 vcl_evt (VCL_EVT_EPOLL_CTLDEL, session, vep_sh);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002559 break;
2560
2561 default:
Florin Corasa7a1a222018-12-30 17:11:31 -08002562 VDBG (0, "Invalid operation (%d)!", op);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002563 rv = VPPCOM_EINVAL;
2564 }
2565
Florin Coras134a9962018-08-28 11:32:04 -07002566 vep_verify_epoll_chain (wrk, vep_handle);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002567
2568done:
Dave Wallacef7f809c2017-10-03 01:48:42 -04002569 return rv;
2570}
2571
Florin Coras86f04502018-09-12 16:08:01 -07002572static inline void
2573vcl_epoll_wait_handle_mq_event (vcl_worker_t * wrk, session_event_t * e,
2574 struct epoll_event *events, u32 * num_ev)
Florin Coras54693d22018-07-17 10:46:29 -07002575{
2576 session_disconnected_msg_t *disconnected_msg;
2577 session_connected_msg_t *connected_msg;
Florin Coras99368312018-08-02 10:45:44 -07002578 u32 sid = ~0, session_events;
Florin Coras3c7d4f92018-12-14 11:28:43 -08002579 u64 session_evt_data = ~0;
Florin Coras54693d22018-07-17 10:46:29 -07002580 vcl_session_t *session;
Florin Coras86f04502018-09-12 16:08:01 -07002581 u8 add_event = 0;
2582
2583 switch (e->event_type)
2584 {
Florin Coras653e43f2019-03-04 10:56:23 -08002585 case SESSION_IO_EVT_RX:
Florin Corasc0737e92019-03-04 14:19:39 -08002586 sid = e->session_index;
Florin Corasfa915f82018-12-26 16:29:06 -08002587 if (!(session = vcl_session_get (wrk, sid)))
2588 break;
Florin Corasc0737e92019-03-04 14:19:39 -08002589 vcl_fifo_rx_evt_valid_or_break (session);
Florin Coras86f04502018-09-12 16:08:01 -07002590 session_events = session->vep.ev.events;
Florin Corasaa27eb92018-10-13 12:20:01 -07002591 if (!(EPOLLIN & session->vep.ev.events) || session->has_rx_evt)
Florin Coras86f04502018-09-12 16:08:01 -07002592 break;
2593 add_event = 1;
2594 events[*num_ev].events |= EPOLLIN;
2595 session_evt_data = session->vep.ev.data.u64;
Florin Corasaa27eb92018-10-13 12:20:01 -07002596 session->has_rx_evt = 1;
Florin Coras86f04502018-09-12 16:08:01 -07002597 break;
Florin Coras653e43f2019-03-04 10:56:23 -08002598 case SESSION_IO_EVT_TX:
Florin Corasc0737e92019-03-04 14:19:39 -08002599 sid = e->session_index;
Florin Corasfa915f82018-12-26 16:29:06 -08002600 if (!(session = vcl_session_get (wrk, sid)))
2601 break;
Florin Coras86f04502018-09-12 16:08:01 -07002602 session_events = session->vep.ev.events;
2603 if (!(EPOLLOUT & session_events))
2604 break;
2605 add_event = 1;
2606 events[*num_ev].events |= EPOLLOUT;
2607 session_evt_data = session->vep.ev.data.u64;
Florin Coras2d379d82019-06-28 12:45:12 -07002608 svm_fifo_reset_has_deq_ntf (session->tx_fifo);
Florin Coras86f04502018-09-12 16:08:01 -07002609 break;
Florin Coras86f04502018-09-12 16:08:01 -07002610 case SESSION_CTRL_EVT_ACCEPTED:
Florin Coras3c7d4f92018-12-14 11:28:43 -08002611 session = vcl_session_accepted (wrk,
2612 (session_accepted_msg_t *) e->data);
Florin Coras86f04502018-09-12 16:08:01 -07002613 if (!session)
Florin Coras3c7d4f92018-12-14 11:28:43 -08002614 break;
Florin Coras86f04502018-09-12 16:08:01 -07002615
Florin Coras86f04502018-09-12 16:08:01 -07002616 session_events = session->vep.ev.events;
2617 if (!(EPOLLIN & session_events))
2618 break;
2619
2620 add_event = 1;
2621 events[*num_ev].events |= EPOLLIN;
2622 session_evt_data = session->vep.ev.data.u64;
2623 break;
2624 case SESSION_CTRL_EVT_CONNECTED:
2625 connected_msg = (session_connected_msg_t *) e->data;
2626 vcl_session_connected_handler (wrk, connected_msg);
2627 /* Generate EPOLLOUT because there's no connected event */
2628 sid = vcl_session_index_from_vpp_handle (wrk, connected_msg->handle);
Florin Corasfa915f82018-12-26 16:29:06 -08002629 if (!(session = vcl_session_get (wrk, sid)))
2630 break;
Florin Coras86f04502018-09-12 16:08:01 -07002631 session_events = session->vep.ev.events;
Florin Coras72f77822019-01-22 19:05:52 -08002632 if (!(EPOLLOUT & session_events))
2633 break;
2634 add_event = 1;
2635 events[*num_ev].events |= EPOLLOUT;
2636 session_evt_data = session->vep.ev.data.u64;
Florin Coras86f04502018-09-12 16:08:01 -07002637 break;
2638 case SESSION_CTRL_EVT_DISCONNECTED:
2639 disconnected_msg = (session_disconnected_msg_t *) e->data;
Florin Coras3c7d4f92018-12-14 11:28:43 -08002640 session = vcl_session_disconnected_handler (wrk, disconnected_msg);
2641 if (!session)
Florin Coras86f04502018-09-12 16:08:01 -07002642 break;
Florin Coras72f77822019-01-22 19:05:52 -08002643 session_events = session->vep.ev.events;
2644 if (!((EPOLLHUP | EPOLLRDHUP) & session_events))
2645 break;
Florin Coras86f04502018-09-12 16:08:01 -07002646 add_event = 1;
2647 events[*num_ev].events |= EPOLLHUP | EPOLLRDHUP;
2648 session_evt_data = session->vep.ev.data.u64;
Florin Coras86f04502018-09-12 16:08:01 -07002649 break;
2650 case SESSION_CTRL_EVT_RESET:
2651 sid = vcl_session_reset_handler (wrk, (session_reset_msg_t *) e->data);
2652 if (!(session = vcl_session_get (wrk, sid)))
2653 break;
Florin Coras72f77822019-01-22 19:05:52 -08002654 session_events = session->vep.ev.events;
2655 if (!((EPOLLHUP | EPOLLRDHUP) & session_events))
2656 break;
Florin Coras86f04502018-09-12 16:08:01 -07002657 add_event = 1;
2658 events[*num_ev].events |= EPOLLHUP | EPOLLRDHUP;
2659 session_evt_data = session->vep.ev.data.u64;
Florin Coras86f04502018-09-12 16:08:01 -07002660 break;
Florin Corasdfae9f92019-02-20 19:48:31 -08002661 case SESSION_CTRL_EVT_UNLISTEN_REPLY:
2662 vcl_session_unlisten_reply_handler (wrk, e->data);
2663 break;
Florin Coras30e79c22019-01-02 19:31:22 -08002664 case SESSION_CTRL_EVT_REQ_WORKER_UPDATE:
2665 vcl_session_req_worker_update_handler (wrk, e->data);
2666 break;
2667 case SESSION_CTRL_EVT_WORKER_UPDATE_REPLY:
2668 vcl_session_worker_update_reply_handler (wrk, e->data);
2669 break;
Florin Coras86f04502018-09-12 16:08:01 -07002670 default:
2671 VDBG (0, "unhandled: %u", e->event_type);
2672 break;
2673 }
2674
2675 if (add_event)
2676 {
2677 events[*num_ev].data.u64 = session_evt_data;
2678 if (EPOLLONESHOT & session_events)
2679 {
2680 session = vcl_session_get (wrk, sid);
2681 session->vep.ev.events = 0;
2682 }
2683 *num_ev += 1;
2684 }
2685}
2686
2687static int
2688vcl_epoll_wait_handle_mq (vcl_worker_t * wrk, svm_msg_q_t * mq,
2689 struct epoll_event *events, u32 maxevents,
2690 double wait_for_time, u32 * num_ev)
2691{
Florin Coras99368312018-08-02 10:45:44 -07002692 svm_msg_q_msg_t *msg;
Florin Coras54693d22018-07-17 10:46:29 -07002693 session_event_t *e;
Florin Coras54693d22018-07-17 10:46:29 -07002694 int i;
2695
Florin Coras539663c2018-09-28 14:59:37 -07002696 if (vec_len (wrk->mq_msg_vector) && svm_msg_q_is_empty (mq))
2697 goto handle_dequeued;
2698
Florin Coras54693d22018-07-17 10:46:29 -07002699 svm_msg_q_lock (mq);
2700 if (svm_msg_q_is_empty (mq))
2701 {
2702 if (!wait_for_time)
2703 {
2704 svm_msg_q_unlock (mq);
2705 return 0;
2706 }
2707 else if (wait_for_time < 0)
2708 {
2709 svm_msg_q_wait (mq);
2710 }
2711 else
2712 {
Florin Coras60f1fc12018-08-16 14:57:31 -07002713 if (svm_msg_q_timedwait (mq, wait_for_time / 1e3))
Florin Coras54693d22018-07-17 10:46:29 -07002714 {
2715 svm_msg_q_unlock (mq);
2716 return 0;
2717 }
2718 }
2719 }
Florin Corase003a1b2019-06-05 10:47:16 -07002720 ASSERT (maxevents > *num_ev);
2721 vcl_mq_dequeue_batch (wrk, mq, maxevents - *num_ev);
Florin Coras54693d22018-07-17 10:46:29 -07002722 svm_msg_q_unlock (mq);
2723
Florin Coras539663c2018-09-28 14:59:37 -07002724handle_dequeued:
Florin Coras134a9962018-08-28 11:32:04 -07002725 for (i = 0; i < vec_len (wrk->mq_msg_vector); i++)
Florin Coras54693d22018-07-17 10:46:29 -07002726 {
Florin Coras134a9962018-08-28 11:32:04 -07002727 msg = vec_elt_at_index (wrk->mq_msg_vector, i);
Florin Coras99368312018-08-02 10:45:44 -07002728 e = svm_msg_q_msg_data (mq, msg);
Florin Corase003a1b2019-06-05 10:47:16 -07002729 vcl_epoll_wait_handle_mq_event (wrk, e, events, num_ev);
Florin Coras99368312018-08-02 10:45:44 -07002730 svm_msg_q_free_msg (mq, msg);
Florin Coras54693d22018-07-17 10:46:29 -07002731 }
Florin Corasaa27eb92018-10-13 12:20:01 -07002732 vec_reset_length (wrk->mq_msg_vector);
Florin Coras30e79c22019-01-02 19:31:22 -08002733 vcl_handle_pending_wrk_updates (wrk);
Florin Coras54693d22018-07-17 10:46:29 -07002734 return *num_ev;
2735}
2736
Florin Coras99368312018-08-02 10:45:44 -07002737static int
Florin Coras134a9962018-08-28 11:32:04 -07002738vppcom_epoll_wait_condvar (vcl_worker_t * wrk, struct epoll_event *events,
Florin Coras86f04502018-09-12 16:08:01 -07002739 int maxevents, u32 n_evts, double wait_for_time)
Florin Coras99368312018-08-02 10:45:44 -07002740{
Florin Corase003a1b2019-06-05 10:47:16 -07002741 double wait = 0, start = 0, now;
Florin Coras14ed6df2019-03-06 21:13:42 -08002742
2743 if (!n_evts)
2744 {
2745 wait = wait_for_time;
2746 start = clib_time_now (&wrk->clib_time);
2747 }
2748
2749 do
2750 {
2751 vcl_epoll_wait_handle_mq (wrk, wrk->app_event_queue, events, maxevents,
2752 wait, &n_evts);
2753 if (n_evts)
2754 return n_evts;
2755 if (wait == -1)
2756 continue;
2757
Florin Corase003a1b2019-06-05 10:47:16 -07002758 now = clib_time_now (&wrk->clib_time);
2759 wait -= now - start;
2760 start = now;
Florin Coras14ed6df2019-03-06 21:13:42 -08002761 }
2762 while (wait > 0);
2763
2764 return 0;
Florin Coras99368312018-08-02 10:45:44 -07002765}
2766
2767static int
Florin Coras134a9962018-08-28 11:32:04 -07002768vppcom_epoll_wait_eventfd (vcl_worker_t * wrk, struct epoll_event *events,
Florin Coras86f04502018-09-12 16:08:01 -07002769 int maxevents, u32 n_evts, double wait_for_time)
Florin Coras99368312018-08-02 10:45:44 -07002770{
2771 vcl_mq_evt_conn_t *mqc;
2772 int __clib_unused n_read;
2773 int n_mq_evts, i;
Florin Coras99368312018-08-02 10:45:44 -07002774 u64 buf;
2775
Florin Coras134a9962018-08-28 11:32:04 -07002776 vec_validate (wrk->mq_events, pool_elts (wrk->mq_evt_conns));
Florin Corasa4878ed2018-10-12 13:09:36 -07002777again:
Florin Coras134a9962018-08-28 11:32:04 -07002778 n_mq_evts = epoll_wait (wrk->mqs_epfd, wrk->mq_events,
2779 vec_len (wrk->mq_events), wait_for_time);
Florin Coras99368312018-08-02 10:45:44 -07002780 for (i = 0; i < n_mq_evts; i++)
2781 {
Florin Coras134a9962018-08-28 11:32:04 -07002782 mqc = vcl_mq_evt_conn_get (wrk, wrk->mq_events[i].data.u32);
Florin Coras99368312018-08-02 10:45:44 -07002783 n_read = read (mqc->mq_fd, &buf, sizeof (buf));
Florin Coras134a9962018-08-28 11:32:04 -07002784 vcl_epoll_wait_handle_mq (wrk, mqc->mq, events, maxevents, 0, &n_evts);
Florin Coras99368312018-08-02 10:45:44 -07002785 }
Florin Corasa4878ed2018-10-12 13:09:36 -07002786 if (!n_evts && n_mq_evts > 0)
2787 goto again;
Florin Coras99368312018-08-02 10:45:44 -07002788
2789 return (int) n_evts;
2790}
2791
Dave Wallacef7f809c2017-10-03 01:48:42 -04002792int
Florin Coras134a9962018-08-28 11:32:04 -07002793vppcom_epoll_wait (uint32_t vep_handle, struct epoll_event *events,
Dave Wallacef7f809c2017-10-03 01:48:42 -04002794 int maxevents, double wait_for_time)
2795{
Florin Coras134a9962018-08-28 11:32:04 -07002796 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras7e12d942018-06-27 14:32:43 -07002797 vcl_session_t *vep_session;
Florin Coras86f04502018-09-12 16:08:01 -07002798 u32 n_evts = 0;
2799 int i;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002800
2801 if (PREDICT_FALSE (maxevents <= 0))
2802 {
Florin Coras5e062572019-03-14 19:07:51 -07002803 VDBG (0, "ERROR: Invalid maxevents (%d)!", maxevents);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002804 return VPPCOM_EINVAL;
2805 }
Dave Wallacef7f809c2017-10-03 01:48:42 -04002806
Florin Coras134a9962018-08-28 11:32:04 -07002807 vep_session = vcl_session_get_w_handle (wrk, vep_handle);
Florin Coras14598772018-09-04 19:47:52 -07002808 if (!vep_session)
2809 return VPPCOM_EBADFD;
2810
Florin Coras54693d22018-07-17 10:46:29 -07002811 if (PREDICT_FALSE (!vep_session->is_vep))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002812 {
Florin Coras5e062572019-03-14 19:07:51 -07002813 VDBG (0, "ERROR: vep_idx (%u) is not a vep!", vep_handle);
Florin Coras54693d22018-07-17 10:46:29 -07002814 return VPPCOM_EINVAL;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002815 }
Florin Coras54693d22018-07-17 10:46:29 -07002816
2817 memset (events, 0, sizeof (*events) * maxevents);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002818
Florin Coras86f04502018-09-12 16:08:01 -07002819 if (vec_len (wrk->unhandled_evts_vector))
2820 {
2821 for (i = 0; i < vec_len (wrk->unhandled_evts_vector); i++)
2822 {
2823 vcl_epoll_wait_handle_mq_event (wrk, &wrk->unhandled_evts_vector[i],
2824 events, &n_evts);
2825 if (n_evts == maxevents)
2826 {
Florin Corase003a1b2019-06-05 10:47:16 -07002827 vec_delete (wrk->unhandled_evts_vector, i + 1, 0);
2828 return n_evts;
Florin Coras86f04502018-09-12 16:08:01 -07002829 }
2830 }
Florin Corase003a1b2019-06-05 10:47:16 -07002831 vec_reset_length (wrk->unhandled_evts_vector);
Florin Coras86f04502018-09-12 16:08:01 -07002832 }
2833
2834 if (vcm->cfg.use_mq_eventfd)
2835 return vppcom_epoll_wait_eventfd (wrk, events, maxevents, n_evts,
2836 wait_for_time);
2837
2838 return vppcom_epoll_wait_condvar (wrk, events, maxevents, n_evts,
2839 wait_for_time);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002840}
2841
Dave Wallace35830af2017-10-09 01:43:42 -04002842int
Florin Coras134a9962018-08-28 11:32:04 -07002843vppcom_session_attr (uint32_t session_handle, uint32_t op,
Dave Wallace35830af2017-10-09 01:43:42 -04002844 void *buffer, uint32_t * buflen)
2845{
Florin Coras134a9962018-08-28 11:32:04 -07002846 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras7e12d942018-06-27 14:32:43 -07002847 vcl_session_t *session;
Dave Wallace35830af2017-10-09 01:43:42 -04002848 int rv = VPPCOM_OK;
Florin Coras7baeb712019-01-04 17:05:43 -08002849 u32 *flags = buffer, tmp_flags = 0;
Steven2199aab2017-10-15 20:18:47 -07002850 vppcom_endpt_t *ep = buffer;
Dave Wallace35830af2017-10-09 01:43:42 -04002851
Florin Coras134a9962018-08-28 11:32:04 -07002852 session = vcl_session_get_w_handle (wrk, session_handle);
Florin Coras070453d2018-08-24 17:04:27 -07002853 if (!session)
2854 return VPPCOM_EBADFD;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002855
Dave Wallace35830af2017-10-09 01:43:42 -04002856 switch (op)
2857 {
2858 case VPPCOM_ATTR_GET_NREAD:
Florin Coras0ef8ef22019-01-18 08:37:13 -08002859 rv = vcl_session_read_ready (session);
Florin Coras5e062572019-03-14 19:07:51 -07002860 VDBG (2, "VPPCOM_ATTR_GET_NREAD: sh %u, nread = %d", session_handle,
2861 rv);
Dave Wallace35830af2017-10-09 01:43:42 -04002862 break;
2863
Dave Wallace227867f2017-11-13 21:21:53 -05002864 case VPPCOM_ATTR_GET_NWRITE:
Florin Coras0ef8ef22019-01-18 08:37:13 -08002865 rv = vcl_session_write_ready (session);
Florin Coras5e062572019-03-14 19:07:51 -07002866 VDBG (2, "VPPCOM_ATTR_GET_NWRITE: sh %u, nwrite = %d", session_handle,
2867 rv);
Dave Wallace35830af2017-10-09 01:43:42 -04002868 break;
2869
2870 case VPPCOM_ATTR_GET_FLAGS:
Dave Wallace048b1d62018-01-03 22:24:41 -05002871 if (PREDICT_TRUE (buffer && buflen && (*buflen >= sizeof (*flags))))
Dave Wallace35830af2017-10-09 01:43:42 -04002872 {
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002873 *flags = O_RDWR | (VCL_SESS_ATTR_TEST (session->attr,
2874 VCL_SESS_ATTR_NONBLOCK));
Dave Wallace35830af2017-10-09 01:43:42 -04002875 *buflen = sizeof (*flags);
Florin Coras5e062572019-03-14 19:07:51 -07002876 VDBG (2, "VPPCOM_ATTR_GET_FLAGS: sh %u, flags = 0x%08x, "
2877 "is_nonblocking = %u", session_handle, *flags,
Florin Coras0d427d82018-06-27 03:24:07 -07002878 VCL_SESS_ATTR_TEST (session->attr, VCL_SESS_ATTR_NONBLOCK));
Dave Wallace35830af2017-10-09 01:43:42 -04002879 }
2880 else
2881 rv = VPPCOM_EINVAL;
2882 break;
2883
2884 case VPPCOM_ATTR_SET_FLAGS:
Dave Wallace048b1d62018-01-03 22:24:41 -05002885 if (PREDICT_TRUE (buffer && buflen && (*buflen == sizeof (*flags))))
Dave Wallace35830af2017-10-09 01:43:42 -04002886 {
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002887 if (*flags & O_NONBLOCK)
2888 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_NONBLOCK);
2889 else
2890 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_NONBLOCK);
2891
Florin Coras5e062572019-03-14 19:07:51 -07002892 VDBG (2, "VPPCOM_ATTR_SET_FLAGS: sh %u, flags = 0x%08x,"
2893 " is_nonblocking = %u", session_handle, *flags,
Florin Coras0d427d82018-06-27 03:24:07 -07002894 VCL_SESS_ATTR_TEST (session->attr, VCL_SESS_ATTR_NONBLOCK));
Dave Wallace35830af2017-10-09 01:43:42 -04002895 }
2896 else
2897 rv = VPPCOM_EINVAL;
2898 break;
2899
2900 case VPPCOM_ATTR_GET_PEER_ADDR:
Dave Wallace048b1d62018-01-03 22:24:41 -05002901 if (PREDICT_TRUE (buffer && buflen &&
2902 (*buflen >= sizeof (*ep)) && ep->ip))
Dave Wallace35830af2017-10-09 01:43:42 -04002903 {
Florin Coras7e12d942018-06-27 14:32:43 -07002904 ep->is_ip4 = session->transport.is_ip4;
2905 ep->port = session->transport.rmt_port;
2906 if (session->transport.is_ip4)
Dave Barach178cf492018-11-13 16:34:13 -05002907 clib_memcpy_fast (ep->ip, &session->transport.rmt_ip.ip4,
2908 sizeof (ip4_address_t));
Steven2199aab2017-10-15 20:18:47 -07002909 else
Dave Barach178cf492018-11-13 16:34:13 -05002910 clib_memcpy_fast (ep->ip, &session->transport.rmt_ip.ip6,
2911 sizeof (ip6_address_t));
Steven2199aab2017-10-15 20:18:47 -07002912 *buflen = sizeof (*ep);
Florin Coras5e062572019-03-14 19:07:51 -07002913 VDBG (1, "VPPCOM_ATTR_GET_PEER_ADDR: sh %u, is_ip4 = %u, "
2914 "addr = %U, port %u", session_handle, ep->is_ip4,
2915 format_ip46_address, &session->transport.rmt_ip,
Florin Coras0d427d82018-06-27 03:24:07 -07002916 ep->is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6,
2917 clib_net_to_host_u16 (ep->port));
Dave Wallace35830af2017-10-09 01:43:42 -04002918 }
2919 else
2920 rv = VPPCOM_EINVAL;
2921 break;
2922
2923 case VPPCOM_ATTR_GET_LCL_ADDR:
Dave Wallace048b1d62018-01-03 22:24:41 -05002924 if (PREDICT_TRUE (buffer && buflen &&
2925 (*buflen >= sizeof (*ep)) && ep->ip))
Dave Wallace35830af2017-10-09 01:43:42 -04002926 {
Florin Coras7e12d942018-06-27 14:32:43 -07002927 ep->is_ip4 = session->transport.is_ip4;
2928 ep->port = session->transport.lcl_port;
2929 if (session->transport.is_ip4)
Dave Barach178cf492018-11-13 16:34:13 -05002930 clib_memcpy_fast (ep->ip, &session->transport.lcl_ip.ip4,
2931 sizeof (ip4_address_t));
Steven2199aab2017-10-15 20:18:47 -07002932 else
Dave Barach178cf492018-11-13 16:34:13 -05002933 clib_memcpy_fast (ep->ip, &session->transport.lcl_ip.ip6,
2934 sizeof (ip6_address_t));
Steven2199aab2017-10-15 20:18:47 -07002935 *buflen = sizeof (*ep);
Florin Coras5e062572019-03-14 19:07:51 -07002936 VDBG (1, "VPPCOM_ATTR_GET_LCL_ADDR: sh %u, is_ip4 = %u, addr = %U"
2937 " port %d", session_handle, ep->is_ip4, format_ip46_address,
Florin Coras7e12d942018-06-27 14:32:43 -07002938 &session->transport.lcl_ip,
Florin Coras0d427d82018-06-27 03:24:07 -07002939 ep->is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6,
2940 clib_net_to_host_u16 (ep->port));
Dave Wallace35830af2017-10-09 01:43:42 -04002941 }
2942 else
2943 rv = VPPCOM_EINVAL;
2944 break;
Stevenb5a11602017-10-11 09:59:30 -07002945
Florin Corasef7cbf62019-10-17 09:56:27 -07002946 case VPPCOM_ATTR_SET_LCL_ADDR:
2947 if (PREDICT_TRUE (buffer && buflen &&
2948 (*buflen >= sizeof (*ep)) && ep->ip))
2949 {
2950 session->transport.is_ip4 = ep->is_ip4;
2951 session->transport.lcl_port = ep->port;
2952 vcl_ip_copy_from_ep (&session->transport.lcl_ip, ep);
2953 *buflen = sizeof (*ep);
2954 VDBG (1, "VPPCOM_ATTR_SET_LCL_ADDR: sh %u, is_ip4 = %u, addr = %U"
2955 " port %d", session_handle, ep->is_ip4, format_ip46_address,
2956 &session->transport.lcl_ip,
2957 ep->is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6,
2958 clib_net_to_host_u16 (ep->port));
2959 }
2960 else
2961 rv = VPPCOM_EINVAL;
2962 break;
2963
Dave Wallace048b1d62018-01-03 22:24:41 -05002964 case VPPCOM_ATTR_GET_LIBC_EPFD:
2965 rv = session->libc_epfd;
Florin Coras5e062572019-03-14 19:07:51 -07002966 VDBG (2, "VPPCOM_ATTR_GET_LIBC_EPFD: libc_epfd %d", rv);
Dave Wallace048b1d62018-01-03 22:24:41 -05002967 break;
2968
2969 case VPPCOM_ATTR_SET_LIBC_EPFD:
2970 if (PREDICT_TRUE (buffer && buflen &&
2971 (*buflen == sizeof (session->libc_epfd))))
2972 {
2973 session->libc_epfd = *(int *) buffer;
2974 *buflen = sizeof (session->libc_epfd);
2975
Florin Coras5e062572019-03-14 19:07:51 -07002976 VDBG (2, "VPPCOM_ATTR_SET_LIBC_EPFD: libc_epfd %d, buflen %d",
2977 session->libc_epfd, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002978 }
2979 else
2980 rv = VPPCOM_EINVAL;
2981 break;
2982
2983 case VPPCOM_ATTR_GET_PROTOCOL:
2984 if (buffer && buflen && (*buflen >= sizeof (int)))
2985 {
Florin Coras7e12d942018-06-27 14:32:43 -07002986 *(int *) buffer = session->session_type;
Dave Wallace048b1d62018-01-03 22:24:41 -05002987 *buflen = sizeof (int);
2988
Florin Coras5e062572019-03-14 19:07:51 -07002989 VDBG (2, "VPPCOM_ATTR_GET_PROTOCOL: %d (%s), buflen %d",
2990 *(int *) buffer, *(int *) buffer ? "UDP" : "TCP", *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002991 }
2992 else
2993 rv = VPPCOM_EINVAL;
2994 break;
2995
2996 case VPPCOM_ATTR_GET_LISTEN:
2997 if (buffer && buflen && (*buflen >= sizeof (int)))
2998 {
2999 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
3000 VCL_SESS_ATTR_LISTEN);
3001 *buflen = sizeof (int);
3002
Florin Coras5e062572019-03-14 19:07:51 -07003003 VDBG (2, "VPPCOM_ATTR_GET_LISTEN: %d, buflen %d", *(int *) buffer,
3004 *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003005 }
3006 else
3007 rv = VPPCOM_EINVAL;
3008 break;
3009
3010 case VPPCOM_ATTR_GET_ERROR:
3011 if (buffer && buflen && (*buflen >= sizeof (int)))
3012 {
3013 *(int *) buffer = 0;
3014 *buflen = sizeof (int);
3015
Florin Coras5e062572019-03-14 19:07:51 -07003016 VDBG (2, "VPPCOM_ATTR_GET_ERROR: %d, buflen %d, #VPP-TBD#",
3017 *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003018 }
3019 else
3020 rv = VPPCOM_EINVAL;
3021 break;
3022
3023 case VPPCOM_ATTR_GET_TX_FIFO_LEN:
3024 if (buffer && buflen && (*buflen >= sizeof (u32)))
3025 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003026
3027 /* VPP-TBD */
3028 *(size_t *) buffer = (session->sndbuf_size ? session->sndbuf_size :
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003029 session->tx_fifo ? session->tx_fifo->nitems :
Dave Wallace048b1d62018-01-03 22:24:41 -05003030 vcm->cfg.tx_fifo_size);
3031 *buflen = sizeof (u32);
3032
Florin Coras5e062572019-03-14 19:07:51 -07003033 VDBG (2, "VPPCOM_ATTR_GET_TX_FIFO_LEN: %u (0x%x), buflen %d,"
3034 " #VPP-TBD#", *(size_t *) buffer, *(size_t *) buffer,
3035 *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003036 }
3037 else
3038 rv = VPPCOM_EINVAL;
3039 break;
3040
3041 case VPPCOM_ATTR_SET_TX_FIFO_LEN:
3042 if (buffer && buflen && (*buflen == sizeof (u32)))
3043 {
3044 /* VPP-TBD */
3045 session->sndbuf_size = *(u32 *) buffer;
Florin Coras5e062572019-03-14 19:07:51 -07003046 VDBG (2, "VPPCOM_ATTR_SET_TX_FIFO_LEN: %u (0x%x), buflen %d,"
3047 " #VPP-TBD#", session->sndbuf_size, session->sndbuf_size,
3048 *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003049 }
3050 else
3051 rv = VPPCOM_EINVAL;
3052 break;
3053
3054 case VPPCOM_ATTR_GET_RX_FIFO_LEN:
3055 if (buffer && buflen && (*buflen >= sizeof (u32)))
3056 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003057
3058 /* VPP-TBD */
3059 *(size_t *) buffer = (session->rcvbuf_size ? session->rcvbuf_size :
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003060 session->rx_fifo ? session->rx_fifo->nitems :
Dave Wallace048b1d62018-01-03 22:24:41 -05003061 vcm->cfg.rx_fifo_size);
3062 *buflen = sizeof (u32);
3063
Florin Coras5e062572019-03-14 19:07:51 -07003064 VDBG (2, "VPPCOM_ATTR_GET_RX_FIFO_LEN: %u (0x%x), buflen %d, "
3065 "#VPP-TBD#", *(size_t *) buffer, *(size_t *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003066 }
3067 else
3068 rv = VPPCOM_EINVAL;
3069 break;
3070
3071 case VPPCOM_ATTR_SET_RX_FIFO_LEN:
3072 if (buffer && buflen && (*buflen == sizeof (u32)))
3073 {
3074 /* VPP-TBD */
3075 session->rcvbuf_size = *(u32 *) buffer;
Florin Coras5e062572019-03-14 19:07:51 -07003076 VDBG (2, "VPPCOM_ATTR_SET_RX_FIFO_LEN: %u (0x%x), buflen %d,"
3077 " #VPP-TBD#", session->sndbuf_size, session->sndbuf_size,
3078 *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003079 }
3080 else
3081 rv = VPPCOM_EINVAL;
3082 break;
3083
3084 case VPPCOM_ATTR_GET_REUSEADDR:
3085 if (buffer && buflen && (*buflen >= sizeof (int)))
3086 {
3087 /* VPP-TBD */
3088 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
3089 VCL_SESS_ATTR_REUSEADDR);
3090 *buflen = sizeof (int);
3091
Florin Coras5e062572019-03-14 19:07:51 -07003092 VDBG (2, "VPPCOM_ATTR_GET_REUSEADDR: %d, buflen %d, #VPP-TBD#",
3093 *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003094 }
3095 else
3096 rv = VPPCOM_EINVAL;
3097 break;
3098
Stevenb5a11602017-10-11 09:59:30 -07003099 case VPPCOM_ATTR_SET_REUSEADDR:
Dave Wallace048b1d62018-01-03 22:24:41 -05003100 if (buffer && buflen && (*buflen == sizeof (int)) &&
3101 !VCL_SESS_ATTR_TEST (session->attr, VCL_SESS_ATTR_LISTEN))
3102 {
3103 /* VPP-TBD */
3104 if (*(int *) buffer)
3105 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_REUSEADDR);
3106 else
3107 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_REUSEADDR);
3108
Florin Coras5e062572019-03-14 19:07:51 -07003109 VDBG (2, "VPPCOM_ATTR_SET_REUSEADDR: %d, buflen %d, #VPP-TBD#",
3110 VCL_SESS_ATTR_TEST (session->attr, VCL_SESS_ATTR_REUSEADDR),
3111 *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003112 }
3113 else
3114 rv = VPPCOM_EINVAL;
3115 break;
3116
3117 case VPPCOM_ATTR_GET_REUSEPORT:
3118 if (buffer && buflen && (*buflen >= sizeof (int)))
3119 {
3120 /* VPP-TBD */
3121 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
3122 VCL_SESS_ATTR_REUSEPORT);
3123 *buflen = sizeof (int);
3124
Florin Coras5e062572019-03-14 19:07:51 -07003125 VDBG (2, "VPPCOM_ATTR_GET_REUSEPORT: %d, buflen %d, #VPP-TBD#",
3126 *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003127 }
3128 else
3129 rv = VPPCOM_EINVAL;
3130 break;
3131
3132 case VPPCOM_ATTR_SET_REUSEPORT:
3133 if (buffer && buflen && (*buflen == sizeof (int)) &&
3134 !VCL_SESS_ATTR_TEST (session->attr, VCL_SESS_ATTR_LISTEN))
3135 {
3136 /* VPP-TBD */
3137 if (*(int *) buffer)
3138 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_REUSEPORT);
3139 else
3140 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_REUSEPORT);
3141
Florin Coras5e062572019-03-14 19:07:51 -07003142 VDBG (2, "VPPCOM_ATTR_SET_REUSEPORT: %d, buflen %d, #VPP-TBD#",
3143 VCL_SESS_ATTR_TEST (session->attr, VCL_SESS_ATTR_REUSEPORT),
3144 *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003145 }
3146 else
3147 rv = VPPCOM_EINVAL;
3148 break;
3149
3150 case VPPCOM_ATTR_GET_BROADCAST:
3151 if (buffer && buflen && (*buflen >= sizeof (int)))
3152 {
3153 /* VPP-TBD */
3154 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
3155 VCL_SESS_ATTR_BROADCAST);
3156 *buflen = sizeof (int);
3157
Florin Coras5e062572019-03-14 19:07:51 -07003158 VDBG (2, "VPPCOM_ATTR_GET_BROADCAST: %d, buflen %d, #VPP-TBD#",
3159 *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003160 }
3161 else
3162 rv = VPPCOM_EINVAL;
Stevenb5a11602017-10-11 09:59:30 -07003163 break;
3164
3165 case VPPCOM_ATTR_SET_BROADCAST:
Dave Wallace048b1d62018-01-03 22:24:41 -05003166 if (buffer && buflen && (*buflen == sizeof (int)))
3167 {
3168 /* VPP-TBD */
3169 if (*(int *) buffer)
3170 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_BROADCAST);
3171 else
3172 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_BROADCAST);
3173
Florin Coras5e062572019-03-14 19:07:51 -07003174 VDBG (2, "VPPCOM_ATTR_SET_BROADCAST: %d, buflen %d, #VPP-TBD#",
3175 VCL_SESS_ATTR_TEST (session->attr, VCL_SESS_ATTR_BROADCAST),
3176 *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003177 }
3178 else
3179 rv = VPPCOM_EINVAL;
3180 break;
3181
3182 case VPPCOM_ATTR_GET_V6ONLY:
3183 if (buffer && buflen && (*buflen >= sizeof (int)))
3184 {
3185 /* VPP-TBD */
3186 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
3187 VCL_SESS_ATTR_V6ONLY);
3188 *buflen = sizeof (int);
3189
Florin Coras5e062572019-03-14 19:07:51 -07003190 VDBG (2, "VPPCOM_ATTR_GET_V6ONLY: %d, buflen %d, #VPP-TBD#",
3191 *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003192 }
3193 else
3194 rv = VPPCOM_EINVAL;
Stevenb5a11602017-10-11 09:59:30 -07003195 break;
3196
3197 case VPPCOM_ATTR_SET_V6ONLY:
Dave Wallace048b1d62018-01-03 22:24:41 -05003198 if (buffer && buflen && (*buflen == sizeof (int)))
3199 {
3200 /* VPP-TBD */
3201 if (*(int *) buffer)
3202 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_V6ONLY);
3203 else
3204 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_V6ONLY);
3205
Florin Coras5e062572019-03-14 19:07:51 -07003206 VDBG (2, "VPPCOM_ATTR_SET_V6ONLY: %d, buflen %d, #VPP-TBD#",
3207 VCL_SESS_ATTR_TEST (session->attr, VCL_SESS_ATTR_V6ONLY),
3208 *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003209 }
3210 else
3211 rv = VPPCOM_EINVAL;
3212 break;
3213
3214 case VPPCOM_ATTR_GET_KEEPALIVE:
3215 if (buffer && buflen && (*buflen >= sizeof (int)))
3216 {
3217 /* VPP-TBD */
3218 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
3219 VCL_SESS_ATTR_KEEPALIVE);
3220 *buflen = sizeof (int);
3221
Florin Coras5e062572019-03-14 19:07:51 -07003222 VDBG (2, "VPPCOM_ATTR_GET_KEEPALIVE: %d, buflen %d, #VPP-TBD#",
3223 *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003224 }
3225 else
3226 rv = VPPCOM_EINVAL;
Stevenb5a11602017-10-11 09:59:30 -07003227 break;
Stevenbccd3392017-10-12 20:42:21 -07003228
3229 case VPPCOM_ATTR_SET_KEEPALIVE:
Dave Wallace048b1d62018-01-03 22:24:41 -05003230 if (buffer && buflen && (*buflen == sizeof (int)))
3231 {
3232 /* VPP-TBD */
3233 if (*(int *) buffer)
3234 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_KEEPALIVE);
3235 else
3236 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_KEEPALIVE);
3237
Florin Coras5e062572019-03-14 19:07:51 -07003238 VDBG (2, "VPPCOM_ATTR_SET_KEEPALIVE: %d, buflen %d, #VPP-TBD#",
3239 VCL_SESS_ATTR_TEST (session->attr, VCL_SESS_ATTR_KEEPALIVE),
3240 *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003241 }
3242 else
3243 rv = VPPCOM_EINVAL;
3244 break;
3245
3246 case VPPCOM_ATTR_GET_TCP_NODELAY:
3247 if (buffer && buflen && (*buflen >= sizeof (int)))
3248 {
3249 /* VPP-TBD */
3250 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
3251 VCL_SESS_ATTR_TCP_NODELAY);
3252 *buflen = sizeof (int);
3253
Florin Coras5e062572019-03-14 19:07:51 -07003254 VDBG (2, "VPPCOM_ATTR_GET_TCP_NODELAY: %d, buflen %d, #VPP-TBD#",
3255 *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003256 }
3257 else
3258 rv = VPPCOM_EINVAL;
3259 break;
3260
3261 case VPPCOM_ATTR_SET_TCP_NODELAY:
3262 if (buffer && buflen && (*buflen == sizeof (int)))
3263 {
3264 /* VPP-TBD */
3265 if (*(int *) buffer)
3266 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_TCP_NODELAY);
3267 else
3268 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_TCP_NODELAY);
3269
Florin Coras5e062572019-03-14 19:07:51 -07003270 VDBG (2, "VPPCOM_ATTR_SET_TCP_NODELAY: %d, buflen %d, #VPP-TBD#",
3271 VCL_SESS_ATTR_TEST (session->attr, VCL_SESS_ATTR_TCP_NODELAY),
3272 *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003273 }
3274 else
3275 rv = VPPCOM_EINVAL;
3276 break;
3277
3278 case VPPCOM_ATTR_GET_TCP_KEEPIDLE:
3279 if (buffer && buflen && (*buflen >= sizeof (int)))
3280 {
3281 /* VPP-TBD */
3282 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
3283 VCL_SESS_ATTR_TCP_KEEPIDLE);
3284 *buflen = sizeof (int);
3285
Florin Coras5e062572019-03-14 19:07:51 -07003286 VDBG (2, "VPPCOM_ATTR_GET_TCP_KEEPIDLE: %d, buflen %d, #VPP-TBD#",
3287 *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003288 }
3289 else
3290 rv = VPPCOM_EINVAL;
Stevenbccd3392017-10-12 20:42:21 -07003291 break;
3292
3293 case VPPCOM_ATTR_SET_TCP_KEEPIDLE:
Dave Wallace048b1d62018-01-03 22:24:41 -05003294 if (buffer && buflen && (*buflen == sizeof (int)))
3295 {
3296 /* VPP-TBD */
3297 if (*(int *) buffer)
3298 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_TCP_KEEPIDLE);
3299 else
3300 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_TCP_KEEPIDLE);
3301
Florin Coras5e062572019-03-14 19:07:51 -07003302 VDBG (2, "VPPCOM_ATTR_SET_TCP_KEEPIDLE: %d, buflen %d, #VPP-TBD#",
Florin Coras0d427d82018-06-27 03:24:07 -07003303 VCL_SESS_ATTR_TEST (session->attr,
3304 VCL_SESS_ATTR_TCP_KEEPIDLE), *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003305 }
3306 else
3307 rv = VPPCOM_EINVAL;
3308 break;
3309
3310 case VPPCOM_ATTR_GET_TCP_KEEPINTVL:
3311 if (buffer && buflen && (*buflen >= sizeof (int)))
3312 {
3313 /* VPP-TBD */
3314 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
3315 VCL_SESS_ATTR_TCP_KEEPINTVL);
3316 *buflen = sizeof (int);
3317
Florin Coras5e062572019-03-14 19:07:51 -07003318 VDBG (2, "VPPCOM_ATTR_GET_TCP_KEEPINTVL: %d, buflen %d, #VPP-TBD#",
3319 *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003320 }
3321 else
3322 rv = VPPCOM_EINVAL;
Stevenbccd3392017-10-12 20:42:21 -07003323 break;
3324
3325 case VPPCOM_ATTR_SET_TCP_KEEPINTVL:
Dave Wallace048b1d62018-01-03 22:24:41 -05003326 if (buffer && buflen && (*buflen == sizeof (int)))
3327 {
3328 /* VPP-TBD */
3329 if (*(int *) buffer)
3330 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_TCP_KEEPINTVL);
3331 else
3332 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_TCP_KEEPINTVL);
3333
Florin Coras5e062572019-03-14 19:07:51 -07003334 VDBG (2, "VPPCOM_ATTR_SET_TCP_KEEPINTVL: %d, buflen %d, #VPP-TBD#",
Florin Coras0d427d82018-06-27 03:24:07 -07003335 VCL_SESS_ATTR_TEST (session->attr,
3336 VCL_SESS_ATTR_TCP_KEEPINTVL), *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003337 }
3338 else
3339 rv = VPPCOM_EINVAL;
3340 break;
3341
3342 case VPPCOM_ATTR_GET_TCP_USER_MSS:
3343 if (buffer && buflen && (*buflen >= sizeof (u32)))
3344 {
3345 /* VPP-TBD */
3346 *(u32 *) buffer = session->user_mss;
3347 *buflen = sizeof (int);
3348
Florin Coras5e062572019-03-14 19:07:51 -07003349 VDBG (2, "VPPCOM_ATTR_GET_TCP_USER_MSS: %d, buflen %d, #VPP-TBD#",
3350 *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003351 }
3352 else
3353 rv = VPPCOM_EINVAL;
3354 break;
3355
3356 case VPPCOM_ATTR_SET_TCP_USER_MSS:
3357 if (buffer && buflen && (*buflen == sizeof (u32)))
3358 {
3359 /* VPP-TBD */
3360 session->user_mss = *(u32 *) buffer;
3361
Florin Coras5e062572019-03-14 19:07:51 -07003362 VDBG (2, "VPPCOM_ATTR_SET_TCP_USER_MSS: %u, buflen %d, #VPP-TBD#",
3363 session->user_mss, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003364 }
3365 else
3366 rv = VPPCOM_EINVAL;
Stevenbccd3392017-10-12 20:42:21 -07003367 break;
Dave Wallacee22aa742017-10-20 12:30:38 -04003368
Florin Coras7baeb712019-01-04 17:05:43 -08003369 case VPPCOM_ATTR_SET_SHUT:
3370 if (*flags == SHUT_RD || *flags == SHUT_RDWR)
3371 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_SHUT_RD);
3372 if (*flags == SHUT_WR || *flags == SHUT_RDWR)
3373 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_SHUT_WR);
3374 break;
3375
3376 case VPPCOM_ATTR_GET_SHUT:
3377 if (VCL_SESS_ATTR_TEST (session->attr, VCL_SESS_ATTR_SHUT_RD))
3378 tmp_flags = 1;
3379 if (VCL_SESS_ATTR_TEST (session->attr, VCL_SESS_ATTR_SHUT_WR))
3380 tmp_flags |= 2;
3381 if (tmp_flags == 1)
3382 *(int *) buffer = SHUT_RD;
3383 else if (tmp_flags == 2)
3384 *(int *) buffer = SHUT_WR;
3385 else if (tmp_flags == 3)
3386 *(int *) buffer = SHUT_RDWR;
3387 *buflen = sizeof (int);
3388 break;
Dave Wallacee22aa742017-10-20 12:30:38 -04003389 default:
3390 rv = VPPCOM_EINVAL;
3391 break;
Dave Wallace35830af2017-10-09 01:43:42 -04003392 }
3393
Dave Wallace35830af2017-10-09 01:43:42 -04003394 return rv;
3395}
3396
Stevenac1f96d2017-10-24 16:03:58 -07003397int
Florin Coras134a9962018-08-28 11:32:04 -07003398vppcom_session_recvfrom (uint32_t session_handle, void *buffer,
Stevenac1f96d2017-10-24 16:03:58 -07003399 uint32_t buflen, int flags, vppcom_endpt_t * ep)
3400{
Florin Coras134a9962018-08-28 11:32:04 -07003401 vcl_worker_t *wrk = vcl_worker_get_current ();
Stevenac1f96d2017-10-24 16:03:58 -07003402 int rv = VPPCOM_OK;
Florin Coras7e12d942018-06-27 14:32:43 -07003403 vcl_session_t *session = 0;
Stevenac1f96d2017-10-24 16:03:58 -07003404
3405 if (ep)
3406 {
Florin Coras134a9962018-08-28 11:32:04 -07003407 session = vcl_session_get_w_handle (wrk, session_handle);
Florin Coras070453d2018-08-24 17:04:27 -07003408 if (PREDICT_FALSE (!session))
Stevenac1f96d2017-10-24 16:03:58 -07003409 {
Florin Coras5e062572019-03-14 19:07:51 -07003410 VDBG (0, "sh 0x%llx is closed!", session_handle);
Florin Coras460dce62018-07-27 05:45:06 -07003411 return VPPCOM_EBADFD;
Stevenac1f96d2017-10-24 16:03:58 -07003412 }
Florin Coras7e12d942018-06-27 14:32:43 -07003413 ep->is_ip4 = session->transport.is_ip4;
3414 ep->port = session->transport.rmt_port;
Stevenac1f96d2017-10-24 16:03:58 -07003415 }
Steven58f464e2017-10-25 12:33:12 -07003416
3417 if (flags == 0)
Florin Coras134a9962018-08-28 11:32:04 -07003418 rv = vppcom_session_read (session_handle, buffer, buflen);
Stevenac1f96d2017-10-24 16:03:58 -07003419 else if (flags & MSG_PEEK)
Florin Coras134a9962018-08-28 11:32:04 -07003420 rv = vppcom_session_peek (session_handle, buffer, buflen);
Stevenac1f96d2017-10-24 16:03:58 -07003421 else
3422 {
Florin Corasa7a1a222018-12-30 17:11:31 -08003423 VDBG (0, "Unsupport flags for recvfrom %d", flags);
Florin Coras460dce62018-07-27 05:45:06 -07003424 return VPPCOM_EAFNOSUPPORT;
Stevenac1f96d2017-10-24 16:03:58 -07003425 }
3426
Florin Coras99368312018-08-02 10:45:44 -07003427 if (ep)
3428 {
3429 if (session->transport.is_ip4)
Dave Barach178cf492018-11-13 16:34:13 -05003430 clib_memcpy_fast (ep->ip, &session->transport.rmt_ip.ip4,
3431 sizeof (ip4_address_t));
Florin Coras99368312018-08-02 10:45:44 -07003432 else
Dave Barach178cf492018-11-13 16:34:13 -05003433 clib_memcpy_fast (ep->ip, &session->transport.rmt_ip.ip6,
3434 sizeof (ip6_address_t));
Florin Coras99368312018-08-02 10:45:44 -07003435 }
Florin Coras460dce62018-07-27 05:45:06 -07003436
Stevenac1f96d2017-10-24 16:03:58 -07003437 return rv;
3438}
3439
3440int
Florin Coras134a9962018-08-28 11:32:04 -07003441vppcom_session_sendto (uint32_t session_handle, void *buffer,
Stevenac1f96d2017-10-24 16:03:58 -07003442 uint32_t buflen, int flags, vppcom_endpt_t * ep)
3443{
Dave Wallace617dffa2017-10-26 14:47:06 -04003444 if (!buffer)
3445 return VPPCOM_EINVAL;
3446
3447 if (ep)
3448 {
3449 // TBD
3450 return VPPCOM_EINVAL;
3451 }
3452
3453 if (flags)
3454 {
3455 // TBD check the flags and do the right thing
Florin Coras5e062572019-03-14 19:07:51 -07003456 VDBG (2, "handling flags 0x%u (%d) not implemented yet.", flags, flags);
Dave Wallace617dffa2017-10-26 14:47:06 -04003457 }
3458
Florin Coras42ceddb2018-12-12 10:56:01 -08003459 return (vppcom_session_write_inline (session_handle, buffer, buflen, 1));
Stevenac1f96d2017-10-24 16:03:58 -07003460}
3461
Dave Wallace048b1d62018-01-03 22:24:41 -05003462int
3463vppcom_poll (vcl_poll_t * vp, uint32_t n_sids, double wait_for_time)
3464{
Florin Coras134a9962018-08-28 11:32:04 -07003465 vcl_worker_t *wrk = vcl_worker_get_current ();
3466 f64 timeout = clib_time_now (&wrk->clib_time) + wait_for_time;
Dave Wallace048b1d62018-01-03 22:24:41 -05003467 u32 i, keep_trying = 1;
Florin Coras6917b942018-11-13 22:44:54 -08003468 svm_msg_q_msg_t msg;
3469 session_event_t *e;
Dave Wallace048b1d62018-01-03 22:24:41 -05003470 int rv, num_ev = 0;
3471
Florin Coras5e062572019-03-14 19:07:51 -07003472 VDBG (3, "vp %p, nsids %u, wait_for_time %f", vp, n_sids, wait_for_time);
Dave Wallace048b1d62018-01-03 22:24:41 -05003473
3474 if (!vp)
3475 return VPPCOM_EFAULT;
3476
3477 do
3478 {
Florin Coras7e12d942018-06-27 14:32:43 -07003479 vcl_session_t *session;
Dave Wallace048b1d62018-01-03 22:24:41 -05003480
Florin Coras6917b942018-11-13 22:44:54 -08003481 /* Dequeue all events and drop all unhandled io events */
3482 while (svm_msg_q_sub (wrk->app_event_queue, &msg, SVM_Q_NOWAIT, 0) == 0)
3483 {
3484 e = svm_msg_q_msg_data (wrk->app_event_queue, &msg);
3485 vcl_handle_mq_event (wrk, e);
3486 svm_msg_q_free_msg (wrk->app_event_queue, &msg);
3487 }
3488 vec_reset_length (wrk->unhandled_evts_vector);
3489
Dave Wallace048b1d62018-01-03 22:24:41 -05003490 for (i = 0; i < n_sids; i++)
3491 {
Florin Coras7baeb712019-01-04 17:05:43 -08003492 session = vcl_session_get (wrk, vp[i].sh);
Florin Coras070453d2018-08-24 17:04:27 -07003493 if (!session)
Florin Coras6917b942018-11-13 22:44:54 -08003494 {
3495 vp[i].revents = POLLHUP;
3496 num_ev++;
3497 continue;
3498 }
Dave Wallace048b1d62018-01-03 22:24:41 -05003499
Florin Coras6917b942018-11-13 22:44:54 -08003500 vp[i].revents = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -05003501
3502 if (POLLIN & vp[i].events)
3503 {
Florin Coras0ef8ef22019-01-18 08:37:13 -08003504 rv = vcl_session_read_ready (session);
Dave Wallace048b1d62018-01-03 22:24:41 -05003505 if (rv > 0)
3506 {
Florin Coras6917b942018-11-13 22:44:54 -08003507 vp[i].revents |= POLLIN;
Dave Wallace048b1d62018-01-03 22:24:41 -05003508 num_ev++;
3509 }
3510 else if (rv < 0)
3511 {
3512 switch (rv)
3513 {
3514 case VPPCOM_ECONNRESET:
Florin Coras6917b942018-11-13 22:44:54 -08003515 vp[i].revents = POLLHUP;
Dave Wallace048b1d62018-01-03 22:24:41 -05003516 break;
3517
3518 default:
Florin Coras6917b942018-11-13 22:44:54 -08003519 vp[i].revents = POLLERR;
Dave Wallace048b1d62018-01-03 22:24:41 -05003520 break;
3521 }
3522 num_ev++;
3523 }
3524 }
3525
3526 if (POLLOUT & vp[i].events)
3527 {
Florin Coras0ef8ef22019-01-18 08:37:13 -08003528 rv = vcl_session_write_ready (session);
Dave Wallace048b1d62018-01-03 22:24:41 -05003529 if (rv > 0)
3530 {
Florin Coras6917b942018-11-13 22:44:54 -08003531 vp[i].revents |= POLLOUT;
Dave Wallace048b1d62018-01-03 22:24:41 -05003532 num_ev++;
3533 }
3534 else if (rv < 0)
3535 {
3536 switch (rv)
3537 {
3538 case VPPCOM_ECONNRESET:
Florin Coras6917b942018-11-13 22:44:54 -08003539 vp[i].revents = POLLHUP;
Dave Wallace048b1d62018-01-03 22:24:41 -05003540 break;
3541
3542 default:
Florin Coras6917b942018-11-13 22:44:54 -08003543 vp[i].revents = POLLERR;
Dave Wallace048b1d62018-01-03 22:24:41 -05003544 break;
3545 }
3546 num_ev++;
3547 }
3548 }
3549
Dave Wallace7e607a72018-06-18 18:41:32 -04003550 if (0) // Note "done:" label used by VCL_SESSION_LOCK_AND_GET()
Dave Wallace048b1d62018-01-03 22:24:41 -05003551 {
Florin Coras6917b942018-11-13 22:44:54 -08003552 vp[i].revents = POLLNVAL;
Dave Wallace048b1d62018-01-03 22:24:41 -05003553 num_ev++;
3554 }
3555 }
3556 if (wait_for_time != -1)
Florin Coras134a9962018-08-28 11:32:04 -07003557 keep_trying = (clib_time_now (&wrk->clib_time) <= timeout) ? 1 : 0;
Dave Wallace048b1d62018-01-03 22:24:41 -05003558 }
3559 while ((num_ev == 0) && keep_trying);
3560
Dave Wallace048b1d62018-01-03 22:24:41 -05003561 return num_ev;
3562}
3563
Florin Coras99368312018-08-02 10:45:44 -07003564int
3565vppcom_mq_epoll_fd (void)
3566{
Florin Coras134a9962018-08-28 11:32:04 -07003567 vcl_worker_t *wrk = vcl_worker_get_current ();
3568 return wrk->mqs_epfd;
3569}
3570
3571int
Florin Coras30e79c22019-01-02 19:31:22 -08003572vppcom_session_index (vcl_session_handle_t session_handle)
Florin Coras134a9962018-08-28 11:32:04 -07003573{
3574 return session_handle & 0xFFFFFF;
3575}
3576
3577int
Florin Coras30e79c22019-01-02 19:31:22 -08003578vppcom_session_worker (vcl_session_handle_t session_handle)
3579{
3580 return session_handle >> 24;
3581}
3582
3583int
Florin Coras134a9962018-08-28 11:32:04 -07003584vppcom_worker_register (void)
3585{
Florin Coras47c40e22018-11-26 17:01:36 -08003586 if (!vcl_worker_alloc_and_init ())
3587 return VPPCOM_EEXIST;
3588
3589 if (vcl_worker_set_bapi ())
3590 return VPPCOM_EEXIST;
3591
3592 if (vcl_worker_register_with_vpp ())
3593 return VPPCOM_EEXIST;
3594
3595 return VPPCOM_OK;
Florin Coras99368312018-08-02 10:45:44 -07003596}
3597
Florin Coras369db832019-07-08 12:34:45 -07003598void
3599vppcom_worker_unregister (void)
3600{
3601 vcl_worker_cleanup (vcl_worker_get_current (), 1 /* notify vpp */ );
3602 vcl_set_worker_index (~0);
3603}
3604
Florin Corasdfe4cf42018-11-28 22:13:45 -08003605int
3606vppcom_worker_index (void)
3607{
3608 return vcl_get_worker_index ();
3609}
3610
Florin Corase0982e52019-01-25 13:19:56 -08003611int
3612vppcom_worker_mqs_epfd (void)
3613{
3614 vcl_worker_t *wrk = vcl_worker_get_current ();
3615 if (!vcm->cfg.use_mq_eventfd)
3616 return -1;
3617 return wrk->mqs_epfd;
3618}
3619
Nathan Skrzypczak9fd99622019-05-16 14:38:44 +02003620int
3621vppcom_session_is_connectable_listener (uint32_t session_handle)
3622{
3623 vcl_session_t *session;
3624 vcl_worker_t *wrk = vcl_worker_get_current ();
3625 session = vcl_session_get_w_handle (wrk, session_handle);
3626 if (!session)
3627 return VPPCOM_EBADFD;
3628 return vcl_session_is_connectable_listener (wrk, session);
3629}
3630
3631int
3632vppcom_session_listener (uint32_t session_handle)
3633{
3634 vcl_worker_t *wrk = vcl_worker_get_current ();
3635 vcl_session_t *listen_session, *session;
3636 session = vcl_session_get_w_handle (wrk, session_handle);
3637 if (!session)
3638 return VPPCOM_EBADFD;
3639 if (session->listener_index == VCL_INVALID_SESSION_INDEX)
3640 return VPPCOM_EBADFD;
3641 listen_session = vcl_session_get_w_handle (wrk, session->listener_index);
3642 if (!listen_session)
3643 return VPPCOM_EBADFD;
3644 return vcl_session_handle (listen_session);
3645}
3646
3647int
3648vppcom_session_n_accepted (uint32_t session_handle)
3649{
3650 vcl_worker_t *wrk = vcl_worker_get_current ();
3651 vcl_session_t *session = vcl_session_get_w_handle (wrk, session_handle);
3652 if (!session)
3653 return VPPCOM_EBADFD;
3654 return session->n_accepted_sessions;
3655}
3656
Dave Wallacee22aa742017-10-20 12:30:38 -04003657/*
3658 * fd.io coding-style-patch-verification: ON
3659 *
3660 * Local Variables:
3661 * eval: (c-set-style "gnu")
3662 * End:
3663 */