blob: bf21f5204b49bf1d05193d44defb9a7fdff489f1 [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>
Florin Coras0d427d82018-06-27 03:24:07 -070020#include <vcl/vcl_debug.h>
Florin Coras697faea2018-06-27 17:10:49 -070021#include <vcl/vcl_private.h>
Dave Wallace7e607a72018-06-18 18:41:32 -040022
Florin Coras134a9962018-08-28 11:32:04 -070023__thread uword __vcl_worker_index = ~0;
24
Florin Coras54693d22018-07-17 10:46:29 -070025
Florin Corasd85de682018-11-29 17:02:29 -080026static int
27vcl_wait_for_segment (u64 segment_handle)
Florin Coras54693d22018-07-17 10:46:29 -070028{
Florin Corasd85de682018-11-29 17:02:29 -080029 vcl_worker_t *wrk = vcl_worker_get_current ();
30 u32 wait_for_seconds = 10, segment_index;
31 f64 timeout;
Florin Coras54693d22018-07-17 10:46:29 -070032
Florin Corasd85de682018-11-29 17:02:29 -080033 if (segment_handle == VCL_INVALID_SEGMENT_HANDLE)
34 return 1;
Florin Coras54693d22018-07-17 10:46:29 -070035
Florin Corasd85de682018-11-29 17:02:29 -080036 timeout = clib_time_now (&wrk->clib_time) + wait_for_seconds;
37 while (clib_time_now (&wrk->clib_time) < timeout)
Florin Coras54693d22018-07-17 10:46:29 -070038 {
Florin Corasd85de682018-11-29 17:02:29 -080039 segment_index = vcl_segment_table_lookup (segment_handle);
40 if (segment_index != VCL_INVALID_SEGMENT_INDEX)
41 return 0;
42 usleep (10);
Florin Coras54693d22018-07-17 10:46:29 -070043 }
Florin Corasd85de682018-11-29 17:02:29 -080044 return 1;
Florin Coras54693d22018-07-17 10:46:29 -070045}
46
Florin Coras697faea2018-06-27 17:10:49 -070047const char *
Dave Wallace543852a2017-08-03 02:11:34 -040048vppcom_session_state_str (session_state_t state)
49{
50 char *st;
51
52 switch (state)
53 {
54 case STATE_START:
55 st = "STATE_START";
56 break;
57
58 case STATE_CONNECT:
59 st = "STATE_CONNECT";
60 break;
61
62 case STATE_LISTEN:
63 st = "STATE_LISTEN";
64 break;
65
66 case STATE_ACCEPT:
67 st = "STATE_ACCEPT";
68 break;
69
Dave Wallace4878cbe2017-11-21 03:45:09 -050070 case STATE_CLOSE_ON_EMPTY:
71 st = "STATE_CLOSE_ON_EMPTY";
72 break;
73
Dave Wallace543852a2017-08-03 02:11:34 -040074 case STATE_DISCONNECT:
75 st = "STATE_DISCONNECT";
76 break;
77
78 case STATE_FAILED:
79 st = "STATE_FAILED";
80 break;
81
82 default:
83 st = "UNKNOWN_STATE";
84 break;
85 }
86
87 return st;
88}
89
Dave Wallace543852a2017-08-03 02:11:34 -040090u8 *
91format_ip4_address (u8 * s, va_list * args)
92{
93 u8 *a = va_arg (*args, u8 *);
94 return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
95}
96
97u8 *
98format_ip6_address (u8 * s, va_list * args)
99{
100 ip6_address_t *a = va_arg (*args, ip6_address_t *);
101 u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
102
103 i_max_n_zero = ARRAY_LEN (a->as_u16);
104 max_n_zeros = 0;
105 i_first_zero = i_max_n_zero;
106 n_zeros = 0;
107 for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
108 {
109 u32 is_zero = a->as_u16[i] == 0;
110 if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
111 {
112 i_first_zero = i;
113 n_zeros = 0;
114 }
115 n_zeros += is_zero;
116 if ((!is_zero && n_zeros > max_n_zeros)
117 || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
118 {
119 i_max_n_zero = i_first_zero;
120 max_n_zeros = n_zeros;
121 i_first_zero = ARRAY_LEN (a->as_u16);
122 n_zeros = 0;
123 }
124 }
125
126 last_double_colon = 0;
127 for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
128 {
129 if (i == i_max_n_zero && max_n_zeros > 1)
130 {
131 s = format (s, "::");
132 i += max_n_zeros - 1;
133 last_double_colon = 1;
134 }
135 else
136 {
137 s = format (s, "%s%x",
138 (last_double_colon || i == 0) ? "" : ":",
139 clib_net_to_host_u16 (a->as_u16[i]));
140 last_double_colon = 0;
141 }
142 }
143
144 return s;
145}
146
147/* Format an IP46 address. */
148u8 *
149format_ip46_address (u8 * s, va_list * args)
150{
151 ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
152 ip46_type_t type = va_arg (*args, ip46_type_t);
153 int is_ip4 = 1;
154
155 switch (type)
156 {
157 case IP46_TYPE_ANY:
158 is_ip4 = ip46_address_is_ip4 (ip46);
159 break;
160 case IP46_TYPE_IP4:
161 is_ip4 = 1;
162 break;
163 case IP46_TYPE_IP6:
164 is_ip4 = 0;
165 break;
166 }
167
168 return is_ip4 ?
169 format (s, "%U", format_ip4_address, &ip46->ip4) :
170 format (s, "%U", format_ip6_address, &ip46->ip6);
171}
172
Florin Coras697faea2018-06-27 17:10:49 -0700173/*
174 * VPPCOM Utility Functions
175 */
176
Florin Coras697faea2018-06-27 17:10:49 -0700177
Florin Corasc9fbd662018-08-24 12:59:56 -0700178static svm_msg_q_t *
Florin Coras134a9962018-08-28 11:32:04 -0700179vcl_session_vpp_evt_q (vcl_worker_t * wrk, vcl_session_t * s)
Florin Corasc9fbd662018-08-24 12:59:56 -0700180{
181 if (vcl_session_is_ct (s))
Florin Coras134a9962018-08-28 11:32:04 -0700182 return wrk->vpp_event_queues[0];
Florin Corasc9fbd662018-08-24 12:59:56 -0700183 else
Florin Coras134a9962018-08-28 11:32:04 -0700184 return wrk->vpp_event_queues[s->tx_fifo->master_thread_index];
Florin Corasc9fbd662018-08-24 12:59:56 -0700185}
186
Florin Coras54693d22018-07-17 10:46:29 -0700187static void
188vcl_send_session_accepted_reply (svm_msg_q_t * mq, u32 context,
189 session_handle_t handle, int retval)
190{
191 app_session_evt_t _app_evt, *app_evt = &_app_evt;
192 session_accepted_reply_msg_t *rmp;
193 app_alloc_ctrl_evt_to_vpp (mq, app_evt, SESSION_CTRL_EVT_ACCEPTED_REPLY);
194 rmp = (session_accepted_reply_msg_t *) app_evt->evt->data;
195 rmp->handle = handle;
196 rmp->context = context;
197 rmp->retval = retval;
198 app_send_ctrl_evt_to_vpp (mq, app_evt);
199}
200
Florin Coras99368312018-08-02 10:45:44 -0700201static void
202vcl_send_session_disconnected_reply (svm_msg_q_t * mq, u32 context,
203 session_handle_t handle, int retval)
204{
205 app_session_evt_t _app_evt, *app_evt = &_app_evt;
206 session_disconnected_reply_msg_t *rmp;
207 app_alloc_ctrl_evt_to_vpp (mq, app_evt,
208 SESSION_CTRL_EVT_DISCONNECTED_REPLY);
209 rmp = (session_disconnected_reply_msg_t *) app_evt->evt->data;
210 rmp->handle = handle;
211 rmp->context = context;
212 rmp->retval = retval;
213 app_send_ctrl_evt_to_vpp (mq, app_evt);
214}
215
Florin Corasc9fbd662018-08-24 12:59:56 -0700216static void
217vcl_send_session_reset_reply (svm_msg_q_t * mq, u32 context,
218 session_handle_t handle, int retval)
219{
220 app_session_evt_t _app_evt, *app_evt = &_app_evt;
221 session_reset_reply_msg_t *rmp;
222 app_alloc_ctrl_evt_to_vpp (mq, app_evt, SESSION_CTRL_EVT_RESET_REPLY);
223 rmp = (session_reset_reply_msg_t *) app_evt->evt->data;
224 rmp->handle = handle;
225 rmp->context = context;
226 rmp->retval = retval;
227 app_send_ctrl_evt_to_vpp (mq, app_evt);
228}
229
Florin Coras54693d22018-07-17 10:46:29 -0700230static u32
Florin Coras134a9962018-08-28 11:32:04 -0700231vcl_session_accepted_handler (vcl_worker_t * wrk, session_accepted_msg_t * mp)
Florin Coras54693d22018-07-17 10:46:29 -0700232{
233 vcl_session_t *session, *listen_session;
234 svm_fifo_t *rx_fifo, *tx_fifo;
Florin Coras134a9962018-08-28 11:32:04 -0700235 u32 vpp_wrk_index;
Florin Coras99368312018-08-02 10:45:44 -0700236 svm_msg_q_t *evt_q;
Florin Coras54693d22018-07-17 10:46:29 -0700237
Florin Coras134a9962018-08-28 11:32:04 -0700238 session = vcl_session_alloc (wrk);
Florin Coras99368312018-08-02 10:45:44 -0700239
Florin Coras134a9962018-08-28 11:32:04 -0700240 listen_session = vcl_session_table_lookup_listener (wrk,
241 mp->listener_handle);
Florin Coras54693d22018-07-17 10:46:29 -0700242 if (!listen_session)
243 {
244 svm_msg_q_t *evt_q;
245 evt_q = uword_to_pointer (mp->vpp_event_queue_address, svm_msg_q_t *);
246 clib_warning ("VCL<%d>: ERROR: couldn't find listen session: "
247 "unknown vpp listener handle %llx",
248 getpid (), mp->listener_handle);
249 vcl_send_session_accepted_reply (evt_q, mp->context, mp->handle,
250 VNET_API_ERROR_INVALID_ARGUMENT);
Florin Coras134a9962018-08-28 11:32:04 -0700251 vcl_session_free (wrk, session);
Florin Coras54693d22018-07-17 10:46:29 -0700252 return VCL_INVALID_SESSION_INDEX;
253 }
254
Florin Coras54693d22018-07-17 10:46:29 -0700255 rx_fifo = uword_to_pointer (mp->server_rx_fifo, svm_fifo_t *);
256 tx_fifo = uword_to_pointer (mp->server_tx_fifo, svm_fifo_t *);
257
258 if (mp->server_event_queue_address)
259 {
260 session->vpp_evt_q = uword_to_pointer (mp->client_event_queue_address,
261 svm_msg_q_t *);
262 session->our_evt_q = uword_to_pointer (mp->server_event_queue_address,
263 svm_msg_q_t *);
Florin Corasd85de682018-11-29 17:02:29 -0800264 if (vcl_wait_for_segment (mp->segment_handle))
265 {
266 clib_warning ("segment for session %u couldn't be mounted!",
267 session->session_index);
268 return VCL_INVALID_SESSION_INDEX;
269 }
Florin Coras134a9962018-08-28 11:32:04 -0700270 rx_fifo->master_session_index = session->session_index;
271 tx_fifo->master_session_index = session->session_index;
Florin Coras21795132018-09-09 09:40:51 -0700272 rx_fifo->master_thread_index = vcl_get_worker_index ();
273 tx_fifo->master_thread_index = vcl_get_worker_index ();
Florin Coras134a9962018-08-28 11:32:04 -0700274 vec_validate (wrk->vpp_event_queues, 0);
Florin Coras99368312018-08-02 10:45:44 -0700275 evt_q = uword_to_pointer (mp->vpp_event_queue_address, svm_msg_q_t *);
Florin Coras134a9962018-08-28 11:32:04 -0700276 wrk->vpp_event_queues[0] = evt_q;
Florin Coras54693d22018-07-17 10:46:29 -0700277 }
278 else
279 {
280 session->vpp_evt_q = uword_to_pointer (mp->vpp_event_queue_address,
281 svm_msg_q_t *);
Florin Coras134a9962018-08-28 11:32:04 -0700282 rx_fifo->client_session_index = session->session_index;
283 tx_fifo->client_session_index = session->session_index;
Florin Coras21795132018-09-09 09:40:51 -0700284 rx_fifo->client_thread_index = vcl_get_worker_index ();
285 tx_fifo->client_thread_index = vcl_get_worker_index ();
Florin Coras99368312018-08-02 10:45:44 -0700286 vpp_wrk_index = tx_fifo->master_thread_index;
Florin Coras134a9962018-08-28 11:32:04 -0700287 vec_validate (wrk->vpp_event_queues, vpp_wrk_index);
288 wrk->vpp_event_queues[vpp_wrk_index] = session->vpp_evt_q;
Florin Coras54693d22018-07-17 10:46:29 -0700289 }
290
291 session->vpp_handle = mp->handle;
292 session->client_context = mp->context;
293 session->rx_fifo = rx_fifo;
294 session->tx_fifo = tx_fifo;
295
296 session->session_state = STATE_ACCEPT;
297 session->transport.rmt_port = mp->port;
298 session->transport.is_ip4 = mp->is_ip4;
Dave Barach178cf492018-11-13 16:34:13 -0500299 clib_memcpy_fast (&session->transport.rmt_ip, mp->ip,
300 sizeof (ip46_address_t));
Florin Coras54693d22018-07-17 10:46:29 -0700301
Florin Coras134a9962018-08-28 11:32:04 -0700302 vcl_session_table_add_vpp_handle (wrk, mp->handle, session->session_index);
Florin Coras54693d22018-07-17 10:46:29 -0700303 session->transport.lcl_port = listen_session->transport.lcl_port;
304 session->transport.lcl_ip = listen_session->transport.lcl_ip;
Florin Coras460dce62018-07-27 05:45:06 -0700305 session->session_type = listen_session->session_type;
306 session->is_dgram = session->session_type == VPPCOM_PROTO_UDP;
Florin Coras54693d22018-07-17 10:46:29 -0700307
308 VDBG (1, "VCL<%d>: vpp handle 0x%llx, sid %u: client accept request from %s"
Florin Coras134a9962018-08-28 11:32:04 -0700309 " address %U port %d queue %p!", getpid (), mp->handle,
310 session->session_index,
Florin Coras54693d22018-07-17 10:46:29 -0700311 mp->is_ip4 ? "IPv4" : "IPv6", format_ip46_address, &mp->ip,
312 mp->is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6,
313 clib_net_to_host_u16 (mp->port), session->vpp_evt_q);
314 vcl_evt (VCL_EVT_ACCEPT, session, listen_session, session_index);
315
Florin Coras134a9962018-08-28 11:32:04 -0700316 return session->session_index;
Florin Coras54693d22018-07-17 10:46:29 -0700317}
318
319static u32
Florin Coras134a9962018-08-28 11:32:04 -0700320vcl_session_connected_handler (vcl_worker_t * wrk,
321 session_connected_msg_t * mp)
Florin Coras54693d22018-07-17 10:46:29 -0700322{
Florin Coras99368312018-08-02 10:45:44 -0700323 u32 session_index, vpp_wrk_index;
Florin Coras54693d22018-07-17 10:46:29 -0700324 svm_fifo_t *rx_fifo, *tx_fifo;
Florin Coras99368312018-08-02 10:45:44 -0700325 vcl_session_t *session = 0;
326 svm_msg_q_t *evt_q;
Florin Coras54693d22018-07-17 10:46:29 -0700327
328 session_index = mp->context;
Florin Coras134a9962018-08-28 11:32:04 -0700329 session = vcl_session_get (wrk, session_index);
Florin Coras070453d2018-08-24 17:04:27 -0700330 if (!session)
331 {
332 clib_warning ("[%s] ERROR: vpp handle 0x%llx, sid %u: "
333 "Invalid session index (%u)!",
334 getpid (), mp->handle, session_index);
335 return VCL_INVALID_SESSION_INDEX;
336 }
Florin Coras54693d22018-07-17 10:46:29 -0700337 if (mp->retval)
338 {
Florin Coras070453d2018-08-24 17:04:27 -0700339 clib_warning ("VCL<%d>: ERROR: sid %u: connect failed! %U", getpid (),
Florin Coras21795132018-09-09 09:40:51 -0700340 session_index, format_api_error, ntohl (mp->retval));
Florin Coras070453d2018-08-24 17:04:27 -0700341 session->session_state = STATE_FAILED;
342 session->vpp_handle = mp->handle;
343 return session_index;
Florin Coras54693d22018-07-17 10:46:29 -0700344 }
345
Florin Coras460dce62018-07-27 05:45:06 -0700346 rx_fifo = uword_to_pointer (mp->server_rx_fifo, svm_fifo_t *);
347 tx_fifo = uword_to_pointer (mp->server_tx_fifo, svm_fifo_t *);
Florin Corasd85de682018-11-29 17:02:29 -0800348 if (vcl_wait_for_segment (mp->segment_handle))
349 {
350 clib_warning ("segment for session %u couldn't be mounted!",
351 session->session_index);
352 return VCL_INVALID_SESSION_INDEX;
353 }
354
Florin Coras460dce62018-07-27 05:45:06 -0700355 rx_fifo->client_session_index = session_index;
356 tx_fifo->client_session_index = session_index;
Florin Coras21795132018-09-09 09:40:51 -0700357 rx_fifo->client_thread_index = vcl_get_worker_index ();
358 tx_fifo->client_thread_index = vcl_get_worker_index ();
Florin Coras460dce62018-07-27 05:45:06 -0700359
Florin Coras54693d22018-07-17 10:46:29 -0700360 if (mp->client_event_queue_address)
361 {
362 session->vpp_evt_q = uword_to_pointer (mp->server_event_queue_address,
363 svm_msg_q_t *);
364 session->our_evt_q = uword_to_pointer (mp->client_event_queue_address,
365 svm_msg_q_t *);
Florin Coras99368312018-08-02 10:45:44 -0700366
Florin Coras134a9962018-08-28 11:32:04 -0700367 vec_validate (wrk->vpp_event_queues, 0);
Florin Coras99368312018-08-02 10:45:44 -0700368 evt_q = uword_to_pointer (mp->vpp_event_queue_address, svm_msg_q_t *);
Florin Coras134a9962018-08-28 11:32:04 -0700369 wrk->vpp_event_queues[0] = evt_q;
Florin Coras54693d22018-07-17 10:46:29 -0700370 }
371 else
Florin Coras99368312018-08-02 10:45:44 -0700372 {
373 session->vpp_evt_q = uword_to_pointer (mp->vpp_event_queue_address,
374 svm_msg_q_t *);
375 vpp_wrk_index = tx_fifo->master_thread_index;
Florin Coras134a9962018-08-28 11:32:04 -0700376 vec_validate (wrk->vpp_event_queues, vpp_wrk_index);
377 wrk->vpp_event_queues[vpp_wrk_index] = session->vpp_evt_q;
Florin Coras99368312018-08-02 10:45:44 -0700378 }
Florin Coras54693d22018-07-17 10:46:29 -0700379
Florin Coras54693d22018-07-17 10:46:29 -0700380 session->rx_fifo = rx_fifo;
381 session->tx_fifo = tx_fifo;
382 session->vpp_handle = mp->handle;
383 session->transport.is_ip4 = mp->is_ip4;
Dave Barach178cf492018-11-13 16:34:13 -0500384 clib_memcpy_fast (&session->transport.lcl_ip, mp->lcl_ip,
385 sizeof (session->transport.lcl_ip));
Florin Coras54693d22018-07-17 10:46:29 -0700386 session->transport.lcl_port = mp->lcl_port;
387 session->session_state = STATE_CONNECT;
388
389 /* Add it to lookup table */
Florin Coras134a9962018-08-28 11:32:04 -0700390 hash_set (wrk->session_index_by_vpp_handles, mp->handle, session_index);
Florin Coras54693d22018-07-17 10:46:29 -0700391
392 VDBG (1, "VCL<%d>: vpp handle 0x%llx, sid %u: connect succeeded! "
393 "session_rx_fifo %p, refcnt %d, session_tx_fifo %p, refcnt %d",
394 getpid (), mp->handle, session_index, session->rx_fifo,
395 session->rx_fifo->refcnt, session->tx_fifo, session->tx_fifo->refcnt);
Florin Coras070453d2018-08-24 17:04:27 -0700396
Florin Coras54693d22018-07-17 10:46:29 -0700397 return session_index;
398}
399
Florin Corasc9fbd662018-08-24 12:59:56 -0700400static u32
Florin Coras134a9962018-08-28 11:32:04 -0700401vcl_session_reset_handler (vcl_worker_t * wrk,
402 session_reset_msg_t * reset_msg)
Florin Corasc9fbd662018-08-24 12:59:56 -0700403{
404 vcl_session_t *session;
405 u32 sid;
406
Florin Coras134a9962018-08-28 11:32:04 -0700407 sid = vcl_session_index_from_vpp_handle (wrk, reset_msg->handle);
408 session = vcl_session_get (wrk, sid);
Florin Corasc9fbd662018-08-24 12:59:56 -0700409 if (!session)
410 {
411 VDBG (0, "request to reset unknown handle 0x%llx", reset_msg->handle);
412 return VCL_INVALID_SESSION_INDEX;
413 }
414 session->session_state = STATE_CLOSE_ON_EMPTY;
415 VDBG (0, "reset handle 0x%llx, sid %u ", reset_msg->handle, sid);
Florin Coras134a9962018-08-28 11:32:04 -0700416 vcl_send_session_reset_reply (vcl_session_vpp_evt_q (wrk, session),
Florin Coras47c40e22018-11-26 17:01:36 -0800417 wrk->my_client_index, reset_msg->handle, 0);
Florin Corasc9fbd662018-08-24 12:59:56 -0700418 return sid;
419}
420
Florin Coras60116992018-08-27 09:52:18 -0700421static u32
Florin Coras134a9962018-08-28 11:32:04 -0700422vcl_session_bound_handler (vcl_worker_t * wrk, session_bound_msg_t * mp)
Florin Coras60116992018-08-27 09:52:18 -0700423{
424 vcl_session_t *session;
425 u32 sid = mp->context;
426
Florin Coras134a9962018-08-28 11:32:04 -0700427 session = vcl_session_get (wrk, sid);
Florin Coras60116992018-08-27 09:52:18 -0700428 if (mp->retval)
429 {
Florin Corasd85de682018-11-29 17:02:29 -0800430 VERR ("vpp handle 0x%llx, sid %u: bind failed: %U", mp->handle, sid,
431 format_api_error, mp->retval);
Florin Coras60116992018-08-27 09:52:18 -0700432 if (session)
433 {
434 session->session_state = STATE_FAILED;
435 session->vpp_handle = mp->handle;
436 return sid;
437 }
438 else
439 {
440 clib_warning ("[%s] ERROR: vpp handle 0x%llx, sid %u: "
441 "Invalid session index (%u)!",
442 getpid (), mp->handle, sid);
443 return VCL_INVALID_SESSION_INDEX;
444 }
445 }
446
447 session->vpp_handle = mp->handle;
448 session->transport.is_ip4 = mp->lcl_is_ip4;
Dave Barach178cf492018-11-13 16:34:13 -0500449 clib_memcpy_fast (&session->transport.lcl_ip, mp->lcl_ip,
450 sizeof (ip46_address_t));
Florin Coras60116992018-08-27 09:52:18 -0700451 session->transport.lcl_port = mp->lcl_port;
Florin Coras134a9962018-08-28 11:32:04 -0700452 vcl_session_table_add_listener (wrk, mp->handle, sid);
Florin Coras60116992018-08-27 09:52:18 -0700453 session->session_state = STATE_LISTEN;
454
455 if (session->is_dgram)
456 {
457 svm_fifo_t *rx_fifo, *tx_fifo;
458 session->vpp_evt_q = uword_to_pointer (mp->vpp_evt_q, svm_msg_q_t *);
459 rx_fifo = uword_to_pointer (mp->rx_fifo, svm_fifo_t *);
460 rx_fifo->client_session_index = sid;
461 tx_fifo = uword_to_pointer (mp->tx_fifo, svm_fifo_t *);
462 tx_fifo->client_session_index = sid;
463 session->rx_fifo = rx_fifo;
464 session->tx_fifo = tx_fifo;
465 }
466
Florin Corasdc2e2512018-12-03 17:47:26 -0800467 VDBG (0, "VCL<%d>: vpp handle 0x%llx, sid %u: bind succeeded!",
Florin Coras60116992018-08-27 09:52:18 -0700468 getpid (), mp->handle, sid);
469 return sid;
470}
471
Florin Coras86f04502018-09-12 16:08:01 -0700472static int
473vcl_handle_mq_event (vcl_worker_t * wrk, session_event_t * e)
Florin Coras54693d22018-07-17 10:46:29 -0700474{
475 session_accepted_msg_t *accepted_msg;
476 session_disconnected_msg_t *disconnected_msg;
477 vcl_session_msg_t *vcl_msg;
478 vcl_session_t *session;
479 u64 handle;
480 u32 sid;
481
482 switch (e->event_type)
483 {
484 case FIFO_EVENT_APP_RX:
Florin Coras86f04502018-09-12 16:08:01 -0700485 case FIFO_EVENT_APP_TX:
486 case SESSION_IO_EVT_CT_RX:
487 case SESSION_IO_EVT_CT_TX:
488 vec_add1 (wrk->unhandled_evts_vector, *e);
Florin Coras54693d22018-07-17 10:46:29 -0700489 break;
490 case SESSION_CTRL_EVT_ACCEPTED:
491 accepted_msg = (session_accepted_msg_t *) e->data;
492 handle = accepted_msg->listener_handle;
Florin Coras134a9962018-08-28 11:32:04 -0700493 session = vcl_session_table_lookup_listener (wrk, handle);
Florin Coras54693d22018-07-17 10:46:29 -0700494 if (!session)
495 {
496 clib_warning ("VCL<%d>: ERROR: couldn't find listen session:"
497 "listener handle %llx", getpid (), handle);
498 break;
499 }
500
501 clib_fifo_add2 (session->accept_evts_fifo, vcl_msg);
502 vcl_msg->accepted_msg = *accepted_msg;
503 break;
504 case SESSION_CTRL_EVT_CONNECTED:
Florin Coras134a9962018-08-28 11:32:04 -0700505 vcl_session_connected_handler (wrk,
506 (session_connected_msg_t *) e->data);
Florin Coras54693d22018-07-17 10:46:29 -0700507 break;
508 case SESSION_CTRL_EVT_DISCONNECTED:
509 disconnected_msg = (session_disconnected_msg_t *) e->data;
Florin Coras134a9962018-08-28 11:32:04 -0700510 sid = vcl_session_index_from_vpp_handle (wrk, disconnected_msg->handle);
511 session = vcl_session_get (wrk, sid);
Florin Corasc9fbd662018-08-24 12:59:56 -0700512 if (!session)
513 {
514 VDBG (0, "request to disconnect unknown handle 0x%llx",
515 disconnected_msg->handle);
516 break;
517 }
Florin Coras54693d22018-07-17 10:46:29 -0700518 session->session_state = STATE_DISCONNECT;
Florin Coras86f04502018-09-12 16:08:01 -0700519 VDBG (0, "disconnected handle 0x%llx, sid %u", disconnected_msg->handle,
Florin Corasc9fbd662018-08-24 12:59:56 -0700520 sid);
521 break;
522 case SESSION_CTRL_EVT_RESET:
Florin Coras134a9962018-08-28 11:32:04 -0700523 vcl_session_reset_handler (wrk, (session_reset_msg_t *) e->data);
Florin Coras60116992018-08-27 09:52:18 -0700524 break;
525 case SESSION_CTRL_EVT_BOUND:
Florin Coras134a9962018-08-28 11:32:04 -0700526 vcl_session_bound_handler (wrk, (session_bound_msg_t *) e->data);
Florin Coras54693d22018-07-17 10:46:29 -0700527 break;
528 default:
529 clib_warning ("unhandled %u", e->event_type);
530 }
531 return VPPCOM_OK;
532}
533
Florin Coras697faea2018-06-27 17:10:49 -0700534static inline int
535vppcom_wait_for_session_state_change (u32 session_index,
536 session_state_t state,
537 f64 wait_for_time)
538{
Florin Coras134a9962018-08-28 11:32:04 -0700539 vcl_worker_t *wrk = vcl_worker_get_current ();
540 f64 timeout = clib_time_now (&wrk->clib_time) + wait_for_time;
Florin Coras697faea2018-06-27 17:10:49 -0700541 vcl_session_t *volatile session;
Florin Coras54693d22018-07-17 10:46:29 -0700542 svm_msg_q_msg_t msg;
543 session_event_t *e;
Dave Wallace543852a2017-08-03 02:11:34 -0400544
Florin Coras697faea2018-06-27 17:10:49 -0700545 do
Dave Wallace543852a2017-08-03 02:11:34 -0400546 {
Florin Coras134a9962018-08-28 11:32:04 -0700547 session = vcl_session_get (wrk, session_index);
Florin Coras070453d2018-08-24 17:04:27 -0700548 if (PREDICT_FALSE (!session))
Florin Coras697faea2018-06-27 17:10:49 -0700549 {
Florin Coras070453d2018-08-24 17:04:27 -0700550 return VPPCOM_EBADFD;
Florin Coras697faea2018-06-27 17:10:49 -0700551 }
552 if (session->session_state & state)
553 {
Florin Coras697faea2018-06-27 17:10:49 -0700554 return VPPCOM_OK;
555 }
556 if (session->session_state & STATE_FAILED)
557 {
Florin Coras697faea2018-06-27 17:10:49 -0700558 return VPPCOM_ECONNREFUSED;
559 }
Florin Coras54693d22018-07-17 10:46:29 -0700560
Florin Coras134a9962018-08-28 11:32:04 -0700561 if (svm_msg_q_sub (wrk->app_event_queue, &msg, SVM_Q_NOWAIT, 0))
Florin Corasdc2e2512018-12-03 17:47:26 -0800562 {
563 usleep (100);
564 continue;
565 }
Florin Coras134a9962018-08-28 11:32:04 -0700566 e = svm_msg_q_msg_data (wrk->app_event_queue, &msg);
Florin Coras86f04502018-09-12 16:08:01 -0700567 vcl_handle_mq_event (wrk, e);
Florin Coras134a9962018-08-28 11:32:04 -0700568 svm_msg_q_free_msg (wrk->app_event_queue, &msg);
Florin Corasdcf55ce2017-11-16 15:32:50 -0800569 }
Florin Coras134a9962018-08-28 11:32:04 -0700570 while (clib_time_now (&wrk->clib_time) < timeout);
Florin Corasdcf55ce2017-11-16 15:32:50 -0800571
Florin Coras697faea2018-06-27 17:10:49 -0700572 VDBG (0, "VCL<%d>: timeout waiting for state 0x%x (%s)", getpid (), state,
573 vppcom_session_state_str (state));
574 vcl_evt (VCL_EVT_SESSION_TIMEOUT, session, session_state);
Dave Wallace543852a2017-08-03 02:11:34 -0400575
Florin Coras697faea2018-06-27 17:10:49 -0700576 return VPPCOM_ETIMEDOUT;
Dave Wallace60caa062017-11-10 17:07:13 -0500577}
578
Florin Coras697faea2018-06-27 17:10:49 -0700579static int
580vppcom_app_session_enable (void)
Dave Wallace543852a2017-08-03 02:11:34 -0400581{
Florin Coras697faea2018-06-27 17:10:49 -0700582 int rv;
Dave Wallace543852a2017-08-03 02:11:34 -0400583
Florin Coras697faea2018-06-27 17:10:49 -0700584 if (vcm->app_state != STATE_APP_ENABLED)
585 {
586 vppcom_send_session_enable_disable (1 /* is_enabled == TRUE */ );
Florin Coras134a9962018-08-28 11:32:04 -0700587 rv = vcl_wait_for_app_state_change (STATE_APP_ENABLED);
Florin Coras697faea2018-06-27 17:10:49 -0700588 if (PREDICT_FALSE (rv))
589 {
590 VDBG (0, "VCL<%d>: application session enable timed out! "
591 "returning %d (%s)", getpid (), rv, vppcom_retval_str (rv));
592 return rv;
593 }
594 }
595 return VPPCOM_OK;
Dave Wallace543852a2017-08-03 02:11:34 -0400596}
597
Florin Coras697faea2018-06-27 17:10:49 -0700598static int
599vppcom_app_attach (void)
Dave Wallace543852a2017-08-03 02:11:34 -0400600{
Florin Coras697faea2018-06-27 17:10:49 -0700601 int rv;
Dave Wallace543852a2017-08-03 02:11:34 -0400602
Florin Coras697faea2018-06-27 17:10:49 -0700603 vppcom_app_send_attach ();
Florin Coras134a9962018-08-28 11:32:04 -0700604 rv = vcl_wait_for_app_state_change (STATE_APP_ATTACHED);
Florin Coras697faea2018-06-27 17:10:49 -0700605 if (PREDICT_FALSE (rv))
606 {
607 VDBG (0, "VCL<%d>: application attach timed out! returning %d (%s)",
608 getpid (), rv, vppcom_retval_str (rv));
609 return rv;
610 }
Dave Wallace543852a2017-08-03 02:11:34 -0400611
Florin Coras697faea2018-06-27 17:10:49 -0700612 return VPPCOM_OK;
Dave Wallace543852a2017-08-03 02:11:34 -0400613}
614
615static int
Florin Corasab2f6db2018-08-31 14:31:41 -0700616vppcom_session_unbind (u32 session_handle)
Dave Wallace543852a2017-08-03 02:11:34 -0400617{
Florin Coras134a9962018-08-28 11:32:04 -0700618 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras7e12d942018-06-27 14:32:43 -0700619 vcl_session_t *session = 0;
Dave Wallace4878cbe2017-11-21 03:45:09 -0500620 u64 vpp_handle;
Dave Wallace543852a2017-08-03 02:11:34 -0400621
Florin Corasab2f6db2018-08-31 14:31:41 -0700622 session = vcl_session_get_w_handle (wrk, session_handle);
Florin Coras070453d2018-08-24 17:04:27 -0700623 if (!session)
624 return VPPCOM_EBADFD;
Dave Wallace4878cbe2017-11-21 03:45:09 -0500625
626 vpp_handle = session->vpp_handle;
Florin Coras134a9962018-08-28 11:32:04 -0700627 vcl_session_table_del_listener (wrk, vpp_handle);
Dave Wallace4878cbe2017-11-21 03:45:09 -0500628 session->vpp_handle = ~0;
Florin Coras7e12d942018-06-27 14:32:43 -0700629 session->session_state = STATE_DISCONNECT;
Dave Wallace4878cbe2017-11-21 03:45:09 -0500630
Florin Coras0d427d82018-06-27 03:24:07 -0700631 VDBG (1, "VCL<%d>: vpp handle 0x%llx, sid %u: sending unbind msg! new state"
Florin Corasab2f6db2018-08-31 14:31:41 -0700632 " 0x%x (%s)", getpid (), vpp_handle, session_handle, STATE_DISCONNECT,
Florin Coras0d427d82018-06-27 03:24:07 -0700633 vppcom_session_state_str (STATE_DISCONNECT));
634 vcl_evt (VCL_EVT_UNBIND, session);
Dave Wallace4878cbe2017-11-21 03:45:09 -0500635 vppcom_send_unbind_sock (vpp_handle);
636
Florin Coras070453d2018-08-24 17:04:27 -0700637 return VPPCOM_OK;
Dave Wallace543852a2017-08-03 02:11:34 -0400638}
639
Florin Coras697faea2018-06-27 17:10:49 -0700640static int
Florin Corasab2f6db2018-08-31 14:31:41 -0700641vppcom_session_disconnect (u32 session_handle)
Dave Wallace543852a2017-08-03 02:11:34 -0400642{
Florin Coras134a9962018-08-28 11:32:04 -0700643 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras99368312018-08-02 10:45:44 -0700644 svm_msg_q_t *vpp_evt_q;
Florin Coras7e12d942018-06-27 14:32:43 -0700645 vcl_session_t *session;
Dave Wallace4878cbe2017-11-21 03:45:09 -0500646 session_state_t state;
Florin Coras99368312018-08-02 10:45:44 -0700647 u64 vpp_handle;
Dave Wallace543852a2017-08-03 02:11:34 -0400648
Florin Corasab2f6db2018-08-31 14:31:41 -0700649 session = vcl_session_get_w_handle (wrk, session_handle);
Florin Coras21795132018-09-09 09:40:51 -0700650 if (!session)
651 return VPPCOM_EBADFD;
652
Dave Wallace4878cbe2017-11-21 03:45:09 -0500653 vpp_handle = session->vpp_handle;
Florin Coras7e12d942018-06-27 14:32:43 -0700654 state = session->session_state;
Dave Wallace4878cbe2017-11-21 03:45:09 -0500655
Florin Coras0d427d82018-06-27 03:24:07 -0700656 VDBG (1, "VCL<%d>: vpp handle 0x%llx, sid %u state 0x%x (%s)", getpid (),
Florin Corasab2f6db2018-08-31 14:31:41 -0700657 vpp_handle, session_handle, state, vppcom_session_state_str (state));
Dave Wallace66cf6eb2017-10-26 02:51:07 -0400658
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -0800659 if (PREDICT_FALSE (state & STATE_LISTEN))
Dave Wallace66cf6eb2017-10-26 02:51:07 -0400660 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500661 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -0500662 "Cannot disconnect a listen socket!",
Florin Corasab2f6db2018-08-31 14:31:41 -0700663 getpid (), vpp_handle, session_handle);
Florin Coras070453d2018-08-24 17:04:27 -0700664 return VPPCOM_EBADFD;
Dave Wallace4878cbe2017-11-21 03:45:09 -0500665 }
Dave Wallace66cf6eb2017-10-26 02:51:07 -0400666
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -0800667 if (state & STATE_CLOSE_ON_EMPTY)
Dave Wallace4878cbe2017-11-21 03:45:09 -0500668 {
Florin Coras134a9962018-08-28 11:32:04 -0700669 vpp_evt_q = vcl_session_vpp_evt_q (wrk, session);
Florin Coras47c40e22018-11-26 17:01:36 -0800670 vcl_send_session_disconnected_reply (vpp_evt_q, wrk->my_client_index,
Florin Coras99368312018-08-02 10:45:44 -0700671 vpp_handle, 0);
Florin Coras0d427d82018-06-27 03:24:07 -0700672 VDBG (1, "VCL<%d>: vpp handle 0x%llx, sid %u: sending disconnect "
Florin Corasab2f6db2018-08-31 14:31:41 -0700673 "REPLY...", getpid (), vpp_handle, session_handle);
Dave Wallace66cf6eb2017-10-26 02:51:07 -0400674 }
675 else
Dave Wallace227867f2017-11-13 21:21:53 -0500676 {
Florin Coras0d427d82018-06-27 03:24:07 -0700677 VDBG (1, "VCL<%d>: vpp handle 0x%llx, sid %u: sending disconnect...",
Florin Corasab2f6db2018-08-31 14:31:41 -0700678 getpid (), vpp_handle, session_handle);
679 vppcom_send_disconnect_session (vpp_handle);
Dave Wallace227867f2017-11-13 21:21:53 -0500680 }
Dave Wallace66cf6eb2017-10-26 02:51:07 -0400681
Florin Coras070453d2018-08-24 17:04:27 -0700682 return VPPCOM_OK;
Dave Wallace543852a2017-08-03 02:11:34 -0400683}
684
Florin Coras053a0e42018-11-13 15:52:38 -0800685static void
686vcl_cleanup_bapi (void)
687{
Florin Coras47c40e22018-11-26 17:01:36 -0800688 socket_client_main_t *scm = &socket_client_main;
Florin Coras053a0e42018-11-13 15:52:38 -0800689 api_main_t *am = &api_main;
690
691 am->my_client_index = ~0;
692 am->my_registration = 0;
693 am->vl_input_queue = 0;
694 am->msg_index_by_name_and_crc = 0;
Florin Coras47c40e22018-11-26 17:01:36 -0800695 scm->socket_fd = 0;
Florin Coras053a0e42018-11-13 15:52:38 -0800696
697 vl_client_api_unmap ();
698}
699
700void
701vcl_app_fork_child_handler (void)
702{
703 u8 *child_name;
Florin Coras47c40e22018-11-26 17:01:36 -0800704 int rv, parent_wrk;
Florin Coras053a0e42018-11-13 15:52:38 -0800705
Florin Coras940f78f2018-11-30 12:11:20 -0800706 parent_wrk = vcl_get_worker_index ();
707 VDBG (0, "initializing forked child with parent wrk %u", parent_wrk);
Florin Coras053a0e42018-11-13 15:52:38 -0800708
Florin Coras47c40e22018-11-26 17:01:36 -0800709 /*
710 * Allocate worker
711 */
Florin Coras47c40e22018-11-26 17:01:36 -0800712 vcl_set_worker_index (~0);
713 if (!vcl_worker_alloc_and_init ())
714 VERR ("couldn't allocate new worker");
715
716 /*
717 * Attach to binary api
718 */
719 child_name = format (0, "%v-child-%u%c", vcm->app_name, getpid (), 0);
Florin Coras053a0e42018-11-13 15:52:38 -0800720 vcl_cleanup_bapi ();
721 vppcom_api_hookup ();
722 vcm->app_state = STATE_APP_START;
723 rv = vppcom_connect_to_vpp ((char *) child_name);
724 vec_free (child_name);
725 if (rv)
726 {
727 VERR ("couldn't connect to VPP!");
728 return;
729 }
730
Florin Coras47c40e22018-11-26 17:01:36 -0800731 /*
732 * Register worker with vpp and share sessions
733 */
734 vcl_worker_register_with_vpp ();
735 vcl_worker_share_sessions (parent_wrk);
736
Florin Coras053a0e42018-11-13 15:52:38 -0800737 VDBG (0, "forked child main worker initialized");
Florin Coras47c40e22018-11-26 17:01:36 -0800738 vcm->forking = 0;
739}
740
741void
742vcl_app_fork_parent_handler (void)
743{
744 vcm->forking = 1;
745
746 while (vcm->forking)
747 ;
Florin Coras053a0e42018-11-13 15:52:38 -0800748}
749
Florin Coras940f78f2018-11-30 12:11:20 -0800750/**
751 * Handle app exit
752 *
753 * Notify vpp of the disconnect and mark the worker as free. If we're the
754 * last worker, do a full cleanup otherwise, since we're probably a forked
755 * child, avoid syscalls as much as possible. We might've lost privileges.
756 */
757void
758vppcom_app_exit (void)
759{
760 if (!pool_elts (vcm->workers))
761 return;
762
763 vcl_worker_cleanup (1 /* notify vpp */ );
764 vcl_elog_stop (vcm);
765 if (vec_len (vcm->workers) == 1)
766 vl_client_disconnect_from_vlib ();
767 else
768 vl_client_send_disconnect ();
769}
770
Dave Wallace543852a2017-08-03 02:11:34 -0400771/*
772 * VPPCOM Public API functions
773 */
774int
775vppcom_app_create (char *app_name)
776{
Dave Wallace543852a2017-08-03 02:11:34 -0400777 vppcom_cfg_t *vcl_cfg = &vcm->cfg;
Dave Wallace543852a2017-08-03 02:11:34 -0400778 int rv;
779
Florin Coras47c40e22018-11-26 17:01:36 -0800780 if (vcm->is_init)
Dave Wallace543852a2017-08-03 02:11:34 -0400781 {
Florin Corasdc2e2512018-12-03 17:47:26 -0800782 clib_warning ("vcl<%u> already initialized", getpid ());
Florin Coras47c40e22018-11-26 17:01:36 -0800783 return -1;
Dave Wallace543852a2017-08-03 02:11:34 -0400784 }
785
Florin Coras47c40e22018-11-26 17:01:36 -0800786 vcm->is_init = 1;
787 vppcom_cfg (&vcm->cfg);
788 vcl_cfg = &vcm->cfg;
789
790 vcm->main_cpu = pthread_self ();
791 vcm->main_pid = getpid ();
792 vcm->app_name = format (0, "%s", app_name);
793 vppcom_init_error_string_table ();
Florin Corasadc74d72018-12-02 13:36:00 -0800794 svm_fifo_segment_main_init (&vcm->segment_main, vcl_cfg->segment_baseva,
Florin Coras47c40e22018-11-26 17:01:36 -0800795 20 /* timeout in secs */ );
796 pool_alloc (vcm->workers, vcl_cfg->max_workers);
797 clib_spinlock_init (&vcm->workers_lock);
Florin Corasd85de682018-11-29 17:02:29 -0800798 clib_rwlock_init (&vcm->segment_table_lock);
Florin Coras47c40e22018-11-26 17:01:36 -0800799 pthread_atfork (NULL, vcl_app_fork_parent_handler,
800 vcl_app_fork_child_handler);
Florin Coras940f78f2018-11-30 12:11:20 -0800801 atexit (vppcom_app_exit);
Florin Coras47c40e22018-11-26 17:01:36 -0800802
803 /* Allocate default worker */
804 vcl_worker_alloc_and_init ();
805
806 /* API hookup and connect to VPP */
807 vppcom_api_hookup ();
808 vcl_elog_init (vcm);
809 vcm->app_state = STATE_APP_START;
810 rv = vppcom_connect_to_vpp (app_name);
811 if (rv)
Dave Wallace543852a2017-08-03 02:11:34 -0400812 {
Florin Coras47c40e22018-11-26 17:01:36 -0800813 VERR ("couldn't connect to VPP!");
814 return rv;
Dave Wallace66cf6eb2017-10-26 02:51:07 -0400815 }
Florin Coras47c40e22018-11-26 17:01:36 -0800816 VDBG (0, "sending session enable");
817 rv = vppcom_app_session_enable ();
818 if (rv)
819 {
820 VERR ("vppcom_app_session_enable() failed!");
821 return rv;
822 }
823
824 VDBG (0, "sending app attach");
825 rv = vppcom_app_attach ();
826 if (rv)
827 {
828 VERR ("vppcom_app_attach() failed!");
829 return rv;
830 }
831
832 VDBG (0, "app_name '%s', my_client_index %d (0x%x)", app_name,
833 vcm->workers[0].my_client_index, vcm->workers[0].my_client_index);
Dave Wallace543852a2017-08-03 02:11:34 -0400834
835 return VPPCOM_OK;
836}
837
838void
839vppcom_app_destroy (void)
840{
Dave Wallace543852a2017-08-03 02:11:34 -0400841 int rv;
Dave Wallacede910062018-03-20 09:22:13 -0400842 f64 orig_app_timeout;
Dave Wallace543852a2017-08-03 02:11:34 -0400843
Florin Coras940f78f2018-11-30 12:11:20 -0800844 if (!pool_elts (vcm->workers))
845 return;
846
Florin Coras0d427d82018-06-27 03:24:07 -0700847 vcl_evt (VCL_EVT_DETACH, vcm);
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -0800848
Florin Coras940f78f2018-11-30 12:11:20 -0800849 if (pool_elts (vcm->workers) == 1)
Florin Coras47c40e22018-11-26 17:01:36 -0800850 {
851 vppcom_app_send_detach ();
852 orig_app_timeout = vcm->cfg.app_timeout;
853 vcm->cfg.app_timeout = 2.0;
854 rv = vcl_wait_for_app_state_change (STATE_APP_ENABLED);
855 vcm->cfg.app_timeout = orig_app_timeout;
856 if (PREDICT_FALSE (rv))
857 VDBG (0, "application detach timed out! returning %d (%s)", rv,
858 vppcom_retval_str (rv));
Florin Coras940f78f2018-11-30 12:11:20 -0800859 vec_free (vcm->app_name);
860 vcl_worker_cleanup (0 /* notify vpp */ );
Florin Coras47c40e22018-11-26 17:01:36 -0800861 }
862 else
863 {
Florin Coras940f78f2018-11-30 12:11:20 -0800864 vcl_worker_cleanup (1 /* notify vpp */ );
Florin Coras47c40e22018-11-26 17:01:36 -0800865 }
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -0800866
Florin Coras0d427d82018-06-27 03:24:07 -0700867 vcl_elog_stop (vcm);
Dave Wallace543852a2017-08-03 02:11:34 -0400868 vl_client_disconnect_from_vlib ();
Dave Wallace543852a2017-08-03 02:11:34 -0400869}
870
871int
Dave Wallacec04cbf12018-02-07 18:14:02 -0500872vppcom_session_create (u8 proto, u8 is_nonblocking)
Dave Wallace543852a2017-08-03 02:11:34 -0400873{
Florin Coras134a9962018-08-28 11:32:04 -0700874 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras7e12d942018-06-27 14:32:43 -0700875 vcl_session_t *session;
Dave Wallace543852a2017-08-03 02:11:34 -0400876
Florin Coras134a9962018-08-28 11:32:04 -0700877 session = vcl_session_alloc (wrk);
Dave Wallace543852a2017-08-03 02:11:34 -0400878
Florin Coras7e12d942018-06-27 14:32:43 -0700879 session->session_type = proto;
880 session->session_state = STATE_START;
Dave Wallace4878cbe2017-11-21 03:45:09 -0500881 session->vpp_handle = ~0;
Florin Coras460dce62018-07-27 05:45:06 -0700882 session->is_dgram = proto == VPPCOM_PROTO_UDP;
Dave Wallace543852a2017-08-03 02:11:34 -0400883
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -0800884 if (is_nonblocking)
885 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_NONBLOCK);
Dave Wallace543852a2017-08-03 02:11:34 -0400886
Florin Coras7e12d942018-06-27 14:32:43 -0700887 vcl_evt (VCL_EVT_CREATE, session, session_type, session->session_state,
888 is_nonblocking, session_index);
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -0800889
Florin Coras053a0e42018-11-13 15:52:38 -0800890 VDBG (0, "created sid %u", session->session_index);
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -0800891
Florin Coras134a9962018-08-28 11:32:04 -0700892 return vcl_session_handle (session);
Dave Wallace543852a2017-08-03 02:11:34 -0400893}
894
895int
Florin Coras134a9962018-08-28 11:32:04 -0700896vppcom_session_close (uint32_t session_handle)
Dave Wallace543852a2017-08-03 02:11:34 -0400897{
Florin Coras134a9962018-08-28 11:32:04 -0700898 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras47c40e22018-11-26 17:01:36 -0800899 u8 is_vep, do_disconnect = 1;
Florin Coras7e12d942018-06-27 14:32:43 -0700900 vcl_session_t *session = 0;
Dave Wallace66cf6eb2017-10-26 02:51:07 -0400901 session_state_t state;
Florin Coras134a9962018-08-28 11:32:04 -0700902 u32 next_sh, vep_sh;
903 int rv = VPPCOM_OK;
904 u64 vpp_handle;
Dave Wallace543852a2017-08-03 02:11:34 -0400905
Florin Coras134a9962018-08-28 11:32:04 -0700906 session = vcl_session_get_w_handle (wrk, session_handle);
Florin Coras070453d2018-08-24 17:04:27 -0700907 if (!session)
908 return VPPCOM_EBADFD;
909
Florin Coras47c40e22018-11-26 17:01:36 -0800910 if (session->shared_index != ~0)
911 do_disconnect = vcl_worker_unshare_session (wrk, session);
912
Dave Wallace66cf6eb2017-10-26 02:51:07 -0400913 is_vep = session->is_vep;
Florin Coras134a9962018-08-28 11:32:04 -0700914 next_sh = session->vep.next_sh;
915 vep_sh = session->vep.vep_sh;
Florin Coras7e12d942018-06-27 14:32:43 -0700916 state = session->session_state;
Dave Wallaceee45d412017-11-24 21:44:06 -0500917 vpp_handle = session->vpp_handle;
Dave Wallace543852a2017-08-03 02:11:34 -0400918
Florin Coras47c40e22018-11-26 17:01:36 -0800919 VDBG (0, "Closing session handle %u vpp handle %u", session_handle,
920 vpp_handle);
Dave Wallace543852a2017-08-03 02:11:34 -0400921
Dave Wallace66cf6eb2017-10-26 02:51:07 -0400922 if (is_vep)
Dave Wallace543852a2017-08-03 02:11:34 -0400923 {
Florin Coras134a9962018-08-28 11:32:04 -0700924 while (next_sh != ~0)
Dave Wallace19481612017-09-15 18:47:44 -0400925 {
Florin Coras134a9962018-08-28 11:32:04 -0700926 rv = vppcom_epoll_ctl (session_handle, EPOLL_CTL_DEL, next_sh, 0);
Florin Coras0d427d82018-06-27 03:24:07 -0700927 if (PREDICT_FALSE (rv < 0))
Florin Coras47c40e22018-11-26 17:01:36 -0800928 VDBG (0, "vpp handle 0x%llx, sid %u: EPOLL_CTL_DEL vep_idx %u"
929 " failed! rv %d (%s)", vpp_handle, next_sh, vep_sh, rv,
930 vppcom_retval_str (rv));
Dave Wallacef7f809c2017-10-03 01:48:42 -0400931
Florin Coras134a9962018-08-28 11:32:04 -0700932 next_sh = session->vep.next_sh;
Dave Wallacef7f809c2017-10-03 01:48:42 -0400933 }
934 }
935 else
936 {
Florin Coras47c40e22018-11-26 17:01:36 -0800937 if (session->is_vep_session)
Dave Wallacef7f809c2017-10-03 01:48:42 -0400938 {
Florin Coras134a9962018-08-28 11:32:04 -0700939 rv = vppcom_epoll_ctl (vep_sh, EPOLL_CTL_DEL, session_handle, 0);
Florin Coras0d427d82018-06-27 03:24:07 -0700940 if (rv < 0)
Florin Coras47c40e22018-11-26 17:01:36 -0800941 VDBG (0, "vpp handle 0x%llx, sid %u: EPOLL_CTL_DEL vep_idx %u "
942 "failed! rv %d (%s)", vpp_handle, session_handle, vep_sh,
943 rv, vppcom_retval_str (rv));
Dave Wallacef7f809c2017-10-03 01:48:42 -0400944 }
945
Florin Coras47c40e22018-11-26 17:01:36 -0800946 if (!do_disconnect)
947 goto cleanup;
948
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -0800949 if (state & STATE_LISTEN)
Dave Wallacef7f809c2017-10-03 01:48:42 -0400950 {
Florin Coras134a9962018-08-28 11:32:04 -0700951 rv = vppcom_session_unbind (session_handle);
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -0800952 if (PREDICT_FALSE (rv < 0))
Florin Coras47c40e22018-11-26 17:01:36 -0800953 VDBG (0, "vpp handle 0x%llx, sid %u: listener unbind failed! "
954 "rv %d (%s)", vpp_handle, session_handle, rv,
955 vppcom_retval_str (rv));
Dave Wallacef7f809c2017-10-03 01:48:42 -0400956 }
Florin Coras070453d2018-08-24 17:04:27 -0700957 else if (state & STATE_OPEN)
Dave Wallacef7f809c2017-10-03 01:48:42 -0400958 {
Florin Coras134a9962018-08-28 11:32:04 -0700959 rv = vppcom_session_disconnect (session_handle);
Dave Wallace4878cbe2017-11-21 03:45:09 -0500960 if (PREDICT_FALSE (rv < 0))
Dave Wallace048b1d62018-01-03 22:24:41 -0500961 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -0500962 "session disconnect failed! rv %d (%s)",
Florin Coras134a9962018-08-28 11:32:04 -0700963 getpid (), vpp_handle, session_handle,
Dave Wallaceee45d412017-11-24 21:44:06 -0500964 rv, vppcom_retval_str (rv));
Dave Wallacef7f809c2017-10-03 01:48:42 -0400965 }
Dave Wallace19481612017-09-15 18:47:44 -0400966 }
Dave Wallace4878cbe2017-11-21 03:45:09 -0500967
Florin Coras47c40e22018-11-26 17:01:36 -0800968cleanup:
969
Florin Coras99368312018-08-02 10:45:44 -0700970 if (vcl_session_is_ct (session))
971 {
972 vcl_cut_through_registration_t *ctr;
973 uword mq_addr;
974
975 mq_addr = pointer_to_uword (session->our_evt_q);
Florin Coras134a9962018-08-28 11:32:04 -0700976 ctr = vcl_ct_registration_lock_and_lookup (wrk, mq_addr);
Florin Coras99368312018-08-02 10:45:44 -0700977 ASSERT (ctr);
978 if (ctr->epoll_evt_conn_index != ~0)
Florin Coras134a9962018-08-28 11:32:04 -0700979 vcl_mq_epoll_del_evfd (wrk, ctr->epoll_evt_conn_index);
Florin Coras99368312018-08-02 10:45:44 -0700980 VDBG (0, "Removing ct registration %u",
Florin Coras134a9962018-08-28 11:32:04 -0700981 vcl_ct_registration_index (wrk, ctr));
982 vcl_ct_registration_del (wrk, ctr);
983 vcl_ct_registration_lookup_del (wrk, mq_addr);
984 vcl_ct_registration_unlock (wrk);
Florin Coras99368312018-08-02 10:45:44 -0700985 }
Florin Coras54693d22018-07-17 10:46:29 -0700986
Dave Wallaceee45d412017-11-24 21:44:06 -0500987 if (vpp_handle != ~0)
Dave Wallace4878cbe2017-11-21 03:45:09 -0500988 {
Florin Coras134a9962018-08-28 11:32:04 -0700989 vcl_session_table_del_vpp_handle (wrk, vpp_handle);
Dave Wallace4878cbe2017-11-21 03:45:09 -0500990 }
Florin Coras134a9962018-08-28 11:32:04 -0700991 vcl_session_free (wrk, session);
Dave Wallace4878cbe2017-11-21 03:45:09 -0500992
Florin Coras47c40e22018-11-26 17:01:36 -0800993 VDBG (0, "session handle %u vpp handle %u removed", session_handle,
994 vpp_handle);
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -0800995
Florin Coras0d427d82018-06-27 03:24:07 -0700996 vcl_evt (VCL_EVT_CLOSE, session, rv);
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -0800997
Dave Wallace543852a2017-08-03 02:11:34 -0400998 return rv;
999}
1000
1001int
Florin Coras134a9962018-08-28 11:32:04 -07001002vppcom_session_bind (uint32_t session_handle, vppcom_endpt_t * ep)
Dave Wallace543852a2017-08-03 02:11:34 -04001003{
Florin Coras134a9962018-08-28 11:32:04 -07001004 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras7e12d942018-06-27 14:32:43 -07001005 vcl_session_t *session = 0;
Dave Wallace543852a2017-08-03 02:11:34 -04001006
1007 if (!ep || !ep->ip)
1008 return VPPCOM_EINVAL;
1009
Florin Coras134a9962018-08-28 11:32:04 -07001010 session = vcl_session_get_w_handle (wrk, session_handle);
Florin Coras070453d2018-08-24 17:04:27 -07001011 if (!session)
1012 return VPPCOM_EBADFD;
Dave Wallace543852a2017-08-03 02:11:34 -04001013
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001014 if (session->is_vep)
1015 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001016 clib_warning ("VCL<%d>: ERROR: sid %u: cannot "
Florin Coras134a9962018-08-28 11:32:04 -07001017 "bind to an epoll session!", getpid (), session_handle);
Florin Coras070453d2018-08-24 17:04:27 -07001018 return VPPCOM_EBADFD;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001019 }
1020
Florin Coras7e12d942018-06-27 14:32:43 -07001021 session->transport.is_ip4 = ep->is_ip4;
Florin Coras54693d22018-07-17 10:46:29 -07001022 if (ep->is_ip4)
Dave Barach178cf492018-11-13 16:34:13 -05001023 clib_memcpy_fast (&session->transport.lcl_ip.ip4, ep->ip,
1024 sizeof (ip4_address_t));
Florin Coras54693d22018-07-17 10:46:29 -07001025 else
Dave Barach178cf492018-11-13 16:34:13 -05001026 clib_memcpy_fast (&session->transport.lcl_ip.ip6, ep->ip,
1027 sizeof (ip6_address_t));
Florin Coras7e12d942018-06-27 14:32:43 -07001028 session->transport.lcl_port = ep->port;
Stevenac1f96d2017-10-24 16:03:58 -07001029
Florin Coras0d427d82018-06-27 03:24:07 -07001030 VDBG (0, "VCL<%d>: sid %u: binding to local %s address %U port %u, "
Florin Coras134a9962018-08-28 11:32:04 -07001031 "proto %s", getpid (), session_handle,
Florin Coras7e12d942018-06-27 14:32:43 -07001032 session->transport.is_ip4 ? "IPv4" : "IPv6",
1033 format_ip46_address, &session->transport.lcl_ip,
1034 session->transport.is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6,
1035 clib_net_to_host_u16 (session->transport.lcl_port),
1036 session->session_type ? "UDP" : "TCP");
Florin Coras0d427d82018-06-27 03:24:07 -07001037 vcl_evt (VCL_EVT_BIND, session);
Florin Coras460dce62018-07-27 05:45:06 -07001038
1039 if (session->session_type == VPPCOM_PROTO_UDP)
Florin Coras134a9962018-08-28 11:32:04 -07001040 vppcom_session_listen (session_handle, 10);
Florin Coras460dce62018-07-27 05:45:06 -07001041
Florin Coras070453d2018-08-24 17:04:27 -07001042 return VPPCOM_OK;
Dave Wallace543852a2017-08-03 02:11:34 -04001043}
1044
1045int
Florin Coras134a9962018-08-28 11:32:04 -07001046vppcom_session_listen (uint32_t listen_sh, uint32_t q_len)
Dave Wallace543852a2017-08-03 02:11:34 -04001047{
Florin Coras134a9962018-08-28 11:32:04 -07001048 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras7e12d942018-06-27 14:32:43 -07001049 vcl_session_t *listen_session = 0;
Dave Wallaceee45d412017-11-24 21:44:06 -05001050 u64 listen_vpp_handle;
Florin Coras070453d2018-08-24 17:04:27 -07001051 int rv;
1052
Florin Coras134a9962018-08-28 11:32:04 -07001053 listen_session = vcl_session_get_w_handle (wrk, listen_sh);
Florin Coras070453d2018-08-24 17:04:27 -07001054 if (!listen_session)
1055 return VPPCOM_EBADFD;
Dave Wallace543852a2017-08-03 02:11:34 -04001056
Keith Burns (alagalah)aba98de2018-02-22 03:23:40 -08001057 if (q_len == 0 || q_len == ~0)
1058 q_len = vcm->cfg.listen_queue_size;
1059
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001060 if (listen_session->is_vep)
1061 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001062 clib_warning ("VCL<%d>: ERROR: sid %u: cannot listen on an "
Florin Coras134a9962018-08-28 11:32:04 -07001063 "epoll session!", getpid (), listen_sh);
Florin Coras070453d2018-08-24 17:04:27 -07001064 return VPPCOM_EBADFD;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001065 }
1066
Dave Wallaceee45d412017-11-24 21:44:06 -05001067 listen_vpp_handle = listen_session->vpp_handle;
Florin Coras7e12d942018-06-27 14:32:43 -07001068 if (listen_session->session_state & STATE_LISTEN)
Dave Wallacee695cb42017-11-02 22:04:42 -04001069 {
Florin Coras0d427d82018-06-27 03:24:07 -07001070 VDBG (0, "VCL<%d>: vpp handle 0x%llx, sid %u: already in listen state!",
Florin Coras134a9962018-08-28 11:32:04 -07001071 getpid (), listen_vpp_handle, listen_sh);
Florin Coras070453d2018-08-24 17:04:27 -07001072 return VPPCOM_OK;
Dave Wallacee695cb42017-11-02 22:04:42 -04001073 }
1074
Florin Coras0d427d82018-06-27 03:24:07 -07001075 VDBG (0, "VCL<%d>: vpp handle 0x%llx, sid %u: sending VPP bind+listen "
Florin Coras134a9962018-08-28 11:32:04 -07001076 "request...", getpid (), listen_vpp_handle, listen_sh);
Dave Wallace543852a2017-08-03 02:11:34 -04001077
Florin Coras070453d2018-08-24 17:04:27 -07001078 /*
1079 * Send listen request to vpp and wait for reply
1080 */
Florin Coras134a9962018-08-28 11:32:04 -07001081 vppcom_send_bind_sock (listen_session);
1082 rv = vppcom_wait_for_session_state_change (listen_session->session_index,
1083 STATE_LISTEN,
1084 vcm->cfg.session_timeout);
Dave Wallace543852a2017-08-03 02:11:34 -04001085
Florin Coras070453d2018-08-24 17:04:27 -07001086 if (PREDICT_FALSE (rv))
Dave Wallaceee45d412017-11-24 21:44:06 -05001087 {
Florin Coras134a9962018-08-28 11:32:04 -07001088 listen_session = vcl_session_get_w_handle (wrk, listen_sh);
Florin Coras0d427d82018-06-27 03:24:07 -07001089 VDBG (0, "VCL<%d>: vpp handle 0x%llx, sid %u: bind+listen failed! "
1090 "returning %d (%s)", getpid (), listen_session->vpp_handle,
Florin Coras134a9962018-08-28 11:32:04 -07001091 listen_sh, rv, vppcom_retval_str (rv));
Florin Coras070453d2018-08-24 17:04:27 -07001092 return rv;
Dave Wallaceee45d412017-11-24 21:44:06 -05001093 }
1094
Florin Coras070453d2018-08-24 17:04:27 -07001095 return VPPCOM_OK;
Keith Burns (alagalah)0d2b0d52018-03-06 15:55:22 -08001096}
1097
Florin Coras134a9962018-08-28 11:32:04 -07001098static int
1099validate_args_session_accept_ (vcl_worker_t * wrk,
1100 vcl_session_t * listen_session)
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001101{
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001102 /* Input validation - expects spinlock on sessions_lockp */
1103 if (listen_session->is_vep)
1104 {
1105 clib_warning ("VCL<%d>: ERROR: sid %u: cannot accept on an "
Florin Coras134a9962018-08-28 11:32:04 -07001106 "epoll session!", getpid (),
1107 listen_session->session_index);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001108 return VPPCOM_EBADFD;
1109 }
1110
Florin Coras7e12d942018-06-27 14:32:43 -07001111 if (listen_session->session_state != STATE_LISTEN)
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001112 {
1113 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
1114 "not in listen state! state 0x%x (%s)", getpid (),
Florin Coras134a9962018-08-28 11:32:04 -07001115 listen_session->vpp_handle, listen_session->session_index,
Florin Coras7e12d942018-06-27 14:32:43 -07001116 listen_session->session_state,
1117 vppcom_session_state_str (listen_session->session_state));
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001118 return VPPCOM_EBADFD;
1119 }
1120 return VPPCOM_OK;
1121}
1122
1123int
Florin Coras134a9962018-08-28 11:32:04 -07001124vppcom_session_accept (uint32_t listen_session_handle, vppcom_endpt_t * ep,
Dave Wallace048b1d62018-01-03 22:24:41 -05001125 uint32_t flags)
Dave Wallace543852a2017-08-03 02:11:34 -04001126{
Florin Coras134a9962018-08-28 11:32:04 -07001127 u32 client_session_index = ~0, listen_session_index;
1128 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras54693d22018-07-17 10:46:29 -07001129 session_accepted_msg_t accepted_msg;
Florin Coras7e12d942018-06-27 14:32:43 -07001130 vcl_session_t *listen_session = 0;
1131 vcl_session_t *client_session = 0;
Florin Coras54693d22018-07-17 10:46:29 -07001132 svm_msg_q_t *vpp_evt_q;
1133 vcl_session_msg_t *evt;
Dave Wallaceee45d412017-11-24 21:44:06 -05001134 u64 listen_vpp_handle;
Florin Coras54693d22018-07-17 10:46:29 -07001135 svm_msg_q_msg_t msg;
1136 session_event_t *e;
1137 u8 is_nonblocking;
1138 int rv;
Dave Wallace543852a2017-08-03 02:11:34 -04001139
Florin Coras134a9962018-08-28 11:32:04 -07001140 listen_session = vcl_session_get_w_handle (wrk, listen_session_handle);
Florin Coras070453d2018-08-24 17:04:27 -07001141 if (!listen_session)
1142 return VPPCOM_EBADFD;
Dave Wallace543852a2017-08-03 02:11:34 -04001143
Florin Coras134a9962018-08-28 11:32:04 -07001144 listen_session_index = listen_session->session_index;
1145 if ((rv = validate_args_session_accept_ (wrk, listen_session)))
Florin Coras070453d2018-08-24 17:04:27 -07001146 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04001147
Florin Coras54693d22018-07-17 10:46:29 -07001148 if (clib_fifo_elts (listen_session->accept_evts_fifo))
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001149 {
Florin Coras54693d22018-07-17 10:46:29 -07001150 clib_fifo_sub2 (listen_session->accept_evts_fifo, evt);
1151 accepted_msg = evt->accepted_msg;
1152 goto handle;
1153 }
1154
1155 is_nonblocking = VCL_SESS_ATTR_TEST (listen_session->attr,
1156 VCL_SESS_ATTR_NONBLOCK);
Florin Coras134a9962018-08-28 11:32:04 -07001157 if (svm_msg_q_is_empty (wrk->app_event_queue) && is_nonblocking)
Florin Coras54693d22018-07-17 10:46:29 -07001158 return VPPCOM_EAGAIN;
1159
1160 while (1)
1161 {
Florin Coras134a9962018-08-28 11:32:04 -07001162 if (svm_msg_q_sub (wrk->app_event_queue, &msg, SVM_Q_WAIT, 0))
Florin Coras54693d22018-07-17 10:46:29 -07001163 return VPPCOM_EAGAIN;
1164
Florin Coras134a9962018-08-28 11:32:04 -07001165 e = svm_msg_q_msg_data (wrk->app_event_queue, &msg);
Florin Coras54693d22018-07-17 10:46:29 -07001166 if (e->event_type != SESSION_CTRL_EVT_ACCEPTED)
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001167 {
Florin Coras54693d22018-07-17 10:46:29 -07001168 clib_warning ("discarded event: %u", e->event_type);
Florin Coras134a9962018-08-28 11:32:04 -07001169 svm_msg_q_free_msg (wrk->app_event_queue, &msg);
Florin Coras54693d22018-07-17 10:46:29 -07001170 continue;
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001171 }
Dave Barach178cf492018-11-13 16:34:13 -05001172 clib_memcpy_fast (&accepted_msg, e->data, sizeof (accepted_msg));
Florin Coras134a9962018-08-28 11:32:04 -07001173 svm_msg_q_free_msg (wrk->app_event_queue, &msg);
Florin Coras54693d22018-07-17 10:46:29 -07001174 break;
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001175 }
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001176
Florin Coras54693d22018-07-17 10:46:29 -07001177handle:
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08001178
Florin Coras134a9962018-08-28 11:32:04 -07001179 client_session_index = vcl_session_accepted_handler (wrk, &accepted_msg);
1180 listen_session = vcl_session_get (wrk, listen_session_index);
1181 client_session = vcl_session_get (wrk, client_session_index);
Dave Wallace543852a2017-08-03 02:11:34 -04001182
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001183 if (flags & O_NONBLOCK)
1184 VCL_SESS_ATTR_SET (client_session->attr, VCL_SESS_ATTR_NONBLOCK);
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001185
Florin Coras54693d22018-07-17 10:46:29 -07001186 listen_vpp_handle = listen_session->vpp_handle;
Florin Corasdc2e2512018-12-03 17:47:26 -08001187 VDBG (0, "vpp handle 0x%llx, sid %u: Got a client request! "
Florin Coras0d427d82018-06-27 03:24:07 -07001188 "vpp handle 0x%llx, sid %u, flags %d, is_nonblocking %u",
Florin Corasdc2e2512018-12-03 17:47:26 -08001189 listen_vpp_handle, listen_session_handle,
Florin Coras0d427d82018-06-27 03:24:07 -07001190 client_session->vpp_handle, client_session_index,
1191 flags, VCL_SESS_ATTR_TEST (client_session->attr,
1192 VCL_SESS_ATTR_NONBLOCK));
Dave Wallace543852a2017-08-03 02:11:34 -04001193
Dave Wallace048b1d62018-01-03 22:24:41 -05001194 if (ep)
1195 {
Florin Coras7e12d942018-06-27 14:32:43 -07001196 ep->is_ip4 = client_session->transport.is_ip4;
1197 ep->port = client_session->transport.rmt_port;
1198 if (client_session->transport.is_ip4)
Dave Barach178cf492018-11-13 16:34:13 -05001199 clib_memcpy_fast (ep->ip, &client_session->transport.rmt_ip.ip4,
1200 sizeof (ip4_address_t));
Dave Wallace048b1d62018-01-03 22:24:41 -05001201 else
Dave Barach178cf492018-11-13 16:34:13 -05001202 clib_memcpy_fast (ep->ip, &client_session->transport.rmt_ip.ip6,
1203 sizeof (ip6_address_t));
Dave Wallace048b1d62018-01-03 22:24:41 -05001204 }
Dave Wallace60caa062017-11-10 17:07:13 -05001205
Florin Coras54693d22018-07-17 10:46:29 -07001206 if (accepted_msg.server_event_queue_address)
1207 vpp_evt_q = uword_to_pointer (accepted_msg.vpp_event_queue_address,
1208 svm_msg_q_t *);
1209 else
1210 vpp_evt_q = client_session->vpp_evt_q;
Florin Coras99368312018-08-02 10:45:44 -07001211
Florin Coras54693d22018-07-17 10:46:29 -07001212 vcl_send_session_accepted_reply (vpp_evt_q, client_session->client_context,
1213 client_session->vpp_handle, 0);
Dave Wallace60caa062017-11-10 17:07:13 -05001214
Florin Corasdc2e2512018-12-03 17:47:26 -08001215 VDBG (0, "vpp handle 0x%llx, sid %u: accepted vpp handle 0x%llx, "
Florin Coras54693d22018-07-17 10:46:29 -07001216 "sid %u connection from peer %s address %U port %u to local %s "
Florin Corasdc2e2512018-12-03 17:47:26 -08001217 "address %U port %u", listen_vpp_handle,
Florin Coras134a9962018-08-28 11:32:04 -07001218 listen_session_handle, client_session->vpp_handle,
Florin Coras0d427d82018-06-27 03:24:07 -07001219 client_session_index,
Florin Coras7e12d942018-06-27 14:32:43 -07001220 client_session->transport.is_ip4 ? "IPv4" : "IPv6",
1221 format_ip46_address, &client_session->transport.rmt_ip,
Florin Coras54693d22018-07-17 10:46:29 -07001222 client_session->transport.is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6,
Florin Coras7e12d942018-06-27 14:32:43 -07001223 clib_net_to_host_u16 (client_session->transport.rmt_port),
1224 client_session->transport.is_ip4 ? "IPv4" : "IPv6",
1225 format_ip46_address, &client_session->transport.lcl_ip,
Florin Coras54693d22018-07-17 10:46:29 -07001226 client_session->transport.is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6,
Florin Coras7e12d942018-06-27 14:32:43 -07001227 clib_net_to_host_u16 (client_session->transport.lcl_port));
Florin Coras0d427d82018-06-27 03:24:07 -07001228 vcl_evt (VCL_EVT_ACCEPT, client_session, listen_session,
1229 client_session_index);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001230
Florin Corasab2f6db2018-08-31 14:31:41 -07001231 return vcl_session_handle (client_session);
Dave Wallace543852a2017-08-03 02:11:34 -04001232}
1233
1234int
Florin Coras134a9962018-08-28 11:32:04 -07001235vppcom_session_connect (uint32_t session_handle, vppcom_endpt_t * server_ep)
Dave Wallace543852a2017-08-03 02:11:34 -04001236{
Florin Coras134a9962018-08-28 11:32:04 -07001237 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras7e12d942018-06-27 14:32:43 -07001238 vcl_session_t *session = 0;
Florin Coras134a9962018-08-28 11:32:04 -07001239 u32 session_index;
Florin Coras070453d2018-08-24 17:04:27 -07001240 int rv;
Dave Wallace543852a2017-08-03 02:11:34 -04001241
Florin Coras134a9962018-08-28 11:32:04 -07001242 session = vcl_session_get_w_handle (wrk, session_handle);
Florin Coras070453d2018-08-24 17:04:27 -07001243 if (!session)
1244 return VPPCOM_EBADFD;
Florin Coras134a9962018-08-28 11:32:04 -07001245 session_index = session->session_index;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001246
1247 if (PREDICT_FALSE (session->is_vep))
Dave Wallace543852a2017-08-03 02:11:34 -04001248 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001249 clib_warning ("VCL<%d>: ERROR: sid %u: cannot "
Florin Coras134a9962018-08-28 11:32:04 -07001250 "connect on an epoll session!", getpid (),
1251 session_handle);
Florin Coras070453d2018-08-24 17:04:27 -07001252 return VPPCOM_EBADFD;
Dave Wallace543852a2017-08-03 02:11:34 -04001253 }
1254
Florin Coras7e12d942018-06-27 14:32:43 -07001255 if (PREDICT_FALSE (session->session_state & CLIENT_STATE_OPEN))
Dave Wallace543852a2017-08-03 02:11:34 -04001256 {
Florin Coras0d427d82018-06-27 03:24:07 -07001257 VDBG (0, "VCL<%d>: vpp handle 0x%llx, sid %u: session already "
1258 "connected to %s %U port %d proto %s, state 0x%x (%s)",
Florin Coras134a9962018-08-28 11:32:04 -07001259 getpid (), session->vpp_handle, session_handle,
Florin Coras7e12d942018-06-27 14:32:43 -07001260 session->transport.is_ip4 ? "IPv4" : "IPv6",
Florin Coras0d427d82018-06-27 03:24:07 -07001261 format_ip46_address,
Florin Coras7e12d942018-06-27 14:32:43 -07001262 &session->transport.rmt_ip, session->transport.is_ip4 ?
Florin Coras0d427d82018-06-27 03:24:07 -07001263 IP46_TYPE_IP4 : IP46_TYPE_IP6,
Florin Coras7e12d942018-06-27 14:32:43 -07001264 clib_net_to_host_u16 (session->transport.rmt_port),
1265 session->session_type ? "UDP" : "TCP", session->session_state,
1266 vppcom_session_state_str (session->session_state));
Florin Coras070453d2018-08-24 17:04:27 -07001267 return VPPCOM_OK;
Dave Wallace543852a2017-08-03 02:11:34 -04001268 }
1269
Florin Coras7e12d942018-06-27 14:32:43 -07001270 session->transport.is_ip4 = server_ep->is_ip4;
1271 if (session->transport.is_ip4)
Dave Barach178cf492018-11-13 16:34:13 -05001272 clib_memcpy_fast (&session->transport.rmt_ip.ip4, server_ep->ip,
1273 sizeof (ip4_address_t));
Dave Wallaced239f8d2018-06-19 13:37:30 -04001274 else
Dave Barach178cf492018-11-13 16:34:13 -05001275 clib_memcpy_fast (&session->transport.rmt_ip.ip6, server_ep->ip,
1276 sizeof (ip6_address_t));
Florin Coras7e12d942018-06-27 14:32:43 -07001277 session->transport.rmt_port = server_ep->port;
Dave Wallace543852a2017-08-03 02:11:34 -04001278
Florin Coras0d427d82018-06-27 03:24:07 -07001279 VDBG (0, "VCL<%d>: vpp handle 0x%llx, sid %u: connecting to server %s %U "
1280 "port %d proto %s",
Florin Coras134a9962018-08-28 11:32:04 -07001281 getpid (), session->vpp_handle, session_handle,
Florin Coras7e12d942018-06-27 14:32:43 -07001282 session->transport.is_ip4 ? "IPv4" : "IPv6",
Florin Coras0d427d82018-06-27 03:24:07 -07001283 format_ip46_address,
Florin Coras7e12d942018-06-27 14:32:43 -07001284 &session->transport.rmt_ip, session->transport.is_ip4 ?
Florin Coras0d427d82018-06-27 03:24:07 -07001285 IP46_TYPE_IP4 : IP46_TYPE_IP6,
Florin Coras7e12d942018-06-27 14:32:43 -07001286 clib_net_to_host_u16 (session->transport.rmt_port),
1287 session->session_type ? "UDP" : "TCP");
Dave Wallace543852a2017-08-03 02:11:34 -04001288
Florin Coras070453d2018-08-24 17:04:27 -07001289 /*
1290 * Send connect request and wait for reply from vpp
1291 */
Florin Coras134a9962018-08-28 11:32:04 -07001292 vppcom_send_connect_sock (session);
Florin Coras070453d2018-08-24 17:04:27 -07001293 rv = vppcom_wait_for_session_state_change (session_index, STATE_CONNECT,
1294 vcm->cfg.session_timeout);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001295
Florin Coras134a9962018-08-28 11:32:04 -07001296 session = vcl_session_get (wrk, session_index);
Dave Wallace7876d392017-10-19 03:53:57 -04001297
Florin Coras070453d2018-08-24 17:04:27 -07001298 if (PREDICT_FALSE (rv))
Dave Wallaceee45d412017-11-24 21:44:06 -05001299 {
Dave Wallaceee45d412017-11-24 21:44:06 -05001300 if (VPPCOM_DEBUG > 0)
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001301 {
1302 if (session)
Florin Coras0d427d82018-06-27 03:24:07 -07001303 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: connect "
Florin Coras134a9962018-08-28 11:32:04 -07001304 "failed! returning %d (%s)", getpid (),
1305 session->vpp_handle, session_handle, rv,
1306 vppcom_retval_str (rv));
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001307 else
1308 clib_warning ("VCL<%d>: no session for sid %u: connect failed! "
1309 "returning %d (%s)", getpid (),
Florin Coras134a9962018-08-28 11:32:04 -07001310 session_handle, rv, vppcom_retval_str (rv));
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001311 }
Dave Wallaceee45d412017-11-24 21:44:06 -05001312 }
Florin Coras0d427d82018-06-27 03:24:07 -07001313 else
1314 VDBG (0, "VCL<%d>: vpp handle 0x%llx, sid %u: connected!",
Florin Coras134a9962018-08-28 11:32:04 -07001315 getpid (), session->vpp_handle, session_handle);
Dave Wallaceee45d412017-11-24 21:44:06 -05001316
Dave Wallace4878cbe2017-11-21 03:45:09 -05001317 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04001318}
1319
Florin Coras54693d22018-07-17 10:46:29 -07001320static u8
1321vcl_is_rx_evt_for_session (session_event_t * e, u32 sid, u8 is_ct)
1322{
1323 if (!is_ct)
1324 return (e->event_type == FIFO_EVENT_APP_RX
1325 && e->fifo->client_session_index == sid);
1326 else
1327 return (e->event_type == SESSION_IO_EVT_CT_TX);
1328}
1329
Florin Coras460dce62018-07-27 05:45:06 -07001330static inline u8
1331vcl_session_is_readable (vcl_session_t * s)
1332{
1333 return ((s->session_state & STATE_OPEN)
1334 || (s->session_state == STATE_LISTEN
1335 && s->session_type == VPPCOM_PROTO_UDP));
1336}
1337
Steven58f464e2017-10-25 12:33:12 -07001338static inline int
Florin Coras134a9962018-08-28 11:32:04 -07001339vppcom_session_read_internal (uint32_t session_handle, void *buf, int n,
Steven58f464e2017-10-25 12:33:12 -07001340 u8 peek)
Dave Wallace543852a2017-08-03 02:11:34 -04001341{
Florin Coras134a9962018-08-28 11:32:04 -07001342 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras54693d22018-07-17 10:46:29 -07001343 int n_read = 0, rv, is_nonblocking;
Florin Coras460dce62018-07-27 05:45:06 -07001344 vcl_session_t *s = 0;
Dave Wallace543852a2017-08-03 02:11:34 -04001345 svm_fifo_t *rx_fifo;
Florin Coras54693d22018-07-17 10:46:29 -07001346 svm_msg_q_msg_t msg;
1347 session_event_t *e;
1348 svm_msg_q_t *mq;
Florin Coras41c9e042018-09-11 00:10:41 -07001349 u8 is_ct;
Dave Wallace543852a2017-08-03 02:11:34 -04001350
Florin Coras070453d2018-08-24 17:04:27 -07001351 if (PREDICT_FALSE (!buf))
1352 return VPPCOM_EINVAL;
Dave Wallace543852a2017-08-03 02:11:34 -04001353
Florin Coras134a9962018-08-28 11:32:04 -07001354 s = vcl_session_get_w_handle (wrk, session_handle);
Florin Coras2cba8532018-09-11 16:33:36 -07001355 if (PREDICT_FALSE (!s || s->is_vep))
Florin Coras070453d2018-08-24 17:04:27 -07001356 return VPPCOM_EBADFD;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001357
Florin Coras460dce62018-07-27 05:45:06 -07001358 if (PREDICT_FALSE (!vcl_session_is_readable (s)))
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001359 {
Florin Coras460dce62018-07-27 05:45:06 -07001360 session_state_t state = s->session_state;
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08001361 rv = ((state & STATE_DISCONNECT) ? VPPCOM_ECONNRESET : VPPCOM_ENOTCONN);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001362
Florin Coras0d427d82018-06-27 03:24:07 -07001363 VDBG (0, "VCL<%d>: vpp handle 0x%llx, sid %u: %s session is not open! "
1364 "state 0x%x (%s), returning %d (%s)",
Florin Coras134a9962018-08-28 11:32:04 -07001365 getpid (), s->vpp_handle, session_handle, state,
Florin Coras0d427d82018-06-27 03:24:07 -07001366 vppcom_session_state_str (state), rv, vppcom_retval_str (rv));
Florin Coras070453d2018-08-24 17:04:27 -07001367 return rv;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001368 }
1369
Florin Coras2cba8532018-09-11 16:33:36 -07001370 is_nonblocking = VCL_SESS_ATTR_TEST (s->attr, VCL_SESS_ATTR_NONBLOCK);
Florin Coras41c9e042018-09-11 00:10:41 -07001371 is_ct = vcl_session_is_ct (s);
1372 mq = is_ct ? s->our_evt_q : wrk->app_event_queue;
Florin Coras2cba8532018-09-11 16:33:36 -07001373 rx_fifo = s->rx_fifo;
Florin Corasaa27eb92018-10-13 12:20:01 -07001374 s->has_rx_evt = 0;
Dave Wallacef7f809c2017-10-03 01:48:42 -04001375
Florin Coras54693d22018-07-17 10:46:29 -07001376 if (svm_fifo_is_empty (rx_fifo))
Dave Wallacef7f809c2017-10-03 01:48:42 -04001377 {
Florin Coras54693d22018-07-17 10:46:29 -07001378 if (is_nonblocking)
Dave Wallace4878cbe2017-11-21 03:45:09 -05001379 {
Florin Coras41c9e042018-09-11 00:10:41 -07001380 svm_fifo_unset_event (rx_fifo);
Florin Corasaa27eb92018-10-13 12:20:01 -07001381 return VPPCOM_EWOULDBLOCK;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001382 }
Florin Coras41c9e042018-09-11 00:10:41 -07001383 while (svm_fifo_is_empty (rx_fifo))
Florin Coras54693d22018-07-17 10:46:29 -07001384 {
Florin Coras41c9e042018-09-11 00:10:41 -07001385 svm_fifo_unset_event (rx_fifo);
Florin Coras99368312018-08-02 10:45:44 -07001386 svm_msg_q_lock (mq);
Florin Coras54693d22018-07-17 10:46:29 -07001387 if (svm_msg_q_is_empty (mq))
1388 svm_msg_q_wait (mq);
Florin Coras99368312018-08-02 10:45:44 -07001389
Florin Coras54693d22018-07-17 10:46:29 -07001390 svm_msg_q_sub_w_lock (mq, &msg);
1391 e = svm_msg_q_msg_data (mq, &msg);
Florin Coras99368312018-08-02 10:45:44 -07001392 svm_msg_q_unlock (mq);
Florin Coras41c9e042018-09-11 00:10:41 -07001393 if (!vcl_is_rx_evt_for_session (e, s->session_index, is_ct))
Florin Coras54693d22018-07-17 10:46:29 -07001394 {
Florin Coras86f04502018-09-12 16:08:01 -07001395 vcl_handle_mq_event (wrk, e);
Florin Coras54693d22018-07-17 10:46:29 -07001396 svm_msg_q_free_msg (mq, &msg);
1397 continue;
1398 }
Florin Coras54693d22018-07-17 10:46:29 -07001399 svm_msg_q_free_msg (mq, &msg);
Florin Coras41c9e042018-09-11 00:10:41 -07001400
Florin Coras60f1fc12018-08-16 14:57:31 -07001401 if (PREDICT_FALSE (s->session_state == STATE_CLOSE_ON_EMPTY))
1402 return 0;
Florin Coras54693d22018-07-17 10:46:29 -07001403 }
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001404 }
Florin Coras54693d22018-07-17 10:46:29 -07001405
Florin Coras460dce62018-07-27 05:45:06 -07001406 if (s->is_dgram)
Florin Coras99368312018-08-02 10:45:44 -07001407 n_read = app_recv_dgram_raw (rx_fifo, buf, n, &s->transport, 0, peek);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001408 else
Florin Coras99368312018-08-02 10:45:44 -07001409 n_read = app_recv_stream_raw (rx_fifo, buf, n, 0, peek);
Florin Coras54693d22018-07-17 10:46:29 -07001410
Florin Coras41c9e042018-09-11 00:10:41 -07001411 if (svm_fifo_is_empty (rx_fifo))
1412 svm_fifo_unset_event (rx_fifo);
1413
Florin Coras58c101a2018-10-06 13:49:16 -07001414 if (is_ct && svm_fifo_want_tx_evt (rx_fifo))
Florin Coras99368312018-08-02 10:45:44 -07001415 {
Florin Coras58c101a2018-10-06 13:49:16 -07001416 svm_fifo_set_want_tx_evt (s->rx_fifo, 0);
1417 app_send_io_evt_to_vpp (s->vpp_evt_q, s->rx_fifo, SESSION_IO_EVT_CT_RX,
1418 SVM_Q_WAIT);
Florin Coras99368312018-08-02 10:45:44 -07001419 }
Florin Coras54693d22018-07-17 10:46:29 -07001420
Florin Coras2cba8532018-09-11 16:33:36 -07001421 VDBG (2, "VCL<%d>: vpp handle 0x%llx, sid %u: read %d bytes from (%p)",
1422 getpid (), s->vpp_handle, session_handle, n_read, rx_fifo);
1423
Florin Coras54693d22018-07-17 10:46:29 -07001424 return n_read;
Dave Wallace543852a2017-08-03 02:11:34 -04001425}
1426
Steven58f464e2017-10-25 12:33:12 -07001427int
Florin Coras134a9962018-08-28 11:32:04 -07001428vppcom_session_read (uint32_t session_handle, void *buf, size_t n)
Steven58f464e2017-10-25 12:33:12 -07001429{
Florin Coras134a9962018-08-28 11:32:04 -07001430 return (vppcom_session_read_internal (session_handle, buf, n, 0));
Steven58f464e2017-10-25 12:33:12 -07001431}
1432
1433static int
Florin Coras134a9962018-08-28 11:32:04 -07001434vppcom_session_peek (uint32_t session_handle, void *buf, int n)
Steven58f464e2017-10-25 12:33:12 -07001435{
Florin Coras134a9962018-08-28 11:32:04 -07001436 return (vppcom_session_read_internal (session_handle, buf, n, 1));
Steven58f464e2017-10-25 12:33:12 -07001437}
1438
Florin Coras2cba8532018-09-11 16:33:36 -07001439int
1440vppcom_session_read_segments (uint32_t session_handle,
1441 vppcom_data_segments_t ds)
1442{
1443 vcl_worker_t *wrk = vcl_worker_get_current ();
1444 int n_read = 0, rv, is_nonblocking;
1445 vcl_session_t *s = 0;
1446 svm_fifo_t *rx_fifo;
1447 svm_msg_q_msg_t msg;
1448 session_event_t *e;
1449 svm_msg_q_t *mq;
1450 u8 is_ct;
1451
1452 s = vcl_session_get_w_handle (wrk, session_handle);
1453 if (PREDICT_FALSE (!s || s->is_vep))
1454 return VPPCOM_EBADFD;
1455
1456 if (PREDICT_FALSE (!vcl_session_is_readable (s)))
1457 {
1458 session_state_t state = s->session_state;
1459 rv = ((state & STATE_DISCONNECT) ? VPPCOM_ECONNRESET : VPPCOM_ENOTCONN);
1460 return rv;
1461 }
1462
1463 is_nonblocking = VCL_SESS_ATTR_TEST (s->attr, VCL_SESS_ATTR_NONBLOCK);
1464 is_ct = vcl_session_is_ct (s);
1465 mq = is_ct ? s->our_evt_q : wrk->app_event_queue;
1466 rx_fifo = s->rx_fifo;
Florin Corasaa27eb92018-10-13 12:20:01 -07001467 s->has_rx_evt = 0;
Florin Coras2cba8532018-09-11 16:33:36 -07001468
1469 if (svm_fifo_is_empty (rx_fifo))
1470 {
1471 if (is_nonblocking)
1472 {
1473 svm_fifo_unset_event (rx_fifo);
Florin Corasaa27eb92018-10-13 12:20:01 -07001474 return VPPCOM_EWOULDBLOCK;
Florin Coras2cba8532018-09-11 16:33:36 -07001475 }
1476 while (svm_fifo_is_empty (rx_fifo))
1477 {
1478 svm_fifo_unset_event (rx_fifo);
1479 svm_msg_q_lock (mq);
1480 if (svm_msg_q_is_empty (mq))
1481 svm_msg_q_wait (mq);
1482
1483 svm_msg_q_sub_w_lock (mq, &msg);
1484 e = svm_msg_q_msg_data (mq, &msg);
1485 svm_msg_q_unlock (mq);
1486 if (!vcl_is_rx_evt_for_session (e, s->session_index, is_ct))
1487 {
Florin Coras86f04502018-09-12 16:08:01 -07001488 vcl_handle_mq_event (wrk, e);
Florin Coras2cba8532018-09-11 16:33:36 -07001489 svm_msg_q_free_msg (mq, &msg);
1490 continue;
1491 }
1492 svm_msg_q_free_msg (mq, &msg);
1493
1494 if (PREDICT_FALSE (s->session_state == STATE_CLOSE_ON_EMPTY))
1495 return 0;
1496 }
1497 }
1498
1499 n_read = svm_fifo_segments (rx_fifo, (svm_fifo_segment_t *) ds);
1500 svm_fifo_unset_event (rx_fifo);
1501
1502 if (is_ct && n_read + svm_fifo_max_dequeue (rx_fifo) == rx_fifo->nitems)
1503 {
1504 /* If the peer is not polling send notification */
1505 if (!svm_fifo_has_event (s->rx_fifo))
1506 app_send_io_evt_to_vpp (s->vpp_evt_q, s->rx_fifo,
1507 SESSION_IO_EVT_CT_RX, SVM_Q_WAIT);
1508 }
1509
1510 return n_read;
1511}
1512
1513void
1514vppcom_session_free_segments (uint32_t session_handle,
1515 vppcom_data_segments_t ds)
1516{
1517 vcl_worker_t *wrk = vcl_worker_get_current ();
1518 vcl_session_t *s;
1519
1520 s = vcl_session_get_w_handle (wrk, session_handle);
1521 if (PREDICT_FALSE (!s || s->is_vep))
1522 return;
1523
1524 svm_fifo_segments_free (s->rx_fifo, (svm_fifo_segment_t *) ds);
1525}
1526
Dave Wallace543852a2017-08-03 02:11:34 -04001527static inline int
Florin Coras54693d22018-07-17 10:46:29 -07001528vppcom_session_read_ready (vcl_session_t * session)
Dave Wallace543852a2017-08-03 02:11:34 -04001529{
Dave Wallace543852a2017-08-03 02:11:34 -04001530 /* Assumes caller has acquired spinlock: vcm->sessions_lockp */
Dave Wallace4878cbe2017-11-21 03:45:09 -05001531 if (PREDICT_FALSE (session->is_vep))
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001532 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001533 clib_warning ("VCL<%d>: ERROR: sid %u: cannot read from an "
Florin Coras134a9962018-08-28 11:32:04 -07001534 "epoll session!", getpid (), session->session_index);
Florin Coras54693d22018-07-17 10:46:29 -07001535 return VPPCOM_EBADFD;
1536 }
1537
1538 if (PREDICT_FALSE (!(session->session_state & (STATE_OPEN | STATE_LISTEN))))
1539 {
1540 session_state_t state = session->session_state;
1541 int rv;
1542
1543 rv = ((state & STATE_DISCONNECT) ? VPPCOM_ECONNRESET : VPPCOM_ENOTCONN);
1544
1545 VDBG (1, "VCL<%d>: vpp handle 0x%llx, sid %u: session is not open!"
1546 " state 0x%x (%s), returning %d (%s)", getpid (),
Florin Coras134a9962018-08-28 11:32:04 -07001547 session->vpp_handle, session->session_index, state,
Florin Coras54693d22018-07-17 10:46:29 -07001548 vppcom_session_state_str (state), rv, vppcom_retval_str (rv));
1549 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04001550 }
Dave Wallace33e002b2017-09-06 01:20:02 -04001551
Florin Coras7e12d942018-06-27 14:32:43 -07001552 if (session->session_state & STATE_LISTEN)
Florin Coras54693d22018-07-17 10:46:29 -07001553 return clib_fifo_elts (session->accept_evts_fifo);
1554
1555 return svm_fifo_max_dequeue (session->rx_fifo);
1556}
1557
Florin Coras2cba8532018-09-11 16:33:36 -07001558int
1559vppcom_data_segment_copy (void *buf, vppcom_data_segments_t ds, u32 max_bytes)
1560{
1561 u32 first_copy = clib_min (ds[0].len, max_bytes);
Dave Barach178cf492018-11-13 16:34:13 -05001562 clib_memcpy_fast (buf, ds[0].data, first_copy);
Florin Coras2cba8532018-09-11 16:33:36 -07001563 if (first_copy < max_bytes)
1564 {
Dave Barach178cf492018-11-13 16:34:13 -05001565 clib_memcpy_fast (buf + first_copy, ds[1].data,
1566 clib_min (ds[1].len, max_bytes - first_copy));
Florin Coras2cba8532018-09-11 16:33:36 -07001567 }
1568 return 0;
1569}
1570
Florin Coras54693d22018-07-17 10:46:29 -07001571static u8
1572vcl_is_tx_evt_for_session (session_event_t * e, u32 sid, u8 is_ct)
1573{
1574 if (!is_ct)
1575 return (e->event_type == FIFO_EVENT_APP_TX
1576 && e->fifo->client_session_index == sid);
Dave Wallace543852a2017-08-03 02:11:34 -04001577 else
Florin Coras54693d22018-07-17 10:46:29 -07001578 return (e->event_type == SESSION_IO_EVT_CT_RX);
Dave Wallace543852a2017-08-03 02:11:34 -04001579}
1580
1581int
Florin Coras134a9962018-08-28 11:32:04 -07001582vppcom_session_write (uint32_t session_handle, void *buf, size_t n)
Dave Wallace543852a2017-08-03 02:11:34 -04001583{
Florin Coras134a9962018-08-28 11:32:04 -07001584 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras54693d22018-07-17 10:46:29 -07001585 int rv, n_write, is_nonblocking;
Florin Coras460dce62018-07-27 05:45:06 -07001586 vcl_session_t *s = 0;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001587 svm_fifo_t *tx_fifo = 0;
Florin Coras460dce62018-07-27 05:45:06 -07001588 session_evt_type_t et;
Florin Coras54693d22018-07-17 10:46:29 -07001589 svm_msg_q_msg_t msg;
1590 session_event_t *e;
Florin Coras3c2fed52018-07-04 04:15:05 -07001591 svm_msg_q_t *mq;
Florin Coras0e88e852018-09-17 22:09:02 -07001592 u8 is_ct;
Dave Wallace543852a2017-08-03 02:11:34 -04001593
Florin Coras070453d2018-08-24 17:04:27 -07001594 if (PREDICT_FALSE (!buf))
1595 return VPPCOM_EINVAL;
Dave Wallace543852a2017-08-03 02:11:34 -04001596
Florin Coras134a9962018-08-28 11:32:04 -07001597 s = vcl_session_get_w_handle (wrk, session_handle);
Florin Coras070453d2018-08-24 17:04:27 -07001598 if (PREDICT_FALSE (!s))
1599 return VPPCOM_EBADFD;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001600
Florin Coras460dce62018-07-27 05:45:06 -07001601 if (PREDICT_FALSE (s->is_vep))
Dave Wallace543852a2017-08-03 02:11:34 -04001602 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001603 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -05001604 "cannot write to an epoll session!",
Florin Coras134a9962018-08-28 11:32:04 -07001605 getpid (), s->vpp_handle, session_handle);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001606
Florin Coras070453d2018-08-24 17:04:27 -07001607 return VPPCOM_EBADFD;
Dave Wallace543852a2017-08-03 02:11:34 -04001608 }
1609
Florin Coras0e88e852018-09-17 22:09:02 -07001610 if (PREDICT_FALSE (!(s->session_state & STATE_OPEN)))
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001611 {
Florin Coras460dce62018-07-27 05:45:06 -07001612 session_state_t state = s->session_state;
Florin Coras54693d22018-07-17 10:46:29 -07001613 rv = ((state & STATE_DISCONNECT) ? VPPCOM_ECONNRESET : VPPCOM_ENOTCONN);
Florin Coras0d427d82018-06-27 03:24:07 -07001614 VDBG (1, "VCL<%d>: vpp handle 0x%llx, sid %u: session is not open! "
Florin Coras0e88e852018-09-17 22:09:02 -07001615 "state 0x%x (%s)", getpid (), s->vpp_handle, session_handle,
Florin Coras0d427d82018-06-27 03:24:07 -07001616 state, vppcom_session_state_str (state));
Florin Coras070453d2018-08-24 17:04:27 -07001617 return rv;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001618 }
1619
Florin Coras0e88e852018-09-17 22:09:02 -07001620 tx_fifo = s->tx_fifo;
1621 is_ct = vcl_session_is_ct (s);
1622 is_nonblocking = VCL_SESS_ATTR_TEST (s->attr, VCL_SESS_ATTR_NONBLOCK);
1623 mq = is_ct ? s->our_evt_q : wrk->app_event_queue;
Florin Coras54693d22018-07-17 10:46:29 -07001624 if (svm_fifo_is_full (tx_fifo))
Dave Wallace543852a2017-08-03 02:11:34 -04001625 {
Florin Coras54693d22018-07-17 10:46:29 -07001626 if (is_nonblocking)
1627 {
Florin Coras070453d2018-08-24 17:04:27 -07001628 return VPPCOM_EWOULDBLOCK;
Florin Coras54693d22018-07-17 10:46:29 -07001629 }
Florin Coras60f1fc12018-08-16 14:57:31 -07001630 while (svm_fifo_is_full (tx_fifo))
Florin Coras54693d22018-07-17 10:46:29 -07001631 {
Florin Coras0e88e852018-09-17 22:09:02 -07001632 svm_fifo_set_want_tx_evt (tx_fifo, 1);
Florin Coras99368312018-08-02 10:45:44 -07001633 svm_msg_q_lock (mq);
Florin Corasaa27eb92018-10-13 12:20:01 -07001634 if (svm_msg_q_is_empty (mq))
1635 svm_msg_q_wait (mq);
Florin Coras0e88e852018-09-17 22:09:02 -07001636
Florin Coras54693d22018-07-17 10:46:29 -07001637 svm_msg_q_sub_w_lock (mq, &msg);
1638 e = svm_msg_q_msg_data (mq, &msg);
Florin Coras99368312018-08-02 10:45:44 -07001639 svm_msg_q_unlock (mq);
1640
Florin Coras0e88e852018-09-17 22:09:02 -07001641 if (!vcl_is_tx_evt_for_session (e, s->session_index, is_ct))
Florin Coras86f04502018-09-12 16:08:01 -07001642 vcl_handle_mq_event (wrk, e);
Florin Coras54693d22018-07-17 10:46:29 -07001643 svm_msg_q_free_msg (mq, &msg);
Florin Coras54693d22018-07-17 10:46:29 -07001644 }
Dave Wallace543852a2017-08-03 02:11:34 -04001645 }
Dave Wallace543852a2017-08-03 02:11:34 -04001646
Florin Coras460dce62018-07-27 05:45:06 -07001647 ASSERT (FIFO_EVENT_APP_TX + 1 == SESSION_IO_EVT_CT_TX);
1648 et = FIFO_EVENT_APP_TX + vcl_session_is_ct (s);
1649 if (s->is_dgram)
1650 n_write = app_send_dgram_raw (tx_fifo, &s->transport,
1651 s->vpp_evt_q, buf, n, et, SVM_Q_WAIT);
1652 else
1653 n_write = app_send_stream_raw (tx_fifo, s->vpp_evt_q, buf, n, et,
1654 SVM_Q_WAIT);
Keith Burns (alagalah)410bcca2018-03-23 13:42:49 -07001655
Florin Coras460dce62018-07-27 05:45:06 -07001656 ASSERT (n_write > 0);
Dave Wallace543852a2017-08-03 02:11:34 -04001657
Florin Coras0e88e852018-09-17 22:09:02 -07001658 VDBG (2, "VCL<%d>: vpp handle 0x%llx, sid %u: wrote %d bytes", getpid (),
1659 s->vpp_handle, session_handle, n_write);
1660
Florin Coras54693d22018-07-17 10:46:29 -07001661 return n_write;
Dave Wallace543852a2017-08-03 02:11:34 -04001662}
1663
Florin Coras99368312018-08-02 10:45:44 -07001664static vcl_session_t *
Florin Coras134a9962018-08-28 11:32:04 -07001665vcl_ct_session_get_from_fifo (vcl_worker_t * wrk, svm_fifo_t * f, u8 type)
Florin Coras99368312018-08-02 10:45:44 -07001666{
1667 vcl_session_t *s;
Florin Coras134a9962018-08-28 11:32:04 -07001668 s = vcl_session_get (wrk, f->client_session_index);
Florin Coras99368312018-08-02 10:45:44 -07001669 if (s)
1670 {
1671 /* rx fifo */
1672 if (type == 0 && s->rx_fifo == f)
1673 return s;
1674 /* tx fifo */
1675 if (type == 1 && s->tx_fifo == f)
1676 return s;
1677 }
Florin Coras134a9962018-08-28 11:32:04 -07001678 s = vcl_session_get (wrk, f->master_session_index);
Florin Coras99368312018-08-02 10:45:44 -07001679 if (s)
1680 {
1681 if (type == 0 && s->rx_fifo == f)
1682 return s;
1683 if (type == 1 && s->tx_fifo == f)
1684 return s;
1685 }
1686 return 0;
1687}
1688
Dave Wallace543852a2017-08-03 02:11:34 -04001689static inline int
Florin Coras134a9962018-08-28 11:32:04 -07001690vppcom_session_write_ready (vcl_session_t * session)
Dave Wallace543852a2017-08-03 02:11:34 -04001691{
Dave Wallace543852a2017-08-03 02:11:34 -04001692 /* Assumes caller has acquired spinlock: vcm->sessions_lockp */
Dave Wallace4878cbe2017-11-21 03:45:09 -05001693 if (PREDICT_FALSE (session->is_vep))
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001694 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001695 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -05001696 "cannot write to an epoll session!",
Florin Coras134a9962018-08-28 11:32:04 -07001697 getpid (), session->vpp_handle, session->session_index);
Florin Coras54693d22018-07-17 10:46:29 -07001698 return VPPCOM_EBADFD;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001699 }
1700
Florin Coras7e12d942018-06-27 14:32:43 -07001701 if (PREDICT_FALSE (session->session_state & STATE_LISTEN))
Dave Wallace33e002b2017-09-06 01:20:02 -04001702 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001703 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -05001704 "cannot write to a listen session!",
Florin Coras134a9962018-08-28 11:32:04 -07001705 getpid (), session->vpp_handle, session->session_index);
Florin Coras54693d22018-07-17 10:46:29 -07001706 return VPPCOM_EBADFD;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001707 }
1708
Florin Coras54693d22018-07-17 10:46:29 -07001709 if (PREDICT_FALSE (!(session->session_state & STATE_OPEN)))
Dave Wallace4878cbe2017-11-21 03:45:09 -05001710 {
Florin Coras7e12d942018-06-27 14:32:43 -07001711 session_state_t state = session->session_state;
Florin Coras54693d22018-07-17 10:46:29 -07001712 int rv;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001713
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08001714 rv = ((state & STATE_DISCONNECT) ? VPPCOM_ECONNRESET : VPPCOM_ENOTCONN);
Dave Wallace048b1d62018-01-03 22:24:41 -05001715 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001716 "session is not open! state 0x%x (%s), "
Dave Wallaceee45d412017-11-24 21:44:06 -05001717 "returning %d (%s)", getpid (), session->vpp_handle,
Florin Coras134a9962018-08-28 11:32:04 -07001718 session->session_index,
Dave Wallace4878cbe2017-11-21 03:45:09 -05001719 state, vppcom_session_state_str (state),
1720 rv, vppcom_retval_str (rv));
Florin Coras54693d22018-07-17 10:46:29 -07001721 return rv;
Dave Wallace33e002b2017-09-06 01:20:02 -04001722 }
1723
Florin Coras0d427d82018-06-27 03:24:07 -07001724 VDBG (3, "VCL<%d>: vpp handle 0x%llx, sid %u: peek %s (%p), ready = %d",
Florin Coras134a9962018-08-28 11:32:04 -07001725 getpid (), session->vpp_handle, session->session_index,
1726 session->tx_fifo, svm_fifo_max_enqueue (session->tx_fifo));
Dave Wallacef7f809c2017-10-03 01:48:42 -04001727
Florin Coras54693d22018-07-17 10:46:29 -07001728 return svm_fifo_max_enqueue (session->tx_fifo);
1729}
1730
Florin Coras99368312018-08-02 10:45:44 -07001731static inline int
Florin Coras134a9962018-08-28 11:32:04 -07001732vcl_mq_dequeue_batch (vcl_worker_t * wrk, svm_msg_q_t * mq)
Florin Coras99368312018-08-02 10:45:44 -07001733{
1734 svm_msg_q_msg_t *msg;
1735 u32 n_msgs;
1736 int i;
1737
1738 n_msgs = svm_msg_q_size (mq);
1739 for (i = 0; i < n_msgs; i++)
1740 {
Florin Coras134a9962018-08-28 11:32:04 -07001741 vec_add2 (wrk->mq_msg_vector, msg, 1);
Florin Coras99368312018-08-02 10:45:44 -07001742 svm_msg_q_sub_w_lock (mq, msg);
1743 }
1744 return n_msgs;
1745}
1746
Florin Coras6d4bb422018-09-04 22:07:27 -07001747#define vcl_fifo_rx_evt_valid_or_break(_fifo) \
1748if (PREDICT_FALSE (svm_fifo_is_empty (_fifo))) \
1749 { \
1750 svm_fifo_unset_event (_fifo); \
1751 if (svm_fifo_is_empty (_fifo)) \
Florin Coras41c9e042018-09-11 00:10:41 -07001752 break; \
Florin Coras6d4bb422018-09-04 22:07:27 -07001753 } \
1754
Florin Coras86f04502018-09-12 16:08:01 -07001755static void
1756vcl_select_handle_mq_event (vcl_worker_t * wrk, session_event_t * e,
1757 unsigned long n_bits, unsigned long *read_map,
1758 unsigned long *write_map,
1759 unsigned long *except_map, u32 * bits_set)
Florin Coras54693d22018-07-17 10:46:29 -07001760{
1761 session_disconnected_msg_t *disconnected_msg;
Florin Coras99368312018-08-02 10:45:44 -07001762 session_connected_msg_t *connected_msg;
Florin Coras54693d22018-07-17 10:46:29 -07001763 session_accepted_msg_t *accepted_msg;
1764 vcl_session_msg_t *vcl_msg;
1765 vcl_session_t *session;
Florin Coras86f04502018-09-12 16:08:01 -07001766 u64 handle;
1767 u32 sid;
1768
1769 switch (e->event_type)
1770 {
1771 case FIFO_EVENT_APP_RX:
1772 vcl_fifo_rx_evt_valid_or_break (e->fifo);
1773 sid = e->fifo->client_session_index;
1774 session = vcl_session_get (wrk, sid);
1775 if (!session)
1776 break;
1777 if (sid < n_bits && read_map)
1778 {
1779 clib_bitmap_set_no_check (read_map, sid, 1);
1780 *bits_set += 1;
1781 }
1782 break;
1783 case FIFO_EVENT_APP_TX:
1784 sid = e->fifo->client_session_index;
1785 session = vcl_session_get (wrk, sid);
1786 if (!session)
1787 break;
1788 if (sid < n_bits && write_map)
1789 {
1790 clib_bitmap_set_no_check (write_map, sid, 1);
1791 *bits_set += 1;
1792 }
1793 break;
1794 case SESSION_IO_EVT_CT_TX:
1795 vcl_fifo_rx_evt_valid_or_break (e->fifo);
1796 session = vcl_ct_session_get_from_fifo (wrk, e->fifo, 0);
1797 if (!session)
1798 break;
1799 sid = session->session_index;
1800 if (sid < n_bits && read_map)
1801 {
1802 clib_bitmap_set_no_check (read_map, sid, 1);
1803 *bits_set += 1;
1804 }
1805 break;
1806 case SESSION_IO_EVT_CT_RX:
1807 session = vcl_ct_session_get_from_fifo (wrk, e->fifo, 1);
1808 if (!session)
1809 break;
1810 sid = session->session_index;
1811 if (sid < n_bits && write_map)
1812 {
1813 clib_bitmap_set_no_check (write_map, sid, 1);
1814 *bits_set += 1;
1815 }
1816 break;
1817 case SESSION_CTRL_EVT_ACCEPTED:
1818 accepted_msg = (session_accepted_msg_t *) e->data;
1819 handle = accepted_msg->listener_handle;
1820 session = vcl_session_table_lookup_listener (wrk, handle);
1821 if (!session)
1822 {
1823 clib_warning ("VCL<%d>: ERROR: couldn't find listen session:"
1824 "listener handle %llx", getpid (), handle);
1825 break;
1826 }
1827
1828 clib_fifo_add2 (session->accept_evts_fifo, vcl_msg);
1829 vcl_msg->accepted_msg = *accepted_msg;
1830 sid = session->session_index;
1831 if (sid < n_bits && read_map)
1832 {
1833 clib_bitmap_set_no_check (read_map, sid, 1);
1834 *bits_set += 1;
1835 }
1836 break;
1837 case SESSION_CTRL_EVT_CONNECTED:
1838 connected_msg = (session_connected_msg_t *) e->data;
1839 vcl_session_connected_handler (wrk, connected_msg);
1840 break;
1841 case SESSION_CTRL_EVT_DISCONNECTED:
1842 disconnected_msg = (session_disconnected_msg_t *) e->data;
1843 sid = vcl_session_index_from_vpp_handle (wrk, disconnected_msg->handle);
1844 if (sid < n_bits && except_map)
1845 {
1846 clib_bitmap_set_no_check (except_map, sid, 1);
1847 *bits_set += 1;
1848 }
1849 break;
1850 case SESSION_CTRL_EVT_RESET:
1851 sid = vcl_session_reset_handler (wrk, (session_reset_msg_t *) e->data);
1852 if (sid < n_bits && except_map)
1853 {
1854 clib_bitmap_set_no_check (except_map, sid, 1);
1855 *bits_set += 1;
1856 }
1857 break;
1858 default:
1859 clib_warning ("unhandled: %u", e->event_type);
1860 break;
1861 }
1862}
1863
1864static int
1865vcl_select_handle_mq (vcl_worker_t * wrk, svm_msg_q_t * mq,
1866 unsigned long n_bits, unsigned long *read_map,
1867 unsigned long *write_map, unsigned long *except_map,
1868 double time_to_wait, u32 * bits_set)
1869{
Florin Coras99368312018-08-02 10:45:44 -07001870 svm_msg_q_msg_t *msg;
Florin Coras54693d22018-07-17 10:46:29 -07001871 session_event_t *e;
Florin Coras86f04502018-09-12 16:08:01 -07001872 u32 i;
Florin Coras54693d22018-07-17 10:46:29 -07001873
1874 svm_msg_q_lock (mq);
1875 if (svm_msg_q_is_empty (mq))
Dave Wallace4878cbe2017-11-21 03:45:09 -05001876 {
Florin Coras54693d22018-07-17 10:46:29 -07001877 if (*bits_set)
Dave Wallace4878cbe2017-11-21 03:45:09 -05001878 {
Florin Coras54693d22018-07-17 10:46:29 -07001879 svm_msg_q_unlock (mq);
1880 return 0;
1881 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05001882
Florin Coras54693d22018-07-17 10:46:29 -07001883 if (!time_to_wait)
1884 {
1885 svm_msg_q_unlock (mq);
1886 return 0;
1887 }
1888 else if (time_to_wait < 0)
1889 {
1890 svm_msg_q_wait (mq);
1891 }
1892 else
1893 {
1894 if (svm_msg_q_timedwait (mq, time_to_wait))
1895 {
1896 svm_msg_q_unlock (mq);
1897 return 0;
1898 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05001899 }
1900 }
Florin Coras134a9962018-08-28 11:32:04 -07001901 vcl_mq_dequeue_batch (wrk, mq);
Florin Coras54693d22018-07-17 10:46:29 -07001902 svm_msg_q_unlock (mq);
1903
Florin Coras134a9962018-08-28 11:32:04 -07001904 for (i = 0; i < vec_len (wrk->mq_msg_vector); i++)
Florin Coras54693d22018-07-17 10:46:29 -07001905 {
Florin Coras134a9962018-08-28 11:32:04 -07001906 msg = vec_elt_at_index (wrk->mq_msg_vector, i);
Florin Coras99368312018-08-02 10:45:44 -07001907 e = svm_msg_q_msg_data (mq, msg);
Florin Coras86f04502018-09-12 16:08:01 -07001908 vcl_select_handle_mq_event (wrk, e, n_bits, read_map, write_map,
1909 except_map, bits_set);
Florin Coras99368312018-08-02 10:45:44 -07001910 svm_msg_q_free_msg (mq, msg);
Florin Coras54693d22018-07-17 10:46:29 -07001911 }
Florin Coras134a9962018-08-28 11:32:04 -07001912 vec_reset_length (wrk->mq_msg_vector);
Florin Coras54693d22018-07-17 10:46:29 -07001913 return *bits_set;
Dave Wallace543852a2017-08-03 02:11:34 -04001914}
1915
Florin Coras99368312018-08-02 10:45:44 -07001916static int
Florin Coras134a9962018-08-28 11:32:04 -07001917vppcom_select_condvar (vcl_worker_t * wrk, unsigned long n_bits,
1918 unsigned long *read_map, unsigned long *write_map,
1919 unsigned long *except_map, double time_to_wait,
1920 u32 * bits_set)
Florin Coras99368312018-08-02 10:45:44 -07001921{
1922 double total_wait = 0, wait_slice;
1923 vcl_cut_through_registration_t *cr;
1924
1925 time_to_wait = (time_to_wait == -1) ? 10e9 : time_to_wait;
Florin Coras134a9962018-08-28 11:32:04 -07001926 wait_slice = wrk->cut_through_registrations ? 10e-6 : time_to_wait;
Florin Coras99368312018-08-02 10:45:44 -07001927 do
1928 {
Florin Coras134a9962018-08-28 11:32:04 -07001929 vcl_ct_registration_lock (wrk);
Florin Coras99368312018-08-02 10:45:44 -07001930 /* *INDENT-OFF* */
Florin Coras134a9962018-08-28 11:32:04 -07001931 pool_foreach (cr, wrk->cut_through_registrations, ({
1932 vcl_select_handle_mq (wrk, cr->mq, n_bits, read_map, write_map, except_map,
Florin Coras99368312018-08-02 10:45:44 -07001933 0, bits_set);
1934 }));
1935 /* *INDENT-ON* */
Florin Coras134a9962018-08-28 11:32:04 -07001936 vcl_ct_registration_unlock (wrk);
Florin Coras99368312018-08-02 10:45:44 -07001937
Florin Coras134a9962018-08-28 11:32:04 -07001938 vcl_select_handle_mq (wrk, wrk->app_event_queue, n_bits, read_map,
1939 write_map, except_map, time_to_wait, bits_set);
Florin Coras99368312018-08-02 10:45:44 -07001940 total_wait += wait_slice;
1941 if (*bits_set)
1942 return *bits_set;
1943 }
1944 while (total_wait < time_to_wait);
1945
1946 return 0;
1947}
1948
1949static int
Florin Coras134a9962018-08-28 11:32:04 -07001950vppcom_select_eventfd (vcl_worker_t * wrk, unsigned long n_bits,
1951 unsigned long *read_map, unsigned long *write_map,
1952 unsigned long *except_map, double time_to_wait,
1953 u32 * bits_set)
Florin Coras99368312018-08-02 10:45:44 -07001954{
1955 vcl_mq_evt_conn_t *mqc;
1956 int __clib_unused n_read;
1957 int n_mq_evts, i;
1958 u64 buf;
1959
Florin Coras134a9962018-08-28 11:32:04 -07001960 vec_validate (wrk->mq_events, pool_elts (wrk->mq_evt_conns));
1961 n_mq_evts = epoll_wait (wrk->mqs_epfd, wrk->mq_events,
1962 vec_len (wrk->mq_events), time_to_wait);
Florin Coras99368312018-08-02 10:45:44 -07001963 for (i = 0; i < n_mq_evts; i++)
1964 {
Florin Coras134a9962018-08-28 11:32:04 -07001965 mqc = vcl_mq_evt_conn_get (wrk, wrk->mq_events[i].data.u32);
Florin Coras99368312018-08-02 10:45:44 -07001966 n_read = read (mqc->mq_fd, &buf, sizeof (buf));
Florin Coras134a9962018-08-28 11:32:04 -07001967 vcl_select_handle_mq (wrk, mqc->mq, n_bits, read_map, write_map,
Florin Coras99368312018-08-02 10:45:44 -07001968 except_map, 0, bits_set);
1969 }
1970
1971 return (n_mq_evts > 0 ? (int) *bits_set : 0);
1972}
1973
Dave Wallace543852a2017-08-03 02:11:34 -04001974int
1975vppcom_select (unsigned long n_bits, unsigned long *read_map,
1976 unsigned long *write_map, unsigned long *except_map,
1977 double time_to_wait)
1978{
Florin Coras54693d22018-07-17 10:46:29 -07001979 u32 sid, minbits = clib_max (n_bits, BITS (uword)), bits_set = 0;
Florin Coras134a9962018-08-28 11:32:04 -07001980 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras7e12d942018-06-27 14:32:43 -07001981 vcl_session_t *session = 0;
Florin Coras86f04502018-09-12 16:08:01 -07001982 int rv, i;
Dave Wallace543852a2017-08-03 02:11:34 -04001983
1984 ASSERT (sizeof (clib_bitmap_t) == sizeof (long int));
1985
Dave Wallace7876d392017-10-19 03:53:57 -04001986 if (n_bits && read_map)
Dave Wallace543852a2017-08-03 02:11:34 -04001987 {
Florin Coras134a9962018-08-28 11:32:04 -07001988 clib_bitmap_validate (wrk->rd_bitmap, minbits);
Dave Barach178cf492018-11-13 16:34:13 -05001989 clib_memcpy_fast (wrk->rd_bitmap, read_map,
1990 vec_len (wrk->rd_bitmap) * sizeof (clib_bitmap_t));
Florin Coras134a9962018-08-28 11:32:04 -07001991 memset (read_map, 0, vec_len (wrk->rd_bitmap) * sizeof (clib_bitmap_t));
Dave Wallace543852a2017-08-03 02:11:34 -04001992 }
Dave Wallace7876d392017-10-19 03:53:57 -04001993 if (n_bits && write_map)
Dave Wallace543852a2017-08-03 02:11:34 -04001994 {
Florin Coras134a9962018-08-28 11:32:04 -07001995 clib_bitmap_validate (wrk->wr_bitmap, minbits);
Dave Barach178cf492018-11-13 16:34:13 -05001996 clib_memcpy_fast (wrk->wr_bitmap, write_map,
1997 vec_len (wrk->wr_bitmap) * sizeof (clib_bitmap_t));
Dave Wallace048b1d62018-01-03 22:24:41 -05001998 memset (write_map, 0,
Florin Coras134a9962018-08-28 11:32:04 -07001999 vec_len (wrk->wr_bitmap) * sizeof (clib_bitmap_t));
Dave Wallace543852a2017-08-03 02:11:34 -04002000 }
Dave Wallace7876d392017-10-19 03:53:57 -04002001 if (n_bits && except_map)
Dave Wallace543852a2017-08-03 02:11:34 -04002002 {
Florin Coras134a9962018-08-28 11:32:04 -07002003 clib_bitmap_validate (wrk->ex_bitmap, minbits);
Dave Barach178cf492018-11-13 16:34:13 -05002004 clib_memcpy_fast (wrk->ex_bitmap, except_map,
2005 vec_len (wrk->ex_bitmap) * sizeof (clib_bitmap_t));
Dave Wallace048b1d62018-01-03 22:24:41 -05002006 memset (except_map, 0,
Florin Coras134a9962018-08-28 11:32:04 -07002007 vec_len (wrk->ex_bitmap) * sizeof (clib_bitmap_t));
Dave Wallace543852a2017-08-03 02:11:34 -04002008 }
2009
Florin Coras54693d22018-07-17 10:46:29 -07002010 if (!n_bits)
2011 return 0;
2012
2013 if (!write_map)
2014 goto check_rd;
2015
2016 /* *INDENT-OFF* */
Florin Coras134a9962018-08-28 11:32:04 -07002017 clib_bitmap_foreach (sid, wrk->wr_bitmap, ({
2018 if (!(session = vcl_session_get (wrk, sid)))
Florin Coras54693d22018-07-17 10:46:29 -07002019 {
Florin Coras47c40e22018-11-26 17:01:36 -08002020 if (except_map && sid < minbits)
2021 clib_bitmap_set_no_check (except_map, sid, 1);
2022 continue;
Florin Coras54693d22018-07-17 10:46:29 -07002023 }
2024
2025 rv = svm_fifo_is_full (session->tx_fifo);
Florin Coras54693d22018-07-17 10:46:29 -07002026 if (!rv)
2027 {
2028 clib_bitmap_set_no_check (write_map, sid, 1);
2029 bits_set++;
2030 }
2031 }));
2032
2033check_rd:
2034 if (!read_map)
2035 goto check_mq;
Florin Coras99368312018-08-02 10:45:44 -07002036
Florin Coras134a9962018-08-28 11:32:04 -07002037 clib_bitmap_foreach (sid, wrk->rd_bitmap, ({
2038 if (!(session = vcl_session_get (wrk, sid)))
Florin Coras54693d22018-07-17 10:46:29 -07002039 {
Florin Coras47c40e22018-11-26 17:01:36 -08002040 if (except_map && sid < minbits)
2041 clib_bitmap_set_no_check (except_map, sid, 1);
2042 continue;
Florin Coras54693d22018-07-17 10:46:29 -07002043 }
2044
2045 rv = vppcom_session_read_ready (session);
Florin Coras54693d22018-07-17 10:46:29 -07002046 if (rv)
2047 {
2048 clib_bitmap_set_no_check (read_map, sid, 1);
2049 bits_set++;
2050 }
2051 }));
2052 /* *INDENT-ON* */
2053
2054check_mq:
Dave Wallace543852a2017-08-03 02:11:34 -04002055
Florin Coras86f04502018-09-12 16:08:01 -07002056 for (i = 0; i < vec_len (wrk->unhandled_evts_vector); i++)
2057 {
2058 vcl_select_handle_mq_event (wrk, &wrk->unhandled_evts_vector[i], n_bits,
2059 read_map, write_map, except_map, &bits_set);
2060 }
2061 vec_reset_length (wrk->unhandled_evts_vector);
2062
Florin Coras99368312018-08-02 10:45:44 -07002063 if (vcm->cfg.use_mq_eventfd)
Florin Coras134a9962018-08-28 11:32:04 -07002064 vppcom_select_eventfd (wrk, n_bits, read_map, write_map, except_map,
Florin Coras99368312018-08-02 10:45:44 -07002065 time_to_wait, &bits_set);
2066 else
Florin Coras134a9962018-08-28 11:32:04 -07002067 vppcom_select_condvar (wrk, n_bits, read_map, write_map, except_map,
Florin Coras99368312018-08-02 10:45:44 -07002068 time_to_wait, &bits_set);
Florin Coras54693d22018-07-17 10:46:29 -07002069
Dave Wallace543852a2017-08-03 02:11:34 -04002070 return (bits_set);
2071}
2072
Dave Wallacef7f809c2017-10-03 01:48:42 -04002073static inline void
Florin Coras134a9962018-08-28 11:32:04 -07002074vep_verify_epoll_chain (vcl_worker_t * wrk, u32 vep_idx)
Dave Wallacef7f809c2017-10-03 01:48:42 -04002075{
Florin Coras7e12d942018-06-27 14:32:43 -07002076 vcl_session_t *session;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002077 vppcom_epoll_t *vep;
Dave Wallace498b3a52017-11-09 13:00:34 -05002078 u32 sid = vep_idx;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002079
Dave Wallace498b3a52017-11-09 13:00:34 -05002080 if (VPPCOM_DEBUG <= 1)
Dave Wallacef7f809c2017-10-03 01:48:42 -04002081 return;
2082
2083 /* Assumes caller has acquired spinlock: vcm->sessions_lockp */
Florin Coras134a9962018-08-28 11:32:04 -07002084 session = vcl_session_get (wrk, vep_idx);
Florin Coras070453d2018-08-24 17:04:27 -07002085 if (PREDICT_FALSE (!session))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002086 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002087 clib_warning ("VCL<%d>: ERROR: Invalid vep_idx (%u)!",
2088 getpid (), vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002089 goto done;
2090 }
2091 if (PREDICT_FALSE (!session->is_vep))
2092 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002093 clib_warning ("VCL<%d>: ERROR: vep_idx (%u) is not a vep!",
2094 getpid (), vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002095 goto done;
2096 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05002097 vep = &session->vep;
Dave Wallace048b1d62018-01-03 22:24:41 -05002098 clib_warning ("VCL<%d>: vep_idx (%u): Dumping epoll chain\n"
Dave Wallace498b3a52017-11-09 13:00:34 -05002099 "{\n"
2100 " is_vep = %u\n"
2101 " is_vep_session = %u\n"
Dave Wallace4878cbe2017-11-21 03:45:09 -05002102 " next_sid = 0x%x (%u)\n"
Dave Wallace498b3a52017-11-09 13:00:34 -05002103 " wait_cont_idx = 0x%x (%u)\n"
Dave Wallace4878cbe2017-11-21 03:45:09 -05002104 "}\n", getpid (), vep_idx,
2105 session->is_vep, session->is_vep_session,
Florin Coras134a9962018-08-28 11:32:04 -07002106 vep->next_sh, vep->next_sh,
Dave Wallace498b3a52017-11-09 13:00:34 -05002107 session->wait_cont_idx, session->wait_cont_idx);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002108
Florin Coras134a9962018-08-28 11:32:04 -07002109 for (sid = vep->next_sh; sid != ~0; sid = vep->next_sh)
Dave Wallacef7f809c2017-10-03 01:48:42 -04002110 {
Florin Coras134a9962018-08-28 11:32:04 -07002111 session = vcl_session_get (wrk, sid);
Florin Coras070453d2018-08-24 17:04:27 -07002112 if (PREDICT_FALSE (!session))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002113 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002114 clib_warning ("VCL<%d>: ERROR: Invalid sid (%u)!", getpid (), sid);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002115 goto done;
2116 }
2117 if (PREDICT_FALSE (session->is_vep))
Dave Wallace048b1d62018-01-03 22:24:41 -05002118 clib_warning ("VCL<%d>: ERROR: sid (%u) is a vep!",
2119 getpid (), vep_idx);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002120 else if (PREDICT_FALSE (!session->is_vep_session))
2121 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002122 clib_warning ("VCL<%d>: ERROR: session (%u) "
2123 "is not a vep session!", getpid (), sid);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002124 goto done;
2125 }
2126 vep = &session->vep;
Florin Coras134a9962018-08-28 11:32:04 -07002127 if (PREDICT_FALSE (vep->vep_sh != vep_idx))
Dave Wallace048b1d62018-01-03 22:24:41 -05002128 clib_warning ("VCL<%d>: ERROR: session (%u) vep_idx (%u) != "
Dave Wallace4878cbe2017-11-21 03:45:09 -05002129 "vep_idx (%u)!", getpid (),
Florin Coras134a9962018-08-28 11:32:04 -07002130 sid, session->vep.vep_sh, vep_idx);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002131 if (session->is_vep_session)
2132 {
2133 clib_warning ("vep_idx[%u]: sid 0x%x (%u)\n"
2134 "{\n"
2135 " next_sid = 0x%x (%u)\n"
2136 " prev_sid = 0x%x (%u)\n"
2137 " vep_idx = 0x%x (%u)\n"
2138 " ev.events = 0x%x\n"
2139 " ev.data.u64 = 0x%llx\n"
2140 " et_mask = 0x%x\n"
2141 "}\n",
2142 vep_idx, sid, sid,
Florin Coras134a9962018-08-28 11:32:04 -07002143 vep->next_sh, vep->next_sh,
2144 vep->prev_sh, vep->prev_sh,
2145 vep->vep_sh, vep->vep_sh,
Dave Wallace4878cbe2017-11-21 03:45:09 -05002146 vep->ev.events, vep->ev.data.u64, vep->et_mask);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002147 }
2148 }
Dave Wallacef7f809c2017-10-03 01:48:42 -04002149
2150done:
Dave Wallace048b1d62018-01-03 22:24:41 -05002151 clib_warning ("VCL<%d>: vep_idx (%u): Dump complete!\n",
2152 getpid (), vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002153}
2154
2155int
2156vppcom_epoll_create (void)
2157{
Florin Coras134a9962018-08-28 11:32:04 -07002158 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras7e12d942018-06-27 14:32:43 -07002159 vcl_session_t *vep_session;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002160
Florin Coras134a9962018-08-28 11:32:04 -07002161 vep_session = vcl_session_alloc (wrk);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002162
2163 vep_session->is_vep = 1;
Florin Coras134a9962018-08-28 11:32:04 -07002164 vep_session->vep.vep_sh = ~0;
2165 vep_session->vep.next_sh = ~0;
2166 vep_session->vep.prev_sh = ~0;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002167 vep_session->wait_cont_idx = ~0;
Dave Wallace4878cbe2017-11-21 03:45:09 -05002168 vep_session->vpp_handle = ~0;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002169
Florin Coras134a9962018-08-28 11:32:04 -07002170 vcl_evt (VCL_EVT_EPOLL_CREATE, vep_session, vep_sh);
Florin Coras0d427d82018-06-27 03:24:07 -07002171 VDBG (0, "VCL<%d>: Created vep_idx %u / sid %u!",
Florin Coras134a9962018-08-28 11:32:04 -07002172 getpid (), vep_session->session_index, vep_session->session_index);
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002173
Florin Corasab2f6db2018-08-31 14:31:41 -07002174 return vcl_session_handle (vep_session);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002175}
2176
2177int
Florin Coras134a9962018-08-28 11:32:04 -07002178vppcom_epoll_ctl (uint32_t vep_handle, int op, uint32_t session_handle,
Dave Wallacef7f809c2017-10-03 01:48:42 -04002179 struct epoll_event *event)
2180{
Florin Coras134a9962018-08-28 11:32:04 -07002181 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras7e12d942018-06-27 14:32:43 -07002182 vcl_session_t *vep_session;
2183 vcl_session_t *session;
Florin Coras070453d2018-08-24 17:04:27 -07002184 int rv = VPPCOM_OK;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002185
Florin Coras134a9962018-08-28 11:32:04 -07002186 if (vep_handle == session_handle)
Dave Wallacef7f809c2017-10-03 01:48:42 -04002187 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002188 clib_warning ("VCL<%d>: ERROR: vep_idx == session_index (%u)!",
Florin Coras134a9962018-08-28 11:32:04 -07002189 getpid (), vep_handle);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002190 return VPPCOM_EINVAL;
2191 }
2192
Florin Coras134a9962018-08-28 11:32:04 -07002193 vep_session = vcl_session_get_w_handle (wrk, vep_handle);
Florin Coras070453d2018-08-24 17:04:27 -07002194 if (PREDICT_FALSE (!vep_session))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002195 {
Florin Coras134a9962018-08-28 11:32:04 -07002196 clib_warning ("VCL<%d>: ERROR: Invalid vep_idx (%u)!", vep_handle);
Florin Coras070453d2018-08-24 17:04:27 -07002197 return VPPCOM_EBADFD;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002198 }
2199 if (PREDICT_FALSE (!vep_session->is_vep))
2200 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002201 clib_warning ("VCL<%d>: ERROR: vep_idx (%u) is not a vep!",
Florin Coras134a9962018-08-28 11:32:04 -07002202 getpid (), vep_handle);
Florin Coras070453d2018-08-24 17:04:27 -07002203 return VPPCOM_EINVAL;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002204 }
2205
Florin Coras134a9962018-08-28 11:32:04 -07002206 ASSERT (vep_session->vep.vep_sh == ~0);
2207 ASSERT (vep_session->vep.prev_sh == ~0);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002208
Florin Coras134a9962018-08-28 11:32:04 -07002209 session = vcl_session_get_w_handle (wrk, session_handle);
Florin Coras070453d2018-08-24 17:04:27 -07002210 if (PREDICT_FALSE (!session))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002211 {
Florin Coras134a9962018-08-28 11:32:04 -07002212 VDBG (0, "VCL<%d>: ERROR: Invalid session_handle (%u)!",
2213 getpid (), session_handle);
Florin Coras070453d2018-08-24 17:04:27 -07002214 return VPPCOM_EBADFD;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002215 }
2216 if (PREDICT_FALSE (session->is_vep))
2217 {
Florin Coras134a9962018-08-28 11:32:04 -07002218 clib_warning ("ERROR: session_handle (%u) is a vep!", vep_handle);
Florin Coras070453d2018-08-24 17:04:27 -07002219 return VPPCOM_EINVAL;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002220 }
2221
2222 switch (op)
2223 {
2224 case EPOLL_CTL_ADD:
2225 if (PREDICT_FALSE (!event))
2226 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002227 clib_warning ("VCL<%d>: ERROR: EPOLL_CTL_ADD: NULL pointer to "
Dave Wallace2e005bb2017-11-07 01:21:39 -05002228 "epoll_event structure!", getpid ());
Florin Coras070453d2018-08-24 17:04:27 -07002229 return VPPCOM_EINVAL;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002230 }
Florin Coras134a9962018-08-28 11:32:04 -07002231 if (vep_session->vep.next_sh != ~0)
Dave Wallacef7f809c2017-10-03 01:48:42 -04002232 {
Florin Coras7e12d942018-06-27 14:32:43 -07002233 vcl_session_t *next_session;
Florin Corasab2f6db2018-08-31 14:31:41 -07002234 next_session = vcl_session_get_w_handle (wrk,
2235 vep_session->vep.next_sh);
Florin Coras070453d2018-08-24 17:04:27 -07002236 if (PREDICT_FALSE (!next_session))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002237 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002238 clib_warning ("VCL<%d>: ERROR: EPOLL_CTL_ADD: Invalid "
Dave Wallace4878cbe2017-11-21 03:45:09 -05002239 "vep.next_sid (%u) on vep_idx (%u)!",
Florin Coras134a9962018-08-28 11:32:04 -07002240 getpid (), vep_session->vep.next_sh, vep_handle);
Florin Coras070453d2018-08-24 17:04:27 -07002241 return VPPCOM_EBADFD;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002242 }
Florin Coras134a9962018-08-28 11:32:04 -07002243 ASSERT (next_session->vep.prev_sh == vep_handle);
2244 next_session->vep.prev_sh = session_handle;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002245 }
Florin Coras134a9962018-08-28 11:32:04 -07002246 session->vep.next_sh = vep_session->vep.next_sh;
2247 session->vep.prev_sh = vep_handle;
2248 session->vep.vep_sh = vep_handle;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002249 session->vep.et_mask = VEP_DEFAULT_ET_MASK;
2250 session->vep.ev = *event;
Dave Wallace4878cbe2017-11-21 03:45:09 -05002251 session->is_vep = 0;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002252 session->is_vep_session = 1;
Florin Coras134a9962018-08-28 11:32:04 -07002253 vep_session->vep.next_sh = session_handle;
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002254
Florin Coras070453d2018-08-24 17:04:27 -07002255 VDBG (1, "VCL<%d>: EPOLL_CTL_ADD: vep_idx %u, sid %u, events 0x%x, "
Florin Coras134a9962018-08-28 11:32:04 -07002256 "data 0x%llx!", getpid (), vep_handle, session_handle,
2257 event->events, event->data.u64);
Florin Coras0d427d82018-06-27 03:24:07 -07002258 vcl_evt (VCL_EVT_EPOLL_CTLADD, session, event->events, event->data.u64);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002259 break;
2260
2261 case EPOLL_CTL_MOD:
2262 if (PREDICT_FALSE (!event))
2263 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002264 clib_warning ("VCL<%d>: ERROR: EPOLL_CTL_MOD: NULL pointer to "
Dave Wallace2e005bb2017-11-07 01:21:39 -05002265 "epoll_event structure!", getpid ());
Dave Wallacef7f809c2017-10-03 01:48:42 -04002266 rv = VPPCOM_EINVAL;
2267 goto done;
2268 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05002269 else if (PREDICT_FALSE (!session->is_vep_session))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002270 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002271 clib_warning ("VCL<%d>: ERROR: sid %u EPOLL_CTL_MOD: "
Florin Coras134a9962018-08-28 11:32:04 -07002272 "not a vep session!", getpid (), session_handle);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002273 rv = VPPCOM_EINVAL;
2274 goto done;
2275 }
Florin Coras134a9962018-08-28 11:32:04 -07002276 else if (PREDICT_FALSE (session->vep.vep_sh != vep_handle))
Dave Wallace4878cbe2017-11-21 03:45:09 -05002277 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002278 clib_warning ("VCL<%d>: ERROR: sid %u EPOLL_CTL_MOD: "
Dave Wallace4878cbe2017-11-21 03:45:09 -05002279 "vep_idx (%u) != vep_idx (%u)!",
Florin Coras134a9962018-08-28 11:32:04 -07002280 getpid (), session_handle,
2281 session->vep.vep_sh, vep_handle);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002282 rv = VPPCOM_EINVAL;
2283 goto done;
2284 }
2285 session->vep.et_mask = VEP_DEFAULT_ET_MASK;
2286 session->vep.ev = *event;
Florin Coras0d427d82018-06-27 03:24:07 -07002287 VDBG (1, "VCL<%d>: EPOLL_CTL_MOD: vep_idx %u, sid %u, events 0x%x,"
Florin Coras134a9962018-08-28 11:32:04 -07002288 " data 0x%llx!", getpid (), vep_handle, session_handle,
2289 event->events, event->data.u64);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002290 break;
2291
2292 case EPOLL_CTL_DEL:
Dave Wallace4878cbe2017-11-21 03:45:09 -05002293 if (PREDICT_FALSE (!session->is_vep_session))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002294 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002295 clib_warning ("VCL<%d>: ERROR: sid %u EPOLL_CTL_DEL: "
Florin Coras134a9962018-08-28 11:32:04 -07002296 "not a vep session!", getpid (), session_handle);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002297 rv = VPPCOM_EINVAL;
2298 goto done;
2299 }
Florin Coras134a9962018-08-28 11:32:04 -07002300 else if (PREDICT_FALSE (session->vep.vep_sh != vep_handle))
Dave Wallace4878cbe2017-11-21 03:45:09 -05002301 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002302 clib_warning ("VCL<%d>: ERROR: sid %u EPOLL_CTL_DEL: "
Dave Wallace4878cbe2017-11-21 03:45:09 -05002303 "vep_idx (%u) != vep_idx (%u)!",
Florin Coras134a9962018-08-28 11:32:04 -07002304 getpid (), session_handle,
2305 session->vep.vep_sh, vep_handle);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002306 rv = VPPCOM_EINVAL;
2307 goto done;
2308 }
2309
2310 vep_session->wait_cont_idx =
Florin Coras134a9962018-08-28 11:32:04 -07002311 (vep_session->wait_cont_idx == session_handle) ?
2312 session->vep.next_sh : vep_session->wait_cont_idx;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002313
Florin Coras134a9962018-08-28 11:32:04 -07002314 if (session->vep.prev_sh == vep_handle)
2315 vep_session->vep.next_sh = session->vep.next_sh;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002316 else
2317 {
Florin Coras7e12d942018-06-27 14:32:43 -07002318 vcl_session_t *prev_session;
Florin Corasab2f6db2018-08-31 14:31:41 -07002319 prev_session = vcl_session_get_w_handle (wrk, session->vep.prev_sh);
Florin Coras070453d2018-08-24 17:04:27 -07002320 if (PREDICT_FALSE (!prev_session))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002321 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002322 clib_warning ("VCL<%d>: ERROR: EPOLL_CTL_DEL: Invalid "
Dave Wallace4878cbe2017-11-21 03:45:09 -05002323 "vep.prev_sid (%u) on sid (%u)!",
Florin Coras134a9962018-08-28 11:32:04 -07002324 getpid (), session->vep.prev_sh, session_handle);
Florin Coras070453d2018-08-24 17:04:27 -07002325 return VPPCOM_EBADFD;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002326 }
Florin Coras134a9962018-08-28 11:32:04 -07002327 ASSERT (prev_session->vep.next_sh == session_handle);
2328 prev_session->vep.next_sh = session->vep.next_sh;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002329 }
Florin Coras134a9962018-08-28 11:32:04 -07002330 if (session->vep.next_sh != ~0)
Dave Wallacef7f809c2017-10-03 01:48:42 -04002331 {
Florin Coras7e12d942018-06-27 14:32:43 -07002332 vcl_session_t *next_session;
Florin Corasab2f6db2018-08-31 14:31:41 -07002333 next_session = vcl_session_get_w_handle (wrk, session->vep.next_sh);
Florin Coras070453d2018-08-24 17:04:27 -07002334 if (PREDICT_FALSE (!next_session))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002335 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002336 clib_warning ("VCL<%d>: ERROR: EPOLL_CTL_DEL: Invalid "
Dave Wallace4878cbe2017-11-21 03:45:09 -05002337 "vep.next_sid (%u) on sid (%u)!",
Florin Coras134a9962018-08-28 11:32:04 -07002338 getpid (), session->vep.next_sh, session_handle);
Florin Coras070453d2018-08-24 17:04:27 -07002339 return VPPCOM_EBADFD;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002340 }
Florin Coras134a9962018-08-28 11:32:04 -07002341 ASSERT (next_session->vep.prev_sh == session_handle);
2342 next_session->vep.prev_sh = session->vep.prev_sh;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002343 }
2344
2345 memset (&session->vep, 0, sizeof (session->vep));
Florin Coras134a9962018-08-28 11:32:04 -07002346 session->vep.next_sh = ~0;
2347 session->vep.prev_sh = ~0;
2348 session->vep.vep_sh = ~0;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002349 session->is_vep_session = 0;
Florin Coras0d427d82018-06-27 03:24:07 -07002350 VDBG (1, "VCL<%d>: EPOLL_CTL_DEL: vep_idx %u, sid %u!",
Florin Coras134a9962018-08-28 11:32:04 -07002351 getpid (), vep_handle, session_handle);
2352 vcl_evt (VCL_EVT_EPOLL_CTLDEL, session, vep_sh);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002353 break;
2354
2355 default:
Dave Wallace048b1d62018-01-03 22:24:41 -05002356 clib_warning ("VCL<%d>: ERROR: Invalid operation (%d)!", getpid (), op);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002357 rv = VPPCOM_EINVAL;
2358 }
2359
Florin Coras134a9962018-08-28 11:32:04 -07002360 vep_verify_epoll_chain (wrk, vep_handle);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002361
2362done:
Dave Wallacef7f809c2017-10-03 01:48:42 -04002363 return rv;
2364}
2365
Florin Coras86f04502018-09-12 16:08:01 -07002366static inline void
2367vcl_epoll_wait_handle_mq_event (vcl_worker_t * wrk, session_event_t * e,
2368 struct epoll_event *events, u32 * num_ev)
Florin Coras54693d22018-07-17 10:46:29 -07002369{
2370 session_disconnected_msg_t *disconnected_msg;
2371 session_connected_msg_t *connected_msg;
2372 session_accepted_msg_t *accepted_msg;
Florin Coras54693d22018-07-17 10:46:29 -07002373 u64 session_evt_data = ~0, handle;
Florin Coras99368312018-08-02 10:45:44 -07002374 u32 sid = ~0, session_events;
Florin Coras54693d22018-07-17 10:46:29 -07002375 vcl_session_msg_t *vcl_msg;
2376 vcl_session_t *session;
Florin Coras86f04502018-09-12 16:08:01 -07002377 u8 add_event = 0;
2378
2379 switch (e->event_type)
2380 {
2381 case FIFO_EVENT_APP_RX:
2382 ASSERT (e->fifo->client_thread_index == vcl_get_worker_index ());
2383 vcl_fifo_rx_evt_valid_or_break (e->fifo);
2384 sid = e->fifo->client_session_index;
2385 session = vcl_session_get (wrk, sid);
2386 session_events = session->vep.ev.events;
Florin Corasaa27eb92018-10-13 12:20:01 -07002387 if (!(EPOLLIN & session->vep.ev.events) || session->has_rx_evt)
Florin Coras86f04502018-09-12 16:08:01 -07002388 break;
2389 add_event = 1;
2390 events[*num_ev].events |= EPOLLIN;
2391 session_evt_data = session->vep.ev.data.u64;
Florin Corasaa27eb92018-10-13 12:20:01 -07002392 session->has_rx_evt = 1;
Florin Coras86f04502018-09-12 16:08:01 -07002393 break;
2394 case FIFO_EVENT_APP_TX:
2395 sid = e->fifo->client_session_index;
2396 session = vcl_session_get (wrk, sid);
2397 session_events = session->vep.ev.events;
2398 if (!(EPOLLOUT & session_events))
2399 break;
2400 add_event = 1;
2401 events[*num_ev].events |= EPOLLOUT;
2402 session_evt_data = session->vep.ev.data.u64;
2403 break;
2404 case SESSION_IO_EVT_CT_TX:
2405 vcl_fifo_rx_evt_valid_or_break (e->fifo);
2406 session = vcl_ct_session_get_from_fifo (wrk, e->fifo, 0);
2407 sid = session->session_index;
2408 session_events = session->vep.ev.events;
Florin Corasaa27eb92018-10-13 12:20:01 -07002409 if (!(EPOLLIN & session->vep.ev.events) || session->has_rx_evt)
Florin Coras86f04502018-09-12 16:08:01 -07002410 break;
2411 add_event = 1;
2412 events[*num_ev].events |= EPOLLIN;
2413 session_evt_data = session->vep.ev.data.u64;
Florin Corasaa27eb92018-10-13 12:20:01 -07002414 session->has_rx_evt = 1;
Florin Coras86f04502018-09-12 16:08:01 -07002415 break;
2416 case SESSION_IO_EVT_CT_RX:
2417 session = vcl_ct_session_get_from_fifo (wrk, e->fifo, 1);
2418 sid = session->session_index;
2419 session_events = session->vep.ev.events;
2420 if (!(EPOLLOUT & session_events))
2421 break;
2422 add_event = 1;
2423 events[*num_ev].events |= EPOLLOUT;
2424 session_evt_data = session->vep.ev.data.u64;
2425 break;
2426 case SESSION_CTRL_EVT_ACCEPTED:
2427 accepted_msg = (session_accepted_msg_t *) e->data;
2428 handle = accepted_msg->listener_handle;
2429 session = vcl_session_table_lookup_listener (wrk, handle);
2430 if (!session)
2431 {
2432 clib_warning ("VCL<%d>: ERROR: couldn't find listen session:"
2433 "listener handle %llx", getpid (), handle);
2434 break;
2435 }
2436
2437 clib_fifo_add2 (session->accept_evts_fifo, vcl_msg);
2438 vcl_msg->accepted_msg = *accepted_msg;
2439 session_events = session->vep.ev.events;
2440 if (!(EPOLLIN & session_events))
2441 break;
2442
2443 add_event = 1;
2444 events[*num_ev].events |= EPOLLIN;
2445 session_evt_data = session->vep.ev.data.u64;
2446 break;
2447 case SESSION_CTRL_EVT_CONNECTED:
2448 connected_msg = (session_connected_msg_t *) e->data;
2449 vcl_session_connected_handler (wrk, connected_msg);
2450 /* Generate EPOLLOUT because there's no connected event */
2451 sid = vcl_session_index_from_vpp_handle (wrk, connected_msg->handle);
2452 session = vcl_session_get (wrk, sid);
2453 session_events = session->vep.ev.events;
2454 if (EPOLLOUT & session_events)
2455 {
2456 add_event = 1;
2457 events[*num_ev].events |= EPOLLOUT;
2458 session_evt_data = session->vep.ev.data.u64;
2459 }
2460 break;
2461 case SESSION_CTRL_EVT_DISCONNECTED:
2462 disconnected_msg = (session_disconnected_msg_t *) e->data;
2463 sid = vcl_session_index_from_vpp_handle (wrk, disconnected_msg->handle);
2464 if (!(session = vcl_session_get (wrk, sid)))
2465 break;
2466 add_event = 1;
2467 events[*num_ev].events |= EPOLLHUP | EPOLLRDHUP;
2468 session_evt_data = session->vep.ev.data.u64;
2469 session_events = session->vep.ev.events;
2470 break;
2471 case SESSION_CTRL_EVT_RESET:
2472 sid = vcl_session_reset_handler (wrk, (session_reset_msg_t *) e->data);
2473 if (!(session = vcl_session_get (wrk, sid)))
2474 break;
2475 add_event = 1;
2476 events[*num_ev].events |= EPOLLHUP | EPOLLRDHUP;
2477 session_evt_data = session->vep.ev.data.u64;
2478 session_events = session->vep.ev.events;
2479 break;
2480 default:
2481 VDBG (0, "unhandled: %u", e->event_type);
2482 break;
2483 }
2484
2485 if (add_event)
2486 {
2487 events[*num_ev].data.u64 = session_evt_data;
2488 if (EPOLLONESHOT & session_events)
2489 {
2490 session = vcl_session_get (wrk, sid);
2491 session->vep.ev.events = 0;
2492 }
2493 *num_ev += 1;
2494 }
2495}
2496
2497static int
2498vcl_epoll_wait_handle_mq (vcl_worker_t * wrk, svm_msg_q_t * mq,
2499 struct epoll_event *events, u32 maxevents,
2500 double wait_for_time, u32 * num_ev)
2501{
Florin Coras99368312018-08-02 10:45:44 -07002502 svm_msg_q_msg_t *msg;
Florin Coras54693d22018-07-17 10:46:29 -07002503 session_event_t *e;
Florin Coras54693d22018-07-17 10:46:29 -07002504 int i;
2505
Florin Coras539663c2018-09-28 14:59:37 -07002506 if (vec_len (wrk->mq_msg_vector) && svm_msg_q_is_empty (mq))
2507 goto handle_dequeued;
2508
Florin Coras54693d22018-07-17 10:46:29 -07002509 svm_msg_q_lock (mq);
2510 if (svm_msg_q_is_empty (mq))
2511 {
2512 if (!wait_for_time)
2513 {
2514 svm_msg_q_unlock (mq);
2515 return 0;
2516 }
2517 else if (wait_for_time < 0)
2518 {
2519 svm_msg_q_wait (mq);
2520 }
2521 else
2522 {
Florin Coras60f1fc12018-08-16 14:57:31 -07002523 if (svm_msg_q_timedwait (mq, wait_for_time / 1e3))
Florin Coras54693d22018-07-17 10:46:29 -07002524 {
2525 svm_msg_q_unlock (mq);
2526 return 0;
2527 }
2528 }
2529 }
Florin Coras134a9962018-08-28 11:32:04 -07002530 vcl_mq_dequeue_batch (wrk, mq);
Florin Coras54693d22018-07-17 10:46:29 -07002531 svm_msg_q_unlock (mq);
2532
Florin Coras539663c2018-09-28 14:59:37 -07002533handle_dequeued:
Florin Coras134a9962018-08-28 11:32:04 -07002534 for (i = 0; i < vec_len (wrk->mq_msg_vector); i++)
Florin Coras54693d22018-07-17 10:46:29 -07002535 {
Florin Coras134a9962018-08-28 11:32:04 -07002536 msg = vec_elt_at_index (wrk->mq_msg_vector, i);
Florin Coras99368312018-08-02 10:45:44 -07002537 e = svm_msg_q_msg_data (mq, msg);
Florin Corasaa27eb92018-10-13 12:20:01 -07002538 if (*num_ev < maxevents)
2539 vcl_epoll_wait_handle_mq_event (wrk, e, events, num_ev);
2540 else
2541 vec_add1 (wrk->unhandled_evts_vector, *e);
Florin Coras99368312018-08-02 10:45:44 -07002542 svm_msg_q_free_msg (mq, msg);
Florin Coras54693d22018-07-17 10:46:29 -07002543 }
Florin Corasaa27eb92018-10-13 12:20:01 -07002544 vec_reset_length (wrk->mq_msg_vector);
Florin Coras86f04502018-09-12 16:08:01 -07002545
Florin Coras54693d22018-07-17 10:46:29 -07002546 return *num_ev;
2547}
2548
Florin Coras99368312018-08-02 10:45:44 -07002549static int
Florin Coras134a9962018-08-28 11:32:04 -07002550vppcom_epoll_wait_condvar (vcl_worker_t * wrk, struct epoll_event *events,
Florin Coras86f04502018-09-12 16:08:01 -07002551 int maxevents, u32 n_evts, double wait_for_time)
Florin Coras99368312018-08-02 10:45:44 -07002552{
2553 vcl_cut_through_registration_t *cr;
2554 double total_wait = 0, wait_slice;
Florin Coras99368312018-08-02 10:45:44 -07002555 int rv;
2556
2557 wait_for_time = (wait_for_time == -1) ? (double) 10e9 : wait_for_time;
Florin Coras134a9962018-08-28 11:32:04 -07002558 wait_slice = wrk->cut_through_registrations ? 10e-6 : wait_for_time;
Florin Coras99368312018-08-02 10:45:44 -07002559
2560 do
2561 {
Florin Coras134a9962018-08-28 11:32:04 -07002562 vcl_ct_registration_lock (wrk);
Florin Coras99368312018-08-02 10:45:44 -07002563 /* *INDENT-OFF* */
Florin Coras134a9962018-08-28 11:32:04 -07002564 pool_foreach (cr, wrk->cut_through_registrations, ({
Florin Coras86f04502018-09-12 16:08:01 -07002565 vcl_epoll_wait_handle_mq (wrk, cr->mq, events, maxevents, 0, &n_evts);
Florin Coras99368312018-08-02 10:45:44 -07002566 }));
2567 /* *INDENT-ON* */
Florin Coras134a9962018-08-28 11:32:04 -07002568 vcl_ct_registration_unlock (wrk);
Florin Coras99368312018-08-02 10:45:44 -07002569
Florin Coras134a9962018-08-28 11:32:04 -07002570 rv = vcl_epoll_wait_handle_mq (wrk, wrk->app_event_queue, events,
Florin Coras86f04502018-09-12 16:08:01 -07002571 maxevents, n_evts ? 0 : wait_slice,
2572 &n_evts);
Florin Coras99368312018-08-02 10:45:44 -07002573 if (rv)
2574 total_wait += wait_slice;
Florin Coras86f04502018-09-12 16:08:01 -07002575 if (n_evts)
2576 return n_evts;
Florin Coras99368312018-08-02 10:45:44 -07002577 }
2578 while (total_wait < wait_for_time);
Florin Coras86f04502018-09-12 16:08:01 -07002579 return n_evts;
Florin Coras99368312018-08-02 10:45:44 -07002580}
2581
2582static int
Florin Coras134a9962018-08-28 11:32:04 -07002583vppcom_epoll_wait_eventfd (vcl_worker_t * wrk, struct epoll_event *events,
Florin Coras86f04502018-09-12 16:08:01 -07002584 int maxevents, u32 n_evts, double wait_for_time)
Florin Coras99368312018-08-02 10:45:44 -07002585{
2586 vcl_mq_evt_conn_t *mqc;
2587 int __clib_unused n_read;
2588 int n_mq_evts, i;
Florin Coras99368312018-08-02 10:45:44 -07002589 u64 buf;
2590
Florin Coras134a9962018-08-28 11:32:04 -07002591 vec_validate (wrk->mq_events, pool_elts (wrk->mq_evt_conns));
Florin Corasa4878ed2018-10-12 13:09:36 -07002592again:
Florin Coras134a9962018-08-28 11:32:04 -07002593 n_mq_evts = epoll_wait (wrk->mqs_epfd, wrk->mq_events,
2594 vec_len (wrk->mq_events), wait_for_time);
Florin Coras99368312018-08-02 10:45:44 -07002595 for (i = 0; i < n_mq_evts; i++)
2596 {
Florin Coras134a9962018-08-28 11:32:04 -07002597 mqc = vcl_mq_evt_conn_get (wrk, wrk->mq_events[i].data.u32);
Florin Coras99368312018-08-02 10:45:44 -07002598 n_read = read (mqc->mq_fd, &buf, sizeof (buf));
Florin Coras134a9962018-08-28 11:32:04 -07002599 vcl_epoll_wait_handle_mq (wrk, mqc->mq, events, maxevents, 0, &n_evts);
Florin Coras99368312018-08-02 10:45:44 -07002600 }
Florin Corasa4878ed2018-10-12 13:09:36 -07002601 if (!n_evts && n_mq_evts > 0)
2602 goto again;
Florin Coras99368312018-08-02 10:45:44 -07002603
2604 return (int) n_evts;
2605}
2606
Dave Wallacef7f809c2017-10-03 01:48:42 -04002607int
Florin Coras134a9962018-08-28 11:32:04 -07002608vppcom_epoll_wait (uint32_t vep_handle, struct epoll_event *events,
Dave Wallacef7f809c2017-10-03 01:48:42 -04002609 int maxevents, double wait_for_time)
2610{
Florin Coras134a9962018-08-28 11:32:04 -07002611 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras7e12d942018-06-27 14:32:43 -07002612 vcl_session_t *vep_session;
Florin Coras86f04502018-09-12 16:08:01 -07002613 u32 n_evts = 0;
2614 int i;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002615
2616 if (PREDICT_FALSE (maxevents <= 0))
2617 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002618 clib_warning ("VCL<%d>: ERROR: Invalid maxevents (%d)!",
Dave Wallace4878cbe2017-11-21 03:45:09 -05002619 getpid (), maxevents);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002620 return VPPCOM_EINVAL;
2621 }
Dave Wallacef7f809c2017-10-03 01:48:42 -04002622
Florin Coras134a9962018-08-28 11:32:04 -07002623 vep_session = vcl_session_get_w_handle (wrk, vep_handle);
Florin Coras14598772018-09-04 19:47:52 -07002624 if (!vep_session)
2625 return VPPCOM_EBADFD;
2626
Florin Coras54693d22018-07-17 10:46:29 -07002627 if (PREDICT_FALSE (!vep_session->is_vep))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002628 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002629 clib_warning ("VCL<%d>: ERROR: vep_idx (%u) is not a vep!",
Florin Coras134a9962018-08-28 11:32:04 -07002630 getpid (), vep_handle);
Florin Coras54693d22018-07-17 10:46:29 -07002631 return VPPCOM_EINVAL;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002632 }
Florin Coras54693d22018-07-17 10:46:29 -07002633
2634 memset (events, 0, sizeof (*events) * maxevents);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002635
Florin Coras86f04502018-09-12 16:08:01 -07002636 if (vec_len (wrk->unhandled_evts_vector))
2637 {
2638 for (i = 0; i < vec_len (wrk->unhandled_evts_vector); i++)
2639 {
2640 vcl_epoll_wait_handle_mq_event (wrk, &wrk->unhandled_evts_vector[i],
2641 events, &n_evts);
2642 if (n_evts == maxevents)
2643 {
2644 i += 1;
2645 break;
2646 }
2647 }
Dave Wallacef7f809c2017-10-03 01:48:42 -04002648
Florin Coras86f04502018-09-12 16:08:01 -07002649 vec_delete (wrk->unhandled_evts_vector, i, 0);
2650 }
2651
2652 if (vcm->cfg.use_mq_eventfd)
2653 return vppcom_epoll_wait_eventfd (wrk, events, maxevents, n_evts,
2654 wait_for_time);
2655
2656 return vppcom_epoll_wait_condvar (wrk, events, maxevents, n_evts,
2657 wait_for_time);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002658}
2659
Dave Wallace35830af2017-10-09 01:43:42 -04002660int
Florin Coras134a9962018-08-28 11:32:04 -07002661vppcom_session_attr (uint32_t session_handle, uint32_t op,
Dave Wallace35830af2017-10-09 01:43:42 -04002662 void *buffer, uint32_t * buflen)
2663{
Florin Coras134a9962018-08-28 11:32:04 -07002664 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras7e12d942018-06-27 14:32:43 -07002665 vcl_session_t *session;
Dave Wallace35830af2017-10-09 01:43:42 -04002666 int rv = VPPCOM_OK;
2667 u32 *flags = buffer;
Steven2199aab2017-10-15 20:18:47 -07002668 vppcom_endpt_t *ep = buffer;
Dave Wallace35830af2017-10-09 01:43:42 -04002669
Florin Coras134a9962018-08-28 11:32:04 -07002670 session = vcl_session_get_w_handle (wrk, session_handle);
Florin Coras070453d2018-08-24 17:04:27 -07002671 if (!session)
2672 return VPPCOM_EBADFD;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002673
Dave Wallace35830af2017-10-09 01:43:42 -04002674 switch (op)
2675 {
2676 case VPPCOM_ATTR_GET_NREAD:
Florin Coras54693d22018-07-17 10:46:29 -07002677 rv = vppcom_session_read_ready (session);
Florin Coras0d427d82018-06-27 03:24:07 -07002678 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_NREAD: sid %u, nread = %d",
2679 getpid (), rv);
Dave Wallace35830af2017-10-09 01:43:42 -04002680 break;
2681
Dave Wallace227867f2017-11-13 21:21:53 -05002682 case VPPCOM_ATTR_GET_NWRITE:
Florin Coras134a9962018-08-28 11:32:04 -07002683 rv = vppcom_session_write_ready (session);
Florin Coras0d427d82018-06-27 03:24:07 -07002684 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_NWRITE: sid %u, nwrite = %d",
Florin Coras134a9962018-08-28 11:32:04 -07002685 getpid (), session_handle, rv);
Dave Wallace35830af2017-10-09 01:43:42 -04002686 break;
2687
2688 case VPPCOM_ATTR_GET_FLAGS:
Dave Wallace048b1d62018-01-03 22:24:41 -05002689 if (PREDICT_TRUE (buffer && buflen && (*buflen >= sizeof (*flags))))
Dave Wallace35830af2017-10-09 01:43:42 -04002690 {
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002691 *flags = O_RDWR | (VCL_SESS_ATTR_TEST (session->attr,
2692 VCL_SESS_ATTR_NONBLOCK));
Dave Wallace35830af2017-10-09 01:43:42 -04002693 *buflen = sizeof (*flags);
Florin Coras0d427d82018-06-27 03:24:07 -07002694 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_FLAGS: sid %u, flags = 0x%08x, "
2695 "is_nonblocking = %u", getpid (),
Florin Coras134a9962018-08-28 11:32:04 -07002696 session_handle, *flags,
Florin Coras0d427d82018-06-27 03:24:07 -07002697 VCL_SESS_ATTR_TEST (session->attr, VCL_SESS_ATTR_NONBLOCK));
Dave Wallace35830af2017-10-09 01:43:42 -04002698 }
2699 else
2700 rv = VPPCOM_EINVAL;
2701 break;
2702
2703 case VPPCOM_ATTR_SET_FLAGS:
Dave Wallace048b1d62018-01-03 22:24:41 -05002704 if (PREDICT_TRUE (buffer && buflen && (*buflen == sizeof (*flags))))
Dave Wallace35830af2017-10-09 01:43:42 -04002705 {
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002706 if (*flags & O_NONBLOCK)
2707 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_NONBLOCK);
2708 else
2709 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_NONBLOCK);
2710
Florin Coras0d427d82018-06-27 03:24:07 -07002711 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_FLAGS: sid %u, flags = 0x%08x,"
2712 " is_nonblocking = %u",
Florin Coras134a9962018-08-28 11:32:04 -07002713 getpid (), session_handle, *flags,
Florin Coras0d427d82018-06-27 03:24:07 -07002714 VCL_SESS_ATTR_TEST (session->attr, VCL_SESS_ATTR_NONBLOCK));
Dave Wallace35830af2017-10-09 01:43:42 -04002715 }
2716 else
2717 rv = VPPCOM_EINVAL;
2718 break;
2719
2720 case VPPCOM_ATTR_GET_PEER_ADDR:
Dave Wallace048b1d62018-01-03 22:24:41 -05002721 if (PREDICT_TRUE (buffer && buflen &&
2722 (*buflen >= sizeof (*ep)) && ep->ip))
Dave Wallace35830af2017-10-09 01:43:42 -04002723 {
Florin Coras7e12d942018-06-27 14:32:43 -07002724 ep->is_ip4 = session->transport.is_ip4;
2725 ep->port = session->transport.rmt_port;
2726 if (session->transport.is_ip4)
Dave Barach178cf492018-11-13 16:34:13 -05002727 clib_memcpy_fast (ep->ip, &session->transport.rmt_ip.ip4,
2728 sizeof (ip4_address_t));
Steven2199aab2017-10-15 20:18:47 -07002729 else
Dave Barach178cf492018-11-13 16:34:13 -05002730 clib_memcpy_fast (ep->ip, &session->transport.rmt_ip.ip6,
2731 sizeof (ip6_address_t));
Steven2199aab2017-10-15 20:18:47 -07002732 *buflen = sizeof (*ep);
Florin Coras0d427d82018-06-27 03:24:07 -07002733 VDBG (1, "VCL<%d>: VPPCOM_ATTR_GET_PEER_ADDR: sid %u, is_ip4 = %u, "
2734 "addr = %U, port %u", getpid (),
Florin Coras134a9962018-08-28 11:32:04 -07002735 session_handle, ep->is_ip4, format_ip46_address,
Florin Coras7e12d942018-06-27 14:32:43 -07002736 &session->transport.rmt_ip,
Florin Coras0d427d82018-06-27 03:24:07 -07002737 ep->is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6,
2738 clib_net_to_host_u16 (ep->port));
Dave Wallace35830af2017-10-09 01:43:42 -04002739 }
2740 else
2741 rv = VPPCOM_EINVAL;
2742 break;
2743
2744 case VPPCOM_ATTR_GET_LCL_ADDR:
Dave Wallace048b1d62018-01-03 22:24:41 -05002745 if (PREDICT_TRUE (buffer && buflen &&
2746 (*buflen >= sizeof (*ep)) && ep->ip))
Dave Wallace35830af2017-10-09 01:43:42 -04002747 {
Florin Coras7e12d942018-06-27 14:32:43 -07002748 ep->is_ip4 = session->transport.is_ip4;
2749 ep->port = session->transport.lcl_port;
2750 if (session->transport.is_ip4)
Dave Barach178cf492018-11-13 16:34:13 -05002751 clib_memcpy_fast (ep->ip, &session->transport.lcl_ip.ip4,
2752 sizeof (ip4_address_t));
Steven2199aab2017-10-15 20:18:47 -07002753 else
Dave Barach178cf492018-11-13 16:34:13 -05002754 clib_memcpy_fast (ep->ip, &session->transport.lcl_ip.ip6,
2755 sizeof (ip6_address_t));
Steven2199aab2017-10-15 20:18:47 -07002756 *buflen = sizeof (*ep);
Florin Coras0d427d82018-06-27 03:24:07 -07002757 VDBG (1, "VCL<%d>: VPPCOM_ATTR_GET_LCL_ADDR: sid %u, is_ip4 = %u,"
2758 " addr = %U port %d", getpid (),
Florin Coras134a9962018-08-28 11:32:04 -07002759 session_handle, ep->is_ip4, format_ip46_address,
Florin Coras7e12d942018-06-27 14:32:43 -07002760 &session->transport.lcl_ip,
Florin Coras0d427d82018-06-27 03:24:07 -07002761 ep->is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6,
2762 clib_net_to_host_u16 (ep->port));
Dave Wallace35830af2017-10-09 01:43:42 -04002763 }
2764 else
2765 rv = VPPCOM_EINVAL;
2766 break;
Stevenb5a11602017-10-11 09:59:30 -07002767
Dave Wallace048b1d62018-01-03 22:24:41 -05002768 case VPPCOM_ATTR_GET_LIBC_EPFD:
2769 rv = session->libc_epfd;
Florin Coras0d427d82018-06-27 03:24:07 -07002770 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_LIBC_EPFD: libc_epfd %d",
2771 getpid (), rv);
Dave Wallace048b1d62018-01-03 22:24:41 -05002772 break;
2773
2774 case VPPCOM_ATTR_SET_LIBC_EPFD:
2775 if (PREDICT_TRUE (buffer && buflen &&
2776 (*buflen == sizeof (session->libc_epfd))))
2777 {
2778 session->libc_epfd = *(int *) buffer;
2779 *buflen = sizeof (session->libc_epfd);
2780
Florin Coras0d427d82018-06-27 03:24:07 -07002781 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_LIBC_EPFD: libc_epfd %d, "
2782 "buflen %d", getpid (), session->libc_epfd, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002783 }
2784 else
2785 rv = VPPCOM_EINVAL;
2786 break;
2787
2788 case VPPCOM_ATTR_GET_PROTOCOL:
2789 if (buffer && buflen && (*buflen >= sizeof (int)))
2790 {
Florin Coras7e12d942018-06-27 14:32:43 -07002791 *(int *) buffer = session->session_type;
Dave Wallace048b1d62018-01-03 22:24:41 -05002792 *buflen = sizeof (int);
2793
Florin Coras0d427d82018-06-27 03:24:07 -07002794 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_PROTOCOL: %d (%s), buflen %d",
2795 getpid (), *(int *) buffer, *(int *) buffer ? "UDP" : "TCP",
2796 *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002797 }
2798 else
2799 rv = VPPCOM_EINVAL;
2800 break;
2801
2802 case VPPCOM_ATTR_GET_LISTEN:
2803 if (buffer && buflen && (*buflen >= sizeof (int)))
2804 {
2805 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
2806 VCL_SESS_ATTR_LISTEN);
2807 *buflen = sizeof (int);
2808
Florin Coras0d427d82018-06-27 03:24:07 -07002809 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_LISTEN: %d, buflen %d",
2810 getpid (), *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002811 }
2812 else
2813 rv = VPPCOM_EINVAL;
2814 break;
2815
2816 case VPPCOM_ATTR_GET_ERROR:
2817 if (buffer && buflen && (*buflen >= sizeof (int)))
2818 {
2819 *(int *) buffer = 0;
2820 *buflen = sizeof (int);
2821
Florin Coras0d427d82018-06-27 03:24:07 -07002822 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_ERROR: %d, buflen %d, #VPP-TBD#",
2823 getpid (), *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002824 }
2825 else
2826 rv = VPPCOM_EINVAL;
2827 break;
2828
2829 case VPPCOM_ATTR_GET_TX_FIFO_LEN:
2830 if (buffer && buflen && (*buflen >= sizeof (u32)))
2831 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002832
2833 /* VPP-TBD */
2834 *(size_t *) buffer = (session->sndbuf_size ? session->sndbuf_size :
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002835 session->tx_fifo ? session->tx_fifo->nitems :
Dave Wallace048b1d62018-01-03 22:24:41 -05002836 vcm->cfg.tx_fifo_size);
2837 *buflen = sizeof (u32);
2838
Florin Coras0d427d82018-06-27 03:24:07 -07002839 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_TX_FIFO_LEN: %u (0x%x), "
2840 "buflen %d, #VPP-TBD#", getpid (),
2841 *(size_t *) buffer, *(size_t *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002842 }
2843 else
2844 rv = VPPCOM_EINVAL;
2845 break;
2846
2847 case VPPCOM_ATTR_SET_TX_FIFO_LEN:
2848 if (buffer && buflen && (*buflen == sizeof (u32)))
2849 {
2850 /* VPP-TBD */
2851 session->sndbuf_size = *(u32 *) buffer;
Florin Coras0d427d82018-06-27 03:24:07 -07002852 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_TX_FIFO_LEN: %u (0x%x), "
2853 "buflen %d, #VPP-TBD#", getpid (),
2854 session->sndbuf_size, session->sndbuf_size, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002855 }
2856 else
2857 rv = VPPCOM_EINVAL;
2858 break;
2859
2860 case VPPCOM_ATTR_GET_RX_FIFO_LEN:
2861 if (buffer && buflen && (*buflen >= sizeof (u32)))
2862 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002863
2864 /* VPP-TBD */
2865 *(size_t *) buffer = (session->rcvbuf_size ? session->rcvbuf_size :
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002866 session->rx_fifo ? session->rx_fifo->nitems :
Dave Wallace048b1d62018-01-03 22:24:41 -05002867 vcm->cfg.rx_fifo_size);
2868 *buflen = sizeof (u32);
2869
Florin Coras0d427d82018-06-27 03:24:07 -07002870 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_RX_FIFO_LEN: %u (0x%x), "
2871 "buflen %d, #VPP-TBD#", getpid (),
2872 *(size_t *) buffer, *(size_t *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002873 }
2874 else
2875 rv = VPPCOM_EINVAL;
2876 break;
2877
2878 case VPPCOM_ATTR_SET_RX_FIFO_LEN:
2879 if (buffer && buflen && (*buflen == sizeof (u32)))
2880 {
2881 /* VPP-TBD */
2882 session->rcvbuf_size = *(u32 *) buffer;
Florin Coras0d427d82018-06-27 03:24:07 -07002883 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_RX_FIFO_LEN: %u (0x%x), "
2884 "buflen %d, #VPP-TBD#", getpid (),
2885 session->sndbuf_size, session->sndbuf_size, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002886 }
2887 else
2888 rv = VPPCOM_EINVAL;
2889 break;
2890
2891 case VPPCOM_ATTR_GET_REUSEADDR:
2892 if (buffer && buflen && (*buflen >= sizeof (int)))
2893 {
2894 /* VPP-TBD */
2895 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
2896 VCL_SESS_ATTR_REUSEADDR);
2897 *buflen = sizeof (int);
2898
Florin Coras0d427d82018-06-27 03:24:07 -07002899 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_REUSEADDR: %d, "
2900 "buflen %d, #VPP-TBD#", getpid (), *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002901 }
2902 else
2903 rv = VPPCOM_EINVAL;
2904 break;
2905
Stevenb5a11602017-10-11 09:59:30 -07002906 case VPPCOM_ATTR_SET_REUSEADDR:
Dave Wallace048b1d62018-01-03 22:24:41 -05002907 if (buffer && buflen && (*buflen == sizeof (int)) &&
2908 !VCL_SESS_ATTR_TEST (session->attr, VCL_SESS_ATTR_LISTEN))
2909 {
2910 /* VPP-TBD */
2911 if (*(int *) buffer)
2912 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_REUSEADDR);
2913 else
2914 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_REUSEADDR);
2915
Florin Coras0d427d82018-06-27 03:24:07 -07002916 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_REUSEADDR: %d, buflen %d,"
2917 " #VPP-TBD#", getpid (),
2918 VCL_SESS_ATTR_TEST (session->attr,
2919 VCL_SESS_ATTR_REUSEADDR), *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002920 }
2921 else
2922 rv = VPPCOM_EINVAL;
2923 break;
2924
2925 case VPPCOM_ATTR_GET_REUSEPORT:
2926 if (buffer && buflen && (*buflen >= sizeof (int)))
2927 {
2928 /* VPP-TBD */
2929 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
2930 VCL_SESS_ATTR_REUSEPORT);
2931 *buflen = sizeof (int);
2932
Florin Coras0d427d82018-06-27 03:24:07 -07002933 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_REUSEPORT: %d, buflen %d,"
2934 " #VPP-TBD#", getpid (), *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002935 }
2936 else
2937 rv = VPPCOM_EINVAL;
2938 break;
2939
2940 case VPPCOM_ATTR_SET_REUSEPORT:
2941 if (buffer && buflen && (*buflen == sizeof (int)) &&
2942 !VCL_SESS_ATTR_TEST (session->attr, VCL_SESS_ATTR_LISTEN))
2943 {
2944 /* VPP-TBD */
2945 if (*(int *) buffer)
2946 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_REUSEPORT);
2947 else
2948 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_REUSEPORT);
2949
Florin Coras0d427d82018-06-27 03:24:07 -07002950 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_REUSEPORT: %d, buflen %d,"
2951 " #VPP-TBD#", getpid (),
2952 VCL_SESS_ATTR_TEST (session->attr,
2953 VCL_SESS_ATTR_REUSEPORT), *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002954 }
2955 else
2956 rv = VPPCOM_EINVAL;
2957 break;
2958
2959 case VPPCOM_ATTR_GET_BROADCAST:
2960 if (buffer && buflen && (*buflen >= sizeof (int)))
2961 {
2962 /* VPP-TBD */
2963 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
2964 VCL_SESS_ATTR_BROADCAST);
2965 *buflen = sizeof (int);
2966
Florin Coras0d427d82018-06-27 03:24:07 -07002967 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_BROADCAST: %d, buflen %d,"
2968 " #VPP-TBD#", getpid (), *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002969 }
2970 else
2971 rv = VPPCOM_EINVAL;
Stevenb5a11602017-10-11 09:59:30 -07002972 break;
2973
2974 case VPPCOM_ATTR_SET_BROADCAST:
Dave Wallace048b1d62018-01-03 22:24:41 -05002975 if (buffer && buflen && (*buflen == sizeof (int)))
2976 {
2977 /* VPP-TBD */
2978 if (*(int *) buffer)
2979 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_BROADCAST);
2980 else
2981 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_BROADCAST);
2982
Florin Coras0d427d82018-06-27 03:24:07 -07002983 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_BROADCAST: %d, buflen %d, "
2984 "#VPP-TBD#", getpid (),
2985 VCL_SESS_ATTR_TEST (session->attr,
2986 VCL_SESS_ATTR_BROADCAST), *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002987 }
2988 else
2989 rv = VPPCOM_EINVAL;
2990 break;
2991
2992 case VPPCOM_ATTR_GET_V6ONLY:
2993 if (buffer && buflen && (*buflen >= sizeof (int)))
2994 {
2995 /* VPP-TBD */
2996 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
2997 VCL_SESS_ATTR_V6ONLY);
2998 *buflen = sizeof (int);
2999
Florin Coras0d427d82018-06-27 03:24:07 -07003000 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_V6ONLY: %d, buflen %d, "
3001 "#VPP-TBD#", getpid (), *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003002 }
3003 else
3004 rv = VPPCOM_EINVAL;
Stevenb5a11602017-10-11 09:59:30 -07003005 break;
3006
3007 case VPPCOM_ATTR_SET_V6ONLY:
Dave Wallace048b1d62018-01-03 22:24:41 -05003008 if (buffer && buflen && (*buflen == sizeof (int)))
3009 {
3010 /* VPP-TBD */
3011 if (*(int *) buffer)
3012 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_V6ONLY);
3013 else
3014 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_V6ONLY);
3015
Florin Coras0d427d82018-06-27 03:24:07 -07003016 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_V6ONLY: %d, buflen %d, "
3017 "#VPP-TBD#", getpid (),
3018 VCL_SESS_ATTR_TEST (session->attr,
3019 VCL_SESS_ATTR_V6ONLY), *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003020 }
3021 else
3022 rv = VPPCOM_EINVAL;
3023 break;
3024
3025 case VPPCOM_ATTR_GET_KEEPALIVE:
3026 if (buffer && buflen && (*buflen >= sizeof (int)))
3027 {
3028 /* VPP-TBD */
3029 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
3030 VCL_SESS_ATTR_KEEPALIVE);
3031 *buflen = sizeof (int);
3032
Florin Coras0d427d82018-06-27 03:24:07 -07003033 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_KEEPALIVE: %d, buflen %d, "
3034 "#VPP-TBD#", getpid (), *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003035 }
3036 else
3037 rv = VPPCOM_EINVAL;
Stevenb5a11602017-10-11 09:59:30 -07003038 break;
Stevenbccd3392017-10-12 20:42:21 -07003039
3040 case VPPCOM_ATTR_SET_KEEPALIVE:
Dave Wallace048b1d62018-01-03 22:24:41 -05003041 if (buffer && buflen && (*buflen == sizeof (int)))
3042 {
3043 /* VPP-TBD */
3044 if (*(int *) buffer)
3045 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_KEEPALIVE);
3046 else
3047 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_KEEPALIVE);
3048
Florin Coras0d427d82018-06-27 03:24:07 -07003049 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_KEEPALIVE: %d, buflen %d, "
3050 "#VPP-TBD#", getpid (),
3051 VCL_SESS_ATTR_TEST (session->attr,
3052 VCL_SESS_ATTR_KEEPALIVE), *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003053 }
3054 else
3055 rv = VPPCOM_EINVAL;
3056 break;
3057
3058 case VPPCOM_ATTR_GET_TCP_NODELAY:
3059 if (buffer && buflen && (*buflen >= sizeof (int)))
3060 {
3061 /* VPP-TBD */
3062 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
3063 VCL_SESS_ATTR_TCP_NODELAY);
3064 *buflen = sizeof (int);
3065
Florin Coras0d427d82018-06-27 03:24:07 -07003066 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_TCP_NODELAY: %d, buflen %d, "
3067 "#VPP-TBD#", getpid (), *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003068 }
3069 else
3070 rv = VPPCOM_EINVAL;
3071 break;
3072
3073 case VPPCOM_ATTR_SET_TCP_NODELAY:
3074 if (buffer && buflen && (*buflen == sizeof (int)))
3075 {
3076 /* VPP-TBD */
3077 if (*(int *) buffer)
3078 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_TCP_NODELAY);
3079 else
3080 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_TCP_NODELAY);
3081
Florin Coras0d427d82018-06-27 03:24:07 -07003082 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_TCP_NODELAY: %d, buflen %d, "
3083 "#VPP-TBD#", getpid (),
3084 VCL_SESS_ATTR_TEST (session->attr,
3085 VCL_SESS_ATTR_TCP_NODELAY), *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003086 }
3087 else
3088 rv = VPPCOM_EINVAL;
3089 break;
3090
3091 case VPPCOM_ATTR_GET_TCP_KEEPIDLE:
3092 if (buffer && buflen && (*buflen >= sizeof (int)))
3093 {
3094 /* VPP-TBD */
3095 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
3096 VCL_SESS_ATTR_TCP_KEEPIDLE);
3097 *buflen = sizeof (int);
3098
Florin Coras0d427d82018-06-27 03:24:07 -07003099 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_TCP_KEEPIDLE: %d, buflen %d, "
3100 "#VPP-TBD#", getpid (), *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003101 }
3102 else
3103 rv = VPPCOM_EINVAL;
Stevenbccd3392017-10-12 20:42:21 -07003104 break;
3105
3106 case VPPCOM_ATTR_SET_TCP_KEEPIDLE:
Dave Wallace048b1d62018-01-03 22:24:41 -05003107 if (buffer && buflen && (*buflen == sizeof (int)))
3108 {
3109 /* VPP-TBD */
3110 if (*(int *) buffer)
3111 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_TCP_KEEPIDLE);
3112 else
3113 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_TCP_KEEPIDLE);
3114
Florin Coras0d427d82018-06-27 03:24:07 -07003115 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_TCP_KEEPIDLE: %d, buflen %d, "
3116 "#VPP-TBD#", getpid (),
3117 VCL_SESS_ATTR_TEST (session->attr,
3118 VCL_SESS_ATTR_TCP_KEEPIDLE), *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003119 }
3120 else
3121 rv = VPPCOM_EINVAL;
3122 break;
3123
3124 case VPPCOM_ATTR_GET_TCP_KEEPINTVL:
3125 if (buffer && buflen && (*buflen >= sizeof (int)))
3126 {
3127 /* VPP-TBD */
3128 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
3129 VCL_SESS_ATTR_TCP_KEEPINTVL);
3130 *buflen = sizeof (int);
3131
Florin Coras0d427d82018-06-27 03:24:07 -07003132 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_TCP_KEEPINTVL: %d, buflen %d, "
3133 "#VPP-TBD#", getpid (), *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003134 }
3135 else
3136 rv = VPPCOM_EINVAL;
Stevenbccd3392017-10-12 20:42:21 -07003137 break;
3138
3139 case VPPCOM_ATTR_SET_TCP_KEEPINTVL:
Dave Wallace048b1d62018-01-03 22:24:41 -05003140 if (buffer && buflen && (*buflen == sizeof (int)))
3141 {
3142 /* VPP-TBD */
3143 if (*(int *) buffer)
3144 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_TCP_KEEPINTVL);
3145 else
3146 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_TCP_KEEPINTVL);
3147
Florin Coras0d427d82018-06-27 03:24:07 -07003148 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_TCP_KEEPINTVL: %d, buflen %d, "
3149 "#VPP-TBD#", getpid (),
3150 VCL_SESS_ATTR_TEST (session->attr,
3151 VCL_SESS_ATTR_TCP_KEEPINTVL), *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003152 }
3153 else
3154 rv = VPPCOM_EINVAL;
3155 break;
3156
3157 case VPPCOM_ATTR_GET_TCP_USER_MSS:
3158 if (buffer && buflen && (*buflen >= sizeof (u32)))
3159 {
3160 /* VPP-TBD */
3161 *(u32 *) buffer = session->user_mss;
3162 *buflen = sizeof (int);
3163
Florin Coras0d427d82018-06-27 03:24:07 -07003164 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_TCP_USER_MSS: %d, buflen %d,"
3165 " #VPP-TBD#", getpid (), *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003166 }
3167 else
3168 rv = VPPCOM_EINVAL;
3169 break;
3170
3171 case VPPCOM_ATTR_SET_TCP_USER_MSS:
3172 if (buffer && buflen && (*buflen == sizeof (u32)))
3173 {
3174 /* VPP-TBD */
3175 session->user_mss = *(u32 *) buffer;
3176
Florin Coras0d427d82018-06-27 03:24:07 -07003177 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_TCP_USER_MSS: %u, buflen %d, "
3178 "#VPP-TBD#", getpid (), session->user_mss, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003179 }
3180 else
3181 rv = VPPCOM_EINVAL;
Stevenbccd3392017-10-12 20:42:21 -07003182 break;
Dave Wallacee22aa742017-10-20 12:30:38 -04003183
Florin Coras47c40e22018-11-26 17:01:36 -08003184 case VPPCOM_ATTR_GET_REFCNT:
3185 rv = vcl_session_get_refcnt (session);
3186 break;
3187
Dave Wallacee22aa742017-10-20 12:30:38 -04003188 default:
3189 rv = VPPCOM_EINVAL;
3190 break;
Dave Wallace35830af2017-10-09 01:43:42 -04003191 }
3192
Dave Wallace35830af2017-10-09 01:43:42 -04003193 return rv;
3194}
3195
Stevenac1f96d2017-10-24 16:03:58 -07003196int
Florin Coras134a9962018-08-28 11:32:04 -07003197vppcom_session_recvfrom (uint32_t session_handle, void *buffer,
Stevenac1f96d2017-10-24 16:03:58 -07003198 uint32_t buflen, int flags, vppcom_endpt_t * ep)
3199{
Florin Coras134a9962018-08-28 11:32:04 -07003200 vcl_worker_t *wrk = vcl_worker_get_current ();
Stevenac1f96d2017-10-24 16:03:58 -07003201 int rv = VPPCOM_OK;
Florin Coras7e12d942018-06-27 14:32:43 -07003202 vcl_session_t *session = 0;
Stevenac1f96d2017-10-24 16:03:58 -07003203
3204 if (ep)
3205 {
Florin Coras134a9962018-08-28 11:32:04 -07003206 session = vcl_session_get_w_handle (wrk, session_handle);
Florin Coras070453d2018-08-24 17:04:27 -07003207 if (PREDICT_FALSE (!session))
Stevenac1f96d2017-10-24 16:03:58 -07003208 {
Florin Coras0d427d82018-06-27 03:24:07 -07003209 VDBG (0, "VCL<%d>: invalid session, sid (%u) has been closed!",
Florin Coras134a9962018-08-28 11:32:04 -07003210 getpid (), session_handle);
Florin Coras460dce62018-07-27 05:45:06 -07003211 return VPPCOM_EBADFD;
Stevenac1f96d2017-10-24 16:03:58 -07003212 }
Florin Coras7e12d942018-06-27 14:32:43 -07003213 ep->is_ip4 = session->transport.is_ip4;
3214 ep->port = session->transport.rmt_port;
Stevenac1f96d2017-10-24 16:03:58 -07003215 }
Steven58f464e2017-10-25 12:33:12 -07003216
3217 if (flags == 0)
Florin Coras134a9962018-08-28 11:32:04 -07003218 rv = vppcom_session_read (session_handle, buffer, buflen);
Stevenac1f96d2017-10-24 16:03:58 -07003219 else if (flags & MSG_PEEK)
Florin Coras134a9962018-08-28 11:32:04 -07003220 rv = vppcom_session_peek (session_handle, buffer, buflen);
Stevenac1f96d2017-10-24 16:03:58 -07003221 else
3222 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003223 clib_warning ("VCL<%d>: Unsupport flags for recvfrom %d",
3224 getpid (), flags);
Florin Coras460dce62018-07-27 05:45:06 -07003225 return VPPCOM_EAFNOSUPPORT;
Stevenac1f96d2017-10-24 16:03:58 -07003226 }
3227
Florin Coras99368312018-08-02 10:45:44 -07003228 if (ep)
3229 {
3230 if (session->transport.is_ip4)
Dave Barach178cf492018-11-13 16:34:13 -05003231 clib_memcpy_fast (ep->ip, &session->transport.rmt_ip.ip4,
3232 sizeof (ip4_address_t));
Florin Coras99368312018-08-02 10:45:44 -07003233 else
Dave Barach178cf492018-11-13 16:34:13 -05003234 clib_memcpy_fast (ep->ip, &session->transport.rmt_ip.ip6,
3235 sizeof (ip6_address_t));
Florin Coras99368312018-08-02 10:45:44 -07003236 }
Florin Coras460dce62018-07-27 05:45:06 -07003237
Stevenac1f96d2017-10-24 16:03:58 -07003238 return rv;
3239}
3240
3241int
Florin Coras134a9962018-08-28 11:32:04 -07003242vppcom_session_sendto (uint32_t session_handle, void *buffer,
Stevenac1f96d2017-10-24 16:03:58 -07003243 uint32_t buflen, int flags, vppcom_endpt_t * ep)
3244{
Dave Wallace617dffa2017-10-26 14:47:06 -04003245 if (!buffer)
3246 return VPPCOM_EINVAL;
3247
3248 if (ep)
3249 {
3250 // TBD
3251 return VPPCOM_EINVAL;
3252 }
3253
3254 if (flags)
3255 {
3256 // TBD check the flags and do the right thing
Florin Coras0d427d82018-06-27 03:24:07 -07003257 VDBG (2, "VCL<%d>: handling flags 0x%u (%d) not implemented yet.",
3258 getpid (), flags, flags);
Dave Wallace617dffa2017-10-26 14:47:06 -04003259 }
3260
Florin Coras134a9962018-08-28 11:32:04 -07003261 return (vppcom_session_write (session_handle, buffer, buflen));
Stevenac1f96d2017-10-24 16:03:58 -07003262}
3263
Dave Wallace048b1d62018-01-03 22:24:41 -05003264int
3265vppcom_poll (vcl_poll_t * vp, uint32_t n_sids, double wait_for_time)
3266{
Florin Coras134a9962018-08-28 11:32:04 -07003267 vcl_worker_t *wrk = vcl_worker_get_current ();
3268 f64 timeout = clib_time_now (&wrk->clib_time) + wait_for_time;
Dave Wallace048b1d62018-01-03 22:24:41 -05003269 u32 i, keep_trying = 1;
Florin Coras6917b942018-11-13 22:44:54 -08003270 svm_msg_q_msg_t msg;
3271 session_event_t *e;
Dave Wallace048b1d62018-01-03 22:24:41 -05003272 int rv, num_ev = 0;
3273
Florin Coras0d427d82018-06-27 03:24:07 -07003274 VDBG (3, "VCL<%d>: vp %p, nsids %u, wait_for_time %f",
3275 getpid (), vp, n_sids, wait_for_time);
Dave Wallace048b1d62018-01-03 22:24:41 -05003276
3277 if (!vp)
3278 return VPPCOM_EFAULT;
3279
3280 do
3281 {
Florin Coras7e12d942018-06-27 14:32:43 -07003282 vcl_session_t *session;
Dave Wallace048b1d62018-01-03 22:24:41 -05003283
Florin Coras6917b942018-11-13 22:44:54 -08003284 /* Dequeue all events and drop all unhandled io events */
3285 while (svm_msg_q_sub (wrk->app_event_queue, &msg, SVM_Q_NOWAIT, 0) == 0)
3286 {
3287 e = svm_msg_q_msg_data (wrk->app_event_queue, &msg);
3288 vcl_handle_mq_event (wrk, e);
3289 svm_msg_q_free_msg (wrk->app_event_queue, &msg);
3290 }
3291 vec_reset_length (wrk->unhandled_evts_vector);
3292
Dave Wallace048b1d62018-01-03 22:24:41 -05003293 for (i = 0; i < n_sids; i++)
3294 {
Florin Coras134a9962018-08-28 11:32:04 -07003295 session = vcl_session_get (wrk, vp[i].sid);
Florin Coras070453d2018-08-24 17:04:27 -07003296 if (!session)
Florin Coras6917b942018-11-13 22:44:54 -08003297 {
3298 vp[i].revents = POLLHUP;
3299 num_ev++;
3300 continue;
3301 }
Dave Wallace048b1d62018-01-03 22:24:41 -05003302
Florin Coras6917b942018-11-13 22:44:54 -08003303 vp[i].revents = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -05003304
3305 if (POLLIN & vp[i].events)
3306 {
Florin Coras54693d22018-07-17 10:46:29 -07003307 rv = vppcom_session_read_ready (session);
Dave Wallace048b1d62018-01-03 22:24:41 -05003308 if (rv > 0)
3309 {
Florin Coras6917b942018-11-13 22:44:54 -08003310 vp[i].revents |= POLLIN;
Dave Wallace048b1d62018-01-03 22:24:41 -05003311 num_ev++;
3312 }
3313 else if (rv < 0)
3314 {
3315 switch (rv)
3316 {
3317 case VPPCOM_ECONNRESET:
Florin Coras6917b942018-11-13 22:44:54 -08003318 vp[i].revents = POLLHUP;
Dave Wallace048b1d62018-01-03 22:24:41 -05003319 break;
3320
3321 default:
Florin Coras6917b942018-11-13 22:44:54 -08003322 vp[i].revents = POLLERR;
Dave Wallace048b1d62018-01-03 22:24:41 -05003323 break;
3324 }
3325 num_ev++;
3326 }
3327 }
3328
3329 if (POLLOUT & vp[i].events)
3330 {
Florin Coras134a9962018-08-28 11:32:04 -07003331 rv = vppcom_session_write_ready (session);
Dave Wallace048b1d62018-01-03 22:24:41 -05003332 if (rv > 0)
3333 {
Florin Coras6917b942018-11-13 22:44:54 -08003334 vp[i].revents |= POLLOUT;
Dave Wallace048b1d62018-01-03 22:24:41 -05003335 num_ev++;
3336 }
3337 else if (rv < 0)
3338 {
3339 switch (rv)
3340 {
3341 case VPPCOM_ECONNRESET:
Florin Coras6917b942018-11-13 22:44:54 -08003342 vp[i].revents = POLLHUP;
Dave Wallace048b1d62018-01-03 22:24:41 -05003343 break;
3344
3345 default:
Florin Coras6917b942018-11-13 22:44:54 -08003346 vp[i].revents = POLLERR;
Dave Wallace048b1d62018-01-03 22:24:41 -05003347 break;
3348 }
3349 num_ev++;
3350 }
3351 }
3352
Dave Wallace7e607a72018-06-18 18:41:32 -04003353 if (0) // Note "done:" label used by VCL_SESSION_LOCK_AND_GET()
Dave Wallace048b1d62018-01-03 22:24:41 -05003354 {
Florin Coras6917b942018-11-13 22:44:54 -08003355 vp[i].revents = POLLNVAL;
Dave Wallace048b1d62018-01-03 22:24:41 -05003356 num_ev++;
3357 }
3358 }
3359 if (wait_for_time != -1)
Florin Coras134a9962018-08-28 11:32:04 -07003360 keep_trying = (clib_time_now (&wrk->clib_time) <= timeout) ? 1 : 0;
Dave Wallace048b1d62018-01-03 22:24:41 -05003361 }
3362 while ((num_ev == 0) && keep_trying);
3363
3364 if (VPPCOM_DEBUG > 3)
3365 {
3366 clib_warning ("VCL<%d>: returning %d", getpid (), num_ev);
3367 for (i = 0; i < n_sids; i++)
3368 {
3369 clib_warning ("VCL<%d>: vp[%d].sid %d (0x%x), .events 0x%x, "
3370 ".revents 0x%x", getpid (), i, vp[i].sid, vp[i].sid,
Florin Coras6917b942018-11-13 22:44:54 -08003371 vp[i].events, vp[i].revents);
Dave Wallace048b1d62018-01-03 22:24:41 -05003372 }
3373 }
3374 return num_ev;
3375}
3376
Florin Coras99368312018-08-02 10:45:44 -07003377int
3378vppcom_mq_epoll_fd (void)
3379{
Florin Coras134a9962018-08-28 11:32:04 -07003380 vcl_worker_t *wrk = vcl_worker_get_current ();
3381 return wrk->mqs_epfd;
3382}
3383
3384int
3385vppcom_session_index (uint32_t session_handle)
3386{
3387 return session_handle & 0xFFFFFF;
3388}
3389
3390int
Florin Coras30e273b2018-11-27 00:04:59 -08003391vppcom_session_handle (uint32_t session_index)
3392{
Florin Coras47c40e22018-11-26 17:01:36 -08003393 return (vcl_get_worker_index () << 24) | session_index;
Florin Coras30e273b2018-11-27 00:04:59 -08003394}
3395
3396int
Florin Coras134a9962018-08-28 11:32:04 -07003397vppcom_worker_register (void)
3398{
Florin Coras47c40e22018-11-26 17:01:36 -08003399 if (!vcl_worker_alloc_and_init ())
3400 return VPPCOM_EEXIST;
3401
3402 if (vcl_worker_set_bapi ())
3403 return VPPCOM_EEXIST;
3404
3405 if (vcl_worker_register_with_vpp ())
3406 return VPPCOM_EEXIST;
3407
3408 return VPPCOM_OK;
Florin Coras99368312018-08-02 10:45:44 -07003409}
3410
Florin Corasdfe4cf42018-11-28 22:13:45 -08003411int
3412vppcom_worker_index (void)
3413{
3414 return vcl_get_worker_index ();
3415}
3416
Dave Wallacee22aa742017-10-20 12:30:38 -04003417/*
3418 * fd.io coding-style-patch-verification: ON
3419 *
3420 * Local Variables:
3421 * eval: (c-set-style "gnu")
3422 * End:
3423 */