blob: c3dc64a4d3b17c3e4bf9ed4f81d52928d6d4a41e [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 Coras955bfbb2018-12-04 13:43:45 -0800261 ldp->vcl_needs_real_epoll = 0;
262 if (rv == VPPCOM_EEXIST)
263 return 0;
264 LDBG (2, "\nLDP<%d>: ERROR: ldp_init: vppcom_app_create()"
265 " failed! rv = %d (%s)\n",
266 getpid (), rv, vppcom_retval_str (rv));
Florin Coras99368312018-08-02 10:45:44 -0700267 ldp->init = 0;
268 return rv;
269 }
270 ldp->vcl_needs_real_epoll = 0;
Florin Corasdfe4cf42018-11-28 22:13:45 -0800271 pool_alloc (ldp->workers, LDP_MAX_NWORKERS);
272 ldpw = ldp_worker_get_current ();
Florin Coras99368312018-08-02 10:45:44 -0700273
274 char *env_var_str = getenv (LDP_ENV_DEBUG);
275 if (env_var_str)
276 {
277 u32 tmp;
278 if (sscanf (env_var_str, "%u", &tmp) != 1)
279 clib_warning ("LDP<%d>: WARNING: Invalid LDP debug level specified in"
280 " the env var " LDP_ENV_DEBUG " (%s)!", getpid (),
281 env_var_str);
282 else
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700283 {
Florin Coras99368312018-08-02 10:45:44 -0700284 ldp->debug = tmp;
285 LDBG (0, "LDP<%d>: configured LDP debug level (%u) from env var "
286 LDP_ENV_DEBUG "!", getpid (), ldp->debug);
287 }
288 }
Dave Wallace048b1d62018-01-03 22:24:41 -0500289
Florin Coras99368312018-08-02 10:45:44 -0700290 env_var_str = getenv (LDP_ENV_APP_NAME);
291 if (env_var_str)
292 {
293 ldp_set_app_name (env_var_str);
294 LDBG (0, "LDP<%d>: configured LDP app name (%s) from the env var "
295 LDP_ENV_APP_NAME "!", getpid (), ldp->app_name);
296 }
Dave Wallace048b1d62018-01-03 22:24:41 -0500297
Florin Coras99368312018-08-02 10:45:44 -0700298 env_var_str = getenv (LDP_ENV_SID_BIT);
299 if (env_var_str)
300 {
301 u32 sb;
302 if (sscanf (env_var_str, "%u", &sb) != 1)
303 {
304 clib_warning ("LDP<%d>: WARNING: Invalid LDP sid bit specified in"
305 " the env var " LDP_ENV_SID_BIT " (%s)! sid bit "
306 "value %d (0x%x)", getpid (), env_var_str,
307 ldp->sid_bit_val, ldp->sid_bit_val);
308 }
309 else if (sb < LDP_SID_BIT_MIN)
310 {
311 ldp->sid_bit_val = (1 << LDP_SID_BIT_MIN);
312 ldp->sid_bit_mask = ldp->sid_bit_val - 1;
Dave Wallace048b1d62018-01-03 22:24:41 -0500313
Florin Coras99368312018-08-02 10:45:44 -0700314 clib_warning ("LDP<%d>: WARNING: LDP sid bit (%u) specified in the"
315 " env var " LDP_ENV_SID_BIT " (%s) is too small. "
316 "Using LDP_SID_BIT_MIN (%d)! sid bit value %d (0x%x)",
317 getpid (), sb, env_var_str, LDP_SID_BIT_MIN,
318 ldp->sid_bit_val, ldp->sid_bit_val);
319 }
320 else if (sb > LDP_SID_BIT_MAX)
321 {
322 ldp->sid_bit_val = (1 << LDP_SID_BIT_MAX);
323 ldp->sid_bit_mask = ldp->sid_bit_val - 1;
Dave Wallace048b1d62018-01-03 22:24:41 -0500324
Florin Coras99368312018-08-02 10:45:44 -0700325 clib_warning ("LDP<%d>: WARNING: LDP sid bit (%u) specified in the"
326 " env var " LDP_ENV_SID_BIT " (%s) is too big. Using"
327 " LDP_SID_BIT_MAX (%d)! sid bit value %d (0x%x)",
328 getpid (), sb, env_var_str, LDP_SID_BIT_MAX,
329 ldp->sid_bit_val, ldp->sid_bit_val);
Dave Wallace048b1d62018-01-03 22:24:41 -0500330 }
331 else
332 {
Florin Coras99368312018-08-02 10:45:44 -0700333 ldp->sid_bit_val = (1 << sb);
334 ldp->sid_bit_mask = ldp->sid_bit_val - 1;
335
336 LDBG (0, "LDP<%d>: configured LDP sid bit (%u) from "
337 LDP_ENV_SID_BIT "! sid bit value %d (0x%x)", getpid (), sb,
338 ldp->sid_bit_val, ldp->sid_bit_val);
Dave Wallace048b1d62018-01-03 22:24:41 -0500339 }
340 }
Florin Coras99368312018-08-02 10:45:44 -0700341
Florin Corasdfe4cf42018-11-28 22:13:45 -0800342 clib_time_init (&ldpw->clib_time);
Florin Coras30e273b2018-11-27 00:04:59 -0800343 clib_rwlock_init (&ldp->fd_table_lock);
Florin Coras99368312018-08-02 10:45:44 -0700344 LDBG (0, "LDP<%d>: LDP initialization: done!", getpid ());
345
346 return 0;
Dave Wallace048b1d62018-01-03 22:24:41 -0500347}
348
349int
350close (int fd)
351{
Florin Coras47c40e22018-11-26 17:01:36 -0800352 int rv, refcnt;
Dave Wallace048b1d62018-01-03 22:24:41 -0500353 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -0500354 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -0500355
Dave Wallace2a865272018-02-07 21:00:42 -0500356 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500357 return -1;
358
359 if (sid != INVALID_SESSION_ID)
360 {
361 int epfd;
362
363 func_str = "vppcom_session_attr[GET_LIBC_EPFD]";
364 epfd = vppcom_session_attr (sid, VPPCOM_ATTR_GET_LIBC_EPFD, 0, 0);
365 if (epfd > 0)
366 {
367 func_str = "libc_close";
368
Florin Coras6917b942018-11-13 22:44:54 -0800369 LDBG (0, "LDP<%d>: fd %d (0x%x): calling %s(): epfd %u (0x%x)",
370 getpid (), fd, fd, func_str, epfd, epfd);
Dave Wallace048b1d62018-01-03 22:24:41 -0500371
372 rv = libc_close (epfd);
373 if (rv < 0)
374 {
375 u32 size = sizeof (epfd);
376 epfd = 0;
377
378 (void) vppcom_session_attr (sid, VPPCOM_ATTR_SET_LIBC_EPFD,
379 &epfd, &size);
380 }
381 }
382 else if (PREDICT_FALSE (epfd < 0))
383 {
384 errno = -epfd;
385 rv = -1;
386 goto done;
387 }
388
389 func_str = "vppcom_session_close";
390
Florin Coras6917b942018-11-13 22:44:54 -0800391 LDBG (0, "LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x)",
392 getpid (), fd, fd, func_str, sid, sid);
Dave Wallace048b1d62018-01-03 22:24:41 -0500393
Florin Coras47c40e22018-11-26 17:01:36 -0800394 refcnt = vppcom_session_attr (sid, VPPCOM_ATTR_GET_REFCNT, 0, 0);
Dave Wallace048b1d62018-01-03 22:24:41 -0500395 rv = vppcom_session_close (sid);
396 if (rv != VPPCOM_OK)
397 {
398 errno = -rv;
399 rv = -1;
400 }
Florin Coras47c40e22018-11-26 17:01:36 -0800401 if (refcnt == 1)
402 ldp_fd_free_w_sid (sid);
Dave Wallace048b1d62018-01-03 22:24:41 -0500403 }
404 else
405 {
406 func_str = "libc_close";
407
Florin Coras6917b942018-11-13 22:44:54 -0800408 LDBG (0, "LDP<%d>: fd %d (0x%x): calling %s()", getpid (), fd, fd,
409 func_str);
Dave Wallace048b1d62018-01-03 22:24:41 -0500410
411 rv = libc_close (fd);
412 }
413
414done:
Dave Wallace2a865272018-02-07 21:00:42 -0500415 if (LDP_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -0500416 {
417 if (rv < 0)
418 {
419 int errno_val = errno;
420 perror (func_str);
421 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
422 "rv %d, errno = %d", getpid (), fd, fd,
423 func_str, rv, errno_val);
424 errno = errno_val;
425 }
426 else
427 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
428 getpid (), fd, fd, rv, rv);
429 }
430 return rv;
431}
432
433ssize_t
434read (int fd, void *buf, size_t nbytes)
435{
436 ssize_t size;
437 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -0500438 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -0500439
Dave Wallace2a865272018-02-07 21:00:42 -0500440 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500441 return -1;
442
443 if (sid != INVALID_SESSION_ID)
444 {
445 func_str = "vppcom_session_read";
446
Dave Wallace2a865272018-02-07 21:00:42 -0500447 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -0500448 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
449 "sid %u (0x%x), buf %p, nbytes %u", getpid (),
450 fd, fd, func_str, sid, sid, buf, nbytes);
451
452 size = vppcom_session_read (sid, buf, nbytes);
453 if (size < 0)
454 {
455 errno = -size;
456 size = -1;
457 }
458 }
459 else
460 {
461 func_str = "libc_read";
462
Dave Wallace2a865272018-02-07 21:00:42 -0500463 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -0500464 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
465 "buf %p, nbytes %u", getpid (),
466 fd, fd, func_str, buf, nbytes);
467
468 size = libc_read (fd, buf, nbytes);
469 }
470
Dave Wallace2a865272018-02-07 21:00:42 -0500471 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -0500472 {
473 if (size < 0)
474 {
475 int errno_val = errno;
476 perror (func_str);
477 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
478 "rv %d, errno = %d", getpid (), fd, fd,
479 func_str, size, errno_val);
480 errno = errno_val;
481 }
482 else
483 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
484 getpid (), fd, fd, size, size);
485 }
486 return size;
487}
488
489ssize_t
490readv (int fd, const struct iovec * iov, int iovcnt)
491{
492 const char *func_str;
493 ssize_t size = 0;
Dave Wallace2a865272018-02-07 21:00:42 -0500494 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace8aaba562018-01-18 17:21:19 -0500495 int rv = 0, i, total = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -0500496
Dave Wallace2a865272018-02-07 21:00:42 -0500497 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500498 return -1;
499
500 if (sid != INVALID_SESSION_ID)
501 {
502 func_str = "vppcom_session_read";
503 do
504 {
505 for (i = 0; i < iovcnt; ++i)
506 {
Dave Wallace2a865272018-02-07 21:00:42 -0500507 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -0500508 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s() [%d]: "
509 "sid %u (0x%x), iov %p, iovcnt %d, total %d",
510 getpid (), fd, fd, func_str, i, sid, sid,
511 iov, iovcnt, total);
512
513 rv = vppcom_session_read (sid, iov[i].iov_base, iov[i].iov_len);
514 if (rv < 0)
515 break;
516 else
517 {
518 total += rv;
519 if (rv < iov[i].iov_len)
520 {
Dave Wallace2a865272018-02-07 21:00:42 -0500521 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -0500522 clib_warning ("LDP<%d>: fd %d (0x%x): "
523 "rv (%d) < iov[%d].iov_len (%d)",
524 getpid (), fd, fd, rv, i,
525 iov[i].iov_len);
526 break;
527 }
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700528 }
529 }
530 }
Dave Wallace048b1d62018-01-03 22:24:41 -0500531 while ((rv >= 0) && (total == 0));
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700532
Dave Wallace048b1d62018-01-03 22:24:41 -0500533 if (rv < 0)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700534 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500535 errno = -rv;
536 size = -1;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700537 }
Dave Wallace048b1d62018-01-03 22:24:41 -0500538 else
539 size = total;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700540 }
541 else
542 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500543 func_str = "libc_readv";
544
Dave Wallace2a865272018-02-07 21:00:42 -0500545 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -0500546 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
547 "iov %p, iovcnt %d", getpid (), fd, fd, iov, iovcnt);
548
549 size = libc_readv (fd, iov, iovcnt);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700550 }
551
Dave Wallace2a865272018-02-07 21:00:42 -0500552 if (LDP_DEBUG > 2)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700553 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500554 if (size < 0)
555 {
556 int errno_val = errno;
557 perror (func_str);
558 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
559 "rv %d, errno = %d", getpid (), fd, fd,
560 func_str, size, errno_val);
561 errno = errno_val;
562 }
563 else
564 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
565 getpid (), fd, fd, size, size);
566 }
567 return size;
568}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700569
Dave Wallace048b1d62018-01-03 22:24:41 -0500570ssize_t
571write (int fd, const void *buf, size_t nbytes)
572{
573 const char *func_str;
574 ssize_t size = 0;
Dave Wallace2a865272018-02-07 21:00:42 -0500575 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -0500576
Dave Wallace2a865272018-02-07 21:00:42 -0500577 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500578 return -1;
579
580 if (sid != INVALID_SESSION_ID)
581 {
582 func_str = "vppcom_session_write";
583
Dave Wallace2a865272018-02-07 21:00:42 -0500584 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -0500585 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
586 "sid %u (0x%x), buf %p, nbytes %u", getpid (),
587 fd, fd, func_str, sid, sid, buf, nbytes);
588
589 size = vppcom_session_write (sid, (void *) buf, nbytes);
590 if (size < 0)
591 {
592 errno = -size;
593 size = -1;
594 }
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700595 }
596 else
597 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500598 func_str = "libc_write";
599
Dave Wallace2a865272018-02-07 21:00:42 -0500600 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -0500601 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
602 "buf %p, nbytes %u", getpid (),
603 fd, fd, func_str, buf, nbytes);
604
605 size = libc_write (fd, buf, nbytes);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700606 }
607
Dave Wallace2a865272018-02-07 21:00:42 -0500608 if (LDP_DEBUG > 2)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700609 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500610 if (size < 0)
611 {
612 int errno_val = errno;
613 perror (func_str);
614 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
615 "rv %d, errno = %d", getpid (), fd, fd,
616 func_str, size, errno_val);
617 errno = errno_val;
618 }
619 else
620 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
621 getpid (), fd, fd, size, size);
622 }
623 return size;
624}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700625
Dave Wallace048b1d62018-01-03 22:24:41 -0500626ssize_t
627writev (int fd, const struct iovec * iov, int iovcnt)
628{
629 const char *func_str;
630 ssize_t size = 0, total = 0;
Dave Wallace2a865272018-02-07 21:00:42 -0500631 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace8aaba562018-01-18 17:21:19 -0500632 int i, rv = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -0500633
634 /*
635 * Use [f]printf() instead of clib_warning() to prevent recursion SIGSEGV.
636 */
637
Dave Wallace2a865272018-02-07 21:00:42 -0500638 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500639 return -1;
640
641 if (sid != INVALID_SESSION_ID)
642 {
643 func_str = "vppcom_session_write";
644 do
645 {
646 for (i = 0; i < iovcnt; ++i)
647 {
Dave Wallace2a865272018-02-07 21:00:42 -0500648 if (LDP_DEBUG > 4)
Dave Wallace048b1d62018-01-03 22:24:41 -0500649 printf ("%s:%d: LDP<%d>: fd %d (0x%x): calling %s() [%d]: "
650 "sid %u (0x%x), buf %p, nbytes %ld, total %ld",
651 __func__, __LINE__, getpid (), fd, fd, func_str,
652 i, sid, sid, iov[i].iov_base, iov[i].iov_len, total);
653
654 rv = vppcom_session_write (sid, iov[i].iov_base,
655 iov[i].iov_len);
656 if (rv < 0)
657 break;
658 else
659 {
660 total += rv;
661 if (rv < iov[i].iov_len)
662 {
Dave Wallace2a865272018-02-07 21:00:42 -0500663 if (LDP_DEBUG > 4)
Dave Wallace048b1d62018-01-03 22:24:41 -0500664 printf ("%s:%d: LDP<%d>: fd %d (0x%x): "
665 "rv (%d) < iov[%d].iov_len (%ld)",
666 __func__, __LINE__, getpid (), fd, fd,
667 rv, i, iov[i].iov_len);
668 break;
669 }
670 }
671 }
672 }
673 while ((rv >= 0) && (total == 0));
674
675 if (rv < 0)
676 {
677 errno = -rv;
678 size = -1;
679 }
680 else
681 size = total;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700682 }
683 else
684 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500685 func_str = "libc_writev";
686
Dave Wallace2a865272018-02-07 21:00:42 -0500687 if (LDP_DEBUG > 4)
Dave Wallace048b1d62018-01-03 22:24:41 -0500688 printf ("%s:%d: LDP<%d>: fd %d (0x%x): calling %s(): "
689 "iov %p, iovcnt %d\n", __func__, __LINE__, getpid (),
690 fd, fd, func_str, iov, iovcnt);
691
692 size = libc_writev (fd, iov, iovcnt);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700693 }
694
Dave Wallace2a865272018-02-07 21:00:42 -0500695 if (LDP_DEBUG > 4)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700696 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500697 if (size < 0)
698 {
699 int errno_val = errno;
700 perror (func_str);
701 fprintf (stderr,
702 "%s:%d: LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
703 "rv %ld, errno = %d\n", __func__, __LINE__, getpid (), fd,
704 fd, func_str, size, errno_val);
705 errno = errno_val;
706 }
707 else
708 printf ("%s:%d: LDP<%d>: fd %d (0x%x): returning %ld\n",
709 __func__, __LINE__, getpid (), fd, fd, size);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700710 }
Dave Wallace048b1d62018-01-03 22:24:41 -0500711 return size;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700712}
713
714int
Dave Wallace048b1d62018-01-03 22:24:41 -0500715fcntl (int fd, int cmd, ...)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700716{
Dave Wallace048b1d62018-01-03 22:24:41 -0500717 const char *func_str = __func__;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700718 int rv = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -0500719 va_list ap;
Dave Wallace2a865272018-02-07 21:00:42 -0500720 u32 sid = ldp_sid_from_fd (fd);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700721
Dave Wallace2a865272018-02-07 21:00:42 -0500722 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500723 return -1;
724
725 va_start (ap, cmd);
726 if (sid != INVALID_SESSION_ID)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700727 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500728 int flags = va_arg (ap, int);
729 u32 size;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700730
Dave Wallace048b1d62018-01-03 22:24:41 -0500731 size = sizeof (flags);
732 rv = -EOPNOTSUPP;
733 switch (cmd)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700734 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500735 case F_SETFL:
736 func_str = "vppcom_session_attr[SET_FLAGS]";
Florin Coras173bae32018-11-16 18:56:28 -0800737 LDBG (2, "LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x) "
738 "flags %d (0x%x), size %d", getpid (), fd, fd, func_str, sid,
739 sid, flags, flags, size);
Dave Wallace048b1d62018-01-03 22:24:41 -0500740
Florin Coras173bae32018-11-16 18:56:28 -0800741 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_FLAGS, &flags,
742 &size);
Dave Wallace048b1d62018-01-03 22:24:41 -0500743 break;
744
745 case F_GETFL:
746 func_str = "vppcom_session_attr[GET_FLAGS]";
Florin Coras173bae32018-11-16 18:56:28 -0800747 LDBG (2, "LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), "
748 "flags %d (0x%x), size %d", getpid (), fd, fd, func_str, sid,
749 sid, flags, flags, size);
Dave Wallace048b1d62018-01-03 22:24:41 -0500750
Florin Coras173bae32018-11-16 18:56:28 -0800751 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_FLAGS, &flags,
752 &size);
Dave Wallace048b1d62018-01-03 22:24:41 -0500753 if (rv == VPPCOM_OK)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700754 {
Florin Coras173bae32018-11-16 18:56:28 -0800755 LDBG (2, "LDP<%d>: fd %d (0x%x), cmd %d (F_GETFL): %s() "
756 "returned flags %d (0x%x)", getpid (), fd, fd, cmd,
757 func_str, flags, flags);
Dave Wallace048b1d62018-01-03 22:24:41 -0500758 rv = flags;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700759 }
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700760 break;
Florin Coras173bae32018-11-16 18:56:28 -0800761 case F_SETFD:
762 /* TODO handle this */
763 LDBG (0, "F_SETFD ignored flags %u", flags);
764 rv = 0;
765 break;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700766 default:
Dave Wallace048b1d62018-01-03 22:24:41 -0500767 rv = -EOPNOTSUPP;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700768 break;
769 }
Dave Wallace048b1d62018-01-03 22:24:41 -0500770 if (rv < 0)
771 {
772 errno = -rv;
773 rv = -1;
774 }
775 }
776 else
777 {
778 func_str = "libc_vfcntl";
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700779
Dave Wallace2a865272018-02-07 21:00:42 -0500780 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -0500781 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): cmd %d",
782 getpid (), fd, fd, func_str, cmd);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700783
Dave Wallace048b1d62018-01-03 22:24:41 -0500784 rv = libc_vfcntl (fd, cmd, ap);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700785 }
786
Dave Wallace048b1d62018-01-03 22:24:41 -0500787 va_end (ap);
788
Dave Wallace2a865272018-02-07 21:00:42 -0500789 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -0500790 {
791 if (rv < 0)
792 {
793 int errno_val = errno;
794 perror (func_str);
795 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
796 "rv %d, errno = %d", getpid (), fd, fd,
797 func_str, rv, errno_val);
798 errno = errno_val;
799 }
800 else
801 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
802 getpid (), fd, fd, rv, rv);
803 }
804 return rv;
805}
806
807int
808ioctl (int fd, unsigned long int cmd, ...)
809{
810 const char *func_str;
811 int rv;
812 va_list ap;
Dave Wallace2a865272018-02-07 21:00:42 -0500813 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -0500814
Dave Wallace2a865272018-02-07 21:00:42 -0500815 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500816 return -1;
817
818 va_start (ap, cmd);
819 if (sid != INVALID_SESSION_ID)
820 {
821 func_str = "vppcom_session_attr[GET_NREAD]";
822
823 switch (cmd)
824 {
825 case FIONREAD:
Dave Wallace2a865272018-02-07 21:00:42 -0500826 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -0500827 clib_warning
828 ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x)",
829 getpid (), fd, fd, func_str, sid, sid);
830
831 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_NREAD, 0, 0);
832 break;
833
834 case FIONBIO:
835 {
836 u32 flags = va_arg (ap, int) ? O_NONBLOCK : 0;
837 u32 size = sizeof (flags);
838
839 /* TBD: When VPPCOM_ATTR_[GS]ET_FLAGS supports flags other than
840 * non-blocking, the flags should be read here and merged
841 * with O_NONBLOCK.
842 */
Dave Wallace2a865272018-02-07 21:00:42 -0500843 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -0500844 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
845 "sid %u (0x%x), flags %d (0x%x), size %d",
846 getpid (), fd, fd, func_str, sid, sid,
847 flags, flags, size);
848
849 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_FLAGS, &flags,
850 &size);
851 }
852 break;
853
854 default:
855 rv = -EOPNOTSUPP;
856 break;
857 }
858 if (rv < 0)
859 {
860 errno = -rv;
861 rv = -1;
862 }
863 }
864 else
865 {
866 func_str = "libc_vioctl";
867
Dave Wallace2a865272018-02-07 21:00:42 -0500868 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -0500869 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): cmd %d",
870 getpid (), fd, fd, func_str, cmd);
871
872 rv = libc_vioctl (fd, cmd, ap);
873 }
874
Dave Wallace2a865272018-02-07 21:00:42 -0500875 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -0500876 {
877 if (rv < 0)
878 {
879 int errno_val = errno;
880 perror (func_str);
881 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
882 "rv %d, errno = %d", getpid (), fd, fd,
883 func_str, rv, errno_val);
884 errno = errno_val;
885 }
886 else
887 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
888 getpid (), fd, fd, rv, rv);
889 }
890 va_end (ap);
891 return rv;
892}
893
894int
Dave Wallace2a865272018-02-07 21:00:42 -0500895ldp_pselect (int nfds, fd_set * __restrict readfds,
896 fd_set * __restrict writefds,
897 fd_set * __restrict exceptfds,
898 const struct timespec *__restrict timeout,
899 const __sigset_t * __restrict sigmask)
Dave Wallace048b1d62018-01-03 22:24:41 -0500900{
Florin Coras30e273b2018-11-27 00:04:59 -0800901 uword sid_bits, sid_bits_set, libc_bits, libc_bits_set;
Florin Corasdfe4cf42018-11-28 22:13:45 -0800902 ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
Florin Coras30e273b2018-11-27 00:04:59 -0800903 u32 minbits = clib_max (nfds, BITS (uword)), sid;
Dave Wallace048b1d62018-01-03 22:24:41 -0500904 char *func_str = "##";
905 f64 time_out;
Florin Coras30e273b2018-11-27 00:04:59 -0800906 int rv, fd;
Dave Wallace048b1d62018-01-03 22:24:41 -0500907
908 if (nfds < 0)
909 {
910 errno = EINVAL;
911 return -1;
912 }
913
Dave Wallace3ee1fe12018-02-23 01:09:11 -0500914 if (timeout)
915 {
916 time_out = (timeout->tv_sec == 0 && timeout->tv_nsec == 0) ?
917 (f64) 0 : (f64) timeout->tv_sec +
918 (f64) timeout->tv_nsec / (f64) 1000000000;
919
920 /* select as fine grained sleep */
921 if (!nfds)
922 {
Florin Coras173bae32018-11-16 18:56:28 -0800923 LDBG (3, "LDP<%d>: sleeping for %.02f seconds", getpid (),
924 time_out);
Dave Wallace3ee1fe12018-02-23 01:09:11 -0500925
Florin Corasdfe4cf42018-11-28 22:13:45 -0800926 time_out += clib_time_now (&ldpw->clib_time);
927 while (clib_time_now (&ldpw->clib_time) < time_out)
Dave Wallace3ee1fe12018-02-23 01:09:11 -0500928 ;
929 return 0;
930 }
931 }
932 else if (!nfds)
933 {
934 errno = EINVAL;
935 return -1;
936 }
937 else
938 time_out = -1;
939
940
Dave Wallace2a865272018-02-07 21:00:42 -0500941 if (nfds <= ldp->sid_bit_val)
Dave Wallace048b1d62018-01-03 22:24:41 -0500942 {
943 func_str = "libc_pselect";
944
Florin Coras173bae32018-11-16 18:56:28 -0800945 LDBG (3, "LDP<%d>: calling %s(): nfds %d, readfds %p, writefds %p, "
946 "exceptfds %p, timeout %p, sigmask %p", getpid (), func_str, nfds,
947 readfds, writefds, exceptfds, timeout, sigmask);
Dave Wallace048b1d62018-01-03 22:24:41 -0500948
949 rv = libc_pselect (nfds, readfds, writefds, exceptfds,
950 timeout, sigmask);
951 goto done;
952 }
953
Dave Wallace2a865272018-02-07 21:00:42 -0500954 if (PREDICT_FALSE (ldp->sid_bit_val > FD_SETSIZE / 2))
Dave Wallace048b1d62018-01-03 22:24:41 -0500955 {
Dave Wallace2a865272018-02-07 21:00:42 -0500956 clib_warning ("LDP<%d>: ERROR: LDP sid bit value %d (0x%x) > "
Dave Wallace048b1d62018-01-03 22:24:41 -0500957 "FD_SETSIZE/2 %d (0x%x)!", getpid (),
Dave Wallace2a865272018-02-07 21:00:42 -0500958 ldp->sid_bit_val, ldp->sid_bit_val,
Dave Wallace048b1d62018-01-03 22:24:41 -0500959 FD_SETSIZE / 2, FD_SETSIZE / 2);
960 errno = EOVERFLOW;
961 return -1;
962 }
963
Dave Wallace048b1d62018-01-03 22:24:41 -0500964 sid_bits = libc_bits = 0;
Florin Coras173bae32018-11-16 18:56:28 -0800965 u32 n_bytes = nfds / 8 + ((nfds % 8) ? 1 : 0);
Dave Wallace048b1d62018-01-03 22:24:41 -0500966 if (readfds)
967 {
Florin Corasdfe4cf42018-11-28 22:13:45 -0800968 clib_bitmap_validate (ldpw->sid_rd_bitmap, minbits);
969 clib_bitmap_validate (ldpw->libc_rd_bitmap, minbits);
970 clib_bitmap_validate (ldpw->rd_bitmap, minbits);
971 clib_memcpy_fast (ldpw->rd_bitmap, readfds, n_bytes);
Florin Coras173bae32018-11-16 18:56:28 -0800972 memset (readfds, 0, n_bytes);
Dave Wallace048b1d62018-01-03 22:24:41 -0500973
974 /* *INDENT-OFF* */
Florin Corasdfe4cf42018-11-28 22:13:45 -0800975 clib_bitmap_foreach (fd, ldpw->rd_bitmap, ({
Florin Coras173bae32018-11-16 18:56:28 -0800976 if (fd > nfds)
977 break;
978 sid = ldp_sid_from_fd (fd);
979 LDBG (3, "LDP<%d>: readfds: fd %d (0x%x), sid %u (0x%x)",
980 getpid (), fd, fd, sid, sid);
981 if (sid == INVALID_SESSION_ID)
Florin Corasdfe4cf42018-11-28 22:13:45 -0800982 clib_bitmap_set_no_check (ldpw->libc_rd_bitmap, fd, 1);
Florin Coras173bae32018-11-16 18:56:28 -0800983 else
Florin Corasdfe4cf42018-11-28 22:13:45 -0800984 clib_bitmap_set_no_check (ldpw->sid_rd_bitmap,
Florin Coras30e273b2018-11-27 00:04:59 -0800985 vppcom_session_index (sid), 1);
Florin Coras173bae32018-11-16 18:56:28 -0800986 }));
Dave Wallace048b1d62018-01-03 22:24:41 -0500987 /* *INDENT-ON* */
988
Florin Corasdfe4cf42018-11-28 22:13:45 -0800989 sid_bits_set = clib_bitmap_last_set (ldpw->sid_rd_bitmap) + 1;
Dave Wallace048b1d62018-01-03 22:24:41 -0500990 sid_bits = (sid_bits_set > sid_bits) ? sid_bits_set : sid_bits;
991
Florin Corasdfe4cf42018-11-28 22:13:45 -0800992 libc_bits_set = clib_bitmap_last_set (ldpw->libc_rd_bitmap) + 1;
Dave Wallace048b1d62018-01-03 22:24:41 -0500993 libc_bits = (libc_bits_set > libc_bits) ? libc_bits_set : libc_bits;
994
Florin Coras173bae32018-11-16 18:56:28 -0800995 LDBG (3, "LDP<%d>: readfds: sid_bits_set %d, sid_bits %d, "
996 "libc_bits_set %d, libc_bits %d", getpid (), sid_bits_set,
997 sid_bits, libc_bits_set, libc_bits);
Dave Wallace048b1d62018-01-03 22:24:41 -0500998 }
999 if (writefds)
1000 {
Florin Corasdfe4cf42018-11-28 22:13:45 -08001001 clib_bitmap_validate (ldpw->sid_wr_bitmap, minbits);
1002 clib_bitmap_validate (ldpw->libc_wr_bitmap, minbits);
1003 clib_bitmap_validate (ldpw->wr_bitmap, minbits);
1004 clib_memcpy_fast (ldpw->wr_bitmap, writefds, n_bytes);
Florin Coras173bae32018-11-16 18:56:28 -08001005 memset (writefds, 0, n_bytes);
Dave Wallace048b1d62018-01-03 22:24:41 -05001006
1007 /* *INDENT-OFF* */
Florin Corasdfe4cf42018-11-28 22:13:45 -08001008 clib_bitmap_foreach (fd, ldpw->wr_bitmap, ({
Florin Coras173bae32018-11-16 18:56:28 -08001009 if (fd > nfds)
1010 break;
1011 sid = ldp_sid_from_fd (fd);
1012 LDBG (3, "LDP<%d>: writefds: fd %d (0x%x), sid %u (0x%x)",
1013 getpid (), fd, fd, sid, sid);
1014 if (sid == INVALID_SESSION_ID)
Florin Corasdfe4cf42018-11-28 22:13:45 -08001015 clib_bitmap_set_no_check (ldpw->libc_wr_bitmap, fd, 1);
Florin Coras173bae32018-11-16 18:56:28 -08001016 else
Florin Corasdfe4cf42018-11-28 22:13:45 -08001017 clib_bitmap_set_no_check (ldpw->sid_wr_bitmap,
Florin Coras30e273b2018-11-27 00:04:59 -08001018 vppcom_session_index (sid), 1);
Florin Coras173bae32018-11-16 18:56:28 -08001019 }));
Dave Wallace048b1d62018-01-03 22:24:41 -05001020 /* *INDENT-ON* */
1021
Florin Corasdfe4cf42018-11-28 22:13:45 -08001022 sid_bits_set = clib_bitmap_last_set (ldpw->sid_wr_bitmap) + 1;
Dave Wallace048b1d62018-01-03 22:24:41 -05001023 sid_bits = (sid_bits_set > sid_bits) ? sid_bits_set : sid_bits;
1024
Florin Corasdfe4cf42018-11-28 22:13:45 -08001025 libc_bits_set = clib_bitmap_last_set (ldpw->libc_wr_bitmap) + 1;
Dave Wallace048b1d62018-01-03 22:24:41 -05001026 libc_bits = (libc_bits_set > libc_bits) ? libc_bits_set : libc_bits;
1027
Florin Coras173bae32018-11-16 18:56:28 -08001028 LDBG (3, "LDP<%d>: writefds: sid_bits_set %d, sid_bits %d, "
1029 "libc_bits_set %d, libc_bits %d", getpid (),
1030 sid_bits_set, sid_bits, libc_bits_set, libc_bits);
Dave Wallace048b1d62018-01-03 22:24:41 -05001031 }
1032 if (exceptfds)
1033 {
Florin Corasdfe4cf42018-11-28 22:13:45 -08001034 clib_bitmap_validate (ldpw->sid_ex_bitmap, minbits);
1035 clib_bitmap_validate (ldpw->libc_ex_bitmap, minbits);
1036 clib_bitmap_validate (ldpw->ex_bitmap, minbits);
1037 clib_memcpy_fast (ldpw->ex_bitmap, exceptfds, n_bytes);
Florin Coras173bae32018-11-16 18:56:28 -08001038 memset (exceptfds, 0, n_bytes);
Dave Wallace048b1d62018-01-03 22:24:41 -05001039
1040 /* *INDENT-OFF* */
Florin Corasdfe4cf42018-11-28 22:13:45 -08001041 clib_bitmap_foreach (fd, ldpw->ex_bitmap, ({
Florin Coras173bae32018-11-16 18:56:28 -08001042 if (fd > nfds)
1043 break;
1044 sid = ldp_sid_from_fd (fd);
1045 LDBG (3, "LDP<%d>: exceptfds: fd %d (0x%x), sid %u (0x%x)",
1046 getpid (), fd, fd, sid, sid);
1047 if (sid == INVALID_SESSION_ID)
Florin Corasdfe4cf42018-11-28 22:13:45 -08001048 clib_bitmap_set_no_check (ldpw->libc_ex_bitmap, fd, 1);
Florin Coras173bae32018-11-16 18:56:28 -08001049 else
Florin Corasdfe4cf42018-11-28 22:13:45 -08001050 clib_bitmap_set_no_check (ldpw->sid_ex_bitmap,
Florin Coras30e273b2018-11-27 00:04:59 -08001051 vppcom_session_index (sid), 1);
Florin Coras173bae32018-11-16 18:56:28 -08001052 }));
Dave Wallace048b1d62018-01-03 22:24:41 -05001053 /* *INDENT-ON* */
1054
Florin Corasdfe4cf42018-11-28 22:13:45 -08001055 sid_bits_set = clib_bitmap_last_set (ldpw->sid_ex_bitmap) + 1;
Dave Wallace048b1d62018-01-03 22:24:41 -05001056 sid_bits = (sid_bits_set > sid_bits) ? sid_bits_set : sid_bits;
1057
Florin Corasdfe4cf42018-11-28 22:13:45 -08001058 libc_bits_set = clib_bitmap_last_set (ldpw->libc_ex_bitmap) + 1;
Dave Wallace048b1d62018-01-03 22:24:41 -05001059 libc_bits = (libc_bits_set > libc_bits) ? libc_bits_set : libc_bits;
1060
Florin Coras173bae32018-11-16 18:56:28 -08001061 LDBG (3, "LDP<%d>: exceptfds: sid_bits_set %d, sid_bits %d, "
1062 "libc_bits_set %d, libc_bits %d", getpid (),
1063 sid_bits_set, sid_bits, libc_bits_set, libc_bits);
Dave Wallace048b1d62018-01-03 22:24:41 -05001064 }
1065
1066 if (PREDICT_FALSE (!sid_bits && !libc_bits))
1067 {
1068 errno = EINVAL;
1069 rv = -1;
1070 goto done;
1071 }
1072
1073 do
1074 {
1075 if (sid_bits)
1076 {
Florin Corasdfe4cf42018-11-28 22:13:45 -08001077 if (!ldpw->select_vcl)
Dave Wallace048b1d62018-01-03 22:24:41 -05001078 {
1079 func_str = "vppcom_select";
1080
1081 if (readfds)
Florin Corasdfe4cf42018-11-28 22:13:45 -08001082 clib_memcpy_fast (ldpw->rd_bitmap, ldpw->sid_rd_bitmap,
1083 vec_len (ldpw->rd_bitmap) *
Dave Barach178cf492018-11-13 16:34:13 -05001084 sizeof (clib_bitmap_t));
Dave Wallace048b1d62018-01-03 22:24:41 -05001085 if (writefds)
Florin Corasdfe4cf42018-11-28 22:13:45 -08001086 clib_memcpy_fast (ldpw->wr_bitmap, ldpw->sid_wr_bitmap,
1087 vec_len (ldpw->wr_bitmap) *
Dave Barach178cf492018-11-13 16:34:13 -05001088 sizeof (clib_bitmap_t));
Dave Wallace048b1d62018-01-03 22:24:41 -05001089 if (exceptfds)
Florin Corasdfe4cf42018-11-28 22:13:45 -08001090 clib_memcpy_fast (ldpw->ex_bitmap, ldpw->sid_ex_bitmap,
1091 vec_len (ldpw->ex_bitmap) *
Dave Barach178cf492018-11-13 16:34:13 -05001092 sizeof (clib_bitmap_t));
Dave Wallace048b1d62018-01-03 22:24:41 -05001093
1094 rv = vppcom_select (sid_bits,
Florin Corasdfe4cf42018-11-28 22:13:45 -08001095 readfds ? ldpw->rd_bitmap : NULL,
1096 writefds ? ldpw->wr_bitmap : NULL,
1097 exceptfds ? ldpw->ex_bitmap : NULL, 0);
Dave Wallace048b1d62018-01-03 22:24:41 -05001098 if (rv < 0)
1099 {
1100 errno = -rv;
1101 rv = -1;
1102 }
1103 else if (rv > 0)
1104 {
1105 if (readfds)
1106 {
1107 /* *INDENT-OFF* */
Florin Corasdfe4cf42018-11-28 22:13:45 -08001108 clib_bitmap_foreach (sid, ldpw->rd_bitmap,
Dave Wallace048b1d62018-01-03 22:24:41 -05001109 ({
Florin Coras30e273b2018-11-27 00:04:59 -08001110 fd = ldp_fd_from_sid (vppcom_session_handle (sid));
Dave Wallace048b1d62018-01-03 22:24:41 -05001111 if (PREDICT_FALSE (fd < 0))
1112 {
1113 errno = EBADFD;
1114 rv = -1;
1115 goto done;
1116 }
1117 FD_SET (fd, readfds);
1118 }));
1119 /* *INDENT-ON* */
1120 }
1121 if (writefds)
1122 {
1123 /* *INDENT-OFF* */
Florin Corasdfe4cf42018-11-28 22:13:45 -08001124 clib_bitmap_foreach (sid, ldpw->wr_bitmap,
Dave Wallace048b1d62018-01-03 22:24:41 -05001125 ({
Florin Coras30e273b2018-11-27 00:04:59 -08001126 fd = ldp_fd_from_sid (vppcom_session_handle (sid));
Dave Wallace048b1d62018-01-03 22:24:41 -05001127 if (PREDICT_FALSE (fd < 0))
1128 {
1129 errno = EBADFD;
1130 rv = -1;
1131 goto done;
1132 }
1133 FD_SET (fd, writefds);
1134 }));
1135 /* *INDENT-ON* */
1136 }
1137 if (exceptfds)
1138 {
1139 /* *INDENT-OFF* */
Florin Corasdfe4cf42018-11-28 22:13:45 -08001140 clib_bitmap_foreach (sid, ldpw->ex_bitmap,
Dave Wallace048b1d62018-01-03 22:24:41 -05001141 ({
Florin Coras30e273b2018-11-27 00:04:59 -08001142 fd = ldp_fd_from_sid (vppcom_session_handle (sid));
Dave Wallace048b1d62018-01-03 22:24:41 -05001143 if (PREDICT_FALSE (fd < 0))
1144 {
1145 errno = EBADFD;
1146 rv = -1;
1147 goto done;
1148 }
1149 FD_SET (fd, exceptfds);
1150 }));
1151 /* *INDENT-ON* */
1152 }
Florin Corasdfe4cf42018-11-28 22:13:45 -08001153 ldpw->select_vcl = 1;
Dave Wallace048b1d62018-01-03 22:24:41 -05001154 goto done;
1155 }
1156 }
1157 else
Florin Corasdfe4cf42018-11-28 22:13:45 -08001158 ldpw->select_vcl = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -05001159 }
1160 if (libc_bits)
1161 {
1162 struct timespec tspec;
1163
1164 func_str = "libc_pselect";
1165
1166 if (readfds)
Florin Corasdfe4cf42018-11-28 22:13:45 -08001167 clib_memcpy_fast (readfds, ldpw->libc_rd_bitmap,
1168 vec_len (ldpw->rd_bitmap) *
Dave Barach178cf492018-11-13 16:34:13 -05001169 sizeof (clib_bitmap_t));
Dave Wallace048b1d62018-01-03 22:24:41 -05001170 if (writefds)
Florin Corasdfe4cf42018-11-28 22:13:45 -08001171 clib_memcpy_fast (writefds, ldpw->libc_wr_bitmap,
1172 vec_len (ldpw->wr_bitmap) *
Dave Barach178cf492018-11-13 16:34:13 -05001173 sizeof (clib_bitmap_t));
Dave Wallace048b1d62018-01-03 22:24:41 -05001174 if (exceptfds)
Florin Corasdfe4cf42018-11-28 22:13:45 -08001175 clib_memcpy_fast (exceptfds, ldpw->libc_ex_bitmap,
1176 vec_len (ldpw->ex_bitmap) *
Dave Barach178cf492018-11-13 16:34:13 -05001177 sizeof (clib_bitmap_t));
Dave Wallace048b1d62018-01-03 22:24:41 -05001178 tspec.tv_sec = tspec.tv_nsec = 0;
1179 rv = libc_pselect (libc_bits,
1180 readfds ? readfds : NULL,
1181 writefds ? writefds : NULL,
1182 exceptfds ? exceptfds : NULL, &tspec, sigmask);
1183 if (rv != 0)
1184 goto done;
1185 }
1186 }
Florin Corasdfe4cf42018-11-28 22:13:45 -08001187 while ((time_out == -1) || (clib_time_now (&ldpw->clib_time) < time_out));
Dave Wallace048b1d62018-01-03 22:24:41 -05001188 rv = 0;
1189
1190done:
1191 /* TBD: set timeout to amount of time left */
Florin Corasdfe4cf42018-11-28 22:13:45 -08001192 clib_bitmap_zero (ldpw->rd_bitmap);
1193 clib_bitmap_zero (ldpw->sid_rd_bitmap);
1194 clib_bitmap_zero (ldpw->libc_rd_bitmap);
1195 clib_bitmap_zero (ldpw->wr_bitmap);
1196 clib_bitmap_zero (ldpw->sid_wr_bitmap);
1197 clib_bitmap_zero (ldpw->libc_wr_bitmap);
1198 clib_bitmap_zero (ldpw->ex_bitmap);
1199 clib_bitmap_zero (ldpw->sid_ex_bitmap);
1200 clib_bitmap_zero (ldpw->libc_ex_bitmap);
Dave Wallace048b1d62018-01-03 22:24:41 -05001201
Dave Wallace2a865272018-02-07 21:00:42 -05001202 if (LDP_DEBUG > 3)
Dave Wallace048b1d62018-01-03 22:24:41 -05001203 {
1204 if (rv < 0)
1205 {
1206 int errno_val = errno;
1207 perror (func_str);
1208 clib_warning ("LDP<%d>: ERROR: %s() failed! "
1209 "rv %d, errno = %d", getpid (),
1210 func_str, rv, errno_val);
1211 errno = errno_val;
1212 }
1213 else
1214 clib_warning ("LDP<%d>: returning %d (0x%x)", getpid (), rv, rv);
1215 }
1216 return rv;
1217}
1218
1219int
1220select (int nfds, fd_set * __restrict readfds,
1221 fd_set * __restrict writefds,
1222 fd_set * __restrict exceptfds, struct timeval *__restrict timeout)
1223{
1224 struct timespec tspec;
1225
1226 if (timeout)
1227 {
1228 tspec.tv_sec = timeout->tv_sec;
1229 tspec.tv_nsec = timeout->tv_usec * 1000;
1230 }
Dave Wallace2a865272018-02-07 21:00:42 -05001231 return ldp_pselect (nfds, readfds, writefds, exceptfds,
1232 timeout ? &tspec : NULL, NULL);
Dave Wallace048b1d62018-01-03 22:24:41 -05001233}
1234
1235#ifdef __USE_XOPEN2K
1236int
1237pselect (int nfds, fd_set * __restrict readfds,
1238 fd_set * __restrict writefds,
1239 fd_set * __restrict exceptfds,
1240 const struct timespec *__restrict timeout,
1241 const __sigset_t * __restrict sigmask)
1242{
Dave Wallace2a865272018-02-07 21:00:42 -05001243 return ldp_pselect (nfds, readfds, writefds, exceptfds, timeout, 0);
Dave Wallace048b1d62018-01-03 22:24:41 -05001244}
1245#endif
1246
1247int
1248socket (int domain, int type, int protocol)
1249{
1250 const char *func_str;
1251 int rv;
1252 u8 is_nonblocking = type & SOCK_NONBLOCK ? 1 : 0;
1253 int sock_type = type & ~(SOCK_CLOEXEC | SOCK_NONBLOCK);
1254
Dave Wallace2a865272018-02-07 21:00:42 -05001255 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001256 return -1;
1257
1258 if (((domain == AF_INET) || (domain == AF_INET6)) &&
1259 ((sock_type == SOCK_STREAM) || (sock_type == SOCK_DGRAM)))
1260 {
1261 int sid;
Dave Wallace048b1d62018-01-03 22:24:41 -05001262 u8 proto = ((sock_type == SOCK_DGRAM) ?
1263 VPPCOM_PROTO_UDP : VPPCOM_PROTO_TCP);
1264
1265 func_str = "vppcom_session_create";
1266
Florin Coras99368312018-08-02 10:45:44 -07001267 LDBG (0, "LDP<%d>: : calling %s(): proto %u (%s), is_nonblocking %u",
1268 getpid (), func_str, proto, vppcom_proto_str (proto),
1269 is_nonblocking);
Dave Wallace048b1d62018-01-03 22:24:41 -05001270
Dave Wallacec04cbf12018-02-07 18:14:02 -05001271 sid = vppcom_session_create (proto, is_nonblocking);
Dave Wallace048b1d62018-01-03 22:24:41 -05001272 if (sid < 0)
1273 {
1274 errno = -sid;
1275 rv = -1;
1276 }
1277 else
1278 {
Dave Wallace2a865272018-02-07 21:00:42 -05001279 func_str = "ldp_fd_from_sid";
Florin Coras30e273b2018-11-27 00:04:59 -08001280 rv = ldp_fd_alloc (sid);
Dave Wallace048b1d62018-01-03 22:24:41 -05001281 if (rv < 0)
1282 {
1283 (void) vppcom_session_close (sid);
1284 errno = -rv;
1285 rv = -1;
1286 }
1287 }
1288 }
1289 else
1290 {
1291 func_str = "libc_socket";
1292
Florin Coras99368312018-08-02 10:45:44 -07001293 LDBG (0, "LDP<%d>: : calling %s()", getpid (), func_str);
Dave Wallace048b1d62018-01-03 22:24:41 -05001294
1295 rv = libc_socket (domain, type, protocol);
1296 }
1297
Dave Wallace2a865272018-02-07 21:00:42 -05001298 if (LDP_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001299 {
1300 if (rv < 0)
1301 {
1302 int errno_val = errno;
1303 perror (func_str);
1304 clib_warning ("LDP<%d>: ERROR: %s() failed! "
1305 "rv %d, errno = %d",
1306 getpid (), func_str, rv, errno_val);
1307 errno = errno_val;
1308 }
1309 else
1310 clib_warning ("LDP<%d>: : returning fd %d (0x%x)", getpid (), rv, rv);
1311 }
1312 return rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001313}
1314
1315/*
1316 * Create two new sockets, of type TYPE in domain DOMAIN and using
1317 * protocol PROTOCOL, which are connected to each other, and put file
1318 * descriptors for them in FDS[0] and FDS[1]. If PROTOCOL is zero,
1319 * one will be chosen automatically.
1320 * Returns 0 on success, -1 for errors.
1321 * */
1322int
Dave Wallace048b1d62018-01-03 22:24:41 -05001323socketpair (int domain, int type, int protocol, int fds[2])
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001324{
Dave Wallace048b1d62018-01-03 22:24:41 -05001325 const char *func_str;
1326 int rv;
1327 int sock_type = type & ~(SOCK_CLOEXEC | SOCK_NONBLOCK);
1328
Dave Wallace2a865272018-02-07 21:00:42 -05001329 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001330 return -1;
1331
1332 if (((domain == AF_INET) || (domain == AF_INET6)) &&
1333 ((sock_type == SOCK_STREAM) || (sock_type == SOCK_DGRAM)))
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001334 {
Dave Wallace8aaba562018-01-18 17:21:19 -05001335 func_str = __func__;
1336
Dave Wallace048b1d62018-01-03 22:24:41 -05001337 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
1338 errno = ENOSYS;
1339 rv = -1;
1340 }
1341 else
1342 {
1343 func_str = "libc_socket";
1344
Florin Coras173bae32018-11-16 18:56:28 -08001345 LDBG (1, "LDP<%d>: : calling %s()", getpid (), func_str);
Dave Wallace048b1d62018-01-03 22:24:41 -05001346
Florin Coras173bae32018-11-16 18:56:28 -08001347 rv = libc_socketpair (domain, type, protocol, fds);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001348 }
1349
Dave Wallace2a865272018-02-07 21:00:42 -05001350 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05001351 {
1352 if (rv < 0)
1353 {
1354 int errno_val = errno;
1355 perror (func_str);
1356 clib_warning ("LDP<%d>: ERROR: %s() failed! "
1357 "rv %d, errno = %d",
1358 getpid (), func_str, rv, errno_val);
1359 errno = errno_val;
1360 }
1361 else
1362 clib_warning ("LDP<%d>: : returning fd %d (0x%x)", getpid (), rv, rv);
1363 }
1364 return rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001365}
1366
1367int
Dave Wallace048b1d62018-01-03 22:24:41 -05001368bind (int fd, __CONST_SOCKADDR_ARG addr, socklen_t len)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001369{
1370 int rv;
Dave Wallace048b1d62018-01-03 22:24:41 -05001371 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05001372 u32 sid = ldp_sid_from_fd (fd);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001373
Dave Wallace2a865272018-02-07 21:00:42 -05001374 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001375 return -1;
1376
1377 if (sid != INVALID_SESSION_ID)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001378 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001379 vppcom_endpt_t ep;
1380
1381 func_str = "vppcom_session_bind";
1382
Dave Wallace048b1d62018-01-03 22:24:41 -05001383 switch (addr->sa_family)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001384 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001385 case AF_INET:
1386 if (len != sizeof (struct sockaddr_in))
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001387 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001388 clib_warning
1389 ("LDP<%d>: ERROR: fd %d (0x%x): sid %u (0x%x): Invalid "
1390 "AF_INET addr len %u!", getpid (), fd, fd, sid, sid, len);
1391 errno = EINVAL;
1392 rv = -1;
1393 goto done;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001394 }
Dave Wallace048b1d62018-01-03 22:24:41 -05001395 ep.is_ip4 = VPPCOM_IS_IP4;
1396 ep.ip = (u8 *) & ((const struct sockaddr_in *) addr)->sin_addr;
1397 ep.port = (u16) ((const struct sockaddr_in *) addr)->sin_port;
1398 break;
1399
1400 case AF_INET6:
1401 if (len != sizeof (struct sockaddr_in6))
1402 {
1403 clib_warning
1404 ("LDP<%d>: ERROR: fd %d (0x%x): sid %u (0x%x): Invalid "
1405 "AF_INET6 addr len %u!", getpid (), fd, fd, sid, sid, len);
1406 errno = EINVAL;
1407 rv = -1;
1408 goto done;
1409 }
1410 ep.is_ip4 = VPPCOM_IS_IP6;
1411 ep.ip = (u8 *) & ((const struct sockaddr_in6 *) addr)->sin6_addr;
1412 ep.port = (u16) ((const struct sockaddr_in6 *) addr)->sin6_port;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001413 break;
1414
1415 default:
Dave Wallace048b1d62018-01-03 22:24:41 -05001416 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): sid %u (0x%x): "
1417 "Unsupported address family %u!",
1418 getpid (), fd, fd, sid, sid, addr->sa_family);
1419 errno = EAFNOSUPPORT;
1420 rv = -1;
1421 goto done;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001422 }
Dave Wallace2a865272018-02-07 21:00:42 -05001423 if (LDP_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001424 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), "
1425 "addr %p, len %u",
1426 getpid (), fd, fd, func_str, sid, sid, addr, len);
1427
1428 rv = vppcom_session_bind (sid, &ep);
1429 if (rv != VPPCOM_OK)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001430 {
1431 errno = -rv;
Dave Wallace048b1d62018-01-03 22:24:41 -05001432 rv = -1;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001433 }
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001434 }
Dave Wallace048b1d62018-01-03 22:24:41 -05001435 else
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001436 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001437 func_str = "libc_bind";
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001438
Dave Wallace2a865272018-02-07 21:00:42 -05001439 if (LDP_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001440 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1441 "addr %p, len %u",
1442 getpid (), fd, fd, func_str, addr, len);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001443
Dave Wallace048b1d62018-01-03 22:24:41 -05001444 rv = libc_bind (fd, addr, len);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001445 }
1446
Dave Wallace048b1d62018-01-03 22:24:41 -05001447done:
Dave Wallace2a865272018-02-07 21:00:42 -05001448 if (LDP_DEBUG > 0)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001449 {
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001450 if (rv < 0)
1451 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001452 int errno_val = errno;
1453 perror (func_str);
1454 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
1455 "rv %d, errno = %d", getpid (), fd, fd,
1456 func_str, rv, errno_val);
1457 errno = errno_val;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001458 }
Dave Wallace048b1d62018-01-03 22:24:41 -05001459 else
1460 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
1461 getpid (), fd, fd, rv, rv);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001462 }
1463 return rv;
1464}
1465
1466static inline int
Dave Wallace2a865272018-02-07 21:00:42 -05001467ldp_copy_ep_to_sockaddr (__SOCKADDR_ARG addr, socklen_t * __restrict len,
1468 vppcom_endpt_t * ep)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001469{
Dave Wallace048b1d62018-01-03 22:24:41 -05001470 int rv = 0;
1471 int sa_len, copy_len;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001472
Dave Wallace2a865272018-02-07 21:00:42 -05001473 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001474 return -1;
1475
1476 if (addr && len && ep)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001477 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001478 addr->sa_family = (ep->is_ip4 == VPPCOM_IS_IP4) ? AF_INET : AF_INET6;
1479 switch (addr->sa_family)
1480 {
1481 case AF_INET:
1482 ((struct sockaddr_in *) addr)->sin_port = ep->port;
1483 if (*len > sizeof (struct sockaddr_in))
1484 *len = sizeof (struct sockaddr_in);
1485 sa_len = sizeof (struct sockaddr_in) - sizeof (struct in_addr);
1486 copy_len = *len - sa_len;
1487 if (copy_len > 0)
1488 memcpy (&((struct sockaddr_in *) addr)->sin_addr, ep->ip,
1489 copy_len);
1490 break;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001491
Dave Wallace048b1d62018-01-03 22:24:41 -05001492 case AF_INET6:
1493 ((struct sockaddr_in6 *) addr)->sin6_port = ep->port;
1494 if (*len > sizeof (struct sockaddr_in6))
1495 *len = sizeof (struct sockaddr_in6);
1496 sa_len = sizeof (struct sockaddr_in6) - sizeof (struct in6_addr);
1497 copy_len = *len - sa_len;
1498 if (copy_len > 0)
1499 memcpy (((struct sockaddr_in6 *) addr)->sin6_addr.
1500 __in6_u.__u6_addr8, ep->ip, copy_len);
1501 break;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001502
Dave Wallace048b1d62018-01-03 22:24:41 -05001503 default:
1504 /* Not possible */
1505 rv = -EAFNOSUPPORT;
1506 break;
1507 }
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001508 }
Dave Wallacee695cb42017-11-02 22:04:42 -04001509 return rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001510}
1511
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001512int
Dave Wallace048b1d62018-01-03 22:24:41 -05001513getsockname (int fd, __SOCKADDR_ARG addr, socklen_t * __restrict len)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001514{
1515 int rv;
Dave Wallace048b1d62018-01-03 22:24:41 -05001516 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05001517 u32 sid = ldp_sid_from_fd (fd);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001518
Dave Wallace2a865272018-02-07 21:00:42 -05001519 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001520 return -1;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001521
Dave Wallace048b1d62018-01-03 22:24:41 -05001522 if (sid != INVALID_SESSION_ID)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001523 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001524 vppcom_endpt_t ep;
1525 u8 addr_buf[sizeof (struct in6_addr)];
1526 u32 size = sizeof (ep);
1527
1528 ep.ip = addr_buf;
1529 func_str = "vppcom_session_attr[GET_LCL_ADDR]";
1530
Dave Wallace2a865272018-02-07 21:00:42 -05001531 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001532 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), "
1533 "addr %p, len %u",
1534 getpid (), fd, fd, func_str, sid, sid, addr, len);
1535
1536 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_LCL_ADDR, &ep, &size);
1537 if (rv != VPPCOM_OK)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001538 {
1539 errno = -rv;
Dave Wallace048b1d62018-01-03 22:24:41 -05001540 rv = -1;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001541 }
Dave Wallace048b1d62018-01-03 22:24:41 -05001542 else
1543 {
Dave Wallace2a865272018-02-07 21:00:42 -05001544 rv = ldp_copy_ep_to_sockaddr (addr, len, &ep);
Dave Wallace048b1d62018-01-03 22:24:41 -05001545 if (rv != VPPCOM_OK)
1546 {
1547 errno = -rv;
1548 rv = -1;
1549 }
1550 }
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001551 }
1552 else
1553 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001554 func_str = "libc_getsockname";
1555
Dave Wallace2a865272018-02-07 21:00:42 -05001556 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001557 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1558 "addr %p, len %u",
1559 getpid (), fd, fd, func_str, addr, len);
1560
1561 rv = libc_getsockname (fd, addr, len);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001562 }
1563
Dave Wallace2a865272018-02-07 21:00:42 -05001564 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001565 {
1566 if (rv < 0)
1567 {
1568 int errno_val = errno;
1569 perror (func_str);
1570 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
1571 "rv %d, errno = %d", getpid (), fd, fd,
1572 func_str, rv, errno_val);
1573 errno = errno_val;
1574 }
1575 else
1576 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
1577 getpid (), fd, fd, rv, rv);
1578 }
1579 return rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001580}
1581
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001582int
Dave Wallace048b1d62018-01-03 22:24:41 -05001583connect (int fd, __CONST_SOCKADDR_ARG addr, socklen_t len)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001584{
Dave Wallace048b1d62018-01-03 22:24:41 -05001585 int rv;
1586 const char *func_str = __func__;
Dave Wallace2a865272018-02-07 21:00:42 -05001587 u32 sid = ldp_sid_from_fd (fd);
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001588
Dave Wallace2a865272018-02-07 21:00:42 -05001589 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001590 return -1;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001591
Dave Wallace048b1d62018-01-03 22:24:41 -05001592 if (!addr)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001593 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001594 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): NULL addr, len %u",
1595 getpid (), fd, fd, len);
1596 errno = EINVAL;
1597 rv = -1;
1598 goto done;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001599 }
1600
Dave Wallace048b1d62018-01-03 22:24:41 -05001601 if (sid != INVALID_SESSION_ID)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001602 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001603 vppcom_endpt_t ep;
1604
1605 func_str = "vppcom_session_connect";
1606
Dave Wallace048b1d62018-01-03 22:24:41 -05001607 switch (addr->sa_family)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001608 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001609 case AF_INET:
1610 if (len != sizeof (struct sockaddr_in))
1611 {
1612 clib_warning
1613 ("LDP<%d>: fd %d (0x%x): ERROR sid %u (0x%x): Invalid "
1614 "AF_INET addr len %u!", getpid (), fd, fd, sid, sid, len);
1615 errno = EINVAL;
1616 rv = -1;
1617 goto done;
1618 }
1619 ep.is_ip4 = VPPCOM_IS_IP4;
1620 ep.ip = (u8 *) & ((const struct sockaddr_in *) addr)->sin_addr;
1621 ep.port = (u16) ((const struct sockaddr_in *) addr)->sin_port;
1622 break;
1623
1624 case AF_INET6:
1625 if (len != sizeof (struct sockaddr_in6))
1626 {
1627 clib_warning
1628 ("LDP<%d>: fd %d (0x%x): ERROR sid %u (0x%x): Invalid "
1629 "AF_INET6 addr len %u!", getpid (), fd, fd, sid, sid, len);
1630 errno = EINVAL;
1631 rv = -1;
1632 goto done;
1633 }
1634 ep.is_ip4 = VPPCOM_IS_IP6;
1635 ep.ip = (u8 *) & ((const struct sockaddr_in6 *) addr)->sin6_addr;
1636 ep.port = (u16) ((const struct sockaddr_in6 *) addr)->sin6_port;
1637 break;
1638
1639 default:
1640 clib_warning ("LDP<%d>: fd %d (0x%x): ERROR sid %u (0x%x): "
1641 "Unsupported address family %u!",
1642 getpid (), fd, fd, sid, sid, addr->sa_family);
1643 errno = EAFNOSUPPORT;
1644 rv = -1;
1645 goto done;
1646 }
Dave Wallace2a865272018-02-07 21:00:42 -05001647 if (LDP_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001648 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x) "
1649 "addr %p len %u",
1650 getpid (), fd, fd, func_str, sid, sid, addr, len);
1651
1652 rv = vppcom_session_connect (sid, &ep);
1653 if (rv != VPPCOM_OK)
1654 {
1655 errno = -rv;
1656 rv = -1;
1657 }
1658 }
1659 else
1660 {
1661 func_str = "libc_connect";
1662
Dave Wallace2a865272018-02-07 21:00:42 -05001663 if (LDP_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001664 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1665 "addr %p, len %u",
1666 getpid (), fd, fd, func_str, addr, len);
1667
1668 rv = libc_connect (fd, addr, len);
1669 }
1670
1671done:
Dave Wallace2a865272018-02-07 21:00:42 -05001672 if (LDP_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001673 {
1674 if (rv < 0)
1675 {
1676 int errno_val = errno;
1677 perror (func_str);
1678 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
1679 "rv %d, errno = %d", getpid (), fd, fd,
1680 func_str, rv, errno_val);
1681 errno = errno_val;
1682 }
1683 else
1684 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
1685 getpid (), fd, fd, rv, rv);
1686 }
1687 return rv;
1688}
1689
1690int
1691getpeername (int fd, __SOCKADDR_ARG addr, socklen_t * __restrict len)
1692{
1693 int rv;
1694 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05001695 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05001696
Dave Wallace2a865272018-02-07 21:00:42 -05001697 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001698 return -1;
1699
Dave Wallace048b1d62018-01-03 22:24:41 -05001700 if (sid != INVALID_SESSION_ID)
1701 {
1702 vppcom_endpt_t ep;
1703 u8 addr_buf[sizeof (struct in6_addr)];
1704 u32 size = sizeof (ep);
1705
1706 ep.ip = addr_buf;
1707 func_str = "vppcom_session_attr[GET_PEER_ADDR]";
1708
Dave Wallace2a865272018-02-07 21:00:42 -05001709 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001710 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), "
1711 "addr %p, len %u",
1712 getpid (), fd, fd, func_str, sid, sid, addr, len);
1713
1714 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_PEER_ADDR, &ep, &size);
1715 if (rv != VPPCOM_OK)
1716 {
1717 errno = -rv;
1718 rv = -1;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001719 }
1720 else
1721 {
Dave Wallace2a865272018-02-07 21:00:42 -05001722 rv = ldp_copy_ep_to_sockaddr (addr, len, &ep);
Dave Wallace048b1d62018-01-03 22:24:41 -05001723 if (rv != VPPCOM_OK)
1724 {
1725 errno = -rv;
1726 rv = -1;
1727 }
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001728 }
1729 }
Dave Wallace048b1d62018-01-03 22:24:41 -05001730 else
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001731 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001732 func_str = "libc_getpeername";
1733
Dave Wallace2a865272018-02-07 21:00:42 -05001734 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001735 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1736 "addr %p, len %u",
1737 getpid (), fd, fd, func_str, addr, len);
1738
1739 rv = libc_getpeername (fd, addr, len);
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001740 }
1741
Dave Wallace2a865272018-02-07 21:00:42 -05001742 if (LDP_DEBUG > 2)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001743 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001744 if (rv < 0)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001745 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001746 int errno_val = errno;
1747 perror (func_str);
1748 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
1749 "rv %d, errno = %d", getpid (), fd, fd,
1750 func_str, rv, errno_val);
1751 errno = errno_val;
1752 }
1753 else
1754 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
1755 getpid (), fd, fd, rv, rv);
1756 }
1757 return rv;
1758}
1759
1760ssize_t
1761send (int fd, const void *buf, size_t n, int flags)
1762{
1763 ssize_t size;
1764 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05001765 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05001766
Dave Wallace2a865272018-02-07 21:00:42 -05001767 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001768 return -1;
1769
1770 if (sid != INVALID_SESSION_ID)
1771 {
1772
1773 func_str = "vppcom_session_sendto";
1774
Dave Wallace2a865272018-02-07 21:00:42 -05001775 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001776 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), "
1777 "buf %p, n %u, flags 0x%x",
1778 getpid (), fd, fd, func_str, sid, sid, buf, n, flags);
1779
1780 size = vppcom_session_sendto (sid, (void *) buf, n, flags, NULL);
qchangaa8f63c2018-05-30 11:44:18 -07001781 if (size < VPPCOM_OK)
Dave Wallace048b1d62018-01-03 22:24:41 -05001782 {
1783 errno = -size;
1784 size = -1;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001785 }
1786 }
Dave Wallace048b1d62018-01-03 22:24:41 -05001787 else
1788 {
1789 func_str = "libc_send";
1790
Dave Wallace2a865272018-02-07 21:00:42 -05001791 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001792 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1793 "buf %p, n %u, flags 0x%x",
1794 getpid (), fd, fd, func_str, buf, n, flags);
1795
1796 size = libc_send (fd, buf, n, flags);
1797 }
1798
Dave Wallace2a865272018-02-07 21:00:42 -05001799 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001800 {
1801 if (size < 0)
1802 {
1803 int errno_val = errno;
1804 perror (func_str);
1805 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
1806 "rv %d, errno = %d", getpid (), fd, fd,
1807 func_str, size, errno_val);
1808 errno = errno_val;
1809 }
1810 else
1811 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
1812 getpid (), fd, fd, size, size);
1813 }
1814 return size;
1815}
1816
1817ssize_t
1818sendfile (int out_fd, int in_fd, off_t * offset, size_t len)
1819{
Florin Corasdfe4cf42018-11-28 22:13:45 -08001820 ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
Dave Wallace048b1d62018-01-03 22:24:41 -05001821 ssize_t size = 0;
1822 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05001823 u32 sid = ldp_sid_from_fd (out_fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05001824
Dave Wallace2a865272018-02-07 21:00:42 -05001825 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001826 return -1;
1827
1828 if (sid != INVALID_SESSION_ID)
1829 {
1830 int rv;
1831 ssize_t results = 0;
1832 size_t n_bytes_left = len;
1833 size_t bytes_to_read;
1834 int nbytes;
1835 int errno_val;
1836 u8 eagain = 0;
1837 u32 flags, flags_len = sizeof (flags);
1838
1839 func_str = "vppcom_session_attr[GET_FLAGS]";
1840 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_FLAGS, &flags,
1841 &flags_len);
1842 if (PREDICT_FALSE (rv != VPPCOM_OK))
1843 {
1844 clib_warning ("LDP<%d>: ERROR: out fd %d (0x%x): %s(): "
1845 "sid %u (0x%x), returned %d (%s)!", getpid (),
1846 out_fd, out_fd, func_str, sid, sid, rv,
1847 vppcom_retval_str (rv));
1848
Florin Corasdfe4cf42018-11-28 22:13:45 -08001849 vec_reset_length (ldpw->io_buffer);
Dave Wallace048b1d62018-01-03 22:24:41 -05001850 errno = -rv;
1851 size = -1;
1852 goto done;
1853 }
1854
1855 if (offset)
1856 {
1857 off_t off = lseek (in_fd, *offset, SEEK_SET);
1858 if (PREDICT_FALSE (off == -1))
1859 {
1860 func_str = "lseek";
1861 errno_val = errno;
1862 clib_warning ("LDP<%d>: ERROR: out fd %d (0x%x): %s(): "
1863 "SEEK_SET failed: in_fd %d, offset %p, "
1864 "*offset %ld, rv %ld, errno %d", getpid (),
1865 out_fd, out_fd, in_fd, offset, *offset, off,
1866 errno_val);
1867 errno = errno_val;
1868 size = -1;
1869 goto done;
1870 }
1871
1872 ASSERT (off == *offset);
1873 }
1874
1875 do
1876 {
1877 func_str = "vppcom_session_attr[GET_NWRITE]";
1878 size = vppcom_session_attr (sid, VPPCOM_ATTR_GET_NWRITE, 0, 0);
1879 if (size < 0)
1880 {
1881 clib_warning
1882 ("LDP<%d>: ERROR: fd %d (0x%x): %s(): sid %u (0x%x), "
1883 "returned %d (%s)!", getpid (), out_fd, out_fd, func_str,
1884 sid, sid, size, vppcom_retval_str (size));
Florin Corasdfe4cf42018-11-28 22:13:45 -08001885 vec_reset_length (ldpw->io_buffer);
Dave Wallace048b1d62018-01-03 22:24:41 -05001886 errno = -size;
1887 size = -1;
1888 goto done;
1889 }
1890
1891 bytes_to_read = size;
Dave Wallace2a865272018-02-07 21:00:42 -05001892 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001893 clib_warning
1894 ("LDP<%d>: fd %d (0x%x): called %s(): sid %u (0x%x), "
1895 "results %ld, n_bytes_left %lu, bytes_to_read %lu", getpid (),
1896 out_fd, out_fd, func_str, sid, sid, results, n_bytes_left,
1897 bytes_to_read);
1898
1899 if (bytes_to_read == 0)
1900 {
1901 if (flags & O_NONBLOCK)
1902 {
1903 if (!results)
1904 {
Dave Wallace2a865272018-02-07 21:00:42 -05001905 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001906 clib_warning ("LDP<%d>: fd %d (0x%x): sid %u (0x%x): "
1907 "EAGAIN",
1908 getpid (), out_fd, out_fd, sid, sid);
1909 eagain = 1;
1910 }
1911 goto update_offset;
1912 }
1913 else
1914 continue;
1915 }
1916 bytes_to_read = clib_min (n_bytes_left, bytes_to_read);
Florin Corasdfe4cf42018-11-28 22:13:45 -08001917 vec_validate (ldpw->io_buffer, bytes_to_read);
1918 nbytes = libc_read (in_fd, ldpw->io_buffer, bytes_to_read);
Dave Wallace048b1d62018-01-03 22:24:41 -05001919 if (nbytes < 0)
1920 {
1921 func_str = "libc_read";
1922 errno_val = errno;
1923 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): in_fd (%d), "
1924 "io_buffer %p, bytes_to_read %lu, rv %d, "
1925 "errno %d", getpid (), out_fd, out_fd, func_str,
Florin Corasdfe4cf42018-11-28 22:13:45 -08001926 in_fd, ldpw->io_buffer, bytes_to_read, nbytes,
Dave Wallace048b1d62018-01-03 22:24:41 -05001927 errno_val);
1928 errno = errno_val;
1929
1930 if (results == 0)
1931 {
Florin Corasdfe4cf42018-11-28 22:13:45 -08001932 vec_reset_length (ldpw->io_buffer);
Dave Wallace048b1d62018-01-03 22:24:41 -05001933 size = -1;
1934 goto done;
1935 }
1936 goto update_offset;
1937 }
1938 func_str = "vppcom_session_write";
Dave Wallace2a865272018-02-07 21:00:42 -05001939 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001940 clib_warning
1941 ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), "
1942 "buf %p, nbytes %u: results %d, n_bytes_left %d", getpid (),
Florin Corasdfe4cf42018-11-28 22:13:45 -08001943 out_fd, out_fd, func_str, sid, sid, ldpw->io_buffer, nbytes,
Dave Wallace048b1d62018-01-03 22:24:41 -05001944 results, n_bytes_left);
1945
Florin Corasdfe4cf42018-11-28 22:13:45 -08001946 size = vppcom_session_write (sid, ldpw->io_buffer, nbytes);
Dave Wallace048b1d62018-01-03 22:24:41 -05001947 if (size < 0)
1948 {
1949 if (size == VPPCOM_EAGAIN)
1950 {
1951 if (flags & O_NONBLOCK)
1952 {
1953 if (!results)
1954 {
Dave Wallace2a865272018-02-07 21:00:42 -05001955 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001956 clib_warning
1957 ("LDP<%d>: fd %d (0x%x): sid %u (0x%x): "
1958 "EAGAIN", getpid (), out_fd, out_fd, sid, sid);
1959 eagain = 1;
1960 }
1961 goto update_offset;
1962 }
1963 else
1964 continue;
1965 }
1966 else
1967 {
1968 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s():"
1969 "sid %u, io_buffer %p, nbytes %u "
1970 "returned %d (%s)",
1971 getpid (), out_fd, out_fd, func_str,
Florin Corasdfe4cf42018-11-28 22:13:45 -08001972 sid, ldpw->io_buffer, nbytes,
Dave Wallace048b1d62018-01-03 22:24:41 -05001973 size, vppcom_retval_str (size));
1974 }
1975 if (results == 0)
1976 {
Florin Corasdfe4cf42018-11-28 22:13:45 -08001977 vec_reset_length (ldpw->io_buffer);
Dave Wallace048b1d62018-01-03 22:24:41 -05001978 errno = -size;
1979 size = -1;
1980 goto done;
1981 }
1982 goto update_offset;
1983 }
1984
1985 results += nbytes;
1986 ASSERT (n_bytes_left >= nbytes);
1987 n_bytes_left = n_bytes_left - nbytes;
1988 }
1989 while (n_bytes_left > 0);
1990
1991 update_offset:
Florin Corasdfe4cf42018-11-28 22:13:45 -08001992 vec_reset_length (ldpw->io_buffer);
Dave Wallace048b1d62018-01-03 22:24:41 -05001993 if (offset)
1994 {
1995 off_t off = lseek (in_fd, *offset, SEEK_SET);
1996 if (PREDICT_FALSE (off == -1))
1997 {
1998 func_str = "lseek";
1999 errno_val = errno;
2000 clib_warning ("LDP<%d>: ERROR: %s(): SEEK_SET failed: "
2001 "in_fd %d, offset %p, *offset %ld, "
2002 "rv %ld, errno %d", getpid (), in_fd,
2003 offset, *offset, off, errno_val);
2004 errno = errno_val;
2005 size = -1;
2006 goto done;
2007 }
2008
2009 ASSERT (off == *offset);
2010 *offset += results + 1;
2011 }
2012 if (eagain)
2013 {
2014 errno = EAGAIN;
2015 size = -1;
2016 }
2017 else
2018 size = results;
2019 }
2020 else
2021 {
2022 func_str = "libc_send";
2023
Dave Wallace2a865272018-02-07 21:00:42 -05002024 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002025 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2026 "in_fd %d, offset %p, len %u",
2027 getpid (), out_fd, out_fd, func_str,
2028 in_fd, offset, len);
2029
2030 size = libc_sendfile (out_fd, in_fd, offset, len);
2031 }
2032
2033done:
Dave Wallace2a865272018-02-07 21:00:42 -05002034 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002035 {
2036 if (size < 0)
2037 {
2038 int errno_val = errno;
2039 perror (func_str);
2040 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2041 "rv %d, errno = %d", getpid (), out_fd, out_fd,
2042 func_str, size, errno_val);
2043 errno = errno_val;
2044 }
2045 else
2046 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2047 getpid (), out_fd, out_fd, size, size);
2048 }
2049 return size;
2050}
2051
2052ssize_t
2053sendfile64 (int out_fd, int in_fd, off_t * offset, size_t len)
2054{
2055 return sendfile (out_fd, in_fd, offset, len);
2056}
2057
2058ssize_t
2059recv (int fd, void *buf, size_t n, int flags)
2060{
2061 ssize_t size;
2062 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05002063 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05002064
Dave Wallace2a865272018-02-07 21:00:42 -05002065 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002066 return -1;
2067
2068 if (sid != INVALID_SESSION_ID)
2069 {
2070 func_str = "vppcom_session_recvfrom";
2071
Dave Wallace2a865272018-02-07 21:00:42 -05002072 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002073 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2074 "sid %u (0x%x), buf %p, n %u, flags 0x%x", getpid (),
2075 fd, fd, func_str, sid, sid, buf, n, flags);
2076
2077 size = vppcom_session_recvfrom (sid, buf, n, flags, NULL);
2078 if (size < 0)
2079 {
2080 errno = -size;
2081 size = -1;
2082 }
2083 }
2084 else
2085 {
2086 func_str = "libc_recv";
2087
Dave Wallace2a865272018-02-07 21:00:42 -05002088 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002089 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2090 "buf %p, n %u, flags 0x%x", getpid (),
2091 fd, fd, func_str, buf, n, flags);
2092
2093 size = libc_recv (fd, buf, n, flags);
2094 }
2095
Dave Wallace2a865272018-02-07 21:00:42 -05002096 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002097 {
2098 if (size < 0)
2099 {
2100 int errno_val = errno;
2101 perror (func_str);
2102 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2103 "rv %d, errno = %d", getpid (), fd, fd,
2104 func_str, size, errno_val);
2105 errno = errno_val;
2106 }
2107 else
2108 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2109 getpid (), fd, fd, size, size);
2110 }
2111 return size;
2112}
2113
2114ssize_t
2115sendto (int fd, const void *buf, size_t n, int flags,
2116 __CONST_SOCKADDR_ARG addr, socklen_t addr_len)
2117{
2118 ssize_t size;
2119 const char *func_str = __func__;
Dave Wallace2a865272018-02-07 21:00:42 -05002120 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05002121
Dave Wallace2a865272018-02-07 21:00:42 -05002122 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002123 return -1;
2124
2125 if (sid != INVALID_SESSION_ID)
2126 {
2127 vppcom_endpt_t *ep = 0;
2128 vppcom_endpt_t _ep;
2129
2130 if (addr)
2131 {
2132 ep = &_ep;
Dave Wallace048b1d62018-01-03 22:24:41 -05002133 switch (addr->sa_family)
2134 {
2135 case AF_INET:
2136 ep->is_ip4 = VPPCOM_IS_IP4;
2137 ep->ip =
2138 (uint8_t *) & ((const struct sockaddr_in *) addr)->sin_addr;
2139 ep->port =
2140 (uint16_t) ((const struct sockaddr_in *) addr)->sin_port;
2141 break;
2142
2143 case AF_INET6:
2144 ep->is_ip4 = VPPCOM_IS_IP6;
2145 ep->ip =
2146 (uint8_t *) & ((const struct sockaddr_in6 *) addr)->sin6_addr;
2147 ep->port =
2148 (uint16_t) ((const struct sockaddr_in6 *) addr)->sin6_port;
2149 break;
2150
2151 default:
2152 errno = EAFNOSUPPORT;
2153 size = -1;
2154 goto done;
2155 }
2156 }
2157
2158 func_str = "vppcom_session_sendto";
2159
Dave Wallace2a865272018-02-07 21:00:42 -05002160 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002161 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2162 "sid %u (0x%x), buf %p, n %u, flags 0x%x, ep %p",
2163 getpid (), fd, fd, func_str, sid, sid, buf, n,
2164 flags, ep);
2165
2166 size = vppcom_session_sendto (sid, (void *) buf, n, flags, ep);
2167 if (size < 0)
2168 {
2169 errno = -size;
2170 size = -1;
2171 }
2172 }
2173 else
2174 {
2175 func_str = "libc_sendto";
2176
Dave Wallace2a865272018-02-07 21:00:42 -05002177 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002178 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2179 "buf %p, n %u, flags 0x%x, addr %p, addr_len %d",
2180 getpid (), fd, fd, func_str, buf, n, flags,
2181 addr, addr_len);
2182
2183 size = libc_sendto (fd, buf, n, flags, addr, addr_len);
2184 }
2185
2186done:
Dave Wallace2a865272018-02-07 21:00:42 -05002187 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002188 {
2189 if (size < 0)
2190 {
2191 int errno_val = errno;
2192 perror (func_str);
2193 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2194 "rv %d, errno = %d", getpid (), fd, fd,
2195 func_str, size, errno_val);
2196 errno = errno_val;
2197 }
2198 else
2199 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2200 getpid (), fd, fd, size, size);
2201 }
2202 return size;
2203}
2204
2205ssize_t
2206recvfrom (int fd, void *__restrict buf, size_t n, int flags,
2207 __SOCKADDR_ARG addr, socklen_t * __restrict addr_len)
2208{
2209 ssize_t size;
2210 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05002211 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05002212
Dave Wallace2a865272018-02-07 21:00:42 -05002213 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002214 return -1;
2215
2216 if (sid != INVALID_SESSION_ID)
2217 {
2218 vppcom_endpt_t ep;
2219 u8 src_addr[sizeof (struct sockaddr_in6)];
2220
2221 func_str = "vppcom_session_recvfrom";
2222
Dave Wallace2a865272018-02-07 21:00:42 -05002223 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002224 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2225 "sid %u (0x%x), buf %p, n %u, flags 0x%x, ep %p",
2226 getpid (), fd, fd, func_str, sid, sid, buf, n,
2227 flags, &ep);
2228 if (addr)
2229 {
2230 ep.ip = src_addr;
2231 size = vppcom_session_recvfrom (sid, buf, n, flags, &ep);
2232
2233 if (size > 0)
Dave Wallace2a865272018-02-07 21:00:42 -05002234 size = ldp_copy_ep_to_sockaddr (addr, addr_len, &ep);
Dave Wallace048b1d62018-01-03 22:24:41 -05002235 }
2236 else
2237 size = vppcom_session_recvfrom (sid, buf, n, flags, NULL);
2238
2239 if (size < 0)
2240 {
2241 errno = -size;
2242 size = -1;
2243 }
2244 }
2245 else
2246 {
2247 func_str = "libc_recvfrom";
2248
Dave Wallace2a865272018-02-07 21:00:42 -05002249 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002250 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2251 "buf %p, n %u, flags 0x%x, addr %p, addr_len %d",
2252 getpid (), fd, fd, func_str, buf, n, flags,
2253 addr, addr_len);
2254
2255 size = libc_recvfrom (fd, buf, n, flags, addr, addr_len);
2256 }
2257
Dave Wallace2a865272018-02-07 21:00:42 -05002258 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002259 {
2260 if (size < 0)
2261 {
2262 int errno_val = errno;
2263 perror (func_str);
2264 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2265 "rv %d, errno = %d", getpid (), fd, fd,
2266 func_str, size, errno_val);
2267 errno = errno_val;
2268 }
2269 else
2270 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2271 getpid (), fd, fd, size, size);
2272 }
2273 return size;
2274}
2275
2276ssize_t
2277sendmsg (int fd, const struct msghdr * message, int flags)
2278{
2279 ssize_t size;
2280 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05002281 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05002282
Dave Wallace2a865272018-02-07 21:00:42 -05002283 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002284 return -1;
2285
2286 if (sid != INVALID_SESSION_ID)
2287 {
Dave Wallace8aaba562018-01-18 17:21:19 -05002288 func_str = __func__;
2289
Dave Wallace048b1d62018-01-03 22:24:41 -05002290 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
2291 errno = ENOSYS;
2292 size = -1;
2293 }
2294 else
2295 {
2296 func_str = "libc_sendmsg";
2297
Dave Wallace2a865272018-02-07 21:00:42 -05002298 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002299 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2300 "message %p, flags 0x%x",
2301 getpid (), fd, fd, func_str, message, flags);
2302
2303 size = libc_sendmsg (fd, message, flags);
2304 }
2305
Dave Wallace2a865272018-02-07 21:00:42 -05002306 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002307 {
2308 if (size < 0)
2309 {
2310 int errno_val = errno;
2311 perror (func_str);
2312 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2313 "rv %d, errno = %d", getpid (), fd, fd,
2314 func_str, size, errno_val);
2315 errno = errno_val;
2316 }
2317 else
2318 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2319 getpid (), fd, fd, size, size);
2320 }
2321 return size;
2322}
2323
2324#ifdef USE_GNU
2325int
2326sendmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags)
2327{
2328 ssize_t size;
2329 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05002330 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05002331
Dave Wallace2a865272018-02-07 21:00:42 -05002332 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002333 return -1;
2334
2335 if (sid != INVALID_SESSION_ID)
2336 {
2337 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
2338 errno = ENOSYS;
2339 size = -1;
2340 }
2341 else
2342 {
2343 func_str = "libc_sendmmsg";
2344
Dave Wallace2a865272018-02-07 21:00:42 -05002345 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002346 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2347 "vmessages %p, vlen %u, flags 0x%x",
2348 getpid (), fd, fd, func_str, vmessages, vlen, flags);
2349
2350 size = libc_sendmmsg (fd, vmessages, vlen, flags);
2351 }
2352
Dave Wallace2a865272018-02-07 21:00:42 -05002353 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002354 {
2355 if (size < 0)
2356 {
2357 int errno_val = errno;
2358 perror (func_str);
2359 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2360 "rv %d, errno = %d", getpid (), fd, fd,
2361 func_str, size, errno_val);
2362 errno = errno_val;
2363 }
2364 else
2365 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2366 getpid (), fd, fd, size, size);
2367 }
2368 return size;
2369}
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002370#endif
2371
Dave Wallace048b1d62018-01-03 22:24:41 -05002372ssize_t
2373recvmsg (int fd, struct msghdr * message, int flags)
2374{
2375 ssize_t size;
2376 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05002377 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05002378
Dave Wallace2a865272018-02-07 21:00:42 -05002379 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002380 return -1;
2381
2382 if (sid != INVALID_SESSION_ID)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002383 {
Dave Wallace8aaba562018-01-18 17:21:19 -05002384 func_str = __func__;
2385
Dave Wallace048b1d62018-01-03 22:24:41 -05002386 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
2387 errno = ENOSYS;
2388 size = -1;
2389 }
2390 else
2391 {
2392 func_str = "libc_recvmsg";
2393
Dave Wallace2a865272018-02-07 21:00:42 -05002394 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002395 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2396 "message %p, flags 0x%x",
2397 getpid (), fd, fd, func_str, message, flags);
2398
2399 size = libc_recvmsg (fd, message, flags);
2400 }
2401
Dave Wallace2a865272018-02-07 21:00:42 -05002402 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002403 {
2404 if (size < 0)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002405 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002406 int errno_val = errno;
2407 perror (func_str);
2408 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2409 "rv %d, errno = %d", getpid (), fd, fd,
2410 func_str, size, errno_val);
2411 errno = errno_val;
2412 }
2413 else
2414 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2415 getpid (), fd, fd, size, size);
2416 }
2417 return size;
2418}
2419
2420#ifdef USE_GNU
2421int
2422recvmmsg (int fd, struct mmsghdr *vmessages,
2423 unsigned int vlen, int flags, struct timespec *tmo)
2424{
2425 ssize_t size;
2426 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05002427 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05002428
Dave Wallace2a865272018-02-07 21:00:42 -05002429 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002430 return -1;
2431
2432 if (sid != INVALID_SESSION_ID)
2433 {
2434 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
2435 errno = ENOSYS;
2436 size = -1;
2437 }
2438 else
2439 {
2440 func_str = "libc_recvmmsg";
2441
Dave Wallace2a865272018-02-07 21:00:42 -05002442 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002443 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2444 "vmessages %p, vlen %u, flags 0x%x, tmo %p",
2445 getpid (), fd, fd, func_str, vmessages, vlen,
2446 flags, tmo);
2447
2448 size = libc_recvmmsg (fd, vmessages, vlen, flags, tmo);
2449 }
2450
Dave Wallace2a865272018-02-07 21:00:42 -05002451 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002452 {
2453 if (size < 0)
2454 {
2455 int errno_val = errno;
2456 perror (func_str);
2457 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2458 "rv %d, errno = %d", getpid (), fd, fd,
2459 func_str, size, errno_val);
2460 errno = errno_val;
2461 }
2462 else
2463 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2464 getpid (), fd, fd, size, size);
2465 }
2466 return size;
2467}
2468#endif
2469
2470int
2471getsockopt (int fd, int level, int optname,
2472 void *__restrict optval, socklen_t * __restrict optlen)
2473{
2474 int rv;
2475 const char *func_str = __func__;
Dave Wallace2a865272018-02-07 21:00:42 -05002476 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace8aaba562018-01-18 17:21:19 -05002477 u32 buflen = optlen ? (u32) * optlen : 0;
Dave Wallace048b1d62018-01-03 22:24:41 -05002478
Dave Wallace2a865272018-02-07 21:00:42 -05002479 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002480 return -1;
2481
2482 if (sid != INVALID_SESSION_ID)
2483 {
2484 rv = -EOPNOTSUPP;
2485
2486 switch (level)
2487 {
2488 case SOL_TCP:
2489 switch (optname)
2490 {
2491 case TCP_NODELAY:
2492 func_str = "vppcom_session_attr[SOL_TCP,GET_TCP_NODELAY]";
Dave Wallace2a865272018-02-07 21:00:42 -05002493 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002494 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2495 "sid %u (0x%x)",
2496 getpid (), fd, fd, func_str, sid, sid);
2497 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_TCP_NODELAY,
2498 optval, optlen);
2499 break;
2500 case TCP_MAXSEG:
2501 func_str = "vppcom_session_attr[SOL_TCP,GET_TCP_USER_MSS]";
Dave Wallace2a865272018-02-07 21:00:42 -05002502 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002503 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2504 "sid %u (0x%x)",
2505 getpid (), fd, fd, func_str, sid, sid);
2506 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_TCP_USER_MSS,
2507 optval, optlen);
2508 break;
2509 case TCP_KEEPIDLE:
2510 func_str = "vppcom_session_attr[SOL_TCP,GET_TCP_KEEPIDLE]";
Dave Wallace2a865272018-02-07 21:00:42 -05002511 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002512 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2513 "sid %u (0x%x)",
2514 getpid (), fd, fd, func_str, sid, sid);
2515 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_TCP_KEEPIDLE,
2516 optval, optlen);
2517 break;
2518 case TCP_KEEPINTVL:
2519 func_str = "vppcom_session_attr[SOL_TCP,GET_TCP_KEEPINTVL]";
Dave Wallace2a865272018-02-07 21:00:42 -05002520 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002521 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2522 "sid %u (0x%x), SOL_TCP",
2523 getpid (), fd, fd, func_str, sid, sid);
2524 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_TCP_KEEPINTVL,
2525 optval, optlen);
2526 break;
2527 case TCP_INFO:
2528 if (optval && optlen && (*optlen == sizeof (struct tcp_info)))
2529 {
Dave Wallace2a865272018-02-07 21:00:42 -05002530 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002531 clib_warning ("LDP<%d>: fd %d (0x%x): sid %u (0x%x), "
2532 "SOL_TCP, TCP_INFO, optval %p, "
2533 "optlen %d: #LDP-NOP#",
2534 getpid (), fd, fd, sid, sid,
2535 optval, *optlen);
2536 memset (optval, 0, *optlen);
2537 rv = VPPCOM_OK;
2538 }
2539 else
2540 rv = -EFAULT;
2541 break;
2542 default:
Dave Wallace2a865272018-02-07 21:00:42 -05002543 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002544 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
2545 "sid %u (0x%x), SOL_TCP, "
2546 "optname %d unsupported!",
2547 getpid (), fd, fd, func_str, sid, sid, optname);
2548 break;
2549 }
2550 break;
2551 case SOL_IPV6:
2552 switch (optname)
2553 {
2554 case IPV6_V6ONLY:
2555 func_str = "vppcom_session_attr[SOL_IPV6,GET_V6ONLY]";
Dave Wallace2a865272018-02-07 21:00:42 -05002556 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002557 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2558 "sid %u (0x%x)",
2559 getpid (), fd, fd, func_str, sid, sid);
2560 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_V6ONLY,
2561 optval, optlen);
2562 break;
2563 default:
Dave Wallace2a865272018-02-07 21:00:42 -05002564 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002565 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
2566 "sid %u (0x%x), SOL_IPV6, "
2567 "optname %d unsupported!",
2568 getpid (), fd, fd, func_str, sid, sid, optname);
2569 break;
2570 }
2571 break;
2572 case SOL_SOCKET:
2573 switch (optname)
2574 {
2575 case SO_ACCEPTCONN:
2576 func_str = "vppcom_session_attr[SOL_SOCKET,GET_ACCEPTCONN]";
Dave Wallace2a865272018-02-07 21:00:42 -05002577 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002578 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2579 "sid %u (0x%x)",
2580 getpid (), fd, fd, func_str, sid, sid);
2581 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_LISTEN,
2582 optval, optlen);
2583 break;
2584 case SO_KEEPALIVE:
2585 func_str = "vppcom_session_attr[SOL_SOCKET,GET_KEEPALIVE]";
Dave Wallace2a865272018-02-07 21:00:42 -05002586 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002587 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2588 "sid %u (0x%x)",
2589 getpid (), fd, fd, func_str, sid, sid);
2590 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_KEEPALIVE,
2591 optval, optlen);
2592 break;
2593 case SO_PROTOCOL:
2594 func_str = "vppcom_session_attr[SOL_SOCKET,GET_PROTOCOL]";
Dave Wallace2a865272018-02-07 21:00:42 -05002595 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002596 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2597 "sid %u (0x%x)",
2598 getpid (), fd, fd, func_str, sid, sid);
2599 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_PROTOCOL,
2600 optval, optlen);
2601 *(int *) optval = *(int *) optval ? SOCK_DGRAM : SOCK_STREAM;
2602 break;
2603 case SO_SNDBUF:
2604 func_str = "vppcom_session_attr[SOL_SOCKET,GET_TX_FIFO_LEN]";
Dave Wallace2a865272018-02-07 21:00:42 -05002605 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002606 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2607 "sid %u (0x%x), optlen %d",
2608 getpid (), fd, fd, func_str, sid, sid, buflen);
2609 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_TX_FIFO_LEN,
2610 optval, optlen);
2611 break;
2612 case SO_RCVBUF:
2613 func_str = "vppcom_session_attr[SOL_SOCKET,GET_RX_FIFO_LEN]";
Dave Wallace2a865272018-02-07 21:00:42 -05002614 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002615 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2616 "sid %u (0x%x), optlen %d",
Dave Wallaceb4cd4ff2018-01-19 12:17:08 -05002617 getpid (), fd, fd, func_str, sid, sid, buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002618 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_RX_FIFO_LEN,
2619 optval, optlen);
2620 break;
2621 case SO_REUSEADDR:
2622 func_str = "vppcom_session_attr[SOL_SOCKET,GET_REUSEADDR]";
Dave Wallace2a865272018-02-07 21:00:42 -05002623 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002624 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2625 "sid %u (0x%x)",
2626 getpid (), fd, fd, func_str, sid, sid);
2627 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_REUSEADDR,
2628 optval, optlen);
2629 break;
2630 case SO_BROADCAST:
2631 func_str = "vppcom_session_attr[SOL_SOCKET,GET_BROADCAST]";
Dave Wallace2a865272018-02-07 21:00:42 -05002632 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002633 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2634 "sid %u (0x%x)",
2635 getpid (), fd, fd, func_str, sid, sid);
2636 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_BROADCAST,
2637 optval, optlen);
2638 break;
2639 case SO_ERROR:
2640 func_str = "vppcom_session_attr[SOL_SOCKET,GET_ERROR]";
Dave Wallace2a865272018-02-07 21:00:42 -05002641 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002642 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2643 "sid %u (0x%x)",
2644 getpid (), fd, fd, func_str, sid, sid);
2645 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_ERROR,
2646 optval, optlen);
2647 break;
2648 default:
Dave Wallace2a865272018-02-07 21:00:42 -05002649 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002650 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
2651 "sid %u (0x%x), SOL_SOCKET, "
2652 "optname %d unsupported!",
2653 getpid (), fd, fd, func_str, sid, sid, optname);
2654 break;
2655 }
2656 break;
2657 default:
2658 break;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002659 }
2660
Dave Wallace048b1d62018-01-03 22:24:41 -05002661 if (rv != VPPCOM_OK)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002662 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002663 errno = -rv;
2664 rv = -1;
2665 }
2666 }
2667 else
2668 {
2669 func_str = "libc_getsockopt";
2670
Dave Wallace2a865272018-02-07 21:00:42 -05002671 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002672 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): level %d, "
2673 "optname %d, optval %p, optlen %d",
2674 getpid (), fd, fd, func_str, level, optname,
2675 optval, optlen);
2676
2677 rv = libc_getsockopt (fd, level, optname, optval, optlen);
2678 }
2679
Dave Wallace2a865272018-02-07 21:00:42 -05002680 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002681 {
2682 if (rv < 0)
2683 {
2684 int errno_val = errno;
2685 perror (func_str);
2686 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2687 "rv %d, errno = %d", getpid (), fd, fd,
2688 func_str, rv, errno_val);
2689 errno = errno_val;
2690 }
2691 else
2692 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2693 getpid (), fd, fd, rv, rv);
2694 }
2695 return rv;
2696}
2697
2698int
2699setsockopt (int fd, int level, int optname,
2700 const void *optval, socklen_t optlen)
2701{
2702 int rv;
2703 const char *func_str = __func__;
Dave Wallace2a865272018-02-07 21:00:42 -05002704 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05002705
Dave Wallace2a865272018-02-07 21:00:42 -05002706 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002707 return -1;
2708
2709 if (sid != INVALID_SESSION_ID)
2710 {
2711 rv = -EOPNOTSUPP;
2712
2713 switch (level)
2714 {
2715 case SOL_TCP:
2716 switch (optname)
2717 {
2718 case TCP_NODELAY:
2719 func_str = "vppcom_session_attr[SOL_TCP,SET_TCP_NODELAY]";
Dave Wallace2a865272018-02-07 21:00:42 -05002720 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002721 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2722 "sid %u (0x%x)",
2723 getpid (), fd, fd, func_str, sid, sid);
2724 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_TCP_NODELAY,
2725 (void *) optval, &optlen);
2726 break;
2727 case TCP_MAXSEG:
2728 func_str = "vppcom_session_attr[SOL_TCP,SET_TCP_USER_MSS]";
Dave Wallace2a865272018-02-07 21:00:42 -05002729 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002730 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2731 "sid %u (0x%x)",
2732 getpid (), fd, fd, func_str, sid, sid);
2733 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_TCP_USER_MSS,
2734 (void *) optval, &optlen);
2735 break;
2736 case TCP_KEEPIDLE:
2737 func_str = "vppcom_session_attr[SOL_TCP,SET_TCP_KEEPIDLE]";
Dave Wallace2a865272018-02-07 21:00:42 -05002738 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002739 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2740 "sid %u (0x%x)",
2741 getpid (), fd, fd, func_str, sid, sid);
2742 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_TCP_KEEPIDLE,
2743 (void *) optval, &optlen);
2744 break;
2745 case TCP_KEEPINTVL:
2746 func_str = "vppcom_session_attr[SOL_TCP,SET_TCP_KEEPINTVL]";
Dave Wallace2a865272018-02-07 21:00:42 -05002747 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002748 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2749 "sid %u (0x%x), SOL_TCP",
2750 getpid (), fd, fd, func_str, sid, sid);
2751 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_TCP_KEEPINTVL,
2752 (void *) optval, &optlen);
2753 break;
2754 default:
Dave Wallace2a865272018-02-07 21:00:42 -05002755 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002756 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
2757 "sid %u (0x%x), SOL_TCP, "
2758 "optname %d unsupported!",
2759 getpid (), fd, fd, func_str, sid, sid, optname);
2760 break;
2761 }
2762 break;
2763 case SOL_IPV6:
2764 switch (optname)
2765 {
2766 case IPV6_V6ONLY:
2767 func_str = "vppcom_session_attr[SOL_IPV6,SET_V6ONLY]";
Dave Wallace2a865272018-02-07 21:00:42 -05002768 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002769 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2770 "sid %u (0x%x)",
2771 getpid (), fd, fd, func_str, sid, sid);
2772 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_V6ONLY,
2773 (void *) optval, &optlen);
2774 break;
2775 default:
Dave Wallace2a865272018-02-07 21:00:42 -05002776 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002777 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
2778 "sid %u (0x%x), SOL_IPV6, "
2779 "optname %d unsupported!",
2780 getpid (), fd, fd, func_str, sid, sid, optname);
2781 break;
2782 }
2783 break;
2784 case SOL_SOCKET:
2785 switch (optname)
2786 {
2787 case SO_KEEPALIVE:
2788 func_str = "vppcom_session_attr[SOL_SOCKET,SET_KEEPALIVE]";
Dave Wallace2a865272018-02-07 21:00:42 -05002789 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002790 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2791 "sid %u (0x%x)",
2792 getpid (), fd, fd, func_str, sid, sid);
2793 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_KEEPALIVE,
2794 (void *) optval, &optlen);
2795 break;
2796 case SO_REUSEADDR:
2797 func_str = "vppcom_session_attr[SOL_SOCKET,SET_REUSEADDR]";
Dave Wallace2a865272018-02-07 21:00:42 -05002798 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002799 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2800 "sid %u (0x%x)",
2801 getpid (), fd, fd, func_str, sid, sid);
2802 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_REUSEADDR,
2803 (void *) optval, &optlen);
2804 break;
2805 case SO_BROADCAST:
2806 func_str = "vppcom_session_attr[SOL_SOCKET,SET_BROADCAST]";
Dave Wallace2a865272018-02-07 21:00:42 -05002807 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002808 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2809 "sid %u (0x%x)",
2810 getpid (), fd, fd, func_str, sid, sid);
2811 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_BROADCAST,
2812 (void *) optval, &optlen);
2813 break;
2814 default:
Dave Wallace2a865272018-02-07 21:00:42 -05002815 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002816 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
2817 "sid %u (0x%x), SOL_SOCKET, "
2818 "optname %d unsupported!",
2819 getpid (), fd, fd, func_str, sid, sid, optname);
2820 break;
2821 }
2822 break;
2823 default:
2824 break;
2825 }
2826
2827 if (rv != VPPCOM_OK)
2828 {
2829 errno = -rv;
2830 rv = -1;
2831 }
2832 }
2833 else
2834 {
2835 func_str = "libc_setsockopt";
2836
Dave Wallace2a865272018-02-07 21:00:42 -05002837 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002838 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): level %d, "
2839 "optname %d, optval %p, optlen %d",
2840 getpid (), fd, fd, func_str, level, optname,
2841 optval, optlen);
2842
2843 rv = libc_setsockopt (fd, level, optname, optval, optlen);
2844 }
2845
Dave Wallace2a865272018-02-07 21:00:42 -05002846 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002847 {
2848 if (rv < 0)
2849 {
2850 int errno_val = errno;
2851 perror (func_str);
2852 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2853 "rv %d, errno = %d", getpid (), fd, fd,
2854 func_str, rv, errno_val);
2855 errno = errno_val;
2856 }
2857 else
2858 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2859 getpid (), fd, fd, rv, rv);
2860 }
2861 return rv;
2862}
2863
2864int
2865listen (int fd, int n)
2866{
2867 int rv;
2868 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05002869 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05002870
Dave Wallace2a865272018-02-07 21:00:42 -05002871 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002872 return -1;
2873
2874 if (sid != INVALID_SESSION_ID)
2875 {
2876 func_str = "vppcom_session_listen";
2877
Florin Coras99368312018-08-02 10:45:44 -07002878 LDBG (0, "LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), n %d",
2879 getpid (), fd, fd, func_str, sid, sid, n);
Dave Wallace048b1d62018-01-03 22:24:41 -05002880
2881 rv = vppcom_session_listen (sid, n);
2882 if (rv != VPPCOM_OK)
2883 {
2884 errno = -rv;
2885 rv = -1;
2886 }
2887 }
2888 else
2889 {
2890 func_str = "libc_listen";
2891
Florin Coras99368312018-08-02 10:45:44 -07002892 LDBG (0, "LDP<%d>: fd %d (0x%x): calling %s(): n %d", getpid (), fd,
2893 fd, func_str, n);
Dave Wallace048b1d62018-01-03 22:24:41 -05002894
2895 rv = libc_listen (fd, n);
2896 }
2897
Dave Wallace2a865272018-02-07 21:00:42 -05002898 if (LDP_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002899 {
2900 if (rv < 0)
2901 {
2902 int errno_val = errno;
2903 perror (func_str);
2904 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2905 "rv %d, errno = %d", getpid (), fd, fd,
2906 func_str, rv, errno_val);
2907 errno = errno_val;
2908 }
2909 else
2910 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2911 getpid (), fd, fd, rv, rv);
2912 }
2913 return rv;
2914}
2915
2916static inline int
Dave Wallace2a865272018-02-07 21:00:42 -05002917ldp_accept4 (int listen_fd, __SOCKADDR_ARG addr,
2918 socklen_t * __restrict addr_len, int flags)
Dave Wallace048b1d62018-01-03 22:24:41 -05002919{
2920 int rv;
2921 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05002922 u32 listen_sid = ldp_sid_from_fd (listen_fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05002923 int accept_sid;
2924
Dave Wallace2a865272018-02-07 21:00:42 -05002925 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002926 return -1;
2927
2928 if (listen_sid != INVALID_SESSION_ID)
2929 {
2930 vppcom_endpt_t ep;
2931 u8 src_addr[sizeof (struct sockaddr_in6)];
Dave Wallace8aaba562018-01-18 17:21:19 -05002932 memset (&ep, 0, sizeof (ep));
Dave Wallace048b1d62018-01-03 22:24:41 -05002933 ep.ip = src_addr;
2934
2935 func_str = "vppcom_session_accept";
2936
Dave Wallace2a865272018-02-07 21:00:42 -05002937 if (LDP_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002938 clib_warning ("LDP<%d>: listen fd %d (0x%x): calling %s(): "
2939 "listen sid %u (0x%x), ep %p, flags 0x%x",
2940 getpid (), listen_fd, listen_fd, func_str,
2941 listen_sid, listen_sid, ep, flags);
2942
2943 accept_sid = vppcom_session_accept (listen_sid, &ep, flags);
2944 if (accept_sid < 0)
2945 {
2946 errno = -accept_sid;
2947 rv = -1;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002948 }
2949 else
2950 {
Dave Wallace2a865272018-02-07 21:00:42 -05002951 rv = ldp_copy_ep_to_sockaddr (addr, addr_len, &ep);
Dave Wallace048b1d62018-01-03 22:24:41 -05002952 if (rv != VPPCOM_OK)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002953 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002954 (void) vppcom_session_close ((u32) accept_sid);
2955 errno = -rv;
2956 rv = -1;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002957 }
Dave Wallace048b1d62018-01-03 22:24:41 -05002958 else
2959 {
Dave Wallace2a865272018-02-07 21:00:42 -05002960 func_str = "ldp_fd_from_sid";
2961 if (LDP_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002962 clib_warning ("LDP<%d>: listen fd %d (0x%x): calling %s(): "
2963 "accept sid %u (0x%x), ep %p, flags 0x%x",
2964 getpid (), listen_fd, listen_fd,
2965 func_str, accept_sid, accept_sid, ep, flags);
Florin Coras30e273b2018-11-27 00:04:59 -08002966 rv = ldp_fd_alloc ((u32) accept_sid);
Dave Wallace048b1d62018-01-03 22:24:41 -05002967 if (rv < 0)
2968 {
2969 (void) vppcom_session_close ((u32) accept_sid);
2970 errno = -rv;
2971 rv = -1;
2972 }
2973 }
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002974 }
2975 }
Dave Wallace048b1d62018-01-03 22:24:41 -05002976 else
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002977 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002978 func_str = "libc_accept4";
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002979
Dave Wallace2a865272018-02-07 21:00:42 -05002980 if (LDP_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002981 clib_warning ("LDP<%d>: listen fd %d (0x%x): calling %s(): "
2982 "addr %p, addr_len %p, flags 0x%x",
2983 getpid (), listen_fd, listen_fd, func_str,
2984 addr, addr_len, flags);
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002985
Dave Wallace048b1d62018-01-03 22:24:41 -05002986 rv = libc_accept4 (listen_fd, addr, addr_len, flags);
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002987 }
2988
Dave Wallace2a865272018-02-07 21:00:42 -05002989 if (LDP_DEBUG > 0)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002990 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002991 if (rv < 0)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002992 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002993 int errno_val = errno;
2994 perror (func_str);
2995 clib_warning ("LDP<%d>: ERROR: listen fd %d (0x%x): %s() failed! "
2996 "rv %d, errno = %d", getpid (), listen_fd,
2997 listen_fd, func_str, rv, errno_val);
2998 errno = errno_val;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002999 }
Dave Wallace048b1d62018-01-03 22:24:41 -05003000 else
3001 clib_warning ("LDP<%d>: listen fd %d (0x%x): returning %d (0x%x)",
3002 getpid (), listen_fd, listen_fd, rv, rv);
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07003003 }
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07003004 return rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003005}
3006
Dave Wallace048b1d62018-01-03 22:24:41 -05003007int
3008accept4 (int fd, __SOCKADDR_ARG addr, socklen_t * __restrict addr_len,
3009 int flags)
3010{
Dave Wallace2a865272018-02-07 21:00:42 -05003011 return ldp_accept4 (fd, addr, addr_len, flags);
Dave Wallace048b1d62018-01-03 22:24:41 -05003012}
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07003013
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003014int
Dave Wallace048b1d62018-01-03 22:24:41 -05003015accept (int fd, __SOCKADDR_ARG addr, socklen_t * __restrict addr_len)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003016{
Dave Wallace2a865272018-02-07 21:00:42 -05003017 return ldp_accept4 (fd, addr, addr_len, 0);
Dave Wallace048b1d62018-01-03 22:24:41 -05003018}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003019
Dave Wallace048b1d62018-01-03 22:24:41 -05003020int
3021shutdown (int fd, int how)
3022{
3023 int rv;
3024 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05003025 u32 sid = ldp_sid_from_fd (fd);
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07003026
Dave Wallace2a865272018-02-07 21:00:42 -05003027 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05003028 return -1;
3029
3030 if (sid != INVALID_SESSION_ID)
3031 {
Florin Coras6917b942018-11-13 22:44:54 -08003032 func_str = "vppcom_session_close[TODO]";
3033 rv = close (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05003034 }
3035 else
3036 {
3037 func_str = "libc_shutdown";
3038
Dave Wallace2a865272018-02-07 21:00:42 -05003039 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05003040 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): how %d",
3041 getpid (), fd, fd, func_str, how);
3042
3043 rv = libc_shutdown (fd, how);
3044 }
3045
Dave Wallace2a865272018-02-07 21:00:42 -05003046 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05003047 {
3048 if (rv < 0)
3049 {
3050 int errno_val = errno;
3051 perror (func_str);
3052 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
3053 "rv %d, errno = %d", getpid (), fd, fd,
3054 func_str, rv, errno_val);
3055 errno = errno_val;
3056 }
3057 else
3058 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
3059 getpid (), fd, fd, rv, rv);
3060 }
3061 return rv;
3062}
3063
3064int
3065epoll_create1 (int flags)
3066{
Florin Corasdfe4cf42018-11-28 22:13:45 -08003067 ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
Dave Wallace048b1d62018-01-03 22:24:41 -05003068 const char *func_str;
3069 int rv;
3070
Dave Wallace2a865272018-02-07 21:00:42 -05003071 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05003072 return -1;
3073
Florin Coras99368312018-08-02 10:45:44 -07003074 if (ldp->vcl_needs_real_epoll)
3075 {
3076 rv = libc_epoll_create1 (flags);
3077 ldp->vcl_needs_real_epoll = 0;
Florin Corasdfe4cf42018-11-28 22:13:45 -08003078 ldpw->vcl_mq_epfd = rv;
Florin Coras99368312018-08-02 10:45:44 -07003079 LDBG (0, "LDP<%d>: created vcl epfd %u", getpid (), rv);
3080 return rv;
3081 }
Dave Wallace048b1d62018-01-03 22:24:41 -05003082 func_str = "vppcom_epoll_create";
3083
Florin Coras99368312018-08-02 10:45:44 -07003084 LDBG (1, "LDP<%d>: calling %s()", getpid (), func_str);
Dave Wallace048b1d62018-01-03 22:24:41 -05003085
3086 rv = vppcom_epoll_create ();
3087
3088 if (PREDICT_FALSE (rv < 0))
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07003089 {
3090 errno = -rv;
Dave Wallace048b1d62018-01-03 22:24:41 -05003091 rv = -1;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07003092 }
Dave Wallace048b1d62018-01-03 22:24:41 -05003093 else
Florin Coras30e273b2018-11-27 00:04:59 -08003094 rv = ldp_fd_alloc ((u32) rv);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003095
Dave Wallace2a865272018-02-07 21:00:42 -05003096 if (LDP_DEBUG > 1)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003097 {
Dave Wallace048b1d62018-01-03 22:24:41 -05003098 if (rv < 0)
3099 {
3100 int errno_val = errno;
3101 perror (func_str);
3102 clib_warning ("LDP<%d>: ERROR: %s() failed! "
3103 "rv %d, errno = %d",
3104 getpid (), func_str, rv, errno_val);
3105 errno = errno_val;
3106 }
3107 else
3108 clib_warning ("LDP<%d>: returning epfd %d (0x%x)", getpid (), rv, rv);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003109 }
Dave Wallace048b1d62018-01-03 22:24:41 -05003110 return rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003111}
3112
3113int
Dave Wallace048b1d62018-01-03 22:24:41 -05003114epoll_create (int size)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003115{
Dave Wallace048b1d62018-01-03 22:24:41 -05003116 return epoll_create1 (0);
3117}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003118
Dave Wallace048b1d62018-01-03 22:24:41 -05003119int
3120epoll_ctl (int epfd, int op, int fd, struct epoll_event *event)
3121{
Florin Coras99368312018-08-02 10:45:44 -07003122 u32 vep_idx = ldp_sid_from_fd (epfd), sid;
Dave Wallace048b1d62018-01-03 22:24:41 -05003123 const char *func_str;
Florin Coras99368312018-08-02 10:45:44 -07003124 int rv;
Dave Wallace048b1d62018-01-03 22:24:41 -05003125
Dave Wallace2a865272018-02-07 21:00:42 -05003126 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05003127 return -1;
3128
Florin Coras99368312018-08-02 10:45:44 -07003129 if (PREDICT_FALSE (vep_idx == INVALID_SESSION_ID))
Dave Wallace048b1d62018-01-03 22:24:41 -05003130 {
Dave Wallace3ee1fe12018-02-23 01:09:11 -05003131 /* The LDP epoll_create1 always creates VCL epfd's.
3132 * The app should never have a kernel base epoll fd unless it
3133 * was acquired outside of the LD_PRELOAD process context.
3134 * In any case, if we get one, punt it to libc_epoll_ctl.
3135 */
Dave Wallace048b1d62018-01-03 22:24:41 -05003136 func_str = "libc_epoll_ctl";
3137
Florin Coras99368312018-08-02 10:45:44 -07003138 LDBG (1, "LDP<%d>: epfd %d (0x%x): calling %s(): op %d, fd %d (0x%x),"
3139 " event %p", getpid (), epfd, epfd, func_str, op, fd, fd, event);
Dave Wallace048b1d62018-01-03 22:24:41 -05003140
3141 rv = libc_epoll_ctl (epfd, op, fd, event);
Florin Coras99368312018-08-02 10:45:44 -07003142 goto done;
3143 }
3144
3145 sid = ldp_sid_from_fd (fd);
3146
3147 LDBG (0, "LDP<%d>: epfd %d (0x%x), vep_idx %d (0x%x), sid %d (0x%x)",
3148 getpid (), epfd, epfd, vep_idx, vep_idx, sid, sid);
3149
3150 if (sid != INVALID_SESSION_ID)
3151 {
3152 func_str = "vppcom_epoll_ctl";
3153
3154 LDBG (1, "LDP<%d>: epfd %d (0x%x): calling %s(): vep_idx %d (0x%x),"
3155 " op %d, sid %u (0x%x), event %p", getpid (), epfd, epfd,
3156 func_str, vep_idx, vep_idx, sid, sid, event);
3157
3158 rv = vppcom_epoll_ctl (vep_idx, op, sid, event);
3159 if (rv != VPPCOM_OK)
3160 {
3161 errno = -rv;
3162 rv = -1;
3163 }
3164 }
3165 else
3166 {
3167 int libc_epfd;
3168 u32 size = sizeof (epfd);
3169
3170 func_str = "vppcom_session_attr[GET_LIBC_EPFD]";
3171 libc_epfd = vppcom_session_attr (vep_idx, VPPCOM_ATTR_GET_LIBC_EPFD, 0,
3172 0);
3173 LDBG (1, "LDP<%d>: epfd %d (0x%x), vep_idx %d (0x%x): %s() "
3174 "returned libc_epfd %d (0x%x)", getpid (), epfd, epfd,
3175 vep_idx, vep_idx, func_str, libc_epfd, libc_epfd);
3176
3177 if (!libc_epfd)
3178 {
3179 func_str = "libc_epoll_create1";
3180
3181 LDBG (1, "LDP<%d>: epfd %d (0x%x), vep_idx %d (0x%x): "
3182 "calling %s(): EPOLL_CLOEXEC", getpid (), epfd, epfd,
3183 vep_idx, vep_idx, func_str);
3184
3185 libc_epfd = libc_epoll_create1 (EPOLL_CLOEXEC);
3186 if (libc_epfd < 0)
3187 {
3188 rv = libc_epfd;
3189 goto done;
3190 }
3191
3192 func_str = "vppcom_session_attr[SET_LIBC_EPFD]";
3193 LDBG (1, "LDP<%d>: epfd %d (0x%x): calling %s(): vep_idx %d (0x%x),"
3194 " VPPCOM_ATTR_SET_LIBC_EPFD, libc_epfd %d (0x%x), size %d",
3195 getpid (), epfd, epfd, func_str, vep_idx, vep_idx, libc_epfd,
3196 libc_epfd, size);
3197
3198 rv = vppcom_session_attr (vep_idx, VPPCOM_ATTR_SET_LIBC_EPFD,
3199 &libc_epfd, &size);
3200 if (rv < 0)
3201 {
3202 errno = -rv;
3203 rv = -1;
3204 goto done;
3205 }
3206 }
3207 else if (PREDICT_FALSE (libc_epfd < 0))
3208 {
3209 errno = -epfd;
3210 rv = -1;
3211 goto done;
3212 }
3213
3214 func_str = "libc_epoll_ctl";
3215
3216 LDBG (1, "LDP<%d>: epfd %d (0x%x): calling %s(): libc_epfd %d (0x%x), "
3217 "op %d, fd %d (0x%x), event %p", getpid (), epfd, epfd, func_str,
3218 libc_epfd, libc_epfd, op, fd, fd, event);
3219
3220 rv = libc_epoll_ctl (libc_epfd, op, fd, event);
Dave Wallace048b1d62018-01-03 22:24:41 -05003221 }
3222
3223done:
Dave Wallace2a865272018-02-07 21:00:42 -05003224 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05003225 {
3226 if (rv < 0)
3227 {
3228 int errno_val = errno;
3229 perror (func_str);
3230 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
3231 "rv %d, errno = %d", getpid (), fd, fd,
3232 func_str, rv, errno_val);
3233 errno = errno_val;
3234 }
3235 else
3236 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
3237 getpid (), fd, fd, rv, rv);
3238 }
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003239 return rv;
3240}
Dave Wallace048b1d62018-01-03 22:24:41 -05003241
3242static inline int
Florin Coras99368312018-08-02 10:45:44 -07003243ldp_epoll_pwait (int epfd, struct epoll_event *events, int maxevents,
3244 int timeout, const sigset_t * sigmask)
Dave Wallace048b1d62018-01-03 22:24:41 -05003245{
Florin Corasdfe4cf42018-11-28 22:13:45 -08003246 ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
Florin Coras99368312018-08-02 10:45:44 -07003247 double time_to_wait = (double) 0, time_out, now = 0;
Dave Wallace2a865272018-02-07 21:00:42 -05003248 u32 vep_idx = ldp_sid_from_fd (epfd);
Florin Coras99368312018-08-02 10:45:44 -07003249 int libc_epfd, rv = 0;
3250 const char *func_str;
Dave Wallace048b1d62018-01-03 22:24:41 -05003251
Dave Wallace2a865272018-02-07 21:00:42 -05003252 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05003253 return -1;
3254
3255 if (PREDICT_FALSE (!events || (timeout < -1)))
3256 {
3257 errno = EFAULT;
3258 return -1;
3259 }
3260
Florin Corasdfe4cf42018-11-28 22:13:45 -08003261 if (epfd == ldpw->vcl_mq_epfd)
Florin Coras99368312018-08-02 10:45:44 -07003262 return libc_epoll_pwait (epfd, events, maxevents, timeout, sigmask);
3263
Dave Wallace048b1d62018-01-03 22:24:41 -05003264 if (PREDICT_FALSE (vep_idx == INVALID_SESSION_ID))
3265 {
3266 clib_warning ("LDP<%d>: ERROR: epfd %d (0x%x): bad vep_idx %d (0x%x)!",
3267 getpid (), epfd, epfd, vep_idx, vep_idx);
3268 errno = EBADFD;
3269 return -1;
3270 }
3271
Florin Coras54693d22018-07-17 10:46:29 -07003272 time_to_wait = ((timeout >= 0) ? (double) timeout : 0);
Florin Corasdfe4cf42018-11-28 22:13:45 -08003273 time_out = clib_time_now (&ldpw->clib_time) + time_to_wait;
Dave Wallace048b1d62018-01-03 22:24:41 -05003274
3275 func_str = "vppcom_session_attr[GET_LIBC_EPFD]";
3276 libc_epfd = vppcom_session_attr (vep_idx, VPPCOM_ATTR_GET_LIBC_EPFD, 0, 0);
3277 if (PREDICT_FALSE (libc_epfd < 0))
3278 {
3279 errno = -libc_epfd;
3280 rv = -1;
3281 goto done;
3282 }
3283
Florin Coras99368312018-08-02 10:45:44 -07003284 LDBG (2, "LDP<%d>: epfd %d (0x%x): vep_idx %d (0x%x), libc_epfd %d (0x%x), "
3285 "events %p, maxevents %d, timeout %d, sigmask %p: time_to_wait %.02f",
3286 getpid (), epfd, epfd, vep_idx, vep_idx, libc_epfd, libc_epfd, events,
3287 maxevents, timeout, sigmask, time_to_wait, time_out);
Dave Wallace048b1d62018-01-03 22:24:41 -05003288 do
3289 {
Florin Corasdfe4cf42018-11-28 22:13:45 -08003290 if (!ldpw->epoll_wait_vcl)
Dave Wallace048b1d62018-01-03 22:24:41 -05003291 {
3292 func_str = "vppcom_epoll_wait";
3293
Florin Coras99368312018-08-02 10:45:44 -07003294 LDBG (3, "LDP<%d>: epfd %d (0x%x): calling %s(): vep_idx %d (0x%x),"
3295 " events %p, maxevents %d", getpid (), epfd, epfd, func_str,
3296 vep_idx, vep_idx, events, maxevents);
Dave Wallace048b1d62018-01-03 22:24:41 -05003297
3298 rv = vppcom_epoll_wait (vep_idx, events, maxevents, 0);
3299 if (rv > 0)
3300 {
Florin Corasdfe4cf42018-11-28 22:13:45 -08003301 ldpw->epoll_wait_vcl = 1;
Dave Wallace048b1d62018-01-03 22:24:41 -05003302 goto done;
3303 }
3304 else if (rv < 0)
3305 {
3306 errno = -rv;
3307 rv = -1;
3308 goto done;
3309 }
3310 }
3311 else
Florin Corasdfe4cf42018-11-28 22:13:45 -08003312 ldpw->epoll_wait_vcl = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -05003313
3314 if (libc_epfd > 0)
3315 {
3316 func_str = "libc_epoll_pwait";
3317
Florin Coras99368312018-08-02 10:45:44 -07003318 LDBG (3, "LDP<%d>: epfd %d (0x%x): calling %s(): libc_epfd %d "
3319 "(0x%x), events %p, maxevents %d, sigmask %p", getpid (),
3320 epfd, epfd, func_str, libc_epfd, libc_epfd, events,
3321 maxevents, sigmask);
Dave Wallace048b1d62018-01-03 22:24:41 -05003322
Keith Burns (alagalah)5368efa2018-02-07 13:20:28 -08003323 rv = libc_epoll_pwait (libc_epfd, events, maxevents, 1, sigmask);
Dave Wallace048b1d62018-01-03 22:24:41 -05003324 if (rv != 0)
3325 goto done;
3326 }
3327
3328 if (timeout != -1)
Florin Corasdfe4cf42018-11-28 22:13:45 -08003329 now = clib_time_now (&ldpw->clib_time);
Dave Wallace048b1d62018-01-03 22:24:41 -05003330 }
3331 while (now < time_out);
3332
3333done:
Dave Wallace2a865272018-02-07 21:00:42 -05003334 if (LDP_DEBUG > 3)
Dave Wallace048b1d62018-01-03 22:24:41 -05003335 {
Keith Burns (alagalah)5368efa2018-02-07 13:20:28 -08003336 if (libc_epfd > 0)
3337 epfd = libc_epfd;
Dave Wallace048b1d62018-01-03 22:24:41 -05003338 if (rv < 0)
3339 {
3340 int errno_val = errno;
3341 perror (func_str);
3342 clib_warning ("LDP<%d>: ERROR: epfd %d (0x%x): %s() failed! "
3343 "rv %d, errno = %d", getpid (), epfd, epfd,
3344 func_str, rv, errno_val);
3345 errno = errno_val;
3346 }
3347 else
3348 clib_warning ("LDP<%d>: epfd %d (0x%x): returning %d (0x%x)",
3349 getpid (), epfd, epfd, rv, rv);
3350 }
3351 return rv;
3352}
3353
3354int
3355epoll_pwait (int epfd, struct epoll_event *events,
3356 int maxevents, int timeout, const sigset_t * sigmask)
3357{
Dave Wallace2a865272018-02-07 21:00:42 -05003358 return ldp_epoll_pwait (epfd, events, maxevents, timeout, sigmask);
Dave Wallace048b1d62018-01-03 22:24:41 -05003359}
3360
3361int
3362epoll_wait (int epfd, struct epoll_event *events, int maxevents, int timeout)
3363{
Dave Wallace2a865272018-02-07 21:00:42 -05003364 return ldp_epoll_pwait (epfd, events, maxevents, timeout, NULL);
Dave Wallace048b1d62018-01-03 22:24:41 -05003365}
3366
3367int
3368poll (struct pollfd *fds, nfds_t nfds, int timeout)
3369{
Florin Corasdfe4cf42018-11-28 22:13:45 -08003370 ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
Dave Wallace048b1d62018-01-03 22:24:41 -05003371 const char *func_str = __func__;
Florin Coras6917b942018-11-13 22:44:54 -08003372 int rv, i, n_revents = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -05003373 u32 sid;
3374 vcl_poll_t *vp;
3375 double wait_for_time;
3376
Florin Coras6917b942018-11-13 22:44:54 -08003377 LDBG (3, "LDP<%d>: fds %p, nfds %d, timeout %d", getpid (), fds, nfds,
3378 timeout);
Dave Wallace048b1d62018-01-03 22:24:41 -05003379
3380 if (timeout >= 0)
3381 wait_for_time = (f64) timeout / 1000;
3382 else
3383 wait_for_time = -1;
3384
Dave Wallace048b1d62018-01-03 22:24:41 -05003385 for (i = 0; i < nfds; i++)
3386 {
Florin Coras6917b942018-11-13 22:44:54 -08003387 if (fds[i].fd < 0)
3388 continue;
Dave Wallace048b1d62018-01-03 22:24:41 -05003389
Florin Coras6917b942018-11-13 22:44:54 -08003390 LDBG (3, "LDP<%d>: fds[%d] fd %d (0x%0x) events = 0x%x revents = 0x%x",
3391 getpid (), i, fds[i].fd, fds[i].fd, fds[i].events,
3392 fds[i].revents);
3393
3394 sid = ldp_sid_from_fd (fds[i].fd);
3395 if (sid != INVALID_SESSION_ID)
3396 {
3397 fds[i].fd = -fds[i].fd;
Florin Corasdfe4cf42018-11-28 22:13:45 -08003398 vec_add2 (ldpw->vcl_poll, vp, 1);
Florin Coras6917b942018-11-13 22:44:54 -08003399 vp->fds_ndx = i;
3400 vp->sid = sid;
3401 vp->events = fds[i].events;
Dave Wallace048b1d62018-01-03 22:24:41 -05003402#ifdef __USE_XOPEN2K
Florin Coras6917b942018-11-13 22:44:54 -08003403 if (fds[i].events & POLLRDNORM)
3404 vp->events |= POLLIN;
3405 if (fds[i].events & POLLWRNORM)
3406 vp->events |= POLLOUT;
Dave Wallace048b1d62018-01-03 22:24:41 -05003407#endif
Florin Coras6917b942018-11-13 22:44:54 -08003408 vp->revents = fds[i].revents;
3409 }
3410 else
3411 {
Florin Corasdfe4cf42018-11-28 22:13:45 -08003412 vec_add1 (ldpw->libc_poll, fds[i]);
3413 vec_add1 (ldpw->libc_poll_idxs, i);
Dave Wallace048b1d62018-01-03 22:24:41 -05003414 }
3415 }
3416
Dave Wallace048b1d62018-01-03 22:24:41 -05003417 do
3418 {
Florin Corasdfe4cf42018-11-28 22:13:45 -08003419 if (vec_len (ldpw->vcl_poll))
Dave Wallace048b1d62018-01-03 22:24:41 -05003420 {
3421 func_str = "vppcom_poll";
3422
Florin Coras6917b942018-11-13 22:44:54 -08003423 LDBG (3, "LDP<%d>: calling %s(): vcl_poll %p, n_sids %u (0x%x): "
Florin Corasdfe4cf42018-11-28 22:13:45 -08003424 "n_libc_fds %u", getpid (), func_str, ldpw->vcl_poll,
3425 vec_len (ldpw->vcl_poll), vec_len (ldpw->vcl_poll),
3426 vec_len (ldpw->libc_poll));
Dave Wallace048b1d62018-01-03 22:24:41 -05003427
Florin Corasdfe4cf42018-11-28 22:13:45 -08003428 rv = vppcom_poll (ldpw->vcl_poll, vec_len (ldpw->vcl_poll), 0);
Dave Wallace048b1d62018-01-03 22:24:41 -05003429 if (rv < 0)
3430 {
3431 errno = -rv;
3432 rv = -1;
3433 goto done;
3434 }
3435 else
3436 n_revents += rv;
3437 }
3438
Florin Corasdfe4cf42018-11-28 22:13:45 -08003439 if (vec_len (ldpw->libc_poll))
Dave Wallace048b1d62018-01-03 22:24:41 -05003440 {
3441 func_str = "libc_poll";
3442
Florin Coras6917b942018-11-13 22:44:54 -08003443 LDBG (3, "LDP<%d>: calling %s(): fds %p, nfds %u: n_sids %u",
Florin Corasdfe4cf42018-11-28 22:13:45 -08003444 getpid (), fds, nfds, vec_len (ldpw->vcl_poll));
Dave Wallace048b1d62018-01-03 22:24:41 -05003445
Florin Corasdfe4cf42018-11-28 22:13:45 -08003446 rv = libc_poll (ldpw->libc_poll, vec_len (ldpw->libc_poll), 0);
Dave Wallace048b1d62018-01-03 22:24:41 -05003447 if (rv < 0)
3448 goto done;
3449 else
3450 n_revents += rv;
3451 }
3452
3453 if (n_revents)
3454 {
3455 rv = n_revents;
3456 goto done;
3457 }
3458 }
3459 while ((wait_for_time == -1) ||
Florin Corasdfe4cf42018-11-28 22:13:45 -08003460 (clib_time_now (&ldpw->clib_time) < wait_for_time));
Dave Wallace048b1d62018-01-03 22:24:41 -05003461 rv = 0;
3462
3463done:
Florin Corasdfe4cf42018-11-28 22:13:45 -08003464 vec_foreach (vp, ldpw->vcl_poll)
Dave Wallace048b1d62018-01-03 22:24:41 -05003465 {
3466 fds[vp->fds_ndx].fd = -fds[vp->fds_ndx].fd;
Florin Coras6917b942018-11-13 22:44:54 -08003467 fds[vp->fds_ndx].revents = vp->revents;
Dave Wallace048b1d62018-01-03 22:24:41 -05003468#ifdef __USE_XOPEN2K
3469 if ((fds[vp->fds_ndx].revents & POLLIN) &&
3470 (fds[vp->fds_ndx].events & POLLRDNORM))
3471 fds[vp->fds_ndx].revents |= POLLRDNORM;
3472 if ((fds[vp->fds_ndx].revents & POLLOUT) &&
3473 (fds[vp->fds_ndx].events & POLLWRNORM))
3474 fds[vp->fds_ndx].revents |= POLLWRNORM;
3475#endif
3476 }
Florin Corasdfe4cf42018-11-28 22:13:45 -08003477 vec_reset_length (ldpw->vcl_poll);
Dave Wallace048b1d62018-01-03 22:24:41 -05003478
Florin Corasdfe4cf42018-11-28 22:13:45 -08003479 for (i = 0; i < vec_len (ldpw->libc_poll); i++)
Florin Coras6917b942018-11-13 22:44:54 -08003480 {
Florin Corasdfe4cf42018-11-28 22:13:45 -08003481 fds[ldpw->libc_poll_idxs[i]].revents = ldpw->libc_poll[i].revents;
Florin Coras6917b942018-11-13 22:44:54 -08003482 }
Florin Corasdfe4cf42018-11-28 22:13:45 -08003483 vec_reset_length (ldpw->libc_poll_idxs);
3484 vec_reset_length (ldpw->libc_poll);
Florin Coras6917b942018-11-13 22:44:54 -08003485
Dave Wallace2a865272018-02-07 21:00:42 -05003486 if (LDP_DEBUG > 3)
Dave Wallace048b1d62018-01-03 22:24:41 -05003487 {
3488 if (rv < 0)
3489 {
3490 int errno_val = errno;
3491 perror (func_str);
3492 clib_warning ("LDP<%d>: ERROR: %s() failed! "
3493 "rv %d, errno = %d", getpid (),
3494 func_str, rv, errno_val);
3495 errno = errno_val;
3496 }
3497 else
3498 {
3499 clib_warning ("LDP<%d>: returning %d (0x%x): n_sids %u, "
3500 "n_libc_fds %d", getpid (), rv, rv,
Florin Corasdfe4cf42018-11-28 22:13:45 -08003501 vec_len (ldpw->vcl_poll), vec_len (ldpw->libc_poll));
Dave Wallace048b1d62018-01-03 22:24:41 -05003502
3503 for (i = 0; i < nfds; i++)
3504 {
3505 if (fds[i].fd >= 0)
3506 {
Dave Wallace2a865272018-02-07 21:00:42 -05003507 if (LDP_DEBUG > 3)
Dave Wallace048b1d62018-01-03 22:24:41 -05003508 clib_warning ("LDP<%d>: fds[%d].fd %d (0x%0x), "
3509 ".events = 0x%x, .revents = 0x%x",
3510 getpid (), i, fds[i].fd, fds[i].fd,
3511 fds[i].events, fds[i].revents);
3512 }
3513 }
3514 }
3515 }
3516
3517 return rv;
3518}
3519
3520#ifdef USE_GNU
3521int
3522ppoll (struct pollfd *fds, nfds_t nfds,
3523 const struct timespec *timeout, const sigset_t * sigmask)
3524{
Dave Wallace2a865272018-02-07 21:00:42 -05003525 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05003526 return -1;
3527
3528 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
3529 errno = ENOSYS;
3530
3531
3532 return -1;
3533}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003534#endif
3535
Dave Wallace2a865272018-02-07 21:00:42 -05003536void CONSTRUCTOR_ATTRIBUTE ldp_constructor (void);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003537
Dave Wallace2a865272018-02-07 21:00:42 -05003538void DESTRUCTOR_ATTRIBUTE ldp_destructor (void);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003539
Dave Wallace048b1d62018-01-03 22:24:41 -05003540/*
3541 * This function is called when the library is loaded
3542 */
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003543void
Dave Wallace2a865272018-02-07 21:00:42 -05003544ldp_constructor (void)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003545{
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003546 swrap_constructor ();
Dave Wallace2a865272018-02-07 21:00:42 -05003547 if (ldp_init () != 0)
3548 fprintf (stderr, "\nLDP<%d>: ERROR: ldp_constructor: failed!\n",
Dave Wallace048b1d62018-01-03 22:24:41 -05003549 getpid ());
Dave Wallace69d01192018-02-22 16:22:09 -05003550 else if (LDP_DEBUG > 0)
Dave Wallace2a865272018-02-07 21:00:42 -05003551 clib_warning ("LDP<%d>: LDP constructor: done!\n", getpid ());
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003552}
3553
3554/*
3555 * This function is called when the library is unloaded
3556 */
3557void
Dave Wallace2a865272018-02-07 21:00:42 -05003558ldp_destructor (void)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003559{
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003560 swrap_destructor ();
Dave Wallace2a865272018-02-07 21:00:42 -05003561 if (ldp->init)
Florin Coras940f78f2018-11-30 12:11:20 -08003562 ldp->init = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -05003563
3564 /* Don't use clib_warning() here because that calls writev()
Dave Wallace2a865272018-02-07 21:00:42 -05003565 * which will call ldp_init().
Dave Wallace048b1d62018-01-03 22:24:41 -05003566 */
Dave Wallace69d01192018-02-22 16:22:09 -05003567 if (LDP_DEBUG > 0)
3568 printf ("%s:%d: LDP<%d>: LDP destructor: done!\n",
3569 __func__, __LINE__, getpid ());
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003570}
3571
3572
3573/*
3574 * fd.io coding-style-patch-verification: ON
3575 *
3576 * Local Variables:
3577 * eval: (c-set-style "gnu")
3578 * End:
3579 */