blob: 453ddeb33409234b563c101c866372c53eee0687 [file] [log] [blame]
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001/*
2 * Copyright (c) 2016 Cisco and/or its affiliates.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
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#include <unistd.h>
16#include <stdio.h>
17#include <signal.h>
18#include <dlfcn.h>
19#include <pthread.h>
20#include <time.h>
21#include <stdarg.h>
shrinivasan ganapathy1d359632017-10-15 15:46:09 -070022#include <sys/resource.h>
Dave Wallace048b1d62018-01-03 22:24:41 -050023#include <netinet/tcp.h>
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -070024
Dave Wallace2a865272018-02-07 21:00:42 -050025#include <vcl/ldp_socket_wrapper.h>
26#include <vcl/ldp.h>
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -070027#include <sys/time.h>
28
Dave Wallace5c7cf1c2017-10-24 04:12:18 -040029#include <vcl/vppcom.h>
Dave Wallace048b1d62018-01-03 22:24:41 -050030#include <vppinfra/time.h>
31#include <vppinfra/bitmap.h>
Florin Coras30e273b2018-11-27 00:04:59 -080032#include <vppinfra/lock.h>
33#include <vppinfra/pool.h>
34#include <vppinfra/hash.h>
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -070035
36#define HAVE_CONSTRUCTOR_ATTRIBUTE
37#ifdef HAVE_CONSTRUCTOR_ATTRIBUTE
38#define CONSTRUCTOR_ATTRIBUTE \
39 __attribute__ ((constructor))
40#else
41#define CONSTRUCTOR_ATTRIBUTE
42#endif /* HAVE_CONSTRUCTOR_ATTRIBUTE */
43
44#define HAVE_DESTRUCTOR_ATTRIBUTE
45#ifdef HAVE_DESTRUCTOR_ATTRIBUTE
46#define DESTRUCTOR_ATTRIBUTE \
47 __attribute__ ((destructor))
48#else
49#define DESTRUCTOR_ATTRIBUTE
50#endif
51
Florin Corasdfe4cf42018-11-28 22:13:45 -080052#define LDP_MAX_NWORKERS 32
53
Florin Coras30e273b2018-11-27 00:04:59 -080054typedef struct ldp_fd_entry_
55{
Florin Corasdfe4cf42018-11-28 22:13:45 -080056 u32 session_index;
Florin Coras30e273b2018-11-27 00:04:59 -080057 u32 fd;
58 u32 fd_index;
59} ldp_fd_entry_t;
60
Florin Corasdfe4cf42018-11-28 22:13:45 -080061typedef struct ldp_worker_ctx_
Dave Wallace048b1d62018-01-03 22:24:41 -050062{
Dave Wallace048b1d62018-01-03 22:24:41 -050063 u8 *io_buffer;
64 clib_time_t clib_time;
Florin Corasdfe4cf42018-11-28 22:13:45 -080065
66 /*
67 * Select state
68 */
Dave Wallace048b1d62018-01-03 22:24:41 -050069 clib_bitmap_t *rd_bitmap;
70 clib_bitmap_t *wr_bitmap;
71 clib_bitmap_t *ex_bitmap;
72 clib_bitmap_t *sid_rd_bitmap;
73 clib_bitmap_t *sid_wr_bitmap;
74 clib_bitmap_t *sid_ex_bitmap;
75 clib_bitmap_t *libc_rd_bitmap;
76 clib_bitmap_t *libc_wr_bitmap;
77 clib_bitmap_t *libc_ex_bitmap;
Florin Corasdfe4cf42018-11-28 22:13:45 -080078 u8 select_vcl;
79
80 /*
81 * Poll state
82 */
Dave Wallace048b1d62018-01-03 22:24:41 -050083 vcl_poll_t *vcl_poll;
Florin Coras6917b942018-11-13 22:44:54 -080084 struct pollfd *libc_poll;
85 u16 *libc_poll_idxs;
Florin Corasdfe4cf42018-11-28 22:13:45 -080086
87 /*
88 * Epoll state
89 */
Dave Wallace048b1d62018-01-03 22:24:41 -050090 u8 epoll_wait_vcl;
Florin Coras99368312018-08-02 10:45:44 -070091 int vcl_mq_epfd;
Florin Corasdfe4cf42018-11-28 22:13:45 -080092
93} ldp_worker_ctx_t;
94
95typedef struct
96{
97 ldp_worker_ctx_t *workers;
98 int init;
99 char app_name[LDP_APP_NAME_MAX];
100 u32 sid_bit_val;
101 u32 sid_bit_mask;
102 u32 debug;
Florin Coras30e273b2018-11-27 00:04:59 -0800103 ldp_fd_entry_t *fd_pool;
104 clib_rwlock_t fd_table_lock;
Florin Corasdfe4cf42018-11-28 22:13:45 -0800105 uword *session_index_to_fd_table;
106
107 /** vcl needs next epoll_create to go to libc_epoll */
108 u8 vcl_needs_real_epoll;
Dave Wallace2a865272018-02-07 21:00:42 -0500109} ldp_main_t;
Florin Corasdfe4cf42018-11-28 22:13:45 -0800110
Dave Wallace2a865272018-02-07 21:00:42 -0500111#define LDP_DEBUG ldp->debug
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700112
Florin Coras99368312018-08-02 10:45:44 -0700113#define LDBG(_lvl, _fmt, _args...) \
114 if (ldp->debug > _lvl) \
115 clib_warning (_fmt, ##_args)
116
Dave Wallace2a865272018-02-07 21:00:42 -0500117static ldp_main_t ldp_main = {
118 .sid_bit_val = (1 << LDP_SID_BIT_MIN),
119 .sid_bit_mask = (1 << LDP_SID_BIT_MIN) - 1,
120 .debug = LDP_DEBUG_INIT,
Dave Wallace048b1d62018-01-03 22:24:41 -0500121};
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700122
Dave Wallace2a865272018-02-07 21:00:42 -0500123static ldp_main_t *ldp = &ldp_main;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700124
Florin Corasdfe4cf42018-11-28 22:13:45 -0800125static inline ldp_worker_ctx_t *
126ldp_worker_get_current (void)
127{
128 return (ldp->workers + vppcom_worker_index ());
129}
130
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700131/*
132 * RETURN: 0 on success or -1 on error.
133 * */
Dave Wallace048b1d62018-01-03 22:24:41 -0500134static inline void
Dave Wallace2a865272018-02-07 21:00:42 -0500135ldp_set_app_name (char *app_name)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700136{
Dave Wallace2a865272018-02-07 21:00:42 -0500137 int rv = snprintf (ldp->app_name, LDP_APP_NAME_MAX,
138 "ldp-%d-%s", getpid (), app_name);
Dave Wallace048b1d62018-01-03 22:24:41 -0500139
Dave Wallace2a865272018-02-07 21:00:42 -0500140 if (rv >= LDP_APP_NAME_MAX)
141 app_name[LDP_APP_NAME_MAX - 1] = 0;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700142}
143
Dave Wallace048b1d62018-01-03 22:24:41 -0500144static inline char *
Dave Wallace2a865272018-02-07 21:00:42 -0500145ldp_get_app_name ()
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700146{
Dave Wallace2a865272018-02-07 21:00:42 -0500147 if (ldp->app_name[0] == '\0')
148 ldp_set_app_name ("app");
Dave Wallace048b1d62018-01-03 22:24:41 -0500149
Dave Wallace2a865272018-02-07 21:00:42 -0500150 return ldp->app_name;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700151}
152
Florin Coras30e273b2018-11-27 00:04:59 -0800153static int
154ldp_fd_alloc (u32 sid)
155{
156 ldp_fd_entry_t *fde;
157
158 clib_rwlock_writer_lock (&ldp->fd_table_lock);
159 if (pool_elts (ldp->fd_pool) >= (1ULL << 32) - ldp->sid_bit_val)
160 {
161 clib_rwlock_writer_unlock (&ldp->fd_table_lock);
162 return -1;
163 }
164 pool_get (ldp->fd_pool, fde);
Florin Corasdfe4cf42018-11-28 22:13:45 -0800165 fde->session_index = vppcom_session_index (sid);
Florin Coras30e273b2018-11-27 00:04:59 -0800166 fde->fd_index = fde - ldp->fd_pool;
167 fde->fd = fde->fd_index + ldp->sid_bit_val;
Florin Corasdfe4cf42018-11-28 22:13:45 -0800168 hash_set (ldp->session_index_to_fd_table, fde->session_index, fde->fd);
Florin Coras30e273b2018-11-27 00:04:59 -0800169 clib_rwlock_writer_unlock (&ldp->fd_table_lock);
170 return fde->fd;
171}
172
173static ldp_fd_entry_t *
174ldp_fd_entry_get_w_lock (u32 fd_index)
175{
176 clib_rwlock_reader_lock (&ldp->fd_table_lock);
177 if (pool_is_free_index (ldp->fd_pool, fd_index))
178 return 0;
179
180 return pool_elt_at_index (ldp->fd_pool, fd_index);
181}
182
Dave Wallace048b1d62018-01-03 22:24:41 -0500183static inline int
Dave Wallace2a865272018-02-07 21:00:42 -0500184ldp_fd_from_sid (u32 sid)
Dave Wallace048b1d62018-01-03 22:24:41 -0500185{
Florin Coras30e273b2018-11-27 00:04:59 -0800186 uword *fdp;
187 int fd;
188
189 clib_rwlock_reader_lock (&ldp->fd_table_lock);
Florin Corasdfe4cf42018-11-28 22:13:45 -0800190 fdp = hash_get (ldp->session_index_to_fd_table, vppcom_session_index (sid));
Florin Coras30e273b2018-11-27 00:04:59 -0800191 fd = fdp ? *fdp : -EMFILE;
192 clib_rwlock_reader_unlock (&ldp->fd_table_lock);
193
194 return fd;
Dave Wallace048b1d62018-01-03 22:24:41 -0500195}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700196
Dave Wallace048b1d62018-01-03 22:24:41 -0500197static inline int
Dave Wallace2a865272018-02-07 21:00:42 -0500198ldp_fd_is_sid (int fd)
Dave Wallace048b1d62018-01-03 22:24:41 -0500199{
Florin Coras30e273b2018-11-27 00:04:59 -0800200 return fd >= ldp->sid_bit_val;
Dave Wallace048b1d62018-01-03 22:24:41 -0500201}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700202
Dave Wallace048b1d62018-01-03 22:24:41 -0500203static inline u32
Dave Wallace2a865272018-02-07 21:00:42 -0500204ldp_sid_from_fd (int fd)
Dave Wallace048b1d62018-01-03 22:24:41 -0500205{
Florin Corasdfe4cf42018-11-28 22:13:45 -0800206 u32 fd_index, session_index;
Florin Coras30e273b2018-11-27 00:04:59 -0800207 ldp_fd_entry_t *fde;
Florin Coras30e273b2018-11-27 00:04:59 -0800208
209 if (!ldp_fd_is_sid (fd))
210 return INVALID_SESSION_ID;
211
212 fd_index = fd - ldp->sid_bit_val;
213 fde = ldp_fd_entry_get_w_lock (fd_index);
Florin Corasdfe4cf42018-11-28 22:13:45 -0800214 if (!fde)
215 {
216 LDBG (0, "unknown fd %d", fd);
217 clib_rwlock_reader_unlock (&ldp->fd_table_lock);
218 return INVALID_SESSION_ID;
219 }
220 session_index = fde->session_index;
Florin Coras30e273b2018-11-27 00:04:59 -0800221 clib_rwlock_reader_unlock (&ldp->fd_table_lock);
222
Florin Corasdfe4cf42018-11-28 22:13:45 -0800223 return vppcom_session_handle (session_index);
Florin Coras30e273b2018-11-27 00:04:59 -0800224}
225
226static void
227ldp_fd_free_w_sid (u32 sid)
228{
229 ldp_fd_entry_t *fde;
230 u32 fd_index;
231 int fd;
232
233 fd = ldp_fd_from_sid (sid);
234 if (!fd)
235 return;
236
237 fd_index = fd - ldp->sid_bit_val;
238 fde = ldp_fd_entry_get_w_lock (fd_index);
239 if (fde)
240 {
Florin Corasdfe4cf42018-11-28 22:13:45 -0800241 hash_unset (ldp->session_index_to_fd_table, fde->session_index);
Florin Coras30e273b2018-11-27 00:04:59 -0800242 pool_put (ldp->fd_pool, fde);
243 }
244 clib_rwlock_writer_unlock (&ldp->fd_table_lock);
Dave Wallace048b1d62018-01-03 22:24:41 -0500245}
246
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700247static inline int
Dave Wallace2a865272018-02-07 21:00:42 -0500248ldp_init (void)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700249{
Florin Corasdfe4cf42018-11-28 22:13:45 -0800250 ldp_worker_ctx_t *ldpw;
Florin Coras99368312018-08-02 10:45:44 -0700251 int rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700252
Florin Coras99368312018-08-02 10:45:44 -0700253 if (PREDICT_TRUE (ldp->init))
254 return 0;
255
256 ldp->init = 1;
257 ldp->vcl_needs_real_epoll = 1;
258 rv = vppcom_app_create (ldp_get_app_name ());
259 if (rv != VPPCOM_OK)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700260 {
Florin Coras99368312018-08-02 10:45:44 -0700261 fprintf (stderr, "\nLDP<%d>: ERROR: ldp_init: vppcom_app_create()"
262 " failed! rv = %d (%s)\n",
263 getpid (), rv, vppcom_retval_str (rv));
264 ldp->init = 0;
265 return rv;
266 }
267 ldp->vcl_needs_real_epoll = 0;
Florin Corasdfe4cf42018-11-28 22:13:45 -0800268 pool_alloc (ldp->workers, LDP_MAX_NWORKERS);
269 ldpw = ldp_worker_get_current ();
Florin Coras99368312018-08-02 10:45:44 -0700270
271 char *env_var_str = getenv (LDP_ENV_DEBUG);
272 if (env_var_str)
273 {
274 u32 tmp;
275 if (sscanf (env_var_str, "%u", &tmp) != 1)
276 clib_warning ("LDP<%d>: WARNING: Invalid LDP debug level specified in"
277 " the env var " LDP_ENV_DEBUG " (%s)!", getpid (),
278 env_var_str);
279 else
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700280 {
Florin Coras99368312018-08-02 10:45:44 -0700281 ldp->debug = tmp;
282 LDBG (0, "LDP<%d>: configured LDP debug level (%u) from env var "
283 LDP_ENV_DEBUG "!", getpid (), ldp->debug);
284 }
285 }
Dave Wallace048b1d62018-01-03 22:24:41 -0500286
Florin Coras99368312018-08-02 10:45:44 -0700287 env_var_str = getenv (LDP_ENV_APP_NAME);
288 if (env_var_str)
289 {
290 ldp_set_app_name (env_var_str);
291 LDBG (0, "LDP<%d>: configured LDP app name (%s) from the env var "
292 LDP_ENV_APP_NAME "!", getpid (), ldp->app_name);
293 }
Dave Wallace048b1d62018-01-03 22:24:41 -0500294
Florin Coras99368312018-08-02 10:45:44 -0700295 env_var_str = getenv (LDP_ENV_SID_BIT);
296 if (env_var_str)
297 {
298 u32 sb;
299 if (sscanf (env_var_str, "%u", &sb) != 1)
300 {
301 clib_warning ("LDP<%d>: WARNING: Invalid LDP sid bit specified in"
302 " the env var " LDP_ENV_SID_BIT " (%s)! sid bit "
303 "value %d (0x%x)", getpid (), env_var_str,
304 ldp->sid_bit_val, ldp->sid_bit_val);
305 }
306 else if (sb < LDP_SID_BIT_MIN)
307 {
308 ldp->sid_bit_val = (1 << LDP_SID_BIT_MIN);
309 ldp->sid_bit_mask = ldp->sid_bit_val - 1;
Dave Wallace048b1d62018-01-03 22:24:41 -0500310
Florin Coras99368312018-08-02 10:45:44 -0700311 clib_warning ("LDP<%d>: WARNING: LDP sid bit (%u) specified in the"
312 " env var " LDP_ENV_SID_BIT " (%s) is too small. "
313 "Using LDP_SID_BIT_MIN (%d)! sid bit value %d (0x%x)",
314 getpid (), sb, env_var_str, LDP_SID_BIT_MIN,
315 ldp->sid_bit_val, ldp->sid_bit_val);
316 }
317 else if (sb > LDP_SID_BIT_MAX)
318 {
319 ldp->sid_bit_val = (1 << LDP_SID_BIT_MAX);
320 ldp->sid_bit_mask = ldp->sid_bit_val - 1;
Dave Wallace048b1d62018-01-03 22:24:41 -0500321
Florin Coras99368312018-08-02 10:45:44 -0700322 clib_warning ("LDP<%d>: WARNING: LDP sid bit (%u) specified in the"
323 " env var " LDP_ENV_SID_BIT " (%s) is too big. Using"
324 " LDP_SID_BIT_MAX (%d)! sid bit value %d (0x%x)",
325 getpid (), sb, env_var_str, LDP_SID_BIT_MAX,
326 ldp->sid_bit_val, ldp->sid_bit_val);
Dave Wallace048b1d62018-01-03 22:24:41 -0500327 }
328 else
329 {
Florin Coras99368312018-08-02 10:45:44 -0700330 ldp->sid_bit_val = (1 << sb);
331 ldp->sid_bit_mask = ldp->sid_bit_val - 1;
332
333 LDBG (0, "LDP<%d>: configured LDP sid bit (%u) from "
334 LDP_ENV_SID_BIT "! sid bit value %d (0x%x)", getpid (), sb,
335 ldp->sid_bit_val, ldp->sid_bit_val);
Dave Wallace048b1d62018-01-03 22:24:41 -0500336 }
337 }
Florin Coras99368312018-08-02 10:45:44 -0700338
Florin Corasdfe4cf42018-11-28 22:13:45 -0800339 clib_time_init (&ldpw->clib_time);
Florin Coras30e273b2018-11-27 00:04:59 -0800340 clib_rwlock_init (&ldp->fd_table_lock);
Florin Coras99368312018-08-02 10:45:44 -0700341 LDBG (0, "LDP<%d>: LDP initialization: done!", getpid ());
342
343 return 0;
Dave Wallace048b1d62018-01-03 22:24:41 -0500344}
345
346int
347close (int fd)
348{
Florin Coras47c40e22018-11-26 17:01:36 -0800349 int rv, refcnt;
Dave Wallace048b1d62018-01-03 22:24:41 -0500350 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -0500351 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -0500352
Dave Wallace2a865272018-02-07 21:00:42 -0500353 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500354 return -1;
355
356 if (sid != INVALID_SESSION_ID)
357 {
358 int epfd;
359
360 func_str = "vppcom_session_attr[GET_LIBC_EPFD]";
361 epfd = vppcom_session_attr (sid, VPPCOM_ATTR_GET_LIBC_EPFD, 0, 0);
362 if (epfd > 0)
363 {
364 func_str = "libc_close";
365
Florin Coras6917b942018-11-13 22:44:54 -0800366 LDBG (0, "LDP<%d>: fd %d (0x%x): calling %s(): epfd %u (0x%x)",
367 getpid (), fd, fd, func_str, epfd, epfd);
Dave Wallace048b1d62018-01-03 22:24:41 -0500368
369 rv = libc_close (epfd);
370 if (rv < 0)
371 {
372 u32 size = sizeof (epfd);
373 epfd = 0;
374
375 (void) vppcom_session_attr (sid, VPPCOM_ATTR_SET_LIBC_EPFD,
376 &epfd, &size);
377 }
378 }
379 else if (PREDICT_FALSE (epfd < 0))
380 {
381 errno = -epfd;
382 rv = -1;
383 goto done;
384 }
385
386 func_str = "vppcom_session_close";
387
Florin Coras6917b942018-11-13 22:44:54 -0800388 LDBG (0, "LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x)",
389 getpid (), fd, fd, func_str, sid, sid);
Dave Wallace048b1d62018-01-03 22:24:41 -0500390
Florin Coras47c40e22018-11-26 17:01:36 -0800391 refcnt = vppcom_session_attr (sid, VPPCOM_ATTR_GET_REFCNT, 0, 0);
Dave Wallace048b1d62018-01-03 22:24:41 -0500392 rv = vppcom_session_close (sid);
393 if (rv != VPPCOM_OK)
394 {
395 errno = -rv;
396 rv = -1;
397 }
Florin Coras47c40e22018-11-26 17:01:36 -0800398 if (refcnt == 1)
399 ldp_fd_free_w_sid (sid);
Dave Wallace048b1d62018-01-03 22:24:41 -0500400 }
401 else
402 {
403 func_str = "libc_close";
404
Florin Coras6917b942018-11-13 22:44:54 -0800405 LDBG (0, "LDP<%d>: fd %d (0x%x): calling %s()", getpid (), fd, fd,
406 func_str);
Dave Wallace048b1d62018-01-03 22:24:41 -0500407
408 rv = libc_close (fd);
409 }
410
411done:
Dave Wallace2a865272018-02-07 21:00:42 -0500412 if (LDP_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -0500413 {
414 if (rv < 0)
415 {
416 int errno_val = errno;
417 perror (func_str);
418 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
419 "rv %d, errno = %d", getpid (), fd, fd,
420 func_str, rv, errno_val);
421 errno = errno_val;
422 }
423 else
424 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
425 getpid (), fd, fd, rv, rv);
426 }
427 return rv;
428}
429
430ssize_t
431read (int fd, void *buf, size_t nbytes)
432{
433 ssize_t size;
434 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -0500435 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -0500436
Dave Wallace2a865272018-02-07 21:00:42 -0500437 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500438 return -1;
439
440 if (sid != INVALID_SESSION_ID)
441 {
442 func_str = "vppcom_session_read";
443
Dave Wallace2a865272018-02-07 21:00:42 -0500444 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -0500445 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
446 "sid %u (0x%x), buf %p, nbytes %u", getpid (),
447 fd, fd, func_str, sid, sid, buf, nbytes);
448
449 size = vppcom_session_read (sid, buf, nbytes);
450 if (size < 0)
451 {
452 errno = -size;
453 size = -1;
454 }
455 }
456 else
457 {
458 func_str = "libc_read";
459
Dave Wallace2a865272018-02-07 21:00:42 -0500460 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -0500461 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
462 "buf %p, nbytes %u", getpid (),
463 fd, fd, func_str, buf, nbytes);
464
465 size = libc_read (fd, buf, nbytes);
466 }
467
Dave Wallace2a865272018-02-07 21:00:42 -0500468 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -0500469 {
470 if (size < 0)
471 {
472 int errno_val = errno;
473 perror (func_str);
474 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
475 "rv %d, errno = %d", getpid (), fd, fd,
476 func_str, size, errno_val);
477 errno = errno_val;
478 }
479 else
480 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
481 getpid (), fd, fd, size, size);
482 }
483 return size;
484}
485
486ssize_t
487readv (int fd, const struct iovec * iov, int iovcnt)
488{
489 const char *func_str;
490 ssize_t size = 0;
Dave Wallace2a865272018-02-07 21:00:42 -0500491 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace8aaba562018-01-18 17:21:19 -0500492 int rv = 0, i, total = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -0500493
Dave Wallace2a865272018-02-07 21:00:42 -0500494 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500495 return -1;
496
497 if (sid != INVALID_SESSION_ID)
498 {
499 func_str = "vppcom_session_read";
500 do
501 {
502 for (i = 0; i < iovcnt; ++i)
503 {
Dave Wallace2a865272018-02-07 21:00:42 -0500504 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -0500505 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s() [%d]: "
506 "sid %u (0x%x), iov %p, iovcnt %d, total %d",
507 getpid (), fd, fd, func_str, i, sid, sid,
508 iov, iovcnt, total);
509
510 rv = vppcom_session_read (sid, iov[i].iov_base, iov[i].iov_len);
511 if (rv < 0)
512 break;
513 else
514 {
515 total += rv;
516 if (rv < iov[i].iov_len)
517 {
Dave Wallace2a865272018-02-07 21:00:42 -0500518 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -0500519 clib_warning ("LDP<%d>: fd %d (0x%x): "
520 "rv (%d) < iov[%d].iov_len (%d)",
521 getpid (), fd, fd, rv, i,
522 iov[i].iov_len);
523 break;
524 }
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700525 }
526 }
527 }
Dave Wallace048b1d62018-01-03 22:24:41 -0500528 while ((rv >= 0) && (total == 0));
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700529
Dave Wallace048b1d62018-01-03 22:24:41 -0500530 if (rv < 0)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700531 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500532 errno = -rv;
533 size = -1;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700534 }
Dave Wallace048b1d62018-01-03 22:24:41 -0500535 else
536 size = total;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700537 }
538 else
539 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500540 func_str = "libc_readv";
541
Dave Wallace2a865272018-02-07 21:00:42 -0500542 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -0500543 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
544 "iov %p, iovcnt %d", getpid (), fd, fd, iov, iovcnt);
545
546 size = libc_readv (fd, iov, iovcnt);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700547 }
548
Dave Wallace2a865272018-02-07 21:00:42 -0500549 if (LDP_DEBUG > 2)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700550 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500551 if (size < 0)
552 {
553 int errno_val = errno;
554 perror (func_str);
555 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
556 "rv %d, errno = %d", getpid (), fd, fd,
557 func_str, size, errno_val);
558 errno = errno_val;
559 }
560 else
561 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
562 getpid (), fd, fd, size, size);
563 }
564 return size;
565}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700566
Dave Wallace048b1d62018-01-03 22:24:41 -0500567ssize_t
568write (int fd, const void *buf, size_t nbytes)
569{
570 const char *func_str;
571 ssize_t size = 0;
Dave Wallace2a865272018-02-07 21:00:42 -0500572 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -0500573
Dave Wallace2a865272018-02-07 21:00:42 -0500574 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500575 return -1;
576
577 if (sid != INVALID_SESSION_ID)
578 {
579 func_str = "vppcom_session_write";
580
Dave Wallace2a865272018-02-07 21:00:42 -0500581 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -0500582 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
583 "sid %u (0x%x), buf %p, nbytes %u", getpid (),
584 fd, fd, func_str, sid, sid, buf, nbytes);
585
586 size = vppcom_session_write (sid, (void *) buf, nbytes);
587 if (size < 0)
588 {
589 errno = -size;
590 size = -1;
591 }
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700592 }
593 else
594 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500595 func_str = "libc_write";
596
Dave Wallace2a865272018-02-07 21:00:42 -0500597 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -0500598 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
599 "buf %p, nbytes %u", getpid (),
600 fd, fd, func_str, buf, nbytes);
601
602 size = libc_write (fd, buf, nbytes);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700603 }
604
Dave Wallace2a865272018-02-07 21:00:42 -0500605 if (LDP_DEBUG > 2)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700606 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500607 if (size < 0)
608 {
609 int errno_val = errno;
610 perror (func_str);
611 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
612 "rv %d, errno = %d", getpid (), fd, fd,
613 func_str, size, errno_val);
614 errno = errno_val;
615 }
616 else
617 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
618 getpid (), fd, fd, size, size);
619 }
620 return size;
621}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700622
Dave Wallace048b1d62018-01-03 22:24:41 -0500623ssize_t
624writev (int fd, const struct iovec * iov, int iovcnt)
625{
626 const char *func_str;
627 ssize_t size = 0, total = 0;
Dave Wallace2a865272018-02-07 21:00:42 -0500628 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace8aaba562018-01-18 17:21:19 -0500629 int i, rv = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -0500630
631 /*
632 * Use [f]printf() instead of clib_warning() to prevent recursion SIGSEGV.
633 */
634
Dave Wallace2a865272018-02-07 21:00:42 -0500635 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500636 return -1;
637
638 if (sid != INVALID_SESSION_ID)
639 {
640 func_str = "vppcom_session_write";
641 do
642 {
643 for (i = 0; i < iovcnt; ++i)
644 {
Dave Wallace2a865272018-02-07 21:00:42 -0500645 if (LDP_DEBUG > 4)
Dave Wallace048b1d62018-01-03 22:24:41 -0500646 printf ("%s:%d: LDP<%d>: fd %d (0x%x): calling %s() [%d]: "
647 "sid %u (0x%x), buf %p, nbytes %ld, total %ld",
648 __func__, __LINE__, getpid (), fd, fd, func_str,
649 i, sid, sid, iov[i].iov_base, iov[i].iov_len, total);
650
651 rv = vppcom_session_write (sid, iov[i].iov_base,
652 iov[i].iov_len);
653 if (rv < 0)
654 break;
655 else
656 {
657 total += rv;
658 if (rv < iov[i].iov_len)
659 {
Dave Wallace2a865272018-02-07 21:00:42 -0500660 if (LDP_DEBUG > 4)
Dave Wallace048b1d62018-01-03 22:24:41 -0500661 printf ("%s:%d: LDP<%d>: fd %d (0x%x): "
662 "rv (%d) < iov[%d].iov_len (%ld)",
663 __func__, __LINE__, getpid (), fd, fd,
664 rv, i, iov[i].iov_len);
665 break;
666 }
667 }
668 }
669 }
670 while ((rv >= 0) && (total == 0));
671
672 if (rv < 0)
673 {
674 errno = -rv;
675 size = -1;
676 }
677 else
678 size = total;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700679 }
680 else
681 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500682 func_str = "libc_writev";
683
Dave Wallace2a865272018-02-07 21:00:42 -0500684 if (LDP_DEBUG > 4)
Dave Wallace048b1d62018-01-03 22:24:41 -0500685 printf ("%s:%d: LDP<%d>: fd %d (0x%x): calling %s(): "
686 "iov %p, iovcnt %d\n", __func__, __LINE__, getpid (),
687 fd, fd, func_str, iov, iovcnt);
688
689 size = libc_writev (fd, iov, iovcnt);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700690 }
691
Dave Wallace2a865272018-02-07 21:00:42 -0500692 if (LDP_DEBUG > 4)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700693 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500694 if (size < 0)
695 {
696 int errno_val = errno;
697 perror (func_str);
698 fprintf (stderr,
699 "%s:%d: LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
700 "rv %ld, errno = %d\n", __func__, __LINE__, getpid (), fd,
701 fd, func_str, size, errno_val);
702 errno = errno_val;
703 }
704 else
705 printf ("%s:%d: LDP<%d>: fd %d (0x%x): returning %ld\n",
706 __func__, __LINE__, getpid (), fd, fd, size);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700707 }
Dave Wallace048b1d62018-01-03 22:24:41 -0500708 return size;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700709}
710
711int
Dave Wallace048b1d62018-01-03 22:24:41 -0500712fcntl (int fd, int cmd, ...)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700713{
Dave Wallace048b1d62018-01-03 22:24:41 -0500714 const char *func_str = __func__;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700715 int rv = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -0500716 va_list ap;
Dave Wallace2a865272018-02-07 21:00:42 -0500717 u32 sid = ldp_sid_from_fd (fd);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700718
Dave Wallace2a865272018-02-07 21:00:42 -0500719 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500720 return -1;
721
722 va_start (ap, cmd);
723 if (sid != INVALID_SESSION_ID)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700724 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500725 int flags = va_arg (ap, int);
726 u32 size;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700727
Dave Wallace048b1d62018-01-03 22:24:41 -0500728 size = sizeof (flags);
729 rv = -EOPNOTSUPP;
730 switch (cmd)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700731 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500732 case F_SETFL:
733 func_str = "vppcom_session_attr[SET_FLAGS]";
Florin Coras173bae32018-11-16 18:56:28 -0800734 LDBG (2, "LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x) "
735 "flags %d (0x%x), size %d", getpid (), fd, fd, func_str, sid,
736 sid, flags, flags, size);
Dave Wallace048b1d62018-01-03 22:24:41 -0500737
Florin Coras173bae32018-11-16 18:56:28 -0800738 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_FLAGS, &flags,
739 &size);
Dave Wallace048b1d62018-01-03 22:24:41 -0500740 break;
741
742 case F_GETFL:
743 func_str = "vppcom_session_attr[GET_FLAGS]";
Florin Coras173bae32018-11-16 18:56:28 -0800744 LDBG (2, "LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), "
745 "flags %d (0x%x), size %d", getpid (), fd, fd, func_str, sid,
746 sid, flags, flags, size);
Dave Wallace048b1d62018-01-03 22:24:41 -0500747
Florin Coras173bae32018-11-16 18:56:28 -0800748 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_FLAGS, &flags,
749 &size);
Dave Wallace048b1d62018-01-03 22:24:41 -0500750 if (rv == VPPCOM_OK)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700751 {
Florin Coras173bae32018-11-16 18:56:28 -0800752 LDBG (2, "LDP<%d>: fd %d (0x%x), cmd %d (F_GETFL): %s() "
753 "returned flags %d (0x%x)", getpid (), fd, fd, cmd,
754 func_str, flags, flags);
Dave Wallace048b1d62018-01-03 22:24:41 -0500755 rv = flags;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700756 }
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700757 break;
Florin Coras173bae32018-11-16 18:56:28 -0800758 case F_SETFD:
759 /* TODO handle this */
760 LDBG (0, "F_SETFD ignored flags %u", flags);
761 rv = 0;
762 break;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700763 default:
Dave Wallace048b1d62018-01-03 22:24:41 -0500764 rv = -EOPNOTSUPP;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700765 break;
766 }
Dave Wallace048b1d62018-01-03 22:24:41 -0500767 if (rv < 0)
768 {
769 errno = -rv;
770 rv = -1;
771 }
772 }
773 else
774 {
775 func_str = "libc_vfcntl";
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700776
Dave Wallace2a865272018-02-07 21:00:42 -0500777 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -0500778 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): cmd %d",
779 getpid (), fd, fd, func_str, cmd);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700780
Dave Wallace048b1d62018-01-03 22:24:41 -0500781 rv = libc_vfcntl (fd, cmd, ap);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700782 }
783
Dave Wallace048b1d62018-01-03 22:24:41 -0500784 va_end (ap);
785
Dave Wallace2a865272018-02-07 21:00:42 -0500786 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -0500787 {
788 if (rv < 0)
789 {
790 int errno_val = errno;
791 perror (func_str);
792 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
793 "rv %d, errno = %d", getpid (), fd, fd,
794 func_str, rv, errno_val);
795 errno = errno_val;
796 }
797 else
798 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
799 getpid (), fd, fd, rv, rv);
800 }
801 return rv;
802}
803
804int
805ioctl (int fd, unsigned long int cmd, ...)
806{
807 const char *func_str;
808 int rv;
809 va_list ap;
Dave Wallace2a865272018-02-07 21:00:42 -0500810 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -0500811
Dave Wallace2a865272018-02-07 21:00:42 -0500812 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500813 return -1;
814
815 va_start (ap, cmd);
816 if (sid != INVALID_SESSION_ID)
817 {
818 func_str = "vppcom_session_attr[GET_NREAD]";
819
820 switch (cmd)
821 {
822 case FIONREAD:
Dave Wallace2a865272018-02-07 21:00:42 -0500823 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -0500824 clib_warning
825 ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x)",
826 getpid (), fd, fd, func_str, sid, sid);
827
828 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_NREAD, 0, 0);
829 break;
830
831 case FIONBIO:
832 {
833 u32 flags = va_arg (ap, int) ? O_NONBLOCK : 0;
834 u32 size = sizeof (flags);
835
836 /* TBD: When VPPCOM_ATTR_[GS]ET_FLAGS supports flags other than
837 * non-blocking, the flags should be read here and merged
838 * with O_NONBLOCK.
839 */
Dave Wallace2a865272018-02-07 21:00:42 -0500840 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -0500841 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
842 "sid %u (0x%x), flags %d (0x%x), size %d",
843 getpid (), fd, fd, func_str, sid, sid,
844 flags, flags, size);
845
846 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_FLAGS, &flags,
847 &size);
848 }
849 break;
850
851 default:
852 rv = -EOPNOTSUPP;
853 break;
854 }
855 if (rv < 0)
856 {
857 errno = -rv;
858 rv = -1;
859 }
860 }
861 else
862 {
863 func_str = "libc_vioctl";
864
Dave Wallace2a865272018-02-07 21:00:42 -0500865 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -0500866 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): cmd %d",
867 getpid (), fd, fd, func_str, cmd);
868
869 rv = libc_vioctl (fd, cmd, ap);
870 }
871
Dave Wallace2a865272018-02-07 21:00:42 -0500872 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -0500873 {
874 if (rv < 0)
875 {
876 int errno_val = errno;
877 perror (func_str);
878 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
879 "rv %d, errno = %d", getpid (), fd, fd,
880 func_str, rv, errno_val);
881 errno = errno_val;
882 }
883 else
884 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
885 getpid (), fd, fd, rv, rv);
886 }
887 va_end (ap);
888 return rv;
889}
890
891int
Dave Wallace2a865272018-02-07 21:00:42 -0500892ldp_pselect (int nfds, fd_set * __restrict readfds,
893 fd_set * __restrict writefds,
894 fd_set * __restrict exceptfds,
895 const struct timespec *__restrict timeout,
896 const __sigset_t * __restrict sigmask)
Dave Wallace048b1d62018-01-03 22:24:41 -0500897{
Florin Coras30e273b2018-11-27 00:04:59 -0800898 uword sid_bits, sid_bits_set, libc_bits, libc_bits_set;
Florin Corasdfe4cf42018-11-28 22:13:45 -0800899 ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
Florin Coras30e273b2018-11-27 00:04:59 -0800900 u32 minbits = clib_max (nfds, BITS (uword)), sid;
Dave Wallace048b1d62018-01-03 22:24:41 -0500901 char *func_str = "##";
902 f64 time_out;
Florin Coras30e273b2018-11-27 00:04:59 -0800903 int rv, fd;
Dave Wallace048b1d62018-01-03 22:24:41 -0500904
905 if (nfds < 0)
906 {
907 errno = EINVAL;
908 return -1;
909 }
910
Dave Wallace3ee1fe12018-02-23 01:09:11 -0500911 if (timeout)
912 {
913 time_out = (timeout->tv_sec == 0 && timeout->tv_nsec == 0) ?
914 (f64) 0 : (f64) timeout->tv_sec +
915 (f64) timeout->tv_nsec / (f64) 1000000000;
916
917 /* select as fine grained sleep */
918 if (!nfds)
919 {
Florin Coras173bae32018-11-16 18:56:28 -0800920 LDBG (3, "LDP<%d>: sleeping for %.02f seconds", getpid (),
921 time_out);
Dave Wallace3ee1fe12018-02-23 01:09:11 -0500922
Florin Corasdfe4cf42018-11-28 22:13:45 -0800923 time_out += clib_time_now (&ldpw->clib_time);
924 while (clib_time_now (&ldpw->clib_time) < time_out)
Dave Wallace3ee1fe12018-02-23 01:09:11 -0500925 ;
926 return 0;
927 }
928 }
929 else if (!nfds)
930 {
931 errno = EINVAL;
932 return -1;
933 }
934 else
935 time_out = -1;
936
937
Dave Wallace2a865272018-02-07 21:00:42 -0500938 if (nfds <= ldp->sid_bit_val)
Dave Wallace048b1d62018-01-03 22:24:41 -0500939 {
940 func_str = "libc_pselect";
941
Florin Coras173bae32018-11-16 18:56:28 -0800942 LDBG (3, "LDP<%d>: calling %s(): nfds %d, readfds %p, writefds %p, "
943 "exceptfds %p, timeout %p, sigmask %p", getpid (), func_str, nfds,
944 readfds, writefds, exceptfds, timeout, sigmask);
Dave Wallace048b1d62018-01-03 22:24:41 -0500945
946 rv = libc_pselect (nfds, readfds, writefds, exceptfds,
947 timeout, sigmask);
948 goto done;
949 }
950
Dave Wallace2a865272018-02-07 21:00:42 -0500951 if (PREDICT_FALSE (ldp->sid_bit_val > FD_SETSIZE / 2))
Dave Wallace048b1d62018-01-03 22:24:41 -0500952 {
Dave Wallace2a865272018-02-07 21:00:42 -0500953 clib_warning ("LDP<%d>: ERROR: LDP sid bit value %d (0x%x) > "
Dave Wallace048b1d62018-01-03 22:24:41 -0500954 "FD_SETSIZE/2 %d (0x%x)!", getpid (),
Dave Wallace2a865272018-02-07 21:00:42 -0500955 ldp->sid_bit_val, ldp->sid_bit_val,
Dave Wallace048b1d62018-01-03 22:24:41 -0500956 FD_SETSIZE / 2, FD_SETSIZE / 2);
957 errno = EOVERFLOW;
958 return -1;
959 }
960
Dave Wallace048b1d62018-01-03 22:24:41 -0500961 sid_bits = libc_bits = 0;
Florin Coras173bae32018-11-16 18:56:28 -0800962 u32 n_bytes = nfds / 8 + ((nfds % 8) ? 1 : 0);
Dave Wallace048b1d62018-01-03 22:24:41 -0500963 if (readfds)
964 {
Florin Corasdfe4cf42018-11-28 22:13:45 -0800965 clib_bitmap_validate (ldpw->sid_rd_bitmap, minbits);
966 clib_bitmap_validate (ldpw->libc_rd_bitmap, minbits);
967 clib_bitmap_validate (ldpw->rd_bitmap, minbits);
968 clib_memcpy_fast (ldpw->rd_bitmap, readfds, n_bytes);
Florin Coras173bae32018-11-16 18:56:28 -0800969 memset (readfds, 0, n_bytes);
Dave Wallace048b1d62018-01-03 22:24:41 -0500970
971 /* *INDENT-OFF* */
Florin Corasdfe4cf42018-11-28 22:13:45 -0800972 clib_bitmap_foreach (fd, ldpw->rd_bitmap, ({
Florin Coras173bae32018-11-16 18:56:28 -0800973 if (fd > nfds)
974 break;
975 sid = ldp_sid_from_fd (fd);
976 LDBG (3, "LDP<%d>: readfds: fd %d (0x%x), sid %u (0x%x)",
977 getpid (), fd, fd, sid, sid);
978 if (sid == INVALID_SESSION_ID)
Florin Corasdfe4cf42018-11-28 22:13:45 -0800979 clib_bitmap_set_no_check (ldpw->libc_rd_bitmap, fd, 1);
Florin Coras173bae32018-11-16 18:56:28 -0800980 else
Florin Corasdfe4cf42018-11-28 22:13:45 -0800981 clib_bitmap_set_no_check (ldpw->sid_rd_bitmap,
Florin Coras30e273b2018-11-27 00:04:59 -0800982 vppcom_session_index (sid), 1);
Florin Coras173bae32018-11-16 18:56:28 -0800983 }));
Dave Wallace048b1d62018-01-03 22:24:41 -0500984 /* *INDENT-ON* */
985
Florin Corasdfe4cf42018-11-28 22:13:45 -0800986 sid_bits_set = clib_bitmap_last_set (ldpw->sid_rd_bitmap) + 1;
Dave Wallace048b1d62018-01-03 22:24:41 -0500987 sid_bits = (sid_bits_set > sid_bits) ? sid_bits_set : sid_bits;
988
Florin Corasdfe4cf42018-11-28 22:13:45 -0800989 libc_bits_set = clib_bitmap_last_set (ldpw->libc_rd_bitmap) + 1;
Dave Wallace048b1d62018-01-03 22:24:41 -0500990 libc_bits = (libc_bits_set > libc_bits) ? libc_bits_set : libc_bits;
991
Florin Coras173bae32018-11-16 18:56:28 -0800992 LDBG (3, "LDP<%d>: readfds: sid_bits_set %d, sid_bits %d, "
993 "libc_bits_set %d, libc_bits %d", getpid (), sid_bits_set,
994 sid_bits, libc_bits_set, libc_bits);
Dave Wallace048b1d62018-01-03 22:24:41 -0500995 }
996 if (writefds)
997 {
Florin Corasdfe4cf42018-11-28 22:13:45 -0800998 clib_bitmap_validate (ldpw->sid_wr_bitmap, minbits);
999 clib_bitmap_validate (ldpw->libc_wr_bitmap, minbits);
1000 clib_bitmap_validate (ldpw->wr_bitmap, minbits);
1001 clib_memcpy_fast (ldpw->wr_bitmap, writefds, n_bytes);
Florin Coras173bae32018-11-16 18:56:28 -08001002 memset (writefds, 0, n_bytes);
Dave Wallace048b1d62018-01-03 22:24:41 -05001003
1004 /* *INDENT-OFF* */
Florin Corasdfe4cf42018-11-28 22:13:45 -08001005 clib_bitmap_foreach (fd, ldpw->wr_bitmap, ({
Florin Coras173bae32018-11-16 18:56:28 -08001006 if (fd > nfds)
1007 break;
1008 sid = ldp_sid_from_fd (fd);
1009 LDBG (3, "LDP<%d>: writefds: fd %d (0x%x), sid %u (0x%x)",
1010 getpid (), fd, fd, sid, sid);
1011 if (sid == INVALID_SESSION_ID)
Florin Corasdfe4cf42018-11-28 22:13:45 -08001012 clib_bitmap_set_no_check (ldpw->libc_wr_bitmap, fd, 1);
Florin Coras173bae32018-11-16 18:56:28 -08001013 else
Florin Corasdfe4cf42018-11-28 22:13:45 -08001014 clib_bitmap_set_no_check (ldpw->sid_wr_bitmap,
Florin Coras30e273b2018-11-27 00:04:59 -08001015 vppcom_session_index (sid), 1);
Florin Coras173bae32018-11-16 18:56:28 -08001016 }));
Dave Wallace048b1d62018-01-03 22:24:41 -05001017 /* *INDENT-ON* */
1018
Florin Corasdfe4cf42018-11-28 22:13:45 -08001019 sid_bits_set = clib_bitmap_last_set (ldpw->sid_wr_bitmap) + 1;
Dave Wallace048b1d62018-01-03 22:24:41 -05001020 sid_bits = (sid_bits_set > sid_bits) ? sid_bits_set : sid_bits;
1021
Florin Corasdfe4cf42018-11-28 22:13:45 -08001022 libc_bits_set = clib_bitmap_last_set (ldpw->libc_wr_bitmap) + 1;
Dave Wallace048b1d62018-01-03 22:24:41 -05001023 libc_bits = (libc_bits_set > libc_bits) ? libc_bits_set : libc_bits;
1024
Florin Coras173bae32018-11-16 18:56:28 -08001025 LDBG (3, "LDP<%d>: writefds: sid_bits_set %d, sid_bits %d, "
1026 "libc_bits_set %d, libc_bits %d", getpid (),
1027 sid_bits_set, sid_bits, libc_bits_set, libc_bits);
Dave Wallace048b1d62018-01-03 22:24:41 -05001028 }
1029 if (exceptfds)
1030 {
Florin Corasdfe4cf42018-11-28 22:13:45 -08001031 clib_bitmap_validate (ldpw->sid_ex_bitmap, minbits);
1032 clib_bitmap_validate (ldpw->libc_ex_bitmap, minbits);
1033 clib_bitmap_validate (ldpw->ex_bitmap, minbits);
1034 clib_memcpy_fast (ldpw->ex_bitmap, exceptfds, n_bytes);
Florin Coras173bae32018-11-16 18:56:28 -08001035 memset (exceptfds, 0, n_bytes);
Dave Wallace048b1d62018-01-03 22:24:41 -05001036
1037 /* *INDENT-OFF* */
Florin Corasdfe4cf42018-11-28 22:13:45 -08001038 clib_bitmap_foreach (fd, ldpw->ex_bitmap, ({
Florin Coras173bae32018-11-16 18:56:28 -08001039 if (fd > nfds)
1040 break;
1041 sid = ldp_sid_from_fd (fd);
1042 LDBG (3, "LDP<%d>: exceptfds: fd %d (0x%x), sid %u (0x%x)",
1043 getpid (), fd, fd, sid, sid);
1044 if (sid == INVALID_SESSION_ID)
Florin Corasdfe4cf42018-11-28 22:13:45 -08001045 clib_bitmap_set_no_check (ldpw->libc_ex_bitmap, fd, 1);
Florin Coras173bae32018-11-16 18:56:28 -08001046 else
Florin Corasdfe4cf42018-11-28 22:13:45 -08001047 clib_bitmap_set_no_check (ldpw->sid_ex_bitmap,
Florin Coras30e273b2018-11-27 00:04:59 -08001048 vppcom_session_index (sid), 1);
Florin Coras173bae32018-11-16 18:56:28 -08001049 }));
Dave Wallace048b1d62018-01-03 22:24:41 -05001050 /* *INDENT-ON* */
1051
Florin Corasdfe4cf42018-11-28 22:13:45 -08001052 sid_bits_set = clib_bitmap_last_set (ldpw->sid_ex_bitmap) + 1;
Dave Wallace048b1d62018-01-03 22:24:41 -05001053 sid_bits = (sid_bits_set > sid_bits) ? sid_bits_set : sid_bits;
1054
Florin Corasdfe4cf42018-11-28 22:13:45 -08001055 libc_bits_set = clib_bitmap_last_set (ldpw->libc_ex_bitmap) + 1;
Dave Wallace048b1d62018-01-03 22:24:41 -05001056 libc_bits = (libc_bits_set > libc_bits) ? libc_bits_set : libc_bits;
1057
Florin Coras173bae32018-11-16 18:56:28 -08001058 LDBG (3, "LDP<%d>: exceptfds: sid_bits_set %d, sid_bits %d, "
1059 "libc_bits_set %d, libc_bits %d", getpid (),
1060 sid_bits_set, sid_bits, libc_bits_set, libc_bits);
Dave Wallace048b1d62018-01-03 22:24:41 -05001061 }
1062
1063 if (PREDICT_FALSE (!sid_bits && !libc_bits))
1064 {
1065 errno = EINVAL;
1066 rv = -1;
1067 goto done;
1068 }
1069
1070 do
1071 {
1072 if (sid_bits)
1073 {
Florin Corasdfe4cf42018-11-28 22:13:45 -08001074 if (!ldpw->select_vcl)
Dave Wallace048b1d62018-01-03 22:24:41 -05001075 {
1076 func_str = "vppcom_select";
1077
1078 if (readfds)
Florin Corasdfe4cf42018-11-28 22:13:45 -08001079 clib_memcpy_fast (ldpw->rd_bitmap, ldpw->sid_rd_bitmap,
1080 vec_len (ldpw->rd_bitmap) *
Dave Barach178cf492018-11-13 16:34:13 -05001081 sizeof (clib_bitmap_t));
Dave Wallace048b1d62018-01-03 22:24:41 -05001082 if (writefds)
Florin Corasdfe4cf42018-11-28 22:13:45 -08001083 clib_memcpy_fast (ldpw->wr_bitmap, ldpw->sid_wr_bitmap,
1084 vec_len (ldpw->wr_bitmap) *
Dave Barach178cf492018-11-13 16:34:13 -05001085 sizeof (clib_bitmap_t));
Dave Wallace048b1d62018-01-03 22:24:41 -05001086 if (exceptfds)
Florin Corasdfe4cf42018-11-28 22:13:45 -08001087 clib_memcpy_fast (ldpw->ex_bitmap, ldpw->sid_ex_bitmap,
1088 vec_len (ldpw->ex_bitmap) *
Dave Barach178cf492018-11-13 16:34:13 -05001089 sizeof (clib_bitmap_t));
Dave Wallace048b1d62018-01-03 22:24:41 -05001090
1091 rv = vppcom_select (sid_bits,
Florin Corasdfe4cf42018-11-28 22:13:45 -08001092 readfds ? ldpw->rd_bitmap : NULL,
1093 writefds ? ldpw->wr_bitmap : NULL,
1094 exceptfds ? ldpw->ex_bitmap : NULL, 0);
Dave Wallace048b1d62018-01-03 22:24:41 -05001095 if (rv < 0)
1096 {
1097 errno = -rv;
1098 rv = -1;
1099 }
1100 else if (rv > 0)
1101 {
1102 if (readfds)
1103 {
1104 /* *INDENT-OFF* */
Florin Corasdfe4cf42018-11-28 22:13:45 -08001105 clib_bitmap_foreach (sid, ldpw->rd_bitmap,
Dave Wallace048b1d62018-01-03 22:24:41 -05001106 ({
Florin Coras30e273b2018-11-27 00:04:59 -08001107 fd = ldp_fd_from_sid (vppcom_session_handle (sid));
Dave Wallace048b1d62018-01-03 22:24:41 -05001108 if (PREDICT_FALSE (fd < 0))
1109 {
1110 errno = EBADFD;
1111 rv = -1;
1112 goto done;
1113 }
1114 FD_SET (fd, readfds);
1115 }));
1116 /* *INDENT-ON* */
1117 }
1118 if (writefds)
1119 {
1120 /* *INDENT-OFF* */
Florin Corasdfe4cf42018-11-28 22:13:45 -08001121 clib_bitmap_foreach (sid, ldpw->wr_bitmap,
Dave Wallace048b1d62018-01-03 22:24:41 -05001122 ({
Florin Coras30e273b2018-11-27 00:04:59 -08001123 fd = ldp_fd_from_sid (vppcom_session_handle (sid));
Dave Wallace048b1d62018-01-03 22:24:41 -05001124 if (PREDICT_FALSE (fd < 0))
1125 {
1126 errno = EBADFD;
1127 rv = -1;
1128 goto done;
1129 }
1130 FD_SET (fd, writefds);
1131 }));
1132 /* *INDENT-ON* */
1133 }
1134 if (exceptfds)
1135 {
1136 /* *INDENT-OFF* */
Florin Corasdfe4cf42018-11-28 22:13:45 -08001137 clib_bitmap_foreach (sid, ldpw->ex_bitmap,
Dave Wallace048b1d62018-01-03 22:24:41 -05001138 ({
Florin Coras30e273b2018-11-27 00:04:59 -08001139 fd = ldp_fd_from_sid (vppcom_session_handle (sid));
Dave Wallace048b1d62018-01-03 22:24:41 -05001140 if (PREDICT_FALSE (fd < 0))
1141 {
1142 errno = EBADFD;
1143 rv = -1;
1144 goto done;
1145 }
1146 FD_SET (fd, exceptfds);
1147 }));
1148 /* *INDENT-ON* */
1149 }
Florin Corasdfe4cf42018-11-28 22:13:45 -08001150 ldpw->select_vcl = 1;
Dave Wallace048b1d62018-01-03 22:24:41 -05001151 goto done;
1152 }
1153 }
1154 else
Florin Corasdfe4cf42018-11-28 22:13:45 -08001155 ldpw->select_vcl = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -05001156 }
1157 if (libc_bits)
1158 {
1159 struct timespec tspec;
1160
1161 func_str = "libc_pselect";
1162
1163 if (readfds)
Florin Corasdfe4cf42018-11-28 22:13:45 -08001164 clib_memcpy_fast (readfds, ldpw->libc_rd_bitmap,
1165 vec_len (ldpw->rd_bitmap) *
Dave Barach178cf492018-11-13 16:34:13 -05001166 sizeof (clib_bitmap_t));
Dave Wallace048b1d62018-01-03 22:24:41 -05001167 if (writefds)
Florin Corasdfe4cf42018-11-28 22:13:45 -08001168 clib_memcpy_fast (writefds, ldpw->libc_wr_bitmap,
1169 vec_len (ldpw->wr_bitmap) *
Dave Barach178cf492018-11-13 16:34:13 -05001170 sizeof (clib_bitmap_t));
Dave Wallace048b1d62018-01-03 22:24:41 -05001171 if (exceptfds)
Florin Corasdfe4cf42018-11-28 22:13:45 -08001172 clib_memcpy_fast (exceptfds, ldpw->libc_ex_bitmap,
1173 vec_len (ldpw->ex_bitmap) *
Dave Barach178cf492018-11-13 16:34:13 -05001174 sizeof (clib_bitmap_t));
Dave Wallace048b1d62018-01-03 22:24:41 -05001175 tspec.tv_sec = tspec.tv_nsec = 0;
1176 rv = libc_pselect (libc_bits,
1177 readfds ? readfds : NULL,
1178 writefds ? writefds : NULL,
1179 exceptfds ? exceptfds : NULL, &tspec, sigmask);
1180 if (rv != 0)
1181 goto done;
1182 }
1183 }
Florin Corasdfe4cf42018-11-28 22:13:45 -08001184 while ((time_out == -1) || (clib_time_now (&ldpw->clib_time) < time_out));
Dave Wallace048b1d62018-01-03 22:24:41 -05001185 rv = 0;
1186
1187done:
1188 /* TBD: set timeout to amount of time left */
Florin Corasdfe4cf42018-11-28 22:13:45 -08001189 clib_bitmap_zero (ldpw->rd_bitmap);
1190 clib_bitmap_zero (ldpw->sid_rd_bitmap);
1191 clib_bitmap_zero (ldpw->libc_rd_bitmap);
1192 clib_bitmap_zero (ldpw->wr_bitmap);
1193 clib_bitmap_zero (ldpw->sid_wr_bitmap);
1194 clib_bitmap_zero (ldpw->libc_wr_bitmap);
1195 clib_bitmap_zero (ldpw->ex_bitmap);
1196 clib_bitmap_zero (ldpw->sid_ex_bitmap);
1197 clib_bitmap_zero (ldpw->libc_ex_bitmap);
Dave Wallace048b1d62018-01-03 22:24:41 -05001198
Dave Wallace2a865272018-02-07 21:00:42 -05001199 if (LDP_DEBUG > 3)
Dave Wallace048b1d62018-01-03 22:24:41 -05001200 {
1201 if (rv < 0)
1202 {
1203 int errno_val = errno;
1204 perror (func_str);
1205 clib_warning ("LDP<%d>: ERROR: %s() failed! "
1206 "rv %d, errno = %d", getpid (),
1207 func_str, rv, errno_val);
1208 errno = errno_val;
1209 }
1210 else
1211 clib_warning ("LDP<%d>: returning %d (0x%x)", getpid (), rv, rv);
1212 }
1213 return rv;
1214}
1215
1216int
1217select (int nfds, fd_set * __restrict readfds,
1218 fd_set * __restrict writefds,
1219 fd_set * __restrict exceptfds, struct timeval *__restrict timeout)
1220{
1221 struct timespec tspec;
1222
1223 if (timeout)
1224 {
1225 tspec.tv_sec = timeout->tv_sec;
1226 tspec.tv_nsec = timeout->tv_usec * 1000;
1227 }
Dave Wallace2a865272018-02-07 21:00:42 -05001228 return ldp_pselect (nfds, readfds, writefds, exceptfds,
1229 timeout ? &tspec : NULL, NULL);
Dave Wallace048b1d62018-01-03 22:24:41 -05001230}
1231
1232#ifdef __USE_XOPEN2K
1233int
1234pselect (int nfds, fd_set * __restrict readfds,
1235 fd_set * __restrict writefds,
1236 fd_set * __restrict exceptfds,
1237 const struct timespec *__restrict timeout,
1238 const __sigset_t * __restrict sigmask)
1239{
Dave Wallace2a865272018-02-07 21:00:42 -05001240 return ldp_pselect (nfds, readfds, writefds, exceptfds, timeout, 0);
Dave Wallace048b1d62018-01-03 22:24:41 -05001241}
1242#endif
1243
1244int
1245socket (int domain, int type, int protocol)
1246{
1247 const char *func_str;
1248 int rv;
1249 u8 is_nonblocking = type & SOCK_NONBLOCK ? 1 : 0;
1250 int sock_type = type & ~(SOCK_CLOEXEC | SOCK_NONBLOCK);
1251
Dave Wallace2a865272018-02-07 21:00:42 -05001252 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001253 return -1;
1254
1255 if (((domain == AF_INET) || (domain == AF_INET6)) &&
1256 ((sock_type == SOCK_STREAM) || (sock_type == SOCK_DGRAM)))
1257 {
1258 int sid;
Dave Wallace048b1d62018-01-03 22:24:41 -05001259 u8 proto = ((sock_type == SOCK_DGRAM) ?
1260 VPPCOM_PROTO_UDP : VPPCOM_PROTO_TCP);
1261
1262 func_str = "vppcom_session_create";
1263
Florin Coras99368312018-08-02 10:45:44 -07001264 LDBG (0, "LDP<%d>: : calling %s(): proto %u (%s), is_nonblocking %u",
1265 getpid (), func_str, proto, vppcom_proto_str (proto),
1266 is_nonblocking);
Dave Wallace048b1d62018-01-03 22:24:41 -05001267
Dave Wallacec04cbf12018-02-07 18:14:02 -05001268 sid = vppcom_session_create (proto, is_nonblocking);
Dave Wallace048b1d62018-01-03 22:24:41 -05001269 if (sid < 0)
1270 {
1271 errno = -sid;
1272 rv = -1;
1273 }
1274 else
1275 {
Dave Wallace2a865272018-02-07 21:00:42 -05001276 func_str = "ldp_fd_from_sid";
Florin Coras30e273b2018-11-27 00:04:59 -08001277 rv = ldp_fd_alloc (sid);
Dave Wallace048b1d62018-01-03 22:24:41 -05001278 if (rv < 0)
1279 {
1280 (void) vppcom_session_close (sid);
1281 errno = -rv;
1282 rv = -1;
1283 }
1284 }
1285 }
1286 else
1287 {
1288 func_str = "libc_socket";
1289
Florin Coras99368312018-08-02 10:45:44 -07001290 LDBG (0, "LDP<%d>: : calling %s()", getpid (), func_str);
Dave Wallace048b1d62018-01-03 22:24:41 -05001291
1292 rv = libc_socket (domain, type, protocol);
1293 }
1294
Dave Wallace2a865272018-02-07 21:00:42 -05001295 if (LDP_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001296 {
1297 if (rv < 0)
1298 {
1299 int errno_val = errno;
1300 perror (func_str);
1301 clib_warning ("LDP<%d>: ERROR: %s() failed! "
1302 "rv %d, errno = %d",
1303 getpid (), func_str, rv, errno_val);
1304 errno = errno_val;
1305 }
1306 else
1307 clib_warning ("LDP<%d>: : returning fd %d (0x%x)", getpid (), rv, rv);
1308 }
1309 return rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001310}
1311
1312/*
1313 * Create two new sockets, of type TYPE in domain DOMAIN and using
1314 * protocol PROTOCOL, which are connected to each other, and put file
1315 * descriptors for them in FDS[0] and FDS[1]. If PROTOCOL is zero,
1316 * one will be chosen automatically.
1317 * Returns 0 on success, -1 for errors.
1318 * */
1319int
Dave Wallace048b1d62018-01-03 22:24:41 -05001320socketpair (int domain, int type, int protocol, int fds[2])
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001321{
Dave Wallace048b1d62018-01-03 22:24:41 -05001322 const char *func_str;
1323 int rv;
1324 int sock_type = type & ~(SOCK_CLOEXEC | SOCK_NONBLOCK);
1325
Dave Wallace2a865272018-02-07 21:00:42 -05001326 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001327 return -1;
1328
1329 if (((domain == AF_INET) || (domain == AF_INET6)) &&
1330 ((sock_type == SOCK_STREAM) || (sock_type == SOCK_DGRAM)))
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001331 {
Dave Wallace8aaba562018-01-18 17:21:19 -05001332 func_str = __func__;
1333
Dave Wallace048b1d62018-01-03 22:24:41 -05001334 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
1335 errno = ENOSYS;
1336 rv = -1;
1337 }
1338 else
1339 {
1340 func_str = "libc_socket";
1341
Florin Coras173bae32018-11-16 18:56:28 -08001342 LDBG (1, "LDP<%d>: : calling %s()", getpid (), func_str);
Dave Wallace048b1d62018-01-03 22:24:41 -05001343
Florin Coras173bae32018-11-16 18:56:28 -08001344 rv = libc_socketpair (domain, type, protocol, fds);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001345 }
1346
Dave Wallace2a865272018-02-07 21:00:42 -05001347 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05001348 {
1349 if (rv < 0)
1350 {
1351 int errno_val = errno;
1352 perror (func_str);
1353 clib_warning ("LDP<%d>: ERROR: %s() failed! "
1354 "rv %d, errno = %d",
1355 getpid (), func_str, rv, errno_val);
1356 errno = errno_val;
1357 }
1358 else
1359 clib_warning ("LDP<%d>: : returning fd %d (0x%x)", getpid (), rv, rv);
1360 }
1361 return rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001362}
1363
1364int
Dave Wallace048b1d62018-01-03 22:24:41 -05001365bind (int fd, __CONST_SOCKADDR_ARG addr, socklen_t len)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001366{
1367 int rv;
Dave Wallace048b1d62018-01-03 22:24:41 -05001368 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05001369 u32 sid = ldp_sid_from_fd (fd);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001370
Dave Wallace2a865272018-02-07 21:00:42 -05001371 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001372 return -1;
1373
1374 if (sid != INVALID_SESSION_ID)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001375 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001376 vppcom_endpt_t ep;
1377
1378 func_str = "vppcom_session_bind";
1379
Dave Wallace048b1d62018-01-03 22:24:41 -05001380 switch (addr->sa_family)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001381 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001382 case AF_INET:
1383 if (len != sizeof (struct sockaddr_in))
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001384 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001385 clib_warning
1386 ("LDP<%d>: ERROR: fd %d (0x%x): sid %u (0x%x): Invalid "
1387 "AF_INET addr len %u!", getpid (), fd, fd, sid, sid, len);
1388 errno = EINVAL;
1389 rv = -1;
1390 goto done;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001391 }
Dave Wallace048b1d62018-01-03 22:24:41 -05001392 ep.is_ip4 = VPPCOM_IS_IP4;
1393 ep.ip = (u8 *) & ((const struct sockaddr_in *) addr)->sin_addr;
1394 ep.port = (u16) ((const struct sockaddr_in *) addr)->sin_port;
1395 break;
1396
1397 case AF_INET6:
1398 if (len != sizeof (struct sockaddr_in6))
1399 {
1400 clib_warning
1401 ("LDP<%d>: ERROR: fd %d (0x%x): sid %u (0x%x): Invalid "
1402 "AF_INET6 addr len %u!", getpid (), fd, fd, sid, sid, len);
1403 errno = EINVAL;
1404 rv = -1;
1405 goto done;
1406 }
1407 ep.is_ip4 = VPPCOM_IS_IP6;
1408 ep.ip = (u8 *) & ((const struct sockaddr_in6 *) addr)->sin6_addr;
1409 ep.port = (u16) ((const struct sockaddr_in6 *) addr)->sin6_port;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001410 break;
1411
1412 default:
Dave Wallace048b1d62018-01-03 22:24:41 -05001413 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): sid %u (0x%x): "
1414 "Unsupported address family %u!",
1415 getpid (), fd, fd, sid, sid, addr->sa_family);
1416 errno = EAFNOSUPPORT;
1417 rv = -1;
1418 goto done;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001419 }
Dave Wallace2a865272018-02-07 21:00:42 -05001420 if (LDP_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001421 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), "
1422 "addr %p, len %u",
1423 getpid (), fd, fd, func_str, sid, sid, addr, len);
1424
1425 rv = vppcom_session_bind (sid, &ep);
1426 if (rv != VPPCOM_OK)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001427 {
1428 errno = -rv;
Dave Wallace048b1d62018-01-03 22:24:41 -05001429 rv = -1;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001430 }
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001431 }
Dave Wallace048b1d62018-01-03 22:24:41 -05001432 else
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001433 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001434 func_str = "libc_bind";
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001435
Dave Wallace2a865272018-02-07 21:00:42 -05001436 if (LDP_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001437 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1438 "addr %p, len %u",
1439 getpid (), fd, fd, func_str, addr, len);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001440
Dave Wallace048b1d62018-01-03 22:24:41 -05001441 rv = libc_bind (fd, addr, len);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001442 }
1443
Dave Wallace048b1d62018-01-03 22:24:41 -05001444done:
Dave Wallace2a865272018-02-07 21:00:42 -05001445 if (LDP_DEBUG > 0)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001446 {
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001447 if (rv < 0)
1448 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001449 int errno_val = errno;
1450 perror (func_str);
1451 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
1452 "rv %d, errno = %d", getpid (), fd, fd,
1453 func_str, rv, errno_val);
1454 errno = errno_val;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001455 }
Dave Wallace048b1d62018-01-03 22:24:41 -05001456 else
1457 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
1458 getpid (), fd, fd, rv, rv);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001459 }
1460 return rv;
1461}
1462
1463static inline int
Dave Wallace2a865272018-02-07 21:00:42 -05001464ldp_copy_ep_to_sockaddr (__SOCKADDR_ARG addr, socklen_t * __restrict len,
1465 vppcom_endpt_t * ep)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001466{
Dave Wallace048b1d62018-01-03 22:24:41 -05001467 int rv = 0;
1468 int sa_len, copy_len;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001469
Dave Wallace2a865272018-02-07 21:00:42 -05001470 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001471 return -1;
1472
1473 if (addr && len && ep)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001474 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001475 addr->sa_family = (ep->is_ip4 == VPPCOM_IS_IP4) ? AF_INET : AF_INET6;
1476 switch (addr->sa_family)
1477 {
1478 case AF_INET:
1479 ((struct sockaddr_in *) addr)->sin_port = ep->port;
1480 if (*len > sizeof (struct sockaddr_in))
1481 *len = sizeof (struct sockaddr_in);
1482 sa_len = sizeof (struct sockaddr_in) - sizeof (struct in_addr);
1483 copy_len = *len - sa_len;
1484 if (copy_len > 0)
1485 memcpy (&((struct sockaddr_in *) addr)->sin_addr, ep->ip,
1486 copy_len);
1487 break;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001488
Dave Wallace048b1d62018-01-03 22:24:41 -05001489 case AF_INET6:
1490 ((struct sockaddr_in6 *) addr)->sin6_port = ep->port;
1491 if (*len > sizeof (struct sockaddr_in6))
1492 *len = sizeof (struct sockaddr_in6);
1493 sa_len = sizeof (struct sockaddr_in6) - sizeof (struct in6_addr);
1494 copy_len = *len - sa_len;
1495 if (copy_len > 0)
1496 memcpy (((struct sockaddr_in6 *) addr)->sin6_addr.
1497 __in6_u.__u6_addr8, ep->ip, copy_len);
1498 break;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001499
Dave Wallace048b1d62018-01-03 22:24:41 -05001500 default:
1501 /* Not possible */
1502 rv = -EAFNOSUPPORT;
1503 break;
1504 }
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001505 }
Dave Wallacee695cb42017-11-02 22:04:42 -04001506 return rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001507}
1508
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001509int
Dave Wallace048b1d62018-01-03 22:24:41 -05001510getsockname (int fd, __SOCKADDR_ARG addr, socklen_t * __restrict len)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001511{
1512 int rv;
Dave Wallace048b1d62018-01-03 22:24:41 -05001513 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05001514 u32 sid = ldp_sid_from_fd (fd);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001515
Dave Wallace2a865272018-02-07 21:00:42 -05001516 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001517 return -1;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001518
Dave Wallace048b1d62018-01-03 22:24:41 -05001519 if (sid != INVALID_SESSION_ID)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001520 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001521 vppcom_endpt_t ep;
1522 u8 addr_buf[sizeof (struct in6_addr)];
1523 u32 size = sizeof (ep);
1524
1525 ep.ip = addr_buf;
1526 func_str = "vppcom_session_attr[GET_LCL_ADDR]";
1527
Dave Wallace2a865272018-02-07 21:00:42 -05001528 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001529 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), "
1530 "addr %p, len %u",
1531 getpid (), fd, fd, func_str, sid, sid, addr, len);
1532
1533 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_LCL_ADDR, &ep, &size);
1534 if (rv != VPPCOM_OK)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001535 {
1536 errno = -rv;
Dave Wallace048b1d62018-01-03 22:24:41 -05001537 rv = -1;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001538 }
Dave Wallace048b1d62018-01-03 22:24:41 -05001539 else
1540 {
Dave Wallace2a865272018-02-07 21:00:42 -05001541 rv = ldp_copy_ep_to_sockaddr (addr, len, &ep);
Dave Wallace048b1d62018-01-03 22:24:41 -05001542 if (rv != VPPCOM_OK)
1543 {
1544 errno = -rv;
1545 rv = -1;
1546 }
1547 }
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001548 }
1549 else
1550 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001551 func_str = "libc_getsockname";
1552
Dave Wallace2a865272018-02-07 21:00:42 -05001553 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001554 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1555 "addr %p, len %u",
1556 getpid (), fd, fd, func_str, addr, len);
1557
1558 rv = libc_getsockname (fd, addr, len);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001559 }
1560
Dave Wallace2a865272018-02-07 21:00:42 -05001561 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001562 {
1563 if (rv < 0)
1564 {
1565 int errno_val = errno;
1566 perror (func_str);
1567 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
1568 "rv %d, errno = %d", getpid (), fd, fd,
1569 func_str, rv, errno_val);
1570 errno = errno_val;
1571 }
1572 else
1573 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
1574 getpid (), fd, fd, rv, rv);
1575 }
1576 return rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001577}
1578
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001579int
Dave Wallace048b1d62018-01-03 22:24:41 -05001580connect (int fd, __CONST_SOCKADDR_ARG addr, socklen_t len)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001581{
Dave Wallace048b1d62018-01-03 22:24:41 -05001582 int rv;
1583 const char *func_str = __func__;
Dave Wallace2a865272018-02-07 21:00:42 -05001584 u32 sid = ldp_sid_from_fd (fd);
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001585
Dave Wallace2a865272018-02-07 21:00:42 -05001586 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001587 return -1;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001588
Dave Wallace048b1d62018-01-03 22:24:41 -05001589 if (!addr)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001590 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001591 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): NULL addr, len %u",
1592 getpid (), fd, fd, len);
1593 errno = EINVAL;
1594 rv = -1;
1595 goto done;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001596 }
1597
Dave Wallace048b1d62018-01-03 22:24:41 -05001598 if (sid != INVALID_SESSION_ID)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001599 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001600 vppcom_endpt_t ep;
1601
1602 func_str = "vppcom_session_connect";
1603
Dave Wallace048b1d62018-01-03 22:24:41 -05001604 switch (addr->sa_family)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001605 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001606 case AF_INET:
1607 if (len != sizeof (struct sockaddr_in))
1608 {
1609 clib_warning
1610 ("LDP<%d>: fd %d (0x%x): ERROR sid %u (0x%x): Invalid "
1611 "AF_INET addr len %u!", getpid (), fd, fd, sid, sid, len);
1612 errno = EINVAL;
1613 rv = -1;
1614 goto done;
1615 }
1616 ep.is_ip4 = VPPCOM_IS_IP4;
1617 ep.ip = (u8 *) & ((const struct sockaddr_in *) addr)->sin_addr;
1618 ep.port = (u16) ((const struct sockaddr_in *) addr)->sin_port;
1619 break;
1620
1621 case AF_INET6:
1622 if (len != sizeof (struct sockaddr_in6))
1623 {
1624 clib_warning
1625 ("LDP<%d>: fd %d (0x%x): ERROR sid %u (0x%x): Invalid "
1626 "AF_INET6 addr len %u!", getpid (), fd, fd, sid, sid, len);
1627 errno = EINVAL;
1628 rv = -1;
1629 goto done;
1630 }
1631 ep.is_ip4 = VPPCOM_IS_IP6;
1632 ep.ip = (u8 *) & ((const struct sockaddr_in6 *) addr)->sin6_addr;
1633 ep.port = (u16) ((const struct sockaddr_in6 *) addr)->sin6_port;
1634 break;
1635
1636 default:
1637 clib_warning ("LDP<%d>: fd %d (0x%x): ERROR sid %u (0x%x): "
1638 "Unsupported address family %u!",
1639 getpid (), fd, fd, sid, sid, addr->sa_family);
1640 errno = EAFNOSUPPORT;
1641 rv = -1;
1642 goto done;
1643 }
Dave Wallace2a865272018-02-07 21:00:42 -05001644 if (LDP_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001645 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x) "
1646 "addr %p len %u",
1647 getpid (), fd, fd, func_str, sid, sid, addr, len);
1648
1649 rv = vppcom_session_connect (sid, &ep);
1650 if (rv != VPPCOM_OK)
1651 {
1652 errno = -rv;
1653 rv = -1;
1654 }
1655 }
1656 else
1657 {
1658 func_str = "libc_connect";
1659
Dave Wallace2a865272018-02-07 21:00:42 -05001660 if (LDP_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001661 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1662 "addr %p, len %u",
1663 getpid (), fd, fd, func_str, addr, len);
1664
1665 rv = libc_connect (fd, addr, len);
1666 }
1667
1668done:
Dave Wallace2a865272018-02-07 21:00:42 -05001669 if (LDP_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001670 {
1671 if (rv < 0)
1672 {
1673 int errno_val = errno;
1674 perror (func_str);
1675 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
1676 "rv %d, errno = %d", getpid (), fd, fd,
1677 func_str, rv, errno_val);
1678 errno = errno_val;
1679 }
1680 else
1681 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
1682 getpid (), fd, fd, rv, rv);
1683 }
1684 return rv;
1685}
1686
1687int
1688getpeername (int fd, __SOCKADDR_ARG addr, socklen_t * __restrict len)
1689{
1690 int rv;
1691 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05001692 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05001693
Dave Wallace2a865272018-02-07 21:00:42 -05001694 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001695 return -1;
1696
Dave Wallace048b1d62018-01-03 22:24:41 -05001697 if (sid != INVALID_SESSION_ID)
1698 {
1699 vppcom_endpt_t ep;
1700 u8 addr_buf[sizeof (struct in6_addr)];
1701 u32 size = sizeof (ep);
1702
1703 ep.ip = addr_buf;
1704 func_str = "vppcom_session_attr[GET_PEER_ADDR]";
1705
Dave Wallace2a865272018-02-07 21:00:42 -05001706 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001707 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), "
1708 "addr %p, len %u",
1709 getpid (), fd, fd, func_str, sid, sid, addr, len);
1710
1711 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_PEER_ADDR, &ep, &size);
1712 if (rv != VPPCOM_OK)
1713 {
1714 errno = -rv;
1715 rv = -1;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001716 }
1717 else
1718 {
Dave Wallace2a865272018-02-07 21:00:42 -05001719 rv = ldp_copy_ep_to_sockaddr (addr, len, &ep);
Dave Wallace048b1d62018-01-03 22:24:41 -05001720 if (rv != VPPCOM_OK)
1721 {
1722 errno = -rv;
1723 rv = -1;
1724 }
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001725 }
1726 }
Dave Wallace048b1d62018-01-03 22:24:41 -05001727 else
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001728 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001729 func_str = "libc_getpeername";
1730
Dave Wallace2a865272018-02-07 21:00:42 -05001731 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001732 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1733 "addr %p, len %u",
1734 getpid (), fd, fd, func_str, addr, len);
1735
1736 rv = libc_getpeername (fd, addr, len);
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001737 }
1738
Dave Wallace2a865272018-02-07 21:00:42 -05001739 if (LDP_DEBUG > 2)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001740 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001741 if (rv < 0)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001742 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001743 int errno_val = errno;
1744 perror (func_str);
1745 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
1746 "rv %d, errno = %d", getpid (), fd, fd,
1747 func_str, rv, errno_val);
1748 errno = errno_val;
1749 }
1750 else
1751 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
1752 getpid (), fd, fd, rv, rv);
1753 }
1754 return rv;
1755}
1756
1757ssize_t
1758send (int fd, const void *buf, size_t n, int flags)
1759{
1760 ssize_t size;
1761 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05001762 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05001763
Dave Wallace2a865272018-02-07 21:00:42 -05001764 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001765 return -1;
1766
1767 if (sid != INVALID_SESSION_ID)
1768 {
1769
1770 func_str = "vppcom_session_sendto";
1771
Dave Wallace2a865272018-02-07 21:00:42 -05001772 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001773 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), "
1774 "buf %p, n %u, flags 0x%x",
1775 getpid (), fd, fd, func_str, sid, sid, buf, n, flags);
1776
1777 size = vppcom_session_sendto (sid, (void *) buf, n, flags, NULL);
qchangaa8f63c2018-05-30 11:44:18 -07001778 if (size < VPPCOM_OK)
Dave Wallace048b1d62018-01-03 22:24:41 -05001779 {
1780 errno = -size;
1781 size = -1;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001782 }
1783 }
Dave Wallace048b1d62018-01-03 22:24:41 -05001784 else
1785 {
1786 func_str = "libc_send";
1787
Dave Wallace2a865272018-02-07 21:00:42 -05001788 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001789 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1790 "buf %p, n %u, flags 0x%x",
1791 getpid (), fd, fd, func_str, buf, n, flags);
1792
1793 size = libc_send (fd, buf, n, flags);
1794 }
1795
Dave Wallace2a865272018-02-07 21:00:42 -05001796 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001797 {
1798 if (size < 0)
1799 {
1800 int errno_val = errno;
1801 perror (func_str);
1802 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
1803 "rv %d, errno = %d", getpid (), fd, fd,
1804 func_str, size, errno_val);
1805 errno = errno_val;
1806 }
1807 else
1808 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
1809 getpid (), fd, fd, size, size);
1810 }
1811 return size;
1812}
1813
1814ssize_t
1815sendfile (int out_fd, int in_fd, off_t * offset, size_t len)
1816{
Florin Corasdfe4cf42018-11-28 22:13:45 -08001817 ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
Dave Wallace048b1d62018-01-03 22:24:41 -05001818 ssize_t size = 0;
1819 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05001820 u32 sid = ldp_sid_from_fd (out_fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05001821
Dave Wallace2a865272018-02-07 21:00:42 -05001822 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001823 return -1;
1824
1825 if (sid != INVALID_SESSION_ID)
1826 {
1827 int rv;
1828 ssize_t results = 0;
1829 size_t n_bytes_left = len;
1830 size_t bytes_to_read;
1831 int nbytes;
1832 int errno_val;
1833 u8 eagain = 0;
1834 u32 flags, flags_len = sizeof (flags);
1835
1836 func_str = "vppcom_session_attr[GET_FLAGS]";
1837 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_FLAGS, &flags,
1838 &flags_len);
1839 if (PREDICT_FALSE (rv != VPPCOM_OK))
1840 {
1841 clib_warning ("LDP<%d>: ERROR: out fd %d (0x%x): %s(): "
1842 "sid %u (0x%x), returned %d (%s)!", getpid (),
1843 out_fd, out_fd, func_str, sid, sid, rv,
1844 vppcom_retval_str (rv));
1845
Florin Corasdfe4cf42018-11-28 22:13:45 -08001846 vec_reset_length (ldpw->io_buffer);
Dave Wallace048b1d62018-01-03 22:24:41 -05001847 errno = -rv;
1848 size = -1;
1849 goto done;
1850 }
1851
1852 if (offset)
1853 {
1854 off_t off = lseek (in_fd, *offset, SEEK_SET);
1855 if (PREDICT_FALSE (off == -1))
1856 {
1857 func_str = "lseek";
1858 errno_val = errno;
1859 clib_warning ("LDP<%d>: ERROR: out fd %d (0x%x): %s(): "
1860 "SEEK_SET failed: in_fd %d, offset %p, "
1861 "*offset %ld, rv %ld, errno %d", getpid (),
1862 out_fd, out_fd, in_fd, offset, *offset, off,
1863 errno_val);
1864 errno = errno_val;
1865 size = -1;
1866 goto done;
1867 }
1868
1869 ASSERT (off == *offset);
1870 }
1871
1872 do
1873 {
1874 func_str = "vppcom_session_attr[GET_NWRITE]";
1875 size = vppcom_session_attr (sid, VPPCOM_ATTR_GET_NWRITE, 0, 0);
1876 if (size < 0)
1877 {
1878 clib_warning
1879 ("LDP<%d>: ERROR: fd %d (0x%x): %s(): sid %u (0x%x), "
1880 "returned %d (%s)!", getpid (), out_fd, out_fd, func_str,
1881 sid, sid, size, vppcom_retval_str (size));
Florin Corasdfe4cf42018-11-28 22:13:45 -08001882 vec_reset_length (ldpw->io_buffer);
Dave Wallace048b1d62018-01-03 22:24:41 -05001883 errno = -size;
1884 size = -1;
1885 goto done;
1886 }
1887
1888 bytes_to_read = size;
Dave Wallace2a865272018-02-07 21:00:42 -05001889 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001890 clib_warning
1891 ("LDP<%d>: fd %d (0x%x): called %s(): sid %u (0x%x), "
1892 "results %ld, n_bytes_left %lu, bytes_to_read %lu", getpid (),
1893 out_fd, out_fd, func_str, sid, sid, results, n_bytes_left,
1894 bytes_to_read);
1895
1896 if (bytes_to_read == 0)
1897 {
1898 if (flags & O_NONBLOCK)
1899 {
1900 if (!results)
1901 {
Dave Wallace2a865272018-02-07 21:00:42 -05001902 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001903 clib_warning ("LDP<%d>: fd %d (0x%x): sid %u (0x%x): "
1904 "EAGAIN",
1905 getpid (), out_fd, out_fd, sid, sid);
1906 eagain = 1;
1907 }
1908 goto update_offset;
1909 }
1910 else
1911 continue;
1912 }
1913 bytes_to_read = clib_min (n_bytes_left, bytes_to_read);
Florin Corasdfe4cf42018-11-28 22:13:45 -08001914 vec_validate (ldpw->io_buffer, bytes_to_read);
1915 nbytes = libc_read (in_fd, ldpw->io_buffer, bytes_to_read);
Dave Wallace048b1d62018-01-03 22:24:41 -05001916 if (nbytes < 0)
1917 {
1918 func_str = "libc_read";
1919 errno_val = errno;
1920 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): in_fd (%d), "
1921 "io_buffer %p, bytes_to_read %lu, rv %d, "
1922 "errno %d", getpid (), out_fd, out_fd, func_str,
Florin Corasdfe4cf42018-11-28 22:13:45 -08001923 in_fd, ldpw->io_buffer, bytes_to_read, nbytes,
Dave Wallace048b1d62018-01-03 22:24:41 -05001924 errno_val);
1925 errno = errno_val;
1926
1927 if (results == 0)
1928 {
Florin Corasdfe4cf42018-11-28 22:13:45 -08001929 vec_reset_length (ldpw->io_buffer);
Dave Wallace048b1d62018-01-03 22:24:41 -05001930 size = -1;
1931 goto done;
1932 }
1933 goto update_offset;
1934 }
1935 func_str = "vppcom_session_write";
Dave Wallace2a865272018-02-07 21:00:42 -05001936 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001937 clib_warning
1938 ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), "
1939 "buf %p, nbytes %u: results %d, n_bytes_left %d", getpid (),
Florin Corasdfe4cf42018-11-28 22:13:45 -08001940 out_fd, out_fd, func_str, sid, sid, ldpw->io_buffer, nbytes,
Dave Wallace048b1d62018-01-03 22:24:41 -05001941 results, n_bytes_left);
1942
Florin Corasdfe4cf42018-11-28 22:13:45 -08001943 size = vppcom_session_write (sid, ldpw->io_buffer, nbytes);
Dave Wallace048b1d62018-01-03 22:24:41 -05001944 if (size < 0)
1945 {
1946 if (size == VPPCOM_EAGAIN)
1947 {
1948 if (flags & O_NONBLOCK)
1949 {
1950 if (!results)
1951 {
Dave Wallace2a865272018-02-07 21:00:42 -05001952 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001953 clib_warning
1954 ("LDP<%d>: fd %d (0x%x): sid %u (0x%x): "
1955 "EAGAIN", getpid (), out_fd, out_fd, sid, sid);
1956 eagain = 1;
1957 }
1958 goto update_offset;
1959 }
1960 else
1961 continue;
1962 }
1963 else
1964 {
1965 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s():"
1966 "sid %u, io_buffer %p, nbytes %u "
1967 "returned %d (%s)",
1968 getpid (), out_fd, out_fd, func_str,
Florin Corasdfe4cf42018-11-28 22:13:45 -08001969 sid, ldpw->io_buffer, nbytes,
Dave Wallace048b1d62018-01-03 22:24:41 -05001970 size, vppcom_retval_str (size));
1971 }
1972 if (results == 0)
1973 {
Florin Corasdfe4cf42018-11-28 22:13:45 -08001974 vec_reset_length (ldpw->io_buffer);
Dave Wallace048b1d62018-01-03 22:24:41 -05001975 errno = -size;
1976 size = -1;
1977 goto done;
1978 }
1979 goto update_offset;
1980 }
1981
1982 results += nbytes;
1983 ASSERT (n_bytes_left >= nbytes);
1984 n_bytes_left = n_bytes_left - nbytes;
1985 }
1986 while (n_bytes_left > 0);
1987
1988 update_offset:
Florin Corasdfe4cf42018-11-28 22:13:45 -08001989 vec_reset_length (ldpw->io_buffer);
Dave Wallace048b1d62018-01-03 22:24:41 -05001990 if (offset)
1991 {
1992 off_t off = lseek (in_fd, *offset, SEEK_SET);
1993 if (PREDICT_FALSE (off == -1))
1994 {
1995 func_str = "lseek";
1996 errno_val = errno;
1997 clib_warning ("LDP<%d>: ERROR: %s(): SEEK_SET failed: "
1998 "in_fd %d, offset %p, *offset %ld, "
1999 "rv %ld, errno %d", getpid (), in_fd,
2000 offset, *offset, off, errno_val);
2001 errno = errno_val;
2002 size = -1;
2003 goto done;
2004 }
2005
2006 ASSERT (off == *offset);
2007 *offset += results + 1;
2008 }
2009 if (eagain)
2010 {
2011 errno = EAGAIN;
2012 size = -1;
2013 }
2014 else
2015 size = results;
2016 }
2017 else
2018 {
2019 func_str = "libc_send";
2020
Dave Wallace2a865272018-02-07 21:00:42 -05002021 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002022 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2023 "in_fd %d, offset %p, len %u",
2024 getpid (), out_fd, out_fd, func_str,
2025 in_fd, offset, len);
2026
2027 size = libc_sendfile (out_fd, in_fd, offset, len);
2028 }
2029
2030done:
Dave Wallace2a865272018-02-07 21:00:42 -05002031 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002032 {
2033 if (size < 0)
2034 {
2035 int errno_val = errno;
2036 perror (func_str);
2037 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2038 "rv %d, errno = %d", getpid (), out_fd, out_fd,
2039 func_str, size, errno_val);
2040 errno = errno_val;
2041 }
2042 else
2043 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2044 getpid (), out_fd, out_fd, size, size);
2045 }
2046 return size;
2047}
2048
2049ssize_t
2050sendfile64 (int out_fd, int in_fd, off_t * offset, size_t len)
2051{
2052 return sendfile (out_fd, in_fd, offset, len);
2053}
2054
2055ssize_t
2056recv (int fd, void *buf, size_t n, int flags)
2057{
2058 ssize_t size;
2059 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05002060 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05002061
Dave Wallace2a865272018-02-07 21:00:42 -05002062 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002063 return -1;
2064
2065 if (sid != INVALID_SESSION_ID)
2066 {
2067 func_str = "vppcom_session_recvfrom";
2068
Dave Wallace2a865272018-02-07 21:00:42 -05002069 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002070 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2071 "sid %u (0x%x), buf %p, n %u, flags 0x%x", getpid (),
2072 fd, fd, func_str, sid, sid, buf, n, flags);
2073
2074 size = vppcom_session_recvfrom (sid, buf, n, flags, NULL);
2075 if (size < 0)
2076 {
2077 errno = -size;
2078 size = -1;
2079 }
2080 }
2081 else
2082 {
2083 func_str = "libc_recv";
2084
Dave Wallace2a865272018-02-07 21:00:42 -05002085 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002086 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2087 "buf %p, n %u, flags 0x%x", getpid (),
2088 fd, fd, func_str, buf, n, flags);
2089
2090 size = libc_recv (fd, buf, n, flags);
2091 }
2092
Dave Wallace2a865272018-02-07 21:00:42 -05002093 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002094 {
2095 if (size < 0)
2096 {
2097 int errno_val = errno;
2098 perror (func_str);
2099 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2100 "rv %d, errno = %d", getpid (), fd, fd,
2101 func_str, size, errno_val);
2102 errno = errno_val;
2103 }
2104 else
2105 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2106 getpid (), fd, fd, size, size);
2107 }
2108 return size;
2109}
2110
2111ssize_t
2112sendto (int fd, const void *buf, size_t n, int flags,
2113 __CONST_SOCKADDR_ARG addr, socklen_t addr_len)
2114{
2115 ssize_t size;
2116 const char *func_str = __func__;
Dave Wallace2a865272018-02-07 21:00:42 -05002117 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05002118
Dave Wallace2a865272018-02-07 21:00:42 -05002119 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002120 return -1;
2121
2122 if (sid != INVALID_SESSION_ID)
2123 {
2124 vppcom_endpt_t *ep = 0;
2125 vppcom_endpt_t _ep;
2126
2127 if (addr)
2128 {
2129 ep = &_ep;
Dave Wallace048b1d62018-01-03 22:24:41 -05002130 switch (addr->sa_family)
2131 {
2132 case AF_INET:
2133 ep->is_ip4 = VPPCOM_IS_IP4;
2134 ep->ip =
2135 (uint8_t *) & ((const struct sockaddr_in *) addr)->sin_addr;
2136 ep->port =
2137 (uint16_t) ((const struct sockaddr_in *) addr)->sin_port;
2138 break;
2139
2140 case AF_INET6:
2141 ep->is_ip4 = VPPCOM_IS_IP6;
2142 ep->ip =
2143 (uint8_t *) & ((const struct sockaddr_in6 *) addr)->sin6_addr;
2144 ep->port =
2145 (uint16_t) ((const struct sockaddr_in6 *) addr)->sin6_port;
2146 break;
2147
2148 default:
2149 errno = EAFNOSUPPORT;
2150 size = -1;
2151 goto done;
2152 }
2153 }
2154
2155 func_str = "vppcom_session_sendto";
2156
Dave Wallace2a865272018-02-07 21:00:42 -05002157 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002158 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2159 "sid %u (0x%x), buf %p, n %u, flags 0x%x, ep %p",
2160 getpid (), fd, fd, func_str, sid, sid, buf, n,
2161 flags, ep);
2162
2163 size = vppcom_session_sendto (sid, (void *) buf, n, flags, ep);
2164 if (size < 0)
2165 {
2166 errno = -size;
2167 size = -1;
2168 }
2169 }
2170 else
2171 {
2172 func_str = "libc_sendto";
2173
Dave Wallace2a865272018-02-07 21:00:42 -05002174 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002175 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2176 "buf %p, n %u, flags 0x%x, addr %p, addr_len %d",
2177 getpid (), fd, fd, func_str, buf, n, flags,
2178 addr, addr_len);
2179
2180 size = libc_sendto (fd, buf, n, flags, addr, addr_len);
2181 }
2182
2183done:
Dave Wallace2a865272018-02-07 21:00:42 -05002184 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002185 {
2186 if (size < 0)
2187 {
2188 int errno_val = errno;
2189 perror (func_str);
2190 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2191 "rv %d, errno = %d", getpid (), fd, fd,
2192 func_str, size, errno_val);
2193 errno = errno_val;
2194 }
2195 else
2196 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2197 getpid (), fd, fd, size, size);
2198 }
2199 return size;
2200}
2201
2202ssize_t
2203recvfrom (int fd, void *__restrict buf, size_t n, int flags,
2204 __SOCKADDR_ARG addr, socklen_t * __restrict addr_len)
2205{
2206 ssize_t size;
2207 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05002208 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05002209
Dave Wallace2a865272018-02-07 21:00:42 -05002210 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002211 return -1;
2212
2213 if (sid != INVALID_SESSION_ID)
2214 {
2215 vppcom_endpt_t ep;
2216 u8 src_addr[sizeof (struct sockaddr_in6)];
2217
2218 func_str = "vppcom_session_recvfrom";
2219
Dave Wallace2a865272018-02-07 21:00:42 -05002220 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002221 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2222 "sid %u (0x%x), buf %p, n %u, flags 0x%x, ep %p",
2223 getpid (), fd, fd, func_str, sid, sid, buf, n,
2224 flags, &ep);
2225 if (addr)
2226 {
2227 ep.ip = src_addr;
2228 size = vppcom_session_recvfrom (sid, buf, n, flags, &ep);
2229
2230 if (size > 0)
Dave Wallace2a865272018-02-07 21:00:42 -05002231 size = ldp_copy_ep_to_sockaddr (addr, addr_len, &ep);
Dave Wallace048b1d62018-01-03 22:24:41 -05002232 }
2233 else
2234 size = vppcom_session_recvfrom (sid, buf, n, flags, NULL);
2235
2236 if (size < 0)
2237 {
2238 errno = -size;
2239 size = -1;
2240 }
2241 }
2242 else
2243 {
2244 func_str = "libc_recvfrom";
2245
Dave Wallace2a865272018-02-07 21:00:42 -05002246 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002247 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2248 "buf %p, n %u, flags 0x%x, addr %p, addr_len %d",
2249 getpid (), fd, fd, func_str, buf, n, flags,
2250 addr, addr_len);
2251
2252 size = libc_recvfrom (fd, buf, n, flags, addr, addr_len);
2253 }
2254
Dave Wallace2a865272018-02-07 21:00:42 -05002255 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002256 {
2257 if (size < 0)
2258 {
2259 int errno_val = errno;
2260 perror (func_str);
2261 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2262 "rv %d, errno = %d", getpid (), fd, fd,
2263 func_str, size, errno_val);
2264 errno = errno_val;
2265 }
2266 else
2267 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2268 getpid (), fd, fd, size, size);
2269 }
2270 return size;
2271}
2272
2273ssize_t
2274sendmsg (int fd, const struct msghdr * message, int flags)
2275{
2276 ssize_t size;
2277 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05002278 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05002279
Dave Wallace2a865272018-02-07 21:00:42 -05002280 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002281 return -1;
2282
2283 if (sid != INVALID_SESSION_ID)
2284 {
Dave Wallace8aaba562018-01-18 17:21:19 -05002285 func_str = __func__;
2286
Dave Wallace048b1d62018-01-03 22:24:41 -05002287 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
2288 errno = ENOSYS;
2289 size = -1;
2290 }
2291 else
2292 {
2293 func_str = "libc_sendmsg";
2294
Dave Wallace2a865272018-02-07 21:00:42 -05002295 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002296 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2297 "message %p, flags 0x%x",
2298 getpid (), fd, fd, func_str, message, flags);
2299
2300 size = libc_sendmsg (fd, message, flags);
2301 }
2302
Dave Wallace2a865272018-02-07 21:00:42 -05002303 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002304 {
2305 if (size < 0)
2306 {
2307 int errno_val = errno;
2308 perror (func_str);
2309 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2310 "rv %d, errno = %d", getpid (), fd, fd,
2311 func_str, size, errno_val);
2312 errno = errno_val;
2313 }
2314 else
2315 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2316 getpid (), fd, fd, size, size);
2317 }
2318 return size;
2319}
2320
2321#ifdef USE_GNU
2322int
2323sendmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags)
2324{
2325 ssize_t size;
2326 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05002327 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05002328
Dave Wallace2a865272018-02-07 21:00:42 -05002329 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002330 return -1;
2331
2332 if (sid != INVALID_SESSION_ID)
2333 {
2334 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
2335 errno = ENOSYS;
2336 size = -1;
2337 }
2338 else
2339 {
2340 func_str = "libc_sendmmsg";
2341
Dave Wallace2a865272018-02-07 21:00:42 -05002342 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002343 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2344 "vmessages %p, vlen %u, flags 0x%x",
2345 getpid (), fd, fd, func_str, vmessages, vlen, flags);
2346
2347 size = libc_sendmmsg (fd, vmessages, vlen, flags);
2348 }
2349
Dave Wallace2a865272018-02-07 21:00:42 -05002350 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002351 {
2352 if (size < 0)
2353 {
2354 int errno_val = errno;
2355 perror (func_str);
2356 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2357 "rv %d, errno = %d", getpid (), fd, fd,
2358 func_str, size, errno_val);
2359 errno = errno_val;
2360 }
2361 else
2362 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2363 getpid (), fd, fd, size, size);
2364 }
2365 return size;
2366}
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002367#endif
2368
Dave Wallace048b1d62018-01-03 22:24:41 -05002369ssize_t
2370recvmsg (int fd, struct msghdr * message, int flags)
2371{
2372 ssize_t size;
2373 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05002374 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05002375
Dave Wallace2a865272018-02-07 21:00:42 -05002376 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002377 return -1;
2378
2379 if (sid != INVALID_SESSION_ID)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002380 {
Dave Wallace8aaba562018-01-18 17:21:19 -05002381 func_str = __func__;
2382
Dave Wallace048b1d62018-01-03 22:24:41 -05002383 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
2384 errno = ENOSYS;
2385 size = -1;
2386 }
2387 else
2388 {
2389 func_str = "libc_recvmsg";
2390
Dave Wallace2a865272018-02-07 21:00:42 -05002391 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002392 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2393 "message %p, flags 0x%x",
2394 getpid (), fd, fd, func_str, message, flags);
2395
2396 size = libc_recvmsg (fd, message, flags);
2397 }
2398
Dave Wallace2a865272018-02-07 21:00:42 -05002399 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002400 {
2401 if (size < 0)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002402 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002403 int errno_val = errno;
2404 perror (func_str);
2405 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2406 "rv %d, errno = %d", getpid (), fd, fd,
2407 func_str, size, errno_val);
2408 errno = errno_val;
2409 }
2410 else
2411 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2412 getpid (), fd, fd, size, size);
2413 }
2414 return size;
2415}
2416
2417#ifdef USE_GNU
2418int
2419recvmmsg (int fd, struct mmsghdr *vmessages,
2420 unsigned int vlen, int flags, struct timespec *tmo)
2421{
2422 ssize_t size;
2423 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05002424 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05002425
Dave Wallace2a865272018-02-07 21:00:42 -05002426 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002427 return -1;
2428
2429 if (sid != INVALID_SESSION_ID)
2430 {
2431 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
2432 errno = ENOSYS;
2433 size = -1;
2434 }
2435 else
2436 {
2437 func_str = "libc_recvmmsg";
2438
Dave Wallace2a865272018-02-07 21:00:42 -05002439 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002440 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2441 "vmessages %p, vlen %u, flags 0x%x, tmo %p",
2442 getpid (), fd, fd, func_str, vmessages, vlen,
2443 flags, tmo);
2444
2445 size = libc_recvmmsg (fd, vmessages, vlen, flags, tmo);
2446 }
2447
Dave Wallace2a865272018-02-07 21:00:42 -05002448 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002449 {
2450 if (size < 0)
2451 {
2452 int errno_val = errno;
2453 perror (func_str);
2454 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2455 "rv %d, errno = %d", getpid (), fd, fd,
2456 func_str, size, errno_val);
2457 errno = errno_val;
2458 }
2459 else
2460 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2461 getpid (), fd, fd, size, size);
2462 }
2463 return size;
2464}
2465#endif
2466
2467int
2468getsockopt (int fd, int level, int optname,
2469 void *__restrict optval, socklen_t * __restrict optlen)
2470{
2471 int rv;
2472 const char *func_str = __func__;
Dave Wallace2a865272018-02-07 21:00:42 -05002473 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace8aaba562018-01-18 17:21:19 -05002474 u32 buflen = optlen ? (u32) * optlen : 0;
Dave Wallace048b1d62018-01-03 22:24:41 -05002475
Dave Wallace2a865272018-02-07 21:00:42 -05002476 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002477 return -1;
2478
2479 if (sid != INVALID_SESSION_ID)
2480 {
2481 rv = -EOPNOTSUPP;
2482
2483 switch (level)
2484 {
2485 case SOL_TCP:
2486 switch (optname)
2487 {
2488 case TCP_NODELAY:
2489 func_str = "vppcom_session_attr[SOL_TCP,GET_TCP_NODELAY]";
Dave Wallace2a865272018-02-07 21:00:42 -05002490 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002491 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2492 "sid %u (0x%x)",
2493 getpid (), fd, fd, func_str, sid, sid);
2494 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_TCP_NODELAY,
2495 optval, optlen);
2496 break;
2497 case TCP_MAXSEG:
2498 func_str = "vppcom_session_attr[SOL_TCP,GET_TCP_USER_MSS]";
Dave Wallace2a865272018-02-07 21:00:42 -05002499 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002500 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2501 "sid %u (0x%x)",
2502 getpid (), fd, fd, func_str, sid, sid);
2503 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_TCP_USER_MSS,
2504 optval, optlen);
2505 break;
2506 case TCP_KEEPIDLE:
2507 func_str = "vppcom_session_attr[SOL_TCP,GET_TCP_KEEPIDLE]";
Dave Wallace2a865272018-02-07 21:00:42 -05002508 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002509 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2510 "sid %u (0x%x)",
2511 getpid (), fd, fd, func_str, sid, sid);
2512 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_TCP_KEEPIDLE,
2513 optval, optlen);
2514 break;
2515 case TCP_KEEPINTVL:
2516 func_str = "vppcom_session_attr[SOL_TCP,GET_TCP_KEEPINTVL]";
Dave Wallace2a865272018-02-07 21:00:42 -05002517 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002518 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2519 "sid %u (0x%x), SOL_TCP",
2520 getpid (), fd, fd, func_str, sid, sid);
2521 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_TCP_KEEPINTVL,
2522 optval, optlen);
2523 break;
2524 case TCP_INFO:
2525 if (optval && optlen && (*optlen == sizeof (struct tcp_info)))
2526 {
Dave Wallace2a865272018-02-07 21:00:42 -05002527 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002528 clib_warning ("LDP<%d>: fd %d (0x%x): sid %u (0x%x), "
2529 "SOL_TCP, TCP_INFO, optval %p, "
2530 "optlen %d: #LDP-NOP#",
2531 getpid (), fd, fd, sid, sid,
2532 optval, *optlen);
2533 memset (optval, 0, *optlen);
2534 rv = VPPCOM_OK;
2535 }
2536 else
2537 rv = -EFAULT;
2538 break;
2539 default:
Dave Wallace2a865272018-02-07 21:00:42 -05002540 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002541 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
2542 "sid %u (0x%x), SOL_TCP, "
2543 "optname %d unsupported!",
2544 getpid (), fd, fd, func_str, sid, sid, optname);
2545 break;
2546 }
2547 break;
2548 case SOL_IPV6:
2549 switch (optname)
2550 {
2551 case IPV6_V6ONLY:
2552 func_str = "vppcom_session_attr[SOL_IPV6,GET_V6ONLY]";
Dave Wallace2a865272018-02-07 21:00:42 -05002553 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002554 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2555 "sid %u (0x%x)",
2556 getpid (), fd, fd, func_str, sid, sid);
2557 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_V6ONLY,
2558 optval, optlen);
2559 break;
2560 default:
Dave Wallace2a865272018-02-07 21:00:42 -05002561 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002562 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
2563 "sid %u (0x%x), SOL_IPV6, "
2564 "optname %d unsupported!",
2565 getpid (), fd, fd, func_str, sid, sid, optname);
2566 break;
2567 }
2568 break;
2569 case SOL_SOCKET:
2570 switch (optname)
2571 {
2572 case SO_ACCEPTCONN:
2573 func_str = "vppcom_session_attr[SOL_SOCKET,GET_ACCEPTCONN]";
Dave Wallace2a865272018-02-07 21:00:42 -05002574 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002575 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2576 "sid %u (0x%x)",
2577 getpid (), fd, fd, func_str, sid, sid);
2578 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_LISTEN,
2579 optval, optlen);
2580 break;
2581 case SO_KEEPALIVE:
2582 func_str = "vppcom_session_attr[SOL_SOCKET,GET_KEEPALIVE]";
Dave Wallace2a865272018-02-07 21:00:42 -05002583 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002584 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2585 "sid %u (0x%x)",
2586 getpid (), fd, fd, func_str, sid, sid);
2587 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_KEEPALIVE,
2588 optval, optlen);
2589 break;
2590 case SO_PROTOCOL:
2591 func_str = "vppcom_session_attr[SOL_SOCKET,GET_PROTOCOL]";
Dave Wallace2a865272018-02-07 21:00:42 -05002592 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002593 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2594 "sid %u (0x%x)",
2595 getpid (), fd, fd, func_str, sid, sid);
2596 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_PROTOCOL,
2597 optval, optlen);
2598 *(int *) optval = *(int *) optval ? SOCK_DGRAM : SOCK_STREAM;
2599 break;
2600 case SO_SNDBUF:
2601 func_str = "vppcom_session_attr[SOL_SOCKET,GET_TX_FIFO_LEN]";
Dave Wallace2a865272018-02-07 21:00:42 -05002602 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002603 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2604 "sid %u (0x%x), optlen %d",
2605 getpid (), fd, fd, func_str, sid, sid, buflen);
2606 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_TX_FIFO_LEN,
2607 optval, optlen);
2608 break;
2609 case SO_RCVBUF:
2610 func_str = "vppcom_session_attr[SOL_SOCKET,GET_RX_FIFO_LEN]";
Dave Wallace2a865272018-02-07 21:00:42 -05002611 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002612 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2613 "sid %u (0x%x), optlen %d",
Dave Wallaceb4cd4ff2018-01-19 12:17:08 -05002614 getpid (), fd, fd, func_str, sid, sid, buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002615 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_RX_FIFO_LEN,
2616 optval, optlen);
2617 break;
2618 case SO_REUSEADDR:
2619 func_str = "vppcom_session_attr[SOL_SOCKET,GET_REUSEADDR]";
Dave Wallace2a865272018-02-07 21:00:42 -05002620 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002621 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2622 "sid %u (0x%x)",
2623 getpid (), fd, fd, func_str, sid, sid);
2624 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_REUSEADDR,
2625 optval, optlen);
2626 break;
2627 case SO_BROADCAST:
2628 func_str = "vppcom_session_attr[SOL_SOCKET,GET_BROADCAST]";
Dave Wallace2a865272018-02-07 21:00:42 -05002629 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002630 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2631 "sid %u (0x%x)",
2632 getpid (), fd, fd, func_str, sid, sid);
2633 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_BROADCAST,
2634 optval, optlen);
2635 break;
2636 case SO_ERROR:
2637 func_str = "vppcom_session_attr[SOL_SOCKET,GET_ERROR]";
Dave Wallace2a865272018-02-07 21:00:42 -05002638 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002639 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2640 "sid %u (0x%x)",
2641 getpid (), fd, fd, func_str, sid, sid);
2642 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_ERROR,
2643 optval, optlen);
2644 break;
2645 default:
Dave Wallace2a865272018-02-07 21:00:42 -05002646 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002647 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
2648 "sid %u (0x%x), SOL_SOCKET, "
2649 "optname %d unsupported!",
2650 getpid (), fd, fd, func_str, sid, sid, optname);
2651 break;
2652 }
2653 break;
2654 default:
2655 break;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002656 }
2657
Dave Wallace048b1d62018-01-03 22:24:41 -05002658 if (rv != VPPCOM_OK)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002659 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002660 errno = -rv;
2661 rv = -1;
2662 }
2663 }
2664 else
2665 {
2666 func_str = "libc_getsockopt";
2667
Dave Wallace2a865272018-02-07 21:00:42 -05002668 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002669 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): level %d, "
2670 "optname %d, optval %p, optlen %d",
2671 getpid (), fd, fd, func_str, level, optname,
2672 optval, optlen);
2673
2674 rv = libc_getsockopt (fd, level, optname, optval, optlen);
2675 }
2676
Dave Wallace2a865272018-02-07 21:00:42 -05002677 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002678 {
2679 if (rv < 0)
2680 {
2681 int errno_val = errno;
2682 perror (func_str);
2683 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2684 "rv %d, errno = %d", getpid (), fd, fd,
2685 func_str, rv, errno_val);
2686 errno = errno_val;
2687 }
2688 else
2689 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2690 getpid (), fd, fd, rv, rv);
2691 }
2692 return rv;
2693}
2694
2695int
2696setsockopt (int fd, int level, int optname,
2697 const void *optval, socklen_t optlen)
2698{
2699 int rv;
2700 const char *func_str = __func__;
Dave Wallace2a865272018-02-07 21:00:42 -05002701 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05002702
Dave Wallace2a865272018-02-07 21:00:42 -05002703 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002704 return -1;
2705
2706 if (sid != INVALID_SESSION_ID)
2707 {
2708 rv = -EOPNOTSUPP;
2709
2710 switch (level)
2711 {
2712 case SOL_TCP:
2713 switch (optname)
2714 {
2715 case TCP_NODELAY:
2716 func_str = "vppcom_session_attr[SOL_TCP,SET_TCP_NODELAY]";
Dave Wallace2a865272018-02-07 21:00:42 -05002717 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002718 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2719 "sid %u (0x%x)",
2720 getpid (), fd, fd, func_str, sid, sid);
2721 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_TCP_NODELAY,
2722 (void *) optval, &optlen);
2723 break;
2724 case TCP_MAXSEG:
2725 func_str = "vppcom_session_attr[SOL_TCP,SET_TCP_USER_MSS]";
Dave Wallace2a865272018-02-07 21:00:42 -05002726 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002727 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2728 "sid %u (0x%x)",
2729 getpid (), fd, fd, func_str, sid, sid);
2730 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_TCP_USER_MSS,
2731 (void *) optval, &optlen);
2732 break;
2733 case TCP_KEEPIDLE:
2734 func_str = "vppcom_session_attr[SOL_TCP,SET_TCP_KEEPIDLE]";
Dave Wallace2a865272018-02-07 21:00:42 -05002735 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002736 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2737 "sid %u (0x%x)",
2738 getpid (), fd, fd, func_str, sid, sid);
2739 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_TCP_KEEPIDLE,
2740 (void *) optval, &optlen);
2741 break;
2742 case TCP_KEEPINTVL:
2743 func_str = "vppcom_session_attr[SOL_TCP,SET_TCP_KEEPINTVL]";
Dave Wallace2a865272018-02-07 21:00:42 -05002744 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002745 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2746 "sid %u (0x%x), SOL_TCP",
2747 getpid (), fd, fd, func_str, sid, sid);
2748 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_TCP_KEEPINTVL,
2749 (void *) optval, &optlen);
2750 break;
2751 default:
Dave Wallace2a865272018-02-07 21:00:42 -05002752 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002753 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
2754 "sid %u (0x%x), SOL_TCP, "
2755 "optname %d unsupported!",
2756 getpid (), fd, fd, func_str, sid, sid, optname);
2757 break;
2758 }
2759 break;
2760 case SOL_IPV6:
2761 switch (optname)
2762 {
2763 case IPV6_V6ONLY:
2764 func_str = "vppcom_session_attr[SOL_IPV6,SET_V6ONLY]";
Dave Wallace2a865272018-02-07 21:00:42 -05002765 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002766 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2767 "sid %u (0x%x)",
2768 getpid (), fd, fd, func_str, sid, sid);
2769 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_V6ONLY,
2770 (void *) optval, &optlen);
2771 break;
2772 default:
Dave Wallace2a865272018-02-07 21:00:42 -05002773 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002774 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
2775 "sid %u (0x%x), SOL_IPV6, "
2776 "optname %d unsupported!",
2777 getpid (), fd, fd, func_str, sid, sid, optname);
2778 break;
2779 }
2780 break;
2781 case SOL_SOCKET:
2782 switch (optname)
2783 {
2784 case SO_KEEPALIVE:
2785 func_str = "vppcom_session_attr[SOL_SOCKET,SET_KEEPALIVE]";
Dave Wallace2a865272018-02-07 21:00:42 -05002786 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002787 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2788 "sid %u (0x%x)",
2789 getpid (), fd, fd, func_str, sid, sid);
2790 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_KEEPALIVE,
2791 (void *) optval, &optlen);
2792 break;
2793 case SO_REUSEADDR:
2794 func_str = "vppcom_session_attr[SOL_SOCKET,SET_REUSEADDR]";
Dave Wallace2a865272018-02-07 21:00:42 -05002795 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002796 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2797 "sid %u (0x%x)",
2798 getpid (), fd, fd, func_str, sid, sid);
2799 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_REUSEADDR,
2800 (void *) optval, &optlen);
2801 break;
2802 case SO_BROADCAST:
2803 func_str = "vppcom_session_attr[SOL_SOCKET,SET_BROADCAST]";
Dave Wallace2a865272018-02-07 21:00:42 -05002804 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002805 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2806 "sid %u (0x%x)",
2807 getpid (), fd, fd, func_str, sid, sid);
2808 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_BROADCAST,
2809 (void *) optval, &optlen);
2810 break;
2811 default:
Dave Wallace2a865272018-02-07 21:00:42 -05002812 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002813 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
2814 "sid %u (0x%x), SOL_SOCKET, "
2815 "optname %d unsupported!",
2816 getpid (), fd, fd, func_str, sid, sid, optname);
2817 break;
2818 }
2819 break;
2820 default:
2821 break;
2822 }
2823
2824 if (rv != VPPCOM_OK)
2825 {
2826 errno = -rv;
2827 rv = -1;
2828 }
2829 }
2830 else
2831 {
2832 func_str = "libc_setsockopt";
2833
Dave Wallace2a865272018-02-07 21:00:42 -05002834 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002835 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): level %d, "
2836 "optname %d, optval %p, optlen %d",
2837 getpid (), fd, fd, func_str, level, optname,
2838 optval, optlen);
2839
2840 rv = libc_setsockopt (fd, level, optname, optval, optlen);
2841 }
2842
Dave Wallace2a865272018-02-07 21:00:42 -05002843 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002844 {
2845 if (rv < 0)
2846 {
2847 int errno_val = errno;
2848 perror (func_str);
2849 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2850 "rv %d, errno = %d", getpid (), fd, fd,
2851 func_str, rv, errno_val);
2852 errno = errno_val;
2853 }
2854 else
2855 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2856 getpid (), fd, fd, rv, rv);
2857 }
2858 return rv;
2859}
2860
2861int
2862listen (int fd, int n)
2863{
2864 int rv;
2865 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05002866 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05002867
Dave Wallace2a865272018-02-07 21:00:42 -05002868 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002869 return -1;
2870
2871 if (sid != INVALID_SESSION_ID)
2872 {
2873 func_str = "vppcom_session_listen";
2874
Florin Coras99368312018-08-02 10:45:44 -07002875 LDBG (0, "LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), n %d",
2876 getpid (), fd, fd, func_str, sid, sid, n);
Dave Wallace048b1d62018-01-03 22:24:41 -05002877
2878 rv = vppcom_session_listen (sid, n);
2879 if (rv != VPPCOM_OK)
2880 {
2881 errno = -rv;
2882 rv = -1;
2883 }
2884 }
2885 else
2886 {
2887 func_str = "libc_listen";
2888
Florin Coras99368312018-08-02 10:45:44 -07002889 LDBG (0, "LDP<%d>: fd %d (0x%x): calling %s(): n %d", getpid (), fd,
2890 fd, func_str, n);
Dave Wallace048b1d62018-01-03 22:24:41 -05002891
2892 rv = libc_listen (fd, n);
2893 }
2894
Dave Wallace2a865272018-02-07 21:00:42 -05002895 if (LDP_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002896 {
2897 if (rv < 0)
2898 {
2899 int errno_val = errno;
2900 perror (func_str);
2901 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2902 "rv %d, errno = %d", getpid (), fd, fd,
2903 func_str, rv, errno_val);
2904 errno = errno_val;
2905 }
2906 else
2907 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2908 getpid (), fd, fd, rv, rv);
2909 }
2910 return rv;
2911}
2912
2913static inline int
Dave Wallace2a865272018-02-07 21:00:42 -05002914ldp_accept4 (int listen_fd, __SOCKADDR_ARG addr,
2915 socklen_t * __restrict addr_len, int flags)
Dave Wallace048b1d62018-01-03 22:24:41 -05002916{
2917 int rv;
2918 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05002919 u32 listen_sid = ldp_sid_from_fd (listen_fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05002920 int accept_sid;
2921
Dave Wallace2a865272018-02-07 21:00:42 -05002922 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002923 return -1;
2924
2925 if (listen_sid != INVALID_SESSION_ID)
2926 {
2927 vppcom_endpt_t ep;
2928 u8 src_addr[sizeof (struct sockaddr_in6)];
Dave Wallace8aaba562018-01-18 17:21:19 -05002929 memset (&ep, 0, sizeof (ep));
Dave Wallace048b1d62018-01-03 22:24:41 -05002930 ep.ip = src_addr;
2931
2932 func_str = "vppcom_session_accept";
2933
Dave Wallace2a865272018-02-07 21:00:42 -05002934 if (LDP_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002935 clib_warning ("LDP<%d>: listen fd %d (0x%x): calling %s(): "
2936 "listen sid %u (0x%x), ep %p, flags 0x%x",
2937 getpid (), listen_fd, listen_fd, func_str,
2938 listen_sid, listen_sid, ep, flags);
2939
2940 accept_sid = vppcom_session_accept (listen_sid, &ep, flags);
2941 if (accept_sid < 0)
2942 {
2943 errno = -accept_sid;
2944 rv = -1;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002945 }
2946 else
2947 {
Dave Wallace2a865272018-02-07 21:00:42 -05002948 rv = ldp_copy_ep_to_sockaddr (addr, addr_len, &ep);
Dave Wallace048b1d62018-01-03 22:24:41 -05002949 if (rv != VPPCOM_OK)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002950 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002951 (void) vppcom_session_close ((u32) accept_sid);
2952 errno = -rv;
2953 rv = -1;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002954 }
Dave Wallace048b1d62018-01-03 22:24:41 -05002955 else
2956 {
Dave Wallace2a865272018-02-07 21:00:42 -05002957 func_str = "ldp_fd_from_sid";
2958 if (LDP_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002959 clib_warning ("LDP<%d>: listen fd %d (0x%x): calling %s(): "
2960 "accept sid %u (0x%x), ep %p, flags 0x%x",
2961 getpid (), listen_fd, listen_fd,
2962 func_str, accept_sid, accept_sid, ep, flags);
Florin Coras30e273b2018-11-27 00:04:59 -08002963 rv = ldp_fd_alloc ((u32) accept_sid);
Dave Wallace048b1d62018-01-03 22:24:41 -05002964 if (rv < 0)
2965 {
2966 (void) vppcom_session_close ((u32) accept_sid);
2967 errno = -rv;
2968 rv = -1;
2969 }
2970 }
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002971 }
2972 }
Dave Wallace048b1d62018-01-03 22:24:41 -05002973 else
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002974 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002975 func_str = "libc_accept4";
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002976
Dave Wallace2a865272018-02-07 21:00:42 -05002977 if (LDP_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002978 clib_warning ("LDP<%d>: listen fd %d (0x%x): calling %s(): "
2979 "addr %p, addr_len %p, flags 0x%x",
2980 getpid (), listen_fd, listen_fd, func_str,
2981 addr, addr_len, flags);
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002982
Dave Wallace048b1d62018-01-03 22:24:41 -05002983 rv = libc_accept4 (listen_fd, addr, addr_len, flags);
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002984 }
2985
Dave Wallace2a865272018-02-07 21:00:42 -05002986 if (LDP_DEBUG > 0)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002987 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002988 if (rv < 0)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002989 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002990 int errno_val = errno;
2991 perror (func_str);
2992 clib_warning ("LDP<%d>: ERROR: listen fd %d (0x%x): %s() failed! "
2993 "rv %d, errno = %d", getpid (), listen_fd,
2994 listen_fd, func_str, rv, errno_val);
2995 errno = errno_val;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002996 }
Dave Wallace048b1d62018-01-03 22:24:41 -05002997 else
2998 clib_warning ("LDP<%d>: listen fd %d (0x%x): returning %d (0x%x)",
2999 getpid (), listen_fd, listen_fd, rv, rv);
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07003000 }
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07003001 return rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003002}
3003
Dave Wallace048b1d62018-01-03 22:24:41 -05003004int
3005accept4 (int fd, __SOCKADDR_ARG addr, socklen_t * __restrict addr_len,
3006 int flags)
3007{
Dave Wallace2a865272018-02-07 21:00:42 -05003008 return ldp_accept4 (fd, addr, addr_len, flags);
Dave Wallace048b1d62018-01-03 22:24:41 -05003009}
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07003010
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003011int
Dave Wallace048b1d62018-01-03 22:24:41 -05003012accept (int fd, __SOCKADDR_ARG addr, socklen_t * __restrict addr_len)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003013{
Dave Wallace2a865272018-02-07 21:00:42 -05003014 return ldp_accept4 (fd, addr, addr_len, 0);
Dave Wallace048b1d62018-01-03 22:24:41 -05003015}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003016
Dave Wallace048b1d62018-01-03 22:24:41 -05003017int
3018shutdown (int fd, int how)
3019{
3020 int rv;
3021 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05003022 u32 sid = ldp_sid_from_fd (fd);
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07003023
Dave Wallace2a865272018-02-07 21:00:42 -05003024 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05003025 return -1;
3026
3027 if (sid != INVALID_SESSION_ID)
3028 {
Florin Coras6917b942018-11-13 22:44:54 -08003029 func_str = "vppcom_session_close[TODO]";
3030 rv = close (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05003031 }
3032 else
3033 {
3034 func_str = "libc_shutdown";
3035
Dave Wallace2a865272018-02-07 21:00:42 -05003036 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05003037 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): how %d",
3038 getpid (), fd, fd, func_str, how);
3039
3040 rv = libc_shutdown (fd, how);
3041 }
3042
Dave Wallace2a865272018-02-07 21:00:42 -05003043 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05003044 {
3045 if (rv < 0)
3046 {
3047 int errno_val = errno;
3048 perror (func_str);
3049 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
3050 "rv %d, errno = %d", getpid (), fd, fd,
3051 func_str, rv, errno_val);
3052 errno = errno_val;
3053 }
3054 else
3055 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
3056 getpid (), fd, fd, rv, rv);
3057 }
3058 return rv;
3059}
3060
3061int
3062epoll_create1 (int flags)
3063{
Florin Corasdfe4cf42018-11-28 22:13:45 -08003064 ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
Dave Wallace048b1d62018-01-03 22:24:41 -05003065 const char *func_str;
3066 int rv;
3067
Dave Wallace2a865272018-02-07 21:00:42 -05003068 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05003069 return -1;
3070
Florin Coras99368312018-08-02 10:45:44 -07003071 if (ldp->vcl_needs_real_epoll)
3072 {
3073 rv = libc_epoll_create1 (flags);
3074 ldp->vcl_needs_real_epoll = 0;
Florin Corasdfe4cf42018-11-28 22:13:45 -08003075 ldpw->vcl_mq_epfd = rv;
Florin Coras99368312018-08-02 10:45:44 -07003076 LDBG (0, "LDP<%d>: created vcl epfd %u", getpid (), rv);
3077 return rv;
3078 }
Dave Wallace048b1d62018-01-03 22:24:41 -05003079 func_str = "vppcom_epoll_create";
3080
Florin Coras99368312018-08-02 10:45:44 -07003081 LDBG (1, "LDP<%d>: calling %s()", getpid (), func_str);
Dave Wallace048b1d62018-01-03 22:24:41 -05003082
3083 rv = vppcom_epoll_create ();
3084
3085 if (PREDICT_FALSE (rv < 0))
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07003086 {
3087 errno = -rv;
Dave Wallace048b1d62018-01-03 22:24:41 -05003088 rv = -1;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07003089 }
Dave Wallace048b1d62018-01-03 22:24:41 -05003090 else
Florin Coras30e273b2018-11-27 00:04:59 -08003091 rv = ldp_fd_alloc ((u32) rv);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003092
Dave Wallace2a865272018-02-07 21:00:42 -05003093 if (LDP_DEBUG > 1)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003094 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003095 if (rv < 0)
3096 {
3097 int errno_val = errno;
3098 perror (func_str);
3099 clib_warning ("LDP<%d>: ERROR: %s() failed! "
3100 "rv %d, errno = %d",
3101 getpid (), func_str, rv, errno_val);
3102 errno = errno_val;
3103 }
3104 else
3105 clib_warning ("LDP<%d>: returning epfd %d (0x%x)", getpid (), rv, rv);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003106 }
Dave Wallace048b1d62018-01-03 22:24:41 -05003107 return rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003108}
3109
3110int
Dave Wallace048b1d62018-01-03 22:24:41 -05003111epoll_create (int size)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003112{
Dave Wallace048b1d62018-01-03 22:24:41 -05003113 return epoll_create1 (0);
3114}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003115
Dave Wallace048b1d62018-01-03 22:24:41 -05003116int
3117epoll_ctl (int epfd, int op, int fd, struct epoll_event *event)
3118{
Florin Coras99368312018-08-02 10:45:44 -07003119 u32 vep_idx = ldp_sid_from_fd (epfd), sid;
Dave Wallace048b1d62018-01-03 22:24:41 -05003120 const char *func_str;
Florin Coras99368312018-08-02 10:45:44 -07003121 int rv;
Dave Wallace048b1d62018-01-03 22:24:41 -05003122
Dave Wallace2a865272018-02-07 21:00:42 -05003123 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05003124 return -1;
3125
Florin Coras99368312018-08-02 10:45:44 -07003126 if (PREDICT_FALSE (vep_idx == INVALID_SESSION_ID))
Dave Wallace048b1d62018-01-03 22:24:41 -05003127 {
Dave Wallace3ee1fe12018-02-23 01:09:11 -05003128 /* The LDP epoll_create1 always creates VCL epfd's.
3129 * The app should never have a kernel base epoll fd unless it
3130 * was acquired outside of the LD_PRELOAD process context.
3131 * In any case, if we get one, punt it to libc_epoll_ctl.
3132 */
Dave Wallace048b1d62018-01-03 22:24:41 -05003133 func_str = "libc_epoll_ctl";
3134
Florin Coras99368312018-08-02 10:45:44 -07003135 LDBG (1, "LDP<%d>: epfd %d (0x%x): calling %s(): op %d, fd %d (0x%x),"
3136 " event %p", getpid (), epfd, epfd, func_str, op, fd, fd, event);
Dave Wallace048b1d62018-01-03 22:24:41 -05003137
3138 rv = libc_epoll_ctl (epfd, op, fd, event);
Florin Coras99368312018-08-02 10:45:44 -07003139 goto done;
3140 }
3141
3142 sid = ldp_sid_from_fd (fd);
3143
3144 LDBG (0, "LDP<%d>: epfd %d (0x%x), vep_idx %d (0x%x), sid %d (0x%x)",
3145 getpid (), epfd, epfd, vep_idx, vep_idx, sid, sid);
3146
3147 if (sid != INVALID_SESSION_ID)
3148 {
3149 func_str = "vppcom_epoll_ctl";
3150
3151 LDBG (1, "LDP<%d>: epfd %d (0x%x): calling %s(): vep_idx %d (0x%x),"
3152 " op %d, sid %u (0x%x), event %p", getpid (), epfd, epfd,
3153 func_str, vep_idx, vep_idx, sid, sid, event);
3154
3155 rv = vppcom_epoll_ctl (vep_idx, op, sid, event);
3156 if (rv != VPPCOM_OK)
3157 {
3158 errno = -rv;
3159 rv = -1;
3160 }
3161 }
3162 else
3163 {
3164 int libc_epfd;
3165 u32 size = sizeof (epfd);
3166
3167 func_str = "vppcom_session_attr[GET_LIBC_EPFD]";
3168 libc_epfd = vppcom_session_attr (vep_idx, VPPCOM_ATTR_GET_LIBC_EPFD, 0,
3169 0);
3170 LDBG (1, "LDP<%d>: epfd %d (0x%x), vep_idx %d (0x%x): %s() "
3171 "returned libc_epfd %d (0x%x)", getpid (), epfd, epfd,
3172 vep_idx, vep_idx, func_str, libc_epfd, libc_epfd);
3173
3174 if (!libc_epfd)
3175 {
3176 func_str = "libc_epoll_create1";
3177
3178 LDBG (1, "LDP<%d>: epfd %d (0x%x), vep_idx %d (0x%x): "
3179 "calling %s(): EPOLL_CLOEXEC", getpid (), epfd, epfd,
3180 vep_idx, vep_idx, func_str);
3181
3182 libc_epfd = libc_epoll_create1 (EPOLL_CLOEXEC);
3183 if (libc_epfd < 0)
3184 {
3185 rv = libc_epfd;
3186 goto done;
3187 }
3188
3189 func_str = "vppcom_session_attr[SET_LIBC_EPFD]";
3190 LDBG (1, "LDP<%d>: epfd %d (0x%x): calling %s(): vep_idx %d (0x%x),"
3191 " VPPCOM_ATTR_SET_LIBC_EPFD, libc_epfd %d (0x%x), size %d",
3192 getpid (), epfd, epfd, func_str, vep_idx, vep_idx, libc_epfd,
3193 libc_epfd, size);
3194
3195 rv = vppcom_session_attr (vep_idx, VPPCOM_ATTR_SET_LIBC_EPFD,
3196 &libc_epfd, &size);
3197 if (rv < 0)
3198 {
3199 errno = -rv;
3200 rv = -1;
3201 goto done;
3202 }
3203 }
3204 else if (PREDICT_FALSE (libc_epfd < 0))
3205 {
3206 errno = -epfd;
3207 rv = -1;
3208 goto done;
3209 }
3210
3211 func_str = "libc_epoll_ctl";
3212
3213 LDBG (1, "LDP<%d>: epfd %d (0x%x): calling %s(): libc_epfd %d (0x%x), "
3214 "op %d, fd %d (0x%x), event %p", getpid (), epfd, epfd, func_str,
3215 libc_epfd, libc_epfd, op, fd, fd, event);
3216
3217 rv = libc_epoll_ctl (libc_epfd, op, fd, event);
Dave Wallace048b1d62018-01-03 22:24:41 -05003218 }
3219
3220done:
Dave Wallace2a865272018-02-07 21:00:42 -05003221 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05003222 {
3223 if (rv < 0)
3224 {
3225 int errno_val = errno;
3226 perror (func_str);
3227 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
3228 "rv %d, errno = %d", getpid (), fd, fd,
3229 func_str, rv, errno_val);
3230 errno = errno_val;
3231 }
3232 else
3233 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
3234 getpid (), fd, fd, rv, rv);
3235 }
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003236 return rv;
3237}
Dave Wallace048b1d62018-01-03 22:24:41 -05003238
3239static inline int
Florin Coras99368312018-08-02 10:45:44 -07003240ldp_epoll_pwait (int epfd, struct epoll_event *events, int maxevents,
3241 int timeout, const sigset_t * sigmask)
Dave Wallace048b1d62018-01-03 22:24:41 -05003242{
Florin Corasdfe4cf42018-11-28 22:13:45 -08003243 ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
Florin Coras99368312018-08-02 10:45:44 -07003244 double time_to_wait = (double) 0, time_out, now = 0;
Dave Wallace2a865272018-02-07 21:00:42 -05003245 u32 vep_idx = ldp_sid_from_fd (epfd);
Florin Coras99368312018-08-02 10:45:44 -07003246 int libc_epfd, rv = 0;
3247 const char *func_str;
Dave Wallace048b1d62018-01-03 22:24:41 -05003248
Dave Wallace2a865272018-02-07 21:00:42 -05003249 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05003250 return -1;
3251
3252 if (PREDICT_FALSE (!events || (timeout < -1)))
3253 {
3254 errno = EFAULT;
3255 return -1;
3256 }
3257
Florin Corasdfe4cf42018-11-28 22:13:45 -08003258 if (epfd == ldpw->vcl_mq_epfd)
Florin Coras99368312018-08-02 10:45:44 -07003259 return libc_epoll_pwait (epfd, events, maxevents, timeout, sigmask);
3260
Dave Wallace048b1d62018-01-03 22:24:41 -05003261 if (PREDICT_FALSE (vep_idx == INVALID_SESSION_ID))
3262 {
3263 clib_warning ("LDP<%d>: ERROR: epfd %d (0x%x): bad vep_idx %d (0x%x)!",
3264 getpid (), epfd, epfd, vep_idx, vep_idx);
3265 errno = EBADFD;
3266 return -1;
3267 }
3268
Florin Coras54693d22018-07-17 10:46:29 -07003269 time_to_wait = ((timeout >= 0) ? (double) timeout : 0);
Florin Corasdfe4cf42018-11-28 22:13:45 -08003270 time_out = clib_time_now (&ldpw->clib_time) + time_to_wait;
Dave Wallace048b1d62018-01-03 22:24:41 -05003271
3272 func_str = "vppcom_session_attr[GET_LIBC_EPFD]";
3273 libc_epfd = vppcom_session_attr (vep_idx, VPPCOM_ATTR_GET_LIBC_EPFD, 0, 0);
3274 if (PREDICT_FALSE (libc_epfd < 0))
3275 {
3276 errno = -libc_epfd;
3277 rv = -1;
3278 goto done;
3279 }
3280
Florin Coras99368312018-08-02 10:45:44 -07003281 LDBG (2, "LDP<%d>: epfd %d (0x%x): vep_idx %d (0x%x), libc_epfd %d (0x%x), "
3282 "events %p, maxevents %d, timeout %d, sigmask %p: time_to_wait %.02f",
3283 getpid (), epfd, epfd, vep_idx, vep_idx, libc_epfd, libc_epfd, events,
3284 maxevents, timeout, sigmask, time_to_wait, time_out);
Dave Wallace048b1d62018-01-03 22:24:41 -05003285 do
3286 {
Florin Corasdfe4cf42018-11-28 22:13:45 -08003287 if (!ldpw->epoll_wait_vcl)
Dave Wallace048b1d62018-01-03 22:24:41 -05003288 {
3289 func_str = "vppcom_epoll_wait";
3290
Florin Coras99368312018-08-02 10:45:44 -07003291 LDBG (3, "LDP<%d>: epfd %d (0x%x): calling %s(): vep_idx %d (0x%x),"
3292 " events %p, maxevents %d", getpid (), epfd, epfd, func_str,
3293 vep_idx, vep_idx, events, maxevents);
Dave Wallace048b1d62018-01-03 22:24:41 -05003294
3295 rv = vppcom_epoll_wait (vep_idx, events, maxevents, 0);
3296 if (rv > 0)
3297 {
Florin Corasdfe4cf42018-11-28 22:13:45 -08003298 ldpw->epoll_wait_vcl = 1;
Dave Wallace048b1d62018-01-03 22:24:41 -05003299 goto done;
3300 }
3301 else if (rv < 0)
3302 {
3303 errno = -rv;
3304 rv = -1;
3305 goto done;
3306 }
3307 }
3308 else
Florin Corasdfe4cf42018-11-28 22:13:45 -08003309 ldpw->epoll_wait_vcl = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -05003310
3311 if (libc_epfd > 0)
3312 {
3313 func_str = "libc_epoll_pwait";
3314
Florin Coras99368312018-08-02 10:45:44 -07003315 LDBG (3, "LDP<%d>: epfd %d (0x%x): calling %s(): libc_epfd %d "
3316 "(0x%x), events %p, maxevents %d, sigmask %p", getpid (),
3317 epfd, epfd, func_str, libc_epfd, libc_epfd, events,
3318 maxevents, sigmask);
Dave Wallace048b1d62018-01-03 22:24:41 -05003319
Keith Burns (alagalah)5368efa2018-02-07 13:20:28 -08003320 rv = libc_epoll_pwait (libc_epfd, events, maxevents, 1, sigmask);
Dave Wallace048b1d62018-01-03 22:24:41 -05003321 if (rv != 0)
3322 goto done;
3323 }
3324
3325 if (timeout != -1)
Florin Corasdfe4cf42018-11-28 22:13:45 -08003326 now = clib_time_now (&ldpw->clib_time);
Dave Wallace048b1d62018-01-03 22:24:41 -05003327 }
3328 while (now < time_out);
3329
3330done:
Dave Wallace2a865272018-02-07 21:00:42 -05003331 if (LDP_DEBUG > 3)
Dave Wallace048b1d62018-01-03 22:24:41 -05003332 {
Keith Burns (alagalah)5368efa2018-02-07 13:20:28 -08003333 if (libc_epfd > 0)
3334 epfd = libc_epfd;
Dave Wallace048b1d62018-01-03 22:24:41 -05003335 if (rv < 0)
3336 {
3337 int errno_val = errno;
3338 perror (func_str);
3339 clib_warning ("LDP<%d>: ERROR: epfd %d (0x%x): %s() failed! "
3340 "rv %d, errno = %d", getpid (), epfd, epfd,
3341 func_str, rv, errno_val);
3342 errno = errno_val;
3343 }
3344 else
3345 clib_warning ("LDP<%d>: epfd %d (0x%x): returning %d (0x%x)",
3346 getpid (), epfd, epfd, rv, rv);
3347 }
3348 return rv;
3349}
3350
3351int
3352epoll_pwait (int epfd, struct epoll_event *events,
3353 int maxevents, int timeout, const sigset_t * sigmask)
3354{
Dave Wallace2a865272018-02-07 21:00:42 -05003355 return ldp_epoll_pwait (epfd, events, maxevents, timeout, sigmask);
Dave Wallace048b1d62018-01-03 22:24:41 -05003356}
3357
3358int
3359epoll_wait (int epfd, struct epoll_event *events, int maxevents, int timeout)
3360{
Dave Wallace2a865272018-02-07 21:00:42 -05003361 return ldp_epoll_pwait (epfd, events, maxevents, timeout, NULL);
Dave Wallace048b1d62018-01-03 22:24:41 -05003362}
3363
3364int
3365poll (struct pollfd *fds, nfds_t nfds, int timeout)
3366{
Florin Corasdfe4cf42018-11-28 22:13:45 -08003367 ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
Dave Wallace048b1d62018-01-03 22:24:41 -05003368 const char *func_str = __func__;
Florin Coras6917b942018-11-13 22:44:54 -08003369 int rv, i, n_revents = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -05003370 u32 sid;
3371 vcl_poll_t *vp;
3372 double wait_for_time;
3373
Florin Coras6917b942018-11-13 22:44:54 -08003374 LDBG (3, "LDP<%d>: fds %p, nfds %d, timeout %d", getpid (), fds, nfds,
3375 timeout);
Dave Wallace048b1d62018-01-03 22:24:41 -05003376
3377 if (timeout >= 0)
3378 wait_for_time = (f64) timeout / 1000;
3379 else
3380 wait_for_time = -1;
3381
Dave Wallace048b1d62018-01-03 22:24:41 -05003382 for (i = 0; i < nfds; i++)
3383 {
Florin Coras6917b942018-11-13 22:44:54 -08003384 if (fds[i].fd < 0)
3385 continue;
Dave Wallace048b1d62018-01-03 22:24:41 -05003386
Florin Coras6917b942018-11-13 22:44:54 -08003387 LDBG (3, "LDP<%d>: fds[%d] fd %d (0x%0x) events = 0x%x revents = 0x%x",
3388 getpid (), i, fds[i].fd, fds[i].fd, fds[i].events,
3389 fds[i].revents);
3390
3391 sid = ldp_sid_from_fd (fds[i].fd);
3392 if (sid != INVALID_SESSION_ID)
3393 {
3394 fds[i].fd = -fds[i].fd;
Florin Corasdfe4cf42018-11-28 22:13:45 -08003395 vec_add2 (ldpw->vcl_poll, vp, 1);
Florin Coras6917b942018-11-13 22:44:54 -08003396 vp->fds_ndx = i;
3397 vp->sid = sid;
3398 vp->events = fds[i].events;
Dave Wallace048b1d62018-01-03 22:24:41 -05003399#ifdef __USE_XOPEN2K
Florin Coras6917b942018-11-13 22:44:54 -08003400 if (fds[i].events & POLLRDNORM)
3401 vp->events |= POLLIN;
3402 if (fds[i].events & POLLWRNORM)
3403 vp->events |= POLLOUT;
Dave Wallace048b1d62018-01-03 22:24:41 -05003404#endif
Florin Coras6917b942018-11-13 22:44:54 -08003405 vp->revents = fds[i].revents;
3406 }
3407 else
3408 {
Florin Corasdfe4cf42018-11-28 22:13:45 -08003409 vec_add1 (ldpw->libc_poll, fds[i]);
3410 vec_add1 (ldpw->libc_poll_idxs, i);
Dave Wallace048b1d62018-01-03 22:24:41 -05003411 }
3412 }
3413
Dave Wallace048b1d62018-01-03 22:24:41 -05003414 do
3415 {
Florin Corasdfe4cf42018-11-28 22:13:45 -08003416 if (vec_len (ldpw->vcl_poll))
Dave Wallace048b1d62018-01-03 22:24:41 -05003417 {
3418 func_str = "vppcom_poll";
3419
Florin Coras6917b942018-11-13 22:44:54 -08003420 LDBG (3, "LDP<%d>: calling %s(): vcl_poll %p, n_sids %u (0x%x): "
Florin Corasdfe4cf42018-11-28 22:13:45 -08003421 "n_libc_fds %u", getpid (), func_str, ldpw->vcl_poll,
3422 vec_len (ldpw->vcl_poll), vec_len (ldpw->vcl_poll),
3423 vec_len (ldpw->libc_poll));
Dave Wallace048b1d62018-01-03 22:24:41 -05003424
Florin Corasdfe4cf42018-11-28 22:13:45 -08003425 rv = vppcom_poll (ldpw->vcl_poll, vec_len (ldpw->vcl_poll), 0);
Dave Wallace048b1d62018-01-03 22:24:41 -05003426 if (rv < 0)
3427 {
3428 errno = -rv;
3429 rv = -1;
3430 goto done;
3431 }
3432 else
3433 n_revents += rv;
3434 }
3435
Florin Corasdfe4cf42018-11-28 22:13:45 -08003436 if (vec_len (ldpw->libc_poll))
Dave Wallace048b1d62018-01-03 22:24:41 -05003437 {
3438 func_str = "libc_poll";
3439
Florin Coras6917b942018-11-13 22:44:54 -08003440 LDBG (3, "LDP<%d>: calling %s(): fds %p, nfds %u: n_sids %u",
Florin Corasdfe4cf42018-11-28 22:13:45 -08003441 getpid (), fds, nfds, vec_len (ldpw->vcl_poll));
Dave Wallace048b1d62018-01-03 22:24:41 -05003442
Florin Corasdfe4cf42018-11-28 22:13:45 -08003443 rv = libc_poll (ldpw->libc_poll, vec_len (ldpw->libc_poll), 0);
Dave Wallace048b1d62018-01-03 22:24:41 -05003444 if (rv < 0)
3445 goto done;
3446 else
3447 n_revents += rv;
3448 }
3449
3450 if (n_revents)
3451 {
3452 rv = n_revents;
3453 goto done;
3454 }
3455 }
3456 while ((wait_for_time == -1) ||
Florin Corasdfe4cf42018-11-28 22:13:45 -08003457 (clib_time_now (&ldpw->clib_time) < wait_for_time));
Dave Wallace048b1d62018-01-03 22:24:41 -05003458 rv = 0;
3459
3460done:
Florin Corasdfe4cf42018-11-28 22:13:45 -08003461 vec_foreach (vp, ldpw->vcl_poll)
Dave Wallace048b1d62018-01-03 22:24:41 -05003462 {
3463 fds[vp->fds_ndx].fd = -fds[vp->fds_ndx].fd;
Florin Coras6917b942018-11-13 22:44:54 -08003464 fds[vp->fds_ndx].revents = vp->revents;
Dave Wallace048b1d62018-01-03 22:24:41 -05003465#ifdef __USE_XOPEN2K
3466 if ((fds[vp->fds_ndx].revents & POLLIN) &&
3467 (fds[vp->fds_ndx].events & POLLRDNORM))
3468 fds[vp->fds_ndx].revents |= POLLRDNORM;
3469 if ((fds[vp->fds_ndx].revents & POLLOUT) &&
3470 (fds[vp->fds_ndx].events & POLLWRNORM))
3471 fds[vp->fds_ndx].revents |= POLLWRNORM;
3472#endif
3473 }
Florin Corasdfe4cf42018-11-28 22:13:45 -08003474 vec_reset_length (ldpw->vcl_poll);
Dave Wallace048b1d62018-01-03 22:24:41 -05003475
Florin Corasdfe4cf42018-11-28 22:13:45 -08003476 for (i = 0; i < vec_len (ldpw->libc_poll); i++)
Florin Coras6917b942018-11-13 22:44:54 -08003477 {
Florin Corasdfe4cf42018-11-28 22:13:45 -08003478 fds[ldpw->libc_poll_idxs[i]].revents = ldpw->libc_poll[i].revents;
Florin Coras6917b942018-11-13 22:44:54 -08003479 }
Florin Corasdfe4cf42018-11-28 22:13:45 -08003480 vec_reset_length (ldpw->libc_poll_idxs);
3481 vec_reset_length (ldpw->libc_poll);
Florin Coras6917b942018-11-13 22:44:54 -08003482
Dave Wallace2a865272018-02-07 21:00:42 -05003483 if (LDP_DEBUG > 3)
Dave Wallace048b1d62018-01-03 22:24:41 -05003484 {
3485 if (rv < 0)
3486 {
3487 int errno_val = errno;
3488 perror (func_str);
3489 clib_warning ("LDP<%d>: ERROR: %s() failed! "
3490 "rv %d, errno = %d", getpid (),
3491 func_str, rv, errno_val);
3492 errno = errno_val;
3493 }
3494 else
3495 {
3496 clib_warning ("LDP<%d>: returning %d (0x%x): n_sids %u, "
3497 "n_libc_fds %d", getpid (), rv, rv,
Florin Corasdfe4cf42018-11-28 22:13:45 -08003498 vec_len (ldpw->vcl_poll), vec_len (ldpw->libc_poll));
Dave Wallace048b1d62018-01-03 22:24:41 -05003499
3500 for (i = 0; i < nfds; i++)
3501 {
3502 if (fds[i].fd >= 0)
3503 {
Dave Wallace2a865272018-02-07 21:00:42 -05003504 if (LDP_DEBUG > 3)
Dave Wallace048b1d62018-01-03 22:24:41 -05003505 clib_warning ("LDP<%d>: fds[%d].fd %d (0x%0x), "
3506 ".events = 0x%x, .revents = 0x%x",
3507 getpid (), i, fds[i].fd, fds[i].fd,
3508 fds[i].events, fds[i].revents);
3509 }
3510 }
3511 }
3512 }
3513
3514 return rv;
3515}
3516
3517#ifdef USE_GNU
3518int
3519ppoll (struct pollfd *fds, nfds_t nfds,
3520 const struct timespec *timeout, const sigset_t * sigmask)
3521{
Dave Wallace2a865272018-02-07 21:00:42 -05003522 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05003523 return -1;
3524
3525 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
3526 errno = ENOSYS;
3527
3528
3529 return -1;
3530}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003531#endif
3532
Dave Wallace2a865272018-02-07 21:00:42 -05003533void CONSTRUCTOR_ATTRIBUTE ldp_constructor (void);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003534
Dave Wallace2a865272018-02-07 21:00:42 -05003535void DESTRUCTOR_ATTRIBUTE ldp_destructor (void);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003536
Dave Wallace048b1d62018-01-03 22:24:41 -05003537/*
3538 * This function is called when the library is loaded
3539 */
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003540void
Dave Wallace2a865272018-02-07 21:00:42 -05003541ldp_constructor (void)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003542{
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003543 swrap_constructor ();
Dave Wallace2a865272018-02-07 21:00:42 -05003544 if (ldp_init () != 0)
3545 fprintf (stderr, "\nLDP<%d>: ERROR: ldp_constructor: failed!\n",
Dave Wallace048b1d62018-01-03 22:24:41 -05003546 getpid ());
Dave Wallace69d01192018-02-22 16:22:09 -05003547 else if (LDP_DEBUG > 0)
Dave Wallace2a865272018-02-07 21:00:42 -05003548 clib_warning ("LDP<%d>: LDP constructor: done!\n", getpid ());
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003549}
3550
3551/*
3552 * This function is called when the library is unloaded
3553 */
3554void
Dave Wallace2a865272018-02-07 21:00:42 -05003555ldp_destructor (void)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003556{
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003557 swrap_destructor ();
Dave Wallace2a865272018-02-07 21:00:42 -05003558 if (ldp->init)
Florin Coras940f78f2018-11-30 12:11:20 -08003559 ldp->init = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -05003560
3561 /* Don't use clib_warning() here because that calls writev()
Dave Wallace2a865272018-02-07 21:00:42 -05003562 * which will call ldp_init().
Dave Wallace048b1d62018-01-03 22:24:41 -05003563 */
Dave Wallace69d01192018-02-22 16:22:09 -05003564 if (LDP_DEBUG > 0)
3565 printf ("%s:%d: LDP<%d>: LDP destructor: done!\n",
3566 __func__, __LINE__, getpid ());
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003567}
3568
3569
3570/*
3571 * fd.io coding-style-patch-verification: ON
3572 *
3573 * Local Variables:
3574 * eval: (c-set-style "gnu")
3575 * End:
3576 */