blob: beaa988185d8d9021c4e87c97543a4f86f3afa5a [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;
Florin Coras6917b942018-11-13 22:44:54 -080068 struct pollfd *libc_poll;
69 u16 *libc_poll_idxs;
Dave Wallace048b1d62018-01-03 22:24:41 -050070 u8 select_vcl;
71 u8 epoll_wait_vcl;
Florin Coras99368312018-08-02 10:45:44 -070072 u8 vcl_needs_real_epoll; /*< vcl needs next epoll_create to
73 go to libc_epoll */
74 int vcl_mq_epfd;
75
Dave Wallace2a865272018-02-07 21:00:42 -050076} ldp_main_t;
77#define LDP_DEBUG ldp->debug
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -070078
Florin Coras99368312018-08-02 10:45:44 -070079#define LDBG(_lvl, _fmt, _args...) \
80 if (ldp->debug > _lvl) \
81 clib_warning (_fmt, ##_args)
82
Dave Wallace2a865272018-02-07 21:00:42 -050083static ldp_main_t ldp_main = {
84 .sid_bit_val = (1 << LDP_SID_BIT_MIN),
85 .sid_bit_mask = (1 << LDP_SID_BIT_MIN) - 1,
86 .debug = LDP_DEBUG_INIT,
Dave Wallace048b1d62018-01-03 22:24:41 -050087};
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -070088
Dave Wallace2a865272018-02-07 21:00:42 -050089static ldp_main_t *ldp = &ldp_main;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -070090
91/*
92 * RETURN: 0 on success or -1 on error.
93 * */
Dave Wallace048b1d62018-01-03 22:24:41 -050094static inline void
Dave Wallace2a865272018-02-07 21:00:42 -050095ldp_set_app_name (char *app_name)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -070096{
Dave Wallace2a865272018-02-07 21:00:42 -050097 int rv = snprintf (ldp->app_name, LDP_APP_NAME_MAX,
98 "ldp-%d-%s", getpid (), app_name);
Dave Wallace048b1d62018-01-03 22:24:41 -050099
Dave Wallace2a865272018-02-07 21:00:42 -0500100 if (rv >= LDP_APP_NAME_MAX)
101 app_name[LDP_APP_NAME_MAX - 1] = 0;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700102}
103
Dave Wallace048b1d62018-01-03 22:24:41 -0500104static inline char *
Dave Wallace2a865272018-02-07 21:00:42 -0500105ldp_get_app_name ()
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700106{
Dave Wallace2a865272018-02-07 21:00:42 -0500107 if (ldp->app_name[0] == '\0')
108 ldp_set_app_name ("app");
Dave Wallace048b1d62018-01-03 22:24:41 -0500109
Dave Wallace2a865272018-02-07 21:00:42 -0500110 return ldp->app_name;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700111}
112
Dave Wallace048b1d62018-01-03 22:24:41 -0500113static inline int
Dave Wallace2a865272018-02-07 21:00:42 -0500114ldp_fd_from_sid (u32 sid)
Dave Wallace048b1d62018-01-03 22:24:41 -0500115{
Dave Wallace2a865272018-02-07 21:00:42 -0500116 if (PREDICT_FALSE (sid >= ldp->sid_bit_val))
Dave Wallace048b1d62018-01-03 22:24:41 -0500117 return -EMFILE;
118 else
Dave Wallace2a865272018-02-07 21:00:42 -0500119 return (sid | ldp->sid_bit_val);
Dave Wallace048b1d62018-01-03 22:24:41 -0500120}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700121
Dave Wallace048b1d62018-01-03 22:24:41 -0500122static inline int
Dave Wallace2a865272018-02-07 21:00:42 -0500123ldp_fd_is_sid (int fd)
Dave Wallace048b1d62018-01-03 22:24:41 -0500124{
Dave Wallace2a865272018-02-07 21:00:42 -0500125 return ((u32) fd & ldp->sid_bit_val) ? 1 : 0;
Dave Wallace048b1d62018-01-03 22:24:41 -0500126}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700127
Dave Wallace048b1d62018-01-03 22:24:41 -0500128static inline u32
Dave Wallace2a865272018-02-07 21:00:42 -0500129ldp_sid_from_fd (int fd)
Dave Wallace048b1d62018-01-03 22:24:41 -0500130{
Dave Wallace2a865272018-02-07 21:00:42 -0500131 return (ldp_fd_is_sid (fd) ? ((u32) fd & ldp->sid_bit_mask) :
Dave Wallace048b1d62018-01-03 22:24:41 -0500132 INVALID_SESSION_ID);
133}
134
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700135static inline int
Dave Wallace2a865272018-02-07 21:00:42 -0500136ldp_init (void)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700137{
Florin Coras99368312018-08-02 10:45:44 -0700138 int rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700139
Florin Coras99368312018-08-02 10:45:44 -0700140 if (PREDICT_TRUE (ldp->init))
141 return 0;
142
143 ldp->init = 1;
144 ldp->vcl_needs_real_epoll = 1;
145 rv = vppcom_app_create (ldp_get_app_name ());
146 if (rv != VPPCOM_OK)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700147 {
Florin Coras99368312018-08-02 10:45:44 -0700148 fprintf (stderr, "\nLDP<%d>: ERROR: ldp_init: vppcom_app_create()"
149 " failed! rv = %d (%s)\n",
150 getpid (), rv, vppcom_retval_str (rv));
151 ldp->init = 0;
152 return rv;
153 }
154 ldp->vcl_needs_real_epoll = 0;
155
156 char *env_var_str = getenv (LDP_ENV_DEBUG);
157 if (env_var_str)
158 {
159 u32 tmp;
160 if (sscanf (env_var_str, "%u", &tmp) != 1)
161 clib_warning ("LDP<%d>: WARNING: Invalid LDP debug level specified in"
162 " the env var " LDP_ENV_DEBUG " (%s)!", getpid (),
163 env_var_str);
164 else
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700165 {
Florin Coras99368312018-08-02 10:45:44 -0700166 ldp->debug = tmp;
167 LDBG (0, "LDP<%d>: configured LDP debug level (%u) from env var "
168 LDP_ENV_DEBUG "!", getpid (), ldp->debug);
169 }
170 }
Dave Wallace048b1d62018-01-03 22:24:41 -0500171
Florin Coras99368312018-08-02 10:45:44 -0700172 env_var_str = getenv (LDP_ENV_APP_NAME);
173 if (env_var_str)
174 {
175 ldp_set_app_name (env_var_str);
176 LDBG (0, "LDP<%d>: configured LDP app name (%s) from the env var "
177 LDP_ENV_APP_NAME "!", getpid (), ldp->app_name);
178 }
Dave Wallace048b1d62018-01-03 22:24:41 -0500179
Florin Coras99368312018-08-02 10:45:44 -0700180 env_var_str = getenv (LDP_ENV_SID_BIT);
181 if (env_var_str)
182 {
183 u32 sb;
184 if (sscanf (env_var_str, "%u", &sb) != 1)
185 {
186 clib_warning ("LDP<%d>: WARNING: Invalid LDP sid bit specified in"
187 " the env var " LDP_ENV_SID_BIT " (%s)! sid bit "
188 "value %d (0x%x)", getpid (), env_var_str,
189 ldp->sid_bit_val, ldp->sid_bit_val);
190 }
191 else if (sb < LDP_SID_BIT_MIN)
192 {
193 ldp->sid_bit_val = (1 << LDP_SID_BIT_MIN);
194 ldp->sid_bit_mask = ldp->sid_bit_val - 1;
Dave Wallace048b1d62018-01-03 22:24:41 -0500195
Florin Coras99368312018-08-02 10:45:44 -0700196 clib_warning ("LDP<%d>: WARNING: LDP sid bit (%u) specified in the"
197 " env var " LDP_ENV_SID_BIT " (%s) is too small. "
198 "Using LDP_SID_BIT_MIN (%d)! sid bit value %d (0x%x)",
199 getpid (), sb, env_var_str, LDP_SID_BIT_MIN,
200 ldp->sid_bit_val, ldp->sid_bit_val);
201 }
202 else if (sb > LDP_SID_BIT_MAX)
203 {
204 ldp->sid_bit_val = (1 << LDP_SID_BIT_MAX);
205 ldp->sid_bit_mask = ldp->sid_bit_val - 1;
Dave Wallace048b1d62018-01-03 22:24:41 -0500206
Florin Coras99368312018-08-02 10:45:44 -0700207 clib_warning ("LDP<%d>: WARNING: LDP sid bit (%u) specified in the"
208 " env var " LDP_ENV_SID_BIT " (%s) is too big. Using"
209 " LDP_SID_BIT_MAX (%d)! sid bit value %d (0x%x)",
210 getpid (), sb, env_var_str, LDP_SID_BIT_MAX,
211 ldp->sid_bit_val, ldp->sid_bit_val);
Dave Wallace048b1d62018-01-03 22:24:41 -0500212 }
213 else
214 {
Florin Coras99368312018-08-02 10:45:44 -0700215 ldp->sid_bit_val = (1 << sb);
216 ldp->sid_bit_mask = ldp->sid_bit_val - 1;
217
218 LDBG (0, "LDP<%d>: configured LDP sid bit (%u) from "
219 LDP_ENV_SID_BIT "! sid bit value %d (0x%x)", getpid (), sb,
220 ldp->sid_bit_val, ldp->sid_bit_val);
Dave Wallace048b1d62018-01-03 22:24:41 -0500221 }
222 }
Florin Coras99368312018-08-02 10:45:44 -0700223
224 clib_time_init (&ldp->clib_time);
225 LDBG (0, "LDP<%d>: LDP initialization: done!", getpid ());
226
227 return 0;
Dave Wallace048b1d62018-01-03 22:24:41 -0500228}
229
230int
231close (int fd)
232{
233 int rv;
234 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -0500235 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -0500236
Dave Wallace2a865272018-02-07 21:00:42 -0500237 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500238 return -1;
239
240 if (sid != INVALID_SESSION_ID)
241 {
242 int epfd;
243
244 func_str = "vppcom_session_attr[GET_LIBC_EPFD]";
245 epfd = vppcom_session_attr (sid, VPPCOM_ATTR_GET_LIBC_EPFD, 0, 0);
246 if (epfd > 0)
247 {
248 func_str = "libc_close";
249
Florin Coras6917b942018-11-13 22:44:54 -0800250 LDBG (0, "LDP<%d>: fd %d (0x%x): calling %s(): epfd %u (0x%x)",
251 getpid (), fd, fd, func_str, epfd, epfd);
Dave Wallace048b1d62018-01-03 22:24:41 -0500252
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
Florin Coras6917b942018-11-13 22:44:54 -0800272 LDBG (0, "LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x)",
273 getpid (), fd, fd, func_str, sid, sid);
Dave Wallace048b1d62018-01-03 22:24:41 -0500274
275 rv = vppcom_session_close (sid);
276 if (rv != VPPCOM_OK)
277 {
278 errno = -rv;
279 rv = -1;
280 }
281 }
282 else
283 {
284 func_str = "libc_close";
285
Florin Coras6917b942018-11-13 22:44:54 -0800286 LDBG (0, "LDP<%d>: fd %d (0x%x): calling %s()", getpid (), fd, fd,
287 func_str);
Dave Wallace048b1d62018-01-03 22:24:41 -0500288
289 rv = libc_close (fd);
290 }
291
292done:
Dave Wallace2a865272018-02-07 21:00:42 -0500293 if (LDP_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -0500294 {
295 if (rv < 0)
296 {
297 int errno_val = errno;
298 perror (func_str);
299 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
300 "rv %d, errno = %d", getpid (), fd, fd,
301 func_str, rv, errno_val);
302 errno = errno_val;
303 }
304 else
305 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
306 getpid (), fd, fd, rv, rv);
307 }
308 return rv;
309}
310
311ssize_t
312read (int fd, void *buf, size_t nbytes)
313{
314 ssize_t size;
315 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -0500316 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -0500317
Dave Wallace2a865272018-02-07 21:00:42 -0500318 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500319 return -1;
320
321 if (sid != INVALID_SESSION_ID)
322 {
323 func_str = "vppcom_session_read";
324
Dave Wallace2a865272018-02-07 21:00:42 -0500325 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -0500326 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
327 "sid %u (0x%x), buf %p, nbytes %u", getpid (),
328 fd, fd, func_str, sid, sid, buf, nbytes);
329
330 size = vppcom_session_read (sid, buf, nbytes);
331 if (size < 0)
332 {
333 errno = -size;
334 size = -1;
335 }
336 }
337 else
338 {
339 func_str = "libc_read";
340
Dave Wallace2a865272018-02-07 21:00:42 -0500341 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -0500342 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
343 "buf %p, nbytes %u", getpid (),
344 fd, fd, func_str, buf, nbytes);
345
346 size = libc_read (fd, buf, nbytes);
347 }
348
Dave Wallace2a865272018-02-07 21:00:42 -0500349 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -0500350 {
351 if (size < 0)
352 {
353 int errno_val = errno;
354 perror (func_str);
355 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
356 "rv %d, errno = %d", getpid (), fd, fd,
357 func_str, size, errno_val);
358 errno = errno_val;
359 }
360 else
361 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
362 getpid (), fd, fd, size, size);
363 }
364 return size;
365}
366
367ssize_t
368readv (int fd, const struct iovec * iov, int iovcnt)
369{
370 const char *func_str;
371 ssize_t size = 0;
Dave Wallace2a865272018-02-07 21:00:42 -0500372 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace8aaba562018-01-18 17:21:19 -0500373 int rv = 0, i, total = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -0500374
Dave Wallace2a865272018-02-07 21:00:42 -0500375 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500376 return -1;
377
378 if (sid != INVALID_SESSION_ID)
379 {
380 func_str = "vppcom_session_read";
381 do
382 {
383 for (i = 0; i < iovcnt; ++i)
384 {
Dave Wallace2a865272018-02-07 21:00:42 -0500385 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -0500386 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s() [%d]: "
387 "sid %u (0x%x), iov %p, iovcnt %d, total %d",
388 getpid (), fd, fd, func_str, i, sid, sid,
389 iov, iovcnt, total);
390
391 rv = vppcom_session_read (sid, iov[i].iov_base, iov[i].iov_len);
392 if (rv < 0)
393 break;
394 else
395 {
396 total += rv;
397 if (rv < iov[i].iov_len)
398 {
Dave Wallace2a865272018-02-07 21:00:42 -0500399 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -0500400 clib_warning ("LDP<%d>: fd %d (0x%x): "
401 "rv (%d) < iov[%d].iov_len (%d)",
402 getpid (), fd, fd, rv, i,
403 iov[i].iov_len);
404 break;
405 }
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700406 }
407 }
408 }
Dave Wallace048b1d62018-01-03 22:24:41 -0500409 while ((rv >= 0) && (total == 0));
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700410
Dave Wallace048b1d62018-01-03 22:24:41 -0500411 if (rv < 0)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700412 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500413 errno = -rv;
414 size = -1;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700415 }
Dave Wallace048b1d62018-01-03 22:24:41 -0500416 else
417 size = total;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700418 }
419 else
420 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500421 func_str = "libc_readv";
422
Dave Wallace2a865272018-02-07 21:00:42 -0500423 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -0500424 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
425 "iov %p, iovcnt %d", getpid (), fd, fd, iov, iovcnt);
426
427 size = libc_readv (fd, iov, iovcnt);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700428 }
429
Dave Wallace2a865272018-02-07 21:00:42 -0500430 if (LDP_DEBUG > 2)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700431 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500432 if (size < 0)
433 {
434 int errno_val = errno;
435 perror (func_str);
436 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
437 "rv %d, errno = %d", getpid (), fd, fd,
438 func_str, size, errno_val);
439 errno = errno_val;
440 }
441 else
442 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
443 getpid (), fd, fd, size, size);
444 }
445 return size;
446}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700447
Dave Wallace048b1d62018-01-03 22:24:41 -0500448ssize_t
449write (int fd, const void *buf, size_t nbytes)
450{
451 const char *func_str;
452 ssize_t size = 0;
Dave Wallace2a865272018-02-07 21:00:42 -0500453 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -0500454
Dave Wallace2a865272018-02-07 21:00:42 -0500455 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500456 return -1;
457
458 if (sid != INVALID_SESSION_ID)
459 {
460 func_str = "vppcom_session_write";
461
Dave Wallace2a865272018-02-07 21:00:42 -0500462 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -0500463 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
464 "sid %u (0x%x), buf %p, nbytes %u", getpid (),
465 fd, fd, func_str, sid, sid, buf, nbytes);
466
467 size = vppcom_session_write (sid, (void *) buf, nbytes);
468 if (size < 0)
469 {
470 errno = -size;
471 size = -1;
472 }
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700473 }
474 else
475 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500476 func_str = "libc_write";
477
Dave Wallace2a865272018-02-07 21:00:42 -0500478 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -0500479 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
480 "buf %p, nbytes %u", getpid (),
481 fd, fd, func_str, buf, nbytes);
482
483 size = libc_write (fd, buf, nbytes);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700484 }
485
Dave Wallace2a865272018-02-07 21:00:42 -0500486 if (LDP_DEBUG > 2)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700487 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500488 if (size < 0)
489 {
490 int errno_val = errno;
491 perror (func_str);
492 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
493 "rv %d, errno = %d", getpid (), fd, fd,
494 func_str, size, errno_val);
495 errno = errno_val;
496 }
497 else
498 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
499 getpid (), fd, fd, size, size);
500 }
501 return size;
502}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700503
Dave Wallace048b1d62018-01-03 22:24:41 -0500504ssize_t
505writev (int fd, const struct iovec * iov, int iovcnt)
506{
507 const char *func_str;
508 ssize_t size = 0, total = 0;
Dave Wallace2a865272018-02-07 21:00:42 -0500509 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace8aaba562018-01-18 17:21:19 -0500510 int i, rv = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -0500511
512 /*
513 * Use [f]printf() instead of clib_warning() to prevent recursion SIGSEGV.
514 */
515
Dave Wallace2a865272018-02-07 21:00:42 -0500516 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500517 return -1;
518
519 if (sid != INVALID_SESSION_ID)
520 {
521 func_str = "vppcom_session_write";
522 do
523 {
524 for (i = 0; i < iovcnt; ++i)
525 {
Dave Wallace2a865272018-02-07 21:00:42 -0500526 if (LDP_DEBUG > 4)
Dave Wallace048b1d62018-01-03 22:24:41 -0500527 printf ("%s:%d: LDP<%d>: fd %d (0x%x): calling %s() [%d]: "
528 "sid %u (0x%x), buf %p, nbytes %ld, total %ld",
529 __func__, __LINE__, getpid (), fd, fd, func_str,
530 i, sid, sid, iov[i].iov_base, iov[i].iov_len, total);
531
532 rv = vppcom_session_write (sid, iov[i].iov_base,
533 iov[i].iov_len);
534 if (rv < 0)
535 break;
536 else
537 {
538 total += rv;
539 if (rv < iov[i].iov_len)
540 {
Dave Wallace2a865272018-02-07 21:00:42 -0500541 if (LDP_DEBUG > 4)
Dave Wallace048b1d62018-01-03 22:24:41 -0500542 printf ("%s:%d: LDP<%d>: fd %d (0x%x): "
543 "rv (%d) < iov[%d].iov_len (%ld)",
544 __func__, __LINE__, getpid (), fd, fd,
545 rv, i, iov[i].iov_len);
546 break;
547 }
548 }
549 }
550 }
551 while ((rv >= 0) && (total == 0));
552
553 if (rv < 0)
554 {
555 errno = -rv;
556 size = -1;
557 }
558 else
559 size = total;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700560 }
561 else
562 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500563 func_str = "libc_writev";
564
Dave Wallace2a865272018-02-07 21:00:42 -0500565 if (LDP_DEBUG > 4)
Dave Wallace048b1d62018-01-03 22:24:41 -0500566 printf ("%s:%d: LDP<%d>: fd %d (0x%x): calling %s(): "
567 "iov %p, iovcnt %d\n", __func__, __LINE__, getpid (),
568 fd, fd, func_str, iov, iovcnt);
569
570 size = libc_writev (fd, iov, iovcnt);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700571 }
572
Dave Wallace2a865272018-02-07 21:00:42 -0500573 if (LDP_DEBUG > 4)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700574 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500575 if (size < 0)
576 {
577 int errno_val = errno;
578 perror (func_str);
579 fprintf (stderr,
580 "%s:%d: LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
581 "rv %ld, errno = %d\n", __func__, __LINE__, getpid (), fd,
582 fd, func_str, size, errno_val);
583 errno = errno_val;
584 }
585 else
586 printf ("%s:%d: LDP<%d>: fd %d (0x%x): returning %ld\n",
587 __func__, __LINE__, getpid (), fd, fd, size);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700588 }
Dave Wallace048b1d62018-01-03 22:24:41 -0500589 return size;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700590}
591
592int
Dave Wallace048b1d62018-01-03 22:24:41 -0500593fcntl (int fd, int cmd, ...)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700594{
Dave Wallace048b1d62018-01-03 22:24:41 -0500595 const char *func_str = __func__;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700596 int rv = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -0500597 va_list ap;
Dave Wallace2a865272018-02-07 21:00:42 -0500598 u32 sid = ldp_sid_from_fd (fd);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700599
Dave Wallace2a865272018-02-07 21:00:42 -0500600 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500601 return -1;
602
603 va_start (ap, cmd);
604 if (sid != INVALID_SESSION_ID)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700605 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500606 int flags = va_arg (ap, int);
607 u32 size;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700608
Dave Wallace048b1d62018-01-03 22:24:41 -0500609 size = sizeof (flags);
610 rv = -EOPNOTSUPP;
611 switch (cmd)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700612 {
Dave Wallace048b1d62018-01-03 22:24:41 -0500613 case F_SETFL:
614 func_str = "vppcom_session_attr[SET_FLAGS]";
Florin Coras173bae32018-11-16 18:56:28 -0800615 LDBG (2, "LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x) "
616 "flags %d (0x%x), size %d", getpid (), fd, fd, func_str, sid,
617 sid, flags, flags, size);
Dave Wallace048b1d62018-01-03 22:24:41 -0500618
Florin Coras173bae32018-11-16 18:56:28 -0800619 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_FLAGS, &flags,
620 &size);
Dave Wallace048b1d62018-01-03 22:24:41 -0500621 break;
622
623 case F_GETFL:
624 func_str = "vppcom_session_attr[GET_FLAGS]";
Florin Coras173bae32018-11-16 18:56:28 -0800625 LDBG (2, "LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), "
626 "flags %d (0x%x), size %d", getpid (), fd, fd, func_str, sid,
627 sid, flags, flags, size);
Dave Wallace048b1d62018-01-03 22:24:41 -0500628
Florin Coras173bae32018-11-16 18:56:28 -0800629 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_FLAGS, &flags,
630 &size);
Dave Wallace048b1d62018-01-03 22:24:41 -0500631 if (rv == VPPCOM_OK)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700632 {
Florin Coras173bae32018-11-16 18:56:28 -0800633 LDBG (2, "LDP<%d>: fd %d (0x%x), cmd %d (F_GETFL): %s() "
634 "returned flags %d (0x%x)", getpid (), fd, fd, cmd,
635 func_str, flags, flags);
Dave Wallace048b1d62018-01-03 22:24:41 -0500636 rv = flags;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700637 }
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700638 break;
Florin Coras173bae32018-11-16 18:56:28 -0800639 case F_SETFD:
640 /* TODO handle this */
641 LDBG (0, "F_SETFD ignored flags %u", flags);
642 rv = 0;
643 break;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700644 default:
Dave Wallace048b1d62018-01-03 22:24:41 -0500645 rv = -EOPNOTSUPP;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700646 break;
647 }
Dave Wallace048b1d62018-01-03 22:24:41 -0500648 if (rv < 0)
649 {
650 errno = -rv;
651 rv = -1;
652 }
653 }
654 else
655 {
656 func_str = "libc_vfcntl";
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700657
Dave Wallace2a865272018-02-07 21:00:42 -0500658 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -0500659 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): cmd %d",
660 getpid (), fd, fd, func_str, cmd);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700661
Dave Wallace048b1d62018-01-03 22:24:41 -0500662 rv = libc_vfcntl (fd, cmd, ap);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700663 }
664
Dave Wallace048b1d62018-01-03 22:24:41 -0500665 va_end (ap);
666
Dave Wallace2a865272018-02-07 21:00:42 -0500667 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -0500668 {
669 if (rv < 0)
670 {
671 int errno_val = errno;
672 perror (func_str);
673 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
674 "rv %d, errno = %d", getpid (), fd, fd,
675 func_str, rv, errno_val);
676 errno = errno_val;
677 }
678 else
679 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
680 getpid (), fd, fd, rv, rv);
681 }
682 return rv;
683}
684
685int
686ioctl (int fd, unsigned long int cmd, ...)
687{
688 const char *func_str;
689 int rv;
690 va_list ap;
Dave Wallace2a865272018-02-07 21:00:42 -0500691 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -0500692
Dave Wallace2a865272018-02-07 21:00:42 -0500693 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -0500694 return -1;
695
696 va_start (ap, cmd);
697 if (sid != INVALID_SESSION_ID)
698 {
699 func_str = "vppcom_session_attr[GET_NREAD]";
700
701 switch (cmd)
702 {
703 case FIONREAD:
Dave Wallace2a865272018-02-07 21:00:42 -0500704 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -0500705 clib_warning
706 ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x)",
707 getpid (), fd, fd, func_str, sid, sid);
708
709 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_NREAD, 0, 0);
710 break;
711
712 case FIONBIO:
713 {
714 u32 flags = va_arg (ap, int) ? O_NONBLOCK : 0;
715 u32 size = sizeof (flags);
716
717 /* TBD: When VPPCOM_ATTR_[GS]ET_FLAGS supports flags other than
718 * non-blocking, the flags should be read here and merged
719 * with O_NONBLOCK.
720 */
Dave Wallace2a865272018-02-07 21:00:42 -0500721 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -0500722 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
723 "sid %u (0x%x), flags %d (0x%x), size %d",
724 getpid (), fd, fd, func_str, sid, sid,
725 flags, flags, size);
726
727 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_FLAGS, &flags,
728 &size);
729 }
730 break;
731
732 default:
733 rv = -EOPNOTSUPP;
734 break;
735 }
736 if (rv < 0)
737 {
738 errno = -rv;
739 rv = -1;
740 }
741 }
742 else
743 {
744 func_str = "libc_vioctl";
745
Dave Wallace2a865272018-02-07 21:00:42 -0500746 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -0500747 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): cmd %d",
748 getpid (), fd, fd, func_str, cmd);
749
750 rv = libc_vioctl (fd, cmd, ap);
751 }
752
Dave Wallace2a865272018-02-07 21:00:42 -0500753 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -0500754 {
755 if (rv < 0)
756 {
757 int errno_val = errno;
758 perror (func_str);
759 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
760 "rv %d, errno = %d", getpid (), fd, fd,
761 func_str, rv, errno_val);
762 errno = errno_val;
763 }
764 else
765 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
766 getpid (), fd, fd, rv, rv);
767 }
768 va_end (ap);
769 return rv;
770}
771
772int
Dave Wallace2a865272018-02-07 21:00:42 -0500773ldp_pselect (int nfds, fd_set * __restrict readfds,
774 fd_set * __restrict writefds,
775 fd_set * __restrict exceptfds,
776 const struct timespec *__restrict timeout,
777 const __sigset_t * __restrict sigmask)
Dave Wallace048b1d62018-01-03 22:24:41 -0500778{
779 int rv;
780 char *func_str = "##";
781 f64 time_out;
782 int fd;
783 uword sid_bits, sid_bits_set, libc_bits, libc_bits_set;
784 u32 minbits = clib_max (nfds, BITS (uword));
785 u32 sid;
786
787 if (nfds < 0)
788 {
789 errno = EINVAL;
790 return -1;
791 }
792
Dave Wallace3ee1fe12018-02-23 01:09:11 -0500793 if (timeout)
794 {
795 time_out = (timeout->tv_sec == 0 && timeout->tv_nsec == 0) ?
796 (f64) 0 : (f64) timeout->tv_sec +
797 (f64) timeout->tv_nsec / (f64) 1000000000;
798
799 /* select as fine grained sleep */
800 if (!nfds)
801 {
Florin Coras173bae32018-11-16 18:56:28 -0800802 LDBG (3, "LDP<%d>: sleeping for %.02f seconds", getpid (),
803 time_out);
Dave Wallace3ee1fe12018-02-23 01:09:11 -0500804
805 time_out += clib_time_now (&ldp->clib_time);
806 while (clib_time_now (&ldp->clib_time) < time_out)
807 ;
808 return 0;
809 }
810 }
811 else if (!nfds)
812 {
813 errno = EINVAL;
814 return -1;
815 }
816 else
817 time_out = -1;
818
819
Dave Wallace2a865272018-02-07 21:00:42 -0500820 if (nfds <= ldp->sid_bit_val)
Dave Wallace048b1d62018-01-03 22:24:41 -0500821 {
822 func_str = "libc_pselect";
823
Florin Coras173bae32018-11-16 18:56:28 -0800824 LDBG (3, "LDP<%d>: calling %s(): nfds %d, readfds %p, writefds %p, "
825 "exceptfds %p, timeout %p, sigmask %p", getpid (), func_str, nfds,
826 readfds, writefds, exceptfds, timeout, sigmask);
Dave Wallace048b1d62018-01-03 22:24:41 -0500827
828 rv = libc_pselect (nfds, readfds, writefds, exceptfds,
829 timeout, sigmask);
830 goto done;
831 }
832
Dave Wallace2a865272018-02-07 21:00:42 -0500833 if (PREDICT_FALSE (ldp->sid_bit_val > FD_SETSIZE / 2))
Dave Wallace048b1d62018-01-03 22:24:41 -0500834 {
Dave Wallace2a865272018-02-07 21:00:42 -0500835 clib_warning ("LDP<%d>: ERROR: LDP sid bit value %d (0x%x) > "
Dave Wallace048b1d62018-01-03 22:24:41 -0500836 "FD_SETSIZE/2 %d (0x%x)!", getpid (),
Dave Wallace2a865272018-02-07 21:00:42 -0500837 ldp->sid_bit_val, ldp->sid_bit_val,
Dave Wallace048b1d62018-01-03 22:24:41 -0500838 FD_SETSIZE / 2, FD_SETSIZE / 2);
839 errno = EOVERFLOW;
840 return -1;
841 }
842
Dave Wallace048b1d62018-01-03 22:24:41 -0500843 sid_bits = libc_bits = 0;
Florin Coras173bae32018-11-16 18:56:28 -0800844 u32 n_bytes = nfds / 8 + ((nfds % 8) ? 1 : 0);
Dave Wallace048b1d62018-01-03 22:24:41 -0500845 if (readfds)
846 {
Dave Wallace2a865272018-02-07 21:00:42 -0500847 clib_bitmap_validate (ldp->sid_rd_bitmap, minbits);
848 clib_bitmap_validate (ldp->libc_rd_bitmap, minbits);
849 clib_bitmap_validate (ldp->rd_bitmap, minbits);
Florin Coras173bae32018-11-16 18:56:28 -0800850 clib_memcpy_fast (ldp->rd_bitmap, readfds, n_bytes);
851 memset (readfds, 0, n_bytes);
Dave Wallace048b1d62018-01-03 22:24:41 -0500852
853 /* *INDENT-OFF* */
Florin Coras173bae32018-11-16 18:56:28 -0800854 clib_bitmap_foreach (fd, ldp->rd_bitmap, ({
855 if (fd > nfds)
856 break;
857 sid = ldp_sid_from_fd (fd);
858 LDBG (3, "LDP<%d>: readfds: fd %d (0x%x), sid %u (0x%x)",
859 getpid (), fd, fd, sid, sid);
860 if (sid == INVALID_SESSION_ID)
861 clib_bitmap_set_no_check (ldp->libc_rd_bitmap, fd, 1);
862 else
863 clib_bitmap_set_no_check (ldp->sid_rd_bitmap, sid, 1);
864 }));
Dave Wallace048b1d62018-01-03 22:24:41 -0500865 /* *INDENT-ON* */
866
Dave Wallace2a865272018-02-07 21:00:42 -0500867 sid_bits_set = clib_bitmap_last_set (ldp->sid_rd_bitmap) + 1;
Dave Wallace048b1d62018-01-03 22:24:41 -0500868 sid_bits = (sid_bits_set > sid_bits) ? sid_bits_set : sid_bits;
869
Dave Wallace2a865272018-02-07 21:00:42 -0500870 libc_bits_set = clib_bitmap_last_set (ldp->libc_rd_bitmap) + 1;
Dave Wallace048b1d62018-01-03 22:24:41 -0500871 libc_bits = (libc_bits_set > libc_bits) ? libc_bits_set : libc_bits;
872
Florin Coras173bae32018-11-16 18:56:28 -0800873 LDBG (3, "LDP<%d>: readfds: sid_bits_set %d, sid_bits %d, "
874 "libc_bits_set %d, libc_bits %d", getpid (), sid_bits_set,
875 sid_bits, libc_bits_set, libc_bits);
Dave Wallace048b1d62018-01-03 22:24:41 -0500876 }
877 if (writefds)
878 {
Dave Wallace2a865272018-02-07 21:00:42 -0500879 clib_bitmap_validate (ldp->sid_wr_bitmap, minbits);
880 clib_bitmap_validate (ldp->libc_wr_bitmap, minbits);
881 clib_bitmap_validate (ldp->wr_bitmap, minbits);
Florin Coras173bae32018-11-16 18:56:28 -0800882 clib_memcpy_fast (ldp->wr_bitmap, writefds, n_bytes);
883 memset (writefds, 0, n_bytes);
Dave Wallace048b1d62018-01-03 22:24:41 -0500884
885 /* *INDENT-OFF* */
Florin Coras173bae32018-11-16 18:56:28 -0800886 clib_bitmap_foreach (fd, ldp->wr_bitmap, ({
887 if (fd > nfds)
888 break;
889 sid = ldp_sid_from_fd (fd);
890 LDBG (3, "LDP<%d>: writefds: fd %d (0x%x), sid %u (0x%x)",
891 getpid (), fd, fd, sid, sid);
892 if (sid == INVALID_SESSION_ID)
893 clib_bitmap_set_no_check (ldp->libc_wr_bitmap, fd, 1);
894 else
895 clib_bitmap_set_no_check (ldp->sid_wr_bitmap, sid, 1);
896 }));
Dave Wallace048b1d62018-01-03 22:24:41 -0500897 /* *INDENT-ON* */
898
Dave Wallace2a865272018-02-07 21:00:42 -0500899 sid_bits_set = clib_bitmap_last_set (ldp->sid_wr_bitmap) + 1;
Dave Wallace048b1d62018-01-03 22:24:41 -0500900 sid_bits = (sid_bits_set > sid_bits) ? sid_bits_set : sid_bits;
901
Dave Wallace2a865272018-02-07 21:00:42 -0500902 libc_bits_set = clib_bitmap_last_set (ldp->libc_wr_bitmap) + 1;
Dave Wallace048b1d62018-01-03 22:24:41 -0500903 libc_bits = (libc_bits_set > libc_bits) ? libc_bits_set : libc_bits;
904
Florin Coras173bae32018-11-16 18:56:28 -0800905 LDBG (3, "LDP<%d>: writefds: sid_bits_set %d, sid_bits %d, "
906 "libc_bits_set %d, libc_bits %d", getpid (),
907 sid_bits_set, sid_bits, libc_bits_set, libc_bits);
Dave Wallace048b1d62018-01-03 22:24:41 -0500908 }
909 if (exceptfds)
910 {
Dave Wallace2a865272018-02-07 21:00:42 -0500911 clib_bitmap_validate (ldp->sid_ex_bitmap, minbits);
912 clib_bitmap_validate (ldp->libc_ex_bitmap, minbits);
913 clib_bitmap_validate (ldp->ex_bitmap, minbits);
Florin Coras173bae32018-11-16 18:56:28 -0800914 clib_memcpy_fast (ldp->ex_bitmap, exceptfds, n_bytes);
915 memset (exceptfds, 0, n_bytes);
Dave Wallace048b1d62018-01-03 22:24:41 -0500916
917 /* *INDENT-OFF* */
Florin Coras173bae32018-11-16 18:56:28 -0800918 clib_bitmap_foreach (fd, ldp->ex_bitmap, ({
919 if (fd > nfds)
920 break;
921 sid = ldp_sid_from_fd (fd);
922 LDBG (3, "LDP<%d>: exceptfds: fd %d (0x%x), sid %u (0x%x)",
923 getpid (), fd, fd, sid, sid);
924 if (sid == INVALID_SESSION_ID)
925 clib_bitmap_set_no_check (ldp->libc_ex_bitmap, fd, 1);
926 else
927 clib_bitmap_set_no_check (ldp->sid_ex_bitmap, sid, 1);
928 }));
Dave Wallace048b1d62018-01-03 22:24:41 -0500929 /* *INDENT-ON* */
930
Dave Wallace2a865272018-02-07 21:00:42 -0500931 sid_bits_set = clib_bitmap_last_set (ldp->sid_ex_bitmap) + 1;
Dave Wallace048b1d62018-01-03 22:24:41 -0500932 sid_bits = (sid_bits_set > sid_bits) ? sid_bits_set : sid_bits;
933
Dave Wallace2a865272018-02-07 21:00:42 -0500934 libc_bits_set = clib_bitmap_last_set (ldp->libc_ex_bitmap) + 1;
Dave Wallace048b1d62018-01-03 22:24:41 -0500935 libc_bits = (libc_bits_set > libc_bits) ? libc_bits_set : libc_bits;
936
Florin Coras173bae32018-11-16 18:56:28 -0800937 LDBG (3, "LDP<%d>: exceptfds: sid_bits_set %d, sid_bits %d, "
938 "libc_bits_set %d, libc_bits %d", getpid (),
939 sid_bits_set, sid_bits, libc_bits_set, libc_bits);
Dave Wallace048b1d62018-01-03 22:24:41 -0500940 }
941
942 if (PREDICT_FALSE (!sid_bits && !libc_bits))
943 {
944 errno = EINVAL;
945 rv = -1;
946 goto done;
947 }
948
949 do
950 {
951 if (sid_bits)
952 {
Dave Wallace2a865272018-02-07 21:00:42 -0500953 if (!ldp->select_vcl)
Dave Wallace048b1d62018-01-03 22:24:41 -0500954 {
955 func_str = "vppcom_select";
956
957 if (readfds)
Dave Barach178cf492018-11-13 16:34:13 -0500958 clib_memcpy_fast (ldp->rd_bitmap, ldp->sid_rd_bitmap,
959 vec_len (ldp->rd_bitmap) *
960 sizeof (clib_bitmap_t));
Dave Wallace048b1d62018-01-03 22:24:41 -0500961 if (writefds)
Dave Barach178cf492018-11-13 16:34:13 -0500962 clib_memcpy_fast (ldp->wr_bitmap, ldp->sid_wr_bitmap,
963 vec_len (ldp->wr_bitmap) *
964 sizeof (clib_bitmap_t));
Dave Wallace048b1d62018-01-03 22:24:41 -0500965 if (exceptfds)
Dave Barach178cf492018-11-13 16:34:13 -0500966 clib_memcpy_fast (ldp->ex_bitmap, ldp->sid_ex_bitmap,
967 vec_len (ldp->ex_bitmap) *
968 sizeof (clib_bitmap_t));
Dave Wallace048b1d62018-01-03 22:24:41 -0500969
970 rv = vppcom_select (sid_bits,
Dave Wallace2a865272018-02-07 21:00:42 -0500971 readfds ? ldp->rd_bitmap : NULL,
972 writefds ? ldp->wr_bitmap : NULL,
973 exceptfds ? ldp->ex_bitmap : NULL, 0);
Dave Wallace048b1d62018-01-03 22:24:41 -0500974 if (rv < 0)
975 {
976 errno = -rv;
977 rv = -1;
978 }
979 else if (rv > 0)
980 {
981 if (readfds)
982 {
983 /* *INDENT-OFF* */
Dave Wallace2a865272018-02-07 21:00:42 -0500984 clib_bitmap_foreach (sid, ldp->rd_bitmap,
Dave Wallace048b1d62018-01-03 22:24:41 -0500985 ({
Dave Wallace2a865272018-02-07 21:00:42 -0500986 fd = ldp_fd_from_sid (sid);
Dave Wallace048b1d62018-01-03 22:24:41 -0500987 if (PREDICT_FALSE (fd < 0))
988 {
989 errno = EBADFD;
990 rv = -1;
991 goto done;
992 }
993 FD_SET (fd, readfds);
994 }));
995 /* *INDENT-ON* */
996 }
997 if (writefds)
998 {
999 /* *INDENT-OFF* */
Dave Wallace2a865272018-02-07 21:00:42 -05001000 clib_bitmap_foreach (sid, ldp->wr_bitmap,
Dave Wallace048b1d62018-01-03 22:24:41 -05001001 ({
Dave Wallace2a865272018-02-07 21:00:42 -05001002 fd = ldp_fd_from_sid (sid);
Dave Wallace048b1d62018-01-03 22:24:41 -05001003 if (PREDICT_FALSE (fd < 0))
1004 {
1005 errno = EBADFD;
1006 rv = -1;
1007 goto done;
1008 }
1009 FD_SET (fd, writefds);
1010 }));
1011 /* *INDENT-ON* */
1012 }
1013 if (exceptfds)
1014 {
1015 /* *INDENT-OFF* */
Dave Wallace2a865272018-02-07 21:00:42 -05001016 clib_bitmap_foreach (sid, ldp->ex_bitmap,
Dave Wallace048b1d62018-01-03 22:24:41 -05001017 ({
Dave Wallace2a865272018-02-07 21:00:42 -05001018 fd = ldp_fd_from_sid (sid);
Dave Wallace048b1d62018-01-03 22:24:41 -05001019 if (PREDICT_FALSE (fd < 0))
1020 {
1021 errno = EBADFD;
1022 rv = -1;
1023 goto done;
1024 }
1025 FD_SET (fd, exceptfds);
1026 }));
1027 /* *INDENT-ON* */
1028 }
Dave Wallace2a865272018-02-07 21:00:42 -05001029 ldp->select_vcl = 1;
Dave Wallace048b1d62018-01-03 22:24:41 -05001030 goto done;
1031 }
1032 }
1033 else
Dave Wallace2a865272018-02-07 21:00:42 -05001034 ldp->select_vcl = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -05001035 }
1036 if (libc_bits)
1037 {
1038 struct timespec tspec;
1039
1040 func_str = "libc_pselect";
1041
1042 if (readfds)
Dave Barach178cf492018-11-13 16:34:13 -05001043 clib_memcpy_fast (readfds, ldp->libc_rd_bitmap,
1044 vec_len (ldp->rd_bitmap) *
1045 sizeof (clib_bitmap_t));
Dave Wallace048b1d62018-01-03 22:24:41 -05001046 if (writefds)
Dave Barach178cf492018-11-13 16:34:13 -05001047 clib_memcpy_fast (writefds, ldp->libc_wr_bitmap,
1048 vec_len (ldp->wr_bitmap) *
1049 sizeof (clib_bitmap_t));
Dave Wallace048b1d62018-01-03 22:24:41 -05001050 if (exceptfds)
Dave Barach178cf492018-11-13 16:34:13 -05001051 clib_memcpy_fast (exceptfds, ldp->libc_ex_bitmap,
1052 vec_len (ldp->ex_bitmap) *
1053 sizeof (clib_bitmap_t));
Dave Wallace048b1d62018-01-03 22:24:41 -05001054 tspec.tv_sec = tspec.tv_nsec = 0;
1055 rv = libc_pselect (libc_bits,
1056 readfds ? readfds : NULL,
1057 writefds ? writefds : NULL,
1058 exceptfds ? exceptfds : NULL, &tspec, sigmask);
1059 if (rv != 0)
1060 goto done;
1061 }
1062 }
Dave Wallace2a865272018-02-07 21:00:42 -05001063 while ((time_out == -1) || (clib_time_now (&ldp->clib_time) < time_out));
Dave Wallace048b1d62018-01-03 22:24:41 -05001064 rv = 0;
1065
1066done:
1067 /* TBD: set timeout to amount of time left */
Florin Coras173bae32018-11-16 18:56:28 -08001068 clib_bitmap_zero (ldp->rd_bitmap);
1069 clib_bitmap_zero (ldp->sid_rd_bitmap);
1070 clib_bitmap_zero (ldp->libc_rd_bitmap);
1071 clib_bitmap_zero (ldp->wr_bitmap);
1072 clib_bitmap_zero (ldp->sid_wr_bitmap);
1073 clib_bitmap_zero (ldp->libc_wr_bitmap);
1074 clib_bitmap_zero (ldp->ex_bitmap);
1075 clib_bitmap_zero (ldp->sid_ex_bitmap);
1076 clib_bitmap_zero (ldp->libc_ex_bitmap);
Dave Wallace048b1d62018-01-03 22:24:41 -05001077
Dave Wallace2a865272018-02-07 21:00:42 -05001078 if (LDP_DEBUG > 3)
Dave Wallace048b1d62018-01-03 22:24:41 -05001079 {
1080 if (rv < 0)
1081 {
1082 int errno_val = errno;
1083 perror (func_str);
1084 clib_warning ("LDP<%d>: ERROR: %s() failed! "
1085 "rv %d, errno = %d", getpid (),
1086 func_str, rv, errno_val);
1087 errno = errno_val;
1088 }
1089 else
1090 clib_warning ("LDP<%d>: returning %d (0x%x)", getpid (), rv, rv);
1091 }
1092 return rv;
1093}
1094
1095int
1096select (int nfds, fd_set * __restrict readfds,
1097 fd_set * __restrict writefds,
1098 fd_set * __restrict exceptfds, struct timeval *__restrict timeout)
1099{
1100 struct timespec tspec;
1101
1102 if (timeout)
1103 {
1104 tspec.tv_sec = timeout->tv_sec;
1105 tspec.tv_nsec = timeout->tv_usec * 1000;
1106 }
Dave Wallace2a865272018-02-07 21:00:42 -05001107 return ldp_pselect (nfds, readfds, writefds, exceptfds,
1108 timeout ? &tspec : NULL, NULL);
Dave Wallace048b1d62018-01-03 22:24:41 -05001109}
1110
1111#ifdef __USE_XOPEN2K
1112int
1113pselect (int nfds, fd_set * __restrict readfds,
1114 fd_set * __restrict writefds,
1115 fd_set * __restrict exceptfds,
1116 const struct timespec *__restrict timeout,
1117 const __sigset_t * __restrict sigmask)
1118{
Dave Wallace2a865272018-02-07 21:00:42 -05001119 return ldp_pselect (nfds, readfds, writefds, exceptfds, timeout, 0);
Dave Wallace048b1d62018-01-03 22:24:41 -05001120}
1121#endif
1122
1123int
1124socket (int domain, int type, int protocol)
1125{
1126 const char *func_str;
1127 int rv;
1128 u8 is_nonblocking = type & SOCK_NONBLOCK ? 1 : 0;
1129 int sock_type = type & ~(SOCK_CLOEXEC | SOCK_NONBLOCK);
1130
Dave Wallace2a865272018-02-07 21:00:42 -05001131 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001132 return -1;
1133
1134 if (((domain == AF_INET) || (domain == AF_INET6)) &&
1135 ((sock_type == SOCK_STREAM) || (sock_type == SOCK_DGRAM)))
1136 {
1137 int sid;
Dave Wallace048b1d62018-01-03 22:24:41 -05001138 u8 proto = ((sock_type == SOCK_DGRAM) ?
1139 VPPCOM_PROTO_UDP : VPPCOM_PROTO_TCP);
1140
1141 func_str = "vppcom_session_create";
1142
Florin Coras99368312018-08-02 10:45:44 -07001143 LDBG (0, "LDP<%d>: : calling %s(): proto %u (%s), is_nonblocking %u",
1144 getpid (), func_str, proto, vppcom_proto_str (proto),
1145 is_nonblocking);
Dave Wallace048b1d62018-01-03 22:24:41 -05001146
Dave Wallacec04cbf12018-02-07 18:14:02 -05001147 sid = vppcom_session_create (proto, is_nonblocking);
Dave Wallace048b1d62018-01-03 22:24:41 -05001148 if (sid < 0)
1149 {
1150 errno = -sid;
1151 rv = -1;
1152 }
1153 else
1154 {
Dave Wallace2a865272018-02-07 21:00:42 -05001155 func_str = "ldp_fd_from_sid";
1156 rv = ldp_fd_from_sid (sid);
Dave Wallace048b1d62018-01-03 22:24:41 -05001157 if (rv < 0)
1158 {
1159 (void) vppcom_session_close (sid);
1160 errno = -rv;
1161 rv = -1;
1162 }
1163 }
1164 }
1165 else
1166 {
1167 func_str = "libc_socket";
1168
Florin Coras99368312018-08-02 10:45:44 -07001169 LDBG (0, "LDP<%d>: : calling %s()", getpid (), func_str);
Dave Wallace048b1d62018-01-03 22:24:41 -05001170
1171 rv = libc_socket (domain, type, protocol);
1172 }
1173
Dave Wallace2a865272018-02-07 21:00:42 -05001174 if (LDP_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001175 {
1176 if (rv < 0)
1177 {
1178 int errno_val = errno;
1179 perror (func_str);
1180 clib_warning ("LDP<%d>: ERROR: %s() failed! "
1181 "rv %d, errno = %d",
1182 getpid (), func_str, rv, errno_val);
1183 errno = errno_val;
1184 }
1185 else
1186 clib_warning ("LDP<%d>: : returning fd %d (0x%x)", getpid (), rv, rv);
1187 }
1188 return rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001189}
1190
1191/*
1192 * Create two new sockets, of type TYPE in domain DOMAIN and using
1193 * protocol PROTOCOL, which are connected to each other, and put file
1194 * descriptors for them in FDS[0] and FDS[1]. If PROTOCOL is zero,
1195 * one will be chosen automatically.
1196 * Returns 0 on success, -1 for errors.
1197 * */
1198int
Dave Wallace048b1d62018-01-03 22:24:41 -05001199socketpair (int domain, int type, int protocol, int fds[2])
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001200{
Dave Wallace048b1d62018-01-03 22:24:41 -05001201 const char *func_str;
1202 int rv;
1203 int sock_type = type & ~(SOCK_CLOEXEC | SOCK_NONBLOCK);
1204
Dave Wallace2a865272018-02-07 21:00:42 -05001205 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001206 return -1;
1207
1208 if (((domain == AF_INET) || (domain == AF_INET6)) &&
1209 ((sock_type == SOCK_STREAM) || (sock_type == SOCK_DGRAM)))
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001210 {
Dave Wallace8aaba562018-01-18 17:21:19 -05001211 func_str = __func__;
1212
Dave Wallace048b1d62018-01-03 22:24:41 -05001213 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
1214 errno = ENOSYS;
1215 rv = -1;
1216 }
1217 else
1218 {
1219 func_str = "libc_socket";
1220
Florin Coras173bae32018-11-16 18:56:28 -08001221 LDBG (1, "LDP<%d>: : calling %s()", getpid (), func_str);
Dave Wallace048b1d62018-01-03 22:24:41 -05001222
Florin Coras173bae32018-11-16 18:56:28 -08001223 rv = libc_socketpair (domain, type, protocol, fds);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001224 }
1225
Dave Wallace2a865272018-02-07 21:00:42 -05001226 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05001227 {
1228 if (rv < 0)
1229 {
1230 int errno_val = errno;
1231 perror (func_str);
1232 clib_warning ("LDP<%d>: ERROR: %s() failed! "
1233 "rv %d, errno = %d",
1234 getpid (), func_str, rv, errno_val);
1235 errno = errno_val;
1236 }
1237 else
1238 clib_warning ("LDP<%d>: : returning fd %d (0x%x)", getpid (), rv, rv);
1239 }
1240 return rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001241}
1242
1243int
Dave Wallace048b1d62018-01-03 22:24:41 -05001244bind (int fd, __CONST_SOCKADDR_ARG addr, socklen_t len)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001245{
1246 int rv;
Dave Wallace048b1d62018-01-03 22:24:41 -05001247 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05001248 u32 sid = ldp_sid_from_fd (fd);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001249
Dave Wallace2a865272018-02-07 21:00:42 -05001250 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001251 return -1;
1252
1253 if (sid != INVALID_SESSION_ID)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001254 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001255 vppcom_endpt_t ep;
1256
1257 func_str = "vppcom_session_bind";
1258
Dave Wallace048b1d62018-01-03 22:24:41 -05001259 switch (addr->sa_family)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001260 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001261 case AF_INET:
1262 if (len != sizeof (struct sockaddr_in))
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001263 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001264 clib_warning
1265 ("LDP<%d>: ERROR: fd %d (0x%x): sid %u (0x%x): Invalid "
1266 "AF_INET addr len %u!", getpid (), fd, fd, sid, sid, len);
1267 errno = EINVAL;
1268 rv = -1;
1269 goto done;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001270 }
Dave Wallace048b1d62018-01-03 22:24:41 -05001271 ep.is_ip4 = VPPCOM_IS_IP4;
1272 ep.ip = (u8 *) & ((const struct sockaddr_in *) addr)->sin_addr;
1273 ep.port = (u16) ((const struct sockaddr_in *) addr)->sin_port;
1274 break;
1275
1276 case AF_INET6:
1277 if (len != sizeof (struct sockaddr_in6))
1278 {
1279 clib_warning
1280 ("LDP<%d>: ERROR: fd %d (0x%x): sid %u (0x%x): Invalid "
1281 "AF_INET6 addr len %u!", getpid (), fd, fd, sid, sid, len);
1282 errno = EINVAL;
1283 rv = -1;
1284 goto done;
1285 }
1286 ep.is_ip4 = VPPCOM_IS_IP6;
1287 ep.ip = (u8 *) & ((const struct sockaddr_in6 *) addr)->sin6_addr;
1288 ep.port = (u16) ((const struct sockaddr_in6 *) addr)->sin6_port;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001289 break;
1290
1291 default:
Dave Wallace048b1d62018-01-03 22:24:41 -05001292 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): sid %u (0x%x): "
1293 "Unsupported address family %u!",
1294 getpid (), fd, fd, sid, sid, addr->sa_family);
1295 errno = EAFNOSUPPORT;
1296 rv = -1;
1297 goto done;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001298 }
Dave Wallace2a865272018-02-07 21:00:42 -05001299 if (LDP_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001300 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), "
1301 "addr %p, len %u",
1302 getpid (), fd, fd, func_str, sid, sid, addr, len);
1303
1304 rv = vppcom_session_bind (sid, &ep);
1305 if (rv != VPPCOM_OK)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001306 {
1307 errno = -rv;
Dave Wallace048b1d62018-01-03 22:24:41 -05001308 rv = -1;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001309 }
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001310 }
Dave Wallace048b1d62018-01-03 22:24:41 -05001311 else
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001312 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001313 func_str = "libc_bind";
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001314
Dave Wallace2a865272018-02-07 21:00:42 -05001315 if (LDP_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001316 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1317 "addr %p, len %u",
1318 getpid (), fd, fd, func_str, addr, len);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001319
Dave Wallace048b1d62018-01-03 22:24:41 -05001320 rv = libc_bind (fd, addr, len);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001321 }
1322
Dave Wallace048b1d62018-01-03 22:24:41 -05001323done:
Dave Wallace2a865272018-02-07 21:00:42 -05001324 if (LDP_DEBUG > 0)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001325 {
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001326 if (rv < 0)
1327 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001328 int errno_val = errno;
1329 perror (func_str);
1330 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
1331 "rv %d, errno = %d", getpid (), fd, fd,
1332 func_str, rv, errno_val);
1333 errno = errno_val;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001334 }
Dave Wallace048b1d62018-01-03 22:24:41 -05001335 else
1336 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
1337 getpid (), fd, fd, rv, rv);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001338 }
1339 return rv;
1340}
1341
1342static inline int
Dave Wallace2a865272018-02-07 21:00:42 -05001343ldp_copy_ep_to_sockaddr (__SOCKADDR_ARG addr, socklen_t * __restrict len,
1344 vppcom_endpt_t * ep)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001345{
Dave Wallace048b1d62018-01-03 22:24:41 -05001346 int rv = 0;
1347 int sa_len, copy_len;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001348
Dave Wallace2a865272018-02-07 21:00:42 -05001349 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001350 return -1;
1351
1352 if (addr && len && ep)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001353 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001354 addr->sa_family = (ep->is_ip4 == VPPCOM_IS_IP4) ? AF_INET : AF_INET6;
1355 switch (addr->sa_family)
1356 {
1357 case AF_INET:
1358 ((struct sockaddr_in *) addr)->sin_port = ep->port;
1359 if (*len > sizeof (struct sockaddr_in))
1360 *len = sizeof (struct sockaddr_in);
1361 sa_len = sizeof (struct sockaddr_in) - sizeof (struct in_addr);
1362 copy_len = *len - sa_len;
1363 if (copy_len > 0)
1364 memcpy (&((struct sockaddr_in *) addr)->sin_addr, ep->ip,
1365 copy_len);
1366 break;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001367
Dave Wallace048b1d62018-01-03 22:24:41 -05001368 case AF_INET6:
1369 ((struct sockaddr_in6 *) addr)->sin6_port = ep->port;
1370 if (*len > sizeof (struct sockaddr_in6))
1371 *len = sizeof (struct sockaddr_in6);
1372 sa_len = sizeof (struct sockaddr_in6) - sizeof (struct in6_addr);
1373 copy_len = *len - sa_len;
1374 if (copy_len > 0)
1375 memcpy (((struct sockaddr_in6 *) addr)->sin6_addr.
1376 __in6_u.__u6_addr8, ep->ip, copy_len);
1377 break;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001378
Dave Wallace048b1d62018-01-03 22:24:41 -05001379 default:
1380 /* Not possible */
1381 rv = -EAFNOSUPPORT;
1382 break;
1383 }
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001384 }
Dave Wallacee695cb42017-11-02 22:04:42 -04001385 return rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001386}
1387
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001388int
Dave Wallace048b1d62018-01-03 22:24:41 -05001389getsockname (int fd, __SOCKADDR_ARG addr, socklen_t * __restrict len)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001390{
1391 int rv;
Dave Wallace048b1d62018-01-03 22:24:41 -05001392 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05001393 u32 sid = ldp_sid_from_fd (fd);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001394
Dave Wallace2a865272018-02-07 21:00:42 -05001395 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001396 return -1;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001397
Dave Wallace048b1d62018-01-03 22:24:41 -05001398 if (sid != INVALID_SESSION_ID)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001399 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001400 vppcom_endpt_t ep;
1401 u8 addr_buf[sizeof (struct in6_addr)];
1402 u32 size = sizeof (ep);
1403
1404 ep.ip = addr_buf;
1405 func_str = "vppcom_session_attr[GET_LCL_ADDR]";
1406
Dave Wallace2a865272018-02-07 21:00:42 -05001407 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001408 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), "
1409 "addr %p, len %u",
1410 getpid (), fd, fd, func_str, sid, sid, addr, len);
1411
1412 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_LCL_ADDR, &ep, &size);
1413 if (rv != VPPCOM_OK)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001414 {
1415 errno = -rv;
Dave Wallace048b1d62018-01-03 22:24:41 -05001416 rv = -1;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001417 }
Dave Wallace048b1d62018-01-03 22:24:41 -05001418 else
1419 {
Dave Wallace2a865272018-02-07 21:00:42 -05001420 rv = ldp_copy_ep_to_sockaddr (addr, len, &ep);
Dave Wallace048b1d62018-01-03 22:24:41 -05001421 if (rv != VPPCOM_OK)
1422 {
1423 errno = -rv;
1424 rv = -1;
1425 }
1426 }
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001427 }
1428 else
1429 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001430 func_str = "libc_getsockname";
1431
Dave Wallace2a865272018-02-07 21:00:42 -05001432 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001433 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1434 "addr %p, len %u",
1435 getpid (), fd, fd, func_str, addr, len);
1436
1437 rv = libc_getsockname (fd, addr, len);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001438 }
1439
Dave Wallace2a865272018-02-07 21:00:42 -05001440 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001441 {
1442 if (rv < 0)
1443 {
1444 int errno_val = errno;
1445 perror (func_str);
1446 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
1447 "rv %d, errno = %d", getpid (), fd, fd,
1448 func_str, rv, errno_val);
1449 errno = errno_val;
1450 }
1451 else
1452 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
1453 getpid (), fd, fd, rv, rv);
1454 }
1455 return rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001456}
1457
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001458int
Dave Wallace048b1d62018-01-03 22:24:41 -05001459connect (int fd, __CONST_SOCKADDR_ARG addr, socklen_t len)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001460{
Dave Wallace048b1d62018-01-03 22:24:41 -05001461 int rv;
1462 const char *func_str = __func__;
Dave Wallace2a865272018-02-07 21:00:42 -05001463 u32 sid = ldp_sid_from_fd (fd);
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001464
Dave Wallace2a865272018-02-07 21:00:42 -05001465 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001466 return -1;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001467
Dave Wallace048b1d62018-01-03 22:24:41 -05001468 if (!addr)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001469 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001470 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): NULL addr, len %u",
1471 getpid (), fd, fd, len);
1472 errno = EINVAL;
1473 rv = -1;
1474 goto done;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001475 }
1476
Dave Wallace048b1d62018-01-03 22:24:41 -05001477 if (sid != INVALID_SESSION_ID)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001478 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001479 vppcom_endpt_t ep;
1480
1481 func_str = "vppcom_session_connect";
1482
Dave Wallace048b1d62018-01-03 22:24:41 -05001483 switch (addr->sa_family)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001484 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001485 case AF_INET:
1486 if (len != sizeof (struct sockaddr_in))
1487 {
1488 clib_warning
1489 ("LDP<%d>: fd %d (0x%x): ERROR sid %u (0x%x): Invalid "
1490 "AF_INET addr len %u!", getpid (), fd, fd, sid, sid, len);
1491 errno = EINVAL;
1492 rv = -1;
1493 goto done;
1494 }
1495 ep.is_ip4 = VPPCOM_IS_IP4;
1496 ep.ip = (u8 *) & ((const struct sockaddr_in *) addr)->sin_addr;
1497 ep.port = (u16) ((const struct sockaddr_in *) addr)->sin_port;
1498 break;
1499
1500 case AF_INET6:
1501 if (len != sizeof (struct sockaddr_in6))
1502 {
1503 clib_warning
1504 ("LDP<%d>: fd %d (0x%x): ERROR sid %u (0x%x): Invalid "
1505 "AF_INET6 addr len %u!", getpid (), fd, fd, sid, sid, len);
1506 errno = EINVAL;
1507 rv = -1;
1508 goto done;
1509 }
1510 ep.is_ip4 = VPPCOM_IS_IP6;
1511 ep.ip = (u8 *) & ((const struct sockaddr_in6 *) addr)->sin6_addr;
1512 ep.port = (u16) ((const struct sockaddr_in6 *) addr)->sin6_port;
1513 break;
1514
1515 default:
1516 clib_warning ("LDP<%d>: fd %d (0x%x): ERROR sid %u (0x%x): "
1517 "Unsupported address family %u!",
1518 getpid (), fd, fd, sid, sid, addr->sa_family);
1519 errno = EAFNOSUPPORT;
1520 rv = -1;
1521 goto done;
1522 }
Dave Wallace2a865272018-02-07 21:00:42 -05001523 if (LDP_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001524 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x) "
1525 "addr %p len %u",
1526 getpid (), fd, fd, func_str, sid, sid, addr, len);
1527
1528 rv = vppcom_session_connect (sid, &ep);
1529 if (rv != VPPCOM_OK)
1530 {
1531 errno = -rv;
1532 rv = -1;
1533 }
1534 }
1535 else
1536 {
1537 func_str = "libc_connect";
1538
Dave Wallace2a865272018-02-07 21:00:42 -05001539 if (LDP_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001540 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1541 "addr %p, len %u",
1542 getpid (), fd, fd, func_str, addr, len);
1543
1544 rv = libc_connect (fd, addr, len);
1545 }
1546
1547done:
Dave Wallace2a865272018-02-07 21:00:42 -05001548 if (LDP_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05001549 {
1550 if (rv < 0)
1551 {
1552 int errno_val = errno;
1553 perror (func_str);
1554 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
1555 "rv %d, errno = %d", getpid (), fd, fd,
1556 func_str, rv, errno_val);
1557 errno = errno_val;
1558 }
1559 else
1560 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
1561 getpid (), fd, fd, rv, rv);
1562 }
1563 return rv;
1564}
1565
1566int
1567getpeername (int fd, __SOCKADDR_ARG addr, socklen_t * __restrict len)
1568{
1569 int rv;
1570 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05001571 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05001572
Dave Wallace2a865272018-02-07 21:00:42 -05001573 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001574 return -1;
1575
Dave Wallace048b1d62018-01-03 22:24:41 -05001576 if (sid != INVALID_SESSION_ID)
1577 {
1578 vppcom_endpt_t ep;
1579 u8 addr_buf[sizeof (struct in6_addr)];
1580 u32 size = sizeof (ep);
1581
1582 ep.ip = addr_buf;
1583 func_str = "vppcom_session_attr[GET_PEER_ADDR]";
1584
Dave Wallace2a865272018-02-07 21:00:42 -05001585 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001586 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), "
1587 "addr %p, len %u",
1588 getpid (), fd, fd, func_str, sid, sid, addr, len);
1589
1590 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_PEER_ADDR, &ep, &size);
1591 if (rv != VPPCOM_OK)
1592 {
1593 errno = -rv;
1594 rv = -1;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001595 }
1596 else
1597 {
Dave Wallace2a865272018-02-07 21:00:42 -05001598 rv = ldp_copy_ep_to_sockaddr (addr, len, &ep);
Dave Wallace048b1d62018-01-03 22:24:41 -05001599 if (rv != VPPCOM_OK)
1600 {
1601 errno = -rv;
1602 rv = -1;
1603 }
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001604 }
1605 }
Dave Wallace048b1d62018-01-03 22:24:41 -05001606 else
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001607 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001608 func_str = "libc_getpeername";
1609
Dave Wallace2a865272018-02-07 21:00:42 -05001610 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001611 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1612 "addr %p, len %u",
1613 getpid (), fd, fd, func_str, addr, len);
1614
1615 rv = libc_getpeername (fd, addr, len);
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001616 }
1617
Dave Wallace2a865272018-02-07 21:00:42 -05001618 if (LDP_DEBUG > 2)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001619 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001620 if (rv < 0)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001621 {
Dave Wallace048b1d62018-01-03 22:24:41 -05001622 int errno_val = errno;
1623 perror (func_str);
1624 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
1625 "rv %d, errno = %d", getpid (), fd, fd,
1626 func_str, rv, errno_val);
1627 errno = errno_val;
1628 }
1629 else
1630 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
1631 getpid (), fd, fd, rv, rv);
1632 }
1633 return rv;
1634}
1635
1636ssize_t
1637send (int fd, const void *buf, size_t n, int flags)
1638{
1639 ssize_t size;
1640 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05001641 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05001642
Dave Wallace2a865272018-02-07 21:00:42 -05001643 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001644 return -1;
1645
1646 if (sid != INVALID_SESSION_ID)
1647 {
1648
1649 func_str = "vppcom_session_sendto";
1650
Dave Wallace2a865272018-02-07 21:00:42 -05001651 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001652 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), "
1653 "buf %p, n %u, flags 0x%x",
1654 getpid (), fd, fd, func_str, sid, sid, buf, n, flags);
1655
1656 size = vppcom_session_sendto (sid, (void *) buf, n, flags, NULL);
qchangaa8f63c2018-05-30 11:44:18 -07001657 if (size < VPPCOM_OK)
Dave Wallace048b1d62018-01-03 22:24:41 -05001658 {
1659 errno = -size;
1660 size = -1;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07001661 }
1662 }
Dave Wallace048b1d62018-01-03 22:24:41 -05001663 else
1664 {
1665 func_str = "libc_send";
1666
Dave Wallace2a865272018-02-07 21:00:42 -05001667 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001668 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1669 "buf %p, n %u, flags 0x%x",
1670 getpid (), fd, fd, func_str, buf, n, flags);
1671
1672 size = libc_send (fd, buf, n, flags);
1673 }
1674
Dave Wallace2a865272018-02-07 21:00:42 -05001675 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001676 {
1677 if (size < 0)
1678 {
1679 int errno_val = errno;
1680 perror (func_str);
1681 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
1682 "rv %d, errno = %d", getpid (), fd, fd,
1683 func_str, size, errno_val);
1684 errno = errno_val;
1685 }
1686 else
1687 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
1688 getpid (), fd, fd, size, size);
1689 }
1690 return size;
1691}
1692
1693ssize_t
1694sendfile (int out_fd, int in_fd, off_t * offset, size_t len)
1695{
1696 ssize_t size = 0;
1697 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05001698 u32 sid = ldp_sid_from_fd (out_fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05001699
Dave Wallace2a865272018-02-07 21:00:42 -05001700 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001701 return -1;
1702
1703 if (sid != INVALID_SESSION_ID)
1704 {
1705 int rv;
1706 ssize_t results = 0;
1707 size_t n_bytes_left = len;
1708 size_t bytes_to_read;
1709 int nbytes;
1710 int errno_val;
1711 u8 eagain = 0;
1712 u32 flags, flags_len = sizeof (flags);
1713
1714 func_str = "vppcom_session_attr[GET_FLAGS]";
1715 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_FLAGS, &flags,
1716 &flags_len);
1717 if (PREDICT_FALSE (rv != VPPCOM_OK))
1718 {
1719 clib_warning ("LDP<%d>: ERROR: out fd %d (0x%x): %s(): "
1720 "sid %u (0x%x), returned %d (%s)!", getpid (),
1721 out_fd, out_fd, func_str, sid, sid, rv,
1722 vppcom_retval_str (rv));
1723
Dave Wallace2a865272018-02-07 21:00:42 -05001724 vec_reset_length (ldp->io_buffer);
Dave Wallace048b1d62018-01-03 22:24:41 -05001725 errno = -rv;
1726 size = -1;
1727 goto done;
1728 }
1729
1730 if (offset)
1731 {
1732 off_t off = lseek (in_fd, *offset, SEEK_SET);
1733 if (PREDICT_FALSE (off == -1))
1734 {
1735 func_str = "lseek";
1736 errno_val = errno;
1737 clib_warning ("LDP<%d>: ERROR: out fd %d (0x%x): %s(): "
1738 "SEEK_SET failed: in_fd %d, offset %p, "
1739 "*offset %ld, rv %ld, errno %d", getpid (),
1740 out_fd, out_fd, in_fd, offset, *offset, off,
1741 errno_val);
1742 errno = errno_val;
1743 size = -1;
1744 goto done;
1745 }
1746
1747 ASSERT (off == *offset);
1748 }
1749
1750 do
1751 {
1752 func_str = "vppcom_session_attr[GET_NWRITE]";
1753 size = vppcom_session_attr (sid, VPPCOM_ATTR_GET_NWRITE, 0, 0);
1754 if (size < 0)
1755 {
1756 clib_warning
1757 ("LDP<%d>: ERROR: fd %d (0x%x): %s(): sid %u (0x%x), "
1758 "returned %d (%s)!", getpid (), out_fd, out_fd, func_str,
1759 sid, sid, size, vppcom_retval_str (size));
Dave Wallace2a865272018-02-07 21:00:42 -05001760 vec_reset_length (ldp->io_buffer);
Dave Wallace048b1d62018-01-03 22:24:41 -05001761 errno = -size;
1762 size = -1;
1763 goto done;
1764 }
1765
1766 bytes_to_read = size;
Dave Wallace2a865272018-02-07 21:00:42 -05001767 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001768 clib_warning
1769 ("LDP<%d>: fd %d (0x%x): called %s(): sid %u (0x%x), "
1770 "results %ld, n_bytes_left %lu, bytes_to_read %lu", getpid (),
1771 out_fd, out_fd, func_str, sid, sid, results, n_bytes_left,
1772 bytes_to_read);
1773
1774 if (bytes_to_read == 0)
1775 {
1776 if (flags & O_NONBLOCK)
1777 {
1778 if (!results)
1779 {
Dave Wallace2a865272018-02-07 21:00:42 -05001780 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001781 clib_warning ("LDP<%d>: fd %d (0x%x): sid %u (0x%x): "
1782 "EAGAIN",
1783 getpid (), out_fd, out_fd, sid, sid);
1784 eagain = 1;
1785 }
1786 goto update_offset;
1787 }
1788 else
1789 continue;
1790 }
1791 bytes_to_read = clib_min (n_bytes_left, bytes_to_read);
Dave Wallace2a865272018-02-07 21:00:42 -05001792 vec_validate (ldp->io_buffer, bytes_to_read);
1793 nbytes = libc_read (in_fd, ldp->io_buffer, bytes_to_read);
Dave Wallace048b1d62018-01-03 22:24:41 -05001794 if (nbytes < 0)
1795 {
1796 func_str = "libc_read";
1797 errno_val = errno;
1798 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): in_fd (%d), "
1799 "io_buffer %p, bytes_to_read %lu, rv %d, "
1800 "errno %d", getpid (), out_fd, out_fd, func_str,
Dave Wallace2a865272018-02-07 21:00:42 -05001801 in_fd, ldp->io_buffer, bytes_to_read, nbytes,
Dave Wallace048b1d62018-01-03 22:24:41 -05001802 errno_val);
1803 errno = errno_val;
1804
1805 if (results == 0)
1806 {
Dave Wallace2a865272018-02-07 21:00:42 -05001807 vec_reset_length (ldp->io_buffer);
Dave Wallace048b1d62018-01-03 22:24:41 -05001808 size = -1;
1809 goto done;
1810 }
1811 goto update_offset;
1812 }
1813 func_str = "vppcom_session_write";
Dave Wallace2a865272018-02-07 21:00:42 -05001814 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001815 clib_warning
1816 ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), "
1817 "buf %p, nbytes %u: results %d, n_bytes_left %d", getpid (),
Dave Wallace2a865272018-02-07 21:00:42 -05001818 out_fd, out_fd, func_str, sid, sid, ldp->io_buffer, nbytes,
Dave Wallace048b1d62018-01-03 22:24:41 -05001819 results, n_bytes_left);
1820
Dave Wallace2a865272018-02-07 21:00:42 -05001821 size = vppcom_session_write (sid, ldp->io_buffer, nbytes);
Dave Wallace048b1d62018-01-03 22:24:41 -05001822 if (size < 0)
1823 {
1824 if (size == VPPCOM_EAGAIN)
1825 {
1826 if (flags & O_NONBLOCK)
1827 {
1828 if (!results)
1829 {
Dave Wallace2a865272018-02-07 21:00:42 -05001830 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001831 clib_warning
1832 ("LDP<%d>: fd %d (0x%x): sid %u (0x%x): "
1833 "EAGAIN", getpid (), out_fd, out_fd, sid, sid);
1834 eagain = 1;
1835 }
1836 goto update_offset;
1837 }
1838 else
1839 continue;
1840 }
1841 else
1842 {
1843 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s():"
1844 "sid %u, io_buffer %p, nbytes %u "
1845 "returned %d (%s)",
1846 getpid (), out_fd, out_fd, func_str,
Dave Wallace2a865272018-02-07 21:00:42 -05001847 sid, ldp->io_buffer, nbytes,
Dave Wallace048b1d62018-01-03 22:24:41 -05001848 size, vppcom_retval_str (size));
1849 }
1850 if (results == 0)
1851 {
Dave Wallace2a865272018-02-07 21:00:42 -05001852 vec_reset_length (ldp->io_buffer);
Dave Wallace048b1d62018-01-03 22:24:41 -05001853 errno = -size;
1854 size = -1;
1855 goto done;
1856 }
1857 goto update_offset;
1858 }
1859
1860 results += nbytes;
1861 ASSERT (n_bytes_left >= nbytes);
1862 n_bytes_left = n_bytes_left - nbytes;
1863 }
1864 while (n_bytes_left > 0);
1865
1866 update_offset:
Dave Wallace2a865272018-02-07 21:00:42 -05001867 vec_reset_length (ldp->io_buffer);
Dave Wallace048b1d62018-01-03 22:24:41 -05001868 if (offset)
1869 {
1870 off_t off = lseek (in_fd, *offset, SEEK_SET);
1871 if (PREDICT_FALSE (off == -1))
1872 {
1873 func_str = "lseek";
1874 errno_val = errno;
1875 clib_warning ("LDP<%d>: ERROR: %s(): SEEK_SET failed: "
1876 "in_fd %d, offset %p, *offset %ld, "
1877 "rv %ld, errno %d", getpid (), in_fd,
1878 offset, *offset, off, errno_val);
1879 errno = errno_val;
1880 size = -1;
1881 goto done;
1882 }
1883
1884 ASSERT (off == *offset);
1885 *offset += results + 1;
1886 }
1887 if (eagain)
1888 {
1889 errno = EAGAIN;
1890 size = -1;
1891 }
1892 else
1893 size = results;
1894 }
1895 else
1896 {
1897 func_str = "libc_send";
1898
Dave Wallace2a865272018-02-07 21:00:42 -05001899 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001900 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1901 "in_fd %d, offset %p, len %u",
1902 getpid (), out_fd, out_fd, func_str,
1903 in_fd, offset, len);
1904
1905 size = libc_sendfile (out_fd, in_fd, offset, len);
1906 }
1907
1908done:
Dave Wallace2a865272018-02-07 21:00:42 -05001909 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001910 {
1911 if (size < 0)
1912 {
1913 int errno_val = errno;
1914 perror (func_str);
1915 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
1916 "rv %d, errno = %d", getpid (), out_fd, out_fd,
1917 func_str, size, errno_val);
1918 errno = errno_val;
1919 }
1920 else
1921 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
1922 getpid (), out_fd, out_fd, size, size);
1923 }
1924 return size;
1925}
1926
1927ssize_t
1928sendfile64 (int out_fd, int in_fd, off_t * offset, size_t len)
1929{
1930 return sendfile (out_fd, in_fd, offset, len);
1931}
1932
1933ssize_t
1934recv (int fd, void *buf, size_t n, int flags)
1935{
1936 ssize_t size;
1937 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05001938 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05001939
Dave Wallace2a865272018-02-07 21:00:42 -05001940 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001941 return -1;
1942
1943 if (sid != INVALID_SESSION_ID)
1944 {
1945 func_str = "vppcom_session_recvfrom";
1946
Dave Wallace2a865272018-02-07 21:00:42 -05001947 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001948 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1949 "sid %u (0x%x), buf %p, n %u, flags 0x%x", getpid (),
1950 fd, fd, func_str, sid, sid, buf, n, flags);
1951
1952 size = vppcom_session_recvfrom (sid, buf, n, flags, NULL);
1953 if (size < 0)
1954 {
1955 errno = -size;
1956 size = -1;
1957 }
1958 }
1959 else
1960 {
1961 func_str = "libc_recv";
1962
Dave Wallace2a865272018-02-07 21:00:42 -05001963 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001964 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
1965 "buf %p, n %u, flags 0x%x", getpid (),
1966 fd, fd, func_str, buf, n, flags);
1967
1968 size = libc_recv (fd, buf, n, flags);
1969 }
1970
Dave Wallace2a865272018-02-07 21:00:42 -05001971 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05001972 {
1973 if (size < 0)
1974 {
1975 int errno_val = errno;
1976 perror (func_str);
1977 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
1978 "rv %d, errno = %d", getpid (), fd, fd,
1979 func_str, size, errno_val);
1980 errno = errno_val;
1981 }
1982 else
1983 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
1984 getpid (), fd, fd, size, size);
1985 }
1986 return size;
1987}
1988
1989ssize_t
1990sendto (int fd, const void *buf, size_t n, int flags,
1991 __CONST_SOCKADDR_ARG addr, socklen_t addr_len)
1992{
1993 ssize_t size;
1994 const char *func_str = __func__;
Dave Wallace2a865272018-02-07 21:00:42 -05001995 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05001996
Dave Wallace2a865272018-02-07 21:00:42 -05001997 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05001998 return -1;
1999
2000 if (sid != INVALID_SESSION_ID)
2001 {
2002 vppcom_endpt_t *ep = 0;
2003 vppcom_endpt_t _ep;
2004
2005 if (addr)
2006 {
2007 ep = &_ep;
Dave Wallace048b1d62018-01-03 22:24:41 -05002008 switch (addr->sa_family)
2009 {
2010 case AF_INET:
2011 ep->is_ip4 = VPPCOM_IS_IP4;
2012 ep->ip =
2013 (uint8_t *) & ((const struct sockaddr_in *) addr)->sin_addr;
2014 ep->port =
2015 (uint16_t) ((const struct sockaddr_in *) addr)->sin_port;
2016 break;
2017
2018 case AF_INET6:
2019 ep->is_ip4 = VPPCOM_IS_IP6;
2020 ep->ip =
2021 (uint8_t *) & ((const struct sockaddr_in6 *) addr)->sin6_addr;
2022 ep->port =
2023 (uint16_t) ((const struct sockaddr_in6 *) addr)->sin6_port;
2024 break;
2025
2026 default:
2027 errno = EAFNOSUPPORT;
2028 size = -1;
2029 goto done;
2030 }
2031 }
2032
2033 func_str = "vppcom_session_sendto";
2034
Dave Wallace2a865272018-02-07 21:00:42 -05002035 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002036 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2037 "sid %u (0x%x), buf %p, n %u, flags 0x%x, ep %p",
2038 getpid (), fd, fd, func_str, sid, sid, buf, n,
2039 flags, ep);
2040
2041 size = vppcom_session_sendto (sid, (void *) buf, n, flags, ep);
2042 if (size < 0)
2043 {
2044 errno = -size;
2045 size = -1;
2046 }
2047 }
2048 else
2049 {
2050 func_str = "libc_sendto";
2051
Dave Wallace2a865272018-02-07 21:00:42 -05002052 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002053 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2054 "buf %p, n %u, flags 0x%x, addr %p, addr_len %d",
2055 getpid (), fd, fd, func_str, buf, n, flags,
2056 addr, addr_len);
2057
2058 size = libc_sendto (fd, buf, n, flags, addr, addr_len);
2059 }
2060
2061done:
Dave Wallace2a865272018-02-07 21:00:42 -05002062 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002063 {
2064 if (size < 0)
2065 {
2066 int errno_val = errno;
2067 perror (func_str);
2068 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2069 "rv %d, errno = %d", getpid (), fd, fd,
2070 func_str, size, errno_val);
2071 errno = errno_val;
2072 }
2073 else
2074 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2075 getpid (), fd, fd, size, size);
2076 }
2077 return size;
2078}
2079
2080ssize_t
2081recvfrom (int fd, void *__restrict buf, size_t n, int flags,
2082 __SOCKADDR_ARG addr, socklen_t * __restrict addr_len)
2083{
2084 ssize_t size;
2085 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05002086 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05002087
Dave Wallace2a865272018-02-07 21:00:42 -05002088 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002089 return -1;
2090
2091 if (sid != INVALID_SESSION_ID)
2092 {
2093 vppcom_endpt_t ep;
2094 u8 src_addr[sizeof (struct sockaddr_in6)];
2095
2096 func_str = "vppcom_session_recvfrom";
2097
Dave Wallace2a865272018-02-07 21:00:42 -05002098 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002099 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2100 "sid %u (0x%x), buf %p, n %u, flags 0x%x, ep %p",
2101 getpid (), fd, fd, func_str, sid, sid, buf, n,
2102 flags, &ep);
2103 if (addr)
2104 {
2105 ep.ip = src_addr;
2106 size = vppcom_session_recvfrom (sid, buf, n, flags, &ep);
2107
2108 if (size > 0)
Dave Wallace2a865272018-02-07 21:00:42 -05002109 size = ldp_copy_ep_to_sockaddr (addr, addr_len, &ep);
Dave Wallace048b1d62018-01-03 22:24:41 -05002110 }
2111 else
2112 size = vppcom_session_recvfrom (sid, buf, n, flags, NULL);
2113
2114 if (size < 0)
2115 {
2116 errno = -size;
2117 size = -1;
2118 }
2119 }
2120 else
2121 {
2122 func_str = "libc_recvfrom";
2123
Dave Wallace2a865272018-02-07 21:00:42 -05002124 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002125 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2126 "buf %p, n %u, flags 0x%x, addr %p, addr_len %d",
2127 getpid (), fd, fd, func_str, buf, n, flags,
2128 addr, addr_len);
2129
2130 size = libc_recvfrom (fd, buf, n, flags, addr, addr_len);
2131 }
2132
Dave Wallace2a865272018-02-07 21:00:42 -05002133 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002134 {
2135 if (size < 0)
2136 {
2137 int errno_val = errno;
2138 perror (func_str);
2139 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2140 "rv %d, errno = %d", getpid (), fd, fd,
2141 func_str, size, errno_val);
2142 errno = errno_val;
2143 }
2144 else
2145 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2146 getpid (), fd, fd, size, size);
2147 }
2148 return size;
2149}
2150
2151ssize_t
2152sendmsg (int fd, const struct msghdr * message, int flags)
2153{
2154 ssize_t size;
2155 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05002156 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05002157
Dave Wallace2a865272018-02-07 21:00:42 -05002158 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002159 return -1;
2160
2161 if (sid != INVALID_SESSION_ID)
2162 {
Dave Wallace8aaba562018-01-18 17:21:19 -05002163 func_str = __func__;
2164
Dave Wallace048b1d62018-01-03 22:24:41 -05002165 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
2166 errno = ENOSYS;
2167 size = -1;
2168 }
2169 else
2170 {
2171 func_str = "libc_sendmsg";
2172
Dave Wallace2a865272018-02-07 21:00:42 -05002173 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002174 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2175 "message %p, flags 0x%x",
2176 getpid (), fd, fd, func_str, message, flags);
2177
2178 size = libc_sendmsg (fd, message, flags);
2179 }
2180
Dave Wallace2a865272018-02-07 21:00:42 -05002181 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002182 {
2183 if (size < 0)
2184 {
2185 int errno_val = errno;
2186 perror (func_str);
2187 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2188 "rv %d, errno = %d", getpid (), fd, fd,
2189 func_str, size, errno_val);
2190 errno = errno_val;
2191 }
2192 else
2193 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2194 getpid (), fd, fd, size, size);
2195 }
2196 return size;
2197}
2198
2199#ifdef USE_GNU
2200int
2201sendmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags)
2202{
2203 ssize_t size;
2204 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05002205 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05002206
Dave Wallace2a865272018-02-07 21:00:42 -05002207 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002208 return -1;
2209
2210 if (sid != INVALID_SESSION_ID)
2211 {
2212 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
2213 errno = ENOSYS;
2214 size = -1;
2215 }
2216 else
2217 {
2218 func_str = "libc_sendmmsg";
2219
Dave Wallace2a865272018-02-07 21:00:42 -05002220 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002221 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2222 "vmessages %p, vlen %u, flags 0x%x",
2223 getpid (), fd, fd, func_str, vmessages, vlen, flags);
2224
2225 size = libc_sendmmsg (fd, vmessages, vlen, flags);
2226 }
2227
Dave Wallace2a865272018-02-07 21:00:42 -05002228 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002229 {
2230 if (size < 0)
2231 {
2232 int errno_val = errno;
2233 perror (func_str);
2234 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2235 "rv %d, errno = %d", getpid (), fd, fd,
2236 func_str, size, errno_val);
2237 errno = errno_val;
2238 }
2239 else
2240 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2241 getpid (), fd, fd, size, size);
2242 }
2243 return size;
2244}
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002245#endif
2246
Dave Wallace048b1d62018-01-03 22:24:41 -05002247ssize_t
2248recvmsg (int fd, struct msghdr * message, int flags)
2249{
2250 ssize_t size;
2251 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05002252 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05002253
Dave Wallace2a865272018-02-07 21:00:42 -05002254 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002255 return -1;
2256
2257 if (sid != INVALID_SESSION_ID)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002258 {
Dave Wallace8aaba562018-01-18 17:21:19 -05002259 func_str = __func__;
2260
Dave Wallace048b1d62018-01-03 22:24:41 -05002261 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
2262 errno = ENOSYS;
2263 size = -1;
2264 }
2265 else
2266 {
2267 func_str = "libc_recvmsg";
2268
Dave Wallace2a865272018-02-07 21:00:42 -05002269 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002270 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2271 "message %p, flags 0x%x",
2272 getpid (), fd, fd, func_str, message, flags);
2273
2274 size = libc_recvmsg (fd, message, flags);
2275 }
2276
Dave Wallace2a865272018-02-07 21:00:42 -05002277 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002278 {
2279 if (size < 0)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002280 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002281 int errno_val = errno;
2282 perror (func_str);
2283 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2284 "rv %d, errno = %d", getpid (), fd, fd,
2285 func_str, size, errno_val);
2286 errno = errno_val;
2287 }
2288 else
2289 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2290 getpid (), fd, fd, size, size);
2291 }
2292 return size;
2293}
2294
2295#ifdef USE_GNU
2296int
2297recvmmsg (int fd, struct mmsghdr *vmessages,
2298 unsigned int vlen, int flags, struct timespec *tmo)
2299{
2300 ssize_t size;
2301 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05002302 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05002303
Dave Wallace2a865272018-02-07 21:00:42 -05002304 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002305 return -1;
2306
2307 if (sid != INVALID_SESSION_ID)
2308 {
2309 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
2310 errno = ENOSYS;
2311 size = -1;
2312 }
2313 else
2314 {
2315 func_str = "libc_recvmmsg";
2316
Dave Wallace2a865272018-02-07 21:00:42 -05002317 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002318 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2319 "vmessages %p, vlen %u, flags 0x%x, tmo %p",
2320 getpid (), fd, fd, func_str, vmessages, vlen,
2321 flags, tmo);
2322
2323 size = libc_recvmmsg (fd, vmessages, vlen, flags, tmo);
2324 }
2325
Dave Wallace2a865272018-02-07 21:00:42 -05002326 if (LDP_DEBUG > 2)
Dave Wallace048b1d62018-01-03 22:24:41 -05002327 {
2328 if (size < 0)
2329 {
2330 int errno_val = errno;
2331 perror (func_str);
2332 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2333 "rv %d, errno = %d", getpid (), fd, fd,
2334 func_str, size, errno_val);
2335 errno = errno_val;
2336 }
2337 else
2338 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2339 getpid (), fd, fd, size, size);
2340 }
2341 return size;
2342}
2343#endif
2344
2345int
2346getsockopt (int fd, int level, int optname,
2347 void *__restrict optval, socklen_t * __restrict optlen)
2348{
2349 int rv;
2350 const char *func_str = __func__;
Dave Wallace2a865272018-02-07 21:00:42 -05002351 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace8aaba562018-01-18 17:21:19 -05002352 u32 buflen = optlen ? (u32) * optlen : 0;
Dave Wallace048b1d62018-01-03 22:24:41 -05002353
Dave Wallace2a865272018-02-07 21:00:42 -05002354 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002355 return -1;
2356
2357 if (sid != INVALID_SESSION_ID)
2358 {
2359 rv = -EOPNOTSUPP;
2360
2361 switch (level)
2362 {
2363 case SOL_TCP:
2364 switch (optname)
2365 {
2366 case TCP_NODELAY:
2367 func_str = "vppcom_session_attr[SOL_TCP,GET_TCP_NODELAY]";
Dave Wallace2a865272018-02-07 21:00:42 -05002368 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002369 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2370 "sid %u (0x%x)",
2371 getpid (), fd, fd, func_str, sid, sid);
2372 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_TCP_NODELAY,
2373 optval, optlen);
2374 break;
2375 case TCP_MAXSEG:
2376 func_str = "vppcom_session_attr[SOL_TCP,GET_TCP_USER_MSS]";
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_USER_MSS,
2382 optval, optlen);
2383 break;
2384 case TCP_KEEPIDLE:
2385 func_str = "vppcom_session_attr[SOL_TCP,GET_TCP_KEEPIDLE]";
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_KEEPIDLE,
2391 optval, optlen);
2392 break;
2393 case TCP_KEEPINTVL:
2394 func_str = "vppcom_session_attr[SOL_TCP,GET_TCP_KEEPINTVL]";
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), SOL_TCP",
2398 getpid (), fd, fd, func_str, sid, sid);
2399 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_TCP_KEEPINTVL,
2400 optval, optlen);
2401 break;
2402 case TCP_INFO:
2403 if (optval && optlen && (*optlen == sizeof (struct tcp_info)))
2404 {
Dave Wallace2a865272018-02-07 21:00:42 -05002405 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002406 clib_warning ("LDP<%d>: fd %d (0x%x): sid %u (0x%x), "
2407 "SOL_TCP, TCP_INFO, optval %p, "
2408 "optlen %d: #LDP-NOP#",
2409 getpid (), fd, fd, sid, sid,
2410 optval, *optlen);
2411 memset (optval, 0, *optlen);
2412 rv = VPPCOM_OK;
2413 }
2414 else
2415 rv = -EFAULT;
2416 break;
2417 default:
Dave Wallace2a865272018-02-07 21:00:42 -05002418 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002419 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
2420 "sid %u (0x%x), SOL_TCP, "
2421 "optname %d unsupported!",
2422 getpid (), fd, fd, func_str, sid, sid, optname);
2423 break;
2424 }
2425 break;
2426 case SOL_IPV6:
2427 switch (optname)
2428 {
2429 case IPV6_V6ONLY:
2430 func_str = "vppcom_session_attr[SOL_IPV6,GET_V6ONLY]";
Dave Wallace2a865272018-02-07 21:00:42 -05002431 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002432 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2433 "sid %u (0x%x)",
2434 getpid (), fd, fd, func_str, sid, sid);
2435 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_V6ONLY,
2436 optval, optlen);
2437 break;
2438 default:
Dave Wallace2a865272018-02-07 21:00:42 -05002439 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002440 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
2441 "sid %u (0x%x), SOL_IPV6, "
2442 "optname %d unsupported!",
2443 getpid (), fd, fd, func_str, sid, sid, optname);
2444 break;
2445 }
2446 break;
2447 case SOL_SOCKET:
2448 switch (optname)
2449 {
2450 case SO_ACCEPTCONN:
2451 func_str = "vppcom_session_attr[SOL_SOCKET,GET_ACCEPTCONN]";
Dave Wallace2a865272018-02-07 21:00:42 -05002452 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002453 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2454 "sid %u (0x%x)",
2455 getpid (), fd, fd, func_str, sid, sid);
2456 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_LISTEN,
2457 optval, optlen);
2458 break;
2459 case SO_KEEPALIVE:
2460 func_str = "vppcom_session_attr[SOL_SOCKET,GET_KEEPALIVE]";
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_KEEPALIVE,
2466 optval, optlen);
2467 break;
2468 case SO_PROTOCOL:
2469 func_str = "vppcom_session_attr[SOL_SOCKET,GET_PROTOCOL]";
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_PROTOCOL,
2475 optval, optlen);
2476 *(int *) optval = *(int *) optval ? SOCK_DGRAM : SOCK_STREAM;
2477 break;
2478 case SO_SNDBUF:
2479 func_str = "vppcom_session_attr[SOL_SOCKET,GET_TX_FIFO_LEN]";
Dave Wallace2a865272018-02-07 21:00:42 -05002480 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002481 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2482 "sid %u (0x%x), optlen %d",
2483 getpid (), fd, fd, func_str, sid, sid, buflen);
2484 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_TX_FIFO_LEN,
2485 optval, optlen);
2486 break;
2487 case SO_RCVBUF:
2488 func_str = "vppcom_session_attr[SOL_SOCKET,GET_RX_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",
Dave Wallaceb4cd4ff2018-01-19 12:17:08 -05002492 getpid (), fd, fd, func_str, sid, sid, buflen);
Dave Wallace048b1d62018-01-03 22:24:41 -05002493 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_RX_FIFO_LEN,
2494 optval, optlen);
2495 break;
2496 case SO_REUSEADDR:
2497 func_str = "vppcom_session_attr[SOL_SOCKET,GET_REUSEADDR]";
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)",
2501 getpid (), fd, fd, func_str, sid, sid);
2502 rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_REUSEADDR,
2503 optval, optlen);
2504 break;
2505 case SO_BROADCAST:
2506 func_str = "vppcom_session_attr[SOL_SOCKET,GET_BROADCAST]";
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_BROADCAST,
2512 optval, optlen);
2513 break;
2514 case SO_ERROR:
2515 func_str = "vppcom_session_attr[SOL_SOCKET,GET_ERROR]";
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_ERROR,
2521 optval, optlen);
2522 break;
2523 default:
Dave Wallace2a865272018-02-07 21:00:42 -05002524 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002525 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
2526 "sid %u (0x%x), SOL_SOCKET, "
2527 "optname %d unsupported!",
2528 getpid (), fd, fd, func_str, sid, sid, optname);
2529 break;
2530 }
2531 break;
2532 default:
2533 break;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002534 }
2535
Dave Wallace048b1d62018-01-03 22:24:41 -05002536 if (rv != VPPCOM_OK)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002537 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002538 errno = -rv;
2539 rv = -1;
2540 }
2541 }
2542 else
2543 {
2544 func_str = "libc_getsockopt";
2545
Dave Wallace2a865272018-02-07 21:00:42 -05002546 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002547 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): level %d, "
2548 "optname %d, optval %p, optlen %d",
2549 getpid (), fd, fd, func_str, level, optname,
2550 optval, optlen);
2551
2552 rv = libc_getsockopt (fd, level, optname, optval, optlen);
2553 }
2554
Dave Wallace2a865272018-02-07 21:00:42 -05002555 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002556 {
2557 if (rv < 0)
2558 {
2559 int errno_val = errno;
2560 perror (func_str);
2561 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2562 "rv %d, errno = %d", getpid (), fd, fd,
2563 func_str, rv, errno_val);
2564 errno = errno_val;
2565 }
2566 else
2567 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2568 getpid (), fd, fd, rv, rv);
2569 }
2570 return rv;
2571}
2572
2573int
2574setsockopt (int fd, int level, int optname,
2575 const void *optval, socklen_t optlen)
2576{
2577 int rv;
2578 const char *func_str = __func__;
Dave Wallace2a865272018-02-07 21:00:42 -05002579 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05002580
Dave Wallace2a865272018-02-07 21:00:42 -05002581 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002582 return -1;
2583
2584 if (sid != INVALID_SESSION_ID)
2585 {
2586 rv = -EOPNOTSUPP;
2587
2588 switch (level)
2589 {
2590 case SOL_TCP:
2591 switch (optname)
2592 {
2593 case TCP_NODELAY:
2594 func_str = "vppcom_session_attr[SOL_TCP,SET_TCP_NODELAY]";
Dave Wallace2a865272018-02-07 21:00:42 -05002595 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002596 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2597 "sid %u (0x%x)",
2598 getpid (), fd, fd, func_str, sid, sid);
2599 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_TCP_NODELAY,
2600 (void *) optval, &optlen);
2601 break;
2602 case TCP_MAXSEG:
2603 func_str = "vppcom_session_attr[SOL_TCP,SET_TCP_USER_MSS]";
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_USER_MSS,
2609 (void *) optval, &optlen);
2610 break;
2611 case TCP_KEEPIDLE:
2612 func_str = "vppcom_session_attr[SOL_TCP,SET_TCP_KEEPIDLE]";
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_KEEPIDLE,
2618 (void *) optval, &optlen);
2619 break;
2620 case TCP_KEEPINTVL:
2621 func_str = "vppcom_session_attr[SOL_TCP,SET_TCP_KEEPINTVL]";
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), SOL_TCP",
2625 getpid (), fd, fd, func_str, sid, sid);
2626 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_TCP_KEEPINTVL,
2627 (void *) optval, &optlen);
2628 break;
2629 default:
Dave Wallace2a865272018-02-07 21:00:42 -05002630 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002631 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
2632 "sid %u (0x%x), SOL_TCP, "
2633 "optname %d unsupported!",
2634 getpid (), fd, fd, func_str, sid, sid, optname);
2635 break;
2636 }
2637 break;
2638 case SOL_IPV6:
2639 switch (optname)
2640 {
2641 case IPV6_V6ONLY:
2642 func_str = "vppcom_session_attr[SOL_IPV6,SET_V6ONLY]";
Dave Wallace2a865272018-02-07 21:00:42 -05002643 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002644 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2645 "sid %u (0x%x)",
2646 getpid (), fd, fd, func_str, sid, sid);
2647 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_V6ONLY,
2648 (void *) optval, &optlen);
2649 break;
2650 default:
Dave Wallace2a865272018-02-07 21:00:42 -05002651 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002652 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
2653 "sid %u (0x%x), SOL_IPV6, "
2654 "optname %d unsupported!",
2655 getpid (), fd, fd, func_str, sid, sid, optname);
2656 break;
2657 }
2658 break;
2659 case SOL_SOCKET:
2660 switch (optname)
2661 {
2662 case SO_KEEPALIVE:
2663 func_str = "vppcom_session_attr[SOL_SOCKET,SET_KEEPALIVE]";
Dave Wallace2a865272018-02-07 21:00:42 -05002664 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002665 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
2666 "sid %u (0x%x)",
2667 getpid (), fd, fd, func_str, sid, sid);
2668 rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_KEEPALIVE,
2669 (void *) optval, &optlen);
2670 break;
2671 case SO_REUSEADDR:
2672 func_str = "vppcom_session_attr[SOL_SOCKET,SET_REUSEADDR]";
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_REUSEADDR,
2678 (void *) optval, &optlen);
2679 break;
2680 case SO_BROADCAST:
2681 func_str = "vppcom_session_attr[SOL_SOCKET,SET_BROADCAST]";
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_BROADCAST,
2687 (void *) optval, &optlen);
2688 break;
2689 default:
Dave Wallace2a865272018-02-07 21:00:42 -05002690 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002691 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s(): "
2692 "sid %u (0x%x), SOL_SOCKET, "
2693 "optname %d unsupported!",
2694 getpid (), fd, fd, func_str, sid, sid, optname);
2695 break;
2696 }
2697 break;
2698 default:
2699 break;
2700 }
2701
2702 if (rv != VPPCOM_OK)
2703 {
2704 errno = -rv;
2705 rv = -1;
2706 }
2707 }
2708 else
2709 {
2710 func_str = "libc_setsockopt";
2711
Dave Wallace2a865272018-02-07 21:00:42 -05002712 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002713 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): level %d, "
2714 "optname %d, optval %p, optlen %d",
2715 getpid (), fd, fd, func_str, level, optname,
2716 optval, optlen);
2717
2718 rv = libc_setsockopt (fd, level, optname, optval, optlen);
2719 }
2720
Dave Wallace2a865272018-02-07 21:00:42 -05002721 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002722 {
2723 if (rv < 0)
2724 {
2725 int errno_val = errno;
2726 perror (func_str);
2727 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2728 "rv %d, errno = %d", getpid (), fd, fd,
2729 func_str, rv, errno_val);
2730 errno = errno_val;
2731 }
2732 else
2733 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2734 getpid (), fd, fd, rv, rv);
2735 }
2736 return rv;
2737}
2738
2739int
2740listen (int fd, int n)
2741{
2742 int rv;
2743 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05002744 u32 sid = ldp_sid_from_fd (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05002745
Dave Wallace2a865272018-02-07 21:00:42 -05002746 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002747 return -1;
2748
2749 if (sid != INVALID_SESSION_ID)
2750 {
2751 func_str = "vppcom_session_listen";
2752
Florin Coras99368312018-08-02 10:45:44 -07002753 LDBG (0, "LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), n %d",
2754 getpid (), fd, fd, func_str, sid, sid, n);
Dave Wallace048b1d62018-01-03 22:24:41 -05002755
2756 rv = vppcom_session_listen (sid, n);
2757 if (rv != VPPCOM_OK)
2758 {
2759 errno = -rv;
2760 rv = -1;
2761 }
2762 }
2763 else
2764 {
2765 func_str = "libc_listen";
2766
Florin Coras99368312018-08-02 10:45:44 -07002767 LDBG (0, "LDP<%d>: fd %d (0x%x): calling %s(): n %d", getpid (), fd,
2768 fd, func_str, n);
Dave Wallace048b1d62018-01-03 22:24:41 -05002769
2770 rv = libc_listen (fd, n);
2771 }
2772
Dave Wallace2a865272018-02-07 21:00:42 -05002773 if (LDP_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002774 {
2775 if (rv < 0)
2776 {
2777 int errno_val = errno;
2778 perror (func_str);
2779 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2780 "rv %d, errno = %d", getpid (), fd, fd,
2781 func_str, rv, errno_val);
2782 errno = errno_val;
2783 }
2784 else
2785 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2786 getpid (), fd, fd, rv, rv);
2787 }
2788 return rv;
2789}
2790
2791static inline int
Dave Wallace2a865272018-02-07 21:00:42 -05002792ldp_accept4 (int listen_fd, __SOCKADDR_ARG addr,
2793 socklen_t * __restrict addr_len, int flags)
Dave Wallace048b1d62018-01-03 22:24:41 -05002794{
2795 int rv;
2796 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05002797 u32 listen_sid = ldp_sid_from_fd (listen_fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05002798 int accept_sid;
2799
Dave Wallace2a865272018-02-07 21:00:42 -05002800 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002801 return -1;
2802
2803 if (listen_sid != INVALID_SESSION_ID)
2804 {
2805 vppcom_endpt_t ep;
2806 u8 src_addr[sizeof (struct sockaddr_in6)];
Dave Wallace8aaba562018-01-18 17:21:19 -05002807 memset (&ep, 0, sizeof (ep));
Dave Wallace048b1d62018-01-03 22:24:41 -05002808 ep.ip = src_addr;
2809
2810 func_str = "vppcom_session_accept";
2811
Dave Wallace2a865272018-02-07 21:00:42 -05002812 if (LDP_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002813 clib_warning ("LDP<%d>: listen fd %d (0x%x): calling %s(): "
2814 "listen sid %u (0x%x), ep %p, flags 0x%x",
2815 getpid (), listen_fd, listen_fd, func_str,
2816 listen_sid, listen_sid, ep, flags);
2817
2818 accept_sid = vppcom_session_accept (listen_sid, &ep, flags);
2819 if (accept_sid < 0)
2820 {
2821 errno = -accept_sid;
2822 rv = -1;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002823 }
2824 else
2825 {
Dave Wallace2a865272018-02-07 21:00:42 -05002826 rv = ldp_copy_ep_to_sockaddr (addr, addr_len, &ep);
Dave Wallace048b1d62018-01-03 22:24:41 -05002827 if (rv != VPPCOM_OK)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002828 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002829 (void) vppcom_session_close ((u32) accept_sid);
2830 errno = -rv;
2831 rv = -1;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002832 }
Dave Wallace048b1d62018-01-03 22:24:41 -05002833 else
2834 {
Dave Wallace2a865272018-02-07 21:00:42 -05002835 func_str = "ldp_fd_from_sid";
2836 if (LDP_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002837 clib_warning ("LDP<%d>: listen fd %d (0x%x): calling %s(): "
2838 "accept sid %u (0x%x), ep %p, flags 0x%x",
2839 getpid (), listen_fd, listen_fd,
2840 func_str, accept_sid, accept_sid, ep, flags);
Dave Wallace2a865272018-02-07 21:00:42 -05002841 rv = ldp_fd_from_sid ((u32) accept_sid);
Dave Wallace048b1d62018-01-03 22:24:41 -05002842 if (rv < 0)
2843 {
2844 (void) vppcom_session_close ((u32) accept_sid);
2845 errno = -rv;
2846 rv = -1;
2847 }
2848 }
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002849 }
2850 }
Dave Wallace048b1d62018-01-03 22:24:41 -05002851 else
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002852 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002853 func_str = "libc_accept4";
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002854
Dave Wallace2a865272018-02-07 21:00:42 -05002855 if (LDP_DEBUG > 0)
Dave Wallace048b1d62018-01-03 22:24:41 -05002856 clib_warning ("LDP<%d>: listen fd %d (0x%x): calling %s(): "
2857 "addr %p, addr_len %p, flags 0x%x",
2858 getpid (), listen_fd, listen_fd, func_str,
2859 addr, addr_len, flags);
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002860
Dave Wallace048b1d62018-01-03 22:24:41 -05002861 rv = libc_accept4 (listen_fd, addr, addr_len, flags);
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002862 }
2863
Dave Wallace2a865272018-02-07 21:00:42 -05002864 if (LDP_DEBUG > 0)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002865 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002866 if (rv < 0)
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002867 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002868 int errno_val = errno;
2869 perror (func_str);
2870 clib_warning ("LDP<%d>: ERROR: listen fd %d (0x%x): %s() failed! "
2871 "rv %d, errno = %d", getpid (), listen_fd,
2872 listen_fd, func_str, rv, errno_val);
2873 errno = errno_val;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002874 }
Dave Wallace048b1d62018-01-03 22:24:41 -05002875 else
2876 clib_warning ("LDP<%d>: listen fd %d (0x%x): returning %d (0x%x)",
2877 getpid (), listen_fd, listen_fd, rv, rv);
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002878 }
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002879 return rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002880}
2881
Dave Wallace048b1d62018-01-03 22:24:41 -05002882int
2883accept4 (int fd, __SOCKADDR_ARG addr, socklen_t * __restrict addr_len,
2884 int flags)
2885{
Dave Wallace2a865272018-02-07 21:00:42 -05002886 return ldp_accept4 (fd, addr, addr_len, flags);
Dave Wallace048b1d62018-01-03 22:24:41 -05002887}
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002888
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002889int
Dave Wallace048b1d62018-01-03 22:24:41 -05002890accept (int fd, __SOCKADDR_ARG addr, socklen_t * __restrict addr_len)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002891{
Dave Wallace2a865272018-02-07 21:00:42 -05002892 return ldp_accept4 (fd, addr, addr_len, 0);
Dave Wallace048b1d62018-01-03 22:24:41 -05002893}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002894
Dave Wallace048b1d62018-01-03 22:24:41 -05002895int
2896shutdown (int fd, int how)
2897{
2898 int rv;
2899 const char *func_str;
Dave Wallace2a865272018-02-07 21:00:42 -05002900 u32 sid = ldp_sid_from_fd (fd);
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002901
Dave Wallace2a865272018-02-07 21:00:42 -05002902 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002903 return -1;
2904
2905 if (sid != INVALID_SESSION_ID)
2906 {
Florin Coras6917b942018-11-13 22:44:54 -08002907 func_str = "vppcom_session_close[TODO]";
2908 rv = close (fd);
Dave Wallace048b1d62018-01-03 22:24:41 -05002909 }
2910 else
2911 {
2912 func_str = "libc_shutdown";
2913
Dave Wallace2a865272018-02-07 21:00:42 -05002914 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002915 clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): how %d",
2916 getpid (), fd, fd, func_str, how);
2917
2918 rv = libc_shutdown (fd, how);
2919 }
2920
Dave Wallace2a865272018-02-07 21:00:42 -05002921 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05002922 {
2923 if (rv < 0)
2924 {
2925 int errno_val = errno;
2926 perror (func_str);
2927 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
2928 "rv %d, errno = %d", getpid (), fd, fd,
2929 func_str, rv, errno_val);
2930 errno = errno_val;
2931 }
2932 else
2933 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
2934 getpid (), fd, fd, rv, rv);
2935 }
2936 return rv;
2937}
2938
2939int
2940epoll_create1 (int flags)
2941{
2942 const char *func_str;
2943 int rv;
2944
Dave Wallace2a865272018-02-07 21:00:42 -05002945 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05002946 return -1;
2947
Florin Coras99368312018-08-02 10:45:44 -07002948 if (ldp->vcl_needs_real_epoll)
2949 {
2950 rv = libc_epoll_create1 (flags);
2951 ldp->vcl_needs_real_epoll = 0;
2952 ldp->vcl_mq_epfd = rv;
2953 LDBG (0, "LDP<%d>: created vcl epfd %u", getpid (), rv);
2954 return rv;
2955 }
Dave Wallace048b1d62018-01-03 22:24:41 -05002956 func_str = "vppcom_epoll_create";
2957
Florin Coras99368312018-08-02 10:45:44 -07002958 LDBG (1, "LDP<%d>: calling %s()", getpid (), func_str);
Dave Wallace048b1d62018-01-03 22:24:41 -05002959
2960 rv = vppcom_epoll_create ();
2961
2962 if (PREDICT_FALSE (rv < 0))
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002963 {
2964 errno = -rv;
Dave Wallace048b1d62018-01-03 22:24:41 -05002965 rv = -1;
shrinivasan ganapathy1d359632017-10-15 15:46:09 -07002966 }
Dave Wallace048b1d62018-01-03 22:24:41 -05002967 else
Dave Wallace2a865272018-02-07 21:00:42 -05002968 rv = ldp_fd_from_sid ((u32) rv);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002969
Dave Wallace2a865272018-02-07 21:00:42 -05002970 if (LDP_DEBUG > 1)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002971 {
Dave Wallace048b1d62018-01-03 22:24:41 -05002972 if (rv < 0)
2973 {
2974 int errno_val = errno;
2975 perror (func_str);
2976 clib_warning ("LDP<%d>: ERROR: %s() failed! "
2977 "rv %d, errno = %d",
2978 getpid (), func_str, rv, errno_val);
2979 errno = errno_val;
2980 }
2981 else
2982 clib_warning ("LDP<%d>: returning epfd %d (0x%x)", getpid (), rv, rv);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002983 }
Dave Wallace048b1d62018-01-03 22:24:41 -05002984 return rv;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002985}
2986
2987int
Dave Wallace048b1d62018-01-03 22:24:41 -05002988epoll_create (int size)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002989{
Dave Wallace048b1d62018-01-03 22:24:41 -05002990 return epoll_create1 (0);
2991}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07002992
Dave Wallace048b1d62018-01-03 22:24:41 -05002993int
2994epoll_ctl (int epfd, int op, int fd, struct epoll_event *event)
2995{
Florin Coras99368312018-08-02 10:45:44 -07002996 u32 vep_idx = ldp_sid_from_fd (epfd), sid;
Dave Wallace048b1d62018-01-03 22:24:41 -05002997 const char *func_str;
Florin Coras99368312018-08-02 10:45:44 -07002998 int rv;
Dave Wallace048b1d62018-01-03 22:24:41 -05002999
Dave Wallace2a865272018-02-07 21:00:42 -05003000 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05003001 return -1;
3002
Florin Coras99368312018-08-02 10:45:44 -07003003 if (PREDICT_FALSE (vep_idx == INVALID_SESSION_ID))
Dave Wallace048b1d62018-01-03 22:24:41 -05003004 {
Dave Wallace3ee1fe12018-02-23 01:09:11 -05003005 /* The LDP epoll_create1 always creates VCL epfd's.
3006 * The app should never have a kernel base epoll fd unless it
3007 * was acquired outside of the LD_PRELOAD process context.
3008 * In any case, if we get one, punt it to libc_epoll_ctl.
3009 */
Dave Wallace048b1d62018-01-03 22:24:41 -05003010 func_str = "libc_epoll_ctl";
3011
Florin Coras99368312018-08-02 10:45:44 -07003012 LDBG (1, "LDP<%d>: epfd %d (0x%x): calling %s(): op %d, fd %d (0x%x),"
3013 " event %p", getpid (), epfd, epfd, func_str, op, fd, fd, event);
Dave Wallace048b1d62018-01-03 22:24:41 -05003014
3015 rv = libc_epoll_ctl (epfd, op, fd, event);
Florin Coras99368312018-08-02 10:45:44 -07003016 goto done;
3017 }
3018
3019 sid = ldp_sid_from_fd (fd);
3020
3021 LDBG (0, "LDP<%d>: epfd %d (0x%x), vep_idx %d (0x%x), sid %d (0x%x)",
3022 getpid (), epfd, epfd, vep_idx, vep_idx, sid, sid);
3023
3024 if (sid != INVALID_SESSION_ID)
3025 {
3026 func_str = "vppcom_epoll_ctl";
3027
3028 LDBG (1, "LDP<%d>: epfd %d (0x%x): calling %s(): vep_idx %d (0x%x),"
3029 " op %d, sid %u (0x%x), event %p", getpid (), epfd, epfd,
3030 func_str, vep_idx, vep_idx, sid, sid, event);
3031
3032 rv = vppcom_epoll_ctl (vep_idx, op, sid, event);
3033 if (rv != VPPCOM_OK)
3034 {
3035 errno = -rv;
3036 rv = -1;
3037 }
3038 }
3039 else
3040 {
3041 int libc_epfd;
3042 u32 size = sizeof (epfd);
3043
3044 func_str = "vppcom_session_attr[GET_LIBC_EPFD]";
3045 libc_epfd = vppcom_session_attr (vep_idx, VPPCOM_ATTR_GET_LIBC_EPFD, 0,
3046 0);
3047 LDBG (1, "LDP<%d>: epfd %d (0x%x), vep_idx %d (0x%x): %s() "
3048 "returned libc_epfd %d (0x%x)", getpid (), epfd, epfd,
3049 vep_idx, vep_idx, func_str, libc_epfd, libc_epfd);
3050
3051 if (!libc_epfd)
3052 {
3053 func_str = "libc_epoll_create1";
3054
3055 LDBG (1, "LDP<%d>: epfd %d (0x%x), vep_idx %d (0x%x): "
3056 "calling %s(): EPOLL_CLOEXEC", getpid (), epfd, epfd,
3057 vep_idx, vep_idx, func_str);
3058
3059 libc_epfd = libc_epoll_create1 (EPOLL_CLOEXEC);
3060 if (libc_epfd < 0)
3061 {
3062 rv = libc_epfd;
3063 goto done;
3064 }
3065
3066 func_str = "vppcom_session_attr[SET_LIBC_EPFD]";
3067 LDBG (1, "LDP<%d>: epfd %d (0x%x): calling %s(): vep_idx %d (0x%x),"
3068 " VPPCOM_ATTR_SET_LIBC_EPFD, libc_epfd %d (0x%x), size %d",
3069 getpid (), epfd, epfd, func_str, vep_idx, vep_idx, libc_epfd,
3070 libc_epfd, size);
3071
3072 rv = vppcom_session_attr (vep_idx, VPPCOM_ATTR_SET_LIBC_EPFD,
3073 &libc_epfd, &size);
3074 if (rv < 0)
3075 {
3076 errno = -rv;
3077 rv = -1;
3078 goto done;
3079 }
3080 }
3081 else if (PREDICT_FALSE (libc_epfd < 0))
3082 {
3083 errno = -epfd;
3084 rv = -1;
3085 goto done;
3086 }
3087
3088 func_str = "libc_epoll_ctl";
3089
3090 LDBG (1, "LDP<%d>: epfd %d (0x%x): calling %s(): libc_epfd %d (0x%x), "
3091 "op %d, fd %d (0x%x), event %p", getpid (), epfd, epfd, func_str,
3092 libc_epfd, libc_epfd, op, fd, fd, event);
3093
3094 rv = libc_epoll_ctl (libc_epfd, op, fd, event);
Dave Wallace048b1d62018-01-03 22:24:41 -05003095 }
3096
3097done:
Dave Wallace2a865272018-02-07 21:00:42 -05003098 if (LDP_DEBUG > 1)
Dave Wallace048b1d62018-01-03 22:24:41 -05003099 {
3100 if (rv < 0)
3101 {
3102 int errno_val = errno;
3103 perror (func_str);
3104 clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
3105 "rv %d, errno = %d", getpid (), fd, fd,
3106 func_str, rv, errno_val);
3107 errno = errno_val;
3108 }
3109 else
3110 clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
3111 getpid (), fd, fd, rv, rv);
3112 }
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003113 return rv;
3114}
Dave Wallace048b1d62018-01-03 22:24:41 -05003115
3116static inline int
Florin Coras99368312018-08-02 10:45:44 -07003117ldp_epoll_pwait (int epfd, struct epoll_event *events, int maxevents,
3118 int timeout, const sigset_t * sigmask)
Dave Wallace048b1d62018-01-03 22:24:41 -05003119{
Florin Coras99368312018-08-02 10:45:44 -07003120 double time_to_wait = (double) 0, time_out, now = 0;
Dave Wallace2a865272018-02-07 21:00:42 -05003121 u32 vep_idx = ldp_sid_from_fd (epfd);
Florin Coras99368312018-08-02 10:45:44 -07003122 int libc_epfd, rv = 0;
3123 const char *func_str;
Dave Wallace048b1d62018-01-03 22:24:41 -05003124
Dave Wallace2a865272018-02-07 21:00:42 -05003125 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05003126 return -1;
3127
3128 if (PREDICT_FALSE (!events || (timeout < -1)))
3129 {
3130 errno = EFAULT;
3131 return -1;
3132 }
3133
Florin Coras99368312018-08-02 10:45:44 -07003134 if (epfd == ldp->vcl_mq_epfd)
3135 return libc_epoll_pwait (epfd, events, maxevents, timeout, sigmask);
3136
Dave Wallace048b1d62018-01-03 22:24:41 -05003137 if (PREDICT_FALSE (vep_idx == INVALID_SESSION_ID))
3138 {
3139 clib_warning ("LDP<%d>: ERROR: epfd %d (0x%x): bad vep_idx %d (0x%x)!",
3140 getpid (), epfd, epfd, vep_idx, vep_idx);
3141 errno = EBADFD;
3142 return -1;
3143 }
3144
Florin Coras54693d22018-07-17 10:46:29 -07003145 time_to_wait = ((timeout >= 0) ? (double) timeout : 0);
Dave Wallace2a865272018-02-07 21:00:42 -05003146 time_out = clib_time_now (&ldp->clib_time) + time_to_wait;
Dave Wallace048b1d62018-01-03 22:24:41 -05003147
3148 func_str = "vppcom_session_attr[GET_LIBC_EPFD]";
3149 libc_epfd = vppcom_session_attr (vep_idx, VPPCOM_ATTR_GET_LIBC_EPFD, 0, 0);
3150 if (PREDICT_FALSE (libc_epfd < 0))
3151 {
3152 errno = -libc_epfd;
3153 rv = -1;
3154 goto done;
3155 }
3156
Florin Coras99368312018-08-02 10:45:44 -07003157 LDBG (2, "LDP<%d>: epfd %d (0x%x): vep_idx %d (0x%x), libc_epfd %d (0x%x), "
3158 "events %p, maxevents %d, timeout %d, sigmask %p: time_to_wait %.02f",
3159 getpid (), epfd, epfd, vep_idx, vep_idx, libc_epfd, libc_epfd, events,
3160 maxevents, timeout, sigmask, time_to_wait, time_out);
Dave Wallace048b1d62018-01-03 22:24:41 -05003161 do
3162 {
Dave Wallace2a865272018-02-07 21:00:42 -05003163 if (!ldp->epoll_wait_vcl)
Dave Wallace048b1d62018-01-03 22:24:41 -05003164 {
3165 func_str = "vppcom_epoll_wait";
3166
Florin Coras99368312018-08-02 10:45:44 -07003167 LDBG (3, "LDP<%d>: epfd %d (0x%x): calling %s(): vep_idx %d (0x%x),"
3168 " events %p, maxevents %d", getpid (), epfd, epfd, func_str,
3169 vep_idx, vep_idx, events, maxevents);
Dave Wallace048b1d62018-01-03 22:24:41 -05003170
3171 rv = vppcom_epoll_wait (vep_idx, events, maxevents, 0);
3172 if (rv > 0)
3173 {
Dave Wallace2a865272018-02-07 21:00:42 -05003174 ldp->epoll_wait_vcl = 1;
Dave Wallace048b1d62018-01-03 22:24:41 -05003175 goto done;
3176 }
3177 else if (rv < 0)
3178 {
3179 errno = -rv;
3180 rv = -1;
3181 goto done;
3182 }
3183 }
3184 else
Dave Wallace2a865272018-02-07 21:00:42 -05003185 ldp->epoll_wait_vcl = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -05003186
3187 if (libc_epfd > 0)
3188 {
3189 func_str = "libc_epoll_pwait";
3190
Florin Coras99368312018-08-02 10:45:44 -07003191 LDBG (3, "LDP<%d>: epfd %d (0x%x): calling %s(): libc_epfd %d "
3192 "(0x%x), events %p, maxevents %d, sigmask %p", getpid (),
3193 epfd, epfd, func_str, libc_epfd, libc_epfd, events,
3194 maxevents, sigmask);
Dave Wallace048b1d62018-01-03 22:24:41 -05003195
Keith Burns (alagalah)5368efa2018-02-07 13:20:28 -08003196 rv = libc_epoll_pwait (libc_epfd, events, maxevents, 1, sigmask);
Dave Wallace048b1d62018-01-03 22:24:41 -05003197 if (rv != 0)
3198 goto done;
3199 }
3200
3201 if (timeout != -1)
Dave Wallace2a865272018-02-07 21:00:42 -05003202 now = clib_time_now (&ldp->clib_time);
Dave Wallace048b1d62018-01-03 22:24:41 -05003203 }
3204 while (now < time_out);
3205
3206done:
Dave Wallace2a865272018-02-07 21:00:42 -05003207 if (LDP_DEBUG > 3)
Dave Wallace048b1d62018-01-03 22:24:41 -05003208 {
Keith Burns (alagalah)5368efa2018-02-07 13:20:28 -08003209 if (libc_epfd > 0)
3210 epfd = libc_epfd;
Dave Wallace048b1d62018-01-03 22:24:41 -05003211 if (rv < 0)
3212 {
3213 int errno_val = errno;
3214 perror (func_str);
3215 clib_warning ("LDP<%d>: ERROR: epfd %d (0x%x): %s() failed! "
3216 "rv %d, errno = %d", getpid (), epfd, epfd,
3217 func_str, rv, errno_val);
3218 errno = errno_val;
3219 }
3220 else
3221 clib_warning ("LDP<%d>: epfd %d (0x%x): returning %d (0x%x)",
3222 getpid (), epfd, epfd, rv, rv);
3223 }
3224 return rv;
3225}
3226
3227int
3228epoll_pwait (int epfd, struct epoll_event *events,
3229 int maxevents, int timeout, const sigset_t * sigmask)
3230{
Dave Wallace2a865272018-02-07 21:00:42 -05003231 return ldp_epoll_pwait (epfd, events, maxevents, timeout, sigmask);
Dave Wallace048b1d62018-01-03 22:24:41 -05003232}
3233
3234int
3235epoll_wait (int epfd, struct epoll_event *events, int maxevents, int timeout)
3236{
Dave Wallace2a865272018-02-07 21:00:42 -05003237 return ldp_epoll_pwait (epfd, events, maxevents, timeout, NULL);
Dave Wallace048b1d62018-01-03 22:24:41 -05003238}
3239
3240int
3241poll (struct pollfd *fds, nfds_t nfds, int timeout)
3242{
3243 const char *func_str = __func__;
Florin Coras6917b942018-11-13 22:44:54 -08003244 int rv, i, n_revents = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -05003245 u32 sid;
3246 vcl_poll_t *vp;
3247 double wait_for_time;
3248
Florin Coras6917b942018-11-13 22:44:54 -08003249 LDBG (3, "LDP<%d>: fds %p, nfds %d, timeout %d", getpid (), fds, nfds,
3250 timeout);
Dave Wallace048b1d62018-01-03 22:24:41 -05003251
3252 if (timeout >= 0)
3253 wait_for_time = (f64) timeout / 1000;
3254 else
3255 wait_for_time = -1;
3256
Dave Wallace048b1d62018-01-03 22:24:41 -05003257 for (i = 0; i < nfds; i++)
3258 {
Florin Coras6917b942018-11-13 22:44:54 -08003259 if (fds[i].fd < 0)
3260 continue;
Dave Wallace048b1d62018-01-03 22:24:41 -05003261
Florin Coras6917b942018-11-13 22:44:54 -08003262 LDBG (3, "LDP<%d>: fds[%d] fd %d (0x%0x) events = 0x%x revents = 0x%x",
3263 getpid (), i, fds[i].fd, fds[i].fd, fds[i].events,
3264 fds[i].revents);
3265
3266 sid = ldp_sid_from_fd (fds[i].fd);
3267 if (sid != INVALID_SESSION_ID)
3268 {
3269 fds[i].fd = -fds[i].fd;
3270 vec_add2 (ldp->vcl_poll, vp, 1);
3271 vp->fds_ndx = i;
3272 vp->sid = sid;
3273 vp->events = fds[i].events;
Dave Wallace048b1d62018-01-03 22:24:41 -05003274#ifdef __USE_XOPEN2K
Florin Coras6917b942018-11-13 22:44:54 -08003275 if (fds[i].events & POLLRDNORM)
3276 vp->events |= POLLIN;
3277 if (fds[i].events & POLLWRNORM)
3278 vp->events |= POLLOUT;
Dave Wallace048b1d62018-01-03 22:24:41 -05003279#endif
Florin Coras6917b942018-11-13 22:44:54 -08003280 vp->revents = fds[i].revents;
3281 }
3282 else
3283 {
3284 vec_add1 (ldp->libc_poll, fds[i]);
3285 vec_add1 (ldp->libc_poll_idxs, i);
Dave Wallace048b1d62018-01-03 22:24:41 -05003286 }
3287 }
3288
Dave Wallace048b1d62018-01-03 22:24:41 -05003289 do
3290 {
Dave Wallace2a865272018-02-07 21:00:42 -05003291 if (vec_len (ldp->vcl_poll))
Dave Wallace048b1d62018-01-03 22:24:41 -05003292 {
3293 func_str = "vppcom_poll";
3294
Florin Coras6917b942018-11-13 22:44:54 -08003295 LDBG (3, "LDP<%d>: calling %s(): vcl_poll %p, n_sids %u (0x%x): "
3296 "n_libc_fds %u", getpid (), func_str, ldp->vcl_poll,
3297 vec_len (ldp->vcl_poll), vec_len (ldp->vcl_poll),
3298 vec_len (ldp->libc_poll));
Dave Wallace048b1d62018-01-03 22:24:41 -05003299
Dave Wallace2a865272018-02-07 21:00:42 -05003300 rv = vppcom_poll (ldp->vcl_poll, vec_len (ldp->vcl_poll), 0);
Dave Wallace048b1d62018-01-03 22:24:41 -05003301 if (rv < 0)
3302 {
3303 errno = -rv;
3304 rv = -1;
3305 goto done;
3306 }
3307 else
3308 n_revents += rv;
3309 }
3310
Florin Coras6917b942018-11-13 22:44:54 -08003311 if (vec_len (ldp->libc_poll))
Dave Wallace048b1d62018-01-03 22:24:41 -05003312 {
3313 func_str = "libc_poll";
3314
Florin Coras6917b942018-11-13 22:44:54 -08003315 LDBG (3, "LDP<%d>: calling %s(): fds %p, nfds %u: n_sids %u",
3316 getpid (), fds, nfds, vec_len (ldp->vcl_poll));
Dave Wallace048b1d62018-01-03 22:24:41 -05003317
Florin Coras6917b942018-11-13 22:44:54 -08003318 rv = libc_poll (ldp->libc_poll, vec_len (ldp->libc_poll), 0);
Dave Wallace048b1d62018-01-03 22:24:41 -05003319 if (rv < 0)
3320 goto done;
3321 else
3322 n_revents += rv;
3323 }
3324
3325 if (n_revents)
3326 {
3327 rv = n_revents;
3328 goto done;
3329 }
3330 }
3331 while ((wait_for_time == -1) ||
Dave Wallace2a865272018-02-07 21:00:42 -05003332 (clib_time_now (&ldp->clib_time) < wait_for_time));
Dave Wallace048b1d62018-01-03 22:24:41 -05003333 rv = 0;
3334
3335done:
Dave Wallace2a865272018-02-07 21:00:42 -05003336 vec_foreach (vp, ldp->vcl_poll)
Dave Wallace048b1d62018-01-03 22:24:41 -05003337 {
3338 fds[vp->fds_ndx].fd = -fds[vp->fds_ndx].fd;
Florin Coras6917b942018-11-13 22:44:54 -08003339 fds[vp->fds_ndx].revents = vp->revents;
Dave Wallace048b1d62018-01-03 22:24:41 -05003340#ifdef __USE_XOPEN2K
3341 if ((fds[vp->fds_ndx].revents & POLLIN) &&
3342 (fds[vp->fds_ndx].events & POLLRDNORM))
3343 fds[vp->fds_ndx].revents |= POLLRDNORM;
3344 if ((fds[vp->fds_ndx].revents & POLLOUT) &&
3345 (fds[vp->fds_ndx].events & POLLWRNORM))
3346 fds[vp->fds_ndx].revents |= POLLWRNORM;
3347#endif
3348 }
Dave Wallace2a865272018-02-07 21:00:42 -05003349 vec_reset_length (ldp->vcl_poll);
Dave Wallace048b1d62018-01-03 22:24:41 -05003350
Florin Coras6917b942018-11-13 22:44:54 -08003351 for (i = 0; i < vec_len (ldp->libc_poll); i++)
3352 {
3353 fds[ldp->libc_poll_idxs[i]].revents = ldp->libc_poll[i].revents;
3354 }
3355 vec_reset_length (ldp->libc_poll_idxs);
3356 vec_reset_length (ldp->libc_poll);
3357
Dave Wallace2a865272018-02-07 21:00:42 -05003358 if (LDP_DEBUG > 3)
Dave Wallace048b1d62018-01-03 22:24:41 -05003359 {
3360 if (rv < 0)
3361 {
3362 int errno_val = errno;
3363 perror (func_str);
3364 clib_warning ("LDP<%d>: ERROR: %s() failed! "
3365 "rv %d, errno = %d", getpid (),
3366 func_str, rv, errno_val);
3367 errno = errno_val;
3368 }
3369 else
3370 {
3371 clib_warning ("LDP<%d>: returning %d (0x%x): n_sids %u, "
3372 "n_libc_fds %d", getpid (), rv, rv,
Florin Coras6917b942018-11-13 22:44:54 -08003373 vec_len (ldp->vcl_poll), vec_len (ldp->libc_poll));
Dave Wallace048b1d62018-01-03 22:24:41 -05003374
3375 for (i = 0; i < nfds; i++)
3376 {
3377 if (fds[i].fd >= 0)
3378 {
Dave Wallace2a865272018-02-07 21:00:42 -05003379 if (LDP_DEBUG > 3)
Dave Wallace048b1d62018-01-03 22:24:41 -05003380 clib_warning ("LDP<%d>: fds[%d].fd %d (0x%0x), "
3381 ".events = 0x%x, .revents = 0x%x",
3382 getpid (), i, fds[i].fd, fds[i].fd,
3383 fds[i].events, fds[i].revents);
3384 }
3385 }
3386 }
3387 }
3388
3389 return rv;
3390}
3391
3392#ifdef USE_GNU
3393int
3394ppoll (struct pollfd *fds, nfds_t nfds,
3395 const struct timespec *timeout, const sigset_t * sigmask)
3396{
Dave Wallace2a865272018-02-07 21:00:42 -05003397 if ((errno = -ldp_init ()))
Dave Wallace048b1d62018-01-03 22:24:41 -05003398 return -1;
3399
3400 clib_warning ("LDP<%d>: LDP-TBD", getpid ());
3401 errno = ENOSYS;
3402
3403
3404 return -1;
3405}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003406#endif
3407
Dave Wallace2a865272018-02-07 21:00:42 -05003408void CONSTRUCTOR_ATTRIBUTE ldp_constructor (void);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003409
Dave Wallace2a865272018-02-07 21:00:42 -05003410void DESTRUCTOR_ATTRIBUTE ldp_destructor (void);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003411
Dave Wallace048b1d62018-01-03 22:24:41 -05003412/*
3413 * This function is called when the library is loaded
3414 */
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003415void
Dave Wallace2a865272018-02-07 21:00:42 -05003416ldp_constructor (void)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003417{
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003418 swrap_constructor ();
Dave Wallace2a865272018-02-07 21:00:42 -05003419 if (ldp_init () != 0)
3420 fprintf (stderr, "\nLDP<%d>: ERROR: ldp_constructor: failed!\n",
Dave Wallace048b1d62018-01-03 22:24:41 -05003421 getpid ());
Dave Wallace69d01192018-02-22 16:22:09 -05003422 else if (LDP_DEBUG > 0)
Dave Wallace2a865272018-02-07 21:00:42 -05003423 clib_warning ("LDP<%d>: LDP constructor: done!\n", getpid ());
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003424}
3425
3426/*
3427 * This function is called when the library is unloaded
3428 */
3429void
Dave Wallace2a865272018-02-07 21:00:42 -05003430ldp_destructor (void)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003431{
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003432 swrap_destructor ();
Dave Wallace2a865272018-02-07 21:00:42 -05003433 if (ldp->init)
Dave Wallace048b1d62018-01-03 22:24:41 -05003434 {
3435 vppcom_app_destroy ();
Dave Wallace2a865272018-02-07 21:00:42 -05003436 ldp->init = 0;
Dave Wallace048b1d62018-01-03 22:24:41 -05003437 }
3438
3439 /* Don't use clib_warning() here because that calls writev()
Dave Wallace2a865272018-02-07 21:00:42 -05003440 * which will call ldp_init().
Dave Wallace048b1d62018-01-03 22:24:41 -05003441 */
Dave Wallace69d01192018-02-22 16:22:09 -05003442 if (LDP_DEBUG > 0)
3443 printf ("%s:%d: LDP<%d>: LDP destructor: done!\n",
3444 __func__, __LINE__, getpid ());
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003445}
3446
3447
3448/*
3449 * fd.io coding-style-patch-verification: ON
3450 *
3451 * Local Variables:
3452 * eval: (c-set-style "gnu")
3453 * End:
3454 */