blob: 7fffc3bcbe2037fe97d13be4c64c040f95891014 [file] [log] [blame]
Dave Wallace543852a2017-08-03 02:11:34 -04001/*
Florin Coras5e062572019-03-14 19:07:51 -07002 * Copyright (c) 2017-2019 Cisco and/or its affiliates.
Dave Wallace543852a2017-08-03 02:11:34 -04003 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this
5 * You may obtain a copy of the License at:
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include <stdio.h>
17#include <stdlib.h>
Dave Wallace5c7cf1c2017-10-24 04:12:18 -040018#include <vcl/vppcom.h>
Florin Coras0d427d82018-06-27 03:24:07 -070019#include <vcl/vcl_debug.h>
Florin Coras697faea2018-06-27 17:10:49 -070020#include <vcl/vcl_private.h>
Florin Coras88001c62019-04-24 14:44:46 -070021#include <svm/fifo_segment.h>
Dave Wallace7e607a72018-06-18 18:41:32 -040022
Florin Coras134a9962018-08-28 11:32:04 -070023__thread uword __vcl_worker_index = ~0;
24
Florin Coras30e79c22019-01-02 19:31:22 -080025static inline int
Florin Corase003a1b2019-06-05 10:47:16 -070026vcl_mq_dequeue_batch (vcl_worker_t * wrk, svm_msg_q_t * mq, u32 n_max_msg)
Florin Coras30e79c22019-01-02 19:31:22 -080027{
Florin Coras5398dfb2021-01-25 20:31:27 -080028 u32 n_msgs = 0, sz, len;
Florin Coras30e79c22019-01-02 19:31:22 -080029
Florin Coras5398dfb2021-01-25 20:31:27 -080030 while ((sz = svm_msg_q_size (mq)))
Florin Coras30e79c22019-01-02 19:31:22 -080031 {
Florin Coras5398dfb2021-01-25 20:31:27 -080032 len = vec_len (wrk->mq_msg_vector);
33 vec_validate (wrk->mq_msg_vector, len + sz - 1);
34 svm_msg_q_sub_raw_batch (mq, wrk->mq_msg_vector + len, sz);
35 n_msgs += sz;
Florin Coras30e79c22019-01-02 19:31:22 -080036 }
37 return n_msgs;
38}
39
Dave Wallace543852a2017-08-03 02:11:34 -040040
Florin Coras697faea2018-06-27 17:10:49 -070041
Florin Coras458089b2019-08-21 16:20:44 -070042static void
Florin Coras4ac25842021-04-19 17:34:54 -070043vcl_msg_add_ext_config (vcl_session_t *s, uword *offset)
44{
45 svm_fifo_chunk_t *c;
46
47 c = vcl_segment_alloc_chunk (vcl_vpp_worker_segment_handle (0),
48 0 /* one slice only */, s->ext_config->len,
49 offset);
50 if (c)
51 clib_memcpy_fast (c->data, s->ext_config, s->ext_config->len);
52}
53
54static void
Florin Coras458089b2019-08-21 16:20:44 -070055vcl_send_session_listen (vcl_worker_t * wrk, vcl_session_t * s)
56{
57 app_session_evt_t _app_evt, *app_evt = &_app_evt;
58 session_listen_msg_t *mp;
59 svm_msg_q_t *mq;
60
61 mq = vcl_worker_ctrl_mq (wrk);
62 app_alloc_ctrl_evt_to_vpp (mq, app_evt, SESSION_CTRL_EVT_LISTEN);
63 mp = (session_listen_msg_t *) app_evt->evt->data;
64 memset (mp, 0, sizeof (*mp));
Florin Corascc7c88e2020-09-15 15:56:51 -070065 mp->client_index = wrk->api_client_handle;
Florin Coras458089b2019-08-21 16:20:44 -070066 mp->context = s->session_index;
67 mp->wrk_index = wrk->vpp_wrk_index;
68 mp->is_ip4 = s->transport.is_ip4;
69 clib_memcpy_fast (&mp->ip, &s->transport.lcl_ip, sizeof (mp->ip));
70 mp->port = s->transport.lcl_port;
71 mp->proto = s->session_type;
Florin Coras6a6555a2021-01-28 11:39:27 -080072 mp->vrf = s->vrf;
Florin Coras1e966172020-05-16 18:18:14 +000073 if (s->flags & VCL_SESSION_F_CONNECTED)
74 mp->flags = TRANSPORT_CFG_F_CONNECTED;
Florin Coras4ac25842021-04-19 17:34:54 -070075 if (s->ext_config)
76 vcl_msg_add_ext_config (s, &mp->ext_config);
Florin Coras458089b2019-08-21 16:20:44 -070077 app_send_ctrl_evt_to_vpp (mq, app_evt);
Florin Coras4ac25842021-04-19 17:34:54 -070078 if (s->ext_config)
79 {
80 clib_mem_free (s->ext_config);
81 s->ext_config = 0;
82 }
Florin Coras458089b2019-08-21 16:20:44 -070083}
84
85static void
86vcl_send_session_connect (vcl_worker_t * wrk, vcl_session_t * s)
87{
88 app_session_evt_t _app_evt, *app_evt = &_app_evt;
89 session_connect_msg_t *mp;
90 svm_msg_q_t *mq;
91
92 mq = vcl_worker_ctrl_mq (wrk);
93 app_alloc_ctrl_evt_to_vpp (mq, app_evt, SESSION_CTRL_EVT_CONNECT);
94 mp = (session_connect_msg_t *) app_evt->evt->data;
95 memset (mp, 0, sizeof (*mp));
Florin Corascc7c88e2020-09-15 15:56:51 -070096 mp->client_index = wrk->api_client_handle;
Florin Coras458089b2019-08-21 16:20:44 -070097 mp->context = s->session_index;
Filip Tehlar2f09bfc2021-11-15 10:26:56 +000098 mp->dscp = s->dscp;
Florin Coras458089b2019-08-21 16:20:44 -070099 mp->wrk_index = wrk->vpp_wrk_index;
100 mp->is_ip4 = s->transport.is_ip4;
101 mp->parent_handle = s->parent_handle;
102 clib_memcpy_fast (&mp->ip, &s->transport.rmt_ip, sizeof (mp->ip));
Florin Corasef7cbf62019-10-17 09:56:27 -0700103 clib_memcpy_fast (&mp->lcl_ip, &s->transport.lcl_ip, sizeof (mp->lcl_ip));
Florin Coras458089b2019-08-21 16:20:44 -0700104 mp->port = s->transport.rmt_port;
Florin Coras0a1e1832020-03-29 18:54:04 +0000105 mp->lcl_port = s->transport.lcl_port;
Florin Coras458089b2019-08-21 16:20:44 -0700106 mp->proto = s->session_type;
Florin Coras6a6555a2021-01-28 11:39:27 -0800107 mp->vrf = s->vrf;
Florin Coras0a1e1832020-03-29 18:54:04 +0000108 if (s->flags & VCL_SESSION_F_CONNECTED)
109 mp->flags |= TRANSPORT_CFG_F_CONNECTED;
Florin Coras4ac25842021-04-19 17:34:54 -0700110 if (s->ext_config)
111 vcl_msg_add_ext_config (s, &mp->ext_config);
Florin Coras458089b2019-08-21 16:20:44 -0700112 app_send_ctrl_evt_to_vpp (mq, app_evt);
Florin Coras4ac25842021-04-19 17:34:54 -0700113
114 if (s->ext_config)
115 {
116 clib_mem_free (s->ext_config);
117 s->ext_config = 0;
118 }
Florin Coras458089b2019-08-21 16:20:44 -0700119}
120
121void
122vcl_send_session_unlisten (vcl_worker_t * wrk, vcl_session_t * s)
123{
124 app_session_evt_t _app_evt, *app_evt = &_app_evt;
125 session_unlisten_msg_t *mp;
126 svm_msg_q_t *mq;
127
128 mq = vcl_worker_ctrl_mq (wrk);
129 app_alloc_ctrl_evt_to_vpp (mq, app_evt, SESSION_CTRL_EVT_UNLISTEN);
130 mp = (session_unlisten_msg_t *) app_evt->evt->data;
131 memset (mp, 0, sizeof (*mp));
Florin Corascc7c88e2020-09-15 15:56:51 -0700132 mp->client_index = wrk->api_client_handle;
Florin Coras458089b2019-08-21 16:20:44 -0700133 mp->wrk_index = wrk->vpp_wrk_index;
134 mp->handle = s->vpp_handle;
135 mp->context = wrk->wrk_index;
136 app_send_ctrl_evt_to_vpp (mq, app_evt);
137}
138
139static void
liuyacan534468e2021-05-09 03:50:40 +0000140vcl_send_session_shutdown (vcl_worker_t *wrk, vcl_session_t *s)
141{
142 app_session_evt_t _app_evt, *app_evt = &_app_evt;
143 session_shutdown_msg_t *mp;
144 svm_msg_q_t *mq;
145
146 /* Send to thread that owns the session */
147 mq = s->vpp_evt_q;
148 app_alloc_ctrl_evt_to_vpp (mq, app_evt, SESSION_CTRL_EVT_SHUTDOWN);
149 mp = (session_shutdown_msg_t *) app_evt->evt->data;
150 memset (mp, 0, sizeof (*mp));
151 mp->client_index = wrk->api_client_handle;
152 mp->handle = s->vpp_handle;
153 app_send_ctrl_evt_to_vpp (mq, app_evt);
154}
155
156static void
Florin Coras458089b2019-08-21 16:20:44 -0700157vcl_send_session_disconnect (vcl_worker_t * wrk, vcl_session_t * s)
158{
159 app_session_evt_t _app_evt, *app_evt = &_app_evt;
160 session_disconnect_msg_t *mp;
161 svm_msg_q_t *mq;
162
163 /* Send to thread that owns the session */
164 mq = s->vpp_evt_q;
165 app_alloc_ctrl_evt_to_vpp (mq, app_evt, SESSION_CTRL_EVT_DISCONNECT);
166 mp = (session_disconnect_msg_t *) app_evt->evt->data;
167 memset (mp, 0, sizeof (*mp));
Florin Corascc7c88e2020-09-15 15:56:51 -0700168 mp->client_index = wrk->api_client_handle;
Florin Coras458089b2019-08-21 16:20:44 -0700169 mp->handle = s->vpp_handle;
170 app_send_ctrl_evt_to_vpp (mq, app_evt);
171}
172
173static void
174vcl_send_app_detach (vcl_worker_t * wrk)
175{
176 app_session_evt_t _app_evt, *app_evt = &_app_evt;
177 session_app_detach_msg_t *mp;
178 svm_msg_q_t *mq;
179
180 mq = vcl_worker_ctrl_mq (wrk);
181 app_alloc_ctrl_evt_to_vpp (mq, app_evt, SESSION_CTRL_EVT_APP_DETACH);
182 mp = (session_app_detach_msg_t *) app_evt->evt->data;
183 memset (mp, 0, sizeof (*mp));
Florin Corascc7c88e2020-09-15 15:56:51 -0700184 mp->client_index = wrk->api_client_handle;
Florin Coras458089b2019-08-21 16:20:44 -0700185 app_send_ctrl_evt_to_vpp (mq, app_evt);
186}
Florin Coras697faea2018-06-27 17:10:49 -0700187
Florin Coras54693d22018-07-17 10:46:29 -0700188static void
189vcl_send_session_accepted_reply (svm_msg_q_t * mq, u32 context,
190 session_handle_t handle, int retval)
191{
192 app_session_evt_t _app_evt, *app_evt = &_app_evt;
193 session_accepted_reply_msg_t *rmp;
194 app_alloc_ctrl_evt_to_vpp (mq, app_evt, SESSION_CTRL_EVT_ACCEPTED_REPLY);
195 rmp = (session_accepted_reply_msg_t *) app_evt->evt->data;
196 rmp->handle = handle;
197 rmp->context = context;
198 rmp->retval = retval;
199 app_send_ctrl_evt_to_vpp (mq, app_evt);
200}
201
Florin Coras99368312018-08-02 10:45:44 -0700202static void
Florin Coras52dd29f2020-11-18 19:02:17 -0800203vcl_send_session_disconnected_reply (vcl_worker_t * wrk, vcl_session_t * s,
204 int retval)
Florin Coras99368312018-08-02 10:45:44 -0700205{
206 app_session_evt_t _app_evt, *app_evt = &_app_evt;
207 session_disconnected_reply_msg_t *rmp;
Florin Coras52dd29f2020-11-18 19:02:17 -0800208 app_alloc_ctrl_evt_to_vpp (s->vpp_evt_q, app_evt,
Florin Coras99368312018-08-02 10:45:44 -0700209 SESSION_CTRL_EVT_DISCONNECTED_REPLY);
210 rmp = (session_disconnected_reply_msg_t *) app_evt->evt->data;
Florin Coras52dd29f2020-11-18 19:02:17 -0800211 rmp->handle = s->vpp_handle;
212 rmp->context = wrk->api_client_handle;
Florin Coras99368312018-08-02 10:45:44 -0700213 rmp->retval = retval;
Florin Coras52dd29f2020-11-18 19:02:17 -0800214 app_send_ctrl_evt_to_vpp (s->vpp_evt_q, app_evt);
Florin Coras99368312018-08-02 10:45:44 -0700215}
216
Florin Corasc9fbd662018-08-24 12:59:56 -0700217static void
Florin Coras52dd29f2020-11-18 19:02:17 -0800218vcl_send_session_reset_reply (vcl_worker_t * wrk, vcl_session_t * s,
219 int retval)
Florin Corasc9fbd662018-08-24 12:59:56 -0700220{
221 app_session_evt_t _app_evt, *app_evt = &_app_evt;
222 session_reset_reply_msg_t *rmp;
Florin Coras52dd29f2020-11-18 19:02:17 -0800223 app_alloc_ctrl_evt_to_vpp (s->vpp_evt_q, app_evt,
224 SESSION_CTRL_EVT_RESET_REPLY);
Florin Corasc9fbd662018-08-24 12:59:56 -0700225 rmp = (session_reset_reply_msg_t *) app_evt->evt->data;
Florin Coras52dd29f2020-11-18 19:02:17 -0800226 rmp->handle = s->vpp_handle;
227 rmp->context = wrk->api_client_handle;
Florin Corasc9fbd662018-08-24 12:59:56 -0700228 rmp->retval = retval;
Florin Coras52dd29f2020-11-18 19:02:17 -0800229 app_send_ctrl_evt_to_vpp (s->vpp_evt_q, app_evt);
Florin Corasc9fbd662018-08-24 12:59:56 -0700230}
231
Florin Coras30e79c22019-01-02 19:31:22 -0800232void
233vcl_send_session_worker_update (vcl_worker_t * wrk, vcl_session_t * s,
234 u32 wrk_index)
235{
236 app_session_evt_t _app_evt, *app_evt = &_app_evt;
237 session_worker_update_msg_t *mp;
Florin Coras30e79c22019-01-02 19:31:22 -0800238
Florin Coras52dd29f2020-11-18 19:02:17 -0800239 app_alloc_ctrl_evt_to_vpp (s->vpp_evt_q, app_evt,
240 SESSION_CTRL_EVT_WORKER_UPDATE);
Florin Coras30e79c22019-01-02 19:31:22 -0800241 mp = (session_worker_update_msg_t *) app_evt->evt->data;
Florin Corascc7c88e2020-09-15 15:56:51 -0700242 mp->client_index = wrk->api_client_handle;
Florin Coras30e79c22019-01-02 19:31:22 -0800243 mp->handle = s->vpp_handle;
244 mp->req_wrk_index = wrk->vpp_wrk_index;
245 mp->wrk_index = wrk_index;
Florin Coras52dd29f2020-11-18 19:02:17 -0800246 app_send_ctrl_evt_to_vpp (s->vpp_evt_q, app_evt);
Florin Coras30e79c22019-01-02 19:31:22 -0800247}
248
hanlina3a48962020-07-13 11:09:15 +0800249int
Florin Coras40c07ce2020-07-16 20:46:17 -0700250vcl_send_worker_rpc (u32 dst_wrk_index, void *data, u32 data_len)
251{
252 app_session_evt_t _app_evt, *app_evt = &_app_evt;
253 session_app_wrk_rpc_msg_t *mp;
254 vcl_worker_t *dst_wrk, *wrk;
255 svm_msg_q_t *mq;
hanlina3a48962020-07-13 11:09:15 +0800256 int ret = -1;
Florin Coras40c07ce2020-07-16 20:46:17 -0700257
258 if (data_len > sizeof (mp->data))
259 goto done;
260
261 clib_spinlock_lock (&vcm->workers_lock);
262
263 dst_wrk = vcl_worker_get_if_valid (dst_wrk_index);
264 if (!dst_wrk)
265 goto done;
266
267 wrk = vcl_worker_get_current ();
268 mq = vcl_worker_ctrl_mq (wrk);
269 app_alloc_ctrl_evt_to_vpp (mq, app_evt, SESSION_CTRL_EVT_APP_WRK_RPC);
270 mp = (session_app_wrk_rpc_msg_t *) app_evt->evt->data;
Florin Corascc7c88e2020-09-15 15:56:51 -0700271 mp->client_index = wrk->api_client_handle;
Florin Coras40c07ce2020-07-16 20:46:17 -0700272 mp->wrk_index = dst_wrk->vpp_wrk_index;
273 clib_memcpy (mp->data, data, data_len);
274 app_send_ctrl_evt_to_vpp (mq, app_evt);
hanlina3a48962020-07-13 11:09:15 +0800275 ret = 0;
Florin Coras40c07ce2020-07-16 20:46:17 -0700276
277done:
278 clib_spinlock_unlock (&vcm->workers_lock);
hanlina3a48962020-07-13 11:09:15 +0800279 return ret;
Florin Coras40c07ce2020-07-16 20:46:17 -0700280}
281
Florin Coras04ae8272021-04-12 19:55:37 -0700282int
283vcl_session_transport_attr (vcl_worker_t *wrk, vcl_session_t *s, u8 is_get,
284 transport_endpt_attr_t *attr)
285{
286 app_session_evt_t _app_evt, *app_evt = &_app_evt;
287 session_transport_attr_msg_t *mp;
288 svm_msg_q_t *mq;
289 f64 timeout;
290
291 ASSERT (!wrk->session_attr_op);
292 wrk->session_attr_op = 1;
293 wrk->session_attr_op_rv = -1;
294
295 mq = s->vpp_evt_q;
296 app_alloc_ctrl_evt_to_vpp (mq, app_evt, SESSION_CTRL_EVT_TRANSPORT_ATTR);
297 mp = (session_transport_attr_msg_t *) app_evt->evt->data;
298 memset (mp, 0, sizeof (*mp));
299 mp->client_index = wrk->api_client_handle;
300 mp->handle = s->vpp_handle;
301 mp->is_get = is_get;
302 mp->attr = *attr;
303 app_send_ctrl_evt_to_vpp (mq, app_evt);
304
305 timeout = clib_time_now (&wrk->clib_time) + 1;
306
307 while (wrk->session_attr_op && clib_time_now (&wrk->clib_time) < timeout)
308 vcl_flush_mq_events ();
309
310 if (!wrk->session_attr_op_rv && is_get)
311 *attr = wrk->session_attr_rv;
312
313 wrk->session_attr_op = 0;
314
315 return wrk->session_attr_op_rv;
316}
317
Florin Coras54693d22018-07-17 10:46:29 -0700318static u32
Florin Coras00cca802019-06-06 09:38:44 -0700319vcl_session_accepted_handler (vcl_worker_t * wrk, session_accepted_msg_t * mp,
320 u32 ls_index)
Florin Coras54693d22018-07-17 10:46:29 -0700321{
322 vcl_session_t *session, *listen_session;
Florin Coras99368312018-08-02 10:45:44 -0700323 svm_msg_q_t *evt_q;
Florin Coras54693d22018-07-17 10:46:29 -0700324
Florin Coras134a9962018-08-28 11:32:04 -0700325 session = vcl_session_alloc (wrk);
Florin Coras99368312018-08-02 10:45:44 -0700326
Florin Coras00cca802019-06-06 09:38:44 -0700327 listen_session = vcl_session_get (wrk, ls_index);
328 if (listen_session->vpp_handle != mp->listener_handle)
Florin Coras54693d22018-07-17 10:46:29 -0700329 {
Florin Coras00cca802019-06-06 09:38:44 -0700330 VDBG (0, "ERROR: listener handle %lu does not match session %u",
331 mp->listener_handle, ls_index);
332 goto error;
333 }
334
Florin Corasf6e284b2021-07-21 18:17:20 -0700335 if (vcl_segment_attach_session (
336 mp->segment_handle, mp->server_rx_fifo, mp->server_tx_fifo,
337 mp->vpp_event_queue_address, mp->mq_index, 0, session))
Florin Coras00cca802019-06-06 09:38:44 -0700338 {
Florin Coras5ffb9642021-12-03 17:24:13 -0800339 VDBG (0, "session %u [0x%llx]: failed to attach fifos",
340 session->session_index, mp->handle);
Florin Coras00cca802019-06-06 09:38:44 -0700341 goto error;
Florin Coras54693d22018-07-17 10:46:29 -0700342 }
343
Florin Coras54693d22018-07-17 10:46:29 -0700344 session->vpp_handle = mp->handle;
Florin Corasdfffdd72020-10-15 10:54:47 -0700345 session->session_state = VCL_STATE_READY;
Florin Coras09d18c22019-04-24 11:10:02 -0700346 session->transport.rmt_port = mp->rmt.port;
347 session->transport.is_ip4 = mp->rmt.is_ip4;
348 clib_memcpy_fast (&session->transport.rmt_ip, &mp->rmt.ip,
Dave Barach178cf492018-11-13 16:34:13 -0500349 sizeof (ip46_address_t));
Florin Coras54693d22018-07-17 10:46:29 -0700350
Florin Coras134a9962018-08-28 11:32:04 -0700351 vcl_session_table_add_vpp_handle (wrk, mp->handle, session->session_index);
Florin Coras67c90a32021-03-09 18:36:06 -0800352 session->transport.lcl_port = mp->lcl.port;
353 session->transport.lcl_ip = mp->lcl.ip;
Florin Coras460dce62018-07-27 05:45:06 -0700354 session->session_type = listen_session->session_type;
Nathan Skrzypczak9fd99622019-05-16 14:38:44 +0200355 session->is_dgram = vcl_proto_is_dgram (session->session_type);
356 session->listener_index = listen_session->session_index;
357 listen_session->n_accepted_sessions++;
Florin Coras54693d22018-07-17 10:46:29 -0700358
Florin Coras54693d22018-07-17 10:46:29 -0700359 vcl_evt (VCL_EVT_ACCEPT, session, listen_session, session_index);
360
Florin Coras00cca802019-06-06 09:38:44 -0700361 vcl_send_session_accepted_reply (session->vpp_evt_q, mp->context,
362 session->vpp_handle, 0);
363
Florin Coras134a9962018-08-28 11:32:04 -0700364 return session->session_index;
Florin Coras00cca802019-06-06 09:38:44 -0700365
366error:
Florin Corasb4624182020-12-11 13:58:12 -0800367 vcl_segment_attach_mq (vcl_vpp_worker_segment_handle (0),
368 mp->vpp_event_queue_address, mp->mq_index, &evt_q);
Florin Coras00cca802019-06-06 09:38:44 -0700369 vcl_send_session_accepted_reply (evt_q, mp->context, mp->handle,
370 VNET_API_ERROR_INVALID_ARGUMENT);
371 vcl_session_free (wrk, session);
372 return VCL_INVALID_SESSION_INDEX;
Florin Coras54693d22018-07-17 10:46:29 -0700373}
374
375static u32
Florin Coras134a9962018-08-28 11:32:04 -0700376vcl_session_connected_handler (vcl_worker_t * wrk,
377 session_connected_msg_t * mp)
Florin Coras54693d22018-07-17 10:46:29 -0700378{
Florin Coras99368312018-08-02 10:45:44 -0700379 vcl_session_t *session = 0;
Florin Coras52dd29f2020-11-18 19:02:17 -0800380 u32 session_index;
Florin Coras54693d22018-07-17 10:46:29 -0700381
382 session_index = mp->context;
Florin Coras134a9962018-08-28 11:32:04 -0700383 session = vcl_session_get (wrk, session_index);
Florin Corasef2c0f12021-11-10 22:44:52 -0800384 if (PREDICT_FALSE (!session))
Florin Coras070453d2018-08-24 17:04:27 -0700385 {
Florin Coras8d42c752021-11-29 23:26:19 -0800386 VERR ("vpp handle 0x%llx has no session index (%u)!", mp->handle,
387 session_index);
Florin Corasef2c0f12021-11-10 22:44:52 -0800388 /* Should not happen but if it does, force vpp session cleanup */
389 vcl_session_t tmp_session = {
390 .vpp_handle = mp->handle,
391 .vpp_evt_q = 0,
392 };
393 vcl_segment_attach_session (
394 mp->segment_handle, mp->server_rx_fifo, mp->server_tx_fifo,
395 mp->vpp_event_queue_address, mp->mq_index, 0, session);
396 if (tmp_session.vpp_evt_q)
397 vcl_send_session_disconnect (wrk, &tmp_session);
Florin Coras070453d2018-08-24 17:04:27 -0700398 return VCL_INVALID_SESSION_INDEX;
399 }
Florin Coras8d42c752021-11-29 23:26:19 -0800400
Florin Coras54693d22018-07-17 10:46:29 -0700401 if (mp->retval)
402 {
Florin Coras5ffb9642021-12-03 17:24:13 -0800403 VDBG (0, "session %u: connect failed! %U", session_index,
Florin Coras8d42c752021-11-29 23:26:19 -0800404 format_session_error, mp->retval);
Florin Corasc127d5a2020-10-14 16:35:58 -0700405 session->session_state = VCL_STATE_DETACHED;
Florin Coras8d42c752021-11-29 23:26:19 -0800406 session->vpp_handle = VCL_INVALID_SESSION_HANDLE;
Florin Coras070453d2018-08-24 17:04:27 -0700407 return session_index;
Florin Coras54693d22018-07-17 10:46:29 -0700408 }
409
Florin Corasdbc9c592019-09-25 16:37:43 -0700410 session->vpp_handle = mp->handle;
Florin Corasc547e912020-12-08 17:50:45 -0800411
Florin Coras8d42c752021-11-29 23:26:19 -0800412 /* Add to lookup table. Even if something fails, session cannot be
413 * cleaned up prior to notifying vpp and going through the cleanup
414 * "procedure" see @ref vcl_session_cleanup_handler */
415 vcl_session_table_add_vpp_handle (wrk, mp->handle, session_index);
416
Florin Corasf6e284b2021-07-21 18:17:20 -0700417 if (vcl_segment_attach_session (
418 mp->segment_handle, mp->server_rx_fifo, mp->server_tx_fifo,
419 mp->vpp_event_queue_address, mp->mq_index, 0, session))
Florin Corasd85de682018-11-29 17:02:29 -0800420 {
Florin Coras5ffb9642021-12-03 17:24:13 -0800421 VDBG (0, "session %u [0x%llx]: failed to attach fifos",
422 session->session_index, session->vpp_handle);
Florin Coras8d42c752021-11-29 23:26:19 -0800423 session->session_state = VCL_STATE_UPDATED;
Florin Corasdbc9c592019-09-25 16:37:43 -0700424 vcl_send_session_disconnect (wrk, session);
425 return session_index;
Florin Corasd85de682018-11-29 17:02:29 -0800426 }
427
Florin Coras653e43f2019-03-04 10:56:23 -0800428 if (mp->ct_rx_fifo)
Florin Coras99368312018-08-02 10:45:44 -0700429 {
Florin Corasc547e912020-12-08 17:50:45 -0800430 if (vcl_segment_attach_session (mp->ct_segment_handle, mp->ct_rx_fifo,
Florin Corasf6e284b2021-07-21 18:17:20 -0700431 mp->ct_tx_fifo, (uword) ~0, ~0, 1,
432 session))
Florin Coras653e43f2019-03-04 10:56:23 -0800433 {
Florin Coras5ffb9642021-12-03 17:24:13 -0800434 VDBG (0, "session %u [0x%llx]: failed to attach ct fifos",
435 session->session_index, session->vpp_handle);
Florin Coras8d42c752021-11-29 23:26:19 -0800436 session->session_state = VCL_STATE_UPDATED;
Florin Corasdbc9c592019-09-25 16:37:43 -0700437 vcl_send_session_disconnect (wrk, session);
438 return session_index;
Florin Coras653e43f2019-03-04 10:56:23 -0800439 }
Florin Coras99368312018-08-02 10:45:44 -0700440 }
Florin Coras54693d22018-07-17 10:46:29 -0700441
Florin Coras09d18c22019-04-24 11:10:02 -0700442 session->transport.is_ip4 = mp->lcl.is_ip4;
443 clib_memcpy_fast (&session->transport.lcl_ip, &mp->lcl.ip,
Dave Barach178cf492018-11-13 16:34:13 -0500444 sizeof (session->transport.lcl_ip));
Florin Coras09d18c22019-04-24 11:10:02 -0700445 session->transport.lcl_port = mp->lcl.port;
Florin Corasa5ea8212020-08-24 21:23:51 -0700446
447 /* Application closed session before connect reply */
Florin Corasac422d62020-10-19 20:51:36 -0700448 if (vcl_session_has_attr (session, VCL_SESS_ATTR_NONBLOCK)
Florin Corasc127d5a2020-10-14 16:35:58 -0700449 && session->session_state == VCL_STATE_CLOSED)
Florin Corasa5ea8212020-08-24 21:23:51 -0700450 vcl_send_session_disconnect (wrk, session);
451 else
Florin Corasdfffdd72020-10-15 10:54:47 -0700452 session->session_state = VCL_STATE_READY;
Florin Coras54693d22018-07-17 10:46:29 -0700453
Florin Coras5ffb9642021-12-03 17:24:13 -0800454 VDBG (0, "session %u [0x%llx] connected local: %U:%u remote %U:%u",
455 session->session_index, session->vpp_handle, vcl_format_ip46_address,
456 &session->transport.lcl_ip,
457 session->transport.is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6,
458 clib_net_to_host_u16 (session->transport.lcl_port),
459 vcl_format_ip46_address, &session->transport.rmt_ip,
460 session->transport.is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6,
461 clib_net_to_host_u16 (session->transport.rmt_port));
Florin Coras070453d2018-08-24 17:04:27 -0700462
Florin Coras54693d22018-07-17 10:46:29 -0700463 return session_index;
464}
465
Florin Coras3c7d4f92018-12-14 11:28:43 -0800466static int
467vcl_flag_accepted_session (vcl_session_t * session, u64 handle, u32 flags)
468{
469 vcl_session_msg_t *accepted_msg;
470 int i;
471
472 for (i = 0; i < vec_len (session->accept_evts_fifo); i++)
473 {
474 accepted_msg = &session->accept_evts_fifo[i];
475 if (accepted_msg->accepted_msg.handle == handle)
476 {
Florin Corasb0f662f2018-12-27 14:51:46 -0800477 accepted_msg->flags |= flags;
Florin Coras3c7d4f92018-12-14 11:28:43 -0800478 return 1;
479 }
480 }
481 return 0;
482}
483
Florin Corasc9fbd662018-08-24 12:59:56 -0700484static u32
Florin Coras134a9962018-08-28 11:32:04 -0700485vcl_session_reset_handler (vcl_worker_t * wrk,
486 session_reset_msg_t * reset_msg)
Florin Corasc9fbd662018-08-24 12:59:56 -0700487{
488 vcl_session_t *session;
489 u32 sid;
490
Florin Coras134a9962018-08-28 11:32:04 -0700491 sid = vcl_session_index_from_vpp_handle (wrk, reset_msg->handle);
492 session = vcl_session_get (wrk, sid);
Florin Corasc9fbd662018-08-24 12:59:56 -0700493 if (!session)
494 {
495 VDBG (0, "request to reset unknown handle 0x%llx", reset_msg->handle);
496 return VCL_INVALID_SESSION_INDEX;
497 }
Florin Coras3c7d4f92018-12-14 11:28:43 -0800498
499 /* Caught a reset before actually accepting the session */
Florin Corasc127d5a2020-10-14 16:35:58 -0700500 if (session->session_state == VCL_STATE_LISTEN)
Florin Coras3c7d4f92018-12-14 11:28:43 -0800501 {
502
503 if (!vcl_flag_accepted_session (session, reset_msg->handle,
504 VCL_ACCEPTED_F_RESET))
505 VDBG (0, "session was not accepted!");
506 return VCL_INVALID_SESSION_INDEX;
507 }
508
Florin Corasc127d5a2020-10-14 16:35:58 -0700509 if (session->session_state != VCL_STATE_CLOSED)
510 session->session_state = VCL_STATE_DISCONNECT;
Florin Coras5ffb9642021-12-03 17:24:13 -0800511 VDBG (0, "session %u [0x%llx]: reset", sid, reset_msg->handle);
Florin Corasc9fbd662018-08-24 12:59:56 -0700512 return sid;
513}
514
Florin Coras60116992018-08-27 09:52:18 -0700515static u32
Florin Coras134a9962018-08-28 11:32:04 -0700516vcl_session_bound_handler (vcl_worker_t * wrk, session_bound_msg_t * mp)
Florin Coras60116992018-08-27 09:52:18 -0700517{
518 vcl_session_t *session;
519 u32 sid = mp->context;
520
Florin Coras134a9962018-08-28 11:32:04 -0700521 session = vcl_session_get (wrk, sid);
Florin Coras60116992018-08-27 09:52:18 -0700522 if (mp->retval)
523 {
Florin Coras5e062572019-03-14 19:07:51 -0700524 VERR ("session %u [0x%llx]: bind failed: %U", sid, mp->handle,
Florin Coras00e01d32019-10-21 16:07:46 -0700525 format_session_error, mp->retval);
Florin Coras60116992018-08-27 09:52:18 -0700526 if (session)
527 {
Florin Corasc127d5a2020-10-14 16:35:58 -0700528 session->session_state = VCL_STATE_DETACHED;
Florin Coras60116992018-08-27 09:52:18 -0700529 session->vpp_handle = mp->handle;
530 return sid;
531 }
532 else
533 {
Florin Coras5ffb9642021-12-03 17:24:13 -0800534 VDBG (0, "session %u [0x%llx]: Invalid session index!", sid,
535 mp->handle);
Florin Coras60116992018-08-27 09:52:18 -0700536 return VCL_INVALID_SESSION_INDEX;
537 }
538 }
539
540 session->vpp_handle = mp->handle;
541 session->transport.is_ip4 = mp->lcl_is_ip4;
Dave Barach178cf492018-11-13 16:34:13 -0500542 clib_memcpy_fast (&session->transport.lcl_ip, mp->lcl_ip,
543 sizeof (ip46_address_t));
Florin Coras60116992018-08-27 09:52:18 -0700544 session->transport.lcl_port = mp->lcl_port;
Florin Coras134a9962018-08-28 11:32:04 -0700545 vcl_session_table_add_listener (wrk, mp->handle, sid);
Florin Corasc127d5a2020-10-14 16:35:58 -0700546 session->session_state = VCL_STATE_LISTEN;
Florin Coras5f45e012019-01-23 09:21:30 -0800547
Florin Coras6e3c1f82020-01-15 01:30:46 +0000548 if (vcl_session_is_cl (session))
Florin Coras60116992018-08-27 09:52:18 -0700549 {
Florin Corasc547e912020-12-08 17:50:45 -0800550 if (vcl_segment_attach_session (mp->segment_handle, mp->rx_fifo,
Florin Corasf6e284b2021-07-21 18:17:20 -0700551 mp->tx_fifo, mp->vpp_evt_q, mp->mq_index,
552 0, session))
Florin Corasc547e912020-12-08 17:50:45 -0800553 {
Florin Coras5ffb9642021-12-03 17:24:13 -0800554 VDBG (0, "session %u [0x%llx]: failed to attach fifos",
555 session->session_index, session->vpp_handle);
Florin Corasc547e912020-12-08 17:50:45 -0800556 session->session_state = VCL_STATE_DETACHED;
557 return VCL_INVALID_SESSION_INDEX;
558 }
Florin Coras60116992018-08-27 09:52:18 -0700559 }
560
Florin Coras05ecfcc2018-12-12 18:19:39 -0800561 VDBG (0, "session %u [0x%llx]: listen succeeded!", sid, mp->handle);
Florin Coras60116992018-08-27 09:52:18 -0700562 return sid;
563}
564
Florin Corasdfae9f92019-02-20 19:48:31 -0800565static void
566vcl_session_unlisten_reply_handler (vcl_worker_t * wrk, void *data)
567{
568 session_unlisten_reply_msg_t *mp = (session_unlisten_reply_msg_t *) data;
569 vcl_session_t *s;
570
571 s = vcl_session_get_w_vpp_handle (wrk, mp->handle);
Florin Coras0a1e1832020-03-29 18:54:04 +0000572 if (!s)
Florin Corasdfae9f92019-02-20 19:48:31 -0800573 {
574 VDBG (0, "Unlisten reply with wrong handle %llx", mp->handle);
575 return;
576 }
Florin Corasc127d5a2020-10-14 16:35:58 -0700577 if (s->session_state != VCL_STATE_DISCONNECT)
Florin Coras0a1e1832020-03-29 18:54:04 +0000578 {
579 /* Connected udp listener */
580 if (s->session_type == VPPCOM_PROTO_UDP
Florin Corasc127d5a2020-10-14 16:35:58 -0700581 && s->session_state == VCL_STATE_CLOSED)
Florin Coras0a1e1832020-03-29 18:54:04 +0000582 return;
583
584 VDBG (0, "Unlisten session in wrong state %llx", mp->handle);
585 return;
586 }
Florin Corasdfae9f92019-02-20 19:48:31 -0800587
588 if (mp->retval)
589 VDBG (0, "ERROR: session %u [0xllx]: unlisten failed: %U",
Florin Coras00e01d32019-10-21 16:07:46 -0700590 s->session_index, mp->handle, format_session_error, mp->retval);
Florin Corasdfae9f92019-02-20 19:48:31 -0800591
592 if (mp->context != wrk->wrk_index)
593 VDBG (0, "wrong context");
594
595 vcl_session_table_del_vpp_handle (wrk, mp->handle);
596 vcl_session_free (wrk, s);
597}
598
Florin Coras68b7e582020-01-21 18:33:23 -0800599static void
600vcl_session_migrated_handler (vcl_worker_t * wrk, void *data)
601{
602 session_migrated_msg_t *mp = (session_migrated_msg_t *) data;
603 vcl_session_t *s;
Florin Corasc547e912020-12-08 17:50:45 -0800604 u32 fs_index;
Florin Coras68b7e582020-01-21 18:33:23 -0800605
606 s = vcl_session_get_w_vpp_handle (wrk, mp->handle);
607 if (!s)
608 {
609 VDBG (0, "Migrated notification with wrong handle %llx", mp->handle);
610 return;
611 }
612
Florin Coras1bb74942021-02-10 15:26:37 -0800613 /* Only validate if a value is provided */
614 if (mp->segment_handle != SESSION_INVALID_HANDLE)
Florin Corasc547e912020-12-08 17:50:45 -0800615 {
Florin Coras1bb74942021-02-10 15:26:37 -0800616 fs_index = vcl_segment_table_lookup (mp->segment_handle);
617 if (fs_index == VCL_INVALID_SEGMENT_INDEX)
618 {
619 VDBG (0, "segment %lx for session %u is not mounted!",
620 mp->segment_handle, s->session_index);
621 s->session_state = VCL_STATE_DETACHED;
622 return;
623 }
Florin Corasc547e912020-12-08 17:50:45 -0800624 }
625
Florin Coras57660d92020-04-04 22:45:34 +0000626 s->vpp_handle = mp->new_handle;
Florin Corasb4624182020-12-11 13:58:12 -0800627
628 vcl_segment_attach_mq (vcl_vpp_worker_segment_handle (0), mp->vpp_evt_q,
629 mp->vpp_thread_index, &s->vpp_evt_q);
Florin Coras68b7e582020-01-21 18:33:23 -0800630
Florin Coras68b7e582020-01-21 18:33:23 -0800631 vcl_session_table_del_vpp_handle (wrk, mp->handle);
632 vcl_session_table_add_vpp_handle (wrk, mp->new_handle, s->session_index);
633
634 /* Generate new tx event if we have outstanding data */
635 if (svm_fifo_has_event (s->tx_fifo))
Florin Corasc547e912020-12-08 17:50:45 -0800636 app_send_io_evt_to_vpp (s->vpp_evt_q,
637 s->tx_fifo->shr->master_session_index,
Florin Coras68b7e582020-01-21 18:33:23 -0800638 SESSION_IO_EVT_TX, SVM_Q_WAIT);
639
Florin Coras57660d92020-04-04 22:45:34 +0000640 VDBG (0, "Migrated 0x%lx to thread %u 0x%lx", mp->handle,
Florin Coras52dd29f2020-11-18 19:02:17 -0800641 mp->vpp_thread_index, mp->new_handle);
Florin Coras68b7e582020-01-21 18:33:23 -0800642}
643
Florin Coras3c7d4f92018-12-14 11:28:43 -0800644static vcl_session_t *
645vcl_session_accepted (vcl_worker_t * wrk, session_accepted_msg_t * msg)
646{
647 vcl_session_msg_t *vcl_msg;
648 vcl_session_t *session;
649
650 session = vcl_session_get_w_vpp_handle (wrk, msg->handle);
651 if (PREDICT_FALSE (session != 0))
Florin Corasb0f662f2018-12-27 14:51:46 -0800652 VWRN ("session overlap handle %lu state %u!", msg->handle,
653 session->session_state);
Florin Coras3c7d4f92018-12-14 11:28:43 -0800654
655 session = vcl_session_table_lookup_listener (wrk, msg->listener_handle);
656 if (!session)
657 {
658 VERR ("couldn't find listen session: listener handle %llx",
659 msg->listener_handle);
660 return 0;
661 }
662
663 clib_fifo_add2 (session->accept_evts_fifo, vcl_msg);
Florin Corase88845e2020-02-13 20:04:28 +0000664 vcl_msg->flags = 0;
Florin Coras3c7d4f92018-12-14 11:28:43 -0800665 vcl_msg->accepted_msg = *msg;
666 /* Session handle points to listener until fully accepted by app */
667 vcl_session_table_add_vpp_handle (wrk, msg->handle, session->session_index);
668
669 return session;
670}
671
672static vcl_session_t *
673vcl_session_disconnected_handler (vcl_worker_t * wrk,
674 session_disconnected_msg_t * msg)
675{
676 vcl_session_t *session;
677
678 session = vcl_session_get_w_vpp_handle (wrk, msg->handle);
679 if (!session)
680 {
Florin Coras5ffb9642021-12-03 17:24:13 -0800681 VWRN ("request to disconnect unknown handle 0x%llx", msg->handle);
Florin Coras3c7d4f92018-12-14 11:28:43 -0800682 return 0;
683 }
684
Florin Corasadcfb152020-02-12 08:50:29 +0000685 /* Late disconnect notification on a session that has been closed */
Florin Corasc127d5a2020-10-14 16:35:58 -0700686 if (session->session_state == VCL_STATE_CLOSED)
Florin Corasadcfb152020-02-12 08:50:29 +0000687 return 0;
688
Florin Coras3c7d4f92018-12-14 11:28:43 -0800689 /* Caught a disconnect before actually accepting the session */
Florin Corasc127d5a2020-10-14 16:35:58 -0700690 if (session->session_state == VCL_STATE_LISTEN)
Florin Coras3c7d4f92018-12-14 11:28:43 -0800691 {
Florin Coras3c7d4f92018-12-14 11:28:43 -0800692 if (!vcl_flag_accepted_session (session, msg->handle,
693 VCL_ACCEPTED_F_CLOSED))
694 VDBG (0, "session was not accepted!");
695 return 0;
696 }
697
Florin Corasadcfb152020-02-12 08:50:29 +0000698 /* If not already reset change state */
Florin Corasc127d5a2020-10-14 16:35:58 -0700699 if (session->session_state != VCL_STATE_DISCONNECT)
700 session->session_state = VCL_STATE_VPP_CLOSING;
Florin Corasadcfb152020-02-12 08:50:29 +0000701
Florin Coras3c7d4f92018-12-14 11:28:43 -0800702 return session;
703}
704
liuyacan534468e2021-05-09 03:50:40 +0000705int
liuyacan55c952e2021-06-13 14:54:55 +0800706vppcom_session_shutdown (uint32_t session_handle, int how)
liuyacan534468e2021-05-09 03:50:40 +0000707{
708 vcl_worker_t *wrk = vcl_worker_get_current ();
709 vcl_session_t *session;
710 vcl_session_state_t state;
711 u64 vpp_handle;
712
713 session = vcl_session_get_w_handle (wrk, session_handle);
714 if (PREDICT_FALSE (!session))
715 return VPPCOM_EBADFD;
716
717 vpp_handle = session->vpp_handle;
718 state = session->session_state;
719
720 VDBG (1, "session %u [0x%llx] state 0x%x (%s)", session->session_index,
Florin Coras60687192021-11-29 21:00:47 -0800721 vpp_handle, state, vcl_session_state_str (state));
liuyacan534468e2021-05-09 03:50:40 +0000722
723 if (PREDICT_FALSE (state == VCL_STATE_LISTEN))
724 {
725 VDBG (0, "ERROR: Cannot shutdown a listen socket!");
726 return VPPCOM_EBADFD;
727 }
728
liuyacan55c952e2021-06-13 14:54:55 +0800729 if (how == SHUT_RD || how == SHUT_RDWR)
730 {
731 session->flags |= VCL_SESSION_F_RD_SHUTDOWN;
732 if (how == SHUT_RD)
733 return VPPCOM_OK;
734 }
735 session->flags |= VCL_SESSION_F_WR_SHUTDOWN;
736
liuyacan534468e2021-05-09 03:50:40 +0000737 if (PREDICT_TRUE (state == VCL_STATE_READY))
738 {
739 VDBG (1, "session %u [0x%llx]: sending shutdown...",
740 session->session_index, vpp_handle);
741
742 vcl_send_session_shutdown (wrk, session);
liuyacan534468e2021-05-09 03:50:40 +0000743 }
744
745 return VPPCOM_OK;
746}
747
Florin Coras2bd8b3a2020-10-25 20:28:23 -0700748static int
749vppcom_session_disconnect (u32 session_handle)
750{
751 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras2bd8b3a2020-10-25 20:28:23 -0700752 vcl_session_t *session, *listen_session;
753 vcl_session_state_t state;
754 u64 vpp_handle;
755
756 session = vcl_session_get_w_handle (wrk, session_handle);
757 if (!session)
758 return VPPCOM_EBADFD;
759
760 vpp_handle = session->vpp_handle;
761 state = session->session_state;
762
Florin Coras5ffb9642021-12-03 17:24:13 -0800763 VDBG (1, "session %u [0x%llx]: disconnecting state (%s)",
764 session->session_index, vpp_handle, vcl_session_state_str (state));
Florin Coras2bd8b3a2020-10-25 20:28:23 -0700765
766 if (PREDICT_FALSE (state == VCL_STATE_LISTEN))
767 {
768 VDBG (0, "ERROR: Cannot disconnect a listen socket!");
769 return VPPCOM_EBADFD;
770 }
771
772 if (state == VCL_STATE_VPP_CLOSING)
773 {
Florin Coras52dd29f2020-11-18 19:02:17 -0800774 vcl_send_session_disconnected_reply (wrk, session, 0);
Florin Coras2bd8b3a2020-10-25 20:28:23 -0700775 VDBG (1, "session %u [0x%llx]: sending disconnect REPLY...",
776 session->session_index, vpp_handle);
777 }
778 else
779 {
780 /* Session doesn't have an event queue yet. Probably a non-blocking
781 * connect. Wait for the reply */
782 if (PREDICT_FALSE (!session->vpp_evt_q))
783 return VPPCOM_OK;
784
Florin Coras5ffb9642021-12-03 17:24:13 -0800785 VDBG (1, "session %u [0x%llx]: sending disconnect",
Florin Coras2bd8b3a2020-10-25 20:28:23 -0700786 session->session_index, vpp_handle);
787 vcl_send_session_disconnect (wrk, session);
788 }
789
790 if (session->listener_index != VCL_INVALID_SESSION_INDEX)
791 {
792 listen_session = vcl_session_get (wrk, session->listener_index);
793 listen_session->n_accepted_sessions--;
794 }
795
796 return VPPCOM_OK;
797}
798
Florin Coras30e79c22019-01-02 19:31:22 -0800799static void
Florin Coras9ace36d2019-10-28 13:14:17 -0700800vcl_session_cleanup_handler (vcl_worker_t * wrk, void *data)
801{
802 session_cleanup_msg_t *msg;
803 vcl_session_t *session;
804
805 msg = (session_cleanup_msg_t *) data;
806 session = vcl_session_get_w_vpp_handle (wrk, msg->handle);
807 if (!session)
808 {
Florin Coras5ffb9642021-12-03 17:24:13 -0800809 VWRN ("disconnect confirmed for unknown handle 0x%llx", msg->handle);
Florin Coras9ace36d2019-10-28 13:14:17 -0700810 return;
811 }
812
Florin Coras36d49392020-04-24 23:00:11 +0000813 if (msg->type == SESSION_CLEANUP_TRANSPORT)
814 {
815 /* Transport was cleaned up before we confirmed close. Probably the
816 * app is still waiting for some data that cannot be delivered.
Florin Coras2bd8b3a2020-10-25 20:28:23 -0700817 * Confirm close to make sure everything is cleaned up.
818 * Move to undetermined state to ensure that the session is not
819 * removed before both vpp and the app cleanup.
820 * - If the app closes first, the session is moved to CLOSED state
821 * and the session cleanup notification from vpp removes the
822 * session.
823 * - If vpp cleans up the session first, the session is moved to
824 * DETACHED state lower and subsequently the close from the app
825 * frees the session
826 */
827 if (session->session_state == VCL_STATE_VPP_CLOSING)
Florin Coras0ff7eec2020-08-03 18:55:40 -0700828 {
Florin Coras2bd8b3a2020-10-25 20:28:23 -0700829 vppcom_session_disconnect (vcl_session_handle (session));
830 session->session_state = VCL_STATE_UPDATED;
831 }
832 else if (session->session_state == VCL_STATE_DISCONNECT)
833 {
Florin Coras52dd29f2020-11-18 19:02:17 -0800834 vcl_send_session_reset_reply (wrk, session, 0);
Florin Coras0ff7eec2020-08-03 18:55:40 -0700835 session->session_state = VCL_STATE_UPDATED;
836 }
Florin Coras36d49392020-04-24 23:00:11 +0000837 return;
838 }
839
Florin Corasf0fe1ea2021-12-03 17:03:37 -0800840 /* VPP will reuse the handle so clean it up now */
Florin Coras9ace36d2019-10-28 13:14:17 -0700841 vcl_session_table_del_vpp_handle (wrk, msg->handle);
Florin Corasf0fe1ea2021-12-03 17:03:37 -0800842
843 /* App did not close the connection yet so don't free it. */
Florin Corasc127d5a2020-10-14 16:35:58 -0700844 if (session->session_state != VCL_STATE_CLOSED)
Florin Corasadcfb152020-02-12 08:50:29 +0000845 {
Florin Coras5ffb9642021-12-03 17:24:13 -0800846 VDBG (0, "session %u: app did not close", session->session_index);
Florin Corasc127d5a2020-10-14 16:35:58 -0700847 session->session_state = VCL_STATE_DETACHED;
Florin Corasadcfb152020-02-12 08:50:29 +0000848 session->vpp_handle = VCL_INVALID_SESSION_HANDLE;
849 return;
850 }
Florin Corasf0fe1ea2021-12-03 17:03:37 -0800851
852 /* Session probably tracked with epoll, disconnect not yet handled and
853 * 1) both transport and session cleanup completed 2) app closed. Wait
854 * until message is drained to free the session.
855 * See @ref vcl_handle_mq_event */
856 if (session->flags & VCL_SESSION_F_PENDING_DISCONNECT)
857 {
858 session->flags |= VCL_SESSION_F_PENDING_FREE;
859 return;
860 }
861
Florin Coras9ace36d2019-10-28 13:14:17 -0700862 vcl_session_free (wrk, session);
863}
864
865static void
Florin Coras30e79c22019-01-02 19:31:22 -0800866vcl_session_req_worker_update_handler (vcl_worker_t * wrk, void *data)
867{
868 session_req_worker_update_msg_t *msg;
869 vcl_session_t *s;
870
871 msg = (session_req_worker_update_msg_t *) data;
872 s = vcl_session_get_w_vpp_handle (wrk, msg->session_handle);
873 if (!s)
874 return;
875
876 vec_add1 (wrk->pending_session_wrk_updates, s->session_index);
877}
878
879static void
880vcl_session_worker_update_reply_handler (vcl_worker_t * wrk, void *data)
881{
882 session_worker_update_reply_msg_t *msg;
883 vcl_session_t *s;
884
885 msg = (session_worker_update_reply_msg_t *) data;
886 s = vcl_session_get_w_vpp_handle (wrk, msg->handle);
887 if (!s)
888 {
889 VDBG (0, "unknown handle 0x%llx", msg->handle);
890 return;
891 }
Florin Coras30e79c22019-01-02 19:31:22 -0800892
Florin Coras5f45e012019-01-23 09:21:30 -0800893 if (s->rx_fifo)
894 {
Florin Corasc547e912020-12-08 17:50:45 -0800895 if (vcl_segment_attach_session (msg->segment_handle, msg->rx_fifo,
Florin Corasf6e284b2021-07-21 18:17:20 -0700896 msg->tx_fifo, (uword) ~0, ~0, 0, s))
Florin Corasc547e912020-12-08 17:50:45 -0800897 {
898 VDBG (0, "failed to attach fifos for %u", s->session_index);
899 return;
900 }
Florin Coras5f45e012019-01-23 09:21:30 -0800901 }
Florin Corasc127d5a2020-10-14 16:35:58 -0700902 s->session_state = VCL_STATE_UPDATED;
Florin Coras30e79c22019-01-02 19:31:22 -0800903
Florin Coras30e79c22019-01-02 19:31:22 -0800904 VDBG (0, "session %u[0x%llx] moved to worker %u", s->session_index,
905 s->vpp_handle, wrk->wrk_index);
906}
907
Florin Coras935ce752020-09-08 22:43:47 -0700908static int
909vcl_api_recv_fd (vcl_worker_t * wrk, int *fds, int n_fds)
910{
911
912 if (vcm->cfg.vpp_app_socket_api)
913 return vcl_sapi_recv_fds (wrk, fds, n_fds);
914
915 return vcl_bapi_recv_fds (wrk, fds, n_fds);
916}
917
Florin Corasc4c4cf52019-08-24 18:17:34 -0700918static void
919vcl_session_app_add_segment_handler (vcl_worker_t * wrk, void *data)
920{
921 ssvm_segment_type_t seg_type = SSVM_SEGMENT_SHM;
922 session_app_add_segment_msg_t *msg;
923 u64 segment_handle;
924 int fd = -1;
925
926 msg = (session_app_add_segment_msg_t *) data;
927
928 if (msg->fd_flags)
929 {
Florin Coras935ce752020-09-08 22:43:47 -0700930 vcl_api_recv_fd (wrk, &fd, 1);
Florin Corasc4c4cf52019-08-24 18:17:34 -0700931 seg_type = SSVM_SEGMENT_MEMFD;
932 }
933
934 segment_handle = msg->segment_handle;
935 if (segment_handle == VCL_INVALID_SEGMENT_HANDLE)
936 {
937 clib_warning ("invalid segment handle");
938 return;
939 }
940
941 if (vcl_segment_attach (segment_handle, (char *) msg->segment_name,
942 seg_type, fd))
943 {
944 VDBG (0, "vcl_segment_attach ('%s') failed", msg->segment_name);
945 return;
946 }
947
948 VDBG (1, "mapped new segment '%s' size %d", msg->segment_name,
949 msg->segment_size);
950}
951
952static void
953vcl_session_app_del_segment_handler (vcl_worker_t * wrk, void *data)
954{
955 session_app_del_segment_msg_t *msg = (session_app_del_segment_msg_t *) data;
956 vcl_segment_detach (msg->segment_handle);
957 VDBG (1, "Unmapped segment: %d", msg->segment_handle);
958}
959
Florin Coras40c07ce2020-07-16 20:46:17 -0700960static void
961vcl_worker_rpc_handler (vcl_worker_t * wrk, void *data)
962{
963 if (!vcm->wrk_rpc_fn)
964 return;
965
hanlina3a48962020-07-13 11:09:15 +0800966 (vcm->wrk_rpc_fn) (((session_app_wrk_rpc_msg_t *) data)->data);
Florin Coras40c07ce2020-07-16 20:46:17 -0700967}
968
Florin Coras04ae8272021-04-12 19:55:37 -0700969static void
970vcl_session_transport_attr_reply_handler (vcl_worker_t *wrk, void *data)
971{
972 session_transport_attr_reply_msg_t *mp;
973
974 if (!wrk->session_attr_op)
975 return;
976
977 mp = (session_transport_attr_reply_msg_t *) data;
978
979 wrk->session_attr_op_rv = mp->retval;
980 wrk->session_attr_op = 0;
981 wrk->session_attr_rv = mp->attr;
982}
983
Florin Coras86f04502018-09-12 16:08:01 -0700984static int
985vcl_handle_mq_event (vcl_worker_t * wrk, session_event_t * e)
Florin Coras54693d22018-07-17 10:46:29 -0700986{
Florin Coras54693d22018-07-17 10:46:29 -0700987 session_disconnected_msg_t *disconnected_msg;
Florin Corasb242d312020-10-26 15:35:40 -0700988 session_connected_msg_t *connected_msg;
989 session_reset_msg_t *reset_msg;
990 session_event_t *ecpy;
Florin Corasc127d5a2020-10-14 16:35:58 -0700991 vcl_session_t *s;
Florin Corasb242d312020-10-26 15:35:40 -0700992 u32 sid;
Florin Coras54693d22018-07-17 10:46:29 -0700993
994 switch (e->event_type)
995 {
Florin Coras653e43f2019-03-04 10:56:23 -0800996 case SESSION_IO_EVT_RX:
997 case SESSION_IO_EVT_TX:
Florin Corasc127d5a2020-10-14 16:35:58 -0700998 s = vcl_session_get (wrk, e->session_index);
Florin Coras1bc919e2020-10-18 20:17:49 -0700999 if (!s || !vcl_session_is_open (s))
Florin Coras653e43f2019-03-04 10:56:23 -08001000 break;
Florin Coras86f04502018-09-12 16:08:01 -07001001 vec_add1 (wrk->unhandled_evts_vector, *e);
Florin Coras54693d22018-07-17 10:46:29 -07001002 break;
Florin Corasb242d312020-10-26 15:35:40 -07001003 case SESSION_CTRL_EVT_BOUND:
1004 /* We can only wait for only one listen so not postponed */
1005 vcl_session_bound_handler (wrk, (session_bound_msg_t *) e->data);
1006 break;
Florin Coras54693d22018-07-17 10:46:29 -07001007 case SESSION_CTRL_EVT_ACCEPTED:
Florin Corasb242d312020-10-26 15:35:40 -07001008 s = vcl_session_accepted (wrk, (session_accepted_msg_t *) e->data);
1009 if (vcl_session_has_attr (s, VCL_SESS_ATTR_NONBLOCK))
1010 {
1011 vec_add2 (wrk->unhandled_evts_vector, ecpy, 1);
1012 *ecpy = *e;
1013 ecpy->postponed = 1;
1014 ecpy->session_index = s->session_index;
1015 }
Florin Coras54693d22018-07-17 10:46:29 -07001016 break;
1017 case SESSION_CTRL_EVT_CONNECTED:
Florin Corasb242d312020-10-26 15:35:40 -07001018 connected_msg = (session_connected_msg_t *) e->data;
1019 sid = vcl_session_connected_handler (wrk, connected_msg);
1020 if (!(s = vcl_session_get (wrk, sid)))
1021 break;
1022 if (vcl_session_has_attr (s, VCL_SESS_ATTR_NONBLOCK))
1023 {
1024 vec_add2 (wrk->unhandled_evts_vector, ecpy, 1);
1025 *ecpy = *e;
1026 ecpy->postponed = 1;
1027 ecpy->session_index = s->session_index;
1028 }
Florin Coras54693d22018-07-17 10:46:29 -07001029 break;
1030 case SESSION_CTRL_EVT_DISCONNECTED:
1031 disconnected_msg = (session_disconnected_msg_t *) e->data;
Florin Corasb242d312020-10-26 15:35:40 -07001032 if (!(s = vcl_session_get_w_vpp_handle (wrk, disconnected_msg->handle)))
1033 break;
Florin Corasf0fe1ea2021-12-03 17:03:37 -08001034 if (s->session_state == VCL_STATE_CLOSED)
1035 break;
Florin Corasb242d312020-10-26 15:35:40 -07001036 if (vcl_session_has_attr (s, VCL_SESS_ATTR_NONBLOCK))
1037 {
Florin Corasf0fe1ea2021-12-03 17:03:37 -08001038 s->session_state = VCL_STATE_VPP_CLOSING;
1039 s->flags |= VCL_SESSION_F_PENDING_DISCONNECT;
1040 vec_add2 (wrk->unhandled_evts_vector, ecpy, 1);
1041 *ecpy = *e;
1042 ecpy->postponed = 1;
1043 ecpy->session_index = s->session_index;
Florin Corasb242d312020-10-26 15:35:40 -07001044 break;
1045 }
1046 if (!(s = vcl_session_disconnected_handler (wrk, disconnected_msg)))
Florin Coras3c7d4f92018-12-14 11:28:43 -08001047 break;
Florin Corasc127d5a2020-10-14 16:35:58 -07001048 VDBG (0, "disconnected session %u [0x%llx]", s->session_index,
1049 s->vpp_handle);
Florin Corasc9fbd662018-08-24 12:59:56 -07001050 break;
1051 case SESSION_CTRL_EVT_RESET:
Florin Corasb242d312020-10-26 15:35:40 -07001052 reset_msg = (session_reset_msg_t *) e->data;
1053 if (!(s = vcl_session_get_w_vpp_handle (wrk, reset_msg->handle)))
1054 break;
Florin Corasf0fe1ea2021-12-03 17:03:37 -08001055 if (s->session_state == VCL_STATE_CLOSED)
1056 break;
Florin Corasb242d312020-10-26 15:35:40 -07001057 if (vcl_session_has_attr (s, VCL_SESS_ATTR_NONBLOCK))
1058 {
Florin Corasf0fe1ea2021-12-03 17:03:37 -08001059 s->flags |= VCL_SESSION_F_PENDING_DISCONNECT;
1060 s->session_state = VCL_STATE_DISCONNECT;
1061 vec_add2 (wrk->unhandled_evts_vector, ecpy, 1);
1062 *ecpy = *e;
1063 ecpy->postponed = 1;
1064 ecpy->session_index = s->session_index;
Florin Corasb242d312020-10-26 15:35:40 -07001065 break;
1066 }
Florin Coras134a9962018-08-28 11:32:04 -07001067 vcl_session_reset_handler (wrk, (session_reset_msg_t *) e->data);
Florin Coras60116992018-08-27 09:52:18 -07001068 break;
Florin Corasdfae9f92019-02-20 19:48:31 -08001069 case SESSION_CTRL_EVT_UNLISTEN_REPLY:
1070 vcl_session_unlisten_reply_handler (wrk, e->data);
1071 break;
Florin Coras68b7e582020-01-21 18:33:23 -08001072 case SESSION_CTRL_EVT_MIGRATED:
1073 vcl_session_migrated_handler (wrk, e->data);
1074 break;
Florin Coras9ace36d2019-10-28 13:14:17 -07001075 case SESSION_CTRL_EVT_CLEANUP:
1076 vcl_session_cleanup_handler (wrk, e->data);
1077 break;
Florin Coras30e79c22019-01-02 19:31:22 -08001078 case SESSION_CTRL_EVT_REQ_WORKER_UPDATE:
1079 vcl_session_req_worker_update_handler (wrk, e->data);
1080 break;
1081 case SESSION_CTRL_EVT_WORKER_UPDATE_REPLY:
1082 vcl_session_worker_update_reply_handler (wrk, e->data);
1083 break;
Florin Corasc4c4cf52019-08-24 18:17:34 -07001084 case SESSION_CTRL_EVT_APP_ADD_SEGMENT:
1085 vcl_session_app_add_segment_handler (wrk, e->data);
1086 break;
1087 case SESSION_CTRL_EVT_APP_DEL_SEGMENT:
1088 vcl_session_app_del_segment_handler (wrk, e->data);
1089 break;
hanlina3a48962020-07-13 11:09:15 +08001090 case SESSION_CTRL_EVT_APP_WRK_RPC:
Florin Coras40c07ce2020-07-16 20:46:17 -07001091 vcl_worker_rpc_handler (wrk, e->data);
1092 break;
Florin Coras04ae8272021-04-12 19:55:37 -07001093 case SESSION_CTRL_EVT_TRANSPORT_ATTR_REPLY:
1094 vcl_session_transport_attr_reply_handler (wrk, e->data);
1095 break;
Florin Coras54693d22018-07-17 10:46:29 -07001096 default:
1097 clib_warning ("unhandled %u", e->event_type);
1098 }
1099 return VPPCOM_OK;
1100}
1101
Florin Coras30e79c22019-01-02 19:31:22 -08001102static int
Florin Coras697faea2018-06-27 17:10:49 -07001103vppcom_wait_for_session_state_change (u32 session_index,
Florin Coras288eaab2019-02-03 15:26:14 -08001104 vcl_session_state_t state,
Florin Coras697faea2018-06-27 17:10:49 -07001105 f64 wait_for_time)
1106{
Florin Coras134a9962018-08-28 11:32:04 -07001107 vcl_worker_t *wrk = vcl_worker_get_current ();
1108 f64 timeout = clib_time_now (&wrk->clib_time) + wait_for_time;
Florin Coras697faea2018-06-27 17:10:49 -07001109 vcl_session_t *volatile session;
Florin Coras54693d22018-07-17 10:46:29 -07001110 svm_msg_q_msg_t msg;
1111 session_event_t *e;
Dave Wallace543852a2017-08-03 02:11:34 -04001112
Florin Coras697faea2018-06-27 17:10:49 -07001113 do
Dave Wallace543852a2017-08-03 02:11:34 -04001114 {
Florin Coras134a9962018-08-28 11:32:04 -07001115 session = vcl_session_get (wrk, session_index);
Florin Coras070453d2018-08-24 17:04:27 -07001116 if (PREDICT_FALSE (!session))
Florin Coras697faea2018-06-27 17:10:49 -07001117 {
Florin Coras070453d2018-08-24 17:04:27 -07001118 return VPPCOM_EBADFD;
Florin Coras697faea2018-06-27 17:10:49 -07001119 }
Florin Corasdfffdd72020-10-15 10:54:47 -07001120 if (session->session_state == state)
Florin Coras697faea2018-06-27 17:10:49 -07001121 {
Florin Coras697faea2018-06-27 17:10:49 -07001122 return VPPCOM_OK;
1123 }
Florin Corasc127d5a2020-10-14 16:35:58 -07001124 if (session->session_state == VCL_STATE_DETACHED)
Florin Coras697faea2018-06-27 17:10:49 -07001125 {
Florin Coras697faea2018-06-27 17:10:49 -07001126 return VPPCOM_ECONNREFUSED;
1127 }
Florin Coras54693d22018-07-17 10:46:29 -07001128
Florin Coras134a9962018-08-28 11:32:04 -07001129 if (svm_msg_q_sub (wrk->app_event_queue, &msg, SVM_Q_NOWAIT, 0))
Florin Corasdc2e2512018-12-03 17:47:26 -08001130 {
1131 usleep (100);
1132 continue;
1133 }
Florin Coras134a9962018-08-28 11:32:04 -07001134 e = svm_msg_q_msg_data (wrk->app_event_queue, &msg);
Florin Coras86f04502018-09-12 16:08:01 -07001135 vcl_handle_mq_event (wrk, e);
Florin Coras134a9962018-08-28 11:32:04 -07001136 svm_msg_q_free_msg (wrk->app_event_queue, &msg);
Florin Corasdcf55ce2017-11-16 15:32:50 -08001137 }
Florin Coras134a9962018-08-28 11:32:04 -07001138 while (clib_time_now (&wrk->clib_time) < timeout);
Florin Corasdcf55ce2017-11-16 15:32:50 -08001139
Florin Coras05ecfcc2018-12-12 18:19:39 -08001140 VDBG (0, "timeout waiting for state 0x%x (%s)", state,
Florin Coras60687192021-11-29 21:00:47 -08001141 vcl_session_state_str (state));
Florin Coras697faea2018-06-27 17:10:49 -07001142 vcl_evt (VCL_EVT_SESSION_TIMEOUT, session, session_state);
Dave Wallace543852a2017-08-03 02:11:34 -04001143
Florin Coras697faea2018-06-27 17:10:49 -07001144 return VPPCOM_ETIMEDOUT;
Dave Wallace60caa062017-11-10 17:07:13 -05001145}
1146
Florin Coras30e79c22019-01-02 19:31:22 -08001147static void
1148vcl_handle_pending_wrk_updates (vcl_worker_t * wrk)
1149{
Florin Coras288eaab2019-02-03 15:26:14 -08001150 vcl_session_state_t state;
Florin Coras30e79c22019-01-02 19:31:22 -08001151 vcl_session_t *s;
1152 u32 *sip;
1153
1154 if (PREDICT_TRUE (vec_len (wrk->pending_session_wrk_updates) == 0))
1155 return;
1156
1157 vec_foreach (sip, wrk->pending_session_wrk_updates)
1158 {
1159 s = vcl_session_get (wrk, *sip);
1160 vcl_send_session_worker_update (wrk, s, wrk->wrk_index);
1161 state = s->session_state;
Florin Corasc127d5a2020-10-14 16:35:58 -07001162 vppcom_wait_for_session_state_change (s->session_index, VCL_STATE_UPDATED,
1163 5);
Florin Coras30e79c22019-01-02 19:31:22 -08001164 s->session_state = state;
1165 }
1166 vec_reset_length (wrk->pending_session_wrk_updates);
1167}
1168
Florin Corasf9240dc2019-01-15 08:03:17 -08001169void
Florin Coras5398dfb2021-01-25 20:31:27 -08001170vcl_worker_flush_mq_events (vcl_worker_t *wrk)
Florin Coras30e79c22019-01-02 19:31:22 -08001171{
Florin Coras30e79c22019-01-02 19:31:22 -08001172 svm_msg_q_msg_t *msg;
1173 session_event_t *e;
1174 svm_msg_q_t *mq;
1175 int i;
1176
1177 mq = wrk->app_event_queue;
Florin Corase003a1b2019-06-05 10:47:16 -07001178 vcl_mq_dequeue_batch (wrk, mq, ~0);
Florin Coras30e79c22019-01-02 19:31:22 -08001179
1180 for (i = 0; i < vec_len (wrk->mq_msg_vector); i++)
1181 {
1182 msg = vec_elt_at_index (wrk->mq_msg_vector, i);
1183 e = svm_msg_q_msg_data (mq, msg);
1184 vcl_handle_mq_event (wrk, e);
1185 svm_msg_q_free_msg (mq, msg);
1186 }
1187 vec_reset_length (wrk->mq_msg_vector);
1188 vcl_handle_pending_wrk_updates (wrk);
1189}
1190
Florin Coras5398dfb2021-01-25 20:31:27 -08001191void
1192vcl_flush_mq_events (void)
1193{
1194 vcl_worker_flush_mq_events (vcl_worker_get_current ());
1195}
1196
Florin Coras697faea2018-06-27 17:10:49 -07001197static int
Florin Corasab2f6db2018-08-31 14:31:41 -07001198vppcom_session_unbind (u32 session_handle)
Dave Wallace543852a2017-08-03 02:11:34 -04001199{
Florin Coras134a9962018-08-28 11:32:04 -07001200 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Corasaaff5ee2019-07-08 13:00:00 -07001201 session_accepted_msg_t *accepted_msg;
Florin Coras7e12d942018-06-27 14:32:43 -07001202 vcl_session_t *session = 0;
Florin Corasaaff5ee2019-07-08 13:00:00 -07001203 vcl_session_msg_t *evt;
Dave Wallace543852a2017-08-03 02:11:34 -04001204
Florin Corasab2f6db2018-08-31 14:31:41 -07001205 session = vcl_session_get_w_handle (wrk, session_handle);
Florin Coras070453d2018-08-24 17:04:27 -07001206 if (!session)
1207 return VPPCOM_EBADFD;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001208
Florin Corasaaff5ee2019-07-08 13:00:00 -07001209 /* Flush pending accept events, if any */
1210 while (clib_fifo_elts (session->accept_evts_fifo))
1211 {
1212 clib_fifo_sub2 (session->accept_evts_fifo, evt);
1213 accepted_msg = &evt->accepted_msg;
1214 vcl_session_table_del_vpp_handle (wrk, accepted_msg->handle);
1215 vcl_send_session_accepted_reply (session->vpp_evt_q,
1216 accepted_msg->context,
wanghanlin785b6ea2020-12-10 19:12:22 +08001217 accepted_msg->handle, -1);
Florin Corasaaff5ee2019-07-08 13:00:00 -07001218 }
1219 clib_fifo_free (session->accept_evts_fifo);
1220
Florin Coras458089b2019-08-21 16:20:44 -07001221 vcl_send_session_unlisten (wrk, session);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001222
Florin Coras5e062572019-03-14 19:07:51 -07001223 VDBG (1, "session %u [0x%llx]: sending unbind!", session->session_index,
Florin Coras458089b2019-08-21 16:20:44 -07001224 session->vpp_handle);
Florin Coras0d427d82018-06-27 03:24:07 -07001225 vcl_evt (VCL_EVT_UNBIND, session);
Florin Coras458089b2019-08-21 16:20:44 -07001226
1227 session->vpp_handle = ~0;
Florin Corasc127d5a2020-10-14 16:35:58 -07001228 session->session_state = VCL_STATE_DISCONNECT;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001229
Florin Coras070453d2018-08-24 17:04:27 -07001230 return VPPCOM_OK;
Dave Wallace543852a2017-08-03 02:11:34 -04001231}
1232
Florin Coras940f78f2018-11-30 12:11:20 -08001233/**
1234 * Handle app exit
1235 *
1236 * Notify vpp of the disconnect and mark the worker as free. If we're the
1237 * last worker, do a full cleanup otherwise, since we're probably a forked
1238 * child, avoid syscalls as much as possible. We might've lost privileges.
1239 */
1240void
1241vppcom_app_exit (void)
1242{
1243 if (!pool_elts (vcm->workers))
1244 return;
Florin Coras01f3f892018-12-02 12:45:53 -08001245 vcl_worker_cleanup (vcl_worker_get_current (), 1 /* notify vpp */ );
1246 vcl_set_worker_index (~0);
Florin Coras940f78f2018-11-30 12:11:20 -08001247 vcl_elog_stop (vcm);
Florin Coras940f78f2018-11-30 12:11:20 -08001248}
1249
Florin Coras935ce752020-09-08 22:43:47 -07001250static int
1251vcl_api_attach (void)
1252{
1253 if (vcm->cfg.vpp_app_socket_api)
1254 return vcl_sapi_attach ();
1255
1256 return vcl_bapi_attach ();
1257}
1258
1259static void
Filip Tehlar8ccc6b32022-02-02 17:38:20 +00001260vcl_api_retry_attach (vcl_worker_t *wrk)
1261{
1262 vcl_session_t *s;
1263
1264 if (vcl_api_attach ())
1265 return;
1266
1267 /* Treat listeners as configuration that needs to be re-added to vpp */
1268 pool_foreach (s, wrk->sessions)
1269 {
1270 if (s->flags & VCL_SESSION_F_IS_VEP)
1271 continue;
1272 if (s->session_state == VCL_STATE_LISTEN_NO_MQ)
1273 vppcom_session_listen (vcl_session_handle (s), 10);
1274 else
1275 VDBG (0, "internal error: unexpected state %d", s->session_state);
1276 }
1277}
1278
1279static void
1280vcl_api_handle_disconnect (vcl_worker_t *wrk)
1281{
1282 wrk->api_client_handle = ~0;
1283 vcl_worker_detach_sessions (wrk);
1284}
1285
1286static void
Florin Coras935ce752020-09-08 22:43:47 -07001287vcl_api_detach (vcl_worker_t * wrk)
1288{
Florin Corasd04ea442022-03-30 16:08:25 -07001289 if (wrk->api_client_handle == ~0)
1290 return;
1291
Florin Coras935ce752020-09-08 22:43:47 -07001292 vcl_send_app_detach (wrk);
1293
1294 if (vcm->cfg.vpp_app_socket_api)
1295 return vcl_sapi_detach (wrk);
1296
1297 return vcl_bapi_disconnect_from_vpp ();
1298}
1299
Dave Wallace543852a2017-08-03 02:11:34 -04001300/*
1301 * VPPCOM Public API functions
1302 */
1303int
Florin Coras66ec4672020-06-15 07:59:40 -07001304vppcom_app_create (const char *app_name)
Dave Wallace543852a2017-08-03 02:11:34 -04001305{
Dave Wallace543852a2017-08-03 02:11:34 -04001306 vppcom_cfg_t *vcl_cfg = &vcm->cfg;
Dave Wallace543852a2017-08-03 02:11:34 -04001307 int rv;
1308
Florin Coras47c40e22018-11-26 17:01:36 -08001309 if (vcm->is_init)
Dave Wallace543852a2017-08-03 02:11:34 -04001310 {
Florin Coras955bfbb2018-12-04 13:43:45 -08001311 VDBG (1, "already initialized");
1312 return VPPCOM_EEXIST;
Dave Wallace543852a2017-08-03 02:11:34 -04001313 }
1314
Florin Coras47c40e22018-11-26 17:01:36 -08001315 vcm->is_init = 1;
1316 vppcom_cfg (&vcm->cfg);
1317 vcl_cfg = &vcm->cfg;
1318
1319 vcm->main_cpu = pthread_self ();
1320 vcm->main_pid = getpid ();
1321 vcm->app_name = format (0, "%s", app_name);
Florin Coras41bc8612021-10-01 14:57:03 -07001322 fifo_segment_main_init (&vcm->segment_main, (uword) ~0,
1323 20 /* timeout in secs */);
Florin Coras47c40e22018-11-26 17:01:36 -08001324 pool_alloc (vcm->workers, vcl_cfg->max_workers);
1325 clib_spinlock_init (&vcm->workers_lock);
Florin Corasd85de682018-11-29 17:02:29 -08001326 clib_rwlock_init (&vcm->segment_table_lock);
Florin Coras940f78f2018-11-30 12:11:20 -08001327 atexit (vppcom_app_exit);
Florin Corasb88de902020-09-08 16:47:57 -07001328 vcl_elog_init (vcm);
Florin Coras47c40e22018-11-26 17:01:36 -08001329
1330 /* Allocate default worker */
1331 vcl_worker_alloc_and_init ();
1332
Florin Coras935ce752020-09-08 22:43:47 -07001333 if ((rv = vcl_api_attach ()))
Florin Corasd04ea442022-03-30 16:08:25 -07001334 {
1335 vppcom_app_destroy ();
1336 return rv;
1337 }
Florin Coras47c40e22018-11-26 17:01:36 -08001338
1339 VDBG (0, "app_name '%s', my_client_index %d (0x%x)", app_name,
Florin Corascc7c88e2020-09-15 15:56:51 -07001340 vcm->workers[0].api_client_handle, vcm->workers[0].api_client_handle);
Dave Wallace543852a2017-08-03 02:11:34 -04001341
1342 return VPPCOM_OK;
1343}
1344
1345void
1346vppcom_app_destroy (void)
1347{
Florin Corasdc0ded72020-04-30 02:59:55 +00001348 vcl_worker_t *wrk, *current_wrk;
Damjan Marion4537c302020-09-28 19:03:37 +02001349 void *heap;
Dave Wallace543852a2017-08-03 02:11:34 -04001350
Florin Coras940f78f2018-11-30 12:11:20 -08001351 if (!pool_elts (vcm->workers))
1352 return;
1353
Florin Coras0d427d82018-06-27 03:24:07 -07001354 vcl_evt (VCL_EVT_DETACH, vcm);
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -08001355
Florin Corasdc0ded72020-04-30 02:59:55 +00001356 current_wrk = vcl_worker_get_current ();
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -08001357
Florin Corasce815de2020-04-16 18:47:27 +00001358 /* *INDENT-OFF* */
Damjan Marionb2c31b62020-12-13 21:47:40 +01001359 pool_foreach (wrk, vcm->workers) {
Florin Corasdc0ded72020-04-30 02:59:55 +00001360 if (current_wrk != wrk)
1361 vcl_worker_cleanup (wrk, 0 /* notify vpp */ );
Damjan Marionb2c31b62020-12-13 21:47:40 +01001362 }
Florin Corasce815de2020-04-16 18:47:27 +00001363 /* *INDENT-ON* */
1364
Florin Coras935ce752020-09-08 22:43:47 -07001365 vcl_api_detach (current_wrk);
Florin Corasdc0ded72020-04-30 02:59:55 +00001366 vcl_worker_cleanup (current_wrk, 0 /* notify vpp */ );
Florin Corasd04ea442022-03-30 16:08:25 -07001367 vcl_set_worker_index (~0);
Florin Corasdc0ded72020-04-30 02:59:55 +00001368
Florin Coras0d427d82018-06-27 03:24:07 -07001369 vcl_elog_stop (vcm);
Florin Corasce815de2020-04-16 18:47:27 +00001370
1371 /*
1372 * Free the heap and fix vcm
1373 */
1374 heap = clib_mem_get_heap ();
Damjan Marion4537c302020-09-28 19:03:37 +02001375 munmap (clib_mem_get_heap_base (heap), clib_mem_get_heap_size (heap));
Florin Corasce815de2020-04-16 18:47:27 +00001376
1377 vcm = &_vppcom_main;
Florin Coras69d97252020-05-11 17:19:31 +00001378 vcm->is_init = 0;
Dave Wallace543852a2017-08-03 02:11:34 -04001379}
1380
1381int
Dave Wallacec04cbf12018-02-07 18:14:02 -05001382vppcom_session_create (u8 proto, u8 is_nonblocking)
Dave Wallace543852a2017-08-03 02:11:34 -04001383{
Florin Coras134a9962018-08-28 11:32:04 -07001384 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras7e12d942018-06-27 14:32:43 -07001385 vcl_session_t *session;
Dave Wallace543852a2017-08-03 02:11:34 -04001386
Florin Coras134a9962018-08-28 11:32:04 -07001387 session = vcl_session_alloc (wrk);
Dave Wallace543852a2017-08-03 02:11:34 -04001388
Florin Coras7e12d942018-06-27 14:32:43 -07001389 session->session_type = proto;
Florin Corasc127d5a2020-10-14 16:35:58 -07001390 session->session_state = VCL_STATE_CLOSED;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001391 session->vpp_handle = ~0;
Nathan Skrzypczak9fd99622019-05-16 14:38:44 +02001392 session->is_dgram = vcl_proto_is_dgram (proto);
Dave Wallace543852a2017-08-03 02:11:34 -04001393
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001394 if (is_nonblocking)
Florin Corasac422d62020-10-19 20:51:36 -07001395 vcl_session_set_attr (session, VCL_SESS_ATTR_NONBLOCK);
Dave Wallace543852a2017-08-03 02:11:34 -04001396
Florin Coras7e12d942018-06-27 14:32:43 -07001397 vcl_evt (VCL_EVT_CREATE, session, session_type, session->session_state,
1398 is_nonblocking, session_index);
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08001399
Florin Coras5e062572019-03-14 19:07:51 -07001400 VDBG (0, "created session %u", session->session_index);
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08001401
Florin Coras134a9962018-08-28 11:32:04 -07001402 return vcl_session_handle (session);
Dave Wallace543852a2017-08-03 02:11:34 -04001403}
1404
Florin Corasfe286f72021-06-04 10:07:55 -07001405static void
Florin Corasfa3884f2021-06-22 20:04:46 -07001406vcl_epoll_lt_add (vcl_worker_t *wrk, vcl_session_t *s)
Florin Corasfe286f72021-06-04 10:07:55 -07001407{
Florin Corasfa3884f2021-06-22 20:04:46 -07001408 vcl_session_t *cur, *prev;
Florin Corasfe286f72021-06-04 10:07:55 -07001409
Florin Corasfa3884f2021-06-22 20:04:46 -07001410 if (wrk->ep_lt_current == VCL_INVALID_SESSION_INDEX)
Florin Corasfe286f72021-06-04 10:07:55 -07001411 {
Florin Corasfa3884f2021-06-22 20:04:46 -07001412 wrk->ep_lt_current = s->session_index;
1413 s->vep.lt_next = s->session_index;
1414 s->vep.lt_prev = s->session_index;
1415 return;
Florin Corasfe286f72021-06-04 10:07:55 -07001416 }
Florin Corasfa3884f2021-06-22 20:04:46 -07001417
1418 cur = vcl_session_get (wrk, wrk->ep_lt_current);
1419 prev = vcl_session_get (wrk, cur->vep.lt_prev);
1420
1421 prev->vep.lt_next = s->session_index;
1422 s->vep.lt_prev = prev->session_index;
1423
1424 s->vep.lt_next = cur->session_index;
1425 cur->vep.lt_prev = s->session_index;
1426}
1427
1428static void
1429vcl_epoll_lt_del (vcl_worker_t *wrk, vcl_session_t *s)
1430{
1431 vcl_session_t *prev, *next;
1432
1433 if (s->vep.lt_next == s->session_index)
1434 {
1435 wrk->ep_lt_current = VCL_INVALID_SESSION_INDEX;
1436 s->vep.lt_next = VCL_INVALID_SESSION_INDEX;
1437 return;
1438 }
1439
1440 prev = vcl_session_get (wrk, s->vep.lt_prev);
1441 next = vcl_session_get (wrk, s->vep.lt_next);
1442
1443 prev->vep.lt_next = next->session_index;
1444 next->vep.lt_prev = prev->session_index;
1445
1446 if (s->session_index == wrk->ep_lt_current)
1447 wrk->ep_lt_current = s->vep.lt_next;
1448
1449 s->vep.lt_next = VCL_INVALID_SESSION_INDEX;
Florin Corasfe286f72021-06-04 10:07:55 -07001450}
1451
Dave Wallace543852a2017-08-03 02:11:34 -04001452int
Florin Corasc127d5a2020-10-14 16:35:58 -07001453vcl_session_cleanup (vcl_worker_t * wrk, vcl_session_t * s,
Florin Corasf9240dc2019-01-15 08:03:17 -08001454 vcl_session_handle_t sh, u8 do_disconnect)
Dave Wallace543852a2017-08-03 02:11:34 -04001455{
Florin Coras134a9962018-08-28 11:32:04 -07001456 int rv = VPPCOM_OK;
Florin Coras47c40e22018-11-26 17:01:36 -08001457
Florin Coras6c3b2182020-10-19 18:36:48 -07001458 VDBG (1, "session %u [0x%llx] closing", s->session_index, s->vpp_handle);
Dave Wallace543852a2017-08-03 02:11:34 -04001459
Florin Coras6c3b2182020-10-19 18:36:48 -07001460 if (s->flags & VCL_SESSION_F_IS_VEP)
Dave Wallace543852a2017-08-03 02:11:34 -04001461 {
Florin Coras6c3b2182020-10-19 18:36:48 -07001462 u32 next_sh = s->vep.next_sh;
Florin Coras134a9962018-08-28 11:32:04 -07001463 while (next_sh != ~0)
Dave Wallace19481612017-09-15 18:47:44 -04001464 {
Florin Corasf9240dc2019-01-15 08:03:17 -08001465 rv = vppcom_epoll_ctl (sh, EPOLL_CTL_DEL, next_sh, 0);
Florin Coras0d427d82018-06-27 03:24:07 -07001466 if (PREDICT_FALSE (rv < 0))
Florin Coras5e062572019-03-14 19:07:51 -07001467 VDBG (0, "vpp handle 0x%llx, sh %u: EPOLL_CTL_DEL vep_idx %u"
Florin Coras6c3b2182020-10-19 18:36:48 -07001468 " failed! rv %d (%s)", s->vpp_handle, next_sh,
1469 s->vep.vep_sh, rv, vppcom_retval_str (rv));
Florin Corasc127d5a2020-10-14 16:35:58 -07001470 next_sh = s->vep.next_sh;
Dave Wallacef7f809c2017-10-03 01:48:42 -04001471 }
Florin Corase4306b62020-10-28 12:51:10 -07001472 goto free_session;
Dave Wallacef7f809c2017-10-03 01:48:42 -04001473 }
Florin Coras9ace36d2019-10-28 13:14:17 -07001474
Florin Coras6c3b2182020-10-19 18:36:48 -07001475 if (s->flags & VCL_SESSION_F_IS_VEP_SESSION)
Dave Wallacef7f809c2017-10-03 01:48:42 -04001476 {
Florin Coras6c3b2182020-10-19 18:36:48 -07001477 rv = vppcom_epoll_ctl (s->vep.vep_sh, EPOLL_CTL_DEL, sh, 0);
Florin Coras9ace36d2019-10-28 13:14:17 -07001478 if (rv < 0)
1479 VDBG (0, "session %u [0x%llx]: EPOLL_CTL_DEL vep_idx %u "
Florin Coras6c3b2182020-10-19 18:36:48 -07001480 "failed! rv %d (%s)", s->session_index, s->vpp_handle,
1481 s->vep.vep_sh, rv, vppcom_retval_str (rv));
Dave Wallace19481612017-09-15 18:47:44 -04001482 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05001483
Florin Coras9ace36d2019-10-28 13:14:17 -07001484 if (!do_disconnect)
1485 {
1486 VDBG (1, "session %u [0x%llx] disconnect skipped",
Florin Coras6c3b2182020-10-19 18:36:48 -07001487 s->session_index, s->vpp_handle);
Florin Coras9ace36d2019-10-28 13:14:17 -07001488 goto cleanup;
1489 }
1490
Florin Coras6c3b2182020-10-19 18:36:48 -07001491 if (s->session_state == VCL_STATE_LISTEN)
Florin Coras9ace36d2019-10-28 13:14:17 -07001492 {
1493 rv = vppcom_session_unbind (sh);
1494 if (PREDICT_FALSE (rv < 0))
1495 VDBG (0, "session %u [0x%llx]: listener unbind failed! "
Florin Coras6c3b2182020-10-19 18:36:48 -07001496 "rv %d (%s)", s->session_index, s->vpp_handle, rv,
Florin Coras9ace36d2019-10-28 13:14:17 -07001497 vppcom_retval_str (rv));
1498 return rv;
1499 }
Florin Coras1bc919e2020-10-18 20:17:49 -07001500 else if (vcl_session_is_ready (s)
Florin Corasc127d5a2020-10-14 16:35:58 -07001501 || (vcl_session_is_connectable_listener (wrk, s)))
Florin Coras9ace36d2019-10-28 13:14:17 -07001502 {
1503 rv = vppcom_session_disconnect (sh);
1504 if (PREDICT_FALSE (rv < 0))
1505 VDBG (0, "ERROR: session %u [0x%llx]: disconnect failed!"
Florin Coras6c3b2182020-10-19 18:36:48 -07001506 " rv %d (%s)", s->session_index, s->vpp_handle,
Florin Coras9ace36d2019-10-28 13:14:17 -07001507 rv, vppcom_retval_str (rv));
1508 }
Florin Coras6c3b2182020-10-19 18:36:48 -07001509 else if (s->session_state == VCL_STATE_DISCONNECT)
Florin Coras9ace36d2019-10-28 13:14:17 -07001510 {
Florin Coras52dd29f2020-11-18 19:02:17 -08001511 vcl_send_session_reset_reply (wrk, s, 0);
Florin Coras9ace36d2019-10-28 13:14:17 -07001512 }
Florin Coras6c3b2182020-10-19 18:36:48 -07001513 else if (s->session_state == VCL_STATE_DETACHED)
Florin Corasadcfb152020-02-12 08:50:29 +00001514 {
Florin Corasc127d5a2020-10-14 16:35:58 -07001515 VDBG (0, "vpp freed session %d before close", s->session_index);
Florin Corasf0fe1ea2021-12-03 17:03:37 -08001516
1517 if (!(s->flags & VCL_SESSION_F_PENDING_DISCONNECT))
1518 goto free_session;
1519
1520 /* Disconnect/reset messages pending but vpp transport and session
1521 * cleanups already done. Free only after messages drained. */
1522 s->flags |= VCL_SESSION_F_PENDING_FREE;
Florin Corasadcfb152020-02-12 08:50:29 +00001523 }
Florin Coras9ace36d2019-10-28 13:14:17 -07001524
Florin Corasc127d5a2020-10-14 16:35:58 -07001525 s->session_state = VCL_STATE_CLOSED;
Florin Coras54140622020-02-04 19:04:34 +00001526
Florin Coras9ace36d2019-10-28 13:14:17 -07001527 /* Session is removed only after vpp confirms the disconnect */
1528 return rv;
Florin Coras0ef8ef22019-01-18 08:37:13 -08001529
Florin Corasf9240dc2019-01-15 08:03:17 -08001530cleanup:
Florin Coras6c3b2182020-10-19 18:36:48 -07001531 vcl_session_table_del_vpp_handle (wrk, s->vpp_handle);
Florin Corasadcfb152020-02-12 08:50:29 +00001532free_session:
Florin Corasc127d5a2020-10-14 16:35:58 -07001533 vcl_session_free (wrk, s);
1534 vcl_evt (VCL_EVT_CLOSE, s, rv);
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08001535
Dave Wallace543852a2017-08-03 02:11:34 -04001536 return rv;
1537}
1538
1539int
Florin Corasf9240dc2019-01-15 08:03:17 -08001540vppcom_session_close (uint32_t session_handle)
1541{
1542 vcl_worker_t *wrk = vcl_worker_get_current ();
1543 vcl_session_t *session;
1544
1545 session = vcl_session_get_w_handle (wrk, session_handle);
1546 if (!session)
1547 return VPPCOM_EBADFD;
1548 return vcl_session_cleanup (wrk, session, session_handle,
1549 1 /* do_disconnect */ );
1550}
1551
1552int
Florin Coras134a9962018-08-28 11:32:04 -07001553vppcom_session_bind (uint32_t session_handle, vppcom_endpt_t * ep)
Dave Wallace543852a2017-08-03 02:11:34 -04001554{
Florin Coras134a9962018-08-28 11:32:04 -07001555 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras7e12d942018-06-27 14:32:43 -07001556 vcl_session_t *session = 0;
Dave Wallace543852a2017-08-03 02:11:34 -04001557
1558 if (!ep || !ep->ip)
1559 return VPPCOM_EINVAL;
1560
Florin Coras134a9962018-08-28 11:32:04 -07001561 session = vcl_session_get_w_handle (wrk, session_handle);
Florin Coras070453d2018-08-24 17:04:27 -07001562 if (!session)
1563 return VPPCOM_EBADFD;
Dave Wallace543852a2017-08-03 02:11:34 -04001564
Florin Coras6c3b2182020-10-19 18:36:48 -07001565 if (session->flags & VCL_SESSION_F_IS_VEP)
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001566 {
Florin Coras5e062572019-03-14 19:07:51 -07001567 VDBG (0, "ERROR: cannot bind to epoll session %u!",
1568 session->session_index);
Florin Coras070453d2018-08-24 17:04:27 -07001569 return VPPCOM_EBADFD;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001570 }
1571
Florin Coras7e12d942018-06-27 14:32:43 -07001572 session->transport.is_ip4 = ep->is_ip4;
Florin Coras54693d22018-07-17 10:46:29 -07001573 if (ep->is_ip4)
Dave Barach178cf492018-11-13 16:34:13 -05001574 clib_memcpy_fast (&session->transport.lcl_ip.ip4, ep->ip,
1575 sizeof (ip4_address_t));
Florin Coras54693d22018-07-17 10:46:29 -07001576 else
Dave Barach178cf492018-11-13 16:34:13 -05001577 clib_memcpy_fast (&session->transport.lcl_ip.ip6, ep->ip,
1578 sizeof (ip6_address_t));
Florin Coras7e12d942018-06-27 14:32:43 -07001579 session->transport.lcl_port = ep->port;
Stevenac1f96d2017-10-24 16:03:58 -07001580
Florin Coras60687192021-11-29 21:00:47 -08001581 VDBG (0,
1582 "session %u handle %u: binding to local %s address %U port %u, "
1583 "proto %s",
1584 session->session_index, session_handle,
1585 session->transport.is_ip4 ? "IPv4" : "IPv6", vcl_format_ip46_address,
1586 &session->transport.lcl_ip,
Florin Coras7e12d942018-06-27 14:32:43 -07001587 session->transport.is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6,
1588 clib_net_to_host_u16 (session->transport.lcl_port),
Ping Yu34a3a082018-11-30 19:16:17 -05001589 vppcom_proto_str (session->session_type));
Florin Coras0d427d82018-06-27 03:24:07 -07001590 vcl_evt (VCL_EVT_BIND, session);
Florin Coras460dce62018-07-27 05:45:06 -07001591
1592 if (session->session_type == VPPCOM_PROTO_UDP)
Florin Coras134a9962018-08-28 11:32:04 -07001593 vppcom_session_listen (session_handle, 10);
Florin Coras460dce62018-07-27 05:45:06 -07001594
Florin Coras070453d2018-08-24 17:04:27 -07001595 return VPPCOM_OK;
Dave Wallace543852a2017-08-03 02:11:34 -04001596}
1597
1598int
Florin Coras134a9962018-08-28 11:32:04 -07001599vppcom_session_listen (uint32_t listen_sh, uint32_t q_len)
Dave Wallace543852a2017-08-03 02:11:34 -04001600{
Florin Coras134a9962018-08-28 11:32:04 -07001601 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras7e12d942018-06-27 14:32:43 -07001602 vcl_session_t *listen_session = 0;
Dave Wallaceee45d412017-11-24 21:44:06 -05001603 u64 listen_vpp_handle;
Florin Coras070453d2018-08-24 17:04:27 -07001604 int rv;
1605
Florin Coras134a9962018-08-28 11:32:04 -07001606 listen_session = vcl_session_get_w_handle (wrk, listen_sh);
Florin Coras6c3b2182020-10-19 18:36:48 -07001607 if (!listen_session || (listen_session->flags & VCL_SESSION_F_IS_VEP))
Florin Coras070453d2018-08-24 17:04:27 -07001608 return VPPCOM_EBADFD;
Dave Wallace543852a2017-08-03 02:11:34 -04001609
Dave Wallaceee45d412017-11-24 21:44:06 -05001610 listen_vpp_handle = listen_session->vpp_handle;
Florin Corasc127d5a2020-10-14 16:35:58 -07001611 if (listen_session->session_state == VCL_STATE_LISTEN)
Dave Wallacee695cb42017-11-02 22:04:42 -04001612 {
Florin Coras05ecfcc2018-12-12 18:19:39 -08001613 VDBG (0, "session %u [0x%llx]: already in listen state!",
1614 listen_sh, listen_vpp_handle);
Florin Coras070453d2018-08-24 17:04:27 -07001615 return VPPCOM_OK;
Dave Wallacee695cb42017-11-02 22:04:42 -04001616 }
1617
Nathan Skrzypczak9fd99622019-05-16 14:38:44 +02001618 VDBG (0, "session %u: sending vpp listen request...", listen_sh);
Dave Wallace543852a2017-08-03 02:11:34 -04001619
Florin Coras070453d2018-08-24 17:04:27 -07001620 /*
1621 * Send listen request to vpp and wait for reply
1622 */
Florin Coras458089b2019-08-21 16:20:44 -07001623 vcl_send_session_listen (wrk, listen_session);
Florin Coras134a9962018-08-28 11:32:04 -07001624 rv = vppcom_wait_for_session_state_change (listen_session->session_index,
Florin Corasc127d5a2020-10-14 16:35:58 -07001625 VCL_STATE_LISTEN,
Florin Coras134a9962018-08-28 11:32:04 -07001626 vcm->cfg.session_timeout);
Dave Wallace543852a2017-08-03 02:11:34 -04001627
Florin Coras070453d2018-08-24 17:04:27 -07001628 if (PREDICT_FALSE (rv))
Dave Wallaceee45d412017-11-24 21:44:06 -05001629 {
Florin Coras134a9962018-08-28 11:32:04 -07001630 listen_session = vcl_session_get_w_handle (wrk, listen_sh);
Florin Coras05ecfcc2018-12-12 18:19:39 -08001631 VDBG (0, "session %u [0x%llx]: listen failed! returning %d (%s)",
1632 listen_sh, listen_session->vpp_handle, rv,
1633 vppcom_retval_str (rv));
Florin Coras070453d2018-08-24 17:04:27 -07001634 return rv;
Dave Wallaceee45d412017-11-24 21:44:06 -05001635 }
1636
Florin Coras070453d2018-08-24 17:04:27 -07001637 return VPPCOM_OK;
Keith Burns (alagalah)0d2b0d52018-03-06 15:55:22 -08001638}
1639
Florin Coras134a9962018-08-28 11:32:04 -07001640static int
Florin Coras5e062572019-03-14 19:07:51 -07001641validate_args_session_accept_ (vcl_worker_t * wrk, vcl_session_t * ls)
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001642{
Florin Coras6c3b2182020-10-19 18:36:48 -07001643 if (ls->flags & VCL_SESSION_F_IS_VEP)
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001644 {
Florin Coras5e062572019-03-14 19:07:51 -07001645 VDBG (0, "ERROR: cannot accept on epoll session %u!",
1646 ls->session_index);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001647 return VPPCOM_EBADFD;
1648 }
1649
Florin Corasc127d5a2020-10-14 16:35:58 -07001650 if ((ls->session_state != VCL_STATE_LISTEN)
Nathan Skrzypczak9fd99622019-05-16 14:38:44 +02001651 && (!vcl_session_is_connectable_listener (wrk, ls)))
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001652 {
Florin Coras60687192021-11-29 21:00:47 -08001653 VDBG (0,
1654 "ERROR: session [0x%llx]: not in listen state! state 0x%x"
1655 " (%s)",
1656 ls->vpp_handle, ls->session_state,
1657 vcl_session_state_str (ls->session_state));
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001658 return VPPCOM_EBADFD;
1659 }
1660 return VPPCOM_OK;
1661}
1662
1663int
Nathan Skrzypczak9fd99622019-05-16 14:38:44 +02001664vppcom_unformat_proto (uint8_t * proto, char *proto_str)
1665{
1666 if (!strcmp (proto_str, "TCP"))
1667 *proto = VPPCOM_PROTO_TCP;
1668 else if (!strcmp (proto_str, "tcp"))
1669 *proto = VPPCOM_PROTO_TCP;
1670 else if (!strcmp (proto_str, "UDP"))
1671 *proto = VPPCOM_PROTO_UDP;
1672 else if (!strcmp (proto_str, "udp"))
1673 *proto = VPPCOM_PROTO_UDP;
Nathan Skrzypczak9fd99622019-05-16 14:38:44 +02001674 else if (!strcmp (proto_str, "TLS"))
1675 *proto = VPPCOM_PROTO_TLS;
1676 else if (!strcmp (proto_str, "tls"))
1677 *proto = VPPCOM_PROTO_TLS;
1678 else if (!strcmp (proto_str, "QUIC"))
1679 *proto = VPPCOM_PROTO_QUIC;
1680 else if (!strcmp (proto_str, "quic"))
1681 *proto = VPPCOM_PROTO_QUIC;
Florin Coras4b47ee22020-11-19 13:38:26 -08001682 else if (!strcmp (proto_str, "DTLS"))
1683 *proto = VPPCOM_PROTO_DTLS;
1684 else if (!strcmp (proto_str, "dtls"))
1685 *proto = VPPCOM_PROTO_DTLS;
Florin Coras6621abf2021-01-06 17:35:17 -08001686 else if (!strcmp (proto_str, "SRTP"))
1687 *proto = VPPCOM_PROTO_SRTP;
1688 else if (!strcmp (proto_str, "srtp"))
1689 *proto = VPPCOM_PROTO_SRTP;
Nathan Skrzypczak9fd99622019-05-16 14:38:44 +02001690 else
1691 return 1;
1692 return 0;
1693}
1694
1695int
Florin Coras134a9962018-08-28 11:32:04 -07001696vppcom_session_accept (uint32_t listen_session_handle, vppcom_endpt_t * ep,
Dave Wallace048b1d62018-01-03 22:24:41 -05001697 uint32_t flags)
Dave Wallace543852a2017-08-03 02:11:34 -04001698{
Florin Coras3c7d4f92018-12-14 11:28:43 -08001699 u32 client_session_index = ~0, listen_session_index, accept_flags = 0;
Florin Coras134a9962018-08-28 11:32:04 -07001700 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras54693d22018-07-17 10:46:29 -07001701 session_accepted_msg_t accepted_msg;
Florin Coras7e12d942018-06-27 14:32:43 -07001702 vcl_session_t *listen_session = 0;
1703 vcl_session_t *client_session = 0;
Florin Coras54693d22018-07-17 10:46:29 -07001704 vcl_session_msg_t *evt;
Florin Coras54693d22018-07-17 10:46:29 -07001705 u8 is_nonblocking;
1706 int rv;
Dave Wallace543852a2017-08-03 02:11:34 -04001707
Florin Coras5398dfb2021-01-25 20:31:27 -08001708again:
1709
Florin Coras134a9962018-08-28 11:32:04 -07001710 listen_session = vcl_session_get_w_handle (wrk, listen_session_handle);
Florin Coras070453d2018-08-24 17:04:27 -07001711 if (!listen_session)
1712 return VPPCOM_EBADFD;
Dave Wallace543852a2017-08-03 02:11:34 -04001713
Florin Coras134a9962018-08-28 11:32:04 -07001714 listen_session_index = listen_session->session_index;
1715 if ((rv = validate_args_session_accept_ (wrk, listen_session)))
Florin Coras070453d2018-08-24 17:04:27 -07001716 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04001717
Florin Coras54693d22018-07-17 10:46:29 -07001718 if (clib_fifo_elts (listen_session->accept_evts_fifo))
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001719 {
Florin Coras54693d22018-07-17 10:46:29 -07001720 clib_fifo_sub2 (listen_session->accept_evts_fifo, evt);
Florin Coras3c7d4f92018-12-14 11:28:43 -08001721 accept_flags = evt->flags;
Florin Coras54693d22018-07-17 10:46:29 -07001722 accepted_msg = evt->accepted_msg;
1723 goto handle;
1724 }
1725
Florin Corasac422d62020-10-19 20:51:36 -07001726 is_nonblocking = vcl_session_has_attr (listen_session,
1727 VCL_SESS_ATTR_NONBLOCK);
Florin Coras54693d22018-07-17 10:46:29 -07001728 while (1)
1729 {
Carl Smith592a9092019-11-12 14:57:37 +13001730 if (svm_msg_q_is_empty (wrk->app_event_queue) && is_nonblocking)
1731 return VPPCOM_EAGAIN;
1732
Florin Coras5398dfb2021-01-25 20:31:27 -08001733 svm_msg_q_wait (wrk->app_event_queue, SVM_MQ_WAIT_EMPTY);
1734 vcl_worker_flush_mq_events (wrk);
1735 goto again;
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001736 }
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001737
Florin Coras54693d22018-07-17 10:46:29 -07001738handle:
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08001739
Florin Coras00cca802019-06-06 09:38:44 -07001740 client_session_index = vcl_session_accepted_handler (wrk, &accepted_msg,
1741 listen_session_index);
1742 if (client_session_index == VCL_INVALID_SESSION_INDEX)
1743 return VPPCOM_ECONNABORTED;
1744
Florin Coras134a9962018-08-28 11:32:04 -07001745 listen_session = vcl_session_get (wrk, listen_session_index);
1746 client_session = vcl_session_get (wrk, client_session_index);
Dave Wallace543852a2017-08-03 02:11:34 -04001747
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001748 if (flags & O_NONBLOCK)
Florin Corasac422d62020-10-19 20:51:36 -07001749 vcl_session_set_attr (client_session, VCL_SESS_ATTR_NONBLOCK);
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001750
Florin Coras5e062572019-03-14 19:07:51 -07001751 VDBG (1, "listener %u [0x%llx]: Got a connect request! session %u [0x%llx],"
1752 " flags %d, is_nonblocking %u", listen_session->session_index,
1753 listen_session->vpp_handle, client_session_index,
1754 client_session->vpp_handle, flags,
Florin Corasac422d62020-10-19 20:51:36 -07001755 vcl_session_has_attr (client_session, VCL_SESS_ATTR_NONBLOCK));
Dave Wallace543852a2017-08-03 02:11:34 -04001756
Dave Wallace048b1d62018-01-03 22:24:41 -05001757 if (ep)
1758 {
Florin Coras7e12d942018-06-27 14:32:43 -07001759 ep->is_ip4 = client_session->transport.is_ip4;
1760 ep->port = client_session->transport.rmt_port;
1761 if (client_session->transport.is_ip4)
Dave Barach178cf492018-11-13 16:34:13 -05001762 clib_memcpy_fast (ep->ip, &client_session->transport.rmt_ip.ip4,
1763 sizeof (ip4_address_t));
Dave Wallace048b1d62018-01-03 22:24:41 -05001764 else
Dave Barach178cf492018-11-13 16:34:13 -05001765 clib_memcpy_fast (ep->ip, &client_session->transport.rmt_ip.ip6,
1766 sizeof (ip6_address_t));
Dave Wallace048b1d62018-01-03 22:24:41 -05001767 }
Dave Wallace60caa062017-11-10 17:07:13 -05001768
Florin Coras60687192021-11-29 21:00:47 -08001769 VDBG (0,
1770 "listener %u [0x%llx] accepted %u [0x%llx] peer: %U:%u "
1771 "local: %U:%u",
1772 listen_session_handle, listen_session->vpp_handle,
Florin Coras05ecfcc2018-12-12 18:19:39 -08001773 client_session_index, client_session->vpp_handle,
Florin Coras60687192021-11-29 21:00:47 -08001774 vcl_format_ip46_address, &client_session->transport.rmt_ip,
Florin Coras54693d22018-07-17 10:46:29 -07001775 client_session->transport.is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6,
Florin Coras7e12d942018-06-27 14:32:43 -07001776 clib_net_to_host_u16 (client_session->transport.rmt_port),
Florin Coras60687192021-11-29 21:00:47 -08001777 vcl_format_ip46_address, &client_session->transport.lcl_ip,
Florin Coras54693d22018-07-17 10:46:29 -07001778 client_session->transport.is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6,
Florin Coras7e12d942018-06-27 14:32:43 -07001779 clib_net_to_host_u16 (client_session->transport.lcl_port));
Florin Coras0d427d82018-06-27 03:24:07 -07001780 vcl_evt (VCL_EVT_ACCEPT, client_session, listen_session,
1781 client_session_index);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001782
Florin Coras3c7d4f92018-12-14 11:28:43 -08001783 /*
1784 * Session might have been closed already
1785 */
1786 if (accept_flags)
1787 {
Florin Coras3c7d4f92018-12-14 11:28:43 -08001788 if (accept_flags & VCL_ACCEPTED_F_CLOSED)
Florin Corasc127d5a2020-10-14 16:35:58 -07001789 client_session->session_state = VCL_STATE_VPP_CLOSING;
Florin Coras3c7d4f92018-12-14 11:28:43 -08001790 else if (accept_flags & VCL_ACCEPTED_F_RESET)
Florin Corasc127d5a2020-10-14 16:35:58 -07001791 client_session->session_state = VCL_STATE_DISCONNECT;
Florin Coras3c7d4f92018-12-14 11:28:43 -08001792 }
Florin Corasab2f6db2018-08-31 14:31:41 -07001793 return vcl_session_handle (client_session);
Dave Wallace543852a2017-08-03 02:11:34 -04001794}
1795
1796int
Florin Coras134a9962018-08-28 11:32:04 -07001797vppcom_session_connect (uint32_t session_handle, vppcom_endpt_t * server_ep)
Dave Wallace543852a2017-08-03 02:11:34 -04001798{
Florin Coras134a9962018-08-28 11:32:04 -07001799 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras7e12d942018-06-27 14:32:43 -07001800 vcl_session_t *session = 0;
Florin Coras134a9962018-08-28 11:32:04 -07001801 u32 session_index;
Florin Coras070453d2018-08-24 17:04:27 -07001802 int rv;
Dave Wallace543852a2017-08-03 02:11:34 -04001803
Florin Coras134a9962018-08-28 11:32:04 -07001804 session = vcl_session_get_w_handle (wrk, session_handle);
Florin Coras070453d2018-08-24 17:04:27 -07001805 if (!session)
1806 return VPPCOM_EBADFD;
Florin Coras134a9962018-08-28 11:32:04 -07001807 session_index = session->session_index;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001808
Florin Coras6c3b2182020-10-19 18:36:48 -07001809 if (PREDICT_FALSE (session->flags & VCL_SESSION_F_IS_VEP))
Dave Wallace543852a2017-08-03 02:11:34 -04001810 {
Florin Coras5ffb9642021-12-03 17:24:13 -08001811 VWRN ("cannot connect epoll session %u!", session->session_index);
Florin Coras070453d2018-08-24 17:04:27 -07001812 return VPPCOM_EBADFD;
Dave Wallace543852a2017-08-03 02:11:34 -04001813 }
1814
Florin Corasc127d5a2020-10-14 16:35:58 -07001815 if (PREDICT_FALSE (vcl_session_is_ready (session)))
Dave Wallace543852a2017-08-03 02:11:34 -04001816 {
Florin Coras60687192021-11-29 21:00:47 -08001817 VDBG (0,
Florin Coras5ffb9642021-12-03 17:24:13 -08001818 "session %u [0x%llx]: already connected to %U:%d proto %s,"
1819 " state (%s)",
1820 session->session_index, session->vpp_handle,
Florin Coras60687192021-11-29 21:00:47 -08001821 vcl_format_ip46_address, &session->transport.rmt_ip,
1822 session->transport.is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6,
Florin Coras7e12d942018-06-27 14:32:43 -07001823 clib_net_to_host_u16 (session->transport.rmt_port),
Florin Coras5ffb9642021-12-03 17:24:13 -08001824 vppcom_proto_str (session->session_type),
Florin Coras60687192021-11-29 21:00:47 -08001825 vcl_session_state_str (session->session_state));
Florin Coras070453d2018-08-24 17:04:27 -07001826 return VPPCOM_OK;
Dave Wallace543852a2017-08-03 02:11:34 -04001827 }
1828
Florin Coras0a1e1832020-03-29 18:54:04 +00001829 /* Attempt to connect a connectionless listener */
Florin Corasc127d5a2020-10-14 16:35:58 -07001830 if (PREDICT_FALSE (session->session_state == VCL_STATE_LISTEN))
Florin Coras0a1e1832020-03-29 18:54:04 +00001831 {
1832 if (session->session_type != VPPCOM_PROTO_UDP)
1833 return VPPCOM_EINVAL;
1834 vcl_send_session_unlisten (wrk, session);
Florin Corasc127d5a2020-10-14 16:35:58 -07001835 session->session_state = VCL_STATE_CLOSED;
Florin Coras0a1e1832020-03-29 18:54:04 +00001836 }
1837
Florin Coras7e12d942018-06-27 14:32:43 -07001838 session->transport.is_ip4 = server_ep->is_ip4;
Florin Corasef7cbf62019-10-17 09:56:27 -07001839 vcl_ip_copy_from_ep (&session->transport.rmt_ip, server_ep);
Florin Coras7e12d942018-06-27 14:32:43 -07001840 session->transport.rmt_port = server_ep->port;
Nathan Skrzypczak8ac1d6d2019-07-17 11:02:20 +02001841 session->parent_handle = VCL_INVALID_SESSION_HANDLE;
Florin Coras0a1e1832020-03-29 18:54:04 +00001842 session->flags |= VCL_SESSION_F_CONNECTED;
Dave Wallace543852a2017-08-03 02:11:34 -04001843
Florin Coras5ffb9642021-12-03 17:24:13 -08001844 VDBG (0, "session %u: connecting to peer %U:%d proto %s",
1845 session->session_index, vcl_format_ip46_address,
Florin Coras60687192021-11-29 21:00:47 -08001846 &session->transport.rmt_ip,
1847 session->transport.is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6,
Florin Coras7e12d942018-06-27 14:32:43 -07001848 clib_net_to_host_u16 (session->transport.rmt_port),
Ping Yu34a3a082018-11-30 19:16:17 -05001849 vppcom_proto_str (session->session_type));
Dave Wallace543852a2017-08-03 02:11:34 -04001850
Florin Coras458089b2019-08-21 16:20:44 -07001851 vcl_send_session_connect (wrk, session);
Florin Coras57c88932019-08-29 12:03:17 -07001852
Florin Corasac422d62020-10-19 20:51:36 -07001853 if (vcl_session_has_attr (session, VCL_SESS_ATTR_NONBLOCK))
Florin Corasa5ea8212020-08-24 21:23:51 -07001854 {
fanyfa49d59d2020-10-13 17:07:16 +08001855 /* State set to STATE_UPDATED to ensure the session is not assumed
Florin Corasdfffdd72020-10-15 10:54:47 -07001856 * to be ready and to also allow the app to close it prior to vpp's
fanyfa49d59d2020-10-13 17:07:16 +08001857 * connected reply. */
Florin Corasc127d5a2020-10-14 16:35:58 -07001858 session->session_state = VCL_STATE_UPDATED;
Florin Corasa5ea8212020-08-24 21:23:51 -07001859 return VPPCOM_EINPROGRESS;
1860 }
Florin Coras57c88932019-08-29 12:03:17 -07001861
1862 /*
1863 * Wait for reply from vpp if blocking
1864 */
Florin Corasdfffdd72020-10-15 10:54:47 -07001865 rv = vppcom_wait_for_session_state_change (session_index, VCL_STATE_READY,
Florin Coras070453d2018-08-24 17:04:27 -07001866 vcm->cfg.session_timeout);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001867
Florin Coras134a9962018-08-28 11:32:04 -07001868 session = vcl_session_get (wrk, session_index);
Florin Coras5e062572019-03-14 19:07:51 -07001869 VDBG (0, "session %u [0x%llx]: connect %s!", session->session_index,
1870 session->vpp_handle, rv ? "failed" : "succeeded");
Dave Wallaceee45d412017-11-24 21:44:06 -05001871
Dave Wallace4878cbe2017-11-21 03:45:09 -05001872 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04001873}
1874
Nathan Skrzypczak9fd99622019-05-16 14:38:44 +02001875int
1876vppcom_session_stream_connect (uint32_t session_handle,
1877 uint32_t parent_session_handle)
1878{
1879 vcl_worker_t *wrk = vcl_worker_get_current ();
1880 vcl_session_t *session, *parent_session;
1881 u32 session_index, parent_session_index;
1882 int rv;
1883
1884 session = vcl_session_get_w_handle (wrk, session_handle);
1885 if (!session)
1886 return VPPCOM_EBADFD;
1887 parent_session = vcl_session_get_w_handle (wrk, parent_session_handle);
1888 if (!parent_session)
1889 return VPPCOM_EBADFD;
1890
1891 session_index = session->session_index;
1892 parent_session_index = parent_session->session_index;
Florin Coras6c3b2182020-10-19 18:36:48 -07001893 if (PREDICT_FALSE (session->flags & VCL_SESSION_F_IS_VEP))
Nathan Skrzypczak9fd99622019-05-16 14:38:44 +02001894 {
1895 VDBG (0, "ERROR: cannot connect epoll session %u!",
1896 session->session_index);
1897 return VPPCOM_EBADFD;
1898 }
1899
Florin Corasc127d5a2020-10-14 16:35:58 -07001900 if (PREDICT_FALSE (vcl_session_is_ready (session)))
Nathan Skrzypczak9fd99622019-05-16 14:38:44 +02001901 {
Florin Coras60687192021-11-29 21:00:47 -08001902 VDBG (0,
1903 "session handle %u [0x%llx]: session already "
Nathan Skrzypczak9fd99622019-05-16 14:38:44 +02001904 "connected to session %u [0x%llx] proto %s, state 0x%x (%s)",
Florin Coras60687192021-11-29 21:00:47 -08001905 session_handle, session->vpp_handle, parent_session_handle,
1906 parent_session->vpp_handle,
Nathan Skrzypczak9fd99622019-05-16 14:38:44 +02001907 vppcom_proto_str (session->session_type), session->session_state,
Florin Coras60687192021-11-29 21:00:47 -08001908 vcl_session_state_str (session->session_state));
Nathan Skrzypczak9fd99622019-05-16 14:38:44 +02001909 return VPPCOM_OK;
1910 }
1911
1912 /* Connect to quic session specifics */
1913 session->transport.is_ip4 = parent_session->transport.is_ip4;
1914 session->transport.rmt_ip.ip4.as_u32 = (uint32_t) 1;
1915 session->transport.rmt_port = 0;
Nathan Skrzypczak8ac1d6d2019-07-17 11:02:20 +02001916 session->parent_handle = parent_session->vpp_handle;
Nathan Skrzypczak9fd99622019-05-16 14:38:44 +02001917
1918 VDBG (0, "session handle %u: connecting to session %u [0x%llx]",
1919 session_handle, parent_session_handle, parent_session->vpp_handle);
1920
1921 /*
1922 * Send connect request and wait for reply from vpp
1923 */
Florin Coras458089b2019-08-21 16:20:44 -07001924 vcl_send_session_connect (wrk, session);
Florin Corasdfffdd72020-10-15 10:54:47 -07001925 rv = vppcom_wait_for_session_state_change (session_index, VCL_STATE_READY,
Nathan Skrzypczak9fd99622019-05-16 14:38:44 +02001926 vcm->cfg.session_timeout);
1927
1928 session->listener_index = parent_session_index;
1929 parent_session = vcl_session_get_w_handle (wrk, parent_session_handle);
Florin Coras028eaf02019-07-19 12:15:52 -07001930 if (parent_session)
1931 parent_session->n_accepted_sessions++;
Nathan Skrzypczak9fd99622019-05-16 14:38:44 +02001932
1933 session = vcl_session_get (wrk, session_index);
1934 VDBG (0, "session %u [0x%llx]: connect %s!", session->session_index,
1935 session->vpp_handle, rv ? "failed" : "succeeded");
1936
1937 return rv;
1938}
1939
Steven58f464e2017-10-25 12:33:12 -07001940static inline int
Florin Coras134a9962018-08-28 11:32:04 -07001941vppcom_session_read_internal (uint32_t session_handle, void *buf, int n,
Steven58f464e2017-10-25 12:33:12 -07001942 u8 peek)
Dave Wallace543852a2017-08-03 02:11:34 -04001943{
Florin Coras134a9962018-08-28 11:32:04 -07001944 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras4a2c7942020-09-10 12:27:14 -07001945 int rv, n_read = 0, is_nonblocking;
Florin Coras460dce62018-07-27 05:45:06 -07001946 vcl_session_t *s = 0;
Dave Wallace543852a2017-08-03 02:11:34 -04001947 svm_fifo_t *rx_fifo;
Florin Coras54693d22018-07-17 10:46:29 -07001948 session_event_t *e;
1949 svm_msg_q_t *mq;
Florin Coras41c9e042018-09-11 00:10:41 -07001950 u8 is_ct;
Dave Wallace543852a2017-08-03 02:11:34 -04001951
Florin Coras070453d2018-08-24 17:04:27 -07001952 if (PREDICT_FALSE (!buf))
wanghanlin72228a22021-07-06 17:18:29 +08001953 return VPPCOM_EFAULT;
Dave Wallace543852a2017-08-03 02:11:34 -04001954
Florin Coras134a9962018-08-28 11:32:04 -07001955 s = vcl_session_get_w_handle (wrk, session_handle);
Florin Coras6c3b2182020-10-19 18:36:48 -07001956 if (PREDICT_FALSE (!s || (s->flags & VCL_SESSION_F_IS_VEP)))
Florin Coras070453d2018-08-24 17:04:27 -07001957 return VPPCOM_EBADFD;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001958
Florin Coras6d0106e2019-01-29 20:11:58 -08001959 if (PREDICT_FALSE (!vcl_session_is_open (s)))
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001960 {
Florin Coras5e062572019-03-14 19:07:51 -07001961 VDBG (0, "session %u[0x%llx] is not open! state 0x%x (%s)",
Florin Coras6d0106e2019-01-29 20:11:58 -08001962 s->session_index, s->vpp_handle, s->session_state,
Florin Coras60687192021-11-29 21:00:47 -08001963 vcl_session_state_str (s->session_state));
Florin Coras6d0106e2019-01-29 20:11:58 -08001964 return vcl_session_closed_error (s);
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001965 }
1966
liuyacan55c952e2021-06-13 14:54:55 +08001967 if (PREDICT_FALSE (s->flags & VCL_SESSION_F_RD_SHUTDOWN))
1968 {
1969 /* Vpp would ack the incoming data and enqueue it for reading.
1970 * So even if SHUT_RD is set, we can still read() the data if
1971 * the session is ready.
1972 */
1973 if (!vcl_session_read_ready (s))
1974 {
1975 return 0;
1976 }
1977 }
1978
Florin Corasac422d62020-10-19 20:51:36 -07001979 is_nonblocking = vcl_session_has_attr (s, VCL_SESS_ATTR_NONBLOCK);
Florin Coras41c9e042018-09-11 00:10:41 -07001980 is_ct = vcl_session_is_ct (s);
Florin Coras653e43f2019-03-04 10:56:23 -08001981 mq = wrk->app_event_queue;
1982 rx_fifo = is_ct ? s->ct_rx_fifo : s->rx_fifo;
Florin Corasac422d62020-10-19 20:51:36 -07001983 s->flags &= ~VCL_SESSION_F_HAS_RX_EVT;
Dave Wallacef7f809c2017-10-03 01:48:42 -04001984
Sirshak Das28aa5392019-02-05 01:33:33 -06001985 if (svm_fifo_is_empty_cons (rx_fifo))
Dave Wallacef7f809c2017-10-03 01:48:42 -04001986 {
Florin Coras54693d22018-07-17 10:46:29 -07001987 if (is_nonblocking)
Florin Corasc0737e92019-03-04 14:19:39 -08001988 {
Yu Pingb2955352019-12-04 06:49:04 +08001989 if (vcl_session_is_closing (s))
1990 return vcl_session_closing_error (s);
Florin Corasd6894562020-10-28 00:37:15 -07001991 if (is_ct)
1992 svm_fifo_unset_event (s->rx_fifo);
1993 svm_fifo_unset_event (rx_fifo);
Florin Corasc0737e92019-03-04 14:19:39 -08001994 return VPPCOM_EWOULDBLOCK;
1995 }
Sirshak Das28aa5392019-02-05 01:33:33 -06001996 while (svm_fifo_is_empty_cons (rx_fifo))
Florin Coras54693d22018-07-17 10:46:29 -07001997 {
Florin Coras6d0106e2019-01-29 20:11:58 -08001998 if (vcl_session_is_closing (s))
1999 return vcl_session_closing_error (s);
2000
Florin Corasd6894562020-10-28 00:37:15 -07002001 if (is_ct)
2002 svm_fifo_unset_event (s->rx_fifo);
2003 svm_fifo_unset_event (rx_fifo);
Florin Coras99368312018-08-02 10:45:44 -07002004
Florin Coras5398dfb2021-01-25 20:31:27 -08002005 svm_msg_q_wait (mq, SVM_MQ_WAIT_EMPTY);
2006 vcl_worker_flush_mq_events (wrk);
Florin Coras54693d22018-07-17 10:46:29 -07002007 }
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002008 }
Florin Coras54693d22018-07-17 10:46:29 -07002009
Florin Coras4a2c7942020-09-10 12:27:14 -07002010read_again:
2011
Florin Coras460dce62018-07-27 05:45:06 -07002012 if (s->is_dgram)
Florin Coras4a2c7942020-09-10 12:27:14 -07002013 rv = app_recv_dgram_raw (rx_fifo, buf, n, &s->transport, 0, peek);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002014 else
Florin Coras4a2c7942020-09-10 12:27:14 -07002015 rv = app_recv_stream_raw (rx_fifo, buf, n, 0, peek);
2016
2017 ASSERT (rv >= 0);
Florin Coras23368312021-06-04 16:28:18 -07002018
2019 if (peek)
2020 return rv;
2021
Florin Coras4a2c7942020-09-10 12:27:14 -07002022 n_read += rv;
Florin Coras54693d22018-07-17 10:46:29 -07002023
Sirshak Das28aa5392019-02-05 01:33:33 -06002024 if (svm_fifo_is_empty_cons (rx_fifo))
Florin Corasc34118b2020-08-12 18:58:25 -07002025 {
Florin Corasd6894562020-10-28 00:37:15 -07002026 if (is_ct)
2027 svm_fifo_unset_event (s->rx_fifo);
2028 svm_fifo_unset_event (rx_fifo);
Florin Corasc34118b2020-08-12 18:58:25 -07002029 if (!svm_fifo_is_empty_cons (rx_fifo)
Florin Corasd6894562020-10-28 00:37:15 -07002030 && svm_fifo_set_event (rx_fifo) && is_nonblocking)
Florin Corasc34118b2020-08-12 18:58:25 -07002031 {
Florin Corasc34118b2020-08-12 18:58:25 -07002032 vec_add2 (wrk->unhandled_evts_vector, e, 1);
2033 e->event_type = SESSION_IO_EVT_RX;
2034 e->session_index = s->session_index;
2035 }
2036 }
Florin Coras54fe32c2020-11-25 20:26:32 -08002037 else if (PREDICT_FALSE (rv < n && !s->is_dgram))
Florin Coras4a2c7942020-09-10 12:27:14 -07002038 {
2039 /* More data enqueued while reading. Try to drain it
Florin Coras54fe32c2020-11-25 20:26:32 -08002040 * or fill the buffer. Avoid doing that for dgrams */
Florin Coras4a2c7942020-09-10 12:27:14 -07002041 buf += rv;
2042 n -= rv;
2043 goto read_again;
2044 }
Florin Coras41c9e042018-09-11 00:10:41 -07002045
Florin Coras17ec5772020-08-12 20:46:29 -07002046 if (PREDICT_FALSE (svm_fifo_needs_deq_ntf (rx_fifo, n_read)))
Florin Coras317b8e02019-04-17 09:57:46 -07002047 {
Florin Coras17ec5772020-08-12 20:46:29 -07002048 svm_fifo_clear_deq_ntf (rx_fifo);
Florin Corasc547e912020-12-08 17:50:45 -08002049 app_send_io_evt_to_vpp (s->vpp_evt_q,
2050 s->rx_fifo->shr->master_session_index,
Florin Coras317b8e02019-04-17 09:57:46 -07002051 SESSION_IO_EVT_RX, SVM_Q_WAIT);
Florin Coras317b8e02019-04-17 09:57:46 -07002052 }
2053
Florin Coras5e062572019-03-14 19:07:51 -07002054 VDBG (2, "session %u[0x%llx]: read %d bytes from (%p)", s->session_index,
2055 s->vpp_handle, n_read, rx_fifo);
Florin Coras2cba8532018-09-11 16:33:36 -07002056
Florin Coras54693d22018-07-17 10:46:29 -07002057 return n_read;
Dave Wallace543852a2017-08-03 02:11:34 -04002058}
2059
Steven58f464e2017-10-25 12:33:12 -07002060int
Florin Coras134a9962018-08-28 11:32:04 -07002061vppcom_session_read (uint32_t session_handle, void *buf, size_t n)
Steven58f464e2017-10-25 12:33:12 -07002062{
Florin Coras134a9962018-08-28 11:32:04 -07002063 return (vppcom_session_read_internal (session_handle, buf, n, 0));
Steven58f464e2017-10-25 12:33:12 -07002064}
2065
2066static int
Florin Coras134a9962018-08-28 11:32:04 -07002067vppcom_session_peek (uint32_t session_handle, void *buf, int n)
Steven58f464e2017-10-25 12:33:12 -07002068{
Florin Coras134a9962018-08-28 11:32:04 -07002069 return (vppcom_session_read_internal (session_handle, buf, n, 1));
Steven58f464e2017-10-25 12:33:12 -07002070}
2071
Florin Coras2cba8532018-09-11 16:33:36 -07002072int
2073vppcom_session_read_segments (uint32_t session_handle,
Florin Corasd68faf82020-09-25 15:18:13 -07002074 vppcom_data_segment_t * ds, uint32_t n_segments,
2075 uint32_t max_bytes)
Florin Coras2cba8532018-09-11 16:33:36 -07002076{
2077 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras6d0106e2019-01-29 20:11:58 -08002078 int n_read = 0, is_nonblocking;
Florin Coras2cba8532018-09-11 16:33:36 -07002079 vcl_session_t *s = 0;
2080 svm_fifo_t *rx_fifo;
Florin Coras2cba8532018-09-11 16:33:36 -07002081 svm_msg_q_t *mq;
2082 u8 is_ct;
2083
2084 s = vcl_session_get_w_handle (wrk, session_handle);
Florin Coras6c3b2182020-10-19 18:36:48 -07002085 if (PREDICT_FALSE (!s || (s->flags & VCL_SESSION_F_IS_VEP)))
Florin Coras2cba8532018-09-11 16:33:36 -07002086 return VPPCOM_EBADFD;
2087
Florin Coras6d0106e2019-01-29 20:11:58 -08002088 if (PREDICT_FALSE (!vcl_session_is_open (s)))
2089 return vcl_session_closed_error (s);
Florin Coras2cba8532018-09-11 16:33:36 -07002090
Florin Corasac422d62020-10-19 20:51:36 -07002091 is_nonblocking = vcl_session_has_attr (s, VCL_SESS_ATTR_NONBLOCK);
Florin Coras2cba8532018-09-11 16:33:36 -07002092 is_ct = vcl_session_is_ct (s);
Florin Corasac422d62020-10-19 20:51:36 -07002093 mq = wrk->app_event_queue;
Florin Coras62877022020-10-28 21:22:04 -07002094 rx_fifo = is_ct ? s->ct_rx_fifo : s->rx_fifo;
Florin Corasac422d62020-10-19 20:51:36 -07002095 s->flags &= ~VCL_SESSION_F_HAS_RX_EVT;
Florin Coras2cba8532018-09-11 16:33:36 -07002096
Sirshak Das28aa5392019-02-05 01:33:33 -06002097 if (svm_fifo_is_empty_cons (rx_fifo))
Florin Coras2cba8532018-09-11 16:33:36 -07002098 {
2099 if (is_nonblocking)
2100 {
Florin Coras62877022020-10-28 21:22:04 -07002101 if (is_ct)
2102 svm_fifo_unset_event (s->rx_fifo);
Florin Coras2cba8532018-09-11 16:33:36 -07002103 svm_fifo_unset_event (rx_fifo);
Florin Corasaa27eb92018-10-13 12:20:01 -07002104 return VPPCOM_EWOULDBLOCK;
Florin Coras2cba8532018-09-11 16:33:36 -07002105 }
Sirshak Das28aa5392019-02-05 01:33:33 -06002106 while (svm_fifo_is_empty_cons (rx_fifo))
Florin Coras2cba8532018-09-11 16:33:36 -07002107 {
Florin Coras6d0106e2019-01-29 20:11:58 -08002108 if (vcl_session_is_closing (s))
2109 return vcl_session_closing_error (s);
2110
Florin Coras62877022020-10-28 21:22:04 -07002111 if (is_ct)
2112 svm_fifo_unset_event (s->rx_fifo);
Florin Coras2cba8532018-09-11 16:33:36 -07002113 svm_fifo_unset_event (rx_fifo);
Florin Coras2cba8532018-09-11 16:33:36 -07002114
Florin Coras5398dfb2021-01-25 20:31:27 -08002115 svm_msg_q_wait (mq, SVM_MQ_WAIT_EMPTY);
2116 vcl_worker_flush_mq_events (wrk);
Florin Coras2cba8532018-09-11 16:33:36 -07002117 }
2118 }
2119
Florin Corasd1cc38d2020-10-11 11:05:04 -07002120 n_read = svm_fifo_segments (rx_fifo, s->rx_bytes_pending,
Florin Corasb85de192022-01-18 20:51:08 -08002121 (svm_fifo_seg_t *) ds, &n_segments, max_bytes);
Florin Corasd1cc38d2020-10-11 11:05:04 -07002122 if (n_read < 0)
2123 return VPPCOM_EAGAIN;
2124
2125 if (svm_fifo_max_dequeue_cons (rx_fifo) == n_read)
2126 {
Florin Coras62877022020-10-28 21:22:04 -07002127 if (is_ct)
2128 svm_fifo_unset_event (s->rx_fifo);
2129 svm_fifo_unset_event (rx_fifo);
Florin Corasd1cc38d2020-10-11 11:05:04 -07002130 if (svm_fifo_max_dequeue_cons (rx_fifo) != n_read
Florin Coras62877022020-10-28 21:22:04 -07002131 && svm_fifo_set_event (rx_fifo)
Florin Corasac422d62020-10-19 20:51:36 -07002132 && vcl_session_has_attr (s, VCL_SESS_ATTR_NONBLOCK))
Florin Corasd1cc38d2020-10-11 11:05:04 -07002133 {
2134 session_event_t *e;
2135 vec_add2 (wrk->unhandled_evts_vector, e, 1);
2136 e->event_type = SESSION_IO_EVT_RX;
2137 e->session_index = s->session_index;
2138 }
2139 }
2140
2141 s->rx_bytes_pending += n_read;
Florin Coras2cba8532018-09-11 16:33:36 -07002142 return n_read;
2143}
2144
2145void
Florin Corasd68faf82020-09-25 15:18:13 -07002146vppcom_session_free_segments (uint32_t session_handle, uint32_t n_bytes)
Florin Coras2cba8532018-09-11 16:33:36 -07002147{
2148 vcl_worker_t *wrk = vcl_worker_get_current ();
2149 vcl_session_t *s;
Florin Coras62877022020-10-28 21:22:04 -07002150 u8 is_ct;
Florin Coras2cba8532018-09-11 16:33:36 -07002151
2152 s = vcl_session_get_w_handle (wrk, session_handle);
Florin Coras6c3b2182020-10-19 18:36:48 -07002153 if (PREDICT_FALSE (!s || (s->flags & VCL_SESSION_F_IS_VEP)))
Florin Coras2cba8532018-09-11 16:33:36 -07002154 return;
2155
Florin Coras62877022020-10-28 21:22:04 -07002156 is_ct = vcl_session_is_ct (s);
2157 svm_fifo_dequeue_drop (is_ct ? s->ct_rx_fifo : s->rx_fifo, n_bytes);
Florin Corasd1cc38d2020-10-11 11:05:04 -07002158
Florin Coras8cc93212021-09-10 11:37:12 -07002159 ASSERT (s->rx_bytes_pending >= n_bytes);
Florin Corasd1cc38d2020-10-11 11:05:04 -07002160 s->rx_bytes_pending -= n_bytes;
Florin Coras2cba8532018-09-11 16:33:36 -07002161}
2162
Florin Coras7a2abce2020-04-05 19:25:44 +00002163always_inline u8
2164vcl_fifo_is_writeable (svm_fifo_t * f, u32 len, u8 is_dgram)
Dave Wallace543852a2017-08-03 02:11:34 -04002165{
Florin Coras7a2abce2020-04-05 19:25:44 +00002166 u32 max_enq = svm_fifo_max_enqueue_prod (f);
2167 if (is_dgram)
2168 return max_enq >= (sizeof (session_dgram_hdr_t) + len);
2169 else
2170 return max_enq > 0;
Florin Coras7a2abce2020-04-05 19:25:44 +00002171}
2172
2173always_inline int
2174vppcom_session_write_inline (vcl_worker_t * wrk, vcl_session_t * s, void *buf,
2175 size_t n, u8 is_flush, u8 is_dgram)
2176{
Florin Coras6d0106e2019-01-29 20:11:58 -08002177 int n_write, is_nonblocking;
Florin Coras460dce62018-07-27 05:45:06 -07002178 session_evt_type_t et;
Florin Coras14ed6df2019-03-06 21:13:42 -08002179 svm_fifo_t *tx_fifo;
Florin Coras3c2fed52018-07-04 04:15:05 -07002180 svm_msg_q_t *mq;
Florin Coras0e88e852018-09-17 22:09:02 -07002181 u8 is_ct;
Dave Wallace543852a2017-08-03 02:11:34 -04002182
Florin Coras0b0d28e2021-06-04 17:31:53 -07002183 /* Accept zero length writes but just return */
2184 if (PREDICT_FALSE (!n))
2185 return VPPCOM_OK;
2186
2187 if (PREDICT_FALSE (!buf))
2188 return VPPCOM_EFAULT;
Dave Wallace543852a2017-08-03 02:11:34 -04002189
Florin Coras6c3b2182020-10-19 18:36:48 -07002190 if (PREDICT_FALSE (s->flags & VCL_SESSION_F_IS_VEP))
Dave Wallace543852a2017-08-03 02:11:34 -04002191 {
Florin Coras6d0106e2019-01-29 20:11:58 -08002192 VDBG (0, "ERROR: session %u [0x%llx]: cannot write to an epoll"
2193 " session!", s->session_index, s->vpp_handle);
Florin Coras070453d2018-08-24 17:04:27 -07002194 return VPPCOM_EBADFD;
Dave Wallace543852a2017-08-03 02:11:34 -04002195 }
2196
liuyacan55c952e2021-06-13 14:54:55 +08002197 if (PREDICT_FALSE (!vcl_session_is_open (s)))
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002198 {
Florin Coras6d0106e2019-01-29 20:11:58 -08002199 VDBG (1, "session %u [0x%llx]: is not open! state 0x%x (%s)",
2200 s->session_index, s->vpp_handle, s->session_state,
Florin Coras60687192021-11-29 21:00:47 -08002201 vcl_session_state_str (s->session_state));
Florin Coras6d0106e2019-01-29 20:11:58 -08002202 return vcl_session_closed_error (s);;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002203 }
2204
liuyacan55c952e2021-06-13 14:54:55 +08002205 if (PREDICT_FALSE (s->flags & VCL_SESSION_F_WR_SHUTDOWN))
2206 {
2207 VDBG (1, "session %u [0x%llx]: is shutdown! state 0x%x (%s)",
2208 s->session_index, s->vpp_handle, s->session_state,
Florin Coras60687192021-11-29 21:00:47 -08002209 vcl_session_state_str (s->session_state));
liuyacan55c952e2021-06-13 14:54:55 +08002210 return VPPCOM_EPIPE;
2211 }
2212
Florin Coras0e88e852018-09-17 22:09:02 -07002213 is_ct = vcl_session_is_ct (s);
Florin Coras653e43f2019-03-04 10:56:23 -08002214 tx_fifo = is_ct ? s->ct_tx_fifo : s->tx_fifo;
Florin Corasac422d62020-10-19 20:51:36 -07002215 is_nonblocking = vcl_session_has_attr (s, VCL_SESS_ATTR_NONBLOCK);
Sirshak Das28aa5392019-02-05 01:33:33 -06002216
Florin Coras653e43f2019-03-04 10:56:23 -08002217 mq = wrk->app_event_queue;
Florin Coras7a2abce2020-04-05 19:25:44 +00002218 if (!vcl_fifo_is_writeable (tx_fifo, n, is_dgram))
Dave Wallace543852a2017-08-03 02:11:34 -04002219 {
Florin Coras54693d22018-07-17 10:46:29 -07002220 if (is_nonblocking)
2221 {
Florin Coras070453d2018-08-24 17:04:27 -07002222 return VPPCOM_EWOULDBLOCK;
Florin Coras54693d22018-07-17 10:46:29 -07002223 }
Florin Coras7a2abce2020-04-05 19:25:44 +00002224 while (!vcl_fifo_is_writeable (tx_fifo, n, is_dgram))
Florin Coras54693d22018-07-17 10:46:29 -07002225 {
Florin Coras2d379d82019-06-28 12:45:12 -07002226 svm_fifo_add_want_deq_ntf (tx_fifo, SVM_FIFO_WANT_DEQ_NOTIF);
Florin Coras6d0106e2019-01-29 20:11:58 -08002227 if (vcl_session_is_closing (s))
2228 return vcl_session_closing_error (s);
Florin Coras0e88e852018-09-17 22:09:02 -07002229
Florin Coras5398dfb2021-01-25 20:31:27 -08002230 svm_msg_q_wait (mq, SVM_MQ_WAIT_EMPTY);
2231 vcl_worker_flush_mq_events (wrk);
Florin Coras54693d22018-07-17 10:46:29 -07002232 }
Dave Wallace543852a2017-08-03 02:11:34 -04002233 }
Dave Wallace543852a2017-08-03 02:11:34 -04002234
Florin Coras653e43f2019-03-04 10:56:23 -08002235 et = SESSION_IO_EVT_TX;
2236 if (is_flush && !is_ct)
Florin Coras42ceddb2018-12-12 10:56:01 -08002237 et = SESSION_IO_EVT_TX_FLUSH;
2238
Florin Coras7a2abce2020-04-05 19:25:44 +00002239 if (is_dgram)
Florin Coras460dce62018-07-27 05:45:06 -07002240 n_write = app_send_dgram_raw (tx_fifo, &s->transport,
Florin Coras653e43f2019-03-04 10:56:23 -08002241 s->vpp_evt_q, buf, n, et,
Florin Coras14ed6df2019-03-06 21:13:42 -08002242 0 /* do_evt */ , SVM_Q_WAIT);
Florin Coras460dce62018-07-27 05:45:06 -07002243 else
2244 n_write = app_send_stream_raw (tx_fifo, s->vpp_evt_q, buf, n, et,
Florin Coras14ed6df2019-03-06 21:13:42 -08002245 0 /* do_evt */ , SVM_Q_WAIT);
Florin Coras653e43f2019-03-04 10:56:23 -08002246
Florin Coras14ed6df2019-03-06 21:13:42 -08002247 if (svm_fifo_set_event (s->tx_fifo))
Florin Corasc547e912020-12-08 17:50:45 -08002248 app_send_io_evt_to_vpp (
2249 s->vpp_evt_q, s->tx_fifo->shr->master_session_index, et, SVM_Q_WAIT);
Keith Burns (alagalah)410bcca2018-03-23 13:42:49 -07002250
Florin Coras56230092020-09-02 20:52:58 -07002251 /* The underlying fifo segment can run out of memory */
2252 if (PREDICT_FALSE (n_write < 0))
2253 return VPPCOM_EAGAIN;
Dave Wallace543852a2017-08-03 02:11:34 -04002254
Florin Coras6d0106e2019-01-29 20:11:58 -08002255 VDBG (2, "session %u [0x%llx]: wrote %d bytes", s->session_index,
2256 s->vpp_handle, n_write);
Florin Coras0e88e852018-09-17 22:09:02 -07002257
Florin Coras54693d22018-07-17 10:46:29 -07002258 return n_write;
Dave Wallace543852a2017-08-03 02:11:34 -04002259}
2260
Florin Coras42ceddb2018-12-12 10:56:01 -08002261int
2262vppcom_session_write (uint32_t session_handle, void *buf, size_t n)
2263{
Florin Coras7a2abce2020-04-05 19:25:44 +00002264 vcl_worker_t *wrk = vcl_worker_get_current ();
2265 vcl_session_t *s;
2266
2267 s = vcl_session_get_w_handle (wrk, session_handle);
2268 if (PREDICT_FALSE (!s))
2269 return VPPCOM_EBADFD;
2270
2271 return vppcom_session_write_inline (wrk, s, buf, n,
2272 0 /* is_flush */ , s->is_dgram ? 1 : 0);
Florin Coras42ceddb2018-12-12 10:56:01 -08002273}
2274
Florin Corasb0f662f2018-12-27 14:51:46 -08002275int
2276vppcom_session_write_msg (uint32_t session_handle, void *buf, size_t n)
2277{
Florin Coras7a2abce2020-04-05 19:25:44 +00002278 vcl_worker_t *wrk = vcl_worker_get_current ();
2279 vcl_session_t *s;
2280
2281 s = vcl_session_get_w_handle (wrk, session_handle);
2282 if (PREDICT_FALSE (!s))
2283 return VPPCOM_EBADFD;
2284
2285 return vppcom_session_write_inline (wrk, s, buf, n,
2286 1 /* is_flush */ , s->is_dgram ? 1 : 0);
Florin Corasb0f662f2018-12-27 14:51:46 -08002287}
2288
Florin Corasc0737e92019-03-04 14:19:39 -08002289#define vcl_fifo_rx_evt_valid_or_break(_s) \
Florin Corasbd52e462019-10-28 13:22:37 -07002290if (PREDICT_FALSE (!_s->rx_fifo)) \
2291 break; \
Florin Corasc0737e92019-03-04 14:19:39 -08002292if (PREDICT_FALSE (svm_fifo_is_empty (_s->rx_fifo))) \
2293 { \
2294 if (!vcl_session_is_ct (_s)) \
2295 { \
2296 svm_fifo_unset_event (_s->rx_fifo); \
2297 if (svm_fifo_is_empty (_s->rx_fifo)) \
2298 break; \
2299 } \
2300 else if (svm_fifo_is_empty (_s->ct_rx_fifo)) \
2301 { \
Florin Coras2f630182020-08-13 00:17:51 -07002302 svm_fifo_unset_event (_s->rx_fifo); /* rx evts on actual fifo*/ \
Florin Corasc0737e92019-03-04 14:19:39 -08002303 if (svm_fifo_is_empty (_s->ct_rx_fifo)) \
2304 break; \
2305 } \
2306 } \
Florin Coras6d4bb422018-09-04 22:07:27 -07002307
Florin Coras86f04502018-09-12 16:08:01 -07002308static void
2309vcl_select_handle_mq_event (vcl_worker_t * wrk, session_event_t * e,
2310 unsigned long n_bits, unsigned long *read_map,
2311 unsigned long *write_map,
2312 unsigned long *except_map, u32 * bits_set)
Florin Coras54693d22018-07-17 10:46:29 -07002313{
2314 session_disconnected_msg_t *disconnected_msg;
Florin Coras99368312018-08-02 10:45:44 -07002315 session_connected_msg_t *connected_msg;
Florin Corasb242d312020-10-26 15:35:40 -07002316 vcl_session_t *s;
Florin Coras86f04502018-09-12 16:08:01 -07002317 u32 sid;
2318
2319 switch (e->event_type)
2320 {
Florin Corasc0737e92019-03-04 14:19:39 -08002321 case SESSION_IO_EVT_RX:
2322 sid = e->session_index;
Florin Corasb242d312020-10-26 15:35:40 -07002323 s = vcl_session_get (wrk, sid);
2324 if (!s || !vcl_session_is_open (s))
Florin Coras86f04502018-09-12 16:08:01 -07002325 break;
Florin Corasb242d312020-10-26 15:35:40 -07002326 vcl_fifo_rx_evt_valid_or_break (s);
Florin Coras86f04502018-09-12 16:08:01 -07002327 if (sid < n_bits && read_map)
2328 {
David Johnsond9818dd2018-12-14 14:53:41 -05002329 clib_bitmap_set_no_check ((uword *) read_map, sid, 1);
Florin Coras86f04502018-09-12 16:08:01 -07002330 *bits_set += 1;
2331 }
2332 break;
Florin Corasfe97da32019-03-06 10:09:04 -08002333 case SESSION_IO_EVT_TX:
Florin Corasc0737e92019-03-04 14:19:39 -08002334 sid = e->session_index;
Florin Corasb242d312020-10-26 15:35:40 -07002335 s = vcl_session_get (wrk, sid);
2336 if (!s || !vcl_session_is_open (s))
Florin Coras86f04502018-09-12 16:08:01 -07002337 break;
2338 if (sid < n_bits && write_map)
2339 {
David Johnsond9818dd2018-12-14 14:53:41 -05002340 clib_bitmap_set_no_check ((uword *) write_map, sid, 1);
Florin Coras86f04502018-09-12 16:08:01 -07002341 *bits_set += 1;
2342 }
2343 break;
Florin Coras86f04502018-09-12 16:08:01 -07002344 case SESSION_CTRL_EVT_ACCEPTED:
Florin Corasb242d312020-10-26 15:35:40 -07002345 if (!e->postponed)
2346 s = vcl_session_accepted (wrk, (session_accepted_msg_t *) e->data);
2347 else
2348 s = vcl_session_get (wrk, e->session_index);
2349 if (!s)
Florin Coras3c7d4f92018-12-14 11:28:43 -08002350 break;
Florin Corasb242d312020-10-26 15:35:40 -07002351 sid = s->session_index;
Florin Coras86f04502018-09-12 16:08:01 -07002352 if (sid < n_bits && read_map)
2353 {
David Johnsond9818dd2018-12-14 14:53:41 -05002354 clib_bitmap_set_no_check ((uword *) read_map, sid, 1);
Florin Coras86f04502018-09-12 16:08:01 -07002355 *bits_set += 1;
2356 }
2357 break;
2358 case SESSION_CTRL_EVT_CONNECTED:
Florin Corasb242d312020-10-26 15:35:40 -07002359 if (!e->postponed)
2360 {
2361 connected_msg = (session_connected_msg_t *) e->data;
2362 sid = vcl_session_connected_handler (wrk, connected_msg);
2363 }
2364 else
2365 sid = e->session_index;
Florin Coras57c88932019-08-29 12:03:17 -07002366 if (sid == VCL_INVALID_SESSION_INDEX)
2367 break;
2368 if (sid < n_bits && write_map)
2369 {
2370 clib_bitmap_set_no_check ((uword *) write_map, sid, 1);
2371 *bits_set += 1;
2372 }
Florin Coras86f04502018-09-12 16:08:01 -07002373 break;
2374 case SESSION_CTRL_EVT_DISCONNECTED:
2375 disconnected_msg = (session_disconnected_msg_t *) e->data;
Florin Corasb242d312020-10-26 15:35:40 -07002376 s = vcl_session_disconnected_handler (wrk, disconnected_msg);
2377 if (!s)
Florin Coras3c7d4f92018-12-14 11:28:43 -08002378 break;
Florin Corasb242d312020-10-26 15:35:40 -07002379 sid = s->session_index;
Florin Coras86f04502018-09-12 16:08:01 -07002380 if (sid < n_bits && except_map)
2381 {
David Johnsond9818dd2018-12-14 14:53:41 -05002382 clib_bitmap_set_no_check ((uword *) except_map, sid, 1);
Florin Coras86f04502018-09-12 16:08:01 -07002383 *bits_set += 1;
2384 }
2385 break;
2386 case SESSION_CTRL_EVT_RESET:
2387 sid = vcl_session_reset_handler (wrk, (session_reset_msg_t *) e->data);
2388 if (sid < n_bits && except_map)
2389 {
David Johnsond9818dd2018-12-14 14:53:41 -05002390 clib_bitmap_set_no_check ((uword *) except_map, sid, 1);
Florin Coras86f04502018-09-12 16:08:01 -07002391 *bits_set += 1;
2392 }
2393 break;
Florin Corasdfae9f92019-02-20 19:48:31 -08002394 case SESSION_CTRL_EVT_UNLISTEN_REPLY:
2395 vcl_session_unlisten_reply_handler (wrk, e->data);
2396 break;
Florin Coras68b7e582020-01-21 18:33:23 -08002397 case SESSION_CTRL_EVT_MIGRATED:
2398 vcl_session_migrated_handler (wrk, e->data);
2399 break;
Florin Coras9ace36d2019-10-28 13:14:17 -07002400 case SESSION_CTRL_EVT_CLEANUP:
2401 vcl_session_cleanup_handler (wrk, e->data);
2402 break;
Florin Coras30e79c22019-01-02 19:31:22 -08002403 case SESSION_CTRL_EVT_WORKER_UPDATE_REPLY:
2404 vcl_session_worker_update_reply_handler (wrk, e->data);
2405 break;
2406 case SESSION_CTRL_EVT_REQ_WORKER_UPDATE:
2407 vcl_session_req_worker_update_handler (wrk, e->data);
2408 break;
Florin Corasc4c4cf52019-08-24 18:17:34 -07002409 case SESSION_CTRL_EVT_APP_ADD_SEGMENT:
2410 vcl_session_app_add_segment_handler (wrk, e->data);
2411 break;
2412 case SESSION_CTRL_EVT_APP_DEL_SEGMENT:
2413 vcl_session_app_del_segment_handler (wrk, e->data);
2414 break;
hanlina3a48962020-07-13 11:09:15 +08002415 case SESSION_CTRL_EVT_APP_WRK_RPC:
Florin Coras40c07ce2020-07-16 20:46:17 -07002416 vcl_worker_rpc_handler (wrk, e->data);
2417 break;
Florin Coras86f04502018-09-12 16:08:01 -07002418 default:
2419 clib_warning ("unhandled: %u", e->event_type);
2420 break;
2421 }
2422}
2423
2424static int
2425vcl_select_handle_mq (vcl_worker_t * wrk, svm_msg_q_t * mq,
2426 unsigned long n_bits, unsigned long *read_map,
2427 unsigned long *write_map, unsigned long *except_map,
2428 double time_to_wait, u32 * bits_set)
2429{
Florin Coras99368312018-08-02 10:45:44 -07002430 svm_msg_q_msg_t *msg;
Florin Coras54693d22018-07-17 10:46:29 -07002431 session_event_t *e;
Florin Coras86f04502018-09-12 16:08:01 -07002432 u32 i;
Florin Coras54693d22018-07-17 10:46:29 -07002433
Florin Coras54693d22018-07-17 10:46:29 -07002434 if (svm_msg_q_is_empty (mq))
Dave Wallace4878cbe2017-11-21 03:45:09 -05002435 {
Florin Coras54693d22018-07-17 10:46:29 -07002436 if (*bits_set)
Florin Coras5398dfb2021-01-25 20:31:27 -08002437 return 0;
Dave Wallace4878cbe2017-11-21 03:45:09 -05002438
Florin Coras54693d22018-07-17 10:46:29 -07002439 if (!time_to_wait)
Florin Coras5398dfb2021-01-25 20:31:27 -08002440 return 0;
Florin Coras54693d22018-07-17 10:46:29 -07002441 else if (time_to_wait < 0)
Florin Coras5398dfb2021-01-25 20:31:27 -08002442 svm_msg_q_wait (mq, SVM_MQ_WAIT_EMPTY);
Florin Coras54693d22018-07-17 10:46:29 -07002443 else
2444 {
2445 if (svm_msg_q_timedwait (mq, time_to_wait))
Florin Coras5398dfb2021-01-25 20:31:27 -08002446 return 0;
Dave Wallace4878cbe2017-11-21 03:45:09 -05002447 }
2448 }
Florin Corase003a1b2019-06-05 10:47:16 -07002449 vcl_mq_dequeue_batch (wrk, mq, ~0);
Florin Coras54693d22018-07-17 10:46:29 -07002450
Florin Coras134a9962018-08-28 11:32:04 -07002451 for (i = 0; i < vec_len (wrk->mq_msg_vector); i++)
Florin Coras54693d22018-07-17 10:46:29 -07002452 {
Florin Coras134a9962018-08-28 11:32:04 -07002453 msg = vec_elt_at_index (wrk->mq_msg_vector, i);
Florin Coras99368312018-08-02 10:45:44 -07002454 e = svm_msg_q_msg_data (mq, msg);
Florin Coras86f04502018-09-12 16:08:01 -07002455 vcl_select_handle_mq_event (wrk, e, n_bits, read_map, write_map,
2456 except_map, bits_set);
Florin Coras99368312018-08-02 10:45:44 -07002457 svm_msg_q_free_msg (mq, msg);
Florin Coras54693d22018-07-17 10:46:29 -07002458 }
Florin Coras134a9962018-08-28 11:32:04 -07002459 vec_reset_length (wrk->mq_msg_vector);
Florin Coras30e79c22019-01-02 19:31:22 -08002460 vcl_handle_pending_wrk_updates (wrk);
Florin Coras54693d22018-07-17 10:46:29 -07002461 return *bits_set;
Dave Wallace543852a2017-08-03 02:11:34 -04002462}
2463
Florin Coras99368312018-08-02 10:45:44 -07002464static int
Florin Coras294afe22019-01-07 17:49:17 -08002465vppcom_select_condvar (vcl_worker_t * wrk, int n_bits,
2466 vcl_si_set * read_map, vcl_si_set * write_map,
2467 vcl_si_set * except_map, double time_to_wait,
Florin Coras134a9962018-08-28 11:32:04 -07002468 u32 * bits_set)
Florin Coras99368312018-08-02 10:45:44 -07002469{
Florin Coras14ed6df2019-03-06 21:13:42 -08002470 double wait = 0, start = 0;
2471
2472 if (!*bits_set)
2473 {
2474 wait = time_to_wait;
2475 start = clib_time_now (&wrk->clib_time);
2476 }
2477
2478 do
2479 {
2480 vcl_select_handle_mq (wrk, wrk->app_event_queue, n_bits, read_map,
2481 write_map, except_map, wait, bits_set);
2482 if (*bits_set)
2483 return *bits_set;
2484 if (wait == -1)
2485 continue;
2486
2487 wait = wait - (clib_time_now (&wrk->clib_time) - start);
2488 }
2489 while (wait > 0);
2490
2491 return 0;
Florin Coras99368312018-08-02 10:45:44 -07002492}
2493
2494static int
Florin Coras294afe22019-01-07 17:49:17 -08002495vppcom_select_eventfd (vcl_worker_t * wrk, int n_bits,
2496 vcl_si_set * read_map, vcl_si_set * write_map,
2497 vcl_si_set * except_map, double time_to_wait,
Florin Coras134a9962018-08-28 11:32:04 -07002498 u32 * bits_set)
Florin Coras99368312018-08-02 10:45:44 -07002499{
2500 vcl_mq_evt_conn_t *mqc;
2501 int __clib_unused n_read;
2502 int n_mq_evts, i;
2503 u64 buf;
2504
Filip Tehlar8ccc6b32022-02-02 17:38:20 +00002505 if (PREDICT_FALSE (wrk->api_client_handle == ~0))
2506 {
2507 vcl_api_retry_attach (wrk);
2508 return 0;
2509 }
2510
Florin Coras134a9962018-08-28 11:32:04 -07002511 vec_validate (wrk->mq_events, pool_elts (wrk->mq_evt_conns));
2512 n_mq_evts = epoll_wait (wrk->mqs_epfd, wrk->mq_events,
2513 vec_len (wrk->mq_events), time_to_wait);
Florin Coras99368312018-08-02 10:45:44 -07002514 for (i = 0; i < n_mq_evts; i++)
2515 {
Filip Tehlar8ccc6b32022-02-02 17:38:20 +00002516 if (PREDICT_FALSE (wrk->mq_events[i].data.u32 == ~0))
2517 {
2518 vcl_api_handle_disconnect (wrk);
2519 continue;
2520 }
2521
Florin Coras134a9962018-08-28 11:32:04 -07002522 mqc = vcl_mq_evt_conn_get (wrk, wrk->mq_events[i].data.u32);
Florin Coras99368312018-08-02 10:45:44 -07002523 n_read = read (mqc->mq_fd, &buf, sizeof (buf));
Florin Coras134a9962018-08-28 11:32:04 -07002524 vcl_select_handle_mq (wrk, mqc->mq, n_bits, read_map, write_map,
Florin Coras99368312018-08-02 10:45:44 -07002525 except_map, 0, bits_set);
2526 }
2527
2528 return (n_mq_evts > 0 ? (int) *bits_set : 0);
2529}
2530
Dave Wallace543852a2017-08-03 02:11:34 -04002531int
Florin Coras294afe22019-01-07 17:49:17 -08002532vppcom_select (int n_bits, vcl_si_set * read_map, vcl_si_set * write_map,
2533 vcl_si_set * except_map, double time_to_wait)
Dave Wallace543852a2017-08-03 02:11:34 -04002534{
Florin Coras54693d22018-07-17 10:46:29 -07002535 u32 sid, minbits = clib_max (n_bits, BITS (uword)), bits_set = 0;
Florin Coras134a9962018-08-28 11:32:04 -07002536 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras096a1d52021-01-27 15:33:51 -08002537 vcl_session_t *s = 0;
Florin Corasf49cf472020-04-19 23:12:08 +00002538 int i;
Dave Wallace543852a2017-08-03 02:11:34 -04002539
Dave Wallace7876d392017-10-19 03:53:57 -04002540 if (n_bits && read_map)
Dave Wallace543852a2017-08-03 02:11:34 -04002541 {
Florin Coras134a9962018-08-28 11:32:04 -07002542 clib_bitmap_validate (wrk->rd_bitmap, minbits);
Dave Barach178cf492018-11-13 16:34:13 -05002543 clib_memcpy_fast (wrk->rd_bitmap, read_map,
Florin Coras294afe22019-01-07 17:49:17 -08002544 vec_len (wrk->rd_bitmap) * sizeof (vcl_si_set));
2545 memset (read_map, 0, vec_len (wrk->rd_bitmap) * sizeof (vcl_si_set));
Dave Wallace543852a2017-08-03 02:11:34 -04002546 }
Dave Wallace7876d392017-10-19 03:53:57 -04002547 if (n_bits && write_map)
Dave Wallace543852a2017-08-03 02:11:34 -04002548 {
Florin Coras134a9962018-08-28 11:32:04 -07002549 clib_bitmap_validate (wrk->wr_bitmap, minbits);
Dave Barach178cf492018-11-13 16:34:13 -05002550 clib_memcpy_fast (wrk->wr_bitmap, write_map,
Florin Coras294afe22019-01-07 17:49:17 -08002551 vec_len (wrk->wr_bitmap) * sizeof (vcl_si_set));
2552 memset (write_map, 0, vec_len (wrk->wr_bitmap) * sizeof (vcl_si_set));
Dave Wallace543852a2017-08-03 02:11:34 -04002553 }
Dave Wallace7876d392017-10-19 03:53:57 -04002554 if (n_bits && except_map)
Dave Wallace543852a2017-08-03 02:11:34 -04002555 {
Florin Coras134a9962018-08-28 11:32:04 -07002556 clib_bitmap_validate (wrk->ex_bitmap, minbits);
Dave Barach178cf492018-11-13 16:34:13 -05002557 clib_memcpy_fast (wrk->ex_bitmap, except_map,
Florin Coras294afe22019-01-07 17:49:17 -08002558 vec_len (wrk->ex_bitmap) * sizeof (vcl_si_set));
2559 memset (except_map, 0, vec_len (wrk->ex_bitmap) * sizeof (vcl_si_set));
Dave Wallace543852a2017-08-03 02:11:34 -04002560 }
2561
Florin Coras54693d22018-07-17 10:46:29 -07002562 if (!n_bits)
2563 return 0;
2564
2565 if (!write_map)
2566 goto check_rd;
2567
Florin Coras096a1d52021-01-27 15:33:51 -08002568 clib_bitmap_foreach (sid, wrk->wr_bitmap)
2569 {
2570 if (!(s = vcl_session_get (wrk, sid)))
2571 {
2572 clib_bitmap_set_no_check ((uword *) write_map, sid, 1);
2573 bits_set++;
2574 continue;
2575 }
Florin Coras54693d22018-07-17 10:46:29 -07002576
Florin Coras096a1d52021-01-27 15:33:51 -08002577 if (vcl_session_write_ready (s))
2578 {
2579 clib_bitmap_set_no_check ((uword *) write_map, sid, 1);
2580 bits_set++;
2581 }
2582 else
2583 {
2584 svm_fifo_t *txf = vcl_session_is_ct (s) ? s->ct_tx_fifo : s->tx_fifo;
2585 svm_fifo_add_want_deq_ntf (txf, SVM_FIFO_WANT_DEQ_NOTIF);
2586 }
2587 }
Florin Coras54693d22018-07-17 10:46:29 -07002588
2589check_rd:
2590 if (!read_map)
2591 goto check_mq;
Florin Coras99368312018-08-02 10:45:44 -07002592
Florin Coras096a1d52021-01-27 15:33:51 -08002593 clib_bitmap_foreach (sid, wrk->rd_bitmap)
2594 {
2595 if (!(s = vcl_session_get (wrk, sid)))
2596 {
2597 clib_bitmap_set_no_check ((uword *) read_map, sid, 1);
2598 bits_set++;
2599 continue;
2600 }
Florin Coras54693d22018-07-17 10:46:29 -07002601
Florin Coras096a1d52021-01-27 15:33:51 -08002602 if (vcl_session_read_ready (s))
2603 {
2604 clib_bitmap_set_no_check ((uword *) read_map, sid, 1);
2605 bits_set++;
2606 }
2607 }
Florin Coras54693d22018-07-17 10:46:29 -07002608
2609check_mq:
Dave Wallace543852a2017-08-03 02:11:34 -04002610
Florin Coras86f04502018-09-12 16:08:01 -07002611 for (i = 0; i < vec_len (wrk->unhandled_evts_vector); i++)
2612 {
2613 vcl_select_handle_mq_event (wrk, &wrk->unhandled_evts_vector[i], n_bits,
2614 read_map, write_map, except_map, &bits_set);
2615 }
2616 vec_reset_length (wrk->unhandled_evts_vector);
2617
Florin Coras99368312018-08-02 10:45:44 -07002618 if (vcm->cfg.use_mq_eventfd)
Florin Coras134a9962018-08-28 11:32:04 -07002619 vppcom_select_eventfd (wrk, n_bits, read_map, write_map, except_map,
Florin Coras99368312018-08-02 10:45:44 -07002620 time_to_wait, &bits_set);
2621 else
Florin Coras134a9962018-08-28 11:32:04 -07002622 vppcom_select_condvar (wrk, n_bits, read_map, write_map, except_map,
Florin Coras99368312018-08-02 10:45:44 -07002623 time_to_wait, &bits_set);
Florin Coras54693d22018-07-17 10:46:29 -07002624
Dave Wallace543852a2017-08-03 02:11:34 -04002625 return (bits_set);
2626}
2627
Dave Wallacef7f809c2017-10-03 01:48:42 -04002628static inline void
Florin Coras7e5e62b2019-07-30 14:08:23 -07002629vep_verify_epoll_chain (vcl_worker_t * wrk, u32 vep_handle)
Dave Wallacef7f809c2017-10-03 01:48:42 -04002630{
Dave Wallacef7f809c2017-10-03 01:48:42 -04002631 vppcom_epoll_t *vep;
Florin Coras7e5e62b2019-07-30 14:08:23 -07002632 u32 sh = vep_handle;
Florin Coras6c3b2182020-10-19 18:36:48 -07002633 vcl_session_t *s;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002634
Florin Corasc0737e92019-03-04 14:19:39 -08002635 if (VPPCOM_DEBUG <= 2)
Dave Wallacef7f809c2017-10-03 01:48:42 -04002636 return;
2637
Florin Coras6c3b2182020-10-19 18:36:48 -07002638 s = vcl_session_get_w_handle (wrk, vep_handle);
2639 if (PREDICT_FALSE (!s))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002640 {
Florin Coras7e5e62b2019-07-30 14:08:23 -07002641 VDBG (0, "ERROR: Invalid vep_sh (%u)!", vep_handle);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002642 goto done;
2643 }
Florin Coras6c3b2182020-10-19 18:36:48 -07002644 if (PREDICT_FALSE (!(s->flags & VCL_SESSION_F_IS_VEP)))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002645 {
Florin Coras7e5e62b2019-07-30 14:08:23 -07002646 VDBG (0, "ERROR: vep_sh (%u) is not a vep!", vep_handle);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002647 goto done;
2648 }
Florin Coras6c3b2182020-10-19 18:36:48 -07002649 vep = &s->vep;
Florin Coras7e5e62b2019-07-30 14:08:23 -07002650 VDBG (0, "vep_sh (%u): Dumping epoll chain\n"
Florin Coras5e062572019-03-14 19:07:51 -07002651 "{\n"
2652 " is_vep = %u\n"
2653 " is_vep_session = %u\n"
Florin Coras7e5e62b2019-07-30 14:08:23 -07002654 " next_sh = 0x%x (%u)\n"
Florin Coras6c3b2182020-10-19 18:36:48 -07002655 "}\n", vep_handle, s->flags & VCL_SESSION_F_IS_VEP,
2656 s->flags & VCL_SESSION_F_IS_VEP_SESSION, vep->next_sh, vep->next_sh);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002657
Florin Coras7e5e62b2019-07-30 14:08:23 -07002658 for (sh = vep->next_sh; sh != ~0; sh = vep->next_sh)
Dave Wallacef7f809c2017-10-03 01:48:42 -04002659 {
Florin Coras6c3b2182020-10-19 18:36:48 -07002660 s = vcl_session_get_w_handle (wrk, sh);
2661 if (PREDICT_FALSE (!s))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002662 {
Florin Coras7e5e62b2019-07-30 14:08:23 -07002663 VDBG (0, "ERROR: Invalid sh (%u)!", sh);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002664 goto done;
2665 }
Florin Coras6c3b2182020-10-19 18:36:48 -07002666 if (PREDICT_FALSE (s->flags & VCL_SESSION_F_IS_VEP))
Florin Coras5e062572019-03-14 19:07:51 -07002667 {
Florin Coras7e5e62b2019-07-30 14:08:23 -07002668 VDBG (0, "ERROR: sh (%u) is a vep!", vep_handle);
Florin Coras5e062572019-03-14 19:07:51 -07002669 }
Florin Coras6c3b2182020-10-19 18:36:48 -07002670 else if (PREDICT_FALSE (!(s->flags & VCL_SESSION_F_IS_VEP_SESSION)))
Dave Wallace4878cbe2017-11-21 03:45:09 -05002671 {
Florin Coras7e5e62b2019-07-30 14:08:23 -07002672 VDBG (0, "ERROR: sh (%u) is not a vep session handle!", sh);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002673 goto done;
2674 }
Florin Coras6c3b2182020-10-19 18:36:48 -07002675 vep = &s->vep;
Florin Coras7e5e62b2019-07-30 14:08:23 -07002676 if (PREDICT_FALSE (vep->vep_sh != vep_handle))
2677 VDBG (0, "ERROR: session (%u) vep_sh (%u) != vep_sh (%u)!",
Florin Coras6c3b2182020-10-19 18:36:48 -07002678 sh, s->vep.vep_sh, vep_handle);
2679 if (s->flags & VCL_SESSION_F_IS_VEP_SESSION)
Dave Wallace4878cbe2017-11-21 03:45:09 -05002680 {
Florin Coras7e5e62b2019-07-30 14:08:23 -07002681 VDBG (0, "vep_sh[%u]: sh 0x%x (%u)\n"
Florin Coras5e062572019-03-14 19:07:51 -07002682 "{\n"
Florin Coras7e5e62b2019-07-30 14:08:23 -07002683 " next_sh = 0x%x (%u)\n"
2684 " prev_sh = 0x%x (%u)\n"
2685 " vep_sh = 0x%x (%u)\n"
Florin Coras5e062572019-03-14 19:07:51 -07002686 " ev.events = 0x%x\n"
2687 " ev.data.u64 = 0x%llx\n"
2688 " et_mask = 0x%x\n"
2689 "}\n",
Florin Coras7e5e62b2019-07-30 14:08:23 -07002690 vep_handle, sh, sh, vep->next_sh, vep->next_sh, vep->prev_sh,
Florin Coras5e062572019-03-14 19:07:51 -07002691 vep->prev_sh, vep->vep_sh, vep->vep_sh, vep->ev.events,
2692 vep->ev.data.u64, vep->et_mask);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002693 }
2694 }
Dave Wallacef7f809c2017-10-03 01:48:42 -04002695
2696done:
Florin Coras7e5e62b2019-07-30 14:08:23 -07002697 VDBG (0, "vep_sh (%u): Dump complete!\n", vep_handle);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002698}
2699
2700int
2701vppcom_epoll_create (void)
2702{
Florin Coras134a9962018-08-28 11:32:04 -07002703 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras7e12d942018-06-27 14:32:43 -07002704 vcl_session_t *vep_session;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002705
Florin Coras134a9962018-08-28 11:32:04 -07002706 vep_session = vcl_session_alloc (wrk);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002707
Florin Coras6c3b2182020-10-19 18:36:48 -07002708 vep_session->flags |= VCL_SESSION_F_IS_VEP;
Florin Coras134a9962018-08-28 11:32:04 -07002709 vep_session->vep.vep_sh = ~0;
2710 vep_session->vep.next_sh = ~0;
2711 vep_session->vep.prev_sh = ~0;
Dave Wallace4878cbe2017-11-21 03:45:09 -05002712 vep_session->vpp_handle = ~0;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002713
Florin Corasa7a1a222018-12-30 17:11:31 -08002714 vcl_evt (VCL_EVT_EPOLL_CREATE, vep_session, vep_session->session_index);
2715 VDBG (0, "Created vep_idx %u", vep_session->session_index);
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002716
Florin Corasab2f6db2018-08-31 14:31:41 -07002717 return vcl_session_handle (vep_session);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002718}
2719
2720int
Florin Coras134a9962018-08-28 11:32:04 -07002721vppcom_epoll_ctl (uint32_t vep_handle, int op, uint32_t session_handle,
Dave Wallacef7f809c2017-10-03 01:48:42 -04002722 struct epoll_event *event)
2723{
Florin Coras134a9962018-08-28 11:32:04 -07002724 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras87f76002021-06-28 19:13:29 -07002725 int rv = VPPCOM_OK, add_evt = 0;
Florin Coras7e12d942018-06-27 14:32:43 -07002726 vcl_session_t *vep_session;
Florin Coras17ec5772020-08-12 20:46:29 -07002727 vcl_session_t *s;
2728 svm_fifo_t *txf;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002729
Florin Coras134a9962018-08-28 11:32:04 -07002730 if (vep_handle == session_handle)
Dave Wallacef7f809c2017-10-03 01:48:42 -04002731 {
Florin Corasa7a1a222018-12-30 17:11:31 -08002732 VDBG (0, "vep_sh == session handle (%u)!", vep_handle);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002733 return VPPCOM_EINVAL;
2734 }
2735
Florin Coras134a9962018-08-28 11:32:04 -07002736 vep_session = vcl_session_get_w_handle (wrk, vep_handle);
Florin Coras070453d2018-08-24 17:04:27 -07002737 if (PREDICT_FALSE (!vep_session))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002738 {
Florin Corasa7a1a222018-12-30 17:11:31 -08002739 VDBG (0, "Invalid vep_sh (%u)!", vep_handle);
Florin Coras070453d2018-08-24 17:04:27 -07002740 return VPPCOM_EBADFD;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002741 }
Florin Coras6c3b2182020-10-19 18:36:48 -07002742 if (PREDICT_FALSE (!(vep_session->flags & VCL_SESSION_F_IS_VEP)))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002743 {
Florin Corasa7a1a222018-12-30 17:11:31 -08002744 VDBG (0, "vep_sh (%u) is not a vep!", vep_handle);
Florin Coras070453d2018-08-24 17:04:27 -07002745 return VPPCOM_EINVAL;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002746 }
2747
Florin Coras134a9962018-08-28 11:32:04 -07002748 ASSERT (vep_session->vep.vep_sh == ~0);
2749 ASSERT (vep_session->vep.prev_sh == ~0);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002750
Florin Coras17ec5772020-08-12 20:46:29 -07002751 s = vcl_session_get_w_handle (wrk, session_handle);
2752 if (PREDICT_FALSE (!s))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002753 {
Florin Corasa7a1a222018-12-30 17:11:31 -08002754 VDBG (0, "Invalid session_handle (%u)!", session_handle);
Florin Coras070453d2018-08-24 17:04:27 -07002755 return VPPCOM_EBADFD;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002756 }
Florin Coras6c3b2182020-10-19 18:36:48 -07002757 if (PREDICT_FALSE (s->flags & VCL_SESSION_F_IS_VEP))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002758 {
Florin Corasa7a1a222018-12-30 17:11:31 -08002759 VDBG (0, "session_handle (%u) is a vep!", vep_handle);
Florin Coras070453d2018-08-24 17:04:27 -07002760 return VPPCOM_EINVAL;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002761 }
2762
2763 switch (op)
2764 {
2765 case EPOLL_CTL_ADD:
2766 if (PREDICT_FALSE (!event))
2767 {
Florin Corasa7a1a222018-12-30 17:11:31 -08002768 VDBG (0, "EPOLL_CTL_ADD: NULL pointer to epoll_event structure!");
Florin Coras070453d2018-08-24 17:04:27 -07002769 return VPPCOM_EINVAL;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002770 }
Florin Coras2645f682021-06-04 15:59:41 -07002771 if (s->flags & VCL_SESSION_F_IS_VEP_SESSION)
2772 {
2773 VDBG (0, "EPOLL_CTL_ADD: %u already epolled!", s->session_index);
2774 rv = VPPCOM_EEXIST;
2775 goto done;
2776 }
Florin Coras134a9962018-08-28 11:32:04 -07002777 if (vep_session->vep.next_sh != ~0)
Dave Wallacef7f809c2017-10-03 01:48:42 -04002778 {
Florin Coras7e12d942018-06-27 14:32:43 -07002779 vcl_session_t *next_session;
Florin Corasab2f6db2018-08-31 14:31:41 -07002780 next_session = vcl_session_get_w_handle (wrk,
2781 vep_session->vep.next_sh);
Florin Coras070453d2018-08-24 17:04:27 -07002782 if (PREDICT_FALSE (!next_session))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002783 {
Florin Coras5e062572019-03-14 19:07:51 -07002784 VDBG (0, "EPOLL_CTL_ADD: Invalid vep.next_sh (%u) on "
Florin Corasa7a1a222018-12-30 17:11:31 -08002785 "vep_idx (%u)!", vep_session->vep.next_sh, vep_handle);
Florin Coras070453d2018-08-24 17:04:27 -07002786 return VPPCOM_EBADFD;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002787 }
Florin Coras134a9962018-08-28 11:32:04 -07002788 ASSERT (next_session->vep.prev_sh == vep_handle);
2789 next_session->vep.prev_sh = session_handle;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002790 }
Florin Coras17ec5772020-08-12 20:46:29 -07002791 s->vep.next_sh = vep_session->vep.next_sh;
2792 s->vep.prev_sh = vep_handle;
2793 s->vep.vep_sh = vep_handle;
2794 s->vep.et_mask = VEP_DEFAULT_ET_MASK;
Florin Corasfa3884f2021-06-22 20:04:46 -07002795 s->vep.lt_next = VCL_INVALID_SESSION_INDEX;
Florin Coras17ec5772020-08-12 20:46:29 -07002796 s->vep.ev = *event;
Florin Coras6c3b2182020-10-19 18:36:48 -07002797 s->flags &= ~VCL_SESSION_F_IS_VEP;
2798 s->flags |= VCL_SESSION_F_IS_VEP_SESSION;
Florin Coras134a9962018-08-28 11:32:04 -07002799 vep_session->vep.next_sh = session_handle;
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002800
Florin Coras17ec5772020-08-12 20:46:29 -07002801 txf = vcl_session_is_ct (s) ? s->ct_tx_fifo : s->tx_fifo;
2802 if (txf && (event->events & EPOLLOUT))
2803 svm_fifo_add_want_deq_ntf (txf, SVM_FIFO_WANT_DEQ_NOTIF_IF_FULL);
Florin Coras1bcad5c2019-01-09 20:04:38 -08002804
Florin Coras6e3c1f82020-01-15 01:30:46 +00002805 /* Generate EPOLLOUT if tx fifo not full */
Florin Coras17ec5772020-08-12 20:46:29 -07002806 if ((event->events & EPOLLOUT) && (vcl_session_write_ready (s) > 0))
hanlin475c9d72019-12-26 11:44:28 +08002807 {
2808 session_event_t e = { 0 };
2809 e.event_type = SESSION_IO_EVT_TX;
Florin Coras17ec5772020-08-12 20:46:29 -07002810 e.session_index = s->session_index;
hanlin475c9d72019-12-26 11:44:28 +08002811 vec_add1 (wrk->unhandled_evts_vector, e);
Florin Coras87f76002021-06-28 19:13:29 -07002812 add_evt = 1;
hanlin475c9d72019-12-26 11:44:28 +08002813 }
Florin Coras6e3c1f82020-01-15 01:30:46 +00002814 /* Generate EPOLLIN if rx fifo has data */
Florin Coras17ec5772020-08-12 20:46:29 -07002815 if ((event->events & EPOLLIN) && (vcl_session_read_ready (s) > 0))
Florin Coras6e3c1f82020-01-15 01:30:46 +00002816 {
2817 session_event_t e = { 0 };
2818 e.event_type = SESSION_IO_EVT_RX;
Florin Coras17ec5772020-08-12 20:46:29 -07002819 e.session_index = s->session_index;
Florin Coras6e3c1f82020-01-15 01:30:46 +00002820 vec_add1 (wrk->unhandled_evts_vector, e);
Florin Coras87f76002021-06-28 19:13:29 -07002821 s->flags &= ~VCL_SESSION_F_HAS_RX_EVT;
2822 add_evt = 1;
2823 }
2824 if (!add_evt && vcl_session_is_closing (s))
2825 {
2826 session_event_t e = { 0 };
2827 if (s->session_state == VCL_STATE_VPP_CLOSING)
2828 e.event_type = SESSION_CTRL_EVT_DISCONNECTED;
2829 else
2830 e.event_type = SESSION_CTRL_EVT_RESET;
2831 e.session_index = s->session_index;
2832 e.postponed = 1;
2833 vec_add1 (wrk->unhandled_evts_vector, e);
Florin Coras6e3c1f82020-01-15 01:30:46 +00002834 }
Florin Corasa7a1a222018-12-30 17:11:31 -08002835 VDBG (1, "EPOLL_CTL_ADD: vep_sh %u, sh %u, events 0x%x, data 0x%llx!",
2836 vep_handle, session_handle, event->events, event->data.u64);
Florin Coras17ec5772020-08-12 20:46:29 -07002837 vcl_evt (VCL_EVT_EPOLL_CTLADD, s, event->events, event->data.u64);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002838 break;
2839
2840 case EPOLL_CTL_MOD:
2841 if (PREDICT_FALSE (!event))
2842 {
Florin Corasa7a1a222018-12-30 17:11:31 -08002843 VDBG (0, "EPOLL_CTL_MOD: NULL pointer to epoll_event structure!");
Dave Wallacef7f809c2017-10-03 01:48:42 -04002844 rv = VPPCOM_EINVAL;
2845 goto done;
2846 }
Florin Coras6c3b2182020-10-19 18:36:48 -07002847 else if (PREDICT_FALSE (!(s->flags & VCL_SESSION_F_IS_VEP_SESSION)))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002848 {
Florin Coras5e062572019-03-14 19:07:51 -07002849 VDBG (0, "sh %u EPOLL_CTL_MOD: not a vep session!", session_handle);
Florin Coras2645f682021-06-04 15:59:41 -07002850 rv = VPPCOM_ENOENT;
Dave Wallace4878cbe2017-11-21 03:45:09 -05002851 goto done;
2852 }
Florin Coras17ec5772020-08-12 20:46:29 -07002853 else if (PREDICT_FALSE (s->vep.vep_sh != vep_handle))
Dave Wallace4878cbe2017-11-21 03:45:09 -05002854 {
Florin Corasa7a1a222018-12-30 17:11:31 -08002855 VDBG (0, "EPOLL_CTL_MOD: sh %u vep_sh (%u) != vep_sh (%u)!",
Florin Coras17ec5772020-08-12 20:46:29 -07002856 session_handle, s->vep.vep_sh, vep_handle);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002857 rv = VPPCOM_EINVAL;
2858 goto done;
2859 }
hanlin475c9d72019-12-26 11:44:28 +08002860
Florin Coras2645f682021-06-04 15:59:41 -07002861 /* Generate EPOLLOUT if session write ready nd event was not on */
2862 if ((event->events & EPOLLOUT) && !(s->vep.ev.events & EPOLLOUT) &&
2863 (vcl_session_write_ready (s) > 0))
hanlin475c9d72019-12-26 11:44:28 +08002864 {
2865 session_event_t e = { 0 };
2866 e.event_type = SESSION_IO_EVT_TX;
Florin Coras17ec5772020-08-12 20:46:29 -07002867 e.session_index = s->session_index;
hanlin475c9d72019-12-26 11:44:28 +08002868 vec_add1 (wrk->unhandled_evts_vector, e);
2869 }
Florin Coras2645f682021-06-04 15:59:41 -07002870 /* Generate EPOLLIN if session read ready and event was not on */
2871 if ((event->events & EPOLLIN) && !(s->vep.ev.events & EPOLLIN) &&
2872 (vcl_session_read_ready (s) > 0))
2873 {
2874 session_event_t e = { 0 };
2875 e.event_type = SESSION_IO_EVT_RX;
2876 e.session_index = s->session_index;
2877 vec_add1 (wrk->unhandled_evts_vector, e);
Florin Coras87f76002021-06-28 19:13:29 -07002878 s->flags &= ~VCL_SESSION_F_HAS_RX_EVT;
Florin Coras2645f682021-06-04 15:59:41 -07002879 }
Florin Coras17ec5772020-08-12 20:46:29 -07002880 s->vep.et_mask = VEP_DEFAULT_ET_MASK;
2881 s->vep.ev = *event;
2882 txf = vcl_session_is_ct (s) ? s->ct_tx_fifo : s->tx_fifo;
Florin Coras8fb22fd2021-02-17 17:35:32 -08002883 if (txf)
2884 {
2885 if (event->events & EPOLLOUT)
2886 svm_fifo_add_want_deq_ntf (txf, SVM_FIFO_WANT_DEQ_NOTIF_IF_FULL);
2887 else
2888 svm_fifo_del_want_deq_ntf (txf, SVM_FIFO_WANT_DEQ_NOTIF_IF_FULL);
2889 }
Florin Corasa7a1a222018-12-30 17:11:31 -08002890 VDBG (1, "EPOLL_CTL_MOD: vep_sh %u, sh %u, events 0x%x, data 0x%llx!",
2891 vep_handle, session_handle, event->events, event->data.u64);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002892 break;
2893
2894 case EPOLL_CTL_DEL:
Florin Coras6c3b2182020-10-19 18:36:48 -07002895 if (PREDICT_FALSE (!(s->flags & VCL_SESSION_F_IS_VEP_SESSION)))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002896 {
Florin Corasa7a1a222018-12-30 17:11:31 -08002897 VDBG (0, "EPOLL_CTL_DEL: %u not a vep session!", session_handle);
Florin Coras2645f682021-06-04 15:59:41 -07002898 rv = VPPCOM_ENOENT;
Dave Wallace4878cbe2017-11-21 03:45:09 -05002899 goto done;
2900 }
Florin Coras17ec5772020-08-12 20:46:29 -07002901 else if (PREDICT_FALSE (s->vep.vep_sh != vep_handle))
Dave Wallace4878cbe2017-11-21 03:45:09 -05002902 {
Florin Corasa7a1a222018-12-30 17:11:31 -08002903 VDBG (0, "EPOLL_CTL_DEL: sh %u vep_sh (%u) != vep_sh (%u)!",
Florin Coras17ec5772020-08-12 20:46:29 -07002904 session_handle, s->vep.vep_sh, vep_handle);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002905 rv = VPPCOM_EINVAL;
2906 goto done;
2907 }
2908
Florin Coras17ec5772020-08-12 20:46:29 -07002909 if (s->vep.prev_sh == vep_handle)
2910 vep_session->vep.next_sh = s->vep.next_sh;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002911 else
2912 {
Florin Coras7e12d942018-06-27 14:32:43 -07002913 vcl_session_t *prev_session;
Florin Coras17ec5772020-08-12 20:46:29 -07002914 prev_session = vcl_session_get_w_handle (wrk, s->vep.prev_sh);
Florin Coras070453d2018-08-24 17:04:27 -07002915 if (PREDICT_FALSE (!prev_session))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002916 {
Florin Coras5e062572019-03-14 19:07:51 -07002917 VDBG (0, "EPOLL_CTL_DEL: Invalid prev_sh (%u) on sh (%u)!",
Florin Coras17ec5772020-08-12 20:46:29 -07002918 s->vep.prev_sh, session_handle);
Florin Coras070453d2018-08-24 17:04:27 -07002919 return VPPCOM_EBADFD;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002920 }
Florin Coras134a9962018-08-28 11:32:04 -07002921 ASSERT (prev_session->vep.next_sh == session_handle);
Florin Coras17ec5772020-08-12 20:46:29 -07002922 prev_session->vep.next_sh = s->vep.next_sh;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002923 }
Florin Coras17ec5772020-08-12 20:46:29 -07002924 if (s->vep.next_sh != ~0)
Dave Wallacef7f809c2017-10-03 01:48:42 -04002925 {
Florin Coras7e12d942018-06-27 14:32:43 -07002926 vcl_session_t *next_session;
Florin Coras17ec5772020-08-12 20:46:29 -07002927 next_session = vcl_session_get_w_handle (wrk, s->vep.next_sh);
Florin Coras070453d2018-08-24 17:04:27 -07002928 if (PREDICT_FALSE (!next_session))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002929 {
Florin Coras5e062572019-03-14 19:07:51 -07002930 VDBG (0, "EPOLL_CTL_DEL: Invalid next_sh (%u) on sh (%u)!",
Florin Coras17ec5772020-08-12 20:46:29 -07002931 s->vep.next_sh, session_handle);
Florin Coras070453d2018-08-24 17:04:27 -07002932 return VPPCOM_EBADFD;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002933 }
Florin Coras134a9962018-08-28 11:32:04 -07002934 ASSERT (next_session->vep.prev_sh == session_handle);
Florin Coras17ec5772020-08-12 20:46:29 -07002935 next_session->vep.prev_sh = s->vep.prev_sh;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002936 }
2937
Florin Corasfa3884f2021-06-22 20:04:46 -07002938 if (s->vep.lt_next != VCL_INVALID_SESSION_INDEX)
2939 vcl_epoll_lt_del (wrk, s);
2940
Florin Coras17ec5772020-08-12 20:46:29 -07002941 memset (&s->vep, 0, sizeof (s->vep));
2942 s->vep.next_sh = ~0;
2943 s->vep.prev_sh = ~0;
2944 s->vep.vep_sh = ~0;
Florin Corasfa3884f2021-06-22 20:04:46 -07002945 s->vep.lt_next = VCL_INVALID_SESSION_INDEX;
Florin Coras6c3b2182020-10-19 18:36:48 -07002946 s->flags &= ~VCL_SESSION_F_IS_VEP_SESSION;
Florin Coras1bcad5c2019-01-09 20:04:38 -08002947
Florin Corasf1ddeeb2021-06-10 08:08:53 -07002948 if (vcl_session_is_open (s))
2949 {
2950 txf = vcl_session_is_ct (s) ? s->ct_tx_fifo : s->tx_fifo;
2951 if (txf)
2952 svm_fifo_del_want_deq_ntf (txf, SVM_FIFO_WANT_DEQ_NOTIF_IF_FULL);
2953 }
Florin Coras1bcad5c2019-01-09 20:04:38 -08002954
Florin Coras5e062572019-03-14 19:07:51 -07002955 VDBG (1, "EPOLL_CTL_DEL: vep_idx %u, sh %u!", vep_handle,
Florin Corasa7a1a222018-12-30 17:11:31 -08002956 session_handle);
Florin Coras17ec5772020-08-12 20:46:29 -07002957 vcl_evt (VCL_EVT_EPOLL_CTLDEL, s, vep_sh);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002958 break;
2959
2960 default:
Florin Corasa7a1a222018-12-30 17:11:31 -08002961 VDBG (0, "Invalid operation (%d)!", op);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002962 rv = VPPCOM_EINVAL;
2963 }
2964
Florin Coras134a9962018-08-28 11:32:04 -07002965 vep_verify_epoll_chain (wrk, vep_handle);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002966
2967done:
Dave Wallacef7f809c2017-10-03 01:48:42 -04002968 return rv;
2969}
2970
Florin Coras86f04502018-09-12 16:08:01 -07002971static inline void
2972vcl_epoll_wait_handle_mq_event (vcl_worker_t * wrk, session_event_t * e,
2973 struct epoll_event *events, u32 * num_ev)
Florin Coras54693d22018-07-17 10:46:29 -07002974{
2975 session_disconnected_msg_t *disconnected_msg;
2976 session_connected_msg_t *connected_msg;
Florin Coras99368312018-08-02 10:45:44 -07002977 u32 sid = ~0, session_events;
Florin Coras3c7d4f92018-12-14 11:28:43 -08002978 u64 session_evt_data = ~0;
Florin Corasb242d312020-10-26 15:35:40 -07002979 vcl_session_t *s;
Florin Coras86f04502018-09-12 16:08:01 -07002980 u8 add_event = 0;
2981
2982 switch (e->event_type)
2983 {
Florin Coras653e43f2019-03-04 10:56:23 -08002984 case SESSION_IO_EVT_RX:
Florin Corasc0737e92019-03-04 14:19:39 -08002985 sid = e->session_index;
Florin Corasb242d312020-10-26 15:35:40 -07002986 s = vcl_session_get (wrk, sid);
2987 if (vcl_session_is_closed (s))
Florin Corasfa915f82018-12-26 16:29:06 -08002988 break;
Florin Corasb242d312020-10-26 15:35:40 -07002989 vcl_fifo_rx_evt_valid_or_break (s);
2990 session_events = s->vep.ev.events;
Florin Coras99e41452021-08-31 13:29:41 -07002991 if (!(EPOLLIN & s->vep.ev.events) ||
2992 (s->flags & VCL_SESSION_F_HAS_RX_EVT) ||
2993 (s->vep.lt_next != VCL_INVALID_SESSION_INDEX))
Florin Coras86f04502018-09-12 16:08:01 -07002994 break;
2995 add_event = 1;
wanghanlin9e42cc22021-06-25 17:40:13 +08002996 events[*num_ev].events = EPOLLIN;
Florin Corasb242d312020-10-26 15:35:40 -07002997 session_evt_data = s->vep.ev.data.u64;
2998 s->flags |= VCL_SESSION_F_HAS_RX_EVT;
Florin Coras86f04502018-09-12 16:08:01 -07002999 break;
Florin Coras653e43f2019-03-04 10:56:23 -08003000 case SESSION_IO_EVT_TX:
Florin Corasc0737e92019-03-04 14:19:39 -08003001 sid = e->session_index;
Florin Corasb242d312020-10-26 15:35:40 -07003002 s = vcl_session_get (wrk, sid);
Florin Corasf0fe1ea2021-12-03 17:03:37 -08003003 if (!s || !vcl_session_is_open (s))
Florin Corasfa915f82018-12-26 16:29:06 -08003004 break;
Florin Corasb242d312020-10-26 15:35:40 -07003005 session_events = s->vep.ev.events;
Florin Coras86f04502018-09-12 16:08:01 -07003006 if (!(EPOLLOUT & session_events))
3007 break;
3008 add_event = 1;
wanghanlin9e42cc22021-06-25 17:40:13 +08003009 events[*num_ev].events = EPOLLOUT;
Florin Corasb242d312020-10-26 15:35:40 -07003010 session_evt_data = s->vep.ev.data.u64;
3011 svm_fifo_reset_has_deq_ntf (vcl_session_is_ct (s) ?
3012 s->ct_tx_fifo : s->tx_fifo);
Florin Coras86f04502018-09-12 16:08:01 -07003013 break;
Florin Coras86f04502018-09-12 16:08:01 -07003014 case SESSION_CTRL_EVT_ACCEPTED:
Florin Corasb242d312020-10-26 15:35:40 -07003015 if (!e->postponed)
3016 s = vcl_session_accepted (wrk, (session_accepted_msg_t *) e->data);
3017 else
3018 s = vcl_session_get (wrk, e->session_index);
3019 if (!s)
Florin Coras3c7d4f92018-12-14 11:28:43 -08003020 break;
Florin Corasb242d312020-10-26 15:35:40 -07003021 session_events = s->vep.ev.events;
3022 sid = s->session_index;
liuyacancba87102021-09-10 15:14:05 +08003023 if (!(EPOLLIN & session_events) ||
3024 (s->vep.lt_next != VCL_INVALID_SESSION_INDEX))
Florin Coras86f04502018-09-12 16:08:01 -07003025 break;
Florin Coras86f04502018-09-12 16:08:01 -07003026 add_event = 1;
wanghanlin9e42cc22021-06-25 17:40:13 +08003027 events[*num_ev].events = EPOLLIN;
Florin Corasb242d312020-10-26 15:35:40 -07003028 session_evt_data = s->vep.ev.data.u64;
Florin Coras86f04502018-09-12 16:08:01 -07003029 break;
3030 case SESSION_CTRL_EVT_CONNECTED:
Florin Corasb242d312020-10-26 15:35:40 -07003031 if (!e->postponed)
3032 {
3033 connected_msg = (session_connected_msg_t *) e->data;
3034 sid = vcl_session_connected_handler (wrk, connected_msg);
3035 }
3036 else
3037 sid = e->session_index;
3038 s = vcl_session_get (wrk, sid);
3039 if (vcl_session_is_closed (s))
Florin Corasfa915f82018-12-26 16:29:06 -08003040 break;
Florin Corasb242d312020-10-26 15:35:40 -07003041 session_events = s->vep.ev.events;
3042 /* Generate EPOLLOUT because there's no connected event */
Florin Coras72f77822019-01-22 19:05:52 -08003043 if (!(EPOLLOUT & session_events))
3044 break;
3045 add_event = 1;
wanghanlin9e42cc22021-06-25 17:40:13 +08003046 events[*num_ev].events = EPOLLOUT;
Florin Corasb242d312020-10-26 15:35:40 -07003047 session_evt_data = s->vep.ev.data.u64;
3048 if (s->session_state == VCL_STATE_DETACHED)
Florin Corasdbc9c592019-09-25 16:37:43 -07003049 events[*num_ev].events |= EPOLLHUP;
Florin Coras86f04502018-09-12 16:08:01 -07003050 break;
3051 case SESSION_CTRL_EVT_DISCONNECTED:
Florin Coras87f76002021-06-28 19:13:29 -07003052 if (!e->postponed)
3053 {
3054 disconnected_msg = (session_disconnected_msg_t *) e->data;
3055 s = vcl_session_disconnected_handler (wrk, disconnected_msg);
3056 }
3057 else
3058 {
3059 s = vcl_session_get (wrk, e->session_index);
Florin Corasf0fe1ea2021-12-03 17:03:37 -08003060 s->flags &= ~VCL_SESSION_F_PENDING_DISCONNECT;
Florin Coras87f76002021-06-28 19:13:29 -07003061 }
3062 if (vcl_session_is_closed (s) ||
3063 !(s->flags & VCL_SESSION_F_IS_VEP_SESSION))
Florin Corasf0fe1ea2021-12-03 17:03:37 -08003064 {
Florin Coras74254b52021-12-08 11:03:08 -08003065 if (s && (s->flags & VCL_SESSION_F_PENDING_FREE))
Florin Corasf0fe1ea2021-12-03 17:03:37 -08003066 vcl_session_free (wrk, s);
3067 break;
3068 }
Florin Corasb242d312020-10-26 15:35:40 -07003069 sid = s->session_index;
3070 session_events = s->vep.ev.events;
Florin Coras86f04502018-09-12 16:08:01 -07003071 add_event = 1;
liuyacanffd9ddb2021-11-01 10:22:09 +08003072 if (EPOLLRDHUP & session_events)
3073 {
3074 /* If app can distinguish between RDHUP and HUP,
3075 * we make finer control */
3076 events[*num_ev].events = EPOLLRDHUP;
3077 if (s->flags & VCL_SESSION_F_WR_SHUTDOWN)
3078 {
3079 events[*num_ev].events |= EPOLLHUP;
3080 }
3081 }
3082 else
3083 {
3084 events[*num_ev].events = EPOLLHUP;
3085 }
Florin Corasb242d312020-10-26 15:35:40 -07003086 session_evt_data = s->vep.ev.data.u64;
liuyacanffd9ddb2021-11-01 10:22:09 +08003087
Florin Coras86f04502018-09-12 16:08:01 -07003088 break;
3089 case SESSION_CTRL_EVT_RESET:
Florin Coras87f76002021-06-28 19:13:29 -07003090 if (!e->postponed)
Florin Corasf0fe1ea2021-12-03 17:03:37 -08003091 {
3092 sid =
3093 vcl_session_reset_handler (wrk, (session_reset_msg_t *) e->data);
3094 s = vcl_session_get (wrk, sid);
3095 }
Florin Coras87f76002021-06-28 19:13:29 -07003096 else
Florin Corasf0fe1ea2021-12-03 17:03:37 -08003097 {
3098 sid = e->session_index;
3099 s = vcl_session_get (wrk, sid);
3100 s->flags &= ~VCL_SESSION_F_PENDING_DISCONNECT;
3101 }
Florin Coras87f76002021-06-28 19:13:29 -07003102 if (vcl_session_is_closed (s) ||
3103 !(s->flags & VCL_SESSION_F_IS_VEP_SESSION))
Florin Corasf0fe1ea2021-12-03 17:03:37 -08003104 {
Florin Coras74254b52021-12-08 11:03:08 -08003105 if (s && (s->flags & VCL_SESSION_F_PENDING_FREE))
Florin Corasf0fe1ea2021-12-03 17:03:37 -08003106 vcl_session_free (wrk, s);
3107 break;
3108 }
Florin Corasb242d312020-10-26 15:35:40 -07003109 session_events = s->vep.ev.events;
Florin Coras86f04502018-09-12 16:08:01 -07003110 add_event = 1;
wanghanlin9e42cc22021-06-25 17:40:13 +08003111 events[*num_ev].events = EPOLLHUP | EPOLLRDHUP;
Florin Corasb242d312020-10-26 15:35:40 -07003112 session_evt_data = s->vep.ev.data.u64;
Florin Coras86f04502018-09-12 16:08:01 -07003113 break;
Florin Corasdfae9f92019-02-20 19:48:31 -08003114 case SESSION_CTRL_EVT_UNLISTEN_REPLY:
3115 vcl_session_unlisten_reply_handler (wrk, e->data);
3116 break;
Florin Coras68b7e582020-01-21 18:33:23 -08003117 case SESSION_CTRL_EVT_MIGRATED:
3118 vcl_session_migrated_handler (wrk, e->data);
3119 break;
Florin Coras9ace36d2019-10-28 13:14:17 -07003120 case SESSION_CTRL_EVT_CLEANUP:
3121 vcl_session_cleanup_handler (wrk, e->data);
3122 break;
Florin Coras30e79c22019-01-02 19:31:22 -08003123 case SESSION_CTRL_EVT_REQ_WORKER_UPDATE:
3124 vcl_session_req_worker_update_handler (wrk, e->data);
3125 break;
3126 case SESSION_CTRL_EVT_WORKER_UPDATE_REPLY:
3127 vcl_session_worker_update_reply_handler (wrk, e->data);
3128 break;
Florin Corasc4c4cf52019-08-24 18:17:34 -07003129 case SESSION_CTRL_EVT_APP_ADD_SEGMENT:
3130 vcl_session_app_add_segment_handler (wrk, e->data);
3131 break;
3132 case SESSION_CTRL_EVT_APP_DEL_SEGMENT:
3133 vcl_session_app_del_segment_handler (wrk, e->data);
3134 break;
hanlina3a48962020-07-13 11:09:15 +08003135 case SESSION_CTRL_EVT_APP_WRK_RPC:
Florin Coras40c07ce2020-07-16 20:46:17 -07003136 vcl_worker_rpc_handler (wrk, e->data);
3137 break;
Florin Coras86f04502018-09-12 16:08:01 -07003138 default:
3139 VDBG (0, "unhandled: %u", e->event_type);
3140 break;
3141 }
3142
3143 if (add_event)
3144 {
3145 events[*num_ev].data.u64 = session_evt_data;
3146 if (EPOLLONESHOT & session_events)
3147 {
Florin Corasb242d312020-10-26 15:35:40 -07003148 s = vcl_session_get (wrk, sid);
3149 s->vep.ev.events = 0;
Florin Coras86f04502018-09-12 16:08:01 -07003150 }
Florin Corasfa3884f2021-06-22 20:04:46 -07003151 else if (!(EPOLLET & session_events))
Florin Corasfe286f72021-06-04 10:07:55 -07003152 {
Florin Corasfa3884f2021-06-22 20:04:46 -07003153 s = vcl_session_get (wrk, sid);
3154 if (s->vep.lt_next == VCL_INVALID_SESSION_INDEX)
3155 vcl_epoll_lt_add (wrk, s);
Florin Corasfe286f72021-06-04 10:07:55 -07003156 }
Florin Coras86f04502018-09-12 16:08:01 -07003157 *num_ev += 1;
3158 }
3159}
3160
3161static int
3162vcl_epoll_wait_handle_mq (vcl_worker_t * wrk, svm_msg_q_t * mq,
3163 struct epoll_event *events, u32 maxevents,
3164 double wait_for_time, u32 * num_ev)
3165{
Florin Coras99368312018-08-02 10:45:44 -07003166 svm_msg_q_msg_t *msg;
Florin Coras54693d22018-07-17 10:46:29 -07003167 session_event_t *e;
Florin Coras54693d22018-07-17 10:46:29 -07003168 int i;
3169
Florin Coras539663c2018-09-28 14:59:37 -07003170 if (vec_len (wrk->mq_msg_vector) && svm_msg_q_is_empty (mq))
3171 goto handle_dequeued;
3172
Florin Coras54693d22018-07-17 10:46:29 -07003173 if (svm_msg_q_is_empty (mq))
3174 {
3175 if (!wait_for_time)
Florin Coras5398dfb2021-01-25 20:31:27 -08003176 return 0;
Florin Coras54693d22018-07-17 10:46:29 -07003177 else if (wait_for_time < 0)
Florin Coras5398dfb2021-01-25 20:31:27 -08003178 svm_msg_q_wait (mq, SVM_MQ_WAIT_EMPTY);
Florin Coras54693d22018-07-17 10:46:29 -07003179 else
3180 {
Florin Coras60f1fc12018-08-16 14:57:31 -07003181 if (svm_msg_q_timedwait (mq, wait_for_time / 1e3))
Florin Coras5398dfb2021-01-25 20:31:27 -08003182 return 0;
Florin Coras54693d22018-07-17 10:46:29 -07003183 }
3184 }
Florin Corase003a1b2019-06-05 10:47:16 -07003185 ASSERT (maxevents > *num_ev);
hanlind0e646f2020-05-11 22:20:37 +08003186 vcl_mq_dequeue_batch (wrk, mq, ~0);
Florin Coras54693d22018-07-17 10:46:29 -07003187
Florin Coras539663c2018-09-28 14:59:37 -07003188handle_dequeued:
Florin Coras134a9962018-08-28 11:32:04 -07003189 for (i = 0; i < vec_len (wrk->mq_msg_vector); i++)
Florin Coras54693d22018-07-17 10:46:29 -07003190 {
Florin Coras134a9962018-08-28 11:32:04 -07003191 msg = vec_elt_at_index (wrk->mq_msg_vector, i);
Florin Coras99368312018-08-02 10:45:44 -07003192 e = svm_msg_q_msg_data (mq, msg);
hanlind0e646f2020-05-11 22:20:37 +08003193 if (*num_ev < maxevents)
3194 vcl_epoll_wait_handle_mq_event (wrk, e, events, num_ev);
3195 else
3196 vcl_handle_mq_event (wrk, e);
Florin Coras99368312018-08-02 10:45:44 -07003197 svm_msg_q_free_msg (mq, msg);
Florin Coras54693d22018-07-17 10:46:29 -07003198 }
Florin Corasaa27eb92018-10-13 12:20:01 -07003199 vec_reset_length (wrk->mq_msg_vector);
Florin Coras30e79c22019-01-02 19:31:22 -08003200 vcl_handle_pending_wrk_updates (wrk);
Florin Coras54693d22018-07-17 10:46:29 -07003201 return *num_ev;
3202}
3203
Florin Coras99368312018-08-02 10:45:44 -07003204static int
Florin Corasccdb8b82021-04-28 13:01:06 -07003205vppcom_epoll_wait_condvar (vcl_worker_t *wrk, struct epoll_event *events,
3206 int maxevents, u32 n_evts, double timeout_ms)
Florin Coras99368312018-08-02 10:45:44 -07003207{
Florin Corasccdb8b82021-04-28 13:01:06 -07003208 double end = -1;
Florin Coras14ed6df2019-03-06 21:13:42 -08003209
3210 if (!n_evts)
3211 {
Florin Corasccdb8b82021-04-28 13:01:06 -07003212 if (timeout_ms > 0)
3213 end = clib_time_now (&wrk->clib_time) + (timeout_ms / 1e3);
Florin Coras14ed6df2019-03-06 21:13:42 -08003214 }
3215
3216 do
3217 {
3218 vcl_epoll_wait_handle_mq (wrk, wrk->app_event_queue, events, maxevents,
Florin Corasccdb8b82021-04-28 13:01:06 -07003219 timeout_ms, &n_evts);
3220 if (n_evts || !timeout_ms)
Florin Coras14ed6df2019-03-06 21:13:42 -08003221 return n_evts;
Florin Coras14ed6df2019-03-06 21:13:42 -08003222 }
Florin Corasccdb8b82021-04-28 13:01:06 -07003223 while (end == -1 || clib_time_now (&wrk->clib_time) < end);
Florin Coras14ed6df2019-03-06 21:13:42 -08003224
3225 return 0;
Florin Coras99368312018-08-02 10:45:44 -07003226}
3227
3228static int
Florin Corasccdb8b82021-04-28 13:01:06 -07003229vppcom_epoll_wait_eventfd (vcl_worker_t *wrk, struct epoll_event *events,
3230 int maxevents, u32 n_evts, double timeout_ms)
Florin Coras99368312018-08-02 10:45:44 -07003231{
Florin Coras99368312018-08-02 10:45:44 -07003232 int __clib_unused n_read;
Florin Corasb13ba132021-01-27 16:05:24 -08003233 vcl_mq_evt_conn_t *mqc;
Florin Coras99368312018-08-02 10:45:44 -07003234 int n_mq_evts, i;
Florin Corasccdb8b82021-04-28 13:01:06 -07003235 double end = -1;
Florin Coras99368312018-08-02 10:45:44 -07003236 u64 buf;
3237
Filip Tehlar8ccc6b32022-02-02 17:38:20 +00003238 if (PREDICT_FALSE (wrk->api_client_handle == ~0))
3239 {
3240 vcl_api_retry_attach (wrk);
3241 return n_evts;
3242 }
3243
Florin Coras134a9962018-08-28 11:32:04 -07003244 vec_validate (wrk->mq_events, pool_elts (wrk->mq_evt_conns));
Florin Corasb13ba132021-01-27 16:05:24 -08003245 if (!n_evts)
Florin Coras99368312018-08-02 10:45:44 -07003246 {
Florin Corasccdb8b82021-04-28 13:01:06 -07003247 if (timeout_ms > 0)
3248 end = clib_time_now (&wrk->clib_time) + (timeout_ms / 1e3);
Florin Coras99368312018-08-02 10:45:44 -07003249 }
3250
Florin Corasb13ba132021-01-27 16:05:24 -08003251 do
3252 {
3253 n_mq_evts = epoll_wait (wrk->mqs_epfd, wrk->mq_events,
Florin Corasccdb8b82021-04-28 13:01:06 -07003254 vec_len (wrk->mq_events), timeout_ms);
Florin Corasb13ba132021-01-27 16:05:24 -08003255 if (n_mq_evts < 0)
3256 {
3257 VDBG (0, "epoll_wait error %u", errno);
3258 return n_evts;
3259 }
3260
3261 for (i = 0; i < n_mq_evts; i++)
3262 {
Filip Tehlar8ccc6b32022-02-02 17:38:20 +00003263 if (PREDICT_FALSE (wrk->mq_events[i].data.u32 == ~0))
3264 {
3265 /* api socket was closed */
3266 vcl_api_handle_disconnect (wrk);
3267 continue;
3268 }
3269
Florin Corasb13ba132021-01-27 16:05:24 -08003270 mqc = vcl_mq_evt_conn_get (wrk, wrk->mq_events[i].data.u32);
3271 n_read = read (mqc->mq_fd, &buf, sizeof (buf));
3272 vcl_epoll_wait_handle_mq (wrk, mqc->mq, events, maxevents, 0,
3273 &n_evts);
3274 }
3275
Florin Corasccdb8b82021-04-28 13:01:06 -07003276 if (n_evts || !timeout_ms)
Florin Corasb13ba132021-01-27 16:05:24 -08003277 return n_evts;
Florin Corasb13ba132021-01-27 16:05:24 -08003278 }
Florin Corasccdb8b82021-04-28 13:01:06 -07003279 while (end == -1 || clib_time_now (&wrk->clib_time) < end);
Florin Corasb13ba132021-01-27 16:05:24 -08003280
3281 return 0;
Florin Coras99368312018-08-02 10:45:44 -07003282}
3283
Florin Corasfe286f72021-06-04 10:07:55 -07003284static void
Florin Corasfe286f72021-06-04 10:07:55 -07003285vcl_epoll_wait_handle_lt (vcl_worker_t *wrk, struct epoll_event *events,
3286 int maxevents, u32 *n_evts)
3287{
Florin Coras734268f2021-06-30 07:54:29 -07003288 u32 add_event = 0, next;
Florin Corasfe286f72021-06-04 10:07:55 -07003289 vcl_session_t *s;
3290 u64 evt_data;
Florin Corasfa3884f2021-06-22 20:04:46 -07003291 int rv;
Florin Corasfe286f72021-06-04 10:07:55 -07003292
Florin Corasfa3884f2021-06-22 20:04:46 -07003293 ASSERT (wrk->ep_lt_current != VCL_INVALID_SESSION_INDEX);
Florin Corasfe286f72021-06-04 10:07:55 -07003294 if (*n_evts >= maxevents)
Florin Corasfa3884f2021-06-22 20:04:46 -07003295 return;
Florin Corasfe286f72021-06-04 10:07:55 -07003296
Florin Corasfa3884f2021-06-22 20:04:46 -07003297 next = wrk->ep_lt_current;
3298 do
Florin Corasfe286f72021-06-04 10:07:55 -07003299 {
Florin Corasfa3884f2021-06-22 20:04:46 -07003300 s = vcl_session_get (wrk, next);
3301 next = s->vep.lt_next;
3302
3303 if ((s->vep.ev.events & EPOLLIN) && (rv = vcl_session_read_ready (s)))
Florin Corasfe286f72021-06-04 10:07:55 -07003304 {
3305 add_event = 1;
Florin Corasfa3884f2021-06-22 20:04:46 -07003306 events[*n_evts].events |= rv > 0 ? EPOLLIN : EPOLLHUP | EPOLLRDHUP;
Florin Corasfe286f72021-06-04 10:07:55 -07003307 evt_data = s->vep.ev.data.u64;
3308 }
Florin Corasfa3884f2021-06-22 20:04:46 -07003309 if ((s->vep.ev.events & EPOLLOUT) && (rv = vcl_session_write_ready (s)))
Florin Corasfe286f72021-06-04 10:07:55 -07003310 {
3311 add_event = 1;
Florin Corasfa3884f2021-06-22 20:04:46 -07003312 events[*n_evts].events |= rv > 0 ? EPOLLOUT : EPOLLHUP | EPOLLRDHUP;
3313 evt_data = s->vep.ev.data.u64;
3314 }
3315 if (!add_event && s->session_state > VCL_STATE_READY)
3316 {
3317 add_event = 1;
3318 events[*n_evts].events |= EPOLLHUP | EPOLLRDHUP;
Florin Corasfe286f72021-06-04 10:07:55 -07003319 evt_data = s->vep.ev.data.u64;
3320 }
3321 if (add_event)
3322 {
3323 events[*n_evts].data.u64 = evt_data;
3324 *n_evts += 1;
3325 add_event = 0;
Florin Corasfa3884f2021-06-22 20:04:46 -07003326 if (EPOLLONESHOT & s->vep.ev.events)
3327 s->vep.ev.events = 0;
Florin Corasfe286f72021-06-04 10:07:55 -07003328 if (*n_evts == maxevents)
3329 {
Florin Corasfa3884f2021-06-22 20:04:46 -07003330 wrk->ep_lt_current = next;
Florin Corasfe286f72021-06-04 10:07:55 -07003331 break;
3332 }
3333 }
Florin Corasfa3884f2021-06-22 20:04:46 -07003334 else
3335 {
3336 vcl_epoll_lt_del (wrk, s);
3337 if (wrk->ep_lt_current == VCL_INVALID_SESSION_INDEX)
3338 break;
3339 }
Florin Corasfe286f72021-06-04 10:07:55 -07003340 }
Florin Corasfa3884f2021-06-22 20:04:46 -07003341 while (next != wrk->ep_lt_current);
Florin Corasfe286f72021-06-04 10:07:55 -07003342}
3343
Dave Wallacef7f809c2017-10-03 01:48:42 -04003344int
Florin Coras134a9962018-08-28 11:32:04 -07003345vppcom_epoll_wait (uint32_t vep_handle, struct epoll_event *events,
Dave Wallacef7f809c2017-10-03 01:48:42 -04003346 int maxevents, double wait_for_time)
3347{
Florin Coras134a9962018-08-28 11:32:04 -07003348 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras7e12d942018-06-27 14:32:43 -07003349 vcl_session_t *vep_session;
Florin Corasfa3884f2021-06-22 20:04:46 -07003350 u32 n_evts = 0;
Florin Coras86f04502018-09-12 16:08:01 -07003351 int i;
Dave Wallacef7f809c2017-10-03 01:48:42 -04003352
3353 if (PREDICT_FALSE (maxevents <= 0))
3354 {
Florin Coras5e062572019-03-14 19:07:51 -07003355 VDBG (0, "ERROR: Invalid maxevents (%d)!", maxevents);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003356 return VPPCOM_EINVAL;
3357 }
Dave Wallacef7f809c2017-10-03 01:48:42 -04003358
Florin Coras134a9962018-08-28 11:32:04 -07003359 vep_session = vcl_session_get_w_handle (wrk, vep_handle);
Florin Coras14598772018-09-04 19:47:52 -07003360 if (!vep_session)
3361 return VPPCOM_EBADFD;
3362
Florin Coras6c3b2182020-10-19 18:36:48 -07003363 if (PREDICT_FALSE (!(vep_session->flags & VCL_SESSION_F_IS_VEP)))
Dave Wallacef7f809c2017-10-03 01:48:42 -04003364 {
Florin Coras5e062572019-03-14 19:07:51 -07003365 VDBG (0, "ERROR: vep_idx (%u) is not a vep!", vep_handle);
Florin Coras54693d22018-07-17 10:46:29 -07003366 return VPPCOM_EINVAL;
Dave Wallacef7f809c2017-10-03 01:48:42 -04003367 }
Florin Coras54693d22018-07-17 10:46:29 -07003368
Florin Coras86f04502018-09-12 16:08:01 -07003369 if (vec_len (wrk->unhandled_evts_vector))
3370 {
3371 for (i = 0; i < vec_len (wrk->unhandled_evts_vector); i++)
3372 {
3373 vcl_epoll_wait_handle_mq_event (wrk, &wrk->unhandled_evts_vector[i],
3374 events, &n_evts);
3375 if (n_evts == maxevents)
3376 {
Florin Corase003a1b2019-06-05 10:47:16 -07003377 vec_delete (wrk->unhandled_evts_vector, i + 1, 0);
3378 return n_evts;
Florin Coras86f04502018-09-12 16:08:01 -07003379 }
3380 }
Florin Corase003a1b2019-06-05 10:47:16 -07003381 vec_reset_length (wrk->unhandled_evts_vector);
Florin Coras86f04502018-09-12 16:08:01 -07003382 }
liuyacancba87102021-09-10 15:14:05 +08003383
3384 if (PREDICT_FALSE (wrk->ep_lt_current != VCL_INVALID_SESSION_INDEX))
3385 vcl_epoll_wait_handle_lt (wrk, events, maxevents, &n_evts);
3386
wanghanlin8919fec2021-03-18 20:00:41 +08003387 /* Request to only drain unhandled */
3388 if ((int) wait_for_time == -2)
3389 return n_evts;
Florin Coras86f04502018-09-12 16:08:01 -07003390
Florin Coras86f04502018-09-12 16:08:01 -07003391
Florin Corasfe286f72021-06-04 10:07:55 -07003392 if (vcm->cfg.use_mq_eventfd)
3393 n_evts = vppcom_epoll_wait_eventfd (wrk, events, maxevents, n_evts,
3394 wait_for_time);
3395 else
3396 n_evts = vppcom_epoll_wait_condvar (wrk, events, maxevents, n_evts,
3397 wait_for_time);
3398
Florin Corasfe286f72021-06-04 10:07:55 -07003399 return n_evts;
Dave Wallacef7f809c2017-10-03 01:48:42 -04003400}
3401
Dave Wallace35830af2017-10-09 01:43:42 -04003402int
Florin Coras134a9962018-08-28 11:32:04 -07003403vppcom_session_attr (uint32_t session_handle, uint32_t op,
Dave Wallace35830af2017-10-09 01:43:42 -04003404 void *buffer, uint32_t * buflen)
3405{
Florin Coras134a9962018-08-28 11:32:04 -07003406 vcl_worker_t *wrk = vcl_worker_get_current ();
liuyacan55c952e2021-06-13 14:54:55 +08003407 u32 *flags = buffer;
Steven2199aab2017-10-15 20:18:47 -07003408 vppcom_endpt_t *ep = buffer;
Florin Coras04ae8272021-04-12 19:55:37 -07003409 transport_endpt_attr_t tea;
Florin Corasa5a9efd2021-01-05 17:03:29 -08003410 vcl_session_t *session;
3411 int rv = VPPCOM_OK;
Dave Wallace35830af2017-10-09 01:43:42 -04003412
Florin Coras134a9962018-08-28 11:32:04 -07003413 session = vcl_session_get_w_handle (wrk, session_handle);
Florin Coras070453d2018-08-24 17:04:27 -07003414 if (!session)
3415 return VPPCOM_EBADFD;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003416
Dave Wallace35830af2017-10-09 01:43:42 -04003417 switch (op)
3418 {
3419 case VPPCOM_ATTR_GET_NREAD:
Florin Coras0ef8ef22019-01-18 08:37:13 -08003420 rv = vcl_session_read_ready (session);
Florin Coras5e062572019-03-14 19:07:51 -07003421 VDBG (2, "VPPCOM_ATTR_GET_NREAD: sh %u, nread = %d", session_handle,
3422 rv);
Dave Wallace35830af2017-10-09 01:43:42 -04003423 break;
3424
Dave Wallace227867f2017-11-13 21:21:53 -05003425 case VPPCOM_ATTR_GET_NWRITE:
Florin Coras0ef8ef22019-01-18 08:37:13 -08003426 rv = vcl_session_write_ready (session);
Florin Coras5e062572019-03-14 19:07:51 -07003427 VDBG (2, "VPPCOM_ATTR_GET_NWRITE: sh %u, nwrite = %d", session_handle,
3428 rv);
Dave Wallace35830af2017-10-09 01:43:42 -04003429 break;
3430
3431 case VPPCOM_ATTR_GET_FLAGS:
Dave Wallace048b1d62018-01-03 22:24:41 -05003432 if (PREDICT_TRUE (buffer && buflen && (*buflen >= sizeof (*flags))))
Dave Wallace35830af2017-10-09 01:43:42 -04003433 {
Simon Zhang53ec9672020-08-07 05:20:47 +08003434 *flags =
3435 O_RDWR |
Florin Corasac422d62020-10-19 20:51:36 -07003436 (vcl_session_has_attr (session, VCL_SESS_ATTR_NONBLOCK) ?
Simon Zhang53ec9672020-08-07 05:20:47 +08003437 O_NONBLOCK : 0);
Dave Wallace35830af2017-10-09 01:43:42 -04003438 *buflen = sizeof (*flags);
Florin Coras5e062572019-03-14 19:07:51 -07003439 VDBG (2, "VPPCOM_ATTR_GET_FLAGS: sh %u, flags = 0x%08x, "
3440 "is_nonblocking = %u", session_handle, *flags,
Florin Corasac422d62020-10-19 20:51:36 -07003441 vcl_session_has_attr (session, VCL_SESS_ATTR_NONBLOCK));
Dave Wallace35830af2017-10-09 01:43:42 -04003442 }
3443 else
3444 rv = VPPCOM_EINVAL;
3445 break;
3446
3447 case VPPCOM_ATTR_SET_FLAGS:
Dave Wallace048b1d62018-01-03 22:24:41 -05003448 if (PREDICT_TRUE (buffer && buflen && (*buflen == sizeof (*flags))))
Dave Wallace35830af2017-10-09 01:43:42 -04003449 {
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003450 if (*flags & O_NONBLOCK)
Florin Corasac422d62020-10-19 20:51:36 -07003451 vcl_session_set_attr (session, VCL_SESS_ATTR_NONBLOCK);
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003452 else
Florin Corasac422d62020-10-19 20:51:36 -07003453 vcl_session_clear_attr (session, VCL_SESS_ATTR_NONBLOCK);
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003454
Florin Coras5e062572019-03-14 19:07:51 -07003455 VDBG (2, "VPPCOM_ATTR_SET_FLAGS: sh %u, flags = 0x%08x,"
3456 " is_nonblocking = %u", session_handle, *flags,
Florin Corasac422d62020-10-19 20:51:36 -07003457 vcl_session_has_attr (session, VCL_SESS_ATTR_NONBLOCK));
Dave Wallace35830af2017-10-09 01:43:42 -04003458 }
3459 else
3460 rv = VPPCOM_EINVAL;
3461 break;
3462
3463 case VPPCOM_ATTR_GET_PEER_ADDR:
Dave Wallace048b1d62018-01-03 22:24:41 -05003464 if (PREDICT_TRUE (buffer && buflen &&
3465 (*buflen >= sizeof (*ep)) && ep->ip))
Dave Wallace35830af2017-10-09 01:43:42 -04003466 {
Florin Coras7e12d942018-06-27 14:32:43 -07003467 ep->is_ip4 = session->transport.is_ip4;
3468 ep->port = session->transport.rmt_port;
3469 if (session->transport.is_ip4)
Dave Barach178cf492018-11-13 16:34:13 -05003470 clib_memcpy_fast (ep->ip, &session->transport.rmt_ip.ip4,
3471 sizeof (ip4_address_t));
Steven2199aab2017-10-15 20:18:47 -07003472 else
Dave Barach178cf492018-11-13 16:34:13 -05003473 clib_memcpy_fast (ep->ip, &session->transport.rmt_ip.ip6,
3474 sizeof (ip6_address_t));
Steven2199aab2017-10-15 20:18:47 -07003475 *buflen = sizeof (*ep);
Florin Coras60687192021-11-29 21:00:47 -08003476 VDBG (1,
3477 "VPPCOM_ATTR_GET_PEER_ADDR: sh %u, is_ip4 = %u, "
3478 "addr = %U, port %u",
3479 session_handle, ep->is_ip4, vcl_format_ip46_address,
3480 &session->transport.rmt_ip,
Florin Coras0d427d82018-06-27 03:24:07 -07003481 ep->is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6,
3482 clib_net_to_host_u16 (ep->port));
Dave Wallace35830af2017-10-09 01:43:42 -04003483 }
3484 else
3485 rv = VPPCOM_EINVAL;
3486 break;
3487
3488 case VPPCOM_ATTR_GET_LCL_ADDR:
Dave Wallace048b1d62018-01-03 22:24:41 -05003489 if (PREDICT_TRUE (buffer && buflen &&
3490 (*buflen >= sizeof (*ep)) && ep->ip))
Dave Wallace35830af2017-10-09 01:43:42 -04003491 {
Florin Coras7e12d942018-06-27 14:32:43 -07003492 ep->is_ip4 = session->transport.is_ip4;
3493 ep->port = session->transport.lcl_port;
3494 if (session->transport.is_ip4)
Dave Barach178cf492018-11-13 16:34:13 -05003495 clib_memcpy_fast (ep->ip, &session->transport.lcl_ip.ip4,
3496 sizeof (ip4_address_t));
Steven2199aab2017-10-15 20:18:47 -07003497 else
Dave Barach178cf492018-11-13 16:34:13 -05003498 clib_memcpy_fast (ep->ip, &session->transport.lcl_ip.ip6,
3499 sizeof (ip6_address_t));
Steven2199aab2017-10-15 20:18:47 -07003500 *buflen = sizeof (*ep);
Florin Coras60687192021-11-29 21:00:47 -08003501 VDBG (1,
3502 "VPPCOM_ATTR_GET_LCL_ADDR: sh %u, is_ip4 = %u, addr = %U"
3503 " port %d",
3504 session_handle, ep->is_ip4, vcl_format_ip46_address,
Florin Coras7e12d942018-06-27 14:32:43 -07003505 &session->transport.lcl_ip,
Florin Coras0d427d82018-06-27 03:24:07 -07003506 ep->is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6,
3507 clib_net_to_host_u16 (ep->port));
Dave Wallace35830af2017-10-09 01:43:42 -04003508 }
3509 else
3510 rv = VPPCOM_EINVAL;
3511 break;
Stevenb5a11602017-10-11 09:59:30 -07003512
Florin Corasef7cbf62019-10-17 09:56:27 -07003513 case VPPCOM_ATTR_SET_LCL_ADDR:
3514 if (PREDICT_TRUE (buffer && buflen &&
3515 (*buflen >= sizeof (*ep)) && ep->ip))
3516 {
3517 session->transport.is_ip4 = ep->is_ip4;
3518 session->transport.lcl_port = ep->port;
3519 vcl_ip_copy_from_ep (&session->transport.lcl_ip, ep);
3520 *buflen = sizeof (*ep);
Florin Coras60687192021-11-29 21:00:47 -08003521 VDBG (1,
3522 "VPPCOM_ATTR_SET_LCL_ADDR: sh %u, is_ip4 = %u, addr = %U"
3523 " port %d",
3524 session_handle, ep->is_ip4, vcl_format_ip46_address,
Florin Corasef7cbf62019-10-17 09:56:27 -07003525 &session->transport.lcl_ip,
3526 ep->is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6,
3527 clib_net_to_host_u16 (ep->port));
3528 }
3529 else
3530 rv = VPPCOM_EINVAL;
3531 break;
3532
Dave Wallace048b1d62018-01-03 22:24:41 -05003533 case VPPCOM_ATTR_GET_LIBC_EPFD:
3534 rv = session->libc_epfd;
Florin Coras5e062572019-03-14 19:07:51 -07003535 VDBG (2, "VPPCOM_ATTR_GET_LIBC_EPFD: libc_epfd %d", rv);
Dave Wallace048b1d62018-01-03 22:24:41 -05003536 break;
3537
3538 case VPPCOM_ATTR_SET_LIBC_EPFD:
3539 if (PREDICT_TRUE (buffer && buflen &&
3540 (*buflen == sizeof (session->libc_epfd))))
3541 {
3542 session->libc_epfd = *(int *) buffer;
3543 *buflen = sizeof (session->libc_epfd);
3544
Florin Coras5e062572019-03-14 19:07:51 -07003545 VDBG (2, "VPPCOM_ATTR_SET_LIBC_EPFD: libc_epfd %d, buflen %d",
3546 session->libc_epfd, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003547 }
3548 else
3549 rv = VPPCOM_EINVAL;
3550 break;
3551
3552 case VPPCOM_ATTR_GET_PROTOCOL:
3553 if (buffer && buflen && (*buflen >= sizeof (int)))
3554 {
Florin Coras7e12d942018-06-27 14:32:43 -07003555 *(int *) buffer = session->session_type;
Dave Wallace048b1d62018-01-03 22:24:41 -05003556 *buflen = sizeof (int);
3557
Florin Coras5e062572019-03-14 19:07:51 -07003558 VDBG (2, "VPPCOM_ATTR_GET_PROTOCOL: %d (%s), buflen %d",
3559 *(int *) buffer, *(int *) buffer ? "UDP" : "TCP", *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003560 }
3561 else
3562 rv = VPPCOM_EINVAL;
3563 break;
3564
3565 case VPPCOM_ATTR_GET_LISTEN:
3566 if (buffer && buflen && (*buflen >= sizeof (int)))
3567 {
Florin Corasac422d62020-10-19 20:51:36 -07003568 *(int *) buffer = vcl_session_has_attr (session,
3569 VCL_SESS_ATTR_LISTEN);
Dave Wallace048b1d62018-01-03 22:24:41 -05003570 *buflen = sizeof (int);
3571
Florin Coras5e062572019-03-14 19:07:51 -07003572 VDBG (2, "VPPCOM_ATTR_GET_LISTEN: %d, buflen %d", *(int *) buffer,
3573 *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003574 }
3575 else
3576 rv = VPPCOM_EINVAL;
3577 break;
3578
3579 case VPPCOM_ATTR_GET_ERROR:
3580 if (buffer && buflen && (*buflen >= sizeof (int)))
3581 {
3582 *(int *) buffer = 0;
3583 *buflen = sizeof (int);
3584
Florin Coras5e062572019-03-14 19:07:51 -07003585 VDBG (2, "VPPCOM_ATTR_GET_ERROR: %d, buflen %d, #VPP-TBD#",
3586 *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003587 }
3588 else
3589 rv = VPPCOM_EINVAL;
3590 break;
3591
3592 case VPPCOM_ATTR_GET_TX_FIFO_LEN:
3593 if (buffer && buflen && (*buflen >= sizeof (u32)))
3594 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003595
3596 /* VPP-TBD */
3597 *(size_t *) buffer = (session->sndbuf_size ? session->sndbuf_size :
Florin Corasf22f4e52019-12-19 16:10:58 -08003598 session->tx_fifo ?
3599 svm_fifo_size (session->tx_fifo) :
Dave Wallace048b1d62018-01-03 22:24:41 -05003600 vcm->cfg.tx_fifo_size);
3601 *buflen = sizeof (u32);
3602
Florin Coras5e062572019-03-14 19:07:51 -07003603 VDBG (2, "VPPCOM_ATTR_GET_TX_FIFO_LEN: %u (0x%x), buflen %d,"
3604 " #VPP-TBD#", *(size_t *) buffer, *(size_t *) buffer,
3605 *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003606 }
3607 else
3608 rv = VPPCOM_EINVAL;
3609 break;
3610
Filip Tehlar2f09bfc2021-11-15 10:26:56 +00003611 case VPPCOM_ATTR_SET_DSCP:
3612 if (buffer && buflen && (*buflen >= sizeof (u8)))
3613 {
3614 session->dscp = *(u8 *) buffer;
3615
3616 VDBG (2, "VPPCOM_ATTR_SET_DSCP: %u (0x%x), buflen %d,",
3617 *(u8 *) buffer, *(u8 *) buffer, *buflen);
3618 }
3619 else
3620 rv = VPPCOM_EINVAL;
3621 break;
3622
Dave Wallace048b1d62018-01-03 22:24:41 -05003623 case VPPCOM_ATTR_SET_TX_FIFO_LEN:
3624 if (buffer && buflen && (*buflen == sizeof (u32)))
3625 {
3626 /* VPP-TBD */
3627 session->sndbuf_size = *(u32 *) buffer;
Florin Coras5e062572019-03-14 19:07:51 -07003628 VDBG (2, "VPPCOM_ATTR_SET_TX_FIFO_LEN: %u (0x%x), buflen %d,"
3629 " #VPP-TBD#", session->sndbuf_size, session->sndbuf_size,
3630 *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003631 }
3632 else
3633 rv = VPPCOM_EINVAL;
3634 break;
3635
3636 case VPPCOM_ATTR_GET_RX_FIFO_LEN:
3637 if (buffer && buflen && (*buflen >= sizeof (u32)))
3638 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003639
3640 /* VPP-TBD */
3641 *(size_t *) buffer = (session->rcvbuf_size ? session->rcvbuf_size :
Florin Corasf22f4e52019-12-19 16:10:58 -08003642 session->rx_fifo ?
3643 svm_fifo_size (session->rx_fifo) :
Dave Wallace048b1d62018-01-03 22:24:41 -05003644 vcm->cfg.rx_fifo_size);
3645 *buflen = sizeof (u32);
3646
Florin Coras5e062572019-03-14 19:07:51 -07003647 VDBG (2, "VPPCOM_ATTR_GET_RX_FIFO_LEN: %u (0x%x), buflen %d, "
3648 "#VPP-TBD#", *(size_t *) buffer, *(size_t *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003649 }
3650 else
3651 rv = VPPCOM_EINVAL;
3652 break;
3653
3654 case VPPCOM_ATTR_SET_RX_FIFO_LEN:
3655 if (buffer && buflen && (*buflen == sizeof (u32)))
3656 {
3657 /* VPP-TBD */
3658 session->rcvbuf_size = *(u32 *) buffer;
Florin Coras5e062572019-03-14 19:07:51 -07003659 VDBG (2, "VPPCOM_ATTR_SET_RX_FIFO_LEN: %u (0x%x), buflen %d,"
3660 " #VPP-TBD#", session->sndbuf_size, session->sndbuf_size,
3661 *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003662 }
3663 else
3664 rv = VPPCOM_EINVAL;
3665 break;
3666
3667 case VPPCOM_ATTR_GET_REUSEADDR:
3668 if (buffer && buflen && (*buflen >= sizeof (int)))
3669 {
3670 /* VPP-TBD */
Florin Corasac422d62020-10-19 20:51:36 -07003671 *(int *) buffer = vcl_session_has_attr (session,
3672 VCL_SESS_ATTR_REUSEADDR);
Dave Wallace048b1d62018-01-03 22:24:41 -05003673 *buflen = sizeof (int);
3674
Florin Coras5e062572019-03-14 19:07:51 -07003675 VDBG (2, "VPPCOM_ATTR_GET_REUSEADDR: %d, buflen %d, #VPP-TBD#",
3676 *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003677 }
3678 else
3679 rv = VPPCOM_EINVAL;
3680 break;
3681
Stevenb5a11602017-10-11 09:59:30 -07003682 case VPPCOM_ATTR_SET_REUSEADDR:
Dave Wallace048b1d62018-01-03 22:24:41 -05003683 if (buffer && buflen && (*buflen == sizeof (int)) &&
Florin Corasac422d62020-10-19 20:51:36 -07003684 !vcl_session_has_attr (session, VCL_SESS_ATTR_LISTEN))
Dave Wallace048b1d62018-01-03 22:24:41 -05003685 {
3686 /* VPP-TBD */
3687 if (*(int *) buffer)
Florin Corasac422d62020-10-19 20:51:36 -07003688 vcl_session_set_attr (session, VCL_SESS_ATTR_REUSEADDR);
Dave Wallace048b1d62018-01-03 22:24:41 -05003689 else
Florin Corasac422d62020-10-19 20:51:36 -07003690 vcl_session_clear_attr (session, VCL_SESS_ATTR_REUSEADDR);
Dave Wallace048b1d62018-01-03 22:24:41 -05003691
Florin Coras5e062572019-03-14 19:07:51 -07003692 VDBG (2, "VPPCOM_ATTR_SET_REUSEADDR: %d, buflen %d, #VPP-TBD#",
Florin Corasac422d62020-10-19 20:51:36 -07003693 vcl_session_has_attr (session, VCL_SESS_ATTR_REUSEADDR),
Florin Coras5e062572019-03-14 19:07:51 -07003694 *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003695 }
3696 else
3697 rv = VPPCOM_EINVAL;
3698 break;
3699
3700 case VPPCOM_ATTR_GET_REUSEPORT:
3701 if (buffer && buflen && (*buflen >= sizeof (int)))
3702 {
3703 /* VPP-TBD */
Florin Corasac422d62020-10-19 20:51:36 -07003704 *(int *) buffer = vcl_session_has_attr (session,
3705 VCL_SESS_ATTR_REUSEPORT);
Dave Wallace048b1d62018-01-03 22:24:41 -05003706 *buflen = sizeof (int);
3707
Florin Coras5e062572019-03-14 19:07:51 -07003708 VDBG (2, "VPPCOM_ATTR_GET_REUSEPORT: %d, buflen %d, #VPP-TBD#",
3709 *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003710 }
3711 else
3712 rv = VPPCOM_EINVAL;
3713 break;
3714
3715 case VPPCOM_ATTR_SET_REUSEPORT:
3716 if (buffer && buflen && (*buflen == sizeof (int)) &&
Florin Corasac422d62020-10-19 20:51:36 -07003717 !vcl_session_has_attr (session, VCL_SESS_ATTR_LISTEN))
Dave Wallace048b1d62018-01-03 22:24:41 -05003718 {
3719 /* VPP-TBD */
3720 if (*(int *) buffer)
Florin Corasac422d62020-10-19 20:51:36 -07003721 vcl_session_set_attr (session, VCL_SESS_ATTR_REUSEPORT);
Dave Wallace048b1d62018-01-03 22:24:41 -05003722 else
Florin Corasac422d62020-10-19 20:51:36 -07003723 vcl_session_clear_attr (session, VCL_SESS_ATTR_REUSEPORT);
Dave Wallace048b1d62018-01-03 22:24:41 -05003724
Florin Coras5e062572019-03-14 19:07:51 -07003725 VDBG (2, "VPPCOM_ATTR_SET_REUSEPORT: %d, buflen %d, #VPP-TBD#",
Florin Corasac422d62020-10-19 20:51:36 -07003726 vcl_session_has_attr (session, VCL_SESS_ATTR_REUSEPORT),
Florin Coras5e062572019-03-14 19:07:51 -07003727 *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003728 }
3729 else
3730 rv = VPPCOM_EINVAL;
3731 break;
3732
3733 case VPPCOM_ATTR_GET_BROADCAST:
3734 if (buffer && buflen && (*buflen >= sizeof (int)))
3735 {
3736 /* VPP-TBD */
Florin Corasac422d62020-10-19 20:51:36 -07003737 *(int *) buffer = vcl_session_has_attr (session,
3738 VCL_SESS_ATTR_BROADCAST);
Dave Wallace048b1d62018-01-03 22:24:41 -05003739 *buflen = sizeof (int);
3740
Florin Coras5e062572019-03-14 19:07:51 -07003741 VDBG (2, "VPPCOM_ATTR_GET_BROADCAST: %d, buflen %d, #VPP-TBD#",
3742 *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003743 }
3744 else
3745 rv = VPPCOM_EINVAL;
Stevenb5a11602017-10-11 09:59:30 -07003746 break;
3747
3748 case VPPCOM_ATTR_SET_BROADCAST:
Dave Wallace048b1d62018-01-03 22:24:41 -05003749 if (buffer && buflen && (*buflen == sizeof (int)))
3750 {
3751 /* VPP-TBD */
3752 if (*(int *) buffer)
Florin Corasac422d62020-10-19 20:51:36 -07003753 vcl_session_set_attr (session, VCL_SESS_ATTR_BROADCAST);
Dave Wallace048b1d62018-01-03 22:24:41 -05003754 else
Florin Corasac422d62020-10-19 20:51:36 -07003755 vcl_session_clear_attr (session, VCL_SESS_ATTR_BROADCAST);
Dave Wallace048b1d62018-01-03 22:24:41 -05003756
Florin Coras5e062572019-03-14 19:07:51 -07003757 VDBG (2, "VPPCOM_ATTR_SET_BROADCAST: %d, buflen %d, #VPP-TBD#",
Florin Corasac422d62020-10-19 20:51:36 -07003758 vcl_session_has_attr (session, VCL_SESS_ATTR_BROADCAST),
Florin Coras5e062572019-03-14 19:07:51 -07003759 *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003760 }
3761 else
3762 rv = VPPCOM_EINVAL;
3763 break;
3764
3765 case VPPCOM_ATTR_GET_V6ONLY:
3766 if (buffer && buflen && (*buflen >= sizeof (int)))
3767 {
3768 /* VPP-TBD */
Florin Corasac422d62020-10-19 20:51:36 -07003769 *(int *) buffer = vcl_session_has_attr (session,
3770 VCL_SESS_ATTR_V6ONLY);
Dave Wallace048b1d62018-01-03 22:24:41 -05003771 *buflen = sizeof (int);
3772
Florin Coras5e062572019-03-14 19:07:51 -07003773 VDBG (2, "VPPCOM_ATTR_GET_V6ONLY: %d, buflen %d, #VPP-TBD#",
3774 *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003775 }
3776 else
3777 rv = VPPCOM_EINVAL;
Stevenb5a11602017-10-11 09:59:30 -07003778 break;
3779
3780 case VPPCOM_ATTR_SET_V6ONLY:
Dave Wallace048b1d62018-01-03 22:24:41 -05003781 if (buffer && buflen && (*buflen == sizeof (int)))
3782 {
3783 /* VPP-TBD */
3784 if (*(int *) buffer)
Florin Corasac422d62020-10-19 20:51:36 -07003785 vcl_session_set_attr (session, VCL_SESS_ATTR_V6ONLY);
Dave Wallace048b1d62018-01-03 22:24:41 -05003786 else
Florin Corasac422d62020-10-19 20:51:36 -07003787 vcl_session_clear_attr (session, VCL_SESS_ATTR_V6ONLY);
Dave Wallace048b1d62018-01-03 22:24:41 -05003788
Florin Coras5e062572019-03-14 19:07:51 -07003789 VDBG (2, "VPPCOM_ATTR_SET_V6ONLY: %d, buflen %d, #VPP-TBD#",
Florin Corasac422d62020-10-19 20:51:36 -07003790 vcl_session_has_attr (session, VCL_SESS_ATTR_V6ONLY),
Florin Coras5e062572019-03-14 19:07:51 -07003791 *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003792 }
3793 else
3794 rv = VPPCOM_EINVAL;
3795 break;
3796
3797 case VPPCOM_ATTR_GET_KEEPALIVE:
3798 if (buffer && buflen && (*buflen >= sizeof (int)))
3799 {
3800 /* VPP-TBD */
Florin Corasac422d62020-10-19 20:51:36 -07003801 *(int *) buffer = vcl_session_has_attr (session,
3802 VCL_SESS_ATTR_KEEPALIVE);
Dave Wallace048b1d62018-01-03 22:24:41 -05003803 *buflen = sizeof (int);
3804
Florin Coras5e062572019-03-14 19:07:51 -07003805 VDBG (2, "VPPCOM_ATTR_GET_KEEPALIVE: %d, buflen %d, #VPP-TBD#",
3806 *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003807 }
3808 else
3809 rv = VPPCOM_EINVAL;
Stevenb5a11602017-10-11 09:59:30 -07003810 break;
Stevenbccd3392017-10-12 20:42:21 -07003811
3812 case VPPCOM_ATTR_SET_KEEPALIVE:
Dave Wallace048b1d62018-01-03 22:24:41 -05003813 if (buffer && buflen && (*buflen == sizeof (int)))
3814 {
3815 /* VPP-TBD */
3816 if (*(int *) buffer)
Florin Corasac422d62020-10-19 20:51:36 -07003817 vcl_session_set_attr (session, VCL_SESS_ATTR_KEEPALIVE);
Dave Wallace048b1d62018-01-03 22:24:41 -05003818 else
Florin Corasac422d62020-10-19 20:51:36 -07003819 vcl_session_clear_attr (session, VCL_SESS_ATTR_KEEPALIVE);
Dave Wallace048b1d62018-01-03 22:24:41 -05003820
Florin Coras5e062572019-03-14 19:07:51 -07003821 VDBG (2, "VPPCOM_ATTR_SET_KEEPALIVE: %d, buflen %d, #VPP-TBD#",
Florin Corasac422d62020-10-19 20:51:36 -07003822 vcl_session_has_attr (session, VCL_SESS_ATTR_KEEPALIVE),
Florin Coras5e062572019-03-14 19:07:51 -07003823 *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003824 }
3825 else
3826 rv = VPPCOM_EINVAL;
3827 break;
3828
3829 case VPPCOM_ATTR_GET_TCP_NODELAY:
3830 if (buffer && buflen && (*buflen >= sizeof (int)))
3831 {
3832 /* VPP-TBD */
Florin Corasac422d62020-10-19 20:51:36 -07003833 *(int *) buffer = vcl_session_has_attr (session,
3834 VCL_SESS_ATTR_TCP_NODELAY);
Dave Wallace048b1d62018-01-03 22:24:41 -05003835 *buflen = sizeof (int);
3836
Florin Coras5e062572019-03-14 19:07:51 -07003837 VDBG (2, "VPPCOM_ATTR_GET_TCP_NODELAY: %d, buflen %d, #VPP-TBD#",
3838 *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003839 }
3840 else
3841 rv = VPPCOM_EINVAL;
3842 break;
3843
3844 case VPPCOM_ATTR_SET_TCP_NODELAY:
3845 if (buffer && buflen && (*buflen == sizeof (int)))
3846 {
3847 /* VPP-TBD */
3848 if (*(int *) buffer)
Florin Corasac422d62020-10-19 20:51:36 -07003849 vcl_session_set_attr (session, VCL_SESS_ATTR_TCP_NODELAY);
Dave Wallace048b1d62018-01-03 22:24:41 -05003850 else
Florin Corasac422d62020-10-19 20:51:36 -07003851 vcl_session_clear_attr (session, VCL_SESS_ATTR_TCP_NODELAY);
Dave Wallace048b1d62018-01-03 22:24:41 -05003852
Florin Coras5e062572019-03-14 19:07:51 -07003853 VDBG (2, "VPPCOM_ATTR_SET_TCP_NODELAY: %d, buflen %d, #VPP-TBD#",
Florin Corasac422d62020-10-19 20:51:36 -07003854 vcl_session_has_attr (session, VCL_SESS_ATTR_TCP_NODELAY),
Florin Coras5e062572019-03-14 19:07:51 -07003855 *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003856 }
3857 else
3858 rv = VPPCOM_EINVAL;
3859 break;
3860
3861 case VPPCOM_ATTR_GET_TCP_KEEPIDLE:
3862 if (buffer && buflen && (*buflen >= sizeof (int)))
3863 {
3864 /* VPP-TBD */
Florin Corasac422d62020-10-19 20:51:36 -07003865 *(int *) buffer = vcl_session_has_attr (session,
3866 VCL_SESS_ATTR_TCP_KEEPIDLE);
Dave Wallace048b1d62018-01-03 22:24:41 -05003867 *buflen = sizeof (int);
3868
Florin Coras5e062572019-03-14 19:07:51 -07003869 VDBG (2, "VPPCOM_ATTR_GET_TCP_KEEPIDLE: %d, buflen %d, #VPP-TBD#",
3870 *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003871 }
3872 else
3873 rv = VPPCOM_EINVAL;
Stevenbccd3392017-10-12 20:42:21 -07003874 break;
3875
3876 case VPPCOM_ATTR_SET_TCP_KEEPIDLE:
Dave Wallace048b1d62018-01-03 22:24:41 -05003877 if (buffer && buflen && (*buflen == sizeof (int)))
3878 {
3879 /* VPP-TBD */
3880 if (*(int *) buffer)
Florin Corasac422d62020-10-19 20:51:36 -07003881 vcl_session_set_attr (session, VCL_SESS_ATTR_TCP_KEEPIDLE);
Dave Wallace048b1d62018-01-03 22:24:41 -05003882 else
Florin Corasac422d62020-10-19 20:51:36 -07003883 vcl_session_clear_attr (session, VCL_SESS_ATTR_TCP_KEEPIDLE);
Dave Wallace048b1d62018-01-03 22:24:41 -05003884
Florin Coras5e062572019-03-14 19:07:51 -07003885 VDBG (2, "VPPCOM_ATTR_SET_TCP_KEEPIDLE: %d, buflen %d, #VPP-TBD#",
Florin Corasac422d62020-10-19 20:51:36 -07003886 vcl_session_has_attr (session,
3887 VCL_SESS_ATTR_TCP_KEEPIDLE), *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003888 }
3889 else
3890 rv = VPPCOM_EINVAL;
3891 break;
3892
3893 case VPPCOM_ATTR_GET_TCP_KEEPINTVL:
3894 if (buffer && buflen && (*buflen >= sizeof (int)))
3895 {
3896 /* VPP-TBD */
Florin Corasac422d62020-10-19 20:51:36 -07003897 *(int *) buffer = vcl_session_has_attr (session,
3898 VCL_SESS_ATTR_TCP_KEEPINTVL);
Dave Wallace048b1d62018-01-03 22:24:41 -05003899 *buflen = sizeof (int);
3900
Florin Coras5e062572019-03-14 19:07:51 -07003901 VDBG (2, "VPPCOM_ATTR_GET_TCP_KEEPINTVL: %d, buflen %d, #VPP-TBD#",
3902 *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003903 }
3904 else
3905 rv = VPPCOM_EINVAL;
Stevenbccd3392017-10-12 20:42:21 -07003906 break;
3907
3908 case VPPCOM_ATTR_SET_TCP_KEEPINTVL:
Dave Wallace048b1d62018-01-03 22:24:41 -05003909 if (buffer && buflen && (*buflen == sizeof (int)))
3910 {
3911 /* VPP-TBD */
3912 if (*(int *) buffer)
Florin Corasac422d62020-10-19 20:51:36 -07003913 vcl_session_set_attr (session, VCL_SESS_ATTR_TCP_KEEPINTVL);
Dave Wallace048b1d62018-01-03 22:24:41 -05003914 else
Florin Corasac422d62020-10-19 20:51:36 -07003915 vcl_session_clear_attr (session, VCL_SESS_ATTR_TCP_KEEPINTVL);
Dave Wallace048b1d62018-01-03 22:24:41 -05003916
Florin Coras5e062572019-03-14 19:07:51 -07003917 VDBG (2, "VPPCOM_ATTR_SET_TCP_KEEPINTVL: %d, buflen %d, #VPP-TBD#",
Florin Corasac422d62020-10-19 20:51:36 -07003918 vcl_session_has_attr (session,
3919 VCL_SESS_ATTR_TCP_KEEPINTVL), *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003920 }
3921 else
3922 rv = VPPCOM_EINVAL;
3923 break;
3924
3925 case VPPCOM_ATTR_GET_TCP_USER_MSS:
Florin Coras04ae8272021-04-12 19:55:37 -07003926 if (!(buffer && buflen && (*buflen >= sizeof (u32))))
Dave Wallace048b1d62018-01-03 22:24:41 -05003927 {
Florin Coras04ae8272021-04-12 19:55:37 -07003928 rv = VPPCOM_EINVAL;
3929 break;
Dave Wallace048b1d62018-01-03 22:24:41 -05003930 }
Florin Coras04ae8272021-04-12 19:55:37 -07003931
3932 tea.type = TRANSPORT_ENDPT_ATTR_MSS;
3933 tea.mss = *(u32 *) buffer;
3934 if (vcl_session_transport_attr (wrk, session, 1 /* is_get */, &tea))
3935 rv = VPPCOM_ENOPROTOOPT;
3936
3937 if (!rv)
3938 {
3939 *(u32 *) buffer = tea.mss;
3940 *buflen = sizeof (int);
3941 }
3942
3943 VDBG (2, "VPPCOM_ATTR_GET_TCP_USER_MSS: %d, buflen %d", *(int *) buffer,
3944 *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003945 break;
3946
3947 case VPPCOM_ATTR_SET_TCP_USER_MSS:
Florin Coras04ae8272021-04-12 19:55:37 -07003948 if (!(buffer && buflen && (*buflen == sizeof (u32))))
Dave Wallace048b1d62018-01-03 22:24:41 -05003949 {
Florin Coras04ae8272021-04-12 19:55:37 -07003950 rv = VPPCOM_EINVAL;
3951 break;
Dave Wallace048b1d62018-01-03 22:24:41 -05003952 }
Florin Coras04ae8272021-04-12 19:55:37 -07003953
3954 tea.type = TRANSPORT_ENDPT_ATTR_MSS;
3955 tea.mss = *(u32 *) buffer;
3956 if (vcl_session_transport_attr (wrk, session, 0 /* is_get */, &tea))
3957 rv = VPPCOM_ENOPROTOOPT;
3958
3959 VDBG (2, "VPPCOM_ATTR_SET_TCP_USER_MSS: %u, buflen %d", tea.mss,
3960 *buflen);
Stevenbccd3392017-10-12 20:42:21 -07003961 break;
Dave Wallacee22aa742017-10-20 12:30:38 -04003962
Florin Coras1e966172020-05-16 18:18:14 +00003963 case VPPCOM_ATTR_SET_CONNECTED:
3964 session->flags |= VCL_SESSION_F_CONNECTED;
3965 break;
3966
Florin Corasa5a9efd2021-01-05 17:03:29 -08003967 case VPPCOM_ATTR_SET_CKPAIR:
3968 if (!(buffer && buflen && (*buflen == sizeof (int))) ||
3969 !vcl_session_has_crypto (session))
3970 {
3971 rv = VPPCOM_EINVAL;
3972 break;
3973 }
Florin Corasa54b62d2021-04-21 09:05:56 -07003974 if (!session->ext_config)
3975 {
Florin Coras87f63892021-05-01 16:01:40 -07003976 vcl_session_alloc_ext_cfg (session, TRANSPORT_ENDPT_EXT_CFG_CRYPTO,
3977 sizeof (transport_endpt_ext_cfg_t));
Florin Corasa54b62d2021-04-21 09:05:56 -07003978 }
3979 else if (session->ext_config->type != TRANSPORT_ENDPT_EXT_CFG_CRYPTO)
3980 {
3981 rv = VPPCOM_EINVAL;
3982 break;
3983 }
3984
3985 session->ext_config->crypto.ckpair_index = *(uint32_t *) buffer;
Florin Corasa5a9efd2021-01-05 17:03:29 -08003986 break;
3987
Florin Coras6a6555a2021-01-28 11:39:27 -08003988 case VPPCOM_ATTR_SET_VRF:
3989 if (!(buffer && buflen && (*buflen == sizeof (u32))))
3990 {
3991 rv = VPPCOM_EINVAL;
3992 break;
3993 }
3994 session->vrf = *(u32 *) buffer;
3995 break;
3996
3997 case VPPCOM_ATTR_GET_VRF:
3998 if (!(buffer && buflen && (*buflen >= sizeof (u32))))
3999 {
4000 rv = VPPCOM_EINVAL;
4001 break;
4002 }
4003 *(u32 *) buffer = session->vrf;
4004 *buflen = sizeof (u32);
4005 break;
4006
wanghanlin0674f852021-02-22 10:38:36 +08004007 case VPPCOM_ATTR_GET_DOMAIN:
Florin Corasd77325c2021-02-23 12:03:03 -08004008 if (!(buffer && buflen && (*buflen >= sizeof (int))))
wanghanlin0674f852021-02-22 10:38:36 +08004009 {
Florin Corasd77325c2021-02-23 12:03:03 -08004010 rv = VPPCOM_EINVAL;
4011 break;
wanghanlin0674f852021-02-22 10:38:36 +08004012 }
Florin Corasd77325c2021-02-23 12:03:03 -08004013
4014 if (session->transport.is_ip4)
4015 *(int *) buffer = AF_INET;
wanghanlin0674f852021-02-22 10:38:36 +08004016 else
Florin Corasd77325c2021-02-23 12:03:03 -08004017 *(int *) buffer = AF_INET6;
4018 *buflen = sizeof (int);
4019
wanghanlin0674f852021-02-22 10:38:36 +08004020 VDBG (2, "VPPCOM_ATTR_GET_DOMAIN: %d, buflen %u", *(int *) buffer,
4021 *buflen);
4022 break;
4023
Florin Coras87f63892021-05-01 16:01:40 -07004024 case VPPCOM_ATTR_SET_ENDPT_EXT_CFG:
4025 if (!(buffer && buflen && (*buflen > 0)))
4026 {
4027 rv = VPPCOM_EINVAL;
4028 break;
4029 }
4030 if (session->ext_config)
4031 {
4032 rv = VPPCOM_EINVAL;
4033 break;
4034 }
4035 vcl_session_alloc_ext_cfg (session, TRANSPORT_ENDPT_EXT_CFG_NONE,
4036 *buflen + sizeof (u32));
4037 clib_memcpy (session->ext_config->data, buffer, *buflen);
4038 session->ext_config->len = *buflen;
4039 break;
4040
Dave Wallacee22aa742017-10-20 12:30:38 -04004041 default:
4042 rv = VPPCOM_EINVAL;
4043 break;
Dave Wallace35830af2017-10-09 01:43:42 -04004044 }
4045
Dave Wallace35830af2017-10-09 01:43:42 -04004046 return rv;
4047}
4048
Stevenac1f96d2017-10-24 16:03:58 -07004049int
Florin Coras134a9962018-08-28 11:32:04 -07004050vppcom_session_recvfrom (uint32_t session_handle, void *buffer,
Stevenac1f96d2017-10-24 16:03:58 -07004051 uint32_t buflen, int flags, vppcom_endpt_t * ep)
4052{
Florin Coras134a9962018-08-28 11:32:04 -07004053 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras5da10c42020-04-01 04:31:21 +00004054 vcl_session_t *session;
Stevenac1f96d2017-10-24 16:03:58 -07004055 int rv = VPPCOM_OK;
Steven58f464e2017-10-25 12:33:12 -07004056
4057 if (flags == 0)
Florin Coras134a9962018-08-28 11:32:04 -07004058 rv = vppcom_session_read (session_handle, buffer, buflen);
Stevenac1f96d2017-10-24 16:03:58 -07004059 else if (flags & MSG_PEEK)
Florin Coras134a9962018-08-28 11:32:04 -07004060 rv = vppcom_session_peek (session_handle, buffer, buflen);
Stevenac1f96d2017-10-24 16:03:58 -07004061 else
4062 {
Florin Corasa7a1a222018-12-30 17:11:31 -08004063 VDBG (0, "Unsupport flags for recvfrom %d", flags);
Florin Coras460dce62018-07-27 05:45:06 -07004064 return VPPCOM_EAFNOSUPPORT;
Stevenac1f96d2017-10-24 16:03:58 -07004065 }
4066
Florin Coras0a1e1832020-03-29 18:54:04 +00004067 if (ep && rv > 0)
Florin Coras99368312018-08-02 10:45:44 -07004068 {
Florin Coras5da10c42020-04-01 04:31:21 +00004069 session = vcl_session_get_w_handle (wrk, session_handle);
Florin Coras99368312018-08-02 10:45:44 -07004070 if (session->transport.is_ip4)
Dave Barach178cf492018-11-13 16:34:13 -05004071 clib_memcpy_fast (ep->ip, &session->transport.rmt_ip.ip4,
4072 sizeof (ip4_address_t));
Florin Coras99368312018-08-02 10:45:44 -07004073 else
Dave Barach178cf492018-11-13 16:34:13 -05004074 clib_memcpy_fast (ep->ip, &session->transport.rmt_ip.ip6,
4075 sizeof (ip6_address_t));
Florin Coras5da10c42020-04-01 04:31:21 +00004076 ep->is_ip4 = session->transport.is_ip4;
4077 ep->port = session->transport.rmt_port;
Florin Coras99368312018-08-02 10:45:44 -07004078 }
Florin Coras460dce62018-07-27 05:45:06 -07004079
Stevenac1f96d2017-10-24 16:03:58 -07004080 return rv;
4081}
4082
4083int
Florin Coras134a9962018-08-28 11:32:04 -07004084vppcom_session_sendto (uint32_t session_handle, void *buffer,
Stevenac1f96d2017-10-24 16:03:58 -07004085 uint32_t buflen, int flags, vppcom_endpt_t * ep)
4086{
Florin Coras7a2abce2020-04-05 19:25:44 +00004087 vcl_worker_t *wrk = vcl_worker_get_current ();
4088 vcl_session_t *s;
4089
4090 s = vcl_session_get_w_handle (wrk, session_handle);
Florin Coras0b0d28e2021-06-04 17:31:53 -07004091 if (PREDICT_FALSE (!s))
Florin Coras7a2abce2020-04-05 19:25:44 +00004092 return VPPCOM_EBADFD;
4093
Dave Wallace617dffa2017-10-26 14:47:06 -04004094 if (ep)
4095 {
Florin Coras5824cc52020-10-20 18:44:41 -07004096 if (!vcl_session_is_cl (s))
Florin Coras5da10c42020-04-01 04:31:21 +00004097 return VPPCOM_EINVAL;
4098
liuyacanbc0c7542021-08-02 20:15:05 +08004099 s->transport.is_ip4 = ep->is_ip4;
4100 s->transport.rmt_port = ep->port;
4101 vcl_ip_copy_from_ep (&s->transport.rmt_ip, ep);
4102
Florin Coras5da10c42020-04-01 04:31:21 +00004103 /* Session not connected/bound in vpp. Create it by 'connecting' it */
Florin Corasc127d5a2020-10-14 16:35:58 -07004104 if (PREDICT_FALSE (s->session_state == VCL_STATE_CLOSED))
Florin Coras5da10c42020-04-01 04:31:21 +00004105 {
Florin Coras5824cc52020-10-20 18:44:41 -07004106 u32 session_index = s->session_index;
4107 f64 timeout = vcm->cfg.session_timeout;
4108 int rv;
4109
Florin Coras5da10c42020-04-01 04:31:21 +00004110 vcl_send_session_connect (wrk, s);
Florin Coras5824cc52020-10-20 18:44:41 -07004111 rv = vppcom_wait_for_session_state_change (session_index,
4112 VCL_STATE_READY,
4113 timeout);
4114 if (rv < 0)
4115 return rv;
4116 s = vcl_session_get (wrk, session_index);
Florin Coras5da10c42020-04-01 04:31:21 +00004117 }
Dave Wallace617dffa2017-10-26 14:47:06 -04004118 }
4119
4120 if (flags)
4121 {
4122 // TBD check the flags and do the right thing
Florin Coras5e062572019-03-14 19:07:51 -07004123 VDBG (2, "handling flags 0x%u (%d) not implemented yet.", flags, flags);
Dave Wallace617dffa2017-10-26 14:47:06 -04004124 }
4125
Florin Coras7a2abce2020-04-05 19:25:44 +00004126 return (vppcom_session_write_inline (wrk, s, buffer, buflen, 1,
4127 s->is_dgram ? 1 : 0));
Stevenac1f96d2017-10-24 16:03:58 -07004128}
4129
Dave Wallace048b1d62018-01-03 22:24:41 -05004130int
4131vppcom_poll (vcl_poll_t * vp, uint32_t n_sids, double wait_for_time)
4132{
Florin Coras134a9962018-08-28 11:32:04 -07004133 vcl_worker_t *wrk = vcl_worker_get_current ();
4134 f64 timeout = clib_time_now (&wrk->clib_time) + wait_for_time;
Dave Wallace048b1d62018-01-03 22:24:41 -05004135 u32 i, keep_trying = 1;
Florin Coras6917b942018-11-13 22:44:54 -08004136 svm_msg_q_msg_t msg;
4137 session_event_t *e;
Dave Wallace048b1d62018-01-03 22:24:41 -05004138 int rv, num_ev = 0;
4139
Florin Coras5e062572019-03-14 19:07:51 -07004140 VDBG (3, "vp %p, nsids %u, wait_for_time %f", vp, n_sids, wait_for_time);
Dave Wallace048b1d62018-01-03 22:24:41 -05004141
4142 if (!vp)
4143 return VPPCOM_EFAULT;
4144
4145 do
4146 {
Florin Coras7e12d942018-06-27 14:32:43 -07004147 vcl_session_t *session;
Dave Wallace048b1d62018-01-03 22:24:41 -05004148
Florin Coras6917b942018-11-13 22:44:54 -08004149 /* Dequeue all events and drop all unhandled io events */
4150 while (svm_msg_q_sub (wrk->app_event_queue, &msg, SVM_Q_NOWAIT, 0) == 0)
4151 {
4152 e = svm_msg_q_msg_data (wrk->app_event_queue, &msg);
4153 vcl_handle_mq_event (wrk, e);
4154 svm_msg_q_free_msg (wrk->app_event_queue, &msg);
4155 }
4156 vec_reset_length (wrk->unhandled_evts_vector);
4157
Dave Wallace048b1d62018-01-03 22:24:41 -05004158 for (i = 0; i < n_sids; i++)
4159 {
Florin Coras7baeb712019-01-04 17:05:43 -08004160 session = vcl_session_get (wrk, vp[i].sh);
Florin Coras070453d2018-08-24 17:04:27 -07004161 if (!session)
Florin Coras6917b942018-11-13 22:44:54 -08004162 {
4163 vp[i].revents = POLLHUP;
4164 num_ev++;
4165 continue;
4166 }
Dave Wallace048b1d62018-01-03 22:24:41 -05004167
Florin Coras6917b942018-11-13 22:44:54 -08004168 vp[i].revents = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -05004169
4170 if (POLLIN & vp[i].events)
4171 {
Florin Coras0ef8ef22019-01-18 08:37:13 -08004172 rv = vcl_session_read_ready (session);
Dave Wallace048b1d62018-01-03 22:24:41 -05004173 if (rv > 0)
4174 {
Florin Coras6917b942018-11-13 22:44:54 -08004175 vp[i].revents |= POLLIN;
Dave Wallace048b1d62018-01-03 22:24:41 -05004176 num_ev++;
4177 }
4178 else if (rv < 0)
4179 {
4180 switch (rv)
4181 {
4182 case VPPCOM_ECONNRESET:
Florin Coras6917b942018-11-13 22:44:54 -08004183 vp[i].revents = POLLHUP;
Dave Wallace048b1d62018-01-03 22:24:41 -05004184 break;
4185
4186 default:
Florin Coras6917b942018-11-13 22:44:54 -08004187 vp[i].revents = POLLERR;
Dave Wallace048b1d62018-01-03 22:24:41 -05004188 break;
4189 }
4190 num_ev++;
4191 }
4192 }
4193
4194 if (POLLOUT & vp[i].events)
4195 {
Florin Coras0ef8ef22019-01-18 08:37:13 -08004196 rv = vcl_session_write_ready (session);
Dave Wallace048b1d62018-01-03 22:24:41 -05004197 if (rv > 0)
4198 {
Florin Coras6917b942018-11-13 22:44:54 -08004199 vp[i].revents |= POLLOUT;
Dave Wallace048b1d62018-01-03 22:24:41 -05004200 num_ev++;
4201 }
4202 else if (rv < 0)
4203 {
4204 switch (rv)
4205 {
4206 case VPPCOM_ECONNRESET:
Florin Coras6917b942018-11-13 22:44:54 -08004207 vp[i].revents = POLLHUP;
Dave Wallace048b1d62018-01-03 22:24:41 -05004208 break;
4209
4210 default:
Florin Coras6917b942018-11-13 22:44:54 -08004211 vp[i].revents = POLLERR;
Dave Wallace048b1d62018-01-03 22:24:41 -05004212 break;
4213 }
4214 num_ev++;
4215 }
4216 }
4217
Dave Wallace7e607a72018-06-18 18:41:32 -04004218 if (0) // Note "done:" label used by VCL_SESSION_LOCK_AND_GET()
Dave Wallace048b1d62018-01-03 22:24:41 -05004219 {
Florin Coras6917b942018-11-13 22:44:54 -08004220 vp[i].revents = POLLNVAL;
Dave Wallace048b1d62018-01-03 22:24:41 -05004221 num_ev++;
4222 }
4223 }
4224 if (wait_for_time != -1)
Florin Coras134a9962018-08-28 11:32:04 -07004225 keep_trying = (clib_time_now (&wrk->clib_time) <= timeout) ? 1 : 0;
Dave Wallace048b1d62018-01-03 22:24:41 -05004226 }
4227 while ((num_ev == 0) && keep_trying);
4228
Dave Wallace048b1d62018-01-03 22:24:41 -05004229 return num_ev;
4230}
4231
Florin Coras99368312018-08-02 10:45:44 -07004232int
4233vppcom_mq_epoll_fd (void)
4234{
Florin Coras134a9962018-08-28 11:32:04 -07004235 vcl_worker_t *wrk = vcl_worker_get_current ();
4236 return wrk->mqs_epfd;
4237}
4238
4239int
Florin Coras30e79c22019-01-02 19:31:22 -08004240vppcom_session_index (vcl_session_handle_t session_handle)
Florin Coras134a9962018-08-28 11:32:04 -07004241{
4242 return session_handle & 0xFFFFFF;
4243}
4244
4245int
Florin Coras30e79c22019-01-02 19:31:22 -08004246vppcom_session_worker (vcl_session_handle_t session_handle)
4247{
4248 return session_handle >> 24;
4249}
4250
4251int
Florin Coras134a9962018-08-28 11:32:04 -07004252vppcom_worker_register (void)
4253{
Florin Coras47c40e22018-11-26 17:01:36 -08004254 if (!vcl_worker_alloc_and_init ())
4255 return VPPCOM_EEXIST;
4256
Florin Coras47c40e22018-11-26 17:01:36 -08004257 if (vcl_worker_register_with_vpp ())
4258 return VPPCOM_EEXIST;
4259
4260 return VPPCOM_OK;
Florin Coras99368312018-08-02 10:45:44 -07004261}
4262
Florin Coras369db832019-07-08 12:34:45 -07004263void
4264vppcom_worker_unregister (void)
4265{
4266 vcl_worker_cleanup (vcl_worker_get_current (), 1 /* notify vpp */ );
4267 vcl_set_worker_index (~0);
4268}
4269
Pivo6017ff02020-05-04 17:57:33 +02004270void
4271vppcom_worker_index_set (int index)
4272{
4273 vcl_set_worker_index (index);
4274}
4275
Florin Corasdfe4cf42018-11-28 22:13:45 -08004276int
4277vppcom_worker_index (void)
4278{
4279 return vcl_get_worker_index ();
4280}
4281
Florin Corase0982e52019-01-25 13:19:56 -08004282int
4283vppcom_worker_mqs_epfd (void)
4284{
4285 vcl_worker_t *wrk = vcl_worker_get_current ();
4286 if (!vcm->cfg.use_mq_eventfd)
4287 return -1;
4288 return wrk->mqs_epfd;
4289}
4290
Nathan Skrzypczak9fd99622019-05-16 14:38:44 +02004291int
4292vppcom_session_is_connectable_listener (uint32_t session_handle)
4293{
4294 vcl_session_t *session;
4295 vcl_worker_t *wrk = vcl_worker_get_current ();
4296 session = vcl_session_get_w_handle (wrk, session_handle);
4297 if (!session)
4298 return VPPCOM_EBADFD;
4299 return vcl_session_is_connectable_listener (wrk, session);
4300}
4301
4302int
4303vppcom_session_listener (uint32_t session_handle)
4304{
4305 vcl_worker_t *wrk = vcl_worker_get_current ();
4306 vcl_session_t *listen_session, *session;
4307 session = vcl_session_get_w_handle (wrk, session_handle);
4308 if (!session)
4309 return VPPCOM_EBADFD;
4310 if (session->listener_index == VCL_INVALID_SESSION_INDEX)
4311 return VPPCOM_EBADFD;
4312 listen_session = vcl_session_get_w_handle (wrk, session->listener_index);
4313 if (!listen_session)
4314 return VPPCOM_EBADFD;
4315 return vcl_session_handle (listen_session);
4316}
4317
4318int
4319vppcom_session_n_accepted (uint32_t session_handle)
4320{
4321 vcl_worker_t *wrk = vcl_worker_get_current ();
4322 vcl_session_t *session = vcl_session_get_w_handle (wrk, session_handle);
4323 if (!session)
4324 return VPPCOM_EBADFD;
4325 return session->n_accepted_sessions;
4326}
4327
Florin Coras66ec4672020-06-15 07:59:40 -07004328const char *
4329vppcom_proto_str (vppcom_proto_t proto)
4330{
4331 char const *proto_str;
4332
4333 switch (proto)
4334 {
4335 case VPPCOM_PROTO_TCP:
4336 proto_str = "TCP";
4337 break;
4338 case VPPCOM_PROTO_UDP:
4339 proto_str = "UDP";
4340 break;
4341 case VPPCOM_PROTO_TLS:
4342 proto_str = "TLS";
4343 break;
4344 case VPPCOM_PROTO_QUIC:
4345 proto_str = "QUIC";
4346 break;
Florin Coras4b47ee22020-11-19 13:38:26 -08004347 case VPPCOM_PROTO_DTLS:
4348 proto_str = "DTLS";
4349 break;
Florin Coras6621abf2021-01-06 17:35:17 -08004350 case VPPCOM_PROTO_SRTP:
4351 proto_str = "SRTP";
4352 break;
Florin Coras66ec4672020-06-15 07:59:40 -07004353 default:
4354 proto_str = "UNKNOWN";
4355 break;
4356 }
4357 return proto_str;
4358}
4359
4360const char *
4361vppcom_retval_str (int retval)
4362{
4363 char const *st;
4364
4365 switch (retval)
4366 {
4367 case VPPCOM_OK:
4368 st = "VPPCOM_OK";
4369 break;
4370
4371 case VPPCOM_EAGAIN:
4372 st = "VPPCOM_EAGAIN";
4373 break;
4374
4375 case VPPCOM_EFAULT:
4376 st = "VPPCOM_EFAULT";
4377 break;
4378
4379 case VPPCOM_ENOMEM:
4380 st = "VPPCOM_ENOMEM";
4381 break;
4382
4383 case VPPCOM_EINVAL:
4384 st = "VPPCOM_EINVAL";
4385 break;
4386
4387 case VPPCOM_EBADFD:
4388 st = "VPPCOM_EBADFD";
4389 break;
4390
4391 case VPPCOM_EAFNOSUPPORT:
4392 st = "VPPCOM_EAFNOSUPPORT";
4393 break;
4394
4395 case VPPCOM_ECONNABORTED:
4396 st = "VPPCOM_ECONNABORTED";
4397 break;
4398
4399 case VPPCOM_ECONNRESET:
4400 st = "VPPCOM_ECONNRESET";
4401 break;
4402
4403 case VPPCOM_ENOTCONN:
4404 st = "VPPCOM_ENOTCONN";
4405 break;
4406
4407 case VPPCOM_ECONNREFUSED:
4408 st = "VPPCOM_ECONNREFUSED";
4409 break;
4410
4411 case VPPCOM_ETIMEDOUT:
4412 st = "VPPCOM_ETIMEDOUT";
4413 break;
4414
4415 default:
4416 st = "UNKNOWN_STATE";
4417 break;
4418 }
4419
4420 return st;
4421}
4422
Florin Corasa5a9efd2021-01-05 17:03:29 -08004423int
4424vppcom_add_cert_key_pair (vppcom_cert_key_pair_t *ckpair)
4425{
4426 if (vcm->cfg.vpp_app_socket_api)
Florin Corase191d762021-08-11 14:55:49 -07004427 return vcl_sapi_add_cert_key_pair (ckpair);
4428 else
4429 return vcl_bapi_add_cert_key_pair (ckpair);
Florin Corasa5a9efd2021-01-05 17:03:29 -08004430}
4431
4432int
4433vppcom_del_cert_key_pair (uint32_t ckpair_index)
4434{
4435 if (vcm->cfg.vpp_app_socket_api)
Florin Corase191d762021-08-11 14:55:49 -07004436 return vcl_sapi_del_cert_key_pair (ckpair_index);
4437 else
4438 return vcl_bapi_del_cert_key_pair (ckpair_index);
Florin Corasa5a9efd2021-01-05 17:03:29 -08004439}
4440
Dave Wallacee22aa742017-10-20 12:30:38 -04004441/*
4442 * fd.io coding-style-patch-verification: ON
4443 *
4444 * Local Variables:
4445 * eval: (c-set-style "gnu")
4446 * End:
4447 */