blob: 0d4fe43dd7d152f087a3a32f43ab3e79624a87f2 [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) \
Florin Coras05ecfcc2018-12-12 18:19:39 -0800115 clib_warning ("ldp<%d>: " _fmt, getpid(), ##_args)
Florin Coras99368312018-08-02 10:45:44 -0700116
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;
Florin Coras05ecfcc2018-12-12 18:19:39 -0800264 LDBG (2, "\nERROR: ldp_init: vppcom_app_create()"
265 " failed! rv = %d (%s)\n", rv, vppcom_retval_str (rv));
Florin Coras99368312018-08-02 10:45:44 -0700266 ldp->init = 0;
267 return rv;
268 }
269 ldp->vcl_needs_real_epoll = 0;
Florin Corasdfe4cf42018-11-28 22:13:45 -0800270 pool_alloc (ldp->workers, LDP_MAX_NWORKERS);
271 ldpw = ldp_worker_get_current ();
Florin Coras99368312018-08-02 10:45:44 -0700272
273 char *env_var_str = getenv (LDP_ENV_DEBUG);
274 if (env_var_str)
275 {
276 u32 tmp;
277 if (sscanf (env_var_str, "%u", &tmp) != 1)
278 clib_warning ("LDP<%d>: WARNING: Invalid LDP debug level specified in"
279 " the env var " LDP_ENV_DEBUG " (%s)!", getpid (),
280 env_var_str);
281 else
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700282 {
Florin Coras99368312018-08-02 10:45:44 -0700283 ldp->debug = tmp;
Florin Coras05ecfcc2018-12-12 18:19:39 -0800284 LDBG (0, "configured LDP debug level (%u) from env var "
285 LDP_ENV_DEBUG "!", ldp->debug);
Florin Coras99368312018-08-02 10:45:44 -0700286 }
287 }
Dave Wallace048b1d62018-01-03 22:24:41 -0500288
Florin Coras99368312018-08-02 10:45:44 -0700289 env_var_str = getenv (LDP_ENV_APP_NAME);
290 if (env_var_str)
291 {
292 ldp_set_app_name (env_var_str);
Florin Coras05ecfcc2018-12-12 18:19:39 -0800293 LDBG (0, "configured LDP app name (%s) from the env var "
294 LDP_ENV_APP_NAME "!", ldp->app_name);
Florin Coras99368312018-08-02 10:45:44 -0700295 }
Dave Wallace048b1d62018-01-03 22:24:41 -0500296
Florin Coras99368312018-08-02 10:45:44 -0700297 env_var_str = getenv (LDP_ENV_SID_BIT);
298 if (env_var_str)
299 {
300 u32 sb;
301 if (sscanf (env_var_str, "%u", &sb) != 1)
302 {
303 clib_warning ("LDP<%d>: WARNING: Invalid LDP sid bit specified in"
304 " the env var " LDP_ENV_SID_BIT " (%s)! sid bit "
305 "value %d (0x%x)", getpid (), env_var_str,
306 ldp->sid_bit_val, ldp->sid_bit_val);
307 }
308 else if (sb < LDP_SID_BIT_MIN)
309 {
310 ldp->sid_bit_val = (1 << LDP_SID_BIT_MIN);
311 ldp->sid_bit_mask = ldp->sid_bit_val - 1;
Dave Wallace048b1d62018-01-03 22:24:41 -0500312
Florin Coras99368312018-08-02 10:45:44 -0700313 clib_warning ("LDP<%d>: WARNING: LDP sid bit (%u) specified in the"
314 " env var " LDP_ENV_SID_BIT " (%s) is too small. "
315 "Using LDP_SID_BIT_MIN (%d)! sid bit value %d (0x%x)",
316 getpid (), sb, env_var_str, LDP_SID_BIT_MIN,
317 ldp->sid_bit_val, ldp->sid_bit_val);
318 }
319 else if (sb > LDP_SID_BIT_MAX)
320 {
321 ldp->sid_bit_val = (1 << LDP_SID_BIT_MAX);
322 ldp->sid_bit_mask = ldp->sid_bit_val - 1;
Dave Wallace048b1d62018-01-03 22:24:41 -0500323
Florin Coras99368312018-08-02 10:45:44 -0700324 clib_warning ("LDP<%d>: WARNING: LDP sid bit (%u) specified in the"
325 " env var " LDP_ENV_SID_BIT " (%s) is too big. Using"
326 " LDP_SID_BIT_MAX (%d)! sid bit value %d (0x%x)",
327 getpid (), sb, env_var_str, LDP_SID_BIT_MAX,
328 ldp->sid_bit_val, ldp->sid_bit_val);
Dave Wallace048b1d62018-01-03 22:24:41 -0500329 }
330 else
331 {
Florin Coras99368312018-08-02 10:45:44 -0700332 ldp->sid_bit_val = (1 << sb);
333 ldp->sid_bit_mask = ldp->sid_bit_val - 1;
334
Florin Coras05ecfcc2018-12-12 18:19:39 -0800335 LDBG (0, "configured LDP sid bit (%u) from "
336 LDP_ENV_SID_BIT "! sid bit value %d (0x%x)", sb,
Florin Coras99368312018-08-02 10:45:44 -0700337 ldp->sid_bit_val, ldp->sid_bit_val);
Dave Wallace048b1d62018-01-03 22:24:41 -0500338 }
339 }
Florin Coras99368312018-08-02 10:45:44 -0700340
Florin Corasdfe4cf42018-11-28 22:13:45 -0800341 clib_time_init (&ldpw->clib_time);
Florin Coras30e273b2018-11-27 00:04:59 -0800342 clib_rwlock_init (&ldp->fd_table_lock);
Florin Coras05ecfcc2018-12-12 18:19:39 -0800343 LDBG (0, "LDP initialization: done!");
Florin Coras99368312018-08-02 10:45:44 -0700344
345 return 0;
Dave Wallace048b1d62018-01-03 22:24:41 -0500346}
347
348int
349close (int fd)
350{
Florin Coras47c40e22018-11-26 17:01:36 -0800351 int rv, refcnt;
Dave Wallace2a865272018-02-07 21:00:42 -0500352 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -0500353
Dave Wallace2a865272018-02-07 21:00:42 -0500354 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500355 return -1;
356
357 if (sid != INVALID_SESSION_ID)
358 {
359 int epfd;
360
Dave Wallace048b1d62018-01-03 22:24:41 -0500361 epfd = vppcom_session_attr (sid, VPPCOM_ATTR_GET_LIBC_EPFD, 0, 0);
362 if (epfd > 0)
363 {
Florin Coras05ecfcc2018-12-12 18:19:39 -0800364 LDBG (0, "fd %d (0x%x): calling libc_close: epfd %u (0x%x)",
365 fd, fd, epfd, epfd);
Dave Wallace048b1d62018-01-03 22:24:41 -0500366
367 rv = libc_close (epfd);
368 if (rv < 0)
369 {
370 u32 size = sizeof (epfd);
371 epfd = 0;
372
373 (void) vppcom_session_attr (sid, VPPCOM_ATTR_SET_LIBC_EPFD,
374 &epfd, &size);
375 }
376 }
377 else if (PREDICT_FALSE (epfd < 0))
378 {
379 errno = -epfd;
380 rv = -1;
381 goto done;
382 }
383
Florin Coras05ecfcc2018-12-12 18:19:39 -0800384 LDBG (0, "fd %d (0x%x): calling vppcom_session_close: sid %u (0x%x)",
385 fd, fd, sid, sid);
Dave Wallace048b1d62018-01-03 22:24:41 -0500386
Florin Coras47c40e22018-11-26 17:01:36 -0800387 refcnt = vppcom_session_attr (sid, VPPCOM_ATTR_GET_REFCNT, 0, 0);
Dave Wallace048b1d62018-01-03 22:24:41 -0500388 rv = vppcom_session_close (sid);
389 if (rv != VPPCOM_OK)
390 {
391 errno = -rv;
392 rv = -1;
393 }
Florin Corasb0f662f2018-12-27 14:51:46 -0800394 if (refcnt <= 1)
Florin Coras47c40e22018-11-26 17:01:36 -0800395 ldp_fd_free_w_sid (sid);
Dave Wallace048b1d62018-01-03 22:24:41 -0500396 }
397 else
398 {
Florin Coras05ecfcc2018-12-12 18:19:39 -0800399 LDBG (0, "fd %d (0x%x): calling libc_close", fd, fd);
Dave Wallace048b1d62018-01-03 22:24:41 -0500400 rv = libc_close (fd);
401 }
402
403done:
Florin Coras05ecfcc2018-12-12 18:19:39 -0800404
405 LDBG (1, "fd %d (0x%x): returning %d (0x%x)", fd, fd, rv, rv);
Dave Wallace048b1d62018-01-03 22:24:41 -0500406 return rv;
407}
408
409ssize_t
410read (int fd, void *buf, size_t nbytes)
411{
412 ssize_t size;
Dave Wallace2a865272018-02-07 21:00:42 -0500413 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -0500414
Dave Wallace2a865272018-02-07 21:00:42 -0500415 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500416 return -1;
417
418 if (sid != INVALID_SESSION_ID)
419 {
Florin Coras05ecfcc2018-12-12 18:19:39 -0800420 LDBG (2, "fd %d (0x%x): calling vppcom_session_read(): sid %u (0x%x),"
421 " buf %p, nbytes %u", fd, fd, sid, sid, buf, nbytes);
Dave Wallace048b1d62018-01-03 22:24:41 -0500422
423 size = vppcom_session_read (sid, buf, nbytes);
424 if (size < 0)
425 {
426 errno = -size;
427 size = -1;
428 }
429 }
430 else
431 {
Florin Coras05ecfcc2018-12-12 18:19:39 -0800432 LDBG (2, "fd %d (0x%x): calling libc_read(): buf %p, nbytes %u",
433 fd, fd, buf, nbytes);
Dave Wallace048b1d62018-01-03 22:24:41 -0500434
435 size = libc_read (fd, buf, nbytes);
436 }
437
Florin Coras05ecfcc2018-12-12 18:19:39 -0800438 LDBG (2, "fd %d (0x%x): returning %d (0x%x)", fd, fd, size, size);
Dave Wallace048b1d62018-01-03 22:24:41 -0500439 return size;
440}
441
442ssize_t
443readv (int fd, const struct iovec * iov, int iovcnt)
444{
Dave Wallace048b1d62018-01-03 22:24:41 -0500445 ssize_t size = 0;
Dave Wallace2a865272018-02-07 21:00:42 -0500446 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace8aaba562018-01-18 17:21:19 -0500447 int rv = 0, i, total = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -0500448
Dave Wallace2a865272018-02-07 21:00:42 -0500449 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500450 return -1;
451
452 if (sid != INVALID_SESSION_ID)
453 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500454 do
455 {
456 for (i = 0; i < iovcnt; ++i)
457 {
Florin Coras05ecfcc2018-12-12 18:19:39 -0800458 LDBG (2, "fd %d (0x%x): calling vppcom_session_read() [%d]:"
459 " sid %u (0x%x), iov %p, iovcnt %d, total %d", fd, fd, i,
460 sid, sid, iov, iovcnt, total);
Dave Wallace048b1d62018-01-03 22:24:41 -0500461
462 rv = vppcom_session_read (sid, iov[i].iov_base, iov[i].iov_len);
463 if (rv < 0)
464 break;
465 else
466 {
467 total += rv;
468 if (rv < iov[i].iov_len)
469 {
Florin Coras05ecfcc2018-12-12 18:19:39 -0800470 LDBG (2, "fd %d (0x%x): rv (%d) < iov[%d].iov_len (%d)",
471 fd, fd, rv, i, iov[i].iov_len);
Dave Wallace048b1d62018-01-03 22:24:41 -0500472 break;
473 }
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700474 }
475 }
476 }
Dave Wallace048b1d62018-01-03 22:24:41 -0500477 while ((rv >= 0) && (total == 0));
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700478
Dave Wallace048b1d62018-01-03 22:24:41 -0500479 if (rv < 0)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700480 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500481 errno = -rv;
482 size = -1;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700483 }
Dave Wallace048b1d62018-01-03 22:24:41 -0500484 else
485 size = total;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700486 }
487 else
488 {
Florin Coras05ecfcc2018-12-12 18:19:39 -0800489 LDBG (2, "fd %d (0x%x): calling libc_readv(): iov %p, iovcnt %d", fd,
490 fd, iov, iovcnt);
Dave Wallace048b1d62018-01-03 22:24:41 -0500491
492 size = libc_readv (fd, iov, iovcnt);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700493 }
494
Florin Coras05ecfcc2018-12-12 18:19:39 -0800495
496 LDBG (2, "fd %d (0x%x): returning %d (0x%x)", fd, fd, size, size);
Dave Wallace048b1d62018-01-03 22:24:41 -0500497 return size;
498}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700499
Dave Wallace048b1d62018-01-03 22:24:41 -0500500ssize_t
501write (int fd, const void *buf, size_t nbytes)
502{
Dave Wallace048b1d62018-01-03 22:24:41 -0500503 ssize_t size = 0;
Dave Wallace2a865272018-02-07 21:00:42 -0500504 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -0500505
Dave Wallace2a865272018-02-07 21:00:42 -0500506 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500507 return -1;
508
509 if (sid != INVALID_SESSION_ID)
510 {
Florin Coras05ecfcc2018-12-12 18:19:39 -0800511 LDBG (2, "fd %d (0x%x): calling vppcom_session_write(): sid %u (0x%x), "
512 "buf %p, nbytes %u", fd, fd, sid, sid, buf, nbytes);
Dave Wallace048b1d62018-01-03 22:24:41 -0500513
Florin Corasb0f662f2018-12-27 14:51:46 -0800514 size = vppcom_session_write_msg (sid, (void *) buf, nbytes);
Dave Wallace048b1d62018-01-03 22:24:41 -0500515 if (size < 0)
516 {
517 errno = -size;
518 size = -1;
519 }
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700520 }
521 else
522 {
Florin Coras05ecfcc2018-12-12 18:19:39 -0800523 LDBG (2, "fd %d (0x%x): calling libc_write(): buf %p, nbytes %u",
524 fd, fd, buf, nbytes);
Dave Wallace048b1d62018-01-03 22:24:41 -0500525
526 size = libc_write (fd, buf, nbytes);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700527 }
528
Florin Coras05ecfcc2018-12-12 18:19:39 -0800529 LDBG (2, "fd %d (0x%x): returning %d (0x%x)", fd, fd, size, size);
Dave Wallace048b1d62018-01-03 22:24:41 -0500530 return size;
531}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700532
Dave Wallace048b1d62018-01-03 22:24:41 -0500533ssize_t
534writev (int fd, const struct iovec * iov, int iovcnt)
535{
Dave Wallace048b1d62018-01-03 22:24:41 -0500536 ssize_t size = 0, total = 0;
Dave Wallace2a865272018-02-07 21:00:42 -0500537 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace8aaba562018-01-18 17:21:19 -0500538 int i, rv = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -0500539
540 /*
541 * Use [f]printf() instead of clib_warning() to prevent recursion SIGSEGV.
542 */
543
Dave Wallace2a865272018-02-07 21:00:42 -0500544 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500545 return -1;
546
547 if (sid != INVALID_SESSION_ID)
548 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500549 do
550 {
551 for (i = 0; i < iovcnt; ++i)
552 {
Florin Corasb0f662f2018-12-27 14:51:46 -0800553 rv = vppcom_session_write_msg (sid, iov[i].iov_base,
554 iov[i].iov_len);
Dave Wallace048b1d62018-01-03 22:24:41 -0500555 if (rv < 0)
556 break;
557 else
558 {
559 total += rv;
560 if (rv < iov[i].iov_len)
Florin Corasb0f662f2018-12-27 14:51:46 -0800561 break;
Dave Wallace048b1d62018-01-03 22:24:41 -0500562 }
563 }
564 }
565 while ((rv >= 0) && (total == 0));
566
567 if (rv < 0)
568 {
569 errno = -rv;
570 size = -1;
571 }
572 else
573 size = total;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700574 }
575 else
576 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500577 size = libc_writev (fd, iov, iovcnt);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700578 }
579
Dave Wallace048b1d62018-01-03 22:24:41 -0500580 return size;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700581}
582
583int
Dave Wallace048b1d62018-01-03 22:24:41 -0500584fcntl (int fd, int cmd, ...)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700585{
Dave Wallace048b1d62018-01-03 22:24:41 -0500586 const char *func_str = __func__;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700587 int rv = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -0500588 va_list ap;
Dave Wallace2a865272018-02-07 21:00:42 -0500589 u32 sid = ldp_sid_from_fd (fd);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700590
Dave Wallace2a865272018-02-07 21:00:42 -0500591 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500592 return -1;
593
594 va_start (ap, cmd);
595 if (sid != INVALID_SESSION_ID)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700596 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500597 int flags = va_arg (ap, int);
598 u32 size;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700599
Dave Wallace048b1d62018-01-03 22:24:41 -0500600 size = sizeof (flags);
601 rv = -EOPNOTSUPP;
602 switch (cmd)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700603 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500604 case F_SETFL:
605 func_str = "vppcom_session_attr[SET_FLAGS]";
Florin Coras05ecfcc2018-12-12 18:19:39 -0800606 LDBG (2, "fd %d (0x%x): calling %s(): sid %u (0x%x) "
607 "flags %d (0x%x), size %d", fd, fd, func_str, sid,
Florin Coras173bae32018-11-16 18:56:28 -0800608 sid, flags, flags, size);
Dave Wallace048b1d62018-01-03 22:24:41 -0500609
Florin Coras173bae32018-11-16 18:56:28 -0800610 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_FLAGS, &flags,
611 &size);
Dave Wallace048b1d62018-01-03 22:24:41 -0500612 break;
613
614 case F_GETFL:
615 func_str = "vppcom_session_attr[GET_FLAGS]";
Florin Coras05ecfcc2018-12-12 18:19:39 -0800616 LDBG (2, "fd %d (0x%x): calling %s(): sid %u (0x%x), "
617 "flags %d (0x%x), size %d", fd, fd, func_str, sid,
Florin Coras173bae32018-11-16 18:56:28 -0800618 sid, flags, flags, size);
Dave Wallace048b1d62018-01-03 22:24:41 -0500619
Florin Coras173bae32018-11-16 18:56:28 -0800620 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_FLAGS, &flags,
621 &size);
Dave Wallace048b1d62018-01-03 22:24:41 -0500622 if (rv == VPPCOM_OK)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700623 {
Florin Coras05ecfcc2018-12-12 18:19:39 -0800624 LDBG (2, "fd %d (0x%x), cmd %d (F_GETFL): %s() "
625 "returned flags %d (0x%x)", fd, fd, cmd,
Florin Coras173bae32018-11-16 18:56:28 -0800626 func_str, flags, flags);
Dave Wallace048b1d62018-01-03 22:24:41 -0500627 rv = flags;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700628 }
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700629 break;
Florin Coras173bae32018-11-16 18:56:28 -0800630 case F_SETFD:
631 /* TODO handle this */
632 LDBG (0, "F_SETFD ignored flags %u", flags);
633 rv = 0;
634 break;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700635 default:
Dave Wallace048b1d62018-01-03 22:24:41 -0500636 rv = -EOPNOTSUPP;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700637 break;
638 }
Dave Wallace048b1d62018-01-03 22:24:41 -0500639 if (rv < 0)
640 {
641 errno = -rv;
642 rv = -1;
643 }
644 }
645 else
646 {
647 func_str = "libc_vfcntl";
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700648
Florin Coras05ecfcc2018-12-12 18:19:39 -0800649 LDBG (2, "fd %d (0x%x): calling %s(): cmd %d", fd, fd, func_str, cmd);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700650
Dave Wallace048b1d62018-01-03 22:24:41 -0500651 rv = libc_vfcntl (fd, cmd, ap);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700652 }
653
Dave Wallace048b1d62018-01-03 22:24:41 -0500654 va_end (ap);
655
Dave Wallace2a865272018-02-07 21:00:42 -0500656 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -0500657 {
658 if (rv < 0)
659 {
660 int errno_val = errno;
661 perror (func_str);
662 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
663 "rv %d, errno = %d", getpid (), fd, fd,
664 func_str, rv, errno_val);
665 errno = errno_val;
666 }
667 else
668 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
669 getpid (), fd, fd, rv, rv);
670 }
671 return rv;
672}
673
674int
675ioctl (int fd, unsigned long int cmd, ...)
676{
677 const char *func_str;
678 int rv;
679 va_list ap;
Dave Wallace2a865272018-02-07 21:00:42 -0500680 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -0500681
Dave Wallace2a865272018-02-07 21:00:42 -0500682 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500683 return -1;
684
685 va_start (ap, cmd);
686 if (sid != INVALID_SESSION_ID)
687 {
688 func_str = "vppcom_session_attr[GET_NREAD]";
689
690 switch (cmd)
691 {
692 case FIONREAD:
Dave Wallace2a865272018-02-07 21:00:42 -0500693 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -0500694 clib_warning
695 ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x)",
696 getpid (), fd, fd, func_str, sid, sid);
697
698 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_NREAD, 0, 0);
699 break;
700
701 case FIONBIO:
702 {
703 u32 flags = va_arg (ap, int) ? O_NONBLOCK : 0;
704 u32 size = sizeof (flags);
705
706 /* TBD: When VPPCOM_ATTR_[GS]ET_FLAGS supports flags other than
707 * non-blocking, the flags should be read here and merged
708 * with O_NONBLOCK.
709 */
Dave Wallace2a865272018-02-07 21:00:42 -0500710 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -0500711 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
712 "sid %u (0x%x), flags %d (0x%x), size %d",
713 getpid (), fd, fd, func_str, sid, sid,
714 flags, flags, size);
715
716 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_FLAGS, &flags,
717 &size);
718 }
719 break;
720
721 default:
722 rv = -EOPNOTSUPP;
723 break;
724 }
725 if (rv < 0)
726 {
727 errno = -rv;
728 rv = -1;
729 }
730 }
731 else
732 {
733 func_str = "libc_vioctl";
734
Dave Wallace2a865272018-02-07 21:00:42 -0500735 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -0500736 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): cmd %d",
737 getpid (), fd, fd, func_str, cmd);
738
739 rv = libc_vioctl (fd, cmd, ap);
740 }
741
Dave Wallace2a865272018-02-07 21:00:42 -0500742 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -0500743 {
744 if (rv < 0)
745 {
746 int errno_val = errno;
747 perror (func_str);
748 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
749 "rv %d, errno = %d", getpid (), fd, fd,
750 func_str, rv, errno_val);
751 errno = errno_val;
752 }
753 else
754 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
755 getpid (), fd, fd, rv, rv);
756 }
757 va_end (ap);
758 return rv;
759}
760
761int
Dave Wallace2a865272018-02-07 21:00:42 -0500762ldp_pselect (int nfds, fd_set * __restrict readfds,
763 fd_set * __restrict writefds,
764 fd_set * __restrict exceptfds,
765 const struct timespec *__restrict timeout,
766 const __sigset_t * __restrict sigmask)
Dave Wallace048b1d62018-01-03 22:24:41 -0500767{
Florin Coras30e273b2018-11-27 00:04:59 -0800768 uword sid_bits, sid_bits_set, libc_bits, libc_bits_set;
Florin Corasdfe4cf42018-11-28 22:13:45 -0800769 ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
Florin Coras30e273b2018-11-27 00:04:59 -0800770 u32 minbits = clib_max (nfds, BITS (uword)), sid;
Dave Wallace048b1d62018-01-03 22:24:41 -0500771 char *func_str = "##";
772 f64 time_out;
Florin Coras30e273b2018-11-27 00:04:59 -0800773 int rv, fd;
Dave Wallace048b1d62018-01-03 22:24:41 -0500774
775 if (nfds < 0)
776 {
777 errno = EINVAL;
778 return -1;
779 }
780
Dave Wallace3ee1fe12018-02-23 01:09:11 -0500781 if (timeout)
782 {
783 time_out = (timeout->tv_sec == 0 && timeout->tv_nsec == 0) ?
784 (f64) 0 : (f64) timeout->tv_sec +
785 (f64) timeout->tv_nsec / (f64) 1000000000;
786
787 /* select as fine grained sleep */
788 if (!nfds)
789 {
Florin Coras05ecfcc2018-12-12 18:19:39 -0800790 LDBG (3, "sleeping for %.02f seconds", time_out);
Dave Wallace3ee1fe12018-02-23 01:09:11 -0500791
Florin Corasdfe4cf42018-11-28 22:13:45 -0800792 time_out += clib_time_now (&ldpw->clib_time);
793 while (clib_time_now (&ldpw->clib_time) < time_out)
Dave Wallace3ee1fe12018-02-23 01:09:11 -0500794 ;
795 return 0;
796 }
797 }
798 else if (!nfds)
799 {
800 errno = EINVAL;
801 return -1;
802 }
803 else
804 time_out = -1;
805
806
Dave Wallace2a865272018-02-07 21:00:42 -0500807 if (nfds <= ldp->sid_bit_val)
Dave Wallace048b1d62018-01-03 22:24:41 -0500808 {
809 func_str = "libc_pselect";
810
Florin Coras05ecfcc2018-12-12 18:19:39 -0800811 LDBG (3, "calling %s(): nfds %d, readfds %p, writefds %p, "
812 "exceptfds %p, timeout %p, sigmask %p", func_str, nfds,
Florin Coras173bae32018-11-16 18:56:28 -0800813 readfds, writefds, exceptfds, timeout, sigmask);
Dave Wallace048b1d62018-01-03 22:24:41 -0500814
815 rv = libc_pselect (nfds, readfds, writefds, exceptfds,
816 timeout, sigmask);
817 goto done;
818 }
819
Dave Wallace2a865272018-02-07 21:00:42 -0500820 if (PREDICT_FALSE (ldp->sid_bit_val > FD_SETSIZE / 2))
Dave Wallace048b1d62018-01-03 22:24:41 -0500821 {
Dave Wallace2a865272018-02-07 21:00:42 -0500822 clib_warning ("LDP<%d>: ERROR: LDP sid bit value %d (0x%x) > "
Dave Wallace048b1d62018-01-03 22:24:41 -0500823 "FD_SETSIZE/2 %d (0x%x)!", getpid (),
Dave Wallace2a865272018-02-07 21:00:42 -0500824 ldp->sid_bit_val, ldp->sid_bit_val,
Dave Wallace048b1d62018-01-03 22:24:41 -0500825 FD_SETSIZE / 2, FD_SETSIZE / 2);
826 errno = EOVERFLOW;
827 return -1;
828 }
829
Dave Wallace048b1d62018-01-03 22:24:41 -0500830 sid_bits = libc_bits = 0;
Florin Coras173bae32018-11-16 18:56:28 -0800831 u32 n_bytes = nfds / 8 + ((nfds % 8) ? 1 : 0);
Dave Wallace048b1d62018-01-03 22:24:41 -0500832 if (readfds)
833 {
Florin Corasdfe4cf42018-11-28 22:13:45 -0800834 clib_bitmap_validate (ldpw->sid_rd_bitmap, minbits);
835 clib_bitmap_validate (ldpw->libc_rd_bitmap, minbits);
836 clib_bitmap_validate (ldpw->rd_bitmap, minbits);
837 clib_memcpy_fast (ldpw->rd_bitmap, readfds, n_bytes);
Florin Coras173bae32018-11-16 18:56:28 -0800838 memset (readfds, 0, n_bytes);
Dave Wallace048b1d62018-01-03 22:24:41 -0500839
840 /* *INDENT-OFF* */
Florin Corasdfe4cf42018-11-28 22:13:45 -0800841 clib_bitmap_foreach (fd, ldpw->rd_bitmap, ({
Florin Coras173bae32018-11-16 18:56:28 -0800842 if (fd > nfds)
843 break;
844 sid = ldp_sid_from_fd (fd);
Florin Coras05ecfcc2018-12-12 18:19:39 -0800845 LDBG (3, "readfds: fd %d (0x%x), sid %u (0x%x)", fd, fd, sid, sid);
Florin Coras173bae32018-11-16 18:56:28 -0800846 if (sid == INVALID_SESSION_ID)
Florin Corasdfe4cf42018-11-28 22:13:45 -0800847 clib_bitmap_set_no_check (ldpw->libc_rd_bitmap, fd, 1);
Florin Coras173bae32018-11-16 18:56:28 -0800848 else
Florin Corasdfe4cf42018-11-28 22:13:45 -0800849 clib_bitmap_set_no_check (ldpw->sid_rd_bitmap,
Florin Coras30e273b2018-11-27 00:04:59 -0800850 vppcom_session_index (sid), 1);
Florin Coras173bae32018-11-16 18:56:28 -0800851 }));
Dave Wallace048b1d62018-01-03 22:24:41 -0500852 /* *INDENT-ON* */
853
Florin Corasdfe4cf42018-11-28 22:13:45 -0800854 sid_bits_set = clib_bitmap_last_set (ldpw->sid_rd_bitmap) + 1;
Dave Wallace048b1d62018-01-03 22:24:41 -0500855 sid_bits = (sid_bits_set > sid_bits) ? sid_bits_set : sid_bits;
856
Florin Corasdfe4cf42018-11-28 22:13:45 -0800857 libc_bits_set = clib_bitmap_last_set (ldpw->libc_rd_bitmap) + 1;
Dave Wallace048b1d62018-01-03 22:24:41 -0500858 libc_bits = (libc_bits_set > libc_bits) ? libc_bits_set : libc_bits;
859
Florin Coras05ecfcc2018-12-12 18:19:39 -0800860 LDBG (3, "readfds: sid_bits_set %d, sid_bits %d, "
861 "libc_bits_set %d, libc_bits %d", sid_bits_set,
Florin Coras173bae32018-11-16 18:56:28 -0800862 sid_bits, libc_bits_set, libc_bits);
Dave Wallace048b1d62018-01-03 22:24:41 -0500863 }
864 if (writefds)
865 {
Florin Corasdfe4cf42018-11-28 22:13:45 -0800866 clib_bitmap_validate (ldpw->sid_wr_bitmap, minbits);
867 clib_bitmap_validate (ldpw->libc_wr_bitmap, minbits);
868 clib_bitmap_validate (ldpw->wr_bitmap, minbits);
869 clib_memcpy_fast (ldpw->wr_bitmap, writefds, n_bytes);
Florin Coras173bae32018-11-16 18:56:28 -0800870 memset (writefds, 0, n_bytes);
Dave Wallace048b1d62018-01-03 22:24:41 -0500871
872 /* *INDENT-OFF* */
Florin Corasdfe4cf42018-11-28 22:13:45 -0800873 clib_bitmap_foreach (fd, ldpw->wr_bitmap, ({
Florin Coras173bae32018-11-16 18:56:28 -0800874 if (fd > nfds)
875 break;
876 sid = ldp_sid_from_fd (fd);
Florin Coras05ecfcc2018-12-12 18:19:39 -0800877 LDBG (3, "writefds: fd %d (0x%x), sid %u (0x%x)", fd, fd, sid, sid);
Florin Coras173bae32018-11-16 18:56:28 -0800878 if (sid == INVALID_SESSION_ID)
Florin Corasdfe4cf42018-11-28 22:13:45 -0800879 clib_bitmap_set_no_check (ldpw->libc_wr_bitmap, fd, 1);
Florin Coras173bae32018-11-16 18:56:28 -0800880 else
Florin Corasdfe4cf42018-11-28 22:13:45 -0800881 clib_bitmap_set_no_check (ldpw->sid_wr_bitmap,
Florin Coras30e273b2018-11-27 00:04:59 -0800882 vppcom_session_index (sid), 1);
Florin Coras173bae32018-11-16 18:56:28 -0800883 }));
Dave Wallace048b1d62018-01-03 22:24:41 -0500884 /* *INDENT-ON* */
885
Florin Corasdfe4cf42018-11-28 22:13:45 -0800886 sid_bits_set = clib_bitmap_last_set (ldpw->sid_wr_bitmap) + 1;
Dave Wallace048b1d62018-01-03 22:24:41 -0500887 sid_bits = (sid_bits_set > sid_bits) ? sid_bits_set : sid_bits;
888
Florin Corasdfe4cf42018-11-28 22:13:45 -0800889 libc_bits_set = clib_bitmap_last_set (ldpw->libc_wr_bitmap) + 1;
Dave Wallace048b1d62018-01-03 22:24:41 -0500890 libc_bits = (libc_bits_set > libc_bits) ? libc_bits_set : libc_bits;
891
Florin Coras05ecfcc2018-12-12 18:19:39 -0800892 LDBG (3, "writefds: sid_bits_set %d, sid_bits %d, "
893 "libc_bits_set %d, libc_bits %d",
Florin Coras173bae32018-11-16 18:56:28 -0800894 sid_bits_set, sid_bits, libc_bits_set, libc_bits);
Dave Wallace048b1d62018-01-03 22:24:41 -0500895 }
896 if (exceptfds)
897 {
Florin Corasdfe4cf42018-11-28 22:13:45 -0800898 clib_bitmap_validate (ldpw->sid_ex_bitmap, minbits);
899 clib_bitmap_validate (ldpw->libc_ex_bitmap, minbits);
900 clib_bitmap_validate (ldpw->ex_bitmap, minbits);
901 clib_memcpy_fast (ldpw->ex_bitmap, exceptfds, n_bytes);
Florin Coras173bae32018-11-16 18:56:28 -0800902 memset (exceptfds, 0, n_bytes);
Dave Wallace048b1d62018-01-03 22:24:41 -0500903
904 /* *INDENT-OFF* */
Florin Corasdfe4cf42018-11-28 22:13:45 -0800905 clib_bitmap_foreach (fd, ldpw->ex_bitmap, ({
Florin Coras173bae32018-11-16 18:56:28 -0800906 if (fd > nfds)
907 break;
908 sid = ldp_sid_from_fd (fd);
Florin Coras05ecfcc2018-12-12 18:19:39 -0800909 LDBG (3, "exceptfds: fd %d (0x%x), sid %u (0x%x)", fd, fd, sid, sid);
Florin Coras173bae32018-11-16 18:56:28 -0800910 if (sid == INVALID_SESSION_ID)
Florin Corasdfe4cf42018-11-28 22:13:45 -0800911 clib_bitmap_set_no_check (ldpw->libc_ex_bitmap, fd, 1);
Florin Coras173bae32018-11-16 18:56:28 -0800912 else
Florin Corasdfe4cf42018-11-28 22:13:45 -0800913 clib_bitmap_set_no_check (ldpw->sid_ex_bitmap,
Florin Coras30e273b2018-11-27 00:04:59 -0800914 vppcom_session_index (sid), 1);
Florin Coras173bae32018-11-16 18:56:28 -0800915 }));
Dave Wallace048b1d62018-01-03 22:24:41 -0500916 /* *INDENT-ON* */
917
Florin Corasdfe4cf42018-11-28 22:13:45 -0800918 sid_bits_set = clib_bitmap_last_set (ldpw->sid_ex_bitmap) + 1;
Dave Wallace048b1d62018-01-03 22:24:41 -0500919 sid_bits = (sid_bits_set > sid_bits) ? sid_bits_set : sid_bits;
920
Florin Corasdfe4cf42018-11-28 22:13:45 -0800921 libc_bits_set = clib_bitmap_last_set (ldpw->libc_ex_bitmap) + 1;
Dave Wallace048b1d62018-01-03 22:24:41 -0500922 libc_bits = (libc_bits_set > libc_bits) ? libc_bits_set : libc_bits;
923
Florin Coras05ecfcc2018-12-12 18:19:39 -0800924 LDBG (3, "exceptfds: sid_bits_set %d, sid_bits %d, "
925 "libc_bits_set %d, libc_bits %d",
Florin Coras173bae32018-11-16 18:56:28 -0800926 sid_bits_set, sid_bits, libc_bits_set, libc_bits);
Dave Wallace048b1d62018-01-03 22:24:41 -0500927 }
928
929 if (PREDICT_FALSE (!sid_bits && !libc_bits))
930 {
931 errno = EINVAL;
932 rv = -1;
933 goto done;
934 }
935
936 do
937 {
938 if (sid_bits)
939 {
Florin Corasdfe4cf42018-11-28 22:13:45 -0800940 if (!ldpw->select_vcl)
Dave Wallace048b1d62018-01-03 22:24:41 -0500941 {
942 func_str = "vppcom_select";
943
944 if (readfds)
Florin Corasdfe4cf42018-11-28 22:13:45 -0800945 clib_memcpy_fast (ldpw->rd_bitmap, ldpw->sid_rd_bitmap,
946 vec_len (ldpw->rd_bitmap) *
Dave Barach178cf492018-11-13 16:34:13 -0500947 sizeof (clib_bitmap_t));
Dave Wallace048b1d62018-01-03 22:24:41 -0500948 if (writefds)
Florin Corasdfe4cf42018-11-28 22:13:45 -0800949 clib_memcpy_fast (ldpw->wr_bitmap, ldpw->sid_wr_bitmap,
950 vec_len (ldpw->wr_bitmap) *
Dave Barach178cf492018-11-13 16:34:13 -0500951 sizeof (clib_bitmap_t));
Dave Wallace048b1d62018-01-03 22:24:41 -0500952 if (exceptfds)
Florin Corasdfe4cf42018-11-28 22:13:45 -0800953 clib_memcpy_fast (ldpw->ex_bitmap, ldpw->sid_ex_bitmap,
954 vec_len (ldpw->ex_bitmap) *
Dave Barach178cf492018-11-13 16:34:13 -0500955 sizeof (clib_bitmap_t));
Dave Wallace048b1d62018-01-03 22:24:41 -0500956
957 rv = vppcom_select (sid_bits,
Florin Corasdfe4cf42018-11-28 22:13:45 -0800958 readfds ? ldpw->rd_bitmap : NULL,
959 writefds ? ldpw->wr_bitmap : NULL,
960 exceptfds ? ldpw->ex_bitmap : NULL, 0);
Dave Wallace048b1d62018-01-03 22:24:41 -0500961 if (rv < 0)
962 {
963 errno = -rv;
964 rv = -1;
965 }
966 else if (rv > 0)
967 {
968 if (readfds)
969 {
970 /* *INDENT-OFF* */
Florin Corasdfe4cf42018-11-28 22:13:45 -0800971 clib_bitmap_foreach (sid, ldpw->rd_bitmap,
Dave Wallace048b1d62018-01-03 22:24:41 -0500972 ({
Florin Coras30e273b2018-11-27 00:04:59 -0800973 fd = ldp_fd_from_sid (vppcom_session_handle (sid));
Dave Wallace048b1d62018-01-03 22:24:41 -0500974 if (PREDICT_FALSE (fd < 0))
975 {
976 errno = EBADFD;
977 rv = -1;
978 goto done;
979 }
980 FD_SET (fd, readfds);
981 }));
982 /* *INDENT-ON* */
983 }
984 if (writefds)
985 {
986 /* *INDENT-OFF* */
Florin Corasdfe4cf42018-11-28 22:13:45 -0800987 clib_bitmap_foreach (sid, ldpw->wr_bitmap,
Dave Wallace048b1d62018-01-03 22:24:41 -0500988 ({
Florin Coras30e273b2018-11-27 00:04:59 -0800989 fd = ldp_fd_from_sid (vppcom_session_handle (sid));
Dave Wallace048b1d62018-01-03 22:24:41 -0500990 if (PREDICT_FALSE (fd < 0))
991 {
992 errno = EBADFD;
993 rv = -1;
994 goto done;
995 }
996 FD_SET (fd, writefds);
997 }));
998 /* *INDENT-ON* */
999 }
1000 if (exceptfds)
1001 {
1002 /* *INDENT-OFF* */
Florin Corasdfe4cf42018-11-28 22:13:45 -08001003 clib_bitmap_foreach (sid, ldpw->ex_bitmap,
Dave Wallace048b1d62018-01-03 22:24:41 -05001004 ({
Florin Coras30e273b2018-11-27 00:04:59 -08001005 fd = ldp_fd_from_sid (vppcom_session_handle (sid));
Dave Wallace048b1d62018-01-03 22:24:41 -05001006 if (PREDICT_FALSE (fd < 0))
1007 {
1008 errno = EBADFD;
1009 rv = -1;
1010 goto done;
1011 }
1012 FD_SET (fd, exceptfds);
1013 }));
1014 /* *INDENT-ON* */
1015 }
Florin Corasdfe4cf42018-11-28 22:13:45 -08001016 ldpw->select_vcl = 1;
Dave Wallace048b1d62018-01-03 22:24:41 -05001017 goto done;
1018 }
1019 }
1020 else
Florin Corasdfe4cf42018-11-28 22:13:45 -08001021 ldpw->select_vcl = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -05001022 }
1023 if (libc_bits)
1024 {
1025 struct timespec tspec;
1026
1027 func_str = "libc_pselect";
1028
1029 if (readfds)
Florin Corasdfe4cf42018-11-28 22:13:45 -08001030 clib_memcpy_fast (readfds, ldpw->libc_rd_bitmap,
1031 vec_len (ldpw->rd_bitmap) *
Dave Barach178cf492018-11-13 16:34:13 -05001032 sizeof (clib_bitmap_t));
Dave Wallace048b1d62018-01-03 22:24:41 -05001033 if (writefds)
Florin Corasdfe4cf42018-11-28 22:13:45 -08001034 clib_memcpy_fast (writefds, ldpw->libc_wr_bitmap,
1035 vec_len (ldpw->wr_bitmap) *
Dave Barach178cf492018-11-13 16:34:13 -05001036 sizeof (clib_bitmap_t));
Dave Wallace048b1d62018-01-03 22:24:41 -05001037 if (exceptfds)
Florin Corasdfe4cf42018-11-28 22:13:45 -08001038 clib_memcpy_fast (exceptfds, ldpw->libc_ex_bitmap,
1039 vec_len (ldpw->ex_bitmap) *
Dave Barach178cf492018-11-13 16:34:13 -05001040 sizeof (clib_bitmap_t));
Dave Wallace048b1d62018-01-03 22:24:41 -05001041 tspec.tv_sec = tspec.tv_nsec = 0;
1042 rv = libc_pselect (libc_bits,
1043 readfds ? readfds : NULL,
1044 writefds ? writefds : NULL,
1045 exceptfds ? exceptfds : NULL, &tspec, sigmask);
1046 if (rv != 0)
1047 goto done;
1048 }
1049 }
Florin Corasdfe4cf42018-11-28 22:13:45 -08001050 while ((time_out == -1) || (clib_time_now (&ldpw->clib_time) < time_out));
Dave Wallace048b1d62018-01-03 22:24:41 -05001051 rv = 0;
1052
1053done:
1054 /* TBD: set timeout to amount of time left */
Florin Corasdfe4cf42018-11-28 22:13:45 -08001055 clib_bitmap_zero (ldpw->rd_bitmap);
1056 clib_bitmap_zero (ldpw->sid_rd_bitmap);
1057 clib_bitmap_zero (ldpw->libc_rd_bitmap);
1058 clib_bitmap_zero (ldpw->wr_bitmap);
1059 clib_bitmap_zero (ldpw->sid_wr_bitmap);
1060 clib_bitmap_zero (ldpw->libc_wr_bitmap);
1061 clib_bitmap_zero (ldpw->ex_bitmap);
1062 clib_bitmap_zero (ldpw->sid_ex_bitmap);
1063 clib_bitmap_zero (ldpw->libc_ex_bitmap);
Dave Wallace048b1d62018-01-03 22:24:41 -05001064
Dave Wallace2a865272018-02-07 21:00:42 -05001065 if (LDP_DEBUG > 3)
Dave Wallace048b1d62018-01-03 22:24:41 -05001066 {
1067 if (rv < 0)
1068 {
1069 int errno_val = errno;
1070 perror (func_str);
1071 clib_warning ("LDP<%d>: ERROR: %s() failed! "
1072 "rv %d, errno = %d", getpid (),
1073 func_str, rv, errno_val);
1074 errno = errno_val;
1075 }
1076 else
1077 clib_warning ("LDP<%d>: returning %d (0x%x)", getpid (), rv, rv);
1078 }
1079 return rv;
1080}
1081
1082int
1083select (int nfds, fd_set * __restrict readfds,
1084 fd_set * __restrict writefds,
1085 fd_set * __restrict exceptfds, struct timeval *__restrict timeout)
1086{
1087 struct timespec tspec;
1088
1089 if (timeout)
1090 {
1091 tspec.tv_sec = timeout->tv_sec;
1092 tspec.tv_nsec = timeout->tv_usec * 1000;
1093 }
Dave Wallace2a865272018-02-07 21:00:42 -05001094 return ldp_pselect (nfds, readfds, writefds, exceptfds,
1095 timeout ? &tspec : NULL, NULL);
Dave Wallace048b1d62018-01-03 22:24:41 -05001096}
1097
1098#ifdef __USE_XOPEN2K
1099int
1100pselect (int nfds, fd_set * __restrict readfds,
1101 fd_set * __restrict writefds,
1102 fd_set * __restrict exceptfds,
1103 const struct timespec *__restrict timeout,
1104 const __sigset_t * __restrict sigmask)
1105{
Dave Wallace2a865272018-02-07 21:00:42 -05001106 return ldp_pselect (nfds, readfds, writefds, exceptfds, timeout, 0);
Dave Wallace048b1d62018-01-03 22:24:41 -05001107}
1108#endif
1109
1110int
1111socket (int domain, int type, int protocol)
1112{
1113 const char *func_str;
1114 int rv;
1115 u8 is_nonblocking = type & SOCK_NONBLOCK ? 1 : 0;
1116 int sock_type = type & ~(SOCK_CLOEXEC | SOCK_NONBLOCK);
1117
Dave Wallace2a865272018-02-07 21:00:42 -05001118 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001119 return -1;
1120
1121 if (((domain == AF_INET) || (domain == AF_INET6)) &&
1122 ((sock_type == SOCK_STREAM) || (sock_type == SOCK_DGRAM)))
1123 {
1124 int sid;
Dave Wallace048b1d62018-01-03 22:24:41 -05001125 u8 proto = ((sock_type == SOCK_DGRAM) ?
1126 VPPCOM_PROTO_UDP : VPPCOM_PROTO_TCP);
1127
1128 func_str = "vppcom_session_create";
1129
Florin Coras05ecfcc2018-12-12 18:19:39 -08001130 LDBG (0, "calling %s(): proto %u (%s), is_nonblocking %u",
1131 func_str, proto, vppcom_proto_str (proto), is_nonblocking);
Dave Wallace048b1d62018-01-03 22:24:41 -05001132
Dave Wallacec04cbf12018-02-07 18:14:02 -05001133 sid = vppcom_session_create (proto, is_nonblocking);
Dave Wallace048b1d62018-01-03 22:24:41 -05001134 if (sid < 0)
1135 {
1136 errno = -sid;
1137 rv = -1;
1138 }
1139 else
1140 {
Dave Wallace2a865272018-02-07 21:00:42 -05001141 func_str = "ldp_fd_from_sid";
Florin Coras30e273b2018-11-27 00:04:59 -08001142 rv = ldp_fd_alloc (sid);
Dave Wallace048b1d62018-01-03 22:24:41 -05001143 if (rv < 0)
1144 {
1145 (void) vppcom_session_close (sid);
1146 errno = -rv;
1147 rv = -1;
1148 }
1149 }
1150 }
1151 else
1152 {
1153 func_str = "libc_socket";
1154
Florin Coras05ecfcc2018-12-12 18:19:39 -08001155 LDBG (0, "calling %s()", func_str);
Dave Wallace048b1d62018-01-03 22:24:41 -05001156
1157 rv = libc_socket (domain, type, protocol);
1158 }
1159
Dave Wallace2a865272018-02-07 21:00:42 -05001160 if (LDP_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001161 {
1162 if (rv < 0)
1163 {
1164 int errno_val = errno;
1165 perror (func_str);
1166 clib_warning ("LDP<%d>: ERROR: %s() failed! "
1167 "rv %d, errno = %d",
1168 getpid (), func_str, rv, errno_val);
1169 errno = errno_val;
1170 }
1171 else
Florin Coras05ecfcc2018-12-12 18:19:39 -08001172 clib_warning ("returning fd %d (0x%x)", getpid (), rv, rv);
Dave Wallace048b1d62018-01-03 22:24:41 -05001173 }
1174 return rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001175}
1176
1177/*
1178 * Create two new sockets, of type TYPE in domain DOMAIN and using
1179 * protocol PROTOCOL, which are connected to each other, and put file
1180 * descriptors for them in FDS[0] and FDS[1]. If PROTOCOL is zero,
1181 * one will be chosen automatically.
1182 * Returns 0 on success, -1 for errors.
1183 * */
1184int
Dave Wallace048b1d62018-01-03 22:24:41 -05001185socketpair (int domain, int type, int protocol, int fds[2])
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001186{
Dave Wallace048b1d62018-01-03 22:24:41 -05001187 const char *func_str;
1188 int rv;
1189 int sock_type = type & ~(SOCK_CLOEXEC | SOCK_NONBLOCK);
1190
Dave Wallace2a865272018-02-07 21:00:42 -05001191 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001192 return -1;
1193
1194 if (((domain == AF_INET) || (domain == AF_INET6)) &&
1195 ((sock_type == SOCK_STREAM) || (sock_type == SOCK_DGRAM)))
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001196 {
Dave Wallace8aaba562018-01-18 17:21:19 -05001197 func_str = __func__;
1198
Dave Wallace048b1d62018-01-03 22:24:41 -05001199 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
1200 errno = ENOSYS;
1201 rv = -1;
1202 }
1203 else
1204 {
1205 func_str = "libc_socket";
1206
Florin Coras05ecfcc2018-12-12 18:19:39 -08001207 LDBG (1, "calling %s()", func_str);
Dave Wallace048b1d62018-01-03 22:24:41 -05001208
Florin Coras173bae32018-11-16 18:56:28 -08001209 rv = libc_socketpair (domain, type, protocol, fds);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001210 }
1211
Dave Wallace2a865272018-02-07 21:00:42 -05001212 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05001213 {
1214 if (rv < 0)
1215 {
1216 int errno_val = errno;
1217 perror (func_str);
1218 clib_warning ("LDP<%d>: ERROR: %s() failed! "
1219 "rv %d, errno = %d",
1220 getpid (), func_str, rv, errno_val);
1221 errno = errno_val;
1222 }
1223 else
1224 clib_warning ("LDP<%d>: : returning fd %d (0x%x)", getpid (), rv, rv);
1225 }
1226 return rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001227}
1228
1229int
Dave Wallace048b1d62018-01-03 22:24:41 -05001230bind (int fd, __CONST_SOCKADDR_ARG addr, socklen_t len)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001231{
1232 int rv;
Dave Wallace2a865272018-02-07 21:00:42 -05001233 u32 sid = ldp_sid_from_fd (fd);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001234
Dave Wallace2a865272018-02-07 21:00:42 -05001235 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001236 return -1;
1237
1238 if (sid != INVALID_SESSION_ID)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001239 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001240 vppcom_endpt_t ep;
1241
Dave Wallace048b1d62018-01-03 22:24:41 -05001242 switch (addr->sa_family)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001243 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001244 case AF_INET:
1245 if (len != sizeof (struct sockaddr_in))
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001246 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001247 clib_warning
1248 ("LDP<%d>: ERROR: fd %d (0x%x): sid %u (0x%x): Invalid "
1249 "AF_INET addr len %u!", getpid (), fd, fd, sid, sid, len);
1250 errno = EINVAL;
1251 rv = -1;
1252 goto done;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001253 }
Dave Wallace048b1d62018-01-03 22:24:41 -05001254 ep.is_ip4 = VPPCOM_IS_IP4;
1255 ep.ip = (u8 *) & ((const struct sockaddr_in *) addr)->sin_addr;
1256 ep.port = (u16) ((const struct sockaddr_in *) addr)->sin_port;
1257 break;
1258
1259 case AF_INET6:
1260 if (len != sizeof (struct sockaddr_in6))
1261 {
1262 clib_warning
1263 ("LDP<%d>: ERROR: fd %d (0x%x): sid %u (0x%x): Invalid "
1264 "AF_INET6 addr len %u!", getpid (), fd, fd, sid, sid, len);
1265 errno = EINVAL;
1266 rv = -1;
1267 goto done;
1268 }
1269 ep.is_ip4 = VPPCOM_IS_IP6;
1270 ep.ip = (u8 *) & ((const struct sockaddr_in6 *) addr)->sin6_addr;
1271 ep.port = (u16) ((const struct sockaddr_in6 *) addr)->sin6_port;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001272 break;
1273
1274 default:
Dave Wallace048b1d62018-01-03 22:24:41 -05001275 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): sid %u (0x%x): "
1276 "Unsupported address family %u!",
1277 getpid (), fd, fd, sid, sid, addr->sa_family);
1278 errno = EAFNOSUPPORT;
1279 rv = -1;
1280 goto done;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001281 }
Florin Coras05ecfcc2018-12-12 18:19:39 -08001282 LDBG (0, "fd %d (0x%x): calling vppcom_session_bind(): "
1283 "sid %u (0x%x), addr %p, len %u", fd, fd, sid, sid, addr, len);
Dave Wallace048b1d62018-01-03 22:24:41 -05001284
1285 rv = vppcom_session_bind (sid, &ep);
1286 if (rv != VPPCOM_OK)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001287 {
1288 errno = -rv;
Dave Wallace048b1d62018-01-03 22:24:41 -05001289 rv = -1;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001290 }
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001291 }
Dave Wallace048b1d62018-01-03 22:24:41 -05001292 else
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001293 {
Florin Coras05ecfcc2018-12-12 18:19:39 -08001294 LDBG (0, "fd %d (0x%x): calling libc_bind(): addr %p, len %u",
1295 fd, fd, addr, len);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001296
Dave Wallace048b1d62018-01-03 22:24:41 -05001297 rv = libc_bind (fd, addr, len);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001298 }
1299
Dave Wallace048b1d62018-01-03 22:24:41 -05001300done:
Florin Coras05ecfcc2018-12-12 18:19:39 -08001301 LDBG (1, "fd %d (0x%x): returning %d", fd, fd, rv);
1302
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001303 return rv;
1304}
1305
1306static inline int
Dave Wallace2a865272018-02-07 21:00:42 -05001307ldp_copy_ep_to_sockaddr (__SOCKADDR_ARG addr, socklen_t * __restrict len,
1308 vppcom_endpt_t * ep)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001309{
Dave Wallace048b1d62018-01-03 22:24:41 -05001310 int rv = 0;
1311 int sa_len, copy_len;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001312
Dave Wallace2a865272018-02-07 21:00:42 -05001313 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001314 return -1;
1315
1316 if (addr && len && ep)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001317 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001318 addr->sa_family = (ep->is_ip4 == VPPCOM_IS_IP4) ? AF_INET : AF_INET6;
1319 switch (addr->sa_family)
1320 {
1321 case AF_INET:
1322 ((struct sockaddr_in *) addr)->sin_port = ep->port;
1323 if (*len > sizeof (struct sockaddr_in))
1324 *len = sizeof (struct sockaddr_in);
1325 sa_len = sizeof (struct sockaddr_in) - sizeof (struct in_addr);
1326 copy_len = *len - sa_len;
1327 if (copy_len > 0)
1328 memcpy (&((struct sockaddr_in *) addr)->sin_addr, ep->ip,
1329 copy_len);
1330 break;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001331
Dave Wallace048b1d62018-01-03 22:24:41 -05001332 case AF_INET6:
1333 ((struct sockaddr_in6 *) addr)->sin6_port = ep->port;
1334 if (*len > sizeof (struct sockaddr_in6))
1335 *len = sizeof (struct sockaddr_in6);
1336 sa_len = sizeof (struct sockaddr_in6) - sizeof (struct in6_addr);
1337 copy_len = *len - sa_len;
1338 if (copy_len > 0)
1339 memcpy (((struct sockaddr_in6 *) addr)->sin6_addr.
1340 __in6_u.__u6_addr8, ep->ip, copy_len);
1341 break;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001342
Dave Wallace048b1d62018-01-03 22:24:41 -05001343 default:
1344 /* Not possible */
1345 rv = -EAFNOSUPPORT;
1346 break;
1347 }
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001348 }
Dave Wallacee695cb42017-11-02 22:04:42 -04001349 return rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001350}
1351
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001352int
Dave Wallace048b1d62018-01-03 22:24:41 -05001353getsockname (int fd, __SOCKADDR_ARG addr, socklen_t * __restrict len)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001354{
1355 int rv;
Dave Wallace048b1d62018-01-03 22:24:41 -05001356 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05001357 u32 sid = ldp_sid_from_fd (fd);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001358
Dave Wallace2a865272018-02-07 21:00:42 -05001359 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001360 return -1;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001361
Dave Wallace048b1d62018-01-03 22:24:41 -05001362 if (sid != INVALID_SESSION_ID)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001363 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001364 vppcom_endpt_t ep;
1365 u8 addr_buf[sizeof (struct in6_addr)];
1366 u32 size = sizeof (ep);
1367
1368 ep.ip = addr_buf;
1369 func_str = "vppcom_session_attr[GET_LCL_ADDR]";
1370
Dave Wallace2a865272018-02-07 21:00:42 -05001371 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001372 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), "
1373 "addr %p, len %u",
1374 getpid (), fd, fd, func_str, sid, sid, addr, len);
1375
1376 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_LCL_ADDR, &ep, &size);
1377 if (rv != VPPCOM_OK)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001378 {
1379 errno = -rv;
Dave Wallace048b1d62018-01-03 22:24:41 -05001380 rv = -1;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001381 }
Dave Wallace048b1d62018-01-03 22:24:41 -05001382 else
1383 {
Dave Wallace2a865272018-02-07 21:00:42 -05001384 rv = ldp_copy_ep_to_sockaddr (addr, len, &ep);
Dave Wallace048b1d62018-01-03 22:24:41 -05001385 if (rv != VPPCOM_OK)
1386 {
1387 errno = -rv;
1388 rv = -1;
1389 }
1390 }
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001391 }
1392 else
1393 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001394 func_str = "libc_getsockname";
1395
Dave Wallace2a865272018-02-07 21:00:42 -05001396 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001397 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1398 "addr %p, len %u",
1399 getpid (), fd, fd, func_str, addr, len);
1400
1401 rv = libc_getsockname (fd, addr, len);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001402 }
1403
Dave Wallace2a865272018-02-07 21:00:42 -05001404 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001405 {
1406 if (rv < 0)
1407 {
1408 int errno_val = errno;
1409 perror (func_str);
1410 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
1411 "rv %d, errno = %d", getpid (), fd, fd,
1412 func_str, rv, errno_val);
1413 errno = errno_val;
1414 }
1415 else
1416 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
1417 getpid (), fd, fd, rv, rv);
1418 }
1419 return rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001420}
1421
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001422int
Dave Wallace048b1d62018-01-03 22:24:41 -05001423connect (int fd, __CONST_SOCKADDR_ARG addr, socklen_t len)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001424{
Dave Wallace048b1d62018-01-03 22:24:41 -05001425 int rv;
Dave Wallace2a865272018-02-07 21:00:42 -05001426 u32 sid = ldp_sid_from_fd (fd);
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001427
Dave Wallace2a865272018-02-07 21:00:42 -05001428 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001429 return -1;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001430
Dave Wallace048b1d62018-01-03 22:24:41 -05001431 if (!addr)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001432 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001433 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): NULL addr, len %u",
1434 getpid (), fd, fd, len);
1435 errno = EINVAL;
1436 rv = -1;
1437 goto done;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001438 }
1439
Dave Wallace048b1d62018-01-03 22:24:41 -05001440 if (sid != INVALID_SESSION_ID)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001441 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001442 vppcom_endpt_t ep;
1443
Dave Wallace048b1d62018-01-03 22:24:41 -05001444 switch (addr->sa_family)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001445 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001446 case AF_INET:
1447 if (len != sizeof (struct sockaddr_in))
1448 {
1449 clib_warning
1450 ("LDP<%d>: fd %d (0x%x): ERROR sid %u (0x%x): Invalid "
1451 "AF_INET addr len %u!", getpid (), fd, fd, sid, sid, len);
1452 errno = EINVAL;
1453 rv = -1;
1454 goto done;
1455 }
1456 ep.is_ip4 = VPPCOM_IS_IP4;
1457 ep.ip = (u8 *) & ((const struct sockaddr_in *) addr)->sin_addr;
1458 ep.port = (u16) ((const struct sockaddr_in *) addr)->sin_port;
1459 break;
1460
1461 case AF_INET6:
1462 if (len != sizeof (struct sockaddr_in6))
1463 {
1464 clib_warning
1465 ("LDP<%d>: fd %d (0x%x): ERROR sid %u (0x%x): Invalid "
1466 "AF_INET6 addr len %u!", getpid (), fd, fd, sid, sid, len);
1467 errno = EINVAL;
1468 rv = -1;
1469 goto done;
1470 }
1471 ep.is_ip4 = VPPCOM_IS_IP6;
1472 ep.ip = (u8 *) & ((const struct sockaddr_in6 *) addr)->sin6_addr;
1473 ep.port = (u16) ((const struct sockaddr_in6 *) addr)->sin6_port;
1474 break;
1475
1476 default:
1477 clib_warning ("LDP<%d>: fd %d (0x%x): ERROR sid %u (0x%x): "
1478 "Unsupported address family %u!",
1479 getpid (), fd, fd, sid, sid, addr->sa_family);
1480 errno = EAFNOSUPPORT;
1481 rv = -1;
1482 goto done;
1483 }
Florin Coras05ecfcc2018-12-12 18:19:39 -08001484 LDBG (0, "fd %d (0x%x): calling vppcom_session_connect(): sid %u (0x%x)"
1485 " addr %p len %u", fd, fd, sid, sid, addr, len);
Dave Wallace048b1d62018-01-03 22:24:41 -05001486
1487 rv = vppcom_session_connect (sid, &ep);
1488 if (rv != VPPCOM_OK)
1489 {
1490 errno = -rv;
1491 rv = -1;
1492 }
1493 }
1494 else
1495 {
Florin Coras05ecfcc2018-12-12 18:19:39 -08001496 LDBG (0, "fd %d (0x%x): calling libc_connect(): addr %p, len %u",
1497 fd, fd, addr, len);
Dave Wallace048b1d62018-01-03 22:24:41 -05001498
1499 rv = libc_connect (fd, addr, len);
1500 }
1501
1502done:
Florin Coras05ecfcc2018-12-12 18:19:39 -08001503 LDBG (1, "fd %d (0x%x): returning %d (0x%x)", fd, fd, rv, rv);
Dave Wallace048b1d62018-01-03 22:24:41 -05001504 return rv;
1505}
1506
1507int
1508getpeername (int fd, __SOCKADDR_ARG addr, socklen_t * __restrict len)
1509{
1510 int rv;
1511 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05001512 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05001513
Dave Wallace2a865272018-02-07 21:00:42 -05001514 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001515 return -1;
1516
Dave Wallace048b1d62018-01-03 22:24:41 -05001517 if (sid != INVALID_SESSION_ID)
1518 {
1519 vppcom_endpt_t ep;
1520 u8 addr_buf[sizeof (struct in6_addr)];
1521 u32 size = sizeof (ep);
1522
1523 ep.ip = addr_buf;
1524 func_str = "vppcom_session_attr[GET_PEER_ADDR]";
1525
Dave Wallace2a865272018-02-07 21:00:42 -05001526 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001527 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), "
1528 "addr %p, len %u",
1529 getpid (), fd, fd, func_str, sid, sid, addr, len);
1530
1531 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_PEER_ADDR, &ep, &size);
1532 if (rv != VPPCOM_OK)
1533 {
1534 errno = -rv;
1535 rv = -1;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001536 }
1537 else
1538 {
Dave Wallace2a865272018-02-07 21:00:42 -05001539 rv = ldp_copy_ep_to_sockaddr (addr, len, &ep);
Dave Wallace048b1d62018-01-03 22:24:41 -05001540 if (rv != VPPCOM_OK)
1541 {
1542 errno = -rv;
1543 rv = -1;
1544 }
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001545 }
1546 }
Dave Wallace048b1d62018-01-03 22:24:41 -05001547 else
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001548 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001549 func_str = "libc_getpeername";
1550
Dave Wallace2a865272018-02-07 21:00:42 -05001551 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001552 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1553 "addr %p, len %u",
1554 getpid (), fd, fd, func_str, addr, len);
1555
1556 rv = libc_getpeername (fd, addr, len);
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001557 }
1558
Dave Wallace2a865272018-02-07 21:00:42 -05001559 if (LDP_DEBUG > 2)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001560 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001561 if (rv < 0)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001562 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001563 int errno_val = errno;
1564 perror (func_str);
1565 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
1566 "rv %d, errno = %d", getpid (), fd, fd,
1567 func_str, rv, errno_val);
1568 errno = errno_val;
1569 }
1570 else
1571 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
1572 getpid (), fd, fd, rv, rv);
1573 }
1574 return rv;
1575}
1576
1577ssize_t
1578send (int fd, const void *buf, size_t n, int flags)
1579{
1580 ssize_t size;
1581 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05001582 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05001583
Dave Wallace2a865272018-02-07 21:00:42 -05001584 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001585 return -1;
1586
1587 if (sid != INVALID_SESSION_ID)
1588 {
1589
1590 func_str = "vppcom_session_sendto";
1591
Dave Wallace2a865272018-02-07 21:00:42 -05001592 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001593 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), "
1594 "buf %p, n %u, flags 0x%x",
1595 getpid (), fd, fd, func_str, sid, sid, buf, n, flags);
1596
1597 size = vppcom_session_sendto (sid, (void *) buf, n, flags, NULL);
qchangaa8f63c2018-05-30 11:44:18 -07001598 if (size < VPPCOM_OK)
Dave Wallace048b1d62018-01-03 22:24:41 -05001599 {
1600 errno = -size;
1601 size = -1;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001602 }
1603 }
Dave Wallace048b1d62018-01-03 22:24:41 -05001604 else
1605 {
1606 func_str = "libc_send";
1607
Dave Wallace2a865272018-02-07 21:00:42 -05001608 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001609 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1610 "buf %p, n %u, flags 0x%x",
1611 getpid (), fd, fd, func_str, buf, n, flags);
1612
1613 size = libc_send (fd, buf, n, flags);
1614 }
1615
Dave Wallace2a865272018-02-07 21:00:42 -05001616 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001617 {
1618 if (size < 0)
1619 {
1620 int errno_val = errno;
1621 perror (func_str);
1622 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
1623 "rv %d, errno = %d", getpid (), fd, fd,
1624 func_str, size, errno_val);
1625 errno = errno_val;
1626 }
1627 else
1628 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
1629 getpid (), fd, fd, size, size);
1630 }
1631 return size;
1632}
1633
1634ssize_t
1635sendfile (int out_fd, int in_fd, off_t * offset, size_t len)
1636{
Florin Corasdfe4cf42018-11-28 22:13:45 -08001637 ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
Dave Wallace048b1d62018-01-03 22:24:41 -05001638 ssize_t size = 0;
1639 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05001640 u32 sid = ldp_sid_from_fd (out_fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05001641
Dave Wallace2a865272018-02-07 21:00:42 -05001642 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001643 return -1;
1644
1645 if (sid != INVALID_SESSION_ID)
1646 {
1647 int rv;
1648 ssize_t results = 0;
1649 size_t n_bytes_left = len;
1650 size_t bytes_to_read;
1651 int nbytes;
1652 int errno_val;
1653 u8 eagain = 0;
1654 u32 flags, flags_len = sizeof (flags);
1655
1656 func_str = "vppcom_session_attr[GET_FLAGS]";
1657 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_FLAGS, &flags,
1658 &flags_len);
1659 if (PREDICT_FALSE (rv != VPPCOM_OK))
1660 {
1661 clib_warning ("LDP<%d>: ERROR: out fd %d (0x%x): %s(): "
1662 "sid %u (0x%x), returned %d (%s)!", getpid (),
1663 out_fd, out_fd, func_str, sid, sid, rv,
1664 vppcom_retval_str (rv));
1665
Florin Corasdfe4cf42018-11-28 22:13:45 -08001666 vec_reset_length (ldpw->io_buffer);
Dave Wallace048b1d62018-01-03 22:24:41 -05001667 errno = -rv;
1668 size = -1;
1669 goto done;
1670 }
1671
1672 if (offset)
1673 {
1674 off_t off = lseek (in_fd, *offset, SEEK_SET);
1675 if (PREDICT_FALSE (off == -1))
1676 {
1677 func_str = "lseek";
1678 errno_val = errno;
1679 clib_warning ("LDP<%d>: ERROR: out fd %d (0x%x): %s(): "
1680 "SEEK_SET failed: in_fd %d, offset %p, "
1681 "*offset %ld, rv %ld, errno %d", getpid (),
1682 out_fd, out_fd, in_fd, offset, *offset, off,
1683 errno_val);
1684 errno = errno_val;
1685 size = -1;
1686 goto done;
1687 }
1688
1689 ASSERT (off == *offset);
1690 }
1691
1692 do
1693 {
1694 func_str = "vppcom_session_attr[GET_NWRITE]";
1695 size = vppcom_session_attr (sid, VPPCOM_ATTR_GET_NWRITE, 0, 0);
1696 if (size < 0)
1697 {
1698 clib_warning
1699 ("LDP<%d>: ERROR: fd %d (0x%x): %s(): sid %u (0x%x), "
1700 "returned %d (%s)!", getpid (), out_fd, out_fd, func_str,
1701 sid, sid, size, vppcom_retval_str (size));
Florin Corasdfe4cf42018-11-28 22:13:45 -08001702 vec_reset_length (ldpw->io_buffer);
Dave Wallace048b1d62018-01-03 22:24:41 -05001703 errno = -size;
1704 size = -1;
1705 goto done;
1706 }
1707
1708 bytes_to_read = size;
Dave Wallace2a865272018-02-07 21:00:42 -05001709 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001710 clib_warning
1711 ("LDP<%d>: fd %d (0x%x): called %s(): sid %u (0x%x), "
1712 "results %ld, n_bytes_left %lu, bytes_to_read %lu", getpid (),
1713 out_fd, out_fd, func_str, sid, sid, results, n_bytes_left,
1714 bytes_to_read);
1715
1716 if (bytes_to_read == 0)
1717 {
1718 if (flags & O_NONBLOCK)
1719 {
1720 if (!results)
1721 {
Dave Wallace2a865272018-02-07 21:00:42 -05001722 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001723 clib_warning ("LDP<%d>: fd %d (0x%x): sid %u (0x%x): "
1724 "EAGAIN",
1725 getpid (), out_fd, out_fd, sid, sid);
1726 eagain = 1;
1727 }
1728 goto update_offset;
1729 }
1730 else
1731 continue;
1732 }
1733 bytes_to_read = clib_min (n_bytes_left, bytes_to_read);
Florin Corasdfe4cf42018-11-28 22:13:45 -08001734 vec_validate (ldpw->io_buffer, bytes_to_read);
1735 nbytes = libc_read (in_fd, ldpw->io_buffer, bytes_to_read);
Dave Wallace048b1d62018-01-03 22:24:41 -05001736 if (nbytes < 0)
1737 {
1738 func_str = "libc_read";
1739 errno_val = errno;
1740 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): in_fd (%d), "
1741 "io_buffer %p, bytes_to_read %lu, rv %d, "
1742 "errno %d", getpid (), out_fd, out_fd, func_str,
Florin Corasdfe4cf42018-11-28 22:13:45 -08001743 in_fd, ldpw->io_buffer, bytes_to_read, nbytes,
Dave Wallace048b1d62018-01-03 22:24:41 -05001744 errno_val);
1745 errno = errno_val;
1746
1747 if (results == 0)
1748 {
Florin Corasdfe4cf42018-11-28 22:13:45 -08001749 vec_reset_length (ldpw->io_buffer);
Dave Wallace048b1d62018-01-03 22:24:41 -05001750 size = -1;
1751 goto done;
1752 }
1753 goto update_offset;
1754 }
1755 func_str = "vppcom_session_write";
Dave Wallace2a865272018-02-07 21:00:42 -05001756 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001757 clib_warning
1758 ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), "
1759 "buf %p, nbytes %u: results %d, n_bytes_left %d", getpid (),
Florin Corasdfe4cf42018-11-28 22:13:45 -08001760 out_fd, out_fd, func_str, sid, sid, ldpw->io_buffer, nbytes,
Dave Wallace048b1d62018-01-03 22:24:41 -05001761 results, n_bytes_left);
1762
Florin Corasdfe4cf42018-11-28 22:13:45 -08001763 size = vppcom_session_write (sid, ldpw->io_buffer, nbytes);
Dave Wallace048b1d62018-01-03 22:24:41 -05001764 if (size < 0)
1765 {
1766 if (size == VPPCOM_EAGAIN)
1767 {
1768 if (flags & O_NONBLOCK)
1769 {
1770 if (!results)
1771 {
Dave Wallace2a865272018-02-07 21:00:42 -05001772 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001773 clib_warning
1774 ("LDP<%d>: fd %d (0x%x): sid %u (0x%x): "
1775 "EAGAIN", getpid (), out_fd, out_fd, sid, sid);
1776 eagain = 1;
1777 }
1778 goto update_offset;
1779 }
1780 else
1781 continue;
1782 }
1783 else
1784 {
1785 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s():"
1786 "sid %u, io_buffer %p, nbytes %u "
1787 "returned %d (%s)",
1788 getpid (), out_fd, out_fd, func_str,
Florin Corasdfe4cf42018-11-28 22:13:45 -08001789 sid, ldpw->io_buffer, nbytes,
Dave Wallace048b1d62018-01-03 22:24:41 -05001790 size, vppcom_retval_str (size));
1791 }
1792 if (results == 0)
1793 {
Florin Corasdfe4cf42018-11-28 22:13:45 -08001794 vec_reset_length (ldpw->io_buffer);
Dave Wallace048b1d62018-01-03 22:24:41 -05001795 errno = -size;
1796 size = -1;
1797 goto done;
1798 }
1799 goto update_offset;
1800 }
1801
1802 results += nbytes;
1803 ASSERT (n_bytes_left >= nbytes);
1804 n_bytes_left = n_bytes_left - nbytes;
1805 }
1806 while (n_bytes_left > 0);
1807
1808 update_offset:
Florin Corasdfe4cf42018-11-28 22:13:45 -08001809 vec_reset_length (ldpw->io_buffer);
Dave Wallace048b1d62018-01-03 22:24:41 -05001810 if (offset)
1811 {
1812 off_t off = lseek (in_fd, *offset, SEEK_SET);
1813 if (PREDICT_FALSE (off == -1))
1814 {
1815 func_str = "lseek";
1816 errno_val = errno;
1817 clib_warning ("LDP<%d>: ERROR: %s(): SEEK_SET failed: "
1818 "in_fd %d, offset %p, *offset %ld, "
1819 "rv %ld, errno %d", getpid (), in_fd,
1820 offset, *offset, off, errno_val);
1821 errno = errno_val;
1822 size = -1;
1823 goto done;
1824 }
1825
1826 ASSERT (off == *offset);
1827 *offset += results + 1;
1828 }
1829 if (eagain)
1830 {
1831 errno = EAGAIN;
1832 size = -1;
1833 }
1834 else
1835 size = results;
1836 }
1837 else
1838 {
1839 func_str = "libc_send";
1840
Dave Wallace2a865272018-02-07 21:00:42 -05001841 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001842 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1843 "in_fd %d, offset %p, len %u",
1844 getpid (), out_fd, out_fd, func_str,
1845 in_fd, offset, len);
1846
1847 size = libc_sendfile (out_fd, in_fd, offset, len);
1848 }
1849
1850done:
Dave Wallace2a865272018-02-07 21:00:42 -05001851 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001852 {
1853 if (size < 0)
1854 {
1855 int errno_val = errno;
1856 perror (func_str);
1857 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
1858 "rv %d, errno = %d", getpid (), out_fd, out_fd,
1859 func_str, size, errno_val);
1860 errno = errno_val;
1861 }
1862 else
1863 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
1864 getpid (), out_fd, out_fd, size, size);
1865 }
1866 return size;
1867}
1868
1869ssize_t
1870sendfile64 (int out_fd, int in_fd, off_t * offset, size_t len)
1871{
1872 return sendfile (out_fd, in_fd, offset, len);
1873}
1874
1875ssize_t
1876recv (int fd, void *buf, size_t n, int flags)
1877{
1878 ssize_t size;
1879 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05001880 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05001881
Dave Wallace2a865272018-02-07 21:00:42 -05001882 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001883 return -1;
1884
1885 if (sid != INVALID_SESSION_ID)
1886 {
1887 func_str = "vppcom_session_recvfrom";
1888
Dave Wallace2a865272018-02-07 21:00:42 -05001889 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001890 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1891 "sid %u (0x%x), buf %p, n %u, flags 0x%x", getpid (),
1892 fd, fd, func_str, sid, sid, buf, n, flags);
1893
1894 size = vppcom_session_recvfrom (sid, buf, n, flags, NULL);
1895 if (size < 0)
1896 {
1897 errno = -size;
1898 size = -1;
1899 }
1900 }
1901 else
1902 {
1903 func_str = "libc_recv";
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): calling %s(): "
1907 "buf %p, n %u, flags 0x%x", getpid (),
1908 fd, fd, func_str, buf, n, flags);
1909
1910 size = libc_recv (fd, buf, n, flags);
1911 }
1912
Dave Wallace2a865272018-02-07 21:00:42 -05001913 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001914 {
1915 if (size < 0)
1916 {
1917 int errno_val = errno;
1918 perror (func_str);
1919 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
1920 "rv %d, errno = %d", getpid (), fd, fd,
1921 func_str, size, errno_val);
1922 errno = errno_val;
1923 }
1924 else
1925 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
1926 getpid (), fd, fd, size, size);
1927 }
1928 return size;
1929}
1930
1931ssize_t
1932sendto (int fd, const void *buf, size_t n, int flags,
1933 __CONST_SOCKADDR_ARG addr, socklen_t addr_len)
1934{
1935 ssize_t size;
1936 const char *func_str = __func__;
Dave Wallace2a865272018-02-07 21:00:42 -05001937 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05001938
Dave Wallace2a865272018-02-07 21:00:42 -05001939 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001940 return -1;
1941
1942 if (sid != INVALID_SESSION_ID)
1943 {
1944 vppcom_endpt_t *ep = 0;
1945 vppcom_endpt_t _ep;
1946
1947 if (addr)
1948 {
1949 ep = &_ep;
Dave Wallace048b1d62018-01-03 22:24:41 -05001950 switch (addr->sa_family)
1951 {
1952 case AF_INET:
1953 ep->is_ip4 = VPPCOM_IS_IP4;
1954 ep->ip =
1955 (uint8_t *) & ((const struct sockaddr_in *) addr)->sin_addr;
1956 ep->port =
1957 (uint16_t) ((const struct sockaddr_in *) addr)->sin_port;
1958 break;
1959
1960 case AF_INET6:
1961 ep->is_ip4 = VPPCOM_IS_IP6;
1962 ep->ip =
1963 (uint8_t *) & ((const struct sockaddr_in6 *) addr)->sin6_addr;
1964 ep->port =
1965 (uint16_t) ((const struct sockaddr_in6 *) addr)->sin6_port;
1966 break;
1967
1968 default:
1969 errno = EAFNOSUPPORT;
1970 size = -1;
1971 goto done;
1972 }
1973 }
1974
1975 func_str = "vppcom_session_sendto";
1976
Dave Wallace2a865272018-02-07 21:00:42 -05001977 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001978 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1979 "sid %u (0x%x), buf %p, n %u, flags 0x%x, ep %p",
1980 getpid (), fd, fd, func_str, sid, sid, buf, n,
1981 flags, ep);
1982
1983 size = vppcom_session_sendto (sid, (void *) buf, n, flags, ep);
1984 if (size < 0)
1985 {
1986 errno = -size;
1987 size = -1;
1988 }
1989 }
1990 else
1991 {
1992 func_str = "libc_sendto";
1993
Dave Wallace2a865272018-02-07 21:00:42 -05001994 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001995 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1996 "buf %p, n %u, flags 0x%x, addr %p, addr_len %d",
1997 getpid (), fd, fd, func_str, buf, n, flags,
1998 addr, addr_len);
1999
2000 size = libc_sendto (fd, buf, n, flags, addr, addr_len);
2001 }
2002
2003done:
Dave Wallace2a865272018-02-07 21:00:42 -05002004 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002005 {
2006 if (size < 0)
2007 {
2008 int errno_val = errno;
2009 perror (func_str);
2010 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2011 "rv %d, errno = %d", getpid (), fd, fd,
2012 func_str, size, errno_val);
2013 errno = errno_val;
2014 }
2015 else
2016 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2017 getpid (), fd, fd, size, size);
2018 }
2019 return size;
2020}
2021
2022ssize_t
2023recvfrom (int fd, void *__restrict buf, size_t n, int flags,
2024 __SOCKADDR_ARG addr, socklen_t * __restrict addr_len)
2025{
2026 ssize_t size;
2027 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05002028 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05002029
Dave Wallace2a865272018-02-07 21:00:42 -05002030 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002031 return -1;
2032
2033 if (sid != INVALID_SESSION_ID)
2034 {
2035 vppcom_endpt_t ep;
2036 u8 src_addr[sizeof (struct sockaddr_in6)];
2037
2038 func_str = "vppcom_session_recvfrom";
2039
Dave Wallace2a865272018-02-07 21:00:42 -05002040 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002041 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2042 "sid %u (0x%x), buf %p, n %u, flags 0x%x, ep %p",
2043 getpid (), fd, fd, func_str, sid, sid, buf, n,
2044 flags, &ep);
2045 if (addr)
2046 {
2047 ep.ip = src_addr;
2048 size = vppcom_session_recvfrom (sid, buf, n, flags, &ep);
2049
2050 if (size > 0)
Dave Wallace2a865272018-02-07 21:00:42 -05002051 size = ldp_copy_ep_to_sockaddr (addr, addr_len, &ep);
Dave Wallace048b1d62018-01-03 22:24:41 -05002052 }
2053 else
2054 size = vppcom_session_recvfrom (sid, buf, n, flags, NULL);
2055
2056 if (size < 0)
2057 {
2058 errno = -size;
2059 size = -1;
2060 }
2061 }
2062 else
2063 {
2064 func_str = "libc_recvfrom";
2065
Dave Wallace2a865272018-02-07 21:00:42 -05002066 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002067 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2068 "buf %p, n %u, flags 0x%x, addr %p, addr_len %d",
2069 getpid (), fd, fd, func_str, buf, n, flags,
2070 addr, addr_len);
2071
2072 size = libc_recvfrom (fd, buf, n, flags, addr, addr_len);
2073 }
2074
Dave Wallace2a865272018-02-07 21:00:42 -05002075 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002076 {
2077 if (size < 0)
2078 {
2079 int errno_val = errno;
2080 perror (func_str);
2081 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2082 "rv %d, errno = %d", getpid (), fd, fd,
2083 func_str, size, errno_val);
2084 errno = errno_val;
2085 }
2086 else
2087 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2088 getpid (), fd, fd, size, size);
2089 }
2090 return size;
2091}
2092
2093ssize_t
2094sendmsg (int fd, const struct msghdr * message, int flags)
2095{
2096 ssize_t size;
2097 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05002098 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05002099
Dave Wallace2a865272018-02-07 21:00:42 -05002100 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002101 return -1;
2102
2103 if (sid != INVALID_SESSION_ID)
2104 {
Dave Wallace8aaba562018-01-18 17:21:19 -05002105 func_str = __func__;
2106
Dave Wallace048b1d62018-01-03 22:24:41 -05002107 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
2108 errno = ENOSYS;
2109 size = -1;
2110 }
2111 else
2112 {
2113 func_str = "libc_sendmsg";
2114
Dave Wallace2a865272018-02-07 21:00:42 -05002115 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002116 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2117 "message %p, flags 0x%x",
2118 getpid (), fd, fd, func_str, message, flags);
2119
2120 size = libc_sendmsg (fd, message, flags);
2121 }
2122
Dave Wallace2a865272018-02-07 21:00:42 -05002123 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002124 {
2125 if (size < 0)
2126 {
2127 int errno_val = errno;
2128 perror (func_str);
2129 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2130 "rv %d, errno = %d", getpid (), fd, fd,
2131 func_str, size, errno_val);
2132 errno = errno_val;
2133 }
2134 else
2135 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2136 getpid (), fd, fd, size, size);
2137 }
2138 return size;
2139}
2140
2141#ifdef USE_GNU
2142int
2143sendmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags)
2144{
2145 ssize_t size;
2146 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05002147 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05002148
Dave Wallace2a865272018-02-07 21:00:42 -05002149 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002150 return -1;
2151
2152 if (sid != INVALID_SESSION_ID)
2153 {
2154 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
2155 errno = ENOSYS;
2156 size = -1;
2157 }
2158 else
2159 {
2160 func_str = "libc_sendmmsg";
2161
Dave Wallace2a865272018-02-07 21:00:42 -05002162 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002163 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2164 "vmessages %p, vlen %u, flags 0x%x",
2165 getpid (), fd, fd, func_str, vmessages, vlen, flags);
2166
2167 size = libc_sendmmsg (fd, vmessages, vlen, flags);
2168 }
2169
Dave Wallace2a865272018-02-07 21:00:42 -05002170 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002171 {
2172 if (size < 0)
2173 {
2174 int errno_val = errno;
2175 perror (func_str);
2176 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2177 "rv %d, errno = %d", getpid (), fd, fd,
2178 func_str, size, errno_val);
2179 errno = errno_val;
2180 }
2181 else
2182 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2183 getpid (), fd, fd, size, size);
2184 }
2185 return size;
2186}
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002187#endif
2188
Dave Wallace048b1d62018-01-03 22:24:41 -05002189ssize_t
2190recvmsg (int fd, struct msghdr * message, int flags)
2191{
2192 ssize_t size;
2193 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05002194 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05002195
Dave Wallace2a865272018-02-07 21:00:42 -05002196 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002197 return -1;
2198
2199 if (sid != INVALID_SESSION_ID)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002200 {
Dave Wallace8aaba562018-01-18 17:21:19 -05002201 func_str = __func__;
2202
Dave Wallace048b1d62018-01-03 22:24:41 -05002203 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
2204 errno = ENOSYS;
2205 size = -1;
2206 }
2207 else
2208 {
2209 func_str = "libc_recvmsg";
2210
Dave Wallace2a865272018-02-07 21:00:42 -05002211 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002212 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2213 "message %p, flags 0x%x",
2214 getpid (), fd, fd, func_str, message, flags);
2215
2216 size = libc_recvmsg (fd, message, flags);
2217 }
2218
Dave Wallace2a865272018-02-07 21:00:42 -05002219 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002220 {
2221 if (size < 0)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002222 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002223 int errno_val = errno;
2224 perror (func_str);
2225 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2226 "rv %d, errno = %d", getpid (), fd, fd,
2227 func_str, size, errno_val);
2228 errno = errno_val;
2229 }
2230 else
2231 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2232 getpid (), fd, fd, size, size);
2233 }
2234 return size;
2235}
2236
2237#ifdef USE_GNU
2238int
2239recvmmsg (int fd, struct mmsghdr *vmessages,
2240 unsigned int vlen, int flags, struct timespec *tmo)
2241{
2242 ssize_t size;
2243 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05002244 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05002245
Dave Wallace2a865272018-02-07 21:00:42 -05002246 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002247 return -1;
2248
2249 if (sid != INVALID_SESSION_ID)
2250 {
2251 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
2252 errno = ENOSYS;
2253 size = -1;
2254 }
2255 else
2256 {
2257 func_str = "libc_recvmmsg";
2258
Dave Wallace2a865272018-02-07 21:00:42 -05002259 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002260 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2261 "vmessages %p, vlen %u, flags 0x%x, tmo %p",
2262 getpid (), fd, fd, func_str, vmessages, vlen,
2263 flags, tmo);
2264
2265 size = libc_recvmmsg (fd, vmessages, vlen, flags, tmo);
2266 }
2267
Dave Wallace2a865272018-02-07 21:00:42 -05002268 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002269 {
2270 if (size < 0)
2271 {
2272 int errno_val = errno;
2273 perror (func_str);
2274 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2275 "rv %d, errno = %d", getpid (), fd, fd,
2276 func_str, size, errno_val);
2277 errno = errno_val;
2278 }
2279 else
2280 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2281 getpid (), fd, fd, size, size);
2282 }
2283 return size;
2284}
2285#endif
2286
2287int
2288getsockopt (int fd, int level, int optname,
2289 void *__restrict optval, socklen_t * __restrict optlen)
2290{
2291 int rv;
2292 const char *func_str = __func__;
Dave Wallace2a865272018-02-07 21:00:42 -05002293 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace8aaba562018-01-18 17:21:19 -05002294 u32 buflen = optlen ? (u32) * optlen : 0;
Dave Wallace048b1d62018-01-03 22:24:41 -05002295
Dave Wallace2a865272018-02-07 21:00:42 -05002296 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002297 return -1;
2298
2299 if (sid != INVALID_SESSION_ID)
2300 {
2301 rv = -EOPNOTSUPP;
2302
2303 switch (level)
2304 {
2305 case SOL_TCP:
2306 switch (optname)
2307 {
2308 case TCP_NODELAY:
2309 func_str = "vppcom_session_attr[SOL_TCP,GET_TCP_NODELAY]";
Dave Wallace2a865272018-02-07 21:00:42 -05002310 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002311 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2312 "sid %u (0x%x)",
2313 getpid (), fd, fd, func_str, sid, sid);
2314 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_TCP_NODELAY,
2315 optval, optlen);
2316 break;
2317 case TCP_MAXSEG:
2318 func_str = "vppcom_session_attr[SOL_TCP,GET_TCP_USER_MSS]";
Dave Wallace2a865272018-02-07 21:00:42 -05002319 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002320 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2321 "sid %u (0x%x)",
2322 getpid (), fd, fd, func_str, sid, sid);
2323 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_TCP_USER_MSS,
2324 optval, optlen);
2325 break;
2326 case TCP_KEEPIDLE:
2327 func_str = "vppcom_session_attr[SOL_TCP,GET_TCP_KEEPIDLE]";
Dave Wallace2a865272018-02-07 21:00:42 -05002328 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002329 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2330 "sid %u (0x%x)",
2331 getpid (), fd, fd, func_str, sid, sid);
2332 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_TCP_KEEPIDLE,
2333 optval, optlen);
2334 break;
2335 case TCP_KEEPINTVL:
2336 func_str = "vppcom_session_attr[SOL_TCP,GET_TCP_KEEPINTVL]";
Dave Wallace2a865272018-02-07 21:00:42 -05002337 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002338 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2339 "sid %u (0x%x), SOL_TCP",
2340 getpid (), fd, fd, func_str, sid, sid);
2341 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_TCP_KEEPINTVL,
2342 optval, optlen);
2343 break;
2344 case TCP_INFO:
2345 if (optval && optlen && (*optlen == sizeof (struct tcp_info)))
2346 {
Dave Wallace2a865272018-02-07 21:00:42 -05002347 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002348 clib_warning ("LDP<%d>: fd %d (0x%x): sid %u (0x%x), "
2349 "SOL_TCP, TCP_INFO, optval %p, "
2350 "optlen %d: #LDP-NOP#",
2351 getpid (), fd, fd, sid, sid,
2352 optval, *optlen);
2353 memset (optval, 0, *optlen);
2354 rv = VPPCOM_OK;
2355 }
2356 else
2357 rv = -EFAULT;
2358 break;
2359 default:
Dave Wallace2a865272018-02-07 21:00:42 -05002360 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002361 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
2362 "sid %u (0x%x), SOL_TCP, "
2363 "optname %d unsupported!",
2364 getpid (), fd, fd, func_str, sid, sid, optname);
2365 break;
2366 }
2367 break;
2368 case SOL_IPV6:
2369 switch (optname)
2370 {
2371 case IPV6_V6ONLY:
2372 func_str = "vppcom_session_attr[SOL_IPV6,GET_V6ONLY]";
Dave Wallace2a865272018-02-07 21:00:42 -05002373 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002374 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2375 "sid %u (0x%x)",
2376 getpid (), fd, fd, func_str, sid, sid);
2377 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_V6ONLY,
2378 optval, optlen);
2379 break;
2380 default:
Dave Wallace2a865272018-02-07 21:00:42 -05002381 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002382 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
2383 "sid %u (0x%x), SOL_IPV6, "
2384 "optname %d unsupported!",
2385 getpid (), fd, fd, func_str, sid, sid, optname);
2386 break;
2387 }
2388 break;
2389 case SOL_SOCKET:
2390 switch (optname)
2391 {
2392 case SO_ACCEPTCONN:
2393 func_str = "vppcom_session_attr[SOL_SOCKET,GET_ACCEPTCONN]";
Dave Wallace2a865272018-02-07 21:00:42 -05002394 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002395 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2396 "sid %u (0x%x)",
2397 getpid (), fd, fd, func_str, sid, sid);
2398 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_LISTEN,
2399 optval, optlen);
2400 break;
2401 case SO_KEEPALIVE:
2402 func_str = "vppcom_session_attr[SOL_SOCKET,GET_KEEPALIVE]";
Dave Wallace2a865272018-02-07 21:00:42 -05002403 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002404 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2405 "sid %u (0x%x)",
2406 getpid (), fd, fd, func_str, sid, sid);
2407 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_KEEPALIVE,
2408 optval, optlen);
2409 break;
2410 case SO_PROTOCOL:
2411 func_str = "vppcom_session_attr[SOL_SOCKET,GET_PROTOCOL]";
Dave Wallace2a865272018-02-07 21:00:42 -05002412 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002413 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2414 "sid %u (0x%x)",
2415 getpid (), fd, fd, func_str, sid, sid);
2416 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_PROTOCOL,
2417 optval, optlen);
2418 *(int *) optval = *(int *) optval ? SOCK_DGRAM : SOCK_STREAM;
2419 break;
2420 case SO_SNDBUF:
2421 func_str = "vppcom_session_attr[SOL_SOCKET,GET_TX_FIFO_LEN]";
Dave Wallace2a865272018-02-07 21:00:42 -05002422 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002423 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2424 "sid %u (0x%x), optlen %d",
2425 getpid (), fd, fd, func_str, sid, sid, buflen);
2426 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_TX_FIFO_LEN,
2427 optval, optlen);
2428 break;
2429 case SO_RCVBUF:
2430 func_str = "vppcom_session_attr[SOL_SOCKET,GET_RX_FIFO_LEN]";
Dave Wallace2a865272018-02-07 21:00:42 -05002431 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002432 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2433 "sid %u (0x%x), optlen %d",
Dave Wallaceb4cd4ff2018-01-19 12:17:08 -05002434 getpid (), fd, fd, func_str, sid, sid, buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002435 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_RX_FIFO_LEN,
2436 optval, optlen);
2437 break;
2438 case SO_REUSEADDR:
2439 func_str = "vppcom_session_attr[SOL_SOCKET,GET_REUSEADDR]";
Dave Wallace2a865272018-02-07 21:00:42 -05002440 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002441 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2442 "sid %u (0x%x)",
2443 getpid (), fd, fd, func_str, sid, sid);
2444 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_REUSEADDR,
2445 optval, optlen);
2446 break;
2447 case SO_BROADCAST:
2448 func_str = "vppcom_session_attr[SOL_SOCKET,GET_BROADCAST]";
Dave Wallace2a865272018-02-07 21:00:42 -05002449 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002450 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2451 "sid %u (0x%x)",
2452 getpid (), fd, fd, func_str, sid, sid);
2453 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_BROADCAST,
2454 optval, optlen);
2455 break;
2456 case SO_ERROR:
2457 func_str = "vppcom_session_attr[SOL_SOCKET,GET_ERROR]";
Dave Wallace2a865272018-02-07 21:00:42 -05002458 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002459 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2460 "sid %u (0x%x)",
2461 getpid (), fd, fd, func_str, sid, sid);
2462 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_ERROR,
2463 optval, optlen);
2464 break;
2465 default:
Dave Wallace2a865272018-02-07 21:00:42 -05002466 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002467 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
2468 "sid %u (0x%x), SOL_SOCKET, "
2469 "optname %d unsupported!",
2470 getpid (), fd, fd, func_str, sid, sid, optname);
2471 break;
2472 }
2473 break;
2474 default:
2475 break;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002476 }
2477
Dave Wallace048b1d62018-01-03 22:24:41 -05002478 if (rv != VPPCOM_OK)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002479 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002480 errno = -rv;
2481 rv = -1;
2482 }
2483 }
2484 else
2485 {
2486 func_str = "libc_getsockopt";
2487
Dave Wallace2a865272018-02-07 21:00:42 -05002488 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002489 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): level %d, "
2490 "optname %d, optval %p, optlen %d",
2491 getpid (), fd, fd, func_str, level, optname,
2492 optval, optlen);
2493
2494 rv = libc_getsockopt (fd, level, optname, optval, optlen);
2495 }
2496
Dave Wallace2a865272018-02-07 21:00:42 -05002497 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002498 {
2499 if (rv < 0)
2500 {
2501 int errno_val = errno;
2502 perror (func_str);
2503 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2504 "rv %d, errno = %d", getpid (), fd, fd,
2505 func_str, rv, errno_val);
2506 errno = errno_val;
2507 }
2508 else
2509 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2510 getpid (), fd, fd, rv, rv);
2511 }
2512 return rv;
2513}
2514
2515int
2516setsockopt (int fd, int level, int optname,
2517 const void *optval, socklen_t optlen)
2518{
2519 int rv;
2520 const char *func_str = __func__;
Dave Wallace2a865272018-02-07 21:00:42 -05002521 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05002522
Dave Wallace2a865272018-02-07 21:00:42 -05002523 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002524 return -1;
2525
2526 if (sid != INVALID_SESSION_ID)
2527 {
2528 rv = -EOPNOTSUPP;
2529
2530 switch (level)
2531 {
2532 case SOL_TCP:
2533 switch (optname)
2534 {
2535 case TCP_NODELAY:
2536 func_str = "vppcom_session_attr[SOL_TCP,SET_TCP_NODELAY]";
Dave Wallace2a865272018-02-07 21:00:42 -05002537 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002538 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2539 "sid %u (0x%x)",
2540 getpid (), fd, fd, func_str, sid, sid);
2541 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_TCP_NODELAY,
2542 (void *) optval, &optlen);
2543 break;
2544 case TCP_MAXSEG:
2545 func_str = "vppcom_session_attr[SOL_TCP,SET_TCP_USER_MSS]";
Dave Wallace2a865272018-02-07 21:00:42 -05002546 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002547 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2548 "sid %u (0x%x)",
2549 getpid (), fd, fd, func_str, sid, sid);
2550 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_TCP_USER_MSS,
2551 (void *) optval, &optlen);
2552 break;
2553 case TCP_KEEPIDLE:
2554 func_str = "vppcom_session_attr[SOL_TCP,SET_TCP_KEEPIDLE]";
Dave Wallace2a865272018-02-07 21:00:42 -05002555 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002556 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2557 "sid %u (0x%x)",
2558 getpid (), fd, fd, func_str, sid, sid);
2559 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_TCP_KEEPIDLE,
2560 (void *) optval, &optlen);
2561 break;
2562 case TCP_KEEPINTVL:
2563 func_str = "vppcom_session_attr[SOL_TCP,SET_TCP_KEEPINTVL]";
Dave Wallace2a865272018-02-07 21:00:42 -05002564 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002565 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2566 "sid %u (0x%x), SOL_TCP",
2567 getpid (), fd, fd, func_str, sid, sid);
2568 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_TCP_KEEPINTVL,
2569 (void *) optval, &optlen);
2570 break;
2571 default:
Dave Wallace2a865272018-02-07 21:00:42 -05002572 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002573 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
2574 "sid %u (0x%x), SOL_TCP, "
2575 "optname %d unsupported!",
2576 getpid (), fd, fd, func_str, sid, sid, optname);
2577 break;
2578 }
2579 break;
2580 case SOL_IPV6:
2581 switch (optname)
2582 {
2583 case IPV6_V6ONLY:
2584 func_str = "vppcom_session_attr[SOL_IPV6,SET_V6ONLY]";
Dave Wallace2a865272018-02-07 21:00:42 -05002585 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002586 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2587 "sid %u (0x%x)",
2588 getpid (), fd, fd, func_str, sid, sid);
2589 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_V6ONLY,
2590 (void *) optval, &optlen);
2591 break;
2592 default:
Dave Wallace2a865272018-02-07 21:00:42 -05002593 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002594 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
2595 "sid %u (0x%x), SOL_IPV6, "
2596 "optname %d unsupported!",
2597 getpid (), fd, fd, func_str, sid, sid, optname);
2598 break;
2599 }
2600 break;
2601 case SOL_SOCKET:
2602 switch (optname)
2603 {
2604 case SO_KEEPALIVE:
2605 func_str = "vppcom_session_attr[SOL_SOCKET,SET_KEEPALIVE]";
Dave Wallace2a865272018-02-07 21:00:42 -05002606 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002607 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2608 "sid %u (0x%x)",
2609 getpid (), fd, fd, func_str, sid, sid);
2610 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_KEEPALIVE,
2611 (void *) optval, &optlen);
2612 break;
2613 case SO_REUSEADDR:
2614 func_str = "vppcom_session_attr[SOL_SOCKET,SET_REUSEADDR]";
Dave Wallace2a865272018-02-07 21:00:42 -05002615 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002616 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2617 "sid %u (0x%x)",
2618 getpid (), fd, fd, func_str, sid, sid);
2619 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_REUSEADDR,
2620 (void *) optval, &optlen);
2621 break;
2622 case SO_BROADCAST:
2623 func_str = "vppcom_session_attr[SOL_SOCKET,SET_BROADCAST]";
Dave Wallace2a865272018-02-07 21:00:42 -05002624 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002625 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2626 "sid %u (0x%x)",
2627 getpid (), fd, fd, func_str, sid, sid);
2628 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_BROADCAST,
2629 (void *) optval, &optlen);
2630 break;
2631 default:
Dave Wallace2a865272018-02-07 21:00:42 -05002632 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002633 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
2634 "sid %u (0x%x), SOL_SOCKET, "
2635 "optname %d unsupported!",
2636 getpid (), fd, fd, func_str, sid, sid, optname);
2637 break;
2638 }
2639 break;
2640 default:
2641 break;
2642 }
2643
2644 if (rv != VPPCOM_OK)
2645 {
2646 errno = -rv;
2647 rv = -1;
2648 }
2649 }
2650 else
2651 {
2652 func_str = "libc_setsockopt";
2653
Dave Wallace2a865272018-02-07 21:00:42 -05002654 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002655 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): level %d, "
2656 "optname %d, optval %p, optlen %d",
2657 getpid (), fd, fd, func_str, level, optname,
2658 optval, optlen);
2659
2660 rv = libc_setsockopt (fd, level, optname, optval, optlen);
2661 }
2662
Dave Wallace2a865272018-02-07 21:00:42 -05002663 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002664 {
2665 if (rv < 0)
2666 {
2667 int errno_val = errno;
2668 perror (func_str);
2669 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2670 "rv %d, errno = %d", getpid (), fd, fd,
2671 func_str, rv, errno_val);
2672 errno = errno_val;
2673 }
2674 else
2675 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2676 getpid (), fd, fd, rv, rv);
2677 }
2678 return rv;
2679}
2680
2681int
2682listen (int fd, int n)
2683{
2684 int rv;
Dave Wallace2a865272018-02-07 21:00:42 -05002685 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05002686
Dave Wallace2a865272018-02-07 21:00:42 -05002687 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002688 return -1;
2689
2690 if (sid != INVALID_SESSION_ID)
2691 {
Florin Coras05ecfcc2018-12-12 18:19:39 -08002692 LDBG (0, "fd %d (0x%x): calling vppcom_session_listen():"
2693 " sid %u (0x%x), n %d", fd, fd, sid, sid, n);
Dave Wallace048b1d62018-01-03 22:24:41 -05002694
2695 rv = vppcom_session_listen (sid, n);
2696 if (rv != VPPCOM_OK)
2697 {
2698 errno = -rv;
2699 rv = -1;
2700 }
2701 }
2702 else
2703 {
Florin Coras05ecfcc2018-12-12 18:19:39 -08002704 LDBG (0, "fd %d (0x%x): calling libc_listen(): n %d", fd, fd, n);
Dave Wallace048b1d62018-01-03 22:24:41 -05002705
2706 rv = libc_listen (fd, n);
2707 }
2708
Florin Coras05ecfcc2018-12-12 18:19:39 -08002709 LDBG (1, "fd %d (0x%x): returning %d (0x%x)", fd, fd, rv, rv);
Dave Wallace048b1d62018-01-03 22:24:41 -05002710 return rv;
2711}
2712
2713static inline int
Dave Wallace2a865272018-02-07 21:00:42 -05002714ldp_accept4 (int listen_fd, __SOCKADDR_ARG addr,
2715 socklen_t * __restrict addr_len, int flags)
Dave Wallace048b1d62018-01-03 22:24:41 -05002716{
2717 int rv;
Dave Wallace2a865272018-02-07 21:00:42 -05002718 u32 listen_sid = ldp_sid_from_fd (listen_fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05002719 int accept_sid;
2720
Dave Wallace2a865272018-02-07 21:00:42 -05002721 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002722 return -1;
2723
2724 if (listen_sid != INVALID_SESSION_ID)
2725 {
2726 vppcom_endpt_t ep;
2727 u8 src_addr[sizeof (struct sockaddr_in6)];
Dave Wallace8aaba562018-01-18 17:21:19 -05002728 memset (&ep, 0, sizeof (ep));
Dave Wallace048b1d62018-01-03 22:24:41 -05002729 ep.ip = src_addr;
2730
Florin Coras05ecfcc2018-12-12 18:19:39 -08002731 LDBG (0, "listen fd %d (0x%x): calling vppcom_session_accept:"
2732 " listen sid %u (0x%x), ep %p, flags 0x%x", listen_fd,
2733 listen_fd, listen_sid, listen_sid, ep, flags);
Dave Wallace048b1d62018-01-03 22:24:41 -05002734
2735 accept_sid = vppcom_session_accept (listen_sid, &ep, flags);
2736 if (accept_sid < 0)
2737 {
2738 errno = -accept_sid;
2739 rv = -1;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002740 }
2741 else
2742 {
Dave Wallace2a865272018-02-07 21:00:42 -05002743 rv = ldp_copy_ep_to_sockaddr (addr, addr_len, &ep);
Dave Wallace048b1d62018-01-03 22:24:41 -05002744 if (rv != VPPCOM_OK)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002745 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002746 (void) vppcom_session_close ((u32) accept_sid);
2747 errno = -rv;
2748 rv = -1;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002749 }
Dave Wallace048b1d62018-01-03 22:24:41 -05002750 else
2751 {
Florin Coras30e273b2018-11-27 00:04:59 -08002752 rv = ldp_fd_alloc ((u32) accept_sid);
Dave Wallace048b1d62018-01-03 22:24:41 -05002753 if (rv < 0)
2754 {
2755 (void) vppcom_session_close ((u32) accept_sid);
2756 errno = -rv;
2757 rv = -1;
2758 }
2759 }
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002760 }
2761 }
Dave Wallace048b1d62018-01-03 22:24:41 -05002762 else
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002763 {
Florin Coras05ecfcc2018-12-12 18:19:39 -08002764 LDBG (0, "listen fd %d (0x%x): calling libc_accept4(): "
2765 "addr %p, addr_len %p, flags 0x%x", listen_fd,
2766 listen_fd, addr, addr_len, flags);
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002767
Dave Wallace048b1d62018-01-03 22:24:41 -05002768 rv = libc_accept4 (listen_fd, addr, addr_len, flags);
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002769 }
2770
Florin Coras05ecfcc2018-12-12 18:19:39 -08002771 LDBG (1, "listen fd %d (0x%x): returning %d (0x%x)", listen_fd, listen_fd,
2772 rv, rv);
2773
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002774 return rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002775}
2776
Dave Wallace048b1d62018-01-03 22:24:41 -05002777int
2778accept4 (int fd, __SOCKADDR_ARG addr, socklen_t * __restrict addr_len,
2779 int flags)
2780{
Dave Wallace2a865272018-02-07 21:00:42 -05002781 return ldp_accept4 (fd, addr, addr_len, flags);
Dave Wallace048b1d62018-01-03 22:24:41 -05002782}
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002783
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002784int
Dave Wallace048b1d62018-01-03 22:24:41 -05002785accept (int fd, __SOCKADDR_ARG addr, socklen_t * __restrict addr_len)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002786{
Dave Wallace2a865272018-02-07 21:00:42 -05002787 return ldp_accept4 (fd, addr, addr_len, 0);
Dave Wallace048b1d62018-01-03 22:24:41 -05002788}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002789
Dave Wallace048b1d62018-01-03 22:24:41 -05002790int
2791shutdown (int fd, int how)
2792{
2793 int rv;
2794 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05002795 u32 sid = ldp_sid_from_fd (fd);
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002796
Dave Wallace2a865272018-02-07 21:00:42 -05002797 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002798 return -1;
2799
2800 if (sid != INVALID_SESSION_ID)
2801 {
Florin Coras6917b942018-11-13 22:44:54 -08002802 func_str = "vppcom_session_close[TODO]";
2803 rv = close (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05002804 }
2805 else
2806 {
2807 func_str = "libc_shutdown";
2808
Dave Wallace2a865272018-02-07 21:00:42 -05002809 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002810 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): how %d",
2811 getpid (), fd, fd, func_str, how);
2812
2813 rv = libc_shutdown (fd, how);
2814 }
2815
Dave Wallace2a865272018-02-07 21:00:42 -05002816 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002817 {
2818 if (rv < 0)
2819 {
2820 int errno_val = errno;
2821 perror (func_str);
2822 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2823 "rv %d, errno = %d", getpid (), fd, fd,
2824 func_str, rv, errno_val);
2825 errno = errno_val;
2826 }
2827 else
2828 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2829 getpid (), fd, fd, rv, rv);
2830 }
2831 return rv;
2832}
2833
2834int
2835epoll_create1 (int flags)
2836{
Florin Corasdfe4cf42018-11-28 22:13:45 -08002837 ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
Dave Wallace048b1d62018-01-03 22:24:41 -05002838 const char *func_str;
2839 int rv;
2840
Dave Wallace2a865272018-02-07 21:00:42 -05002841 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002842 return -1;
2843
Florin Coras99368312018-08-02 10:45:44 -07002844 if (ldp->vcl_needs_real_epoll)
2845 {
2846 rv = libc_epoll_create1 (flags);
2847 ldp->vcl_needs_real_epoll = 0;
Florin Corasdfe4cf42018-11-28 22:13:45 -08002848 ldpw->vcl_mq_epfd = rv;
Florin Coras05ecfcc2018-12-12 18:19:39 -08002849 LDBG (0, "created vcl epfd %u", rv);
Florin Coras99368312018-08-02 10:45:44 -07002850 return rv;
2851 }
Dave Wallace048b1d62018-01-03 22:24:41 -05002852 func_str = "vppcom_epoll_create";
2853
Florin Coras05ecfcc2018-12-12 18:19:39 -08002854 LDBG (1, "calling %s()", func_str);
Dave Wallace048b1d62018-01-03 22:24:41 -05002855
2856 rv = vppcom_epoll_create ();
2857
2858 if (PREDICT_FALSE (rv < 0))
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002859 {
2860 errno = -rv;
Dave Wallace048b1d62018-01-03 22:24:41 -05002861 rv = -1;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002862 }
Dave Wallace048b1d62018-01-03 22:24:41 -05002863 else
Florin Coras30e273b2018-11-27 00:04:59 -08002864 rv = ldp_fd_alloc ((u32) rv);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002865
Dave Wallace2a865272018-02-07 21:00:42 -05002866 if (LDP_DEBUG > 1)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002867 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002868 if (rv < 0)
2869 {
2870 int errno_val = errno;
2871 perror (func_str);
2872 clib_warning ("LDP<%d>: ERROR: %s() failed! "
2873 "rv %d, errno = %d",
2874 getpid (), func_str, rv, errno_val);
2875 errno = errno_val;
2876 }
2877 else
2878 clib_warning ("LDP<%d>: returning epfd %d (0x%x)", getpid (), rv, rv);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002879 }
Dave Wallace048b1d62018-01-03 22:24:41 -05002880 return rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002881}
2882
2883int
Dave Wallace048b1d62018-01-03 22:24:41 -05002884epoll_create (int size)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002885{
Dave Wallace048b1d62018-01-03 22:24:41 -05002886 return epoll_create1 (0);
2887}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002888
Dave Wallace048b1d62018-01-03 22:24:41 -05002889int
2890epoll_ctl (int epfd, int op, int fd, struct epoll_event *event)
2891{
Florin Coras99368312018-08-02 10:45:44 -07002892 u32 vep_idx = ldp_sid_from_fd (epfd), sid;
Dave Wallace048b1d62018-01-03 22:24:41 -05002893 const char *func_str;
Florin Coras99368312018-08-02 10:45:44 -07002894 int rv;
Dave Wallace048b1d62018-01-03 22:24:41 -05002895
Dave Wallace2a865272018-02-07 21:00:42 -05002896 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002897 return -1;
2898
Florin Coras99368312018-08-02 10:45:44 -07002899 if (PREDICT_FALSE (vep_idx == INVALID_SESSION_ID))
Dave Wallace048b1d62018-01-03 22:24:41 -05002900 {
Dave Wallace3ee1fe12018-02-23 01:09:11 -05002901 /* The LDP epoll_create1 always creates VCL epfd's.
2902 * The app should never have a kernel base epoll fd unless it
2903 * was acquired outside of the LD_PRELOAD process context.
2904 * In any case, if we get one, punt it to libc_epoll_ctl.
2905 */
Dave Wallace048b1d62018-01-03 22:24:41 -05002906 func_str = "libc_epoll_ctl";
2907
Florin Coras05ecfcc2018-12-12 18:19:39 -08002908 LDBG (1, "epfd %d (0x%x): calling %s(): op %d, fd %d (0x%x),"
2909 " event %p", epfd, epfd, func_str, op, fd, fd, event);
Dave Wallace048b1d62018-01-03 22:24:41 -05002910
2911 rv = libc_epoll_ctl (epfd, op, fd, event);
Florin Coras99368312018-08-02 10:45:44 -07002912 goto done;
2913 }
2914
2915 sid = ldp_sid_from_fd (fd);
2916
Florin Coras05ecfcc2018-12-12 18:19:39 -08002917 LDBG (0, "epfd %d (0x%x), vep_idx %d (0x%x), sid %d (0x%x)",
2918 epfd, epfd, vep_idx, vep_idx, sid, sid);
Florin Coras99368312018-08-02 10:45:44 -07002919
2920 if (sid != INVALID_SESSION_ID)
2921 {
2922 func_str = "vppcom_epoll_ctl";
2923
Florin Coras05ecfcc2018-12-12 18:19:39 -08002924 LDBG (1, "epfd %d (0x%x): calling %s(): vep_idx %d (0x%x),"
2925 " op %d, sid %u (0x%x), event %p", epfd, epfd,
Florin Coras99368312018-08-02 10:45:44 -07002926 func_str, vep_idx, vep_idx, sid, sid, event);
2927
2928 rv = vppcom_epoll_ctl (vep_idx, op, sid, event);
2929 if (rv != VPPCOM_OK)
2930 {
2931 errno = -rv;
2932 rv = -1;
2933 }
2934 }
2935 else
2936 {
2937 int libc_epfd;
2938 u32 size = sizeof (epfd);
2939
2940 func_str = "vppcom_session_attr[GET_LIBC_EPFD]";
2941 libc_epfd = vppcom_session_attr (vep_idx, VPPCOM_ATTR_GET_LIBC_EPFD, 0,
2942 0);
Florin Coras05ecfcc2018-12-12 18:19:39 -08002943 LDBG (1, "epfd %d (0x%x), vep_idx %d (0x%x): %s() "
2944 "returned libc_epfd %d (0x%x)", epfd, epfd,
Florin Coras99368312018-08-02 10:45:44 -07002945 vep_idx, vep_idx, func_str, libc_epfd, libc_epfd);
2946
2947 if (!libc_epfd)
2948 {
2949 func_str = "libc_epoll_create1";
2950
Florin Coras05ecfcc2018-12-12 18:19:39 -08002951 LDBG (1, "epfd %d (0x%x), vep_idx %d (0x%x): "
2952 "calling %s(): EPOLL_CLOEXEC", epfd, epfd,
Florin Coras99368312018-08-02 10:45:44 -07002953 vep_idx, vep_idx, func_str);
2954
2955 libc_epfd = libc_epoll_create1 (EPOLL_CLOEXEC);
2956 if (libc_epfd < 0)
2957 {
2958 rv = libc_epfd;
2959 goto done;
2960 }
2961
2962 func_str = "vppcom_session_attr[SET_LIBC_EPFD]";
Florin Coras05ecfcc2018-12-12 18:19:39 -08002963 LDBG (1, "epfd %d (0x%x): calling %s(): vep_idx %d (0x%x),"
Florin Coras99368312018-08-02 10:45:44 -07002964 " VPPCOM_ATTR_SET_LIBC_EPFD, libc_epfd %d (0x%x), size %d",
Florin Coras05ecfcc2018-12-12 18:19:39 -08002965 epfd, epfd, func_str, vep_idx, vep_idx, libc_epfd,
Florin Coras99368312018-08-02 10:45:44 -07002966 libc_epfd, size);
2967
2968 rv = vppcom_session_attr (vep_idx, VPPCOM_ATTR_SET_LIBC_EPFD,
2969 &libc_epfd, &size);
2970 if (rv < 0)
2971 {
2972 errno = -rv;
2973 rv = -1;
2974 goto done;
2975 }
2976 }
2977 else if (PREDICT_FALSE (libc_epfd < 0))
2978 {
2979 errno = -epfd;
2980 rv = -1;
2981 goto done;
2982 }
2983
2984 func_str = "libc_epoll_ctl";
2985
Florin Coras05ecfcc2018-12-12 18:19:39 -08002986 LDBG (1, "epfd %d (0x%x): calling %s(): libc_epfd %d (0x%x), "
2987 "op %d, fd %d (0x%x), event %p", epfd, epfd, func_str,
Florin Coras99368312018-08-02 10:45:44 -07002988 libc_epfd, libc_epfd, op, fd, fd, event);
2989
2990 rv = libc_epoll_ctl (libc_epfd, op, fd, event);
Dave Wallace048b1d62018-01-03 22:24:41 -05002991 }
2992
2993done:
Dave Wallace2a865272018-02-07 21:00:42 -05002994 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002995 {
2996 if (rv < 0)
2997 {
2998 int errno_val = errno;
2999 perror (func_str);
3000 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
3001 "rv %d, errno = %d", getpid (), fd, fd,
3002 func_str, rv, errno_val);
3003 errno = errno_val;
3004 }
3005 else
3006 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
3007 getpid (), fd, fd, rv, rv);
3008 }
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003009 return rv;
3010}
Dave Wallace048b1d62018-01-03 22:24:41 -05003011
3012static inline int
Florin Coras99368312018-08-02 10:45:44 -07003013ldp_epoll_pwait (int epfd, struct epoll_event *events, int maxevents,
3014 int timeout, const sigset_t * sigmask)
Dave Wallace048b1d62018-01-03 22:24:41 -05003015{
Florin Corasdfe4cf42018-11-28 22:13:45 -08003016 ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
Florin Coras99368312018-08-02 10:45:44 -07003017 double time_to_wait = (double) 0, time_out, now = 0;
Dave Wallace2a865272018-02-07 21:00:42 -05003018 u32 vep_idx = ldp_sid_from_fd (epfd);
Florin Coras99368312018-08-02 10:45:44 -07003019 int libc_epfd, rv = 0;
3020 const char *func_str;
Dave Wallace048b1d62018-01-03 22:24:41 -05003021
Dave Wallace2a865272018-02-07 21:00:42 -05003022 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05003023 return -1;
3024
3025 if (PREDICT_FALSE (!events || (timeout < -1)))
3026 {
3027 errno = EFAULT;
3028 return -1;
3029 }
3030
Florin Corasdfe4cf42018-11-28 22:13:45 -08003031 if (epfd == ldpw->vcl_mq_epfd)
Florin Coras99368312018-08-02 10:45:44 -07003032 return libc_epoll_pwait (epfd, events, maxevents, timeout, sigmask);
3033
Dave Wallace048b1d62018-01-03 22:24:41 -05003034 if (PREDICT_FALSE (vep_idx == INVALID_SESSION_ID))
3035 {
3036 clib_warning ("LDP<%d>: ERROR: epfd %d (0x%x): bad vep_idx %d (0x%x)!",
3037 getpid (), epfd, epfd, vep_idx, vep_idx);
3038 errno = EBADFD;
3039 return -1;
3040 }
3041
Florin Corasb0f662f2018-12-27 14:51:46 -08003042 time_to_wait = ((timeout >= 0) ? (double) timeout / 1000 : 0);
Florin Corasdfe4cf42018-11-28 22:13:45 -08003043 time_out = clib_time_now (&ldpw->clib_time) + time_to_wait;
Dave Wallace048b1d62018-01-03 22:24:41 -05003044
3045 func_str = "vppcom_session_attr[GET_LIBC_EPFD]";
3046 libc_epfd = vppcom_session_attr (vep_idx, VPPCOM_ATTR_GET_LIBC_EPFD, 0, 0);
3047 if (PREDICT_FALSE (libc_epfd < 0))
3048 {
3049 errno = -libc_epfd;
3050 rv = -1;
3051 goto done;
3052 }
3053
Florin Coras05ecfcc2018-12-12 18:19:39 -08003054 LDBG (2, "epfd %d (0x%x): vep_idx %d (0x%x), libc_epfd %d (0x%x), "
Florin Coras99368312018-08-02 10:45:44 -07003055 "events %p, maxevents %d, timeout %d, sigmask %p: time_to_wait %.02f",
Florin Coras05ecfcc2018-12-12 18:19:39 -08003056 epfd, epfd, vep_idx, vep_idx, libc_epfd, libc_epfd, events,
Florin Coras99368312018-08-02 10:45:44 -07003057 maxevents, timeout, sigmask, time_to_wait, time_out);
Dave Wallace048b1d62018-01-03 22:24:41 -05003058 do
3059 {
Florin Corasdfe4cf42018-11-28 22:13:45 -08003060 if (!ldpw->epoll_wait_vcl)
Dave Wallace048b1d62018-01-03 22:24:41 -05003061 {
3062 func_str = "vppcom_epoll_wait";
3063
Florin Coras05ecfcc2018-12-12 18:19:39 -08003064 LDBG (3, "epfd %d (0x%x): calling %s(): vep_idx %d (0x%x),"
3065 " events %p, maxevents %d", epfd, epfd, func_str,
Florin Coras99368312018-08-02 10:45:44 -07003066 vep_idx, vep_idx, events, maxevents);
Dave Wallace048b1d62018-01-03 22:24:41 -05003067
3068 rv = vppcom_epoll_wait (vep_idx, events, maxevents, 0);
3069 if (rv > 0)
3070 {
Florin Corasdfe4cf42018-11-28 22:13:45 -08003071 ldpw->epoll_wait_vcl = 1;
Dave Wallace048b1d62018-01-03 22:24:41 -05003072 goto done;
3073 }
3074 else if (rv < 0)
3075 {
3076 errno = -rv;
3077 rv = -1;
3078 goto done;
3079 }
3080 }
3081 else
Florin Corasdfe4cf42018-11-28 22:13:45 -08003082 ldpw->epoll_wait_vcl = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -05003083
3084 if (libc_epfd > 0)
3085 {
3086 func_str = "libc_epoll_pwait";
3087
Florin Coras05ecfcc2018-12-12 18:19:39 -08003088 LDBG (3, "epfd %d (0x%x): calling %s(): libc_epfd %d "
3089 "(0x%x), events %p, maxevents %d, sigmask %p",
Florin Coras99368312018-08-02 10:45:44 -07003090 epfd, epfd, func_str, libc_epfd, libc_epfd, events,
3091 maxevents, sigmask);
Dave Wallace048b1d62018-01-03 22:24:41 -05003092
Florin Corasb0f662f2018-12-27 14:51:46 -08003093 rv = libc_epoll_pwait (libc_epfd, events, maxevents, 0, sigmask);
Dave Wallace048b1d62018-01-03 22:24:41 -05003094 if (rv != 0)
3095 goto done;
3096 }
3097
3098 if (timeout != -1)
Florin Corasdfe4cf42018-11-28 22:13:45 -08003099 now = clib_time_now (&ldpw->clib_time);
Dave Wallace048b1d62018-01-03 22:24:41 -05003100 }
3101 while (now < time_out);
3102
3103done:
Dave Wallace2a865272018-02-07 21:00:42 -05003104 if (LDP_DEBUG > 3)
Dave Wallace048b1d62018-01-03 22:24:41 -05003105 {
Keith Burns (alagalah)5368efa2018-02-07 13:20:28 -08003106 if (libc_epfd > 0)
3107 epfd = libc_epfd;
Dave Wallace048b1d62018-01-03 22:24:41 -05003108 if (rv < 0)
3109 {
3110 int errno_val = errno;
3111 perror (func_str);
3112 clib_warning ("LDP<%d>: ERROR: epfd %d (0x%x): %s() failed! "
3113 "rv %d, errno = %d", getpid (), epfd, epfd,
3114 func_str, rv, errno_val);
3115 errno = errno_val;
3116 }
3117 else
3118 clib_warning ("LDP<%d>: epfd %d (0x%x): returning %d (0x%x)",
3119 getpid (), epfd, epfd, rv, rv);
3120 }
3121 return rv;
3122}
3123
3124int
3125epoll_pwait (int epfd, struct epoll_event *events,
3126 int maxevents, int timeout, const sigset_t * sigmask)
3127{
Dave Wallace2a865272018-02-07 21:00:42 -05003128 return ldp_epoll_pwait (epfd, events, maxevents, timeout, sigmask);
Dave Wallace048b1d62018-01-03 22:24:41 -05003129}
3130
3131int
3132epoll_wait (int epfd, struct epoll_event *events, int maxevents, int timeout)
3133{
Dave Wallace2a865272018-02-07 21:00:42 -05003134 return ldp_epoll_pwait (epfd, events, maxevents, timeout, NULL);
Dave Wallace048b1d62018-01-03 22:24:41 -05003135}
3136
3137int
3138poll (struct pollfd *fds, nfds_t nfds, int timeout)
3139{
Florin Corasdfe4cf42018-11-28 22:13:45 -08003140 ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
Dave Wallace048b1d62018-01-03 22:24:41 -05003141 const char *func_str = __func__;
Florin Coras6917b942018-11-13 22:44:54 -08003142 int rv, i, n_revents = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -05003143 u32 sid;
3144 vcl_poll_t *vp;
3145 double wait_for_time;
3146
Florin Coras05ecfcc2018-12-12 18:19:39 -08003147 LDBG (3, "fds %p, nfds %d, timeout %d", fds, nfds, timeout);
Dave Wallace048b1d62018-01-03 22:24:41 -05003148
3149 if (timeout >= 0)
3150 wait_for_time = (f64) timeout / 1000;
3151 else
3152 wait_for_time = -1;
3153
Dave Wallace048b1d62018-01-03 22:24:41 -05003154 for (i = 0; i < nfds; i++)
3155 {
Florin Coras6917b942018-11-13 22:44:54 -08003156 if (fds[i].fd < 0)
3157 continue;
Dave Wallace048b1d62018-01-03 22:24:41 -05003158
Florin Coras05ecfcc2018-12-12 18:19:39 -08003159 LDBG (3, "fds[%d] fd %d (0x%0x) events = 0x%x revents = 0x%x",
3160 i, fds[i].fd, fds[i].fd, fds[i].events, fds[i].revents);
Florin Coras6917b942018-11-13 22:44:54 -08003161
3162 sid = ldp_sid_from_fd (fds[i].fd);
3163 if (sid != INVALID_SESSION_ID)
3164 {
3165 fds[i].fd = -fds[i].fd;
Florin Corasdfe4cf42018-11-28 22:13:45 -08003166 vec_add2 (ldpw->vcl_poll, vp, 1);
Florin Coras6917b942018-11-13 22:44:54 -08003167 vp->fds_ndx = i;
3168 vp->sid = sid;
3169 vp->events = fds[i].events;
Dave Wallace048b1d62018-01-03 22:24:41 -05003170#ifdef __USE_XOPEN2K
Florin Coras6917b942018-11-13 22:44:54 -08003171 if (fds[i].events & POLLRDNORM)
3172 vp->events |= POLLIN;
3173 if (fds[i].events & POLLWRNORM)
3174 vp->events |= POLLOUT;
Dave Wallace048b1d62018-01-03 22:24:41 -05003175#endif
Florin Coras6917b942018-11-13 22:44:54 -08003176 vp->revents = fds[i].revents;
3177 }
3178 else
3179 {
Florin Corasdfe4cf42018-11-28 22:13:45 -08003180 vec_add1 (ldpw->libc_poll, fds[i]);
3181 vec_add1 (ldpw->libc_poll_idxs, i);
Dave Wallace048b1d62018-01-03 22:24:41 -05003182 }
3183 }
3184
Dave Wallace048b1d62018-01-03 22:24:41 -05003185 do
3186 {
Florin Corasdfe4cf42018-11-28 22:13:45 -08003187 if (vec_len (ldpw->vcl_poll))
Dave Wallace048b1d62018-01-03 22:24:41 -05003188 {
3189 func_str = "vppcom_poll";
3190
Florin Coras05ecfcc2018-12-12 18:19:39 -08003191 LDBG (3, "calling %s(): vcl_poll %p, n_sids %u (0x%x): "
3192 "n_libc_fds %u", func_str, ldpw->vcl_poll,
Florin Corasdfe4cf42018-11-28 22:13:45 -08003193 vec_len (ldpw->vcl_poll), vec_len (ldpw->vcl_poll),
3194 vec_len (ldpw->libc_poll));
Dave Wallace048b1d62018-01-03 22:24:41 -05003195
Florin Corasdfe4cf42018-11-28 22:13:45 -08003196 rv = vppcom_poll (ldpw->vcl_poll, vec_len (ldpw->vcl_poll), 0);
Dave Wallace048b1d62018-01-03 22:24:41 -05003197 if (rv < 0)
3198 {
3199 errno = -rv;
3200 rv = -1;
3201 goto done;
3202 }
3203 else
3204 n_revents += rv;
3205 }
3206
Florin Corasdfe4cf42018-11-28 22:13:45 -08003207 if (vec_len (ldpw->libc_poll))
Dave Wallace048b1d62018-01-03 22:24:41 -05003208 {
3209 func_str = "libc_poll";
3210
Florin Coras05ecfcc2018-12-12 18:19:39 -08003211 LDBG (3, "calling %s(): fds %p, nfds %u: n_sids %u",
3212 fds, nfds, vec_len (ldpw->vcl_poll));
Dave Wallace048b1d62018-01-03 22:24:41 -05003213
Florin Corasdfe4cf42018-11-28 22:13:45 -08003214 rv = libc_poll (ldpw->libc_poll, vec_len (ldpw->libc_poll), 0);
Dave Wallace048b1d62018-01-03 22:24:41 -05003215 if (rv < 0)
3216 goto done;
3217 else
3218 n_revents += rv;
3219 }
3220
3221 if (n_revents)
3222 {
3223 rv = n_revents;
3224 goto done;
3225 }
3226 }
3227 while ((wait_for_time == -1) ||
Florin Corasdfe4cf42018-11-28 22:13:45 -08003228 (clib_time_now (&ldpw->clib_time) < wait_for_time));
Dave Wallace048b1d62018-01-03 22:24:41 -05003229 rv = 0;
3230
3231done:
Florin Corasdfe4cf42018-11-28 22:13:45 -08003232 vec_foreach (vp, ldpw->vcl_poll)
Dave Wallace048b1d62018-01-03 22:24:41 -05003233 {
3234 fds[vp->fds_ndx].fd = -fds[vp->fds_ndx].fd;
Florin Coras6917b942018-11-13 22:44:54 -08003235 fds[vp->fds_ndx].revents = vp->revents;
Dave Wallace048b1d62018-01-03 22:24:41 -05003236#ifdef __USE_XOPEN2K
3237 if ((fds[vp->fds_ndx].revents & POLLIN) &&
3238 (fds[vp->fds_ndx].events & POLLRDNORM))
3239 fds[vp->fds_ndx].revents |= POLLRDNORM;
3240 if ((fds[vp->fds_ndx].revents & POLLOUT) &&
3241 (fds[vp->fds_ndx].events & POLLWRNORM))
3242 fds[vp->fds_ndx].revents |= POLLWRNORM;
3243#endif
3244 }
Florin Corasdfe4cf42018-11-28 22:13:45 -08003245 vec_reset_length (ldpw->vcl_poll);
Dave Wallace048b1d62018-01-03 22:24:41 -05003246
Florin Corasdfe4cf42018-11-28 22:13:45 -08003247 for (i = 0; i < vec_len (ldpw->libc_poll); i++)
Florin Coras6917b942018-11-13 22:44:54 -08003248 {
Florin Corasdfe4cf42018-11-28 22:13:45 -08003249 fds[ldpw->libc_poll_idxs[i]].revents = ldpw->libc_poll[i].revents;
Florin Coras6917b942018-11-13 22:44:54 -08003250 }
Florin Corasdfe4cf42018-11-28 22:13:45 -08003251 vec_reset_length (ldpw->libc_poll_idxs);
3252 vec_reset_length (ldpw->libc_poll);
Florin Coras6917b942018-11-13 22:44:54 -08003253
Dave Wallace2a865272018-02-07 21:00:42 -05003254 if (LDP_DEBUG > 3)
Dave Wallace048b1d62018-01-03 22:24:41 -05003255 {
3256 if (rv < 0)
3257 {
3258 int errno_val = errno;
3259 perror (func_str);
3260 clib_warning ("LDP<%d>: ERROR: %s() failed! "
3261 "rv %d, errno = %d", getpid (),
3262 func_str, rv, errno_val);
3263 errno = errno_val;
3264 }
3265 else
3266 {
3267 clib_warning ("LDP<%d>: returning %d (0x%x): n_sids %u, "
3268 "n_libc_fds %d", getpid (), rv, rv,
Florin Corasdfe4cf42018-11-28 22:13:45 -08003269 vec_len (ldpw->vcl_poll), vec_len (ldpw->libc_poll));
Dave Wallace048b1d62018-01-03 22:24:41 -05003270
3271 for (i = 0; i < nfds; i++)
3272 {
3273 if (fds[i].fd >= 0)
3274 {
Dave Wallace2a865272018-02-07 21:00:42 -05003275 if (LDP_DEBUG > 3)
Dave Wallace048b1d62018-01-03 22:24:41 -05003276 clib_warning ("LDP<%d>: fds[%d].fd %d (0x%0x), "
3277 ".events = 0x%x, .revents = 0x%x",
3278 getpid (), i, fds[i].fd, fds[i].fd,
3279 fds[i].events, fds[i].revents);
3280 }
3281 }
3282 }
3283 }
3284
3285 return rv;
3286}
3287
3288#ifdef USE_GNU
3289int
3290ppoll (struct pollfd *fds, nfds_t nfds,
3291 const struct timespec *timeout, const sigset_t * sigmask)
3292{
Dave Wallace2a865272018-02-07 21:00:42 -05003293 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05003294 return -1;
3295
3296 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
3297 errno = ENOSYS;
3298
3299
3300 return -1;
3301}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003302#endif
3303
Dave Wallace2a865272018-02-07 21:00:42 -05003304void CONSTRUCTOR_ATTRIBUTE ldp_constructor (void);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003305
Dave Wallace2a865272018-02-07 21:00:42 -05003306void DESTRUCTOR_ATTRIBUTE ldp_destructor (void);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003307
Dave Wallace048b1d62018-01-03 22:24:41 -05003308/*
3309 * This function is called when the library is loaded
3310 */
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003311void
Dave Wallace2a865272018-02-07 21:00:42 -05003312ldp_constructor (void)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003313{
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003314 swrap_constructor ();
Dave Wallace2a865272018-02-07 21:00:42 -05003315 if (ldp_init () != 0)
3316 fprintf (stderr, "\nLDP<%d>: ERROR: ldp_constructor: failed!\n",
Dave Wallace048b1d62018-01-03 22:24:41 -05003317 getpid ());
Dave Wallace69d01192018-02-22 16:22:09 -05003318 else if (LDP_DEBUG > 0)
Dave Wallace2a865272018-02-07 21:00:42 -05003319 clib_warning ("LDP<%d>: LDP constructor: done!\n", getpid ());
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003320}
3321
3322/*
3323 * This function is called when the library is unloaded
3324 */
3325void
Dave Wallace2a865272018-02-07 21:00:42 -05003326ldp_destructor (void)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003327{
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003328 swrap_destructor ();
Dave Wallace2a865272018-02-07 21:00:42 -05003329 if (ldp->init)
Florin Coras940f78f2018-11-30 12:11:20 -08003330 ldp->init = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -05003331
3332 /* Don't use clib_warning() here because that calls writev()
Dave Wallace2a865272018-02-07 21:00:42 -05003333 * which will call ldp_init().
Dave Wallace048b1d62018-01-03 22:24:41 -05003334 */
Dave Wallace69d01192018-02-22 16:22:09 -05003335 if (LDP_DEBUG > 0)
3336 printf ("%s:%d: LDP<%d>: LDP destructor: done!\n",
3337 __func__, __LINE__, getpid ());
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003338}
3339
3340
3341/*
3342 * fd.io coding-style-patch-verification: ON
3343 *
3344 * Local Variables:
3345 * eval: (c-set-style "gnu")
3346 * End:
3347 */