blob: b7b6b3c26b1c6961c31259308732347697676b71 [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>
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -070032
33#define HAVE_CONSTRUCTOR_ATTRIBUTE
34#ifdef HAVE_CONSTRUCTOR_ATTRIBUTE
35#define CONSTRUCTOR_ATTRIBUTE \
36 __attribute__ ((constructor))
37#else
38#define CONSTRUCTOR_ATTRIBUTE
39#endif /* HAVE_CONSTRUCTOR_ATTRIBUTE */
40
41#define HAVE_DESTRUCTOR_ATTRIBUTE
42#ifdef HAVE_DESTRUCTOR_ATTRIBUTE
43#define DESTRUCTOR_ATTRIBUTE \
44 __attribute__ ((destructor))
45#else
46#define DESTRUCTOR_ATTRIBUTE
47#endif
48
Dave Wallace048b1d62018-01-03 22:24:41 -050049typedef struct
50{
51 int init;
Dave Wallace2a865272018-02-07 21:00:42 -050052 char app_name[LDP_APP_NAME_MAX];
Dave Wallace048b1d62018-01-03 22:24:41 -050053 u32 sid_bit_val;
54 u32 sid_bit_mask;
55 u32 debug;
56 u8 *io_buffer;
57 clib_time_t clib_time;
58 clib_bitmap_t *rd_bitmap;
59 clib_bitmap_t *wr_bitmap;
60 clib_bitmap_t *ex_bitmap;
61 clib_bitmap_t *sid_rd_bitmap;
62 clib_bitmap_t *sid_wr_bitmap;
63 clib_bitmap_t *sid_ex_bitmap;
64 clib_bitmap_t *libc_rd_bitmap;
65 clib_bitmap_t *libc_wr_bitmap;
66 clib_bitmap_t *libc_ex_bitmap;
67 vcl_poll_t *vcl_poll;
68 u8 select_vcl;
69 u8 epoll_wait_vcl;
Florin Coras99368312018-08-02 10:45:44 -070070 u8 vcl_needs_real_epoll; /*< vcl needs next epoll_create to
71 go to libc_epoll */
72 int vcl_mq_epfd;
73
Dave Wallace2a865272018-02-07 21:00:42 -050074} ldp_main_t;
75#define LDP_DEBUG ldp->debug
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -070076
Florin Coras99368312018-08-02 10:45:44 -070077#define LDBG(_lvl, _fmt, _args...) \
78 if (ldp->debug > _lvl) \
79 clib_warning (_fmt, ##_args)
80
Dave Wallace2a865272018-02-07 21:00:42 -050081static ldp_main_t ldp_main = {
82 .sid_bit_val = (1 << LDP_SID_BIT_MIN),
83 .sid_bit_mask = (1 << LDP_SID_BIT_MIN) - 1,
84 .debug = LDP_DEBUG_INIT,
Dave Wallace048b1d62018-01-03 22:24:41 -050085};
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -070086
Dave Wallace2a865272018-02-07 21:00:42 -050087static ldp_main_t *ldp = &ldp_main;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -070088
89/*
90 * RETURN: 0 on success or -1 on error.
91 * */
Dave Wallace048b1d62018-01-03 22:24:41 -050092static inline void
Dave Wallace2a865272018-02-07 21:00:42 -050093ldp_set_app_name (char *app_name)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -070094{
Dave Wallace2a865272018-02-07 21:00:42 -050095 int rv = snprintf (ldp->app_name, LDP_APP_NAME_MAX,
96 "ldp-%d-%s", getpid (), app_name);
Dave Wallace048b1d62018-01-03 22:24:41 -050097
Dave Wallace2a865272018-02-07 21:00:42 -050098 if (rv >= LDP_APP_NAME_MAX)
99 app_name[LDP_APP_NAME_MAX - 1] = 0;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700100}
101
Dave Wallace048b1d62018-01-03 22:24:41 -0500102static inline char *
Dave Wallace2a865272018-02-07 21:00:42 -0500103ldp_get_app_name ()
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700104{
Dave Wallace2a865272018-02-07 21:00:42 -0500105 if (ldp->app_name[0] == '\0')
106 ldp_set_app_name ("app");
Dave Wallace048b1d62018-01-03 22:24:41 -0500107
Dave Wallace2a865272018-02-07 21:00:42 -0500108 return ldp->app_name;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700109}
110
Dave Wallace048b1d62018-01-03 22:24:41 -0500111static inline int
Dave Wallace2a865272018-02-07 21:00:42 -0500112ldp_fd_from_sid (u32 sid)
Dave Wallace048b1d62018-01-03 22:24:41 -0500113{
Dave Wallace2a865272018-02-07 21:00:42 -0500114 if (PREDICT_FALSE (sid >= ldp->sid_bit_val))
Dave Wallace048b1d62018-01-03 22:24:41 -0500115 return -EMFILE;
116 else
Dave Wallace2a865272018-02-07 21:00:42 -0500117 return (sid | ldp->sid_bit_val);
Dave Wallace048b1d62018-01-03 22:24:41 -0500118}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700119
Dave Wallace048b1d62018-01-03 22:24:41 -0500120static inline int
Dave Wallace2a865272018-02-07 21:00:42 -0500121ldp_fd_is_sid (int fd)
Dave Wallace048b1d62018-01-03 22:24:41 -0500122{
Dave Wallace2a865272018-02-07 21:00:42 -0500123 return ((u32) fd & ldp->sid_bit_val) ? 1 : 0;
Dave Wallace048b1d62018-01-03 22:24:41 -0500124}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700125
Dave Wallace048b1d62018-01-03 22:24:41 -0500126static inline u32
Dave Wallace2a865272018-02-07 21:00:42 -0500127ldp_sid_from_fd (int fd)
Dave Wallace048b1d62018-01-03 22:24:41 -0500128{
Dave Wallace2a865272018-02-07 21:00:42 -0500129 return (ldp_fd_is_sid (fd) ? ((u32) fd & ldp->sid_bit_mask) :
Dave Wallace048b1d62018-01-03 22:24:41 -0500130 INVALID_SESSION_ID);
131}
132
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700133static inline int
Dave Wallace2a865272018-02-07 21:00:42 -0500134ldp_init (void)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700135{
Florin Coras99368312018-08-02 10:45:44 -0700136 int rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700137
Florin Coras99368312018-08-02 10:45:44 -0700138 if (PREDICT_TRUE (ldp->init))
139 return 0;
140
141 ldp->init = 1;
142 ldp->vcl_needs_real_epoll = 1;
143 rv = vppcom_app_create (ldp_get_app_name ());
144 if (rv != VPPCOM_OK)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700145 {
Florin Coras99368312018-08-02 10:45:44 -0700146 fprintf (stderr, "\nLDP<%d>: ERROR: ldp_init: vppcom_app_create()"
147 " failed! rv = %d (%s)\n",
148 getpid (), rv, vppcom_retval_str (rv));
149 ldp->init = 0;
150 return rv;
151 }
152 ldp->vcl_needs_real_epoll = 0;
153
154 char *env_var_str = getenv (LDP_ENV_DEBUG);
155 if (env_var_str)
156 {
157 u32 tmp;
158 if (sscanf (env_var_str, "%u", &tmp) != 1)
159 clib_warning ("LDP<%d>: WARNING: Invalid LDP debug level specified in"
160 " the env var " LDP_ENV_DEBUG " (%s)!", getpid (),
161 env_var_str);
162 else
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700163 {
Florin Coras99368312018-08-02 10:45:44 -0700164 ldp->debug = tmp;
165 LDBG (0, "LDP<%d>: configured LDP debug level (%u) from env var "
166 LDP_ENV_DEBUG "!", getpid (), ldp->debug);
167 }
168 }
Dave Wallace048b1d62018-01-03 22:24:41 -0500169
Florin Coras99368312018-08-02 10:45:44 -0700170 env_var_str = getenv (LDP_ENV_APP_NAME);
171 if (env_var_str)
172 {
173 ldp_set_app_name (env_var_str);
174 LDBG (0, "LDP<%d>: configured LDP app name (%s) from the env var "
175 LDP_ENV_APP_NAME "!", getpid (), ldp->app_name);
176 }
Dave Wallace048b1d62018-01-03 22:24:41 -0500177
Florin Coras99368312018-08-02 10:45:44 -0700178 env_var_str = getenv (LDP_ENV_SID_BIT);
179 if (env_var_str)
180 {
181 u32 sb;
182 if (sscanf (env_var_str, "%u", &sb) != 1)
183 {
184 clib_warning ("LDP<%d>: WARNING: Invalid LDP sid bit specified in"
185 " the env var " LDP_ENV_SID_BIT " (%s)! sid bit "
186 "value %d (0x%x)", getpid (), env_var_str,
187 ldp->sid_bit_val, ldp->sid_bit_val);
188 }
189 else if (sb < LDP_SID_BIT_MIN)
190 {
191 ldp->sid_bit_val = (1 << LDP_SID_BIT_MIN);
192 ldp->sid_bit_mask = ldp->sid_bit_val - 1;
Dave Wallace048b1d62018-01-03 22:24:41 -0500193
Florin Coras99368312018-08-02 10:45:44 -0700194 clib_warning ("LDP<%d>: WARNING: LDP sid bit (%u) specified in the"
195 " env var " LDP_ENV_SID_BIT " (%s) is too small. "
196 "Using LDP_SID_BIT_MIN (%d)! sid bit value %d (0x%x)",
197 getpid (), sb, env_var_str, LDP_SID_BIT_MIN,
198 ldp->sid_bit_val, ldp->sid_bit_val);
199 }
200 else if (sb > LDP_SID_BIT_MAX)
201 {
202 ldp->sid_bit_val = (1 << LDP_SID_BIT_MAX);
203 ldp->sid_bit_mask = ldp->sid_bit_val - 1;
Dave Wallace048b1d62018-01-03 22:24:41 -0500204
Florin Coras99368312018-08-02 10:45:44 -0700205 clib_warning ("LDP<%d>: WARNING: LDP sid bit (%u) specified in the"
206 " env var " LDP_ENV_SID_BIT " (%s) is too big. Using"
207 " LDP_SID_BIT_MAX (%d)! sid bit value %d (0x%x)",
208 getpid (), sb, env_var_str, LDP_SID_BIT_MAX,
209 ldp->sid_bit_val, ldp->sid_bit_val);
Dave Wallace048b1d62018-01-03 22:24:41 -0500210 }
211 else
212 {
Florin Coras99368312018-08-02 10:45:44 -0700213 ldp->sid_bit_val = (1 << sb);
214 ldp->sid_bit_mask = ldp->sid_bit_val - 1;
215
216 LDBG (0, "LDP<%d>: configured LDP sid bit (%u) from "
217 LDP_ENV_SID_BIT "! sid bit value %d (0x%x)", getpid (), sb,
218 ldp->sid_bit_val, ldp->sid_bit_val);
Dave Wallace048b1d62018-01-03 22:24:41 -0500219 }
220 }
Florin Coras99368312018-08-02 10:45:44 -0700221
222 clib_time_init (&ldp->clib_time);
223 LDBG (0, "LDP<%d>: LDP initialization: done!", getpid ());
224
225 return 0;
Dave Wallace048b1d62018-01-03 22:24:41 -0500226}
227
228int
229close (int fd)
230{
231 int rv;
232 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -0500233 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -0500234
Dave Wallace2a865272018-02-07 21:00:42 -0500235 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500236 return -1;
237
238 if (sid != INVALID_SESSION_ID)
239 {
240 int epfd;
241
242 func_str = "vppcom_session_attr[GET_LIBC_EPFD]";
243 epfd = vppcom_session_attr (sid, VPPCOM_ATTR_GET_LIBC_EPFD, 0, 0);
244 if (epfd > 0)
245 {
246 func_str = "libc_close";
247
Dave Wallace2a865272018-02-07 21:00:42 -0500248 if (LDP_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -0500249 clib_warning
250 ("LDP<%d>: fd %d (0x%x): calling %s(): epfd %u (0x%x)",
251 getpid (), fd, fd, func_str, epfd, epfd);
252
253 rv = libc_close (epfd);
254 if (rv < 0)
255 {
256 u32 size = sizeof (epfd);
257 epfd = 0;
258
259 (void) vppcom_session_attr (sid, VPPCOM_ATTR_SET_LIBC_EPFD,
260 &epfd, &size);
261 }
262 }
263 else if (PREDICT_FALSE (epfd < 0))
264 {
265 errno = -epfd;
266 rv = -1;
267 goto done;
268 }
269
270 func_str = "vppcom_session_close";
271
Dave Wallace2a865272018-02-07 21:00:42 -0500272 if (LDP_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -0500273 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x)",
274 getpid (), fd, fd, func_str, sid, sid);
275
276 rv = vppcom_session_close (sid);
277 if (rv != VPPCOM_OK)
278 {
279 errno = -rv;
280 rv = -1;
281 }
282 }
283 else
284 {
285 func_str = "libc_close";
286
Dave Wallace2a865272018-02-07 21:00:42 -0500287 if (LDP_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -0500288 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s()",
289 getpid (), fd, fd, func_str);
290
291 rv = libc_close (fd);
292 }
293
294done:
Dave Wallace2a865272018-02-07 21:00:42 -0500295 if (LDP_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -0500296 {
297 if (rv < 0)
298 {
299 int errno_val = errno;
300 perror (func_str);
301 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
302 "rv %d, errno = %d", getpid (), fd, fd,
303 func_str, rv, errno_val);
304 errno = errno_val;
305 }
306 else
307 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
308 getpid (), fd, fd, rv, rv);
309 }
310 return rv;
311}
312
313ssize_t
314read (int fd, void *buf, size_t nbytes)
315{
316 ssize_t size;
317 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -0500318 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -0500319
Dave Wallace2a865272018-02-07 21:00:42 -0500320 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500321 return -1;
322
323 if (sid != INVALID_SESSION_ID)
324 {
325 func_str = "vppcom_session_read";
326
Dave Wallace2a865272018-02-07 21:00:42 -0500327 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -0500328 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
329 "sid %u (0x%x), buf %p, nbytes %u", getpid (),
330 fd, fd, func_str, sid, sid, buf, nbytes);
331
332 size = vppcom_session_read (sid, buf, nbytes);
333 if (size < 0)
334 {
335 errno = -size;
336 size = -1;
337 }
338 }
339 else
340 {
341 func_str = "libc_read";
342
Dave Wallace2a865272018-02-07 21:00:42 -0500343 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -0500344 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
345 "buf %p, nbytes %u", getpid (),
346 fd, fd, func_str, buf, nbytes);
347
348 size = libc_read (fd, buf, nbytes);
349 }
350
Dave Wallace2a865272018-02-07 21:00:42 -0500351 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -0500352 {
353 if (size < 0)
354 {
355 int errno_val = errno;
356 perror (func_str);
357 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
358 "rv %d, errno = %d", getpid (), fd, fd,
359 func_str, size, errno_val);
360 errno = errno_val;
361 }
362 else
363 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
364 getpid (), fd, fd, size, size);
365 }
366 return size;
367}
368
369ssize_t
370readv (int fd, const struct iovec * iov, int iovcnt)
371{
372 const char *func_str;
373 ssize_t size = 0;
Dave Wallace2a865272018-02-07 21:00:42 -0500374 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace8aaba562018-01-18 17:21:19 -0500375 int rv = 0, i, total = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -0500376
Dave Wallace2a865272018-02-07 21:00:42 -0500377 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500378 return -1;
379
380 if (sid != INVALID_SESSION_ID)
381 {
382 func_str = "vppcom_session_read";
383 do
384 {
385 for (i = 0; i < iovcnt; ++i)
386 {
Dave Wallace2a865272018-02-07 21:00:42 -0500387 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -0500388 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s() [%d]: "
389 "sid %u (0x%x), iov %p, iovcnt %d, total %d",
390 getpid (), fd, fd, func_str, i, sid, sid,
391 iov, iovcnt, total);
392
393 rv = vppcom_session_read (sid, iov[i].iov_base, iov[i].iov_len);
394 if (rv < 0)
395 break;
396 else
397 {
398 total += rv;
399 if (rv < iov[i].iov_len)
400 {
Dave Wallace2a865272018-02-07 21:00:42 -0500401 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -0500402 clib_warning ("LDP<%d>: fd %d (0x%x): "
403 "rv (%d) < iov[%d].iov_len (%d)",
404 getpid (), fd, fd, rv, i,
405 iov[i].iov_len);
406 break;
407 }
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700408 }
409 }
410 }
Dave Wallace048b1d62018-01-03 22:24:41 -0500411 while ((rv >= 0) && (total == 0));
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700412
Dave Wallace048b1d62018-01-03 22:24:41 -0500413 if (rv < 0)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700414 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500415 errno = -rv;
416 size = -1;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700417 }
Dave Wallace048b1d62018-01-03 22:24:41 -0500418 else
419 size = total;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700420 }
421 else
422 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500423 func_str = "libc_readv";
424
Dave Wallace2a865272018-02-07 21:00:42 -0500425 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -0500426 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
427 "iov %p, iovcnt %d", getpid (), fd, fd, iov, iovcnt);
428
429 size = libc_readv (fd, iov, iovcnt);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700430 }
431
Dave Wallace2a865272018-02-07 21:00:42 -0500432 if (LDP_DEBUG > 2)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700433 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500434 if (size < 0)
435 {
436 int errno_val = errno;
437 perror (func_str);
438 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
439 "rv %d, errno = %d", getpid (), fd, fd,
440 func_str, size, errno_val);
441 errno = errno_val;
442 }
443 else
444 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
445 getpid (), fd, fd, size, size);
446 }
447 return size;
448}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700449
Dave Wallace048b1d62018-01-03 22:24:41 -0500450ssize_t
451write (int fd, const void *buf, size_t nbytes)
452{
453 const char *func_str;
454 ssize_t size = 0;
Dave Wallace2a865272018-02-07 21:00:42 -0500455 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -0500456
Dave Wallace2a865272018-02-07 21:00:42 -0500457 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500458 return -1;
459
460 if (sid != INVALID_SESSION_ID)
461 {
462 func_str = "vppcom_session_write";
463
Dave Wallace2a865272018-02-07 21:00:42 -0500464 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -0500465 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
466 "sid %u (0x%x), buf %p, nbytes %u", getpid (),
467 fd, fd, func_str, sid, sid, buf, nbytes);
468
469 size = vppcom_session_write (sid, (void *) buf, nbytes);
470 if (size < 0)
471 {
472 errno = -size;
473 size = -1;
474 }
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700475 }
476 else
477 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500478 func_str = "libc_write";
479
Dave Wallace2a865272018-02-07 21:00:42 -0500480 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -0500481 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
482 "buf %p, nbytes %u", getpid (),
483 fd, fd, func_str, buf, nbytes);
484
485 size = libc_write (fd, buf, nbytes);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700486 }
487
Dave Wallace2a865272018-02-07 21:00:42 -0500488 if (LDP_DEBUG > 2)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700489 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500490 if (size < 0)
491 {
492 int errno_val = errno;
493 perror (func_str);
494 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
495 "rv %d, errno = %d", getpid (), fd, fd,
496 func_str, size, errno_val);
497 errno = errno_val;
498 }
499 else
500 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
501 getpid (), fd, fd, size, size);
502 }
503 return size;
504}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700505
Dave Wallace048b1d62018-01-03 22:24:41 -0500506ssize_t
507writev (int fd, const struct iovec * iov, int iovcnt)
508{
509 const char *func_str;
510 ssize_t size = 0, total = 0;
Dave Wallace2a865272018-02-07 21:00:42 -0500511 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace8aaba562018-01-18 17:21:19 -0500512 int i, rv = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -0500513
514 /*
515 * Use [f]printf() instead of clib_warning() to prevent recursion SIGSEGV.
516 */
517
Dave Wallace2a865272018-02-07 21:00:42 -0500518 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500519 return -1;
520
521 if (sid != INVALID_SESSION_ID)
522 {
523 func_str = "vppcom_session_write";
524 do
525 {
526 for (i = 0; i < iovcnt; ++i)
527 {
Dave Wallace2a865272018-02-07 21:00:42 -0500528 if (LDP_DEBUG > 4)
Dave Wallace048b1d62018-01-03 22:24:41 -0500529 printf ("%s:%d: LDP<%d>: fd %d (0x%x): calling %s() [%d]: "
530 "sid %u (0x%x), buf %p, nbytes %ld, total %ld",
531 __func__, __LINE__, getpid (), fd, fd, func_str,
532 i, sid, sid, iov[i].iov_base, iov[i].iov_len, total);
533
534 rv = vppcom_session_write (sid, iov[i].iov_base,
535 iov[i].iov_len);
536 if (rv < 0)
537 break;
538 else
539 {
540 total += rv;
541 if (rv < iov[i].iov_len)
542 {
Dave Wallace2a865272018-02-07 21:00:42 -0500543 if (LDP_DEBUG > 4)
Dave Wallace048b1d62018-01-03 22:24:41 -0500544 printf ("%s:%d: LDP<%d>: fd %d (0x%x): "
545 "rv (%d) < iov[%d].iov_len (%ld)",
546 __func__, __LINE__, getpid (), fd, fd,
547 rv, i, iov[i].iov_len);
548 break;
549 }
550 }
551 }
552 }
553 while ((rv >= 0) && (total == 0));
554
555 if (rv < 0)
556 {
557 errno = -rv;
558 size = -1;
559 }
560 else
561 size = total;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700562 }
563 else
564 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500565 func_str = "libc_writev";
566
Dave Wallace2a865272018-02-07 21:00:42 -0500567 if (LDP_DEBUG > 4)
Dave Wallace048b1d62018-01-03 22:24:41 -0500568 printf ("%s:%d: LDP<%d>: fd %d (0x%x): calling %s(): "
569 "iov %p, iovcnt %d\n", __func__, __LINE__, getpid (),
570 fd, fd, func_str, iov, iovcnt);
571
572 size = libc_writev (fd, iov, iovcnt);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700573 }
574
Dave Wallace2a865272018-02-07 21:00:42 -0500575 if (LDP_DEBUG > 4)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700576 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500577 if (size < 0)
578 {
579 int errno_val = errno;
580 perror (func_str);
581 fprintf (stderr,
582 "%s:%d: LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
583 "rv %ld, errno = %d\n", __func__, __LINE__, getpid (), fd,
584 fd, func_str, size, errno_val);
585 errno = errno_val;
586 }
587 else
588 printf ("%s:%d: LDP<%d>: fd %d (0x%x): returning %ld\n",
589 __func__, __LINE__, getpid (), fd, fd, size);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700590 }
Dave Wallace048b1d62018-01-03 22:24:41 -0500591 return size;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700592}
593
594int
Dave Wallace048b1d62018-01-03 22:24:41 -0500595fcntl (int fd, int cmd, ...)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700596{
Dave Wallace048b1d62018-01-03 22:24:41 -0500597 const char *func_str = __func__;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700598 int rv = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -0500599 va_list ap;
Dave Wallace2a865272018-02-07 21:00:42 -0500600 u32 sid = ldp_sid_from_fd (fd);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700601
Dave Wallace2a865272018-02-07 21:00:42 -0500602 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500603 return -1;
604
605 va_start (ap, cmd);
606 if (sid != INVALID_SESSION_ID)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700607 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500608 int flags = va_arg (ap, int);
609 u32 size;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700610
Dave Wallace048b1d62018-01-03 22:24:41 -0500611 size = sizeof (flags);
612 rv = -EOPNOTSUPP;
613 switch (cmd)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700614 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500615 case F_SETFL:
616 func_str = "vppcom_session_attr[SET_FLAGS]";
Dave Wallace2a865272018-02-07 21:00:42 -0500617 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -0500618 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
619 "sid %u (0x%x) flags %d (0x%x), size %d",
620 getpid (), fd, fd, func_str, sid, sid,
621 flags, flags, size);
622
623 rv =
624 vppcom_session_attr (sid, VPPCOM_ATTR_SET_FLAGS, &flags, &size);
625 break;
626
627 case F_GETFL:
628 func_str = "vppcom_session_attr[GET_FLAGS]";
Dave Wallace2a865272018-02-07 21:00:42 -0500629 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -0500630 clib_warning
631 ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), "
632 "flags %d (0x%x), size %d", getpid (), fd, fd, func_str, sid,
633 sid, flags, flags, size);
634
635 rv =
636 vppcom_session_attr (sid, VPPCOM_ATTR_GET_FLAGS, &flags, &size);
637 if (rv == VPPCOM_OK)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700638 {
Dave Wallace2a865272018-02-07 21:00:42 -0500639 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -0500640 clib_warning ("LDP<%d>: fd %d (0x%x), cmd %d (F_GETFL): "
641 "%s() returned flags %d (0x%x)",
642 getpid (), fd, fd, cmd, func_str, flags, flags);
643 rv = flags;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700644 }
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700645 break;
646
647 default:
Dave Wallace048b1d62018-01-03 22:24:41 -0500648 rv = -EOPNOTSUPP;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700649 break;
650 }
Dave Wallace048b1d62018-01-03 22:24:41 -0500651 if (rv < 0)
652 {
653 errno = -rv;
654 rv = -1;
655 }
656 }
657 else
658 {
659 func_str = "libc_vfcntl";
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700660
Dave Wallace2a865272018-02-07 21:00:42 -0500661 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -0500662 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): cmd %d",
663 getpid (), fd, fd, func_str, cmd);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700664
Dave Wallace048b1d62018-01-03 22:24:41 -0500665 rv = libc_vfcntl (fd, cmd, ap);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700666 }
667
Dave Wallace048b1d62018-01-03 22:24:41 -0500668 va_end (ap);
669
Dave Wallace2a865272018-02-07 21:00:42 -0500670 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -0500671 {
672 if (rv < 0)
673 {
674 int errno_val = errno;
675 perror (func_str);
676 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
677 "rv %d, errno = %d", getpid (), fd, fd,
678 func_str, rv, errno_val);
679 errno = errno_val;
680 }
681 else
682 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
683 getpid (), fd, fd, rv, rv);
684 }
685 return rv;
686}
687
688int
689ioctl (int fd, unsigned long int cmd, ...)
690{
691 const char *func_str;
692 int rv;
693 va_list ap;
Dave Wallace2a865272018-02-07 21:00:42 -0500694 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -0500695
Dave Wallace2a865272018-02-07 21:00:42 -0500696 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500697 return -1;
698
699 va_start (ap, cmd);
700 if (sid != INVALID_SESSION_ID)
701 {
702 func_str = "vppcom_session_attr[GET_NREAD]";
703
704 switch (cmd)
705 {
706 case FIONREAD:
Dave Wallace2a865272018-02-07 21:00:42 -0500707 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -0500708 clib_warning
709 ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x)",
710 getpid (), fd, fd, func_str, sid, sid);
711
712 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_NREAD, 0, 0);
713 break;
714
715 case FIONBIO:
716 {
717 u32 flags = va_arg (ap, int) ? O_NONBLOCK : 0;
718 u32 size = sizeof (flags);
719
720 /* TBD: When VPPCOM_ATTR_[GS]ET_FLAGS supports flags other than
721 * non-blocking, the flags should be read here and merged
722 * with O_NONBLOCK.
723 */
Dave Wallace2a865272018-02-07 21:00:42 -0500724 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -0500725 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
726 "sid %u (0x%x), flags %d (0x%x), size %d",
727 getpid (), fd, fd, func_str, sid, sid,
728 flags, flags, size);
729
730 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_FLAGS, &flags,
731 &size);
732 }
733 break;
734
735 default:
736 rv = -EOPNOTSUPP;
737 break;
738 }
739 if (rv < 0)
740 {
741 errno = -rv;
742 rv = -1;
743 }
744 }
745 else
746 {
747 func_str = "libc_vioctl";
748
Dave Wallace2a865272018-02-07 21:00:42 -0500749 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -0500750 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): cmd %d",
751 getpid (), fd, fd, func_str, cmd);
752
753 rv = libc_vioctl (fd, cmd, ap);
754 }
755
Dave Wallace2a865272018-02-07 21:00:42 -0500756 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -0500757 {
758 if (rv < 0)
759 {
760 int errno_val = errno;
761 perror (func_str);
762 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
763 "rv %d, errno = %d", getpid (), fd, fd,
764 func_str, rv, errno_val);
765 errno = errno_val;
766 }
767 else
768 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
769 getpid (), fd, fd, rv, rv);
770 }
771 va_end (ap);
772 return rv;
773}
774
775int
Dave Wallace2a865272018-02-07 21:00:42 -0500776ldp_pselect (int nfds, fd_set * __restrict readfds,
777 fd_set * __restrict writefds,
778 fd_set * __restrict exceptfds,
779 const struct timespec *__restrict timeout,
780 const __sigset_t * __restrict sigmask)
Dave Wallace048b1d62018-01-03 22:24:41 -0500781{
782 int rv;
783 char *func_str = "##";
784 f64 time_out;
785 int fd;
786 uword sid_bits, sid_bits_set, libc_bits, libc_bits_set;
787 u32 minbits = clib_max (nfds, BITS (uword));
788 u32 sid;
789
790 if (nfds < 0)
791 {
792 errno = EINVAL;
793 return -1;
794 }
795
Dave Wallace3ee1fe12018-02-23 01:09:11 -0500796 if (timeout)
797 {
798 time_out = (timeout->tv_sec == 0 && timeout->tv_nsec == 0) ?
799 (f64) 0 : (f64) timeout->tv_sec +
800 (f64) timeout->tv_nsec / (f64) 1000000000;
801
802 /* select as fine grained sleep */
803 if (!nfds)
804 {
805 if (LDP_DEBUG > 3)
806 clib_warning ("LDP<%d>: sleeping for %.02f seconds",
807 getpid (), time_out);
808
809 time_out += clib_time_now (&ldp->clib_time);
810 while (clib_time_now (&ldp->clib_time) < time_out)
811 ;
812 return 0;
813 }
814 }
815 else if (!nfds)
816 {
817 errno = EINVAL;
818 return -1;
819 }
820 else
821 time_out = -1;
822
823
Dave Wallace2a865272018-02-07 21:00:42 -0500824 if (nfds <= ldp->sid_bit_val)
Dave Wallace048b1d62018-01-03 22:24:41 -0500825 {
826 func_str = "libc_pselect";
827
Dave Wallace2a865272018-02-07 21:00:42 -0500828 if (LDP_DEBUG > 3)
Dave Wallace048b1d62018-01-03 22:24:41 -0500829 clib_warning
830 ("LDP<%d>: calling %s(): nfds %d, readfds %p, writefds %p, "
831 "exceptfds %p, timeout %p, sigmask %p", getpid (), func_str, nfds,
832 readfds, writefds, exceptfds, timeout, sigmask);
833
834 rv = libc_pselect (nfds, readfds, writefds, exceptfds,
835 timeout, sigmask);
836 goto done;
837 }
838
Dave Wallace2a865272018-02-07 21:00:42 -0500839 if (PREDICT_FALSE (ldp->sid_bit_val > FD_SETSIZE / 2))
Dave Wallace048b1d62018-01-03 22:24:41 -0500840 {
Dave Wallace2a865272018-02-07 21:00:42 -0500841 clib_warning ("LDP<%d>: ERROR: LDP sid bit value %d (0x%x) > "
Dave Wallace048b1d62018-01-03 22:24:41 -0500842 "FD_SETSIZE/2 %d (0x%x)!", getpid (),
Dave Wallace2a865272018-02-07 21:00:42 -0500843 ldp->sid_bit_val, ldp->sid_bit_val,
Dave Wallace048b1d62018-01-03 22:24:41 -0500844 FD_SETSIZE / 2, FD_SETSIZE / 2);
845 errno = EOVERFLOW;
846 return -1;
847 }
848
Dave Wallace048b1d62018-01-03 22:24:41 -0500849 sid_bits = libc_bits = 0;
850 if (readfds)
851 {
Dave Wallace2a865272018-02-07 21:00:42 -0500852 clib_bitmap_validate (ldp->sid_rd_bitmap, minbits);
853 clib_bitmap_validate (ldp->libc_rd_bitmap, minbits);
854 clib_bitmap_validate (ldp->rd_bitmap, minbits);
855 clib_memcpy (ldp->rd_bitmap, readfds,
856 vec_len (ldp->rd_bitmap) * sizeof (clib_bitmap_t));
Dave Wallace048b1d62018-01-03 22:24:41 -0500857 FD_ZERO (readfds);
858
859 /* *INDENT-OFF* */
Dave Wallace2a865272018-02-07 21:00:42 -0500860 clib_bitmap_foreach (fd, ldp->rd_bitmap,
Dave Wallace048b1d62018-01-03 22:24:41 -0500861 ({
Dave Wallace2a865272018-02-07 21:00:42 -0500862 sid = ldp_sid_from_fd (fd);
863 if (LDP_DEBUG > 3)
Dave Wallace048b1d62018-01-03 22:24:41 -0500864 clib_warning ("LDP<%d>: readfds: fd %d (0x%x), sid %u (0x%x)",
865 getpid (), fd, fd, sid, sid);
866 if (sid == INVALID_SESSION_ID)
Dave Wallace2a865272018-02-07 21:00:42 -0500867 clib_bitmap_set_no_check (ldp->libc_rd_bitmap, fd, 1);
Dave Wallace048b1d62018-01-03 22:24:41 -0500868 else
Dave Wallace2a865272018-02-07 21:00:42 -0500869 clib_bitmap_set_no_check (ldp->sid_rd_bitmap, sid, 1);
Dave Wallace048b1d62018-01-03 22:24:41 -0500870 }));
871 /* *INDENT-ON* */
872
Dave Wallace2a865272018-02-07 21:00:42 -0500873 sid_bits_set = clib_bitmap_last_set (ldp->sid_rd_bitmap) + 1;
Dave Wallace048b1d62018-01-03 22:24:41 -0500874 sid_bits = (sid_bits_set > sid_bits) ? sid_bits_set : sid_bits;
875
Dave Wallace2a865272018-02-07 21:00:42 -0500876 libc_bits_set = clib_bitmap_last_set (ldp->libc_rd_bitmap) + 1;
Dave Wallace048b1d62018-01-03 22:24:41 -0500877 libc_bits = (libc_bits_set > libc_bits) ? libc_bits_set : libc_bits;
878
Dave Wallace2a865272018-02-07 21:00:42 -0500879 if (LDP_DEBUG > 3)
Dave Wallace048b1d62018-01-03 22:24:41 -0500880 clib_warning ("LDP<%d>: readfds: sid_bits_set %d, sid_bits %d, "
881 "libc_bits_set %d, libc_bits %d", getpid (),
882 sid_bits_set, sid_bits, libc_bits_set, libc_bits);
883 }
884 if (writefds)
885 {
Dave Wallace2a865272018-02-07 21:00:42 -0500886 clib_bitmap_validate (ldp->sid_wr_bitmap, minbits);
887 clib_bitmap_validate (ldp->libc_wr_bitmap, minbits);
888 clib_bitmap_validate (ldp->wr_bitmap, minbits);
889 clib_memcpy (ldp->wr_bitmap, writefds,
890 vec_len (ldp->wr_bitmap) * sizeof (clib_bitmap_t));
Dave Wallace048b1d62018-01-03 22:24:41 -0500891 FD_ZERO (writefds);
892
893 /* *INDENT-OFF* */
Dave Wallace2a865272018-02-07 21:00:42 -0500894 clib_bitmap_foreach (fd, ldp->wr_bitmap,
Dave Wallace048b1d62018-01-03 22:24:41 -0500895 ({
Dave Wallace2a865272018-02-07 21:00:42 -0500896 sid = ldp_sid_from_fd (fd);
897 if (LDP_DEBUG > 3)
Dave Wallace048b1d62018-01-03 22:24:41 -0500898 clib_warning ("LDP<%d>: writefds: fd %d (0x%x), sid %u (0x%x)",
899 getpid (), fd, fd, sid, sid);
900 if (sid == INVALID_SESSION_ID)
Dave Wallace2a865272018-02-07 21:00:42 -0500901 clib_bitmap_set_no_check (ldp->libc_wr_bitmap, fd, 1);
Dave Wallace048b1d62018-01-03 22:24:41 -0500902 else
Dave Wallace2a865272018-02-07 21:00:42 -0500903 clib_bitmap_set_no_check (ldp->sid_wr_bitmap, sid, 1);
Dave Wallace048b1d62018-01-03 22:24:41 -0500904 }));
905 /* *INDENT-ON* */
906
Dave Wallace2a865272018-02-07 21:00:42 -0500907 sid_bits_set = clib_bitmap_last_set (ldp->sid_wr_bitmap) + 1;
Dave Wallace048b1d62018-01-03 22:24:41 -0500908 sid_bits = (sid_bits_set > sid_bits) ? sid_bits_set : sid_bits;
909
Dave Wallace2a865272018-02-07 21:00:42 -0500910 libc_bits_set = clib_bitmap_last_set (ldp->libc_wr_bitmap) + 1;
Dave Wallace048b1d62018-01-03 22:24:41 -0500911 libc_bits = (libc_bits_set > libc_bits) ? libc_bits_set : libc_bits;
912
Dave Wallace2a865272018-02-07 21:00:42 -0500913 if (LDP_DEBUG > 3)
Dave Wallace048b1d62018-01-03 22:24:41 -0500914 clib_warning ("LDP<%d>: writefds: sid_bits_set %d, sid_bits %d, "
915 "libc_bits_set %d, libc_bits %d", getpid (),
916 sid_bits_set, sid_bits, libc_bits_set, libc_bits);
917 }
918 if (exceptfds)
919 {
Dave Wallace2a865272018-02-07 21:00:42 -0500920 clib_bitmap_validate (ldp->sid_ex_bitmap, minbits);
921 clib_bitmap_validate (ldp->libc_ex_bitmap, minbits);
922 clib_bitmap_validate (ldp->ex_bitmap, minbits);
923 clib_memcpy (ldp->ex_bitmap, exceptfds,
924 vec_len (ldp->ex_bitmap) * sizeof (clib_bitmap_t));
Dave Wallace048b1d62018-01-03 22:24:41 -0500925 FD_ZERO (exceptfds);
926
927 /* *INDENT-OFF* */
Dave Wallace2a865272018-02-07 21:00:42 -0500928 clib_bitmap_foreach (fd, ldp->ex_bitmap,
Dave Wallace048b1d62018-01-03 22:24:41 -0500929 ({
Dave Wallace2a865272018-02-07 21:00:42 -0500930 sid = ldp_sid_from_fd (fd);
931 if (LDP_DEBUG > 3)
Dave Wallace048b1d62018-01-03 22:24:41 -0500932 clib_warning ("LDP<%d>: exceptfds: fd %d (0x%x), sid %u (0x%x)",
933 getpid (), fd, fd, sid, sid);
934 if (sid == INVALID_SESSION_ID)
Dave Wallace2a865272018-02-07 21:00:42 -0500935 clib_bitmap_set_no_check (ldp->libc_ex_bitmap, fd, 1);
Dave Wallace048b1d62018-01-03 22:24:41 -0500936 else
Dave Wallace2a865272018-02-07 21:00:42 -0500937 clib_bitmap_set_no_check (ldp->sid_ex_bitmap, sid, 1);
Dave Wallace048b1d62018-01-03 22:24:41 -0500938 }));
939 /* *INDENT-ON* */
940
Dave Wallace2a865272018-02-07 21:00:42 -0500941 sid_bits_set = clib_bitmap_last_set (ldp->sid_ex_bitmap) + 1;
Dave Wallace048b1d62018-01-03 22:24:41 -0500942 sid_bits = (sid_bits_set > sid_bits) ? sid_bits_set : sid_bits;
943
Dave Wallace2a865272018-02-07 21:00:42 -0500944 libc_bits_set = clib_bitmap_last_set (ldp->libc_ex_bitmap) + 1;
Dave Wallace048b1d62018-01-03 22:24:41 -0500945 libc_bits = (libc_bits_set > libc_bits) ? libc_bits_set : libc_bits;
946
Dave Wallace2a865272018-02-07 21:00:42 -0500947 if (LDP_DEBUG > 3)
Dave Wallace048b1d62018-01-03 22:24:41 -0500948 clib_warning ("LDP<%d>: exceptfds: sid_bits_set %d, sid_bits %d, "
949 "libc_bits_set %d, libc_bits %d", getpid (),
950 sid_bits_set, sid_bits, libc_bits_set, libc_bits);
951 }
952
953 if (PREDICT_FALSE (!sid_bits && !libc_bits))
954 {
955 errno = EINVAL;
956 rv = -1;
957 goto done;
958 }
959
960 do
961 {
962 if (sid_bits)
963 {
Dave Wallace2a865272018-02-07 21:00:42 -0500964 if (!ldp->select_vcl)
Dave Wallace048b1d62018-01-03 22:24:41 -0500965 {
966 func_str = "vppcom_select";
967
968 if (readfds)
Dave Wallace2a865272018-02-07 21:00:42 -0500969 clib_memcpy (ldp->rd_bitmap, ldp->sid_rd_bitmap,
970 vec_len (ldp->rd_bitmap) *
Dave Wallace048b1d62018-01-03 22:24:41 -0500971 sizeof (clib_bitmap_t));
972 if (writefds)
Dave Wallace2a865272018-02-07 21:00:42 -0500973 clib_memcpy (ldp->wr_bitmap, ldp->sid_wr_bitmap,
974 vec_len (ldp->wr_bitmap) *
Dave Wallace048b1d62018-01-03 22:24:41 -0500975 sizeof (clib_bitmap_t));
976 if (exceptfds)
Dave Wallace2a865272018-02-07 21:00:42 -0500977 clib_memcpy (ldp->ex_bitmap, ldp->sid_ex_bitmap,
978 vec_len (ldp->ex_bitmap) *
Dave Wallace048b1d62018-01-03 22:24:41 -0500979 sizeof (clib_bitmap_t));
980
981 rv = vppcom_select (sid_bits,
Dave Wallace2a865272018-02-07 21:00:42 -0500982 readfds ? ldp->rd_bitmap : NULL,
983 writefds ? ldp->wr_bitmap : NULL,
984 exceptfds ? ldp->ex_bitmap : NULL, 0);
Dave Wallace048b1d62018-01-03 22:24:41 -0500985 if (rv < 0)
986 {
987 errno = -rv;
988 rv = -1;
989 }
990 else if (rv > 0)
991 {
992 if (readfds)
993 {
994 /* *INDENT-OFF* */
Dave Wallace2a865272018-02-07 21:00:42 -0500995 clib_bitmap_foreach (sid, ldp->rd_bitmap,
Dave Wallace048b1d62018-01-03 22:24:41 -0500996 ({
Dave Wallace2a865272018-02-07 21:00:42 -0500997 fd = ldp_fd_from_sid (sid);
Dave Wallace048b1d62018-01-03 22:24:41 -0500998 if (PREDICT_FALSE (fd < 0))
999 {
1000 errno = EBADFD;
1001 rv = -1;
1002 goto done;
1003 }
1004 FD_SET (fd, readfds);
1005 }));
1006 /* *INDENT-ON* */
1007 }
1008 if (writefds)
1009 {
1010 /* *INDENT-OFF* */
Dave Wallace2a865272018-02-07 21:00:42 -05001011 clib_bitmap_foreach (sid, ldp->wr_bitmap,
Dave Wallace048b1d62018-01-03 22:24:41 -05001012 ({
Dave Wallace2a865272018-02-07 21:00:42 -05001013 fd = ldp_fd_from_sid (sid);
Dave Wallace048b1d62018-01-03 22:24:41 -05001014 if (PREDICT_FALSE (fd < 0))
1015 {
1016 errno = EBADFD;
1017 rv = -1;
1018 goto done;
1019 }
1020 FD_SET (fd, writefds);
1021 }));
1022 /* *INDENT-ON* */
1023 }
1024 if (exceptfds)
1025 {
1026 /* *INDENT-OFF* */
Dave Wallace2a865272018-02-07 21:00:42 -05001027 clib_bitmap_foreach (sid, ldp->ex_bitmap,
Dave Wallace048b1d62018-01-03 22:24:41 -05001028 ({
Dave Wallace2a865272018-02-07 21:00:42 -05001029 fd = ldp_fd_from_sid (sid);
Dave Wallace048b1d62018-01-03 22:24:41 -05001030 if (PREDICT_FALSE (fd < 0))
1031 {
1032 errno = EBADFD;
1033 rv = -1;
1034 goto done;
1035 }
1036 FD_SET (fd, exceptfds);
1037 }));
1038 /* *INDENT-ON* */
1039 }
Dave Wallace2a865272018-02-07 21:00:42 -05001040 ldp->select_vcl = 1;
Dave Wallace048b1d62018-01-03 22:24:41 -05001041 goto done;
1042 }
1043 }
1044 else
Dave Wallace2a865272018-02-07 21:00:42 -05001045 ldp->select_vcl = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -05001046 }
1047 if (libc_bits)
1048 {
1049 struct timespec tspec;
1050
1051 func_str = "libc_pselect";
1052
1053 if (readfds)
Dave Wallace2a865272018-02-07 21:00:42 -05001054 clib_memcpy (readfds, ldp->libc_rd_bitmap,
1055 vec_len (ldp->rd_bitmap) * sizeof (clib_bitmap_t));
Dave Wallace048b1d62018-01-03 22:24:41 -05001056 if (writefds)
Dave Wallace2a865272018-02-07 21:00:42 -05001057 clib_memcpy (writefds, ldp->libc_wr_bitmap,
1058 vec_len (ldp->wr_bitmap) * sizeof (clib_bitmap_t));
Dave Wallace048b1d62018-01-03 22:24:41 -05001059 if (exceptfds)
Dave Wallace2a865272018-02-07 21:00:42 -05001060 clib_memcpy (exceptfds, ldp->libc_ex_bitmap,
1061 vec_len (ldp->ex_bitmap) * sizeof (clib_bitmap_t));
Dave Wallace048b1d62018-01-03 22:24:41 -05001062 tspec.tv_sec = tspec.tv_nsec = 0;
1063 rv = libc_pselect (libc_bits,
1064 readfds ? readfds : NULL,
1065 writefds ? writefds : NULL,
1066 exceptfds ? exceptfds : NULL, &tspec, sigmask);
1067 if (rv != 0)
1068 goto done;
1069 }
1070 }
Dave Wallace2a865272018-02-07 21:00:42 -05001071 while ((time_out == -1) || (clib_time_now (&ldp->clib_time) < time_out));
Dave Wallace048b1d62018-01-03 22:24:41 -05001072 rv = 0;
1073
1074done:
1075 /* TBD: set timeout to amount of time left */
Dave Wallace2a865272018-02-07 21:00:42 -05001076 vec_reset_length (ldp->rd_bitmap);
1077 vec_reset_length (ldp->sid_rd_bitmap);
1078 vec_reset_length (ldp->libc_rd_bitmap);
1079 vec_reset_length (ldp->wr_bitmap);
1080 vec_reset_length (ldp->sid_wr_bitmap);
1081 vec_reset_length (ldp->libc_wr_bitmap);
1082 vec_reset_length (ldp->ex_bitmap);
1083 vec_reset_length (ldp->sid_ex_bitmap);
1084 vec_reset_length (ldp->libc_ex_bitmap);
Dave Wallace048b1d62018-01-03 22:24:41 -05001085
Dave Wallace2a865272018-02-07 21:00:42 -05001086 if (LDP_DEBUG > 3)
Dave Wallace048b1d62018-01-03 22:24:41 -05001087 {
1088 if (rv < 0)
1089 {
1090 int errno_val = errno;
1091 perror (func_str);
1092 clib_warning ("LDP<%d>: ERROR: %s() failed! "
1093 "rv %d, errno = %d", getpid (),
1094 func_str, rv, errno_val);
1095 errno = errno_val;
1096 }
1097 else
1098 clib_warning ("LDP<%d>: returning %d (0x%x)", getpid (), rv, rv);
1099 }
1100 return rv;
1101}
1102
1103int
1104select (int nfds, fd_set * __restrict readfds,
1105 fd_set * __restrict writefds,
1106 fd_set * __restrict exceptfds, struct timeval *__restrict timeout)
1107{
1108 struct timespec tspec;
1109
1110 if (timeout)
1111 {
1112 tspec.tv_sec = timeout->tv_sec;
1113 tspec.tv_nsec = timeout->tv_usec * 1000;
1114 }
Dave Wallace2a865272018-02-07 21:00:42 -05001115 return ldp_pselect (nfds, readfds, writefds, exceptfds,
1116 timeout ? &tspec : NULL, NULL);
Dave Wallace048b1d62018-01-03 22:24:41 -05001117}
1118
1119#ifdef __USE_XOPEN2K
1120int
1121pselect (int nfds, fd_set * __restrict readfds,
1122 fd_set * __restrict writefds,
1123 fd_set * __restrict exceptfds,
1124 const struct timespec *__restrict timeout,
1125 const __sigset_t * __restrict sigmask)
1126{
Dave Wallace2a865272018-02-07 21:00:42 -05001127 return ldp_pselect (nfds, readfds, writefds, exceptfds, timeout, 0);
Dave Wallace048b1d62018-01-03 22:24:41 -05001128}
1129#endif
1130
1131int
1132socket (int domain, int type, int protocol)
1133{
1134 const char *func_str;
1135 int rv;
1136 u8 is_nonblocking = type & SOCK_NONBLOCK ? 1 : 0;
1137 int sock_type = type & ~(SOCK_CLOEXEC | SOCK_NONBLOCK);
1138
Dave Wallace2a865272018-02-07 21:00:42 -05001139 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001140 return -1;
1141
1142 if (((domain == AF_INET) || (domain == AF_INET6)) &&
1143 ((sock_type == SOCK_STREAM) || (sock_type == SOCK_DGRAM)))
1144 {
1145 int sid;
Dave Wallace048b1d62018-01-03 22:24:41 -05001146 u8 proto = ((sock_type == SOCK_DGRAM) ?
1147 VPPCOM_PROTO_UDP : VPPCOM_PROTO_TCP);
1148
1149 func_str = "vppcom_session_create";
1150
Florin Coras99368312018-08-02 10:45:44 -07001151 LDBG (0, "LDP<%d>: : calling %s(): proto %u (%s), is_nonblocking %u",
1152 getpid (), func_str, proto, vppcom_proto_str (proto),
1153 is_nonblocking);
Dave Wallace048b1d62018-01-03 22:24:41 -05001154
Dave Wallacec04cbf12018-02-07 18:14:02 -05001155 sid = vppcom_session_create (proto, is_nonblocking);
Dave Wallace048b1d62018-01-03 22:24:41 -05001156 if (sid < 0)
1157 {
1158 errno = -sid;
1159 rv = -1;
1160 }
1161 else
1162 {
Dave Wallace2a865272018-02-07 21:00:42 -05001163 func_str = "ldp_fd_from_sid";
1164 rv = ldp_fd_from_sid (sid);
Dave Wallace048b1d62018-01-03 22:24:41 -05001165 if (rv < 0)
1166 {
1167 (void) vppcom_session_close (sid);
1168 errno = -rv;
1169 rv = -1;
1170 }
1171 }
1172 }
1173 else
1174 {
1175 func_str = "libc_socket";
1176
Florin Coras99368312018-08-02 10:45:44 -07001177 LDBG (0, "LDP<%d>: : calling %s()", getpid (), func_str);
Dave Wallace048b1d62018-01-03 22:24:41 -05001178
1179 rv = libc_socket (domain, type, protocol);
1180 }
1181
Dave Wallace2a865272018-02-07 21:00:42 -05001182 if (LDP_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001183 {
1184 if (rv < 0)
1185 {
1186 int errno_val = errno;
1187 perror (func_str);
1188 clib_warning ("LDP<%d>: ERROR: %s() failed! "
1189 "rv %d, errno = %d",
1190 getpid (), func_str, rv, errno_val);
1191 errno = errno_val;
1192 }
1193 else
1194 clib_warning ("LDP<%d>: : returning fd %d (0x%x)", getpid (), rv, rv);
1195 }
1196 return rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001197}
1198
1199/*
1200 * Create two new sockets, of type TYPE in domain DOMAIN and using
1201 * protocol PROTOCOL, which are connected to each other, and put file
1202 * descriptors for them in FDS[0] and FDS[1]. If PROTOCOL is zero,
1203 * one will be chosen automatically.
1204 * Returns 0 on success, -1 for errors.
1205 * */
1206int
Dave Wallace048b1d62018-01-03 22:24:41 -05001207socketpair (int domain, int type, int protocol, int fds[2])
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001208{
Dave Wallace048b1d62018-01-03 22:24:41 -05001209 const char *func_str;
1210 int rv;
1211 int sock_type = type & ~(SOCK_CLOEXEC | SOCK_NONBLOCK);
1212
Dave Wallace2a865272018-02-07 21:00:42 -05001213 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001214 return -1;
1215
1216 if (((domain == AF_INET) || (domain == AF_INET6)) &&
1217 ((sock_type == SOCK_STREAM) || (sock_type == SOCK_DGRAM)))
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001218 {
Dave Wallace8aaba562018-01-18 17:21:19 -05001219 func_str = __func__;
1220
Dave Wallace048b1d62018-01-03 22:24:41 -05001221 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
1222 errno = ENOSYS;
1223 rv = -1;
1224 }
1225 else
1226 {
1227 func_str = "libc_socket";
1228
Dave Wallace2a865272018-02-07 21:00:42 -05001229 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05001230 clib_warning ("LDP<%d>: : calling %s()", getpid (), func_str);
1231
1232 rv = libc_socket (domain, type, protocol);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001233 }
1234
Dave Wallace2a865272018-02-07 21:00:42 -05001235 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05001236 {
1237 if (rv < 0)
1238 {
1239 int errno_val = errno;
1240 perror (func_str);
1241 clib_warning ("LDP<%d>: ERROR: %s() failed! "
1242 "rv %d, errno = %d",
1243 getpid (), func_str, rv, errno_val);
1244 errno = errno_val;
1245 }
1246 else
1247 clib_warning ("LDP<%d>: : returning fd %d (0x%x)", getpid (), rv, rv);
1248 }
1249 return rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001250}
1251
1252int
Dave Wallace048b1d62018-01-03 22:24:41 -05001253bind (int fd, __CONST_SOCKADDR_ARG addr, socklen_t len)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001254{
1255 int rv;
Dave Wallace048b1d62018-01-03 22:24:41 -05001256 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05001257 u32 sid = ldp_sid_from_fd (fd);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001258
Dave Wallace2a865272018-02-07 21:00:42 -05001259 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001260 return -1;
1261
1262 if (sid != INVALID_SESSION_ID)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001263 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001264 vppcom_endpt_t ep;
1265
1266 func_str = "vppcom_session_bind";
1267
Dave Wallace048b1d62018-01-03 22:24:41 -05001268 switch (addr->sa_family)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001269 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001270 case AF_INET:
1271 if (len != sizeof (struct sockaddr_in))
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001272 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001273 clib_warning
1274 ("LDP<%d>: ERROR: fd %d (0x%x): sid %u (0x%x): Invalid "
1275 "AF_INET addr len %u!", getpid (), fd, fd, sid, sid, len);
1276 errno = EINVAL;
1277 rv = -1;
1278 goto done;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001279 }
Dave Wallace048b1d62018-01-03 22:24:41 -05001280 ep.is_ip4 = VPPCOM_IS_IP4;
1281 ep.ip = (u8 *) & ((const struct sockaddr_in *) addr)->sin_addr;
1282 ep.port = (u16) ((const struct sockaddr_in *) addr)->sin_port;
1283 break;
1284
1285 case AF_INET6:
1286 if (len != sizeof (struct sockaddr_in6))
1287 {
1288 clib_warning
1289 ("LDP<%d>: ERROR: fd %d (0x%x): sid %u (0x%x): Invalid "
1290 "AF_INET6 addr len %u!", getpid (), fd, fd, sid, sid, len);
1291 errno = EINVAL;
1292 rv = -1;
1293 goto done;
1294 }
1295 ep.is_ip4 = VPPCOM_IS_IP6;
1296 ep.ip = (u8 *) & ((const struct sockaddr_in6 *) addr)->sin6_addr;
1297 ep.port = (u16) ((const struct sockaddr_in6 *) addr)->sin6_port;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001298 break;
1299
1300 default:
Dave Wallace048b1d62018-01-03 22:24:41 -05001301 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): sid %u (0x%x): "
1302 "Unsupported address family %u!",
1303 getpid (), fd, fd, sid, sid, addr->sa_family);
1304 errno = EAFNOSUPPORT;
1305 rv = -1;
1306 goto done;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001307 }
Dave Wallace2a865272018-02-07 21:00:42 -05001308 if (LDP_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001309 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), "
1310 "addr %p, len %u",
1311 getpid (), fd, fd, func_str, sid, sid, addr, len);
1312
1313 rv = vppcom_session_bind (sid, &ep);
1314 if (rv != VPPCOM_OK)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001315 {
1316 errno = -rv;
Dave Wallace048b1d62018-01-03 22:24:41 -05001317 rv = -1;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001318 }
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001319 }
Dave Wallace048b1d62018-01-03 22:24:41 -05001320 else
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001321 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001322 func_str = "libc_bind";
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001323
Dave Wallace2a865272018-02-07 21:00:42 -05001324 if (LDP_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001325 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1326 "addr %p, len %u",
1327 getpid (), fd, fd, func_str, addr, len);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001328
Dave Wallace048b1d62018-01-03 22:24:41 -05001329 rv = libc_bind (fd, addr, len);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001330 }
1331
Dave Wallace048b1d62018-01-03 22:24:41 -05001332done:
Dave Wallace2a865272018-02-07 21:00:42 -05001333 if (LDP_DEBUG > 0)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001334 {
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001335 if (rv < 0)
1336 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001337 int errno_val = errno;
1338 perror (func_str);
1339 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
1340 "rv %d, errno = %d", getpid (), fd, fd,
1341 func_str, rv, errno_val);
1342 errno = errno_val;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001343 }
Dave Wallace048b1d62018-01-03 22:24:41 -05001344 else
1345 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
1346 getpid (), fd, fd, rv, rv);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001347 }
1348 return rv;
1349}
1350
1351static inline int
Dave Wallace2a865272018-02-07 21:00:42 -05001352ldp_copy_ep_to_sockaddr (__SOCKADDR_ARG addr, socklen_t * __restrict len,
1353 vppcom_endpt_t * ep)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001354{
Dave Wallace048b1d62018-01-03 22:24:41 -05001355 int rv = 0;
1356 int sa_len, copy_len;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001357
Dave Wallace2a865272018-02-07 21:00:42 -05001358 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001359 return -1;
1360
1361 if (addr && len && ep)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001362 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001363 addr->sa_family = (ep->is_ip4 == VPPCOM_IS_IP4) ? AF_INET : AF_INET6;
1364 switch (addr->sa_family)
1365 {
1366 case AF_INET:
1367 ((struct sockaddr_in *) addr)->sin_port = ep->port;
1368 if (*len > sizeof (struct sockaddr_in))
1369 *len = sizeof (struct sockaddr_in);
1370 sa_len = sizeof (struct sockaddr_in) - sizeof (struct in_addr);
1371 copy_len = *len - sa_len;
1372 if (copy_len > 0)
1373 memcpy (&((struct sockaddr_in *) addr)->sin_addr, ep->ip,
1374 copy_len);
1375 break;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001376
Dave Wallace048b1d62018-01-03 22:24:41 -05001377 case AF_INET6:
1378 ((struct sockaddr_in6 *) addr)->sin6_port = ep->port;
1379 if (*len > sizeof (struct sockaddr_in6))
1380 *len = sizeof (struct sockaddr_in6);
1381 sa_len = sizeof (struct sockaddr_in6) - sizeof (struct in6_addr);
1382 copy_len = *len - sa_len;
1383 if (copy_len > 0)
1384 memcpy (((struct sockaddr_in6 *) addr)->sin6_addr.
1385 __in6_u.__u6_addr8, ep->ip, copy_len);
1386 break;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001387
Dave Wallace048b1d62018-01-03 22:24:41 -05001388 default:
1389 /* Not possible */
1390 rv = -EAFNOSUPPORT;
1391 break;
1392 }
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001393 }
Dave Wallacee695cb42017-11-02 22:04:42 -04001394 return rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001395}
1396
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001397int
Dave Wallace048b1d62018-01-03 22:24:41 -05001398getsockname (int fd, __SOCKADDR_ARG addr, socklen_t * __restrict len)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001399{
1400 int rv;
Dave Wallace048b1d62018-01-03 22:24:41 -05001401 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05001402 u32 sid = ldp_sid_from_fd (fd);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001403
Dave Wallace2a865272018-02-07 21:00:42 -05001404 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001405 return -1;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001406
Dave Wallace048b1d62018-01-03 22:24:41 -05001407 if (sid != INVALID_SESSION_ID)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001408 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001409 vppcom_endpt_t ep;
1410 u8 addr_buf[sizeof (struct in6_addr)];
1411 u32 size = sizeof (ep);
1412
1413 ep.ip = addr_buf;
1414 func_str = "vppcom_session_attr[GET_LCL_ADDR]";
1415
Dave Wallace2a865272018-02-07 21:00:42 -05001416 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001417 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), "
1418 "addr %p, len %u",
1419 getpid (), fd, fd, func_str, sid, sid, addr, len);
1420
1421 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_LCL_ADDR, &ep, &size);
1422 if (rv != VPPCOM_OK)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001423 {
1424 errno = -rv;
Dave Wallace048b1d62018-01-03 22:24:41 -05001425 rv = -1;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001426 }
Dave Wallace048b1d62018-01-03 22:24:41 -05001427 else
1428 {
Dave Wallace2a865272018-02-07 21:00:42 -05001429 rv = ldp_copy_ep_to_sockaddr (addr, len, &ep);
Dave Wallace048b1d62018-01-03 22:24:41 -05001430 if (rv != VPPCOM_OK)
1431 {
1432 errno = -rv;
1433 rv = -1;
1434 }
1435 }
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001436 }
1437 else
1438 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001439 func_str = "libc_getsockname";
1440
Dave Wallace2a865272018-02-07 21:00:42 -05001441 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001442 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1443 "addr %p, len %u",
1444 getpid (), fd, fd, func_str, addr, len);
1445
1446 rv = libc_getsockname (fd, addr, len);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001447 }
1448
Dave Wallace2a865272018-02-07 21:00:42 -05001449 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001450 {
1451 if (rv < 0)
1452 {
1453 int errno_val = errno;
1454 perror (func_str);
1455 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
1456 "rv %d, errno = %d", getpid (), fd, fd,
1457 func_str, rv, errno_val);
1458 errno = errno_val;
1459 }
1460 else
1461 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
1462 getpid (), fd, fd, rv, rv);
1463 }
1464 return rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001465}
1466
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001467int
Dave Wallace048b1d62018-01-03 22:24:41 -05001468connect (int fd, __CONST_SOCKADDR_ARG addr, socklen_t len)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001469{
Dave Wallace048b1d62018-01-03 22:24:41 -05001470 int rv;
1471 const char *func_str = __func__;
Dave Wallace2a865272018-02-07 21:00:42 -05001472 u32 sid = ldp_sid_from_fd (fd);
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001473
Dave Wallace2a865272018-02-07 21:00:42 -05001474 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001475 return -1;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001476
Dave Wallace048b1d62018-01-03 22:24:41 -05001477 if (!addr)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001478 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001479 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): NULL addr, len %u",
1480 getpid (), fd, fd, len);
1481 errno = EINVAL;
1482 rv = -1;
1483 goto done;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001484 }
1485
Dave Wallace048b1d62018-01-03 22:24:41 -05001486 if (sid != INVALID_SESSION_ID)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001487 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001488 vppcom_endpt_t ep;
1489
1490 func_str = "vppcom_session_connect";
1491
Dave Wallace048b1d62018-01-03 22:24:41 -05001492 switch (addr->sa_family)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001493 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001494 case AF_INET:
1495 if (len != sizeof (struct sockaddr_in))
1496 {
1497 clib_warning
1498 ("LDP<%d>: fd %d (0x%x): ERROR sid %u (0x%x): Invalid "
1499 "AF_INET addr len %u!", getpid (), fd, fd, sid, sid, len);
1500 errno = EINVAL;
1501 rv = -1;
1502 goto done;
1503 }
1504 ep.is_ip4 = VPPCOM_IS_IP4;
1505 ep.ip = (u8 *) & ((const struct sockaddr_in *) addr)->sin_addr;
1506 ep.port = (u16) ((const struct sockaddr_in *) addr)->sin_port;
1507 break;
1508
1509 case AF_INET6:
1510 if (len != sizeof (struct sockaddr_in6))
1511 {
1512 clib_warning
1513 ("LDP<%d>: fd %d (0x%x): ERROR sid %u (0x%x): Invalid "
1514 "AF_INET6 addr len %u!", getpid (), fd, fd, sid, sid, len);
1515 errno = EINVAL;
1516 rv = -1;
1517 goto done;
1518 }
1519 ep.is_ip4 = VPPCOM_IS_IP6;
1520 ep.ip = (u8 *) & ((const struct sockaddr_in6 *) addr)->sin6_addr;
1521 ep.port = (u16) ((const struct sockaddr_in6 *) addr)->sin6_port;
1522 break;
1523
1524 default:
1525 clib_warning ("LDP<%d>: fd %d (0x%x): ERROR sid %u (0x%x): "
1526 "Unsupported address family %u!",
1527 getpid (), fd, fd, sid, sid, addr->sa_family);
1528 errno = EAFNOSUPPORT;
1529 rv = -1;
1530 goto done;
1531 }
Dave Wallace2a865272018-02-07 21:00:42 -05001532 if (LDP_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001533 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x) "
1534 "addr %p len %u",
1535 getpid (), fd, fd, func_str, sid, sid, addr, len);
1536
1537 rv = vppcom_session_connect (sid, &ep);
1538 if (rv != VPPCOM_OK)
1539 {
1540 errno = -rv;
1541 rv = -1;
1542 }
1543 }
1544 else
1545 {
1546 func_str = "libc_connect";
1547
Dave Wallace2a865272018-02-07 21:00:42 -05001548 if (LDP_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001549 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1550 "addr %p, len %u",
1551 getpid (), fd, fd, func_str, addr, len);
1552
1553 rv = libc_connect (fd, addr, len);
1554 }
1555
1556done:
Dave Wallace2a865272018-02-07 21:00:42 -05001557 if (LDP_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001558 {
1559 if (rv < 0)
1560 {
1561 int errno_val = errno;
1562 perror (func_str);
1563 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
1564 "rv %d, errno = %d", getpid (), fd, fd,
1565 func_str, rv, errno_val);
1566 errno = errno_val;
1567 }
1568 else
1569 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
1570 getpid (), fd, fd, rv, rv);
1571 }
1572 return rv;
1573}
1574
1575int
1576getpeername (int fd, __SOCKADDR_ARG addr, socklen_t * __restrict len)
1577{
1578 int rv;
1579 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05001580 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05001581
Dave Wallace2a865272018-02-07 21:00:42 -05001582 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001583 return -1;
1584
Dave Wallace048b1d62018-01-03 22:24:41 -05001585 if (sid != INVALID_SESSION_ID)
1586 {
1587 vppcom_endpt_t ep;
1588 u8 addr_buf[sizeof (struct in6_addr)];
1589 u32 size = sizeof (ep);
1590
1591 ep.ip = addr_buf;
1592 func_str = "vppcom_session_attr[GET_PEER_ADDR]";
1593
Dave Wallace2a865272018-02-07 21:00:42 -05001594 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001595 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), "
1596 "addr %p, len %u",
1597 getpid (), fd, fd, func_str, sid, sid, addr, len);
1598
1599 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_PEER_ADDR, &ep, &size);
1600 if (rv != VPPCOM_OK)
1601 {
1602 errno = -rv;
1603 rv = -1;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001604 }
1605 else
1606 {
Dave Wallace2a865272018-02-07 21:00:42 -05001607 rv = ldp_copy_ep_to_sockaddr (addr, len, &ep);
Dave Wallace048b1d62018-01-03 22:24:41 -05001608 if (rv != VPPCOM_OK)
1609 {
1610 errno = -rv;
1611 rv = -1;
1612 }
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001613 }
1614 }
Dave Wallace048b1d62018-01-03 22:24:41 -05001615 else
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001616 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001617 func_str = "libc_getpeername";
1618
Dave Wallace2a865272018-02-07 21:00:42 -05001619 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001620 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1621 "addr %p, len %u",
1622 getpid (), fd, fd, func_str, addr, len);
1623
1624 rv = libc_getpeername (fd, addr, len);
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001625 }
1626
Dave Wallace2a865272018-02-07 21:00:42 -05001627 if (LDP_DEBUG > 2)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001628 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001629 if (rv < 0)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001630 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001631 int errno_val = errno;
1632 perror (func_str);
1633 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
1634 "rv %d, errno = %d", getpid (), fd, fd,
1635 func_str, rv, errno_val);
1636 errno = errno_val;
1637 }
1638 else
1639 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
1640 getpid (), fd, fd, rv, rv);
1641 }
1642 return rv;
1643}
1644
1645ssize_t
1646send (int fd, const void *buf, size_t n, int flags)
1647{
1648 ssize_t size;
1649 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05001650 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05001651
Dave Wallace2a865272018-02-07 21:00:42 -05001652 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001653 return -1;
1654
1655 if (sid != INVALID_SESSION_ID)
1656 {
1657
1658 func_str = "vppcom_session_sendto";
1659
Dave Wallace2a865272018-02-07 21:00:42 -05001660 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001661 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), "
1662 "buf %p, n %u, flags 0x%x",
1663 getpid (), fd, fd, func_str, sid, sid, buf, n, flags);
1664
1665 size = vppcom_session_sendto (sid, (void *) buf, n, flags, NULL);
qchangaa8f63c2018-05-30 11:44:18 -07001666 if (size < VPPCOM_OK)
Dave Wallace048b1d62018-01-03 22:24:41 -05001667 {
1668 errno = -size;
1669 size = -1;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001670 }
1671 }
Dave Wallace048b1d62018-01-03 22:24:41 -05001672 else
1673 {
1674 func_str = "libc_send";
1675
Dave Wallace2a865272018-02-07 21:00:42 -05001676 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001677 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1678 "buf %p, n %u, flags 0x%x",
1679 getpid (), fd, fd, func_str, buf, n, flags);
1680
1681 size = libc_send (fd, buf, n, flags);
1682 }
1683
Dave Wallace2a865272018-02-07 21:00:42 -05001684 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001685 {
1686 if (size < 0)
1687 {
1688 int errno_val = errno;
1689 perror (func_str);
1690 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
1691 "rv %d, errno = %d", getpid (), fd, fd,
1692 func_str, size, errno_val);
1693 errno = errno_val;
1694 }
1695 else
1696 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
1697 getpid (), fd, fd, size, size);
1698 }
1699 return size;
1700}
1701
1702ssize_t
1703sendfile (int out_fd, int in_fd, off_t * offset, size_t len)
1704{
1705 ssize_t size = 0;
1706 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05001707 u32 sid = ldp_sid_from_fd (out_fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05001708
Dave Wallace2a865272018-02-07 21:00:42 -05001709 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001710 return -1;
1711
1712 if (sid != INVALID_SESSION_ID)
1713 {
1714 int rv;
1715 ssize_t results = 0;
1716 size_t n_bytes_left = len;
1717 size_t bytes_to_read;
1718 int nbytes;
1719 int errno_val;
1720 u8 eagain = 0;
1721 u32 flags, flags_len = sizeof (flags);
1722
1723 func_str = "vppcom_session_attr[GET_FLAGS]";
1724 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_FLAGS, &flags,
1725 &flags_len);
1726 if (PREDICT_FALSE (rv != VPPCOM_OK))
1727 {
1728 clib_warning ("LDP<%d>: ERROR: out fd %d (0x%x): %s(): "
1729 "sid %u (0x%x), returned %d (%s)!", getpid (),
1730 out_fd, out_fd, func_str, sid, sid, rv,
1731 vppcom_retval_str (rv));
1732
Dave Wallace2a865272018-02-07 21:00:42 -05001733 vec_reset_length (ldp->io_buffer);
Dave Wallace048b1d62018-01-03 22:24:41 -05001734 errno = -rv;
1735 size = -1;
1736 goto done;
1737 }
1738
1739 if (offset)
1740 {
1741 off_t off = lseek (in_fd, *offset, SEEK_SET);
1742 if (PREDICT_FALSE (off == -1))
1743 {
1744 func_str = "lseek";
1745 errno_val = errno;
1746 clib_warning ("LDP<%d>: ERROR: out fd %d (0x%x): %s(): "
1747 "SEEK_SET failed: in_fd %d, offset %p, "
1748 "*offset %ld, rv %ld, errno %d", getpid (),
1749 out_fd, out_fd, in_fd, offset, *offset, off,
1750 errno_val);
1751 errno = errno_val;
1752 size = -1;
1753 goto done;
1754 }
1755
1756 ASSERT (off == *offset);
1757 }
1758
1759 do
1760 {
1761 func_str = "vppcom_session_attr[GET_NWRITE]";
1762 size = vppcom_session_attr (sid, VPPCOM_ATTR_GET_NWRITE, 0, 0);
1763 if (size < 0)
1764 {
1765 clib_warning
1766 ("LDP<%d>: ERROR: fd %d (0x%x): %s(): sid %u (0x%x), "
1767 "returned %d (%s)!", getpid (), out_fd, out_fd, func_str,
1768 sid, sid, size, vppcom_retval_str (size));
Dave Wallace2a865272018-02-07 21:00:42 -05001769 vec_reset_length (ldp->io_buffer);
Dave Wallace048b1d62018-01-03 22:24:41 -05001770 errno = -size;
1771 size = -1;
1772 goto done;
1773 }
1774
1775 bytes_to_read = size;
Dave Wallace2a865272018-02-07 21:00:42 -05001776 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001777 clib_warning
1778 ("LDP<%d>: fd %d (0x%x): called %s(): sid %u (0x%x), "
1779 "results %ld, n_bytes_left %lu, bytes_to_read %lu", getpid (),
1780 out_fd, out_fd, func_str, sid, sid, results, n_bytes_left,
1781 bytes_to_read);
1782
1783 if (bytes_to_read == 0)
1784 {
1785 if (flags & O_NONBLOCK)
1786 {
1787 if (!results)
1788 {
Dave Wallace2a865272018-02-07 21:00:42 -05001789 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001790 clib_warning ("LDP<%d>: fd %d (0x%x): sid %u (0x%x): "
1791 "EAGAIN",
1792 getpid (), out_fd, out_fd, sid, sid);
1793 eagain = 1;
1794 }
1795 goto update_offset;
1796 }
1797 else
1798 continue;
1799 }
1800 bytes_to_read = clib_min (n_bytes_left, bytes_to_read);
Dave Wallace2a865272018-02-07 21:00:42 -05001801 vec_validate (ldp->io_buffer, bytes_to_read);
1802 nbytes = libc_read (in_fd, ldp->io_buffer, bytes_to_read);
Dave Wallace048b1d62018-01-03 22:24:41 -05001803 if (nbytes < 0)
1804 {
1805 func_str = "libc_read";
1806 errno_val = errno;
1807 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): in_fd (%d), "
1808 "io_buffer %p, bytes_to_read %lu, rv %d, "
1809 "errno %d", getpid (), out_fd, out_fd, func_str,
Dave Wallace2a865272018-02-07 21:00:42 -05001810 in_fd, ldp->io_buffer, bytes_to_read, nbytes,
Dave Wallace048b1d62018-01-03 22:24:41 -05001811 errno_val);
1812 errno = errno_val;
1813
1814 if (results == 0)
1815 {
Dave Wallace2a865272018-02-07 21:00:42 -05001816 vec_reset_length (ldp->io_buffer);
Dave Wallace048b1d62018-01-03 22:24:41 -05001817 size = -1;
1818 goto done;
1819 }
1820 goto update_offset;
1821 }
1822 func_str = "vppcom_session_write";
Dave Wallace2a865272018-02-07 21:00:42 -05001823 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001824 clib_warning
1825 ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), "
1826 "buf %p, nbytes %u: results %d, n_bytes_left %d", getpid (),
Dave Wallace2a865272018-02-07 21:00:42 -05001827 out_fd, out_fd, func_str, sid, sid, ldp->io_buffer, nbytes,
Dave Wallace048b1d62018-01-03 22:24:41 -05001828 results, n_bytes_left);
1829
Dave Wallace2a865272018-02-07 21:00:42 -05001830 size = vppcom_session_write (sid, ldp->io_buffer, nbytes);
Dave Wallace048b1d62018-01-03 22:24:41 -05001831 if (size < 0)
1832 {
1833 if (size == VPPCOM_EAGAIN)
1834 {
1835 if (flags & O_NONBLOCK)
1836 {
1837 if (!results)
1838 {
Dave Wallace2a865272018-02-07 21:00:42 -05001839 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001840 clib_warning
1841 ("LDP<%d>: fd %d (0x%x): sid %u (0x%x): "
1842 "EAGAIN", getpid (), out_fd, out_fd, sid, sid);
1843 eagain = 1;
1844 }
1845 goto update_offset;
1846 }
1847 else
1848 continue;
1849 }
1850 else
1851 {
1852 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s():"
1853 "sid %u, io_buffer %p, nbytes %u "
1854 "returned %d (%s)",
1855 getpid (), out_fd, out_fd, func_str,
Dave Wallace2a865272018-02-07 21:00:42 -05001856 sid, ldp->io_buffer, nbytes,
Dave Wallace048b1d62018-01-03 22:24:41 -05001857 size, vppcom_retval_str (size));
1858 }
1859 if (results == 0)
1860 {
Dave Wallace2a865272018-02-07 21:00:42 -05001861 vec_reset_length (ldp->io_buffer);
Dave Wallace048b1d62018-01-03 22:24:41 -05001862 errno = -size;
1863 size = -1;
1864 goto done;
1865 }
1866 goto update_offset;
1867 }
1868
1869 results += nbytes;
1870 ASSERT (n_bytes_left >= nbytes);
1871 n_bytes_left = n_bytes_left - nbytes;
1872 }
1873 while (n_bytes_left > 0);
1874
1875 update_offset:
Dave Wallace2a865272018-02-07 21:00:42 -05001876 vec_reset_length (ldp->io_buffer);
Dave Wallace048b1d62018-01-03 22:24:41 -05001877 if (offset)
1878 {
1879 off_t off = lseek (in_fd, *offset, SEEK_SET);
1880 if (PREDICT_FALSE (off == -1))
1881 {
1882 func_str = "lseek";
1883 errno_val = errno;
1884 clib_warning ("LDP<%d>: ERROR: %s(): SEEK_SET failed: "
1885 "in_fd %d, offset %p, *offset %ld, "
1886 "rv %ld, errno %d", getpid (), in_fd,
1887 offset, *offset, off, errno_val);
1888 errno = errno_val;
1889 size = -1;
1890 goto done;
1891 }
1892
1893 ASSERT (off == *offset);
1894 *offset += results + 1;
1895 }
1896 if (eagain)
1897 {
1898 errno = EAGAIN;
1899 size = -1;
1900 }
1901 else
1902 size = results;
1903 }
1904 else
1905 {
1906 func_str = "libc_send";
1907
Dave Wallace2a865272018-02-07 21:00:42 -05001908 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001909 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1910 "in_fd %d, offset %p, len %u",
1911 getpid (), out_fd, out_fd, func_str,
1912 in_fd, offset, len);
1913
1914 size = libc_sendfile (out_fd, in_fd, offset, len);
1915 }
1916
1917done:
Dave Wallace2a865272018-02-07 21:00:42 -05001918 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001919 {
1920 if (size < 0)
1921 {
1922 int errno_val = errno;
1923 perror (func_str);
1924 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
1925 "rv %d, errno = %d", getpid (), out_fd, out_fd,
1926 func_str, size, errno_val);
1927 errno = errno_val;
1928 }
1929 else
1930 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
1931 getpid (), out_fd, out_fd, size, size);
1932 }
1933 return size;
1934}
1935
1936ssize_t
1937sendfile64 (int out_fd, int in_fd, off_t * offset, size_t len)
1938{
1939 return sendfile (out_fd, in_fd, offset, len);
1940}
1941
1942ssize_t
1943recv (int fd, void *buf, size_t n, int flags)
1944{
1945 ssize_t size;
1946 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05001947 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05001948
Dave Wallace2a865272018-02-07 21:00:42 -05001949 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001950 return -1;
1951
1952 if (sid != INVALID_SESSION_ID)
1953 {
1954 func_str = "vppcom_session_recvfrom";
1955
Dave Wallace2a865272018-02-07 21:00:42 -05001956 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001957 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1958 "sid %u (0x%x), buf %p, n %u, flags 0x%x", getpid (),
1959 fd, fd, func_str, sid, sid, buf, n, flags);
1960
1961 size = vppcom_session_recvfrom (sid, buf, n, flags, NULL);
1962 if (size < 0)
1963 {
1964 errno = -size;
1965 size = -1;
1966 }
1967 }
1968 else
1969 {
1970 func_str = "libc_recv";
1971
Dave Wallace2a865272018-02-07 21:00:42 -05001972 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001973 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1974 "buf %p, n %u, flags 0x%x", getpid (),
1975 fd, fd, func_str, buf, n, flags);
1976
1977 size = libc_recv (fd, buf, n, flags);
1978 }
1979
Dave Wallace2a865272018-02-07 21:00:42 -05001980 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001981 {
1982 if (size < 0)
1983 {
1984 int errno_val = errno;
1985 perror (func_str);
1986 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
1987 "rv %d, errno = %d", getpid (), fd, fd,
1988 func_str, size, errno_val);
1989 errno = errno_val;
1990 }
1991 else
1992 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
1993 getpid (), fd, fd, size, size);
1994 }
1995 return size;
1996}
1997
1998ssize_t
1999sendto (int fd, const void *buf, size_t n, int flags,
2000 __CONST_SOCKADDR_ARG addr, socklen_t addr_len)
2001{
2002 ssize_t size;
2003 const char *func_str = __func__;
Dave Wallace2a865272018-02-07 21:00:42 -05002004 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05002005
Dave Wallace2a865272018-02-07 21:00:42 -05002006 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002007 return -1;
2008
2009 if (sid != INVALID_SESSION_ID)
2010 {
2011 vppcom_endpt_t *ep = 0;
2012 vppcom_endpt_t _ep;
2013
2014 if (addr)
2015 {
2016 ep = &_ep;
Dave Wallace048b1d62018-01-03 22:24:41 -05002017 switch (addr->sa_family)
2018 {
2019 case AF_INET:
2020 ep->is_ip4 = VPPCOM_IS_IP4;
2021 ep->ip =
2022 (uint8_t *) & ((const struct sockaddr_in *) addr)->sin_addr;
2023 ep->port =
2024 (uint16_t) ((const struct sockaddr_in *) addr)->sin_port;
2025 break;
2026
2027 case AF_INET6:
2028 ep->is_ip4 = VPPCOM_IS_IP6;
2029 ep->ip =
2030 (uint8_t *) & ((const struct sockaddr_in6 *) addr)->sin6_addr;
2031 ep->port =
2032 (uint16_t) ((const struct sockaddr_in6 *) addr)->sin6_port;
2033 break;
2034
2035 default:
2036 errno = EAFNOSUPPORT;
2037 size = -1;
2038 goto done;
2039 }
2040 }
2041
2042 func_str = "vppcom_session_sendto";
2043
Dave Wallace2a865272018-02-07 21:00:42 -05002044 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002045 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2046 "sid %u (0x%x), buf %p, n %u, flags 0x%x, ep %p",
2047 getpid (), fd, fd, func_str, sid, sid, buf, n,
2048 flags, ep);
2049
2050 size = vppcom_session_sendto (sid, (void *) buf, n, flags, ep);
2051 if (size < 0)
2052 {
2053 errno = -size;
2054 size = -1;
2055 }
2056 }
2057 else
2058 {
2059 func_str = "libc_sendto";
2060
Dave Wallace2a865272018-02-07 21:00:42 -05002061 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002062 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2063 "buf %p, n %u, flags 0x%x, addr %p, addr_len %d",
2064 getpid (), fd, fd, func_str, buf, n, flags,
2065 addr, addr_len);
2066
2067 size = libc_sendto (fd, buf, n, flags, addr, addr_len);
2068 }
2069
2070done:
Dave Wallace2a865272018-02-07 21:00:42 -05002071 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002072 {
2073 if (size < 0)
2074 {
2075 int errno_val = errno;
2076 perror (func_str);
2077 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2078 "rv %d, errno = %d", getpid (), fd, fd,
2079 func_str, size, errno_val);
2080 errno = errno_val;
2081 }
2082 else
2083 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2084 getpid (), fd, fd, size, size);
2085 }
2086 return size;
2087}
2088
2089ssize_t
2090recvfrom (int fd, void *__restrict buf, size_t n, int flags,
2091 __SOCKADDR_ARG addr, socklen_t * __restrict addr_len)
2092{
2093 ssize_t size;
2094 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05002095 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05002096
Dave Wallace2a865272018-02-07 21:00:42 -05002097 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002098 return -1;
2099
2100 if (sid != INVALID_SESSION_ID)
2101 {
2102 vppcom_endpt_t ep;
2103 u8 src_addr[sizeof (struct sockaddr_in6)];
2104
2105 func_str = "vppcom_session_recvfrom";
2106
Dave Wallace2a865272018-02-07 21:00:42 -05002107 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002108 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2109 "sid %u (0x%x), buf %p, n %u, flags 0x%x, ep %p",
2110 getpid (), fd, fd, func_str, sid, sid, buf, n,
2111 flags, &ep);
2112 if (addr)
2113 {
2114 ep.ip = src_addr;
2115 size = vppcom_session_recvfrom (sid, buf, n, flags, &ep);
2116
2117 if (size > 0)
Dave Wallace2a865272018-02-07 21:00:42 -05002118 size = ldp_copy_ep_to_sockaddr (addr, addr_len, &ep);
Dave Wallace048b1d62018-01-03 22:24:41 -05002119 }
2120 else
2121 size = vppcom_session_recvfrom (sid, buf, n, flags, NULL);
2122
2123 if (size < 0)
2124 {
2125 errno = -size;
2126 size = -1;
2127 }
2128 }
2129 else
2130 {
2131 func_str = "libc_recvfrom";
2132
Dave Wallace2a865272018-02-07 21:00:42 -05002133 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002134 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2135 "buf %p, n %u, flags 0x%x, addr %p, addr_len %d",
2136 getpid (), fd, fd, func_str, buf, n, flags,
2137 addr, addr_len);
2138
2139 size = libc_recvfrom (fd, buf, n, flags, addr, addr_len);
2140 }
2141
Dave Wallace2a865272018-02-07 21:00:42 -05002142 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002143 {
2144 if (size < 0)
2145 {
2146 int errno_val = errno;
2147 perror (func_str);
2148 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2149 "rv %d, errno = %d", getpid (), fd, fd,
2150 func_str, size, errno_val);
2151 errno = errno_val;
2152 }
2153 else
2154 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2155 getpid (), fd, fd, size, size);
2156 }
2157 return size;
2158}
2159
2160ssize_t
2161sendmsg (int fd, const struct msghdr * message, int flags)
2162{
2163 ssize_t size;
2164 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05002165 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05002166
Dave Wallace2a865272018-02-07 21:00:42 -05002167 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002168 return -1;
2169
2170 if (sid != INVALID_SESSION_ID)
2171 {
Dave Wallace8aaba562018-01-18 17:21:19 -05002172 func_str = __func__;
2173
Dave Wallace048b1d62018-01-03 22:24:41 -05002174 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
2175 errno = ENOSYS;
2176 size = -1;
2177 }
2178 else
2179 {
2180 func_str = "libc_sendmsg";
2181
Dave Wallace2a865272018-02-07 21:00:42 -05002182 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002183 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2184 "message %p, flags 0x%x",
2185 getpid (), fd, fd, func_str, message, flags);
2186
2187 size = libc_sendmsg (fd, message, flags);
2188 }
2189
Dave Wallace2a865272018-02-07 21:00:42 -05002190 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002191 {
2192 if (size < 0)
2193 {
2194 int errno_val = errno;
2195 perror (func_str);
2196 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2197 "rv %d, errno = %d", getpid (), fd, fd,
2198 func_str, size, errno_val);
2199 errno = errno_val;
2200 }
2201 else
2202 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2203 getpid (), fd, fd, size, size);
2204 }
2205 return size;
2206}
2207
2208#ifdef USE_GNU
2209int
2210sendmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags)
2211{
2212 ssize_t size;
2213 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05002214 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05002215
Dave Wallace2a865272018-02-07 21:00:42 -05002216 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002217 return -1;
2218
2219 if (sid != INVALID_SESSION_ID)
2220 {
2221 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
2222 errno = ENOSYS;
2223 size = -1;
2224 }
2225 else
2226 {
2227 func_str = "libc_sendmmsg";
2228
Dave Wallace2a865272018-02-07 21:00:42 -05002229 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002230 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2231 "vmessages %p, vlen %u, flags 0x%x",
2232 getpid (), fd, fd, func_str, vmessages, vlen, flags);
2233
2234 size = libc_sendmmsg (fd, vmessages, vlen, flags);
2235 }
2236
Dave Wallace2a865272018-02-07 21:00:42 -05002237 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002238 {
2239 if (size < 0)
2240 {
2241 int errno_val = errno;
2242 perror (func_str);
2243 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2244 "rv %d, errno = %d", getpid (), fd, fd,
2245 func_str, size, errno_val);
2246 errno = errno_val;
2247 }
2248 else
2249 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2250 getpid (), fd, fd, size, size);
2251 }
2252 return size;
2253}
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002254#endif
2255
Dave Wallace048b1d62018-01-03 22:24:41 -05002256ssize_t
2257recvmsg (int fd, struct msghdr * message, int flags)
2258{
2259 ssize_t size;
2260 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05002261 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05002262
Dave Wallace2a865272018-02-07 21:00:42 -05002263 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002264 return -1;
2265
2266 if (sid != INVALID_SESSION_ID)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002267 {
Dave Wallace8aaba562018-01-18 17:21:19 -05002268 func_str = __func__;
2269
Dave Wallace048b1d62018-01-03 22:24:41 -05002270 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
2271 errno = ENOSYS;
2272 size = -1;
2273 }
2274 else
2275 {
2276 func_str = "libc_recvmsg";
2277
Dave Wallace2a865272018-02-07 21:00:42 -05002278 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002279 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2280 "message %p, flags 0x%x",
2281 getpid (), fd, fd, func_str, message, flags);
2282
2283 size = libc_recvmsg (fd, message, flags);
2284 }
2285
Dave Wallace2a865272018-02-07 21:00:42 -05002286 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002287 {
2288 if (size < 0)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002289 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002290 int errno_val = errno;
2291 perror (func_str);
2292 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2293 "rv %d, errno = %d", getpid (), fd, fd,
2294 func_str, size, errno_val);
2295 errno = errno_val;
2296 }
2297 else
2298 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2299 getpid (), fd, fd, size, size);
2300 }
2301 return size;
2302}
2303
2304#ifdef USE_GNU
2305int
2306recvmmsg (int fd, struct mmsghdr *vmessages,
2307 unsigned int vlen, int flags, struct timespec *tmo)
2308{
2309 ssize_t size;
2310 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05002311 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05002312
Dave Wallace2a865272018-02-07 21:00:42 -05002313 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002314 return -1;
2315
2316 if (sid != INVALID_SESSION_ID)
2317 {
2318 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
2319 errno = ENOSYS;
2320 size = -1;
2321 }
2322 else
2323 {
2324 func_str = "libc_recvmmsg";
2325
Dave Wallace2a865272018-02-07 21:00:42 -05002326 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002327 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2328 "vmessages %p, vlen %u, flags 0x%x, tmo %p",
2329 getpid (), fd, fd, func_str, vmessages, vlen,
2330 flags, tmo);
2331
2332 size = libc_recvmmsg (fd, vmessages, vlen, flags, tmo);
2333 }
2334
Dave Wallace2a865272018-02-07 21:00:42 -05002335 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002336 {
2337 if (size < 0)
2338 {
2339 int errno_val = errno;
2340 perror (func_str);
2341 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2342 "rv %d, errno = %d", getpid (), fd, fd,
2343 func_str, size, errno_val);
2344 errno = errno_val;
2345 }
2346 else
2347 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2348 getpid (), fd, fd, size, size);
2349 }
2350 return size;
2351}
2352#endif
2353
2354int
2355getsockopt (int fd, int level, int optname,
2356 void *__restrict optval, socklen_t * __restrict optlen)
2357{
2358 int rv;
2359 const char *func_str = __func__;
Dave Wallace2a865272018-02-07 21:00:42 -05002360 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace8aaba562018-01-18 17:21:19 -05002361 u32 buflen = optlen ? (u32) * optlen : 0;
Dave Wallace048b1d62018-01-03 22:24:41 -05002362
Dave Wallace2a865272018-02-07 21:00:42 -05002363 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002364 return -1;
2365
2366 if (sid != INVALID_SESSION_ID)
2367 {
2368 rv = -EOPNOTSUPP;
2369
2370 switch (level)
2371 {
2372 case SOL_TCP:
2373 switch (optname)
2374 {
2375 case TCP_NODELAY:
2376 func_str = "vppcom_session_attr[SOL_TCP,GET_TCP_NODELAY]";
Dave Wallace2a865272018-02-07 21:00:42 -05002377 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002378 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2379 "sid %u (0x%x)",
2380 getpid (), fd, fd, func_str, sid, sid);
2381 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_TCP_NODELAY,
2382 optval, optlen);
2383 break;
2384 case TCP_MAXSEG:
2385 func_str = "vppcom_session_attr[SOL_TCP,GET_TCP_USER_MSS]";
Dave Wallace2a865272018-02-07 21:00:42 -05002386 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002387 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2388 "sid %u (0x%x)",
2389 getpid (), fd, fd, func_str, sid, sid);
2390 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_TCP_USER_MSS,
2391 optval, optlen);
2392 break;
2393 case TCP_KEEPIDLE:
2394 func_str = "vppcom_session_attr[SOL_TCP,GET_TCP_KEEPIDLE]";
Dave Wallace2a865272018-02-07 21:00:42 -05002395 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002396 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2397 "sid %u (0x%x)",
2398 getpid (), fd, fd, func_str, sid, sid);
2399 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_TCP_KEEPIDLE,
2400 optval, optlen);
2401 break;
2402 case TCP_KEEPINTVL:
2403 func_str = "vppcom_session_attr[SOL_TCP,GET_TCP_KEEPINTVL]";
Dave Wallace2a865272018-02-07 21:00:42 -05002404 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002405 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2406 "sid %u (0x%x), SOL_TCP",
2407 getpid (), fd, fd, func_str, sid, sid);
2408 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_TCP_KEEPINTVL,
2409 optval, optlen);
2410 break;
2411 case TCP_INFO:
2412 if (optval && optlen && (*optlen == sizeof (struct tcp_info)))
2413 {
Dave Wallace2a865272018-02-07 21:00:42 -05002414 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002415 clib_warning ("LDP<%d>: fd %d (0x%x): sid %u (0x%x), "
2416 "SOL_TCP, TCP_INFO, optval %p, "
2417 "optlen %d: #LDP-NOP#",
2418 getpid (), fd, fd, sid, sid,
2419 optval, *optlen);
2420 memset (optval, 0, *optlen);
2421 rv = VPPCOM_OK;
2422 }
2423 else
2424 rv = -EFAULT;
2425 break;
2426 default:
Dave Wallace2a865272018-02-07 21:00:42 -05002427 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002428 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
2429 "sid %u (0x%x), SOL_TCP, "
2430 "optname %d unsupported!",
2431 getpid (), fd, fd, func_str, sid, sid, optname);
2432 break;
2433 }
2434 break;
2435 case SOL_IPV6:
2436 switch (optname)
2437 {
2438 case IPV6_V6ONLY:
2439 func_str = "vppcom_session_attr[SOL_IPV6,GET_V6ONLY]";
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_V6ONLY,
2445 optval, optlen);
2446 break;
2447 default:
Dave Wallace2a865272018-02-07 21:00:42 -05002448 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002449 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
2450 "sid %u (0x%x), SOL_IPV6, "
2451 "optname %d unsupported!",
2452 getpid (), fd, fd, func_str, sid, sid, optname);
2453 break;
2454 }
2455 break;
2456 case SOL_SOCKET:
2457 switch (optname)
2458 {
2459 case SO_ACCEPTCONN:
2460 func_str = "vppcom_session_attr[SOL_SOCKET,GET_ACCEPTCONN]";
Dave Wallace2a865272018-02-07 21:00:42 -05002461 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002462 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2463 "sid %u (0x%x)",
2464 getpid (), fd, fd, func_str, sid, sid);
2465 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_LISTEN,
2466 optval, optlen);
2467 break;
2468 case SO_KEEPALIVE:
2469 func_str = "vppcom_session_attr[SOL_SOCKET,GET_KEEPALIVE]";
Dave Wallace2a865272018-02-07 21:00:42 -05002470 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002471 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2472 "sid %u (0x%x)",
2473 getpid (), fd, fd, func_str, sid, sid);
2474 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_KEEPALIVE,
2475 optval, optlen);
2476 break;
2477 case SO_PROTOCOL:
2478 func_str = "vppcom_session_attr[SOL_SOCKET,GET_PROTOCOL]";
Dave Wallace2a865272018-02-07 21:00:42 -05002479 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002480 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2481 "sid %u (0x%x)",
2482 getpid (), fd, fd, func_str, sid, sid);
2483 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_PROTOCOL,
2484 optval, optlen);
2485 *(int *) optval = *(int *) optval ? SOCK_DGRAM : SOCK_STREAM;
2486 break;
2487 case SO_SNDBUF:
2488 func_str = "vppcom_session_attr[SOL_SOCKET,GET_TX_FIFO_LEN]";
Dave Wallace2a865272018-02-07 21:00:42 -05002489 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002490 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2491 "sid %u (0x%x), optlen %d",
2492 getpid (), fd, fd, func_str, sid, sid, buflen);
2493 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_TX_FIFO_LEN,
2494 optval, optlen);
2495 break;
2496 case SO_RCVBUF:
2497 func_str = "vppcom_session_attr[SOL_SOCKET,GET_RX_FIFO_LEN]";
Dave Wallace2a865272018-02-07 21:00:42 -05002498 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002499 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2500 "sid %u (0x%x), optlen %d",
Dave Wallaceb4cd4ff2018-01-19 12:17:08 -05002501 getpid (), fd, fd, func_str, sid, sid, buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002502 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_RX_FIFO_LEN,
2503 optval, optlen);
2504 break;
2505 case SO_REUSEADDR:
2506 func_str = "vppcom_session_attr[SOL_SOCKET,GET_REUSEADDR]";
Dave Wallace2a865272018-02-07 21:00:42 -05002507 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002508 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2509 "sid %u (0x%x)",
2510 getpid (), fd, fd, func_str, sid, sid);
2511 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_REUSEADDR,
2512 optval, optlen);
2513 break;
2514 case SO_BROADCAST:
2515 func_str = "vppcom_session_attr[SOL_SOCKET,GET_BROADCAST]";
Dave Wallace2a865272018-02-07 21:00:42 -05002516 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002517 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2518 "sid %u (0x%x)",
2519 getpid (), fd, fd, func_str, sid, sid);
2520 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_BROADCAST,
2521 optval, optlen);
2522 break;
2523 case SO_ERROR:
2524 func_str = "vppcom_session_attr[SOL_SOCKET,GET_ERROR]";
Dave Wallace2a865272018-02-07 21:00:42 -05002525 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002526 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2527 "sid %u (0x%x)",
2528 getpid (), fd, fd, func_str, sid, sid);
2529 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_ERROR,
2530 optval, optlen);
2531 break;
2532 default:
Dave Wallace2a865272018-02-07 21:00:42 -05002533 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002534 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
2535 "sid %u (0x%x), SOL_SOCKET, "
2536 "optname %d unsupported!",
2537 getpid (), fd, fd, func_str, sid, sid, optname);
2538 break;
2539 }
2540 break;
2541 default:
2542 break;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002543 }
2544
Dave Wallace048b1d62018-01-03 22:24:41 -05002545 if (rv != VPPCOM_OK)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002546 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002547 errno = -rv;
2548 rv = -1;
2549 }
2550 }
2551 else
2552 {
2553 func_str = "libc_getsockopt";
2554
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(): level %d, "
2557 "optname %d, optval %p, optlen %d",
2558 getpid (), fd, fd, func_str, level, optname,
2559 optval, optlen);
2560
2561 rv = libc_getsockopt (fd, level, optname, optval, optlen);
2562 }
2563
Dave Wallace2a865272018-02-07 21:00:42 -05002564 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002565 {
2566 if (rv < 0)
2567 {
2568 int errno_val = errno;
2569 perror (func_str);
2570 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2571 "rv %d, errno = %d", getpid (), fd, fd,
2572 func_str, rv, errno_val);
2573 errno = errno_val;
2574 }
2575 else
2576 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2577 getpid (), fd, fd, rv, rv);
2578 }
2579 return rv;
2580}
2581
2582int
2583setsockopt (int fd, int level, int optname,
2584 const void *optval, socklen_t optlen)
2585{
2586 int rv;
2587 const char *func_str = __func__;
Dave Wallace2a865272018-02-07 21:00:42 -05002588 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05002589
Dave Wallace2a865272018-02-07 21:00:42 -05002590 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002591 return -1;
2592
2593 if (sid != INVALID_SESSION_ID)
2594 {
2595 rv = -EOPNOTSUPP;
2596
2597 switch (level)
2598 {
2599 case SOL_TCP:
2600 switch (optname)
2601 {
2602 case TCP_NODELAY:
2603 func_str = "vppcom_session_attr[SOL_TCP,SET_TCP_NODELAY]";
Dave Wallace2a865272018-02-07 21:00:42 -05002604 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002605 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2606 "sid %u (0x%x)",
2607 getpid (), fd, fd, func_str, sid, sid);
2608 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_TCP_NODELAY,
2609 (void *) optval, &optlen);
2610 break;
2611 case TCP_MAXSEG:
2612 func_str = "vppcom_session_attr[SOL_TCP,SET_TCP_USER_MSS]";
Dave Wallace2a865272018-02-07 21:00:42 -05002613 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002614 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2615 "sid %u (0x%x)",
2616 getpid (), fd, fd, func_str, sid, sid);
2617 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_TCP_USER_MSS,
2618 (void *) optval, &optlen);
2619 break;
2620 case TCP_KEEPIDLE:
2621 func_str = "vppcom_session_attr[SOL_TCP,SET_TCP_KEEPIDLE]";
Dave Wallace2a865272018-02-07 21:00:42 -05002622 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002623 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2624 "sid %u (0x%x)",
2625 getpid (), fd, fd, func_str, sid, sid);
2626 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_TCP_KEEPIDLE,
2627 (void *) optval, &optlen);
2628 break;
2629 case TCP_KEEPINTVL:
2630 func_str = "vppcom_session_attr[SOL_TCP,SET_TCP_KEEPINTVL]";
Dave Wallace2a865272018-02-07 21:00:42 -05002631 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002632 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2633 "sid %u (0x%x), SOL_TCP",
2634 getpid (), fd, fd, func_str, sid, sid);
2635 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_TCP_KEEPINTVL,
2636 (void *) optval, &optlen);
2637 break;
2638 default:
Dave Wallace2a865272018-02-07 21:00:42 -05002639 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002640 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
2641 "sid %u (0x%x), SOL_TCP, "
2642 "optname %d unsupported!",
2643 getpid (), fd, fd, func_str, sid, sid, optname);
2644 break;
2645 }
2646 break;
2647 case SOL_IPV6:
2648 switch (optname)
2649 {
2650 case IPV6_V6ONLY:
2651 func_str = "vppcom_session_attr[SOL_IPV6,SET_V6ONLY]";
Dave Wallace2a865272018-02-07 21:00:42 -05002652 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002653 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2654 "sid %u (0x%x)",
2655 getpid (), fd, fd, func_str, sid, sid);
2656 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_V6ONLY,
2657 (void *) optval, &optlen);
2658 break;
2659 default:
Dave Wallace2a865272018-02-07 21:00:42 -05002660 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002661 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
2662 "sid %u (0x%x), SOL_IPV6, "
2663 "optname %d unsupported!",
2664 getpid (), fd, fd, func_str, sid, sid, optname);
2665 break;
2666 }
2667 break;
2668 case SOL_SOCKET:
2669 switch (optname)
2670 {
2671 case SO_KEEPALIVE:
2672 func_str = "vppcom_session_attr[SOL_SOCKET,SET_KEEPALIVE]";
Dave Wallace2a865272018-02-07 21:00:42 -05002673 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002674 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2675 "sid %u (0x%x)",
2676 getpid (), fd, fd, func_str, sid, sid);
2677 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_KEEPALIVE,
2678 (void *) optval, &optlen);
2679 break;
2680 case SO_REUSEADDR:
2681 func_str = "vppcom_session_attr[SOL_SOCKET,SET_REUSEADDR]";
Dave Wallace2a865272018-02-07 21:00:42 -05002682 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002683 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2684 "sid %u (0x%x)",
2685 getpid (), fd, fd, func_str, sid, sid);
2686 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_REUSEADDR,
2687 (void *) optval, &optlen);
2688 break;
2689 case SO_BROADCAST:
2690 func_str = "vppcom_session_attr[SOL_SOCKET,SET_BROADCAST]";
Dave Wallace2a865272018-02-07 21:00:42 -05002691 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002692 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2693 "sid %u (0x%x)",
2694 getpid (), fd, fd, func_str, sid, sid);
2695 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_BROADCAST,
2696 (void *) optval, &optlen);
2697 break;
2698 default:
Dave Wallace2a865272018-02-07 21:00:42 -05002699 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002700 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
2701 "sid %u (0x%x), SOL_SOCKET, "
2702 "optname %d unsupported!",
2703 getpid (), fd, fd, func_str, sid, sid, optname);
2704 break;
2705 }
2706 break;
2707 default:
2708 break;
2709 }
2710
2711 if (rv != VPPCOM_OK)
2712 {
2713 errno = -rv;
2714 rv = -1;
2715 }
2716 }
2717 else
2718 {
2719 func_str = "libc_setsockopt";
2720
Dave Wallace2a865272018-02-07 21:00:42 -05002721 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002722 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): level %d, "
2723 "optname %d, optval %p, optlen %d",
2724 getpid (), fd, fd, func_str, level, optname,
2725 optval, optlen);
2726
2727 rv = libc_setsockopt (fd, level, optname, optval, optlen);
2728 }
2729
Dave Wallace2a865272018-02-07 21:00:42 -05002730 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002731 {
2732 if (rv < 0)
2733 {
2734 int errno_val = errno;
2735 perror (func_str);
2736 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2737 "rv %d, errno = %d", getpid (), fd, fd,
2738 func_str, rv, errno_val);
2739 errno = errno_val;
2740 }
2741 else
2742 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2743 getpid (), fd, fd, rv, rv);
2744 }
2745 return rv;
2746}
2747
2748int
2749listen (int fd, int n)
2750{
2751 int rv;
2752 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05002753 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05002754
Dave Wallace2a865272018-02-07 21:00:42 -05002755 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002756 return -1;
2757
2758 if (sid != INVALID_SESSION_ID)
2759 {
2760 func_str = "vppcom_session_listen";
2761
Florin Coras99368312018-08-02 10:45:44 -07002762 LDBG (0, "LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), n %d",
2763 getpid (), fd, fd, func_str, sid, sid, n);
Dave Wallace048b1d62018-01-03 22:24:41 -05002764
2765 rv = vppcom_session_listen (sid, n);
2766 if (rv != VPPCOM_OK)
2767 {
2768 errno = -rv;
2769 rv = -1;
2770 }
2771 }
2772 else
2773 {
2774 func_str = "libc_listen";
2775
Florin Coras99368312018-08-02 10:45:44 -07002776 LDBG (0, "LDP<%d>: fd %d (0x%x): calling %s(): n %d", getpid (), fd,
2777 fd, func_str, n);
Dave Wallace048b1d62018-01-03 22:24:41 -05002778
2779 rv = libc_listen (fd, n);
2780 }
2781
Dave Wallace2a865272018-02-07 21:00:42 -05002782 if (LDP_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002783 {
2784 if (rv < 0)
2785 {
2786 int errno_val = errno;
2787 perror (func_str);
2788 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2789 "rv %d, errno = %d", getpid (), fd, fd,
2790 func_str, rv, errno_val);
2791 errno = errno_val;
2792 }
2793 else
2794 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2795 getpid (), fd, fd, rv, rv);
2796 }
2797 return rv;
2798}
2799
2800static inline int
Dave Wallace2a865272018-02-07 21:00:42 -05002801ldp_accept4 (int listen_fd, __SOCKADDR_ARG addr,
2802 socklen_t * __restrict addr_len, int flags)
Dave Wallace048b1d62018-01-03 22:24:41 -05002803{
2804 int rv;
2805 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05002806 u32 listen_sid = ldp_sid_from_fd (listen_fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05002807 int accept_sid;
2808
Dave Wallace2a865272018-02-07 21:00:42 -05002809 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002810 return -1;
2811
2812 if (listen_sid != INVALID_SESSION_ID)
2813 {
2814 vppcom_endpt_t ep;
2815 u8 src_addr[sizeof (struct sockaddr_in6)];
Dave Wallace8aaba562018-01-18 17:21:19 -05002816 memset (&ep, 0, sizeof (ep));
Dave Wallace048b1d62018-01-03 22:24:41 -05002817 ep.ip = src_addr;
2818
2819 func_str = "vppcom_session_accept";
2820
Dave Wallace2a865272018-02-07 21:00:42 -05002821 if (LDP_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002822 clib_warning ("LDP<%d>: listen fd %d (0x%x): calling %s(): "
2823 "listen sid %u (0x%x), ep %p, flags 0x%x",
2824 getpid (), listen_fd, listen_fd, func_str,
2825 listen_sid, listen_sid, ep, flags);
2826
2827 accept_sid = vppcom_session_accept (listen_sid, &ep, flags);
2828 if (accept_sid < 0)
2829 {
2830 errno = -accept_sid;
2831 rv = -1;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002832 }
2833 else
2834 {
Dave Wallace2a865272018-02-07 21:00:42 -05002835 rv = ldp_copy_ep_to_sockaddr (addr, addr_len, &ep);
Dave Wallace048b1d62018-01-03 22:24:41 -05002836 if (rv != VPPCOM_OK)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002837 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002838 (void) vppcom_session_close ((u32) accept_sid);
2839 errno = -rv;
2840 rv = -1;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002841 }
Dave Wallace048b1d62018-01-03 22:24:41 -05002842 else
2843 {
Dave Wallace2a865272018-02-07 21:00:42 -05002844 func_str = "ldp_fd_from_sid";
2845 if (LDP_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002846 clib_warning ("LDP<%d>: listen fd %d (0x%x): calling %s(): "
2847 "accept sid %u (0x%x), ep %p, flags 0x%x",
2848 getpid (), listen_fd, listen_fd,
2849 func_str, accept_sid, accept_sid, ep, flags);
Dave Wallace2a865272018-02-07 21:00:42 -05002850 rv = ldp_fd_from_sid ((u32) accept_sid);
Dave Wallace048b1d62018-01-03 22:24:41 -05002851 if (rv < 0)
2852 {
2853 (void) vppcom_session_close ((u32) accept_sid);
2854 errno = -rv;
2855 rv = -1;
2856 }
2857 }
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002858 }
2859 }
Dave Wallace048b1d62018-01-03 22:24:41 -05002860 else
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002861 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002862 func_str = "libc_accept4";
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002863
Dave Wallace2a865272018-02-07 21:00:42 -05002864 if (LDP_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002865 clib_warning ("LDP<%d>: listen fd %d (0x%x): calling %s(): "
2866 "addr %p, addr_len %p, flags 0x%x",
2867 getpid (), listen_fd, listen_fd, func_str,
2868 addr, addr_len, flags);
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002869
Dave Wallace048b1d62018-01-03 22:24:41 -05002870 rv = libc_accept4 (listen_fd, addr, addr_len, flags);
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002871 }
2872
Dave Wallace2a865272018-02-07 21:00:42 -05002873 if (LDP_DEBUG > 0)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002874 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002875 if (rv < 0)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002876 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002877 int errno_val = errno;
2878 perror (func_str);
2879 clib_warning ("LDP<%d>: ERROR: listen fd %d (0x%x): %s() failed! "
2880 "rv %d, errno = %d", getpid (), listen_fd,
2881 listen_fd, func_str, rv, errno_val);
2882 errno = errno_val;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002883 }
Dave Wallace048b1d62018-01-03 22:24:41 -05002884 else
2885 clib_warning ("LDP<%d>: listen fd %d (0x%x): returning %d (0x%x)",
2886 getpid (), listen_fd, listen_fd, rv, rv);
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002887 }
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002888 return rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002889}
2890
Dave Wallace048b1d62018-01-03 22:24:41 -05002891int
2892accept4 (int fd, __SOCKADDR_ARG addr, socklen_t * __restrict addr_len,
2893 int flags)
2894{
Dave Wallace2a865272018-02-07 21:00:42 -05002895 return ldp_accept4 (fd, addr, addr_len, flags);
Dave Wallace048b1d62018-01-03 22:24:41 -05002896}
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002897
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002898int
Dave Wallace048b1d62018-01-03 22:24:41 -05002899accept (int fd, __SOCKADDR_ARG addr, socklen_t * __restrict addr_len)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002900{
Dave Wallace2a865272018-02-07 21:00:42 -05002901 return ldp_accept4 (fd, addr, addr_len, 0);
Dave Wallace048b1d62018-01-03 22:24:41 -05002902}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002903
Dave Wallace048b1d62018-01-03 22:24:41 -05002904int
2905shutdown (int fd, int how)
2906{
2907 int rv;
2908 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05002909 u32 sid = ldp_sid_from_fd (fd);
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002910
Dave Wallace2a865272018-02-07 21:00:42 -05002911 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002912 return -1;
2913
2914 if (sid != INVALID_SESSION_ID)
2915 {
Dave Wallace8aaba562018-01-18 17:21:19 -05002916 func_str = __func__;
2917
Dave Wallace048b1d62018-01-03 22:24:41 -05002918 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
2919 errno = ENOSYS;
2920 rv = -1;
2921 }
2922 else
2923 {
2924 func_str = "libc_shutdown";
2925
Dave Wallace2a865272018-02-07 21:00:42 -05002926 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002927 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): how %d",
2928 getpid (), fd, fd, func_str, how);
2929
2930 rv = libc_shutdown (fd, how);
2931 }
2932
Dave Wallace2a865272018-02-07 21:00:42 -05002933 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002934 {
2935 if (rv < 0)
2936 {
2937 int errno_val = errno;
2938 perror (func_str);
2939 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2940 "rv %d, errno = %d", getpid (), fd, fd,
2941 func_str, rv, errno_val);
2942 errno = errno_val;
2943 }
2944 else
2945 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2946 getpid (), fd, fd, rv, rv);
2947 }
2948 return rv;
2949}
2950
2951int
2952epoll_create1 (int flags)
2953{
2954 const char *func_str;
2955 int rv;
2956
Dave Wallace2a865272018-02-07 21:00:42 -05002957 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002958 return -1;
2959
Florin Coras99368312018-08-02 10:45:44 -07002960 if (ldp->vcl_needs_real_epoll)
2961 {
2962 rv = libc_epoll_create1 (flags);
2963 ldp->vcl_needs_real_epoll = 0;
2964 ldp->vcl_mq_epfd = rv;
2965 LDBG (0, "LDP<%d>: created vcl epfd %u", getpid (), rv);
2966 return rv;
2967 }
Dave Wallace048b1d62018-01-03 22:24:41 -05002968 func_str = "vppcom_epoll_create";
2969
Florin Coras99368312018-08-02 10:45:44 -07002970 LDBG (1, "LDP<%d>: calling %s()", getpid (), func_str);
Dave Wallace048b1d62018-01-03 22:24:41 -05002971
2972 rv = vppcom_epoll_create ();
2973
2974 if (PREDICT_FALSE (rv < 0))
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002975 {
2976 errno = -rv;
Dave Wallace048b1d62018-01-03 22:24:41 -05002977 rv = -1;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002978 }
Dave Wallace048b1d62018-01-03 22:24:41 -05002979 else
Dave Wallace2a865272018-02-07 21:00:42 -05002980 rv = ldp_fd_from_sid ((u32) rv);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002981
Dave Wallace2a865272018-02-07 21:00:42 -05002982 if (LDP_DEBUG > 1)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002983 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002984 if (rv < 0)
2985 {
2986 int errno_val = errno;
2987 perror (func_str);
2988 clib_warning ("LDP<%d>: ERROR: %s() failed! "
2989 "rv %d, errno = %d",
2990 getpid (), func_str, rv, errno_val);
2991 errno = errno_val;
2992 }
2993 else
2994 clib_warning ("LDP<%d>: returning epfd %d (0x%x)", getpid (), rv, rv);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002995 }
Dave Wallace048b1d62018-01-03 22:24:41 -05002996 return rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002997}
2998
2999int
Dave Wallace048b1d62018-01-03 22:24:41 -05003000epoll_create (int size)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003001{
Dave Wallace048b1d62018-01-03 22:24:41 -05003002 return epoll_create1 (0);
3003}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003004
Dave Wallace048b1d62018-01-03 22:24:41 -05003005int
3006epoll_ctl (int epfd, int op, int fd, struct epoll_event *event)
3007{
Florin Coras99368312018-08-02 10:45:44 -07003008 u32 vep_idx = ldp_sid_from_fd (epfd), sid;
Dave Wallace048b1d62018-01-03 22:24:41 -05003009 const char *func_str;
Florin Coras99368312018-08-02 10:45:44 -07003010 int rv;
Dave Wallace048b1d62018-01-03 22:24:41 -05003011
Dave Wallace2a865272018-02-07 21:00:42 -05003012 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05003013 return -1;
3014
Florin Coras99368312018-08-02 10:45:44 -07003015 if (PREDICT_FALSE (vep_idx == INVALID_SESSION_ID))
Dave Wallace048b1d62018-01-03 22:24:41 -05003016 {
Dave Wallace3ee1fe12018-02-23 01:09:11 -05003017 /* The LDP epoll_create1 always creates VCL epfd's.
3018 * The app should never have a kernel base epoll fd unless it
3019 * was acquired outside of the LD_PRELOAD process context.
3020 * In any case, if we get one, punt it to libc_epoll_ctl.
3021 */
Dave Wallace048b1d62018-01-03 22:24:41 -05003022 func_str = "libc_epoll_ctl";
3023
Florin Coras99368312018-08-02 10:45:44 -07003024 LDBG (1, "LDP<%d>: epfd %d (0x%x): calling %s(): op %d, fd %d (0x%x),"
3025 " event %p", getpid (), epfd, epfd, func_str, op, fd, fd, event);
Dave Wallace048b1d62018-01-03 22:24:41 -05003026
3027 rv = libc_epoll_ctl (epfd, op, fd, event);
Florin Coras99368312018-08-02 10:45:44 -07003028 goto done;
3029 }
3030
3031 sid = ldp_sid_from_fd (fd);
3032
3033 LDBG (0, "LDP<%d>: epfd %d (0x%x), vep_idx %d (0x%x), sid %d (0x%x)",
3034 getpid (), epfd, epfd, vep_idx, vep_idx, sid, sid);
3035
3036 if (sid != INVALID_SESSION_ID)
3037 {
3038 func_str = "vppcom_epoll_ctl";
3039
3040 LDBG (1, "LDP<%d>: epfd %d (0x%x): calling %s(): vep_idx %d (0x%x),"
3041 " op %d, sid %u (0x%x), event %p", getpid (), epfd, epfd,
3042 func_str, vep_idx, vep_idx, sid, sid, event);
3043
3044 rv = vppcom_epoll_ctl (vep_idx, op, sid, event);
3045 if (rv != VPPCOM_OK)
3046 {
3047 errno = -rv;
3048 rv = -1;
3049 }
3050 }
3051 else
3052 {
3053 int libc_epfd;
3054 u32 size = sizeof (epfd);
3055
3056 func_str = "vppcom_session_attr[GET_LIBC_EPFD]";
3057 libc_epfd = vppcom_session_attr (vep_idx, VPPCOM_ATTR_GET_LIBC_EPFD, 0,
3058 0);
3059 LDBG (1, "LDP<%d>: epfd %d (0x%x), vep_idx %d (0x%x): %s() "
3060 "returned libc_epfd %d (0x%x)", getpid (), epfd, epfd,
3061 vep_idx, vep_idx, func_str, libc_epfd, libc_epfd);
3062
3063 if (!libc_epfd)
3064 {
3065 func_str = "libc_epoll_create1";
3066
3067 LDBG (1, "LDP<%d>: epfd %d (0x%x), vep_idx %d (0x%x): "
3068 "calling %s(): EPOLL_CLOEXEC", getpid (), epfd, epfd,
3069 vep_idx, vep_idx, func_str);
3070
3071 libc_epfd = libc_epoll_create1 (EPOLL_CLOEXEC);
3072 if (libc_epfd < 0)
3073 {
3074 rv = libc_epfd;
3075 goto done;
3076 }
3077
3078 func_str = "vppcom_session_attr[SET_LIBC_EPFD]";
3079 LDBG (1, "LDP<%d>: epfd %d (0x%x): calling %s(): vep_idx %d (0x%x),"
3080 " VPPCOM_ATTR_SET_LIBC_EPFD, libc_epfd %d (0x%x), size %d",
3081 getpid (), epfd, epfd, func_str, vep_idx, vep_idx, libc_epfd,
3082 libc_epfd, size);
3083
3084 rv = vppcom_session_attr (vep_idx, VPPCOM_ATTR_SET_LIBC_EPFD,
3085 &libc_epfd, &size);
3086 if (rv < 0)
3087 {
3088 errno = -rv;
3089 rv = -1;
3090 goto done;
3091 }
3092 }
3093 else if (PREDICT_FALSE (libc_epfd < 0))
3094 {
3095 errno = -epfd;
3096 rv = -1;
3097 goto done;
3098 }
3099
3100 func_str = "libc_epoll_ctl";
3101
3102 LDBG (1, "LDP<%d>: epfd %d (0x%x): calling %s(): libc_epfd %d (0x%x), "
3103 "op %d, fd %d (0x%x), event %p", getpid (), epfd, epfd, func_str,
3104 libc_epfd, libc_epfd, op, fd, fd, event);
3105
3106 rv = libc_epoll_ctl (libc_epfd, op, fd, event);
Dave Wallace048b1d62018-01-03 22:24:41 -05003107 }
3108
3109done:
Dave Wallace2a865272018-02-07 21:00:42 -05003110 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05003111 {
3112 if (rv < 0)
3113 {
3114 int errno_val = errno;
3115 perror (func_str);
3116 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
3117 "rv %d, errno = %d", getpid (), fd, fd,
3118 func_str, rv, errno_val);
3119 errno = errno_val;
3120 }
3121 else
3122 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
3123 getpid (), fd, fd, rv, rv);
3124 }
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003125 return rv;
3126}
Dave Wallace048b1d62018-01-03 22:24:41 -05003127
3128static inline int
Florin Coras99368312018-08-02 10:45:44 -07003129ldp_epoll_pwait (int epfd, struct epoll_event *events, int maxevents,
3130 int timeout, const sigset_t * sigmask)
Dave Wallace048b1d62018-01-03 22:24:41 -05003131{
Florin Coras99368312018-08-02 10:45:44 -07003132 double time_to_wait = (double) 0, time_out, now = 0;
Dave Wallace2a865272018-02-07 21:00:42 -05003133 u32 vep_idx = ldp_sid_from_fd (epfd);
Florin Coras99368312018-08-02 10:45:44 -07003134 int libc_epfd, rv = 0;
3135 const char *func_str;
Dave Wallace048b1d62018-01-03 22:24:41 -05003136
Dave Wallace2a865272018-02-07 21:00:42 -05003137 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05003138 return -1;
3139
3140 if (PREDICT_FALSE (!events || (timeout < -1)))
3141 {
3142 errno = EFAULT;
3143 return -1;
3144 }
3145
Florin Coras99368312018-08-02 10:45:44 -07003146 if (epfd == ldp->vcl_mq_epfd)
3147 return libc_epoll_pwait (epfd, events, maxevents, timeout, sigmask);
3148
Dave Wallace048b1d62018-01-03 22:24:41 -05003149 if (PREDICT_FALSE (vep_idx == INVALID_SESSION_ID))
3150 {
3151 clib_warning ("LDP<%d>: ERROR: epfd %d (0x%x): bad vep_idx %d (0x%x)!",
3152 getpid (), epfd, epfd, vep_idx, vep_idx);
3153 errno = EBADFD;
3154 return -1;
3155 }
3156
Florin Coras54693d22018-07-17 10:46:29 -07003157 time_to_wait = ((timeout >= 0) ? (double) timeout : 0);
Dave Wallace2a865272018-02-07 21:00:42 -05003158 time_out = clib_time_now (&ldp->clib_time) + time_to_wait;
Dave Wallace048b1d62018-01-03 22:24:41 -05003159
3160 func_str = "vppcom_session_attr[GET_LIBC_EPFD]";
3161 libc_epfd = vppcom_session_attr (vep_idx, VPPCOM_ATTR_GET_LIBC_EPFD, 0, 0);
3162 if (PREDICT_FALSE (libc_epfd < 0))
3163 {
3164 errno = -libc_epfd;
3165 rv = -1;
3166 goto done;
3167 }
3168
Florin Coras99368312018-08-02 10:45:44 -07003169 LDBG (2, "LDP<%d>: epfd %d (0x%x): vep_idx %d (0x%x), libc_epfd %d (0x%x), "
3170 "events %p, maxevents %d, timeout %d, sigmask %p: time_to_wait %.02f",
3171 getpid (), epfd, epfd, vep_idx, vep_idx, libc_epfd, libc_epfd, events,
3172 maxevents, timeout, sigmask, time_to_wait, time_out);
Dave Wallace048b1d62018-01-03 22:24:41 -05003173 do
3174 {
Dave Wallace2a865272018-02-07 21:00:42 -05003175 if (!ldp->epoll_wait_vcl)
Dave Wallace048b1d62018-01-03 22:24:41 -05003176 {
3177 func_str = "vppcom_epoll_wait";
3178
Florin Coras99368312018-08-02 10:45:44 -07003179 LDBG (3, "LDP<%d>: epfd %d (0x%x): calling %s(): vep_idx %d (0x%x),"
3180 " events %p, maxevents %d", getpid (), epfd, epfd, func_str,
3181 vep_idx, vep_idx, events, maxevents);
Dave Wallace048b1d62018-01-03 22:24:41 -05003182
3183 rv = vppcom_epoll_wait (vep_idx, events, maxevents, 0);
3184 if (rv > 0)
3185 {
Dave Wallace2a865272018-02-07 21:00:42 -05003186 ldp->epoll_wait_vcl = 1;
Dave Wallace048b1d62018-01-03 22:24:41 -05003187 goto done;
3188 }
3189 else if (rv < 0)
3190 {
3191 errno = -rv;
3192 rv = -1;
3193 goto done;
3194 }
3195 }
3196 else
Dave Wallace2a865272018-02-07 21:00:42 -05003197 ldp->epoll_wait_vcl = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -05003198
3199 if (libc_epfd > 0)
3200 {
3201 func_str = "libc_epoll_pwait";
3202
Florin Coras99368312018-08-02 10:45:44 -07003203 LDBG (3, "LDP<%d>: epfd %d (0x%x): calling %s(): libc_epfd %d "
3204 "(0x%x), events %p, maxevents %d, sigmask %p", getpid (),
3205 epfd, epfd, func_str, libc_epfd, libc_epfd, events,
3206 maxevents, sigmask);
Dave Wallace048b1d62018-01-03 22:24:41 -05003207
Keith Burns (alagalah)5368efa2018-02-07 13:20:28 -08003208 rv = libc_epoll_pwait (libc_epfd, events, maxevents, 1, sigmask);
Dave Wallace048b1d62018-01-03 22:24:41 -05003209 if (rv != 0)
3210 goto done;
3211 }
3212
3213 if (timeout != -1)
Dave Wallace2a865272018-02-07 21:00:42 -05003214 now = clib_time_now (&ldp->clib_time);
Dave Wallace048b1d62018-01-03 22:24:41 -05003215 }
3216 while (now < time_out);
3217
3218done:
Dave Wallace2a865272018-02-07 21:00:42 -05003219 if (LDP_DEBUG > 3)
Dave Wallace048b1d62018-01-03 22:24:41 -05003220 {
Keith Burns (alagalah)5368efa2018-02-07 13:20:28 -08003221 if (libc_epfd > 0)
3222 epfd = libc_epfd;
Dave Wallace048b1d62018-01-03 22:24:41 -05003223 if (rv < 0)
3224 {
3225 int errno_val = errno;
3226 perror (func_str);
3227 clib_warning ("LDP<%d>: ERROR: epfd %d (0x%x): %s() failed! "
3228 "rv %d, errno = %d", getpid (), epfd, epfd,
3229 func_str, rv, errno_val);
3230 errno = errno_val;
3231 }
3232 else
3233 clib_warning ("LDP<%d>: epfd %d (0x%x): returning %d (0x%x)",
3234 getpid (), epfd, epfd, rv, rv);
3235 }
3236 return rv;
3237}
3238
3239int
3240epoll_pwait (int epfd, struct epoll_event *events,
3241 int maxevents, int timeout, const sigset_t * sigmask)
3242{
Dave Wallace2a865272018-02-07 21:00:42 -05003243 return ldp_epoll_pwait (epfd, events, maxevents, timeout, sigmask);
Dave Wallace048b1d62018-01-03 22:24:41 -05003244}
3245
3246int
3247epoll_wait (int epfd, struct epoll_event *events, int maxevents, int timeout)
3248{
Dave Wallace2a865272018-02-07 21:00:42 -05003249 return ldp_epoll_pwait (epfd, events, maxevents, timeout, NULL);
Dave Wallace048b1d62018-01-03 22:24:41 -05003250}
3251
3252int
3253poll (struct pollfd *fds, nfds_t nfds, int timeout)
3254{
3255 const char *func_str = __func__;
3256 int rv, i, n_libc_fds, n_revents;
3257 u32 sid;
3258 vcl_poll_t *vp;
3259 double wait_for_time;
3260
Dave Wallace2a865272018-02-07 21:00:42 -05003261 if (LDP_DEBUG > 3)
Dave Wallace048b1d62018-01-03 22:24:41 -05003262 clib_warning ("LDP<%d>: fds %p, nfds %d, timeout %d",
3263 getpid (), fds, nfds, timeout);
3264
3265 if (timeout >= 0)
3266 wait_for_time = (f64) timeout / 1000;
3267 else
3268 wait_for_time = -1;
3269
3270 n_libc_fds = 0;
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), .events = 0x%x, "
3277 ".revents = 0x%x", getpid (), i, fds[i].fd,
3278 fds[i].fd, fds[i].events, fds[i].revents);
3279
Dave Wallace2a865272018-02-07 21:00:42 -05003280 sid = ldp_sid_from_fd (fds[i].fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05003281 if (sid != INVALID_SESSION_ID)
3282 {
3283 fds[i].fd = -fds[i].fd;
Dave Wallace2a865272018-02-07 21:00:42 -05003284 vec_add2 (ldp->vcl_poll, vp, 1);
Dave Wallace048b1d62018-01-03 22:24:41 -05003285 vp->fds_ndx = i;
3286 vp->sid = sid;
3287 vp->events = fds[i].events;
3288#ifdef __USE_XOPEN2K
3289 if (fds[i].events & POLLRDNORM)
3290 vp->events |= POLLIN;
3291 if (fds[i].events & POLLWRNORM)
3292 vp->events |= POLLOUT;
3293#endif
3294 vp->revents = &fds[i].revents;
3295 }
3296 else
3297 n_libc_fds++;
3298 }
3299 }
3300
3301 n_revents = 0;
3302 do
3303 {
Dave Wallace2a865272018-02-07 21:00:42 -05003304 if (vec_len (ldp->vcl_poll))
Dave Wallace048b1d62018-01-03 22:24:41 -05003305 {
3306 func_str = "vppcom_poll";
3307
Dave Wallace2a865272018-02-07 21:00:42 -05003308 if (LDP_DEBUG > 3)
Dave Wallace048b1d62018-01-03 22:24:41 -05003309 clib_warning ("LDP<%d>: calling %s(): "
3310 "vcl_poll %p, n_sids %u (0x%x): "
3311 "n_libc_fds %u",
Dave Wallace2a865272018-02-07 21:00:42 -05003312 getpid (), func_str, ldp->vcl_poll,
3313 vec_len (ldp->vcl_poll), vec_len (ldp->vcl_poll),
Dave Wallace048b1d62018-01-03 22:24:41 -05003314 n_libc_fds);
3315
Dave Wallace2a865272018-02-07 21:00:42 -05003316 rv = vppcom_poll (ldp->vcl_poll, vec_len (ldp->vcl_poll), 0);
Dave Wallace048b1d62018-01-03 22:24:41 -05003317 if (rv < 0)
3318 {
3319 errno = -rv;
3320 rv = -1;
3321 goto done;
3322 }
3323 else
3324 n_revents += rv;
3325 }
3326
3327 if (n_libc_fds)
3328 {
3329 func_str = "libc_poll";
3330
Dave Wallace2a865272018-02-07 21:00:42 -05003331 if (LDP_DEBUG > 3)
Dave Wallace048b1d62018-01-03 22:24:41 -05003332 clib_warning ("LDP<%d>: calling %s(): fds %p, nfds %u: n_sids %u",
Dave Wallace2a865272018-02-07 21:00:42 -05003333 getpid (), fds, nfds, vec_len (ldp->vcl_poll));
Dave Wallace048b1d62018-01-03 22:24:41 -05003334
3335 rv = libc_poll (fds, nfds, 0);
3336 if (rv < 0)
3337 goto done;
3338 else
3339 n_revents += rv;
3340 }
3341
3342 if (n_revents)
3343 {
3344 rv = n_revents;
3345 goto done;
3346 }
3347 }
3348 while ((wait_for_time == -1) ||
Dave Wallace2a865272018-02-07 21:00:42 -05003349 (clib_time_now (&ldp->clib_time) < wait_for_time));
Dave Wallace048b1d62018-01-03 22:24:41 -05003350 rv = 0;
3351
3352done:
Dave Wallace2a865272018-02-07 21:00:42 -05003353 vec_foreach (vp, ldp->vcl_poll)
Dave Wallace048b1d62018-01-03 22:24:41 -05003354 {
3355 fds[vp->fds_ndx].fd = -fds[vp->fds_ndx].fd;
3356#ifdef __USE_XOPEN2K
3357 if ((fds[vp->fds_ndx].revents & POLLIN) &&
3358 (fds[vp->fds_ndx].events & POLLRDNORM))
3359 fds[vp->fds_ndx].revents |= POLLRDNORM;
3360 if ((fds[vp->fds_ndx].revents & POLLOUT) &&
3361 (fds[vp->fds_ndx].events & POLLWRNORM))
3362 fds[vp->fds_ndx].revents |= POLLWRNORM;
3363#endif
3364 }
Dave Wallace2a865272018-02-07 21:00:42 -05003365 vec_reset_length (ldp->vcl_poll);
Dave Wallace048b1d62018-01-03 22:24:41 -05003366
Dave Wallace2a865272018-02-07 21:00:42 -05003367 if (LDP_DEBUG > 3)
Dave Wallace048b1d62018-01-03 22:24:41 -05003368 {
3369 if (rv < 0)
3370 {
3371 int errno_val = errno;
3372 perror (func_str);
3373 clib_warning ("LDP<%d>: ERROR: %s() failed! "
3374 "rv %d, errno = %d", getpid (),
3375 func_str, rv, errno_val);
3376 errno = errno_val;
3377 }
3378 else
3379 {
3380 clib_warning ("LDP<%d>: returning %d (0x%x): n_sids %u, "
3381 "n_libc_fds %d", getpid (), rv, rv,
Dave Wallace2a865272018-02-07 21:00:42 -05003382 vec_len (ldp->vcl_poll), n_libc_fds);
Dave Wallace048b1d62018-01-03 22:24:41 -05003383
3384 for (i = 0; i < nfds; i++)
3385 {
3386 if (fds[i].fd >= 0)
3387 {
Dave Wallace2a865272018-02-07 21:00:42 -05003388 if (LDP_DEBUG > 3)
Dave Wallace048b1d62018-01-03 22:24:41 -05003389 clib_warning ("LDP<%d>: fds[%d].fd %d (0x%0x), "
3390 ".events = 0x%x, .revents = 0x%x",
3391 getpid (), i, fds[i].fd, fds[i].fd,
3392 fds[i].events, fds[i].revents);
3393 }
3394 }
3395 }
3396 }
3397
3398 return rv;
3399}
3400
3401#ifdef USE_GNU
3402int
3403ppoll (struct pollfd *fds, nfds_t nfds,
3404 const struct timespec *timeout, const sigset_t * sigmask)
3405{
Dave Wallace2a865272018-02-07 21:00:42 -05003406 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05003407 return -1;
3408
3409 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
3410 errno = ENOSYS;
3411
3412
3413 return -1;
3414}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003415#endif
3416
Dave Wallace2a865272018-02-07 21:00:42 -05003417void CONSTRUCTOR_ATTRIBUTE ldp_constructor (void);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003418
Dave Wallace2a865272018-02-07 21:00:42 -05003419void DESTRUCTOR_ATTRIBUTE ldp_destructor (void);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003420
Dave Wallace048b1d62018-01-03 22:24:41 -05003421/*
3422 * This function is called when the library is loaded
3423 */
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003424void
Dave Wallace2a865272018-02-07 21:00:42 -05003425ldp_constructor (void)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003426{
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003427 swrap_constructor ();
Dave Wallace2a865272018-02-07 21:00:42 -05003428 if (ldp_init () != 0)
3429 fprintf (stderr, "\nLDP<%d>: ERROR: ldp_constructor: failed!\n",
Dave Wallace048b1d62018-01-03 22:24:41 -05003430 getpid ());
Dave Wallace69d01192018-02-22 16:22:09 -05003431 else if (LDP_DEBUG > 0)
Dave Wallace2a865272018-02-07 21:00:42 -05003432 clib_warning ("LDP<%d>: LDP constructor: done!\n", getpid ());
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003433}
3434
3435/*
3436 * This function is called when the library is unloaded
3437 */
3438void
Dave Wallace2a865272018-02-07 21:00:42 -05003439ldp_destructor (void)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003440{
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003441 swrap_destructor ();
Dave Wallace2a865272018-02-07 21:00:42 -05003442 if (ldp->init)
Dave Wallace048b1d62018-01-03 22:24:41 -05003443 {
3444 vppcom_app_destroy ();
Dave Wallace2a865272018-02-07 21:00:42 -05003445 ldp->init = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -05003446 }
3447
3448 /* Don't use clib_warning() here because that calls writev()
Dave Wallace2a865272018-02-07 21:00:42 -05003449 * which will call ldp_init().
Dave Wallace048b1d62018-01-03 22:24:41 -05003450 */
Dave Wallace69d01192018-02-22 16:22:09 -05003451 if (LDP_DEBUG > 0)
3452 printf ("%s:%d: LDP<%d>: LDP destructor: done!\n",
3453 __func__, __LINE__, getpid ());
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003454}
3455
3456
3457/*
3458 * fd.io coding-style-patch-verification: ON
3459 *
3460 * Local Variables:
3461 * eval: (c-set-style "gnu")
3462 * End:
3463 */