blob: 107b109dc752913e6916aa1b65e996c417663d48 [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
Florin Coras697faea2018-06-27 17:10:49 -070040const char *
Florin Coras288eaab2019-02-03 15:26:14 -080041vppcom_session_state_str (vcl_session_state_t state)
Dave Wallace543852a2017-08-03 02:11:34 -040042{
43 char *st;
44
45 switch (state)
46 {
Florin Corasc127d5a2020-10-14 16:35:58 -070047 case VCL_STATE_CLOSED:
Florin Coras54140622020-02-04 19:04:34 +000048 st = "STATE_CLOSED";
Dave Wallace543852a2017-08-03 02:11:34 -040049 break;
Florin Corasc127d5a2020-10-14 16:35:58 -070050 case VCL_STATE_LISTEN:
Dave Wallace543852a2017-08-03 02:11:34 -040051 st = "STATE_LISTEN";
52 break;
Florin Corasdfffdd72020-10-15 10:54:47 -070053 case VCL_STATE_READY:
54 st = "STATE_READY";
Dave Wallace543852a2017-08-03 02:11:34 -040055 break;
Florin Corasc127d5a2020-10-14 16:35:58 -070056 case VCL_STATE_VPP_CLOSING:
Florin Coras3c7d4f92018-12-14 11:28:43 -080057 st = "STATE_VPP_CLOSING";
Dave Wallace4878cbe2017-11-21 03:45:09 -050058 break;
Florin Corasc127d5a2020-10-14 16:35:58 -070059 case VCL_STATE_DISCONNECT:
Dave Wallace543852a2017-08-03 02:11:34 -040060 st = "STATE_DISCONNECT";
61 break;
Florin Corasc127d5a2020-10-14 16:35:58 -070062 case VCL_STATE_DETACHED:
Florin Corasadcfb152020-02-12 08:50:29 +000063 st = "STATE_DETACHED";
Dave Wallace543852a2017-08-03 02:11:34 -040064 break;
Florin Corasc127d5a2020-10-14 16:35:58 -070065 case VCL_STATE_UPDATED:
Florin Coras2d675d72019-01-28 15:54:27 -080066 st = "STATE_UPDATED";
67 break;
Florin Corasc127d5a2020-10-14 16:35:58 -070068 case VCL_STATE_LISTEN_NO_MQ:
Florin Coras2d675d72019-01-28 15:54:27 -080069 st = "STATE_LISTEN_NO_MQ";
70 break;
Dave Wallace543852a2017-08-03 02:11:34 -040071 default:
72 st = "UNKNOWN_STATE";
73 break;
74 }
75
76 return st;
77}
78
Dave Wallace543852a2017-08-03 02:11:34 -040079u8 *
80format_ip4_address (u8 * s, va_list * args)
81{
82 u8 *a = va_arg (*args, u8 *);
83 return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
84}
85
86u8 *
87format_ip6_address (u8 * s, va_list * args)
88{
89 ip6_address_t *a = va_arg (*args, ip6_address_t *);
90 u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
91
92 i_max_n_zero = ARRAY_LEN (a->as_u16);
93 max_n_zeros = 0;
94 i_first_zero = i_max_n_zero;
95 n_zeros = 0;
96 for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
97 {
98 u32 is_zero = a->as_u16[i] == 0;
99 if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
100 {
101 i_first_zero = i;
102 n_zeros = 0;
103 }
104 n_zeros += is_zero;
105 if ((!is_zero && n_zeros > max_n_zeros)
106 || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
107 {
108 i_max_n_zero = i_first_zero;
109 max_n_zeros = n_zeros;
110 i_first_zero = ARRAY_LEN (a->as_u16);
111 n_zeros = 0;
112 }
113 }
114
115 last_double_colon = 0;
116 for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
117 {
118 if (i == i_max_n_zero && max_n_zeros > 1)
119 {
120 s = format (s, "::");
121 i += max_n_zeros - 1;
122 last_double_colon = 1;
123 }
124 else
125 {
126 s = format (s, "%s%x",
127 (last_double_colon || i == 0) ? "" : ":",
128 clib_net_to_host_u16 (a->as_u16[i]));
129 last_double_colon = 0;
130 }
131 }
132
133 return s;
134}
135
136/* Format an IP46 address. */
137u8 *
138format_ip46_address (u8 * s, va_list * args)
139{
140 ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
141 ip46_type_t type = va_arg (*args, ip46_type_t);
142 int is_ip4 = 1;
143
144 switch (type)
145 {
146 case IP46_TYPE_ANY:
147 is_ip4 = ip46_address_is_ip4 (ip46);
148 break;
149 case IP46_TYPE_IP4:
150 is_ip4 = 1;
151 break;
152 case IP46_TYPE_IP6:
153 is_ip4 = 0;
154 break;
155 }
156
157 return is_ip4 ?
158 format (s, "%U", format_ip4_address, &ip46->ip4) :
159 format (s, "%U", format_ip6_address, &ip46->ip6);
160}
161
Florin Coras697faea2018-06-27 17:10:49 -0700162/*
163 * VPPCOM Utility Functions
164 */
165
Florin Coras458089b2019-08-21 16:20:44 -0700166static void
Florin Coras4ac25842021-04-19 17:34:54 -0700167vcl_msg_add_ext_config (vcl_session_t *s, uword *offset)
168{
169 svm_fifo_chunk_t *c;
170
171 c = vcl_segment_alloc_chunk (vcl_vpp_worker_segment_handle (0),
172 0 /* one slice only */, s->ext_config->len,
173 offset);
174 if (c)
175 clib_memcpy_fast (c->data, s->ext_config, s->ext_config->len);
176}
177
178static void
Florin Coras458089b2019-08-21 16:20:44 -0700179vcl_send_session_listen (vcl_worker_t * wrk, vcl_session_t * s)
180{
181 app_session_evt_t _app_evt, *app_evt = &_app_evt;
182 session_listen_msg_t *mp;
183 svm_msg_q_t *mq;
184
185 mq = vcl_worker_ctrl_mq (wrk);
186 app_alloc_ctrl_evt_to_vpp (mq, app_evt, SESSION_CTRL_EVT_LISTEN);
187 mp = (session_listen_msg_t *) app_evt->evt->data;
188 memset (mp, 0, sizeof (*mp));
Florin Corascc7c88e2020-09-15 15:56:51 -0700189 mp->client_index = wrk->api_client_handle;
Florin Coras458089b2019-08-21 16:20:44 -0700190 mp->context = s->session_index;
191 mp->wrk_index = wrk->vpp_wrk_index;
192 mp->is_ip4 = s->transport.is_ip4;
193 clib_memcpy_fast (&mp->ip, &s->transport.lcl_ip, sizeof (mp->ip));
194 mp->port = s->transport.lcl_port;
195 mp->proto = s->session_type;
Florin Coras6a6555a2021-01-28 11:39:27 -0800196 mp->vrf = s->vrf;
Florin Coras1e966172020-05-16 18:18:14 +0000197 if (s->flags & VCL_SESSION_F_CONNECTED)
198 mp->flags = TRANSPORT_CFG_F_CONNECTED;
Florin Coras4ac25842021-04-19 17:34:54 -0700199 if (s->ext_config)
200 vcl_msg_add_ext_config (s, &mp->ext_config);
Florin Coras458089b2019-08-21 16:20:44 -0700201 app_send_ctrl_evt_to_vpp (mq, app_evt);
Florin Coras4ac25842021-04-19 17:34:54 -0700202 if (s->ext_config)
203 {
204 clib_mem_free (s->ext_config);
205 s->ext_config = 0;
206 }
Florin Coras458089b2019-08-21 16:20:44 -0700207}
208
209static void
210vcl_send_session_connect (vcl_worker_t * wrk, vcl_session_t * s)
211{
212 app_session_evt_t _app_evt, *app_evt = &_app_evt;
213 session_connect_msg_t *mp;
214 svm_msg_q_t *mq;
215
216 mq = vcl_worker_ctrl_mq (wrk);
217 app_alloc_ctrl_evt_to_vpp (mq, app_evt, SESSION_CTRL_EVT_CONNECT);
218 mp = (session_connect_msg_t *) app_evt->evt->data;
219 memset (mp, 0, sizeof (*mp));
Florin Corascc7c88e2020-09-15 15:56:51 -0700220 mp->client_index = wrk->api_client_handle;
Florin Coras458089b2019-08-21 16:20:44 -0700221 mp->context = s->session_index;
Filip Tehlar2f09bfc2021-11-15 10:26:56 +0000222 mp->dscp = s->dscp;
Florin Coras458089b2019-08-21 16:20:44 -0700223 mp->wrk_index = wrk->vpp_wrk_index;
224 mp->is_ip4 = s->transport.is_ip4;
225 mp->parent_handle = s->parent_handle;
226 clib_memcpy_fast (&mp->ip, &s->transport.rmt_ip, sizeof (mp->ip));
Florin Corasef7cbf62019-10-17 09:56:27 -0700227 clib_memcpy_fast (&mp->lcl_ip, &s->transport.lcl_ip, sizeof (mp->lcl_ip));
Florin Coras458089b2019-08-21 16:20:44 -0700228 mp->port = s->transport.rmt_port;
Florin Coras0a1e1832020-03-29 18:54:04 +0000229 mp->lcl_port = s->transport.lcl_port;
Florin Coras458089b2019-08-21 16:20:44 -0700230 mp->proto = s->session_type;
Florin Coras6a6555a2021-01-28 11:39:27 -0800231 mp->vrf = s->vrf;
Florin Coras0a1e1832020-03-29 18:54:04 +0000232 if (s->flags & VCL_SESSION_F_CONNECTED)
233 mp->flags |= TRANSPORT_CFG_F_CONNECTED;
Florin Coras4ac25842021-04-19 17:34:54 -0700234 if (s->ext_config)
235 vcl_msg_add_ext_config (s, &mp->ext_config);
Florin Coras458089b2019-08-21 16:20:44 -0700236 app_send_ctrl_evt_to_vpp (mq, app_evt);
Florin Coras4ac25842021-04-19 17:34:54 -0700237
238 if (s->ext_config)
239 {
240 clib_mem_free (s->ext_config);
241 s->ext_config = 0;
242 }
Florin Coras458089b2019-08-21 16:20:44 -0700243}
244
245void
246vcl_send_session_unlisten (vcl_worker_t * wrk, vcl_session_t * s)
247{
248 app_session_evt_t _app_evt, *app_evt = &_app_evt;
249 session_unlisten_msg_t *mp;
250 svm_msg_q_t *mq;
251
252 mq = vcl_worker_ctrl_mq (wrk);
253 app_alloc_ctrl_evt_to_vpp (mq, app_evt, SESSION_CTRL_EVT_UNLISTEN);
254 mp = (session_unlisten_msg_t *) app_evt->evt->data;
255 memset (mp, 0, sizeof (*mp));
Florin Corascc7c88e2020-09-15 15:56:51 -0700256 mp->client_index = wrk->api_client_handle;
Florin Coras458089b2019-08-21 16:20:44 -0700257 mp->wrk_index = wrk->vpp_wrk_index;
258 mp->handle = s->vpp_handle;
259 mp->context = wrk->wrk_index;
260 app_send_ctrl_evt_to_vpp (mq, app_evt);
261}
262
263static void
liuyacan534468e2021-05-09 03:50:40 +0000264vcl_send_session_shutdown (vcl_worker_t *wrk, vcl_session_t *s)
265{
266 app_session_evt_t _app_evt, *app_evt = &_app_evt;
267 session_shutdown_msg_t *mp;
268 svm_msg_q_t *mq;
269
270 /* Send to thread that owns the session */
271 mq = s->vpp_evt_q;
272 app_alloc_ctrl_evt_to_vpp (mq, app_evt, SESSION_CTRL_EVT_SHUTDOWN);
273 mp = (session_shutdown_msg_t *) app_evt->evt->data;
274 memset (mp, 0, sizeof (*mp));
275 mp->client_index = wrk->api_client_handle;
276 mp->handle = s->vpp_handle;
277 app_send_ctrl_evt_to_vpp (mq, app_evt);
278}
279
280static void
Florin Coras458089b2019-08-21 16:20:44 -0700281vcl_send_session_disconnect (vcl_worker_t * wrk, vcl_session_t * s)
282{
283 app_session_evt_t _app_evt, *app_evt = &_app_evt;
284 session_disconnect_msg_t *mp;
285 svm_msg_q_t *mq;
286
287 /* Send to thread that owns the session */
288 mq = s->vpp_evt_q;
289 app_alloc_ctrl_evt_to_vpp (mq, app_evt, SESSION_CTRL_EVT_DISCONNECT);
290 mp = (session_disconnect_msg_t *) app_evt->evt->data;
291 memset (mp, 0, sizeof (*mp));
Florin Corascc7c88e2020-09-15 15:56:51 -0700292 mp->client_index = wrk->api_client_handle;
Florin Coras458089b2019-08-21 16:20:44 -0700293 mp->handle = s->vpp_handle;
294 app_send_ctrl_evt_to_vpp (mq, app_evt);
295}
296
297static void
298vcl_send_app_detach (vcl_worker_t * wrk)
299{
300 app_session_evt_t _app_evt, *app_evt = &_app_evt;
301 session_app_detach_msg_t *mp;
302 svm_msg_q_t *mq;
303
304 mq = vcl_worker_ctrl_mq (wrk);
305 app_alloc_ctrl_evt_to_vpp (mq, app_evt, SESSION_CTRL_EVT_APP_DETACH);
306 mp = (session_app_detach_msg_t *) app_evt->evt->data;
307 memset (mp, 0, sizeof (*mp));
Florin Corascc7c88e2020-09-15 15:56:51 -0700308 mp->client_index = wrk->api_client_handle;
Florin Coras458089b2019-08-21 16:20:44 -0700309 app_send_ctrl_evt_to_vpp (mq, app_evt);
310}
Florin Coras697faea2018-06-27 17:10:49 -0700311
Florin Coras54693d22018-07-17 10:46:29 -0700312static void
313vcl_send_session_accepted_reply (svm_msg_q_t * mq, u32 context,
314 session_handle_t handle, int retval)
315{
316 app_session_evt_t _app_evt, *app_evt = &_app_evt;
317 session_accepted_reply_msg_t *rmp;
318 app_alloc_ctrl_evt_to_vpp (mq, app_evt, SESSION_CTRL_EVT_ACCEPTED_REPLY);
319 rmp = (session_accepted_reply_msg_t *) app_evt->evt->data;
320 rmp->handle = handle;
321 rmp->context = context;
322 rmp->retval = retval;
323 app_send_ctrl_evt_to_vpp (mq, app_evt);
324}
325
Florin Coras99368312018-08-02 10:45:44 -0700326static void
Florin Coras52dd29f2020-11-18 19:02:17 -0800327vcl_send_session_disconnected_reply (vcl_worker_t * wrk, vcl_session_t * s,
328 int retval)
Florin Coras99368312018-08-02 10:45:44 -0700329{
330 app_session_evt_t _app_evt, *app_evt = &_app_evt;
331 session_disconnected_reply_msg_t *rmp;
Florin Coras52dd29f2020-11-18 19:02:17 -0800332 app_alloc_ctrl_evt_to_vpp (s->vpp_evt_q, app_evt,
Florin Coras99368312018-08-02 10:45:44 -0700333 SESSION_CTRL_EVT_DISCONNECTED_REPLY);
334 rmp = (session_disconnected_reply_msg_t *) app_evt->evt->data;
Florin Coras52dd29f2020-11-18 19:02:17 -0800335 rmp->handle = s->vpp_handle;
336 rmp->context = wrk->api_client_handle;
Florin Coras99368312018-08-02 10:45:44 -0700337 rmp->retval = retval;
Florin Coras52dd29f2020-11-18 19:02:17 -0800338 app_send_ctrl_evt_to_vpp (s->vpp_evt_q, app_evt);
Florin Coras99368312018-08-02 10:45:44 -0700339}
340
Florin Corasc9fbd662018-08-24 12:59:56 -0700341static void
Florin Coras52dd29f2020-11-18 19:02:17 -0800342vcl_send_session_reset_reply (vcl_worker_t * wrk, vcl_session_t * s,
343 int retval)
Florin Corasc9fbd662018-08-24 12:59:56 -0700344{
345 app_session_evt_t _app_evt, *app_evt = &_app_evt;
346 session_reset_reply_msg_t *rmp;
Florin Coras52dd29f2020-11-18 19:02:17 -0800347 app_alloc_ctrl_evt_to_vpp (s->vpp_evt_q, app_evt,
348 SESSION_CTRL_EVT_RESET_REPLY);
Florin Corasc9fbd662018-08-24 12:59:56 -0700349 rmp = (session_reset_reply_msg_t *) app_evt->evt->data;
Florin Coras52dd29f2020-11-18 19:02:17 -0800350 rmp->handle = s->vpp_handle;
351 rmp->context = wrk->api_client_handle;
Florin Corasc9fbd662018-08-24 12:59:56 -0700352 rmp->retval = retval;
Florin Coras52dd29f2020-11-18 19:02:17 -0800353 app_send_ctrl_evt_to_vpp (s->vpp_evt_q, app_evt);
Florin Corasc9fbd662018-08-24 12:59:56 -0700354}
355
Florin Coras30e79c22019-01-02 19:31:22 -0800356void
357vcl_send_session_worker_update (vcl_worker_t * wrk, vcl_session_t * s,
358 u32 wrk_index)
359{
360 app_session_evt_t _app_evt, *app_evt = &_app_evt;
361 session_worker_update_msg_t *mp;
Florin Coras30e79c22019-01-02 19:31:22 -0800362
Florin Coras52dd29f2020-11-18 19:02:17 -0800363 app_alloc_ctrl_evt_to_vpp (s->vpp_evt_q, app_evt,
364 SESSION_CTRL_EVT_WORKER_UPDATE);
Florin Coras30e79c22019-01-02 19:31:22 -0800365 mp = (session_worker_update_msg_t *) app_evt->evt->data;
Florin Corascc7c88e2020-09-15 15:56:51 -0700366 mp->client_index = wrk->api_client_handle;
Florin Coras30e79c22019-01-02 19:31:22 -0800367 mp->handle = s->vpp_handle;
368 mp->req_wrk_index = wrk->vpp_wrk_index;
369 mp->wrk_index = wrk_index;
Florin Coras52dd29f2020-11-18 19:02:17 -0800370 app_send_ctrl_evt_to_vpp (s->vpp_evt_q, app_evt);
Florin Coras30e79c22019-01-02 19:31:22 -0800371}
372
hanlina3a48962020-07-13 11:09:15 +0800373int
Florin Coras40c07ce2020-07-16 20:46:17 -0700374vcl_send_worker_rpc (u32 dst_wrk_index, void *data, u32 data_len)
375{
376 app_session_evt_t _app_evt, *app_evt = &_app_evt;
377 session_app_wrk_rpc_msg_t *mp;
378 vcl_worker_t *dst_wrk, *wrk;
379 svm_msg_q_t *mq;
hanlina3a48962020-07-13 11:09:15 +0800380 int ret = -1;
Florin Coras40c07ce2020-07-16 20:46:17 -0700381
382 if (data_len > sizeof (mp->data))
383 goto done;
384
385 clib_spinlock_lock (&vcm->workers_lock);
386
387 dst_wrk = vcl_worker_get_if_valid (dst_wrk_index);
388 if (!dst_wrk)
389 goto done;
390
391 wrk = vcl_worker_get_current ();
392 mq = vcl_worker_ctrl_mq (wrk);
393 app_alloc_ctrl_evt_to_vpp (mq, app_evt, SESSION_CTRL_EVT_APP_WRK_RPC);
394 mp = (session_app_wrk_rpc_msg_t *) app_evt->evt->data;
Florin Corascc7c88e2020-09-15 15:56:51 -0700395 mp->client_index = wrk->api_client_handle;
Florin Coras40c07ce2020-07-16 20:46:17 -0700396 mp->wrk_index = dst_wrk->vpp_wrk_index;
397 clib_memcpy (mp->data, data, data_len);
398 app_send_ctrl_evt_to_vpp (mq, app_evt);
hanlina3a48962020-07-13 11:09:15 +0800399 ret = 0;
Florin Coras40c07ce2020-07-16 20:46:17 -0700400
401done:
402 clib_spinlock_unlock (&vcm->workers_lock);
hanlina3a48962020-07-13 11:09:15 +0800403 return ret;
Florin Coras40c07ce2020-07-16 20:46:17 -0700404}
405
Florin Coras04ae8272021-04-12 19:55:37 -0700406int
407vcl_session_transport_attr (vcl_worker_t *wrk, vcl_session_t *s, u8 is_get,
408 transport_endpt_attr_t *attr)
409{
410 app_session_evt_t _app_evt, *app_evt = &_app_evt;
411 session_transport_attr_msg_t *mp;
412 svm_msg_q_t *mq;
413 f64 timeout;
414
415 ASSERT (!wrk->session_attr_op);
416 wrk->session_attr_op = 1;
417 wrk->session_attr_op_rv = -1;
418
419 mq = s->vpp_evt_q;
420 app_alloc_ctrl_evt_to_vpp (mq, app_evt, SESSION_CTRL_EVT_TRANSPORT_ATTR);
421 mp = (session_transport_attr_msg_t *) app_evt->evt->data;
422 memset (mp, 0, sizeof (*mp));
423 mp->client_index = wrk->api_client_handle;
424 mp->handle = s->vpp_handle;
425 mp->is_get = is_get;
426 mp->attr = *attr;
427 app_send_ctrl_evt_to_vpp (mq, app_evt);
428
429 timeout = clib_time_now (&wrk->clib_time) + 1;
430
431 while (wrk->session_attr_op && clib_time_now (&wrk->clib_time) < timeout)
432 vcl_flush_mq_events ();
433
434 if (!wrk->session_attr_op_rv && is_get)
435 *attr = wrk->session_attr_rv;
436
437 wrk->session_attr_op = 0;
438
439 return wrk->session_attr_op_rv;
440}
441
Florin Coras54693d22018-07-17 10:46:29 -0700442static u32
Florin Coras00cca802019-06-06 09:38:44 -0700443vcl_session_accepted_handler (vcl_worker_t * wrk, session_accepted_msg_t * mp,
444 u32 ls_index)
Florin Coras54693d22018-07-17 10:46:29 -0700445{
446 vcl_session_t *session, *listen_session;
Florin Coras99368312018-08-02 10:45:44 -0700447 svm_msg_q_t *evt_q;
Florin Coras54693d22018-07-17 10:46:29 -0700448
Florin Coras134a9962018-08-28 11:32:04 -0700449 session = vcl_session_alloc (wrk);
Florin Coras99368312018-08-02 10:45:44 -0700450
Florin Coras00cca802019-06-06 09:38:44 -0700451 listen_session = vcl_session_get (wrk, ls_index);
452 if (listen_session->vpp_handle != mp->listener_handle)
Florin Coras54693d22018-07-17 10:46:29 -0700453 {
Florin Coras00cca802019-06-06 09:38:44 -0700454 VDBG (0, "ERROR: listener handle %lu does not match session %u",
455 mp->listener_handle, ls_index);
456 goto error;
457 }
458
Florin Corasf6e284b2021-07-21 18:17:20 -0700459 if (vcl_segment_attach_session (
460 mp->segment_handle, mp->server_rx_fifo, mp->server_tx_fifo,
461 mp->vpp_event_queue_address, mp->mq_index, 0, session))
Florin Coras00cca802019-06-06 09:38:44 -0700462 {
Florin Corasc547e912020-12-08 17:50:45 -0800463 VDBG (0, "failed to attach fifos for %u", session->session_index);
Florin Coras00cca802019-06-06 09:38:44 -0700464 goto error;
Florin Coras54693d22018-07-17 10:46:29 -0700465 }
466
Florin Coras54693d22018-07-17 10:46:29 -0700467 session->vpp_handle = mp->handle;
Florin Corasdfffdd72020-10-15 10:54:47 -0700468 session->session_state = VCL_STATE_READY;
Florin Coras09d18c22019-04-24 11:10:02 -0700469 session->transport.rmt_port = mp->rmt.port;
470 session->transport.is_ip4 = mp->rmt.is_ip4;
471 clib_memcpy_fast (&session->transport.rmt_ip, &mp->rmt.ip,
Dave Barach178cf492018-11-13 16:34:13 -0500472 sizeof (ip46_address_t));
Florin Coras54693d22018-07-17 10:46:29 -0700473
Florin Coras134a9962018-08-28 11:32:04 -0700474 vcl_session_table_add_vpp_handle (wrk, mp->handle, session->session_index);
Florin Coras67c90a32021-03-09 18:36:06 -0800475 session->transport.lcl_port = mp->lcl.port;
476 session->transport.lcl_ip = mp->lcl.ip;
Florin Coras460dce62018-07-27 05:45:06 -0700477 session->session_type = listen_session->session_type;
Nathan Skrzypczak9fd99622019-05-16 14:38:44 +0200478 session->is_dgram = vcl_proto_is_dgram (session->session_type);
479 session->listener_index = listen_session->session_index;
480 listen_session->n_accepted_sessions++;
Florin Coras54693d22018-07-17 10:46:29 -0700481
Florin Coras5e062572019-03-14 19:07:51 -0700482 VDBG (1, "session %u [0x%llx]: client accept request from %s address %U"
483 " port %d queue %p!", session->session_index, mp->handle,
Florin Coras09d18c22019-04-24 11:10:02 -0700484 mp->rmt.is_ip4 ? "IPv4" : "IPv6", format_ip46_address, &mp->rmt.ip,
485 mp->rmt.is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6,
486 clib_net_to_host_u16 (mp->rmt.port), session->vpp_evt_q);
Florin Coras54693d22018-07-17 10:46:29 -0700487 vcl_evt (VCL_EVT_ACCEPT, session, listen_session, session_index);
488
Florin Coras00cca802019-06-06 09:38:44 -0700489 vcl_send_session_accepted_reply (session->vpp_evt_q, mp->context,
490 session->vpp_handle, 0);
491
Florin Coras134a9962018-08-28 11:32:04 -0700492 return session->session_index;
Florin Coras00cca802019-06-06 09:38:44 -0700493
494error:
Florin Corasb4624182020-12-11 13:58:12 -0800495 vcl_segment_attach_mq (vcl_vpp_worker_segment_handle (0),
496 mp->vpp_event_queue_address, mp->mq_index, &evt_q);
Florin Coras00cca802019-06-06 09:38:44 -0700497 vcl_send_session_accepted_reply (evt_q, mp->context, mp->handle,
498 VNET_API_ERROR_INVALID_ARGUMENT);
499 vcl_session_free (wrk, session);
500 return VCL_INVALID_SESSION_INDEX;
Florin Coras54693d22018-07-17 10:46:29 -0700501}
502
503static u32
Florin Coras134a9962018-08-28 11:32:04 -0700504vcl_session_connected_handler (vcl_worker_t * wrk,
505 session_connected_msg_t * mp)
Florin Coras54693d22018-07-17 10:46:29 -0700506{
Florin Coras99368312018-08-02 10:45:44 -0700507 vcl_session_t *session = 0;
Florin Coras52dd29f2020-11-18 19:02:17 -0800508 u32 session_index;
Florin Coras54693d22018-07-17 10:46:29 -0700509
510 session_index = mp->context;
Florin Coras134a9962018-08-28 11:32:04 -0700511 session = vcl_session_get (wrk, session_index);
Florin Corasef2c0f12021-11-10 22:44:52 -0800512 if (PREDICT_FALSE (!session))
Florin Coras070453d2018-08-24 17:04:27 -0700513 {
Florin Coras5e062572019-03-14 19:07:51 -0700514 VDBG (0, "ERROR: vpp handle 0x%llx has no session index (%u)!",
515 mp->handle, session_index);
Florin Corasef2c0f12021-11-10 22:44:52 -0800516 /* Should not happen but if it does, force vpp session cleanup */
517 vcl_session_t tmp_session = {
518 .vpp_handle = mp->handle,
519 .vpp_evt_q = 0,
520 };
521 vcl_segment_attach_session (
522 mp->segment_handle, mp->server_rx_fifo, mp->server_tx_fifo,
523 mp->vpp_event_queue_address, mp->mq_index, 0, session);
524 if (tmp_session.vpp_evt_q)
525 vcl_send_session_disconnect (wrk, &tmp_session);
Florin Coras070453d2018-08-24 17:04:27 -0700526 return VCL_INVALID_SESSION_INDEX;
527 }
Florin Coras54693d22018-07-17 10:46:29 -0700528 if (mp->retval)
529 {
Florin Coras5e062572019-03-14 19:07:51 -0700530 VDBG (0, "ERROR: session index %u: connect failed! %U",
Florin Coras00e01d32019-10-21 16:07:46 -0700531 session_index, format_session_error, mp->retval);
Florin Corasc127d5a2020-10-14 16:35:58 -0700532 session->session_state = VCL_STATE_DETACHED;
Florin Coras070453d2018-08-24 17:04:27 -0700533 session->vpp_handle = mp->handle;
534 return session_index;
Florin Coras54693d22018-07-17 10:46:29 -0700535 }
536
Florin Corasdbc9c592019-09-25 16:37:43 -0700537 session->vpp_handle = mp->handle;
Florin Corasc547e912020-12-08 17:50:45 -0800538
Florin Corasf6e284b2021-07-21 18:17:20 -0700539 if (vcl_segment_attach_session (
540 mp->segment_handle, mp->server_rx_fifo, mp->server_tx_fifo,
541 mp->vpp_event_queue_address, mp->mq_index, 0, session))
Florin Corasd85de682018-11-29 17:02:29 -0800542 {
Florin Corasc547e912020-12-08 17:50:45 -0800543 VDBG (0, "failed to attach fifos for %u", session->session_index);
Florin Corasc127d5a2020-10-14 16:35:58 -0700544 session->session_state = VCL_STATE_DETACHED;
Florin Corasdbc9c592019-09-25 16:37:43 -0700545 vcl_send_session_disconnect (wrk, session);
546 return session_index;
Florin Corasd85de682018-11-29 17:02:29 -0800547 }
548
Florin Coras653e43f2019-03-04 10:56:23 -0800549 if (mp->ct_rx_fifo)
Florin Coras99368312018-08-02 10:45:44 -0700550 {
Florin Corasc547e912020-12-08 17:50:45 -0800551 if (vcl_segment_attach_session (mp->ct_segment_handle, mp->ct_rx_fifo,
Florin Corasf6e284b2021-07-21 18:17:20 -0700552 mp->ct_tx_fifo, (uword) ~0, ~0, 1,
553 session))
Florin Coras653e43f2019-03-04 10:56:23 -0800554 {
Florin Corasc547e912020-12-08 17:50:45 -0800555 VDBG (0, "failed to attach ct fifos for %u", session->session_index);
Florin Corasc127d5a2020-10-14 16:35:58 -0700556 session->session_state = VCL_STATE_DETACHED;
Florin Corasdbc9c592019-09-25 16:37:43 -0700557 vcl_send_session_disconnect (wrk, session);
558 return session_index;
Florin Coras653e43f2019-03-04 10:56:23 -0800559 }
Florin Coras99368312018-08-02 10:45:44 -0700560 }
Florin Coras54693d22018-07-17 10:46:29 -0700561
Florin Coras09d18c22019-04-24 11:10:02 -0700562 session->transport.is_ip4 = mp->lcl.is_ip4;
563 clib_memcpy_fast (&session->transport.lcl_ip, &mp->lcl.ip,
Dave Barach178cf492018-11-13 16:34:13 -0500564 sizeof (session->transport.lcl_ip));
Florin Coras09d18c22019-04-24 11:10:02 -0700565 session->transport.lcl_port = mp->lcl.port;
Florin Corasa5ea8212020-08-24 21:23:51 -0700566
567 /* Application closed session before connect reply */
Florin Corasac422d62020-10-19 20:51:36 -0700568 if (vcl_session_has_attr (session, VCL_SESS_ATTR_NONBLOCK)
Florin Corasc127d5a2020-10-14 16:35:58 -0700569 && session->session_state == VCL_STATE_CLOSED)
Florin Corasa5ea8212020-08-24 21:23:51 -0700570 vcl_send_session_disconnect (wrk, session);
571 else
Florin Corasdfffdd72020-10-15 10:54:47 -0700572 session->session_state = VCL_STATE_READY;
Florin Coras54693d22018-07-17 10:46:29 -0700573
574 /* Add it to lookup table */
Florin Coras3c7d4f92018-12-14 11:28:43 -0800575 vcl_session_table_add_vpp_handle (wrk, mp->handle, session_index);
Florin Coras54693d22018-07-17 10:46:29 -0700576
Florin Coras5e062572019-03-14 19:07:51 -0700577 VDBG (1, "session %u [0x%llx] connected! rx_fifo %p, refcnt %d, tx_fifo %p,"
578 " refcnt %d", session_index, mp->handle, session->rx_fifo,
Florin Coras54693d22018-07-17 10:46:29 -0700579 session->rx_fifo->refcnt, session->tx_fifo, session->tx_fifo->refcnt);
Florin Coras070453d2018-08-24 17:04:27 -0700580
Florin Coras54693d22018-07-17 10:46:29 -0700581 return session_index;
582}
583
Florin Coras3c7d4f92018-12-14 11:28:43 -0800584static int
585vcl_flag_accepted_session (vcl_session_t * session, u64 handle, u32 flags)
586{
587 vcl_session_msg_t *accepted_msg;
588 int i;
589
590 for (i = 0; i < vec_len (session->accept_evts_fifo); i++)
591 {
592 accepted_msg = &session->accept_evts_fifo[i];
593 if (accepted_msg->accepted_msg.handle == handle)
594 {
Florin Corasb0f662f2018-12-27 14:51:46 -0800595 accepted_msg->flags |= flags;
Florin Coras3c7d4f92018-12-14 11:28:43 -0800596 return 1;
597 }
598 }
599 return 0;
600}
601
Florin Corasc9fbd662018-08-24 12:59:56 -0700602static u32
Florin Coras134a9962018-08-28 11:32:04 -0700603vcl_session_reset_handler (vcl_worker_t * wrk,
604 session_reset_msg_t * reset_msg)
Florin Corasc9fbd662018-08-24 12:59:56 -0700605{
606 vcl_session_t *session;
607 u32 sid;
608
Florin Coras134a9962018-08-28 11:32:04 -0700609 sid = vcl_session_index_from_vpp_handle (wrk, reset_msg->handle);
610 session = vcl_session_get (wrk, sid);
Florin Corasc9fbd662018-08-24 12:59:56 -0700611 if (!session)
612 {
613 VDBG (0, "request to reset unknown handle 0x%llx", reset_msg->handle);
614 return VCL_INVALID_SESSION_INDEX;
615 }
Florin Coras3c7d4f92018-12-14 11:28:43 -0800616
617 /* Caught a reset before actually accepting the session */
Florin Corasc127d5a2020-10-14 16:35:58 -0700618 if (session->session_state == VCL_STATE_LISTEN)
Florin Coras3c7d4f92018-12-14 11:28:43 -0800619 {
620
621 if (!vcl_flag_accepted_session (session, reset_msg->handle,
622 VCL_ACCEPTED_F_RESET))
623 VDBG (0, "session was not accepted!");
624 return VCL_INVALID_SESSION_INDEX;
625 }
626
Florin Corasc127d5a2020-10-14 16:35:58 -0700627 if (session->session_state != VCL_STATE_CLOSED)
628 session->session_state = VCL_STATE_DISCONNECT;
Florin Coras3c7d4f92018-12-14 11:28:43 -0800629 VDBG (0, "reset session %u [0x%llx]", sid, reset_msg->handle);
Florin Corasc9fbd662018-08-24 12:59:56 -0700630 return sid;
631}
632
Florin Coras60116992018-08-27 09:52:18 -0700633static u32
Florin Coras134a9962018-08-28 11:32:04 -0700634vcl_session_bound_handler (vcl_worker_t * wrk, session_bound_msg_t * mp)
Florin Coras60116992018-08-27 09:52:18 -0700635{
636 vcl_session_t *session;
637 u32 sid = mp->context;
638
Florin Coras134a9962018-08-28 11:32:04 -0700639 session = vcl_session_get (wrk, sid);
Florin Coras60116992018-08-27 09:52:18 -0700640 if (mp->retval)
641 {
Florin Coras5e062572019-03-14 19:07:51 -0700642 VERR ("session %u [0x%llx]: bind failed: %U", sid, mp->handle,
Florin Coras00e01d32019-10-21 16:07:46 -0700643 format_session_error, mp->retval);
Florin Coras60116992018-08-27 09:52:18 -0700644 if (session)
645 {
Florin Corasc127d5a2020-10-14 16:35:58 -0700646 session->session_state = VCL_STATE_DETACHED;
Florin Coras60116992018-08-27 09:52:18 -0700647 session->vpp_handle = mp->handle;
648 return sid;
649 }
650 else
651 {
Florin Coras5e062572019-03-14 19:07:51 -0700652 VDBG (0, "ERROR: session %u [0x%llx]: Invalid session index!",
653 sid, mp->handle);
Florin Coras60116992018-08-27 09:52:18 -0700654 return VCL_INVALID_SESSION_INDEX;
655 }
656 }
657
658 session->vpp_handle = mp->handle;
659 session->transport.is_ip4 = mp->lcl_is_ip4;
Dave Barach178cf492018-11-13 16:34:13 -0500660 clib_memcpy_fast (&session->transport.lcl_ip, mp->lcl_ip,
661 sizeof (ip46_address_t));
Florin Coras60116992018-08-27 09:52:18 -0700662 session->transport.lcl_port = mp->lcl_port;
Florin Coras134a9962018-08-28 11:32:04 -0700663 vcl_session_table_add_listener (wrk, mp->handle, sid);
Florin Corasc127d5a2020-10-14 16:35:58 -0700664 session->session_state = VCL_STATE_LISTEN;
Florin Coras5f45e012019-01-23 09:21:30 -0800665
Florin Coras6e3c1f82020-01-15 01:30:46 +0000666 if (vcl_session_is_cl (session))
Florin Coras60116992018-08-27 09:52:18 -0700667 {
Florin Corasc547e912020-12-08 17:50:45 -0800668 if (vcl_segment_attach_session (mp->segment_handle, mp->rx_fifo,
Florin Corasf6e284b2021-07-21 18:17:20 -0700669 mp->tx_fifo, mp->vpp_evt_q, mp->mq_index,
670 0, session))
Florin Corasc547e912020-12-08 17:50:45 -0800671 {
672 VDBG (0, "failed to attach fifos for %u", session->session_index);
673 session->session_state = VCL_STATE_DETACHED;
674 return VCL_INVALID_SESSION_INDEX;
675 }
Florin Coras60116992018-08-27 09:52:18 -0700676 }
677
Florin Coras05ecfcc2018-12-12 18:19:39 -0800678 VDBG (0, "session %u [0x%llx]: listen succeeded!", sid, mp->handle);
Florin Coras60116992018-08-27 09:52:18 -0700679 return sid;
680}
681
Florin Corasdfae9f92019-02-20 19:48:31 -0800682static void
683vcl_session_unlisten_reply_handler (vcl_worker_t * wrk, void *data)
684{
685 session_unlisten_reply_msg_t *mp = (session_unlisten_reply_msg_t *) data;
686 vcl_session_t *s;
687
688 s = vcl_session_get_w_vpp_handle (wrk, mp->handle);
Florin Coras0a1e1832020-03-29 18:54:04 +0000689 if (!s)
Florin Corasdfae9f92019-02-20 19:48:31 -0800690 {
691 VDBG (0, "Unlisten reply with wrong handle %llx", mp->handle);
692 return;
693 }
Florin Corasc127d5a2020-10-14 16:35:58 -0700694 if (s->session_state != VCL_STATE_DISCONNECT)
Florin Coras0a1e1832020-03-29 18:54:04 +0000695 {
696 /* Connected udp listener */
697 if (s->session_type == VPPCOM_PROTO_UDP
Florin Corasc127d5a2020-10-14 16:35:58 -0700698 && s->session_state == VCL_STATE_CLOSED)
Florin Coras0a1e1832020-03-29 18:54:04 +0000699 return;
700
701 VDBG (0, "Unlisten session in wrong state %llx", mp->handle);
702 return;
703 }
Florin Corasdfae9f92019-02-20 19:48:31 -0800704
705 if (mp->retval)
706 VDBG (0, "ERROR: session %u [0xllx]: unlisten failed: %U",
Florin Coras00e01d32019-10-21 16:07:46 -0700707 s->session_index, mp->handle, format_session_error, mp->retval);
Florin Corasdfae9f92019-02-20 19:48:31 -0800708
709 if (mp->context != wrk->wrk_index)
710 VDBG (0, "wrong context");
711
712 vcl_session_table_del_vpp_handle (wrk, mp->handle);
713 vcl_session_free (wrk, s);
714}
715
Florin Coras68b7e582020-01-21 18:33:23 -0800716static void
717vcl_session_migrated_handler (vcl_worker_t * wrk, void *data)
718{
719 session_migrated_msg_t *mp = (session_migrated_msg_t *) data;
720 vcl_session_t *s;
Florin Corasc547e912020-12-08 17:50:45 -0800721 u32 fs_index;
Florin Coras68b7e582020-01-21 18:33:23 -0800722
723 s = vcl_session_get_w_vpp_handle (wrk, mp->handle);
724 if (!s)
725 {
726 VDBG (0, "Migrated notification with wrong handle %llx", mp->handle);
727 return;
728 }
729
Florin Coras1bb74942021-02-10 15:26:37 -0800730 /* Only validate if a value is provided */
731 if (mp->segment_handle != SESSION_INVALID_HANDLE)
Florin Corasc547e912020-12-08 17:50:45 -0800732 {
Florin Coras1bb74942021-02-10 15:26:37 -0800733 fs_index = vcl_segment_table_lookup (mp->segment_handle);
734 if (fs_index == VCL_INVALID_SEGMENT_INDEX)
735 {
736 VDBG (0, "segment %lx for session %u is not mounted!",
737 mp->segment_handle, s->session_index);
738 s->session_state = VCL_STATE_DETACHED;
739 return;
740 }
Florin Corasc547e912020-12-08 17:50:45 -0800741 }
742
Florin Coras57660d92020-04-04 22:45:34 +0000743 s->vpp_handle = mp->new_handle;
Florin Corasb4624182020-12-11 13:58:12 -0800744
745 vcl_segment_attach_mq (vcl_vpp_worker_segment_handle (0), mp->vpp_evt_q,
746 mp->vpp_thread_index, &s->vpp_evt_q);
Florin Coras68b7e582020-01-21 18:33:23 -0800747
Florin Coras68b7e582020-01-21 18:33:23 -0800748 vcl_session_table_del_vpp_handle (wrk, mp->handle);
749 vcl_session_table_add_vpp_handle (wrk, mp->new_handle, s->session_index);
750
751 /* Generate new tx event if we have outstanding data */
752 if (svm_fifo_has_event (s->tx_fifo))
Florin Corasc547e912020-12-08 17:50:45 -0800753 app_send_io_evt_to_vpp (s->vpp_evt_q,
754 s->tx_fifo->shr->master_session_index,
Florin Coras68b7e582020-01-21 18:33:23 -0800755 SESSION_IO_EVT_TX, SVM_Q_WAIT);
756
Florin Coras57660d92020-04-04 22:45:34 +0000757 VDBG (0, "Migrated 0x%lx to thread %u 0x%lx", mp->handle,
Florin Coras52dd29f2020-11-18 19:02:17 -0800758 mp->vpp_thread_index, mp->new_handle);
Florin Coras68b7e582020-01-21 18:33:23 -0800759}
760
Florin Coras3c7d4f92018-12-14 11:28:43 -0800761static vcl_session_t *
762vcl_session_accepted (vcl_worker_t * wrk, session_accepted_msg_t * msg)
763{
764 vcl_session_msg_t *vcl_msg;
765 vcl_session_t *session;
766
767 session = vcl_session_get_w_vpp_handle (wrk, msg->handle);
768 if (PREDICT_FALSE (session != 0))
Florin Corasb0f662f2018-12-27 14:51:46 -0800769 VWRN ("session overlap handle %lu state %u!", msg->handle,
770 session->session_state);
Florin Coras3c7d4f92018-12-14 11:28:43 -0800771
772 session = vcl_session_table_lookup_listener (wrk, msg->listener_handle);
773 if (!session)
774 {
775 VERR ("couldn't find listen session: listener handle %llx",
776 msg->listener_handle);
777 return 0;
778 }
779
780 clib_fifo_add2 (session->accept_evts_fifo, vcl_msg);
Florin Corase88845e2020-02-13 20:04:28 +0000781 vcl_msg->flags = 0;
Florin Coras3c7d4f92018-12-14 11:28:43 -0800782 vcl_msg->accepted_msg = *msg;
783 /* Session handle points to listener until fully accepted by app */
784 vcl_session_table_add_vpp_handle (wrk, msg->handle, session->session_index);
785
786 return session;
787}
788
789static vcl_session_t *
790vcl_session_disconnected_handler (vcl_worker_t * wrk,
791 session_disconnected_msg_t * msg)
792{
793 vcl_session_t *session;
794
795 session = vcl_session_get_w_vpp_handle (wrk, msg->handle);
796 if (!session)
797 {
798 VDBG (0, "request to disconnect unknown handle 0x%llx", msg->handle);
799 return 0;
800 }
801
Florin Corasadcfb152020-02-12 08:50:29 +0000802 /* Late disconnect notification on a session that has been closed */
Florin Corasc127d5a2020-10-14 16:35:58 -0700803 if (session->session_state == VCL_STATE_CLOSED)
Florin Corasadcfb152020-02-12 08:50:29 +0000804 return 0;
805
Florin Coras3c7d4f92018-12-14 11:28:43 -0800806 /* Caught a disconnect before actually accepting the session */
Florin Corasc127d5a2020-10-14 16:35:58 -0700807 if (session->session_state == VCL_STATE_LISTEN)
Florin Coras3c7d4f92018-12-14 11:28:43 -0800808 {
Florin Coras3c7d4f92018-12-14 11:28:43 -0800809 if (!vcl_flag_accepted_session (session, msg->handle,
810 VCL_ACCEPTED_F_CLOSED))
811 VDBG (0, "session was not accepted!");
812 return 0;
813 }
814
Florin Corasadcfb152020-02-12 08:50:29 +0000815 /* If not already reset change state */
Florin Corasc127d5a2020-10-14 16:35:58 -0700816 if (session->session_state != VCL_STATE_DISCONNECT)
817 session->session_state = VCL_STATE_VPP_CLOSING;
Florin Corasadcfb152020-02-12 08:50:29 +0000818
Florin Coras3c7d4f92018-12-14 11:28:43 -0800819 return session;
820}
821
liuyacan534468e2021-05-09 03:50:40 +0000822int
liuyacan55c952e2021-06-13 14:54:55 +0800823vppcom_session_shutdown (uint32_t session_handle, int how)
liuyacan534468e2021-05-09 03:50:40 +0000824{
825 vcl_worker_t *wrk = vcl_worker_get_current ();
826 vcl_session_t *session;
827 vcl_session_state_t state;
828 u64 vpp_handle;
829
830 session = vcl_session_get_w_handle (wrk, session_handle);
831 if (PREDICT_FALSE (!session))
832 return VPPCOM_EBADFD;
833
834 vpp_handle = session->vpp_handle;
835 state = session->session_state;
836
837 VDBG (1, "session %u [0x%llx] state 0x%x (%s)", session->session_index,
838 vpp_handle, state, vppcom_session_state_str (state));
839
840 if (PREDICT_FALSE (state == VCL_STATE_LISTEN))
841 {
842 VDBG (0, "ERROR: Cannot shutdown a listen socket!");
843 return VPPCOM_EBADFD;
844 }
845
liuyacan55c952e2021-06-13 14:54:55 +0800846 if (how == SHUT_RD || how == SHUT_RDWR)
847 {
848 session->flags |= VCL_SESSION_F_RD_SHUTDOWN;
849 if (how == SHUT_RD)
850 return VPPCOM_OK;
851 }
852 session->flags |= VCL_SESSION_F_WR_SHUTDOWN;
853
liuyacan534468e2021-05-09 03:50:40 +0000854 if (PREDICT_TRUE (state == VCL_STATE_READY))
855 {
856 VDBG (1, "session %u [0x%llx]: sending shutdown...",
857 session->session_index, vpp_handle);
858
859 vcl_send_session_shutdown (wrk, session);
liuyacan534468e2021-05-09 03:50:40 +0000860 }
861
862 return VPPCOM_OK;
863}
864
Florin Coras2bd8b3a2020-10-25 20:28:23 -0700865static int
866vppcom_session_disconnect (u32 session_handle)
867{
868 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras2bd8b3a2020-10-25 20:28:23 -0700869 vcl_session_t *session, *listen_session;
870 vcl_session_state_t state;
871 u64 vpp_handle;
872
873 session = vcl_session_get_w_handle (wrk, session_handle);
874 if (!session)
875 return VPPCOM_EBADFD;
876
877 vpp_handle = session->vpp_handle;
878 state = session->session_state;
879
880 VDBG (1, "session %u [0x%llx] state 0x%x (%s)", session->session_index,
881 vpp_handle, state, vppcom_session_state_str (state));
882
883 if (PREDICT_FALSE (state == VCL_STATE_LISTEN))
884 {
885 VDBG (0, "ERROR: Cannot disconnect a listen socket!");
886 return VPPCOM_EBADFD;
887 }
888
889 if (state == VCL_STATE_VPP_CLOSING)
890 {
Florin Coras52dd29f2020-11-18 19:02:17 -0800891 vcl_send_session_disconnected_reply (wrk, session, 0);
Florin Coras2bd8b3a2020-10-25 20:28:23 -0700892 VDBG (1, "session %u [0x%llx]: sending disconnect REPLY...",
893 session->session_index, vpp_handle);
894 }
895 else
896 {
897 /* Session doesn't have an event queue yet. Probably a non-blocking
898 * connect. Wait for the reply */
899 if (PREDICT_FALSE (!session->vpp_evt_q))
900 return VPPCOM_OK;
901
902 VDBG (1, "session %u [0x%llx]: sending disconnect...",
903 session->session_index, vpp_handle);
904 vcl_send_session_disconnect (wrk, session);
905 }
906
907 if (session->listener_index != VCL_INVALID_SESSION_INDEX)
908 {
909 listen_session = vcl_session_get (wrk, session->listener_index);
910 listen_session->n_accepted_sessions--;
911 }
912
913 return VPPCOM_OK;
914}
915
Florin Coras30e79c22019-01-02 19:31:22 -0800916static void
Florin Coras9ace36d2019-10-28 13:14:17 -0700917vcl_session_cleanup_handler (vcl_worker_t * wrk, void *data)
918{
919 session_cleanup_msg_t *msg;
920 vcl_session_t *session;
921
922 msg = (session_cleanup_msg_t *) data;
923 session = vcl_session_get_w_vpp_handle (wrk, msg->handle);
924 if (!session)
925 {
926 VDBG (0, "disconnect confirmed for unknown handle 0x%llx", msg->handle);
927 return;
928 }
929
Florin Coras36d49392020-04-24 23:00:11 +0000930 if (msg->type == SESSION_CLEANUP_TRANSPORT)
931 {
932 /* Transport was cleaned up before we confirmed close. Probably the
933 * app is still waiting for some data that cannot be delivered.
Florin Coras2bd8b3a2020-10-25 20:28:23 -0700934 * Confirm close to make sure everything is cleaned up.
935 * Move to undetermined state to ensure that the session is not
936 * removed before both vpp and the app cleanup.
937 * - If the app closes first, the session is moved to CLOSED state
938 * and the session cleanup notification from vpp removes the
939 * session.
940 * - If vpp cleans up the session first, the session is moved to
941 * DETACHED state lower and subsequently the close from the app
942 * frees the session
943 */
944 if (session->session_state == VCL_STATE_VPP_CLOSING)
Florin Coras0ff7eec2020-08-03 18:55:40 -0700945 {
Florin Coras2bd8b3a2020-10-25 20:28:23 -0700946 vppcom_session_disconnect (vcl_session_handle (session));
947 session->session_state = VCL_STATE_UPDATED;
948 }
949 else if (session->session_state == VCL_STATE_DISCONNECT)
950 {
Florin Coras52dd29f2020-11-18 19:02:17 -0800951 vcl_send_session_reset_reply (wrk, session, 0);
Florin Coras0ff7eec2020-08-03 18:55:40 -0700952 session->session_state = VCL_STATE_UPDATED;
953 }
Florin Coras36d49392020-04-24 23:00:11 +0000954 return;
955 }
956
Florin Coras9ace36d2019-10-28 13:14:17 -0700957 vcl_session_table_del_vpp_handle (wrk, msg->handle);
Florin Corasadcfb152020-02-12 08:50:29 +0000958 /* Should not happen. App did not close the connection so don't free it. */
Florin Corasc127d5a2020-10-14 16:35:58 -0700959 if (session->session_state != VCL_STATE_CLOSED)
Florin Corasadcfb152020-02-12 08:50:29 +0000960 {
961 VDBG (0, "app did not close session %d", session->session_index);
Florin Corasc127d5a2020-10-14 16:35:58 -0700962 session->session_state = VCL_STATE_DETACHED;
Florin Corasadcfb152020-02-12 08:50:29 +0000963 session->vpp_handle = VCL_INVALID_SESSION_HANDLE;
964 return;
965 }
Florin Coras9ace36d2019-10-28 13:14:17 -0700966 vcl_session_free (wrk, session);
967}
968
969static void
Florin Coras30e79c22019-01-02 19:31:22 -0800970vcl_session_req_worker_update_handler (vcl_worker_t * wrk, void *data)
971{
972 session_req_worker_update_msg_t *msg;
973 vcl_session_t *s;
974
975 msg = (session_req_worker_update_msg_t *) data;
976 s = vcl_session_get_w_vpp_handle (wrk, msg->session_handle);
977 if (!s)
978 return;
979
980 vec_add1 (wrk->pending_session_wrk_updates, s->session_index);
981}
982
983static void
984vcl_session_worker_update_reply_handler (vcl_worker_t * wrk, void *data)
985{
986 session_worker_update_reply_msg_t *msg;
987 vcl_session_t *s;
988
989 msg = (session_worker_update_reply_msg_t *) data;
990 s = vcl_session_get_w_vpp_handle (wrk, msg->handle);
991 if (!s)
992 {
993 VDBG (0, "unknown handle 0x%llx", msg->handle);
994 return;
995 }
Florin Coras30e79c22019-01-02 19:31:22 -0800996
Florin Coras5f45e012019-01-23 09:21:30 -0800997 if (s->rx_fifo)
998 {
Florin Corasc547e912020-12-08 17:50:45 -0800999 if (vcl_segment_attach_session (msg->segment_handle, msg->rx_fifo,
Florin Corasf6e284b2021-07-21 18:17:20 -07001000 msg->tx_fifo, (uword) ~0, ~0, 0, s))
Florin Corasc547e912020-12-08 17:50:45 -08001001 {
1002 VDBG (0, "failed to attach fifos for %u", s->session_index);
1003 return;
1004 }
Florin Coras5f45e012019-01-23 09:21:30 -08001005 }
Florin Corasc127d5a2020-10-14 16:35:58 -07001006 s->session_state = VCL_STATE_UPDATED;
Florin Coras30e79c22019-01-02 19:31:22 -08001007
Florin Coras30e79c22019-01-02 19:31:22 -08001008 VDBG (0, "session %u[0x%llx] moved to worker %u", s->session_index,
1009 s->vpp_handle, wrk->wrk_index);
1010}
1011
Florin Coras935ce752020-09-08 22:43:47 -07001012static int
1013vcl_api_recv_fd (vcl_worker_t * wrk, int *fds, int n_fds)
1014{
1015
1016 if (vcm->cfg.vpp_app_socket_api)
1017 return vcl_sapi_recv_fds (wrk, fds, n_fds);
1018
1019 return vcl_bapi_recv_fds (wrk, fds, n_fds);
1020}
1021
Florin Corasc4c4cf52019-08-24 18:17:34 -07001022static void
1023vcl_session_app_add_segment_handler (vcl_worker_t * wrk, void *data)
1024{
1025 ssvm_segment_type_t seg_type = SSVM_SEGMENT_SHM;
1026 session_app_add_segment_msg_t *msg;
1027 u64 segment_handle;
1028 int fd = -1;
1029
1030 msg = (session_app_add_segment_msg_t *) data;
1031
1032 if (msg->fd_flags)
1033 {
Florin Coras935ce752020-09-08 22:43:47 -07001034 vcl_api_recv_fd (wrk, &fd, 1);
Florin Corasc4c4cf52019-08-24 18:17:34 -07001035 seg_type = SSVM_SEGMENT_MEMFD;
1036 }
1037
1038 segment_handle = msg->segment_handle;
1039 if (segment_handle == VCL_INVALID_SEGMENT_HANDLE)
1040 {
1041 clib_warning ("invalid segment handle");
1042 return;
1043 }
1044
1045 if (vcl_segment_attach (segment_handle, (char *) msg->segment_name,
1046 seg_type, fd))
1047 {
1048 VDBG (0, "vcl_segment_attach ('%s') failed", msg->segment_name);
1049 return;
1050 }
1051
1052 VDBG (1, "mapped new segment '%s' size %d", msg->segment_name,
1053 msg->segment_size);
1054}
1055
1056static void
1057vcl_session_app_del_segment_handler (vcl_worker_t * wrk, void *data)
1058{
1059 session_app_del_segment_msg_t *msg = (session_app_del_segment_msg_t *) data;
1060 vcl_segment_detach (msg->segment_handle);
1061 VDBG (1, "Unmapped segment: %d", msg->segment_handle);
1062}
1063
Florin Coras40c07ce2020-07-16 20:46:17 -07001064static void
1065vcl_worker_rpc_handler (vcl_worker_t * wrk, void *data)
1066{
1067 if (!vcm->wrk_rpc_fn)
1068 return;
1069
hanlina3a48962020-07-13 11:09:15 +08001070 (vcm->wrk_rpc_fn) (((session_app_wrk_rpc_msg_t *) data)->data);
Florin Coras40c07ce2020-07-16 20:46:17 -07001071}
1072
Florin Coras04ae8272021-04-12 19:55:37 -07001073static void
1074vcl_session_transport_attr_reply_handler (vcl_worker_t *wrk, void *data)
1075{
1076 session_transport_attr_reply_msg_t *mp;
1077
1078 if (!wrk->session_attr_op)
1079 return;
1080
1081 mp = (session_transport_attr_reply_msg_t *) data;
1082
1083 wrk->session_attr_op_rv = mp->retval;
1084 wrk->session_attr_op = 0;
1085 wrk->session_attr_rv = mp->attr;
1086}
1087
Florin Coras86f04502018-09-12 16:08:01 -07001088static int
1089vcl_handle_mq_event (vcl_worker_t * wrk, session_event_t * e)
Florin Coras54693d22018-07-17 10:46:29 -07001090{
Florin Coras54693d22018-07-17 10:46:29 -07001091 session_disconnected_msg_t *disconnected_msg;
Florin Corasb242d312020-10-26 15:35:40 -07001092 session_connected_msg_t *connected_msg;
1093 session_reset_msg_t *reset_msg;
1094 session_event_t *ecpy;
Florin Corasc127d5a2020-10-14 16:35:58 -07001095 vcl_session_t *s;
Florin Corasb242d312020-10-26 15:35:40 -07001096 u32 sid;
Florin Coras54693d22018-07-17 10:46:29 -07001097
1098 switch (e->event_type)
1099 {
Florin Coras653e43f2019-03-04 10:56:23 -08001100 case SESSION_IO_EVT_RX:
1101 case SESSION_IO_EVT_TX:
Florin Corasc127d5a2020-10-14 16:35:58 -07001102 s = vcl_session_get (wrk, e->session_index);
Florin Coras1bc919e2020-10-18 20:17:49 -07001103 if (!s || !vcl_session_is_open (s))
Florin Coras653e43f2019-03-04 10:56:23 -08001104 break;
Florin Coras86f04502018-09-12 16:08:01 -07001105 vec_add1 (wrk->unhandled_evts_vector, *e);
Florin Coras54693d22018-07-17 10:46:29 -07001106 break;
Florin Corasb242d312020-10-26 15:35:40 -07001107 case SESSION_CTRL_EVT_BOUND:
1108 /* We can only wait for only one listen so not postponed */
1109 vcl_session_bound_handler (wrk, (session_bound_msg_t *) e->data);
1110 break;
Florin Coras54693d22018-07-17 10:46:29 -07001111 case SESSION_CTRL_EVT_ACCEPTED:
Florin Corasb242d312020-10-26 15:35:40 -07001112 s = vcl_session_accepted (wrk, (session_accepted_msg_t *) e->data);
1113 if (vcl_session_has_attr (s, VCL_SESS_ATTR_NONBLOCK))
1114 {
1115 vec_add2 (wrk->unhandled_evts_vector, ecpy, 1);
1116 *ecpy = *e;
1117 ecpy->postponed = 1;
1118 ecpy->session_index = s->session_index;
1119 }
Florin Coras54693d22018-07-17 10:46:29 -07001120 break;
1121 case SESSION_CTRL_EVT_CONNECTED:
Florin Corasb242d312020-10-26 15:35:40 -07001122 connected_msg = (session_connected_msg_t *) e->data;
1123 sid = vcl_session_connected_handler (wrk, connected_msg);
1124 if (!(s = vcl_session_get (wrk, sid)))
1125 break;
1126 if (vcl_session_has_attr (s, VCL_SESS_ATTR_NONBLOCK))
1127 {
1128 vec_add2 (wrk->unhandled_evts_vector, ecpy, 1);
1129 *ecpy = *e;
1130 ecpy->postponed = 1;
1131 ecpy->session_index = s->session_index;
1132 }
Florin Coras54693d22018-07-17 10:46:29 -07001133 break;
1134 case SESSION_CTRL_EVT_DISCONNECTED:
1135 disconnected_msg = (session_disconnected_msg_t *) e->data;
Florin Corasb242d312020-10-26 15:35:40 -07001136 if (!(s = vcl_session_get_w_vpp_handle (wrk, disconnected_msg->handle)))
1137 break;
1138 if (vcl_session_has_attr (s, VCL_SESS_ATTR_NONBLOCK))
1139 {
1140 vec_add1 (wrk->unhandled_evts_vector, *e);
1141 break;
1142 }
1143 if (!(s = vcl_session_disconnected_handler (wrk, disconnected_msg)))
Florin Coras3c7d4f92018-12-14 11:28:43 -08001144 break;
Florin Corasc127d5a2020-10-14 16:35:58 -07001145 VDBG (0, "disconnected session %u [0x%llx]", s->session_index,
1146 s->vpp_handle);
Florin Corasc9fbd662018-08-24 12:59:56 -07001147 break;
1148 case SESSION_CTRL_EVT_RESET:
Florin Corasb242d312020-10-26 15:35:40 -07001149 reset_msg = (session_reset_msg_t *) e->data;
1150 if (!(s = vcl_session_get_w_vpp_handle (wrk, reset_msg->handle)))
1151 break;
1152 if (vcl_session_has_attr (s, VCL_SESS_ATTR_NONBLOCK))
1153 {
1154 vec_add1 (wrk->unhandled_evts_vector, *e);
1155 break;
1156 }
Florin Coras134a9962018-08-28 11:32:04 -07001157 vcl_session_reset_handler (wrk, (session_reset_msg_t *) e->data);
Florin Coras60116992018-08-27 09:52:18 -07001158 break;
Florin Corasdfae9f92019-02-20 19:48:31 -08001159 case SESSION_CTRL_EVT_UNLISTEN_REPLY:
1160 vcl_session_unlisten_reply_handler (wrk, e->data);
1161 break;
Florin Coras68b7e582020-01-21 18:33:23 -08001162 case SESSION_CTRL_EVT_MIGRATED:
1163 vcl_session_migrated_handler (wrk, e->data);
1164 break;
Florin Coras9ace36d2019-10-28 13:14:17 -07001165 case SESSION_CTRL_EVT_CLEANUP:
1166 vcl_session_cleanup_handler (wrk, e->data);
1167 break;
Florin Coras30e79c22019-01-02 19:31:22 -08001168 case SESSION_CTRL_EVT_REQ_WORKER_UPDATE:
1169 vcl_session_req_worker_update_handler (wrk, e->data);
1170 break;
1171 case SESSION_CTRL_EVT_WORKER_UPDATE_REPLY:
1172 vcl_session_worker_update_reply_handler (wrk, e->data);
1173 break;
Florin Corasc4c4cf52019-08-24 18:17:34 -07001174 case SESSION_CTRL_EVT_APP_ADD_SEGMENT:
1175 vcl_session_app_add_segment_handler (wrk, e->data);
1176 break;
1177 case SESSION_CTRL_EVT_APP_DEL_SEGMENT:
1178 vcl_session_app_del_segment_handler (wrk, e->data);
1179 break;
hanlina3a48962020-07-13 11:09:15 +08001180 case SESSION_CTRL_EVT_APP_WRK_RPC:
Florin Coras40c07ce2020-07-16 20:46:17 -07001181 vcl_worker_rpc_handler (wrk, e->data);
1182 break;
Florin Coras04ae8272021-04-12 19:55:37 -07001183 case SESSION_CTRL_EVT_TRANSPORT_ATTR_REPLY:
1184 vcl_session_transport_attr_reply_handler (wrk, e->data);
1185 break;
Florin Coras54693d22018-07-17 10:46:29 -07001186 default:
1187 clib_warning ("unhandled %u", e->event_type);
1188 }
1189 return VPPCOM_OK;
1190}
1191
Florin Coras30e79c22019-01-02 19:31:22 -08001192static int
Florin Coras697faea2018-06-27 17:10:49 -07001193vppcom_wait_for_session_state_change (u32 session_index,
Florin Coras288eaab2019-02-03 15:26:14 -08001194 vcl_session_state_t state,
Florin Coras697faea2018-06-27 17:10:49 -07001195 f64 wait_for_time)
1196{
Florin Coras134a9962018-08-28 11:32:04 -07001197 vcl_worker_t *wrk = vcl_worker_get_current ();
1198 f64 timeout = clib_time_now (&wrk->clib_time) + wait_for_time;
Florin Coras697faea2018-06-27 17:10:49 -07001199 vcl_session_t *volatile session;
Florin Coras54693d22018-07-17 10:46:29 -07001200 svm_msg_q_msg_t msg;
1201 session_event_t *e;
Dave Wallace543852a2017-08-03 02:11:34 -04001202
Florin Coras697faea2018-06-27 17:10:49 -07001203 do
Dave Wallace543852a2017-08-03 02:11:34 -04001204 {
Florin Coras134a9962018-08-28 11:32:04 -07001205 session = vcl_session_get (wrk, session_index);
Florin Coras070453d2018-08-24 17:04:27 -07001206 if (PREDICT_FALSE (!session))
Florin Coras697faea2018-06-27 17:10:49 -07001207 {
Florin Coras070453d2018-08-24 17:04:27 -07001208 return VPPCOM_EBADFD;
Florin Coras697faea2018-06-27 17:10:49 -07001209 }
Florin Corasdfffdd72020-10-15 10:54:47 -07001210 if (session->session_state == state)
Florin Coras697faea2018-06-27 17:10:49 -07001211 {
Florin Coras697faea2018-06-27 17:10:49 -07001212 return VPPCOM_OK;
1213 }
Florin Corasc127d5a2020-10-14 16:35:58 -07001214 if (session->session_state == VCL_STATE_DETACHED)
Florin Coras697faea2018-06-27 17:10:49 -07001215 {
Florin Coras697faea2018-06-27 17:10:49 -07001216 return VPPCOM_ECONNREFUSED;
1217 }
Florin Coras54693d22018-07-17 10:46:29 -07001218
Florin Coras134a9962018-08-28 11:32:04 -07001219 if (svm_msg_q_sub (wrk->app_event_queue, &msg, SVM_Q_NOWAIT, 0))
Florin Corasdc2e2512018-12-03 17:47:26 -08001220 {
1221 usleep (100);
1222 continue;
1223 }
Florin Coras134a9962018-08-28 11:32:04 -07001224 e = svm_msg_q_msg_data (wrk->app_event_queue, &msg);
Florin Coras86f04502018-09-12 16:08:01 -07001225 vcl_handle_mq_event (wrk, e);
Florin Coras134a9962018-08-28 11:32:04 -07001226 svm_msg_q_free_msg (wrk->app_event_queue, &msg);
Florin Corasdcf55ce2017-11-16 15:32:50 -08001227 }
Florin Coras134a9962018-08-28 11:32:04 -07001228 while (clib_time_now (&wrk->clib_time) < timeout);
Florin Corasdcf55ce2017-11-16 15:32:50 -08001229
Florin Coras05ecfcc2018-12-12 18:19:39 -08001230 VDBG (0, "timeout waiting for state 0x%x (%s)", state,
Florin Coras697faea2018-06-27 17:10:49 -07001231 vppcom_session_state_str (state));
1232 vcl_evt (VCL_EVT_SESSION_TIMEOUT, session, session_state);
Dave Wallace543852a2017-08-03 02:11:34 -04001233
Florin Coras697faea2018-06-27 17:10:49 -07001234 return VPPCOM_ETIMEDOUT;
Dave Wallace60caa062017-11-10 17:07:13 -05001235}
1236
Florin Coras30e79c22019-01-02 19:31:22 -08001237static void
1238vcl_handle_pending_wrk_updates (vcl_worker_t * wrk)
1239{
Florin Coras288eaab2019-02-03 15:26:14 -08001240 vcl_session_state_t state;
Florin Coras30e79c22019-01-02 19:31:22 -08001241 vcl_session_t *s;
1242 u32 *sip;
1243
1244 if (PREDICT_TRUE (vec_len (wrk->pending_session_wrk_updates) == 0))
1245 return;
1246
1247 vec_foreach (sip, wrk->pending_session_wrk_updates)
1248 {
1249 s = vcl_session_get (wrk, *sip);
1250 vcl_send_session_worker_update (wrk, s, wrk->wrk_index);
1251 state = s->session_state;
Florin Corasc127d5a2020-10-14 16:35:58 -07001252 vppcom_wait_for_session_state_change (s->session_index, VCL_STATE_UPDATED,
1253 5);
Florin Coras30e79c22019-01-02 19:31:22 -08001254 s->session_state = state;
1255 }
1256 vec_reset_length (wrk->pending_session_wrk_updates);
1257}
1258
Florin Corasf9240dc2019-01-15 08:03:17 -08001259void
Florin Coras5398dfb2021-01-25 20:31:27 -08001260vcl_worker_flush_mq_events (vcl_worker_t *wrk)
Florin Coras30e79c22019-01-02 19:31:22 -08001261{
Florin Coras30e79c22019-01-02 19:31:22 -08001262 svm_msg_q_msg_t *msg;
1263 session_event_t *e;
1264 svm_msg_q_t *mq;
1265 int i;
1266
1267 mq = wrk->app_event_queue;
Florin Corase003a1b2019-06-05 10:47:16 -07001268 vcl_mq_dequeue_batch (wrk, mq, ~0);
Florin Coras30e79c22019-01-02 19:31:22 -08001269
1270 for (i = 0; i < vec_len (wrk->mq_msg_vector); i++)
1271 {
1272 msg = vec_elt_at_index (wrk->mq_msg_vector, i);
1273 e = svm_msg_q_msg_data (mq, msg);
1274 vcl_handle_mq_event (wrk, e);
1275 svm_msg_q_free_msg (mq, msg);
1276 }
1277 vec_reset_length (wrk->mq_msg_vector);
1278 vcl_handle_pending_wrk_updates (wrk);
1279}
1280
Florin Coras5398dfb2021-01-25 20:31:27 -08001281void
1282vcl_flush_mq_events (void)
1283{
1284 vcl_worker_flush_mq_events (vcl_worker_get_current ());
1285}
1286
Florin Coras697faea2018-06-27 17:10:49 -07001287static int
Florin Corasab2f6db2018-08-31 14:31:41 -07001288vppcom_session_unbind (u32 session_handle)
Dave Wallace543852a2017-08-03 02:11:34 -04001289{
Florin Coras134a9962018-08-28 11:32:04 -07001290 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Corasaaff5ee2019-07-08 13:00:00 -07001291 session_accepted_msg_t *accepted_msg;
Florin Coras7e12d942018-06-27 14:32:43 -07001292 vcl_session_t *session = 0;
Florin Corasaaff5ee2019-07-08 13:00:00 -07001293 vcl_session_msg_t *evt;
Dave Wallace543852a2017-08-03 02:11:34 -04001294
Florin Corasab2f6db2018-08-31 14:31:41 -07001295 session = vcl_session_get_w_handle (wrk, session_handle);
Florin Coras070453d2018-08-24 17:04:27 -07001296 if (!session)
1297 return VPPCOM_EBADFD;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001298
Florin Corasaaff5ee2019-07-08 13:00:00 -07001299 /* Flush pending accept events, if any */
1300 while (clib_fifo_elts (session->accept_evts_fifo))
1301 {
1302 clib_fifo_sub2 (session->accept_evts_fifo, evt);
1303 accepted_msg = &evt->accepted_msg;
1304 vcl_session_table_del_vpp_handle (wrk, accepted_msg->handle);
1305 vcl_send_session_accepted_reply (session->vpp_evt_q,
1306 accepted_msg->context,
wanghanlin785b6ea2020-12-10 19:12:22 +08001307 accepted_msg->handle, -1);
Florin Corasaaff5ee2019-07-08 13:00:00 -07001308 }
1309 clib_fifo_free (session->accept_evts_fifo);
1310
Florin Coras458089b2019-08-21 16:20:44 -07001311 vcl_send_session_unlisten (wrk, session);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001312
Florin Coras5e062572019-03-14 19:07:51 -07001313 VDBG (1, "session %u [0x%llx]: sending unbind!", session->session_index,
Florin Coras458089b2019-08-21 16:20:44 -07001314 session->vpp_handle);
Florin Coras0d427d82018-06-27 03:24:07 -07001315 vcl_evt (VCL_EVT_UNBIND, session);
Florin Coras458089b2019-08-21 16:20:44 -07001316
1317 session->vpp_handle = ~0;
Florin Corasc127d5a2020-10-14 16:35:58 -07001318 session->session_state = VCL_STATE_DISCONNECT;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001319
Florin Coras070453d2018-08-24 17:04:27 -07001320 return VPPCOM_OK;
Dave Wallace543852a2017-08-03 02:11:34 -04001321}
1322
Florin Coras940f78f2018-11-30 12:11:20 -08001323/**
1324 * Handle app exit
1325 *
1326 * Notify vpp of the disconnect and mark the worker as free. If we're the
1327 * last worker, do a full cleanup otherwise, since we're probably a forked
1328 * child, avoid syscalls as much as possible. We might've lost privileges.
1329 */
1330void
1331vppcom_app_exit (void)
1332{
1333 if (!pool_elts (vcm->workers))
1334 return;
Florin Coras01f3f892018-12-02 12:45:53 -08001335 vcl_worker_cleanup (vcl_worker_get_current (), 1 /* notify vpp */ );
1336 vcl_set_worker_index (~0);
Florin Coras940f78f2018-11-30 12:11:20 -08001337 vcl_elog_stop (vcm);
Florin Coras940f78f2018-11-30 12:11:20 -08001338}
1339
Florin Coras935ce752020-09-08 22:43:47 -07001340static int
1341vcl_api_attach (void)
1342{
1343 if (vcm->cfg.vpp_app_socket_api)
1344 return vcl_sapi_attach ();
1345
1346 return vcl_bapi_attach ();
1347}
1348
1349static void
1350vcl_api_detach (vcl_worker_t * wrk)
1351{
1352 vcl_send_app_detach (wrk);
1353
1354 if (vcm->cfg.vpp_app_socket_api)
1355 return vcl_sapi_detach (wrk);
1356
1357 return vcl_bapi_disconnect_from_vpp ();
1358}
1359
Dave Wallace543852a2017-08-03 02:11:34 -04001360/*
1361 * VPPCOM Public API functions
1362 */
1363int
Florin Coras66ec4672020-06-15 07:59:40 -07001364vppcom_app_create (const char *app_name)
Dave Wallace543852a2017-08-03 02:11:34 -04001365{
Dave Wallace543852a2017-08-03 02:11:34 -04001366 vppcom_cfg_t *vcl_cfg = &vcm->cfg;
Dave Wallace543852a2017-08-03 02:11:34 -04001367 int rv;
1368
Florin Coras47c40e22018-11-26 17:01:36 -08001369 if (vcm->is_init)
Dave Wallace543852a2017-08-03 02:11:34 -04001370 {
Florin Coras955bfbb2018-12-04 13:43:45 -08001371 VDBG (1, "already initialized");
1372 return VPPCOM_EEXIST;
Dave Wallace543852a2017-08-03 02:11:34 -04001373 }
1374
Florin Coras47c40e22018-11-26 17:01:36 -08001375 vcm->is_init = 1;
1376 vppcom_cfg (&vcm->cfg);
1377 vcl_cfg = &vcm->cfg;
1378
1379 vcm->main_cpu = pthread_self ();
1380 vcm->main_pid = getpid ();
1381 vcm->app_name = format (0, "%s", app_name);
Florin Coras41bc8612021-10-01 14:57:03 -07001382 fifo_segment_main_init (&vcm->segment_main, (uword) ~0,
1383 20 /* timeout in secs */);
Florin Coras47c40e22018-11-26 17:01:36 -08001384 pool_alloc (vcm->workers, vcl_cfg->max_workers);
1385 clib_spinlock_init (&vcm->workers_lock);
Florin Corasd85de682018-11-29 17:02:29 -08001386 clib_rwlock_init (&vcm->segment_table_lock);
Florin Coras940f78f2018-11-30 12:11:20 -08001387 atexit (vppcom_app_exit);
Florin Corasb88de902020-09-08 16:47:57 -07001388 vcl_elog_init (vcm);
Florin Coras47c40e22018-11-26 17:01:36 -08001389
1390 /* Allocate default worker */
1391 vcl_worker_alloc_and_init ();
1392
Florin Coras935ce752020-09-08 22:43:47 -07001393 if ((rv = vcl_api_attach ()))
Florin Corasb88de902020-09-08 16:47:57 -07001394 return rv;
Florin Coras47c40e22018-11-26 17:01:36 -08001395
1396 VDBG (0, "app_name '%s', my_client_index %d (0x%x)", app_name,
Florin Corascc7c88e2020-09-15 15:56:51 -07001397 vcm->workers[0].api_client_handle, vcm->workers[0].api_client_handle);
Dave Wallace543852a2017-08-03 02:11:34 -04001398
1399 return VPPCOM_OK;
1400}
1401
1402void
1403vppcom_app_destroy (void)
1404{
Florin Corasdc0ded72020-04-30 02:59:55 +00001405 vcl_worker_t *wrk, *current_wrk;
Damjan Marion4537c302020-09-28 19:03:37 +02001406 void *heap;
Dave Wallace543852a2017-08-03 02:11:34 -04001407
Florin Coras940f78f2018-11-30 12:11:20 -08001408 if (!pool_elts (vcm->workers))
1409 return;
1410
Florin Coras0d427d82018-06-27 03:24:07 -07001411 vcl_evt (VCL_EVT_DETACH, vcm);
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -08001412
Florin Corasdc0ded72020-04-30 02:59:55 +00001413 current_wrk = vcl_worker_get_current ();
Keith Burns (alagalah)8aa9aaf2018-01-05 12:16:22 -08001414
Florin Corasce815de2020-04-16 18:47:27 +00001415 /* *INDENT-OFF* */
Damjan Marionb2c31b62020-12-13 21:47:40 +01001416 pool_foreach (wrk, vcm->workers) {
Florin Corasdc0ded72020-04-30 02:59:55 +00001417 if (current_wrk != wrk)
1418 vcl_worker_cleanup (wrk, 0 /* notify vpp */ );
Damjan Marionb2c31b62020-12-13 21:47:40 +01001419 }
Florin Corasce815de2020-04-16 18:47:27 +00001420 /* *INDENT-ON* */
1421
Florin Coras935ce752020-09-08 22:43:47 -07001422 vcl_api_detach (current_wrk);
Florin Corasdc0ded72020-04-30 02:59:55 +00001423 vcl_worker_cleanup (current_wrk, 0 /* notify vpp */ );
1424
Florin Coras0d427d82018-06-27 03:24:07 -07001425 vcl_elog_stop (vcm);
Florin Corasce815de2020-04-16 18:47:27 +00001426
1427 /*
1428 * Free the heap and fix vcm
1429 */
1430 heap = clib_mem_get_heap ();
Damjan Marion4537c302020-09-28 19:03:37 +02001431 munmap (clib_mem_get_heap_base (heap), clib_mem_get_heap_size (heap));
Florin Corasce815de2020-04-16 18:47:27 +00001432
1433 vcm = &_vppcom_main;
Florin Coras69d97252020-05-11 17:19:31 +00001434 vcm->is_init = 0;
Dave Wallace543852a2017-08-03 02:11:34 -04001435}
1436
1437int
Dave Wallacec04cbf12018-02-07 18:14:02 -05001438vppcom_session_create (u8 proto, u8 is_nonblocking)
Dave Wallace543852a2017-08-03 02:11:34 -04001439{
Florin Coras134a9962018-08-28 11:32:04 -07001440 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras7e12d942018-06-27 14:32:43 -07001441 vcl_session_t *session;
Dave Wallace543852a2017-08-03 02:11:34 -04001442
Florin Coras134a9962018-08-28 11:32:04 -07001443 session = vcl_session_alloc (wrk);
Dave Wallace543852a2017-08-03 02:11:34 -04001444
Florin Coras7e12d942018-06-27 14:32:43 -07001445 session->session_type = proto;
Florin Corasc127d5a2020-10-14 16:35:58 -07001446 session->session_state = VCL_STATE_CLOSED;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001447 session->vpp_handle = ~0;
Nathan Skrzypczak9fd99622019-05-16 14:38:44 +02001448 session->is_dgram = vcl_proto_is_dgram (proto);
Dave Wallace543852a2017-08-03 02:11:34 -04001449
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001450 if (is_nonblocking)
Florin Corasac422d62020-10-19 20:51:36 -07001451 vcl_session_set_attr (session, VCL_SESS_ATTR_NONBLOCK);
Dave Wallace543852a2017-08-03 02:11:34 -04001452
Florin Coras7e12d942018-06-27 14:32:43 -07001453 vcl_evt (VCL_EVT_CREATE, session, session_type, session->session_state,
1454 is_nonblocking, session_index);
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08001455
Florin Coras5e062572019-03-14 19:07:51 -07001456 VDBG (0, "created session %u", session->session_index);
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08001457
Florin Coras134a9962018-08-28 11:32:04 -07001458 return vcl_session_handle (session);
Dave Wallace543852a2017-08-03 02:11:34 -04001459}
1460
Florin Corasfe286f72021-06-04 10:07:55 -07001461static void
Florin Corasfa3884f2021-06-22 20:04:46 -07001462vcl_epoll_lt_add (vcl_worker_t *wrk, vcl_session_t *s)
Florin Corasfe286f72021-06-04 10:07:55 -07001463{
Florin Corasfa3884f2021-06-22 20:04:46 -07001464 vcl_session_t *cur, *prev;
Florin Corasfe286f72021-06-04 10:07:55 -07001465
Florin Corasfa3884f2021-06-22 20:04:46 -07001466 if (wrk->ep_lt_current == VCL_INVALID_SESSION_INDEX)
Florin Corasfe286f72021-06-04 10:07:55 -07001467 {
Florin Corasfa3884f2021-06-22 20:04:46 -07001468 wrk->ep_lt_current = s->session_index;
1469 s->vep.lt_next = s->session_index;
1470 s->vep.lt_prev = s->session_index;
1471 return;
Florin Corasfe286f72021-06-04 10:07:55 -07001472 }
Florin Corasfa3884f2021-06-22 20:04:46 -07001473
1474 cur = vcl_session_get (wrk, wrk->ep_lt_current);
1475 prev = vcl_session_get (wrk, cur->vep.lt_prev);
1476
1477 prev->vep.lt_next = s->session_index;
1478 s->vep.lt_prev = prev->session_index;
1479
1480 s->vep.lt_next = cur->session_index;
1481 cur->vep.lt_prev = s->session_index;
1482}
1483
1484static void
1485vcl_epoll_lt_del (vcl_worker_t *wrk, vcl_session_t *s)
1486{
1487 vcl_session_t *prev, *next;
1488
1489 if (s->vep.lt_next == s->session_index)
1490 {
1491 wrk->ep_lt_current = VCL_INVALID_SESSION_INDEX;
1492 s->vep.lt_next = VCL_INVALID_SESSION_INDEX;
1493 return;
1494 }
1495
1496 prev = vcl_session_get (wrk, s->vep.lt_prev);
1497 next = vcl_session_get (wrk, s->vep.lt_next);
1498
1499 prev->vep.lt_next = next->session_index;
1500 next->vep.lt_prev = prev->session_index;
1501
1502 if (s->session_index == wrk->ep_lt_current)
1503 wrk->ep_lt_current = s->vep.lt_next;
1504
1505 s->vep.lt_next = VCL_INVALID_SESSION_INDEX;
Florin Corasfe286f72021-06-04 10:07:55 -07001506}
1507
Dave Wallace543852a2017-08-03 02:11:34 -04001508int
Florin Corasc127d5a2020-10-14 16:35:58 -07001509vcl_session_cleanup (vcl_worker_t * wrk, vcl_session_t * s,
Florin Corasf9240dc2019-01-15 08:03:17 -08001510 vcl_session_handle_t sh, u8 do_disconnect)
Dave Wallace543852a2017-08-03 02:11:34 -04001511{
Florin Coras134a9962018-08-28 11:32:04 -07001512 int rv = VPPCOM_OK;
Florin Coras47c40e22018-11-26 17:01:36 -08001513
Florin Coras6c3b2182020-10-19 18:36:48 -07001514 VDBG (1, "session %u [0x%llx] closing", s->session_index, s->vpp_handle);
Dave Wallace543852a2017-08-03 02:11:34 -04001515
Florin Coras6c3b2182020-10-19 18:36:48 -07001516 if (s->flags & VCL_SESSION_F_IS_VEP)
Dave Wallace543852a2017-08-03 02:11:34 -04001517 {
Florin Coras6c3b2182020-10-19 18:36:48 -07001518 u32 next_sh = s->vep.next_sh;
Florin Coras134a9962018-08-28 11:32:04 -07001519 while (next_sh != ~0)
Dave Wallace19481612017-09-15 18:47:44 -04001520 {
Florin Corasf9240dc2019-01-15 08:03:17 -08001521 rv = vppcom_epoll_ctl (sh, EPOLL_CTL_DEL, next_sh, 0);
Florin Coras0d427d82018-06-27 03:24:07 -07001522 if (PREDICT_FALSE (rv < 0))
Florin Coras5e062572019-03-14 19:07:51 -07001523 VDBG (0, "vpp handle 0x%llx, sh %u: EPOLL_CTL_DEL vep_idx %u"
Florin Coras6c3b2182020-10-19 18:36:48 -07001524 " failed! rv %d (%s)", s->vpp_handle, next_sh,
1525 s->vep.vep_sh, rv, vppcom_retval_str (rv));
Florin Corasc127d5a2020-10-14 16:35:58 -07001526 next_sh = s->vep.next_sh;
Dave Wallacef7f809c2017-10-03 01:48:42 -04001527 }
Florin Corase4306b62020-10-28 12:51:10 -07001528 goto free_session;
Dave Wallacef7f809c2017-10-03 01:48:42 -04001529 }
Florin Coras9ace36d2019-10-28 13:14:17 -07001530
Florin Coras6c3b2182020-10-19 18:36:48 -07001531 if (s->flags & VCL_SESSION_F_IS_VEP_SESSION)
Dave Wallacef7f809c2017-10-03 01:48:42 -04001532 {
Florin Coras6c3b2182020-10-19 18:36:48 -07001533 rv = vppcom_epoll_ctl (s->vep.vep_sh, EPOLL_CTL_DEL, sh, 0);
Florin Coras9ace36d2019-10-28 13:14:17 -07001534 if (rv < 0)
1535 VDBG (0, "session %u [0x%llx]: EPOLL_CTL_DEL vep_idx %u "
Florin Coras6c3b2182020-10-19 18:36:48 -07001536 "failed! rv %d (%s)", s->session_index, s->vpp_handle,
1537 s->vep.vep_sh, rv, vppcom_retval_str (rv));
Dave Wallace19481612017-09-15 18:47:44 -04001538 }
Dave Wallace4878cbe2017-11-21 03:45:09 -05001539
Florin Coras9ace36d2019-10-28 13:14:17 -07001540 if (!do_disconnect)
1541 {
1542 VDBG (1, "session %u [0x%llx] disconnect skipped",
Florin Coras6c3b2182020-10-19 18:36:48 -07001543 s->session_index, s->vpp_handle);
Florin Coras9ace36d2019-10-28 13:14:17 -07001544 goto cleanup;
1545 }
1546
Florin Coras6c3b2182020-10-19 18:36:48 -07001547 if (s->session_state == VCL_STATE_LISTEN)
Florin Coras9ace36d2019-10-28 13:14:17 -07001548 {
1549 rv = vppcom_session_unbind (sh);
1550 if (PREDICT_FALSE (rv < 0))
1551 VDBG (0, "session %u [0x%llx]: listener unbind failed! "
Florin Coras6c3b2182020-10-19 18:36:48 -07001552 "rv %d (%s)", s->session_index, s->vpp_handle, rv,
Florin Coras9ace36d2019-10-28 13:14:17 -07001553 vppcom_retval_str (rv));
1554 return rv;
1555 }
Florin Coras1bc919e2020-10-18 20:17:49 -07001556 else if (vcl_session_is_ready (s)
Florin Corasc127d5a2020-10-14 16:35:58 -07001557 || (vcl_session_is_connectable_listener (wrk, s)))
Florin Coras9ace36d2019-10-28 13:14:17 -07001558 {
1559 rv = vppcom_session_disconnect (sh);
1560 if (PREDICT_FALSE (rv < 0))
1561 VDBG (0, "ERROR: session %u [0x%llx]: disconnect failed!"
Florin Coras6c3b2182020-10-19 18:36:48 -07001562 " rv %d (%s)", s->session_index, s->vpp_handle,
Florin Coras9ace36d2019-10-28 13:14:17 -07001563 rv, vppcom_retval_str (rv));
1564 }
Florin Coras6c3b2182020-10-19 18:36:48 -07001565 else if (s->session_state == VCL_STATE_DISCONNECT)
Florin Coras9ace36d2019-10-28 13:14:17 -07001566 {
Florin Coras52dd29f2020-11-18 19:02:17 -08001567 vcl_send_session_reset_reply (wrk, s, 0);
Florin Coras9ace36d2019-10-28 13:14:17 -07001568 }
Florin Coras6c3b2182020-10-19 18:36:48 -07001569 else if (s->session_state == VCL_STATE_DETACHED)
Florin Corasadcfb152020-02-12 08:50:29 +00001570 {
1571 /* Should not happen. VPP cleaned up before app confirmed close */
Florin Corasc127d5a2020-10-14 16:35:58 -07001572 VDBG (0, "vpp freed session %d before close", s->session_index);
Florin Corasadcfb152020-02-12 08:50:29 +00001573 goto free_session;
1574 }
Florin Coras9ace36d2019-10-28 13:14:17 -07001575
Florin Corasc127d5a2020-10-14 16:35:58 -07001576 s->session_state = VCL_STATE_CLOSED;
Florin Coras54140622020-02-04 19:04:34 +00001577
Florin Coras9ace36d2019-10-28 13:14:17 -07001578 /* Session is removed only after vpp confirms the disconnect */
1579 return rv;
Florin Coras0ef8ef22019-01-18 08:37:13 -08001580
Florin Corasf9240dc2019-01-15 08:03:17 -08001581cleanup:
Florin Coras6c3b2182020-10-19 18:36:48 -07001582 vcl_session_table_del_vpp_handle (wrk, s->vpp_handle);
Florin Corasadcfb152020-02-12 08:50:29 +00001583free_session:
Florin Corasc127d5a2020-10-14 16:35:58 -07001584 vcl_session_free (wrk, s);
1585 vcl_evt (VCL_EVT_CLOSE, s, rv);
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08001586
Dave Wallace543852a2017-08-03 02:11:34 -04001587 return rv;
1588}
1589
1590int
Florin Corasf9240dc2019-01-15 08:03:17 -08001591vppcom_session_close (uint32_t session_handle)
1592{
1593 vcl_worker_t *wrk = vcl_worker_get_current ();
1594 vcl_session_t *session;
1595
1596 session = vcl_session_get_w_handle (wrk, session_handle);
1597 if (!session)
1598 return VPPCOM_EBADFD;
1599 return vcl_session_cleanup (wrk, session, session_handle,
1600 1 /* do_disconnect */ );
1601}
1602
1603int
Florin Coras134a9962018-08-28 11:32:04 -07001604vppcom_session_bind (uint32_t session_handle, vppcom_endpt_t * ep)
Dave Wallace543852a2017-08-03 02:11:34 -04001605{
Florin Coras134a9962018-08-28 11:32:04 -07001606 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras7e12d942018-06-27 14:32:43 -07001607 vcl_session_t *session = 0;
Dave Wallace543852a2017-08-03 02:11:34 -04001608
1609 if (!ep || !ep->ip)
1610 return VPPCOM_EINVAL;
1611
Florin Coras134a9962018-08-28 11:32:04 -07001612 session = vcl_session_get_w_handle (wrk, session_handle);
Florin Coras070453d2018-08-24 17:04:27 -07001613 if (!session)
1614 return VPPCOM_EBADFD;
Dave Wallace543852a2017-08-03 02:11:34 -04001615
Florin Coras6c3b2182020-10-19 18:36:48 -07001616 if (session->flags & VCL_SESSION_F_IS_VEP)
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001617 {
Florin Coras5e062572019-03-14 19:07:51 -07001618 VDBG (0, "ERROR: cannot bind to epoll session %u!",
1619 session->session_index);
Florin Coras070453d2018-08-24 17:04:27 -07001620 return VPPCOM_EBADFD;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04001621 }
1622
Florin Coras7e12d942018-06-27 14:32:43 -07001623 session->transport.is_ip4 = ep->is_ip4;
Florin Coras54693d22018-07-17 10:46:29 -07001624 if (ep->is_ip4)
Dave Barach178cf492018-11-13 16:34:13 -05001625 clib_memcpy_fast (&session->transport.lcl_ip.ip4, ep->ip,
1626 sizeof (ip4_address_t));
Florin Coras54693d22018-07-17 10:46:29 -07001627 else
Dave Barach178cf492018-11-13 16:34:13 -05001628 clib_memcpy_fast (&session->transport.lcl_ip.ip6, ep->ip,
1629 sizeof (ip6_address_t));
Florin Coras7e12d942018-06-27 14:32:43 -07001630 session->transport.lcl_port = ep->port;
Stevenac1f96d2017-10-24 16:03:58 -07001631
Florin Coras5e062572019-03-14 19:07:51 -07001632 VDBG (0, "session %u handle %u: binding to local %s address %U port %u, "
1633 "proto %s", session->session_index, session_handle,
Florin Coras7e12d942018-06-27 14:32:43 -07001634 session->transport.is_ip4 ? "IPv4" : "IPv6",
1635 format_ip46_address, &session->transport.lcl_ip,
1636 session->transport.is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6,
1637 clib_net_to_host_u16 (session->transport.lcl_port),
Ping Yu34a3a082018-11-30 19:16:17 -05001638 vppcom_proto_str (session->session_type));
Florin Coras0d427d82018-06-27 03:24:07 -07001639 vcl_evt (VCL_EVT_BIND, session);
Florin Coras460dce62018-07-27 05:45:06 -07001640
1641 if (session->session_type == VPPCOM_PROTO_UDP)
Florin Coras134a9962018-08-28 11:32:04 -07001642 vppcom_session_listen (session_handle, 10);
Florin Coras460dce62018-07-27 05:45:06 -07001643
Florin Coras070453d2018-08-24 17:04:27 -07001644 return VPPCOM_OK;
Dave Wallace543852a2017-08-03 02:11:34 -04001645}
1646
1647int
Florin Coras134a9962018-08-28 11:32:04 -07001648vppcom_session_listen (uint32_t listen_sh, uint32_t q_len)
Dave Wallace543852a2017-08-03 02:11:34 -04001649{
Florin Coras134a9962018-08-28 11:32:04 -07001650 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras7e12d942018-06-27 14:32:43 -07001651 vcl_session_t *listen_session = 0;
Dave Wallaceee45d412017-11-24 21:44:06 -05001652 u64 listen_vpp_handle;
Florin Coras070453d2018-08-24 17:04:27 -07001653 int rv;
1654
Florin Coras134a9962018-08-28 11:32:04 -07001655 listen_session = vcl_session_get_w_handle (wrk, listen_sh);
Florin Coras6c3b2182020-10-19 18:36:48 -07001656 if (!listen_session || (listen_session->flags & VCL_SESSION_F_IS_VEP))
Florin Coras070453d2018-08-24 17:04:27 -07001657 return VPPCOM_EBADFD;
Dave Wallace543852a2017-08-03 02:11:34 -04001658
Dave Wallaceee45d412017-11-24 21:44:06 -05001659 listen_vpp_handle = listen_session->vpp_handle;
Florin Corasc127d5a2020-10-14 16:35:58 -07001660 if (listen_session->session_state == VCL_STATE_LISTEN)
Dave Wallacee695cb42017-11-02 22:04:42 -04001661 {
Florin Coras05ecfcc2018-12-12 18:19:39 -08001662 VDBG (0, "session %u [0x%llx]: already in listen state!",
1663 listen_sh, listen_vpp_handle);
Florin Coras070453d2018-08-24 17:04:27 -07001664 return VPPCOM_OK;
Dave Wallacee695cb42017-11-02 22:04:42 -04001665 }
1666
Nathan Skrzypczak9fd99622019-05-16 14:38:44 +02001667 VDBG (0, "session %u: sending vpp listen request...", listen_sh);
Dave Wallace543852a2017-08-03 02:11:34 -04001668
Florin Coras070453d2018-08-24 17:04:27 -07001669 /*
1670 * Send listen request to vpp and wait for reply
1671 */
Florin Coras458089b2019-08-21 16:20:44 -07001672 vcl_send_session_listen (wrk, listen_session);
Florin Coras134a9962018-08-28 11:32:04 -07001673 rv = vppcom_wait_for_session_state_change (listen_session->session_index,
Florin Corasc127d5a2020-10-14 16:35:58 -07001674 VCL_STATE_LISTEN,
Florin Coras134a9962018-08-28 11:32:04 -07001675 vcm->cfg.session_timeout);
Dave Wallace543852a2017-08-03 02:11:34 -04001676
Florin Coras070453d2018-08-24 17:04:27 -07001677 if (PREDICT_FALSE (rv))
Dave Wallaceee45d412017-11-24 21:44:06 -05001678 {
Florin Coras134a9962018-08-28 11:32:04 -07001679 listen_session = vcl_session_get_w_handle (wrk, listen_sh);
Florin Coras05ecfcc2018-12-12 18:19:39 -08001680 VDBG (0, "session %u [0x%llx]: listen failed! returning %d (%s)",
1681 listen_sh, listen_session->vpp_handle, rv,
1682 vppcom_retval_str (rv));
Florin Coras070453d2018-08-24 17:04:27 -07001683 return rv;
Dave Wallaceee45d412017-11-24 21:44:06 -05001684 }
1685
Florin Coras070453d2018-08-24 17:04:27 -07001686 return VPPCOM_OK;
Keith Burns (alagalah)0d2b0d52018-03-06 15:55:22 -08001687}
1688
Florin Coras134a9962018-08-28 11:32:04 -07001689static int
Florin Coras5e062572019-03-14 19:07:51 -07001690validate_args_session_accept_ (vcl_worker_t * wrk, vcl_session_t * ls)
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001691{
Florin Coras6c3b2182020-10-19 18:36:48 -07001692 if (ls->flags & VCL_SESSION_F_IS_VEP)
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001693 {
Florin Coras5e062572019-03-14 19:07:51 -07001694 VDBG (0, "ERROR: cannot accept on epoll session %u!",
1695 ls->session_index);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001696 return VPPCOM_EBADFD;
1697 }
1698
Florin Corasc127d5a2020-10-14 16:35:58 -07001699 if ((ls->session_state != VCL_STATE_LISTEN)
Nathan Skrzypczak9fd99622019-05-16 14:38:44 +02001700 && (!vcl_session_is_connectable_listener (wrk, ls)))
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001701 {
Florin Coras6c3b2182020-10-19 18:36:48 -07001702 VDBG (0, "ERROR: session [0x%llx]: not in listen state! state 0x%x"
Nathan Skrzypczak9fd99622019-05-16 14:38:44 +02001703 " (%s)", ls->vpp_handle, ls->session_state,
Florin Coras5e062572019-03-14 19:07:51 -07001704 vppcom_session_state_str (ls->session_state));
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001705 return VPPCOM_EBADFD;
1706 }
1707 return VPPCOM_OK;
1708}
1709
1710int
Nathan Skrzypczak9fd99622019-05-16 14:38:44 +02001711vppcom_unformat_proto (uint8_t * proto, char *proto_str)
1712{
1713 if (!strcmp (proto_str, "TCP"))
1714 *proto = VPPCOM_PROTO_TCP;
1715 else if (!strcmp (proto_str, "tcp"))
1716 *proto = VPPCOM_PROTO_TCP;
1717 else if (!strcmp (proto_str, "UDP"))
1718 *proto = VPPCOM_PROTO_UDP;
1719 else if (!strcmp (proto_str, "udp"))
1720 *proto = VPPCOM_PROTO_UDP;
Nathan Skrzypczak9fd99622019-05-16 14:38:44 +02001721 else if (!strcmp (proto_str, "TLS"))
1722 *proto = VPPCOM_PROTO_TLS;
1723 else if (!strcmp (proto_str, "tls"))
1724 *proto = VPPCOM_PROTO_TLS;
1725 else if (!strcmp (proto_str, "QUIC"))
1726 *proto = VPPCOM_PROTO_QUIC;
1727 else if (!strcmp (proto_str, "quic"))
1728 *proto = VPPCOM_PROTO_QUIC;
Florin Coras4b47ee22020-11-19 13:38:26 -08001729 else if (!strcmp (proto_str, "DTLS"))
1730 *proto = VPPCOM_PROTO_DTLS;
1731 else if (!strcmp (proto_str, "dtls"))
1732 *proto = VPPCOM_PROTO_DTLS;
Florin Coras6621abf2021-01-06 17:35:17 -08001733 else if (!strcmp (proto_str, "SRTP"))
1734 *proto = VPPCOM_PROTO_SRTP;
1735 else if (!strcmp (proto_str, "srtp"))
1736 *proto = VPPCOM_PROTO_SRTP;
Nathan Skrzypczak9fd99622019-05-16 14:38:44 +02001737 else
1738 return 1;
1739 return 0;
1740}
1741
1742int
Florin Coras134a9962018-08-28 11:32:04 -07001743vppcom_session_accept (uint32_t listen_session_handle, vppcom_endpt_t * ep,
Dave Wallace048b1d62018-01-03 22:24:41 -05001744 uint32_t flags)
Dave Wallace543852a2017-08-03 02:11:34 -04001745{
Florin Coras3c7d4f92018-12-14 11:28:43 -08001746 u32 client_session_index = ~0, listen_session_index, accept_flags = 0;
Florin Coras134a9962018-08-28 11:32:04 -07001747 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras54693d22018-07-17 10:46:29 -07001748 session_accepted_msg_t accepted_msg;
Florin Coras7e12d942018-06-27 14:32:43 -07001749 vcl_session_t *listen_session = 0;
1750 vcl_session_t *client_session = 0;
Florin Coras54693d22018-07-17 10:46:29 -07001751 vcl_session_msg_t *evt;
Florin Coras54693d22018-07-17 10:46:29 -07001752 u8 is_nonblocking;
1753 int rv;
Dave Wallace543852a2017-08-03 02:11:34 -04001754
Florin Coras5398dfb2021-01-25 20:31:27 -08001755again:
1756
Florin Coras134a9962018-08-28 11:32:04 -07001757 listen_session = vcl_session_get_w_handle (wrk, listen_session_handle);
Florin Coras070453d2018-08-24 17:04:27 -07001758 if (!listen_session)
1759 return VPPCOM_EBADFD;
Dave Wallace543852a2017-08-03 02:11:34 -04001760
Florin Coras134a9962018-08-28 11:32:04 -07001761 listen_session_index = listen_session->session_index;
1762 if ((rv = validate_args_session_accept_ (wrk, listen_session)))
Florin Coras070453d2018-08-24 17:04:27 -07001763 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04001764
Florin Coras54693d22018-07-17 10:46:29 -07001765 if (clib_fifo_elts (listen_session->accept_evts_fifo))
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001766 {
Florin Coras54693d22018-07-17 10:46:29 -07001767 clib_fifo_sub2 (listen_session->accept_evts_fifo, evt);
Florin Coras3c7d4f92018-12-14 11:28:43 -08001768 accept_flags = evt->flags;
Florin Coras54693d22018-07-17 10:46:29 -07001769 accepted_msg = evt->accepted_msg;
1770 goto handle;
1771 }
1772
Florin Corasac422d62020-10-19 20:51:36 -07001773 is_nonblocking = vcl_session_has_attr (listen_session,
1774 VCL_SESS_ATTR_NONBLOCK);
Florin Coras54693d22018-07-17 10:46:29 -07001775 while (1)
1776 {
Carl Smith592a9092019-11-12 14:57:37 +13001777 if (svm_msg_q_is_empty (wrk->app_event_queue) && is_nonblocking)
1778 return VPPCOM_EAGAIN;
1779
Florin Coras5398dfb2021-01-25 20:31:27 -08001780 svm_msg_q_wait (wrk->app_event_queue, SVM_MQ_WAIT_EMPTY);
1781 vcl_worker_flush_mq_events (wrk);
1782 goto again;
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001783 }
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001784
Florin Coras54693d22018-07-17 10:46:29 -07001785handle:
Keith Burns (alagalah)00f44cc2018-03-07 09:26:38 -08001786
Florin Coras00cca802019-06-06 09:38:44 -07001787 client_session_index = vcl_session_accepted_handler (wrk, &accepted_msg,
1788 listen_session_index);
1789 if (client_session_index == VCL_INVALID_SESSION_INDEX)
1790 return VPPCOM_ECONNABORTED;
1791
Florin Coras134a9962018-08-28 11:32:04 -07001792 listen_session = vcl_session_get (wrk, listen_session_index);
1793 client_session = vcl_session_get (wrk, client_session_index);
Dave Wallace543852a2017-08-03 02:11:34 -04001794
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001795 if (flags & O_NONBLOCK)
Florin Corasac422d62020-10-19 20:51:36 -07001796 vcl_session_set_attr (client_session, VCL_SESS_ATTR_NONBLOCK);
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08001797
Florin Coras5e062572019-03-14 19:07:51 -07001798 VDBG (1, "listener %u [0x%llx]: Got a connect request! session %u [0x%llx],"
1799 " flags %d, is_nonblocking %u", listen_session->session_index,
1800 listen_session->vpp_handle, client_session_index,
1801 client_session->vpp_handle, flags,
Florin Corasac422d62020-10-19 20:51:36 -07001802 vcl_session_has_attr (client_session, VCL_SESS_ATTR_NONBLOCK));
Dave Wallace543852a2017-08-03 02:11:34 -04001803
Dave Wallace048b1d62018-01-03 22:24:41 -05001804 if (ep)
1805 {
Florin Coras7e12d942018-06-27 14:32:43 -07001806 ep->is_ip4 = client_session->transport.is_ip4;
1807 ep->port = client_session->transport.rmt_port;
1808 if (client_session->transport.is_ip4)
Dave Barach178cf492018-11-13 16:34:13 -05001809 clib_memcpy_fast (ep->ip, &client_session->transport.rmt_ip.ip4,
1810 sizeof (ip4_address_t));
Dave Wallace048b1d62018-01-03 22:24:41 -05001811 else
Dave Barach178cf492018-11-13 16:34:13 -05001812 clib_memcpy_fast (ep->ip, &client_session->transport.rmt_ip.ip6,
1813 sizeof (ip6_address_t));
Dave Wallace048b1d62018-01-03 22:24:41 -05001814 }
Dave Wallace60caa062017-11-10 17:07:13 -05001815
Florin Coras05ecfcc2018-12-12 18:19:39 -08001816 VDBG (0, "listener %u [0x%llx] accepted %u [0x%llx] peer: %U:%u "
Florin Coras5e062572019-03-14 19:07:51 -07001817 "local: %U:%u", listen_session_handle, listen_session->vpp_handle,
Florin Coras05ecfcc2018-12-12 18:19:39 -08001818 client_session_index, client_session->vpp_handle,
Florin Coras7e12d942018-06-27 14:32:43 -07001819 format_ip46_address, &client_session->transport.rmt_ip,
Florin Coras54693d22018-07-17 10:46:29 -07001820 client_session->transport.is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6,
Florin Coras7e12d942018-06-27 14:32:43 -07001821 clib_net_to_host_u16 (client_session->transport.rmt_port),
Florin Coras7e12d942018-06-27 14:32:43 -07001822 format_ip46_address, &client_session->transport.lcl_ip,
Florin Coras54693d22018-07-17 10:46:29 -07001823 client_session->transport.is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6,
Florin Coras7e12d942018-06-27 14:32:43 -07001824 clib_net_to_host_u16 (client_session->transport.lcl_port));
Florin Coras0d427d82018-06-27 03:24:07 -07001825 vcl_evt (VCL_EVT_ACCEPT, client_session, listen_session,
1826 client_session_index);
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08001827
Florin Coras3c7d4f92018-12-14 11:28:43 -08001828 /*
1829 * Session might have been closed already
1830 */
1831 if (accept_flags)
1832 {
Florin Coras3c7d4f92018-12-14 11:28:43 -08001833 if (accept_flags & VCL_ACCEPTED_F_CLOSED)
Florin Corasc127d5a2020-10-14 16:35:58 -07001834 client_session->session_state = VCL_STATE_VPP_CLOSING;
Florin Coras3c7d4f92018-12-14 11:28:43 -08001835 else if (accept_flags & VCL_ACCEPTED_F_RESET)
Florin Corasc127d5a2020-10-14 16:35:58 -07001836 client_session->session_state = VCL_STATE_DISCONNECT;
Florin Coras3c7d4f92018-12-14 11:28:43 -08001837 }
Florin Corasab2f6db2018-08-31 14:31:41 -07001838 return vcl_session_handle (client_session);
Dave Wallace543852a2017-08-03 02:11:34 -04001839}
1840
1841int
Florin Coras134a9962018-08-28 11:32:04 -07001842vppcom_session_connect (uint32_t session_handle, vppcom_endpt_t * server_ep)
Dave Wallace543852a2017-08-03 02:11:34 -04001843{
Florin Coras134a9962018-08-28 11:32:04 -07001844 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras7e12d942018-06-27 14:32:43 -07001845 vcl_session_t *session = 0;
Florin Coras134a9962018-08-28 11:32:04 -07001846 u32 session_index;
Florin Coras070453d2018-08-24 17:04:27 -07001847 int rv;
Dave Wallace543852a2017-08-03 02:11:34 -04001848
Florin Coras134a9962018-08-28 11:32:04 -07001849 session = vcl_session_get_w_handle (wrk, session_handle);
Florin Coras070453d2018-08-24 17:04:27 -07001850 if (!session)
1851 return VPPCOM_EBADFD;
Florin Coras134a9962018-08-28 11:32:04 -07001852 session_index = session->session_index;
Dave Wallace4878cbe2017-11-21 03:45:09 -05001853
Florin Coras6c3b2182020-10-19 18:36:48 -07001854 if (PREDICT_FALSE (session->flags & VCL_SESSION_F_IS_VEP))
Dave Wallace543852a2017-08-03 02:11:34 -04001855 {
Florin Coras5e062572019-03-14 19:07:51 -07001856 VDBG (0, "ERROR: cannot connect epoll session %u!",
1857 session->session_index);
Florin Coras070453d2018-08-24 17:04:27 -07001858 return VPPCOM_EBADFD;
Dave Wallace543852a2017-08-03 02:11:34 -04001859 }
1860
Florin Corasc127d5a2020-10-14 16:35:58 -07001861 if (PREDICT_FALSE (vcl_session_is_ready (session)))
Dave Wallace543852a2017-08-03 02:11:34 -04001862 {
Florin Coras7baeb712019-01-04 17:05:43 -08001863 VDBG (0, "session handle %u [0x%llx]: session already "
Florin Coras0d427d82018-06-27 03:24:07 -07001864 "connected to %s %U port %d proto %s, state 0x%x (%s)",
Florin Coras7baeb712019-01-04 17:05:43 -08001865 session_handle, session->vpp_handle,
Nathan Skrzypczak9fd99622019-05-16 14:38:44 +02001866 session->transport.is_ip4 ? "IPv4" : "IPv6", format_ip46_address,
Florin Coras7e12d942018-06-27 14:32:43 -07001867 &session->transport.rmt_ip, session->transport.is_ip4 ?
Florin Coras0d427d82018-06-27 03:24:07 -07001868 IP46_TYPE_IP4 : IP46_TYPE_IP6,
Florin Coras7e12d942018-06-27 14:32:43 -07001869 clib_net_to_host_u16 (session->transport.rmt_port),
Ping Yu34a3a082018-11-30 19:16:17 -05001870 vppcom_proto_str (session->session_type), session->session_state,
Florin Coras7e12d942018-06-27 14:32:43 -07001871 vppcom_session_state_str (session->session_state));
Florin Coras070453d2018-08-24 17:04:27 -07001872 return VPPCOM_OK;
Dave Wallace543852a2017-08-03 02:11:34 -04001873 }
1874
Florin Coras0a1e1832020-03-29 18:54:04 +00001875 /* Attempt to connect a connectionless listener */
Florin Corasc127d5a2020-10-14 16:35:58 -07001876 if (PREDICT_FALSE (session->session_state == VCL_STATE_LISTEN))
Florin Coras0a1e1832020-03-29 18:54:04 +00001877 {
1878 if (session->session_type != VPPCOM_PROTO_UDP)
1879 return VPPCOM_EINVAL;
1880 vcl_send_session_unlisten (wrk, session);
Florin Corasc127d5a2020-10-14 16:35:58 -07001881 session->session_state = VCL_STATE_CLOSED;
Florin Coras0a1e1832020-03-29 18:54:04 +00001882 }
1883
Florin Coras7e12d942018-06-27 14:32:43 -07001884 session->transport.is_ip4 = server_ep->is_ip4;
Florin Corasef7cbf62019-10-17 09:56:27 -07001885 vcl_ip_copy_from_ep (&session->transport.rmt_ip, server_ep);
Florin Coras7e12d942018-06-27 14:32:43 -07001886 session->transport.rmt_port = server_ep->port;
Nathan Skrzypczak8ac1d6d2019-07-17 11:02:20 +02001887 session->parent_handle = VCL_INVALID_SESSION_HANDLE;
Florin Coras0a1e1832020-03-29 18:54:04 +00001888 session->flags |= VCL_SESSION_F_CONNECTED;
Dave Wallace543852a2017-08-03 02:11:34 -04001889
Florin Coras0a1e1832020-03-29 18:54:04 +00001890 VDBG (0, "session handle %u (%s): connecting to peer %s %U "
Nathan Skrzypczak9fd99622019-05-16 14:38:44 +02001891 "port %d proto %s", session_handle,
Florin Coras0a1e1832020-03-29 18:54:04 +00001892 vppcom_session_state_str (session->session_state),
Florin Coras7e12d942018-06-27 14:32:43 -07001893 session->transport.is_ip4 ? "IPv4" : "IPv6",
Florin Coras0d427d82018-06-27 03:24:07 -07001894 format_ip46_address,
Florin Coras7e12d942018-06-27 14:32:43 -07001895 &session->transport.rmt_ip, session->transport.is_ip4 ?
Florin Coras0d427d82018-06-27 03:24:07 -07001896 IP46_TYPE_IP4 : IP46_TYPE_IP6,
Florin Coras7e12d942018-06-27 14:32:43 -07001897 clib_net_to_host_u16 (session->transport.rmt_port),
Ping Yu34a3a082018-11-30 19:16:17 -05001898 vppcom_proto_str (session->session_type));
Dave Wallace543852a2017-08-03 02:11:34 -04001899
Florin Coras458089b2019-08-21 16:20:44 -07001900 vcl_send_session_connect (wrk, session);
Florin Coras57c88932019-08-29 12:03:17 -07001901
Florin Corasac422d62020-10-19 20:51:36 -07001902 if (vcl_session_has_attr (session, VCL_SESS_ATTR_NONBLOCK))
Florin Corasa5ea8212020-08-24 21:23:51 -07001903 {
fanyfa49d59d2020-10-13 17:07:16 +08001904 /* State set to STATE_UPDATED to ensure the session is not assumed
Florin Corasdfffdd72020-10-15 10:54:47 -07001905 * to be ready and to also allow the app to close it prior to vpp's
fanyfa49d59d2020-10-13 17:07:16 +08001906 * connected reply. */
Florin Corasc127d5a2020-10-14 16:35:58 -07001907 session->session_state = VCL_STATE_UPDATED;
Florin Corasa5ea8212020-08-24 21:23:51 -07001908 return VPPCOM_EINPROGRESS;
1909 }
Florin Coras57c88932019-08-29 12:03:17 -07001910
1911 /*
1912 * Wait for reply from vpp if blocking
1913 */
Florin Corasdfffdd72020-10-15 10:54:47 -07001914 rv = vppcom_wait_for_session_state_change (session_index, VCL_STATE_READY,
Florin Coras070453d2018-08-24 17:04:27 -07001915 vcm->cfg.session_timeout);
Dave Wallace4878cbe2017-11-21 03:45:09 -05001916
Florin Coras134a9962018-08-28 11:32:04 -07001917 session = vcl_session_get (wrk, session_index);
Florin Coras5e062572019-03-14 19:07:51 -07001918 VDBG (0, "session %u [0x%llx]: connect %s!", session->session_index,
1919 session->vpp_handle, rv ? "failed" : "succeeded");
Dave Wallaceee45d412017-11-24 21:44:06 -05001920
Dave Wallace4878cbe2017-11-21 03:45:09 -05001921 return rv;
Dave Wallace543852a2017-08-03 02:11:34 -04001922}
1923
Nathan Skrzypczak9fd99622019-05-16 14:38:44 +02001924int
1925vppcom_session_stream_connect (uint32_t session_handle,
1926 uint32_t parent_session_handle)
1927{
1928 vcl_worker_t *wrk = vcl_worker_get_current ();
1929 vcl_session_t *session, *parent_session;
1930 u32 session_index, parent_session_index;
1931 int rv;
1932
1933 session = vcl_session_get_w_handle (wrk, session_handle);
1934 if (!session)
1935 return VPPCOM_EBADFD;
1936 parent_session = vcl_session_get_w_handle (wrk, parent_session_handle);
1937 if (!parent_session)
1938 return VPPCOM_EBADFD;
1939
1940 session_index = session->session_index;
1941 parent_session_index = parent_session->session_index;
Florin Coras6c3b2182020-10-19 18:36:48 -07001942 if (PREDICT_FALSE (session->flags & VCL_SESSION_F_IS_VEP))
Nathan Skrzypczak9fd99622019-05-16 14:38:44 +02001943 {
1944 VDBG (0, "ERROR: cannot connect epoll session %u!",
1945 session->session_index);
1946 return VPPCOM_EBADFD;
1947 }
1948
Florin Corasc127d5a2020-10-14 16:35:58 -07001949 if (PREDICT_FALSE (vcl_session_is_ready (session)))
Nathan Skrzypczak9fd99622019-05-16 14:38:44 +02001950 {
1951 VDBG (0, "session handle %u [0x%llx]: session already "
1952 "connected to session %u [0x%llx] proto %s, state 0x%x (%s)",
1953 session_handle, session->vpp_handle,
1954 parent_session_handle, parent_session->vpp_handle,
1955 vppcom_proto_str (session->session_type), session->session_state,
1956 vppcom_session_state_str (session->session_state));
1957 return VPPCOM_OK;
1958 }
1959
1960 /* Connect to quic session specifics */
1961 session->transport.is_ip4 = parent_session->transport.is_ip4;
1962 session->transport.rmt_ip.ip4.as_u32 = (uint32_t) 1;
1963 session->transport.rmt_port = 0;
Nathan Skrzypczak8ac1d6d2019-07-17 11:02:20 +02001964 session->parent_handle = parent_session->vpp_handle;
Nathan Skrzypczak9fd99622019-05-16 14:38:44 +02001965
1966 VDBG (0, "session handle %u: connecting to session %u [0x%llx]",
1967 session_handle, parent_session_handle, parent_session->vpp_handle);
1968
1969 /*
1970 * Send connect request and wait for reply from vpp
1971 */
Florin Coras458089b2019-08-21 16:20:44 -07001972 vcl_send_session_connect (wrk, session);
Florin Corasdfffdd72020-10-15 10:54:47 -07001973 rv = vppcom_wait_for_session_state_change (session_index, VCL_STATE_READY,
Nathan Skrzypczak9fd99622019-05-16 14:38:44 +02001974 vcm->cfg.session_timeout);
1975
1976 session->listener_index = parent_session_index;
1977 parent_session = vcl_session_get_w_handle (wrk, parent_session_handle);
Florin Coras028eaf02019-07-19 12:15:52 -07001978 if (parent_session)
1979 parent_session->n_accepted_sessions++;
Nathan Skrzypczak9fd99622019-05-16 14:38:44 +02001980
1981 session = vcl_session_get (wrk, session_index);
1982 VDBG (0, "session %u [0x%llx]: connect %s!", session->session_index,
1983 session->vpp_handle, rv ? "failed" : "succeeded");
1984
1985 return rv;
1986}
1987
Steven58f464e2017-10-25 12:33:12 -07001988static inline int
Florin Coras134a9962018-08-28 11:32:04 -07001989vppcom_session_read_internal (uint32_t session_handle, void *buf, int n,
Steven58f464e2017-10-25 12:33:12 -07001990 u8 peek)
Dave Wallace543852a2017-08-03 02:11:34 -04001991{
Florin Coras134a9962018-08-28 11:32:04 -07001992 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras4a2c7942020-09-10 12:27:14 -07001993 int rv, n_read = 0, is_nonblocking;
Florin Coras460dce62018-07-27 05:45:06 -07001994 vcl_session_t *s = 0;
Dave Wallace543852a2017-08-03 02:11:34 -04001995 svm_fifo_t *rx_fifo;
Florin Coras54693d22018-07-17 10:46:29 -07001996 session_event_t *e;
1997 svm_msg_q_t *mq;
Florin Coras41c9e042018-09-11 00:10:41 -07001998 u8 is_ct;
Dave Wallace543852a2017-08-03 02:11:34 -04001999
Florin Coras070453d2018-08-24 17:04:27 -07002000 if (PREDICT_FALSE (!buf))
wanghanlin72228a22021-07-06 17:18:29 +08002001 return VPPCOM_EFAULT;
Dave Wallace543852a2017-08-03 02:11:34 -04002002
Florin Coras134a9962018-08-28 11:32:04 -07002003 s = vcl_session_get_w_handle (wrk, session_handle);
Florin Coras6c3b2182020-10-19 18:36:48 -07002004 if (PREDICT_FALSE (!s || (s->flags & VCL_SESSION_F_IS_VEP)))
Florin Coras070453d2018-08-24 17:04:27 -07002005 return VPPCOM_EBADFD;
Dave Wallace4878cbe2017-11-21 03:45:09 -05002006
Florin Coras6d0106e2019-01-29 20:11:58 -08002007 if (PREDICT_FALSE (!vcl_session_is_open (s)))
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002008 {
Florin Coras5e062572019-03-14 19:07:51 -07002009 VDBG (0, "session %u[0x%llx] is not open! state 0x%x (%s)",
Florin Coras6d0106e2019-01-29 20:11:58 -08002010 s->session_index, s->vpp_handle, s->session_state,
2011 vppcom_session_state_str (s->session_state));
2012 return vcl_session_closed_error (s);
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002013 }
2014
liuyacan55c952e2021-06-13 14:54:55 +08002015 if (PREDICT_FALSE (s->flags & VCL_SESSION_F_RD_SHUTDOWN))
2016 {
2017 /* Vpp would ack the incoming data and enqueue it for reading.
2018 * So even if SHUT_RD is set, we can still read() the data if
2019 * the session is ready.
2020 */
2021 if (!vcl_session_read_ready (s))
2022 {
2023 return 0;
2024 }
2025 }
2026
Florin Corasac422d62020-10-19 20:51:36 -07002027 is_nonblocking = vcl_session_has_attr (s, VCL_SESS_ATTR_NONBLOCK);
Florin Coras41c9e042018-09-11 00:10:41 -07002028 is_ct = vcl_session_is_ct (s);
Florin Coras653e43f2019-03-04 10:56:23 -08002029 mq = wrk->app_event_queue;
2030 rx_fifo = is_ct ? s->ct_rx_fifo : s->rx_fifo;
Florin Corasac422d62020-10-19 20:51:36 -07002031 s->flags &= ~VCL_SESSION_F_HAS_RX_EVT;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002032
Sirshak Das28aa5392019-02-05 01:33:33 -06002033 if (svm_fifo_is_empty_cons (rx_fifo))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002034 {
Florin Coras54693d22018-07-17 10:46:29 -07002035 if (is_nonblocking)
Florin Corasc0737e92019-03-04 14:19:39 -08002036 {
Yu Pingb2955352019-12-04 06:49:04 +08002037 if (vcl_session_is_closing (s))
2038 return vcl_session_closing_error (s);
Florin Corasd6894562020-10-28 00:37:15 -07002039 if (is_ct)
2040 svm_fifo_unset_event (s->rx_fifo);
2041 svm_fifo_unset_event (rx_fifo);
Florin Corasc0737e92019-03-04 14:19:39 -08002042 return VPPCOM_EWOULDBLOCK;
2043 }
Sirshak Das28aa5392019-02-05 01:33:33 -06002044 while (svm_fifo_is_empty_cons (rx_fifo))
Florin Coras54693d22018-07-17 10:46:29 -07002045 {
Florin Coras6d0106e2019-01-29 20:11:58 -08002046 if (vcl_session_is_closing (s))
2047 return vcl_session_closing_error (s);
2048
Florin Corasd6894562020-10-28 00:37:15 -07002049 if (is_ct)
2050 svm_fifo_unset_event (s->rx_fifo);
2051 svm_fifo_unset_event (rx_fifo);
Florin Coras99368312018-08-02 10:45:44 -07002052
Florin Coras5398dfb2021-01-25 20:31:27 -08002053 svm_msg_q_wait (mq, SVM_MQ_WAIT_EMPTY);
2054 vcl_worker_flush_mq_events (wrk);
Florin Coras54693d22018-07-17 10:46:29 -07002055 }
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002056 }
Florin Coras54693d22018-07-17 10:46:29 -07002057
Florin Coras4a2c7942020-09-10 12:27:14 -07002058read_again:
2059
Florin Coras460dce62018-07-27 05:45:06 -07002060 if (s->is_dgram)
Florin Coras4a2c7942020-09-10 12:27:14 -07002061 rv = app_recv_dgram_raw (rx_fifo, buf, n, &s->transport, 0, peek);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002062 else
Florin Coras4a2c7942020-09-10 12:27:14 -07002063 rv = app_recv_stream_raw (rx_fifo, buf, n, 0, peek);
2064
2065 ASSERT (rv >= 0);
Florin Coras23368312021-06-04 16:28:18 -07002066
2067 if (peek)
2068 return rv;
2069
Florin Coras4a2c7942020-09-10 12:27:14 -07002070 n_read += rv;
Florin Coras54693d22018-07-17 10:46:29 -07002071
Sirshak Das28aa5392019-02-05 01:33:33 -06002072 if (svm_fifo_is_empty_cons (rx_fifo))
Florin Corasc34118b2020-08-12 18:58:25 -07002073 {
Florin Corasd6894562020-10-28 00:37:15 -07002074 if (is_ct)
2075 svm_fifo_unset_event (s->rx_fifo);
2076 svm_fifo_unset_event (rx_fifo);
Florin Corasc34118b2020-08-12 18:58:25 -07002077 if (!svm_fifo_is_empty_cons (rx_fifo)
Florin Corasd6894562020-10-28 00:37:15 -07002078 && svm_fifo_set_event (rx_fifo) && is_nonblocking)
Florin Corasc34118b2020-08-12 18:58:25 -07002079 {
Florin Corasc34118b2020-08-12 18:58:25 -07002080 vec_add2 (wrk->unhandled_evts_vector, e, 1);
2081 e->event_type = SESSION_IO_EVT_RX;
2082 e->session_index = s->session_index;
2083 }
2084 }
Florin Coras54fe32c2020-11-25 20:26:32 -08002085 else if (PREDICT_FALSE (rv < n && !s->is_dgram))
Florin Coras4a2c7942020-09-10 12:27:14 -07002086 {
2087 /* More data enqueued while reading. Try to drain it
Florin Coras54fe32c2020-11-25 20:26:32 -08002088 * or fill the buffer. Avoid doing that for dgrams */
Florin Coras4a2c7942020-09-10 12:27:14 -07002089 buf += rv;
2090 n -= rv;
2091 goto read_again;
2092 }
Florin Coras41c9e042018-09-11 00:10:41 -07002093
Florin Coras17ec5772020-08-12 20:46:29 -07002094 if (PREDICT_FALSE (svm_fifo_needs_deq_ntf (rx_fifo, n_read)))
Florin Coras317b8e02019-04-17 09:57:46 -07002095 {
Florin Coras17ec5772020-08-12 20:46:29 -07002096 svm_fifo_clear_deq_ntf (rx_fifo);
Florin Corasc547e912020-12-08 17:50:45 -08002097 app_send_io_evt_to_vpp (s->vpp_evt_q,
2098 s->rx_fifo->shr->master_session_index,
Florin Coras317b8e02019-04-17 09:57:46 -07002099 SESSION_IO_EVT_RX, SVM_Q_WAIT);
Florin Coras317b8e02019-04-17 09:57:46 -07002100 }
2101
Florin Coras5e062572019-03-14 19:07:51 -07002102 VDBG (2, "session %u[0x%llx]: read %d bytes from (%p)", s->session_index,
2103 s->vpp_handle, n_read, rx_fifo);
Florin Coras2cba8532018-09-11 16:33:36 -07002104
Florin Coras54693d22018-07-17 10:46:29 -07002105 return n_read;
Dave Wallace543852a2017-08-03 02:11:34 -04002106}
2107
Steven58f464e2017-10-25 12:33:12 -07002108int
Florin Coras134a9962018-08-28 11:32:04 -07002109vppcom_session_read (uint32_t session_handle, void *buf, size_t n)
Steven58f464e2017-10-25 12:33:12 -07002110{
Florin Coras134a9962018-08-28 11:32:04 -07002111 return (vppcom_session_read_internal (session_handle, buf, n, 0));
Steven58f464e2017-10-25 12:33:12 -07002112}
2113
2114static int
Florin Coras134a9962018-08-28 11:32:04 -07002115vppcom_session_peek (uint32_t session_handle, void *buf, int n)
Steven58f464e2017-10-25 12:33:12 -07002116{
Florin Coras134a9962018-08-28 11:32:04 -07002117 return (vppcom_session_read_internal (session_handle, buf, n, 1));
Steven58f464e2017-10-25 12:33:12 -07002118}
2119
Florin Coras2cba8532018-09-11 16:33:36 -07002120int
2121vppcom_session_read_segments (uint32_t session_handle,
Florin Corasd68faf82020-09-25 15:18:13 -07002122 vppcom_data_segment_t * ds, uint32_t n_segments,
2123 uint32_t max_bytes)
Florin Coras2cba8532018-09-11 16:33:36 -07002124{
2125 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras6d0106e2019-01-29 20:11:58 -08002126 int n_read = 0, is_nonblocking;
Florin Coras2cba8532018-09-11 16:33:36 -07002127 vcl_session_t *s = 0;
2128 svm_fifo_t *rx_fifo;
Florin Coras2cba8532018-09-11 16:33:36 -07002129 svm_msg_q_t *mq;
2130 u8 is_ct;
2131
2132 s = vcl_session_get_w_handle (wrk, session_handle);
Florin Coras6c3b2182020-10-19 18:36:48 -07002133 if (PREDICT_FALSE (!s || (s->flags & VCL_SESSION_F_IS_VEP)))
Florin Coras2cba8532018-09-11 16:33:36 -07002134 return VPPCOM_EBADFD;
2135
Florin Coras6d0106e2019-01-29 20:11:58 -08002136 if (PREDICT_FALSE (!vcl_session_is_open (s)))
2137 return vcl_session_closed_error (s);
Florin Coras2cba8532018-09-11 16:33:36 -07002138
Florin Corasac422d62020-10-19 20:51:36 -07002139 is_nonblocking = vcl_session_has_attr (s, VCL_SESS_ATTR_NONBLOCK);
Florin Coras2cba8532018-09-11 16:33:36 -07002140 is_ct = vcl_session_is_ct (s);
Florin Corasac422d62020-10-19 20:51:36 -07002141 mq = wrk->app_event_queue;
Florin Coras62877022020-10-28 21:22:04 -07002142 rx_fifo = is_ct ? s->ct_rx_fifo : s->rx_fifo;
Florin Corasac422d62020-10-19 20:51:36 -07002143 s->flags &= ~VCL_SESSION_F_HAS_RX_EVT;
Florin Coras2cba8532018-09-11 16:33:36 -07002144
Sirshak Das28aa5392019-02-05 01:33:33 -06002145 if (svm_fifo_is_empty_cons (rx_fifo))
Florin Coras2cba8532018-09-11 16:33:36 -07002146 {
2147 if (is_nonblocking)
2148 {
Florin Coras62877022020-10-28 21:22:04 -07002149 if (is_ct)
2150 svm_fifo_unset_event (s->rx_fifo);
Florin Coras2cba8532018-09-11 16:33:36 -07002151 svm_fifo_unset_event (rx_fifo);
Florin Corasaa27eb92018-10-13 12:20:01 -07002152 return VPPCOM_EWOULDBLOCK;
Florin Coras2cba8532018-09-11 16:33:36 -07002153 }
Sirshak Das28aa5392019-02-05 01:33:33 -06002154 while (svm_fifo_is_empty_cons (rx_fifo))
Florin Coras2cba8532018-09-11 16:33:36 -07002155 {
Florin Coras6d0106e2019-01-29 20:11:58 -08002156 if (vcl_session_is_closing (s))
2157 return vcl_session_closing_error (s);
2158
Florin Coras62877022020-10-28 21:22:04 -07002159 if (is_ct)
2160 svm_fifo_unset_event (s->rx_fifo);
Florin Coras2cba8532018-09-11 16:33:36 -07002161 svm_fifo_unset_event (rx_fifo);
Florin Coras2cba8532018-09-11 16:33:36 -07002162
Florin Coras5398dfb2021-01-25 20:31:27 -08002163 svm_msg_q_wait (mq, SVM_MQ_WAIT_EMPTY);
2164 vcl_worker_flush_mq_events (wrk);
Florin Coras2cba8532018-09-11 16:33:36 -07002165 }
2166 }
2167
Florin Corasd1cc38d2020-10-11 11:05:04 -07002168 n_read = svm_fifo_segments (rx_fifo, s->rx_bytes_pending,
2169 (svm_fifo_seg_t *) ds, n_segments, max_bytes);
2170 if (n_read < 0)
2171 return VPPCOM_EAGAIN;
2172
2173 if (svm_fifo_max_dequeue_cons (rx_fifo) == n_read)
2174 {
Florin Coras62877022020-10-28 21:22:04 -07002175 if (is_ct)
2176 svm_fifo_unset_event (s->rx_fifo);
2177 svm_fifo_unset_event (rx_fifo);
Florin Corasd1cc38d2020-10-11 11:05:04 -07002178 if (svm_fifo_max_dequeue_cons (rx_fifo) != n_read
Florin Coras62877022020-10-28 21:22:04 -07002179 && svm_fifo_set_event (rx_fifo)
Florin Corasac422d62020-10-19 20:51:36 -07002180 && vcl_session_has_attr (s, VCL_SESS_ATTR_NONBLOCK))
Florin Corasd1cc38d2020-10-11 11:05:04 -07002181 {
2182 session_event_t *e;
2183 vec_add2 (wrk->unhandled_evts_vector, e, 1);
2184 e->event_type = SESSION_IO_EVT_RX;
2185 e->session_index = s->session_index;
2186 }
2187 }
2188
2189 s->rx_bytes_pending += n_read;
Florin Coras2cba8532018-09-11 16:33:36 -07002190 return n_read;
2191}
2192
2193void
Florin Corasd68faf82020-09-25 15:18:13 -07002194vppcom_session_free_segments (uint32_t session_handle, uint32_t n_bytes)
Florin Coras2cba8532018-09-11 16:33:36 -07002195{
2196 vcl_worker_t *wrk = vcl_worker_get_current ();
2197 vcl_session_t *s;
Florin Coras62877022020-10-28 21:22:04 -07002198 u8 is_ct;
Florin Coras2cba8532018-09-11 16:33:36 -07002199
2200 s = vcl_session_get_w_handle (wrk, session_handle);
Florin Coras6c3b2182020-10-19 18:36:48 -07002201 if (PREDICT_FALSE (!s || (s->flags & VCL_SESSION_F_IS_VEP)))
Florin Coras2cba8532018-09-11 16:33:36 -07002202 return;
2203
Florin Coras62877022020-10-28 21:22:04 -07002204 is_ct = vcl_session_is_ct (s);
2205 svm_fifo_dequeue_drop (is_ct ? s->ct_rx_fifo : s->rx_fifo, n_bytes);
Florin Corasd1cc38d2020-10-11 11:05:04 -07002206
Florin Coras8cc93212021-09-10 11:37:12 -07002207 ASSERT (s->rx_bytes_pending >= n_bytes);
Florin Corasd1cc38d2020-10-11 11:05:04 -07002208 s->rx_bytes_pending -= n_bytes;
Florin Coras2cba8532018-09-11 16:33:36 -07002209}
2210
Florin Coras7a2abce2020-04-05 19:25:44 +00002211always_inline u8
2212vcl_fifo_is_writeable (svm_fifo_t * f, u32 len, u8 is_dgram)
Dave Wallace543852a2017-08-03 02:11:34 -04002213{
Florin Coras7a2abce2020-04-05 19:25:44 +00002214 u32 max_enq = svm_fifo_max_enqueue_prod (f);
2215 if (is_dgram)
2216 return max_enq >= (sizeof (session_dgram_hdr_t) + len);
2217 else
2218 return max_enq > 0;
Florin Coras7a2abce2020-04-05 19:25:44 +00002219}
2220
2221always_inline int
2222vppcom_session_write_inline (vcl_worker_t * wrk, vcl_session_t * s, void *buf,
2223 size_t n, u8 is_flush, u8 is_dgram)
2224{
Florin Coras6d0106e2019-01-29 20:11:58 -08002225 int n_write, is_nonblocking;
Florin Coras460dce62018-07-27 05:45:06 -07002226 session_evt_type_t et;
Florin Coras14ed6df2019-03-06 21:13:42 -08002227 svm_fifo_t *tx_fifo;
Florin Coras3c2fed52018-07-04 04:15:05 -07002228 svm_msg_q_t *mq;
Florin Coras0e88e852018-09-17 22:09:02 -07002229 u8 is_ct;
Dave Wallace543852a2017-08-03 02:11:34 -04002230
Florin Coras0b0d28e2021-06-04 17:31:53 -07002231 /* Accept zero length writes but just return */
2232 if (PREDICT_FALSE (!n))
2233 return VPPCOM_OK;
2234
2235 if (PREDICT_FALSE (!buf))
2236 return VPPCOM_EFAULT;
Dave Wallace543852a2017-08-03 02:11:34 -04002237
Florin Coras6c3b2182020-10-19 18:36:48 -07002238 if (PREDICT_FALSE (s->flags & VCL_SESSION_F_IS_VEP))
Dave Wallace543852a2017-08-03 02:11:34 -04002239 {
Florin Coras6d0106e2019-01-29 20:11:58 -08002240 VDBG (0, "ERROR: session %u [0x%llx]: cannot write to an epoll"
2241 " session!", s->session_index, s->vpp_handle);
Florin Coras070453d2018-08-24 17:04:27 -07002242 return VPPCOM_EBADFD;
Dave Wallace543852a2017-08-03 02:11:34 -04002243 }
2244
liuyacan55c952e2021-06-13 14:54:55 +08002245 if (PREDICT_FALSE (!vcl_session_is_open (s)))
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002246 {
Florin Coras6d0106e2019-01-29 20:11:58 -08002247 VDBG (1, "session %u [0x%llx]: is not open! state 0x%x (%s)",
2248 s->session_index, s->vpp_handle, s->session_state,
2249 vppcom_session_state_str (s->session_state));
2250 return vcl_session_closed_error (s);;
Dave Wallace9c4b5b22017-10-18 21:15:48 -04002251 }
2252
liuyacan55c952e2021-06-13 14:54:55 +08002253 if (PREDICT_FALSE (s->flags & VCL_SESSION_F_WR_SHUTDOWN))
2254 {
2255 VDBG (1, "session %u [0x%llx]: is shutdown! state 0x%x (%s)",
2256 s->session_index, s->vpp_handle, s->session_state,
2257 vppcom_session_state_str (s->session_state));
2258 return VPPCOM_EPIPE;
2259 }
2260
Florin Coras0e88e852018-09-17 22:09:02 -07002261 is_ct = vcl_session_is_ct (s);
Florin Coras653e43f2019-03-04 10:56:23 -08002262 tx_fifo = is_ct ? s->ct_tx_fifo : s->tx_fifo;
Florin Corasac422d62020-10-19 20:51:36 -07002263 is_nonblocking = vcl_session_has_attr (s, VCL_SESS_ATTR_NONBLOCK);
Sirshak Das28aa5392019-02-05 01:33:33 -06002264
Florin Coras653e43f2019-03-04 10:56:23 -08002265 mq = wrk->app_event_queue;
Florin Coras7a2abce2020-04-05 19:25:44 +00002266 if (!vcl_fifo_is_writeable (tx_fifo, n, is_dgram))
Dave Wallace543852a2017-08-03 02:11:34 -04002267 {
Florin Coras54693d22018-07-17 10:46:29 -07002268 if (is_nonblocking)
2269 {
Florin Coras070453d2018-08-24 17:04:27 -07002270 return VPPCOM_EWOULDBLOCK;
Florin Coras54693d22018-07-17 10:46:29 -07002271 }
Florin Coras7a2abce2020-04-05 19:25:44 +00002272 while (!vcl_fifo_is_writeable (tx_fifo, n, is_dgram))
Florin Coras54693d22018-07-17 10:46:29 -07002273 {
Florin Coras2d379d82019-06-28 12:45:12 -07002274 svm_fifo_add_want_deq_ntf (tx_fifo, SVM_FIFO_WANT_DEQ_NOTIF);
Florin Coras6d0106e2019-01-29 20:11:58 -08002275 if (vcl_session_is_closing (s))
2276 return vcl_session_closing_error (s);
Florin Coras0e88e852018-09-17 22:09:02 -07002277
Florin Coras5398dfb2021-01-25 20:31:27 -08002278 svm_msg_q_wait (mq, SVM_MQ_WAIT_EMPTY);
2279 vcl_worker_flush_mq_events (wrk);
Florin Coras54693d22018-07-17 10:46:29 -07002280 }
Dave Wallace543852a2017-08-03 02:11:34 -04002281 }
Dave Wallace543852a2017-08-03 02:11:34 -04002282
Florin Coras653e43f2019-03-04 10:56:23 -08002283 et = SESSION_IO_EVT_TX;
2284 if (is_flush && !is_ct)
Florin Coras42ceddb2018-12-12 10:56:01 -08002285 et = SESSION_IO_EVT_TX_FLUSH;
2286
Florin Coras7a2abce2020-04-05 19:25:44 +00002287 if (is_dgram)
Florin Coras460dce62018-07-27 05:45:06 -07002288 n_write = app_send_dgram_raw (tx_fifo, &s->transport,
Florin Coras653e43f2019-03-04 10:56:23 -08002289 s->vpp_evt_q, buf, n, et,
Florin Coras14ed6df2019-03-06 21:13:42 -08002290 0 /* do_evt */ , SVM_Q_WAIT);
Florin Coras460dce62018-07-27 05:45:06 -07002291 else
2292 n_write = app_send_stream_raw (tx_fifo, s->vpp_evt_q, buf, n, et,
Florin Coras14ed6df2019-03-06 21:13:42 -08002293 0 /* do_evt */ , SVM_Q_WAIT);
Florin Coras653e43f2019-03-04 10:56:23 -08002294
Florin Coras14ed6df2019-03-06 21:13:42 -08002295 if (svm_fifo_set_event (s->tx_fifo))
Florin Corasc547e912020-12-08 17:50:45 -08002296 app_send_io_evt_to_vpp (
2297 s->vpp_evt_q, s->tx_fifo->shr->master_session_index, et, SVM_Q_WAIT);
Keith Burns (alagalah)410bcca2018-03-23 13:42:49 -07002298
Florin Coras56230092020-09-02 20:52:58 -07002299 /* The underlying fifo segment can run out of memory */
2300 if (PREDICT_FALSE (n_write < 0))
2301 return VPPCOM_EAGAIN;
Dave Wallace543852a2017-08-03 02:11:34 -04002302
Florin Coras6d0106e2019-01-29 20:11:58 -08002303 VDBG (2, "session %u [0x%llx]: wrote %d bytes", s->session_index,
2304 s->vpp_handle, n_write);
Florin Coras0e88e852018-09-17 22:09:02 -07002305
Florin Coras54693d22018-07-17 10:46:29 -07002306 return n_write;
Dave Wallace543852a2017-08-03 02:11:34 -04002307}
2308
Florin Coras42ceddb2018-12-12 10:56:01 -08002309int
2310vppcom_session_write (uint32_t session_handle, void *buf, size_t n)
2311{
Florin Coras7a2abce2020-04-05 19:25:44 +00002312 vcl_worker_t *wrk = vcl_worker_get_current ();
2313 vcl_session_t *s;
2314
2315 s = vcl_session_get_w_handle (wrk, session_handle);
2316 if (PREDICT_FALSE (!s))
2317 return VPPCOM_EBADFD;
2318
2319 return vppcom_session_write_inline (wrk, s, buf, n,
2320 0 /* is_flush */ , s->is_dgram ? 1 : 0);
Florin Coras42ceddb2018-12-12 10:56:01 -08002321}
2322
Florin Corasb0f662f2018-12-27 14:51:46 -08002323int
2324vppcom_session_write_msg (uint32_t session_handle, void *buf, size_t n)
2325{
Florin Coras7a2abce2020-04-05 19:25:44 +00002326 vcl_worker_t *wrk = vcl_worker_get_current ();
2327 vcl_session_t *s;
2328
2329 s = vcl_session_get_w_handle (wrk, session_handle);
2330 if (PREDICT_FALSE (!s))
2331 return VPPCOM_EBADFD;
2332
2333 return vppcom_session_write_inline (wrk, s, buf, n,
2334 1 /* is_flush */ , s->is_dgram ? 1 : 0);
Florin Corasb0f662f2018-12-27 14:51:46 -08002335}
2336
Florin Corasc0737e92019-03-04 14:19:39 -08002337#define vcl_fifo_rx_evt_valid_or_break(_s) \
Florin Corasbd52e462019-10-28 13:22:37 -07002338if (PREDICT_FALSE (!_s->rx_fifo)) \
2339 break; \
Florin Corasc0737e92019-03-04 14:19:39 -08002340if (PREDICT_FALSE (svm_fifo_is_empty (_s->rx_fifo))) \
2341 { \
2342 if (!vcl_session_is_ct (_s)) \
2343 { \
2344 svm_fifo_unset_event (_s->rx_fifo); \
2345 if (svm_fifo_is_empty (_s->rx_fifo)) \
2346 break; \
2347 } \
2348 else if (svm_fifo_is_empty (_s->ct_rx_fifo)) \
2349 { \
Florin Coras2f630182020-08-13 00:17:51 -07002350 svm_fifo_unset_event (_s->rx_fifo); /* rx evts on actual fifo*/ \
Florin Corasc0737e92019-03-04 14:19:39 -08002351 if (svm_fifo_is_empty (_s->ct_rx_fifo)) \
2352 break; \
2353 } \
2354 } \
Florin Coras6d4bb422018-09-04 22:07:27 -07002355
Florin Coras86f04502018-09-12 16:08:01 -07002356static void
2357vcl_select_handle_mq_event (vcl_worker_t * wrk, session_event_t * e,
2358 unsigned long n_bits, unsigned long *read_map,
2359 unsigned long *write_map,
2360 unsigned long *except_map, u32 * bits_set)
Florin Coras54693d22018-07-17 10:46:29 -07002361{
2362 session_disconnected_msg_t *disconnected_msg;
Florin Coras99368312018-08-02 10:45:44 -07002363 session_connected_msg_t *connected_msg;
Florin Corasb242d312020-10-26 15:35:40 -07002364 vcl_session_t *s;
Florin Coras86f04502018-09-12 16:08:01 -07002365 u32 sid;
2366
2367 switch (e->event_type)
2368 {
Florin Corasc0737e92019-03-04 14:19:39 -08002369 case SESSION_IO_EVT_RX:
2370 sid = e->session_index;
Florin Corasb242d312020-10-26 15:35:40 -07002371 s = vcl_session_get (wrk, sid);
2372 if (!s || !vcl_session_is_open (s))
Florin Coras86f04502018-09-12 16:08:01 -07002373 break;
Florin Corasb242d312020-10-26 15:35:40 -07002374 vcl_fifo_rx_evt_valid_or_break (s);
Florin Coras86f04502018-09-12 16:08:01 -07002375 if (sid < n_bits && read_map)
2376 {
David Johnsond9818dd2018-12-14 14:53:41 -05002377 clib_bitmap_set_no_check ((uword *) read_map, sid, 1);
Florin Coras86f04502018-09-12 16:08:01 -07002378 *bits_set += 1;
2379 }
2380 break;
Florin Corasfe97da32019-03-06 10:09:04 -08002381 case SESSION_IO_EVT_TX:
Florin Corasc0737e92019-03-04 14:19:39 -08002382 sid = e->session_index;
Florin Corasb242d312020-10-26 15:35:40 -07002383 s = vcl_session_get (wrk, sid);
2384 if (!s || !vcl_session_is_open (s))
Florin Coras86f04502018-09-12 16:08:01 -07002385 break;
2386 if (sid < n_bits && write_map)
2387 {
David Johnsond9818dd2018-12-14 14:53:41 -05002388 clib_bitmap_set_no_check ((uword *) write_map, sid, 1);
Florin Coras86f04502018-09-12 16:08:01 -07002389 *bits_set += 1;
2390 }
2391 break;
Florin Coras86f04502018-09-12 16:08:01 -07002392 case SESSION_CTRL_EVT_ACCEPTED:
Florin Corasb242d312020-10-26 15:35:40 -07002393 if (!e->postponed)
2394 s = vcl_session_accepted (wrk, (session_accepted_msg_t *) e->data);
2395 else
2396 s = vcl_session_get (wrk, e->session_index);
2397 if (!s)
Florin Coras3c7d4f92018-12-14 11:28:43 -08002398 break;
Florin Corasb242d312020-10-26 15:35:40 -07002399 sid = s->session_index;
Florin Coras86f04502018-09-12 16:08:01 -07002400 if (sid < n_bits && read_map)
2401 {
David Johnsond9818dd2018-12-14 14:53:41 -05002402 clib_bitmap_set_no_check ((uword *) read_map, sid, 1);
Florin Coras86f04502018-09-12 16:08:01 -07002403 *bits_set += 1;
2404 }
2405 break;
2406 case SESSION_CTRL_EVT_CONNECTED:
Florin Corasb242d312020-10-26 15:35:40 -07002407 if (!e->postponed)
2408 {
2409 connected_msg = (session_connected_msg_t *) e->data;
2410 sid = vcl_session_connected_handler (wrk, connected_msg);
2411 }
2412 else
2413 sid = e->session_index;
Florin Coras57c88932019-08-29 12:03:17 -07002414 if (sid == VCL_INVALID_SESSION_INDEX)
2415 break;
2416 if (sid < n_bits && write_map)
2417 {
2418 clib_bitmap_set_no_check ((uword *) write_map, sid, 1);
2419 *bits_set += 1;
2420 }
Florin Coras86f04502018-09-12 16:08:01 -07002421 break;
2422 case SESSION_CTRL_EVT_DISCONNECTED:
2423 disconnected_msg = (session_disconnected_msg_t *) e->data;
Florin Corasb242d312020-10-26 15:35:40 -07002424 s = vcl_session_disconnected_handler (wrk, disconnected_msg);
2425 if (!s)
Florin Coras3c7d4f92018-12-14 11:28:43 -08002426 break;
Florin Corasb242d312020-10-26 15:35:40 -07002427 sid = s->session_index;
Florin Coras86f04502018-09-12 16:08:01 -07002428 if (sid < n_bits && except_map)
2429 {
David Johnsond9818dd2018-12-14 14:53:41 -05002430 clib_bitmap_set_no_check ((uword *) except_map, sid, 1);
Florin Coras86f04502018-09-12 16:08:01 -07002431 *bits_set += 1;
2432 }
2433 break;
2434 case SESSION_CTRL_EVT_RESET:
2435 sid = vcl_session_reset_handler (wrk, (session_reset_msg_t *) e->data);
2436 if (sid < n_bits && except_map)
2437 {
David Johnsond9818dd2018-12-14 14:53:41 -05002438 clib_bitmap_set_no_check ((uword *) except_map, sid, 1);
Florin Coras86f04502018-09-12 16:08:01 -07002439 *bits_set += 1;
2440 }
2441 break;
Florin Corasdfae9f92019-02-20 19:48:31 -08002442 case SESSION_CTRL_EVT_UNLISTEN_REPLY:
2443 vcl_session_unlisten_reply_handler (wrk, e->data);
2444 break;
Florin Coras68b7e582020-01-21 18:33:23 -08002445 case SESSION_CTRL_EVT_MIGRATED:
2446 vcl_session_migrated_handler (wrk, e->data);
2447 break;
Florin Coras9ace36d2019-10-28 13:14:17 -07002448 case SESSION_CTRL_EVT_CLEANUP:
2449 vcl_session_cleanup_handler (wrk, e->data);
2450 break;
Florin Coras30e79c22019-01-02 19:31:22 -08002451 case SESSION_CTRL_EVT_WORKER_UPDATE_REPLY:
2452 vcl_session_worker_update_reply_handler (wrk, e->data);
2453 break;
2454 case SESSION_CTRL_EVT_REQ_WORKER_UPDATE:
2455 vcl_session_req_worker_update_handler (wrk, e->data);
2456 break;
Florin Corasc4c4cf52019-08-24 18:17:34 -07002457 case SESSION_CTRL_EVT_APP_ADD_SEGMENT:
2458 vcl_session_app_add_segment_handler (wrk, e->data);
2459 break;
2460 case SESSION_CTRL_EVT_APP_DEL_SEGMENT:
2461 vcl_session_app_del_segment_handler (wrk, e->data);
2462 break;
hanlina3a48962020-07-13 11:09:15 +08002463 case SESSION_CTRL_EVT_APP_WRK_RPC:
Florin Coras40c07ce2020-07-16 20:46:17 -07002464 vcl_worker_rpc_handler (wrk, e->data);
2465 break;
Florin Coras86f04502018-09-12 16:08:01 -07002466 default:
2467 clib_warning ("unhandled: %u", e->event_type);
2468 break;
2469 }
2470}
2471
2472static int
2473vcl_select_handle_mq (vcl_worker_t * wrk, svm_msg_q_t * mq,
2474 unsigned long n_bits, unsigned long *read_map,
2475 unsigned long *write_map, unsigned long *except_map,
2476 double time_to_wait, u32 * bits_set)
2477{
Florin Coras99368312018-08-02 10:45:44 -07002478 svm_msg_q_msg_t *msg;
Florin Coras54693d22018-07-17 10:46:29 -07002479 session_event_t *e;
Florin Coras86f04502018-09-12 16:08:01 -07002480 u32 i;
Florin Coras54693d22018-07-17 10:46:29 -07002481
Florin Coras54693d22018-07-17 10:46:29 -07002482 if (svm_msg_q_is_empty (mq))
Dave Wallace4878cbe2017-11-21 03:45:09 -05002483 {
Florin Coras54693d22018-07-17 10:46:29 -07002484 if (*bits_set)
Florin Coras5398dfb2021-01-25 20:31:27 -08002485 return 0;
Dave Wallace4878cbe2017-11-21 03:45:09 -05002486
Florin Coras54693d22018-07-17 10:46:29 -07002487 if (!time_to_wait)
Florin Coras5398dfb2021-01-25 20:31:27 -08002488 return 0;
Florin Coras54693d22018-07-17 10:46:29 -07002489 else if (time_to_wait < 0)
Florin Coras5398dfb2021-01-25 20:31:27 -08002490 svm_msg_q_wait (mq, SVM_MQ_WAIT_EMPTY);
Florin Coras54693d22018-07-17 10:46:29 -07002491 else
2492 {
2493 if (svm_msg_q_timedwait (mq, time_to_wait))
Florin Coras5398dfb2021-01-25 20:31:27 -08002494 return 0;
Dave Wallace4878cbe2017-11-21 03:45:09 -05002495 }
2496 }
Florin Corase003a1b2019-06-05 10:47:16 -07002497 vcl_mq_dequeue_batch (wrk, mq, ~0);
Florin Coras54693d22018-07-17 10:46:29 -07002498
Florin Coras134a9962018-08-28 11:32:04 -07002499 for (i = 0; i < vec_len (wrk->mq_msg_vector); i++)
Florin Coras54693d22018-07-17 10:46:29 -07002500 {
Florin Coras134a9962018-08-28 11:32:04 -07002501 msg = vec_elt_at_index (wrk->mq_msg_vector, i);
Florin Coras99368312018-08-02 10:45:44 -07002502 e = svm_msg_q_msg_data (mq, msg);
Florin Coras86f04502018-09-12 16:08:01 -07002503 vcl_select_handle_mq_event (wrk, e, n_bits, read_map, write_map,
2504 except_map, bits_set);
Florin Coras99368312018-08-02 10:45:44 -07002505 svm_msg_q_free_msg (mq, msg);
Florin Coras54693d22018-07-17 10:46:29 -07002506 }
Florin Coras134a9962018-08-28 11:32:04 -07002507 vec_reset_length (wrk->mq_msg_vector);
Florin Coras30e79c22019-01-02 19:31:22 -08002508 vcl_handle_pending_wrk_updates (wrk);
Florin Coras54693d22018-07-17 10:46:29 -07002509 return *bits_set;
Dave Wallace543852a2017-08-03 02:11:34 -04002510}
2511
Florin Coras99368312018-08-02 10:45:44 -07002512static int
Florin Coras294afe22019-01-07 17:49:17 -08002513vppcom_select_condvar (vcl_worker_t * wrk, int n_bits,
2514 vcl_si_set * read_map, vcl_si_set * write_map,
2515 vcl_si_set * except_map, double time_to_wait,
Florin Coras134a9962018-08-28 11:32:04 -07002516 u32 * bits_set)
Florin Coras99368312018-08-02 10:45:44 -07002517{
Florin Coras14ed6df2019-03-06 21:13:42 -08002518 double wait = 0, start = 0;
2519
2520 if (!*bits_set)
2521 {
2522 wait = time_to_wait;
2523 start = clib_time_now (&wrk->clib_time);
2524 }
2525
2526 do
2527 {
2528 vcl_select_handle_mq (wrk, wrk->app_event_queue, n_bits, read_map,
2529 write_map, except_map, wait, bits_set);
2530 if (*bits_set)
2531 return *bits_set;
2532 if (wait == -1)
2533 continue;
2534
2535 wait = wait - (clib_time_now (&wrk->clib_time) - start);
2536 }
2537 while (wait > 0);
2538
2539 return 0;
Florin Coras99368312018-08-02 10:45:44 -07002540}
2541
2542static int
Florin Coras294afe22019-01-07 17:49:17 -08002543vppcom_select_eventfd (vcl_worker_t * wrk, int n_bits,
2544 vcl_si_set * read_map, vcl_si_set * write_map,
2545 vcl_si_set * except_map, double time_to_wait,
Florin Coras134a9962018-08-28 11:32:04 -07002546 u32 * bits_set)
Florin Coras99368312018-08-02 10:45:44 -07002547{
2548 vcl_mq_evt_conn_t *mqc;
2549 int __clib_unused n_read;
2550 int n_mq_evts, i;
2551 u64 buf;
2552
Florin Coras134a9962018-08-28 11:32:04 -07002553 vec_validate (wrk->mq_events, pool_elts (wrk->mq_evt_conns));
2554 n_mq_evts = epoll_wait (wrk->mqs_epfd, wrk->mq_events,
2555 vec_len (wrk->mq_events), time_to_wait);
Florin Coras99368312018-08-02 10:45:44 -07002556 for (i = 0; i < n_mq_evts; i++)
2557 {
Florin Coras134a9962018-08-28 11:32:04 -07002558 mqc = vcl_mq_evt_conn_get (wrk, wrk->mq_events[i].data.u32);
Florin Coras99368312018-08-02 10:45:44 -07002559 n_read = read (mqc->mq_fd, &buf, sizeof (buf));
Florin Coras134a9962018-08-28 11:32:04 -07002560 vcl_select_handle_mq (wrk, mqc->mq, n_bits, read_map, write_map,
Florin Coras99368312018-08-02 10:45:44 -07002561 except_map, 0, bits_set);
2562 }
2563
2564 return (n_mq_evts > 0 ? (int) *bits_set : 0);
2565}
2566
Dave Wallace543852a2017-08-03 02:11:34 -04002567int
Florin Coras294afe22019-01-07 17:49:17 -08002568vppcom_select (int n_bits, vcl_si_set * read_map, vcl_si_set * write_map,
2569 vcl_si_set * except_map, double time_to_wait)
Dave Wallace543852a2017-08-03 02:11:34 -04002570{
Florin Coras54693d22018-07-17 10:46:29 -07002571 u32 sid, minbits = clib_max (n_bits, BITS (uword)), bits_set = 0;
Florin Coras134a9962018-08-28 11:32:04 -07002572 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras096a1d52021-01-27 15:33:51 -08002573 vcl_session_t *s = 0;
Florin Corasf49cf472020-04-19 23:12:08 +00002574 int i;
Dave Wallace543852a2017-08-03 02:11:34 -04002575
Dave Wallace7876d392017-10-19 03:53:57 -04002576 if (n_bits && read_map)
Dave Wallace543852a2017-08-03 02:11:34 -04002577 {
Florin Coras134a9962018-08-28 11:32:04 -07002578 clib_bitmap_validate (wrk->rd_bitmap, minbits);
Dave Barach178cf492018-11-13 16:34:13 -05002579 clib_memcpy_fast (wrk->rd_bitmap, read_map,
Florin Coras294afe22019-01-07 17:49:17 -08002580 vec_len (wrk->rd_bitmap) * sizeof (vcl_si_set));
2581 memset (read_map, 0, vec_len (wrk->rd_bitmap) * sizeof (vcl_si_set));
Dave Wallace543852a2017-08-03 02:11:34 -04002582 }
Dave Wallace7876d392017-10-19 03:53:57 -04002583 if (n_bits && write_map)
Dave Wallace543852a2017-08-03 02:11:34 -04002584 {
Florin Coras134a9962018-08-28 11:32:04 -07002585 clib_bitmap_validate (wrk->wr_bitmap, minbits);
Dave Barach178cf492018-11-13 16:34:13 -05002586 clib_memcpy_fast (wrk->wr_bitmap, write_map,
Florin Coras294afe22019-01-07 17:49:17 -08002587 vec_len (wrk->wr_bitmap) * sizeof (vcl_si_set));
2588 memset (write_map, 0, vec_len (wrk->wr_bitmap) * sizeof (vcl_si_set));
Dave Wallace543852a2017-08-03 02:11:34 -04002589 }
Dave Wallace7876d392017-10-19 03:53:57 -04002590 if (n_bits && except_map)
Dave Wallace543852a2017-08-03 02:11:34 -04002591 {
Florin Coras134a9962018-08-28 11:32:04 -07002592 clib_bitmap_validate (wrk->ex_bitmap, minbits);
Dave Barach178cf492018-11-13 16:34:13 -05002593 clib_memcpy_fast (wrk->ex_bitmap, except_map,
Florin Coras294afe22019-01-07 17:49:17 -08002594 vec_len (wrk->ex_bitmap) * sizeof (vcl_si_set));
2595 memset (except_map, 0, vec_len (wrk->ex_bitmap) * sizeof (vcl_si_set));
Dave Wallace543852a2017-08-03 02:11:34 -04002596 }
2597
Florin Coras54693d22018-07-17 10:46:29 -07002598 if (!n_bits)
2599 return 0;
2600
2601 if (!write_map)
2602 goto check_rd;
2603
Florin Coras096a1d52021-01-27 15:33:51 -08002604 clib_bitmap_foreach (sid, wrk->wr_bitmap)
2605 {
2606 if (!(s = vcl_session_get (wrk, sid)))
2607 {
2608 clib_bitmap_set_no_check ((uword *) write_map, sid, 1);
2609 bits_set++;
2610 continue;
2611 }
Florin Coras54693d22018-07-17 10:46:29 -07002612
Florin Coras096a1d52021-01-27 15:33:51 -08002613 if (vcl_session_write_ready (s))
2614 {
2615 clib_bitmap_set_no_check ((uword *) write_map, sid, 1);
2616 bits_set++;
2617 }
2618 else
2619 {
2620 svm_fifo_t *txf = vcl_session_is_ct (s) ? s->ct_tx_fifo : s->tx_fifo;
2621 svm_fifo_add_want_deq_ntf (txf, SVM_FIFO_WANT_DEQ_NOTIF);
2622 }
2623 }
Florin Coras54693d22018-07-17 10:46:29 -07002624
2625check_rd:
2626 if (!read_map)
2627 goto check_mq;
Florin Coras99368312018-08-02 10:45:44 -07002628
Florin Coras096a1d52021-01-27 15:33:51 -08002629 clib_bitmap_foreach (sid, wrk->rd_bitmap)
2630 {
2631 if (!(s = vcl_session_get (wrk, sid)))
2632 {
2633 clib_bitmap_set_no_check ((uword *) read_map, sid, 1);
2634 bits_set++;
2635 continue;
2636 }
Florin Coras54693d22018-07-17 10:46:29 -07002637
Florin Coras096a1d52021-01-27 15:33:51 -08002638 if (vcl_session_read_ready (s))
2639 {
2640 clib_bitmap_set_no_check ((uword *) read_map, sid, 1);
2641 bits_set++;
2642 }
2643 }
Florin Coras54693d22018-07-17 10:46:29 -07002644
2645check_mq:
Dave Wallace543852a2017-08-03 02:11:34 -04002646
Florin Coras86f04502018-09-12 16:08:01 -07002647 for (i = 0; i < vec_len (wrk->unhandled_evts_vector); i++)
2648 {
2649 vcl_select_handle_mq_event (wrk, &wrk->unhandled_evts_vector[i], n_bits,
2650 read_map, write_map, except_map, &bits_set);
2651 }
2652 vec_reset_length (wrk->unhandled_evts_vector);
2653
Florin Coras99368312018-08-02 10:45:44 -07002654 if (vcm->cfg.use_mq_eventfd)
Florin Coras134a9962018-08-28 11:32:04 -07002655 vppcom_select_eventfd (wrk, n_bits, read_map, write_map, except_map,
Florin Coras99368312018-08-02 10:45:44 -07002656 time_to_wait, &bits_set);
2657 else
Florin Coras134a9962018-08-28 11:32:04 -07002658 vppcom_select_condvar (wrk, n_bits, read_map, write_map, except_map,
Florin Coras99368312018-08-02 10:45:44 -07002659 time_to_wait, &bits_set);
Florin Coras54693d22018-07-17 10:46:29 -07002660
Dave Wallace543852a2017-08-03 02:11:34 -04002661 return (bits_set);
2662}
2663
Dave Wallacef7f809c2017-10-03 01:48:42 -04002664static inline void
Florin Coras7e5e62b2019-07-30 14:08:23 -07002665vep_verify_epoll_chain (vcl_worker_t * wrk, u32 vep_handle)
Dave Wallacef7f809c2017-10-03 01:48:42 -04002666{
Dave Wallacef7f809c2017-10-03 01:48:42 -04002667 vppcom_epoll_t *vep;
Florin Coras7e5e62b2019-07-30 14:08:23 -07002668 u32 sh = vep_handle;
Florin Coras6c3b2182020-10-19 18:36:48 -07002669 vcl_session_t *s;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002670
Florin Corasc0737e92019-03-04 14:19:39 -08002671 if (VPPCOM_DEBUG <= 2)
Dave Wallacef7f809c2017-10-03 01:48:42 -04002672 return;
2673
Florin Coras6c3b2182020-10-19 18:36:48 -07002674 s = vcl_session_get_w_handle (wrk, vep_handle);
2675 if (PREDICT_FALSE (!s))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002676 {
Florin Coras7e5e62b2019-07-30 14:08:23 -07002677 VDBG (0, "ERROR: Invalid vep_sh (%u)!", vep_handle);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002678 goto done;
2679 }
Florin Coras6c3b2182020-10-19 18:36:48 -07002680 if (PREDICT_FALSE (!(s->flags & VCL_SESSION_F_IS_VEP)))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002681 {
Florin Coras7e5e62b2019-07-30 14:08:23 -07002682 VDBG (0, "ERROR: vep_sh (%u) is not a vep!", vep_handle);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002683 goto done;
2684 }
Florin Coras6c3b2182020-10-19 18:36:48 -07002685 vep = &s->vep;
Florin Coras7e5e62b2019-07-30 14:08:23 -07002686 VDBG (0, "vep_sh (%u): Dumping epoll chain\n"
Florin Coras5e062572019-03-14 19:07:51 -07002687 "{\n"
2688 " is_vep = %u\n"
2689 " is_vep_session = %u\n"
Florin Coras7e5e62b2019-07-30 14:08:23 -07002690 " next_sh = 0x%x (%u)\n"
Florin Coras6c3b2182020-10-19 18:36:48 -07002691 "}\n", vep_handle, s->flags & VCL_SESSION_F_IS_VEP,
2692 s->flags & VCL_SESSION_F_IS_VEP_SESSION, vep->next_sh, vep->next_sh);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002693
Florin Coras7e5e62b2019-07-30 14:08:23 -07002694 for (sh = vep->next_sh; sh != ~0; sh = vep->next_sh)
Dave Wallacef7f809c2017-10-03 01:48:42 -04002695 {
Florin Coras6c3b2182020-10-19 18:36:48 -07002696 s = vcl_session_get_w_handle (wrk, sh);
2697 if (PREDICT_FALSE (!s))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002698 {
Florin Coras7e5e62b2019-07-30 14:08:23 -07002699 VDBG (0, "ERROR: Invalid sh (%u)!", sh);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002700 goto done;
2701 }
Florin Coras6c3b2182020-10-19 18:36:48 -07002702 if (PREDICT_FALSE (s->flags & VCL_SESSION_F_IS_VEP))
Florin Coras5e062572019-03-14 19:07:51 -07002703 {
Florin Coras7e5e62b2019-07-30 14:08:23 -07002704 VDBG (0, "ERROR: sh (%u) is a vep!", vep_handle);
Florin Coras5e062572019-03-14 19:07:51 -07002705 }
Florin Coras6c3b2182020-10-19 18:36:48 -07002706 else if (PREDICT_FALSE (!(s->flags & VCL_SESSION_F_IS_VEP_SESSION)))
Dave Wallace4878cbe2017-11-21 03:45:09 -05002707 {
Florin Coras7e5e62b2019-07-30 14:08:23 -07002708 VDBG (0, "ERROR: sh (%u) is not a vep session handle!", sh);
Dave Wallace4878cbe2017-11-21 03:45:09 -05002709 goto done;
2710 }
Florin Coras6c3b2182020-10-19 18:36:48 -07002711 vep = &s->vep;
Florin Coras7e5e62b2019-07-30 14:08:23 -07002712 if (PREDICT_FALSE (vep->vep_sh != vep_handle))
2713 VDBG (0, "ERROR: session (%u) vep_sh (%u) != vep_sh (%u)!",
Florin Coras6c3b2182020-10-19 18:36:48 -07002714 sh, s->vep.vep_sh, vep_handle);
2715 if (s->flags & VCL_SESSION_F_IS_VEP_SESSION)
Dave Wallace4878cbe2017-11-21 03:45:09 -05002716 {
Florin Coras7e5e62b2019-07-30 14:08:23 -07002717 VDBG (0, "vep_sh[%u]: sh 0x%x (%u)\n"
Florin Coras5e062572019-03-14 19:07:51 -07002718 "{\n"
Florin Coras7e5e62b2019-07-30 14:08:23 -07002719 " next_sh = 0x%x (%u)\n"
2720 " prev_sh = 0x%x (%u)\n"
2721 " vep_sh = 0x%x (%u)\n"
Florin Coras5e062572019-03-14 19:07:51 -07002722 " ev.events = 0x%x\n"
2723 " ev.data.u64 = 0x%llx\n"
2724 " et_mask = 0x%x\n"
2725 "}\n",
Florin Coras7e5e62b2019-07-30 14:08:23 -07002726 vep_handle, sh, sh, vep->next_sh, vep->next_sh, vep->prev_sh,
Florin Coras5e062572019-03-14 19:07:51 -07002727 vep->prev_sh, vep->vep_sh, vep->vep_sh, vep->ev.events,
2728 vep->ev.data.u64, vep->et_mask);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002729 }
2730 }
Dave Wallacef7f809c2017-10-03 01:48:42 -04002731
2732done:
Florin Coras7e5e62b2019-07-30 14:08:23 -07002733 VDBG (0, "vep_sh (%u): Dump complete!\n", vep_handle);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002734}
2735
2736int
2737vppcom_epoll_create (void)
2738{
Florin Coras134a9962018-08-28 11:32:04 -07002739 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras7e12d942018-06-27 14:32:43 -07002740 vcl_session_t *vep_session;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002741
Florin Coras134a9962018-08-28 11:32:04 -07002742 vep_session = vcl_session_alloc (wrk);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002743
Florin Coras6c3b2182020-10-19 18:36:48 -07002744 vep_session->flags |= VCL_SESSION_F_IS_VEP;
Florin Coras134a9962018-08-28 11:32:04 -07002745 vep_session->vep.vep_sh = ~0;
2746 vep_session->vep.next_sh = ~0;
2747 vep_session->vep.prev_sh = ~0;
Dave Wallace4878cbe2017-11-21 03:45:09 -05002748 vep_session->vpp_handle = ~0;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08002749
Florin Corasa7a1a222018-12-30 17:11:31 -08002750 vcl_evt (VCL_EVT_EPOLL_CREATE, vep_session, vep_session->session_index);
2751 VDBG (0, "Created vep_idx %u", vep_session->session_index);
Keith Burns (alagalah)09b27842018-01-05 14:39:59 -08002752
Florin Corasab2f6db2018-08-31 14:31:41 -07002753 return vcl_session_handle (vep_session);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002754}
2755
2756int
Florin Coras134a9962018-08-28 11:32:04 -07002757vppcom_epoll_ctl (uint32_t vep_handle, int op, uint32_t session_handle,
Dave Wallacef7f809c2017-10-03 01:48:42 -04002758 struct epoll_event *event)
2759{
Florin Coras134a9962018-08-28 11:32:04 -07002760 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras87f76002021-06-28 19:13:29 -07002761 int rv = VPPCOM_OK, add_evt = 0;
Florin Coras7e12d942018-06-27 14:32:43 -07002762 vcl_session_t *vep_session;
Florin Coras17ec5772020-08-12 20:46:29 -07002763 vcl_session_t *s;
2764 svm_fifo_t *txf;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002765
Florin Coras134a9962018-08-28 11:32:04 -07002766 if (vep_handle == session_handle)
Dave Wallacef7f809c2017-10-03 01:48:42 -04002767 {
Florin Corasa7a1a222018-12-30 17:11:31 -08002768 VDBG (0, "vep_sh == session handle (%u)!", vep_handle);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002769 return VPPCOM_EINVAL;
2770 }
2771
Florin Coras134a9962018-08-28 11:32:04 -07002772 vep_session = vcl_session_get_w_handle (wrk, vep_handle);
Florin Coras070453d2018-08-24 17:04:27 -07002773 if (PREDICT_FALSE (!vep_session))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002774 {
Florin Corasa7a1a222018-12-30 17:11:31 -08002775 VDBG (0, "Invalid vep_sh (%u)!", vep_handle);
Florin Coras070453d2018-08-24 17:04:27 -07002776 return VPPCOM_EBADFD;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002777 }
Florin Coras6c3b2182020-10-19 18:36:48 -07002778 if (PREDICT_FALSE (!(vep_session->flags & VCL_SESSION_F_IS_VEP)))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002779 {
Florin Corasa7a1a222018-12-30 17:11:31 -08002780 VDBG (0, "vep_sh (%u) is not a vep!", vep_handle);
Florin Coras070453d2018-08-24 17:04:27 -07002781 return VPPCOM_EINVAL;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002782 }
2783
Florin Coras134a9962018-08-28 11:32:04 -07002784 ASSERT (vep_session->vep.vep_sh == ~0);
2785 ASSERT (vep_session->vep.prev_sh == ~0);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002786
Florin Coras17ec5772020-08-12 20:46:29 -07002787 s = vcl_session_get_w_handle (wrk, session_handle);
2788 if (PREDICT_FALSE (!s))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002789 {
Florin Corasa7a1a222018-12-30 17:11:31 -08002790 VDBG (0, "Invalid session_handle (%u)!", session_handle);
Florin Coras070453d2018-08-24 17:04:27 -07002791 return VPPCOM_EBADFD;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002792 }
Florin Coras6c3b2182020-10-19 18:36:48 -07002793 if (PREDICT_FALSE (s->flags & VCL_SESSION_F_IS_VEP))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002794 {
Florin Corasa7a1a222018-12-30 17:11:31 -08002795 VDBG (0, "session_handle (%u) is a vep!", vep_handle);
Florin Coras070453d2018-08-24 17:04:27 -07002796 return VPPCOM_EINVAL;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002797 }
2798
2799 switch (op)
2800 {
2801 case EPOLL_CTL_ADD:
2802 if (PREDICT_FALSE (!event))
2803 {
Florin Corasa7a1a222018-12-30 17:11:31 -08002804 VDBG (0, "EPOLL_CTL_ADD: NULL pointer to epoll_event structure!");
Florin Coras070453d2018-08-24 17:04:27 -07002805 return VPPCOM_EINVAL;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002806 }
Florin Coras2645f682021-06-04 15:59:41 -07002807 if (s->flags & VCL_SESSION_F_IS_VEP_SESSION)
2808 {
2809 VDBG (0, "EPOLL_CTL_ADD: %u already epolled!", s->session_index);
2810 rv = VPPCOM_EEXIST;
2811 goto done;
2812 }
Florin Coras134a9962018-08-28 11:32:04 -07002813 if (vep_session->vep.next_sh != ~0)
Dave Wallacef7f809c2017-10-03 01:48:42 -04002814 {
Florin Coras7e12d942018-06-27 14:32:43 -07002815 vcl_session_t *next_session;
Florin Corasab2f6db2018-08-31 14:31:41 -07002816 next_session = vcl_session_get_w_handle (wrk,
2817 vep_session->vep.next_sh);
Florin Coras070453d2018-08-24 17:04:27 -07002818 if (PREDICT_FALSE (!next_session))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002819 {
Florin Coras5e062572019-03-14 19:07:51 -07002820 VDBG (0, "EPOLL_CTL_ADD: Invalid vep.next_sh (%u) on "
Florin Corasa7a1a222018-12-30 17:11:31 -08002821 "vep_idx (%u)!", vep_session->vep.next_sh, vep_handle);
Florin Coras070453d2018-08-24 17:04:27 -07002822 return VPPCOM_EBADFD;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002823 }
Florin Coras134a9962018-08-28 11:32:04 -07002824 ASSERT (next_session->vep.prev_sh == vep_handle);
2825 next_session->vep.prev_sh = session_handle;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002826 }
Florin Coras17ec5772020-08-12 20:46:29 -07002827 s->vep.next_sh = vep_session->vep.next_sh;
2828 s->vep.prev_sh = vep_handle;
2829 s->vep.vep_sh = vep_handle;
2830 s->vep.et_mask = VEP_DEFAULT_ET_MASK;
Florin Corasfa3884f2021-06-22 20:04:46 -07002831 s->vep.lt_next = VCL_INVALID_SESSION_INDEX;
Florin Coras17ec5772020-08-12 20:46:29 -07002832 s->vep.ev = *event;
Florin Coras6c3b2182020-10-19 18:36:48 -07002833 s->flags &= ~VCL_SESSION_F_IS_VEP;
2834 s->flags |= VCL_SESSION_F_IS_VEP_SESSION;
Florin Coras134a9962018-08-28 11:32:04 -07002835 vep_session->vep.next_sh = session_handle;
Keith Burns (alagalah)3cf2d642018-02-23 10:17:01 -08002836
Florin Coras17ec5772020-08-12 20:46:29 -07002837 txf = vcl_session_is_ct (s) ? s->ct_tx_fifo : s->tx_fifo;
2838 if (txf && (event->events & EPOLLOUT))
2839 svm_fifo_add_want_deq_ntf (txf, SVM_FIFO_WANT_DEQ_NOTIF_IF_FULL);
Florin Coras1bcad5c2019-01-09 20:04:38 -08002840
Florin Coras6e3c1f82020-01-15 01:30:46 +00002841 /* Generate EPOLLOUT if tx fifo not full */
Florin Coras17ec5772020-08-12 20:46:29 -07002842 if ((event->events & EPOLLOUT) && (vcl_session_write_ready (s) > 0))
hanlin475c9d72019-12-26 11:44:28 +08002843 {
2844 session_event_t e = { 0 };
2845 e.event_type = SESSION_IO_EVT_TX;
Florin Coras17ec5772020-08-12 20:46:29 -07002846 e.session_index = s->session_index;
hanlin475c9d72019-12-26 11:44:28 +08002847 vec_add1 (wrk->unhandled_evts_vector, e);
Florin Coras87f76002021-06-28 19:13:29 -07002848 add_evt = 1;
hanlin475c9d72019-12-26 11:44:28 +08002849 }
Florin Coras6e3c1f82020-01-15 01:30:46 +00002850 /* Generate EPOLLIN if rx fifo has data */
Florin Coras17ec5772020-08-12 20:46:29 -07002851 if ((event->events & EPOLLIN) && (vcl_session_read_ready (s) > 0))
Florin Coras6e3c1f82020-01-15 01:30:46 +00002852 {
2853 session_event_t e = { 0 };
2854 e.event_type = SESSION_IO_EVT_RX;
Florin Coras17ec5772020-08-12 20:46:29 -07002855 e.session_index = s->session_index;
Florin Coras6e3c1f82020-01-15 01:30:46 +00002856 vec_add1 (wrk->unhandled_evts_vector, e);
Florin Coras87f76002021-06-28 19:13:29 -07002857 s->flags &= ~VCL_SESSION_F_HAS_RX_EVT;
2858 add_evt = 1;
2859 }
2860 if (!add_evt && vcl_session_is_closing (s))
2861 {
2862 session_event_t e = { 0 };
2863 if (s->session_state == VCL_STATE_VPP_CLOSING)
2864 e.event_type = SESSION_CTRL_EVT_DISCONNECTED;
2865 else
2866 e.event_type = SESSION_CTRL_EVT_RESET;
2867 e.session_index = s->session_index;
2868 e.postponed = 1;
2869 vec_add1 (wrk->unhandled_evts_vector, e);
Florin Coras6e3c1f82020-01-15 01:30:46 +00002870 }
Florin Corasa7a1a222018-12-30 17:11:31 -08002871 VDBG (1, "EPOLL_CTL_ADD: vep_sh %u, sh %u, events 0x%x, data 0x%llx!",
2872 vep_handle, session_handle, event->events, event->data.u64);
Florin Coras17ec5772020-08-12 20:46:29 -07002873 vcl_evt (VCL_EVT_EPOLL_CTLADD, s, event->events, event->data.u64);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002874 break;
2875
2876 case EPOLL_CTL_MOD:
2877 if (PREDICT_FALSE (!event))
2878 {
Florin Corasa7a1a222018-12-30 17:11:31 -08002879 VDBG (0, "EPOLL_CTL_MOD: NULL pointer to epoll_event structure!");
Dave Wallacef7f809c2017-10-03 01:48:42 -04002880 rv = VPPCOM_EINVAL;
2881 goto done;
2882 }
Florin Coras6c3b2182020-10-19 18:36:48 -07002883 else if (PREDICT_FALSE (!(s->flags & VCL_SESSION_F_IS_VEP_SESSION)))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002884 {
Florin Coras5e062572019-03-14 19:07:51 -07002885 VDBG (0, "sh %u EPOLL_CTL_MOD: not a vep session!", session_handle);
Florin Coras2645f682021-06-04 15:59:41 -07002886 rv = VPPCOM_ENOENT;
Dave Wallace4878cbe2017-11-21 03:45:09 -05002887 goto done;
2888 }
Florin Coras17ec5772020-08-12 20:46:29 -07002889 else if (PREDICT_FALSE (s->vep.vep_sh != vep_handle))
Dave Wallace4878cbe2017-11-21 03:45:09 -05002890 {
Florin Corasa7a1a222018-12-30 17:11:31 -08002891 VDBG (0, "EPOLL_CTL_MOD: sh %u vep_sh (%u) != vep_sh (%u)!",
Florin Coras17ec5772020-08-12 20:46:29 -07002892 session_handle, s->vep.vep_sh, vep_handle);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002893 rv = VPPCOM_EINVAL;
2894 goto done;
2895 }
hanlin475c9d72019-12-26 11:44:28 +08002896
Florin Coras2645f682021-06-04 15:59:41 -07002897 /* Generate EPOLLOUT if session write ready nd event was not on */
2898 if ((event->events & EPOLLOUT) && !(s->vep.ev.events & EPOLLOUT) &&
2899 (vcl_session_write_ready (s) > 0))
hanlin475c9d72019-12-26 11:44:28 +08002900 {
2901 session_event_t e = { 0 };
2902 e.event_type = SESSION_IO_EVT_TX;
Florin Coras17ec5772020-08-12 20:46:29 -07002903 e.session_index = s->session_index;
hanlin475c9d72019-12-26 11:44:28 +08002904 vec_add1 (wrk->unhandled_evts_vector, e);
2905 }
Florin Coras2645f682021-06-04 15:59:41 -07002906 /* Generate EPOLLIN if session read ready and event was not on */
2907 if ((event->events & EPOLLIN) && !(s->vep.ev.events & EPOLLIN) &&
2908 (vcl_session_read_ready (s) > 0))
2909 {
2910 session_event_t e = { 0 };
2911 e.event_type = SESSION_IO_EVT_RX;
2912 e.session_index = s->session_index;
2913 vec_add1 (wrk->unhandled_evts_vector, e);
Florin Coras87f76002021-06-28 19:13:29 -07002914 s->flags &= ~VCL_SESSION_F_HAS_RX_EVT;
Florin Coras2645f682021-06-04 15:59:41 -07002915 }
Florin Coras17ec5772020-08-12 20:46:29 -07002916 s->vep.et_mask = VEP_DEFAULT_ET_MASK;
2917 s->vep.ev = *event;
2918 txf = vcl_session_is_ct (s) ? s->ct_tx_fifo : s->tx_fifo;
Florin Coras8fb22fd2021-02-17 17:35:32 -08002919 if (txf)
2920 {
2921 if (event->events & EPOLLOUT)
2922 svm_fifo_add_want_deq_ntf (txf, SVM_FIFO_WANT_DEQ_NOTIF_IF_FULL);
2923 else
2924 svm_fifo_del_want_deq_ntf (txf, SVM_FIFO_WANT_DEQ_NOTIF_IF_FULL);
2925 }
Florin Corasa7a1a222018-12-30 17:11:31 -08002926 VDBG (1, "EPOLL_CTL_MOD: vep_sh %u, sh %u, events 0x%x, data 0x%llx!",
2927 vep_handle, session_handle, event->events, event->data.u64);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002928 break;
2929
2930 case EPOLL_CTL_DEL:
Florin Coras6c3b2182020-10-19 18:36:48 -07002931 if (PREDICT_FALSE (!(s->flags & VCL_SESSION_F_IS_VEP_SESSION)))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002932 {
Florin Corasa7a1a222018-12-30 17:11:31 -08002933 VDBG (0, "EPOLL_CTL_DEL: %u not a vep session!", session_handle);
Florin Coras2645f682021-06-04 15:59:41 -07002934 rv = VPPCOM_ENOENT;
Dave Wallace4878cbe2017-11-21 03:45:09 -05002935 goto done;
2936 }
Florin Coras17ec5772020-08-12 20:46:29 -07002937 else if (PREDICT_FALSE (s->vep.vep_sh != vep_handle))
Dave Wallace4878cbe2017-11-21 03:45:09 -05002938 {
Florin Corasa7a1a222018-12-30 17:11:31 -08002939 VDBG (0, "EPOLL_CTL_DEL: sh %u vep_sh (%u) != vep_sh (%u)!",
Florin Coras17ec5772020-08-12 20:46:29 -07002940 session_handle, s->vep.vep_sh, vep_handle);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002941 rv = VPPCOM_EINVAL;
2942 goto done;
2943 }
2944
Florin Coras17ec5772020-08-12 20:46:29 -07002945 if (s->vep.prev_sh == vep_handle)
2946 vep_session->vep.next_sh = s->vep.next_sh;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002947 else
2948 {
Florin Coras7e12d942018-06-27 14:32:43 -07002949 vcl_session_t *prev_session;
Florin Coras17ec5772020-08-12 20:46:29 -07002950 prev_session = vcl_session_get_w_handle (wrk, s->vep.prev_sh);
Florin Coras070453d2018-08-24 17:04:27 -07002951 if (PREDICT_FALSE (!prev_session))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002952 {
Florin Coras5e062572019-03-14 19:07:51 -07002953 VDBG (0, "EPOLL_CTL_DEL: Invalid prev_sh (%u) on sh (%u)!",
Florin Coras17ec5772020-08-12 20:46:29 -07002954 s->vep.prev_sh, session_handle);
Florin Coras070453d2018-08-24 17:04:27 -07002955 return VPPCOM_EBADFD;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002956 }
Florin Coras134a9962018-08-28 11:32:04 -07002957 ASSERT (prev_session->vep.next_sh == session_handle);
Florin Coras17ec5772020-08-12 20:46:29 -07002958 prev_session->vep.next_sh = s->vep.next_sh;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002959 }
Florin Coras17ec5772020-08-12 20:46:29 -07002960 if (s->vep.next_sh != ~0)
Dave Wallacef7f809c2017-10-03 01:48:42 -04002961 {
Florin Coras7e12d942018-06-27 14:32:43 -07002962 vcl_session_t *next_session;
Florin Coras17ec5772020-08-12 20:46:29 -07002963 next_session = vcl_session_get_w_handle (wrk, s->vep.next_sh);
Florin Coras070453d2018-08-24 17:04:27 -07002964 if (PREDICT_FALSE (!next_session))
Dave Wallacef7f809c2017-10-03 01:48:42 -04002965 {
Florin Coras5e062572019-03-14 19:07:51 -07002966 VDBG (0, "EPOLL_CTL_DEL: Invalid next_sh (%u) on sh (%u)!",
Florin Coras17ec5772020-08-12 20:46:29 -07002967 s->vep.next_sh, session_handle);
Florin Coras070453d2018-08-24 17:04:27 -07002968 return VPPCOM_EBADFD;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002969 }
Florin Coras134a9962018-08-28 11:32:04 -07002970 ASSERT (next_session->vep.prev_sh == session_handle);
Florin Coras17ec5772020-08-12 20:46:29 -07002971 next_session->vep.prev_sh = s->vep.prev_sh;
Dave Wallacef7f809c2017-10-03 01:48:42 -04002972 }
2973
Florin Corasfa3884f2021-06-22 20:04:46 -07002974 if (s->vep.lt_next != VCL_INVALID_SESSION_INDEX)
2975 vcl_epoll_lt_del (wrk, s);
2976
Florin Coras17ec5772020-08-12 20:46:29 -07002977 memset (&s->vep, 0, sizeof (s->vep));
2978 s->vep.next_sh = ~0;
2979 s->vep.prev_sh = ~0;
2980 s->vep.vep_sh = ~0;
Florin Corasfa3884f2021-06-22 20:04:46 -07002981 s->vep.lt_next = VCL_INVALID_SESSION_INDEX;
Florin Coras6c3b2182020-10-19 18:36:48 -07002982 s->flags &= ~VCL_SESSION_F_IS_VEP_SESSION;
Florin Coras1bcad5c2019-01-09 20:04:38 -08002983
Florin Corasf1ddeeb2021-06-10 08:08:53 -07002984 if (vcl_session_is_open (s))
2985 {
2986 txf = vcl_session_is_ct (s) ? s->ct_tx_fifo : s->tx_fifo;
2987 if (txf)
2988 svm_fifo_del_want_deq_ntf (txf, SVM_FIFO_WANT_DEQ_NOTIF_IF_FULL);
2989 }
Florin Coras1bcad5c2019-01-09 20:04:38 -08002990
Florin Coras5e062572019-03-14 19:07:51 -07002991 VDBG (1, "EPOLL_CTL_DEL: vep_idx %u, sh %u!", vep_handle,
Florin Corasa7a1a222018-12-30 17:11:31 -08002992 session_handle);
Florin Coras17ec5772020-08-12 20:46:29 -07002993 vcl_evt (VCL_EVT_EPOLL_CTLDEL, s, vep_sh);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002994 break;
2995
2996 default:
Florin Corasa7a1a222018-12-30 17:11:31 -08002997 VDBG (0, "Invalid operation (%d)!", op);
Dave Wallacef7f809c2017-10-03 01:48:42 -04002998 rv = VPPCOM_EINVAL;
2999 }
3000
Florin Coras134a9962018-08-28 11:32:04 -07003001 vep_verify_epoll_chain (wrk, vep_handle);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003002
3003done:
Dave Wallacef7f809c2017-10-03 01:48:42 -04003004 return rv;
3005}
3006
Florin Coras86f04502018-09-12 16:08:01 -07003007static inline void
3008vcl_epoll_wait_handle_mq_event (vcl_worker_t * wrk, session_event_t * e,
3009 struct epoll_event *events, u32 * num_ev)
Florin Coras54693d22018-07-17 10:46:29 -07003010{
3011 session_disconnected_msg_t *disconnected_msg;
3012 session_connected_msg_t *connected_msg;
Florin Coras99368312018-08-02 10:45:44 -07003013 u32 sid = ~0, session_events;
Florin Coras3c7d4f92018-12-14 11:28:43 -08003014 u64 session_evt_data = ~0;
Florin Corasb242d312020-10-26 15:35:40 -07003015 vcl_session_t *s;
Florin Coras86f04502018-09-12 16:08:01 -07003016 u8 add_event = 0;
3017
3018 switch (e->event_type)
3019 {
Florin Coras653e43f2019-03-04 10:56:23 -08003020 case SESSION_IO_EVT_RX:
Florin Corasc0737e92019-03-04 14:19:39 -08003021 sid = e->session_index;
Florin Corasb242d312020-10-26 15:35:40 -07003022 s = vcl_session_get (wrk, sid);
3023 if (vcl_session_is_closed (s))
Florin Corasfa915f82018-12-26 16:29:06 -08003024 break;
Florin Corasb242d312020-10-26 15:35:40 -07003025 vcl_fifo_rx_evt_valid_or_break (s);
3026 session_events = s->vep.ev.events;
Florin Coras99e41452021-08-31 13:29:41 -07003027 if (!(EPOLLIN & s->vep.ev.events) ||
3028 (s->flags & VCL_SESSION_F_HAS_RX_EVT) ||
3029 (s->vep.lt_next != VCL_INVALID_SESSION_INDEX))
Florin Coras86f04502018-09-12 16:08:01 -07003030 break;
3031 add_event = 1;
wanghanlin9e42cc22021-06-25 17:40:13 +08003032 events[*num_ev].events = EPOLLIN;
Florin Corasb242d312020-10-26 15:35:40 -07003033 session_evt_data = s->vep.ev.data.u64;
3034 s->flags |= VCL_SESSION_F_HAS_RX_EVT;
Florin Coras86f04502018-09-12 16:08:01 -07003035 break;
Florin Coras653e43f2019-03-04 10:56:23 -08003036 case SESSION_IO_EVT_TX:
Florin Corasc0737e92019-03-04 14:19:39 -08003037 sid = e->session_index;
Florin Corasb242d312020-10-26 15:35:40 -07003038 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;
Florin Coras86f04502018-09-12 16:08:01 -07003042 if (!(EPOLLOUT & session_events))
3043 break;
3044 add_event = 1;
wanghanlin9e42cc22021-06-25 17:40:13 +08003045 events[*num_ev].events = EPOLLOUT;
Florin Corasb242d312020-10-26 15:35:40 -07003046 session_evt_data = s->vep.ev.data.u64;
3047 svm_fifo_reset_has_deq_ntf (vcl_session_is_ct (s) ?
3048 s->ct_tx_fifo : s->tx_fifo);
Florin Coras86f04502018-09-12 16:08:01 -07003049 break;
Florin Coras86f04502018-09-12 16:08:01 -07003050 case SESSION_CTRL_EVT_ACCEPTED:
Florin Corasb242d312020-10-26 15:35:40 -07003051 if (!e->postponed)
3052 s = vcl_session_accepted (wrk, (session_accepted_msg_t *) e->data);
3053 else
3054 s = vcl_session_get (wrk, e->session_index);
3055 if (!s)
Florin Coras3c7d4f92018-12-14 11:28:43 -08003056 break;
Florin Corasb242d312020-10-26 15:35:40 -07003057 session_events = s->vep.ev.events;
3058 sid = s->session_index;
liuyacancba87102021-09-10 15:14:05 +08003059 if (!(EPOLLIN & session_events) ||
3060 (s->vep.lt_next != VCL_INVALID_SESSION_INDEX))
Florin Coras86f04502018-09-12 16:08:01 -07003061 break;
Florin Coras86f04502018-09-12 16:08:01 -07003062 add_event = 1;
wanghanlin9e42cc22021-06-25 17:40:13 +08003063 events[*num_ev].events = EPOLLIN;
Florin Corasb242d312020-10-26 15:35:40 -07003064 session_evt_data = s->vep.ev.data.u64;
Florin Coras86f04502018-09-12 16:08:01 -07003065 break;
3066 case SESSION_CTRL_EVT_CONNECTED:
Florin Corasb242d312020-10-26 15:35:40 -07003067 if (!e->postponed)
3068 {
3069 connected_msg = (session_connected_msg_t *) e->data;
3070 sid = vcl_session_connected_handler (wrk, connected_msg);
3071 }
3072 else
3073 sid = e->session_index;
3074 s = vcl_session_get (wrk, sid);
3075 if (vcl_session_is_closed (s))
Florin Corasfa915f82018-12-26 16:29:06 -08003076 break;
Florin Corasb242d312020-10-26 15:35:40 -07003077 session_events = s->vep.ev.events;
3078 /* Generate EPOLLOUT because there's no connected event */
Florin Coras72f77822019-01-22 19:05:52 -08003079 if (!(EPOLLOUT & session_events))
3080 break;
3081 add_event = 1;
wanghanlin9e42cc22021-06-25 17:40:13 +08003082 events[*num_ev].events = EPOLLOUT;
Florin Corasb242d312020-10-26 15:35:40 -07003083 session_evt_data = s->vep.ev.data.u64;
3084 if (s->session_state == VCL_STATE_DETACHED)
Florin Corasdbc9c592019-09-25 16:37:43 -07003085 events[*num_ev].events |= EPOLLHUP;
Florin Coras86f04502018-09-12 16:08:01 -07003086 break;
3087 case SESSION_CTRL_EVT_DISCONNECTED:
Florin Coras87f76002021-06-28 19:13:29 -07003088 if (!e->postponed)
3089 {
3090 disconnected_msg = (session_disconnected_msg_t *) e->data;
3091 s = vcl_session_disconnected_handler (wrk, disconnected_msg);
3092 }
3093 else
3094 {
3095 s = vcl_session_get (wrk, e->session_index);
3096 }
3097 if (vcl_session_is_closed (s) ||
3098 !(s->flags & VCL_SESSION_F_IS_VEP_SESSION))
Florin Coras86f04502018-09-12 16:08:01 -07003099 break;
Florin Corasb242d312020-10-26 15:35:40 -07003100 sid = s->session_index;
3101 session_events = s->vep.ev.events;
Florin Coras86f04502018-09-12 16:08:01 -07003102 add_event = 1;
liuyacanffd9ddb2021-11-01 10:22:09 +08003103 if (EPOLLRDHUP & session_events)
3104 {
3105 /* If app can distinguish between RDHUP and HUP,
3106 * we make finer control */
3107 events[*num_ev].events = EPOLLRDHUP;
3108 if (s->flags & VCL_SESSION_F_WR_SHUTDOWN)
3109 {
3110 events[*num_ev].events |= EPOLLHUP;
3111 }
3112 }
3113 else
3114 {
3115 events[*num_ev].events = EPOLLHUP;
3116 }
Florin Corasb242d312020-10-26 15:35:40 -07003117 session_evt_data = s->vep.ev.data.u64;
liuyacanffd9ddb2021-11-01 10:22:09 +08003118
Florin Coras86f04502018-09-12 16:08:01 -07003119 break;
3120 case SESSION_CTRL_EVT_RESET:
Florin Coras87f76002021-06-28 19:13:29 -07003121 if (!e->postponed)
3122 sid = vcl_session_reset_handler (wrk, (session_reset_msg_t *) e->data);
3123 else
3124 sid = e->session_index;
Florin Corasb242d312020-10-26 15:35:40 -07003125 s = vcl_session_get (wrk, sid);
Florin Coras87f76002021-06-28 19:13:29 -07003126 if (vcl_session_is_closed (s) ||
3127 !(s->flags & VCL_SESSION_F_IS_VEP_SESSION))
Florin Coras86f04502018-09-12 16:08:01 -07003128 break;
Florin Corasb242d312020-10-26 15:35:40 -07003129 session_events = s->vep.ev.events;
Florin Coras86f04502018-09-12 16:08:01 -07003130 add_event = 1;
wanghanlin9e42cc22021-06-25 17:40:13 +08003131 events[*num_ev].events = EPOLLHUP | EPOLLRDHUP;
Florin Corasb242d312020-10-26 15:35:40 -07003132 session_evt_data = s->vep.ev.data.u64;
Florin Coras86f04502018-09-12 16:08:01 -07003133 break;
Florin Corasdfae9f92019-02-20 19:48:31 -08003134 case SESSION_CTRL_EVT_UNLISTEN_REPLY:
3135 vcl_session_unlisten_reply_handler (wrk, e->data);
3136 break;
Florin Coras68b7e582020-01-21 18:33:23 -08003137 case SESSION_CTRL_EVT_MIGRATED:
3138 vcl_session_migrated_handler (wrk, e->data);
3139 break;
Florin Coras9ace36d2019-10-28 13:14:17 -07003140 case SESSION_CTRL_EVT_CLEANUP:
3141 vcl_session_cleanup_handler (wrk, e->data);
3142 break;
Florin Coras30e79c22019-01-02 19:31:22 -08003143 case SESSION_CTRL_EVT_REQ_WORKER_UPDATE:
3144 vcl_session_req_worker_update_handler (wrk, e->data);
3145 break;
3146 case SESSION_CTRL_EVT_WORKER_UPDATE_REPLY:
3147 vcl_session_worker_update_reply_handler (wrk, e->data);
3148 break;
Florin Corasc4c4cf52019-08-24 18:17:34 -07003149 case SESSION_CTRL_EVT_APP_ADD_SEGMENT:
3150 vcl_session_app_add_segment_handler (wrk, e->data);
3151 break;
3152 case SESSION_CTRL_EVT_APP_DEL_SEGMENT:
3153 vcl_session_app_del_segment_handler (wrk, e->data);
3154 break;
hanlina3a48962020-07-13 11:09:15 +08003155 case SESSION_CTRL_EVT_APP_WRK_RPC:
Florin Coras40c07ce2020-07-16 20:46:17 -07003156 vcl_worker_rpc_handler (wrk, e->data);
3157 break;
Florin Coras86f04502018-09-12 16:08:01 -07003158 default:
3159 VDBG (0, "unhandled: %u", e->event_type);
3160 break;
3161 }
3162
3163 if (add_event)
3164 {
3165 events[*num_ev].data.u64 = session_evt_data;
3166 if (EPOLLONESHOT & session_events)
3167 {
Florin Corasb242d312020-10-26 15:35:40 -07003168 s = vcl_session_get (wrk, sid);
3169 s->vep.ev.events = 0;
Florin Coras86f04502018-09-12 16:08:01 -07003170 }
Florin Corasfa3884f2021-06-22 20:04:46 -07003171 else if (!(EPOLLET & session_events))
Florin Corasfe286f72021-06-04 10:07:55 -07003172 {
Florin Corasfa3884f2021-06-22 20:04:46 -07003173 s = vcl_session_get (wrk, sid);
3174 if (s->vep.lt_next == VCL_INVALID_SESSION_INDEX)
3175 vcl_epoll_lt_add (wrk, s);
Florin Corasfe286f72021-06-04 10:07:55 -07003176 }
Florin Coras86f04502018-09-12 16:08:01 -07003177 *num_ev += 1;
3178 }
3179}
3180
3181static int
3182vcl_epoll_wait_handle_mq (vcl_worker_t * wrk, svm_msg_q_t * mq,
3183 struct epoll_event *events, u32 maxevents,
3184 double wait_for_time, u32 * num_ev)
3185{
Florin Coras99368312018-08-02 10:45:44 -07003186 svm_msg_q_msg_t *msg;
Florin Coras54693d22018-07-17 10:46:29 -07003187 session_event_t *e;
Florin Coras54693d22018-07-17 10:46:29 -07003188 int i;
3189
Florin Coras539663c2018-09-28 14:59:37 -07003190 if (vec_len (wrk->mq_msg_vector) && svm_msg_q_is_empty (mq))
3191 goto handle_dequeued;
3192
Florin Coras54693d22018-07-17 10:46:29 -07003193 if (svm_msg_q_is_empty (mq))
3194 {
3195 if (!wait_for_time)
Florin Coras5398dfb2021-01-25 20:31:27 -08003196 return 0;
Florin Coras54693d22018-07-17 10:46:29 -07003197 else if (wait_for_time < 0)
Florin Coras5398dfb2021-01-25 20:31:27 -08003198 svm_msg_q_wait (mq, SVM_MQ_WAIT_EMPTY);
Florin Coras54693d22018-07-17 10:46:29 -07003199 else
3200 {
Florin Coras60f1fc12018-08-16 14:57:31 -07003201 if (svm_msg_q_timedwait (mq, wait_for_time / 1e3))
Florin Coras5398dfb2021-01-25 20:31:27 -08003202 return 0;
Florin Coras54693d22018-07-17 10:46:29 -07003203 }
3204 }
Florin Corase003a1b2019-06-05 10:47:16 -07003205 ASSERT (maxevents > *num_ev);
hanlind0e646f2020-05-11 22:20:37 +08003206 vcl_mq_dequeue_batch (wrk, mq, ~0);
Florin Coras54693d22018-07-17 10:46:29 -07003207
Florin Coras539663c2018-09-28 14:59:37 -07003208handle_dequeued:
Florin Coras134a9962018-08-28 11:32:04 -07003209 for (i = 0; i < vec_len (wrk->mq_msg_vector); i++)
Florin Coras54693d22018-07-17 10:46:29 -07003210 {
Florin Coras134a9962018-08-28 11:32:04 -07003211 msg = vec_elt_at_index (wrk->mq_msg_vector, i);
Florin Coras99368312018-08-02 10:45:44 -07003212 e = svm_msg_q_msg_data (mq, msg);
hanlind0e646f2020-05-11 22:20:37 +08003213 if (*num_ev < maxevents)
3214 vcl_epoll_wait_handle_mq_event (wrk, e, events, num_ev);
3215 else
3216 vcl_handle_mq_event (wrk, e);
Florin Coras99368312018-08-02 10:45:44 -07003217 svm_msg_q_free_msg (mq, msg);
Florin Coras54693d22018-07-17 10:46:29 -07003218 }
Florin Corasaa27eb92018-10-13 12:20:01 -07003219 vec_reset_length (wrk->mq_msg_vector);
Florin Coras30e79c22019-01-02 19:31:22 -08003220 vcl_handle_pending_wrk_updates (wrk);
Florin Coras54693d22018-07-17 10:46:29 -07003221 return *num_ev;
3222}
3223
Florin Coras99368312018-08-02 10:45:44 -07003224static int
Florin Corasccdb8b82021-04-28 13:01:06 -07003225vppcom_epoll_wait_condvar (vcl_worker_t *wrk, struct epoll_event *events,
3226 int maxevents, u32 n_evts, double timeout_ms)
Florin Coras99368312018-08-02 10:45:44 -07003227{
Florin Corasccdb8b82021-04-28 13:01:06 -07003228 double end = -1;
Florin Coras14ed6df2019-03-06 21:13:42 -08003229
3230 if (!n_evts)
3231 {
Florin Corasccdb8b82021-04-28 13:01:06 -07003232 if (timeout_ms > 0)
3233 end = clib_time_now (&wrk->clib_time) + (timeout_ms / 1e3);
Florin Coras14ed6df2019-03-06 21:13:42 -08003234 }
3235
3236 do
3237 {
3238 vcl_epoll_wait_handle_mq (wrk, wrk->app_event_queue, events, maxevents,
Florin Corasccdb8b82021-04-28 13:01:06 -07003239 timeout_ms, &n_evts);
3240 if (n_evts || !timeout_ms)
Florin Coras14ed6df2019-03-06 21:13:42 -08003241 return n_evts;
Florin Coras14ed6df2019-03-06 21:13:42 -08003242 }
Florin Corasccdb8b82021-04-28 13:01:06 -07003243 while (end == -1 || clib_time_now (&wrk->clib_time) < end);
Florin Coras14ed6df2019-03-06 21:13:42 -08003244
3245 return 0;
Florin Coras99368312018-08-02 10:45:44 -07003246}
3247
3248static int
Florin Corasccdb8b82021-04-28 13:01:06 -07003249vppcom_epoll_wait_eventfd (vcl_worker_t *wrk, struct epoll_event *events,
3250 int maxevents, u32 n_evts, double timeout_ms)
Florin Coras99368312018-08-02 10:45:44 -07003251{
Florin Coras99368312018-08-02 10:45:44 -07003252 int __clib_unused n_read;
Florin Corasb13ba132021-01-27 16:05:24 -08003253 vcl_mq_evt_conn_t *mqc;
Florin Coras99368312018-08-02 10:45:44 -07003254 int n_mq_evts, i;
Florin Corasccdb8b82021-04-28 13:01:06 -07003255 double end = -1;
Florin Coras99368312018-08-02 10:45:44 -07003256 u64 buf;
3257
Florin Coras134a9962018-08-28 11:32:04 -07003258 vec_validate (wrk->mq_events, pool_elts (wrk->mq_evt_conns));
Florin Corasb13ba132021-01-27 16:05:24 -08003259 if (!n_evts)
Florin Coras99368312018-08-02 10:45:44 -07003260 {
Florin Corasccdb8b82021-04-28 13:01:06 -07003261 if (timeout_ms > 0)
3262 end = clib_time_now (&wrk->clib_time) + (timeout_ms / 1e3);
Florin Coras99368312018-08-02 10:45:44 -07003263 }
3264
Florin Corasb13ba132021-01-27 16:05:24 -08003265 do
3266 {
3267 n_mq_evts = epoll_wait (wrk->mqs_epfd, wrk->mq_events,
Florin Corasccdb8b82021-04-28 13:01:06 -07003268 vec_len (wrk->mq_events), timeout_ms);
Florin Corasb13ba132021-01-27 16:05:24 -08003269 if (n_mq_evts < 0)
3270 {
3271 VDBG (0, "epoll_wait error %u", errno);
3272 return n_evts;
3273 }
3274
3275 for (i = 0; i < n_mq_evts; i++)
3276 {
3277 mqc = vcl_mq_evt_conn_get (wrk, wrk->mq_events[i].data.u32);
3278 n_read = read (mqc->mq_fd, &buf, sizeof (buf));
3279 vcl_epoll_wait_handle_mq (wrk, mqc->mq, events, maxevents, 0,
3280 &n_evts);
3281 }
3282
Florin Corasccdb8b82021-04-28 13:01:06 -07003283 if (n_evts || !timeout_ms)
Florin Corasb13ba132021-01-27 16:05:24 -08003284 return n_evts;
Florin Corasb13ba132021-01-27 16:05:24 -08003285 }
Florin Corasccdb8b82021-04-28 13:01:06 -07003286 while (end == -1 || clib_time_now (&wrk->clib_time) < end);
Florin Corasb13ba132021-01-27 16:05:24 -08003287
3288 return 0;
Florin Coras99368312018-08-02 10:45:44 -07003289}
3290
Florin Corasfe286f72021-06-04 10:07:55 -07003291static void
Florin Corasfe286f72021-06-04 10:07:55 -07003292vcl_epoll_wait_handle_lt (vcl_worker_t *wrk, struct epoll_event *events,
3293 int maxevents, u32 *n_evts)
3294{
Florin Coras734268f2021-06-30 07:54:29 -07003295 u32 add_event = 0, next;
Florin Corasfe286f72021-06-04 10:07:55 -07003296 vcl_session_t *s;
3297 u64 evt_data;
Florin Corasfa3884f2021-06-22 20:04:46 -07003298 int rv;
Florin Corasfe286f72021-06-04 10:07:55 -07003299
Florin Corasfa3884f2021-06-22 20:04:46 -07003300 ASSERT (wrk->ep_lt_current != VCL_INVALID_SESSION_INDEX);
Florin Corasfe286f72021-06-04 10:07:55 -07003301 if (*n_evts >= maxevents)
Florin Corasfa3884f2021-06-22 20:04:46 -07003302 return;
Florin Corasfe286f72021-06-04 10:07:55 -07003303
Florin Corasfa3884f2021-06-22 20:04:46 -07003304 next = wrk->ep_lt_current;
3305 do
Florin Corasfe286f72021-06-04 10:07:55 -07003306 {
Florin Corasfa3884f2021-06-22 20:04:46 -07003307 s = vcl_session_get (wrk, next);
3308 next = s->vep.lt_next;
3309
3310 if ((s->vep.ev.events & EPOLLIN) && (rv = vcl_session_read_ready (s)))
Florin Corasfe286f72021-06-04 10:07:55 -07003311 {
3312 add_event = 1;
Florin Corasfa3884f2021-06-22 20:04:46 -07003313 events[*n_evts].events |= rv > 0 ? EPOLLIN : EPOLLHUP | EPOLLRDHUP;
Florin Corasfe286f72021-06-04 10:07:55 -07003314 evt_data = s->vep.ev.data.u64;
3315 }
Florin Corasfa3884f2021-06-22 20:04:46 -07003316 if ((s->vep.ev.events & EPOLLOUT) && (rv = vcl_session_write_ready (s)))
Florin Corasfe286f72021-06-04 10:07:55 -07003317 {
3318 add_event = 1;
Florin Corasfa3884f2021-06-22 20:04:46 -07003319 events[*n_evts].events |= rv > 0 ? EPOLLOUT : EPOLLHUP | EPOLLRDHUP;
3320 evt_data = s->vep.ev.data.u64;
3321 }
3322 if (!add_event && s->session_state > VCL_STATE_READY)
3323 {
3324 add_event = 1;
3325 events[*n_evts].events |= EPOLLHUP | EPOLLRDHUP;
Florin Corasfe286f72021-06-04 10:07:55 -07003326 evt_data = s->vep.ev.data.u64;
3327 }
3328 if (add_event)
3329 {
3330 events[*n_evts].data.u64 = evt_data;
3331 *n_evts += 1;
3332 add_event = 0;
Florin Corasfa3884f2021-06-22 20:04:46 -07003333 if (EPOLLONESHOT & s->vep.ev.events)
3334 s->vep.ev.events = 0;
Florin Corasfe286f72021-06-04 10:07:55 -07003335 if (*n_evts == maxevents)
3336 {
Florin Corasfa3884f2021-06-22 20:04:46 -07003337 wrk->ep_lt_current = next;
Florin Corasfe286f72021-06-04 10:07:55 -07003338 break;
3339 }
3340 }
Florin Corasfa3884f2021-06-22 20:04:46 -07003341 else
3342 {
3343 vcl_epoll_lt_del (wrk, s);
3344 if (wrk->ep_lt_current == VCL_INVALID_SESSION_INDEX)
3345 break;
3346 }
Florin Corasfe286f72021-06-04 10:07:55 -07003347 }
Florin Corasfa3884f2021-06-22 20:04:46 -07003348 while (next != wrk->ep_lt_current);
Florin Corasfe286f72021-06-04 10:07:55 -07003349}
3350
Dave Wallacef7f809c2017-10-03 01:48:42 -04003351int
Florin Coras134a9962018-08-28 11:32:04 -07003352vppcom_epoll_wait (uint32_t vep_handle, struct epoll_event *events,
Dave Wallacef7f809c2017-10-03 01:48:42 -04003353 int maxevents, double wait_for_time)
3354{
Florin Coras134a9962018-08-28 11:32:04 -07003355 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras7e12d942018-06-27 14:32:43 -07003356 vcl_session_t *vep_session;
Florin Corasfa3884f2021-06-22 20:04:46 -07003357 u32 n_evts = 0;
Florin Coras86f04502018-09-12 16:08:01 -07003358 int i;
Dave Wallacef7f809c2017-10-03 01:48:42 -04003359
3360 if (PREDICT_FALSE (maxevents <= 0))
3361 {
Florin Coras5e062572019-03-14 19:07:51 -07003362 VDBG (0, "ERROR: Invalid maxevents (%d)!", maxevents);
Dave Wallacef7f809c2017-10-03 01:48:42 -04003363 return VPPCOM_EINVAL;
3364 }
Dave Wallacef7f809c2017-10-03 01:48:42 -04003365
Florin Coras134a9962018-08-28 11:32:04 -07003366 vep_session = vcl_session_get_w_handle (wrk, vep_handle);
Florin Coras14598772018-09-04 19:47:52 -07003367 if (!vep_session)
3368 return VPPCOM_EBADFD;
3369
Florin Coras6c3b2182020-10-19 18:36:48 -07003370 if (PREDICT_FALSE (!(vep_session->flags & VCL_SESSION_F_IS_VEP)))
Dave Wallacef7f809c2017-10-03 01:48:42 -04003371 {
Florin Coras5e062572019-03-14 19:07:51 -07003372 VDBG (0, "ERROR: vep_idx (%u) is not a vep!", vep_handle);
Florin Coras54693d22018-07-17 10:46:29 -07003373 return VPPCOM_EINVAL;
Dave Wallacef7f809c2017-10-03 01:48:42 -04003374 }
Florin Coras54693d22018-07-17 10:46:29 -07003375
Florin Coras86f04502018-09-12 16:08:01 -07003376 if (vec_len (wrk->unhandled_evts_vector))
3377 {
3378 for (i = 0; i < vec_len (wrk->unhandled_evts_vector); i++)
3379 {
3380 vcl_epoll_wait_handle_mq_event (wrk, &wrk->unhandled_evts_vector[i],
3381 events, &n_evts);
3382 if (n_evts == maxevents)
3383 {
Florin Corase003a1b2019-06-05 10:47:16 -07003384 vec_delete (wrk->unhandled_evts_vector, i + 1, 0);
3385 return n_evts;
Florin Coras86f04502018-09-12 16:08:01 -07003386 }
3387 }
Florin Corase003a1b2019-06-05 10:47:16 -07003388 vec_reset_length (wrk->unhandled_evts_vector);
Florin Coras86f04502018-09-12 16:08:01 -07003389 }
liuyacancba87102021-09-10 15:14:05 +08003390
3391 if (PREDICT_FALSE (wrk->ep_lt_current != VCL_INVALID_SESSION_INDEX))
3392 vcl_epoll_wait_handle_lt (wrk, events, maxevents, &n_evts);
3393
wanghanlin8919fec2021-03-18 20:00:41 +08003394 /* Request to only drain unhandled */
3395 if ((int) wait_for_time == -2)
3396 return n_evts;
Florin Coras86f04502018-09-12 16:08:01 -07003397
Florin Coras86f04502018-09-12 16:08:01 -07003398
Florin Corasfe286f72021-06-04 10:07:55 -07003399 if (vcm->cfg.use_mq_eventfd)
3400 n_evts = vppcom_epoll_wait_eventfd (wrk, events, maxevents, n_evts,
3401 wait_for_time);
3402 else
3403 n_evts = vppcom_epoll_wait_condvar (wrk, events, maxevents, n_evts,
3404 wait_for_time);
3405
Florin Corasfe286f72021-06-04 10:07:55 -07003406 return n_evts;
Dave Wallacef7f809c2017-10-03 01:48:42 -04003407}
3408
Dave Wallace35830af2017-10-09 01:43:42 -04003409int
Florin Coras134a9962018-08-28 11:32:04 -07003410vppcom_session_attr (uint32_t session_handle, uint32_t op,
Dave Wallace35830af2017-10-09 01:43:42 -04003411 void *buffer, uint32_t * buflen)
3412{
Florin Coras134a9962018-08-28 11:32:04 -07003413 vcl_worker_t *wrk = vcl_worker_get_current ();
liuyacan55c952e2021-06-13 14:54:55 +08003414 u32 *flags = buffer;
Steven2199aab2017-10-15 20:18:47 -07003415 vppcom_endpt_t *ep = buffer;
Florin Coras04ae8272021-04-12 19:55:37 -07003416 transport_endpt_attr_t tea;
Florin Corasa5a9efd2021-01-05 17:03:29 -08003417 vcl_session_t *session;
3418 int rv = VPPCOM_OK;
Dave Wallace35830af2017-10-09 01:43:42 -04003419
Florin Coras134a9962018-08-28 11:32:04 -07003420 session = vcl_session_get_w_handle (wrk, session_handle);
Florin Coras070453d2018-08-24 17:04:27 -07003421 if (!session)
3422 return VPPCOM_EBADFD;
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003423
Dave Wallace35830af2017-10-09 01:43:42 -04003424 switch (op)
3425 {
3426 case VPPCOM_ATTR_GET_NREAD:
Florin Coras0ef8ef22019-01-18 08:37:13 -08003427 rv = vcl_session_read_ready (session);
Florin Coras5e062572019-03-14 19:07:51 -07003428 VDBG (2, "VPPCOM_ATTR_GET_NREAD: sh %u, nread = %d", session_handle,
3429 rv);
Dave Wallace35830af2017-10-09 01:43:42 -04003430 break;
3431
Dave Wallace227867f2017-11-13 21:21:53 -05003432 case VPPCOM_ATTR_GET_NWRITE:
Florin Coras0ef8ef22019-01-18 08:37:13 -08003433 rv = vcl_session_write_ready (session);
Florin Coras5e062572019-03-14 19:07:51 -07003434 VDBG (2, "VPPCOM_ATTR_GET_NWRITE: sh %u, nwrite = %d", session_handle,
3435 rv);
Dave Wallace35830af2017-10-09 01:43:42 -04003436 break;
3437
3438 case VPPCOM_ATTR_GET_FLAGS:
Dave Wallace048b1d62018-01-03 22:24:41 -05003439 if (PREDICT_TRUE (buffer && buflen && (*buflen >= sizeof (*flags))))
Dave Wallace35830af2017-10-09 01:43:42 -04003440 {
Simon Zhang53ec9672020-08-07 05:20:47 +08003441 *flags =
3442 O_RDWR |
Florin Corasac422d62020-10-19 20:51:36 -07003443 (vcl_session_has_attr (session, VCL_SESS_ATTR_NONBLOCK) ?
Simon Zhang53ec9672020-08-07 05:20:47 +08003444 O_NONBLOCK : 0);
Dave Wallace35830af2017-10-09 01:43:42 -04003445 *buflen = sizeof (*flags);
Florin Coras5e062572019-03-14 19:07:51 -07003446 VDBG (2, "VPPCOM_ATTR_GET_FLAGS: sh %u, flags = 0x%08x, "
3447 "is_nonblocking = %u", session_handle, *flags,
Florin Corasac422d62020-10-19 20:51:36 -07003448 vcl_session_has_attr (session, VCL_SESS_ATTR_NONBLOCK));
Dave Wallace35830af2017-10-09 01:43:42 -04003449 }
3450 else
3451 rv = VPPCOM_EINVAL;
3452 break;
3453
3454 case VPPCOM_ATTR_SET_FLAGS:
Dave Wallace048b1d62018-01-03 22:24:41 -05003455 if (PREDICT_TRUE (buffer && buflen && (*buflen == sizeof (*flags))))
Dave Wallace35830af2017-10-09 01:43:42 -04003456 {
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003457 if (*flags & O_NONBLOCK)
Florin Corasac422d62020-10-19 20:51:36 -07003458 vcl_session_set_attr (session, VCL_SESS_ATTR_NONBLOCK);
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003459 else
Florin Corasac422d62020-10-19 20:51:36 -07003460 vcl_session_clear_attr (session, VCL_SESS_ATTR_NONBLOCK);
Keith Burns (alagalah)9b793772018-02-16 08:20:56 -08003461
Florin Coras5e062572019-03-14 19:07:51 -07003462 VDBG (2, "VPPCOM_ATTR_SET_FLAGS: sh %u, flags = 0x%08x,"
3463 " is_nonblocking = %u", session_handle, *flags,
Florin Corasac422d62020-10-19 20:51:36 -07003464 vcl_session_has_attr (session, VCL_SESS_ATTR_NONBLOCK));
Dave Wallace35830af2017-10-09 01:43:42 -04003465 }
3466 else
3467 rv = VPPCOM_EINVAL;
3468 break;
3469
3470 case VPPCOM_ATTR_GET_PEER_ADDR:
Dave Wallace048b1d62018-01-03 22:24:41 -05003471 if (PREDICT_TRUE (buffer && buflen &&
3472 (*buflen >= sizeof (*ep)) && ep->ip))
Dave Wallace35830af2017-10-09 01:43:42 -04003473 {
Florin Coras7e12d942018-06-27 14:32:43 -07003474 ep->is_ip4 = session->transport.is_ip4;
3475 ep->port = session->transport.rmt_port;
3476 if (session->transport.is_ip4)
Dave Barach178cf492018-11-13 16:34:13 -05003477 clib_memcpy_fast (ep->ip, &session->transport.rmt_ip.ip4,
3478 sizeof (ip4_address_t));
Steven2199aab2017-10-15 20:18:47 -07003479 else
Dave Barach178cf492018-11-13 16:34:13 -05003480 clib_memcpy_fast (ep->ip, &session->transport.rmt_ip.ip6,
3481 sizeof (ip6_address_t));
Steven2199aab2017-10-15 20:18:47 -07003482 *buflen = sizeof (*ep);
Florin Coras5e062572019-03-14 19:07:51 -07003483 VDBG (1, "VPPCOM_ATTR_GET_PEER_ADDR: sh %u, is_ip4 = %u, "
3484 "addr = %U, port %u", session_handle, ep->is_ip4,
3485 format_ip46_address, &session->transport.rmt_ip,
Florin Coras0d427d82018-06-27 03:24:07 -07003486 ep->is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6,
3487 clib_net_to_host_u16 (ep->port));
Dave Wallace35830af2017-10-09 01:43:42 -04003488 }
3489 else
3490 rv = VPPCOM_EINVAL;
3491 break;
3492
3493 case VPPCOM_ATTR_GET_LCL_ADDR:
Dave Wallace048b1d62018-01-03 22:24:41 -05003494 if (PREDICT_TRUE (buffer && buflen &&
3495 (*buflen >= sizeof (*ep)) && ep->ip))
Dave Wallace35830af2017-10-09 01:43:42 -04003496 {
Florin Coras7e12d942018-06-27 14:32:43 -07003497 ep->is_ip4 = session->transport.is_ip4;
3498 ep->port = session->transport.lcl_port;
3499 if (session->transport.is_ip4)
Dave Barach178cf492018-11-13 16:34:13 -05003500 clib_memcpy_fast (ep->ip, &session->transport.lcl_ip.ip4,
3501 sizeof (ip4_address_t));
Steven2199aab2017-10-15 20:18:47 -07003502 else
Dave Barach178cf492018-11-13 16:34:13 -05003503 clib_memcpy_fast (ep->ip, &session->transport.lcl_ip.ip6,
3504 sizeof (ip6_address_t));
Steven2199aab2017-10-15 20:18:47 -07003505 *buflen = sizeof (*ep);
Florin Coras5e062572019-03-14 19:07:51 -07003506 VDBG (1, "VPPCOM_ATTR_GET_LCL_ADDR: sh %u, is_ip4 = %u, addr = %U"
3507 " port %d", session_handle, ep->is_ip4, format_ip46_address,
Florin Coras7e12d942018-06-27 14:32:43 -07003508 &session->transport.lcl_ip,
Florin Coras0d427d82018-06-27 03:24:07 -07003509 ep->is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6,
3510 clib_net_to_host_u16 (ep->port));
Dave Wallace35830af2017-10-09 01:43:42 -04003511 }
3512 else
3513 rv = VPPCOM_EINVAL;
3514 break;
Stevenb5a11602017-10-11 09:59:30 -07003515
Florin Corasef7cbf62019-10-17 09:56:27 -07003516 case VPPCOM_ATTR_SET_LCL_ADDR:
3517 if (PREDICT_TRUE (buffer && buflen &&
3518 (*buflen >= sizeof (*ep)) && ep->ip))
3519 {
3520 session->transport.is_ip4 = ep->is_ip4;
3521 session->transport.lcl_port = ep->port;
3522 vcl_ip_copy_from_ep (&session->transport.lcl_ip, ep);
3523 *buflen = sizeof (*ep);
3524 VDBG (1, "VPPCOM_ATTR_SET_LCL_ADDR: sh %u, is_ip4 = %u, addr = %U"
3525 " port %d", session_handle, ep->is_ip4, format_ip46_address,
3526 &session->transport.lcl_ip,
3527 ep->is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6,
3528 clib_net_to_host_u16 (ep->port));
3529 }
3530 else
3531 rv = VPPCOM_EINVAL;
3532 break;
3533
Dave Wallace048b1d62018-01-03 22:24:41 -05003534 case VPPCOM_ATTR_GET_LIBC_EPFD:
3535 rv = session->libc_epfd;
Florin Coras5e062572019-03-14 19:07:51 -07003536 VDBG (2, "VPPCOM_ATTR_GET_LIBC_EPFD: libc_epfd %d", rv);
Dave Wallace048b1d62018-01-03 22:24:41 -05003537 break;
3538
3539 case VPPCOM_ATTR_SET_LIBC_EPFD:
3540 if (PREDICT_TRUE (buffer && buflen &&
3541 (*buflen == sizeof (session->libc_epfd))))
3542 {
3543 session->libc_epfd = *(int *) buffer;
3544 *buflen = sizeof (session->libc_epfd);
3545
Florin Coras5e062572019-03-14 19:07:51 -07003546 VDBG (2, "VPPCOM_ATTR_SET_LIBC_EPFD: libc_epfd %d, buflen %d",
3547 session->libc_epfd, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003548 }
3549 else
3550 rv = VPPCOM_EINVAL;
3551 break;
3552
3553 case VPPCOM_ATTR_GET_PROTOCOL:
3554 if (buffer && buflen && (*buflen >= sizeof (int)))
3555 {
Florin Coras7e12d942018-06-27 14:32:43 -07003556 *(int *) buffer = session->session_type;
Dave Wallace048b1d62018-01-03 22:24:41 -05003557 *buflen = sizeof (int);
3558
Florin Coras5e062572019-03-14 19:07:51 -07003559 VDBG (2, "VPPCOM_ATTR_GET_PROTOCOL: %d (%s), buflen %d",
3560 *(int *) buffer, *(int *) buffer ? "UDP" : "TCP", *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003561 }
3562 else
3563 rv = VPPCOM_EINVAL;
3564 break;
3565
3566 case VPPCOM_ATTR_GET_LISTEN:
3567 if (buffer && buflen && (*buflen >= sizeof (int)))
3568 {
Florin Corasac422d62020-10-19 20:51:36 -07003569 *(int *) buffer = vcl_session_has_attr (session,
3570 VCL_SESS_ATTR_LISTEN);
Dave Wallace048b1d62018-01-03 22:24:41 -05003571 *buflen = sizeof (int);
3572
Florin Coras5e062572019-03-14 19:07:51 -07003573 VDBG (2, "VPPCOM_ATTR_GET_LISTEN: %d, buflen %d", *(int *) buffer,
3574 *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003575 }
3576 else
3577 rv = VPPCOM_EINVAL;
3578 break;
3579
3580 case VPPCOM_ATTR_GET_ERROR:
3581 if (buffer && buflen && (*buflen >= sizeof (int)))
3582 {
3583 *(int *) buffer = 0;
3584 *buflen = sizeof (int);
3585
Florin Coras5e062572019-03-14 19:07:51 -07003586 VDBG (2, "VPPCOM_ATTR_GET_ERROR: %d, buflen %d, #VPP-TBD#",
3587 *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003588 }
3589 else
3590 rv = VPPCOM_EINVAL;
3591 break;
3592
3593 case VPPCOM_ATTR_GET_TX_FIFO_LEN:
3594 if (buffer && buflen && (*buflen >= sizeof (u32)))
3595 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003596
3597 /* VPP-TBD */
3598 *(size_t *) buffer = (session->sndbuf_size ? session->sndbuf_size :
Florin Corasf22f4e52019-12-19 16:10:58 -08003599 session->tx_fifo ?
3600 svm_fifo_size (session->tx_fifo) :
Dave Wallace048b1d62018-01-03 22:24:41 -05003601 vcm->cfg.tx_fifo_size);
3602 *buflen = sizeof (u32);
3603
Florin Coras5e062572019-03-14 19:07:51 -07003604 VDBG (2, "VPPCOM_ATTR_GET_TX_FIFO_LEN: %u (0x%x), buflen %d,"
3605 " #VPP-TBD#", *(size_t *) buffer, *(size_t *) buffer,
3606 *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003607 }
3608 else
3609 rv = VPPCOM_EINVAL;
3610 break;
3611
Filip Tehlar2f09bfc2021-11-15 10:26:56 +00003612 case VPPCOM_ATTR_SET_DSCP:
3613 if (buffer && buflen && (*buflen >= sizeof (u8)))
3614 {
3615 session->dscp = *(u8 *) buffer;
3616
3617 VDBG (2, "VPPCOM_ATTR_SET_DSCP: %u (0x%x), buflen %d,",
3618 *(u8 *) buffer, *(u8 *) buffer, *buflen);
3619 }
3620 else
3621 rv = VPPCOM_EINVAL;
3622 break;
3623
Dave Wallace048b1d62018-01-03 22:24:41 -05003624 case VPPCOM_ATTR_SET_TX_FIFO_LEN:
3625 if (buffer && buflen && (*buflen == sizeof (u32)))
3626 {
3627 /* VPP-TBD */
3628 session->sndbuf_size = *(u32 *) buffer;
Florin Coras5e062572019-03-14 19:07:51 -07003629 VDBG (2, "VPPCOM_ATTR_SET_TX_FIFO_LEN: %u (0x%x), buflen %d,"
3630 " #VPP-TBD#", session->sndbuf_size, session->sndbuf_size,
3631 *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003632 }
3633 else
3634 rv = VPPCOM_EINVAL;
3635 break;
3636
3637 case VPPCOM_ATTR_GET_RX_FIFO_LEN:
3638 if (buffer && buflen && (*buflen >= sizeof (u32)))
3639 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003640
3641 /* VPP-TBD */
3642 *(size_t *) buffer = (session->rcvbuf_size ? session->rcvbuf_size :
Florin Corasf22f4e52019-12-19 16:10:58 -08003643 session->rx_fifo ?
3644 svm_fifo_size (session->rx_fifo) :
Dave Wallace048b1d62018-01-03 22:24:41 -05003645 vcm->cfg.rx_fifo_size);
3646 *buflen = sizeof (u32);
3647
Florin Coras5e062572019-03-14 19:07:51 -07003648 VDBG (2, "VPPCOM_ATTR_GET_RX_FIFO_LEN: %u (0x%x), buflen %d, "
3649 "#VPP-TBD#", *(size_t *) buffer, *(size_t *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003650 }
3651 else
3652 rv = VPPCOM_EINVAL;
3653 break;
3654
3655 case VPPCOM_ATTR_SET_RX_FIFO_LEN:
3656 if (buffer && buflen && (*buflen == sizeof (u32)))
3657 {
3658 /* VPP-TBD */
3659 session->rcvbuf_size = *(u32 *) buffer;
Florin Coras5e062572019-03-14 19:07:51 -07003660 VDBG (2, "VPPCOM_ATTR_SET_RX_FIFO_LEN: %u (0x%x), buflen %d,"
3661 " #VPP-TBD#", session->sndbuf_size, session->sndbuf_size,
3662 *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003663 }
3664 else
3665 rv = VPPCOM_EINVAL;
3666 break;
3667
3668 case VPPCOM_ATTR_GET_REUSEADDR:
3669 if (buffer && buflen && (*buflen >= sizeof (int)))
3670 {
3671 /* VPP-TBD */
Florin Corasac422d62020-10-19 20:51:36 -07003672 *(int *) buffer = vcl_session_has_attr (session,
3673 VCL_SESS_ATTR_REUSEADDR);
Dave Wallace048b1d62018-01-03 22:24:41 -05003674 *buflen = sizeof (int);
3675
Florin Coras5e062572019-03-14 19:07:51 -07003676 VDBG (2, "VPPCOM_ATTR_GET_REUSEADDR: %d, buflen %d, #VPP-TBD#",
3677 *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003678 }
3679 else
3680 rv = VPPCOM_EINVAL;
3681 break;
3682
Stevenb5a11602017-10-11 09:59:30 -07003683 case VPPCOM_ATTR_SET_REUSEADDR:
Dave Wallace048b1d62018-01-03 22:24:41 -05003684 if (buffer && buflen && (*buflen == sizeof (int)) &&
Florin Corasac422d62020-10-19 20:51:36 -07003685 !vcl_session_has_attr (session, VCL_SESS_ATTR_LISTEN))
Dave Wallace048b1d62018-01-03 22:24:41 -05003686 {
3687 /* VPP-TBD */
3688 if (*(int *) buffer)
Florin Corasac422d62020-10-19 20:51:36 -07003689 vcl_session_set_attr (session, VCL_SESS_ATTR_REUSEADDR);
Dave Wallace048b1d62018-01-03 22:24:41 -05003690 else
Florin Corasac422d62020-10-19 20:51:36 -07003691 vcl_session_clear_attr (session, VCL_SESS_ATTR_REUSEADDR);
Dave Wallace048b1d62018-01-03 22:24:41 -05003692
Florin Coras5e062572019-03-14 19:07:51 -07003693 VDBG (2, "VPPCOM_ATTR_SET_REUSEADDR: %d, buflen %d, #VPP-TBD#",
Florin Corasac422d62020-10-19 20:51:36 -07003694 vcl_session_has_attr (session, VCL_SESS_ATTR_REUSEADDR),
Florin Coras5e062572019-03-14 19:07:51 -07003695 *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003696 }
3697 else
3698 rv = VPPCOM_EINVAL;
3699 break;
3700
3701 case VPPCOM_ATTR_GET_REUSEPORT:
3702 if (buffer && buflen && (*buflen >= sizeof (int)))
3703 {
3704 /* VPP-TBD */
Florin Corasac422d62020-10-19 20:51:36 -07003705 *(int *) buffer = vcl_session_has_attr (session,
3706 VCL_SESS_ATTR_REUSEPORT);
Dave Wallace048b1d62018-01-03 22:24:41 -05003707 *buflen = sizeof (int);
3708
Florin Coras5e062572019-03-14 19:07:51 -07003709 VDBG (2, "VPPCOM_ATTR_GET_REUSEPORT: %d, buflen %d, #VPP-TBD#",
3710 *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003711 }
3712 else
3713 rv = VPPCOM_EINVAL;
3714 break;
3715
3716 case VPPCOM_ATTR_SET_REUSEPORT:
3717 if (buffer && buflen && (*buflen == sizeof (int)) &&
Florin Corasac422d62020-10-19 20:51:36 -07003718 !vcl_session_has_attr (session, VCL_SESS_ATTR_LISTEN))
Dave Wallace048b1d62018-01-03 22:24:41 -05003719 {
3720 /* VPP-TBD */
3721 if (*(int *) buffer)
Florin Corasac422d62020-10-19 20:51:36 -07003722 vcl_session_set_attr (session, VCL_SESS_ATTR_REUSEPORT);
Dave Wallace048b1d62018-01-03 22:24:41 -05003723 else
Florin Corasac422d62020-10-19 20:51:36 -07003724 vcl_session_clear_attr (session, VCL_SESS_ATTR_REUSEPORT);
Dave Wallace048b1d62018-01-03 22:24:41 -05003725
Florin Coras5e062572019-03-14 19:07:51 -07003726 VDBG (2, "VPPCOM_ATTR_SET_REUSEPORT: %d, buflen %d, #VPP-TBD#",
Florin Corasac422d62020-10-19 20:51:36 -07003727 vcl_session_has_attr (session, VCL_SESS_ATTR_REUSEPORT),
Florin Coras5e062572019-03-14 19:07:51 -07003728 *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003729 }
3730 else
3731 rv = VPPCOM_EINVAL;
3732 break;
3733
3734 case VPPCOM_ATTR_GET_BROADCAST:
3735 if (buffer && buflen && (*buflen >= sizeof (int)))
3736 {
3737 /* VPP-TBD */
Florin Corasac422d62020-10-19 20:51:36 -07003738 *(int *) buffer = vcl_session_has_attr (session,
3739 VCL_SESS_ATTR_BROADCAST);
Dave Wallace048b1d62018-01-03 22:24:41 -05003740 *buflen = sizeof (int);
3741
Florin Coras5e062572019-03-14 19:07:51 -07003742 VDBG (2, "VPPCOM_ATTR_GET_BROADCAST: %d, buflen %d, #VPP-TBD#",
3743 *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003744 }
3745 else
3746 rv = VPPCOM_EINVAL;
Stevenb5a11602017-10-11 09:59:30 -07003747 break;
3748
3749 case VPPCOM_ATTR_SET_BROADCAST:
Dave Wallace048b1d62018-01-03 22:24:41 -05003750 if (buffer && buflen && (*buflen == sizeof (int)))
3751 {
3752 /* VPP-TBD */
3753 if (*(int *) buffer)
Florin Corasac422d62020-10-19 20:51:36 -07003754 vcl_session_set_attr (session, VCL_SESS_ATTR_BROADCAST);
Dave Wallace048b1d62018-01-03 22:24:41 -05003755 else
Florin Corasac422d62020-10-19 20:51:36 -07003756 vcl_session_clear_attr (session, VCL_SESS_ATTR_BROADCAST);
Dave Wallace048b1d62018-01-03 22:24:41 -05003757
Florin Coras5e062572019-03-14 19:07:51 -07003758 VDBG (2, "VPPCOM_ATTR_SET_BROADCAST: %d, buflen %d, #VPP-TBD#",
Florin Corasac422d62020-10-19 20:51:36 -07003759 vcl_session_has_attr (session, VCL_SESS_ATTR_BROADCAST),
Florin Coras5e062572019-03-14 19:07:51 -07003760 *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003761 }
3762 else
3763 rv = VPPCOM_EINVAL;
3764 break;
3765
3766 case VPPCOM_ATTR_GET_V6ONLY:
3767 if (buffer && buflen && (*buflen >= sizeof (int)))
3768 {
3769 /* VPP-TBD */
Florin Corasac422d62020-10-19 20:51:36 -07003770 *(int *) buffer = vcl_session_has_attr (session,
3771 VCL_SESS_ATTR_V6ONLY);
Dave Wallace048b1d62018-01-03 22:24:41 -05003772 *buflen = sizeof (int);
3773
Florin Coras5e062572019-03-14 19:07:51 -07003774 VDBG (2, "VPPCOM_ATTR_GET_V6ONLY: %d, buflen %d, #VPP-TBD#",
3775 *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003776 }
3777 else
3778 rv = VPPCOM_EINVAL;
Stevenb5a11602017-10-11 09:59:30 -07003779 break;
3780
3781 case VPPCOM_ATTR_SET_V6ONLY:
Dave Wallace048b1d62018-01-03 22:24:41 -05003782 if (buffer && buflen && (*buflen == sizeof (int)))
3783 {
3784 /* VPP-TBD */
3785 if (*(int *) buffer)
Florin Corasac422d62020-10-19 20:51:36 -07003786 vcl_session_set_attr (session, VCL_SESS_ATTR_V6ONLY);
Dave Wallace048b1d62018-01-03 22:24:41 -05003787 else
Florin Corasac422d62020-10-19 20:51:36 -07003788 vcl_session_clear_attr (session, VCL_SESS_ATTR_V6ONLY);
Dave Wallace048b1d62018-01-03 22:24:41 -05003789
Florin Coras5e062572019-03-14 19:07:51 -07003790 VDBG (2, "VPPCOM_ATTR_SET_V6ONLY: %d, buflen %d, #VPP-TBD#",
Florin Corasac422d62020-10-19 20:51:36 -07003791 vcl_session_has_attr (session, VCL_SESS_ATTR_V6ONLY),
Florin Coras5e062572019-03-14 19:07:51 -07003792 *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003793 }
3794 else
3795 rv = VPPCOM_EINVAL;
3796 break;
3797
3798 case VPPCOM_ATTR_GET_KEEPALIVE:
3799 if (buffer && buflen && (*buflen >= sizeof (int)))
3800 {
3801 /* VPP-TBD */
Florin Corasac422d62020-10-19 20:51:36 -07003802 *(int *) buffer = vcl_session_has_attr (session,
3803 VCL_SESS_ATTR_KEEPALIVE);
Dave Wallace048b1d62018-01-03 22:24:41 -05003804 *buflen = sizeof (int);
3805
Florin Coras5e062572019-03-14 19:07:51 -07003806 VDBG (2, "VPPCOM_ATTR_GET_KEEPALIVE: %d, buflen %d, #VPP-TBD#",
3807 *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003808 }
3809 else
3810 rv = VPPCOM_EINVAL;
Stevenb5a11602017-10-11 09:59:30 -07003811 break;
Stevenbccd3392017-10-12 20:42:21 -07003812
3813 case VPPCOM_ATTR_SET_KEEPALIVE:
Dave Wallace048b1d62018-01-03 22:24:41 -05003814 if (buffer && buflen && (*buflen == sizeof (int)))
3815 {
3816 /* VPP-TBD */
3817 if (*(int *) buffer)
Florin Corasac422d62020-10-19 20:51:36 -07003818 vcl_session_set_attr (session, VCL_SESS_ATTR_KEEPALIVE);
Dave Wallace048b1d62018-01-03 22:24:41 -05003819 else
Florin Corasac422d62020-10-19 20:51:36 -07003820 vcl_session_clear_attr (session, VCL_SESS_ATTR_KEEPALIVE);
Dave Wallace048b1d62018-01-03 22:24:41 -05003821
Florin Coras5e062572019-03-14 19:07:51 -07003822 VDBG (2, "VPPCOM_ATTR_SET_KEEPALIVE: %d, buflen %d, #VPP-TBD#",
Florin Corasac422d62020-10-19 20:51:36 -07003823 vcl_session_has_attr (session, VCL_SESS_ATTR_KEEPALIVE),
Florin Coras5e062572019-03-14 19:07:51 -07003824 *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003825 }
3826 else
3827 rv = VPPCOM_EINVAL;
3828 break;
3829
3830 case VPPCOM_ATTR_GET_TCP_NODELAY:
3831 if (buffer && buflen && (*buflen >= sizeof (int)))
3832 {
3833 /* VPP-TBD */
Florin Corasac422d62020-10-19 20:51:36 -07003834 *(int *) buffer = vcl_session_has_attr (session,
3835 VCL_SESS_ATTR_TCP_NODELAY);
Dave Wallace048b1d62018-01-03 22:24:41 -05003836 *buflen = sizeof (int);
3837
Florin Coras5e062572019-03-14 19:07:51 -07003838 VDBG (2, "VPPCOM_ATTR_GET_TCP_NODELAY: %d, buflen %d, #VPP-TBD#",
3839 *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003840 }
3841 else
3842 rv = VPPCOM_EINVAL;
3843 break;
3844
3845 case VPPCOM_ATTR_SET_TCP_NODELAY:
3846 if (buffer && buflen && (*buflen == sizeof (int)))
3847 {
3848 /* VPP-TBD */
3849 if (*(int *) buffer)
Florin Corasac422d62020-10-19 20:51:36 -07003850 vcl_session_set_attr (session, VCL_SESS_ATTR_TCP_NODELAY);
Dave Wallace048b1d62018-01-03 22:24:41 -05003851 else
Florin Corasac422d62020-10-19 20:51:36 -07003852 vcl_session_clear_attr (session, VCL_SESS_ATTR_TCP_NODELAY);
Dave Wallace048b1d62018-01-03 22:24:41 -05003853
Florin Coras5e062572019-03-14 19:07:51 -07003854 VDBG (2, "VPPCOM_ATTR_SET_TCP_NODELAY: %d, buflen %d, #VPP-TBD#",
Florin Corasac422d62020-10-19 20:51:36 -07003855 vcl_session_has_attr (session, VCL_SESS_ATTR_TCP_NODELAY),
Florin Coras5e062572019-03-14 19:07:51 -07003856 *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003857 }
3858 else
3859 rv = VPPCOM_EINVAL;
3860 break;
3861
3862 case VPPCOM_ATTR_GET_TCP_KEEPIDLE:
3863 if (buffer && buflen && (*buflen >= sizeof (int)))
3864 {
3865 /* VPP-TBD */
Florin Corasac422d62020-10-19 20:51:36 -07003866 *(int *) buffer = vcl_session_has_attr (session,
3867 VCL_SESS_ATTR_TCP_KEEPIDLE);
Dave Wallace048b1d62018-01-03 22:24:41 -05003868 *buflen = sizeof (int);
3869
Florin Coras5e062572019-03-14 19:07:51 -07003870 VDBG (2, "VPPCOM_ATTR_GET_TCP_KEEPIDLE: %d, buflen %d, #VPP-TBD#",
3871 *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003872 }
3873 else
3874 rv = VPPCOM_EINVAL;
Stevenbccd3392017-10-12 20:42:21 -07003875 break;
3876
3877 case VPPCOM_ATTR_SET_TCP_KEEPIDLE:
Dave Wallace048b1d62018-01-03 22:24:41 -05003878 if (buffer && buflen && (*buflen == sizeof (int)))
3879 {
3880 /* VPP-TBD */
3881 if (*(int *) buffer)
Florin Corasac422d62020-10-19 20:51:36 -07003882 vcl_session_set_attr (session, VCL_SESS_ATTR_TCP_KEEPIDLE);
Dave Wallace048b1d62018-01-03 22:24:41 -05003883 else
Florin Corasac422d62020-10-19 20:51:36 -07003884 vcl_session_clear_attr (session, VCL_SESS_ATTR_TCP_KEEPIDLE);
Dave Wallace048b1d62018-01-03 22:24:41 -05003885
Florin Coras5e062572019-03-14 19:07:51 -07003886 VDBG (2, "VPPCOM_ATTR_SET_TCP_KEEPIDLE: %d, buflen %d, #VPP-TBD#",
Florin Corasac422d62020-10-19 20:51:36 -07003887 vcl_session_has_attr (session,
3888 VCL_SESS_ATTR_TCP_KEEPIDLE), *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003889 }
3890 else
3891 rv = VPPCOM_EINVAL;
3892 break;
3893
3894 case VPPCOM_ATTR_GET_TCP_KEEPINTVL:
3895 if (buffer && buflen && (*buflen >= sizeof (int)))
3896 {
3897 /* VPP-TBD */
Florin Corasac422d62020-10-19 20:51:36 -07003898 *(int *) buffer = vcl_session_has_attr (session,
3899 VCL_SESS_ATTR_TCP_KEEPINTVL);
Dave Wallace048b1d62018-01-03 22:24:41 -05003900 *buflen = sizeof (int);
3901
Florin Coras5e062572019-03-14 19:07:51 -07003902 VDBG (2, "VPPCOM_ATTR_GET_TCP_KEEPINTVL: %d, buflen %d, #VPP-TBD#",
3903 *(int *) buffer, *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003904 }
3905 else
3906 rv = VPPCOM_EINVAL;
Stevenbccd3392017-10-12 20:42:21 -07003907 break;
3908
3909 case VPPCOM_ATTR_SET_TCP_KEEPINTVL:
Dave Wallace048b1d62018-01-03 22:24:41 -05003910 if (buffer && buflen && (*buflen == sizeof (int)))
3911 {
3912 /* VPP-TBD */
3913 if (*(int *) buffer)
Florin Corasac422d62020-10-19 20:51:36 -07003914 vcl_session_set_attr (session, VCL_SESS_ATTR_TCP_KEEPINTVL);
Dave Wallace048b1d62018-01-03 22:24:41 -05003915 else
Florin Corasac422d62020-10-19 20:51:36 -07003916 vcl_session_clear_attr (session, VCL_SESS_ATTR_TCP_KEEPINTVL);
Dave Wallace048b1d62018-01-03 22:24:41 -05003917
Florin Coras5e062572019-03-14 19:07:51 -07003918 VDBG (2, "VPPCOM_ATTR_SET_TCP_KEEPINTVL: %d, buflen %d, #VPP-TBD#",
Florin Corasac422d62020-10-19 20:51:36 -07003919 vcl_session_has_attr (session,
3920 VCL_SESS_ATTR_TCP_KEEPINTVL), *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003921 }
3922 else
3923 rv = VPPCOM_EINVAL;
3924 break;
3925
3926 case VPPCOM_ATTR_GET_TCP_USER_MSS:
Florin Coras04ae8272021-04-12 19:55:37 -07003927 if (!(buffer && buflen && (*buflen >= sizeof (u32))))
Dave Wallace048b1d62018-01-03 22:24:41 -05003928 {
Florin Coras04ae8272021-04-12 19:55:37 -07003929 rv = VPPCOM_EINVAL;
3930 break;
Dave Wallace048b1d62018-01-03 22:24:41 -05003931 }
Florin Coras04ae8272021-04-12 19:55:37 -07003932
3933 tea.type = TRANSPORT_ENDPT_ATTR_MSS;
3934 tea.mss = *(u32 *) buffer;
3935 if (vcl_session_transport_attr (wrk, session, 1 /* is_get */, &tea))
3936 rv = VPPCOM_ENOPROTOOPT;
3937
3938 if (!rv)
3939 {
3940 *(u32 *) buffer = tea.mss;
3941 *buflen = sizeof (int);
3942 }
3943
3944 VDBG (2, "VPPCOM_ATTR_GET_TCP_USER_MSS: %d, buflen %d", *(int *) buffer,
3945 *buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05003946 break;
3947
3948 case VPPCOM_ATTR_SET_TCP_USER_MSS:
Florin Coras04ae8272021-04-12 19:55:37 -07003949 if (!(buffer && buflen && (*buflen == sizeof (u32))))
Dave Wallace048b1d62018-01-03 22:24:41 -05003950 {
Florin Coras04ae8272021-04-12 19:55:37 -07003951 rv = VPPCOM_EINVAL;
3952 break;
Dave Wallace048b1d62018-01-03 22:24:41 -05003953 }
Florin Coras04ae8272021-04-12 19:55:37 -07003954
3955 tea.type = TRANSPORT_ENDPT_ATTR_MSS;
3956 tea.mss = *(u32 *) buffer;
3957 if (vcl_session_transport_attr (wrk, session, 0 /* is_get */, &tea))
3958 rv = VPPCOM_ENOPROTOOPT;
3959
3960 VDBG (2, "VPPCOM_ATTR_SET_TCP_USER_MSS: %u, buflen %d", tea.mss,
3961 *buflen);
Stevenbccd3392017-10-12 20:42:21 -07003962 break;
Dave Wallacee22aa742017-10-20 12:30:38 -04003963
Florin Coras1e966172020-05-16 18:18:14 +00003964 case VPPCOM_ATTR_SET_CONNECTED:
3965 session->flags |= VCL_SESSION_F_CONNECTED;
3966 break;
3967
Florin Corasa5a9efd2021-01-05 17:03:29 -08003968 case VPPCOM_ATTR_SET_CKPAIR:
3969 if (!(buffer && buflen && (*buflen == sizeof (int))) ||
3970 !vcl_session_has_crypto (session))
3971 {
3972 rv = VPPCOM_EINVAL;
3973 break;
3974 }
Florin Corasa54b62d2021-04-21 09:05:56 -07003975 if (!session->ext_config)
3976 {
Florin Coras87f63892021-05-01 16:01:40 -07003977 vcl_session_alloc_ext_cfg (session, TRANSPORT_ENDPT_EXT_CFG_CRYPTO,
3978 sizeof (transport_endpt_ext_cfg_t));
Florin Corasa54b62d2021-04-21 09:05:56 -07003979 }
3980 else if (session->ext_config->type != TRANSPORT_ENDPT_EXT_CFG_CRYPTO)
3981 {
3982 rv = VPPCOM_EINVAL;
3983 break;
3984 }
3985
3986 session->ext_config->crypto.ckpair_index = *(uint32_t *) buffer;
Florin Corasa5a9efd2021-01-05 17:03:29 -08003987 break;
3988
Florin Coras6a6555a2021-01-28 11:39:27 -08003989 case VPPCOM_ATTR_SET_VRF:
3990 if (!(buffer && buflen && (*buflen == sizeof (u32))))
3991 {
3992 rv = VPPCOM_EINVAL;
3993 break;
3994 }
3995 session->vrf = *(u32 *) buffer;
3996 break;
3997
3998 case VPPCOM_ATTR_GET_VRF:
3999 if (!(buffer && buflen && (*buflen >= sizeof (u32))))
4000 {
4001 rv = VPPCOM_EINVAL;
4002 break;
4003 }
4004 *(u32 *) buffer = session->vrf;
4005 *buflen = sizeof (u32);
4006 break;
4007
wanghanlin0674f852021-02-22 10:38:36 +08004008 case VPPCOM_ATTR_GET_DOMAIN:
Florin Corasd77325c2021-02-23 12:03:03 -08004009 if (!(buffer && buflen && (*buflen >= sizeof (int))))
wanghanlin0674f852021-02-22 10:38:36 +08004010 {
Florin Corasd77325c2021-02-23 12:03:03 -08004011 rv = VPPCOM_EINVAL;
4012 break;
wanghanlin0674f852021-02-22 10:38:36 +08004013 }
Florin Corasd77325c2021-02-23 12:03:03 -08004014
4015 if (session->transport.is_ip4)
4016 *(int *) buffer = AF_INET;
wanghanlin0674f852021-02-22 10:38:36 +08004017 else
Florin Corasd77325c2021-02-23 12:03:03 -08004018 *(int *) buffer = AF_INET6;
4019 *buflen = sizeof (int);
4020
wanghanlin0674f852021-02-22 10:38:36 +08004021 VDBG (2, "VPPCOM_ATTR_GET_DOMAIN: %d, buflen %u", *(int *) buffer,
4022 *buflen);
4023 break;
4024
Florin Coras87f63892021-05-01 16:01:40 -07004025 case VPPCOM_ATTR_SET_ENDPT_EXT_CFG:
4026 if (!(buffer && buflen && (*buflen > 0)))
4027 {
4028 rv = VPPCOM_EINVAL;
4029 break;
4030 }
4031 if (session->ext_config)
4032 {
4033 rv = VPPCOM_EINVAL;
4034 break;
4035 }
4036 vcl_session_alloc_ext_cfg (session, TRANSPORT_ENDPT_EXT_CFG_NONE,
4037 *buflen + sizeof (u32));
4038 clib_memcpy (session->ext_config->data, buffer, *buflen);
4039 session->ext_config->len = *buflen;
4040 break;
4041
Dave Wallacee22aa742017-10-20 12:30:38 -04004042 default:
4043 rv = VPPCOM_EINVAL;
4044 break;
Dave Wallace35830af2017-10-09 01:43:42 -04004045 }
4046
Dave Wallace35830af2017-10-09 01:43:42 -04004047 return rv;
4048}
4049
Stevenac1f96d2017-10-24 16:03:58 -07004050int
Florin Coras134a9962018-08-28 11:32:04 -07004051vppcom_session_recvfrom (uint32_t session_handle, void *buffer,
Stevenac1f96d2017-10-24 16:03:58 -07004052 uint32_t buflen, int flags, vppcom_endpt_t * ep)
4053{
Florin Coras134a9962018-08-28 11:32:04 -07004054 vcl_worker_t *wrk = vcl_worker_get_current ();
Florin Coras5da10c42020-04-01 04:31:21 +00004055 vcl_session_t *session;
Stevenac1f96d2017-10-24 16:03:58 -07004056 int rv = VPPCOM_OK;
Steven58f464e2017-10-25 12:33:12 -07004057
4058 if (flags == 0)
Florin Coras134a9962018-08-28 11:32:04 -07004059 rv = vppcom_session_read (session_handle, buffer, buflen);
Stevenac1f96d2017-10-24 16:03:58 -07004060 else if (flags & MSG_PEEK)
Florin Coras134a9962018-08-28 11:32:04 -07004061 rv = vppcom_session_peek (session_handle, buffer, buflen);
Stevenac1f96d2017-10-24 16:03:58 -07004062 else
4063 {
Florin Corasa7a1a222018-12-30 17:11:31 -08004064 VDBG (0, "Unsupport flags for recvfrom %d", flags);
Florin Coras460dce62018-07-27 05:45:06 -07004065 return VPPCOM_EAFNOSUPPORT;
Stevenac1f96d2017-10-24 16:03:58 -07004066 }
4067
Florin Coras0a1e1832020-03-29 18:54:04 +00004068 if (ep && rv > 0)
Florin Coras99368312018-08-02 10:45:44 -07004069 {
Florin Coras5da10c42020-04-01 04:31:21 +00004070 session = vcl_session_get_w_handle (wrk, session_handle);
Florin Coras99368312018-08-02 10:45:44 -07004071 if (session->transport.is_ip4)
Dave Barach178cf492018-11-13 16:34:13 -05004072 clib_memcpy_fast (ep->ip, &session->transport.rmt_ip.ip4,
4073 sizeof (ip4_address_t));
Florin Coras99368312018-08-02 10:45:44 -07004074 else
Dave Barach178cf492018-11-13 16:34:13 -05004075 clib_memcpy_fast (ep->ip, &session->transport.rmt_ip.ip6,
4076 sizeof (ip6_address_t));
Florin Coras5da10c42020-04-01 04:31:21 +00004077 ep->is_ip4 = session->transport.is_ip4;
4078 ep->port = session->transport.rmt_port;
Florin Coras99368312018-08-02 10:45:44 -07004079 }
Florin Coras460dce62018-07-27 05:45:06 -07004080
Stevenac1f96d2017-10-24 16:03:58 -07004081 return rv;
4082}
4083
4084int
Florin Coras134a9962018-08-28 11:32:04 -07004085vppcom_session_sendto (uint32_t session_handle, void *buffer,
Stevenac1f96d2017-10-24 16:03:58 -07004086 uint32_t buflen, int flags, vppcom_endpt_t * ep)
4087{
Florin Coras7a2abce2020-04-05 19:25:44 +00004088 vcl_worker_t *wrk = vcl_worker_get_current ();
4089 vcl_session_t *s;
4090
4091 s = vcl_session_get_w_handle (wrk, session_handle);
Florin Coras0b0d28e2021-06-04 17:31:53 -07004092 if (PREDICT_FALSE (!s))
Florin Coras7a2abce2020-04-05 19:25:44 +00004093 return VPPCOM_EBADFD;
4094
Dave Wallace617dffa2017-10-26 14:47:06 -04004095 if (ep)
4096 {
Florin Coras5824cc52020-10-20 18:44:41 -07004097 if (!vcl_session_is_cl (s))
Florin Coras5da10c42020-04-01 04:31:21 +00004098 return VPPCOM_EINVAL;
4099
liuyacanbc0c7542021-08-02 20:15:05 +08004100 s->transport.is_ip4 = ep->is_ip4;
4101 s->transport.rmt_port = ep->port;
4102 vcl_ip_copy_from_ep (&s->transport.rmt_ip, ep);
4103
Florin Coras5da10c42020-04-01 04:31:21 +00004104 /* Session not connected/bound in vpp. Create it by 'connecting' it */
Florin Corasc127d5a2020-10-14 16:35:58 -07004105 if (PREDICT_FALSE (s->session_state == VCL_STATE_CLOSED))
Florin Coras5da10c42020-04-01 04:31:21 +00004106 {
Florin Coras5824cc52020-10-20 18:44:41 -07004107 u32 session_index = s->session_index;
4108 f64 timeout = vcm->cfg.session_timeout;
4109 int rv;
4110
Florin Coras5da10c42020-04-01 04:31:21 +00004111 vcl_send_session_connect (wrk, s);
Florin Coras5824cc52020-10-20 18:44:41 -07004112 rv = vppcom_wait_for_session_state_change (session_index,
4113 VCL_STATE_READY,
4114 timeout);
4115 if (rv < 0)
4116 return rv;
4117 s = vcl_session_get (wrk, session_index);
Florin Coras5da10c42020-04-01 04:31:21 +00004118 }
Dave Wallace617dffa2017-10-26 14:47:06 -04004119 }
4120
4121 if (flags)
4122 {
4123 // TBD check the flags and do the right thing
Florin Coras5e062572019-03-14 19:07:51 -07004124 VDBG (2, "handling flags 0x%u (%d) not implemented yet.", flags, flags);
Dave Wallace617dffa2017-10-26 14:47:06 -04004125 }
4126
Florin Coras7a2abce2020-04-05 19:25:44 +00004127 return (vppcom_session_write_inline (wrk, s, buffer, buflen, 1,
4128 s->is_dgram ? 1 : 0));
Stevenac1f96d2017-10-24 16:03:58 -07004129}
4130
Dave Wallace048b1d62018-01-03 22:24:41 -05004131int
4132vppcom_poll (vcl_poll_t * vp, uint32_t n_sids, double wait_for_time)
4133{
Florin Coras134a9962018-08-28 11:32:04 -07004134 vcl_worker_t *wrk = vcl_worker_get_current ();
4135 f64 timeout = clib_time_now (&wrk->clib_time) + wait_for_time;
Dave Wallace048b1d62018-01-03 22:24:41 -05004136 u32 i, keep_trying = 1;
Florin Coras6917b942018-11-13 22:44:54 -08004137 svm_msg_q_msg_t msg;
4138 session_event_t *e;
Dave Wallace048b1d62018-01-03 22:24:41 -05004139 int rv, num_ev = 0;
4140
Florin Coras5e062572019-03-14 19:07:51 -07004141 VDBG (3, "vp %p, nsids %u, wait_for_time %f", vp, n_sids, wait_for_time);
Dave Wallace048b1d62018-01-03 22:24:41 -05004142
4143 if (!vp)
4144 return VPPCOM_EFAULT;
4145
4146 do
4147 {
Florin Coras7e12d942018-06-27 14:32:43 -07004148 vcl_session_t *session;
Dave Wallace048b1d62018-01-03 22:24:41 -05004149
Florin Coras6917b942018-11-13 22:44:54 -08004150 /* Dequeue all events and drop all unhandled io events */
4151 while (svm_msg_q_sub (wrk->app_event_queue, &msg, SVM_Q_NOWAIT, 0) == 0)
4152 {
4153 e = svm_msg_q_msg_data (wrk->app_event_queue, &msg);
4154 vcl_handle_mq_event (wrk, e);
4155 svm_msg_q_free_msg (wrk->app_event_queue, &msg);
4156 }
4157 vec_reset_length (wrk->unhandled_evts_vector);
4158
Dave Wallace048b1d62018-01-03 22:24:41 -05004159 for (i = 0; i < n_sids; i++)
4160 {
Florin Coras7baeb712019-01-04 17:05:43 -08004161 session = vcl_session_get (wrk, vp[i].sh);
Florin Coras070453d2018-08-24 17:04:27 -07004162 if (!session)
Florin Coras6917b942018-11-13 22:44:54 -08004163 {
4164 vp[i].revents = POLLHUP;
4165 num_ev++;
4166 continue;
4167 }
Dave Wallace048b1d62018-01-03 22:24:41 -05004168
Florin Coras6917b942018-11-13 22:44:54 -08004169 vp[i].revents = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -05004170
4171 if (POLLIN & vp[i].events)
4172 {
Florin Coras0ef8ef22019-01-18 08:37:13 -08004173 rv = vcl_session_read_ready (session);
Dave Wallace048b1d62018-01-03 22:24:41 -05004174 if (rv > 0)
4175 {
Florin Coras6917b942018-11-13 22:44:54 -08004176 vp[i].revents |= POLLIN;
Dave Wallace048b1d62018-01-03 22:24:41 -05004177 num_ev++;
4178 }
4179 else if (rv < 0)
4180 {
4181 switch (rv)
4182 {
4183 case VPPCOM_ECONNRESET:
Florin Coras6917b942018-11-13 22:44:54 -08004184 vp[i].revents = POLLHUP;
Dave Wallace048b1d62018-01-03 22:24:41 -05004185 break;
4186
4187 default:
Florin Coras6917b942018-11-13 22:44:54 -08004188 vp[i].revents = POLLERR;
Dave Wallace048b1d62018-01-03 22:24:41 -05004189 break;
4190 }
4191 num_ev++;
4192 }
4193 }
4194
4195 if (POLLOUT & vp[i].events)
4196 {
Florin Coras0ef8ef22019-01-18 08:37:13 -08004197 rv = vcl_session_write_ready (session);
Dave Wallace048b1d62018-01-03 22:24:41 -05004198 if (rv > 0)
4199 {
Florin Coras6917b942018-11-13 22:44:54 -08004200 vp[i].revents |= POLLOUT;
Dave Wallace048b1d62018-01-03 22:24:41 -05004201 num_ev++;
4202 }
4203 else if (rv < 0)
4204 {
4205 switch (rv)
4206 {
4207 case VPPCOM_ECONNRESET:
Florin Coras6917b942018-11-13 22:44:54 -08004208 vp[i].revents = POLLHUP;
Dave Wallace048b1d62018-01-03 22:24:41 -05004209 break;
4210
4211 default:
Florin Coras6917b942018-11-13 22:44:54 -08004212 vp[i].revents = POLLERR;
Dave Wallace048b1d62018-01-03 22:24:41 -05004213 break;
4214 }
4215 num_ev++;
4216 }
4217 }
4218
Dave Wallace7e607a72018-06-18 18:41:32 -04004219 if (0) // Note "done:" label used by VCL_SESSION_LOCK_AND_GET()
Dave Wallace048b1d62018-01-03 22:24:41 -05004220 {
Florin Coras6917b942018-11-13 22:44:54 -08004221 vp[i].revents = POLLNVAL;
Dave Wallace048b1d62018-01-03 22:24:41 -05004222 num_ev++;
4223 }
4224 }
4225 if (wait_for_time != -1)
Florin Coras134a9962018-08-28 11:32:04 -07004226 keep_trying = (clib_time_now (&wrk->clib_time) <= timeout) ? 1 : 0;
Dave Wallace048b1d62018-01-03 22:24:41 -05004227 }
4228 while ((num_ev == 0) && keep_trying);
4229
Dave Wallace048b1d62018-01-03 22:24:41 -05004230 return num_ev;
4231}
4232
Florin Coras99368312018-08-02 10:45:44 -07004233int
4234vppcom_mq_epoll_fd (void)
4235{
Florin Coras134a9962018-08-28 11:32:04 -07004236 vcl_worker_t *wrk = vcl_worker_get_current ();
4237 return wrk->mqs_epfd;
4238}
4239
4240int
Florin Coras30e79c22019-01-02 19:31:22 -08004241vppcom_session_index (vcl_session_handle_t session_handle)
Florin Coras134a9962018-08-28 11:32:04 -07004242{
4243 return session_handle & 0xFFFFFF;
4244}
4245
4246int
Florin Coras30e79c22019-01-02 19:31:22 -08004247vppcom_session_worker (vcl_session_handle_t session_handle)
4248{
4249 return session_handle >> 24;
4250}
4251
4252int
Florin Coras134a9962018-08-28 11:32:04 -07004253vppcom_worker_register (void)
4254{
Florin Coras47c40e22018-11-26 17:01:36 -08004255 if (!vcl_worker_alloc_and_init ())
4256 return VPPCOM_EEXIST;
4257
Florin Coras47c40e22018-11-26 17:01:36 -08004258 if (vcl_worker_register_with_vpp ())
4259 return VPPCOM_EEXIST;
4260
4261 return VPPCOM_OK;
Florin Coras99368312018-08-02 10:45:44 -07004262}
4263
Florin Coras369db832019-07-08 12:34:45 -07004264void
4265vppcom_worker_unregister (void)
4266{
4267 vcl_worker_cleanup (vcl_worker_get_current (), 1 /* notify vpp */ );
4268 vcl_set_worker_index (~0);
4269}
4270
Pivo6017ff02020-05-04 17:57:33 +02004271void
4272vppcom_worker_index_set (int index)
4273{
4274 vcl_set_worker_index (index);
4275}
4276
Florin Corasdfe4cf42018-11-28 22:13:45 -08004277int
4278vppcom_worker_index (void)
4279{
4280 return vcl_get_worker_index ();
4281}
4282
Florin Corase0982e52019-01-25 13:19:56 -08004283int
4284vppcom_worker_mqs_epfd (void)
4285{
4286 vcl_worker_t *wrk = vcl_worker_get_current ();
4287 if (!vcm->cfg.use_mq_eventfd)
4288 return -1;
4289 return wrk->mqs_epfd;
4290}
4291
Nathan Skrzypczak9fd99622019-05-16 14:38:44 +02004292int
4293vppcom_session_is_connectable_listener (uint32_t session_handle)
4294{
4295 vcl_session_t *session;
4296 vcl_worker_t *wrk = vcl_worker_get_current ();
4297 session = vcl_session_get_w_handle (wrk, session_handle);
4298 if (!session)
4299 return VPPCOM_EBADFD;
4300 return vcl_session_is_connectable_listener (wrk, session);
4301}
4302
4303int
4304vppcom_session_listener (uint32_t session_handle)
4305{
4306 vcl_worker_t *wrk = vcl_worker_get_current ();
4307 vcl_session_t *listen_session, *session;
4308 session = vcl_session_get_w_handle (wrk, session_handle);
4309 if (!session)
4310 return VPPCOM_EBADFD;
4311 if (session->listener_index == VCL_INVALID_SESSION_INDEX)
4312 return VPPCOM_EBADFD;
4313 listen_session = vcl_session_get_w_handle (wrk, session->listener_index);
4314 if (!listen_session)
4315 return VPPCOM_EBADFD;
4316 return vcl_session_handle (listen_session);
4317}
4318
4319int
4320vppcom_session_n_accepted (uint32_t session_handle)
4321{
4322 vcl_worker_t *wrk = vcl_worker_get_current ();
4323 vcl_session_t *session = vcl_session_get_w_handle (wrk, session_handle);
4324 if (!session)
4325 return VPPCOM_EBADFD;
4326 return session->n_accepted_sessions;
4327}
4328
Florin Coras66ec4672020-06-15 07:59:40 -07004329const char *
4330vppcom_proto_str (vppcom_proto_t proto)
4331{
4332 char const *proto_str;
4333
4334 switch (proto)
4335 {
4336 case VPPCOM_PROTO_TCP:
4337 proto_str = "TCP";
4338 break;
4339 case VPPCOM_PROTO_UDP:
4340 proto_str = "UDP";
4341 break;
4342 case VPPCOM_PROTO_TLS:
4343 proto_str = "TLS";
4344 break;
4345 case VPPCOM_PROTO_QUIC:
4346 proto_str = "QUIC";
4347 break;
Florin Coras4b47ee22020-11-19 13:38:26 -08004348 case VPPCOM_PROTO_DTLS:
4349 proto_str = "DTLS";
4350 break;
Florin Coras6621abf2021-01-06 17:35:17 -08004351 case VPPCOM_PROTO_SRTP:
4352 proto_str = "SRTP";
4353 break;
Florin Coras66ec4672020-06-15 07:59:40 -07004354 default:
4355 proto_str = "UNKNOWN";
4356 break;
4357 }
4358 return proto_str;
4359}
4360
4361const char *
4362vppcom_retval_str (int retval)
4363{
4364 char const *st;
4365
4366 switch (retval)
4367 {
4368 case VPPCOM_OK:
4369 st = "VPPCOM_OK";
4370 break;
4371
4372 case VPPCOM_EAGAIN:
4373 st = "VPPCOM_EAGAIN";
4374 break;
4375
4376 case VPPCOM_EFAULT:
4377 st = "VPPCOM_EFAULT";
4378 break;
4379
4380 case VPPCOM_ENOMEM:
4381 st = "VPPCOM_ENOMEM";
4382 break;
4383
4384 case VPPCOM_EINVAL:
4385 st = "VPPCOM_EINVAL";
4386 break;
4387
4388 case VPPCOM_EBADFD:
4389 st = "VPPCOM_EBADFD";
4390 break;
4391
4392 case VPPCOM_EAFNOSUPPORT:
4393 st = "VPPCOM_EAFNOSUPPORT";
4394 break;
4395
4396 case VPPCOM_ECONNABORTED:
4397 st = "VPPCOM_ECONNABORTED";
4398 break;
4399
4400 case VPPCOM_ECONNRESET:
4401 st = "VPPCOM_ECONNRESET";
4402 break;
4403
4404 case VPPCOM_ENOTCONN:
4405 st = "VPPCOM_ENOTCONN";
4406 break;
4407
4408 case VPPCOM_ECONNREFUSED:
4409 st = "VPPCOM_ECONNREFUSED";
4410 break;
4411
4412 case VPPCOM_ETIMEDOUT:
4413 st = "VPPCOM_ETIMEDOUT";
4414 break;
4415
4416 default:
4417 st = "UNKNOWN_STATE";
4418 break;
4419 }
4420
4421 return st;
4422}
4423
Florin Corasa5a9efd2021-01-05 17:03:29 -08004424int
4425vppcom_add_cert_key_pair (vppcom_cert_key_pair_t *ckpair)
4426{
4427 if (vcm->cfg.vpp_app_socket_api)
Florin Corase191d762021-08-11 14:55:49 -07004428 return vcl_sapi_add_cert_key_pair (ckpair);
4429 else
4430 return vcl_bapi_add_cert_key_pair (ckpair);
Florin Corasa5a9efd2021-01-05 17:03:29 -08004431}
4432
4433int
4434vppcom_del_cert_key_pair (uint32_t ckpair_index)
4435{
4436 if (vcm->cfg.vpp_app_socket_api)
Florin Corase191d762021-08-11 14:55:49 -07004437 return vcl_sapi_del_cert_key_pair (ckpair_index);
4438 else
4439 return vcl_bapi_del_cert_key_pair (ckpair_index);
Florin Corasa5a9efd2021-01-05 17:03:29 -08004440}
4441
Dave Wallacee22aa742017-10-20 12:30:38 -04004442/*
4443 * fd.io coding-style-patch-verification: ON
4444 *
4445 * Local Variables:
4446 * eval: (c-set-style "gnu")
4447 * End:
4448 */