blob: c91d0f4b8b6bf51f7eaf9d171f53f423c69cba95 [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 Corasd85de682018-11-29 17:02:29 -080025static int
26vcl_wait_for_segment (u64 segment_handle)
Florin Coras54693d22018-07-17 10:46:29 -070027{
Florin Corasd85de682018-11-29 17:02:29 -080028 vcl_worker_t *wrk = vcl_worker_get_current ();
29 u32 wait_for_seconds = 10, segment_index;
30 f64 timeout;
Florin Coras54693d22018-07-17 10:46:29 -070031
Florin Corasd85de682018-11-29 17:02:29 -080032 if (segment_handle == VCL_INVALID_SEGMENT_HANDLE)
33 return 1;
Florin Coras54693d22018-07-17 10:46:29 -070034
Florin Corasd85de682018-11-29 17:02:29 -080035 timeout = clib_time_now (&wrk->clib_time) + wait_for_seconds;
36 while (clib_time_now (&wrk->clib_time) < timeout)
Florin Coras54693d22018-07-17 10:46:29 -070037 {
Florin Corasd85de682018-11-29 17:02:29 -080038 segment_index = vcl_segment_table_lookup (segment_handle);
39 if (segment_index != VCL_INVALID_SEGMENT_INDEX)
40 return 0;
41 usleep (10);
Florin Coras54693d22018-07-17 10:46:29 -070042 }
Florin Corasd85de682018-11-29 17:02:29 -080043 return 1;
Florin Coras54693d22018-07-17 10:46:29 -070044}
45
Florin Coras30e79c22019-01-02 19:31:22 -080046static inline int
47vcl_mq_dequeue_batch (vcl_worker_t * wrk, svm_msg_q_t * mq)
48{
49 svm_msg_q_msg_t *msg;
50 u32 n_msgs;
51 int i;
52
53 n_msgs = svm_msg_q_size (mq);
54 for (i = 0; i < n_msgs; i++)
55 {
56 vec_add2 (wrk->mq_msg_vector, msg, 1);
57 svm_msg_q_sub_w_lock (mq, msg);
58 }
59 return n_msgs;
60}
61
Florin Coras697faea2018-06-27 17:10:49 -070062const char *
Dave Wallace543852a2017-08-03 02:11:34 -040063vppcom_session_state_str (session_state_t state)
64{
65 char *st;
66
67 switch (state)
68 {
69 case STATE_START:
70 st = "STATE_START";
71 break;
72
73 case STATE_CONNECT:
74 st = "STATE_CONNECT";
75 break;
76
77 case STATE_LISTEN:
78 st = "STATE_LISTEN";
79 break;
80
81 case STATE_ACCEPT:
82 st = "STATE_ACCEPT";
83 break;
84
Florin Coras3c7d4f92018-12-14 11:28:43 -080085 case STATE_VPP_CLOSING:
86 st = "STATE_VPP_CLOSING";
Dave Wallace4878cbe2017-11-21 03:45:09 -050087 break;
88
Dave Wallace543852a2017-08-03 02:11:34 -040089 case STATE_DISCONNECT:
90 st = "STATE_DISCONNECT";
91 break;
92
93 case STATE_FAILED:
94 st = "STATE_FAILED";
95 break;
96
97 default:
98 st = "UNKNOWN_STATE";
99 break;
100 }
101
102 return st;
103}
104
Dave Wallace543852a2017-08-03 02:11:34 -0400105u8 *
106format_ip4_address (u8 * s, va_list * args)
107{
108 u8 *a = va_arg (*args, u8 *);
109 return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
110}
111
112u8 *
113format_ip6_address (u8 * s, va_list * args)
114{
115 ip6_address_t *a = va_arg (*args, ip6_address_t *);
116 u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
117
118 i_max_n_zero = ARRAY_LEN (a->as_u16);
119 max_n_zeros = 0;
120 i_first_zero = i_max_n_zero;
121 n_zeros = 0;
122 for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
123 {
124 u32 is_zero = a->as_u16[i] == 0;
125 if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
126 {
127 i_first_zero = i;
128 n_zeros = 0;
129 }
130 n_zeros += is_zero;
131 if ((!is_zero && n_zeros > max_n_zeros)
132 || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
133 {
134 i_max_n_zero = i_first_zero;
135 max_n_zeros = n_zeros;
136 i_first_zero = ARRAY_LEN (a->as_u16);
137 n_zeros = 0;
138 }
139 }
140
141 last_double_colon = 0;
142 for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
143 {
144 if (i == i_max_n_zero && max_n_zeros > 1)
145 {
146 s = format (s, "::");
147 i += max_n_zeros - 1;
148 last_double_colon = 1;
149 }
150 else
151 {
152 s = format (s, "%s%x",
153 (last_double_colon || i == 0) ? "" : ":",
154 clib_net_to_host_u16 (a->as_u16[i]));
155 last_double_colon = 0;
156 }
157 }
158
159 return s;
160}
161
162/* Format an IP46 address. */
163u8 *
164format_ip46_address (u8 * s, va_list * args)
165{
166 ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
167 ip46_type_t type = va_arg (*args, ip46_type_t);
168 int is_ip4 = 1;
169
170 switch (type)
171 {
172 case IP46_TYPE_ANY:
173 is_ip4 = ip46_address_is_ip4 (ip46);
174 break;
175 case IP46_TYPE_IP4:
176 is_ip4 = 1;
177 break;
178 case IP46_TYPE_IP6:
179 is_ip4 = 0;
180 break;
181 }
182
183 return is_ip4 ?
184 format (s, "%U", format_ip4_address, &ip46->ip4) :
185 format (s, "%U", format_ip6_address, &ip46->ip6);
186}
187
Florin Coras697faea2018-06-27 17:10:49 -0700188/*
189 * VPPCOM Utility Functions
190 */
191
Florin Coras697faea2018-06-27 17:10:49 -0700192
Florin Coras54693d22018-07-17 10:46:29 -0700193static void
194vcl_send_session_accepted_reply (svm_msg_q_t * mq, u32 context,
195 session_handle_t handle, int retval)
196{
197 app_session_evt_t _app_evt, *app_evt = &_app_evt;
198 session_accepted_reply_msg_t *rmp;
199 app_alloc_ctrl_evt_to_vpp (mq, app_evt, SESSION_CTRL_EVT_ACCEPTED_REPLY);
200 rmp = (session_accepted_reply_msg_t *) app_evt->evt->data;
201 rmp->handle = handle;
202 rmp->context = context;
203 rmp->retval = retval;
204 app_send_ctrl_evt_to_vpp (mq, app_evt);
205}
206
Florin Coras99368312018-08-02 10:45:44 -0700207static void
208vcl_send_session_disconnected_reply (svm_msg_q_t * mq, u32 context,
209 session_handle_t handle, int retval)
210{
211 app_session_evt_t _app_evt, *app_evt = &_app_evt;
212 session_disconnected_reply_msg_t *rmp;
213 app_alloc_ctrl_evt_to_vpp (mq, app_evt,
214 SESSION_CTRL_EVT_DISCONNECTED_REPLY);
215 rmp = (session_disconnected_reply_msg_t *) app_evt->evt->data;
216 rmp->handle = handle;
217 rmp->context = context;
218 rmp->retval = retval;
219 app_send_ctrl_evt_to_vpp (mq, app_evt);
220}
221
Florin Corasc9fbd662018-08-24 12:59:56 -0700222static void
223vcl_send_session_reset_reply (svm_msg_q_t * mq, u32 context,
224 session_handle_t handle, int retval)
225{
226 app_session_evt_t _app_evt, *app_evt = &_app_evt;
227 session_reset_reply_msg_t *rmp;
228 app_alloc_ctrl_evt_to_vpp (mq, app_evt, SESSION_CTRL_EVT_RESET_REPLY);
229 rmp = (session_reset_reply_msg_t *) app_evt->evt->data;
230 rmp->handle = handle;
231 rmp->context = context;
232 rmp->retval = retval;
233 app_send_ctrl_evt_to_vpp (mq, app_evt);
234}
235
Florin Coras30e79c22019-01-02 19:31:22 -0800236void
237vcl_send_session_worker_update (vcl_worker_t * wrk, vcl_session_t * s,
238 u32 wrk_index)
239{
240 app_session_evt_t _app_evt, *app_evt = &_app_evt;
241 session_worker_update_msg_t *mp;
242 svm_msg_q_t *mq;
243
244 mq = vcl_session_vpp_evt_q (wrk, s);
245 app_alloc_ctrl_evt_to_vpp (mq, app_evt, SESSION_CTRL_EVT_WORKER_UPDATE);
246 mp = (session_worker_update_msg_t *) app_evt->evt->data;
247 mp->client_index = wrk->my_client_index;
248 mp->handle = s->vpp_handle;
249 mp->req_wrk_index = wrk->vpp_wrk_index;
250 mp->wrk_index = wrk_index;
251 app_send_ctrl_evt_to_vpp (mq, app_evt);
252}
253
Florin Coras54693d22018-07-17 10:46:29 -0700254static u32
Florin Coras134a9962018-08-28 11:32:04 -0700255vcl_session_accepted_handler (vcl_worker_t * wrk, session_accepted_msg_t * mp)
Florin Coras54693d22018-07-17 10:46:29 -0700256{
257 vcl_session_t *session, *listen_session;
258 svm_fifo_t *rx_fifo, *tx_fifo;
Florin Coras134a9962018-08-28 11:32:04 -0700259 u32 vpp_wrk_index;
Florin Coras99368312018-08-02 10:45:44 -0700260 svm_msg_q_t *evt_q;
Florin Coras54693d22018-07-17 10:46:29 -0700261
Florin Coras134a9962018-08-28 11:32:04 -0700262 session = vcl_session_alloc (wrk);
Florin Coras99368312018-08-02 10:45:44 -0700263
Florin Coras134a9962018-08-28 11:32:04 -0700264 listen_session = vcl_session_table_lookup_listener (wrk,
265 mp->listener_handle);
Florin Coras54693d22018-07-17 10:46:29 -0700266 if (!listen_session)
267 {
268 svm_msg_q_t *evt_q;
269 evt_q = uword_to_pointer (mp->vpp_event_queue_address, svm_msg_q_t *);
270 clib_warning ("VCL<%d>: ERROR: couldn't find listen session: "
271 "unknown vpp listener handle %llx",
272 getpid (), mp->listener_handle);
273 vcl_send_session_accepted_reply (evt_q, mp->context, mp->handle,
274 VNET_API_ERROR_INVALID_ARGUMENT);
Florin Coras134a9962018-08-28 11:32:04 -0700275 vcl_session_free (wrk, session);
Florin Coras54693d22018-07-17 10:46:29 -0700276 return VCL_INVALID_SESSION_INDEX;
277 }
278
Florin Coras54693d22018-07-17 10:46:29 -0700279 rx_fifo = uword_to_pointer (mp->server_rx_fifo, svm_fifo_t *);
280 tx_fifo = uword_to_pointer (mp->server_tx_fifo, svm_fifo_t *);
281
282 if (mp->server_event_queue_address)
283 {
284 session->vpp_evt_q = uword_to_pointer (mp->client_event_queue_address,
285 svm_msg_q_t *);
286 session->our_evt_q = uword_to_pointer (mp->server_event_queue_address,
287 svm_msg_q_t *);
Florin Corasd85de682018-11-29 17:02:29 -0800288 if (vcl_wait_for_segment (mp->segment_handle))
289 {
290 clib_warning ("segment for session %u couldn't be mounted!",
291 session->session_index);
292 return VCL_INVALID_SESSION_INDEX;
293 }
Florin Coras134a9962018-08-28 11:32:04 -0700294 rx_fifo->master_session_index = session->session_index;
295 tx_fifo->master_session_index = session->session_index;
Florin Coras21795132018-09-09 09:40:51 -0700296 rx_fifo->master_thread_index = vcl_get_worker_index ();
297 tx_fifo->master_thread_index = vcl_get_worker_index ();
Florin Coras134a9962018-08-28 11:32:04 -0700298 vec_validate (wrk->vpp_event_queues, 0);
Florin Coras99368312018-08-02 10:45:44 -0700299 evt_q = uword_to_pointer (mp->vpp_event_queue_address, svm_msg_q_t *);
Florin Coras134a9962018-08-28 11:32:04 -0700300 wrk->vpp_event_queues[0] = evt_q;
Florin Coras54693d22018-07-17 10:46:29 -0700301 }
302 else
303 {
304 session->vpp_evt_q = uword_to_pointer (mp->vpp_event_queue_address,
305 svm_msg_q_t *);
Florin Coras134a9962018-08-28 11:32:04 -0700306 rx_fifo->client_session_index = session->session_index;
307 tx_fifo->client_session_index = session->session_index;
Florin Coras21795132018-09-09 09:40:51 -0700308 rx_fifo->client_thread_index = vcl_get_worker_index ();
309 tx_fifo->client_thread_index = vcl_get_worker_index ();
Florin Coras99368312018-08-02 10:45:44 -0700310 vpp_wrk_index = tx_fifo->master_thread_index;
Florin Coras134a9962018-08-28 11:32:04 -0700311 vec_validate (wrk->vpp_event_queues, vpp_wrk_index);
312 wrk->vpp_event_queues[vpp_wrk_index] = session->vpp_evt_q;
Florin Coras54693d22018-07-17 10:46:29 -0700313 }
314
315 session->vpp_handle = mp->handle;
Florin Coras3c7d4f92018-12-14 11:28:43 -0800316 session->vpp_thread_index = rx_fifo->master_thread_index;
Florin Coras54693d22018-07-17 10:46:29 -0700317 session->client_context = mp->context;
318 session->rx_fifo = rx_fifo;
319 session->tx_fifo = tx_fifo;
320
321 session->session_state = STATE_ACCEPT;
322 session->transport.rmt_port = mp->port;
323 session->transport.is_ip4 = mp->is_ip4;
Dave Barach178cf492018-11-13 16:34:13 -0500324 clib_memcpy_fast (&session->transport.rmt_ip, mp->ip,
325 sizeof (ip46_address_t));
Florin Coras54693d22018-07-17 10:46:29 -0700326
Florin Coras134a9962018-08-28 11:32:04 -0700327 vcl_session_table_add_vpp_handle (wrk, mp->handle, session->session_index);
Florin Coras54693d22018-07-17 10:46:29 -0700328 session->transport.lcl_port = listen_session->transport.lcl_port;
329 session->transport.lcl_ip = listen_session->transport.lcl_ip;
Florin Coras460dce62018-07-27 05:45:06 -0700330 session->session_type = listen_session->session_type;
331 session->is_dgram = session->session_type == VPPCOM_PROTO_UDP;
Florin Coras54693d22018-07-17 10:46:29 -0700332
333 VDBG (1, "VCL<%d>: vpp handle 0x%llx, sid %u: client accept request from %s"
Florin Coras134a9962018-08-28 11:32:04 -0700334 " address %U port %d queue %p!", getpid (), mp->handle,
335 session->session_index,
Florin Coras54693d22018-07-17 10:46:29 -0700336 mp->is_ip4 ? "IPv4" : "IPv6", format_ip46_address, &mp->ip,
337 mp->is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6,
338 clib_net_to_host_u16 (mp->port), session->vpp_evt_q);
339 vcl_evt (VCL_EVT_ACCEPT, session, listen_session, session_index);
340
Florin Coras134a9962018-08-28 11:32:04 -0700341 return session->session_index;
Florin Coras54693d22018-07-17 10:46:29 -0700342}
343
344static u32
Florin Coras134a9962018-08-28 11:32:04 -0700345vcl_session_connected_handler (vcl_worker_t * wrk,
346 session_connected_msg_t * mp)
Florin Coras54693d22018-07-17 10:46:29 -0700347{
Florin Coras99368312018-08-02 10:45:44 -0700348 u32 session_index, vpp_wrk_index;
Florin Coras54693d22018-07-17 10:46:29 -0700349 svm_fifo_t *rx_fifo, *tx_fifo;
Florin Coras99368312018-08-02 10:45:44 -0700350 vcl_session_t *session = 0;
351 svm_msg_q_t *evt_q;
Florin Coras54693d22018-07-17 10:46:29 -0700352
353 session_index = mp->context;
Florin Coras134a9962018-08-28 11:32:04 -0700354 session = vcl_session_get (wrk, session_index);
Florin Coras070453d2018-08-24 17:04:27 -0700355 if (!session)
356 {
357 clib_warning ("[%s] ERROR: vpp handle 0x%llx, sid %u: "
358 "Invalid session index (%u)!",
359 getpid (), mp->handle, session_index);
360 return VCL_INVALID_SESSION_INDEX;
361 }
Florin Coras54693d22018-07-17 10:46:29 -0700362 if (mp->retval)
363 {
Florin Coras070453d2018-08-24 17:04:27 -0700364 clib_warning ("VCL<%d>: ERROR: sid %u: connect failed! %U", getpid (),
Florin Coras21795132018-09-09 09:40:51 -0700365 session_index, format_api_error, ntohl (mp->retval));
Florin Coras070453d2018-08-24 17:04:27 -0700366 session->session_state = STATE_FAILED;
367 session->vpp_handle = mp->handle;
368 return session_index;
Florin Coras54693d22018-07-17 10:46:29 -0700369 }
370
Florin Coras460dce62018-07-27 05:45:06 -0700371 rx_fifo = uword_to_pointer (mp->server_rx_fifo, svm_fifo_t *);
372 tx_fifo = uword_to_pointer (mp->server_tx_fifo, svm_fifo_t *);
Florin Corasd85de682018-11-29 17:02:29 -0800373 if (vcl_wait_for_segment (mp->segment_handle))
374 {
375 clib_warning ("segment for session %u couldn't be mounted!",
376 session->session_index);
377 return VCL_INVALID_SESSION_INDEX;
378 }
379
Florin Coras460dce62018-07-27 05:45:06 -0700380 rx_fifo->client_session_index = session_index;
381 tx_fifo->client_session_index = session_index;
Florin Coras21795132018-09-09 09:40:51 -0700382 rx_fifo->client_thread_index = vcl_get_worker_index ();
383 tx_fifo->client_thread_index = vcl_get_worker_index ();
Florin Coras460dce62018-07-27 05:45:06 -0700384
Florin Coras54693d22018-07-17 10:46:29 -0700385 if (mp->client_event_queue_address)
386 {
387 session->vpp_evt_q = uword_to_pointer (mp->server_event_queue_address,
388 svm_msg_q_t *);
389 session->our_evt_q = uword_to_pointer (mp->client_event_queue_address,
390 svm_msg_q_t *);
Florin Coras99368312018-08-02 10:45:44 -0700391
Florin Coras134a9962018-08-28 11:32:04 -0700392 vec_validate (wrk->vpp_event_queues, 0);
Florin Coras99368312018-08-02 10:45:44 -0700393 evt_q = uword_to_pointer (mp->vpp_event_queue_address, svm_msg_q_t *);
Florin Coras134a9962018-08-28 11:32:04 -0700394 wrk->vpp_event_queues[0] = evt_q;
Florin Coras54693d22018-07-17 10:46:29 -0700395 }
396 else
Florin Coras99368312018-08-02 10:45:44 -0700397 {
398 session->vpp_evt_q = uword_to_pointer (mp->vpp_event_queue_address,
399 svm_msg_q_t *);
400 vpp_wrk_index = tx_fifo->master_thread_index;
Florin Coras134a9962018-08-28 11:32:04 -0700401 vec_validate (wrk->vpp_event_queues, vpp_wrk_index);
402 wrk->vpp_event_queues[vpp_wrk_index] = session->vpp_evt_q;
Florin Coras99368312018-08-02 10:45:44 -0700403 }
Florin Coras54693d22018-07-17 10:46:29 -0700404
Florin Coras54693d22018-07-17 10:46:29 -0700405 session->rx_fifo = rx_fifo;
406 session->tx_fifo = tx_fifo;
407 session->vpp_handle = mp->handle;
Florin Coras3c7d4f92018-12-14 11:28:43 -0800408 session->vpp_thread_index = rx_fifo->master_thread_index;
Florin Coras54693d22018-07-17 10:46:29 -0700409 session->transport.is_ip4 = mp->is_ip4;
Dave Barach178cf492018-11-13 16:34:13 -0500410 clib_memcpy_fast (&session->transport.lcl_ip, mp->lcl_ip,
411 sizeof (session->transport.lcl_ip));
Florin Coras54693d22018-07-17 10:46:29 -0700412 session->transport.lcl_port = mp->lcl_port;
413 session->session_state = STATE_CONNECT;
414
415 /* Add it to lookup table */
Florin Coras3c7d4f92018-12-14 11:28:43 -0800416 vcl_session_table_add_vpp_handle (wrk, mp->handle, session_index);
Florin Coras54693d22018-07-17 10:46:29 -0700417
418 VDBG (1, "VCL<%d>: vpp handle 0x%llx, sid %u: connect succeeded! "
419 "session_rx_fifo %p, refcnt %d, session_tx_fifo %p, refcnt %d",
420 getpid (), mp->handle, session_index, session->rx_fifo,
421 session->rx_fifo->refcnt, session->tx_fifo, session->tx_fifo->refcnt);
Florin Coras070453d2018-08-24 17:04:27 -0700422
Florin Coras54693d22018-07-17 10:46:29 -0700423 return session_index;
424}
425
Florin Coras3c7d4f92018-12-14 11:28:43 -0800426static int
427vcl_flag_accepted_session (vcl_session_t * session, u64 handle, u32 flags)
428{
429 vcl_session_msg_t *accepted_msg;
430 int i;
431
432 for (i = 0; i < vec_len (session->accept_evts_fifo); i++)
433 {
434 accepted_msg = &session->accept_evts_fifo[i];
435 if (accepted_msg->accepted_msg.handle == handle)
436 {
Florin Corasb0f662f2018-12-27 14:51:46 -0800437 accepted_msg->flags |= flags;
Florin Coras3c7d4f92018-12-14 11:28:43 -0800438 return 1;
439 }
440 }
441 return 0;
442}
443
Florin Corasc9fbd662018-08-24 12:59:56 -0700444static u32
Florin Coras134a9962018-08-28 11:32:04 -0700445vcl_session_reset_handler (vcl_worker_t * wrk,
446 session_reset_msg_t * reset_msg)
Florin Corasc9fbd662018-08-24 12:59:56 -0700447{
448 vcl_session_t *session;
449 u32 sid;
450
Florin Coras134a9962018-08-28 11:32:04 -0700451 sid = vcl_session_index_from_vpp_handle (wrk, reset_msg->handle);
452 session = vcl_session_get (wrk, sid);
Florin Corasc9fbd662018-08-24 12:59:56 -0700453 if (!session)
454 {
455 VDBG (0, "request to reset unknown handle 0x%llx", reset_msg->handle);
456 return VCL_INVALID_SESSION_INDEX;
457 }
Florin Coras3c7d4f92018-12-14 11:28:43 -0800458
459 /* Caught a reset before actually accepting the session */
460 if (session->session_state == STATE_LISTEN)
461 {
462
463 if (!vcl_flag_accepted_session (session, reset_msg->handle,
464 VCL_ACCEPTED_F_RESET))
465 VDBG (0, "session was not accepted!");
466 return VCL_INVALID_SESSION_INDEX;
467 }
468
469 session->session_state = STATE_DISCONNECT;
470 VDBG (0, "reset session %u [0x%llx]", sid, reset_msg->handle);
Florin Corasc9fbd662018-08-24 12:59:56 -0700471 return sid;
472}
473
Florin Coras60116992018-08-27 09:52:18 -0700474static u32
Florin Coras134a9962018-08-28 11:32:04 -0700475vcl_session_bound_handler (vcl_worker_t * wrk, session_bound_msg_t * mp)
Florin Coras60116992018-08-27 09:52:18 -0700476{
477 vcl_session_t *session;
478 u32 sid = mp->context;
479
Florin Coras134a9962018-08-28 11:32:04 -0700480 session = vcl_session_get (wrk, sid);
Florin Coras60116992018-08-27 09:52:18 -0700481 if (mp->retval)
482 {
Florin Corasd85de682018-11-29 17:02:29 -0800483 VERR ("vpp handle 0x%llx, sid %u: bind failed: %U", mp->handle, sid,
484 format_api_error, mp->retval);
Florin Coras60116992018-08-27 09:52:18 -0700485 if (session)
486 {
487 session->session_state = STATE_FAILED;
488 session->vpp_handle = mp->handle;
489 return sid;
490 }
491 else
492 {
493 clib_warning ("[%s] ERROR: vpp handle 0x%llx, sid %u: "
494 "Invalid session index (%u)!",
495 getpid (), mp->handle, sid);
496 return VCL_INVALID_SESSION_INDEX;
497 }
498 }
499
500 session->vpp_handle = mp->handle;
501 session->transport.is_ip4 = mp->lcl_is_ip4;
Dave Barach178cf492018-11-13 16:34:13 -0500502 clib_memcpy_fast (&session->transport.lcl_ip, mp->lcl_ip,
503 sizeof (ip46_address_t));
Florin Coras60116992018-08-27 09:52:18 -0700504 session->transport.lcl_port = mp->lcl_port;
Florin Coras134a9962018-08-28 11:32:04 -0700505 vcl_session_table_add_listener (wrk, mp->handle, sid);
Florin Coras60116992018-08-27 09:52:18 -0700506 session->session_state = STATE_LISTEN;
507
508 if (session->is_dgram)
509 {
510 svm_fifo_t *rx_fifo, *tx_fifo;
511 session->vpp_evt_q = uword_to_pointer (mp->vpp_evt_q, svm_msg_q_t *);
512 rx_fifo = uword_to_pointer (mp->rx_fifo, svm_fifo_t *);
513 rx_fifo->client_session_index = sid;
514 tx_fifo = uword_to_pointer (mp->tx_fifo, svm_fifo_t *);
515 tx_fifo->client_session_index = sid;
516 session->rx_fifo = rx_fifo;
517 session->tx_fifo = tx_fifo;
518 }
519
Florin Coras05ecfcc2018-12-12 18:19:39 -0800520 VDBG (0, "session %u [0x%llx]: listen succeeded!", sid, mp->handle);
Florin Coras60116992018-08-27 09:52:18 -0700521 return sid;
522}
523
Florin Coras3c7d4f92018-12-14 11:28:43 -0800524static vcl_session_t *
525vcl_session_accepted (vcl_worker_t * wrk, session_accepted_msg_t * msg)
526{
527 vcl_session_msg_t *vcl_msg;
528 vcl_session_t *session;
529
530 session = vcl_session_get_w_vpp_handle (wrk, msg->handle);
531 if (PREDICT_FALSE (session != 0))
Florin Corasb0f662f2018-12-27 14:51:46 -0800532 VWRN ("session overlap handle %lu state %u!", msg->handle,
533 session->session_state);
Florin Coras3c7d4f92018-12-14 11:28:43 -0800534
535 session = vcl_session_table_lookup_listener (wrk, msg->listener_handle);
536 if (!session)
537 {
538 VERR ("couldn't find listen session: listener handle %llx",
539 msg->listener_handle);
540 return 0;
541 }
542
543 clib_fifo_add2 (session->accept_evts_fifo, vcl_msg);
544 vcl_msg->accepted_msg = *msg;
545 /* Session handle points to listener until fully accepted by app */
546 vcl_session_table_add_vpp_handle (wrk, msg->handle, session->session_index);
547
548 return session;
549}
550
551static vcl_session_t *
552vcl_session_disconnected_handler (vcl_worker_t * wrk,
553 session_disconnected_msg_t * msg)
554{
555 vcl_session_t *session;
556
557 session = vcl_session_get_w_vpp_handle (wrk, msg->handle);
558 if (!session)
559 {
560 VDBG (0, "request to disconnect unknown handle 0x%llx", msg->handle);
561 return 0;
562 }
563
564 /* Caught a disconnect before actually accepting the session */
565 if (session->session_state == STATE_LISTEN)
566 {
Florin Coras3c7d4f92018-12-14 11:28:43 -0800567 if (!vcl_flag_accepted_session (session, msg->handle,
568 VCL_ACCEPTED_F_CLOSED))
569 VDBG (0, "session was not accepted!");
570 return 0;
571 }
572
573 session->session_state = STATE_VPP_CLOSING;
574 return session;
575}
576
Florin Coras30e79c22019-01-02 19:31:22 -0800577static void
578vcl_session_req_worker_update_handler (vcl_worker_t * wrk, void *data)
579{
580 session_req_worker_update_msg_t *msg;
581 vcl_session_t *s;
582
583 msg = (session_req_worker_update_msg_t *) data;
584 s = vcl_session_get_w_vpp_handle (wrk, msg->session_handle);
585 if (!s)
586 return;
587
588 vec_add1 (wrk->pending_session_wrk_updates, s->session_index);
589}
590
591static void
592vcl_session_worker_update_reply_handler (vcl_worker_t * wrk, void *data)
593{
594 session_worker_update_reply_msg_t *msg;
595 vcl_session_t *s;
596
597 msg = (session_worker_update_reply_msg_t *) data;
598 s = vcl_session_get_w_vpp_handle (wrk, msg->handle);
599 if (!s)
600 {
601 VDBG (0, "unknown handle 0x%llx", msg->handle);
602 return;
603 }
604 if (vcl_wait_for_segment (msg->segment_handle))
605 {
606 clib_warning ("segment for session %u couldn't be mounted!",
607 s->session_index);
608 return;
609 }
610 s->rx_fifo = uword_to_pointer (msg->rx_fifo, svm_fifo_t *);
611 s->tx_fifo = uword_to_pointer (msg->tx_fifo, svm_fifo_t *);
612
613 s->rx_fifo->client_session_index = s->session_index;
614 s->tx_fifo->client_session_index = s->session_index;
615 s->rx_fifo->client_thread_index = wrk->wrk_index;
616 s->tx_fifo->client_thread_index = wrk->wrk_index;
617 s->session_state = STATE_UPDATED;
618
Florin Coras30e79c22019-01-02 19:31:22 -0800619 VDBG (0, "session %u[0x%llx] moved to worker %u", s->session_index,
620 s->vpp_handle, wrk->wrk_index);
621}
622
Florin Coras86f04502018-09-12 16:08:01 -0700623static int
624vcl_handle_mq_event (vcl_worker_t * wrk, session_event_t * e)
Florin Coras54693d22018-07-17 10:46:29 -0700625{
Florin Coras54693d22018-07-17 10:46:29 -0700626 session_disconnected_msg_t *disconnected_msg;
Florin Coras54693d22018-07-17 10:46:29 -0700627 vcl_session_t *session;
Florin Coras54693d22018-07-17 10:46:29 -0700628
629 switch (e->event_type)
630 {
631 case FIFO_EVENT_APP_RX:
Florin Coras86f04502018-09-12 16:08:01 -0700632 case FIFO_EVENT_APP_TX:
633 case SESSION_IO_EVT_CT_RX:
634 case SESSION_IO_EVT_CT_TX:
635 vec_add1 (wrk->unhandled_evts_vector, *e);
Florin Coras54693d22018-07-17 10:46:29 -0700636 break;
637 case SESSION_CTRL_EVT_ACCEPTED:
Florin Coras3c7d4f92018-12-14 11:28:43 -0800638 vcl_session_accepted (wrk, (session_accepted_msg_t *) e->data);
Florin Coras54693d22018-07-17 10:46:29 -0700639 break;
640 case SESSION_CTRL_EVT_CONNECTED:
Florin Coras134a9962018-08-28 11:32:04 -0700641 vcl_session_connected_handler (wrk,
642 (session_connected_msg_t *) e->data);
Florin Coras54693d22018-07-17 10:46:29 -0700643 break;
644 case SESSION_CTRL_EVT_DISCONNECTED:
645 disconnected_msg = (session_disconnected_msg_t *) e->data;
Florin Coras3c7d4f92018-12-14 11:28:43 -0800646 session = vcl_session_disconnected_handler (wrk, disconnected_msg);
Florin Corasc9fbd662018-08-24 12:59:56 -0700647 if (!session)
Florin Coras3c7d4f92018-12-14 11:28:43 -0800648 break;
Florin Coras54693d22018-07-17 10:46:29 -0700649 session->session_state = STATE_DISCONNECT;
Florin Coras3c7d4f92018-12-14 11:28:43 -0800650 VDBG (0, "disconnected session %u [0x%llx]", session->session_index,
651 session->vpp_handle);
Florin Corasc9fbd662018-08-24 12:59:56 -0700652 break;
653 case SESSION_CTRL_EVT_RESET:
Florin Coras134a9962018-08-28 11:32:04 -0700654 vcl_session_reset_handler (wrk, (session_reset_msg_t *) e->data);
Florin Coras60116992018-08-27 09:52:18 -0700655 break;
656 case SESSION_CTRL_EVT_BOUND:
Florin Coras134a9962018-08-28 11:32:04 -0700657 vcl_session_bound_handler (wrk, (session_bound_msg_t *) e->data);
Florin Coras54693d22018-07-17 10:46:29 -0700658 break;
Florin Coras30e79c22019-01-02 19:31:22 -0800659 case SESSION_CTRL_EVT_REQ_WORKER_UPDATE:
660 vcl_session_req_worker_update_handler (wrk, e->data);
661 break;
662 case SESSION_CTRL_EVT_WORKER_UPDATE_REPLY:
663 vcl_session_worker_update_reply_handler (wrk, e->data);
664 break;
Florin Coras54693d22018-07-17 10:46:29 -0700665 default:
666 clib_warning ("unhandled %u", e->event_type);
667 }
668 return VPPCOM_OK;
669}
670
Florin Coras30e79c22019-01-02 19:31:22 -0800671static int
Florin Coras697faea2018-06-27 17:10:49 -0700672vppcom_wait_for_session_state_change (u32 session_index,
673 session_state_t state,
674 f64 wait_for_time)
675{
Florin Coras134a9962018-08-28 11:32:04 -0700676 vcl_worker_t *wrk = vcl_worker_get_current ();
677 f64 timeout = clib_time_now (&wrk->clib_time) + wait_for_time;
Florin Coras697faea2018-06-27 17:10:49 -0700678 vcl_session_t *volatile session;
Florin Coras54693d22018-07-17 10:46:29 -0700679 svm_msg_q_msg_t msg;
680 session_event_t *e;
Dave Wallace543852a2017-08-03 02:11:34 -0400681
Florin Coras697faea2018-06-27 17:10:49 -0700682 do
Dave Wallace543852a2017-08-03 02:11:34 -0400683 {
Florin Coras134a9962018-08-28 11:32:04 -0700684 session = vcl_session_get (wrk, session_index);
Florin Coras070453d2018-08-24 17:04:27 -0700685 if (PREDICT_FALSE (!session))
Florin Coras697faea2018-06-27 17:10:49 -0700686 {
Florin Coras070453d2018-08-24 17:04:27 -0700687 return VPPCOM_EBADFD;
Florin Coras697faea2018-06-27 17:10:49 -0700688 }
689 if (session->session_state & state)
690 {
Florin Coras697faea2018-06-27 17:10:49 -0700691 return VPPCOM_OK;
692 }
693 if (session->session_state & STATE_FAILED)
694 {
Florin Coras697faea2018-06-27 17:10:49 -0700695 return VPPCOM_ECONNREFUSED;
696 }
Florin Coras54693d22018-07-17 10:46:29 -0700697
Florin Coras134a9962018-08-28 11:32:04 -0700698 if (svm_msg_q_sub (wrk->app_event_queue, &msg, SVM_Q_NOWAIT, 0))
Florin Corasdc2e2512018-12-03 17:47:26 -0800699 {
700 usleep (100);
701 continue;
702 }
Florin Coras134a9962018-08-28 11:32:04 -0700703 e = svm_msg_q_msg_data (wrk->app_event_queue, &msg);
Florin Coras86f04502018-09-12 16:08:01 -0700704 vcl_handle_mq_event (wrk, e);
Florin Coras134a9962018-08-28 11:32:04 -0700705 svm_msg_q_free_msg (wrk->app_event_queue, &msg);
Florin Corasdcf55ce2017-11-16 15:32:50 -0800706 }
Florin Coras134a9962018-08-28 11:32:04 -0700707 while (clib_time_now (&wrk->clib_time) < timeout);
Florin Corasdcf55ce2017-11-16 15:32:50 -0800708
Florin Coras05ecfcc2018-12-12 18:19:39 -0800709 VDBG (0, "timeout waiting for state 0x%x (%s)", state,
Florin Coras697faea2018-06-27 17:10:49 -0700710 vppcom_session_state_str (state));
711 vcl_evt (VCL_EVT_SESSION_TIMEOUT, session, session_state);
Dave Wallace543852a2017-08-03 02:11:34 -0400712
Florin Coras697faea2018-06-27 17:10:49 -0700713 return VPPCOM_ETIMEDOUT;
Dave Wallace60caa062017-11-10 17:07:13 -0500714}
715
Florin Coras30e79c22019-01-02 19:31:22 -0800716static void
717vcl_handle_pending_wrk_updates (vcl_worker_t * wrk)
718{
719 session_state_t state;
720 vcl_session_t *s;
721 u32 *sip;
722
723 if (PREDICT_TRUE (vec_len (wrk->pending_session_wrk_updates) == 0))
724 return;
725
726 vec_foreach (sip, wrk->pending_session_wrk_updates)
727 {
728 s = vcl_session_get (wrk, *sip);
729 vcl_send_session_worker_update (wrk, s, wrk->wrk_index);
730 state = s->session_state;
731 vppcom_wait_for_session_state_change (s->session_index, STATE_UPDATED, 5);
732 s->session_state = state;
733 }
734 vec_reset_length (wrk->pending_session_wrk_updates);
735}
736
Florin Corasf9240dc2019-01-15 08:03:17 -0800737void
Florin Coras30e79c22019-01-02 19:31:22 -0800738vcl_flush_mq_events (void)
739{
740 vcl_worker_t *wrk = vcl_worker_get_current ();
741 svm_msg_q_msg_t *msg;
742 session_event_t *e;
743 svm_msg_q_t *mq;
744 int i;
745
746 mq = wrk->app_event_queue;
747 svm_msg_q_lock (mq);
748 vcl_mq_dequeue_batch (wrk, mq);
749 svm_msg_q_unlock (mq);
750
751 for (i = 0; i < vec_len (wrk->mq_msg_vector); i++)
752 {
753 msg = vec_elt_at_index (wrk->mq_msg_vector, i);
754 e = svm_msg_q_msg_data (mq, msg);
755 vcl_handle_mq_event (wrk, e);
756 svm_msg_q_free_msg (mq, msg);
757 }
758 vec_reset_length (wrk->mq_msg_vector);
759 vcl_handle_pending_wrk_updates (wrk);
760}
761
Florin Coras697faea2018-06-27 17:10:49 -0700762static int
763vppcom_app_session_enable (void)
Dave Wallace543852a2017-08-03 02:11:34 -0400764{
Florin Coras697faea2018-06-27 17:10:49 -0700765 int rv;
Dave Wallace543852a2017-08-03 02:11:34 -0400766
Florin Coras697faea2018-06-27 17:10:49 -0700767 if (vcm->app_state != STATE_APP_ENABLED)
768 {
769 vppcom_send_session_enable_disable (1 /* is_enabled == TRUE */ );
Florin Coras134a9962018-08-28 11:32:04 -0700770 rv = vcl_wait_for_app_state_change (STATE_APP_ENABLED);
Florin Coras697faea2018-06-27 17:10:49 -0700771 if (PREDICT_FALSE (rv))
772 {
773 VDBG (0, "VCL<%d>: application session enable timed out! "
774 "returning %d (%s)", getpid (), rv, vppcom_retval_str (rv));
775 return rv;
776 }
777 }
778 return VPPCOM_OK;
Dave Wallace543852a2017-08-03 02:11:34 -0400779}
780
Florin Coras697faea2018-06-27 17:10:49 -0700781static int
782vppcom_app_attach (void)
Dave Wallace543852a2017-08-03 02:11:34 -0400783{
Florin Coras697faea2018-06-27 17:10:49 -0700784 int rv;
Dave Wallace543852a2017-08-03 02:11:34 -0400785
Florin Coras697faea2018-06-27 17:10:49 -0700786 vppcom_app_send_attach ();
Florin Coras134a9962018-08-28 11:32:04 -0700787 rv = vcl_wait_for_app_state_change (STATE_APP_ATTACHED);
Florin Coras697faea2018-06-27 17:10:49 -0700788 if (PREDICT_FALSE (rv))
789 {
790 VDBG (0, "VCL<%d>: application attach timed out! returning %d (%s)",
791 getpid (), rv, vppcom_retval_str (rv));
792 return rv;
793 }
Dave Wallace543852a2017-08-03 02:11:34 -0400794
Florin Coras697faea2018-06-27 17:10:49 -0700795 return VPPCOM_OK;
Dave Wallace543852a2017-08-03 02:11:34 -0400796}
797
798static int
Florin Corasab2f6db2018-08-31 14:31:41 -0700799vppcom_session_unbind (u32 session_handle)
Dave Wallace543852a2017-08-03 02:11:34 -0400800{
Florin Coras134a9962018-08-28 11:32:04 -0700801 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras7e12d942018-06-27 14:32:43 -0700802 vcl_session_t *session = 0;
Dave Wallace4878cbe2017-11-21 03:45:09 -0500803 u64 vpp_handle;
Dave Wallace543852a2017-08-03 02:11:34 -0400804
Florin Corasab2f6db2018-08-31 14:31:41 -0700805 session = vcl_session_get_w_handle (wrk, session_handle);
Florin Coras070453d2018-08-24 17:04:27 -0700806 if (!session)
807 return VPPCOM_EBADFD;
Dave Wallace4878cbe2017-11-21 03:45:09 -0500808
809 vpp_handle = session->vpp_handle;
Florin Coras134a9962018-08-28 11:32:04 -0700810 vcl_session_table_del_listener (wrk, vpp_handle);
Dave Wallace4878cbe2017-11-21 03:45:09 -0500811 session->vpp_handle = ~0;
Florin Coras7e12d942018-06-27 14:32:43 -0700812 session->session_state = STATE_DISCONNECT;
Dave Wallace4878cbe2017-11-21 03:45:09 -0500813
Florin Coras0d427d82018-06-27 03:24:07 -0700814 VDBG (1, "VCL<%d>: vpp handle 0x%llx, sid %u: sending unbind msg! new state"
Florin Corasab2f6db2018-08-31 14:31:41 -0700815 " 0x%x (%s)", getpid (), vpp_handle, session_handle, STATE_DISCONNECT,
Florin Coras0d427d82018-06-27 03:24:07 -0700816 vppcom_session_state_str (STATE_DISCONNECT));
817 vcl_evt (VCL_EVT_UNBIND, session);
Dave Wallace4878cbe2017-11-21 03:45:09 -0500818 vppcom_send_unbind_sock (vpp_handle);
819
Florin Coras070453d2018-08-24 17:04:27 -0700820 return VPPCOM_OK;
Dave Wallace543852a2017-08-03 02:11:34 -0400821}
822
Florin Coras697faea2018-06-27 17:10:49 -0700823static int
Florin Corasab2f6db2018-08-31 14:31:41 -0700824vppcom_session_disconnect (u32 session_handle)
Dave Wallace543852a2017-08-03 02:11:34 -0400825{
Florin Coras134a9962018-08-28 11:32:04 -0700826 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras99368312018-08-02 10:45:44 -0700827 svm_msg_q_t *vpp_evt_q;
Florin Coras7e12d942018-06-27 14:32:43 -0700828 vcl_session_t *session;
Dave Wallace4878cbe2017-11-21 03:45:09 -0500829 session_state_t state;
Florin Coras99368312018-08-02 10:45:44 -0700830 u64 vpp_handle;
Dave Wallace543852a2017-08-03 02:11:34 -0400831
Florin Corasab2f6db2018-08-31 14:31:41 -0700832 session = vcl_session_get_w_handle (wrk, session_handle);
Florin Coras21795132018-09-09 09:40:51 -0700833 if (!session)
834 return VPPCOM_EBADFD;
835
Dave Wallace4878cbe2017-11-21 03:45:09 -0500836 vpp_handle = session->vpp_handle;
Florin Coras7e12d942018-06-27 14:32:43 -0700837 state = session->session_state;
Dave Wallace4878cbe2017-11-21 03:45:09 -0500838
Florin Coras0d427d82018-06-27 03:24:07 -0700839 VDBG (1, "VCL<%d>: vpp handle 0x%llx, sid %u state 0x%x (%s)", getpid (),
Florin Corasab2f6db2018-08-31 14:31:41 -0700840 vpp_handle, session_handle, state, vppcom_session_state_str (state));
Dave Wallace66cf6eb2017-10-26 02:51:07 -0400841
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -0800842 if (PREDICT_FALSE (state & STATE_LISTEN))
Dave Wallace66cf6eb2017-10-26 02:51:07 -0400843 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500844 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -0500845 "Cannot disconnect a listen socket!",
Florin Corasab2f6db2018-08-31 14:31:41 -0700846 getpid (), vpp_handle, session_handle);
Florin Coras070453d2018-08-24 17:04:27 -0700847 return VPPCOM_EBADFD;
Dave Wallace4878cbe2017-11-21 03:45:09 -0500848 }
Dave Wallace66cf6eb2017-10-26 02:51:07 -0400849
Florin Coras3c7d4f92018-12-14 11:28:43 -0800850 if (state & STATE_VPP_CLOSING)
Dave Wallace4878cbe2017-11-21 03:45:09 -0500851 {
Florin Coras134a9962018-08-28 11:32:04 -0700852 vpp_evt_q = vcl_session_vpp_evt_q (wrk, session);
Florin Coras47c40e22018-11-26 17:01:36 -0800853 vcl_send_session_disconnected_reply (vpp_evt_q, wrk->my_client_index,
Florin Coras99368312018-08-02 10:45:44 -0700854 vpp_handle, 0);
Florin Coras0d427d82018-06-27 03:24:07 -0700855 VDBG (1, "VCL<%d>: vpp handle 0x%llx, sid %u: sending disconnect "
Florin Corasab2f6db2018-08-31 14:31:41 -0700856 "REPLY...", getpid (), vpp_handle, session_handle);
Dave Wallace66cf6eb2017-10-26 02:51:07 -0400857 }
858 else
Dave Wallace227867f2017-11-13 21:21:53 -0500859 {
Florin Coras0d427d82018-06-27 03:24:07 -0700860 VDBG (1, "VCL<%d>: vpp handle 0x%llx, sid %u: sending disconnect...",
Florin Corasab2f6db2018-08-31 14:31:41 -0700861 getpid (), vpp_handle, session_handle);
862 vppcom_send_disconnect_session (vpp_handle);
Dave Wallace227867f2017-11-13 21:21:53 -0500863 }
Dave Wallace66cf6eb2017-10-26 02:51:07 -0400864
Florin Coras070453d2018-08-24 17:04:27 -0700865 return VPPCOM_OK;
Dave Wallace543852a2017-08-03 02:11:34 -0400866}
867
Florin Coras940f78f2018-11-30 12:11:20 -0800868/**
869 * Handle app exit
870 *
871 * Notify vpp of the disconnect and mark the worker as free. If we're the
872 * last worker, do a full cleanup otherwise, since we're probably a forked
873 * child, avoid syscalls as much as possible. We might've lost privileges.
874 */
875void
876vppcom_app_exit (void)
877{
878 if (!pool_elts (vcm->workers))
879 return;
Florin Coras01f3f892018-12-02 12:45:53 -0800880 vcl_worker_cleanup (vcl_worker_get_current (), 1 /* notify vpp */ );
881 vcl_set_worker_index (~0);
Florin Coras940f78f2018-11-30 12:11:20 -0800882 vcl_elog_stop (vcm);
883 if (vec_len (vcm->workers) == 1)
884 vl_client_disconnect_from_vlib ();
885 else
Florin Coraseaec2a62018-12-04 16:34:05 -0800886 vl_client_send_disconnect (1 /* vpp should cleanup */ );
Florin Coras940f78f2018-11-30 12:11:20 -0800887}
888
Dave Wallace543852a2017-08-03 02:11:34 -0400889/*
890 * VPPCOM Public API functions
891 */
892int
893vppcom_app_create (char *app_name)
894{
Dave Wallace543852a2017-08-03 02:11:34 -0400895 vppcom_cfg_t *vcl_cfg = &vcm->cfg;
Dave Wallace543852a2017-08-03 02:11:34 -0400896 int rv;
897
Florin Coras47c40e22018-11-26 17:01:36 -0800898 if (vcm->is_init)
Dave Wallace543852a2017-08-03 02:11:34 -0400899 {
Florin Coras955bfbb2018-12-04 13:43:45 -0800900 VDBG (1, "already initialized");
901 return VPPCOM_EEXIST;
Dave Wallace543852a2017-08-03 02:11:34 -0400902 }
903
Florin Coras47c40e22018-11-26 17:01:36 -0800904 vcm->is_init = 1;
905 vppcom_cfg (&vcm->cfg);
906 vcl_cfg = &vcm->cfg;
907
908 vcm->main_cpu = pthread_self ();
909 vcm->main_pid = getpid ();
910 vcm->app_name = format (0, "%s", app_name);
911 vppcom_init_error_string_table ();
Florin Corasadc74d72018-12-02 13:36:00 -0800912 svm_fifo_segment_main_init (&vcm->segment_main, vcl_cfg->segment_baseva,
Florin Coras47c40e22018-11-26 17:01:36 -0800913 20 /* timeout in secs */ );
914 pool_alloc (vcm->workers, vcl_cfg->max_workers);
915 clib_spinlock_init (&vcm->workers_lock);
Florin Corasd85de682018-11-29 17:02:29 -0800916 clib_rwlock_init (&vcm->segment_table_lock);
Florin Coras940f78f2018-11-30 12:11:20 -0800917 atexit (vppcom_app_exit);
Florin Coras47c40e22018-11-26 17:01:36 -0800918
919 /* Allocate default worker */
920 vcl_worker_alloc_and_init ();
921
922 /* API hookup and connect to VPP */
923 vppcom_api_hookup ();
924 vcl_elog_init (vcm);
925 vcm->app_state = STATE_APP_START;
926 rv = vppcom_connect_to_vpp (app_name);
927 if (rv)
Dave Wallace543852a2017-08-03 02:11:34 -0400928 {
Florin Coras47c40e22018-11-26 17:01:36 -0800929 VERR ("couldn't connect to VPP!");
930 return rv;
Dave Wallace66cf6eb2017-10-26 02:51:07 -0400931 }
Florin Coras47c40e22018-11-26 17:01:36 -0800932 VDBG (0, "sending session enable");
933 rv = vppcom_app_session_enable ();
934 if (rv)
935 {
936 VERR ("vppcom_app_session_enable() failed!");
937 return rv;
938 }
939
940 VDBG (0, "sending app attach");
941 rv = vppcom_app_attach ();
942 if (rv)
943 {
944 VERR ("vppcom_app_attach() failed!");
945 return rv;
946 }
947
948 VDBG (0, "app_name '%s', my_client_index %d (0x%x)", app_name,
949 vcm->workers[0].my_client_index, vcm->workers[0].my_client_index);
Dave Wallace543852a2017-08-03 02:11:34 -0400950
951 return VPPCOM_OK;
952}
953
954void
955vppcom_app_destroy (void)
956{
Dave Wallace543852a2017-08-03 02:11:34 -0400957 int rv;
Dave Wallacede910062018-03-20 09:22:13 -0400958 f64 orig_app_timeout;
Dave Wallace543852a2017-08-03 02:11:34 -0400959
Florin Coras940f78f2018-11-30 12:11:20 -0800960 if (!pool_elts (vcm->workers))
961 return;
962
Florin Coras0d427d82018-06-27 03:24:07 -0700963 vcl_evt (VCL_EVT_DETACH, vcm);
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -0800964
Florin Coras940f78f2018-11-30 12:11:20 -0800965 if (pool_elts (vcm->workers) == 1)
Florin Coras47c40e22018-11-26 17:01:36 -0800966 {
967 vppcom_app_send_detach ();
968 orig_app_timeout = vcm->cfg.app_timeout;
969 vcm->cfg.app_timeout = 2.0;
970 rv = vcl_wait_for_app_state_change (STATE_APP_ENABLED);
971 vcm->cfg.app_timeout = orig_app_timeout;
972 if (PREDICT_FALSE (rv))
973 VDBG (0, "application detach timed out! returning %d (%s)", rv,
974 vppcom_retval_str (rv));
Florin Coras940f78f2018-11-30 12:11:20 -0800975 vec_free (vcm->app_name);
Florin Coras01f3f892018-12-02 12:45:53 -0800976 vcl_worker_cleanup (vcl_worker_get_current (), 0 /* notify vpp */ );
Florin Coras47c40e22018-11-26 17:01:36 -0800977 }
978 else
979 {
Florin Coras01f3f892018-12-02 12:45:53 -0800980 vcl_worker_cleanup (vcl_worker_get_current (), 1 /* notify vpp */ );
Florin Coras47c40e22018-11-26 17:01:36 -0800981 }
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -0800982
Florin Coras01f3f892018-12-02 12:45:53 -0800983 vcl_set_worker_index (~0);
Florin Coras0d427d82018-06-27 03:24:07 -0700984 vcl_elog_stop (vcm);
Dave Wallace543852a2017-08-03 02:11:34 -0400985 vl_client_disconnect_from_vlib ();
Dave Wallace543852a2017-08-03 02:11:34 -0400986}
987
988int
Dave Wallacec04cbf12018-02-07 18:14:02 -0500989vppcom_session_create (u8 proto, u8 is_nonblocking)
Dave Wallace543852a2017-08-03 02:11:34 -0400990{
Florin Coras134a9962018-08-28 11:32:04 -0700991 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras7e12d942018-06-27 14:32:43 -0700992 vcl_session_t *session;
Dave Wallace543852a2017-08-03 02:11:34 -0400993
Florin Coras134a9962018-08-28 11:32:04 -0700994 session = vcl_session_alloc (wrk);
Dave Wallace543852a2017-08-03 02:11:34 -0400995
Florin Coras7e12d942018-06-27 14:32:43 -0700996 session->session_type = proto;
997 session->session_state = STATE_START;
Dave Wallace4878cbe2017-11-21 03:45:09 -0500998 session->vpp_handle = ~0;
Florin Coras460dce62018-07-27 05:45:06 -0700999 session->is_dgram = proto == VPPCOM_PROTO_UDP;
Dave Wallace543852a2017-08-03 02:11:34 -04001000
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001001 if (is_nonblocking)
1002 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_NONBLOCK);
Dave Wallace543852a2017-08-03 02:11:34 -04001003
Florin Coras7e12d942018-06-27 14:32:43 -07001004 vcl_evt (VCL_EVT_CREATE, session, session_type, session->session_state,
1005 is_nonblocking, session_index);
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08001006
Florin Coras053a0e42018-11-13 15:52:38 -08001007 VDBG (0, "created sid %u", session->session_index);
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08001008
Florin Coras134a9962018-08-28 11:32:04 -07001009 return vcl_session_handle (session);
Dave Wallace543852a2017-08-03 02:11:34 -04001010}
1011
1012int
Florin Corasf9240dc2019-01-15 08:03:17 -08001013vcl_session_cleanup (vcl_worker_t * wrk, vcl_session_t * session,
1014 vcl_session_handle_t sh, u8 do_disconnect)
Dave Wallace543852a2017-08-03 02:11:34 -04001015{
Dave Wallace66cf6eb2017-10-26 02:51:07 -04001016 session_state_t state;
Florin Coras134a9962018-08-28 11:32:04 -07001017 u32 next_sh, vep_sh;
1018 int rv = VPPCOM_OK;
1019 u64 vpp_handle;
Florin Corasf9240dc2019-01-15 08:03:17 -08001020 u8 is_vep;
Florin Coras47c40e22018-11-26 17:01:36 -08001021
Dave Wallace66cf6eb2017-10-26 02:51:07 -04001022 is_vep = session->is_vep;
Florin Coras134a9962018-08-28 11:32:04 -07001023 next_sh = session->vep.next_sh;
1024 vep_sh = session->vep.vep_sh;
Florin Coras7e12d942018-06-27 14:32:43 -07001025 state = session->session_state;
Dave Wallaceee45d412017-11-24 21:44:06 -05001026 vpp_handle = session->vpp_handle;
Dave Wallace543852a2017-08-03 02:11:34 -04001027
Florin Corasf9240dc2019-01-15 08:03:17 -08001028 VDBG (1, "session %u [0x%llx] closing", session->session_index, vpp_handle);
Dave Wallace543852a2017-08-03 02:11:34 -04001029
Dave Wallace66cf6eb2017-10-26 02:51:07 -04001030 if (is_vep)
Dave Wallace543852a2017-08-03 02:11:34 -04001031 {
Florin Coras134a9962018-08-28 11:32:04 -07001032 while (next_sh != ~0)
Dave Wallace19481612017-09-15 18:47:44 -04001033 {
Florin Corasf9240dc2019-01-15 08:03:17 -08001034 rv = vppcom_epoll_ctl (sh, EPOLL_CTL_DEL, next_sh, 0);
Florin Coras0d427d82018-06-27 03:24:07 -07001035 if (PREDICT_FALSE (rv < 0))
Florin Coras47c40e22018-11-26 17:01:36 -08001036 VDBG (0, "vpp handle 0x%llx, sid %u: EPOLL_CTL_DEL vep_idx %u"
1037 " failed! rv %d (%s)", vpp_handle, next_sh, vep_sh, rv,
1038 vppcom_retval_str (rv));
Dave Wallacef7f809c2017-10-03 01:48:42 -04001039
Florin Coras134a9962018-08-28 11:32:04 -07001040 next_sh = session->vep.next_sh;
Dave Wallacef7f809c2017-10-03 01:48:42 -04001041 }
1042 }
1043 else
1044 {
Florin Coras47c40e22018-11-26 17:01:36 -08001045 if (session->is_vep_session)
Dave Wallacef7f809c2017-10-03 01:48:42 -04001046 {
Florin Corasf9240dc2019-01-15 08:03:17 -08001047 rv = vppcom_epoll_ctl (vep_sh, EPOLL_CTL_DEL, sh, 0);
Florin Coras0d427d82018-06-27 03:24:07 -07001048 if (rv < 0)
Florin Corasf9240dc2019-01-15 08:03:17 -08001049 VDBG (0, "session %u [0x%llx]: EPOLL_CTL_DEL vep_idx %u "
1050 "failed! rv %d (%s)", session->session_index, vpp_handle,
1051 vep_sh, rv, vppcom_retval_str (rv));
Dave Wallacef7f809c2017-10-03 01:48:42 -04001052 }
1053
Florin Coras47c40e22018-11-26 17:01:36 -08001054 if (!do_disconnect)
Florin Coras30e79c22019-01-02 19:31:22 -08001055 {
Florin Corasf9240dc2019-01-15 08:03:17 -08001056 VDBG (0, "session %u [0x%llx] disconnect skipped",
1057 session->session_index, vpp_handle);
Florin Coras30e79c22019-01-02 19:31:22 -08001058 goto cleanup;
1059 }
Florin Coras47c40e22018-11-26 17:01:36 -08001060
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001061 if (state & STATE_LISTEN)
Dave Wallacef7f809c2017-10-03 01:48:42 -04001062 {
Florin Corasf9240dc2019-01-15 08:03:17 -08001063 rv = vppcom_session_unbind (sh);
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001064 if (PREDICT_FALSE (rv < 0))
Florin Corasf9240dc2019-01-15 08:03:17 -08001065 VDBG (0, "session %u [0x%llx]: listener unbind failed! "
1066 "rv %d (%s)", session->session_index, vpp_handle, rv,
Florin Coras47c40e22018-11-26 17:01:36 -08001067 vppcom_retval_str (rv));
Dave Wallacef7f809c2017-10-03 01:48:42 -04001068 }
Florin Coras070453d2018-08-24 17:04:27 -07001069 else if (state & STATE_OPEN)
Dave Wallacef7f809c2017-10-03 01:48:42 -04001070 {
Florin Corasf9240dc2019-01-15 08:03:17 -08001071 rv = vppcom_session_disconnect (sh);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001072 if (PREDICT_FALSE (rv < 0))
Florin Corasf9240dc2019-01-15 08:03:17 -08001073 VDBG (0, "ERROR: session %u [0x%llx]: disconnect failed!"
1074 " rv %d (%s)", session->session_index, vpp_handle,
1075 rv, vppcom_retval_str (rv));
Dave Wallacef7f809c2017-10-03 01:48:42 -04001076 }
Florin Corasb0f662f2018-12-27 14:51:46 -08001077 else if (state == STATE_DISCONNECT)
1078 {
1079 svm_msg_q_t *mq = vcl_session_vpp_evt_q (wrk, session);
1080 vcl_send_session_reset_reply (mq, wrk->my_client_index,
1081 session->vpp_handle, 0);
1082 }
Dave Wallace19481612017-09-15 18:47:44 -04001083 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05001084
Florin Coras99368312018-08-02 10:45:44 -07001085 if (vcl_session_is_ct (session))
1086 {
1087 vcl_cut_through_registration_t *ctr;
1088 uword mq_addr;
1089
1090 mq_addr = pointer_to_uword (session->our_evt_q);
Florin Coras134a9962018-08-28 11:32:04 -07001091 ctr = vcl_ct_registration_lock_and_lookup (wrk, mq_addr);
Florin Coras99368312018-08-02 10:45:44 -07001092 ASSERT (ctr);
1093 if (ctr->epoll_evt_conn_index != ~0)
Florin Coras134a9962018-08-28 11:32:04 -07001094 vcl_mq_epoll_del_evfd (wrk, ctr->epoll_evt_conn_index);
Florin Coras99368312018-08-02 10:45:44 -07001095 VDBG (0, "Removing ct registration %u",
Florin Coras134a9962018-08-28 11:32:04 -07001096 vcl_ct_registration_index (wrk, ctr));
1097 vcl_ct_registration_del (wrk, ctr);
1098 vcl_ct_registration_lookup_del (wrk, mq_addr);
1099 vcl_ct_registration_unlock (wrk);
Florin Coras99368312018-08-02 10:45:44 -07001100 }
Florin Coras54693d22018-07-17 10:46:29 -07001101
Florin Corasf9240dc2019-01-15 08:03:17 -08001102cleanup:
Florin Coras30e79c22019-01-02 19:31:22 -08001103 vcl_session_table_del_vpp_handle (wrk, vpp_handle);
Florin Coras134a9962018-08-28 11:32:04 -07001104 vcl_session_free (wrk, session);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001105
Florin Corasf9240dc2019-01-15 08:03:17 -08001106 VDBG (0, "session %u [0x%llx] removed", session->session_index, vpp_handle);
Florin Coras0d427d82018-06-27 03:24:07 -07001107 vcl_evt (VCL_EVT_CLOSE, session, rv);
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08001108
Dave Wallace543852a2017-08-03 02:11:34 -04001109 return rv;
1110}
1111
1112int
Florin Corasf9240dc2019-01-15 08:03:17 -08001113vppcom_session_close (uint32_t session_handle)
1114{
1115 vcl_worker_t *wrk = vcl_worker_get_current ();
1116 vcl_session_t *session;
1117
1118 session = vcl_session_get_w_handle (wrk, session_handle);
1119 if (!session)
1120 return VPPCOM_EBADFD;
1121 return vcl_session_cleanup (wrk, session, session_handle,
1122 1 /* do_disconnect */ );
1123}
1124
1125int
Florin Coras134a9962018-08-28 11:32:04 -07001126vppcom_session_bind (uint32_t session_handle, vppcom_endpt_t * ep)
Dave Wallace543852a2017-08-03 02:11:34 -04001127{
Florin Coras134a9962018-08-28 11:32:04 -07001128 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras7e12d942018-06-27 14:32:43 -07001129 vcl_session_t *session = 0;
Dave Wallace543852a2017-08-03 02:11:34 -04001130
1131 if (!ep || !ep->ip)
1132 return VPPCOM_EINVAL;
1133
Florin Coras134a9962018-08-28 11:32:04 -07001134 session = vcl_session_get_w_handle (wrk, session_handle);
Florin Coras070453d2018-08-24 17:04:27 -07001135 if (!session)
1136 return VPPCOM_EBADFD;
Dave Wallace543852a2017-08-03 02:11:34 -04001137
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001138 if (session->is_vep)
1139 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001140 clib_warning ("VCL<%d>: ERROR: sid %u: cannot "
Florin Coras134a9962018-08-28 11:32:04 -07001141 "bind to an epoll session!", getpid (), session_handle);
Florin Coras070453d2018-08-24 17:04:27 -07001142 return VPPCOM_EBADFD;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001143 }
1144
Florin Coras7e12d942018-06-27 14:32:43 -07001145 session->transport.is_ip4 = ep->is_ip4;
Florin Coras54693d22018-07-17 10:46:29 -07001146 if (ep->is_ip4)
Dave Barach178cf492018-11-13 16:34:13 -05001147 clib_memcpy_fast (&session->transport.lcl_ip.ip4, ep->ip,
1148 sizeof (ip4_address_t));
Florin Coras54693d22018-07-17 10:46:29 -07001149 else
Dave Barach178cf492018-11-13 16:34:13 -05001150 clib_memcpy_fast (&session->transport.lcl_ip.ip6, ep->ip,
1151 sizeof (ip6_address_t));
Florin Coras7e12d942018-06-27 14:32:43 -07001152 session->transport.lcl_port = ep->port;
Stevenac1f96d2017-10-24 16:03:58 -07001153
Florin Coras0d427d82018-06-27 03:24:07 -07001154 VDBG (0, "VCL<%d>: sid %u: binding to local %s address %U port %u, "
Florin Coras134a9962018-08-28 11:32:04 -07001155 "proto %s", getpid (), session_handle,
Florin Coras7e12d942018-06-27 14:32:43 -07001156 session->transport.is_ip4 ? "IPv4" : "IPv6",
1157 format_ip46_address, &session->transport.lcl_ip,
1158 session->transport.is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6,
1159 clib_net_to_host_u16 (session->transport.lcl_port),
Ping Yu34a3a082018-11-30 19:16:17 -05001160 vppcom_proto_str (session->session_type));
Florin Coras0d427d82018-06-27 03:24:07 -07001161 vcl_evt (VCL_EVT_BIND, session);
Florin Coras460dce62018-07-27 05:45:06 -07001162
1163 if (session->session_type == VPPCOM_PROTO_UDP)
Florin Coras134a9962018-08-28 11:32:04 -07001164 vppcom_session_listen (session_handle, 10);
Florin Coras460dce62018-07-27 05:45:06 -07001165
Florin Coras070453d2018-08-24 17:04:27 -07001166 return VPPCOM_OK;
Dave Wallace543852a2017-08-03 02:11:34 -04001167}
1168
1169int
Florin Coras134a9962018-08-28 11:32:04 -07001170vppcom_session_listen (uint32_t listen_sh, uint32_t q_len)
Dave Wallace543852a2017-08-03 02:11:34 -04001171{
Florin Coras134a9962018-08-28 11:32:04 -07001172 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras7e12d942018-06-27 14:32:43 -07001173 vcl_session_t *listen_session = 0;
Dave Wallaceee45d412017-11-24 21:44:06 -05001174 u64 listen_vpp_handle;
Florin Coras070453d2018-08-24 17:04:27 -07001175 int rv;
1176
Florin Coras134a9962018-08-28 11:32:04 -07001177 listen_session = vcl_session_get_w_handle (wrk, listen_sh);
Florin Coras05ecfcc2018-12-12 18:19:39 -08001178 if (!listen_session || listen_session->is_vep)
Florin Coras070453d2018-08-24 17:04:27 -07001179 return VPPCOM_EBADFD;
Dave Wallace543852a2017-08-03 02:11:34 -04001180
Keith Burns (alagalah)aba98de2018-02-22 03:23:40 -08001181 if (q_len == 0 || q_len == ~0)
1182 q_len = vcm->cfg.listen_queue_size;
1183
Dave Wallaceee45d412017-11-24 21:44:06 -05001184 listen_vpp_handle = listen_session->vpp_handle;
Florin Coras7e12d942018-06-27 14:32:43 -07001185 if (listen_session->session_state & STATE_LISTEN)
Dave Wallacee695cb42017-11-02 22:04:42 -04001186 {
Florin Coras05ecfcc2018-12-12 18:19:39 -08001187 VDBG (0, "session %u [0x%llx]: already in listen state!",
1188 listen_sh, listen_vpp_handle);
Florin Coras070453d2018-08-24 17:04:27 -07001189 return VPPCOM_OK;
Dave Wallacee695cb42017-11-02 22:04:42 -04001190 }
1191
Florin Coras05ecfcc2018-12-12 18:19:39 -08001192 VDBG (0, "session %u [0x%llx]: sending vpp listen request...",
1193 listen_sh, listen_vpp_handle);
Dave Wallace543852a2017-08-03 02:11:34 -04001194
Florin Coras070453d2018-08-24 17:04:27 -07001195 /*
1196 * Send listen request to vpp and wait for reply
1197 */
Florin Coras134a9962018-08-28 11:32:04 -07001198 vppcom_send_bind_sock (listen_session);
1199 rv = vppcom_wait_for_session_state_change (listen_session->session_index,
1200 STATE_LISTEN,
1201 vcm->cfg.session_timeout);
Dave Wallace543852a2017-08-03 02:11:34 -04001202
Florin Coras070453d2018-08-24 17:04:27 -07001203 if (PREDICT_FALSE (rv))
Dave Wallaceee45d412017-11-24 21:44:06 -05001204 {
Florin Coras134a9962018-08-28 11:32:04 -07001205 listen_session = vcl_session_get_w_handle (wrk, listen_sh);
Florin Coras05ecfcc2018-12-12 18:19:39 -08001206 VDBG (0, "session %u [0x%llx]: listen failed! returning %d (%s)",
1207 listen_sh, listen_session->vpp_handle, rv,
1208 vppcom_retval_str (rv));
Florin Coras070453d2018-08-24 17:04:27 -07001209 return rv;
Dave Wallaceee45d412017-11-24 21:44:06 -05001210 }
1211
Florin Coras070453d2018-08-24 17:04:27 -07001212 return VPPCOM_OK;
Keith Burns (alagalah)0d2b0d52018-03-06 15:55:22 -08001213}
1214
Ping Yu34a3a082018-11-30 19:16:17 -05001215int
1216vppcom_session_tls_add_cert (uint32_t session_handle, char *cert,
1217 uint32_t cert_len)
1218{
1219
1220 vcl_worker_t *wrk = vcl_worker_get_current ();
1221 vcl_session_t *session = 0;
1222
1223 session = vcl_session_get_w_handle (wrk, session_handle);
1224 if (!session)
1225 return VPPCOM_EBADFD;
1226
1227 if (cert_len == 0 || cert_len == ~0)
1228 return VPPCOM_EBADFD;
1229
1230 /*
1231 * Send listen request to vpp and wait for reply
1232 */
1233 vppcom_send_application_tls_cert_add (session, cert, cert_len);
1234
1235 return VPPCOM_OK;
1236
1237}
1238
1239int
1240vppcom_session_tls_add_key (uint32_t session_handle, char *key,
1241 uint32_t key_len)
1242{
1243
1244 vcl_worker_t *wrk = vcl_worker_get_current ();
1245 vcl_session_t *session = 0;
1246
1247 session = vcl_session_get_w_handle (wrk, session_handle);
1248 if (!session)
1249 return VPPCOM_EBADFD;
1250
1251 if (key_len == 0 || key_len == ~0)
1252 return VPPCOM_EBADFD;
1253
1254 /*
1255 * Send listen request to vpp and wait for reply
1256 */
1257 vppcom_send_application_tls_key_add (session, key, key_len);
1258
1259 return VPPCOM_OK;
1260
1261
1262}
1263
Florin Coras134a9962018-08-28 11:32:04 -07001264static int
1265validate_args_session_accept_ (vcl_worker_t * wrk,
1266 vcl_session_t * listen_session)
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001267{
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001268 /* Input validation - expects spinlock on sessions_lockp */
1269 if (listen_session->is_vep)
1270 {
1271 clib_warning ("VCL<%d>: ERROR: sid %u: cannot accept on an "
Florin Coras134a9962018-08-28 11:32:04 -07001272 "epoll session!", getpid (),
1273 listen_session->session_index);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001274 return VPPCOM_EBADFD;
1275 }
1276
Florin Coras7e12d942018-06-27 14:32:43 -07001277 if (listen_session->session_state != STATE_LISTEN)
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001278 {
1279 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
1280 "not in listen state! state 0x%x (%s)", getpid (),
Florin Coras134a9962018-08-28 11:32:04 -07001281 listen_session->vpp_handle, listen_session->session_index,
Florin Coras7e12d942018-06-27 14:32:43 -07001282 listen_session->session_state,
1283 vppcom_session_state_str (listen_session->session_state));
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001284 return VPPCOM_EBADFD;
1285 }
1286 return VPPCOM_OK;
1287}
1288
1289int
Florin Coras134a9962018-08-28 11:32:04 -07001290vppcom_session_accept (uint32_t listen_session_handle, vppcom_endpt_t * ep,
Dave Wallace048b1d62018-01-03 22:24:41 -05001291 uint32_t flags)
Dave Wallace543852a2017-08-03 02:11:34 -04001292{
Florin Coras3c7d4f92018-12-14 11:28:43 -08001293 u32 client_session_index = ~0, listen_session_index, accept_flags = 0;
Florin Coras134a9962018-08-28 11:32:04 -07001294 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras54693d22018-07-17 10:46:29 -07001295 session_accepted_msg_t accepted_msg;
Florin Coras7e12d942018-06-27 14:32:43 -07001296 vcl_session_t *listen_session = 0;
1297 vcl_session_t *client_session = 0;
Florin Coras54693d22018-07-17 10:46:29 -07001298 svm_msg_q_t *vpp_evt_q;
1299 vcl_session_msg_t *evt;
Dave Wallaceee45d412017-11-24 21:44:06 -05001300 u64 listen_vpp_handle;
Florin Coras54693d22018-07-17 10:46:29 -07001301 svm_msg_q_msg_t msg;
1302 session_event_t *e;
1303 u8 is_nonblocking;
1304 int rv;
Dave Wallace543852a2017-08-03 02:11:34 -04001305
Florin Coras134a9962018-08-28 11:32:04 -07001306 listen_session = vcl_session_get_w_handle (wrk, listen_session_handle);
Florin Coras070453d2018-08-24 17:04:27 -07001307 if (!listen_session)
1308 return VPPCOM_EBADFD;
Dave Wallace543852a2017-08-03 02:11:34 -04001309
Florin Coras134a9962018-08-28 11:32:04 -07001310 listen_session_index = listen_session->session_index;
1311 if ((rv = validate_args_session_accept_ (wrk, listen_session)))
Florin Coras070453d2018-08-24 17:04:27 -07001312 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04001313
Florin Coras54693d22018-07-17 10:46:29 -07001314 if (clib_fifo_elts (listen_session->accept_evts_fifo))
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001315 {
Florin Coras54693d22018-07-17 10:46:29 -07001316 clib_fifo_sub2 (listen_session->accept_evts_fifo, evt);
Florin Coras3c7d4f92018-12-14 11:28:43 -08001317 accept_flags = evt->flags;
Florin Coras54693d22018-07-17 10:46:29 -07001318 accepted_msg = evt->accepted_msg;
1319 goto handle;
1320 }
1321
1322 is_nonblocking = VCL_SESS_ATTR_TEST (listen_session->attr,
1323 VCL_SESS_ATTR_NONBLOCK);
Florin Coras134a9962018-08-28 11:32:04 -07001324 if (svm_msg_q_is_empty (wrk->app_event_queue) && is_nonblocking)
Florin Coras54693d22018-07-17 10:46:29 -07001325 return VPPCOM_EAGAIN;
1326
1327 while (1)
1328 {
Florin Coras134a9962018-08-28 11:32:04 -07001329 if (svm_msg_q_sub (wrk->app_event_queue, &msg, SVM_Q_WAIT, 0))
Florin Coras54693d22018-07-17 10:46:29 -07001330 return VPPCOM_EAGAIN;
1331
Florin Coras134a9962018-08-28 11:32:04 -07001332 e = svm_msg_q_msg_data (wrk->app_event_queue, &msg);
Florin Coras54693d22018-07-17 10:46:29 -07001333 if (e->event_type != SESSION_CTRL_EVT_ACCEPTED)
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001334 {
Florin Coras54693d22018-07-17 10:46:29 -07001335 clib_warning ("discarded event: %u", e->event_type);
Florin Coras134a9962018-08-28 11:32:04 -07001336 svm_msg_q_free_msg (wrk->app_event_queue, &msg);
Florin Coras54693d22018-07-17 10:46:29 -07001337 continue;
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001338 }
Dave Barach178cf492018-11-13 16:34:13 -05001339 clib_memcpy_fast (&accepted_msg, e->data, sizeof (accepted_msg));
Florin Coras134a9962018-08-28 11:32:04 -07001340 svm_msg_q_free_msg (wrk->app_event_queue, &msg);
Florin Coras54693d22018-07-17 10:46:29 -07001341 break;
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001342 }
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001343
Florin Coras54693d22018-07-17 10:46:29 -07001344handle:
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08001345
Florin Coras134a9962018-08-28 11:32:04 -07001346 client_session_index = vcl_session_accepted_handler (wrk, &accepted_msg);
1347 listen_session = vcl_session_get (wrk, listen_session_index);
1348 client_session = vcl_session_get (wrk, client_session_index);
Dave Wallace543852a2017-08-03 02:11:34 -04001349
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001350 if (flags & O_NONBLOCK)
1351 VCL_SESS_ATTR_SET (client_session->attr, VCL_SESS_ATTR_NONBLOCK);
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001352
Florin Coras54693d22018-07-17 10:46:29 -07001353 listen_vpp_handle = listen_session->vpp_handle;
Florin Coras05ecfcc2018-12-12 18:19:39 -08001354 VDBG (1, "vpp handle 0x%llx, sid %u: Got a client request! "
Florin Coras0d427d82018-06-27 03:24:07 -07001355 "vpp handle 0x%llx, sid %u, flags %d, is_nonblocking %u",
Florin Corasdc2e2512018-12-03 17:47:26 -08001356 listen_vpp_handle, listen_session_handle,
Florin Coras0d427d82018-06-27 03:24:07 -07001357 client_session->vpp_handle, client_session_index,
1358 flags, VCL_SESS_ATTR_TEST (client_session->attr,
1359 VCL_SESS_ATTR_NONBLOCK));
Dave Wallace543852a2017-08-03 02:11:34 -04001360
Dave Wallace048b1d62018-01-03 22:24:41 -05001361 if (ep)
1362 {
Florin Coras7e12d942018-06-27 14:32:43 -07001363 ep->is_ip4 = client_session->transport.is_ip4;
1364 ep->port = client_session->transport.rmt_port;
1365 if (client_session->transport.is_ip4)
Dave Barach178cf492018-11-13 16:34:13 -05001366 clib_memcpy_fast (ep->ip, &client_session->transport.rmt_ip.ip4,
1367 sizeof (ip4_address_t));
Dave Wallace048b1d62018-01-03 22:24:41 -05001368 else
Dave Barach178cf492018-11-13 16:34:13 -05001369 clib_memcpy_fast (ep->ip, &client_session->transport.rmt_ip.ip6,
1370 sizeof (ip6_address_t));
Dave Wallace048b1d62018-01-03 22:24:41 -05001371 }
Dave Wallace60caa062017-11-10 17:07:13 -05001372
Florin Coras54693d22018-07-17 10:46:29 -07001373 if (accepted_msg.server_event_queue_address)
1374 vpp_evt_q = uword_to_pointer (accepted_msg.vpp_event_queue_address,
1375 svm_msg_q_t *);
1376 else
1377 vpp_evt_q = client_session->vpp_evt_q;
Florin Coras99368312018-08-02 10:45:44 -07001378
Florin Coras54693d22018-07-17 10:46:29 -07001379 vcl_send_session_accepted_reply (vpp_evt_q, client_session->client_context,
1380 client_session->vpp_handle, 0);
Dave Wallace60caa062017-11-10 17:07:13 -05001381
Florin Coras05ecfcc2018-12-12 18:19:39 -08001382 VDBG (0, "listener %u [0x%llx] accepted %u [0x%llx] peer: %U:%u "
1383 "local: %U:%u", listen_session_handle, listen_vpp_handle,
1384 client_session_index, client_session->vpp_handle,
Florin Coras7e12d942018-06-27 14:32:43 -07001385 format_ip46_address, &client_session->transport.rmt_ip,
Florin Coras54693d22018-07-17 10:46:29 -07001386 client_session->transport.is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6,
Florin Coras7e12d942018-06-27 14:32:43 -07001387 clib_net_to_host_u16 (client_session->transport.rmt_port),
Florin Coras7e12d942018-06-27 14:32:43 -07001388 format_ip46_address, &client_session->transport.lcl_ip,
Florin Coras54693d22018-07-17 10:46:29 -07001389 client_session->transport.is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6,
Florin Coras7e12d942018-06-27 14:32:43 -07001390 clib_net_to_host_u16 (client_session->transport.lcl_port));
Florin Coras0d427d82018-06-27 03:24:07 -07001391 vcl_evt (VCL_EVT_ACCEPT, client_session, listen_session,
1392 client_session_index);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001393
Florin Coras3c7d4f92018-12-14 11:28:43 -08001394 /*
1395 * Session might have been closed already
1396 */
1397 if (accept_flags)
1398 {
Florin Coras3c7d4f92018-12-14 11:28:43 -08001399 if (accept_flags & VCL_ACCEPTED_F_CLOSED)
Florin Corasb0f662f2018-12-27 14:51:46 -08001400 client_session->session_state = STATE_VPP_CLOSING;
Florin Coras3c7d4f92018-12-14 11:28:43 -08001401 else if (accept_flags & VCL_ACCEPTED_F_RESET)
Florin Corasb0f662f2018-12-27 14:51:46 -08001402 client_session->session_state = STATE_DISCONNECT;
Florin Coras3c7d4f92018-12-14 11:28:43 -08001403 }
Florin Corasab2f6db2018-08-31 14:31:41 -07001404 return vcl_session_handle (client_session);
Dave Wallace543852a2017-08-03 02:11:34 -04001405}
1406
1407int
Florin Coras134a9962018-08-28 11:32:04 -07001408vppcom_session_connect (uint32_t session_handle, vppcom_endpt_t * server_ep)
Dave Wallace543852a2017-08-03 02:11:34 -04001409{
Florin Coras134a9962018-08-28 11:32:04 -07001410 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras7e12d942018-06-27 14:32:43 -07001411 vcl_session_t *session = 0;
Florin Coras134a9962018-08-28 11:32:04 -07001412 u32 session_index;
Florin Coras070453d2018-08-24 17:04:27 -07001413 int rv;
Dave Wallace543852a2017-08-03 02:11:34 -04001414
Florin Coras134a9962018-08-28 11:32:04 -07001415 session = vcl_session_get_w_handle (wrk, session_handle);
Florin Coras070453d2018-08-24 17:04:27 -07001416 if (!session)
1417 return VPPCOM_EBADFD;
Florin Coras134a9962018-08-28 11:32:04 -07001418 session_index = session->session_index;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001419
1420 if (PREDICT_FALSE (session->is_vep))
Dave Wallace543852a2017-08-03 02:11:34 -04001421 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001422 clib_warning ("VCL<%d>: ERROR: sid %u: cannot "
Florin Coras134a9962018-08-28 11:32:04 -07001423 "connect on an epoll session!", getpid (),
1424 session_handle);
Florin Coras070453d2018-08-24 17:04:27 -07001425 return VPPCOM_EBADFD;
Dave Wallace543852a2017-08-03 02:11:34 -04001426 }
1427
Florin Coras7e12d942018-06-27 14:32:43 -07001428 if (PREDICT_FALSE (session->session_state & CLIENT_STATE_OPEN))
Dave Wallace543852a2017-08-03 02:11:34 -04001429 {
Florin Coras7baeb712019-01-04 17:05:43 -08001430 VDBG (0, "session handle %u [0x%llx]: session already "
Florin Coras0d427d82018-06-27 03:24:07 -07001431 "connected to %s %U port %d proto %s, state 0x%x (%s)",
Florin Coras7baeb712019-01-04 17:05:43 -08001432 session_handle, session->vpp_handle,
Florin Coras7e12d942018-06-27 14:32:43 -07001433 session->transport.is_ip4 ? "IPv4" : "IPv6",
Florin Coras0d427d82018-06-27 03:24:07 -07001434 format_ip46_address,
Florin Coras7e12d942018-06-27 14:32:43 -07001435 &session->transport.rmt_ip, session->transport.is_ip4 ?
Florin Coras0d427d82018-06-27 03:24:07 -07001436 IP46_TYPE_IP4 : IP46_TYPE_IP6,
Florin Coras7e12d942018-06-27 14:32:43 -07001437 clib_net_to_host_u16 (session->transport.rmt_port),
Ping Yu34a3a082018-11-30 19:16:17 -05001438 vppcom_proto_str (session->session_type), session->session_state,
Florin Coras7e12d942018-06-27 14:32:43 -07001439 vppcom_session_state_str (session->session_state));
Florin Coras070453d2018-08-24 17:04:27 -07001440 return VPPCOM_OK;
Dave Wallace543852a2017-08-03 02:11:34 -04001441 }
1442
Florin Coras7e12d942018-06-27 14:32:43 -07001443 session->transport.is_ip4 = server_ep->is_ip4;
1444 if (session->transport.is_ip4)
Dave Barach178cf492018-11-13 16:34:13 -05001445 clib_memcpy_fast (&session->transport.rmt_ip.ip4, server_ep->ip,
1446 sizeof (ip4_address_t));
Dave Wallaced239f8d2018-06-19 13:37:30 -04001447 else
Dave Barach178cf492018-11-13 16:34:13 -05001448 clib_memcpy_fast (&session->transport.rmt_ip.ip6, server_ep->ip,
1449 sizeof (ip6_address_t));
Florin Coras7e12d942018-06-27 14:32:43 -07001450 session->transport.rmt_port = server_ep->port;
Dave Wallace543852a2017-08-03 02:11:34 -04001451
Florin Coras7baeb712019-01-04 17:05:43 -08001452 VDBG (0, "session handle %u [0x%llx]: connecting to server %s %U "
1453 "port %d proto %s", session_handle, session->vpp_handle,
Florin Coras7e12d942018-06-27 14:32:43 -07001454 session->transport.is_ip4 ? "IPv4" : "IPv6",
Florin Coras0d427d82018-06-27 03:24:07 -07001455 format_ip46_address,
Florin Coras7e12d942018-06-27 14:32:43 -07001456 &session->transport.rmt_ip, session->transport.is_ip4 ?
Florin Coras0d427d82018-06-27 03:24:07 -07001457 IP46_TYPE_IP4 : IP46_TYPE_IP6,
Florin Coras7e12d942018-06-27 14:32:43 -07001458 clib_net_to_host_u16 (session->transport.rmt_port),
Ping Yu34a3a082018-11-30 19:16:17 -05001459 vppcom_proto_str (session->session_type));
Dave Wallace543852a2017-08-03 02:11:34 -04001460
Florin Coras070453d2018-08-24 17:04:27 -07001461 /*
1462 * Send connect request and wait for reply from vpp
1463 */
Florin Coras134a9962018-08-28 11:32:04 -07001464 vppcom_send_connect_sock (session);
Florin Coras070453d2018-08-24 17:04:27 -07001465 rv = vppcom_wait_for_session_state_change (session_index, STATE_CONNECT,
1466 vcm->cfg.session_timeout);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001467
Florin Coras134a9962018-08-28 11:32:04 -07001468 session = vcl_session_get (wrk, session_index);
Dave Wallace7876d392017-10-19 03:53:57 -04001469
Florin Coras070453d2018-08-24 17:04:27 -07001470 if (PREDICT_FALSE (rv))
Dave Wallaceee45d412017-11-24 21:44:06 -05001471 {
Dave Wallaceee45d412017-11-24 21:44:06 -05001472 if (VPPCOM_DEBUG > 0)
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001473 {
1474 if (session)
Florin Coras0d427d82018-06-27 03:24:07 -07001475 clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: connect "
Florin Coras134a9962018-08-28 11:32:04 -07001476 "failed! returning %d (%s)", getpid (),
1477 session->vpp_handle, session_handle, rv,
1478 vppcom_retval_str (rv));
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001479 else
1480 clib_warning ("VCL<%d>: no session for sid %u: connect failed! "
1481 "returning %d (%s)", getpid (),
Florin Coras134a9962018-08-28 11:32:04 -07001482 session_handle, rv, vppcom_retval_str (rv));
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001483 }
Dave Wallaceee45d412017-11-24 21:44:06 -05001484 }
Florin Coras0d427d82018-06-27 03:24:07 -07001485 else
1486 VDBG (0, "VCL<%d>: vpp handle 0x%llx, sid %u: connected!",
Florin Coras134a9962018-08-28 11:32:04 -07001487 getpid (), session->vpp_handle, session_handle);
Dave Wallaceee45d412017-11-24 21:44:06 -05001488
Dave Wallace4878cbe2017-11-21 03:45:09 -05001489 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04001490}
1491
Florin Coras54693d22018-07-17 10:46:29 -07001492static u8
1493vcl_is_rx_evt_for_session (session_event_t * e, u32 sid, u8 is_ct)
1494{
1495 if (!is_ct)
1496 return (e->event_type == FIFO_EVENT_APP_RX
1497 && e->fifo->client_session_index == sid);
1498 else
1499 return (e->event_type == SESSION_IO_EVT_CT_TX);
1500}
1501
Florin Coras460dce62018-07-27 05:45:06 -07001502static inline u8
1503vcl_session_is_readable (vcl_session_t * s)
1504{
1505 return ((s->session_state & STATE_OPEN)
1506 || (s->session_state == STATE_LISTEN
1507 && s->session_type == VPPCOM_PROTO_UDP));
1508}
1509
Steven58f464e2017-10-25 12:33:12 -07001510static inline int
Florin Coras134a9962018-08-28 11:32:04 -07001511vppcom_session_read_internal (uint32_t session_handle, void *buf, int n,
Steven58f464e2017-10-25 12:33:12 -07001512 u8 peek)
Dave Wallace543852a2017-08-03 02:11:34 -04001513{
Florin Coras134a9962018-08-28 11:32:04 -07001514 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras54693d22018-07-17 10:46:29 -07001515 int n_read = 0, rv, is_nonblocking;
Florin Coras460dce62018-07-27 05:45:06 -07001516 vcl_session_t *s = 0;
Dave Wallace543852a2017-08-03 02:11:34 -04001517 svm_fifo_t *rx_fifo;
Florin Coras54693d22018-07-17 10:46:29 -07001518 svm_msg_q_msg_t msg;
1519 session_event_t *e;
1520 svm_msg_q_t *mq;
Florin Coras41c9e042018-09-11 00:10:41 -07001521 u8 is_ct;
Dave Wallace543852a2017-08-03 02:11:34 -04001522
Florin Coras070453d2018-08-24 17:04:27 -07001523 if (PREDICT_FALSE (!buf))
1524 return VPPCOM_EINVAL;
Dave Wallace543852a2017-08-03 02:11:34 -04001525
Florin Coras134a9962018-08-28 11:32:04 -07001526 s = vcl_session_get_w_handle (wrk, session_handle);
Florin Coras2cba8532018-09-11 16:33:36 -07001527 if (PREDICT_FALSE (!s || s->is_vep))
Florin Coras070453d2018-08-24 17:04:27 -07001528 return VPPCOM_EBADFD;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001529
Florin Coras460dce62018-07-27 05:45:06 -07001530 if (PREDICT_FALSE (!vcl_session_is_readable (s)))
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001531 {
Florin Coras460dce62018-07-27 05:45:06 -07001532 session_state_t state = s->session_state;
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08001533 rv = ((state & STATE_DISCONNECT) ? VPPCOM_ECONNRESET : VPPCOM_ENOTCONN);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001534
Florin Corasb0f662f2018-12-27 14:51:46 -08001535 VDBG (0, "session handle %u[0x%llx] is not open! state 0x%x (%s),"
1536 " returning %d (%s)", session_handle, s->vpp_handle, state,
Florin Coras0d427d82018-06-27 03:24:07 -07001537 vppcom_session_state_str (state), rv, vppcom_retval_str (rv));
Florin Coras070453d2018-08-24 17:04:27 -07001538 return rv;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001539 }
1540
Florin Coras2cba8532018-09-11 16:33:36 -07001541 is_nonblocking = VCL_SESS_ATTR_TEST (s->attr, VCL_SESS_ATTR_NONBLOCK);
Florin Coras41c9e042018-09-11 00:10:41 -07001542 is_ct = vcl_session_is_ct (s);
1543 mq = is_ct ? s->our_evt_q : wrk->app_event_queue;
Florin Coras2cba8532018-09-11 16:33:36 -07001544 rx_fifo = s->rx_fifo;
Florin Corasaa27eb92018-10-13 12:20:01 -07001545 s->has_rx_evt = 0;
Dave Wallacef7f809c2017-10-03 01:48:42 -04001546
Florin Coras54693d22018-07-17 10:46:29 -07001547 if (svm_fifo_is_empty (rx_fifo))
Dave Wallacef7f809c2017-10-03 01:48:42 -04001548 {
Florin Coras54693d22018-07-17 10:46:29 -07001549 if (is_nonblocking)
Dave Wallace4878cbe2017-11-21 03:45:09 -05001550 {
Florin Coras41c9e042018-09-11 00:10:41 -07001551 svm_fifo_unset_event (rx_fifo);
Florin Corasaa27eb92018-10-13 12:20:01 -07001552 return VPPCOM_EWOULDBLOCK;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001553 }
Florin Coras41c9e042018-09-11 00:10:41 -07001554 while (svm_fifo_is_empty (rx_fifo))
Florin Coras54693d22018-07-17 10:46:29 -07001555 {
Florin Coras41c9e042018-09-11 00:10:41 -07001556 svm_fifo_unset_event (rx_fifo);
Florin Coras99368312018-08-02 10:45:44 -07001557 svm_msg_q_lock (mq);
Florin Coras54693d22018-07-17 10:46:29 -07001558 if (svm_msg_q_is_empty (mq))
1559 svm_msg_q_wait (mq);
Florin Coras99368312018-08-02 10:45:44 -07001560
Florin Coras54693d22018-07-17 10:46:29 -07001561 svm_msg_q_sub_w_lock (mq, &msg);
1562 e = svm_msg_q_msg_data (mq, &msg);
Florin Coras99368312018-08-02 10:45:44 -07001563 svm_msg_q_unlock (mq);
Florin Coras41c9e042018-09-11 00:10:41 -07001564 if (!vcl_is_rx_evt_for_session (e, s->session_index, is_ct))
Florin Coras05ce4b82018-12-15 18:30:43 -08001565 vcl_handle_mq_event (wrk, e);
Florin Coras54693d22018-07-17 10:46:29 -07001566 svm_msg_q_free_msg (mq, &msg);
Florin Coras41c9e042018-09-11 00:10:41 -07001567
Florin Coras05ce4b82018-12-15 18:30:43 -08001568 if (PREDICT_FALSE (s->session_state == STATE_DISCONNECT))
1569 return VPPCOM_ECONNRESET;
Florin Coras54693d22018-07-17 10:46:29 -07001570 }
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001571 }
Florin Coras54693d22018-07-17 10:46:29 -07001572
Florin Coras460dce62018-07-27 05:45:06 -07001573 if (s->is_dgram)
Florin Coras99368312018-08-02 10:45:44 -07001574 n_read = app_recv_dgram_raw (rx_fifo, buf, n, &s->transport, 0, peek);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001575 else
Florin Coras99368312018-08-02 10:45:44 -07001576 n_read = app_recv_stream_raw (rx_fifo, buf, n, 0, peek);
Florin Coras54693d22018-07-17 10:46:29 -07001577
Florin Coras41c9e042018-09-11 00:10:41 -07001578 if (svm_fifo_is_empty (rx_fifo))
1579 svm_fifo_unset_event (rx_fifo);
1580
Florin Coras1bcad5c2019-01-09 20:04:38 -08001581 if (is_ct && svm_fifo_needs_tx_ntf (rx_fifo, n_read))
Florin Coras99368312018-08-02 10:45:44 -07001582 {
Florin Coras1bcad5c2019-01-09 20:04:38 -08001583 svm_fifo_clear_tx_ntf (s->rx_fifo);
Florin Coras58c101a2018-10-06 13:49:16 -07001584 app_send_io_evt_to_vpp (s->vpp_evt_q, s->rx_fifo, SESSION_IO_EVT_CT_RX,
1585 SVM_Q_WAIT);
Florin Coras99368312018-08-02 10:45:44 -07001586 }
Florin Coras54693d22018-07-17 10:46:29 -07001587
Florin Corasa7a1a222018-12-30 17:11:31 -08001588 VDBG (2, "vpp handle 0x%llx, sid %u: read %d bytes from (%p)",
1589 s->vpp_handle, session_handle, n_read, rx_fifo);
Florin Coras2cba8532018-09-11 16:33:36 -07001590
Florin Coras54693d22018-07-17 10:46:29 -07001591 return n_read;
Dave Wallace543852a2017-08-03 02:11:34 -04001592}
1593
Steven58f464e2017-10-25 12:33:12 -07001594int
Florin Coras134a9962018-08-28 11:32:04 -07001595vppcom_session_read (uint32_t session_handle, void *buf, size_t n)
Steven58f464e2017-10-25 12:33:12 -07001596{
Florin Coras134a9962018-08-28 11:32:04 -07001597 return (vppcom_session_read_internal (session_handle, buf, n, 0));
Steven58f464e2017-10-25 12:33:12 -07001598}
1599
1600static int
Florin Coras134a9962018-08-28 11:32:04 -07001601vppcom_session_peek (uint32_t session_handle, void *buf, int n)
Steven58f464e2017-10-25 12:33:12 -07001602{
Florin Coras134a9962018-08-28 11:32:04 -07001603 return (vppcom_session_read_internal (session_handle, buf, n, 1));
Steven58f464e2017-10-25 12:33:12 -07001604}
1605
Florin Coras2cba8532018-09-11 16:33:36 -07001606int
1607vppcom_session_read_segments (uint32_t session_handle,
1608 vppcom_data_segments_t ds)
1609{
1610 vcl_worker_t *wrk = vcl_worker_get_current ();
1611 int n_read = 0, rv, is_nonblocking;
1612 vcl_session_t *s = 0;
1613 svm_fifo_t *rx_fifo;
1614 svm_msg_q_msg_t msg;
1615 session_event_t *e;
1616 svm_msg_q_t *mq;
1617 u8 is_ct;
1618
1619 s = vcl_session_get_w_handle (wrk, session_handle);
1620 if (PREDICT_FALSE (!s || s->is_vep))
1621 return VPPCOM_EBADFD;
1622
1623 if (PREDICT_FALSE (!vcl_session_is_readable (s)))
1624 {
1625 session_state_t state = s->session_state;
1626 rv = ((state & STATE_DISCONNECT) ? VPPCOM_ECONNRESET : VPPCOM_ENOTCONN);
1627 return rv;
1628 }
1629
1630 is_nonblocking = VCL_SESS_ATTR_TEST (s->attr, VCL_SESS_ATTR_NONBLOCK);
1631 is_ct = vcl_session_is_ct (s);
1632 mq = is_ct ? s->our_evt_q : wrk->app_event_queue;
1633 rx_fifo = s->rx_fifo;
Florin Corasaa27eb92018-10-13 12:20:01 -07001634 s->has_rx_evt = 0;
Florin Coras2cba8532018-09-11 16:33:36 -07001635
1636 if (svm_fifo_is_empty (rx_fifo))
1637 {
1638 if (is_nonblocking)
1639 {
1640 svm_fifo_unset_event (rx_fifo);
Florin Corasaa27eb92018-10-13 12:20:01 -07001641 return VPPCOM_EWOULDBLOCK;
Florin Coras2cba8532018-09-11 16:33:36 -07001642 }
1643 while (svm_fifo_is_empty (rx_fifo))
1644 {
1645 svm_fifo_unset_event (rx_fifo);
1646 svm_msg_q_lock (mq);
1647 if (svm_msg_q_is_empty (mq))
1648 svm_msg_q_wait (mq);
1649
1650 svm_msg_q_sub_w_lock (mq, &msg);
1651 e = svm_msg_q_msg_data (mq, &msg);
1652 svm_msg_q_unlock (mq);
1653 if (!vcl_is_rx_evt_for_session (e, s->session_index, is_ct))
Florin Coras05ce4b82018-12-15 18:30:43 -08001654 vcl_handle_mq_event (wrk, e);
Florin Coras2cba8532018-09-11 16:33:36 -07001655 svm_msg_q_free_msg (mq, &msg);
1656
Florin Coras05ce4b82018-12-15 18:30:43 -08001657 if (PREDICT_FALSE (s->session_state == STATE_DISCONNECT))
1658 return VPPCOM_ECONNRESET;
Florin Coras2cba8532018-09-11 16:33:36 -07001659 }
1660 }
1661
1662 n_read = svm_fifo_segments (rx_fifo, (svm_fifo_segment_t *) ds);
1663 svm_fifo_unset_event (rx_fifo);
1664
1665 if (is_ct && n_read + svm_fifo_max_dequeue (rx_fifo) == rx_fifo->nitems)
1666 {
1667 /* If the peer is not polling send notification */
1668 if (!svm_fifo_has_event (s->rx_fifo))
1669 app_send_io_evt_to_vpp (s->vpp_evt_q, s->rx_fifo,
1670 SESSION_IO_EVT_CT_RX, SVM_Q_WAIT);
1671 }
1672
1673 return n_read;
1674}
1675
1676void
1677vppcom_session_free_segments (uint32_t session_handle,
1678 vppcom_data_segments_t ds)
1679{
1680 vcl_worker_t *wrk = vcl_worker_get_current ();
1681 vcl_session_t *s;
1682
1683 s = vcl_session_get_w_handle (wrk, session_handle);
1684 if (PREDICT_FALSE (!s || s->is_vep))
1685 return;
1686
1687 svm_fifo_segments_free (s->rx_fifo, (svm_fifo_segment_t *) ds);
1688}
1689
Dave Wallace543852a2017-08-03 02:11:34 -04001690static inline int
Florin Coras54693d22018-07-17 10:46:29 -07001691vppcom_session_read_ready (vcl_session_t * session)
Dave Wallace543852a2017-08-03 02:11:34 -04001692{
Dave Wallace543852a2017-08-03 02:11:34 -04001693 /* Assumes caller has acquired spinlock: vcm->sessions_lockp */
Dave Wallace4878cbe2017-11-21 03:45:09 -05001694 if (PREDICT_FALSE (session->is_vep))
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001695 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001696 clib_warning ("VCL<%d>: ERROR: sid %u: cannot read from an "
Florin Coras134a9962018-08-28 11:32:04 -07001697 "epoll session!", getpid (), session->session_index);
Florin Coras54693d22018-07-17 10:46:29 -07001698 return VPPCOM_EBADFD;
1699 }
1700
1701 if (PREDICT_FALSE (!(session->session_state & (STATE_OPEN | STATE_LISTEN))))
1702 {
1703 session_state_t state = session->session_state;
1704 int rv;
1705
1706 rv = ((state & STATE_DISCONNECT) ? VPPCOM_ECONNRESET : VPPCOM_ENOTCONN);
1707
1708 VDBG (1, "VCL<%d>: vpp handle 0x%llx, sid %u: session is not open!"
1709 " state 0x%x (%s), returning %d (%s)", getpid (),
Florin Coras134a9962018-08-28 11:32:04 -07001710 session->vpp_handle, session->session_index, state,
Florin Coras54693d22018-07-17 10:46:29 -07001711 vppcom_session_state_str (state), rv, vppcom_retval_str (rv));
1712 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04001713 }
Dave Wallace33e002b2017-09-06 01:20:02 -04001714
Florin Coras7e12d942018-06-27 14:32:43 -07001715 if (session->session_state & STATE_LISTEN)
Florin Coras54693d22018-07-17 10:46:29 -07001716 return clib_fifo_elts (session->accept_evts_fifo);
1717
1718 return svm_fifo_max_dequeue (session->rx_fifo);
1719}
1720
Florin Coras2cba8532018-09-11 16:33:36 -07001721int
1722vppcom_data_segment_copy (void *buf, vppcom_data_segments_t ds, u32 max_bytes)
1723{
1724 u32 first_copy = clib_min (ds[0].len, max_bytes);
Dave Barach178cf492018-11-13 16:34:13 -05001725 clib_memcpy_fast (buf, ds[0].data, first_copy);
Florin Coras2cba8532018-09-11 16:33:36 -07001726 if (first_copy < max_bytes)
1727 {
Dave Barach178cf492018-11-13 16:34:13 -05001728 clib_memcpy_fast (buf + first_copy, ds[1].data,
1729 clib_min (ds[1].len, max_bytes - first_copy));
Florin Coras2cba8532018-09-11 16:33:36 -07001730 }
1731 return 0;
1732}
1733
Florin Coras54693d22018-07-17 10:46:29 -07001734static u8
1735vcl_is_tx_evt_for_session (session_event_t * e, u32 sid, u8 is_ct)
1736{
1737 if (!is_ct)
1738 return (e->event_type == FIFO_EVENT_APP_TX
1739 && e->fifo->client_session_index == sid);
Dave Wallace543852a2017-08-03 02:11:34 -04001740 else
Florin Coras54693d22018-07-17 10:46:29 -07001741 return (e->event_type == SESSION_IO_EVT_CT_RX);
Dave Wallace543852a2017-08-03 02:11:34 -04001742}
1743
Florin Coras42ceddb2018-12-12 10:56:01 -08001744static inline int
1745vppcom_session_write_inline (uint32_t session_handle, void *buf, size_t n,
1746 u8 is_flush)
Dave Wallace543852a2017-08-03 02:11:34 -04001747{
Florin Coras134a9962018-08-28 11:32:04 -07001748 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras54693d22018-07-17 10:46:29 -07001749 int rv, n_write, is_nonblocking;
Florin Coras460dce62018-07-27 05:45:06 -07001750 vcl_session_t *s = 0;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001751 svm_fifo_t *tx_fifo = 0;
Florin Coras460dce62018-07-27 05:45:06 -07001752 session_evt_type_t et;
Florin Coras54693d22018-07-17 10:46:29 -07001753 svm_msg_q_msg_t msg;
1754 session_event_t *e;
Florin Coras3c2fed52018-07-04 04:15:05 -07001755 svm_msg_q_t *mq;
Florin Coras0e88e852018-09-17 22:09:02 -07001756 u8 is_ct;
Dave Wallace543852a2017-08-03 02:11:34 -04001757
Florin Coras070453d2018-08-24 17:04:27 -07001758 if (PREDICT_FALSE (!buf))
1759 return VPPCOM_EINVAL;
Dave Wallace543852a2017-08-03 02:11:34 -04001760
Florin Coras134a9962018-08-28 11:32:04 -07001761 s = vcl_session_get_w_handle (wrk, session_handle);
Florin Coras070453d2018-08-24 17:04:27 -07001762 if (PREDICT_FALSE (!s))
1763 return VPPCOM_EBADFD;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001764
Florin Coras460dce62018-07-27 05:45:06 -07001765 if (PREDICT_FALSE (s->is_vep))
Dave Wallace543852a2017-08-03 02:11:34 -04001766 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001767 clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: "
Dave Wallaceee45d412017-11-24 21:44:06 -05001768 "cannot write to an epoll session!",
Florin Coras134a9962018-08-28 11:32:04 -07001769 getpid (), s->vpp_handle, session_handle);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001770
Florin Coras070453d2018-08-24 17:04:27 -07001771 return VPPCOM_EBADFD;
Dave Wallace543852a2017-08-03 02:11:34 -04001772 }
1773
Florin Coras0e88e852018-09-17 22:09:02 -07001774 if (PREDICT_FALSE (!(s->session_state & STATE_OPEN)))
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001775 {
Florin Coras460dce62018-07-27 05:45:06 -07001776 session_state_t state = s->session_state;
Florin Coras54693d22018-07-17 10:46:29 -07001777 rv = ((state & STATE_DISCONNECT) ? VPPCOM_ECONNRESET : VPPCOM_ENOTCONN);
Florin Coras0d427d82018-06-27 03:24:07 -07001778 VDBG (1, "VCL<%d>: vpp handle 0x%llx, sid %u: session is not open! "
Florin Coras0e88e852018-09-17 22:09:02 -07001779 "state 0x%x (%s)", getpid (), s->vpp_handle, session_handle,
Florin Coras0d427d82018-06-27 03:24:07 -07001780 state, vppcom_session_state_str (state));
Florin Coras070453d2018-08-24 17:04:27 -07001781 return rv;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001782 }
1783
Florin Coras0e88e852018-09-17 22:09:02 -07001784 tx_fifo = s->tx_fifo;
1785 is_ct = vcl_session_is_ct (s);
1786 is_nonblocking = VCL_SESS_ATTR_TEST (s->attr, VCL_SESS_ATTR_NONBLOCK);
1787 mq = is_ct ? s->our_evt_q : wrk->app_event_queue;
Florin Coras54693d22018-07-17 10:46:29 -07001788 if (svm_fifo_is_full (tx_fifo))
Dave Wallace543852a2017-08-03 02:11:34 -04001789 {
Florin Coras54693d22018-07-17 10:46:29 -07001790 if (is_nonblocking)
1791 {
Florin Coras070453d2018-08-24 17:04:27 -07001792 return VPPCOM_EWOULDBLOCK;
Florin Coras54693d22018-07-17 10:46:29 -07001793 }
Florin Coras60f1fc12018-08-16 14:57:31 -07001794 while (svm_fifo_is_full (tx_fifo))
Florin Coras54693d22018-07-17 10:46:29 -07001795 {
Florin Coras1bcad5c2019-01-09 20:04:38 -08001796 svm_fifo_add_want_tx_ntf (tx_fifo, SVM_FIFO_WANT_TX_NOTIF);
Florin Coras99368312018-08-02 10:45:44 -07001797 svm_msg_q_lock (mq);
Florin Corasaa27eb92018-10-13 12:20:01 -07001798 if (svm_msg_q_is_empty (mq))
1799 svm_msg_q_wait (mq);
Florin Coras0e88e852018-09-17 22:09:02 -07001800
Florin Coras54693d22018-07-17 10:46:29 -07001801 svm_msg_q_sub_w_lock (mq, &msg);
1802 e = svm_msg_q_msg_data (mq, &msg);
Florin Coras99368312018-08-02 10:45:44 -07001803 svm_msg_q_unlock (mq);
1804
Florin Coras0e88e852018-09-17 22:09:02 -07001805 if (!vcl_is_tx_evt_for_session (e, s->session_index, is_ct))
Florin Coras86f04502018-09-12 16:08:01 -07001806 vcl_handle_mq_event (wrk, e);
Florin Coras54693d22018-07-17 10:46:29 -07001807 svm_msg_q_free_msg (mq, &msg);
Florin Coras05ce4b82018-12-15 18:30:43 -08001808
1809 if (PREDICT_FALSE (!(s->session_state & STATE_OPEN)))
1810 return VPPCOM_ECONNRESET;
Florin Coras54693d22018-07-17 10:46:29 -07001811 }
Dave Wallace543852a2017-08-03 02:11:34 -04001812 }
Dave Wallace543852a2017-08-03 02:11:34 -04001813
Florin Coras460dce62018-07-27 05:45:06 -07001814 ASSERT (FIFO_EVENT_APP_TX + 1 == SESSION_IO_EVT_CT_TX);
1815 et = FIFO_EVENT_APP_TX + vcl_session_is_ct (s);
Florin Coras42ceddb2018-12-12 10:56:01 -08001816 if (is_flush && !vcl_session_is_ct (s))
1817 et = SESSION_IO_EVT_TX_FLUSH;
1818
Florin Coras460dce62018-07-27 05:45:06 -07001819 if (s->is_dgram)
1820 n_write = app_send_dgram_raw (tx_fifo, &s->transport,
1821 s->vpp_evt_q, buf, n, et, SVM_Q_WAIT);
1822 else
1823 n_write = app_send_stream_raw (tx_fifo, s->vpp_evt_q, buf, n, et,
1824 SVM_Q_WAIT);
Keith Burns (alagalah)410bcca2018-03-23 13:42:49 -07001825
Florin Coras460dce62018-07-27 05:45:06 -07001826 ASSERT (n_write > 0);
Dave Wallace543852a2017-08-03 02:11:34 -04001827
Florin Coras0e88e852018-09-17 22:09:02 -07001828 VDBG (2, "VCL<%d>: vpp handle 0x%llx, sid %u: wrote %d bytes", getpid (),
1829 s->vpp_handle, session_handle, n_write);
1830
Florin Coras54693d22018-07-17 10:46:29 -07001831 return n_write;
Dave Wallace543852a2017-08-03 02:11:34 -04001832}
1833
Florin Coras42ceddb2018-12-12 10:56:01 -08001834int
1835vppcom_session_write (uint32_t session_handle, void *buf, size_t n)
1836{
1837 return vppcom_session_write_inline (session_handle, buf, n,
1838 0 /* is_flush */ );
1839}
1840
Florin Corasb0f662f2018-12-27 14:51:46 -08001841int
1842vppcom_session_write_msg (uint32_t session_handle, void *buf, size_t n)
1843{
1844 return vppcom_session_write_inline (session_handle, buf, n,
1845 1 /* is_flush */ );
1846}
1847
1848
Florin Coras99368312018-08-02 10:45:44 -07001849static vcl_session_t *
Florin Coras134a9962018-08-28 11:32:04 -07001850vcl_ct_session_get_from_fifo (vcl_worker_t * wrk, svm_fifo_t * f, u8 type)
Florin Coras99368312018-08-02 10:45:44 -07001851{
1852 vcl_session_t *s;
Florin Coras134a9962018-08-28 11:32:04 -07001853 s = vcl_session_get (wrk, f->client_session_index);
Florin Coras99368312018-08-02 10:45:44 -07001854 if (s)
1855 {
1856 /* rx fifo */
1857 if (type == 0 && s->rx_fifo == f)
1858 return s;
1859 /* tx fifo */
1860 if (type == 1 && s->tx_fifo == f)
1861 return s;
1862 }
Florin Coras134a9962018-08-28 11:32:04 -07001863 s = vcl_session_get (wrk, f->master_session_index);
Florin Coras99368312018-08-02 10:45:44 -07001864 if (s)
1865 {
1866 if (type == 0 && s->rx_fifo == f)
1867 return s;
1868 if (type == 1 && s->tx_fifo == f)
1869 return s;
1870 }
1871 return 0;
1872}
1873
Dave Wallace543852a2017-08-03 02:11:34 -04001874static inline int
Florin Coras134a9962018-08-28 11:32:04 -07001875vppcom_session_write_ready (vcl_session_t * session)
Dave Wallace543852a2017-08-03 02:11:34 -04001876{
Dave Wallace543852a2017-08-03 02:11:34 -04001877 /* Assumes caller has acquired spinlock: vcm->sessions_lockp */
Dave Wallace4878cbe2017-11-21 03:45:09 -05001878 if (PREDICT_FALSE (session->is_vep))
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001879 {
Florin Coras294afe22019-01-07 17:49:17 -08001880 VDBG (0, "session %u [0x%llx]: cannot write to an epoll session!",
1881 session->session_index, session->vpp_handle);
Florin Coras54693d22018-07-17 10:46:29 -07001882 return VPPCOM_EBADFD;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001883 }
1884
Florin Coras7e12d942018-06-27 14:32:43 -07001885 if (PREDICT_FALSE (session->session_state & STATE_LISTEN))
Dave Wallace33e002b2017-09-06 01:20:02 -04001886 {
Florin Coras294afe22019-01-07 17:49:17 -08001887 if (session->tx_fifo)
1888 return svm_fifo_max_enqueue (session->tx_fifo);
1889 else
1890 return VPPCOM_EBADFD;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001891 }
1892
Florin Coras54693d22018-07-17 10:46:29 -07001893 if (PREDICT_FALSE (!(session->session_state & STATE_OPEN)))
Dave Wallace4878cbe2017-11-21 03:45:09 -05001894 {
Florin Coras7e12d942018-06-27 14:32:43 -07001895 session_state_t state = session->session_state;
Florin Coras54693d22018-07-17 10:46:29 -07001896 int rv;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001897
Keith Burns (alagalah)56a0d062018-02-15 07:52:50 -08001898 rv = ((state & STATE_DISCONNECT) ? VPPCOM_ECONNRESET : VPPCOM_ENOTCONN);
Florin Coras294afe22019-01-07 17:49:17 -08001899 VDBG (0, "session %u [0x%llx]: session is not open! state 0x%x (%s), "
1900 "returning %d (%s)", session->session_index, session->vpp_handle,
1901 state, vppcom_session_state_str (state), rv,
1902 vppcom_retval_str (rv));
Florin Coras54693d22018-07-17 10:46:29 -07001903 return rv;
Dave Wallace33e002b2017-09-06 01:20:02 -04001904 }
1905
Florin Coras54693d22018-07-17 10:46:29 -07001906 return svm_fifo_max_enqueue (session->tx_fifo);
1907}
1908
Florin Coras6d4bb422018-09-04 22:07:27 -07001909#define vcl_fifo_rx_evt_valid_or_break(_fifo) \
1910if (PREDICT_FALSE (svm_fifo_is_empty (_fifo))) \
1911 { \
1912 svm_fifo_unset_event (_fifo); \
1913 if (svm_fifo_is_empty (_fifo)) \
Florin Coras41c9e042018-09-11 00:10:41 -07001914 break; \
Florin Coras6d4bb422018-09-04 22:07:27 -07001915 } \
1916
Florin Coras86f04502018-09-12 16:08:01 -07001917static void
1918vcl_select_handle_mq_event (vcl_worker_t * wrk, session_event_t * e,
1919 unsigned long n_bits, unsigned long *read_map,
1920 unsigned long *write_map,
1921 unsigned long *except_map, u32 * bits_set)
Florin Coras54693d22018-07-17 10:46:29 -07001922{
1923 session_disconnected_msg_t *disconnected_msg;
Florin Coras99368312018-08-02 10:45:44 -07001924 session_connected_msg_t *connected_msg;
Florin Coras54693d22018-07-17 10:46:29 -07001925 vcl_session_t *session;
Florin Coras86f04502018-09-12 16:08:01 -07001926 u32 sid;
1927
1928 switch (e->event_type)
1929 {
1930 case FIFO_EVENT_APP_RX:
1931 vcl_fifo_rx_evt_valid_or_break (e->fifo);
1932 sid = e->fifo->client_session_index;
1933 session = vcl_session_get (wrk, sid);
1934 if (!session)
1935 break;
1936 if (sid < n_bits && read_map)
1937 {
David Johnsond9818dd2018-12-14 14:53:41 -05001938 clib_bitmap_set_no_check ((uword *) read_map, sid, 1);
Florin Coras86f04502018-09-12 16:08:01 -07001939 *bits_set += 1;
1940 }
1941 break;
1942 case FIFO_EVENT_APP_TX:
1943 sid = e->fifo->client_session_index;
1944 session = vcl_session_get (wrk, sid);
1945 if (!session)
1946 break;
1947 if (sid < n_bits && write_map)
1948 {
David Johnsond9818dd2018-12-14 14:53:41 -05001949 clib_bitmap_set_no_check ((uword *) write_map, sid, 1);
Florin Coras86f04502018-09-12 16:08:01 -07001950 *bits_set += 1;
1951 }
1952 break;
1953 case SESSION_IO_EVT_CT_TX:
1954 vcl_fifo_rx_evt_valid_or_break (e->fifo);
1955 session = vcl_ct_session_get_from_fifo (wrk, e->fifo, 0);
1956 if (!session)
1957 break;
1958 sid = session->session_index;
1959 if (sid < n_bits && read_map)
1960 {
David Johnsond9818dd2018-12-14 14:53:41 -05001961 clib_bitmap_set_no_check ((uword *) read_map, sid, 1);
Florin Coras86f04502018-09-12 16:08:01 -07001962 *bits_set += 1;
1963 }
1964 break;
1965 case SESSION_IO_EVT_CT_RX:
1966 session = vcl_ct_session_get_from_fifo (wrk, e->fifo, 1);
1967 if (!session)
1968 break;
1969 sid = session->session_index;
1970 if (sid < n_bits && write_map)
1971 {
David Johnsond9818dd2018-12-14 14:53:41 -05001972 clib_bitmap_set_no_check ((uword *) write_map, sid, 1);
Florin Coras86f04502018-09-12 16:08:01 -07001973 *bits_set += 1;
1974 }
1975 break;
1976 case SESSION_CTRL_EVT_ACCEPTED:
Florin Coras3c7d4f92018-12-14 11:28:43 -08001977 session = vcl_session_accepted (wrk,
1978 (session_accepted_msg_t *) e->data);
Florin Coras86f04502018-09-12 16:08:01 -07001979 if (!session)
Florin Coras3c7d4f92018-12-14 11:28:43 -08001980 break;
Florin Coras86f04502018-09-12 16:08:01 -07001981 sid = session->session_index;
1982 if (sid < n_bits && read_map)
1983 {
David Johnsond9818dd2018-12-14 14:53:41 -05001984 clib_bitmap_set_no_check ((uword *) read_map, sid, 1);
Florin Coras86f04502018-09-12 16:08:01 -07001985 *bits_set += 1;
1986 }
1987 break;
1988 case SESSION_CTRL_EVT_CONNECTED:
1989 connected_msg = (session_connected_msg_t *) e->data;
1990 vcl_session_connected_handler (wrk, connected_msg);
1991 break;
1992 case SESSION_CTRL_EVT_DISCONNECTED:
1993 disconnected_msg = (session_disconnected_msg_t *) e->data;
Florin Coras3c7d4f92018-12-14 11:28:43 -08001994 session = vcl_session_disconnected_handler (wrk, disconnected_msg);
1995 if (!session)
1996 break;
1997 sid = session->session_index;
Florin Coras86f04502018-09-12 16:08:01 -07001998 if (sid < n_bits && except_map)
1999 {
David Johnsond9818dd2018-12-14 14:53:41 -05002000 clib_bitmap_set_no_check ((uword *) except_map, sid, 1);
Florin Coras86f04502018-09-12 16:08:01 -07002001 *bits_set += 1;
2002 }
2003 break;
2004 case SESSION_CTRL_EVT_RESET:
2005 sid = vcl_session_reset_handler (wrk, (session_reset_msg_t *) e->data);
2006 if (sid < n_bits && except_map)
2007 {
David Johnsond9818dd2018-12-14 14:53:41 -05002008 clib_bitmap_set_no_check ((uword *) except_map, sid, 1);
Florin Coras86f04502018-09-12 16:08:01 -07002009 *bits_set += 1;
2010 }
2011 break;
Florin Coras30e79c22019-01-02 19:31:22 -08002012 case SESSION_CTRL_EVT_WORKER_UPDATE_REPLY:
2013 vcl_session_worker_update_reply_handler (wrk, e->data);
2014 break;
2015 case SESSION_CTRL_EVT_REQ_WORKER_UPDATE:
2016 vcl_session_req_worker_update_handler (wrk, e->data);
2017 break;
Florin Coras86f04502018-09-12 16:08:01 -07002018 default:
2019 clib_warning ("unhandled: %u", e->event_type);
2020 break;
2021 }
2022}
2023
2024static int
2025vcl_select_handle_mq (vcl_worker_t * wrk, svm_msg_q_t * mq,
2026 unsigned long n_bits, unsigned long *read_map,
2027 unsigned long *write_map, unsigned long *except_map,
2028 double time_to_wait, u32 * bits_set)
2029{
Florin Coras99368312018-08-02 10:45:44 -07002030 svm_msg_q_msg_t *msg;
Florin Coras54693d22018-07-17 10:46:29 -07002031 session_event_t *e;
Florin Coras86f04502018-09-12 16:08:01 -07002032 u32 i;
Florin Coras54693d22018-07-17 10:46:29 -07002033
2034 svm_msg_q_lock (mq);
2035 if (svm_msg_q_is_empty (mq))
Dave Wallace4878cbe2017-11-21 03:45:09 -05002036 {
Florin Coras54693d22018-07-17 10:46:29 -07002037 if (*bits_set)
Dave Wallace4878cbe2017-11-21 03:45:09 -05002038 {
Florin Coras54693d22018-07-17 10:46:29 -07002039 svm_msg_q_unlock (mq);
2040 return 0;
2041 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05002042
Florin Coras54693d22018-07-17 10:46:29 -07002043 if (!time_to_wait)
2044 {
2045 svm_msg_q_unlock (mq);
2046 return 0;
2047 }
2048 else if (time_to_wait < 0)
2049 {
2050 svm_msg_q_wait (mq);
2051 }
2052 else
2053 {
2054 if (svm_msg_q_timedwait (mq, time_to_wait))
2055 {
2056 svm_msg_q_unlock (mq);
2057 return 0;
2058 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05002059 }
2060 }
Florin Coras134a9962018-08-28 11:32:04 -07002061 vcl_mq_dequeue_batch (wrk, mq);
Florin Coras54693d22018-07-17 10:46:29 -07002062 svm_msg_q_unlock (mq);
2063
Florin Coras134a9962018-08-28 11:32:04 -07002064 for (i = 0; i < vec_len (wrk->mq_msg_vector); i++)
Florin Coras54693d22018-07-17 10:46:29 -07002065 {
Florin Coras134a9962018-08-28 11:32:04 -07002066 msg = vec_elt_at_index (wrk->mq_msg_vector, i);
Florin Coras99368312018-08-02 10:45:44 -07002067 e = svm_msg_q_msg_data (mq, msg);
Florin Coras86f04502018-09-12 16:08:01 -07002068 vcl_select_handle_mq_event (wrk, e, n_bits, read_map, write_map,
2069 except_map, bits_set);
Florin Coras99368312018-08-02 10:45:44 -07002070 svm_msg_q_free_msg (mq, msg);
Florin Coras54693d22018-07-17 10:46:29 -07002071 }
Florin Coras134a9962018-08-28 11:32:04 -07002072 vec_reset_length (wrk->mq_msg_vector);
Florin Coras30e79c22019-01-02 19:31:22 -08002073 vcl_handle_pending_wrk_updates (wrk);
Florin Coras54693d22018-07-17 10:46:29 -07002074 return *bits_set;
Dave Wallace543852a2017-08-03 02:11:34 -04002075}
2076
Florin Coras99368312018-08-02 10:45:44 -07002077static int
Florin Coras294afe22019-01-07 17:49:17 -08002078vppcom_select_condvar (vcl_worker_t * wrk, int n_bits,
2079 vcl_si_set * read_map, vcl_si_set * write_map,
2080 vcl_si_set * except_map, double time_to_wait,
Florin Coras134a9962018-08-28 11:32:04 -07002081 u32 * bits_set)
Florin Coras99368312018-08-02 10:45:44 -07002082{
2083 double total_wait = 0, wait_slice;
2084 vcl_cut_through_registration_t *cr;
2085
Florin Coras294afe22019-01-07 17:49:17 -08002086 time_to_wait = (time_to_wait == -1) ? 1e6 : time_to_wait;
Florin Coras134a9962018-08-28 11:32:04 -07002087 wait_slice = wrk->cut_through_registrations ? 10e-6 : time_to_wait;
Florin Coras99368312018-08-02 10:45:44 -07002088 do
2089 {
Florin Coras134a9962018-08-28 11:32:04 -07002090 vcl_ct_registration_lock (wrk);
Florin Coras99368312018-08-02 10:45:44 -07002091 /* *INDENT-OFF* */
Florin Coras134a9962018-08-28 11:32:04 -07002092 pool_foreach (cr, wrk->cut_through_registrations, ({
2093 vcl_select_handle_mq (wrk, cr->mq, n_bits, read_map, write_map, except_map,
Florin Coras99368312018-08-02 10:45:44 -07002094 0, bits_set);
2095 }));
2096 /* *INDENT-ON* */
Florin Coras134a9962018-08-28 11:32:04 -07002097 vcl_ct_registration_unlock (wrk);
Florin Coras99368312018-08-02 10:45:44 -07002098
Florin Coras134a9962018-08-28 11:32:04 -07002099 vcl_select_handle_mq (wrk, wrk->app_event_queue, n_bits, read_map,
Florin Coras294afe22019-01-07 17:49:17 -08002100 write_map, except_map, wait_slice, bits_set);
Florin Coras99368312018-08-02 10:45:44 -07002101 total_wait += wait_slice;
2102 if (*bits_set)
2103 return *bits_set;
2104 }
2105 while (total_wait < time_to_wait);
2106
2107 return 0;
2108}
2109
2110static int
Florin Coras294afe22019-01-07 17:49:17 -08002111vppcom_select_eventfd (vcl_worker_t * wrk, int n_bits,
2112 vcl_si_set * read_map, vcl_si_set * write_map,
2113 vcl_si_set * except_map, double time_to_wait,
Florin Coras134a9962018-08-28 11:32:04 -07002114 u32 * bits_set)
Florin Coras99368312018-08-02 10:45:44 -07002115{
2116 vcl_mq_evt_conn_t *mqc;
2117 int __clib_unused n_read;
2118 int n_mq_evts, i;
2119 u64 buf;
2120
Florin Coras134a9962018-08-28 11:32:04 -07002121 vec_validate (wrk->mq_events, pool_elts (wrk->mq_evt_conns));
2122 n_mq_evts = epoll_wait (wrk->mqs_epfd, wrk->mq_events,
2123 vec_len (wrk->mq_events), time_to_wait);
Florin Coras99368312018-08-02 10:45:44 -07002124 for (i = 0; i < n_mq_evts; i++)
2125 {
Florin Coras134a9962018-08-28 11:32:04 -07002126 mqc = vcl_mq_evt_conn_get (wrk, wrk->mq_events[i].data.u32);
Florin Coras99368312018-08-02 10:45:44 -07002127 n_read = read (mqc->mq_fd, &buf, sizeof (buf));
Florin Coras134a9962018-08-28 11:32:04 -07002128 vcl_select_handle_mq (wrk, mqc->mq, n_bits, read_map, write_map,
Florin Coras99368312018-08-02 10:45:44 -07002129 except_map, 0, bits_set);
2130 }
2131
2132 return (n_mq_evts > 0 ? (int) *bits_set : 0);
2133}
2134
Dave Wallace543852a2017-08-03 02:11:34 -04002135int
Florin Coras294afe22019-01-07 17:49:17 -08002136vppcom_select (int n_bits, vcl_si_set * read_map, vcl_si_set * write_map,
2137 vcl_si_set * except_map, double time_to_wait)
Dave Wallace543852a2017-08-03 02:11:34 -04002138{
Florin Coras54693d22018-07-17 10:46:29 -07002139 u32 sid, minbits = clib_max (n_bits, BITS (uword)), bits_set = 0;
Florin Coras134a9962018-08-28 11:32:04 -07002140 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras7e12d942018-06-27 14:32:43 -07002141 vcl_session_t *session = 0;
Florin Coras86f04502018-09-12 16:08:01 -07002142 int rv, i;
Dave Wallace543852a2017-08-03 02:11:34 -04002143
Dave Wallace7876d392017-10-19 03:53:57 -04002144 if (n_bits && read_map)
Dave Wallace543852a2017-08-03 02:11:34 -04002145 {
Florin Coras134a9962018-08-28 11:32:04 -07002146 clib_bitmap_validate (wrk->rd_bitmap, minbits);
Dave Barach178cf492018-11-13 16:34:13 -05002147 clib_memcpy_fast (wrk->rd_bitmap, read_map,
Florin Coras294afe22019-01-07 17:49:17 -08002148 vec_len (wrk->rd_bitmap) * sizeof (vcl_si_set));
2149 memset (read_map, 0, vec_len (wrk->rd_bitmap) * sizeof (vcl_si_set));
Dave Wallace543852a2017-08-03 02:11:34 -04002150 }
Dave Wallace7876d392017-10-19 03:53:57 -04002151 if (n_bits && write_map)
Dave Wallace543852a2017-08-03 02:11:34 -04002152 {
Florin Coras134a9962018-08-28 11:32:04 -07002153 clib_bitmap_validate (wrk->wr_bitmap, minbits);
Dave Barach178cf492018-11-13 16:34:13 -05002154 clib_memcpy_fast (wrk->wr_bitmap, write_map,
Florin Coras294afe22019-01-07 17:49:17 -08002155 vec_len (wrk->wr_bitmap) * sizeof (vcl_si_set));
2156 memset (write_map, 0, vec_len (wrk->wr_bitmap) * sizeof (vcl_si_set));
Dave Wallace543852a2017-08-03 02:11:34 -04002157 }
Dave Wallace7876d392017-10-19 03:53:57 -04002158 if (n_bits && except_map)
Dave Wallace543852a2017-08-03 02:11:34 -04002159 {
Florin Coras134a9962018-08-28 11:32:04 -07002160 clib_bitmap_validate (wrk->ex_bitmap, minbits);
Dave Barach178cf492018-11-13 16:34:13 -05002161 clib_memcpy_fast (wrk->ex_bitmap, except_map,
Florin Coras294afe22019-01-07 17:49:17 -08002162 vec_len (wrk->ex_bitmap) * sizeof (vcl_si_set));
2163 memset (except_map, 0, vec_len (wrk->ex_bitmap) * sizeof (vcl_si_set));
Dave Wallace543852a2017-08-03 02:11:34 -04002164 }
2165
Florin Coras54693d22018-07-17 10:46:29 -07002166 if (!n_bits)
2167 return 0;
2168
2169 if (!write_map)
2170 goto check_rd;
2171
2172 /* *INDENT-OFF* */
Florin Coras134a9962018-08-28 11:32:04 -07002173 clib_bitmap_foreach (sid, wrk->wr_bitmap, ({
2174 if (!(session = vcl_session_get (wrk, sid)))
Florin Coras54693d22018-07-17 10:46:29 -07002175 {
Florin Coras47c40e22018-11-26 17:01:36 -08002176 if (except_map && sid < minbits)
2177 clib_bitmap_set_no_check (except_map, sid, 1);
2178 continue;
Florin Coras54693d22018-07-17 10:46:29 -07002179 }
2180
2181 rv = svm_fifo_is_full (session->tx_fifo);
Florin Coras54693d22018-07-17 10:46:29 -07002182 if (!rv)
2183 {
David Johnsond9818dd2018-12-14 14:53:41 -05002184 clib_bitmap_set_no_check ((uword*)write_map, sid, 1);
Florin Coras54693d22018-07-17 10:46:29 -07002185 bits_set++;
2186 }
Florin Coras294afe22019-01-07 17:49:17 -08002187 else
Florin Coras1bcad5c2019-01-09 20:04:38 -08002188 svm_fifo_add_want_tx_ntf (session->tx_fifo, SVM_FIFO_WANT_TX_NOTIF);
Florin Coras54693d22018-07-17 10:46:29 -07002189 }));
2190
2191check_rd:
2192 if (!read_map)
2193 goto check_mq;
Florin Coras99368312018-08-02 10:45:44 -07002194
Florin Coras134a9962018-08-28 11:32:04 -07002195 clib_bitmap_foreach (sid, wrk->rd_bitmap, ({
2196 if (!(session = vcl_session_get (wrk, sid)))
Florin Coras54693d22018-07-17 10:46:29 -07002197 {
Florin Coras47c40e22018-11-26 17:01:36 -08002198 if (except_map && sid < minbits)
2199 clib_bitmap_set_no_check (except_map, sid, 1);
2200 continue;
Florin Coras54693d22018-07-17 10:46:29 -07002201 }
2202
2203 rv = vppcom_session_read_ready (session);
Florin Coras54693d22018-07-17 10:46:29 -07002204 if (rv)
2205 {
David Johnsond9818dd2018-12-14 14:53:41 -05002206 clib_bitmap_set_no_check ((uword*)read_map, sid, 1);
Florin Coras54693d22018-07-17 10:46:29 -07002207 bits_set++;
2208 }
2209 }));
2210 /* *INDENT-ON* */
2211
2212check_mq:
Dave Wallace543852a2017-08-03 02:11:34 -04002213
Florin Coras86f04502018-09-12 16:08:01 -07002214 for (i = 0; i < vec_len (wrk->unhandled_evts_vector); i++)
2215 {
2216 vcl_select_handle_mq_event (wrk, &wrk->unhandled_evts_vector[i], n_bits,
2217 read_map, write_map, except_map, &bits_set);
2218 }
2219 vec_reset_length (wrk->unhandled_evts_vector);
2220
Florin Coras99368312018-08-02 10:45:44 -07002221 if (vcm->cfg.use_mq_eventfd)
Florin Coras134a9962018-08-28 11:32:04 -07002222 vppcom_select_eventfd (wrk, n_bits, read_map, write_map, except_map,
Florin Coras99368312018-08-02 10:45:44 -07002223 time_to_wait, &bits_set);
2224 else
Florin Coras134a9962018-08-28 11:32:04 -07002225 vppcom_select_condvar (wrk, n_bits, read_map, write_map, except_map,
Florin Coras99368312018-08-02 10:45:44 -07002226 time_to_wait, &bits_set);
Florin Coras54693d22018-07-17 10:46:29 -07002227
Dave Wallace543852a2017-08-03 02:11:34 -04002228 return (bits_set);
2229}
2230
Dave Wallacef7f809c2017-10-03 01:48:42 -04002231static inline void
Florin Coras134a9962018-08-28 11:32:04 -07002232vep_verify_epoll_chain (vcl_worker_t * wrk, u32 vep_idx)
Dave Wallacef7f809c2017-10-03 01:48:42 -04002233{
Florin Coras7e12d942018-06-27 14:32:43 -07002234 vcl_session_t *session;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002235 vppcom_epoll_t *vep;
Dave Wallace498b3a52017-11-09 13:00:34 -05002236 u32 sid = vep_idx;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002237
Dave Wallace498b3a52017-11-09 13:00:34 -05002238 if (VPPCOM_DEBUG <= 1)
Dave Wallacef7f809c2017-10-03 01:48:42 -04002239 return;
2240
2241 /* Assumes caller has acquired spinlock: vcm->sessions_lockp */
Florin Coras134a9962018-08-28 11:32:04 -07002242 session = vcl_session_get (wrk, vep_idx);
Florin Coras070453d2018-08-24 17:04:27 -07002243 if (PREDICT_FALSE (!session))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002244 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002245 clib_warning ("VCL<%d>: ERROR: Invalid vep_idx (%u)!",
2246 getpid (), vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002247 goto done;
2248 }
2249 if (PREDICT_FALSE (!session->is_vep))
2250 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002251 clib_warning ("VCL<%d>: ERROR: vep_idx (%u) is not a vep!",
2252 getpid (), vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002253 goto done;
2254 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05002255 vep = &session->vep;
Dave Wallace048b1d62018-01-03 22:24:41 -05002256 clib_warning ("VCL<%d>: vep_idx (%u): Dumping epoll chain\n"
Dave Wallace498b3a52017-11-09 13:00:34 -05002257 "{\n"
2258 " is_vep = %u\n"
2259 " is_vep_session = %u\n"
Dave Wallace4878cbe2017-11-21 03:45:09 -05002260 " next_sid = 0x%x (%u)\n"
Dave Wallace498b3a52017-11-09 13:00:34 -05002261 " wait_cont_idx = 0x%x (%u)\n"
Dave Wallace4878cbe2017-11-21 03:45:09 -05002262 "}\n", getpid (), vep_idx,
2263 session->is_vep, session->is_vep_session,
Florin Coras134a9962018-08-28 11:32:04 -07002264 vep->next_sh, vep->next_sh,
Dave Wallace498b3a52017-11-09 13:00:34 -05002265 session->wait_cont_idx, session->wait_cont_idx);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002266
Florin Coras134a9962018-08-28 11:32:04 -07002267 for (sid = vep->next_sh; sid != ~0; sid = vep->next_sh)
Dave Wallacef7f809c2017-10-03 01:48:42 -04002268 {
Florin Coras134a9962018-08-28 11:32:04 -07002269 session = vcl_session_get (wrk, sid);
Florin Coras070453d2018-08-24 17:04:27 -07002270 if (PREDICT_FALSE (!session))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002271 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002272 clib_warning ("VCL<%d>: ERROR: Invalid sid (%u)!", getpid (), sid);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002273 goto done;
2274 }
2275 if (PREDICT_FALSE (session->is_vep))
Dave Wallace048b1d62018-01-03 22:24:41 -05002276 clib_warning ("VCL<%d>: ERROR: sid (%u) is a vep!",
2277 getpid (), vep_idx);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002278 else if (PREDICT_FALSE (!session->is_vep_session))
2279 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002280 clib_warning ("VCL<%d>: ERROR: session (%u) "
2281 "is not a vep session!", getpid (), sid);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002282 goto done;
2283 }
2284 vep = &session->vep;
Florin Coras134a9962018-08-28 11:32:04 -07002285 if (PREDICT_FALSE (vep->vep_sh != vep_idx))
Dave Wallace048b1d62018-01-03 22:24:41 -05002286 clib_warning ("VCL<%d>: ERROR: session (%u) vep_idx (%u) != "
Dave Wallace4878cbe2017-11-21 03:45:09 -05002287 "vep_idx (%u)!", getpid (),
Florin Coras134a9962018-08-28 11:32:04 -07002288 sid, session->vep.vep_sh, vep_idx);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002289 if (session->is_vep_session)
2290 {
2291 clib_warning ("vep_idx[%u]: sid 0x%x (%u)\n"
2292 "{\n"
2293 " next_sid = 0x%x (%u)\n"
2294 " prev_sid = 0x%x (%u)\n"
2295 " vep_idx = 0x%x (%u)\n"
2296 " ev.events = 0x%x\n"
2297 " ev.data.u64 = 0x%llx\n"
2298 " et_mask = 0x%x\n"
2299 "}\n",
2300 vep_idx, sid, sid,
Florin Coras134a9962018-08-28 11:32:04 -07002301 vep->next_sh, vep->next_sh,
2302 vep->prev_sh, vep->prev_sh,
2303 vep->vep_sh, vep->vep_sh,
Dave Wallace4878cbe2017-11-21 03:45:09 -05002304 vep->ev.events, vep->ev.data.u64, vep->et_mask);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002305 }
2306 }
Dave Wallacef7f809c2017-10-03 01:48:42 -04002307
2308done:
Dave Wallace048b1d62018-01-03 22:24:41 -05002309 clib_warning ("VCL<%d>: vep_idx (%u): Dump complete!\n",
2310 getpid (), vep_idx);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002311}
2312
2313int
2314vppcom_epoll_create (void)
2315{
Florin Coras134a9962018-08-28 11:32:04 -07002316 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras7e12d942018-06-27 14:32:43 -07002317 vcl_session_t *vep_session;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002318
Florin Coras134a9962018-08-28 11:32:04 -07002319 vep_session = vcl_session_alloc (wrk);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002320
2321 vep_session->is_vep = 1;
Florin Coras134a9962018-08-28 11:32:04 -07002322 vep_session->vep.vep_sh = ~0;
2323 vep_session->vep.next_sh = ~0;
2324 vep_session->vep.prev_sh = ~0;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002325 vep_session->wait_cont_idx = ~0;
Dave Wallace4878cbe2017-11-21 03:45:09 -05002326 vep_session->vpp_handle = ~0;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002327
Florin Corasa7a1a222018-12-30 17:11:31 -08002328 vcl_evt (VCL_EVT_EPOLL_CREATE, vep_session, vep_session->session_index);
2329 VDBG (0, "Created vep_idx %u", vep_session->session_index);
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002330
Florin Corasab2f6db2018-08-31 14:31:41 -07002331 return vcl_session_handle (vep_session);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002332}
2333
2334int
Florin Coras134a9962018-08-28 11:32:04 -07002335vppcom_epoll_ctl (uint32_t vep_handle, int op, uint32_t session_handle,
Dave Wallacef7f809c2017-10-03 01:48:42 -04002336 struct epoll_event *event)
2337{
Florin Coras134a9962018-08-28 11:32:04 -07002338 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras7e12d942018-06-27 14:32:43 -07002339 vcl_session_t *vep_session;
2340 vcl_session_t *session;
Florin Coras070453d2018-08-24 17:04:27 -07002341 int rv = VPPCOM_OK;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002342
Florin Coras134a9962018-08-28 11:32:04 -07002343 if (vep_handle == session_handle)
Dave Wallacef7f809c2017-10-03 01:48:42 -04002344 {
Florin Corasa7a1a222018-12-30 17:11:31 -08002345 VDBG (0, "vep_sh == session handle (%u)!", vep_handle);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002346 return VPPCOM_EINVAL;
2347 }
2348
Florin Coras134a9962018-08-28 11:32:04 -07002349 vep_session = vcl_session_get_w_handle (wrk, vep_handle);
Florin Coras070453d2018-08-24 17:04:27 -07002350 if (PREDICT_FALSE (!vep_session))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002351 {
Florin Corasa7a1a222018-12-30 17:11:31 -08002352 VDBG (0, "Invalid vep_sh (%u)!", vep_handle);
Florin Coras070453d2018-08-24 17:04:27 -07002353 return VPPCOM_EBADFD;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002354 }
2355 if (PREDICT_FALSE (!vep_session->is_vep))
2356 {
Florin Corasa7a1a222018-12-30 17:11:31 -08002357 VDBG (0, "vep_sh (%u) is not a vep!", vep_handle);
Florin Coras070453d2018-08-24 17:04:27 -07002358 return VPPCOM_EINVAL;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002359 }
2360
Florin Coras134a9962018-08-28 11:32:04 -07002361 ASSERT (vep_session->vep.vep_sh == ~0);
2362 ASSERT (vep_session->vep.prev_sh == ~0);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002363
Florin Coras134a9962018-08-28 11:32:04 -07002364 session = vcl_session_get_w_handle (wrk, session_handle);
Florin Coras070453d2018-08-24 17:04:27 -07002365 if (PREDICT_FALSE (!session))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002366 {
Florin Corasa7a1a222018-12-30 17:11:31 -08002367 VDBG (0, "Invalid session_handle (%u)!", session_handle);
Florin Coras070453d2018-08-24 17:04:27 -07002368 return VPPCOM_EBADFD;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002369 }
2370 if (PREDICT_FALSE (session->is_vep))
2371 {
Florin Corasa7a1a222018-12-30 17:11:31 -08002372 VDBG (0, "session_handle (%u) is a vep!", vep_handle);
Florin Coras070453d2018-08-24 17:04:27 -07002373 return VPPCOM_EINVAL;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002374 }
2375
2376 switch (op)
2377 {
2378 case EPOLL_CTL_ADD:
2379 if (PREDICT_FALSE (!event))
2380 {
Florin Corasa7a1a222018-12-30 17:11:31 -08002381 VDBG (0, "EPOLL_CTL_ADD: NULL pointer to epoll_event structure!");
Florin Coras070453d2018-08-24 17:04:27 -07002382 return VPPCOM_EINVAL;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002383 }
Florin Coras134a9962018-08-28 11:32:04 -07002384 if (vep_session->vep.next_sh != ~0)
Dave Wallacef7f809c2017-10-03 01:48:42 -04002385 {
Florin Coras7e12d942018-06-27 14:32:43 -07002386 vcl_session_t *next_session;
Florin Corasab2f6db2018-08-31 14:31:41 -07002387 next_session = vcl_session_get_w_handle (wrk,
2388 vep_session->vep.next_sh);
Florin Coras070453d2018-08-24 17:04:27 -07002389 if (PREDICT_FALSE (!next_session))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002390 {
Florin Corasa7a1a222018-12-30 17:11:31 -08002391 VDBG (0, "EPOLL_CTL_ADD: Invalid vep.next_sid (%u) on "
2392 "vep_idx (%u)!", vep_session->vep.next_sh, vep_handle);
Florin Coras070453d2018-08-24 17:04:27 -07002393 return VPPCOM_EBADFD;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002394 }
Florin Coras134a9962018-08-28 11:32:04 -07002395 ASSERT (next_session->vep.prev_sh == vep_handle);
2396 next_session->vep.prev_sh = session_handle;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002397 }
Florin Coras134a9962018-08-28 11:32:04 -07002398 session->vep.next_sh = vep_session->vep.next_sh;
2399 session->vep.prev_sh = vep_handle;
2400 session->vep.vep_sh = vep_handle;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002401 session->vep.et_mask = VEP_DEFAULT_ET_MASK;
2402 session->vep.ev = *event;
Dave Wallace4878cbe2017-11-21 03:45:09 -05002403 session->is_vep = 0;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002404 session->is_vep_session = 1;
Florin Coras134a9962018-08-28 11:32:04 -07002405 vep_session->vep.next_sh = session_handle;
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002406
Florin Coras1bcad5c2019-01-09 20:04:38 -08002407 if (session->tx_fifo)
2408 svm_fifo_add_want_tx_ntf (session->tx_fifo,
2409 SVM_FIFO_WANT_TX_NOTIF_IF_FULL);
2410
Florin Corasa7a1a222018-12-30 17:11:31 -08002411 VDBG (1, "EPOLL_CTL_ADD: vep_sh %u, sh %u, events 0x%x, data 0x%llx!",
2412 vep_handle, session_handle, event->events, event->data.u64);
Florin Coras0d427d82018-06-27 03:24:07 -07002413 vcl_evt (VCL_EVT_EPOLL_CTLADD, session, event->events, event->data.u64);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002414 break;
2415
2416 case EPOLL_CTL_MOD:
2417 if (PREDICT_FALSE (!event))
2418 {
Florin Corasa7a1a222018-12-30 17:11:31 -08002419 VDBG (0, "EPOLL_CTL_MOD: NULL pointer to epoll_event structure!");
Dave Wallacef7f809c2017-10-03 01:48:42 -04002420 rv = VPPCOM_EINVAL;
2421 goto done;
2422 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05002423 else if (PREDICT_FALSE (!session->is_vep_session))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002424 {
Florin Corasa7a1a222018-12-30 17:11:31 -08002425 VDBG (0, "sid %u EPOLL_CTL_MOD: not a vep session!",
2426 session_handle);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002427 rv = VPPCOM_EINVAL;
2428 goto done;
2429 }
Florin Coras134a9962018-08-28 11:32:04 -07002430 else if (PREDICT_FALSE (session->vep.vep_sh != vep_handle))
Dave Wallace4878cbe2017-11-21 03:45:09 -05002431 {
Florin Corasa7a1a222018-12-30 17:11:31 -08002432 VDBG (0, "EPOLL_CTL_MOD: sh %u vep_sh (%u) != vep_sh (%u)!",
2433 session_handle, session->vep.vep_sh, vep_handle);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002434 rv = VPPCOM_EINVAL;
2435 goto done;
2436 }
2437 session->vep.et_mask = VEP_DEFAULT_ET_MASK;
2438 session->vep.ev = *event;
Florin Corasa7a1a222018-12-30 17:11:31 -08002439 VDBG (1, "EPOLL_CTL_MOD: vep_sh %u, sh %u, events 0x%x, data 0x%llx!",
2440 vep_handle, session_handle, event->events, event->data.u64);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002441 break;
2442
2443 case EPOLL_CTL_DEL:
Dave Wallace4878cbe2017-11-21 03:45:09 -05002444 if (PREDICT_FALSE (!session->is_vep_session))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002445 {
Florin Corasa7a1a222018-12-30 17:11:31 -08002446 VDBG (0, "EPOLL_CTL_DEL: %u not a vep session!", session_handle);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002447 rv = VPPCOM_EINVAL;
2448 goto done;
2449 }
Florin Coras134a9962018-08-28 11:32:04 -07002450 else if (PREDICT_FALSE (session->vep.vep_sh != vep_handle))
Dave Wallace4878cbe2017-11-21 03:45:09 -05002451 {
Florin Corasa7a1a222018-12-30 17:11:31 -08002452 VDBG (0, "EPOLL_CTL_DEL: sh %u vep_sh (%u) != vep_sh (%u)!",
2453 session_handle, session->vep.vep_sh, vep_handle);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002454 rv = VPPCOM_EINVAL;
2455 goto done;
2456 }
2457
2458 vep_session->wait_cont_idx =
Florin Coras134a9962018-08-28 11:32:04 -07002459 (vep_session->wait_cont_idx == session_handle) ?
2460 session->vep.next_sh : vep_session->wait_cont_idx;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002461
Florin Coras134a9962018-08-28 11:32:04 -07002462 if (session->vep.prev_sh == vep_handle)
2463 vep_session->vep.next_sh = session->vep.next_sh;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002464 else
2465 {
Florin Coras7e12d942018-06-27 14:32:43 -07002466 vcl_session_t *prev_session;
Florin Corasab2f6db2018-08-31 14:31:41 -07002467 prev_session = vcl_session_get_w_handle (wrk, session->vep.prev_sh);
Florin Coras070453d2018-08-24 17:04:27 -07002468 if (PREDICT_FALSE (!prev_session))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002469 {
Florin Corasa7a1a222018-12-30 17:11:31 -08002470 VDBG (0, "EPOLL_CTL_DEL: Invalid prev_sid (%u) on sid (%u)!",
2471 session->vep.prev_sh, session_handle);
Florin Coras070453d2018-08-24 17:04:27 -07002472 return VPPCOM_EBADFD;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002473 }
Florin Coras134a9962018-08-28 11:32:04 -07002474 ASSERT (prev_session->vep.next_sh == session_handle);
2475 prev_session->vep.next_sh = session->vep.next_sh;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002476 }
Florin Coras134a9962018-08-28 11:32:04 -07002477 if (session->vep.next_sh != ~0)
Dave Wallacef7f809c2017-10-03 01:48:42 -04002478 {
Florin Coras7e12d942018-06-27 14:32:43 -07002479 vcl_session_t *next_session;
Florin Corasab2f6db2018-08-31 14:31:41 -07002480 next_session = vcl_session_get_w_handle (wrk, session->vep.next_sh);
Florin Coras070453d2018-08-24 17:04:27 -07002481 if (PREDICT_FALSE (!next_session))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002482 {
Florin Corasa7a1a222018-12-30 17:11:31 -08002483 VDBG (0, "EPOLL_CTL_DEL: Invalid next_sid (%u) on sid (%u)!",
2484 session->vep.next_sh, session_handle);
Florin Coras070453d2018-08-24 17:04:27 -07002485 return VPPCOM_EBADFD;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002486 }
Florin Coras134a9962018-08-28 11:32:04 -07002487 ASSERT (next_session->vep.prev_sh == session_handle);
2488 next_session->vep.prev_sh = session->vep.prev_sh;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002489 }
2490
2491 memset (&session->vep, 0, sizeof (session->vep));
Florin Coras134a9962018-08-28 11:32:04 -07002492 session->vep.next_sh = ~0;
2493 session->vep.prev_sh = ~0;
2494 session->vep.vep_sh = ~0;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002495 session->is_vep_session = 0;
Florin Coras1bcad5c2019-01-09 20:04:38 -08002496
2497 if (session->tx_fifo)
2498 svm_fifo_del_want_tx_ntf (session->tx_fifo, SVM_FIFO_NO_TX_NOTIF);
2499
Florin Corasa7a1a222018-12-30 17:11:31 -08002500 VDBG (1, "EPOLL_CTL_DEL: vep_idx %u, sid %u!", vep_handle,
2501 session_handle);
Florin Coras134a9962018-08-28 11:32:04 -07002502 vcl_evt (VCL_EVT_EPOLL_CTLDEL, session, vep_sh);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002503 break;
2504
2505 default:
Florin Corasa7a1a222018-12-30 17:11:31 -08002506 VDBG (0, "Invalid operation (%d)!", op);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002507 rv = VPPCOM_EINVAL;
2508 }
2509
Florin Coras134a9962018-08-28 11:32:04 -07002510 vep_verify_epoll_chain (wrk, vep_handle);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002511
2512done:
Dave Wallacef7f809c2017-10-03 01:48:42 -04002513 return rv;
2514}
2515
Florin Coras86f04502018-09-12 16:08:01 -07002516static inline void
2517vcl_epoll_wait_handle_mq_event (vcl_worker_t * wrk, session_event_t * e,
2518 struct epoll_event *events, u32 * num_ev)
Florin Coras54693d22018-07-17 10:46:29 -07002519{
2520 session_disconnected_msg_t *disconnected_msg;
2521 session_connected_msg_t *connected_msg;
Florin Coras99368312018-08-02 10:45:44 -07002522 u32 sid = ~0, session_events;
Florin Coras3c7d4f92018-12-14 11:28:43 -08002523 u64 session_evt_data = ~0;
Florin Coras54693d22018-07-17 10:46:29 -07002524 vcl_session_t *session;
Florin Coras86f04502018-09-12 16:08:01 -07002525 u8 add_event = 0;
2526
2527 switch (e->event_type)
2528 {
2529 case FIFO_EVENT_APP_RX:
2530 ASSERT (e->fifo->client_thread_index == vcl_get_worker_index ());
2531 vcl_fifo_rx_evt_valid_or_break (e->fifo);
2532 sid = e->fifo->client_session_index;
Florin Corasfa915f82018-12-26 16:29:06 -08002533 if (!(session = vcl_session_get (wrk, sid)))
2534 break;
Florin Coras86f04502018-09-12 16:08:01 -07002535 session_events = session->vep.ev.events;
Florin Corasaa27eb92018-10-13 12:20:01 -07002536 if (!(EPOLLIN & session->vep.ev.events) || session->has_rx_evt)
Florin Coras86f04502018-09-12 16:08:01 -07002537 break;
2538 add_event = 1;
2539 events[*num_ev].events |= EPOLLIN;
2540 session_evt_data = session->vep.ev.data.u64;
Florin Corasaa27eb92018-10-13 12:20:01 -07002541 session->has_rx_evt = 1;
Florin Coras86f04502018-09-12 16:08:01 -07002542 break;
2543 case FIFO_EVENT_APP_TX:
2544 sid = e->fifo->client_session_index;
Florin Corasfa915f82018-12-26 16:29:06 -08002545 if (!(session = vcl_session_get (wrk, sid)))
2546 break;
Florin Coras86f04502018-09-12 16:08:01 -07002547 session_events = session->vep.ev.events;
2548 if (!(EPOLLOUT & session_events))
2549 break;
2550 add_event = 1;
2551 events[*num_ev].events |= EPOLLOUT;
2552 session_evt_data = session->vep.ev.data.u64;
Florin Coras1bcad5c2019-01-09 20:04:38 -08002553 svm_fifo_reset_tx_ntf (session->tx_fifo);
Florin Coras86f04502018-09-12 16:08:01 -07002554 break;
2555 case SESSION_IO_EVT_CT_TX:
2556 vcl_fifo_rx_evt_valid_or_break (e->fifo);
2557 session = vcl_ct_session_get_from_fifo (wrk, e->fifo, 0);
Florin Corasfa915f82018-12-26 16:29:06 -08002558 if (PREDICT_FALSE (!session))
2559 break;
Florin Coras86f04502018-09-12 16:08:01 -07002560 sid = session->session_index;
2561 session_events = session->vep.ev.events;
Florin Corasaa27eb92018-10-13 12:20:01 -07002562 if (!(EPOLLIN & session->vep.ev.events) || session->has_rx_evt)
Florin Coras86f04502018-09-12 16:08:01 -07002563 break;
2564 add_event = 1;
2565 events[*num_ev].events |= EPOLLIN;
2566 session_evt_data = session->vep.ev.data.u64;
Florin Corasaa27eb92018-10-13 12:20:01 -07002567 session->has_rx_evt = 1;
Florin Coras86f04502018-09-12 16:08:01 -07002568 break;
2569 case SESSION_IO_EVT_CT_RX:
2570 session = vcl_ct_session_get_from_fifo (wrk, e->fifo, 1);
Florin Corasfa915f82018-12-26 16:29:06 -08002571 if (PREDICT_FALSE (!session))
2572 break;
Florin Coras86f04502018-09-12 16:08:01 -07002573 sid = session->session_index;
2574 session_events = session->vep.ev.events;
2575 if (!(EPOLLOUT & session_events))
2576 break;
2577 add_event = 1;
2578 events[*num_ev].events |= EPOLLOUT;
2579 session_evt_data = session->vep.ev.data.u64;
Florin Coras1bcad5c2019-01-09 20:04:38 -08002580 svm_fifo_reset_tx_ntf (session->tx_fifo);
Florin Coras86f04502018-09-12 16:08:01 -07002581 break;
2582 case SESSION_CTRL_EVT_ACCEPTED:
Florin Coras3c7d4f92018-12-14 11:28:43 -08002583 session = vcl_session_accepted (wrk,
2584 (session_accepted_msg_t *) e->data);
Florin Coras86f04502018-09-12 16:08:01 -07002585 if (!session)
Florin Coras3c7d4f92018-12-14 11:28:43 -08002586 break;
Florin Coras86f04502018-09-12 16:08:01 -07002587
Florin Coras86f04502018-09-12 16:08:01 -07002588 session_events = session->vep.ev.events;
2589 if (!(EPOLLIN & session_events))
2590 break;
2591
2592 add_event = 1;
2593 events[*num_ev].events |= EPOLLIN;
2594 session_evt_data = session->vep.ev.data.u64;
2595 break;
2596 case SESSION_CTRL_EVT_CONNECTED:
2597 connected_msg = (session_connected_msg_t *) e->data;
2598 vcl_session_connected_handler (wrk, connected_msg);
2599 /* Generate EPOLLOUT because there's no connected event */
2600 sid = vcl_session_index_from_vpp_handle (wrk, connected_msg->handle);
Florin Corasfa915f82018-12-26 16:29:06 -08002601 if (!(session = vcl_session_get (wrk, sid)))
2602 break;
Florin Coras86f04502018-09-12 16:08:01 -07002603 session_events = session->vep.ev.events;
Florin Coras72f77822019-01-22 19:05:52 -08002604 if (!(EPOLLOUT & session_events))
2605 break;
2606 add_event = 1;
2607 events[*num_ev].events |= EPOLLOUT;
2608 session_evt_data = session->vep.ev.data.u64;
Florin Coras86f04502018-09-12 16:08:01 -07002609 break;
2610 case SESSION_CTRL_EVT_DISCONNECTED:
2611 disconnected_msg = (session_disconnected_msg_t *) e->data;
Florin Coras3c7d4f92018-12-14 11:28:43 -08002612 session = vcl_session_disconnected_handler (wrk, disconnected_msg);
2613 if (!session)
Florin Coras86f04502018-09-12 16:08:01 -07002614 break;
Florin Coras72f77822019-01-22 19:05:52 -08002615 session_events = session->vep.ev.events;
2616 if (!((EPOLLHUP | EPOLLRDHUP) & session_events))
2617 break;
Florin Coras86f04502018-09-12 16:08:01 -07002618 add_event = 1;
2619 events[*num_ev].events |= EPOLLHUP | EPOLLRDHUP;
2620 session_evt_data = session->vep.ev.data.u64;
Florin Coras86f04502018-09-12 16:08:01 -07002621 break;
2622 case SESSION_CTRL_EVT_RESET:
2623 sid = vcl_session_reset_handler (wrk, (session_reset_msg_t *) e->data);
2624 if (!(session = vcl_session_get (wrk, sid)))
2625 break;
Florin Coras72f77822019-01-22 19:05:52 -08002626 session_events = session->vep.ev.events;
2627 if (!((EPOLLHUP | EPOLLRDHUP) & session_events))
2628 break;
Florin Coras86f04502018-09-12 16:08:01 -07002629 add_event = 1;
2630 events[*num_ev].events |= EPOLLHUP | EPOLLRDHUP;
2631 session_evt_data = session->vep.ev.data.u64;
Florin Coras86f04502018-09-12 16:08:01 -07002632 break;
Florin Coras30e79c22019-01-02 19:31:22 -08002633 case SESSION_CTRL_EVT_REQ_WORKER_UPDATE:
2634 vcl_session_req_worker_update_handler (wrk, e->data);
2635 break;
2636 case SESSION_CTRL_EVT_WORKER_UPDATE_REPLY:
2637 vcl_session_worker_update_reply_handler (wrk, e->data);
2638 break;
Florin Coras86f04502018-09-12 16:08:01 -07002639 default:
2640 VDBG (0, "unhandled: %u", e->event_type);
2641 break;
2642 }
2643
2644 if (add_event)
2645 {
2646 events[*num_ev].data.u64 = session_evt_data;
2647 if (EPOLLONESHOT & session_events)
2648 {
2649 session = vcl_session_get (wrk, sid);
2650 session->vep.ev.events = 0;
2651 }
2652 *num_ev += 1;
2653 }
2654}
2655
2656static int
2657vcl_epoll_wait_handle_mq (vcl_worker_t * wrk, svm_msg_q_t * mq,
2658 struct epoll_event *events, u32 maxevents,
2659 double wait_for_time, u32 * num_ev)
2660{
Florin Coras99368312018-08-02 10:45:44 -07002661 svm_msg_q_msg_t *msg;
Florin Coras54693d22018-07-17 10:46:29 -07002662 session_event_t *e;
Florin Coras54693d22018-07-17 10:46:29 -07002663 int i;
2664
Florin Coras539663c2018-09-28 14:59:37 -07002665 if (vec_len (wrk->mq_msg_vector) && svm_msg_q_is_empty (mq))
2666 goto handle_dequeued;
2667
Florin Coras54693d22018-07-17 10:46:29 -07002668 svm_msg_q_lock (mq);
2669 if (svm_msg_q_is_empty (mq))
2670 {
2671 if (!wait_for_time)
2672 {
2673 svm_msg_q_unlock (mq);
2674 return 0;
2675 }
2676 else if (wait_for_time < 0)
2677 {
2678 svm_msg_q_wait (mq);
2679 }
2680 else
2681 {
Florin Coras60f1fc12018-08-16 14:57:31 -07002682 if (svm_msg_q_timedwait (mq, wait_for_time / 1e3))
Florin Coras54693d22018-07-17 10:46:29 -07002683 {
2684 svm_msg_q_unlock (mq);
2685 return 0;
2686 }
2687 }
2688 }
Florin Coras134a9962018-08-28 11:32:04 -07002689 vcl_mq_dequeue_batch (wrk, mq);
Florin Coras54693d22018-07-17 10:46:29 -07002690 svm_msg_q_unlock (mq);
2691
Florin Coras539663c2018-09-28 14:59:37 -07002692handle_dequeued:
Florin Coras134a9962018-08-28 11:32:04 -07002693 for (i = 0; i < vec_len (wrk->mq_msg_vector); i++)
Florin Coras54693d22018-07-17 10:46:29 -07002694 {
Florin Coras134a9962018-08-28 11:32:04 -07002695 msg = vec_elt_at_index (wrk->mq_msg_vector, i);
Florin Coras99368312018-08-02 10:45:44 -07002696 e = svm_msg_q_msg_data (mq, msg);
Florin Corasaa27eb92018-10-13 12:20:01 -07002697 if (*num_ev < maxevents)
2698 vcl_epoll_wait_handle_mq_event (wrk, e, events, num_ev);
2699 else
2700 vec_add1 (wrk->unhandled_evts_vector, *e);
Florin Coras99368312018-08-02 10:45:44 -07002701 svm_msg_q_free_msg (mq, msg);
Florin Coras54693d22018-07-17 10:46:29 -07002702 }
Florin Corasaa27eb92018-10-13 12:20:01 -07002703 vec_reset_length (wrk->mq_msg_vector);
Florin Coras30e79c22019-01-02 19:31:22 -08002704 vcl_handle_pending_wrk_updates (wrk);
Florin Coras54693d22018-07-17 10:46:29 -07002705 return *num_ev;
2706}
2707
Florin Coras99368312018-08-02 10:45:44 -07002708static int
Florin Coras134a9962018-08-28 11:32:04 -07002709vppcom_epoll_wait_condvar (vcl_worker_t * wrk, struct epoll_event *events,
Florin Coras86f04502018-09-12 16:08:01 -07002710 int maxevents, u32 n_evts, double wait_for_time)
Florin Coras99368312018-08-02 10:45:44 -07002711{
2712 vcl_cut_through_registration_t *cr;
2713 double total_wait = 0, wait_slice;
Florin Coras99368312018-08-02 10:45:44 -07002714 int rv;
2715
Florin Coras72f77822019-01-22 19:05:52 -08002716 wait_for_time = (wait_for_time == -1) ? (double) 1e6 : wait_for_time;
Florin Coras134a9962018-08-28 11:32:04 -07002717 wait_slice = wrk->cut_through_registrations ? 10e-6 : wait_for_time;
Florin Coras99368312018-08-02 10:45:44 -07002718
2719 do
2720 {
Florin Coras134a9962018-08-28 11:32:04 -07002721 vcl_ct_registration_lock (wrk);
Florin Coras99368312018-08-02 10:45:44 -07002722 /* *INDENT-OFF* */
Florin Coras134a9962018-08-28 11:32:04 -07002723 pool_foreach (cr, wrk->cut_through_registrations, ({
Florin Coras86f04502018-09-12 16:08:01 -07002724 vcl_epoll_wait_handle_mq (wrk, cr->mq, events, maxevents, 0, &n_evts);
Florin Coras99368312018-08-02 10:45:44 -07002725 }));
2726 /* *INDENT-ON* */
Florin Coras134a9962018-08-28 11:32:04 -07002727 vcl_ct_registration_unlock (wrk);
Florin Coras99368312018-08-02 10:45:44 -07002728
Florin Coras134a9962018-08-28 11:32:04 -07002729 rv = vcl_epoll_wait_handle_mq (wrk, wrk->app_event_queue, events,
Florin Coras86f04502018-09-12 16:08:01 -07002730 maxevents, n_evts ? 0 : wait_slice,
2731 &n_evts);
Florin Coras99368312018-08-02 10:45:44 -07002732 if (rv)
2733 total_wait += wait_slice;
Florin Coras86f04502018-09-12 16:08:01 -07002734 if (n_evts)
2735 return n_evts;
Florin Coras99368312018-08-02 10:45:44 -07002736 }
2737 while (total_wait < wait_for_time);
Florin Coras86f04502018-09-12 16:08:01 -07002738 return n_evts;
Florin Coras99368312018-08-02 10:45:44 -07002739}
2740
2741static int
Florin Coras134a9962018-08-28 11:32:04 -07002742vppcom_epoll_wait_eventfd (vcl_worker_t * wrk, struct epoll_event *events,
Florin Coras86f04502018-09-12 16:08:01 -07002743 int maxevents, u32 n_evts, double wait_for_time)
Florin Coras99368312018-08-02 10:45:44 -07002744{
2745 vcl_mq_evt_conn_t *mqc;
2746 int __clib_unused n_read;
2747 int n_mq_evts, i;
Florin Coras99368312018-08-02 10:45:44 -07002748 u64 buf;
2749
Florin Coras134a9962018-08-28 11:32:04 -07002750 vec_validate (wrk->mq_events, pool_elts (wrk->mq_evt_conns));
Florin Corasa4878ed2018-10-12 13:09:36 -07002751again:
Florin Coras134a9962018-08-28 11:32:04 -07002752 n_mq_evts = epoll_wait (wrk->mqs_epfd, wrk->mq_events,
2753 vec_len (wrk->mq_events), wait_for_time);
Florin Coras99368312018-08-02 10:45:44 -07002754 for (i = 0; i < n_mq_evts; i++)
2755 {
Florin Coras134a9962018-08-28 11:32:04 -07002756 mqc = vcl_mq_evt_conn_get (wrk, wrk->mq_events[i].data.u32);
Florin Coras99368312018-08-02 10:45:44 -07002757 n_read = read (mqc->mq_fd, &buf, sizeof (buf));
Florin Coras134a9962018-08-28 11:32:04 -07002758 vcl_epoll_wait_handle_mq (wrk, mqc->mq, events, maxevents, 0, &n_evts);
Florin Coras99368312018-08-02 10:45:44 -07002759 }
Florin Corasa4878ed2018-10-12 13:09:36 -07002760 if (!n_evts && n_mq_evts > 0)
2761 goto again;
Florin Coras99368312018-08-02 10:45:44 -07002762
2763 return (int) n_evts;
2764}
2765
Dave Wallacef7f809c2017-10-03 01:48:42 -04002766int
Florin Coras134a9962018-08-28 11:32:04 -07002767vppcom_epoll_wait (uint32_t vep_handle, struct epoll_event *events,
Dave Wallacef7f809c2017-10-03 01:48:42 -04002768 int maxevents, double wait_for_time)
2769{
Florin Coras134a9962018-08-28 11:32:04 -07002770 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras7e12d942018-06-27 14:32:43 -07002771 vcl_session_t *vep_session;
Florin Coras86f04502018-09-12 16:08:01 -07002772 u32 n_evts = 0;
2773 int i;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002774
2775 if (PREDICT_FALSE (maxevents <= 0))
2776 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002777 clib_warning ("VCL<%d>: ERROR: Invalid maxevents (%d)!",
Dave Wallace4878cbe2017-11-21 03:45:09 -05002778 getpid (), maxevents);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002779 return VPPCOM_EINVAL;
2780 }
Dave Wallacef7f809c2017-10-03 01:48:42 -04002781
Florin Coras134a9962018-08-28 11:32:04 -07002782 vep_session = vcl_session_get_w_handle (wrk, vep_handle);
Florin Coras14598772018-09-04 19:47:52 -07002783 if (!vep_session)
2784 return VPPCOM_EBADFD;
2785
Florin Coras54693d22018-07-17 10:46:29 -07002786 if (PREDICT_FALSE (!vep_session->is_vep))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002787 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002788 clib_warning ("VCL<%d>: ERROR: vep_idx (%u) is not a vep!",
Florin Coras134a9962018-08-28 11:32:04 -07002789 getpid (), vep_handle);
Florin Coras54693d22018-07-17 10:46:29 -07002790 return VPPCOM_EINVAL;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002791 }
Florin Coras54693d22018-07-17 10:46:29 -07002792
2793 memset (events, 0, sizeof (*events) * maxevents);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002794
Florin Coras86f04502018-09-12 16:08:01 -07002795 if (vec_len (wrk->unhandled_evts_vector))
2796 {
2797 for (i = 0; i < vec_len (wrk->unhandled_evts_vector); i++)
2798 {
2799 vcl_epoll_wait_handle_mq_event (wrk, &wrk->unhandled_evts_vector[i],
2800 events, &n_evts);
2801 if (n_evts == maxevents)
2802 {
2803 i += 1;
2804 break;
2805 }
2806 }
Dave Wallacef7f809c2017-10-03 01:48:42 -04002807
Florin Coras86f04502018-09-12 16:08:01 -07002808 vec_delete (wrk->unhandled_evts_vector, i, 0);
2809 }
2810
2811 if (vcm->cfg.use_mq_eventfd)
2812 return vppcom_epoll_wait_eventfd (wrk, events, maxevents, n_evts,
2813 wait_for_time);
2814
2815 return vppcom_epoll_wait_condvar (wrk, events, maxevents, n_evts,
2816 wait_for_time);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002817}
2818
Dave Wallace35830af2017-10-09 01:43:42 -04002819int
Florin Coras134a9962018-08-28 11:32:04 -07002820vppcom_session_attr (uint32_t session_handle, uint32_t op,
Dave Wallace35830af2017-10-09 01:43:42 -04002821 void *buffer, uint32_t * buflen)
2822{
Florin Coras134a9962018-08-28 11:32:04 -07002823 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras7e12d942018-06-27 14:32:43 -07002824 vcl_session_t *session;
Dave Wallace35830af2017-10-09 01:43:42 -04002825 int rv = VPPCOM_OK;
Florin Coras7baeb712019-01-04 17:05:43 -08002826 u32 *flags = buffer, tmp_flags = 0;
Steven2199aab2017-10-15 20:18:47 -07002827 vppcom_endpt_t *ep = buffer;
Dave Wallace35830af2017-10-09 01:43:42 -04002828
Florin Coras134a9962018-08-28 11:32:04 -07002829 session = vcl_session_get_w_handle (wrk, session_handle);
Florin Coras070453d2018-08-24 17:04:27 -07002830 if (!session)
2831 return VPPCOM_EBADFD;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002832
Dave Wallace35830af2017-10-09 01:43:42 -04002833 switch (op)
2834 {
2835 case VPPCOM_ATTR_GET_NREAD:
Florin Coras54693d22018-07-17 10:46:29 -07002836 rv = vppcom_session_read_ready (session);
Florin Coras7baeb712019-01-04 17:05:43 -08002837 VDBG (2, "VPPCOM_ATTR_GET_NREAD: sid %u, nread = %d", rv);
Dave Wallace35830af2017-10-09 01:43:42 -04002838 break;
2839
Dave Wallace227867f2017-11-13 21:21:53 -05002840 case VPPCOM_ATTR_GET_NWRITE:
Florin Coras134a9962018-08-28 11:32:04 -07002841 rv = vppcom_session_write_ready (session);
Florin Coras0d427d82018-06-27 03:24:07 -07002842 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_NWRITE: sid %u, nwrite = %d",
Florin Coras134a9962018-08-28 11:32:04 -07002843 getpid (), session_handle, rv);
Dave Wallace35830af2017-10-09 01:43:42 -04002844 break;
2845
2846 case VPPCOM_ATTR_GET_FLAGS:
Dave Wallace048b1d62018-01-03 22:24:41 -05002847 if (PREDICT_TRUE (buffer && buflen && (*buflen >= sizeof (*flags))))
Dave Wallace35830af2017-10-09 01:43:42 -04002848 {
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002849 *flags = O_RDWR | (VCL_SESS_ATTR_TEST (session->attr,
2850 VCL_SESS_ATTR_NONBLOCK));
Dave Wallace35830af2017-10-09 01:43:42 -04002851 *buflen = sizeof (*flags);
Florin Coras0d427d82018-06-27 03:24:07 -07002852 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_FLAGS: sid %u, flags = 0x%08x, "
2853 "is_nonblocking = %u", getpid (),
Florin Coras134a9962018-08-28 11:32:04 -07002854 session_handle, *flags,
Florin Coras0d427d82018-06-27 03:24:07 -07002855 VCL_SESS_ATTR_TEST (session->attr, VCL_SESS_ATTR_NONBLOCK));
Dave Wallace35830af2017-10-09 01:43:42 -04002856 }
2857 else
2858 rv = VPPCOM_EINVAL;
2859 break;
2860
2861 case VPPCOM_ATTR_SET_FLAGS:
Dave Wallace048b1d62018-01-03 22:24:41 -05002862 if (PREDICT_TRUE (buffer && buflen && (*buflen == sizeof (*flags))))
Dave Wallace35830af2017-10-09 01:43:42 -04002863 {
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002864 if (*flags & O_NONBLOCK)
2865 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_NONBLOCK);
2866 else
2867 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_NONBLOCK);
2868
Florin Coras0d427d82018-06-27 03:24:07 -07002869 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_FLAGS: sid %u, flags = 0x%08x,"
2870 " is_nonblocking = %u",
Florin Coras134a9962018-08-28 11:32:04 -07002871 getpid (), session_handle, *flags,
Florin Coras0d427d82018-06-27 03:24:07 -07002872 VCL_SESS_ATTR_TEST (session->attr, VCL_SESS_ATTR_NONBLOCK));
Dave Wallace35830af2017-10-09 01:43:42 -04002873 }
2874 else
2875 rv = VPPCOM_EINVAL;
2876 break;
2877
2878 case VPPCOM_ATTR_GET_PEER_ADDR:
Dave Wallace048b1d62018-01-03 22:24:41 -05002879 if (PREDICT_TRUE (buffer && buflen &&
2880 (*buflen >= sizeof (*ep)) && ep->ip))
Dave Wallace35830af2017-10-09 01:43:42 -04002881 {
Florin Coras7e12d942018-06-27 14:32:43 -07002882 ep->is_ip4 = session->transport.is_ip4;
2883 ep->port = session->transport.rmt_port;
2884 if (session->transport.is_ip4)
Dave Barach178cf492018-11-13 16:34:13 -05002885 clib_memcpy_fast (ep->ip, &session->transport.rmt_ip.ip4,
2886 sizeof (ip4_address_t));
Steven2199aab2017-10-15 20:18:47 -07002887 else
Dave Barach178cf492018-11-13 16:34:13 -05002888 clib_memcpy_fast (ep->ip, &session->transport.rmt_ip.ip6,
2889 sizeof (ip6_address_t));
Steven2199aab2017-10-15 20:18:47 -07002890 *buflen = sizeof (*ep);
Florin Coras0d427d82018-06-27 03:24:07 -07002891 VDBG (1, "VCL<%d>: VPPCOM_ATTR_GET_PEER_ADDR: sid %u, is_ip4 = %u, "
2892 "addr = %U, port %u", getpid (),
Florin Coras134a9962018-08-28 11:32:04 -07002893 session_handle, ep->is_ip4, format_ip46_address,
Florin Coras7e12d942018-06-27 14:32:43 -07002894 &session->transport.rmt_ip,
Florin Coras0d427d82018-06-27 03:24:07 -07002895 ep->is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6,
2896 clib_net_to_host_u16 (ep->port));
Dave Wallace35830af2017-10-09 01:43:42 -04002897 }
2898 else
2899 rv = VPPCOM_EINVAL;
2900 break;
2901
2902 case VPPCOM_ATTR_GET_LCL_ADDR:
Dave Wallace048b1d62018-01-03 22:24:41 -05002903 if (PREDICT_TRUE (buffer && buflen &&
2904 (*buflen >= sizeof (*ep)) && ep->ip))
Dave Wallace35830af2017-10-09 01:43:42 -04002905 {
Florin Coras7e12d942018-06-27 14:32:43 -07002906 ep->is_ip4 = session->transport.is_ip4;
2907 ep->port = session->transport.lcl_port;
2908 if (session->transport.is_ip4)
Dave Barach178cf492018-11-13 16:34:13 -05002909 clib_memcpy_fast (ep->ip, &session->transport.lcl_ip.ip4,
2910 sizeof (ip4_address_t));
Steven2199aab2017-10-15 20:18:47 -07002911 else
Dave Barach178cf492018-11-13 16:34:13 -05002912 clib_memcpy_fast (ep->ip, &session->transport.lcl_ip.ip6,
2913 sizeof (ip6_address_t));
Steven2199aab2017-10-15 20:18:47 -07002914 *buflen = sizeof (*ep);
Florin Coras0d427d82018-06-27 03:24:07 -07002915 VDBG (1, "VCL<%d>: VPPCOM_ATTR_GET_LCL_ADDR: sid %u, is_ip4 = %u,"
2916 " addr = %U port %d", getpid (),
Florin Coras134a9962018-08-28 11:32:04 -07002917 session_handle, ep->is_ip4, format_ip46_address,
Florin Coras7e12d942018-06-27 14:32:43 -07002918 &session->transport.lcl_ip,
Florin Coras0d427d82018-06-27 03:24:07 -07002919 ep->is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6,
2920 clib_net_to_host_u16 (ep->port));
Dave Wallace35830af2017-10-09 01:43:42 -04002921 }
2922 else
2923 rv = VPPCOM_EINVAL;
2924 break;
Stevenb5a11602017-10-11 09:59:30 -07002925
Dave Wallace048b1d62018-01-03 22:24:41 -05002926 case VPPCOM_ATTR_GET_LIBC_EPFD:
2927 rv = session->libc_epfd;
Florin Coras0d427d82018-06-27 03:24:07 -07002928 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_LIBC_EPFD: libc_epfd %d",
2929 getpid (), rv);
Dave Wallace048b1d62018-01-03 22:24:41 -05002930 break;
2931
2932 case VPPCOM_ATTR_SET_LIBC_EPFD:
2933 if (PREDICT_TRUE (buffer && buflen &&
2934 (*buflen == sizeof (session->libc_epfd))))
2935 {
2936 session->libc_epfd = *(int *) buffer;
2937 *buflen = sizeof (session->libc_epfd);
2938
Florin Coras0d427d82018-06-27 03:24:07 -07002939 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_LIBC_EPFD: libc_epfd %d, "
2940 "buflen %d", getpid (), session->libc_epfd, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002941 }
2942 else
2943 rv = VPPCOM_EINVAL;
2944 break;
2945
2946 case VPPCOM_ATTR_GET_PROTOCOL:
2947 if (buffer && buflen && (*buflen >= sizeof (int)))
2948 {
Florin Coras7e12d942018-06-27 14:32:43 -07002949 *(int *) buffer = session->session_type;
Dave Wallace048b1d62018-01-03 22:24:41 -05002950 *buflen = sizeof (int);
2951
Florin Coras0d427d82018-06-27 03:24:07 -07002952 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_PROTOCOL: %d (%s), buflen %d",
2953 getpid (), *(int *) buffer, *(int *) buffer ? "UDP" : "TCP",
2954 *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002955 }
2956 else
2957 rv = VPPCOM_EINVAL;
2958 break;
2959
2960 case VPPCOM_ATTR_GET_LISTEN:
2961 if (buffer && buflen && (*buflen >= sizeof (int)))
2962 {
2963 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
2964 VCL_SESS_ATTR_LISTEN);
2965 *buflen = sizeof (int);
2966
Florin Coras0d427d82018-06-27 03:24:07 -07002967 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_LISTEN: %d, buflen %d",
2968 getpid (), *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002969 }
2970 else
2971 rv = VPPCOM_EINVAL;
2972 break;
2973
2974 case VPPCOM_ATTR_GET_ERROR:
2975 if (buffer && buflen && (*buflen >= sizeof (int)))
2976 {
2977 *(int *) buffer = 0;
2978 *buflen = sizeof (int);
2979
Florin Coras0d427d82018-06-27 03:24:07 -07002980 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_ERROR: %d, buflen %d, #VPP-TBD#",
2981 getpid (), *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002982 }
2983 else
2984 rv = VPPCOM_EINVAL;
2985 break;
2986
2987 case VPPCOM_ATTR_GET_TX_FIFO_LEN:
2988 if (buffer && buflen && (*buflen >= sizeof (u32)))
2989 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002990
2991 /* VPP-TBD */
2992 *(size_t *) buffer = (session->sndbuf_size ? session->sndbuf_size :
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002993 session->tx_fifo ? session->tx_fifo->nitems :
Dave Wallace048b1d62018-01-03 22:24:41 -05002994 vcm->cfg.tx_fifo_size);
2995 *buflen = sizeof (u32);
2996
Florin Coras0d427d82018-06-27 03:24:07 -07002997 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_TX_FIFO_LEN: %u (0x%x), "
2998 "buflen %d, #VPP-TBD#", getpid (),
2999 *(size_t *) buffer, *(size_t *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003000 }
3001 else
3002 rv = VPPCOM_EINVAL;
3003 break;
3004
3005 case VPPCOM_ATTR_SET_TX_FIFO_LEN:
3006 if (buffer && buflen && (*buflen == sizeof (u32)))
3007 {
3008 /* VPP-TBD */
3009 session->sndbuf_size = *(u32 *) buffer;
Florin Coras0d427d82018-06-27 03:24:07 -07003010 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_TX_FIFO_LEN: %u (0x%x), "
3011 "buflen %d, #VPP-TBD#", getpid (),
3012 session->sndbuf_size, session->sndbuf_size, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003013 }
3014 else
3015 rv = VPPCOM_EINVAL;
3016 break;
3017
3018 case VPPCOM_ATTR_GET_RX_FIFO_LEN:
3019 if (buffer && buflen && (*buflen >= sizeof (u32)))
3020 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003021
3022 /* VPP-TBD */
3023 *(size_t *) buffer = (session->rcvbuf_size ? session->rcvbuf_size :
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003024 session->rx_fifo ? session->rx_fifo->nitems :
Dave Wallace048b1d62018-01-03 22:24:41 -05003025 vcm->cfg.rx_fifo_size);
3026 *buflen = sizeof (u32);
3027
Florin Coras0d427d82018-06-27 03:24:07 -07003028 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_RX_FIFO_LEN: %u (0x%x), "
3029 "buflen %d, #VPP-TBD#", getpid (),
3030 *(size_t *) buffer, *(size_t *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003031 }
3032 else
3033 rv = VPPCOM_EINVAL;
3034 break;
3035
3036 case VPPCOM_ATTR_SET_RX_FIFO_LEN:
3037 if (buffer && buflen && (*buflen == sizeof (u32)))
3038 {
3039 /* VPP-TBD */
3040 session->rcvbuf_size = *(u32 *) buffer;
Florin Coras0d427d82018-06-27 03:24:07 -07003041 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_RX_FIFO_LEN: %u (0x%x), "
3042 "buflen %d, #VPP-TBD#", getpid (),
3043 session->sndbuf_size, session->sndbuf_size, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003044 }
3045 else
3046 rv = VPPCOM_EINVAL;
3047 break;
3048
3049 case VPPCOM_ATTR_GET_REUSEADDR:
3050 if (buffer && buflen && (*buflen >= sizeof (int)))
3051 {
3052 /* VPP-TBD */
3053 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
3054 VCL_SESS_ATTR_REUSEADDR);
3055 *buflen = sizeof (int);
3056
Florin Coras0d427d82018-06-27 03:24:07 -07003057 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_REUSEADDR: %d, "
3058 "buflen %d, #VPP-TBD#", getpid (), *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003059 }
3060 else
3061 rv = VPPCOM_EINVAL;
3062 break;
3063
Stevenb5a11602017-10-11 09:59:30 -07003064 case VPPCOM_ATTR_SET_REUSEADDR:
Dave Wallace048b1d62018-01-03 22:24:41 -05003065 if (buffer && buflen && (*buflen == sizeof (int)) &&
3066 !VCL_SESS_ATTR_TEST (session->attr, VCL_SESS_ATTR_LISTEN))
3067 {
3068 /* VPP-TBD */
3069 if (*(int *) buffer)
3070 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_REUSEADDR);
3071 else
3072 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_REUSEADDR);
3073
Florin Coras0d427d82018-06-27 03:24:07 -07003074 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_REUSEADDR: %d, buflen %d,"
3075 " #VPP-TBD#", getpid (),
3076 VCL_SESS_ATTR_TEST (session->attr,
3077 VCL_SESS_ATTR_REUSEADDR), *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003078 }
3079 else
3080 rv = VPPCOM_EINVAL;
3081 break;
3082
3083 case VPPCOM_ATTR_GET_REUSEPORT:
3084 if (buffer && buflen && (*buflen >= sizeof (int)))
3085 {
3086 /* VPP-TBD */
3087 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
3088 VCL_SESS_ATTR_REUSEPORT);
3089 *buflen = sizeof (int);
3090
Florin Coras0d427d82018-06-27 03:24:07 -07003091 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_REUSEPORT: %d, buflen %d,"
3092 " #VPP-TBD#", getpid (), *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003093 }
3094 else
3095 rv = VPPCOM_EINVAL;
3096 break;
3097
3098 case VPPCOM_ATTR_SET_REUSEPORT:
3099 if (buffer && buflen && (*buflen == sizeof (int)) &&
3100 !VCL_SESS_ATTR_TEST (session->attr, VCL_SESS_ATTR_LISTEN))
3101 {
3102 /* VPP-TBD */
3103 if (*(int *) buffer)
3104 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_REUSEPORT);
3105 else
3106 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_REUSEPORT);
3107
Florin Coras0d427d82018-06-27 03:24:07 -07003108 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_REUSEPORT: %d, buflen %d,"
3109 " #VPP-TBD#", getpid (),
3110 VCL_SESS_ATTR_TEST (session->attr,
3111 VCL_SESS_ATTR_REUSEPORT), *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003112 }
3113 else
3114 rv = VPPCOM_EINVAL;
3115 break;
3116
3117 case VPPCOM_ATTR_GET_BROADCAST:
3118 if (buffer && buflen && (*buflen >= sizeof (int)))
3119 {
3120 /* VPP-TBD */
3121 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
3122 VCL_SESS_ATTR_BROADCAST);
3123 *buflen = sizeof (int);
3124
Florin Coras0d427d82018-06-27 03:24:07 -07003125 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_BROADCAST: %d, buflen %d,"
3126 " #VPP-TBD#", getpid (), *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003127 }
3128 else
3129 rv = VPPCOM_EINVAL;
Stevenb5a11602017-10-11 09:59:30 -07003130 break;
3131
3132 case VPPCOM_ATTR_SET_BROADCAST:
Dave Wallace048b1d62018-01-03 22:24:41 -05003133 if (buffer && buflen && (*buflen == sizeof (int)))
3134 {
3135 /* VPP-TBD */
3136 if (*(int *) buffer)
3137 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_BROADCAST);
3138 else
3139 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_BROADCAST);
3140
Florin Coras0d427d82018-06-27 03:24:07 -07003141 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_BROADCAST: %d, buflen %d, "
3142 "#VPP-TBD#", getpid (),
3143 VCL_SESS_ATTR_TEST (session->attr,
3144 VCL_SESS_ATTR_BROADCAST), *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003145 }
3146 else
3147 rv = VPPCOM_EINVAL;
3148 break;
3149
3150 case VPPCOM_ATTR_GET_V6ONLY:
3151 if (buffer && buflen && (*buflen >= sizeof (int)))
3152 {
3153 /* VPP-TBD */
3154 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
3155 VCL_SESS_ATTR_V6ONLY);
3156 *buflen = sizeof (int);
3157
Florin Coras0d427d82018-06-27 03:24:07 -07003158 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_V6ONLY: %d, buflen %d, "
3159 "#VPP-TBD#", getpid (), *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003160 }
3161 else
3162 rv = VPPCOM_EINVAL;
Stevenb5a11602017-10-11 09:59:30 -07003163 break;
3164
3165 case VPPCOM_ATTR_SET_V6ONLY:
Dave Wallace048b1d62018-01-03 22:24:41 -05003166 if (buffer && buflen && (*buflen == sizeof (int)))
3167 {
3168 /* VPP-TBD */
3169 if (*(int *) buffer)
3170 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_V6ONLY);
3171 else
3172 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_V6ONLY);
3173
Florin Coras0d427d82018-06-27 03:24:07 -07003174 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_V6ONLY: %d, buflen %d, "
3175 "#VPP-TBD#", getpid (),
3176 VCL_SESS_ATTR_TEST (session->attr,
3177 VCL_SESS_ATTR_V6ONLY), *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003178 }
3179 else
3180 rv = VPPCOM_EINVAL;
3181 break;
3182
3183 case VPPCOM_ATTR_GET_KEEPALIVE:
3184 if (buffer && buflen && (*buflen >= sizeof (int)))
3185 {
3186 /* VPP-TBD */
3187 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
3188 VCL_SESS_ATTR_KEEPALIVE);
3189 *buflen = sizeof (int);
3190
Florin Coras0d427d82018-06-27 03:24:07 -07003191 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_KEEPALIVE: %d, buflen %d, "
3192 "#VPP-TBD#", getpid (), *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003193 }
3194 else
3195 rv = VPPCOM_EINVAL;
Stevenb5a11602017-10-11 09:59:30 -07003196 break;
Stevenbccd3392017-10-12 20:42:21 -07003197
3198 case VPPCOM_ATTR_SET_KEEPALIVE:
Dave Wallace048b1d62018-01-03 22:24:41 -05003199 if (buffer && buflen && (*buflen == sizeof (int)))
3200 {
3201 /* VPP-TBD */
3202 if (*(int *) buffer)
3203 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_KEEPALIVE);
3204 else
3205 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_KEEPALIVE);
3206
Florin Coras0d427d82018-06-27 03:24:07 -07003207 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_KEEPALIVE: %d, buflen %d, "
3208 "#VPP-TBD#", getpid (),
3209 VCL_SESS_ATTR_TEST (session->attr,
3210 VCL_SESS_ATTR_KEEPALIVE), *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003211 }
3212 else
3213 rv = VPPCOM_EINVAL;
3214 break;
3215
3216 case VPPCOM_ATTR_GET_TCP_NODELAY:
3217 if (buffer && buflen && (*buflen >= sizeof (int)))
3218 {
3219 /* VPP-TBD */
3220 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
3221 VCL_SESS_ATTR_TCP_NODELAY);
3222 *buflen = sizeof (int);
3223
Florin Coras0d427d82018-06-27 03:24:07 -07003224 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_TCP_NODELAY: %d, buflen %d, "
3225 "#VPP-TBD#", getpid (), *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003226 }
3227 else
3228 rv = VPPCOM_EINVAL;
3229 break;
3230
3231 case VPPCOM_ATTR_SET_TCP_NODELAY:
3232 if (buffer && buflen && (*buflen == sizeof (int)))
3233 {
3234 /* VPP-TBD */
3235 if (*(int *) buffer)
3236 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_TCP_NODELAY);
3237 else
3238 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_TCP_NODELAY);
3239
Florin Coras0d427d82018-06-27 03:24:07 -07003240 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_TCP_NODELAY: %d, buflen %d, "
3241 "#VPP-TBD#", getpid (),
3242 VCL_SESS_ATTR_TEST (session->attr,
3243 VCL_SESS_ATTR_TCP_NODELAY), *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003244 }
3245 else
3246 rv = VPPCOM_EINVAL;
3247 break;
3248
3249 case VPPCOM_ATTR_GET_TCP_KEEPIDLE:
3250 if (buffer && buflen && (*buflen >= sizeof (int)))
3251 {
3252 /* VPP-TBD */
3253 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
3254 VCL_SESS_ATTR_TCP_KEEPIDLE);
3255 *buflen = sizeof (int);
3256
Florin Coras0d427d82018-06-27 03:24:07 -07003257 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_TCP_KEEPIDLE: %d, buflen %d, "
3258 "#VPP-TBD#", getpid (), *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003259 }
3260 else
3261 rv = VPPCOM_EINVAL;
Stevenbccd3392017-10-12 20:42:21 -07003262 break;
3263
3264 case VPPCOM_ATTR_SET_TCP_KEEPIDLE:
Dave Wallace048b1d62018-01-03 22:24:41 -05003265 if (buffer && buflen && (*buflen == sizeof (int)))
3266 {
3267 /* VPP-TBD */
3268 if (*(int *) buffer)
3269 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_TCP_KEEPIDLE);
3270 else
3271 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_TCP_KEEPIDLE);
3272
Florin Coras0d427d82018-06-27 03:24:07 -07003273 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_TCP_KEEPIDLE: %d, buflen %d, "
3274 "#VPP-TBD#", getpid (),
3275 VCL_SESS_ATTR_TEST (session->attr,
3276 VCL_SESS_ATTR_TCP_KEEPIDLE), *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003277 }
3278 else
3279 rv = VPPCOM_EINVAL;
3280 break;
3281
3282 case VPPCOM_ATTR_GET_TCP_KEEPINTVL:
3283 if (buffer && buflen && (*buflen >= sizeof (int)))
3284 {
3285 /* VPP-TBD */
3286 *(int *) buffer = VCL_SESS_ATTR_TEST (session->attr,
3287 VCL_SESS_ATTR_TCP_KEEPINTVL);
3288 *buflen = sizeof (int);
3289
Florin Coras0d427d82018-06-27 03:24:07 -07003290 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_TCP_KEEPINTVL: %d, buflen %d, "
3291 "#VPP-TBD#", getpid (), *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003292 }
3293 else
3294 rv = VPPCOM_EINVAL;
Stevenbccd3392017-10-12 20:42:21 -07003295 break;
3296
3297 case VPPCOM_ATTR_SET_TCP_KEEPINTVL:
Dave Wallace048b1d62018-01-03 22:24:41 -05003298 if (buffer && buflen && (*buflen == sizeof (int)))
3299 {
3300 /* VPP-TBD */
3301 if (*(int *) buffer)
3302 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_TCP_KEEPINTVL);
3303 else
3304 VCL_SESS_ATTR_CLR (session->attr, VCL_SESS_ATTR_TCP_KEEPINTVL);
3305
Florin Coras0d427d82018-06-27 03:24:07 -07003306 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_TCP_KEEPINTVL: %d, buflen %d, "
3307 "#VPP-TBD#", getpid (),
3308 VCL_SESS_ATTR_TEST (session->attr,
3309 VCL_SESS_ATTR_TCP_KEEPINTVL), *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003310 }
3311 else
3312 rv = VPPCOM_EINVAL;
3313 break;
3314
3315 case VPPCOM_ATTR_GET_TCP_USER_MSS:
3316 if (buffer && buflen && (*buflen >= sizeof (u32)))
3317 {
3318 /* VPP-TBD */
3319 *(u32 *) buffer = session->user_mss;
3320 *buflen = sizeof (int);
3321
Florin Coras0d427d82018-06-27 03:24:07 -07003322 VDBG (2, "VCL<%d>: VPPCOM_ATTR_GET_TCP_USER_MSS: %d, buflen %d,"
3323 " #VPP-TBD#", getpid (), *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003324 }
3325 else
3326 rv = VPPCOM_EINVAL;
3327 break;
3328
3329 case VPPCOM_ATTR_SET_TCP_USER_MSS:
3330 if (buffer && buflen && (*buflen == sizeof (u32)))
3331 {
3332 /* VPP-TBD */
3333 session->user_mss = *(u32 *) buffer;
3334
Florin Coras0d427d82018-06-27 03:24:07 -07003335 VDBG (2, "VCL<%d>: VPPCOM_ATTR_SET_TCP_USER_MSS: %u, buflen %d, "
3336 "#VPP-TBD#", getpid (), session->user_mss, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003337 }
3338 else
3339 rv = VPPCOM_EINVAL;
Stevenbccd3392017-10-12 20:42:21 -07003340 break;
Dave Wallacee22aa742017-10-20 12:30:38 -04003341
Florin Coras7baeb712019-01-04 17:05:43 -08003342 case VPPCOM_ATTR_SET_SHUT:
3343 if (*flags == SHUT_RD || *flags == SHUT_RDWR)
3344 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_SHUT_RD);
3345 if (*flags == SHUT_WR || *flags == SHUT_RDWR)
3346 VCL_SESS_ATTR_SET (session->attr, VCL_SESS_ATTR_SHUT_WR);
3347 break;
3348
3349 case VPPCOM_ATTR_GET_SHUT:
3350 if (VCL_SESS_ATTR_TEST (session->attr, VCL_SESS_ATTR_SHUT_RD))
3351 tmp_flags = 1;
3352 if (VCL_SESS_ATTR_TEST (session->attr, VCL_SESS_ATTR_SHUT_WR))
3353 tmp_flags |= 2;
3354 if (tmp_flags == 1)
3355 *(int *) buffer = SHUT_RD;
3356 else if (tmp_flags == 2)
3357 *(int *) buffer = SHUT_WR;
3358 else if (tmp_flags == 3)
3359 *(int *) buffer = SHUT_RDWR;
3360 *buflen = sizeof (int);
3361 break;
Dave Wallacee22aa742017-10-20 12:30:38 -04003362 default:
3363 rv = VPPCOM_EINVAL;
3364 break;
Dave Wallace35830af2017-10-09 01:43:42 -04003365 }
3366
Dave Wallace35830af2017-10-09 01:43:42 -04003367 return rv;
3368}
3369
Stevenac1f96d2017-10-24 16:03:58 -07003370int
Florin Coras134a9962018-08-28 11:32:04 -07003371vppcom_session_recvfrom (uint32_t session_handle, void *buffer,
Stevenac1f96d2017-10-24 16:03:58 -07003372 uint32_t buflen, int flags, vppcom_endpt_t * ep)
3373{
Florin Coras134a9962018-08-28 11:32:04 -07003374 vcl_worker_t *wrk = vcl_worker_get_current ();
Stevenac1f96d2017-10-24 16:03:58 -07003375 int rv = VPPCOM_OK;
Florin Coras7e12d942018-06-27 14:32:43 -07003376 vcl_session_t *session = 0;
Stevenac1f96d2017-10-24 16:03:58 -07003377
3378 if (ep)
3379 {
Florin Coras134a9962018-08-28 11:32:04 -07003380 session = vcl_session_get_w_handle (wrk, session_handle);
Florin Coras070453d2018-08-24 17:04:27 -07003381 if (PREDICT_FALSE (!session))
Stevenac1f96d2017-10-24 16:03:58 -07003382 {
Florin Coras0d427d82018-06-27 03:24:07 -07003383 VDBG (0, "VCL<%d>: invalid session, sid (%u) has been closed!",
Florin Coras134a9962018-08-28 11:32:04 -07003384 getpid (), session_handle);
Florin Coras460dce62018-07-27 05:45:06 -07003385 return VPPCOM_EBADFD;
Stevenac1f96d2017-10-24 16:03:58 -07003386 }
Florin Coras7e12d942018-06-27 14:32:43 -07003387 ep->is_ip4 = session->transport.is_ip4;
3388 ep->port = session->transport.rmt_port;
Stevenac1f96d2017-10-24 16:03:58 -07003389 }
Steven58f464e2017-10-25 12:33:12 -07003390
3391 if (flags == 0)
Florin Coras134a9962018-08-28 11:32:04 -07003392 rv = vppcom_session_read (session_handle, buffer, buflen);
Stevenac1f96d2017-10-24 16:03:58 -07003393 else if (flags & MSG_PEEK)
Florin Coras134a9962018-08-28 11:32:04 -07003394 rv = vppcom_session_peek (session_handle, buffer, buflen);
Stevenac1f96d2017-10-24 16:03:58 -07003395 else
3396 {
Florin Corasa7a1a222018-12-30 17:11:31 -08003397 VDBG (0, "Unsupport flags for recvfrom %d", flags);
Florin Coras460dce62018-07-27 05:45:06 -07003398 return VPPCOM_EAFNOSUPPORT;
Stevenac1f96d2017-10-24 16:03:58 -07003399 }
3400
Florin Coras99368312018-08-02 10:45:44 -07003401 if (ep)
3402 {
3403 if (session->transport.is_ip4)
Dave Barach178cf492018-11-13 16:34:13 -05003404 clib_memcpy_fast (ep->ip, &session->transport.rmt_ip.ip4,
3405 sizeof (ip4_address_t));
Florin Coras99368312018-08-02 10:45:44 -07003406 else
Dave Barach178cf492018-11-13 16:34:13 -05003407 clib_memcpy_fast (ep->ip, &session->transport.rmt_ip.ip6,
3408 sizeof (ip6_address_t));
Florin Coras99368312018-08-02 10:45:44 -07003409 }
Florin Coras460dce62018-07-27 05:45:06 -07003410
Stevenac1f96d2017-10-24 16:03:58 -07003411 return rv;
3412}
3413
3414int
Florin Coras134a9962018-08-28 11:32:04 -07003415vppcom_session_sendto (uint32_t session_handle, void *buffer,
Stevenac1f96d2017-10-24 16:03:58 -07003416 uint32_t buflen, int flags, vppcom_endpt_t * ep)
3417{
Dave Wallace617dffa2017-10-26 14:47:06 -04003418 if (!buffer)
3419 return VPPCOM_EINVAL;
3420
3421 if (ep)
3422 {
3423 // TBD
3424 return VPPCOM_EINVAL;
3425 }
3426
3427 if (flags)
3428 {
3429 // TBD check the flags and do the right thing
Florin Coras0d427d82018-06-27 03:24:07 -07003430 VDBG (2, "VCL<%d>: handling flags 0x%u (%d) not implemented yet.",
3431 getpid (), flags, flags);
Dave Wallace617dffa2017-10-26 14:47:06 -04003432 }
3433
Florin Coras42ceddb2018-12-12 10:56:01 -08003434 return (vppcom_session_write_inline (session_handle, buffer, buflen, 1));
Stevenac1f96d2017-10-24 16:03:58 -07003435}
3436
Dave Wallace048b1d62018-01-03 22:24:41 -05003437int
3438vppcom_poll (vcl_poll_t * vp, uint32_t n_sids, double wait_for_time)
3439{
Florin Coras134a9962018-08-28 11:32:04 -07003440 vcl_worker_t *wrk = vcl_worker_get_current ();
3441 f64 timeout = clib_time_now (&wrk->clib_time) + wait_for_time;
Dave Wallace048b1d62018-01-03 22:24:41 -05003442 u32 i, keep_trying = 1;
Florin Coras6917b942018-11-13 22:44:54 -08003443 svm_msg_q_msg_t msg;
3444 session_event_t *e;
Dave Wallace048b1d62018-01-03 22:24:41 -05003445 int rv, num_ev = 0;
3446
Florin Coras0d427d82018-06-27 03:24:07 -07003447 VDBG (3, "VCL<%d>: vp %p, nsids %u, wait_for_time %f",
3448 getpid (), vp, n_sids, wait_for_time);
Dave Wallace048b1d62018-01-03 22:24:41 -05003449
3450 if (!vp)
3451 return VPPCOM_EFAULT;
3452
3453 do
3454 {
Florin Coras7e12d942018-06-27 14:32:43 -07003455 vcl_session_t *session;
Dave Wallace048b1d62018-01-03 22:24:41 -05003456
Florin Coras6917b942018-11-13 22:44:54 -08003457 /* Dequeue all events and drop all unhandled io events */
3458 while (svm_msg_q_sub (wrk->app_event_queue, &msg, SVM_Q_NOWAIT, 0) == 0)
3459 {
3460 e = svm_msg_q_msg_data (wrk->app_event_queue, &msg);
3461 vcl_handle_mq_event (wrk, e);
3462 svm_msg_q_free_msg (wrk->app_event_queue, &msg);
3463 }
3464 vec_reset_length (wrk->unhandled_evts_vector);
3465
Dave Wallace048b1d62018-01-03 22:24:41 -05003466 for (i = 0; i < n_sids; i++)
3467 {
Florin Coras7baeb712019-01-04 17:05:43 -08003468 session = vcl_session_get (wrk, vp[i].sh);
Florin Coras070453d2018-08-24 17:04:27 -07003469 if (!session)
Florin Coras6917b942018-11-13 22:44:54 -08003470 {
3471 vp[i].revents = POLLHUP;
3472 num_ev++;
3473 continue;
3474 }
Dave Wallace048b1d62018-01-03 22:24:41 -05003475
Florin Coras6917b942018-11-13 22:44:54 -08003476 vp[i].revents = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -05003477
3478 if (POLLIN & vp[i].events)
3479 {
Florin Coras54693d22018-07-17 10:46:29 -07003480 rv = vppcom_session_read_ready (session);
Dave Wallace048b1d62018-01-03 22:24:41 -05003481 if (rv > 0)
3482 {
Florin Coras6917b942018-11-13 22:44:54 -08003483 vp[i].revents |= POLLIN;
Dave Wallace048b1d62018-01-03 22:24:41 -05003484 num_ev++;
3485 }
3486 else if (rv < 0)
3487 {
3488 switch (rv)
3489 {
3490 case VPPCOM_ECONNRESET:
Florin Coras6917b942018-11-13 22:44:54 -08003491 vp[i].revents = POLLHUP;
Dave Wallace048b1d62018-01-03 22:24:41 -05003492 break;
3493
3494 default:
Florin Coras6917b942018-11-13 22:44:54 -08003495 vp[i].revents = POLLERR;
Dave Wallace048b1d62018-01-03 22:24:41 -05003496 break;
3497 }
3498 num_ev++;
3499 }
3500 }
3501
3502 if (POLLOUT & vp[i].events)
3503 {
Florin Coras134a9962018-08-28 11:32:04 -07003504 rv = vppcom_session_write_ready (session);
Dave Wallace048b1d62018-01-03 22:24:41 -05003505 if (rv > 0)
3506 {
Florin Coras6917b942018-11-13 22:44:54 -08003507 vp[i].revents |= POLLOUT;
Dave Wallace048b1d62018-01-03 22:24:41 -05003508 num_ev++;
3509 }
3510 else if (rv < 0)
3511 {
3512 switch (rv)
3513 {
3514 case VPPCOM_ECONNRESET:
Florin Coras6917b942018-11-13 22:44:54 -08003515 vp[i].revents = POLLHUP;
Dave Wallace048b1d62018-01-03 22:24:41 -05003516 break;
3517
3518 default:
Florin Coras6917b942018-11-13 22:44:54 -08003519 vp[i].revents = POLLERR;
Dave Wallace048b1d62018-01-03 22:24:41 -05003520 break;
3521 }
3522 num_ev++;
3523 }
3524 }
3525
Dave Wallace7e607a72018-06-18 18:41:32 -04003526 if (0) // Note "done:" label used by VCL_SESSION_LOCK_AND_GET()
Dave Wallace048b1d62018-01-03 22:24:41 -05003527 {
Florin Coras6917b942018-11-13 22:44:54 -08003528 vp[i].revents = POLLNVAL;
Dave Wallace048b1d62018-01-03 22:24:41 -05003529 num_ev++;
3530 }
3531 }
3532 if (wait_for_time != -1)
Florin Coras134a9962018-08-28 11:32:04 -07003533 keep_trying = (clib_time_now (&wrk->clib_time) <= timeout) ? 1 : 0;
Dave Wallace048b1d62018-01-03 22:24:41 -05003534 }
3535 while ((num_ev == 0) && keep_trying);
3536
3537 if (VPPCOM_DEBUG > 3)
3538 {
3539 clib_warning ("VCL<%d>: returning %d", getpid (), num_ev);
3540 for (i = 0; i < n_sids; i++)
3541 {
3542 clib_warning ("VCL<%d>: vp[%d].sid %d (0x%x), .events 0x%x, "
Florin Coras7baeb712019-01-04 17:05:43 -08003543 ".revents 0x%x", getpid (), i, vp[i].sh, vp[i].sh,
Florin Coras6917b942018-11-13 22:44:54 -08003544 vp[i].events, vp[i].revents);
Dave Wallace048b1d62018-01-03 22:24:41 -05003545 }
3546 }
3547 return num_ev;
3548}
3549
Florin Coras99368312018-08-02 10:45:44 -07003550int
3551vppcom_mq_epoll_fd (void)
3552{
Florin Coras134a9962018-08-28 11:32:04 -07003553 vcl_worker_t *wrk = vcl_worker_get_current ();
3554 return wrk->mqs_epfd;
3555}
3556
3557int
Florin Coras30e79c22019-01-02 19:31:22 -08003558vppcom_session_index (vcl_session_handle_t session_handle)
Florin Coras134a9962018-08-28 11:32:04 -07003559{
3560 return session_handle & 0xFFFFFF;
3561}
3562
3563int
Florin Coras30e79c22019-01-02 19:31:22 -08003564vppcom_session_worker (vcl_session_handle_t session_handle)
3565{
3566 return session_handle >> 24;
3567}
3568
3569int
Florin Coras134a9962018-08-28 11:32:04 -07003570vppcom_worker_register (void)
3571{
Florin Coras47c40e22018-11-26 17:01:36 -08003572 if (!vcl_worker_alloc_and_init ())
3573 return VPPCOM_EEXIST;
3574
3575 if (vcl_worker_set_bapi ())
3576 return VPPCOM_EEXIST;
3577
3578 if (vcl_worker_register_with_vpp ())
3579 return VPPCOM_EEXIST;
3580
3581 return VPPCOM_OK;
Florin Coras99368312018-08-02 10:45:44 -07003582}
3583
Florin Corasdfe4cf42018-11-28 22:13:45 -08003584int
3585vppcom_worker_index (void)
3586{
3587 return vcl_get_worker_index ();
3588}
3589
Dave Wallacee22aa742017-10-20 12:30:38 -04003590/*
3591 * fd.io coding-style-patch-verification: ON
3592 *
3593 * Local Variables:
3594 * eval: (c-set-style "gnu")
3595 * End:
3596 */