blob: 1991e3e72774ea05bcf0cb290f50793e0b54d04d [file] [log] [blame]
Dave Wallace543852a2017-08-03 02:11:34 -04001/*
Dave Wallace33e002b2017-09-06 01:20:02 -04002 * Copyright (c) 2017 Cisco and/or its affiliates.
Dave Wallace543852a2017-08-03 02:11:34 -04003 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this
5 * You may obtain a copy of the License at:
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include <stdio.h>
17#include <stdlib.h>
Dave Wallace543852a2017-08-03 02:11:34 -040018#include <svm/svm_fifo_segment.h>
Dave Wallace5c7cf1c2017-10-24 04:12:18 -040019#include <vcl/vppcom.h>
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -080020#include <vcl/vcl_event.h>
Florin Coras0d427d82018-06-27 03:24:07 -070021#include <vcl/vcl_debug.h>
Florin Coras697faea2018-06-27 17:10:49 -070022#include <vcl/vcl_private.h>
Dave Wallace7e607a72018-06-18 18:41:32 -040023
Florin Coras134a9962018-08-28 11:32:04 -070024__thread uword __vcl_worker_index = ~0;
25
Florin Coras54693d22018-07-17 10:46:29 -070026static u8 not_ready;
27
28void
29sigsegv_signal (int signum)
30{
31 not_ready = 1;
32}
33
34static void
35vcl_wait_for_memory (void *mem)
36{
37 u8 __clib_unused test;
Florin Coras460dce62018-07-27 05:45:06 -070038 if (vcm->mounting_segment)
39 {
40 while (vcm->mounting_segment)
41 ;
42 return;
43 }
Florin Coras54693d22018-07-17 10:46:29 -070044 if (1 || vcm->debug)
45 {
Florin Coras460dce62018-07-27 05:45:06 -070046 usleep (1e5);
Florin Coras54693d22018-07-17 10:46:29 -070047 return;
48 }
49 if (signal (SIGSEGV, sigsegv_signal))
50 {
51 perror ("signal()");
52 return;
53 }
54 not_ready = 0;
55
56again:
57 test = *(u8 *) mem;
58 if (not_ready)
59 {
60 not_ready = 0;
61 usleep (1);
62 goto again;
63 }
64
65 signal (SIGSEGV, SIG_DFL);
66}
67
Florin Coras697faea2018-06-27 17:10:49 -070068const char *
Dave Wallace543852a2017-08-03 02:11:34 -040069vppcom_session_state_str (session_state_t state)
70{
71 char *st;
72
73 switch (state)
74 {
75 case STATE_START:
76 st = "STATE_START";
77 break;
78
79 case STATE_CONNECT:
80 st = "STATE_CONNECT";
81 break;
82
83 case STATE_LISTEN:
84 st = "STATE_LISTEN";
85 break;
86
87 case STATE_ACCEPT:
88 st = "STATE_ACCEPT";
89 break;
90
Dave Wallace4878cbe2017-11-21 03:45:09 -050091 case STATE_CLOSE_ON_EMPTY:
92 st = "STATE_CLOSE_ON_EMPTY";
93 break;
94
Dave Wallace543852a2017-08-03 02:11:34 -040095 case STATE_DISCONNECT:
96 st = "STATE_DISCONNECT";
97 break;
98
99 case STATE_FAILED:
100 st = "STATE_FAILED";
101 break;
102
103 default:
104 st = "UNKNOWN_STATE";
105 break;
106 }
107
108 return st;
109}
110
Dave Wallace543852a2017-08-03 02:11:34 -0400111u8 *
112format_ip4_address (u8 * s, va_list * args)
113{
114 u8 *a = va_arg (*args, u8 *);
115 return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
116}
117
118u8 *
119format_ip6_address (u8 * s, va_list * args)
120{
121 ip6_address_t *a = va_arg (*args, ip6_address_t *);
122 u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
123
124 i_max_n_zero = ARRAY_LEN (a->as_u16);
125 max_n_zeros = 0;
126 i_first_zero = i_max_n_zero;
127 n_zeros = 0;
128 for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
129 {
130 u32 is_zero = a->as_u16[i] == 0;
131 if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
132 {
133 i_first_zero = i;
134 n_zeros = 0;
135 }
136 n_zeros += is_zero;
137 if ((!is_zero && n_zeros > max_n_zeros)
138 || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
139 {
140 i_max_n_zero = i_first_zero;
141 max_n_zeros = n_zeros;
142 i_first_zero = ARRAY_LEN (a->as_u16);
143 n_zeros = 0;
144 }
145 }
146
147 last_double_colon = 0;
148 for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
149 {
150 if (i == i_max_n_zero && max_n_zeros > 1)
151 {
152 s = format (s, "::");
153 i += max_n_zeros - 1;
154 last_double_colon = 1;
155 }
156 else
157 {
158 s = format (s, "%s%x",
159 (last_double_colon || i == 0) ? "" : ":",
160 clib_net_to_host_u16 (a->as_u16[i]));
161 last_double_colon = 0;
162 }
163 }
164
165 return s;
166}
167
168/* Format an IP46 address. */
169u8 *
170format_ip46_address (u8 * s, va_list * args)
171{
172 ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
173 ip46_type_t type = va_arg (*args, ip46_type_t);
174 int is_ip4 = 1;
175
176 switch (type)
177 {
178 case IP46_TYPE_ANY:
179 is_ip4 = ip46_address_is_ip4 (ip46);
180 break;
181 case IP46_TYPE_IP4:
182 is_ip4 = 1;
183 break;
184 case IP46_TYPE_IP6:
185 is_ip4 = 0;
186 break;
187 }
188
189 return is_ip4 ?
190 format (s, "%U", format_ip4_address, &ip46->ip4) :
191 format (s, "%U", format_ip6_address, &ip46->ip6);
192}
193
Florin Coras697faea2018-06-27 17:10:49 -0700194/*
195 * VPPCOM Utility Functions
196 */
197
Florin Coras697faea2018-06-27 17:10:49 -0700198
Florin Corasc9fbd662018-08-24 12:59:56 -0700199static svm_msg_q_t *
Florin Coras134a9962018-08-28 11:32:04 -0700200vcl_session_vpp_evt_q (vcl_worker_t * wrk, vcl_session_t * s)
Florin Corasc9fbd662018-08-24 12:59:56 -0700201{
202 if (vcl_session_is_ct (s))
Florin Coras134a9962018-08-28 11:32:04 -0700203 return wrk->vpp_event_queues[0];
Florin Corasc9fbd662018-08-24 12:59:56 -0700204 else
Florin Coras134a9962018-08-28 11:32:04 -0700205 return wrk->vpp_event_queues[s->tx_fifo->master_thread_index];
Florin Corasc9fbd662018-08-24 12:59:56 -0700206}
207
Florin Coras54693d22018-07-17 10:46:29 -0700208static void
209vcl_send_session_accepted_reply (svm_msg_q_t * mq, u32 context,
210 session_handle_t handle, int retval)
211{
212 app_session_evt_t _app_evt, *app_evt = &_app_evt;
213 session_accepted_reply_msg_t *rmp;
214 app_alloc_ctrl_evt_to_vpp (mq, app_evt, SESSION_CTRL_EVT_ACCEPTED_REPLY);
215 rmp = (session_accepted_reply_msg_t *) app_evt->evt->data;
216 rmp->handle = handle;
217 rmp->context = context;
218 rmp->retval = retval;
219 app_send_ctrl_evt_to_vpp (mq, app_evt);
220}
221
Florin Coras99368312018-08-02 10:45:44 -0700222static void
223vcl_send_session_disconnected_reply (svm_msg_q_t * mq, u32 context,
224 session_handle_t handle, int retval)
225{
226 app_session_evt_t _app_evt, *app_evt = &_app_evt;
227 session_disconnected_reply_msg_t *rmp;
228 app_alloc_ctrl_evt_to_vpp (mq, app_evt,
229 SESSION_CTRL_EVT_DISCONNECTED_REPLY);
230 rmp = (session_disconnected_reply_msg_t *) app_evt->evt->data;
231 rmp->handle = handle;
232 rmp->context = context;
233 rmp->retval = retval;
234 app_send_ctrl_evt_to_vpp (mq, app_evt);
235}
236
Florin Corasc9fbd662018-08-24 12:59:56 -0700237static void
238vcl_send_session_reset_reply (svm_msg_q_t * mq, u32 context,
239 session_handle_t handle, int retval)
240{
241 app_session_evt_t _app_evt, *app_evt = &_app_evt;
242 session_reset_reply_msg_t *rmp;
243 app_alloc_ctrl_evt_to_vpp (mq, app_evt, SESSION_CTRL_EVT_RESET_REPLY);
244 rmp = (session_reset_reply_msg_t *) app_evt->evt->data;
245 rmp->handle = handle;
246 rmp->context = context;
247 rmp->retval = retval;
248 app_send_ctrl_evt_to_vpp (mq, app_evt);
249}
250
Florin Coras54693d22018-07-17 10:46:29 -0700251static u32
Florin Coras134a9962018-08-28 11:32:04 -0700252vcl_session_accepted_handler (vcl_worker_t * wrk, session_accepted_msg_t * mp)
Florin Coras54693d22018-07-17 10:46:29 -0700253{
254 vcl_session_t *session, *listen_session;
255 svm_fifo_t *rx_fifo, *tx_fifo;
Florin Coras134a9962018-08-28 11:32:04 -0700256 u32 vpp_wrk_index;
Florin Coras99368312018-08-02 10:45:44 -0700257 svm_msg_q_t *evt_q;
Florin Coras54693d22018-07-17 10:46:29 -0700258
Florin Coras134a9962018-08-28 11:32:04 -0700259 session = vcl_session_alloc (wrk);
Florin Coras99368312018-08-02 10:45:44 -0700260
Florin Coras134a9962018-08-28 11:32:04 -0700261 listen_session = vcl_session_table_lookup_listener (wrk,
262 mp->listener_handle);
Florin Coras54693d22018-07-17 10:46:29 -0700263 if (!listen_session)
264 {
265 svm_msg_q_t *evt_q;
266 evt_q = uword_to_pointer (mp->vpp_event_queue_address, svm_msg_q_t *);
267 clib_warning ("VCL<%d>: ERROR: couldn't find listen session: "
268 "unknown vpp listener handle %llx",
269 getpid (), mp->listener_handle);
270 vcl_send_session_accepted_reply (evt_q, mp->context, mp->handle,
271 VNET_API_ERROR_INVALID_ARGUMENT);
Florin Coras134a9962018-08-28 11:32:04 -0700272 vcl_session_free (wrk, session);
Florin Coras54693d22018-07-17 10:46:29 -0700273 return VCL_INVALID_SESSION_INDEX;
274 }
275
Florin Coras54693d22018-07-17 10:46:29 -0700276 rx_fifo = uword_to_pointer (mp->server_rx_fifo, svm_fifo_t *);
277 tx_fifo = uword_to_pointer (mp->server_tx_fifo, svm_fifo_t *);
278
279 if (mp->server_event_queue_address)
280 {
281 session->vpp_evt_q = uword_to_pointer (mp->client_event_queue_address,
282 svm_msg_q_t *);
283 session->our_evt_q = uword_to_pointer (mp->server_event_queue_address,
284 svm_msg_q_t *);
285 vcl_wait_for_memory (session->vpp_evt_q);
Florin Coras134a9962018-08-28 11:32:04 -0700286 rx_fifo->master_session_index = session->session_index;
287 tx_fifo->master_session_index = session->session_index;
288 vec_validate (wrk->vpp_event_queues, 0);
Florin Coras99368312018-08-02 10:45:44 -0700289 evt_q = uword_to_pointer (mp->vpp_event_queue_address, svm_msg_q_t *);
Florin Coras134a9962018-08-28 11:32:04 -0700290 wrk->vpp_event_queues[0] = evt_q;
Florin Coras54693d22018-07-17 10:46:29 -0700291 }
292 else
293 {
294 session->vpp_evt_q = uword_to_pointer (mp->vpp_event_queue_address,
295 svm_msg_q_t *);
Florin Coras134a9962018-08-28 11:32:04 -0700296 rx_fifo->client_session_index = session->session_index;
297 tx_fifo->client_session_index = session->session_index;
Florin Coras99368312018-08-02 10:45:44 -0700298
299 vpp_wrk_index = tx_fifo->master_thread_index;
Florin Coras134a9962018-08-28 11:32:04 -0700300 vec_validate (wrk->vpp_event_queues, vpp_wrk_index);
301 wrk->vpp_event_queues[vpp_wrk_index] = session->vpp_evt_q;
Florin Coras54693d22018-07-17 10:46:29 -0700302 }
303
304 session->vpp_handle = mp->handle;
305 session->client_context = mp->context;
306 session->rx_fifo = rx_fifo;
307 session->tx_fifo = tx_fifo;
308
309 session->session_state = STATE_ACCEPT;
310 session->transport.rmt_port = mp->port;
311 session->transport.is_ip4 = mp->is_ip4;
312 clib_memcpy (&session->transport.rmt_ip, mp->ip, sizeof (ip46_address_t));
313
Florin Coras134a9962018-08-28 11:32:04 -0700314 vcl_session_table_add_vpp_handle (wrk, mp->handle, session->session_index);
Florin Coras54693d22018-07-17 10:46:29 -0700315 session->transport.lcl_port = listen_session->transport.lcl_port;
316 session->transport.lcl_ip = listen_session->transport.lcl_ip;
Florin Coras460dce62018-07-27 05:45:06 -0700317 session->session_type = listen_session->session_type;
318 session->is_dgram = session->session_type == VPPCOM_PROTO_UDP;
Florin Coras54693d22018-07-17 10:46:29 -0700319
320 VDBG (1, "VCL<%d>: vpp handle 0x%llx, sid %u: client accept request from %s"
Florin Coras134a9962018-08-28 11:32:04 -0700321 " address %U port %d queue %p!", getpid (), mp->handle,
322 session->session_index,
Florin Coras54693d22018-07-17 10:46:29 -0700323 mp->is_ip4 ? "IPv4" : "IPv6", format_ip46_address, &mp->ip,
324 mp->is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6,
325 clib_net_to_host_u16 (mp->port), session->vpp_evt_q);
326 vcl_evt (VCL_EVT_ACCEPT, session, listen_session, session_index);
327
Florin Coras134a9962018-08-28 11:32:04 -0700328 return session->session_index;
Florin Coras54693d22018-07-17 10:46:29 -0700329}
330
331static u32
Florin Coras134a9962018-08-28 11:32:04 -0700332vcl_session_connected_handler (vcl_worker_t * wrk,
333 session_connected_msg_t * mp)
Florin Coras54693d22018-07-17 10:46:29 -0700334{
Florin Coras99368312018-08-02 10:45:44 -0700335 u32 session_index, vpp_wrk_index;
Florin Coras54693d22018-07-17 10:46:29 -0700336 svm_fifo_t *rx_fifo, *tx_fifo;
Florin Coras99368312018-08-02 10:45:44 -0700337 vcl_session_t *session = 0;
338 svm_msg_q_t *evt_q;
Florin Coras54693d22018-07-17 10:46:29 -0700339
340 session_index = mp->context;
Florin Coras134a9962018-08-28 11:32:04 -0700341 session = vcl_session_get (wrk, session_index);
Florin Coras070453d2018-08-24 17:04:27 -0700342 if (!session)
343 {
344 clib_warning ("[%s] ERROR: vpp handle 0x%llx, sid %u: "
345 "Invalid session index (%u)!",
346 getpid (), mp->handle, session_index);
347 return VCL_INVALID_SESSION_INDEX;
348 }
Florin Coras54693d22018-07-17 10:46:29 -0700349 if (mp->retval)
350 {
Florin Coras070453d2018-08-24 17:04:27 -0700351 clib_warning ("VCL<%d>: ERROR: sid %u: connect failed! %U", getpid (),
352 mp->handle, session_index, format_api_error,
353 ntohl (mp->retval));
354 session->session_state = STATE_FAILED;
355 session->vpp_handle = mp->handle;
356 return session_index;
Florin Coras54693d22018-07-17 10:46:29 -0700357 }
358
Florin Coras460dce62018-07-27 05:45:06 -0700359 rx_fifo = uword_to_pointer (mp->server_rx_fifo, svm_fifo_t *);
360 tx_fifo = uword_to_pointer (mp->server_tx_fifo, svm_fifo_t *);
361 vcl_wait_for_memory (rx_fifo);
362 rx_fifo->client_session_index = session_index;
363 tx_fifo->client_session_index = session_index;
364
Florin Coras54693d22018-07-17 10:46:29 -0700365 if (mp->client_event_queue_address)
366 {
367 session->vpp_evt_q = uword_to_pointer (mp->server_event_queue_address,
368 svm_msg_q_t *);
369 session->our_evt_q = uword_to_pointer (mp->client_event_queue_address,
370 svm_msg_q_t *);
Florin Coras99368312018-08-02 10:45:44 -0700371
Florin Coras134a9962018-08-28 11:32:04 -0700372 vec_validate (wrk->vpp_event_queues, 0);
Florin Coras99368312018-08-02 10:45:44 -0700373 evt_q = uword_to_pointer (mp->vpp_event_queue_address, svm_msg_q_t *);
Florin Coras134a9962018-08-28 11:32:04 -0700374 wrk->vpp_event_queues[0] = evt_q;
Florin Coras54693d22018-07-17 10:46:29 -0700375 }
376 else
Florin Coras99368312018-08-02 10:45:44 -0700377 {
378 session->vpp_evt_q = uword_to_pointer (mp->vpp_event_queue_address,
379 svm_msg_q_t *);
380 vpp_wrk_index = tx_fifo->master_thread_index;
Florin Coras134a9962018-08-28 11:32:04 -0700381 vec_validate (wrk->vpp_event_queues, vpp_wrk_index);
382 wrk->vpp_event_queues[vpp_wrk_index] = session->vpp_evt_q;
Florin Coras99368312018-08-02 10:45:44 -0700383 }
Florin Coras54693d22018-07-17 10:46:29 -0700384
Florin Coras54693d22018-07-17 10:46:29 -0700385 session->rx_fifo = rx_fifo;
386 session->tx_fifo = tx_fifo;
387 session->vpp_handle = mp->handle;
388 session->transport.is_ip4 = mp->is_ip4;
389 clib_memcpy (&session->transport.lcl_ip, mp->lcl_ip,
390 sizeof (session->transport.lcl_ip));
391 session->transport.lcl_port = mp->lcl_port;
392 session->session_state = STATE_CONNECT;
393
394 /* Add it to lookup table */
Florin Coras134a9962018-08-28 11:32:04 -0700395 hash_set (wrk->session_index_by_vpp_handles, mp->handle, session_index);
Florin Coras54693d22018-07-17 10:46:29 -0700396
397 VDBG (1, "VCL<%d>: vpp handle 0x%llx, sid %u: connect succeeded! "
398 "session_rx_fifo %p, refcnt %d, session_tx_fifo %p, refcnt %d",
399 getpid (), mp->handle, session_index, session->rx_fifo,
400 session->rx_fifo->refcnt, session->tx_fifo, session->tx_fifo->refcnt);
Florin Coras070453d2018-08-24 17:04:27 -0700401
Florin Coras54693d22018-07-17 10:46:29 -0700402 return session_index;
403}
404
Florin Corasc9fbd662018-08-24 12:59:56 -0700405static u32
Florin Coras134a9962018-08-28 11:32:04 -0700406vcl_session_reset_handler (vcl_worker_t * wrk,
407 session_reset_msg_t * reset_msg)
Florin Corasc9fbd662018-08-24 12:59:56 -0700408{
409 vcl_session_t *session;
410 u32 sid;
411
Florin Coras134a9962018-08-28 11:32:04 -0700412 sid = vcl_session_index_from_vpp_handle (wrk, reset_msg->handle);
413 session = vcl_session_get (wrk, sid);
Florin Corasc9fbd662018-08-24 12:59:56 -0700414 if (!session)
415 {
416 VDBG (0, "request to reset unknown handle 0x%llx", reset_msg->handle);
417 return VCL_INVALID_SESSION_INDEX;
418 }
419 session->session_state = STATE_CLOSE_ON_EMPTY;
420 VDBG (0, "reset handle 0x%llx, sid %u ", reset_msg->handle, sid);
Florin Coras134a9962018-08-28 11:32:04 -0700421 vcl_send_session_reset_reply (vcl_session_vpp_evt_q (wrk, session),
Florin Corasc9fbd662018-08-24 12:59:56 -0700422 vcm->my_client_index, reset_msg->handle, 0);
423 return sid;
424}
425
Florin Coras60116992018-08-27 09:52:18 -0700426static u32
Florin Coras134a9962018-08-28 11:32:04 -0700427vcl_session_bound_handler (vcl_worker_t * wrk, session_bound_msg_t * mp)
Florin Coras60116992018-08-27 09:52:18 -0700428{
429 vcl_session_t *session;
430 u32 sid = mp->context;
431
Florin Coras134a9962018-08-28 11:32:04 -0700432 session = vcl_session_get (wrk, sid);
Florin Coras60116992018-08-27 09:52:18 -0700433 if (mp->retval)
434 {
435 VDBG (0, "VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: bind failed: %U",
436 getpid (), mp->handle, sid, format_api_error, ntohl (mp->retval));
437 if (session)
438 {
439 session->session_state = STATE_FAILED;
440 session->vpp_handle = mp->handle;
441 return sid;
442 }
443 else
444 {
445 clib_warning ("[%s] ERROR: vpp handle 0x%llx, sid %u: "
446 "Invalid session index (%u)!",
447 getpid (), mp->handle, sid);
448 return VCL_INVALID_SESSION_INDEX;
449 }
450 }
451
452 session->vpp_handle = mp->handle;
453 session->transport.is_ip4 = mp->lcl_is_ip4;
454 clib_memcpy (&session->transport.lcl_ip, mp->lcl_ip,
455 sizeof (ip46_address_t));
456 session->transport.lcl_port = mp->lcl_port;
Florin Coras134a9962018-08-28 11:32:04 -0700457 vcl_session_table_add_listener (wrk, mp->handle, sid);
Florin Coras60116992018-08-27 09:52:18 -0700458 session->session_state = STATE_LISTEN;
459
460 if (session->is_dgram)
461 {
462 svm_fifo_t *rx_fifo, *tx_fifo;
463 session->vpp_evt_q = uword_to_pointer (mp->vpp_evt_q, svm_msg_q_t *);
464 rx_fifo = uword_to_pointer (mp->rx_fifo, svm_fifo_t *);
465 rx_fifo->client_session_index = sid;
466 tx_fifo = uword_to_pointer (mp->tx_fifo, svm_fifo_t *);
467 tx_fifo->client_session_index = sid;
468 session->rx_fifo = rx_fifo;
469 session->tx_fifo = tx_fifo;
470 }
471
472 VDBG (1, "VCL<%d>: vpp handle 0x%llx, sid %u: bind succeeded!",
473 getpid (), mp->handle, sid);
474 return sid;
475}
476
Florin Coras54693d22018-07-17 10:46:29 -0700477int
Florin Coras134a9962018-08-28 11:32:04 -0700478vcl_handle_mq_ctrl_event (vcl_worker_t * wrk, session_event_t * e)
Florin Coras54693d22018-07-17 10:46:29 -0700479{
480 session_accepted_msg_t *accepted_msg;
481 session_disconnected_msg_t *disconnected_msg;
482 vcl_session_msg_t *vcl_msg;
483 vcl_session_t *session;
484 u64 handle;
485 u32 sid;
486
487 switch (e->event_type)
488 {
489 case FIFO_EVENT_APP_RX:
490 clib_warning ("unhandled rx: sid %u (0x%x)",
491 e->fifo->client_session_index,
492 e->fifo->client_session_index);
493 break;
494 case SESSION_CTRL_EVT_ACCEPTED:
495 accepted_msg = (session_accepted_msg_t *) e->data;
496 handle = accepted_msg->listener_handle;
Florin Coras134a9962018-08-28 11:32:04 -0700497 session = vcl_session_table_lookup_listener (wrk, handle);
Florin Coras54693d22018-07-17 10:46:29 -0700498 if (!session)
499 {
500 clib_warning ("VCL<%d>: ERROR: couldn't find listen session:"
501 "listener handle %llx", getpid (), handle);
502 break;
503 }
504
505 clib_fifo_add2 (session->accept_evts_fifo, vcl_msg);
506 vcl_msg->accepted_msg = *accepted_msg;
507 break;
508 case SESSION_CTRL_EVT_CONNECTED:
Florin Coras134a9962018-08-28 11:32:04 -0700509 vcl_session_connected_handler (wrk,
510 (session_connected_msg_t *) e->data);
Florin Coras54693d22018-07-17 10:46:29 -0700511 break;
512 case SESSION_CTRL_EVT_DISCONNECTED:
513 disconnected_msg = (session_disconnected_msg_t *) e->data;
Florin Coras134a9962018-08-28 11:32:04 -0700514 sid = vcl_session_index_from_vpp_handle (wrk, disconnected_msg->handle);
515 session = vcl_session_get (wrk, sid);
Florin Corasc9fbd662018-08-24 12:59:56 -0700516 if (!session)
517 {
518 VDBG (0, "request to disconnect unknown handle 0x%llx",
519 disconnected_msg->handle);
520 break;
521 }
Florin Coras54693d22018-07-17 10:46:29 -0700522 session->session_state = STATE_DISCONNECT;
Florin Corasc9fbd662018-08-24 12:59:56 -0700523 VDBG (0, "disconnected handle 0xllx, sid %u", disconnected_msg->handle,
524 sid);
525 break;
526 case SESSION_CTRL_EVT_RESET:
Florin Coras134a9962018-08-28 11:32:04 -0700527 vcl_session_reset_handler (wrk, (session_reset_msg_t *) e->data);
Florin Coras60116992018-08-27 09:52:18 -0700528 break;
529 case SESSION_CTRL_EVT_BOUND:
Florin Coras134a9962018-08-28 11:32:04 -0700530 vcl_session_bound_handler (wrk, (session_bound_msg_t *) e->data);
Florin Coras54693d22018-07-17 10:46:29 -0700531 break;
532 default:
533 clib_warning ("unhandled %u", e->event_type);
534 }
535 return VPPCOM_OK;
536}
537
Florin Coras697faea2018-06-27 17:10:49 -0700538static inline int
539vppcom_wait_for_session_state_change (u32 session_index,
540 session_state_t state,
541 f64 wait_for_time)
542{
Florin Coras134a9962018-08-28 11:32:04 -0700543 vcl_worker_t *wrk = vcl_worker_get_current ();
544 f64 timeout = clib_time_now (&wrk->clib_time) + wait_for_time;
Florin Coras697faea2018-06-27 17:10:49 -0700545 vcl_session_t *volatile session;
Florin Coras54693d22018-07-17 10:46:29 -0700546 svm_msg_q_msg_t msg;
547 session_event_t *e;
Dave Wallace543852a2017-08-03 02:11:34 -0400548
Florin Coras697faea2018-06-27 17:10:49 -0700549 do
Dave Wallace543852a2017-08-03 02:11:34 -0400550 {
Florin Coras134a9962018-08-28 11:32:04 -0700551 session = vcl_session_get (wrk, session_index);
Florin Coras070453d2018-08-24 17:04:27 -0700552 if (PREDICT_FALSE (!session))
Florin Coras697faea2018-06-27 17:10:49 -0700553 {
Florin Coras070453d2018-08-24 17:04:27 -0700554 return VPPCOM_EBADFD;
Florin Coras697faea2018-06-27 17:10:49 -0700555 }
556 if (session->session_state & state)
557 {
Florin Coras697faea2018-06-27 17:10:49 -0700558 return VPPCOM_OK;
559 }
560 if (session->session_state & STATE_FAILED)
561 {
Florin Coras697faea2018-06-27 17:10:49 -0700562 return VPPCOM_ECONNREFUSED;
563 }
Florin Coras54693d22018-07-17 10:46:29 -0700564
Florin Coras134a9962018-08-28 11:32:04 -0700565 if (svm_msg_q_sub (wrk->app_event_queue, &msg, SVM_Q_NOWAIT, 0))
Florin Coras54693d22018-07-17 10:46:29 -0700566 continue;
Florin Coras134a9962018-08-28 11:32:04 -0700567 e = svm_msg_q_msg_data (wrk->app_event_queue, &msg);
568 vcl_handle_mq_ctrl_event (wrk, e);
569 svm_msg_q_free_msg (wrk->app_event_queue, &msg);
Florin Corasdcf55ce2017-11-16 15:32:50 -0800570 }
Florin Coras134a9962018-08-28 11:32:04 -0700571 while (clib_time_now (&wrk->clib_time) < timeout);
Florin Corasdcf55ce2017-11-16 15:32:50 -0800572
Florin Coras697faea2018-06-27 17:10:49 -0700573 VDBG (0, "VCL<%d>: timeout waiting for state 0x%x (%s)", getpid (), state,
574 vppcom_session_state_str (state));
575 vcl_evt (VCL_EVT_SESSION_TIMEOUT, session, session_state);
Dave Wallace543852a2017-08-03 02:11:34 -0400576
Florin Coras697faea2018-06-27 17:10:49 -0700577 return VPPCOM_ETIMEDOUT;
Dave Wallace60caa062017-11-10 17:07:13 -0500578}
579
Florin Coras697faea2018-06-27 17:10:49 -0700580static int
581vppcom_app_session_enable (void)
Dave Wallace543852a2017-08-03 02:11:34 -0400582{
Florin Coras697faea2018-06-27 17:10:49 -0700583 int rv;
Dave Wallace543852a2017-08-03 02:11:34 -0400584
Florin Coras697faea2018-06-27 17:10:49 -0700585 if (vcm->app_state != STATE_APP_ENABLED)
586 {
587 vppcom_send_session_enable_disable (1 /* is_enabled == TRUE */ );
Florin Coras134a9962018-08-28 11:32:04 -0700588 rv = vcl_wait_for_app_state_change (STATE_APP_ENABLED);
Florin Coras697faea2018-06-27 17:10:49 -0700589 if (PREDICT_FALSE (rv))
590 {
591 VDBG (0, "VCL<%d>: application session enable timed out! "
592 "returning %d (%s)", getpid (), rv, vppcom_retval_str (rv));
593 return rv;
594 }
595 }
596 return VPPCOM_OK;
Dave Wallace543852a2017-08-03 02:11:34 -0400597}
598
Florin Coras697faea2018-06-27 17:10:49 -0700599static int
600vppcom_app_attach (void)
Dave Wallace543852a2017-08-03 02:11:34 -0400601{
Florin Coras697faea2018-06-27 17:10:49 -0700602 int rv;
Dave Wallace543852a2017-08-03 02:11:34 -0400603
Florin Coras697faea2018-06-27 17:10:49 -0700604 vppcom_app_send_attach ();
Florin Coras134a9962018-08-28 11:32:04 -0700605 rv = vcl_wait_for_app_state_change (STATE_APP_ATTACHED);
Florin Coras697faea2018-06-27 17:10:49 -0700606 if (PREDICT_FALSE (rv))
607 {
608 VDBG (0, "VCL<%d>: application attach timed out! returning %d (%s)",
609 getpid (), rv, vppcom_retval_str (rv));
610 return rv;
611 }
Dave Wallace543852a2017-08-03 02:11:34 -0400612
Florin Coras697faea2018-06-27 17:10:49 -0700613 return VPPCOM_OK;
Dave Wallace543852a2017-08-03 02:11:34 -0400614}
615
616static int
Florin Corasab2f6db2018-08-31 14:31:41 -0700617vppcom_session_unbind (u32 session_handle)
Dave Wallace543852a2017-08-03 02:11:34 -0400618{
Florin Coras134a9962018-08-28 11:32:04 -0700619 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras7e12d942018-06-27 14:32:43 -0700620 vcl_session_t *session = 0;
Dave Wallace4878cbe2017-11-21 03:45:09 -0500621 u64 vpp_handle;
Dave Wallace543852a2017-08-03 02:11:34 -0400622
Florin Corasab2f6db2018-08-31 14:31:41 -0700623 session = vcl_session_get_w_handle (wrk, session_handle);
Florin Coras070453d2018-08-24 17:04:27 -0700624 if (!session)
625 return VPPCOM_EBADFD;
Dave Wallace4878cbe2017-11-21 03:45:09 -0500626
627 vpp_handle = session->vpp_handle;
Florin Coras134a9962018-08-28 11:32:04 -0700628 vcl_session_table_del_listener (wrk, vpp_handle);
Dave Wallace4878cbe2017-11-21 03:45:09 -0500629 session->vpp_handle = ~0;
Florin Coras7e12d942018-06-27 14:32:43 -0700630 session->session_state = STATE_DISCONNECT;
Dave Wallace4878cbe2017-11-21 03:45:09 -0500631
Florin Coras0d427d82018-06-27 03:24:07 -0700632 VDBG (1, "VCL<%d>: vpp handle 0x%llx, sid %u: sending unbind msg! new state"
Florin Corasab2f6db2018-08-31 14:31:41 -0700633 " 0x%x (%s)", getpid (), vpp_handle, session_handle, STATE_DISCONNECT,
Florin Coras0d427d82018-06-27 03:24:07 -0700634 vppcom_session_state_str (STATE_DISCONNECT));
635 vcl_evt (VCL_EVT_UNBIND, session);
Dave Wallace4878cbe2017-11-21 03:45:09 -0500636 vppcom_send_unbind_sock (vpp_handle);
637
Florin Coras070453d2018-08-24 17:04:27 -0700638 return VPPCOM_OK;
Dave Wallace543852a2017-08-03 02:11:34 -0400639}
640
Florin Coras697faea2018-06-27 17:10:49 -0700641static int
Florin Corasab2f6db2018-08-31 14:31:41 -0700642vppcom_session_disconnect (u32 session_handle)
Dave Wallace543852a2017-08-03 02:11:34 -0400643{
Florin Coras134a9962018-08-28 11:32:04 -0700644 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras99368312018-08-02 10:45:44 -0700645 svm_msg_q_t *vpp_evt_q;
Florin Coras7e12d942018-06-27 14:32:43 -0700646 vcl_session_t *session;
Dave Wallace4878cbe2017-11-21 03:45:09 -0500647 session_state_t state;
Florin Coras99368312018-08-02 10:45:44 -0700648 u64 vpp_handle;
Dave Wallace543852a2017-08-03 02:11:34 -0400649
Florin Corasab2f6db2018-08-31 14:31:41 -0700650 session = vcl_session_get_w_handle (wrk, session_handle);
Dave Wallace4878cbe2017-11-21 03:45:09 -0500651 vpp_handle = session->vpp_handle;
Florin Coras7e12d942018-06-27 14:32:43 -0700652 state = session->session_state;
Dave Wallace4878cbe2017-11-21 03:45:09 -0500653
Florin Coras0d427d82018-06-27 03:24:07 -0700654 VDBG (1, "VCL<%d>: vpp handle 0x%llx, sid %u state 0x%x (%s)", getpid (),
Florin Corasab2f6db2018-08-31 14:31:41 -0700655 vpp_handle, session_handle, state, vppcom_session_state_str (state));
Dave Wallace66cf6eb2017-10-26 02:51:07 -0400656
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -0800657 if (PREDICT_FALSE (state & STATE_LISTEN))
Dave Wallace66cf6eb2017-10-26 02:51:07 -0400658 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500659 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -0500660 "Cannot disconnect a listen socket!",
Florin Corasab2f6db2018-08-31 14:31:41 -0700661 getpid (), vpp_handle, session_handle);
Florin Coras070453d2018-08-24 17:04:27 -0700662 return VPPCOM_EBADFD;
Dave Wallace4878cbe2017-11-21 03:45:09 -0500663 }
Dave Wallace66cf6eb2017-10-26 02:51:07 -0400664
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -0800665 if (state & STATE_CLOSE_ON_EMPTY)
Dave Wallace4878cbe2017-11-21 03:45:09 -0500666 {
Florin Coras134a9962018-08-28 11:32:04 -0700667 vpp_evt_q = vcl_session_vpp_evt_q (wrk, session);
Florin Coras99368312018-08-02 10:45:44 -0700668 vcl_send_session_disconnected_reply (vpp_evt_q, vcm->my_client_index,
669 vpp_handle, 0);
Florin Coras0d427d82018-06-27 03:24:07 -0700670 VDBG (1, "VCL<%d>: vpp handle 0x%llx, sid %u: sending disconnect "
Florin Corasab2f6db2018-08-31 14:31:41 -0700671 "REPLY...", getpid (), vpp_handle, session_handle);
Dave Wallace66cf6eb2017-10-26 02:51:07 -0400672 }
673 else
Dave Wallace227867f2017-11-13 21:21:53 -0500674 {
Florin Coras0d427d82018-06-27 03:24:07 -0700675 VDBG (1, "VCL<%d>: vpp handle 0x%llx, sid %u: sending disconnect...",
Florin Corasab2f6db2018-08-31 14:31:41 -0700676 getpid (), vpp_handle, session_handle);
677 vppcom_send_disconnect_session (vpp_handle);
Dave Wallace227867f2017-11-13 21:21:53 -0500678 }
Dave Wallace66cf6eb2017-10-26 02:51:07 -0400679
Florin Coras070453d2018-08-24 17:04:27 -0700680 return VPPCOM_OK;
Dave Wallace543852a2017-08-03 02:11:34 -0400681}
682
Dave Wallace543852a2017-08-03 02:11:34 -0400683/*
684 * VPPCOM Public API functions
685 */
686int
687vppcom_app_create (char *app_name)
688{
Dave Wallace543852a2017-08-03 02:11:34 -0400689 vppcom_cfg_t *vcl_cfg = &vcm->cfg;
Dave Wallace543852a2017-08-03 02:11:34 -0400690 int rv;
691
Florin Coras134a9962018-08-28 11:32:04 -0700692 if (!vcm->is_init)
Dave Wallace543852a2017-08-03 02:11:34 -0400693 {
Florin Coras134a9962018-08-28 11:32:04 -0700694 vcm->is_init = 1;
Dave Barach6a5adc32018-07-04 10:56:23 -0400695 vppcom_cfg (&vcm->cfg);
Florin Coras99368312018-08-02 10:45:44 -0700696 vcl_cfg = &vcm->cfg;
697
Florin Coras134a9962018-08-28 11:32:04 -0700698 vcm->main_cpu = pthread_self ();
Dave Wallace543852a2017-08-03 02:11:34 -0400699 vppcom_init_error_string_table ();
Florin Corasa332c462018-01-31 06:52:17 -0800700 svm_fifo_segment_main_init (vcl_cfg->segment_baseva,
701 20 /* timeout in secs */ );
Florin Coras134a9962018-08-28 11:32:04 -0700702 pool_init_fixed (vcm->workers, vcl_cfg->max_workers);
703 vcl_worker_alloc_and_init ();
Dave Wallace543852a2017-08-03 02:11:34 -0400704 }
705
706 if (vcm->my_client_index == ~0)
707 {
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -0800708 /* API hookup and connect to VPP */
Dave Wallace048b1d62018-01-03 22:24:41 -0500709 vppcom_api_hookup ();
Florin Coras0d427d82018-06-27 03:24:07 -0700710 vcl_elog_init (vcm);
Dave Wallace543852a2017-08-03 02:11:34 -0400711 vcm->app_state = STATE_APP_START;
712 rv = vppcom_connect_to_vpp (app_name);
713 if (rv)
714 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500715 clib_warning ("VCL<%d>: ERROR: couldn't connect to VPP!",
Dave Wallace2e005bb2017-11-07 01:21:39 -0500716 getpid ());
Dave Wallace543852a2017-08-03 02:11:34 -0400717 return rv;
718 }
719
Florin Coras0d427d82018-06-27 03:24:07 -0700720 VDBG (0, "VCL<%d>: sending session enable", getpid ());
Dave Wallace048b1d62018-01-03 22:24:41 -0500721 rv = vppcom_app_session_enable ();
Dave Wallace543852a2017-08-03 02:11:34 -0400722 if (rv)
723 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500724 clib_warning ("VCL<%d>: ERROR: vppcom_app_session_enable() "
725 "failed!", getpid ());
Dave Wallace543852a2017-08-03 02:11:34 -0400726 return rv;
727 }
Dave Wallace543852a2017-08-03 02:11:34 -0400728
Florin Coras0d427d82018-06-27 03:24:07 -0700729 VDBG (0, "VCL<%d>: sending app attach", getpid ());
Dave Wallace048b1d62018-01-03 22:24:41 -0500730 rv = vppcom_app_attach ();
731 if (rv)
732 {
733 clib_warning ("VCL<%d>: ERROR: vppcom_app_attach() failed!",
734 getpid ());
735 return rv;
736 }
737
Florin Coras0d427d82018-06-27 03:24:07 -0700738 VDBG (0, "VCL<%d>: app_name '%s', my_client_index %d (0x%x)",
739 getpid (), app_name, vcm->my_client_index, vcm->my_client_index);
Dave Wallace66cf6eb2017-10-26 02:51:07 -0400740 }
Dave Wallace543852a2017-08-03 02:11:34 -0400741
742 return VPPCOM_OK;
743}
744
745void
746vppcom_app_destroy (void)
747{
Dave Wallace543852a2017-08-03 02:11:34 -0400748 int rv;
Dave Wallacede910062018-03-20 09:22:13 -0400749 f64 orig_app_timeout;
Dave Wallace543852a2017-08-03 02:11:34 -0400750
751 if (vcm->my_client_index == ~0)
752 return;
753
Florin Coras0d427d82018-06-27 03:24:07 -0700754 VDBG (0, "VCL<%d>: detaching from VPP, my_client_index %d (0x%x)",
755 getpid (), vcm->my_client_index, vcm->my_client_index);
756 vcl_evt (VCL_EVT_DETACH, vcm);
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -0800757
Florin Coras697faea2018-06-27 17:10:49 -0700758 vppcom_app_send_detach ();
Dave Wallacede910062018-03-20 09:22:13 -0400759 orig_app_timeout = vcm->cfg.app_timeout;
760 vcm->cfg.app_timeout = 2.0;
Florin Coras134a9962018-08-28 11:32:04 -0700761 rv = vcl_wait_for_app_state_change (STATE_APP_ENABLED);
Dave Wallacede910062018-03-20 09:22:13 -0400762 vcm->cfg.app_timeout = orig_app_timeout;
Dave Wallace543852a2017-08-03 02:11:34 -0400763 if (PREDICT_FALSE (rv))
Florin Coras0d427d82018-06-27 03:24:07 -0700764 VDBG (0, "VCL<%d>: application detach timed out! returning %d (%s)",
765 getpid (), rv, vppcom_retval_str (rv));
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -0800766
Florin Coras0d427d82018-06-27 03:24:07 -0700767 vcl_elog_stop (vcm);
Dave Wallace543852a2017-08-03 02:11:34 -0400768 vl_client_disconnect_from_vlib ();
769 vcm->my_client_index = ~0;
770 vcm->app_state = STATE_APP_START;
771}
772
773int
Dave Wallacec04cbf12018-02-07 18:14:02 -0500774vppcom_session_create (u8 proto, u8 is_nonblocking)
Dave Wallace543852a2017-08-03 02:11:34 -0400775{
Florin Coras134a9962018-08-28 11:32:04 -0700776 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras7e12d942018-06-27 14:32:43 -0700777 vcl_session_t *session;
Dave Wallace543852a2017-08-03 02:11:34 -0400778
Florin Coras134a9962018-08-28 11:32:04 -0700779 session = vcl_session_alloc (wrk);
Dave Wallace543852a2017-08-03 02:11:34 -0400780
Florin Coras7e12d942018-06-27 14:32:43 -0700781 session->session_type = proto;
782 session->session_state = STATE_START;
Dave Wallace4878cbe2017-11-21 03:45:09 -0500783 session->vpp_handle = ~0;
Florin Coras460dce62018-07-27 05:45:06 -0700784 session->is_dgram = proto == VPPCOM_PROTO_UDP;
Dave Wallace543852a2017-08-03 02:11:34 -0400785
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -0800786 if (is_nonblocking)
787 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_NONBLOCK);
Dave Wallace543852a2017-08-03 02:11:34 -0400788
Florin Coras7e12d942018-06-27 14:32:43 -0700789 vcl_evt (VCL_EVT_CREATE, session, session_type, session->session_state,
790 is_nonblocking, session_index);
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -0800791
Florin Coras134a9962018-08-28 11:32:04 -0700792 VDBG (0, "VCL<%d>: sid %u", getpid (), session->session_index);
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -0800793
Florin Coras134a9962018-08-28 11:32:04 -0700794 return vcl_session_handle (session);
Dave Wallace543852a2017-08-03 02:11:34 -0400795}
796
797int
Florin Coras134a9962018-08-28 11:32:04 -0700798vppcom_session_close (uint32_t session_handle)
Dave Wallace543852a2017-08-03 02:11:34 -0400799{
Florin Coras134a9962018-08-28 11:32:04 -0700800 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras7e12d942018-06-27 14:32:43 -0700801 vcl_session_t *session = 0;
Florin Coras134a9962018-08-28 11:32:04 -0700802 u8 is_vep, is_vep_session;
Dave Wallace66cf6eb2017-10-26 02:51:07 -0400803 session_state_t state;
Florin Coras134a9962018-08-28 11:32:04 -0700804 u32 next_sh, vep_sh;
805 int rv = VPPCOM_OK;
806 u64 vpp_handle;
Dave Wallace543852a2017-08-03 02:11:34 -0400807
Florin Coras134a9962018-08-28 11:32:04 -0700808 session = vcl_session_get_w_handle (wrk, session_handle);
Florin Coras070453d2018-08-24 17:04:27 -0700809 if (!session)
810 return VPPCOM_EBADFD;
811
Dave Wallace66cf6eb2017-10-26 02:51:07 -0400812 is_vep = session->is_vep;
813 is_vep_session = session->is_vep_session;
Florin Coras134a9962018-08-28 11:32:04 -0700814 next_sh = session->vep.next_sh;
815 vep_sh = session->vep.vep_sh;
Florin Coras7e12d942018-06-27 14:32:43 -0700816 state = session->session_state;
Dave Wallaceee45d412017-11-24 21:44:06 -0500817 vpp_handle = session->vpp_handle;
Dave Wallace543852a2017-08-03 02:11:34 -0400818
819 if (VPPCOM_DEBUG > 0)
Dave Wallaceee45d412017-11-24 21:44:06 -0500820 {
821 if (is_vep)
Dave Wallace048b1d62018-01-03 22:24:41 -0500822 clib_warning ("VCL<%d>: vep_idx %u / sid %u: "
823 "closing epoll session...",
Florin Coras134a9962018-08-28 11:32:04 -0700824 getpid (), session_handle, session_handle);
Dave Wallaceee45d412017-11-24 21:44:06 -0500825 else
Dave Wallace048b1d62018-01-03 22:24:41 -0500826 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %d: "
827 "closing session...",
Florin Coras134a9962018-08-28 11:32:04 -0700828 getpid (), vpp_handle, session_handle);
Dave Wallaceee45d412017-11-24 21:44:06 -0500829 }
Dave Wallace543852a2017-08-03 02:11:34 -0400830
Dave Wallace66cf6eb2017-10-26 02:51:07 -0400831 if (is_vep)
Dave Wallace543852a2017-08-03 02:11:34 -0400832 {
Florin Coras134a9962018-08-28 11:32:04 -0700833 while (next_sh != ~0)
Dave Wallace19481612017-09-15 18:47:44 -0400834 {
Florin Coras134a9962018-08-28 11:32:04 -0700835 rv = vppcom_epoll_ctl (session_handle, EPOLL_CTL_DEL, next_sh, 0);
Florin Coras0d427d82018-06-27 03:24:07 -0700836 if (PREDICT_FALSE (rv < 0))
837 VDBG (0, "VCL<%d>: vpp handle 0x%llx, sid %u: EPOLL_CTL_DEL "
838 "vep_idx %u failed! rv %d (%s)",
Florin Coras134a9962018-08-28 11:32:04 -0700839 getpid (), vpp_handle, next_sh, vep_sh,
Florin Coras0d427d82018-06-27 03:24:07 -0700840 rv, vppcom_retval_str (rv));
Dave Wallacef7f809c2017-10-03 01:48:42 -0400841
Florin Coras134a9962018-08-28 11:32:04 -0700842 next_sh = session->vep.next_sh;
Dave Wallacef7f809c2017-10-03 01:48:42 -0400843 }
844 }
845 else
846 {
Dave Wallace66cf6eb2017-10-26 02:51:07 -0400847 if (is_vep_session)
Dave Wallacef7f809c2017-10-03 01:48:42 -0400848 {
Florin Coras134a9962018-08-28 11:32:04 -0700849 rv = vppcom_epoll_ctl (vep_sh, EPOLL_CTL_DEL, session_handle, 0);
Florin Coras0d427d82018-06-27 03:24:07 -0700850 if (rv < 0)
851 VDBG (0, "VCL<%d>: vpp handle 0x%llx, sid %u: EPOLL_CTL_DEL "
852 "vep_idx %u failed! rv %d (%s)",
Florin Coras134a9962018-08-28 11:32:04 -0700853 getpid (), vpp_handle, session_handle,
854 vep_sh, rv, vppcom_retval_str (rv));
Dave Wallacef7f809c2017-10-03 01:48:42 -0400855 }
856
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -0800857 if (state & STATE_LISTEN)
Dave Wallacef7f809c2017-10-03 01:48:42 -0400858 {
Florin Coras134a9962018-08-28 11:32:04 -0700859 rv = vppcom_session_unbind (session_handle);
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -0800860 if (PREDICT_FALSE (rv < 0))
Florin Coras0d427d82018-06-27 03:24:07 -0700861 VDBG (0, "VCL<%d>: vpp handle 0x%llx, sid %u: listener unbind "
862 "failed! rv %d (%s)",
Florin Coras134a9962018-08-28 11:32:04 -0700863 getpid (), vpp_handle, session_handle,
Florin Coras0d427d82018-06-27 03:24:07 -0700864 rv, vppcom_retval_str (rv));
Dave Wallacef7f809c2017-10-03 01:48:42 -0400865 }
Florin Coras070453d2018-08-24 17:04:27 -0700866 else if (state & STATE_OPEN)
Dave Wallacef7f809c2017-10-03 01:48:42 -0400867 {
Florin Coras134a9962018-08-28 11:32:04 -0700868 rv = vppcom_session_disconnect (session_handle);
Dave Wallace4878cbe2017-11-21 03:45:09 -0500869 if (PREDICT_FALSE (rv < 0))
Dave Wallace048b1d62018-01-03 22:24:41 -0500870 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -0500871 "session disconnect failed! rv %d (%s)",
Florin Coras134a9962018-08-28 11:32:04 -0700872 getpid (), vpp_handle, session_handle,
Dave Wallaceee45d412017-11-24 21:44:06 -0500873 rv, vppcom_retval_str (rv));
Dave Wallacef7f809c2017-10-03 01:48:42 -0400874 }
Dave Wallace19481612017-09-15 18:47:44 -0400875 }
Dave Wallace4878cbe2017-11-21 03:45:09 -0500876
Florin Coras99368312018-08-02 10:45:44 -0700877 if (vcl_session_is_ct (session))
878 {
879 vcl_cut_through_registration_t *ctr;
880 uword mq_addr;
881
882 mq_addr = pointer_to_uword (session->our_evt_q);
Florin Coras134a9962018-08-28 11:32:04 -0700883 ctr = vcl_ct_registration_lock_and_lookup (wrk, mq_addr);
Florin Coras99368312018-08-02 10:45:44 -0700884 ASSERT (ctr);
885 if (ctr->epoll_evt_conn_index != ~0)
Florin Coras134a9962018-08-28 11:32:04 -0700886 vcl_mq_epoll_del_evfd (wrk, ctr->epoll_evt_conn_index);
Florin Coras99368312018-08-02 10:45:44 -0700887 VDBG (0, "Removing ct registration %u",
Florin Coras134a9962018-08-28 11:32:04 -0700888 vcl_ct_registration_index (wrk, ctr));
889 vcl_ct_registration_del (wrk, ctr);
890 vcl_ct_registration_lookup_del (wrk, mq_addr);
891 vcl_ct_registration_unlock (wrk);
Florin Coras99368312018-08-02 10:45:44 -0700892 }
Florin Coras54693d22018-07-17 10:46:29 -0700893
Dave Wallaceee45d412017-11-24 21:44:06 -0500894 if (vpp_handle != ~0)
Dave Wallace4878cbe2017-11-21 03:45:09 -0500895 {
Florin Coras134a9962018-08-28 11:32:04 -0700896 vcl_session_table_del_vpp_handle (wrk, vpp_handle);
Dave Wallace4878cbe2017-11-21 03:45:09 -0500897 }
Florin Coras134a9962018-08-28 11:32:04 -0700898 vcl_session_free (wrk, session);
Dave Wallace4878cbe2017-11-21 03:45:09 -0500899
900 if (VPPCOM_DEBUG > 0)
Dave Wallaceee45d412017-11-24 21:44:06 -0500901 {
902 if (is_vep)
Dave Wallace048b1d62018-01-03 22:24:41 -0500903 clib_warning ("VCL<%d>: vep_idx %u / sid %u: epoll session removed.",
Florin Coras134a9962018-08-28 11:32:04 -0700904 getpid (), session_handle, session_handle);
Dave Wallaceee45d412017-11-24 21:44:06 -0500905 else
Dave Wallace048b1d62018-01-03 22:24:41 -0500906 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: session removed.",
Florin Coras134a9962018-08-28 11:32:04 -0700907 getpid (), vpp_handle, session_handle);
Dave Wallaceee45d412017-11-24 21:44:06 -0500908 }
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -0800909
Florin Coras0d427d82018-06-27 03:24:07 -0700910 vcl_evt (VCL_EVT_CLOSE, session, rv);
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -0800911
Dave Wallace543852a2017-08-03 02:11:34 -0400912 return rv;
913}
914
915int
Florin Coras134a9962018-08-28 11:32:04 -0700916vppcom_session_bind (uint32_t session_handle, vppcom_endpt_t * ep)
Dave Wallace543852a2017-08-03 02:11:34 -0400917{
Florin Coras134a9962018-08-28 11:32:04 -0700918 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras7e12d942018-06-27 14:32:43 -0700919 vcl_session_t *session = 0;
Dave Wallace543852a2017-08-03 02:11:34 -0400920
921 if (!ep || !ep->ip)
922 return VPPCOM_EINVAL;
923
Florin Coras134a9962018-08-28 11:32:04 -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 Wallace543852a2017-08-03 02:11:34 -0400927
Dave Wallace9c4b5b22017-10-18 21:15:48 -0400928 if (session->is_vep)
929 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500930 clib_warning ("VCL<%d>: ERROR: sid %u: cannot "
Florin Coras134a9962018-08-28 11:32:04 -0700931 "bind to an epoll session!", getpid (), session_handle);
Florin Coras070453d2018-08-24 17:04:27 -0700932 return VPPCOM_EBADFD;
Dave Wallace9c4b5b22017-10-18 21:15:48 -0400933 }
934
Florin Coras7e12d942018-06-27 14:32:43 -0700935 session->transport.is_ip4 = ep->is_ip4;
Florin Coras54693d22018-07-17 10:46:29 -0700936 if (ep->is_ip4)
937 clib_memcpy (&session->transport.lcl_ip.ip4, ep->ip,
938 sizeof (ip4_address_t));
939 else
940 clib_memcpy (&session->transport.lcl_ip.ip6, ep->ip,
941 sizeof (ip6_address_t));
Florin Coras7e12d942018-06-27 14:32:43 -0700942 session->transport.lcl_port = ep->port;
Stevenac1f96d2017-10-24 16:03:58 -0700943
Florin Coras0d427d82018-06-27 03:24:07 -0700944 VDBG (0, "VCL<%d>: sid %u: binding to local %s address %U port %u, "
Florin Coras134a9962018-08-28 11:32:04 -0700945 "proto %s", getpid (), session_handle,
Florin Coras7e12d942018-06-27 14:32:43 -0700946 session->transport.is_ip4 ? "IPv4" : "IPv6",
947 format_ip46_address, &session->transport.lcl_ip,
948 session->transport.is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6,
949 clib_net_to_host_u16 (session->transport.lcl_port),
950 session->session_type ? "UDP" : "TCP");
Florin Coras0d427d82018-06-27 03:24:07 -0700951 vcl_evt (VCL_EVT_BIND, session);
Florin Coras460dce62018-07-27 05:45:06 -0700952
953 if (session->session_type == VPPCOM_PROTO_UDP)
Florin Coras134a9962018-08-28 11:32:04 -0700954 vppcom_session_listen (session_handle, 10);
Florin Coras460dce62018-07-27 05:45:06 -0700955
Florin Coras070453d2018-08-24 17:04:27 -0700956 return VPPCOM_OK;
Dave Wallace543852a2017-08-03 02:11:34 -0400957}
958
959int
Florin Coras134a9962018-08-28 11:32:04 -0700960vppcom_session_listen (uint32_t listen_sh, uint32_t q_len)
Dave Wallace543852a2017-08-03 02:11:34 -0400961{
Florin Coras134a9962018-08-28 11:32:04 -0700962 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras7e12d942018-06-27 14:32:43 -0700963 vcl_session_t *listen_session = 0;
Dave Wallaceee45d412017-11-24 21:44:06 -0500964 u64 listen_vpp_handle;
Florin Coras070453d2018-08-24 17:04:27 -0700965 int rv;
966
Florin Coras134a9962018-08-28 11:32:04 -0700967 listen_session = vcl_session_get_w_handle (wrk, listen_sh);
Florin Coras070453d2018-08-24 17:04:27 -0700968 if (!listen_session)
969 return VPPCOM_EBADFD;
Dave Wallace543852a2017-08-03 02:11:34 -0400970
Keith Burns (alagalah)aba98de2018-02-22 03:23:40 -0800971 if (q_len == 0 || q_len == ~0)
972 q_len = vcm->cfg.listen_queue_size;
973
Dave Wallace9c4b5b22017-10-18 21:15:48 -0400974 if (listen_session->is_vep)
975 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500976 clib_warning ("VCL<%d>: ERROR: sid %u: cannot listen on an "
Florin Coras134a9962018-08-28 11:32:04 -0700977 "epoll session!", getpid (), listen_sh);
Florin Coras070453d2018-08-24 17:04:27 -0700978 return VPPCOM_EBADFD;
Dave Wallace9c4b5b22017-10-18 21:15:48 -0400979 }
980
Dave Wallaceee45d412017-11-24 21:44:06 -0500981 listen_vpp_handle = listen_session->vpp_handle;
Florin Coras7e12d942018-06-27 14:32:43 -0700982 if (listen_session->session_state & STATE_LISTEN)
Dave Wallacee695cb42017-11-02 22:04:42 -0400983 {
Florin Coras0d427d82018-06-27 03:24:07 -0700984 VDBG (0, "VCL<%d>: vpp handle 0x%llx, sid %u: already in listen state!",
Florin Coras134a9962018-08-28 11:32:04 -0700985 getpid (), listen_vpp_handle, listen_sh);
Florin Coras070453d2018-08-24 17:04:27 -0700986 return VPPCOM_OK;
Dave Wallacee695cb42017-11-02 22:04:42 -0400987 }
988
Florin Coras0d427d82018-06-27 03:24:07 -0700989 VDBG (0, "VCL<%d>: vpp handle 0x%llx, sid %u: sending VPP bind+listen "
Florin Coras134a9962018-08-28 11:32:04 -0700990 "request...", getpid (), listen_vpp_handle, listen_sh);
Dave Wallace543852a2017-08-03 02:11:34 -0400991
Florin Coras070453d2018-08-24 17:04:27 -0700992 /*
993 * Send listen request to vpp and wait for reply
994 */
Florin Coras134a9962018-08-28 11:32:04 -0700995 vppcom_send_bind_sock (listen_session);
996 rv = vppcom_wait_for_session_state_change (listen_session->session_index,
997 STATE_LISTEN,
998 vcm->cfg.session_timeout);
Dave Wallace543852a2017-08-03 02:11:34 -0400999
Florin Coras070453d2018-08-24 17:04:27 -07001000 if (PREDICT_FALSE (rv))
Dave Wallaceee45d412017-11-24 21:44:06 -05001001 {
Florin Coras134a9962018-08-28 11:32:04 -07001002 listen_session = vcl_session_get_w_handle (wrk, listen_sh);
Florin Coras0d427d82018-06-27 03:24:07 -07001003 VDBG (0, "VCL<%d>: vpp handle 0x%llx, sid %u: bind+listen failed! "
1004 "returning %d (%s)", getpid (), listen_session->vpp_handle,
Florin Coras134a9962018-08-28 11:32:04 -07001005 listen_sh, rv, vppcom_retval_str (rv));
Florin Coras070453d2018-08-24 17:04:27 -07001006 return rv;
Dave Wallaceee45d412017-11-24 21:44:06 -05001007 }
1008
Florin Coras070453d2018-08-24 17:04:27 -07001009 return VPPCOM_OK;
Keith Burns (alagalah)0d2b0d52018-03-06 15:55:22 -08001010}
1011
Florin Coras134a9962018-08-28 11:32:04 -07001012static int
1013validate_args_session_accept_ (vcl_worker_t * wrk,
1014 vcl_session_t * listen_session)
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001015{
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001016 /* Input validation - expects spinlock on sessions_lockp */
1017 if (listen_session->is_vep)
1018 {
1019 clib_warning ("VCL<%d>: ERROR: sid %u: cannot accept on an "
Florin Coras134a9962018-08-28 11:32:04 -07001020 "epoll session!", getpid (),
1021 listen_session->session_index);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001022 return VPPCOM_EBADFD;
1023 }
1024
Florin Coras7e12d942018-06-27 14:32:43 -07001025 if (listen_session->session_state != STATE_LISTEN)
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001026 {
1027 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
1028 "not in listen state! state 0x%x (%s)", getpid (),
Florin Coras134a9962018-08-28 11:32:04 -07001029 listen_session->vpp_handle, listen_session->session_index,
Florin Coras7e12d942018-06-27 14:32:43 -07001030 listen_session->session_state,
1031 vppcom_session_state_str (listen_session->session_state));
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001032 return VPPCOM_EBADFD;
1033 }
1034 return VPPCOM_OK;
1035}
1036
1037int
Florin Coras134a9962018-08-28 11:32:04 -07001038vppcom_session_accept (uint32_t listen_session_handle, vppcom_endpt_t * ep,
Dave Wallace048b1d62018-01-03 22:24:41 -05001039 uint32_t flags)
Dave Wallace543852a2017-08-03 02:11:34 -04001040{
Florin Coras134a9962018-08-28 11:32:04 -07001041 u32 client_session_index = ~0, listen_session_index;
1042 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras54693d22018-07-17 10:46:29 -07001043 session_accepted_msg_t accepted_msg;
Florin Coras7e12d942018-06-27 14:32:43 -07001044 vcl_session_t *listen_session = 0;
1045 vcl_session_t *client_session = 0;
Florin Coras54693d22018-07-17 10:46:29 -07001046 svm_msg_q_t *vpp_evt_q;
1047 vcl_session_msg_t *evt;
Dave Wallaceee45d412017-11-24 21:44:06 -05001048 u64 listen_vpp_handle;
Florin Coras54693d22018-07-17 10:46:29 -07001049 svm_msg_q_msg_t msg;
1050 session_event_t *e;
1051 u8 is_nonblocking;
1052 int rv;
Dave Wallace543852a2017-08-03 02:11:34 -04001053
Florin Coras134a9962018-08-28 11:32:04 -07001054 listen_session = vcl_session_get_w_handle (wrk, listen_session_handle);
Florin Coras070453d2018-08-24 17:04:27 -07001055 if (!listen_session)
1056 return VPPCOM_EBADFD;
Dave Wallace543852a2017-08-03 02:11:34 -04001057
Florin Coras134a9962018-08-28 11:32:04 -07001058 listen_session_index = listen_session->session_index;
1059 if ((rv = validate_args_session_accept_ (wrk, listen_session)))
Florin Coras070453d2018-08-24 17:04:27 -07001060 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04001061
Florin Coras54693d22018-07-17 10:46:29 -07001062 if (clib_fifo_elts (listen_session->accept_evts_fifo))
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001063 {
Florin Coras54693d22018-07-17 10:46:29 -07001064 clib_fifo_sub2 (listen_session->accept_evts_fifo, evt);
1065 accepted_msg = evt->accepted_msg;
1066 goto handle;
1067 }
1068
1069 is_nonblocking = VCL_SESS_ATTR_TEST (listen_session->attr,
1070 VCL_SESS_ATTR_NONBLOCK);
Florin Coras134a9962018-08-28 11:32:04 -07001071 if (svm_msg_q_is_empty (wrk->app_event_queue) && is_nonblocking)
Florin Coras54693d22018-07-17 10:46:29 -07001072 return VPPCOM_EAGAIN;
1073
1074 while (1)
1075 {
Florin Coras134a9962018-08-28 11:32:04 -07001076 if (svm_msg_q_sub (wrk->app_event_queue, &msg, SVM_Q_WAIT, 0))
Florin Coras54693d22018-07-17 10:46:29 -07001077 return VPPCOM_EAGAIN;
1078
Florin Coras134a9962018-08-28 11:32:04 -07001079 e = svm_msg_q_msg_data (wrk->app_event_queue, &msg);
Florin Coras54693d22018-07-17 10:46:29 -07001080 if (e->event_type != SESSION_CTRL_EVT_ACCEPTED)
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001081 {
Florin Coras54693d22018-07-17 10:46:29 -07001082 clib_warning ("discarded event: %u", e->event_type);
Florin Coras134a9962018-08-28 11:32:04 -07001083 svm_msg_q_free_msg (wrk->app_event_queue, &msg);
Florin Coras54693d22018-07-17 10:46:29 -07001084 continue;
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001085 }
Florin Coras54693d22018-07-17 10:46:29 -07001086 clib_memcpy (&accepted_msg, e->data, sizeof (accepted_msg));
Florin Coras134a9962018-08-28 11:32:04 -07001087 svm_msg_q_free_msg (wrk->app_event_queue, &msg);
Florin Coras54693d22018-07-17 10:46:29 -07001088 break;
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001089 }
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001090
Florin Coras54693d22018-07-17 10:46:29 -07001091handle:
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08001092
Florin Coras134a9962018-08-28 11:32:04 -07001093 client_session_index = vcl_session_accepted_handler (wrk, &accepted_msg);
1094 listen_session = vcl_session_get (wrk, listen_session_index);
1095 client_session = vcl_session_get (wrk, client_session_index);
Dave Wallace543852a2017-08-03 02:11:34 -04001096
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001097 if (flags & O_NONBLOCK)
1098 VCL_SESS_ATTR_SET (client_session->attr, VCL_SESS_ATTR_NONBLOCK);
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001099
Florin Coras54693d22018-07-17 10:46:29 -07001100 listen_vpp_handle = listen_session->vpp_handle;
Florin Coras0d427d82018-06-27 03:24:07 -07001101 VDBG (0, "VCL<%d>: vpp handle 0x%llx, sid %u: Got a client request! "
1102 "vpp handle 0x%llx, sid %u, flags %d, is_nonblocking %u",
Florin Coras134a9962018-08-28 11:32:04 -07001103 getpid (), listen_vpp_handle, listen_session_handle,
Florin Coras0d427d82018-06-27 03:24:07 -07001104 client_session->vpp_handle, client_session_index,
1105 flags, VCL_SESS_ATTR_TEST (client_session->attr,
1106 VCL_SESS_ATTR_NONBLOCK));
Dave Wallace543852a2017-08-03 02:11:34 -04001107
Dave Wallace048b1d62018-01-03 22:24:41 -05001108 if (ep)
1109 {
Florin Coras7e12d942018-06-27 14:32:43 -07001110 ep->is_ip4 = client_session->transport.is_ip4;
1111 ep->port = client_session->transport.rmt_port;
1112 if (client_session->transport.is_ip4)
1113 clib_memcpy (ep->ip, &client_session->transport.rmt_ip.ip4,
Dave Wallace048b1d62018-01-03 22:24:41 -05001114 sizeof (ip4_address_t));
1115 else
Florin Coras7e12d942018-06-27 14:32:43 -07001116 clib_memcpy (ep->ip, &client_session->transport.rmt_ip.ip6,
Dave Wallace048b1d62018-01-03 22:24:41 -05001117 sizeof (ip6_address_t));
1118 }
Dave Wallace60caa062017-11-10 17:07:13 -05001119
Florin Coras54693d22018-07-17 10:46:29 -07001120 if (accepted_msg.server_event_queue_address)
1121 vpp_evt_q = uword_to_pointer (accepted_msg.vpp_event_queue_address,
1122 svm_msg_q_t *);
1123 else
1124 vpp_evt_q = client_session->vpp_evt_q;
Florin Coras99368312018-08-02 10:45:44 -07001125
Florin Coras54693d22018-07-17 10:46:29 -07001126 vcl_send_session_accepted_reply (vpp_evt_q, client_session->client_context,
1127 client_session->vpp_handle, 0);
Dave Wallace60caa062017-11-10 17:07:13 -05001128
Florin Coras54693d22018-07-17 10:46:29 -07001129 VDBG (0, "VCL<%d>: vpp handle 0x%llx, sid %u: accepted vpp handle 0x%llx, "
1130 "sid %u connection from peer %s address %U port %u to local %s "
1131 "address %U port %u", getpid (), listen_vpp_handle,
Florin Coras134a9962018-08-28 11:32:04 -07001132 listen_session_handle, client_session->vpp_handle,
Florin Coras0d427d82018-06-27 03:24:07 -07001133 client_session_index,
Florin Coras7e12d942018-06-27 14:32:43 -07001134 client_session->transport.is_ip4 ? "IPv4" : "IPv6",
1135 format_ip46_address, &client_session->transport.rmt_ip,
Florin Coras54693d22018-07-17 10:46:29 -07001136 client_session->transport.is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6,
Florin Coras7e12d942018-06-27 14:32:43 -07001137 clib_net_to_host_u16 (client_session->transport.rmt_port),
1138 client_session->transport.is_ip4 ? "IPv4" : "IPv6",
1139 format_ip46_address, &client_session->transport.lcl_ip,
Florin Coras54693d22018-07-17 10:46:29 -07001140 client_session->transport.is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6,
Florin Coras7e12d942018-06-27 14:32:43 -07001141 clib_net_to_host_u16 (client_session->transport.lcl_port));
Florin Coras0d427d82018-06-27 03:24:07 -07001142 vcl_evt (VCL_EVT_ACCEPT, client_session, listen_session,
1143 client_session_index);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001144
Florin Corasab2f6db2018-08-31 14:31:41 -07001145 return vcl_session_handle (client_session);
Dave Wallace543852a2017-08-03 02:11:34 -04001146}
1147
1148int
Florin Coras134a9962018-08-28 11:32:04 -07001149vppcom_session_connect (uint32_t session_handle, vppcom_endpt_t * server_ep)
Dave Wallace543852a2017-08-03 02:11:34 -04001150{
Florin Coras134a9962018-08-28 11:32:04 -07001151 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras7e12d942018-06-27 14:32:43 -07001152 vcl_session_t *session = 0;
Florin Coras134a9962018-08-28 11:32:04 -07001153 u32 session_index;
Florin Coras070453d2018-08-24 17:04:27 -07001154 int rv;
Dave Wallace543852a2017-08-03 02:11:34 -04001155
Florin Coras134a9962018-08-28 11:32:04 -07001156 session = vcl_session_get_w_handle (wrk, session_handle);
Florin Coras070453d2018-08-24 17:04:27 -07001157 if (!session)
1158 return VPPCOM_EBADFD;
Florin Coras134a9962018-08-28 11:32:04 -07001159 session_index = session->session_index;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001160
1161 if (PREDICT_FALSE (session->is_vep))
Dave Wallace543852a2017-08-03 02:11:34 -04001162 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001163 clib_warning ("VCL<%d>: ERROR: sid %u: cannot "
Florin Coras134a9962018-08-28 11:32:04 -07001164 "connect on an epoll session!", getpid (),
1165 session_handle);
Florin Coras070453d2018-08-24 17:04:27 -07001166 return VPPCOM_EBADFD;
Dave Wallace543852a2017-08-03 02:11:34 -04001167 }
1168
Florin Coras7e12d942018-06-27 14:32:43 -07001169 if (PREDICT_FALSE (session->session_state & CLIENT_STATE_OPEN))
Dave Wallace543852a2017-08-03 02:11:34 -04001170 {
Florin Coras0d427d82018-06-27 03:24:07 -07001171 VDBG (0, "VCL<%d>: vpp handle 0x%llx, sid %u: session already "
1172 "connected to %s %U port %d proto %s, state 0x%x (%s)",
Florin Coras134a9962018-08-28 11:32:04 -07001173 getpid (), session->vpp_handle, session_handle,
Florin Coras7e12d942018-06-27 14:32:43 -07001174 session->transport.is_ip4 ? "IPv4" : "IPv6",
Florin Coras0d427d82018-06-27 03:24:07 -07001175 format_ip46_address,
Florin Coras7e12d942018-06-27 14:32:43 -07001176 &session->transport.rmt_ip, session->transport.is_ip4 ?
Florin Coras0d427d82018-06-27 03:24:07 -07001177 IP46_TYPE_IP4 : IP46_TYPE_IP6,
Florin Coras7e12d942018-06-27 14:32:43 -07001178 clib_net_to_host_u16 (session->transport.rmt_port),
1179 session->session_type ? "UDP" : "TCP", session->session_state,
1180 vppcom_session_state_str (session->session_state));
Florin Coras070453d2018-08-24 17:04:27 -07001181 return VPPCOM_OK;
Dave Wallace543852a2017-08-03 02:11:34 -04001182 }
1183
Florin Coras7e12d942018-06-27 14:32:43 -07001184 session->transport.is_ip4 = server_ep->is_ip4;
1185 if (session->transport.is_ip4)
1186 clib_memcpy (&session->transport.rmt_ip.ip4, server_ep->ip,
Dave Wallaced239f8d2018-06-19 13:37:30 -04001187 sizeof (ip4_address_t));
1188 else
Florin Coras7e12d942018-06-27 14:32:43 -07001189 clib_memcpy (&session->transport.rmt_ip.ip6, server_ep->ip,
Dave Wallaced239f8d2018-06-19 13:37:30 -04001190 sizeof (ip6_address_t));
Florin Coras7e12d942018-06-27 14:32:43 -07001191 session->transport.rmt_port = server_ep->port;
Dave Wallace543852a2017-08-03 02:11:34 -04001192
Florin Coras0d427d82018-06-27 03:24:07 -07001193 VDBG (0, "VCL<%d>: vpp handle 0x%llx, sid %u: connecting to server %s %U "
1194 "port %d proto %s",
Florin Coras134a9962018-08-28 11:32:04 -07001195 getpid (), session->vpp_handle, session_handle,
Florin Coras7e12d942018-06-27 14:32:43 -07001196 session->transport.is_ip4 ? "IPv4" : "IPv6",
Florin Coras0d427d82018-06-27 03:24:07 -07001197 format_ip46_address,
Florin Coras7e12d942018-06-27 14:32:43 -07001198 &session->transport.rmt_ip, session->transport.is_ip4 ?
Florin Coras0d427d82018-06-27 03:24:07 -07001199 IP46_TYPE_IP4 : IP46_TYPE_IP6,
Florin Coras7e12d942018-06-27 14:32:43 -07001200 clib_net_to_host_u16 (session->transport.rmt_port),
1201 session->session_type ? "UDP" : "TCP");
Dave Wallace543852a2017-08-03 02:11:34 -04001202
Florin Coras070453d2018-08-24 17:04:27 -07001203 /*
1204 * Send connect request and wait for reply from vpp
1205 */
Florin Coras134a9962018-08-28 11:32:04 -07001206 vppcom_send_connect_sock (session);
Florin Coras070453d2018-08-24 17:04:27 -07001207 rv = vppcom_wait_for_session_state_change (session_index, STATE_CONNECT,
1208 vcm->cfg.session_timeout);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001209
Florin Coras134a9962018-08-28 11:32:04 -07001210 session = vcl_session_get (wrk, session_index);
Dave Wallace7876d392017-10-19 03:53:57 -04001211
Florin Coras070453d2018-08-24 17:04:27 -07001212 if (PREDICT_FALSE (rv))
Dave Wallaceee45d412017-11-24 21:44:06 -05001213 {
Dave Wallaceee45d412017-11-24 21:44:06 -05001214 if (VPPCOM_DEBUG > 0)
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001215 {
1216 if (session)
Florin Coras0d427d82018-06-27 03:24:07 -07001217 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: connect "
Florin Coras134a9962018-08-28 11:32:04 -07001218 "failed! returning %d (%s)", getpid (),
1219 session->vpp_handle, session_handle, rv,
1220 vppcom_retval_str (rv));
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001221 else
1222 clib_warning ("VCL<%d>: no session for sid %u: connect failed! "
1223 "returning %d (%s)", getpid (),
Florin Coras134a9962018-08-28 11:32:04 -07001224 session_handle, rv, vppcom_retval_str (rv));
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001225 }
Dave Wallaceee45d412017-11-24 21:44:06 -05001226 }
Florin Coras0d427d82018-06-27 03:24:07 -07001227 else
1228 VDBG (0, "VCL<%d>: vpp handle 0x%llx, sid %u: connected!",
Florin Coras134a9962018-08-28 11:32:04 -07001229 getpid (), session->vpp_handle, session_handle);
Dave Wallaceee45d412017-11-24 21:44:06 -05001230
Dave Wallace4878cbe2017-11-21 03:45:09 -05001231 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04001232}
1233
Florin Coras54693d22018-07-17 10:46:29 -07001234static u8
1235vcl_is_rx_evt_for_session (session_event_t * e, u32 sid, u8 is_ct)
1236{
1237 if (!is_ct)
1238 return (e->event_type == FIFO_EVENT_APP_RX
1239 && e->fifo->client_session_index == sid);
1240 else
1241 return (e->event_type == SESSION_IO_EVT_CT_TX);
1242}
1243
Florin Coras460dce62018-07-27 05:45:06 -07001244static inline u8
1245vcl_session_is_readable (vcl_session_t * s)
1246{
1247 return ((s->session_state & STATE_OPEN)
1248 || (s->session_state == STATE_LISTEN
1249 && s->session_type == VPPCOM_PROTO_UDP));
1250}
1251
Steven58f464e2017-10-25 12:33:12 -07001252static inline int
Florin Coras134a9962018-08-28 11:32:04 -07001253vppcom_session_read_internal (uint32_t session_handle, void *buf, int n,
Steven58f464e2017-10-25 12:33:12 -07001254 u8 peek)
Dave Wallace543852a2017-08-03 02:11:34 -04001255{
Florin Coras134a9962018-08-28 11:32:04 -07001256 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras54693d22018-07-17 10:46:29 -07001257 int n_read = 0, rv, is_nonblocking;
Florin Coras460dce62018-07-27 05:45:06 -07001258 vcl_session_t *s = 0;
Dave Wallace543852a2017-08-03 02:11:34 -04001259 svm_fifo_t *rx_fifo;
Florin Coras54693d22018-07-17 10:46:29 -07001260 svm_msg_q_msg_t msg;
1261 session_event_t *e;
1262 svm_msg_q_t *mq;
1263 u8 is_full;
Dave Wallace543852a2017-08-03 02:11:34 -04001264
Florin Coras070453d2018-08-24 17:04:27 -07001265 if (PREDICT_FALSE (!buf))
1266 return VPPCOM_EINVAL;
Dave Wallace543852a2017-08-03 02:11:34 -04001267
Florin Coras134a9962018-08-28 11:32:04 -07001268 s = vcl_session_get_w_handle (wrk, session_handle);
Florin Coras070453d2018-08-24 17:04:27 -07001269 if (PREDICT_FALSE (!s))
1270 return VPPCOM_EBADFD;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001271
Florin Coras460dce62018-07-27 05:45:06 -07001272 if (PREDICT_FALSE (s->is_vep))
Dave Wallace543852a2017-08-03 02:11:34 -04001273 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001274 clib_warning ("VCL<%d>: ERROR: sid %u: cannot "
Florin Coras134a9962018-08-28 11:32:04 -07001275 "read from an epoll session!", getpid (), session_handle);
Florin Coras070453d2018-08-24 17:04:27 -07001276 return VPPCOM_EBADFD;
Dave Wallace543852a2017-08-03 02:11:34 -04001277 }
1278
Florin Coras460dce62018-07-27 05:45:06 -07001279 is_nonblocking = VCL_SESS_ATTR_TEST (s->attr, VCL_SESS_ATTR_NONBLOCK);
1280 rx_fifo = s->rx_fifo;
Florin Coras54693d22018-07-17 10:46:29 -07001281
Florin Coras460dce62018-07-27 05:45:06 -07001282 if (PREDICT_FALSE (!vcl_session_is_readable (s)))
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001283 {
Florin Coras460dce62018-07-27 05:45:06 -07001284 session_state_t state = s->session_state;
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08001285 rv = ((state & STATE_DISCONNECT) ? VPPCOM_ECONNRESET : VPPCOM_ENOTCONN);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001286
Florin Coras0d427d82018-06-27 03:24:07 -07001287 VDBG (0, "VCL<%d>: vpp handle 0x%llx, sid %u: %s session is not open! "
1288 "state 0x%x (%s), returning %d (%s)",
Florin Coras134a9962018-08-28 11:32:04 -07001289 getpid (), s->vpp_handle, session_handle, state,
Florin Coras0d427d82018-06-27 03:24:07 -07001290 vppcom_session_state_str (state), rv, vppcom_retval_str (rv));
Florin Coras070453d2018-08-24 17:04:27 -07001291 return rv;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001292 }
1293
Florin Coras134a9962018-08-28 11:32:04 -07001294 mq = vcl_session_is_ct (s) ? s->our_evt_q : wrk->app_event_queue;
Florin Coras99368312018-08-02 10:45:44 -07001295 svm_fifo_unset_event (rx_fifo);
Florin Coras54693d22018-07-17 10:46:29 -07001296 is_full = svm_fifo_is_full (rx_fifo);
Dave Wallacef7f809c2017-10-03 01:48:42 -04001297
Florin Coras54693d22018-07-17 10:46:29 -07001298 if (svm_fifo_is_empty (rx_fifo))
Dave Wallacef7f809c2017-10-03 01:48:42 -04001299 {
Florin Coras54693d22018-07-17 10:46:29 -07001300 if (is_nonblocking)
Dave Wallace4878cbe2017-11-21 03:45:09 -05001301 {
Florin Coras070453d2018-08-24 17:04:27 -07001302 return VPPCOM_OK;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001303 }
Florin Coras54693d22018-07-17 10:46:29 -07001304 while (1)
1305 {
Florin Coras99368312018-08-02 10:45:44 -07001306 svm_msg_q_lock (mq);
Florin Coras54693d22018-07-17 10:46:29 -07001307 if (svm_msg_q_is_empty (mq))
1308 svm_msg_q_wait (mq);
Florin Coras99368312018-08-02 10:45:44 -07001309
Florin Coras54693d22018-07-17 10:46:29 -07001310 svm_msg_q_sub_w_lock (mq, &msg);
1311 e = svm_msg_q_msg_data (mq, &msg);
Florin Coras99368312018-08-02 10:45:44 -07001312 svm_msg_q_unlock (mq);
Florin Coras134a9962018-08-28 11:32:04 -07001313 if (!vcl_is_rx_evt_for_session (e, s->session_index,
Florin Coras460dce62018-07-27 05:45:06 -07001314 s->our_evt_q != 0))
Florin Coras54693d22018-07-17 10:46:29 -07001315 {
Florin Coras134a9962018-08-28 11:32:04 -07001316 vcl_handle_mq_ctrl_event (wrk, e);
Florin Coras54693d22018-07-17 10:46:29 -07001317 svm_msg_q_free_msg (mq, &msg);
1318 continue;
1319 }
Florin Coras99368312018-08-02 10:45:44 -07001320 svm_fifo_unset_event (rx_fifo);
Florin Coras54693d22018-07-17 10:46:29 -07001321 svm_msg_q_free_msg (mq, &msg);
Florin Coras60f1fc12018-08-16 14:57:31 -07001322 if (PREDICT_FALSE (s->session_state == STATE_CLOSE_ON_EMPTY))
1323 return 0;
1324 if (svm_fifo_is_empty (rx_fifo))
1325 continue;
Florin Coras54693d22018-07-17 10:46:29 -07001326 break;
1327 }
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001328 }
Florin Coras54693d22018-07-17 10:46:29 -07001329
Florin Coras460dce62018-07-27 05:45:06 -07001330 if (s->is_dgram)
Florin Coras99368312018-08-02 10:45:44 -07001331 n_read = app_recv_dgram_raw (rx_fifo, buf, n, &s->transport, 0, peek);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001332 else
Florin Coras99368312018-08-02 10:45:44 -07001333 n_read = app_recv_stream_raw (rx_fifo, buf, n, 0, peek);
Florin Coras54693d22018-07-17 10:46:29 -07001334
Florin Coras460dce62018-07-27 05:45:06 -07001335 if (vcl_session_is_ct (s) && is_full)
Florin Coras99368312018-08-02 10:45:44 -07001336 {
1337 /* If the peer is not polling send notification */
1338 if (!svm_fifo_has_event (s->rx_fifo))
1339 app_send_io_evt_to_vpp (s->vpp_evt_q, s->rx_fifo,
1340 SESSION_IO_EVT_CT_RX, SVM_Q_WAIT);
1341 }
Florin Coras54693d22018-07-17 10:46:29 -07001342
Dave Wallace4878cbe2017-11-21 03:45:09 -05001343 if (VPPCOM_DEBUG > 2)
1344 {
Florin Coras54693d22018-07-17 10:46:29 -07001345 if (n_read > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001346 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: read %d bytes "
Florin Coras460dce62018-07-27 05:45:06 -07001347 "from (%p)", getpid (), s->vpp_handle,
Florin Coras134a9962018-08-28 11:32:04 -07001348 session_handle, n_read, rx_fifo);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001349 else
Dave Wallace048b1d62018-01-03 22:24:41 -05001350 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: nothing read! "
Florin Coras460dce62018-07-27 05:45:06 -07001351 "returning %d (%s)", getpid (), s->vpp_handle,
Florin Coras134a9962018-08-28 11:32:04 -07001352 session_handle, n_read, vppcom_retval_str (n_read));
Dave Wallace4878cbe2017-11-21 03:45:09 -05001353 }
Florin Coras54693d22018-07-17 10:46:29 -07001354 return n_read;
Dave Wallace543852a2017-08-03 02:11:34 -04001355}
1356
Steven58f464e2017-10-25 12:33:12 -07001357int
Florin Coras134a9962018-08-28 11:32:04 -07001358vppcom_session_read (uint32_t session_handle, void *buf, size_t n)
Steven58f464e2017-10-25 12:33:12 -07001359{
Florin Coras134a9962018-08-28 11:32:04 -07001360 return (vppcom_session_read_internal (session_handle, buf, n, 0));
Steven58f464e2017-10-25 12:33:12 -07001361}
1362
1363static int
Florin Coras134a9962018-08-28 11:32:04 -07001364vppcom_session_peek (uint32_t session_handle, void *buf, int n)
Steven58f464e2017-10-25 12:33:12 -07001365{
Florin Coras134a9962018-08-28 11:32:04 -07001366 return (vppcom_session_read_internal (session_handle, buf, n, 1));
Steven58f464e2017-10-25 12:33:12 -07001367}
1368
Dave Wallace543852a2017-08-03 02:11:34 -04001369static inline int
Florin Coras54693d22018-07-17 10:46:29 -07001370vppcom_session_read_ready (vcl_session_t * session)
Dave Wallace543852a2017-08-03 02:11:34 -04001371{
Dave Wallace543852a2017-08-03 02:11:34 -04001372 /* Assumes caller has acquired spinlock: vcm->sessions_lockp */
Dave Wallace4878cbe2017-11-21 03:45:09 -05001373 if (PREDICT_FALSE (session->is_vep))
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001374 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001375 clib_warning ("VCL<%d>: ERROR: sid %u: cannot read from an "
Florin Coras134a9962018-08-28 11:32:04 -07001376 "epoll session!", getpid (), session->session_index);
Florin Coras54693d22018-07-17 10:46:29 -07001377 return VPPCOM_EBADFD;
1378 }
1379
1380 if (PREDICT_FALSE (!(session->session_state & (STATE_OPEN | STATE_LISTEN))))
1381 {
1382 session_state_t state = session->session_state;
1383 int rv;
1384
1385 rv = ((state & STATE_DISCONNECT) ? VPPCOM_ECONNRESET : VPPCOM_ENOTCONN);
1386
1387 VDBG (1, "VCL<%d>: vpp handle 0x%llx, sid %u: session is not open!"
1388 " state 0x%x (%s), returning %d (%s)", getpid (),
Florin Coras134a9962018-08-28 11:32:04 -07001389 session->vpp_handle, session->session_index, state,
Florin Coras54693d22018-07-17 10:46:29 -07001390 vppcom_session_state_str (state), rv, vppcom_retval_str (rv));
1391 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04001392 }
Dave Wallace33e002b2017-09-06 01:20:02 -04001393
Florin Coras7e12d942018-06-27 14:32:43 -07001394 if (session->session_state & STATE_LISTEN)
Florin Coras54693d22018-07-17 10:46:29 -07001395 return clib_fifo_elts (session->accept_evts_fifo);
1396
1397 return svm_fifo_max_dequeue (session->rx_fifo);
1398}
1399
1400static u8
1401vcl_is_tx_evt_for_session (session_event_t * e, u32 sid, u8 is_ct)
1402{
1403 if (!is_ct)
1404 return (e->event_type == FIFO_EVENT_APP_TX
1405 && e->fifo->client_session_index == sid);
Dave Wallace543852a2017-08-03 02:11:34 -04001406 else
Florin Coras54693d22018-07-17 10:46:29 -07001407 return (e->event_type == SESSION_IO_EVT_CT_RX);
Dave Wallace543852a2017-08-03 02:11:34 -04001408}
1409
1410int
Florin Coras134a9962018-08-28 11:32:04 -07001411vppcom_session_write (uint32_t session_handle, void *buf, size_t n)
Dave Wallace543852a2017-08-03 02:11:34 -04001412{
Florin Coras134a9962018-08-28 11:32:04 -07001413 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras54693d22018-07-17 10:46:29 -07001414 int rv, n_write, is_nonblocking;
Florin Coras460dce62018-07-27 05:45:06 -07001415 vcl_session_t *s = 0;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001416 svm_fifo_t *tx_fifo = 0;
Florin Coras460dce62018-07-27 05:45:06 -07001417 session_evt_type_t et;
Florin Coras54693d22018-07-17 10:46:29 -07001418 svm_msg_q_msg_t msg;
1419 session_event_t *e;
Florin Coras3c2fed52018-07-04 04:15:05 -07001420 svm_msg_q_t *mq;
Dave Wallace543852a2017-08-03 02:11:34 -04001421
Florin Coras070453d2018-08-24 17:04:27 -07001422 if (PREDICT_FALSE (!buf))
1423 return VPPCOM_EINVAL;
Dave Wallace543852a2017-08-03 02:11:34 -04001424
Florin Coras134a9962018-08-28 11:32:04 -07001425 s = vcl_session_get_w_handle (wrk, session_handle);
Florin Coras070453d2018-08-24 17:04:27 -07001426 if (PREDICT_FALSE (!s))
1427 return VPPCOM_EBADFD;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001428
Florin Coras460dce62018-07-27 05:45:06 -07001429 tx_fifo = s->tx_fifo;
1430 is_nonblocking = VCL_SESS_ATTR_TEST (s->attr, VCL_SESS_ATTR_NONBLOCK);
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001431
Florin Coras460dce62018-07-27 05:45:06 -07001432 if (PREDICT_FALSE (s->is_vep))
Dave Wallace543852a2017-08-03 02:11:34 -04001433 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001434 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -05001435 "cannot write to an epoll session!",
Florin Coras134a9962018-08-28 11:32:04 -07001436 getpid (), s->vpp_handle, session_handle);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001437
Florin Coras070453d2018-08-24 17:04:27 -07001438 return VPPCOM_EBADFD;
Dave Wallace543852a2017-08-03 02:11:34 -04001439 }
1440
Florin Coras460dce62018-07-27 05:45:06 -07001441 if (!(s->session_state & STATE_OPEN))
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001442 {
Florin Coras460dce62018-07-27 05:45:06 -07001443 session_state_t state = s->session_state;
Florin Coras54693d22018-07-17 10:46:29 -07001444 rv = ((state & STATE_DISCONNECT) ? VPPCOM_ECONNRESET : VPPCOM_ENOTCONN);
Florin Coras0d427d82018-06-27 03:24:07 -07001445 VDBG (1, "VCL<%d>: vpp handle 0x%llx, sid %u: session is not open! "
1446 "state 0x%x (%s)",
Florin Coras134a9962018-08-28 11:32:04 -07001447 getpid (), s->vpp_handle, session_handle,
Florin Coras0d427d82018-06-27 03:24:07 -07001448 state, vppcom_session_state_str (state));
Florin Coras070453d2018-08-24 17:04:27 -07001449 return rv;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001450 }
1451
Florin Coras134a9962018-08-28 11:32:04 -07001452 mq = vcl_session_is_ct (s) ? s->our_evt_q : wrk->app_event_queue;
Florin Coras54693d22018-07-17 10:46:29 -07001453 if (svm_fifo_is_full (tx_fifo))
Dave Wallace543852a2017-08-03 02:11:34 -04001454 {
Florin Coras54693d22018-07-17 10:46:29 -07001455 if (is_nonblocking)
1456 {
Florin Coras070453d2018-08-24 17:04:27 -07001457 return VPPCOM_EWOULDBLOCK;
Florin Coras54693d22018-07-17 10:46:29 -07001458 }
Florin Coras60f1fc12018-08-16 14:57:31 -07001459 while (svm_fifo_is_full (tx_fifo))
Florin Coras54693d22018-07-17 10:46:29 -07001460 {
Florin Coras99368312018-08-02 10:45:44 -07001461 svm_msg_q_lock (mq);
Florin Coras99368312018-08-02 10:45:44 -07001462 while (svm_msg_q_is_empty (mq) && svm_msg_q_timedwait (mq, 10e-6))
1463 ;
Florin Coras54693d22018-07-17 10:46:29 -07001464 svm_msg_q_sub_w_lock (mq, &msg);
1465 e = svm_msg_q_msg_data (mq, &msg);
Florin Coras99368312018-08-02 10:45:44 -07001466 svm_msg_q_unlock (mq);
1467
Florin Coras134a9962018-08-28 11:32:04 -07001468 if (!vcl_is_tx_evt_for_session (e, s->session_index,
Florin Coras460dce62018-07-27 05:45:06 -07001469 s->our_evt_q != 0))
Florin Coras134a9962018-08-28 11:32:04 -07001470 vcl_handle_mq_ctrl_event (wrk, e);
Florin Coras54693d22018-07-17 10:46:29 -07001471 svm_msg_q_free_msg (mq, &msg);
Florin Coras54693d22018-07-17 10:46:29 -07001472 }
Dave Wallace543852a2017-08-03 02:11:34 -04001473 }
Dave Wallace543852a2017-08-03 02:11:34 -04001474
Florin Coras460dce62018-07-27 05:45:06 -07001475 ASSERT (FIFO_EVENT_APP_TX + 1 == SESSION_IO_EVT_CT_TX);
1476 et = FIFO_EVENT_APP_TX + vcl_session_is_ct (s);
1477 if (s->is_dgram)
1478 n_write = app_send_dgram_raw (tx_fifo, &s->transport,
1479 s->vpp_evt_q, buf, n, et, SVM_Q_WAIT);
1480 else
1481 n_write = app_send_stream_raw (tx_fifo, s->vpp_evt_q, buf, n, et,
1482 SVM_Q_WAIT);
Keith Burns (alagalah)410bcca2018-03-23 13:42:49 -07001483
Florin Coras460dce62018-07-27 05:45:06 -07001484 ASSERT (n_write > 0);
Dave Wallace543852a2017-08-03 02:11:34 -04001485
1486 if (VPPCOM_DEBUG > 2)
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001487 {
Dave Wallace4878cbe2017-11-21 03:45:09 -05001488 if (n_write <= 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001489 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
Florin Coras460dce62018-07-27 05:45:06 -07001490 "FIFO-FULL (%p)", getpid (), s->vpp_handle,
Florin Coras134a9962018-08-28 11:32:04 -07001491 session_handle, tx_fifo);
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001492 else
Dave Wallace048b1d62018-01-03 22:24:41 -05001493 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: "
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001494 "wrote %d bytes tx-fifo: (%p)", getpid (),
Florin Coras134a9962018-08-28 11:32:04 -07001495 s->vpp_handle, session_handle, n_write, tx_fifo);
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001496 }
Florin Coras54693d22018-07-17 10:46:29 -07001497 return n_write;
Dave Wallace543852a2017-08-03 02:11:34 -04001498}
1499
Florin Coras99368312018-08-02 10:45:44 -07001500static vcl_session_t *
Florin Coras134a9962018-08-28 11:32:04 -07001501vcl_ct_session_get_from_fifo (vcl_worker_t * wrk, svm_fifo_t * f, u8 type)
Florin Coras99368312018-08-02 10:45:44 -07001502{
1503 vcl_session_t *s;
Florin Coras134a9962018-08-28 11:32:04 -07001504 s = vcl_session_get (wrk, f->client_session_index);
Florin Coras99368312018-08-02 10:45:44 -07001505 if (s)
1506 {
1507 /* rx fifo */
1508 if (type == 0 && s->rx_fifo == f)
1509 return s;
1510 /* tx fifo */
1511 if (type == 1 && s->tx_fifo == f)
1512 return s;
1513 }
Florin Coras134a9962018-08-28 11:32:04 -07001514 s = vcl_session_get (wrk, f->master_session_index);
Florin Coras99368312018-08-02 10:45:44 -07001515 if (s)
1516 {
1517 if (type == 0 && s->rx_fifo == f)
1518 return s;
1519 if (type == 1 && s->tx_fifo == f)
1520 return s;
1521 }
1522 return 0;
1523}
1524
Dave Wallace543852a2017-08-03 02:11:34 -04001525static inline int
Florin Coras134a9962018-08-28 11:32:04 -07001526vppcom_session_write_ready (vcl_session_t * session)
Dave Wallace543852a2017-08-03 02:11:34 -04001527{
Dave Wallace543852a2017-08-03 02:11:34 -04001528 /* Assumes caller has acquired spinlock: vcm->sessions_lockp */
Dave Wallace4878cbe2017-11-21 03:45:09 -05001529 if (PREDICT_FALSE (session->is_vep))
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001530 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001531 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -05001532 "cannot write to an epoll session!",
Florin Coras134a9962018-08-28 11:32:04 -07001533 getpid (), session->vpp_handle, session->session_index);
Florin Coras54693d22018-07-17 10:46:29 -07001534 return VPPCOM_EBADFD;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001535 }
1536
Florin Coras7e12d942018-06-27 14:32:43 -07001537 if (PREDICT_FALSE (session->session_state & STATE_LISTEN))
Dave Wallace33e002b2017-09-06 01:20:02 -04001538 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001539 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -05001540 "cannot write to a listen session!",
Florin Coras134a9962018-08-28 11:32:04 -07001541 getpid (), session->vpp_handle, session->session_index);
Florin Coras54693d22018-07-17 10:46:29 -07001542 return VPPCOM_EBADFD;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001543 }
1544
Florin Coras54693d22018-07-17 10:46:29 -07001545 if (PREDICT_FALSE (!(session->session_state & STATE_OPEN)))
Dave Wallace4878cbe2017-11-21 03:45:09 -05001546 {
Florin Coras7e12d942018-06-27 14:32:43 -07001547 session_state_t state = session->session_state;
Florin Coras54693d22018-07-17 10:46:29 -07001548 int rv;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001549
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08001550 rv = ((state & STATE_DISCONNECT) ? VPPCOM_ECONNRESET : VPPCOM_ENOTCONN);
Dave Wallace048b1d62018-01-03 22:24:41 -05001551 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001552 "session is not open! state 0x%x (%s), "
Dave Wallaceee45d412017-11-24 21:44:06 -05001553 "returning %d (%s)", getpid (), session->vpp_handle,
Florin Coras134a9962018-08-28 11:32:04 -07001554 session->session_index,
Dave Wallace4878cbe2017-11-21 03:45:09 -05001555 state, vppcom_session_state_str (state),
1556 rv, vppcom_retval_str (rv));
Florin Coras54693d22018-07-17 10:46:29 -07001557 return rv;
Dave Wallace33e002b2017-09-06 01:20:02 -04001558 }
1559
Florin Coras0d427d82018-06-27 03:24:07 -07001560 VDBG (3, "VCL<%d>: vpp handle 0x%llx, sid %u: peek %s (%p), ready = %d",
Florin Coras134a9962018-08-28 11:32:04 -07001561 getpid (), session->vpp_handle, session->session_index,
1562 session->tx_fifo, svm_fifo_max_enqueue (session->tx_fifo));
Dave Wallacef7f809c2017-10-03 01:48:42 -04001563
Florin Coras54693d22018-07-17 10:46:29 -07001564 return svm_fifo_max_enqueue (session->tx_fifo);
1565}
1566
Florin Coras99368312018-08-02 10:45:44 -07001567static inline int
Florin Coras134a9962018-08-28 11:32:04 -07001568vcl_mq_dequeue_batch (vcl_worker_t * wrk, svm_msg_q_t * mq)
Florin Coras99368312018-08-02 10:45:44 -07001569{
1570 svm_msg_q_msg_t *msg;
1571 u32 n_msgs;
1572 int i;
1573
1574 n_msgs = svm_msg_q_size (mq);
1575 for (i = 0; i < n_msgs; i++)
1576 {
Florin Coras134a9962018-08-28 11:32:04 -07001577 vec_add2 (wrk->mq_msg_vector, msg, 1);
Florin Coras99368312018-08-02 10:45:44 -07001578 svm_msg_q_sub_w_lock (mq, msg);
1579 }
1580 return n_msgs;
1581}
1582
Florin Coras54693d22018-07-17 10:46:29 -07001583static int
Florin Coras134a9962018-08-28 11:32:04 -07001584vcl_select_handle_mq (vcl_worker_t * wrk, svm_msg_q_t * mq,
1585 unsigned long n_bits, unsigned long *read_map,
1586 unsigned long *write_map, unsigned long *except_map,
1587 double time_to_wait, u32 * bits_set)
Florin Coras54693d22018-07-17 10:46:29 -07001588{
1589 session_disconnected_msg_t *disconnected_msg;
Florin Coras99368312018-08-02 10:45:44 -07001590 session_connected_msg_t *connected_msg;
Florin Coras54693d22018-07-17 10:46:29 -07001591 session_accepted_msg_t *accepted_msg;
1592 vcl_session_msg_t *vcl_msg;
1593 vcl_session_t *session;
Florin Coras99368312018-08-02 10:45:44 -07001594 svm_msg_q_msg_t *msg;
Florin Coras54693d22018-07-17 10:46:29 -07001595 session_event_t *e;
Florin Coras99368312018-08-02 10:45:44 -07001596 u32 i, sid;
Florin Coras54693d22018-07-17 10:46:29 -07001597 u64 handle;
1598
1599 svm_msg_q_lock (mq);
1600 if (svm_msg_q_is_empty (mq))
Dave Wallace4878cbe2017-11-21 03:45:09 -05001601 {
Florin Coras54693d22018-07-17 10:46:29 -07001602 if (*bits_set)
Dave Wallace4878cbe2017-11-21 03:45:09 -05001603 {
Florin Coras54693d22018-07-17 10:46:29 -07001604 svm_msg_q_unlock (mq);
1605 return 0;
1606 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05001607
Florin Coras54693d22018-07-17 10:46:29 -07001608 if (!time_to_wait)
1609 {
1610 svm_msg_q_unlock (mq);
1611 return 0;
1612 }
1613 else if (time_to_wait < 0)
1614 {
1615 svm_msg_q_wait (mq);
1616 }
1617 else
1618 {
1619 if (svm_msg_q_timedwait (mq, time_to_wait))
1620 {
1621 svm_msg_q_unlock (mq);
1622 return 0;
1623 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05001624 }
1625 }
Florin Coras134a9962018-08-28 11:32:04 -07001626 vcl_mq_dequeue_batch (wrk, mq);
Florin Coras54693d22018-07-17 10:46:29 -07001627 svm_msg_q_unlock (mq);
1628
Florin Coras134a9962018-08-28 11:32:04 -07001629 for (i = 0; i < vec_len (wrk->mq_msg_vector); i++)
Florin Coras54693d22018-07-17 10:46:29 -07001630 {
Florin Coras134a9962018-08-28 11:32:04 -07001631 msg = vec_elt_at_index (wrk->mq_msg_vector, i);
Florin Coras99368312018-08-02 10:45:44 -07001632 e = svm_msg_q_msg_data (mq, msg);
Florin Coras54693d22018-07-17 10:46:29 -07001633 switch (e->event_type)
1634 {
1635 case FIFO_EVENT_APP_RX:
1636 sid = e->fifo->client_session_index;
Florin Coras134a9962018-08-28 11:32:04 -07001637 session = vcl_session_get (wrk, sid);
Florin Coras14598772018-09-04 19:47:52 -07001638 if (!session)
1639 break;
Florin Coras54693d22018-07-17 10:46:29 -07001640 if (sid < n_bits && read_map)
1641 {
1642 clib_bitmap_set_no_check (read_map, sid, 1);
1643 *bits_set += 1;
1644 }
1645 break;
1646 case FIFO_EVENT_APP_TX:
1647 sid = e->fifo->client_session_index;
Florin Coras134a9962018-08-28 11:32:04 -07001648 session = vcl_session_get (wrk, sid);
Florin Coras60f1fc12018-08-16 14:57:31 -07001649 if (!session)
Florin Coras54693d22018-07-17 10:46:29 -07001650 break;
1651 if (sid < n_bits && write_map)
1652 {
1653 clib_bitmap_set_no_check (write_map, sid, 1);
1654 *bits_set += 1;
1655 }
1656 break;
1657 case SESSION_IO_EVT_CT_TX:
Florin Corasab2f6db2018-08-31 14:31:41 -07001658 if (svm_fifo_is_empty (e->fifo))
1659 {
1660 svm_fifo_unset_event (e->fifo);
1661 if (svm_fifo_is_empty (e->fifo))
1662 break;
1663 }
Florin Coras134a9962018-08-28 11:32:04 -07001664 session = vcl_ct_session_get_from_fifo (wrk, e->fifo, 0);
Florin Coras14598772018-09-04 19:47:52 -07001665 if (!session)
1666 break;
Florin Coras134a9962018-08-28 11:32:04 -07001667 sid = session->session_index;
Florin Coras54693d22018-07-17 10:46:29 -07001668 if (sid < n_bits && read_map)
1669 {
1670 clib_bitmap_set_no_check (read_map, sid, 1);
1671 *bits_set += 1;
1672 }
1673 break;
Florin Coras54693d22018-07-17 10:46:29 -07001674 case SESSION_IO_EVT_CT_RX:
Florin Coras134a9962018-08-28 11:32:04 -07001675 session = vcl_ct_session_get_from_fifo (wrk, e->fifo, 1);
Florin Coras60f1fc12018-08-16 14:57:31 -07001676 if (!session)
Florin Coras54693d22018-07-17 10:46:29 -07001677 break;
Florin Coras14598772018-09-04 19:47:52 -07001678 sid = session->session_index;
Florin Coras54693d22018-07-17 10:46:29 -07001679 if (sid < n_bits && write_map)
1680 {
1681 clib_bitmap_set_no_check (write_map, sid, 1);
1682 *bits_set += 1;
1683 }
1684 break;
1685 case SESSION_CTRL_EVT_ACCEPTED:
1686 accepted_msg = (session_accepted_msg_t *) e->data;
1687 handle = accepted_msg->listener_handle;
Florin Coras134a9962018-08-28 11:32:04 -07001688 session = vcl_session_table_lookup_listener (wrk, handle);
Florin Coras54693d22018-07-17 10:46:29 -07001689 if (!session)
1690 {
1691 clib_warning ("VCL<%d>: ERROR: couldn't find listen session:"
1692 "listener handle %llx", getpid (), handle);
1693 break;
1694 }
1695
1696 clib_fifo_add2 (session->accept_evts_fifo, vcl_msg);
1697 vcl_msg->accepted_msg = *accepted_msg;
Florin Coras134a9962018-08-28 11:32:04 -07001698 sid = session->session_index;
Florin Coras54693d22018-07-17 10:46:29 -07001699 if (sid < n_bits && read_map)
1700 {
1701 clib_bitmap_set_no_check (read_map, sid, 1);
1702 *bits_set += 1;
1703 }
1704 break;
Florin Coras99368312018-08-02 10:45:44 -07001705 case SESSION_CTRL_EVT_CONNECTED:
1706 connected_msg = (session_connected_msg_t *) e->data;
Florin Coras134a9962018-08-28 11:32:04 -07001707 vcl_session_connected_handler (wrk, connected_msg);
Florin Coras99368312018-08-02 10:45:44 -07001708 break;
Florin Coras54693d22018-07-17 10:46:29 -07001709 case SESSION_CTRL_EVT_DISCONNECTED:
1710 disconnected_msg = (session_disconnected_msg_t *) e->data;
Florin Coras134a9962018-08-28 11:32:04 -07001711 sid = vcl_session_index_from_vpp_handle (wrk,
1712 disconnected_msg->handle);
Florin Coras54693d22018-07-17 10:46:29 -07001713 if (sid < n_bits && except_map)
1714 {
1715 clib_bitmap_set_no_check (except_map, sid, 1);
1716 *bits_set += 1;
1717 }
1718 break;
Florin Corasc9fbd662018-08-24 12:59:56 -07001719 case SESSION_CTRL_EVT_RESET:
Florin Coras134a9962018-08-28 11:32:04 -07001720 sid = vcl_session_reset_handler (wrk,
1721 (session_reset_msg_t *) e->data);
Florin Corasc9fbd662018-08-24 12:59:56 -07001722 if (sid < n_bits && except_map)
1723 {
1724 clib_bitmap_set_no_check (except_map, sid, 1);
1725 *bits_set += 1;
1726 }
1727 break;
Florin Coras54693d22018-07-17 10:46:29 -07001728 default:
1729 clib_warning ("unhandled: %u", e->event_type);
1730 break;
1731 }
Florin Coras99368312018-08-02 10:45:44 -07001732 svm_msg_q_free_msg (mq, msg);
Florin Coras54693d22018-07-17 10:46:29 -07001733 }
1734
Florin Coras134a9962018-08-28 11:32:04 -07001735 vec_reset_length (wrk->mq_msg_vector);
Florin Coras54693d22018-07-17 10:46:29 -07001736 return *bits_set;
Dave Wallace543852a2017-08-03 02:11:34 -04001737}
1738
Florin Coras99368312018-08-02 10:45:44 -07001739static int
Florin Coras134a9962018-08-28 11:32:04 -07001740vppcom_select_condvar (vcl_worker_t * wrk, unsigned long n_bits,
1741 unsigned long *read_map, unsigned long *write_map,
1742 unsigned long *except_map, double time_to_wait,
1743 u32 * bits_set)
Florin Coras99368312018-08-02 10:45:44 -07001744{
1745 double total_wait = 0, wait_slice;
1746 vcl_cut_through_registration_t *cr;
1747
1748 time_to_wait = (time_to_wait == -1) ? 10e9 : time_to_wait;
Florin Coras134a9962018-08-28 11:32:04 -07001749 wait_slice = wrk->cut_through_registrations ? 10e-6 : time_to_wait;
Florin Coras99368312018-08-02 10:45:44 -07001750 do
1751 {
Florin Coras134a9962018-08-28 11:32:04 -07001752 vcl_ct_registration_lock (wrk);
Florin Coras99368312018-08-02 10:45:44 -07001753 /* *INDENT-OFF* */
Florin Coras134a9962018-08-28 11:32:04 -07001754 pool_foreach (cr, wrk->cut_through_registrations, ({
1755 vcl_select_handle_mq (wrk, cr->mq, n_bits, read_map, write_map, except_map,
Florin Coras99368312018-08-02 10:45:44 -07001756 0, bits_set);
1757 }));
1758 /* *INDENT-ON* */
Florin Coras134a9962018-08-28 11:32:04 -07001759 vcl_ct_registration_unlock (wrk);
Florin Coras99368312018-08-02 10:45:44 -07001760
Florin Coras134a9962018-08-28 11:32:04 -07001761 vcl_select_handle_mq (wrk, wrk->app_event_queue, n_bits, read_map,
1762 write_map, except_map, time_to_wait, bits_set);
Florin Coras99368312018-08-02 10:45:44 -07001763 total_wait += wait_slice;
1764 if (*bits_set)
1765 return *bits_set;
1766 }
1767 while (total_wait < time_to_wait);
1768
1769 return 0;
1770}
1771
1772static int
Florin Coras134a9962018-08-28 11:32:04 -07001773vppcom_select_eventfd (vcl_worker_t * wrk, unsigned long n_bits,
1774 unsigned long *read_map, unsigned long *write_map,
1775 unsigned long *except_map, double time_to_wait,
1776 u32 * bits_set)
Florin Coras99368312018-08-02 10:45:44 -07001777{
1778 vcl_mq_evt_conn_t *mqc;
1779 int __clib_unused n_read;
1780 int n_mq_evts, i;
1781 u64 buf;
1782
Florin Coras134a9962018-08-28 11:32:04 -07001783 vec_validate (wrk->mq_events, pool_elts (wrk->mq_evt_conns));
1784 n_mq_evts = epoll_wait (wrk->mqs_epfd, wrk->mq_events,
1785 vec_len (wrk->mq_events), time_to_wait);
Florin Coras99368312018-08-02 10:45:44 -07001786 for (i = 0; i < n_mq_evts; i++)
1787 {
Florin Coras134a9962018-08-28 11:32:04 -07001788 mqc = vcl_mq_evt_conn_get (wrk, wrk->mq_events[i].data.u32);
Florin Coras99368312018-08-02 10:45:44 -07001789 n_read = read (mqc->mq_fd, &buf, sizeof (buf));
Florin Coras134a9962018-08-28 11:32:04 -07001790 vcl_select_handle_mq (wrk, mqc->mq, n_bits, read_map, write_map,
Florin Coras99368312018-08-02 10:45:44 -07001791 except_map, 0, bits_set);
1792 }
1793
1794 return (n_mq_evts > 0 ? (int) *bits_set : 0);
1795}
1796
Dave Wallace543852a2017-08-03 02:11:34 -04001797int
1798vppcom_select (unsigned long n_bits, unsigned long *read_map,
1799 unsigned long *write_map, unsigned long *except_map,
1800 double time_to_wait)
1801{
Florin Coras54693d22018-07-17 10:46:29 -07001802 u32 sid, minbits = clib_max (n_bits, BITS (uword)), bits_set = 0;
Florin Coras134a9962018-08-28 11:32:04 -07001803 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras7e12d942018-06-27 14:32:43 -07001804 vcl_session_t *session = 0;
Florin Coras54693d22018-07-17 10:46:29 -07001805 int rv;
Dave Wallace543852a2017-08-03 02:11:34 -04001806
1807 ASSERT (sizeof (clib_bitmap_t) == sizeof (long int));
1808
Dave Wallace7876d392017-10-19 03:53:57 -04001809 if (n_bits && read_map)
Dave Wallace543852a2017-08-03 02:11:34 -04001810 {
Florin Coras134a9962018-08-28 11:32:04 -07001811 clib_bitmap_validate (wrk->rd_bitmap, minbits);
1812 clib_memcpy (wrk->rd_bitmap, read_map,
1813 vec_len (wrk->rd_bitmap) * sizeof (clib_bitmap_t));
1814 memset (read_map, 0, vec_len (wrk->rd_bitmap) * sizeof (clib_bitmap_t));
Dave Wallace543852a2017-08-03 02:11:34 -04001815 }
Dave Wallace7876d392017-10-19 03:53:57 -04001816 if (n_bits && write_map)
Dave Wallace543852a2017-08-03 02:11:34 -04001817 {
Florin Coras134a9962018-08-28 11:32:04 -07001818 clib_bitmap_validate (wrk->wr_bitmap, minbits);
1819 clib_memcpy (wrk->wr_bitmap, write_map,
1820 vec_len (wrk->wr_bitmap) * sizeof (clib_bitmap_t));
Dave Wallace048b1d62018-01-03 22:24:41 -05001821 memset (write_map, 0,
Florin Coras134a9962018-08-28 11:32:04 -07001822 vec_len (wrk->wr_bitmap) * sizeof (clib_bitmap_t));
Dave Wallace543852a2017-08-03 02:11:34 -04001823 }
Dave Wallace7876d392017-10-19 03:53:57 -04001824 if (n_bits && except_map)
Dave Wallace543852a2017-08-03 02:11:34 -04001825 {
Florin Coras134a9962018-08-28 11:32:04 -07001826 clib_bitmap_validate (wrk->ex_bitmap, minbits);
1827 clib_memcpy (wrk->ex_bitmap, except_map,
1828 vec_len (wrk->ex_bitmap) * sizeof (clib_bitmap_t));
Dave Wallace048b1d62018-01-03 22:24:41 -05001829 memset (except_map, 0,
Florin Coras134a9962018-08-28 11:32:04 -07001830 vec_len (wrk->ex_bitmap) * sizeof (clib_bitmap_t));
Dave Wallace543852a2017-08-03 02:11:34 -04001831 }
1832
Florin Coras54693d22018-07-17 10:46:29 -07001833 if (!n_bits)
1834 return 0;
1835
1836 if (!write_map)
1837 goto check_rd;
1838
1839 /* *INDENT-OFF* */
Florin Coras134a9962018-08-28 11:32:04 -07001840 clib_bitmap_foreach (sid, wrk->wr_bitmap, ({
1841 if (!(session = vcl_session_get (wrk, sid)))
Florin Coras54693d22018-07-17 10:46:29 -07001842 {
Florin Coras54693d22018-07-17 10:46:29 -07001843 VDBG (0, "VCL<%d>: session %d specified in write_map is closed.",
1844 getpid (), sid);
1845 return VPPCOM_EBADFD;
1846 }
1847
1848 rv = svm_fifo_is_full (session->tx_fifo);
Florin Coras54693d22018-07-17 10:46:29 -07001849 if (!rv)
1850 {
1851 clib_bitmap_set_no_check (write_map, sid, 1);
1852 bits_set++;
1853 }
1854 }));
1855
1856check_rd:
1857 if (!read_map)
1858 goto check_mq;
Florin Coras99368312018-08-02 10:45:44 -07001859
Florin Coras134a9962018-08-28 11:32:04 -07001860 clib_bitmap_foreach (sid, wrk->rd_bitmap, ({
1861 if (!(session = vcl_session_get (wrk, sid)))
Florin Coras54693d22018-07-17 10:46:29 -07001862 {
Florin Coras54693d22018-07-17 10:46:29 -07001863 VDBG (0, "VCL<%d>: session %d specified in write_map is closed.",
1864 getpid (), sid);
1865 return VPPCOM_EBADFD;
1866 }
1867
1868 rv = vppcom_session_read_ready (session);
Florin Coras54693d22018-07-17 10:46:29 -07001869 if (rv)
1870 {
1871 clib_bitmap_set_no_check (read_map, sid, 1);
1872 bits_set++;
1873 }
1874 }));
1875 /* *INDENT-ON* */
1876
1877check_mq:
Dave Wallace543852a2017-08-03 02:11:34 -04001878
Florin Coras99368312018-08-02 10:45:44 -07001879 if (vcm->cfg.use_mq_eventfd)
Florin Coras134a9962018-08-28 11:32:04 -07001880 vppcom_select_eventfd (wrk, n_bits, read_map, write_map, except_map,
Florin Coras99368312018-08-02 10:45:44 -07001881 time_to_wait, &bits_set);
1882 else
Florin Coras134a9962018-08-28 11:32:04 -07001883 vppcom_select_condvar (wrk, n_bits, read_map, write_map, except_map,
Florin Coras99368312018-08-02 10:45:44 -07001884 time_to_wait, &bits_set);
Florin Coras54693d22018-07-17 10:46:29 -07001885
Dave Wallace543852a2017-08-03 02:11:34 -04001886 return (bits_set);
1887}
1888
Dave Wallacef7f809c2017-10-03 01:48:42 -04001889static inline void
Florin Coras134a9962018-08-28 11:32:04 -07001890vep_verify_epoll_chain (vcl_worker_t * wrk, u32 vep_idx)
Dave Wallacef7f809c2017-10-03 01:48:42 -04001891{
Florin Coras7e12d942018-06-27 14:32:43 -07001892 vcl_session_t *session;
Dave Wallacef7f809c2017-10-03 01:48:42 -04001893 vppcom_epoll_t *vep;
Dave Wallace498b3a52017-11-09 13:00:34 -05001894 u32 sid = vep_idx;
Dave Wallacef7f809c2017-10-03 01:48:42 -04001895
Dave Wallace498b3a52017-11-09 13:00:34 -05001896 if (VPPCOM_DEBUG <= 1)
Dave Wallacef7f809c2017-10-03 01:48:42 -04001897 return;
1898
1899 /* Assumes caller has acquired spinlock: vcm->sessions_lockp */
Florin Coras134a9962018-08-28 11:32:04 -07001900 session = vcl_session_get (wrk, vep_idx);
Florin Coras070453d2018-08-24 17:04:27 -07001901 if (PREDICT_FALSE (!session))
Dave Wallacef7f809c2017-10-03 01:48:42 -04001902 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001903 clib_warning ("VCL<%d>: ERROR: Invalid vep_idx (%u)!",
1904 getpid (), vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04001905 goto done;
1906 }
1907 if (PREDICT_FALSE (!session->is_vep))
1908 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001909 clib_warning ("VCL<%d>: ERROR: vep_idx (%u) is not a vep!",
1910 getpid (), vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04001911 goto done;
1912 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05001913 vep = &session->vep;
Dave Wallace048b1d62018-01-03 22:24:41 -05001914 clib_warning ("VCL<%d>: vep_idx (%u): Dumping epoll chain\n"
Dave Wallace498b3a52017-11-09 13:00:34 -05001915 "{\n"
1916 " is_vep = %u\n"
1917 " is_vep_session = %u\n"
Dave Wallace4878cbe2017-11-21 03:45:09 -05001918 " next_sid = 0x%x (%u)\n"
Dave Wallace498b3a52017-11-09 13:00:34 -05001919 " wait_cont_idx = 0x%x (%u)\n"
Dave Wallace4878cbe2017-11-21 03:45:09 -05001920 "}\n", getpid (), vep_idx,
1921 session->is_vep, session->is_vep_session,
Florin Coras134a9962018-08-28 11:32:04 -07001922 vep->next_sh, vep->next_sh,
Dave Wallace498b3a52017-11-09 13:00:34 -05001923 session->wait_cont_idx, session->wait_cont_idx);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001924
Florin Coras134a9962018-08-28 11:32:04 -07001925 for (sid = vep->next_sh; sid != ~0; sid = vep->next_sh)
Dave Wallacef7f809c2017-10-03 01:48:42 -04001926 {
Florin Coras134a9962018-08-28 11:32:04 -07001927 session = vcl_session_get (wrk, sid);
Florin Coras070453d2018-08-24 17:04:27 -07001928 if (PREDICT_FALSE (!session))
Dave Wallacef7f809c2017-10-03 01:48:42 -04001929 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001930 clib_warning ("VCL<%d>: ERROR: Invalid sid (%u)!", getpid (), sid);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001931 goto done;
1932 }
1933 if (PREDICT_FALSE (session->is_vep))
Dave Wallace048b1d62018-01-03 22:24:41 -05001934 clib_warning ("VCL<%d>: ERROR: sid (%u) is a vep!",
1935 getpid (), vep_idx);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001936 else if (PREDICT_FALSE (!session->is_vep_session))
1937 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001938 clib_warning ("VCL<%d>: ERROR: session (%u) "
1939 "is not a vep session!", getpid (), sid);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001940 goto done;
1941 }
1942 vep = &session->vep;
Florin Coras134a9962018-08-28 11:32:04 -07001943 if (PREDICT_FALSE (vep->vep_sh != vep_idx))
Dave Wallace048b1d62018-01-03 22:24:41 -05001944 clib_warning ("VCL<%d>: ERROR: session (%u) vep_idx (%u) != "
Dave Wallace4878cbe2017-11-21 03:45:09 -05001945 "vep_idx (%u)!", getpid (),
Florin Coras134a9962018-08-28 11:32:04 -07001946 sid, session->vep.vep_sh, vep_idx);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001947 if (session->is_vep_session)
1948 {
1949 clib_warning ("vep_idx[%u]: sid 0x%x (%u)\n"
1950 "{\n"
1951 " next_sid = 0x%x (%u)\n"
1952 " prev_sid = 0x%x (%u)\n"
1953 " vep_idx = 0x%x (%u)\n"
1954 " ev.events = 0x%x\n"
1955 " ev.data.u64 = 0x%llx\n"
1956 " et_mask = 0x%x\n"
1957 "}\n",
1958 vep_idx, sid, sid,
Florin Coras134a9962018-08-28 11:32:04 -07001959 vep->next_sh, vep->next_sh,
1960 vep->prev_sh, vep->prev_sh,
1961 vep->vep_sh, vep->vep_sh,
Dave Wallace4878cbe2017-11-21 03:45:09 -05001962 vep->ev.events, vep->ev.data.u64, vep->et_mask);
Dave Wallacef7f809c2017-10-03 01:48:42 -04001963 }
1964 }
Dave Wallacef7f809c2017-10-03 01:48:42 -04001965
1966done:
Dave Wallace048b1d62018-01-03 22:24:41 -05001967 clib_warning ("VCL<%d>: vep_idx (%u): Dump complete!\n",
1968 getpid (), vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04001969}
1970
1971int
1972vppcom_epoll_create (void)
1973{
Florin Coras134a9962018-08-28 11:32:04 -07001974 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras7e12d942018-06-27 14:32:43 -07001975 vcl_session_t *vep_session;
Dave Wallacef7f809c2017-10-03 01:48:42 -04001976
Florin Coras134a9962018-08-28 11:32:04 -07001977 vep_session = vcl_session_alloc (wrk);
Dave Wallacef7f809c2017-10-03 01:48:42 -04001978
1979 vep_session->is_vep = 1;
Florin Coras134a9962018-08-28 11:32:04 -07001980 vep_session->vep.vep_sh = ~0;
1981 vep_session->vep.next_sh = ~0;
1982 vep_session->vep.prev_sh = ~0;
Dave Wallacef7f809c2017-10-03 01:48:42 -04001983 vep_session->wait_cont_idx = ~0;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001984 vep_session->vpp_handle = ~0;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001985
Florin Coras134a9962018-08-28 11:32:04 -07001986 vcl_evt (VCL_EVT_EPOLL_CREATE, vep_session, vep_sh);
Florin Coras0d427d82018-06-27 03:24:07 -07001987 VDBG (0, "VCL<%d>: Created vep_idx %u / sid %u!",
Florin Coras134a9962018-08-28 11:32:04 -07001988 getpid (), vep_session->session_index, vep_session->session_index);
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08001989
Florin Corasab2f6db2018-08-31 14:31:41 -07001990 return vcl_session_handle (vep_session);
Dave Wallacef7f809c2017-10-03 01:48:42 -04001991}
1992
1993int
Florin Coras134a9962018-08-28 11:32:04 -07001994vppcom_epoll_ctl (uint32_t vep_handle, int op, uint32_t session_handle,
Dave Wallacef7f809c2017-10-03 01:48:42 -04001995 struct epoll_event *event)
1996{
Florin Coras134a9962018-08-28 11:32:04 -07001997 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras7e12d942018-06-27 14:32:43 -07001998 vcl_session_t *vep_session;
1999 vcl_session_t *session;
Florin Coras070453d2018-08-24 17:04:27 -07002000 int rv = VPPCOM_OK;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002001
Florin Coras134a9962018-08-28 11:32:04 -07002002 if (vep_handle == session_handle)
Dave Wallacef7f809c2017-10-03 01:48:42 -04002003 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002004 clib_warning ("VCL<%d>: ERROR: vep_idx == session_index (%u)!",
Florin Coras134a9962018-08-28 11:32:04 -07002005 getpid (), vep_handle);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002006 return VPPCOM_EINVAL;
2007 }
2008
Florin Coras134a9962018-08-28 11:32:04 -07002009 vep_session = vcl_session_get_w_handle (wrk, vep_handle);
Florin Coras070453d2018-08-24 17:04:27 -07002010 if (PREDICT_FALSE (!vep_session))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002011 {
Florin Coras134a9962018-08-28 11:32:04 -07002012 clib_warning ("VCL<%d>: ERROR: Invalid vep_idx (%u)!", vep_handle);
Florin Coras070453d2018-08-24 17:04:27 -07002013 return VPPCOM_EBADFD;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002014 }
2015 if (PREDICT_FALSE (!vep_session->is_vep))
2016 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002017 clib_warning ("VCL<%d>: ERROR: vep_idx (%u) is not a vep!",
Florin Coras134a9962018-08-28 11:32:04 -07002018 getpid (), vep_handle);
Florin Coras070453d2018-08-24 17:04:27 -07002019 return VPPCOM_EINVAL;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002020 }
2021
Florin Coras134a9962018-08-28 11:32:04 -07002022 ASSERT (vep_session->vep.vep_sh == ~0);
2023 ASSERT (vep_session->vep.prev_sh == ~0);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002024
Florin Coras134a9962018-08-28 11:32:04 -07002025 session = vcl_session_get_w_handle (wrk, session_handle);
Florin Coras070453d2018-08-24 17:04:27 -07002026 if (PREDICT_FALSE (!session))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002027 {
Florin Coras134a9962018-08-28 11:32:04 -07002028 VDBG (0, "VCL<%d>: ERROR: Invalid session_handle (%u)!",
2029 getpid (), session_handle);
Florin Coras070453d2018-08-24 17:04:27 -07002030 return VPPCOM_EBADFD;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002031 }
2032 if (PREDICT_FALSE (session->is_vep))
2033 {
Florin Coras134a9962018-08-28 11:32:04 -07002034 clib_warning ("ERROR: session_handle (%u) is a vep!", vep_handle);
Florin Coras070453d2018-08-24 17:04:27 -07002035 return VPPCOM_EINVAL;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002036 }
2037
2038 switch (op)
2039 {
2040 case EPOLL_CTL_ADD:
2041 if (PREDICT_FALSE (!event))
2042 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002043 clib_warning ("VCL<%d>: ERROR: EPOLL_CTL_ADD: NULL pointer to "
Dave Wallace2e005bb2017-11-07 01:21:39 -05002044 "epoll_event structure!", getpid ());
Florin Coras070453d2018-08-24 17:04:27 -07002045 return VPPCOM_EINVAL;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002046 }
Florin Coras134a9962018-08-28 11:32:04 -07002047 if (vep_session->vep.next_sh != ~0)
Dave Wallacef7f809c2017-10-03 01:48:42 -04002048 {
Florin Coras7e12d942018-06-27 14:32:43 -07002049 vcl_session_t *next_session;
Florin Corasab2f6db2018-08-31 14:31:41 -07002050 next_session = vcl_session_get_w_handle (wrk,
2051 vep_session->vep.next_sh);
Florin Coras070453d2018-08-24 17:04:27 -07002052 if (PREDICT_FALSE (!next_session))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002053 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002054 clib_warning ("VCL<%d>: ERROR: EPOLL_CTL_ADD: Invalid "
Dave Wallace4878cbe2017-11-21 03:45:09 -05002055 "vep.next_sid (%u) on vep_idx (%u)!",
Florin Coras134a9962018-08-28 11:32:04 -07002056 getpid (), vep_session->vep.next_sh, vep_handle);
Florin Coras070453d2018-08-24 17:04:27 -07002057 return VPPCOM_EBADFD;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002058 }
Florin Coras134a9962018-08-28 11:32:04 -07002059 ASSERT (next_session->vep.prev_sh == vep_handle);
2060 next_session->vep.prev_sh = session_handle;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002061 }
Florin Coras134a9962018-08-28 11:32:04 -07002062 session->vep.next_sh = vep_session->vep.next_sh;
2063 session->vep.prev_sh = vep_handle;
2064 session->vep.vep_sh = vep_handle;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002065 session->vep.et_mask = VEP_DEFAULT_ET_MASK;
2066 session->vep.ev = *event;
Dave Wallace4878cbe2017-11-21 03:45:09 -05002067 session->is_vep = 0;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002068 session->is_vep_session = 1;
Florin Coras134a9962018-08-28 11:32:04 -07002069 vep_session->vep.next_sh = session_handle;
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002070
Florin Coras070453d2018-08-24 17:04:27 -07002071 VDBG (1, "VCL<%d>: EPOLL_CTL_ADD: vep_idx %u, sid %u, events 0x%x, "
Florin Coras134a9962018-08-28 11:32:04 -07002072 "data 0x%llx!", getpid (), vep_handle, session_handle,
2073 event->events, event->data.u64);
Florin Coras0d427d82018-06-27 03:24:07 -07002074 vcl_evt (VCL_EVT_EPOLL_CTLADD, session, event->events, event->data.u64);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002075 break;
2076
2077 case EPOLL_CTL_MOD:
2078 if (PREDICT_FALSE (!event))
2079 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002080 clib_warning ("VCL<%d>: ERROR: EPOLL_CTL_MOD: NULL pointer to "
Dave Wallace2e005bb2017-11-07 01:21:39 -05002081 "epoll_event structure!", getpid ());
Dave Wallacef7f809c2017-10-03 01:48:42 -04002082 rv = VPPCOM_EINVAL;
2083 goto done;
2084 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05002085 else if (PREDICT_FALSE (!session->is_vep_session))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002086 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002087 clib_warning ("VCL<%d>: ERROR: sid %u EPOLL_CTL_MOD: "
Florin Coras134a9962018-08-28 11:32:04 -07002088 "not a vep session!", getpid (), session_handle);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002089 rv = VPPCOM_EINVAL;
2090 goto done;
2091 }
Florin Coras134a9962018-08-28 11:32:04 -07002092 else if (PREDICT_FALSE (session->vep.vep_sh != vep_handle))
Dave Wallace4878cbe2017-11-21 03:45:09 -05002093 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002094 clib_warning ("VCL<%d>: ERROR: sid %u EPOLL_CTL_MOD: "
Dave Wallace4878cbe2017-11-21 03:45:09 -05002095 "vep_idx (%u) != vep_idx (%u)!",
Florin Coras134a9962018-08-28 11:32:04 -07002096 getpid (), session_handle,
2097 session->vep.vep_sh, vep_handle);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002098 rv = VPPCOM_EINVAL;
2099 goto done;
2100 }
2101 session->vep.et_mask = VEP_DEFAULT_ET_MASK;
2102 session->vep.ev = *event;
Florin Coras0d427d82018-06-27 03:24:07 -07002103 VDBG (1, "VCL<%d>: EPOLL_CTL_MOD: vep_idx %u, sid %u, events 0x%x,"
Florin Coras134a9962018-08-28 11:32:04 -07002104 " data 0x%llx!", getpid (), vep_handle, session_handle,
2105 event->events, event->data.u64);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002106 break;
2107
2108 case EPOLL_CTL_DEL:
Dave Wallace4878cbe2017-11-21 03:45:09 -05002109 if (PREDICT_FALSE (!session->is_vep_session))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002110 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002111 clib_warning ("VCL<%d>: ERROR: sid %u EPOLL_CTL_DEL: "
Florin Coras134a9962018-08-28 11:32:04 -07002112 "not a vep session!", getpid (), session_handle);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002113 rv = VPPCOM_EINVAL;
2114 goto done;
2115 }
Florin Coras134a9962018-08-28 11:32:04 -07002116 else if (PREDICT_FALSE (session->vep.vep_sh != vep_handle))
Dave Wallace4878cbe2017-11-21 03:45:09 -05002117 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002118 clib_warning ("VCL<%d>: ERROR: sid %u EPOLL_CTL_DEL: "
Dave Wallace4878cbe2017-11-21 03:45:09 -05002119 "vep_idx (%u) != vep_idx (%u)!",
Florin Coras134a9962018-08-28 11:32:04 -07002120 getpid (), session_handle,
2121 session->vep.vep_sh, vep_handle);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002122 rv = VPPCOM_EINVAL;
2123 goto done;
2124 }
2125
2126 vep_session->wait_cont_idx =
Florin Coras134a9962018-08-28 11:32:04 -07002127 (vep_session->wait_cont_idx == session_handle) ?
2128 session->vep.next_sh : vep_session->wait_cont_idx;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002129
Florin Coras134a9962018-08-28 11:32:04 -07002130 if (session->vep.prev_sh == vep_handle)
2131 vep_session->vep.next_sh = session->vep.next_sh;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002132 else
2133 {
Florin Coras7e12d942018-06-27 14:32:43 -07002134 vcl_session_t *prev_session;
Florin Corasab2f6db2018-08-31 14:31:41 -07002135 prev_session = vcl_session_get_w_handle (wrk, session->vep.prev_sh);
Florin Coras070453d2018-08-24 17:04:27 -07002136 if (PREDICT_FALSE (!prev_session))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002137 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002138 clib_warning ("VCL<%d>: ERROR: EPOLL_CTL_DEL: Invalid "
Dave Wallace4878cbe2017-11-21 03:45:09 -05002139 "vep.prev_sid (%u) on sid (%u)!",
Florin Coras134a9962018-08-28 11:32:04 -07002140 getpid (), session->vep.prev_sh, session_handle);
Florin Coras070453d2018-08-24 17:04:27 -07002141 return VPPCOM_EBADFD;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002142 }
Florin Coras134a9962018-08-28 11:32:04 -07002143 ASSERT (prev_session->vep.next_sh == session_handle);
2144 prev_session->vep.next_sh = session->vep.next_sh;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002145 }
Florin Coras134a9962018-08-28 11:32:04 -07002146 if (session->vep.next_sh != ~0)
Dave Wallacef7f809c2017-10-03 01:48:42 -04002147 {
Florin Coras7e12d942018-06-27 14:32:43 -07002148 vcl_session_t *next_session;
Florin Corasab2f6db2018-08-31 14:31:41 -07002149 next_session = vcl_session_get_w_handle (wrk, session->vep.next_sh);
Florin Coras070453d2018-08-24 17:04:27 -07002150 if (PREDICT_FALSE (!next_session))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002151 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002152 clib_warning ("VCL<%d>: ERROR: EPOLL_CTL_DEL: Invalid "
Dave Wallace4878cbe2017-11-21 03:45:09 -05002153 "vep.next_sid (%u) on sid (%u)!",
Florin Coras134a9962018-08-28 11:32:04 -07002154 getpid (), session->vep.next_sh, session_handle);
Florin Coras070453d2018-08-24 17:04:27 -07002155 return VPPCOM_EBADFD;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002156 }
Florin Coras134a9962018-08-28 11:32:04 -07002157 ASSERT (next_session->vep.prev_sh == session_handle);
2158 next_session->vep.prev_sh = session->vep.prev_sh;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002159 }
2160
2161 memset (&session->vep, 0, sizeof (session->vep));
Florin Coras134a9962018-08-28 11:32:04 -07002162 session->vep.next_sh = ~0;
2163 session->vep.prev_sh = ~0;
2164 session->vep.vep_sh = ~0;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002165 session->is_vep_session = 0;
Florin Coras0d427d82018-06-27 03:24:07 -07002166 VDBG (1, "VCL<%d>: EPOLL_CTL_DEL: vep_idx %u, sid %u!",
Florin Coras134a9962018-08-28 11:32:04 -07002167 getpid (), vep_handle, session_handle);
2168 vcl_evt (VCL_EVT_EPOLL_CTLDEL, session, vep_sh);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002169 break;
2170
2171 default:
Dave Wallace048b1d62018-01-03 22:24:41 -05002172 clib_warning ("VCL<%d>: ERROR: Invalid operation (%d)!", getpid (), op);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002173 rv = VPPCOM_EINVAL;
2174 }
2175
Florin Coras134a9962018-08-28 11:32:04 -07002176 vep_verify_epoll_chain (wrk, vep_handle);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002177
2178done:
Dave Wallacef7f809c2017-10-03 01:48:42 -04002179 return rv;
2180}
2181
Florin Coras54693d22018-07-17 10:46:29 -07002182static int
Florin Coras134a9962018-08-28 11:32:04 -07002183vcl_epoll_wait_handle_mq (vcl_worker_t * wrk, svm_msg_q_t * mq,
2184 struct epoll_event *events, u32 maxevents,
2185 double wait_for_time, u32 * num_ev)
Florin Coras54693d22018-07-17 10:46:29 -07002186{
2187 session_disconnected_msg_t *disconnected_msg;
2188 session_connected_msg_t *connected_msg;
2189 session_accepted_msg_t *accepted_msg;
Florin Coras54693d22018-07-17 10:46:29 -07002190 u64 session_evt_data = ~0, handle;
Florin Coras99368312018-08-02 10:45:44 -07002191 u32 sid = ~0, session_events;
Florin Coras54693d22018-07-17 10:46:29 -07002192 vcl_session_msg_t *vcl_msg;
2193 vcl_session_t *session;
Florin Coras99368312018-08-02 10:45:44 -07002194 svm_msg_q_msg_t *msg;
Florin Coras54693d22018-07-17 10:46:29 -07002195 session_event_t *e;
2196 u8 add_event;
2197 int i;
2198
2199 svm_msg_q_lock (mq);
2200 if (svm_msg_q_is_empty (mq))
2201 {
2202 if (!wait_for_time)
2203 {
2204 svm_msg_q_unlock (mq);
2205 return 0;
2206 }
2207 else if (wait_for_time < 0)
2208 {
2209 svm_msg_q_wait (mq);
2210 }
2211 else
2212 {
Florin Coras60f1fc12018-08-16 14:57:31 -07002213 if (svm_msg_q_timedwait (mq, wait_for_time / 1e3))
Florin Coras54693d22018-07-17 10:46:29 -07002214 {
2215 svm_msg_q_unlock (mq);
2216 return 0;
2217 }
2218 }
2219 }
Florin Coras134a9962018-08-28 11:32:04 -07002220 vcl_mq_dequeue_batch (wrk, mq);
Florin Coras54693d22018-07-17 10:46:29 -07002221 svm_msg_q_unlock (mq);
2222
Florin Coras134a9962018-08-28 11:32:04 -07002223 for (i = 0; i < vec_len (wrk->mq_msg_vector); i++)
Florin Coras54693d22018-07-17 10:46:29 -07002224 {
Florin Coras134a9962018-08-28 11:32:04 -07002225 msg = vec_elt_at_index (wrk->mq_msg_vector, i);
Florin Coras99368312018-08-02 10:45:44 -07002226 e = svm_msg_q_msg_data (mq, msg);
Florin Coras54693d22018-07-17 10:46:29 -07002227 add_event = 0;
2228 switch (e->event_type)
2229 {
2230 case FIFO_EVENT_APP_RX:
2231 sid = e->fifo->client_session_index;
Florin Coras134a9962018-08-28 11:32:04 -07002232 session = vcl_session_get (wrk, sid);
Florin Coras54693d22018-07-17 10:46:29 -07002233 session_events = session->vep.ev.events;
Florin Coras99368312018-08-02 10:45:44 -07002234 if (!(EPOLLIN & session->vep.ev.events))
2235 break;
Florin Coras60f1fc12018-08-16 14:57:31 -07002236 add_event = 1;
2237 events[*num_ev].events |= EPOLLIN;
2238 session_evt_data = session->vep.ev.data.u64;
Florin Coras54693d22018-07-17 10:46:29 -07002239 break;
2240 case FIFO_EVENT_APP_TX:
2241 sid = e->fifo->client_session_index;
Florin Coras134a9962018-08-28 11:32:04 -07002242 session = vcl_session_get (wrk, sid);
Florin Coras54693d22018-07-17 10:46:29 -07002243 session_events = session->vep.ev.events;
Florin Coras99368312018-08-02 10:45:44 -07002244 if (!(EPOLLOUT & session_events))
2245 break;
Florin Coras60f1fc12018-08-16 14:57:31 -07002246 add_event = 1;
2247 events[*num_ev].events |= EPOLLOUT;
2248 session_evt_data = session->vep.ev.data.u64;
Florin Coras54693d22018-07-17 10:46:29 -07002249 break;
2250 case SESSION_IO_EVT_CT_TX:
Florin Coras134a9962018-08-28 11:32:04 -07002251 session = vcl_ct_session_get_from_fifo (wrk, e->fifo, 0);
2252 sid = session->session_index;
Florin Coras54693d22018-07-17 10:46:29 -07002253 session_events = session->vep.ev.events;
Florin Coras99368312018-08-02 10:45:44 -07002254 if (!(EPOLLIN & session->vep.ev.events))
2255 break;
Florin Coras60f1fc12018-08-16 14:57:31 -07002256 add_event = 1;
2257 events[*num_ev].events |= EPOLLIN;
2258 session_evt_data = session->vep.ev.data.u64;
Florin Coras54693d22018-07-17 10:46:29 -07002259 break;
2260 case SESSION_IO_EVT_CT_RX:
Florin Coras134a9962018-08-28 11:32:04 -07002261 session = vcl_ct_session_get_from_fifo (wrk, e->fifo, 1);
2262 sid = session->session_index;
Florin Coras54693d22018-07-17 10:46:29 -07002263 session_events = session->vep.ev.events;
Florin Coras99368312018-08-02 10:45:44 -07002264 if (!(EPOLLOUT & session_events))
2265 break;
Florin Coras60f1fc12018-08-16 14:57:31 -07002266 add_event = 1;
2267 events[*num_ev].events |= EPOLLOUT;
2268 session_evt_data = session->vep.ev.data.u64;
Florin Coras54693d22018-07-17 10:46:29 -07002269 break;
2270 case SESSION_CTRL_EVT_ACCEPTED:
2271 accepted_msg = (session_accepted_msg_t *) e->data;
2272 handle = accepted_msg->listener_handle;
Florin Coras134a9962018-08-28 11:32:04 -07002273 session = vcl_session_table_lookup_listener (wrk, handle);
Florin Coras54693d22018-07-17 10:46:29 -07002274 if (!session)
2275 {
2276 clib_warning ("VCL<%d>: ERROR: couldn't find listen session:"
2277 "listener handle %llx", getpid (), handle);
2278 break;
2279 }
2280
2281 clib_fifo_add2 (session->accept_evts_fifo, vcl_msg);
2282 vcl_msg->accepted_msg = *accepted_msg;
2283 session_events = session->vep.ev.events;
2284 if (!(EPOLLIN & session_events))
2285 break;
2286
2287 add_event = 1;
2288 events[*num_ev].events |= EPOLLIN;
2289 session_evt_data = session->vep.ev.data.u64;
2290 break;
2291 case SESSION_CTRL_EVT_CONNECTED:
2292 connected_msg = (session_connected_msg_t *) e->data;
Florin Coras134a9962018-08-28 11:32:04 -07002293 vcl_session_connected_handler (wrk, connected_msg);
Florin Coras54693d22018-07-17 10:46:29 -07002294 /* Generate EPOLLOUT because there's no connected event */
Florin Coras134a9962018-08-28 11:32:04 -07002295 sid = vcl_session_index_from_vpp_handle (wrk,
2296 connected_msg->handle);
2297 session = vcl_session_get (wrk, sid);
Florin Coras54693d22018-07-17 10:46:29 -07002298 session_events = session->vep.ev.events;
2299 if (EPOLLOUT & session_events)
2300 {
2301 add_event = 1;
2302 events[*num_ev].events |= EPOLLOUT;
2303 session_evt_data = session->vep.ev.data.u64;
2304 }
Florin Coras54693d22018-07-17 10:46:29 -07002305 break;
2306 case SESSION_CTRL_EVT_DISCONNECTED:
2307 disconnected_msg = (session_disconnected_msg_t *) e->data;
Florin Coras134a9962018-08-28 11:32:04 -07002308 sid = vcl_session_index_from_vpp_handle (wrk,
2309 disconnected_msg->handle);
2310 if (!(session = vcl_session_get (wrk, sid)))
Florin Corasc9fbd662018-08-24 12:59:56 -07002311 break;
Florin Coras54693d22018-07-17 10:46:29 -07002312 add_event = 1;
2313 events[*num_ev].events |= EPOLLHUP | EPOLLRDHUP;
2314 session_evt_data = session->vep.ev.data.u64;
2315 session_events = session->vep.ev.events;
Florin Coras54693d22018-07-17 10:46:29 -07002316 break;
Florin Corasc9fbd662018-08-24 12:59:56 -07002317 case SESSION_CTRL_EVT_RESET:
Florin Coras134a9962018-08-28 11:32:04 -07002318 sid = vcl_session_reset_handler (wrk,
2319 (session_reset_msg_t *) e->data);
2320 if (!(session = vcl_session_get (wrk, sid)))
Florin Corasc9fbd662018-08-24 12:59:56 -07002321 break;
2322 add_event = 1;
2323 events[*num_ev].events |= EPOLLHUP | EPOLLRDHUP;
2324 session_evt_data = session->vep.ev.data.u64;
2325 session_events = session->vep.ev.events;
2326 break;
Florin Coras54693d22018-07-17 10:46:29 -07002327 default:
Florin Corasab2f6db2018-08-31 14:31:41 -07002328 VDBG (0, "unhandled: %u", e->event_type);
Florin Coras99368312018-08-02 10:45:44 -07002329 svm_msg_q_free_msg (mq, msg);
Florin Coras54693d22018-07-17 10:46:29 -07002330 continue;
2331 }
Florin Coras99368312018-08-02 10:45:44 -07002332 svm_msg_q_free_msg (mq, msg);
Florin Coras54693d22018-07-17 10:46:29 -07002333
2334 if (add_event)
2335 {
2336 events[*num_ev].data.u64 = session_evt_data;
2337 if (EPOLLONESHOT & session_events)
2338 {
Florin Coras134a9962018-08-28 11:32:04 -07002339 session = vcl_session_get (wrk, sid);
Florin Coras54693d22018-07-17 10:46:29 -07002340 session->vep.ev.events = 0;
Florin Coras54693d22018-07-17 10:46:29 -07002341 }
2342 *num_ev += 1;
2343 if (*num_ev == maxevents)
2344 break;
2345 }
2346 }
Florin Coras99368312018-08-02 10:45:44 -07002347
Florin Coras134a9962018-08-28 11:32:04 -07002348 vec_reset_length (wrk->mq_msg_vector);
Florin Coras54693d22018-07-17 10:46:29 -07002349 return *num_ev;
2350}
2351
Florin Coras99368312018-08-02 10:45:44 -07002352static int
Florin Coras134a9962018-08-28 11:32:04 -07002353vppcom_epoll_wait_condvar (vcl_worker_t * wrk, struct epoll_event *events,
2354 int maxevents, double wait_for_time)
Florin Coras99368312018-08-02 10:45:44 -07002355{
2356 vcl_cut_through_registration_t *cr;
2357 double total_wait = 0, wait_slice;
2358 u32 num_ev = 0;
2359 int rv;
2360
2361 wait_for_time = (wait_for_time == -1) ? (double) 10e9 : wait_for_time;
Florin Coras134a9962018-08-28 11:32:04 -07002362 wait_slice = wrk->cut_through_registrations ? 10e-6 : wait_for_time;
Florin Coras99368312018-08-02 10:45:44 -07002363
2364 do
2365 {
Florin Coras134a9962018-08-28 11:32:04 -07002366 vcl_ct_registration_lock (wrk);
Florin Coras99368312018-08-02 10:45:44 -07002367 /* *INDENT-OFF* */
Florin Coras134a9962018-08-28 11:32:04 -07002368 pool_foreach (cr, wrk->cut_through_registrations, ({
2369 vcl_epoll_wait_handle_mq (wrk, cr->mq, events, maxevents, 0, &num_ev);
Florin Coras99368312018-08-02 10:45:44 -07002370 }));
2371 /* *INDENT-ON* */
Florin Coras134a9962018-08-28 11:32:04 -07002372 vcl_ct_registration_unlock (wrk);
Florin Coras99368312018-08-02 10:45:44 -07002373
Florin Coras134a9962018-08-28 11:32:04 -07002374 rv = vcl_epoll_wait_handle_mq (wrk, wrk->app_event_queue, events,
2375 maxevents, num_ev ? 0 : wait_slice,
2376 &num_ev);
Florin Coras99368312018-08-02 10:45:44 -07002377 if (rv)
2378 total_wait += wait_slice;
2379 if (num_ev)
2380 return num_ev;
2381 }
2382 while (total_wait < wait_for_time);
2383 return (int) num_ev;
2384}
2385
2386static int
Florin Coras134a9962018-08-28 11:32:04 -07002387vppcom_epoll_wait_eventfd (vcl_worker_t * wrk, struct epoll_event *events,
2388 int maxevents, double wait_for_time)
Florin Coras99368312018-08-02 10:45:44 -07002389{
2390 vcl_mq_evt_conn_t *mqc;
2391 int __clib_unused n_read;
2392 int n_mq_evts, i;
2393 u32 n_evts = 0;
2394 u64 buf;
2395
Florin Coras134a9962018-08-28 11:32:04 -07002396 vec_validate (wrk->mq_events, pool_elts (wrk->mq_evt_conns));
2397 n_mq_evts = epoll_wait (wrk->mqs_epfd, wrk->mq_events,
2398 vec_len (wrk->mq_events), wait_for_time);
Florin Coras99368312018-08-02 10:45:44 -07002399 for (i = 0; i < n_mq_evts; i++)
2400 {
Florin Coras134a9962018-08-28 11:32:04 -07002401 mqc = vcl_mq_evt_conn_get (wrk, wrk->mq_events[i].data.u32);
Florin Coras99368312018-08-02 10:45:44 -07002402 n_read = read (mqc->mq_fd, &buf, sizeof (buf));
Florin Coras134a9962018-08-28 11:32:04 -07002403 vcl_epoll_wait_handle_mq (wrk, mqc->mq, events, maxevents, 0, &n_evts);
Florin Coras99368312018-08-02 10:45:44 -07002404 }
2405
2406 return (int) n_evts;
2407}
2408
Dave Wallacef7f809c2017-10-03 01:48:42 -04002409int
Florin Coras134a9962018-08-28 11:32:04 -07002410vppcom_epoll_wait (uint32_t vep_handle, struct epoll_event *events,
Dave Wallacef7f809c2017-10-03 01:48:42 -04002411 int maxevents, double wait_for_time)
2412{
Florin Coras134a9962018-08-28 11:32:04 -07002413 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras7e12d942018-06-27 14:32:43 -07002414 vcl_session_t *vep_session;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002415
2416 if (PREDICT_FALSE (maxevents <= 0))
2417 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002418 clib_warning ("VCL<%d>: ERROR: Invalid maxevents (%d)!",
Dave Wallace4878cbe2017-11-21 03:45:09 -05002419 getpid (), maxevents);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002420 return VPPCOM_EINVAL;
2421 }
Dave Wallacef7f809c2017-10-03 01:48:42 -04002422
Florin Coras134a9962018-08-28 11:32:04 -07002423 vep_session = vcl_session_get_w_handle (wrk, vep_handle);
Florin Coras14598772018-09-04 19:47:52 -07002424 if (!vep_session)
2425 return VPPCOM_EBADFD;
2426
Florin Coras54693d22018-07-17 10:46:29 -07002427 if (PREDICT_FALSE (!vep_session->is_vep))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002428 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002429 clib_warning ("VCL<%d>: ERROR: vep_idx (%u) is not a vep!",
Florin Coras134a9962018-08-28 11:32:04 -07002430 getpid (), vep_handle);
Florin Coras54693d22018-07-17 10:46:29 -07002431 return VPPCOM_EINVAL;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002432 }
Florin Coras54693d22018-07-17 10:46:29 -07002433
2434 memset (events, 0, sizeof (*events) * maxevents);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002435
Florin Coras99368312018-08-02 10:45:44 -07002436 if (vcm->cfg.use_mq_eventfd)
Florin Coras134a9962018-08-28 11:32:04 -07002437 return vppcom_epoll_wait_eventfd (wrk, events, maxevents, wait_for_time);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002438
Florin Coras134a9962018-08-28 11:32:04 -07002439 return vppcom_epoll_wait_condvar (wrk, events, maxevents, wait_for_time);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002440}
2441
Dave Wallace35830af2017-10-09 01:43:42 -04002442int
Florin Coras134a9962018-08-28 11:32:04 -07002443vppcom_session_attr (uint32_t session_handle, uint32_t op,
Dave Wallace35830af2017-10-09 01:43:42 -04002444 void *buffer, uint32_t * buflen)
2445{
Florin Coras134a9962018-08-28 11:32:04 -07002446 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras7e12d942018-06-27 14:32:43 -07002447 vcl_session_t *session;
Dave Wallace35830af2017-10-09 01:43:42 -04002448 int rv = VPPCOM_OK;
2449 u32 *flags = buffer;
Steven2199aab2017-10-15 20:18:47 -07002450 vppcom_endpt_t *ep = buffer;
Dave Wallace35830af2017-10-09 01:43:42 -04002451
Florin Coras134a9962018-08-28 11:32:04 -07002452 session = vcl_session_get_w_handle (wrk, session_handle);
Florin Coras070453d2018-08-24 17:04:27 -07002453 if (!session)
2454 return VPPCOM_EBADFD;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002455
Dave Wallace35830af2017-10-09 01:43:42 -04002456 switch (op)
2457 {
2458 case VPPCOM_ATTR_GET_NREAD:
Florin Coras54693d22018-07-17 10:46:29 -07002459 rv = vppcom_session_read_ready (session);
Florin Coras0d427d82018-06-27 03:24:07 -07002460 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_NREAD: sid %u, nread = %d",
2461 getpid (), rv);
Dave Wallace35830af2017-10-09 01:43:42 -04002462 break;
2463
Dave Wallace227867f2017-11-13 21:21:53 -05002464 case VPPCOM_ATTR_GET_NWRITE:
Florin Coras134a9962018-08-28 11:32:04 -07002465 rv = vppcom_session_write_ready (session);
Florin Coras0d427d82018-06-27 03:24:07 -07002466 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_NWRITE: sid %u, nwrite = %d",
Florin Coras134a9962018-08-28 11:32:04 -07002467 getpid (), session_handle, rv);
Dave Wallace35830af2017-10-09 01:43:42 -04002468 break;
2469
2470 case VPPCOM_ATTR_GET_FLAGS:
Dave Wallace048b1d62018-01-03 22:24:41 -05002471 if (PREDICT_TRUE (buffer && buflen && (*buflen >= sizeof (*flags))))
Dave Wallace35830af2017-10-09 01:43:42 -04002472 {
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002473 *flags = O_RDWR | (VCL_SESS_ATTR_TEST (session->attr,
2474 VCL_SESS_ATTR_NONBLOCK));
Dave Wallace35830af2017-10-09 01:43:42 -04002475 *buflen = sizeof (*flags);
Florin Coras0d427d82018-06-27 03:24:07 -07002476 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_FLAGS: sid %u, flags = 0x%08x, "
2477 "is_nonblocking = %u", getpid (),
Florin Coras134a9962018-08-28 11:32:04 -07002478 session_handle, *flags,
Florin Coras0d427d82018-06-27 03:24:07 -07002479 VCL_SESS_ATTR_TEST (session->attr, VCL_SESS_ATTR_NONBLOCK));
Dave Wallace35830af2017-10-09 01:43:42 -04002480 }
2481 else
2482 rv = VPPCOM_EINVAL;
2483 break;
2484
2485 case VPPCOM_ATTR_SET_FLAGS:
Dave Wallace048b1d62018-01-03 22:24:41 -05002486 if (PREDICT_TRUE (buffer && buflen && (*buflen == sizeof (*flags))))
Dave Wallace35830af2017-10-09 01:43:42 -04002487 {
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002488 if (*flags & O_NONBLOCK)
2489 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_NONBLOCK);
2490 else
2491 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_NONBLOCK);
2492
Florin Coras0d427d82018-06-27 03:24:07 -07002493 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_FLAGS: sid %u, flags = 0x%08x,"
2494 " is_nonblocking = %u",
Florin Coras134a9962018-08-28 11:32:04 -07002495 getpid (), session_handle, *flags,
Florin Coras0d427d82018-06-27 03:24:07 -07002496 VCL_SESS_ATTR_TEST (session->attr, VCL_SESS_ATTR_NONBLOCK));
Dave Wallace35830af2017-10-09 01:43:42 -04002497 }
2498 else
2499 rv = VPPCOM_EINVAL;
2500 break;
2501
2502 case VPPCOM_ATTR_GET_PEER_ADDR:
Dave Wallace048b1d62018-01-03 22:24:41 -05002503 if (PREDICT_TRUE (buffer && buflen &&
2504 (*buflen >= sizeof (*ep)) && ep->ip))
Dave Wallace35830af2017-10-09 01:43:42 -04002505 {
Florin Coras7e12d942018-06-27 14:32:43 -07002506 ep->is_ip4 = session->transport.is_ip4;
2507 ep->port = session->transport.rmt_port;
2508 if (session->transport.is_ip4)
2509 clib_memcpy (ep->ip, &session->transport.rmt_ip.ip4,
Steven2199aab2017-10-15 20:18:47 -07002510 sizeof (ip4_address_t));
2511 else
Florin Coras7e12d942018-06-27 14:32:43 -07002512 clib_memcpy (ep->ip, &session->transport.rmt_ip.ip6,
Steven2199aab2017-10-15 20:18:47 -07002513 sizeof (ip6_address_t));
2514 *buflen = sizeof (*ep);
Florin Coras0d427d82018-06-27 03:24:07 -07002515 VDBG (1, "VCL<%d>: VPPCOM_ATTR_GET_PEER_ADDR: sid %u, is_ip4 = %u, "
2516 "addr = %U, port %u", getpid (),
Florin Coras134a9962018-08-28 11:32:04 -07002517 session_handle, ep->is_ip4, format_ip46_address,
Florin Coras7e12d942018-06-27 14:32:43 -07002518 &session->transport.rmt_ip,
Florin Coras0d427d82018-06-27 03:24:07 -07002519 ep->is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6,
2520 clib_net_to_host_u16 (ep->port));
Dave Wallace35830af2017-10-09 01:43:42 -04002521 }
2522 else
2523 rv = VPPCOM_EINVAL;
2524 break;
2525
2526 case VPPCOM_ATTR_GET_LCL_ADDR:
Dave Wallace048b1d62018-01-03 22:24:41 -05002527 if (PREDICT_TRUE (buffer && buflen &&
2528 (*buflen >= sizeof (*ep)) && ep->ip))
Dave Wallace35830af2017-10-09 01:43:42 -04002529 {
Florin Coras7e12d942018-06-27 14:32:43 -07002530 ep->is_ip4 = session->transport.is_ip4;
2531 ep->port = session->transport.lcl_port;
2532 if (session->transport.is_ip4)
2533 clib_memcpy (ep->ip, &session->transport.lcl_ip.ip4,
Steven2199aab2017-10-15 20:18:47 -07002534 sizeof (ip4_address_t));
2535 else
Florin Coras7e12d942018-06-27 14:32:43 -07002536 clib_memcpy (ep->ip, &session->transport.lcl_ip.ip6,
Steven2199aab2017-10-15 20:18:47 -07002537 sizeof (ip6_address_t));
2538 *buflen = sizeof (*ep);
Florin Coras0d427d82018-06-27 03:24:07 -07002539 VDBG (1, "VCL<%d>: VPPCOM_ATTR_GET_LCL_ADDR: sid %u, is_ip4 = %u,"
2540 " addr = %U port %d", getpid (),
Florin Coras134a9962018-08-28 11:32:04 -07002541 session_handle, ep->is_ip4, format_ip46_address,
Florin Coras7e12d942018-06-27 14:32:43 -07002542 &session->transport.lcl_ip,
Florin Coras0d427d82018-06-27 03:24:07 -07002543 ep->is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6,
2544 clib_net_to_host_u16 (ep->port));
Dave Wallace35830af2017-10-09 01:43:42 -04002545 }
2546 else
2547 rv = VPPCOM_EINVAL;
2548 break;
Stevenb5a11602017-10-11 09:59:30 -07002549
Dave Wallace048b1d62018-01-03 22:24:41 -05002550 case VPPCOM_ATTR_GET_LIBC_EPFD:
2551 rv = session->libc_epfd;
Florin Coras0d427d82018-06-27 03:24:07 -07002552 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_LIBC_EPFD: libc_epfd %d",
2553 getpid (), rv);
Dave Wallace048b1d62018-01-03 22:24:41 -05002554 break;
2555
2556 case VPPCOM_ATTR_SET_LIBC_EPFD:
2557 if (PREDICT_TRUE (buffer && buflen &&
2558 (*buflen == sizeof (session->libc_epfd))))
2559 {
2560 session->libc_epfd = *(int *) buffer;
2561 *buflen = sizeof (session->libc_epfd);
2562
Florin Coras0d427d82018-06-27 03:24:07 -07002563 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_LIBC_EPFD: libc_epfd %d, "
2564 "buflen %d", getpid (), session->libc_epfd, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002565 }
2566 else
2567 rv = VPPCOM_EINVAL;
2568 break;
2569
2570 case VPPCOM_ATTR_GET_PROTOCOL:
2571 if (buffer && buflen && (*buflen >= sizeof (int)))
2572 {
Florin Coras7e12d942018-06-27 14:32:43 -07002573 *(int *) buffer = session->session_type;
Dave Wallace048b1d62018-01-03 22:24:41 -05002574 *buflen = sizeof (int);
2575
Florin Coras0d427d82018-06-27 03:24:07 -07002576 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_PROTOCOL: %d (%s), buflen %d",
2577 getpid (), *(int *) buffer, *(int *) buffer ? "UDP" : "TCP",
2578 *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002579 }
2580 else
2581 rv = VPPCOM_EINVAL;
2582 break;
2583
2584 case VPPCOM_ATTR_GET_LISTEN:
2585 if (buffer && buflen && (*buflen >= sizeof (int)))
2586 {
2587 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
2588 VCL_SESS_ATTR_LISTEN);
2589 *buflen = sizeof (int);
2590
Florin Coras0d427d82018-06-27 03:24:07 -07002591 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_LISTEN: %d, buflen %d",
2592 getpid (), *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002593 }
2594 else
2595 rv = VPPCOM_EINVAL;
2596 break;
2597
2598 case VPPCOM_ATTR_GET_ERROR:
2599 if (buffer && buflen && (*buflen >= sizeof (int)))
2600 {
2601 *(int *) buffer = 0;
2602 *buflen = sizeof (int);
2603
Florin Coras0d427d82018-06-27 03:24:07 -07002604 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_ERROR: %d, buflen %d, #VPP-TBD#",
2605 getpid (), *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002606 }
2607 else
2608 rv = VPPCOM_EINVAL;
2609 break;
2610
2611 case VPPCOM_ATTR_GET_TX_FIFO_LEN:
2612 if (buffer && buflen && (*buflen >= sizeof (u32)))
2613 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002614
2615 /* VPP-TBD */
2616 *(size_t *) buffer = (session->sndbuf_size ? session->sndbuf_size :
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002617 session->tx_fifo ? session->tx_fifo->nitems :
Dave Wallace048b1d62018-01-03 22:24:41 -05002618 vcm->cfg.tx_fifo_size);
2619 *buflen = sizeof (u32);
2620
Florin Coras0d427d82018-06-27 03:24:07 -07002621 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_TX_FIFO_LEN: %u (0x%x), "
2622 "buflen %d, #VPP-TBD#", getpid (),
2623 *(size_t *) buffer, *(size_t *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002624 }
2625 else
2626 rv = VPPCOM_EINVAL;
2627 break;
2628
2629 case VPPCOM_ATTR_SET_TX_FIFO_LEN:
2630 if (buffer && buflen && (*buflen == sizeof (u32)))
2631 {
2632 /* VPP-TBD */
2633 session->sndbuf_size = *(u32 *) buffer;
Florin Coras0d427d82018-06-27 03:24:07 -07002634 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_TX_FIFO_LEN: %u (0x%x), "
2635 "buflen %d, #VPP-TBD#", getpid (),
2636 session->sndbuf_size, session->sndbuf_size, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002637 }
2638 else
2639 rv = VPPCOM_EINVAL;
2640 break;
2641
2642 case VPPCOM_ATTR_GET_RX_FIFO_LEN:
2643 if (buffer && buflen && (*buflen >= sizeof (u32)))
2644 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002645
2646 /* VPP-TBD */
2647 *(size_t *) buffer = (session->rcvbuf_size ? session->rcvbuf_size :
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002648 session->rx_fifo ? session->rx_fifo->nitems :
Dave Wallace048b1d62018-01-03 22:24:41 -05002649 vcm->cfg.rx_fifo_size);
2650 *buflen = sizeof (u32);
2651
Florin Coras0d427d82018-06-27 03:24:07 -07002652 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_RX_FIFO_LEN: %u (0x%x), "
2653 "buflen %d, #VPP-TBD#", getpid (),
2654 *(size_t *) buffer, *(size_t *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002655 }
2656 else
2657 rv = VPPCOM_EINVAL;
2658 break;
2659
2660 case VPPCOM_ATTR_SET_RX_FIFO_LEN:
2661 if (buffer && buflen && (*buflen == sizeof (u32)))
2662 {
2663 /* VPP-TBD */
2664 session->rcvbuf_size = *(u32 *) buffer;
Florin Coras0d427d82018-06-27 03:24:07 -07002665 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_RX_FIFO_LEN: %u (0x%x), "
2666 "buflen %d, #VPP-TBD#", getpid (),
2667 session->sndbuf_size, session->sndbuf_size, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002668 }
2669 else
2670 rv = VPPCOM_EINVAL;
2671 break;
2672
2673 case VPPCOM_ATTR_GET_REUSEADDR:
2674 if (buffer && buflen && (*buflen >= sizeof (int)))
2675 {
2676 /* VPP-TBD */
2677 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
2678 VCL_SESS_ATTR_REUSEADDR);
2679 *buflen = sizeof (int);
2680
Florin Coras0d427d82018-06-27 03:24:07 -07002681 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_REUSEADDR: %d, "
2682 "buflen %d, #VPP-TBD#", getpid (), *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002683 }
2684 else
2685 rv = VPPCOM_EINVAL;
2686 break;
2687
Stevenb5a11602017-10-11 09:59:30 -07002688 case VPPCOM_ATTR_SET_REUSEADDR:
Dave Wallace048b1d62018-01-03 22:24:41 -05002689 if (buffer && buflen && (*buflen == sizeof (int)) &&
2690 !VCL_SESS_ATTR_TEST (session->attr, VCL_SESS_ATTR_LISTEN))
2691 {
2692 /* VPP-TBD */
2693 if (*(int *) buffer)
2694 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_REUSEADDR);
2695 else
2696 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_REUSEADDR);
2697
Florin Coras0d427d82018-06-27 03:24:07 -07002698 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_REUSEADDR: %d, buflen %d,"
2699 " #VPP-TBD#", getpid (),
2700 VCL_SESS_ATTR_TEST (session->attr,
2701 VCL_SESS_ATTR_REUSEADDR), *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002702 }
2703 else
2704 rv = VPPCOM_EINVAL;
2705 break;
2706
2707 case VPPCOM_ATTR_GET_REUSEPORT:
2708 if (buffer && buflen && (*buflen >= sizeof (int)))
2709 {
2710 /* VPP-TBD */
2711 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
2712 VCL_SESS_ATTR_REUSEPORT);
2713 *buflen = sizeof (int);
2714
Florin Coras0d427d82018-06-27 03:24:07 -07002715 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_REUSEPORT: %d, buflen %d,"
2716 " #VPP-TBD#", getpid (), *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002717 }
2718 else
2719 rv = VPPCOM_EINVAL;
2720 break;
2721
2722 case VPPCOM_ATTR_SET_REUSEPORT:
2723 if (buffer && buflen && (*buflen == sizeof (int)) &&
2724 !VCL_SESS_ATTR_TEST (session->attr, VCL_SESS_ATTR_LISTEN))
2725 {
2726 /* VPP-TBD */
2727 if (*(int *) buffer)
2728 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_REUSEPORT);
2729 else
2730 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_REUSEPORT);
2731
Florin Coras0d427d82018-06-27 03:24:07 -07002732 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_REUSEPORT: %d, buflen %d,"
2733 " #VPP-TBD#", getpid (),
2734 VCL_SESS_ATTR_TEST (session->attr,
2735 VCL_SESS_ATTR_REUSEPORT), *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002736 }
2737 else
2738 rv = VPPCOM_EINVAL;
2739 break;
2740
2741 case VPPCOM_ATTR_GET_BROADCAST:
2742 if (buffer && buflen && (*buflen >= sizeof (int)))
2743 {
2744 /* VPP-TBD */
2745 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
2746 VCL_SESS_ATTR_BROADCAST);
2747 *buflen = sizeof (int);
2748
Florin Coras0d427d82018-06-27 03:24:07 -07002749 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_BROADCAST: %d, buflen %d,"
2750 " #VPP-TBD#", getpid (), *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002751 }
2752 else
2753 rv = VPPCOM_EINVAL;
Stevenb5a11602017-10-11 09:59:30 -07002754 break;
2755
2756 case VPPCOM_ATTR_SET_BROADCAST:
Dave Wallace048b1d62018-01-03 22:24:41 -05002757 if (buffer && buflen && (*buflen == sizeof (int)))
2758 {
2759 /* VPP-TBD */
2760 if (*(int *) buffer)
2761 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_BROADCAST);
2762 else
2763 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_BROADCAST);
2764
Florin Coras0d427d82018-06-27 03:24:07 -07002765 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_BROADCAST: %d, buflen %d, "
2766 "#VPP-TBD#", getpid (),
2767 VCL_SESS_ATTR_TEST (session->attr,
2768 VCL_SESS_ATTR_BROADCAST), *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002769 }
2770 else
2771 rv = VPPCOM_EINVAL;
2772 break;
2773
2774 case VPPCOM_ATTR_GET_V6ONLY:
2775 if (buffer && buflen && (*buflen >= sizeof (int)))
2776 {
2777 /* VPP-TBD */
2778 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
2779 VCL_SESS_ATTR_V6ONLY);
2780 *buflen = sizeof (int);
2781
Florin Coras0d427d82018-06-27 03:24:07 -07002782 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_V6ONLY: %d, buflen %d, "
2783 "#VPP-TBD#", getpid (), *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002784 }
2785 else
2786 rv = VPPCOM_EINVAL;
Stevenb5a11602017-10-11 09:59:30 -07002787 break;
2788
2789 case VPPCOM_ATTR_SET_V6ONLY:
Dave Wallace048b1d62018-01-03 22:24:41 -05002790 if (buffer && buflen && (*buflen == sizeof (int)))
2791 {
2792 /* VPP-TBD */
2793 if (*(int *) buffer)
2794 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_V6ONLY);
2795 else
2796 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_V6ONLY);
2797
Florin Coras0d427d82018-06-27 03:24:07 -07002798 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_V6ONLY: %d, buflen %d, "
2799 "#VPP-TBD#", getpid (),
2800 VCL_SESS_ATTR_TEST (session->attr,
2801 VCL_SESS_ATTR_V6ONLY), *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002802 }
2803 else
2804 rv = VPPCOM_EINVAL;
2805 break;
2806
2807 case VPPCOM_ATTR_GET_KEEPALIVE:
2808 if (buffer && buflen && (*buflen >= sizeof (int)))
2809 {
2810 /* VPP-TBD */
2811 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
2812 VCL_SESS_ATTR_KEEPALIVE);
2813 *buflen = sizeof (int);
2814
Florin Coras0d427d82018-06-27 03:24:07 -07002815 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_KEEPALIVE: %d, buflen %d, "
2816 "#VPP-TBD#", getpid (), *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002817 }
2818 else
2819 rv = VPPCOM_EINVAL;
Stevenb5a11602017-10-11 09:59:30 -07002820 break;
Stevenbccd3392017-10-12 20:42:21 -07002821
2822 case VPPCOM_ATTR_SET_KEEPALIVE:
Dave Wallace048b1d62018-01-03 22:24:41 -05002823 if (buffer && buflen && (*buflen == sizeof (int)))
2824 {
2825 /* VPP-TBD */
2826 if (*(int *) buffer)
2827 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_KEEPALIVE);
2828 else
2829 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_KEEPALIVE);
2830
Florin Coras0d427d82018-06-27 03:24:07 -07002831 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_KEEPALIVE: %d, buflen %d, "
2832 "#VPP-TBD#", getpid (),
2833 VCL_SESS_ATTR_TEST (session->attr,
2834 VCL_SESS_ATTR_KEEPALIVE), *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002835 }
2836 else
2837 rv = VPPCOM_EINVAL;
2838 break;
2839
2840 case VPPCOM_ATTR_GET_TCP_NODELAY:
2841 if (buffer && buflen && (*buflen >= sizeof (int)))
2842 {
2843 /* VPP-TBD */
2844 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
2845 VCL_SESS_ATTR_TCP_NODELAY);
2846 *buflen = sizeof (int);
2847
Florin Coras0d427d82018-06-27 03:24:07 -07002848 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_TCP_NODELAY: %d, buflen %d, "
2849 "#VPP-TBD#", getpid (), *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002850 }
2851 else
2852 rv = VPPCOM_EINVAL;
2853 break;
2854
2855 case VPPCOM_ATTR_SET_TCP_NODELAY:
2856 if (buffer && buflen && (*buflen == sizeof (int)))
2857 {
2858 /* VPP-TBD */
2859 if (*(int *) buffer)
2860 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_TCP_NODELAY);
2861 else
2862 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_TCP_NODELAY);
2863
Florin Coras0d427d82018-06-27 03:24:07 -07002864 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_TCP_NODELAY: %d, buflen %d, "
2865 "#VPP-TBD#", getpid (),
2866 VCL_SESS_ATTR_TEST (session->attr,
2867 VCL_SESS_ATTR_TCP_NODELAY), *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002868 }
2869 else
2870 rv = VPPCOM_EINVAL;
2871 break;
2872
2873 case VPPCOM_ATTR_GET_TCP_KEEPIDLE:
2874 if (buffer && buflen && (*buflen >= sizeof (int)))
2875 {
2876 /* VPP-TBD */
2877 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
2878 VCL_SESS_ATTR_TCP_KEEPIDLE);
2879 *buflen = sizeof (int);
2880
Florin Coras0d427d82018-06-27 03:24:07 -07002881 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_TCP_KEEPIDLE: %d, buflen %d, "
2882 "#VPP-TBD#", getpid (), *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002883 }
2884 else
2885 rv = VPPCOM_EINVAL;
Stevenbccd3392017-10-12 20:42:21 -07002886 break;
2887
2888 case VPPCOM_ATTR_SET_TCP_KEEPIDLE:
Dave Wallace048b1d62018-01-03 22:24:41 -05002889 if (buffer && buflen && (*buflen == sizeof (int)))
2890 {
2891 /* VPP-TBD */
2892 if (*(int *) buffer)
2893 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_TCP_KEEPIDLE);
2894 else
2895 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_TCP_KEEPIDLE);
2896
Florin Coras0d427d82018-06-27 03:24:07 -07002897 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_TCP_KEEPIDLE: %d, buflen %d, "
2898 "#VPP-TBD#", getpid (),
2899 VCL_SESS_ATTR_TEST (session->attr,
2900 VCL_SESS_ATTR_TCP_KEEPIDLE), *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002901 }
2902 else
2903 rv = VPPCOM_EINVAL;
2904 break;
2905
2906 case VPPCOM_ATTR_GET_TCP_KEEPINTVL:
2907 if (buffer && buflen && (*buflen >= sizeof (int)))
2908 {
2909 /* VPP-TBD */
2910 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
2911 VCL_SESS_ATTR_TCP_KEEPINTVL);
2912 *buflen = sizeof (int);
2913
Florin Coras0d427d82018-06-27 03:24:07 -07002914 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_TCP_KEEPINTVL: %d, buflen %d, "
2915 "#VPP-TBD#", getpid (), *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002916 }
2917 else
2918 rv = VPPCOM_EINVAL;
Stevenbccd3392017-10-12 20:42:21 -07002919 break;
2920
2921 case VPPCOM_ATTR_SET_TCP_KEEPINTVL:
Dave Wallace048b1d62018-01-03 22:24:41 -05002922 if (buffer && buflen && (*buflen == sizeof (int)))
2923 {
2924 /* VPP-TBD */
2925 if (*(int *) buffer)
2926 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_TCP_KEEPINTVL);
2927 else
2928 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_TCP_KEEPINTVL);
2929
Florin Coras0d427d82018-06-27 03:24:07 -07002930 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_TCP_KEEPINTVL: %d, buflen %d, "
2931 "#VPP-TBD#", getpid (),
2932 VCL_SESS_ATTR_TEST (session->attr,
2933 VCL_SESS_ATTR_TCP_KEEPINTVL), *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002934 }
2935 else
2936 rv = VPPCOM_EINVAL;
2937 break;
2938
2939 case VPPCOM_ATTR_GET_TCP_USER_MSS:
2940 if (buffer && buflen && (*buflen >= sizeof (u32)))
2941 {
2942 /* VPP-TBD */
2943 *(u32 *) buffer = session->user_mss;
2944 *buflen = sizeof (int);
2945
Florin Coras0d427d82018-06-27 03:24:07 -07002946 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_TCP_USER_MSS: %d, buflen %d,"
2947 " #VPP-TBD#", getpid (), *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002948 }
2949 else
2950 rv = VPPCOM_EINVAL;
2951 break;
2952
2953 case VPPCOM_ATTR_SET_TCP_USER_MSS:
2954 if (buffer && buflen && (*buflen == sizeof (u32)))
2955 {
2956 /* VPP-TBD */
2957 session->user_mss = *(u32 *) buffer;
2958
Florin Coras0d427d82018-06-27 03:24:07 -07002959 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_TCP_USER_MSS: %u, buflen %d, "
2960 "#VPP-TBD#", getpid (), session->user_mss, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002961 }
2962 else
2963 rv = VPPCOM_EINVAL;
Stevenbccd3392017-10-12 20:42:21 -07002964 break;
Dave Wallacee22aa742017-10-20 12:30:38 -04002965
2966 default:
2967 rv = VPPCOM_EINVAL;
2968 break;
Dave Wallace35830af2017-10-09 01:43:42 -04002969 }
2970
Dave Wallace35830af2017-10-09 01:43:42 -04002971 return rv;
2972}
2973
Stevenac1f96d2017-10-24 16:03:58 -07002974int
Florin Coras134a9962018-08-28 11:32:04 -07002975vppcom_session_recvfrom (uint32_t session_handle, void *buffer,
Stevenac1f96d2017-10-24 16:03:58 -07002976 uint32_t buflen, int flags, vppcom_endpt_t * ep)
2977{
Florin Coras134a9962018-08-28 11:32:04 -07002978 vcl_worker_t *wrk = vcl_worker_get_current ();
Stevenac1f96d2017-10-24 16:03:58 -07002979 int rv = VPPCOM_OK;
Florin Coras7e12d942018-06-27 14:32:43 -07002980 vcl_session_t *session = 0;
Stevenac1f96d2017-10-24 16:03:58 -07002981
2982 if (ep)
2983 {
Florin Coras134a9962018-08-28 11:32:04 -07002984 session = vcl_session_get_w_handle (wrk, session_handle);
Florin Coras070453d2018-08-24 17:04:27 -07002985 if (PREDICT_FALSE (!session))
Stevenac1f96d2017-10-24 16:03:58 -07002986 {
Florin Coras0d427d82018-06-27 03:24:07 -07002987 VDBG (0, "VCL<%d>: invalid session, sid (%u) has been closed!",
Florin Coras134a9962018-08-28 11:32:04 -07002988 getpid (), session_handle);
Florin Coras460dce62018-07-27 05:45:06 -07002989 return VPPCOM_EBADFD;
Stevenac1f96d2017-10-24 16:03:58 -07002990 }
Florin Coras7e12d942018-06-27 14:32:43 -07002991 ep->is_ip4 = session->transport.is_ip4;
2992 ep->port = session->transport.rmt_port;
Stevenac1f96d2017-10-24 16:03:58 -07002993 }
Steven58f464e2017-10-25 12:33:12 -07002994
2995 if (flags == 0)
Florin Coras134a9962018-08-28 11:32:04 -07002996 rv = vppcom_session_read (session_handle, buffer, buflen);
Stevenac1f96d2017-10-24 16:03:58 -07002997 else if (flags & MSG_PEEK)
Florin Coras134a9962018-08-28 11:32:04 -07002998 rv = vppcom_session_peek (session_handle, buffer, buflen);
Stevenac1f96d2017-10-24 16:03:58 -07002999 else
3000 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003001 clib_warning ("VCL<%d>: Unsupport flags for recvfrom %d",
3002 getpid (), flags);
Florin Coras460dce62018-07-27 05:45:06 -07003003 return VPPCOM_EAFNOSUPPORT;
Stevenac1f96d2017-10-24 16:03:58 -07003004 }
3005
Florin Coras99368312018-08-02 10:45:44 -07003006 if (ep)
3007 {
3008 if (session->transport.is_ip4)
3009 clib_memcpy (ep->ip, &session->transport.rmt_ip.ip4,
3010 sizeof (ip4_address_t));
3011 else
3012 clib_memcpy (ep->ip, &session->transport.rmt_ip.ip6,
3013 sizeof (ip6_address_t));
3014 }
Florin Coras460dce62018-07-27 05:45:06 -07003015
Stevenac1f96d2017-10-24 16:03:58 -07003016 return rv;
3017}
3018
3019int
Florin Coras134a9962018-08-28 11:32:04 -07003020vppcom_session_sendto (uint32_t session_handle, void *buffer,
Stevenac1f96d2017-10-24 16:03:58 -07003021 uint32_t buflen, int flags, vppcom_endpt_t * ep)
3022{
Dave Wallace617dffa2017-10-26 14:47:06 -04003023 if (!buffer)
3024 return VPPCOM_EINVAL;
3025
3026 if (ep)
3027 {
3028 // TBD
3029 return VPPCOM_EINVAL;
3030 }
3031
3032 if (flags)
3033 {
3034 // TBD check the flags and do the right thing
Florin Coras0d427d82018-06-27 03:24:07 -07003035 VDBG (2, "VCL<%d>: handling flags 0x%u (%d) not implemented yet.",
3036 getpid (), flags, flags);
Dave Wallace617dffa2017-10-26 14:47:06 -04003037 }
3038
Florin Coras134a9962018-08-28 11:32:04 -07003039 return (vppcom_session_write (session_handle, buffer, buflen));
Stevenac1f96d2017-10-24 16:03:58 -07003040}
3041
Dave Wallace048b1d62018-01-03 22:24:41 -05003042int
3043vppcom_poll (vcl_poll_t * vp, uint32_t n_sids, double wait_for_time)
3044{
Florin Coras134a9962018-08-28 11:32:04 -07003045 vcl_worker_t *wrk = vcl_worker_get_current ();
3046 f64 timeout = clib_time_now (&wrk->clib_time) + wait_for_time;
Dave Wallace048b1d62018-01-03 22:24:41 -05003047 u32 i, keep_trying = 1;
3048 int rv, num_ev = 0;
3049
Florin Coras0d427d82018-06-27 03:24:07 -07003050 VDBG (3, "VCL<%d>: vp %p, nsids %u, wait_for_time %f",
3051 getpid (), vp, n_sids, wait_for_time);
Dave Wallace048b1d62018-01-03 22:24:41 -05003052
3053 if (!vp)
3054 return VPPCOM_EFAULT;
3055
3056 do
3057 {
Florin Coras7e12d942018-06-27 14:32:43 -07003058 vcl_session_t *session;
Dave Wallace048b1d62018-01-03 22:24:41 -05003059
3060 for (i = 0; i < n_sids; i++)
3061 {
3062 ASSERT (vp[i].revents);
3063
Florin Coras134a9962018-08-28 11:32:04 -07003064 session = vcl_session_get (wrk, vp[i].sid);
Florin Coras070453d2018-08-24 17:04:27 -07003065 if (!session)
3066 continue;
Dave Wallace048b1d62018-01-03 22:24:41 -05003067
3068 if (*vp[i].revents)
3069 *vp[i].revents = 0;
3070
3071 if (POLLIN & vp[i].events)
3072 {
Florin Coras54693d22018-07-17 10:46:29 -07003073 rv = vppcom_session_read_ready (session);
Dave Wallace048b1d62018-01-03 22:24:41 -05003074 if (rv > 0)
3075 {
3076 *vp[i].revents |= POLLIN;
3077 num_ev++;
3078 }
3079 else if (rv < 0)
3080 {
3081 switch (rv)
3082 {
3083 case VPPCOM_ECONNRESET:
3084 *vp[i].revents = POLLHUP;
3085 break;
3086
3087 default:
3088 *vp[i].revents = POLLERR;
3089 break;
3090 }
3091 num_ev++;
3092 }
3093 }
3094
3095 if (POLLOUT & vp[i].events)
3096 {
Florin Coras134a9962018-08-28 11:32:04 -07003097 rv = vppcom_session_write_ready (session);
Dave Wallace048b1d62018-01-03 22:24:41 -05003098 if (rv > 0)
3099 {
3100 *vp[i].revents |= POLLOUT;
3101 num_ev++;
3102 }
3103 else if (rv < 0)
3104 {
3105 switch (rv)
3106 {
3107 case VPPCOM_ECONNRESET:
3108 *vp[i].revents = POLLHUP;
3109 break;
3110
3111 default:
3112 *vp[i].revents = POLLERR;
3113 break;
3114 }
3115 num_ev++;
3116 }
3117 }
3118
Dave Wallace7e607a72018-06-18 18:41:32 -04003119 if (0) // Note "done:" label used by VCL_SESSION_LOCK_AND_GET()
Dave Wallace048b1d62018-01-03 22:24:41 -05003120 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003121 *vp[i].revents = POLLNVAL;
3122 num_ev++;
3123 }
3124 }
3125 if (wait_for_time != -1)
Florin Coras134a9962018-08-28 11:32:04 -07003126 keep_trying = (clib_time_now (&wrk->clib_time) <= timeout) ? 1 : 0;
Dave Wallace048b1d62018-01-03 22:24:41 -05003127 }
3128 while ((num_ev == 0) && keep_trying);
3129
3130 if (VPPCOM_DEBUG > 3)
3131 {
3132 clib_warning ("VCL<%d>: returning %d", getpid (), num_ev);
3133 for (i = 0; i < n_sids; i++)
3134 {
3135 clib_warning ("VCL<%d>: vp[%d].sid %d (0x%x), .events 0x%x, "
3136 ".revents 0x%x", getpid (), i, vp[i].sid, vp[i].sid,
3137 vp[i].events, *vp[i].revents);
3138 }
3139 }
3140 return num_ev;
3141}
3142
Florin Coras99368312018-08-02 10:45:44 -07003143int
3144vppcom_mq_epoll_fd (void)
3145{
Florin Coras134a9962018-08-28 11:32:04 -07003146 vcl_worker_t *wrk = vcl_worker_get_current ();
3147 return wrk->mqs_epfd;
3148}
3149
3150int
3151vppcom_session_index (uint32_t session_handle)
3152{
3153 return session_handle & 0xFFFFFF;
3154}
3155
3156int
3157vppcom_worker_register (void)
3158{
3159 if (!vcl_worker_alloc_and_init ())
3160 return VPPCOM_OK;
3161 return VPPCOM_EEXIST;
Florin Coras99368312018-08-02 10:45:44 -07003162}
3163
Dave Wallacee22aa742017-10-20 12:30:38 -04003164/*
3165 * fd.io coding-style-patch-verification: ON
3166 *
3167 * Local Variables:
3168 * eval: (c-set-style "gnu")
3169 * End:
3170 */